diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 00000000000..61ebe523dd4 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,58 @@ +--- +image: Visual Studio 2019 + +shallow_clone: true + +# set clone depth +clone_depth: 1 + +# environment: +# APPVEYOR_SAVE_CACHE_ON_ERROR: true + +platform: + - x64 + +configuration: + - Release + +matrix: + fast_finish: true + +only_commits: + files: + - src/ + - vc14/ + - .appveyor.yml + - cmake/ + - CMakeLists.txt + +install: + - call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" + - cd C:\Tools\vcpkg + - git pull + - .\bootstrap-vcpkg.bat + - .\vcpkg integrate install + - cd %APPVEYOR_BUILD_FOLDER% + +before_build: + - cmd: |- + if not exist build mkdir build + cd build + cmake -DCMAKE_TOOLCHAIN_FILE=C:\Tools\vcpkg\scripts\buildsystems\vcpkg.cmake .. + cmake --build . --config Release + +build: + project: C:\projects\otservbr-global\build\otbr.sln + verbosity: minimal + parallel: true + +after_build: + - cd %APPVEYOR_BUILD_FOLDER%\build\bin + - 7z a -tzip otservbr-global.zip Release\ + +cache: + - C:\projects\otservbr-global\build\vcpkg_installed\ + - C:\Users\appveyor\AppData\Local\vcpkg\archives + +artifacts: + - path: \build\bin\otservbr-global.zip diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000000..cd1cea93ab1 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,40 @@ +root = true + +# General configuration +[*] +charset = utf-8 +end_of_line = lf +indent_style = tab +insert_final_newline = true +trim_trailing_whitespace = true + +# Lua, XML +[*.{lua,xml}] +indent_style = tab +indent_size = 2 + +# SQL +[**.{sql}] +indent_style = space +indent_size = 2 + +#cmake +[CMakeLists.txt] +indent_style = tab +indent_size = 2 + +# Google Style +[*.{cpp,hpp,h}] +indent_style = tab +indent_size = 2 +indent_brace_style = K&R +spaces_around_brackets = none + +[*.{yml,yaml,json}] +indent_style = space +indent_size = 2 + +# CMake +[CMakeLists.txt] +indent_style = space +indent_size = 2 diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000000..cae38e62db2 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,14 @@ +--- + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: [ + 'https://opentibiabr.github.io/donation/', +] diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000000..89b2d390648 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: 'Help / Support' + url: 'https://discord.gg/3NxYnyV?utm_source=Github' + about: If you have support question or need help, please use our Discord Server. diff --git a/.github/ISSUE_TEMPLATE/i-want-to-help.md b/.github/ISSUE_TEMPLATE/i-want-to-help.md new file mode 100644 index 00000000000..7528c2bd4d5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/i-want-to-help.md @@ -0,0 +1,10 @@ +--- +name: I have a snippet to share +about: If you have any lua, xml or cpp code that you want to share to be added to the server +--- + +If you have a piece of code to contribute and want to share with OTServBR, **please do it with a pull request instead**. Refrain from opening issues for simple code changes, it makes everything slower while you could be contributing to the community and improving the life of every player that uses this server. + +If you don't know how to contribute in GitHub, you don't even need to know Git: can try to edit the files that you want to change directly from the web interface. If you need to change more files you need to create a complete pull request, [you can learn how to do that with this tutorial](https://github.com/firstcontributions/first-contributions). + +Please don't be afraid if this is your first contribution, we are all here to help you if you are willing to invest the time :) \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/map-issues.md b/.github/ISSUE_TEMPLATE/map-issues.md new file mode 100644 index 00000000000..6ed06960e30 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/map-issues.md @@ -0,0 +1,32 @@ +--- +name: Report map issues +about: Any problems, missing places or wrong content in the map +title: 'MAP: ' +labels: 'Where: Map' +assignees: '' + +--- + +## READ BEFORE PROCEEDING: OUR SERVER IS UPDATED DAILY. IF POSSIBLE MAKE SURE TO UPDATE TO THE LATEST VERSION BEFORE REPORTING. + +#### What are the coordinates of the place where the issue with the map was found? +- X: +- Y: +- Z: + +#### What kind of issue you found (respawns missing, details, large areas...)? +- + +#### Screenshots +> Please include screenshots or recordings of the place in the map + +#### What was expected to be in place? +> A clear and concise description of what you expected to see on the place you described. + +#### Environment +- OS (e.g. Windows): +- OTServ Version (e.g. commit): +- Tibia Version (e.g. 12.52): + +#### Additional context +> Add any other context about the problem here. \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/missing-feature.md b/.github/ISSUE_TEMPLATE/missing-feature.md new file mode 100644 index 00000000000..210df826c8a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/missing-feature.md @@ -0,0 +1,27 @@ +--- +name: Feature request +about: Request larger pieces of feature. Eg. actions, interactions, mechanics, ... +title: 'FEATURE: ' +labels: "Type: Enhancement" +assignees: '' +--- + +## READ BEFORE PROCEEDING: OUR SERVER IS UPDATED DAILY. IF POSSIBLE MAKE SURE TO UPDATE TO THE LATEST VERSION BEFORE REPORTING. + +#### Describe your feature request +> A clear and concise description of what the request is about. Ex. I'm always frustrated when [...] + +#### Describe the solution you'd like +> A clear and concise description of what you expected to happen. + +#### Describe alternatives you've considered +> A clear and concise description of any alternative solutions or features you've considered. + +#### Links +> If applicable, add links to help explain how this feature works. + +#### Screenshots +> If applicable, add screenshots to help explain your feature request + +#### Additional context +> Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/missing-wrong-content.md b/.github/ISSUE_TEMPLATE/missing-wrong-content.md new file mode 100644 index 00000000000..2541331d0a4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/missing-wrong-content.md @@ -0,0 +1,24 @@ +--- +name: Missing content +about: Report missing or wrong content in the server. Eg. NPCs, quests, items, monsters... +title: 'CONTENT: ' +labels: "Type: Missing Content" +assignees: '' +--- + +## READ BEFORE PROCEEDING: OUR SERVER IS UPDATED DAILY. IF POSSIBLE MAKE SURE TO UPDATE TO THE LATEST VERSION BEFORE REPORTING. + +#### Describe the wrong or missing content +> A clear and concise description of what content is wrong or missing + +#### Describe the correct content +> A clear and concise description of what would be the correct content in place + +#### Links +> If applicable, add links to help references of how the content + +#### Screenshots +> If applicable, add screenshots to help explain the content + +#### Additional context +> Add any other context about the problem here \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/z-bug-report.md b/.github/ISSUE_TEMPLATE/z-bug-report.md new file mode 100644 index 00000000000..f4161f2386f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/z-bug-report.md @@ -0,0 +1,39 @@ +--- +name: Report a problem +about: Any issues that you have found while using the server +title: 'BUG: ' +labels: 'Type: Bug' +assignees: '' + +--- + +## READ BEFORE PROCEEDING: OUR SERVER IS UPDATED DAILY. IF POSSIBLE MAKE SURE TO UPDATE TO THE LATEST VERSION BEFORE REPORTING. + +#### Describe the bug +> A clear and concise description of what the bug is. + +#### How to Reproduce? +> If you cannot reproduce an issue by redoing the same steps, we also will not be able :) + +> Give us all details to reproduce the behavior: +> 1. Walk to city '...' +> 2. Click on item '....' +> 3. Drag it to backpack '....' +> 4. See error + +#### Logs or errors +> Please include any errors or logs that are relevant + +#### Expected behavior +> A clear and concise description of what you expected to happen. + +#### Screenshots +> If applicable, add screenshots to help explain your problem. + +#### Environment +- OS (e.g. Windows): +- OTServ Version (e.g. commit): +- Tibia Version (e.g. 12.52): + +#### Additional context +> Add any other context about the problem here. \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md new file mode 100644 index 00000000000..47b19df7018 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md @@ -0,0 +1,49 @@ + +# Description + +Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. + +## Behaviour +### **Actual** + +Do this and that doesn't happens + +### **Expected** + +Do this and that happens + +## Fixes + +\# (issue) + +## Type of change + +Please delete options that are not relevant. + + - [ ] Bug fix (non-breaking change which fixes an issue) + - [ ] New feature (non-breaking change which adds functionality) + - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) + - [ ] This change requires a documentation update + +## How Has This Been Tested + +Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration + + - [ ] Test A + - [ ] Test B + +**Test Configuration**: + + - Server Version: + - Client: + - Operating System: + +## Checklist + + - [ ] My code follows the style guidelines of this project + - [ ] I have performed a self-review of my own code + - [ ] I checked the PR checks reports + - [ ] I have commented my code, particularly in hard-to-understand areas + - [ ] I have made corresponding changes to the documentation + - [ ] My changes generate no new warnings + - [ ] I have added tests that prove my fix is effective or that my feature works diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 00000000000..2a296153a79 --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,12 @@ +--- +source: + - any: ['src/**/*'] + +data: + - any: ['data/**/*', '!data/world/*'] + +map: + - any: ['data/world/*'] + +docker: + - any: ['docker/**/*'] diff --git a/.github/workflows/build-ubuntu.yml b/.github/workflows/build-ubuntu.yml new file mode 100644 index 00000000000..c3e5f2b1d63 --- /dev/null +++ b/.github/workflows/build-ubuntu.yml @@ -0,0 +1,95 @@ +--- + +name: Build on Ubuntu + +on: + push: + branches: + - master + - develop + - v* + + tags: + - v* + + pull_request: + paths: + - cmake/** + - src/** + - CMakeLists.txt + - .github/** + +jobs: + job: + name: ${{ matrix.os }}-${{ matrix.buildtype }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-18.04, ubuntu-20.04] + buildtype: [Debug, Release] + include: + - os: ubuntu-18.04 + triplet: x64-linux + - os: ubuntu-20.04 + triplet: x64-linux + + steps: + - uses: actions/checkout@v2 + - uses: lukka/get-cmake@latest + + - name: Install Dependencies + run: > + sudo apt-get update && sudo apt-get install ccache build-essential + libluajit-5.1-dev zip + + - name: CCache + id: ccache + uses: actions/cache@v2 + with: + path: ~/.ccache + key: ${{ matrix.os }}-${{ matrix.buildtype }}-${{ hashFiles('**/src') }} + restore-keys: | + ${{ matrix.os }}-${{ matrix.buildtype }}-${{ hashFiles('**/src') }} + ${{ matrix.os }}-${{ matrix.buildtype }}- + + - name: Restore artifacts, or setup vcpkg (do not install any package) + uses: lukka/run-vcpkg@v7 + with: + setupOnly: true + vcpkgDirectory: '${{ github.workspace }}/vcpkg' + appendedCacheKey: ${{ hashFiles( '**/vcpkg.json' ) }} + vcpkgTriplet: ${{ matrix.triplet }} + additionalCachedPaths: ${{ github.workspace }}/build/vcpkg_installed + vcpkgGitCommitId: ${{ secrets.VCPKG_ID }} + + - name: 'Run CMake with Ninja, install dependencies with vcpkg, build with CMake' + uses: lukka/run-cmake@v3 + with: + cmakeListsTxtPath: '${{ github.workspace }}/CMakeLists.txt' + useVcpkgToolchainFile: true + buildDirectory: ${{ github.workspace }}/build/ + cmakeBuildType: ${{ matrix.buildtype }} + + - name: Clean workspace + if: ${{ matrix.buildtype == 'Release' }} + shell: bash + run: | + mv ${{ github.workspace }}/build/bin/otbr ${{ github.workspace }}/otbr + find . -maxdepth 1 ! -name otbr ! -name data ! -name config.lua.dist ! -name key.pem ! -name LICENSE ! -name README.md ! -name schema.sql -exec rm -r {} \; + + - name: Prepare datapack contents + if: ${{ matrix.buildtype == 'Release' }} + shell: bash + run: | + mv config.lua.dist config.lua + unzip -o data/world/world.zip -d data/world/ + rm data/world/world.zip + cd .. + zip -r otservbr.zip otservbr-global + + - name: Upload binary + if: ${{ matrix.buildtype == 'Release' }} + uses: actions/upload-artifact@v2 + with: + name: ${{ matrix.os }}-otbr-amd64-${{ matrix.buildtype }}-${{ github.sha }} + path: ${{ runner.workspace }}/otservbr.zip diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml new file mode 100644 index 00000000000..af030df907d --- /dev/null +++ b/.github/workflows/build-windows.yml @@ -0,0 +1,97 @@ +--- + +name: Build on Windows + +on: + push: + branches: + - master + - develop + - v* + + tags: + - v* + + pull_request: + paths: + - cmake/** + - src/** + - CMakeLists.txt + - .github/** + +jobs: + job: + name: ${{ matrix.os }}-${{ matrix.buildtype }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [windows-latest] + buildtype: [Debug, Release] + include: + - os: windows-latest + triplet: x64-windows + packages: > + boost-asio boost-iostreams boost-system boost-filesystem + boost-variant boost-lockfree cryptopp curl jsoncpp + luajit libmariadb pugixml spdlog + + steps: + - uses: actions/checkout@v2 + - uses: lukka/get-cmake@latest + + - name: Windows - remove C:/mysql* + run: rm -r -fo C:/mysql-5.7.21-winx64 + if: contains( matrix.os, 'windows') + + - name: Restore artifacts, or setup vcpkg (do not install any package) + uses: lukka/run-vcpkg@v7 + with: + setupOnly: true + vcpkgDirectory: '${{ github.workspace }}/vcpkg' + appendedCacheKey: ${{ hashFiles( '**/vcpkg.json' ) }} + vcpkgTriplet: ${{ matrix.triplet }} + additionalCachedPaths: ${{ github.workspace }}/build/vcpkg_installed + vcpkgGitCommitId: ${{ secrets.VCPKG_ID }} + + - name: Run CMake to install the dependencies specified in the vcpkg.json manifest, generate project file and build the project + uses: lukka/run-cmake@v3 + with: + cmakeListsTxtPath: '${{ github.workspace }}/CMakeLists.txt' + buildDirectory: ${{ github.workspace }}/build + useVcpkgToolchainFile: true + buildWithCMake: true + + - name: Copy artifacts + if: ${{ matrix.buildtype == 'Release' }} + shell: pwsh + run: | + Copy-Item -Path ${{ github.workspace }}\build\bin\* -Destination ${{ github.workspace }} -Recurse + + - name: Create and Upload Full Datapack + if: ${{ matrix.buildtype == 'Release' }} + uses: actions/upload-artifact@v2 + with: + name: otbr-full-${{ matrix.os }}-${{ matrix.buildtype }}-${{ github.sha }} + path: | + ${{ github.workspace }} + !${{ github.workspace }}/build/ + !${{ github.workspace }}/vcpkg/ + !${{ github.workspace }}/.git/ + !${{ github.workspace }}/.github/ + !${{ github.workspace }}/.appveyor.yml + !${{ github.workspace }}/.editorconfig + !${{ github.workspace }}/.gitignore + !${{ github.workspace }}/.reviewdog.yml + !${{ github.workspace }}/.travis.yml + !${{ github.workspace }}/tests/ + !${{ github.workspace }}/cmake/ + !${{ github.workspace }}/sonar-project.properties + !${{ github.workspace }}/Jenkinsfile + + - name: Create and Upload Server Only + if: ${{ matrix.buildtype == 'Release' }} + uses: actions/upload-artifact@v2 + with: + name: otbr-server-only-${{ matrix.os }}-${{ matrix.buildtype }}-${{ github.sha }} + path: | + ${{ github.workspace }}/build/bin/ diff --git a/.github/workflows/codacy-analysis.yml b/.github/workflows/codacy-analysis.yml new file mode 100644 index 00000000000..89c080205d0 --- /dev/null +++ b/.github/workflows/codacy-analysis.yml @@ -0,0 +1,35 @@ +--- + +name: Codacy Security Scan + +on: + push: + branches: [ develop ] + pull_request: + branches: [ develop ] + schedule: + - cron: '44 0 * * 1' + +jobs: + codacy-security-scan: + name: Codacy Security Scan + runs-on: ubuntu-latest + steps: + + - name: Checkout code + uses: actions/checkout@v2 + + - name: Run Codacy Analysis CLI + uses: codacy/codacy-analysis-cli-action@1.1.0 + with: + project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} + verbose: true + output: results.sarif + format: sarif + gh-code-scanning-compat: true + max-allowed-issues: 2147483647 + + - name: Upload SARIF results file + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: results.sarif diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 00000000000..1b799fdb3a7 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,61 @@ +--- + +name: "CodeQL" + +on: + push: + branches: [ develop ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ develop ] + schedule: + - cron: '17 22 * * 2' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + language: [ 'cpp', 'python' ] + + steps: + - uses: lukka/get-cmake@latest + + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + + - name: Install Dependencies + if: ${{ matrix.language == 'cpp' }} + run: > + sudo apt-get update && sudo apt-get install ccache build-essential + libluajit-5.1-dev zip + + - name: Restore artifacts, or setup vcpkg (do not install any package) + if: ${{ matrix.language == 'cpp' }} + uses: lukka/run-vcpkg@v7 + with: + setupOnly: true + vcpkgDirectory: '${{ github.workspace }}/vcpkg' + appendedCacheKey: ${{ hashFiles( '**/vcpkg.json' ) }} + vcpkgTriplet: ${{ matrix.triplet }} + additionalCachedPaths: ${{ github.workspace }}/build/vcpkg_installed + vcpkgGitCommitId: ${{ secrets.VCPKG_ID }} + + - name: 'Run CMake with Ninja, install dependencies with vcpkg, build with CMake' + if: ${{ matrix.language == 'cpp' }} + uses: lukka/run-cmake@v3 + with: + cmakeListsTxtPath: '${{ github.workspace }}/CMakeLists.txt' + useVcpkgToolchainFile: true + buildDirectory: ${{ github.workspace }}/build/ + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml new file mode 100644 index 00000000000..d197f40e7a9 --- /dev/null +++ b/.github/workflows/labeler.yml @@ -0,0 +1,13 @@ +--- + +name: "Pull Request Labeler" +on: +- pull_request_target + +jobs: + triage: + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@main + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/reviewdog.yml b/.github/workflows/reviewdog.yml new file mode 100644 index 00000000000..e4a7333243c --- /dev/null +++ b/.github/workflows/reviewdog.yml @@ -0,0 +1,82 @@ +--- + +name: Review +on: [pull_request] +jobs: + reviewers: + runs-on: ubuntu-latest + steps: + - name: Update + run: sudo apt-get update + + - name: Setup Lua + run: sudo apt-get install -y lua5.1 liblua5.1-0-dev + + - name: Setup Luacheck + run: sudo apt-get install -y lua-check + + - name: Setup xmllint + run: sudo apt-get update && sudo apt-get install -y libxml2-utils + + - name: Setup cppcheck + run: sudo apt-get install -y cppcheck + + - name: Check out code. + uses: actions/checkout@v1 + + - name: Setup reviewdog + run: | + mkdir -p $HOME/bin && curl -sfL https://raw.githubusercontent.com/reviewdog/reviewdog/master/install.sh| sh -s -- -b $HOME/bin + + - name: cpplint + uses: reviewdog/action-cpplint@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + reporter: github-pr-check + filter: "-whitespace/tab\ + ,-whitespace/line_length\ + ,-build/include_subdir\ + ,-whitespace/braces\ + " + # flags: --linelength=120 + + - name: cppcheck + env: + REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + cd ${{ runner.workspace }}/otservbr-global + cppcheck --version + $HOME/bin/reviewdog -reporter=github-pr-check -runners=cppcheck + + - name: luacheck + env: + REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + luacheck --version + cd ${{ runner.workspace }}/otservbr-global + $HOME/bin/reviewdog -reporter=github-pr-check -runners=luacheck + + - name: luac + env: + REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + cd ${{ runner.workspace }}/otservbr-global + luac -v + $HOME/bin/reviewdog -reporter=github-pr-check -runners=luac + + - name: xmllint + env: + REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + cd ${{ runner.workspace }}/otservbr-global + xmllint --version + $HOME/bin/reviewdog -reporter=github-pr-check -runners=xmllint + + - name: shellcheck + uses: reviewdog/action-shellcheck@v1 + with: + github_token: ${{ secrets.github_token }} + reporter: github-pr-check + + - name: Run yamllint + uses: actionshub/yamllint@main diff --git a/.github/workflows/run-lua-tests.yml b/.github/workflows/run-lua-tests.yml new file mode 100644 index 00000000000..315a6cc38e9 --- /dev/null +++ b/.github/workflows/run-lua-tests.yml @@ -0,0 +1,19 @@ +--- + +name: Run Lua Tests +on: [pull_request] +jobs: + lua-tests: + runs-on: ubuntu-latest + steps: + - name: Update + run: sudo apt-get update + + - name: Setup Lua + run: sudo apt-get install -y lua5.1 liblua5.1-0-dev + + - name: Check out code. + uses: actions/checkout@v1 + + - name: Lua Tests + run: lua ${{ github.workspace }}/tests/lua/runtests.lua -v diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 00000000000..760c92c89e7 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,20 @@ +--- + +name: 'Stale issues and PRs' +on: + schedule: + - cron: '30 1 * * *' + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: 'This issue is stale because it has been open 120 days with no activity.' + stale-pr-message: 'This PR is stale because it has been open 45 days with no activity.' + days-before-issue-stale: 90 + days-before-pr-stale: 30 + days-before-issue-close: -1 + days-before-pr-close: -1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000000..0fdd4e8af85 --- /dev/null +++ b/.gitignore @@ -0,0 +1,385 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.dll +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +build/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Doxygen files +doc/* + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Docker folders with generated artifacts +docker/**/otserver + +# VSCode +settings.json +c_cpp_properties.json +.history + +# CLion (JetBrains) +.idea/ + +## CUSTOM +# Files +config.lua +# Extensions +*.ini +*.otb +*.exe +*.otbm +*.rar + +# SFTP for Sublime +sftp-config.json + +# Binaries +otbr +otbr.old + +# VCPKG +vcpkg_installed diff --git a/.reviewdog.yml b/.reviewdog.yml new file mode 100644 index 00000000000..bb84ffbb444 --- /dev/null +++ b/.reviewdog.yml @@ -0,0 +1,27 @@ +--- +runner: + + cppcheck: + cmd: cppcheck --enable=all --template="{file}:{line}:{message}" src/ + errorformat: + - "%f:%l:%m" + level: warning + + luacheck: + cmd: luacheck --formatter=plain --no-color --no-config --no-global \ + --no-unused --no-unused-args --no-cache -d ./data/ + errorformat: + - "%f:%l:%c: %m" + level: warning + + luac: + cmd: find data/ -name '*.lua' -exec luac -p {} \; + errorformat: + - "%r: %f:%l: %m" + level: warning + + xmllint: + cmd: find data/ -name '*.xml' -exec xmllint --noout {} \; + errorformat: + - "%f:%l: %m" + level: warning diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000000..1583457e0b7 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,57 @@ +--- +arch: amd64 +os: linux +dist: focal +language: cpp +compiler: gcc +env: + - VCPKG_TRIPLET=x64-linux + +git: + strategy: clone + depth: false + +addons: + sonarcloud: + organization: "opentibiabr" + token: + secure: X+7KiitGRaVuYh8wjZQDJ3kmv2B+FNudXaRUbOwjK/a+0YK0z7FkVmXklg05MygF4QtjkTOdUqg/HSgSY492/jMkb2ZxOlI/utR+UUnKf77XiwBFcUG+bmdNAG8+U0MG5I70xKjauXdNrUFZu9Ds5TpD40m4UMmAr0pGtrXyP6T28WG7t/sNxzlmwSx0Z+2+ZKhEFdneAXVXX6zC6TXA5yPFvEdawPm8iqJ7fjq559Yqsn7l38Sd3BVoa9tbcwTMCvQwn6DivxLbkSKYs173y33bbGx48rikf9JHdFaSPVD7rNzpiuz7JCxJu6eBjh+FP9lxs4jJ0Kb8NEzxzotjGNSyxAW7+o0F8F869PL3fpTcWMlWTnrEVAn5pIXGaZ6+0yhoCSCwbHGKX42rUXndlROF1laCnE8ANOBFqxElVQpRNJVI2Xh34q32VdElGX9I73BmaTq8QZN9o4a895g3a2XeP4tCUxNbflh60uMHa6eOS5mOuuOc4l6ehYvwJw3aa3Pcz46RvcAWfp+5aslTDXnCZzDoBlTSx8tKkR7kNe+AnZj2yQi0j/mWOR97S9N2qfKDaEGnMtyq+EUEkOE6KPI8eqzrNYHbNX6SVbyfMer8nAem6b1p8PgaU+vgeixgtWaB+OgZSf592xrtkrKEeuA37dm+hwQJ2IzcZ7+p7RA= + apt: + update: true + packages: + - ccache + - build-essential + - cmake + - libluajit-5.1-dev + - tar + - curl + - zip + - unzip + +install: + - cd /home/travis/build/opentibiabr + - git clone https://github.com/microsoft/vcpkg + - ./vcpkg/bootstrap-vcpkg.sh + - ./vcpkg/vcpkg integrate install + +script: + - cd /home/travis/build/opentibiabr/otservbr-global + - export CXXFLAGS="$CXXFLAGS -DBOOST_ASIO_DISABLE_NOEXCEPT=1 " + - /home/travis/build/opentibiabr/vcpkg/vcpkg --feature-flags=binarycaching,manifests,versions install + - mkdir build + - cd build + - cmake -DCMAKE_TOOLCHAIN_FILE=/home/travis/build/opentibiabr/vcpkg/scripts/buildsystems/vcpkg.cmake .. + - cd .. + - NUMBER_OF_PROCESSORS=$(nproc --all) + - build-wrapper-linux-x86-64 --out-dir bw-output cmake --build build/ + - sonar-scanner -Dsonar.cfamily.cache.enabled=true -Dsonar.cfamily.cache.path=${TRAVIS_HOME}/.cfamily -Dsonar.cfamily.threads=${NUMBER_OF_PROCESSORS} || true + + # - sonar-scanner -Dsonar.cfamily.cache.enabled=true -Dsonar.cfamily.cache.path=${TRAVIS_HOME}/.cfamily -Dsonar.cfamily.threads=${NUMBER_OF_PROCESSORS} || true + # - curl --upload-file /home/travis/build/opentibiabr/otservbr-global/sonar-cfamily-reproducer.zip https://transfer.sh/sonar-cfamily-reproducer.zip + +cache: + directories: + - $HOME/.sonar/cache + - $HOME/.cache + - $HOME/.ccache + - $HOME/.cfamily diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000000..11819ef1bdb --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,85 @@ +cmake_minimum_required(VERSION 3.16 FATAL_ERROR) + +# CMAKE +# apt install build-essential git +# git clone https://github.com/Kitware/CMake/; cd CMake +# ./bootstrap && make && sudo make install + +# VCPKG +# cmake -DCMAKE_TOOLCHAIN_FILE=/opt/workspace/vcpkg/scripts/buildsystems/vcpkg.cmake .. +# ./vcpkg install boost-asio boost-lockfree boost-variant boost-filesystem boost-iostreams boost-system libmariadb pugixml spdlog +if(DEFINED ENV{VCPKG_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE) + set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" + CACHE STRING "") +endif() + +if(DEFINED ENV{VCPKG_DEFAULT_TRIPLET} AND NOT DEFINED VCPKG_TARGET_TRIPLET) + set(VCPKG_TARGET_TRIPLET "$ENV{VCPKG_DEFAULT_TRIPLET}" CACHE STRING "") +endif() + +set(VCPKG_FEATURE_FLAGS "versions") +set(VCPKG_BUILD_TYPE "release") + +# ***************************************************************************** +# Project otbr +# ***************************************************************************** +project(otbr) + + +# ***************************************************************************** +# Append cmake search path +# ***************************************************************************** +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) + + +# ***************************************************************************** +# Include cmake tools +# ***************************************************************************** +include(MessageColors) +include(LoggingHelper) + + +# ***************************************************************************** +# Options +# ***************************************************************************** +option(OPTIONS_ENABLE_CCACHE "Enable ccache" ON) +option(OPTIONS_ENABLE_IPO "Check and Enable interprocedural optimization (IPO/LTO)" ON) + + +# ***************************************************************************** +# Options Code +# ***************************************************************************** + +# === CCACHE === +if(OPTIONS_ENABLE_CCACHE) + find_program(CCACHE ccache) + if(CCACHE) + log_option_enabled("ccache") + set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE}) + else() + log_option_disabled("ccache") + endif() +endif() + + +# === IPO === +option(OPTIONS_ENABLE_IPO "Check and Enable interprocedural optimization (IPO/LTO)" ON) +if(OPTIONS_ENABLE_IPO) + log_option_enabled("ipo") + + include(CheckIPOSupported) + check_ipo_supported(RESULT result OUTPUT output) + if(result) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) + else() + log_war("IPO is not supported: ${output}") + endif() +else() + log_option_disabled("ipo") +endif() + + +# ***************************************************************************** +# Add project +# ***************************************************************************** +add_subdirectory(src) diff --git a/CMakeSettings.json b/CMakeSettings.json new file mode 100644 index 00000000000..5932468c9e5 --- /dev/null +++ b/CMakeSettings.json @@ -0,0 +1,15 @@ +{ + "configurations": [ + { + "name": "x64-Release", + "generator": "Ninja", + "configurationType": "Release", + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "msvc_x64_x64" ] + } + ] +} \ No newline at end of file diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000000..c2181699867 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at ```opentibiabr@outlook.com```. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 00000000000..8fd46f2a9b1 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1 @@ +TestServer() diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000000..d159169d105 --- /dev/null +++ b/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/README.md b/README.md new file mode 100644 index 00000000000..fcc10a648fd --- /dev/null +++ b/README.md @@ -0,0 +1,72 @@ +# OTServ Brasil - Global Server + +[![Discord Channel](https://img.shields.io/discord/528117503952551936.svg?style=flat-square&logo=discord)](https://discord.gg/3NxYnyV) +[![GitHub issues](https://img.shields.io/github/issues/opentibiabr/otservbr-global)](https://github.com/opentibiabr/otservbr-global/issues) +[![GitHub pull request](https://img.shields.io/github/issues-pr/opentibiabr/otservbr-global)](https://github.com/opentibiabr/otservbr-global/pulls) +[![Contributors](https://img.shields.io/github/contributors/opentibiabr/otservbr-global.svg?style=flat-square)](https://github.com/opentibiabr/otservbr-global/graphs/contributors) +[![GitHub](https://img.shields.io/github/license/opentibiabr/otservbr-global)](https://github.com/opentibiabr/otservbr-global/blob/develop/LICENSE) + +![GitHub repo size](https://img.shields.io/github/repo-size/opentibiabr/otservbr-global) + +[![Codacy Badge](https://app.codacy.com/project/badge/Grade/a71728d523ac4b23a9c0b974ae4ec5df)](https://www.codacy.com/gh/opentibiabr/otservbr-global/dashboard?utm_source=github.com&utm_medium=referral&utm_content=opentibiabr/otservbr-global&utm_campaign=Badge_Grade) +[![CodeQL](https://github.com/opentibiabr/otservbr-global/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/opentibiabr/otservbr-global/actions/workflows/codeql-analysis.yml) +[![Codacy Security Scan](https://github.com/opentibiabr/otservbr-global/actions/workflows/codacy-analysis.yml/badge.svg)](https://github.com/opentibiabr/otservbr-global/actions/workflows/codacy-analysis.yml) + +## Builds + +[![Build status](https://ci.appveyor.com/api/projects/status/github/opentibiabr/otservbr-global?branch=develop&passingText=develop%20-%20OK&svg=true)](https://ci.appveyor.com/project/opentibiabr/otservbr-global/build/artifacts "Download nightly builds for Windows") + +[![Build on Ubuntu](https://github.com/opentibiabr/otservbr-global/workflows/Build%20on%20Ubuntu/badge.svg)](https://github.com/opentibiabr/otservbr-global/actions?query=workflow%3A%22Build+on+Ubuntu%22) +[![Build on Windows](https://github.com/opentibiabr/otservbr-global/workflows/Build%20on%20Windows/badge.svg)](https://github.com/opentibiabr/otservbr-global/actions?query=workflow%3A%22Build+on+Windows%22) + +## Project + +OTServ Brasil - Global Server is a free and open-source MMORPG server emulator written in C++. It is a fork of the [Forgotten Server](https://github.com/otland/forgottenserver) project. To connect to the server and to take a stable experience, you can use our [own client](https://forums.otserv.com.br/index.php?/forums/topic/167933-otservbr-global-cliente-tibia-12/) and if you want to edit something, check our [customized tools](https://github.com/opentibiabr/tools). + +You are subject to our code of conduct, read at [this link](https://github.com/opentibiabr/otservbr-global/blob/develop/CODE_OF_CONDUCT.md). + +### Getting **Started** + +* **WARNING: YOU NEED TO UNZIP THE MAP BEFORE START THE SERVER.** +* [Compiling on Windows](https://forums.otserv.com.br/index.php?/forums/topic/169235-windowsvc2019-compilando-sources-otservbr-global/), alternatively if you are ****not** going to change anything on the source** you can download the latest compiled version for windows from [nightly builds for Windows](https://ci.appveyor.com/project/opentibiabr/otservbr-global/build/artifacts). +* Wiki: Compiling ([Ubuntu/Debian](https://github.com/opentibiabr/otservbr-global/wiki/Compiling-on-Ubuntu-or-Debian-GNU-Linux), [Windows](https://github.com/opentibiabr/otservbr-global/wiki/Compiling-on-Windows-(vcpkg))) + +### Issues + +We use the [issue tracker on GitHub](https://github.com/opentibiabr/OTServBR-Global/issues). Keep in mind that everyone who is watching the repository gets notified by e-mail when there is an activity, so be thoughtful and avoid writing comments that aren't meant for an issue (e.g. "+1"). If you'd like for an issue to be fixed faster, you should either fix it yourself and submit a pull request, or place a bounty on the issue. + +### Pull requests + +Before [creating a pull request](https://github.com/opentibiabr/otservbr-global/pulls) please keep in mind: + + * Do not send Pull Request changing the map, as we can't review the changes it's better to use our [Discord](https://discord.gg/3NxYnyV) to talk about or send the map changes to the responsible for updating it. + * Focus on fixing only one thing, mixing too much things on the same Pull Request make it harder to review, harder to test and if we need to revert the change it will remove other things together. + * Follow the project indentation, if your editor support you can use the [editorconfig](https://editorconfig.org/) to automatic configure the indentation. + * There are people that doesn't play the game on the official server, so explain your changes to help understand what are you changing and why. + * Avoid opening a Pull Request to just update one line of an xml file. + +### Special Thanks + + * our partners + * our crew (majesty, gpedro, eduardo dantas, foot) + * [our contributors](https://github.com/opentibiabr/OTServBR-Global/graphs/contributors) + * [fear lucien](https://github.com/FearLucien) + * [cjaker](https://github.com/Eternal-Scripts) + * [slavidodo](https://github.com/slavidodo) + * [mignari and our awesome tools](https://github.com/ottools) + * [mattyx14/otxserver](https://github.com/mattyx14/otxserver) and contributors + * [otland/forgottenserver](https://github.com/otland/forgottenserver) and contributors + * [saiyansking/optimized_forgottenserver](https://github.com/SaiyansKing/optimized_forgottenserver) and contributors + * if we forget someone, we apologize by forgot you. but you know, **forgot**tenserver. + +### **Sponsors** + +If you want to sponsor here, join on discord and send a message for one of our administrators. + +### Partners + +[![Supported by OTServ Brasil](https://raw.githubusercontent.com/otbr/otserv-brasil/main/otbr.png)](https://forums.otserv.com.br) + +[![Protected by ServerCore](https://mktsc.servercore.com.br/protectedbyservercore.png)](https://bit.ly/1q2q4de) + +[![Supported by OTHispano](https://othispano.com/styles/purplefreak/logo3.png)](https://othispano.com/) diff --git a/cmake/FindCryptoPP.cmake b/cmake/FindCryptoPP.cmake new file mode 100644 index 00000000000..9ac38face41 --- /dev/null +++ b/cmake/FindCryptoPP.cmake @@ -0,0 +1,108 @@ +# Module for locating the Crypto++ encryption library. +# +# Customizable variables: +# CRYPTOPP_ROOT_DIR +# This variable points to the CryptoPP root directory. On Windows the +# library location typically will have to be provided explicitly using the +# -D command-line option. The directory should include the include/cryptopp, +# lib and/or bin sub-directories. +# +# Read-only variables: +# CRYPTOPP_FOUND +# Indicates whether the library has been found. +# +# CRYPTOPP_INCLUDE_DIRS +# Points to the CryptoPP include directory. +# +# CRYPTOPP_LIBRARIES +# Points to the CryptoPP libraries that should be passed to +# target_link_libararies. +# +# +# Copyright (c) 2012 Sergiu Dotenco +# +# 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. + +INCLUDE (FindPackageHandleStandardArgs) + +FIND_PATH (CRYPTOPP_ROOT_DIR + NAMES cryptopp/cryptlib.h include/cryptopp/cryptlib.h + PATHS ENV CRYPTOPPROOT + DOC "CryptoPP root directory") + +# Re-use the previous path: +FIND_PATH (CRYPTOPP_INCLUDE_DIR + NAMES cryptopp/cryptlib.h + HINTS ${CRYPTOPP_ROOT_DIR} + PATH_SUFFIXES include + DOC "CryptoPP include directory") + +FIND_LIBRARY (CRYPTOPP_LIBRARY_DEBUG + NAMES cryptlibd cryptoppd libcryptopp + HINTS ${CRYPTOPP_ROOT_DIR} + PATH_SUFFIXES lib + DOC "CryptoPP debug library") + +FIND_LIBRARY (CRYPTOPP_LIBRARY_RELEASE + NAMES cryptlib cryptopp libcryptopp + HINTS ${CRYPTOPP_ROOT_DIR} + PATH_SUFFIXES lib + DOC "CryptoPP release library") + +IF (CRYPTOPP_LIBRARY_DEBUG AND CRYPTOPP_LIBRARY_RELEASE) + SET (CRYPTOPP_LIBRARY + optimized ${CRYPTOPP_LIBRARY_RELEASE} + debug ${CRYPTOPP_LIBRARY_DEBUG} CACHE DOC "CryptoPP library") +ELSEIF (CRYPTOPP_LIBRARY_RELEASE) + SET (CRYPTOPP_LIBRARY ${CRYPTOPP_LIBRARY_RELEASE} CACHE DOC + "CryptoPP library") +ENDIF (CRYPTOPP_LIBRARY_DEBUG AND CRYPTOPP_LIBRARY_RELEASE) + +IF (CRYPTOPP_INCLUDE_DIR) + SET (_CRYPTOPP_VERSION_HEADER ${CRYPTOPP_INCLUDE_DIR}/cryptopp/config.h) + + IF (EXISTS ${_CRYPTOPP_VERSION_HEADER}) + FILE (STRINGS ${_CRYPTOPP_VERSION_HEADER} _CRYPTOPP_VERSION_TMP REGEX + "^#define CRYPTOPP_VERSION[ \t]+[0-9]+$") + + STRING (REGEX REPLACE + "^#define CRYPTOPP_VERSION[ \t]+([0-9]+)" "\\1" _CRYPTOPP_VERSION_TMP + ${_CRYPTOPP_VERSION_TMP}) + + STRING (REGEX REPLACE "([0-9]+)[0-9][0-9]" "\\1" CRYPTOPP_VERSION_MAJOR + ${_CRYPTOPP_VERSION_TMP}) + STRING (REGEX REPLACE "[0-9]([0-9])[0-9]" "\\1" CRYPTOPP_VERSION_MINOR + ${_CRYPTOPP_VERSION_TMP}) + STRING (REGEX REPLACE "[0-9][0-9]([0-9])" "\\1" CRYPTOPP_VERSION_PATCH + ${_CRYPTOPP_VERSION_TMP}) + + SET (CRYPTOPP_VERSION_COUNT 3) + SET (CRYPTOPP_VERSION + ${CRYPTOPP_VERSION_MAJOR}.${CRYPTOPP_VERSION_MINOR}.${CRYPTOPP_VERSION_PATCH}) + ENDIF (EXISTS ${_CRYPTOPP_VERSION_HEADER}) +ENDIF (CRYPTOPP_INCLUDE_DIR) + +SET (CRYPTOPP_INCLUDE_DIRS ${CRYPTOPP_INCLUDE_DIR}) +SET (CRYPTOPP_LIBRARIES ${CRYPTOPP_LIBRARY}) + +MARK_AS_ADVANCED (CRYPTOPP_INCLUDE_DIR CRYPTOPP_LIBRARY CRYPTOPP_LIBRARY_DEBUG + CRYPTOPP_LIBRARY_RELEASE) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS (CryptoPP REQUIRED_VARS CRYPTOPP_ROOT_DIR + CRYPTOPP_INCLUDE_DIR CRYPTOPP_LIBRARY VERSION_VAR CRYPTOPP_VERSION) diff --git a/cmake/FindGMP.cmake b/cmake/FindGMP.cmake new file mode 100644 index 00000000000..5064fda1ed8 --- /dev/null +++ b/cmake/FindGMP.cmake @@ -0,0 +1,127 @@ +# +# - Find GMP/MPIR libraries and headers +# This module defines the following variables: +# +# GMP_FOUND - true if GMP/MPIR was found +# GMP_INCLUDE_DIRS - include search path +# GMP_LIBRARIES - libraries to link with +# GMP_LIBRARY_DLL - library DLL to install. Only available on WIN32. +# GMP_LIBRARIES_DIR - the directory the library we link with is found in. + + +if (ANDROID) + + set( GMP_ROOT ${CMAKE_SOURCE_DIR}/../gmp/${ANDROID_ABI} ) + if (EXISTS ${GMP_ROOT} ) + message("Looking good for ${GMP_ROOT}") + set(GMP_INCLUDE_DIRS ${GMP_ROOT} CACHE PATH "include search path") + set(GMP_LIBRARIES ${GMP_ROOT}/libgmp.so CACHE FILEPATH "include search path") + set(GMP_LIBRARIES_DIR ${GMP_ROOT} CACHE PATH "include search path") + else() + message("Bad call: ${GMP_ROOT} does not exist") + endif() +set( GMP_ROOT ${CMAKE_SOURCE_DIR}/../../gmp/${ANDROID_ABI} ) +if (EXISTS ${GMP_ROOT} ) + message("Looking good for ${GMP_ROOT}") + set(GMP_INCLUDE_DIRS ${GMP_ROOT} CACHE PATH "include search path") + set(GMP_LIBRARIES ${GMP_ROOT}/libgmp.so CACHE FILEPATH "include search path") + set(GMP_LIBRARIES_DIR ${GMP_ROOT} CACHE PATH "include search path") + else() + message("Bad call: ${GMP_ROOT} does not exist") + endif() +find_path(GMP_INCLUDE_DIRS + NAMES gmp.h + HINTS ${GMP_ROOT} + NO_SYSTEM_ENVIRONMENT_PATH) + find_library(GMP_LIBRARIES NAMES gmp + PATHS + ${GMP_ROOT} + NO_SYSTEM_ENVIRONMENT_PATH) + + +elseif(MSVC) + find_library(GMP_LIBRARIES NAMES mpir mpird + PATHS + $ENV{GMP_ROOT} + $ENV{GMP_ROOT}/lib + ${GMP_ROOT} + ${GMP_ROOT}/lib + ${CMAKE_SOURCE_DIR}/../tools/mpir/lib + ${CMAKE_SOURCE_DIR}/../tools/mpird/lib + ${CMAKE_SOURCE_DIR}/../mpir/lib + ${CMAKE_SOURCE_DIR}/../mpird/lib + + $ENV{PROGRAMFILES}/mpir/lib + $ENV{PROGRAMFILES}/mpird/lib + $ENV{HOME}/mpir/lib + $ENV{HOME}/mpird/lib + ${CMAKE_INSTALL_PREFIX}/lib + DOC "Try first the MPIR DLL when in an Windows environment" + ) + + get_filename_component(GMP_LIBRARIES_DIR "${GMP_LIBRARIES}" PATH) + +find_file(GMP_LIBRARY_DLL NAMES mpir.dll mpird.dll + PATHS + ${GMP_LIBRARIES_DIR}/../bin + ${GMP_LIBRARIES_DIR} +) + + find_path(GMP_INCLUDE_DIRS + NAMES mpir.h mpird.h + PATHS + ${GMP_LIBRARIES_DIR}/../include + ${GMP_LIBRARIES_DIR} +) + +else() + +#use GMP, notice that there are two cases, everything is the same directory, or everything is in +#its proper places + + + + find_library(GMP_LIBRARIES + NAMES gmp libgmp + HINTS + . + $ENV{GMP_ROOT} + $ENV{GMP_ROOT}/lib + ${GMP_ROOT} + ${GMP_ROOT}/lib + /usr/local/opt/gmp/lib + /opt/lib + /usr/local/lib + $ENV{HOME}/lib + ${CMAKE_INSTALL_PREFIX}/lib + ) + + + find_path(GMP_INCLUDE_DIRS + NAMES gmp.h + HINTS + . + $ENV{GMP_ROOT} + $ENV{GMP_ROOT}/include + ${GMP_ROOT} + ${GMP_ROOT}/include + ${GMP_LIBRARIES_DIR}/../include + ${GMP_LIBRARIES_DIR} + ) +endif() + +get_filename_component(GMP_LIBRARIES_DIR "${GMP_LIBRARIES}" PATH CACHE) + + +# handle the QUIET and REQUIRED arguments and set GMP_FOUND to TRUE if +# all listed variables are true +include(FindPackageHandleStandardArgs) +if(MSVC) + find_package_handle_standard_args(GMP DEFAULT_MSG GMP_LIBRARIES GMP_LIBRARIES_DIR GMP_LIBRARY_DLL GMP_INCLUDE_DIRS) + mark_as_advanced(GMP_LIBRARY_DLL) +else() + find_package_handle_standard_args(GMP DEFAULT_MSG GMP_LIBRARIES GMP_LIBRARIES_DIR GMP_INCLUDE_DIRS) +endif() + + +mark_as_advanced(GMP_LIBRARIES GMP_LIBRARIES_DIR GMP_INCLUDE_DIRS) diff --git a/cmake/FindLua.cmake b/cmake/FindLua.cmake new file mode 100644 index 00000000000..57a48ebca92 --- /dev/null +++ b/cmake/FindLua.cmake @@ -0,0 +1,118 @@ +# Locate Lua library +# This module defines +# LUA_EXECUTABLE, if found +# LUA_FOUND, if false, do not try to link to Lua +# LUA_LIBRARIES +# LUA_INCLUDE_DIR, where to find lua.h +# LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8) +# +# Note that the expected include convention is +# #include "lua.h" +# and not +# #include +# This is because, the lua location is not standardized and may exist +# in locations other than lua/ + +#============================================================================= +# Copyright 2007-2009 Kitware, Inc. +# Modified to support Lua 5.2 by LuaDist 2012 +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) +# +# The required version of Lua can be specified using the +# standard syntax, e.g. FIND_PACKAGE(Lua 5.1) +# Otherwise the module will search for any available Lua implementation + +# Always search for non-versioned lua first (recommended) +SET(_POSSIBLE_LUA_INCLUDE include include/lua) +SET(_POSSIBLE_LUA_EXECUTABLE lua) +SET(_POSSIBLE_LUA_LIBRARY lua) + +# Determine possible naming suffixes (there is no standard for this) +IF(Lua_FIND_VERSION_MAJOR AND Lua_FIND_VERSION_MINOR) + SET(_POSSIBLE_SUFFIXES "${Lua_FIND_VERSION_MAJOR}${Lua_FIND_VERSION_MINOR}" "${Lua_FIND_VERSION_MAJOR}.${Lua_FIND_VERSION_MINOR}" "-${Lua_FIND_VERSION_MAJOR}.${Lua_FIND_VERSION_MINOR}") +ELSE(Lua_FIND_VERSION_MAJOR AND Lua_FIND_VERSION_MINOR) + SET(_POSSIBLE_SUFFIXES "52" "5.2" "-5.2" "51" "5.1" "-5.1") +ENDIF(Lua_FIND_VERSION_MAJOR AND Lua_FIND_VERSION_MINOR) + +# Set up possible search names and locations +FOREACH(_SUFFIX ${_POSSIBLE_SUFFIXES}) + LIST(APPEND _POSSIBLE_LUA_INCLUDE "include/lua${_SUFFIX}") + LIST(APPEND _POSSIBLE_LUA_EXECUTABLE "lua${_SUFFIX}") + LIST(APPEND _POSSIBLE_LUA_LIBRARY "lua${_SUFFIX}") +ENDFOREACH(_SUFFIX) + +# Find the lua executable +FIND_PROGRAM(LUA_EXECUTABLE + NAMES ${_POSSIBLE_LUA_EXECUTABLE} +) + +# Find the lua header +FIND_PATH(LUA_INCLUDE_DIR lua.h + HINTS + $ENV{LUA_DIR} + PATH_SUFFIXES ${_POSSIBLE_LUA_INCLUDE} + PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local + /usr + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt +) + +# Find the lua library +FIND_LIBRARY(LUA_LIBRARY + NAMES ${_POSSIBLE_LUA_LIBRARY} + HINTS + $ENV{LUA_DIR} + PATH_SUFFIXES lib64 lib + PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local + /usr + /sw + /opt/local + /opt/csw + /opt +) + +IF(LUA_LIBRARY) + # include the math library for Unix + IF(UNIX AND NOT APPLE) + FIND_LIBRARY(LUA_MATH_LIBRARY m) + SET( LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries") + # For Windows and Mac, don't need to explicitly include the math library + ELSE(UNIX AND NOT APPLE) + SET( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries") + ENDIF(UNIX AND NOT APPLE) +ENDIF(LUA_LIBRARY) + +# Determine Lua version +IF(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h") + FILE(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"") + + STRING(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}") + UNSET(lua_version_str) +ENDIF() + +INCLUDE(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set LUA_FOUND to TRUE if +# all listed variables are TRUE +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua + REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR + VERSION_VAR LUA_VERSION_STRING) + +MARK_AS_ADVANCED(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY LUA_EXECUTABLE) + diff --git a/cmake/FindLuaJIT.cmake b/cmake/FindLuaJIT.cmake new file mode 100644 index 00000000000..9ae91c25ef0 --- /dev/null +++ b/cmake/FindLuaJIT.cmake @@ -0,0 +1,62 @@ +# Locate LuaJIT library +# This module defines +# LUAJIT_FOUND, if false, do not try to link to Lua +# LUA_LIBRARIES +# LUA_INCLUDE_DIR, where to find lua.h +# LUAJIT_VERSION_STRING, the version of Lua found (since CMake 2.8.8) + +## Copied from default CMake FindLua51.cmake + +find_path(LUA_INCLUDE_DIR luajit.h + HINTS + ENV LUA_DIR + PATH_SUFFIXES include/luajit-2.0 include/luajit-2.1 include luajit + PATHS + ~/Library/Frameworks + /Library/Frameworks + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt +) + +find_library(LUA_LIBRARY + NAMES luajit-5.1 lua51 + HINTS + ENV LUA_DIR + PATH_SUFFIXES lib + PATHS + ~/Library/Frameworks + /Library/Frameworks + /sw + /opt/local + /opt/csw + /opt +) + +if(LUA_LIBRARY) + # include the math library for Unix + if(UNIX AND NOT APPLE) + find_library(LUA_MATH_LIBRARY m) + set( LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries") + # For Windows and Mac, don't need to explicitly include the math library + else() + set( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries") + endif() +endif() + +if(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/luajit.h") + file(STRINGS "${LUA_INCLUDE_DIR}/luajit.h" luajit_version_str REGEX "^#define[ \t]+LUAJIT_VERSION[ \t]+\"LuaJIT .+\"") + + string(REGEX REPLACE "^#define[ \t]+LUAJIT_VERSION[ \t]+\"LuaJIT ([^\"]+)\".*" "\\1" LUAJIT_VERSION_STRING "${luajit_version_str}") + unset(luajit_version_str) +endif() + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set LUA_FOUND to TRUE if +# all listed variables are TRUE +FIND_PACKAGE_HANDLE_STANDARD_ARGS(LuaJIT + REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR + VERSION_VAR LUAJIT_VERSION_STRING) + +mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY) diff --git a/cmake/FindMySQL.cmake b/cmake/FindMySQL.cmake new file mode 100644 index 00000000000..e96b1e27d53 --- /dev/null +++ b/cmake/FindMySQL.cmake @@ -0,0 +1,124 @@ +#-------------------------------------------------------- +# Copyright (C) 1995-2007 MySQL AB +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# There are special exceptions to the terms and conditions of the GPL +# as it is applied to this software. View the full text of the exception +# in file LICENSE.exceptions in the top-level directory of this software +# distribution. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# The MySQL Connector/ODBC is licensed under the terms of the +# GPL, like most MySQL Connectors. There are special exceptions +# to the terms and conditions of the GPL as it is applied to +# this software, see the FLOSS License Exception available on +# mysql.com. + +########################################################################## + + +#-------------- FIND MYSQL_INCLUDE_DIR ------------------ +FIND_PATH(MYSQL_INCLUDE_DIR mysql.h + $ENV{MYSQL_INCLUDE_DIR} + $ENV{MYSQL_DIR}/include + /usr/include/mysql + /usr/local/include/mysql + /opt/mysql/mysql/include + /opt/mysql/mysql/include/mysql + /opt/mysql/include + /opt/local/include/mysql5 + /usr/local/mysql/include + /usr/local/mysql/include/mysql + $ENV{ProgramFiles}/MySQL/*/include + $ENV{SystemDrive}/MySQL/*/include + PATH_SUFFIXES mysql) + +#----------------- FIND MYSQL_LIB_DIR ------------------- +IF (WIN32) + # Set lib path suffixes + # dist = for mysql binary distributions + # build = for custom built tree + IF (CMAKE_BUILD_TYPE STREQUAL Debug) + SET(libsuffixDist debug) + SET(libsuffixBuild Debug) + ELSE (CMAKE_BUILD_TYPE STREQUAL Debug) + SET(libsuffixDist opt) + SET(libsuffixBuild Release) + ADD_DEFINITIONS(-DDBUG_OFF) + ENDIF (CMAKE_BUILD_TYPE STREQUAL Debug) + + FIND_LIBRARY(MYSQL_LIB NAMES mysqlclient libmariadb + PATHS + $ENV{MYSQL_DIR}/lib/${libsuffixDist} + $ENV{MYSQL_DIR}/libmysql + $ENV{MYSQL_DIR}/libmysql/${libsuffixBuild} + $ENV{MYSQL_DIR}/client/${libsuffixBuild} + $ENV{MYSQL_DIR}/libmysql/${libsuffixBuild} + $ENV{ProgramFiles}/MySQL/*/lib/${libsuffixDist} + $ENV{SystemDrive}/MySQL/*/lib/${libsuffixDist}) +ELSE (WIN32) + FIND_LIBRARY(MYSQL_LIB NAMES mysqlclient mariadbclient libmariadb libmariadbclient + PATHS + $ENV{MYSQL_DIR}/libmysql/.libs + $ENV{MYSQL_DIR}/lib + $ENV{MYSQL_DIR}/lib/mysql + /usr/lib/mysql + /usr/local/lib/mysql + /usr/local/mysql/lib + /usr/local/mysql/lib/mysql + /opt/local/mysql5/lib + /opt/local/lib/mysql5/mysql + /opt/mysql/mysql/lib/mysql + /opt/mysql/lib/mysql) +ENDIF (WIN32) + +IF(MYSQL_LIB) + GET_FILENAME_COMPONENT(MYSQL_LIB_DIR ${MYSQL_LIB} PATH) +ENDIF(MYSQL_LIB) + +IF (MYSQL_INCLUDE_DIR AND MYSQL_LIB_DIR) + SET(MYSQL_FOUND TRUE) + + INCLUDE_DIRECTORIES(${MYSQL_INCLUDE_DIR}) + LINK_DIRECTORIES(${MYSQL_LIB_DIR}) + + FIND_LIBRARY(MYSQL_ZLIB zlib PATHS ${MYSQL_LIB_DIR}) + FIND_LIBRARY(MYSQL_YASSL yassl PATHS ${MYSQL_LIB_DIR}) + FIND_LIBRARY(MYSQL_TAOCRYPT taocrypt PATHS ${MYSQL_LIB_DIR}) + SET(MYSQL_CLIENT_LIBS ${MYSQL_LIB}) + IF (MYSQL_ZLIB) + SET(MYSQL_CLIENT_LIBS ${MYSQL_CLIENT_LIBS} ${MYSQL_ZLIB}) + ENDIF (MYSQL_ZLIB) + IF (MYSQL_YASSL) + SET(MYSQL_CLIENT_LIBS ${MYSQL_CLIENT_LIBS} ${MYSQL_YASSL}) + ENDIF (MYSQL_YASSL) + IF (MYSQL_TAOCRYPT) + SET(MYSQL_CLIENT_LIBS ${MYSQL_CLIENT_LIBS} ${MYSQL_TAOCRYPT}) + ENDIF (MYSQL_TAOCRYPT) + # Add needed mysqlclient dependencies on Windows + IF (WIN32) + SET(MYSQL_CLIENT_LIBS ${MYSQL_CLIENT_LIBS} ws2_32) + ENDIF (WIN32) + IF (APPLE) + SET(MYSQL_CLIENT_LIBS ${MYSQL_CLIENT_LIBS} iconv) + ENDIF (APPLE) + IF (UNIX) + SET(MYSQL_CLIENT_LIBS ${MYSQL_CLIENT_LIBS} "-ldl") + ENDIF (UNIX) + + MESSAGE(STATUS "MySQL Include dir: ${MYSQL_INCLUDE_DIR} library dir: ${MYSQL_LIB_DIR}") + MESSAGE(STATUS "MySQL client libraries: ${MYSQL_CLIENT_LIBS}") +ELSE (MYSQL_INCLUDE_DIR AND MYSQL_LIB_DIR) + MESSAGE(FATAL_ERROR "Cannot find MySQL. Include dir: ${MYSQL_INCLUDE_DIR} library dir: ${MYSQL_LIB_DIR}") +ENDIF (MYSQL_INCLUDE_DIR AND MYSQL_LIB_DIR) diff --git a/cmake/FindPugiXML.cmake b/cmake/FindPugiXML.cmake new file mode 100644 index 00000000000..609a1e247bf --- /dev/null +++ b/cmake/FindPugiXML.cmake @@ -0,0 +1,19 @@ +if(APPLE) + find_package(PkgConfig REQUIRED) + pkg_check_modules(PC_PUGIXML QUIET pugixml) + set(PUGIXML_DEFINITIONS ${PC_PUGIXML_CFLAGS_OTHER}) + + find_path(PUGIXML_INCLUDE_DIR pugixml.hpp HINTS ${PC_PUGIXML_INCLUDEDIR} ${PC_PUGIXML_INCLUDE_DIRS}) + find_library(PUGIXML_LIBRARIES NAMES pugixml HINTS ${PC_PUGIXML_LIBDIR} ${PC_PUGIXML_LIBRARY_DIRS}) +else() + find_path(PUGIXML_INCLUDE_DIR NAMES pugixml.hpp) + if(CMAKE_BUILD_TYPE STREQUAL Debug) + find_library(PUGIXML_LIBRARIES NAMES pugixml_d pugixml) + else() + find_library(PUGIXML_LIBRARIES NAMES pugixml) + endif() +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(PugiXML REQUIRED_VARS PUGIXML_INCLUDE_DIR PUGIXML_LIBRARIES) +mark_as_advanced(PUGIXML_INCLUDE_DIR PUGIXML_LIBRARIES) diff --git a/cmake/LoggingHelper.cmake b/cmake/LoggingHelper.cmake new file mode 100644 index 00000000000..662769b00db --- /dev/null +++ b/cmake/LoggingHelper.cmake @@ -0,0 +1,27 @@ +function(log_info MSG) + message(STATUS "${MsgOk}${MSG}${MsgClr}") +endfunction() + +function(log_war MSG) + message(STATUS "${MsgWar}${MSG}${MsgClr}") +endfunction() + +function(log_err MSG) + message(SEND_ERROR "${MsgErr}${MSG}${MsgClr}") +endfunction() + +function(log_fatal MSG) + message(FATAL_ERROR "${MsgErr}${MSG}${MsgClr}") +endfunction() + +function(log_option_enabled OPTION) + message(STATUS "${MsgBold}Enabled:${MsgClr} ${MsgOk}${OPTION}${MsgClr}") +endfunction() + +function(log_option_disabled OPTION) + message(STATUS "${MsgBold}Disabled:${MsgClr} ${MsgWar}${OPTION}${MsgClr}") +endfunction() + +function(log_program_missing PROGRAM) + message(SEND_ERROR "${MsgErr}Unable to find ${PROGRAM}${MsgClr}") +endfunction() diff --git a/cmake/MessageColors.cmake b/cmake/MessageColors.cmake new file mode 100644 index 00000000000..fa14557c67b --- /dev/null +++ b/cmake/MessageColors.cmake @@ -0,0 +1,13 @@ +if(NOT WIN32) + string(ASCII 27 Esc) + set(ColorReset "${Esc}[m") + set(ColorBold "${Esc}[1m") + set(ColorRed "${Esc}[31m") + set(ColorYellow "${Esc}[33m") + set(ColorGreen "${Esc}[32m") + + set(MsgErr "${ColorRed}${ColorBold}") + set(MsgWar "${ColorYellow}${ColorBold}") + set(MsgOk "${ColorGreen}${ColorBold}") + set(MsgClr "${ColorReset}") +endif() diff --git a/cmake/git_watcher.cmake b/cmake/git_watcher.cmake new file mode 100644 index 00000000000..6f4365535f3 --- /dev/null +++ b/cmake/git_watcher.cmake @@ -0,0 +1,295 @@ +# git_watcher.cmake +# https://raw.githubusercontent.com/andrew-hardin/cmake-git-version-tracking/master/git_watcher.cmake +# +# Released under the MIT License. +# https://raw.githubusercontent.com/andrew-hardin/cmake-git-version-tracking/master/LICENSE + + +# This file defines a target that monitors the state of a git repo. +# If the state changes (e.g. a commit is made), then a file gets reconfigured. +# Here are the primary variables that control script behavior: +# +# PRE_CONFIGURE_FILE (REQUIRED) +# -- The path to the file that'll be configured. +# +# POST_CONFIGURE_FILE (REQUIRED) +# -- The path to the configured PRE_CONFIGURE_FILE. +# +# GIT_STATE_FILE (OPTIONAL) +# -- The path to the file used to store the previous build's git state. +# Defaults to the current binary directory. +# +# GIT_WORKING_DIR (OPTIONAL) +# -- The directory from which git commands will be run. +# Defaults to the directory with the top level CMakeLists.txt. +# +# GIT_EXECUTABLE (OPTIONAL) +# -- The path to the git executable. It'll automatically be set if the +# user doesn't supply a path. +# +# DESIGN +# - This script was designed similar to a Python application +# with a Main() function. I wanted to keep it compact to +# simplify "copy + paste" usage. +# +# - This script is invoked under two CMake contexts: +# 1. Configure time (when build files are created). +# 2. Build time (called via CMake -P). +# The first invocation is what registers the script to +# be executed at build time. +# +# MODIFICATIONS +# You may wish to track other git properties like when the last +# commit was made. There are two sections you need to modify, +# and they're tagged with a ">>>" header. + +# Short hand for converting paths to absolute. +macro(PATH_TO_ABSOLUTE var_name) + get_filename_component(${var_name} "${${var_name}}" ABSOLUTE) +endmacro() + +# Check that a required variable is set. +macro(CHECK_REQUIRED_VARIABLE var_name) + if(NOT DEFINED ${var_name}) + message(FATAL_ERROR "The \"${var_name}\" variable must be defined.") + endif() + PATH_TO_ABSOLUTE(${var_name}) +endmacro() + +# Check that an optional variable is set, or, set it to a default value. +macro(CHECK_OPTIONAL_VARIABLE var_name default_value) + if(NOT DEFINED ${var_name}) + set(${var_name} ${default_value}) + endif() + PATH_TO_ABSOLUTE(${var_name}) +endmacro() + +CHECK_REQUIRED_VARIABLE(PRE_CONFIGURE_FILE) +CHECK_REQUIRED_VARIABLE(POST_CONFIGURE_FILE) +CHECK_OPTIONAL_VARIABLE(GIT_STATE_FILE "${CMAKE_BINARY_DIR}/git-state-hash") +CHECK_OPTIONAL_VARIABLE(GIT_WORKING_DIR "${CMAKE_SOURCE_DIR}") + +# Check the optional git variable. +# If it's not set, we'll try to find it using the CMake packaging system. +if(NOT DEFINED GIT_EXECUTABLE) + find_package(Git QUIET) + if (NOT Git_FOUND) + return() + endif() +endif() +CHECK_REQUIRED_VARIABLE(GIT_EXECUTABLE) + + +set(_state_variable_names + GIT_RETRIEVED_STATE + GIT_HEAD_SHA1 + GIT_IS_DIRTY + GIT_AUTHOR_NAME + GIT_AUTHOR_EMAIL + GIT_COMMIT_DATE_ISO8601 + GIT_COMMIT_SUBJECT + GIT_COMMIT_BODY + # GIT_SHORT_SHA1 + # GIT_DESCRIBE + # >>> + # 1. Add the name of the additional git variable you're interested in monitoring + # to this list. +) + + + +# Macro: RunGitCommand +# Description: short-hand macro for calling a git function. Outputs are the +# "exit_code" and "output" variables. +macro(RunGitCommand) + execute_process(COMMAND + "${GIT_EXECUTABLE}" ${ARGV} + WORKING_DIRECTORY "${_working_dir}" + RESULT_VARIABLE exit_code + OUTPUT_VARIABLE output + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT exit_code EQUAL 0) + set(ENV{GIT_RETRIEVED_STATE} "false") + endif() +endmacro() + + + +# Function: GetGitState +# Description: gets the current state of the git repo. +# Args: +# _working_dir (in) string; the directory from which git commands will be executed. +function(GetGitState _working_dir) + + # This is an error code that'll be set to FALSE if the + # RunGitCommand ever returns a non-zero exit code. + set(ENV{GIT_RETRIEVED_STATE} "true") + + # Get whether or not the working tree is dirty. + RunGitCommand(status --porcelain) + if(NOT exit_code EQUAL 0) + set(ENV{GIT_IS_DIRTY} "false") + else() + if(NOT "${output}" STREQUAL "") + set(ENV{GIT_IS_DIRTY} "true") + else() + set(ENV{GIT_IS_DIRTY} "false") + endif() + endif() + + # There's a long list of attributes grabbed from git show. + set(object HEAD) + RunGitCommand(show -s "--format=%H" ${object}) + if(exit_code EQUAL 0) + set(ENV{GIT_HEAD_SHA1} ${output}) + endif() + + RunGitCommand(show -s "--format=%an" ${object}) + if(exit_code EQUAL 0) + set(ENV{GIT_AUTHOR_NAME} "${output}") + endif() + + RunGitCommand(show -s "--format=%ae" ${object}) + if(exit_code EQUAL 0) + set(ENV{GIT_AUTHOR_EMAIL} "${output}") + endif() + + RunGitCommand(show -s "--format=%cI" ${object}) + if(exit_code EQUAL 0) + set(ENV{GIT_COMMIT_DATE_ISO8601} "${output}") + endif() + + RunGitCommand(show -s "--format=%s" ${object}) + if(exit_code EQUAL 0) + set(ENV{GIT_COMMIT_SUBJECT} "${output}") + endif() + + RunGitCommand(show -s "--format=%b" ${object}) + if(exit_code EQUAL 0) + set(ENV{GIT_COMMIT_BODY} "${output}") + endif() + + # RunGitCommand(rev-parse --short ${object}) + # if(exit_code EQUAL 0) + # set(ENV{GIT_SHORT_SHA1} ${output}) + # endif() + + # RunGitCommand(describe --tags "--match=v*" ${object}) + # if(exit_code EQUAL 0) + # set(ENV{GIT_DESCRIBE} "${output}") + # endif() + + # >>> + # 2. Additional git properties can be added here via the + # "execute_process()" command. Be sure to set them in + # the environment using the same variable name you added + # to the "_state_variable_names" list. + +endfunction() + + + +# Function: GitStateChangedAction +# Description: this function is executed when the state of the git +# repository changes (e.g. a commit is made). +function(GitStateChangedAction) + foreach(var_name ${_state_variable_names}) + set(${var_name} $ENV{${var_name}}) + endforeach() + configure_file("${PRE_CONFIGURE_FILE}" "${POST_CONFIGURE_FILE}" @ONLY) +endfunction() + + + +# Function: HashGitState +# Description: loop through the git state variables and compute a unique hash. +# Args: +# _state (out) string; a hash computed from the current git state. +function(HashGitState _state) + set(ans "") + foreach(var_name ${_state_variable_names}) + string(SHA256 ans "${ans}$ENV{${var_name}}") + endforeach() + set(${_state} ${ans} PARENT_SCOPE) +endfunction() + + + +# Function: CheckGit +# Description: check if the git repo has changed. If so, update the state file. +# Args: +# _working_dir (in) string; the directory from which git commands will be ran. +# _state_changed (out) bool; whether or no the state of the repo has changed. +function(CheckGit _working_dir _state_changed) + + # Get the current state of the repo. + GetGitState("${_working_dir}") + + # Convert that state into a hash that we can compare against + # the hash stored on-disk. + HashGitState(state) + + # Check if the state has changed compared to the backup on disk. + if(EXISTS "${GIT_STATE_FILE}") + file(READ "${GIT_STATE_FILE}" OLD_HEAD_CONTENTS) + if(OLD_HEAD_CONTENTS STREQUAL "${state}") + # State didn't change. + set(${_state_changed} "false" PARENT_SCOPE) + return() + endif() + endif() + + # The state has changed. + # We need to update the state file on disk. + # Future builds will compare their state to this file. + file(WRITE "${GIT_STATE_FILE}" "${state}") + set(${_state_changed} "true" PARENT_SCOPE) +endfunction() + + + +# Function: SetupGitMonitoring +# Description: this function sets up custom commands that make the build system +# check the state of git before every build. If the state has +# changed, then a file is configured. +function(SetupGitMonitoring) + add_custom_target(check_git + ALL + DEPENDS ${PRE_CONFIGURE_FILE} + BYPRODUCTS + ${POST_CONFIGURE_FILE} + ${GIT_STATE_FILE} + COMMENT "Checking the git repository for changes..." + COMMAND + ${CMAKE_COMMAND} + -D_BUILD_TIME_CHECK_GIT=TRUE + -DGIT_WORKING_DIR=${GIT_WORKING_DIR} + -DGIT_EXECUTABLE=${GIT_EXECUTABLE} + -DGIT_STATE_FILE=${GIT_STATE_FILE} + -DPRE_CONFIGURE_FILE=${PRE_CONFIGURE_FILE} + -DPOST_CONFIGURE_FILE=${POST_CONFIGURE_FILE} + -P "${CMAKE_CURRENT_LIST_FILE}") +endfunction() + + + +# Function: Main +# Description: primary entry-point to the script. Functions are selected based +# on whether it's configure or build time. +function(Main) + if(_BUILD_TIME_CHECK_GIT) + # Check if the repo has changed. + # If so, run the change action. + CheckGit("${GIT_WORKING_DIR}" changed) + if(changed OR NOT EXISTS "${POST_CONFIGURE_FILE}") + GitStateChangedAction() + endif() + else() + # >> Executes at configure time. + SetupGitMonitoring() + endif() +endfunction() + +# And off we go... +Main() diff --git a/cmake/gitmetadata.h.in b/cmake/gitmetadata.h.in new file mode 100644 index 00000000000..d6fda7bf4e1 --- /dev/null +++ b/cmake/gitmetadata.h.in @@ -0,0 +1,20 @@ +// This file was created automatically by CMake. +#pragma once + +// Whether or not we retrieved the state of the repo. +#define GIT_RETRIEVED_STATE @GIT_RETRIEVED_STATE@ + +// The SHA1 for the HEAD of the repo. +#define GIT_HEAD_SHA1 "@GIT_HEAD_SHA1@" + +// Whether or not there were uncommited changes present. +#define GIT_IS_DIRTY @GIT_IS_DIRTY@ + +// When HEAD was committed. +#define GIT_COMMIT_DATE_ISO8601 "@GIT_COMMIT_DATE_ISO8601@" + +// git rev-parse --short HEAD +// #define GIT_SHORT_SHA1 "@GIT_SHORT_SHA1@" + +// git describe --tags --match 'v*' +// #define GIT_DESCRIBE "@GIT_DESCRIBE@" diff --git a/cmake/otservbr-global.ico b/cmake/otservbr-global.ico new file mode 100644 index 00000000000..ec405a77387 Binary files /dev/null and b/cmake/otservbr-global.ico differ diff --git a/cmake/otservbr-global.rc b/cmake/otservbr-global.rc new file mode 100644 index 00000000000..451ad09fabe --- /dev/null +++ b/cmake/otservbr-global.rc @@ -0,0 +1 @@ +MAINICON ICON "otservbr-global.ico" diff --git a/config.lua.dist b/config.lua.dist new file mode 100644 index 00000000000..8fb08c50ec6 --- /dev/null +++ b/config.lua.dist @@ -0,0 +1,181 @@ +-- Combat settings +-- NOTE: valid values for worldType are: "pvp", "no-pvp" and "pvp-enforced" +worldType = "pvp" +hotkeyAimbotEnabled = true +protectionLevel = 7 +pzLocked = 60 * 1000 +removeChargesFromRunes = true +removeChargesFromPotions = true +removeWeaponAmmunition = true +removeWeaponCharges = true +timeToDecreaseFrags = 1 * 24 * 60 * 60 +whiteSkullTime = 15 * 60 * 1000 +stairJumpExhaustion = 2 * 1000 +experienceByKillingPlayers = false +expFromPlayersLevelRange = 75 +dayKillsToRedSkull = 3 +weekKillsToRedSkull = 5 +monthKillsToRedSkull = 10 +redSkullDuration = 1 +blackSkullDuration = 3 +orangeSkullDuration = 7 + +onlyInvitedCanMoveHouseItems = true +cleanProtectionZones = false + +-- Connection Config +-- NOTE: maxPlayers set to 0 means no limit +-- NOTE: MaxPacketsPerSeconds if you change you will be subject to bugs by WPE, keep the default value of 25 +ip = "127.0.0.1" +bindOnlyGlobalAddress = false +loginProtocolPort = 7171 +gameProtocolPort = 7172 +statusProtocolPort = 7171 +maxPlayers = 0 +motd = "Bem vindo ao OTServBR-Global!" +onePlayerOnlinePerAccount = true +allowClones = false +serverName = "OTServBR-Global" +statusTimeout = 5 * 1000 +replaceKickOnLogin = true +maxPacketsPerSecond = 25 +maxItem = 2000 +maxContainer = 100 + +-- Version +clientVersion = 1264 +clientVersionStr = "12.64" + +-- Depot Limit +freeDepotLimit = 2000 +premiumDepotLimit = 10000 +depotBoxes = 18 + +-- GameStore +gamestoreByModules = true + +-- NOTE: Access only for Premium Account +onlyPremiumAccount = false + +-- Customs +weatherRain = false +thunderEffect = false +freeQuests = false +allConsoleLog = false + +-- Deaths +-- NOTE: Leave deathLosePercent as -1 if you want to use the default +-- death penalty formula. For the old formula, set it to 10. For +-- no skill/experience loss, set it to 0. +deathLosePercent = -1 + +-- Houses +-- NOTE: set housePriceEachSQM to -1 to disable the ingame buy house functionality +-- Periods: daily/weekly/monthly/yearly/never +housePriceEachSQM = 1000 +houseRentPeriod = "never" +houseOwnedByAccount = false + +-- Item Usage +timeBetweenActions = 200 +timeBetweenExActions = 1000 + +-- Push Delay +pushDelay = 1000 +pushDistanceDelay = 1500 + +-- Map +-- NOTE: set mapName WITHOUT .otbm at the end +-- NOTE: unzip the map world.rar +mapName = "otservbr" +mapAuthor = "OTServBR" + +-- Party List limitations +-- max distance in which players in party list are visible +-- NOTE partyListMaxDistance set to 0 means no limit +partyListMaxDistance = 30 + +-- Custom Map +-- NOTE: mapCustomEnabled: true = activate the map, false = disable the map +mapCustomName = "otservbr-custom" +mapCustomFile = "data/world/custom/otservbr-custom.otbm" +mapCustomSpawn = "data/world/custom/otservbr-custom-spawn.xml" +mapCustomAuthor = "OTServBR" +mapCustomEnabled = true + +-- Market +marketOfferDuration = 30 * 24 * 60 * 60 +premiumToCreateMarketOffer = true +checkExpiredMarketOffersEachMinutes = 60 +maxMarketOffersAtATimePerPlayer = 100 + +-- MySQL +mysqlHost = "127.0.0.1" +mysqlUser = "root" +mysqlPass = "" +mysqlDatabase = "otservbr-global" +mysqlPort = 3306 +mysqlSock = "" + +-- Misc. +allowChangeOutfit = true +freePremium = false +kickIdlePlayerAfterMinutes = 15 +maxMessageBuffer = 4 +emoteSpells = false +classicEquipmentSlots = false +allowWalkthrough = true +coinPacketSize = 25 +coinImagesURL = "http://127.0.0.1/images/store/" +classicAttackSpeed = false +showScriptsLogInConsole = false + +-- Server Save +-- NOTE: serverSaveNotifyDuration in minutes +serverSaveNotifyMessage = true +serverSaveNotifyDuration = 5 +serverSaveCleanMap = false +serverSaveClose = false +serverSaveShutdown = true + +-- Rates +-- NOTE: rateExp, rateSkill and rateMagic is used as a fallback only +-- To configure rates see file data/stages.lua +rateExp = 1 +rateSkill = 50 +rateLoot = 3 +rateMagic = 25 +rateSpawn = 1 + +-- Monster rates +rateMonsterHealth = 1.0 +rateMonsterAttack = 1.0 +rateMonsterDefense = 1.0 + +-- Monsters +deSpawnRange = 2 +deSpawnRadius = 50 + +-- Stamina +staminaSystem = true + +-- Scripts +warnUnsafeScripts = true +convertUnsafeScripts = true + +-- Startup +-- NOTE: defaultPriority only works on Windows and sets process +-- priority, valid values are: "normal", "above-normal", "high" +defaultPriority = "high" +startupDatabaseOptimization = true + +-- Status server information +ownerName = "OTServBR-Global" +ownerEmail = "" +url = "https://github.com/opentibiabr/otservbr-global" +location = "South America" + +-- Sends Discord webhook notifications on startup, raids and shutdown. +-- The URL layout is https://discord.com/api/webhooks/:id/:token +-- Leave empty if you wish to disable. +discordWebhookURL = "" diff --git a/data/XML/events.xml b/data/XML/events.xml new file mode 100644 index 00000000000..6cec9c04060 --- /dev/null +++ b/data/XML/events.xml @@ -0,0 +1,15 @@ + + + + + + +
+ + + + + +
+ + diff --git a/data/XML/familiars.xml b/data/XML/familiars.xml new file mode 100644 index 00000000000..3c446167b5b --- /dev/null +++ b/data/XML/familiars.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/XML/groups.xml b/data/XML/groups.xml new file mode 100644 index 00000000000..64f1c61537b --- /dev/null +++ b/data/XML/groups.xml @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/XML/imbuements.xml b/data/XML/imbuements.xml new file mode 100644 index 00000000000..21a62b8d5cf --- /dev/null +++ b/data/XML/imbuements.xml @@ -0,0 +1,434 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/XML/mounts.xml b/data/XML/mounts.xml new file mode 100644 index 00000000000..52180266c49 --- /dev/null +++ b/data/XML/mounts.xml @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/XML/outfits.xml b/data/XML/outfits.xml new file mode 100644 index 00000000000..1e5276a949b --- /dev/null +++ b/data/XML/outfits.xml @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/XML/vocations.xml b/data/XML/vocations.xml new file mode 100644 index 00000000000..c5639911395 --- /dev/null +++ b/data/XML/vocations.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/chatchannels/chatchannels.xml b/data/chatchannels/chatchannels.xml new file mode 100644 index 00000000000..e819080856b --- /dev/null +++ b/data/chatchannels/chatchannels.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/data/chatchannels/scripts/advertising-rook.lua b/data/chatchannels/scripts/advertising-rook.lua new file mode 100644 index 00000000000..e652a2423d9 --- /dev/null +++ b/data/chatchannels/scripts/advertising-rook.lua @@ -0,0 +1,40 @@ +function canJoin(player) + return player:getVocation():getId() == VOCATION_NONE or player:getAccountType() >= ACCOUNT_TYPE_SENIORTUTOR +end + +local CHANNEL_ADVERTISING_ROOK = 6 + +local muted = Condition(CONDITION_CHANNELMUTEDTICKS, CONDITIONID_DEFAULT) +muted:setParameter(CONDITION_PARAM_SUBID, CHANNEL_ADVERTISING_ROOK) +muted:setParameter(CONDITION_PARAM_TICKS, 120000) + +function onSpeak(player, type, message) + if player:getAccountType() >= ACCOUNT_TYPE_GAMEMASTER then + if type == TALKTYPE_CHANNEL_Y then + return TALKTYPE_CHANNEL_O + end + return true + end + + if player:getLevel() == 1 then + player:sendCancelMessage("You may not speak into channels as long as you are on level 1.") + return false + end + + if player:getCondition(CONDITION_CHANNELMUTEDTICKS, CONDITIONID_DEFAULT, CHANNEL_ADVERTISING_ROOK) then + player:sendCancelMessage("You may only place one offer in two minutes.") + return false + end + player:addCondition(muted) + + if type == TALKTYPE_CHANNEL_O then + if player:getAccountType() < ACCOUNT_TYPE_GAMEMASTER then + type = TALKTYPE_CHANNEL_Y + end + elseif type == TALKTYPE_CHANNEL_R1 then + if not player:hasFlag(PlayerFlag_CanTalkRedChannel) then + type = TALKTYPE_CHANNEL_Y + end + end + return type +end diff --git a/data/chatchannels/scripts/advertising.lua b/data/chatchannels/scripts/advertising.lua new file mode 100644 index 00000000000..0998faa203a --- /dev/null +++ b/data/chatchannels/scripts/advertising.lua @@ -0,0 +1,40 @@ +function canJoin(player) + return player:getVocation():getId() ~= VOCATION_NONE or player:getAccountType() >= ACCOUNT_TYPE_SENIORTUTOR +end + +local CHANNEL_ADVERTISING = 5 + +local muted = Condition(CONDITION_CHANNELMUTEDTICKS, CONDITIONID_DEFAULT) +muted:setParameter(CONDITION_PARAM_SUBID, CHANNEL_ADVERTISING) +muted:setParameter(CONDITION_PARAM_TICKS, 120000) + +function onSpeak(player, type, message) + if player:getAccountType() >= ACCOUNT_TYPE_GAMEMASTER then + if type == TALKTYPE_CHANNEL_Y then + return TALKTYPE_CHANNEL_O + end + return true + end + + if player:getLevel() == 1 then + player:sendCancelMessage("You may not speak into channels as long as you are on level 1.") + return false + end + + if player:getCondition(CONDITION_CHANNELMUTEDTICKS, CONDITIONID_DEFAULT, CHANNEL_ADVERTISING) then + player:sendCancelMessage("You may only place one offer in two minutes.") + return false + end + player:addCondition(muted) + + if type == TALKTYPE_CHANNEL_O then + if player:getAccountType() < ACCOUNT_TYPE_GAMEMASTER then + type = TALKTYPE_CHANNEL_Y + end + elseif type == TALKTYPE_CHANNEL_R1 then + if not player:hasFlag(PlayerFlag_CanTalkRedChannel) then + type = TALKTYPE_CHANNEL_Y + end + end + return type +end diff --git a/data/chatchannels/scripts/english_chat.lua b/data/chatchannels/scripts/english_chat.lua new file mode 100644 index 00000000000..42517d2a591 --- /dev/null +++ b/data/chatchannels/scripts/english_chat.lua @@ -0,0 +1,22 @@ +function onSpeak(player, type, message) + local playerAccountType = player:getAccountType() + if player:getLevel() == 1 and playerAccountType < ACCOUNT_TYPE_GAMEMASTER then + player:sendCancelMessage("You may not speak into channels as long as you are on level 1.") + return false + end + + if type == TALKTYPE_CHANNEL_Y then + if playerAccountType >= ACCOUNT_TYPE_GAMEMASTER then + type = TALKTYPE_CHANNEL_O + end + elseif type == TALKTYPE_CHANNEL_O then + if playerAccountType < ACCOUNT_TYPE_GAMEMASTER then + type = TALKTYPE_CHANNEL_Y + end + elseif type == TALKTYPE_CHANNEL_R1 then + if playerAccountType < ACCOUNT_TYPE_GAMEMASTER and not player:hasFlag(PlayerFlag_CanTalkRedChannel) then + type = TALKTYPE_CHANNEL_Y + end + end + return type +end diff --git a/data/chatchannels/scripts/gamemaster.lua b/data/chatchannels/scripts/gamemaster.lua new file mode 100644 index 00000000000..19725eef33c --- /dev/null +++ b/data/chatchannels/scripts/gamemaster.lua @@ -0,0 +1,21 @@ +function canJoin(player) + return player:getAccountType() >= ACCOUNT_TYPE_GAMEMASTER +end + +function onSpeak(player, type, message) + local playerAccountType = player:getAccountType() + if type == TALKTYPE_CHANNEL_Y then + if playerAccountType == ACCOUNT_TYPE_GOD then + type = TALKTYPE_CHANNEL_O + end + elseif type == TALKTYPE_CHANNEL_O then + if playerAccountType ~= ACCOUNT_TYPE_GOD then + type = TALKTYPE_CHANNEL_Y + end + elseif type == TALKTYPE_CHANNEL_R1 then + if playerAccountType ~= ACCOUNT_TYPE_GOD and not player:hasFlag(PlayerFlag_CanTalkRedChannel) then + type = TALKTYPE_CHANNEL_Y + end + end + return type +end diff --git a/data/chatchannels/scripts/guild_leaders.lua b/data/chatchannels/scripts/guild_leaders.lua new file mode 100644 index 00000000000..bd0dcdc930c --- /dev/null +++ b/data/chatchannels/scripts/guild_leaders.lua @@ -0,0 +1,20 @@ +function canJoin(player) + return player:getGuildLevel() == 3 or player:getGroup():getAccess() +end + +function onSpeak(player, type, message) + local staff = player:getGroup():getAccess() + local guild = player:getGuild() + local info = "staff" + type = TALKTYPE_CHANNEL_Y + if staff then + if guild then + info = info .. "][" .. guild:getName() + end + type = TALKTYPE_CHANNEL_O + else + info = guild:getName() + end + sendChannelMessage(10, type, player:getName() .. " [" .. info .. "]: " .. message) + return false +end diff --git a/data/chatchannels/scripts/help.lua b/data/chatchannels/scripts/help.lua new file mode 100644 index 00000000000..e8da2f5d0aa --- /dev/null +++ b/data/chatchannels/scripts/help.lua @@ -0,0 +1,80 @@ +local CHANNEL_HELP = 7 +local storage = 456112 + +local muted = Condition(CONDITION_CHANNELMUTEDTICKS, CONDITIONID_DEFAULT) +muted:setParameter(CONDITION_PARAM_SUBID, CHANNEL_HELP) +muted:setParameter(CONDITION_PARAM_TICKS, 3600000) + +function onSpeak(player, type, message) + local playerAccountType = player:getAccountType() + if player:getLevel() == 1 and playerAccountType == ACCOUNT_TYPE_NORMAL then + player:sendCancelMessage("You may not speak into channels as long as you are on level 1.") + return false + end + + if player:getStorageValue(storage) > os.time() then + player:sendCancelMessage("You are muted from the Help channel for using it inappropriately.") + return false + end + + if playerAccountType >= ACCOUNT_TYPE_TUTOR then + if string.sub(message, 1, 6) == "!mute " then + local targetName = string.sub(message, 7) + local target = Player(targetName) + if target then + if playerAccountType > target:getAccountType() then + if not target:getCondition(CONDITION_CHANNELMUTEDTICKS, CONDITIONID_DEFAULT, CHANNEL_HELP) then + target:addCondition(muted) + target:setStorageValue(storage, os.time() + 180) + sendChannelMessage(CHANNEL_HELP, TALKTYPE_CHANNEL_R1, target:getName() .. " has been muted by " .. player:getName() .. " for using Help Channel inappropriately.") + else + player:sendCancelMessage("That player is already muted.") + end + else + player:sendCancelMessage("You are not authorized to mute that player.") + end + else + player:sendCancelMessage(RETURNVALUE_PLAYERWITHTHISNAMEISNOTONLINE) + end + return false + elseif string.sub(message, 1, 8) == "!unmute " then + local targetName = string.sub(message, 9) + local target = Player(targetName) + if target then + if playerAccountType > target:getAccountType() then + if target:getStorageValue(storage) > os.time() then + target:removeCondition(CONDITION_CHANNELMUTEDTICKS, CONDITIONID_DEFAULT, CHANNEL_HELP) + sendChannelMessage(CHANNEL_HELP, TALKTYPE_CHANNEL_R1, target:getName() .. " has been unmuted.") + target:setStorageValue(storage, -1) + else + player:sendCancelMessage("That player is not muted.") + end + else + player:sendCancelMessage("You are not authorized to unmute that player.") + end + else + player:sendCancelMessage(RETURNVALUE_PLAYERWITHTHISNAMEISNOTONLINE) + end + return false + end + end + + if type == TALKTYPE_CHANNEL_Y then + if playerAccountType >= ACCOUNT_TYPE_TUTOR or player:hasFlag(PlayerFlag_TalkOrangeHelpChannel) then + type = TALKTYPE_CHANNEL_O + end + elseif type == TALKTYPE_CHANNEL_O then + if playerAccountType < ACCOUNT_TYPE_TUTOR and not player:hasFlag(PlayerFlag_TalkOrangeHelpChannel) then + type = TALKTYPE_CHANNEL_Y + end + elseif type == TALKTYPE_CHANNEL_R1 then + if playerAccountType < ACCOUNT_TYPE_GAMEMASTER and not player:hasFlag(PlayerFlag_CanTalkRedChannel) then + if playerAccountType >= ACCOUNT_TYPE_TUTOR or player:hasFlag(PlayerFlag_TalkOrangeHelpChannel) then + type = TALKTYPE_CHANNEL_O + else + type = TALKTYPE_CHANNEL_Y + end + end + end + return type +end diff --git a/data/chatchannels/scripts/loot.lua b/data/chatchannels/scripts/loot.lua new file mode 100644 index 00000000000..172e6458b44 --- /dev/null +++ b/data/chatchannels/scripts/loot.lua @@ -0,0 +1,7 @@ +function canJoin() + return true +end + +function onSpeak() + return false +end diff --git a/data/chatchannels/scripts/tutor.lua b/data/chatchannels/scripts/tutor.lua new file mode 100644 index 00000000000..9928fef9e7a --- /dev/null +++ b/data/chatchannels/scripts/tutor.lua @@ -0,0 +1,21 @@ +function canJoin(player) + return player:getAccountType() >= ACCOUNT_TYPE_TUTOR +end + +function onSpeak(player, type, message) + local playerAccountType = player:getAccountType() + if type == TALKTYPE_CHANNEL_Y then + if playerAccountType >= ACCOUNT_TYPE_SENIORTUTOR then + type = TALKTYPE_CHANNEL_O + end + elseif type == TALKTYPE_CHANNEL_O then + if playerAccountType < ACCOUNT_TYPE_SENIORTUTOR then + type = TALKTYPE_CHANNEL_Y + end + elseif type == TALKTYPE_CHANNEL_R1 then + if playerAccountType < ACCOUNT_TYPE_GAMEMASTER and not player:hasFlag(PlayerFlag_CanTalkRedChannel) then + type = TALKTYPE_CHANNEL_Y + end + end + return type +end diff --git a/data/chatchannels/scripts/world_chat.lua b/data/chatchannels/scripts/world_chat.lua new file mode 100644 index 00000000000..42517d2a591 --- /dev/null +++ b/data/chatchannels/scripts/world_chat.lua @@ -0,0 +1,22 @@ +function onSpeak(player, type, message) + local playerAccountType = player:getAccountType() + if player:getLevel() == 1 and playerAccountType < ACCOUNT_TYPE_GAMEMASTER then + player:sendCancelMessage("You may not speak into channels as long as you are on level 1.") + return false + end + + if type == TALKTYPE_CHANNEL_Y then + if playerAccountType >= ACCOUNT_TYPE_GAMEMASTER then + type = TALKTYPE_CHANNEL_O + end + elseif type == TALKTYPE_CHANNEL_O then + if playerAccountType < ACCOUNT_TYPE_GAMEMASTER then + type = TALKTYPE_CHANNEL_Y + end + elseif type == TALKTYPE_CHANNEL_R1 then + if playerAccountType < ACCOUNT_TYPE_GAMEMASTER and not player:hasFlag(PlayerFlag_CanTalkRedChannel) then + type = TALKTYPE_CHANNEL_Y + end + end + return type +end diff --git a/data/events/events.xml b/data/events/events.xml new file mode 100644 index 00000000000..6482e1cf884 --- /dev/null +++ b/data/events/events.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/events/scripts/creature.lua b/data/events/scripts/creature.lua new file mode 100644 index 00000000000..97f9779fcb8 --- /dev/null +++ b/data/events/scripts/creature.lua @@ -0,0 +1,159 @@ +-- Functions from The Forgotten Server +function Creature:onChangeOutfit(outfit) + if self:isPlayer() then + local familiarLookType = self:getFamiliarLooktype() + if familiarLookType ~= 0 then + for _, summon in pairs(self:getSummons()) do + if summon:getType():isPet() then + if summon:getOutfit().lookType ~= familiarLookType then + summon:setOutfit({lookType = familiarLookType}) + end + break + end + end + end + end + return true +end + +function Creature:onAreaCombat(tile, isAggressive) + return RETURNVALUE_NOERROR +end + +function Creature:onTargetCombat(target) + return RETURNVALUE_NOERROR +end + +function Creature:onHear(speaker, words, type) +end + +-- Functions from OTServBR-Global +function Creature:onAreaCombat(tile, isAggressive) + return true +end + +local function removeCombatProtection(cid) + local player = Player(cid) + if not player then + return true + end + + local time = 0 + if player:isMage() then + time = 10 + elseif player:isPaladin() then + time = 20 + else + time = 30 + end + + player:setStorageValue(Storage.combatProtectionStorage, 2) + addEvent(function(cid) + local player = Player(cid) + if not player then + return + end + + player:setStorageValue(Storage.combatProtectionStorage, 0) + player:remove() + end, time * 1000, cid) +end + +picIf = {} +function Creature:onTargetCombat(target) + if not self then + return true + end + + if not picIf[target.uid] then + if target:isMonster() then + target:registerEvent("RewardSystemSlogan") + picIf[target.uid] = {} + end + end + + if target:isPlayer() then + if self:isMonster() then + local protectionStorage = target:getStorageValue(Storage.combatProtectionStorage) + + if target:getIp() == 0 then -- If player is disconnected, monster shall ignore to attack the player + if target:isPzLocked() then return true end + if protectionStorage <= 0 then + addEvent(removeCombatProtection, 30 * 1000, target.uid) + target:setStorageValue(Storage.combatProtectionStorage, 1) + elseif protectionStorage == 1 then + self:searchTarget() + return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER + end + + return true + end + + if protectionStorage >= os.time() then + return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER + end + end + end + + if ((target:isMonster() and self:isPlayer() and target:getMaster() == self) + or (self:isMonster() and target:isPlayer() and self:getMaster() == target)) then + return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE + end + + if PARTY_PROTECTION ~= 0 then + if self:isPlayer() and target:isPlayer() then + local party = self:getParty() + if party then + local targetParty = target:getParty() + if targetParty and targetParty == party then + return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER + end + end + end + end + + if ADVANCED_SECURE_MODE ~= 0 then + if self:isPlayer() and target:isPlayer() then + if self:hasSecureMode() then + return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER + end + end + end + return true +end + +function Creature:onDrainHealth(attacker, typePrimary, damagePrimary, + typeSecondary, damageSecondary, colorPrimary, colorSecondary) + if (not self) then + return typePrimary, damagePrimary, typeSecondary, damageSecondary, colorPrimary, colorSecondary + end + + if (not attacker) then + return typePrimary, damagePrimary, typeSecondary, damageSecondary, colorPrimary, colorSecondary + end + + -- New prey => Bonus damage + if (attacker:isPlayer()) then + if (self:isMonster() and not self:getMaster()) then + for slot = CONST_PREY_SLOT_FIRST, CONST_PREY_SLOT_THIRD do + if (attacker:getPreyCurrentMonster(slot) == self:getName() + and attacker:getPreyBonusType(slot) == CONST_BONUS_DAMAGE_BOOST) then + damagePrimary = damagePrimary + math.floor(damagePrimary * (attacker:getPreyBonusValue(slot) / 100)) + break + end + end + end + -- New prey => Damage reduction + elseif (attacker:isMonster()) then + if (self:isPlayer()) then + for slot = CONST_PREY_SLOT_FIRST, CONST_PREY_SLOT_THIRD do + if (self:getPreyCurrentMonster(slot) == attacker:getName() + and self:getPreyBonusType(slot) == CONST_BONUS_DAMAGE_REDUCTION) then + damagePrimary = damagePrimary - math.floor(damagePrimary * (self:getPreyBonusValue(slot) / 100)) + break + end + end + end + end + return typePrimary, damagePrimary, typeSecondary, damageSecondary, colorPrimary, colorSecondary +end diff --git a/data/events/scripts/monster.lua b/data/events/scripts/monster.lua new file mode 100644 index 00000000000..e80b5deba0a --- /dev/null +++ b/data/events/scripts/monster.lua @@ -0,0 +1,114 @@ +function Monster:onDropLoot(corpse) + if configManager.getNumber(configKeys.RATE_LOOT) == 0 then + return + end + + local mType = self:getType() + if mType:isRewardBoss() then + corpse:registerReward() + return + end + + local player = Player(corpse:getCorpseOwner()) + local mType = self:getType() + if not player or player:getStamina() > 840 then + local monsterLoot = mType:getLoot() + for i = 1, #monsterLoot do + local boolCharm = false + if player then + local charmType = player:getCharmMonsterType(CHARM_GUT) + if charmType and charmType:raceId() == mType:raceId() then + boolCharm = true + end + end + + local item = corpse:createLootItem(monsterLoot[i], boolCharm) + if self:getName():lower() == (Game.getBoostedCreature()):lower() then + local itemBoosted = corpse:createLootItem(monsterLoot[i], boolCharm) + end + if not item then + Spdlog.warn("[Monster:onDropLoot] - Could not add loot item to corpse.") + end + end + + if player then + local text = {} + if self:getName():lower() == (Game.getBoostedCreature()):lower() then + text = ("Loot of %s: %s (boosted loot)"):format(mType:getNameDescription(), corpse:getContentDescription()) + else + text = ("Loot of %s: %s"):format(mType:getNameDescription(), corpse:getContentDescription()) + end + local party = player:getParty() + if party then + party:broadcastPartyLoot(text) + else + player:sendTextMessage(MESSAGE_LOOT, text) + end + player:updateKillTracker(self, corpse) + end + else + local text = ("Loot of %s: nothing (due to low stamina)"):format(mType:getNameDescription()) + local party = player:getParty() + if party then + party:broadcastPartyLoot(text) + else + player:sendTextMessage(MESSAGE_LOOT, text) + end + end +end + +function Monster:onSpawn(position) + if self:getType():isRewardBoss() then + self:setReward(true) + end + + if self:getName():lower() == "cobra scout" or + self:getName():lower() == "cobra vizier" or + self:getName():lower() == "cobra assassin" then + if getGlobalStorageValue(GlobalStorage.CobraBastionFlask) >= os.time() then + self:setHealth(self:getMaxHealth() * 0.75) + end + end + + if not self:getType():canSpawn(position) then + self:remove() + else + local spec = Game.getSpectators(position, false, false) + for _, pid in pairs(spec) do + local monster = Monster(pid) + if monster and not monster:getType():canSpawn(position) then + monster:remove() + end + end + + if self:getName():lower() == 'iron servant replica' then + local chance = math.random(100) + if Game.getStorageValue(GlobalStorage.ForgottenKnowledge.MechanismDiamond) >= 1 + and Game.getStorageValue(GlobalStorage.ForgottenKnowledge.MechanismGolden) >= 1 then + if chance > 30 then + local chance2 = math.random(2) + if chance2 == 1 then + Game.createMonster('diamond servant replica', self:getPosition(), false, true) + elseif chance2 == 2 then + Game.createMonster('golden servant replica', self:getPosition(), false, true) + end + self:remove() + end + return true + end + if Game.getStorageValue(GlobalStorage.ForgottenKnowledge.MechanismDiamond) >= 1 then + if chance > 30 then + Game.createMonster('diamond servant replica', self:getPosition(), false, true) + self:remove() + end + end + if Game.getStorageValue(GlobalStorage.ForgottenKnowledge.MechanismGolden) >= 1 then + if chance > 30 then + Game.createMonster('golden servant replica', self:getPosition(), false, true) + self:remove() + end + end + return true + end + end +end diff --git a/data/events/scripts/party.lua b/data/events/scripts/party.lua new file mode 100644 index 00000000000..1a6b561af42 --- /dev/null +++ b/data/events/scripts/party.lua @@ -0,0 +1,35 @@ +function Party:onJoin(player) + return true +end + +function Party:onLeave(player) + return true +end + +function Party:onDisband() + return true +end + +function Party:onShareExperience(exp) + local sharedExperienceMultiplier = 1.20 --20% + local vocationsIds = {} + + local vocationId = self:getLeader():getVocation():getBase():getId() + if vocationId ~= VOCATION_NONE then + table.insert(vocationsIds, vocationId) + end + + for _, member in ipairs(self:getMembers()) do + vocationId = member:getVocation():getBase():getId() + if not table.contains(vocationsIds, vocationId) and vocationId ~= VOCATION_NONE then + table.insert(vocationsIds, vocationId) + end + end + + local size = #vocationsIds + if size > 1 then + sharedExperienceMultiplier = 1.0 + ((size * (5 * (size - 1) + 10)) / 100) + end + + return (exp * sharedExperienceMultiplier) / (#self:getMembers() + 1) +end diff --git a/data/events/scripts/player.lua b/data/events/scripts/player.lua new file mode 100644 index 00000000000..da226246be0 --- /dev/null +++ b/data/events/scripts/player.lua @@ -0,0 +1,982 @@ +CONTAINER_WEIGHT_CHECK = true -- true = enable / false = disable +CONTAINER_WEIGHT_MAX = 1000000 -- 1000000 = 10k = 10000.00 oz + +local storeItemID = { + -- registered item ids here are not tradable with players + -- these items can be set to moveable at items.xml + -- 500 charges exercise weapons + 32384, -- exercise sword + 32385, -- exercise axe + 32386, -- exercise club + 32387, -- exercise bow + 32388, -- exercise rod + 32389, -- exercise wand + + -- 50 charges exercise weapons + 32124, -- training sword + 32125, -- training axe + 32126, -- training club + 32127, -- training bow + 32128, -- training wand + 32129, -- training club + + -- magic gold and magic converter (activated/deactivated) + 32109, -- magic gold converter + 33299, -- magic gold converter + 26378, -- gold converter + 29020, -- gold converter + + -- foods + 35172, -- roasted wyvern wings + 35173, -- carrot pie + 35174, -- tropical marinated tiger + 35175, -- delicatessen salad + 35176, -- chilli con carniphila + 35177, -- svargrond salmon filet + 35178, -- carrion casserole + 35179, -- consecrated beef + 35180, -- overcooked noodles +} + +-- Capacity imbuement store +local STORAGE_CAPACITY_IMBUEMENT = 42154 + +-- Players cannot throw items on teleports if set to true +local blockTeleportTrashing = true + +local titles = { + {storageID = 14960, title = " Scout"}, + {storageID = 14961, title = " Sentinel"}, + {storageID = 14962, title = " Steward"}, + {storageID = 14963, title = " Warden"}, + {storageID = 14964, title = " Squire"}, + {storageID = 14965, title = " Warrior"}, + {storageID = 14966, title = " Keeper"}, + {storageID = 14967, title = " Guardian"}, + {storageID = 14968, title = " Sage"}, + {storageID = 14969, title = " Tutor"}, + {storageID = 14970, title = " Senior Tutor"}, + {storageID = 14971, title = " King"}, +} + +local function getTitle(uid) + local player = Player(uid) + if not player then return false end + + for i = #titles, 1, -1 do + if player:getStorageValue(titles[i].storageID) == 1 then + return titles[i].title + end + end + + return false +end + +function Player:onBrowseField(position) + return true +end + +local function getHours(seconds) + return math.floor((seconds/60)/60) +end + +local function getMinutes(seconds) + return math.floor(seconds/60) +end + +local function getSeconds(seconds) + return seconds%60 +end + +local function getTime(seconds) + local hours, minutes = getHours(seconds), getMinutes(seconds) + if (minutes > 59) then + minutes = minutes-hours*60 + end + + if (minutes < 10) then + minutes = "0" ..minutes + end + + return hours..":"..minutes.. "h" +end + +local function getTimeinWords(secs) + local hours, minutes, seconds = getHours(secs), getMinutes(secs), getSeconds(secs) + if (minutes > 59) then + minutes = minutes-hours*60 + end + + local timeStr = '' + + if hours > 0 then + timeStr = timeStr .. ' hours ' + end + + timeStr = timeStr .. minutes .. ' minutes and '.. seconds .. ' seconds.' + + return timeStr +end + +function Player:onLook(thing, position, distance) + local description = "You see " + if thing:isItem() then + if thing.actionid == 5640 then + description = description .. "a honeyflower patch." + elseif thing.actionid == 5641 then + description = description .. "a banana palm." + elseif thing.itemid >= ITEM_HEALTH_CASK_START and thing.itemid <= ITEM_HEALTH_CASK_END + or thing.itemid >= ITEM_MANA_CASK_START and thing.itemid <= ITEM_MANA_CASK_END + or thing.itemid >= ITEM_SPIRIT_CASK_START and thing.itemid <= ITEM_SPIRIT_CASK_END + or thing.itemid >= ITEM_KEG_START and thing.itemid <= ITEM_KEG_END then + description = description .. thing:getDescription(distance) + local charges = thing:getCharges() + if charges then + description = string.format("%s\nIt has %d refillings left.", description, charges) + end + else + description = description .. thing:getDescription(distance) + end + + local itemType = thing:getType() + if (itemType and itemType:getImbuingSlots() > 0) then + local imbuingSlots = "Imbuements: (" + for slot = 0, itemType:getImbuingSlots() - 1 do + if slot > 0 then + imbuingSlots = string.format("%s, ", imbuingSlots) + end + local duration = thing:getImbuementDuration(slot) + if duration > 0 then + local imbue = thing:getImbuement(slot) + imbuingSlots = string.format("%s%s %s %s", + imbuingSlots, imbue:getBase().name, imbue:getName(), getTime(duration)) + else + imbuingSlots = string.format("%sEmpty Slot", imbuingSlots) + end + end + imbuingSlots = string.format("%s).", imbuingSlots) + description = string.gsub(description, "It weighs", imbuingSlots.. "\nIt weighs") + end + else + description = description .. thing:getDescription(distance) + if thing:isMonster() then + local master = thing:getMaster() + if master and table.contains({'sorcerer familiar','knight familiar','druid familiar','paladin familiar'}, + thing:getName():lower()) then + description = description..' (Master: ' .. master:getName() .. '). \z + It will disappear in ' .. getTimeinWords(master:getStorageValue(Storage.PetSummon) - os.time()) + end + end + end + + if self:getGroup():getAccess() then + if thing:isItem() then + description = string.format("%s\nItem ID: %d", description, thing:getId()) + + local actionId = thing:getActionId() + if actionId ~= 0 then + description = string.format("%s, Action ID: %d", description, actionId) + end + + local uniqueId = thing:getAttribute(ITEM_ATTRIBUTE_UNIQUEID) + if uniqueId > 0 and uniqueId < 65536 then + description = string.format("%s, Unique ID: %d", description, uniqueId) + end + + local itemType = thing:getType() + + local transformEquipId = itemType:getTransformEquipId() + local transformDeEquipId = itemType:getTransformDeEquipId() + if transformEquipId ~= 0 then + description = string.format("%s\nTransforms to: %d (onEquip)", description, transformEquipId) + elseif transformDeEquipId ~= 0 then + description = string.format("%s\nTransforms to: %d (onDeEquip)", description, transformDeEquipId) + end + + local decayId = itemType:getDecayId() + if decayId ~= -1 then + description = string.format("%s\nDecays to: %d", description, decayId) + end + + local clientId = itemType:getClientId() + if clientId then + description = string.format("%s\nClient ID: %d", description, clientId) + end + + elseif thing:isCreature() then + local str = "%s\nHealth: %d / %d" + if thing:isPlayer() and thing:getMaxMana() > 0 then + str = string.format("%s, Mana: %d / %d", str, thing:getMana(), thing:getMaxMana()) + end + description = string.format(str, description, thing:getHealth(), thing:getMaxHealth()) .. "." + end + + description = string.format( + "%s\nPosition: %d, %d, %d", + description, position.x, position.y, position.z + ) + + if thing:isCreature() then + if thing:isPlayer() then + description = string.format("%s\nIP: %s.", description, Game.convertIpToString(thing:getIp())) + end + end + end + self:sendTextMessage(MESSAGE_LOOK, description) +end + +function Player:onLookInBattleList(creature, distance) + local description = "You see " .. creature:getDescription(distance) + if creature:isMonster() then + local master = creature:getMaster() + local summons = {'sorcerer familiar','knight familiar','druid familiar','paladin familiar'} + if master and table.contains(summons, creature:getName():lower()) then + description = description..' (Master: ' .. master:getName() .. '). \z + It will disappear in ' .. getTimeinWords(master:getStorageValue(Storage.PetSummon) - os.time()) + end + end + if self:getGroup():getAccess() then + local str = "%s\nHealth: %d / %d" + if creature:isPlayer() and creature:getMaxMana() > 0 then + str = string.format("%s, Mana: %d / %d", str, creature:getMana(), creature:getMaxMana()) + end + description = string.format(str, description, creature:getHealth(), creature:getMaxHealth()) .. "." + + local position = creature:getPosition() + description = string.format( + "%s\nPosition: %d, %d, %d", + description, position.x, position.y, position.z + + ) + + if creature:isPlayer() then + description = string.format("%s\nIP: %s", description, Game.convertIpToString(creature:getIp())) + end + end + self:sendTextMessage(MESSAGE_LOOK, description) +end + +function Player:onLookInTrade(partner, item, distance) + self:sendTextMessage(MESSAGE_LOOK, "You see " .. item:getDescription(distance)) +end + +function Player:onLookInShop(itemType, count) + return true +end + +local config = { + maxItemsPerSeconds = 1, + exhaustTime = 2000, +} + +if not pushDelay then + pushDelay = { } +end + +local function antiPush(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder) + if toPosition.x == CONTAINER_POSITION then + return true + end + + local tile = Tile(toPosition) + if not tile then + self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + return false + end + + local cid = self:getId() + if not pushDelay[cid] then + pushDelay[cid] = {items = 0, time = 0} + end + + pushDelay[cid].items = pushDelay[cid].items + 1 + + local currentTime = os.mtime() + if pushDelay[cid].time == 0 then + pushDelay[cid].time = currentTime + elseif pushDelay[cid].time == currentTime then + pushDelay[cid].items = pushDelay[cid].items + 1 + elseif currentTime > pushDelay[cid].time then + pushDelay[cid].time = 0 + pushDelay[cid].items = 0 + end + + if pushDelay[cid].items > config.maxItemsPerSeconds then + pushDelay[cid].time = currentTime + config.exhaustTime + end + + if pushDelay[cid].time > currentTime then + self:sendCancelMessage("You can't move that item so fast.") + return false + end + + return true +end + +function Player:onMoveItem(item, count, fromPosition, toPosition, fromCylinder, toCylinder) + + -- No move items with actionID = 100 + if item:getActionId() == NOT_MOVEABLE_ACTION then + self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + return false + end + + -- No move if item count > 20 items + local tile = Tile(toPosition) + if tile and tile:getItemCount() > 20 then + self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + return false + end + + -- No move parcel very heavy + if CONTAINER_WEIGHT_CHECK and ItemType(item:getId()):isContainer() + and item:getWeight() > CONTAINER_WEIGHT_MAX then + self:sendCancelMessage("Your cannot move this item too heavy.") + return false + end + + -- Cults of Tibia begin + local frompos = Position(33023, 31904, 14) -- Checagem + local topos = Position(33052, 31932, 15) -- Checagem + if self:getPosition():isInRange(frompos, topos) and item:getId() == 26397 then + local tileBoss = Tile(toPosition) + if tileBoss and tileBoss:getTopCreature() and tileBoss:getTopCreature():isMonster() then + if tileBoss:getTopCreature():getName():lower() == 'the remorseless corruptor' then + tileBoss:getTopCreature():addHealth(-17000) + item:remove(1) + if tileBoss:getTopCreature():getHealth() <= 300 then + tileBoss:getTopCreature():remove() + local monster = Game.createMonster('the corruptor of souls', toPosition) + monster:registerEvent('CheckTile') + if Game.getStorageValue('healthSoul') > 0 then + monster:addHealth(-(monster:getHealth() - Game.getStorageValue('healthSoul'))) + end + Game.setStorageValue('CheckTile', os.time()+30) + end + elseif tileBoss:getTopCreature():getName():lower() == 'the corruptor of souls' then + Game.setStorageValue('CheckTile', os.time()+30) + item:remove(1) + end + end + end + -- Cults of Tibia end + + -- SSA exhaust + local exhaust = { } + if toPosition.x == CONTAINER_POSITION and toPosition.y == CONST_SLOT_NECKLACE + and item:getId() == ITEM_STONE_SKIN_AMULET then + local pid = self:getId() + if exhaust[pid] then + self:sendCancelMessage(RETURNVALUE_YOUAREEXHAUSTED) + return false + else + exhaust[pid] = true + addEvent(function() exhaust[pid] = false end, 2000, pid) + return true + end + end + + -- Store Inbox + local containerIdFrom = fromPosition.y - 64 + local containerFrom = self:getContainerById(containerIdFrom) + if (containerFrom) then + if (containerFrom:getId() == ITEM_STORE_INBOX + and toPosition.y >= 1 and toPosition.y <= 11 and toPosition.y ~= 3) then + self:sendCancelMessage(RETURNVALUE_CONTAINERNOTENOUGHROOM) + return false + end + end + + local containerTo = self:getContainerById(toPosition.y-64) + if (containerTo) then + if (containerTo:getId() == ITEM_STORE_INBOX) or (containerTo:getParent():isContainer() and containerTo:getParent():getId() == ITEM_STORE_INBOX and containerTo:getId() ~= ITEM_GOLD_POUCH) then + self:sendCancelMessage(RETURNVALUE_CONTAINERNOTENOUGHROOM) + return false + end + -- Gold Pouch + if (containerTo:getId() == ITEM_GOLD_POUCH) then + if (not (item:getId() == ITEM_CRYSTAL_COIN or item:getId() == ITEM_PLATINUM_COIN + or item:getId() == ITEM_GOLD_COIN)) then + self:sendCancelMessage("You can move only money to this container.") + return false + end + end + end + + + -- Bath tube + local toTile = Tile(toCylinder:getPosition()) + local topDownItem = toTile:getTopDownItem() + if topDownItem and table.contains({ BATHTUB_EMPTY, BATHTUB_FILLED }, topDownItem:getId()) then + return false + end + + -- Handle move items to the ground + if toPosition.x ~= CONTAINER_POSITION then + return true + end + + -- Check two-handed weapons + if item:getTopParent() == self and bit.band(toPosition.y, 0x40) == 0 then + local itemType, moveItem = ItemType(item:getId()) + if bit.band(itemType:getSlotPosition(), SLOTP_TWO_HAND) ~= 0 and toPosition.y == CONST_SLOT_LEFT then + moveItem = self:getSlotItem(CONST_SLOT_RIGHT) + if moveItem and itemType:getWeaponType() == WEAPON_DISTANCE and ItemType(moveItem:getId()):getWeaponType() == WEAPON_QUIVER then + return true + end + elseif itemType:getWeaponType() == WEAPON_SHIELD and toPosition.y == CONST_SLOT_RIGHT then + moveItem = self:getSlotItem(CONST_SLOT_LEFT) + if moveItem and bit.band(ItemType(moveItem:getId()):getSlotPosition(), SLOTP_TWO_HAND) == 0 then + return true + end + end + + if moveItem then + local parent = item:getParent() + if parent:getSize() == parent:getCapacity() then + self:sendTextMessage(MESSAGE_FAILURE, Game.getReturnMessage(RETURNVALUE_CONTAINERNOTENOUGHROOM)) + return false + else + return moveItem:moveTo(parent) + end + end + end + + -- Reward System + if toPosition.x == CONTAINER_POSITION then + local containerId = toPosition.y - 64 + local container = self:getContainerById(containerId) + if not container then + return true + end + + -- Do not let the player insert items into either the Reward Container or the Reward Chest + local itemId = container:getId() + if itemId == ITEM_REWARD_CONTAINER or itemId == ITEM_REWARD_CHEST then + self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + return false + end + + -- The player also shouldn't be able to insert items into the boss corpse + local tileCorpse = Tile(container:getPosition()) + for index, value in ipairs(tileCorpse:getItems() or { }) do + if value:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == 2^31 - 1 and value:getName() == container:getName() then + self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + return false + end + end + end + + -- Do not let the player move the boss corpse. + if item:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == 2^31 - 1 then + self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + return false + end + + -- Players cannot throw items on reward chest + local tileChest = Tile(toPosition) + if tileChest and tileChest:getItemById(ITEM_REWARD_CHEST) then + self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + self:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + + -- Players cannot throw items on teleports + if blockTeleportTrashing and toPosition.x ~= CONTAINER_POSITION then + local thing = Tile(toPosition):getItemByType(ITEM_TYPE_TELEPORT) + if thing then + self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + self:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + end + + if tile and tile:getItemById(370) then -- Trapdoor + self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + self:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + + if not antiPush(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder) then + return false + end + + return true +end + +function Player:onItemMoved(item, count, fromPosition, toPosition, fromCylinder, toCylinder) +end + +function Player:onMoveCreature(creature, fromPosition, toPosition) + if creature:isPlayer() and creature:getStorageValue(Storage.isTraining) == 1 and self:getGroup():hasFlag(PlayerFlag_CanPushAllCreatures) == false then + self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + return false + end + return true +end + +local function hasPendingReport(name, targetName, reportType) + local f = io.open(string.format("data/reports/players/%s-%s-%d.txt", name, targetName, reportType), "r") + if f then + io.close(f) + return true + else + return false + end +end + +function Player:onReportRuleViolation(targetName, reportType, reportReason, comment, translation) + local name = self:getName() + if hasPendingReport(name, targetName, reportType) then + self:sendTextMessage(MESSAGE_REPORT, "Your report is being processed.") + return + end + + local file = io.open(string.format("data/reports/players/%s-%s-%d.txt", name, targetName, reportType), "a") + if not file then + self:sendTextMessage(MESSAGE_REPORT, + "There was an error when processing your report, please contact a gamemaster.") + return + end + + io.output(file) + io.write("------------------------------\n") + io.write("Reported by: " .. name .. "\n") + io.write("Target: " .. targetName .. "\n") + io.write("Type: " .. reportType .. "\n") + io.write("Reason: " .. reportReason .. "\n") + io.write("Comment: " .. comment .. "\n") + if reportType ~= REPORT_TYPE_BOT then + io.write("Translation: " .. translation .. "\n") + end + io.write("------------------------------\n") + io.close(file) + self:sendTextMessage(MESSAGE_REPORT, string.format("Thank you for reporting %s. Your report \z + will be processed by %s team as soon as possible.", targetName, configManager.getString(configKeys.SERVER_NAME))) + return +end + +function Player:onReportBug(message, position, category) + if self:getAccountType() == ACCOUNT_TYPE_NORMAL then + return false + end + + local name = self:getName() + local file = io.open("data/reports/bugs/" .. name .. " report.txt", "a") + + if not file then + self:sendTextMessage(MESSAGE_REPORT, + "There was an error when processing your report, please contact a gamemaster.") + return true + end + + io.output(file) + io.write("------------------------------\n") + io.write("Name: " .. name) + if category == BUG_CATEGORY_MAP then + io.write(" [Map position: " .. position.x .. ", " .. position.y .. ", " .. position.z .. "]") + end + local playerPosition = self:getPosition() + io.write(" [Player Position: " .. playerPosition.x .. ", " .. playerPosition.y .. ", " .. playerPosition.z .. "]\n") + io.write("Comment: " .. message .. "\n") + io.close(file) + + self:sendTextMessage(MESSAGE_REPORT, + "Your report has been sent to " .. configManager.getString(configKeys.SERVER_NAME) .. ".") + return true +end + +function Player:onTurn(direction) + if self:getGroup():getAccess() and self:getDirection() == direction then + local nextPosition = self:getPosition() + nextPosition:getNextPosition(direction) + + self:teleportTo(nextPosition, true) + end + + return true +end + +function Player:onTradeRequest(target, item) + -- No trade items with actionID = 100 + if item:getActionId() == NOT_MOVEABLE_ACTION then + return false + end + + if isInArray(storeItemID,item.itemid) then + return false + end + return true +end + +function Player:onTradeAccept(target, item, targetItem) + self:closeImbuementWindow() + target:closeImbuementWindow() + return true +end + +local soulCondition = Condition(CONDITION_SOUL, CONDITIONID_DEFAULT) +soulCondition:setTicks(4 * 60 * 1000) +soulCondition:setParameter(CONDITION_PARAM_SOULGAIN, 1) + +local function useStamina(player) + local staminaMinutes = player:getStamina() + if staminaMinutes == 0 then + return + end + + local playerId = player:getId() + local currentTime = os.time() + local timePassed = currentTime - nextUseStaminaTime[playerId] + if timePassed <= 0 then + return + end + + if timePassed > 60 then + if staminaMinutes > 2 then + staminaMinutes = staminaMinutes - 2 + else + staminaMinutes = 0 + end + nextUseStaminaTime[playerId] = currentTime + 120 + else + staminaMinutes = staminaMinutes - 1 + nextUseStaminaTime[playerId] = currentTime + 60 + end + player:setStamina(staminaMinutes) +end + +local function useStaminaXp(player) + local staminaMinutes = player:getExpBoostStamina() / 60 + if staminaMinutes == 0 then + return + end + + local playerId = player:getId() + local currentTime = os.time() + local timePassed = currentTime - nextUseXpStamina[playerId] + if timePassed <= 0 then + return + end + + if timePassed > 60 then + if staminaMinutes > 2 then + staminaMinutes = staminaMinutes - 2 + else + staminaMinutes = 0 + end + nextUseXpStamina[playerId] = currentTime + 120 + else + staminaMinutes = staminaMinutes - 1 + nextUseXpStamina[playerId] = currentTime + 60 + end + player:setExpBoostStamina(staminaMinutes * 60) +end + +function Player:onGainExperience(source, exp, rawExp) + if not source or source:isPlayer() then + return exp + end + + -- Soul regeneration + local vocation = self:getVocation() + if self:getSoul() < vocation:getMaxSoul() and exp >= self:getLevel() then + soulCondition:setParameter(CONDITION_PARAM_SOULTICKS, vocation:getSoulGainTicks() * 1000) + self:addCondition(soulCondition) + end + + -- Experience Stage Multiplier + local expStage = getRateFromTable(experienceStages, self:getLevel(), configManager.getNumber(configKeys.RATE_EXP)) + exp = exp * expStage + baseExp = rawExp * expStage + if Game.getStorageValue(GlobalStorage.XpDisplayMode) > 0 then + displayRate = expStage + else + displayRate = 1 + end + + -- Prey Bonus + for slot = CONST_PREY_SLOT_FIRST, CONST_PREY_SLOT_THIRD do + if (self:getPreyCurrentMonster(slot) == source:getName() + and self:getPreyBonusType(slot) == CONST_BONUS_XP_BONUS) then + exp = exp + math.floor(exp * (self:getPreyBonusValue(slot) / 100)) + break + end + if (self:getPreyTimeLeft(slot) / 60) > 0 then + preyTimeLeft(self, slot) -- slot consumption, outside of the mosnter check + end + end + + -- Store Bonus + useStaminaXp(self) -- Use store boost stamina + + local Boost = self:getExpBoostStamina() + local stillHasBoost = Boost > 0 + local storeXpBoostAmount = stillHasBoost and self:getStoreXpBoost() or 0 + + self:setStoreXpBoost(storeXpBoostAmount) + + if (storeXpBoostAmount > 0) then + exp = exp + (baseExp * (storeXpBoostAmount/100)) -- Exp Boost + end + + -- Stamina Bonus + if configManager.getBoolean(configKeys.STAMINA_SYSTEM) then + useStamina(self) + local staminaMinutes = self:getStamina() + if staminaMinutes > 2340 and self:isPremium() then + exp = exp * 1.5 + self:setStaminaXpBoost(150) + elseif staminaMinutes <= 840 then + exp = exp * 0.5 --TODO destroy loot of people with 840- stamina + self:setStaminaXpBoost(50) + else + self:setStaminaXpBoost(100) + end + end + + -- Boosted creature + if source:getName():lower() == (Game.getBoostedCreature()):lower() then + exp = exp * 2 + end + + -- Event scheduler + if SCHEDULE_EXP_RATE ~= 100 then + exp = (exp * SCHEDULE_EXP_RATE)/100 + end + self:setBaseXpGain(displayRate * 100) + return exp +end + +function Player:onLoseExperience(exp) + return exp +end + +function Player:onGainSkillTries(skill, tries) + -- Dawnport skills limit + if isSkillGrowthLimited(self, skill) then + return 0 + end + if APPLY_SKILL_MULTIPLIER == false then + return tries + end + + -- Event scheduler skill rate + if SCHEDULE_SKILL_RATE ~= 100 then + tries = (tries * SCHEDULE_SKILL_RATE)/100 + end + + local skillRate = configManager.getNumber(configKeys.RATE_SKILL) + local magicRate = configManager.getNumber(configKeys.RATE_MAGIC) + + if(skill == SKILL_MAGLEVEL) then -- Magic getLevel + return tries * getRateFromTable(magicLevelStages, self:getMagicLevel(), magicRate) + end + + return tries * getRateFromTable(skillsStages, self:getEffectiveSkillLevel(skill), skillRate) +end + +function Player:onRemoveCount(item) + self:sendWaste(item:getId()) +end + +function Player:onRequestQuestLog() + self:sendQuestLog() +end + +function Player:onRequestQuestLine(questId) + self:sendQuestLine(questId) +end + +function Player:onStorageUpdate(key, value, oldValue, currentFrameTime) + self:updateStorage(key, value, oldValue, currentFrameTime) +end + +function Player:canBeAppliedImbuement(imbuement, item) + local categories = {} + local slots = ItemType(item:getId()):getImbuingSlots() + if slots > 0 then + for slot = 0, slots - 1 do + local duration = item:getImbuementDuration(slot) + if duration > 0 then + local imbue = item:getImbuement(slot) + local catid = imbue:getCategory().id + table.insert(categories, catid) + end + end + end + + if isInArray(categories, imbuement:getCategory().id) then + return false + end + + if imbuement:isPremium() and self:getPremiumDays() < 1 then + return false + end + + if self:getStorageValue(Storage.ForgottenKnowledge.Tomes) > 0 then + imbuable = true + else + return false + end + + if not self:canImbueItem(imbuement, item) then + return false + end + + return true +end + +function Player:onApplyImbuement(imbuement, item, slot, protectionCharm) + for slot = CONST_SLOT_HEAD, CONST_SLOT_AMMO do + local slotItem = self:getSlotItem(slot) + if slotItem and slotItem == item then + self:sendImbuementResult(MESSAGEDIALOG_IMBUEMENT_ROLL_FAILED, "You can't imbue a equipped item.") + self:closeImbuementWindow() + return true + end + end + + for _, pid in pairs(imbuement:getItems()) do + if (self:getItemCount(pid.itemid) + self:getStashItemCount(pid.itemid)) < pid.count then + self:sendImbuementResult(MESSAGEDIALOG_IMBUEMENT_ROLL_FAILED, "You don't have all necessary items.") + return false + end + end + + if item:getImbuementDuration(slot) > 0 then + self:sendImbuementResult(MESSAGEDIALOG_IMBUEMENT_ERROR, "An error ocurred, please reopen imbuement window.") + return false + end + local base = imbuement:getBase() + local price = base.price + (protectionCharm and base.protection or 0) + + local chance = protectionCharm and 100 or base.percent + if math.random(100) > chance then -- failed attempt + self:sendImbuementResult(MESSAGEDIALOG_IMBUEMENT_ROLL_FAILED, "Oh no!\n\nThe imbuement has failed. You have lost the astral sources and gold you needed for the imbuement.\n\nNext time use a protection charm to better your chances.") + -- Removing items + for _, pid in pairs(imbuement:getItems()) do + self:removeItem(pid.itemid, pid.count) + end + -- Removing money + self:removeMoneyNpc(price) + -- Refreshing shrine window + local nitem = Item(item.uid) + self:sendImbuementPanel(nitem) + return false + end + + -- Removing items + for _, pid in pairs(imbuement:getItems()) do + local invertoryItemCount = self:getItemCount(pid.itemid) + if invertoryItemCount >= pid.count then + if not(self:removeItem(pid.itemid, pid.count)) then + self:sendImbuementResult(MESSAGEDIALOG_IMBUEMENT_ERROR, "An error ocurred, please reopen imbuement window.") + return false + end + else + local mathItemCount = pid.count + if invertoryItemCount > 0 and self:removeItem(pid.itemid, invertoryItemCount) then + mathItemCount = mathItemCount - invertoryItemCount + end + + if not(self:removeStashItem(pid.itemid, mathItemCount)) then + self:sendImbuementResult(MESSAGEDIALOG_IMBUEMENT_ERROR, "An error ocurred, please reopen imbuement window.") + return false + end + end + end + + if not self:removeMoneyNpc(price) then + self:sendImbuementResult(MESSAGEDIALOG_IMBUEMENT_ROLL_FAILED, "You don't have enough money " ..price.. " gps.") + return false + end + + if not item:addImbuement(slot, imbuement:getId()) then + self:sendImbuementResult(MESSAGEDIALOG_IMBUEMENT_ROLL_FAILED, "Item failed to apply imbuement.") + return false + end + + -- Update item + local nitem = Item(item.uid) + self:sendImbuementPanel(nitem) + return true +end + +function Player:clearImbuement(item, slot) + local slots = ItemType(item:getId()):getImbuingSlots() + if slots < slot then + self:sendImbuementResult(MESSAGEDIALOG_CLEARING_CHARM_ERROR, "Sorry, not possible.") + return false + end + + if item:getTopParent() ~= self or item:getParent() == self then + self:sendImbuementResult(MESSAGEDIALOG_CLEARING_CHARM_ERROR, + "An error occurred while applying the clearing charm to the item.") + return false + end + + -- slot is not used + local info = item:getImbuementDuration(slot) + if info == 0 then + self:sendImbuementResult(MESSAGEDIALOG_CLEARING_CHARM_ERROR, + "An error occurred while applying the clearing charm to the item.") + return false + end + + local imbuement = item:getImbuement(slot) + if not self:removeMoneyNpc(imbuement:getBase().removecust) then + self:sendImbuementResult(MESSAGEDIALOG_CLEARING_CHARM_ERROR, + "You don't have enough money " ..imbuement:getBase().removecust.. " gps.") + return false + end + + if not item:cleanImbuement(slot) then + self:sendImbuementResult(MESSAGEDIALOG_CLEARING_CHARM_ERROR, + "An error occurred while applying the clearing charm to the item.") + return false + end + + -- Update item + local nitem = Item(item.uid) + self:sendImbuementResult(MESSAGEDIALOG_CLEARING_CHARM_SUCCESS, + "Congratulations! You have successfully applied the clearing charm to your item."); + self:sendImbuementPanel(nitem) + + return true +end + +function Player:onCombat(target, item, primaryDamage, primaryType, secondaryDamage, secondaryType) + if not item or not target then + return primaryDamage, primaryType, secondaryDamage, secondaryType + end + + if ItemType(item:getId()):getWeaponType() == WEAPON_AMMO then + if isInArray({ITEM_OLD_DIAMOND_ARROW, ITEM_DIAMOND_ARROW}, item:getId()) then + return primaryDamage, primaryType, secondaryDamage, secondaryType + else + item = self:getSlotItem(CONST_SLOT_LEFT) + end + end + + local slots = ItemType(item:getId()):getImbuingSlots() + if slots > 0 then + for i = 0, slots - 1 do + local imbuement = item:getImbuement(i) + if imbuement then + local percent = imbuement:getElementDamage() + local totalDmg = primaryDamage --store it for damage adjustment + if percent and percent > 0 then + if primaryDamage ~= 0 then + local factor = percent / 100 + secondaryType = imbuement:getCombatType() + primaryDamage = totalDmg * (1 - factor) + secondaryDamage = totalDmg * (factor) + end + end + end + end + end + + return primaryDamage, primaryType, secondaryDamage, secondaryType +end diff --git a/data/events/scripts/scheduler/example.lua b/data/events/scripts/scheduler/example.lua new file mode 100644 index 00000000000..71b85c5f528 --- /dev/null +++ b/data/events/scripts/scheduler/example.lua @@ -0,0 +1,25 @@ +-- [OtServerBr] +-- Event scheduler lua scripts, on this file is possible to load any kind +-- of global values, create functions or create and register GlobalEvents using the revscript system. +-- For example you can load a 'local Example = GlobalEvent("example")' and register it with 'Example:register()', +-- adding the 'Example.onStartup()' or 'Example.onThink(interval)' with 'Example:interval(time)'. +-- With 'onStartup()' you can load any raid, for example loading a entire map/hunt and the choseen spawns. + +-- Examples: +-- Loading map: Game.loadMap('data/world/myMapFolder/myMapFile.otbm') +-- Loading spawn: addEvent(function() Game.loadSpawnFile('data/world/mySpawnFolder/mySpawnFile.xml) end, 30 * 1000) + +local Example_One = GlobalEvent("Example one") +function Example_One.onStartup() + return true +end + +Example_One:register() + +local Example_Two = GlobalEvent("Example two") +function Example_Two.onThink(interval) + return true +end + +Example_Two:interval(10000) -- 10 seconds interval +Example_Two:register() diff --git a/data/global.lua b/data/global.lua new file mode 100644 index 00000000000..7d203317c56 --- /dev/null +++ b/data/global.lua @@ -0,0 +1,160 @@ +math.randomseed(os.time()) +dofile('data/lib/lib.lua') + +NOT_MOVEABLE_ACTION = 100 +PARTY_PROTECTION = 1 -- Set to 0 to disable. +ADVANCED_SECURE_MODE = 1 -- Set to 0 to disable. + +STORAGEVALUE_PROMOTION = 30018 + +SERVER_NAME = configManager.getString(configKeys.SERVER_NAME) + +-- Bestiary charm +GLOBAL_CHARM_GUT = 0 +GLOBAL_CHARM_SCAVENGE = 0 + +--WEATHER +weatherConfig = { + groundEffect = CONST_ME_LOSEENERGY, + fallEffect = CONST_ANI_SMALLICE, + thunderEffect = configManager.getBoolean(configKeys.WEATHER_THUNDER), + minDMG = 1, + maxDMG = 5 +} + +-- Event Schedule +SCHEDULE_LOOT_RATE = 100 +SCHEDULE_EXP_RATE = 100 +SCHEDULE_SKILL_RATE = 100 + +-- MARRY +PROPOSED_STATUS = 1 +MARRIED_STATUS = 2 +PROPACCEPT_STATUS = 3 +LOOK_MARRIAGE_DESCR = TRUE +ITEM_WEDDING_RING = 2121 +ITEM_ENGRAVED_WEDDING_RING = 10502 + +-- Scarlett Etzel +SCARLETT_MAY_TRANSFORM = 0 +SCARLETT_MAY_DIE = 0 + +ropeSpots = {384, 418, 8278, 8592, 13189, 14436, 15635, 19518, 26019, 24621, 24622, 24623, 24624} +specialRopeSpots = { 14435 } + +-- Impact Analyser +-- Every 2 seconds +updateInterval = 2 +-- Healing +-- Global table to insert data +healingImpact = {} +-- Damage +-- Global table to insert data +damageImpact = {} + +-- New prey => preyTimeLeft +nextPreyTime = {} + +startupGlobalStorages = { + GlobalStorage.TheAncientTombs.AshmunrahSwitchesGlobalStorage, + GlobalStorage.TheAncientTombs.DiprathSwitchesGlobalStorage, + GlobalStorage.TheAncientTombs.ThalasSwitchesGlobalStorage, + GlobalStorage.HeroRathleton.FirstMachines, + GlobalStorage.HeroRathleton.SecondMachines, + GlobalStorage.HeroRathleton.ThirdMachines, + GlobalStorage.HeroRathleton.DeepRunning, + GlobalStorage.HeroRathleton.HorrorRunning, + GlobalStorage.HeroRathleton.LavaRunning, + GlobalStorage.HeroRathleton.MaxxenRunning, + GlobalStorage.HeroRathleton.LavaCounter, + GlobalStorage.HeroRathleton.FourthMachines, + GlobalStorage.FerumbrasAscendant.Crystals.Crystal1, + GlobalStorage.FerumbrasAscendant.Crystals.Crystal2, + GlobalStorage.FerumbrasAscendant.Crystals.Crystal3, + GlobalStorage.FerumbrasAscendant.Crystals.Crystal4, + GlobalStorage.FerumbrasAscendant.Crystals.Crystal5, + GlobalStorage.FerumbrasAscendant.Crystals.Crystal6, + GlobalStorage.FerumbrasAscendant.Crystals.Crystal7, + GlobalStorage.FerumbrasAscendant.Crystals.Crystal8, + GlobalStorage.FerumbrasAscendant.Crystals.AllCrystals, + GlobalStorage.FerumbrasAscendant.FerumbrasEssence, + GlobalStorage.Feroxa.Active, + GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats, + GlobalStorage.FerumbrasAscendant.Elements.Active, + GlobalStorage.FerumbrasAscendant.Elements.First, + GlobalStorage.FerumbrasAscendant.Elements.Second, + GlobalStorage.FerumbrasAscendant.Elements.Third, + GlobalStorage.FerumbrasAscendant.Elements.Done +} + +do -- Event Schedule rates + local lootRate = Game.getEventSLoot() + if lootRate ~= 100 then + SCHEDULE_LOOT_RATE = lootRate + end + + local expRate = Game.getEventSExp() + if expRate ~= 100 then + SCHEDULE_EXP_RATE = expRate + end + + local skillRate = Game.getEventSSkill() + if skillRate ~= 100 then + SCHEDULE_SKILL_RATE = skillRate + end +end + +table.contains = function(array, value) + for _, targetColumn in pairs(array) do + if targetColumn == value then + return true + end + end + return false +end + +string.split = function(str, sep) + local res = {} + for v in str:gmatch("([^" .. sep .. "]+)") do + res[#res + 1] = v + end + return res +end + +string.splitTrimmed = function(str, sep) + local res = {} + for v in str:gmatch("([^" .. sep .. "]+)") do + res[#res + 1] = v:trim() + end + return res +end + +string.trim = function(str) + return str:match'^()%s*$' and '' or str:match'^%s*(.*%S)' +end + +-- Stamina +if nextUseStaminaTime == nil then + nextUseStaminaTime = {} +end + +if nextUseStaminaPrey == nil then + nextUseStaminaPrey = {} +end + +if nextUseXpStamina == nil then + nextUseXpStamina = {} +end + +if lastItemImbuing == nil then + lastItemImbuing = {} +end + +if nextDelayPreyReroll == nil then + nextDelayPreyReroll = {} +end + +-- Delay potion +if not playerDelayPotion then + playerDelayPotion = {} +end diff --git a/data/items/items.otb b/data/items/items.otb new file mode 100644 index 00000000000..8ddb9151591 Binary files /dev/null and b/data/items/items.otb differ diff --git a/data/items/items.xml b/data/items/items.xml new file mode 100644 index 00000000000..543520fa0fc --- /dev/null +++ b/data/items/items.xml @@ -0,0 +1,52435 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/lib/compat/compat.lua b/data/lib/compat/compat.lua new file mode 100644 index 00000000000..6f74c131060 --- /dev/null +++ b/data/lib/compat/compat.lua @@ -0,0 +1,1385 @@ +TRUE = true +FALSE = false + +MESSAGE_STATUS_CONSOLE_RED = MESSAGE_GAMEMASTER_CONSOLE + +MESSAGE_STATUS_DEFAULT = MESSAGE_LOGIN +MESSAGE_STATUS_WARNING = MESSAGE_ADMINISTRADOR +MESSAGE_EVENT_ADVANCE = MESSAGE_EVENT_ADVANCE + +MESSAGE_STATUS_SMALL = MESSAGE_FAILURE +MESSAGE_INFO_DESCR = MESSAGE_LOOK +MESSAGE_DAMAGE_DEALT = MESSAGE_DAMAGE_DEALT +MESSAGE_DAMAGE_RECEIVED = MESSAGE_DAMAGE_RECEIVED +MESSAGE_EVENT_DEFAULT = MESSAGE_STATUS + +MESSAGE_EVENT_ORANGE = TALKTYPE_MONSTER_SAY +MESSAGE_STATUS_CONSOLE_ORANGE = TALKTYPE_MONSTER_YELL + +result.getDataInt = result.getNumber +result.getDataLong = result.getNumber +result.getDataString = result.getString +result.getDataStream = result.getStream + +LUA_ERROR = false +LUA_NO_ERROR = true + +STACKPOS_GROUND = 0 +STACKPOS_FIRST_ITEM_ABOVE_GROUNDTILE = 1 +STACKPOS_SECOND_ITEM_ABOVE_GROUNDTILE = 2 +STACKPOS_THIRD_ITEM_ABOVE_GROUNDTILE = 3 +STACKPOS_FOURTH_ITEM_ABOVE_GROUNDTILE = 4 +STACKPOS_FIFTH_ITEM_ABOVE_GROUNDTILE = 5 +STACKPOS_TOP_CREATURE = 253 +STACKPOS_TOP_FIELD = 254 +STACKPOS_TOP_MOVEABLE_ITEM_OR_CREATURE = 255 + +THING_TYPE_PLAYER = CREATURETYPE_PLAYER + 1 +THING_TYPE_MONSTER = CREATURETYPE_MONSTER + 1 +THING_TYPE_NPC = CREATURETYPE_NPC + 1 + +COMBAT_POISONDAMAGE = COMBAT_EARTHDAMAGE +CONDITION_EXHAUST = CONDITION_EXHAUST_WEAPON +TALKTYPE_ORANGE_1 = TALKTYPE_MONSTER_SAY +TALKTYPE_ORANGE_2 = TALKTYPE_MONSTER_YELL + +NORTH = DIRECTION_NORTH +EAST = DIRECTION_EAST +SOUTH = DIRECTION_SOUTH +WEST = DIRECTION_WEST +SOUTHWEST = DIRECTION_SOUTHWEST +SOUTHEAST = DIRECTION_SOUTHEAST +NORTHWEST = DIRECTION_NORTHWEST +NORTHEAST = DIRECTION_NORTHEAST + +do + local function CreatureIndex(self, key) + local methods = getmetatable(self) + if key == "uid" then + return methods.getId(self) + elseif key == "type" then + local creatureType = 0 + if methods.isPlayer(self) then + creatureType = THING_TYPE_PLAYER + elseif methods.isMonster(self) then + creatureType = THING_TYPE_MONSTER + elseif methods.isNpc(self) then + creatureType = THING_TYPE_NPC + end + return creatureType + elseif key == "itemid" then + return 1 + elseif key == "actionid" then + return 0 + end + return methods[key] + end + rawgetmetatable("Player").__index = CreatureIndex + rawgetmetatable("Monster").__index = CreatureIndex + rawgetmetatable("Npc").__index = CreatureIndex +end + +do + local function ItemIndex(self, key) + local methods = getmetatable(self) + if key == "itemid" then + return methods.getId(self) + elseif key == "actionid" then + return methods.getActionId(self) + elseif key == "uid" then + return methods.getUniqueId(self) + elseif key == "type" then + return methods.getSubType(self) + end + return methods[key] + end + rawgetmetatable("Item").__index = ItemIndex + rawgetmetatable("Container").__index = ItemIndex + rawgetmetatable("Teleport").__index = ItemIndex +end + +do + local function ActionNewIndex(self, key, value) + if key == "onUse" then + self:onUse(value) + return + end + rawset(self, key, value) + end + rawgetmetatable("Action").__newindex = ActionNewIndex +end + +do + local function TalkActionNewIndex(self, key, value) + if key == "onSay" then + self:onSay(value) + return + end + rawset(self, key, value) + end + rawgetmetatable("TalkAction").__newindex = TalkActionNewIndex +end + +do + local function CreatureEventNewIndex(self, key, value) + if key == "onLogin" then + self:type("login") + self:onLogin(value) + return + elseif key == "onLogout" then + self:type("logout") + self:onLogout(value) + return + elseif key == "onThink" then + self:type("think") + self:onThink(value) + return + elseif key == "onPrepareDeath" then + self:type("preparedeath") + self:onPrepareDeath(value) + return + elseif key == "onDeath" then + self:type("death") + self:onDeath(value) + return + elseif key == "onKill" then + self:type("kill") + self:onKill(value) + return + elseif key == "onAdvance" then + self:type("advance") + self:onAdvance(value) + return + elseif key == "onModalWindow" then + self:type("modalwindow") + self:onModalWindow(value) + return + elseif key == "onTextEdit" then + self:type("textedit") + self:onTextEdit(value) + return + elseif key == "onHealthChange" then + self:type("healthchange") + self:onHealthChange(value) + return + elseif key == "onManaChange" then + self:type("manachange") + self:onManaChange(value) + return + elseif key == "onExtendedOpcode" then + self:type("extendedopcode") + self:onExtendedOpcode(value) + return + end + rawset(self, key, value) + end + rawgetmetatable("CreatureEvent").__newindex = CreatureEventNewIndex +end + +do + local function MoveEventNewIndex(self, key, value) + if key == "onEquip" then + self:type("equip") + self:onEquip(value) + return + elseif key == "onDeEquip" then + self:type("deequip") + self:onDeEquip(value) + return + elseif key == "onAddItem" then + self:type("additem") + self:onAddItem(value) + return + elseif key == "onRemoveItem" then + self:type("removeitem") + self:onRemoveItem(value) + return + elseif key == "onStepIn" then + self:type("stepin") + self:onStepIn(value) + return + elseif key == "onStepOut" then + self:type("stepout") + self:onStepOut(value) + return + end + rawset(self, key, value) + end + rawgetmetatable("MoveEvent").__newindex = MoveEventNewIndex +end + +do + local function GlobalEventNewIndex(self, key, value) + if key == "onThink" then + self:onThink(value) + return + elseif key == "onTime" then + self:onTime(value) + return + elseif key == "onStartup" then + self:type("startup") + self:onStartup(value) + return + elseif key == "onShutdown" then + self:type("shutdown") + self:onShutdown(value) + return + elseif key == "onRecord" then + self:type("record") + self:onRecord(value) + return + elseif key == "onPeriodChange" then + self:type("periodchange") + self:onPeriodChange(value) + return + end + rawset(self, key, value) + end + rawgetmetatable("GlobalEvent").__newindex = GlobalEventNewIndex +end + +do + local function WeaponNewIndex(self, key, value) + if key == "onUseWeapon" then + self:onUseWeapon(value) + return + end + rawset(self, key, value) + end + rawgetmetatable("Weapon").__newindex = WeaponNewIndex +end + +do + local function SpellNewIndex(self, key, value) + if key == "onCastSpell" then + self:onCastSpell(value) + return + end + rawset(self, key, value) + end + rawgetmetatable("Spell").__newindex = SpellNewIndex +end + +do + local function MonsterTypeNewIndex(self, key, value) + if key == "onThink" then + self:eventType(MONSTERS_EVENT_THINK) + self:onThink(value) + return + elseif key == "onAppear" then + self:eventType(MONSTERS_EVENT_APPEAR) + self:onAppear(value) + return + elseif key == "onDisappear" then + self:eventType(MONSTERS_EVENT_DISAPPEAR) + self:onDisappear(value) + return + elseif key == "onMove" then + self:eventType(MONSTERS_EVENT_MOVE) + self:onMove(value) + return + elseif key == "onSay" then + self:eventType(MONSTERS_EVENT_SAY) + self:onSay(value) + return + end + rawset(self, key, value) + end + rawgetmetatable("MonsterType").__newindex = MonsterTypeNewIndex +end + +do + local function NpcTypeNewIndex(self, key, value) + if key == "onThink" then + self:eventType(NPCS_EVENT_THINK) + self:onThink(value) + return + elseif key == "onAppear" then + self:eventType(NPCS_EVENT_APPEAR) + self:onAppear(value) + return + elseif key == "onDisappear" then + self:eventType(NPCS_EVENT_DISAPPEAR) + self:onDisappear(value) + return + elseif key == "onMove" then + self:eventType(NPCS_EVENT_MOVE) + self:onMove(value) + return + elseif key == "onSay" then + self:eventType(NPCS_EVENT_SAY) + self:onSay(value) + return + elseif key == "onPlayerBuyItem" then + self:eventType(NPCS_EVENT_PLAYER_BUY) + self:onPlayerBuyItem(value) + return + elseif key == "onPlayerSellItem" then + self:eventType(NPCS_EVENT_PLAYER_SELL) + self:onPlayerSellItem(value) + return + elseif key == "onPlayerCheckItem" then + self:eventType(NPCS_EVENT_PLAYER_CHECK_ITEM) + self:onPlayerCheckItem(value) + return + end + rawset(self, key, value) + end + rawgetmetatable("NpcType").__newindex = NpcTypeNewIndex +end + +function pushThing(thing) + local t = {uid = 0, itemid = 0, type = 0, actionid = 0} + if thing then + if thing:isItem() then + t.uid = thing:getUniqueId() + t.itemid = thing:getId() + if ItemType(t.itemid):hasSubType() then + t.type = thing:getSubType() + end + t.actionid = thing:getActionId() + elseif thing:isCreature() then + t.uid = thing:getId() + t.itemid = 1 + if thing:isPlayer() then + t.type = THING_TYPE_PLAYER + elseif thing:isMonster() then + t.type = THING_TYPE_MONSTER + else + t.type = THING_TYPE_NPC + end + end + end + return t +end + +createCombatObject = Combat +addCombatCondition = Combat.addCondition +setCombatArea = Combat.setArea +setCombatCallback = Combat.setCallback +setCombatFormula = Combat.setFormula +setCombatParam = Combat.setParameter + +Combat.setCondition = function(...) + Spdlog.warn("[Combat.setCondition] - Function was renamed to Combat.addCondition and will be removed in the future") + Combat.addCondition(...) +end + +setCombatCondition = function(...) + Spdlog.warn("[setCombatCondition] - Function was renamed to addCombatCondition and will be removed in the future") + Combat.addCondition(...) +end + +createConditionObject = Condition +setConditionParam = Condition.setParameter +setConditionFormula = Condition.setFormula +addDamageCondition = Condition.addDamage +addOutfitCondition = Condition.setOutfit + +function doCombat(cid, combat, var) return combat:execute(cid, var) end + +function isCreature(cid) return Creature(cid) ~= nil end +function isPlayer(cid) return Player(cid) ~= nil end +function isMonster(cid) return Monster(cid) ~= nil end +function isSummon(cid) return Creature(cid):getMaster() ~= nil end +function isNpc(cid) return Npc(cid) ~= nil end +function isItem(uid) return Item(uid) ~= nil end +function isContainer(uid) return Container(uid) ~= nil end + +function getCreatureName(cid) local c = Creature(cid) return c and c:getName() or false end +function getCreatureHealth(cid) local c = Creature(cid) return c and c:getHealth() or false end +function getCreatureMaxHealth(cid) local c = Creature(cid) return c and c:getMaxHealth() or false end +function getCreaturePosition(cid) local c = Creature(cid) return c and c:getPosition() or false end +function getCreatureOutfit(cid) local c = Creature(cid) return c and c:getOutfit() or false end +function getCreatureSpeed(cid) local c = Creature(cid) return c and c:getSpeed() or false end +function getCreatureBaseSpeed(cid) local c = Creature(cid) return c and c:getBaseSpeed() or false end + +function getCreatureTarget(cid) + local c = Creature(cid) + if c then + local target = c:getTarget() + return target and target:getId() or 0 + end + return false +end + +function getCreatureMaster(cid) + local c = Creature(cid) + if c then + local master = c:getMaster() + return master and master:getId() or c:getId() + end + return false +end + +function getCreatureSummons(cid) + local c = Creature(cid) + if c == nil then + return false + end + + local result = {} + for _, summon in ipairs(c:getSummons()) do + result[#result + 1] = summon:getId() + end + return result +end + +getCreaturePos = getCreaturePosition + +function doCreatureAddHealth(cid, health) local c = Creature(cid) return c and c:addHealth(health) or false end +function doRemoveCreature(cid) local c = Creature(cid) return c and c:remove() or false end +function doCreatureSetLookDir(cid, direction) local c = Creature(cid) return c and c:setDirection(direction) or false end +function doCreatureSay(cid, text, type, ...) local c = Creature(cid) return c and c:say(text, type, ...) or false end +function doCreatureChangeOutfit(cid, outfit) local c = Creature(cid) return c and c:setOutfit(outfit) or false end +function doSetCreatureDropLoot(cid, doDrop) local c = Creature(cid) return c and c:setDropLoot(doDrop) or false end +function doChangeSpeed(cid, delta) local c = Creature(cid) return c and c:changeSpeed(delta) or false end +function doAddCondition(cid, conditionId) local c = Creature(cid) return c and c:addCondition(conditionId) or false end +function doRemoveCondition(cid, conditionType, subId) local c = Creature(cid) return c and (c:removeCondition(conditionType, CONDITIONID_COMBAT, subId) or c:removeCondition(conditionType, CONDITIONID_DEFAULT, subId) or true) end +function getCreatureCondition(cid, type, subId) local c = Creature(cid) return c and c:hasCondition(type, subId) or false end + +doSetCreatureDirection = doCreatureSetLookDir + +function registerCreatureEvent(cid, name) local c = Creature(cid) return c and c:registerEvent(name) or false end +function unregisterCreatureEvent(cid, name) local c = Creature(cid) return c and c:unregisterEvent(name) or false end + +function getPlayerByName(name) local p = Player(name) return p and p:getId() or false end +function getIPByPlayerName(name) local p = Player(name) return p and p:getIp() or false end +function getPlayerGUID(cid) local p = Player(cid) return p and p:getGuid() or false end +function getPlayerIp(cid) local p = Player(cid) return p and p:getIp() or false end +function getPlayerAccountType(cid) local p = Player(cid) return p and p:getAccountType() or false end +function getPlayerLastLoginSaved(cid) local p = Player(cid) return p and p:getLastLoginSaved() or false end +function getPlayerName(cid) local p = Player(cid) return p and p:getName() or false end +function getPlayerFreeCap(cid) local p = Player(cid) return p and (p:getFreeCapacity() / 100) or false end +function getPlayerPosition(cid) local p = Player(cid) return p and p:getPosition() or false end +function getPlayerMagLevel(cid) local p = Player(cid) return p and p:getMagicLevel() or false end +function getPlayerAccess(cid) + local player = Player(cid) + if player == nil then + return false + end + return player:getGroup():getAccess() and 1 or 0 +end +function getPlayerSkill(cid, skillId) local p = Player(cid) return p and p:getSkillLevel(skillId) or false end +function getPlayerMana(cid) local p = Player(cid) return p and p:getMana() or false end +function getPlayerMaxMana(cid) local p = Player(cid) return p and p:getMaxMana() or false end +function getPlayerLevel(cid) local p = Player(cid) return p and p:getLevel() or false end +function getPlayerTown(cid) local p = Player(cid) return p and p:getTown():getId() or false end +function getPlayerVocation(cid) local p = Player(cid) return p and p:getVocation():getId() or false end +function getPlayerSoul(cid) local p = Player(cid) return p and p:getSoul() or false end +function getPlayerSex(cid) local p = Player(cid) return p and p:getSex() or false end +function getPlayerStorageValue(cid, key) local p = Player(cid) return p and p:getStorageValue(key) or false end +function getPlayerBalance(cid) local p = Player(cid) return p and p:getBankBalance() or false end +function getPlayerMoney(cid) local p = Player(cid) return p and p:getMoney() or false end +function getPlayerGroupId(cid) local p = Player(cid) return p and p:getGroup():getId() or false end +function getPlayerLookDir(cid) local p = Player(cid) return p and p:getDirection() or false end +function getPlayerLight(cid) local p = Player(cid) return p and p:getLight() or false end +function getPlayerDepotItems(cid, depotId) local p = Player(cid) return p and p:getDepotItems(depotId) or false end +function getPlayerSkullType(cid) local p = Player(cid) return p and p:getSkull() or false end +function getPlayerLossPercent(cid) local p = Player(cid) return p and p:getDeathPenalty() or false end +function getPlayerMount(cid, mountId) local p = Player(cid) return p and p:hasMount(mountId) or false end +function getPlayerPremiumDays(cid) local p = Player(cid) return p and p:getPremiumDays() or false end +function getPlayerBlessing(cid, blessing) local p = Player(cid) return p and p:hasBlessing(blessing) or false end +function getPlayerFlagValue(cid, flag) local p = Player(cid) return p ~= nil and p:hasFlag(flag) or false end +function getPlayerParty(cid) + local player = Player(cid) + if player == nil then + return false + end + + local party = player:getParty() + if party == nil then + return nil + end + return party:getLeader():getId() +end +function getPlayerGuildId(cid) + local player = Player(cid) + if player == nil then + return false + end + + local guild = player:getGuild() + if guild == nil then + return false + end + return guild:getId() +end +function getPlayerGuildLevel(cid) local p = Player(cid) return p and p:getGuildLevel() or false end +function getPlayerGuildName(cid) + local player = Player(cid) + if player == nil then + return false + end + + local guild = player:getGuild() + if guild == nil then + return false + end + return guild:getName() +end +function getPlayerGuildRank(cid) + local player = Player(cid) + if player == nil then + return false + end + + local guild = player:getGuild() + if guild == nil then + return false + end + + local rank = guild:getRankByLevel(player:getGuildLevel()) + return rank and rank.name or false +end +function getPlayerGuildNick(cid) local p = Player(cid) return p and p:getGuildNick() or false end +function getPlayerMasterPos(cid) local p = Player(cid) return p and p:getTown():getTemplePosition() or false end +function getPlayerItemCount(cid, itemId, ...) local p = Player(cid) return p and p:getItemCount(itemId, ...) or false end +function getPlayerSlotItem(cid, slot) + local player = Player(cid) + if player == nil then + return pushThing(nil) + end + return pushThing(player:getSlotItem(slot)) +end +function getPlayerItemById(cid, deepSearch, itemId, ...) + local player = Player(cid) + if player == nil then + return pushThing(nil) + end + return pushThing(player:getItemById(itemId, deepSearch, ...)) +end +function getPlayerFood(cid) + local player = Player(cid) + if player == nil then + return false + end + local c = player:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) return c and math.floor(c:getTicks() / 1000) or 0 +end +function canPlayerLearnInstantSpell(cid, name) local p = Player(cid) return p and p:canLearnSpell(name) or false end +function getPlayerLearnedInstantSpell(cid, name) local p = Player(cid) return p and p:hasLearnedSpell(name) or false end +function isPlayerGhost(cid) local p = Player(cid) return p ~= nil and p:isInGhostMode() or false end +function isPlayerPzLocked(cid) local p = Player(cid) return p ~= nil and p:isPzLocked() or false end +function isPremium(cid) local p = Player(cid) return p ~= nil and p:isPremium() or false end +function getBlessingsCost(level) return Blessings.getBlessingsCost(level) end +function getPvpBlessingCost(level) return Blessings.getPvpBlessingCost(level) end +function getPlayersByIPAddress(ip, mask) + if mask == nil then mask = 0xFFFFFFFF end + local masked = bit.band(ip, mask) + local result = {} + for _, player in ipairs(Game.getPlayers()) do + if bit.band(player:getIp(), mask) == masked then + result[#result + 1] = player:getId() + end + end + return result +end +function getOnlinePlayers() + local result = {} + for _, player in ipairs(Game.getPlayers()) do + result[#result + 1] = player:getName() + end + return result +end +function getPlayersByAccountNumber(accountNumber) + local result = {} + for _, player in ipairs(Game.getPlayers()) do + if player:getAccountId() == accountNumber then + result[#result + 1] = player:getId() + end + end + return result +end +function getPlayerGUIDByName(name) + local player = Player(name) + if player then + return player:getGuid() + end + + local resultId = db.storeQuery("SELECT `id` FROM `players` WHERE `name` = " .. db.escapeString(name)) + if resultId ~= false then + local guid = result.getDataInt(resultId, "id") + result.free(resultId) + return guid + end + return 0 +end +function getAccountNumberByPlayerName(name) + local player = Player(name) + if player then + return player:getAccountId() + end + + local resultId = db.storeQuery("SELECT `account_id` FROM `players` WHERE `name` = " .. db.escapeString(name)) + if resultId ~= false then + local accountId = result.getDataInt(resultId, "account_id") + result.free(resultId) + return accountId + end + return 0 +end + +getPlayerAccountBalance = getPlayerBalance +getIpByName = getIPByPlayerName + +function setPlayerStorageValue(cid, key, value) local p = Player(cid) return p and p:setStorageValue(key, value) or false end +function doPlayerSetBalance(cid, balance) local p = Player(cid) return p and p:setBankBalance(balance) or false end +function doPlayerAddMoney(cid, money) local p = Player(cid) return p and p:addMoney(money) or false end +function doPlayerRemoveMoney(cid, money) local p = Player(cid) return p and p:removeMoney(money) or false end +function doPlayerTakeItem(cid, itemid, count) local p = Player(cid) return p and p:removeItem(itemid, count) or false end +function doPlayerAddSoul(cid, soul) local p = Player(cid) return p and p:addSoul(soul) or false end +function doPlayerSetVocation(cid, vocation) local p = Player(cid) return p and p:setVocation(Vocation(vocation)) or false end +function doPlayerSetTown(cid, town) local p = Player(cid) return p and p:setTown(Town(town)) or false end +function setPlayerGroupId(cid, groupId) local p = Player(cid) return p and p:setGroup(Group(groupId)) or false end +function doPlayerSetSex(cid, sex) local p = Player(cid) return p and p:setSex(sex) or false end +function doPlayerSetGuildLevel(cid, level) local p = Player(cid) return p and p:setGuildLevel(level) or false end +function doPlayerSetGuildNick(cid, nick) local p = Player(cid) return p and p:setGuildNick(nick) or false end +function doPlayerSetOfflineTrainingSkill(cid, skillId) local p = Player(cid) return p and p:setOfflineTrainingSkill(skillId) or false end +function doShowTextDialog(cid, itemId, text) local p = Player(cid) return p and p:showTextDialog(itemId, text) or false end +function doPlayerAddItemEx(cid, uid, ...) local p = Player(cid) return p and p:addItemEx(Item(uid), ...) or false end +function doPlayerRemoveItem(cid, itemid, count, ...) local p = Player(cid) return p and p:removeItem(itemid, count, ...) or false end +function doPlayerAddPremiumDays(cid, days) local p = Player(cid) return p and p:addPremiumDays(days) or false end +function doPlayerRemovePremiumDays(cid, days) local p = Player(cid) return p and p:removePremiumDays(days) or false end +function doPlayerAddBlessing(cid, blessing) local p = Player(cid) return p and p:addBlessing(blessing) or false end +function doPlayerAddOutfit(cid, lookType, addons) local p = Player(cid) return p and p:addOutfitAddon(lookType, addons) or false end +function doPlayerRemOutfit(cid, lookType, addons) + local player = Player(cid) + if player == nil then + return false + end + if addons == 255 then + return player:removeOutfit(lookType) + else + return player:removeOutfitAddon(lookType, addons) + end +end +function canPlayerWearOutfit(cid, lookType, addons) local p = Player(cid) return p and p:hasOutfit(lookType, addons) or false end +function doPlayerAddMount(cid, mountId) local p = Player(cid) return p and p:addMount(mountId) or false end +function doPlayerRemoveMount(cid, mountId) local p = Player(cid) return p and p:removeMount(mountId) or false end +function doPlayerSendCancel(cid, text) local p = Player(cid) return p and p:sendCancelMessage(text) or false end +function doPlayerFeed(cid, food) local p = Player(cid) return p and p:feed(food) or false end +function playerLearnInstantSpell(cid, name) local p = Player(cid) return p and p:learnSpell(name) or false end +function doPlayerPopupFYI(cid, message) local p = Player(cid) return p and p:popupFYI(message) or false end +function doSendTutorial(cid, tutorialId) local p = Player(cid) return p and p:sendTutorial(tutorialId) or false end +function doAddMapMark(cid, pos, type, description) local p = Player(cid) return p and p:addMapMark(pos, type, description or "") or false end +function doPlayerSendTextMessage(cid, type, text, ...) local p = Player(cid) return p and p:sendTextMessage(type, text, ...) or false end +function doPlayerSendChannelMessage(cid, author, message, SpeakClasses, channel) local p = Player(cid) return p and p:sendChannelMessage(author, message, SpeakClasses, channel) or false end +function doSendAnimatedText() debugPrint("Deprecated function.") return true end +function doPlayerAddExp(cid, exp, useMult, ...) + local player = Player(cid) + if player == nil then + return false + end + + if useMult then + exp = exp * getRateFromTable(experienceStages, player:getLevel(), configManager.getNumber(configKeys.RATE_EXP)) + end + return player:addExperience(exp, ...) +end +function doPlayerAddManaSpent(cid, mana) local p = Player(cid) return p and p:addManaSpent(mana) or false end +function doPlayerAddSkillTry(cid, skillid, n) local p = Player(cid) return p and p:addSkillTries(skillid, n) or false end +function doPlayerAddMana(cid, mana, ...) local p = Player(cid) return p and p:addMana(mana, ...) or false end +function doPlayerJoinParty(cid, leaderId) + local player = Player(cid) + if player == nil then + return false + end + + if player:getParty() then + player:sendTextMessage(MESSAGE_PARTY_MANAGEMENT, "You are already in a party.") + return true + end + + local leader = Player(leaderId) + if leader == nil then + return false + end + + local party = leader:getParty() + if party == nil or party:getLeader() ~= leader then + return true + end + + for _, invitee in ipairs(party:getInvitees()) do + if player ~= invitee then + return true + end + end + + party:addMember(player) + return true +end +function getPartyMembers(cid) + local player = Player(cid) + if player == nil then + return false + end + + local party = player:getParty() + if party == nil then + return false + end + + local result = {party:getLeader():getId()} + for _, member in ipairs(party:getMembers()) do + result[#result + 1] = member:getId() + end + return result +end + +doPlayerSendDefaultCancel = doPlayerSendCancel + +function getMonsterTargetList(cid) + local monster = Monster(cid) + if monster == nil then + return false + end + + local result = {} + for _, creature in ipairs(monster:getTargetList()) do + if monster:isTarget(creature) then + result[#result + 1] = creature:getId() + end + end + return result +end +function getMonsterFriendList(cid) + local monster = Monster(cid) + if monster == nil then + return false + end + + local z = monster:getPosition().z + + local result = {} + for _, creature in ipairs(monster:getFriendList()) do + if not creature:isRemoved() and creature:getPosition().z == z then + result[#result + 1] = creature:getId() + end + end + return result +end +function doSetMonsterTarget(cid, target) + local monster = Monster(cid) + if monster == nil then + return false + end + + if monster:getMaster() then + return true + end + + local target = Creature(cid) + if target == nil then + return false + end + + monster:selectTarget(target) + return true +end +function doMonsterChangeTarget(cid) + local monster = Monster(cid) + if monster == nil then + return false + end + + if monster:getMaster() then + return true + end + + monster:searchTarget(1) + return true +end +function doCreateNpc(name, pos, ...) + local npc = Game.createNpc(name, pos, ...) return npc and npc:setMasterPos(pos) or false +end +function doSummonCreature(name, pos, ...) + local m = Game.createMonster(name, pos, ...) return m and m:getId() or false +end +function doConvinceCreature(cid, target) + local creature = Creature(cid) + if creature == nil then + return false + end + + local targetCreature = Creature(target) + if targetCreature == nil then + return false + end + + creature:addSummon(targetCreature) + return true +end + +function getTownId(townName) local t = Town(townName) return t and t:getId() or false end +function getTownName(townId) local t = Town(townId) return t and t:getName() or false end +function getTownTemplePosition(townId) local t = Town(townId) return t and t:getTemplePosition() or false end + +function doSetItemActionId(uid, actionId) local i = Item(uid) return i and i:setActionId(actionId) or false end +function doTransformItem(uid, newItemId, ...) local i = Item(uid) return i and i:transform(newItemId, ...) or false end +function doChangeTypeItem(uid, newType) local i = Item(uid) return i and i:transform(i:getId(), newType) or false end +function doRemoveItem(uid, ...) local i = Item(uid) return i and i:remove(...) or false end + +function getContainerSize(uid) local c = Container(uid) return c and c:getSize() or false end +function getContainerCap(uid) local c = Container(uid) return c and c:getCapacity() or false end +function getContainerItem(uid, slot) + local container = Container(uid) + if container == nil then + return pushThing(nil) + end + return pushThing(container:getItem(slot)) +end + +function doAddContainerItemEx(uid, virtualId) + local container = Container(uid) + if container == nil then + return false + end + + local res = container:addItemEx(Item(virtualId)) + if res == nil then + return false + end + return res +end + +function doSendMagicEffect(pos, magicEffect, ...) return Position(pos):sendMagicEffect(magicEffect, ...) end +function doSendDistanceShoot(fromPos, toPos, distanceEffect, ...) return Position(fromPos):sendDistanceEffect(toPos, distanceEffect, ...) end +function isSightClear(fromPos, toPos, floorCheck) return Position(fromPos):isSightClear(toPos, floorCheck) end + +function getPromotedVocation(vocationId) + local vocation = Vocation(vocationId) + if vocation == nil then + return 0 + end + + local promotedVocation = vocation:getPromotion() + if promotedVocation == nil then + return 0 + end + return promotedVocation:getId() +end + +function getGuildId(guildName) + local resultId = db.storeQuery("SELECT `id` FROM `guilds` WHERE `name` = " .. db.escapeString(guildName)) + if resultId == false then + return false + end + + local guildId = result.getDataInt(resultId, "id") + result.free(resultId) + return guildId +end + +function getHouseName(houseId) local h = House(houseId) return h and h:getName() or false end +function getHouseOwner(houseId) local h = House(houseId) return h and h:getOwnerGuid() or false end +function getHouseEntry(houseId) local h = House(houseId) return h and h:getExitPosition() or false end +function getHouseTown(houseId) local h = House(houseId) if h == nil then return false end local t = h:getTown() return t and t:getId() or false end +function getHouseTilesSize(houseId) local h = House(houseId) return h and h:getTileCount() or false end + +function isItemStackable(itemId) return ItemType(itemId):isStackable() end +function isItemRune(itemId) return ItemType(itemId):isRune() end +function isItemDoor(itemId) return ItemType(itemId):isDoor() end +function isItemContainer(itemId) return ItemType(itemId):isContainer() end +function isItemFluidContainer(itemId) return ItemType(itemId):isFluidContainer() end +function isItemMovable(itemId) return ItemType(itemId):isMovable() end +function isCorpse(uid) local i = Item(uid) return i ~= nil and ItemType(i:getId()):isCorpse() or false end + +isItemMoveable = isItemMovable +isMoveable = isMovable + +function getItemName(itemId) return ItemType(itemId):getName() end +function getItemWeight(itemId, ...) return ItemType(itemId):getWeight(...) / 100 end +function getItemDescriptions(itemId) + local itemType = ItemType(itemId) + return { + name = itemType:getName(), + plural = itemType:getPluralName(), + article = itemType:getArticle(), + description = itemType:getDescription() + } +end +function getItemIdByName(name) + local id = ItemType(name):getId() + if id == 0 then + return false + end + return id +end +function getItemWeightByUID(uid, ...) + local item = Item(uid) + if item == nil then + return false + end + + local itemType = ItemType(item:getId()) + return itemType:isStackable() and (itemType:getWeight(item:getCount(), ...) / 100) or (itemType:getWeight(1, ...) / 100) +end +function getItemRWInfo(uid) + local item = Item(uid) + if item == nil then + return false + end + + local rwFlags = 0 + local itemType = ItemType(item:getId()) + if itemType:isReadable() then + rwFlags = bit.bor(rwFlags, 1) + end + + if itemType:isWritable() then + rwFlags = bit.bor(rwFlags, 2) + end + return rwFlags +end +function getContainerCapById(itemId) return ItemType(itemId):getCapacity() end +function getFluidSourceType(itemId) local it = ItemType(itemId) return it.id ~= 0 and it:getFluidSource() or false end +function hasProperty(uid, prop) + local item = Item(uid) + if item == nil then + return false + end + + local parent = item:getParent() + if parent:isTile() and item == parent:getGround() then + return parent:hasProperty(prop) + else + return item:hasProperty(prop) + end +end + +function doSetItemText(uid, text) + local item = Item(uid) + if item == nil then + return false + end + + if text ~= "" then + item:setAttribute(ITEM_ATTRIBUTE_TEXT, text) + else + item:removeAttribute(ITEM_ATTRIBUTE_TEXT) + end + return true +end +function doSetItemSpecialDescription(uid, desc) + local item = Item(uid) + if item == nil then + return false + end + + if desc ~= "" then + item:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, desc) + else + item:removeAttribute(ITEM_ATTRIBUTE_DESCRIPTION) + end + return true +end +function doDecayItem(uid) local i = Item(uid) return i and i:decay() or false end + +function setHouseOwner(id, guid) local h = House(id) return h and h:setOwnerGuid(guid) or false end +function getHouseRent(id) local h = House(id) return h and h:getRent() or nil end +function getHouseAccessList(id, listId) local h = House(id) return h and h:getAccessList(listId) or nil end +function setHouseAccessList(id, listId, listText) local h = House(id) return h and h:setAccessList(listId, listText) or false end + +function getHouseByPlayerGUID(playerGUID) + for _, house in ipairs(Game.getHouses()) do + if house:getOwnerGuid() == playerGUID then + return house:getId() + end + end + return nil +end + +function getTileHouseInfo(pos) + local t = Tile(pos) + if t == nil then + return false + end + local h = t:getHouse() + return h and h:getId() or false +end + +function getTilePzInfo(position) + local t = Tile(position) + if t == nil then + return false + end + return t:hasFlag(TILESTATE_PROTECTIONZONE) +end + +function getTileInfo(position) + local t = Tile(position) + if t == nil then + return false + end + + local ret = pushThing(t:getGround()) + ret.protection = t:hasFlag(TILESTATE_PROTECTIONZONE) + ret.pvp = t:hasFlag(TILESTATE_PVPZONE) + ret.nopvp = t:hasFlag(TILESTATE_NOPVPZONE) + ret.nopz = ret.protection + ret.nologout = t:hasFlag(TILESTATE_NOLOGOUT) + ret.refresh = t:hasFlag(TILESTATE_REFRESH) + ret.house = t:getHouse() ~= nil + ret.bed = t:hasFlag(TILESTATE_BED) + ret.depot = t:hasFlag(TILESTATE_DEPOT) + + ret.things = t:getThingCount() + ret.creatures = t:getCreatureCount() + ret.items = t:getItemCount() + ret.topItems = t:getTopItemCount() + ret.downItems = t:getDownItemCount() + return ret +end + +function getTileItemByType(position, itemType) + local t = Tile(position) + if t == nil then + return pushThing(nil) + end + return pushThing(t:getItemByType(itemType)) +end + +function getTileItemById(position, itemId, ...) + local t = Tile(position) + if t == nil then + return pushThing(nil) + end + return pushThing(t:getItemById(itemId, ...)) +end + +function getTileThingByPos(position) + local t = Tile(position) + if t == nil then + if position.stackpos == -1 then + return -1 + end + return pushThing(nil) + end + + if position.stackpos == -1 then + return t:getThingCount() + end + return pushThing(t:getThing(position.stackpos)) +end + +function getTileThingByTopOrder(position, topOrder) + local t = Tile(position) + if t == nil then + return pushThing(nil) + end + return pushThing(t:getItemByTopOrder(topOrder)) +end + +function getTopCreature(position) + local t = Tile(position) + if t == nil then + return pushThing(nil) + end + return pushThing(t:getTopCreature()) +end + +function queryTileAddThing(thing, position, ...) local t = Tile(position) return t and t:queryAdd(thing, ...) or false end + +function doTeleportThing(uid, dest, pushMovement) + if type(uid) == "userdata" then + if uid:isCreature() then + return uid:teleportTo(dest, pushMovement or false) + else + return uid:moveTo(dest) + end + else + if uid >= 0x10000000 then + local creature = Creature(uid) + if creature then + return creature:teleportTo(dest, pushMovement or false) + end + else + local item = Item(uid) + if item then + return item:moveTo(dest) + end + end + end + return false +end + +function getThingPos(uid) + local thing + if type(uid) ~= "userdata" then + if uid >= 0x10000000 then + thing = Creature(uid) + else + thing = Item(uid) + end + else + thing = uid + end + + if thing == nil then + return false + end + + local stackpos = 0 + local tile = thing:getTile() + if tile then + stackpos = tile:getThingIndex(thing) + end + + local position = thing:getPosition() + position.stackpos = stackpos + return position +end + +function getThingfromPos(pos) + local tile = Tile(pos) + if tile == nil then + return pushThing(nil) + end + + local thing + local stackpos = pos.stackpos or 0 + if stackpos == STACKPOS_TOP_MOVEABLE_ITEM_OR_CREATURE then + thing = tile:getTopCreature() + if thing == nil then + local item = tile:getTopDownItem() + if item and item:getType():isMovable() then + thing = item + end + end + elseif stackpos == STACKPOS_TOP_FIELD then + thing = tile:getFieldItem() + elseif stackpos == STACKPOS_TOP_CREATURE then + thing = tile:getTopCreature() + else + thing = tile:getThing(stackpos) + end + return pushThing(thing) +end + +function doRelocate(fromPos, toPos) + if fromPos == toPos then + return false + end + + local fromTile = Tile(fromPos) + if fromTile == nil then + return false + end + + if Tile(toPos) == nil then + return false + end + + for i = fromTile:getThingCount() - 1, 0, -1 do + local thing = fromTile:getThing(i) + if thing then + if thing:isItem() then + if ItemType(thing:getId()):isMovable() then + thing:moveTo(toPos) + end + elseif thing:isCreature() then + thing:teleportTo(toPos) + end + end + end + return true +end + +function getThing(uid) + return uid >= 0x10000000 and pushThing(Creature(uid)) or pushThing(Item(uid)) +end + +function getConfigInfo(info) + if type(info) ~= "string" then + return nil + end + dofile('config.lua') + return _G[info] +end + +function getWorldCreatures(type) + if type == 0 then + return Game.getPlayerCount() + elseif type == 1 then + return Game.getMonsterCount() + elseif type == 2 then + return Game.getNpcCount() + end + return Game.getPlayerCount() + Game.getMonsterCount() + Game.getNpcCount() +end + +saveData = saveServer + +function getGlobalStorageValue(key) + return Game.getStorageValue(key) or -1 +end + +function setGlobalStorageValue(key, value) + Game.setStorageValue(key, value) + return true +end + +getWorldType = Game.getWorldType + +numberToVariant = Variant +stringToVariant = Variant +positionToVariant = Variant + +function targetPositionToVariant(position) + local variant = Variant(position) + variant.type = VARIANT_TARGETPOSITION + return variant +end + +variantToNumber = Variant.getNumber +variantToString = Variant.getString +variantToPosition = Variant.getPosition + +function doCreateTeleport(itemId, destination, position) + local item = Game.createItem(itemId, 1, position) + if not item:isTeleport() then + item:remove() + return false + end + item:setDestination(destination) + return item:getUniqueId() +end + +function getSpectators(centerPos, rangex, rangey, multifloor, onlyPlayers) + local result = Game.getSpectators(centerPos, multifloor, onlyPlayers or false, rangex, rangex, rangey, rangey) + if #result == 0 then + return nil + end + + for index, spectator in ipairs(result) do + result[index] = spectator:getId() + end + return result +end + +function broadcastMessage(message, messageType) + Game.broadcastMessage(message, messageType) + Spdlog.info("Broadcasted message: \"" .. message .. "\"") +end + +function Guild.addMember(self, player) + return player:setGuild(guild) +end +function Guild.removeMember(self, player) + return player:getGuild() == self and player:setGuild(nil) +end + +function getPlayerInstantSpellCount(cid) local p = Player(cid) return p and #p:getInstantSpells() end +function getPlayerInstantSpellInfo(cid, spellId) + local player = Player(cid) + if not player then + return false + end + + local spell = Spell(spellId) + if not spell or not player:canCast(spell) then + return false + end + + return spell +end + +function doSetItemOutfit(cid, item, time) local c = Creature(cid) return c and c:setItemOutfit(item, time) end +function doSetMonsterOutfit(cid, name, time) local c = Creature(cid) return c and c:setMonsterOutfit(name, time) end +function doSetCreatureOutfit(cid, outfit, time) + local creature = Creature(cid) + if not creature then + return false + end + + local condition = Condition(CONDITION_OUTFIT) + condition:setOutfit(outfit) + condition:setTicks(time) + creature:addCondition(condition) + + return true +end + +function doTileAddItemEx(pos, uid, flags) + local tile = Tile(pos) + if not tile then + return false + end + + local item = Item(uid) + if item then + return tile:addItemEx(item, flags) + end + + return false +end + +function isInArray(array, value) return table.contains(array, value) end + +function doCreateItem(itemid, count, pos) + local tile = Tile(pos) + if not tile then + return false + end + + local item = Game.createItem(itemid, count, pos) + if item then + return item:getUniqueId() + end + return false +end + +function doCreateItemEx(itemid, count) + local item = Game.createItem(itemid, count) + if item then + return item:getUniqueId() + end + return false +end + +function doMoveCreature(cid, direction) local c = Creature(cid) return c ~= nil and c:move(direction) end + +function createFunctions(class) + local exclude = {[2] = {"is"}, [3] = {"get", "set", "add", "can"}, [4] = {"need"}} + local temp = {} + for name, func in pairs(class) do + local add = true + for strLen, strTable in pairs(exclude) do + if table.contains(strTable, name:sub(1, strLen)) then + add = false + end + end + if add then + local str = name:sub(1, 1):upper() .. name:sub(2) + local getFunc = function(self) return func(self) end + local setFunc = function(self, ...) return func(self, ...) end + local get = "get" .. str + local set = "set" .. str + if not (rawget(class, get) and rawget(class, set)) then + table.insert(temp, {set, setFunc, get, getFunc}) + end + end + end + for _, func in ipairs(temp) do + rawset(class, func[1], func[2]) + rawset(class, func[3], func[4]) + end +end + +function doSetCreatureLight(cid, lightLevel, lightColor, time) + local creature = Creature(cid) + if not creature then + return false + end + + local condition = Condition(CONDITION_LIGHT) + condition:setParameter(CONDITION_PARAM_LIGHT_LEVEL, lightLevel) + condition:setParameter(CONDITION_PARAM_LIGHT_COLOR, lightColor) + condition:setTicks(time) + creature:addCondition(condition) + return true +end + +-- this is a fix for lua52 or higher which has the function renamed to table.unpack, while luajit still uses unpack +if unpack == nil then unpack = table.unpack end diff --git a/data/lib/core/bit.lua b/data/lib/core/bit.lua new file mode 100644 index 00000000000..2710e80b4f1 --- /dev/null +++ b/data/lib/core/bit.lua @@ -0,0 +1,42 @@ +-- objeto a ser criado +local BIT ={} + +-- criando a metatable +function BIT:new(number) + return setmetatable({number = number}, { __index = self }) +end + +-- Simplificando a criacao da metatable +function NewBit(number) + return BIT:new(number) +end + +-- checa se a flag tem o valor +function hasBitSet( flag, flags) + return bit.band(flags, flag) ~= 0; +end + +-- setando uma nova flag +function setFlag(bt, flag) + return bit.bor(bt, flag) +end + +-- checa se tem a flag +function BIT:hasFlag(flag) + return hasBitSet( flag, self.number) +end + +-- adiciona uma nova flag +function BIT:updateFlag(flag) + self.number = setFlag(self.number, flag) +end + +-- atualiza o numero/flag por fora da metatable +function BIT:updateNumber(number) + self.number = number +end + +-- retorna o numero/flag +function BIT:getNumber() + return self.number +end diff --git a/data/lib/core/combat.lua b/data/lib/core/combat.lua new file mode 100644 index 00000000000..236ab744738 --- /dev/null +++ b/data/lib/core/combat.lua @@ -0,0 +1,21 @@ +function Combat:getPositions(creature, variant) + local positions = {} + function onTargetTile(creature, position) + positions[#positions + 1] = position + end + + self:setCallback(CALLBACK_PARAM_TARGETTILE, "onTargetTile") + self:execute(creature, variant) + return positions +end + +function Combat:getTargets(creature, variant) + local targets = {} + function onTargetCreature(creature, target) + targets[#targets + 1] = target + end + + self:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") + self:execute(creature, variant) + return targets +end diff --git a/data/lib/core/constants.lua b/data/lib/core/constants.lua new file mode 100644 index 00000000000..9c6d7525cee --- /dev/null +++ b/data/lib/core/constants.lua @@ -0,0 +1,34 @@ +CONTAINER_POSITION = 0xFFFF +ROSHAMUUL_MORTAR_THROWN = 20200 +ROSHAMUUL_KILLED_FRAZZLEMAWS = 20201 +ROSHAMUUL_KILLED_SILENCERS = 20202 +ROSHAMUUL_GOLD_RECORD = 20203 + +SPIKE_FAME_POINTS = 27890 + +SPIKE_UPPER_PACIFIER_MAIN = 27891 +SPIKE_UPPER_PACIFIER_DAILY = 27892 +SPIKE_UPPER_MOUND_MAIN = 27893 +SPIKE_UPPER_MOUND_DAILY = 27894 +SPIKE_UPPER_TRACK_MAIN = 27895 +SPIKE_UPPER_TRACK_DAILY = 27896 +SPIKE_UPPER_KILL_MAIN = 27897 +SPIKE_UPPER_KILL_DAILY = 27898 + +SPIKE_MIDDLE_CHARGE_MAIN = 27899 +SPIKE_MIDDLE_CHARGE_DAILY = 27900 +SPIKE_MIDDLE_MUSHROOM_MAIN = 27901 +SPIKE_MIDDLE_MUSHROOM_DAILY = 27902 +SPIKE_MIDDLE_NEST_MAIN = 27903 +SPIKE_MIDDLE_NEST_DAILY = 27904 +SPIKE_MIDDLE_KILL_MAIN = 27905 +SPIKE_MIDDLE_KILL_DAILY = 27906 + +SPIKE_LOWER_PARCEL_MAIN = 27907 +SPIKE_LOWER_PARCEL_DAILY = 27908 +SPIKE_LOWER_UNDERCOVER_MAIN = 27909 +SPIKE_LOWER_UNDERCOVER_DAILY = 27910 +SPIKE_LOWER_LAVA_MAIN = 27911 +SPIKE_LOWER_LAVA_DAILY = 27912 +SPIKE_LOWER_KILL_MAIN = 27913 +SPIKE_LOWER_KILL_DAILY = 27914 diff --git a/data/lib/core/container.lua b/data/lib/core/container.lua new file mode 100644 index 00000000000..04c90103b2d --- /dev/null +++ b/data/lib/core/container.lua @@ -0,0 +1,65 @@ +function Container.isContainer(self) + return true +end + +function Container.createLootItem(self, item, boolCharm) + if self:getEmptySlots() == 0 then + return true + end + + local itemCount = 0 + local randvalue = getLootRandom() + local lootBlockType = ItemType(item.itemId) + local chanceTo = item.chance + + if not lootBlockType then + return + end + + if boolCharm and lootBlockType:getType() == ITEM_TYPE_CREATUREPRODUCT then + chanceTo = (chanceTo * (GLOBAL_CHARM_GUT + 100))/100 + end + + if randvalue < chanceTo then + if lootBlockType:isStackable() then + local maxc, minc = item.maxCount or 1, item.minCount or 1 + itemCount = math.max(0, randvalue % (maxc - minc + 1)) + minc + else + itemCount = 1 + end + end + + while (itemCount > 0) do + local n = math.min(itemCount, 100) + itemCount = itemCount - n + + local tmpItem = self:addItem(item.itemId, n) + if not tmpItem then + return false + end + + if tmpItem:isContainer() then + for i = 1, #item.childLoot do + if not tmpItem:createLootItem(item.childLoot[i]) then + tmpItem:remove() + return false + end + end + end + + if item.subType ~= -1 then + tmpItem:transform(item.itemId, item.subType) + elseif lootBlockType:isFluidContainer() then + tmpItem:transform(item.itemId, 0) + end + + if item.actionId ~= -1 then + tmpItem:setActionId(item.actionId) + end + + if item.text and item.text ~= "" then + tmpItem:setText(item.text) + end + end + return true +end diff --git a/data/lib/core/core.lua b/data/lib/core/core.lua new file mode 100644 index 00000000000..4247d9424ba --- /dev/null +++ b/data/lib/core/core.lua @@ -0,0 +1,21 @@ +dofile('data/lib/core/storages.lua') +dofile('data/lib/core/bit.lua') +dofile('data/lib/core/combat.lua') +dofile('data/lib/core/constants.lua') +dofile('data/lib/core/container.lua') +dofile('data/lib/core/creature.lua') +dofile('data/lib/core/functions.lua') +dofile('data/lib/core/game.lua') +dofile('data/lib/core/imbuements.lua') +dofile('data/lib/core/item.lua') +dofile('data/lib/core/itemtype.lua') +dofile('data/lib/core/monster.lua') +dofile('data/lib/core/party.lua') +dofile('data/lib/core/player.lua') +dofile('data/lib/core/position.lua') +dofile('data/lib/core/string.lua') +dofile('data/lib/core/tables.lua') +dofile('data/lib/core/teleport.lua') +dofile('data/lib/core/tile.lua') +dofile('data/lib/core/quests.lua') +dofile('data/lib/core/vocation.lua') diff --git a/data/lib/core/creature.lua b/data/lib/core/creature.lua new file mode 100644 index 00000000000..7791b0a3349 --- /dev/null +++ b/data/lib/core/creature.lua @@ -0,0 +1,199 @@ +function Creature.getClosestFreePosition(self, position, maxRadius, mustBeReachable) + maxRadius = maxRadius or 1 + + -- backward compatability (extended) + if maxRadius == true then + maxRadius = 2 + end + + local checkPosition = Position(position) + for radius = 0, maxRadius do + checkPosition.x = checkPosition.x - math.min(1, radius) + checkPosition.y = checkPosition.y + math.min(1, radius) + + local total = math.max(1, radius * 8) + for i = 1, total do + if radius > 0 then + local direction = math.floor((i - 1) / (radius * 2)) + checkPosition:getNextPosition(direction) + end + + local tile = Tile(checkPosition) + if tile:getCreatureCount() == 0 and not tile:hasProperty(CONST_PROP_IMMOVABLEBLOCKSOLID) and + (not mustBeReachable or self:getPathTo(checkPosition)) then + return checkPosition + end + end + end + return Position() +end + +function Creature.getMonster(self) + return self:isMonster() and self or nil +end + +function Creature.getPlayer(self) + return self:isPlayer() and self or nil +end + +function Creature.isContainer(self) + return false +end + +function Creature.isItem(self) + return false +end + +function Creature.isMonster(self) + return false +end + +function Creature.isNpc(self) + return false +end + +function Creature.isPlayer(self) + return false +end + +function Creature.isTeleport(self) + return false +end + +function Creature.isTile(self) + return false +end + +function Creature:setMonsterOutfit(monster, time) + local monsterType = MonsterType(monster) + if not monsterType then + return false + end + + if self:isPlayer() and not (self:hasFlag(PlayerFlag_CanIllusionAll) or monsterType:isIllusionable()) then + return false + end + + local condition = Condition(CONDITION_OUTFIT) + condition:setOutfit(monsterType:getOutfit()) + condition:setTicks(time) + self:addCondition(condition) + + return true +end + +function Creature:setItemOutfit(item, time) + local itemType = ItemType(item) + if not itemType then + return false + end + + local condition = Condition(CONDITION_OUTFIT) + condition:setOutfit({ + lookTypeEx = itemType:getId() + }) + condition:setTicks(time) + self:addCondition(condition) + + return true +end + +function Creature:addSummon(monster) + local summon = Monster(monster) + if not summon then + return false + end + + summon:setTarget(nil) + summon:setFollowCreature(nil) + summon:setDropLoot(false) + summon:setSkillLoss(false) + summon:setMaster(self) + + return true +end + +function Creature:removeSummon(monster) + local summon = Monster(monster) + if not summon or summon:getMaster() ~= self then + return false + end + + summon:setTarget(nil) + summon:setFollowCreature(nil) + summon:setDropLoot(true) + summon:setSkillLoss(true) + summon:setMaster(nil) + + return true +end + +function Creature:addDamageCondition(target, type, list, damage, period, rounds) + if damage <= 0 or not target or target:isImmune(type) then + return false + end + + local condition = Condition(type) + condition:setParameter(CONDITION_PARAM_OWNER, self:getId()) + condition:setParameter(CONDITION_PARAM_DELAYED, true) + + if list == DAMAGELIST_EXPONENTIAL_DAMAGE then + local exponent, value = -10, 0 + while value < damage do + value = math.floor(10 * math.pow(1.2, exponent) + 0.5) + condition:addDamage(1, period or 4000, -value) + + if value >= damage then + local permille = math.random(10, 1200) / 1000 + condition:addDamage(1, period or 4000, -math.max(1, math.floor(value * permille + 0.5))) + else + exponent = exponent + 1 + end + end + elseif list == DAMAGELIST_LOGARITHMIC_DAMAGE then + local n, value = 0, damage + while value > 0 do + value = math.floor(damage * math.pow(2.718281828459, -0.05 * n) + 0.5) + if value ~= 0 then + condition:addDamage(1, period or 4000, -value) + n = n + 1 + end + end + elseif list == DAMAGELIST_VARYING_PERIOD then + for _ = 1, rounds do + condition:addDamage(1, math.random(period[1], period[2]) * 1000, -damage) + end + elseif list == DAMAGELIST_CONSTANT_PERIOD then + condition:addDamage(rounds, period * 1000, -damage) + end + + target:addCondition(condition) + return true +end + +function Creature.checkCreatureInsideDoor(player, toPosition) + local creature = Tile(toPosition):getTopCreature() + if creature then + toPosition.x = toPosition.x + 1 + local query = Tile(toPosition):queryAdd(creature, bit.bor(FLAG_IGNOREBLOCKCREATURE, FLAG_PATHFINDING)) + if query ~= RETURNVALUE_NOERROR then + toPosition.x = toPosition.x - 1 + toPosition.y = toPosition.y + 1 + query = Tile(toPosition):queryAdd(creature, bit.bor(FLAG_IGNOREBLOCKCREATURE, FLAG_PATHFINDING)) + end + if query ~= RETURNVALUE_NOERROR then + toPosition.y = toPosition.y - 2 + query = Tile(toPosition):queryAdd(creature, bit.bor(FLAG_IGNOREBLOCKCREATURE, FLAG_PATHFINDING)) + end + if query ~= RETURNVALUE_NOERROR then + toPosition.x = toPosition.x - 1 + toPosition.y = toPosition.y + 1 + query = Tile(toPosition):queryAdd(creature, bit.bor(FLAG_IGNOREBLOCKCREATURE, FLAG_PATHFINDING)) + end + if query ~= RETURNVALUE_NOERROR then + player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + return true + end + creature:teleportTo(toPosition, true) + end +end diff --git a/data/lib/core/functions.lua b/data/lib/core/functions.lua new file mode 100644 index 00000000000..f6748223f3a --- /dev/null +++ b/data/lib/core/functions.lua @@ -0,0 +1,920 @@ +-- From here down are the functions of TFS +function getTibiaTimerDayOrNight() + local light = getWorldLight() + if (light == 40) then + return "night" + else + return "day" + end +end + +function getFormattedWorldTime() + local worldTime = getWorldTime() + local hours = math.floor(worldTime / 60) + + local minutes = worldTime % 60 + if minutes < 10 then + minutes = '0' .. minutes + end + return hours .. ':' .. minutes +end + +function getLootRandom() + return math.random(0, MAX_LOOTCHANCE) * 100 / (configManager.getNumber(configKeys.RATE_LOOT) * SCHEDULE_LOOT_RATE) +end + +local start = os.time() +local linecount = 0 +debug.sethook(function(event, line) + linecount = linecount + 1 + if os.mtime() - start >= 1 then + if linecount >= 30000 then + Spdlog.warn(string.format("[debug.sethook] - Possible infinite loop in file [%s] near line [%d]", + debug.getinfo(2).source, line)) + debug.sethook() + end + linecount = 0 + start = os.time() + end +end, "l") + +-- OTServBr-Global functions +function getJackLastMissionState(player) + if player:getStorageValue(Storage.TibiaTales.JackFutureQuest.LastMissionState) == 1 then + return "You told Jack the truth about his personality. You also explained that you and Spectulus \z + made a mistake by assuming him as the real Jack." + else + return "You lied to the confused Jack about his true personality. You and Spectulus made him \z + believe that he is in fact a completely different person. Now he will never be able to find out the truth." + end +end + +function getRateFromTable(t, level, default) + for _, rate in ipairs(t) do + if level >= rate.minlevel and (not rate.maxlevel or level <= rate.maxlevel) then + return rate.multiplier + end + end + return default +end + +function getAccountNumberByPlayerName(name) + local player = Player(name) + if player ~= nil then + return player:getAccountId() + end + + local resultId = db.storeQuery("SELECT `account_id` FROM `players` WHERE `name` = " .. db.escapeString(name)) + if resultId ~= false then + local accountId = result.getNumber(resultId, "account_id") + result.free(resultId) + return accountId + end + return 0 +end + +function getMoneyCount(string) + local b, + e = string:find("%d+") + local money = b and e and tonumber(string:sub(b, e)) or -1 + if isValidMoney(money) then + return money + end + return -1 +end + +function getBankMoney(cid, amount) + local player = Player(cid) + if player:getBankBalance() >= amount then + player:setBankBalance(player:getBankBalance() - amount) + player:sendTextMessage(MESSAGE_TRADE, "Paid " .. amount .. " gold from bank account. Your account balance is now " .. player:getBankBalance() .. " gold.") + return true + end + return false +end + +function getMoneyWeight(money) + local gold = money + local crystal = math.floor(gold / 10000) + gold = gold - crystal * 10000 + local platinum = math.floor(gold / 100) + gold = gold - platinum * 100 + return (ItemType(2160):getWeight() * crystal) + (ItemType(2152):getWeight() * platinum) + + (ItemType(2148):getWeight() * gold) +end + +function getRealDate() + local month = tonumber(os.date("%m", os.time())) + local day = tonumber(os.date("%d", os.time())) + + if month < 10 then + month = "0" .. month + end + if day < 10 then + day = "0" .. day + end + return day .. "/" .. month +end + +function getRealTime() + local hours = tonumber(os.date("%H", os.time())) + local minutes = tonumber(os.date("%M", os.time())) + + if hours < 10 then + hours = "0" .. hours + end + if minutes < 10 then + minutes = "0" .. minutes + end + return hours .. ":" .. minutes +end + +-- Marry +function getPlayerSpouse(id) + local resultQuery = db.storeQuery("SELECT `marriage_spouse` FROM `players` WHERE `id` = " .. db.escapeString(id)) + if resultQuery ~= false then + local ret = result.getDataInt(resultQuery, "marriage_spouse") + result.free(resultQuery) + return ret + end + return -1 +end + +function getPlayerMarriageStatus(id) + local resultQuery = db.storeQuery("SELECT `marriage_status` FROM `players` WHERE `id` = " .. db.escapeString(id)) + if resultQuery ~= false then + local ret = result.getDataInt(resultQuery, "marriage_status") + result.free(resultQuery) + return ret + end + return -1 +end + +function getPlayerNameById(id) + local resultName = db.storeQuery("SELECT `name` FROM `players` WHERE `id` = " .. db.escapeString(id)) + local name = result.getDataString(resultName, "name") + if resultName ~= false then + result.free(resultName) + return name + end + return false +end + +function setPlayerSpouse(id, val) + db.query("UPDATE `players` SET `marriage_spouse` = " .. val .. " WHERE `id` = " .. id) +end + +function setPlayerMarriageStatus(id, val) + db.query("UPDATE `players` SET `marriage_status` = " .. val .. " WHERE `id` = " .. id) +end + +-- The following 2 functions can be used for delayed shouted text +function say(param) + selfSay(text) + doCreatureSay(param.cid, param.text, 1) +end + +function delayedSay(text, delay) + local delaySay = delay or 0 + local cid = getNpcCid() + addEvent(say, delaySay, {cid = cid, text = text}) +end + +function clearBossRoom(playerId, bossId, centerPosition, rangeX, rangeY, exitPosition) + local spectators, + spectator = Game.getSpectators(centerPosition, false, false, rangeX, rangeX, rangeY, rangeY) + for i = 1, #spectators do + spectator = spectators[i] + if spectator:isPlayer() and spectator.uid == playerId then + spectator:teleportTo(exitPosition) + exitPosition:sendMagicEffect(CONST_ME_TELEPORT) + end + + if spectator:isMonster() then + spectator:remove() + end + end +end + +function clearRoom(centerPosition, rangeX, rangeY, resetGlobalStorage) + local spectators, + spectator = Game.getSpectators(centerPosition, false, false, rangeX, rangeX, rangeY, rangeY) + for i = 1, #spectators do + spectator = spectators[i] + if spectator:isMonster() then + spectator:remove() + end + end + if Game.getStorageValue(resetGlobalStorage) == 1 then + Game.setStorageValue(resetGlobalStorage, -1) + end +end + +function roomIsOccupied(centerPosition, rangeX, rangeY) + local spectators = Game.getSpectators(centerPosition, false, false, rangeX, rangeX, rangeY, rangeY) + if #spectators ~= 0 then + return true + end + return false +end + +function clearForgotten(fromPosition, toPosition, exitPosition, storage) + for x = fromPosition.x, toPosition.x do + for y = fromPosition.y, toPosition.y do + for z = fromPosition.z, toPosition.z do + if Tile(Position(x, y, z)) then + local creature = Tile(Position(x, y, z)):getTopCreature() + if creature then + if creature:isPlayer() then + creature:teleportTo(exitPosition) + exitPosition:sendMagicEffect(CONST_ME_TELEPORT) + creature:say("Time out! You were teleported out by strange forces.", TALKTYPE_MONSTER_SAY) + elseif creature:isMonster() then + creature:remove() + end + end + end + end + end + end + Game.setStorageValue(storage, 0) +end + +function isValidMoney(money) + return isNumber(money) and money > 0 and money < 4294967296 +end + +function iterateArea(func, from, to) + for z = from.z, to.z do + for y = from.y, to.y do + for x = from.x, to.x do + func(Position(x, y, z)) + end + end + end +end + +function playerExists(name) + local resultId = db.storeQuery("SELECT `name` FROM `players` WHERE `name` = " .. db.escapeString(name)) + if resultId then + result.free(resultId) + return true + end + return false +end + +function functionRevert() + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Corrupted, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Desert, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Dimension, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Grass, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Ice, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Mushroom, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Roshamuul, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Venom, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats, 0) + for a = 1, #basins do + local item = Tile(basins[a].pos):getItemById(24852) + item:transform(12070) + end + local specs, spec = Game.getSpectators(Position(33629, 32693, 12), false, false, 25, 25, 85, 85) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + spec:teleportTo(Position(33630, 32648, 12)) + spec:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + spec:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You were teleported because the habitats are returning to their original form.') + elseif spec:isMonster() then + spec:remove() + end + end + for x = 33611, 33625 do + for y = 32658, 32727 do + local position = Position(x, y, 12) + local tile = Tile(position) + if not tile then + return + end + local ground = tile:getGround() + if not ground then + return + end + ground:remove() + local items = tile:getItems() + if items then + for i = 1, #items do + local item = items[i] + item:remove() + end + end + end + end + + for x = 33634, 33648 do + for y = 32658, 32727 do + local position = Position(x, y, 12) + local tile = Tile(position) + if not tile then + return + end + local ground = tile:getGround() + if not ground then + return + end + ground:remove() + local items = tile:getItems() + if items then + for i = 1, #items do + local item = items[i] + item:remove() + end + end + end + end + + Game.loadMap('data/world/worldchanges/habitats.otbm') + return true +end + +function checkWallArito(item, toPosition) + if (not item:isItem()) then + return false + end + local wallTile = Tile(Position(33206, 32536, 6)) + if not wallTile or wallTile:getItemCountById(8202) > 0 then + return false + end + local checkEqual = { + [2016] = {Position(33207, 32537, 6), {5858, -1}, Position(33205, 32537, 6)}, + [2419] = {Position(33205, 32537, 6), {2016, 1}, Position(33207, 32537, 6), 5858} + } + local it = checkEqual[item:getId()] + if (it and it[1] == toPosition and Tile(it[3]):getItemCountById(it[2][1], it[2][2]) > 0) then + wallTile:getItemById(877):transform(8202) + + if (it[4]) then + item:transform(it[4]) + end + + addEvent( + function() + if (Tile(Position(33206, 32536, 6)):getItemCountById(8210) > 0) then + Tile(Position(33206, 32536, 6)):getItemById(8210):transform(877) + end + if (Tile(Position(33205, 32537, 6)):getItemCountById(5858) > 0) then + Tile(Position(33205, 32537, 6)):getItemById(5858):remove() + end + end, + 5 * 60 * 1000 + ) + else + if (it and it[4] and it[1] == toPosition) then + item:transform(it[4]) + end + end +end + +function placeSpawnRandom(fromPositon, toPosition, monsterName, ammount, hasCall, storage, value, removestorage, + sharedHP, event, message) + for _x = fromPositon.x, toPosition.x do + for _y = fromPositon.y, toPosition.y do + for _z = fromPositon.z, toPosition.z do + local tile = Tile(Position(_x, _y, _z)) + if not removestorage then + if tile and tile:getTopCreature() and tile:getTopCreature():isMonster() and + tile:getTopCreature():getName() == monsterName + then + tile:getTopCreature():remove() + end + else + if tile and tile:getTopCreature() and tile:getTopCreature():isMonster() and + tile:getTopCreature():getStorageValue(storage) == value + then + tile:getTopCreature():remove() + end + end + end + end + end + if ammount and ammount > 0 then + local summoned = 0 + local tm = os.time() + repeat + local tile = false + -- repeat + local position = { + x = math.random(fromPositon.x, toPosition.x), + y = math.random(fromPositon.y, toPosition.y), + z = math.random(fromPositon.z, toPosition.z) + } + -- tile = Tile(position) + -- passing = tile and #tile:getItems() <= 0 + -- until (passing == true) + local monster = Game.createMonster(monsterName, position) + if monster then + summoned = summoned + 1 + -- Set first spawn + monster:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + if (hasCall) then + monster:setStorage(storage, value) + if sharedHP then + monster:beginSharedLife(tm) + monster:registerEvent("sharedLife") + end + if event then + monster:registerEvent(event) + end + local function SendMessage(mit, message) + if not Monster(mit) then + return false + end + Monster(mit):say(message, TALKTYPE_MONSTER_SAY) + end + if message then + addEvent(SendMessage, 200, monster:getId(), message) + end + end + end + until (summoned == ammount) + end +end + +function getMonstersInArea(fromPos, toPos, monsterName, ignoreMonsterId) + local monsters = {} + for _x = fromPos.x, toPos.x do + for _y = fromPos.y, toPos.y do + for _z = fromPos.z, toPos.z do + local tile = Tile(Position(_x, _y, _z)) + if tile and tile:getTopCreature() then + for _, pid in pairs(tile:getCreatures()) do + local mt = Monster(pid) + if not ignoreMonsterId then + if (mt and mt:isMonster() and mt:getName():lower() == monsterName:lower() and not mt:getMaster()) then + monsters[#monsters + 1] = mt + end + else + if (mt and mt:isMonster() and mt:getName():lower() == monsterName:lower() + and not mt:getMaster() and ignoreMonsterId ~= mt:getId()) then + monsters[#monsters + 1] = mt + end + end + end + end + end + end + end + return monsters +end + +function isPlayerInArea(fromPos, toPos) + for _x = fromPos.x, toPos.x do + for _y = fromPos.y, toPos.y do + for _z = fromPos.z, toPos.z do + creature = getTopCreature({x = _x, y = _y, z = _z}) + if (isPlayer(creature.uid)) then + return true + end + end + end + end + return false +end + +function cleanAreaQuest(frompos, topos, itemtable, blockmonsters) + if not itemtable then + itemtable = {} + end + if not blockmonsters then + blockmonsters = {} + end + for _x = frompos.x, topos.x do + for _y = frompos.y, topos.y do + for _z = frompos.z, topos.z do + local tile = Tile(Position(_x, _y, _z)) + if tile then + local itc = tile:getItems() + if itc and tile:getItemCount() > 0 then + for _, pid in pairs(itc) do + local itp = ItemType(pid:getId()) + if itp and itp:isCorpse() then + pid:remove() + end + end + end + for _, pid in pairs(itemtable) do + local _until = tile:getItemCountById(pid) + if _until > 0 then + for i = 1, _until do + local it = tile:getItemById(pid) + if it then + it:remove() + end + end + end + end + local mtempc = tile:getCreatures() + if mtempc and tile:getCreatureCount() > 0 then + for _, pid in pairs(mtempc) do + if pid:isMonster() and not isInArray(blockmonsters, pid:getName():lower()) then + -- broadcastMessage(pid:getName()) + pid:remove() + end + end + end + end + end + end + end + return true +end + +function kickerPlayerRoomAfferMin(playername, fromPosition, toPosition, teleportPos, message, monsterName, minutes, + firstCall, itemtable, blockmonsters) + local players = false + if type(playername) == table then + players = true + end + local player = false + if not players then + player = Player(playername) + end + local monster = {} + if monsterName ~= "" then + monster = getMonstersInArea(fromPosition, toPosition, monsterName) + end + if player == false and players == false then + return false + end + if not players and player then + if player:getPosition():isInRange(fromPosition, toPosition) and minutes == 0 then + if monsterName ~= "" then + for _, pid in pairs(monster) do + if pid:isMonster() then + if pid:getStorageValue("playername") == playername then + pid:remove() + end + end + end + else + if not itemtable then + itemtable = {} + end + if not blockmonsters then + blockmonsters = {} + end + cleanAreaQuest(fromPosition, toPosition, itemtable, blockmonsters) + end + player:teleportTo(teleportPos, true) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, message) + return true + end + else + if minutes == 0 then + if monsterName ~= "" then + for _, pid in pairs(monster) do + if pid:isMonster() then + if pid:getStorageValue("playername") == playername then + pid:remove() + end + end + end + else + if not itemtable then + itemtable = {} + end + if not blockmonsters then + blockmonsters = {} + end + cleanAreaQuest(fromPosition, toPosition, itemtable, blockmonsters) + end + for _, pid in pairs(playername) do + local player = Player(pid) + if player and player:getPosition():isInRange(fromPosition, toPosition) then + player:teleportTo(teleportPos, true) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, message) + end + end + return true + end + end + local min = 60 -- Use the 60 for 1 minute + if (firstCall) then + addEvent( kickerPlayerRoomAfferMin, 1000, playername, fromPosition, toPosition, teleportPos, message, + monsterName, minutes, false, itemtable, blockmonsters) + else + local subt = minutes - 1 + if (monsterName ~= "") then + if minutes > 3 and table.maxn(monster) == 0 then + subt = 2 + end + end + addEvent(kickerPlayerRoomAfferMin, min * 1000, playername, fromPosition, toPosition, teleportPos, message, + monsterName, subt, false, itemtable, blockmonsters) + end +end + +function checkWeightAndBackpackRoom(player, itemWeight, message) + local backpack = player:getSlotItem(CONST_SLOT_BACKPACK) + if not backpack or backpack:getEmptySlots(true) < 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, message .. ", but you have no room to take it.") + return false + end + if (player:getFreeCapacity() / 100) < itemWeight then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + message .. ". Weighing " .. itemWeight .. " oz, it is too heavy for you to carry.") + return false + end + return true +end + +function doCreatureSayWithRadius(cid, text, type, radiusx, radiusy, position) + if not position then + position = Creature(cid):getPosition() + end + + local spectators, spectator = Game.getSpectators(position, false, true, radiusx, radiusx, radiusy, radiusy) + for i = 1, #spectators do + spectator = spectators[i] + spectator:say(text, type, false, spectator, position) + end +end + +--Boss entry +if not bosssPlayers then + bosssPlayers = { + addPlayers = function (self, cid) + local player = Player(cid) + if not player then return false end + if not self.players then + self.players = {} + end + self.players[player:getId()] = 1 + end, + removePlayer = function (self, cid) + local player = Player(cid) + if not player then return false end + if not self.players then return false end + self.players[player:getId()] = nil + end, + getPlayersCount = function (self) + if not self.players then return 0 end + local c = 0 + for _ in pairs(self.players) do c = c + 1 end + return c + end + } +end + +function isInRange(pos, fromPos, toPos) + return pos.x >= fromPos.x and pos.y >= fromPos.y + and pos.z >= fromPos.z and pos.x <= toPos.x + and pos.y <= toPos.y and pos.z <= toPos.z +end + +function isNumber(str) + return tonumber(str) ~= nil +end + +function isInteger(n) + return (type(n) == "number") and (math.floor(n) == n) +end + +-- Function for the reload talkaction +local logFormat = "[%s] %s %s" + +function logCommand(player, words, param) + local file = io.open("data/logs/" .. player:getName() .. " commands.log", "a") + if not file then + return + end + + io.output(file) + io.write(logFormat:format(os.date("%d/%m/%Y %H:%M"), words, param):trim() .. "\n") + io.close(file) +end + +-- Special lib functions +function insertIndex(i, buffer) + table.insert(buffer, "[") + if type(i) == "string" then + table.insert(buffer, '"') + table.insert(buffer, i) + table.insert(buffer, '"') + elseif type(i) == "number" then + table.insert(buffer, tostring(i)) + end + table.insert(buffer, "] = ") +end + +function indexToStr(i, v, buffer) + local tp = type(v) + local itp = type(i) + if itp ~= "number" and itp ~= "string" then + Spdlog.warn("[indexToStr] - Invalid index to serialize: " .. type(i)) + else + if tp == "table" then + insertIndex(i, buffer) + serializeTable(v, buffer) + table.insert(buffer, ",") + elseif tp == "number" then + insertIndex(i, buffer) + table.insert(buffer, tostring(v)) + table.insert(buffer, ",") + elseif tp == "string" then + insertIndex(i, buffer) + table.insert(buffer, '"') + table.insert(buffer, v) + table.insert(buffer, '",') + elseif tp == "boolean" then + insertIndex(i, buffer) + table.insert(buffer, v == true and "true" or "false") + table.insert(buffer, ",") + else + Spdlog.warn("[indexToStr] - Invalid type to serialize: " .. tp .. ", index: " .. i) + end + end +end + +function serializeTable(t, buffer) + local buffer = buffer or {} + table.insert(buffer, "{") + for i, x in pairs(t) do + indexToStr(i, x, buffer) + end + table.insert(buffer, "}") + return table.concat(buffer) +end + +function table.copy(t, out) + out = out or {} + if type(t) ~= "table" then + return false + end + + for i, x in pairs(t) do + if type(x) == "table" then + out[i] = {} + table.copy(t[i], out[i]) + else + out[i] = x + end + end + return out +end + +function unserializeTable(str, out) + local tmp = load("return " .. str) + if tmp then + tmp = tmp() + else + Spdlog.warn("[unserializeTable] - Unserialization error: " .. str) + return false + end + return table.copy(tmp, out) +end + +local function setTableIndexes(t, i, v, ...) + if i and v then + t[i] = v + return setTableIndexes(t, ...) + end +end + +local function getTableIndexes(t, i, ...) + if i then + return t[i], getTableIndexes(t, ...) + end +end + +function unpack2(tab, i) + local i, v = next(tab, i) + if next(tab, i) then + return i, v, unpack2(tab, i) + else + return i, v + end +end + +function pack(t, ...) + for i = 1, select("#", ...) do + local tmp = select(i, ...) + t[i] = tmp + end + return t +end + +function Item:setSpecialAttribute(...) + local tmp + if self:hasAttribute(ITEM_ATTRIBUTE_SPECIAL) then + tmp = self:getAttribute(ITEM_ATTRIBUTE_SPECIAL) + else + tmp = "{}" + end + + local tab = unserializeTable(tmp) + if tab then + setTableIndexes(tab, ...) + tmp = serializeTable(tab) + self:setAttribute(ITEM_ATTRIBUTE_SPECIAL, tmp) + return true + end +end + +function Item:getSpecialAttribute(...) + local tmp + if self:hasAttribute(ITEM_ATTRIBUTE_SPECIAL) then + tmp = self:getAttribute(ITEM_ATTRIBUTE_SPECIAL) + else + tmp = "{}" + end + + local tab = unserializeTable(tmp) + if tab then + return getTableIndexes(tab, ...) + end +end + +if not PLAYER_STORAGE then + PLAYER_STORAGE = {} +end + +function Player:setSpecialStorage(storage, value) + if not PLAYER_STORAGE[self:getGuid()] then + self:loadSpecialStorage() + end + + PLAYER_STORAGE[self:getGuid()][storage] = value +end + +function Player:getSpecialStorage(storage) + if not PLAYER_STORAGE[self:getGuid()] then + self:loadSpecialStorage() + end + + return PLAYER_STORAGE[self:getGuid()][storage] +end + +function Player:loadSpecialStorage() + if not PLAYER_STORAGE then + PLAYER_STORAGE = {} + end + + PLAYER_STORAGE[self:getGuid()] = {} + local resultId = db.storeQuery("SELECT * FROM `player_misc` WHERE `player_id` = " .. self:getGuid()) + if resultId then + local info = result.getStream(resultId , "info") or "{}" + unserializeTable(info, PLAYER_STORAGE[self:getGuid()]) + end +end + +function Player:saveSpecialStorage() + if PLAYER_STORAGE and PLAYER_STORAGE[self:getGuid()] then + local tmp = serializeTable(PLAYER_STORAGE[self:getGuid()]) + db.query("DELETE FROM `player_misc` WHERE `player_id` = " .. self:getGuid()) + db.query(string.format("INSERT INTO `player_misc` (`player_id`, `info`) VALUES (%d, %s)", self:getGuid(), db.escapeBlob(tmp, #tmp))) + end +end + +-- Can be used in every boss +function kickPlayersAfterTime(players, fromPos, toPos, exit) + for _, pid in pairs(players) do + local player = Player(pid) + if player and player:getPosition():isInRange(fromPos, toPos) then + player:teleportTo(exit) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You were kicked by exceding time inside the boss room.') + end + end +end + +function Player:doCheckBossRoom(bossName, fromPos, toPos) + if self then + for x = fromPos.x, toPos.x do + for y = fromPos.y, toPos.y do + for z = fromPos.z, toPos.z do + local sqm = Tile(Position(x, y, z)) + if sqm then + if sqm:getTopCreature() and sqm:getTopCreature():isPlayer() then + self:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You must wait. Someone is challenging '..bossName..' now.') + return false + end + end + end + end + end + -- Room cleaning + for x = fromPos.x, toPos.x do + for y = fromPos.y, toPos.y do + for z = fromPos.z, toPos.z do + local sqm = Tile(Position(x, y, z)) + if sqm and sqm:getTopCreature() then + local monster = sqm:getTopCreature() + if monster then + monster:remove() + end + end + end + end + end + end + return true +end diff --git a/data/lib/core/game.lua b/data/lib/core/game.lua new file mode 100644 index 00000000000..5203dd9e9e1 --- /dev/null +++ b/data/lib/core/game.lua @@ -0,0 +1,119 @@ +function getGlobalStorageValueDB(key) + local resultId = db.storeQuery("SELECT `value` FROM `global_storage` WHERE `key` = " .. key) + if resultId ~= false then + local val = result.getString(resultId, "value") + result.free(resultId) + return val + end + return -1 +end + +function setGlobalStorageValueDB(key, value) + db.query("INSERT INTO `global_storage` (`key`, `value`) VALUES (".. key ..", ".. value ..") ON DUPLICATE KEY UPDATE `value` = ".. value) +end + +function Game.broadcastMessage(message, messageType) + if not messageType then + messageType = MESSAGE_GAME_HIGHLIGHT + end + + for _, player in ipairs(Game.getPlayers()) do + player:sendTextMessage(messageType, message) + end +end + +function Game.convertIpToString(ip) + local band = bit.band + local rshift = bit.rshift + return string.format("%d.%d.%d.%d", + band(ip, 0xFF), + band(rshift(ip, 8), 0xFF), + band(rshift(ip, 16), 0xFF), + rshift(ip, 24) + ) +end + +function Game.getHouseByPlayerGUID(playerGUID) + local houses, house = Game.getHouses() + for i = 1, #houses do + house = houses[i] + if house:getOwnerGuid() == playerGUID then + return house + end + end + return nil +end + +function Game.getPlayersByAccountNumber(accountNumber) + local result = {} + local players, player = Game.getPlayers() + for i = 1, #players do + player = players[i] + if player:getAccountId() == accountNumber then + result[#result + 1] = player + end + end + return result +end + +function Game.getPlayersByIPAddress(ip, mask) + if not mask then mask = 0xFFFFFFFF end + local masked = bit.band(ip, mask) + local result = {} + local players, player = Game.getPlayers() + for i = 1, #players do + player = players[i] + if bit.band(player:getIp(), mask) == masked then + result[#result + 1] = player + end + end + return result +end + +function Game.getReverseDirection(direction) + if direction == WEST then + return EAST + elseif direction == EAST then + return WEST + elseif direction == NORTH then + return SOUTH + elseif direction == SOUTH then + return NORTH + elseif direction == NORTHWEST then + return SOUTHEAST + elseif direction == NORTHEAST then + return SOUTHWEST + elseif direction == SOUTHWEST then + return NORTHEAST + elseif direction == SOUTHEAST then + return NORTHWEST + end + return NORTH +end + +function Game.getSkillType(weaponType) + if weaponType == WEAPON_CLUB then + return SKILL_CLUB + elseif weaponType == WEAPON_SWORD then + return SKILL_SWORD + elseif weaponType == WEAPON_AXE then + return SKILL_AXE + elseif weaponType == WEAPON_DISTANCE then + return SKILL_DISTANCE + elseif weaponType == WEAPON_SHIELD then + return SKILL_SHIELD + end + return SKILL_FIST +end + +if not globalStorageTable then + globalStorageTable = {} +end + +function Game.getStorageValue(key) + return globalStorageTable[key] or -1 +end + +function Game.setStorageValue(key, value) + globalStorageTable[key] = value +end diff --git a/data/lib/core/imbuements.lua b/data/lib/core/imbuements.lua new file mode 100644 index 00000000000..52cfcd68215 --- /dev/null +++ b/data/lib/core/imbuements.lua @@ -0,0 +1,191 @@ +MESSAGEDIALOG_IMBUEMENT_ERROR = 1 +MESSAGEDIALOG_IMBUEMENT_ROLL_FAILED = 2 +MESSAGEDIALOG_IMBUING_STATION_NOT_FOUND = 3 +MESSAGEDIALOG_CLEARING_CHARM_SUCCESS = 10 +MESSAGEDIALOG_CLEARING_CHARM_ERROR = 11 + +-- tables +Imbuements_Weapons = { + ["armor"] = {21692, 2500, 2656, 2464, 2487, 2494, 2492, 2503, 12607, 2505, 32419, 2466, 23538, 10296, 2476, 3968, 2472, 7463, 8888, 23537, 2486, 15406, 8891, 18404, 38992, 38929, 38930}, -- ok + ["shield"] = {34068, 2537, 2518, 15491, 2535, 2519, 25414, 2520, 15411, 2516, 32422, 32421, 30885, 2522, 2533, 21707, 2514, 10289, 2536, 6433, 6391, 7460, 2524, 15413, 2539, 25382, 21697, 3974, 10297, 12644, 10294, 2509, 2542, 2528, 2534, 2531, 15453, 38989, 38934}, -- ok + ["boots"] = {34062, 24742, 2195, 2644, 9931, 3982, 11117, 15410, 11118, 12646, 7457, 7892, 2646, 11240, 2643, 7893, 7891, 23540, 24637, 2641, 5462, 18406, 2642, 2645, 7886, 25412, 21708, 11303, 35229, 36452, 38932, 38933}, --ok + ["helmet"] = {34065, 2499, 2139, 3972, 2458, 2491, 2497, 2493, 2502, 12645, 32415, 7458, 2471, 10299, 20132, 10298, 2662, 10291, 2498, 24848, 5741, 25410, 2475, 11302, 35232, 36412, 38991}, --ok + ["helmetmage"] = {10016, 2323, 11368, 8820, 10570, 9778, 32414, 30882, 36417}, -- ok + ["bow"] = {34055, 25946, 30690, 8855, 7438, 32418, 15643, 21696, 10295, 18454, 25522, 8857, 22417, 22418, 8854, 36416, 38923, 38985}, -- ok + ["crossbow"] = {25950, 8850, 2455, 30691, 8849, 25523, 8851, 8852, 8853, 16111, 21690, 22420, 22421, 35228, 38924}, -- ok + ["backpack"] = {1988, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2365, 3940, 3960, 5801, 5926, 5949, 7342, 9774, 10518, 10519, 10521, 10522, 11119, 11241, 11243, 11244, 11263, 15645, 15646, 16007, 18393, 18394, 21475, 22696, 23666, 23816, 24740, 26181, 27061, 27063, 35056, 33318}, + ["wand"] = {29005, 2191, 8920, 8921, 8922}, --ok + ["rod"] = {8910, 8911, 24839}, --ok + ["axe"] = {30686, 2429, 3962, 7412, 30687, 18451, 8926, 2414, 11305, 7419, 2435, 7453, 2415, 2427, 7380, 8924, 7389, 15492, 7435, 2430, 7455, 7456, 2443, 25383, 7434, 6553, 8925, 2431, 2447, 22405, 22408, 22406, 22409, 2454, 15451, 11323}, --ok + ["club"] = {7414, 7426, 2453, 7429, 2423, 7415, 2445, 15647, 7431, 7430, 23543, 30689, 2444, 2452, 20093, 7424, 30688, 25418, 18452, 8928, 7421, 7392, 15414, 7410, 7437, 7451, 2424, 2436, 7423, 12648, 7452, 8929, 22414, 22411, 22415, 22412, 2421, 2391}, --ok + ["sword"] = {7404, 7403, 7406, 12649, 30684, 7416, 2407, 2413, 7385, 7382, 2451, 7402, 8930, 2438, 32423, 2393, 7407, 7405, 2400, 7384, 7418, 7383, 7417, 18465, 30685, 2383, 2376, 7391, 6528, 8931, 12613, 11309, 22399, 22403, 22400, 22402, 7408, 11307, 35233}, --ok + ["spellbooks"] = {25411, 2175, 8900, 8901, 22423, 22424, 29004, 34069, 34058, 34064, 38988}, -- ok + ["special_strike"] = {32417, 32416, 30693, 30692, 32523, 32522, 34063, 38925, 38926}, --ok + ["crit_wandrod"] = {35234, 38986}, + ["life_wandrod"] = {35235, 38987}, + ["elemental_swords"] = {30886, 34059, 34060, 36449, 38918, 38917, 38990}, + ["elemental_axes"] = {32424, 35231, 39088, 38919, 38920, 37451}, + ["elemental_clubs"] = {32425, 34057, 35230, 36415, 38922, 38921, 39089}, + -- Note: if an armor has native protection, it can't be imbue with this protection + ["armor_energy"] = {30883}, + ["armor_only_energy"] = {34061}, + ["armor_ice"] = {36414}, + ["armor_earth"] = {34056, 36413}, + ["armor_death"] = {15407, 36418, 38931} +} + +local equipitems = { + ["lich shroud"] = {"armor", "armor_energy", "armor_only_energy", "armor_ice", "armor_earth", "spellbooks", "shield"}, + ["reap"] = {"axe", "club", "sword", "bow", "crossbow"}, + ["vampirism"] = {"axe", "club", "sword", "wand", "rod", "special_strike", "bow", "crossbow", "armor", "armor_energy", "armor_only_energy", "armor_ice", "armor_earth", "armor_death", "elemental_swords", "elemental_axes", "elemental_clubs", "crit_wandrod"}, + ["cloud fabric"] = {"armor", "armor_earth", "armor_death", "spellbooks", "shield"}, + ["electrify"] = {"axe", "club", "sword", "bow", "crossbow"}, + ["swiftness"] = {"boots"}, + ["snake skin"] = {"armor", "armor_energy", "armor_only_energy", "armor_ice", "armor_death", "spellbooks", "shield"}, + ["venom"] = {"axe", "club", "sword", "bow", "crossbow"}, + ["slash"] = {"sword", "helmet", "elemental_swords"}, + ["chop"] = {"axe", "helmet", "elemental_axes"}, + ["bash"] = {"club", "helmet", "elemental_clubs"}, + ["dragon hide"] = {"armor", "armor_energy", "armor_only_energy", "armor_ice", "armor_death", "spellbooks", "shield"}, + ["scorch"] = {"axe", "club", "sword", "bow", "crossbow"}, + ["void"] = {"axe", "club", "sword", "wand", "rod", "special_strike", "bow", "crossbow", "helmet","helmetmage", "elemental_swords", "elemental_axes", "elemental_clubs", "crit_wandrod", "life_wandrod"}, -- Mana + ["quara scale"] = {"armor", "armor_only_energy", "armor_earth", "armor_death", "spellbooks", "shield"}, + ["frost"] = {"axe", "club", "sword", "bow", "crossbow"}, + ["blockade"] = {"shield", "helmet", "spellbooks", "shield"}, + ["demon presence"] = {"armor", "armor_energy", "armor_only_energy", "armor_ice", "armor_earth", "armor_death", "spellbooks", "shield"}, + ["precision"] = {"bow", "crossbow", "helmet"}, + ["strike"] = {"axe", "club", "sword", "bow", "crossbow", "special_strike", "elemental_swords", "elemental_axes", "elemental_clubs", "life_wandrod"}, + ["epiphany"] = {"wand", "rod", "helmetmage", "special_strike", "special_wand", "special_rod", "crit_wandrod", "life_wandrod"}, + ["featherweight"] = {"backpack"}, +} + +local enablingStorages = { + ["lich shroud"] = Storage.ForgottenKnowledge.LadyTenebrisKilled, + ["reap"] = Storage.ForgottenKnowledge.LadyTenebrisKilled, + ["vampirism"] = Storage.ForgottenKnowledge.LadyTenebrisKilled, + ["cloud fabric"] = Storage.ForgottenKnowledge.LloydKilled, + ["electrify"] = Storage.ForgottenKnowledge.LloydKilled, + ["swiftness"] = Storage.ForgottenKnowledge.LloydKilled, + ["snake skin"] = Storage.ForgottenKnowledge.ThornKnightKilled, + ["venom"] = Storage.ForgottenKnowledge.ThornKnightKilled, + ["slash"] = Storage.ForgottenKnowledge.ThornKnightKilled, + ["chop"] = Storage.ForgottenKnowledge.ThornKnightKilled, + ["bash"] = Storage.ForgottenKnowledge.ThornKnightKilled, + ["dragon hide"] = Storage.ForgottenKnowledge.DragonkingKilled, + ["scorch"] = Storage.ForgottenKnowledge.DragonkingKilled, + ["void"] = Storage.ForgottenKnowledge.DragonkingKilled, + ["quara scale"] = Storage.ForgottenKnowledge.HorrorKilled, + ["frost"] = Storage.ForgottenKnowledge.HorrorKilled, + ["blockade"] = Storage.ForgottenKnowledge.HorrorKilled, + ["demon presence"] = Storage.ForgottenKnowledge.TimeGuardianKilled, + ["precision"] = Storage.ForgottenKnowledge.TimeGuardianKilled, + ["strike"] = Storage.ForgottenKnowledge.LastLoreKilled, + ["epiphany"] = Storage.ForgottenKnowledge.LastLoreKilled, + ["featherweight"] = -1, +} + +function Player.canImbueItem(self, imbuement, item) + local item_type = "" + for tp, items in pairs(Imbuements_Weapons) do + if isInArray(items, item:getId()) then + item_type = tp + break + end + end + local imb_type = "" + for ibt, imb_n in pairs(enablingStorages) do + if string.find(ibt, imbuement:getName():lower()) then + imb_type = ibt + break + end + end + if imb_type == "" then + Spdlog.error(string.format("[Imbuement::canImbueItem] - Error on searching imbuement %s"), + imbuement:getName()) + return false + end + + local equip = equipitems[imb_type] + if not equip then + Spdlog.error(string.format("[Imbuement::canImbueItem] - Error on searching weapon imbuement %s", + imbuement:getName())) + return false + end + + local imbuable = false + for i, p in pairs(equip) do + if p:lower() == item_type then + imbuable = true + break + end + end + if not imbuable then + return false + end + local stg = enablingStorages[imb_type] + if not stg then + Spdlog.error("[Imbuement::canImbueItem] - Error on search storage imbuement '" .. imbuement:getName()) + return false + end + + if imbuement:getBase().id == 3 and not self:getGroup():getAccess() and stg > -1 and self:getStorageValue(stg) < 1 then + return false + end + + return true +end + +-- Player functions +function Player.sendImbuementResult(self, errorType, message) + local msg = NetworkMessage() + msg:addByte(0xED) + msg:addByte(errorType or 0x01) + msg:addString(message) + msg:sendToPlayer(self) + msg:delete() + return +end + +function Player.closeImbuementWindow(self) + local msg = NetworkMessage() + msg:addByte(0xEC) + msg:sendToPlayer(self) +end + +-- Items functions +function Item.getImbuementDuration(self, slot) + local info = 0 + local binfo = tonumber(self:getCustomAttribute(IMBUEMENT_SLOT + slot)) + if binfo then + info = bit.rshift(binfo, 8) + end + + return info +end + +function Item.getImbuement(self, slot) + local binfo = tonumber(self:getCustomAttribute(IMBUEMENT_SLOT + slot)) + if not binfo then + return false + end + local id = bit.band(binfo, 0xFF) + if id == 0 then + return false + end + return Imbuement(id) +end + +function Item.addImbuement(self, slot, id) + local imbuement = Imbuement(id) + if not imbuement then return false end + local duration = imbuement:getBase().duration + + local imbue = bit.bor(bit.lshift(duration, 8), id) + self:setCustomAttribute(IMBUEMENT_SLOT + slot, imbue) + return true +end + +function Item.cleanImbuement(self, slot) + self:setCustomAttribute(IMBUEMENT_SLOT + slot, 0) + return true +end diff --git a/data/lib/core/item.lua b/data/lib/core/item.lua new file mode 100644 index 00000000000..ceb00977ef2 --- /dev/null +++ b/data/lib/core/item.lua @@ -0,0 +1,55 @@ +function Item.getType(self) + return ItemType(self:getId()) +end + +function Item.isContainer(self) + return false +end + +function Item.isCreature(self) + return false +end + +function Item.isMonster(self) + return false +end + +function Item.isNpc(self) + return false +end + +function Item.isPlayer(self) + return false +end + +function Item.isTeleport(self) + return false +end + +function Item.isTile(self) + return false +end + +function Item.setDescription(self, description) + if description ~= '' then + self:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, description) + else + self:removeAttribute(ITEM_ATTRIBUTE_DESCRIPTION) + end +end + +function Item.setText(self, text) + if text ~= '' then + self:setAttribute(ITEM_ATTRIBUTE_TEXT, text) + else + self:removeAttribute(ITEM_ATTRIBUTE_TEXT) + end +end + +function Item.setUniqueId(self, uniqueId) + if type(uniqueId) ~= 'number' or uniqueId < 0 or uniqueId > 65535 then + return false + end + + self:setAttribute(ITEM_ATTRIBUTE_UNIQUEID, uniqueId) +end diff --git a/data/lib/core/itemtype.lua b/data/lib/core/itemtype.lua new file mode 100644 index 00000000000..c94ba7f1b4a --- /dev/null +++ b/data/lib/core/itemtype.lua @@ -0,0 +1,16 @@ +local slotBits = { + [CONST_SLOT_HEAD] = SLOTP_HEAD, + [CONST_SLOT_NECKLACE] = SLOTP_NECKLACE, + [CONST_SLOT_BACKPACK] = SLOTP_BACKPACK, + [CONST_SLOT_ARMOR] = SLOTP_ARMOR, + [CONST_SLOT_RIGHT] = SLOTP_RIGHT, + [CONST_SLOT_LEFT] = SLOTP_LEFT, + [CONST_SLOT_LEGS] = SLOTP_LEGS, + [CONST_SLOT_FEET] = SLOTP_FEET, + [CONST_SLOT_RING] = SLOTP_RING, + [CONST_SLOT_AMMO] = SLOTP_AMMO +} + +function ItemType.usesSlot(self, slot) + return bit.band(self:getSlotPosition(), slotBits[slot] or 0) ~= 0 +end diff --git a/data/lib/core/monster.lua b/data/lib/core/monster.lua new file mode 100644 index 00000000000..2a166556ceb --- /dev/null +++ b/data/lib/core/monster.lua @@ -0,0 +1,117 @@ +if not monsterStorage then + monsterStorage = {[0] = {[0] = 0}} +end + +function Monster.getStorageValue(self, key) + if not self:isMonster() then + return -1 + end + local ret = -1 + for id, pid in pairs(monsterStorage) do + if id == self:getId() then + for key1, value in pairs(pid) do + if(key1 == key)then + ret = value + break + end + end + end + end + return ret +end + +function Monster.setStorageValue(self, key, value) + if not self:isMonster() then + return false + end + if not monsterStorage[self:getId()] then + monsterStorage[self:getId()] = {} + end + if not monsterStorage[self:getId()][key] then + monsterStorage[self:getId()][key] = value + else + monsterStorage[self:getId()][key] = value + end + return true +end + +function Monster.getStorage(self, key) + return self:getStorageValue(key) +end + +function Monster.setStorage(self, key, value) + return self:setStorageValue(key, value) +end + +if not hpCompartilhada then + hpCompartilhada = {[0] = {hp = 0, monsters = {}}} +end + +function Monster.beginSharedLife(self, hpid) + if not self:isMonster() then + return false + end + if not hpCompartilhada[hpid] then + hpCompartilhada[hpid] = {hp = self:getMaxHealth(), monsters = {}} + end + table.insert(hpCompartilhada[hpid].monsters, self:getId()) + self:setStorageValue("shared_storage", hpid) +end + +function Monster.inSharedLife(self) + if not self:isMonster() then + return false + end + local storage = self:getStorageValue("shared_storage") + if storage < 1 then + return false + end + for id, pid in pairs(hpCompartilhada) do + if(storage == id) then + for _id, mid in pairs(pid.monsters) do + local mtemp = Monster(mid) + if(mtemp and mtemp:getId() == self:getId())then + return true + end + end + end + end + return false +end + +function updateMonstersSharedLife(hpid, amount, orign, _type, kill) + if not hpCompartilhada[hpid] then + return false + end + if(_type == "healing") then + hpCompartilhada[hpid].hp = hpCompartilhada[hpid].hp + amount + else + hpCompartilhada[hpid].hp = hpCompartilhada[hpid].hp - amount + end + if(hpCompartilhada[hpid].hp < 0)then + hpCompartilhada[hpid].hp = 0 + end + for _, monster in pairs(hpCompartilhada[hpid].monsters)do + local mt = Monster(monster) + if mt and mt:getId() ~= orign then + if kill then + mt:addHealth(-mt:getHealth()) + else + mt:setHealth(hpCompartilhada[hpid].hp) + end + end + end + return true +end + +function Monster.onReceivDamageSL(self, damage, tp, killer) + if not self:inSharedLife() then + return true + end + local storage = self:getStorageValue("shared_storage") + if storage < 1 then + return false + end + updateMonstersSharedLife(storage, damage, self:getId(), tp, killer) + return true +end diff --git a/data/lib/core/party.lua b/data/lib/core/party.lua new file mode 100644 index 00000000000..fd9e36d23ac --- /dev/null +++ b/data/lib/core/party.lua @@ -0,0 +1,10 @@ +function Party.broadcastPartyLoot(self, text) + self:getLeader():sendTextMessage(MESSAGE_LOOT, text) + local membersList = self:getMembers() + for i = 1, #membersList do + local player = membersList[i] + if player then + player:sendTextMessage(MESSAGE_LOOT, text) + end + end +end diff --git a/data/lib/core/player.lua b/data/lib/core/player.lua new file mode 100644 index 00000000000..057381ad1d9 --- /dev/null +++ b/data/lib/core/player.lua @@ -0,0 +1,327 @@ +-- Functions from The Forgotten Server +local foodCondition = Condition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) + +function Player.feed(self, food) + local condition = self:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) + if condition then + condition:setTicks(condition:getTicks() + (food * 1000)) + else + local vocation = self:getVocation() + if not vocation then + return nil + end + + foodCondition:setTicks(food * 1000) + foodCondition:setParameter(CONDITION_PARAM_HEALTHGAIN, vocation:getHealthGainAmount()) + foodCondition:setParameter(CONDITION_PARAM_HEALTHTICKS, vocation:getHealthGainTicks() * 1000) + foodCondition:setParameter(CONDITION_PARAM_MANAGAIN, vocation:getManaGainAmount()) + foodCondition:setParameter(CONDITION_PARAM_MANATICKS, vocation:getManaGainTicks() * 1000) + + self:addCondition(foodCondition) + end + return true +end + +function Player.getClosestFreePosition(self, position, extended) + if self:getGroup():getAccess() and self:getAccountType() >= ACCOUNT_TYPE_GOD then + return position + end + return Creature.getClosestFreePosition(self, position, extended) +end + +function Player.getDepotItems(self, depotId) + return self:getDepotChest(depotId, true):getItemHoldingCount() +end + +function Player.hasFlag(self, flag) + return self:getGroup():hasFlag(flag) +end + +function Player.hasCustomFlag(self, customflag) + return self:getGroup():hasCustomFlag(customflag) +end + +function Player.isPremium(self) + return self:getPremiumDays() > 0 or configManager.getBoolean(configKeys.FREE_PREMIUM) +end + +function Player.isPromoted(self) + local vocation = self:getVocation() + local promotedVocation = vocation:getPromotion() + promotedVocation = promotedVocation and promotedVocation:getId() or 0 + + return promotedVocation == 0 and vocation:getId() ~= promotedVocation +end + +function Player.sendCancelMessage(self, message) + if type(message) == "number" then + message = Game.getReturnMessage(message) + end + return self:sendTextMessage(MESSAGE_FAILURE, message) +end + +function Player.isUsingOtClient(self) + return self:getClient().os >= CLIENTOS_OTCLIENT_LINUX +end + +function Player.sendExtendedOpcode(self, opcode, buffer) + if not self:isUsingOtClient() then + return false + end + + local networkMessage = NetworkMessage() + networkMessage:addByte(0x32) + networkMessage:addByte(opcode) + networkMessage:addString(buffer) + networkMessage:sendToPlayer(self) + networkMessage:delete() + return true +end + +APPLY_SKILL_MULTIPLIER = true +local addSkillTriesFunc = Player.addSkillTries +function Player.addSkillTries(...) + APPLY_SKILL_MULTIPLIER = false + local ret = addSkillTriesFunc(...) + APPLY_SKILL_MULTIPLIER = true + return ret +end + +local addManaSpentFunc = Player.addManaSpent +function Player.addManaSpent(...) + APPLY_SKILL_MULTIPLIER = false + local ret = addManaSpentFunc(...) + APPLY_SKILL_MULTIPLIER = true + return ret +end + +-- Functions From OTServBR-Global +function Player.getCookiesDelivered(self) + local storage, amount = { + Storage.WhatAFoolish.CookieDelivery.SimonTheBeggar, Storage.WhatAFoolish.CookieDelivery.Markwin, Storage.WhatAFoolish.CookieDelivery.Ariella, + Storage.WhatAFoolish.CookieDelivery.Hairycles, Storage.WhatAFoolish.CookieDelivery.Djinn, Storage.WhatAFoolish.CookieDelivery.AvarTar, + Storage.WhatAFoolish.CookieDelivery.OrcKing, Storage.WhatAFoolish.CookieDelivery.Lorbas, Storage.WhatAFoolish.CookieDelivery.Wyda, + Storage.WhatAFoolish.CookieDelivery.Hjaern + }, 0 + for i = 1, #storage do + if self:getStorageValue(storage[i]) == 1 then + amount = amount + 1 + end + end + return amount +end + +function Player.allowMovement(self, allow) + return self:setStorageValue(STORAGE.blockMovementStorage, allow and -1 or 1) +end + +function Player.checkGnomeRank(self) + local points = self:getStorageValue(Storage.BigfootBurden.Rank) + local questProgress = self:getStorageValue(Storage.BigfootBurden.QuestLine) + if points >= 30 and points < 120 then + if questProgress <= 25 then + self:setStorageValue(Storage.BigfootBurden.QuestLine, 26) + self:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + self:addAchievement('Gnome Little Helper') + end + elseif points >= 120 and points < 480 then + if questProgress <= 26 then + self:setStorageValue(Storage.BigfootBurden.QuestLine, 27) + self:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + self:addAchievement('Gnome Little Helper') + self:addAchievement('Gnome Friend') + end + elseif points >= 480 and points < 1440 then + if questProgress <= 27 then + self:setStorageValue(Storage.BigfootBurden.QuestLine, 28) + self:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + self:addAchievement('Gnome Little Helper') + self:addAchievement('Gnome Friend') + self:addAchievement('Gnomelike') + end + elseif points >= 1440 then + if questProgress <= 29 then + self:setStorageValue(Storage.BigfootBurden.QuestLine, 30) + self:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + self:addAchievement('Gnome Little Helper') + self:addAchievement('Gnome Friend') + self:addAchievement('Gnomelike') + self:addAchievement('Honorary Gnome') + end + end + return true +end + +function Player.addFamePoint(self) + local points = self:getStorageValue(SPIKE_FAME_POINTS) + local current = math.max(0, points) + self:setStorageValue(SPIKE_FAME_POINTS, current + 1) + self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have received a fame point.") +end + +function Player.getFamePoints(self) + local points = self:getStorageValue(SPIKE_FAME_POINTS) + return math.max(0, points) +end + +function Player.removeFamePoints(self, amount) + local points = self:getStorageValue(SPIKE_FAME_POINTS) + local current = math.max(0, points) + self:setStorageValue(SPIKE_FAME_POINTS, current - amount) +end + +function Player.depositMoney(self, amount) + if not self:removeMoney(amount) then + return false + end + + self:setBankBalance(self:getBankBalance() + amount) + return true +end + +function Player.transferMoneyTo(self, target, amount) + local balance = self:getBankBalance() + if amount > balance then + return false + end + + local targetPlayer = Player(target) + if targetPlayer then + local town = targetPlayer:getTown() + if town and town:getId() ~= TOWNS_LIST.DAWNPORT or town:getId() ~= TOWNS_LIST.DAWNPORT_TUTORIAL then -- Blocking transfer to Dawnport + targetPlayer:setBankBalance(targetPlayer:getBankBalance() + amount) + end + else + if not playerExists(target) then + return false + end + + local query_town = db.storeQuery('SELECT `town_id` FROM `players` WHERE `name` = ' .. db.escapeString(target) ..' LIMIT 1;') + if query_town ~= false then + local town = result.getDataInt(query_town, "town_id") + if town then + local town_id = Town(town) and Town(town):getId() + if town_id and town_id == TOWNS_LIST.DAWNPORT or town_id == TOWNS_LIST.DAWNPORT_TUTORIAL then -- Blocking transfer to Dawnport + return false + end + end + result.free(consulta) + db.query("UPDATE `players` SET `balance` = `balance` + '" .. amount .. "' WHERE `name` = " .. db.escapeString(target)) + end + end + + self:setBankBalance(self:getBankBalance() - amount) + return true +end + +function Player.withdrawMoney(self, amount) + local balance = self:getBankBalance() + if amount > balance or not self:addMoney(amount) then + return false + end + + self:setBankBalance(balance - amount) + return true +end + +function Player.hasAllowMovement(self) + return self:getStorageValue(STORAGE.blockMovementStorage) ~= 1 +end + +function Player.hasRookgaardShield(self) + -- Wooden Shield, Studded Shield, Brass Shield, Plate Shield, Copper Shield + return self:getItemCount(2512) > 0 + or self:getItemCount(2526) > 0 + or self:getItemCount(2511) > 0 + or self:getItemCount(2510) > 0 + or self:getItemCount(2530) > 0 +end + + +function Player.isSorcerer(self) + return table.contains({VOCATION.ID.SORCERER, VOCATION.ID.MASTER_SORCERER}, self:getVocation():getId()) +end + +function Player.isDruid(self) + return table.contains({VOCATION.ID.DRUID, VOCATION.ID.ELDER_DRUID}, self:getVocation():getId()) +end + +function Player.isKnight(self) + return table.contains({VOCATION.ID.KNIGHT, VOCATION.ID.ELITE_KNIGHT}, self:getVocation():getId()) +end + +function Player.isPaladin(self) + return table.contains({VOCATION.ID.PALADIN, VOCATION.ID.ROYAL_PALADIN}, self:getVocation():getId()) +end + +function Player.isMage(self) + return table.contains({VOCATION.ID.SORCERER, VOCATION.ID.MASTER_SORCERER, VOCATION.ID.DRUID, VOCATION.ID.ELDER_DRUID}, + self:getVocation():getId()) +end + +local ACCOUNT_STORAGES = {} +function Player.getAccountStorage(self, accountId, key, forceUpdate) + local accountId = self:getAccountId() + if ACCOUNT_STORAGES[accountId] and not forceUpdate then + return ACCOUNT_STORAGES[accountId] + end + + local query = db.storeQuery("SELECT `key`, MAX(`value`) as value FROM `player_storage` WHERE `player_id` IN (SELECT `id` FROM `players` WHERE `account_id` = ".. accountId ..") AND `key` = ".. key .." GROUP BY `key` LIMIT 1;") + if query ~= false then + local value = result.getDataInt(query, "value") + ACCOUNT_STORAGES[accountId] = value + result.free(query) + return value + end + return false +end + +function Player.getMarriageDescription(thing) + local descr = "" + if getPlayerMarriageStatus(thing:getGuid()) == MARRIED_STATUS then + playerSpouse = getPlayerSpouse(thing:getGuid()) + if self == thing then + descr = descr .. " You are " + elseif thing:getSex() == PLAYERSEX_FEMALE then + descr = descr .. " She is " + else + descr = descr .. " He is " + end + descr = descr .. "married to " .. getPlayerNameById(playerSpouse) .. '.' + end + return descr +end + +function Player.sendWeatherEffect(self, groundEffect, fallEffect, thunderEffect) + local position, random = self:getPosition(), math.random + position.x = position.x + random(-7, 7) + position.y = position.y + random(-5, 5) + local fromPosition = Position(position.x + 1, position.y, position.z) + fromPosition.x = position.x - 7 + fromPosition.y = position.y - 5 + local tile, getGround + for Z = 1, 7 do + fromPosition.z = Z + position.z = Z + tile = Tile(position) + if tile then -- If there is a tile, stop checking floors + fromPosition:sendDistanceEffect(position, fallEffect) + position:sendMagicEffect(groundEffect, self) + getGround = tile:getGround() + if getGround and ItemType(getGround:getId()):getFluidSource() == 1 then + position:sendMagicEffect(CONST_ME_LOSEENERGY, self) + end + break + end + end + if thunderEffect and tile and not tile:hasFlag(TILESTATE_PROTECTIONZONE) then + if random(2) == 1 then + local topCreature = tile:getTopCreature() + if topCreature and topCreature:isPlayer() and topCreature:getAccountType() < ACCOUNT_TYPE_SENIORTUTOR then + position:sendMagicEffect(CONST_ME_BIGCLOUDS, self) + doTargetCombatHealth(0, self, COMBAT_ENERGYDAMAGE, -weatherConfig.minDMG, -weatherConfig.maxDMG, CONST_ME_NONE) + --self:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You were hit by lightning and lost some health.") + end + end + end +end diff --git a/data/lib/core/position.lua b/data/lib/core/position.lua new file mode 100644 index 00000000000..24b5417ea2e --- /dev/null +++ b/data/lib/core/position.lua @@ -0,0 +1,353 @@ +-- Functions from The Forgotten Server +Position.directionOffset = { + [DIRECTION_NORTH] = {x = 0, y = -1}, + [DIRECTION_EAST] = {x = 1, y = 0}, + [DIRECTION_SOUTH] = {x = 0, y = 1}, + [DIRECTION_WEST] = {x = -1, y = 0}, + [DIRECTION_SOUTHWEST] = {x = -1, y = 1}, + [DIRECTION_SOUTHEAST] = {x = 1, y = 1}, + [DIRECTION_NORTHWEST] = {x = -1, y = -1}, + [DIRECTION_NORTHEAST] = {x = 1, y = -1} +} + +function Position:getNextPosition(direction, steps) + local offset = Position.directionOffset[direction] + if offset then + steps = steps or 1 + self.x = self.x + offset.x * steps + self.y = self.y + offset.y * steps + end +end + +function Position:moveUpstairs() + local swap = function (lhs, rhs) + lhs.x, rhs.x = rhs.x, lhs.x + lhs.y, rhs.y = rhs.y, lhs.y + lhs.z, rhs.z = rhs.z, lhs.z + end + + self.z = self.z - 1 + + local defaultPosition = self + Position.directionOffset[DIRECTION_SOUTH] + local toTile = Tile(defaultPosition) + if not toTile or not toTile:isWalkable(false, false, false, false, true) then + for direction = DIRECTION_NORTH, DIRECTION_NORTHEAST do + if direction == DIRECTION_SOUTH then + direction = DIRECTION_WEST + end + + local position = self + Position.directionOffset[direction] + toTile = Tile(position) + if toTile and toTile:isWalkable(false, false, false, false, true) then + swap(self, position) + return self + end + end + end + swap(self, defaultPosition) + return self +end + +-- Functions from OTServBR-Global +function Position:isInRange(from, to) + -- No matter what corner from and to is, we want to make + -- life easier by calculating north-west and south-east + local zone = { + nW = { + x = (from.x < to.x and from.x or to.x), + y = (from.y < to.y and from.y or to.y), + z = (from.z < to.z and from.z or to.z) + }, + sE = { + x = (to.x > from.x and to.x or from.x), + y = (to.y > from.y and to.y or from.y), + z = (to.z > from.z and to.z or from.z) + } + } + + if self.x >= zone.nW.x and self.x <= zone.sE.x + and self.y >= zone.nW.y and self.y <= zone.sE.y + and self.z >= zone.nW.z and self.z <= zone.sE.z then + return true + end + return false +end + +function Position:moveDownstairs() + local swap = function (lhs, rhs) + lhs.x, rhs.x = rhs.x, lhs.x + lhs.y, rhs.y = rhs.y, lhs.y + lhs.z, rhs.z = rhs.z, lhs.z + end + + self.z = self.z + 1 + + local defaultPosition = self + Position.directionOffset[DIRECTION_SOUTH] + local tile = Tile(defaultPosition) + if not tile then return false end + + if not tile:isWalkable(false, false, false, false, true) then + for direction = DIRECTION_NORTH, DIRECTION_NORTHEAST do + if direction == DIRECTION_SOUTH then + direction = DIRECTION_WEST + end + + local position = self + Position.directionOffset[direction] + local newTile = Tile(position) + if not newTile then return false end + + if newTile:isWalkable(false, false, false, false, true) then + swap(self, position) + return self + end + end + end + swap(self, defaultPosition) + return self +end + +function Position.getTile(self) + return Tile(self) +end + +function Position:getDistanceBetween(position) + local xDif = math.abs(self.x - position.x) + local yDif = math.abs(self.y - position.y) + local posDif = math.max(xDif, yDif) + if self.z ~= position.z then + posDif = posDif + 15 + end + return posDif +end + +function Position:compare(position) + return self.x == position.x and self.y == position.y and self.z == position.z +end + +function Position.hasPlayer(centerPosition, rangeX, rangeY) + local spectators = Game.getSpectators(centerPosition, false, true, rangeX, rangeX, rangeY, rangeY) + if #spectators ~= 0 then + return true + end + return false +end + +function Position.removeMonster(centerPosition, rangeX, rangeY) + local spectators = Game.getSpectators(centerPosition, false, false, rangeX, rangeX, rangeY, rangeY) + local spectators, + spectator = Game.getSpectators(centerPosition, false, false, rangeX, rangeX, rangeY, rangeY) + for i = 1, #spectators do + spectator = spectators[i] + if spectator:isMonster() then + spectator:remove() + end + end +end + +function Position.getFreePosition(from, to) + local result, tries = Position(from.x, from.y, from.z), 0 + repeat + local x, y, z = math.random(from.x, to.x), math.random(from.y, to.y), math.random(from.z, to.z) + result = Position(x, y, z) + tries = tries + 1 + if tries >= 20 then + return result + end + + local tile = Tile(result) + + until tile and tile:isWalkable(false, false, false, false, true) + return result +end + +function Position.getFreeSand() + local from, to = ghost_detector_area.from, ghost_detector_area.to + local result, tries = Position(from.x, from.y, from.z), 0 + repeat + local x, y, z = math.random(from.x, to.x), math.random(from.y, to.y), math.random(from.z, to.z) + result = Position(x, y, z) + tries = tries + 1 + if tries >= 50 then + return result + end + + local tile = Tile(result) + + until tile and tile:isWalkable(false, false, false, false, true) and tile:getGround():getName() == "grey sand" + return result +end + +function Position.getDirectionTo(pos1, pos2) + local dir = DIRECTION_NORTH + if (pos1.x > pos2.x) then + dir = DIRECTION_WEST + if(pos1.y > pos2.y) then + dir = DIRECTION_NORTHWEST + elseif(pos1.y < pos2.y) then + dir = DIRECTION_SOUTHWEST + end + elseif (pos1.x < pos2.x) then + dir = DIRECTION_EAST + if(pos1.y > pos2.y) then + dir = DIRECTION_NORTHEAST + elseif(pos1.y < pos2.y) then + dir = DIRECTION_SOUTHEAST + end + else + if (pos1.y > pos2.y) then + dir = DIRECTION_NORTH + elseif(pos1.y < pos2.y) then + dir = DIRECTION_SOUTH + end + end + return dir +end + +-- Checks if there is a creature in a certain position (self) +-- If so, teleports to another position (teleportTo) +function Position:hasCreature(teleportTo) + local creature = Tile(self):getTopCreature() + if creature then + creature:teleportTo(teleportTo, true) + end +end + +--[[ +Checks whether there is an item in a position table +Use the index to check which positions the script should check + +-- Position table +local position = { + {x = 1000, y = 1000, z = 7}, + {x = 1001, y = 1000, z = 7} +} + +-- Checks position 1 +if Position(position[1]):hasItem(1498) then + return true +end + +-- Checks position 2 +if Position(position[2]):hasItem(1499) then + return true +end + +-- Check two positions +if Position(position[1]):hasItem(1498) and Position(position[2]):hasItem(1499) then + return true +end +]] +function Position:hasItem(itemId) + local tile = Tile(self) + if tile then + local item = tile:getItemById(itemId) + if item then + return true + end + end +end + +--[[ +position.hasCreatureInArea({x = positionx, y = positiony, z = positionz}, {x = positionx, y = positiony, z = positionz}, true or false, true or false, {x = positionx, y = positiony, z = positionz}) + +fromPosition: is the upper left corner +toPosition: is the lower right corner, +removeCreatures[true or false]: is to say whether or not to remove the monster +removePlayer[true or false] is to say whether or not to remove the player +teleportTo: is where you will teleport the player (it is only necessary to put this position in the function, if the previous value is true) +]] + +function Position.hasCreatureInArea(fromPosition, toPosition, removeCreatures, removePlayer, teleportTo) + for positionX = fromPosition.x, toPosition.x do + for positionY = fromPosition.y, toPosition.y do + for positionZ = fromPosition.z, toPosition.z do + local room = {x = positionX, y = positionY, z= positionZ} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, creature in pairs(creatures) do + if removeCreatures == true then + if removePlayer == true then + if isPlayer(creature) then + creature:teleportTo(teleportTo) + end + end + if isMonster(creature) then + creature:remove() + end + end + end + end + end + end + end + end +end + +--[[ +If the script have one lever and item to revert uses: +Position.revertItem(createItemPosition, createItemId, tilePosition, itemTransform, itemId, effect) + +If not have lever, use only the first two variables +Revert item: Position.revertItem(createItemPosition, createItemId) +"effect" variable is optional +]] +function Position.revertItem(positionCreateItem, itemIdCreate, positionTransform, itemId, itemTransform, effect) + local tile = Tile(positionTransform) + if tile then + local lever = tile:getItemById(itemId) + if lever then + lever:transform(itemTransform) + end + end + + local getItemTile = Tile(positionCreateItem) + if getItemTile then + local getItemId = getItemTile:getItemById(itemIdCreate) + if not getItemId then + Game.createItem(itemIdCreate, 1, positionCreateItem) + Position(positionCreateItem):sendMagicEffect(effect) + end + end +end + +-- Position.transformItem(itemPosition, itemId, itemTransform, effect) +-- Variable "effect" is optional +function Position:transformItem(itemId, itemTransform, effect) + local thing = Tile(self):getItemById(itemId) + if thing then + thing:transform(itemTransform) + Position(self):sendMagicEffect(effect) + end +end + +-- Position.createItem(tilePosition, itemId, effect) +-- Variable "effect" is optional +function Position:createItem(itemId, effect) + local tile = Tile(self) + if not tile then + return true + end + + local thing = tile:getItemById(itemId) + if not thing then + Game.createItem(itemId, 1, self) + Position(self):sendMagicEffect(effect) + end +end + +-- Position.removeItem(position, itemId, effect) +-- Variable "effect" is optional +function Position:removeItem(itemId, effect) + local tile = Tile(self) + if not tile then + return true + end + + local thing = tile:getItemById(itemId) + if thing then + thing:remove(1) + Position(self):sendMagicEffect(effect) + end +end diff --git a/data/lib/core/quests.lua b/data/lib/core/quests.lua new file mode 100644 index 00000000000..ed849cc03bd --- /dev/null +++ b/data/lib/core/quests.lua @@ -0,0 +1,6221 @@ +if not Quests then + Quests = { + [1] = { + name = "The Queen of the Banshees", + startStorageId = Storage.Quest.TheQueenOfTheBanshees.FirstSeal, + startStorageValue = 1, + missions = { + [1] = { + name = "The Hidden Seal", + storageId = Storage.Quest.TheQueenOfTheBanshees.FirstSeal, + missionId = 1, + startValue = 1, + endValue = 1, + description = "You broke the first seal." + }, + [2] = { + name = "The Plague Seal", + storageId = Storage.Quest.TheQueenOfTheBanshees.SecondSeal, + missionId = 2, + startValue = 1, + endValue = 1, + description = "You broke the second seal." + }, + [3] = { + name = "The Seal of Demonrage", + storageId = Storage.Quest.TheQueenOfTheBanshees.ThirdSeal, + missionId = 3, + startValue = 1, + endValue = 1, + description = "You broke the third seal." + }, + [4] = { + name = "The Seal of Sacrifice", + storageId = Storage.Quest.TheQueenOfTheBanshees.FourthSeal, + missionId = 4, + startValue = 1, + endValue = 1, + description = "You broke the fourth seal." + }, + [5] = { + name = "The Seal of True Path", + storageId = Storage.Quest.TheQueenOfTheBanshees.FifthSeal, + missionId = 5, + startValue = 1, + endValue = 1, + description = "You broke the fifth seal." + }, + [6] = { + name = "The Seal of Logic", + storageId = Storage.Quest.TheQueenOfTheBanshees.SixthSeal, + missionId = 6, + startValue = 1, + endValue = 1, + description = "You broke the sixth seal." + }, + [7] = { + name = "The Kiss of the Banshee Queen", + storageId = Storage.Quest.TheQueenOfTheBanshees.LastSeal, + missionId = 7, + startValue = 1, + endValue = 1, + description = "The Banshee Queen kissed you. This meant your death, and part of your soul always belongs to her now. You broke the last seal." + }, + [8] = { + name = "The Final Battle", + storageId = Storage.Quest.TheQueenOfTheBanshees.FinalBattle, + missionId = 8, + startValue = 1, + endValue = 1, + description = "You have braved all dangers of the Banshee Quest and escaped the dungeon alive. The end room is sealed for you from now on." + } + } + }, + [2] = { + name = "The Paradox Tower", + startStorageId = Storage.Quest.TheParadoxTower.QuestLine, + startStorageValue = 1, + missions = { + [1] = { + name = "The Feared Hugo", + storageId = Storage.Quest.TheParadoxTower.TheFearedHugo, + missionId = 9, + startValue = 1, + endValue = 4, + states = { + [1] = "Oldrak told you that the fearsome Hugo was accidentally created by the mage Yenny the Gentle. Try to find out more about this.", + [2] = "Zoltan told you about Crunor's Caress, a druid order originating from Carlin. Try to find out more about this.", + [3] = "Padreia told you that Crunor's Caress founded the inn Crunor's Cottage south of Mt. Sternum. Try to find out more about this.", + [4] = "Lubo told you about a magical experiment that went wrong and created a demonbunny. Someone might be interested in this...", + } + }, + [2] = { + name = "Favorite colour: Green", + storageId = Storage.Quest.TheParadoxTower.FavoriteColour, + missionId = 10, + startValue = 1, + endValue = 2, + states = { + [1] = "Favorite colour is the green.", + [2] = "Favorite colour is the green." + } + }, + [3] = { + name = "The Secret of Mathemagics", + storageId = Storage.Quest.TheParadoxTower.Mathemagics, + missionId = 10, + startValue = 1, + endValue = 2, + states = { + [1] = "You learnt Mathemagics. Everything is based on the simple fact that 1+1=1.", + [2] = "You learnt Mathemagics. Everything is based on the simple fact that 1+1=1." + } + } + } + }, + [45] = { + name = "Spirithunters Quest", + startStorageId = Storage.SpiritHunters.Mission01, + startStorageValue = 1, + missions = { + [1] = { + name = "Method", + storageId = Storage.SpiritHunters.Mission01, + missionId = 1018, + startValue = 1, + endValue = 2, + states = { + [1] = "Use the item on the tombstones.", + [2] = "You have used these item in the tombstones." + } + }, + [2] = { + name = "First Mission", + storageId = Storage.SpiritHunters.Mission01, + missionId = 1019, + startValue = 2, + endValue = 4, + states = { + [3] = "Talk to Sinclair and take the ghost residue.", + [4] = "You got the ghost waste." + } + }, + [3] = { + name = "Second Mission", + storageId = Storage.SpiritHunters.Mission01, + missionId = 1020, + startValue = 4, + endValue = 6, + states = { + [5] = "You need to get more samples of ghosts.", + [6] = "You got all the ghost scraps." + } + } + } + }, + [3] = { + name = "Spike Task", + startStorageId = Storage.SpikeTaskQuest.QuestLine, + startStorageValue = 1, + missions = { + [1] = { + name = "First Task", + storageId = Storage.SpikeTaskQuest.Gnomilly, + missionId = 1021, + startValue = 0, + endValue = 100, + description = function(player) + return string.format( + "You have %d points of task. You need 100 points to take Cave Explorer outfit.", + (math.max(player:getStorageValue(Storage.SpikeTaskQuest.Gnomilly), 0)) + ) + end + }, + [2] = { + name = "Second Task", + storageId = Storage.SpikeTaskQuest.Gnombold.Points, + missionId = 1022, + startValue = 0, + endValue = 100, + description = function(player) + return string.format( + "You have %d points of task. You need 100 points to take first addon.", + (math.max(player:getStorageValue(Storage.SpikeTaskQuest.Gnombold.Points), 0)) + ) + end + }, + [3] = { + name = "Third Task", + storageId = Storage.SpikeTaskQuest.Gnomargery.Points, + missionId = 1023, + startValue = 0, + endValue = 100, + description = function(player) + return string.format( + "You have %d points of task. You need 100 points to take second addon.", + (math.max(player:getStorageValue(Storage.SpikeTaskQuest.Gnomargery.Points), 0)) + ) + end + } + } + }, + [4] = { + name = "A Father\'s Burden", + startStorageId = Storage.FathersBurden.QuestLog, + startStorageValue = 1, + missions = { + [1] = { + name = "The Birthday Presents", + storageId = Storage.FathersBurden.Status, + missionId = 1024, + startValue = 1, + endValue = 2, + states = { + [1] = "Gather the material Tereban listed. \z + Talk to him about your mission when you have given him everything he was looking for.", + [2] = "You brought all the required materials to Tereban and guaranteed his sons a great birthday party." + } + }, + [2] = { + name = "The Magic Bow - Sinew", + storageId = Storage.FathersBurden.Sinew, + missionId = 1025, + startValue = 1, + endValue = 2, + states = { + [1] = "Find the wyvern Heoni in the Edron mountains and take his sinew to Tereban.", + [2] = "You delivered Heoni\'s sinew to Tereban." + } + }, + [3] = { + name = "The Magic Bow - Wood", + storageId = Storage.FathersBurden.Wood, + missionId = 1026, + startValue = 1, + endValue = 2, + states = { + [1] = "Find the special wood in the barbarian camps of Hrodmir and bring it to Tereban. \z + It might be a good idea to start looking in the northernmost camp.", + [2] = "You delivered the Wood to Tereban." + } + }, + [4] = { + name = "The Magic Robe - Cloth", + storageId = Storage.FathersBurden.Cloth, + missionId = 1027, + startValue = 1, + endValue = 2, + states = { + [1] = "Find the spectral cloth hidden deep in the crypts of the isle of the kings and bring it to Tereban. \z + You might have to look for a secret entrance.", + [2] = "You delivered the spectral cloth to Tereban." + } + }, + [5] = { + name = "The Magic Robe - Silk", + storageId = Storage.FathersBurden.Silk, + missionId = 1028, + startValue = 1, + endValue = 2, + states = { + [1] = "Find exquisite silk in the spider caves of southern Zao and deliver it to Tereban.", + [2] = "You brought Tereban the required silk." + } + }, + [6] = { + name = "The Magic Rod - Crystal", + storageId = Storage.FathersBurden.Crystal, + missionId = 1029, + startValue = 1, + endValue = 2, + states = { + [1] = "Find a magic crystal in the tomb buried under the sand east of Ankrahmun and bring it to Tereban.", + [2] = "Tereban received the magic crystal he was looking for." + } + }, + [7] = { + name = "The Magic Rod - Root", + storageId = Storage.FathersBurden.Root, + missionId = 1030, + startValue = 1, + endValue = 2, + states = { + [1] = "Find the mystic root under the city of Banuta and bring it to Tereban.", + [2] = "The magic root was delievered to Tereban." + } + }, + [8] = { + name = "The Magic Shield - Iron", + storageId = Storage.FathersBurden.Iron, + missionId = 1031, + startValue = 1, + endValue = 2, + states = { + [1] = "Find some old iron in the mines of Kazordoon for Tereban. Don't get lost - \z + start searching close to the city.", + [2] = "Tereban got the old iron he required." + } + }, + [9] = { + name = "The Magic Shield - Scale", + storageId = Storage.FathersBurden.Scale, + missionId = 1032, + startValue = 1, + endValue = 2, + states = { + [1] = "Find the dragon Glitterscale in the caves north of Thais and take its scale to Tereban.", + [2] = "You handed the looted scale to Tereban." + } + } + } + }, + [5] = { + name = "Bigfoot\'s Burden", + startStorageId = Storage.BigfootBurden.QuestLine, + startStorageValue = 1, + missions = { + [1] = { + name = "Looking for Gnomerik", + storageId = Storage.BigfootBurden.QuestLine, + missionId = 1033, + startValue = 1, + endValue = 2, + description = "The dwarf Xelvar has sent you to meet the gnome Gnomerik. \z + He can recruit you to the Bigfoot Company. \z + Use the teleporter near Xelvar to enter the gnomish base and start looking for Gnomerik." + }, + [2] = { + name = "A New Recruit", + storageId = Storage.BigfootBurden.QuestLine, + missionId = 1034, + startValue = 3, + endValue = 4, + description = "You have found the gnomish recruiter and are ready to become a Bigfoot." + }, + [3] = { + name = "Recruitment: A Test in Gnomology", + storageId = Storage.BigfootBurden.QuestLine, + missionId = 1035, + startValue = 5, + endValue = 7, + states = { + [5] = "Pass Gnomerik\'s test by answering his questions. \z + If you fail to get a high enough score drink a mushroom beer and start again.", + [6] = "You have passed the gnomish psychology test and can proceed to the medical exam. \z + Talk to Gnomespector about your next examination." + } + }, + [4] = { + name = "Recruitment: Medical Examination", + storageId = Storage.BigfootBurden.QuestLine, + missionId = 1036, + startValue = 8, + endValue = 9, + description = "Walk through the g-ray apparatus for your g-raying." + }, + [5] = { + name = "Recruitment: Ear Examination", + storageId = Storage.BigfootBurden.QuestLine, + missionId = 1037, + startValue = 10, + endValue = 12, + states = { + [10] = "You have been g-rayed. It has been an ... unexpected experience. Now you are ready for your \z + ear examination. Walk up to doctor Gnomedix and wait for him to finish your ear examination.", + [11] = "You passed the ear examination. Well, at least most of you did. \z + Now talk to Gnomaticus about your next test. " + } + }, + [6] = { + name = "Recruitment: Gnomish Warfare", + storageId = Storage.BigfootBurden.Shooting, + missionId = 1038, + startValue = 0, + endValue = 5, + description = function(player) + return string.format( + "Hit five targets in a row. \z + Don't hit an innocent target as it will reset your hit counter. %d / 5", + (math.max(player:getStorageValue(Storage.BigfootBurden.Shooting), 0)) + ) + end + }, + [7] = { + name = "Recruitment: Gnomish Warfare", + storageId = Storage.BigfootBurden.QuestLine, + missionId = 1039, + startValue = 15, + endValue = 16, + description = "You are now ready for your endurance test. Talk to Gnomewart about it." + }, + [8] = { + name = "Recruitment: Endurance Test", + storageId = Storage.BigfootBurden.QuestLine, + missionId = 1040, + startValue = 17, + endValue = 20, + states = { + [17] = "Enter the lower chamber for your endurance test. Reach the teleporter north of the hall.", + [18] = "You have passed the endurance test. Report back to Gnomewart.", + [19] = "You passed the endurance test and are ready to talk to Gnomelvis about your soul melody." + } + }, + [9] = { + name = "Recruitment: Soul Melody", + storageId = Storage.BigfootBurden.QuestLine, + missionId = 1041, + startValue = 21, + endValue = 23, + states = { + [21] = "Find your personal soul melody by trial and error. \z + Create the complete soul melody of seven notes and then report to Gnomelvis. Red notes indicate a failure.", + [22] = "You found your very own soul melody. You should talk to Gnomelvis about it!" + } + }, + [10] = { + name = "Recruitment", + storageId = Storage.BigfootBurden.QuestLineComplete, + missionId = 1042, + startValue = 1, + endValue = 2, + description = "You are now a true member of the Bigfoot company." + }, + [11] = { + name = "Gnome Reputation", + storageId = Storage.BigfootBurden.Rank, + missionId = 1043, + startValue = 0, + endValue = 999999, + description = function(player) + return string.format( + "Your reputation in the eyes of gnomekind is %d.\nYour standing rises at: \z + \nReputation 30 - I \nReputation 120 - II \nReputation 480 - III \nReputation 1440 - IV \n", + (math.max(player:getStorageValue(Storage.BigfootBurden.Rank), 0)) + ) + end + }, + [12] = { + name = "Daily Minor: Crystal Keeper", + storageId = Storage.BigfootBurden.RepairedCrystalCount, + missionId = 1044, + startValue = 0, + endValue = 5, + description = function(player) + return string.format( + "Use the repair crystal to repair five damaged blue crystals in the crystal caves. \z + Damaged crystals will not glow.\n%d / 5", + (math.max(player:getStorageValue(Storage.BigfootBurden.RepairedCrystalCount), 0)) + ) + end + }, + [13] = { + name = "Daily Minor: Raiders of the Lost Spark", + storageId = Storage.BigfootBurden.ExtractedCount, + missionId = 1045, + startValue = 0, + endValue = 7, + description = function(player) + return string.format( + "Kill crystal crushers and use the discharger item on the corpse to collect their charges. \z + Gather 7 charges and report back. %d / 7", + (math.max(player:getStorageValue(Storage.BigfootBurden.ExtractedCount), 0)) + ) + end + }, + [14] = { + name = "Daily Minor Plus: Exterminators", + storageId = Storage.BigfootBurden.ExterminatedCount, + missionId = 1046, + startValue = 0, + endValue = 10, + description = function(player) + return string.format( + "Kill 10 of the wigglers for the gnomes. Then report back. %d / 10", + (math.max(player:getStorageValue(Storage.BigfootBurden.ExterminatedCount), 0)) + ) + end + }, + [15] = { + name = "Daily Minor Plus: Mushroom Digger", + storageId = Storage.BigfootBurden.MushroomCount, + missionId = 1047, + startValue = 0, + endValue = 3, + description = function(player) + return string.format( + "Find a truffle sniffing pig and lure it around. \z + Occasionally it will unearth some truffles. Use the baby pig on the truffles to feed it 3 times. \z + Then report back to the gnomes. %d / 3", + (math.max(player:getStorageValue(Storage.BigfootBurden.MushroomCount), 0)) + ) + end + }, + [16] = { + name = "Daily Major: Matchmaker", + storageId = Storage.BigfootBurden.MatchmakerStatus, + missionId = 1048, + startValue = 0, + endValue = 1, + states = { + [0] = "You have to enter the crystal caves and find a crystal that is fitting the crystal you got \z + from the gnomes. Use the crystal on one of the bigger red crystals in the caves to bond them.", + [1] = "You have finished this quest for now." + } + }, + [17] = { + name = "Daily Major: The Tinker\'s Bell", + storageId = Storage.BigfootBurden.GolemCount, + missionId = 1049, + startValue = 0, + endValue = 4, + description = function(player) + return string.format( + "Use the harmonic bell on the mad golems in the golem workshop so that they will \z + automatically be teleported to the gnomish workshops. Then report back to the gnomes. %d / 4", + (math.max(player:getStorageValue(Storage.BigfootBurden.GolemCount), 0)) + ) + end + }, + [18] = { + name = "Daily Major Advanced: Spores", + storageId = Storage.BigfootBurden.SporeCount, + missionId = 1050, + startValue = 0, + endValue = 4, + description = "Gather spores in the correct order. \z + Your spore gathering list will display the next color you have to look for." + }, + [19] = { + name = "Daily Major Advanced: Yet Another Grinding", + storageId = Storage.BigfootBurden.GrindstoneStatus, + missionId = 1051, + startValue = 0, + endValue = 2, + description = "Gather a grindstone from the lava area en report back." + }, + [20] = { + name = "Gnomish War Hero (Warzone 1)", + storageId = Storage.BigfootBurden.Warzone1Access, + missionId = 1052, + startValue = 1, + endValue = 2, + states = { + [1] = "Deliver the Deathstrike\'s snippet to gnomission to enter the first warzone for free.", + [2] = "You may enter the first warzone without using a mission crystal." + } + }, + [21] = { + name = "Gnomish War Hero (Warzone 2)", + storageId = Storage.BigfootBurden.Warzone2Access, + missionId = 1053, + startValue = 1, + endValue = 2, + states = { + [1] = "Deliver the Gnomevil\'s hat to gnomission to enter the second warzone for free.", + [2] = "You may enter the second warzone without using a mission crystal." + } + }, + [22] = { + name = "Gnomish War Hero (Warzone 3)", + storageId = Storage.BigfootBurden.Warzone3Access, + missionId = 1054, + startValue = 1, + endValue = 2, + states = { + [1] = "Deliver the Abyssador\'s lash to gnomission to enter the third warzone for free.", + [2] = "You may enter the third warzone without using a mission crystal." + } + } + } + }, + [6] = { + name = "Barbarian Test Quest", + startStorageId = Storage.BarbarianTest.Questline, + startStorageValue = 1, + missions = { + [1] = { + name = "Barbarian Test 1: Barbarian Booze", + storageId = Storage.BarbarianTest.Mission01, + missionId = 1055, + startValue = 1, + endValue = 3, + states = { + [1] = "Talk to Sven about mead and give him a honeycomb. For each honeycomb you will be allowed 20 sips.", + [2] = "Now drink from the bucket until you drink 10 sips in a row without passing out", + [3] = "You have completed this Test! Talk to Sven about the mead." + } + }, + [2] = { + name = "Barbarian Test 2: The Bear Hugging", + storageId = Storage.BarbarianTest.Mission02, + missionId = 1056, + startValue = 1, + endValue = 3, + states = { + [1] = "Sven gave you a Mead Horn. Fill it with mead from the bucket behind Sven (brown contents) \z + and then proceed to the sleeping bear. The bear is inside a small ice cave in the north. \z + Use the full mead horn on the bear so it becomes unconscious, then use the bear to hug it.", + [2] = "You hugging the bear! Go tell Sven that you hugged the bear!", + [3] = "You have completed this Test!" + } + }, + [3] = { + name = "Barbarian Test 3: The Mammoth Pushing", + storageId = Storage.BarbarianTest.Mission03, + missionId = 1057, + startValue = 1, + endValue = 3, + states = { + [1] = "Go to the north-west of Svargrond and find the Mammoth. Drink your three mugs of mead, \z + stand in front of the Mammoth and push it. Just use it...", + [2] = "You pushed the Mammoth! Go tell Sven that you pushed the Mammoth!", + [3] = "You have completed this Test! You can now be a citizen of Svargrond!" + } + } + } + }, + [7] = { + name = "Children of the Revolution", + startStorageId = Storage.ChildrenoftheRevolution.Questline, + startStorageValue = 1, + missions = { + [1] = { + name = "Prove Your Worzz!", + storageId = Storage.ChildrenoftheRevolution.Mission00, + missionId = 1058, + startValue = 1, + endValue = 2, + states = { + [1] = "Your Mission is to go to a little camp of lizards at north-east of the Dragonblaze Peaks. \z + You have to find and deliver the Tactical map complete the mission.", + [2] = "You delivered the Tactical map to Zalamon." + } + }, + [2] = { + name = "Mission 1: Corruption", + storageId = Storage.ChildrenoftheRevolution.Mission01, + missionId = 1059, + startValue = 1, + endValue = 3, + states = { + [1] = "Go to the Temple of Equilibrium (it\'s marked on your map) and find out what happened there.", + [2] = "The temple has been corrupted and is lost. Zalamon should be informed about this as soon as possible.", + [3] = "You already reported Zalamon about the Temple! Ask him for new mission!" + } + }, + [3] = { + name = "Mission 2: Imperial Zzecret Weaponzz", + storageId = Storage.ChildrenoftheRevolution.Mission02, + missionId = 1060, + startValue = 1, + endValue = 5, + states = { + [1] = "Go into the small camp Chaochai to the north of the Dragonblaze Peaks \z + (Zalamon marks the entrance on your map). There are 3 buildings which you have to spy", + [2] = "You spied 1 of 3 buildings of the camp.", + [3] = "You spied 2 of 3 buildings of the camp.", + [4] = "You spied 3 of 3 buildings of the camp. Zalamon should be informed about this as soon as possible.", + [5] = "You already reported Zalamon about the camp! Ask him for new mission!" + } + }, + [4] = { + name = "Mission 3: Zee Killing Fieldzz", + storageId = Storage.ChildrenoftheRevolution.Mission03, + missionId = 1061, + startValue = 1, + endValue = 3, + states = { + [1] = "Get the poison from Zalamon\'s storage room. Then go to the teleporter to the Muggy Plains and head \z + east from there to the rice fields. Go to the very top rice field and use the poison anywhere on the water.", + [2] = "The rice has been poisoned. This will weaken the Emperor\'s army significantly. \z + Return and tell Zalamon about your success.", + [3] = "You already reported Zalamon about your success! Ask him for new mission!" + } + }, + [5] = { + name = "Mission 4: Zze Way of Zztonezz", + storageId = Storage.ChildrenoftheRevolution.Mission04, + missionId = 1062, + startValue = 1, + endValue = 6, + states = { + [1] = "Your mission is to find a way to enter the north of the valley and find a \z + passage to the great gate itself. Search any temples or settlements you come across for hidden passages.", + [2] = "Report Zalamon about the strange symbols that you found.", + [3] = "Get the greasy oil from Zalamon\'s storage room and put them on the levers that you found.", + [4] = "Due to being extra greasy, the leavers can now be moved.", + [5] = "You found the right combination for the puzzle in the mountains and triggered some kind of mechanism. \z + You should head back to Zalamon to report your success.", + [6] = "You already reported Zalamon about your success! You got a Tome of Knowledge as reward! \z + Ask him for new mission!" + } + }, + [6] = { + name = "Mission 5: Phantom Army", + storageId = Storage.ChildrenoftheRevolution.Mission05, + missionId = 1063, + startValue = 1, + endValue = 3, + states = { + [1] = "Your mission is to use the portal in the chamber beyond the mechanism. \z + It will lead you to the great gate.", + [2] = "Eternal guardians and lizard chosen has been awaken. Survive them and report it to Zalamon!", + [3] = "You Survived the Waves and reported Zalamon about your success! You got a Serpent Crest as reward!" + } + } + } + }, + [8] = { + name = "Factions", + startStorageId = Storage.Factions, + startStorageValue = 1, + missions = { + [1] = { + name = "The Marid and the Efreet - Djinn Greeting", + storageId = Storage.DjinnWar.Faction.Greeting, + missionId = 1064, + startValue = 1, + endValue = 2, + states = { + [1] = "Melchior told you the word "Djanni'hah" which can be used to talk to Djinns. \z + Be aware that once you become an ally of one Djinn race, you cannot switch sides anymore.", + [2] = "" + } + }, + [2] = { + name = "The Marid and the Efreet - Marid Faction", + storageId = Storage.DjinnWar.Faction.MaridDoor, + missionId = 1065, + startValue = 1, + endValue = 2, + states = { + [1] = "You have joined the Marid. These friendly, blue Djinns are honest and fair allies. \z + You have pledged eternal loyalty to King Gabel and may enter Asha'daramai freely. Djanni'hah!", + [2] = "" + } + }, + [3] = { + name = "The Efreet and the Efreet - Efreet Faction", + storageId = Storage.DjinnWar.Faction.EfreetDoor, + missionId = 1066, + startValue = 1, + endValue = 2, + states = { + [1] = "You have joined the Efreet. These evil, green Djinns are always up to mischievous pranks. \z + You have pledged eternal loyalty to King Malor and may enter Mal'ouquah freely. Djanni'hah!", + [2] = "" + } + } + } + }, + [9] = { + name = "Friends and Traders", + startStorageId = Storage.FriendsandTraders.DefaultStart, + startStorageValue = 1, + missions = { + [1] = { + name = "The Sweaty Cyclops", + storageId = Storage.FriendsandTraders.TheSweatyCyclops, + missionId = 1067, + startValue = 1, + endValue = 2, + states = { + [1] = "Big Ben, the cyclops in Ab'Dendriel sends you to bring him 3 bast skirts for his woman. \z + After this he will help you to forge different steel.", + [2] = "Big Ben, the cyclops in Ab'Dendriel will help you to forge different steel now. \z + Just ask him if you need something." + } + }, + [2] = { + name = "The Mermaid Marina", + storageId = Storage.FriendsandTraders.TheMermaidMarina, + missionId = 1068, + startValue = 1, + endValue = 2, + states = { + [1] = "Marina, the mermaid north of Sabrehaven sends you to bring her 50 honeycombs. \z + After this she will help you create spool of yarn.", + [2] = "Marina, the mermaid north of Sabrehaven will help you to create a spool of yarn \z + from 10 pieces of spider silk. Just ask her if you need something." + } + }, + [3] = { + name = "The Blessed Stake", + storageId = Storage.FriendsandTraders.TheBlessedStake, + missionId = 1069, + startValue = 1, + endValue = 12, + states = { + [1] = "Quentin told you about an old prayer which can bind holy energy to an object. \z + Each of its ten lines has to be recited by a different priest though. \z + Bring Quentin a wooden stake from Gamon to start.", + [2] = "You received Quentin\'s prayer: "Light shall be near - and darkness afar". \z + Now, bring your stake to Tibra in the Carlin church for the next line of the prayer.", + [3] = "You received Tibra\'s prayer: "Hope may fill your heart - doubt shall be banned". \z + Now, bring your stake to Maealil in the Elven settlement for the next line of the prayer.", + [4] = "You received Maealil\'s prayer: "Peace may fill your soul - evil shall be cleansed". \z + Now, bring your stake to Yberius in the Venore temple for the next line of the prayer.", + [5] = "You received Yberius' prayer: "Protection will be granted - from dangers at hand". \z + Now, bring your stake to Isimov in the dwarven settlement for the next line of the prayer.", + [6] = "You received Isimov\'s prayer: "Unclean spirits shall be repelled". \z + Now, bring your stake to Amanda in Edron for the next line of the prayer.", + [7] = "You received Amanda\'s prayer: "Wicked curses shall be broken". \z + Now, bring your stake to Kasmir in Darashia for the next line of the prayer.", + [8] = "You received Kasmir\'s prayer: "Let there be honor and humility". \z + Now, bring your stake to Rahkem in Ankrahmun for the next line of the prayer.", + [9] = "You received Rahkem\'s prayer: "Let there be power and compassion". \z + Now, bring your stake to Brewster in Port Hope for the next line of the prayer.", + [10] = "You received Brewster\'s prayer: "Your hand shall be guided - your feet shall \z + walk in harmony". Now, bring your stake to Tyrias in Liberty Bay for the next line of the prayer.", + [11] = "You received Tyrias' prayer: "Your mind shall be a vessel for joy, light \z + and wisdom". He wasn't exactly happy though and said that if you need some mumbo jumbo again, \z + you should rather go to Chondur.", + [12] = "Chondur was surprised to hear that you had to travel through all of Tibia to have your \z + wooden stake blessed. He offered you help with the blessing if you should need one again in the future." + } + } + } + }, + [10] = { + name = "Hot Cuisine", + startStorageId = Storage.HotCuisineQuest.QuestStart, + startStorageValue = 1, + missions = { + [1] = { + name = "Hot Cuisine", + storageId = Storage.HotCuisineQuest.QuestLog, + missionId = 1070, + startValue = 1, + endValue = 16, + states = { + [1] = "You've become the apprentice of Maltre Jean Pierre. \z + The first dish he will teach you to prepare is Rotworm Stew. Bring him the ingredients he told you.", + [2] = "You have completed the first dish, the second dish he will teach you to prepare is Hydra Tongue Salad. \z + Bring him the ingredients he told you.", + [3] = "You have completed the second dish, the third dish he will teach you to prepare is Roasted Dragon Wings. \z + Bring him the ingredients he told you.", + [4] = "You have completed the third dish, the fourth dish he will teach you to prepare is Tropical Fried \z + Terrorbird. Bring him the ingredients he told you.", + [5] = "You have completed the fourth dish, the fifth dish he will teach you to prepare is \z + Banana Chocolate Shake. Bring him the ingredients he told you.", + [6] = "You have completed the fifth dish, the sixth dish he will teach you to prepare is Veggie Casserole. \z + Bring him the ingredients he told you.", + [7] = "You have completed the sixth dish, the seventh dish he will teach you to prepare is \z + Filled Jalapeno Peppers. Bring him the ingredients he told you.", + [8] = "You have completed the seventh dish, the eight dish he will teach you to prepare is Blessed Steak. \z + Bring him the ingredients he told you.", + [9] = "You have completed the eight dish, the ninth dish he will teach you to prepare is Northern Fishburger. \z + Bring him the ingredients he told you.", + [10] = "You have completed the ninth dish, the tenth dish he will teach you to prepare is Carrot Cake. \z + Bring him the ingredients he told you.", + [11] = "You have completed the tenth dish. You are now able to obtain the cookbook from \z + Jean Pierre\'s room upstairs.", + [12] = "The eleventh dish he will teach you to prepare is Coconut Shrimp Bake. \z + Bring him the ingredients he told you.", + [13] = "You have completed the eleventh dish, the twelfth dish he will teach you to prepare is Blackjack. \z + Bring him the ingredients he told you.", + [14] = "You have completed the twelfth dish, the thirteenth dish he will teach you to \z + prepare is Demonic Candy Balls. Bring him the ingredients he told you.", + [15] = "You have completed the thirteenth dish, the fourteenth dish he will teach you to \z + prepare is Sweet Mangonaise Elixir. Bring him the ingredients he told you.", + [16] = "You have completed all the dishes. You are now able to make all the dishes in any order you want." + } + } + } + }, + [11] = { + name = "In Service of Yalahar", + startStorageId = Storage.InServiceofYalahar.Questline, + startStorageValue = 5, + missions = { + [1] = { + name = "Mission 01: Something Rotten", + storageId = Storage.InServiceofYalahar.Mission01, + missionId = 1071, + startValue = 1, + endValue = 6, + states = { + [1] = "Palimuth asked you to help with some sewer malfunctions. \z + You will need a Crowbar, there are 4 places where you need to go marked with an X on your map.", + [2] = "You cleaned 1 pipe of 4 from the garbage.", + [3] = "You cleaned 2 pipes of 4 from the garbage.", + [4] = "You cleaned 3 pipes of 4 from the garbage.", + [5] = "You cleaned 4 pipes of 4 from the garbage. Go back to Palimuth and report your mission", + [6] = "You cleaned all pipes from the garbage! Go back to Palimuth and ask for mission." + } + }, + [2] = { + name = "Mission 02: Watching the Watchmen", + storageId = Storage.InServiceofYalahar.Mission02, + missionId = 1072, + startValue = 1, + endValue = 8, + states = { + [1] = "You have to find all 7 guards and give a report to them. \z + You should start by Foreign Quarter or by Trade Quarter and follow the order of the path..", + [2] = "You reported to 1 of 7 guards", + [3] = "You reported to 2 of 7 guards", + [4] = "You reported to 3 of 7 guards", + [5] = "You reported to 4 of 7 guards", + [6] = "You reported to 5 of 7 guards", + [7] = "You reported to 6 of 7 guards", + [8] = "You reported to 7 of 7 guards! Go back to Palimuth and ask for mission." + } + }, + [3] = { + name = "Mission 03: Death to the Deathbringer", + storageId = Storage.InServiceofYalahar.Mission03, + missionId = 1073, + startValue = 1, + endValue = 6, + states = { + [1] = "Get the notes in Palimuths room and read them. Talk to Palimuth again when you've read the notes.", + [2] = "Talk to Azerus the Yalahari in the city centre to get your next mission.", + [3] = "Get the notes behind the Yalahari and read them. \z + Talk to Azerus again and ask him for mission when you've read the notes.", + [4] = "Ask Palimuth for mission.", + [5] = "First you will need to kill the three plague bearers and then get The Alchemists' Formulas. \z + When this have been done head back to either Palimuth (good side) or Yalahari (Azerus) (bad side).", + [6] = "Ask Azerus the Yalahari for a mission." + } + }, + [4] = { + name = "Mission 04: Good to be Kingpin", + storageId = Storage.InServiceofYalahar.Mission04, + missionId = 1074, + startValue = 1, + endValue = 6, + states = { + [1] = "Ask Palimuth for mission.", + [2] = "For this mission you are asked to go to the Trade Quarter and negotiate or threaten Mr. West. \z + Once again you will gain access to the mechanism although if you \z + choose to help Palimuth you should go through the sewers.", + [3] = "You decided to help Palimuth, report him your mission.", + [4] = "You decided to help Azerus, report him your mission. ", + [5] = "Get back to Azerus and report him your mission.", + [6] = "Ask Azerus for a mission." + } + }, + [5] = { + name = "Mission 05: Food or Fight", + storageId = Storage.InServiceofYalahar.Mission05, + missionId = 1075, + startValue = 1, + endValue = 8, + states = { + [1] = "Ask Palimuth for mission.", + [2] = "On this mission you are asked to find a druid by the name of Tamerin, on the Arena Quarter. \z + You now have permission to use the gates mechanism.", + [3] = "The first is to bring Tamerin a flask of Animal Cure, \z + you can buy this from Siflind on Nibelor (northeast of Svargrond).", + [4] = "now you have to kill Morik the Gladiator and bring his helmet to Tamerin as proof.", + [5] = "Report back to Tamerin as he will listen to your request and you can now make your choice: \z + Cattle for Palimuth (good side), Warbeasts for Yalahari (Azerus) (bad side). \z + Then report the one you decided your mission.", + [6] = "You decided to help Palimuth, report him your mission.", + [7] = "You decided to help Azerus, report him your mission.", + [8] = "Ask Azerus for a mission." + } + }, + [6] = { + name = "Mission 06: Frightening Fuel", + storageId = Storage.InServiceofYalahar.Mission06, + missionId = 1076, + startValue = 1, + endValue = 5, + states = { + [1] = "Ask Palimuth for mission.", + [2] = "Yalahari (Azerus) orders you to travel to the Cemetery Quarter and find the Strange Carving. \z + He gives you a Ghost Charm and tells you to charge it with the tormented souls of the ghosts there \z + to be used as an energy source. Palimuth wants the Charged Ghost Charm in order to free those souls. \z + You can new use the Cemetery Quarter mechanism now. Go to the big building in the Cemetery Quarter and \z + use the Ghost Charm on the Strange Carving at the back of the room.", + [3] = "Good side: Go to Palimuth, ask him about your mission, and hand in the charm. Bad side: \z + Ask about your mission to Yalahari (Azerus) and give it back.", + [4] = "Get back to Azerus and report him your mission.", + [5] = "Ask Azerus for a mission." + } + }, + [7] = { + name = "Mission 07: A Fishy Mission", + storageId = Storage.InServiceofYalahar.Mission07, + missionId = 1077, + startValue = 1, + endValue = 5, + states = { + [1] = "Ask Palimuth for mission.", + [2] = "Bad side: Yalahari (Azerus) will send you for a new mission to go to the Sunken Quarter and kill the \z + Quara Leaders, Inky, Splasher and Sharptooth. Good side: Rather than fighting any Quara leaders Palimuth \z + will instead send you to find the cause for the Quaras aggressive behavior. Find Maritima and talk to her \z + about the Quara and she will explain what their problem is.", + [3] = "Get back to Palimuth and report him your mission.", + [4] = "You killed the Quarabosses. Ask Azerus for a mission.", + [5] = "Ask Azerus for a mission." + } + }, + [8] = { + name = "Mission 08: Dangerous Machinations", + storageId = Storage.InServiceofYalahar.Mission08, + missionId = 1078, + startValue = 1, + endValue = 4, + states = { + [1] = "Ask Palimuth for mission.", + [2] = "Bad side: For this mission the Yalahari requests you go to the Factory Quarter and \z + find a pattern crystal, which will be used to supply weapons to help take control of the city. Good side: \z + Palimuth will send you there to use the crystal to supply food for the city.", + [3] = "Get back to Azerus and report him your mission.", + [4] = "Ask Azerus for a mission." + } + }, + [9] = { + name = "Mission 09: Decision", + storageId = Storage.InServiceofYalahar.Mission09, + missionId = 1079, + startValue = 1, + endValue = 2, + states = { + [1] = "You now need to decide between supporting Palimuth or the Yalahari\'s goal. \z + To choose Palimuth\'s good side go to him, and simply ask him for a mission mission. \z + Likewise, to join the Yalahari (Azerus) (bad side) go to him and say the same.", + [2] = "you already decided!" + } + }, + [10] = { + name = "Mission 10: The Final Battle", + storageId = Storage.InServiceofYalahar.Mission10, + missionId = 1080, + startValue = 1, + endValue = 5, + states = { + [1] = "Palimuth told you that a circle of Yalahari is planning some kind of ritual. They plan to create \z + a portal for some powerful demons and to unleash them in the city to 'purge' it once and for all.", + [2] = "The entrance to their inner sanctum has been opened for you. \z + Be prepared for a HARD battle! Better gather some friends to assist you.", + [3] = "Report back to whichever principal you have chosen to help and you will receive Yalaharian Outfits.", + [4] = "You got the access to the reward room. \z + Choose carefully which reward you pick as you can only take one item.", + [5] = "You have completed the Quest!" + } + } + } + }, + [12] = { + name = "Killing in the Name of...", + startStorageId = 100157, + startStorageValue = 1, + missions = { + [1] = { + name = "Paw and Fur: Member", + storageId = 2500, + missionId = 1081, + startValue = 0, + endValue = 10, + description = function(player) + return string.format( + "You are member of the Paw and Fur hunting elite. You currently have %d Paw and Fur points.", + (math.max(player:getStorageValue(2500), 0)) + ) + end + }, + [2] = { + name = "Paw and Fur: Ranger", + storageId = 2500, + missionId = 1082, + startValue = 11, + endValue = 40, + description = function(player) + return string.format( + "You are Ranger of the Paw and Fur hunting elite. You currently have %d Paw and Fur points.", + (math.max(player:getStorageValue(2500), 0)) + ) + end + }, + [3] = { + name = "Paw and Fur: Big Game Hunter", + storageId = 2500, + missionId = 1083, + startValue = 41, + endValue = 69, + description = function(player) + return string.format( + "You are Big Game Hunter in the Paw and Fur hunting elite. \z + You currently have %d Paw and Fur points.", + (math.max(player:getStorageValue(2500), 0)) + ) + end + }, + [4] = { + name = "Paw and Fur: Trophy Hunter", + storageId = 2500, + missionId = 1084, + startValue = 70, + endValue = 99, + description = function(player) + return string.format( + "You are Trophy Hunter in the Paw and Fur hunting elite. \z + You currently have %d Paw and Fur points. \z + Ask Grizzly Adams for 'special task' he might have something for you.", + (math.max(player:getStorageValue(2500), 0)) + ) + end + }, + [5] = { + name = "Paw and Fur: Elite Hunter", + storageId = 2500, + missionId = 1085, + startValue = 100, + endValue = 9999, + description = function(player) + return string.format( + "You have obtained the highest possible rank in the Paw and Fur hunting elite, \z + you are Elite Hunter. You currently have %d Paw and Fur points. \z + Ask Grizzly Adams for 'special task' he might have something for you.", + (math.max(player:getStorageValue(2500), 0)) + ) + end + }, + [6] = { + name = "Paw and Fur: Tiquandas Revenge", + storageId = Storage.KillingInTheNameOf.TiquandasRevengeTeleport, + missionId = 1086, + startValue = 1, + endValue = 2, + states = { + [1] = "Grizzly Adams told you that there is Tiquandas Revenge hiding somewhere in the jungle of Port Hope. \z + Go find its hideout and kill it.", + [2] = "You have slained the Tiquandas Revenge." + } + }, + [7] = { + name = "Paw and Fur: Demodras", + storageId = Storage.KillingInTheNameOf.DemodrasTeleport, + missionId = 1087, + startValue = 1, + endValue = 2, + states = { + [1] = "Grizzly Adams wanted you to go look for Demodras' hideout. \z + He also mentioned that it might be somewhere under the Plains of Havoc.", + [2] = "You have slained the Demodras." + } + }, + [8] = { + name = "Paw and Fur: The Snapper", + storageId = 34100, + missionId = 1088, + startValue = 1, + endValue = 2, + description = "Grizzly told you about the Snapper, a crocodile that already killed many citizens of Port Hope. \z + Try find its hideout and kill it." + }, + [9] = { + name = "Paw and Fur: Hide", + storageId = 34101, + missionId = 1089, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [10] = { + name = "Paw and Fur: Deathbine", + storageId = 34102, + missionId = 1090, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [11] = { + name = "Paw and Fur: The Bloodtusk", + storageId = 34103, + missionId = 1091, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [12] = { + name = "Paw and Fur: Shardhead", + storageId = 34104, + missionId = 1092, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [13] = { + name = "Paw and Fur: Esmerelda", + storageId = 34105, + missionId = 1093, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [14] = { + name = "Paw and Fur: Fleshcrawler", + storageId = 34106, + missionId = 1094, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [15] = { + name = "Paw and Fur: Ribstride", + storageId = 34107, + missionId = 1095, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [16] = { + name = "Paw and Fur: Bloodweb", + storageId = 34108, + missionId = 1096, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [17] = { + name = "Paw and Fur: Thul", + storageId = 34109, + missionId = 1097, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [18] = { + name = "Paw and Fur: The Old Widow", + storageId = 34110, + missionId = 1098, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [19] = { + name = "Paw and Fur: Hemming", + storageId = 34111, + missionId = 1099, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [20] = { + name = "Paw and Fur: Tormentor", + storageId = 34112, + missionId = 10100, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [21] = { + name = "Paw and Fur: Flameborn", + storageId = 34113, + missionId = 10101, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [22] = { + name = "Paw and Fur: Fazzrah", + storageId = 34114, + missionId = 10102, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [23] = { + name = "Paw and Fur: Tromphonyte", + storageId = 34115, + missionId = 10103, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [24] = { + name = "Paw and Fur: Sulphur Scuttler", + storageId = 34116, + missionId = 10104, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [25] = { + name = "Paw and Fur: Bruise Payne", + storageId = 34117, + missionId = 10105, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [26] = { + name = "Paw and Fur: The Many", + storageId = 34118, + missionId = 10106, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [27] = { + name = "Paw and Fur: The Noxious Spawn", + storageId = 34119, + missionId = 10107, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [28] = { + name = "Paw and Fur: Gorgo", + storageId = 34120, + missionId = 10108, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [29] = { + name = "Paw and Fur: Stonecracker", + storageId = 34121, + missionId = 10109, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [30] = { + name = "Paw and Fur: Leviathan", + storageId = 34122, + missionId = 10110, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [31] = { + name = "Paw and Fur: Kerberos", + storageId = 34123, + missionId = 10111, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [32] = { + name = "Paw and Fur: Ethershreck", + storageId = 34124, + missionId = 10112, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [33] = { + name = "Paw and Fur: Paiz the Pauperizer", + storageId = 34125, + missionId = 10113, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [34] = { + name = "Paw and Fur: Bretzecutioner", + storageId = 34126, + missionId = 10114, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [35] = { + name = "Paw and Fur: Zanakeph", + storageId = 34127, + missionId = 10115, + startValue = 1, + endValue = 2, + description = "Try find its hideout and kill it." + }, + [36] = { + name = "Edron City - Elite Hunting: Trolls", + storageId = 1501, + missionId = 10116, + startValue = 0, + endValue = 100, + description = function(player) + return string.format("You already hunted %d/100 Trolls.", (math.max(player:getStorageValue(1501), 0))) + end + }, + [37] = { + name = "Edron City - Elite Hunting: Goblins", + storageId = 1502, + missionId = 10117, + startValue = 0, + endValue = 150, + description = function(player) + return string.format("You already hunted %d/150 Goblins.", (math.max(player:getStorageValue(1502), 0))) + end + }, + [38] = { + name = "Paw and Fur: Minotaurs", + storageId = 65002, + missionId = 10118, + startValue = 0, + endValue = 5000, + description = function(player) + return string.format("You already hunted %d/5000 Minotaurs.", (math.max(player:getStorageValue(65002), 0))) + end + }, + [39] = { + name = "Paw and Fur: Necromancers and Priestess", + storageId = 65001, + missionId = 10119, + startValue = 0, + endValue = 4000, + description = function(player) + return string.format( + "You already hunted %d/4000 Necromancers and Priestess.", + (math.max(player:getStorageValue(65001), 0)) + ) + end + }, + [40] = { + name = "Paw and Fur: Crocodiles", + storageId = 65003, + missionId = 10120, + startValue = 0, + endValue = 300, + description = function(player) + return string.format("You already hunted %d/300 crocodiles.", (math.max(player:getStorageValue(65003), 0))) + end + }, + [41] = { + name = "Paw and Fur: Badgers", + storageId = 65004, + missionId = 10121, + startValue = 0, + endValue = 300, + description = function(player) + return string.format("You already hunted %d/300 badgers.", (math.max(player:getStorageValue(65004), 0))) + end + }, + [42] = { + name = "Paw and Fur: Tarantulas", + storageId = 65005, + missionId = 10122, + startValue = 0, + endValue = 300, + description = function(player) + return string.format("You already hunted %d/300 tarantulas.", (math.max(player:getStorageValue(65005), 0))) + end + }, + [43] = { + name = "Paw and Fur: Carniphilas", + storageId = 65006, + missionId = 10123, + startValue = 0, + endValue = 150, + description = function(player) + return string.format("You already hunted %d/150 carniphilas.", (math.max(player:getStorageValue(65006), 0))) + end + }, + [44] = { + name = "Paw and Fur: Stone Golems", + storageId = 65007, + missionId = 10124, + startValue = 0, + endValue = 200, + description = function(player) + return string.format("You already hunted %d/200 stone golems.", (math.max(player:getStorageValue(65007), 0))) + end + }, + [45] = { + name = "Paw and Fur: Mammoths", + storageId = 65008, + missionId = 10125, + startValue = 0, + endValue = 300, + description = function(player) + return string.format("You already hunted %d/300 mammoths.", (math.max(player:getStorageValue(65008), 0))) + end + }, + [46] = { + name = "Paw and Fur: Gnarlhounds", + storageId = 65009, + missionId = 10126, + startValue = 0, + endValue = 300, + description = function(player) + return string.format("You already hunted %d/300 gnarlhounds.", (math.max(player:getStorageValue(65009), 0))) + end + }, + [47] = { + name = "Paw and Fur: Terramites", + storageId = 65010, + missionId = 10127, + startValue = 0, + endValue = 300, + description = function(player) + return string.format("You already hunted %d/300 terramites.", (math.max(player:getStorageValue(65010), 0))) + end + }, + [48] = { + name = "Paw and Fur: Apes", + storageId = 65011, + missionId = 10128, + startValue = 0, + endValue = 300, + description = function(player) + return string.format("You already hunted %d/300 apes.", (math.max(player:getStorageValue(65011), 0))) + end + }, + [49] = { + name = "Paw and Fur: Thornback Tortoises", + storageId = 65012, + missionId = 10129, + startValue = 0, + endValue = 300, + description = function(player) + return string.format( + "You already hunted %d/300 thornback tortoises.", + (math.max(player:getStorageValue(65012), 0)) + ) + end + }, + [50] = { + name = "Paw and Fur: Gargoyles", + storageId = 65013, + missionId = 10130, + startValue = 0, + endValue = 300, + description = function(player) + return string.format("You already hunted %d/300 gargoyles.", (math.max(player:getStorageValue(65013), 0))) + end + }, + [51] = { + name = "Paw and Fur: Ice Golems", + storageId = 65014, + missionId = 10131, + startValue = 0, + endValue = 300, + description = function(player) + return string.format("You already hunted %d/300 ice golems.", (math.max(player:getStorageValue(65014), 0))) + end + }, + [52] = { + name = "Paw and Fur: Quara Scouts", + storageId = 65015, + missionId = 10132, + startValue = 0, + endValue = 400, + description = function(player) + return string.format("You already hunted %d/400 quara scouts.", (math.max(player:getStorageValue(65015), 0))) + end + }, + [53] = { + name = "Paw and Fur: Mutated Rats", + storageId = 65016, + missionId = 10133, + startValue = 0, + endValue = 400, + description = function(player) + return string.format("You already hunted %d/400 mutated rats.", (math.max(player:getStorageValue(65016), 0))) + end + }, + [54] = { + name = "Paw and Fur: Ancient Scarabs", + storageId = 65017, + missionId = 10134, + startValue = 0, + endValue = 250, + description = function(player) + return string.format("You already hunted %d/250 ancient scarabs.", (math.max(player:getStorageValue(65017), 0))) + end + }, + [55] = { + name = "Paw and Fur: Wyverns", + storageId = 65018, + missionId = 10135, + startValue = 0, + endValue = 300, + description = function(player) + return string.format("You already hunted %d/300 wyverns.", (math.max(player:getStorageValue(65018), 0))) + end + }, + [56] = { + name = "Paw and Fur: Lancer Beetles", + storageId = 65019, + missionId = 10136, + startValue = 0, + endValue = 300, + description = function(player) + return string.format("You already hunted %d/300 lancer beetles.", (math.max(player:getStorageValue(65019), 0))) + end + }, + [57] = { + name = "Paw and Fur: Wailing Widows", + storageId = 65020, + missionId = 10137, + startValue = 0, + endValue = 400, + description = function(player) + return string.format("You already hunted %d/400 wailing widows.", (math.max(player:getStorageValue(65020), 0))) + end + }, + [58] = { + name = "Paw and Fur: Killer Caimans", + storageId = 65021, + missionId = 10138, + startValue = 0, + endValue = 250, + description = function(player) + return string.format("You already hunted %d/250 killer caimans.", (math.max(player:getStorageValue(65021), 0))) + end + }, + [59] = { + name = "Paw and Fur: Bonebeasts", + storageId = 65022, + missionId = 10139, + startValue = 0, + endValue = 300, + description = function(player) + return string.format("You already hunted %d/300 bonebeasts.", (math.max(player:getStorageValue(65022), 0))) + end + }, + [60] = { + name = "Paw and Fur: Crystal Spiders", + storageId = 65023, + missionId = 10140, + startValue = 0, + endValue = 300, + description = function(player) + return string.format("You already hunted %d/300 crystal spiders.", (math.max(player:getStorageValue(65023), 0))) + end + }, + [61] = { + name = "Paw and Fur: Mutated Tigers", + storageId = 65024, + missionId = 10141, + startValue = 0, + endValue = 300, + description = function(player) + return string.format("You already hunted %d/300 mutated tigers.", (math.max(player:getStorageValue(65024), 0))) + end + }, + [62] = { + name = "Paw and Fur: Underwater Quara", + storageId = 65025, + missionId = 10142, + startValue = 0, + endValue = 600, + description = function(player) + return string.format("You already hunted %d/600 underwater quara.", (math.max(player:getStorageValue(65025), 0))) + end + }, + [63] = { + name = "Paw and Fur: Giant Spiders", + storageId = 65026, + missionId = 10143, + startValue = 0, + endValue = 500, + description = function(player) + return string.format("You already hunted %d/500 giant spiders.", (math.max(player:getStorageValue(65026), 0))) + end + }, + [64] = { + name = "Paw and Fur: Werewolves", + storageId = 65027, + missionId = 10144, + startValue = 0, + endValue = 300, + description = function(player) + return string.format("You already hunted %d/300 werewolves.", (math.max(player:getStorageValue(65027), 0))) + end + }, + [65] = { + name = "Paw and Fur: Nightmares", + storageId = 65028, + missionId = 10145, + startValue = 0, + endValue = 400, + description = function(player) + return string.format("You already hunted %d/400 nightmares.", (math.max(player:getStorageValue(65028), 0))) + end + }, + [66] = { + name = "Paw and Fur: Hellspawns", + storageId = 65029, + missionId = 10146, + startValue = 0, + endValue = 600, + description = function(player) + return string.format("You already hunted %d/600 hellspawns.", (math.max(player:getStorageValue(65029), 0))) + end + }, + [67] = { + name = "Paw and Fur: High Class Lizards", + storageId = 65030, + missionId = 10147, + startValue = 0, + endValue = 800, + description = function(player) + return string.format( + "You already hunted %d/800 high class lizards.", + (math.max(player:getStorageValue(65030), 0)) + ) + end + }, + [68] = { + name = "Paw and Fur: Stampors", + storageId = 65031, + missionId = 10148, + startValue = 0, + endValue = 600, + description = function(player) + return string.format("You already hunted %d/600 stampors.", (math.max(player:getStorageValue(65031), 0))) + end + }, + [69] = { + name = "Paw and Fur: Brimstone Bugs", + storageId = 65032, + missionId = 10149, + startValue = 0, + endValue = 500, + description = function(player) + return string.format("You already hunted %d/500 brimstone bugs.", (math.max(player:getStorageValue(65032), 0))) + end + }, + [70] = { + name = "Paw and Fur: Mutated Bats", + storageId = 65033, + missionId = 10150, + startValue = 0, + endValue = 400, + description = function(player) + return string.format("You already hunted %d/400 mutated bats.", (math.max(player:getStorageValue(65033), 0))) + end + }, + [71] = { + name = "Paw and Fur: Hydras", + storageId = 65034, + missionId = 10151, + startValue = 0, + endValue = 650, + description = function(player) + return string.format("You already hunted %d/650 hydras.", (math.max(player:getStorageValue(65034), 0))) + end + }, + [72] = { + name = "Paw and Fur: Serpent Spawns", + storageId = 65035, + missionId = 10152, + startValue = 0, + endValue = 800, + description = function(player) + return string.format("You already hunted %d/800 serpent spawns.", (math.max(player:getStorageValue(65035), 0))) + end + }, + [73] = { + name = "Paw and Fur: Medusas", + storageId = 65036, + missionId = 10153, + startValue = 0, + endValue = 500, + description = function(player) + return string.format("You already hunted %d/500 medusas.", (math.max(player:getStorageValue(65036), 0))) + end + }, + [74] = { + name = "Paw and Fur: Behemoths", + storageId = 65037, + missionId = 10154, + startValue = 0, + endValue = 700, + description = function(player) + return string.format("You already hunted %d/700 behemoths.", (math.max(player:getStorageValue(65037), 0))) + end + }, + [75] = { + name = "Paw and Fur: Sea Serpents and Young Sea Serpents", + storageId = 65038, + missionId = 10155, + startValue = 0, + endValue = 900, + description = function(player) + return string.format( + "You already hunted %d/900 sea serpents and young sea serpents.", + (math.max(player:getStorageValue(65038), 0)) + ) + end + }, + [76] = { + name = "Paw and Fur: Hellhounds", + storageId = 65039, + missionId = 10156, + startValue = 0, + endValue = 250, + description = function(player) + return string.format("You already hunted %d/250 hellhounds.", (math.max(player:getStorageValue(65039), 0))) + end + }, + [77] = { + name = "Paw and Fur: Ghastly Dragons", + storageId = 65040, + missionId = 10157, + startValue = 0, + endValue = 500, + description = function(player) + return string.format("You already hunted %d/500 ghastly dragons.", (math.max(player:getStorageValue(65040), 0))) + end + }, + [78] = { + name = "Paw and Fur: Drakens", + storageId = 65041, + missionId = 10158, + startValue = 0, + endValue = 900, + description = function(player) + return string.format("You already hunted %d/900 drakens.", (math.max(player:getStorageValue(65041), 0))) + end + }, + [79] = { + name = "Paw and Fur: Destroyers", + storageId = 65042, + missionId = 10159, + startValue = 0, + endValue = 650, + description = function(player) + return string.format("You already hunted %d/650 destroyers.", (math.max(player:getStorageValue(65042), 0))) + end + }, + [80] = { + name = "Paw and Fur: Undead Dragons", + storageId = 65043, + missionId = 10160, + startValue = 0, + endValue = 400, + description = function(player) + return string.format("You already hunted %d/400 undead dragons.", (math.max(player:getStorageValue(65043), 0))) + end + }, + [81] = { + name = "Paw and Fur: Demons", + storageId = 65044, + missionId = 10161, + startValue = 0, + endValue = 6666, + description = function(player) + return string.format("You already hunted %d/6666 demons.", (math.max(player:getStorageValue(65044), 0))) + end + }, + [82] = { + name = "Paw and Fur: Green Djinns or Efreets", + storageId = 65045, + missionId = 10162, + startValue = 0, + endValue = 500, + description = function(player) + return string.format( + "You already hunted %d/500 green djinns or efreets.", + (math.max(player:getStorageValue(65045), 0)) + ) + end + }, + [83] = { + name = "Paw and Fur: Blue Djinns or Marids", + storageId = 65046, + missionId = 10163, + startValue = 0, + endValue = 500, + description = function(player) + return string.format( + "You already hunted %d/500 blue djinns or marids.", + (math.max(player:getStorageValue(65046), 0)) + ) + end + }, + [84] = { + name = "Paw and Fur: Pirates", + storageId = 65047, + missionId = 10164, + startValue = 0, + endValue = 3000, + description = function(player) + return string.format("You already hunted %d/3000 pirates.", (math.max(player:getStorageValue(65047), 0))) + end + }, + [85] = { + name = "Paw and Fur: Pirates Second", + storageId = 65048, + missionId = 10165, + startValue = 0, + endValue = 3000, + description = function(player) + return string.format("You already hunted %d/3000 pirates.", (math.max(player:getStorageValue(65048), 0))) + end + }, + [86] = { + name = "Turmoil of War", + storageId = Storage.KillingInTheNameOf.BudrikMinos, + missionId = 10166, + startValue = 0, + endValue = 5000, + description = function(player) + return string.format( + "Budrik asked you to kill 5000 minotaurs for him. You already killed %d minotaurs.", + (math.max(player:getStorageValue(Storage.KillingInTheNameOf.BudrikMinosCount), 0)) + ) + end + }, + [87] = { + name = "Paw and Fur: Necromancers and Priestess", + storageId = Storage.KillingInTheNameOf.LugriNecromancers, + missionId = 10167, + startValue = 0, + endValue = 4000, + description = function(player) + return string.format( + "You already hunted %d/4000 necromancers and priestess.", + (math.max(player:getStorageValue(Storage.KillingInTheNameOf.LugriNecromancerCount), 0)) + ) + end + } + } + }, + [13] = { + name = "Outfit and Addon Quests", + startStorageId = Storage.OutfitQuest.DefaultStart, + startStorageValue = 1, + missions = { + [1] = { + name = "Assassin Addon: The Red Death", + storageId = Storage.OutfitQuest.AssassinSecondAddon, + missionId = 10168, + startValue = 1, + endValue = 2, + states = { + [1] = "Atrad wants only two items from you for his old katana: a behemoth claw and a nose ring, \z + both at the same time. He also told you about a "horned fox" who wears such as nose ring", + [2] = "You have received the second assassin addon." + } + }, + [2] = { + name = "Citizen Addon: Backpack", + storageId = Storage.OutfitQuest.Citizen.MissionBackpack, + missionId = 10169, + startValue = 1, + endValue = 2, + states = { + [1] = "Collect 100 pieces of minotaur leather and bring it to either Amber or Lubo \z + to have them make a backpack addon for you.", + [2] = "You delivered 100 pieces of minotaur leather. Some time is needed to make the backpack for you though. \z + You should check back later and ask either Amber or Lubo for your backpack." + } + }, + [3] = { + name = "Citizen Addon: Feather Hat", + storageId = Storage.OutfitQuest.Citizen.MissionHat, + missionId = 10170, + startValue = 1, + endValue = 2, + states = { + [1] = "Collect a legion helmet, 100 chicken feathers and 50 honeycombs and bring them to either \z + Hanna or Norma to have them make a feather hat addon for you." + } + }, + [4] = { + name = "Barbarian Outfit Quest", + storageId = Storage.OutfitQuest.BarbarianAddon, + missionId = 10171, + startValue = 1, + endValue = 17, + states = { + [1] = "Bron told you that his brother Ajax in Northport needs to learn that violence is not \z + always the answer. He told you to make his brother angry, then show him that all he \z + needed to do was say 'please' to fix the situation.", + [2] = "You will need to leave Ajax alone for an hour, then return to him.", + [3] = "Ajax told you that he has thought about it, and that violence is not always good. \z + Return to Bron now, and tell him that Ajax said fist not always good", + [4] = "Bron mentioned that he has someone in his house that he doesn't like, and he wants you to \z + get advice from Ajax about how to handle the situation. Go back to Ajax and ask him about Gelagos", + [5] = "Ajax told you his brother needs Fighting Spirit, and that you should get some from a Djinn \z + and give it to him.", + [6] = "You brought Bron the Fighting Spirit. He acted a little strange.", + [7] = "In order to make a shirt as a present for Ajax, Bron wants you to bring him 50 Pieces of \z + Red Cloth and 50 Pieces of Green Cloth.", + [8] = "Bron wants you to bring him 10 Spider Silk Yarn.", + [9] = "Bron wants you to bring him the Warrior\'s Sweat.", + [10] = "You brought him all required items! accept it!", + [11] = "You got the Barbarian Wig Addon! Bring now the present from Bron to Ajax!", + [12] = "Bring Ajax in Northport 100 Iron Ore.", + [13] = "Bring Ajax 1 Huge Chunk of Crude Iron.", + [14] = "Bring Ajax 50 Perfect Behemoth Fang", + [15] = "Bring Ajax 50 Lizard Leather", + [16] = "Come later in 2 hours and ask Ajax for the axe.", + [17] = "You got the Axe Addon!" + } + }, + [5] = { + name = "Beggar Outfit: The Newest Fashion", + storageId = Storage.OutfitQuest.BeggarOutfit, + missionId = 10172, + startValue = 1, + endValue = 6, + states = { + [1] = "Your current task is to bring Hugo 20 pieces of brown cloth, like the worn and ragged ghoul clothing.", + [2] = "Your current task is to bring 50 pieces of minotaur leather to Hugo. \z + If you don't know how to get leather, you should ask Kalvin.", + [3] = "Your current task is to bring 10 bat wings to Hugo.", + [4] = "Your current task is to bring 30 heaven blossoms to Hugo. Elves are said to cultivate these flowers.", + [5] = "You brought all items required for the "poor man\'s look" to Hugo. \z + He told you to come back to him after a whole day has passed, then the outfit should be finished.", + [6] = "You got the outfit!" + } + }, + [6] = { + name = "Druid Outfit Quest", + storageId = Storage.OutfitQuest.DruidHatAddon, + missionId = 10173, + startValue = 1, + endValue = 10, + states = { + [1] = "Ceiron sends you to collect a sample of the blooming Griffinclaw.", + [2] = "Ask Ceiron for task.", + [3] = "take Ceirons waterskin and try to fill it with water from this special trickle. \z + In the mountains between Ankrahmun and Tiquanda are two hydra lairs. \z + It is important that you take the water directly from the trickle, not from the pond", + [4] = "Ask Ceiron for task.", + [5] = "Bring Ceiron 100 ounces of demon dust.", + [6] = "Ask Ceiron for task.", + [7] = "The last mission is to find and retrieve Ceiron\'s Wolf Tooth Chain lost inside the Orc Fortress.", + [8] = "Ask Ceiron for Faolan.", + [9] = "Head over to Cormaya, find A Majestic Warwolf\'s Cave and ask her about an addon.", + [10] = "You got the Outfit!" + } + }, + [7] = { + name = "Hunter Outfit Quest", + storageId = Storage.OutfitQuest.HunterHatAddon, + missionId = 10174, + startValue = 1, + endValue = 5, + states = { + [1] = "Elane sends you to Liberty Bay to bring her the Crossbow from the Cult.", + [2] = "Bring Elane 100 pieces of lizard leather and 100 pieces of red dragon leather.", + [3] = "Bring Elane 5 enchanted chicken wings.", + [4] = "Bring Elane one piece of royal steel, draconian steel and hell steel each.", + [5] = "You got the Outfit!" + } + }, + [8] = { + name = "Knight Addon: Helmet", + storageId = Storage.OutfitQuest.Knight.MissionHelmet, + missionId = 10175, + startValue = 1, + endValue = 6, + states = { + [1] = "Your current task is to bring 100 perfect behemoth fangs to Gregor in Thais.", + [2] = "Your current task is to retrieve the helmet of Ramsay the Reckless from Banuta. \z + These pesky apes steal everything they can get their dirty hands on.", + [3] = "Your current task is to obtain a flask of warrior\'s sweat, which can be magicially extracted \z + from headgear worn by a true warrior, but only in small amounts. Djinns are said to be good at this.", + [4] = "Your current task is to bring royal steel to Gregor in Thais. \z + Royal steel can only be refined by very skilled smiths.", + [5] = "You have delivered all items required for the helmet addon. \z + Go talk to Sam and tell him Gregor sent you. He will be glad to refine your helmet.", + [6] = "Sam is currently creating the helmet for you. Be patient and don't forget to check on it later!" + } + }, + [9] = { + name = "Mage & Summoner Outfit Quest (Wand)", + storageId = Storage.OutfitQuest.MageSummoner.AddonWand, + missionId = 10176, + startValue = 1, + endValue = 7, + states = { + [1] = "You found Angelina in a Prison. She told you a secret: \z + Lynda in Thais can create a blessed wand. Greet her from Angelina, maybe she will aid you.", + [2] = "Lynda send you to bring her a sample of all five wands and five rods \z + (Snakebite, Moonlight, Necrotic, Terra, Hailstorm, Vortex, Dragonbreath, Decay, Cosmic Energy and Inferno)", + [3] = "Bring Lynda 10 ounces of magic sulphur", + [4] = "Bring Lynda the Necromancer\'s soul stone", + [5] = "Bring Lynda 20 ankhs now to complete the ritual.", + [6] = "You need to wait 3 hours for the ritual to be completed", + [7] = "You got the Outfit!" + } + }, + [10] = { + name = "Mage & Summoner Outfit Quest (Fluid Belt)", + storageId = Storage.OutfitQuest.MageSummoner.AddonBelt, + missionId = 10177, + startValue = 1, + endValue = 2, + states = { + [1] = "Now you can get a lottery ticket at Sandra for 100 empty vials.", + [2] = "You got the Outfit! Now you can get for a lottery prize 50000 gold!" + } + }, + [11] = { + name = "Female Mage and Male Summoner Addon: Headgear", + storageId = Storage.OutfitQuest.MageSummoner.MissionHatCloak, + missionId = 10178, + startValue = 1, + endValue = 11, + states = { + [1] = "Your current task is to bring 70 bat wings to Myra in Port Hope.", + [2] = "Your current task is to bring 20 pieces of red cloth to Myra in Port Hope. \z + These are said to make an excellent material for a cape.", + [3] = "Your current task is to bring 40 pieces of ape fur to Myra in Port Hope.", + [4] = "Your current task is to bring 35 holy orchids to Myra in Port Hope. Elves are said to cultivate these.", + [5] = "Your current task is to bring 10 spools of spider silk yarn to Myra in Port Hope. \z + Only very large spiders produce silk which is strong enough to be yarned by mermaids.", + [6] = "Your current task is to bring 60 lizard scales to Myra in Port Hope. \z + Lizard scales are great for all sort of magical potions.", + [7] = "Your current task is to bring 40 red dragon scales to Myra in Port Hope.", + [8] = "Your current task is to bring 15 ounces of magic sulphur to Myra in Port Hope. \z + Djinns are said to be good at extracting magic sulphur.", + [9] = "Your current task is to bring 30 ounces of vampire dusts to Myra in Port Hope. \z + You might need to ask a priest for a special blessed stake to turn vampires into dust.", + [10] = "You finally collected all of the items which Myra asked for. \z + Go talk to Zoltan in Edron and tell him that Myra nominated you for an award." + } + }, + [12] = { + name = "Norseman Outfit Quest", + storageId = Storage.OutfitQuest.NorsemanAddon, + missionId = 10179, + startValue = 1, + endValue = 3, + states = { + [1] = "Bring Hjaern 5 frostheart shards to get the first Addon. Ask him for shard!", + [2] = "Bring Hjaern 10 frostheart shards to get the second Addon. Ask him for shard!", + [3] = "You got the Outfit Addons! You can trade the rest shards to Hjaern for 2000 gold each!" + } + }, + [13] = { + name = "Warrior Addon: Shoulder Spike", + storageId = Storage.OutfitQuest.WarriorShoulderAddon, + missionId = 10180, + startValue = 1, + endValue = 7, + states = { + [1] = "Your current task is to bring 100 hardened bones to Trisha in Carlin. \z + They can sometimes be extracted from creatures that consist only of - you guessed it, bones. \z + You need an obsidian knife though.", + [2] = "Your current task is to bring 100 turtle shells to Trisha in Carlin. \z + Turtles can be found on some idyllic islands which have recently been discovered.", + [3] = "Your current task is to show that you have fighting spirit. Maybe someone grants you a wish...?", + [4] = "Your current task is to obtain a dragon claw. \z + You cannot get this special claw from any common dragons in Tibia. \z + It requires a special one, a lord among the lords.", + [5] = "You have delivered all items requried for the shoulder spike addon. \z + Go talk to Cornelia and tell her Trisha sent you. She will be glad to create the should spikes.", + [6] = "Cornelia is currently creating the should spikes for you. \z + Be patient and don't forget to check on it later!", + [7] = "You have obtained the shoulder spike addon." + } + }, + [14] = { + name = "Wizard Outfits Quest", + storageId = Storage.OutfitQuest.WizardAddon, + missionId = 10181, + startValue = 1, + endValue = 7, + states = { + [1] = "Bring Lugri the Medusa shield!", + [2] = "Bring Lugri the Dragon Scale Mail!", + [3] = "Bring Lugri the Crown Legs!", + [4] = "Bring Lugri the Ring of the Sky!", + [5] = "You got the first Outfit Addon!", + [6] = "Bring The Queen Of The Banshees 50 Holy Orchids and she will reward you with the second addon.", + [7] = "You got the second Outfit Addon!" + } + }, + [15] = { + name = "Pirate Outfit Quest (Sabre)", + storageId = Storage.OutfitQuest.PirateSabreAddon, + missionId = 10182, + startValue = 1, + endValue = 5, + states = { + [1] = "Bring Duncan 100 Eye Patches from pirates!", + [2] = "Bring Duncan 100 peg legs from pirates!", + [3] = "Bring Duncan 100 pirate hooks from pirates!", + [4] = "Go to Morgan and tell him this codeword: 'firebird' to get the outfit addon!", + [5] = "You got the Outfit Addon!" + } + }, + [16] = { + name = "Oriental Addon: Hipwear", + storageId = Storage.OutfitQuest.FirstOrientalAddon, + missionId = 10183, + startValue = 1, + endValue = 2, + states = { + [1] = "Your current task is to find a mermaid\'s comb. \z + If you have ever encountered a mermaid, you should ask her. \z + Bring the comb to Habdel if you are male or to Ishina if you are female.", + [2] = "You have received the first oriental addon." + } + }, + [17] = { + name = "Oriental Addon: Headgear", + storageId = Storage.OutfitQuest.SecondOrientalAddon, + missionId = 10184, + startValue = 1, + endValue = 5, + states = { + [1] = "Your current task is to bring 100 pieces of ape fur to Razan if you are male, \z + or to Miraia if you are female.", + [2] = "Your current task is to bring 100 fish fins to Razan if you are male, or to Miraia if you are female.", + [3] = "Your current task is to bring 2 enchanted chicken wings to Razan if you are male, \z + or to Miraia if you are female.", + [4] = "Your current task is to bring 100 pieces of blue cloth to Razan if you are male, \z + or to Miraia if you are female.", + [5] = "You have received the second oriental addon." + } + }, + [18] = { + name = "Shaman Addon: Staff", + storageId = Storage.OutfitQuest.Shaman.MissionStaff, + missionId = 10185, + startValue = 1, + endValue = 2, + states = { + [1] = "Try to find a monster which sometimes lurks in the Tiquandian jungle as the revenge of the jungle \z + against mankind. Bring the rare root it carries to Chondur as well as 5 voodoo dolls." + } + }, + [19] = { + name = "Shaman Addon: Mask", + storageId = Storage.OutfitQuest.Shaman.MissionMask, + missionId = 10186, + startValue = 1, + endValue = 2, + states = { + [1] = "Your current task is to collect 5 tribal masks from the dworcs and 5 banana staves from the apes. \z + Bring them to Chondur to earn your shamanic mask." + } + } + } + }, + [14] = { + name = "Sam\'s Old Backpack", + startStorageId = Storage.SamsOldBackpack, + startStorageValue = 1, + missions = { + [1] = { + name = "Dwarven Armor Quest", + storageId = Storage.SamsOldBackpack, + missionId = 10187, + startValue = 1, + endValue = 3, + states = { + [1] = "Sam sends you to see Kroox in Kazordoon to get a special dwarven armor. \z + Just tell him, his old buddy Sam is sending you.", + [2] = "You have the permission to retrive a dwarven armor from the mines. \z + The problem is, some giant spiders made the tunnels where the storage is their new home.", + [3] = "You have completed Dwarven Armor Quest!" + } + } + } + }, + [15] = { + name = "Sea of Light", + startStorageId = Storage.SeaOfLight.Questline, + startStorageValue = 1, + missions = { + [1] = { + name = "Mission 1: The Plans", + storageId = Storage.SeaOfLight.Mission1, + missionId = 10188, + startValue = 1, + endValue = 4, + states = { + [1] = "Spectulus in Edron has sent you on a mission to find out the whereabouts of a certain inventor. \z + A beggar in Edron seems to know more about this topic than he wants to tell.", + [2] = "The beggar turned out to be the inventor himself. \z + You successfully convinced him to give you the only remaining plans of his creation. \z + You should return to Spectulus in Edron to tell him the news.", + [3] = "You gave the plans to the astronomer. \z + He began reconstructing the invention as soon as he got ahold of them. \z + It will take a while for him to work out the problem which caused the initial failure.", + [4] = "You returned to Speculus who finally worked out the failure of the initial construction. \z + He recapitulated the plans and needs only one item before he can start building the magic device." + } + }, + [2] = { + name = "Mission 2: The Collector", + storageId = Storage.SeaOfLight.Mission2, + missionId = 10189, + startValue = 1, + endValue = 3, + states = { + [1] = "Spectulus asked you to enter the Lost Mines beneath Edron and recover a rare crystal. In exchange for \z + it you will gain access to the lair of the Collector who guards a vital component of the device.", + [2] = "Luckily, you survived the horrors of the Lost Mines and recovered a rare crystal. \z + You should visit Spectulus in Edron to seek counsel on what to do next.", + [3] = "You returned to astronomer Spectulus and gave him the rare crystal." + } + }, + [3] = { + name = "Mission 3: The Mirror Crystal", + storageId = Storage.SeaOfLight.Mission3, + missionId = 10190, + startValue = 1, + endValue = 4, + states = { + [1] = "In order to access the lair of the Collector, you will need to find the creature\'s well on \z + an ice isle near Carlin. To donate the rare crystal overcome your greed and use it at the well\'s pedestal.", + [2] = "You offered the rare crystal to the creature and can now enter the Collector\'s lair. \z + Its crystal chamber cannot be accessed by outsiders. You need to find a way to snatch the Mirror Crystal.", + [3] = "The Collector has been defeated. \z + You packed the fragile Mirror Crystal into the device Spectulus gave you. \z + All yo have to do now is to return to the astronomer and to present him your acquisition.", + [4] = "It may have been the excitement or simple nervousness but as soon as Spectulus removed the crystal, \z + it somehow slipped. Unfinishable for all eternity, the device left yet another scholar in despair." + } + } + } + }, + [16] = { + name = "Secret Service", + startStorageId = Storage.SecretService.Quest, + startStorageValue = 1, + missions = { + [1] = { + name = "Mission 1: From Thais with Love", + storageId = Storage.SecretService.TBIMission01, + missionId = 10191, + startValue = 1, + endValue = 3, + states = { + [1] = "Your first mission is to deliver a warning to the Venoreans. \z + Get a fire bug from Liberty Bay and set their shipyard on fire.", + [2] = "You have set the Venoreans shipyard on fire, report back to Chester!", + [3] = "You have reported back that you have completed your mission, ask Chester for a new mission!" + } + }, + [2] = { + name = "Mission 1: For Your Eyes Only", + storageId = Storage.SecretService.AVINMission01, + missionId = 10192, + startValue = 1, + endValue = 4, + states = { + [1] = "Your first task is to deliver a letter to Gamel in thais, If he is a bit reluctant, be persuasive.", + [2] = "Gamel sent his thugs on you, defeat them and deliver the letter to Gamel!", + [3] = "After defeating Gamel\'s thugs, he found you to be persuasive enough to accept the letter. \z + Report back to Uncle!", + [4] = "You have reported back that you have completed your task. Ask Uncle for a new mission!" + } + }, + [3] = { + name = "Mission 1: Borrowed Knowledge", + storageId = Storage.SecretService.CGBMission01, + missionId = 10193, + startValue = 1, + endValue = 2, + states = { + [1] = "Emma has requested that you steal a Nature Magic Spellbook in the Edron academy.", + [2] = "You have delivered the Nature Magic Spellbook to Emma, ask her for a new mission!" + } + }, + [4] = { + name = "Mission 2: Operation Green Claw", + storageId = Storage.SecretService.TBIMission02, + missionId = 10194, + startValue = 1, + endValue = 2, + states = { + [1] = "Your next mission is to find some information about one of \z + their missing agents in The Green Claw Swamp.", + [2] = "You have delivered the Black Knight\'s notes to Chester, ask him for a new mission!" + } + }, + [5] = { + name = "Mission 2: A File Between Friends", + storageId = Storage.SecretService.AVINMission02, + missionId = 10195, + startValue = 1, + endValue = 2, + states = { + [1] = "Your next task is to retrieve a file named AH-X17L89.", + [2] = "You have delivered the file named AH-X17L89 to Uncle, ask him for a new mission!" + } + }, + [6] = { + name = "Mission 2: Codename:Lumberjack", + storageId = Storage.SecretService.CGBMission02, + missionId = 10196, + startValue = 1, + endValue = 2, + states = { + [1] = "Emma has requested that you retrieve a Rotten Heart of a Tree from \z + the Black Knight Villa in Greenclaw swamp north-west of Venore.", + [2] = "You have delivered the Rotten Heart of a Tree to Emma, ask her for a new mission!" + } + }, + [7] = { + name = "Mission 3: Treachery in Port Hope", + storageId = Storage.SecretService.TBIMission03, + missionId = 10197, + startValue = 1, + endValue = 3, + states = { + [1] = "Your next mission is to retrieve some evidence that the traders in Port Hope are up to no good!", + [2] = "You have found the evidence, report back to Chester!", + [3] = "You have reported back that you have completed your mission, ask Chester for a new mission!" + } + }, + [8] = { + name = "Mission 3: What Men are Made of", + storageId = Storage.SecretService.AVINMission03, + missionId = 10198, + startValue = 1, + endValue = 4, + states = { + [1] = "Your next task is to bring a barrel of beer to the Secret Tavern in the sewers of Carlin.", + [2] = "On your way to the Secret Tavern in the sewers you were attacked by amazons trying to stop you! \z + Deliver the barrel of beer to Karl.", + [3] = "You have delivered the barrel of beer to Karl, report back to Uncle!", + [4] = "You have reported back that you have completed your task, ask Uncle for a new mission!" + } + }, + [9] = { + name = "Mission 3: Rust in Peace", + storageId = Storage.SecretService.CGBMission03, + missionId = 10199, + startValue = 1, + endValue = 3, + states = { + [1] = "Emma has requested that you damage the Ironhouse of Venore, use the \z + Case of Rust Bugs on the keyhole in the cellar of the ironhouse.", + [2] = "The bugs are at work! Report back to Emma.", + [3] = "You have reported back that you have completed your mission, ask her for a new mission!" + } + }, + [10] = { + name = "Mission 4: Objective Hellgate", + storageId = Storage.SecretService.TBIMission04, + missionId = 10200, + startValue = 1, + endValue = 2, + states = { + [1] = "Your next mission is to investigate for some documents in Hellgate.", + [2] = "You have delivered the documents to Chester, ask him for a new mission!" + } + }, + [11] = { + name = "Mission 4: Pawn Captures Knight", + storageId = Storage.SecretService.AVINMission04, + missionId = 10201, + startValue = 1, + endValue = 3, + states = { + [1] = "Your next task is to travel to the Black Knight\'s Villa and kill the Black Knight!", + [2] = "You have killed the Black Knight, report back to Uncle!", + [3] = "You have reported back that you have completed your task, ask Uncle for a new mission!" + } + }, + [12] = { + name = "Mission 4: Plot for A Plan", + storageId = Storage.SecretService.CGBMission04, + missionId = 10202, + startValue = 1, + endValue = 2, + states = { + [1] = "Emma has requested that you retrieve the Building Plans for a ship from the Venore shipyard.", + [2] = "You have delivered the Building Plans to Emma, ask her for a new mission!" + } + }, + [13] = { + name = "Mission 5: Coldfinger", + storageId = Storage.SecretService.TBIMission05, + missionId = 10203, + startValue = 1, + endValue = 3, + states = { + [1] = "Your next mission is to travel to the southern barbarians camp and place false evidence!", + [2] = "You have placed the false evidence! Report back to Chester.", + [3] = "You have reported back that you have completed your mission, ask Chester for a new mission!" + } + }, + [14] = { + name = "Mission 5: A Cryptic Mission", + storageId = Storage.SecretService.AVINMission05, + missionId = 10204, + startValue = 1, + endValue = 2, + states = { + [1] = "Your next task is to travel to the Isle of the Kings and find a ring.", + [2] = "You have delivered the ring to Uncle, ask him for a new mission!" + } + }, + [15] = { + name = "Mission 5: No Admittance", + storageId = Storage.SecretService.CGBMission05, + missionId = 10205, + startValue = 1, + endValue = 2, + states = { + [1] = "Emma has requested that you find some hints in the ruins of Dark Cathedral.", + [2] = "You have delivered the Suspicious Documents to Emma, ask her for a new mission!" + } + }, + [16] = { + name = "Mission 6: The Weakest Spot", + storageId = Storage.SecretService.TBIMission06, + missionId = 10206, + startValue = 1, + endValue = 3, + states = { + [1] = "Your next mission is to disguise yourself as an amazon and destroy a \z + beer casket in the north-east corner in the cellar of Svargrond\'s Tavern.", + [2] = "You have succesfully destroyed the beer casket disguised as an amazon, report back to Chester!", + [3] = "You have reported back that you have completed your mission, ask Chester for a new mission!" + } + }, + [17] = { + name = "Mission 6: A Little Bribe Won't Hurt", + storageId = Storage.SecretService.AVINMission06, + missionId = 10207, + startValue = 1, + endValue = 3, + states = { + [1] = "Your next task is to bribe a barbarian in the large barbarian camp with a weapons crate.", + [2] = "You have bribed Freezhild with the weapons create! Report back to Uncle.", + [3] = "You have reported back that you have completed your task, ask Uncle for a new mission!" + } + }, + [18] = { + name = "Mission 6: News From the Past", + storageId = Storage.SecretService.CGBMission06, + missionId = 10208, + startValue = 1, + endValue = 2, + states = { + [1] = "Emma has requested that you go to the Isle of the Kings and retrieve a book.", + [2] = "You have delivered the book to Emma, ask her for a new mission!" + } + }, + [19] = { + name = "Mission 7: Licence to Kill", + storageId = Storage.SecretService.Mission07, + missionId = 10209, + startValue = 1, + endValue = 2, + states = { + [1] = "A Mad Technomancer in Kazordoon is trying to blackmail the city! \z + Kill him and bring back his beard as proof.", + [2] = "You have reported back that you have completed your mission, you are now a Special Agent!" + } + } + } + }, + [17] = { + name = "The Ancient Tombs", + startStorageId = Storage.TheAncientTombs.DefaultStart, + startStorageValue = 1, + missions = { + [1] = { + name = "Omruc\'s Treasure", + storageId = Storage.TheAncientTombs.OmrucsTreasure, + missionId = 10210, + startValue = 1, + endValue = 1, + description = "You defeated Omruc and received a helmet adornment" + }, + [2] = { + name = "Thalas' Treasure", + storageId = Storage.TheAncientTombs.ThalasTreasure, + missionId = 10211, + startValue = 1, + endValue = 1, + description = "You defeated Thalas and received a Gem Holder" + }, + [3] = { + name = "Diphtrah\'s Treasure", + storageId = Storage.TheAncientTombs.DiphtrahsTreasure, + missionId = 10212, + startValue = 1, + endValue = 1, + description = "You defeated Dipthrah and received a Damaged Helmet" + }, + [4] = { + name = "Mahrdis' Treasure", + storageId = Storage.TheAncientTombs.MahrdisTreasure, + missionId = 10213, + startValue = 1, + endValue = 1, + description = "You defeated Mahrdis and received a Helmet Ornament" + }, + [5] = { + name = "Vashresamun\'s Treasure", + storageId = Storage.TheAncientTombs.VashresamunsTreasure, + missionId = 10214, + startValue = 1, + endValue = 1, + description = "You solved the musical riddles of Vashresamun\'s Tomb and received a left horn." + }, + [6] = { + name = "Morguthis' Treasure", + storageId = Storage.TheAncientTombs.MorguthisTreasure, + missionId = 10215, + startValue = 1, + endValue = 1, + description = "You defeated Morguthis and received a Right Horn" + }, + [7] = { + name = "Rahemos' Treasure", + storageId = Storage.TheAncientTombs.RahemosTreasure, + missionId = 10216, + startValue = 1, + endValue = 1, + description = "You defeated Rahemos and received a Helmet Piece" + } + } + }, + [18] = { + name = "The Ape City", + startStorageId = Storage.TheApeCity.Started, + startStorageValue = 1, + missions = { + [1] = { + name = "Hairycles' Missions", + storageId = Storage.TheApeCity.Questline, + missionId = 10217, + startValue = 1, + endValue = 18, + states = { + [1] = "Find whisper moss in the dworc settlement south of Port Hope and bring it back to Hairycles.", + [2] = "You have completed the first mission. Hairycles was happy about the whisper moss you gave to him. \z + He might have another mission for you.", + [3] = "Hairycles asked you to bring him cough syrup from a human settlement. \z + A healer might know more about this medicine.", + [4] = "You have completed the second mission. Hairycles was happy about the cough syrup you gave to him. \z + He might have another mission for you.", + [5] = "Hairycles asked you to bring him a magical scroll from the lizard settlement Chor.", + [6] = "You have completed the third mission. Hairycles appreciated that you brought \z + the scroll to him and will try to read it. Maybe he has another mission for you later.", + [7] = "Since Hairycles was not able to read the scroll you brought him, he asked you dig for a tomb in the \z + desert to the east. Proceed in this tomb until you find an obelisk between red stones and read it.", + [8] = "You have completed the fourth mission. \z + Hairycles read your mind and can now translate the lizard scroll. \z + He might have another mission for you.", + [9] = "Hairycles wants to create a life charm for the ape people. \z + He needs a hydra egg since it has strong regenerating powers.", + [10] = "You have completed the fifth mission. \z + Hairycles attempts to create a might charm for the protection of the ape people. \z + He might have another mission for you later.", + [11] = "Hairycles need a witches' cap mushroom which is supposed to be hidden in a dungeon deep under Fibula.", + [12] = "You have completed the sixth mission. You brought the witches' cap mushroom back to Hairycles. \z + He might have another mission for you.", + [13] = "Hairycles is worried about an ape cult which drinks some strange fluid that the lizards left behind. \z + Go to the old lizard temple under Banuta and destroy three of the casks there with a crowbar.", + [14] = "You have completed the seventh mission. \z + You found the old lizard ruins under Banuta and destroyed three of the casks with snake blood. \z + Hairycles might have another mission for you.", + [15] = "The apes now need a symbol of their faith. \z + Speak with the blind prophet in a cave to the northeast and go to the Forbidden Land. \z + Find a hair of the giant, holy ape Bong and bring it back.", + [16] = "You completed the eighth mission. Hairycles gladly accepted the hair of the ape \z + god which you brought him. He told you to have one final mission for you.", + [17] = "Go into the deepest catacombs under Banuta and destroy the monument of \z + the snake god with the hammer that Hairycles gave to you.", + [18] = "You successfully destroyed the monument of the snake god. \z + As reward, you can buy sacred statues from Hairycles. \z + If you haven't done so yet, you should also ask him for a shaman outfit." + } + } + } + }, + [19] = { + name = "The Beginning", + startStorageId = Storage.RookgaardTutorialIsland.SantiagoQuestLog, + startStorageValue = 1, + missions = { + [1] = { + name = "The Cockroach Plague", + storageId = Storage.RookgaardTutorialIsland.SantiagoQuestLog, + missionId = 10218, + startValue = 1, + endValue = 11, + states = { + [1] = "You have found a fisherman called Santiago, who has a little problem. \z + Maybe you should talk to him again to find out more.", + [2] = "Santiago asked you to go into his house. Upstairs you will find a chest. \z + You can keep what you find inside of it. Once you got that, talk to Santiago again.", + [3] = "You have found Santiago\'s Coat and reported back to him. \z + Your quest is not done yet, you should talk to him a bit more.", + [4] = "Santiago gave you a weapon. After equipping it, go to the cellar of his house to find out \z + about the cockroach plague.", + [5] = "You brought the cockroach legs to Santiago. He still has something to tell you though.", + [6] = "Santiago asked you, if those cockroaches hurt you. You should reply to him!", + [7] = "Santiago has a valuable lesson for you. You should talk to him again.", + [8] = "Santiago showed you how some monsters might hurt you. \z + Better to talk to him to learn a way to heal yourself.", + [9] = "Santiago gave you some fish! Just 'use' it to eat it and regain health. \z + Afterwards, you should talk to Santiago again.", + [10] = "Santiago asked you if you had seen Zirella. Don't let him wait for the answer.", + [11] = "You have helped Santiago a lot by killing the cokcroaches in his cellar. \z + In exchange, he gave you equipment and some valuable experience. Well done!" + } + }, + [2] = { + name = "Collecting Wood", + storageId = Storage.RookgaardTutorialIsland.ZirellaQuestLog, + missionId = 10219, + startValue = 1, + endValue = 8, + states = { + [1] = "You have a vague idea that Zirella might need you for collecting firewood, \z + but you don't know yet where to get it. You should talk to her again.", + [2] = "You know that the branches Zirella needs might be gotten from dead trees in \z + the forest south of here, but you don't know the details yet. You should talk to her \z + but there is some information missing. You should talk to Zirella again.", + [4] = "You have learned that you can push the branch which you've broken from a dead tree by \z + 'Drag & Drop', but you still need some information. You should talk to Zirella again.", + [5] = "You know that you have to 'Use' the branch. Then leftclick with the changed cursor on the cart. \z + Now you just have to tell Zirella that you will help her.", + [6] = "Go into the forest south of here and look for trees without leaves. 'Use' one to break a branch \z + from it, then drag & drop the branch back to her cart and 'Use' it with the cart.", + [7] = "You have brought a branch to Zirella, congratulations! You should talk to her again for your reward.", + [8] = "You have helped Zirella by collecting wood for her. The reward can be found in her house." + } + }, + [3] = { + name = "A Hungry Tailor", + storageId = Storage.RookgaardTutorialIsland.CarlosQuestLog, + missionId = 10220, + startValue = 1, + endValue = 8, + states = { + [1] = "You found another person named Carlos. You should talk to him learn how to change your outfit.", + [2] = "Carlos taught you how to change your outfit. Now he seems to be wanting a small favour from you. \z + Talk to him again to learn more.", + [3] = "Carlos asked you whether you could bring him some food. \z + Talk to him again to learn how to find food here.", + [4] = "Carlos asked you to hunt some deer and rabbits and loot them to find a piece of ham or meat. \z + However you haven't agreed yet, so you should tell him that you'll do it.", + [5] = "You agreed to bring Carlos some food. \z + Hunt some deer or rabbit until you find a piece of meat or ham talk to Carlos again.", + [6] = "To sell the meat or ham to Carlos, talk to him and ask him for a 'trade'.", + [7] = "You sucessfully learnt how to change your outfit and how to trade with NPCs. \z + Time to head over the bridge to Rookgaard!", + [8] = "You have passed the bridge to Rookgaard and have sucessfully completed the Tutorial. \z + If you want to skip the tutorial in the future with a new character, simply say \'skip tutorial' to Santiago." + } + } + } + }, + [20] = { + name = "The Djinn War - Efreet Faction", + startStorageId = Storage.DjinnWar.EfreetFaction.Start, + startStorageValue = 1, + missions = { + [1] = { + name = "Efreet Mission 1: The Supply Thief", + storageId = Storage.DjinnWar.EfreetFaction.Mission01, + missionId = 10221, + startValue = 1, + endValue = 3, + states = { + [1] = "Travel to Thais and keep your eyes open for something that might give you a clue on the supply thief.", + [2] = "You have found the potential supply thief - Partos in Thais seemed very suspicious. \z + Baa'leal might be interested in this matter.", + [3] = "You have reported the case to Baa'leal. \z + He seemed very satisfied and told you that Alesar might have another mission for you." + } + }, + [2] = { + name = "Efreet Mission 2: The Tear of Daraman", + storageId = Storage.DjinnWar.EfreetFaction.Mission02, + missionId = 10222, + startValue = 1, + endValue = 3, + states = { + [1] = "Sneak into Ashta'daramai and steal a "Tear of Daraman". \z + For more information about these gems visit the Efreet library.", + [2] = "You have successfully managed to steal a Tear of Daraman from Ashta'daramai. Bring it to Alesar.", + [3] = "You have delivered Daraman\'s Tear. \z + Alesar seemed very satisfied and told you that Malor himself might have another mission for you." + } + }, + [3] = { + name = "Efreet Mission 3: The Sleeping Lamp", + storageId = Storage.DjinnWar.EfreetFaction.Mission03, + missionId = 10223, + startValue = 1, + endValue = 3, + states = { + [1] = "Malor asked you to find Fa'hradin\'s sleeping lamp in the orc fortress at Ulderek\'s Rock. \z + Then, sneak into Ashta'daramai and exchange Gabel\'s sleeping lamp with Fa'hradin\'s lamp.", + [2] = "You successfully exchanged the lamps. Malor will be happy to hear about this.", + [3] = "The Efreet are very satisfied with your help. King Malor allowed you to trade with Yaman and Alesar." + } + } + } + }, + [21] = { + name = "The Djinn War - Marid Faction", + startStorageId = Storage.DjinnWar.MaridFaction.Start, + startStorageValue = 1, + missions = { + [1] = { + name = "Marid Mission 1: The Dwarven Kitchen", + storageId = Storage.DjinnWar.MaridFaction.Mission01, + missionId = 10224, + startValue = 1, + endValue = 2, + states = { + [1] = "Bring a cookbook of the dwarven kitchen to Bo'ques.", + [2] = "You have delivered the cookbook. \z + Bo'ques seemed very satisfied and told you that Fa'hradin might have another mission for you." + } + }, + [2] = { + name = "Marid Mission 2: The Spyreport", + storageId = Storage.DjinnWar.MaridFaction.Mission02, + missionId = 10225, + startValue = 1, + endValue = 2, + states = { + [1] = "Fa'hradin asked you to sneak into the Efreet fortress Mal'ouqhah and find their undercover spy. \z + The codeword is PIEDPIPER.", + [2] = "You have delivered the spyreport. \z + Fa'hradin seemed impressed and told you that Gabel himself might have another mission for you." + } + }, + [3] = { + name = "Rata'Mari and the Cheese", + storageId = Storage.DjinnWar.MaridFaction.RataMari, + missionId = 10226, + startValue = 1, + endValue = 2, + states = { + [1] = "You have promised Rata'Mari cheese. Once you deliver some to him, he will hand over his spyreport.", + [2] = "You got Rata'Mari\'s spyreport. He seems to be quite happy with the cheese you brought him." + } + }, + [4] = { + name = "Marid Mission 3: The Sleeping Lamp", + storageId = Storage.DjinnWar.MaridFaction.Mission03, + missionId = 10227, + startValue = 1, + endValue = 3, + states = { + [1] = "Gabel asked you to find Fa'hradin\'s sleeping lamp in the orc fortress at Ulderek\'s Rock. \z + Then, sneak into Mal'ouqhah and exchange Malor\'s sleeping lamp with Fa'hradin\'s lamp.", + [2] = "You successfully exchanged the lamps. Gabel will be happy to hear about this.", + [3] = "The Marid deeply appreciate your help. King Gabel allowed you to trade with Haroun and Nah'bob." + } + } + } + }, + [22] = { + name = "The Hidden City of Beregar", + startStorageId = Storage.HiddenCityOfBeregar.DefaultStart, + startStorageValue = 1, + missions = { + [1] = { + name = "Going Down", + storageId = Storage.HiddenCityOfBeregar.GoingDown, + missionId = 10228, + startValue = 1, + endValue = 2, + states = { + [1] = "Deliver 3 Gear Wheels to Xorlosh.", + [2] = "You sucessfully helped Xorlosh in repairing the elevator. \z + You can now enter the teleporter to the eastern part of the mine." + } + }, + [2] = { + name = "Justice for All", + storageId = Storage.HiddenCityOfBeregar.JusticeForAll, + missionId = 10229, + startValue = 1, + endValue = 6, + states = { + [1] = "Nokmir told you that he is falsely accused of being a thief. \z + You could help him by talking to Grombur about the case. \z + Furthermore you should try to find that ring which belongs to Rerun.", + [2] = "You should talking to Grombur about Nokmir.", + [3] = "You should try to find that ring which belongs to Rerun everywhere in the mine.", + [4] = "You have found Rerun\'s ring. Bring the ring to the emperor Rehal and talk to him about Nokmir.", + [5] = "You informed emperor Rehal about your recent discoveries and he acquitted Nokmir of being a thief.", + [6] = "You told Nokmir about his acquittal and he granted you access to the northern mine." + } + }, + [3] = { + name = "Pythius the Rotten", + storageId = Storage.QuestChests.FirewalkerBoots, + missionId = 10230, + startValue = 1, + endValue = 1, + states = { + [1] = "You won the battle against the malicious undead dragon Pythius the Rotten. \z + He granted you firewalker boots as a reward." + } + }, + [4] = { + name = "Sweet as Chocolate Cake", + storageId = Storage.HiddenCityOfBeregar.SweetAsChocolateCake, + missionId = 10231, + startValue = 1, + endValue = 3, + states = { + [1] = "Bake a Chocolate Cake and bring it to Bolfona at the bar.", + [2] = "Report back to Frafnar by telling him about the mission.", + [3] = "You told Frafnar that you did everything he asked you to do. \z + You may now enter the western part of the mine." + } + }, + [5] = { + name = "The Good Guard", + storageId = Storage.HiddenCityOfBeregar.TheGoodGuard, + missionId = 10232, + startValue = 1, + endValue = 2, + states = { + [1] = "Grombur asked you to get him a cask of dwarven brown ale. \z + You heard that Boozer in Venore tried to brew some. Maybe you should pay him a visit.", + [2] = "Grombur liked the ale and you are now allowed to enter his part of the mine." + } + } + } + }, + [23] = { + name = "The Ice Islands Quest", + startStorageId = Storage.TheIceIslands.Questline, + startStorageValue = 1, + missions = { + [1] = { + name = "Befriending the Musher", + storageId = Storage.TheIceIslands.Mission01, + missionId = 10233, + startValue = 1, + endValue = 3, + states = { + [1] = "Find Sniffler the husky of Iskan. He should be somewhere north west of the town. \z + He is probably marking his territory so you should be able to find his trace. \z + Call him sniffler and feed him with meat.", + [2] = "Tell Iskan that you found and feed Sniffler", + [3] = "You are now a friend of Iskan and can ask him for a passage to Nibelor. \z + You should ask Hjaern in Nibelor if you can help him." + } + }, + [2] = { + name = "Nibelor 1: Breaking the Ice", + storageId = Storage.TheIceIslands.Mission02, + missionId = 10234, + startValue = 1, + endValue = 5, + states = { + [1] = "Chakoyas may use the ice for a passage to the west and attack Svargrond. Use the rocks at east \z + of nibelor on at least three of these places and the chakoyas probably won't be able to pass the ice.", + [2] = "You have broke 1 of 3 icepassages", + [3] = "You have broke 2 of 3 icepassages", + [4] = "You have broke 3 of 3 icepassages! Tell Hjaern your mission!", + [5] = "You should ask Silfind if you can help her in some matters." + } + }, + [3] = { + name = "Nibelor 2: Ecological Terrorism", + storageId = Storage.TheIceIslands.Mission03, + missionId = 10235, + startValue = 1, + endValue = 3, + states = { + [1] = "Siflind send you to travel to a distant land to get ants from an Ant-Hill to \z + perform ecological terrorism on some pirates on Tyrsung. Just use the jug on an anthill.", + [2] = "Now head back to Svargrond and go to Buddel, the drunk sailor in southern Svargrond, \z + and ask him to take you to Tyrsung. Now go all the way to the southern shores \z + where you find a outpost. Go to the bottom deck and use the jug with the western mast", + [3] = "Go tell Siflind that you released the ants and aks her for mission!" + } + }, + [4] = { + name = "Nibelor 3: Artful Sabotage", + storageId = Storage.TheIceIslands.Mission04, + missionId = 10236, + startValue = 1, + endValue = 2, + states = { + [1] = "Siflind gave you a Vial of Paint to use on some Baby Seals. \z + Go back to Tyrsung and follow the shore from Buddel south. Use the Vial of Paint on three of these seals.", + [2] = "Go tell Siflind that you painted the seals and aks her for mission!" + } + }, + [5] = { + name = "Nibelor 4: Berserk Brewery", + storageId = Storage.TheIceIslands.Mission05, + missionId = 10237, + startValue = 1, + endValue = 6, + states = { + [1] = "The first things needed are 5 bat wings to brew a berserker elixir. Bring her them!", + [2] = "The next items Siflind need are 4 bear paws. Bring her them!", + [3] = "The next items Siflind need are 3 bonelord eyes. Bring her them!", + [4] = "The next items Siflind need are 2 fish fins. Bring her them!", + [5] = "The next item Siflind need is a green dragon scale. Bring her that!", + [6] = "You helped Siflind to defend Svargrond. Now Nilsor need help, go ask him for mission." + } + }, + [6] = { + name = "Nibelor 5: Cure the Dogs", + storageId = Storage.TheIceIslands.Mission06, + missionId = 10238, + startValue = 1, + endValue = 8, + states = { + [1] = "To cure Nilsor dogs, bring him the 1st of 7 ingredients: a Part of the Sun Adorer Cactus. \z + Only an ordinary kitchen knife will be precise enough to produce the ingredient weneed.", + [2] = "To cure Nilsor dogs, bring him the 2nd of 7 ingredients: Geyser Water in a Waterskin. \z + Use it on a geyser that is NOT active. The water of active geysers is far too hot.", + [3] = "To cure Nilsor dogs, bring him the 3rd of 7 ingredients: Fine Sulphur. \z + Use an ordinary kitchen spoon on an inactive lava hole.", + [4] = "To cure Nilsor dogs, bring him the 4th of 7 ingredients: the Frostbite Herb. \z + You can find it on mountain peaks. You will need to cut it with a fine kitchen knife.", + [5] = "To cure Nilsor dogs, bring him the 5th of 7 ingredients: Purple Kiss Blossom. \z + The purple kiss is a plant that grows in a place called jungle. \z + You will have to use a kitchen knife to harvest its blossom.", + [6] = "To cure Nilsor dogs, bring him the 6th of 7 ingredients: the Hydra Tongue. \z + The hydra tongue is a common pest plant in warmer regions. You might find one in a shop.", + [7] = "To cure Nilsor dogs, bring him the 7th of 7 ingredients: Spores of a Giant Glimmercap Mushroom. \z + The giant glimmercap mushroom exists in caves and other preferably warm and humid places. \z + Use an ordinary kitchen spoon on a mushroom to collectits spores.", + [8] = "You found all ingredients to cure Nilsor dogs, ask him for mission. \z + You can now travel by Dog Sleds to Inukaya." + } + }, + [7] = { + name = "The Secret of Helheim", + storageId = Storage.TheIceIslands.Mission07, + missionId = 10239, + startValue = 1, + endValue = 3, + states = { + [1] = "Hjaern might have a mission for you. So maybe you go and talk to him.", + [2] = "Hjaern send you to find someone in Svargrond who can give you a passage to \z + Helheim and seek the reason for the unrest there.", + [3] = "You discovered the necromantic altar and should report Hjaern about it." + } + }, + [8] = { + name = "The Contact", + storageId = Storage.TheIceIslands.Mission08, + missionId = 10240, + startValue = 1, + endValue = 4, + states = { + [1] = "Get out of Nibelor and go to the Svargrond Explorer\'s Society. Ask Lurik for the mission.", + [2] = "Get to the raider camp, then follow to the extreme south where you find lots of barbarians. \z + Near the southern most coastline, try looking for the NPC Nor. Ask him about Memory Crystal.", + [3] = "Go back to Lurik and deliver him the memory crystal.", + [4] = "Give Lurik some time to evaluate the information (ca. 5min). \z + Then talk to him again about your mission." + } + }, + [9] = { + name = "Formorgar Mines 1: The Mission", + storageId = Storage.TheIceIslands.Mission09, + missionId = 10241, + startValue = 1, + endValue = 2, + states = { + [1] = "Find the entrance of the Formorgar Mines. \z + Find some hint or someone who is willing to talk about what is going on there.", + [2] = "You found a old and tattered written paper in a skeleton next to a Restless Soul, \z + you can only make out a signature: Tylaf, apprentice of Hjaern. Ask Hjaern about Tylaf." + } + }, + [10] = { + name = "Formorgar Mines 2: Ghostwhisperer", + storageId = Storage.TheIceIslands.Mission10, + missionId = 10242, + startValue = 1, + endValue = 2, + states = { + [1] = "Go back to the mine and ask the restless soul about his story.", + [2] = "You already have listen to his story!" + } + }, + [11] = { + name = "Formorgar Mines 3: The Secret", + storageId = Storage.TheIceIslands.Mission11, + missionId = 10243, + startValue = 1, + endValue = 2, + states = { + [1] = "The Cultists plan is to create a new demon army for their master to conquer the world. \z + Hjaern and the other shamans must learn about it! Hurry before its too late.", + [2] = "The Cultists plan is to create a new demon army for their master to conquer the world. \z + Hjaern and the other shamans are already informed!" + } + }, + [12] = { + name = "Formorgar Mines 4: Retaliation", + storageId = Storage.TheIceIslands.Mission12, + missionId = 10244, + startValue = 1, + endValue = 6, + states = { + [1] = "Hjaern gave you a spirit charm of cold. Travel to the mines and find four \z + special obelisks to mark them with the charm.", + [2] = "1 of 4 obelisks are marked.", + [3] = "2 of 4 obelisks are marked.", + [4] = "3 of 4 obelisks are marked.", + [5] = "Once all 4 obelisks are marked report back to Hjaern.", + [6] = "You got the Norseman outfit and you have access to the Yakchal room deep in the Formorgar Mines." + } + } + } + }, + [24] = { + name = "The Inquisition", + startStorageId = Storage.TheInquisition.Questline, + startStorageValue = 2, + missions = { + [1] = { + name = "Mission 1: Interrogation", + storageId = Storage.TheInquisition.Mission01, + missionId = 10245, + startValue = 1, + endValue = 7, + states = { + [1] = "Your mission is to investigate the 5 guards in Thais regarding the Heretic behavior. \z + Tim, Kulag, Grof, Miles and Walter are their names. If you do well you see a holy sprite on you.", + [2] = "You investigated 1 of 5 guards in Thais.", + [3] = "You investigated 2 of 5 guards in Thais.", + [4] = "You investigated 3 of 5 guards in Thais.", + [5] = "You investigated 4 of 5 guards in Thais.", + [6] = "You investigated 5 of 5 guards in Thais. Get back to Thais and report your mission to Henricus.", + [7] = "You investigated all guards in Thais." + } + }, + [2] = { + name = "Mission 2: Eclipse", + storageId = Storage.TheInquisition.Mission02, + missionId = 10246, + startValue = 1, + endValue = 3, + states = { + [1] = "Henricus tells you to get The Witches' Grimoire, he sends you to Femor Hills where you \z + can fly to the witches' mountain, say Eclipse to Uzon and he will take you there. \z + Use the vial of holy water that he gives you on the big cauldron and open the chest to your left, \z + then bring the witches' grimoire to Henricus.", + [2] = "Find the witches' grimoire and bring it to Henricus.", + [3] = "You already brought the witches' grimoire to Henricus." + } + }, + [3] = { + name = "Mission 3: Vampire Hunt", + storageId = Storage.TheInquisition.Mission03, + missionId = 10247, + startValue = 1, + endValue = 6, + states = { + [1] = "Henricus wants you to find the Dwarfish Vampire Hunter, Storkus, located west of the Dwarf Bridge. \z + It\'s good idea bring your 20 Vampire Dusts with you to save some time.", + [2] = "Go Back to Storkus the Dwarf and ask for Mission.", + [3] = "Now Storkus wants you to kill a vampire lord, The Count in the Green Claw Swamp, \z + The Count is located near to the Blood Herb Quest. To summon The Count, \z + you must use the coffin in the center of the room. Kill it and bring The Ring of the Count to Storkus.", + [4] = "Kill The Count and bring his ring to Storkus the Dwarf and ask for Mission.", + [5] = "Return to Henricus and tell him that you finished your job here.", + [6] = "Get back to Thais and report your mission to Henricus." + } + }, + [4] = { + name = "Mission 4: The Haunted Ruin", + storageId = Storage.TheInquisition.Mission04, + missionId = 10248, + startValue = 1, + endValue = 3, + states = { + [1] = "Henricus will gave you a Special Flask (vial of holy water). Go to Liberty Bay \z + and use the vial on an old house. Use this vial of holy water on that spot to drive out the evil being.", + [2] = "Kill the Pirate Ghost and get back to Thais and report your mission to Henricus.", + [3] = "You already cleaned the abandoned and haunted house in Liberty, ask Henricus for mission." + } + }, + [5] = { + name = "Mission 5: Essential Gathering", + storageId = Storage.TheInquisition.Mission05, + missionId = 10249, + startValue = 1, + endValue = 3, + states = { + [1] = "Henricus wants 20 Demonic Essences as a proof of your accomplishments.", + [2] = "Now ask Henricus for outfit to get the Demon Hunter Outfit.", + [3] = "You got the Demon Hunter Outfit! Ask Henricus for mission to unlock more addons." + } + }, + [6] = { + name = "Mission 6: The Demon Ungreez", + storageId = Storage.TheInquisition.Mission06, + missionId = 10250, + startValue = 1, + endValue = 3, + states = { + [1] = "Henricus wants you to kill a demon called Ungreez. Head to Edron Hero Cave and go down a few levels.", + [2] = "You killed Ungreez, report your mission to Henricus.", + [3] = "You got the the first addon of Demon Hunter Outfit! Ask Henricus for mission to unlock more addons." + } + }, + [7] = { + name = "Mission 7: The Shadow Nexus", + storageId = Storage.TheInquisition.Mission07, + missionId = 10251, + startValue = 1, + endValue = 5, + states = { + [1] = "Your mission is to go to the Demon Forge and slay seven of The Ruthless Seven Minions. \z + The Demon Forge is located in the Edron Hero Cave, through a portal after the Vampire Shield Quest.", + [2] = "You destroyed the shadow nexus! Get back to Thais and report your mission to Henricus.", + [3] = "Now ask to Henricus for a outfit. He will give you the 2nd addon of the Demon Hunter Outfits.", + [4] = "You got the the second addon of Demon Hunter Outfit! Go now to the reward room and choose one wisely!", + [5] = "You have completed The Inquisition Quest! You can now buy the Blessing of the Inquisition!" + } + } + } + }, + [25] = { + name = "The New Frontier", + startStorageId = Storage.TheNewFrontier.Questline, + startStorageValue = 1, + missions = { + [1] = { + name = "Mission 01: New Land", + storageId = Storage.TheNewFrontier.Mission01, + missionId = 10252, + startValue = 1, + endValue = 3, + states = { + [1] = "Ongulf sends you to explore the passage to the east of farmine.", + [2] = "You have found the passage through the mountains and can report Ongulf about your success.", + [3] = "You already reported Ongulf your success! Ask Ongulf for new mission!" + } + }, + [2] = { + name = "Mission 02: From Kazordoon With Love", + storageId = Storage.TheNewFrontier.Mission02, + missionId = 10253, + startValue = 1, + endValue = 6, + states = { + [1] = "Ongulf will tell you that he needs to send a message to the dwarves in Kazordoon. \z + Travel there and then walk to the Dwarf Mines to the west. Cross the two rivers and find Melfar.", + [2] = "Melfar gave you a Flask with Beaver Bait that you must use on the 3 \z + trees(Trees will be marked on your map).", + [3] = "You marked 1 of 3 trees with Beaver Bait in near the Dwarf Mines", + [4] = "You marked 2 of 3 trees with Beaver Bait in near the Dwarf Mines", + [5] = "You marked all 3 trees with Beaver Bait in near the Dwarf Mines. \z + Return to talk to Melfar before heading back to Farmine.", + [6] = "Return to Ongulf and report your mission!" + } + }, + [3] = { + name = "Mission 03: Strangers in the Night", + storageId = Storage.TheNewFrontier.Mission03, + missionId = 10254, + startValue = 1, + endValue = 3, + states = { + [1] = "You need to find the tribe which lives in the mountains. \z + Find some vines in this mountain, climb up there and find out who is spying on us!", + [2] = "Return to Ongulf and report your mission about primitive humans.", + [3] = "You already reported Ongulf about primitive humans! Ask Ongulf for new mission!" + } + }, + [4] = { + name = "Mission 04: The Mine Is Mine", + storageId = Storage.TheNewFrontier.Mission04, + missionId = 10255, + startValue = 1, + endValue = 2, + states = { + [1] = "Head back to the levers and this time use the left one. \z + Go North through the tunnel of Stone Golems. Kill the boss, Shard of Corruption at the end of the tunnel.", + [2] = "You killed the Shard of Corruption. Return to Ongulf and report your mission!" + } + }, + [5] = { + name = "Mission 05: Getting Things Busy", + storageId = Storage.TheNewFrontier.Mission05, + missionId = 10256, + startValue = 1, + endValue = 7, + states = { + [1] = "This mission consists of getting support from 6 people (King Tibianus in Thais, Leeland in Venore, \z + Angus in Port Hope, Wyrdin in the Ivory Towers, Telas in Edron, Humgolf in Kazordoon around Tibia. \z + You need to ask for farmine and then you either need to Flatter, Threaten, Impress, Bluff, Reason or Plea him!", + [2] = "You got support from 1 of 6 people, King Tibianus in Thais, Leeland in Venore, Angus in Port Hope, \z + Wyrdin in the Ivory Towers, Telas in Edron and Humgolf in Kazordoon. \z + You need to ask for farmine and then you either need to Flatter, Threaten, Impress, Bluff, Reason or Plea him!", + [3] = "You got support from 2 of 6 people, King Tibianus in Thais, Leeland in Venore, Angus in Port Hope, \z + Wyrdin in the Ivory Towers, Telas in Edron and Humgolf in Kazordoon. \z + You need to ask for farmine and then you either need to Flatter, Threaten, Impress, Bluff, Reason or Plea him!", + [4] = "You got support from 3 of 6 people, King Tibianus in Thais, Leeland in Venore, Angus in Port Hope, \z + Wyrdin in the Ivory Towers, Telas in Edron and Humgolf in Kazordoon. \z + You need to ask for farmine and then you either need to Flatter, Threaten, Impress, Bluff, Reason or Plea him!", + [5] = "You got support from 4 of 6 people, King Tibianus in Thais, Leeland in Venore, Angus in Port Hope, \z + Wyrdin in the Ivory Towers, Telas in Edron and Humgolf in Kazordoon. \z + You need to ask for farmine and then you either need to Flatter, Threaten, Impress, Bluff, Reason or Plea him!", + [6] = "You got support from 5 of 6 people, King Tibianus in Thais, Leeland in Venore, Angus in Port Hope, \z + Wyrdin in the Ivory Towers, Telas in Edron and Humgolf in Kazordoon. \z + You need to ask for farmine and then you either need to Flatter, Threaten, Impress, Bluff, Reason or Plea him!", + [7] = "You got support from all needed people to help farmine! Return to Ongulf and report your mission!" + } + }, + [6] = { + name = "Mission 06: Days Of Doom", + storageId = Storage.TheNewFrontier.Mission06, + missionId = 10257, + startValue = 1, + endValue = 3, + states = { + [1] = "Go to Curos, leader of the Orcs, in the middle of the Zao Steppe in the north-east area of an Orc camp. \z + Ask for a mission and accept it.", + [2] = "Enter the ring of battle, close to Curos quarter. \z + Face Mooh'Tah Master in a battle and survive for two minutes. Return to him after you have passed this test.", + [3] = "You passed the test of Curos. Return to Ongulf and report your mission!" + } + }, + [7] = { + name = "Mission 07: Messengers Of Peace", + storageId = Storage.TheNewFrontier.Mission07, + missionId = 10258, + startValue = 1, + endValue = 3, + states = { + [1] = "You now have to contact the Lizards, the real rulers of Zao. \z + Find them, contact them, talk to them, scare them, bribe them, whatever.", + [2] = "You have been trapped! Find a way out!", + [3] = "You found the Lizards!" + } + }, + [8] = { + name = "Mission 08: An Offer You Can't Refuse", + storageId = Storage.TheNewFrontier.Mission08, + missionId = 10259, + startValue = 1, + endValue = 2, + states = { + [1] = "Take the boat at the northern of Dragonblaze Peaks to tournament Isle. \z + Ask Zurak for a passage. There you'll learn anything you need to know about the great tournament. \z + Ask there Chrak for the battle.", + [2] = "You agreed the Offer." + } + }, + [9] = { + name = "Mission 09: Mortal Combat", + storageId = Storage.TheNewFrontier.Mission09, + missionId = 10260, + startValue = 1, + endValue = 3, + states = { + [1] = "You have to go into the Arena with another player, \z + because 2 players are needed, at the same time, to enter. Choose your companion wisely!", + [2] = "You have won! Report Chrak your mission about the battle.", + [3] = "Go back to Farmine and talk to Ongulf about your mission." + } + }, + [10] = { + name = "Mission 10: New Horizons", + storageId = Storage.TheNewFrontier.Mission10, + missionId = 10261, + startValue = 1, + endValue = 1, + description = "You now have permission to use the Magic Carpet on the mountain above Farmine, \z + Cael now accepts more Tomes of Knowledge from you and you got the Warmaster Outfit!" + }, + [11] = { + name = "Tome of Knowledge Counter", + storageId = Storage.TheNewFrontier.TomeofKnowledge, + missionId = 10262, + startValue = 1, + endValue = 12, + states = { + [1] = "You brought the fist Tome of Knowledge to Cael. He learnt more about the lizard culture. \z + Pompan will sell you dragon tapestries from now on.", + [2] = "You brought the second Tome of Knowledge to Cael. He learnt more about the minotaur culture. \z + Pompan will sell you minotaur backpacks from now on.", + [3] = "You brought the third Tome of Knowledge to Cael. \z + He learnt more about the last stand of the draken culture. Esrik will sell you lizard weapon rack from now on.", + [4] = "You brought the fourth Tome of Knowledge to Cael. \z + He learnt something interesting about a certain food that the lizardmen apparently prepare. \z + Swolt will trade you a bunch of ripe rice for 10 rice balls from now on.", + [5] = "You brought the fifth Tome of Knowledge to Cael. \z + He learnt more about the last stand of the lizards in the South, Zzaion. \z + Pompan will sell you lizard backpacks from now on.", + [6] = "You brought the sixth Tome of Knowledge to Cael. \z + He learnt a few things about the primitive human culture on this continent. \z + Cael will sell you War Drums and Didgeridoo from now on.", + [7] = "You brought the seventh Tome of Knowledge to Cael. \z + He learnt something interesting about the Zao steppe. \z + Now you to use the snake teleport at the peak of the mountain.", + [8] = "You brought the eighth Tome of Knowledge to Cael. \z + He learnt a few things about an illness. \z + Now you can enter a corruption hole in the north-eastern end of Zao.", + [9] = "You brought the ninth Tome of Knowledge to Cael. \z + He learnt something interesting about the Draken origin. \z + Esrik will buy lizard equipment from you now.", + [10] = "You brought the tenth Tome of Knowledge to Cael. \z + He learnt more about the last stand of the lizard dynasty. \z + Now you can enter the Zao Palace. It is situated deep underground, below the mountain base of the Lizards.", + [11] = "You brought the eleventh Tome of Knowledge to Cael. \z + He learnt something interesting about dragons and their symbolism. \z + You can buy a Dragon Statue from NPC Cael after you bring him a Red Lantern.", + [12] = "You brought the twelfth Tome of Knowledge to Cael. \z + He learnt something about reveals some of the power structures in Zao. \z + Cael will now make a Dragon Throne for you after you bring him a Red Piece of Cloth. \z + He will reward you with 5000 experience points for each extra tome you give to him." + } + } + } + }, + [26] = { + name = "The Postman Missions", + startStorageId = Storage.Postman.Mission01, + startStorageValue = 1, + missions = { + [1] = { + name = "Mission 01 - Check Postal Routes", + storageId = Storage.Postman.Mission01, + missionId = 10263, + startValue = 1, + endValue = 6, + states = { + [1] = "Kevin wants you to travel with Captain Bluebear to Carlin.", + [2] = "Kevin wants you to travel with Uzon in Femor Hills to Edron.", + [3] = "Kevin wants you to travel with Captain Seahorse to Venore.", + [4] = "Kevin wants you to travel with Brodrosch to Cormaya", + [5] = "You have checked the Postal Routes, report back to Kevin!", + [6] = "You have reported back that you have completed the mission." + } + }, + [2] = { + name = "Mission 02 - Fix Mailbox", + storageId = Storage.Postman.Mission02, + missionId = 10264, + startValue = 1, + endValue = 3, + states = { + [1] = "Kevin wants you to fix one of their Mailboxes located on Folda with a crowbar.", + [2] = "You have fixed the mailbox, report back to Kevin!", + [3] = "You have reported back that you have completed the mission." + } + }, + [3] = { + name = "Mission 03 - Bill Delivery", + storageId = Storage.Postman.Mission03, + missionId = 10265, + startValue = 1, + endValue = 3, + states = { + [1] = "Kevin wants you to deliver a bill to the stage magician David Brassacres. \z + He\'s hiding from his creditors somewhere in Venore.", + [2] = "You have delivered the bill to the stage magician David Brassacres, report back to Kevin!", + [3] = "You have reported back that you have completed the mission." + } + }, + [4] = { + name = "Mission 04 - Aggressive Dogs", + storageId = Storage.Postman.Mission04, + missionId = 10266, + startValue = 1, + endValue = 2, + states = { + [1] = "Kevin has asked you to deliver 20 Bones to him.", + [2] = "You have delivered 20 Bones to Kevin." + } + }, + [5] = { + name = "Mission 05 - Present Delivery", + storageId = Storage.Postman.Mission05, + missionId = 10267, + startValue = 1, + endValue = 4, + states = { + [1] = "Kevin has asked you to retrieve the present behind the door on the \z + lower right side of his room and deliver it to Dermot in Fibula.", + [2] = "Deliver the present to Dermot in Fibula.", + [3] = "You have delivered the present to Dermot, report back to Kevin!", + [4] = "You have reported back that you have completed the mission." + } + }, + [6] = { + name = "Mission 06 - New Uniforms", + storageId = Storage.Postman.Mission06, + missionId = 10268, + startValue = 1, + endValue = 13, + states = { + [1] = "Kevin has asked you to travel to Venore and negotiate with Hugo for new uniforms.", + [2] = "Hugo said that his dog ate the last dress pattern they used and he \z + has no clue where Kevin Postner got it from, go ask Kevin.", + [3] = "Kevin wants you to ask the great Technomancer Talphion in Kazordoon for the technical details.", + [4] = "Talphion will send a copy to Kevin, report back to Kevin.", + [5] = "Kevin wants you to ask Queen Eloise of Carlin for the perfect colours.", + [6] = "Queen Eloise said she will send some color samples via mail to Kevin, report back to Kevin.", + [7] = "Kevin has asked you to go to Noodles and find out what he dislikes the most: \z + mouldy cheese, a piece of fur or a banana skin.", + [8] = "Noodles seems to like banana skin, check if he likes dirty fur.", + [9] = "Noodles seems to like dirty fur, check if he likes mouldy cheese.", + [10] = "Noodles dislikes mouldy cheese! Report back to Kevin.", + [11] = "Kevin wants you to tell Hugo that they order those uniforms.", + [12] = "Hugo has agreed to make the uniforms, report back to Kevin!", + [13] = "You have reported back that you have completed the mission." + } + }, + [7] = { + name = "Mission 07 - Measurements", + storageId = Storage.Postman.Mission07, + missionId = 10269, + startValue = 1, + endValue = 8, + states = { + [1] = "Kevin wants you to bring him the measurements of Benjamin, Lokur, Dove, Liane, Chrystal and Olrik.", + [2] = "You have received the measurements from 1 of 6 post officers.", + [3] = "You have received the measurements from 2 of 6 post officers.", + [4] = "You have received the measurements from 3 of 6 post officers.", + [5] = "You have received the measurements from 4 of 6 post officers.", + [6] = "You have received the measurements from 5 of 6 post officers.", + [7] = "You have received all measurements, report back to Kevin!", + [8] = "You have reported back that you have completed the mission." + } + }, + [8] = { + name = "Mission 08 - Missing Courier", + storageId = Storage.Postman.Mission08, + missionId = 10270, + startValue = 1, + endValue = 3, + states = { + [1] = "Kevin wants you to find the missing courier Waldo or at least his posthorn.", + [2] = "You have found Waldos posthorn.", + [3] = "You have reported back that you have completed the mission." + } + }, + [9] = { + name = "Mission 09 - Dear Santa", + storageId = Storage.Postman.Mission09, + missionId = 10271, + startValue = 1, + endValue = 4, + states = { + [1] = "Kevin wants you to deliver som letters to Santa Claus on Vega.", + [2] = "You have retrieved the letters, deliver them to Santa Claus on Vega.", + [3] = "You have delivered the letters to Santa Claus on Vega.", + [4] = "You have reported back that you have completed the mission." + } + }, + [10] = { + name = "Mission 10 - Mintwallin", + storageId = Storage.Postman.Mission10, + missionId = 10272, + startValue = 1, + endValue = 3, + states = { + [1] = "Kevin wants you to deliver a letter to Markwin, king of Mintwallin from his mother.", + [2] = "You have delivered the letter to Markwin.", + [3] = "You have reported back that you have completed the mission." + } + }, + [11] = { + name = "Postman Rank", + storageId = Storage.Postman.Rank, + missionId = 10273, + startValue = 1, + endValue = 5, + states = { + [1] = "Assistant Postman", + [2] = "Postman", + [3] = "Grand Postman", + [4] = "Grand Postman for Special Operations", + [5] = "Arch Postman" + } + } + } + }, + [27] = { + name = "The Shattered Isles", + startStorageId = Storage.TheShatteredIsles.DefaultStart, + startStorageValue = 1, + missions = { + [1] = { + name = "A Djinn in Love", + storageId = Storage.TheShatteredIsles.ADjinnInLove, + missionId = 10274, + startValue = 1, + endValue = 5, + states = { + [1] = "You need to return to Marina and ask her for a date with Ocelus.", + [2] = "You need to return to Ocelus with the bad news.", + [3] = "Ocelus told you to get a poem for him, if you didn't buy one already, \z + head to Ab'Dendriel and buy a Love Poem from Elvith.", + [4] = "You need to go recite the poem to Marina and impress her \z + with the Djinn\'s romantic and poetic abilities.", + [5] = "After reciting the poem to Marina, she decided to date Ocelus and release Ray Striker from her spell." + } + }, + [2] = { + name = "A Poem for the Mermaid", + storageId = Storage.TheShatteredIsles.APoemForTheMermaid, + missionId = 10275, + startValue = 1, + endValue = 3, + states = { + [1] = "You need to find the man-stealing mermaid and try to break her spell over poor Raymond, \z + the mermaid Marina is near the northern coast of the island.", + [2] = "You discovered that she does in fact have a spell on him, and will not release him unless \z + someone better comes along.", + [3] = "You are a true master in reciting love poems now. \z + No mermaid will be able to resist if you ask for a date!" + } + }, + [3] = { + name = "Access to Goroma", + storageId = Storage.TheShatteredIsles.AccessToGoroma, + missionId = 10276, + startValue = 1, + endValue = 1, + description = "After helping Jack Fate to collect the 30 woodpieces, \z + Jack Fate in Liberty Bay will bring you to Goroma." + }, + [4] = { + name = "Access to Laguna Island", + storageId = Storage.TheShatteredIsles.AccessToLagunaIsland, + missionId = 10277, + startValue = 1, + endValue = 1, + description = "After arranging a date for Marina and Ocelus, you are allowed to use Marina\'s sea turtles. \z + They will bring you to the idyllic Laguna Islands." + }, + [5] = { + name = "Access to Meriana", + storageId = Storage.TheShatteredIsles.AccessToMeriana, + missionId = 10278, + startValue = 1, + endValue = 1, + description = "After earning the trust of the governor\'s daughter Eleonore, \z + Captain Waverider in Liberty Bay will bring you to Meriana if you tell him the secret codeword 'peg leg'." + }, + [6] = { + name = "Access to Nargor", + storageId = Storage.TheShatteredIsles.AccessToNargor, + missionId = 10279, + startValue = 1, + endValue = 1, + description = "After convincing the people in Sabrehaven that you are a trustworthy hero, \z + Sebastian will sail you to Nargor." + }, + [7] = { + name = "Ray\'s Mission 1: Fafnar\'s Fire", + storageId = Storage.TheShatteredIsles.RaysMission1, + missionId = 10280, + startValue = 1, + endValue = 3, + states = { + [1] = "Ray Striker asked you to travel to Edron and pretend to the alchemist Sandra that you are the one \z + whom the other pirates sent to get the fire. When she asks for a payment, tell her \z + 'Your continued existence is payment enough'.", + [2] = "Sandra will be enraged and will cut any deals with pirates. Report back to Raymond Striker.", + [3] = "Ray Striker was pleased to hear about Sandra\'s rage. If you haven't done so yet, \z + ask him for other missions." + } + }, + [8] = { + name = "Ray\'s Mission 2: Sabotage", + storageId = Storage.TheShatteredIsles.RaysMission2, + missionId = 10281, + startValue = 1, + endValue = 3, + states = { + [1] = "Buy a fire bug at Liberty Bay and infiltrate Nargor. \z + Find the pirates' harbor and use the fire bug to sabotage their catapult there.", + [2] = "You were able to sabotage the catapult in the pirate\'s harbor. \z + Report back to Ray Striker to tell him about mission.", + [3] = "Ray Striker was pleased to hear about successful sabotage. \z + If you haven't done so yet, ask him for other missions." + } + }, + [9] = { + name = "Ray\'s Mission 3: Spy Mission", + storageId = Storage.TheShatteredIsles.RaysMission3, + missionId = 10282, + startValue = 1, + endValue = 2, + states = { + [1] = "Travel to Nargor and try to enter de pirate\'s tavern by deceiving the guard in front of it. \z + Read all the plans which you can find in the tavern and report back to Striker.", + [2] = "You studied all of the pirate\'s plans in their tavern which will give insight about their next strikes. \z + If you haven't done so yet, ask Ray for another mission." + } + }, + [10] = { + name = "Ray\'s Mission 4: Proof of Death", + storageId = Storage.TheShatteredIsles.RaysMission4, + missionId = 10283, + startValue = 1, + endValue = 5, + states = { + [1] = "Travel to Nargor and try to find out more about the mission Klaus offers. \z + He apparently wants the death of Ray Striker and your task is to convince him that Ray is dead.", + [2] = "Klaus told you to kill Ray Striker and bring him his lucky pillow as a proof. \z + Ray should be interested in hearing about this mission.", + [3] = "You informed Ray that Klaus needs his lucky pillow as proof of his death. \z + Ray gave it to you, now go convince Klaus that the mission is fulfilled and Ray is Dead!", + [4] = "Klaus belieaves that Ray Striker is dead and will celebrate a big party. \z + You should tell Ray about your successful mission.", + [5] = "Ray was very impressed to hear about your successful mission \z + and gave you a ship and a pirate outfit as reward." + } + }, + [11] = { + name = "Reputation in Sabrehaven: Suspicious", + storageId = Storage.TheShatteredIsles.ReputationInSabrehaven, + missionId = 10284, + startValue = 2, + endValue = 13, + states = { + [2] = "Ariella asked you for a few days of adequate supply. \z + Help her and improve your reputation in Sabrehaven.", + [3] = "You have finished one mission. Ask around in Sabrehaven and surroundings whether the \z + people there might have missions for you. This will improve your reputation and earn their trust.", + [4] = "Morgan asked you to deliver a letter safely to old Eremo on Cormaya. \z + Help him and improve your reputation in Sabrehaven.", + [5] = "You delivered the letter safely to old Eremo. Report back to Morgan and \z + improve your reputation in Sabrehaven.", + [6] = "You have finished two missions. Ask around in Sabrehaven and surroundings \z + whether the people there might have missions for you. This will improve your reputation and earn their trust.", + [7] = "Duncan requested an atlas of the explorers society. Help him and improve your reputation in Sabrehaven.", + [8] = "You have finished three missions. Ask around in Sabrehaven and surroundings whether the \z + people there might have missions for you. This will improve your reputation and earn their trust.", + [9] = "Chondur asked at least five pirate voodoo dolls to lift the curse. Help him and improve \z + your reputation in Sabrehaven.", + [10] = "You have finished four missions. Ask around in Sabrehaven and surroundings whether the \z + people there might have missions for you. This will improve your reputation and earn their trust.", + [11] = "Ariella asked you to bring a sample of whisper beer from a secret whisper bar in Carlin. \z + Help her and improve your reputation in Sabrehaven.", + [12] = "Take the sample of whisper beer to Ariella. Help her and improve your reputation in Sabrehaven." + } + }, + [12] = { + name = "Reputation in Sabrehaven: Friendly", + storageId = Storage.TheShatteredIsles.ReputationInSabrehaven, + missionId = 10285, + startValue = 14, + endValue = 17, + states = { + [14] = "You have finished five missions. People in Sabrehaven seem to start trusting you. \z + Maybe this is a good time for some more difficult missions.", + [15] = "You have finished six missions. People in Sabrehaven seem to start trusting you. \z + Maybe this is a good time for some more difficult missions.", + [16] = "You have finished seven missions. People in Sabrehaven seem to start trusting you. \z + Maybe this is a good time for some more difficult missions." + } + }, + [13] = { + name = "Reputation in Sabrehaven: Cordial", + storageId = Storage.TheShatteredIsles.ReputationInSabrehaven, + missionId = 10286, + startValue = 18, + endValue = 19, + description = "You have finished eight missions. \z + People in Sabrehaven seem to trust you, but there is still one last mission left." + }, + [14] = { + name = "Reputation in Sabrehaven: Loyal", + storageId = Storage.TheShatteredIsles.ReputationInSabrehaven, + missionId = 10287, + startValue = 20, + endValue = 22, + states = { + [20] = "You have finished nine missions. People in Sabrehaven are considering you as one of them.", + [21] = "You have finished all missions. \z + People in Sabrehaven are considering you as one of them and you earned their full trust." + } + }, + [15] = { + name = "The Counterspell", + storageId = Storage.TheShatteredIsles.TheCounterspell, + missionId = 10288, + startValue = 1, + endValue = 4, + states = { + [1] = "You have begun Chondur\'s ritual. Bring him a fresh dead chicken so that he can begin to \z + create a counterspell which will allow you to pass the magical barrier on Goroma.", + [2] = "You have begun Chondur\'s ritual. Bring him a fresh dead rat so that he can continue \z + creating a counterspell which will allow you to pass the magical barrier on Goroma.", + [3] = "You have begun Chondur\'s ritual. Bring him a fresh dead black sheep so that he can \z + complete his counterspell which will allow you to pass the magical barrier on Goroma.", + [4] = "You may pass the energy barrier on Goroma. The counterspell Chondur created for you \z + with his ritual will allow you to withstand the evil magic of the cultist." + } + }, + [16] = { + name = "The Errand", + storageId = Storage.TheShatteredIsles.TheErrand, + missionId = 10289, + startValue = 1, + endValue = 2, + states = { + [1] = "You told Eleonore to run a small errand. Deliver the 200 gold pieces she \z + gave to the herbalist Charlotta in the south-western part of Liberty Bay.", + [2] = "You delivered the gold to Charlotta. Return to Eleonore and tell her the secret password: peg leg" + } + }, + [17] = { + name = "The Governor\'s Daughter", + storageId = Storage.TheShatteredIsles.TheGovernorDaughter, + missionId = 10290, + startValue = 1, + endValue = 3, + states = { + [1] = "You promised to find Eleonore\'s lost ring. She told you that a parrot stole it from her \z + dressing table and flew to the nearby mountains. You might need a rake to retrieve the ring.", + [2] = "You found the ring. Return it to Eleonore.", + [3] = "You returned the ring to Eleonore." + } + } + } + }, + [28] = { + name = "The Thieves Guild", + startStorageId = Storage.ThievesGuild.Quest, + startStorageValue = 1, + missions = { + [1] = { + name = "Mission 1: Ivory Poaching", + storageId = Storage.ThievesGuild.Mission01, + missionId = 10291, + startValue = 1, + endValue = 2, + states = { + [1] = "Dorian wants you to collect 10 elephant tusks and deliver them to him.", + [2] = "You delivered the ten tusks to Dorian." + } + }, + [2] = { + name = "Mission 2: Burglary", + storageId = Storage.ThievesGuild.Mission02, + missionId = 10292, + startValue = 1, + endValue = 3, + states = { + [1] = "Dorian wants you to steal a vase from Sarina, the owner of Carlin\'s general store.", + [2] = "You have stolen the vase, report back to Dorian!", + [3] = "You have delivered the stolen vase to Dorian, ask him for a new mission!" + } + }, + [3] = { + name = "Mission 3: Invitation", + storageId = Storage.ThievesGuild.Mission03, + missionId = 10293, + startValue = 1, + endValue = 3, + states = { + [1] = "Your task is to somehow convince Oswald to hand you an invitation to the king\'s ball.", + [2] = "You have received the invitation to the King\'s ball, report back to Dorian!", + [3] = "You have delivered the invitation to Dorian, ask him for a new mission!" + } + }, + [4] = { + name = "Mission 4: Bridge Robbery", + storageId = Storage.ThievesGuild.Mission04, + missionId = 10294, + startValue = 1, + endValue = 8, + states = { + [1] = "Dorian wants you to find a forger in the outlaw camp, go talk to Snake eye.", + [2] = "Snake Eye told you to visit Ahmet in Ankrahmun.", + [3] = "Ahmet told you that he will only help a friend and asked you to kill at least one Nomad.", + [4] = "You have killed a Nomad, go back to Ahmet!", + [5] = "You have received the forged documents from Ahmet, next is to get a disguise from Percybald in Venore!", + [6] = "You have received the dwarf disguise from Percybald. Now go do the deal with Nurik.", + [7] = "You have traded the forged documents for the painting, report back to Dorian.", + [8] = "You have delivered the painting to Dorian, ask him for a new mission!" + } + }, + [5] = { + name = "Mission 5: Enforcing Debts", + storageId = Storage.ThievesGuild.Mission05, + missionId = 10295, + startValue = 1, + endValue = 2, + states = { + [1] = "Your mission is to travel to Tiquanda. Fina a hidden smuggler cave to the north of Port Hope \z + and try to retrieve the valuable goblet which Dorian is looking for. Once you got it, bring it to him.", + [2] = "You have delivered the golden goblet to Dorian, ask him for a new mission!" + } + }, + [6] = { + name = "Mission 6: Fishnapping", + storageId = Storage.ThievesGuild.Mission06, + missionId = 10296, + startValue = 1, + endValue = 4, + states = { + [1] = "Dorian wants you to fishnap Theodore Loveless' fish, first you need to get the key to his room. \z + Talk to Chantalle in Liberty Bay.", + [2] = "You have received the key for Theodore Loveless' room, time to fishnap his fish!", + [3] = "You have fishnapped Theodore Loveless' fish, deliver it to Dorian.", + [4] = "You have delivered the fish to Dorian, ask him for a new mission!" + } + }, + [7] = { + name = "Mission 7: Blackmail", + storageId = Storage.ThievesGuild.Mission07, + missionId = 10297, + startValue = 1, + endValue = 2, + states = { + [1] = "Your current task is to find compromising information about one of the \z + Venore city guards, no matter how. A good starting point might be in their barracks.", + [2] = "You have delivered the compromising letter to Dorian, ask him for a new mission!" + } + }, + [8] = { + name = "Mission 8: Message", + storageId = Storage.ThievesGuild.Mission08, + missionId = 10298, + startValue = 1, + endValue = 3, + states = { + [1] = "Dorian wants you to deliver a message to his competitors in the dark cathedral.", + [2] = "You have put up the message, report back to Dorian.", + [3] = "You have reported back that you have completed the mission, \z + Dorian now allows you to trade with Black Bert." + } + } + } + }, + [29] = { + name = "The Travelling Trader Quest", + startStorageId = Storage.TravellingTrader.Mission01, + startStorageValue = 1, + missions = { + [1] = { + name = "Mission 1: Trophy", + storageId = Storage.TravellingTrader.Mission01, + missionId = 10299, + startValue = 1, + endValue = 2, + states = { + [1] = "Your first mission for becoming a recognized trader is to bring the \z + traveling salesman Rashid a Deer Trophy.", + [2] = "You have completed this mission. Talk with Rashid to continue." + } + }, + [2] = { + name = "Mission 2: Delivery", + storageId = Storage.TravellingTrader.Mission02, + missionId = 10300, + startValue = 1, + endValue = 5, + states = { + [1] = "Your mission is to get the package from Willard the weapon dealer at Edron.", + [2] = "Willard forgot to pick it up from Snake Eye at Outlaw Camp. \z + So he wants you to go and pick it up from Snake Eye.", + [3] = "Take the package just next door.", + [4] = "Now bring back the package to Rashid.", + [5] = "You have completed this mission. Talk with Rashid to continue." + } + }, + [3] = { + name = "Mission 3: Cheese", + storageId = Storage.TravellingTrader.Mission03, + missionId = 10301, + startValue = 1, + endValue = 3, + states = { + [1] = "Rashid wants you to pick his special order from Miraia in Darashia. \z + But you have to be quick, Scarab cheese can rot really fast in high temperature.", + [2] = "Now quickly bring back the Scarab cheese to Rashid.", + [3] = "You have completed this mission. Talk with Rashid to continue." + } + }, + [4] = { + name = "Mission 4: Vase", + storageId = Storage.TravellingTrader.Mission04, + missionId = 10302, + startValue = 1, + endValue = 3, + states = { + [1] = "Rashid have ordered a special elven vase from Briasol in Ab'Dendriel. \z + He asks you to buy it from Briasol and bring it back. \z + But you should be carefully, since the vase is very fragile.", + [2] = "Now carefully bring the vase back to Rashid.", + [3] = "You have completed this mission. Talk with Rashid to continue." + } + }, + [5] = { + name = "Mission 5: Make a deal", + storageId = Storage.TravellingTrader.Mission05, + missionId = 10303, + startValue = 1, + endValue = 3, + states = { + [1] = "This time, Rashid is testing your trading skills to buy a Crimson Sword from Uzgod. \z + But it have to be less than 400 gold coins and the quality has to be perfect.", + [2] = "Now bring the sword back to Rashid.", + [3] = "You have completed this mission. Talk with Rashid to continue." + } + }, + [6] = { + name = "Mission 6: Goldfish", + storageId = Storage.TravellingTrader.Mission06, + missionId = 10304, + startValue = 1, + endValue = 2, + states = { + [1] = "Rashid wants you to bring him a Goldfish Bowl.", + [2] = "You have completed this mission. Talk with Rashid to continue." + } + }, + [7] = { + name = "Mission 7: Declare", + storageId = Storage.TravellingTrader.Mission07, + missionId = 10305, + startValue = 1, + endValue = 1, + states = { + [1] = "Rashid has declare you as one of his recognized traders, \z + and now you are able to trade with him anytime.." + } + } + } + }, + [30] = { + name = "The Explorer Society", + startStorageId = Storage.ExplorerSociety.QuestLine, + startStorageValue = 1, + missions = { + [1] = { + name = "Joining the Explorers", + storageId = Storage.ExplorerSociety.JoiningTheExplorers, + missionId = 11296, + startValue = 1, + endValue = 4, + states = { + [1] = "The mission should be simple to fulfil. You have to seek out Uzgod in \z + Kazordoon and get the pickaxe for us. Or just find dwarven pickaxe on your own...", + [2] = "Get into Dwacatra and bring family brooch back to Uzgod.", + [3] = "Bring the pickaxe back to the Explorer Society representative." + } + }, + [2] = { + name = "The Ice Delivery", + storageId = Storage.ExplorerSociety.TheIceDelivery, + missionId = 11297, + startValue = 5, + endValue = 7, + states = { + [5] = "Take this ice pick and use it on a block of ice in the caves beneath Folda. \z + Get some ice and bring it here as fast as you can. \z + If the ice melt away, report on your ice delivery mission anyway.", + [6] = "You have 10 minutes before the icicle defrosts. Run back to the Explorer Society representative!" + } + }, + [3] = { + name = "The Butterfly Hunt", + storageId = Storage.ExplorerSociety.TheButterflyHunt, + missionId = 11298, + startValue = 8, + endValue = 16, + states = { + [8] = "This preparation kit will allow you to collect a PURPLE butterfly you have killed. \z + Just use it on the fresh corpse of a PURPLE butterfly.", + [9] = "Return the prepared butterfly to Explorer Society representative.", + [10] = "Ask for another butterfly hunt.", + [11] = "This preparation kit will allow you to collect a BLUE butterfly you have killed. \z + Just use it on the fresh corpse of a BLUE butterfly.", + [12] = "Return the prepared butterfly to Explorer Society representative.", + [13] = "Ask for another butterfly hunt.", + [14] = "This preparation kit will allow you to collect a RED butterfly you have killed. \z + Just use it on the fresh corpse of a RED butterfly.", + [15] = "Return the prepared butterfly to Explorer Society representative." + } + }, + [4] = { + name = "The Plant Collection", + storageId = Storage.ExplorerSociety.ThePlantCollection, + missionId = 11299, + startValue = 17, + endValue = 26, + states = { + [17] = "Take botanist\'s container. Use it on a jungle bells plant to collect a sample.", + [18] = "Report about your plant collection to Explorer Society representative.", + [19] = "Ask for plant collection when you are ready to continue.", + [20] = "Use botanist\'s container on a witches cauldron to collect a sample.", + [21] = "Report about your plant collection to Explorer Society representative.", + [22] = "Ask for plant collection when you are ready to continue.", + [23] = "Use this botanist\'s container on a giant jungle rose to obtain a sample.", + [24] = "Report about your plant collection to Explorer Society representative." + } + }, + [5] = { + name = "The Lizard Urn", + storageId = Storage.ExplorerSociety.TheLizardUrn, + missionId = 11300, + startValue = 27, + endValue = 29, + states = { + [27] = "In the south-east of Tiquanda is a small settlement of the lizard people. \z + Beneath the newly constructed temple there, the lizards hide the urn. \z + Acquire an ancient urn which is some sort of relic to the lizard people of Tiquanda.", + [28] = "Bring the Funeral Urn back to the Explorer Society." + } + }, + [6] = { + name = "The Bonelord Secret", + storageId = Storage.ExplorerSociety.TheBonelordSecret, + missionId = 11301, + startValue = 30, + endValue = 32, + states = { + [30] = "Travel to the city of Darashia and then head north-east for the pyramid. \z + If any documents are left, you probably find them in the catacombs beneath.", + [31] = "Bring the Wrinkled Parchment back to the Explorer Society representative." + } + }, + [7] = { + name = "The Orc Powder", + storageId = Storage.ExplorerSociety.TheOrcPowder, + missionId = 11302, + startValue = 33, + endValue = 35, + states = { + [33] = "As far as we can tell, the orcs maintain some sort of training facility \z + in some hill in the north-east of their city. \z + There you should find lots of their war wolves and hopefully also some of the orcish powder.", + [34] = "Bring the Strange Powder to the Explorer Society representative to complete your mission." + } + }, + [8] = { + name = "The Elven Poetry", + storageId = Storage.ExplorerSociety.TheElvenPoetry, + missionId = 11303, + startValue = 36, + endValue = 38, + states = { + [36] = "This mission is easy but nonetheless vital. Travel Hellgate beneath Ab'Dendriel and get the book.", + [37] = "Bring back an elven poetry book to the Explorer Society representative." + } + }, + [9] = { + name = "The Memory Stone", + storageId = Storage.ExplorerSociety.TheMemoryStone, + missionId = 11304, + startValue = 39, + endValue = 41, + states = { + [39] = "In the ruins of north-western Edron you should be able to find a memory stone. ", + [40] = "Bring back a memory stone to the Explorer Society representative." + } + }, + [10] = { + name = "The Rune Writings", + storageId = Storage.ExplorerSociety.TheRuneWritings, + missionId = 11305, + startValue = 42, + endValue = 44, + states = { + [42] = "Somewhere under the ape infested city of Banuta, one can find dungeons \z + that were once inhabited by lizards. Look there for an atypical structure that \z + would rather fit to Ankrahmun and its Ankrahmun Tombs. Copy the runes you will find on this structure.", + [43] = "Report back to the Explorer Society representative." + } + }, + [11] = { + name = "The Ectoplasm", + storageId = Storage.ExplorerSociety.TheEctoplasm, + missionId = 11306, + startValue = 45, + endValue = 47, + states = { + [45] = "Take ectoplasm container and use it on a ghost that was recently slain.", + [46] = "Return back to the Explorer Society representative with the collected ectoplasm." + } + }, + [12] = { + name = "The Spectral Dress", + storageId = Storage.ExplorerSociety.TheSpectralDress, + missionId = 11307, + startValue = 48, + endValue = 50, + states = { + [48] = "The queen of the banshees lives in the so called Ghostlands, south west of Carlin. \z + Try to get a spectral dress from her.", + [49] = "Report to the Explorer Society with the spectral dress." + } + }, + [13] = { + name = "The Spectral Stone", + storageId = Storage.ExplorerSociety.TheSpectralStone, + missionId = 11308, + startValue = 51, + endValue = 55, + states = { + [51] = "Please travel to our second base and ask them to mail us their latest research reports. \z + Then return here and ask about new missions.", + [52] = "Tell our fellow explorer that the papers are in the mail already.", + [53] = "Take the spectral essence and use it on the strange carving in this building \z + as well as on the corresponding tile in our second base.", + [54] = "Good! Now use the spectral essence on the strange carving in our second base." + } + }, + [14] = { + name = "The Astral Portals", + storageId = Storage.ExplorerSociety.TheAstralPortals, + missionId = 11309, + startValue = 56, + endValue = 56, + states = { + [56] = "Both carvings are now charged and harmonised. You are able to travel in zero time from \z + one base to the other, but you need to have an orichalcum pearl in your possession to use it as power source." + } + }, + [15] = { + name = "The Island of Dragons", + storageId = Storage.ExplorerSociety.TheIslandofDragons, + missionId = 11310, + startValue = 57, + endValue = 59, + states = { + [57] = "Travel to Okolnir and try to find a proof for the existence of dragon lords there in the old times. \z + I think old Buddel might be able to bring you there.", + [58] = "Report back to Lurik with the dragon scale." + } + }, + [16] = { + name = "The Ice Music", + storageId = Storage.ExplorerSociety.TheIceMusic, + missionId = 11311, + startValue = 60, + endValue = 62, + states = { + [60] = "There is a cave on Hrodmir, north of the southernmost barbarian camp Krimhorn. \z + In this cave, there are a waterfall and a lot of stalagmites. \z + Take the resonance crystal and use it on the stalagmites in the cave to record the sound of the wind.", + [61] = "Report back to Lurik.", + [62] = "Now you may use the Astral Bridge from Liberty Bay to Svargrond." + } + }, + [17] = { + name = "The Undersea Kingdom", + storageId = Storage.ExplorerSociety.CalassaQuest, + missionId = 11312, + startValue = 1, + endValue = 3, + states = { + [1] = "Captain Max will bring you to Calassa whenever you are ready. \z + Please try to retrieve the missing logbook which must be in one of the sunken shipwrecks.", + [2] = "Report about your Calassa mission to Berenice in Liberty Bay." + } + } + } + }, + [31] = { + name = "The Ultimate Challenges", + startStorageId = Storage.SvargrondArena.QuestLogGreenhorn, + startStorageValue = 1, + missions = { + [1] = { + name = "Barbarian Arena - Greenhorn Mode", + storageId = Storage.SvargrondArena.QuestLogGreenhorn, + missionId = 11313, + startValue = 1, + endValue = 2, + states = { + [1] = "You have to defeat all enemies in this mode.", + [2] = "You have defeated all enemies in this mode." + } + }, + [2] = { + name = "Barbarian Arena - Scrapper Mode", + storageId = Storage.SvargrondArena.QuestLogScrapper, + missionId = 11314, + startValue = 1, + endValue = 2, + states = { + [1] = "You have to defeat all enemies in this mode.", + [2] = "You have defeated all enemies in this mode." + } + }, + [3] = { + name = "Barbarian Arena - Warlord Mode", + storageId = Storage.SvargrondArena.QuestLogWarlord, + missionId = 11315, + startValue = 1, + endValue = 2, + states = { + [1] = "You have to defeat all enemies in this mode.", + [2] = "You have defeated all enemies in this mode." + } + } + } + }, + [32] = { + name = "The White Raven Monastery", + startStorageId = Storage.WhiteRavenMonastery.QuestLog, + startStorageValue = 1, + missions = { + [1] = { + name = "Access to the Isle of Kings", + storageId = Storage.WhiteRavenMonastery.Passage, + missionId = 10316, + startValue = 1, + endValue = 2, + states = { + [1] = "You are a friend of Dalbrect. \z + Since you returned his family brooch he will sail you to the Isle of Kings unless you do something stupid." + } + }, + [2] = { + name = "The Investigation", + storageId = Storage.WhiteRavenMonastery.Diary, + missionId = 10317, + startValue = 1, + endValue = 2, + states = { + [1] = "Investigate the catacombs. Abbot Costello should be interested in information about brother Fugio.", + [2] = "You returned Fugio\'s Diary. \z + Costello was very thankful about your help and gave you a blessed ankh as reward." + } + } + } + }, + [33] = { + name = "Tibia Tales", + startStorageId = Storage.TibiaTales.DefaultStart, + startStorageValue = 1, + missions = { + [1] = { + name = "To Appease the Mighty", + storageId = Storage.TibiaTales.ToAppeaseTheMightyQuest, + missionId = 10318, + startValue = 0, + endValue = 4, + states = { + [1] = "Kazzan sent you to talk with Ubaid and Umar to offer an appeasement treaty to the Djinn races. \z + Talk to Umar first.", + [2] = "Umar said he won't be part of Kazzan\'s plans. Now you need to try with Ubaid.", + [3] = "Umar and Ubaid said they won't be part of those plans. Return to Kazzan and collect your reward.", + [4] = "You have completed the quest!" + } + }, + [2] = { + name = "Arito\'s Task", + storageId = Storage.TibiaTales.AritosTask, + missionId = 10319, + startValue = 1, + endValue = 3, + states = { + [1] = "Arito asked you to make a peace agreement between him and the Nomads.", + [2] = "Return to Arito and tell him the good news.", + [3] = "Now Arito are safe and you have access to Nomads Cave." + } + }, + [3] = { + name = "Lion\'s Rock", + storageId = Storage.LionsRock.Questline, + missionId = 10320, + startValue = 1, + endValue = 12, + states = { + [1] = "You have discovered the Lion's Rock. If you pass the following tests you may enter the inner sanctum.\z + \n\nThe Lion's Strength 0/1\nThe Lion's Beauty 0/1\nThe Lion's Tears 0/1", + [2] = "You have discovered the Lion's Rock. If you pass the following tests you may enter the inner sanctum.\z + \n\nThe Lion's Strength 1/1\nThe Lion's Beauty 0/1\nThe Lion's Tears 0/1", + [3] = "You have discovered the Lion's Rock. If you pass the following tests you may enter the inner sanctum.\z + \n\nThe Lion's Strength 1/1\nThe Lion's Beauty 1/1\nThe Lion's Tears 0/1", + [4] = "You have passed the three tests of Lion's Rock and thus lit the three mystical pyramids. You may enter\z + the inner sanctum now. - What other secrets could be hidden down there?", + [5] = "You found a mysterious scroll in the debris of an old amphora. It seems it could help to translate the\z + old temple inscriptions.", + [6] = function(player) + return string.format( + "lions' enemies in this area of the temple. What could be the resolution?\z + \n\nblood %d/1\negg %d/1\neye %d/1\npoison %d/1", + (math.max(player:getStorageValue(Storage.LionsRock.SnakeSign), 0)), + (math.max(player:getStorageValue(Storage.LionsRock.LizardSign), 0)), + (math.max(player:getStorageValue(Storage.LionsRock.ScorpionSign), 0)), + (math.max(player:getStorageValue(Storage.LionsRock.HyenaSign), 0)) + ) + end, + [7] = function(player) + return string.format( + "lions' enemies in this area of the temple. What could be the resolution?\z + \n\nblood %d/1\negg %d/1\neye %d/1\npoison %d/1", + (math.max(player:getStorageValue(Storage.LionsRock.SnakeSign), 0)), + (math.max(player:getStorageValue(Storage.LionsRock.LizardSign), 0)), + (math.max(player:getStorageValue(Storage.LionsRock.ScorpionSign), 0)), + (math.max(player:getStorageValue(Storage.LionsRock.HyenaSign), 0)) + ) + end, + [8] = function(player) + return string.format( + "lions' enemies in this area of the temple. What could be the resolution?\z + \n\nblood %d/1\negg %d/1\neye %d/1\npoison %d/1", + (math.max(player:getStorageValue(Storage.LionsRock.SnakeSign), 0)), + (math.max(player:getStorageValue(Storage.LionsRock.LizardSign), 0)), + (math.max(player:getStorageValue(Storage.LionsRock.ScorpionSign), 0)), + (math.max(player:getStorageValue(Storage.LionsRock.HyenaSign), 0)) + ) + end, + [9] = "lions' enemies in this area of the temple. What could be the resolution?\z + \n\nblood 1/1\negg 1/1\neye 1/1\npoison 1/1", + [10] = 'In the north-west area of the Inner Sanctum, find the southern rectangular room to the south-west. \z + In this room you will find 4 "sun" floor inscriptions as well as a rock in the center. The sun inscriptions \z + represent gem slots.', + [11] = "By solving the gem puzzle you unveiled the last secret of the Lion's Rock. You drew a treasure out \z + of the ornamented fountain in the lower temple areas." + } + }, + [4] = { + name = "Against the Spider Cult", + storageId = Storage.TibiaTales.AgainstTheSpiderCult, + missionId = 10321, + startValue = 1, + endValue = 6, + states = { + [1] = "Daniel Steelsoul in Edron wants you to infiltrate the Edron Orc Cave and destroy 4 Spider Eggs.", + [2] = "You destroyed 1 of 4 Spider Eggs in the Edron Orc Cave", + [3] = "You destroyed 2 of 4 Spider Eggs in the Edron Orc Cave", + [4] = "You destroyed 3 of 4 Spider Eggs in the Edron Orc Cave", + [5] = "You destroyed all Spider Eggs in the Edron Orc Cave, report back to Daniel Steelsoul!", + [6] = "You have completed the Quest!" + } + }, + [4] = { + name = "An Interest In Botany", + storageId = Storage.TibiaTales.AnInterestInBotany, + missionId = 10322, + startValue = 1, + endValue = 4, + states = { + [1] = "Rabaz in Farmine asked you to collect samples from rare plant specimen in Zao. \z + Go to the storage room to the west and receive the Botany Almanach. \z + Find then the Giant Dreadcoil and use your Obsidian Knife on it to obtain a sample.", + [2] = "Now you must find the second plant, a Giant Verminous and use your \z + Obsidian Knife on it to obtain a sample.", + [3] = "You found the two samples, report back to Rabaz in Farmine!", + [4] = "You have completed the Quest!" + } + }, + [5] = { + name = "Graves Sanctified - In Progress", + storageId = Storage.TibiaTales.RestInHallowedGround.HolyWater, + missionId = 10323, + startValue = 1, + endValue = 15, + description = function(player) + return string.format( + "You sanctified %d of 15 graves.", + (math.max(player:getStorageValue(Storage.TibiaTales.RestInHallowedGround.HolyWater), 0)) + ) + end + }, + [6] = { + name = "Into the Bone Pit", + storageId = Storage.TibiaTales.IntoTheBonePit, + missionId = 10324, + startValue = 1, + endValue = 3, + states = { + [1] = "Search the Cursed Bone Pit in the dungeon north of Thais and dig for a \z + well-preserved human bone for Muriel.", + [2] = "You have found a desecrated bone for Muriel.", + [3] = "You helped Muriel to obtain a desecrated bone." + } + }, + [7] = { + name = "Rest in Hallowed Ground", + storageId = Storage.TibiaTales.RestInHallowedGround.Questline, + missionId = 10325, + startValue = 1, + endValue = 5, + states = { + [1] = "Go to the white raven monastery and ask for some holy water for Amanda.", + [2] = "You got the holy water from the white raven monastery. \z + Go back to Amanda and report about your mission.", + [3] = "Sanctify every single grave at the unholy graveyard north of Edron with the holy water.", + [4] = "You have sanctified all graves at the unholy graveyard of Edron. Report about your mission at Amanda.", + [5] = "You helped Amanda by sanctifying the cursed graveyard of Edron." + } + }, + [8] = { + name = "The Exterminator", + storageId = Storage.TibiaTales.TheExterminator, + missionId = 10326, + startValue = 1, + endValue = 3, + states = { + [1] = "Padreia in Carlin asked you to exterminate the slimes in the sewers of \z + Carlin by poisoning their spawn pool.", + [2] = "You poisoned the spawn pool of the slimes in the sewers of Carlin. \z + Report to Padreia about your mission.", + [3] = "You successfully helped Padreia in saving Carlin from a slimy disease." + } + }, + [9] = { + name = "The Ultimate Booze", + storageId = Storage.TibiaTales.ultimateBoozeQuest, + missionId = 10327, + startValue = 1, + endValue = 3, + states = { + [1] = "Boozer in Vernore asked you to bring him some special dwarven brown ale. \z + You may find some in the brewery in Kazordoon.", + [2] = "You found the special dwarven brown ale. Bring it to Boozer in Vernore.", + [3] = "You have completed The Ultimate Booze Quest!" + } + }, + [10] = { + name = "Jack to the Future", + storageId = Storage.TibiaTales.JackFutureQuest.QuestLine, + missionId = 10328, + startValue = 1, + endValue = 11, + states = { + [1] = "Spectulus told you about a failed experiment he once did, involving an intern \z + named Jack, and asked you to help him rescue Jack. Go to Jack\'s house and talk to him \z + about Spectulus.", + [2] = "You have talked to Jack and found out that he is not remembering the time \z + accident or Spectulus. Return to Spectulus in the Edron Academy to tell him about \z + your findings.", + [3] = "Spectulus wants you to trigger Jack\'s memory. Jack used to like his red cushioned \z + chair, an old globe, a telescope, a large amphora and a rocking horse. Place those in his \z + room and ask him about it.", + [4] = "You have talked to Jack about the furniture you placed in his house. Report it back \z + to Spectulus in the Edron Academy.", + [5] = "Spectulus sent you once again to his former intern Jack. Explain the incident to the \z + people close to him. Talk to Jack\'s mother and sister and return to Spectulus to report their reaction.", + [6] = "You have talked with Jack\'s mother and sister. Report it back to Spectulus.", + [7] = "Spectulus suggested asking Jack abouthis hobbies. Make Jack leave his hobby be by whateber \z + means it takes. Only by doing this he will be separated from what distracts him from his former self.", + [8] = "You found out and destroyed Jack\'s hobby. Jack is now finally ready and beginning to change. \z + He event seems to start remembering Spectulus and the Academy.", + [9] = "Jack is finally remembering Spectulus and the Academy. Report back your mission.", + [10] = "Spectulus found out that you were convincing the wrong Jack. His real intern was transported \z + way back to the past. He left a note years ago which, to your misery, reached Spectulus a little too late.", + [11] = function(player) + return string.format("%s", getJackLastMissionState(player)) + end + } + }, + [11] = { + name = "The Cursed Crystal", + storageId = Storage.TibiaTales.TheCursedCrystal.Questline, + missionId = 10329, + startValue = 0, + endValue = 4, + states = { + [0] = "A pirate told you about an evil artifact down in the crystal caves under Nargor.\z + It is a big crystal that affects the caves in a negative manner. Perhaps a jarring,\z + very loud sound could destroy it.", + [1] = "You found an old inscription to a mysterious recipe: 'vial of emb... fl... and \z + mix ... a medusa's bl... Then ... the dust of ... crystal ... get Medusa's Ointm... able \z + to unpetrify ...'", + [2] = "You mixed the proper ingredients to create a special salve. The Medusa's Ointment. \z + With this balm you may unpetrify a petrified object.", + [3] = "With the Medusa's Ointment you unpetrified a banshee's scream near the evil crystal. \z + Thus the baleful artefact was destroyed. You should return to One-Eyed Joe.", + [4] = "You have completed the Quest!" + } + } + } + }, + [34] = { + name = "Unnatural Selection", + startStorageId = Storage.UnnaturalSelection.Questline, + startStorageValue = 1, + missions = { + [1] = { + name = "Mission 1: Skulled", + storageId = Storage.UnnaturalSelection.Mission01, + missionId = 10330, + startValue = 1, + endValue = 3, + states = { + [1] = "Your mission is to find the Holy Skull. It is in a cave in the northern orc settlement, \z + which is located north-west on the Zao Steppe.", + [2] = "You found the Holy Skull. Retrieve it to Lazaran in the Zao Mountains.", + [3] = "You brought Lazaran the Holy Skull. Ask him for new mission!" + } + }, + [2] = { + name = "Mission 2: All Around the World", + storageId = Storage.UnnaturalSelection.Mission02, + missionId = 10331, + startValue = 1, + endValue = 13, + states = { + [1] = "You received the Skull of a Caveman and need to explore the world, letting the skull see everything. \z + You need to stand at the highest place of Edron.", + [2] = "You received the Skull of a Caveman and need to explore the world, letting the skull see everything. \z + You need to stand at the highest place of Ab'dendriel.", + [3] = "You received the Skull of a Caveman and need to explore the world, letting the skull see everything. \z + You need to stand at the highest place of Femor Hills.", + [4] = "You received the Skull of a Caveman and need to explore the world, letting the skull see everything. \z + You need to stand at the highest place of Darashia", + [5] = "You received the Skull of a Caveman and need to explore the world, letting the skull see everything. \z + You need to stand at the highest place of Ankrahmun", + [6] = "You received the Skull of a Caveman and need to explore the world, letting the skull see everything. \z + You need to stand at the highest place of Port Hope", + [7] = "You received the Skull of a Caveman and need to explore the world, letting the skull see everything. \z + You need to stand at the highest place of Liberty Bay", + [8] = "You received the Skull of a Caveman and need to explore the world, letting the skull see everything. \z + You need to stand at the highest place of Yalahar", + [9] = "You received the Skull of a Caveman and need to explore the world, letting the skull see everything. \z + You need to stand at the highest place of Svargrond", + [10] = "You received the Skull of a Caveman and need to explore the world, letting the skull see everything. \z + You need to stand at the highest place of Thais", + [11] = "You received the Skull of a Caveman and need to explore the world, letting the skull see everything. \z + You need to stand at the highest place of Carlin", + [12] = "You visited all the highest places with the skull. \z + Turn the skull back to Lazaran and report him your mission!", + [13] = "You turned the skull already back to Lazaran. Ask him for new mission!" + } + }, + [3] = { + name = "Mission 3: Dance Dance Evolution", + storageId = Storage.UnnaturalSelection.Mission03, + missionId = 10332, + startValue = 1, + endValue = 3, + states = { + [1] = "Lazaran told you to go to Ulala, who is located above Lazaran.", + [2] = "Ulala told you to dance to please their god Krunus. \z + On the south mountain in the camp you will find the Krunus altar, there are lots of leaves on the ground.", + [3] = "You solved the dance. Head back to Ulala and report your mission!" + } + }, + [4] = { + name = "Mission 4: Bits and Pieces", + storageId = Storage.UnnaturalSelection.Mission04, + missionId = 10333, + startValue = 1, + endValue = 2, + states = { + [1] = "Now the god Krunus is pleased, another god called Pandor needs to be pleased. \z + Ulala wants you to collect 5 Orc Teeth, 5 Minotaur leathers and 5 Lizard Leathers. Bring them to her.", + [2] = "You brought Ulala 5 Orc Teeth, 5 Minotaur leathers and 5 Lizard Leathers. Ask her for new mission!" + } + }, + [5] = { + name = "Mission 5: Ray of Light", + storageId = Storage.UnnaturalSelection.Mission05, + missionId = 10334, + startValue = 1, + endValue = 3, + states = { + [1] = "The third god which needs to be pleased is called Fasuon. \z + Find the great crystal on top of mountain of Fasuon and pray there for his support!", + [2] = "You already prayed at the great crystal. Report it to Ulala", + [3] = "You have reported back to Ulala that you have completed the mission." + } + }, + [6] = { + name = "Mission 6: Firewater Burn", + storageId = Storage.UnnaturalSelection.Mission06, + missionId = 10335, + startValue = 1, + endValue = 3, + states = { + [1] = "Speak with Lazaran and tell the gods are pleased now.", + [2] = "Bring Lazaran a Pot of brown water for a party after the great hunt.", + [3] = "You brought Lazaran the beer and got a Serpent Crest as reward!" + } + } + } + }, + [35] = { + name = "What a foolish Quest", + startStorageId = Storage.WhatAFoolish.Questline, + startStorageValue = 1, + missions = { + [1] = { + name = "What a foolish Quest - Tasks of a Fool", + storageId = Storage.WhatAFoolish.Mission1, + missionId = 10336, + startValue = 1, + endValue = 2, + states = { + [1] = "Cut a flower at the Whiteflower Temple south of Thais. Then report to Bozo about your mission.", + [2] = "You have finished your first mission and should ask Bozo for the next mission." + } + }, + [2] = { + name = "What a foolish Quest - That stinks!", + storageId = Storage.WhatAFoolish.Mission2, + missionId = 10337, + startValue = 1, + endValue = 2, + states = { + [1] = "It sometimes stinks to be a fool. \z + Collect some noxious fumes from a recently slain slime with the special vial. \z + Then report to Bozo about your mission.", + [2] = "You have finished your second mission and should ask Bozo for the next mission." + } + }, + [3] = { + name = "What a foolish Quest - A Piece of Cake", + storageId = Storage.WhatAFoolish.Mission3, + missionId = 10338, + startValue = 1, + endValue = 2, + states = { + [1] = "Get 12 pies from Mirabell in Edron. Then report to Bozo about your mission.", + [2] = "You have finished your third mission and should ask Bozo for the next mission." + } + }, + [4] = { + name = "What a foolish Quest - Fool Spirits", + storageId = Storage.WhatAFoolish.Mission4, + missionId = 10339, + startValue = 1, + endValue = 3, + states = { + [1] = "Get 18 vials of wine for Bozo. Then report to Bozo about your mission.", + [2] = "Exchange the crates in front of Xodet\'s house and return to Bozo with the swapped crate.", + [3] = "You have finished your fourth mission and should ask Bozo for the next mission." + } + }, + [5] = { + name = "What a foolish Quest - Watch out for the foolish", + storageId = Storage.WhatAFoolish.Mission5, + missionId = 10340, + startValue = 1, + endValue = 3, + states = { + [1] = "Steal the magic watch from the Triangle Tower west of Jakundaf Desert. \z + Then report to Bozo about your mission.", + [2] = "Use the magic watch to steal the beard of the sleeping dwarven emperor.", + [3] = "You have already finished five missions for that fool. \z + You should definitely talk to Bozo about your jester outfit now!" + } + }, + [6] = { + name = "What a foolish Quest - The queen of farts", + storageId = Storage.WhatAFoolish.Mission6, + missionId = 10341, + startValue = 1, + endValue = 5, + states = { + [1] = "Get Bozo 4 pieces of minotaur leather.", + [2] = "Get Bozo a piece of giant spider silk.", + [3] = "Ask Bozo about your mission, he might be finished with the whoopee cushion by now.", + [4] = "Place the whoopee cushion on the queen\'s throne in Carlin by using the cushion with the throne.", + [5] = "You have finished your sixth mission and should ask Bozo for the next mission." + } + }, + [7] = { + name = "What a foolish Quest - For your mice only", + storageId = Storage.WhatAFoolish.Mission7, + missionId = 10342, + startValue = 1, + endValue = 2, + states = { + [1] = "Get the toy mouse of Queen Eloise\'s cat and show it to Carina, the jeweler in Venore, to scare her.", + [2] = "You have finished your seventh mission and should ask Bozo for the next mission." + } + }, + [8] = { + name = "What a foolish Quest - Smoking is a foolish thing", + storageId = Storage.WhatAFoolish.Mission8, + missionId = 10343, + startValue = 1, + endValue = 5, + states = { + [1] = "Gather some easily inflammable sulphur using a spoon on an inactive lava hole.", + [2] = "You brought Bozo the sulphur. Now cut him some leaves of the jungle dweller bush with a kitchen knife.", + [3] = "You have gathered the ordered ingredients and should ask Bozo for the next mission.", + [4] = "Deliver the exploding cigar to Theodore Loveless in Liberty Bay.", + [5] = "You have finished your eighth mission and should ask Bozo for the next mission." + } + }, + [9] = { + name = "What a foolish Quest - A fool\'s bargain", + storageId = Storage.WhatAFoolish.Mission9, + missionId = 10344, + startValue = 1, + endValue = 5, + states = { + [1] = "Bozo wants you to fill a vial with the blood of a stalker. \z + Use the vial on a slain stalker immediately after his death. Then report to Bozo about your mission.", + [2] = "Bozo wants you to fill a vial with the ink of a quara constrictor. \z + Use the vial on a slain constrictor immediately after its death. Then report to Bozo about your mission.", + [3] = "You have gathered the ordered ingredients and should ask Bozo for the next mission.", + [4] = "Order 2000 steel shields from Sam. Sign his contract with the magic ink.", + [5] = "You have finished your ninth mission and should ask Bozo for the next mission." + } + }, + [10] = { + name = "What a foolish Quest - A sweet surprise", + storageId = Storage.WhatAFoolish.Mission10, + missionId = 10345, + startValue = 1, + endValue = 2, + states = { + [1] = "Deliver a cookie to Avar Tar, Simon, Ariella, Lorbas, King Markwin, \z + Hjaern, Wyda, Hairycles, the orc king and EITHER Yaman OR Nah'Bob. Then report to Bozo about the mission.", + [2] = "You have finished your tenth mission and should ask Bozo for the next mission." + } + }, + [11] = { + name = "What a foolish Quest - The final foolishness", + storageId = Storage.WhatAFoolish.Mission11, + missionId = 10346, + startValue = 1, + endValue = 4, + states = { + [1] = "Gather 5 pieces of white cloth for Bozo. Then report about your mission.", + [2] = "Travel to Darama and climb the highest point of the Plague Spike to give these pieces of white \z + cloth an old and worn look. Some ancient altar should suit your needs best - use the white cloth on it.", + [3] = "Use your mummy disguise to scare the caliph Kazzan in Darashia. \z + DON'T use the disguise too early or you will fail the quest.", + [4] = "You have finished all of Bozo\'s missions and you are a complete fool now. Yay!" + } + }, + [12] = { + name = "What a foolish Quest - To become a complete fool", + storageId = Storage.WhatAFoolish.JesterOutfit, + missionId = 10347, + startValue = 4, + endValue = 4, + states = { + [4] = "Now that you have a basic outfit, you should talk to Bozo about your missions to gain further rewards." + } + } + } + }, + [36] = { + name = "Wrath of the Emperor", + startStorageId = Storage.WrathoftheEmperor.Questline, + startStorageValue = 1, + missions = { + [1] = { + name = "Mission 01: Catering the Lions Den", + storageId = Storage.WrathoftheEmperor.Mission01, + missionId = 10348, + startValue = 1, + endValue = 3, + states = { + [1] = "You must bring Zalamon 3 nails and a piece of wood so that he can make a Marked Crate for you.", + [2] = "Go to the tunnel in eastern Muggy Plains and reach the other side. \z + Try to hide in the dark and avoid being seen at all by using the crate. \z + After that you need to find the rebel hideout and talk to their leader Chartan.", + [3] = "You found the leader of the rebel Chartan and reported him about Zalamon. Ask him for new mission!" + } + }, + [2] = { + name = "Mission 02: First Contact", + storageId = Storage.WrathoftheEmperor.Mission02, + missionId = 10349, + startValue = 1, + endValue = 3, + states = { + [1] = "Chartan needs you to reactivate the teleport to the Muggy Plains. \z + Head downstairs and into the temple and craft material to repair the teleport. \z + To do this you will need some tools to improvise.", + [2] = "As you give the coal into the pool the corrupted fluid begins to dissolve, leaving purified, \z + refreshing water. The teleporter is reactivated. Report back to Chartan.", + [3] = "Report back to Zalamon for the next mission." + } + }, + [3] = { + name = "Mission 03: The Keeper", + storageId = Storage.WrathoftheEmperor.Mission03, + missionId = 10350, + startValue = 1, + endValue = 3, + states = { + [1] = "Zalamon gives you a Flask of Plant Poison to destroy plants in the garden \z + of the Emperor to lure out and kill The Keeper to get his tail. The garden is southeast of the rebel hideout.", + [2] = "You killed the Keeper and got his tail. Bring it to Zalamon.", + [3] = "You brought the tail of the Keeper to Zalamon and completed the mission. Ask for the next mission." + } + }, + [4] = { + name = "Mission 04: Sacrament of the Snake", + storageId = Storage.WrathoftheEmperor.Mission04, + missionId = 10351, + startValue = 1, + endValue = 3, + states = { + [1] = "Zalamon now wants you to go to Deeper Banuta and get an Ancient Sceptre \z + that will help in the fight against the emperor. \z + On each floor under Deeper Banuta you collect a sceptre part from a Ghost of a Priest. \z + On the 4th and final floor you need to assemble the sceptre..", + [2] = "After you've assembled the Snake Sceptre and fought your way back out, \z + head back to Zalamon and give it to him.", + [3] = "You brought the Snake Sceptre to Zalamon and completed the mission. Ask for the next mission." + } + }, + [5] = { + name = "Mission 05: New in Town", + storageId = Storage.WrathoftheEmperor.Mission05, + missionId = 10352, + startValue = 1, + endValue = 3, + states = { + [1] = "Zalamon tells you that you have to go inside the city. \z + From the rebel hideout go out to the gray road and follow it to the southwest. \z + Find the Gate Guardian and ask him for a mission to enter the city.", + [2] = "Now you only have to walk west until you find Zlak inside the big green building.", + [3] = "You went deep inside the city to find Zlak and completed the mission. Ask for the next mission." + } + }, + [6] = { + name = "Mission 06: The Office Job", + storageId = Storage.WrathoftheEmperor.Mission06, + missionId = 10353, + startValue = 0, + endValue = 4, + description = function(player) + return string.format( + "Explore the area where Zlak is to find Lizard Magistratus and kill 4 of them. \z + You currently have %d killed. Report back to Zlak if you finished it.", + (math.max(player:getStorageValue(Storage.WrathoftheEmperor.Mission06), 0)) + ) + end + }, + [7] = { + name = "Mission 07: A Noble Cause", + storageId = Storage.WrathoftheEmperor.Mission07, + missionId = 10354, + startValue = 0, + endValue = 6, + description = function(player) + return string.format( + "Explore the area where Zlak is to find Lizard Noble and kill 6 of them. \z + You currently have %d killed. Report back to Zlak if you finished it.", + (math.max(player:getStorageValue(Storage.WrathoftheEmperor.Mission07), 0)) + ) + end + }, + [8] = { + name = "Mission 08: Uninvited Guests", + storageId = Storage.WrathoftheEmperor.Mission08, + missionId = 10355, + startValue = 1, + endValue = 2, + states = { + [1] = "Your mission is to reach your rebel contact Zizzle in the imperial palace. \z + You need to take the old escape tunnel that leads from the abandoned basement \z + in the north of the ministry to a lift that ends somewhere in the palace.", + [2] = "You have reached your rebel contact Zizzle in the imperial palace." + } + }, + [9] = { + name = "Mission 09: The Sleeping Dragon", + storageId = Storage.WrathoftheEmperor.Mission09, + missionId = 10356, + startValue = 1, + endValue = 2, + states = { + [1] = "To enter the inner realms of the Emperor you need to free the mind of a dragon. \z + An interdimensional potion will help you to enter this dream and unleash his consciousness.", + [2] = "You travelled through the Sleeping Dragon dreams and freed his mind." + } + }, + [10] = { + name = "Mission 10: A Message of Freedom", + storageId = Storage.WrathoftheEmperor.Mission10, + missionId = 10357, + startValue = 1, + endValue = 6, + states = { + [1] = "After solving the riddle, and talking again to the Sleeping Dragon you got a Spiritual Charm. \z + Report back to Zizzle.", + [2] = "You possess the key to enter the inner realms of the emperor. \z + Start with the one in the north-west and work your way clockwise trough the room and kill those manifestation. \z + Then use your sceptre on the remain to destroy the emperor\'s influence over the crystal.", + [3] = "You possess the key to enter the inner realms of the emperor. \z + You destroyed 1 of 4 emperor\'s influences.", + [4] = "You possess the key to enter the inner realms of the emperor. \z + You destroyed 2 of 4 emperor\'s influences.", + [5] = "You possess the key to enter the inner realms of the emperor. \z + You destroyed 3 of 4 emperor\'s influences.", + [6] = "You possess the key to enter the inner realms of the emperor. \z + You destroyed all emperor\'s influences." + } + }, + [11] = { + name = "Mission 11: Payback Time", + storageId = Storage.WrathoftheEmperor.Mission11, + missionId = 10358, + startValue = 1, + endValue = 2, + states = { + [1] = "Your Mission is to kill Zalamon. Step into the teleporter to confront him. \z + Finally use your sceptre on the death body.", + [2] = "Go back to Awareness Of The Emperor and report him your success!" + } + }, + [12] = { + name = "Mission 12: Just Rewards", + storageId = Storage.WrathoftheEmperor.Mission12, + missionId = 10359, + startValue = 0, + endValue = 1, + states = { + [0] = "The Emperor has promised you wealth beyond measure. Go claim it in the ministry.", + [1] = "You completed this Quest!" + } + } + } + }, + [37] = { + name = "Oramond", + startStorageId = Storage.Oramond.QuestLine, + startStorageValue = 1, + missions = { + [1] = { + name = "To Take Roots", + storageId = Storage.Oramond.MissionToTakeRoots, + missionId = 10360, + startValue = 1, + endValue = 3000, + description = "Five Juicy roots from the outskirts of Rathleton may already help feed the poor. \z + Try to find a city official to deliver them to or go to the Rathleton poor house." + } + } + }, + [38] = { + name = "Forgotten Knowledge", + startStorageId = Storage.ForgottenKnowledge.Tomes, + startStorageValue = 1, + missions = { + [1] = { + name = "Circle of the Black Sphinx", + storageId = Storage.ForgottenKnowledge.LadyTenebrisKilled, + missionId = 10361, + startValue = 0, + endValue = 1522018605, + states = { + [1] = "You defeated the rogue Lady Tenebris." + } + }, + [2] = { + name = "Bane of the Cosmic Force", + storageId = Storage.ForgottenKnowledge.LloydKilled, + missionId = 10362, + startValue = 0, + endValue = 1522018605, + states = { + [1] = "You calmed poor, misguided Lloyd. All he wanted was protection from the outside world. \z + Luckily he seems to have learned his lesson... or has he?" + } + }, + [3] = { + name = "The Desecrated Glade", + storageId = Storage.ForgottenKnowledge.ThornKnightKilled, + missionId = 10363, + startValue = 0, + endValue = 1522018605, + states = { + [1] = "You defeated the Thorn Knight and shattered the root of evil with all your might. \z + The honor of being a guardian of the glade indeed comes with pride as well as responsibility." + } + }, + [4] = { + name = "The Unwary Mage", + storageId = Storage.ForgottenKnowledge.DragonkingKilled, + missionId = 10364, + startValue = 0, + endValue = 1522018605, + states = { + [1] = "With help of Ivalisse from the temple of the Astral Shapers in Thais and her father, \z + you averted the Dragon King\'s menace deep in the Zao Muggy Plains." + } + }, + [5] = { + name = "Dragon in Distress", + storageId = Storage.ForgottenKnowledge.HorrorKilled, + missionId = 10365, + startValue = 0, + endValue = 1522018605, + states = { + [1] = "You saved the Dragon Mother\'s egg and she melted the ice wall that blocked your way." + } + }, + [6] = { + name = "Time is a Window", + storageId = Storage.ForgottenKnowledge.TimeGuardianKilled, + missionId = 10366, + startValue = 0, + endValue = 1522018605, + states = { + [1] = "You defeated the Time Guardian and are free to return to your own time. \z + For some creatures in this world, it seems neither past nor future are an obstacle." + } + }, + [7] = { + name = "Final Fight", + storageId = Storage.ForgottenKnowledge.LastLoreKilled, + missionId = 10367, + startValue = 0, + endValue = 1522018605, + states = { + [1] = "Description Fault." + } + } + } + }, + [39] = { + name = "The First Dragon", + startStorageId = Storage.FirstDragon.Questline, + startStorageValue = 1, + missions = { + [1] = { + name = "Power", + storageId = Storage.FirstDragon.DragonCounter, + missionId = 10368, + startValue = 0, + endValue = 200, + description = function(player) + return ("You already hunted %d/200 dragons."):format(player:getStorageValue(Storage.FirstDragon.DragonCounter)) + end + }, + [2] = { + name = "Treasure", + storageId = Storage.FirstDragon.ChestCounter, + missionId = 10369, + startValue = 0, + endValue = 20, + description = "Treasure is the favorite of the dragon lords. \z + Find and take Kalyassa\'s treasures spread across the world." + }, + [3] = { + name = "Knowledge", + storageId = Storage.FirstDragon.GelidrazahAccess, + missionId = 10370, + startValue = 0, + endValue = 1, + description = "You learned that frost dragon\'s incitement is the thirst for knowledge, \z + perhaps if you bring some to Gelidrazah\'s you'll meet him." + }, + [4] = { + name = "Life", + storageId = Storage.FirstDragon.SecretsCounter, + missionId = 10371, + startValue = 0, + endValue = 3, + description = "Undead dragons aspires for life. \z + No better way to see life as it grows around the world, is there?" + } + } + }, + [40] = { + name = "Cults of Tibia", + startStorageId = Storage.CultsOfTibia.Questline, + startStorageValue = 1, + missions = { + [1] = { + name = "The Strengthtening of the Minotaurs", + storageId = Storage.CultsOfTibia.Minotaurs.JamesfrancisTask, + missionId = 10372, + startValue = 0, + endValue = 50, + description = function(player) + return ("James asked you to enter the cave for hunting 50 empowered minotaurs. \z + Then he will be able to continue his research.\nMinotaurs killed: %d/50"):format( + player:getStorageValue(Storage.CultsOfTibia.Minotaurs.JamesfrancisTask) + ) + end + }, + [2] = { + name = "The Strengthtening of the Minotaurs", + storageId = Storage.CultsOfTibia.Minotaurs.Mission, + missionId = 10373, + startValue = 1, + endValue = 5, + states = { + [1] = "Gerimor told you that the naturalist Jamesfrancis is an expert of minotaurs. \z + Right now he is investigating a cave in minocity. But this time something seems to be completely different.", + [2] = "Jamesfrancis already entered the inner part of the cave weeks ago but had to flee when \z + the minotaurs became too strong. He gave you the key to investigate this room as well.", + [3] = "You found an entrance to the minotaur boss. You killed it and now you have to return to Jamesfrancis.", + [4] = "Jamesfrancis sent you to talk with Gerimor about the minotaur cult.", + [5] = "You have reported the Druid of Crunor about the minotaur cult." + } + }, + [3] = { + name = "Patron of Arts", + storageId = Storage.CultsOfTibia.MotA.Mission, + missionId = 10374, + startValue = 1, + endValue = 15, + states = { + [1] = "The Druid of Cronor gave you the hint that the Thais exhibition has expanded. \z + The new section is called MOTA (Museum of Tibian Arts). It\'s really worth a visit.", + [2] = "Gareth told you how to become a patron of the arts. To fulfil your duty you have to manage some tasks. \z + First you have to investigate the crime scene of a theft in the museum.", + [3] = "You found a ransom note, wich requests you to pay some money for \z + the stolen picture to a stonge in Kazordoon. His name is Iwar. Nevertheless I should talk to Gareth first.", + [4] = "You told Gareth about the ransom note. \z + He asked you to pay the money to Iwar to get the picture back. In his opinion, there is no alternative.", + [5] = "You paid the money to stooge in Kazordoon. \z + You were told that the picture is delivered to Gareth himself.", + [6] = "You have to go to Angelo and get a magnifier to investigate all small \z + pictures in the entrance hall of the MOTA. One of them should be a fake.", + [7] = "Angelo allowed you to take a magnifier from a crate next to the cave entrance.", + [8] = "You've fetched the magnifier from Angelo\'s crate. You're ready for your job in the museum.", + [9] = "Indeed! One of the investigated small pictures is fake. Report to Gareth!", + [10] = "After you told Gareth about the fake painting, he asked you to go to Angelo to get a new picture.", + [11] = "Angelo was not willing to give you a new picture. \z + However, they havent found any artefact in the sandy cave yet. Report to Gareth about your failure.", + [12] = "Even though you weren't successful in getting a replacement for the fake picture, \z + Gareth gave you access to the last floor of the museum. This area is for patrons only.", + [13] = "INTERNAL MESSAGE: THIS NEED QUESTLOG INFORMATION", + [14] = "The Denomintator opened the door for you after you answered his questions to the wanted number. \z + In the end he mentioned the Druid of Conor. Maybe you should pay him a visit.", + [15] = "In the end you told the Druid of Crunor about your experiences in the MoTA." + } + }, + [4] = { + name = "Barkless", + storageId = Storage.CultsOfTibia.Barkless.Mission, + missionId = 10375, + startValue = 1, + endValue = 7, + states = { + [1] = "The members of the Barkless follow a rigid path of hardship and sacrifice. \z + Their cult is located somewhere beneath Ab'dendriel. \z + Whatever happened to their leader, only a true Barkless can find out.", + [2] = "You survived the sulphur and tar trial. You accepted the stigma of misfortune and vanity. \z + The hardest part, however, is yet to come. Give your life to the ice... to become true and purified.", + [3] = function(player) + return ("You survived the Trial. Barkless now have the right to see the cult leader but a \z + powerful relic is sealing the path. Barkless markings broken to reverse the power of the cult object: \z %d of 10"):format(math.max(player:getStorageValue(Storage.CultsOfTibia.Barkless.Objects), 0)) + end, + [4] = "You broke enough Barkless markings to now reverse the seal \z + held up by the cult object in the ritual chamber. \z + The power you gained feels unnatural and excessive but it seems ther is no other way.", + [5] = 'Something far more powerful than the beliel of your Barkless brothers \z + and sisters powered the seal to the leader. Whatever the case - find Leiden, \z + or as he\'s known to his devotees: the "Penitent".', + [6] = "The Leiden you confronted has strayed far from his own original vision of Barkless. \z + What you encountered was more monster than elf and less virtuous than his devotees would have you believe.", + [7] = "You returned to Gerimor after putting an end to the mischief of Leyden the Penitent. \z + May the Barkless walk the true path again one day." + } + }, + [5] = { + name = "Misguided", + storageId = Storage.CultsOfTibia.Misguided.Mission, + missionId = 10376, + startValue = 1, + endValue = 5, + states = { + [1] = "ASD", + [2] = "Below a ruin in the vicinity of the outlaw camp east of Thais a strange figure in ragged clothes \z + hinted at something weird going on in a cave. He seemed too confused to decide whether to stop you.", + [3] = function(player) + return ("While rubbish, the amulet you equipe emits a strange aura of splendour. \z + You feel an urge to fulfill the amulets hunger for especific deaths... Exorcisms: %d/5 "):format(math.max(player:getStorageValue(Storage.CultsOfTibia.Misguided.Exorcisms), 0)) + end, + [4] = "You defeated the cult leader of Misguided by uncovering the true master to pull his strings \z + and freeing this world from its malicious existance. Return to Gerimor to tell him about the victory.", + [5] = "You have spoken to Gerimor about your victory." + } + }, + [6] = { + name = "The Orc Idol", + storageId = Storage.CultsOfTibia.Orcs.Mission, + missionId = 10377, + startValue = 1, + endValue = 3, + states = { + [1] = "ASD", + [2] = "ASD", + [3] = "You returned to Gerimor after facing the being the orcs worshipped. \z + Whatever it was, it did not find the orcs by accident. \z + A far more powerful force seems to have strategically place it here." + } + }, + [7] = { + name = "The Secret of the Sandy Cave", + storageId = Storage.CultsOfTibia.Life.Mission, + missionId = 10378, + startValue = 1, + endValue = 10, + states = { + [1] = "ASD", + [2] = "ASD", + [3] = "In the cave you haven't found one of the missing scientists. \z + However, you have faced a lots of strange mummies and a green oasis at the end.", + [4] = "After you informed Angelo about your experiences in the cave, \z + he asked you to go back to analyse the water of the oasis. For that reason you got an analysis tool.", + [5] = "You have analysed the water with the help of the analysis tool from Angelo.", + [6] = "You informed Angelo about the analyzed water. \z + He gave you a counteragent, wich you have to apply to the oasis.", + [7] = "You applied the counteragent to the oasis, just like Angelo had asked you to. \z + But the effect was different from what you had expected. \z + A sandstorm approached and caused create damage to the oasis.", + [8] = "You Killed the boss", + [9] = "You reported your victory to Angelo", + [10] = "You have told Gerimor about your stay in the sandy cave. \z + He was not really surprised and felt vindicated that the rumors about a cult in the cave might be true." + } + }, + [8] = { + name = "Zathroth Remmants", + storageId = Storage.CultsOfTibia.Humans.Mission, + missionId = 10379, + startValue = 1, + endValue = 3, + states = { + [1] = function(player) + return ("A remnant cult of Zathroth has formed in a forbidden temple beneath Carlin. \z + Find out what's behind this and stop it in time.\nTemporarily vaporised souls:\n%d Decaying\n%d Withering"):format( + math.max(player:getStorageValue(18551), 0), + math.max(player:getStorageValue(18550), 0) + ) + end, + [2] = "ASD", + [3] = "You returned to Gerimor after encounter with the remnants of Zathroth. On one hand its is \z + furtunate that Zathroth indeed wasn't behind all this, but on the other... what is going on there?" + } + } + } + }, + [41] = { + name = "Dangerous Depths", + startStorageId = Storage.DangerousDepths.Questline, + startStorageValue = 1, + missions = { + [1] = { + name = "Dwarves: Home Improvement", + storageId = Storage.DangerousDepths.Dwarves.Home, + missionId = 10380, + startValue = 1, + endValue = 2, + states = { + [1] = function(player) + return ("Destroy makeshift homes of the Lost to force them to fight you! Try making some \z + prisoners in the progress and report back to Klom Stonecutter.\n\nLost Exiles: %d/20\nPrisoners (bonus): \z + %d/3"):format( + math.max(player:getStorageValue(Storage.DangerousDepths.Dwarves.LostExiles), 0), + math.max(player:getStorageValue(Storage.DangerousDepths.Dwarves.Prisoners), 0) + ) + end, + [2] = "You drove off the Lost but more are sure to come. Check back with Klom Stonecutter at a later time." + } + }, + [2] = { + name = "Dwarves: Subterranean Life", + storageId = Storage.DangerousDepths.Dwarves.Subterranean, + missionId = 10381, + startValue = 1, + endValue = 2, + states = { + [1] = function(player) + return ("Klome Stonecutter sent you on a grave mission to exterminate large populaces of \z + subterranian life. Looks like the dwarves make short work of the deep intruders.\n\nSubterranean organisms: \z + %d/50"):format( + math.max(player:getStorageValue(Storage.DangerousDepths.Dwarves.Organisms), 0) + ) + end, + [2] = "You helped Klom defend the outpost by cutting down a number of vermin from deep down below. \z + The gnomes don't seem to completely approve of this but everyone appreciates the drop in the enemy's ranks." + } + }, + [3] = { + name = "Gnomes: Gnomal Warming Measurements", + storageId = Storage.DangerousDepths.Gnomes.Measurements, + missionId = 10382, + startValue = 1, + endValue = 2, + states = { + [1] = function(player) + return ("Gnomus sent you on a mission to measure the rising heat from below.\n\nLocation A: \z + %d/1\nLocation B: %d/1\nLocation C: %d/1\nLocation D: %d/1\nLocation E: %d/1"):format( + math.max(player:getStorageValue(Storage.DangerousDepths.Gnomes.LocationA), 0), + math.max(player:getStorageValue(Storage.DangerousDepths.Gnomes.LocationB), 0), + math.max(player:getStorageValue(Storage.DangerousDepths.Gnomes.LocationC), 0), + math.max(player:getStorageValue(Storage.DangerousDepths.Gnomes.LocationD), 0), + math.max(player:getStorageValue(Storage.DangerousDepths.Gnomes.LocationE), 0) + ) + end, + [2] = "You helped Lardoc Bashsmite fighting back the verminous growth in the northern mineshaft. \z + Return to him later to see if he has more work for you." + } + }, + [4] = { + name = "Gnomes: Ordnance", + storageId = Storage.DangerousDepths.Gnomes.Ordnance, + missionId = 10383, + startValue = 1, + endValue = 3, + states = { + [1] = "Gnomus sent you to find and rescue the gnome ordnance the outpost is currently waiting for. \z + Travel to the east of the cave system and find the old gnome trail where reinforcements will arrive.", + [2] = function(player) + return ("You found the old gnome trail where ordnance for the gnome outpost arrive, escort them \z + and their pack animals to safety and return to Gnomus.\n\nRescued gnomes: %d/5\nRescued animals: %d/3"):format( + math.max(player:getStorageValue(Storage.DangerousDepths.Gnomes.GnomesCount), 0), + math.max(player:getStorageValue(Storage.DangerousDepths.Gnomes.CrawlersCount), 0) + ) + end, + [3] = "You helped Lardoc Bashsmite fighting back the verminous growth in the northern mineshaft. \z + Return to him later to see if he has more work for you." + } + }, + [5] = { + name = "Gnomes: Uncharted Territory", + storageId = Storage.DangerousDepths.Gnomes.Charting, + missionId = 10384, + startValue = 1, + endValue = 2, + states = { + [1] = function(player) + return ("Chart the area around the deep base for Gnomus. Look for especific landmarks: \z + \n\nOld Gate: %d/1\nThe Gaze: %d/1\nLost Ruin: %d/1\nOutpost: %d/1\nBastion: %d/1\nBroken Tower: \z + %d/1"):format( + math.max(player:getStorageValue(Storage.DangerousDepths.Gnomes.OldGate), 0), + math.max(player:getStorageValue(Storage.DangerousDepths.Gnomes.TheGaze), 0), + math.max(player:getStorageValue(Storage.DangerousDepths.Gnomes.LostRuin), 0), + math.max(player:getStorageValue(Storage.DangerousDepths.Gnomes.Outpost), 0), + math.max(player:getStorageValue(Storage.DangerousDepths.Gnomes.Bastion), 0), + math.max(player:getStorageValue(Storage.DangerousDepths.Gnomes.BrokenTower), 0) + ) + end, + [2] = "You helped Gnomus chart the area around the deep base. You found traces of what \z + could have been an old civilisation but there's not enough left to draw any conclusion." + } + }, + [6] = { + name = "Scouts: Explosive Growth", + storageId = Storage.DangerousDepths.Scouts.Growth, + missionId = 10385, + startValue = 1, + endValue = 2, + states = { + [1] = function(player) + return ("You found the mine shaft. Burn all the growth and report back to Lardoc Bashsmite! \z + \n\nFirst Room: %d/1\nSecond room: %d/1\nThird room: %d/1\nFourth room: %d/1\nFifth room: %d/1"):format( + math.max(player:getStorageValue(Storage.DangerousDepths.Scouts.FirstBarrel), 0), + math.max(player:getStorageValue(Storage.DangerousDepths.Scouts.SecondBarrel), 0), + math.max(player:getStorageValue(Storage.DangerousDepths.Scouts.ThirdBarrel), 0), + math.max(player:getStorageValue(Storage.DangerousDepths.Scouts.FourthBarrel), 0), + math.max(player:getStorageValue(Storage.DangerousDepths.Scouts.FifthBarrel), 0) + ) + end, + [2] = "You helped Lardoc Bashsmite fighting back the verminous growth in the northern mineshaft. \z + Return to him later to see if he has more work for you." + } + }, + [7] = { + name = "Scouts: Pesticide", + storageId = Storage.DangerousDepths.Scouts.Diremaw, + missionId = 10386, + startValue = 1, + endValue = 2, + states = { + [1] = function(player) + return ("Lardoc asked you to follow a plan of the gnomes to stop the deep threat by trying to \z + neutralise diremaw spawn with pesticies. Diremaws lay eggs inside corpses of their skin. \z + \n\nNeutralised: %d/20"):format( + math.max(player:getStorageValue(Storage.DangerousDepths.Scouts.DiremawsCount), 0) + ) + end, + [2] = "You reported back to Lardoc Bashsmite to inform him that the gnome's plan to \z + neutralise diremaw corpses seems to work." + } + } + } + }, + [42] = { + name = "Threatened Dreams", + startStorageId = Storage.ThreatenedDreams.Start, + startStorageValue = 1, + missions = { + [1] = { + name = "Mission 01: Troubled Animals", + storageId = Storage.ThreatenedDreams.TroubledMission01, + missionId = 10387, + startValue = 1, + endValue = 17, + states = { + [1] = "STATE 1", + [2] = "STATE 2", + [3] = "STATE 3", + [4] = "STATE 4", + [5] = "STATE 5", + [6] = "STATE 6", + [7] = "STATE 7", + [8] = "STATE 8", + [9] = "STATE 9", + [10] = "STATE 10", + [11] = "STATE 11", + [12] = "STATE 12", + [13] = "STATE 13", + [14] = "STATE 14", + [15] = "STATE 15", + [16] = "STATE 16", + [17] = "STATE 17", + } + }, + [2] = { + name = "Mission 02: Tattered Swan Feathers", + storageId = Storage.ThreatenedDreams.TroubledMission01, + missionId = 10400, + startValue = 1, + endValue = 5, + states = { + [1] = "STATE 1", + [2] = "STATE 2", + [3] = "STATE 3", + [4] = "STATE 4", + [5] = "STATE 5" + } + } + } + }, + [43] = { + name = "Adventurers Guild", + startStorageId = Storage.AdventurersGuild.GreatDragonHunt.WarriorSkeleton, + startStorageValue = 1, + missions = { + [1] = { + name = "The Great Dragon Hunt", + storageId = Storage.AdventurersGuild.GreatDragonHunt.WarriorSkeleton, + missionId = 10388, + startValue = 0, + endValue = 2, + description = function(player) + return ("You are exploring the Kha'zeel Dragon Lairs. Others obviously found a terrible end here. \z + But the dragon hoards might justify the risks. You killed %d/50 dragons and dragon lords."):format( + math.max(player:getStorageValue(Storage.AdventurersGuild.GreatDragonHunt.DragonCounter), 0) + ) + end + } + } + }, + [44] = { + name = "Dawnport", + startStorageId = Storage.Quest.Dawnport.Questline, + startStorageValue = 1, + missions = { + [1] = { + name = "In the Adventures Outpost", + storageId = Storage.Quest.Dawnport.GoMain, + missionId = 10389, + startValue = 1, + endValue = 2, + description = "You have reached the Outpost, where young heroes are trained in combat and hunting. \z + When you have reached level 8 at least, you can leave for the Mainland. Talk to Inigo if you have questions." + }, + [2] = { + name = "The Lost Amulet", + storageId = Storage.Quest.Dawnport.TheLostAmulet, + missionId = 10390, + startValue = 1, + endValue = 3, + states = { + [1] = "Mr Morris tasked you to find an ancient amulet that was lost somewhare on Dawnport - probably next to a corpse somewhare.", + [2] = "Come back to Mr Morris", + [3] = "Mr Morris thanks for the help" + } + }, + [3] = { + name = "The Stolen Log Book", + storageId = Storage.Quest.Dawnport.TheStolenLogBook, + missionId = 10391, + startValue = 1, + endValue = 2, + states = { + [1] = "Mr Morris urged you fo find a log book that was stolen by trolls.", + [2] = "Mr Morris thanks for the help" + } + }, + [4] = { + name = "The Rare Herb", + storageId = Storage.Quest.Dawnport.TheRareHerb, + missionId = 10392, + startValue = 1, + endValue = 3, + states = { + [1] = "Mr Morris needs the rae Dawnfire herb harvested and brought to hin. It grows on grey sand only, he said.", + [2] = "Come back to Mr Morris", + [3] = "Mr Morris thanks for the help" + } + }, + [5] = { + name = "The Dorm Key", + storageId = Storage.Quest.Dawnport.TheDormKey, + missionId = 10393, + startValue = 1, + endValue = 5, + states = { + [1] = "The key to the adventurer\'s dormitory has disappeared. Maybe you can find it. Ask around to find out who was the last to have seen it.", + [2] = "use the fishing rod in the nearby lake to fish old nasty", + [3] = "Come back to Woblin with Old Nasty", + [4] = "Come back to Mr Morris with key 0010", + [5] = "Mr Morris thanks for the help" + } + }, + [6] = { + name = "Task: Mountain Trolls", + storageId = 65062, + missionId = 10394, + startValue = 0, + endValue = 20, + description = + function(player) + return string.format("You already hunted %d/20 Mountain Trolls.", + (math.max(player:getStorageValue(65062), 0))) + end + }, + [7] = { + name = "Task: Muglex Clan Footman", + storageId = 65061, + missionId = 10395, + startValue = 0, + endValue = 20, + description = + function(player) + return string.format("You already hunted %d/20 Muglex Clan Footman.", + (math.max(player:getStorageValue(65061), 0))) + end + }, + [8] = { + name = "Task: Minotaur Bruisers", + storageId = 65060, + missionId = 10396, + startValue = 0, + endValue = 20, + description = + function(player) + return string.format("You already hunted %d/20 Minotaurs Bruisers.", + (math.max(player:getStorageValue(65060), 0))) + end + }, + } + }, + [45] = { + name = "The Rookie Guard", + startStorageId = Storage.TheRookieGuard.Questline, + startStorageValue = 1, + missions = { + [1] = { + name = "Mission 01: A Taste of Things to Come", + storageId = Storage.TheRookieGuard.Mission01, + missionId = 10397, + startValue = 1, + endValue = 1, + states = { + [1] = "" + } + }, + [2] = { + name = "Mission 02: Defence!", + storageId = Storage.TheRookieGuard.Mission02, + missionId = 10398, + startValue = 1, + endValue = 5, + states = { + [1] = "Vascalir promised you some equipment, but first you need to build up some muscles. Find a big pile of stone in a barn to the north and use it to get a heavy stone.", + [2] = "You retrieved one stone from the big pile. Climb onto the roof of either Norma's bar, Obi's shop or the academy to find a catapult to use it on.", + [3] = "You loaded a stone on one of the catapults. One more to go! Climb onto the roof of either Norma's bar, Obi's shop or the academy to find a catapult to load with a heavy stone.", + [4] = "Two of the four catapults on the roofs are loaded. That should be enough to build up a decent defence. Return to Vascalir to turn in your quest.", + [5] = "You made sure that Rookgaard's defences are at their best. If the orcs try to enter the village, they won't have an easy time!" + } + }, + [3] = { + name = "Mission 03: A Rational Request", + storageId = Storage.TheRookieGuard.Mission03, + missionId = 10399, + startValue = 1, + endValue = 2, + states = { + [1] = function(player) + return string.format( + "Vascalir sent you to the Rookgaard sewers to kill 5 rats. You have already killed %d/5. Return to Vascalir once you're done.", + player:getStorageValue(Storage.TheRookieGuard.RatKills) + ) + end, + [2] = "Vascalir was pleased with your hunting efforts. You've proven that you are a skilled hunter, ready for the task at hand." + } + }, + [4] = { + name = "Mission 04: Home-Brewed", + storageId = Storage.TheRookieGuard.Mission04, + missionId = 10400, + startValue = 1, + endValue = 6, + states = { + [1] = "Vascalir doesn't have a job for you at the moment. He sent you to Lily in the south-west of town for another mission.", + [2] = "Lily gave you a bag with fresh herbs that need to be delivered to Hyacinth outside of the village. Leave the village to the north and walk east to find his little hut up a mountain.", + [3] = "You've delivered the fresh herbs to Hyacinth. He still has a reward for you though - make sure to talk to him again!", + [4] = "Hyacinth has another reward for you - make sure to talk to him again with enough space in your inventory.", + [5] = "You've delivered the herbs to Hyacinth and got potions and a ring as reward. Save the potions for when you're low on health and wear the ring if you want to regain health faster. Return to Vascalir.", + [6] = "You've told Vascalir about your successful delivery. The next mission awaits." + } + }, + [5] = { + name = "Mission 05: Web of Terror", + storageId = Storage.TheRookieGuard.Mission05, + missionId = 10401, + startValue = 1, + endValue = 6, + states = { + [1] = "Vascalir sent you to the spider queen's lair to retrieve a web sample. Leave the village to the north and cross the bridge to the north-west to find the lair. Look for greasy blue stones.", + [2] = "You've covered yourself in grease. It's a bit disgusting, but the spider queen will not be able to smell you for about two minutes. Enter her cave and USE an intact spider web to retrieve a sample.", + [3] = "You retrieved some of the spider queen's web. Return to Vascalir and try not to get caught by the queen on the way out!", + [4] = "The spider queen caught you in her net. If you had a sample of her web, you've lost it. Find a way out of her net and retry!", + [5] = "Vascalir took the sample from you. He still has a studded armor for you - talk to him once you have enough space in your inventory.", + [6] = "You've brought the spider queen's web back to Vascalir. This will definitely come in handy later on." + } + }, + [6] = { + name = "Mission 06: Run Like a Wolf", + storageId = Storage.TheRookieGuard.Mission06, + missionId = 10402, + startValue = 1, + endValue = 7, + states = { + [1] = "Vascalir sent you to Tom the Tanner, who can be found to the west of the academy. There you will get your next mission.", + [2] = "Leave the village to the north and walk north-east into the forest to find the wolves' den that Tom told you about. Hopefully you will find that poacher to take some leather from him!", + [3] = "You've entered the wolves' den - that was a one-way fall, but luckily you didn't get hurt. The poacher you were looking for is dead - but that doesn't mean you can't get some war wolf leather!", + [4] = "You've skinned a war wolf - but you alerted the wolf pack! Run to the exit, quickly!", + [5] = "RUN! You have only a limited time to reach the exit with the war wolf leather!", + [6] = "Phew - you managed to get out of the wolves' den in time. Return to Tom to finish your mission.", + [7] = "Tom gave you a pair of leather boots as reward for your good work. Vascalir surely has a new mission for you now." + } + }, + [7] = { + name = "Mission 07: Attack!", + storageId = Storage.TheRookieGuard.Mission07, + missionId = 10403, + startValue = 1, + endValue = 2, + states = { + [1] = "While you were gone, trolls have infiltrated the academy and set it on fire! Enter the burning vault deep underground and try to recover the copy of the book of orc language before it's destroyed.", + [2] = "You've done all you could - but unfortunately the book is lost. No need to lose heart though - there is still hidden knowledge about the orc language in the village, and the next mission awaits." + } + }, + [8] = { + name = "Mission 08: Less Risk - More Fun", + storageId = Storage.TheRookieGuard.Mission08, + missionId = 10404, + startValue = 1, + endValue = 2, + states = { + [1] = "Before getting revenge on the trolls, eliminate the risk of losing money on the way. Paulie has an interesting bonus offer for you if you deposit your money at the bank. Find him below the academy.", + [2] = "You've done as Vascalir asked and talked to Paulie. Remember to always leave your gold on your account! That way there's no risk of losing it." + } + }, + [9] = { + name = "Mission 09: Rock 'n Troll", + storageId = Storage.TheRookieGuard.Mission09, + missionId = 10405, + startValue = 1, + endValue = 10, + states = { + [1] = "Enter the troll lair to the north of the village and find the new tunnel which the trolls dug and used to infiltrate the Rookgaard academy. There, you need to find a way to destroy it.", + [2] = "Open the chests in the tunnel and use the pick on the 5 beams to weaken the structure and make the tunnel collapse.", + [3] = "You've weakened one of five beams.", + [4] = "You've weakened two of five beams.", + [5] = "You've weakened tree of five beams.", + [6] = "You've weakened four of five beams.", + [7] = "You've weakened all the beams! Hurry out of the tunnel before it collapses!", + [8] = "The tunnel collapsed behind you. Time to return to Vascalir.", + [9] = "Vascalir rewarded you with experience, but there's still something he has to give you. You should talk to him again.", + [10] = "The trolls will not be able to enter the academy via their tunnel again. The village is safe for now - at least from trolls." + } + }, + [10] = { + name = "Mission 10: Tomb Raiding", + storageId = Storage.TheRookieGuard.Mission10, + missionId = 10406, + startValue = 1, + endValue = 3, + states = { + [1] = "Leave the village to the north and walk south-east to find the haunted graveyard. Descend into the crypt and find a sarcophagus that might still contain a fleshy bone. Bring it to Vascalir.", + [2] = "You've brought the fleshy bone back to Vascalir. Talk to him again to receive your reward.", + [3] = "You managed to get a fleshy bone from the crypt! Who knows what Vascalir plans with it - but this is going to be good." + } + }, + [11] = { + name = "Mission 11: Sweet Poison", + storageId = Storage.TheRookieGuard.Mission11, + missionId = 10407, + startValue = 1, + endValue = 5, + states = { + [1] = "Leave the village to the north and cross the bridge to the west, then walk south-west to find a wasp lair. Make sure you don't lose the flask Vascalir gave you.", + [2] = "You've found the wasp lair. Kill one wasp and use the empty flask on its dead body to retrieve some of its poison.", + [3] = "You've retrieved some lethal wasp poison. Bring it back to Vascalir to complete the mission.", + [4] = "You brought Vascalir the highly toxic poison. You should talk to him again to receive your reward.", + [5] = "You've retrieved highly toxic wasp poison for Vascalir. It's time for your final challenge." + } + }, + [12] = { + name = "Mission 12: Into The Fortress", + storageId = Storage.TheRookieGuard.Mission12, + missionId = 10408, + startValue = 1, + endValue = 15, + states = { + [1] = "This is it - the infiltration of the orc fortress and revenge on Kraknaknork awaits. Get the required items from a chest in the academy near the bank.", + [2] = "You've got all items you need to finally kill Kraknaknork. Don't lose them, and carefully make your way towards the orc fortress located in the far west of Rookgaard. Leave the village to the north.", + [3] = "You've knocked out the unsuspecting orc. USE the orc before it wakes up again to disguise yourself as an orc!", + [4] = "Even your mom wouldn't recognise you. You might not be able to fool all orcs in your disguise, but it should be enough to walk past the orc guarding the entrance.", + [5] = "You managed to sneak into the fortress. Use the fleshy bone and click on the elite orc guard with the crosshairs to create a distraction!", + [6] = "The guard is indeed very distracted - he smells delicious. At least to the wild dogs that entered the scene. This is the perfect time to enter the lower levels of the orc fortress.", + [7] = "You're inside the orc fortress! Now you need to find a kitchen and something that looks like a soup cauldron. Use the wasp poison on the cauldron to create an evil surprise for Kraknaknork.", + [8] = "You \"spiced up\" Kraknaknork's breakfast. Let's see how strong he still is after his meal. Proceed further into the fortress - and keep your tarantula trap ready.", + [9] = "You managed to slow down the furious orc berserker. Now, run through the teleporter while he isn't close to it!", + [10] = "You've entered Kraknaknork's room. Find a way to get rid of the energy barriers.", + [11] = "You solved the riddle of the energy barriers. The way to the throne room should be clear - for a short time. Be prepared for a massive fight!", + [12] = "You've entered Kraknaknork's throne room. Fight him! You can back out at any time via the teleporter, but you'll have to start the battle over. Once he is dead, enter the teleporter near his throne.", + [13] = "You've vanquished Kraknaknork and found his treasure room. You can probably take a few things from there before you leave - he wouldn't care anymore.", + [14] = "With the last bit of Kraknaknork's energy, you were teleported out of the fortress. Time to return to Vascalir victoriously.", + [15] = "You've vanquished Kraknaknork and brought peace to the village of Rookgaard. It will soon be time for you to leave for the Isle of Destiny, choose a vocation and enter the open world of Tibia." + } + } + } + } + } +end + +if not LastQuestlogUpdate then + LastQuestlogUpdate = {} +end + +if not PlayerTrackedMissionsData then + PlayerTrackedMissionsData = {} +end + +-- Text functions + +function evaluateText(value, player) + if type(value) == "function" then + return tostring(value(player)) + end + + return tostring(value) +end + +-- Game functions + +function Player.hasTrackingQuest(self, missionId) + local trackedQuests = PlayerTrackedMissionsData[self:getId()] + if trackedQuests then + for i = 1, #trackedQuests do + local mission = trackedQuests[i] + if mission and mission.missionId == missionId then + return true + end + end + end + return false +end + +function Player.getQuestDataByMissionId(self, missionId) + for questId = 1, #Quests do + local quest = Game.getQuest(questId) + if quest then + if quest.missions then + for i = 1, #quest.missions do + local mission = quest.missions[i] + if mission and mission.missionId == missionId then + return quest.name, questId, i + end + end + end + end + end + return false +end + +function Player.resetTrackedMissions(self, missions) + local maxAllowed = self:getAllowedTrackedQuestCount() + PlayerTrackedMissionsData[self:getId()] = {} + for i = 1, #missions do + local missionId = missions[i] + local questName, questId, missionIndex = self:getQuestDataByMissionId(missionId) + if questName and questId and missionIndex then + if self:missionIsStarted(questId, missionIndex) then + local data = { + missionId = missionId, + questName = questName, + missionName = self:getMissionName(questId, missionIndex), + missionDesc = self:getMissionDescription(questId, missionIndex) + } + table.insert(PlayerTrackedMissionsData[self:getId()], data) + if #PlayerTrackedMissionsData[self:getId()] >= maxAllowed then + break + end + end + end + end + + self:sendTrackedQuests(maxAllowed - #PlayerTrackedMissionsData[self:getId()], PlayerTrackedMissionsData[self:getId()]) +end + +function Player.getAllowedTrackedQuestCount(self) + return self:isPremium() and 25 or 10 +end + +function Game.isValidQuest(questId) + return (Quests and Quests[questId]) +end + +function Game.isValidMission(questId, missionId) + return (Game.isValidQuest(questId) and Quests[questId].missions and Quests[questId].missions[missionId]) +end + +function Game.getQuest(questId) + if Game.isValidQuest(questId) then + return Quests[questId] + end + return false +end + +function Game.getQuestIdByName(name) + for questId = 1, #Quests do + local quest = Game.getQuest(questId) + if quest and quest.name:lower() == name:lower() then + return questId + end + end + return false +end + +function Game.getMission(questId, missionId) + if Game.isValidMission(questId, missionId) then + return Quests[questId].missions[missionId] + end + return false +end + +function Player.getMissionsData(self, storage) + local missions = {} + for questId = 1, #Quests do + local quest = Game.getQuest(questId) + if quest and quest.missions then + for missionId = 1, #quest.missions do + local started = self:missionIsStarted(questId, missionId) + if started then + local mission = quest.missions[missionId] + if mission.storageId == storage then + local data = { + missionId = mission.missionId, + missionName = self:getMissionName(questId, missionId), + missionDesc = self:getMissionDescription(questId, missionId) + } + missions[#missions + 1] = data + end + end + end + end + end + return missions +end + +function Game.isQuestStorage(key, value, oldValue) + for questId = 1, #Quests do + local quest = Game.getQuest(questId) + if quest then + if quest.startStorageId == key and quest.startStorageValue == value then + return true + end + + if quest.missions then + for missionId = 1, #quest.missions do + local mission = Game.getMission(questId, missionId) + if mission then + if mission.storageId == key and value >= mission.startValue and value <= mission.endValue then + return mission.description or oldValue < mission.storageId or oldValue > mission.endValue + end + end + end + end + end + end + return false +end + +function Game.getQuestsCount(player) + local count = 0 + if Quests then + for id = 1, #Quests do + if player:questIsStarted(id) then + count = count + 1 + end + end + end + return count +end + +function Game.getMissionsCount(player, questId) + local quest = Game.getQuest(questId) + local count = 0 + if quest then + local missions = quest.missions + if missions then + for missionId = 1, #missions do + if player:missionIsStarted(questId, missionId) then + count = count + 1 + end + end + end + end + return count +end + +function Game.addQuest(quest) + local findQuest = Game.getQuestIdByName(quest.name) + if findQuest then + Quests[findQuest] = quest + return findQuest + end + + local questId = #Quests + 1 + Quests[questId] = quest + return questId +end + +-- Player functions + +function Player.questIsStarted(self, questId) + local quest = Game.getQuest(questId) + if quest and self:getStorageValue(quest.startStorageId) ~= -1 or self:getStorageValue(quest.startStorageId) >= quest.startStorageValue then + return true + end + return false +end + +function Player.missionIsStarted(self, questId, missionId) + local mission = Game.getMission(questId, missionId) + if mission then + local value = self:getStorageValue(mission.storageId) + if value == -1 or value < mission.startValue or (not mission.ignoreendvalue and value > mission.endValue) then + return false + end + + return true + end + return false +end + +function Player.questIsCompleted(self, questId) + local quest = Game.getQuest(questId) + if quest then + local missions = quest.missions + if missions then + for missionId = 1, #missions do + if not self:missionIsCompleted(questId, missionId) then + return false + end + end + end + return true + end + return false +end + +function Player.missionIsCompleted(self, questId, missionId) + local mission = Game.getMission(questId, missionId) + if mission then + local value = self:getStorageValue(mission.storageId) + if value == -1 then + return false + end + + if mission.ignoreendvalue then + return value >= mission.endValue + end + + return value == mission.endValue + end + return false +end + +function Player.getMissionName(self, questId, missionId) + local mission = Game.getMission(questId, missionId) + if mission then + if self:missionIsCompleted(questId, missionId) then + return mission.name .. " (completed)" + end + return mission.name + end + return "" +end + +function Player.getMissionId(self, questId, missionId) + local mission = Game.getMission(questId, missionId) + if mission then + return mission.missionId + end + return 0 +end + +function Player.getMissionDescription(self, questId, missionId) + local mission = Game.getMission(questId, missionId) + if mission then + if mission.description then + return evaluateText(mission.description, self) + end + + local value = self:getStorageValue(mission.storageId) + local state = value + if mission.ignoreendvalue and value > table.maxn(mission.states) then + state = table.maxn(mission.states) + end + return evaluateText(mission.states[state], self) + end + return "An error has occurred, please contact a gamemaster." +end + +function Player.sendQuestLog(self) + local msg = NetworkMessage() + msg:addByte(0xF0) + msg:addU16(Game.getQuestsCount(self)) + for questId = 1, #Quests do + if self:questIsStarted(questId) then + msg:addU16(questId) + msg:addString(Quests[questId].name .. (self:questIsCompleted(questId) and " (completed)" or "")) + msg:addByte(self:questIsCompleted(questId)) + end + end + msg:sendToPlayer(self) + msg:delete() +end + +function Player.sendQuestLine(self, questId) + local quest = Game.getQuest(questId) + if quest then + local missions = quest.missions + local msg = NetworkMessage() + msg:addByte(0xF1) + msg:addU16(questId) + msg:addByte(Game.getMissionsCount(self, questId)) + if missions then + for missionId = 1, #missions do + if self:missionIsStarted(questId, missionId) then + msg:addU16(self:getMissionId(questId, missionId)) + msg:addString(self:getMissionName(questId, missionId)) + msg:addString(self:getMissionDescription(questId, missionId)) + end + end + end + + msg:sendToPlayer(self) + msg:delete() + end +end + +function Player.sendTrackedQuests(self, remainingQuests, missions) + local msg = NetworkMessage() + msg:addByte(0xD0) + msg:addByte(0x01) + msg:addByte(remainingQuests) + msg:addByte(#missions) + for _, mission in ipairs(missions) do + msg:addU16(mission.missionId) + msg:addString(mission.questName) + msg:addString(mission.missionName) + msg:addString(mission.missionDesc) + end + msg:sendToPlayer(self) + msg:delete() +end + +function Player.sendUpdateTrackedQuest(self, mission) + local msg = NetworkMessage() + msg:addByte(0xD0) + msg:addByte(0x00) + msg:addU16(mission.missionId) + msg:addString(mission.missionName) + msg:addString(mission.missionDesc) + msg:sendToPlayer(self) + msg:delete() +end + +function Player.updateStorage(self, key, value, oldValue, currentFrameTime) + local playerId = self:getId() + if LastQuestlogUpdate[playerId] ~= currentFrameTime and Game.isQuestStorage(key, value, oldValue) then + LastQuestlogUpdate[playerId] = currentFrameTime + self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your questlog has been updated.") + end + local missions = self:getMissionsData(key) + for i = 1, #missions do + local mission = missions[i] + if self:hasTrackingQuest(mission.missionId) then + self:sendUpdateTrackedQuest(mission) + end + end +end + +local function sendPrint(questId, index) + Spdlog.warn(string.format("[sendPrint] - Quest id:[%d] mission:[%d]", + questId, index)) +end + +for questId = 1, #Quests do + local quest = Game.getQuest(questId) + if quest then + for index, value in ipairs(quest.missions) do + if index then + if not value.name then + Spdlog.warn("Quest.load: Wrong mission name found") + sendPrint(questId, index) + end + if not value.storageId then + Spdlog.warn("Quest.load: Wrong mission storage found") + sendPrint(questId, index) + end + if not value.missionId then + Spdlog.warn("Quest.load: Wrong mission id found") + sendPrint(questId, index) + end + if not value.startValue then + Spdlog.warn("Quest.load: Wrong mission start value found") + sendPrint(questId, index) + end + if not value.endValue then + Spdlog.warn("Quest.load: Wrong mission end value found") + sendPrint(questId, index) + end + end + end + end +end diff --git a/data/lib/core/storages.lua b/data/lib/core/storages.lua new file mode 100644 index 00000000000..25ea1ad8bec --- /dev/null +++ b/data/lib/core/storages.lua @@ -0,0 +1,2429 @@ +--[[ +Reserved player action storage key ranges (const.h) + It is possible to place the storage in a quest door, so the player who has that storage will go through the door + + Reserved player action storage key ranges (const.h at the source) + [10000000 - 20000000] + [1000 - 1500] + [2001 - 2011] + + Others reserved player action/storages + [100] = unmoveable/untrade/unusable items + [101] = use pick floor + [102] = well down action + [103-120] = others keys action + [103] = key 0010 + [303] = key 0303 + [1000] = level door. Here 1 must be used followed by the level. + Example: 1010 = level 10, + 1100 = level 100] + + [3001-3008] = key 3001/3008 + [3012] = key 3012 + [3033] = key 3033 + [3100] = key 3100 + [3142] = key 3142 + [3200] = key 3200 + [3301] = key 3301 + [3302] = key 3302 + [3303] = key 3303 + [3304] = key 3304 + [3350] = key 3350 + [3520] = key 3520 + [3600] = key 3600 + [3610] = key 3610 + [3620] = key 3620 + [3650] = key 3650 + [3666] = key 3666 + [3667] = key 3667 + [3700] = key 3700 + [3701/3703] = key 3701/3703 + [3800/3802] = key 3800/3802 + [3899] = key 3899 + [3900] = key 3900 + [3909/3917] = key 3909/3917 + [3923] = key 3923 + [3925] = key 3925 + [3930] = key 3930 + [3932] = key 3932 + [3934] = key 3934 + [3935] = key 3935 + [3936] = key 3936 + [3938] = key 3938 + [3940] = key 3940 + [3950] = key 3950 + [3960] = key 3960 + [3980] = key 3980 + [3988] = key 3988 + [4001] = key 4001 + [4009] = key 4009 + [4022] = key 4022 + [4023] = key 4023 + [4033] = key 4033 + [4037] = key 4037 + [4055] = key 4055 + [4210] = key 4210 + [4501] = key 4501 + [4502] = key 4502 + [4503] = key 4503 + [4600] = key 4600 + [4601] = key 4601 + [4603] = key 4603 + [5000] = key 5000 + [5002] = key 5002 + [5010] = key 5010 + [5050] = key 5050 + [6010] = key 6010 + + Questline = Storage through the Quest +]] + +Storage = { + -- General storages + isTraining = 30000, + NpcExhaust = 30001, + NpcExhaustOnBuy = 30002, + Dragonfetish = 30003, + EdronRopeQuest = 30004, + GhostShipQuest = 30005, + OrcKingGreeting = 30006, + MarkwinGreeting = 30007, + -- empty = 30008 + WagonTicket = 30009, + BloodHerbQuest = 30010, + firstMageWeapon = 30011, + toOutfoxAFoxQuest = 30012, + KawillBlessing = 30014, + RentedHorseTimer = 30015, + FountainOfLife = 30016, + KnightwatchTowerDoor = 30017, + -- Promotion Storage cannot be changed, it is set in source code + Promotion = 30018, + RookgaardHints = 30019, + RookgaardDestiny = 30020, + EruaranGreeting = 30021, + MaryzaCookbook = 30022, + combatProtectionStorage = 30023, + Factions = 30024, + blockMovementStorage = 30025, + PetSummon = 30026, + TrainerRoom = 30027, + NpcSpawn = 30028, + ExerciseDummyExhaust = 30029, + SamsOldBackpack = 30030, + SamsOldBackpackDoor = 30031, + StrawberryCupcake = 30032, + ChayenneReward = 30033, + SwampDiggingTimeout = 30034, + HydraEggQuest = 30035, + Atrad = 30036, + ElementalistQuest1 = 30037, + ElementalistQuest2 = 30038, + ElementalistQuest3 = 30039, + ElementalistOutfitStart = 30040, + WayfarerOutfit = 30041, + DreamOutfit = 30042, + Percht1 = 30043, + Percht2 = 30044, + Percht3 = 30045, + Irmana1 = 30046, + Irmana2 = 30047, + Navigator = 30048, + DwarvenLegs = 30049, + PrinceDrazzakTime = 30050, + StoreExaust = 30051, + LemonCupcake = 30052, + BlueberryCupcake = 30053, + PetSummonEvent10 = 30054, + PetSummonEvent60 = 30055, + FreeQuests = 990000, + PremiumAccount = 998899, + + --[[ + Old storages + Over time, this will be dropped and replaced by the table above + ]] + DeeplingsWorldChange = { + -- Reserved storage from 50000 - 50009 + Questline = 50000, + FirstStage = 50001, + SecondStage = 50002, + ThirdStage = 50003, + Crystal = 50004 + }, + LiquidBlackQuest = { + -- Reserved storage from 50010 - 50014 + Questline = 50010, + Visitor = 50011 + }, + Kilmaresh = { + -- Reserved storage from 50015 - 50049 + Questline = 50015, + First = { + Title = 50016 + }, + Second = { + Investigating = 50017 + }, + Third = { + Recovering = 50018 + }, + Fourth = { + Moe = 50019, + MoeTimer = 50020 + }, + Fifth = { + Memories = 50021, + MemoriesShards = 50022 + }, + Sixth = { + Favor = 50023, + FourMasks = 50024, + BlessedStatues = 50025 + }, + Set = { + Ritual = 50026 + }, + Eighth = { + Yonan = 50027, + Narsai = 50028, + Shimun = 50029, + Tefrit = 50030 + }, + Nine = { + Owl = 50031 + }, + Tem = { + Bleeds = 50032 + }, + Eleven = { + Basin = 50033 + }, + Twelve = { + Boss = 50034, + Bragrumol = 50035, + Mozradek = 50036, + Xogixath = 50037 + }, + Thirteen = { + Fafnar = 50038, + Lyre = 50039, + Presente = 50040 + }, + Fourteen = { + Remains = 50041 + }, + UrmahlulluTimer = 50042 + }, + TheSecretLibrary = { + -- Reserved storage from 50050 - 50069 + TheOrderOfTheFalcon = { + OberonTimer = 50050 + }, + LiquidDeath = 50051, + Mota = 50052, + MotaDoor = 50053, + BasinDoor = 50054, + SkullDoor = 50055, + TheLament = 50056, + GreenTel = 50057, + BlueTel = 50058, + BlackTel = 50059, + PinkTel = 50060, + Peacock = 50061, + HighDry = 50062 + }, + DeeplingBosses = { + -- Reserved storage from 50070 - 50079 + Jaul = 50070, + Tanjis = 50071, + Obujos = 50072, + DeeplingStatus = 50073 + }, + DangerousDepths = { + -- Reserved storage from 50080 - 50199 + Questline = 50080, + Dwarves = { + Status = 50081, + Home = 50082, -- Mission + Subterranean = 50083, -- Mission + LostExiles = 50084, + Prisoners = 50085, + Organisms = 50086, + TimeTaskHome = 50087, + TimeTaskSubterranean = 50088 + }, + Scouts = { + Status = 50090, + Diremaw = 50091, -- Mission + Growth = 50092, -- Mission + DiremawsCount = 50093, + GnomishChest = 50094, + BarrelCount = 50095, + FirstBarrel = 50096, + SecondBarrel = 50097, + ThirdBarrel = 50098, + FourthBarrel = 50099, + FifthBarrel = 50100, + TimeTaskDiremaws = 50101, + TimeTaskGrowth = 50102, + Barrel = 50103, + BarrelTimer = 50104 + }, + Gnomes = { + Status = 50115, + Ordnance = 50116, -- Mission + Measurements = 50117, -- Mission + Charting = 50118, -- Mission + GnomeChartChest = 50119, -- Measurements + GnomeChartPaper = 50120, -- Charting + GnomesCount = 50121, -- Ordnance + CrawlersCount = 50122, -- Ordnance + LocationA = 50123, -- Measurements + LocationB = 50124, -- Measurements + LocationC = 50125, -- Measurements + LocationD = 50126, -- Measurements + LocationE = 50127, -- Measurements + LocationCount = 50128, -- Measurements + OldGate = 50129, -- Charting + TheGaze = 50130, -- Charting + LostRuin = 50131, -- Charting + Outpost = 50132, -- Charting + Bastion = 50133, + -- Charting + BrokenTower = 50134, -- Charting + ChartingCount = 50135, -- Contador + TimeTaskOrdnance = 50136, + TimeTaskMeasurements = 50137, + TimeTaskCharting = 50138 + }, + Access = { + LavaPumpWarzoneVI = 50139, + TimerWarzoneVI = 50140, + LavaPumpWarzoneV = 50141, + TimerWarzoneV = 50142, + LavaPumpWarzoneIV = 50143, + TimerWarzoneIV = 50144 + }, + Crystals = { + WarzoneVI = { + BigCrystal1 = 50155, + BigCrystal2 = 50156, + MediumCrystal1 = 50157, + MediumCrystal2 = 50158, + SmallCrystal1 = 50159, + SmallCrystal2 = 50160 + }, + WarzoneV = { + BigCrystal1 = 50165, + BigCrystal2 = 50166, + MediumCrystal1 = 50167, + MediumCrystal2 = 50168, + SmallCrystal1 = 50169, + SmallCrystal2 = 50170 + }, + WarzoneIV = { + BigCrystal1 = 50175, + BigCrystal2 = 50176, + MediumCrystal1 = 50177, + MediumCrystal2 = 50178, + SmallCrystal1 = 50179, + SmallCrystal2 = 50180 + } + }, + Bosses = { + TheCountOfTheCore = 50185, + TheDukeOfTheDepths = 50186, + TheBaronFromBelow = 50187, + TheCountOfTheCoreAchiev = 50188, + TheDukeOfTheDepthsAchiev = 50189, + TheBaronFromBelowAchiev = 50190, + LastAchievement = 50191 + } + }, + CultsOfTibia = { + -- Reserved storage from 50200 - 50269 + Questline = 50200, + Minotaurs = { + EntranceAccessDoor = 50201, + JamesfrancisTask = 50202, + Mission = 50203, + BossTimer = 50204, + AccessDoor = 50205 + }, + MotA = { + Mission = 50210, + Stone1 = 50211, + Stone2 = 50212, + Stone3 = 50213, + Answer = 50214, + QuestionId = 50215, + AccessDoorInvestigation = 50216, + AccessDoorGareth = 50217, + AccessDoorDenominator = 50218 + }, + Barkless = { + Mission = 50225, + sulphur = 50226, + Tar = 50227, + Ice = 50228, + Death = 50229, + Objects = 50230, + Temp = 50231, + BossTimer = 50232, + TrialAccessDoor = 50233, + TarAccessDoor = 50234, + AccessDoor = 50235, + BossAccessDoor = 50236 + }, + Orcs = { + Mission = 50240, + LookType = 50241, + BossTimer = 50242 + }, + Life = { + Mission = 50245, + BossTimer = 50246, + AccessDoor = 50247 + }, + Humans = { + Mission = 50250, + Vaporized = 50251, + Decaying = 50252, + BossTimer = 50253 + }, + Misguided = { + Mission = 50255, + Monsters = 50256, + Exorcisms = 50257, + Time = 50258, + BossTimer = 50259, + AccessDoor = 50260 + }, + FinalBoss = { + Mission = 50261, + BossTimer = 50262, + AccessDoor = 50263 + } + }, + ThreatenedDreams = { + -- Reserved storage from 50270 - 50349 + Start = 50270, + TroubledMission01 = 50271, + TroubledMission02 = 50272, + TroubledMission03 = 50273, + FairyMission01 = 50274, + FairyMission02 = 50275, + FairyMission03 = 50276, + FairyMission04 = 50277, + DreamMission01 = 50278, + DreamCounter = 50279, + KroazurTimer = 50280, + CoupleMission01 = 50281, + CoupleMission02 = 50282, + FacelessBaneTime = 50283, + Reward01 = 50284, + Reward02 = 50285, + Reward03 = 50286, + TatteredSwanFeathers = 50300, + TatteredSwanFeathers01 = 50301, + TatteredSwanFeathers02 = 50302, + TatteredSwanFeathers03 = 50303, + TatteredSwanFeathers04 = 50304, + TatteredSwanFeathers05 = 50305 + }, + FirstDragon = { + -- Reserved storage from 50350 - 50379 + Questline = 50350, + DragonCounter = 50351, + ChestCounter = 50352, + TazhadurTimer = 50353, + KalyassaTimer = 50354, + SecretsCounter = 50355, + GelidrazahAccess = 50356, + GelidrazahTimer = 50357, + DesertTile = 50358, + StoneSculptureTile = 50359, + SuntowerTile = 50360, + ZorvoraxTimer = 50361, + Horn = 50362, + Scale = 50363, + Bones = 50364, + Tooth = 50365, + AccessCave = 50366, + SomewhatBeatable = 50367, + FirstDragonTimer = 50368, + RewardFeather = 50369, + RewardMask = 50370, + RewardBackpack = 50371 + }, + Grimvale = { + -- Reserved storage from 50380 - 50399 + SilverVein = 50380, + WereHelmetEnchant = 50381 + }, + HeroRathleton = { + -- Reserved storage from 50400 - 50419 + QuestLine = 50400, + VotesCasted = 50401, + Rank = 50402, + AccessDoor = 50403, + AccessTeleport1 = 50404, + AccessTeleport2 = 50405, + AccessTeleport3 = 50406 + }, + FerumbrasAscension = { + -- Reserved storage from 50420 - 50469 + RiftRunner = 50420, -- Scroll + TheShattererTimer = 50421, + TheLordOfTheLiceTimer = 50422, + TarbazTimer = 50423, + RazzagornTimer = 50424, + RagiazTimer = 50425, + ZamuloshTimer = 50426, + ShulgraxTimer = 50427, + MazoranTimer = 50428, + PlagirathTimer = 50429, + FerumbrasTimer = 50430, + Tarbaz = 50431, + Razzagorn = 50432, + Ragiaz = 50433, + Zamulosh = 50434, + Shulgrax = 50435, + Mazoran = 50436, + Plagirath = 50437, + Access = 50438, + TheShatterer = 50439, + ZamuloshTeleports = 50440, + BasinCounter = 50441, + TheLordOfTheLiceAccess = 50442, + FirstDoor = 50443, + MonsterDoor = 50444, + TarbazDoor = 50445, + HabitatsAccess = 50446, + HabitatsTimer = 50447, + TarbazNotes = 50448, + ColorLever = 50449, + BoneFluteWall = 50450, + BoneFlute = 50451, + Ring = 50452, + Statue = 50453, + Fount = 50454, + Vampire = 50455, + Flower = 50456, + Ring2 = 50457, + Bone = 50458, + Reward = 50459 + }, + ForgottenKnowledge = { + -- Reserved storage from 50470 - 50519 + AccessDeath = 50470, + AccessViolet = 50471, + AccessEarth = 50472, + AccessFire = 50473, + AccessIce = 50474, + AccessGolden = 50475, + AccessLast = 50476, + OldDesk = 50477, + GirlPicture = 50478, + SilverKey = 50479, + Phial = 50480, + BirdCounter = 50481, + PlantCounter = 50482, + GoldenServantCounter = 50483, + DiamondServantCounter = 50484, + AccessPortals = 50485, + AccessMachine = 50486, + LadyTenebrisTimer = 50487, + LadyTenebrisKilled = 50488, + LloydTimer = 50489, + LloydKilled = 50490, + ThornKnightTimer = 50491, + ThornKnightKilled = 50492, + DragonkingTimer = 50493, + DragonkingKilled = 50494, + HorrorTimer = 50495, + HorrorKilled = 50496, + TimeGuardianTimer = 50497, + TimeGuardianKilled = 50498, + LastLoreTimer = 50499, + LastLoreKilled = 50501, + BirdCage = 50502, + AccessLavaTeleport = 50503, + Ivalisse = 50504, + Chalice = 50505, + Tomes = 50506, + BabyDragon = 50507, + SpiderWeb = 50508 + }, + SweetyCyclops = { + -- Reserved storage from 50520 - 50529 + AmuletTimer = 50520, + AmuletStatus = 50521 + }, + ExplorerSociety = { + -- Reserved storage from 50530 - 50599 + QuestLine = 50530, + SpectralStone = 50531, + SkullOfRatha = 50532, + GiantSmithHammer = 50533, + JoiningTheExplorers = 505344, + TheIceDelivery = 50535, + TheButterflyHunt = 50536, + ThePlantCollection = 50537, + TheLizardUrn = 50538, + TheBonelordSecret = 50539, + TheOrcPowder = 50540, + CalassaQuest = 50541, + TheMemoryStone = 50542, + TheRuneWritings = 50543, + TheEctoplasm = 50544, + TheSpectralDress = 50545, + TheSpectralStone = 50546, + TheAstralPortals = 50547, + TheIslandofDragons = 50548, + TheIceMusic = 50549, + BansheeDoor = 50550, + BonelordsDoor = 50551, + CalassaDoor = 50552, + MemoryStoneDoor = 50553, + ElvenDoor = 50554, + OrcDoor = 50555, + ChorurnDoor = 50556, + DwacatraDoor = 50557, + FamilyBroochDoor = 50558, + TheElvenPoetry = 50559, + SpectralStoneDoor = 50560, + IceMusicDoor = 50561 + }, + TravellingTrader = { + -- Reserved storage from 50600 - 50619 + Mission01 = 50600, + Mission02 = 50601, + Mission03 = 50602, + Mission04 = 50603, + Mission05 = 50604, + Mission06 = 50605, + Mission07 = 50606, + packageDoor = 50607 + }, + DjinnWar = { + -- Reserved storage from 50620 - 50649 + Faction = { + Greeting = 50620, + MaridDoor = 50621, + EfreetDoor = 50622 + }, + RecievedLamp = 50625, + -- Blue djinn + MaridFaction = { + Start = 50630, + Mission01 = 50631, + Mission02 = 50632, + RataMari = 50633, + Mission03 = 50634, + DoorToLamp = 50635, + DoorToEfreetTerritory = 50636 + }, + -- Green djinn + EfreetFaction = { + Start = 50640, + Mission01 = 50641, + Mission02 = 50642, + Mission03 = 50643, + DoorToLamp = 50644, + DoorToMaridTerritory = 50645 + } + }, + VampireHunter = { + -- Reserved storage from 50650 - 50659 + Rank = 50650 + }, + BigfootBurden = { + -- Reserved storage from 50660 - 50719 + QuestLine = 50660, + Test = 50661, + Shooting = 50662, + QuestLineComplete = 50663, + MelodyTone1 = 50664, + MelodyTone2 = 50665, + MelodyTone3 = 50666, + MelodyTone4 = 50667, + MelodyTone5 = 50668, + MelodyTone6 = 50669, + MelodyTone7 = 50670, + MelodyStatus = 50671, + Rank = 50672, + MissionCrystalKeeper = 50673, + CrystalKeeperTimout = 50674, + RepairedCrystalCount = 50675, + MissionRaidersOfTheLostSpark = 50676, + ExtractedCount = 50677, + RaidersOfTheLostSparkTimeout = 50678, + MissionExterminators = 50679, + ExterminatedCount = 50680, + ExterminatorsTimeout = 50681, + MissionMushroomDigger = 50682, + MushroomCount = 50683, + MushroomDiggerTimeout = 50684, + MissionMatchmaker = 50685, + MatchmakerStatus = 50686, + MatchmakerIdNeeded = 50687, + MatchmakerTimeout = 50688, + MissionTinkersBell = 50689, + GolemCount = 50690, + TinkerBellTimeout = 50691, + MissionSporeGathering = 50692, + SporeCount = 50693, + SporeGatheringTimeout = 50694, + MissionGrindstoneHunt = 50695, + GrindstoneStatus = 50696, + GrindstoneTimeout = 50697, + WarzoneStatus = 50698, + Warzone1Access = 50699, + Warzone2Access = 50700, + Warzone3Access = 50701, + Warzone1Reward = 50702, + Warzone2Reward = 50703, + Warzone3Reward = 50704, + BossKills = 50705, + DoorGoldenFruits = 50706, + BossWarzone1 = 50707, + BossWarzone2 = 50708, + BossWarzone3 = 50709 + }, + TheirMastersVoice = { + -- Reserved storage from 50720 - 50739 + SlimeGobblerTimeout = 50720, + SlimeGobblerReceived = 50721 + }, + KosheiTheDeathless = { + -- Reserved storage from 50740 - 50749 + RewardDoor = 50740 + }, + ElementalSphere = { + -- Reserved storage from 50750 - 50759 + QuestLine = 50750, + BossStorage = 50751, + MachineGemCount = 50752 + }, + GravediggerOfDrefia = { + -- Reserved storage from 50760 - 50849 + QuestStart = 50760, + Mission01 = 50761, + Mission02 = 50762, + Mission03 = 50763, + Mission04 = 50764, + Mission05 = 50765, + Mission06 = 50766, + Mission07 = 50767, + Mission08 = 50768, + Mission09 = 50769, + Mission10 = 50770, + Mission11 = 50771, + Mission12 = 50772, + Mission13 = 50773, + Mission14 = 50774, + Mission15 = 50775, + Mission16 = 50776, + Mission17 = 50777, + Mission18 = 50778, + Mission19 = 50779, + Mission20 = 50780, + Mission21 = 50781, + Mission22 = 50782, + Mission23 = 50783, + Mission24 = 50784, + Mission25 = 50785, + Mission26 = 50786, + Mission27 = 50787, + Mission28 = 50788, + Mission29 = 50789, + Mission30 = 50790, + Mission31 = 50791, + Mission32 = 50792, + Mission32a = 50793, + Mission32b = 50794, + Mission33 = 50795, + Mission34 = 50796, + Mission35 = 50797, + Mission36 = 50798, + Mission36a = 50799, + Mission37 = 50800, + Mission38 = 50801, + Mission38a = 50802, + Mission38b = 50803, + Mission38c = 50804, + Mission39 = 50805, + Mission40 = 50806, + Mission41 = 50807, + Mission42 = 50808, + Mission43 = 50809, + Mission44 = 50810, + Mission45 = 50811, + Mission46 = 50812, + Mission47 = 50813, + Mission48 = 50814, + Mission49 = 50815, + Mission50 = 50816, + Mission51 = 50817, + Mission50 = 50818, + Mission53 = 50819, + Mission54 = 50820, + Mission55 = 50821, + Mission56 = 50822, + Mission57 = 50823, + Mission58 = 50824, + Mission59 = 50825, + Mission60 = 50826, + Mission61 = 50827, + Mission62 = 50828, + Mission63 = 50829, + Mission64 = 50830, + Mission65 = 50831, + Mission66 = 50832, + Mission67 = 50833, + Mission68 = 50834, + Mission69 = 50835, + Mission70 = 50836, + Mission71 = 50837, + Mission72 = 50838, + Mission73 = 50839, + Mission74 = 50840, + Bookcase = 50841 + }, + Oramond = { + -- Reserved storage from 50850 - 50879 + QuestLine = 50850, + VotingPoints = 50851, + MissionToTakeRoots = 50852, + HarvestedRootCount = 50853, + TaskProbing = 50854, + DoorBeggarKing = 50855, + MissionAbandonedSewer = 50856, + DoorAbandonedSewer = 50857 + }, + DarkTrails = { + -- Reserved storage from 50880 - 50909 + Mission01 = 50881, + Mission02 = 50882, + Mission03 = 50883, + Mission04 = 50884, + Mission05 = 50885, + Mission06 = 50886, + Mission07 = 50887, + Mission08 = 50888, + Mission09 = 50889, + Mission10 = 50890, + Mission11 = 50891, + Mission12 = 50892, + Mission13 = 50893, + Mission14 = 50894, + Mission15 = 50895, + Mission16 = 50896, + Mission17 = 50897, + Mission18 = 50898, + Outfit = 50899, -- final storage + DoorQuandon = 50901, + DoorHideout = 50902 + }, + SpikeTaskQuest = { + -- Reserved storage from 50910 - 50959 + QuestLine = 50910, + Gnomilly = 50911, + Gnombold = { + Points = 50912, + Nests = 50913, + Fertilise = 50914, + Kill = 50915, + Charges = 50916 + }, + Gnomargery = { + Points = 50920, + Deliver = 50921, + Undercover = 50922, + Temperature = 50923, + Kill = 50924 + } + }, + OutfitQuest = { + -- Reserved storage from 50960 - 51039 + -- Until all outfit quests are completed + DefaultStart = 50960, + Ref = 50961, + Afflicted = { + Outfit = 50962, + AddonPlagueMask = 50963, + AddonPlagueBell = 50964 + }, + Citizen = { + -- Mission storages for temporary questlog entries + MissionHat = 50966, + AddonHat = 50967, + MissionBackpack = 50968, + AddonBackpack = 50969, + AddonBackpackTimer = 50970 + }, + -- Begger Outfit Quest + BeggarFirstAddonDoor = 50975, -- Staff quest + BeggarSecondAddon = 50976, + -- Druid-outfit Quest + DruidHatAddon = 50977, + DruidBodyAddon = 50978, + DruidAmuletDoor = 50979, + -- Barbarian-outfit Quest + BarbarianAddon = 50980, + BarbarianAddonWaitTimer = 50981, + -- Beggar + BeggarOutfit = 50982, + BeggarOutfitTimer = 50983, + -- Hunter-outfit Quest + HunterMusicSheet01 = 50984, + HunterMusicSheet02 = 50985, + HunterMusicSheet03 = 50986, + HunterMusicSheet04 = 50987, + HunterBodyAddon = 50988, + HunterHatAddon = 50989, + Hunter = { + AddonGlove = 50990, + AddonHat = 50991 + }, + Knight = { + AddonSword = 50992, + MissionHelmet = 50993, + AddonHelmet = 50994, + AddonHelmetTimer = 50995, + RamsaysHelmetDoor = 50996 + }, + MageSummoner = { + AddonWand = 50997, + AddonBelt = 50998, + MissionHatCloak = 50999, + AddonHatCloak = 51000, + AddonWandTimer = 51001 + }, + -- Nobleman Outfit + NoblemanFirstAddon = 51002, + NoblemanSecondAddon = 51003, + -- Norseman-outfit Quest + NorsemanAddon = 51004, + -- Warrior-outfit Quest + WarriorShoulderAddon = 51005, + WarriorSwordAddon = 51006, + WarriorShoulderTimer = 51007, + -- Wizard-outfit Quest + WizardAddon = 51008, + -- Pirate-outfit Quest + PirateBaseOutfit = 51009, + PirateSabreAddon = 51010, + PirateHatAddon = 51011, + -- Assassin Outfit + AssassinBaseOutfit = 51012, + AssassinFirstAddon = 51013, + AssassinSecondAddon = 51014, + -- Golden Outfit + GoldenOutfit = 51015, + NightmareOutfit = 51016, + NightmareDoor = 51017, + BrotherhoodOutfit = 51018, + BrotherhoodDoor = 51019, + Shaman = { + AddonStaffMask = 51020, + MissionStaff = 51021, + MissionMask = 51022 + }, + DeeplingAnchor = 51023, + FirstOrientalAddon = 51024, + SecondOrientalAddon = 51025 + }, + TheAncientTombs = { + -- Reserved storage from 50940 - 51059 + DefaultStart = 50940, + VashresamunInstruments = 50941, + VashresamunsDoor = 50942, + MorguthisBlueFlameStorage1 = 50943, + MorguthisBlueFlameStorage2 = 50944, + MorguthisBlueFlameStorage3 = 50945, + MorguthisBlueFlameStorage4 = 50946, + MorguthisBlueFlameStorage5 = 50947, + MorguthisBlueFlameStorage6 = 50948, + MorguthisBlueFlameStorage7 = 50949, + + OmrucsTreasure = 50950, + ThalasTreasure = 50951, + DiphtrahsTreasure = 50952, + MahrdisTreasure = 50953, + VashresamunsTreasure = 50954, + MorguthisTreasure = 50955, + RahemosTreasure = 50956 + }, + TheApeCity = { + -- Reserved storage from 51060 - 51079 + Started = 51060, + Questline = 51061, + DworcDoor = 51062, + ChorDoor = 51063, + ParchmentDecyphering = 51064, + FibulaDoor = 51065, + WitchesCapSpot = 51066, + CasksDoor = 51067, + Casks = 51068, + HolyApeHair = 51069, + SnakeDestroyer = 51070, + ShamanOufit = 51071 + }, + TheNewFrontier = { + -- Reserved storage from 51080 - 51109 + Questline = 51080, + Mission01 = 51081, + Mission02 = 51082, + Mission03 = 51083, + Mission04 = 51084, + Mission05 = 51085, + Mission06 = 51086, + Mission07 = 51087, + Mission08 = 51088, + Mission09 = 51089, + Mission10 = 51090, + TomeofKnowledge = 51091, + Beaver1 = 51092, + Beaver2 = 51093, + Beaver3 = 51094, + BribeKing = 51095, + BribeLeeland = 51096, + BribeExplorerSociety = 51097, + BribeWydrin = 51098, + BribeTelas = 51099, + BribeHumgolf = 51100 + }, + TheInquisition = { + -- Reserved storage from 51110 - 51139 + Questline = 51110, + Mission01 = 51111, + Mission02 = 51112, + Mission03 = 51113, + Mission04 = 51114, + Mission05 = 51115, + Mission06 = 51116, + Mission07 = 51117, + RewardDoor = 51118, + GrofGuard = 51120, + KulagGuard = 51121, + MilesGuard = 51122, + TimGuard = 51123, + WalterGuard = 51124, + StorkusVampiredust = 51125, + EnterTeleport = 51126, + Reward = 51127, + RewardRoomText = 51128 + }, + BarbarianTest = { + -- Reserved storage from 51140 - 51159 + Questline = 51140, + Mission01 = 51141, + Mission02 = 51142, + Mission03 = 51143, + MeadTotalSips = 51144, + MeadSuccessSips = 51145 + }, + TheIceIslands = { + -- Reserved storage from 51160 - 51199 + Questline = 51160, + Mission01 = 51161, -- Befriending the Musher + Mission02 = 51162, -- Nibelor 1: Breaking the Ice + Mission03 = 51163, -- Nibelor 2: Ecological Terrorism + Mission04 = 51164, -- Nibelor 3: Artful Sabotage + Mission05 = 51165, -- Nibelor 4: Berserk Brewery + Mission06 = 51166, -- Nibelor 5: Cure the Dogs + Mission07 = 51167, -- The Secret of Helheim + Mission08 = 51168, -- The Contact + Mission09 = 51169, -- Formorgar Mines 1: The Mission + Mission10 = 51170, -- Formorgar Mines 2: Ghostwhisperer + Mission11 = 51171, -- Formorgar Mines 3: The Secret + Mission12 = 51172, -- Formorgar Mines 4: Retaliation + PickAmount = 51173, + PaintSeal = 51174, + SulphurLava = 51175, + SporesMushroom = 51176, + FrostbiteHerb = 51177, + FlowerCactus = 51178, + FlowerBush = 51179, + MemoryCrystal = 51180, + Obelisk01 = 51181, + Obelisk02 = 51182, + Obelisk03 = 51183, + Obelisk04 = 51184, + yakchalDoor = 51185 + }, + TheWayToYalahar = { + -- Reserved storage from 51200 - 51209 + QuestLine = 51200 + }, + InServiceofYalahar = { + -- Reserved storage from 51210 - 51259 + Questline = 51210, + Mission01 = 51211, + Mission02 = 51212, + Mission03 = 51213, + Mission04 = 51214, + Mission05 = 51215, + Mission06 = 51216, + Mission07 = 51217, + Mission08 = 51218, + Mission09 = 51219, + Mission10 = 51220, + SewerPipe01 = 51221, + SewerPipe02 = 51222, + SewerPipe03 = 51223, + SewerPipe04 = 51224, + DiseasedDan = 51225, + DiseasedBill = 55226, + DiseasedFred = 55227, + AlchemistFormula = 51228, + BadSide = 51229, + GoodSide = 55230, + MrWestDoor = 51231, + MrWestStatus = 51232, + TamerinStatus = 55233, + MorikSummon = 51234, + QuaraState = 51235, + QuaraSplasher = 51236, + QuaraSharptooth = 51237, + QuaraInky = 51238, + MatrixState = 51239, + SideDecision = 51240, + MatrixReward = 51241, + NotesPalimuth = 51242, + NotesAzerus = 51243, + DoorToAzerus = 51244, + DoorToBog = 55136, + DoorToLastFight = 55137, + DoorToMatrix = 51247, + DoorToQuara = 51248, + DoorToReward = 51249 + }, + ChildrenoftheRevolution = { + -- Reserved storage from 55145 - 51279 + Questline = 55145, + Mission00 = 55146, -- Prove Your Worzz! + Mission01 = 51262, + Mission02 = 51263, + Mission03 = 51264, + Mission04 = 55148, + Mission05 = 51266, + SpyBuilding01 = 51267, + SpyBuilding02 = 51268, + SpyBuilding03 = 51269, + StrangeSymbols = 55154 + }, + UnnaturalSelection = { + -- Reserved storage from 55159 - 51299 + Questline = 55159, + Mission01 = 51281, + Mission02 = 51282, + Mission03 = 51283, + Mission04 = 51284, + Mission05 = 51285, + Mission06 = 51286, + DanceStatus = 51287 + }, + WrathoftheEmperor = { + -- Reserved storage from 51300 - 51339 + Questline = 51300, + Mission01 = 51301, + Mission02 = 51302, + Mission03 = 51303, + Mission04 = 51304, + Mission05 = 51305, + Mission06 = 51306, + Mission07 = 51307, + Mission08 = 51308, + Mission09 = 51309, + Mission10 = 51310, + Mission11 = 51311, + Mission12 = 51312, + CrateStatus = 51313, --1068 + GuardcaughtYou = 51314, --1062 + ZumtahStatus = 51315, --1066 + PrisonReleaseStatus = 51316, --1067 + GhostOfAPriest01 = 51317, --1070 + GhostOfAPriest02 = 51318, --1071 + GhostOfAPriest03 = 51319, --1072 + InterdimensionalPotion = 51320, --1084 + BossStatus = 51321, --1090 + platinumReward = 51322, + backpackReward = 51323, + mainReward = 51324, + -- never set just added here + TeleportAccess = 51325 + }, + FriendsandTraders = { + -- Reserved storage from 51340 - 51359 + DefaultStart = 51340, + TheSweatyCyclops = 51341, + TheMermaidMarina = 51342, + TheBlessedStake = 51343, + TheBlessedStakeWaitTime = 51344 + }, + Postman = { + -- Reserved storage from 51360 - 51389 + Mission01 = 51360, + Mission02 = 51361, + Mission03 = 51362, + Mission04 = 51363, + Mission05 = 51364, + Mission06 = 51365, + Mission07 = 51366, + Mission08 = 51367, + Mission09 = 51368, + Mission10 = 51369, + Rank = 51370, + Door = 51371, + TravelCarlin = 51372, + TravelEdron = 51373, + TravelVenore = 51374, + TravelCormaya = 51375, + MeasurementsBenjamin = 51376, + MeasurementsKroox = 51377, + MeasurementsDove = 51378, + MeasurementsLiane = 51379, + MeasurementsChrystal = 51380, + MeasurementsOlrik = 51381 + }, + ThievesGuild = { + -- Reserved storage from 515206 - 51409 + Quest = 515206, + Mission01 = 515207, + Mission02 = 515208, + Mission03 = 515209, + Mission04 = 51394, + Mission05 = 56395, + Mission06 = 51396, + Mission07 = 51397, + Mission08 = 51398, + Door = 51399, + Reward = 51400, + TheatreScript = 51401 + }, + TheHuntForTheSeaSerpent = { + -- Reserved storage from 51410 - 51419 + CaptainHaba = 51410 + }, + SecretService = { + -- Reserved storage from 51420 - 51449 + Quest = 51420, + TBIMission01 = 51421, + AVINMission01 = 51422, + CGBMission01 = 51423, + TBIMission02 = 51424, + AVINMission02 = 51425, + CGBMission02 = 51426, + TBIMission03 = 51427, + AVINMission03 = 51428, + CGBMission03 = 51429, + TBIMission04 = 51430, + AVINMission04 = 51431, + CGBMission04 = 51432, + TBIMission05 = 51433, + AVINMission05 = 51434, + CGBMission05 = 51435, + TBIMission06 = 51436, + AVINMission06 = 51437, + CGBMission06 = 51438, + Mission07 = 51439, + RottenTree = 51440 + }, + HiddenCityOfBeregar = { + -- Reserved storage from 51450 - 51479 + DefaultStart = 51450, + WayToBeregar = 51451, + OreWagon = 51452, + GoingDown = 51453, + JusticeForAll = 51454, + GearWheel = 51455, + SweetAsChocolateCake = 51456, + RoyalRescue = 51457, + TheGoodGuard = 51458, + PythiusTheRotten = 51459, + DoorNorthMine = 51460, + DoorWestMine = 51461, + DoorSouthMine = 51462, + BrownMushrooms = 51463 + }, + TibiaTales = { + -- Reserved storage from 51480 - 51539 + DefaultStart = 51480, + ultimateBoozeQuest = 51481, + AgainstTheSpiderCult = 51482, + AnInterestInBotany = 51483, + AnInterestInBotanyChestDoor = 51484, + AritosTask = 51485, + ToAppeaseTheMightyQuest = 51486, + IntoTheBonePit = 51487, + TheExterminator = 51488, + RestInHallowedGround = { + Questline = 51495, + HolyWater = 51496, + Graves = { + Grave1 = 51501, + Grave2 = 51502, + Grave3 = 51503, + Grave4 = 51504, + Grave5 = 51505, + Grave6 = 51506, + Grave7 = 51507, + Grave8 = 51508, + Grave9 = 51509, + Grave10 = 51510, + Grave11 = 51511, + Grave12 = 51512, + Grave13 = 51513, + Grave14 = 51514, + Grave15 = 51515, + Grave16 = 51516 + } + }, + JackFutureQuest = { + QuestLine = 51520, + Furniture01 = 51521, + Furniture02 = 51522, + Furniture03 = 51523, + Furniture04 = 51524, + Furniture05 = 51525, + Mother = 51526, + Sister = 51527, + Statue = 51528, + LastMissionState = 51529 + }, + TheCursedCrystal = { + Oneeyedjoe = 51530, + MedusaOil = 51531, + Questline = 51532 + } + }, + TheShatteredIsles = { + -- Reserved storage from 51540 - 51589 + DefaultStart = 51540, + TheGovernorDaughter = 51541, + TheErrand = 51542, + AccessToMeriana = 51543, + APoemForTheMermaid = 51544, + ADjinnInLove = 51545, + AccessToLagunaIsland = 51546, + AccessToGoroma = 51547, + Shipwrecked = 51548, + DragahsSpellbook = 51549, + TheCounterspell = 51550, + ReputationInSabrehaven = 51551, + RaysMission1 = 51552, + RaysMission2 = 51553, + RaysMission3 = 51554, + RaysMission4 = 51555, + AccessToNargor = 51556, + TortoiseEggNargorDoor = 51557, + TortoiseEggNargorTime = 51558, + YavernDoor = 51559, + TavernMap1 = 51560, + TavernMap2 = 51561, + TavernMap3 = 51562 + }, + SearoutesAroundYalahar = { + -- Reserved storage from 51590 - 51609 + TownsCounter = 51590, + AbDendriel = 51591, + Darashia = 51592, + Venore = 51593, + Ankrahmun = 51594, + PortHope = 51595, + Thais = 51596, + LibertyBay = 51597, + Carlin = 51598 + }, + KillingInTheNameOf = { + -- Reserved storage from 51610 - 51629 + LugriNecromancers = 51610, + LugriNecromancerCount = 51611, + BudrikMinos = 51612, + BudrikMinosCount = 51613, + MissionTiquandasRevenge = 51614, + TiquandasRevengeTeleport = 51615, + MissionDemodras = 51616, + DemodrasTeleport = 51617 + }, + HotCuisineQuest = { + -- Reserved storage from 51650 - 51659 + QuestStart = 51650, + CurrentDish = 51651, + QuestLog = 51652, + CookbookDoor = 51653 + }, + RookgaardTutorialIsland = { + -- Reserved storage from 51660 - 51679 + tutorialHintsStorage = 51665, + SantiagoNpcGreetStorage = 51666, + SantiagoQuestLog = 51667, + cockroachKillStorage = 51668, + cockroachLegsMsgStorage = 51669, + cockroachBodyMsgStorage = 51670, + ZirellaNpcGreetStorage = 51671, + ZirellaQuestLog = 51672, + CarlosNpcGreetStorage = 51677, + CarlosQuestLog = 51678 + }, + TheRookieGuard = { + --Reserved storage 52360 - 52395 + Questline = 52360, + Mission01 = 52361, + Mission02 = 52362, + Mission03 = 52363, + Mission04 = 52364, + Mission05 = 52365, + Mission06 = 52366, + Mission07 = 52367, + Mission08 = 52368, + Mission09 = 52369, + Mission10 = 52370, + Mission11 = 52371, + Mission12 = 52372, + StonePileTimer = 52373, + Catapults = 52374, + RatKills = 52375, + PoacherCorpse = 52376, + LibraryChest = 52377, + TrollChests = 52378, + TunnelPillars = 52379, + Sarcophagus = 52380, + AcademyChest = 52381, + KraknaknorkChests = 52382, + TutorialDelay = 52383, + LibraryDoor = 52384, + UnholyCryptDoor = 52385, + AcademyDoor = 52386, + AcademyChestTimer = 52387, + WarWolfDenChest = 52388, + UnholyCryptChests = 52389, + OrcFortressChests = 52390, + Level8Warning = 52391 + }, + BanutaSecretTunnel = { + -- Reserved storage from 51680 - 51689 + DeeperBanutaShortcut = 51680, + }, + DemonOak = { + -- Reserved storage from 51700 - 51709 + Done = 51700, + Progress = 51701, + Squares = 51702, + AxeBlowsBird = 51703, + AxeBlowsLeft = 51704, + AxeBlowsRight = 51705, + AxeBlowsFace = 51706 + }, + SvargrondArena = { + -- Reserved storage from 51710 - 51729 + Arena = 51710, + PitDoor = 51711, + QuestLogGreenhorn = 51712, + QuestLogScrapper = 51713, + QuestLogWarlord = 51714, + RewardGreenhorn = 51715, + RewardScrapper = 51716, + RewardWarlord = 51717, + TrophyGreenhorn = 51718, + TrophyScrapper = 51719, + TrophyWarlord = 51720, + GreenhornDoor = 51721, + ScrapperDoor = 51722, + WarlordDoor= 51723 + }, + QuestChests = { + -- Reserved storage from 51730 - 51999 + KosheiTheDeathlessLegs = 51730, + KosheiTheDeathlessGold = 51731, + TutorialShovel = 51732, + TutorialRope = 51733, + DemonHelmetQuestDemonShield = 51734, + DemonHelmetQuestDemonHelmet = 51735, + DemonHelmetQuestSteelBoots = 51736, + FormorgarMinesHoistSkeleton = 51737, + FormorgarMinesHoistChest = 51738, + -- Custom Quests, currently not using system.lua (aid 2000) + BlackKnightTreeCrownShield = 51739, + BlackKnightTreeCrownArmor = 51740, + BlackKnightTreeKey = 51741, + KosheiAmulet1 = 51742, + KosheiAmulet2 = 51743, + SilverBrooch = 51744, + FamilyBrooch = 51745, + DCQGhoul = 51746, + FirewalkerBoots = 51747, + DeeperFibulaKey = 51748, + SixRubiesQuest = 51749, + ParchmentRoomQuest = 51750, + WarzoneReward1 = 51751, + WarzoneReward2 = 51752, + WarzoneReward3 = 51753, + FathersBurdenWood = 51754, + FathersBurdenIron = 51755, + FathersBurdenRoot = 5176, + FathersBurdenCrystal = 51757, + FathersBurdenSilk = 51758, + FathersBurdenCloth = 51759, + OutlawCampKey1 = 51760, + OutlawCampKey2 = 51761, + OutlawCampKey3 = 51762, + DoubletQuest = 51763, + HoneyFlower = 51764, + BananaPalm = 51765, + WhisperMoss = 51766, + OldParchment = 51767, + DragahsSpellbook = 51768, + StealFromThieves = 51769 + }, + PitsOfInferno = { + -- Reserved storage from 52000 - 52019 + ShortcutHubDoor = 52000, + ShortcutLeverDoor = 52001, + Pumin = 52002, + WeaponReward = 52003, + ThroneInfernatil = 52004, + ThroneTafariel = 52005, + ThroneVerminor = 52006, + ThroneApocalypse = 52007, + ThroneBazir = 52008, + ThroneAshfalor = 52009, + ThronePumin = 52010 + }, + HorestisTomb = { + -- Reserved storage from 52020 - 52029 + JarFloor1 = 52020, + JarFloor2 = 52021, + JarFloor3 = 52022, + JarFloor4 = 52023, + JarFloor5 = 52024 + }, + WhiteRavenMonastery = { + -- Reserved storage from 52030 - 52039 + QuestLog = 52030, + Passage = 52031, + Diary = 52032, + Door = 52033 + }, + FathersBurden = { + -- Reserved storage from 52040 - 52059 + QuestLog = 52040, + Progress = 52041, + Status = 52042, + Sinew = 52043, + Wood = 52044, + Cloth = 52045, + Silk = 52046, + Crystal = 52047, + Root = 52048, + Iron = 52049, + Scale = 52050, + Corpse = { + Scale = 52051, + Sinew = 52052 + } + }, + WhatAFoolish = { + -- Reserved storage from 52060 - 52099 + Questline = 52060, + Mission1 = 52061, + Mission2 = 52062, + Mission3 = 52063, + Mission4 = 52064, + Mission5 = 52065, + Mission6 = 52066, + Mission7 = 52067, + Mission8 = 52068, + Mission9 = 52069, + Mission10 = 52070, + Mission11 = 52071, + PieBuying = 52072, + PieBoxTimer = 52073, + TriangleTowerDoor = 52074, + EmperorBeardShave = 52075, + JesterOutfit = 52076, + WhoopeeCushion = 52077, + QueenEloiseCatDoor = 52078, + CatBasket = 52079, + ScaredCarina = 52080, + InflammableSulphur = 52081, + SpecialLeaves = 52082, + Cigar = 52083, + Contract = 52084, + CookieDelivery = { + SimonTheBeggar = 52085, + Markwin = 52086, + Ariella = 52087, + Hairycles = 52088, + Djinn = 52089, + AvarTar = 52090, + OrcKing = 52091, + Lorbas = 52092, + Wyda = 52093, + Hjaern = 52094 + }, + OldWornCloth = 52095, + LostDisguise = 52096, + ScaredKazzan = 52097 + }, + SpiritHunters = { + -- Reserved storage from 52100 - 52109 + Mission01 = 52100, + TombUse = 52101, + CharmUse = 52102, + NightstalkerUse = 52103, + SouleaterUse = 52104, + GhostUse = 52105 + }, + SeaOfLight = { + -- Reserved storage from 52110 - 52119 + Questline = 52110, + Mission1 = 52111, + Mission2 = 52112, + Mission3 = 52113, + StudyTimer = 52114, + LostMinesCrystal = 52115 + }, + Diapason = { + -- Reserved storage from 52120 - 52129 + Lyre = 52120, + LyreTimer = 52121, + Edala = 52122, + EdalaTimer = 52123 + }, + AdventurersGuild = { + -- Reserved storage from 52130 - 52159 + Stone = 52130, + MagicDoor = 52131, + CharosTrav = 52132, + FreeStone = { + Alia = 52133, + Amanda = 52134, + Brewster = 52135, + Isimov = 52136, + Kasmir = 52137, + Kjesse = 52138, + Lorietta = 52139, + Maealil = 52140, + Quentin = 52141, + RockWithASoftSpot = 52142, + Tyrias = 52143, + Yberius = 52144, + Rahkem = 52145 + }, + GreatDragonHunt = { + WarriorSkeleton = 52146, + DragonCounter = 52147 + } + }, + DreamersChallenge = { + -- Reserved storage from 52160 - 52199 + LeverNightmare1 = 52160, + LeverNightmare2 = 52161, + LeverNightmare3 = 52162, + LeverBrotherhood1 = 52163, + LeverBrotherhood2 = 52164, + LeverBrotherhood3 = 52165, + TicTac = 52166, + Reward = 52167 + }, + HallsOfHope = { + -- Reserved storage from 52200 - 52219 + Questline = 52200, + Reward1 = 52201, + Reward2 = 52202, + Reward3 = 52203, + Reward4 = 52204, + Reward5 = 52205 + }, + InsectoidCell = { + -- Reserved storage from 52220 - 52249 + Questline = 52220, + Reward1 = 52221, + Reward2 = 52222, + Reward3 = 52223, + Reward4 = 52224, + Reward5 = 52225, + Reward6 = 52226, + Reward7 = 52227, + Reward8 = 52228, + Reward9 = 52229, + Reward10 = 52230, + Reward11 = 52231, + Reward12 = 52232, + Reward13 = 52233, + Reward14 = 52234, + Reward15 = 52235, + Reward16 = 52236 + }, + Dawnport = { + -- Reserved storage from 52250 - 52289 + -- Reward items storages + SorcererHealthPotion = 52251, + SorcererManaPotion = 52252, + SorcererLightestMissile = 52253, + SorcererLightStoneShower = 52254, + SorcererMeat = 52255, + DruidHealthPotion = 52256, + DruidManaPotion = 52257, + DruidLightestMissile = 52258, + DruidLightStoneShower = 52259, + DruidMeat = 52260, + PaladinHealthPotion = 52261, + PaladinManaPotion = 52262, + PaladinLightestMissile = 52263, + PaladinLightStoneShower = 52264, + PaladinMeat = 52265, + KnightHealthPotion = 52266, + KnightManaPotion = 52267, + KnightMeat = 52268, + + Sorcerer = 52269, + Druid = 52270, + Paladin = 52271, + Knight = 52272, + DoorVocation = 52273, + DoorVocationFinish = 52274, + ChestRoomFinish = 52275, + Tutorial = 52276, + MessageStair = 52277, + Lever = 52278, + Mainland = 52279 + }, + LionsRock = { + -- Reserved storage from 52290 - 52309 + Questline = 52290, + LionsStrength = 52291, + LionsBeauty = 52292, + LionsTears = 52293, + GetLionsMane = 52294, + GetHolyWater = 52295, + SnakeSign = 52296, + LizardSign = 52297, + ScorpionSign = 52298, + HyenaSign = 52299, + Time = 52300 + }, + GraveDanger = { + -- Reserved storage from 52310 - 52339 + Questline = 52310, + CobraBastion = { + Questline = 52311, + ScarlettTimer = 52312 + } + }, + RottinWoodAndMaried = { + -- Reserved storage from 52340 - 52349 + Questline = 52340, + RottinStart = 52341, + Trap = 52342, + Corpse = 52343, + Time = 52344, + Mission03 = 52345, + }, + TheMummysCurse = { + -- Reserved storage from 52350 - 52359 + Time1 = 52351, + Time2 = 52352, + Time3 = 52353, + Time4 = 52354, + }, + -- News quest development + -- New storages + Quest = { + Key = { + ID0010 = 103, + ID3001 = 3001, + ID3002 = 3002, + ID3003 = 3003, + ID3004 = 3004, + ID3005 = 3005, + ID3006 = 3006, + ID3007 = 3007, + ID3008 = 3008, + ID3012 = 3012, + ID3620 = 3620, + ID3666 = 3666, + ID3702 = 3702, + ID3800 = 3800, + ID3801 = 3801, + ID3802 = 3802, + ID3899 = 3899, + ID3940 = 3940, + ID3980 = 3980, + ID4055 = 4055, + ID4502 = 4502, + ID5010 = 5010, + ID6010 = 6010 + }, + SimpleChest = { + FamilyBrooch = 9000 + }, + -- update pre-6.0 + DeeperFibula = { + -- 10000 EMPTY + RewardTowerShield = 10001, + RewardWarriorHelmet = 10002, + RewardDwarvenRing = 10003, + RewardElvenAmulet = 10004, + RewardKnightAxe = 10005 + }, + OrnamentedShield = { + Bag = 10006, + RedBag = 10007 + }, + ShortSword = { + Book = 10008 + }, + ThaisLighthouse = { + BattleHammer = 10009, + DarkShield = 10010 + }, + -- update 6.0 + StuddedShield = { + BananaFree = 10011, + BananaPremium = 10012 + }, + -- update 6.1 + EmperorsCookies = { + -- 10013/10015 EMPTY + RopeReward = 10016, + }, + ExplorerBrooch = { + Reward = 10017 + }, + OrcFortress = { + KnightAxe = 10018, + KnightArmor = 10019, + FireSword = 10020 + }, + Panpipe = { + -- 10021 EMPTY + Reward = 10022 + }, + -- update 6.2 + Draconia = { + Reward1 = 10023, + Reward2 = 10024 + }, + -- update 6.4 + AdornedUHRune = { + Reward = 10025 + }, + BarbarianAxe = { + BarbarianAxe = 10026, + Scimitar = 10027 + }, + BerserkerTreasure = { + Reward = 10028 + }, + DarkArmor = { + Reward = 10029 + }, + DemonHelmet = { + SteelBoots = 10030, + DemonHelmet = 10031, + DemonShield = 10032 + }, + DoubleHero = { + RedGem = 10033, + ClubRing = 10034 + }, + EdronGoblin = { + SilverAmulet = 10035, + SteelShield = 10036 + }, + FireAxe = { + Bag = 10037, + FireAxe = 10038 + }, + PoisonDaggers = { + BackpackReward = 10039 + }, + Ring = { + TimeRing = 10040, + SwordRing = 10041 + }, + ShamanTreasure = { + Bag = 10042 + }, + StrongPotions = { + Reward = 10043 + }, + TrollCave = { + GarlicNecklace = 10044, + BrassLegs = 10045 + }, + VampireShield = { + Bag = 10046, + DragonLance = 10047, + VampireShield = 10048 + }, + WeddingRing = { + DragonNecklace = 10049, + WeedingRing = 10050 + }, + -- update 6.5 + AlawarsVault = { + WhitePearl = 10051, + Broadsword = 10052 + }, + -- update 7.1 + BlackKnight = { + -- 10053 EMPTY + CrownArmor = 10054, + CrownShield = 10055 + }, + DragonTower = { + Backpack1 = 10056, + Backpack2 = 10057 + }, + TimeRing = { + CrystallBall = 10058, + TimeRing = 10059, + ElvenAmulet = 10060 + }, + -- update 7.2 + Behemoth = { + Bag = 10061, + GuardianHalberd = 10062, + DemonShield = 10063, + GoldenArmor = 10064 + }, + ParchmentRoom = { + Bag = 10065 + }, + TheQueenOfTheBanshees = { + Reward = { + StoneSkinAmulet = 10066, + StealthRing = 10067, + TowerShield = 10068, + GiantSword = 10069, + BootsOfHaste = 10070, + PlatinumCoin = 10071 + }, + QuestLine = 10072, + FirstSeal = 10073, + FirstSealDoor = 10074, + SecondSeal = 10075, + SecondSealDoor = 10076, + ThirdSeal = 10077, + ThirdSealDoor = 10078, + ThirdSealWarlocks = 10079, + FourthSeal = 10080, + FourthSealDoor = 10081, + FifthSeal = 10082, + FifthSealDoor = 10083, + FifthSealTile = 10084, + SixthSeal = 10085, + SixthSealDoor = 10086, + LastSeal = 10087, + LastSealDoor = 10088, + BansheeDoor = 10089, + FinalBattle = 10090 + }, + -- update 7.24 + GiantSmithhammer = { + QuestLine = 10091, + Talon = 10092, + Hammer = 10093, + GoldCoin = 10094 + }, + MadMageRoom = { + QuestLine = 10095, + APrisoner = 10096, + StarAmulet = 10097, + Hat = 10098, + StoneSkinAmulet = 10099 + }, + SkullOfRatha = { + Bag1 = 10100, + Bag2 = 10101 + }, + TheAnnihilator = { + Reward = 10102 + }, + TheParadoxTower = { + QuestLine = 10103, + TheFearedHugo = 10104, + FirstParadoxAcess = 10105, + FavoriteColour = 10106, + Mathemagics = 10107, + Reward = { + Egg = 10108, + Gold = 10109, + Talon = 10110, + Wand = 10111 + } + }, + ThePostmanMissions = {}, + TheWhiteRavenMonastery = {}, + VoodooDoll = {}, + -- update 7.3 + MedusaShield = {}, + SerpentineTower = {}, + WhitePearl = {}, + -- update 7.4 + TheAncientTombs = {}, + TheDjinnWarEfreetFaction = {}, + TheDjinnWarMaridFaction = {}, + -- update 7.5 + ElephantTusk = {}, + Waterfall = {}, + -- update 7.6 + HydraEgg = {}, + TheApeCity = {}, + TheExplorerSociety = {}, + -- update 7.8 + AssassinOutfits = {}, + BarbarianOutfits = {}, + BeggarOutfits = {}, + CitizenOutfits = {}, + CitizenOutfitsRook = {}, + DruidOutfits = {}, + DruidOutfitsRook = {}, + HunterOutfits = {}, + KnightOutfits = {}, + MageOutfits = {}, + MarlinTrophy = {}, + Meriana = {}, + NoblemanOutfits = {}, + ObsidianKnife = {}, + OrientalOutfits = {}, + PirateOutfits = {}, + ShamanOutfits = {}, + SummonerOutfits = {}, + TheBlessedStake = {}, + TheMermaidMarina = {}, + TheShatteredIsles = {}, + TheSweatyCyclops = {}, + TreasureIsland = {}, + WarriorOutfits = {}, + WizardOutfits = {}, + -- update 7.9 + DreamersChallenge = {}, + ThePitsOfInferno = {}, + -- update 8.0 + BarbarianArena = {}, + BarbarianTest = {}, + BerserkPotion = {}, + FishingBox = {}, + FormorgarMinesHoist = {}, + FormorgarMines = {}, + FrostDragon = {}, + Inukaya = {}, + LionTrophy = {}, + MastermindPotion = {}, + NorsemanOutfits = {}, + Sinatuki = {}, + SkeletonDecoration = {}, + TheIceIslands = {}, + WaterskinOfMead = {}, + -- update 8.1 + AgainstTheSpiderCult = {}, + AritosTask = {}, + BrotherhoodOutfits = {}, + OutfitBrotherhoodMaleAddon = {}, + IntoTheBonePit = {}, + KissingAPig = {}, + KosheiTheDeathless = {}, + NightmareOutfits = {}, + OutfitNightmareMaleAddon = {}, + NomadsLand = {}, + RestInHallowedGround = {}, + SecretService = {}, + StealFromThieves = {}, + TheExterminator = {}, + TheTravellingTrader = {}, + TheUltimateBooze = {}, + ToAppeaseTheMighty = {}, + ToBlindTheEnemy = {}, + ToOutfoxAFox = {}, + TowerDefence = {}, + WhatAFoolish = {}, + -- update 8.2 + ElementalSpheres = {}, + MachineryOfWar = {}, + TheBeginning = {}, + TheDemonOak = {}, + TheHuntForTheSeaSerpent = {}, + TheInquisition = {}, + TheThievesGuild = {}, + TrollSabotage = {}, + VampireHunter = {}, + -- update 8.4 + BloodBrothers = {}, + InServiceOfYalahar = {}, + TheHiddenCityOfBeregar = {}, + TopOfTheCity = {}, + YalaharianOutfits = {}, + -- update 8.5 + Braindeath = {}, + DarashiaDragon = {}, + HotCuisine = {}, + KillingInTheNameOf = {}, + LoneMedusa = {}, + PilgrimageOfAshes = {}, + ShadowsOfYalahar = {}, + TheIsleOfEvil = {}, + TheLightbearer = {}, + TheScatterbrainedSorcerer = {}, + TreasureHunt = {}, + -- update 8.54 + AnUneasyAlliance = {}, + ChildrenOfTheRevolution = {}, + SeaOfLight = {}, + TheNewFrontier = {}, + TomesOfKnowledge = {}, + UnnaturalSelection = {}, + WarmasterOutfits = {}, + -- update 8.6 + AFathersBurden = {}, + AnInterestInBotany = {}, + TheSpiritWillGetYou = {}, + WayfarerOutfits = {}, + WrathOfTheEmperor = {}, + -- update 8.61 + RiseOfDevovorga = {}, + -- update 8.7 + APieceOfCake = {}, + APiratesDeathToMe = {}, + AnnualAutumnVintage = {}, + Bewitched = {}, + DemonsLullaby = {}, + JackToTheFuture = {}, + LastCreepStanding = {}, + ResearchAndDevelopment = {}, + RottinWoodAndTheMarriedMen = {}, + Spirithunters = {}, + TheColoursOfMagic = {}, + --update 9.1 + AfflictedOutfits = {}, + AwashWorldChange = {}, + DemonWarsWorldChange = {}, + ElementalistOutfits = {}, + HorseStationWorldChange = {}, + InsectoidInvasionWorldChange = {}, + LooseEnds = {}, + OverhuntingWorldChange = {}, + SteamshipWorldChange = {}, + SwampFeverWorldChange = {}, + TheMagesTowerWorldChange = {}, + TheMummysCurseWorldChange = {}, + TheRookieGuard = {}, + TheirMastersVoiceWorldChange = {}, + ThornfireWorldChange = {}, + TwistedWatersWorldChange = {}, + -- update 9.4 + BankRobberyMiniWorldChange = {}, + BoredMiniWorldChange = {}, + DeeplingsWorldChange = {}, + DownTheDrainMiniWorldChange = {}, + FireFromTheEarthMiniWorldChange = {}, + HiveBornWorldChange = {}, + InsectoidOutfits = {}, + KingsdayMiniWorldChange = {}, + LiquidBlack = {}, + LumberjackMiniWorldChange = {}, + NomadsMiniWorldChange = {}, + NoodlesIsGoneMiniWorldChange = {}, + OrientalTraderMiniWorldChange = {}, + RiverRunsDeepMiniWorldChange = {}, + StampedeMiniWorldChange = {}, + ThawingMiniWorldChange = {}, + WarAgainstTheHive = {}, + -- update 9.5 + SpringIntoLife = {}, + -- update 9.80 + BigfootsBurden = {}, + CrystalWarlordOutfits = {}, + DevovorgasEssenceMiniWorldChange = {}, + SoilGuardianOutfits = {}, + SpiderNestMiniWorldChange = {}, + WarpathMiniWorldChange = {}, + -- update 9.80 + ChildOfDestiny = {}, + DemonOutfits = {}, + GoblinMerchant = {}, + VenoreDailyTasks = {}, + -- update 10.10 + FuryGatesMiniWorldChange = {}, + HuntingForTokens = {}, + OpticordingSphere = {}, + SmallSapphire = {}, + TheGravediggerOfDrefia = {}, + TheRepenters = {}, + -- update 10.20 + CaveExplorerOutfits = {}, + SpikeTasks = {}, + SpiritGroundsMiniWorldChange = {}, + -- update 10.30 + DreamWardenOutfits = {}, + Roshamuul = {}, + -- update 10.37 + TinderBox = {}, + ChyllfroestMiniWorldChange = {}, + -- update 10.50 + DarkTrails = {}, + GloothEngineerOutfits = {}, + Oramond = {}, + Rathleton = {}, + -- update 10.55 + Dawnport = { + VocationReward = 20000, + Questline = 20001, + GoMain = 20002, + TheLostAmulet = 20003, + TheStolenLogBook = 20004, + TheRareHerb = 20005, + TheDormKey = 20006, + StrangeAmulet = 20007, + TornLogBook = 20008, + HerbFlower = 20009, + MorriskTroll = 20010, + MorrisTrollCount = 20011, + MorrisGoblin = 20012, + MorrisGoblinCount = 20013, + MorrisMinos = 20014, + MorrisMinosCount = 20015 + }, + SanctuaryOfTheLizardGod = { + LizardGodTeleport = 20020, + LegionHelmet = 20021 + }, + -- update 10.70 + HeroOfRathleton = {}, + LionsRock = {}, + TheCursedCrystal = {}, + TheFireFeatheredSerpentWorldChange = {}, + TwentyMilesBeneathTheSea = {}, + -- update 10.80 + AsuraPalace = {}, + Cartography101 = {}, + Grimvale = {}, + NightmareTeddy = {}, + TheGreatDragonHunt = {}, + TheLostBrother = {}, + TheTaintedSouls = {}, + -- update 10.90 + FerumbrasAscension = {}, + Krailos = {}, + RiftWarriorOutfits = {}, + -- update 10.94 + HeartOfDestruction = {}, + -- update 11.02 + FestiveOutfits = {}, + FirstDragon = {}, + ForgottenKnowledge = {}, + -- update 11.40 + CultsOfTibia = {}, + ThreatenedDreams = {}, + -- update 11.50 + DangerousDepths = {}, + HiddenThreats = {}, + MakeshiftWarriorOutfits = {}, + -- update 11.80 + BattleMageOutfits = {}, + DiscovererOutfits = {}, + MeasuringTibia = {}, + TheSecretLibrary = {}, + -- update 12.00 + DreamWarriorOutfits = {}, + TheDreamCourts = { + AndrewDoor = 14900 + }, + -- update 12.02 + TibiaAnniversary = {}, + WinterlightSolstice = {}, + -- update 12.15.8659 + GoldenOutfits = {}, + -- update 12.20 + GraveDanger = {}, + HandOfTheInquisitionOutfits = {}, + -- Kilmaresh = {}, done earlier in the file + GraveDanger = {}, + -- update 12.30 + FeasterOfSouls = {}, + PoltergeistOutfits = {} + } +} + +GlobalStorage = { + DangerousDepths = { + -- Reserved storage from 60001 - 60009 + Geodes = { + WarzoneVI = 60001, + WarzoneV = 60002, + WarzoneIV = 60003 + } + }, + TheirMastersVoice = { + -- Reserved storage from 60010 - 60019 + CurrentServantWave = 60010, + ServantsKilled = 60011 + }, + Feroxa = { + -- Reserved storage from 60020 - 60029 + Chance = 60020, + Active = 60021 + }, + FerumbrasAscendant = { + -- Reserved storage from 60030 - 60069 + ZamuloshSummon = 60030, + FerumbrasEssence = 60031, + DesperateSoul = 60032, + Crystals = { + Crystal1 = 60040, + Crystal2 = 60041, + Crystal3 = 60042, + Crystal4 = 60043, + Crystal5 = 60044, + Crystal6 = 60045, + Crystal7 = 60046, + Crystal8 = 60047, + AllCrystals = 60048 + }, + Habitats = { + Roshamuul = 60050, + Grass = 60051, + Mushroom = 60052, + Desert = 60053, + Venom = 60054, + Ice = 60055, + Corrupted = 60056, + Dimension = 60057, + AllHabitats = 60058 + }, + Elements = { + First = 60060, + Second = 60061, + Third = 60062, + Four = 60063, + Active = 60064, + Done = 60065 + } + }, + HeroRathleton = { + -- Reserved storage from 60070 - 60089 + FirstMachines = 60070, + SecondMachines = 60071, + ThirdMachines = 60072, + FourthMachines = 60073, + DeepRunning = 60074, + HorrorRunning = 60075, + LavaRunning = 60076, + LavaCounter = 60077, + MaxxenRunning = 60078, + TentacleWave = 60079, + DevourerWave = 60080, + GloothWave = 60081, + LavaChange = 60082 + }, + ForgottenKnowledge = { + -- Reserved storage from 60090 - 60099 + ActiveTree = 60090, + MechanismGolden = 60091, + MechanismDiamond = 60092, + GoldenServant = 60093, + DiamondServant = 60094, + AstralPowerCounter = 60095, + AstralGlyph = 60096 + }, + InServiceOfYalahar = { + -- Reserved storage from 60100 - 60109 + LastFight = 60100, + WarGolemsMachine1 = 60101, + WarGolemsMachine2 = 60102 + }, + BigfootBurden = { + -- Reserved storage from 60110 - 60119 + Warzones = 60110, + Weeper = 60111, + Versperoth = { + Battle = 60112, + Health = 60113 + }, + Mouthpiece = 60114 + }, + WrathOfTheEmperor = { + -- Reserved storage from 60120 - 60139 + Light01 = 60120, + Light02 = 60121, + Light03 = 60122, + Light04 = 60123, + Bosses = { + Fury = 60130, + Wrath = 60131, + Scorn = 60132, + Spite = 60133 + } + }, + ElementalSphere = { + -- Reserved storage from 60140 - 60159 + BossRoom = 60140, + KnightBoss = 60141, + SorcererBoss = 60142, + PaladinBoss = 60143, + DruidBoss = 60144, + Machine1 = 60145, + Machine2 = 60146, + Machine3 = 60147, + Machine4 = 60148 + }, + TheAncientTombs = { + -- Reserved storage from 60160 - 60169 + ThalasSwitchesGlobalStorage = 60160, + DiprathSwitchesGlobalStorage = 60161, + AshmunrahSwitchesGlobalStorage = 60162 + }, + FuryGates = 65000, + Yakchal = 65001, + PitsOfInfernoLevers = 65002, + NaginataStone = 65003, + ExpBoost = 65004, + SwordOfFury = 65005, + XpDisplayMode = 65006, + LionsRockFields = 65007, + TheMummysCurse = 65008, + OberonEventTime = 65009, + PrinceDrazzakEventTime = 65010, + ScarlettEtzelEventTime = 65011, + CobraBastionFlask = 65012, + Inquisition = 65013, + Yasir = 65014, + NightmareIsle = 65015 +} + + +-- Values extraction function +local function extractValues(tab, ret) + if type(tab) == "number" then + table.insert(ret, tab) + else + for _, v in pairs(tab) do + extractValues(v, ret) + end + end +end + +local benchmark = os.clock() +local extraction = {} +extractValues(Storage, extraction) -- Call function +table.sort(extraction) -- Sort the table +-- The choice of sorting is due to the fact that sorting is very cheap O (n log2 (n)) +-- And then we can simply compare one by one the elements finding duplicates in O(n) + +-- Scroll through the extracted table for duplicates +if #extraction > 1 then + for i = 1, #extraction - 1 do + if extraction[i] == extraction[i+1] then + Spdlog.warn(string.format("Duplicate storage value found: %d", + extraction[i])) + Spdlog.warn(string.format("Processed in %.4f(s)", os.clock() - benchmark)) + end + end +end diff --git a/data/lib/core/string.lua b/data/lib/core/string.lua new file mode 100644 index 00000000000..737be047e42 --- /dev/null +++ b/data/lib/core/string.lua @@ -0,0 +1,42 @@ +string.split = function(str, sep) + local res = {} + for v in str:gmatch("([^" .. sep .. "]+)") do + res[#res + 1] = v + end + return res +end + +string.trim = function(str) + return str:match'^()%s*$' and '' or str:match'^%s*(.*%S)' +end + +string.starts = function(str, substr) + return string.sub(str, 1, #substr) == substr +end + +string.titleCase = function(str) + return str:gsub("(%a)([%w_']*)", function(first, rest) return first:upper() .. rest:lower() end) +end + +string.diff = function(diff) + local format = { + {'day', diff / 60 / 60 / 24}, + {'hour', diff / 60 / 60 % 24}, + {'minute', diff / 60 % 60}, + {'second', diff % 60} + } + + local out = {} + for k, t in ipairs(format) do + local v = math.floor(t[2]) + if(v > 0) then + table.insert(out, (k < #format and (#out > 0 and ', ' or '') or ' and ') .. v .. ' ' .. t[1] .. (v ~= 1 and 's' or '')) + end + end + local ret = table.concat(out) + if ret:len() < 16 and ret:find('second') then + local a, b = ret:find(' and ') + ret = ret:sub(b+1) + end + return ret +end diff --git a/data/lib/core/tables.lua b/data/lib/core/tables.lua new file mode 100644 index 00000000000..e24b62d4b59 --- /dev/null +++ b/data/lib/core/tables.lua @@ -0,0 +1,131 @@ +table.append = table.insert +table.empty = function (t) + return next(t) == nil +end + +table.find = function (table, value) + for i, v in pairs(table) do + if(v == value) then + return i + end + end + + return nil +end + +table.contains = function (txt, str) + for i, v in pairs(str) do + if(txt:find(v) and not txt:find('(%w+)' .. v) and not txt:find(v .. '(%w+)')) then + return true + end + end + + return false +end +table.isStrIn = table.contains + +table.count = function (table, item) + local count = 0 + for i, n in pairs(table) do + if(item == n) then + count = count + 1 + end + end + + return count +end +table.countElements = table.count + +table.getCombinations = function (table, num) + local a, number, select, newlist = {}, #table, num, {} + for i = 1, select do + a[#a + 1] = i + end + + local newthing = {} + while(true) do + local newrow = {} + for i = 1, select do + newrow[#newrow + 1] = table[a[i]] + end + + newlist[#newlist + 1] = newrow + i = select + while(a[i] == (number - select + i)) do + i = i - 1 + end + + if(i < 1) then + break + end + + a[i] = a[i] + 1 + for j = i, select do + a[j] = a[i] + j - i + end + end + + return newlist +end + +function table.serialize(x, recur) + local t = type(x) + recur = recur or {} + + if(t == nil) then + return "nil" + elseif(t == "string") then + return string.format("%q", x) + elseif(t == "number") then + return tostring(x) + elseif(t == "boolean") then + return t and "true" or "false" + elseif(getmetatable(x)) then + error("Can not serialize a table that has a metatable associated with it.") + elseif(t == "table") then + if(table.find(recur, x)) then + error("Can not serialize recursive tables.") + end + table.append(recur, x) + + local s = "{" + for k, v in pairs(x) do + s = s .. "[" .. table.serialize(k, recur) .. "]" + s = s .. " = " .. table.serialize(v, recur) .. "," + end + s = s .. "}" + return s + else + error("Can not serialize value of type '" .. t .. "'.") + end +end + +function table.unserialize(str) + return loadstring("return " .. str)() +end + +function table.concat(tableA, tableB) + local result = {unpack(tableA)} + table.move(tableB, 1, #tableB, #result + 1, result) + return result +end + +function pairsByKeys(t, f) + local a = {} + for n in pairs(t) do table.insert(a, n) end + table.sort(a, f) + local i = 0 -- iterator variable + local iter = function () -- iterator function + i = i + 1 + if a[i] == nil then return nil + else return a[i], t[a[i]] + end + end + return iter +end + +function Set(list) + local set = {} + for _, l in ipairs(list) do set[l] = true end + return set +end \ No newline at end of file diff --git a/data/lib/core/teleport.lua b/data/lib/core/teleport.lua new file mode 100644 index 00000000000..89302688eea --- /dev/null +++ b/data/lib/core/teleport.lua @@ -0,0 +1,3 @@ +function Teleport.isTeleport(self) + return true +end diff --git a/data/lib/core/tile.lua b/data/lib/core/tile.lua new file mode 100644 index 00000000000..bdfb65a0220 --- /dev/null +++ b/data/lib/core/tile.lua @@ -0,0 +1,93 @@ +function Tile.isCreature(self) + return false +end + +function Tile.isItem(self) + return false +end + +function Tile.isTile(self) + return true +end + +function Tile.isContainer(self) + return false +end + +function Tile.relocateTo(self, toPosition) + if self:getPosition() == toPosition or not Tile(toPosition) then + return false + end + + for i = self:getThingCount() - 1, 0, -1 do + local thing = self:getThing(i) + if thing then + if thing:isItem() then + if thing:getFluidType() ~= 0 then + thing:remove() + elseif ItemType(thing:getId()):isMovable() then + thing:moveTo(toPosition) + end + elseif thing:isCreature() then + thing:teleportTo(toPosition) + end + end + end + return true +end + +function Tile:isWalkable(pz, creature, floorchange, block, proj) + if not self then return false end + if not self:getGround() then return false end + if self:hasProperty(CONST_PROP_BLOCKSOLID) or self:hasProperty(CONST_PROP_BLOCKPROJECTILE) then return false end + if pz and (self:hasFlag(TILESTATE_HOUSE) or self:hasFlag(TILESTATE_PROTECTIONZONE)) then return false end + if creature and self:getTopCreature() ~= nil then return false end + if floorchange and self:hasFlag(TILESTATE_FLOORCHANGE) then return false end + if block then + local topStackItem = self:getTopTopItem() + if topStackItem and topStackItem:hasProperty(CONST_PROP_BLOCKPATH) then return false end + end + if proj then + local items = self:getItems() + if #items > 0 then + for i = 1, #items do + local itemType = ItemType(items[i]) + if itemType:getType() ~= ITEM_TYPE_MAGICFIELD and not itemType:isMovable() and items[i]:hasProperty(CONST_PROP_BLOCKSOLID) then return false end + end + end + end + return true +end + +-- Functions from OTServbr-Global +function Tile.isHouse(self) + local house = self:getHouse() + return not not house +end + +function Tile.isPz(self) + return self:hasFlag(TILESTATE_PROTECTIONZONE) +end + +function Tile:isRopeSpot() + if not self then + return false + end + + if not self:getGround() then + return false + end + + if table.contains(ropeSpots, self:getGround():getId()) then + return true + end + + for i = 1, self:getTopItemCount() do + local thing = self:getThing(i) + if thing and table.contains(specialRopeSpots, thing:getId()) then + return true + end + end + + return false +end \ No newline at end of file diff --git a/data/lib/core/vocation.lua b/data/lib/core/vocation.lua new file mode 100644 index 00000000000..acf31afec7b --- /dev/null +++ b/data/lib/core/vocation.lua @@ -0,0 +1,7 @@ +function Vocation.getBase(self) + local base = self + while base:getDemotion() do + base = base:getDemotion() + end + return base +end diff --git a/data/lib/debugging/dump.lua b/data/lib/debugging/dump.lua new file mode 100644 index 00000000000..bca9c045310 --- /dev/null +++ b/data/lib/debugging/dump.lua @@ -0,0 +1,59 @@ +-- recursive dump function +function dumpLevel(input, level) + local indent = '' + + for i = 1, level do + indent = indent .. ' ' + end + + if type(input) == 'table' then + local str = '{ \n' + local lines = {} + + for k, v in pairs(input) do + if type(k) ~= 'number' then + k = '"' .. k .. '"' + end + + if type(v) == 'string' then + v = '"' .. v .. '"' + end + + table.insert(lines, indent .. ' [' .. k .. '] = ' .. dumpLevel(v, level + 1)) + end + return str .. table.concat(lines, ',\n') .. '\n' .. indent .. '}' + end + + return tostring(input) +end + +-- Return a string representation of input for debugging purposes +function dump(input) + return dumpLevel(input, 0) +end + +-- Call the dump function and print it to console +function pdump(input) + local dump_str = dump(input) + Spdlog.debug(dump_str) + return dump_str +end + +-- Call the dump function with a title and print it beautifully to the console +function tdump(title, input) + local title_fill = '' + for i = 1, title:len() do + title_fill = title_fill .. '=' + end + + local header_str = '\n====' .. title_fill .. '====\n' + header_str = header_str .. '=== ' .. title .. ' ===\n' + header_str = header_str .. '====' .. title_fill .. '====\n' + + local dump_str = dump(input) + local footer_str = '\n====' .. title_fill .. '====\n' + + Spdlog.debug(header_str .. dump_str .. footer_str) + + return dump_str +end diff --git a/data/lib/lib.lua b/data/lib/lib.lua new file mode 100644 index 00000000000..434fd14d45d --- /dev/null +++ b/data/lib/lib.lua @@ -0,0 +1,23 @@ +-- Core API functions implemented in Lua +dofile('data/lib/core/core.lua') + +-- Compatibility library for our old Lua API +dofile('data/lib/compat/compat.lua') + +-- Debugging helper function for Lua developers +dofile('data/lib/debugging/dump.lua') + +-- Tables library +dofile('data/lib/tables/table.lua') + +-- Others library +dofile('data/lib/others/others.lua') + +-- Quests library +dofile('data/lib/quests/quest.lua') + +-- Player Processor Library +dofile('data/lib/player_processor/load.lua') + +-- Npcs library +dofile('data/lib/npc/npc.lua') \ No newline at end of file diff --git a/data/lib/npc/npc.lua b/data/lib/npc/npc.lua new file mode 100644 index 00000000000..d946de42775 --- /dev/null +++ b/data/lib/npc/npc.lua @@ -0,0 +1,108 @@ +-- add npc interaction lib +dofile('data/lib/npc/npc_utils.lua') +dofile('data/lib/npc/npc_interaction/load.lua') + +-- Checks whether a message is being sent to npc +-- msgContains(message, keyword) +function msgContains(message, keyword) + local message, keyword = message:lower(), keyword:lower() + if message == keyword then + return true + end + + return message:find(keyword) and not message:find('(%w+)' .. keyword) +end + +function Npc:decoratedTalkToCreature(creature, text) + if type(text) == "table" then + for i = 0, #text do + self:sendMessage(creature, text[i]) + end + else + self:sendMessage(creature, text) + end +end + +-- Npc talk +-- npc:talk({text, text2}) or npc:talk(text) +function Npc:talk(creature, text) + if type(text) == "table" then + for i = 0, #text do + self:sendMessage(creature, text[i]) + end + else + self:sendMessage(creature, text) + end +end + +-- Npc send message to player +-- npc:sendMessage(text) +function Npc:sendMessage(creature, text) + return self:say(string.format(text or "", creature:getName()), TALKTYPE_PRIVATE_NP, true, creature) +end + +function Npc:processOnSay(message, player, npcInteractions) + if not player then + return false + end + + if not self:isInTalkRange(player:getPosition()) then + return false + end + + for _, npcInteraction in pairs(npcInteractions) do + if npcInteraction:execute(message, player, self) then return true end + end + + return false +end + +function Npc:doSellItem(cid, itemId, amount, subType, ignoreCap, inBackpacks, backpack) + local amount = amount or 1 + local subType = subType or 0 + local item = 0 + local player = Player(cid) + + if ItemType(itemId):isStackable() then + local stuff + if inBackpacks then + stuff = Game.createItem(backpack, 1) + item = stuff:addItem(itemId, math.min(100, amount)) + else + stuff = Game.createItem(itemId, math.min(100, amount)) + end + + return player:addItemEx(stuff, ignoreCap) ~= RETURNVALUE_NOERROR and 0 or amount, 0 + end + + local a = 0 + if inBackpacks then + local container, b = Game.createItem(backpack, 1), 1 + for i = 1, amount do + local item = container:addItem(itemId, subType) + if table.contains({(ItemType(backpack):getCapacity() * b), amount}, i) then + if player:addItemEx(container, ignoreCap) ~= RETURNVALUE_NOERROR then + b = b - 1 + break + end + + a = i + if amount > i then + container = Game.createItem(backpack, 1) + b = b + 1 + end + end + end + + return a, b + end + + for i = 1, amount do -- normal method for non-stackable items + local item = Game.createItem(itemId, subType) + if player:addItemEx(item, ignoreCap) ~= RETURNVALUE_NOERROR then + break + end + a = i + end + return a, 0 +end \ No newline at end of file diff --git a/data/lib/npc/npc_interaction/load.lua b/data/lib/npc/npc_interaction/load.lua new file mode 100644 index 00000000000..c92d3668f08 --- /dev/null +++ b/data/lib/npc/npc_interaction/load.lua @@ -0,0 +1,4 @@ +dofile('data/lib/npc/npc_interaction/npc_messages.lua') +dofile('data/lib/npc/npc_interaction/npc_topic.lua') +dofile('data/lib/npc/npc_interaction/npc_interaction.lua') +dofile('data/lib/npc/npc_interaction/npc_interaction_creators.lua') \ No newline at end of file diff --git a/data/lib/npc/npc_interaction/npc_interaction.lua b/data/lib/npc/npc_interaction/npc_interaction.lua new file mode 100644 index 00000000000..81d86b3b499 --- /dev/null +++ b/data/lib/npc/npc_interaction/npc_interaction.lua @@ -0,0 +1,229 @@ +NpcInteraction = {} + +InteractionRelationType = { + RELATION_CONFIRMATION = 1, + RELATION_CANCELLATION = 2, +} + +function NpcInteraction:new(keywords, messages, topic) + obj = { + keywords = keywords or {}, + messages = NpcMessages:new(messages or {}), + topic = NpcTopic:new(topic or {}), + parent = nil, + children = {}, + onInitPlayerProcessors = { + validators = {}, + updaters = {}, + }, + onCompletePlayerProcessors = { + validators = {}, + updaters = {}, + }, + } + + if getmetatable(obj.messages) ~= NpcMessages then + error("Invalid argument: messages needs to be of type NpcMessages") + end + + if getmetatable(obj.topic) ~= NpcTopic then + error("Invalid argument: topic needs to be of type NpcTopic") + end + + setmetatable(obj, self) + self.__index = self + return obj +end + +function NpcInteraction:execute(message, player, npc) + if self:checkPlayerInteraction(player, npc) and self:hasMessageValidKeyword(message) then + -- If initial processor validations failed, skip all the rest + if not self:runOnInitPlayerProcessors(player, npc) then + return false + end + + npc:talk(player, self.messages.reply) + self:updatePlayerInteraction(player, npc) + + if self.parent and self.parent.relationType == InteractionRelationType.RELATION_CONFIRMATION then + self.parent.interaction:runOnCompletePlayerProcessors(player, npc) + elseif self.parent then + npc:talk(player, self.parent.interaction.messages.cancellation) + end + + if #self.children == 0 then + self:runOnCompletePlayerProcessors(player, npc) + end + + return true + end + + for _, child in pairs(self.children) do + child:execute(message, player, npc) + end + + return false +end + +function NpcInteraction:hasMessageValidKeyword(message) + for _, keyword in pairs(self.keywords) do + if msgContains(message, keyword) then + return true + end + end + return false +end + +function NpcInteraction:checkPlayerInteraction(player, npc) + if not self.topic.previous then + return npc:isInteractingWithPlayer(player) + end + + if self.topic.previous == -1 then + return not npc:isInteractingWithPlayer(player) + end + + return npc:isPlayerInteractingOnTopic(player, self.topic.previous) +end + +function NpcInteraction:updatePlayerInteraction(player, npc) + if self.topic.current == -1 then + npc:removePlayerInteraction(player) + else + npc:setPlayerInteraction(player, self.topic.current) + end +end + +function NpcInteraction:runOnInitPlayerProcessors(player, npc) + for _, processor in pairs(self.onInitPlayerProcessors.validators) do + if not processor:validate(player, npc) then return false end + end + + for _, processor in pairs(self.onInitPlayerProcessors.updaters) do + processor:update(player, npc) + end + + return true +end + +function NpcInteraction:runOnCompletePlayerProcessors(player, npc) + for _, processor in pairs(self.onCompletePlayerProcessors.validators) do + if not processor:validate(player, npc) then + if npc then npc:talk(player, self.messages.cannotExecute) end + return false + end + end + + for _, processor in pairs(self.onCompletePlayerProcessors.updaters) do + processor:update(player, npc) + end + + if npc then npc:talk(player, self.messages.confirmation) end + + return true +end + +function NpcInteraction:getValidNpcInteractionForMessage(message, npc, player) + for _, keyword in pairs(self.keywords) do + if msgContains(message, keyword) then return self end + end + + for _, subInteraction in pairs(self.children) do + local child = subInteraction:getValidNpcInteractionForMessage(message, npc, player) + if child and child.topic.previous and npc:isPlayerInteractingOnTopic(player, child.topic.previous) then + return child + end + end + + return nil +end + +function NpcInteraction:addSubInteraction(subInteraction, relationType) + if not self:isValidSubInteraction(subInteraction) then return self end + subInteraction.parent = { interaction = self, relationType = relationType or InteractionRelationType.RELATION_CONFIRMATION } + self.children[#self.children + 1] = subInteraction + + return self +end + +function NpcInteraction:addInitValidationProcessor(validator) + if not self:isValidProcessor(validator) then return self end + self.onInitPlayerProcessors.validators[#self.onInitPlayerProcessors.validators + 1] = validator + + return self +end + +function NpcInteraction:addInitValidationProcessors(validators) + if not validators then return self end + + for _, validator in pairs(validators) do + self:addInitValidationProcessor(validator) + end + + return self +end + +function NpcInteraction:addInitUpdateProcessor(updater) + if not self:isValidProcessor(updater) then return self end + self.onInitPlayerProcessors.updaters[#self.onInitPlayerProcessors.updaters + 1] = updater + + return self +end + +function NpcInteraction:addInitUpdateProcessors(updaters) + if not updaters then return self end + + for _, updater in pairs(updaters) do + self:addInitUpdateProcessor(updater) + end + + return self +end + +function NpcInteraction:addCompletionValidationProcessor(validator) + if not self:isValidProcessor(validator) then return self end + self.onCompletePlayerProcessors.validators[#self.onCompletePlayerProcessors.validators + 1] = validator + + return self +end + +function NpcInteraction:addCompletionValidationProcessors(validators) + if not validators then return self end + + for _, validator in pairs(validators) do + self:addCompletionValidationProcessor(validator) + end + + return self +end + +function NpcInteraction:addCompletionUpdateProcessor(updater) + if not self:isValidProcessor(updater) then return self end + self.onCompletePlayerProcessors.updaters[#self.onCompletePlayerProcessors.updaters + 1] = updater + + return self +end + +function NpcInteraction:addCompletionUpdateProcessors(updaters) + if not updaters then return self end + + for _, updater in pairs(updaters) do + self:addCompletionUpdateProcessor(updater) + end + + return self +end + +function NpcInteraction:isValidSubInteraction(interaction) + if getmetatable(interaction) ~= NpcInteraction then + return false + end + return true +end + +function NpcInteraction:isValidProcessor(procesor) + if getmetatable(procesor) ~= PlayerProcessingConfigs then + return false + end + return true +end \ No newline at end of file diff --git a/data/lib/npc/npc_interaction/npc_interaction_creators.lua b/data/lib/npc/npc_interaction/npc_interaction_creators.lua new file mode 100644 index 00000000000..c184c106f01 --- /dev/null +++ b/data/lib/npc/npc_interaction/npc_interaction_creators.lua @@ -0,0 +1,83 @@ +function NpcInteraction:createGreetInteraction(message, keywords) + return NpcInteraction:new( + keywords or {"hi", "hello"}, + {reply = message or "Hello, %s, what you need?"}, + {previous = -1} + ) +end + +function NpcInteraction:createFarewellInteraction(message, keywords) + return NpcInteraction:new( + keywords or {"bye", "farewell"}, + {reply = message or "Goodbye, %s."}, + {current = -1} + ) +end + +function NpcInteraction:createReplyInteraction(keywords, message, topic) + return NpcInteraction:new( + keywords, + {reply = message}, + topic + ) +end + +function NpcInteraction:createConfirmationInteraction(keywords, messages, childTopic) + return NpcInteraction:new( + keywords, + messages, + {current = childTopic, previous = 0} + ):addSubInteraction( + NpcInteraction:createReplyInteraction( {"yes"}, nil, {current = 0, previous = childTopic}) + ):addSubInteraction( + NpcInteraction:createReplyInteraction( {"no"},nil, {current = 0, previous = childTopic}), + InteractionRelationType.RELATION_CANCELLATION + ) +end + +function NpcInteraction:createTravelInteraction(player, travelConfigs, baseMessages, travelTopic) + local cost = player and player:calculateTravelPrice(travelConfigs.baseCost, travelConfigs.discounts or {}) or travelConfigs.baseCost + + -- its nice to keep validators separated, we can later on add failure message per validator when it fails + local travelValidators = travelConfigs.completionValidations or {} + travelValidators[#travelValidators + 1] = PlayerProcessingConfigs:new():addAmount(cost) + travelValidators[#travelValidators + 1] = PlayerProcessingConfigs:new():addStorage(Storage.NpcExhaust, os.time(), ConfigsTypes.CONFIG_LTE) + --:addPremium(travelConfig.premium or true) + --:addLevel(travelConfig.level) + --:addProtectionZone(true) + --:addProtectionZone(true) + + local travelUpdaters = travelConfigs.completionUpdaters or {} + travelUpdaters[#travelUpdaters + 1] = PlayerProcessingConfigs:new() + :addPosition(travelConfigs.position) + :removeAmount(cost) + :addStorage(Storage.NpcExhaust, 3 + os.time()) + :addCallback( + function(player) + player:getPosition():sendMagicEffect(travelConfigs.effect or CONST_ME_TELEPORT) + addEvent(function () travelConfigs.position:sendMagicEffect(travelConfigs.effect or CONST_ME_TELEPORT) end, 100) + end + ) + + -- this is some quest weirdness, probably can be encapsulated somewhere else later + travelUpdaters[#travelUpdaters + 1] = PlayerProcessingConfigs:new() + :addCallback( + function(player) + if travelConfigs.town == "kazordoon" and player:getStorageValue(Storage.WhatAFoolish.PieBoxTimer) > os.time() then + player:setStorageValue(Storage.WhatAFoolish.PieBoxTimer, 1) + end + end + ) + + return NpcInteraction:createConfirmationInteraction( + {travelConfigs.town}, + { + reply = buildTravelMessage(baseMessages.reply, travelConfigs.town, cost), + confirmation = baseMessages.confirmation, + cancellation = baseMessages.cancellation, + cannotExecute = baseMessages.cannotExecute, + }, + travelTopic + ):addCompletionValidationProcessors(travelValidators) + :addCompletionUpdateProcessors(travelUpdaters) +end \ No newline at end of file diff --git a/data/lib/npc/npc_interaction/npc_messages.lua b/data/lib/npc/npc_interaction/npc_messages.lua new file mode 100644 index 00000000000..27722e12134 --- /dev/null +++ b/data/lib/npc/npc_interaction/npc_messages.lua @@ -0,0 +1,17 @@ +NpcMessages = {} + +function NpcMessages:new(obj) + if getmetatable(obj) == NpcMessages then return obj end + + obj = obj or {} + obj = { + reply = obj.reply or "", + confirmation = obj.confirmation or "", + cancellation = obj.cancellation or "", + cannotExecute = obj.cannotExecute or "", + } + + setmetatable(obj, self) + self.__index = self + return obj +end \ No newline at end of file diff --git a/data/lib/npc/npc_interaction/npc_topic.lua b/data/lib/npc/npc_interaction/npc_topic.lua new file mode 100644 index 00000000000..5f5a6ab5f42 --- /dev/null +++ b/data/lib/npc/npc_interaction/npc_topic.lua @@ -0,0 +1,15 @@ +NpcTopic = {} + +function NpcTopic:new(obj) + if getmetatable(obj) == NpcTopic then return obj end + + obj = obj or {} + obj = { + current = obj.current or 0, + previous = obj.previous or nil, + } + + setmetatable(obj, self) + self.__index = self + return obj +end \ No newline at end of file diff --git a/data/lib/npc/npc_utils.lua b/data/lib/npc/npc_utils.lua new file mode 100644 index 00000000000..3d176fe5b72 --- /dev/null +++ b/data/lib/npc/npc_utils.lua @@ -0,0 +1,87 @@ +-- Utils functions for NPC System +local travelDiscounts = { + ['postman'] = {price = 10, storage = Storage.Postman.Rank, value = 3}, + ['new frontier'] = {price = 50, storage = Storage.TheNewFrontier.Mission03, value = 1} +} + +function buildTravelMessage(baseMessage, place, cost) + baseMessage = baseMessage or "Do you want to travel to %s for %s gold coins?" + return string.format(baseMessage, place, cost > 0 and cost or "free") +end + +function Player:calculateTravelPrice(basePrice, discount) + return basePrice - self:getTravelDiscount(discount) +end + +function getDiscount(player, discount) + if discount and player:getStorageValue(discount.storage) >= discount.value then + return discount.price + end + return 0 +end + +function Player:getTravelDiscount(discounts) + local discountPrice, discount = 0 + if type(discounts) == 'string' then + return getDiscount(self, travelDiscounts[discounts]) + end + + for i = 1, #discounts do + discountPrice = discountPrice + getDiscount(self, travelDiscounts[discounts[i]]) + end + + return discountPrice +end + +function Player:getTotalMoney() + return self:getMoney() + self:getBankBalance() +end + +function Player:removeMoneyIncludingBalance(amount) + if type(amount) == 'string' then + amount = tonumber(amount) + end + + local moneyCount = self:getMoney() + local bankCount = self:getBankBalance() + + -- The player have all the money with him + if amount <= moneyCount then + -- Removes player inventory money + self:removeMoney(amount) + + self:sendTextMessage(MESSAGE_TRADE, ("Paid %d gold from inventory."):format(amount)) + return true + + -- The player doens't have all the money with him + elseif amount <= (moneyCount + bankCount) then + + -- Check if the player has some money + if moneyCount ~= 0 then + -- Removes player inventory money + self:removeMoney(moneyCount) + local remains = amount - moneyCount + + -- Removes player bank money + self:setBankBalance(bankCount - remains) + + self:sendTextMessage(MESSAGE_TRADE, ("Paid %d from inventory and %d gold from bank account. Your account balance is now %d gold."):format(moneyCount, amount - moneyCount, self:getBankBalance())) + return true + + else + self:setBankBalance(bankCount - amount) + self:sendTextMessage(MESSAGE_TRADE, ("Paid %d gold from bank account. Your account balance is now %d gold."):format(amount, self:getBankBalance())) + return true + end + end + + return false +end + +function Npc:chargePlayer(player, cost, message) + if not player:removeMoneyIncludingBalance(cost) then + self:talk(player, message or "You do not have enough money!") + return false + end + return true +end diff --git a/data/lib/others/bath_tube.lua b/data/lib/others/bath_tube.lua new file mode 100644 index 00000000000..12885800a67 --- /dev/null +++ b/data/lib/others/bath_tube.lua @@ -0,0 +1,3 @@ +BATHTUB_EMPTY = 29312 +BATHTUB_FILLED = 29313 +BATHTUB_FILLED_NOTMOVABLE = 29336 \ No newline at end of file diff --git a/data/lib/others/daily_reward_lib.lua b/data/lib/others/daily_reward_lib.lua new file mode 100644 index 00000000000..e8fe675f3ae --- /dev/null +++ b/data/lib/others/daily_reward_lib.lua @@ -0,0 +1,225 @@ +-- Global virtual tables +Daily_Bonus = { + stamina = {}, + soul = {} +} + +function string.diff(self) + local format = { + {'day', self / 60 / 60 / 24}, + {'hour', self / 60 / 60 % 24}, + {'minute', self / 60 % 60}, + {'second', self % 60} + } + + local out = {} + for k, t in ipairs(format) do + local v = math.floor(t[2]) + if(v > 0) then + table.insert(out, (k < #format and (#out > 0 and ', ' or '') or ' and ') .. v .. ' ' .. t[1] .. (v ~= 1 and 's' or '')) + end + end + local ret = table.concat(out) + if ret:len() < 16 and ret:find('second') then + local a, b = ret:find(' and ') + ret = ret:sub(b+1) + end + return ret +end + +function Game.getLastServerSave() + return retrieveGlobalStorage(DailyReward.storages.lastServerSave) +end + +function updateGlobalStorage(key, value) + db.query("INSERT INTO `global_storage` (`key`, `value`) VALUES (".. key ..", ".. value ..") ON DUPLICATE KEY UPDATE `value` = ".. value) +end + +function retrieveGlobalStorage(key) + local resultId = db.storeQuery("SELECT `value` FROM `global_storage` WHERE `key` = " .. key) + if resultId ~= false then + local val = result.getNumber(resultId, "value") + result.free(resultId) + return val + end + return 1 +end + +function Player.getCollectionTokens(self) + return math.max(self:getStorageValue(DailyReward.storages.collectionTokens), 0) +end + +function Player.getJokerTokens(self) + return math.max(self:getStorageValue(DailyReward.storages.jokerTokens), 0) +end + +function Player.setJokerTokens(self, value) + self:setStorageValue(DailyReward.storages.jokerTokens, value) +end + +function Player.setCollectionTokens(self, value) + self:setStorageValue(DailyReward.storages.collectionTokens, value) +end + +function Player.getDayStreak(self) + return math.max(self:getStorageValue(DailyReward.storages.currentDayStreak), 0) +end + +function Player.setDayStreak(self, value) + self:setStorageValue(DailyReward.storages.currentDayStreak, value) +end + +function Player.getStreakLevel(self) + return math.max(self:getStorageValue(DailyReward.storages.currentStreakLevel), 0) +end + +function Player.setStreakLevel(self, value) + self:setStorageValue(DailyReward.storages.currentStreakLevel, value) +end + +function Player.setNextRewardTime(self, value) + self:setStorageValue(DailyReward.storages.nextRewardTime, value) +end + +function Player.getNextRewardTime(self) + return math.max(self:getStorageValue(DailyReward.storages.nextRewardTime), 0) +end + +function Player.isRestingAreaBonusActive(self) + local levelStreak = self:getStreakLevel() + if levelStreak > 1 then + return true + else + return false + end +end + +local function regenStamina(id, delay) + local staminaEvent = Daily_Bonus.stamina[id] + local player = Player(id) + if not player then + stopEvent(staminaEvent) + Daily_Bonus.stamina[id] = nil + return false + end + if player:getTile():hasFlag(TILESTATE_PROTECTIONZONE) then + local actualStamina = player:getStamina() + if actualStamina > 2340 and actualStamina < 2520 then + delay = 6 * 60 * 1000 -- Bonus stamina + end + if actualStamina < 2520 then + player:setStamina(actualStamina + 1) + player:sendTextMessage(MESSAGE_FAILURE, "One minute of stamina has been refilled.") + end + end + stopEvent(staminaEvent) + Daily_Bonus.stamina[id] = addEvent(regenStamina, delay, id, delay) + return true +end + +local function regenSoul(id, delay) + local soulEvent = Daily_Bonus.soul[id] + local maxsoul = 0 + local player = Player(id) + if not player then + stopEvent(soulEvent) + Daily_Bonus.soul[id] = nil + return false + end + if player:getTile():hasFlag(TILESTATE_PROTECTIONZONE) then + if player:isPremium() then + maxsoul = 200 + else + maxsoul = 100 + end + if player:getSoul() < maxsoul then + player:addSoul(1) + player:sendTextMessage(MESSAGE_FAILURE, "One soul point has been restored.") + end + end + stopEvent(soulEvent) + Daily_Bonus.soul[id] = addEvent(regenSoul, delay, id, delay) + return true +end + +local DAILY_REWARD_HP_REGENERATION = 2 +local DAILY_REWARD_MP_REGENERATION = 3 +local DAILY_REWARD_STAMINA_REGENERATION = 4 +local DAILY_REWARD_DOUBLE_HP_REGENERATION = 5 +local DAILY_REWARD_DOUBLE_MP_REGENERATION = 6 +local DAILY_REWARD_SOUL_REGENERATION = 7 +local DAILY_REWARD_FIRST = 2 +local DAILY_REWARD_LAST = 7 + +function Player.getActiveDailyRewardBonusesName(self) + local msg = "" + local streakLevel = self:getStreakLevel() + if streakLevel >= 2 then + if streakLevel > 7 then + streakLevel = 7 + end + for i = DAILY_REWARD_FIRST, streakLevel do + if i ~= streakLevel then + msg = msg .. "" .. DailyReward.strikeBonuses[i].text .. ", " + else + msg = msg .. "" .. DailyReward.strikeBonuses[i].text .. "." + end + end + end + return msg +end + +function Player.getDailyRewardBonusesCount(self) + local count = 1 + local streakLevel = self:getStreakLevel() + if streakLevel > 2 then + if streakLevel > 7 then + streakLevel = 7 + end + for i = DAILY_REWARD_FIRST, streakLevel do + count = count + 1 + end + else + count = 0 + end + return count +end + +function Player.isBonusActiveById(self, bonusId) + local streakLevel = self:getStreakLevel() + local bonus = "locked" + if streakLevel > 2 then + if streakLevel > 7 then + streakLevel = 7 + end + if streakLevel >= bonusId then + bonus = "unlocked" + end + end + return bonus +end + +function Player.loadDailyRewardBonuses(self) + local streakLevel = self:getStreakLevel() + -- Stamina regeneration + if streakLevel >= DAILY_REWARD_STAMINA_REGENERATION then + local staminaEvent = Daily_Bonus.stamina[self:getId()] + if not staminaEvent then + local delay = 3 + if self:getStamina() > 2340 and self:getStamina() <= 2520 then + delay = 6 + end + Daily_Bonus.stamina[self:getId()] = addEvent(regenStamina, delay * 60 * 1000, self:getId(), delay * 60 * 1000) + end + end + -- Soul regeneration + if streakLevel >= DAILY_REWARD_SOUL_REGENERATION then + local soulEvent = Daily_Bonus.soul[self:getId()] + if not soulEvent then + local delay = self:getVocation():getSoulGainTicks() + Daily_Bonus.soul[self:getId()] = addEvent(regenSoul, delay * 1000, self:getId(), delay * 1000) + end + end + Spdlog.debug(string.format("Player: %s, streak level: %d, active bonuses: %s", + self:getName(), streakLevel, self:getActiveDailyRewardBonusesName())) +end diff --git a/data/lib/others/dawnport_lib.lua b/data/lib/others/dawnport_lib.lua new file mode 100644 index 00000000000..932684af013 --- /dev/null +++ b/data/lib/others/dawnport_lib.lua @@ -0,0 +1,170 @@ +Dawnport = { + skillsLimit = { + [VOCATION.ID.NONE] = {}, + [VOCATION.ID.SORCERER] = { + [SKILL_MAGLEVEL] = 20 + }, + [VOCATION.ID.DRUID] = { + [SKILL_MAGLEVEL] = 20 + }, + [VOCATION.ID.PALADIN] = { + [SKILL_MAGLEVEL] = 9 + }, + [VOCATION.ID.KNIGHT] = { + [SKILL_MAGLEVEL] = 4 + } + } +} + +-- Change player vocation, converts magic level and skills between vocations and set proper stats +-- Used in dawnport vocation trial, Oressa and Inigo NPCs +function Player.changeVocation(self, newVocationId) + -- Skip if change to same vocation + if self:getVocation():getId() == newVocationId then + return false + end + -- Get current vocation magic level and mana spent + local magic = {level = self:getBaseMagicLevel(), manaSpent = self:getManaSpent()} + -- Sum mana spent of every magic level + for level = 1, magic.level do + magic.manaSpent = magic.manaSpent + self:getVocation():getRequiredManaSpent(level) + end + local skills = { + {id = SKILL_FIST}, + {id = SKILL_CLUB}, + {id = SKILL_SWORD}, + {id = SKILL_AXE}, + {id = SKILL_DISTANCE}, + {id = SKILL_SHIELD} + } + -- Get current vocation skills levels and skills tries + for i = 1, #skills do + skills[i].level = self:getSkillLevel(skills[i].id) + skills[i].tries = self:getSkillTries(skills[i].id) + -- Sum skill tries of every skill level + for level = 11, skills[i].level do + skills[i].tries = skills[i].tries + self:getVocation():getRequiredSkillTries(skills[i].id, level) + end + end + -- Set new vocation + self:setVocation(newVocationId) + -- Convert magic level from previous vocation + local newMagicLevel = 0 + if magic.manaSpent > 0 then + local reqManaSpent = self:getVocation():getRequiredManaSpent(newMagicLevel + 1) + while magic.manaSpent >= reqManaSpent do + magic.manaSpent = magic.manaSpent - reqManaSpent + newMagicLevel = newMagicLevel + 1; + reqManaSpent = self:getVocation():getRequiredManaSpent(newMagicLevel + 1) + end + end + -- Apply magic level and/or mana spent + if newMagicLevel > 0 then + self:setMagicLevel(newMagicLevel, magic.manaSpent) + elseif magic.manaSpent > 0 then + self:addManaSpent(magic.manaSpent) + end + -- Convert skills from previous vocation + for i = 1, #skills do + local newSkillLevel = 10 + -- Calculate new level + if skills[i].tries > 0 then + local reqSkillTries = self:getVocation():getRequiredSkillTries(skills[i].id, (newSkillLevel + 1)) + while skills[i].tries >= reqSkillTries do + skills[i].tries = skills[i].tries - reqSkillTries + newSkillLevel = newSkillLevel + 1; + reqSkillTries = self:getVocation():getRequiredSkillTries(skills[i].id, (newSkillLevel + 1)) + end + end + -- Apply skill level and/or skill tries + if newSkillLevel > 10 then + self:setSkillLevel(skills[i].id, newSkillLevel, skills[i].tries) + elseif skills[i].tries > 0 then + self:addSkillTries(skills[i].id, skills[i].tries) + end + end + -- Set health, mana and capacity stats based on the vocation if is higher than level 8 + if self:getLevel() > 8 then + -- Base stats for level 1 + local stats = {health = 150, mana = 55, capacity = 40000} + -- No vocation + if self:getVocation():getId() == VOCATION.ID.NONE then + local level = self:getLevel() - 1 + stats.health = stats.health + (level * self:getVocation():getHealthGain()) + stats.mana = stats.mana + (level * self:getVocation():getManaGain()) + stats.capacity = stats.capacity + (level * self:getVocation():getCapacityGain()) + -- Main vocations + else + local baseLevel = 7 + local baseVocation = Vocation(VOCATION.ID.NONE) + local level = self:getLevel() - 8 + stats.health = stats.health + + (baseLevel * baseVocation:getHealthGain()) + (level * self:getVocation():getHealthGain()) + stats.mana = stats.mana + + (baseLevel * baseVocation:getManaGain()) + (level * self:getVocation():getManaGain()) + stats.capacity = stats.capacity + + (baseLevel * baseVocation:getCapacityGain()) + (level * self:getVocation():getCapacityGain()) + end + self:setMaxHealth(stats.health) + self:addHealth(stats.health) + self:setMaxMana(stats.mana) + self:addMana(stats.mana) + self:setCapacity(stats.capacity) + end + return true +end + +-- Checks if the skill growth is limited for a dawnport player +-- Used in onAdvance to notify and in onGainSkillTries to limit +function isSkillGrowthLimited(player, skillId) + local town = player:getTown() + -- Check that resides on dawnport + if town and town:getId() == TOWNS_LIST.DAWNPORT then + local vocationId = player:getVocation():getId() + local skillsLimit = Dawnport.skillsLimit[vocationId] + -- Check if there is set a skillId limit + if skillsLimit and skillsLimit[skillId] then + -- Get current skillId level + local skillLevel + if skillId == SKILL_MAGLEVEL then + skillLevel = player:getBaseMagicLevel() + else + skillLevel = player:getSkillLevel(skillId) + end + -- Check skillId limit + if skillLevel >= skillsLimit[skillId] then + return true + end + end + end + return false +end + +-- Removes from player inventory (equipped/containers) maindland smuggling items +function removeMainlandSmugglingItems(player) + local smugglingItemIds = { + 2461, -- Leather helmet + 2651, -- Coat + 2649, -- Leather legs + 2643, -- Leather boots + 23719, -- The scorcher + 23721, -- The chiller + 23771, -- Spellbook of the novice + 2456, -- Bow + 2379, -- Dagger + 2512, -- Wooden shield + 40397, -- Quiver + 23839, -- Simple arrow + 7618, -- Health potion + 7620, -- Mana potion + 8704, -- Small health potion + 23723, -- Lightest missile rune + 23722 -- Light stone shower rune + } + for i = 1, #smugglingItemIds do + local smugglingItemAmount = player:getItemCount(smugglingItemIds[i]) + if smugglingItemAmount > 0 then + player:removeItem(smugglingItemIds[i], smugglingItemAmount) + end + end +end diff --git a/data/lib/others/modal_window_lib.lua b/data/lib/others/modal_window_lib.lua new file mode 100644 index 00000000000..da0c70e82eb --- /dev/null +++ b/data/lib/others/modal_window_lib.lua @@ -0,0 +1,116 @@ +if not modalWindows then + modalWindows = { + modalWindowConstructor = ModalWindow, + nextFreeId = 500, + + windows = {} + } +end + +local MT = {} +MT.__index = MT + +function ModalWindow(...) + local args = {...} + if type(args[1]) == 'table' then + local self = setmetatable(args[1], MT) + local id = modalWindows.nextFreeId + self.id = id + self.buttons = {} + self.choices = {} + self.players = {} + self.created = false + + modalWindows.nextFreeId = id + 1 + table.insert(modalWindows.windows, self) + return self + end + + return modalWindows.modalWindowConstructor(...) +end + +function MT:setDefaultCallback(callback) + self.defaultCallback = callback +end + +function MT:addButton(text, callback) + local button = {text = tostring(text), callback = callback} + table.insert(self.buttons, button) + return button +end + +function MT:addButtons(...) + for _, text in ipairs({...}) do + table.insert(self.buttons, {text = tostring(text)}) + end +end + +function MT:addChoice(text) + local choice = {text = tostring(text)} + table.insert(self.choices, choice) + return choice +end + +function MT:addChoices(...) + for _, text in ipairs({...}) do + table.insert(self.choices, {text = tostring(text)}) + end +end + +function MT:setDefaultEnterButton(text) + self.defaultEnterButton = text +end + +function MT:setDefaultEscapeButton(text) + self.defaultEscapeButton = text +end + +function MT:setTitle(title) + self.title = tostring(title) +end + +function MT:setMessage(message) + self.message = tostring(message) +end + +local buttonOrder = { + [4] = {3, 4, 2, 1}, + [3] = {2, 3, 1}, + [2] = {1, 2}, + [1] = {1} +} +function MT:create() + local modalWindow = modalWindows.modalWindowConstructor(self.id, self.title, self.message) + local order = buttonOrder[math.min(#self.buttons, 4)] + + if order then + for _, i in ipairs(order) do + local button = self.buttons[i] + modalWindow:addButton(i, button.text) + button.id = i + + if button.text == self.defaultEnterButton then + modalWindow:setDefaultEnterButton(i) + elseif button.text == self.defaultEscapeButton then + modalWindow:setDefaultEscapeButton(i) + end + end + end + + for _, choice in ipairs(self.choices) do + modalWindow:addChoice(_, choice.text) + choice.id = _ + end + + self.modalWindow = modalWindow +end + +function MT:sendToPlayer(player) + if not self.modalWindow then + self:create() + end + + player:registerEvent('ModalWindowHelper') + self.players[player:getId()] = true + return self.modalWindow:sendToPlayer(player) +end diff --git a/data/lib/others/others.lua b/data/lib/others/others.lua new file mode 100644 index 00000000000..ff7aa64d10b --- /dev/null +++ b/data/lib/others/others.lua @@ -0,0 +1,5 @@ +dofile('data/lib/others/daily_reward_lib.lua') +dofile('data/lib/others/dawnport_lib.lua') +dofile('data/lib/others/modal_window_lib.lua') +dofile('data/lib/others/reward_boss_lib.lua') +dofile('data/lib/others/bath_tube.lua') diff --git a/data/lib/others/reward_boss_lib.lua b/data/lib/others/reward_boss_lib.lua new file mode 100644 index 00000000000..b4f5fb96fec --- /dev/null +++ b/data/lib/others/reward_boss_lib.lua @@ -0,0 +1,88 @@ +if not globalBosses then + globalBosses = {} +end + +function Monster.setReward(self, enable) + if enable then + if not self:getType():isRewardBoss() then + error("Rewards can only be enabled to rewards bosses.") + return false + end + globalBosses[self:getId()] = {} + self:registerEvent("BossDeath") + self:registerEvent("BossThink") + else + globalBosses[self:getId()] = nil + self:unregisterEvent("BossDeath") + self:unregisterEvent("BossThink") + end + return true +end + +local function pushValues(buffer, sep, ...) + local argv = {...} + local argc = #argv + for k, v in ipairs(argv) do + table.insert(buffer, v) + if k < argc and sep then + table.insert(buffer, sep) + end + end +end + +function Player.getRewardChest(self, autocreate) + return self:getDepotChest(99, autocreate) +end + +function Player.inBossFight(self) + if not next(globalBosses) then + return false + end + local playerGuid = self:getGuid() + + for _, info in pairs(globalBosses) do + local stats = info[playerGuid] + if stats and stats.active then + return stats + end + end + return false +end + +function MonsterType.createLootItem(self, lootBlock, chance, lootTable) + local lootTable, itemCount = lootTable or {}, 0 + local randvalue = math.random(0, 100000) / (getConfigInfo("rateLoot") * chance) + if randvalue < lootBlock.chance then + if (ItemType(lootBlock.itemId):isStackable()) then + itemCount = randvalue % lootBlock.maxCount + 1 + else + itemCount = 1 + end + end + + while itemCount > 0 do + local n = math.min(itemCount, 100) + itemCount = itemCount - n + table.insert(lootTable, {lootBlock.itemId, n}) + end + + return lootTable +end + +function MonsterType.getBossReward(self, lootFactor, topScore) + local result = {} + if getConfigInfo("rateLoot") > 0 then + local loot = self:getLoot() or {} + for i = #loot, 0, -1 do + local lootBlock = loot[i] + if lootBlock then + if lootBlock.unique and not topScore then + --continue + else + self:createLootItem(lootBlock, lootFactor, result) + end + end + end + end + return result +end diff --git a/data/lib/player_processor/load.lua b/data/lib/player_processor/load.lua new file mode 100644 index 00000000000..7d6c8ef8ff3 --- /dev/null +++ b/data/lib/player_processor/load.lua @@ -0,0 +1,4 @@ +dofile('data/lib/player_processor/player_config.lua') +dofile('data/lib/player_processor/player_updater.lua') +dofile('data/lib/player_processor/player_validator.lua') +dofile('data/lib/player_processor/player_processing_configs.lua') \ No newline at end of file diff --git a/data/lib/player_processor/player_config.lua b/data/lib/player_processor/player_config.lua new file mode 100644 index 00000000000..14024c25dda --- /dev/null +++ b/data/lib/player_processor/player_config.lua @@ -0,0 +1,64 @@ +PlayerConfig = {} + +ConfigsTypes = { + CONFIG_EQ = 1, + CONFIG_NEQ = 2, + CONFIG_GTE = 3, + CONFIG_LTE = 4, +} + +function PlayerConfig:new(value, type) + obj = { + value = value or 0, + type = type or ConfigsTypes.CONFIG_EQ, + } + + setmetatable(obj, self) + self.__index = self + return obj +end + +function PlayerConfig:getValue(player) + return type(self.value) == "function" and self.value(player) or self.value +end + +function PlayerConfig:checkValue(value, player) + local currentValue = self:getValue(player) + + if type(currentValue) == "number" then + if self.type == ConfigsTypes.CONFIG_GTE then + return value >= currentValue + end + + if self.type == ConfigsTypes.CONFIG_LTE then + return value <= currentValue + end + end + + if self.type == ConfigsTypes.CONFIG_NEQ then + if type(currentValue) == table and #currentValue > 0 then + for _, v in ipairs(currentValue) do + if v == value then return false end + end + return true + end + return currentValue ~= value + end + + if type(currentValue) == table and #currentValue > 0 then + for _, v in ipairs(currentValue) do + if v ~= value then return false end + end + return true + end + + return currentValue == value +end + +function PlayerConfig:setValue(value) + self.value = value +end + +function PlayerConfig:appendValue(value) + self.value = self.value + value +end diff --git a/data/lib/player_processor/player_processing_configs.lua b/data/lib/player_processor/player_processing_configs.lua new file mode 100644 index 00000000000..a5bf1ed0504 --- /dev/null +++ b/data/lib/player_processor/player_processing_configs.lua @@ -0,0 +1,91 @@ +PlayerProcessingConfigs = {} + +function PlayerProcessingConfigs:new() + obj = { + moneyAmount = nil, + position = nil, + storages = {}, + items = {}, + callbacks = {}, + premium = nil, + promotion = nil, + level = nil, + protectionZone = nil, + vocation = nil, + } + + setmetatable(obj, self) + self.__index = self + return obj +end + +function PlayerProcessingConfigs:validate(player, actor) + return PlayerValidator(self, player, actor) +end + +function PlayerProcessingConfigs:update(player, actor) + return PlayerUpdater(self, player, actor) +end + +function PlayerProcessingConfigs:addStorage(key, value, configType) + self.storages[key] = PlayerConfig:new(value, configType) + return self +end + +function PlayerProcessingConfigs:addAmount(amount, configType) + if not self.moneyAmount then + self.moneyAmount = PlayerConfig:new(amount, configType or ConfigsTypes.CONFIG_GTE) + else + self.moneyAmount:appendValue(amount) + end + return self +end + +function PlayerProcessingConfigs:removeAmount(amount, configType) + self:addAmount(-amount, configType) + return self +end + +function PlayerProcessingConfigs:addItem(itemId, count, configType) + if not self.items[itemId] then + self.items[itemId] = PlayerConfig:new(count, configType or ConfigsTypes.CONFIG_GTE) + else + self.items[itemId]:appendValue(count) + end + return self +end + +function PlayerProcessingConfigs:addPosition(position, configType) + self.position = PlayerConfig:new(position, configType) + return self +end + +function PlayerProcessingConfigs:addCallback(callback) + self.callbacks[#self.callbacks + 1] = callback + return self +end + +function PlayerProcessingConfigs:addLevel(level, configType) + self.level = PlayerConfig:new(level, configType) + return self +end + +function PlayerProcessingConfigs:addVocation(vocation, configType) + self.vocation = PlayerConfig:new(vocation, configType) + return self +end + +function PlayerProcessingConfigs:addPromotion(promotion) + self.promotion = promotion + return self +end + +function PlayerProcessingConfigs:addPremium(premium) + self.premium = premium + return self +end + +function PlayerProcessingConfigs:addProtectionZone(protectionZone) + self.protectionZone = protectionZone + return self +end \ No newline at end of file diff --git a/data/lib/player_processor/player_updater.lua b/data/lib/player_processor/player_updater.lua new file mode 100644 index 00000000000..94de7fbbc3b --- /dev/null +++ b/data/lib/player_processor/player_updater.lua @@ -0,0 +1,51 @@ +PlayerUpdater = {} +setmetatable(PlayerUpdater, { + __call = + function(self, configs, player, actor) + if not player or not player:isPlayer() then + error("PlayerUpdater needs a valid player to run") + end + + for i,parse in pairs(self) do + parse(configs, player, actor) + end + end +}) + +PlayerUpdater.updateMoney = function (configs, player) + if not configs.moneyAmount then return end + + local amount = configs.moneyAmount:getValue(player) + if amount < 0 then + player:removeMoneyIncludingBalance(math.abs(amount)) + elseif amount > 0 then + player:addMoney(amount) + end +end + +PlayerUpdater.updatePosition = function (configs, player) + if not configs.position then return end + player:teleportTo(configs.position:getValue(player)) +end + +PlayerUpdater.updateItems = function (configs, player) + for itemId, itemConfig in pairs(configs.items) do + if itemConfig.value < 0 then + player:removeItem(itemId, math.abs(itemConfig:getValue(player))) + elseif itemConfig.value > 0 then + player:addItem(itemId, itemConfig:getValue(player)) + end + end +end + +PlayerUpdater.updateStorages = function (configs, player) + for storage, storageConfig in pairs(configs.storages) do + player:setStorageValue(storage, storageConfig:getValue(player)) + end +end + +PlayerUpdater.runUpdateCallbacks = function (configs, player, actor) + for _, callback in pairs(configs.callbacks) do + callback(player, actor) + end +end \ No newline at end of file diff --git a/data/lib/player_processor/player_validator.lua b/data/lib/player_processor/player_validator.lua new file mode 100644 index 00000000000..512b7a9e2bc --- /dev/null +++ b/data/lib/player_processor/player_validator.lua @@ -0,0 +1,53 @@ +PlayerValidator = {} +setmetatable(PlayerValidator, { + __call = + function(self, configs, player) + if not player or not player:isPlayer() then + error("PlayerValidator needs a valid player to run") + end + + for _,parse in pairs(self) do + if not parse(configs, player) then + return false + end + end + return true + end +}) + +PlayerValidator.validateMoney = function (configs, player) + if not configs.moneyAmount then return true end + return configs.moneyAmount:checkValue(player:getTotalMoney()) +end + +PlayerValidator.validatePosition = function (configs, player) + if not configs.position then return true end + return configs.position:checkValue(player:getPosition()) +end + +PlayerValidator.validateItems = function (configs, player) + for itemId, itemConfig in pairs(configs.items) do + if not itemConfig:checkValue(player:getItemCount(itemId)) then + return false + end + end + return true +end + +PlayerValidator.validateStorages = function (configs, player) + for storage, storageConfig in pairs(configs.storages) do + if not storageConfig:checkValue(player:getStorageValue(storage)) then + return false + end + end + return true +end + +PlayerValidator.validateCallbacks = function (configs, player) + for _, callback in pairs(configs.callbacks) do + if not callback(player) then + return false + end + end + return true +end \ No newline at end of file diff --git a/data/lib/quests/bigfoot_burden.lua b/data/lib/quests/bigfoot_burden.lua new file mode 100644 index 00000000000..a40124998bc --- /dev/null +++ b/data/lib/quests/bigfoot_burden.lua @@ -0,0 +1,73 @@ +if not warzoneConfig then + warzoneConfig = { + [45700] = { + center = Position(33110, 31965, 10), + maxRangeX = 12, minRangeX = 26, minRangeY = 15, maxRangeY = 17, + bossResp = Position(33102, 31956, 10), + boss = "Deathstrike", + teleportTo = Position(33096, 31955, 10), + locked = false, + storage = Storage.BigfootBurden.BossWarzone1, + interval = 20 * 60 * 60,-- 20 hours + exit = Position(33001, 31900, 9) + }, + [45701] = { + center = Position(33117, 31956, 11), + maxRangeX = 14, minRangeX = 14, minRangeY = 14, maxRangeY = 14, + bossResp = Position(33116, 31956, 11), + boss = "Gnomevil", + teleportTo = Position(33106, 31955, 11), + locked = false, + storage = Storage.BigfootBurden.BossWarzone2, + interval = 20 * 60 * 60,-- 20 hours + exit = Position(33001, 31900, 9), + wall = 18459 --Id of current crystais in warzone 2 (open killing parasite) + }, + [45702] = { + center = Position(33090, 31910, 12), + maxRangeX = 12, minRangeX = 12, minRangeY = 12, maxRangeY = 12, + bossResp = Position(33088, 31910, 12), + boss = "Abyssador", + teleportTo = Position(33083, 31904, 12), --Place where the player will be teleported inside the room + locked = false, + storage = Storage.BigfootBurden.BossWarzone3, + interval = 20 * 60 * 60,-- 20 hours + exit = Position(33001, 31900, 9) + } + } + + warzoneConfig.spawnBoss = function (name, pos) + local boss = Game.createMonster(name, pos, false, true) + if boss then + local c = warzoneConfig.findByName(name) + c.locked = true + boss:registerEvent('BossWarzoneDeath') + end + end + warzoneConfig.findByName = function(name, last) + local i, v = next(warzoneConfig, last) + if type(v) == 'table' and v.boss == name then + return v + elseif not i then + return nil + end + return warzoneConfig.findByName(name, i) + end + + warzoneConfig.resetRoom = function(roomwarzone, msg, releaseRoom) + if releaseRoom then + roomwarzone.locked = false + end + + local spectators = Game.getSpectators(roomwarzone.center, false, false, + roomwarzone.minRangeX, roomwarzone.maxRangeX, roomwarzone.minRangeY, roomwarzone.maxRangeY) + for i = 1, #spectators do + if spectators[i]:isPlayer() then + spectators[i]:teleportTo(roomwarzone.exit) + spectators[i]:sendTextMessage(MESSAGE_EVENT_ADVANCE, msg) + else + spectators[i]:remove() + end + end + end +end diff --git a/data/lib/quests/demon_oak.lua b/data/lib/quests/demon_oak.lua new file mode 100644 index 00000000000..1bfc6a3e3be --- /dev/null +++ b/data/lib/quests/demon_oak.lua @@ -0,0 +1,4 @@ +DEMON_OAK_POSITION = Position(32716, 32351, 7) +DEMON_OAK_KICK_POSITION = Position(32716, 32340, 7) +DEMON_OAK_ENTER_POSITION = Position(32716, 32347, 7) +DEMON_OAK_REWARDROOM_POSITION = Position(32714, 32398, 8) diff --git a/data/lib/quests/killing_in_the_name_of.lua b/data/lib/quests/killing_in_the_name_of.lua new file mode 100644 index 00000000000..726c6e9682e --- /dev/null +++ b/data/lib/quests/killing_in_the_name_of.lua @@ -0,0 +1,944 @@ +--[[ +TODO +Unite all related variables/functions in a table +rewrite functions like "getTasksByPlayer" to "Player.getTasks" +]] + +RANK_NONE = 0 +RANK_JOIN = 1 +RANK_HUNTSMAN = 2 +RANK_RANGER = 3 +RANK_BIGGAMEHUNTER = 4 +RANK_TROPHYHUNTER = 5 +RANK_ELITEHUNTER = 6 + +REWARD_MONEY = 1 +REWARD_EXP = 2 +REWARD_ACHIEVEMENT = 3 +REWARD_STORAGE = 4 +REWARD_POINT = 5 +REWARD_ITEM = 6 + +QUESTSTORAGE_BASE = 1500 +JOIN_STOR = 100157 +KILLSSTORAGE_BASE = 65000 +REPEATSTORAGE_BASE = 48950 +POINTSSTORAGE = 2500 +tasks = +{ + [1] = { + killsRequired = 100, + raceName = "Trolls", + level = {6, 19}, + premium = true, + creatures = { + "troll", + "troll champion", + "island troll", + "swamp troll" + }, + rewards = { + {type = "exp", value = {200}}, + {type = "money", value = {200}} + } + }, + [2] = { + killsRequired = 150, + raceName = "Goblins", + level = {6, 19}, + premium = true, + creatures = { + "goblin", + "goblin assassin", + "goblin leader" + }, + rewards = { + {type = "exp", value = {300}}, + {type = "money", value = {250}} + } + }, + [3] = { + killsRequired = 300, + raceName = "Crocodiles", + level = {6, 49}, + premium = true, + creatures = { + "crocodile" + }, + rewards = { + {type = "exp", value = {800}}, + {type = "achievement", value = {"Blood-Red Snapper"}}, + {type = "storage", value = {34100, 1}}, + {type = "points", value = {1}} + } + }, + [4] = { + killsRequired = 300, + raceName = "Badgers", + level = {6, 49}, + premium = true, + creatures = { + "badger" + }, + rewards = { + {type = "exp", value = {500}}, + {type = "points", value = {1}} + } + }, + [5] = { + killsRequired = 300, + raceName = "Tarantulas", + level = {6, 49}, + premium = true, + creatures = { + "tarantula" + }, + rewards = { + {type = "exp", value = {1500}}, + {type = "achievement", value = {"No More Hiding"}}, + {type = "storage", value = {34101, 1}}, + {type = "points", value = {2}} + } + }, + [6] = { + killsRequired = 150, + raceName = "Carniphilas", + level = {6, 999}, + premium = true, + creatures = { + "carniphila" + }, + rewards = { + {type = "exp", value = {2500}}, + {type = "achievement", value = {"Rootless Behaviour"}}, + {type = "storage", value = {34102, 1}}, + {type = "points", value = {3}} + } + }, + [7] = { + killsRequired = 200, + raceName = "Stone Golems", + level = {6, 49}, + premium = true, + creatures = { + "stone golem" + }, + rewards = { + {type = "exp", value = {2000}}, + {type = "points", value = {3}} + } + }, + [8] = { + killsRequired = 300, + raceName = "Mammoths", + level = {6, 49}, + premium = true, + creatures = { + "mammoth" + }, + rewards = { + {type = "exp", value = {4000}}, + {type = "achievement", value = {"Meat Skewer"}}, + {type = "storage", value = {34103, 1}}, + {type = "points", value = {3}} + } + }, + [9] = { + killsRequired = 300, + raceName = "Gnarlhounds", + level = {6, 49}, + premium = true, + creatures = { + "gnarlhound" + }, + rewards = { + {type = "exp", value = {1000}}, + {type = "points", value = {2}} + } + }, + [10] = { + killsRequired = 300, + raceName = "Terramites", + level = {6, 49}, + premium = true, + creatures = { + "terramite" + }, + rewards = { + {type = "exp", value = {1000}}, + {type = "points", value = {2}} + } + }, + [11] = { + killsRequired = 300, + raceName = "Apes", + level = {6, 49}, + premium = true, + creatures = { + "kongra", + "sibang", + "merklin" + }, + rewards = { + {type = "exp", value = {1000}}, + {type = "points", value = {2}} + } + }, + [12] = { + killsRequired = 300, + raceName = "Thornback Tortoises", + level = {6, 49}, + premium = true, + creatures = { + "thornback tortoise" + }, + rewards = { + {type = "exp", value = {1500}}, + {type = "points", value = {2}} + } + }, + [13] = { + killsRequired = 300, + raceName = "Gargoyles", + level = {6, 49}, + premium = true, + creatures = { + "gargoyle" + }, + rewards = { + {type = "exp", value = {1500}} + } + }, + [14] = { + killsRequired = 300, + raceName = "Ice Golems", + level = {50, 79}, + premium = true, + creatures = { + "ice golem" + }, + rewards = { + {type = "exp", value = {12000}}, + {type = "achievement", value = {"Breaking The Ice"}}, + {type = "storage", value = {34104, 1}}, + {type = "points", value = {2}} + } + }, + [15] = { + killsRequired = 400, + raceName = "Quara Scouts", + level = {50, 999}, + premium = true, + creatures = { + "quara pincher scout", + "quara predator scout", + "quara hydromancer scout", + "quara constrictor scout", + "quara mantassin scout" + }, + rewards = { + {type = "exp", value = {10000}}, + {type = "points", value = {2}} + } + }, + [16] = { + killsRequired = 400, + raceName = "Mutated Rats", + level = {50, 999}, + premium = true, + creatures = { + "mutated rat" + }, + rewards = { + {type = "exp", value = {10000}}, + {type = "achievement", value = {"Twisted Mutation"}}, + {type = "storage", value = {34105, 1}}, + {type = "points", value = {2}} + } + }, + [17] = { + killsRequired = 250, + raceName = "Ancient Scarabs", + level = {50, 999}, + premium = true, + creatures = { + "ancient scarab" + }, + rewards = { + {type = "exp", value = {15000}}, + {type = "achievement", value = {"Crawling Death"}}, + {type = "storage", value = {34106, 1}}, + {type = "points", value = {2}} + } + }, + [18] = { + killsRequired = 300, + raceName = "Wyverns", + level = {50, 999}, + premium = true, + creatures = { + "wyvern" + }, + rewards = { + {type = "exp", value = {12000}}, + {type = "points", value = {2}} + } + }, + [19] = { + killsRequired = 300, + raceName = "Lancer Beetles", + level = {50, 79}, + premium = true, + creatures = { + "lancer beetle" + }, + rewards = { + {type = "exp", value = {8000}}, + {type = "points", value = {2}} + } + }, + [20] = { + killsRequired = 400, + raceName = "Wailing Widows", + level = {50, 999}, + premium = true, + creatures = { + "wailing widow" + }, + rewards = { + {type = "exp", value = {12000}}, + {type = "points", value = {3}} + } + }, + [21] = { + killsRequired = 250, + raceName = "Killer Caimans", + level = {50, 999}, + premium = true, + creatures = { + "killer caiman" + }, + rewards = { + {type = "exp", value = {10000}}, + {type = "points", value = {2}} + } + }, + [22] = { + killsRequired = 300, + raceName = "Bonebeasts", + level = {50, 999}, + premium = true, + creatures = { + "bonebeast" + }, + rewards = { + {type = "exp", value = {12000}}, + {type = "achievement", value = {"Spareribs for Dinner"}}, + {type = "storage", value = {34107, 1}}, + {type = "points", value = {2}} + } + }, + [23] = { + killsRequired = 300, + raceName = "Crystal Spiders", + level = {50, 999}, + creatures = { + "crystal spider"}, + premium = true, + rewards = { + {type = "exp", value = {15000}}, + {type = "achievement", value = {"Arachnoise"}}, + {type = "storage", value = {34108, 1}}, + {type = "points", value = {3}} + } + }, + [24] = { + killsRequired = 300, + raceName = "Mutated Tigers", + level = {50, 999}, + premium = true, + creatures = { + "mutated tiger" + }, + rewards = { + {type = "exp", value = {12000}}, + {type = "points", value = {2}} + } + }, + [25] = { + killsRequired = 600, + raceName = "Underwater Quara", + level = {80, 999}, + premium = true, + creatures = { + "quara hydromancer", + "quara predator", + "quara constrictor", + "quara mantassin", + "quara pincher" + }, + rewards = { + {type = "exp", value = {15000}}, + {type = "achievement", value = {"Back into the Abyss"}}, + {type = "storage", value = {34109, 1}}, + {type = "points", value = {3}} + } + }, + [26] = { + killsRequired = 500, + raceName = "Giant Spiders", + level = {80, 999}, + premium = true, + creatures = { + "giant spider" + }, + rewards = { + {type = "exp", value = {20000}}, + {type = "achievement", value = {"Choking on Her Venom"}}, + {type = "storage", value = {34110, 1}}, + {type = "points", value = {3}} + } + }, + [27] = { + killsRequired = 300, + raceName = "Werewolves", + level = {80, 999}, + premium = true, + creatures = { + "werewolf" + }, + rewards = { + {type = "exp", value = {30000}}, + {type = "achievement", value = {"Howly Silence"}}, + {type = "storage", value = {34111, 1}}, + {type = "points", value = {4}} + } + }, + [28] = { + killsRequired = 400, + raceName = "Nightmares", + level = {80, 999}, + premium = true, + creatures = { + "nightmare", + "nightmare scion" + }, + rewards = { + {type = "exp", value = {25000}}, + {type = "achievement", value = {"Dream is Over"}}, + {type = "storage", value = {34112, 1}}, + {type = "points", value = {3}} + } + }, + [29] = { + killsRequired = 600, + raceName = "Hellspawns", + level = {80, 999}, + premium = true, + creatures = { + "hellspawn" + }, + rewards = { + {type = "exp", value = {25000}}, + {type = "achievement", value = {"Scorched Flames"}}, + {type = "storage", value = {34113, 1}} + } + }, + [30] = { + killsRequired = 800, + raceName = "High Class Lizards", + level = {80, 999}, + premium = true, + creatures = { + "lizard chosen", + "lizard dragon priest", + "lizard high guard", + "lizard legionnaire" + }, + rewards = { + {type = "exp", value = {30000}}, + {type = "achievement", value = {"Zzztill Zzztanding!"}}, + {type = "storage", value = {34114, 1}}, + {type = "points", value = {3}} + } + }, + [31] = { + killsRequired = 600, + raceName = "Stampors", + level = {80, 999}, + premium = true, + creatures = { + "stampor" + }, + rewards = { + {type = "exp", value = {20000}}, + {type = "achievement", value = {"Stepped on a Big Toe"}}, + {type = "storage", value = {34115, 1}}, + {type = "points", value = {3}} + } + }, + [32] = { + killsRequired = 500, + raceName = "Brimstone Bugs", + level = {80, 999}, + premium = true, + creatures = { + "brimstone bug" + }, + rewards = { + {type = "exp", value = {15000}}, + {type = "achievement", value = {"Something Smells"}}, + {type = "storage", value = {34116, 1}}, + {type = "points", value = {3}} + } + }, + [33] = { + killsRequired = 400, + raceName = "Mutated Bats", + level = {80, 999}, + premium = true, + creatures = { + "mutated bat" + }, + rewards = { + {type = "exp", value = {20000}}, + {type = "achievement", value = {"Kapow!"}}, + {type = "storage", value = {34117, 1}}, + {type = "points", value = {2}} + } + }, + [34] = { + killsRequired = 650, + raceName = "Hydras", + level = {130, 9999}, + premium = true, + creatures = { + "hydra" + }, + rewards = { + {type = "exp", value = {30000}}, + {type = "achievement", value = {"One Less"}}, + {type = "storage", value = {34118, 1}}, + {type = "points", value = {3}} + } + }, + [35] = { + killsRequired = 800, + raceName = "Serpent Spawns", + level = {130, 9999}, + premium = true, + creatures = { + "serpent spawn" + }, + rewards = { + {type = "exp", value = {30000}}, + {type = "achievement", value = {"Hissing Downfall"}}, + {type = "storage", value = {34119, 1}}, + {type = "points", value = {4}} + } + }, + [36] = { + killsRequired = 500, + raceName = "Medusas", + level = {130, 9999}, + premium = true, + creatures = { + "medusa" + }, + rewards = { + {type = "exp", value = {40000}}, + {type = "achievement", value = {"The Serpent's Bride"}}, + {type = "storage", value = {34120, 1}}, + {type = "points", value = {5}} + } + }, + [37] = { + killsRequired = 700, + raceName = "Behemoths", + level = {130, 9999}, + premium = true, + creatures = { + "behemoth" + }, + rewards = { + {type = "exp", value = {30000}}, + {type = "achievement", value = {"Just Cracked Me Up!"}}, + {type = "storage", value = {34121, 1}}, + {type = "points", value = {4}} + } + }, + [38] = { + killsRequired = 900, + raceName = "Sea Serpents and Young Sea Serpents", + level = {130, 9999}, + premium = true, + creatures = { + "sea serpent", + "young sea serpent" + }, + rewards = { + {type = "exp", value = {30000}}, + {type = "achievement", value = {"The Drowned Sea God"}}, + {type = "storage", value = {34122, 1}}, + {type = "points", value = {4}} + } + }, + [39] = { + killsRequired = 250, + raceName = "Hellhounds", + level = {130, 9999}, + premium = true, + creatures = { + "hellhound" + }, + rewards = { + {type = "exp", value = {40000}}, + {type = "achievement", value = {"The Gates of Hell"}}, + {type = "storage", value = {34123, 1}}, + {type = "points", value = {5}} + } + }, + [40] = { + killsRequired = 500, + raceName = "Ghastly Dragons", + level = {130, 9999}, + premium = true, + creatures = { + "ghastly dragon" + }, + rewards = { + {type = "exp", value = {30000}}, + {type = "achievement", value = {"Beautiful Agony"}}, + {type = "storage", value = {34124, 1}}, + {type = "points", value = {5}} + } + }, + [41] = { + killsRequired = 900, + raceName = "Drakens", + level = {130, 9999}, + premium = true, + creatures = { + "draken spellweaver", + "draken warmaster", + "draken abomination", + "draken elite"} , + rewards = { + {type = "exp", value = {30000}}, + {type = "achievement", value = {"Enter zze Draken!"}}, + {type = "storage", value = {34125, 1}}, + {type = "points", value = {3}} + } + }, + [42] = { + killsRequired = 650, + raceName = "Destroyers", + level = {130, 9999}, + premium = true, + creatures = { + "destroyer" + }, + rewards = { + {type = "exp", value = {30000}}, + {type = "achievement", value = {"Best there was!"}}, + {type = "storage", value = {34126, 1}}, + {type = "points", value = {4}} + } + }, + [43] = { + killsRequired = 400, + raceName = "Undead Dragons", + level = {130, 9999}, + premium = true, + creatures = { + "undead dragon" + }, + rewards = { + {type = "exp", value = {50000}}, + {type = "achievement", value = {"Back from the Dead"}}, + {type = "storage", value = {34127, 1}}, + {type = "points", value = {6}} + } + }, + [44] = { + killsRequired = 6666, + raceName = "Demons", + level = {130, 9999}, rank = RANK_ELITEHUNTER, + premium = true, + creatures = { + "demon" + }, + rewards = { + {type = "item", value = {10305, 1}}, + {type = "storage", value = {41300, 1}} + } + }, + [45] = { + killsRequired = 500, + raceName = "Green Djinns or Efreets", + level = {1, 9999}, storage = {12500, 1}, + premium = true, + creatures = { + "green djinn", + "efreet" + }, + rewards = { + {type = "exp", value = {10000}}, + {type = "money", value = {5000}}, + {type = "storage", value = {34128, 1}} + } + }, + [46] = { + killsRequired = 500, + raceName = "Blue Djinns or Marids", + level = {1, 9999}, storage = {12501, 1}, + premium = true, + creatures = { + "blue djinn", + "marid" + }, + rewards = { + {type = "exp", value = {10000}}, + {type = "money", value = {5000}}, + {type = "storage", value = {34129, 1}} + } + }, + [47] = { + killsRequired = 3000, + raceName = "Pirates", + level = {1, 9999}, storage = {65047, 1}, + premium = true, + creatures = { + "pirate ghost", + "pirate marauder", + "pirate cutthroad", + "pirate buccaneer", + "pirate corsair", + "pirate skeleton" + }, + rewards = { + {type = "exp", value = {10000}}, + {type = "money", value = {5000}}, + {type = "storage", value = {17523, 1}} + } + }, + [48] = { + killsRequired = 3000, + raceName = "Pirates second task", + level = {1, 9999}, storage = {REPEATSTORAGE_BASE + 47, 3}, norepeatable = true, + premium = true, + creatures = { + "pirate ghost", + "pirate marauder", + "pirate cutthroad", + "pirate buccaneer", + "pirate corsair", + "pirate skeleton" + }, + rewards = { + {type = "exp", value = {10000}}, + {type = "money", value = {5000}}, + {type = "storage", value = {17523, 1}} + } + }, + [49] = { + killsRequired = 5000, + raceName = "Minotaurs", + level = {1, 9999}, storage = {12700, 1}, norepeatable = true, + premium = false, + creatures = { + "minotaur", + "minotaur mage", + "minotaur archer" + }, + rewards = { + {type = "storage", value = {17522, 1}} + } + }, + [50] = { + killsRequired = 4000, + raceName = "Necromancers and Priestess", + level = {60, 9999}, norepeatable = true, + premium = true, + creatures = { + "necromancer", + "priestess" + }, + rewards = { + {type = "storage", value = {34133, 1}}, + {type = "storage", value = {17521, 1}} + } + }, + [51] = { + killsRequired = 20, + raceName = "Mountain Trolls", + level = {1, 9999}, storage = {12701, 1}, norepeatable = true, + premium = false, + creatures = { + "mountain trolls" + }, + rewards = { + {type = "storage", value = {17524, 1}} + } + }, + [52] = { + killsRequired = 20, + raceName = "Muglex Clan Footman", + level = {1, 9999}, storage = {12702, 1}, norepeatable = true, + premium = false, + creatures = { + "muglex clan footman " + }, + rewards = { + {type = "storage", value = {17525, 1}} + } + }, + [53] = { + killsRequired = 20, + raceName = "Minotaur Bruisers", + level = {1, 9999}, storage = {12703, 1}, norepeatable = true, + premium = false, + creatures = { + "minotaur bruisers" + }, + rewards = { + {type = "storage", value = {17526, 1}} + } + }, +} + +tasksByPlayer = 3 +repeatTimes = 3 + +function Player.getPawAndFurRank(self) + return (self:getStorageValue(POINTSSTORAGE) >= 100 + and RANK_ELITEHUNTER or self:getStorageValue(POINTSSTORAGE) >= 70 + and RANK_TROPHYHUNTER or self:getStorageValue(POINTSSTORAGE) >= 40 + and RANK_BIGGAMEHUNTER or self:getStorageValue(POINTSSTORAGE) >= 20 + and RANK_RANGER or self:getStorageValue(POINTSSTORAGE) >= 10 + and RANK_HUNTSMAN or self:getStorageValue(JOIN_STOR) == 1 + and RANK_JOIN or RANK_NONE) +end + +function Player.getPawAndFurPoints(self) + return math.max(self:getStorageValue(POINTSSTORAGE), 0) +end + +function getTaskByName(name, table) + local t = (table and table or tasks) + for k, v in pairs(t) do + if v.name then + if v.name:lower() == name:lower() then + return k + end + else + if v.raceName:lower() == name:lower() then + return k + end + end + end + return false +end + +function Player.getTasks(self) + local canmake = {} + local able = {} + for k, v in pairs(tasks) do + if self:getStorageValue(QUESTSTORAGE_BASE + k) < 1 and self:getStorageValue(REPEATSTORAGE_BASE + k) < repeatTimes then + able[k] = true + if self:getLevel() < v.level[1] or self:getLevel() > v.level[2] then + able[k] = false + end + if v.storage and self:getStorageValue(v.storage[1]) < v.storage[2] then + able[k] = false + end + + if v.rank then + if self:getPawAndFurRank() < v.rank then + able[k] = false + end + end + + if v.premium then + if not self:isPremium() then + able[k] = false + end + end + + if able[k] then + canmake[#canmake + 1] = k + end + end + end + return canmake +end + +function Player.canStartTask(self, name, table) + local v = "" + local id = 0 + local t = (table and table or tasks) + for k, i in pairs(t) do + if i.name then + if i.name:lower() == name:lower() then + v = i + id = k + break + end + else + if i.raceName:lower() == name:lower() then + v = i + id = k + break + end + end + end + if v == "" then + return false + end + if self:getStorageValue(QUESTSTORAGE_BASE + id) > 0 then + return false + end + if self:getStorageValue(REPEATSTORAGE_BASE + id) >= repeatTimes or v.norepeatable and self:getStorageValue(REPEATSTORAGE_BASE + id) > 0 then + return false + end + if v.level and self:getLevel() >= v.level[1] and self:getLevel() <= v.level[2] then + if v.premium then + if self:isPremium() then + if v.rank then + if self:getPawAndFurRank() >= v.rank then + if v.storage then + if self:getStorageValue(v.storage[1]) >= v.storage then + return true + end + else + return true + end + end + else + return true + end + else + return true + end + else + return true + end + end + return false +end + +function Player.getStartedTasks(self) + local tmp = {} + for k, v in pairs(tasks) do + if self:getStorageValue(QUESTSTORAGE_BASE + k) > 0 and self:getStorageValue(QUESTSTORAGE_BASE + k) < 2 then + tmp[#tmp + 1] = k + end + end + return tmp +end + +function getPlayerRank(cid) local p = Player(cid) return p and p:getPawAndFurRank() end +function getPlayerTasksPoints(cid) local p = Player(cid) return p and p:getPawAndFurPoints() end +function getTasksByPlayer(cid) local p = Player(cid) return p and p:getTasks() end +function canStartTask(cid, name, table) local p = Player(cid) return p and p:canStartTask(name, table) end +function getPlayerStartedTasks(cid) local p = Player(cid) return p and p:getStartedTasks() end diff --git a/data/lib/quests/quest.lua b/data/lib/quests/quest.lua new file mode 100644 index 00000000000..97e61f409a1 --- /dev/null +++ b/data/lib/quests/quest.lua @@ -0,0 +1,7 @@ +dofile('data/lib/quests/bigfoot_burden.lua') +dofile('data/lib/quests/demon_oak.lua') +dofile('data/lib/quests/killing_in_the_name_of.lua') +dofile('data/lib/quests/svargrond_arena.lua') +dofile('data/lib/quests/the_cursed_crystal.lua') +dofile('data/lib/quests/the_queen_of_the_banshees.lua') +dofile('data/lib/quests/their_masters_voice.lua') diff --git a/data/lib/quests/svargrond_arena.lua b/data/lib/quests/svargrond_arena.lua new file mode 100644 index 00000000000..7d40e193cfd --- /dev/null +++ b/data/lib/quests/svargrond_arena.lua @@ -0,0 +1,345 @@ +--[[ +TODO +- Include PITS and ARENA table in SvargrondArena -> SvargrondArena.arenas / SvargrondArena.PitDoors +- Restructure PITS and ARENA table (reward.storage does not seem to be used) +]] + +SvargrondArena = { + -- kick time in seconds (10 minutes) + kickTime = 600, + kickPosition = Position({x = 32251, y = 31098, z = 6}), + rewardPosition = Position({x = 32222, y = 31080, z = 6}), + + -- used to store event ids + kickEvents = {}, + timerEvents = {}, + effectPositionCache = {}, + + -- item ids used by the script + itemTimer = 10288, + itemPillar = 1354, + itemTeleport = 5023, + itemsNotErasable = {10288, 1354, 1543, 1544, 1545}, +} + +-- Script automatically derives other pit positions from this one +local firstPit = { + fromPos = {x = 32205, y = 31094, z = 7}, + toPos = {x = 32214, y = 31103, z = 7}, + center = {x = 32210, y = 31098, z = 7}, + pillar = {x = 32204, y = 31098, z = 7}, + tp = {x = 32204, y = 31098, z = 7}, + summon = {x = 32210, y = 31100, z = 7} +} + +PITS = { + [1] = { + fromPos = firstPit.fromPos, + toPos = firstPit.toPos, + center = firstPit.center, + pillar = firstPit.pillar, + tp = firstPit.tp, + summon = firstPit.summon + }, + [2] = { + fromPos = {x = firstPit.fromPos.x - 14, y = firstPit.fromPos.y, z = firstPit.fromPos.z}, + toPos = {x = firstPit.toPos.x - 14, y = firstPit.toPos.y, z = firstPit.toPos.z}, + center = {x = firstPit.center.x - 14, y = firstPit.center.y, z = firstPit.center.z}, + pillar = {x = firstPit.pillar.x - 14, y = firstPit.pillar.y, z = firstPit.pillar.z}, + tp = {x = firstPit.tp.x - 14, y = firstPit.tp.y, z = firstPit.tp.z}, + summon = {x = firstPit.summon.x - 14, y = firstPit.summon.y, z = firstPit.summon.z} + }, + [3] = { + fromPos = {x = firstPit.fromPos.x - 28, y = firstPit.fromPos.y, z = firstPit.fromPos.z}, + toPos = {x = firstPit.toPos.x - 28, y = firstPit.toPos.y, z = firstPit.toPos.z}, + center = {x = firstPit.center.x - 28, y = firstPit.center.y, z = firstPit.center.z}, + pillar = {x = firstPit.pillar.x - 28, y = firstPit.pillar.y, z = firstPit.pillar.z}, + tp = {x = firstPit.tp.x - 28, y = firstPit.tp.y, z = firstPit.tp.z}, + summon = {x = firstPit.summon.x - 28, y = firstPit.summon.y, z = firstPit.summon.z} + }, + [4] = { + fromPos = {x = firstPit.fromPos.x - 42, y = firstPit.fromPos.y, z = firstPit.fromPos.z}, + toPos = {x = firstPit.toPos.x - 42, y = firstPit.toPos.y, z = firstPit.toPos.z}, + center = {x = firstPit.center.x - 42, y = firstPit.center.y, z = firstPit.center.z}, + pillar = {x = firstPit.pillar.x - 42, y = firstPit.pillar.y, z = firstPit.pillar.z}, + tp = {x = firstPit.tp.x - 42, y = firstPit.tp.y, z = firstPit.tp.z}, + summon = {x = firstPit.summon.x - 42, y = firstPit.summon.y, z = firstPit.summon.z} + }, + [5] = { + fromPos = {x = firstPit.fromPos.x - 35, y = firstPit.fromPos.y - 14, z = firstPit.fromPos.z}, + toPos = {x = firstPit.toPos.x - 35, y = firstPit.toPos.y - 14, z = firstPit.toPos.z}, + center = {x = firstPit.center.x - 35, y = firstPit.center.y - 14, z = firstPit.center.z}, + pillar = {x = firstPit.pillar.x - 35, y = firstPit.pillar.y - 14, z = firstPit.pillar.z}, + tp = {x = firstPit.tp.x - 35, y = firstPit.tp.y - 14, z = firstPit.tp.z}, + summon = {x = firstPit.summon.x - 35, y = firstPit.summon.y - 14, z = firstPit.summon.z} + }, + [6] = { + fromPos = {x = firstPit.fromPos.x - 21, y = firstPit.fromPos.y - 14, z = firstPit.fromPos.z}, + toPos = {x = firstPit.toPos.x - 21, y = firstPit.toPos.y - 14, z = firstPit.toPos.z}, + center = {x = firstPit.center.x - 21, y = firstPit.center.y - 14, z = firstPit.center.z}, + pillar = {x = firstPit.pillar.x - 21, y = firstPit.pillar.y - 14, z = firstPit.pillar.z}, + tp = {x = firstPit.tp.x - 21, y = firstPit.tp.y - 14, z = firstPit.tp.z}, + summon = {x = firstPit.summon.x - 21, y = firstPit.summon.y - 14, z = firstPit.summon.z} + }, + [7] = { + fromPos = {x = firstPit.fromPos.x - 7, y = firstPit.fromPos.y - 14, z = firstPit.fromPos.z}, + toPos = {x = firstPit.toPos.x - 7, y = firstPit.toPos.y - 14, z = firstPit.toPos.z}, + center = {x = firstPit.center.x - 7, y = firstPit.center.y - 14, z = firstPit.center.z}, + pillar = {x = firstPit.pillar.x - 7, y = firstPit.pillar.y - 14, z = firstPit.pillar.z}, + tp = {x = firstPit.tp.x - 7, y = firstPit.tp.y - 14, z = firstPit.tp.z}, + summon = {x = firstPit.summon.x - 7, y = firstPit.summon.y - 14, z = firstPit.summon.z} + }, + [8] = { + fromPos = {x = firstPit.fromPos.x - 14, y = firstPit.fromPos.y - 28, z = firstPit.fromPos.z}, + toPos = {x = firstPit.toPos.x - 14, y = firstPit.toPos.y - 28, z = firstPit.toPos.z}, + center = {x = firstPit.center.x - 14, y = firstPit.center.y - 28, z = firstPit.center.z}, + pillar = {x = firstPit.pillar.x - 14, y = firstPit.pillar.y - 28, z = firstPit.pillar.z}, + tp = {x = firstPit.tp.x - 14, y = firstPit.tp.y - 28, z = firstPit.tp.z}, + summon = {x = firstPit.summon.x - 14, y = firstPit.summon.y - 28, z = firstPit.summon.z} + }, + [9] = { + fromPos = {x = firstPit.fromPos.x - 28, y = firstPit.fromPos.y - 28, z = firstPit.fromPos.z}, + toPos = {x = firstPit.toPos.x - 28, y = firstPit.toPos.y - 28, z = firstPit.toPos.z}, + center = {x = firstPit.center.x - 28, y = firstPit.center.y - 28, z = firstPit.center.z}, + pillar = {x = firstPit.pillar.x - 28, y = firstPit.pillar.y - 28, z = firstPit.pillar.z}, + tp = {x = firstPit.tp.x - 28, y = firstPit.tp.y - 28, z = firstPit.tp.z}, + summon = {x = firstPit.summon.x - 28, y = firstPit.summon.y - 28, z = firstPit.summon.z} + }, + [10] = { + fromPos = {x = firstPit.fromPos.x - 21, y = firstPit.fromPos.y - 42, z = firstPit.fromPos.z}, + toPos = {x = firstPit.toPos.x - 21, y = firstPit.toPos.y - 42, z = firstPit.toPos.z}, + center = {x = firstPit.center.x - 21, y = firstPit.center.y - 41, z = firstPit.center.z}, + pillar = {x = firstPit.pillar.x - 21, y = firstPit.pillar.y - 41, z = firstPit.pillar.z}, + tp = {x = firstPit.tp.x - 21, y = firstPit.tp.y - 41, z = firstPit.tp.z}, + summon = {x = firstPit.summon.x - 21, y = firstPit.summon.y - 41, z = firstPit.summon.z} + } +} + +ARENA = { + [1] = { + name = 'Greenhorn', + price = 1000, + questLog = Storage.SvargrondArena.QuestLogGreenhorn, + achievement = 'Greenhorn', + creatures = { + [1] = 'frostfur', + [2] = 'bloodpaw', + [3] = 'bovinus', + [4] = 'achad', + [5] = 'colerian the barbarian', + [6] = 'the hairy one', + [7] = 'axeitus headbanger', + [8] = 'rocky', + [9] = 'cursed gladiator', + [10] = 'orcus the cruel' + } + }, + [2] = { + name = 'Scrapper', + price = 5000, + questLog = Storage.SvargrondArena.QuestLogScrapper, + achievement = 'Scrapper', + creatures = { + [1] = 'avalanche', + [2] = 'kreebosh the exile', + [3] = 'the dark dancer', + [4] = 'the hag', + [5] = 'slim', + [6] = 'grimgor guteater', + [7] = 'drasilla', + [8] = 'spirit of earth', + [9] = 'spirit of water', + [10] = 'spirit of fire' + } + }, + [3] = { + name = 'Warlord', + price = 10000, + questLog = Storage.SvargrondArena.QuestLogWarlord, + achievement = 'Warlord of Svargrond', + creatures = { + [1] = 'webster', + [2] = 'darakan the executioner', + [3] = 'norgle glacierbeard', + [4] = 'the pit lord', + [5] = 'svoren the mad', + [6] = 'the masked marauder', + [7] = 'gnorre chyllson', + [8] = 'fallen mooh\'tah master ghar', + [9] = 'deathbringer', + [10] = 'the obliverator' + } + } +} + +ARENA_TROPHY = { + [3264] = { + trophy = 5807, + trophyStorage = Storage.SvargrondArena.TrophyGreenhorn, + desc = 'It is given to the courageous victor of the barbarian arena in greenhorn difficulty. Awarded to %s', + }, + [3265] = { + trophy = 5806, + trophyStorage = Storage.SvargrondArena.TrophyScrapper, + desc = 'It is given to the courageous victor of the barbarian arena in scrapper difficulty. Awarded to %s.', + }, + [3266] = { + trophy = 5805, + trophyStorage = Storage.SvargrondArena.TrophyWarlord, + desc = 'It is given to the courageous victor of the barbarian arena in warlord difficulty. Awarded to %s.', + } +} + +function SvargrondArena.getPitCreatures(pitId) + if not PITS[pitId] then + return {} + end + + local ret = {} + local specs = Game.getSpectators(PITS[pitId].center, false, false, 5, 5, 5, 5) + for i = 1, #specs do + ret[#ret+1] = specs[i] + end + + return ret +end + +function SvargrondArena.resetPit(pitId) + if not PITS[pitId] then + return + end + + for x = PITS[pitId].fromPos.x, PITS[pitId].toPos.x do + for y = PITS[pitId].fromPos.y, PITS[pitId].toPos.y do + for z = PITS[pitId].fromPos.z, PITS[pitId].toPos.z do + local tile = Tile({x=x, y=y, z=z}) + if tile then + local movableItem = tile:getThing(255) + if movableItem and movableItem:isItem() then + local itemType = ItemType(movableItem:getId()) + if itemType and itemType:isMovable() and not isInArray(SvargrondArena.itemsNotErasable, movableItem:getId()) then + moveableItem:remove() + end + end + + local creature = tile:getTopCreature() + if creature and creature:isMonster() then + creature:remove() + end + end + end + end + end + + local pillarTile = Tile(PITS[pitId].pillar) + if pillarTile then + local teleportItem = pillarTile:getItemById(SvargrondArena.itemTeleport) + if teleportItem then + teleportItem:remove() + end + + local pillarItem = pillarTile:getItemById(SvargrondArena.itemPillar) + if not pillarItem then + Game.createItem(SvargrondArena.itemPillar, 1, PITS[pitId].pillar) + end + end +end + +function SvargrondArena.getPitOccupant(pitId, ignorePlayer) + local creatures = SvargrondArena.getPitCreatures(pitId) + for i = 1, #creatures do + if creatures[i]:isPlayer() and creatures[i]:getId() ~= ignorePlayer:getId() then + return creatures[i] + end + end + + return nil +end + +function SvargrondArena.kickPlayer(cid, hideMessage) + SvargrondArena.cancelEvents(cid) + local player = Player(cid) + if not player then + return + end + + if player:getStorageValue(Storage.SvargrondArena.PitDoor) > 0 then + player:teleportTo(SvargrondArena.kickPosition) + SvargrondArena.kickPosition:sendMagicEffect(CONST_ME_TELEPORT) + player:setStorageValue(Storage.SvargrondArena.PitDoor, 0) + if not hideMessage then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Your time ran out!') + end + end +end + +function SvargrondArena.cancelEvents(cid) + local kickEvent = SvargrondArena.kickEvents[cid] + if kickEvent then + SvargrondArena.removeTimer(kickEvent.pitId) + stopEvent(kickEvent.eventId) + end + SvargrondArena.kickEvents[cid] = nil +end + +function SvargrondArena.scheduleKickPlayer(cid, pitId) + SvargrondArena.cancelEvents(cid) + SvargrondArena.startTimer(pitId) + local eventId = addEvent(SvargrondArena.kickPlayer, SvargrondArena.kickTime * 1000, cid) + SvargrondArena.kickEvents[cid] = {eventId = eventId, pitId = pitId} +end + +function SvargrondArena.startTimer(pitId) + local tile = Tile(PITS[pitId].fromPos) + if not tile then + return + end + + local timerItem = tile:getItemById(SvargrondArena.itemTimer) + if timerItem then + timerItem:remove() + end + + timerItem = Game.createItem(SvargrondArena.itemTimer, 1, PITS[pitId].fromPos) + if timerItem then + timerItem:decay() + end + + if SvargrondArena.timerEvents[pitId] then + stopEvent(SvargrondArena.timerEvents[pitId]) + end + SvargrondArena.timerEvents[pitId] = addEvent(SvargrondArena.removeTimer, SvargrondArena.kickTime * 1000, pitId) +end + +function SvargrondArena.removeTimer(pitId) + local tile = Tile(PITS[pitId].fromPos) + if not tile then + return + end + + local timerItem = tile:getItemById(SvargrondArena.itemTimer) + if timerItem then + timerItem:remove() + end + SvargrondArena.timerEvents[pitId] = nil +end + +function SvargrondArena.sendPillarEffect(pitId) + local positions = SvargrondArena.effectPositionCache[pitId] + if not positions then + local position = PITS[pitId].pillar + local effectPositions = { + Position(position.x - 1, position.y, position.z), + Position(position.x + 1, position.y, position.z), + Position(position.x + 1, position.y - 1, position.z), + Position(position.x + 1, position.y + 1, position.z), + Position(position.x, position.y, position.z) + } + SvargrondArena.effectPositionCache[pitId] = effectPositions + positions = effectPositions + end + + for i = 1, #positions do + positions[i]:sendMagicEffect(CONST_ME_MAGIC_BLUE) + end +end diff --git a/data/lib/quests/the_cursed_crystal.lua b/data/lib/quests/the_cursed_crystal.lua new file mode 100644 index 00000000000..445662d0eda --- /dev/null +++ b/data/lib/quests/the_cursed_crystal.lua @@ -0,0 +1,17 @@ +--[The Cursed Crystal]-- +-- Teleports +TCC_VORTEX_POSITION = Position(31961, 32938, 9) -- Position to create the water vortex to use as teleport. +TCC_MEDUSACRYSTAL_ENTRY_MAP = Position(32009, 32928, 9) -- Giant red crystal with medusa blood entrance. (Teloprt item position!) +TCC_MEDUSACRYSTAL_ENTRY = Position(32009, 32929, 10) -- Giant red crystal with medusa blood entrance. +TCC_MEDUSACRYSTAL_EXIT_MAP = Position(32009, 32928, 10) -- Giant red crystal with medusa blood exit. (Teloprt item position!) +TCC_MEDUSACRYSTAL_EXIT = Position(32009, 32929, 9) -- Giant red crystal with medusa blood exit. +TCC_VORTEX_TELEPORTED = Position(31961, 32938, 10) -- Position that the water vortex will teleport the player. +TCC_AFTERVORTEX_EXIT_ONE_MAP = Position(31973, 32905, 11) -- First teleport exit that the player will get teleported after water vortex. (Teloprt item position!) +TCC_AFTERVORTEX_EXIT_ONE = Position(31970, 32904, 10) -- First teleport exit that the player will get teleported after water vortex. +TCC_AFTERVORTEX_EXIT_TWO_MAP = Position(31973, 32905, 10) -- Second teleport exit that the player will get teleported after water vortex. (Teloprt item position!) +TCC_AFTERVORTEX_EXIT_TWO = Position(31975, 32911, 9) -- Second teleport exit that the player will get teleported after water vortex. +TCC_PILLARPETRIFIED = Position(31942, 32936, 10) -- Pillar position. +TCC_SKELETON_PAPER_POS = Position(31974, 32907, 8) +TCC_SKELETON_BELL_POS = Position(32031, 32914, 8) +TCC_MEDUSAMSG_ONEMAP = Position(32017, 32917, 10) -- Second teleport exit that the player will get teleported after water vortex. +TCC_MEDUSAMSG_TWOMAP = Position(32017, 32918, 10) -- Second teleport exit that the player will get teleported after water vortex. diff --git a/data/lib/quests/the_queen_of_the_banshees.lua b/data/lib/quests/the_queen_of_the_banshees.lua new file mode 100644 index 00000000000..bb527aaf067 --- /dev/null +++ b/data/lib/quests/the_queen_of_the_banshees.lua @@ -0,0 +1,126 @@ +-- Table of the first seal +firstSealTable = { + [30010] = { + position = {x = 32259, y = 31891, z = 10}, + revert = true + }, + [30011] = { + position = {x = 32259, y = 31890, z = 10}, + revert = true + }, + [30012] = { + position = {x = 32266, y = 31860, z = 11}, + revert = true + } +} + +-- Table of the second seal +secondSealTable = { + positions = { + {position = {x = 32173, y = 31871, z = 15}, pearlId = 2143}, + {position = {x = 32180, y = 31871, z = 15}, pearlId = 2144} + } +} + +-- Table of the third seal +thirdSealTable = { + [1] = 30013, + [2] = 30014, + [3] = 30015, + [4] = 30016, + [5] = 30017, + + effectPosition = { + --[[ + [uniqueid] = { + {positions} + } + ]] + [1] = { + {x= 32217, y= 31845, z= 14}, + {x= 32218, y= 31845, z= 14}, + {x= 32219, y= 31845, z= 14}, + {x= 32220, y= 31845, z= 14}, + {x= 32217, y= 31843, z= 14}, + {x= 32218, y= 31842, z= 14}, + {x= 32219, y= 31841, z= 14} + }, + [2] = { + {x= 32217, y= 31844, z= 14}, + {x= 32218, y= 31844, z= 14}, + {x= 32219, y= 31843, z= 14}, + {x= 32220, y= 31845, z= 14}, + {x= 32219, y= 31845, z= 14} + }, + [3] = { + {x= 32217, y= 31842, z= 14}, + {x= 32219, y= 31843, z= 14}, + {x= 32219, y= 31845, z= 14}, + {x= 32218, y= 31844, z= 14}, + {x= 32217, y= 31844, z= 14}, + {x= 32217, y= 31845, z= 14} + }, + [4] = { + {x= 32217, y= 31845, z= 14}, + {x= 32218, y= 31846, z= 14}, + {x= 32218, y= 31844, z= 14}, + {x= 32219, y= 31845, z= 14}, + {x= 32220, y= 31846, z= 14} + }, + [5] = { + {x= 32219, y= 31841, z= 14}, + {x= 32219, y= 31842, z= 14}, + {x= 32219, y= 31846, z= 14}, + {x= 32217, y= 31843, z= 14}, + {x= 32217, y= 31844, z= 14}, + {x= 32217, y= 31845, z= 14}, + {x= 32218, y= 31843, z= 14}, + {x= 32218, y= 31845, z= 14} + } + }, + + coalBasinPosition = { + {x = 32214, y = 31850, z = 15}, + {x = 32215, y = 31850, z = 15}, + {x = 32216, y = 31850, z = 15} + }, + + switchPosition = { + {x = 32220, y = 31842, z = 15}, + {x = 32220, y = 31843, z = 15}, + {x = 32220, y = 31844, z = 15}, + {x = 32220, y = 31845, z = 15}, + {x = 32220, y = 31846, z = 15} + } +} + +-- Table of the fourth seal +fourthSealTable = { + positions = { + {x = 32242, y = 31891, z = 14}, + {x = 32243, y = 31891, z = 14}, + {x = 32242, y = 31893, z = 14}, + {x = 32243, y = 31893, z = 14} + } +} + +-- Table of the sixth seal +sixthSealTable = { + uniqueTable = { + [30018] = {x = 32309, y = 31975, z = 13}, + [30019] = {x = 32309, y = 31976, z = 13}, + [30020] = {x = 32311, y = 31975, z = 13}, + [30021] = {x = 32311, y = 31976, z = 13}, + [30022] = {x = 32313, y = 31975, z = 13}, + [30023] = {x = 32313, y = 31976, z = 13}, + }, + + positions = { + {position = {x = 32309, y = 31975, z = 13}, campfireId = 1421}, + {position = {x = 32311, y = 31975, z = 13}, campfireId = 1421}, + {position = {x = 32313, y = 31975, z = 13}, campfireId = 1423}, + {position = {x = 32309, y = 31976, z = 13}, campfireId = 1421}, + {position = {x = 32311, y = 31976, z = 13}, campfireId = 1421}, + {position = {x = 32313, y = 31976, z = 13}, campfireId = 1423} + } +} diff --git a/data/lib/quests/their_masters_voice.lua b/data/lib/quests/their_masters_voice.lua new file mode 100644 index 00000000000..a16b78f0afd --- /dev/null +++ b/data/lib/quests/their_masters_voice.lua @@ -0,0 +1,170 @@ +local config = { + quest_duration = 60, -- how long until quest is reverted, in minutes + slime_exhaust = 5, -- exhaust until you can remove another slime, in seconds + slimes_needed = 25, -- slimes needed to be removed to kill mad mage and complete quest + max_slimes = 100, -- max slimes needed to start waves + max_waves = 25 -- max waves, last one will be mad mage +} + +local mage_positions = { + {x = 33328, y = 31859, z = 9}, + {x = 33367, y = 31873, z = 9}, + {x = 33349, y = 31899, z = 9} +} + +local servant_positions = { + {x = 33313, y = 31852, z = 9}, + {x = 33313, y = 31881, z = 9}, + {x = 33328, y = 31860, z = 9}, + {x = 33328, y = 31873, z = 9}, + {x = 33328, y = 31885, z = 9}, + {x = 33308, y = 31873, z = 9}, + {x = 33320, y = 31873, z = 9}, + {x = 33335, y = 31873, z = 9}, + {x = 33360, y = 31873, z = 9}, + {x = 33336, y = 31914, z = 9}, + {x = 33343, y = 31914, z = 9}, + {x = 33353, y = 31914, z = 9}, + {x = 33361, y = 31914, z = 9}, + {x = 33345, y = 31900, z = 9}, + {x = 33352, y = 31900, z = 9}, + {x = 33355, y = 31854, z = 9}, + {x = 33355, y = 31885, z = 9}, + {x = 33345, y = 31864, z = 9}, + {x = 33345, y = 31881, z = 9}, + {x = 33309, y = 31867, z = 9}, + {x = 33317, y = 31879, z = 9}, + {x = 33311, y = 31854, z = 9}, + {x = 33334, y = 31889, z = 9}, + {x = 33340, y = 31890, z = 9}, + {x = 33347, y = 31889, z = 9} +} + +local slime_ids = {13585, 13586, 13587, 13588, 13589} + +local servants = { + {10, "diamond servant"}, + {40, "golden servant"}, + {100, "iron servant"} +} + +slime_exhaust = slime_exhaust or {} +slimes_removed = slimes_removed or {} +current_servants = current_servants or {} +current_mage = current_mage or 0 +current_wave = current_wave or 0 +valid_participants = valid_participants or {} + +function startServantWave() + current_wave = current_wave + 1 + if current_wave == config.max_waves then + local mage = Game.createMonster("Mad Mage", mage_positions[math.random(#mage_positions)], true, true) + if mage then + mage:registerEvent("Mage_Death") + end + return + end + + current_servants = {} + for pos_key = 1, #servant_positions do + local random = math.random(100) + for servant_key = 1, #servants do + if random <= servants[servant_key][1] then + local servant = Game.createMonster(servants[servant_key][2], servant_positions[pos_key], true, true) + if servant then + current_servants[#current_servants + 1] = servant.uid + servant:registerEvent("Servant_Death") + break + end + end + end + end +end + +function revertQuest() + for i = 1, #current_servants do + local servant = Creature(current_servants[i]) + if servant then + servant:remove() + end + end + current_servants = {} + + local mage = Creature(current_mage) + if mage then + mage:remove() + end + current_mage = 0 + + for i = 1, #slimes_removed do + local ground = Tile(slimes_removed[i].pos):getGround() + if ground then + ground:transform(slimes_removed[i].id) + end + end + slimes_removed = {} + current_wave = 0 +end + +function Gobbler_onUse(player, item, fromPosition, target, toPosition, isHotkey) + if not target or not isInArray(slime_ids, target.itemid) then + return false + end + + local time = os.time() + if slime_exhaust[player.uid] and slime_exhaust[player.uid] >= os.time() then + player:sendCancelMessage(RETURNVALUE_YOUAREEXHAUSTED) + fromPosition:sendMagicEffect(CONST_ME_POFF) + return true + end + + slime_exhaust[player.uid] = time + config.slime_exhaust + player:say("The slime gobbler gobbles large chunks of the slime fungus with great satisfaction.", TALKTYPE_MONSTER_SAY) + player:addExperience(20, true, true) + slimes_removed[#slimes_removed + 1] = {cid = player.uid, id = target.itemid, pos = toPosition} + target:transform(13590) + + if not isInArray(valid_participants, player.uid) then + local slime_count = 0 + for i = 1, #slimes_removed do + if slimes_removed[i].cid == player.uid then + slime_count = slime_count + 1 + if slime_count == 25 then + player:say("You gobbled enough slime to get a good grip on this dungeon's slippery floor.", TALKTYPE_MONSTER_SAY) + valid_participants[#valid_participants + 1] = player.uid + break + end + end + end + end + + if #slimes_removed == 1 then + addEvent(revertQuest, config.quest_duration * 60 * 1000) + elseif #slimes_removed >= config.max_slimes then + player:say("COME! My servants! RISE!", TALKTYPE_MONSTER_SAY) + startServantWave() + end + return true +end + +function Servant_onDeath(creature, corpse, killer, mostDamageKiller, lastHitUnjustified) + for i = 1, #current_servants do + if current_servants[i] == creature.uid then + table.remove(current_servants, i) + break + end + end + + if #current_servants < 1 then + startServantWave() + end + return true +end + +function Mage_onDeath(creature, corpse, killer, mostDamageKiller, lastHitUnjustified) + if killer and isInArray(valid_participants, killer.uid) then + -- add achievements if needed + end + revertQuest() + return true +end diff --git a/data/lib/tables/achievements_lib.lua b/data/lib/tables/achievements_lib.lua new file mode 100644 index 00000000000..375d8cc402b --- /dev/null +++ b/data/lib/tables/achievements_lib.lua @@ -0,0 +1,778 @@ +--[[ + +Achievements Lib Created By Eduardo Montilva (Darkhaos) for TFS 1.X + +LAST UPDATE: 23 July 2019 (PRE-Tibia Update 12.20) + +Functions: + getAchievementInfoById(achievement_id) + getAchievementInfoByName(achievement_name) + getSecretAchievements() + getPublicAchievements() + getAchievements() + Player:addAchievement(achievement_id/name[, showMsg]) + Player:removeAchievement(achievement_id/name) + Player:hasAchievement(achievement_id/name) + Player:addAllAchievements([showMsg]) + Player:removeAllAchievements() + Player:getSecretAchievements() + Player:getPublicAchievements() + Player:getAchievements() + isAchievementSecret(achievement_id/name) + Player:getAchievementPoints() + +Note: This lib was created following the data found in tibia.wikia.com. + Achievements with no points (or points equal to 0) are achievements with no available info about points in tibia.wikia.com. These achievements should be updated +--]] + +-- Updated by F@bio Jr +-- Reordered by Tibia Version and alphabetically +-- LAST UPDATE: 01 December 2019 (PRE-Tibia Update 12.30) + +ACHIEVEMENTS_BASE = 300000 -- base storage +ACHIEVEMENTS_ACTION_BASE = 20000 --this storage will be used to save the process to obtain the certain achievement + --(Ex: this storage + the id of achievement 'Allowance Collector' to save... + -- ...how many piggy banks has been broken + +achievements = +{ + --8.6 + [1] = {name = "Allow Cookies?", grade = 1, points = 2, description = "With a perfectly harmless smile you fooled all of those wisecrackers into eating your exploding cookies. Consider a boy or girl scout outfit next time to make the trick even better."}, + [2] = {name = "Allowance Collector", grade = 1, points = 2, secret = true, description = "You certainly have your ways when it comes to acquiring money. Many of them are pink and paved with broken fragments of porcelain."}, + [3] = {name = "Amateur Actor", grade = 1, points = 2, description = "You helped bringing Princess Buttercup, Doctor Dumbness and Lucky the Wonder Dog to life - and will probably dream of them tonight, since you memorised your lines perfectly. What a .. special piece of.. screenplay."}, + [4] = {name = "Animal Activist", grade = 1, points = 2, description = "You have a soft spot for little, weak animals, and you do everything in your power to protect them - even if you probably eat dragons for breakfast."}, + [5] = {name = "Annihilator", grade = 2, points = 5, description = "You've daringly jumped into the infamous Annihilator and survived - taking home fame, glory and your reward."}, + [6] = {name = "Archpostman", grade = 1, points = 3, description = "Delivering letters and parcels has always been a secret passion of yours, and now you can officially put on your blue hat, blow your Post Horn and do what you like to do most. Beware of dogs!"}, + [7] = {name = "Backpack Tourist", grade = 1, points = 1, secret = true, description = "If someone lost a random thing in a random place, you're probably a good person to ask and go find it, even if you don't know what and where."}, + [8] = {name = "Beach Tamer", grade = 1, points = 2, description = "You re-enacted the Taming of the Shrew on a beach setting and proved that you can handle capricious girls quite well. With or without fish tails."}, + [9] = {name = "Bearhugger", grade = 1, points = 1, description = "Warm, furry and cuddly - though that same bear you just hugged would probably rip you into pieces if he had been conscious, he reminded you of that old teddy bear which always slept in your bed when you were still small."}, + [10] = {name = "Blessed!", grade = 1, points = 2, description = "You travelled the world for an almost meaningless prayer - but at least you don't have to do that again and can get a new blessed stake in the blink of an eye."}, + [11] = {name = "Bone Brother", grade = 1, points = 1, description = "You've joined the undead bone brothers - making death your enemy and your weapon as well. Devouring what's weak and leaving space for what's strong is your primary goal."}, + [12] = {name = "Castlemania", grade = 2, points = 5, secret = true, description = "You have an eye for suspicious places and love to read other people's diaries, especially those with vampire stories in it. You're also a dedicated token collector and explorer. Respect!"}, + [13] = {name = "Champion of Chazorai", grade = 2, points = 4, description = "You won the merciless 2 vs. 2 team tournament on the Isle of Strife and wiped out wave after wave of fearsome opponents. Death or victory - you certainly chose the latter."}, + [14] = {name = "Chorister", grade = 1, points = 1, description = "Lalalala... you now know the cult's hymn sung in Liberty Bay"}, + [15] = {name = "Clay Fighter", grade = 1, points = 3, secret = true, description = "You love getting your hands wet and dirty - and covered with clay. Your perfect sculpture of Brog, the raging Titan is your true masterpiece."}, + [16] = {name = "Clay to Fame", grade = 2, points = 6, secret = true, description = "Sculpting Brog, the raging Titan, is your secret passion. Numerous perfect little clay statues with your name on them can be found everywhere around Tibia."}, + [17] = {name = "Cold as Ice", grade = 2, points = 6, secret = true, description = "Take an ice cube and an obsidian knife and you'll very likely shape something really pretty from it. Mostly cute little mammoths, which are a hit with all the girls."}, + [18] = {name = "Culinary Master", grade = 2, points = 4, description = "Simple hams and bread merely make you laugh. You're the master of the extra-ordinaire, melter of cheese, fryer of bat wings and shaker of shakes. Delicious!"}, + [19] = {name = "Deep Sea Diver", grade = 2, points = 4, secret = true, description = "Under the sea - might not be your natural living space, but you're feeling quite comfortable on the ocean floor. Quara don't scare you anymore and sometimes you sleep with your helmet of the deep still equipped."}, + [20] = {name = "Dread Lord", grade = 3, points = 8, secret = true, description = "You don't care for rules that others set up and shape the world to your liking. Having left behind meaningless conventions and morals, you prize only the power you wield. You're a master of your fate and battle to cleanse the world."}, + [21] = {name = "Efreet Ally", grade = 1, points = 3, description = "Even though the welcomed you only reluctantly and viewed you as \"only a human\" for quite some time, you managed to impress Malor and gained his respect and trade options with the green djinns."}, + [22] = {name = "Elite Hunter", grade = 2, points = 5, description = "You jump at every opportunity for a hunting challenge that's offered to you and carry out those tasks with deadly precision. You're a hunter at heart and a valuable member of the Paw & Fur Society."}, + [23] = {name = "Explorer", grade = 2, points = 4, description = "You've been to places most people don't even know the names of. Collecting botanic, zoologic and ectoplasmic samples is your daily business and you're always prepared to discover new horizons."}, + [24] = {name = "Exquisite Taste", grade = 1, points = 2, secret = true, description = "You love fish - but preferably those caught in the cold north. Even though they're hard to come by you never get tired of picking holes in ice sheets and hanging your fishing rod in."}, + [25] = {name = "Firewalker", grade = 2, points = 4, secret = true, description = "Running barefoot across ember is not for you! You do it the elegant way. Yet, you're kind of drawn to fire and warm surroundings in general - you like it hot!"}, + [26] = {name = "Fireworks in the Sky", grade = 1, points = 2, secret = true, description = "You love the moment right before your rocket takes off and explodes into beautiful colours - not only on new year's eve!"}, + [27] = {name = "Follower of Azerus", grade = 2, points = 4, description = "When you do something, you do it right. You have an opinion and you stand by it - and no one will be able to convince you otherwise. On a sidenote, you're a bit on the brutal and war-oriented side, but that's not a bad thing, is it?"}, + [28] = {name = "Follower of Palimuth", grade = 2, points = 4, description = "You're a peacekeeper and listen to what the small people have to say. You've made up your mind and know who to help and for which reasons - and you do it consistently. Your war is fought with reason rather than weapons."}, + [29] = {name = "Fountain of Life", grade = 1, points = 1, secret = true, description = "You found and took a sip from the Fountain of Life. Thought it didn't grant you eternal life, you feel changed and somehow at peace."}, + [30] = {name = "Friend of the Apes", grade = 2, points = 4, description = "You know Banuta like the back of your hand and are good at destroying caskets and urns. The sight of giant footprints doesn't keep you from exploring unknown areas either."}, + [31] = {name = "Ghostwhisperer", grade = 1, points = 3, description = "You don't hunt them, you talk to them. You know that ghosts might keep secrets that have been long lost among the living, and you're skilled at talking them into revealing them to you."}, + [32] = {name = "Golem in the Gears", grade = 2, points = 4, description = "You're an aspiring mago-mechanic. Science and magic work well together in your eyes - and even though you probably delivered countless wrong charges while working for Telas, you might just have enough knowledge to build your own golem now."}, + [33] = {name = "Green Thumb", grade = 2, points = 4, secret = true, description = "If someone gives you seeds, you usually grow a beautiful plant from it within a few days. You like your house green and decorated with flowers. Probably you also talk to them."}, + [34] = {name = "Greenhorn", grade = 1, points = 2, description = "You wiped out Orcus the Cruel in the Arena of Svargrond. You're still a bit green behind the ears, but there's some great potential."}, + [35] = {name = "Herbicide", grade = 3, points = 8, secret = true, description = "You're one of the brave heroes to face and defeat the mysterious demon oak and all the critters it threw in your face. Wielding your blessed axe no tree dares stand in your way - demonic or not."}, + [36] = {name = "Here, Fishy Fishy!", grade = 1, points = 1, secret = true, description = "Ah, the smell of the sea! Standing at the shore and casting a line is one of your favourite activities. For you, fishingis relaxing - and at the same time, providing easy food. Perfect!"}, + [37] = {name = "High-Flyer", grade = 2, points = 4, secret = true, description = "The breeze in your hair, your fingers clutching the rim of your Carpet - that's how you like to travel. Faster! Higher! And a looping every now and then."}, + [38] = {name = "High Inquisitor", grade = 2, points = 5, description = "You're the one who poses the questions around here, and you know how to get the answers you want to hear. Besides, you're a famous exorcist and slay a few vampires and demons here and there. You and your stake are a perfect team."}, + [39] = {name = "His True Face", grade = 1, points = 3, secret = true, description = "You're one of the few Tibians who Armenius chose to actually show his true face to - and he made you fight him. Either that means you're very lucky or very unlucky, but one thing's for sure - it's extremely rare."}, + [40] = {name = "Honorary Barbarian", grade = 1, points = 1, description = "You've hugged bears, pushed mammoths and proved your drinking skills. And even though you have a slight hangover, a partially fractured rib and some greasy hair on your tongue, you're quite proud to call yourself a honorary barbarian from now on."}, + [41] = {name = "Huntsman", grade = 1, points = 2, description = "You're familiar with hunting tasks and have carried out quite a few already. A bright career as hunter for the Paw & Fur society lies ahead!"}, + [42] = {name = "Ice Sculptor", grade = 1, points = 3, secret = true, description = "You love to hang out in cold surroundings and consider ice the best material to be shaped. What a waste to use ice cubes for drinks when you can create a beautiful mammoth statue from it!"}, + [43] = {name = "Interior Decorator", grade = 2, points = 4, secret = true, description = "Your home is your castle - and the furniture in it is just as important. Your friends ask for your advice when decorating their Houses and your probably own every statue, rack and bed there is."}, + [44] = {name = "Jamjam", grade = 2, points = 5, secret = true, description = "When it comes to interracial understanding, you're an expert. You've mastered the language of the Chakoya and made someone really happy with your generosity. Achuq!"}, + [45] = {name = "Jinx", grade = 1, points = 2, secret = true, description = "Sometimes you feel there's a gremlin in there. So many lottery tickets, so many blanks? That's just not fair! Share your misery with the world."}, + [46] = {name = "Just in Time", grade = 1, points = 1, description = "You're a fast runner and are good at delivering wares which are bound to decay just in the nick of time, even if you can't use any means of transportation or if your hands get cold or smelly in the process."}, + [47] = {name = "King Tibianus Fan", grade = 1, points = 3, description = "You're not sure what it is, but you feel drawn to royalty. Your knees are always a bit grazed from crawling around in front of thrones and you love hanging out in castles. Maybe you should consider applying as a guard?"}, + [48] = {name = "Lord Protector", grade = 3, points = 8, secret = true, description = "You proved yourself - not only in your dreams - and possess a strong and spiritual mind. Your valorous fight against demons and the undead plague has granted you the highest and most respected rank among the Nightmare Knights."}, + [49] = {name = "Lord of the Elements", grade = 2, points = 5, description = "You travelled the surreal realm of the elemental spheres, summoned and slayed the Lord of the Elements, all in order to retrieve neutral matter. And as brave as you were, you couldn't have done it without your team!"}, + [50] = {name = "Lucid Dreamer", grade = 1, points = 2, description = "Dreams - are your reality? Strange visions, ticking clocks, going to bed and waking up somewhere completely else - that was some trip, but you're almost sure you actually did enjoy it."}, + [51] = {name = "Lucky Devil", grade = 2, points = 4, secret = true, description = "That's almost too much luck for one person. If something's really, really rare - it probably falls into your lap sooner or later. Congratulations!"}, + [52] = {name = "Marble Madness", grade = 2, points = 6, secret = true, description = "Your little statues of Tibiasula have become quite famous around Tibia and there's few people with similar skills when it comes to shaping marble."}, + [53] = {name = "Marblelous", grade = 1, points = 3, secret = true, description = "You're an aspiring marble sculptor with promising skills - proven by the perfect little Tibiasula statue you shaped. One day you'll be really famous!"}, + [54] = {name = "Marid Ally", grade = 1, points = 3, description = "You've proven to be a valuable ally to the Marid, and Gabel welcomed you to trade with Haroun and Nah'Bob whenever you want to. Though the Djinn war has still not ended, the Marid can't fail with you on their side."}, + [55] = {name = "Masquerader", grade = 1, points = 3, secret = true, description = "You probably don't know anymore how you really look like - usually when you look into a mirror, some kind of monster stares back at you. On the other hand - maybe that's an improvement?"}, + [56] = {name = "Master Thief", grade = 2, points = 4, description = "Robbing, inviting yourself to VIP parties, faking contracts and pretending to be someone else - you're a jack of all trades when it comes to illegal activities. You take no prisoners, except for the occasional goldfish now and then."}, + [57] = {name = "Master of the Nexus", grade = 2, points = 6, description = "You were able to fight your way through the countless hordes in the Demon Forge. Once more you proved that nothing is impossible."}, + [58] = {name = "Matchmaker", grade = 1, points = 1, description = "You don't believe in romance to be a coincidence or in love at first sight. In fact - love potions, bouquets of flowers and cheesy poems do the trick much better than ever could. Keep those hormones flowing!"}, + [59] = {name = "Mathemagician", grade = 1, points = 1, description = "Sometimes the biggest secrets of life can have a simple solution."}, + [60] = {name = "Ministrel", grade = 1, points = 2, secret = true, description = "You can handle any music instrument you're given - and actually manage to produce a pleasant sound with it. You're a welcome guest and entertainer in most taverns."}, + [61] = {name = "Nightmare Knight", grade = 1, points = 1, description = "You follow the path of dreams and that of responsibility without self-centered power. Free from greed and selfishness, you help others without expecting a reward."}, + [62] = {name = "Party Animal", grade = 1, points = 1, secret = true, description = "Oh my god, it's a paaaaaaaaaaaarty! You're always in for fun, friends and booze and love being the center of attention. There's endless reasons to celebrate! Woohoo!"}, + [63] = {name = "Passionate Kisser", grade = 1, points = 3, description = "For you, a kiss is more than a simple touch of lips. You kiss maidens and deadbeats alike with unmatched affection and faced death and rebirth through the kiss of the banshee queen. Lucky are those who get to share such an intimate moment with you!"}, + [64] = {name = "Perfect Fool", grade = 1, points = 3, description = "You love playing jokes on others and tricking them into looking a little silly. Wagging tongues say that the moment of realisation in your victims' eyes is the reward you feed on, but you're probably just kidding and having fun with them... right??"}, + [65] = {name = "Poet Laureate", grade = 1, points = 2, secret = true, description = "Poems, verses, songs and rhymes you've recited many times. You have passed the cryptic door, raconteur of ancient lore. Even elves you've left impressed, so it seems you're truly blessed."}, + [66] = {name = "Polisher", grade = 2, points = 4, secret = true, description = "If you see a rusty item, you can't resist polishing it. There's always a little flask of rust remover in your inventory - who knows, there might be a golden armor beneath all that dirt!"}, + [67] = {name = "Potion Addict", grade = 2, points = 4, secret = true, description = "Your local magic trader considers you one of his best customers - you usually buy large stocks of potions so you won't wake up in the middle of the night craving for more. Yet, you always seem to run out of them too fast. Cheers!"}, + [68] = {name = "Quick as a Turtle", grade = 1, points = 2, secret = true, description = "There... is... simply... no... better... way - than to travel on the back of a turtle. At least you get to enjoy the beautiful surroundings of Laguna."}, + [69] = {name = "Razing!", grade = 3, points = 7, secret = true, description = "People with sharp canine teeth better beware of you, especially at nighttime, or they might find a stake between their ribs. You're a merciless vampire hunter and have gathered numerous tokens as proof."}, + [70] = {name = "Recognised Trader", grade = 1, points = 3, description = "You're a talented merchant who's able to handle wares with care, finds good offers and digs up rares every now and then. Never late to complete an order, you're a reliable trader - at least in Rashid's eyes."}, + [71] = {name = "Rockstar", grade = 1, points = 3, secret = true, description = "Music just comes to you naturally. You feel comfortable on any stage, at any time, and secretly hope that someday you will be able to defeat your foes by playing music only. Rock on!"}, + [72] = {name = "Ruthless", grade = 2, points = 5, description = "You've touched all thrones of The Ruthless Seven and absorbed some of their evil spirit. It may have changed you forever."}, + [73] = {name = "Scrapper", grade = 1, points = 3, description = "You put out the Spirit of Fire's flames in the arena of Svargrond. Arena fights are for you - fair, square, with simple rules and one-on-one battles."}, + [74] = {name = "Sea Scout", grade = 1, points = 2, description = "Not even the hostile underwater environment stops you from doing your duty for the Explorer Society. Scouting the Quara realm is a piece of cake for you."}, + [75] = {name = "Secret Agent", grade = 1, points = 1, description = "Pack your spy gear and get ready for some dangerous missions in service of a secret agency. You've shown you want to - but can you really do it? Time will tell."}, + [76] = {name = "Shell Seeker", grade = 1, points = 3, secret = true, description = "You found a hundred beautiful pearls in large sea shells. By now that necklace should be finished - and hopefully you didn't get your fingers squeezed too often during the process."}, + [77] = {name = "Ship's Kobold", grade = 2, points = 4, secret = true, description = "You've probably never gotten seasick in your life - you love spending your free time on the ocean and covered quite a lot of miles with ships. Aren't you glad you didn't have to swim all that?"}, + [78] = {name = "Steampunked", grade = 1, points = 2, secret = true, description = "Travelling with the dwarven steamboats through the underground rivers is your preferred way of crossing the lands. No pesky seagulls, and good beer on board!"}, + [79] = {name = "Superstitious", grade = 1, points = 2, secret = true, description = "Fortune tellers and horoscopes guide you through your life. And you probably wouldn't dare going on a big game hunt without your trusty voodoo skull giving you his approval for the day."}, + [80] = {name = "Talented Dancer", grade = 1, points = 1, description = "You're a lord or lady of the dance - and not afraid to use your skills to impress tribal gods. One step to the left, one jump to the right, twist and shout!"}, + [81] = {name = "Territorial", grade = 1, points = 1, secret = true, description = "Your map is your friend - always in your back pocket and covered with countless marks of interesting and useful locations. One could say that you might be lost without it - but luckily there's no way to take it from you."}, + [82] = {name = "The Milkman", grade = 1, points = 2, description = "Who's the milkman? You are!"}, + [83] = {name = "Top AVIN Agent", grade = 2, points = 4, description = "You've proven yourself as a worthy member of the 'family' and successfully carried out numerous spy missions for your 'uncle' to support the Venorean traders and their goals."}, + [84] = {name = "Top CGB Agent", grade = 2, points = 4, description = "Girl power! Whether you're female or not, you've proven absolute loyalty and the willingness to put your life at stake for the girls brigade of Carlin."}, + [85] = {name = "Top TBI Agent", grade = 2, points = 4, description = "Conspiracies and open secrets are your daily bread. You've shown loyalty to the Thaian crown through your courage when facing enemies and completing spy missions. You're an excellent field agent of the TBI."}, + [86] = {name = "Turncoat", grade = 2, points = 4, secret = true, description = "You served Yalahar - but you didn't seem so sure whom to believe on the way. Both Azerus and Palimuth had good reasons for their actions, and thus you followed your gut instinct in the end, even if you helped either of them. May Yalahar prosper!"}, + [87] = {name = "Vanity", grade = 1, points = 3, secret = true, description = "Aren't you just perfectly, wonderfully, beautifully gorgeous? You can't pass a mirror without admiring your looks. Or maybe doing a quick check whether something's stuck in your teeth, perhaps?"}, + [88] = {name = "Vive la Resistance", grade = 1, points = 2, description = "You've always been a rebel - admit it! Supplying prisoners, caring for outcasts, stealing from the rich and giving to the poor - no wait, that was another story."}, + [89] = {name = "Warlord of Svargrond", grade = 2, points = 5, description = "You sent the Obliverator into oblivion in the arena of Svargrond and defeated nine other dangerous enemies on the way. All hail the Warlord of Svargrond!"}, + [90] = {name = "Waverider", grade = 1, points = 2, secret = true, description = "One thing's for sure: You definitely love swimming. Hanging out on the beach with your friends, having ice cream and playing beach ball is splashingly good fun!"}, + [91] = {name = "Wayfarer", grade = 1, points = 3, secret = true, description = "Dragon dreams are golden."}, + [92] = {name = "Worm Whacker", grade = 1, points = 1, secret = true, description = "Weehee! Whack those worms! You sure know how to handle a big hammer."}, + + --8.61 + [93] = {name = "Cocoon of Doom", grade = 1, points = 3, secret = true, description = "You helped bringing Devovorga's dangerous tentacles and her humongous cocoon down - not stopping her transformation, but ultimately completing a crucial step to her death."}, + [94] = {name = "Daring Trespasser", grade = 1, points = 3, secret = true, description = "You've entered the lair of Devovorga and joined the crew trying to take her down - whether crowned with success or not doesn't matter, but they can't blame you for not trying!"}, + [95] = {name = "Devovorga's Nemesis", grade = 2, points = 5, secret = true, description = "One special hero among many. This year - it was you. Devovorga withdrew in a darker realm because she could not withstand your power - and that of your comrades. Time will tell if the choice you made was good - but for now, it saved your world."}, + [96] = {name = "I Did My Part", grade = 1, points = 2, secret = true, description = "Your world is lucky to have you! You don't hesitate to jump in and help when brave heroes are called to save the world."}, + [97] = {name = "Notorious Worldsaver", grade = 3, points = 8, secret = true, description = "You're in the front line when it comes to saving your world or taking part in social events. Whether you do it noticed or unnoticed by the people, your world can rely on you to dutifully do your part to make it a better place for everyone."}, + [98] = {name = "Slayer of Anmothra", grade = 1, points = 2, secret = true, description = "Souls are like butterflies. The black soul of a living weapon yearning to strike lies shattered beneath your feet."}, + [99] = {name = "Slayer of Chikhaton", grade = 1, points = 2, secret = true, description = "Power lies in the will of her who commands it. You fought it with full force - and were stronger."}, + [100] = {name = "Slayer of Irahsae", grade = 1, points = 2, secret = true, description = "Few things equal the wild fury of a trapped and riven creature. You were a worthy opponent."}, + [101] = {name = "Slayer of Phrodomo", grade = 1, points = 2, secret = true, description = "Blind hatred took physical form, violently rebelling against the injustice it was born into. You were not able to bring justice - but at least temporary peace."}, + [102] = {name = "Slayer of Teneshpar", grade = 1, points = 2, secret = true, description = "The forbidden knowledge of aeons was never meant to invade this world. You silenced its voice before it could be made heard."}, + [103] = {name = "Teamplayer", grade = 1, points = 2, secret = true, description = "You don't consider yourself too good to do the dirty work while someone else might win the laurels for killing Devovorga. They couldn't do it without you!"}, + + --8.62 + [104] = {name = "Alumni", grade = 2, points = 6, description = "You're considered a first-rate graduate of the Magic Academy in Edron due to your pioneering discoveries and successful studies in the field of experimental magic and spell development. Ever considered teaching the Armageddon spell?"}, + [105] = {name = "Aristocrat", grade = 2, points = 4, description = "You begin your day by bathing in your pot of gold and you don't mind showing off your wealth while strolling the streets in your best clothes - after all it's your hard-earned money! You prefer to be addressed with 'Your Highness'."}, + [106] = {name = "Bad Timing", grade = 1, points = 2, secret = true, description = "Argh! Not now! How is it that those multifunctional tools never fail when you're using them for something completely trivial like squeezing juice, but mess up when you desperately need to climb up a rope spot with a fire-breathing dragon chasing you?"}, + [107] = {name = "Berserker", grade = 1, points = 3, description = "RAWR! Strength running through your body, your heart racing faster and adrenaline fueling your every weapon swing. All in a little bottle. No refund for destroyed furniture. For further questions consult your healer or potion dealer."}, + [108] = {name = "Bluebarian", grade = 1, points = 2, secret = true, description = "You live the life of hunters and gatherers. Well, especially that of a gatherer, and especially of one who gathers lots of blueberries. Have you checked the colour of your tongue lately?"}, + [109] = {name = "Brutal Politeness", grade = 2, points = 6, description = "What is best in life? To crush your enemies. To see them driven before you. And to maybe have a nice cup of tea afterwards."}, + [110] = {name = "Commitment Phobic", grade = 1, points = 2, secret = true, description = "Longterm relationships are just not for you. And each time you think you're in love, you're proven wrong shortly afterwards. Or maybe you just end up with the wrong lover each time - exploited and betrayed. Staying single might just be better."}, + [111] = {name = "Cookie Monster", grade = 1, points = 1, secret = true, description = "You can easily be found by anyone if they just follow the cookie crumb trail. And for you, true love means to give away your last cookie."}, + [112] = {name = "Cursed!", grade = 1, points = 3, secret = true, description = "The wrath of the Noxious Spawn - you accidentally managed to incur it. Your days are counted and your death inevitable. Sometime. Someplace."}, + [113] = {name = "Demonbane", grade = 2, points = 6, description = "You don't carry that stake just for decoration - you're prepared to use it. Usually you're seen hightailing through the deepest dungeons leaving a trail of slain demons. Whoever dares stand in your way should prepare to die."}, + [114] = {name = "Demonic Barkeeper", grade = 1, points = 3, description = "Thick, red - shaken, not stirred - and with a straw in it: that's the way you prefer your demon blood. Served with an onion ring, the subtle metallic aftertaste is almost not noticeable. Beneficial effects on health or mana are welcome."}, + [116] = {name = "Do Not Disturb", grade = 1, points = 1, secret = true, description = "Urgh! Close the windows! Shut out the sun rearing its ugly yellow head, shut out the earsplitting laughter of your neighbour's corpulent children. Ahhh. Embrace sweet darkness and silence."}, + [117] = {name = "Exemplary Citizen", grade = 2, points = 4, description = "Every city should be proud to call someone like you its inhabitant. You're keeping the streets clean and help settling the usual disputes in front of the depot. Also, you probably own a cat and like hiking."}, + [118] = {name = "Fool at Heart", grade = 1, points = 3, description = "And remember: Never try to teach a pig to sing. It wastes your time and annoys the pig."}, + [119] = {name = "Free Items!", grade = 1, points = 3, secret = true, description = "Yay! Finders keepers, losers weepers! Who cares where all that stuff came from and if you had to crawl through garbage piles to get it? It's FREE!"}, + [120] = {name = "Godslayer", grade = 2, points = 4, description = "You have defeated the Snake God's incarnations and, with a final powerful swing of the snake sceptre, cut off his life force supply. The story of power, deceit and corruption has come to an end - or... not?"}, + [121] = {name = "Gold Digger", grade = 2, points = 4, secret = true, description = "Hidden treasures below the sand dunes of the desert - you have a nose for finding them and you know where to dig. They might not make you filthy rich, but they're shiny and pretty anyhow."}, + [122] = {name = "Happy Farmer", grade = 1, points = 1, secret = true, description = "Scythe swung over your shoulder, sun burning down on your back - you are a farmer at heart and love working in the fields. Or then again maybe you just create fancy crop circles to scare your fellow men."}, + [123] = {name = "Heartbreaker", grade = 1, points = 1, secret = true, description = "Trust? Love? Faithfulness? Pah! Antiquated sentiments. As long as you have fun, you do not mind stepping on lots of hearts. Preferably while wearing combat boots."}, + [124] = {name = "Homebrewed", grade = 1, points = 1, secret = true, description = "Yo-ho-ho and a bottle of rum - homebrewed, of course, made from handpicked and personally harvested sugar cane plants. Now, let it age in an oak barrel and enjoy it in about 10 years. Or for the impatient ones: Let's have a paaaarty right now!"}, + [125] = {name = "Hunting with Style", grade = 2, points = 6, description = "At daytime you can be found camouflaged in the woods laying traps or chasing big game, at night you're sitting by the campfire and sharing your hunting stories. You eat what you hunted and wear what you skinned. Life could go on like that forever."}, + [126] = {name = "I Need a Hug", grade = 1, points = 2, description = "You and your stuffed furry friends are inseparable, and you're not ashamed to take them to bed with you - who knows when you will wake up in the middle of the night in dire need of a cuddle?"}, + [127] = {name = "In Shining Armor", grade = 2, points = 6, description = "With edged blade and fully equipped in a sturdy full plate armor, you charge at your enemies with both strength and valour. There's always a maiden to save and a dragon to slay for you."}, + [128] = {name = "Joke's on You", grade = 1, points = 1, secret = true, description = "Well - the contents of that present weren't quite what you expected. With friends like these, who needs enemies?"}, + [129] = {name = "Keeper of the Flame", grade = 1, points = 2, secret = true, description = "One of the Lightbearers. One of those who helped to keep the basins burning and worked together against the darkness. The demonic whispers behind the thin veil between the worlds - they were silenced again thanks to your help."}, + [130] = {name = "Let the Sunshine In", grade = 1, points = 1, secret = true, description = "Rise and shine! It's a beautiful new day - open your windows, feel the warm sunlight, watch the birds singing on your windowsill and care for your plants. What reason is there not to be happy?"}, + [131] = {name = "Life on the Streets", grade = 2, points = 4, description = "You're a beggar, homeless, wearing filthy and ragged clothes. But that doesn't mean you have to beg anyone for stuff - and you still kept your pride. Fine feathers do not necessarily make fine birds - what's under them is more important."}, + [132] = {name = "Make a Wish", grade = 1, points = 1, secret = true, description = "But close your eyes and don't tell anyone what you wished for, or it won't come true!"}, + [133] = {name = "Master of War", grade = 2, points = 6, description = "You're not afraid to show your colours in the heat of battle. Enemies fear your lethal lance and impenetrable armor. The list of the wars you've won is impressive. Hail and kill!"}, + [134] = {name = "Mastermind", grade = 1, points = 3, description = "You feel you could solve the hardest riddles within a minute or so. Plus, there's a nice boost on your spell damage. All in a little bottle. Aftereffects - feeling slightly stupid. For further questions consult your healer or potion dealer."}, + [135] = {name = "Mister Sandman", grade = 1, points = 2, secret = true, description = "Tired... so tired... curling up in a warm and cosy bed seems like the perfect thing to do right now. Sweet dreams!"}, + [136] = {name = "Modest Guest", grade = 1, points = 1, secret = true, description = "You don't need much to sleep comfortably. A pile of straw and a roof over your head - with the latter being completely optional - is quite enough to relax. You don't even mind the rats nibbling on your toes."}, + [137] = {name = "Mutated Presents", grade = 1, points = 1, secret = true, description = "Muahahaha it's a... mutated pumpkin! After helping to take it down - you DID help, didn't you? - you claimed your reward and got a more or less weird present. Happy Halloween!"}, + [138] = {name = "Natural Sweetener", grade = 1, points = 1, secret = true, description = "Liberty Bay is the perfect hangout for you and harvesting sugar cane quite a relaxing leisure activity. Would you like some tea with your sugar, hon?"}, + [139] = {name = "Nightmare Walker", grade = 2, points = 6, description = "You do not fear nightmares, you travel in them - facing countless horrors and fighting the fate they're about to bring. Few believe the dark prophecies you bring back from those dreams, but those who do fight alongside you as Nightmare Knights."}, + [140] = {name = "Nothing Can Stop Me", grade = 1, points = 1, secret = true, description = "You laugh at unprepared adventurers stuck in high grass or rush wood. Or maybe you actually do help them out. They call you... 'Machete'."}, + [141] = {name = "Number of the Beast", grade = 1, points = 2, description = "Six. Six. Six."}, + [142] = {name = "Of Wolves and Bears", grade = 2, points = 6, description = "One with nature, one with wildlife. Raw and animalistic power, sharpened senses, howling on the highest cliffs and roaring in the thickest forests - that's you."}, + [143] = {name = "One Thousand and One", grade = 2, points = 6, description = "You feel at home under the hot desert sun with sand between your toes, and your favourite means of travel is a flying carpet. Also, you can probably do that head isolation dance move."}, + [144] = {name = "Oops", grade = 1, points = 2, secret = true, description = "So much for your feathered little friend! Maybe standing in front of the birdcage, squeezing its neck and shouting 'Sing! Sing! Sing!' was a little too much for it?!"}, + [145] = {name = "Out in the Snowstorm", grade = 2, points = 4, description = "Snow heaps and hailstorms can't keep you from where you want to go. You're perfectly equipped for any expedition into the perpetual ice and know how to keep your feet warm. If you're a woman, that's quite an accomplishment, too."}, + [146] = {name = "Peazzekeeper", grade = 2, points = 6, description = "You're a humble warrior who doesn't need wealth or specialised equipment for travelling and fighting. You feel at home in the northern lands of Zao and did your part in fighting its corruption."}, + [147] = {name = "Piece of Cake", grade = 1, points = 1, description = "Life can be so easy with the right cake at the right time - and you mastered baking many different ones, so you should be prepared for almost everything life decides to throw at you."}, + [148] = {name = "Ritualist", grade = 2, points = 6, description = "You could be the author of the magnum opus 'How to Summon the Ultimate Beast from the Infernal Depths, Volume I'. Or, if your mind and heart are pure, you rather summon beings to help others. Or maybe just a little cat to have someone to cuddle."}, + [149] = {name = "Rock Me to Sleep", grade = 1, points = 1, secret = true, description = "Sleeping - you do it with style. You're chilling in your hammock, listening to the sound of the birds and crickets as you slowly drift away into the realm of dreams."}, + [150] = {name = "Rocket in Pocket", grade = 1, points = 1, secret = true, description = "Either you are not a fast learner or you find some pleasure in setting yourself on fire. Or you're just looking for a fancy title. In any case, you should know that passing gas during your little donkey experiments is not recommended."}, + [151] = {name = "Rollercoaster", grade = 1, points = 1, description = "Up and down and up and down... and then the big looping! Wait - they don't build loopings in Kazordoon. But ore wagon rides are still fun!"}, + [152] = {name = "Santa's Li'l Helper", grade = 1, points = 2, secret = true, description = "Christmas is your favourite time of the year, and boy, do you love presents. Buy some nice things for your friends, hide them away until - well, until you decide to actually unwrap them rather yourself."}, + [153] = {name = "Sharpshooter", grade = 1, points = 3, description = "Improved eyesight, arrows and bolts flying at the speed of light and pinning your enemies with extra damage. All in a little bottle. No consumption of carrots required. For further questions consult your healer or potion dealer."}, + [154] = {name = "Skull and Bones", grade = 2, points = 6, description = "Wearing the insignia and dark robes of the Brotherhood of Bones you roam the lands spreading fear and pain, creating new soldiers for the necromantic army which is about to rise soon. Hail the Brotherhood."}, + [155] = {name = "Slim Chance", grade = 1, points = 1, description = "Okay, let's face it - as long as you believe it could potentially lead you to the biggest treasure ever, you won't let go of that map, however fishy it might look. There must be a secret behind all of this!"}, + [156] = {name = "Swashbuckler", grade = 2, points = 6, description = "Ye be a gentleman o' fortune, fightin' and carousin' on the high seas, out fer booty and lassies! Ye no be answerin' to no man or blasted monarchy and yer life ain't fer the lily-livered. Aye, matey!"}, + [157] = {name = "Sweet Tooth", grade = 1, points = 2, secret = true, description = "The famous 'Ode to a Molten Chocolate Cake' was probably written by you. Spending a rainy afternoon in front of the chimney, wrapped in a blanket while indulging in cocoa delights sounds just like something you'd do. Enjoy!"}, + [158] = {name = "Swift Death", grade = 2, points = 6, description = "Stealth kills and backstabbing are you specialty. Your numerous victims are usually unaware of their imminent death, which you bring to them silently and swiftly. Everything is permitted."}, + [159] = {name = "The Cake's the Truth", grade = 1, points = 1, secret = true, description = "And anyone claiming otherwise is a liar."}, + [160] = {name = "The Day After", grade = 1, points = 2, secret = true, description = "Uhm... who's that person who you just woke up beside? Broken cocktail glasses on the floor, flowers all over the room, and why the heck are you wearing a ring? Yesterday must have been a long, weird day..."}, + [161] = {name = "The Undertaker", grade = 1, points = 2, secret = true, description = "You and your shovel - a match made in heaven. Or hell, for that matter. Somewhere down below in any case. You're magically attracted by stone piles and love to open them up and see where those holes lead you. Good biceps as well."}, + [162] = {name = "True Lightbearer", grade = 2, points = 5, secret = true, description = "You're one of the most dedicated Lightbearers - without you, the demons would have torn the veil between the worlds for sure. You've lit each and every basin, travelling high and low, pushing back the otherworldly forces. Let there be light!"}, + [163] = {name = "Warlock", grade = 2, points = 6, description = "You're proficient in the darker ways of magic and are usually found sitting inside a circle of candles and skulls muttering unspeakable words. Don't carry things too far or the demons might come get you."}, + [164] = {name = "Way of the Shaman", grade = 2, points = 6, description = "Shaking your rattle and dancing around the fire to jungle drums sounds like something you like doing. Besides, dreadlocks are a convenient way to wear your hair - no combing required!"}, + [165] = {name = "Wild Warrior", grade = 2, points = 6, description = "Valour is for weaklings - it doesn't matter how you win the battle, as long as you're victorious. Thick armor would just hinder your movements, thus you keep it light and rely on speed and skill instead of hiding in an uncomfortable shell."}, + [166] = {name = "With a Cherry on Top", grade = 1, points = 1, secret = true, description = "You like your cake soft, with fruity bits and a nice sugar icing. And you prefer to make them by yourself. Have you ever considered opening a bakery? You must be really good by now!"}, + [167] = {name = "Yalahari of Power", grade = 1, points = 3, description = "You defend Yalahar with brute force and are ready to lead it into a glorious battle, if necessary. Thanks to you, Yalahar will be powerful enough to stand up against any enemy."}, + [168] = {name = "Yalahari of Wisdom", grade = 1, points = 3, description = "Your deeds for Yalahar are usually characterised by deep insight and thoughtful actions. Thanks to you, Yalahar might have a chance to grow peacefully and with happy people living in it."}, + + --8.7 + [169] = {name = "Afraid of no Ghost!", grade = 1, points = 2, description = "You passed their test and helped the Spirithunters testing equipment, researching the supernatural and catching ghosts - it's you they're gonna call."}, + [170] = {name = "Ashes to Dust", grade = 2, points = 4, secret = true, description = "Staking vampires and demons has almost turned into your profession. You make sure to gather even the tiniest amount of evil dust particles. Beware of silicosis."}, + [171] = {name = "Baby Sitter", grade = 1, points = 1, secret = true, description = "You have cheered up a demon baby and returned it to its mother. A quick count of your fingers will reveal if you made it through unharmed."}, + [172] = {name = "Banebringers' Bane", grade = 1, points = 2, secret = true, description = "You sacrificed a lot of ingredients to create the protective brew of the witches and played a significant part in the efforts to repel the dreaded banebringers. The drawback is that even the banebringers may take notice of you ..."}, + [173] = {name = "Berry Picker", grade = 2, points = 4, secret = true, description = "The Combined Magical Winterberry Society hereby honours continued selfless dedication and extraordinary efforts in the Annual Autumn Vintage."}, + [174] = {name = "Bunny Slipped", grade = 1, points = 2, description = "Indeed, you have a soft spot for rabbits. Maybe the rabbits you saved today will be the rabbits that will save you tomorrow. When you are really hungry."}, + [175] = {name = "Cake Conqueror", grade = 1, points = 1, description = "You have bravely stepped onto the cake isle. Is there any more beautiful, tasty place to be in the whole world?"}, + [176] = {name = "Dark Voodoo Priest", grade = 1, points = 2, secret = true, description = "Sinister curses, evil magic - you don't shy away from punishing others by questionable means. Someone just gave you a strange look - now where's that needle again?"}, + [177] = {name = "Extreme Degustation", grade = 1, points = 2, secret = true, description = "Almost all the plants you tested for Chartan in Zao where inedible - you tasted them all, yet you're still standing! You should really get some fresh air now, though."}, + [178] = {name = "Fire Devil", grade = 1, points = 3, secret = true, description = "To keep the witches' fire burning, you trashed a lot of the wood the bane bringers animated. Some might find your fascination for fire ... disturbing."}, + [179] = {name = "Fire Lighter", grade = 1, points = 1, secret = true, description = "You have helped to keep the witches fire burning. Just watch your fingers, it's hot!"}, + [180] = {name = "Ghost Sailor", grade = 1, points = 1, secret = true, description = "You have sailed the nether seas with the Ghost Captain. Despite the perils, you and your fellow crewmen have braved the challenge."}, + [181] = {name = "Guinea Pig", grade = 1, points = 2, description = "True scientists know their equipment. Testing new inventions is essential daily work for any hard working researcher. You showed no fear and took all the new equipment from Spectulus and Sinclair for a spin."}, + [182] = {name = "Hidden Powers", grade = 1, points = 2, description = "You've discovered the Ancients' hidden powers - from now on, they will aid you in your adventures."}, + [183] = {name = "Honorary Witch", grade = 2, points = 4, secret = true, description = "Your efforts in fighting back the banebringers has not gone unnoticed. You are a legend amongst the witches and your name is whispered with awe and admiration."}, + [184] = {name = "I Like it Fancy", grade = 1, points = 1, secret = true, description = "You definitely know how to bring out the best in your furniture and decoration pieces. Beautiful."}, + [185] = {name = "Master Shapeshifter", grade = 1, points = 2, secret = true, description = "You have mastered Kuriks challenge in all possible shapes."}, + [186] = {name = "Merry Adventures", grade = 1, points = 2, description = "You went into the forest, met Rottin Wood and the Married Men and helped them out in their camp. Oh, and don't worry about those merchants. They won't dare mentioning the strangely large sums of gold they actually possessed which are missing now."}, + [187] = {name = "Nanny from Hell", grade = 1, points = 3, secret = true, description = "You have cheered up a bunch of demon babies and returned them to their mother. Don't bother the burn marks, don't bother the strains of grey hair, don't bother the nights you wake up screaming. It was worth it ... probably ... somehow."}, + [188] = {name = "Natural Born Cowboy", grade = 1, points = 1, secret = true, description = "Oh, the joy of riding! You've just got your very first own mount. Conveniently enough you don't even need stables, but can summon it any time you like."}, + [189] = {name = "Nether Pirate", grade = 1, points = 3, secret = true, description = "Not fearing death or ghosts you have traveled with the ghost captain several times and are a seasoned traveler of the netherworld. The dead and the living whisper about your exploits with appreciation."}, + [190] = {name = "Nomad Soul", grade = 1, points = 2, secret = true, description = "Home is where your current favourite hunting ground is, and though you might hold certain places more dear than others you never feel attached enough to really stay in one city for long. Pack all your stuff - it's time to move on again."}, + [191] = {name = "Petrologist", grade = 1, points = 2, secret = true, description = "Stones have always fascinated you. So has the chance of finding something really precious inside one of them. Statistically you should've discovered a few nice treasures by now. But then again, most statistics are overriden by Mother Disfortune."}, + [192] = {name = "Pyromaniac", grade = 2, points = 4, secret = true, description = "Love ... fire! So ... shiny! Must ... buuuurrrn!"}, + [193] = {name = "Safely Stored Away", grade = 1, points = 2, secret = true, description = "Don't worry, no one will be able to take it from you. Probably."}, + [194] = {name = "Scourge of Death", grade = 2, points = 5, secret = true, description = "You are a master of the nether sea and have traveled with the ghost captain so many times that you know his ship and the perils of the nether sea inside out. You laugh in the face of death and may return as a ghost pirate yourself in the afterlife!"}, + [195] = {name = "Silent Pet", grade = 1, points = 1, secret = true, description = "Awww. Your very own little goldfish friend - he's cute, he's shiny and he can't complain should you forget to feed him. He'll definitely brighten up your day!"}, + [196] = {name = "Skin-Deep", grade = 2, points = 4, secret = true, description = "You always carry your obsidian knife with you and won't hesitate to use it. You've skinned countless little - and bigger - critters and yeah: they usually don't get any more beautiful on the inside. It's rather blood and gore and all that..."}, + [197] = {name = "Snowbunny", grade = 1, points = 2, secret = true, description = "Hopping, hopping through the snow - that's the funnest way to go! Making footprints in a flurry - it's more fun the more you hurry! Licking icicles all day - Winter, never go away!"}, + [198] = {name = "Something's in There", grade = 1, points = 1, secret = true, description = "By the gods! What was that?"}, + [199] = {name = "Spectral Traveler", grade = 1, points = 2, secret = true, description = "You have sailed the nether seas with the Ghost Captain several times. The dangers of the nether have become familiar to you and unexperienced travelers turn to you for advice."}, + [200] = {name = "True Colours", grade = 1, points = 3, secret = true, description = "You and your friends showed the three wizards your loyalty three times - I am sure at least one of them is probably eternally thankful and exceedingly proud of you."}, + [201] = {name = "Truth Be Told", grade = 1, points = 2, secret = true, description = "You told Jack the truth by explaining you and Spectulus made a mistake when trying to convince him of being a completely different person."}, + [202] = {name = "Witches Lil' Helper", grade = 1, points = 1, secret = true, description = "You sacrificed ingredients to create the protective brew of the witches."}, + [203] = {name = "You Don't Know Jack", grade = 1, points = 2, secret = true, description = "You did not tell Jack the truth about the mistake you and Spectulus made when trying to convince him about being a completely different person. He will live in doubt until the end of his existence."}, + + --9.1 + [204] = {name = "Askarak Nemesis", grade = 1, points = 1, secret = true, description = "You are now the royal archfiend of the Askarak, prince slayer."}, + [205] = {name = "Beak Doctor", grade = 2, points = 4, description = "You significantly helped the afflicted citizens of Venore in times of dire need. Somehow you still feel close to the victims of the fever outbreak. Your clothes make you one of them, one poor soul amongst the countless afflicted."}, + [206] = {name = "Biodegradable", grade = 1, points = 1, secret = true, description = "You caught fifty rare shimmer swimmers. Getting rid of all those corpses by dumping them into the lake really was worth it, wasn't it? Wait, didn't something move in the water just now...?"}, + [207] = {name = "Deer Hunt", grade = 1, points = 1, secret = true, description = "You managed to kill more than four hundred white deer - it looks like you are one of the main reasons they will soon be considered extinct, way to go!"}, + [208] = {name = "Doctor! Doctor!", grade = 1, points = 2, secret = true, description = "Did someone call a doctor? You delivered 100 medicine bags to Ottokar of the Venore poor house in times of dire need, well done!"}, + [209] = {name = "Eye of the Deep", grade = 1, points = 1, secret = true, description = "You didn't look into it - at least not for too long... but Groam did. And you relieved him. Just don't tell his friend Dronk."}, + [210] = {name = "Firefighter", grade = 1, points = 2, secret = true, description = "You extinguished 500 thornfires! You were there when the Firestarters took over Shadowthorn. You saved the day - and the home of some elves which will try to kill you nonetheless. Isn't it nice to see everything restored just as it was before..?"}, + [211] = {name = "Invader of the Deep", grade = 1, points = 2, secret = true, description = "Many creatures of the deep have lost their lives by your hand. Three hundred have entered the depths of eternity. You should probably fear the revenge of the Eyes of the Deep."}, + [212] = {name = "Mageslayer", grade = 1, points = 1, secret = true, description = "You killed the raging mage in his tower south of Zao. Again. But this one just keeps coming back. The dimensional portal collapsed once more and you know he will eventually return but hey - a raging mage, it's like asking for it..."}, + [213] = {name = "Mystic Fabric Magic", grade = 2, points = 4, description = "You vanquished the mad mage, you subdued the raging mage - no spellweaving self-exposer can stand in your way. Yet you are quite absorbed in magical studies yourself. This very fabric reflects this personal approval of the magic arts."}, + [214] = {name = "Shaburak Nemesis", grade = 1, points = 1, secret = true, description = "You are now the public archenemy of the Shaburak, prince slayer."}, + [215] = {name = "Slimer", grade = 1, points = 1, secret = true, description = "With the assistance of your friendly little helper, you gobbled more than 500 chunks of slime. Well done, Slimer."}, + + --9.2 + [216] = {name = "Arachnoise", grade = 1, points = 1, description = "You've shattered each of Bloodweb's eight frozen legs. As they say: break a leg, and then some more."}, + [217] = {name = "Back into the Abyss", grade = 1, points = 1, description = "You've cut off a whole lot of tentacles today. Thul was driven back to where he belongs."}, + [218] = {name = "Beautiful Agony", grade = 1, points = 2, description = "Ethershreck's cry of agony kept ringing in your ear for hours after he had dissolved into thin air. He probably moved to another plane of existence... for a while."}, + [219] = {name = "Blood-Red Snapper", grade = 1, points = 1, description = "You've tainted the jungle floor with the Snapper's crimson blood."}, + [220] = {name = "Breaking the Ice", grade = 1, points = 1, description = "You almost made friends with Shardhead... before he died. Poor guy only seems to attract violence with his frosty attitude."}, + [221] = {name = "Choking on Her Venom", grade = 1, points = 1, description = "The Old Widow fell prey to your supreme hunting skills."}, + [222] = {name = "Crawling Death", grade = 1, points = 1, description = "You ripped the ancient scarab Fleshcrawler apart and made sure he didn't get under your skin."}, + [223] = {name = "Hissing Downfall", grade = 1, points = 2, description = "You've vansquished the Noxious Spawn and his serpentine heart."}, + [224] = {name = "Just Cracked Me Up!", grade = 1, points = 2, description = "Stonecracker's head was much softer than the stones he threw at you."}, + [225] = {name = "Meat Skewer", grade = 1, points = 1, description = "You've impaled the big mammoth Bloodtusk with his own tusks."}, + [226] = {name = "No More Hiding", grade = 1, points = 1, description = "You've found a well-hidden spider queen and caught her off guard in the middle of her meal."}, + [227] = {name = "One Less", grade = 1, points = 2, description = "The Many is no more, but how many more are there? One can never know."}, + [228] = {name = "Pwned a Lot of Fur", grade = 3, points = 8, secret = true, description = "You've faced and defeated a lot of the mighty bosses the Paw and Fur society sent you out to kill. All by yourself. What a hunt!"}, + [229] = {name = "Rootless Behaviour", grade = 1, points = 1, description = "You've descended into the swampy depths of Deathbine's lair and made quick work of it."}, + [230] = {name = "Scorched Flames", grade = 1, points = 1, description = "A mighty blaze went out today. It's Flameborn's turn to wait for his rebirth in the eternal cycle of life and death."}, + [231] = {name = "Something Smells", grade = 1, points = 1, description = "You've exinguished the Sulphur Scuttler's gas clouds and made the air in his cave a little better... at least for a while."}, + [232] = {name = "Spareribs for Dinner", grade = 1, points = 1, description = "Ribstride is striding no more. He had quite a few ribs to spare though."}, + [233] = {name = "The Drowned Sea God", grade = 1, points = 2, description = "As the killer of Leviathan, the giant sea serpent, his underwater kingdom is now under your reign."}, + [234] = {name = "The Gates of Hell", grade = 1, points = 2, description = "It seems the gates to the underworld have to remain unprotected for a while. Kerberos, the mighty hellhound, lost his head. All three of them."}, + [235] = {name = "The Serpent's Bride", grade = 1, points = 2, description = "You made a knot with Gorgo's living curls and took her scalp. You couldn't save her countless petrified victims, but at least you didn't become one."}, + [236] = {name = "Twisted Mutation", grade = 1, points = 1, description = "You've slain Esmeralda, the most hideous and aggressive of the mutated rats. No one will know that you almost lost a finger in the process."}, + + --9.4 + [237] = {name = "Bane of the Hive", grade = 1, points = 2, description = "Countless fights and never tiring effort in the war against the hive grant you the experience to finish your outfit with the last remaining part. Your chitin outfit is a testament of your skills and dedication for the cause."}, + [238] = {name = "Chest Robber", grade = 1, points = 1, description = "You've discovered three nomad camps and stole their supplies. Well, you can probably use them better then they can."}, + [239] = {name = "Chitin Bane", grade = 2, points = 4, description = "You have become competent and efficient in gathering the substance that is needed to fight the hive. You almost smell like dissolved chitin and the Hive Born would tell their children scary stories about you if they could speak."}, + [240] = {name = "Confusion", grade = 1, points = 3, description = "The destruction you have caused by now can be felt throughout the whole hive. The mayhem that follows your step caused significant confusion in the consciousness of the hive."}, + [241] = {name = "Dazzler", grade = 1, points = 3, description = "In the war against the hive, your efforts in blinding it begin to pay off. Your actions have blinded the hive severely and the entity seems to become aware that something dangerous is happening."}, + [242] = {name = "Death Song", grade = 1, points = 3, description = "You hushed the songs of war in the black depths by sliencing more than three hundred Deepling Spellsingers."}, + [243] = {name = "Depth Dwellers", grade = 1, points = 3, description = "By eliminating at least three hundred Deepling Warriors you delivered quite a blow to the amassing armies of the deep."}, + [244] = {name = "Desert Fisher", grade = 1, points = 1, description = "You managed to catch a fish in a surrounding that usually doesn't even carry water. Everything is subject to change, probably..."}, + [245] = {name = "Dog Sitter", grade = 1, points = 1, description = "You showed Noodles the way home. How long will it take this time until he's on the loose again? That dog must be really bored in the throne room by now."}, + [246] = {name = "Down the Drain", grade = 1, points = 2, description = "You've found a secret dungeon in the flooded plains and killed several of its inhabitants. And now you have wet feet."}, + [247] = {name = "Exterminator", grade = 2, points = 4, description = "Efficient and lethal, you have gained significant experience in fighting the elite forces of the hive. Almost single-handed, you have slain the best of the Hive Born and live to tell the tale."}, + [248] = {name = "Fire from the Earth", grade = 1, points = 2, description = "You've survived the Hellgorge eruption and found a way through the flames and lava. You've even managed to kill a few fireborn on the way."}, + [249] = {name = "Gatherer", grade = 1, points = 2, description = "By killing creatures of the hive and gaining weapons for further missions, you started a quite effective way of war. You gathered a lot of dissolved chitin to resupply the war effort."}, + [250] = {name = "Gem Cutter", grade = 1, points = 1, secret = true, description = "You cut your first gem - and it bears your own name! Now that would be a nice gift! This does not make it a \"true\" Heart of the Sea, however..."}, + [251] = {name = "Goldhunter", grade = 1, points = 2, secret = true, description = " If it wasn't for you, several banks in Tibia would've gotten bankrupt by now. Keep on chasing bank robbers and no one will have to worry about the Tibian economy!"}, + [252] = {name = "Guard Killer", grade = 1, points = 2, description = "You have proven that you can beat the best of the hive. You have caused first promising breaches in the defence of the hive"}, + [253] = {name = "Guardian Downfall", grade = 2, points = 4, description = "You ended the life of over three hundred Deepling Guards. Not quite the guardian of the Deeplings, are you?"}, + [254] = {name = "Headache", grade = 1, points = 2, description = "Even in the deepest structures of the hive, you began to strike against the mighty foe. Your actions probably already gave the hive a headache."}, + [255] = {name = "Heartburn", grade = 1, points = 3, description = "Never-tiring, you attack the inner organs of the mighty hive. Your attacks on the hive's digestion system begin to cause some trouble."}, + [256] = {name = "Hickup", grade = 1, points = 2, description = "You have grown accustomed to frequenting the hive's stomach system. Your actions have caused the hive some first digestion problems."}, + [257] = {name = "Hive Blinder", grade = 2, points = 4, description = "You have put a lot of time and energy into keeping the hive unaware of what is happening on Quirefang. The hive learnt to fear your actions. It would surely crush you with all its might ... if it could only find you!"}, + [258] = {name = "Hive Fighter", grade = 1, points = 1, description = "You have participated that much in the hive war, that you are able to create some makeshift armor from the remains of dead hive born that can be found in the major hive, to show of your skill."}, + [259] = {name = "Hive Infiltrator", grade = 1, points = 3, description = "The most powerful warriors of the hive were killed by you by the dozens. The hive is not safe anymore because of your actions."}, + [260] = {name = "Hive War Veteran", grade = 1, points = 1, description = "Your invaluable experience in fighting the hive allows you to add another piece of armor to your chitin outfit to proove your dedication for the cause."}, + [261] = {name = "Honest Finder", grade = 1, points = 1, description = "You've stopped the bank robber and returned the bag full of gold. Good to know there are still lawful Tibians like you around."}, + [262] = {name = "Ice Harvester", grade = 1, points = 1, description = "You witnessed the thawing of Svargrond and harvested rare seeds from some strange icy plants. They must be good for something."}, + [263] = {name = "Loyal Subject", grade = 1, points = 1, description = "You joined the Kingsday festivities and payed King Tibianus your respects. Now, off to party!"}, + [264] = {name = "Manic", grade = 2, points = 4, description = "You have destroyed a significant amount of the hive's vital nerve centres and caused massive destruction to the hive's awareness. You are probably causing the hive horrible nightmares."}, + [265] = {name = "Minor Disturbance", grade = 1, points = 2, description = "Your actions start to make a difference. You have blinded the antennae of the hive often enough to become an annoyance to it."}, + [266] = {name = "Navigational Error", grade = 2, points = 5, secret = true, description = "You confronted the Navigator."}, + [267] = {name = "Pimple", grade = 1, points = 3, description = "You are getting more and more experienced in destroying the supply of the enemy's forces. Your actions caused the hive some severe skin problems."}, + [268] = {name = "Planter", grade = 1, points = 2, description = "The hive has to be fought with might and main, hampering its soldiers is only the first step. You diligently stopped the pores of the hive to spread its warriors."}, + [269] = {name = "Preservationist", grade = 1, points = 1, secret = true, description = "You are a pretty smart thinker and managed to create everlasting flowers. They might become a big hit with all the people who aren't blessed with a green thumb or just forgetful."}, + [270] = {name = "Si, Ariki!", grade = 1, points = 1, description = "You've found the oriental traveller Yasir and were able to trade with him - even if you didn't really understand his language."}, + [271] = {name = "Someone's Bored", grade = 1, points = 1, secret = true, description = "That was NOT a giant spider. There's some witchcraft at work here."}, + [272] = {name = "Spolium Profundis", grade = 2, points = 4, description = "You travelled the depths of this very world. You entered the blackness of the deep sea to conquer the realm of the Deeplings. May this suit remind you of the strange beauty below."}, + [273] = {name = "Stomach Ulcer", grade = 2, points = 4, description = "You severely disrupted the digestion of the hive. The hive should for sure see a doctor. It seems you proved to be more than it can swallow."}, + [274] = {name = "Supplier", grade = 1, points = 3, description = "The need for supplies often decides over loss or victory. Your tireless efforts to resupply the resources keeps the war against the hive going."}, + [275] = {name = "Suppressor", grade = 2, points = 4, description = "A war is won by those who have the best supply of troops. The hive's troops have been dealt a significant blow by your actions. You interrupted the hive's replenishment of troops lastingly and severely."}, + [276] = {name = "Torn Treasures", grade = 1, points = 1, secret = true, description = "Wyda seems to be really, really bored. You also found out that she doesn't really need all those blood herbs that adventurers brought her. Still, she was nice enough to take one from you and gave you something quite cool in exchange."}, + [277] = {name = "Trail of the Ape God", grade = 1, points = 1, secret = true, description = "You've discovered a trail of giant footprints and Terrified Elephants running everywhere. Could it be that the mysterious Ape God is rambling in the jungle?"}, + [278] = {name = "Whistle-Blower", grade = 1, points = 1, secret = true, description = "You can't keep a secret, can you? Then again, you're just fulfilling your duty to the Queen of Carlin as a lawful citizen. That's a good thing, isn't it...?"}, + + --9.5 + [279] = {name = "Back from the Dead", grade = 1, points = 2, description = "You overcame the undead Zanakeph and sent him back into the darkness that spawned him."}, + [280] = {name = "Dream's Over", grade = 1, points = 1, description = "No more fear and bad dreams. You stabbed Tormentor to death with its scythe leg."}, + [281] = {name = "Enter zze Draken!", grade = 1, points = 2, description = "You gave zzze draken a tazte of your finizzzing move."}, + [282] = {name = "Howly Silence", grade = 1, points = 1, description = "You muted the everlasting howling of Hemming."}, + [283] = {name = "Kapow!", grade = 1, points = 1, description = "No joke, you murdered the bat."}, + [284] = {name = "King of the Ring", grade = 1, points = 2, description = "Bretzecutioner's body just got slammed away. You are a true king of the ring!"}, + [285] = {name = "Pwned All Fur", grade = 3, points = 8, secret = true, description = "You've faced and defeated each of the mighty bosses the Paw and Fur society sent you out to kill. All by yourself. What a hunt!"}, + [286] = {name = "Stepped on a Big Toe", grade = 1, points = 1, description = "This time you knocked out the big one."}, + [287] = {name = "Zzztill Zzztanding!", grade = 1, points = 1, description = "You wiped Fazzrah away - zzeemzz like now you're the captain."}, + + --9.6 + [288] = {name = "Becoming a Bigfoot", grade = 1, points = 1, description = "You did it! You convinced the reclusive gnomes to accept you as one of their Bigfoots. Now you are ready to help them. With big feet big missions seen to come."}, + [289] = {name = "Bibby's Bloodbath", grade = 1, points = 1, secret = true, description = "You lend a helping hand in defeating invading Orcs by destroying their warcamp along with their leader. Bibby's personal bloodbath..."}, + [290] = {name = "Call Me Sparky", grade = 1, points = 1, description = "Admittedly you enjoyed the killing as usual. But the part with the sparks still gives you shivers ... or is it that there is some charge left on you?"}, + [291] = {name = "Crystal Clear", grade = 1, points = 3, description = "If the gnomes had told you that crystal armor is see-through you had probably changed your underwear in time."}, + [292] = {name = "Crystal Keeper", grade = 1, points = 1, description = "So you repaired the light of some crystals for those gnomes. What's next? Sitting a week in a mushroom bed as a temporary mushroom?"}, + [293] = {name = "Crystals in Love", grade = 1, points = 1, description = "You brought two loving crystals together. Perhaps they might even name one of their children after you. To bad you forgot to leave your calling card."}, + [294] = {name = "Death from Below", grade = 1, points = 2, secret = true, description = "The face of the enemy is unmasked. You have encountered one of 'those below' and survived. More than that, you managed to kill the beast and prove once and for all that the enemy can be beaten."}, + [295] = {name = "Death on Strike", grade = 2, points = 4, secret = true, description = "Again and again Deathstrike has fallen to your prowess. Perhaps it's time for people calling YOU Deathstrike from now on."}, + [296] = {name = "Diplomatic Immunity", grade = 2, points = 4, secret = true, description = "You killed the ambassador of the abyss that often that they might consider sending another one. Perhaps that will one day stop further intrusions."}, + [297] = {name = "Dungeon Cleaner", grade = 1, points = 3, secret = true, description = "Seen it all. Done it all. Your unstoppable force swept through the dungeons and you vanquished their masters. Not to forget the precious loot you took! Now stop reading this and continue hunting! Time is money after all!"}, + [298] = {name = "Fall of the Fallen", grade = 2, points = 4, secret = true, description = "Have you ever wondered how he reappears again and again? You only care for the loot, do you? Gotcha!"}, + [299] = {name = "Final Strike", grade = 1, points = 2, secret = true, description = "The mighty Deathstrike is dead! One legend is dead and you're on your way to become one yourself."}, + [300] = {name = "Funghitastic", grade = 1, points = 3, description = "Finally your dream to become a walking mushroom has come true ... No, wait a minute!"}, + [301] = {name = "Gnome Friend", grade = 1, points = 2, description = "The gnomes are warming up to you. One or two of them might actually bother to remember your name. You're allowed to access their gnomebase alpha. You are prepared to boldly put your gib feet into areas few humans have walked before."}, + [302] = {name = "Gnome Little Helper", grade = 1, points = 1, description = "You think the gnomes start to like you. A little step for a Bigfoot but a big step for humanity."}, + [303] = {name = "Gnomebane's Bane", grade = 1, points = 2, secret = true, description = "The fallen gnome is dead and justice served. But what was it that the gnome whispered with his last breath? He's your father???"}, + [304] = {name = "Gnomelike", grade = 1, points = 3, description = "You have become a household name in gnomish society! Your name is mentioned by gnomes more than once. Of course usually by gnomish mothers whose children refuse to eat their mushroom soup, but you are certainly making some tremendous progress."}, + [305] = {name = "Gnomish Art Of War", grade = 1, points = 3, description = "You have unleashed your inner gnome and slain some of the most fearsome threats that gnomekind has ever faced. Now you can come and go to the warzones as it pleases you. The enemies of gnomekind will never be safe again."}, + [306] = {name = "Goo Goo Dancer", grade = 1, points = 1, secret = true, description = "Seeing a mucus plug makes your heart dance and you can't resist to see what it hides. Goo goo away!"}, + [307] = {name = "Grinding Again", grade = 1, points = 1, description = "Burnt fingers and itching lungs are a small price for bringing those gnomes some lousy stone and getting almost killed! Your mother warned you to better become a farmer."}, + [308] = {name = "Honorary Gnome", grade = 2, points = 4, description = "You accomplished what few humans ever will: you truly impressed the gnomes. This might not change their outlook on humanity as a whole, but at least you can bathe in gnomish respect! And don't forget you're now allowed to enter the warzones!"}, + [309] = {name = "Nestling", grade = 1, points = 1, description = "You cleansed the land from an eight legged nuisance by defeating Mamma Longlegs three times. She won't be back soon... or will she?"}, + [310] = {name = "One Foot Vs. Many", grade = 1, points = 1, description = "One Bigfoot won over thousands of tiny feet. Perhaps the gnomes are wrong and size matters?"}, + [311] = {name = "Spore Hunter", grade = 1, points = 1, description = "After hunting for the correct mushrooms and their spores you're starting to feel like a mushroom yourself. A few times more and you might start thinking like a mushroom, who knows?"}, + [312] = {name = "Substitute Tinker", grade = 1, points = 1, description = "Ring-a-ding! You have visited the golem workshop and lent a hand in repairing them. To know those golems are safe is worth all the bruises, isn't it?"}, + [313] = {name = "The Picky Pig", grade = 1, points = 1, description = "The gnomes decided their pigs need some exclusive diet and you had to do all the dirty work - but wasn't the piglet adorable?"}, + + --9.8 + [314] = {name = "Task Manager", grade = 1, points = 2, secret = true, description = "Helping a poor, stupid goblin to feed his starving children and wifes feels good ... if you'd only get rid of the strange feeling that you're missing something."}, + [315] = {name = "True Dedication", grade = 2, points = 5, secret = true, description = "You conquered the demon challenge and prevailed... now show off your success in style!"}, + + --10.1 + [316] = {name = "Gravedigger", grade = 1, points = 3, description = "Assisting Omrabas' sick plan to resurrect made you dig your way through the blood-soaked halls of Drefia. Maybe better he failed!"}, + [317] = {name = "Repenter", grade = 1, points = 1, secret = true, description = "You cleansed your soul in serving the Repenter enclave and purified thine self in completing all tasks in a single day of labour."}, + + --10.2 + [318] = {name = "Cave Completionist", grade = 1, points = 2, description = " You have helped the gnomes of the spike in securing the caves and explored enough of the lightles depths to earn you a complete cave explorers outfit. Well done!"}, + + --10.3 + [319] = {name = "Dream Warden", grade = 2, points = 5, description = "It doesn't matter what noise you would hear... dream, nightmare, illusion - there is nothing you can't vanquish. You are a true Dream Warden."}, + [320] = {name = "Dream Wright", grade = 1, points = 1, description = "You have mended many a broken dream and so, the dream of Roshamuul is safely being told over and over again."}, + [321] = {name = "Ending the Horror", grade = 1, points = 2, description = "You have cleansed the lands of many retching horrors. You sure know how to end a bad dream: forcefully, that's how!"}, + [322] = {name = "Luring Silence", grade = 1, points = 2, description = "What a scientific discovery - they really DO communicate! Using their own communication habits against them, you lured a large pack of silencers away from the walls of Roshamuul."}, + [323] = {name = "Never Surrender", grade = 1, points = 3, description = "You did not show any signs of surrender to any sight of... you get the picture. Even a hundred of them did not pose a threat to you."}, + [324] = {name = "Nevermending Story", grade = 1, points = 3, secret = true, description = "You collected all of the mysterious bottle messages around the island of Roshamuul and located the remains of the first mate. Time will tell if his tale of mending an evil ring holds true."}, + [325] = {name = "Noblesse Obliterated", grade = 2, points = 6, description = "After a battle like this you know who your friends are."}, + [326] = {name = "Prison Break", grade = 3, points = 8, description = "Gaz'haragoth... a day to remember! Your world accomplished someting really big - and you have been part of it!"}, + [327] = {name = "Sleepwalking", grade = 1, points = 1, description = "You know your way, in dream and waking. And how to make tea that transcends the boundaries of conscience."}, + [328] = {name = "Umbral Archer", grade = 2, points = 6, description = "You managed to transform, improve and sacrify your bow into a master state and have proven yourself worthy in a nightmarish world."}, + [329] = {name = "Umbral Berserker", grade = 2, points = 6, description = "You managed to transform, improve and sacrify your hammer into a master state and have proven yourself worthy in a nightmarish world."}, + [330] = {name = "Umbral Bladelord", grade = 2, points = 6, description = "You managed to transform, improve and sacrify your slayer into a master state and have proven yourself worthy in a nightmarish world."}, + [331] = {name = "Umbral Brawler", grade = 2, points = 6, description = "You managed to transform, improve and sacrify your mace into a master state and have proven yourself worthy in a nightmarish world."}, + [332] = {name = "Umbral Executioner", grade = 2, points = 6, description = "You managed to transform, improve and sacrify your chopper into a master state and have proven yourself worthy in a nightmarish world."}, + [333] = {name = "Umbral Harbringer", grade = 2, points = 6, description = "You managed to transform, improve and sacrify your spellbook into a master state and have proven yourself worthy in a nightmarish world."}, + [334] = {name = "Umbral Headsman", grade = 2, points = 6, description = "You managed to transform, improve and sacrify your axe into a master state and have proven yourself worthy in a nightmarish world."}, + [335] = {name = "Umbral Marksman", grade = 2, points = 6, description = "You managed to transform, improve and sacrify your crossbow into a master state and have proven yourself worthy in a nightmarish world."}, + [336] = {name = "Umbral Master", grade = 3, points = 8, description = "You managed to transform, improve and sacrify all kinds of weapons into a master state and have proven yourself worthy in a nightmarish world. Respect!"}, + [337] = {name = "Umbral Swordsman", grade = 2, points = 6, description = "You managed to transform, improve and sacrify your blade into a master state and have proven yourself worthy in a nightmarish world."}, + + --10.5 + [338] = {name = "Combo Master", grade = 1, points = 1, secret = true, description = "You accomplished 10 or more consecutive chains in a row! That's killing at least 39 creatures in the correct order - now that's combinatorics!"}, + [339] = {name = "Elementary, My Dear", grade = 1, points = 1, description = "Through the spirit of science and exploration, you have discovered how to enter the secret hideout of the renowned Dr Merlay."}, + [340] = {name = "Glooth Engineer", grade = 2, points = 5, description = "Though you might have averted a dire threat for Rathleton, this relative peace may only hold for a while. At least you've scavenged an outfit from some of the poor fellows that have fallen prey to death priest Shagron."}, + [341] = {name = "Rathleton Citizen", grade = 1, points = 1, description = "By having rendered numerous services to the city of Rathleton you have been promoted to the rank of Citizen."}, + [342] = {name = "Rathleton Commoner", grade = 1, points = 1, description = "By having rendered numerous services to the city of Rathleton you have been promoted to the rank of Commoner."}, + [343] = {name = "Rathleton Inhabitant", grade = 1, points = 1, description = "By having rendered numerous services to the city of Rathleton you have been promoted to the rank of Inhabitant."}, + + --10.56 + [344] = {name = "Seasoned Adventurer", grade = 1, points = 1, description = "Adventure is your middle name. You spent much time in dangerous lands and have seen things others only dream of. You know your way around in Tibia - you are a seasoned adventurer now. And your journey has only just begun!"}, + + --10.7 + [345] = {name = "Go with da Lava Flow", grade = 1, points = 1, secret = true, description = "You escaped the glowing hot lava death trap, Professor Maxxen has set for you - Captain Caveworm is indeed proud!"}, + [346] = {name = "Lion's Den Explorer", grade = 1, points = 1, secret = true, description = "You discovered the Lion's Rock, passed the tests to enter the inner sanctum and finally revealed the secrets of the buried temple. You literally put your head in the lion's mouth and survived."}, + [347] = {name = "Mind the Step!", grade = 1, points = 1, description = "You've got a mind ready to draw strange conclusions that defy the laws of logic and sidestep reality. Or maybe it's just a lucky guess - or adventurous recklessness?"}, + [348] = {name = "Plant vs. Minos", grade = 1, points = 4, secret = true, description = "You have defeated the wallbreaker and saved the glooth plant."}, + [349] = {name = "Publicity", grade = 1, points = 1, description = "You are a man of the public. Or of good publicity at least. Through your efforts in advertising the airtight cloth, Zeronex might yet be redeemed - and Rathleton might yet see its first working Gloud Ship."}, + [350] = {name = "Rathleton Squire", grade = 1, points = 1, description = "By having rendered numerous services to the city of Rathleton you have been promoted to the rank of Squire."}, + [351] = {name = "Robo Chop", grade = 1, points = 4, secret = true, description = "You have defeated the glooth bomb and chopped down a lot of metal monsters on your way."}, + [352] = {name = "Rumble in the Plant", grade = 2, points = 4, secret = true, description = "You have defeated the tremor worm - and wonder what kind of fish you'd be able to catch with such a bait."}, + [353] = {name = "Snake Charmer", grade = 1, points = 1, description = "By restoring the Everhungry Altar, you charmed the Fire-Feathered Sea Serpent back into its fitful sleep, twenty miles beneath the sea."}, + [354] = {name = "The Professor's Nut", grade = 1, points = 3, description = "He seriously stored away a wallnut? That was a nutty professor indeed."}, + [355] = {name = "Wail of the Banshee", grade = 1, points = 1, secret = true, description = "You saw the Crystal Gardens with all their stunning beauty and survived the equally impressive monsters there. In the end you discovered a great evil and destroyed it with the help of a banshee who was not even aware of her support."}, + + --10.8 + [356] = {name = "Bearbaiting", grade = 1, points = 1, description = "Hunter's greeting! Your skillful use of the slingshot actually stunned a large bear. The creature is slightly dazed, but seems susceptible to your commands. Let's declare open season on all our foes!"}, + [357] = {name = "Beneath the Sea", grade = 1, points = 3, description = "Not really twenty thousand miles, but you had to dive a fair way beneath the sea to find your personal Manta Ray."}, + [358] = {name = "Blacknailed", grade = 1, points = 1, description = "Well, you can rest your nailcase now. This gravedigger's fingernails are nice and clean. Though after the next hellride, you might not want to let it hand any food to you."}, + [359] = {name = "Cartography 101", grade = 1, points = 2, description = "You succeeded in finding and charting several previously unexplored landmarks and locations for the Adventurer's Guild, you probably never need to ask anyone for the way - do you?"}, + [360] = {name = "Chequered Teddy", grade = 1, points = 1, description = "Don't let its fluffy appearance deceive you. The panda is a creature of the wild. It will take you to the most distant regions of Tibia, always in hopes of a little bamboo to nibble on or to check on a possible mate."}, + [361] = {name = "Dragon Mimicry", grade = 1, points = 2, description = "It's not really a dragon, but rather a kind of chimera. Nonetheless a decent mount to impress any passer-by."}, + [362] = {name = "Fabled Construction", grade = 1, points = 3, description = "Finding all the pieces to this complicated vehicle was one kind of a challenge. However, what you built in the end is rather a fabled than a feeble construction."}, + [363] = {name = "Fata Morgana", grade = 1, points = 2, description = "There are many delusions and phantasms in the desert. You saw a false oasis with fruit-bearing palm trees. Instead of water and refreshment, however, you found a dromedary in the end. What a useful Fata Morgana!"}, + [364] = {name = "Fried Shrimp", grade = 1, points = 2, description = "This must be underwater love - this enormous crustacean now does thy bidding. Or maybe it's just in it for a little more of that shrimp barbecue, as that's a little hard to come by in the sea."}, + [365] = {name = "Friend of Elves", grade = 1, points = 1, description = "Kingly deer mostly prefer elves as friends and familiars. This one, however, decided to favour you as a confidant and rider. Well done!"}, + [366] = {name = "Gear Up", grade = 1, points = 3, description = "Installing that control unit was a no-brainer. Now you're in control to make it walk this way or that, or to change tack at any moment if required. Your faithful walker mount obeys your every command."}, + [367] = {name = "Golden Sands", grade = 1, points = 3, description = "Counting ten thousand grains of sand could not have been harder than gaining this impressive mount."}, + [368] = {name = "Hoard of the Dragon", grade = 1, points = 1, secret = true, description = "Your adventurous way through countless dragon lairs earned you a pretty treasure - and surely the enmity of many a dragon."}, + [369] = {name = "Icy Glare", grade = 1, points = 1, description = "Here's looking at you, kid. This ancient creature seems to size you up with its brilliant eyes and barely tolerates you riding it. Maybe it thinks you're the defrosted snack, after all?"}, + [370] = {name = "Knock on Wood", grade = 1, points = 3, description = "It's a wound-up wooden lizard! Well, stranger things have happened, or so you're told. Just hop on and let this wood-and-tin contraption take you anywhere you want to wind down a bit. And hope you don't get hit by lightning underway."}, + [371] = {name = "Lion King", grade = 1, points = 1, description = "By mastering the secrets of Lion's Rock, you proved yourself worthy to face the mighty lions there. One of them even chose to accompany you."}, + [372] = {name = "Little Ball of Wool", grade = 1, points = 1, description = "You found a lost sheep and thus a steady source of black wool. But careful: don't get entangled."}, + [373] = {name = "Lost Palace Raider", grade = 1, points = 2, secret = true, description = "Lifting the secrets of a fabulous palace and defeating a beautiful demon princess was a thrilling experience indeed. This site's marvels nearly matched its terrors. Nearly."}, + [374] = {name = "Lovely Dots", grade = 1, points = 3, description = "Finding a four-leaved clover is always a sign of luck. And as luck would have it, you even baited a lovely dotted ladybug. Lucky you!"}, + [375] = {name = "Loyal Lad", grade = 1, points = 1, description = "Having a loyal friend alongside is comforting to every adventurer. If only this lad was not so stubborn..."}, + [376] = {name = "Lucky Horseshoe", grade = 1, points = 1, description = "'Sweets for my steed' could be your motto. An impressive horse is eating out of your hand. Saddle up and be ready to find adventure, new friends, and maybe someone to shoe your horse now and then."}, + [377] = {name = "Luminous Kitty", grade = 1, points = 3, description = "You made some efforts to bring a little more light into the world. And what a nice present you got in return!"}, + [378] = {name = "Magnetised", grade = 1, points = 2, description = "This magnetic beast attracted you in a very literal way. Or was it attracted by your metal equipment? Anyway, you seem to be stuck together now."}, + [379] = {name = "Mind the Dog!", grade = 1, points = 2, description = "Barking dogs never bite, as the saying goes. But this one clearly tried. In the end, however, you were able to walk the dog - ahem, gnarlhound."}, + [380] = {name = "Out of the Stone Age", grade = 1, points = 3, description = "What a blast from the past! This thankful patient thinks you missed your dentist vocation. It's now ready to take a bite of the future and to carry you to your next adventure, or your next patient."}, + [381] = {name = "Pecking Order", grade = 1, points = 1, description = "Ah, the old carrot-on-a-stick trick. Well done! You've made the racing bird accept you as a rider and provider. Just don't feed it your fingers."}, + [382] = {name = "Personal Nightmare", grade = 1, points = 3, description = "It might come as a shock to you, but this is the mount of your dreams. Not exactly the white steed of Prince Charming, but maybe the ladies will still scream and faint at the sight of you."}, + [383] = {name = "Pig-Headed", grade = 1, points = 2, description = "Whoa, sow long! This boar is like a force of nature, breaking through the undergrowth of all the Tibian forests and all records of speed. Hang on!"}, + [384] = {name = "Scales and Tail", grade = 1, points = 2, description = "The Muggy Plains are a dangerous place, often raided by dragons. But that was your luck: thus you found this scaly little guy."}, + [385] = {name = "Slugging Around", grade = 1, points = 2, description = "Drugging a snail can have some beneficial side effects. You're now the proud owner of a snarling, speed-crazy slug. Maybe it'll purr if you stroke it. Anyway, life should be one slick ride from now on."}, + [386] = {name = "Spin-Off", grade = 1, points = 1, description = "Seems like this spider has got a sweet tooth. As a result, eight hairy legs are now at your disposal to crawl and weave at your whim, and strike fear into the hearts of men."}, + [387] = {name = "Starless Night", grade = 1, points = 3, description = "By many it is considered a myth like the Yeti. But you came, saw and tamed it. Now you're the proud rider of a midnight panther, black as a starless night."}, + [388] = {name = "Stuntman", grade = 1, points = 3, description = "A drop of oil and you're good to go. This unique mount will roll merrily in and out of any strange place you want to visit. If you see no exit, you probably ended up in a circus ring. Ah well, the show must go on!"}, + [389] = {name = "Swamp Beast", grade = 1, points = 1, description = "By cleverly using a leech to cool that raging bull's blood, you managed not to get swamped or trampled in a water buffalo stampede. The creature is now docile and follows your every command."}, + [390] = {name = "The Right Tone", grade = 1, points = 1, description = "By setting the right tone you convinced a crystal wolf to accompany you. Remember it is made of crystal, though, so be careful in a banshee's presence."}, + [391] = {name = "Thick-Skinned", grade = 1, points = 2, description = "It's unstoppable! Walls? Fortresses? Obstacles? Objections? Pah! Nothing will stand before the stampor. Arrows and spears bounce off its hide, enemies are trampled by the dozen. Just don't go for the subtle approach or a date on this thing."}, + [392] = {name = "Way to Hell", grade = 1, points = 2, description = "This fiery beast really tried to give you hell. But not even a magma crawler can resist a mug of spicy, hot glow wine. Skol!"}, + + --10.9 + [393] = {name = "Hat Hunter", grade = 2, points = 5, description = "You sucessfully fought against all odds to protect your world from an ascending god! – You weren't there for the hat only after all?"}, + [394] = {name = "Ogre Chef", grade = 1, points = 1, description = "You didn't manage to become an ogre chief. But at least you are, beyond doubt, a worthy ogre chef."}, + [395] = {name = "Rift Warrior", grade = 1, points = 3, description = "You went through hell. Seven times. You defeated the demons. Countless times. You put an end to Ferumbras claims to ascendancy. Once and for all."}, + [396] = {name = "The Call of the Wild", grade = 1, points = 2, description = "You opposed man-eating ogres and clumsy clomps. You grappled with hungry chieftains, desperate goblins and angry spirits. So you truly overcame the wild vastness of Krailos."}, + + --10.94 + [397] = {name = "Ender of the End", grade = 2, points = 5, description = "You have entered the heart of destruction and valiantly defeated the world devourer. By your actions you have postponed the end of the world — at least for a while."}, + [398] = {name = "Vortex Tamer", grade = 2, points = 5, description = "After a long journey and dedication you were favoured by fortune and have tamed all three elusive beasts of the vortex. Unless the Vortexion decides you're a tasty morsel you can enjoy your small stable of ravaging beasts from beyond."}, + + --11.02 + [399] = {name = "Forbidden Fruit", grade = 1, points = 1, secret = true, description = "You could not resist the taste of the forbidden fruit. Since you don't feel changed at all, it couldn't have been that bad after all. Or could it?"}, + [400] = {name = "Forbidden Knowledge", grade = 1, points = 1, secret = true, description = "Perhaps with so much acquired knowledge, never meant for you, you know even when to stop! Time will tell whether this knowledge will do more harm or good."}, + [401] = {name = "Rhino Rider", grade = 1, points = 1, description = "Don't forget, even your rhino sometimes needs a hug. A careful one in this case."}, + + --11.03 + [402] = {name = "Treasure Hunter", grade = 1, points = 3, description = "You wandered the world of Tibia in search of the ancient dragons' hoards. You are sure, you found them all."}, + + --11.40 + [403] = {name = "Corruption Contained", grade = 2, points = 5, description = "You have managed to stall the worst incursion of corruption. Still this is just one battle won in an all out war for your world."}, + [404] = {name = "Fairy Teasing", grade = 1, points = 1, secret = true, description = "Teasing fairies is fun. They leave behind such pretty clouds of glittering dust when chased. Just hope they don't get you back for it."}, + [405] = {name = "Toothfairy Assistant", grade = 1, points = 1, description = "You assisted a very prominent fae and you fought tooth and nail to earn this title."}, + + --11.50 + [406] = {name = "Buried the Baron", grade = 1, points = 1, description = "You defeated the Baron from Below and destroyed his lava pump!"}, + [407] = {name = "Contender", grade = 1, points = 3, description = "You have fully unlocked 10 medium monsters in the cyclopedia."}, + [408] = {name = "Death in the Depths", grade = 1, points = 2, description = "The Baron from Below, Duke of the Depths and the Count of the Core are no more!"}, + [409] = {name = "Duked It Out", grade = 1, points = 1, description = "You defeated the Duke of the Depths and destroyed his lava pump!"}, + [410] = {name = "His Days are Counted", grade = 1, points = 1, description = "You defeated the Count of the Core and destroyed his lava pump!"}, + [411] = {name = "Hunting Permit", grade = 1, points = 1, description = "You have fully unlocked your very first monster in the cyclopedia."}, + [412] = {name = "Little Adventure", grade = 1, points = 1, description = "You have fully unlocked 10 easy monsters in the cyclopedia."}, + [413] = {name = "Little Big Adventure", grade = 1, points = 2, secret = true, description = "You have fully unlocked 100 easy monsters in the cyclopedia."}, + [414] = {name = "Master Hunter", grade = 2, points = 6, secret = true, description = "You have fully unlocked 100 hard monsters in the cyclopedia."}, + [415] = {name = "Over the Moon", grade = 2, points = 5, description = "The Curse of the Full Moon transforms harmless citizens into feral beasts. But with your help, Edron and Cormaya are safe - fairly."}, + [416] = {name = "Scourge of Scarabs", grade = 1, points = 3, description = "You took the heat and defeated the Ancient Spawn of Morgathla!"}, + [417] = {name = "Serious Contender", grade = 2, points = 4, secret = true, description = "You have fully unlocked 100 medium monsters in the cyclopedia."}, + [418] = {name = "Skilled Hunter", grade = 2, points = 5, description = "You have fully unlocked 10 hard monsters in the cyclopedia."}, + + --11.80 + [419] = {name = "All Hail the King", grade = 1, points = 1, description = "Old temples, a meadowy countryside and the splendour of Thais - you really know every corner of King Tibianus' realm now."}, + [420] = {name = "Ancient Splendor", grade = 1, points = 1, description = "You've braved the perils of Yalahar and learned of its gloomy shadows of long gone greatness."}, + [421] = {name = "Battle Mage", grade = 2, points = 6, description = "Wielding dangerous knowledge as well as the sword is your expertise. You have proven yourself versatile in all manner of situations."}, + [422] = {name = "Bibliomaniac", grade = 1, points = 3, description = "You passion for reading was somewhat diminished by biting books and aggressive quills. But this flying specimen proved to be a loyal companion. Never judge a book by its cover!"}, + [423] = {name = "Daraman's Footsteps", grade = 1, points = 1, description = "You journeyed through Darashia and the sea of sand around it, while fighting the perils of the desert."}, + [424] = {name = "Dwarven Mines", grade = 1, points = 1, description = "Vast mines, an orc fortress and the magnificence of Kazordoon - you really know every corner of North-Eastern Mainland now."}, + [425] = {name = "Elven Woods", grade = 1, points = 1, description = "Tall trees, deep forests and and the beauty of Ab'Dendriel - you really know every corner of the elven lands now."}, + [426] = {name = "Glooth Punk", grade = 1, points = 1, description = "Glooth is the substance that powers a whole continent and all its weird inhabitants, workshops and factories. You travelled this strange smorgasbord of curiosities in its entirety - just in time for tea."}, + [427] = {name = "High and Dry", grade = 1, points = 2, description = "You asked Captain Charles to take a shortcut quite a few times. Now you are all too familiar with desert islands all over Tibia."}, + [428] = {name = "Jewel in the Swamp", grade = 1, points = 1, description = "Damp swamps, a dry desert and the opulence of Venore - you really know every corner of Eastern Mainland now."}, + [429] = {name = "King of the Jungle", grade = 1, points = 1, description = "You have searched Port Hope and the jungle that thoroughly, that you are up to adoption by a friendly ape family."}, + [430] = {name = "Liberty Bay Watch", grade = 1, points = 1, description = "A pirate's haven and a burglar's hideout. You found your way around Liberty Bay and its surroundings - land, ho!"}, + [431] = {name = "Library Liberator", grade = 1, points = 3, description = "Though you couldn't prevent the theft of the godbreaker knowledge, you still managed to fight of the invasion of the library and to kill the scourge of oblivion, a powerful servant of the enemy."}, + [432] = {name = "Lizard Kingdom", grade = 1, points = 1, description = "From the southern steppe through the Dragonblaze Mountains and the Muggy Plains to the forbidden city of Razzachai - you really know every corner of Zao now."}, + [433] = {name = "Long Live the Queen", grade = 1, points = 1, description = "Ancient battlefields, amazons and the glory of Carlin - you really know every corner of Queen Eloise's realm now."}, + [434] = {name = "Master Debater", grade = 1, points = 1, secret = true, description = "You truly are the grand master of verbal debate! Now going forth and putting this wisdom to good use in everyday life... is probably debatable."}, + [435] = {name = "Millennial Falcon", grade = 1, points = 3, secret = true, description = "You defeated Grand Master Oberon and the remnants of the Order of the Falcon, no matter the odds."}, + [436] = {name = "Mummy's Dearest", grade = 1, points = 1, description = "You have combed the desert and searched the pyramid city of Ankrahmun."}, + [437] = {name = "Race to the Pole", grade = 1, points = 1, description = "You have expelled the fog of the unknown from the islands of Svargrond. Maybe not as first, but that's not what matters in the end."}, + [438] = {name = "Realms of Dreams", grade = 1, points = 1, description = "Lush meadows, colourful fairies and sentient stones - you really know every corner of Feyrist now."}, + [439] = {name = "Spectulation", grade = 1, points = 1, secret = true, description = "You checked out a strange temple deep in the jungles of Tiquanda. Spectulus was right, it was indeed overrun by strange fish-men you now call Deathlings."}, + [440] = {name = "Stronghold of Edron", grade = 1, points = 1, description = "Strong fortresses, sprawling woods and ivory towers - you really know every corner of Edron now."}, + [441] = {name = "The Ogre Steppe", grade = 1, points = 1, description = "A vast steppe, voracious ogres and dried out salt seas - you really know every corner of Krailos now."}, + [442] = {name = "Trip to the Beach", grade = 1, points = 1, description = "Braving a hive full of unimaginable proportions and its grotesque creatures on the surface is only one side of Gray Beach. Your full trip of the island also included a dive into the black nothingness of the deep sea, facing the wrath of the Njey."}, + [443] = {name = "Twisted Dreams", grade = 1, points = 1, description = "A journey through a dreamscape of evil is no small feat. Yet you traversed the nightmarish lands of Roshamuul and live to tell the tale. Don't fall asleep now..."}, + [444] = {name = "Widely Travelled", grade = 3, points = 7, description = "As a true globetrotter you can now show your colours proudly with this extraordinary outfit."}, + + --11.86 + [445] = {name = "Exalted Battle Mage", grade = 1, points = 2, description = "Not only did you master the battlefield as a mage, you were also induced to the most inner secrets of the art of magical warfare and prevailed."}, + [446] = {name = "Running the Rift", grade = 1, points = 3, description = "You don't just have a permission to ride a rift runner, you literally went through hell and earned it!"}, + + --12.00 + [447] = {name = "Champion of Summer", grade = 1, points = 2, secret = true, description = "You have vanquished numerous arena champions in the name of the Summer Court."}, + [448] = {name = "Champion of Winter", grade = 1, points = 2, secret = true, description = "You have vanquished numerous arena champions in the name of the Winter Court."}, + [449] = {name = "Dream Catcher", grade = 1, points = 3, description = "You are the slayer of the ancient nightmare beast and prevented the nightmare to spread its madness."}, + [450] = {name = "Dream Warrior", grade = 2, points = 6, description = "You became an acquaintance of the courts of dreams and acquired the right to display your new status and title of 'dream warrior'."}, + [451] = {name = "Keeper of the 7 Keys", grade = 1, points = 2, description = "You found the Seven Keys to unlock ... no, not the seven seas. But at least seven doors in the realm of dreams."}, + [452] = {name = "Lacewing Catcher", grade = 1, points = 3, description = "You caught a lacewing moth with your lantern. It will follow you in companionship as the bearer of the lantern will be its guide through the darkness now."}, + [453] = {name = "Moth Whisperer", grade = 1, points = 3, description = "Your lantern was too bewitching for a hibernal moth. It couldn't withstand and follows you, the bearer of the lantern, now."}, + [454] = {name = "Tied the Knot", grade = 1, points = 1, secret = true, description = "You figured out the right order of spells in the buried cathedral, how enchanting!"}, + + --12.02 + [455] = {name = "No Horse Open Sleigh", grade = 1, points = 3, description = "This sleigh is not driven by magic but pushed by a percht. Hopefully you two get along well together...!"}, + [456] = {name = "Raider in the Dark", grade = 2, points = 6, description = "But can you truly be one of them?"}, + + --12.20 + [457] = {name = "A Study in Scarlett", grade = 1, points = 3, secret = true, description = "You ended the regn of Scarlett Etzel. All-seeing yet blind, ever powerful yet ultimately helpless, she never got a second chance to truly see. Or has she..."}, + [458] = {name = "Avid Spectral Reader", grade = 1, points = 1, secret = true, description = "What draws things to other dimensions, one wonders. You read the almanac at just the right spot to end up... where, of all places? That is the problem with dimensional travel: you will never know. Or you have always known. And everything in between."}, + [459] = {name = "Gryphon Rider", grade = 1, points = 3, description = "Unmasking spies, killing demons, discovering omens, solving puzzles and fighting ogres, manticores and feral sphinxes. - Nobody said it was easy to become a gryphon rider."}, + [460] = {name = "Hippofoddermus", grade = 1, points = 1, secret = true, description = "You did the hippo population of Kilmaresh a great favour. A well-fed hippo is a happy hippo."}, + [461] = {name = "Inquisition's Hand", grade = 1, points = 3, secret = true, description = "You defeated the Lich Knights and became the hand of the Inquisition, allowed to wear their special garb."}, + [462] = {name = "Sculptor Apprentice", grade = 1, points = 2, secret = true, description = "Granted, you didn't carve those lifelike animal figurines yourself. But helping a medusa to find proper objects and even watching her using her petrifying gaze is almost as rewarding."}, + [463] = {name = "Sun and Sea", grade = 2, points = 5, description = "You made sure that the balance of sun and sea is preserved in Kilmaresh. The Golden City of Issavi won't forget your favour."}, + [464] = {name = "The Empire's Glory", grade = 1, points = 1, description = "Mythical creatures, forgotten catacombs and the Golden City - you really know every corner of Kilmaresh now."}, + + --12.20.9066 + [465] = {name = "Do a Barrel Roll!", grade = 1, points = 3, description = "Riding a traditional beer barrel from the Orcsoberfest is a once-in-a-lifetime experience. Beer sold separately."}, + [466] = {name = "Orcsoberfest Welcome", grade = 1, points = 3, secret = true, description = "The Orcsoberfest is not only known for its traditional food, beer and customs but also fun events and excitement! You took part in all of that and can now truly say: \"I survived!\""}, + [467] = {name = "Traditionalist", grade = 2, points = 0, description = "You proudly wear the traditional Orcsoberfest garb, same as it ever was and as it always will be."}, + + --12.30 + [468] = {name = "Beyonder", grade = 1, points = 3, description = "Adventurous beyond death, you travelled the Netherworld. Although you had just the ghost of a chance you survived and even came back from the realm of the dead."}, + [469] = {name = "Falconer", grade = 1, points = 3, description = "A true beastmaster learns the language of his animal companions. Now you as well can bolster your unique bond with nature and help preserve the balance of life as a proud falconer."}, + [470] = {name = "Mainstreet Nightmare", grade = 1, points = 2, description = "Now you are able to wander around Tibia wearing an angst-inducing vestment."}, + [471] = {name = "Monsterhunter", grade = 1, points = 2, description = "Fear me, monsters! There is some more slaying to come!"}, + [472] = {name = "Nothing but Hot Air", grade = 1, points = 2, description = "You have tamed the ghostly mists to do your bidding. For now ..."}, + [473] = {name = "Prospectre", grade = 1, points = 1, secret = true, description = "You made acquaintance with the Thaian. A strange contemporary with a dark history. No man but a derivate of green and obsession."}, + [474] = {name = "Steppe Elegance", grade = 1, points = 2, description = "Champion of the wildlands, a swift strider among the creatures of the wild. The elegant nature of the gallop, this envoy of speed has mastered, indicates the precise understanding of its terrain and environment."}, + [475] = {name = "Taskmaster", grade = 1, points = 2, description = "Having hunted and bested them all, you live for the thrill of the hunt!"}, + [476] = {name = "Verminbane", grade = 1, points = 2, description = "And so it begins!"}, + + --Custom + [477] = {name = "Waypoint Explorer", grade = 1, points = 1, description = "You've explored all the towns of Tibia and discovered each town's waypoint."}, + [478] = {name = "Up the Molehill", grade = 1, points = 3, description = "Putting this candle stump on your new mount was kind of a waiting game. You're even tempted to call it whack-a-mole. But in the end you found a loyal companion for your journeys into the depths."} +} + +ACHIEVEMENT_FIRST = 1 +ACHIEVEMENT_LAST = #achievements + +function getAchievementInfoById(id) + for k, v in pairs(achievements) do + if k == id then + local t = {} + t.id = k + t.actionStorage = ACHIEVEMENTS_ACTION_BASE + k + for inf, it in pairs(v) do + t[inf] = it + end + return t + end + end + return false +end + +function getAchievementInfoByName(name) + for k, v in pairs(achievements) do + if v.name:lower() == name:lower() then + local t = {} + t.id = k + t.actionStorage = ACHIEVEMENTS_ACTION_BASE + k + for inf, it in pairs(v) do + t[inf] = it + end + return t + end + end + return false +end + +function getSecretAchievements() + local t = {} + for k, v in pairs(achievements) do + if v.secret then + t[#t + 1] = k + end + end + return t +end + +function getPublicAchievements() + local t = {} + for k, v in pairs(achivements) do + if not v.secret then + t[#t + 1] = k + end + end + return t +end + +function getAchievements() + return achievements +end + +function isAchievementSecret(ach) + local achievement + if isNumber(ach) then + achievement = getAchievementInfoById(ach) + else + achievement = getAchievementInfoByName(ach) + end + if not achievement then + return Spdlog.error(string.format("[isAchievementSecret] - Invalid achievement '%s'", + ach)) and false + end + + return achievement.secret +end + +function Player.hasAchievement(self, ach) + local achievement + if isNumber(ach) then + achievement = getAchievementInfoById(ach) + else + achievement = getAchievementInfoByName(ach) + end + if not achievement then + return Spdlog.error("[Player.hasAchievement] - Invalid achievement \"" .. ach .. "\".") and false + end + + return self:getStorageValue(ACHIEVEMENTS_BASE + achievement.id) > 0 +end + +function Player.getAchievements(self) + local t = {} + for k = 1, #achievements do + if self:hasAchievement(k) then + t[#t + 1] = k + end + end + return t +end + +function Player.addAchievement(self, ach, denyMsg) + local achievement + if isNumber(ach) then + achievement = getAchievementInfoById(ach) + else + achievement = getAchievementInfoByName(ach) + end + if not achievement then + return Spdlog.error("[Player.addAchievement] - Invalid achievement \"" .. ach .. "\".") and false + end + + if not self:hasAchievement(achievement.id) then + self:setStorageValue(ACHIEVEMENTS_BASE + achievement.id, 1) + if not denyMsg then + self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Congratulations! You earned the achievement \"" .. achievement.name .. "\".") + end + end + return true +end + +function Player.removeAchievement(self, ach) + local achievement + if isNumber(ach) then + achievement = getAchievementInfoById(ach) + else + achievement = getAchievementInfoByName(ach) + end + if not achievement then + return Spdlog.error("[Player.removeAchievement] - Invalid achievement \"" .. ach .. "\".") and false + end + + if self:hasAchievement(achievement.id) then + self:setStorageValue(ACHIEVEMENTS_BASE + achievement.id, -1) + end + return true +end + +function Player.addAllAchievements(self, denyMsg) + for i = ACHIEVEMENT_FIRST, ACHIEVEMENT_LAST do + self:addAchievement(i, denyMsg) + end + return true +end + +function Player.removeAllAchievements(self) + for k = 1, #achievements do + if self:hasAchievement(k) then + self:removeAchievement(k) + end + end + return true +end + +function Player.getSecretAchievements(self) + local t = {} + for k, v in pairs(achievements) do + if self:hasAchievement(k) and v.secret then + t[#t + 1] = k + end + end + return t +end + +function Player.getPublicAchievements(self) + local t = {} + for k, v in pairs(achievements) do + if self:hasAchievement(k) and not v.secret then + t[#t + 1] = k + end + end + return t +end + +function Player.getAchievementPoints(self) + local points = 0 + local list = self:getAchievements() + if #list > 0 then --has achievements + for i = 1, #list do + local a = getAchievementInfoById(list[i]) + if a.points > 0 then --avoid achievements with unknow points + points = points + a.points + end + end + end + return points +end + +function Player.addAchievementProgress(self, ach, value) + local achievement = isNumber(ach) and getAchievementInfoById(ach) or getAchievementInfoByName(ach) + if not achievement then + Spdlog.error('[Player.addAchievementProgress] - Invalid achievement "' .. ach .. '".') + return true + end + + local storage = ACHIEVEMENTS_ACTION_BASE + achievement.id + local progress = self:getStorageValue(storage) + if progress < value then + self:setStorageValue(storage, math.max(1, progress) + 1) + elseif progress == value then + self:setStorageValue(storage, value + 1) + self:addAchievement(achievement.id) + end + return true +end diff --git a/data/lib/tables/door.lua b/data/lib/tables/door.lua new file mode 100644 index 00000000000..ac80e5ad731 --- /dev/null +++ b/data/lib/tables/door.lua @@ -0,0 +1,282 @@ +-- Be careful, do not add quest door inside the level door table, this will lock the doors. + +-- ID of the keys. +keysID = {2086, 2087, 2088, 2089, 2090, 2091, 2092, 23763} + +-- The lockedDoor is the doors with the description "It is locked". Use this (with no action) to keep a door permanently isoled. +-- The closedDoor is the doors that are unlocked, when using them open normally. +KeyDoorTable = { + { lockedDoor = 1209, closedDoor = 1210, openDoor = 1211 }, + { lockedDoor = 1212, closedDoor = 1213, openDoor = 1214 }, + { lockedDoor = 1231, closedDoor = 1232, openDoor = 1233 }, + { lockedDoor = 1234, closedDoor = 1235, openDoor = 1236 }, + { lockedDoor = 1249, closedDoor = 1250, openDoor = 1251 }, + { lockedDoor = 1252, closedDoor = 1253, openDoor = 1254 }, + { lockedDoor = 3535, closedDoor = 3536, openDoor = 3537 }, + { lockedDoor = 3544, closedDoor = 3545, openDoor = 3546 }, + { lockedDoor = 4916, closedDoor = 4917, openDoor = 4918 }, + { lockedDoor = 4913, closedDoor = 4914, openDoor = 4915 }, + { lockedDoor = 5098, closedDoor = 5099, openDoor = 5100 }, + { lockedDoor = 5107, closedDoor = 5108, openDoor = 5109 }, + { lockedDoor = 5116, closedDoor = 5117, openDoor = 5118 }, + { lockedDoor = 5125, closedDoor = 5126, openDoor = 5127 }, + { lockedDoor = 5134, closedDoor = 5135, openDoor = 5136 }, + { lockedDoor = 5137, closedDoor = 5138, openDoor = 5139 }, + { lockedDoor = 5140, closedDoor = 5141, openDoor = 5142 }, + { lockedDoor = 5143, closedDoor = 5144, openDoor = 5145 }, + { lockedDoor = 5278, closedDoor = 5279, openDoor = 5280 }, + { lockedDoor = 5281, closedDoor = 5282, openDoor = 5283 }, + { lockedDoor = 5732, closedDoor = 5733, openDoor = 5734 }, + { lockedDoor = 5735, closedDoor = 5736, openDoor = 5737 }, + { lockedDoor = 6192, closedDoor = 6193, openDoor = 6194 }, + { lockedDoor = 6195, closedDoor = 6196, openDoor = 6197 }, + { lockedDoor = 6249, closedDoor = 6250, openDoor = 6251 }, + { lockedDoor = 6252, closedDoor = 6253, openDoor = 6254 }, + { lockedDoor = 6799, closedDoor = 6795, openDoor = 6796 }, + { lockedDoor = 6801, closedDoor = 6797, openDoor = 6798 }, + { lockedDoor = 6891, closedDoor = 6892, openDoor = 6893 }, + { lockedDoor = 6900, closedDoor = 6901, openDoor = 6902 }, + { lockedDoor = 7033, closedDoor = 7034, openDoor = 7035 }, + { lockedDoor = 7042, closedDoor = 7043, openDoor = 7044 }, + { lockedDoor = 8541, closedDoor = 8542, openDoor = 8543 }, + { lockedDoor = 8544, closedDoor = 8545, openDoor = 8546 }, + { lockedDoor = 9165, closedDoor = 9166, openDoor = 9167 }, + { lockedDoor = 9168, closedDoor = 9169, openDoor = 9170 }, + { lockedDoor = 9267, closedDoor = 9268, openDoor = 9269 }, + { lockedDoor = 9270, closedDoor = 9271, openDoor = 9272 }, + { lockedDoor = 10268, closedDoor = 10269, openDoor = 10270 }, + { lockedDoor = 10271, closedDoor = 10272, openDoor = 10273 }, + { lockedDoor = 10468, closedDoor = 10469, openDoor = 10470 }, + { lockedDoor = 10477, closedDoor = 10478, openDoor = 10479 }, + { lockedDoor = 10775, closedDoor = 10776, openDoor = 10777 }, + { lockedDoor = 10784, closedDoor = 10785, openDoor = 10786 }, + { lockedDoor = 12092, closedDoor = 12093, openDoor = 12094 }, + { lockedDoor = 12099, closedDoor = 12100, openDoor = 12101 }, + { lockedDoor = 12188, closedDoor = 12189, openDoor = 12190 }, + { lockedDoor = 12197, closedDoor = 12198, openDoor = 12199 }, + { lockedDoor = 14633, closedDoor = 14634, openDoor = 14635 }, + { lockedDoor = 19840, closedDoor = 19841, openDoor = 19842 }, + { lockedDoor = 19849, closedDoor = 19850, openDoor = 19851 }, + { lockedDoor = 19980, closedDoor = 19981, openDoor = 19982 }, + { lockedDoor = 19989, closedDoor = 19990, openDoor = 19991 }, + { lockedDoor = 20273, closedDoor = 20274, openDoor = 20275 }, + { lockedDoor = 20282, closedDoor = 20283, openDoor = 20284 }, + { lockedDoor = 22815, closedDoor = 22814, openDoor = 22816 }, + { lockedDoor = 22824, closedDoor = 22823, openDoor = 22825 }, + { lockedDoor = 26541, closedDoor = 26542, openDoor = 26545 }, + { lockedDoor = 26543, closedDoor = 26544, openDoor = 26546 }, + { lockedDoor = 33117, closedDoor = 33118, openDoor = 32582 }, + { lockedDoor = 33119, closedDoor = 33120, openDoor = 32583 }, + { lockedDoor = 35607, closedDoor = 35608, openDoor = 35611 }, + { lockedDoor = 35609, closedDoor = 35610, openDoor = 35612 } +} + +-- These are the common doors, the ones that just open and close without any special requirements. +CustomDoorTable = { + { closedDoor = 1219, openDoor = 1220 }, + { closedDoor = 1221, openDoor = 1222 }, + { closedDoor = 1237, openDoor = 1238 }, + { closedDoor = 1239, openDoor = 1240 }, + { closedDoor = 3538, openDoor = 3539 }, + { closedDoor = 3547, openDoor = 3548 }, + { closedDoor = 1539, openDoor = 1540 }, + { closedDoor = 1541, openDoor = 1542 }, + { closedDoor = 5082, openDoor = 5083 }, + { closedDoor = 5084, openDoor = 5085 }, + { closedDoor = 5101, openDoor = 5102 }, + { closedDoor = 5110, openDoor = 5111 }, + { closedDoor = 5119, openDoor = 5120 }, + { closedDoor = 5128, openDoor = 5129 }, + { closedDoor = 5284, openDoor = 5285 }, + { closedDoor = 5286, openDoor = 5287 }, + { closedDoor = 5515, openDoor = 5516 }, + { closedDoor = 5517, openDoor = 5518 }, + { closedDoor = 6198, openDoor = 6199 }, + { closedDoor = 6200, openDoor = 6201 }, + { closedDoor = 6255, openDoor = 6256 }, + { closedDoor = 6257, openDoor = 6258 }, + { closedDoor = 6894, openDoor = 6895 }, + { closedDoor = 6903, openDoor = 6904 }, + { closedDoor = 7036, openDoor = 7037 }, + { closedDoor = 7045, openDoor = 7046 }, + { closedDoor = 7054, openDoor = 7055 }, + { closedDoor = 7056, openDoor = 7057 }, + { closedDoor = 8547, openDoor = 8548 }, + { closedDoor = 8549, openDoor = 8550 }, + { closedDoor = 9171, openDoor = 9172 }, + { closedDoor = 9173, openDoor = 9174 }, + { closedDoor = 9273, openDoor = 9274 }, + { closedDoor = 9275, openDoor = 9276 }, + { closedDoor = 10274, openDoor = 10275 }, + { closedDoor = 10276, openDoor = 10277 }, + { closedDoor = 10471, openDoor = 10472 }, + { closedDoor = 10480, openDoor = 10481 }, + { closedDoor = 12692, openDoor = 12695 }, + { closedDoor = 12701, openDoor = 12703 }, + { closedDoor = 13236, openDoor = 13237 }, + { closedDoor = 18208, openDoor = 18209 }, + { closedDoor = 19843, openDoor = 19844 }, + { closedDoor = 19852, openDoor = 19853 }, + { closedDoor = 19983, openDoor = 19984 }, + { closedDoor = 19992, openDoor = 19993 }, + { closedDoor = 20276, openDoor = 20277 }, + { closedDoor = 20285, openDoor = 20286 }, + { closedDoor = 20305, openDoor = 20306 }, + { closedDoor = 22817, openDoor = 22818 }, + { closedDoor = 22826, openDoor = 22827 }, + { closedDoor = 27209, openDoor = 27210 }, + { closedDoor = 27211, openDoor = 27212 }, + { closedDoor = 27571, openDoor = 33296 }, + { closedDoor = 35007, openDoor = 35016 }, + { closedDoor = 35008, openDoor = 35017 }, + --[[ do not have the open door id, if activate this, have a conflict of id (is only a locked door?) + { closedDoor = 34687, openDoor = 34673 }, + { closedDoor = 34688, openDoor = 34674 }, + { closedDoor = 34689, openDoor = 34677 }, + { closedDoor = 34690, openDoor = 34678 }, + ]] + { closedDoor = 35668, openDoor = 35672 }, + { closedDoor = 35669, openDoor = 35672 }, + { closedDoor = 35670, openDoor = 35673 }, + { closedDoor = 35671, openDoor = 35673 }, + { closedDoor = 35684, openDoor = 35688 }, + { closedDoor = 35685, openDoor = 35689 }, + { closedDoor = 35686, openDoor = 35690 }, + { closedDoor = 35687, openDoor = 35691 }, + { closedDoor = 36329, openDoor = 36331 }, + { closedDoor = 36330, openDoor = 36332 }, + { closedDoor = 36498, openDoor = 36499 }, + { closedDoor = 36500, openDoor = 36501 }, + { closedDoor = 38106, openDoor = 38107 }, + { closedDoor = 38108, openDoor = 38109 }, + --{ closedDoor = 38170}, -- it's probably door of a quest + --{ closedDoor = 38171}, -- it's probably door of a quest + --{ closedDoor = 38467}, -- it's probably door of a quest + --{ closedDoor = 38469}, -- it's probably door of a quest + { closedDoor = 38468, openDoor = 38471 }, + { closedDoor = 38470, openDoor = 38472 }, + { closedDoor = 39056, openDoor = 39057 }, + { closedDoor = 39058, openDoor = 39059 }, +} + +-- These are the doors for missions, they need access from some mission (storage) to be able to enter. Put the storage value in the action id of the door and it will open only to the player who has the storage value. +QuestDoorTable = { + { closedDoor = 1223, openDoor = 1224 }, + { closedDoor = 1225, openDoor = 1226 }, + { closedDoor = 1241, openDoor = 1242 }, + { closedDoor = 1243, openDoor = 1244 }, + { closedDoor = 1255, openDoor = 1256 }, + { closedDoor = 1257, openDoor = 1258 }, + { closedDoor = 3542, openDoor = 3543 }, + { closedDoor = 3551, openDoor = 3552 }, + { closedDoor = 5105, openDoor = 5106 }, + { closedDoor = 5114, openDoor = 5115 }, + { closedDoor = 5123, openDoor = 5124 }, + { closedDoor = 5132, openDoor = 5133 }, + { closedDoor = 5288, openDoor = 5289 }, + { closedDoor = 5290, openDoor = 5291 }, + { closedDoor = 5748, openDoor = 5749 }, + { closedDoor = 6202, openDoor = 6203 }, + { closedDoor = 6204, openDoor = 6205 }, + { closedDoor = 6259, openDoor = 6260 }, + { closedDoor = 6261, openDoor = 6262 }, + { closedDoor = 6898, openDoor = 6899 }, + { closedDoor = 6907, openDoor = 6908 }, + { closedDoor = 7040, openDoor = 7041 }, + { closedDoor = 7049, openDoor = 7050 }, + { closedDoor = 8551, openDoor = 8552 }, + { closedDoor = 8553, openDoor = 8554 }, + { closedDoor = 9175, openDoor = 9176 }, + { closedDoor = 9177, openDoor = 9178 }, + { closedDoor = 9277, openDoor = 9278 }, + { closedDoor = 9279, openDoor = 9280 }, + { closedDoor = 10278, openDoor = 10279 }, + { closedDoor = 10280, openDoor = 10281 }, + { closedDoor = 10475, openDoor = 10476 }, + { closedDoor = 10484, openDoor = 10485 }, + { closedDoor = 10782, openDoor = 10783 }, + { closedDoor = 10791, openDoor = 10792 }, + { closedDoor = 12104, openDoor = 12105 }, + { closedDoor = 12195, openDoor = 12196 }, + { closedDoor = 12204, openDoor = 12205 }, + { closedDoor = 13022, openDoor = 13023 }, + { closedDoor = 19847, openDoor = 19848 }, + { closedDoor = 19856, openDoor = 19857 }, + { closedDoor = 19987, openDoor = 19988 }, + { closedDoor = 19996, openDoor = 19997 }, + { closedDoor = 20280, openDoor = 20281 }, + { closedDoor = 20289, openDoor = 20290 }, + { closedDoor = 22821, openDoor = 22822 }, + { closedDoor = 22830, openDoor = 22831 }, + { closedDoor = 25162, openDoor = 25163 }, + { closedDoor = 25164, openDoor = 25165 }, + { closedDoor = 34679, openDoor = 34680 }, + { closedDoor = 34681, openDoor = 34682 }, + { closedDoor = 34683, openDoor = 34684 }, + { closedDoor = 34685, openDoor = 34686 }, + { closedDoor = 36403, openDoor = 36404 }, + { closedDoor = 36405, openDoor = 36406 }, +} + +-- Level doors. +-- It's simple, just add a 1 followed by the amount of levels the player needs to be able to pass. +-- For example: +-- Level 10 put the action id: 1010 on the door. +-- Level 100 put the action id: 1100 on the door. And so on. +LevelDoorTable = { + { closedDoor = 1227, openDoor = 1228 }, + { closedDoor = 1229, openDoor = 1230 }, + { closedDoor = 1245, openDoor = 1246 }, + { closedDoor = 1247, openDoor = 1248 }, + { closedDoor = 1259, openDoor = 1260 }, + { closedDoor = 1261, openDoor = 1262 }, + { closedDoor = 3540, openDoor = 3541 }, + { closedDoor = 3549, openDoor = 3550 }, + { closedDoor = 5103, openDoor = 5104 }, + { closedDoor = 5112, openDoor = 5113 }, + { closedDoor = 5121, openDoor = 5122 }, + { closedDoor = 5130, openDoor = 5131 }, + { closedDoor = 5292, openDoor = 5293 }, + { closedDoor = 5294, openDoor = 5295 }, + { closedDoor = 6206, openDoor = 6207 }, + { closedDoor = 6208, openDoor = 6209 }, + { closedDoor = 6263, openDoor = 6264 }, + { closedDoor = 6265, openDoor = 6266 }, + { closedDoor = 6896, openDoor = 6897 }, + { closedDoor = 6905, openDoor = 6906 }, + { closedDoor = 7038, openDoor = 7039 }, + { closedDoor = 7047, openDoor = 7048 }, + { closedDoor = 8555, openDoor = 8556 }, + { closedDoor = 8557, openDoor = 8558 }, + { closedDoor = 9179, openDoor = 9180 }, + { closedDoor = 9181, openDoor = 9182 }, + { closedDoor = 9281, openDoor = 9282 }, + { closedDoor = 9283, openDoor = 9284 }, + { closedDoor = 10282, openDoor = 10283 }, + { closedDoor = 10284, openDoor = 10285 }, + { closedDoor = 10473, openDoor = 10474 }, + { closedDoor = 10482, openDoor = 10483 }, + { closedDoor = 10780, openDoor = 10781 }, + { closedDoor = 10789, openDoor = 10790 }, + { closedDoor = 12095, openDoor = 12096 }, + { closedDoor = 12102, openDoor = 12103 }, + { closedDoor = 12193, openDoor = 12194 }, + { closedDoor = 12202, openDoor = 12203 }, + { closedDoor = 13020, openDoor = 13021 }, + { closedDoor = 17235, openDoor = 17236 }, + { closedDoor = 17237, openDoor = 17238 }, + { closedDoor = 19845, openDoor = 19846 }, + { closedDoor = 19854, openDoor = 19855 }, + { closedDoor = 19985, openDoor = 19986 }, + { closedDoor = 19994, openDoor = 19995 }, + { closedDoor = 20278, openDoor = 20279 }, + { closedDoor = 20287, openDoor = 20288 }, + { closedDoor = 22819, openDoor = 22820 }, + { closedDoor = 22828, openDoor = 22829 }, + { closedDoor = 25158, openDoor = 25159 }, + { closedDoor = 25160, openDoor = 25161 }, + { closedDoor = 34671, openDoor = 34673 }, + { closedDoor = 34672, openDoor = 34674 }, + { closedDoor = 34675, openDoor = 34677 }, + { closedDoor = 34676, openDoor = 34678 }, +} diff --git a/data/lib/tables/hireling_items.lua b/data/lib/tables/hireling_items.lua new file mode 100644 index 00000000000..8ff9237a90e --- /dev/null +++ b/data/lib/tables/hireling_items.lua @@ -0,0 +1,316 @@ +-- TODO: fullfill this table below +HIRELING_GOODS = { + VARIOUS = { + {name = "amphora", id = 2023, buy = 4}, + {name = "armor rack kit", id = 6114, buy = 90}, + {name = "bamboo drawer kit", id = 3921, buy = 20}, + {name = "bamboo table kit", id = 3914, buy = 25}, + {name = "barrel kit", id = 3919, buy = 12}, + {name = "big table kit", id = 3911, buy = 30}, + {name = "birdcage kit", id = 3922, buy = 50}, + {name = "blue bed kit", id = 7907, buy = 80}, + {name = "blue pillow", id = 1686, buy = 25}, + {name = "blue tapestry", id = 1872, buy = 25}, + {name = "bookcase kit", id = 6373, buy = 70}, + {name = "box", id = 1738, buy = 10}, + {name = "canopy bed kit", id = 20252, buy = 200}, + {name = "chest", id = 1740, buy = 10}, + {name = "chest of drawers", id = 3915, buy = 18}, + {name = "chimney kit", id = 8692, buy = 200}, + {name = "coal basin kit", id = 3932, buy = 25}, + {name = "cookie", id = 2687, buy = 2}, + {name = "crate", id = 1739, buy = 10}, + {name = "cuckoo clock", id = 1877, buy = 40}, + {name = "dresser kit", id = 3916, buy = 25}, + {name = "goldfish bowl", id = 5928, buy = 50}, + {name = "exercise axe", id = 32385, buy = 262500, subType = 500}, + {name = "exercise bow", id = 32387, buy = 262500, subType = 500}, + {name = "exercise club", id = 32386, buy = 262500, subType = 500}, + {name = "exercise rod", id = 32388, buy = 262500, subType = 500}, + {name = "exercise sword", id = 32384, buy = 262500, subType = 500}, + {name = "exercise wand", id = 32389, buy = 262500, subType = 500}, + {name = "fireworks rocket", id = 6576, buy = 100}, + {name = "flower bowl", id = 2102, buy = 6}, + {name = "globe", id = 3923, buy = 50}, + {name = "goblin statue kit", id = 3930, buy = 50}, + {name = "god flowers", id = 2100, buy = 5}, + {name = "green balloons", id = 6577, buy = 500}, + {name = "green bed kit", id = 7904, buy = 80}, + {name = "green cushioned chair kit", id = 3902, buy = 40}, + {name = "green pillow", id = 1688, buy = 25}, + {name = "green tapestry", id = 1860, buy = 25}, + {name = "harp kit", id = 3934, buy = 50}, + {name = "heart pillow", id = 1685, buy = 30}, + {name = "honey flower", id = 2103, buy = 5}, + {name = "indoor plant kit", id = 3937, buy = 8}, + {name = "ivory chair kit", id = 3907, buy = 25}, + {name = "knight statue kit", id = 3928, buy = 50}, + {name = "large amphora kit", id = 3931, buy = 50}, + {name = "large trunk", id = 3920, buy = 10}, + {name = "locker kit", id = 3917, buy = 30}, + {name = "minotaur statue kit", id = 3929, buy = 50}, + {name = "orange tapestry", id = 1866, buy = 25}, + {name = "oven kit", id = 6372, buy = 80}, + {name = "party hat", id = 6578, buy = 800}, + {name = "party trumpet", id = 6572, buy = 500}, + {name = "pendulum clock kit", id = 3927, buy = 75}, + {name = "piano kit", id = 3933, buy = 200}, + {name = "potted flower", id = 2104, buy = 5}, + {name = "present", id = 1990, buy = 10}, + {name = "purple tapestry", id = 1857, buy = 25}, + {name = "red balloons", id = 6575, buy = 500}, + {name = "red bed kit", id = 7906, buy = 80}, + {name = "red cushioned chair kit", id = 3901, buy = 40}, + {name = "red pillow", id = 1687, buy = 25}, + {name = "red tapestry", id = 1869, buy = 25}, + {name = "rocking horse", id = 3926, buy = 30}, + {name = "round blue pillow", id = 1690, buy = 25}, + {name = "round purple pillow", id = 1692, buy = 25}, + {name = "round red pillow", id = 1691, buy = 25}, + {name = "round turquoise pillow", id = 1693, buy = 25}, + {name = "small blue pillow", id = 1681, buy = 20}, + {name = "small green pillow", id = 1679, buy = 20}, + {name = "small ice statue", id = 7447, buy = 50}, + {name = "small ice statue", id = 7448, buy = 50}, + {name = "small orange pillow", id = 1682, buy = 20}, + {name = "small purple pillow", id = 1678, buy = 20}, + {name = "small red pillow", id = 1680, buy = 20}, + {name = "small round table", id = 14328, buy = 25}, + {name = "small table kit", id = 3908, buy = 20}, + {name = "small trunk", id = 3821, buy = 20}, + {name = "small turquoise pillow", id = 1683, buy = 20}, + {name = "small white pillow", id = 1684, buy = 20}, + {name = "sofa chair kit", id = 3905, buy = 55}, + {name = "square table kit", id = 14329, buy = 25}, + {name = "stone table kit", id = 3912, buy = 30}, + {name = "table lamp kit", id = 3924, buy = 35}, + {name = "telescope kit", id = 3925, buy = 70}, + {name = "thick trunk", id = 3811, buy = 20}, + {name = "treasure chest", id = 1746, buy = 1000}, + {name = "trophy stand", id = 7936, buy = 50}, + {name = "trough kit", id = 3918, buy = 7}, + {name = "tusk chair kit", id = 3906, buy = 25}, + {name = "tusk table kit", id = 3913, buy = 25}, + {name = "vase", id = 2008, buy = 3}, + {name = "venorean cabinet", id = 20254, buy = 90}, + {name = "venorean drawer", id = 20257, buy = 40}, + {name = "venorean wardrobe", id = 20255, buy = 50}, + {name = "wall mirror", id = 1851, buy = 40}, + {name = "wall mirror", id = 1848, buy = 40}, + {name = "wall mirror", id = 1845, buy = 40}, + {name = "water pipe", id = 2099, buy = 40}, + {name = "weapon rack kit", id = 6115, buy = 90}, + {name = "white tapestry", id = 1880, buy = 25}, + {name = "wooden chair kit", id = 3903, buy = 15}, + {name = "yellow bed kit", id = 7905, buy = 80}, + {name = "yellow pillow", id = 1689, buy = 25}, + {name = "yellow tapestry", id = 1863, buy = 25} + }, + EQUIPMENT = { + {name = "axe", id = 2386, buy = 20, sell = 7}, + {name = "battle axe", id = 2378, buy = 235, sell = 80}, + {name = "battle hammer", id = 2417, buy = 350, sell = 120}, + {name = "bone sword", id = 2450, buy = 75, sell = 20}, + {name = "brass armor", id = 2465, buy = 450, sell = 150}, + {name = "brass helmet", id = 2460, buy = 120, sell = 30}, + {name = "brass legs", id = 2478, buy = 195, sell = 49}, + {name = "brass shield", id = 2511, buy = 65, sell = 25}, + {name = "carlin sword", id = 2395, buy = 473, sell = 118}, + {name = "chain armor", id = 2464, buy = 200, sell = 70}, + {name = "chain helmet", id = 2458, buy = 52, sell = 17}, + {name = "chain legs", id = 2648, buy = 80, sell = 25}, + {name = "club", id = 2382, buy = 5, sell = 1}, + {name = "coat", id = 2651, buy = 8, sell = 1}, + {name = "crowbar", id = 2416, buy = 260, sell = 50}, + {name = "dagger", id = 2379, buy = 5, sell = 2}, + {name = "doublet", id = 2485, buy = 16, sell = 3}, + {name = "dwarven shield", id = 2525, buy = 500, sell = 100}, + {name = "exercise axe", id = 32385, buy = 262500, sell = 500, subType = 500}, + {name = "exercise bow", id = 32387, buy = 262500, sell = 500, subType = 500}, + {name = "exercise club", id = 32386, buy = 262500, sell = 500, subType = 500}, + {name = "exercise sword", id = 32384, buy = 262500, sell = 500, subType = 500}, + {name = "hand axe", id = 2380, buy = 8, sell = 4}, + {name = "iron helmet", id = 2459, buy = 390, sell = 150}, + {name = "jacket", id = 2650, buy = 12, sell = 1}, + {name = "leather armor", id = 2467, buy = 35, sell = 12}, + {name = "leather boots", id = 2643, buy = 10, sell = 2}, + {name = "leather helmet", id = 2461, buy = 12, sell = 4}, + {name = "leather legs", id = 2649, buy = 10, sell = 9}, + {name = "longsword", id = 2397, buy = 160, sell = 51}, + {name = "mace", id = 2398, buy = 90, sell = 30}, + {name = "morning star", id = 2394, buy = 430, sell = 100}, + {name = "plate armor", id = 2463, buy = 1200, sell = 400}, + {name = "plate shield", id = 2510, buy = 125, sell = 45}, + {name = "rapier", id = 2384, buy = 15, sell = 5}, + {name = "sabre", id = 2385, buy = 35, sell = 12}, + {name = "scale armor", id = 2483, buy = 260, sell = 75}, + {name = "short sword", id = 2406, buy = 26, sell = 10}, + {name = "sickle", id = 2405, buy = 7, sell = 3}, + {name = "soldier helmet", id = 2481, buy = 110, sell = 16}, + {name = "spike sword", id = 2383, buy = 8000, sell = 240}, + {name = "steel helmet", id = 2457, buy = 580, sell = 293}, + {name = "steel shield", id = 2509, buy = 240, sell = 80}, + {name = "studded armor", id = 2484, buy = 90, sell = 25}, + {name = "studded helmet", id = 2482, buy = 63, sell = 20}, + {name = "studded legs", id = 2468, buy = 50, sell = 15}, + {name = "studded shield", id = 2526, buy = 50, sell = 16}, + {name = "sword", id = 2376, buy = 85, sell = 25}, + {name = "throwing knife", id = 2410, buy = 25, sell = 2}, + {name = "two handed sword", id = 2377, buy = 950, sell = 450}, + {name = "viking helmet", id = 2473, buy = 265, sell = 66}, + {name = "viking shield", id = 2531, buy = 260, sell = 85}, + {name = "war hammer", id = 2391, buy = 10000, sell = 470}, + {name = "wooden shield", id = 2512, buy = 15, sell = 5} + }, + DISTANCE = { + {name = "arrow", id = 2544, buy = 2}, + {name = "blue quiver", id = 40683, buy = 400}, + {name = "bolt", id = 2580, buy = 4}, + {name = "bow", id = 2456, buy = 400, sell = 100}, + {name = "crossbow", id = 2455, buy = 500, sell = 120}, + {name = "crystalline arrow", id = 18304, buy = 20}, + {name = "drill bolt", id = 18436, buy = 12}, + {name = "diamond arrow", id = 40736, buy = 100}, + {name = "earth arrow", id = 7850, buy = 5}, + {name = "envenomed arrow", id = 18437, buy = 12}, + {name = "flaming arrow", id = 7840, buy = 5}, + {name = "flash arrow", id = 7838, buy = 5}, + {name = "onyx arrow", id = 7365, buy = 7}, + {name = "piercing bolt", id = 7363, buy = 5}, + {name = "power bolt", id = 2547, buy = 7}, + {name = "prismatic bolt", id = 18435, buy = 20}, + {name = "quiver", id = 40397, buy = 400}, + {name = "red quiver", id = 40684, buy = 400}, + {name = "royal spear", id = 7378, buy = 15}, + {name = "shiver arrow", id = 7839, buy = 5}, + {name = "sniper arrow", id = 7364, buy = 5}, + {name = "spear", id = 2389, buy = 9, sell = 3}, + {name = "spectral bolt", id = 40737, buy = 70}, + {name = "tarsal arrow", id = 15648, buy = 6}, + {name = "throwing star", id = 2399, buy = 42}, + {name = "vortex bolt", id = 15649, buy = 6} + }, + WANDS = { + {name = "exercise rod", id = 32388, buy = 262500, subType = 500}, + {name = "exercise wand", id = 32389, buy = 262500, subType = 500}, + {name = "hailstorm rod", id = 2183, buy = 15000}, + {name = "moonlight rod", id = 2186, buy = 1000}, + {name = "necrotic rod", id = 2185, buy = 5000}, + {name = "northwind rod", id = 8911, buy = 7500}, + {name = "snakebite rod", id = 2182, buy = 500}, + {name = "spellwand", id = 7735, sell = 299}, + {name = "springsprout rod", id = 8912, buy = 18000}, + {name = "terra rod", id = 2181, buy = 10000}, + {name = "underworld rod", id = 8910, buy = 22000}, + {name = "wand of cosmic energy", id = 2189, buy = 10000}, + {name = "wand of decay", id = 2188, buy = 5000}, + {name = "wand of draconia", id = 8921, buy = 7500}, + {name = "wand of dragonbreath", id = 2191, buy = 1000}, + {name = "wand of inferno", id = 2187, buy = 15000}, + {name = "wand of starstorm", id = 8920, buy = 18000}, + {name = "wand of voodoo", id = 8922, buy = 22000}, + {name = "wand of vortex", id = 2190, buy = 500} + }, + RODS = { + {name = "exercise rod", id = 32388, buy = 262500, subType = 500}, + {name = "exercise wand", id = 32389, buy = 262500, subType = 500}, + {name = "hailstorm rod", id = 2183, buy = 15000}, + {name = "moonlight rod", id = 2186, buy = 1000}, + {name = "necrotic rod", id = 2185, buy = 5000}, + {name = "northwind rod", id = 8911, buy = 7500}, + {name = "snakebite rod", id = 2182, buy = 500}, + {name = "springsprout rod", id = 8912, buy = 18000}, + {name = "terra rod", id = 2181, buy = 10000}, + {name = "underworld rod", id = 8910, buy = 22000}, + {name = "wand of cosmic energy", id = 2189, buy = 10000}, + {name = "wand of decay", id = 2188, buy = 5000}, + {name = "wand of draconia", id = 8921, buy = 7500}, + {name = "wand of dragonbreath", id = 2191, buy = 1000}, + {name = "wand of inferno", id = 2187, buy = 15000}, + {name = "wand of starstorm", id = 8920, buy = 18000}, + {name = "wand of voodoo", id = 8922, buy = 22000}, + {name = "wand of vortex", id = 2190, buy = 500} + }, + POTIONS = { + {name = "great health potion", id = 7591, buy = 225}, + {name = "great mana potion", id = 7590, buy = 144}, + {name = "great spirit potion", id = 8472, buy = 228}, + {name = "health potion", id = 7618, buy = 50}, + {name = "mana potion", id = 7620, buy = 56}, + {name = "strong health potion", id = 7588, buy = 115}, + {name = "strong mana potion", id = 7589, buy = 93}, + {name = "supreme health potion", id = 26031, buy = 625}, + {name = "ultimate health potion", id = 8473, buy = 379}, + {name = "ultimate mana potion", id = 26029, buy = 438}, + {name = "ultimate spirit potion", id = 26030, buy = 438}, + {name = "empty potion flask", id = 7634, sell = 5}, + {name = "empty potion flask", id = 7635, sell = 5}, + {name = "empty potion flask", id = 7636, sell = 5}, + {name = "vial", id = 2006, sell = 5} + }, + RUNES = { + {name = "animate dead rune", id = 2316, buy = 375}, + {name = "avalanche rune", id = 2274, buy = 57}, + {name = "blank rune", id = 2260, buy = 10}, + {name = "chameleon rune", id = 2291, buy = 210}, + {name = "convince creature rune", id = 2290, buy = 80}, + {name = "cure poison rune", id = 2266, buy = 65}, + {name = "destroy field rune", id = 2261, buy = 15}, + {name = "disintegrate rune", id = 2310, buy = 26}, + {name = "energy bomb rune", id = 2262, buy = 203}, + {name = "energy field rune", id = 2277, buy = 38}, + {name = "energy wall rune", id = 2279, buy = 85}, + {name = "explosion rune", id = 2313, buy = 31}, + {name = "fire bomb rune", id = 2305, buy = 147}, + {name = "fire field rune", id = 2301, buy = 28}, + {name = "fire wall rune", id = 2303, buy = 61}, + {name = "fireball rune", id = 2302, buy = 30}, + {name = "great fireball rune", id = 2304, buy = 57}, + {name = "heavy magic missile rune", id = 2311, buy = 12}, + {name = "holy missile rune", id = 2295, buy = 16}, + {name = "icicle rune", id = 2271, buy = 30}, + {name = "intense healing rune", id = 2265, buy = 95}, + {name = "light magic missile rune", id = 2287, buy = 4}, + {name = "magic wall rune", id = 2293, buy = 116}, + {name = "paralyse rune", id = 2278, buy = 700}, + {name = "poison bomb rune", id = 2286, buy = 85}, + {name = "poison field rune", id = 2285, buy = 21}, + {name = "poison wall rune", id = 2289, buy = 52}, + {name = "soulfire rune", id = 2308, buy = 46}, + {name = "stalagmite rune", id = 2292, buy = 12}, + {name = "stone shower rune", id = 2288, buy = 37}, + {name = "sudden death rune", id = 2268, buy = 135}, + {name = "thunderstorm rune", id = 2315, buy = 47}, + {name = "ultimate healing rune", id = 2273, buy = 175}, + {name = "wild growth rune", id = 2269, buy = 160} + }, + SUPPLIES = { + {name = "brown mushroom", id = 2789, buy = 10}, + {name = "ham", id = 2671, buy = 10}, + {name = "meat", id = 2666, buy = 5} + }, + TOOLS = { + {name = "basket", id = 1989, buy = 6}, + {name = "bottle", id = 2007, buy = 3}, + {name = "bucket", id = 2005, buy = 4}, + {name = "candelabrum", id = 2041, buy = 8}, + {name = "candlestick", id = 2047, buy = 2}, + {name = "closed trap", id = 2578, buy = 280, sell = 75}, + {name = "crowbar", id = 2416, buy = 260, sell = 50}, + {name = "fishing rod", id = 2580, buy = 150, sell = 40}, + {name = "machete", id = 2420, buy = 35, sell = 6}, + {name = "pick", id = 2553, buy = 50, sell = 15}, + {name = "rope", id = 2120, buy = 50, sell = 15}, + {name = "scythe", id = 2550, buy = 50, sell = 10}, + {name = "shovel", id = 2554, buy = 50, sell = 8}, + {name = "spellwand", id = 7735, sell = 299}, + {name = "torch", id = 2050, buy = 2}, + {name = "watch", id = 2036, buy = 20, sell = 6}, + {name = "worm", id = 3976, buy = 1} + }, + POSTAL = { + {name = "label", id = 2599, buy = 1}, + {name = "letter", id = 2597, buy = 8}, + {name = "parcel", id = 2595, buy = 15} + } +} diff --git a/data/lib/tables/npc_spells.lua b/data/lib/tables/npc_spells.lua new file mode 100644 index 00000000000..3acd8a015af --- /dev/null +++ b/data/lib/tables/npc_spells.lua @@ -0,0 +1,1201 @@ +local spells = { + -- Instant spell + { + name = "find person", + group = "support spells", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "hjaern", "charlotta", "azalea", "dario", "elane", "ethan", "hawkyr", "helor", "isolde", "legola", "silas", "ursula", "duria", "gregor", "ormuhn", "puffels", "thorwulf", "trisha", "tristan", "uso", "shalmar", "gundralph", "faluae", "asrak", "razan"}, + price = 80, + vocation = {1, 2, 3, 4, 5, 6, 7, 8}, + premium = false, + level = 8 + }, + { + name = "light", + group ="support spells", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "hjaern", "charlotta", "azalea", "dario", "elane", "ethan", "hawkyr", "helor", "isolde", "legola", "silas", "ursula", "duria", "gregor", "ormuhn", "puffels", "thorwulf", "trisha", "tristan", "uso", "shalmar", "maealil", "gundralph", "faluae", "asrak", "razan"}, + price = 0, + vocation = {1, 2, 4, 5, 6, 8}, + premium = false, + level = 8 + }, + { + name = "light healing", + group ="healing spells", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "hjaern", "charlotta", "azalea", "dario", "elane", "ethan", "hawkyr", "helor", "isolde", "legola", "silas", "ursula", "shalmar", "gundralph", "asrak", "razan"}, + price = 0, + vocation = {1, 2, 3, 5, 6, 7}, + premium = false, + level = 8 + }, + { + name = "magic rope", + group ="support spells", + npc = {"barnabas dee", "malunga", "romir", "tamoril", "tothdral", "tamara", "ustan", "hjaern", "charlotta", "azalea", "dario", "ethan", "hawkyr", "helor", "isolde", "silas", "ursula", "ormuhn", "puffels", "thorwulf", "tristan", "uso", "shalmar", "gundralph", "razan"}, + price = 200, + vocation = {1, 2, 3, 4, 5, 6, 7, 8}, + premium = false, + level = 9 + }, + { + name = "cure poison", + group ="healing spells", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "hjaern", "charlotta", "azalea", "dario", "elane", "ethan", "hawkyr", "helor", "isolde", "legola", "silas", "ursula", "duria", "gregor", "ormuhn", "puffels", "thorwulf", "trisha", "tristan", "uso", "shalmar", "maealil", "gundralph", "asrak", "razan"}, + price = 150, + vocation = {1, 2, 3, 4, 5, 6, 7, 8}, + premium = false, + level = 8 + }, + { + name = "wound cleansing", + group ="healing spells", + npc = {"duria", "gregor", "ormuhn", "puffels", "thorwulf", "trisha", "tristan", "uso", "asrak", "razan"}, + price = 0, + vocation = {4, 8}, + premium = false, + level = 8 + }, + { + name = "levitate", + group ="support spells", + npc = {"barnabas dee", "malunga", "romir", "tamoril", "tothdral", "rahkem", "tamara", "ustan", "hjaern", "charlotta", "azalea", "dario", "ethan", "hawkyr", "helor", "isolde", "silas", "ursula", "ormuhn", "puffels", "thorwulf", "tristan", "uso", "shalmar", "gundralph", "razan"}, + price = 500, + vocation = {1, 2, 3, 4, 5, 6, 7, 8}, + premium = true, + level = 12 + }, + { + name = "energy strike", + group ="attack spells", + npc = {"barnabas dee", "malunga", "myra", "romir", "tamoril", "tothdral", "rahkem", "tamara", "ustan", "hjaern", "charlotta", "azalea", "gundralph"}, + price = 800, + vocation = {1, 2, 5, 6}, + premium = true, + level = 12 + }, + { + name = "great light", + group ="support spells", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "hjaern", "charlotta", "azalea", "dario", "elane", "ethan", "hawkyr", "helor", "isolde", "legola", "silas", "ursula", "duria", "gregor", "ormuhn", "puffels", "thorwulf", "trisha", "tristan", "uso", "shalmar", "gundralph", "faluae", "asrak", "razan"}, + price = 500, + vocation = {1, 2, 4, 5, 6, 8}, + premium = false, + level = 13 + }, + { + name = "terra strike", + group ="attack spells", + npc = {"barnabas dee", "malunga", "myra", "romir", "tothdral", "rahkem", "tamara", "ustan", "hjaern", "charlotta", "azalea", "shalmar", "gundralph"}, + price = 800, + vocation = {1, 2, 3, 5, 6, 7}, + premium = true, + level = 13 + }, + { + name = "conjure arrow", + group ="support spells", + npc = {"dario", "elane", "ethan", "hawkyr", "helor", "isolde", "legola", "silas", "ursula", "asrak", "razan"}, + price = 450, + vocation = {3, 7}, + premium = false, + level = 13 + }, + { + name = "cancel magic shield", + group ="support spells", + npc = {"rahkem", "tamara", "ustan", "hjaern", "charlotta", "azalea", "shalmar", "gundralph"}, + price = 450, + vocation = {1, 2, 5, 6}, + premium = true, + level = 14 + }, + { + name = "flame strike", + group ="attack spells", + npc = {"barnabas dee", "malunga", "myra", "romir", "tamoril", "tothdral", "rahkem", "ustan", "hjaern", "charlotta", "azalea", "shalmar", "gundralph"}, + price = 800, + vocation = {1, 2, 5, 6}, + premium = true, + level = 14 + }, + { + name = "haste", + group ="support spells", + npc = {"barnabas dee", "malunga", "romir", "tamoril", "tothdral", "marvik", "rahkem", "tamara", "ustan", "hjaern", "charlotta", "azalea", "dario", "ethan", "hawkyr", "helor", "isolde", "silas", "ursula", "ormuhn", "puffels", "thorwulf", "tristan", "uso", "shalmar", "gundralph", "razan"}, + price = 600, + vocation = {1, 2, 3, 4, 5, 6, 7, 8}, + premium = true, + level = 14 + }, + { + name = "food", + group ="conjuring spells", + npc = {"marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "hjaern", "charlotta", "azalea", "shalmar", "gundralph", "faluae"}, + price = 300, + vocation = {2, 6}, + premium = false, + level = 14 + }, + { + name = "magic shield", + group ="support spells", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "padreia", "rahkem", "smiley", "tamara", "ustan", "hjaern", "charlotta", "azalea", "shalmar", "gundralph", "eroth"}, + price = 450, + vocation = {1, 2, 5, 6}, + premium = false, + level = 14 + }, + { + name = "ice strike", + group ="attack spells", + npc = {"barnabas dee", "malunga", "romir", "tamoril", "tothdral", "rahkem", "ustan", "hjaern", "charlotta", "shalmar", "gundralph"}, + price = 800, + vocation = {1, 2, 5, 6}, + premium = true, + level = 15 + }, + { + name = "death strike", + group ="attack spells", + npc = {"barnabas dee", "malunga", "myra", "romir", "tamoril", "tothdral", "shalmar", "gundralph"}, + price = 800, + vocation = {1, 5}, + premium = true, + level = 16 + }, + { + name = "brutal strike", + group ="attack spells", + npc = {"ormuhn", "puffels", "thorwulf", "tristan", "uso", "razan"}, + price = 1000, + vocation = {4, 8}, + premium = true, + level = 16 + }, + { + name = "physical strike", + group ="attack spells", + npc = {"rahkem", "ustan", "hjaern", "charlotta", "azalea", "shalmar", "gundralph"}, + price = 800, + vocation = {2, 6}, + premium = true, + level = 16 + }, + { + name = "ice wave", + group ="attack spells", + npc = {"marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "hjaern", "elathriel", "charlotta", "azalea", "shalmar", "gundralph"}, + price = 850, + vocation = {2, 6}, + premium = false, + level = 18 + }, + { + name = "heal friend", + group ="healing spells", + npc = {"rahkem", "tamara", "ustan", "hjaern", "charlotta", "azalea", "shalmar", "gundralph"}, + price = 800, + vocation = {2, 6}, + premium = true, + level = 18 + }, + { + name = "fire wave", + group ="attack spells", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "shalmar", "gundralph"}, + price = 850, + vocation = {1, 5}, + premium = false, + level = 18 + }, + { + name = "challenge", + group ="support spells", + npc = {"eremo"}, + price = 2000, + vocation = {4, 8}, + premium = true, + level = 20 + }, + { + name = "intense healing", + group ="healing spells", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "smiley", "tamara", "hjaern", "charlotta", "azalea", "dario", "elane", "ethan", "hawkyr", "helor", "isolde", "legola", "silas", "ursula", "shalmar", "maealil", "gundralph", "asrak", "razan"}, + price = 350, + vocation = {1, 2, 3, 5, 6, 7}, + premium = false, + level = 20 + }, + { + name = "strong haste", + group ="support spells", + npc = {"barnabas dee", "malunga", "romir", "tamoril", "tothdral", "rahkem", "tamara", "ustan", "hjaern", "charlotta", "azalea", "shalmar", "gundralph"}, + price = 1300, + vocation = {1, 2, 5, 6}, + premium = true, + level = 20 + }, + { + name = "cure electrification", + group ="healing spells", + npc = {"rahkem", "tamara", "ustan", "hjaern", "charlotta", "azalea", "shalmar", "gundralph"}, + price = 1000, + vocation = {2, 6}, + premium = true, + level = 22 + }, + { + name = "creature illusion", + group ="support spells", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "hjaern", "charlotta", "shalmar", "gundralph", "eroth"}, + price = 1000, + vocation = {1, 2, 5, 6}, + premium = false, + level = 23 + }, + { + name = "energy beam", + group ="attack spells", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "romir", "tamoril", "tothdral", "shalmar", "gundralph"}, + price = 1000, + vocation = {1, 5}, + premium = false, + level = 23 + }, + { + name = "ethereal spear", + group ="attack spells", + npc = {"dario", "ethan", "hawkyr", "helor", "isolde", "silas", "ursula", "razan"}, + price = 1100, + vocation = {3, 7}, + premium = true, + level = 23 + }, + { + name = "summon creature", + group ="conjuring spells", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "hjaern", "charlotta", "azalea", "shalmar", "gundralph", "eroth"}, + price = 2000, + vocation = {1, 2, 5, 6}, + premium = false, + level = 25 + }, + { + name = "charge", + group ="support spells", + npc = {"ormuhn", "puffels", "thorwulf", "tristan", "uso", "razan"}, + price = 1300, + vocation = {4, 8}, + premium = true, + level = 25 + }, + { + name = "conjure explosive arrow", + group ="support spells", + npc = {"dario", "elane", "ethan", "hawkyr", "helor", "isolde", "legola", "silas", "ursula", "asrak", "razan"}, + price = 1000, + vocation = {3, 7}, + premium = false, + level = 25 + }, + { + name = "cancel invisibility", + group ="support spells", + npc = {"dario", "ethan", "hawkyr", "helor", "isolde", "silas", "ursula", "razan"}, + price = 1600, + vocation = {3, 7}, + premium = true, + level = 26 + }, + { + name = "ignite", + group ="attack spells", + npc = {"barnabas dee", "malunga", "myra", "romir", "tamoril", "tothdral", "shalmar", "gundralph"}, + price = 1500, + vocation = {1, 5}, + premium = true, + level = 26 + }, + { + name = "ultimate light", + group ="support spells", + npc = {"barnabas dee", "malunga", "romir", "tamoril", "rahkem", "tamara", "ustan", "hjaern", "charlotta", "azalea", "shalmar", "gundralph"}, + price = 1600, + vocation = {1, 2, 5, 6}, + premium = true, + level = 26 + }, + { + name = "whirlwind throw", + group ="attack spells", + npc = {"ormuhn", "puffels", "thorwulf", "tristan", "uso", "razan"}, + price = 1500, + vocation = {4, 8}, + premium = true, + level = 28 + }, + { + name = "great energy beam", + group ="attack spells", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "shalmar", "gundralph"}, + price = 1800, + vocation = {1, 5}, + premium = false, + level = 29 + }, + { + name = "ultimate healing", + group ="healing spells", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "hjaern", "charlotta", "azalea", "shalmar", "maealil", "gundralph"}, + price = 1000, + vocation = {1, 2, 5, 6}, + premium = false, + level = 30 + }, + { + name = "cure burning", + group ="healing spells", + npc = {"rahkem", "tamara", "ustan", "hjaern", "charlotta", "azalea", "shalmar"}, + price = 2000, + vocation = {2, 6}, + premium = true, + level = 30 + }, + { + name = "enchant party", + group ="support spells", + npc = {"eliza"}, + price = 4000, + vocation = {1, 5}, + premium = true, + level = 32 + }, + { + name = "heal party", + group ="support spells", + npc = {"eliza"}, + price = 4000, + vocation = {2, 6}, + premium = true, + level = 32 + }, + { + name = "protect party", + group ="support spells", + npc = {"eliza"}, + price = 4000, + vocation = {3, 7}, + premium = true, + level = 32 + }, + { + name = "train party", + group ="support spells", + npc = {"eliza"}, + price = 4000, + vocation = {4, 8}, + premium = true, + level = 32 + }, + { + name = "groundshaker", + group ="attack spells", + npc = {"ormuhn", "puffels", "thorwulf", "tristan", "uso", "razan"}, + price = 1500, + vocation = {4, 8}, + premium = true, + level = 33 + }, + { + name = "electrify", + group ="attack spells", + npc = {"barnabas dee", "malunga", "myra", "romir", "tamoril", "tothdral", "shalmar", "gundralph"}, + price = 2500, + vocation = {1, 5}, + premium = true, + level = 34 + }, + { + name = "berserk", + group ="attack spells", + npc = {"ormuhn", "puffels", "thorwulf", "tristan", "uso", "razan"}, + price = 2500, + vocation = {4, 8}, + premium = true, + level = 35 + }, + { + name = "divine healing", + group ="healing spells", + npc = {"dario", "elane", "ethan", "hawkyr", "helor", "isolde", "legola", "silas", "ursula", "asrak", "razan"}, + price = 3000, + vocation = {3, 7}, + premium = false, + level = 35 + }, + { + name = "invisible", + group ="support spells", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "myra", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "hjaern", "charlotta", "shalmar", "gundralph", "eroth"}, + price = 2000, + vocation = {1, 2, 5, 6}, + premium = false, + level = 35 + }, + { + name = "mass healing", + group ="healing spells", + npc = {"rahkem", "tamara", "ustan", "hjaern", "charlotta", "azalea", "shalmar", "zoltan", "gundralph"}, + price = 2200, + vocation = {2, 6}, + premium = true, + level = 36 + }, + { + name = "energy wave", + group ="attack spells", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "shalmar", "gundralph"}, + price = 2500, + vocation = {1, 5}, + premium = false, + level = 38 + }, + { + name = "great fire wave", + group ="attack spells", + npc = {0}, + price = 25000, + vocation = {1, 5}, + premium = true, + level = 38 + }, + { + name = "terra wave", + group ="attack spells", + npc = {"marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "hjaern", "elathriel", "charlotta", "azalea", "shalmar", "gundralph"}, + price = 2500, + vocation = {2, 6}, + premium = false, + level = 38 + }, + { + name = "inflict wound", + group ="attack spells", + npc = {"ormuhn", "puffels", "thorwulf", "tristan", "uso", "razan"}, + price = 2500, + vocation = {4, 8}, + premium = true, + level = 40 + }, + { + name = "divine missile", + group ="attack spells", + npc = {"dario", "ethan", "hawkyr", "helor", "isolde", "silas", "ursula", "razan"}, + price = 1800, + vocation = {3, 7}, + premium = true, + level = 40 + }, + { + name = "strong ice wave", + group ="attack spells", + npc = {"rahkem", "tamara", "ustan", "hjaern", "charlotta", "azalea", "shalmar", "gundralph"}, + price = 7500, + vocation = {2, 6}, + premium = true, + level = 40 + }, + { + name = "conjure wand of darkness", + group ="conjuring spells", + npc = {"eremo"}, + price = 5000, + vocation = {1, 5}, + premium = true, + level = 41 + }, + { + name = "cure bleeding", + group ="healing spells", + npc = {"rahkem", "tamara", "ustan", "hjaern", "charlotta", "azalea", "ormuhn", "puffels", "thorwulf", "tristan", "uso", "shalmar", "gundralph", "razan"}, + price = 2500, + vocation = {2, 4, 6, 8}, + premium = true, + level = 45 + }, + { + name = "enchant spear", + group ="support spells", + npc = {"dario", "ethan", "hawkyr", "helor", "isolde", "silas", "ursula", "razan"}, + price = 2000, + vocation = {3, 7}, + premium = true, + level = 45 + }, + { + name = "envenom", + group ="attack spells", + npc = {"rahkem", "tamara", "ustan", "hjaern", "charlotta", "azalea", "shalmar", "gundralph"}, + price = 6000, + vocation = {2, 6}, + premium = true, + level = 50 + }, + { + name = "divine caldera", + group ="attack spells", + npc = {"dario", "ethan", "hawkyr", "helor", "isolde", "silas", "zoltan", "razan"}, + price = 3000, + vocation = {3, 7}, + premium = true, + level = 50 + }, + { + name = "recovery", + group ="healing spells", + npc = {"dario", "ethan", "hawkyr", "helor", "isolde", "silas", "ursula", "ormuhn", "puffels", "thorwulf", "tristan", "uso", "razan"}, + price = 4000, + vocation = {3, 4, 7, 8}, + premium = true, + level = 50 + }, + { + name = "lightning", + group ="attack spells", + npc = {"barnabas dee", "malunga", "myra", "romir", "tamoril", "tothdral", "shalmar", "gundralph"}, + price = 5000, + vocation = {1, 5}, + premium = true, + level = 55 + }, + { + name = "wrath of nature", + group ="attack spells", + npc = {"zoltan"}, + price = 6000, + vocation = {2, 6}, + premium = true, + level = 55 + }, + { + name = "rage of the skies", + group ="attack spells", + npc = {"zoltan"}, + price = 6000, + vocation = {1, 5}, + premium = true, + level = 55 + }, + { + name = "protector", + group ="support spells", + npc = {"zoltan"}, + price = 6000, + vocation = {4, 8}, + premium = true, + level = 55 + }, + { + name = "swift foot", + group ="support spells", + npc = {"zoltan"}, + price = 6000, + vocation = {3, 7}, + premium = true, + level = 55 + }, + { + name = "salvation", + group ="support spells", + npc = {"dario", "ethan", "hawkyr", "helor", "silas", "ursula", "razan"}, + price = 8000, + vocation = {3, 7}, + premium = true, + level = 60 + }, + { + name = "eternal winter", + group ="attack spells", + npc = {"zoltan"}, + price = 8000, + vocation = {2, 6}, + premium = true, + level = 60 + }, + { + name = "hells core", + group ="attack spells", + npc = {"zoltan"}, + price = 8000, + vocation = {1, 5}, + premium = true, + level = 60 + }, + { + name = "blood rage", + group ="support spells", + npc = {"zoltan"}, + price = 8000, + vocation = {4, 8}, + premium = true, + level = 60 + }, + { + name = "sharpshooter", + group ="support spells", + npc = {"zoltan"}, + price = 8000, + vocation = {3, 7}, + premium = true, + level = 60 + }, + { + name = "front sweep", + group ="attack spells", + npc = {"ormuhn", "puffels", "thorwulf", "tristan", "uso", "razan"}, + price = 4000, + vocation = {4, 8}, + premium = true, + level = 70 + }, + { + name = "holy flash", + group ="attack spells", + npc = {"dario", "ethan", "hawkyr", "helor", "silas", "ursula", "razan"}, + price = 7500, + vocation = {3, 7}, + premium = true, + level = 70 + }, + { + name = "strong flame strike", + group ="attack spells", + npc = {"barnabas dee", "malunga", "myra", "romir", "tamoril", "tothdral", "shalmar", "gundralph"}, + price = 6000, + vocation = {1, 5}, + premium = true, + level = 70 + }, + { + name = "strong terra strike", + group ="attack spells", + npc = {"rahkem", "tamara", "ustan", "hjaern", "charlotta", "azalea", "shalmar", "gundralph"}, + price = 6000, + vocation = {2, 6}, + premium = true, + level = 70 + }, + { + name = "curse", + group ="attack spells", + npc = {"barnabas dee", "malunga", "myra", "romir", "tothdral", "shalmar", "gundralph"}, + price = 6000, + vocation = {1, 5}, + premium = true, + level = 75 + }, + { + name = "cure curse", + group ="healing spells", + npc = {"dario", "ethan", "hawkyr", "helor", "silas", "ursula", "razan"}, + price = 6000, + vocation = {3, 7}, + premium = true, + level = 80 + }, + { + name = "intense wound cleansing", + group ="healing spells", + npc = {"ormuhn", "puffels", "thorwulf", "tristan", "uso", "razan"}, + price = 6000, + vocation = {4, 8}, + premium = true, + level = 80 + }, + { + name = "strong energy strike", + group ="attack spells", + npc = {"barnabas dee", "malunga", "myra", "romir", "tothdral", "shalmar", "gundralph"}, + price = 6000, + vocation = {1, 5}, + premium = true, + level = 80 + }, + { + name = "strong ice strike", + group ="attack spells", + npc = {"tamara", "ustan", "hjaern", "charlotta", "azalea", "shalmar", "gundralph"}, + price = 6000, + vocation = {2, 6}, + premium = true, + level = 80 + }, + { + name = "fierce berserk", + group ="attack spells", + npc = {"ormuhn", "puffels", "thorwulf", "uso", "zoltan", "razan"}, + price = 7500, + vocation = {4, 8}, + premium = true, + level = 90 + }, + { + name = "strong ethereal spear", + group ="attack spells", + npc = {"dario", "ethan", "hawkyr", "helor", "isolde", "silas", "ursula", "razan"}, + price = 10000, + vocation = {3, 7}, + premium = true, + level = 90 + }, + { + name = "ultimate terra strike", + group ="attack spells", + npc = {"zoltan"}, + price = 15000, + vocation = {2, 6}, + premium = true, + level = 90 + }, + { + name = "ultimate flame strike", + group ="attack spells", + npc = {"zoltan"}, + price = 15000, + vocation = {1, 5}, + premium = true, + level = 90 + }, + { + name = "intense recovery", + group ="healing spells", + npc = {"dario", "ethan", "hawkyr", "helor", "isolde", "silas", "ursula", "ormuhn", "puffels", "thorwulf", "uso", "razan"}, + price = 10000, + vocation = {3, 4, 7, 8}, + premium = true, + level = 100 + }, + { + name = "ultimate ice strike", + group ="attack spells", + npc = {"zoltan"}, + price = 15000, + vocation = {2, 6}, + premium = true, + level = 100 + }, + { + name = "ultimate energy strike", + group ="attack spells", + npc = {"zoltan"}, + price = 15000, + vocation = {1, 5}, + premium = true, + level = 100 + }, + { + name = "annihilation", + group ="attack spells", + npc = {"ormuhn", "puffels", "thorwulf", "tristan", "uso", "razan"}, + price = 20000, + vocation = {4, 8}, + premium = true, + level = 110 + }, + { + name = "conjure diamond arrow", + group ="conjuring spells", + npc = {"eremo"}, + price = 15000, + vocation = {3, 7}, + premium = true, + level = 150 + }, + { + name = "conjure spectral bolt", + group ="conjuring spells", + npc = {"eremo"}, + price = 15000, + vocation = {3, 7}, + premium = true, + level = 150 + }, + { + name = "summon grovebeast", + group ="conjuring spells", + npc = {"rahkem", "tamara", "ustan", "hjaern", "charlotta", "azalea", "shalmar", "gundralph"}, + price = 50000, + vocation = {2, 6}, + premium = true, + level = 200 + }, + { + name = "summon thundergiant", + group ="conjuring spells", + npc = {"barnabas dee", "malunga", "myra", "romir", "tamoril", "tothdral", "shalmar", "gundralph"}, + price = 50000, + vocation = {1, 5}, + premium = true, + level = 200 + }, + { + name = "summon skullfrost", + group ="support spells", + npc = {"ormuhn", "puffels", "thorwulf", "tristan", "uso", "razan"}, + price = 50000, + vocation = {4, 8}, + premium = true, + level = 200 + }, + { + name = "summon emberwing", + group ="support spells", + npc = {"dario", "ethan", "hawkyr", "helor", "isolde", "silas", "ursula", "razan"}, + price = 50000, + vocation = {3, 7}, + premium = true, + level = 200 + }, + { + name = "chivalrous challenge", + group ="support spells", + npc = {0}, + price = 250000, + vocation = {4, 8}, + premium = true, + level = 250 + }, + { + name = "divine dazzle", + group ="support spells", + npc = {0}, + price = 250000, + vocation = {3, 7}, + premium = true, + level = 250 + }, + { + name = "fair wound cleansing", + group ="healing spells", + npc = {0}, + price = 500000, + vocation = {4, 8}, + premium = true, + level = 300 + }, + { + name = "restoration", + group ="healing spells", + npc = {"shalmar", "gundralph"}, + price = 500000, + vocation = {1, 2, 5, 6}, + premium = true, + level = 300 + }, + { + name = "nature embrace", + group ="healing spells", + npc = {"shalmar", "gundralph"}, + price = 500000, + vocation = {2, 6}, + premium = true, + level = 300 + }, + -- rune spells + { + name = "poison field rune", + group ="support rune", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "charlotta", "shalmar", "gundralph", "eroth"}, + price = 300, + vocation = {1, 2, 5, 6}, + premium = false, + level = 14 + }, + { + name = "fire field rune", + group ="support rune", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "charlotta", "shalmar", "gundralph", "eroth"}, + price = 500, + vocation = {1, 2, 5, 6}, + premium = false, + level = 15 + }, + { + name = "cure poison rune", + group ="support rune", + npc = {"marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "charlotta", "shalmar", "maealil"}, + price = 600, + vocation = {2, 6}, + premium = false, + level = 15 + }, + { + name = "intense healing rune", + group ="support rune", + npc = {"marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "charlotta", "shalmar", "maealil"}, + price = 600, + vocation = {2, 6}, + premium = false, + level = 15 + }, + { + name = "light magic missile rune", + group ="support rune", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "elathriel", "charlotta", "shalmar", "gundralph"}, + price = 500, + vocation = {1, 2, 5, 6}, + premium = false, + level = 15 + }, + { + name = "convince creature rune", + group ="support rune", + npc = {"marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "charlotta", "azalea", "shalmar"}, + price = 800, + vocation = {2, 6}, + premium = false, + level = 16 + }, + { + name = "destroy field rune", + group ="support rune", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "charlotta", "azalea", "dario", "elane", "ethan", "hawkyr", "helor", "isolde", "legola", "silas", "ursula", "shalmar", "gundralph", "eroth", "asrak", "razan"}, + price = 700, + vocation = {1, 2, 3, 5, 6, 7}, + premium = false, + level = 17 + }, + { + name = "energy field rune", + group ="support rune", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "charlotta", "shalmar", "gundralph", "eroth"}, + price = 700, + vocation = {1, 2, 5, 6}, + premium = false, + level = 18 + }, + { + name = "disintegrate rune", + group ="support rune", + npc = {"barnabas dee", "malunga", "myra", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "ustan", "charlotta", "azalea", "shalmar", "gundralph", "razan"}, + price = 900, + vocation = {1, 2, 3, 5, 6, 7}, + premium = true, + level = 21 + }, + { + name = "ultimate healing rune", + group ="support rune", + npc = {"marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "charlotta", "shalmar", "maealil"}, + price = 1500, + vocation = {2, 6}, + premium = false, + level = 24 + }, + { + name = "stalagmite rune", + group ="support rune", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "elathriel", "charlotta", "shalmar", "gundralph"}, + price = 1400, + vocation = {1, 2, 5, 6}, + premium = false, + level = 24 + }, + { + name = "heavy magic missile rune", + group ="support rune", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "elathriel", "charlotta", "shalmar", "gundralph"}, + price = 1500, + vocation = {1, 2, 5, 6}, + premium = false, + level = 25 + }, + { + name = "poison bomb rune", + group ="support rune", + npc = {"ustan", "charlotta", "shalmar", "gundralph"}, + price = 1000, + vocation = {2, 6}, + premium = true, + level = 25 + }, + { + name = "wild growth rune", + group ="support rune", + npc = {"eremo"}, + price = 2000, + vocation = {2, 6}, + premium = true, + level = 27 + }, + { + name = "chameleon rune", + group ="support rune", + npc = {"marvik", "padreia", "smiley", "tamara", "ustan", "charlotta", "azalea", "shalmar", "eroth"}, + price = 1300, + vocation = {2, 6}, + premium = false, + level = 27 + }, + { + name = "soulfire rune", + group ="support rune", + npc = {"barnabas dee", "malunga", "romir", "tamoril", "tothdral", "rahkem", "ustan", "gundralph"}, + price = 1800, + vocation = {1, 2, 5, 6}, + premium = true, + level = 27 + }, + { + name = "holy missile rune", + group ="support rune", + npc = {"razan"}, + price = 1600, + vocation = {3, 7}, + premium = true, + level = 27 + }, + { + name = "fire bomb rune", + group ="support rune", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "charlotta", "shalmar", "gundralph", "eroth"}, + price = 1500, + vocation = {1, 2, 5, 6}, + premium = false, + level = 27 + }, + { + name = "animate dead rune", + group ="support rune", + npc = {"barnabas dee", "romir", "tamoril", "rahkem", "ustan", "charlotta", "azalea", "shalmar"}, + price = 1200, + vocation = {1, 2, 5, 6}, + premium = true, + level = 27 + }, + { + name = "fireball rune", + group ="support rune", + npc = {"barnabas dee", "malunga", "myra", "romir", "tamoril", "tothdral", "gundralph"}, + price = 1600, + vocation = {1, 5}, + premium = true, + level = 27 + }, + { + name = "thunderstorm rune", + group ="support rune", + npc = {"barnabas dee", "malunga", "myra", "romir", "tamoril" ,"tothdral"}, + price = 1100, + vocation = {1, 5}, + premium = true, + level = 28 + }, + { + name = "icicle rune", + group ="support rune", + npc = {"rahkem", "ustan", "charlotta", "shalmar", "gundralph"}, + price = 1700, + vocation = {2, 6}, + premium = true, + level = 28 + }, + { + name = "stone shower rune", + group ="support rune", + npc = {"rahkem", "ustan", "charlotta", "shalmar", "gundralph"}, + price = 1100, + vocation = {2, 6}, + premium = false, + level = 28 + }, + { + name = "poison wall rune", + group ="support rune", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "charlotta", "shalmar", "gundralph", "eroth"}, + price = 1600, + vocation = {1, 2, 5, 6}, + premium = false, + level = 29 + }, + { + name = "great fireball rune", + group ="support rune", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "gundralph"}, + price = 1200, + vocation = {1, 5}, + premium = true, + level = 30 + }, + { + name = "avalanche rune", + group ="support rune", + npc = {"marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "elathriel", "charlotta", "shalmar", "gundralph"}, + price = 1200, + vocation = {2, 6}, + premium = false, + level = 30 + }, + { + name = "explosion rune", + group ="support rune", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "elathriel", "charlotta", "shalmar", "gundralph"}, + price = 1800, + vocation = {1, 2, 5, 6}, + premium = false, + level = 31 + }, + { + name = "magic wall rune", + group ="support rune", + npc = {"barnabas dee", "malunga", "myra", "romir", "tamoril", "tothdral", "gundralph"}, + price = 2000, + vocation = {1, 5}, + premium = true, + level = 32 + }, + { + name = "fire wall rune", + group ="support rune", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "charlotta", "shalmar", "gundralph", "eroth"}, + price = 2000, + vocation = {1, 2, 5, 6}, + premium = false, + level = 33 + }, + { + name = "energy bomb rune", + group ="support rune", + npc = {"barnabas dee", "malunga", "myra", "romir", "tamoril", "tothdral", "zoltan", "gundralph"}, + price = 2300, + vocation = {1, 5}, + premium = true, + level = 37 + }, + { + name = "energy wall rune", + group ="support rune", + npc = {"barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "marvik", "padreia", "rahkem", "smiley", "tamara", "ustan", "charlotta", "gundralph", "eroth"}, + price = 2500, + vocation = {1, 2, 5, 6}, + premium = false, + level = 41 + }, + { + name = "sudden death rune", + group ="support rune", + npc = {"Garamond", "barnabas dee", "chatterbone", "etzel", "lea", "malunga", "muriel", "myra", "romir", "tamoril", "tothdral", "gundralph"}, + price = 3000, + vocation = {1, 5}, + premium = false, + level = 35 + }, + { + name = "paralyze rune", + group ="support rune", + npc = {"Garamond", "marvik", "rahkem", "tamara", "ustan", "charlotta", "azalea", "shalmar", "zoltan"}, + price = 1900, + vocation = {2, 6}, + premium = true, + level = 54 + } +} diff --git a/data/lib/tables/table.lua b/data/lib/tables/table.lua new file mode 100644 index 00000000000..0098dbeb7a6 --- /dev/null +++ b/data/lib/tables/table.lua @@ -0,0 +1,8 @@ +dofile('data/lib/tables/vocation.lua') +dofile('data/lib/tables/achievements_lib.lua') +dofile('data/lib/tables/door.lua') +dofile('data/lib/tables/hireling_items.lua') +dofile('data/lib/tables/teleport_item_destinations.lua') +dofile('data/lib/tables/town.lua') +dofile('data/lib/tables/window.lua') +dofile('data/lib/tables/npc_spells.lua') diff --git a/data/lib/tables/teleport_item_destinations.lua b/data/lib/tables/teleport_item_destinations.lua new file mode 100644 index 00000000000..c92e3a2392b --- /dev/null +++ b/data/lib/tables/teleport_item_destinations.lua @@ -0,0 +1,15 @@ +-- Set to which position items are teleported for each teleport item +-- If no position is set they will not be teleported anywhere +--[[ + [aid] = {destination = Postion(), effect = CONST_ME__} +]] + +ItemTeleports = { + [5630] = {destination = Position(33145, 32863, 7), effect = CONST_ME_MAGIC_GREEN}, + [5631] = {destination = Position(33147, 32864, 7), effect = CONST_ME_MAGIC_GREEN}, + + -- Rookgaard level bridge + [50240] = {destination = Position(32092, 32177, 6), effect = CONST_ME_MAGIC_BLUE}, + -- Rookgaard premium bridge + [50241] = {destination = Position(32066, 32192, 7), effect = CONST_ME_MAGIC_BLUE} +} diff --git a/data/lib/tables/town.lua b/data/lib/tables/town.lua new file mode 100644 index 00000000000..9568101519b --- /dev/null +++ b/data/lib/tables/town.lua @@ -0,0 +1,28 @@ +TOWNS_LIST = { + DAWNPORT_TUTORIAL = 1, + DAWNPORT = 2, + ROOKGAARD = 3, + ISLAND_OF_DESTINY = 4, + AB_DENDRIEL = 5, + CARLIN = 6, + KAZORDOON = 7, + THAIS = 8, + VENORE = 9, + ANKRAHMUN = 10, + EDRON = 11, + FARMINE = 12, + DARASHIA = 13, + LIBERTY_BAY = 14, + PORT_HOPE = 15, + SVARGROND = 16, + YALAHAR = 17, + GRAY_BEACH = 18, + KRAILOS = 19, + RATHLETON = 20, + ROSHAMUUL = 21, + ISSAVI = 22, + EVENT_ROOM = 23, + COBRA_BASTION = 24, + BOUNAC = 25, + FEYRIST = 26 +} diff --git a/data/lib/tables/vocation.lua b/data/lib/tables/vocation.lua new file mode 100644 index 00000000000..c53b39aa955 --- /dev/null +++ b/data/lib/tables/vocation.lua @@ -0,0 +1,20 @@ +VOCATION = { + ID = { + NONE = 0, + SORCERER = 1, + DRUID = 2, + PALADIN = 3, + KNIGHT = 4, + MASTER_SORCERER = 5, + ELDER_DRUID = 6, + ROYAL_PALADIN = 7, + ELITE_KNIGHT = 8 + }, + CLIENT_ID = { + NONE = 0, + KNIGHT = 1, + PALADIN = 2, + SORCERER = 3, + DRUID = 4 + } +} diff --git a/data/lib/tables/window.lua b/data/lib/tables/window.lua new file mode 100644 index 00000000000..8002fc5148a --- /dev/null +++ b/data/lib/tables/window.lua @@ -0,0 +1,94 @@ +windowTable = { + {closedWindow = 5303, openWindow = 6448}, + {closedWindow = 5304, openWindow = 6449}, + {closedWindow = 6438, openWindow = 6436}, + {closedWindow = 6436, openWindow = 6438}, + {closedWindow = 6439, openWindow = 6437}, + {closedWindow = 6437, openWindow = 6439}, + {closedWindow = 6442, openWindow = 6440}, + {closedWindow = 6440, openWindow = 6442}, + {closedWindow = 6443, openWindow = 6441}, + {closedWindow = 6441, openWindow = 6443}, + {closedWindow = 6446, openWindow = 6444}, + {closedWindow = 6444, openWindow = 6446}, + {closedWindow = 6447, openWindow = 6445}, + {closedWindow = 6445, openWindow = 6447}, + {closedWindow = 6448, openWindow = 5303}, + {closedWindow = 6449, openWindow = 5304}, + {closedWindow = 6452, openWindow = 6450}, + {closedWindow = 6450, openWindow = 6452}, + {closedWindow = 6453, openWindow = 6451}, + {closedWindow = 6451, openWindow = 6453}, + {closedWindow = 6456, openWindow = 6454}, + {closedWindow = 6454, openWindow = 6456}, + {closedWindow = 6457, openWindow = 6455}, + {closedWindow = 6455, openWindow = 6457}, + {closedWindow = 6460, openWindow = 6458}, + {closedWindow = 6458, openWindow = 6460}, + {closedWindow = 6461, openWindow = 6459}, + {closedWindow = 6459, openWindow = 6461}, + {closedWindow = 6464, openWindow = 6462}, + {closedWindow = 6462, openWindow = 6464}, + {closedWindow = 6465, openWindow = 6463}, + {closedWindow = 6463, openWindow = 6465}, + {closedWindow = 6468, openWindow = 6466}, + {closedWindow = 6466, openWindow = 6468}, + {closedWindow = 6469, openWindow = 6467}, + {closedWindow = 6467, openWindow = 6469}, + {closedWindow = 6472, openWindow = 6470}, + {closedWindow = 6470, openWindow = 6472}, + {closedWindow = 6473, openWindow = 6471}, + {closedWindow = 6471, openWindow = 6473}, + {closedWindow = 6790, openWindow = 6788}, + {closedWindow = 6788, openWindow = 6790}, + {closedWindow = 6791, openWindow = 6789}, + {closedWindow = 6789, openWindow = 6791}, + {closedWindow = 7027, openWindow = 7025}, + {closedWindow = 7025, openWindow = 7027}, + {closedWindow = 7028, openWindow = 7026}, + {closedWindow = 7026, openWindow = 7028}, + {closedWindow = 7031, openWindow = 7029}, + {closedWindow = 7029, openWindow = 7031}, + {closedWindow = 7032, openWindow = 7030}, + {closedWindow = 7030, openWindow = 7032}, + {closedWindow = 10264, openWindow = 10266}, + {closedWindow = 10266, openWindow = 10264}, + {closedWindow = 10265, openWindow = 10267}, + {closedWindow = 10267, openWindow = 10265}, + {closedWindow = 10488, openWindow = 10490}, + {closedWindow = 10490, openWindow = 10488}, + {closedWindow = 10489, openWindow = 10491}, + {closedWindow = 10491, openWindow = 10489}, + {closedWindow = 19427, openWindow = 19447}, + {closedWindow = 19428, openWindow = 19448}, + {closedWindow = 19441, openWindow = 19450}, + {closedWindow = 19440, openWindow = 19449}, + {closedWindow = 19443, openWindow = 20180}, + {closedWindow = 19444, openWindow = 20181}, + {closedWindow = 19445, openWindow = 20183}, + {closedWindow = 19446, openWindow = 20184}, + {closedWindow = 19447, openWindow = 19427}, + {closedWindow = 19448, openWindow = 19428}, + {closedWindow = 19449, openWindow = 19440}, + {closedWindow = 19450, openWindow = 19441}, + {closedWindow = 19974, openWindow = 20182}, + {closedWindow = 19975, openWindow = 20185}, + {closedWindow = 20180, openWindow = 19443}, + {closedWindow = 20181, openWindow = 19444}, + {closedWindow = 20182, openWindow = 19974}, + {closedWindow = 20183, openWindow = 19445}, + {closedWindow = 20184, openWindow = 19446}, + {closedWindow = 20185, openWindow = 19975}, + {closedWindow = 22838, openWindow = 22812}, + {closedWindow = 22839, openWindow = 22813}, + {closedWindow = 35652, openWindow = 35708}, + {closedWindow = 35653, openWindow = 35711}, + {closedWindow = 35709, openWindow = 35710}, + {closedWindow = 35712, openWindow = 35713}, + {closedWindow = 38465, openWindow = 38463}, + {closedWindow = 38466, openWindow = 38464}, + {closedWindow = 38475, openWindow = 38473}, + {closedWindow = 38476, openWindow = 38474}, + {closedWindow = 38479, openWindow = 38477}, + {closedWindow = 38480, openWindow = 38478} +} diff --git a/data/logs/.gitignore b/data/logs/.gitignore new file mode 100644 index 00000000000..5e7d2734cfc --- /dev/null +++ b/data/logs/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/data/migrations/0.lua b/data/migrations/0.lua new file mode 100644 index 00000000000..9329e31facd --- /dev/null +++ b/data/migrations/0.lua @@ -0,0 +1,14 @@ +function onUpdateDatabase() + Spdlog.info("Updating database to version 1 (sample players)") + -- Rook Sample + db.query("UPDATE `players` SET `level` = 2, `vocation` = 0, `health` = 155, `healthmax` = 155, `experience` = 100, `soul` = 100, `lookbody` = 113, `lookfeet` = 115, `lookhead` = 95, `looklegs` = 39, `looktype` = 129, `mana` = 60, `manamax` = 60, `town_id` = 1, `cap` = 410 WHERE `id` = 1;") + -- Sorcerer Sample + db.query("UPDATE `players` SET `level` = 8, `vocation` = 1, `health` = 185, `healthmax` = 185, `experience` = 4200, `soul` = 100, `lookbody` = 113, `lookfeet` = 115, `lookhead` = 95, `looklegs` = 39, `looktype` = 129, `mana` = 90, `manamax` = 90, `town_id` = 8, `cap` = 470 WHERE `id` = 2;") + -- Druid Sample + db.query("UPDATE `players` SET `level` = 8, `vocation` = 2, `health` = 185, `healthmax` = 185, `experience` = 4200, `soul` = 100, `lookbody` = 113, `lookfeet` = 115, `lookhead` = 95, `looklegs` = 39, `looktype` = 129, `mana` = 90, `manamax` = 90, `town_id` = 8, `cap` = 470 WHERE `id` = 3;") + -- Paladin Sample + db.query("UPDATE `players` SET `level` = 8, `vocation` = 3, `health` = 185, `healthmax` = 185, `experience` = 4200, `soul` = 100, `lookbody` = 113, `lookfeet` = 115, `lookhead` = 95, `looklegs` = 39, `looktype` = 129, `mana` = 90, `manamax` = 90, `town_id` = 8, `cap` = 470 WHERE `id` = 4;") + -- Knight Sample + db.query("UPDATE `players` SET `level` = 8, `vocation` = 4, `health` = 185, `healthmax` = 185, `experience` = 4200, `soul` = 100, `lookbody` = 113, `lookfeet` = 115, `lookhead` = 95, `looklegs` = 39, `looktype` = 129, `mana` = 90, `manamax` = 90, `town_id` = 8, `cap` = 470 WHERE `id` = 5;") + return true +end diff --git a/data/migrations/1.lua b/data/migrations/1.lua new file mode 100644 index 00000000000..b350d1949ed --- /dev/null +++ b/data/migrations/1.lua @@ -0,0 +1,26 @@ +function onUpdateDatabase() + Spdlog.info("Updating database to version 2 (hireling)") + + db.query([[ + CREATE TABLE IF NOT EXISTS `player_hirelings` ( + `id` INT NOT NULL PRIMARY KEY auto_increment, + `player_id` INT NOT NULL, + `name` varchar(255), + `active` tinyint unsigned NOT NULL DEFAULT '0', + `sex` tinyint unsigned NOT NULL DEFAULT '0', + `posx` int(11) NOT NULL DEFAULT '0', + `posy` int(11) NOT NULL DEFAULT '0', + `posz` int(11) NOT NULL DEFAULT '0', + `lookbody` int(11) NOT NULL DEFAULT '0', + `lookfeet` int(11) NOT NULL DEFAULT '0', + `lookhead` int(11) NOT NULL DEFAULT '0', + `looklegs` int(11) NOT NULL DEFAULT '0', + `looktype` int(11) NOT NULL DEFAULT '136', + + FOREIGN KEY(`player_id`) REFERENCES `players`(`id`) + ON DELETE CASCADE + ) + ]]) + + return true +end diff --git a/data/migrations/10.lua b/data/migrations/10.lua new file mode 100644 index 00000000000..9076a3138c9 --- /dev/null +++ b/data/migrations/10.lua @@ -0,0 +1,5 @@ +function onUpdateDatabase() + Spdlog.info("Updating database to version 11 (Guilds Balance)") + db.query("ALTER TABLE `guilds` ADD `balance` bigint(20) UNSIGNED NOT NULL DEFAULT '0';") + return true +end diff --git a/data/migrations/11.lua b/data/migrations/11.lua new file mode 100644 index 00000000000..c7a412f9a1a --- /dev/null +++ b/data/migrations/11.lua @@ -0,0 +1,5 @@ +function onUpdateDatabase() + Spdlog.info("Updating database to version 12 (Player get daily reward)") + db.query("ALTER TABLE `players` ADD `isreward` tinyint(1) NOT NULL DEFAULT 1") + return true +end diff --git a/data/migrations/12.lua b/data/migrations/12.lua new file mode 100644 index 00000000000..7d7707f7642 --- /dev/null +++ b/data/migrations/12.lua @@ -0,0 +1,11 @@ +function onUpdateDatabase() + Spdlog.info("Updating database to version 13 (Boosted Creature Outfit)") + db.query("ALTER TABLE boosted_creature ADD `looktype` int(11) NOT NULL DEFAULT 136;") + db.query("ALTER TABLE boosted_creature ADD `lookfeet` int(11) NOT NULL DEFAULT 0;") + db.query("ALTER TABLE boosted_creature ADD `looklegs` int(11) NOT NULL DEFAULT 0;") + db.query("ALTER TABLE boosted_creature ADD `lookhead` int(11) NOT NULL DEFAULT 0;") + db.query("ALTER TABLE boosted_creature ADD `lookbody` int(11) NOT NULL DEFAULT 0;") + db.query("ALTER TABLE boosted_creature ADD `lookaddons` int(11) NOT NULL DEFAULT 0;") + db.query("ALTER TABLE boosted_creature ADD `lookmount` int(11) DEFAULT 0;") + return true +end diff --git a/data/migrations/13.lua b/data/migrations/13.lua new file mode 100644 index 00000000000..8d6b832480c --- /dev/null +++ b/data/migrations/13.lua @@ -0,0 +1,5 @@ +function onUpdateDatabase() + Spdlog.info("Updating database to version 14 (Fixed mana spent)") + db.query("ALTER TABLE `players` CHANGE `manaspent` `manaspent` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0';") + return true +end diff --git a/data/migrations/14.lua b/data/migrations/14.lua new file mode 100644 index 00000000000..7d883468551 --- /dev/null +++ b/data/migrations/14.lua @@ -0,0 +1,6 @@ +function onUpdateDatabase() + Spdlog.info("Updating database to version 15 (Magic Shield Spell)") + db.query("ALTER TABLE `players` ADD `manashield` SMALLINT UNSIGNED NOT NULL DEFAULT '0' AFTER `skill_manaleech_amount`") + db.query("ALTER TABLE `players` ADD `max_manashield` SMALLINT UNSIGNED NOT NULL DEFAULT '0' AFTER `manashield`") + return true +end diff --git a/data/migrations/15.lua b/data/migrations/15.lua new file mode 100644 index 00000000000..838afd16ebe --- /dev/null +++ b/data/migrations/15.lua @@ -0,0 +1,8 @@ +function onUpdateDatabase() + Spdlog.info("Updating database to version 16 (Rook sample and GOD player values)") + -- Rook Sample + db.query("UPDATE `players` SET `maglevel` = 2, `manaspent` = 5936, `skill_club` = 12, `skill_club_tries` = 155, `skill_sword` = 12, `skill_sword_tries` = 155, `skill_axe` = 12, `skill_axe_tries` = 155, `skill_dist` = 12, `skill_dist_tries` = 93 WHERE `id` = 1;") + -- GOD + db.query("UPDATE `players` SET `health` = 155, `healthmax` = 155, `experience` = 100, `looktype` = 75, `town_id` = 8 WHERE `id` = 6;") + return true +end diff --git a/data/migrations/16.lua b/data/migrations/16.lua new file mode 100644 index 00000000000..7c6e195e3cb --- /dev/null +++ b/data/migrations/16.lua @@ -0,0 +1,5 @@ +function onUpdateDatabase() + print("> Updating database to version 17 (Tutorial support)") + db.query("ALTER TABLE `players` ADD `istutorial` SMALLINT(1) NOT NULL DEFAULT '0'") + return true -- true = There are others migrations file | false = this is the last migration file +end diff --git a/data/migrations/17.lua b/data/migrations/17.lua new file mode 100644 index 00000000000..2c7477d6803 --- /dev/null +++ b/data/migrations/17.lua @@ -0,0 +1,3 @@ +function onUpdateDatabase() + return false -- true = There are others migrations file | false = this is the last migration file +end diff --git a/data/migrations/2.lua b/data/migrations/2.lua new file mode 100644 index 00000000000..2ca1efd2520 --- /dev/null +++ b/data/migrations/2.lua @@ -0,0 +1,114 @@ +function onUpdateDatabase() + Spdlog.info("Updating database to version 3 (account refactor)") + + db.query([[ + LOCK TABLES + players WRITE, + account_bans WRITE, + account_ban_history WRITE, + account_viplist WRITE, + store_history WRITE, + accounts WRITE; + ]]) + + db.query([[ + ALTER TABLE `players` + DROP FOREIGN KEY `players_account_fk`, + MODIFY account_id int(11) UNSIGNED NOT NULL; + ]]) + + db.query([[ + ALTER TABLE `account_bans` + DROP PRIMARY KEY, + DROP FOREIGN KEY `account_bans_account_fk`, + MODIFY `account_id` int(11) UNSIGNED NOT NULL; + ]]) + + db.query([[ + ALTER TABLE `account_ban_history` + DROP FOREIGN KEY `account_bans_history_account_fk`, + MODIFY `account_id` int(11) UNSIGNED NOT NULL; + ]]) + + db.query([[ + ALTER TABLE `account_viplist` + DROP INDEX `account_viplist_unique`, + DROP FOREIGN KEY `account_viplist_account_fk`, + MODIFY `account_id` int(11) UNSIGNED NOT NULL; + ]]) + + db.query([[ + ALTER TABLE `store_history` + DROP FOREIGN KEY `store_history_account_fk`, + MODIFY `account_id` int(11) UNSIGNED NOT NULL; + ]]) + + db.query([[ + ALTER TABLE `accounts` + MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + MODIFY `type` tinyint(1) UNSIGNED NOT NULL DEFAULT '1', + MODIFY `coins` int(12) UNSIGNED NOT NULL DEFAULT '0', + MODIFY `creation` int(11) UNSIGNED NOT NULL DEFAULT '0'; + ]]) + + db.query([[ + ALTER TABLE `players` + ADD CONSTRAINT `players_account_fk` + FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) + ON DELETE CASCADE; + ]]) + + db.query([[ + ALTER TABLE `account_bans` + ADD CONSTRAINT `account_bans_pk` PRIMARY KEY (`account_id`), + ADD CONSTRAINT `account_bans_account_fk` + FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) + ON DELETE CASCADE + ON UPDATE CASCADE; + ]]) + + db.query([[ + ALTER TABLE `account_ban_history` + ADD CONSTRAINT `account_bans_history_account_fk` + FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) + ON DELETE CASCADE + ON UPDATE CASCADE; + ]]) + + db.query([[ + ALTER TABLE `account_viplist` + ADD CONSTRAINT `account_viplist_unique` UNIQUE (`account_id`, `player_id`), + ADD CONSTRAINT `account_viplist_account_fk` + FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) + ON DELETE CASCADE; + ]]) + + db.query([[ + ALTER TABLE `store_history` + ADD CONSTRAINT `store_history_account_fk` + FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) + ON DELETE CASCADE; + ]]) + + db.query([[ + UNLOCK TABLES; + ]]) + + db.query([[ + CREATE TABLE IF NOT EXISTS `coins_transactions` ( + `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `account_id` int(11) UNSIGNED NOT NULL, + `type` tinyint(1) UNSIGNED NOT NULL, + `amount` int(12) UNSIGNED NOT NULL, + `description` varchar(3500) NOT NULL, + `timestamp` timestamp DEFAULT CURRENT_TIMESTAMP, + INDEX `account_id` (`account_id`), + CONSTRAINT `coins_transactions_pk` PRIMARY KEY (`id`), + CONSTRAINT `coins_transactions_account_fk` + FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) + ON DELETE CASCADE + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + ]]) + + return true +end diff --git a/data/migrations/3.lua b/data/migrations/3.lua new file mode 100644 index 00000000000..72823844ee6 --- /dev/null +++ b/data/migrations/3.lua @@ -0,0 +1,9 @@ +function onUpdateDatabase() + Spdlog.info("Updating database to version 4 (prey tick)") + + db.query([[ + ALTER TABLE `prey_slots` + ADD `tick` smallint(3) NOT NULL DEFAULT '0'; + ]]) + return true +end diff --git a/data/migrations/4.lua b/data/migrations/4.lua new file mode 100644 index 00000000000..f646573f120 --- /dev/null +++ b/data/migrations/4.lua @@ -0,0 +1,10 @@ +function onUpdateDatabase() + Spdlog.info("Updating database to version 5 (boosted creature)") + db.query([[CREATE TABLE IF NOT EXISTS `boosted_creature` ( + `boostname` TEXT, + `date` varchar(250) NOT NULL DEFAULT '', + `raceid` varchar(250) NOT NULL DEFAULT '', + PRIMARY KEY (`date`) + ) AS SELECT 0 AS date, "default" AS boostname, 0 AS raceid]]) + return true +end diff --git a/data/migrations/5.lua b/data/migrations/5.lua new file mode 100644 index 00000000000..6bd29d4fa12 --- /dev/null +++ b/data/migrations/5.lua @@ -0,0 +1,5 @@ +function onUpdateDatabase() + Spdlog.info("Updating database to version 6 (quickloot)") + db.query("ALTER TABLE `players` ADD `quickloot_fallback` TINYINT DEFAULT 0") + return true +end diff --git a/data/migrations/6.lua b/data/migrations/6.lua new file mode 100644 index 00000000000..5b44ae63719 --- /dev/null +++ b/data/migrations/6.lua @@ -0,0 +1,8 @@ +function onUpdateDatabase() + Spdlog.info("Updating database to version 7 (Stash supply)") + db.query([[CREATE TABLE IF NOT EXISTS `player_stash` ( + `player_id` INT(16) NOT NULL, + `item_id` INT(16) NOT NULL, + `item_count` INT(32) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8;]]) + return true -- true = There are others migrations file | false = this is the last migration file +end diff --git a/data/migrations/7.lua b/data/migrations/7.lua new file mode 100644 index 00000000000..a546400f06e --- /dev/null +++ b/data/migrations/7.lua @@ -0,0 +1,5 @@ +function onUpdateDatabase() + Spdlog.info("Updating database to version 8 (recruiter system)") + db.query("ALTER TABLE `accounts` ADD `recruiter` INT(6) DEFAULT 0") + return true +end diff --git a/data/migrations/8.lua b/data/migrations/8.lua new file mode 100644 index 00000000000..2fc3ecbb4dc --- /dev/null +++ b/data/migrations/8.lua @@ -0,0 +1,30 @@ +function onUpdateDatabase() + Spdlog.info("Updating database to version 9 (Bestiary cpp)") + db.query([[CREATE TABLE IF NOT EXISTS `player_charms` ( +`player_guid` INT(250) NOT NULL , +`charm_points` VARCHAR(250) NULL , +`charm_expansion` BOOLEAN NULL , +`rune_wound` INT(250) NULL , +`rune_enflame` INT(250) NULL , +`rune_poison` INT(250) NULL , +`rune_freeze` INT(250) NULL , +`rune_zap` INT(250) NULL , +`rune_curse` INT(250) NULL , +`rune_cripple` INT(250) NULL , +`rune_parry` INT(250) NULL , +`rune_dodge` INT(250) NULL , +`rune_adrenaline` INT(250) NULL , +`rune_numb` INT(250) NULL, +`rune_cleanse` INT(250) NULL , +`rune_bless` INT(250) NULL , +`rune_scavenge` INT(250) NULL , +`rune_gut` INT(250) NULL , +`rune_low_blow` INT(250) NULL , +`rune_divine` INT(250) NULL , +`rune_vamp` INT(250) NULL , +`rune_void` INT(250) NULL , +`UsedRunesBit` VARCHAR(250) NULL , +`UnlockedRunesBit` VARCHAR(250) NULL, +`tracker list` BLOB NULL ) ENGINE = InnoDB DEFAULT CHARSET=utf8;]]) + return true -- true = There are others migrations file | false = this is the last migration file +end diff --git a/data/migrations/9.lua b/data/migrations/9.lua new file mode 100644 index 00000000000..d87dd56642a --- /dev/null +++ b/data/migrations/9.lua @@ -0,0 +1,9 @@ +function onUpdateDatabase() + Spdlog.info("Updating database to version 10 (Mount Colors and familiars)") + db.query("ALTER TABLE `players` ADD `lookmountbody` tinyint(3) unsigned NOT NULL DEFAULT '0'") + db.query("ALTER TABLE `players` ADD `lookmountfeet` tinyint(3) unsigned NOT NULL DEFAULT '0'") + db.query("ALTER TABLE `players` ADD `lookmounthead` tinyint(3) unsigned NOT NULL DEFAULT '0'") + db.query("ALTER TABLE `players` ADD `lookmountlegs` tinyint(3) unsigned NOT NULL DEFAULT '0'") + db.query("ALTER TABLE `players` ADD `lookfamiliarstype` int(11) unsigned NOT NULL DEFAULT '0'") + return true +end diff --git a/data/modules/lib/modules.lua b/data/modules/lib/modules.lua new file mode 100644 index 00000000000..3872b0ea766 --- /dev/null +++ b/data/modules/lib/modules.lua @@ -0,0 +1,28 @@ +function addPlayerEvent(callable, delay, playerId, ...) + local player = Player(playerId) + if not player then + return false + end + + addEvent(function(callable, playerId, ...) + local player = Player(playerId) + if player then + pcall(callable, player, ...) + end + end, delay, callable, player.uid, ...) +end + +--[[ +function Player.updateFightModes(self) + local msg = NetworkMessage() + + msg:addByte(0xA7) + + msg:addByte(self:getFightMode()) + msg:addByte(self:getChaseMode()) + msg:addByte(self:getSecureMode() and 1 or 0) + msg:addByte(self:getPvpMode()) + + msg:sendToPlayer(self) +end +]] diff --git a/data/modules/modules.xml b/data/modules/modules.xml new file mode 100644 index 00000000000..e90e6c43b82 --- /dev/null +++ b/data/modules/modules.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/modules/scripts/blessings/assets.lua b/data/modules/scripts/blessings/assets.lua new file mode 100644 index 00000000000..1ccd2e14ac9 --- /dev/null +++ b/data/modules/scripts/blessings/assets.lua @@ -0,0 +1,49 @@ +Blessings.Types = { + REGULAR = 1, + ENHANCED = 2, + PvP = 3 +} + +Blessings.All = { + [1] = {id = 1, name = "Twist of Fate", type = Blessings.Types.PvP}, + [2] = {id = 2, name = "The Wisdom of Solitude", charm = 11262, type = Blessings.Types.REGULAR, losscount = true, inquisition = true}, + [3] = {id = 3, name = "The Spark of the Phoenix", charm = 11258, type = Blessings.Types.REGULAR, losscount = true, inquisition = true}, + [4] = {id = 4, name = "The Fire of the Suns", charm = 11261, type = Blessings.Types.REGULAR, losscount = true, inquisition = true}, + [5] = {id = 5, name = "The Spiritual Shielding", charm = 11260, type = Blessings.Types.REGULAR, losscount = true, inquisition = true}, + [6] = {id = 6, name = "The Embrace of Tibia", charm = 11259, type = Blessings.Types.REGULAR, losscount = true, inquisition = true}, + [7] = {id = 7, name = "Blood of the Mountain", charm = 28036, type = Blessings.Types.ENHANCED, losscount = true, inquisition = false}, + [8] = {id = 8, name = "Heart of the Mountain", charm = 28037, type = Blessings.Types.ENHANCED, losscount = true, inquisition = false} +} + + +Blessings.LossPercent = { + [0] = {item = 100, skill = 0}, + [1] = {item = 70, skill = 8}, + [2] = {item = 45, skill = 16}, + [3] = {item = 25, skill = 24}, + [4] = {item = 10, skill = 32}, + [5] = {item = 0, skill = 40}, + [6] = {item = 0, skill = 48}, + [7] = {item = 0, skill = 56}, + [8] = {item = 0, skill = 56} +} + + +Blessings.BitWiseTable = { + [0] = 1, + [1] = 2, + [2] = 4, + [3] = 8, + [4] = 16, + [5] = 32, + [6] = 64, + [7] = 128, + [8] = 256, + [9] = 512, + [10] = 1024, + [11] = 2048, + [12] = 4096, + [13] = 8192, + [14] = 16384, + [15] = 32768 +} \ No newline at end of file diff --git a/data/modules/scripts/blessings/blessings.lua b/data/modules/scripts/blessings/blessings.lua new file mode 100644 index 00000000000..be0fd6010d4 --- /dev/null +++ b/data/modules/scripts/blessings/blessings.lua @@ -0,0 +1,395 @@ +Blessings = {} + +Blessings.Credits = { + Developer = "Charles (Cjaker), DudZ", + Version = "2.0", + lastUpdate = "08/04/2020", + todo = { + "Insert & Select query in blessings_history", + "Add unfair fight reductio (convert the get killer is pvp fight with getDamageMap of dead player)", + "Gamestore buy blessing", + "Test ank print text", + "Test all functions", + "Test henricus prices/blessings", + "Add data \\movements\\scripts\\quests\\cults of tibia\\icedeath.lua blessing information", + "WotE data\\movements\\scripts\\quests\\wrath of the emperor\\realmTeleport.lua has line checking if player has bless 1??? wtf", + "add blessings module support npc\\lib\\npcsystem\\modules.lua", + "Fix store buying bless", + "Check if store is inside lua or source..." + } +} + +Blessings.Config = { + AdventurerBlessingLevel = 0, -- Free full bless until level + HasToF = false, -- Enables/disables twist of fate + InquisitonBlessPriceMultiplier = 1.1, -- Bless price multiplied by henricus + SkulledDeathLoseStoreItem = true, -- Destroy all items on store when dying with red/blackskull + InventoryGlowOnFiveBless = true, -- Glow in yellow inventory items when the player has 5 or more bless, + Debug = false -- Prin debug messages in console if enabled +} + +dofile('data/modules/scripts/blessings/assets.lua') + +--[=====[ +-- +-- Table structure `blessings_history` +-- + +CREATE TABLE IF NOT EXISTS `blessings_history` ( + `id` int(11) NOT NULL, + `player_id` int(11) NOT NULL, + `blessing` tinyint(4) NOT NULL, + `loss` tinyint(1) NOT NULL, + `timestamp` int(11) NOT NULL, + CONSTRAINT `blessings_history_pk` PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +--]=====] + +Blessings.DebugPrint = function(content, pre, pos) + if not Blessings.Config.Debug then + return + end + if pre == nil then + pre = "" + else + pre = pre.. " " + end + if pos == nil then + pos = "" + else + pos = " " .. pos + end + if type(content) == "boolean" then + Spdlog.debug(string.format("[Blessings] START BOOL - %s", pre)) + Spdlog.debug(content) + Spdlog.debug(string.format("[Blessings] END BOOL - %s", pos)) + else + Spdlog.debug(string.format("[Blessings] pre:[%s], content[%s], pos[%s]", + pre, content, pos)) + end +end + +Blessings.C_Packet = { + OpenWindow = 0xCF +} + +Blessings.S_Packet = { + BlessDialog = 0x9B, + BlessStatus = 0x9C +} + +function onRecvbyte(player, msg, byte) + if (byte == Blessings.C_Packet.OpenWindow) then + Blessings.sendBlessDialog(player) + end +end + +Blessings.sendBlessStatus = function(player, curBless) + -- why not using ProtocolGame::sendBlessStatus ? + local msg = NetworkMessage() + msg:addByte(Blessings.S_Packet.BlessStatus) + callback = function(k) return true end + if curBless == nil then + curBless = player:getBlessings(callback) -- ex: {1, 2, 5, 7} + end + Blessings.DebugPrint(#curBless, "sendBlessStatus curBless") + local bitWiseCurrentBless = 0 + local blessCount = 0 + + for i = 1, #curBless do + if curBless[i].losscount then + blessCount = blessCount + 1 + end + if (not curBless[i].losscount and Blessings.Config.HasToF) or curBless[i].losscount then + bitWiseCurrentBless = bit.bor(bitWiseCurrentBless, Blessings.BitWiseTable[curBless[i].id]) + end + end + + if blessCount > 5 and Blessings.Config.InventoryGlowOnFiveBless then + bitWiseCurrentBless = bit.bor(bitWiseCurrentBless, 1) + end + + msg:addU16(bitWiseCurrentBless) + msg:addByte(blessCount >= 7 and 3 or (blessCount > 0 and 2 or 1)) -- Bless dialog button colour 1 = Disabled | 2 = normal | 3 = green + + -- if #curBless >= 5 then + -- msg:addU16(1) -- TODO ? + -- else + -- msg:addU16(0) + -- end + + msg:sendToPlayer(player) +end + +Blessings.sendBlessDialog = function(player) + -- TODO: Migrate to protocolgame.cpp + local msg = NetworkMessage() + msg:addByte(Blessings.S_Packet.BlessDialog) + + callback = function(k) return true end + local curBless = player:getBlessings() + + msg:addByte(Blessings.Config.HasToF and #Blessings.All or (#Blessings.All - 1)) -- total blessings + for k = 1, #Blessings.All do + v = Blessings.All[k] + if v.type ~= Blessings.Types.PvP or Blessings.Config.HasToF then + msg:addU16(Blessings.BitWiseTable[v.id]) + msg:addByte(player:getBlessingCount(v.id)) + msg:addByte(0) -- Store Blessings Count + end + end + + local promotion = (player:isPremium() and player:isPromoted()) and 30 or 0 + local PvPminXPLoss = Blessings.LossPercent[#curBless].skill + promotion + local PvPmaxXPLoss = PvPminXPLoss + if Blessings.Config.HasToF then + PvPmaxXPLoss = math.floor(PvPminXPLoss * 1.15) + end + local PvEXPLoss = PvPminXPLoss + + local playerAmulet = player:getSlotItem(CONST_SLOT_NECKLACE) + local haveSkull = player:getSkull() >= 4 + hasAol = (playerAmulet and playerAmulet:getId() == ITEM_AMULETOFLOSS) + + equipLoss = Blessings.LossPercent[#curBless].item + if haveSkull then + equipLoss = 100 + elseif hasAol then + equipLoss = 0 + end + + msg:addByte(2) -- BYTE PREMIUM (only work with premium days) + msg:addByte(promotion) -- XP Loss Lower POR SER PREMIUM + msg:addByte(PvPminXPLoss) -- XP/Skill loss min pvp death + msg:addByte(PvPmaxXPLoss) -- XP/Skill loss max pvp death + msg:addByte(PvEXPLoss) -- XP/Skill pve death + msg:addByte(equipLoss) -- Equip container lose pvp death + msg:addByte(equipLoss) -- Equip container pve death + + msg:addByte(haveSkull and 1 or 0) -- is red/black skull + msg:addByte(hasAol and 1 or 0) + + + -- History + local historyAmount = 1 + msg:addByte(historyAmount) -- History log count + for i = 1, historyAmount do + msg:addU32(os.time()) -- timestamp + msg:addByte(0) -- Color message (1 - Red | 0 = White loss) + msg:addString("Blessing Purchased") -- History message + end + + msg:sendToPlayer(player) +end + +Blessings.getBlessingsCost = function(level) + if level <= 30 then + return 2000 + elseif level >= 120 then + return 20000 + else + return (level - 20) * 200 + end +end + +Blessings.getPvpBlessingCost = function(level) + if level <= 30 then + return 2000 + elseif level >= 270 then + return 50000 + else + return (level - 20) * 200 + end +end + +Blessings.useCharm = function(player, item) + for index, value in pairs(Blessings.All) do + if item.itemid == value.charm then + if not value then + return true + end + + if player:hasBlessing(value.id) then + player:say('You already possess this blessing.', TALKTYPE_MONSTER_SAY) + return true + end + + player:addBlessing(value.id, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, value.name .. ' protects you.') + player:getPosition():sendMagicEffect(CONST_ME_LOSEENERGY) + item:remove(1) + return true + end + end +end + +Blessings.checkBless = function(player) + local result, bless = 'Received blessings:' + for k, v in pairs(Blessings.All) do + result = player:hasBlessing(k) and result .. '\n' .. v.name or result + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 20 > result:len() and 'No blessings received.' or result) + return true +end + +Blessings.doAdventurerBlessing = function(player) + if player:getLevel() > Blessings.Config.AdventurerBlessingLevel then + return true + end + player:addMissingBless(true, true) + + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,'You received adventurers blessings for you being level lower than ' .. Blessings.Config.AdventurerBlessingLevel .. '!') + player:getPosition():sendMagicEffect(CONST_ME_HOLYDAMAGE) + return true +end + +Blessings.getInquisitionPrice = function(player) + -- Find how many missing bless we have and give out the price + inquifilter = function(b) return b.inquisition end + donthavefilter = function(p, b) return not p:hasBlessing(b) end + local missing = #player:getBlessings(filter, donthavefilter) + local totalBlessPrice = Blessings.getBlessingsCost(player:getLevel()) * missing * Blessings.Config.InquisitonBlessPriceMultiplier + return missing, totalBlessPrice +end + +Blessings.DropLoot = function(player, corpse, chance, skulled) + local multiplier = 100 -- Improve the loot randomness spectrum + math.randomseed(os.time()) -- Improve the loot randomness spectrum + chance = chance * multiplier + Blessings.DebugPrint(chance, "DropLoot chance") + for i = CONST_SLOT_HEAD, CONST_SLOT_AMMO do + local item = player:getSlotItem(i) + if item then + local thisChance = chance + local thisRandom = math.random(100*multiplier) + if not item:isContainer() then + thisChance = chance/10 + end + Blessings.DebugPrint(thisChance/multiplier .. "%" .. " | thisRandom "..thisRandom/multiplier.."%", "DropLoot item "..item:getName() .. " |") + if skulled or thisRandom <= thisChance then + Blessings.DebugPrint("Dropped "..item:getName()) + item:moveTo(corpse) + end + end + end + if skulled and Blessings.Config.SkulledDeathLoseStoreItem then + local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX) + local inboxsize = inbox:getSize() - 1 + for i = 0, inboxsize do + inbox:getItem(i):destroy() + end + end +end + +Blessings.ClearBless = function(player, killer, currentBless) + Blessings.DebugPrint(#currentBless, "ClearBless #currentBless") + local hasToF = Blessings.Config.HasToF and player:hasBlessing(1) or false + if hasToF and killer (killer:isPlayer() or (killer:getMaster() and killer:getMaster():isPlayer())) then -- TODO add better check if its pvp or pve + player:removeBlessing(1) + return + end + for i = 1, #currentBless do + + Blessings.DebugPrint(i, "ClearBless curBless i", " | "..currentBless[i].name) + player:removeBlessing(currentBless[i].id, 1) + end +end + + +Blessings.BuyAllBlesses = function(player) + if not Tile(player:getPosition()):hasFlag(TILESTATE_PROTECTIONZONE) and (player:isPzLocked() or player:getCondition(CONDITION_INFIGHT, CONDITIONID_DEFAULT)) then + player:sendCancelMessage("You can't buy bless while in battle.") + player:getPosition():sendMagicEffect(CONST_ME_POFF) + return + end + + local blessCost = Blessings.getBlessingsCost(player:getLevel()) + local PvPBlessCost = Blessings.getPvpBlessingCost(player:getLevel()) + local hasToF = Blessings.Config.HasToF and player:hasBlessing(1) or true + donthavefilter = function(p, b) return not p:hasBlessing(b) end + local missingBless = player:getBlessings(nil,donthavefilter) + local missingBlessAmt = #missingBless + (hasToF and 0 or 1) + local totalCost = blessCost * #missingBless + + if missingBlessAmt == 0 then + player:sendCancelMessage("You are already blessed.") + player:getPosition():sendMagicEffect(CONST_ME_POFF) + return + end + if not hasToF then + totalCost = totalCost + PvPBlessCost + end + + if player:removeMoneyNpc(totalCost) then + for i, v in ipairs(missingBless) do + player:addBlessing(v.id, 1) + end + player:sendCancelMessage("You received the remaining " .. missingBlessAmt .. " blesses for a total of " .. totalCost .." gold.") + player:getPosition():sendMagicEffect(CONST_ME_HOLYAREA) + else + player:sendCancelMessage("You don't have enough money. You need " .. totalCost .. " to buy all blesses.", cid) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + end + +end + +Blessings.PlayerDeath = function(player, corpse, killer) + local hasToF = Blessings.Config.HasToF and player:hasBlessing(1) or false + local hasAol = (player:getSlotItem(CONST_SLOT_NECKLACE) and player:getSlotItem(CONST_SLOT_NECKLACE):getId() == ITEM_AMULETOFLOSS) + local haveSkull = isInArray({SKULL_RED, SKULL_BLACK}, player:getSkull()) + local curBless = player:getBlessings() + + if haveSkull then -- lose all bless + drop all items + Blessings.DropLoot(player, corpse, 100, true) + elseif #curBless < 5 and not hasAol then -- lose all items + local equipLoss = Blessings.LossPercent[#curBless].item + Blessings.DropLoot(player, corpse, equipLoss) + elseif #curBless < 5 and hasAol and not hasToF then + player:removeItem(ITEM_AMULETOFLOSS, 1, -1, false) + end + --Blessings.ClearBless(player, killer, curBless) IMPLEMENTED IN SOURCE BECAUSE THIS WAS HAPPENING BEFORE SKILL/EXP CALCULATIONS + + + if not player:getSlotItem(CONST_SLOT_BACKPACK) then + player:addItem(ITEM_BAG, 1, false, CONST_SLOT_BACKPACK) + end + + return true +end + +function Player.getBlessings(self, filter, hasblessingFilter) + local blessings = {} + if filter == nil then + filter = function(b) return b.losscount end + end + + if hasblessingFilter == nil then + hasblessingFilter = function(p, b) return p:hasBlessing(b) end + end + for k, v in pairs(Blessings.All) do + if filter(v) and hasblessingFilter(self, k) then + table.insert(blessings, v) + end + end + return blessings +end + +function Player.addMissingBless(self, all, tof) + if all == nil then + all = true + end + if tof == nil then + tof = false + elseif tof then + tof = tof and Blessings.Config.HasToF + end + for k, v in pairs(Blessings.All) do + if all or (v.type == Blessings.Types.REGULAR) or (tof and v.type == Blessings.Types.PvP) then + if not self:hasBlessing(k) then + self:addBlessing(k, 1) + end + end + end + Blessings.sendBlessStatus(self) +end diff --git a/data/modules/scripts/cults_of_tibia/death.lua b/data/modules/scripts/cults_of_tibia/death.lua new file mode 100644 index 00000000000..206fc81b1e8 --- /dev/null +++ b/data/modules/scripts/cults_of_tibia/death.lua @@ -0,0 +1,13 @@ +function onRecvbyte(player, msg, byte) + if player then + local storageDeathFake = player:getStorageValue(Storage.CultsOfTibia.Barkless.Death) + if storageDeathFake == 1 then + player:setStorageValue(Storage.CultsOfTibia.Barkless.Death, 0) + player:addHealth(player:getMaxHealth()) + player:addMana(player:getMaxMana()) + player:setHiddenHealth(false) + player:removeCondition(CONDITION_OUTFIT) + player:teleportTo(player:getTown():getTemplePosition(), true) + end + end +end diff --git a/data/modules/scripts/daily_reward/daily_reward.lua b/data/modules/scripts/daily_reward/daily_reward.lua new file mode 100644 index 00000000000..8777ccf6aff --- /dev/null +++ b/data/modules/scripts/daily_reward/daily_reward.lua @@ -0,0 +1,646 @@ +DailyRewardSystem = { + Developer = "Westwol, Marcosvf132", + Version = "1.3", + lastUpdate = "12/10/2020 - 20:30", + ToDo = "Move this system to CPP" +} + +local ServerPackets = { + ShowDialog = 0xED, -- universal + DailyRewardCollectionState = 0xDE, -- undone + OpenRewardWall = 0xE2, -- Done + CloseRewardWall = 0xE3, -- is it necessary? + DailyRewardBasic = 0xE4, -- Done + DailyRewardHistory = 0xE5, -- Done + -- RestingAreaState = 0xA9 -- Moved to cpp +} + +local ClientPackets = { + OpenRewardWall = 0xD8, + OpenRewardHistory = 0xD9, + SelectReward = 0xDA, + CollectionResource = 0x14, + JokerResource = 0x15 +} + +--[[-- Constants +Please do not edit any of the next constants: + ]] + +--[[ Overall ]]-- +local DAILY_REWARD_COUNT = 7 +local REWARD_FROM_SHRINE = 0 +local REWARD_FROM_PANEL = 1 + +--[[ Bonuses ]] -- +local DAILY_REWARD_NONE = 1 +local DAILY_REWARD_HP_REGENERATION = 2 +local DAILY_REWARD_MP_REGENERATION = 3 +local DAILY_REWARD_STAMINA_REGENERATION = 4 +local DAILY_REWARD_DOUBLE_HP_REGENERATION = 5 +local DAILY_REWARD_DOUBLE_MP_REGENERATION = 6 +local DAILY_REWARD_SOUL_REGENERATION = 7 + +--[[ Reward Types ]] -- + +-- Server Types +local DAILY_REWARD_TYPE_ITEM = 1 +local DAILY_REWARD_TYPE_STORAGE = 2 +local DAILY_REWARD_TYPE_PREY_REROLL = 3 +local DAILY_REWARD_TYPE_XP_BOOST = 4 + +-- Client Types +local DAILY_REWARD_SYSTEM_SKIP = 1 +local DAILY_REWARD_SYSTEM_TYPE_ONE = 1 +local DAILY_REWARD_SYSTEM_TYPE_TWO = 2 +local DAILY_REWARD_SYSTEM_TYPE_OTHER = 1 +local DAILY_REWARD_SYSTEM_TYPE_PREY_REROLL = 2 +local DAILY_REWARD_SYSTEM_TYPE_XP_BOOST = 3 + +--[[ Account Status ]] -- +local DAILY_REWARD_STATUS_FREE = 0 +local DAILY_REWARD_STATUS_PREMIUM = 1 + +local DailyRewardItems = { + [0] = {7618, 7620}, -- God/no vocation character + [VOCATION.CLIENT_ID.PALADIN] = {7618, 7588, 7620, 7589, 8472, 26030, 2316, 2274, 2291, 2266, 2310, 2262, 2277, 2313, 2305, 2301, 2303, 2302, 2304, 2271, 2265, 2293, 2286, 2289, 2308, 2288, 2268, 2315}, + [VOCATION.CLIENT_ID.DRUID] = {7618, 7620, 7589, 7590, 26029, 2316, 2274, 2291, 2266, 2310, 2262, 2277, 2313, 2305, 2301, 2303, 2302, 2269, 2304, 2271, 2265, 2293, 2286, 2289, 2308, 2288, 2268, 2315}, + [VOCATION.CLIENT_ID.SORCERER] = {7618, 7620, 7589, 7590, 26029, 2316, 2274, 2291, 2266, 2310, 2262, 2277, 2313, 2305, 2301, 2303, 2302, 2304, 2271, 2265, 2293, 2286, 2289, 2308, 2288, 2268, 2315}, + [VOCATION.CLIENT_ID.KNIGHT] = {7618, 7588, 7591, 8473, 26031, 7620, 2316, 2274, 2291, 2266, 2310, 2262, 2277, 2313, 2305, 2301, 2303, 2302, 2304, 2271, 2265, 2293, 2286, 2289, 2308, 2288, 2268, 2315}, +} + +DailyReward = { + testMode = false, + serverTimeThreshold = (24 * 60 * 60), -- Counting down 24hours from last server save + + storages = { + -- Player + currentDayStreak = 14897, + currentStreakLevel = 14898, -- Cpp uses the same storage value on const.h (STORAGEVALUE_DAILYREWARD) + nextRewardTime = 14899, + collectionTokens = 14901, + staminaBonus = 14902, + jokerTokens = 14903, + -- Global + lastServerSave = 14110, + avoidDouble = 13412, + notifyReset = 13413, + avoidDoubleJoker = 13414 + }, + + strikeBonuses = { + -- day + [1] = {text = "No bonus for first day"}, + [2] = {text = "Allow Hit Point Regeneration"}, + [3] = {text = "Allow Mana Regeneration"}, + [4] = {text = "Stamina Regeneration"}, + [5] = {text = "Double Hit Point Regeneration"}, + [6] = {text = "Double Mana Regeneration"}, + [7] = {text = "Soul Points Regeneration"} + }, + + rewards = { + -- day + [1] = { + type = DAILY_REWARD_TYPE_ITEM, + systemType = DAILY_REWARD_SYSTEM_TYPE_ONE, + freeAccount = 5, + premiumAccount = 10 + }, + [2] = { + type = DAILY_REWARD_TYPE_ITEM, + systemType = DAILY_REWARD_SYSTEM_TYPE_ONE, + freeAccount = 5, + premiumAccount = 10 + }, + [3] = { + type = DAILY_REWARD_TYPE_PREY_REROLL, + systemType = DAILY_REWARD_SYSTEM_TYPE_TWO, + freeAccount = 1, + premiumAccount = 2 + }, + [4] = { + type = DAILY_REWARD_TYPE_ITEM, + systemType = DAILY_REWARD_SYSTEM_TYPE_ONE, + freeAccount = 10, + premiumAccount = 20 + }, + [5] = { + type = DAILY_REWARD_TYPE_PREY_REROLL, + systemType = DAILY_REWARD_SYSTEM_TYPE_TWO, + freeAccount = 1, + premiumAccount = 2 + }, + [6] = { + type = DAILY_REWARD_TYPE_ITEM, + systemType = DAILY_REWARD_SYSTEM_TYPE_ONE, + items = {32124, 32125, 32126, 32127, 32128, 32129}, + freeAccount = 1, + premiumAccount = 2, + itemCharges = 50 + }, + [7] = { + type = DAILY_REWARD_TYPE_XP_BOOST, + systemType = DAILY_REWARD_SYSTEM_TYPE_TWO, + freeAccount = 10, + premiumAccount = 30 + } + -- Storage reward template + --[[[5] = { + type = DAILY_REWARD_TYPE_STORAGE, + systemType = DAILY_REWARD_SYSTEM_TYPE_TWO, + freeCount = 1, + premiumCount = 2, + freeAccount = { + things = { + [1] = { + name = "task boost", + id = 1, -- this number can't be repeated + quantity = 1, + storages = { + {storageId = 23454, value = 1}, + {storageId = 45141, value = 2}, + {storageId = 45141, value = 3} + } + } + } + }, + premiumAccount = { + things = { + [1] = { + name = "task boostss", + id = 2, -- this number can't be repeated + quantity = 1, + storages = { + {storageId = 23454, value = 1} + } + }, + [2] = { + name = "another task boost", + id = 3, -- this number can't be repeated + quantity = 2, + storages = { + {storageId = 23454, value = 1}, + {storageId = 45141, value = 2}, + {storageId = 45141, value = 3} + } + } + } + } + },]] + } +} + +function onRecvbyte(player, msg, byte) + if (byte == ClientPackets.OpenRewardWall) then + DailyReward.loadDailyReward(player:getId(), REWARD_FROM_PANEL) + elseif (byte == ClientPackets.OpenRewardHistory) then + player:sendRewardHistory() + elseif (byte == ClientPackets.SelectReward) then + player:selectDailyReward(msg) + end +end + + +-- Core functions +DailyReward.insertHistory = function(playerId, dayStreak, description) + return db.query(string.format("INSERT INTO `daily_reward_history`(`player_id`, `daystreak`, `timestamp`, \z + `description`) VALUES (%s, %s, %s, %s)", playerId, dayStreak, os.time(), db.escapeString(description))) +end + +DailyReward.retrieveHistoryEntries = function(playerId) + + local player = Player(playerId) + if not player then + return false + end + + local entries = {} + local resultId = db.storeQuery("SELECT * FROM `daily_reward_history` WHERE `player_id` = \z + " .. player:getGuid() .. " ORDER BY `timestamp` DESC LIMIT 15;") + if resultId ~= false then + repeat + local entry = { + description = result.getDataString(resultId, "description"), + timestamp = result.getDataInt(resultId, "timestamp"), + daystreak = result.getDataInt(resultId, "daystreak"), + } + table.insert(entries, entry) + until not result.next(resultId) + result.free(resultId) + end + return entries +end + +DailyReward.loadDailyReward = function(playerId, source) + local player = Player(playerId) + if not player then + return false + end + if source ~= 0 then + source = REWARD_FROM_SHRINE + else + source = REWARD_FROM_PANEL + end + + player:sendCollectionResource(ClientPackets.JokerResource, player:getJokerTokens()) + player:sendCollectionResource(ClientPackets.CollectionResource, player:getCollectionTokens()) + player:sendDailyReward() + player:sendOpenRewardWall(source) + player:sendDailyRewardCollectionState(DailyReward.isRewardTaken(player:getId()) and DAILY_REWARD_COLLECTED or DAILY_REWARD_NOTCOLLECTED) + return true +end + +DailyReward.pickedReward = function(playerId) + local player = Player(playerId) + + if not player then + return false + end + + -- Reset day streak to 0 when reaches last reward + if player:getDayStreak() ~= 6 then + player:setDayStreak(player:getDayStreak() + 1) + else + player:setDayStreak(0) + end + + player:setStreakLevel(player:getStreakLevel() + 1) + player:setStorageValue(DailyReward.storages.avoidDouble, Game.getLastServerSave()) + player:setDailyReward(DAILY_REWARD_COLLECTED) + player:setNextRewardTime(Game.getLastServerSave() + DailyReward.serverTimeThreshold) + player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_YELLOW) + return true +end + +DailyReward.isShrine = function(source) + if source ~= 0 then + return false + else + return true + end +end + +function Player.iterateTest(self) + local dailyTable = DailyReward.rewards[5] + local reward = DailyRewardItems[self:getVocation():getClientId()] + + if not(reward) then + reward = {} + end + + for i = 1, #reward.things do + for j = 1, #reward.things[i].storages do + self:setStorageValue(reward.things[i].storages[j].storageId, reward.things[i].storages[j].value) + end + end +end + +DailyReward.isRewardTaken = function(playerId) + local player = Player(playerId) + if not player then + return false + end + local playerStorage = player:getStorageValue(DailyReward.storages.avoidDouble) + if playerStorage == Game.getLastServerSave() then + return true + end + return false +end + +DailyReward.init = function(playerId) + local player = Player(playerId) + + if not player then + return false + end + + if player:getJokerTokens() < 3 and tonumber(os.date("%m")) ~= player:getStorageValue(DailyReward.storages.avoidDoubleJoker) then + player:setStorageValue(DailyReward.storages.avoidDoubleJoker, tonumber(os.date("%m"))) + player:setJokerTokens(player:getJokerTokens() + 1) + end + + local timeMath = Game.getLastServerSave() - player:getNextRewardTime() + if player:getNextRewardTime() < Game.getLastServerSave() then + if player:getStorageValue(DailyReward.storages.notifyReset) ~= Game.getLastServerSave() then + player:setStorageValue(DailyReward.storages.notifyReset, Game.getLastServerSave()) + timeMath = math.ceil(timeMath/(DailyReward.serverTimeThreshold)) + if player:getJokerTokens() >= timeMath then + player:setJokerTokens(player:getJokerTokens() - timeMath) + player:sendTextMessage(MESSAGE_LOGIN, "You lost " .. timeMath .. " joker tokens to prevent loosing your streak.") + else + player:setStreakLevel(0) + if player:getLastLoginSaved() > 0 then -- message wont appear at first character login + player:setJokerTokens(-(player:getJokerTokens())) + player:sendTextMessage(MESSAGE_LOGIN, "You just lost your daily reward streak.") + end + end + end + end + + -- Daily reward golden icon + if DailyReward.isRewardTaken(player:getId()) then + player:sendDailyRewardCollectionState(DAILY_REWARD_COLLECTED) + player:setDailyReward(DAILY_REWARD_COLLECTED) + else + player:sendDailyRewardCollectionState(DAILY_REWARD_NOTCOLLECTED) + player:setDailyReward(DAILY_REWARD_NOTCOLLECTED) + end + player:loadDailyRewardBonuses() +end + +DailyReward.processReward = function(playerId, source) + DailyReward.pickedReward(playerId) + DailyReward.loadDailyReward(playerId, source) + local player = Player(playerId) + if player then + player:loadDailyRewardBonuses() + end + return true +end + +function Player.sendOpenRewardWall(self, shrine) + local msg = NetworkMessage() + msg:addByte(ServerPackets.OpenRewardWall) -- initial packet + msg:addByte(shrine) -- isPlayer taking bonus from reward shrine (1) - taking it from a instant bonus reward (0) + if DailyReward.testMode or not(DailyReward.isRewardTaken(self:getId())) then + msg:addU32(0) + else + msg:addU32(Game.getLastServerSave() + DailyReward.serverTimeThreshold) + end + msg:addByte(self:getDayStreak()) -- current reward? day = 0, day 1, ... this should be resetted to 0 every week imo + if DailyReward.isRewardTaken(self:getId()) then -- state (player already took reward? but just make sure noone wpe) + msg:addByte(1) + msg:addString("Sorry, you have already taken your daily reward or you are unable to collect it.") -- Unknown message + if self:getJokerTokens() > 0 then + msg:addByte(1) + msg:addU16(self:getJokerTokens()) + else + msg:addByte(0) + end + else + msg:addByte(0) + msg:addByte(2) + msg:addU32(Game.getLastServerSave() + DailyReward.serverTimeThreshold) --timeLeft to pickUp reward without loosing streak + msg:addU16(self:getJokerTokens()) + end + msg:addU16(self:getStreakLevel()) -- day strike + msg:sendToPlayer(self) +end + +function Player.sendCollectionResource(self, byte, value) + -- TODO: Migrate to protocolgame.cpp + local msg = NetworkMessage() + msg:addByte(0xEE) -- resource byte + msg:addByte(byte) + msg:addU64(value) + msg:sendToPlayer(self) +end + +function Player.selectDailyReward(self, msg) + local playerId = self:getId() + + if DailyReward.isRewardTaken(playerId) and not DailyReward.testMode then + self:sendError("You have already collected your daily reward.") + return false + end + + local source = msg:getByte() -- 0 -> shrine / 1 -> tibia panel + if not DailyReward.isShrine(source) then + if self:getCollectionTokens() < 1 then + self:sendError("You do not have enough collection tokens to proceed.") + return false + end + self:setCollectionTokens(self:getCollectionTokens() - 1) + end + + local dailyTable = DailyReward.rewards[self:getDayStreak() + 1] + if not dailyTable then + self:sendError("Something went wrong and we cannot process this request.") + return false + end + + -- Items as reward + if (dailyTable.type == DAILY_REWARD_TYPE_ITEM) then + + local items = {} + + -- Creating items table + local columnsPicked = msg:getByte() -- Columns picked + for i = 1, columnsPicked do + local spriteId = msg:getU16() + local count = msg:getByte() + items[i] = {spriteId = spriteId, count = count} + end + + -- Verifying if items if player is picking the correct amount + local counter = 0 + for k, v in ipairs(items) do + counter = counter + v.count + end + + if self:isPremium() then + count = dailyTable.premiumAccount + else + count = dailyTable.freeAccount + end + + if counter > count then + self:sendError("Something went wrong here, please restart this dialog.") + return false + end + + -- Adding items to store inbox + local inbox = self:getSlotItem(CONST_SLOT_STORE_INBOX) + if inbox and inbox:getEmptySlots() < columnsPicked then + self:sendError("You do not have enough space in your store inbox.") + return false + end + + local description = "" + for k, v in ipairs(items) do + local item = Game.getItemIdByClientId(v.spriteId) + if dailyTable.itemCharges then + for i = 1, v.count do + inbox:addItem(item:getId(), dailyTable.itemCharges) -- adding charges for each item + end + else + inbox:addItem(item:getId(), v.count) -- adding single item w/o charges + end + if k ~= columnsPicked then + description = description .. "" .. v.count .. "x " .. getItemName(item:getId()) .. ", " + else + description = description .. "" .. v.count .. "x " .. getItemName(item:getId()) .. "." + end + end + + -- Registering history + DailyReward.insertHistory(self:getGuid(), self:getDayStreak(), "Claimed reward no. \z + " .. self:getDayStreak() + 1 .. ". Picked items: " .. description) + DailyReward.processReward(playerId, source) + end + + local reward = nil + if self:isPremium() then + reward = dailyTable.premiumAccount + else + reward = dailyTable.freeAccount + end + + -- if (dailyTable.type == DAILY_REWARD_TYPE_STORAGE) then + -- local description = "" + -- for i = 1, #reward.things do + -- for j = 1, #reward.things[i].storages do + -- self:setStorageValue(reward.things[i].storages[j].storageId, reward.things[i].storages[j].value) + -- end + -- if i ~= #reward.things then + -- description = description .. reward.things[i].name .. ", " + -- else + -- description = description .. reward.things[i].name .. "." + -- end + -- end + -- DailyReward.insertHistory(self:getGuid(), self:getDayStreak(), "Claimed reward no. \z + -- " .. self:getDayStreak() + 1 .. ". Picked reward: " .. description) + -- DailyReward.processReward(playerId, source) + -- end + + if (dailyTable.type == DAILY_REWARD_TYPE_XP_BOOST) then + self:setExpBoostStamina(self:getExpBoostStamina() + (reward * 60)) + self:setStoreXpBoost(50) + DailyReward.insertHistory(self:getGuid(), self:getDayStreak(), "Claimed reward no. \z + " .. self:getDayStreak() + 1 .. ". Picked reward: XP Bonus for " .. reward .. " minutes.") + DailyReward.processReward(playerId, source) + end + + if (dailyTable.type == DAILY_REWARD_TYPE_PREY_REROLL) then + self:setPreyBonusRerolls(self:getPreyBonusRerolls() + reward) + DailyReward.insertHistory(self:getGuid(), self:getDayStreak(), "Claimed reward no. \z + " .. self:getDayStreak() + 1 .. ". Picked reward: " .. reward .. "x Prey bonus reroll(s)") + DailyReward.processReward(playerId, source) + end + + return true +end + +function Player.sendError(self, error) + local msg = NetworkMessage() + msg:addByte(ServerPackets.ShowDialog) + msg:addByte(0x14) + msg:addString(error) + msg:sendToPlayer(self) +end + +function Player.sendDailyRewardCollectionState(self, state) + local msg = NetworkMessage() + msg:addByte(ServerPackets.DailyRewardCollectionState) + msg:addByte(state) + msg:sendToPlayer(self) +end + +function Player.sendRewardHistory(self) + local msg = NetworkMessage() + msg:addByte(ServerPackets.DailyRewardHistory) + + local entries = DailyReward.retrieveHistoryEntries(self:getId()) + if #entries == 0 then + self:sendError("You don't have any entries yet.") + return false + end + + msg:addByte(#entries) + for k, entry in ipairs(entries) do + msg:addU32(entry.timestamp) + msg:addByte(0) -- (self:isPremium() and 0 or 0) + msg:addString(entry.description) + msg:addU16(entry.daystreak + 1) + end + msg:sendToPlayer(self) +end + +function Player.readDailyReward(self, msg, currentDay, state) + local dailyTable = DailyReward.rewards[currentDay] + local type, systemType = dailyTable.type, dailyTable.systemType + local rewards = nil + local itemsToPick = 0 + if currentDay == 3 or (currentDay >= 5 and currentDay <= 7) then + rewards = dailyTable.items + if (state == DAILY_REWARD_STATUS_FREE) then + itemsToPick = dailyTable.freeAccount + else + itemsToPick = dailyTable.premiumAccount + end + else + if systemType == 1 then + if (state == DAILY_REWARD_STATUS_FREE) then + rewards = DailyRewardItems[self:getVocation():getClientId()] + itemsToPick = dailyTable.freeAccount + else + rewards = DailyRewardItems[self:getVocation():getClientId()] + itemsToPick = dailyTable.premiumAccount + end + + if not(rewards) then + rewards = {} + end + else + if (state == DAILY_REWARD_STATUS_FREE) then + rewards = dailyTable.freeAccount + else + rewards = dailyTable.premiumAccount + end + end + end + msg:addByte(systemType) + if (systemType == 1) then + if (type == DAILY_REWARD_TYPE_ITEM) then + msg:addByte(itemsToPick) + msg:addByte(#rewards) + for i = 1, #rewards do + local itemId = rewards[i] + local itemType = ItemType(itemId) + local itemName = itemType:getArticle() .. " " .. getItemName(itemId) + local itemWeight = itemType:getWeight() + msg:addItemId(itemId) + msg:addString(itemName) + msg:addU32(itemWeight) + end + end + elseif (systemType == 2) then + if (type == DAILY_REWARD_TYPE_STORAGE) then + -- msg:addByte(#rewards.things) + -- for i = 1, #rewards.things do + -- msg:addByte(DAILY_REWARD_SYSTEM_TYPE_OTHER) -- type + -- msg:addU16(rewards.things[i].id * 100) + -- msg:addString(rewards.things[i].name) + -- msg:addByte(rewards.things[i].quantity) + -- end + elseif (type == DAILY_REWARD_TYPE_PREY_REROLL) then + msg:addByte(DAILY_REWARD_SYSTEM_SKIP) + msg:addByte(DAILY_REWARD_SYSTEM_TYPE_PREY_REROLL) + msg:addByte(itemsToPick) + elseif (type == DAILY_REWARD_TYPE_XP_BOOST) then + msg:addByte(DAILY_REWARD_SYSTEM_SKIP) + msg:addByte(DAILY_REWARD_SYSTEM_TYPE_XP_BOOST) + msg:addU16(itemsToPick) + end + end +end + +function Player.sendDailyReward(self) + local msg = NetworkMessage() + msg:addByte(ServerPackets.DailyRewardBasic) + msg:addByte(DAILY_REWARD_COUNT) + for currentDay = 1, DAILY_REWARD_COUNT do + self:readDailyReward(msg, currentDay, DAILY_REWARD_STATUS_FREE) -- Free rewards + self:readDailyReward(msg, currentDay, DAILY_REWARD_STATUS_PREMIUM) -- Premium rewards + end + -- Resting area bonuses + local maxBonus = 7 + msg:addByte(maxBonus - 1) + for i = 2, maxBonus do + msg:addString(DailyReward.strikeBonuses[i].text) + msg:addByte(i) + end + msg:addByte(1) -- Unknown + msg:sendToPlayer(self) +end diff --git a/data/modules/scripts/gamestore/gamestore.lua b/data/modules/scripts/gamestore/gamestore.lua new file mode 100644 index 00000000000..a9e4aa95e85 --- /dev/null +++ b/data/modules/scripts/gamestore/gamestore.lua @@ -0,0 +1,4497 @@ +--[[ +Items have been updated so that if the offer type is not one of the types: OFFER_TYPE_OUTFIT, OFFER_TYPE_OUTFIT_ADDON, +OFFER_TYPE_MOUNT, OFFER_TYPE_NAMECHANGE, OFFER_TYPE_SEXCHANGE, OFFER_TYPE_PROMOTION, OFFER_TYPE_EXPBOOST, +OFFER_TYPE_PREYSLOT, OFFER_TYPE_PREYBONUS, OFFER_TYPE_TEMPLE, OFFER_TYPE_BLESSINGS, OFFER_TYPE_PREMIUM, +OFFER_TYPE_ALLBLESSINGS +]] + +-- Parser +dofile('data/modules/scripts/gamestore/init.lua') +-- Config + +HomeBanners = { + images = { "home/banner_riftwatcher.png" , "home/banner_runemaster.png" , "home/banner_podiumofrenown.png" }, + delay = 10 +} + +GameStore.Categories = { + { + --Premium Time + icons = { "Category_PremiumTime.png" }, + name = "Premium Time", + rookgaard = true, + state = GameStore.States.STATE_NONE, + offers = { + { + icons = { "Premium_Time_30.png" }, + name = "30 Days of Premium Time", + price = 250, + id = 3030, + validUntil = 30, + description = "Enhance your gaming experience by gaining additional abilities and advantages:\n\n• access to Premium areas\n• use Tibia's transport system (ships, carpet)\n• more spells\n• rent houses\n• found guilds\n• offline training\n• larger depots\n• and many more\n\n{usablebyallicon} valid for all characters on this account\n{activated}", + type = GameStore.OfferTypes.OFFER_TYPE_PREMIUM, + }, + { + icons = { "Premium_Time_90.png" }, + name = "90 Days of Premium Time", + price = 750, + id = 3090, + validUntil = 90, + description = "Enhance your gaming experience by gaining additional abilities and advantages:\n\n• access to Premium areas\n• use Tibia's transport system (ships, carpet)\n• more spells\n• rent houses\n• found guilds\n• offline training\n• larger depots\n• and many more\n\n{usablebyallicon} valid for all characters on this account\n{activated}", + type = GameStore.OfferTypes.OFFER_TYPE_PREMIUM, + }, + { + icons = { "Premium_Time_180.png" }, + name = "180 Days of Premium Time", + price = 1500, + id = 3180, + validUntil = 180, + description = "Enhance your gaming experience by gaining additional abilities and advantages:\n\n• access to Premium areas\n• use Tibia's transport system (ships, carpet)\n• more spells\n• rent houses\n• found guilds\n• offline training\n• larger depots\n• and many more\n\n{usablebyallicon} valid for all characters on this account\n{activated}", + type = GameStore.OfferTypes.OFFER_TYPE_PREMIUM, + }, + { + icons = { "Premium_Time_360.png" }, + name = "360 Days of Premium Time", + price = 3000, + id = 3360, + validUntil = 360, + description = "Enhance your gaming experience by gaining additional abilities and advantages:\n\n• access to Premium areas\n• use Tibia's transport system (ships, carpet)\n• more spells\n• rent houses\n• found guilds\n• offline training\n• larger depots\n• and many more\n\n{usablebyallicon} valid for all characters on this account\n{activated}", + type = GameStore.OfferTypes.OFFER_TYPE_PREMIUM, + }, + }, + }, + { + icons = { "Category_Consumables.png" }, + name = "Consumables", + rookgaard = true, + subclasses = {"Blessings", "Casks", "Exercise Weapons", "Kegs", "Potions", "Runes"}, + }, + -- Blessings + { + icons = { "Category_Blessings.png" }, + name = "Blessings", + parent = "Consumables", + rookgaard = true, + state = GameStore.States.STATE_NONE, + offers = { + { + icons = { "All_PvE_Blessings.png" }, + name = "All Regular Blessings", + price = 130, + id = 11, + count = 1, + description = "Reduces your character's chance to lose any items as well as the amount of your character's experience and skill loss upon death:\n\n• 1 blessing = 8.00% less Skill / XP loss, 30% equipment protection\n• 2 blessing = 16.00% less Skill / XP loss, 55% equipment protection\n• 3 blessing = 24.00% less Skill / XP loss, 75% equipment protection\n• 4 blessing = 32.00% less Skill / XP loss, 90% equipment protection\n• 5 blessing = 40.00% less Skill / XP loss, 100% equipment protection\n• 6 blessing = 48.00% less Skill / XP loss, 100% equipment protection\n• 7 blessing = 56.00% less Skill / XP loss, 100% equipment protection\n\n{character} \n{limit|5} \n{info} added directly to the Record of Blessings \n{info} characters with a red or black skull will always lose all equipment upon death", + type = GameStore.OfferTypes.OFFER_TYPE_ALLBLESSINGS, + }, + { + icons = { "All_PvE_Blessings.png" }, + name = "All Regular Blessings", + price = 650, + id = 12, + count = 5, + description = "Reduces your character's chance to lose any items as well as the amount of your character's experience and skill loss upon death:\n\n• 1 blessing = 8.00% less Skill / XP loss, 30% equipment protection\n• 2 blessing = 16.00% less Skill / XP loss, 55% equipment protection\n• 3 blessing = 24.00% less Skill / XP loss, 75% equipment protection\n• 4 blessing = 32.00% less Skill / XP loss, 90% equipment protection\n• 5 blessing = 40.00% less Skill / XP loss, 100% equipment protection\n• 6 blessing = 48.00% less Skill / XP loss, 100% equipment protection\n• 7 blessing = 56.00% less Skill / XP loss, 100% equipment protection\n\n{character} \n{limit|5} \n{info} added directly to the Record of Blessings \n{info} characters with a red or black skull will always lose all equipment upon death", + type = GameStore.OfferTypes.OFFER_TYPE_ALLBLESSINGS, + }, + { + icons = { "Twist_of_Fate.png" }, + name = "Twist of Fate", + price = 8, + blessid = 1, + count = 1, + id = 3, + description = "Protects your character's regular blessings or an Amulet of Loss if you are unfortunate enough to die in a PvP fight.\n\n{character}\n{limit|5}\n{info} added directly to the Record of Blessings\n{info} does not work for characters with a red or black skull", + type = GameStore.OfferTypes.OFFER_TYPE_BLESSINGS, + }, + { + icons = { "Twist_of_Fate.png" }, + name = "Twist of Fate", + price = 40, + blessid = 1, + count = 5, + description = "Protects your character's regular blessings or an Amulet of Loss if you are unfortunate enough to die in a PvP fight.\n\n{character}\n{limit|5}\n{info} added directly to the Record of Blessings\n{info} does not work for characters with a red or black skull", + type = GameStore.OfferTypes.OFFER_TYPE_BLESSINGS, + }, + { + icons = { "Wisdom_of_Solitude.png" }, + name = "The Wisdom of Solitude", + price = 15, + blessid = 2, + count = 1, + id = 4, + description = "Reduces your character's chance to lose any items as well as the amount of your character's experience and skill loss upon death:\n\n• 1 blessing = 8.00% less Skill / XP loss, 30% equipment protection\n• 2 blessing = 16.00% less Skill / XP loss, 55% equipment protection\n• 3 blessing = 24.00% less Skill / XP loss, 75% equipment protection\n• 4 blessing = 32.00% less Skill / XP loss, 90% equipment protection\n• 5 blessing = 40.00% less Skill / XP loss, 100% equipment protection\n• 6 blessing = 48.00% less Skill / XP loss, 100% equipment protection\n• 7 blessing = 56.00% less Skill / XP loss, 100% equipment protection\n\n{character} \n{limit|5} \n{info} added directly to the Record of Blessings \n{info} characters with a red or black skull will always lose all equipment upon death", + type = GameStore.OfferTypes.OFFER_TYPE_BLESSINGS, + }, + { + icons = { "Spark_of_the_Phoenix.png" }, + name = "The Spark of the Phoenix", + price = 20, + blessid = 3, + count = 1, + id = 5, + description = "Reduces your character's chance to lose any items as well as the amount of your character's experience and skill loss upon death:\n\n• 1 blessing = 8.00% less Skill / XP loss, 30% equipment protection\n• 2 blessing = 16.00% less Skill / XP loss, 55% equipment protection\n• 3 blessing = 24.00% less Skill / XP loss, 75% equipment protection\n• 4 blessing = 32.00% less Skill / XP loss, 90% equipment protection\n• 5 blessing = 40.00% less Skill / XP loss, 100% equipment protection\n• 6 blessing = 48.00% less Skill / XP loss, 100% equipment protection\n• 7 blessing = 56.00% less Skill / XP loss, 100% equipment protection\n\n{character} \n{limit|5} \n{info} added directly to the Record of Blessings \n{info} characters with a red or black skull will always lose all equipment upon death", + type = GameStore.OfferTypes.OFFER_TYPE_BLESSINGS, + }, + { + icons = { "Fire_of_the_Suns.png" }, + name = "The Fire of the Suns", + price = 15, + blessid = 4, + count = 1, + id = 6, + description = "Reduces your character's chance to lose any items as well as the amount of your character's experience and skill loss upon death:\n\n• 1 blessing = 8.00% less Skill / XP loss, 30% equipment protection\n• 2 blessing = 16.00% less Skill / XP loss, 55% equipment protection\n• 3 blessing = 24.00% less Skill / XP loss, 75% equipment protection\n• 4 blessing = 32.00% less Skill / XP loss, 90% equipment protection\n• 5 blessing = 40.00% less Skill / XP loss, 100% equipment protection\n• 6 blessing = 48.00% less Skill / XP loss, 100% equipment protection\n• 7 blessing = 56.00% less Skill / XP loss, 100% equipment protection\n\n{character} \n{limit|5} \n{info} added directly to the Record of Blessings \n{info} characters with a red or black skull will always lose all equipment upon death", + type = GameStore.OfferTypes.OFFER_TYPE_BLESSINGS, + }, + { + icons = { "Spiritual_Shielding.png" }, + name = "The Spiritual Shielding", + price = 15, + blessid = 5, + count = 1, + id = 7, + description = "Reduces your character's chance to lose any items as well as the amount of your character's experience and skill loss upon death:\n\n• 1 blessing = 8.00% less Skill / XP loss, 30% equipment protection\n• 2 blessing = 16.00% less Skill / XP loss, 55% equipment protection\n• 3 blessing = 24.00% less Skill / XP loss, 75% equipment protection\n• 4 blessing = 32.00% less Skill / XP loss, 90% equipment protection\n• 5 blessing = 40.00% less Skill / XP loss, 100% equipment protection\n• 6 blessing = 48.00% less Skill / XP loss, 100% equipment protection\n• 7 blessing = 56.00% less Skill / XP loss, 100% equipment protection\n\n{character} \n{limit|5} \n{info} added directly to the Record of Blessings \n{info} characters with a red or black skull will always lose all equipment upon death", + type = GameStore.OfferTypes.OFFER_TYPE_BLESSINGS, + }, + { + icons = { "Embrace_of_Tibia.png" }, + name = "The Embrace of Tibia", + price = 15, + blessid = 6, + count = 1, + id = 8, + description = "Reduces your character's chance to lose any items as well as the amount of your character's experience and skill loss upon death:\n\n• 1 blessing = 8.00% less Skill / XP loss, 30% equipment protection\n• 2 blessing = 16.00% less Skill / XP loss, 55% equipment protection\n• 3 blessing = 24.00% less Skill / XP loss, 75% equipment protection\n• 4 blessing = 32.00% less Skill / XP loss, 90% equipment protection\n• 5 blessing = 40.00% less Skill / XP loss, 100% equipment protection\n• 6 blessing = 48.00% less Skill / XP loss, 100% equipment protection\n• 7 blessing = 56.00% less Skill / XP loss, 100% equipment protection\n\n{character} \n{limit|5} \n{info} added directly to the Record of Blessings \n{info} characters with a red or black skull will always lose all equipment upon death", + type = GameStore.OfferTypes.OFFER_TYPE_BLESSINGS, + }, + { + icons = { "Heart_of_the_Mountain.png" }, + name = "Heart of the Mountain", + price = 25, + blessid = 7, + count = 1, + id = 9, + description = "Reduces your character's chance to lose any items as well as the amount of your character's experience and skill loss upon death:\n\n• 1 blessing = 8.00% less Skill / XP loss, 30% equipment protection\n• 2 blessing = 16.00% less Skill / XP loss, 55% equipment protection\n• 3 blessing = 24.00% less Skill / XP loss, 75% equipment protection\n• 4 blessing = 32.00% less Skill / XP loss, 90% equipment protection\n• 5 blessing = 40.00% less Skill / XP loss, 100% equipment protection\n• 6 blessing = 48.00% less Skill / XP loss, 100% equipment protection\n• 7 blessing = 56.00% less Skill / XP loss, 100% equipment protection\n\n{character} \n{limit|5} \n{info} added directly to the Record of Blessings \n{info} characters with a red or black skull will always lose all equipment upon death", + type = GameStore.OfferTypes.OFFER_TYPE_BLESSINGS, + }, + { + icons = { "Blood_of_the_Mountain.png" }, + name = "Blood of the Mountain", + price = 25, + blessid = 8, + count = 1, + id = 10, + description = "Reduces your character's chance to lose any items as well as the amount of your character's experience and skill loss upon death:\n\n• 1 blessing = 8.00% less Skill / XP loss, 30% equipment protection\n• 2 blessing = 16.00% less Skill / XP loss, 55% equipment protection\n• 3 blessing = 24.00% less Skill / XP loss, 75% equipment protection\n• 4 blessing = 32.00% less Skill / XP loss, 90% equipment protection\n• 5 blessing = 40.00% less Skill / XP loss, 100% equipment protection\n• 6 blessing = 48.00% less Skill / XP loss, 100% equipment protection\n• 7 blessing = 56.00% less Skill / XP loss, 100% equipment protection\n\n{character} \n{limit|5} \n{info} added directly to the Record of Blessings \n{info} characters with a red or black skull will always lose all equipment upon death", + type = GameStore.OfferTypes.OFFER_TYPE_BLESSINGS, + }, + { + icons = { "Death_Redemption.png" }, + name = "Death Redemption", + price = 260, + blessid = 10, + count = 1, + description = "Reduces the penalty of your character's most recent death.\n\n{character}\n{info} can only be used for the most recent death and only within 24 hours after this death", + type = GameStore.OfferTypes.OFFER_TYPE_BLESSINGS, + }, + }, + }, + -- Casks + { + icons = { "Category_Casks.png" }, + name = "Casks", + parent = "Consumables", + rookgaard = true, + state = GameStore.States.STATE_NONE, + offers = { + { + icons = { "Health_Cask.png" }, + name = "Health Cask", + price = 5, + itemtype = 28555, + count = 1000, + description = "Place it in your house and fill up potions to restore your hit points!\n\n{house}\n{box}\n{storeinbox}\n{usablebyallicon} can be used to fill up potions by all characters that have access to the house\n{storeinboxicon} potions created from this cask will be sent to your Store inbox and can only be stored there and in depot box\n{backtoinbox}\n{info} usable 1000 times a piece\n{transferableprice}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Strong_Health_Cask.png" }, + name = "Strong Health Cask", + price = 11, + itemtype = 28556, + count = 1000, + description = "Place it in your house and fill up potions to restore your hit points!\n\n{house}\n{box}\n{storeinbox}\n{usablebyallicon} can be used to fill up potions by all characters that have access to the house\n{storeinboxicon} potions created from this cask will be sent to your Store inbox and can only be stored there and in depot box\n{backtoinbox}\n{info} usable 1000 times a piece\n{transferableprice}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Great_Health_Cask.png" }, + name = "Great Health Cask", + price = 22, + itemtype = 28557, + count = 1000, + description = "Place it in your house and fill up potions to restore your hit points!\n\n{house}\n{box}\n{storeinbox}\n{usablebyallicon} can be used to fill up potions by all characters that have access to the house\n{storeinboxicon} potions created from this cask will be sent to your Store inbox and can only be stored there and in depot box\n{backtoinbox}\n{info} usable 1000 times a piece\n{transferableprice}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Ultimate_Health_Cask.png" }, + name = "Ultimate Health Cask", + price = 36, + itemtype = 28558, + count = 1000, + description = "Place it in your house and fill up potions to restore your hit points!\n\n{house}\n{box}\n{storeinbox}\n{usablebyallicon} can be used to fill up potions by all characters that have access to the house\n{storeinboxicon} potions created from this cask will be sent to your Store inbox and can only be stored there and in depot box\n{backtoinbox}\n{info} usable 1000 times a piece\n{transferableprice}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Supreme_Health_Cask.png" }, + name = "Supreme Health Cask", + price = 59, + itemtype = 28559, + count = 1000, + description = "Place it in your house and fill up potions to restore your hit points!\n\n{house}\n{box}\n{storeinbox}\n{usablebyallicon} can be used to fill up potions by all characters that have access to the house\n{storeinboxicon} potions created from this cask will be sent to your Store inbox and can only be stored there and in depot box\n{backtoinbox}\n{info} usable 1000 times a piece\n{transferableprice}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Mana_Cask.png" }, + name = "Mana Cask", + price = 5, + itemtype = 28565, + count = 1000, + description = "Place it in your house and fill up potions to refill your mana!\n\n{house}\n{box}\n{storeinbox}\n{usablebyallicon} can be used to fill up potions by all characters that have access to the house\n{storeinboxicon} potions created from this cask will be sent to your Store inbox and can only be stored there and in depot box\n{backtoinbox}\n{info} usable 1000 times a piece\n{transferableprice}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Strong_Mana_Cask.png" }, + name = "Strong Mana Cask", + price = 9, + itemtype = 28566, + count = 1000, + description = "Place it in your house and fill up potions to refill your mana!\n\n{house}\n{box}\n{storeinbox}\n{usablebyallicon} can be used to fill up potions by all characters that have access to the house\n{storeinboxicon} potions created from this cask will be sent to your Store inbox and can only be stored there and in depot box\n{backtoinbox}\n{info} usable 1000 times a piece\n{transferableprice}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Great_Mana_Cask.png" }, + name = "Great Mana Cask", + price = 14, + itemtype = 28567, + count = 1000, + description = "Place it in your house and fill up potions to refill your mana!\n\n{house}\n{box}\n{storeinbox}\n{usablebyallicon} can be used to fill up potions by all characters that have access to the house\n{storeinboxicon} potions created from this cask will be sent to your Store inbox and can only be stored there and in depot box\n{backtoinbox}\n{info} usable 1000 times a piece\n{transferableprice}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Ultimate_Mana_Cask.png" }, + name = "Ultimate Mana Cask", + price = 42, + itemtype = 28568, + count = 1000, + description = "Place it in your house and fill up potions to refill your mana!\n\n{house}\n{box}\n{storeinbox}\n{usablebyallicon} can be used to fill up potions by all characters that have access to the house\n{storeinboxicon} potions created from this cask will be sent to your Store inbox and can only be stored there and in depot box\n{backtoinbox}\n{info} usable 1000 times a piece\n{transferableprice}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Great_Spirit_Cask.png" }, + name = "Great Spirit Cask", + price = 22, + itemtype = 28575, + count = 1000, + description = "Place it in your house and fill up potions to restore your hit points and mana!\n\n{house}\n{box}\n{storeinbox}\n{usablebyallicon} can be used to fill up potions by all characters that have access to the house\n{storeinboxicon} potions created from this cask will be sent to your Store inbox and can only be stored there and in depot box\n{backtoinbox}\n{info} usable 1000 times a piece\n{transferableprice}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Ultimate_Spirit_Cask.png" }, + name = "Ultimate Spirit Cask", + price = 42, + itemtype = 28576, + count = 1000, + description = "Place it in your house and fill up potions to restore your hit points and mana!\n\n{house}\n{box}\n{storeinbox}\n{usablebyallicon} can be used to fill up potions by all characters that have access to the house\n{storeinboxicon} potions created from this cask will be sent to your Store inbox and can only be stored there and in depot box\n{backtoinbox}\n{info} usable 1000 times a piece\n{transferableprice}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + }, + }, + -- Exercise Weapons + { + icons = { "Category_ExerciseWeapons.png" }, + name = "Exercise Weapons", + parent = "Consumables", + rookgaard = true, + state = GameStore.States.STATE_NONE, + offers = { + { + icons = { "Exercise_Axe.png" }, + name = "Exercise Axe", + price = 25, + itemtype = 32385, + charges = 500, + description = "Use it to train your axe fighting skill on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your axe fighting skill\n{info} usable 500 times a piece", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + }, + { + icons = { "Exercise_Bow.png" }, + name = "Exercise Bow", + price = 25, + itemtype = 32387, + charges = 500, + description = "Use it to train your distance fighting skill on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your distance fighting skill\n{info} usable 500 times a piece", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + }, + { + icons = { "Exercise_Club.png" }, + name = "Exercise Club", + price = 25, + itemtype = 32386, + charges = 500, + description = "Use it to train your club fighting skill on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your club fighting skill\n{info} usable 500 times a piece", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + }, + { + icons = { "Exercise_Rod.png" }, + name = "Exercise Rod", + price = 25, + itemtype = 32388, + charges = 500, + description = "Use it to train your magic level on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your magic level\n{info} usable 500 times a piece", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + }, + { + icons = { "Exercise_Sword.png" }, + name = "Exercise Sword", + price = 25, + itemtype = 32384, + charges = 500, + description = "Use it to train your sword fighting skill on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your sword fighting skill\n{info} usable 500 times a piece", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + }, + { + icons = { "Exercise_Wand.png" }, + name = "Exercise Wand", + price = 25, + itemtype = 32389, + charges = 500, + description = "Use it to train your magic level on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your magic level\n{info} usable 500 times a piece", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + }, + { + icons = { "Exercise_Axe.png" }, + name = "Durable Exercise Axe", + price = 90, + itemtype = 40115, + charges = 1800, + description = "Use it to train your axe fighting skill on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your axe fighting skill\n{info} usable 1800 times a piece", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + }, + { + icons = { "Exercise_Bow.png" }, + name = "Durable Exercise Bow", + price = 90, + itemtype = 40117, + charges = 1800, + description = "Use it to train your distance fighting skill on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your distance fighting skill\n{info} usable 1800 times a piece", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + }, + { + icons = { "Exercise_Club.png" }, + name = "Durable Exercise Club", + price = 90, + itemtype = 40116, + charges = 1800, + description = "Use it to train your club fighting skill on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your club fighting skill\n{info} usable 1800 times a piece", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + }, + { + icons = { "Exercise_Rod.png" }, + name = "Durable Exercise Rod", + price = 90, + itemtype = 40118, + charges = 1800, + description = "Use it to train your magic level on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your magic level\n{info} usable 1800 times a piece", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + }, + { + icons = { "Exercise_Sword.png" }, + name = "Durable Exercise Sword", + price = 90, + itemtype = 40114, + charges = 1800, + description = "Use it to train your sword fighting skill on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your sword fighting skill\n{info} usable 1800 times a piece", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + }, + { + icons = { "Exercise_Wand.png" }, + name = "Durable Exercise Wand", + price = 90, + itemtype = 40119, + charges = 1800, + description = "Use it to train your magic level on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your magic level\n{info} usable 1800 times a piece", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + }, + { + icons = { "Exercise_Axe.png" }, + name = "Lasting Exercise Axe", + price = 720, + itemtype = 40121, + charges = 14400, + description = "Use it to train your axe fighting skill on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your axe fighting skill\n{info} usable 14400 times a piece", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + }, + { + icons = { "Exercise_Bow.png" }, + name = "Lasting Exercise Bow", + price = 720, + itemtype = 40123, + charges = 14400, + description = "Use it to train your distance fighting skill on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your distance fighting skill\n{info} usable 14400 times a piece", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + }, + { + icons = { "Exercise_Club.png" }, + name = "Lasting Exercise Club", + price = 720, + itemtype = 40122, + charges = 14400, + description = "Use it to train your club fighting skill on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your club fighting skill\n{info} usable 14400 times a piece", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + }, + { + icons = { "Exercise_Rod.png" }, + name = "Lasting Exercise Rod", + price = 720, + itemtype = 40124, + charges = 14400, + description = "Use it to train your magic level on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your magic level\n{info} usable 14400 times a piece", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + }, + { + icons = { "Exercise_Sword.png" }, + name = "Lasting Exercise Sword", + price = 720, + itemtype = 40120, + charges = 14400, + description = "Use it to train your sword fighting skill on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your sword fighting skill\n{info} usable 14400 times a piece", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + }, + { + icons = { "Exercise_Wand.png" }, + name = "Lasting Exercise Wand", + price = 720, + itemtype = 40125, + charges = 14400, + description = "Use it to train your magic level on an exercise dummy!\n\n{character}\n{storeinbox}\n{info} use it on an exercise dummy to train your magic level\n{info} usable 14400 times a piece", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + }, + }, + }, + -- Kegs + { + icons = { "Category_Kegs.png" }, + name = "Kegs", + parent = "Consumables", + rookgaard = true, + state = GameStore.States.STATE_NONE, + offers = { + { + icons = { "Health_Keg.png" }, + name = "Health Keg", + price = 26, + itemtype = 28579, + count = 500, + description = "Fill up potions to restore your hit points no matter where you are!\n\n{character}\n{vocationlevelcheck}\n{storeinboxicon} potions created from this keg will be sent to your Store inbox and can only be stored there and in depot box\n{info} usable 500 times a piece\n{info} saves capacity because it's constant weight equals only 250 potions", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Strong_Health_Keg.png" }, + name = "Strong Health Keg", + price = 53, + itemtype = 28580, + count = 500, + description = "Fill up potions to restore your hit points no matter where you are!\n\n{character}\n{vocationlevelcheck}\n{storeinboxicon} potions created from this keg will be sent to your Store inbox and can only be stored there and in depot box\n{info} usable 500 times a piece\n{info} saves capacity because it's constant weight equals only 250 potions", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Great_Health_Keg.png" }, + name = "Great Health Keg", + price = 103, + itemtype = 28581, + count = 500, + description = "Fill up potions to restore your hit points no matter where you are!\n\n{character}\n{vocationlevelcheck}\n{storeinboxicon} potions created from this keg will be sent to your Store inbox and can only be stored there and in depot box\n{info} usable 500 times a piece\n{info} saves capacity because it's constant weight equals only 250 potions", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Ultimate_Health_Keg.png" }, + name = "Ultimate Health Keg", + price = 175, + itemtype = 28582, + count = 500, + description = "Fill up potions to restore your hit points no matter where you are!\n\n{character}\n{vocationlevelcheck}\n{storeinboxicon} potions created from this keg will be sent to your Store inbox and can only be stored there and in depot box\n{info} usable 500 times a piece\n{info} saves capacity because it's constant weight equals only 250 potions", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Supreme_Health_Keg.png" }, + name = "Supreme Health Keg", + price = 288, + itemtype = 28583, + count = 500, + description = "Fill up potions to restore your hit points no matter where you are!\n\n{character}\n{vocationlevelcheck}\n{storeinboxicon} potions created from this keg will be sent to your Store inbox and can only be stored there and in depot box\n{info} usable 500 times a piece\n{info} saves capacity because it's constant weight equals only 250 potions", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Mana_Keg.png" }, + name = "Mana Keg", + price = 26, + itemtype = 28584, + count = 500, + description = "Fill up potions to refill your mana no matter where you are!\n\n{character}\n{vocationlevelcheck}\n{storeinboxicon} potions created from this keg will be sent to your Store inbox and can only be stored there and in depot box\n{info} usable 500 times a piece\n{info} saves capacity because it's constant weight equals only 250 potions", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Strong_Mana_Keg.png" }, + name = "Strong Mana Keg", + price = 43, + itemtype = 28585, + count = 500, + description = "Fill up potions to refill your mana no matter where you are!\n\n{character}\n{vocationlevelcheck}\n{storeinboxicon} potions created from this keg will be sent to your Store inbox and can only be stored there and in depot box\n{info} usable 500 times a piece\n{info} saves capacity because it's constant weight equals only 250 potions", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Great_Mana_Keg.png" }, + name = "Great Mana Keg", + price = 66, + itemtype = 28586, + count = 500, + description = "Fill up potions to refill your mana no matter where you are!\n\n{character}\n{vocationlevelcheck}\n{storeinboxicon} potions created from this keg will be sent to your Store inbox and can only be stored there and in depot box\n{info} usable 500 times a piece\n{info} saves capacity because it's constant weight equals only 250 potions", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Ultimate_Mana_Keg.png" }, + name = "Ultimate Mana Keg", + price = 202, + itemtype = 28587, + count = 500, + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Great_Spirit_Keg.png" }, + name = "Great Spirit Keg", + price = 105, + itemtype = 28589, + count = 500, + description = "Fill up potions to restore your hit points and mana no matter where you are!\n\n{character}\n{vocationlevelcheck}\n{storeinboxicon} potions created from this keg will be sent to your Store inbox and can only be stored there and in depot box\n{info} usable 500 times a piece\n{info} saves capacity because it's constant weight equals only 250 potions", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = {"Ultimate_Spirit_Keg.png"}, + name = "Ultimate Spirit Keg", + price = 202, + itemtype = 28590, + count = 500, + description = "Fill up potions to restore your hit points and mana no matter where you are!\n\n{character}\n{vocationlevelcheck}\n{storeinboxicon} potions created from this keg will be sent to your Store inbox and can only be stored there and in depot box\n{info} usable 500 times a piece\n{info} saves capacity because it's constant weight equals only 250 potions", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + }, + }, +-- Potions + { + icons = { "Category_Potions.png" }, + name = "Potions", + parent = "Consumables", + offers = { + { + icons = { "Health_Potion.png" }, + name = "Health Potion", + price = 6, + itemtype = 7618, + count = 125, + description = "Restores your character's hit points.\n\n{character}\n{vocationlevelcheck}\n{storeinbox}\n{battlesign}\n{capacity}", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Health_Potion.png" }, + name = "Health Potion", + price = 11, + itemtype = 7618, + count = 300, + description = "Restores your character's hit points.\n\n{character}\n{vocationlevelcheck}\n{storeinbox}\n{battlesign}\n{capacity}", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Strong_Health_Potion.png" }, + name = "Strong Health Potion", + price = 10, + itemtype = 7588, + count = 100, + description = "Restores your character's hit points.\n\n{character}\n{vocationlevelcheck}\n{storeinbox}\n{battlesign}\n{capacity}", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Strong_Health_Potion.png" }, + name = "Strong Health Potion", + price = 21, + itemtype = 7588, + count = 250, + description = "Restores your character's hit points.\n\n{character}\n{vocationlevelcheck}\n{storeinbox}\n{battlesign}\n{capacity}", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Great_Health_Potion.png" }, + name = "Great Health Potion", + price = 18, + itemtype = 7591, + count = 100, + description = "Restores your character's hit points.\n\n{character}\n{vocationlevelcheck}\n{storeinbox}\n{battlesign}\n{capacity}", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Great_Health_Potion.png" }, + name = "Great Health Potion", + price = 41, + itemtype = 7591, + count = 250, + description = "Restores your character's hit points.\n\n{character}\n{vocationlevelcheck}\n{storeinbox}\n{battlesign}\n{capacity}", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Ultimate_Health_Potion.png" }, + name = "Ultimate Health Potion", + price = 29, + itemtype = 8473, + count = 100, + description = "Restores your character's hit points.\n\n{character}\n{vocationlevelcheck}\n{storeinbox}\n{battlesign}\n{capacity}", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Ultimate_Health_Potion.png" }, + name = "Ultimate Health Potion", + price = 68, + itemtype = 8473, + count = 250, + description = "Restores your character's hit points.\n\n{character}\n{vocationlevelcheck}\n{storeinbox}\n{battlesign}\n{capacity}", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Supreme_Health_Potion.png" }, + name = "Supreme Health Potion", + price = 47, + itemtype = 26031, + count = 100, + description = "Restores your character's hit points.\n\n{character}\n{vocationlevelcheck}\n{storeinbox}\n{battlesign}\n{capacity}", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Supreme_Health_Potion.png" }, + name = "Supreme Health Potion", + price = 113, + itemtype = 26031, + count = 250, + description = "Restores your character's hit points.\n\n{character}\n{vocationlevelcheck}\n{storeinbox}\n{battlesign}\n{capacity}", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Mana_Potion.png" }, + name = "Mana Potion", + price = 6, + itemtype = 7620, + count = 125, + description = "Refills your character's mana.\n\n{character}\n{vocationlevelcheck}\n{storeinbox}\n{battlesign}\n{capacity}", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Mana_Potion.png" }, + name = "Mana Potion", + price = 12, + itemtype = 7620, + count = 300, + description = "Refills your character's mana.\n\n{character}\n{vocationlevelcheck}\n{storeinbox}\n{battlesign}\n{capacity}", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Strong_Mana_Potion.png" }, + name = "Strong Mana Potion", + price = 7, + itemtype = 7589, + count = 100, + description = "Refills your character's mana.\n\n{character}\n{vocationlevelcheck}\n{storeinbox}\n{battlesign}\n{capacity}", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Strong_Mana_Potion.png" }, + name = "Strong Mana Potion", + price = 17, + itemtype = 7589, + count = 250, + description = "Refills your character's mana.\n\n{character}\n{vocationlevelcheck}\n{storeinbox}\n{battlesign}\n{capacity}", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Great_Mana_Potion.png" }, + name = "Great Mana Potion", + price = 11, + itemtype = 7590, + count = 100, + description = "Refills your character's mana.\n\n{character}\n{vocationlevelcheck}\n{storeinbox}\n{battlesign}\n{capacity}", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Great_Mana_Potion.png" }, + name = "Great Mana Potion", + price = 26, + itemtype = 7590, + count = 250, + description = "Refills your character's mana.\n\n{character}\n{vocationlevelcheck}\n-{storeinbox}\n{battlesign}\n{capacity}", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Ultimate_Mana_Potion.png" }, + name = "Ultimate Mana Potion", + price = 33, + itemtype = 26029, + count = 100, + description = "Refills your character's mana.\n\n{character}\n{vocationlevelcheck}\n{storeinbox}\n{battlesign}\n{capacity}", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Ultimate_Mana_Potion.png" }, + name = "Ultimate Mana Potion", + price = 79, + itemtype = 26029, + count = 250, + description = "Refills your character's mana.\n\n{character}\n{vocationlevelcheck}\n{storeinbox}\n{battlesign}\n{capacity}", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Great_Spirit_Potion.png" }, + name = "Great Spirit Potion", + price = 18, + itemtype = 8472, + count = 100, + description = "Restores your character's hit points and mana.\n\n{character}\n{vocationlevelcheck}\n{storeinbox}\n{battlesign}\n{capacity}", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Great_Spirit_Potion.png" }, + name = "Great Spirit Potion", + price = 41, + itemtype = 8472, + count = 250, + description = "Restores your character's hit points and mana.\n\n{character}\n{vocationlevelcheck}\n{storeinbox}\n{battlesign}\n{capacity}", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Ultimate_Spirit_Potion.png" }, + name = "Ultimate Spirit Potion", + price = 33, + itemtype = 26030, + count = 100, + description = "Restores your character's hit points and mana.\n\n{character}\n{vocationlevelcheck}\n{storeinbox}\n{battlesign}\n{capacity}", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Ultimate_Spirit_Potion.png" }, + name = "Ultimate Spirit Potion", + price = 79, + itemtype = 26030, + count = 250, + description = "Restores your character's hit points and mana.\n\n{character}\n{vocationlevelcheck}\n{storeinbox}\n{battlesign}\n{capacity}", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + }, + rookgaard = true, + state = GameStore.States.STATE_NONE, + }, + -- Runes + { + icons = { "Category_Runes.png" }, + name = "Runes", + parent = "Consumables", + offers = { + { + icons = { "Animate_Dead_Rune.png" }, + name = "Animate Dead Rune", + price = 75, + itemtype = 2316, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck} only buyable if fitting vocation and level of purchasing character\n{battlesign}\n{capacity}\n\nAfter a long time of research, the magicians of Edron succeeded in storing some life energy in a rune. When this energy was unleashed onto a body it was found that an undead creature arose that could be mentally controlled by the user of the rune. This rune is useful to create allies in combat.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Avalanche_Rune.png" }, + name = "Avalanche Rune", + price = 12, + itemtype = 2274, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nThe ice damage which arises from this rune is a useful weapon in every battle but it comes in particularly handy if you fight against a horde of creatures dominated by the element fire.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Chameleon_Rune.png" }, + name = "Chameleon Rune", + price = 42, + itemtype = 2291, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nThe metamorphosis caused by this rune is only superficial, and while casters who are using the rune can take on the exterior form of nearly any inanimate object, they will always retain their original smell and mental abilities. So there is no real practical use for this rune, making this largely a fun rune.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Convince_Creature_Rune.png" }, + name = "Convince Creature Rune", + price = 16, + itemtype = 2290, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nUsing this rune together with some mana, you can convince certain creatures. The needed amount of mana is determined by the power of the creature one wishes to convince, so the amount of mana to convince a rat is lower than that which is needed for an orc.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Cure_Poison_Rune_(Item).png" }, + name = "Cure Poison Rune", + price = 13, + itemtype = 2266, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nIn the old days, many adventurers fell prey to poisonous creatures that were roaming the caves and forests. After many years of research druids finally succeeded in altering the cure poison spell so it could be bound to a rune. By using this rune it is possible to stop the effect of any known poison.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Disintegrate_Rune.png" }, + name = "Disintegrate Rune", + price = 5, + itemtype = 2310, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nNothing is worse than being cornered when fleeing from an enemy you just cannot beat, especially if the obstacles in your way are items you could easily remove if only you had the time! However, there is one reliable remedy: The Disintegrate rune will instantly destroy up to 500 movable items that are in your way, making room for a quick escape.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Energy_Bomb_Rune.png" }, + name = "Energy Bomb Rune", + price = 40, + itemtype = 2262, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nUsing the Energy Bomb rune will create a field of deadly energy that deals damage to all who carelessly step into it. Its area of effect is covering a full 9 square metres! Creatures that are caught in the middle of an Energy Bomb are frequently confused by the unexpected effect, and some may even stay in the field of deadly sparks for a while.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Energy_Field_Rune.png" }, + name = "Energy Field Rune", + price = 8, + itemtype = 2277, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nThis spell creates a limited barrier made up of crackling energy that will cause electrical damage to all those passing through. Since there are few creatures that are immune to the harmful effects of energy this spell is not to be underestimated.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Energy_Wall_Rune.png" }, + name = "Energy Wall Rune", + price = 17, + itemtype = 2279, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nCasting this spell generates a solid wall made up of magical energy. Walls made this way surpass any other magically created obstacle in width, so it is always a good idea to have an Energy Wall rune or two in one's pocket when travelling through the wilderness.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Explosion_Rune.png" }, + name = "Explosion Rune", + price = 6, + itemtype = 2313, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nThis rune must be aimed at areas rather than at specific creatures, so it is possible for explosions to be unleashed even if no targets are close at all. These explosions cause a considerable physical damage within a substantial blast radius.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Fireball_Rune.png" }, + name = "Fireball Rune", + price = 6, + itemtype = 2302, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nWhen this rune is used a massive fiery ball is released which hits the aimed foe with immense power. It is especially effective against opponents of the element earth.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Fire_Bomb_Rune.png" }, + name = "Fire Bomb Rune", + price = 29, + itemtype = 2305, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nThis rune is a deadly weapon in the hands of the skilled user. On releasing it an area of 9 square metres is covered by searing flames that will scorch all those that are unfortunate enough to be caught in them. Worse, many monsters are confused by the unexpected blaze, and with a bit of luck a caster will even manage to trap his opponents by using the spell.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Fire_Field_Rune.png" }, + name = "Fire Field Rune", + price = 6, + itemtype = 2301, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nWhen this rune is used a field of one square metre is covered by searing fire that will last for some minutes, gradually diminishing as the blaze wears down. As with all field spells, Fire Field is quite useful to block narrow passageways or to create large, connected barriers.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Fire_Wall_Rune.png" }, + name = "Fire Wall Rune", + price = 12, + itemtype = 2303, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nThis rune offers reliable protection against all creatures that are afraid of fire. The exceptionally long duration of the spell as well as the possibility to form massive barriers or even protective circles out of fire walls make this a versatile, practical spell.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Great_Fireball_Rune.png" }, + name = "Great Fireball Rune", + price = 12, + itemtype = 2304, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nA shot of this rune affects a huge area - up to 37 square metres! It stands to reason that the Great Fireball is a favourite of most Tibians, as it is well suited both to hit whole crowds of monsters and individual targets that are difficult to hit because they are fast or hard to spot.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Icicle_Rune.png" }, + name = "Icicle Rune", + price = 6, + itemtype = 2271, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nParticularly creatures determined by the element fire are vulnerable against this ice-cold rune. Being hit by the magic stored in this rune, an ice arrow seems to pierce the heart of the struck victim. The damage done by this rune is quite impressive which makes this a quite popular rune among Tibian mages.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Intense_Healing_Rune.png" }, + name = "Intense Healing Rune", + price = 19, + itemtype = 2265, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nThis rune is commonly used by young adventurers who are not skilled enough to use the rune's stronger version. Also, since the rune's effectiveness is determined by the user's magic skill, it is still popular among experienced spell casters who use it to get effective healing magic at a cheap price.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Magic_Wall_Rune.png" }, + name = "Magic Wall Rune", + price = 23, + itemtype = 2293, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nThis spell causes all particles that are contained in the surrounding air to quickly gather and contract until a solid wall is formed that covers one full square metre. The wall that is formed that way is impenetrable to any missiles or to light and no creature or character can walk through it. However, the wall will only last for a couple of seconds.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Poison_Bomb_Rune.png" }, + name = "Poison Bomb Rune", + price = 17, + itemtype = 2286, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nThis rune causes an area of 9 square metres to be contaminated with toxic gas that will poison anybody who is caught within it. Conceivable applications include the blocking of areas or the combat against fast-moving or invisible targets. Keep in mind, however, that there are a number of creatures that are immune to poison.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Poison_Wall_Rune.png" }, + name = "Poison Wall Rune", + price = 10, + itemtype = 2289, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nWhen this rune is used a wall of concentrated toxic fumes is created which inflicts a moderate poison on all those who are foolish enough to enter it. The effect is usually impressive enough to discourage monsters from doing so, although few of the stronger ones will hesitate if there is nothing but a poison wall between them and their dinner.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Soulfire_Rune.png" }, + name = "Soulfire Rune", + price = 9, + itemtype = 2308, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nSoulfire is an immensely evil spell as it directly targets a creature's very life essence. When the rune is used on a victim, its soul is temporarily moved out of its body, casting it down into the blazing fires of hell itself! Note that the experience and the mental strength of the caster influence the damage that is caused.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Stone_Shower_Rune.png" }, + name = "Stone Shower Rune", + price = 7, + itemtype = 2288, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nParticularly creatures with an affection to energy will suffer greatly from this rune filled with powerful earth damage. As the name already says, a shower of stones drums on the opponents of the rune user in an area up to 37 squares.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Sudden_Death_Rune.png" }, + name = "Sudden Death Rune", + price = 28, + itemtype = 2268, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nNearly no other spell can compare to Sudden Death when it comes to sheer damage. For this reason it is immensely popular despite the fact that only a single target is affected. However, since the damage caused by the rune is of deadly nature, it is less useful against most undead creatures.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Thunderstorm_Rune.png" }, + name = "Thunderstorm Rune", + price = 9, + itemtype = 2315, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nFlashes filled with dangerous energy hit the rune user's opponent when this rune is being used. It is especially effective against ice dominated creatures. Covering up an area up to 37 squares, this rune is particularly useful when you meet a whole mob of opponents.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Ultimate_Healing_Rune.png" }, + name = "Ultimate Healing Rune", + price = 35, + itemtype = 2273, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nThe coveted Ultimate Healing rune is an all-time favourite among all vocations. No other healing enchantments that are bound into runes can compare to its salutary effect.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + { + icons = { "Wild_Growth_Rune.png" }, + name = "Wild Growth Rune", + price = 32, + itemtype = 2269, + count = 250, + description = "{character}\n{storeinbox}\n{vocationlevelcheck}\n{battlesign}\n{capacity}\n\nBy unleashing this spell, all seeds that are lying dormant in the surrounding quickly sprout and grow into full-sized plants, thus forming an impenetrable thicket. Unfortunately, plant life created this way is short-lived and will collapse within minutes, so the magically created obstacle will not last long.", + type = GameStore.OfferTypes.OFFER_TYPE_STACKABLE, + }, + }, + rookgaard = true, + state = GameStore.States.STATE_NONE, + }, + -- Cosmetics + { + icons = { "Category_Cosmetics.png" }, + name = "Cosmetics", + rookgaard = true, + subclasses = {"Mounts", "Outfits"}, + }, + -- Mounts + { + icons = { "Category_Mounts.png" }, + name = "Mounts", + parent = "Cosmetics", + rookgaard = true, + offers = { + { + icons = { "Arctic_Unicorn.png" }, + name = "Artic Unicorn", + price = 870, + id = 114, + description = "{character}\n{speedboost}\n\nThe Arctic Unicorn lives in a deep rivalry with its cousin the Blazing Unicorn. Even though they were born in completely different areas, they somehow share the same bloodline. The eternal battle between fire and ice continues. Who will win? Tangerine vs.crystal blue! The choice is yours!", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Armoured_War_Horse.png" }, + name = "Armoured War Horse", + price = 870, + id = 23, + description = "{character}\n{speedboost}\n\nThe Armoured War Horse is a dangerous black beauty! When you see its threatening, blood-red eyes coming towards you, you'll know trouble is on its way. Protected by its heavy armour plates, the warhorse is the perfect partner for dangerous hunting sessions and excessive enemy slaughtering.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Batcat.png" }, + name = "Batcat", + price = 870, + id = 77, + description = "{character}\n{speedboost}\n\nRumour has it that many years ago elder witches had gathered to hold a magical feast high up in the mountains. They had crossbred Batcat to easily conquer rocky canyons and deep valleys. Nobody knows what happened on their way up but only the mount has been seen ever since.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Battle_Badger.png" }, + name = "Battle Badger", + price = 690, + id = 147, + description = "{character}\n{speedboost}\n\nBadgers have been a staple of the Tibian fauna for a long time, and finally some daring souls have braved the challenge to tame some exceptional specimens - and succeeded! While the common badger you can encounter during your travels might seem like a rather unassuming creature, the Battle Badger, the Ether Badger, and the Zaoan Badger are fierce and mighty beasts, which are at your beck and call.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Black_Stag.png" }, + name = "Black Stag", + price = 660, + id = 73, + description = "{character}\n{speedboost}\n\nTreat your character to a new travelling companion with a gentle nature and an impressive antler: The noble Black Stag will carry you through the deepest snow.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Blackpelt.png" }, + name = "Blackpelt", + price = 690, + id = 58, + description = "{character}\n{speedboost}\n\nThe Blackpelt is out searching for the best bamboo in Tibia. Its heavy armour allows it to visit even the most dangerous places. Treat it nicely with its favourite food from time to time and it will become a loyal partner.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Blazing_Unicorn.png" }, + name = "Blazing Unicorn", + price = 870, + id = 113, + description = "{character}\n{speedboost}\n\nThe Blazing Unicorn lives in a deep rivalry with its cousin the Arctic Unicorn. Even though they were born in completely different areas, they somehow share the same bloodline. The eternal battle between fire and ice continues. Who will win? Crystal blue vs. tangerine! The choice is yours!", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Bloodcurl.png" }, + name = "Bloodcurl", + price = 750, + id = 92, + description = "{character}\n{speedboost}\n\nYou are fascinated by insectoid creatures and can picture yourself riding one during combat or just for travelling? The Bloodcurl will carry you through the Tibian wilderness with ease.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Boreal_Owl.png" }, + name = "Boreal Owl", + price = 870, + id = 129, + description = "{character}\n{speedboost}\n\nOwls have always been a symbol of mystery, magic and wisdom in Tibian myths and fairy tales. Having one of these enigmatic creatures of the night as a trustworthy companion provides you with a silent guide whose ever-watchful eyes will cut through the shadows, help you navigate the darkness and unravel great secrets.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Bunny_Dray.png" }, + name = "Bunny Dray", + price = 870, + id = 139, + description = "{character}\n{speedboost}\n\nYour lower back worsens with every trip you spend on the back of your mount and you are looking for a more comfortable alternative to travel through the lands? Say no more! The Bunny Dray comes with two top-performing hares that never get tired thanks to the brand new and highly innovative propulsion technology. Just keep some back-up carrots in your pocket and you will be fine!", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Caped_Snowman.png" }, + name = "Caped Snowman", + price = 870, + id = 137, + description = "{character}\n{speedboost}\n\nWhen the nights are getting longer and freezing wind brings driving snow into the land, snowmen rise and shine on every corner. Lately, a peaceful, arcane creature has found shelter in one of them and used its magical power to call the Caped Snowman into being. Wrap yourself up well and warmly and jump on the back of your new frosty companion.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Cave_Tarantula.png" }, + name = "Cave Tarantula", + price = 690, + id = 117, + description = "{character}\n{speedboost}\n\nIt is said that the Cave Tarantula was born long before Banor walked the earth of Tibia. While its parents died in the war against the cruel hordes sent by Brog and Zathroth, their child survived by hiding in skulls of burned enemies. It never left its hiding spot and as it grew older, the skulls merged into its body. Now, it is fully-grown and thirsts for revenge.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Cinderhoof.png" }, + name = "Cinderhoof", + price = 870, + id = 90, + description = "{character}\n{speedboost}\n\nIf you are more of an imp than an angel, you may prefer riding out on a Cinderhoof to scare fellow Tibians on their festive strolls. Its devilish mask, claw-like hands and sharp hooves makes it the perfect companion for any daring adventurer who likes to stand out.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Cony_Cart.png" }, + name = "Cony Cart", + price = 870, + id = 140, + description = "{character}\n{speedboost}\n\nYour lower back worsens with every trip you spend on the back of your mount and you are looking for a more comfortable alternative to travel through the lands? Say no more! The Cony Cart comes with two top-performing hares that never get tired thanks to the brand new and highly innovative propulsion technology. Just keep some back-up carrots in your pocket and you will be fine!", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Copper_Fly.png" }, + name = "Copper Fly", + price = 870, + id = 61, + description = "{character}\n{speedboost}\n\nIf you are more interested in the achievements of science, you may enjoy a ride on the Copper Fly, one of the new insect-like flying machines. Even if you do not move around, the wings of these unusual vehicles are always in motion.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Coralripper.png" }, + name = "Coralripper", + price = 570, + id = 79, + description = "{character}\n{speedboost}\n\nIf the Coralripper moves its fins, it generates enough air pressure that it can even float over land. Its numerous eyes allow it to quickly detect dangers even in confusing situations and eliminate them with one powerful bite. If you watch your fingers, you are going to be good friends.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Cranium_Spider.png" }, + name = "Cranium Spider", + price = 690, + id = 116, + description = "{character}\n{speedboost}\n\nIt is said that the Cranium Spider was born long before Banor walked the earth of Tibia. While its parents died in the war against the cruel hordes sent by Brog and Zathroth, their child survived by hiding in skulls of burned enemies. It never left its hiding spot and as it grew older, the skulls merged into its body. Now, it is fully-grown and thirsts for revenge.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Crimson_Ray.png" }, + name = "Crimson Ray", + price = 870, + id = 33, + description = "{character}\n{speedboost}\n\nHave you ever dreamed of gliding through the air on the back of a winged creature? With its deep red wings, the majestic Crimson Ray is a worthy mount for courageous heroes. Feel like a king on its back as you ride into your next adventure.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Death_Crawler.png" }, + name = "Death Crawler", + price = 600, + id = 46, + description = "{character}\n{speedboost}\n\nThe Death Crawler is a scorpion that has surpassed the natural boundaries of its own kind. Way bigger, stronger and faster than ordinary scorpions, it makes a perfect companion for fearless heroes and explorers. Just be careful of his poisonous sting when you mount it.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Desert_King.png" }, + name = "Desert King", + price = 450, + id = 41, + description = "{character}\n{speedboost}\n\nIts roaring is piercing marrow and bone and can be heard over ten miles away. The Desert King is the undisputed ruler of its territory and no one messes with this animal. Show no fear and prove yourself worthy of its trust and you will get yourself a valuable companion for your adventures.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Doombringer.png" }, + name = "Doombringer", + price = 780, + id = 53, + description = "{character}\n{speedboost}\n\nOnce captured and held captive by a mad hunter, the Doombringer is the result of sick experiments. Fed only with demon dust and concentrated demonic blood it had to endure a dreadful transformation. The demonic blood that is now running through its veins, however, provides it with incredible strength and endurance.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Dreadhare.png" }, + name = "Dreadhare", + price = 870, + id = 104, + description = "{character}\n{speedboost}\n\nDo you like fluffy bunnies but think they are too small? Do you admire the majesty of stags and their antlers but are afraid of their untameable wilderness? Do not worry, the mystic creature Dreadhare consolidates the best qualities of both animals. Hop on its backs and enjoy the ride.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Ebony_Tiger.png" }, + name = "Ebony Tiger", + price = 750, + id = 123, + description = "{character}\n{speedboost}\n\nIt is said that in ancient times, the sabre-tooth tiger was already used as a mount by elder warriors of Svargrond. As seafaring began to expand, this noble big cat was also transported to other regions in Tibia. Influenced by the new environment and climatic changes, the fur of the Ebony Tiger has developed its extraordinary colouring over several generations.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Ember_Saurian.png" }, + name = "Ember Saurian", + price = 750, + id = 111, + description = "{character}\n{speedboost}\n\nThousands of years ago, its ancestors ruled the world. Only recently, it found its way into Tibia. The Ember Saurian has been spotted in a sea of flames and fire deep down in the depths of Kazordoon.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Emerald_Sphinx.png" }, + name = "Emerald Sphinx", + price = 750, + id = 108, + description = "{character}\n{speedboost}\n\nRide an Emerald Sphinx on your way through ancient chambers and tombs and have a loyal friend by your side while fighting countless mummies and other creatures.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Emerald_Waccoon.png" }, + name = "Emerald Waccoon", + price = 750, + id = 70, + description = "{character}\n{speedboost}\n\nWaccoons are cuddly creatures that love nothing more than to be petted and snuggled! Share a hug, ruffle the fur of the Emerald Waccoon and scratch it behind its ears to make it happy.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Emperor_Deer.png" }, + name = "Emperor Deer", + price = 660, + id = 74, + description = "{character}\n{speedboost}\n\nTreat your character to a new travelling companion with a gentle nature and an impressive antler: The noble Emperor Deer will carry you through the deepest snow.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Ether_Badger.png" }, + name = "Ether Badger", + price = 690, + id = 148, + description = "{character}\n{speedboost}\n\nBadgers have been a staple of the Tibian fauna for a long time, and finally some daring souls have braved the challenge to tame some exceptional specimens - and succeeded! While the common badger you can encounter during your travels might seem like a rather unassuming creature, the Battle Badger, the Ether Badger, and the Zaoan Badger are fierce and mighty beasts, which are at your beck and call.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Feral_Tiger.png" }, + name = "Feral Tiger", + price = 750, + id = 124, + description = "{character}\n{speedboost}\n\nIt is said that in ancient times, the sabre-tooth tiger was already used as a mount by elder warriors of Svargrond. As seafaring began to expand, this noble big cat was also transported to other regions in Tibia. Influenced by the new environment and climatic changes, the fur of the Feral Tiger has developed its extraordinary colouring over several generations.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Festive_Snowman.png" }, + name = "Festive Snowman", + price = 900, + id = 135, + description = "{character}\n{speedboost}\n\nWhen the nights are getting longer and freezing wind brings driving snow into the land, snowmen rise and shine on every corner. Lately, a peaceful, arcane creature has found shelter in one of them and used its magical power to call the Festive Snowman into being. Wrap yourself up well and warmly and jump on the back of your new frosty companion.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Gloom_Widow.png" }, + name = "Gloom Widow", + price = 690, + id = 118, + description = "{character}\n{speedboost}\n\nIt is said that the Gloom Widow was born long before Banor walked the earth of Tibia. While its parents died in the war against the cruel hordes sent by Brog and Zathroth, their child survived by hiding in skulls of burned enemies. It never left its hiding spot and as it grew older, the skulls merged into its body. Now, it is fully-grown and thirsts for revenge.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Prismatic_Unicorn.png" }, + name = "Prismatic Unicorn", + price = 870, + id = 115, + description = "{character}\n{speedboost}\n\nLegend has it that a mare and a stallion once reached the end of a rainbow and decided to stay there. Influenced by the mystical power of the rainbow, the mare gave birth to an exceptional foal: Not only the big, strong horn on its forehead but the unusual colouring of its hair makes the Prismatic Unicorn a unique mount in every respect.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Rabbit_Rickshaw.png" }, + name = "Rabbit Rickshaw", + price = 870, + id = 138, + description = "{character}\n{speedboost}\n\nYour lower back worsens with every trip you spend on the back of your mount and you are looking for a more comfortable alternative to travel through the lands? Say no more! The Rabbit Rickshaw comes with two top-performing hares that never get tired thanks to the brand new and highly innovative propulsion technology. Just keep some back-up carrots in your pocket and you will be fine!", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Shadow_Draptor.png" }, + name = "Shadow Draptor", + price = 870, + id = 24, + description = "{character}\n{speedboost}\n\nA wild, ancient creature, which had been hiding in the depths of the shadows for a very long time, has been spotted in Tibia again! The almighty Shadow Draptor has returned and only the bravest Tibians can control such a beast!", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Steelbeak.png" }, + name = "Steelbeak", + price = 870, + id = 34, + description = "{character}\n{speedboost}\n\nForged by only the highest skilled blacksmiths in the depths of Kazordoon's furnaces, a wild animal made out of the finest steel arose from glowing embers and blazing heat. Protected by its impenetrable armour, the Steelbeak is ready to accompany its master on every battleground.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Jungle_Saurian.png" }, + name = "Jungle Saurian", + price = 750, + id = 110, + description = "{character}\n{speedboost}\n\nThousands of years ago, its ancestors ruled the world. Only recently, it found its way into Tibia. The Jungle Saurian likes to hide in dense wood and overturned trees.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Jungle_Tiger.png" }, + name = "Jungle Tiger", + price = 750, + id = 125, + description = "{character}\n{speedboost}\n\nIt is said that in ancient times, the sabre-tooth tiger was already used as a mount by elder warriors of Svargrond. As seafaring began to expand, this noble big cat was also transported to other regions in Tibia. Influenced by the new environment and climatic changes, the fur of the Jungle Tiger has developed its extraordinary colouring over several generations.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Lagoon_Saurian.png" }, + name = "Lagoon Saurian", + price = 750, + id = 112, + description = "{character}\n{speedboost}\n\nThousands of years ago, its ancestors ruled the world. Only recently, it found its way into Tibia. The Lagoon Saurian feels most comfortable in torrential rivers and behind dangerous waterfalls.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Gold_Sphinx.png" }, + name = "Gold Sphinx", + price = 750, + id = 107, + description = "{character}\n{speedboost}\n\nRide a Gold Sphinx on your way through ancient chambers and tombs and have a loyal friend by your side while fighting countless mummies and other creatures.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Shadow_Sphinx.png" }, + name = "Shadow Sphinx", + price = 750, + id = 109, + description = "{character}\n{speedboost}\n\nRide a Shadow Sphinx on your way through ancient chambers and tombs and have a loyal friend by your side while fighting countless mummies and other creatures.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Jackalope.png" }, + name = "Jackalope", + price = 870, + id = 103, + description = "{character}\n{speedboost}\n\nDo you like fluffy bunnies but think they are too small? Do you admire the majesty of stags and their antlers but are afraid of their untameable wilderness? Do not worry, the mystic creature Jackalope consolidates the best qualities of both animals. Hop on its backs and enjoy the ride.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Ivory_Fang.png" }, + name = "Ivory Fang", + price = 750, + id = 100, + description = "{character}\n{speedboost}\n\nIncredible strength and smartness, an irrepressible will to survive, passionately hunting in groups. If these attributes apply to your character, we have found the perfect partner for you. Have a proper look at Ivory Fang, which stands loyally by its master's side in every situation. It is time to become the leader of the wolf pack!", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Shadow_Claw.png" }, + name = "Shadow Claw", + price = 750, + id = 101, + description = "{character}\n{speedboost}\n\nIncredible strength and smartness, an irrepressible will to survive, passionately hunting in groups. If these attributes apply to your character, we have found the perfect partner for you. Have a proper look at Shadow Claw, which stands loyally by its master's side in every situation. It is time to become the leader of the wolf pack!", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Snow_Pelt.png" }, + name = "Snow Pelt", + price = 750, + id = 102, + description = "{character}\n{speedboost}\n\nIncredible strength and smartness, an irrepressible will to survive, passionately hunting in groups. If these attributes apply to your character, we have found the perfect partner for you. Have a proper look at Snow Pelt, which stands loyally by its master's side in every situation. It is time to become the leader of the wolf pack!", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Snowy_Owl.png" }, + name = "Snowy Owl", + price = 870, + id = 128, + description = "{character}\n{speedboost}\n\nOwls have always been a symbol of mystery, magic and wisdom in Tibian myths and fairy tales. Having one of these enigmatic creatures of the night as a trustworthy companion provides you with a silent guide whose ever-watchful eyes will cut through the shadows, help you navigate the darkness and unravel great secrets.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Tawny_Owl.png" }, + name = "Tawny Owl", + price = 870, + id = 127, + description = "{character}\n{speedboost}\n\nOwls have always been a symbol of mystery, magic and wisdom in Tibian myths and fairy tales. Having one of these enigmatic creatures of the night as a trustworthy companion provides you with a silent guide whose ever-watchful eyes will cut through the shadows, help you navigate the darkness and unravel great secrets.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Swamp_Crocovile.png" }, + name = "Swamp Crocovile", + price = 750, + id = 142, + description = "{character}\n{speedboost}\n\nTo the keen observer, the crocovile is clearly a relative of the crocodile, albeit their look suggests an even more aggressive nature. While it is true that the power of its massive and muscular body can not only crush enemies dead but also break through any gate like a battering ram, a crocovile is, above all, a steadfast companion showing unwavering loyalty to its owner.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Swamp_Snapper.png" }, + name = "Swamp Snapper", + price = 690, + id = 95, + description = "{character}\n{speedboost}\n\nYou are intrigued by tortoises and would love to throne on a tortoise shell when travelling the Tibian wilderness? The Swamp Snapper might become your new trustworthy companion then, which will transport you safely and even carry you during combat.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Mould_Shell.png" }, + name = "Mould Shell", + price = 690, + id = 96, + description = "{character}\n{speedboost}\n\nYou are intrigued by tortoises and would love to throne on a tortoise shell when travelling the Tibian wilderness? The Mould Shell might become your new trustworthy companion then, which will transport you safely and even carry you during combat.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Reed_Lurker.png" }, + name = "Reed Lurker", + price = 690, + id = 97, + description = "{character}\n{speedboost}\n\nYou are intrigued by tortoises and would love to throne on a tortoise shell when travelling the Tibian wilderness? The Reed Lurker might become your new trustworthy companion then, which will transport you safely and even carry you during combat.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Leafscuttler.png" }, + name = "Leafscuttler", + price = 750, + id = 93, + description = "{character}\n{speedboost}\n\nYou are fascinated by insectoid creatures and can picture yourself riding one during combat or just for travelling? The Leafscuttler will carry you through the Tibian wilderness with ease.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Mouldpincer.png" }, + name = "Mouldpincer", + price = 750, + id = 91, + description = "{character}\n{speedboost}\n\nYou are fascinated by insectoid creatures and can picture yourself riding one during combat or just for travelling? The Mouldpincer will carry you through the Tibian wilderness with ease.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Muffled_Snowman.png" }, + name = "Muffled Snowman", + price = 900, + id = 136, + description = "{character}\n{speedboost}\n\nWhen the nights are getting longer and freezing wind brings driving snow into the land, snowmen rise and shine on every corner. Lately, a peaceful, arcane creature has found shelter in one of them and used its magical power to call the Muffled Snowman into being. Wrap yourself up well and warmly and jump on the back of your new frosty companion.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Nightdweller.png" }, + name = "Nightdweller", + price = 870, + id = 88, + description = "{character}\n{speedboost}\n\nIf you are more of an imp than an angel, you may prefer riding out on a Nightdweller to scare fellow Tibians on their festive strolls. Its devilish mask, claw-like hands and sharp hooves makes it the perfect companion for any daring adventurer who likes to stand out.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Nightmarish_Crocovile.png" }, + name = "Nightmarish Crocovile", + price = 750, + id = 143, + description = "{character}\n{speedboost}\n\nTo the keen observer, the crocovile is clearly a relative of the crocodile, albeit their look suggests an even more aggressive nature. While it is true that the power of its massive and muscular body can not only crush enemies dead but also break through any gate like a battering ram, a crocovile is, above all, a steadfast companion showing unwavering loyalty to its owner.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Frostflare.png" }, + name = "Frostflare", + price = 870, + id = 89, + description = "{character}\n{speedboost}\n\nIf you are more of an imp than an angel, you may prefer riding out on a Frostflare to scare fellow Tibians on their festive strolls. Its devilish mask, claw-like hands and sharp hooves makes it the perfect companion for any daring adventurer who likes to stand out.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Slagsnare.png" }, + name = "Slagsnare", + price = 780, + id = 84, + description = "{character}\n{speedboost}\n\nThe Slagsnare has external characteristics of different breeds. It is assumed that his brain is also composed of many different species, which makes it completely unpredictable. Only few have managed to approach this creature unharmed and only the best could tame it.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Nightstinger.png" }, + name = "Nightstinger", + price = 780, + id = 85, + description = "{character}\n{speedboost}\n\nThe Nightstinger has external characteristics of different breeds. It is assumed that his brain is also composed of many different species, which makes it completely unpredictable. Only few have managed to approach this creature unharmed and only the best could tame it.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Razorcreep.png" }, + name = "Razorcreep", + price = 780, + id = 86, + description = "{character}\n{speedboost}\n\nThe Razorcreep has external characteristics of different breeds. It is assumed that his brain is also composed of many different species, which makes it completely unpredictable. Only few have managed to approach this creature unharmed and only the best could tame it.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Gorongra.png" }, + name = "Gorongra", + price = 720, + id = 81, + description = "{character}\n{speedboost}\n\nGet yourself a mighty travelling companion with broad shoulders and a gentle heart. Gorongra is a physically imposing creature that is much more peaceful than its relatives, Tiquanda's wild kongras, and will carry you safely wherever you ask it to go.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Noctungra.png" }, + name = "Noctungra", + price = 720, + id = 82, + description = "{character}\n{speedboost}\n\nGet yourself a mighty travelling companion with broad shoulders and a gentle heart. Noctungra is a physically imposing creature that is much more peaceful than its relatives, Tiquanda's wild kongras, and will carry you safely wherever you ask it to go.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Silverneck.png" }, + name = "Silverneck", + price = 720, + id = 83, + description = "{character}\n{speedboost}\n\nGet yourself a mighty travelling companion with broad shoulders and a gentle heart. Silverneck is a physically imposing creature that is much more peaceful than its relatives, Tiquanda's wild kongras, and will carry you safely wherever you ask it to go.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Sea_Devil.png" }, + name = "Sea Devil", + price = 570, + id = 78, + description = "{character}\n{speedboost}\n\nIf the Sea Devil moves its fins, it generates enough air pressure that it can even float over land. Its numerous eyes allow it to quickly detect dangers even in confusing situations and eliminate them with one powerful bite. If you watch your fingers, you are going to be good friends.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Plumfish.png" }, + name = "Plumfish", + price = 570, + id = 80, + description = "{character}\n{speedboost}\n\nIf the Plumfish moves its fins, it generates enough air pressure that it can even float over land. Its numerous eyes allow it to quickly detect dangers even in confusing situations and eliminate them with one powerful bite. If you watch your fingers, you are going to be good friends.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Flitterkatzen.png" }, + name = "Flitterkatzen", + price = 870, + id = 75, + description = "{character}\n{speedboost}\n\nRumour has it that many years ago elder witches had gathered to hold a magical feast high up in the mountains. They had crossbred Flitterkatzen to easily conquer rocky canyons and deep valleys. Nobody knows what happened on their way up but only the mount has been seen ever since.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Ringtail_Waccoon.png" }, + name = "Ringtail Waccoon", + price = 750, + id = 68, + description = "{character}\n{speedboost}\n\nWaccoons are cuddly creatures that love nothing more than to be petted and snuggled! Share a hug, ruffle the fur of the Ringtail Waccoon and scratch it behind its ears to make it happy.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "River_Crocovile.png" }, + name = "River Crocovile", + price = 750, + id = 141, + description = "{character}\n{speedboost}\n\nTo the keen observer, the crocovile is clearly a relative of the crocodile, albeit their look suggests an even more aggressive nature. While it is true that the power of its massive and muscular body can not only crush enemies dead but also break through any gate like a battering ram, a crocovile is, above all, a steadfast companion showing unwavering loyalty to its owner.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Sanguine_Frog.png" }, + name = "Sanguine Frog", + price = 690, + id = 121, + description = "{character}\n{speedboost}\n\nFor centuries, humans and monsters have dumped their garbage in the swamps around Venore. The combination of old, rusty weapons, stale mana and broken runes have turned some of the swamp dwellers into gigantic frogs. Benefit from those mutations and make the Sanguine Frog a faithful mount for your adventures even beyond the bounds of the swamp.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Night_Waccoon.png" }, + name = "Night Waccoon", + price = 750, + id = 69, + description = "{character}\n{speedboost}\n\nWaccoons are cuddly creatures that love nothing more than to be petted and snuggled! Share a hug, ruffle the fur of the Night Waccoon and scratch it behind its ears to make it happy.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Flying_Divan.png" }, + name = "Flying Divan", + price = 900, + id = 65, + description = "{character}\n{speedboost}\n\nThe Flying Divan is the perfect mount for those who are too busy to take care of an animal mount or simply like to travel on a beautiful, magic hand-woven carpet.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Magic_Carpet.png" }, + name = "Magic Carpet", + price = 900, + id = 66, + description = "{character}\n{speedboost}\n\nThe Magic Carpet is the perfect mount for those who are too busy to take care of an animal mount or simply like to travel on a beautiful, magic hand-woven carpet.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Marsh_Toad.png" }, + name = "Marsh Toad", + price = 690, + id = 120, + description = "{character}\n{speedboost}\n\nThe Magic Carpet is the perfect mount for those who are too busy to take cFor centuries, humans and monsters have dumped their garbage in the swamps around Venore. The combination of old, rusty weapons, stale mana and broken runes have turned some of the swamp dwellers into gigantic frogs. Benefit from those mutations and make the Marsh Toad a faithful mount for your adventures even beyond the bounds of the swamp.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Floating_Kashmir.png" }, + name = "Floating Kashmir", + price = 900, + id = 67, + description = "{character}\n{speedboost}\n\nThe Floating Kashmir is the perfect mount for those who are too busy to take care of an animal mount or simply like to travel on a beautiful, magic hand-woven carpet.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Shadow_Hart.png" }, + name = "Shadow Hart", + price = 660, + id = 72, + description = "{character}\n{speedboost}\n\nTreat your character to a new travelling companion with a gentle nature and an impressive antler: The noble Shadow Hart will carry you through the deepest snow.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Tundra_Rambler.png" }, + name = "Tundra Rambler", + price = 750, + id = 62, + description = "{character}\n{speedboost}\n\nWith its thick, shaggy hair, the Tundra Rambler will keep you warm even in the chilly climate of the Ice Islands. Due to its calm and peaceful nature, it is not letting itself getting worked up easily.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Highland_Yak.png" }, + name = "Highland Yak", + price = 750, + id = 63, + description = "{character}\n{speedboost}\n\nWith its thick, shaggy hair, the Highland Yak will keep you warm even in the chilly climate of the Ice Islands. Due to its calm and peaceful nature, it is not letting itself getting worked up easily.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Glacier_Vagabond.png" }, + name = "Glacier Vagabond", + price = 750, + id = 64, + description = "{character}\n{speedboost}\n\nWith its thick, shaggy hair, the Glacier Vagabond will keep you warm even in the chilly climate of the Ice Islands. Due to its calm and peaceful nature, it is not letting itself getting worked up easily.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Golden_Dragonfly.png" }, + name = "Golden Dragonfly", + price = 600, + id = 59, + description = "{character}\n{speedboost}\n\nIf you are more interested in the achievements of science, you may enjoy a ride on the Golden Dragonfly, one of the new insect-like flying machines. Even if you do not move around, the wings of these unusual vehicles are always in motion.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Steel_Bee.png" }, + name = "Steel Bee", + price = 600, + id = 60, + description = "{character}\n{speedboost}\n\nIf you are more interested in the achievements of science, you may enjoy a ride on the Steel Bee, one of the new insect-like flying machines. Even if you do not move around, the wings of these unusual vehicles are always in motion.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Hailstorm_Fury.png" }, + name = "Hailtorm Fury", + price = 780, + id = 55, + description = "{character}\n{speedboost}\n\nOnce captured and held captive by a mad hunter, the Hailstorm Fury is the result of sick experiments. Fed only with demon dust and concentrated demonic blood it had to endure a dreadful transformation. The demonic blood that is now running through its veins, however, provides it with incredible strength and endurance.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Siegebreaker.png" }, + name = "Siegebreaker", + price = 690, + id = 56, + description = "{character}\n{speedboost}\n\nThe Siegebreaker is out searching for the best bamboo in Tibia. Its heavy armour allows it to visit even the most dangerous places. Treat it nicely with its favourite food from time to time and it will become a loyal partner.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Poisonbane.png" }, + name = "Poisonbane", + price = 690, + id = 57, + description = "{character}\n{speedboost}\n\nThe Poisonbane is out searching for the best bamboo in Tibia. Its heavy armour allows it to visit even the most dangerous places. Treat it nicely with its favourite food from time to time and it will become a loyal partner.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Nethersteed.png" }, + name = "Nethersteed", + price = 900, + id = 50, + description = "{character}\n{speedboost}\n\nOnce a majestic and proud warhorse, the Nethersteed has fallen in a horrible battle many years ago. Driven by agony and pain, its spirit once again took possession of its rotten corpse to avenge its death. Stronger than ever, it seeks a master to join the battlefield, aiming for nothing but death and destruction.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Tempest.png" }, + name = "Tempest", + price = 900, + id = 51, + description = "{character}\n{speedboost}\n\nOnce a majestic and proud warhorse, the Tempest has fallen in a horrible battle many years ago. Driven by agony and pain, its spirit once again took possession of its rotten corpse to avenge its death. Stronger than ever, it seeks a master to join the battlefield, aiming for nothing but death and destruction.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Flamesteed.png" }, + name = "Flamesteed", + price = 900, + id = 47, + description = "{character}\n{speedboost}\n\nOnce a majestic and proud warhorse, the Flamesteed has fallen in a horrible battle many years ago. Driven by agony and pain, its spirit once again took possession of its rotten corpse to avenge its death. Stronger than ever, it seeks a master to join the battlefield, aiming for nothing but death and destruction.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Tombstinger.png" }, + name = "Tombstinger", + price = 600, + id = 36, + description = "{character}\n{speedboost}\n\nThe Tombstinger is a scorpion that has surpassed the natural boundaries of its own kind. Way bigger, stronger and faster than ordinary scorpions, it makes a perfect companion for fearless heroes and explorers. Just be careful of his poisonous sting when you mount it.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Toxic_Toad.png" }, + name = "Toxic Toad", + price = 690, + id = 122, + description = "{character}\n{speedboost}\n\nFor centuries, humans and monsters have dumped their garbage in the swamps around Venore. The combination of old, rusty weapons, stale mana and broken runes have turned some of the swamp dwellers into gigantic frogs. Benefit from those mutations and make the Toxic Toad a faithful mount for your adventures even beyond the bounds of the swamp.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Jade_Pincer.png" }, + name = "Jade Pincer", + price = 600, + id = 49, + description = "{character}\n{speedboost}\n\nThe Jade Pincer is a scorpion that has surpassed the natural boundaries of its own kind. Way bigger, stronger and faster than ordinary scorpions, it makes a perfect companion for fearless heroes and explorers. Just be careful of his poisonous sting when you mount it.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Jade_Lion.png" }, + name = "Jade Lion", + price = 450, + id = 48, + description = "{character}\n{speedboost}\n\nIts roaring is piercing marrow and bone and can be heard over ten miles away. The Jade Lion is the undisputed ruler of its territory and no one messes with this animal. Show no fear and prove yourself worthy of its trust and you will get yourself a valuable companion for your adventures.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Venompaw.png" }, + name = "Venompaw", + price = 870, + id = 76, + description = "{character}\n{speedboost}\n\nRumour has it that many years ago elder witches had gathered to hold a magical feast high up in the mountains. They had crossbred Venompaw to easily conquer rocky canyons and deep valleys. Nobody knows what happened on their way up but only the mount has been seen ever since.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Winter_King.png" }, + name = "Winter King", + price = 450, + id = 52, + description = "{character}\n{speedboost}\n\nIts roaring is piercing marrow and bone and can be heard over ten miles away. The Winter King is the undisputed ruler of its territory and no one messes with this animal. Show no fear and prove yourself worthy of its trust and you will get yourself a valuable companion for your adventures.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Wolpertinger.png" }, + name = "Wolpertinger", + price = 870, + id = 105, + description = "{character}\n{speedboost}\n\nOnce captured and held captive by a mad hunter, the Woodland Prince is the result of sick experiments. Fed only with demon dust and concentrated demonic blood it had to endure a dreadful transformation. The demonic blood that is now running through its veins, however, provides it with incredible strength and endurance.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Woodland_Prince.png" }, + name = "Woodland Prince", + price = 780, + id = 54, + description = "{character}\n{speedboost}\n\nOnce captured and held captive by a mad hunter, the Woodland Prince is the result of sick experiments. Fed only with demon dust and concentrated demonic blood it had to endure a dreadful transformation. The demonic blood that is now running through its veins, however, provides it with incredible strength and endurance.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Zaoan_Badger.png" }, + name = "Zaoan Badger", + price = 690, + id = 149, + description = "{character}\n{speedboost}\n\nBadgers have been a staple of the Tibian fauna for a long time, and finally some daring souls have braved the challenge to tame some exceptional specimens - and succeeded! While the common badger you can encounter during your travels might seem like a rather unassuming creature, the Battle Badger, the Ether Badger, and the Zaoan Badger are fierce and mighty beasts, which are at your beck and call.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Floating_Augur.png" }, + name = "Floating Augur", + price = 870, + id = 155, + description = "{character}\n{speedboost}\n\nThese creatures are Floating Savants whose mind has been warped and bent to focus their extraordinary mental capabilities on one single goal: to do their master's bidding. Instead of being filled with an endless pursuit of knowledge, their live is now one of continuous thralldom and serfhood. The Floating Sage, the Floating Scholar and the Floating Augur are at your disposal.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Floating_Sage.png" }, + name = "Floating Sage", + price = 870, + id = 153, + description = "{character}\n{speedboost}\n\nThese creatures are Floating Savants whose mind has been warped and bent to focus their extraordinary mental capabilities on one single goal: to do their master's bidding. Instead of being filled with an endless pursuit of knowledge, their live is now one of continuous thralldom and serfhood. The Floating Sage, the Floating Scholar and the Floating Augur are at your disposal.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Floating_Scholar.png" }, + name = "Floating Scholar", + price = 870, + id = 154, + description = "{character}\n{speedboost}\n\nThese creatures are Floating Savants whose mind has been warped and bent to focus their extraordinary mental capabilities on one single goal: to do their master's bidding. Instead of being filled with an endless pursuit of knowledge, their live is now one of continuous thralldom and serfhood. The Floating Sage, the Floating Scholar and the Floating Augur are at your disposal.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Snow_Strider.png" }, + name = "Snow Strider", + price = 870, + id = 164, + description = "{character}\n{speedboost}\n\nA magical fire burns inside these wolves. Bred as the faithful guardians for an eccentric wizard's tower, these creatures make for loyal companions during your travels. While not originally intended for riding, their sturdy frame makes the Dawn Strayer, Dusk Pryer and Snow Strider suitable mounts.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Dusk_Pryer.png" }, + name = "Dusk Pryer", + price = 870, + id = 165, + description = "{character}\n{speedboost}\n\nA magical fire burns inside these wolves. Bred as the faithful guardians for an eccentric wizard's tower, these creatures make for loyal companions during your travels. While not originally intended for riding, their sturdy frame makes the Dawn Strayer, Dusk Pryer and Snow Strider suitable mounts.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Dawn_Strayer.png" }, + name = "Dawn Strayer", + price = 870, + id = 166, + description = "{character}\n{speedboost}\n\nA magical fire burns inside these wolves. Bred as the faithful guardians for an eccentric wizard's tower, these creatures make for loyal companions during your travels. While not originally intended for riding, their sturdy frame makes the Dawn Strayer, Dusk Pryer and Snow Strider suitable mounts.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Savanna_Ostrich.png" }, + name = "Savanna Ostrich", + price = 500, + id = 168, + description = "{character}\n{speedboost}\n\nThese birds have a strong maternal instinct since their fledglings are completely dependent on their parents for protection. Do not expect them to abandon their brood only because they are carrying you around. In fact, if you were to separate them from their chick, the Savanna Ostrich, Coral Rhea and Eventide Nandu would turn into vicious beings, so don't even try it!", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Coral_Rhea.png" }, + name = "Coral Rhea", + price = 500, + id = 169, + description = "{character}\n{speedboost}\n\nThese birds have a strong maternal instinct since their fledglings are completely dependent on their parents for protection. Do not expect them to abandon their brood only because they are carrying you around. In fact, if you were to separate them from their chick, the Savanna Ostrich, Coral Rhea and Eventide Nandu would turn into vicious beings, so don't even try it!", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Eventide_Nandu.png" }, + name = "Eventide Nandu", + price = 500, + id = 170, + description = "{character}\n{speedboost}\n\nThese birds have a strong maternal instinct since their fledglings are completely dependent on their parents for protection. Do not expect them to abandon their brood only because they are carrying you around. In fact, if you were to separate them from their chick, the Savanna Ostrich, Coral Rhea and Eventide Nandu would turn into vicious beings, so don't even try it!", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Voracious_Hyaena.png" }, + name = "Voracious Hyaena", + price = 750, + id = 171, + description = "{character}\n{speedboost}\n\nThe Cunning Hyaena, Scruffy Hyaena and Voracious Hyaena are highly social animals and loyal companions to whomever is able to befriend them. Coming from sun-soaked places, they prefer a warm climate, but are able to cope in other environments as well.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Cunning_Hyaena.png" }, + name = "Cunning Hyaena", + price = 750, + id = 172, + description = "{character}\n{speedboost}\n\nThe Cunning Hyaena, Scruffy Hyaena and Voracious Hyaena are highly social animals and loyal companions to whomever is able to befriend them. Coming from sun-soaked places, they prefer a warm climate, but are able to cope in other environments as well.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Scruffy_Hyaena.png" }, + name = "Scruffy Hyaena", + price = 750, + id = 173, + description = "{character}\n{speedboost}\n\nThe Cunning Hyaena, Scruffy Hyaena and Voracious Hyaena are highly social animals and loyal companions to whomever is able to befriend them. Coming from sun-soaked places, they prefer a warm climate, but are able to cope in other environments as well.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + }, + { + icons = { "Void_Watcher.png" }, + name = "Void Watcher", + price = 870, + id = 179, + description = "{character}\n{speedboost}\n\nIf you are looking for a vigilant and faithful companion, look no further! Glide through every realm and stare into the darkest abyss on the back of a Void Watcher. They already know everything about you anyway for they have been watching you from the shadows!", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + home = true, + }, + { + icons = { "Rune_Watcher.png" }, + name = "Rune Watcher", + price = 870, + id = 180, + description = "{character}\n{speedboost}\n\nIf you are looking for a vigilant and faithful companion, look no further! Glide through every realm and stare into the darkest abyss on the back of a Rune Watcher. They already know everything about you anyway for they have been watching you from the shadows!", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + home = true, + }, + { + icons = { "Rift_Watcher.png" }, + name = "Rift Watcher", + price = 870, + id = 181, + description = "{character}\n{speedboost}\n\nIf you are looking for a vigilant and faithful companion, look no further! Glide through every realm and stare into the darkest abyss on the back of a Rift Watcher. They already know everything about you anyway for they have been watching you from the shadows!", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + home = true, + }, + }, + rookgaard = true, + state = GameStore.States.STATE_NONE, + }, + -- Base outfit has addon = 0 or no defined addon. By default addon is set to 0. + { + icons = { "Category_Outfits.png" }, + name = "Outfits", + parent = "Cosmetics", + offers = { + { + icons = { "Outfit_Arena_Champion_Male_Addon_3.png", "Outfit_Arena_Champion_Female_Addon_3.png" }, + name = "Full Arena Champion Outfit", + price = 870, + sexId = {female = 885, male = 884}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nFight your bloody battles in the arena and become a darling of the crowd. Once you have made it to the top and everyone is cheering your name, the fashionable outfit of an Arena Champion will show the world what you are made of.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Beastmaster_Male_Addon_3.png", "Outfit_Beastmaster_Female_Addon_3.png" }, + name = "Full Beastmaster Outfit", + price = 870, + sexId = {female = 636, male = 637}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nDo you have enough authority to make wild animals subservient to you? Become a Beastmaster and surround yourself with fearsome companions. When your beasts bare their teeth, your enemies will turn tails and run.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Breezy_Garb_Male_Addon_3.png", "Outfit_Breezy_Garb_Female_Addon_3.png" }, + name = "Full Breezy Garb Outfit", + price = 600, + sexId = {female = 1246, male = 1245}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nEven the most eager adventurers and toughest warriors need some time to rest and recharge. Enjoy tranquility and peace as you picnic in good company at one of your favourite places in Tibia. Put on your Breezy Garb outfit, grab your walking stick, a basket filled with tasty snacks and then head out into nature!", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Ceremonial_Garb_Male_Addon_3.png", "Outfit_Ceremonial_Garb_Female_Addon_3.png" }, + name = "Full Ceremonial Garb Outfit", + price = 750, + sexId = {female = 694, male = 695}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nIf you want to make a great entrance at a Tibian costume party, the Ceremonial Garb is certainly a good choice. With a drum over your shoulder and adorned with feathers you are perfectly dressed to lead a carnival parade through the streets of Thais.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Champion_Male_Addon_3.png", "Outfit_Champion_Female_Addon_3.png" }, + name = "Full Champion Outfit", + price = 570, + sexId = {female = 632, male = 633}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nProtect your body with heavy armour plates and spiky bones to teach your enemies the meaning of fear! The Champion outfit perfectly suits battle-hardened warriors who rely on their trusty sword and shield.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Chaos_Acolyte_Male_Addon_3.png", "Outfit_Chaos_Acolyte_Female_Addon_3.png" }, + name = "Full Chaos Acolyte Outfit", + price = 900, + sexId = {female = 664, male = 665}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nYou have always felt like the cat among the pigeons and have a fable for dark magic? The Chaos Acolyte outfit is a perfect way to express your inner nature. Show your commitment for the higher cause and wreak havoc on your enemies in this unique outfit.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Conjurer_Male_Addon_3.png", "Outfit_Conjurer_Female_Addon_3.png" }, + name = "Full Conjurer Outfit", + price = 750, + sexId = {female = 635, male = 634}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nYou recently graduated from the Magic Academy and want to bring your knowledge to good use? Congratulations, you are now an honourable disciple of magic! Open up a bottle of well-aged mana and treat yourself with the fashionable Conjurer outfit.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Death_Herald_Male_Addon_3.png", "Outfit_Death_Herald_Female_Addon_3.png" }, + name = "Full Death Herald Outfit", + price = 600, + sexId = {female = 666, male = 667}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nDeath and decay are your ever-present companions? Your enemies are dropping like flies and your path is covered with their bodies? However, as decency demands, you want to at least give them a proper funeral? Then the Death Herald is just the right outfit for you.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Entrepreneur_Male_Addon_3.png", "Outfit_Entrepreneur_Female_Addon_3.png" }, + name = "Full Entrepreneur Outfit", + price = 750, + sexId = {female = 471, male = 472}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nSlaughter through hordes of monsters during your early morning hunt and kiss the hand of Queen Eloise later on at the evening reception in her historical residence. With the Entrepreneur outfit you will cut a fine figure on every occasion.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Evoker_Male_Addon_3.png", "Outfit_Evoker_Female_Addon_3.png" }, + name = "Full Evoker Outfit", + price = 840, + sexId = {female = 724, male = 725}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nDance around flickering fires in the Evoker outfit while singing unholy chants to praise witchcraft and wizardry. Your faithful bat will always be by your side.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Grove_Keeper_Male_Addon_3.png", "Outfit_Grove_Keeper_Female_Addon_3.png" }, + name = "Full Groove Keeper Outfit", + price = 870, + sexId = {female = 909, male = 908}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nFeeling the springy grass under your feet and inhaling the spicy air of the forest is pure satisfaction for your soul? Every animal is your friend and you caringly look after trees and plants all the time? Then it is time to become one with nature: Become a Grove Keeper!", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Guidon_Bearer_Male_Addon_3.png", "Outfit_Guidon_Bearer_Female_Addon_3.png" }, + name = "Full Guidon Bearer Outfit", + price = 870, + sexId = {female = 1187, male = 1186}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nCarrying the guidon of a unit, always marching in front, is not only an honour but also comes with great responsibility. Guidon bearers wield great power, they lead where others follow and keep the spirits of the troops up as they wave their flag against the golden suns of Tibia.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Herbalist_Male_Addon_3.png", "Outfit_Herbalist_Female_Addon_3.png" }, + name = "Full Herbalist Outfit", + price = 750, + sexId = {female = 1020, male = 1021}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nThe Herbalist outfit is the perfect outfit for all herbs collectors. Those of you who are aware that you do not necessarily have to reach into the mouth of a hydra to get a hydra tongue and those who know exactly where to get blood- and shadow-herbs will find a matching outfit for their daily hobby. Show the world your affinity for herbs and impress your friends with your knowledge of medicine and potions.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Herder_Male_Addon_3.png", "Outfit_Herder_Female_Addon_3.png" }, + name = "Full Herder Outfit", + price = 750, + sexId = {female = 1280, male = 1279}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nThe Herder is one with nature, being outside all day, watching carefully over his flock. If you like to spend time on picturesque meadows and are always looking for greener pastures, then this outfit is for you.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Lupine_Warden_Male_Addon_3.png", "Outfit_Lupine_Warden_Female_Addon_3.png" }, + name = "Full Lupine Warden Outfit", + price = 840, + sexId = {female = 900,male = 899}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nDo you feel the adrenaline rushing through your veins when the sun goes down and a full moon lightens the night? Do you have the urge to hunt down your target no matter what? Unleash the beast inside of you and lead your friends to battle with the Lupine Warden outfit!", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Mercenary_Male_Addon_3.png", "Outfit_Mercenary_Female_Addon_3.png" }, + name = "Full Mercenary Outfit", + price = 870, + sexId = {female = 1057, male = 1056}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nThe Mercenary carries a powerful, razor-sharp axe on his shoulders that effortlessly cuts through any armour and bone. You should better tell your friends to keep a safe distance, since heads will roll over the blood-soaked battleground after a powerful swing of yours.\nConsidering the sheer size of this axe, it might even be possible to chop onions without shedding a tear.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Owl_Keeper_Male_Addon_3.png", "Outfit_Owl_Keeper_Female_Addon_3.png" }, + name = "Full Owl Keeper Outfit", + price = 600, + sexId = {female = 1174,male = 1173}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nOwl Keepers are often referred to as spirits walking through the forest at night, mere shadows during the day. They are also said to be shamans, protecting the flora and fauna of the Tibian lands. You often see them wearing a stag's antlers on their head and in the company of an owl, for they are as wise and mysterious as these intriguing creatures.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Pharaoh_Male_Addon_3.png", "Outfit_Pharaoh_Female_Addon_3.png" }, + name = "Full Pharaoh Outfit", + price = 750, + sexId = {female = 956,male = 955}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nYou know how to read hieroglyphs? You admire the exceptional architectural abilities and the unsolved mysteries of an ancient high culture? Next time you pay a visit to your friends, tell them to prepare a bathtub full of milk and honey for you because a Pharaoh is now walking through the streets of Ankrahmun!", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Philosopher_Male_Addon_3.png", "Outfit_Philosopher_Female_Addon_3.png" }, + name = "Full Philosopher Outfit", + price = 750, + sexId = {female = 874,male = 873}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nDo you feel the urge to tell people what is really going on in the world? Do you know all answers to the important questions of life? Are you a true philosopher? Then dress like one to showcase the latest fashion for all wise theorists.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Pumpkin_Mummy_Male_Addon_3.png", "Outfit_Pumpkin_Mummy_Female_Addon_3.png" }, + name = "Full Pumpkin Mummy Outfit", + price = 870, + sexId = {female = 1128,male = 1127}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nIf you cannot decide whether to wrap yourself up as a mummy or flaunt an enormous pumpkin head for your next hunting party, why not combine both? The Pumpkin Mummy outfit is the perfect costume for scary nights and spooky days.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Puppeteer_Male_Addon_3.png", "Outfit_Puppeteer_Female_Addon_3.png" }, + name = "Full Puppeteer Outfit", + price = 870, + sexId = {female = 696, male = 697}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nAre you a fan of puppetry? You like to travel the world together with one or two little acting fellows? Or are you simply the one who likes to pull the strings? Then the Puppeteer outfit is the right choice for you.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Ranger_Male_Addon_3.png", "Outfit_Ranger_Female_Addon_3.png" }, + name = "Full Ranger Outfit", + price = 750, + sexId = {female = 683,male = 684}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nMost of the day, the Ranger is looking over his forest. He is taking care of all animals and plants and tries to keep everything in balance. Intruders are greeted by a warning shot from his deadly longbow. It is the perfect outfit for Paladins who live in close touch with nature.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Royal_Pumpkin_Male_Addon_3.png", "Outfit_Royal_Pumpkin_Female_Addon_3.png" }, + name = "Full Royal Pumpkin Outfit", + price = 840, + sexId = {male= 760, female= 759}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nThe mutated pumpkin is too weak for your mighty weapons? Time to show that evil vegetable how to scare the living daylight out of people! Put on a scary looking pumpkin on your head and spread terror and fear amongst the Tibian population.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Sea_Dog_Male_Addon_3.png", "Outfit_Sea_Dog_Female_Addon_3.png" }, + name = "Full Sea Dog Outfit", + price = 600, + sexId = {female = 749,male = 750}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nAhoy mateys! Flaunt the swashbuckling Sea Dog outfit and strike a pose with your hook to impress both landlubbers and fellow pirates. Board your next ship in style!", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Seaweaver_Male_Addon_3.png", "Outfit_Seaweaver_Female_Addon_3.png" }, + name = "Full Seaweaver Outfit", + price = 570, + sexId = {female = 732,male = 733}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nThe Seaweaver outfit is the perfect choice if you want to show the world that you are indeed a son or a daughter of the submarine kingdom. You can almost feel the salty taste and the rough wind of the sea when wearing it.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Siege_Master_Male_Addon_3.png", "Outfit_Siege_Master_Female_Addon_3.png" }, + name = "Full Siege Master Outfit", + price = 600, + sexId = {female = 1050,male = 1051}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nNeither thick stone walls nor heavily armoured gates can stop the Siege Master, who brings down hostile fortifications in the blink of an eye. Whenever he tenses his muscular arms to lift the powerful battering ram, his enemies' knees begin to buckle. It is the perfect outfit for those who also stand for brute strength and immense destruction.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Sinister_Archer_Male_Addon_3.png", "Outfit_Sinister_Archer_Female_Addon_3.png" }, + name = "Full Sinister Archer Outfit", + price = 600, + sexId = {female = 1103,male = 1102}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nFrom an early age, the Sinister Archer has been fascinated by people's dark machinations and perversions. Sinister Archers claim that they advocate the good and that they only use their arrows to pierce the hearts of those who have committed many crimes and misdeeds. However, they are still viewed by the public with much suspicion due to their dubious appearance. To keep their identity secret, they often hide themselves behind a skull-like face guard that can easily withstand even axe and club blows.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Spirit_Caller_Male_Addon_3.png", "Outfit_Spirit_Caller_Female_Addon_3.png" }, + name = "Full Spirit Caller Outfit", + price = 600, + sexId = {female = 698, male = 699}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nYou are in love with the deep soul of Mother Earth and prefer to walk in the shadows of her wooden children? Choose the Spirit Caller outfit to live in harmony with nature.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Sun_Priest_Male_Addon_3.png", "Outfit_Sun_Priest_Female_Addon_3.png" }, + name = "Full Sun Priest Outfit", + price = 750, + sexId = {female = 1024, male = 1023}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nDo you worship warm temperatures and are opposed to the thought of long and dark winter nights? Do you refuse to spend countless evenings in front of your chimney while ice-cold wind whistles through the cracks and niches of your house? It is time to stop freezing and to become an honourable Sun Priest! With this stylish outfit, you can finally show the world your unconditional dedication and commitment to the sun!", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Trophy_Hunter_Male_Addon_3.png", "Outfit_Trophy_Hunter_Female_Addon_3.png" }, + name = "Full Trophy Hunter Outfit", + price = 870, + sexId = {female = 900, male = 899}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nYou spend hours in the woods in search of wild and rare animals? Countless stuffed skulls of deer, wolves and other creatures are decorating your walls? Now you have the chance to present your trophies in public. Become a Trophy Hunter and cover your shoulders with the finest bear skulls!", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Winter_Warden_Male_Addon_3.png", "Outfit_Winter_Warden_Female_Addon_3.png" }, + name = "Full Winter Warden Outfit", + price = 870, + sexId = {female = 852,male = 853}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nThe warm and cosy cloak of the Winter Warden outfit will keep you warm in every situation. Best thing, it is not only comfortable but fashionable as well. You will be the envy of any snow queen or king, guaranteed!", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Retro_Citizen_Male.png", "Outfit_Retro_Citizen_Female.png" }, + name = "Retro Citizen", + price = 870, + sexId = {female = 975,male = 974}, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n\nDo you still remember your first stroll through the streets of Thais? For old times' sake, walk the paths of Nostalgia as a Retro Citizen!", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Retro_Hunter_Male.png", "Outfit_Retro_Hunter_Female.png" }, + name = "Retro Hunter", + price = 870, + sexId = {female = 973,male = 972}, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n\nWhenever you pick up your bow and spears, you walk down memory lane and think of your early days? Treat yourself with the fashionable Retro Hunter outfit and hunt some good old monsters from your childhood.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Retro_Knight_Male.png", "Outfit_Retro_Knight_Female.png" }, + name = "Retro Knight", + price = 870, + sexId = {female = 971,male = 970}, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n\nWho needs a fancy looking sword with bling-bling and ornaments? Back in the days, we survived without such unnecessary accessories! Time to show those younkers what a Retro Knight is made of.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Retro_Mage_Male.png", "Outfit_Retro_Mage_Female.png" }, + name = "Retro Wizzard", + price = 870, + sexId = {female = 969, male = 968}, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n\nDress up as a Retro Mage and you will always cut a fine figure on the battleground while eliminating your enemies with your magical powers the old-fashioned way.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Retro_Nobleman_Male.png", "Outfit_Retro_Nobleman_Female.png" }, + name = "Retro Noblewoman", + price = 870, + sexId = { female = 967, male = 966}, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n\nKing Tibianus has invited you to a summer ball and you have nothing to wear for this special event? Do not worry, the Retro Noble(wo)man outfit makes you a real eye catcher on every festive occasion.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Retro_Summoner_Male.png", "Outfit_Retro_Summoner_Female.png" }, + name = "Retro Summoner", + price = 870, + sexId = {female = 965, male = 964}, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n\nWhile the Retro Mage usually throws runes and mighty spells directly at the enemies, the Retro Summoner outfit might be the better choice for Tibians that prefer to send mighty summons to the battlefield to keep their enemies at distance.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Retro_Warrior_Male.png", "Outfit_Retro_Warrior_Female.png" }, + name = "Retro Warrior", + price = 870, + sexId = {female = 963, male = 962}, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n\nYou are fearless and strong as a behemoth but have problems finding the right outfit for your adventures? The Retro Warrior outfit is a must-have for all fashion-conscious old-school Tibians out there.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Trailblazer_Male_Addon_3.png", "Outfit_Trailblazer_Female_Addon_3.png" }, + name = "Full Trailblazer Outfit", + price = 600, + sexId = {female = 1293, male = 1292}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n\nThe Trailblazer is on a mission of enlightenment and carries the flame of wisdom near and far. The everlasting shine brightens the hearts and minds of all creatures its rays touch, bringing light even to the darkest corners of the world as a beacon of insight and knowledge.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Jouster_Male_Addon_3.png", "Outfit_Jouster_Female_Addon_3.png" }, + name = "Full Jouster Outfit", + price = 870, + sexId = {female = 1332, male = 1331}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n\nThe Jouster is all geared up for a tournament, ready to partake in festive activities involving friendly competition to prove their chivalry. However, being well-armoured, they are also a force to be reckoned with on the battlefield, especially with a trusty steed at their service.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + }, + { + icons = { "Outfit_Rune_Master_Male_Addon_3.png", "Outfit_Rune_Master_Female_Addon_3.png" }, + name = "Full Rune Master Outfit", + price = 870, + sexId = {female = 1385, male = 1384}, + addon = 3, + description = "{character}\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nA Rune Master has dedicated their whole life to the study and mastery of runes. They are intrigued by the ancient symbols, shrouded in mystery, and how their magic works. Rune Masters have a deep understanding of the awesome power they are wielding and can make use of the full potential of runes.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + home = true, + }, + }, + rookgaard = true, + state = GameStore.States.STATE_NONE, + }, +--House + { + icons = { "Category_HouseTools.png" }, + name = "Houses", + rookgaard = true, + subclasses = {"Decorations", "Furniture", "Upgrades", "Hirelings", "Hirelings Dresses"}, + }, + { + icons = { "Category_HouseDecorations.png" }, + name = "Decorations", + parent = "Houses", + offers = { +-- Decorations + { + icons = { "Alchemistic_Bookstand.png" }, + name = "Alchemistic Bookstand", + price = 100, + itemtype = 32028, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Alchemistic_Cupboard.png" }, + name = "Alchemistic Cupboard", + price = 50, + itemtype = 32038, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Alchemistic_Scales.png" }, + name = "Alchemistic Scales", + price = 120, + itemtype = 32032, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "All-Seeing_Tapestry.png" }, + name = "All-Seeing Tapestry", + price = 60, + itemtype = 26106, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Anglerfish_Lamp.png" }, + name = "Anglerfish Lamp", + price = 120, + itemtype = 32259, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Arrival_at_Thais_Painting.png" }, + name = "Arrival The Thais Paint", + price = 50, + itemtype = 32046, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rolled-up_Azure_Carpet.png" }, + name = "Azure Carpet", + price = 35, + itemtype = 26366, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Baby_Dragon.png" }, + name = "Baby Dragon", + price = 250, + itemtype = 26098, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Baby_Polar_Bear.png" }, + name = "Baby Polar Bear", + price = 250, + itemtype = 37625, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Baby_Rotworm.png" }, + name = "Baby Rotworm", + price = 150, + itemtype = 32390, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Baby_Unicorn.png" }, + name = "Baby Unicorn", + price = 250, + itemtype = 36538, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rolled-up_Bamboo_Mat.png" }, + name = "Bamboo Mat", + price = 25, + itemtype = 26089, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Barrel_&_Anchor_Lamp.png" }, + name = "Barrel & Anchor Lamp", + price = 80, + itemtype = 36772, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Bath_Tub.png" }, + name = "Bath Tub", + price = 250, + itemtype = 29312, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Bellflower.png" }, + name = "Bellflower", + price = 50, + itemtype = 32396, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Bitter-Smack_Leaf.png" }, + name = "Bitter-Smack Leaf", + price = 50, + itemtype = 27893, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Blooming_Cactus.png" }, + name = "Blooming Cactus", + price = 50, + itemtype = 27892, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Blue_Round_Cushion.png" }, + name = "Blue Round Cushion", + price = 50, + itemtype = 36057, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Blue_Square_Cushion.png" }, + name = "Blue Square Cushion", + price = 50, + itemtype = 36054, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Brocade_Tapestry.png" }, + name = "Brocade Tapestry", + price = 50, + itemtype = 26381, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Carnivorous_Plant.png" }, + name = "Carnivorous Plant", + price = 50, + itemtype = 33417, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Cat_in_a_Basket.png" }, + name = "Cat in a Basket", + price = 150, + itemtype = 26107, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Chameleon.png" }, + name = "Chamaleon", + price = 250, + itemtype = 27889, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Chest_of_Abundance.png" }, + name = "Chest of Abundance", + price = 120, + itemtype = 33516, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rolled-up_Colourful_Carpet.png" }, + name = "Colourful Carpet", + price = 35, + itemtype = 27085, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rolled-up_Crested_Carpet.png" }, + name = "Crested Carpet", + price = 25, + itemtype = 29388, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rolled-up_Crimson_Carpet.png" }, + name = "Crimson Carpet", + price = 35, + itemtype = 26363, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Crystal_Lamp.png" }, + name = "Crystal Lamp", + price = 80, + itemtype = 36031, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Curly_Hortensis_Lamp.png" }, + name = "Curly Hortensis Lamp", + price = 120, + itemtype = 36530, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Dark_Parquet.png" }, + name = "Dark Parquet", + price = 30, + itemtype = 26369, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rolled-up_Decorated_Carpet.png" }, + name = "Decorated Carpet", + price = 35, + itemtype = 29390, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Demon_Pet.png" }, + name = "Demon Pet", + price = 250, + itemtype = 29409, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Demon_Skull.png" }, + name = "Demon Skull", + price = 50, + itemtype = 36047, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rolled-up_Diamond_Carpet.png" }, + name = "Diamond Carpet", + price = 25, + itemtype = 27088, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Dog_House.png" }, + name = "Dog House", + price = 150, + itemtype = 26353, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Dungeon_Scene_Painting.png" }, + name = "Dungeon Scene Painting", + price = 100, + itemtype = 32045, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rolled-up_Emerald_Carpet.png" }, + name = "Emerald Carpet", + price = 35, + itemtype = 26367, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Fennec.png" }, + name = "Fennec", + price = 150, + itemtype = 32394, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{useicon} to trigger an animation feed it with meat, ham, dragon ham, haunch of a boar, roasted meat or bug meat\n{info} can be fed once every 65 seconds\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Ferumbras_Bust.png" }, + name = "Ferumbras Dust", + price = 70, + itemtype = 32040, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}\n{useicon} house owner can use it to display a duplicate of an owned Ferumbras' Hat on this bust - also works if the character has already turned Ferumbras' hat in to earn the outfit addon", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Ferumbras_Portrait.png" }, + name = "Ferumbras Portrait", + price = 100, + itemtype = 32048, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Festive_Filled_Shoes.png" }, + name = "Festive Filled Shoes", + price = 50, + itemtype = 35021, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Festive_Fireplace.png" }, + name = "Festive Fireplace", + price = 180, + itemtype = 35027, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Festive_Pile_of_Presents.png" }, + name = "Festive Pile of Presents", + price = 50, + itemtype = 35039, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Festive_Pyramid.png" }, + name = "Festive Pyramid", + price = 120, + itemtype = 35042, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Festive_Rocking_Chair.png" }, + name = "Festive Rocking Chair", + price = 50, + itemtype = 35035, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Festive_Sack_of_Presents.png" }, + name = "Festive Sack of Presents", + price = 50, + itemtype = 35041, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Festive_Sleigh.png" }, + name = "Festive Sleigh", + price = 50, + itemtype = 35038, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Festive_Table.png" }, + name = "Festive Table", + price = 100, + itemtype = 35023, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Festive_Tree.png" }, + name = "Festive Tree", + price = 180, + itemtype = 35031, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Fish_in_a_Tank.png" }, + name = "Fish Tank", + price = 180, + itemtype = 26347, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rolled-up_Flowery_Carpet.png" }, + name = "Flowery Carpet", + price = 35, + itemtype = 27084, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Fluorescent_Fungi.png" }, + name = "Fluorescent Fungi", + price = 60, + itemtype = 33491, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Forget-Me-Not.png" }, + name = "Forget-Me-Not", + price = 50, + itemtype = 32397, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rolled-up_Fur_Carpet.png" }, + name = "Fur Carpet", + price = 30, + itemtype = 27087, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Gloomy_Poisonous_Fungi.png" }, + name = "Gloomy Poisonous Fungi", + price = 60, + itemtype = 33497, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Glowing_Sulphur_Fungi.png" }, + name = "Glowing Sulphur Fungi", + price = 60, + itemtype = 33495, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Golden_Demon_Skull.png" }, + name = "Golden Demon Skull", + price = 80, + itemtype = 36046, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + description = "Buy an incredible Golden Dragon Tapestry to decorate your home.", + icons = { "Golden_Dragon_Tapestry.png" }, + name = "Golden Dragon Tapestry", + price = 70, + itemtype = 26379, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{info} drag the unwrapped tapestry to a wall to hang it up\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Golden_Minotaur_Skull.png" }, + name = "Golden Minotaur Skull", + price = 100, + itemtype = 36044, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Green_Round_Cushion.png" }, + name = "Green Round Cushion", + price = 50, + itemtype = 36056, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Green_Square_Cushion.png" }, + name = "Green Square Cushion", + price = 50, + itemtype = 36053, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Hamster_in_a_Wheel.png" }, + name = "Hamster in a Wheel", + price = 180, + itemtype = 26100, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Baby_Hedgehog.png" }, + name = "Hedgehog", + price = 150, + itemtype = 36515, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Hrodmir_Weapons_Rack.png" }, + name = "Hrodmir Weapons Rack", + price = 90, + itemtype = 29317, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Idol_Lamp.png" }, + name = "Idol Lamp", + price = 80, + itemtype = 36049, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Incomprehensible_Riches.png" }, + name = "Incomprehensible Riches", + price = 90, + itemtype = 33515, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "King_Tibianus_Bust.png" }, + name = "King Tibianus Bust", + price = 50, + itemtype = 32049, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Light_of_Change.png" }, + name = "Light of Change", + price = 180, + itemtype = 32023, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Light_Parquet.png" }, + name = "Light Parquet", + price = 30, + itemtype = 26368, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Lit_Predator_Lamp.png" }, + name = "Lit Predator Lamp", + price = 60, + itemtype = 26092, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Lit_Protectress_Lamp.png" }, + name = "Lit Protectress Lamp", + price = 90, + itemtype = 26096, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Lit_Skull_Lamp.png" }, + name = "Lit Skull Lamp", + price = 90, + itemtype = 27103, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Little_Big_Flower_Lamp.png" }, + name = "Little Big Flower Lamp", + price = 80, + itemtype = 36532, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Lordly_Tapestry.png" }, + name = "Lordly Tapestry", + price = 50, + itemtype = 26104, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Luminescent_Fungi.png" }, + name = "Luminescent Fungi", + price = 60, + itemtype = 33493, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Marble_Floor.png" }, + name = "Marble Floor", + price = 30, + itemtype = 26376, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Menacing_Tapestry.png" }, + name = "Menacing Tapestry", + price = 70, + itemtype = 26105, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Mermaid_Figure_Head.png" }, + name = "Mermaid Figure Head", + price = 120, + itemtype = 26105, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Minotaur_Skull.png" }, + name = "Minotaur Skull", + price = 70, + itemtype = 36045, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Model_Ship_Lamp.png" }, + name = "Model Ship Lamp", + price = 80, + itemtype = 36777, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Monkey.png" }, + name = "Monkey", + price = 180, + itemtype = 36790, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rolled-up_Mystic_Carpet.png" }, + name = "Mystic Carpet", + price = 35, + itemtype = 29354, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rolled-up_Night_Sky_Carpet.png" }, + name = "Night Sky Carpet", + price = 25, + itemtype = 27090, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Painting_of_Tibiasula.png" }, + name = "Painting of Tibiasula", + price = 250, + itemtype = 33518, + itemtype = 33519, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Parrot.png" }, + name = "Parrot", + price = 180, + itemtype = 27100, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rolled-up_Patterned_Carpet.png" }, + name = "Patterned Carpet", + price = 30, + itemtype = 27089, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Pile_of_Alchemistic_Books.png" }, + name = "Pile of Alchemistic Books", + price = 120, + itemtype = 32036, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Pink_Roses.png" }, + name = "Pink Roses", + price = 50, + itemtype = 27894, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Pirate_Flag.png" }, + name = "Pirate Flag", + price = 50, + itemtype = 36780, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Pirate_Ship_Ballista.png" }, + name = "Pirate Ship Ballista", + price = 120, + itemtype = 36768, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Pirate_Skeleton_Cage.png" }, + name = "Pirate Skeleton Cage", + price = 120, + itemtype = 36782, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Pirate_Treasure_Chest.png" }, + name = "Pirate Treasure Chest", + price = 120, + itemtype = 36771, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Pirate_Treasure_Map.png" }, + name = "Pirate Treasure Map", + price = 50, + itemtype = 36781, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Queen_Eloise_Bust.png" }, + name = "Queen Eloise Bust", + price = 50, + itemtype = 32043, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Red_Geranium.png" }, + name = "Red Geranium", + price = 50, + itemtype = 32398, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Red_Roses.png" }, + name = "Red Roses", + price = 50, + itemtype = 27895, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Exalted_Sarcophagus.png" }, + name = "Sarcophagus", + price = 120, + itemtype = 36518, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rolled-up_Shaggy_Carpet.png" }, + name = "Shaggy Carpet", + price = 30, + itemtype = 29352, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Ship's_Wheel.png" }, + name = "Ship's Wheel", + price = 50, + itemtype = 36783, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + description = "Buy an incredible Star Carpet to decorate your home.", + icons = { "Rolled-up_Star_Carpet.png" }, + name = "Star Carpet", + price = 25, + itemtype = 27091, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Piled-up_Stone_Tiles.png" }, + name = "Stone Tiles", + price = 25, + itemtype = 29357, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rolled-up_Striped_Carpet .png" }, + name = "Striped Carpet", + price = 30, + itemtype = 27086, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Stuffed_Bear_Display.png" }, + name = "Stuffed Bear Display", + price = 90, + itemtype = 33499, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Stuffed_Teddy_Display.png" }, + name = "Stuffed Teddy Display", + price = 50, + itemtype = 33501, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Sulphur_Blossom_Lamp.png" }, + name = "Sulphur Blossom Lamp", + price = 80, + itemtype = 36558, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Sword_Tapestry.png" }, + name = "Sword Tapestry", + price = 60, + itemtype = 26380, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Terrarium_Snake.png" }, + name = "Terrarium Snake", + price = 180, + itemtype = 29407, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Spider_in_a_Terrarium.png" }, + name = "Terrarium Spider", + price = 180, + itemtype = 29314, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Tibia_Streets_Painting.png" }, + name = "Tibia Streets Painting", + price = 100, + itemtype = 32047, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Torch_of_Change.png" }, + name = "Torch of Change", + price = 120, + itemtype = 33175, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Vengothic_Lamp.png" }, + name = "Vengothic Lamp", + price = 180, + itemtype = 27886, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Venorean_Table_Clock.png" }, + name = "Venorean Table Clock", + price = 120, + itemtype = 29348, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rolled-up_Verdant_Carpet.png" }, + name = "Verdant Carpet", + price = 30, + itemtype = 29350, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Violet_Round_Cushion.png" }, + name = "Violet Round Cushion", + price = 50, + itemtype = 36055, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Violet_Square_Cushion.png" }, + name = "Violet Square Cushion", + price = 50, + itemtype = 36052, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rolled-up_Wheat_Carpet.png" }, + name = "Wheat Carpet", + price = 30, + itemtype = 29387, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rolled-up_White_Fur_Carpet.png" }, + name = "White Fur Carpet", + price = 30, + itemtype = 26088, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "White_Shark_Trophy.png" }, + name = "White Shark Trophy", + price = 80, + itemtype = 36786, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rolled-up_Wooden_Planks.png" }, + name = "Wooden Planks", + price = 25, + itemtype = 29359, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rolled-up_Yalaharian_Carpet.png" }, + name = "Yalaharian Carpet", + price = 35, + itemtype = 26087, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Yellow_Roses.png" }, + name = "Yellow Roses", + price = 50, + itemtype = 27896, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + }, + rookgaard = true, + state = GameStore.States.STATE_NONE, + }, +--Furniture + { + icons = { "Category_HouseFurniture.png" }, + name = "Furniture", + parent = "Houses", + rookgaard = true, + state = GameStore.States.STATE_NONE, + offers = { + { + icons = { "Alchemistic_Cabinet.png" }, + name = "Alchemistic Cabinet", + price = 100, + itemtype = 32020, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{useicon} use it to open up some storage space\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Alchemistic_Chair.png" }, + name = "Alchemistic Chair", + price = 50, + itemtype = 32018, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Alchemistic_Table.png" }, + name = "Alchemistic Table", + price = 80, + itemtype = 32021, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{useicon} use it to open up some storage space\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Comfy_Cabinet.png" }, + name = "Comfy Cabinet", + price = 100, + itemtype = 33513, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{useicon} use it to open up some storage space\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Comfy_Chair.png" }, + name = "Comfy Chair", + price = 70, + itemtype = 33505, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{useicon} use it to open up some storage space\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Comfy_Chest.png" }, + name = "Comfy Chest", + price = 60, + itemtype = 33509, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{useicon} use it to open up some storage space\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Comfy_Table.png" }, + name = "Comfy Table", + price = 60, + itemtype = 33507, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{useicon} use it to open up some storage space\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Dwarven_Stone_Cabinet.png" }, + name = "Dwarven Stone Cabinet", + price = 100, + itemtype = 36027, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{useicon} use it to open up some storage space\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Dwarven_Stone_Chair.png" }, + name = "Dwarven Stone Chair", + price = 50, + itemtype = 36020, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{useicon} use it to open up some storage space\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Dwarven_Stone_Chest.png" }, + name = "Dwarven Stone Chest", + price = 80, + itemtype = 36022, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{useicon} use it to open up some storage space\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Dwarven_Stone_Table.png" }, + name = "Dwarven Stone Table", + price = 50, + itemtype = 36026, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{useicon} use it to open up some storage space\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Ferocious_Cabinet.png" }, + name = "Ferocious Cabinet", + price = 110, + itemtype = 26077, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Ferocious_Chair.png" }, + name = "Ferocious Chair", + price = 50, + itemtype = 26065, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Ferocious_Table.png" }, + name = "Ferocious Table", + price = 50, + itemtype = 26070, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Ferocious_Trunk.png" }, + name = "Ferocious Trunk", + price = 80, + itemtype = 26079, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Hrodmir_Chair.png" }, + name = "Hrodmir Chair", + price = 50, + itemtype = 36528, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Hrodmir_Chest.png" }, + name = "Hrodmir Chest", + price = 80, + itemtype = 36522, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Hrodmir_Cupboard.png" }, + name = "Hrodmir Cupboard", + price = 100, + itemtype = 36540, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Hrodmir_Table.png" }, + name = "Hrodmir Table", + price = 50, + itemtype = 36514, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Magnificent_Cabinet.png" }, + name = "Magnificent Cabinet", + price = 100, + itemtype = 26075, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Magnificent_Chair.png" }, + name = "Magnificent Chair", + price = 60, + itemtype = 26061, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Magnificent_Table.png" }, + name = "Magnificent Table", + price = 60, + itemtype = 26074, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Magnificent_Trunk.png" }, + name = "Magnificent Trunk", + price = 70, + itemtype = 26083, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Ornate_Cabinet.png" }, + name = "Ornate Cabinet", + price = 100, + itemtype = 29398, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Ornate_Chair.png" }, + name = "Ornate Chair", + price = 50, + itemtype = 29394, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Ornate_Chest.png" }, + name = "Ornate Chest", + price = 80, + itemtype = 29401, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Ornate_Table.png" }, + name = "Ornate Table", + price = 50, + itemtype = 29397, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Round_Side_Table.png" }, + name = "Round Side Table", + price = 50, + itemtype = 36043, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rustic_Cabinet.png" }, + name = "Rustic Cabinet", + price = 100, + itemtype = 26356, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rustic_Chair.png" }, + name = "Rustic Chair", + price = 50, + itemtype = 26351, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rustic_Table.png" }, + name = "Rustic Table", + price = 50, + itemtype = 26354, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Rustic_Trunk.png" }, + name = "Rustic Trunk", + price = 80, + itemtype = 26358, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Skeletal_Cabinet.png" }, + name = "Skeletal Cabinet", + price = 100, + itemtype = 33415, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Skeletal_Chair.png" }, + name = "Skeletal Chair", + price = 50, + itemtype = 32260, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Skeletal_Chest.png" }, + name = "Skeletal Chest", + price = 80, + itemtype = 32266, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Skeletal_Table.png" }, + name = "Skeletal Table", + price = 50, + itemtype = 32264, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Square_Side_Table.png" }, + name = "Square Side Table", + price = 50, + itemtype = 29397, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Vengothic_Cabinet.png" }, + name = "Vengothic Cabinet", + price = 100, + itemtype = 27903, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Vengothic_Chair.png" }, + name = "Vengothic Chair", + price = 50, + itemtype = 27899, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Vengothic_Chest.png" }, + name = "Vengothic Chest", + price = 80, + itemtype = 27905, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Vengothic_Table.png" }, + name = "Vengothic Table", + price = 50, + itemtype = 27901, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Verdant_Cabinet.png" }, + name = "Verdant Cabinet", + price = 100, + itemtype = 29341, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Verdant_Chair.png" }, + name = "Verdant Chair", + price = 50, + itemtype = 29339, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Verdant_Table.png" }, + name = "Verdant Table", + price = 80, + itemtype = 29347, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Verdant_Trunk.png" }, + name = "Verdant Trunk", + price = 50, + itemtype = 29343, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Wooden_Bookcase.png" }, + name = "Wooden Bookcase", + price = 50, + itemtype = 36029, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + }, + }, + -- Upgrades + { + icons = { "Category_HouseUpgrades.png" }, + name = "Upgrades", + parent = "Houses", + rookgaard = true, + state = GameStore.States.STATE_NONE, + offers = { + { + icons = { "Reward_Shrine.png" }, + name = "Daily Reward Shrine", + price = 150, + itemtype = 29022, + count = 1, + description = "Pick up your daily reward comfortably in your own four walls!\n\n{house}\n{box}\n{storeinbox}\n{usablebyall}\n{useicon} use it to open the reward wall\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Demon_Exercise_Dummy.png" }, + name = "Demon Exercise Dummy", + price = 900, + itemtype = 32145, + count = 1, + description = "Train your skills more effectively at home than in public on this expert exercise dummy!\n\n{house}\n{box}\n{storeinbox}\n{usablebyall}\n{info} can only be used by one character at a time\n{useicon} use one of the exercise weapons on this dummy\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Ferumbras_Exercise_Dummy.png" }, + name = "Ferumbras Exercise Dummy", + price = 900, + itemtype = 32143, + count = 1, + description = "Train your skills more effectively at home than in public on this expert exercise dummy!\n\n{house}\n{box}\n{storeinbox}\n{usablebyall}\n{info} can only be used by one character at a time\n{useicon} use one of the exercise weapons on this dummy\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Gilded_Imbuing_Shrine.png" }, + name = "Gilded Imbuing Shrine", + price = 200, + itemtype = 27851, + count = 1, + description = "Enhance your equipment comfortably in your own four walls!\n\n{house}\n{box}\n{storeinbox}\n{usablebyall}\n{useicon} use it with an imbuable item to open the imbuing dialog\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Imbuing_Shrine.png" }, + name = "Imbuing Shrine", + price = 150, + itemtype = 27843, + count = 1, + description = "Enhance your equipment comfortably in your own four walls!\n\n{house}\n{box}\n{storeinbox}\n{usablebyall}\n{useicon} use it with an imbuable item to open the imbuing dialog\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Mailbox.png" }, + name = "Mailbox", + price = 150, + itemtype = 26055, + count = 1, + description = "Send your letters and parcels right from your own home!\n\n{house}\n{box}\n{storeinbox}\n{usablebyall}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Monk_Exercise_Dummy.png" }, + name = "Monk Exercise Dummy", + price = 900, + itemtype = 32147, + count = 1, + description = "Train your skills more effectively at home than in public on this expert exercise dummy!\n\n{house}\n{box}\n{storeinbox}\n{usablebyall}\n{info} can only be used by one character at a time\n- use one of the exercise weapons on this dummy\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Ornate_Mailbox.png" }, + name = "Ornate Mailbox", + price = 200, + itemtype = 26057, + count = 1, + description = "Send your letters and parcels right from your own home!\n\n{house}\n{box}\n{storeinbox}\n{usablebyall}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Shiny_Reward_Shrine.png" }, + name = "Shiny Daily Reward Shrine", + price = 200, + itemtype = 29024, + count = 1, + description = "Pick up your daily reward comfortably in your own four walls!\n\n{house}\n{box}\n{storeinbox}\n{usablebyall}\n{useicon} use it to open the reward wall\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + }, + }, + { + icons = { "Category_HouseTools_NPCApprenticeships.png" }, + name = "Hirelings", + parent = "Houses", + rookgaard = true, + state = GameStore.States.STATE_NONE, + offers = { + { + icons = { "Hireling_Male.png" }, + name = "Hireling Apprentice", + price = 150, + id = 28799, + count = 1, + number = 1, + sexId = {female = 1107, male = 1108}, + description = "Get your very own hireling to serve you and your guests in your own four walls!\n\n{house} can only be unwrapped in a house owned by the purchasing character\n{boxicon} comes in a magic lamp which can only be used by purchasing character\n{storeinbox}\n{usablebyallicon} can be used by all characters that have access to the house\n{useicon} use the magic lamp to summon your hireling\n{backtoinbox}\n{info} maximum amount that can be owned by character: 10", + type = GameStore.OfferTypes.OFFER_TYPE_HIRELING, + }, + { + icons = { "Hireling_Male.png" }, + name = "Hireling Name Change", + price = 250, + id = 28797, + count = 1, + number = 1, + description = "{info} Change the name of one of your hirelings", + type = GameStore.OfferTypes.OFFER_TYPE_HIRELING_NAMECHANGE, + }, + { + icons = { "Hireling_Male.png" }, + name = "Hireling Sex Change", + price = 120, + id = 28796, + count = 1, + number = 1, + description = "{info} Change the sex of one of your hirelings", + type = GameStore.OfferTypes.OFFER_TYPE_HIRELING_SEXCHANGE, + }, + { + icons = { "Hireling_Cook.png" }, + name = "Hireling Cook", + price = 900, + id = HIRELING_STORAGE.SKILL + HIRELING_SKILLS.COOKING, + count = 1, + number = 1, + description = "{info} Give your hirelings the ability to cook exclusive status enhancement and instant recovery meals!", + type = GameStore.OfferTypes.OFFER_TYPE_HIRELING_SKILL, + }, + { + icons = { "Hireling_Trader.png" }, + name = "Hireling Trader", + price = 250, + id = HIRELING_STORAGE.SKILL + HIRELING_SKILLS.TRADER, + count = 1, + number = 1, + description = "{info} Give your hirelings the ability of trading several types of items, including equipment, tools, potions, runes, wands and rods.", + type = GameStore.OfferTypes.OFFER_TYPE_HIRELING_SKILL, + }, + { + icons = { "Hireling_Steward.png" }, + name = "Hireling Steward", + price = 250, + id = HIRELING_STORAGE.SKILL + HIRELING_SKILLS.STEWARD, + count = 1, + number = 1, + description = "{info} Give your hirelings the ability to access and manage your stash at the confort of your from home", + type = GameStore.OfferTypes.OFFER_TYPE_HIRELING_SKILL, + }, + { + icons = { "Hireling_Banker.png" }, + name = "Hireling Banker", + price = 250, + id = HIRELING_STORAGE.SKILL + HIRELING_SKILLS.BANKER, + count = 1, + number = 1, + description = "{info} Give your hirelings the ability of managing your banking business.", + type = GameStore.OfferTypes.OFFER_TYPE_HIRELING_SKILL, + }, + }, + }, + { + icons = { "Category_HouseTools_NPCDresses.png" }, + name = "Hireling Dresses", + parent = "Houses", + rookgaard = true, + state = GameStore.States.STATE_NONE, + offers = { + { + icons = { "Hireling_Banker.png" }, + name = "Banker Dress", + price = 500, + id = HIRELING_STORAGE.OUTFIT + HIRELING_OUTFITS.BANKER, + count = 1, + number = 1, + description = "{info} can only be used for hirelings of the purchasing character\n{activated}\n{info} the purchased dress can be used by all hirelings, however, how many hirelings can wear this outfit at the same time depends on the number of dresses you own\n{info} colours can be changed using the Outfit dialog\n{info} number that can be purchased depends on the amount of hirelings you own", + type = GameStore.OfferTypes.OFFER_TYPE_HIRELING_OUTFIT, + }, + { + icons = { "Hireling_Trader.png" }, + name = "Trader Dress", + price = 500, + id = HIRELING_STORAGE.OUTFIT + HIRELING_OUTFITS.TRADER, + count = 1, + number = 1, + description = "{info} can only be used for hirelings of the purchasing character\n{activated}\n{info} the purchased dress can be used by all hirelings, however, how many hirelings can wear this outfit at the same time depends on the number of dresses you own\n{info} colours can be changed using the Outfit dialog\n{info} number that can be purchased depends on the amount of hirelings you own", + type = GameStore.OfferTypes.OFFER_TYPE_HIRELING_OUTFIT, + }, + { + icons = { "Hireling_Cook.png" }, + name = "Cook Dress", + price = 500, + id = HIRELING_STORAGE.OUTFIT + HIRELING_OUTFITS.COOKING, + count = 1, + number = 1, + description = "{info} can only be used for hirelings of the purchasing character\n{activated}\n{info} the purchased dress can be used by all hirelings, however, how many hirelings can wear this outfit at the same time depends on the number of dresses you own\n{info} colours can be changed using the Outfit dialog\n{info} number that can be purchased depends on the amount of hirelings you own", + type = GameStore.OfferTypes.OFFER_TYPE_HIRELING_OUTFIT, + }, + { + icons = { "Hireling_Steward.png" }, + name = "Steward Dress", + price = 500, + id = HIRELING_STORAGE.OUTFIT + HIRELING_OUTFITS.STEWARD, + count = 1, + number = 1, + description = "{info} can only be used for hirelings of the purchasing character\n{activated}\n{info} the purchased dress can be used by all hirelings, however, how many hirelings can wear this outfit at the same time depends on the number of dresses you own\n{info} colours can be changed using the Outfit dialog\n{info} number that can be purchased depends on the amount of hirelings you own", + type = GameStore.OfferTypes.OFFER_TYPE_HIRELING_OUTFIT, + }, + { + icons = { "Hireling_Servant.png" }, + name = "Servant Dress", + price = 300, + id = HIRELING_STORAGE.OUTFIT + HIRELING_OUTFITS.SERVANT, + count = 1, + number = 1, + description = "{info} can only be used for hirelings of the purchasing character\n{activated}\n{info} the purchased dress can be used by all hirelings, however, how many hirelings can wear this outfit at the same time depends on the number of dresses you own\n{info} colours can be changed using the Outfit dialog\n{info} number that can be purchased depends on the amount of hirelings you own", + type = GameStore.OfferTypes.OFFER_TYPE_HIRELING_OUTFIT, + }, + { + icons = { "Hireling_Hydra.png" }, + name = "Hydra Dress", + price = 900, + id = HIRELING_STORAGE.OUTFIT + HIRELING_OUTFITS.HYDRA, + count = 1, + number = 1, + description = "{info} can only be used for hirelings of the purchasing character\n{activated}\n{info} the purchased dress can be used by all hirelings, however, how many hirelings can wear this outfit at the same time depends on the number of dresses you own\n{info} number that can be purchased depends on the amount of hirelings you own", + type = GameStore.OfferTypes.OFFER_TYPE_HIRELING_OUTFIT, + }, + { + icons = { "Hireling_Ferumbras.png" }, + name = "Ferumbras Dress", + price = 900, + id = HIRELING_STORAGE.OUTFIT + HIRELING_OUTFITS.FERUMBRAS, + count = 1, + number = 1, + description = "{info} can only be used for hirelings of the purchasing character\n{activated}\n{info} the purchased dress can be used by all hirelings, however, how many hirelings can wear this outfit at the same time depends on the number of dresses you own\n{info} number that can be purchased depends on the amount of hirelings you own", + type = GameStore.OfferTypes.OFFER_TYPE_HIRELING_OUTFIT, + }, + { + icons = { "Hireling_Bonelord.png" }, + name = "Bonelord Dress", + price = 900, + id = HIRELING_STORAGE.OUTFIT + HIRELING_OUTFITS.BONELORD, + count = 1, + number = 1, + description = "{info} can only be used for hirelings of the purchasing character\n{activated}\n{info} the purchased dress can be used by all hirelings, however, how many hirelings can wear this outfit at the same time depends on the number of dresses you own\n{info} number that can be purchased depends on the amount of hirelings you own", + type = GameStore.OfferTypes.OFFER_TYPE_HIRELING_OUTFIT, + }, + { + icons = { "Hireling_Dragon.png" }, + name = "Dragon Dress", + price = 900, + id = HIRELING_STORAGE.OUTFIT + HIRELING_OUTFITS.DRAGON, + count = 1, + number = 1, + description = "{info} can only be used for hirelings of the purchasing character\n{activated}\n{info} the purchased dress can be used by all hirelings, however, how many hirelings can wear this outfit at the same time depends on the number of dresses you own\n{info} number that can be purchased depends on the amount of hirelings you own", + type = GameStore.OfferTypes.OFFER_TYPE_HIRELING_OUTFIT, + }, + }, + }, +-- Boost + { + icons = { "Category_Boosts.png" }, + name = "Boosts", + offers = { + { + icons = { "XP_Boost.png" }, + name = "XP Boost", + price = 30, + id = 65010, + description = "Purchase a boost that increases the experience points your character gains from hunting by 50%!\n\n{character}\n{info} lasts for 1 hour hunting time\n{info} paused if stamina falls under 14 hours\n{info} can be purchased up to 5 times between 2 server saves\n{info} price increases with every purchase\n{info} cannot be purchased if an XP boost is already active", + type = GameStore.OfferTypes.OFFER_TYPE_EXPBOOST, + }, + }, + rookgaard = true, + state = GameStore.States.STATE_NONE, + }, +-- Extras + { + icons = { "Category_Extras.png" }, + name = "Extras", + rookgaard = true, + subclasses = {"Extra Services", "Useful Things"}, + }, + -- Extras Services + { + icons = { "Category_ExtraServices.png" }, + name = "Extra Services", + parent = "Extras", + rookgaard = true, + state = GameStore.States.STATE_NONE, + offers = { + { + icons = { "Name_Change.png" }, + name = "Character Name Change", + price = 250, + id = 65002, + description = "Tired of your current character name? Purchase a new one!\n\n{character}\n{info} relog required after purchase to finalise the name change", + type = GameStore.OfferTypes.OFFER_TYPE_NAMECHANGE, + }, + { + icons = { "Sex_Change.png" }, + name = "Character Sex Change", + price = 120, + id = 65003, + description = "Turns your female character into a male one - or vice versa.\n\n{character}\n{activated}\n{info} you will keep all outfits you have purchased or earned in quest", + type = GameStore.OfferTypes.OFFER_TYPE_SEXCHANGE, + }, + }, + }, +-- Usefull Things + { + icons = { "Category_UsefulThings.png" }, + name = "Useful Things", + parent = "Extras", + rookgaard = true, + state = GameStore.States.STATE_NONE, + offers = { + { + icons = { "Gold_Converter.png" }, + name = "Gold Converter", + price = 5, + itemtype = 26378, + charges = 500, + description = "Changes either a stack of 100 gold pieces into 1 platinum coin, or a stack of 100 platinum coins into 1 crystal coin!\n\n{character}\n{storeinbox}\n{useicon} use it on a stack of 100 to change it to the superior currency\n{info} usable 500 times a piece", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + }, + { + icons = { "Gold_Pouch.png" }, + name = "Gold Pouch", + price = 900, + itemtype = 26377, + count = 1, + description = "Carries as many gold, platinum or crystal coins as your capacity allows, however, no other items.\n\n{character}\n{storeinbox}\n{once}\n{useicon} use it to open it\n{info} always placed on the first position of your Store inbox", + type = GameStore.OfferTypes.OFFER_TYPE_POUNCH, + }, + { + icons = { "Instant_Reward_Access.png" }, + name = "Instant Reward Access", + price = 100, + id = 2, + count = 1, + description = "No matter where you are in Tibia, claim your daily reward on the spot!\n\n{character}\n{info} added to your reward wall\n{info} maximum amount that can be owned by character: 90", + type = GameStore.OfferTypes.OFFER_TYPE_INSTANT_REWARD_ACCESS, + }, + { + icons = { "Charm_Expansion_Offer.png" }, + name = "Charm Expansion", + price = 450, + id = 65005, + description = "Assign as many of your unlocked Charms as you like and get a 25% discount whenever you are removing a Charm from a creature!\n\n{character}\n{once}", + type = GameStore.OfferTypes.OFFER_TYPE_CHARMS, + }, + { + icons = { "Magic_Gold_Converter.png" }, + name = "Magic Gold Converter", + price = 15, + itemtype = 32109, + charges = 500, + description = "Changes automatically either a stack of 100 gold pieces into 1 platinum coin, or a stack of 100 platinum coins into 1 crystal coin!\n\n{character}\n{storeinbox}\n{useicon} use it to activate or deactivate the automatic conversion\n{info} converts all stacks of 100 gold or platinum in the inventory whenever it is activated\n{info} deactivated upon purchase\n{info} usable for 500 conversions a piece", + type = GameStore.OfferTypes.OFFER_TYPE_CHARGES, + }, + { + icons = { "Permanent_Prey_Slot.png" }, + name = "Permanent Prey Slot", + price = 900, + id = 65008, + description = "Get an additional prey slot to activate additional prey!\n\n{character}\n{info} maximum amount that can be owned by character: 3\n{info} added directly to Prey dialog", + type = GameStore.OfferTypes.OFFER_TYPE_PREYSLOT, + }, + { + icons = { "Prey_Bonus_Reroll.png" }, + name = "Prey Wildcard", + price = 50, + id = 1, + count = 5, + description = "Use Prey Wildcards to reroll the bonus of an active prey, to lock your active prey or to select a prey of your choice.\n\n{character}\n{info} added directly to Prey dialog\n{info} maximum amount that can be owned by character: 50", + type = GameStore.OfferTypes.OFFER_TYPE_PREYBONUS, + }, + { + icons = { "Prey_Bonus_Reroll.png" }, + name = "Prey Wildcard", + price = 200, + count = 20, + description = "Use Prey Wildcards to reroll the bonus of an active prey, to lock your active prey or to select a prey of your choice.\n\n{character}\n{info} added directly to Prey dialog\n{info} maximum amount that can be owned by character: 50", + type = GameStore.OfferTypes.OFFER_TYPE_PREYBONUS, + }, + { + icons = { "Temple_Teleport.png" }, + name = "Temple Teleport", + price = 15, + description = "Teleports you instantly to your home temple.\n\n{character}\n{useicon} use it to teleport you to your home temple\n{battlesign}\n{info} does not work in no-logout zones or close to a character's home temple", + type = GameStore.OfferTypes.OFFER_TYPE_TEMPLE, + }, + }, + }, + --Tournament + { + icons = { "Category_Tournament.png" }, + name = "Tournament", + rookgaard = true, + subclasses = {"Tickets", "Exclusive Offers"}, + }, + -- Tickets + { + icons = { "Category_Tickets.png" }, + parent = "Tournament", + name = "Tickets", + rookgaard = true, + offers = { + { + icons = { "Tournament_Restricted.png" }, + name = "Restricted Tournament Ticket", + price = 500, + }, + }, + -- Exclusive Offers + }, { + icons = { "Category_ExclusiveOffers.png" }, + name = "Exclusive Offers", + parent = "Tournament", + rookgaard = true, + state = GameStore.States.STATE_NONE, + offers = { + { + icons = { "Cerberus_Champion.png" }, + name = "Cerberus Champion", + price = 1250, + id = 146, + description = "{info} usable by all characters of the account\n{speedboost}\n\nA fierce and grim guardian of the underworld has risen to fight side by side with the bravest warriors in order to send evil creatures into the realm of the dead. The three headed Cerberus Champion is constantly baying for blood and using its sharp fangs it easily rips apart even the strongest armour and shield.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + coinType = GameStore.CointType.Tournament, + }, + { + icons = { "Jousting_Eagle.png" }, + name = "Jousting Eagle", + price = 1250, + id = 145, + description = "{info} usable by all characters of the account\n{speedboost}\n\nHigh above the clouds far away from dry land, the training of giant eagles takes place. Only the cream of the crop is able to survive in such harsh environment long enough to call themselves Jousting Eagles while the weaklings find themselves at the bottom of the sea. The tough ones become noble and graceful mounts that are well known for their agility and endurance.", + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + coinType = GameStore.CointType.Tournament, + }, + { + icons = { "Outfit_Lion_of_War_Male_Addon_3.png", "Outfit_Lion_of_War_Female_Addon_3.png" }, + name = "Full Lion of War Outfit", + price = 1750, + sexId = {female = 1207, male = 1206}, + addon = 3, + description = "{info} usable by all characters of the account\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nThe Lion of War has fought on countless battlefields and never lost once. Enemies tremble with fear when he batters his sword against his almighty shield. Realising that a Lion of War knows no mercy, his opponents often surrender before the battle even begins.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + coinType = GameStore.CointType.Tournament, + }, + { + icons = { "Outfit_Veteran_Paladin_Male_Addon_3.png", "Outfit_Veteran_Paladin_Female_Addon_3.png" }, + name = "Full Veteran Paladin Outfit", + price = 1750, + sexId = {female = 1205, male = 1204}, + addon = 3, + description = "{info} usable by all characters of the account\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nA Veteran Paladin has mastered the art of distance fighting. No matter how far away his prey may be, a marksman like the Veteran Paladin will always hit with extraordinary precision. No one can escape his keen hawk-eyed vision and even small stones become deadly weapons in his hands.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + coinType = GameStore.CointType.Tournament, + }, + { + icons = { "Outfit_Void_Master_Male_Addon_3.png", "Outfit_Void_Master_Female_Addon_3.png" }, + name = "Full Void Master Outfit", + price = 1750, + sexId = {female = 1203, male = 1202}, + addon = 3, + description = "{info} usable by all characters of the account\n{info} colours can be changed using the Outfit dialog\n{info} includes basic outfit and 2 addons which can be selected individually\n\nAccording to ancient rumours, the pulsating orb that the Void Master balances skilfully on the tip of his staff consists of powerful cosmic spheres. If you gaze too long into the infinite emptiness inside the orb, its powers will absorb your mind.", + type = GameStore.OfferTypes.OFFER_TYPE_OUTFIT, + coinType = GameStore.CointType.Tournament, + }, + { + icons = { "Cerberus_Champion_Puppy.png" }, + name = "Cerberus Champion Puppy", + price = 800, + itemtype = 36299, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CointType.Tournament, + }, + { + icons = { "Jousting_Eagle_Baby.png" }, + name = "Jousting Eagle Baby", + price = 800, + itemtype = 36297, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{use}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CointType.Tournament, + }, + { + icons = { "Sublime_Tournament_Accolade.png" }, + name = "Sublime Tournament Accolade", + price = 500, + itemtype = 36307, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CointType.Tournament, + }, + { + icons = { "Sublime_Tournament_Carpet.png" }, + name = "Sublime Tournament Carpet", + price = 70, + itemtype = 36302, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{useicon} use an unwrapped carpet to roll it out or up\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CointType.Tournament, + }, + { + icons = { "Tournament_Accolade.png" }, + name = "Tournament Accolade", + price = 500, + itemtype = 36305, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CointType.Tournament, + }, + { + icons = { "Tournament_Carpet.png" }, + name = "Tournament Carpet", + price = 70, + itemtype = 36301, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{useicon} use an unwrapped carpet to roll it out or up\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + coinType = GameStore.CointType.Tournament, + }, + { + icons = { "Baby_Vulcongra_Accolade.png" }, + name = "Baby Vulcongra", + price = 800, + itemtype = 37743, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Guzzlemaw_Grub.png" }, + name = "Guzzlemaw Grub", + price = 800, + itemtype = 37742, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Cozy_Couch.png" }, + name = "Cozy Couch", + price = 100, + itemtype = 37783, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Cozy_Couch_Left_End.png" }, + name = "Cozy Couch Left End", + price = 100, + itemtype = 37787, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Cozy_Couch_Right_End.png" }, + name = "Cozy Couch Right End", + price = 100, + itemtype = 37791, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Cozy_Couch_Corner.png" }, + name = "Cozy Couch Corner", + price = 100, + itemtype = 37799, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Baby_Brain_Squid.png" }, + name = "Baby Brain Squid", + price = 800, + itemtype = 37744, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Carved_Table.png" }, + name = "Carved Table", + price = 100, + itemtype = 37807, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Carved_Table_Centre.png" }, + name = "Carved Table Centre", + price = 100, + itemtype = 37809, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + { + icons = { "Carved_Table_Corner.png" }, + name = "Carved Table Corner", + price = 100, + itemtype = 37804, + count = 1, + description = "{house}\n{box}\n{storeinbox}\n{backtoinbox}", + type = GameStore.OfferTypes.OFFER_TYPE_HOUSE, + }, + }, + }, +} + + +-- Each outfit must be uniquely identified to distinguish between addons. +-- Here we dynamically assign ids for outfits. These ids must be unique. +local runningId = 45000 +for k, category in ipairs(GameStore.Categories) do + if category.offers then + for m, offer in ipairs(category.offers) do + if not offer.id then + if type(offer.count) == "table" then + for i = 1, #offer.price do + offer.id[i] = runningId + runningId = runningId + 1 + end + else + offer.id = runningId + runningId = runningId + 1 + end + end + if not offer.type then + offer.type = GameStore.OfferTypes.OFFER_TYPE_NONE + end + if not offer.coinType then + offer.coinType = GameStore.CointType.Coin + end + end + end +end diff --git a/data/modules/scripts/gamestore/init.lua b/data/modules/scripts/gamestore/init.lua new file mode 100644 index 00000000000..1bd16f4cbdf --- /dev/null +++ b/data/modules/scripts/gamestore/init.lua @@ -0,0 +1,1846 @@ +GameStore = { + ModuleName = "GameStore", + Developers = { "Cjaker", "metabob", "Rick" }, + Version = "1.1", + LastUpdated = "25-07-2020 11:52AM" +} + +--== Enums ==-- +GameStore.OfferTypes = { + OFFER_TYPE_NONE = 0, + OFFER_TYPE_ITEM = 1, + OFFER_TYPE_STACKABLE = 2, + OFFER_TYPE_CHARGES = 3, + OFFER_TYPE_OUTFIT = 4, + OFFER_TYPE_OUTFIT_ADDON = 5, + OFFER_TYPE_MOUNT = 6, + OFFER_TYPE_NAMECHANGE = 7, + OFFER_TYPE_SEXCHANGE = 8, + OFFER_TYPE_HOUSE = 9, + OFFER_TYPE_EXPBOOST = 10, + OFFER_TYPE_PREYSLOT = 11, + OFFER_TYPE_PREYBONUS = 12, + OFFER_TYPE_TEMPLE = 13, + OFFER_TYPE_BLESSINGS = 14, + OFFER_TYPE_PREMIUM = 15, + OFFER_TYPE_POUNCH = 16, + OFFER_TYPE_ALLBLESSINGS = 17, + OFFER_TYPE_INSTANT_REWARD_ACCESS = 18, + OFFER_TYPE_CHARMS = 19, + OFFER_TYPE_HIRELING = 20, + OFFER_TYPE_HIRELING_NAMECHANGE = 21, + OFFER_TYPE_HIRELING_SEXCHANGE = 22, + OFFER_TYPE_HIRELING_SKILL = 23, + OFFER_TYPE_HIRELING_OUTFIT = 24 +} + +GameStore.ActionType = { + OPEN_HOME = 0, + OPEN_PREMIUM_BOOST = 1, + OPEN_CATEGORY = 2, + OPEN_USEFUL_THINGS = 3, + OPEN_OFFER = 4, +} + +GameStore.CointType = { + Coin = 0, + Transferable = 1, + Tournament = 2, +} + +GameStore.Storages = { + expBoostCount = 51052 +} + +GameStore.ConverType = { + SHOW_NONE = 0, + SHOW_MOUNT = 1, + SHOW_OUTFIT = 2, + SHOW_ITEM = 3, + SHOW_HIRELING = 4 +} + +GameStore.ConfigureOffers = { + SHOW_NORMAL = 0, + SHOW_CONFIGURE = 1 +} + +function convertType(type) + local types = { + [GameStore.OfferTypes.OFFER_TYPE_OUTFIT] = GameStore.ConverType.SHOW_OUTFIT, + [GameStore.OfferTypes.OFFER_TYPE_OUTFIT_ADDON] = GameStore.ConverType.SHOW_OUTFIT, + [GameStore.OfferTypes.OFFER_TYPE_MOUNT] = GameStore.ConverType.SHOW_MOUNT, + [GameStore.OfferTypes.OFFER_TYPE_ITEM] = GameStore.ConverType.SHOW_ITEM, + [GameStore.OfferTypes.OFFER_TYPE_STACKABLE] = GameStore.ConverType.SHOW_ITEM, + [GameStore.OfferTypes.OFFER_TYPE_HOUSE] = GameStore.ConverType.SHOW_ITEM, + [GameStore.OfferTypes.OFFER_TYPE_CHARGES] = GameStore.ConverType.SHOW_ITEM, + [GameStore.OfferTypes.OFFER_TYPE_HIRELING] = GameStore.ConverType.SHOW_HIRELING, + } + + if not types[type] then + return GameStore.ConverType.SHOW_NONE + end + + return types[type] +end + +function useOfferConfigure(type) + local types = { + [GameStore.OfferTypes.OFFER_TYPE_NAMECHANGE] = GameStore.ConfigureOffers.SHOW_CONFIGURE, + [GameStore.OfferTypes.OFFER_TYPE_HIRELING] = GameStore.ConfigureOffers.SHOW_CONFIGURE, + [GameStore.OfferTypes.OFFER_TYPE_HIRELING_NAMECHANGE] = GameStore.ConfigureOffers.SHOW_CONFIGURE + } + + if not types[type] then + return GameStore.ConfigureOffers.SHOW_NORMAL + end + + return types[type] +end + +GameStore.ClientOfferTypes = { + CLIENT_STORE_OFFER_OTHER = 0, + CLIENT_STORE_OFFER_NAMECHANGE = 1, + CLIENT_STORE_OFFER_HIRELING = 10, +} + +GameStore.HistoryTypes = { + HISTORY_TYPE_NONE = 0, + HISTORY_TYPE_GIFT = 1, + HISTORY_TYPE_REFUND = 2 +} + +GameStore.States = { + STATE_NONE = 0, + STATE_NEW = 1, + STATE_SALE = 2, + STATE_TIMED = 3 +} + +GameStore.StoreErrors = { + STORE_ERROR_PURCHASE = 0, + STORE_ERROR_NETWORK = 1, + STORE_ERROR_HISTORY = 2, + STORE_ERROR_TRANSFER = 3, + STORE_ERROR_INFORMATION = 4 +} + +GameStore.ServiceTypes = { + SERVICE_STANDERD = 0, + SERVICE_OUTFITS = 3, + SERVICE_MOUNTS = 4, + SERVICE_BLESSINGS = 5 +} + +GameStore.SendingPackets = { + S_CoinBalance = 0xDF, -- 223 + S_StoreError = 0xE0, -- 224 + S_RequestPurchaseData = 0xE1, -- 225 + S_CoinBalanceUpdating = 0xF2, -- 242 + S_OpenStore = 0xFB, -- 251 + S_StoreOffers = 0xFC, -- 252 + S_OpenTransactionHistory = 0xFD, -- 253 + S_CompletePurchase = 0xFE -- 254 +} + +GameStore.RecivedPackets = { + C_StoreEvent = 0xE9, -- 233 + C_TransferCoins = 0xEF, -- 239 + C_ParseHirelingName = 0xEC, -- 236 + C_OpenStore = 0xFA, -- 250 + C_RequestStoreOffers = 0xFB, -- 251 + C_BuyStoreOffer = 0xFC, -- 252 + C_OpenTransactionHistory = 0xFD, -- 253 + C_RequestTransactionHistory = 0xFE, -- 254 +} + +GameStore.ExpBoostValues = { + [1] = 30, + [2] = 45, + [3] = 90, + [4] = 180, + [5] = 360 +} + +GameStore.DefaultValues = { + DEFAULT_VALUE_ENTRIES_PER_PAGE = 26 +} + +GameStore.DefaultDescriptions = { + OUTFIT = { "This outfit looks nice. Only high-class people are able to wear it!", + "An outfit that was created to suit you. We are sure you'll like it.", + "Legend says only smart people should wear it, otherwise you will burn!" }, + MOUNT = { "This is a fantastic mount that helps to become faster, try it!", + "The first rider of this mount became the leader of his country! legends say that." }, + NAMECHANGE = { "Are you hunted? Tired of that? Get a new name, a new life!", + "A new name to suit your needs!" }, + SEXCHANGE = { "Bored of your character's sex? Get a new sex for him now!!" }, + EXPBOOST = { "Are you tired of leveling slow? try it!" }, + PREYSLOT = { "It's hunting season! Activate a prey to gain a bonus when hunting a certain monster. Every character can purchase one Permanent Prey Slot, which enables the activation of an additional prey. \nIf you activate a prey, you can select one monster out of nine. The bonus for your prey will be selected randomly from one of the following: damage boost, damage reduction, bonus XP, improved loot. The bonus value may range from 5% to 50%. Your prey will be active for 2 hours hunting time: the duration of an active prey will only be reduced while you are hunting." }, + PREYBONUS = { "You activated a prey but do not like the randomly selected bonus? Roll for a new one! Here you can purchase five Prey Bonus Rerolls! \nA Bonus Reroll allows you to get a bonus with a higher value (max. 50%). The bonus for your prey will be selected randomly from one of the following: damage boost, damage reduction, bonus XP, improved loot. The 2 hours hunting time will start anew once you have rolled for a new bonus. Your prey monster will stay the same." }, + TEMPLE = { "Need a quick way home? Buy this transportation service to get instantly teleported to your home temple. \n\nNote, you cannot use this service while having a battle sign or a protection zone block. Further, the service will not work in no-logout zones or close to your home temple." } +} + +--==Parsing==-- +GameStore.isItsPacket = function(byte) + for k, v in pairs(GameStore.RecivedPackets) do + if v == byte then + return true + end + end + return false +end + +local function queueSendStoreAlertToUser(message, delay, playerId, storeErrorCode) + storeErrorCode = storeErrorCode and storeErrorCode or GameStore.StoreErrors.STORE_ERROR_NETWORK + addPlayerEvent(sendStoreError, delay, playerId, storeErrorCode, message) +end + +function onRecvbyte(player, msg, byte) + if not configManager.getBoolean(STOREMODULES) then return true end + if player:getVocation():getId() == 0 and not GameStore.haveCategoryRook() then + return player:sendCancelMessage("Store don't have offers for rookgaard citizen.") + end + + local exaust = player:getStorageValue(Storage.StoreExaust) + local currentTime = os.time() + + if byte == GameStore.RecivedPackets.C_StoreEvent then + elseif byte == GameStore.RecivedPackets.C_TransferCoins then + parseTransferCoins(player:getId(), msg) + elseif byte == GameStore.RecivedPackets.C_OpenStore then + if exaust > currentTime then + player:sendCancelMessage("You are exhausted") + return false + end + local num = currentTime + 1 + player:setStorageValue(Storage.StoreExaust, num) + + parseOpenStore(player:getId(), msg) + elseif byte == GameStore.RecivedPackets.C_RequestStoreOffers then + parseRequestStoreOffers(player:getId(), msg) + elseif byte == GameStore.RecivedPackets.C_BuyStoreOffer then + parseBuyStoreOffer(player:getId(), msg) + elseif byte == GameStore.RecivedPackets.C_OpenTransactionHistory then + parseOpenTransactionHistory(player:getId(), msg) + elseif byte == GameStore.RecivedPackets.C_RequestTransactionHistory then + parseRequestTransactionHistory(player:getId(), msg) + end + return true +end + +function parseTransferCoins(playerId, msg) + local player = Player(playerId) + if not player then + return false + end + + local reciver = msg:getString() + local amount = msg:getU32() + + if (player:getCoinsBalance() < amount) then + return addPlayerEvent(sendStoreError, 350, playerId, GameStore.StoreErrors.STORE_ERROR_TRANSFER, "You don't have this amount of coins.") + end + + if reciver:lower() == player:getName():lower() then + return addPlayerEvent(sendStoreError, 350, playerId, GameStore.StoreErrors.STORE_ERROR_TRANSFER, "You can't transfer coins to yourself.") + end + + local resultId = db.storeQuery("SELECT `account_id` FROM `players` WHERE `name` = " .. db.escapeString(reciver:lower()) .. "") + if not resultId then + return addPlayerEvent(sendStoreError, 350, playerId, GameStore.StoreErrors.STORE_ERROR_TRANSFER, "We couldn't find that player.") + end + + local accountId = result.getDataInt(resultId, "account_id") + if accountId == player:getAccountId() then + return addPlayerEvent(sendStoreError, 350, playerId, GameStore.StoreErrors.STORE_ERROR_TRANSFER, "You cannot transfer coin to a character in the same account.") + end + + db.query("UPDATE `accounts` SET `coins` = `coins` + " .. amount .. " WHERE `id` = " .. accountId) + player:removeCoinsBalance(amount) + addPlayerEvent(sendStorePurchaseSuccessful, 550, playerId, "You have transfered " .. amount .. " coins to " .. reciver .. " successfully") + + -- Adding history for both reciver/sender + GameStore.insertHistory(accountId, GameStore.HistoryTypes.HISTORY_TYPE_NONE, player:getName() .. " transfered you this amount.", amount) + GameStore.insertHistory(player:getAccountId(), GameStore.HistoryTypes.HISTORY_TYPE_NONE, "You transfered this amount to " .. reciver, -1 * amount) -- negative +end + +function parseOpenStore(playerId, msg) + openStore(playerId) + + local category = GameStore.Categories and GameStore.Categories[1] or nil + if category then + addPlayerEvent(parseRequestStoreOffers, 50, playerId) + end +end + +function parseRequestStoreOffers(playerId, msg) + local player = Player(playerId) + if not player then + return false + end + + local actionType = msg:getByte() + + if actionType == GameStore.ActionType.OPEN_CATEGORY then + local categoryName = msg:getString() + local category = GameStore.getCategoryByName(categoryName) + if category then + addPlayerEvent(sendShowStoreOffers, 50, playerId, category) + end + elseif actionType == GameStore.ActionType.OPEN_HOME then + sendHomePage(player:getId()) + if category then + addPlayerEvent(sendShowStoreOffers, 50, playerId, "Home Offers") + end + elseif actionType == GameStore.ActionType.OPEN_PREMIUM_BOOST then + local subAction = msg:getByte() + local category = nil + + if subAction == 0 then + category = GameStore.getCategoryByName("Premium Time") + else + category = GameStore.getCategoryByName("Boosts") + end + + if category then + addPlayerEvent(sendShowStoreOffers, 50, playerId, category) + end + elseif actionType == GameStore.ActionType.OPEN_USEFUL_THINGS then + local subAction = msg:getByte() + local redirectId = subAction + local category = nil + if subAction >= 4 then + category = GameStore.getCategoryByName("Blessings") + else + category = GameStore.getCategoryByName("Useful Things") + end + + -- Third prey slot offerId + -- We can't use offerId 0 + if subAction == 0 then + redirectId = 65008 + end + + if category then + addPlayerEvent(sendShowStoreOffers, 50, playerId, category, redirectId) + end + + elseif actionType == GameStore.ActionType.OPEN_OFFER then + local offerId = msg:getU32() + local category = GameStore.getCategoryByOffer(offerId) + if category then + addPlayerEvent(sendShowStoreOffers, 50, playerId, category, offerId) + end + end +end + +function parseBuyStoreOffer(playerId, msg) + local player = Player(playerId) + local id = msg:getU32() + local offer = GameStore.getOfferById(id) + local productType = msg:getByte() + + -- All guarding conditions under which the offer should not be processed must be included here + if (table.contains(GameStore.OfferTypes, offer.type) == false) -- we've got an invalid offer type + or (not player) -- player not found + or (player:getVocation():getId() == 0) and (not GameStore.haveOfferRook(id)) -- we don't have such offer + or (not offer) -- we could not find the offer + or (offer.type == GameStore.OfferTypes.OFFER_TYPE_NONE) -- offer is disabled + or (offer.type ~= GameStore.OfferTypes.OFFER_TYPE_NAMECHANGE and + offer.type ~= GameStore.OfferTypes.OFFER_TYPE_EXPBOOST and + offer.type ~= GameStore.OfferTypes.OFFER_TYPE_PREYBONUS and + offer.type ~= GameStore.OfferTypes.OFFER_TYPE_PREYSLOT and + offer.type ~= GameStore.OfferTypes.OFFER_TYPE_TEMPLE and + offer.type ~= GameStore.OfferTypes.OFFER_TYPE_SEXCHANGE and + offer.type ~= GameStore.OfferTypes.OFFER_TYPE_INSTANT_REWARD_ACCESS and + offer.type ~= GameStore.OfferTypes.OFFER_TYPE_POUNCH and + offer.type ~= GameStore.OfferTypes.OFFER_TYPE_HIRELING and + offer.type ~= GameStore.OfferTypes.OFFER_TYPE_HIRELING_NAMECHANGE and + offer.type ~= GameStore.OfferTypes.OFFER_TYPE_HIRELING_SEXCHANGE and + offer.type ~= GameStore.OfferTypes.OFFER_TYPE_HIRELING_SKILL and + offer.type ~= GameStore.OfferTypes.OFFER_TYPE_HIRELING_OUTFIT and + not offer.id) then + return queueSendStoreAlertToUser("This offer is unavailable [1]", 350, playerId, GameStore.StoreErrors.STORE_ERROR_INFORMATION) + end + + -- At this point the purchase is assumed to be formatted correctly + local offerPrice = offer.type == GameStore.OfferTypes.OFFER_TYPE_EXPBOOST and GameStore.ExpBoostValues[player:getStorageValue(GameStore.Storages.expBoostCount)] or offer.price + + if not player:canRemoveCoins(offerPrice) then + return queueSendStoreAlertToUser("You don't have enough coins. Your purchase has been cancelled.", 250, playerId) + end + + -- Use pcall to catch unhandled errors and send an alert to the user because the client expects it at all times; (OTClient will unlock UI) + -- Handled errors are thrown to indicate that the purchase has failed; + -- Handled errors have a code index and unhandled errors do not + local pcallOk, pcallError = pcall(function() + if offer.type == GameStore.OfferTypes.OFFER_TYPE_ITEM then GameStore.processItemPurchase(player, offer.itemtype, offer.count) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_POUNCH then GameStore.processItemPurchase(player, offer.itemtype, offer.count) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_INSTANT_REWARD_ACCESS then GameStore.processInstantRewardAccess(player, offer.count) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_CHARMS then GameStore.processCharmsPurchase(player) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_BLESSINGS then GameStore.processSignleBlessingPurchase(player, offer.blessid, offer.count) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_ALLBLESSINGS then GameStore.processAllBlessingsPurchase(player, offer.count) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_PREMIUM then GameStore.processPremiumPurchase(player, offer.id) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_STACKABLE then GameStore.processStackablePurchase(player, offer.itemtype, offer.count, offer.name) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_HOUSE then GameStore.processHouseRelatedPurchase(player, offer.itemtype, offer.count) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT then GameStore.processOutfitPurchase(player, offer.sexId, offer.addon) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT_ADDON then GameStore.processOutfitPurchase(player, offer.sexId, offer.addon) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_MOUNT then GameStore.processMountPurchase(player, offer.id) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_NAMECHANGE then local newName = msg:getString(); GameStore.processNameChangePurchase(player, offer.id, productType, newName, offer.name, offerPrice) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_SEXCHANGE then GameStore.processSexChangePurchase(player) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_EXPBOOST then GameStore.processExpBoostPuchase(player) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_PREYSLOT then GameStore.processPreySlotPurchase(player) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_HUNTINGSLOT then GameStore.processPreyHuntingSlotPurchase(player) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_PREYBONUS then GameStore.processPreyBonusReroll(player, offer.count) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_TEMPLE then GameStore.processTempleTeleportPurchase(player) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_CHARGES then GameStore.processChargesPurchase(player, offer.itemtype, offer.name, offer.charges) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_HIRELING then local hirelingName = msg:getString(); local sex = msg:getByte(); GameStore.processHirelingPurchase(player, offer, productType, hirelingName, sex) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_HIRELING_NAMECHANGE then local hirelingName = msg:getString(); GameStore.processHirelingChangeNamePurchase(player, offer, productType, hirelingName) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_HIRELING_SEXCHANGE then GameStore.processHirelingChangeSexPurchase(player, offer) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_HIRELING_SKILL then GameStore.processHirelingSkillPurchase(player, offer) + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_HIRELING_OUTFIT then GameStore.processHirelingOutfitPurchase(player, offer) + else + -- This should never happen by our convention, but just in case the guarding condition is messed up... + error({code = 0, message = "This offer is unavailable [2]"}) + end + end) + + if not pcallOk then + local alertMessage = pcallError.code and pcallError.message or "Something went wrong. Your purchase has been cancelled." + + if not pcallError.code then -- unhandled error + -- log some debugging info + Spdlog.warn("[parseBuyStoreOffer] - Purchase failed due to an unhandled script error. Stacktrace: ".. pcallError) + end + + return queueSendStoreAlertToUser(alertMessage, 500, playerId) + end + + local configure = useOfferConfigure(offer.type) + if configure ~= GameStore.ConfigureOffers.SHOW_CONFIGURE then + player:removeCoinsBalance(offerPrice) + GameStore.insertHistory(player:getAccountId(), GameStore.HistoryTypes.HISTORY_TYPE_NONE, offer.name, (offerPrice) * -1) + local message = string.format("You have purchased %s for %d coins.", offer.name, offerPrice) + sendUpdateCoinBalance(playerId) + return addPlayerEvent(sendStorePurchaseSuccessful, 650, playerId, message) + end + return true +end + +-- Both functions use same formula! +function parseOpenTransactionHistory(playerId, msg) + local page = 1 + GameStore.DefaultValues.DEFAULT_VALUE_ENTRIES_PER_PAGE = msg:getByte() + sendStoreTransactionHistory(playerId, page, GameStore.DefaultValues.DEFAULT_VALUE_ENTRIES_PER_PAGE) +end + +function parseRequestTransactionHistory(playerId, msg) + local page = msg:getU32() + sendStoreTransactionHistory(playerId, page + 1, GameStore.DefaultValues.DEFAULT_VALUE_ENTRIES_PER_PAGE) +end + +local function getCategoriesRook() + local tmpTable, count = {}, 0 + for i, v in pairs(GameStore.Categories) do + if (v.rookgaard) then + tmpTable[#tmpTable + 1] = v + count = count + 1 + end + end + + return tmpTable, count +end + +--==Sending==-- +function openStore(playerId) + local player = Player(playerId) + if not player then + return false + end + + if not GameStore.Categories then + return false + end + + local msg = NetworkMessage() + msg:addByte(GameStore.SendingPackets.S_OpenStore) + + local GameStoreCategories, GameStoreCount = nil, 0 + if (player:getVocation():getId() == 0) then + GameStoreCategories, GameStoreCount = getCategoriesRook() + else + GameStoreCategories, GameStoreCount = GameStore.Categories, #GameStore.Categories + end + + if (GameStoreCategories) then + msg:addU16(GameStoreCount) + for k, category in ipairs(GameStoreCategories) do + msg:addString(category.name) + msg:addByte(category.state or GameStore.States.STATE_NONE) + msg:addByte(#category.icons) + for m, icon in ipairs(category.icons) do + msg:addString(icon) + end + + if category.parent then + msg:addString(category.parent) + else + msg:addU16(0) + end + end + + msg:sendToPlayer(player) + sendCoinBalanceUpdating(playerId, true) + end +end + +function sendOfferDescription(player, offerId, description) + local msg = NetworkMessage() + msg:addByte(0xEA) + msg:addU32(offerId) + msg:addString(description) + msg:sendToPlayer(player) +end + +function Player.canBuyOffer(self, offer) + local playerId = self:getId() + local disabled, disabledReason = 0, "" + if offer.disabled == true or not offer.type then + disabled = 1 + end + + if offer.type ~= GameStore.OfferTypes.OFFER_TYPE_NAMECHANGE and + offer.type ~= GameStore.OfferTypes.OFFER_TYPE_EXPBOOST and + offer.type ~= GameStore.OfferTypes.OFFER_TYPE_PREYSLOT and + offer.type ~= GameStore.OfferTypes.OFFER_TYPE_PREYBONUS and + offer.type ~= GameStore.OfferTypes.OFFER_TYPE_TEMPLE and + offer.type ~= GameStore.OfferTypes.OFFER_TYPE_SEXCHANGE and + offer.type ~= GameStore.OfferTypes.OFFER_TYPE_POUNCH and + offer.type ~= GameStore.OfferTypes.OFFER_TYPE_HIRELING_SKILL and + offer.type ~= GameStore.OfferTypes.OFFER_TYPE_HIRELING_OUTFIT and + not offer.id then + disabled = 1 + end + + if disabled == 1 and offer.disabledReason then + -- dynamic disable + disabledReason = offer.disabledReason + end + + if disabled ~= 1 then + if offer.type == GameStore.OfferTypes.OFFER_TYPE_POUNCH then + local pounch = self:getItemById(26377, true) + if pounch then + disabled = 1 + disabledReason = "You already have Loot Pouch." + end + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_BLESSINGS then + if self:getBlessingCount(offer.blessid) >= 5 then + disabled = 1 + disabledReason = "You reached the maximum amount for this blessing." + end + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_ALLBLESSINGS then + for i = 1, 8 do + if self:getBlessingCount(i) >= 5 then + disabled = 1 + disabledReason = "You already have all Blessings." + break + end + end + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT or offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT_ADDON then + local outfitLookType + if self:getSex() == PLAYERSEX_MALE then + outfitLookType = offer.sexId.male + else + outfitLookType = offer.sexId.female + end + + if outfitLookType then + if offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT and self:hasOutfit(outfitLookType) then + disabled = 1 + disabledReason = "You already have this outfit." + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT_ADDON then + if self:hasOutfit(outfitLookType) then + if self:hasOutfit(outfitLookType, offer.addon) then + disabled = 1 + disabledReason = "You already have this addon." + end + else + disabled = 1 + disabledReason = "You don't have the outfit, you can't buy the addon." + end + end + else + disabled = 1 + disabledReason = "The offer is fake." + end + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_MOUNT then + local hasMount = self:hasMount(offer.id) + if hasMount == true then + disabled = 1 + disabledReason = "You already have this mount." + end + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_INSTANT_REWARD_ACCESS then + if self:getCollectionTokens() >= 90 then + disabled = 1 + disabledReason = "You already have maximum of reward tokens." + end + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_PREYBONUS then + if self:getPreyBonusRerolls() >= 50 then + disabled = 1 + disabledReason = "You already have maximum of prey wildcards." + end + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_CHARMS then + if self:charmExpansion() then + disabled = 1 + disabledReason = "You already have charm expansion." + end + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_PREYSLOT then + if self:getStorageValue(Prey.Config.StoreSlotStorage) == 1 then + disabled = 1 + disabledReason = "You already have 3 slots released." + end + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_EXPBOOST then + local remainingBoost = self:getExpBoostStamina() + if self:getStorageValue(GameStore.Storages.expBoostCount) == 6 then + disabled = 1 + disabledReason = "You can't buy XP Boost for today." + end + if (remainingBoost > 0) then + disabled = 1 + disabledReason = "You already have an active XP boost." + end + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_HIRELING then + if self:getHirelingsCount() >= 10 then + disabled = 1 + disabledReason = "You already have bought the maximum number of allowed hirelings." + end + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_HIRELING_SKILL then + local skill = (HIRELING_STORAGE.SKILL + offer.id) + if self:hasHirelingSkill(skill) then + disabled = 1 + disabledReason = "This skill is already unlocked." + end + if self:getHirelingsCount() <= 0 then + disabled = 1 + disabledReason = "You need to have a hireling." + end + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_HIRELING_OUTFIT then + local outfit = offer.id - HIRELING_STORAGE.OUTFIT + if self:hasHirelingOutfit(outfit) then + disabled = 1 + disabledReason = "This hireling outfit is already unlocked." + end + if self:getHirelingsCount() <= 0 then + disabled = 1 + disabledReason = "You need to have a hireling." + end + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_HIRELING_NAMECHANGE then + if self:getHirelingsCount() <= 0 then + disabled = 1 + disabledReason = "You need to have a hireling." + end + elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_HIRELING_SEXCHANGE then + if self:getHirelingsCount() <= 0 then + disabled = 1 + disabledReason = "You need to have a hireling." + end + end + end + + return {disabled = disabled, disabledReason = disabledReason} +end + +function sendShowStoreOffers(playerId, category, redirectId) + local player = Player(playerId) + if not player then + return false + end + + local version = player:getClient().version + local msg = NetworkMessage() + local haveSaleOffer = 0 + msg:addByte(GameStore.SendingPackets.S_StoreOffers) + msg:addString(category.name) + + msg:addU32(redirectId or 0) + + msg:addByte(0) -- Window Type + msg:addByte(0) -- Collections Size + msg:addU16(0) -- Collection Name + + if not category.offers then + msg:addU16(0) + msg:sendToPlayer(player) + return + end + + local offers = {} + local count = 0 + for k, offer in ipairs(category.offers) do + local name = offer.name or "Something Special" + if not offers[name] then + offers[name] = {} + count = count + 1 + offers[name].offers = {} + offers[name].state = offer.state + offers[name].id = offer.id + offers[name].type = offer.type + offers[name].icons = offer.icons + offers[name].basePrice = offer.basePrice + offers[name].description = offer.description + if offer.sexId then + offers[name].sexId = offer.sexId + end + if offer.itemtype then + offers[name].itemtype = offer.itemtype + end + end + table.insert(offers[name].offers, offer) + end + + -- If player doesn't have hireling + if category.name == "Hirelings" then + if player:getHirelingsCount() < 1 then + offers["Hireling Name Change"] = nil + offers["Hireling Sex Change"] = nil + offers["Hireling Trader"] = nil + offers["Hireling Steward"] = nil + offers["Hireling Banker"] = nil + offers["Hireling Cook"] = nil + count = count - 6 + end + end + + msg:addU16(count) + + if count > 0 then + for name, offer in pairs(offers) do + msg:addString(name) + msg:addByte(#offer.offers) + sendOfferDescription(player, offer.id and offer.id or 0xFFFF, offer.description) + for _, off in ipairs(offer.offers) do + xpBoostPrice = nil + if offer.type == GameStore.OfferTypes.OFFER_TYPE_EXPBOOST then + xpBoostPrice = GameStore.ExpBoostValues[player:getStorageValue(GameStore.Storages.expBoostCount)] + end + + msg:addU32(off.id) + msg:addU16(off.count) + msg:addU32(xpBoostPrice or off.price) + msg:addByte(off.coinType or 0x00) + + local disabled, disabledReason = player:canBuyOffer(off).disabled, player:canBuyOffer(off).disabledReason + msg:addByte(disabled) + if disabled == 1 then + msg:addByte(0x01); + msg:addString(disabledReason) + end + + if (off.state) then + if (off.state == GameStore.States.STATE_SALE) then + local daySub = off.validUntil - os.sdate("*t").day + if (daySub >= 0) then + msg:addByte(off.state) + msg:addU32(os.time() + daySub * 86400) + msg:addU32(off.basePrice) + haveSaleOffer = 1 + else + msg:addByte(GameStore.States.STATE_NONE) + end + else + msg:addByte(off.state) + end + else + msg:addByte(GameStore.States.STATE_NONE) + end + end + + local tryOnType = 0 + local type = convertType(offer.type) + + msg:addByte(type); + if type == GameStore.ConverType.SHOW_NONE then + msg:addString(offer.icons[1]) + elseif type == GameStore.ConverType.SHOW_MOUNT then + local mount = Mount(offer.id) + msg:addU16(mount:getClientId()) + + tryOnType = 1 + elseif type == GameStore.ConverType.SHOW_ITEM then + msg:addU16(ItemType(offer.itemtype):getClientId()) + elseif type == GameStore.ConverType.SHOW_OUTFIT then + msg:addU16(player:getSex() == PLAYERSEX_FEMALE and offer.sexId.female or offer.sexId.male) + local outfit = player:getOutfit() + msg:addByte(outfit.lookHead) + msg:addByte(outfit.lookBody) + msg:addByte(outfit.lookLegs) + msg:addByte(outfit.lookFeet) + + tryOnType = 1 + elseif type == GameStore.ConverType.SHOW_HIRELING then + if player:getSex() == PLAYERSEX_MALE then + msg:addByte(1) + else + msg:addByte(2) + end + msg:addU16(offer.sexId.male) + msg:addU16(offer.sexId.female) + local outfit = player:getOutfit() + msg:addByte(outfit.lookHead) + msg:addByte(outfit.lookBody) + msg:addByte(outfit.lookLegs) + msg:addByte(outfit.lookFeet) + end + + msg:addByte(tryOnType) -- TryOn Type + msg:addU16(0) -- Collection (to-do) + msg:addU16(0) -- Popularity Score (to-do) + msg:addU32(0) -- State New Until (timestamp) + + local configure = useOfferConfigure(offer.type) + if configure == GameStore.ConfigureOffers.SHOW_CONFIGURE then + msg:addByte(1) + else + msg:addByte(0) + end + + msg:addU16(0) -- Products Capacity (unnused) + end + end + + player:sendButtonIndication(haveSaleOffer, 1) + msg:sendToPlayer(player) + msg:delete() +end + +function sendStoreTransactionHistory(playerId, page, entriesPerPage) + local player = Player(playerId) + if not player then + return false + end + local version = player:getClient().version + local totalEntries = GameStore.retrieveHistoryTotalPages(player:getAccountId()) + local totalPages = math.ceil(totalEntries / entriesPerPage) + local entries = GameStore.retrieveHistoryEntries(player:getAccountId(), page, entriesPerPage) -- this makes everything easy! + if #entries == 0 then + return addPlayerEvent(sendStoreError, 250, playerId, GameStore.StoreErrors.STORE_ERROR_HISTORY, "You don't have any entries yet.") + end + + local msg = NetworkMessage() + msg:addByte(GameStore.SendingPackets.S_OpenTransactionHistory) + msg:addU32(totalPages > 0 and page - 1 or 0x0) -- current page + msg:addU32(totalPages > 0 and totalPages or 0x0) -- total page + msg:addByte(#entries) + + for k, entry in ipairs(entries) do + if version >= 1220 then + msg:addU32(0) + end + msg:addU32(entry.time) + msg:addByte(entry.mode) + msg:addU32(entry.amount) + msg:addByte(0x0) -- 0 = transferable tibia coin, 1 = normal tibia coin + msg:addString(entry.description) + if version >= 1220 then + msg:addByte(0) -- details + end + end + msg:sendToPlayer(player) +end + +function sendStorePurchaseSuccessful(playerId, message) + local player = Player(playerId) + if not player then + return false + end + + local msg = NetworkMessage() + msg:addByte(GameStore.SendingPackets.S_CompletePurchase) + msg:addByte(0x00) + msg:addString(message) + + msg:sendToPlayer(player) +end + +function sendStoreError(playerId, errorType, message) + local player = Player(playerId) + if not player then + return false + end + + local msg = NetworkMessage() + msg:addByte(GameStore.SendingPackets.S_StoreError) + + msg:addByte(errorType) + msg:addString(message) + + msg:sendToPlayer(player) +end + +function sendCoinBalanceUpdating(playerId, updating) + local player = Player(playerId) + if not player then + return false + end + + local msg = NetworkMessage() + msg:addByte(GameStore.SendingPackets.S_CoinBalanceUpdating) + msg:addByte(0x00) + msg:sendToPlayer(player) + + if updating == true then + sendUpdateCoinBalance(playerId) + end +end + +function sendUpdateCoinBalance(playerId) + local player = Player(playerId) + if not player then + return false + end + + local msg = NetworkMessage() + msg:addByte(GameStore.SendingPackets.S_CoinBalanceUpdating) + msg:addByte(0x01) + + msg:addByte(GameStore.SendingPackets.S_CoinBalance) + msg:addByte(0x01) + + msg:addU32(player:getCoinsBalance()) + msg:addU32(player:getCoinsBalance()) + msg:addU32(player:getCoinsBalance()) + msg:addU32(0) -- Tournament Coins + + msg:sendToPlayer(player) +end + +function sendRequestPurchaseData(playerId, offerId, type) + local player = Player(playerId) + if not player then + return false + end + + local msg = NetworkMessage() + msg:addByte(GameStore.SendingPackets.S_RequestPurchaseData) + msg:addU32(offerId) + msg:addByte(type) + msg:sendToPlayer(player) +end + +--==GameStoreFunctions==-- +GameStore.getCategoryByName = function(name) + for k, category in ipairs(GameStore.Categories) do + if category.name:lower() == name:lower() then + if not category.offers then + return GameStore.getCategoryByName(category.subclasses[1]) + end + return category + end + end + return nil +end + +GameStore.getCategoryByOffer = function(id) + for Cat_k, category in ipairs(GameStore.Categories) do + if category.offers then + for Off_k, offer in ipairs(category.offers) do + if type(offer.id) == "number" then + if offer.id == id then + if not category.offers then + return GameStore.getCategoryByName(category.subclasses[1]) + end + return category + end + elseif type(offer.id) == "table" then + for m, offerId in pairs(offer.id) do + -- in case of outfits we have offer.id = {male = ..., female = ...} + if offerId == id then + if not category.offers then + return GameStore.getCategoryByName(category.subclasses[1]) + end + return category + end + end + end + + end + end + end + return nil +end + +GameStore.getOfferById = function(id) + for Cat_k, category in ipairs(GameStore.Categories) do + if category.offers then + for Off_k, offer in ipairs(category.offers) do + if type(offer.id) == "number" then + if offer.id == id then + return offer + end + elseif type(offer.id) == "table" and (offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT or offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT_ADDON) then + for m, offerId in pairs(offer.id) do + -- in case of outfits we have offer.id = {male = ..., female = ...} + if offerId == id then + return offer + end + end + + -- case multi offer + elseif type(offer.id) == "table" then + local newoffer = offer + for i = 1, #offer.id do + local offerId = offer.id[i] + if offerId == id then + newoffer.id = offerId + newoffer.price = offer.price[i] + return newoffer + end + end + end + + end + end + end + return nil +end + +-- Using for multi offer +function GameStore.getOffersByName(name) + local offers = {} + for Cat_k, category in ipairs(GameStore.Categories) do + if category.offers then + for Off_k, offer in ipairs(category.offers) do + if offer.name:lower() == name:lower() then + table.insert(offers, offer) + end + end + end + end + return offers +end + +GameStore.haveCategoryRook = function() + for Cat_k, category in ipairs(GameStore.Categories) do + if category.offers and category.rookgaard then + return true + end + end + + return false +end + +GameStore.haveOfferRook = function(id) + for Cat_k, category in ipairs(GameStore.Categories) do + if category.offers and category.rookgaard then + for Off_k, offer in ipairs(category.offers) do + if offer.id == id then + return true + end + end + end + end + return nil +end + +GameStore.insertHistory = function(accountId, mode, description, amount) + return db.query(string.format("INSERT INTO `store_history`(`account_id`, `mode`, `description`, `coin_amount`, `time`) VALUES (%s, %s, %s, %s, %s)", accountId, mode, db.escapeString(description), amount, os.time())) +end + +GameStore.retrieveHistoryTotalPages = function (accountId) + local resultId = db.storeQuery("SELECT count(id) as total FROM store_history WHERE account_id = " .. accountId) + if resultId == false then + return 0 + end + + local totalPages = result.getDataInt(resultId, "total") + result.free(resultId) + return totalPages +end + +GameStore.retrieveHistoryEntries = function(accountId, currentPage, entriesPerPage) + local entries = {} + local offset = currentPage > 1 and entriesPerPage * (currentPage - 1) or 0 + + local resultId = db.storeQuery("SELECT * FROM `store_history` WHERE `account_id` = " .. accountId .. " ORDER BY `time` DESC LIMIT " .. offset .. ", " .. entriesPerPage .. ";") + if resultId ~= false then + repeat + local entry = { + mode = result.getDataInt(resultId, "mode"), + description = result.getDataString(resultId, "description"), + amount = result.getDataInt(resultId, "coin_amount"), + time = result.getDataInt(resultId, "time"), + } + table.insert(entries, entry) + until not result.next(resultId) + result.free(resultId) + end + return entries +end + +GameStore.getDefaultDescription = function(offerType, count) + local t, descList = GameStore.OfferTypes + if offerType == t.OFFER_TYPE_OUTFIT or offerType == t.OFFER_TYPE_OUTFIT_ADDON then + descList = GameStore.DefaultDescriptions.OUTFIT + elseif offerType == t.OFFER_TYPE_MOUNT then + descList = GameStore.DefaultDescriptions.MOUNT + elseif offerType == t.OFFER_TYPE_NAMECHANGE then + descList = GameStore.DefaultDescriptions.NAMECHANGE + elseif offerType == t.OFFER_TYPE_SEXCHANGE then + descList = GameStore.DefaultDescriptions.SEXCHANGE + elseif offerType == t.OFFER_TYPE_EXPBOOST then + descList = GameStore.DefaultDescriptions.EXPBOOST + elseif offerType == t.OFFER_TYPE_PREYSLOT then + descList = GameStore.DefaultDescriptions.PREYSLOT + elseif offerType == t.OFFER_TYPE_PREYBONUS then + descList = GameStore.DefaultDescriptions.PREYBONUS + elseif offerType == t.OFFER_TYPE_TEMPLE then + descList = GameStore.DefaultDescriptions.TEMPLE + end + + return descList[math.floor(math.random(1, #descList))] or "" +end + +GameStore.canUseHirelingName = function(name) + local result = { + ability = false + } + if name:len() < 3 or name:len() > 14 then + result.reason = "The length of the hireling name must be between 3 and 14 characters." + return result + end + + local match = name:gmatch("%s+") + local count = 0 + for v in match do + count = count + 1 + end + + local matchtwo = name:match("^%s+") + if (matchtwo) then + result.reason = "The hireling name can't have whitespace at begin." + return result + end + + local matchthree = name:match("[^a-zA-Z ]") + if (matchthree) then + result.reason = "The hireling name has invalid characters" + return result + end + + if (count > 1) then + result.reason = "The hireling name have more than 1 whitespace." + return result + end + + -- just copied from znote aac. + local words = { "owner", "gamemaster", "hoster", "admin", "staff", "tibia", "account", "god", "anal", "ass", "fuck", "sex", "hitler", "pussy", "dick", "rape", "adm", "cm", "gm", "tutor", "counsellor" } + local split = name:split(" ") + for k, word in ipairs(words) do + for k, nameWord in ipairs(split) do + if nameWord:lower() == word then + result.reason = "You can't use word \"" .. word .. "\" in your hireling name." + return result + end + end + end + + local tmpName = name:gsub("%s+", "") + for i = 1, #words do + if (tmpName:lower():find(words[i])) then + result.reason = "You can't use word \"" .. words[i] .. "\" with whitespace in your hireling name." + return result + end + end + + result.ability = true + return result +end + +GameStore.canChangeToName = function(name) + local result = { + ability = false + } + if name:len() < 3 or name:len() > 14 then + result.reason = "The length of your new name must be between 3 and 14 characters." + return result + end + + local match = name:gmatch("%s+") + local count = 0 + for v in match do + count = count + 1 + end + + local matchtwo = name:match("^%s+") + if (matchtwo) then + result.reason = "Your new name can't have whitespace at begin." + return result + end + + if (count > 1) then + result.reason = "Your new name have more than 1 whitespace." + return result + end + + -- just copied from znote aac. + local words = { "owner", "gamemaster", "hoster", "admin", "staff", "tibia", "account", "god", "anal", "ass", "fuck", "sex", "hitler", "pussy", "dick", "rape", "adm", "cm", "gm", "tutor", "counsellor" } + local split = name:split(" ") + for k, word in ipairs(words) do + for k, nameWord in ipairs(split) do + if nameWord:lower() == word then + result.reason = "You can't use word \"" .. word .. "\" in your new name." + return result + end + end + end + + local tmpName = name:gsub("%s+", "") + for i = 1, #words do + if (tmpName:lower():find(words[i])) then + result.reason = "You can't use word \"" .. words[i] .. "\" with whitespace in your new name." + return result + end + end + + if MonsterType(name) then + result.reason = "Your new name \"" .. name .. "\" can't be a monster's name." + return result + elseif Npc(name) then + result.reason = "Your new name \"" .. name .. "\" can't be a npc's name." + return result + end + + local letters = "{}|_*+-=<>0123456789@#%^&()/*'\\.,:;~!\"$" + for i = 1, letters:len() do + local c = letters:sub(i, i) + for i = 1, name:len() do + local m = name:sub(i, i) + if m == c then + result.reason = "You can't use this letter \"" .. c .. "\" in your new name." + return result + end + end + end + result.ability = true + return result +end + +-- +-- PURCHASE PROCESSOR FUNCTIONS +-- Must throw an error when the purchase has not been made. The error must of +-- take a table {code = ..., message = ...} if the error is handled. When no code +-- index is present the error is assumed to be unhandled. + +function GameStore.processItemPurchase(player, offerId, offerCount) + if player:getFreeCapacity() < ItemType(offerId):getWeight(offerCount) then + return error({ code = 0, message = "Please make sure you have free capacity to hold this item."}) + end + + local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX) + if inbox and inbox:getEmptySlots() > offerCount then + for t = 1, offerCount do + inbox:addItem(offerId, offerCount or 1) + end + else + return error({ code = 0, message = "Please make sure you have free slots in your store inbox."}) + end +end +function GameStore.processChargesPurchase(player, itemtype, name, charges) + if player:getFreeCapacity() < ItemType(itemtype):getWeight(1) then + return error({ code = 0, message = "Please make sure you have free capacity to hold this item."}) + end + + local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX) + if inbox and inbox:getEmptySlots() > 1 then + inbox:addItem(itemtype, charges) + else + return error({ code = 0, message = "Please make sure you have free slots in your store inbox."}) + end +end + +function GameStore.processSignleBlessingPurchase(player, blessId, count) + player:addBlessing(blessId, count) +end + +function GameStore.processAllBlessingsPurchase(player, count) + player:addBlessing(1, count) + player:addBlessing(2, count) + player:addBlessing(3, count) + player:addBlessing(4, count) + player:addBlessing(5, count) + player:addBlessing(6, count) + player:addBlessing(7, count) + player:addBlessing(8, count) +end + +function GameStore.processInstantRewardAccess(player, offerCount) + if player:getCollectionTokens() + offerCount >= 91 then + return error({code = 1, message = "You cannot own more than 90 reward tokens."}) + end + player:setCollectionTokens(player:getCollectionTokens() + offerCount) +end + +function GameStore.processCharmsPurchase(player) + player:charmExpansion(true) +end + +function GameStore.processPremiumPurchase(player, offerId) + player:addPremiumDays(offerId - 3000) +end + +function GameStore.processStackablePurchase(player, offerId, offerCount, offerName) + local function isKegItem(itemId) + return itemId >= ITEM_KEG_START and itemId <= ITEM_KEG_END + end + + if isKegItem(offerId) then + if player:getFreeCapacity() < ItemType(offerId):getWeight(1) + ItemType(2596):getWeight() then + return error({code = 0, message = "Please make sure you have free capacity to hold this item."}) + end + elseif player:getFreeCapacity() < ItemType(offerId):getWeight(offerCount) + ItemType(2596):getWeight() then + return error({code = 0, message = "Please make sure you have free capacity to hold this item."}) + end + + local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX) + if inbox and inbox:getEmptySlots() > 0 then + if (isKegItem(offerId)) then + if (offerCount >= 500) then + local parcel = Item(inbox:addItem(2596, 1):getUniqueId()) + local function changeParcel(parcel) + local packagename = '' .. offerCount .. 'x ' .. offerName .. ' package.' + if parcel then + parcel:setAttribute(ITEM_ATTRIBUTE_NAME, packagename) + local pendingCount = offerCount + while (pendingCount > 0) do + local pack + if (pendingCount > 500) then + pack = 500 + else + pack = pendingCount + end + local kegItem = parcel:addItem(offerId, 1) + kegItem:setAttribute(ITEM_ATTRIBUTE_CHARGES, pack) + pendingCount = pendingCount - pack + end + end + end + addEvent(function() changeParcel(parcel) end, 250) + else + local kegItem = inbox:addItem(offerId, 1) + kegItem:setAttribute(ITEM_ATTRIBUTE_CHARGES, offerCount) + end + elseif (offerCount > 100) then + local parcel = Item(inbox:addItem(2596, 1):getUniqueId()) + local function changeParcel(parcel) + local packagename = '' .. offerCount .. 'x ' .. offerName .. ' package.' + if parcel then + parcel:setAttribute(ITEM_ATTRIBUTE_NAME, packagename) + local pendingCount = offerCount + while (pendingCount > 0) do + local pack + if (pendingCount > 100) then + pack = 100 + else + pack = pendingCount + end + parcel:addItem(offerId, pack) + pendingCount = pendingCount - pack + end + end + end + addEvent(function() changeParcel(parcel) end, 250) + else + inbox:addItem(offerId, offerCount) + end + else + return error({code = 0, message = "Please make sure you have free slots in your store inbox."}) + end +end + +function GameStore.processHouseRelatedPurchase(player, offerId, offerCount) + local function isCaskItem(itemId) + return (itemId >= ITEM_HEALTH_CASK_START and itemId <= ITEM_HEALTH_CASK_END) or + (itemId >= ITEM_MANA_CASK_START and itemId <= ITEM_MANA_CASK_END) or + (itemId >= ITEM_SPIRIT_CASK_START and itemId <= ITEM_SPIRIT_CASK_END) + end + + local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX) + if inbox and inbox:getEmptySlots() > 0 then + local decoKit = inbox:addItem(26054, 1) + local function changeKit(kit) + local decoItemName = ItemType(offerId):getName() + if kit then + kit:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, "You bought this item in the Store.\nUnwrap it in your own house to create a <" .. decoItemName .. ">.") + kit:setCustomAttribute("unWrapId", offerId) + + if isCaskItem(offerId) then + kit:setAttribute(ITEM_ATTRIBUTE_DATE, offerCount) + end + end + end + addEvent(function() changeKit(decoKit) end, 250) + else + return error({code = 0, message = "Please make sure you have free slots in your store inbox."}) + end +end + +function GameStore.processOutfitPurchase(player, offerSexIdTable, addon) + local looktype + local _addon = addon and addon or 0 + + if player:getSex() == PLAYERSEX_MALE then + looktype = offerSexIdTable.male + elseif player:getSex() == PLAYERSEX_FEMALE then + looktype = offerSexIdTable.female + end + + if not looktype then + return error({code = 0, message = "This outfit seems not to suit your sex, we are sorry for that!"}) + elseif (not player:hasOutfit(looktype, 0)) and (_addon == 1 or _addon == 2) then + return error({code = 0, message = "You must own the outfit before you can buy its addon."}) + elseif player:hasOutfit(looktype, _addon) then + return error({code = 0, message = "You already own this outfit."}) + else + if not (player:addOutfitAddon(looktype, _addon)) -- TFS call failed + or (not player:hasOutfit(looktype, _addon)) -- Additional check; if the looktype doesn't match player sex for example, + -- then the TFS check will still pass... bug? (TODO) + then + error({ code = 0, message = "There has been an issue with your outfit purchase. Your purchase has been cancelled."}) + else + player:addOutfitAddon(offerSexIdTable.male, _addon) + player:addOutfitAddon(offerSexIdTable.female, _addon) + end + end +end + +function GameStore.processMountPurchase(player, offerId) + player:addMount(offerId) +end + +function GameStore.processNameChangePurchase(player, offerId, productType, newName, offerName, offerPrice) + local playerId = player:getId() + + if productType == GameStore.ClientOfferTypes.CLIENT_STORE_OFFER_NAMECHANGE then + local tile = Tile(player:getPosition()) + if (tile) then + if (not tile:hasFlag(TILESTATE_PROTECTIONZONE)) then + return error({code = 1, message = "You can change name only in Protection Zone."}) + end + end + + local resultId = db.storeQuery("SELECT * FROM `players` WHERE `name` = " .. db.escapeString(newName) .. "") + if resultId ~= false then + return error({code = 1, message = "This name is already used, please try again!"}) + end + + local result = GameStore.canChangeToName(newName) + if not result.ability then + return error({code = 1, message = result.reason}) + end + + player:removeCoinsBalance(offerPrice) + GameStore.insertHistory(player:getAccountId(), GameStore.HistoryTypes.HISTORY_TYPE_NONE, offerName, (offerPrice) * -1) + + local message = string.format("You have purchased %s for %d coins.", offerName, offerPrice) + addPlayerEvent(sendStorePurchaseSuccessful, 500, playerId, message) + + newName = newName:lower():gsub("(%l)(%w*)", function(a, b) return string.upper(a) .. b end) + db.query("UPDATE `players` SET `name` = " .. db.escapeString(newName) .. " WHERE `id` = " .. player:getGuid()) + message = "You have successfully changed you name, relogin!" + addEvent(function() + local player = Player(playerId) + if not player then + return false + end + + player:remove() + end, 1000) + -- If not, we ask him to do! + else + return addPlayerEvent(sendRequestPurchaseData, 250, playerId, offerId, GameStore.ClientOfferTypes.CLIENT_STORE_OFFER_NAMECHANGE) + end +end + +function GameStore.processSexChangePurchase(player) + player:toggleSex() +end + + +function GameStore.processExpBoostPuchase(player) + local currentExpBoostTime = player:getExpBoostStamina() + local expBoostCount = player:getStorageValue(GameStore.Storages.expBoostCount) + + player:setStoreXpBoost(50) + player:setExpBoostStamina(currentExpBoostTime + 3600) + + if (player:getStorageValue(GameStore.Storages.expBoostCount) == -1 or expBoostCount == 6) then + player:setStorageValue(GameStore.Storages.expBoostCount, 1) + end + + player:setStorageValue(GameStore.Storages.expBoostCount, expBoostCount + 1) +end + +function GameStore.processPreySlotPurchase(player) + if player:getStorageValue(Prey.Config.StoreSlotStorage) < 1 then + player:setStorageValue(Prey.Config.StoreSlotStorage, 1) + player:setPreyUnlocked(CONST_PREY_SLOT_THIRD, 2) + player:setPreyState(CONST_PREY_SLOT_THIRD, 1) + + -- Update Prey Data + for slot = CONST_PREY_SLOT_FIRST, CONST_PREY_SLOT_THIRD do + player:sendPreyData(slot) + end + end +end + +function GameStore.processPreyHuntingSlotPurchase(player) + if player:getStorageValue(CONST_HUNTING_STORAGE) < 1 then + player:setStorageValue(CONST_HUNTING_STORAGE, 1) + + -- Update Prey Data + player:sendPreyHuntingData(CONST_PREY_SLOT_THIRD) + end +end + +function GameStore.processPreyBonusReroll(player, offerCount) + if player:getPreyBonusRerolls() + offerCount >= 51 then + return error({code = 1, message = "You cannot own more than 50 prey wildcards."}) + end + player:setPreyBonusRerolls(player:getPreyBonusRerolls() + offerCount) +end + +function GameStore.processTempleTeleportPurchase(player) + if player:getCondition(CONDITION_INFIGHT, CONDITIONID_DEFAULT) or player:isPzLocked() then + return error({code = 0, message = "You can't use temple teleport in fight!"}) + end + + player:teleportTo(player:getTown():getTemplePosition()) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have been teleported to your hometown.') +end + +function GameStore.processHirelingPurchase(player, offer, productType, hirelingName, chosenSex) + local playerId = player:getId() + local offerId = offer.id + + if productType == GameStore.ClientOfferTypes.CLIENT_STORE_OFFER_HIRELING then + + local result = GameStore.canUseHirelingName(hirelingName) + if not result.ability then + return error({code = 1, message = result.reason}) + end + + hirelingName = hirelingName:lower():gsub("(%l)(%w*)", function(a, b) return string.upper(a) .. b end) + + local hireling = player:addNewHireling(hirelingName, chosenSex) + if not hireling then + return error({code = 1, message = "Error delivering your hireling lamp, try again later."}) + end + + player:removeCoinsBalance(offer.price) + GameStore.insertHistory(player:getAccountId(), GameStore.HistoryTypes.HISTORY_TYPE_NONE, offer.name .. ' ('.. hirelingName ..')', (offer.price) * -1) + local message = "You have successfully bought " .. hirelingName + return addPlayerEvent(sendStorePurchaseSuccessful, 650, playerId, message) + -- If not, we ask him to do! + else + if player:getHirelingsCount() >= 10 then + return error({code = 1, message = "You cannot have more than 10 hirelings."}) + end + -- TODO: Use the correct dialog (byte 0xDB) on client 1205+ + -- for compatibility, request name using the change name dialog + return addPlayerEvent(sendRequestPurchaseData, 250, playerId, offerId, GameStore.ClientOfferTypes.CLIENT_STORE_OFFER_HIRELING) + end +end + +function GameStore.processHirelingChangeNamePurchase(player, offer, productType, newHirelingName) + local playerId = player:getId() + local offerId = offer.id + if productType == GameStore.ClientOfferTypes.CLIENT_STORE_OFFER_NAMECHANGE then + local result = GameStore.canUseHirelingName(newHirelingName) + if not result.ability then + return error({code = 1, message = result.reason}) + end + + newHirelingName = newHirelingName:lower():gsub("(%l)(%w*)", function(a, b) return string.upper(a) .. b end) + + local message = 'Close the store window to select which hireling should be renamed to '.. newHirelingName + addPlayerEvent(sendStorePurchaseSuccessful, 200, playerId, message) + + addPlayerEvent(HandleHirelingNameChange,550, playerId, offer, newHirelingName) + + else + return addPlayerEvent(sendRequestPurchaseData, 250, playerId, offerId, GameStore.ClientOfferTypes.CLIENT_STORE_OFFER_NAMECHANGE) + end +end + +function GameStore.processHirelingChangeSexPurchase(player, offer) + local playerId = player:getId() + + local message = 'Close the store window to select which hireling should have the sex changed.' + addPlayerEvent(sendStorePurchaseSuccessful, 200, playerId, message) + + addPlayerEvent(HandleHirelingSexChange, 550, playerId, offer) +end + +function GameStore.processHirelingSkillPurchase(player, offer) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + local skill = offer.id - HIRELING_STORAGE.SKILL + player:enableHirelingSkill(skill) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'A new hireling skill has been added to all your hirelings') +end + +function GameStore.processHirelingOutfitPurchase(player, offer) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + local outfit = offer.id - HIRELING_STORAGE.OUTFIT + player:enableHirelingOutfit(outfit) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'A new hireling outfit has been added to all your hirelings') +end + +--==Player==-- +function Player.getCoinsBalance(self) + resultId = db.storeQuery("SELECT `coins` FROM `accounts` WHERE `id` = " .. self:getAccountId()) + if not resultId then return 0 end + return result.getDataInt(resultId, "coins") +end + +function Player.setCoinsBalance(self, coins) + db.query("UPDATE `accounts` SET `coins` = " .. coins .. " WHERE `id` = " .. self:getAccountId()) + return true +end + +function Player.canRemoveCoins(self, coins) + if self:getCoinsBalance() < coins then + return false + end + return true +end + +function Player.removeCoinsBalance(self, coins) + if self:canRemoveCoins(coins) then + return self:setCoinsBalance(self:getCoinsBalance() - coins) + end + + return false +end + +function Player.addCoinsBalance(self, coins, update) + self:setCoinsBalance(self:getCoinsBalance() + coins) + if update then sendCoinBalanceUpdating(self, true) end + return true +end + +function Player.sendButtonIndication(self, value1, value2) + local msg = NetworkMessage() + msg:addByte(0x19) + msg:addByte(value1) -- Sale + msg:addByte(value2) -- New Item + msg:sendToPlayer(self) +end + +function Player.toggleSex(self) + local currentSex = self:getSex() + local playerOutfit = self:getOutfit() + + playerOutfit.lookAddons = 0 + if currentSex == PLAYERSEX_FEMALE then + self:setSex(PLAYERSEX_MALE) + playerOutfit.lookType = 128 + else + self:setSex(PLAYERSEX_FEMALE) + playerOutfit.lookType = 136 + end + self:setOutfit(playerOutfit) +end + +local function getHomeOffers(playerId) + local player = Player(playerId) + if not player then return {} end + + local GameStoreCategories = GameStore.Categories + + local offers = {} + if (GameStoreCategories) then + for k, category in ipairs(GameStoreCategories) do + if category.offers then + for _, offer in ipairs(category.offers) do + if offer.home then + table.insert(offers, offer) + end + end + end + end + end + + return offers +end + +function sendHomePage(playerId) + local player = Player(playerId) + if not player then + return + end + + local version = player:getClient().version + local msg = NetworkMessage() + msg:addByte(GameStore.SendingPackets.S_StoreOffers) + + msg:addString("Home") + msg:addU32(0x0) -- Redirect ID (not used here) + msg:addByte(0x0) -- Window Type + msg:addByte(0x0) -- Collections Size + msg:addU16(0x00) -- Collection Name + + local homeOffers = getHomeOffers(player:getId()) + msg:addU16(#homeOffers) -- offers + + for p, offer in pairs(homeOffers)do + msg:addString(offer.name) + msg:addByte(0x1) -- ? + msg:addU32(offer.id or 0) -- id + msg:addU16(0x1) + msg:addU32(offer.price) + msg:addByte(offer.coinType or 0x00) + local disabled, disabledReason = player:canBuyOffer(offer).disabled, player:canBuyOffer(offer).disabledReason + msg:addByte(disabled) + if disabled == 1 then + msg:addByte(0x01); + msg:addString(disabledReason) + end + + msg:addByte(0x00) + + local type = convertType(offer.type) + + msg:addByte(type); + if type == GameStore.ConverType.SHOW_NONE then + msg:addString(offer.icons[1]) + elseif type == GameStore.ConverType.SHOW_MOUNT then + local mount = Mount(offer.id) + msg:addU16(mount:getClientId()) + elseif type == GameStore.ConverType.SHOW_ITEM then + msg:addU16(ItemType(offer.itemtype):getClientId()) + elseif type == GameStore.ConverType.SHOW_OUTFIT then + msg:addU16(player:getSex() == PLAYERSEX_FEMALE and offer.sexId.female or offer.sexId.male) + local outfit = player:getOutfit() + msg:addByte(outfit.lookHead) + msg:addByte(outfit.lookBody) + msg:addByte(outfit.lookLegs) + msg:addByte(outfit.lookFeet) + end + + msg:addByte(0) -- TryOn Type + msg:addU16(0) -- Collection + msg:addU16(0) -- Popularity Score + msg:addU32(0) -- State New Until + msg:addByte(0) -- User Configuration + msg:addU16(0) -- Products Capacity + end + + local banner = HomeBanners + msg:addByte(#banner.images) + for m, image in ipairs(banner.images) do + msg:addString(image) + msg:addByte(0x04) -- Banner Type (offer) + msg:addU32(0x00) -- Offer Id + msg:addByte(0) + msg:addByte(0) + end + + msg:addByte(banner.delay) -- Delay to swtich images + + msg:sendToPlayer(player) + +end + +function Player:openStore(serviceName) --exporting the method so other scripts can use to open store + openStore(self:getId()) + + --local serviceType = msg:getByte() + local category = GameStore.Categories and GameStore.Categories[1] or nil + + if serviceName and serviceName:lower() == "home" then + return sendHomePage(self:getId()) + end + + if serviceName and GameStore.getCategoryByName(serviceName) then + category = GameStore.getCategoryByName(serviceName) + end + + if category then + addPlayerEvent(sendShowStoreOffers, 50, playerId, category) + end +end + +-- Hireling Helpers +function HandleHirelingNameChange(playerId, offer, newHirelingName) + local player = Player(playerId); + + local cb = function(playerId, data, hireling) + local offer = data.offer + local newHirelingName = data.newHirelingName + local player = Player(playerId); + if not hireling then + return player:showInfoModal("Error","Your must select a hireling.") + end + + if hireling.active > 0 then + return player:showInfoModal("Error", "Your hireling must be inside his/her lamp.") + end + + if not player:removeCoinsBalance(offer.price) then + return player:showInfoModal("Error", "Transaction error") + end + local oldName = hireling.name + hireling.name = newHirelingName + local lamp = player:findHirelingLamp(hireling:getId()) + if lamp then + lamp:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, "This mysterious lamp summons your very own personal hireling.\nThis item cannot be traded.\nThis magic lamp is the home of " .. hireling:getName() .. ".") + end + GameStore.insertHistory(player:getAccountId(), GameStore.HistoryTypes.HISTORY_TYPE_NONE, offer.name .. ' ('.. oldName .. '->' .. newHirelingName ..')', (offer.price) * -1) + + player:showInfoModal('Info',string.format('%s has been renamed to %s', oldName, newHirelingName)) + end + + player:sendHirelingSelectionModal('Choose a Hireling', 'Select a hireling below', cb, {offer=offer, newHirelingName=newHirelingName}) +end + +function HandleHirelingSexChange(playerId, offer) + local player = Player(playerId); + + local cb = function(playerId, data, hireling) + local player = Player(playerId); + if not hireling then + return player:showInfoModal("Error","Your must select a hireling.") + end + + if hireling.active > 0 then + return player:showInfoModal("Error", "Your hireling must be inside his/her lamp.") + end + + if not player:removeCoinsBalance(data.offer.price) then + return player:showInfoModal("Error", "Transaction error") + end + + local changeTo,sexString,lookType + if hireling.sex == HIRELING_SEX.FEMALE then + changeTo = HIRELING_SEX.MALE + sexString = 'male' + lookType = HIRELING_OUTFIT_DEFAULT.male + else + changeTo = HIRELING_SEX.FEMALE + sexString = 'female' + lookType = HIRELING_OUTFIT_DEFAULT.female + end + + hireling.sex = changeTo + hireling.looktype = lookType + + GameStore.insertHistory(player:getAccountId(), GameStore.HistoryTypes.HISTORY_TYPE_NONE, offer.name .. ' ('.. hireling:getName() ..')', (offer.price) * -1) + + player:showInfoModal('Info',string.format('%s sex was changed to %s', hireling:getName(), sexString)) + end + + player:sendHirelingSelectionModal('Choose a Hireling', 'Select a hireling below', cb, {offer=offer}) +end diff --git a/data/modules/scripts/gamestore/readme.md b/data/modules/scripts/gamestore/readme.md new file mode 100644 index 00000000000..e179a1b8172 --- /dev/null +++ b/data/modules/scripts/gamestore/readme.md @@ -0,0 +1,119 @@ +## Module : Premium Shop - Game Store +--- + +> Notify! Please put the images in folder called "64". + +### Faq + +##### 1. How to make a category? +```lua +--- Method 1 --- +GameStore.Categories = { + { name = "mounts", + ... + }, + { name = "outfits", + ... + } +} +--- Method 2 --- +GameStore.Categories = { + mounts = { + name = "mounts" + }, + outfits = {....} +} +--- Method 3 --- +mounts = {....} +GameStore.Categories = { + mounts, + ... +} +``` + +##### 2. How to add offers to category +```lua +--- Method 1 --- +GameStore.Categories = { + mounts = { + offers = { + + } + } +} +--- Method 2 --- +mounts = { name = "mounts", icons = {"Category_Mounts.png"}} +mounts.offers = { + {name = "fafa", thingId = ....} +} +GameStore.Categories = { + mounts = { name = "mounts", + offers = { + {name = "fafa", thingId = ....} + } + } +} +``` + +### Category Options +| Method | Type | Usage | Default | +|-------------|-----------------------|------------------------------|-----------------------------| +| name* | string | the category name | nil | +| description | string | the category description | "" | +| state | GameStore.States(int) | the category highlight state | GameStore.States.STATE_NONE | +| icons* | table[string(s)] | the icons for the category | nil | +| offers(*) | table[offer(s)] | the category offers | nil | + +#### Example : +```lua +mounts = { + name = "Mounts", + description = "Have a mount and become an important-look person!", + state = GameStore.States.STATE_NEW, + icons = {"Category_Mounts.png"}, + offers = {....} +} +``` + +### Offer Options +| Method | Type | Usage | Default | +|----------------|---------------------------|------------------------------------------------------------------------|--------------------------------------| +| name* | string | the offer name | nil | +| description | string | the offer descrioption | "" | +| thingId* | int | the id of the choosed type ( itemId or mountId or outfitLookType, ....)| nil | +| type* | GameStore.OfferTypes(int) | the type of the offer, item or mount or outfit or ... | GameStore.OfferTypes.OFFER_TYPE_NONE | +| price* | int | the offer price | nil | +| state | GameStore.States(int) | the offer highlight state | GameStore.States.STATE_NONE | +| icons* | table[string(s)] | the icons for the category | nil | +| disabled | bool | dynamically disable the offer | false | +| disabledReason | string | reason for being disabled ( use when disabled is true ) | nil | + +#### Example : +```lua +mounts.offers = { + { name = "Titanica", + description = "Looking for nice mount? Titanica is the one you are looking for, she is beautiful, smart and running quickly.", + thingId = 4, -- here we use mount id. + type = GameStore.OfferTypes.OFFER_TYPE_MOUNT, + price = 500, + state = GameStore.States.STATE_SALE, + icons = {"Product_Titanica1", "Product_Titanica2"} + --[[Dynamicly used variables + disabled = (true|false), + disbabledReason = (string) + ]] + } +} +``` + +### Offer types and States. + +| OfferTypes | States | +|-------------------------|-------------| +| `OFFER_TYPE_ITEM` | `STATE_NEW` | +| `OFFER_TYPE_OUTFIT` | `STATE_SALE` | +| `OFFER_TYPE_OUTFIT_ADDON` | `STATE_TIMED` | +| `OFFER_TYPE_MOUNT` | | +| `OFFER_TYPE_NAMECHANGE` | | +| `OFFER_TYPE_SEXCHANGE` | | +| `OFFER_TYPE_PROMOTION` | | diff --git a/data/modules/scripts/hirelings/hireling_module.lua b/data/modules/scripts/hirelings/hireling_module.lua new file mode 100644 index 00000000000..bf734fe83a2 --- /dev/null +++ b/data/modules/scripts/hirelings/hireling_module.lua @@ -0,0 +1,59 @@ +HirelingModule = {} + +HirelingModule.Credits = { + Developer = 'Leonardo "Leu" Pereira (jlcvp)', + Version = "1.0", + Date = "30/04/2020 " +} + +HirelingModule.S_Packets= { SendOutfitWindow = 0xC8 } + +HirelingModule.C_Packets = { RequestChangeOutfit = 0xD2, ConfirmOutfitChange = 0xD3 } + +local function getOutfit(msg, version) + local outfitType = 0 + if(version >= 1220) then + outfitType = msg:getByte() + end + + local outfit = {} + outfit.lookType = msg:getU16() + outfit.lookHead = msg:getByte() + outfit.lookBody = msg:getByte() + outfit.lookLegs = msg:getByte() + outfit.lookFeet = msg:getByte() + outfit.lookAddons = msg:getByte() + + if outfitType == 0 then + outfit.lookMount = msg:getU16() + else + outfit.lookMount = 0x00 + msg:getU32() --discard this for some reason maybe it's the hireling id + end + return outfit +end + +local function parseChangeOutfit(player,msg) + local hireling = player:getHirelingChangingOutfit() + local outfit + local version = player:getClient().version + if not hireling then + player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + + -- deplete msg to avoid setting an hireling outfit to player + getOutfit(msg,version) + else + outfit = getOutfit(msg, version) + hireling:changeOutfit(outfit) + end +end + +function onRecvbyte(player, msg, byte) + if (byte == HirelingModule.C_Packets.ConfirmOutfitChange) then + if not player:isChangingHirelingOutfit() then + return + end + parseChangeOutfit(player, msg) + end +end diff --git a/data/modules/scripts/prey_system/assets.lua b/data/modules/scripts/prey_system/assets.lua new file mode 100644 index 00000000000..1715cb74d53 --- /dev/null +++ b/data/modules/scripts/prey_system/assets.lua @@ -0,0 +1,36 @@ +preyRaceIds = { + "1196", "262", "267", "268", "269", "270", "271", "314", "563", "738", "913", "112", "237", "238", "239", "240", "241", "242", + "243", "244", "245", "246", "261", "437", "697", "734", "735", "769", "770", "772", "779", "780", "781", "782", "783", + "784", "795", "859", "860", "861", "862", "1097", "1098", "1099", "1100", "1101", "1105", "111", "212", "218", "318", + "561", "562", "914", "915", "1307", "67", "326", "503", "524", "533", "680", "700", "701", "702", "706", "873", "879", + "882", "884", "885", "897", "1038", "1039", "1041", "1043", "1325", "1326", "1327", "1751", "35", "285", "288", "291", + "295", "296", "519", "523", "581", "586", "725", "727", "728", "729", "1019", "1134", "1135", "1197", "1198", "1619", + "1620", "1622", "34", "121", "317", "385", "386", "461", "617", "618", "643", "672", "673", "963", "1376", "1380", + "49", "236", "313", "456", "457", "458", "889", "890", "1000", "1116", "1121", "1563", "1569", "1670", "717", "1224", + "1235", "1260", "1264", "1265", "1266", "383", "1434", "1436", "1437", "1438", "1439", "1485", "1496", "1626", "1740", + "1741", "22", "55", "324", "334", "389", "391", "1161", "1162", "1163", "1314", "1320", "1820", "1821", "1822", "1841", + "1857", "9", "10", "11", "12", "47", "54", "57", "58", "72", "73", "77", "222", "223", "224", "225", "247", "248", "249", + "250", "253", "254", "255", "310", "322", "323", "331", "332", "333", "371", "372", "376", "521", "525", "526", "527", + "529", "578", "579", "583", "585", "587", "719", "776", "777", "867", "868", "922", "960", "961", "974", "1119", "1120", + "1145", "1146", "1147", "1413","1481","1482","1512", "1513", "1514", "1775", "1776", "1824", "1800", "1799", "1798", "2", + "4", "5", "6", "7", "8", "15", "23", "24", "25", "29", "50", "53", "59", "61", "62", "63", "64", "66", "69", "70", "71", + "76", "214", "215", "216", "277", "319", "328", "329", "377", "379", "392", "393", "463", "464", "540", "541", "614", + "737", "741", "745", "886", "888", "916", "917", "918", "920", "924", "925", "926", "1044", "1045", "1046", "1051", + "1052", "1053", "1109", "1321", "1322", "1394", "1412", "1486", "1488", "1503", "1504", "1505", "1506", "1507", "1508", + "1509", "1510", "1529", "1730", "1731", "1732", "1733", "1734", "1735", "510", "1142", "1143", "1144", "1549", "17", "51", + "80", "95", "103", "104", "108", "109", "292", "299", "330", "460", "518", "520", "570", "698", "739", "740", "869", "880", + "894", "978", "980", "1004", "1012", "1013", "1014", "1015", "1016", "1018", "1021", "1022", "1137", "1138", "1157", "1442", + "1443", "1653", "1654", "1655", "1659", "1663", "1664", "1665", "1666", "1668", "1669", "1671", "1721", "1722", "1723", "1728", + "1729", "1808", "1807", "1806", "1816", "1819", "3", "13", "14", "16", "21", "27", "31", "32", "41", "42", "52", "56", "60", + "74", "94", "105", "106", "110", "116", "117", "118", "122", "123", "125", "211", "260", "325", "327", "384", "387", "502", + "509", "516", "555", "556", "557", "559", "560", "630", "693", "720", "723", "730", "733", "750", "751", "752", "870", "872", + "877", "898", "981", "1118", "1139", "1174", "1395", "1548", "1570", "1742", "1855", "1856", "120", "221", "511", "679", "881", + "891", "919", "979", "982", "1042", "1141", "28", "81", "113", "114", "115", "119", "220", "258", "259", "290", "438", "439", + "616", "620", "623", "624", "625", "627", "655", "656", "694", "695", "1096", "1525", "1817", "1818", "19", "20", "265", "289", + "513", "514", "515", "584", "1054", "1056", "1658", "18", "33", "37", "48", "65", "68", "78", "99", "100", "101", "256", "257", + "281", "282", "283", "284", "286", "298", "321", "388", "446", "465", "483", "508", "512", "558", "580", "594", "595", "675", + "696", "704", "707", "708", "710", "711", "712", "958", "959", "962", "975", "976", "1040", "1055", "1148", "1415", "1646", + "1647", "1674", "1675", "1724", "1725", "1726", "1805", "26", "30", "36", "38", "39", "43", "44", "45", "79", "82", "83", "124", + "213", "219", "227", "228", "251", "621", "631", "632", "633", "641", "674", "691", "709", "731", "732", "778", "786", "787", + "788", "790", "791", "792", "796", "797", "801", "878", "899", "912", "1531", "1532", "1544", "1545", "1546", "1736", "1737" +} diff --git a/data/modules/scripts/prey_system/prey.lua b/data/modules/scripts/prey_system/prey.lua new file mode 100644 index 00000000000..785350f8c62 --- /dev/null +++ b/data/modules/scripts/prey_system/prey.lua @@ -0,0 +1,715 @@ +dofile('data/modules/scripts/prey_system/assets.lua') + +Prey = { + Credits = "System remake: Westwol ~ Packet logic: Cjaker ~ Formulas: slavidodo ~ Revision: Rick, Sameshima, RodrigoSilva93", + Version = "6.4", + LastUpdate = "12/02/2021", +} + +Prey.Difficulty = { + HARMLESS = 0, + TRIVIAL = 1, + EASY = 2, + MEDIUM = 3, + HARD = 4, + CHALLEGING = 5 +} + +CONST_PREY_SLOT_FIRST = 0 +CONST_PREY_SLOT_SECOND = 1 +CONST_PREY_SLOT_THIRD = 2 + +CONST_BONUS_DAMAGE_BOOST = 0 +CONST_BONUS_DAMAGE_REDUCTION = 1 +CONST_BONUS_XP_BONUS = 2 +CONST_BONUS_IMPROVED_LOOT = 3 + +Prey.Config = { + PreyTime = 7200, -- Seconds + StoreSlotStorage = 63253, + ListRerollPrice = 150, + BonusRerollPrice = 1, + SelectWithWildCardPrice = 5, +} + +Prey.S_Packets = { + ShowDialog = 0xED, + PreyRerollPrice = 0xE9, + PreyData = 0xE8, + PreyTimeLeft = 0xE7 +} + +Prey.StateTypes = { + LOCKED = 0, + INACTIVE = 1, + ACTIVE = 2, + SELECTION = 3, + SELECTION_CHANGE_MONSTER = 4, + SELECTION_WITH_WILDCARD = 6 +} + +Prey.UnlockTypes = { + PREMIUM_OR_STORE = 0, + STORE = 1, + NONE = 2 +} + +Prey.Actions = { + NEW_LIST = 0, + NEW_BONUS = 1, + SELECT = 2, + LIST_ALL_MONSTERS = 3, + SELECT_ALL_MONSTERS = 4, + TICK_LOCK = 5 +} + +Prey.C_Packets = { + RequestData = 0xED, + PreyAction = 0xEB +} + +Prey.Bonuses = { + [CONST_BONUS_DAMAGE_BOOST] = {7, 9, 11, 13, 15, 17, 19, 21, 23, 25}, + [CONST_BONUS_DAMAGE_REDUCTION] = {12, 14, 16, 18, 20, 22, 24, 26, 28, 30}, + [CONST_BONUS_XP_BONUS] = {13, 16, 19, 22, 25, 28, 31, 34, 37, 40}, + [CONST_BONUS_IMPROVED_LOOT] = {13, 16, 19, 22, 25, 28, 31, 34, 37, 40} +} + +Prey.MonsterList = { + "Azure Frog", "Coral Frog", "Crimson Frog", "Filth Toad", "Infernal Frog", "Orchid Frog", "Salamander", "Toad", + "Abyssal Calamary", "Blood Crab", "Crab", "Deathling Scout", "Deathling Spellsinger", "Deepling Brawler", + "Deepling Elite", "Deepling Guard", "Deepling Master Librarian", "Deepling Scout", "Deepling Spellsinger", + "Deepling Tyrant", "Deepling Warrior", "Deepling Worker", "Deepsea Blood Crab", "Manta Ray", "Quara Constrictor", + "Quara Constrictor Scout", "Quara Hydromancer", "Quara Hydromancer Scout", "Quara Mantassin", "Quara Mantassin Scout", + "Quara Pincher", "Quara Pincher Scout", "Quara Predator", "Quara Predator Scout", "Shark", "Berserker Chicken", + "Demon Parrot", "Marsh Stalker", "Penguin", "Terror Bird", "Biting Book", "Clay Guardian", "Damaged Worker Golem", + "Diamond Servant", "Enraged Crystal Golem", "Eternal Guardian", "Glooth Golem", "Golden Servant", "Ice Golem", + "Infected Weeper", "Iron Servant", "Lava Golem","Metal Gargoyle", "Orewalker", "Rotten Golem", "Rustheap Golem", + "Sandstone Scorpion", "Stone Devourer", "Stone Golem", "Walker", "War Golem", "Weeper", "Worker Golem", "Askarak Demon", + "Askarak Lord", "Askarak Prince", "Brachiodemon", "Dark Torturer", "Dawnfire Asura", "Demon", "Demon Outcast", + "Destroyer", "Diabolic Imp", "Fire Devil", "Floating Savant", "Frost Flower Asura", "Fury", "Gozzler", "Grimeleech", + "Hellfire Fighter", "Hellflayer", "Hellhound", "Hellspawn", "Infernal Demon", "Juggernaut", "Many Faces", + "Midnight Asura", "Nightfiend", "Plaguesmith", "Shaburak Demon", "Shaburak Lord", "Shaburak Prince", + "True Dawnfire Asura", "True Frost Flower Asura", "True Midnight Asura", "Vexclaw", "Dragon", "Dragon Hatchling", + "Dragon Lord", "Dragon Lord Hatchling", "Draken Abomination", "Draken Elite", "Draken Spellweaver", "Draken Warmaster", + "Elder Wyrm", "Frost Dragon", "Frost Dragon Hatchling", "Ghastly Dragon", "Hydra", "Wyrm", "Cliff Strider", + "Earth Elemental", "Energy Elemental", "Fire Elemental", "High Voltage Elemental", "Ironblight", + "Knowledge Elemental", "Lava Lurker", "Massive Earth Elemental", "Massive Fire Elemental", "Massive Water Elemental", + "Ravenous Lava Lurker", "Turbulent Elemental", "Water Elemental", "Breach Brood", "Courage Leech", "Dread Intruder", + "Instable Breach Brood", "Instable Sparkion", "Reality Reaver", "Sparkion", "Stabilizing Dread Intruder", + "Stabilizing Reality Reaver", "Yielothax", "Arctic Faun", "Boogy", "Dark Faun", "Dryad", "Faun", "Nymph", "Percht", + "Pixie", "Pooka", "Schiach", "Swan Maiden", "Twisted Pooka", "Behemoth", "Cyclops", "Cyclops Drone", + "Cyclops Smith", "Frost Giant", "Frost Giantess", "Ogre Brute", "Ogre Rowdy", "Ogre Ruffian", "Ogre Sage", + "Ogre Savage", "Ogre Shaman", "Orclops Doomhauler", "Orclops Ravager", "Acolyte of the Cult", "Adept of the Cult", + "Adventurer", "Amazon", "Assassin", "Bandit", "Barbarian Bloodwalker", "Barbarian Brutetamer", "Barbarian Headsplitter", + "Barbarian Skullhunter", "Black Sphinx Acolyte", "Blood Hand", "Blood Priest", "Burning Gladiator", "Cobra Assassin", + "Cobra Scout", "Cobra Vizier", "Crazed Beggar", "Crypt Defiler", "Cult Believer", "Cult Enforcer", "Cult Scholar", + "Dark Apprentice", "Dark Magician", "Dark Monk", "Enlightened of the Cult", "Feverish Citizen", "Gang Member", + "Gladiator", "Glooth Bandit", "Glooth Brigand", "Goldhanded Cultist", "Grave Robber", + "Hero", "Hunter", "Ice Witch", "Infernalist", "Mad Scientist", "Misguided Thief", "Monk", + "Mutated Human", "Necromancer", "Nomad", "Nomad Female", "Novice of the Cult", "Pirate Buccaneer", "Pirate Corsair", + "Pirate Cutthroat", "Pirate Marauder", "Poacher", "Priestess", "Priestess of the Wild Sun", "Renegade Knight", + "Shadow Pupil", "Smuggler", "Stalker", "Valkyrie", "Vicious Squire", "Vile Grandmaster", "Warlock", "Wild Warrior", + "Witch", "Barkless Devotee", "Barkless Fanatic", "Broken Shaper", "Chakoya Toolshaper", "Chakoya Tribewarden", + "Chakoya Windcaller", "Corym Charlatan", "Corym Skirmisher", "Corym Vanguard", "Crazed Summer Rearguard", + "Crazed Summer Vanguard", "Crazed Winter Rearguard", "Crazed Winter Vanguard", "Dwarf", "Dwarf Geomancer", + "Dwarf Guard", "Dwarf Soldier", "Dworc Fleshhunter", "Dworc Venomsniper", "Dworc Voodoomaster", "Elf", + "Elf Arcanist", "Elf Scout", "Enslaved Dwarf", "Execowtioner", "Firestarter", "Frost Troll", "Furious Troll", + "Goblin", "Goblin Assassin", "Goblin Leader", "Goblin Scavenger", "Insane Siren", "Island Troll", + "Little Corym Charlatan", "Lost Basher", "Lost Berserker", "Lost Exile", "Lost Husher", "Lost Thrower", "Minotaur", + "Minotaur Amazon", "Minotaur Archer", "Minotaur Cult Follower", "Minotaur Cult Prophet", "Minotaur Cult Zealot", + "Minotaur Guard", "Minotaur Hunter", "Minotaur Invader", "Minotaur Mage", "Mooh'Tah Warrior", "Moohtant", "Orc", + "Orc Berserker", "Orc Cult Fanatic", "Orc Cult Inquisitor", "Orc Cult Minion", "Orc Cult Priest", "Orc Cultist", + "Orc Leader", "Orc Marauder", "Orc Rider", "Orc Shaman", "Orc Spearman", "Orc Warlord", "Orc Warrior", + "Pirat Cutthroat", "Pirat Scoundrel", "Shaper Matriarch", "Soul-Broken Harbinger", "Swamp Troll", "Troll", + "Troll Champion", "Troll Guard", "Troll", "Troll Legionnaire", "Twisted Shaper", "Worm Priestess", "Werebadger", + "Werebear", "Wereboar", "Werefox", "Werehyaena", "Werehyaena Shaman", "Werelion", "Werelioness", "Werewolf", + "Animated Feather", "Arachnophobica", "Armadile", "Blue Djinn", "Bog Raider", "Bonelord", "Brain Squid", + "Choking Fear", "Crypt Warden", "Crystal Spider", "Crystal Wolf", "Crystalcrusher", "Cursed Book", "Efreet", + "Elder Bonelord", "Energetic Book", "Energuardian of Tales", "Enfeebled Silencer", + "Feral Sphinx", "Feversleep", "Flying Book", "Forest Fury", "Frazzlemaw", "Gargoyle", "Gazer", "Gryphon", + "Guardian of Tales", "Guzzlemaw", "Icecold Book", "Lamassu", "Lumbering Carnivor", "Manticore", "Marid", "Medusa", + "Menacing Carnivor", "Midnight Panther", "Nightmare", "Nightmare Scion", "Nightstalker", "Phantasm", "Rage Squid", + "Retching Horror", "Rorc", "Shock Head", "Sight of Surrender", "Silencer", "Sphinx", "Spiky Carnivor", + "Squid Warden", "Terrorsleep", "Thanatursus", "Thornfire Wolf", "Weakened Frazzlemaw", "Badger", "Bat", "Bear", + "Boar", "Cave Rat", "Clomp", "Doom Deer", "Elephant", "Evil Sheep", "Evil Sheep Lord", "Exotic Bat", "Fox", + "Gloom Wolf", "Gnarlhound", "Hot Dog", "Killer Rabbit", "Kongra", "Lion", "Mammoth", "Merlkin", "Mole", + "Mutated Bat", "Mutated Rat", "Mutated Tiger", "Noble Lion", "Panda", "Polar Bear", "Rat", "Roaring Lion", + "Sibang", "Skunk", "Starving Wolf", "Stone Rhino", "Tiger", "Vulcongra", "War Wolf", "Water Buffalo", + "White Lion", "Winter Wolf", "Wolf", "Branchy Crawler", "Carniphila", "Cloak Of Terror", "Glooth Anemone", + "Haunted Treeling", "Hideous Fungus", "Humongous Fungus", "Leaf Golem", "Omnivora", "Spit Nettle", "Swampling", + "Wilting Leaf Golem", "Adult Goanna", "Cobra", "Crocodile", "Killer Caiman", "Lizard Chosen", + "Lizard Dragon Priest", "Lizard High Guard", "Lizard Legionnaire", "Lizard Magistratus", "Lizard Noble", + "Lizard Sentinel", "Lizard Snakecharmer", "Lizard Templar", "Lizard Zaogun", "Sea Serpent", "Seacrest Serpent", + "Serpent Spawn", "Snake", "Stampor", "Stonerefiner", "Thornback Tortoise", "Tortoise", "Wyvern", "Young Goanna", + "Young Sea Serpent", "Acid Blob", "Death Blob", "Defiler", "Devourer", "Glooth Blob", "Ink Blob", "Mercury Blob", + "Midnight Spawn", "Slime", "Son of Verminor", "Squidgy Slime", "Banshee", "Betrayed Wraith", "Blightwalker", + "Blood Beast", "Bonebeast", "Bony Sea Devil", "Braindeath", "Burster Spectre", "Capricious Phantom", + "Crypt Shambler", "Cursed Prospector", "Death Priest", "Demon Skeleton", "Distorted Phantom", + "Druid's Apparition", "Elder Mummy", "Evil Prospector", "Falcon Knight", "Falcon Paladin", "Flimsy Lost Soul", + "Freakish Lost Soul", "Gazer Spectre", "Ghost", "Ghost Wolf", "Ghoul", "Ghoulish Hyaena", "Grave Guard", + "Gravedigger", "Grim Reaper", "Hand of Cursed Fate", "Honour Guard", "Infernal Phantom", "Knight's Apparition", + "Lich", "Lost Soul", "Mean Lost Soul", "Mould Phantom", "Mummy", "Paladin's Apparition", "Pirate Ghost", + "Pirate Skeleton", "Putrid Mummy", "Ripper Spectre", "Rot Elemental", "Skeleton", "Skeleton Elite Warrior", + "Skeleton Warrior", "Sorcerer's Apparition", "Souleater", "Spectre", "Tarnished Spirit", "Tomb Servant", + "Undead Dragon", "Undead Elite Gladiator", "Undead Gladiator", "Vampire", "Vampire Bride", "Vampire Pig", + "Vampire Viscount", "Vibrant Phantom", "Vicious Manbat", "White Shade", "Zombie", "Ancient Scarab", + "Brimstone Bug", "Bug", "Carrion Worm", "Cave Devourer", "Centipede", "Crawler", "Deepworm", "Diremaw", + "Drillworm", "Emerald Damselfly", "Exotic Cave Spider", "Giant Spider", "Hibernal Moth", "Hive Overseer", + "Insect Swarm", "Insectoid Scout", "Insectoid Worker", "Kollos", "Lacewing Moth", "Ladybug", "Lancer Beetle", + "Larva", "Poison Spider", "Rotworm", "Sacred Spider", "Sandcrawler", "Scarab", "Scorpion", "Spider", "Spidris", + "Spidris Elite", "Spitter", "Swarmer", "Tarantula", "Terramite", "Tunnel Tyrant", "Wailing Widow", "Wasp", + "Waspoid", "Wiggler", "Terrified Elephant" +} + +-- Communication functions +function Player.sendResource(self, resourceType, value) + local typeByte = 0 + if resourceType == "bank" then + typeByte = 0x00 + elseif resourceType == "inventory" then + typeByte = 0x01 + elseif resourceType == "prey" then + typeByte = 0x0A + end + local msg = NetworkMessage() + msg:addByte(0xEE) + msg:addByte(typeByte) + msg:addU64(value) + msg:sendToPlayer(self) +end + +function Player.sendErrorDialog(self, error) + local msg = NetworkMessage() + msg:addByte(Prey.S_Packets.ShowDialog) + msg:addByte(0x15) + msg:addString(error) + msg:sendToPlayer(self) +end + +-- Core functions +function Player.setRandomBonusValue(self, slot, bonus, typeChange) + local type = self:getPreyBonusType(slot) + local bonusValue = math.random(1, 10) + local starUP = math.random(1, 3) + local value = Prey.Bonuses[type][bonusValue] + local bonusGrade = self:getPreyBonusGrade(slot) + + if bonus then + if typeChange then + self:setPreyBonusGrade(slot, bonusValue) + self:setPreyBonusValue(slot, value) + else + local upgradeStar = bonusGrade + starUP + if upgradeStar >= 10 then + upgradeStar = 10 + end + local newBonus = Prey.Bonuses[type][upgradeStar] + self:setPreyBonusGrade(slot, upgradeStar) + self:setPreyBonusValue(slot, newBonus) + end + end +end + +function Player.createMonsterList(self) + -- Do not allow repeated monsters + local repeatedList = {} + for slot = CONST_PREY_SLOT_FIRST, CONST_PREY_SLOT_THIRD do + if (self:getPreyCurrentMonster(slot) ~= '') then + repeatedList[#repeatedList + 1] = self:getPreyCurrentMonster(slot) + end + if (self:getPreyMonsterList(slot) ~= '') then + local currentList = self:getPreyMonsterList(slot):split(";") + for i = 1, #currentList do + repeatedList[#repeatedList + 1] = currentList[i] + end + end + end + -- Generating monsterList + local monsters = {} + local counters = { + Trivial = 0, + Easy = 0, + Medium = 0, + Hard = 0, + Challeging = 0 + } + while (#monsters ~= 9) do + local randomMonster = Prey.MonsterList[math.random(#Prey.MonsterList)] + local difficulty = getMonsterDifficulty(randomMonster) + -- Verify that monster actually exists + if MonsterType(randomMonster) and not table.contains(monsters, randomMonster) + and not table.contains(repeatedList, randomMonster) then + if difficulty == Prey.Difficulty.TRIVIAL and counters.Trivial < getMaxMonster(self, Prey.Difficulty.TRIVIAL) then + monsters[#monsters + 1] = randomMonster + counters.Trivial = counters.Trivial + 1 + elseif difficulty == Prey.Difficulty.EASY and counters.Easy < getMaxMonster(self, Prey.Difficulty.EASY) then + monsters[#monsters + 1] = randomMonster + counters.Easy = counters.Easy + 1 + elseif difficulty == Prey.Difficulty.MEDIUM and counters.Medium < getMaxMonster(self, Prey.Difficulty.MEDIUM) then + monsters[#monsters + 1] = randomMonster + counters.Medium = counters.Medium + 1 + elseif difficulty == Prey.Difficulty.HARD and counters.Hard < getMaxMonster(self, Prey.Difficulty.HARD) then + monsters[#monsters + 1] = randomMonster + counters.Hard = counters.Hard + 1 + elseif difficulty == Prey.Difficulty.CHALLEGING and counters.Challeging < getMaxMonster(self, Prey.Difficulty.CHALLEGING) then + monsters[#monsters + 1] = randomMonster + counters.Challeging = counters.Challeging + 1 + end + end + end + return table.concat(monsters, ";") +end + +function Player.resetPreySlot(self, slot, from) + self:setPreyMonsterList(slot, self:createMonsterList()) + self:setPreyCurrentMonster(slot, "") + self:setPreyState(slot, from) + return self:sendPreyData(slot) +end + +function Player.getMinutesUntilFreeReroll(self, slot) + local currentTime = os.time() + if (self:getPreyNextUse(slot) <= currentTime) then + return 0 + end + + return math.floor((self:getPreyNextUse(slot) - currentTime)) +end + +function Player.getRerollPrice(self) + return (self:getLevel() * Prey.Config.ListRerollPrice) +end + +function getNameByRace(race) + local mtype = MonsterType(race) + if mtype then + return mtype:getName() + end +end + +function Player.getMonsterList(self) + local repeatedList = {} + local sortList = {} + local monsterList = {} + + for slot = CONST_PREY_SLOT_FIRST, CONST_PREY_SLOT_THIRD do + if (self:getPreyCurrentMonster(slot) ~= '') then + repeatedList[#repeatedList + 1] = self:getPreyCurrentMonster(slot) + end + if (self:getPreyMonsterList(slot) ~= '') then + local currentList = self:getPreyMonsterList(slot):split(";") + for i = 1, #currentList do + repeatedList[#repeatedList + 1] = currentList[i] + end + end + end + + -- Insert the monstersId + for i = 1, #preyRaceIds do + table.insert(sortList, preyRaceIds[i]) + end + + -- Do not allow repeated monsters + for k, v in pairs(sortList) do + if not table.contains(repeatedList, getNameByRace(tonumber(v))) then + table.insert(monsterList, v) + end + end + + return monsterList +end + +function Player.setAutomaticBonus(self, slot) + local monster = self:getPreyCurrentMonster(slot) + + -- Automatic Bonus Reroll + if self:getPreyTick(slot) == 1 and self:getPreyBonusRerolls() >= 1 then + self:setPreyBonusType(slot, self:getDiffBonus(slot)) + self:setRandomBonusValue(slot, true, true) + self:setPreyBonusRerolls(self:getPreyBonusRerolls() - 1) + self:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("Your %s's prey bonus was automatically rolled.", monster:lower())) + self:setPreyTimeLeft(slot, Prey.Config.PreyTime) + + -- Lock Prey + elseif self:getPreyTick(slot) == 2 and self:getPreyBonusRerolls() >= 5 then + self:setPreyBonusRerolls(self:getPreyBonusRerolls() - 5) + self:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("Your %s's prey time was automatically renewed.", monster:lower())) + self:setPreyTimeLeft(slot, Prey.Config.PreyTime) + else + self:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("Your %s's prey has expired because you don't have enough prey wildcards.", monster:lower())) + self:setPreyCurrentMonster(slot, "") + self:setPreyTick(slot, 0) + end +end + +function onRecvbyte(player, msg, byte) + if (byte == Prey.C_Packets.RequestData) then + player:sendPreyData(CONST_PREY_SLOT_FIRST) + player:sendPreyData(CONST_PREY_SLOT_SECOND) + player:sendPreyData(CONST_PREY_SLOT_THIRD) + elseif (byte == Prey.C_Packets.PreyAction) then + player:preyAction(msg) + end +end + +function Player.preyAction(self, msg) + + local slot = msg:getByte() + local action = msg:getByte() + + if not slot then + return self:sendErrorDialog("Sorry, there was an issue, please relog-in.") + end + + -- Verify whether the slot is unlocked + if (self:getPreyUnlocked(slot) ~= 2) then + return self:sendErrorDialog("Sorry, you don't have this slot unlocked yet.") + end + + -- Listreroll + if (action == Prey.Actions.NEW_LIST) then + + -- Verifying state + if (self:getPreyState(slot) ~= Prey.StateTypes.ACTIVE and self:getPreyState(slot) ~= Prey.StateTypes.SELECTION + and self:getPreyState(slot) ~= Prey.StateTypes.SELECTION_CHANGE_MONSTER) + and self:getPreyState(slot) ~= Prey.StateTypes.INACTIVE then + return self:sendErrorDialog("This is slot is not even active.") + end + + -- If free reroll is available + if (self:getMinutesUntilFreeReroll(slot) == 0) then + self:setPreyNextUse(slot, os.time() + 20 * 60 * 60) + elseif (not self:removeMoneyNpc(self:getRerollPrice())) then + return self:sendErrorDialog("You do not have enough money to perform this action.") + end + + self:setPreyCurrentMonster(slot, "") + self:setPreyMonsterList(slot, self:createMonsterList()) + self:setPreyState(slot, Prey.StateTypes.SELECTION_CHANGE_MONSTER) + + -- Listreroll with wildcards + elseif (action == Prey.Actions.LIST_ALL_MONSTERS) then + + -- Removing bonus rerolls + self:setPreyBonusRerolls(self:getPreyBonusRerolls() - 5) + + self:setPreyCurrentMonster(slot, "") + self:setPreyMonsterList(slot, "") + self:setPreyState(slot, Prey.StateTypes.SELECTION_WITH_WILDCARD) + + -- Select monster from the list + elseif (action == Prey.Actions.SELECT_ALL_MONSTERS) then + local race = msg:getU16() + local race = getNameByRace(race) + + -- Converts RaceID to String + self:setPreyCurrentMonster(slot, race) + + self:setPreyState(slot, Prey.StateTypes.ACTIVE) + self:setPreyMonsterList(slot, "") + self:setPreyTimeLeft(slot, Prey.Config.PreyTime) + + -- Bonus reroll + elseif (action == Prey.Actions.NEW_BONUS) then + + -- Verifying state + if (self:getPreyState(slot) ~= Prey.StateTypes.ACTIVE) then + return self:sendErrorDialog("This is slot is not even active.") + end + + if (self:getPreyBonusRerolls() < 1) then + return self:sendErrorDialog("You don't have any bonus rerolls.") + end + + -- Removing bonus rerolls + self:setPreyBonusRerolls(self:getPreyBonusRerolls() - 1) + + -- Calculating new bonus + local oldType = self:getPreyBonusType(slot) + self:setPreyBonusType(slot, math.random(CONST_BONUS_DAMAGE_BOOST, CONST_BONUS_IMPROVED_LOOT)) + self:setRandomBonusValue(slot, true, false) + self:setPreyTimeLeft(slot, Prey.Config.PreyTime) + + -- Select monster from list + elseif (action == Prey.Actions.SELECT) then + + local selectedMonster = msg:getByte() + local monsterList = self:getPreyMonsterList(slot):split(";") + + -- Verify if the monster exists. + local monster = MonsterType(monsterList[selectedMonster + 1]) + if not monster then + return self:sendPreyData(slot) + end + + -- Verifying slot state + if (self:getPreyState(slot) ~= Prey.StateTypes.SELECTION + and self:getPreyState(slot) ~= Prey.StateTypes.SELECTION_CHANGE_MONSTER) then + return self:sendErrorDialog("This slot can't select monsters.") + end + + -- Proceeding to prey monster selection + self:selectPreyMonster(slot, monsterList[selectedMonster + 1]) + + -- Automatic Reroll/Lock + elseif (action == Prey.Actions.TICK_LOCK) then + + local button = msg:getByte() + if button == 1 then + self:setPreyTick(slot, 1) + elseif button == 2 then + self:setPreyTick(slot, 2) + else + self:setPreyTick(slot, 0) + end + end + + -- Perfom slot update + return self:sendPreyData(slot) +end + +function Player.selectPreyMonster(self, slot, monster) + + -- Verify if the monster exists. + local monster = MonsterType(monster) + if not monster then + return self:sendPreyData(slot) + end + + local msg = NetworkMessage() + + -- Only first/expired selection list gets new prey bonus + if (self:getPreyState(slot) == Prey.StateTypes.SELECTION) then + -- Generating random prey type + self:setPreyBonusType(slot, math.random(CONST_BONUS_DAMAGE_BOOST, CONST_BONUS_IMPROVED_LOOT)) + -- Generating random bonus stats + self:setRandomBonusValue(slot, true, true) + elseif (self:getPreyBonusGrade(slot) == 0) then + -- Generating random prey type + self:setPreyBonusType(slot, math.random(CONST_BONUS_DAMAGE_BOOST, CONST_BONUS_IMPROVED_LOOT)) + -- Generating random bonus stats + self:setRandomBonusValue(slot, true, true) + end + + -- Setting current monster + self:setPreyCurrentMonster(slot, monster:getName()) + -- Setting preySlot state + self:setPreyState(slot, Prey.StateTypes.ACTIVE) + -- Cleaning up monsterList + self:setPreyMonsterList(slot, "") + -- Time left + self:setPreyTimeLeft(slot, Prey.Config.PreyTime) +end + +function Player.sendPreyData(self, slot) + -- Unlock First Slot + if self:getPreyState(CONST_PREY_SLOT_FIRST) == 0 then + self:setPreyUnlocked(CONST_PREY_SLOT_FIRST, 2) + self:setPreyState(CONST_PREY_SLOT_FIRST, 1) + end + + -- Unlock/lock second slot (premium status) + if self:isPremium() then + if self:getPreyState(CONST_PREY_SLOT_SECOND) == 0 then + self:setPreyUnlocked(CONST_PREY_SLOT_SECOND, 2) + self:setPreyState(CONST_PREY_SLOT_SECOND, 1) + end + else + self:setPreyUnlocked(CONST_PREY_SLOT_SECOND, 0) + self:setPreyState(CONST_PREY_SLOT_SECOND, 0) + end + + -- Unlock store slot + if self:getPreyState(CONST_PREY_SLOT_THIRD) == 0 then + if self:getStorageValue(Prey.Config.StoreSlotStorage) == 1 then + self:setPreyUnlocked(CONST_PREY_SLOT_THIRD, 2) + self:setPreyState(CONST_PREY_SLOT_THIRD, 1) + else + self:setPreyUnlocked(CONST_PREY_SLOT_THIRD, 1) + self:setPreyState(CONST_PREY_SLOT_THIRD, 0) + end + end + + local slotState = self:getPreyState(slot) + local tickState = self:getPreyTick(slot) + + local msg = NetworkMessage() + msg:addByte(Prey.S_Packets.PreyData) -- packet header + + if slotState == Prey.StateTypes.SELECTION_CHANGE_MONSTER then + msg:addByte(slot) -- slot number + msg:addByte(slotState) + msg:addByte(self:getPreyBonusType(slot)) + msg:addU16(self:getPreyBonusValue(slot)) + msg:addByte(self:getPreyBonusGrade(slot)) + + local monsterList = self:getPreyMonsterList(slot):split(";") + msg:addByte(#monsterList) + for i = 1, #monsterList do + local monster = MonsterType(monsterList[i]) + if monster then + msg:addString(monster:getName()) + msg:addU16(monster:getOutfit().lookType or 21) + msg:addByte(monster:getOutfit().lookHead or 0x00) + msg:addByte(monster:getOutfit().lookBody or 0x00) + msg:addByte(monster:getOutfit().lookLegs or 0x00) + msg:addByte(monster:getOutfit().lookFeet or 0x00) + msg:addByte(monster:getOutfit().lookAddons or 0x00) + else + return self:resetPreySlot(slot, Prey.StateTypes.SELECTION_CHANGE_MONSTER) + end + end + + elseif slotState == Prey.StateTypes.SELECTION then + msg:addByte(slot) + msg:addByte(slotState) + + local preyMonsterList = self:getPreyMonsterList(slot) + if preyMonsterList == '' then + self:setPreyMonsterList(slot, self:createMonsterList()) + return self:sendPreyData(slot) + end + + local monsterList = preyMonsterList:split(";") + msg:addByte(#monsterList) + for i = 1, #monsterList do + local monster = MonsterType(monsterList[i]) + if monster then + msg:addString(monster:getName()) + msg:addU16(monster:getOutfit().lookType or 21) + msg:addByte(monster:getOutfit().lookHead or 0x00) + msg:addByte(monster:getOutfit().lookBody or 0x00) + msg:addByte(monster:getOutfit().lookLegs or 0x00) + msg:addByte(monster:getOutfit().lookFeet or 0x00) + msg:addByte(monster:getOutfit().lookAddons or 0x00) + else + return self:resetPreySlot(slot, Prey.StateTypes.SELECTION) + end + end + + elseif slotState == Prey.StateTypes.ACTIVE then + msg:addByte(slot) + msg:addByte(slotState) + local monster = MonsterType(self:getPreyCurrentMonster(slot)) + if monster and self:getPreyTimeLeft(slot) > 0 then + msg:addString(monster:getName()) + msg:addU16(monster:getOutfit().lookType or 21) + msg:addByte(monster:getOutfit().lookHead or 0x00) + msg:addByte(monster:getOutfit().lookBody or 0x00) + msg:addByte(monster:getOutfit().lookLegs or 0x00) + msg:addByte(monster:getOutfit().lookFeet or 0x00) + msg:addByte(monster:getOutfit().lookAddons or 0x00) + msg:addByte(self:getPreyBonusType(slot)) + msg:addU16(self:getPreyBonusValue(slot)) + msg:addByte(self:getPreyBonusGrade(slot)) + msg:addU16(self:getPreyTimeLeft(slot)) + else + return self:resetPreySlot(slot, Prey.StateTypes.SELECTION) + end + + elseif slotState == Prey.StateTypes.INACTIVE then + msg:addByte(slot) -- slot number + msg:addByte(slotState) -- slot state + self:setRandomBonusValue(slot, true, true) + + elseif slotState == Prey.StateTypes.LOCKED then + msg:addByte(slot) + msg:addByte(slotState) + msg:addByte(self:getPreyUnlocked(slot)) + + elseif slotState == Prey.StateTypes.SELECTION_WITH_WILDCARD then + local raceList = self:getMonsterList() + + msg:addByte(slot) -- slot number + msg:addByte(slotState) -- slot state + + -- Check if has any bonus + if self:getPreyTimeLeft(slot) <= 0 then + self:setRandomBonusValue(slot, true, true) + end + + msg:addByte(self:getPreyBonusType(slot)) -- bonus type + msg:addU16(self:getPreyBonusValue(slot)) -- bonus value + msg:addByte(self:getPreyBonusGrade(slot)) -- bonus grade + msg:addU16(#raceList) -- monsters count + + for i = 1, #raceList do + msg:addU16(raceList[i]) -- raceID + end + end + + -- Next free reroll + msg:addU32(self:getMinutesUntilFreeReroll(slot)) + + -- Automatic Reroll/Lock Prey + msg:addByte(tickState) + + -- send prey message + msg:sendToPlayer(self) + + -- close emb window + self:closeImbuementWindow() + + -- Send resources + self:sendResource("prey", self:getPreyBonusRerolls()) + self:sendResource("bank", self:getBankBalance()) + self:sendResource("inventory", self:getMoney()) + + -- Send reroll price + self:sendPreyRerollPrice() + +end + +function Player:sendPreyRerollPrice() + local msg = NetworkMessage() + + msg:addByte(Prey.S_Packets.PreyRerollPrice) + msg:addU32(self:getRerollPrice()) + msg:addByte(Prey.Config.BonusRerollPrice) -- wildcards + msg:addByte(Prey.Config.SelectWithWildCardPrice) -- select directly + + -- Feature unavailable + msg:addU32(0) + msg:addU32(0) + msg:addByte(0) + msg:addByte(0) + + msg:sendToPlayer(self) +end + +function getMonsterDifficulty(monster) + local stars + if MonsterType(monster) == nil or MonsterType(monster):experience() == 0 then + return 0 + else + stars = MonsterType(monster):BestiaryStars() + end + return stars +end + +function getMaxMonster(self, tier) + local level = self:getLevel() + + if(tier == Prey.Difficulty.HARMLESS) then return 0 end + + if level >=8 and level <= 100 then + if tier == Prey.Difficulty.TRIVIAL then return 1 + elseif tier == Prey.Difficulty.EASY then return 4 + elseif tier == Prey.Difficulty.MEDIUM then return 4 + elseif tier == Prey.Difficulty.HARD then return 4 + elseif tier == Prey.Difficulty.CHALLEGING then return 1 end + elseif level >= 101 and level <= 250 then + if tier == Prey.Difficulty.TRIVIAL then return 1 + elseif tier == Prey.Difficulty.EASY then return 3 + elseif tier == Prey.Difficulty.MEDIUM then return 5 + elseif tier == Prey.Difficulty.HARD then return 4 + elseif tier == Prey.Difficulty.CHALLEGING then return 1 end + else + if tier == Prey.Difficulty.TRIVIAL then return 1 + elseif tier == Prey.Difficulty.EASY then return 3 + elseif tier == Prey.Difficulty.MEDIUM then return 4 + elseif tier == Prey.Difficulty.HARD then return 5 + elseif tier == Prey.Difficulty.CHALLEGING then return 1 end + end +end diff --git a/data/modules/scripts/questtrack/questtrack.lua b/data/modules/scripts/questtrack/questtrack.lua new file mode 100644 index 00000000000..9f26efb4e33 --- /dev/null +++ b/data/modules/scripts/questtrack/questtrack.lua @@ -0,0 +1,10 @@ +function onRecvbyte(player, msg, byte) + if byte == 0xD0 then + local quests = {} + local missions = msg:getByte() + for i = 1, missions do + quests[#quests + 1] = msg:getU16() + end + player:resetTrackedMissions(quests) + end +end diff --git a/data/monster/amphibics/azure_frog.lua b/data/monster/amphibics/azure_frog.lua new file mode 100644 index 00000000000..1ffb0366fb5 --- /dev/null +++ b/data/monster/amphibics/azure_frog.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Azure Frog") +local monster = {} + +monster.description = "an azure frog" +monster.experience = 20 +monster.outfit = { + lookType = 226, + lookHead = 69, + lookBody = 66, + lookLegs = 69, + lookFeet = 66, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 268 +monster.Bestiary = { + class = "Amphibic", + race = BESTY_RACE_AMPHIBIC, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Meriana, Laguna Islands, and other Shattered Isles." + } + +monster.health = 60 +monster.maxHealth = 60 +monster.race = "blood" +monster.corpse = 6079 +monster.speed = 320 +monster.manaCost = 305 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ribbit! Ribbit!", yell = false}, + {text = "Ribbit!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 74230, maxCount = 10}, + {name = "worm", chance = 9240} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -24, effect = CONST_ME_DRAWBLOOD} +} + +monster.defenses = { + defense = 5, + armor = 8 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/amphibics/bog_frog.lua b/data/monster/amphibics/bog_frog.lua new file mode 100644 index 00000000000..47925c85266 --- /dev/null +++ b/data/monster/amphibics/bog_frog.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Bog Frog") +local monster = {} + +monster.description = "a bog frog" +monster.experience = 0 +monster.outfit = { + lookType = 412, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 738 +monster.Bestiary = { + class = "Amphibic", + race = BESTY_RACE_AMPHIBIC, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Shadowthorn in the bog god's temple, Drefia, around Lake Equivocolao when it's dirty." + } + +monster.health = 25 +monster.maxHealth = 25 +monster.race = "blood" +monster.corpse = 6079 +monster.speed = 320 +monster.manaCost = 305 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 25, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ribbit! Ribbit!", yell = false}, + {text = "Ribbit!", yell = false} +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/amphibics/coral_frog.lua b/data/monster/amphibics/coral_frog.lua new file mode 100644 index 00000000000..ad52ff78e27 --- /dev/null +++ b/data/monster/amphibics/coral_frog.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Coral Frog") +local monster = {} + +monster.description = "a coral frog" +monster.experience = 20 +monster.outfit = { + lookType = 226, + lookHead = 114, + lookBody = 98, + lookLegs = 97, + lookFeet = 114, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 269 +monster.Bestiary = { + class = "Amphibic", + race = BESTY_RACE_AMPHIBIC, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Meriana, Laguna Islands, and other Shattered Isles." + } + +monster.health = 60 +monster.maxHealth = 60 +monster.race = "blood" +monster.corpse = 6079 +monster.speed = 320 +monster.manaCost = 305 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ribbit!", yell = false}, + {text = "Ribbit! Ribbit!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 75590, maxCount = 10}, + {name = "worm", chance = 11310} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -24, effect = CONST_ME_DRAWBLOOD} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/amphibics/crimson_frog.lua b/data/monster/amphibics/crimson_frog.lua new file mode 100644 index 00000000000..4e4580555be --- /dev/null +++ b/data/monster/amphibics/crimson_frog.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Crimson Frog") +local monster = {} + +monster.description = "a crimson frog" +monster.experience = 20 +monster.outfit = { + lookType = 226, + lookHead = 94, + lookBody = 78, + lookLegs = 94, + lookFeet = 78, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 270 +monster.Bestiary = { + class = "Amphibic", + race = BESTY_RACE_AMPHIBIC, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Meriana, Laguna Islands, and other Shattered Isles." + } + +monster.health = 60 +monster.maxHealth = 60 +monster.race = "blood" +monster.corpse = 6079 +monster.speed = 320 +monster.manaCost = 305 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ribbit!", yell = false}, + {text = "Ribbit! Ribbit!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 76000, maxCount = 11}, + {name = "worm", chance = 10000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -24, effect = CONST_ME_DRAWBLOOD} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/amphibics/deathspawn.lua b/data/monster/amphibics/deathspawn.lua new file mode 100644 index 00000000000..11a317df552 --- /dev/null +++ b/data/monster/amphibics/deathspawn.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Deathspawn") +local monster = {} + +monster.description = "a deathspawn" +monster.experience = 20 +monster.outfit = { + lookType = 226, + lookHead = 114, + lookBody = 98, + lookLegs = 97, + lookFeet = 114, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 225 +monster.maxHealth = 225 +monster.race = "blood" +monster.corpse = 2220 +monster.speed = 102 +monster.manaCost = 305 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -40, effect = CONST_ME_DRAWBLOOD}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -400, maxDamage = -700, length = 7, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 1000, chance = 11, type = COMBAT_ENERGYDAMAGE, minDamage = -250, maxDamage = -450, length = 7, spread = 3, effect = CONST_ME_PURPLEENERGY, target = false} +} + +monster.defenses = { + defense = 5, + armor = 1 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/amphibics/filth_toad.lua b/data/monster/amphibics/filth_toad.lua new file mode 100644 index 00000000000..20c5c9ac3fc --- /dev/null +++ b/data/monster/amphibics/filth_toad.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Filth Toad") +local monster = {} + +monster.description = "a filth toad" +monster.experience = 90 +monster.outfit = { + lookType = 222, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 735 +monster.Bestiary = { + class = "Amphibic", + race = BESTY_RACE_AMPHIBIC, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Tiquanda, around Lake Equivocolao." + } + +monster.health = 185 +monster.maxHealth = 185 +monster.race = "blood" +monster.corpse = 6077 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 75000, maxCount = 21}, + {name = "two handed sword", chance = 500}, + {name = "mace", chance = 2000}, + {id = 2667, chance = 22000}, + {name = "poisonous slime", chance = 3000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -30, effect = CONST_ME_DRAWBLOOD, condition = {type = CONDITION_POISON, totalDamage = 20, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -8, maxDamage = -17, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_GREEN_RINGS, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="speed", interval = 2000, chance = 15, speedChange = 200, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/amphibics/green_frog.lua b/data/monster/amphibics/green_frog.lua new file mode 100644 index 00000000000..b9ce690f3ab --- /dev/null +++ b/data/monster/amphibics/green_frog.lua @@ -0,0 +1,111 @@ +local mType = Game.createMonsterType("Green Frog") +local monster = {} + +monster.description = "a green frog" +monster.experience = 0 +monster.outfit = { + lookType = 224, + lookHead = 69, + lookBody = 66, + lookLegs = 69, + lookFeet = 66, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 267 +monster.Bestiary = { + class = "Amphibic", + race = BESTY_RACE_AMPHIBIC, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Meriana and other Shattered Isles, Port Hope caves, The Witches Cliff (only accessible during a quest)." + } + +monster.health = 25 +monster.maxHealth = 25 +monster.race = "venom" +monster.corpse = 6079 +monster.speed = 320 +monster.manaCost = 250 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 6, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ribbit!", yell = false}, + {text = "Ribbit! Ribbit!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -25, effect = CONST_ME_DRAWBLOOD} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/amphibics/infernal_frog.lua b/data/monster/amphibics/infernal_frog.lua new file mode 100644 index 00000000000..43739f59cad --- /dev/null +++ b/data/monster/amphibics/infernal_frog.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("Infernal Frog") +local monster = {} + +monster.description = "an infernal frog" +monster.experience = 190 +monster.outfit = { + lookType = 224, + lookHead = 69, + lookBody = 66, + lookLegs = 69, + lookFeet = 66, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 563 +monster.Bestiary = { + class = "Amphibic", + race = BESTY_RACE_AMPHIBIC, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Isle of Evil, Drefia." + } + +monster.health = 655 +monster.maxHealth = 655 +monster.race = "blood" +monster.corpse = 6079 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 40, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ribbit!", yell = false}, + {text = "Ribbit! Ribbit!", yell = false}, + {text = "No Kisses for you!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 73330, maxCount = 65} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -20, effect = CONST_ME_DRAWBLOOD}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_EARTHDAMAGE, minDamage = -16, maxDamage = -32, shootEffect = CONST_ANI_POISON, target = true} +} + +monster.defenses = { + defense = 5, + armor = 5, + {name ="speed", interval = 2000, chance = 20, speedChange = 400, effect = CONST_ME_MAGIC_RED, target = false, duration = 8000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/amphibics/orchid_frog.lua b/data/monster/amphibics/orchid_frog.lua new file mode 100644 index 00000000000..a73d280a452 --- /dev/null +++ b/data/monster/amphibics/orchid_frog.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Orchid Frog") +local monster = {} + +monster.description = "an orchid frog" +monster.experience = 20 +monster.outfit = { + lookType = 226, + lookHead = 109, + lookBody = 14, + lookLegs = 109, + lookFeet = 114, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 271 +monster.Bestiary = { + class = "Amphibic", + race = BESTY_RACE_AMPHIBIC, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Meriana, Laguna Islands, and other Shattered Isles." + } + +monster.health = 60 +monster.maxHealth = 60 +monster.race = "blood" +monster.corpse = 6079 +monster.speed = 320 +monster.manaCost = 305 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ribbit!", yell = false}, + {text = "Ribbit! Ribbit!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 73230, maxCount = 10}, + {name = "worm", chance = 8000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -24, effect = CONST_ME_DRAWBLOOD} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/amphibics/salamander.lua b/data/monster/amphibics/salamander.lua new file mode 100644 index 00000000000..24876c9fa5d --- /dev/null +++ b/data/monster/amphibics/salamander.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Salamander") +local monster = {} + +monster.description = "a salamander" +monster.experience = 25 +monster.outfit = { + lookType = 529, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 913 +monster.Bestiary = { + class = "Amphibic", + race = BESTY_RACE_AMPHIBIC, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Shadowthorn in the bog god's temple, Drefia, around Lake Equivocolao when it's dirty." +} + +monster.health = 70 +monster.maxHealth = 70 +monster.race = "blood" +monster.corpse = 19707 +monster.speed = 120 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Chrrch!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 72000, maxCount = 15}, + {name = "gold coin", chance = 72000, maxCount = 15}, + {name = "mace", chance = 3780}, + {id = 2120, chance = 5190},-- rope + {name = "bow", chance = 740}, + {name = "brass helmet", chance = 2180}, + {name = "arrow", chance = 7890, maxCount = 3}, + {name = "health potion", chance = 1480}, + {id = 2419, chance = 490}-- scimitar +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -60, effect = CONST_ME_DRAWBLOOD, condition = {type = CONDITION_POISON, totalDamage = 10, interval = 4000}} +} + +monster.defenses = { + defense = 5, + armor = 5, + {name ="combat", interval = 6000, chance = 20, type = COMBAT_HEALING, minDamage = 0, maxDamage = 4, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/amphibics/toad.lua b/data/monster/amphibics/toad.lua new file mode 100644 index 00000000000..92814660da6 --- /dev/null +++ b/data/monster/amphibics/toad.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("Toad") +local monster = {} + +monster.description = "a toad" +monster.experience = 60 +monster.outfit = { + lookType = 222, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 262 +monster.Bestiary = { + class = "Amphibic", + race = BESTY_RACE_AMPHIBIC, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "The Laguna Islands, Arena and Zoo Quarter, Tiquanda/Tarantula Caves, \z + Shadowthorn Bog God Temple, Northern Zao Plantations, Northern Brimstone Bug Cave." + } + +monster.health = 135 +monster.maxHealth = 135 +monster.race = "blood" +monster.corpse = 6077 +monster.speed = 210 +monster.manaCost = 400 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ribbit! Ribbit!", yell = false}, + {text = "Ribbit!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 80000, maxCount = 20}, + {name = "war hammer", chance = 148}, + {name = "mace", chance = 2854}, + {id = 2667, chance = 20000}, + {name = "poisonous slime", chance = 4761} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -30, effect = CONST_ME_DRAWBLOOD, condition = {type = CONDITION_POISON, totalDamage = 20, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -8, maxDamage = -17, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_GREEN_RINGS, target = false} +} + +monster.defenses = { + defense = 6, + armor = 6, + {name ="speed", interval = 2000, chance = 15, speedChange = 200, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/abyssal_calamary.lua b/data/monster/aquatics/abyssal_calamary.lua new file mode 100644 index 00000000000..6f06a49ab98 --- /dev/null +++ b/data/monster/aquatics/abyssal_calamary.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Abyssal Calamary") +local monster = {} + +monster.description = "an abyssal calamary" +monster.experience = 200 +monster.outfit = { + lookType = 451, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1105 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 50, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Seacrest Grounds." + } + +monster.health = 300 +monster.maxHealth = 300 +monster.race = "blood" +monster.corpse = 15280 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 89, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2670, chance = 9680},--shrimp + {id = 2667, chance = 10770},--fish + {name = "black pearl", chance = 1500, maxCount = 1}, + {name = "white pearl", chance = 830, maxCount = 1}, + {name = "small sapphire", chance = 250, maxCount = 3}, + {name = "small ruby", chance = 500, maxCount = 3}, + {name = "small amethyst", chance = 750, maxCount = 3} +} + +monster.attacks = { + {name ="drunk", interval = 2000, chance = 10, range = 2, target = false, duration = 5000} +} + +monster.defenses = { + defense = 13, + armor = 13 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/blood_crab.lua b/data/monster/aquatics/blood_crab.lua new file mode 100644 index 00000000000..a4dd32c5f53 --- /dev/null +++ b/data/monster/aquatics/blood_crab.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Blood Crab") +local monster = {} + +monster.description = "a blood crab" +monster.experience = 160 +monster.outfit = { + lookType = 200, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 261 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Goroma (beyond electric barrier), Laguna Islands, Shattered Isles, Underground Port Hope, \z + Mistrock, Treasure Island. There is also one underwater next to The Tibianic, however it is unreachable." + } + +monster.health = 290 +monster.maxHealth = 290 +monster.race = "blood" +monster.corpse = 6075 +monster.speed = 160 +monster.manaCost = 505 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 85750, maxCount = 20}, + {id = 2667, chance = 14300},--fish + {name = "bloody pincers", chance = 6190}, + {name = "chain armor", chance = 5240}, + {name = "brass legs", chance = 2120}, + {name = "white pearl", chance = 530} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -110, effect = CONST_ME_DRAWBLOOD} +} + +monster.defenses = { + defense = 28, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/calamary.lua b/data/monster/aquatics/calamary.lua new file mode 100644 index 00000000000..555e742892d --- /dev/null +++ b/data/monster/aquatics/calamary.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Calamary") +local monster = {} + +monster.description = "a calamary" +monster.experience = 0 +monster.outfit = { + lookType = 451, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 780 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 1, + Locations = "Fiehonja." + } + +monster.health = 75 +monster.maxHealth = 75 +monster.race = "undead" +monster.corpse = 15280 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 75, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Bubble!", yell = false}, + {text = "Bobble!", yell = false} +} + +monster.loot = { + {name = "shrimp", chance = 12270, maxCount = 2} +} + +monster.defenses = { + defense = 5, + armor = 13 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/crab.lua b/data/monster/aquatics/crab.lua new file mode 100644 index 00000000000..c96f98076cc --- /dev/null +++ b/data/monster/aquatics/crab.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Crab") +local monster = {} + +monster.description = "a crab" +monster.experience = 30 +monster.outfit = { + lookType = 112, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 112 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Various locations like Goroma, Edron, Port Hope, Nargor and other Shattered Isles. \z + There is also one located underwater by The Tibianic, however it is unreachable." + } + +monster.health = 55 +monster.maxHealth = 55 +monster.race = "undead" +monster.corpse = 6039 +monster.speed = 144 +monster.manaCost = 305 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 80000, maxCount = 10}, + {id = 2667, chance = 20000}, + {name = "crab pincers", chance = 20000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -20, effect = CONST_ME_DRAWBLOOD} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/crustacea_gigantica.lua b/data/monster/aquatics/crustacea_gigantica.lua new file mode 100644 index 00000000000..9b8d32b45ae --- /dev/null +++ b/data/monster/aquatics/crustacea_gigantica.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Crustacea Gigantica") +local monster = {} + +monster.description = "a crustacea gigantica" +monster.experience = 1800 +monster.outfit = { + lookType = 383, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 697 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 3, + Locations = "Calassa, Treasure Island , Seacrest Grounds. \z + In the Seacrest Grounds the spawns are Varying Monster Spawns in which the common creature is an Abyssal Calamary. \z + The chance to spawn a Crustacea Gigantica seems to be around 1%-2%." + } + +monster.health = 1600 +monster.maxHealth = 1600 +monster.race = "blood" +monster.corpse = 13331 +monster.speed = 480 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Chrchrchr", yell = true}, + {text = "Klonklonk", yell = true}, + {text = "Chrrrrr", yell = true}, + {text = "Crunch crunch", yell = true} +} + +monster.loot = { + {name = "gold coin", chance = 96000, maxCount = 100}, + {name = "gold coin", chance = 56000, maxCount = 75}, + {name = "strong mana potion", chance = 8885}, + {name = "strong health potion", chance = 3880}, + {name = "giant crab pincer", chance = 5000, maxCount = 2}, + {name = "ring of healing", chance = 3000}, + {name = "great mana potion", chance = 1220}, +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -600, effect = CONST_ME_DRAWBLOOD} +} + +monster.defenses = { + defense = 45, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/deathling_scout.lua b/data/monster/aquatics/deathling_scout.lua new file mode 100644 index 00000000000..f9d6be56d85 --- /dev/null +++ b/data/monster/aquatics/deathling_scout.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Deathling Scout") +local monster = {} + +monster.description = "a deathling scout" +monster.experience = 6300 +monster.outfit = { + lookType = 413, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1667 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Deepling Ancestorial Grounds and Sunken Temple." + } + +monster.health = 7200 +monster.maxHealth = 7200 +monster.race = "blood" +monster.corpse = 33373 +monster.speed = 310 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "VBOX°O", yell = false}, + {text = "O(J-\"LJ-T =|-°", yell = false} +} + +monster.loot = { + {name = "crystalline arrow", chance = 25260, maxCount = 25}, + {name = "Vortex Bolt", chance = 21340, maxCount = 25}, + {name = "Small Emerald", chance = 20910, maxCount = 12}, + {name = "Deepling Warts", chance = 20280}, + {name = "Deeptags", chance = 15100}, + {name = "Deepling Filet", chance = 14630}, + {name = "Small Enchanted Sapphire", chance = 13000, maxCount = 8}, + {name = "Deepling Ridge", chance = 11240}, + {name = "Great Mana Potion", chance = 10000}, + {name = "Great Health Potion", chance = 10000}, + {name = "Heavy Trident", chance = 6620}, + {name = "Eye of a Deepling", chance = 6070}, + {name = "Warrior's Shield", chance = 3630}, + {name = "Warrior's Axe", chance = 3470}, + {name = "Life Ring", chance = 3000}, + {name = "Fish Fin", chance = 920}, + {name = "Necklace of the Deep", chance = 440} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300, effect = CONST_ME_DRAWBLOOD}, + {name ="combat", interval = 4000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -400, range = 5, shootEffect = CONST_ANI_HUNTINGSPEAR, target = false}, + {name ="combat", interval = 4000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -150, maxDamage = -300, range = 5, shootEffect = CONST_ANI_LARGEROCK, target = false}, + {name ="combat", interval = 4000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -350, maxDamage = -550, radius = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 72, + armor = 72 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/deathling_spellsinger.lua b/data/monster/aquatics/deathling_spellsinger.lua new file mode 100644 index 00000000000..8a91b8a6bcd --- /dev/null +++ b/data/monster/aquatics/deathling_spellsinger.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Deathling Spellsinger") +local monster = {} + +monster.description = "a deathling spellsinger" +monster.experience = 6400 +monster.outfit = { + lookType = 1088, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1677 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Ancient Ancestorial Grounds and Sunken Temple." + } + +monster.health = 7200 +monster.maxHealth = 7200 +monster.race = "blood" +monster.corpse = 32549 +monster.speed = 310 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 60, + targetDistance = 1, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "BOQOL\"°", yell = false}, + {text = "QOL\" VBOXCL°", yell = false} +} + +monster.loot = { + {name = "platinum coin", chance = 86000, maxCount = 14}, + {name = "crystalline arrow", chance = 26000, maxCount = 25}, + {name = "Small Emerald", chance = 14040, maxCount = 14}, + {name = "Deepling Filet", chance = 12470}, + {name = "Deeptags", chance = 12470}, + {name = "Great Health Potion", chance = 9130}, + {name = "Deepling Ridge", chance = 8840}, + {name = "Deepling Warts", chance = 8540}, + {name = "Great Mana Potion", chance = 8200}, + {name = "Vortex Bolt", chance = 6380, maxCount = 25}, + {name = "Eye of a Deepling", chance = 4760}, + {name = "Heavy Trident", chance = 4120}, + {name = "Warrior's Shield", chance = 3090}, + {name = "Fish Fin", chance = 2990}, + {name = "Warrior's Axe", chance = 2950}, + {name = "Small Enchanted Sapphire", chance = 2220, maxCount = 4}, + {name = "Life Ring", chance = 2010}, + {name = "Necklace of the Deep", chance = 200} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300, effect = CONST_ME_DRAWBLOOD}, + {name ="combat", interval = 4000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -400, range = 5, shootEffect = CONST_ANI_HUNTINGSPEAR, target = false}, + {name ="combat", interval = 4000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -150, maxDamage = -300, range = 5, shootEffect = CONST_ANI_LARGEROCK, target = false}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_HOLYDAMAGE, minDamage = -400, maxDamage = -700, length = 8, spread = 3, effect = CONST_ME_BLOCKHIT, target = false} +} + +monster.defenses = { + defense = 72, + armor = 72 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/deepling_brawler.lua b/data/monster/aquatics/deepling_brawler.lua new file mode 100644 index 00000000000..ffefda6a467 --- /dev/null +++ b/data/monster/aquatics/deepling_brawler.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Deepling Brawler") +local monster = {} + +monster.description = "a deepling brawler" +monster.experience = 260 +monster.outfit = { + lookType = 470, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 859 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 250, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "Fiehonja." + } + +monster.health = 380 +monster.maxHealth = 380 +monster.race = "blood" +monster.corpse = 13840 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 40, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "?", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 96000, maxCount = 44}, + {id = 2667, chance = 19730, maxCount = 3}, + {name = "deepling scales", chance = 14500}, + {name = "eye of a deepling", chance = 6500}, + {name = "heavy trident", chance = 2720}, + {name = "fish fin", chance = 680} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100, effect = CONST_ME_DRAWBLOOD}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DROWNDAMAGE, minDamage = -60, maxDamage = -120, range = 7, shootEffect = CONST_ANI_SPEAR, effect = CONST_ME_LOSEENERGY, target = true} +} + +monster.defenses = { + defense = 18, + armor = 18 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/deepling_elite.lua b/data/monster/aquatics/deepling_elite.lua new file mode 100644 index 00000000000..888740d2ef9 --- /dev/null +++ b/data/monster/aquatics/deepling_elite.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Deepling Elite") +local monster = {} + +monster.description = "a deepling elite" +monster.experience = 3000 +monster.outfit = { + lookType = 441, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 862 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "Fiehonja (Tanjis lair)." + } + +monster.health = 3200 +monster.maxHealth = 3200 +monster.race = "blood" +monster.corpse = 15176 +monster.speed = 330 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 30, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "gold coin", chance = 100000, maxCount = 86}, + {name = "great health potion", chance = 25000}, + {name = "eye of a deepling", chance = 25000}, + {name = "deepling filet", chance = 25000}, + {name = "vortex bolt", chance = 24800, maxCount = 5}, + {name = "deepling warts", chance = 24400}, + {name = "great mana potion", chance = 24200}, + {name = "deeptags", chance = 20600}, + {name = "deepling ridge", chance = 19500}, + {name = "small emerald", chance = 6890, maxCount = 2}, + {name = "life ring", chance = 5360}, + {name = "heavy trident", chance = 3680}, + {name = "fish fin", chance = 2300}, + {name = "warrior's shield", chance = 1534}, + {name = "warrior's axe", chance = 820} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300, effect = CONST_ME_DRAWBLOOD}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -290, range = 7, shootEffect = CONST_ANI_LARGEROCK, target = true} +} + +monster.defenses = { + defense = 45, + armor = 45, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 150, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/deepling_guard.lua b/data/monster/aquatics/deepling_guard.lua new file mode 100644 index 00000000000..8f80899a935 --- /dev/null +++ b/data/monster/aquatics/deepling_guard.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Deepling Guard") +local monster = {} + +monster.description = "a deepling guard" +monster.experience = 2100 +monster.outfit = { + lookType = 442, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 770 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Fiehonja. During Deeplings stage 1 around 10 spawns exist. \z + Also may spawn during the gemcutting mission. Many more spawns in almost all areas of Deepling stage 2 and 3." + } + +monster.health = 1900 +monster.maxHealth = 1900 +monster.race = "blood" +monster.corpse = 15187 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "QJELL NETA NA!!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 90}, + {name = "gold coin", chance = 100000, maxCount = 90}, + {name = "platinum coin", chance = 70000, maxCount = 2}, + {name = "great mana potion", chance = 14285, maxCount = 3}, + {name = "great health potion", chance = 14285, maxCount = 3}, + {name = "deepling breaktime snack", chance = 16666}, + {name = "deepling guard belt buckle", chance = 12500}, + {name = "eye of a deepling", chance = 10000}, + {name = "deepling claw", chance = 9090}, + {name = "small sapphire", chance = 2890, maxCount = 3}, + {name = "heavy trident", chance = 1694}, + {name = "guardian axe", chance = 925}, + {name = "deepling squelcher", chance = 751}, + {name = "deepling backpack", chance = 333}, + {name = "ornate crossbow", chance = 362}, + {name = "foxtail", chance = 10} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400, effect = CONST_ME_DRAWBLOOD}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, range = 7, shootEffect = CONST_ANI_WHIRLWINDSWORD, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DROWNDAMAGE, minDamage = -100, maxDamage = -150, range = 7, shootEffect = CONST_ANI_SPEAR, effect = CONST_ME_LOSEENERGY, target = true} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 100, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/deepling_master_librarian.lua b/data/monster/aquatics/deepling_master_librarian.lua new file mode 100644 index 00000000000..b515600c1d2 --- /dev/null +++ b/data/monster/aquatics/deepling_master_librarian.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Deepling Master Librarian") +local monster = {} + +monster.description = "a deepling master librarian" +monster.experience = 1900 +monster.outfit = { + lookType = 443, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 860 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Fiehonja." + } + +monster.health = 1700 +monster.maxHealth = 1700 +monster.race = "blood" +monster.corpse = 15211 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 60, + targetDistance = 1, + runHealth = 250, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "platinum coin", chance = 89000, maxCount = 3}, + {name = "spellsinger's seal", chance = 25000}, + {name = "deepling filet", chance = 20000}, + {name = "key to the Drowned Library", chance = 20000}, + {name = "eye of a deepling", chance = 9380}, + {id = 2667, chance = 9090, maxCount = 2}, + {name = "small sapphire", chance = 8440, maxCount = 3}, + {name = "deepling staff", chance = 3130}, + {name = "life ring", chance = 3200}, + {name = "fish fin", chance = 1800}, + {name = "necklace of the deep", chance = 1250}, + {name = "ornate crossbow", chance = 35} +} + + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -210, effect = CONST_ME_DRAWBLOOD}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -260, maxDamage = -450, length = 10, spread = 3, effect = CONST_ME_ICETORNADO, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DROWNDAMAGE, minDamage = -150, maxDamage = -280, radius = 4, effect = CONST_ME_BUBBLES, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -80, maxDamage = -140, range = 7, effect = CONST_ME_SMALLPLANTS, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -60, maxDamage = -140, range = 7, effect = CONST_ME_SMALLPLANTS, target = false}, + {name ="deepling spellsinger skill reducer", interval = 2000, chance = 10, range = 5, target = false} +} + +monster.defenses = { + defense = 20, + armor = 45, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 40, maxDamage = 80, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/deepling_scout.lua b/data/monster/aquatics/deepling_scout.lua new file mode 100644 index 00000000000..13394aac53d --- /dev/null +++ b/data/monster/aquatics/deepling_scout.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Deepling Scout") +local monster = {} + +monster.description = "a deepling scout" +monster.experience = 160 +monster.outfit = { + lookType = 413, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 734 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Fiehonja, Sunken Mines near Dwarf Mines." + } + +monster.health = 240 +monster.maxHealth = 240 +monster.race = "blood" +monster.corpse = 13839 +monster.speed = 130 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 50, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Njaaarh!!", yell = false}, + {text = "Begjone, intrjuder!!", yell = false}, + {text = "Djon't djare stjare injo the eyes of the djeep!", yell = false}, + {text = "Ljeave this sjacred pljace while you cjan", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 75000, maxCount = 50}, + {name = "hunting spear", chance = 15185, maxCount = 3}, + {name = "life ring", chance = 2127}, + {name = "rusted armor", chance = 925}, + {name = "heavy trident", chance = 505}, + {name = "eye of a deepling", chance = 310}, + {name = "fish fin", chance = 310}, + {name = "small emerald", chance = 121}, + {name = "flask of rust remover", chance = 111} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100, effect = CONST_ME_DRAWBLOOD}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DROWNDAMAGE, minDamage = -40, maxDamage = -100, range = 7, shootEffect = CONST_ANI_SPEAR, effect = CONST_ME_LOSEENERGY, target = true} +} + +monster.defenses = { + defense = 10, + armor = 7 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/deepling_spellsinger.lua b/data/monster/aquatics/deepling_spellsinger.lua new file mode 100644 index 00000000000..5711e9eff59 --- /dev/null +++ b/data/monster/aquatics/deepling_spellsinger.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Deepling Spellsinger") +local monster = {} + +monster.description = "a deepling spellsinger" +monster.experience = 1000 +monster.outfit = { + lookType = 443, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 772 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Fiehonja." + } + +monster.health = 850 +monster.maxHealth = 850 +monster.race = "blood" +monster.corpse = 15208 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 60, + targetDistance = 1, + runHealth = 60, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Jey Obu giotja!!", yell = false}, + {text = "Mmmmmoooaaaaaahaaa!!", yell = false} +} + +monster.loot = { + {name = "platinum coin", chance = 80120}, + {name = "gold coin", chance = 75110, maxCount = 60}, + {name = "spellsinger's seal", chance = 15185}, + {name = "deepling filet", chance = 14995}, + {name = "key to the Drowned Library", chance = 10740}, + {id = 2667, chance = 3448},--fish + {name = "small sapphire", chance = 2934}, + {name = "eye of a deepling", chance = 2540}, + {name = "life ring", chance = 2459}, + {name = "deepling staff", chance = 2020}, + {name = "necklace of the deep", chance = 790}, + {name = "fish fin", chance = 520}, + {name = "ornate crossbow", chance = 220} +} + + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -152, effect = CONST_ME_DRAWBLOOD}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -180, maxDamage = -350, length = 10, spread = 3, effect = CONST_ME_ICETORNADO, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DROWNDAMAGE, minDamage = -90, maxDamage = -130, radius = 4, effect = CONST_ME_BUBBLES, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -60, maxDamage = -140, range = 7, effect = CONST_ME_SMALLPLANTS, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -60, maxDamage = -140, range = 7, effect = CONST_ME_SMALLPLANTS, target = false}, + {name ="deepling spellsinger skill reducer", interval = 2000, chance = 5, range = 5, target = false} +} + +monster.defenses = { + defense = 25, + armor = 42 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/deepling_tyrant.lua b/data/monster/aquatics/deepling_tyrant.lua new file mode 100644 index 00000000000..15299a1ccdc --- /dev/null +++ b/data/monster/aquatics/deepling_tyrant.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Deepling Tyrant") +local monster = {} + +monster.description = "a deepling tyrant" +monster.experience = 4200 +monster.outfit = { + lookType = 442, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 861 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 2, + Locations = "Fiehonja." + } + +monster.health = 4500 +monster.maxHealth = 4500 +monster.race = "blood" +monster.corpse = 15188 +monster.speed = 310 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "QJELL NETA NA!!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "platinum coin", chance = 70000, maxCount = 4}, + {name = "deepling breaktime snack", chance = 35520}, + {name = "great mana potion", chance = 32640, maxCount = 3}, + {name = "great health potion", chance = 33430, maxCount = 3}, + {name = "deepling claw", chance = 29960}, + {name = "eye of a deepling", chance = 29610}, + {name = "deepling guard belt buckle", chance = 23700}, + {name = "small sapphire", chance = 9410, maxCount = 5}, + {name = "heavy trident", chance = 3530}, + {name = "deepling squelcher", chance = 1440}, + {name = "guardian axe", chance = 1340}, + {name = "ornate crossbow", chance = 1190}, + {name = "deepling backpack", chance = 410}, + {name = "foxtail", chance = 30} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -501, effect = CONST_ME_DRAWBLOOD}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -375, range = 7, shootEffect = CONST_ANI_WHIRLWINDSWORD, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DROWNDAMAGE, minDamage = -180, maxDamage = -215, range = 7, shootEffect = CONST_ANI_SPEAR, effect = CONST_ME_LOSEENERGY, target = true} +} + +monster.defenses = { + defense = 45, + armor = 54, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 200, maxDamage = 400, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/deepling_warrior.lua b/data/monster/aquatics/deepling_warrior.lua new file mode 100644 index 00000000000..9e3489865ab --- /dev/null +++ b/data/monster/aquatics/deepling_warrior.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Deepling Warrior") +local monster = {} + +monster.description = "a deepling warrior" +monster.experience = 1500 +monster.outfit = { + lookType = 441, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 769 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Fiehonja." + } + +monster.health = 1600 +monster.maxHealth = 1600 +monster.race = "blood" +monster.corpse = 15175 +monster.speed = 290 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 30, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Jou wjil ajll djie!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 60000, maxCount = 100}, + {name = "gold coin", chance = 60000, maxCount = 80}, + {name = "deepling filet", chance = 15285}, + {name = "deeptags", chance = 14975}, + {name = "deepling ridge", chance = 11111}, + {name = "great mana potion", chance = 10210}, + {name = "deepling warts", chance = 10040}, + {name = "great health potion", chance = 10030}, + {name = "vortex bolt", chance = 3431, maxCount = 5}, + {name = "small emerald", chance = 3104}, + {name = "life ring", chance = 3001}, + {name = "heavy trident", chance = 999}, + {name = "fish fin", chance = 870}, + {name = "warrior's shield", chance = 610}, + {name = "eye of a deepling", chance = 610}, + {name = "warrior's axe", chance = 510} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300, effect = CONST_ME_DRAWBLOOD}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -290, range = 7, shootEffect = CONST_ANI_WHIRLWINDAXE, target = true} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 50, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/deepling_worker.lua b/data/monster/aquatics/deepling_worker.lua new file mode 100644 index 00000000000..a2b1b25d925 --- /dev/null +++ b/data/monster/aquatics/deepling_worker.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Deepling Worker") +local monster = {} + +monster.description = "a deepling worker" +monster.experience = 130 +monster.outfit = { + lookType = 470, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 795 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Fiehonja, Coral mine." + } + +monster.health = 190 +monster.maxHealth = 190 +monster.race = "blood" +monster.corpse = 15497 +monster.speed = 130 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Qjell afar gou jey!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 75000, maxCount = 25}, + {id = 2667, chance = 12020, maxCount = 3},--fish + {name = "deepling scales", chance = 6950}, + {name = "heavy trident", chance = 510}, + {name = "fish fin", chance = 350}, + {name = "eye of a deepling", chance = 283}, + {name = "small emerald", chance = 110, maxCount = 1} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -80, effect = CONST_ME_DRAWBLOOD} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/deepsea_blood_crab.lua b/data/monster/aquatics/deepsea_blood_crab.lua new file mode 100644 index 00000000000..03aca06e83d --- /dev/null +++ b/data/monster/aquatics/deepsea_blood_crab.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Deepsea Blood Crab") +local monster = {} + +monster.description = "a deepsea blood crab" +monster.experience = 180 +monster.outfit = { + lookType = 200, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 437 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Svargrond (Sea Serpent Area), Drefia. \z + There is also one under Rookgaard Academy, however it is unreachable." + } + +monster.health = 320 +monster.maxHealth = 320 +monster.race = "blood" +monster.corpse = 6075 +monster.speed = 380 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 87000, maxCount = 20}, + {id = 2667, chance = 10450}, + {name = "bloody pincers", chance = 6980}, + {name = "chain armor", chance = 5020}, + {name = "brass legs", chance = 2720}, + {name = "white pearl", chance = 620} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -111, effect = CONST_ME_DRAWBLOOD} +} + +monster.defenses = { + defense = 28, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/fish.lua b/data/monster/aquatics/fish.lua new file mode 100644 index 00000000000..1e3000950a2 --- /dev/null +++ b/data/monster/aquatics/fish.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Fish") +local monster = {} + +monster.description = "a fish" +monster.experience = 0 +monster.outfit = { + lookType = 455, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 784 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Fiehonja." + } + +monster.health = 25 +monster.maxHealth = 25 +monster.race = "undead" +monster.corpse = 2667 +monster.speed = 140 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 25, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Blib!", yell = false}, + {text = "Blub!", yell = false} +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/jellyfish.lua b/data/monster/aquatics/jellyfish.lua new file mode 100644 index 00000000000..3cada9a591b --- /dev/null +++ b/data/monster/aquatics/jellyfish.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("Jellyfish") +local monster = {} + +monster.description = "a jellyfish" +monster.experience = 0 +monster.outfit = { + lookType = 452, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 781 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 1, + Locations = "Fiehonja, Krailos Steppe underwater cave." + } + +monster.health = 55 +monster.maxHealth = 55 +monster.race = "undead" +monster.corpse = 15284 +monster.speed = 168 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Luuurrrp!", yell = false} +} + +monster.loot = { + {name = "shrimp", chance = 8333, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -10, effect = CONST_ME_DRAWBLOOD} +} + +monster.defenses = { + defense = 10, + armor = 10, + {name ="invisible", interval = 2000, chance = 15} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/manta_ray.lua b/data/monster/aquatics/manta_ray.lua new file mode 100644 index 00000000000..89041931328 --- /dev/null +++ b/data/monster/aquatics/manta_ray.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Manta Ray") +local monster = {} + +monster.description = "a manta ray" +monster.experience = 125 +monster.outfit = { + lookType = 449, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 779 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Fiehonja only in stage 3 in a large room." + } + +monster.health = 680 +monster.maxHealth = 680 +monster.race = "blood" +monster.corpse = 15276 +monster.speed = 168 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Flap flap flap!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 63000, maxCount = 39} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -99, effect = CONST_ME_DRAWBLOOD, condition = {type = CONDITION_POISON, totalDamage = 120, interval = 4000}}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -15, maxDamage = -75, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, length = 4, spread = 3, effect = CONST_ME_ENERGYHIT, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 25}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/northern_pike.lua b/data/monster/aquatics/northern_pike.lua new file mode 100644 index 00000000000..87d11a47a90 --- /dev/null +++ b/data/monster/aquatics/northern_pike.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Northern Pike") +local monster = {} + +monster.description = "a northern pike" +monster.experience = 0 +monster.outfit = { + lookType = 454, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 783 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 25, + FirstUnlock = 5, + SecondUnlock = 10, + CharmsPoints = 1, + Stars = 1, + Occurrence = 1, + Locations = "Fiehonja." + } + +monster.health = 95 +monster.maxHealth = 95 +monster.race = "undead" +monster.corpse = 2669 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 95, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 25, + {text = "Blub!", yell = false} +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 9 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/quara_constrictor.lua b/data/monster/aquatics/quara_constrictor.lua new file mode 100644 index 00000000000..58f890a5161 --- /dev/null +++ b/data/monster/aquatics/quara_constrictor.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Quara Constrictor") +local monster = {} + +monster.description = "a quara constrictor" +monster.experience = 250 +monster.outfit = { + lookType = 46, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 239 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Calassa, Frozen Trench underwater sites, Yalahar (Sunken Quarter)." + } + +monster.health = 450 +monster.maxHealth = 450 +monster.race = "blood" +monster.corpse = 6065 +monster.speed = 380 +monster.manaCost = 670 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 45, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Gaaahhh!", yell = false}, + {text = "Gluh! Gluh!", yell = false}, + {text = "Tssss!", yell = false}, + {text = "Boohaa!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 87500, maxCount = 100}, + {name = "quara tentacle", chance = 14520}, + {name = "longsword", chance = 6931}, + {name = "shrimp", chance = 5140, maxCount = 5}, + {name = "brass armor", chance = 4810}, + {name = "small amethyst", chance = 3060}, + {name = "fish fin", chance = 490} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150, effect = CONST_ME_DRAWBLOOD, condition = {type = CONDITION_POISON, totalDamage = 20, interval = 4000}}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -50, maxDamage = -90, radius = 3, effect = CONST_ME_HITAREA, target = false}, + {name ="quara constrictor freeze", interval = 2000, chance = 10, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -40, maxDamage = -70, range = 7, radius = 4, effect = CONST_ME_ICEATTACK, target = false}, + {name ="quara constrictor electrify", interval = 2000, chance = 10, range = 1, target = false} +} + +monster.defenses = { + defense = 20, + armor = 14 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -25}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/quara_constrictor_scout.lua b/data/monster/aquatics/quara_constrictor_scout.lua new file mode 100644 index 00000000000..00f6f4e4ab4 --- /dev/null +++ b/data/monster/aquatics/quara_constrictor_scout.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Quara Constrictor Scout") +local monster = {} + +monster.description = "a quara constrictor scout" +monster.experience = 200 +monster.outfit = { + lookType = 46, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 240 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Malada, Arena Quarter, Treasure Island Eastern Caves, \z + Hrodmir Quara Scout Caves, Quara Grotto, Oramond." + } + +monster.health = 450 +monster.maxHealth = 450 +monster.race = "blood" +monster.corpse = 6065 +monster.speed = 150 +monster.manaCost = 670 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 45, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Gaaahhh!", yell = false}, + {text = "Gluh! Gluh!", yell = false}, + {text = "Tssss!", yell = false}, + {text = "Boohaa!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 87620, maxCount = 100}, + {name = "quara tentacle", chance = 14620}, + {name = "longsword", chance = 6910}, + {name = "shrimp", chance = 5140, maxCount = 3}, + {name = "brass armor", chance = 4810}, + {name = "small amethyst", chance = 3060}, + {name = "fish fin", chance = 490} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -135, effect = CONST_ME_DRAWBLOOD}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -80, radius = 3, effect = CONST_ME_HITAREA, target = false} +} + +monster.defenses = { + defense = 15, + armor = 14 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/quara_hydromancer.lua b/data/monster/aquatics/quara_hydromancer.lua new file mode 100644 index 00000000000..2bf7eb45d84 --- /dev/null +++ b/data/monster/aquatics/quara_hydromancer.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Quara Hydromancer") +local monster = {} + +monster.description = "a quara hydromancer" +monster.experience = 800 +monster.outfit = { + lookType = 47, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 243 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Calassa, Frozen Trench, Yalahar (Sunken Quarter)." + } + +monster.health = 1100 +monster.maxHealth = 1100 +monster.race = "blood" +monster.corpse = 6066 +monster.speed = 490 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Qua hah tsh!", yell = false}, + {text = "Teech tsha tshul!", yell = false}, + {text = "Quara tsha Fach!", yell = false}, + {text = "Tssssha Quara!", yell = false}, + {text = "Blubber.", yell = false}, + {text = "Blup.", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 60}, + {name = "gold coin", chance = 40000, maxCount = 50}, + {name = "quara eye", chance = 15930}, + {name = "white pearl", chance = 5250}, + {name = "small emerald", chance = 5111, maxCount = 2}, + {name = "shrimp", chance = 4545, maxCount = 5}, + {name = "black pearl", chance = 3150}, + {name = "great mana potion", chance = 2880}, + {name = "fish fin", chance = 1410}, + {name = "ring of healing", chance = 1218}, + {name = "wand of cosmic energy", chance = 980}, + {name = "knight armor", chance = 230} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -80, effect = CONST_ME_DRAWBLOOD, condition = {type = CONDITION_POISON, totalDamage = 100, interval = 4000}}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -100, maxDamage = -180, length = 8, spread = 3, effect = CONST_ME_BUBBLES, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -90, maxDamage = -150, radius = 3, effect = CONST_ME_BUBBLES, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -170, maxDamage = -240, length = 8, spread = 3, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -170, range = 7, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="speed", interval = 2000, chance = 15, speedChange = -600, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 15000} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 100, maxDamage = 120, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -25}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/quara_hydromancer_scout.lua b/data/monster/aquatics/quara_hydromancer_scout.lua new file mode 100644 index 00000000000..647c85635e1 --- /dev/null +++ b/data/monster/aquatics/quara_hydromancer_scout.lua @@ -0,0 +1,134 @@ +local mType = Game.createMonsterType("Quara Hydromancer Scout") +local monster = {} + +monster.description = "a quara hydromancer scout" +monster.experience = 800 +monster.outfit = { + lookType = 47, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 244 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Malada, Hrodmir Quara Scout Caves, Quara Grotto, Oramond." + } + +monster.health = 1100 +monster.maxHealth = 1100 +monster.race = "undead" +monster.corpse = 6066 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Qua hah tsh!", yell = false}, + {text = "Teech tsha tshul!", yell = false}, + {text = "Quara tsha Fach!", yell = false}, + {text = "Tssssha Quara!", yell = false}, + {text = "Blubber.", yell = false}, + {text = "Blup.", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 40000, maxCount = 90}, + {name = "gold coin", chance = 49000, maxCount = 50}, + {id = 2667, chance = 18930, maxCount = 3},--fish + {name = "quara eye", chance = 12720}, + {name = "shrimp", chance = 9980, maxCount = 4}, + {name = "small emerald", chance = 6000, maxCount = 2}, + {name = "white pearl", chance = 2900}, + {name = "black pearl", chance = 2650}, + {name = "fish fin", chance = 2090}, + {name = "obsidian lance", chance = 1530}, + {name = "ring of healing", chance = 940}, + {name = "wand of cosmic energy", chance = 910}, + {name = "knight armor", chance = 520} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -80, effect = CONST_ME_DRAWBLOOD, condition = {type = CONDITION_POISON, totalDamage = 100, interval = 4000}}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -100, maxDamage = -180, length = 8, spread = 3, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -90, maxDamage = -150, radius = 3, effect = CONST_ME_BUBBLES, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -170, maxDamage = -240, length = 8, spread = 3, effect = CONST_ME_BUBBLES, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -170, range = 7, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="speed", interval = 2000, chance = 15, speedChange = -600, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 15000} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 100, maxDamage = 120, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/quara_mantassin.lua b/data/monster/aquatics/quara_mantassin.lua new file mode 100644 index 00000000000..da2c68facf2 --- /dev/null +++ b/data/monster/aquatics/quara_mantassin.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Quara Mantassin") +local monster = {} + +monster.description = "a quara mantassin" +monster.experience = 400 +monster.outfit = { + lookType = 72, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 241 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Calassa, Frozen Trench, Yalahar (Sunken Quarter)." + } + +monster.health = 800 +monster.maxHealth = 800 +monster.race = "blood" +monster.corpse = 6064 +monster.speed = 590 +monster.manaCost = 480 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 40, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Zuerk Pachak!", yell = false}, + {text = "Shrrrr", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 5000, maxCount = 100}, + {name = "gold coin", chance = 29000, maxCount = 29}, + {name = "mantassin tail", chance = 12600}, + {name = "shrimp", chance = 5170, maxCount = 5}, + {name = "halberd", chance = 4970}, + {name = "small sapphire", chance = 1130}, + {name = "cape", chance = 1090}, + {name = "stealth ring", chance = 1050}, + {name = "two handed sword", chance = 990}, + {name = "fish fin", chance = 610}, + {name = "strange helmet", chance = 100}, + {name = "blue robe", chance = 60} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -138, effect = CONST_ME_DRAWBLOOD} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="invisible", interval = 2000, chance = 20, effect = CONST_ME_MAGIC_BLUE}, + {name ="speed", interval = 2000, chance = 15, speedChange = 400, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -25}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/quara_mantassin_scout.lua b/data/monster/aquatics/quara_mantassin_scout.lua new file mode 100644 index 00000000000..9079acccdde --- /dev/null +++ b/data/monster/aquatics/quara_mantassin_scout.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("Quara Mantassin Scout") +local monster = {} + +monster.description = "a quara mantassin scout" +monster.experience = 100 +monster.outfit = { + lookType = 72, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 242 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 2, + Occurrence = 0, + Locations = "Malada, Water Elemental Cave near Port Hope, Hrodmir Quara Scout Caves, Quara Grotto, Oramond." + } + +monster.health = 220 +monster.maxHealth = 220 +monster.race = "blood" +monster.corpse = 6064 +monster.speed = 140 +monster.manaCost = 480 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Zuerk Pachak!", yell = false}, + {text = "Shrrrr", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 94000, maxCount = 30}, + {name = "mantassin tail", chance = 7780}, + {name = "chain armor", chance = 5061}, + {id = 2229, chance = 990},--skull + {name = "small sapphire", chance = 990}, + {name = "two handed sword", chance = 810}, + {name = "stealth ring", chance = 710}, + {name = "fish fin", chance = 360} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -110, effect = CONST_ME_DRAWBLOOD} +} + +monster.defenses = { + defense = 15, + armor = 7 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/quara_pincher.lua b/data/monster/aquatics/quara_pincher.lua new file mode 100644 index 00000000000..5c1d89f853e --- /dev/null +++ b/data/monster/aquatics/quara_pincher.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Quara Pincher") +local monster = {} + +monster.description = "a quara pincher" +monster.experience = 1200 +monster.outfit = { + lookType = 77, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 245 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Calassa, Frozen Trench, Yalahar (Sunken Quarter)." + } + +monster.health = 1800 +monster.maxHealth = 1800 +monster.race = "blood" +monster.corpse = 6063 +monster.speed = 396 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Clank! Clank!", yell = false}, + {text = "Clap!", yell = false}, + {text = "Crrrk! Crrrk!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 50}, + {name = "platinum coin", chance = 40000}, + {name = "quara pincers", chance = 14285}, + {name = "great health potion", chance = 10630}, + {name = "small ruby", chance = 7761, maxCount = 2}, + {name = "halberd", chance = 6861}, + {name = "shrimp", chance = 5245, maxCount = 5}, + {name = "fish fin", chance = 1600}, + {name = "warrior helmet", chance = 1460}, + {name = "crown armor", chance = 280}, + {name = "glacier robe", chance = 120}, + {name = "giant shrimp", chance = 40} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -342, effect = CONST_ME_DRAWBLOOD}, + {name ="speed", interval = 2000, chance = 20, speedChange = -600, range = 1, effect = CONST_ME_MAGIC_RED, target = false, duration = 3000} +} + +monster.defenses = { + defense = 50, + armor = 50 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = -25}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/quara_pincher_scout.lua b/data/monster/aquatics/quara_pincher_scout.lua new file mode 100644 index 00000000000..e72aced092c --- /dev/null +++ b/data/monster/aquatics/quara_pincher_scout.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Quara Pincher Scout") +local monster = {} + +monster.description = "a quara pincher scout" +monster.experience = 600 +monster.outfit = { + lookType = 77, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 246 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Malada, Hrodmir Quara Scout Caves, Quara Grotto, Oramond." + } + +monster.health = 775 +monster.maxHealth = 775 +monster.race = "blood" +monster.corpse = 6063 +monster.speed = 156 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Clank! Clank!", yell = false}, + {text = "Clap!", yell = false}, + {text = "Crrrk! Crrrk!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 49000, maxCount = 100}, + {name = "gold coin", chance = 40000, maxCount = 29}, + {name = "quara pincers", chance = 9940}, + {name = "plate armor", chance = 4170}, + {name = "small ruby", chance = 3440}, + {name = "halberd", chance = 2070}, + {name = "fish fin", chance = 800}, + {name = "life crystal", chance = 790} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -240, effect = CONST_ME_DRAWBLOOD}, + {name ="speed", interval = 2000, chance = 20, speedChange = -600, range = 1, effect = CONST_ME_MAGIC_RED, target = false, duration = 3000} +} + +monster.defenses = { + defense = 45, + armor = 70 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/quara_predator.lua b/data/monster/aquatics/quara_predator.lua new file mode 100644 index 00000000000..30e6765d12c --- /dev/null +++ b/data/monster/aquatics/quara_predator.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Quara Predator") +local monster = {} + +monster.description = "a quara predator" +monster.experience = 1600 +monster.outfit = { + lookType = 20, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 237 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Calassa, Frozen Trench, Sunken Quarter, Alchemist Quarter (unreachable), \z + The Inquisition Quest, Seacrest Grounds." + } + +monster.health = 2200 +monster.maxHealth = 2200 +monster.race = "blood" +monster.corpse = 6067 +monster.speed = 450 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Rrrah!", yell = false}, + {text = "Rraaar!", yell = false}, + {text = "Gnarrr!", yell = false}, + {text = "Tcharrr!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 28000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 54}, + {name = "quara bone", chance = 9860}, + {name = "royal spear", chance = 9240, maxCount = 7}, + {name = "small diamond", chance = 5300, maxCount = 2}, + {name = "shrimp", chance = 4980, maxCount = 5}, + {name = "double axe", chance = 3011}, + {name = "fish fin", chance = 1920, maxCount = 1}, + {name = "great health potion", chance = 1040}, + {name = "relic sword", chance = 670}, + {name = "assassin star", chance = 530}, + {name = "glacier robe", chance = 440}, + {name = "skull helmet", chance = 390}, + {name = "giant shrimp", chance = 10} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -473, effect = CONST_ME_DRAWBLOOD} +} + +monster.defenses = { + defense = 45, + armor = 45, + {name ="speed", interval = 2000, chance = 15, speedChange = 270, effect = CONST_ME_MAGIC_GREEN, target = false, duration = 5000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 25, maxDamage = 75, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -25}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/quara_predator_scout.lua b/data/monster/aquatics/quara_predator_scout.lua new file mode 100644 index 00000000000..779a04c0219 --- /dev/null +++ b/data/monster/aquatics/quara_predator_scout.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Quara Predator Scout") +local monster = {} + +monster.description = "a quara predator scout" +monster.experience = 400 +monster.outfit = { + lookType = 20, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 238 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Malada, Hrodmir Quara Scout Caves, Quara Grotto, Oramond." + } + +monster.health = 890 +monster.maxHealth = 890 +monster.race = "blood" +monster.corpse = 6067 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Gnarrr!", yell = false}, + {text = "Tcharrr!", yell = false}, + {text = "Rrrah!", yell = false}, + {text = "Rraaar!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 60}, + {name = "gold coin", chance = 48000, maxCount = 72}, + {name = "quara bone", chance = 10150}, + {name = "scale armor", chance = 8960}, + {name = "double axe", chance = 5770}, + {name = "shrimp", chance = 5050, maxCount = 5}, + {name = "small diamond", chance = 5020, maxCount = 2}, + {name = "two handed sword", chance = 3010}, + {name = "fish fin", chance = 1080}, + {name = "northwind rod", chance = 960} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -193, effect = CONST_ME_DRAWBLOOD} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/renegade_quara_constrictor.lua b/data/monster/aquatics/renegade_quara_constrictor.lua new file mode 100644 index 00000000000..67e41f2e002 --- /dev/null +++ b/data/monster/aquatics/renegade_quara_constrictor.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Renegade Quara Constrictor") +local monster = {} + +monster.description = "a renegade quara constrictor" +monster.experience = 1250 +monster.outfit = { + lookType = 46, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1097 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Seacrest Grounds during a world change." + } + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "blood" +monster.corpse = 6065 +monster.speed = 380 +monster.manaCost = 670 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 79280, maxCount = 3}, + {name = "quara tentacle", chance = 15240}, + {name = "mind stone", chance = 6880}, + {name = "ring of healing", chance = 5580}, + {name = "great mana potion", chance = 5390, maxCount = 5}, + {name = "shrimp", chance = 5300, maxCount = 4}, + {name = "small amethyst", chance = 5200, maxCount = 2}, + {name = "small ruby", chance = 4650, maxCount = 2}, + {name = "assassin star", chance = 4460, maxCount = 7}, + {name = "vortex bolt", chance = 3720, maxCount = 10}, + {name = "violet crystal shard", chance = 1210}, + {name = "northwind rod", chance = 740}, + {name = "fish fin", chance = 370}, + {name = "piggy bank", chance = 190} +} + + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 60, attack = 40, effect = CONST_ME_DRAWBLOOD}, + {name ="quara constrictor freeze", interval = 2000, chance = 10, target = false}, + {name ="quara constrictor electrify", interval = 2000, chance = 10, range = 1, target = false} +} + +monster.defenses = { + defense = 20, + armor = 35, + {name ="combat", interval = 3000, chance = 35, type = COMBAT_HEALING, minDamage = 150, maxDamage = 300, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -25}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/renegade_quara_hydromancer.lua b/data/monster/aquatics/renegade_quara_hydromancer.lua new file mode 100644 index 00000000000..8943e64781c --- /dev/null +++ b/data/monster/aquatics/renegade_quara_hydromancer.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Renegade Quara Hydromancer") +local monster = {} + +monster.description = "a renegade quara hydromancer" +monster.experience = 1800 +monster.outfit = { + lookType = 47, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1098 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Seacrest Grounds during a world change." + } + +monster.health = 2000 +monster.maxHealth = 2000 +monster.race = "blood" +monster.corpse = 6066 +monster.speed = 490 +monster.manaCost = 330 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 78000, maxCount = 4}, + {name = "quara eye", chance = 20160}, + {name = "mind stone", chance = 10710}, + {name = "shrimp", chance = 7140, maxCount = 4}, + {name = "small topaz", chance = 6800, maxCount = 2}, + {name = "small emerald", chance = 6450, maxCount = 2}, + {name = "great mana potion", chance = 5880, maxCount = 2}, + {name = "spirit cloak", chance = 5650}, + {name = "great health potion", chance = 4950, maxCount = 2}, + {name = "yellow piece of cloth", chance = 3230}, + {name = "green crystal shard", chance = 3000}, + {name = "green piece of cloth", chance = 2880}, + {name = "life ring", chance = 2190}, + {name = "fish fin", chance = 1380}, + {id = 7632, chance = 1150}, -- giant shimmering pearl + {name = "wand of cosmic energy", chance = 1150}, + {name = "green gem", chance = 460}, + {name = "knight armor", chance = 460} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 110, attack = 90, effect = CONST_ME_DRAWBLOOD, condition = {type = CONDITION_POISON, totalDamage = 5, interval = 4000}}, + {name ="speed", interval = 2000, chance = 15, speedChange = -350, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 15000} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 100, maxDamage = 120, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -25}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/renegade_quara_mantassin.lua b/data/monster/aquatics/renegade_quara_mantassin.lua new file mode 100644 index 00000000000..10491e55fdc --- /dev/null +++ b/data/monster/aquatics/renegade_quara_mantassin.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Renegade Quara Mantassin") +local monster = {} + +monster.description = "a renegade quara mantassin" +monster.experience = 1000 +monster.outfit = { + lookType = 72, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1099 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 100, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Seacrest Grounds during a world change." + } + +monster.health = 1200 +monster.maxHealth = 1200 +monster.race = "blood" +monster.corpse = 6064 +monster.speed = 590 +monster.manaCost = 330 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "mantassin tail", chance = 14490}, + {name = "mind stone", chance = 10370}, + {name = "shrimp", chance = 3950, maxCount = 3}, + {name = "small sapphire", chance = 3540, maxCount = 3}, + {name = "stealth ring", chance = 3290}, + {name = "ice rapier", chance = 2060}, + {name = "blue crystal shard", chance = 1890}, + {name = "strange helmet", chance = 1320}, + {name = "two handed sword", chance = 820}, + {name = "fish fin", chance = 740}, + {name = "blue robe", chance = 660}, + {name = "energy ring", chance = 580} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 40, attack = 55, effect = CONST_ME_DRAWBLOOD} +} + +monster.defenses = { + defense = 15, + armor = 16, + {name ="invisible", interval = 2000, chance = 20, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -25}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/renegade_quara_pincher.lua b/data/monster/aquatics/renegade_quara_pincher.lua new file mode 100644 index 00000000000..fdf7a52daf4 --- /dev/null +++ b/data/monster/aquatics/renegade_quara_pincher.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Renegade Quara Pincher") +local monster = {} + +monster.description = "a renegade quara pincher" +monster.experience = 2200 +monster.outfit = { + lookType = 77, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1100 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Seacrest Grounds during a world change." + } + +monster.health = 2800 +monster.maxHealth = 2800 +monster.race = "blood" +monster.corpse = 6063 +monster.speed = 396 +monster.manaCost = 330 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 80000, maxCount = 5}, + {name = "quara pincers", chance = 18800, maxCount = 1}, + {name = "great mana potion", chance = 9720, maxCount = 2}, + {name = "great health potion", chance = 9010, maxCount = 2}, + {name = "small ruby", chance = 9010, maxCount = 2}, + {name = "small diamond", chance = 7060, maxCount = 2}, + {name = "mind stone", chance = 6140}, + {name = "red gem", chance = 5120}, + {name = "shrimp", chance = 4810, maxCount = 5}, + {name = "vortex bolt", chance = 3790, maxCount = 5}, + {id = 7632, chance = 1430},--giant shimmering pearl(brown) + {name = "warrior helmet", chance = 1430}, + {name = "fish fin", chance = 920}, + {name = "crown armor", chance = 611}, + {id = 2169, chance = 410}, -- time ring + {name = "talon", chance = 310}, + {name = "glacier robe", chance = 200}, + {name = "giant shrimp", chance = 100}, + {name = "twiceslicer", chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 60, effect = CONST_ME_DRAWBLOOD}, + {name ="speed", interval = 2000, chance = 20, speedChange = -300, range = 1, effect = CONST_ME_MAGIC_RED, target = false, duration = 3000} +} + +monster.defenses = { + defense = 50, + armor = 50 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -25}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/renegade_quara_predator.lua b/data/monster/aquatics/renegade_quara_predator.lua new file mode 100644 index 00000000000..59a69899213 --- /dev/null +++ b/data/monster/aquatics/renegade_quara_predator.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Renegade Quara Predator") +local monster = {} + +monster.description = "a renegade quara predator" +monster.experience = 2700 +monster.outfit = { + lookType = 20, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1101 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Seacrest Grounds during a world change." + } + +monster.health = 3250 +monster.maxHealth = 3250 +monster.race = "blood" +monster.corpse = 6067 +monster.speed = 450 +monster.manaCost = 330 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 80000, maxCount = 4}, + {name = "quara bone", chance = 10000, maxCount = 1}, + {name = "royal spear", chance = 8000, maxCount = 7}, + {name = "great health potion", chance = 6680, maxCount = 2}, + {name = "mind stone", chance = 6440}, + {name = "assassin star", chance = 5233, maxCount = 10}, + {name = "shrimp", chance = 4510, maxCount = 5}, + {name = "small diamond", chance = 3140, maxCount = 3}, + {name = "fish fin", chance = 2101}, + {name = "blue crystal shard", chance = 1290}, + {name = "relic sword", chance = 1051}, + {name = "skull helmet", chance = 560}, + {name = "glacier robe", chance = 400}, + {name = "abyss hammer", chance = 320}, + {name = "frozen plate", chance = 160}, + {name = "giant shrimp", chance = 80} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 100, attack = 82, effect = CONST_ME_DRAWBLOOD} +} + +monster.defenses = { + defense = 45, + armor = 40, + {name ="speed", interval = 2000, chance = 15, speedChange = 30, effect = CONST_ME_MAGIC_GREEN, target = false, duration = 5000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 50, maxDamage = 100, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -25}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/aquatics/shark.lua b/data/monster/aquatics/shark.lua new file mode 100644 index 00000000000..03911d36b5b --- /dev/null +++ b/data/monster/aquatics/shark.lua @@ -0,0 +1,118 @@ +local mType = Game.createMonsterType("Shark") +local monster = {} + +monster.description = "a shark" +monster.experience = 700 +monster.outfit = { + lookType = 453, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 782 +monster.Bestiary = { + class = "Aquatic", + race = BESTY_RACE_AQUATIC, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 2, + Occurrence = 0, + Locations = "Fiehonja, Seacrest Grounds, Krailos Steppe underwater cave." + } + +monster.health = 1200 +monster.maxHealth = 1200 +monster.race = "blood" +monster.corpse = 15287 +monster.speed = 290 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Rarr chomp chomp!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 41000, maxCount = 38}, + {id = 2667, chance = 25430, maxCount = 4}, + {name = "deepling scales", chance = 9620}, + {name = "eye of a deepling", chance = 1200}, + {name = "small sapphire", chance = 1090}, + {id = 7632, chance = 390},--giant shimmering pearl (brown) + {name = "fish fin", chance = 161} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -175, effect = CONST_ME_DRAWBLOOD} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 55}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/birds/agressive_chicken.lua b/data/monster/birds/agressive_chicken.lua new file mode 100644 index 00000000000..97f83405163 --- /dev/null +++ b/data/monster/birds/agressive_chicken.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Agressive Chicken") +local monster = {} + +monster.description = "a agressive chicken" +monster.experience = 0 +monster.outfit = { + lookType = 111, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 15000 +monster.maxHealth = 15000 +monster.race = "blood" +monster.corpse = 6042 +monster.speed = 128 +monster.manaCost = 220 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Gokgoooook", yell = false}, + {text = "Cluck Cluck", yell = false} +} + +monster.loot = { + {name = "meat", chance = 2120, maxCount = 2}, + {id = 2695, chance = 950}, + {name = "worm", chance = 10000, maxCount = 3}, + {name = "chicken feather", chance = 20000} +} + +monster.defenses = { + defense = 5, + armor = 1 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/birds/agrestic_chicken.lua b/data/monster/birds/agrestic_chicken.lua new file mode 100644 index 00000000000..1bb1af76466 --- /dev/null +++ b/data/monster/birds/agrestic_chicken.lua @@ -0,0 +1,96 @@ +local mType = Game.createMonsterType("Agrestic Chicken") +local monster = {} + +monster.description = "a agrestic chicken" +monster.experience = 0 +monster.outfit = { + lookType = 111, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 15 +monster.maxHealth = 15 +monster.race = "blood" +monster.corpse = 6042 +monster.speed = 128 +monster.manaCost = 220 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10 +} + +monster.loot = { + {name = "meat", chance = 2120, maxCount = 2}, + {id = 2695, chance = 980, maxCount = 2}, + {name = "worm", chance = 11000, maxCount = 3}, + {name = "chicken feather", chance = 19000, maxCount = 2} +} + +monster.defenses = { + defense = 5, + armor = 1 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) \ No newline at end of file diff --git a/data/monster/birds/berserker_chicken.lua b/data/monster/birds/berserker_chicken.lua new file mode 100644 index 00000000000..4b759db4788 --- /dev/null +++ b/data/monster/birds/berserker_chicken.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Berserker Chicken") +local monster = {} + +monster.description = "a berserker chicken" +monster.experience = 220 +monster.outfit = { + lookType = 111, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 561 +monster.Bestiary = { + class = "Bird", + race = BESTY_RACE_BIRD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "Isle of Evil." + } + +monster.health = 465 +monster.maxHealth = 465 +monster.race = "blood" +monster.corpse = 6042 +monster.speed = 166 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Gokgoooook", yell = false}, + {text = "Cluck Cluck", yell = false}, + {text = "I will fill MY cushion with YOUR hair! CLUCK!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100} +} + +monster.attacks = { + {name ="melee", interval = 1200, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -100, range = 1, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DROWNDAMAGE, minDamage = -41, maxDamage = -70, effect = CONST_ME_EXPLOSIONAREA, target = false} +} + +monster.defenses = { + defense = 12, + armor = 12, + {name ="speed", interval = 1000, chance = 40, speedChange = 400, effect = CONST_ME_MAGIC_RED, target = false, duration = 8000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/birds/cave_parrot.lua b/data/monster/birds/cave_parrot.lua new file mode 100644 index 00000000000..e092d47da9c --- /dev/null +++ b/data/monster/birds/cave_parrot.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("Cave Parrot") +local monster = {} + +monster.description = "a cave parrot" +monster.experience = 0 +monster.outfit = { + lookType = 217, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1307 +monster.Bestiary = { + class = "Bird", + race = BESTY_RACE_BIRD, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Desecrated Glade." + } + +monster.health = 30 +monster.maxHealth = 30 +monster.race = "blood" +monster.corpse = 6056 +monster.speed = 320 +monster.manaCost = 250 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = false, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 25, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 5} +} + +monster.defenses = { + defense = 6, + armor = 2 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/birds/chicken.lua b/data/monster/birds/chicken.lua new file mode 100644 index 00000000000..e7ff7fea584 --- /dev/null +++ b/data/monster/birds/chicken.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Chicken") +local monster = {} + +monster.description = "a chicken" +monster.experience = 0 +monster.outfit = { + lookType = 111, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 111 +monster.Bestiary = { + class = "Bird", + race = BESTY_RACE_BIRD, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Sabrehaven, Rookgaard, The McRonalds Farm in Thais, Northport, \z + Fibula, Carlin (killable but unreachable), Greenshore, Krimhorn, Orc Fortress, \z + Factory Quarter, also theres one in the farm near Edron." + } + +monster.health = 15 +monster.maxHealth = 15 +monster.race = "blood" +monster.corpse = 6042 +monster.speed = 128 +monster.manaCost = 220 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = false, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Gokgoooook", yell = false}, + {text = "Cluck Cluck", yell = false} +} + +monster.loot = { + {name = "meat", chance = 2120, maxCount = 2}, + {id = 2695, chance = 950}, + {name = "worm", chance = 10000, maxCount = 3}, + {name = "chicken feather", chance = 20000} +} + +monster.defenses = { + defense = 5, + armor = 1 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/birds/demon_parrot.lua b/data/monster/birds/demon_parrot.lua new file mode 100644 index 00000000000..81c826a6c3d --- /dev/null +++ b/data/monster/birds/demon_parrot.lua @@ -0,0 +1,118 @@ +local mType = Game.createMonsterType("Demon Parrot") +local monster = {} + +monster.description = "a demon parrot" +monster.experience = 225 +monster.outfit = { + lookType = 217, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 562 +monster.Bestiary = { + class = "Bird", + race = BESTY_RACE_BIRD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "Isle of Evil." + } + +monster.health = 360 +monster.maxHealth = 360 +monster.race = "blood" +monster.corpse = 6056 +monster.speed = 320 +monster.manaCost = 250 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "ISHH THAT THE BESHHT YOU HAVE TO OFFERRR, TIBIANSHH?", yell = false}, + {text = "YOU ARRRRRE DOOMED!", yell = false}, + {text = "I SHHMELL FEEAARRR!", yell = false}, + {text = "MY SHHEED IS FEARRR AND MY HARRRVEST ISHH YOURRR SHHOUL!", yell = false}, + {text = "Your shhoooul will be mineee!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 81630, maxCount = 99} +} + +monster.attacks = { + {name ="melee", interval = 1200, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="drunk", interval = 1000, chance = 30, length = 5, spread = 3, effect = CONST_ME_SOUND_RED, target = false}, + {name ="combat", interval = 1000, chance = 30, type = COMBAT_LIFEDRAIN, minDamage = -25, maxDamage = -45, range = 5, shootEffect = CONST_ANI_SUDDENDEATH, target = false}, + {name ="combat", interval = 1000, chance = 30, type = COMBAT_LIFEDRAIN, minDamage = -15, maxDamage = -45, range = 1, target = false} +} + +monster.defenses = { + defense = 18, + armor = 18 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/birds/dire_penguin.lua b/data/monster/birds/dire_penguin.lua new file mode 100644 index 00000000000..a59f100015e --- /dev/null +++ b/data/monster/birds/dire_penguin.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("Dire Penguin") +local monster = {} + +monster.description = "a dire penguin" +monster.experience = 119 +monster.outfit = { + lookType = 250, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 335 +monster.Bestiary = { + class = "Bird", + race = BESTY_RACE_BIRD, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 3, + Locations = "Any place with penguins like, Formorgar Glacier, Helheim, Tyrsung or Svargrond. \z + Known spawn locations: west of Svargrond, up the Formorgar Glacier." + } + +monster.health = 173 +monster.maxHealth = 173 +monster.race = "blood" +monster.corpse = 7334 +monster.speed = 174 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grrrrrr", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 78260, maxCount = 10}, + {id = 2667, chance = 11040, maxCount = 3},--fish + {name = "rainbow trout", chance = 4800}, + {id = 2669, chance = 5900},--northern pike + {name = "green perch", chance = 6200} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -80}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -35, range = 7, radius = 1, shootEffect = CONST_ANI_SMALLSTONE, effect = CONST_ME_EXPLOSIONAREA, target = true}, + {name ="speed", interval = 2000, chance = 10, speedChange = -600, range = 7, radius = 4, effect = CONST_ME_POFF, target = false, duration = 9000} +} + +monster.defenses = { + defense = 16, + armor = 16, + {name ="speed", interval = 2000, chance = 15, speedChange = 310, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 3000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/birds/flamingo.lua b/data/monster/birds/flamingo.lua new file mode 100644 index 00000000000..99b419c9dbc --- /dev/null +++ b/data/monster/birds/flamingo.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Flamingo") +local monster = {} + +monster.description = "a flamingo" +monster.experience = 0 +monster.outfit = { + lookType = 212, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 212 +monster.Bestiary = { + class = "Bird", + race = BESTY_RACE_BIRD, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Tiquanda, Shattered Isles, Gardens of Night." + } + +monster.health = 25 +monster.maxHealth = 25 +monster.race = "blood" +monster.corpse = 6054 +monster.speed = 168 +monster.manaCost = 250 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = false, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 25, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "downy feather", chance = 1180} +} + +monster.defenses = { + defense = 5, + armor = 1 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/birds/marsh_stalker.lua b/data/monster/birds/marsh_stalker.lua new file mode 100644 index 00000000000..f21e2c5edbf --- /dev/null +++ b/data/monster/birds/marsh_stalker.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Marsh Stalker") +local monster = {} + +monster.description = "a marsh stalker" +monster.experience = 50 +monster.outfit = { + lookType = 530, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 914 +monster.Bestiary = { + class = "Bird", + race = BESTY_RACE_BIRD, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Venore swamp surface, Venore Salamander Cave, Dryad Gardens." + } + +monster.health = 100 +monster.maxHealth = 100 +monster.race = "blood" +monster.corpse = 19708 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Rrrawk! Rrrrawk!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 64090, maxCount = 23}, + {name = "meat", chance = 19950, maxCount = 2}, + {id = 2667, chance = 20320, maxCount = 2},--fish + {name = "worm", chance = 14730, maxCount = 2}, + {name = "marsh stalker feather", chance = 8650}, + {name = "longsword", chance = 7560}, + {name = "marsh stalker beak", chance = 6080}, + {id = 2120, chance = 4830},--rope + {name = "seeds", chance = 110} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -10}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -8, range = 7, radius = 1, shootEffect = CONST_ANI_EXPLOSION, effect = CONST_ME_EXPLOSIONAREA, target = true} +} + +monster.defenses = { + defense = 3, + armor = 3 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = -5}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/birds/parrot.lua b/data/monster/birds/parrot.lua new file mode 100644 index 00000000000..d53ce79406d --- /dev/null +++ b/data/monster/birds/parrot.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Parrot") +local monster = {} + +monster.description = "a parrot" +monster.experience = 0 +monster.outfit = { + lookType = 217, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 217 +monster.Bestiary = { + class = "Bird", + race = BESTY_RACE_BIRD, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "In the jungle of Tiquanda, Liberty Bay, the Shattered Isles, and as a house pet in Meriana." + } + +monster.health = 25 +monster.maxHealth = 25 +monster.race = "blood" +monster.corpse = 6056 +monster.speed = 320 +monster.manaCost = 250 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = false, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 25, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "BR? PL? SWE?", yell = false}, + {text = "Screeech!", yell = false}, + {text = "Neeewbiiieee!", yell = false}, + {text = "You advanshed, you advanshed!", yell = false}, + {text = "Hope you die and loooosh it!", yell = false}, + {text = "Hunterrr ish PK!", yell = false}, + {text = "Shhtop whining! Rraaah!", yell = false}, + {text = "I'm heeerrre! Screeeech!", yell = false}, + {text = "Leeave orrr hunted!!", yell = false}, + {text = "Blesshhh my stake! Screeech!", yell = false}, + {text = "Tarrrrp?", yell = false}, + {text = "You are corrrrupt! Corrrrupt!", yell = false}, + {text = "You powerrrrrrabuserrrrr!", yell = false}, + {text = "You advanshed, you advanshed!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -5} +} + +monster.defenses = { + defense = 5, + armor = 2 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/birds/penguin.lua b/data/monster/birds/penguin.lua new file mode 100644 index 00000000000..ef6f01d6e2f --- /dev/null +++ b/data/monster/birds/penguin.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("Penguin") +local monster = {} + +monster.description = "a penguin" +monster.experience = 1 +monster.outfit = { + lookType = 250, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 318 +monster.Bestiary = { + class = "Bird", + race = BESTY_RACE_BIRD, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "In and north of Formorgar Glacier, Nibelor, Helheim, Grimlund, south of Svargrond, Chyllfroest." + } + +monster.health = 33 +monster.maxHealth = 33 +monster.race = "blood" +monster.corpse = 7334 +monster.speed = 116 +monster.manaCost = 300 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 32, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2667, chance = 7830, maxCount = 2}, + {name = "rainbow trout", chance = 70}, + {name = "green perch", chance = 130} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -3} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/birds/pigeon.lua b/data/monster/birds/pigeon.lua new file mode 100644 index 00000000000..e914de1c65a --- /dev/null +++ b/data/monster/birds/pigeon.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Pigeon") +local monster = {} + +monster.description = "a pigeon" +monster.experience = 0 +monster.outfit = { + lookType = 531, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 915 +monster.Bestiary = { + class = "Bird", + race = BESTY_RACE_BIRD, + toKill = 25, + FirstUnlock = 5, + SecondUnlock = 10, + CharmsPoints = 1, + Stars = 1, + Occurrence = 1, + Locations = "Streets of Venore, Gardens of Night." + } + +monster.health = 30 +monster.maxHealth = 30 +monster.race = "blood" +monster.corpse = 19709 +monster.speed = 130 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 30, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Coooo! Cooo!", yell = false}, + {text = "Coo! Coooo! Coo! Cooo!", yell = false}, + {text = "Coo! Coo! Coooo!", yell = false} +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/birds/seagull.lua b/data/monster/birds/seagull.lua new file mode 100644 index 00000000000..81809f55989 --- /dev/null +++ b/data/monster/birds/seagull.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("Seagull") +local monster = {} + +monster.description = "a seagull" +monster.experience = 0 +monster.outfit = { + lookType = 223, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 264 +monster.Bestiary = { + class = "Bird", + race = BESTY_RACE_BIRD, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Various locations, sighted in the Shattered Isles, Venore, Thais, Femor Hills, \z + Cormaya, Edron Troll-Goblin Peninsula, Liberty Bay, Port Hope, Fibula, Drefia, Factory Quarter, \z + bordering Orc Fort, Rookgaard Premium Zone (not reachable), AbDendriel elf caves, \z + Northern coast of Tibia between Dalbrect and Northport." + } + +monster.health = 25 +monster.maxHealth = 25 +monster.race = "blood" +monster.corpse = 6076 +monster.speed = 320 +monster.manaCost = 250 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 11, + runHealth = 25, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -3} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/birds/terror_bird.lua b/data/monster/birds/terror_bird.lua new file mode 100644 index 00000000000..f3736a36df6 --- /dev/null +++ b/data/monster/birds/terror_bird.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Terror Bird") +local monster = {} + +monster.description = "a terror bird" +monster.experience = 150 +monster.outfit = { + lookType = 218, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 218 +monster.Bestiary = { + class = "Bird", + race = BESTY_RACE_BIRD, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Around Port Hope, Arena and Zoo Quarter in Yalahar, few on Zao steppes." + } + +monster.health = 300 +monster.maxHealth = 300 +monster.race = "blood" +monster.corpse = 6057 +monster.speed = 212 +monster.manaCost = 490 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "CRAAAHHH!", yell = false}, + {text = "Gruuuh Gruuuh.", yell = false}, + {text = "Carrah! Carrah!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 82430, maxCount = 30}, + {name = "meat", chance = 48550, maxCount = 3}, + {name = "terrorbird beak", chance = 10310}, + {name = "worm", chance = 9540, maxCount = 3}, + {name = "colourful feather", chance = 3090}, + {name = "health potion", chance = 690}, + {name = "seeds", chance = 280}, + {name = "feather headdress", chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -90} +} + +monster.defenses = { + defense = 13, + armor = 13 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/bosses/apocalypse.lua b/data/monster/bosses/apocalypse.lua new file mode 100644 index 00000000000..a2de7f8f52d --- /dev/null +++ b/data/monster/bosses/apocalypse.lua @@ -0,0 +1,166 @@ +local mType = Game.createMonsterType("Apocalypse") +local monster = {} + +monster.description = "Apocalypse" +monster.experience = 550000 +monster.outfit = { + lookType = 12, + lookHead = 38, + lookBody = 114, + lookLegs = 0, + lookFeet = 94, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 160000 +monster.maxHealth = 160000 +monster.race = "fire" +monster.corpse = 6068 +monster.speed = 380 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 40 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "BOW TO THE POWER OF THE RUTHLESS SEVEN!", yell = true}, + {text = "DESTRUCTION!", yell = true}, + {text = "CHAOS!", yell = true}, + {text = "DEATH TO ALL!", yell = true} +} + +monster.loot = { + {name = "ancient amulet", chance = 13500}, + {id = 2231, chance = 19000}, -- big bone + {name = "black pearl", chance = 15000, maxCount = 35}, + {name = "boots of haste", chance = 14000}, + {id = 2192, chance = 22500}, -- crystal ball + {name = "crystal necklace", chance = 21500}, + {id = 2124, chance = 15500}, -- crystal ring + {name = "demon shield", chance = 15500}, + {name = "devil helmet", chance = 11000}, + {name = "dragon hammer", chance = 34500}, + {name = "energy ring", chance = 13500}, + {name = "fire axe", chance = 17000}, + {name = "giant sword", chance = 12500}, + {name = "platinum coin", chance = 69900, maxCount = 100}, + {name = "platinum coin", chance = 68800, maxCount = 100}, + {name = "crystal coin", chance = 47700, maxCount = 40}, + {name = "crystal coin", chance = 36600, maxCount = 15}, + {name = "gold ring", chance = 28000}, + {name = "golden legs", chance = 15000}, + {name = "giant ruby", chance = 31500}, + {name = "giant sapphire", chance = 31500}, + {name = "giant emerald", chance = 31500}, + {name = "ice rapier", chance = 27500}, + {name = "magic plate armor", chance = 13000}, + {name = "mastermind shield", chance = 17500}, + {name = "purple tome", chance = 12600}, + {name = "ring of the sky", chance = 13500}, + {name = "silver dagger", chance = 15500}, + {name = "skull staff", chance = 25000}, + {name = "talon", chance = 14000, maxCount = 27}, + {name = "teddy bear", chance = 10500}, + {name = "thunder hammer", chance = 3500}, + {id = 3955, chance = 5100}, -- voodoo doll + {name = "white pearl", chance = 12500, maxCount = 35} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 230, attack = 210}, + {name ="combat", interval = 1000, chance = 8, type = COMBAT_DEATHDAMAGE, minDamage = -800, maxDamage = -1900, radius = 9, effect = CONST_ME_MORTAREA, target = false}, + {name ="speed", interval = 1000, chance = 12, speedChange = -850, radius = 6, effect = CONST_ME_POISONAREA, target = false, duration = 60000}, + {name ="strength", interval = 1000, chance = 10, minDamage = -600, maxDamage = -1450, radius = 5, effect = CONST_ME_HITAREA, target = false}, + {name ="combat", interval = 3000, chance = 13, type = COMBAT_FIREDAMAGE, minDamage = -300, maxDamage = -800, range = 7, radius = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 3000, chance = 8, type = COMBAT_MANADRAIN, minDamage = -600, maxDamage = -700, radius = 10, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_ENERGYDAMAGE, minDamage = -400, maxDamage = -800, length = 8, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 5000, chance = 18, minDamage = -800, maxDamage = -1000, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 2000, chance = 6, type = COMBAT_LIFEDRAIN, minDamage = -600, maxDamage = -1200, radius = 14, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.defenses = { + defense = 145, + armor = 188, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_HEALING, minDamage = 1000, maxDamage = 3000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 8, speedChange = 480, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/apprentice_sheng.lua b/data/monster/bosses/apprentice_sheng.lua new file mode 100644 index 00000000000..5cf7a2ef4d5 --- /dev/null +++ b/data/monster/bosses/apprentice_sheng.lua @@ -0,0 +1,137 @@ +local mType = Game.createMonsterType("Apprentice Sheng") +local monster = {} + +monster.description = "Apprentice Sheng" +monster.experience = 150 +monster.outfit = { + lookType = 23, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 95 +monster.maxHealth = 95 +monster.race = "blood" +monster.corpse = 5981 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Hyaena", chance = 30, interval = 5000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I will protect the secrets of my master!", yell = false}, + {text = "This isle will become ours alone", yell = false}, + {text = "Kaplar!", yell = false}, + {text = "You already know too much.", yell = false} +} + +monster.loot = { + {name = "minotaur leather", chance = 100000}, + {id = 2162, chance = 76000},-- magic light wand + {name = "gold coin", chance = 38000, maxCount = 10}, + {id = 2050, chance = 30000, maxCount = 2},-- torch + {name = "leather legs", chance = 23000}, + {id = 2684, chance = 7690},-- carrot + {name = "leather helmet", chance = 7690}, + {name = "knife", chance = 7690} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -10}, + {name ="energyfield", interval = 1000, chance = 8, range = 7, radius = 1, shootEffect = CONST_ANI_ENERGY, target = true}, + {name ="combat", interval = 1000, chance = 14, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -25, range = 7, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = 0, maxDamage = -45, range = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = false} +} + +monster.defenses = { + defense = 13, + armor = 12, + {name ="combat", interval = 4000, chance = 15, type = COMBAT_HEALING, minDamage = 10, maxDamage = 20, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/armenius.lua b/data/monster/bosses/armenius.lua new file mode 100644 index 00000000000..7b0f9506a2e --- /dev/null +++ b/data/monster/bosses/armenius.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Armenius") +local monster = {} + +monster.description = "Armenius" +monster.experience = 500 +monster.outfit = { + lookType = 68, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 550 +monster.maxHealth = 550 +monster.race = "undead" +monster.corpse = 6006 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You know what, I changed my mind. BRING IT!", yell = false} +} + +monster.loot = { + {id = 2534, chance = 5230} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 50}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -50, maxDamage = -200, range = 1, radius = 1, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="speed", interval = 2000, chance = 15, speedChange = -400, radius = 1, effect = CONST_ME_MAGIC_RED, target = false, duration = 60000} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="outfit", interval = 2000, chance = 10, effect = CONST_ME_GROUNDSHAKER, target = false, duration = 5000, outfitMonster = "bat"}, + {name ="speed", interval = 2000, chance = 15, speedChange = 300, effect = CONST_ME_MAGIC_RED, target = false, duration = 3000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 15, maxDamage = 25, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -50}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/bazir.lua b/data/monster/bosses/bazir.lua new file mode 100644 index 00000000000..f7df6a8e8c1 --- /dev/null +++ b/data/monster/bosses/bazir.lua @@ -0,0 +1,199 @@ +local mType = Game.createMonsterType("Bazir") +local monster = {} + +monster.description = "Bazir" +monster.experience = 300000 +monster.outfit = { + lookType = 35, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 110000 +monster.maxHealth = 110000 +monster.race = "fire" +monster.corpse = 2916 +monster.speed = 530 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 3000, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "bazir", chance = 15, interval = 1000, max = 1} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "COME HERE! FREE ITEMS FOR EVERYONE!", yell = true}, + {text = "BOW TO THE POWER OF THE RUTHLESS SEVEN!", yell = false}, + {text = "Slay your friends and I will spare you!", yell = true}, + {text = "DON'T BE AFRAID! I AM COMING IN PEACE!", yell = true} +} + +monster.loot = { + {id = 2142, chance = 3500}, + {id = 2231, chance = 9000}, + {id = 2144, chance = 15000, maxCount = 15}, + {id = 2158, chance = 1500}, + {id = 2195, chance = 4000}, + {id = 2186, chance = 3500}, + {id = 2192, chance = 2500}, + {id = 2125, chance = 1500}, + {id = 2124, chance = 5500}, + {id = 2520, chance = 15500}, + {id = 2462, chance = 11000}, + {id = 2387, chance = 20000}, + {id = 2434, chance = 4500}, + {id = 2167, chance = 13500}, + {id = 2432, chance = 17000}, + {id = 2393, chance = 12500}, + {id = 2148, chance = 99900, maxCount = 100}, + {id = 2148, chance = 88800, maxCount = 100}, + {id = 2148, chance = 77700, maxCount = 100}, + {id = 2148, chance = 66600, maxCount = 100}, + {id = 2179, chance = 8000}, + {id = 2470, chance = 5000}, + {id = 2033, chance = 7500}, + {id = 2418, chance = 4500}, + {id = 2182, chance = 3500}, + {id = 2155, chance = 1500}, + {id = 2188, chance = 2500}, + {id = 2396, chance = 7500}, + {id = 2177, chance = 1000}, + {id = 2162, chance = 11500}, + {id = 2472, chance = 3000}, + {id = 2514, chance = 7500}, + {id = 2164, chance = 5000}, + {id = 2178, chance = 4000}, + {id = 2176, chance = 12000}, + {id = 2171, chance = 4500}, + {id = 2200, chance = 4500}, + {id = 1982, chance = 2600}, + {id = 2214, chance = 13000}, + {id = 2123, chance = 3500}, + {id = 2170, chance = 13000}, + {id = 2402, chance = 15500}, + {id = 2436, chance = 5000}, + {id = 2150, chance = 13500, maxCount = 20}, + {id = 2145, chance = 9500, maxCount = 5}, + {id = 2149, chance = 15500, maxCount = 10}, + {id = 2146, chance = 13500, maxCount = 10}, + {id = 2165, chance = 9500}, + {id = 2197, chance = 4000}, + {id = 2174, chance = 2500}, + {id = 2151, chance = 14000, maxCount = 7}, + {id = 2112, chance = 14500}, + {id = 2421, chance = 13500}, + {id = 2377, chance = 20000}, + {id = 3955, chance = 100}, + {id = 2185, chance = 3500}, + {id = 2143, chance = 12500, maxCount = 15} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 200, attack = 250}, + {name ="combat", interval = 1000, chance = 7, type = COMBAT_MANADRAIN, minDamage = -100, maxDamage = -1000, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_POFF, target = false}, + {name ="drunk", interval = 1000, chance = 7, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="strength", interval = 1000, chance = 9, range = 7, shootEffect = CONST_ANI_LARGEROCK, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="combat", interval = 1000, chance = 13, type = COMBAT_LIFEDRAIN, minDamage = -400, maxDamage = -700, radius = 8, effect = CONST_ME_LOSEENERGY, target = false}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -400, maxDamage = -700, radius = 8, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="speed", interval = 1000, chance = 12, speedChange = -1900, radius = 6, effect = CONST_ME_POISONAREA, target = false, duration = 60000}, + {name ="strength", interval = 1000, chance = 8, radius = 5, effect = CONST_ME_HITAREA, target = false}, + {name ="outfit", interval = 1000, chance = 2, radius = 8, effect = CONST_ME_LOSEENERGY, target = false, duration = 5000, outfitMonster = "demon"}, + {name ="outfit", interval = 1000, chance = 2, radius = 8, effect = CONST_ME_LOSEENERGY, target = false, duration = 5000, outfitItem = 3058}, + {name ="combat", interval = 1000, chance = 34, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -900, range = 7, radius = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -500, maxDamage = -850, length = 8, spread = 3, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 160, + armor = 160, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_HEALING, minDamage = 5000, maxDamage = 10000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_HEALING, minDamage = 2000, maxDamage = 3000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 1000, chance = 8, speedChange = 1901, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000}, + {name ="invisible", interval = 1000, chance = 4, effect = CONST_ME_MAGIC_BLUE}, + {name ="invisible", interval = 1000, chance = 17, effect = CONST_ME_MAGIC_BLUE}, + {name ="outfit", interval = 1000, chance = 2, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 7000, outfitItem = 2916} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/bibby_bloodbath.lua b/data/monster/bosses/bibby_bloodbath.lua new file mode 100644 index 00000000000..063c03dc25a --- /dev/null +++ b/data/monster/bosses/bibby_bloodbath.lua @@ -0,0 +1,139 @@ +local mType = Game.createMonsterType("Bibby Bloodbath") +local monster = {} + +monster.description = "Bibby Bloodbath" +monster.experience = 1500 +monster.outfit = { + lookType = 2, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1200 +monster.maxHealth = 1200 +monster.race = "blood" +monster.corpse = 6008 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Don't run, you'll just lose precious fat.", yell = false}, + {text = "Hex hex!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "platinum coin", chance = 100000, maxCount = 10}, + {name = "orcish axe", chance = 32910}, + {name = "two handed sword", chance = 24680}, + {name = "throwing star", chance = 19600, maxCount = 18}, + {name = "mana potion", chance = 15200, maxCount = 3}, + {name = "dark armor", chance = 14000}, + {name = "health potion", chance = 12000, maxCount = 3}, + {id = 2667, chance = 10300, maxCount = 1},-- fish + {name = "meat", chance = 10300}, + {name = "plate legs", chance = 8100}, + {name = "stealth ring", chance = 6960}, + {name = "magma amulet", chance = 5700}, + {name = "giant sword", chance = 3160}, + {name = "crusader helmet", chance = 1900}, + {name = "butcher's axe", chance = 1270}, + {id = 7395, chance = 1270}-- orc trophy +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, length = 5, spread = 3, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -300, radius = 3, effect = CONST_ME_BLOCKHIT, target = false, duration = 30000} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = -20}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/big_boss_trolliver.lua b/data/monster/bosses/big_boss_trolliver.lua new file mode 100644 index 00000000000..47aa849aa4c --- /dev/null +++ b/data/monster/bosses/big_boss_trolliver.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Big Boss Trolliver") +local monster = {} + +monster.description = "Big Boss Trolliver" +monster.experience = 105 +monster.outfit = { + lookType = 281, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 140 +monster.maxHealth = 140 +monster.race = "blood" +monster.corpse = 7926 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 5 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Troll Champion", chance = 30, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 64}, + {name = "meat", chance = 25000}, + {name = "hand axe", chance = 9650}, + {name = "leather boots", chance = 9000}, + {name = "silver amulet", chance = 5450}, + {name = "studded club", chance = 5450}, + {name = "spear", chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -45} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/black_knight.lua b/data/monster/bosses/black_knight.lua new file mode 100644 index 00000000000..18ce3f42170 --- /dev/null +++ b/data/monster/bosses/black_knight.lua @@ -0,0 +1,144 @@ +local mType = Game.createMonsterType("Black Knight") +local monster = {} + +monster.description = "a black knight" +monster.experience = 1600 +monster.outfit = { + lookType = 131, + lookHead = 95, + lookBody = 95, + lookLegs = 95, + lookFeet = 95, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 1800 +monster.maxHealth = 1800 +monster.race = "blood" +monster.corpse = 20355 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 80, + health = 10, + damage = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "MINE!", yell = true}, + {text = "NO PRISONERS!", yell = true}, + {text = "NO MERCY!", yell = true}, + {text = "By Bolg's blood!", yell = false}, + {text = "You're no match for me!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 23000, maxCount = 80}, + {name = "gold coin", chance = 23000, maxCount = 56}, + {name = "spear", chance = 30800, maxCount = 3}, + {name = "brown bread", chance = 21600, maxCount = 2}, + {id = 2120, chance = 16020},--rope + {name = "brass legs", chance = 12200}, + {name = "halberd", chance = 11850}, + {name = "plate armor", chance = 10370}, + {name = "steel helmet", chance = 11220}, + {name = "two handed sword", chance = 8470}, + {name = "battle hammer", chance = 6910}, + {name = "warrior helmet", chance = 4710}, + {name = "knight axe", chance = 2630}, + {name = "dark helmet", chance = 2430}, + {name = "dark armor", chance = 2020}, + {name = "knight legs", chance = 1050}, + {name = "knight armor", chance = 750}, + {name = "ruby necklace", chance = 750}, + {name = "lightning legs", chance = 580}, + {name = "boots of haste", chance = 400}, + {name = "dragon lance", chance = 290}, + {name = "piggy bank", chance = 120} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, range = 7, shootEffect = CONST_ANI_SPEAR, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 80}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 95}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/bullwark.lua b/data/monster/bosses/bullwark.lua new file mode 100644 index 00000000000..4e9695d6f77 --- /dev/null +++ b/data/monster/bosses/bullwark.lua @@ -0,0 +1,144 @@ +local mType = Game.createMonsterType("Bullwark") +local monster = {} + +monster.description = "Bullwark" +monster.experience = 16725 +monster.outfit = { + lookType = 607, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 65000 +monster.maxHealth = 65000 +monster.race = "blood" +monster.corpse = 23367 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 3 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 200}, + {name = "platinum coin", chance = 80000, maxCount = 5}, + {name = "great health potion", chance = 40000, maxCount = 5}, + {name = "great mana potion", chance = 40000, maxCount = 5}, + {name = "great spirit potion", chance = 40000, maxCount = 5}, + {name = "ham", chance = 35250, maxCount = 5}, + {name = "meat", chance = 35250, maxCount = 5}, + {name = "minotaur leather", chance = 26500, maxCount = 2}, + {name = "moohtant horn", chance = 21000, maxCount = 2}, + {name = "small diamond", chance = 17900, maxCount = 5}, + {name = "small emerald", chance = 16350, maxCount = 5}, + {name = "small ruby", chance = 15500, maxCount = 5}, + {name = "small sapphire", chance = 14200, maxCount = 5}, + {name = "giant pacifier", chance = 1920}, + {name = "moohtant cudgel", chance = 1800}, + {name = "red piece of cloth", chance = 1500}, + {name = "yellow gem", chance = 1200}, + {name = "one hit wonder", chance = 350} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 180, attack = 200}, + {name ="combat", interval = 2000, chance = 19, type = COMBAT_LIFEDRAIN, minDamage = -200, maxDamage = -400, radius = 6, effect = CONST_ME_MAGIC_RED, target = false}, + -- bleed + {name ="condition", type = CONDITION_BLEEDING, interval = 2000, chance = 9, minDamage = -400, maxDamage = -600, radius = 8, effect = CONST_ME_ICEATTACK, target = false}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_PHYSICALDAMAGE, minDamage = -250, maxDamage = -400, range = 7, radius = 6, shootEffect = CONST_ANI_LARGEROCK, effect = CONST_ME_STONES, target = true}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -400, range = 7, radius = 4, shootEffect = CONST_ANI_WHIRLWINDCLUB, effect = CONST_ME_EXPLOSIONHIT, target = true}, + {name ="bullwark paralyze", interval = 2000, chance = 6, target = false} +} + +monster.defenses = { + defense = 66, + armor = 48, + {name ="combat", interval = 2000, chance = 1, type = COMBAT_HEALING, minDamage = 4000, maxDamage = 6000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 11, speedChange = 660, effect = CONST_ME_HITAREA, target = false, duration = 7000}, + {name ="bullwark summon", interval = 2000, chance = 9, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/chikhaton.lua b/data/monster/bosses/chikhaton.lua new file mode 100644 index 00000000000..d908a6e5033 --- /dev/null +++ b/data/monster/bosses/chikhaton.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Chikhaton") +local monster = {} + +monster.description = "Chikhaton" +monster.experience = 30000 +monster.outfit = { + lookType = 361, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "blood" +monster.corpse = 12273 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 30 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Victis", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1130}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -500, range = 7, shootEffect = CONST_ANI_LARGEROCK, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 4000, chance = 15, type = COMBAT_HEALING, minDamage = 550, maxDamage = 850, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/clubarc_the_plunderer.lua b/data/monster/bosses/clubarc_the_plunderer.lua new file mode 100644 index 00000000000..94f6b3cb73b --- /dev/null +++ b/data/monster/bosses/clubarc_the_plunderer.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Clubarc The Plunderer") +local monster = {} + +monster.description = "Clubarc The Plunderer" +monster.experience = 400 +monster.outfit = { + lookType = 342, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 400 +monster.maxHealth = 400 +monster.race = "blood" +monster.corpse = 11254 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Orc arga Huummmak!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 53500, maxCount = 78}, + {name = "meat", chance = 23390}, + {name = "orcish axe", chance = 19350}, + {name = "shaggy tail", chance = 13700}, + {name = "disgusting trophy", chance = 4840}, + {name = "bow", chance = 3230}, + {name = "orc tooth", chance = 2420}, + {name = "silkweaver bow", chance = 2420}, + {name = "crossbow", chance = 1610} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -130}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -85, range = 7, shootEffect = CONST_ANI_ONYXARROW, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 11, minDamage = -8, maxDamage = -8, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="speed", interval = 2000, chance = 15, speedChange = 350, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -30}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = -5}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/custodian.lua b/data/monster/bosses/custodian.lua new file mode 100644 index 00000000000..d7a4cf7736a --- /dev/null +++ b/data/monster/bosses/custodian.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Custodian") +local monster = {} + +monster.description = "a custodian" +monster.experience = 27500 +monster.outfit = { + lookType = 1217, + lookHead = 1, + lookBody = 1, + lookLegs = 19, + lookFeet = 19, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 47000 +monster.maxHealth = 47000 +monster.race = "blood" +monster.corpse = 36758 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Small Sapphire", chance = 33500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -550}, + {name ="explosion wave", interval = 2000, chance = 14, minDamage = -450, maxDamage = -600, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = -400, maxDamage = -610, radius = 5, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_FIREDAMAGE, minDamage = -500, maxDamage = -730, radius = 4, effect = CONST_ME_FIREATTACK, target = false} +} + +monster.defenses = { + defense = 86, + armor = 86 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/dharalion.lua b/data/monster/bosses/dharalion.lua new file mode 100644 index 00000000000..0cb140d841a --- /dev/null +++ b/data/monster/bosses/dharalion.lua @@ -0,0 +1,147 @@ +local mType = Game.createMonsterType("Dharalion") +local monster = {} + +monster.description = "Dharalion" +monster.experience = 380 +monster.outfit = { + lookType = 203, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 380 +monster.maxHealth = 380 +monster.race = "blood" +monster.corpse = 6011 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 10, + health = 10, + damage = 20, + random = 60, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "demon skeleton", chance = 6, interval = 1000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Feel my wrath!", yell = false}, + {text = "No one will stop my ascension!", yell = false}, + {text = "You desecrated this temple!", yell = false}, + {text = "Muahahaha!", yell = false}, + {text = "My powers are divine!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "holy orchid", chance = 100000}, + {name = "elvish talisman", chance = 88000}, + {name = "elven astral observer", chance = 82000}, + {name = "yellow gem", chance = 41790}, + {name = "blank rune", chance = 25370, maxCount = 1}, + {name = "melon", chance = 22390}, + {name = "bread", chance = 16420}, + {name = "elven amulet", chance = 14930}, + {name = "great mana potion", chance = 13430}, + {name = "life crystal", chance = 13430}, + {name = "sling herb", chance = 8960}, + {id = 2369, chance = 7460},-- cornucopia + {name = "green tunic", chance = 4480}, + {name = "royal spear", chance = 1490, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 30, attack = 28}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_MANADRAIN, minDamage = -30, maxDamage = -60, range = 7, target = false}, + {name ="combat", interval = 1000, chance = 13, type = COMBAT_ENERGYDAMAGE, minDamage = -70, maxDamage = -90, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = -80, maxDamage = -151, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, target = false}, + {name ="effect", interval = 1000, chance = 13, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 25, + armor = 15, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_HEALING, minDamage = 90, maxDamage = 120, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 1000, chance = 7, speedChange = 300, effect = CONST_ME_MAGIC_RED, target = false, duration = 10000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/diblis_the_fair.lua b/data/monster/bosses/diblis_the_fair.lua new file mode 100644 index 00000000000..062897bc15e --- /dev/null +++ b/data/monster/bosses/diblis_the_fair.lua @@ -0,0 +1,137 @@ +local mType = Game.createMonsterType("Diblis The Fair") +local monster = {} + +monster.description = "Diblis The Fair" +monster.experience = 1800 +monster.outfit = { + lookType = 287, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "undead" +monster.corpse = 8937 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 5000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Banshee", chance = 50, interval = 4500} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I envy you to be slain by someone as beautiful as me.", yell = false}, + {text = "I will drain your ugly corpses of the last drop of blood.", yell = false}, + {text = "Not in my face you barbarian!", yell = false}, + {text = "My brides will feast on your souls!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000}, + {name = "vampire lord token", chance = 100000}, + {name = "blood preservation", chance = 94000}, + {name = "vampire shield", chance = 22000}, + {name = "strong health potion", chance = 18000}, + {name = "platinum coin", chance = 12000, maxCount = 5}, + {name = "ring of healing", chance = 12000}, + {id = 2229, chance = 12000}, + {name = "spellbook of lost souls", chance = 2000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 70, attack = 95}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -155, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_HEALING, minDamage = 100, maxDamage = 235, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 3000, chance = 25, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 40}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/diseased_bill.lua b/data/monster/bosses/diseased_bill.lua new file mode 100644 index 00000000000..69ff2a34f77 --- /dev/null +++ b/data/monster/bosses/diseased_bill.lua @@ -0,0 +1,127 @@ +local mType = Game.createMonsterType("Diseased Bill") +local monster = {} + +monster.description = "a diseased Bill" +monster.experience = 300 +monster.outfit = { + lookType = 299, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "venom" +monster.corpse = 8951 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "People like you are the plague and I'll be the cure!", yell = false}, + {text = "You all will pay for not helping me!", yell = false}, + {text = "Cough! Cough!", yell = false}, + {text = "Desolate! Everything is so desolate!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 28000, maxCount = 20} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -207, condition = {type = CONDITION_POISON, totalDamage = 4, interval = 4000}}, + {name ="combat", interval = 2000, chance = 100, type = COMBAT_LIFEDRAIN, minDamage = -90, maxDamage = -140, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="combat", interval = 1000, chance = 40, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -175, radius = 2, shootEffect = CONST_ANI_SMALLEARTH, target = false}, + {name ="speed", interval = 3000, chance = 40, speedChange = -900, effect = CONST_ME_MAGIC_RED, target = true, duration = 20000} +} + +monster.defenses = { + defense = 15, + armor = 10, + {name ="speed", interval = 10000, chance = 40, speedChange = 310, effect = CONST_ME_MAGIC_GREEN, target = false, duration = 20000}, + {name ="combat", interval = 5000, chance = 60, type = COMBAT_HEALING, minDamage = 50, maxDamage = 80, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 25}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 25}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 25}, + {type = COMBAT_HOLYDAMAGE , percent = 25}, + {type = COMBAT_DEATHDAMAGE , percent = 1} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/diseased_dan.lua b/data/monster/bosses/diseased_dan.lua new file mode 100644 index 00000000000..9dcae431fd1 --- /dev/null +++ b/data/monster/bosses/diseased_dan.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Diseased Dan") +local monster = {} + +monster.description = "a diseased Dan" +monster.experience = 300 +monster.outfit = { + lookType = 299, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 800 +monster.maxHealth = 800 +monster.race = "venom" +monster.corpse = 8951 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Where... Where am I?", yell = false}, + {text = "Is that you, Tom?", yell = false}, + {text = "Phew, what an awful smell ... oh, that's me.", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 28000, maxCount = 21} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -207, condition = {type = CONDITION_POISON, totalDamage = 4, interval = 4000}}, + {name ="combat", interval = 2000, chance = 100, type = COMBAT_LIFEDRAIN, minDamage = -90, maxDamage = -140, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="combat", interval = 1000, chance = 40, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -175, radius = 2, shootEffect = CONST_ANI_SMALLEARTH, target = false}, + {name ="speed", interval = 3000, chance = 40, speedChange = -900, effect = CONST_ME_MAGIC_RED, target = true, duration = 20000} +} + +monster.defenses = { + defense = 15, + armor = 10, + {name ="speed", interval = 10000, chance = 40, speedChange = 310, effect = CONST_ME_MAGIC_GREEN, target = false, duration = 20000}, + {name ="combat", interval = 5000, chance = 60, type = COMBAT_HEALING, minDamage = 50, maxDamage = 80, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 85}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/diseased_fred.lua b/data/monster/bosses/diseased_fred.lua new file mode 100644 index 00000000000..5875e49d5a6 --- /dev/null +++ b/data/monster/bosses/diseased_fred.lua @@ -0,0 +1,127 @@ +local mType = Game.createMonsterType("Diseased Fred") +local monster = {} + +monster.description = "a diseased Fred" +monster.experience = 300 +monster.outfit = { + lookType = 299, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1100 +monster.maxHealth = 1100 +monster.race = "venom" +monster.corpse = 8951 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You will suffer the same fate as I do!", yell = false}, + {text = "The pain! The pain!", yell = false}, + {text = "Stay away! I am contagious!", yell = false}, + {text = "The plague will get you!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 28000, maxCount = 17} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -207, condition = {type = CONDITION_POISON, totalDamage = 4, interval = 4000}}, + {name ="combat", interval = 2000, chance = 100, type = COMBAT_LIFEDRAIN, minDamage = -90, maxDamage = -140, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="combat", interval = 1000, chance = 40, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -175, radius = 2, shootEffect = CONST_ANI_SMALLEARTH, target = false}, + {name ="speed", interval = 3000, chance = 40, speedChange = -900, effect = CONST_ME_MAGIC_RED, target = true, duration = 20000} +} + +monster.defenses = { + defense = 15, + armor = 10, + {name ="speed", interval = 10000, chance = 40, speedChange = 310, effect = CONST_ME_MAGIC_GREEN, target = false, duration = 20000}, + {name ="combat", interval = 5000, chance = 60, type = COMBAT_HEALING, minDamage = 50, maxDamage = 80, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 15}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/ekatrix.lua b/data/monster/bosses/ekatrix.lua new file mode 100644 index 00000000000..dbab3872db0 --- /dev/null +++ b/data/monster/bosses/ekatrix.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Ekatrix") +local monster = {} + +monster.description = "Ekatrix" +monster.experience = 200 +monster.outfit = { + lookType = 54, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 500 +monster.maxHealth = 500 +monster.race = "blood" +monster.corpse = 20535 +monster.speed = 102 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 30, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 60}, + {name = "witch broom", chance = 100000}, + {name = "cape", chance = 64500}, + {id = 2129, chance = 41670}, + {name = "broom", chance = 37500}, + {name = "coat", chance = 37500}, + {name = "cookie", chance = 25000, maxCount = 10}, + {name = "star herb", chance = 11333}, + {name = "bag of apple slices", chance = 2940}, + {name = "necrotic rod", chance = 2940} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -20}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -30, maxDamage = -60, range = 5, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="firefield", interval = 2000, chance = 10, range = 5, radius = 1, shootEffect = CONST_ANI_FIRE, target = true} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/energized_raging_mage.lua b/data/monster/bosses/energized_raging_mage.lua new file mode 100644 index 00000000000..6ceb31d79db --- /dev/null +++ b/data/monster/bosses/energized_raging_mage.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Energized Raging Mage") +local monster = {} + +monster.description = "an energized raging mage" +monster.experience = 0 +monster.outfit = { + lookType = 423, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3500 +monster.maxHealth = 3500 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Golden Servant", chance = 50, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Behold the all permeating powers I draw from this gate!!", yell = false}, + {text = "ENERGY!!", yell = false}, + {text = "I FEEL, I FEEEEEL... OMNIPOTENCE!!", yell = false}, + {text = "MWAAAHAHAAA!! NO ONE!! NO ONE CAN DEFEAT MEEE!!!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="energized raging mage skill reducer", interval = 3000, chance = 15, target = false}, + {name ="energyfield", interval = 2000, chance = 20, range = 7, radius = 2, shootEffect = CONST_ANI_ENERGY, target = true}, + {name ="melee", interval = 2000, chance = 100, skill = 32, attack = 37}, + {name ="thunderstorm", interval = 2000, chance = 40, minDamage = -150, maxDamage = -230, range = 7, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_MANADRAIN, minDamage = -100, maxDamage = -210, range = 7, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -300, length = 8, spread = 3, effect = CONST_ME_BIGCLOUDS, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 155, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -50}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/fleshslicer.lua b/data/monster/bosses/fleshslicer.lua new file mode 100644 index 00000000000..32f4a6e9054 --- /dev/null +++ b/data/monster/bosses/fleshslicer.lua @@ -0,0 +1,117 @@ +local mType = Game.createMonsterType("Fleshslicer") +local monster = {} + +monster.description = "Fleshslicer" +monster.experience = 5500 +monster.outfit = { + lookType = 457, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5700 +monster.maxHealth = 5700 +monster.race = "blood" +monster.corpse = 15296 +monster.speed = 560 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 50 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -99} +} + +monster.defenses = { + defense = 20, + armor = 12 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/freegoiz.lua b/data/monster/bosses/freegoiz.lua new file mode 100644 index 00000000000..fce9347a7ca --- /dev/null +++ b/data/monster/bosses/freegoiz.lua @@ -0,0 +1,189 @@ +local mType = Game.createMonsterType("Freegoiz") +local monster = {} + +monster.description = "Freegoiz" +monster.experience = 350000 +monster.outfit = { + lookType = 12, + lookHead = 38, + lookBody = 114, + lookLegs = 0, + lookFeet = 94, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 80000 +monster.maxHealth = 80000 +monster.race = "fire" +monster.corpse = 6068 +monster.speed = 380 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "BOW TO THE POWER OF THE RUTHLESS SEVEN!", yell = true}, + {text = "DESTRUCTION!", yell = true}, + {text = "CHAOS!", yell = true}, + {text = "DEATH TO ALL!", yell = true} +} + +monster.loot = { + {id = 2142, chance = 3500}, + {id = 2231, chance = 9000}, + {id = 2144, chance = 15000, maxCount = 15}, + {id = 2158, chance = 1500}, + {id = 2195, chance = 4000}, + {id = 2192, chance = 2500}, + {id = 2125, chance = 1500}, + {id = 2124, chance = 5500}, + {id = 2520, chance = 15500}, + {id = 2462, chance = 11000}, + {id = 2387, chance = 20000}, + {id = 2434, chance = 4500}, + {id = 2167, chance = 13500}, + {id = 2432, chance = 17000}, + {id = 2393, chance = 12500}, + {id = 2148, chance = 99900, maxCount = 100}, + {id = 2148, chance = 88800, maxCount = 100}, + {id = 2148, chance = 77700, maxCount = 100}, + {id = 2148, chance = 66600, maxCount = 100}, + {id = 2179, chance = 8000}, + {id = 2470, chance = 5000}, + {id = 2033, chance = 7500}, + {id = 2418, chance = 4500}, + {id = 2155, chance = 1500}, + {id = 2396, chance = 7500}, + {id = 2177, chance = 1000}, + {id = 2162, chance = 11500}, + {id = 2472, chance = 3000}, + {id = 2514, chance = 7500}, + {id = 2164, chance = 5000}, + {id = 2178, chance = 4000}, + {id = 2186, chance = 3500}, + {id = 2176, chance = 12000}, + {id = 2171, chance = 4500}, + {id = 2200, chance = 4500}, + {id = 1982, chance = 2600}, + {id = 2214, chance = 13000}, + {id = 2123, chance = 3500}, + {id = 2170, chance = 13000}, + {id = 2402, chance = 15500}, + {id = 2436, chance = 5000}, + {id = 2150, chance = 13500, maxCount = 20}, + {id = 2145, chance = 9500, maxCount = 5}, + {id = 2149, chance = 15500, maxCount = 10}, + {id = 2146, chance = 13500, maxCount = 10}, + {id = 2182, chance = 3500}, + {id = 2165, chance = 9500}, + {id = 2197, chance = 4000}, + {id = 2174, chance = 2500}, + {id = 2151, chance = 14000, maxCount = 7}, + {id = 2112, chance = 14500}, + {id = 2421, chance = 13500}, + {id = 2377, chance = 20000}, + {id = 2185, chance = 3500}, + {id = 3955, chance = 100}, + {id = 2188, chance = 2500}, + {id = 2143, chance = 12500, maxCount = 15} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 230, attack = 210}, + {name ="combat", interval = 1000, chance = 8, type = COMBAT_DEATHDAMAGE, minDamage = -800, maxDamage = -1900, radius = 9, effect = CONST_ME_MORTAREA, target = false}, + {name ="speed", interval = 1000, chance = 12, speedChange = -850, radius = 6, effect = CONST_ME_POISONAREA, target = false, duration = 60000}, + {name ="strength", interval = 1000, chance = 10, minDamage = -600, maxDamage = -1450, radius = 5, effect = CONST_ME_HITAREA, target = false}, + {name ="combat", interval = 3000, chance = 13, type = COMBAT_FIREDAMAGE, minDamage = -300, maxDamage = -800, range = 7, radius = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 3000, chance = 8, type = COMBAT_MANADRAIN, minDamage = -600, maxDamage = -700, radius = 10, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_ENERGYDAMAGE, minDamage = -400, maxDamage = -800, length = 8, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 5000, chance = 18, minDamage = -800, maxDamage = -1000, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 2000, chance = 6, type = COMBAT_LIFEDRAIN, minDamage = -600, maxDamage = -1200, radius = 14, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.defenses = { + defense = 145, + armor = 188, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_HEALING, minDamage = 1000, maxDamage = 3000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 8, speedChange = 480, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/gaffir.lua b/data/monster/bosses/gaffir.lua new file mode 100644 index 00000000000..efa51db5aef --- /dev/null +++ b/data/monster/bosses/gaffir.lua @@ -0,0 +1,147 @@ +local mType = Game.createMonsterType("Gaffir") +local monster = {} + +monster.description = "a gaffir" +monster.experience = 25000 +monster.outfit = { + lookType = 1217, + lookHead = 34, + lookBody = 129, + lookLegs = 113, + lookFeet = 19, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 54500 +monster.maxHealth = 54500 +monster.race = "blood" +monster.corpse = 36142 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Black Cobra", chance = 10, interval = 2000, max = 1} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 17}, + {name = "small amethyst", chance = 33500, maxCount = 2}, + {name = "small ruby", chance = 33500, maxCount = 2}, + {name = "small sapphire", chance = 33500}, + {name = "small topaz", chance = 33500}, + {name = "small diamond", chance = 33500}, + {name = "great spirit potion", chance = 26400}, + {name = "terra rod", chance = 24000, maxCount = 3}, + {name = "springsprout rod", chance = 21000}, + {name = "blue crystal shard", chance = 21000}, + {name = "blue gem", chance = 21000}, + {name = "cobra crest", chance = 12560}, + {name = "violet crystal shard", chance = 14800}, + {id = 7632, chance = 14520}, -- giant shimmering pearl + {name = "gold ingot", chance = 14500}, + {name = "spellbook of warding", chance = 6500}, + {name = "ring of healing", chance = 5400}, + {name = "terra hood", chance = 1600}, + {name = "amulet of loss", chance = 3400}, + {name = "wand of everblazing", chance = 2900}, + {name = "cobra wand", chance = 400} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -550}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_PHYSICALDAMAGE, minDamage = -450, maxDamage = -650, radius = 3, effect = CONST_ME_GROUNDSHAKER, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -400, maxDamage = -580, length = 5, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 3000, chance = 14, type = COMBAT_FIREDAMAGE, minDamage = -500, maxDamage = -750, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="combat", interval = 2000, chance = 16, type = COMBAT_EARTHDAMAGE, minDamage = -500, maxDamage = -620, radius = 4, shootEffect = CONST_ANI_EARTH, effect = CONST_ME_GREEN_RINGS, target = true}, + {name ="combat", interval = 3000, chance = 12, type = COMBAT_EARTHDAMAGE, minDamage = -320, maxDamage = -500, radius = 2, effect = CONST_ME_GREEN_RINGS, target = false} +} + +monster.defenses = { + defense = 83, + armor = 83 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/general_murius.lua b/data/monster/bosses/general_murius.lua new file mode 100644 index 00000000000..6c5d4d8fa0f --- /dev/null +++ b/data/monster/bosses/general_murius.lua @@ -0,0 +1,143 @@ +local mType = Game.createMonsterType("General Murius") +local monster = {} + +monster.description = "General Murius" +monster.experience = 450 +monster.outfit = { + lookType = 611, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 550 +monster.maxHealth = 550 +monster.race = "blood" +monster.corpse = 23462 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 20, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Minotaur Archer", chance = 15, interval = 1000, max = 2}, + {name = "Minotaur Guard", chance = 12, interval = 1000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You will get what you deserve!", yell = false}, + {text = "Feel the power of the Mooh'Tah!", yell = false}, + {text = "For the king!", yell = false}, + {text = "Guards!", yell = false} +} + +monster.loot = { + {name = "minotaur horn", chance = 100000, maxCount = 2}, + {name = "minotaur leather", chance = 100000}, + {name = "gold coin", chance = 92310, maxCount = 97}, + {name = "platinum coin", chance = 92310, maxCount = 3}, + {name = "brass armor", chance = 76920}, + {name = "double axe", chance = 76920}, + {name = "piercing bolt", chance = 38460, maxCount = 11}, + {name = "meat", chance = 30770}, + {name = "battle shield", chance = 23080}, + {name = "chain legs", chance = 23080}, + {id = 7401, chance = 23080},-- minotaur trophy + {name = "power bolt", chance = 23080, maxCount = 7}, + {name = "fishing rod", chance = 7690}, + {name = "strong health potion", chance = 7690} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -170}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -120, range = 7, shootEffect = CONST_ANI_BOLT, target = false}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -80, radius = 3, effect = CONST_ME_HITAREA, target = false} +} + +monster.defenses = { + defense = 22, + armor = 16, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_HEALING, minDamage = 50, maxDamage = 100, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 275, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/glitterscale.lua b/data/monster/bosses/glitterscale.lua new file mode 100644 index 00000000000..e1c42016077 --- /dev/null +++ b/data/monster/bosses/glitterscale.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("Glitterscale") +local monster = {} + +monster.description = "Glitterscale" +monster.experience = 700 +monster.outfit = { + lookType = 34, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "blood" +monster.corpse = 12545 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 40}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_FIREDAMAGE, minDamage = -90, maxDamage = -180, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_FIREDAMAGE, minDamage = -70, maxDamage = -120, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true} +} + +monster.defenses = { + defense = 18, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/grandfather_tridian.lua b/data/monster/bosses/grandfather_tridian.lua new file mode 100644 index 00000000000..21c0d818bdd --- /dev/null +++ b/data/monster/bosses/grandfather_tridian.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Grandfather Tridian") +local monster = {} + +monster.description = "Grandfather Tridian" +monster.experience = 1400 +monster.outfit = { + lookType = 193, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1800 +monster.maxHealth = 1800 +monster.race = "blood" +monster.corpse = 20391 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 50, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Crypt Shambler", chance = 10, interval = 2000}, + {name = "Ghost", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I will bring peace to your misguided soul!", yell = false}, + {text = "Your intrusion can't be tolerated!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 80}, + {name = "jewelled backpack", chance = 100000}, + {name = "strong mana potion", chance = 5000}, + {name = "brown mushroom", chance = 5000, maxCount = 3}, + {id = 6087, chance = 3000},--first verse + {id = 6088, chance = 3000},--second verse + {id = 6089, chance = 3000},--third verse + {id = 6090, chance = 3000}--fourth verse +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100, effect = CONST_ME_DRAWBLOOD}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_LIFEDRAIN, minDamage = -138, maxDamage = -362, range = 1, radius = 1, shootEffect = CONST_ANI_HOLY, effect = CONST_ME_HOLYAREA, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -50, range = 1, radius = 1, effect = CONST_ME_MAGIC_RED, target = true} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 60, maxDamage = 90, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_YELLOW_RINGS} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 80}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = -1}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/gravelord_oshuran.lua b/data/monster/bosses/gravelord_oshuran.lua new file mode 100644 index 00000000000..e03af9222c5 --- /dev/null +++ b/data/monster/bosses/gravelord_oshuran.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Gravelord Oshuran") +local monster = {} + +monster.description = "Gravelord Oshuran" +monster.experience = 2400 +monster.outfit = { + lookType = 99, + lookHead = 95, + lookBody = 116, + lookLegs = 119, + lookFeet = 115, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3100 +monster.maxHealth = 3100 +monster.race = "undead" +monster.corpse = 6028 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Bonebeast", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Your mortality is disgusting!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 115}, + {id = 7589, chance = 17500}, + {id = 2144, chance = 15960}, + {id = 2143, chance = 15000}, + {id = 2214, chance = 15040}, + {id = 2656, chance = 500}, + {id = 7893, chance = 900}, + {id = 8904, chance = 300}, + {id = 2175, chance = 4650} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250}, + {name ="speed", interval = 2000, chance = 25, speedChange = -300, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 30000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -180, maxDamage = -300, length = 7, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -100, maxDamage = -350, length = 7, spread = 3, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -200, maxDamage = -245, range = 1, effect = CONST_ME_MAGIC_RED, target = true} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 3000, chance = 15, type = COMBAT_HEALING, minDamage = 100, maxDamage = 120, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 80}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 35}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/groam.lua b/data/monster/bosses/groam.lua new file mode 100644 index 00000000000..650062f8e05 --- /dev/null +++ b/data/monster/bosses/groam.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Groam") +local monster = {} + +monster.description = "Groam" +monster.experience = 180 +monster.outfit = { + lookType = 413, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 400 +monster.maxHealth = 400 +monster.race = "blood" +monster.corpse = 13839 +monster.speed = 560 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 50 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 60, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I sjaw the eyes of the djeep!", yell = false}, + {text = "I mjake sjure yjou wjill njot sjufer the sjame fjate Ij djid!", yell = false}, + {text = "Yjou, intrjuder!!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 50}, + {name = "hunting spear", chance = 31250, maxCount = 4}, + {name = "life ring", chance = 25000}, + {name = "rusted armor", chance = 6250}, + {name = "fish fin", chance = 1500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 34, attack = 45}, + {name ="combat", interval = 1000, chance = 11, type = COMBAT_DROWNDAMAGE, minDamage = -15, maxDamage = -100, range = 5, shootEffect = CONST_ANI_SPEAR, effect = CONST_ME_LOSEENERGY, target = true} +} + +monster.defenses = { + defense = 20, + armor = 12 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -20}, + {type = COMBAT_ENERGYDAMAGE, percent = -20}, + {type = COMBAT_EARTHDAMAGE, percent = -20}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -20} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/guard_captain_quaid.lua b/data/monster/bosses/guard_captain_quaid.lua new file mode 100644 index 00000000000..9cffa62a347 --- /dev/null +++ b/data/monster/bosses/guard_captain_quaid.lua @@ -0,0 +1,138 @@ +local mType = Game.createMonsterType("Guard Captain Quaid") +local monster = {} + +monster.description = "a guard captain quaid" +monster.experience = 28000 +monster.outfit = { + lookType = 1217, + lookHead = 38, + lookBody = 57, + lookLegs = 21, + lookFeet = 2, + lookAddons = 2, + lookMount = 0 +} + +monster.health = 55000 +monster.maxHealth = 55000 +monster.race = "blood" +monster.corpse = 36489 +monster.speed = 185 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 20}, + {name = "leaf star", chance = 73000, maxCount = 2}, + {name = "throwing star", chance = 65000, maxCount = 6}, + {name = "hunting spear", chance = 62000}, + {name = "gold ingot", chance = 48000}, + {name = "blue gem", chance = 31000}, + {name = "yellow gem", chance = 31000}, + {name = "green crystal shard", chance = 8600}, + {id = 7632, chance = 28000},--giant shimmering pearl + {name = "cobra boots", chance = 315}, + {name = "cobra crest", chance = 11000}, + {name = "cobra hood", chance = 320}, + {name = "skull helmet", chance = 7500}, + {id = 26198, chance = 7200},-- collar of blue plasma + {name = "cobra crossbow", chance = 225} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -580}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_EARTHDAMAGE, minDamage = -500, maxDamage = -620, radius = 4, shootEffect = CONST_ANI_EARTH, effect = CONST_ME_GREEN_RINGS, target = true}, + {name ="combat", interval = 2000, chance = 22, type = COMBAT_PHYSICALDAMAGE, minDamage = -450, maxDamage = -700, shootEffect = CONST_ANI_THROWINGKNIFE, target = true}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_PHYSICALDAMAGE, minDamage = -350, maxDamage = -550, length = 5, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -400, maxDamage = -550, radius = 1, shootEffect = CONST_ANI_BURSTARROW, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -480, length = 5, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -450, radius = 3, effect = CONST_ME_GREEN_RINGS, target = false} +} + +monster.defenses = { + defense = 86, + armor = 86 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/hairman_the_huge.lua b/data/monster/bosses/hairman_the_huge.lua new file mode 100644 index 00000000000..fd589f025b1 --- /dev/null +++ b/data/monster/bosses/hairman_the_huge.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Hairman The Huge") +local monster = {} + +monster.description = "Hairman The Huge" +monster.experience = 335 +monster.outfit = { + lookType = 116, + lookHead = 20, + lookBody = 30, + lookLegs = 40, + lookFeet = 50, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 600 +monster.maxHealth = 600 +monster.race = "blood" +monster.corpse = 6043 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 14 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 60}, + {name = "club ring", chance = 25000}, + {name = "banana", chance = 25000, maxCount = 1} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 45, attack = 40} +} + +monster.defenses = { + defense = 25, + armor = 20, + {name ="speed", interval = 1000, chance = 7, speedChange = 260, effect = CONST_ME_MAGIC_RED, target = false, duration = 3000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 1}, + {type = COMBAT_ENERGYDAMAGE, percent = 1}, + {type = COMBAT_EARTHDAMAGE, percent = 1}, + {type = COMBAT_FIREDAMAGE, percent = 1}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -1}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -1} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/heoni.lua b/data/monster/bosses/heoni.lua new file mode 100644 index 00000000000..c3195a4926a --- /dev/null +++ b/data/monster/bosses/heoni.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Heoni") +local monster = {} + +monster.description = "Heoni" +monster.experience = 515 +monster.outfit = { + lookType = 239, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 900 +monster.maxHealth = 900 +monster.race = "blood" +monster.corpse = 12546 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Shriiiek", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 40, condition = {type = CONDITION_POISON, totalDamage = 480, interval = 4000}}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -20, maxDamage = -240, length = 8, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="drunk", interval = 2000, chance = 13, length = 8, spread = 3, effect = CONST_ME_SOUND_WHITE, target = false, duration = 25000} +} + +monster.defenses = { + defense = 18, + armor = 25, + {name ="combat", interval = 2000, chance = 11, type = COMBAT_HEALING, minDamage = 76, maxDamage = 84, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = 290, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/incredibly_old_witch.lua b/data/monster/bosses/incredibly_old_witch.lua new file mode 100644 index 00000000000..9d412be20f1 --- /dev/null +++ b/data/monster/bosses/incredibly_old_witch.lua @@ -0,0 +1,127 @@ +local mType = Game.createMonsterType("Incredibly Old Witch") +local monster = {} + +monster.description = "an incredibly old witch" +monster.experience = 0 +monster.outfit = { + lookType = 54, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 100 +monster.maxHealth = 100 +monster.race = "blood" +monster.corpse = 6081 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 100, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Feel the wrath of the witch!", yell = false}, + {text = "Oh how you will regret to have disturbed me!", yell = false}, + {text = "I will teach them all to leave me alone!", yell = false}, + {text = "Everyone is so stupid!", yell = false}, + {text = "Stupid people!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="outfit", interval = 4000, chance = 12, range = 7, radius = 4, effect = CONST_ME_MAGIC_BLUE, target = true, duration = 2000, outfitMonster = "rat"}, + {name ="outfit", interval = 4000, chance = 12, range = 7, radius = 4, effect = CONST_ME_MAGIC_BLUE, target = true, duration = 2000, outfitMonster = "chicken"}, + {name ="outfit", interval = 4000, chance = 12, range = 7, radius = 4, effect = CONST_ME_MAGIC_BLUE, target = true, duration = 2000, outfitMonster = "green frog"}, + {name ="outfit", interval = 4000, chance = 12, range = 7, radius = 4, effect = CONST_ME_MAGIC_BLUE, target = true, duration = 2000, outfitMonster = "bug"}, + {name ="outfit", interval = 4000, chance = 12, range = 7, radius = 4, effect = CONST_ME_MAGIC_BLUE, target = true, duration = 2000, outfitMonster = "pig"}, + {name ="outfit", interval = 4000, chance = 12, range = 7, radius = 4, effect = CONST_ME_MAGIC_BLUE, target = true, duration = 2000, outfitMonster = "kongra"}, + {name ="outfit", interval = 4000, chance = 12, range = 7, radius = 4, effect = CONST_ME_MAGIC_BLUE, target = true, duration = 2000, outfitMonster = "dog"}, + {name ="outfit", interval = 4000, chance = 12, range = 7, radius = 4, effect = CONST_ME_MAGIC_BLUE, target = true, duration = 2000, outfitMonster = "skunk"}, + {name ="outfit", interval = 4000, chance = 12, range = 7, radius = 4, effect = CONST_ME_MAGIC_BLUE, target = true, duration = 2000, outfitMonster = "donkey"} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/infernatil.lua b/data/monster/bosses/infernatil.lua new file mode 100644 index 00000000000..7cdc49cfa4f --- /dev/null +++ b/data/monster/bosses/infernatil.lua @@ -0,0 +1,195 @@ +local mType = Game.createMonsterType("Infernatil") +local monster = {} + +monster.description = "Infernatil" +monster.experience = 85000 +monster.outfit = { + lookType = 35, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 160000 +monster.maxHealth = 160000 +monster.race = "fire" +monster.corpse = 2916 +monster.speed = 605 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 2000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 3000, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "hellfire fighter", chance = 8, interval = 1000, max = 4} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Worship Zathroth pathetic mortal!", yell = false}, + {text = "Your soul will be mine!", yell = false}, + {text = "ASHES TO ASHES!", yell = true}, + {text = "YOU WILL ALL BURN!", yell = true}, + {text = "THE DAY OF RECKONING IS AT HAND!", yell = true}, + {text = "BOW TO THE POWER OF THE RUTHLESS SEVEN!", yell = true} +} + +monster.loot = { + {id = 2142, chance = 3500}, + {id = 2231, chance = 9000}, + {id = 2144, chance = 15000, maxCount = 15}, + {id = 2158, chance = 1500}, + {id = 2195, chance = 4000}, + {id = 2192, chance = 2500}, + {id = 2125, chance = 1500}, + {id = 2124, chance = 5500}, + {id = 2520, chance = 15500}, + {id = 2462, chance = 11000}, + {id = 2387, chance = 20000}, + {id = 2434, chance = 4500}, + {id = 2167, chance = 13500}, + {id = 2432, chance = 17000}, + {id = 2393, chance = 12500}, + {id = 2148, chance = 99900, maxCount = 100}, + {id = 2148, chance = 88800, maxCount = 100}, + {id = 2148, chance = 77700, maxCount = 100}, + {id = 2148, chance = 66600, maxCount = 100}, + {id = 2179, chance = 8000}, + {id = 2470, chance = 5000}, + {id = 2033, chance = 7500}, + {id = 2418, chance = 4500}, + {id = 2155, chance = 1500}, + {id = 2396, chance = 7500}, + {id = 2177, chance = 1000}, + {id = 2162, chance = 11500}, + {id = 2472, chance = 3000}, + {id = 2514, chance = 7500}, + {id = 2164, chance = 5000}, + {id = 2178, chance = 4000}, + {id = 2186, chance = 3500}, + {id = 2176, chance = 12000}, + {id = 2171, chance = 4500}, + {id = 2200, chance = 4500}, + {id = 1982, chance = 2600}, + {id = 2214, chance = 13000}, + {id = 2123, chance = 3500}, + {id = 2170, chance = 13000}, + {id = 2402, chance = 15500}, + {id = 2436, chance = 5000}, + {id = 2150, chance = 13500, maxCount = 20}, + {id = 2145, chance = 9500, maxCount = 5}, + {id = 2149, chance = 15500, maxCount = 10}, + {id = 2146, chance = 13500, maxCount = 10}, + {id = 2182, chance = 3500}, + {id = 2165, chance = 9500}, + {id = 2197, chance = 4000}, + {id = 2174, chance = 2500}, + {id = 2151, chance = 14000, maxCount = 7}, + {id = 2112, chance = 14500}, + {id = 2421, chance = 13500}, + {id = 2377, chance = 20000}, + {id = 2185, chance = 3500}, + {id = 3955, chance = 100}, + {id = 2188, chance = 2500}, + {id = 2143, chance = 12500, maxCount = 15} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 210, attack = 260}, + -- fire + {name ="condition", type = CONDITION_FIRE, interval = 1000, chance = 7, minDamage = -800, maxDamage = -1200, range = 2, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="combat", interval = 1000, chance = 7, type = COMBAT_PHYSICALDAMAGE, minDamage = -250, maxDamage = -750, radius = 6, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 1000, chance = 50, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -500, radius = 5, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="firefield", interval = 1000, chance = 4, radius = 8, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 1000, chance = 34, type = COMBAT_FIREDAMAGE, minDamage = -350, maxDamage = -850, range = 7, radius = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 1000, chance = 13, type = COMBAT_FIREDAMAGE, minDamage = -500, maxDamage = -1000, length = 8, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -300, maxDamage = -1500, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false} +} + +monster.defenses = { + defense = 150, + armor = 165, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_HEALING, minDamage = 5000, maxDamage = 10000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_HEALING, minDamage = 2000, maxDamage = 3000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 1000, chance = 10, speedChange = 1800, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/jesse_the_wicked.lua b/data/monster/bosses/jesse_the_wicked.lua new file mode 100644 index 00000000000..578e3b874a4 --- /dev/null +++ b/data/monster/bosses/jesse_the_wicked.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Jesse The Wicked") +local monster = {} + +monster.description = "Jesse The Wicked" +monster.experience = 180 +monster.outfit = { + lookType = 134, + lookHead = 76, + lookBody = 76, + lookLegs = 76, + lookFeet = 115, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 280 +monster.maxHealth = 280 +monster.race = "blood" +monster.corpse = 20434 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "That banker never saw it coming!", yell = false} +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 99}, + {name = "bag with stolen gold", chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/koshei_the_deathless.lua b/data/monster/bosses/koshei_the_deathless.lua new file mode 100644 index 00000000000..7b872b797cf --- /dev/null +++ b/data/monster/bosses/koshei_the_deathless.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Koshei The Deathless") +local monster = {} + +monster.description = "Koshei the Deathless" +monster.experience = 0 +monster.outfit = { + lookType = 99, + lookHead = 95, + lookBody = 116, + lookLegs = 119, + lookFeet = 115, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1200 +monster.maxHealth = 1200 +monster.race = "undead" +monster.corpse = 8272 +monster.speed = 390 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "bonebeast", chance = 21, interval = 1000, max = 1} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Your pain will be beyond imagination!", yell = false}, + {text = "You can't defeat me! I will resurrect and take your soul!", yell = false}, + {text = "Death is my ally!", yell = false}, + {text = "Welcome to my domain visitor!", yell = false}, + {text = "You will be my toy on the other side!", yell = false}, + {text = "You will endure agony beyond thy death!", yell = false}, + {text = "What a disgusting smell of life!", yell = false}, + {text = "Ahhh, your life energy tastes so delicious!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -170, condition = {type = CONDITION_POISON, totalDamage = 300, interval = 4000}}, + {name ="combat", interval = 3000, chance = 9, type = COMBAT_LIFEDRAIN, minDamage = -60, maxDamage = -250, range = 1, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 1000, chance = 11, type = COMBAT_LIFEDRAIN, minDamage = -70, maxDamage = -135, radius = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_DEATHDAMAGE, minDamage = -50, maxDamage = -140, length = 8, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + -- curse + {name ="condition", type = CONDITION_CURSED, interval = 3000, chance = 15, minDamage = -54, maxDamage = -54, range = 1, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -900, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 30000} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 1000, chance = 30, type = COMBAT_HEALING, minDamage = 150, maxDamage = 300, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 1}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = -50}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/kraknaknork's_demon.lua b/data/monster/bosses/kraknaknork's_demon.lua new file mode 100644 index 00000000000..d5afa7231de --- /dev/null +++ b/data/monster/bosses/kraknaknork's_demon.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Kraknaknork's Demon") +local monster = {} + +monster.description = "Kraknaknork's Demon" +monster.experience = 0 +monster.outfit = { + lookType = 12, + lookHead = 117, + lookBody = 58, + lookLegs = 117, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 120 +monster.maxHealth = 120 +monster.race = "fire" +monster.corpse = 6068 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "STEP A BIT CLOSER, RIGHT THERE, HAHAHA!", yell = true}, + {text = "COME AND DIE!", yell = true}, + {text = "ROOKIE FOR BREAKFAST", yell = true} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -499}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -10, maxDamage = -40, radius = 4, effect = CONST_ME_EXPLOSIONHIT, target = true} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/kraknaknork.lua b/data/monster/bosses/kraknaknork.lua new file mode 100644 index 00000000000..5be0d4d4963 --- /dev/null +++ b/data/monster/bosses/kraknaknork.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Kraknaknork") +local monster = {} + +monster.description = "Kraknaknork" +monster.experience = 300 +monster.outfit = { + lookType = 6, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 80 +monster.maxHealth = 80 +monster.race = "blood" +monster.corpse = 5978 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 23, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Weakened Demon", chance = 20, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "KRAK ORC DEMON", yell = false}, + {text = "???!!!", yell = false}, + {text = "Grak brrretz gulu.", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 95000, maxCount = 15}, + {name = "orc leather", chance = 4300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -10, condition = {type = CONDITION_POISON, totalDamage = 5, interval = 4000}}, + {name ="kraknaknork ice wave", interval = 2000, chance = 10, minDamage = -1, maxDamage = -15, target = false}, + {name ="kraknaknork poison wave", interval = 2000, chance = 10, minDamage = -1, maxDamage = -10, target = false}, + {name ="kraknaknork explosion wave", interval = 2000, chance = 10, minDamage = 0, maxDamage = -12, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -8, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="speed", interval = 1000, chance = 6, speedChange = -100, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000}, + {name ="outfit", interval = 2000, chance = 10, range = 7, target = false, duration = 3000, outfitMonster = "Sheep"} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/kroazur.lua b/data/monster/bosses/kroazur.lua new file mode 100644 index 00000000000..7289696baaa --- /dev/null +++ b/data/monster/bosses/kroazur.lua @@ -0,0 +1,140 @@ +local mType = Game.createMonsterType("Kroazur") +local monster = {} + +monster.description = "Kroazur" +monster.experience = 2700 +monster.outfit = { + lookType = 842, + lookHead = 19, + lookBody = 114, + lookLegs = 94, + lookFeet = 85, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 3000 +monster.maxHealth = 3000 +monster.race = "undead" +monster.corpse = 6325 +monster.speed = 500 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 98, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "fairy wings", chance = 100000}, + {name = "gold coin", chance = 100000, maxCount = 365}, + {name = "platinum coin", chance = 100000, maxCount = 7}, + {name = "strong health potion", chance = 91460, maxCount = 2}, + {name = "great health potion", chance = 76330, maxCount = 3}, + {name = "small enchanted amethyst", chance = 53560, maxCount = 5}, + {name = "ancient coin", chance = 46980, maxCount = 3}, + {name = "gemmed figurine", chance = 32030}, + {name = "small enchanted emerald", chance = 11003, maxCount = 5}, + {name = "small enchanted ruby", chance = 2000}, + {name = "silver token", chance = 10140}, + {name = "cluster of solace", chance = 9960}, + {name = "red crystal fragment", chance = 9960}, + {name = "small enchanted sapphire", chance = 8900}, + {name = "assassin star", chance = 8540}, + {name = "gold token", chance = 6580}, + {name = "gold ingot", chance = 6410}, + {name = "nightmare blade", chance = 3020} +} + +monster.attacks = { + {name ="melee", interval = 200, chance = 20, minDamage = 0, maxDamage = -650}, + {name ="combat", interval = 200, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -300, maxDamage = -500, target = false}, + {name ="combat", interval = 500, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -200, maxDamage = -300, length = 8, spread = 3, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 500, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -250, maxDamage = -300, radius = 8, effect = CONST_ME_MORTAREA, target = false} +} + +monster.defenses = { + defense = 65, + armor = 55, + {name ="combat", interval = 3000, chance = 35, type = COMBAT_HEALING, minDamage = 400, maxDamage = 500, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 320, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 80} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/lisa.lua b/data/monster/bosses/lisa.lua new file mode 100644 index 00000000000..3afd09f437a --- /dev/null +++ b/data/monster/bosses/lisa.lua @@ -0,0 +1,147 @@ +local mType = Game.createMonsterType("Lisa") +local monster = {} + +monster.description = "Lisa" +monster.experience = 18000 +monster.outfit = { + lookType = 604, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 65000 +monster.maxHealth = 65000 +monster.race = "venom" +monster.corpse = 23359 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 3 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "bowl of glooth soup", chance = 55000, maxCount = 5}, + {name = "glooth sandwich", chance = 34500, maxCount = 5}, + {name = "great health potion", chance = 33000, maxCount = 5}, + {name = "great mana potion", chance = 33000, maxCount = 5}, + {name = "great spirit potion", chance = 33000, maxCount = 5}, + {name = "glooth steak", chance = 28000, maxCount = 5}, + {name = "slimy leaf tentacle", chance = 22000, maxCount = 3}, + {name = "small amethyst", chance = 21000, maxCount = 5}, + {name = "small diamond", chance = 18000, maxCount = 5}, + {name = "small ruby", chance = 16000, maxCount = 5}, + {name = "small topaz", chance = 14800, maxCount = 5}, + {name = "glooth club", chance = 10500}, + {name = "glooth spear", chance = 9900}, + {name = "glooth whip", chance = 9500}, + {name = "glooth amulet", chance = 9000}, + {name = "glooth axe", chance = 8000}, + {name = "glooth blade", chance = 7000}, + {name = "glooth cape", chance = 6000}, + {name = "red gem", chance = 2600}, + {name = "yellow gem", chance = 2500}, + {name = "lisa's doll", chance = 300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 150, attack = 100, condition = {type = CONDITION_POISON, totalDamage = 900, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -200, maxDamage = -400, range = 7, radius = 1, shootEffect = CONST_ANI_GREENSTAR, effect = CONST_ME_MORTAREA, target = true}, + {name ="effect", interval = 2000, chance = 15, range = 7, radius = 6, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_BIGPLANTS, target = true}, + {name ="effect", interval = 2000, chance = 15, range = 7, radius = 6, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_PLANTATTACK, target = true}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_MANADRAIN, minDamage = -100, maxDamage = -200, radius = 8, effect = CONST_ME_POISONAREA, target = false}, + {name ="lisa paralyze", interval = 2000, chance = 12, target = false}, + {name ="lisa skill reducer", interval = 2000, chance = 15, target = false}, + {name ="lisa wave", interval = 2000, chance = 11, minDamage = -400, maxDamage = -900, target = false} +} + +monster.defenses = { + defense = 25, + armor = 15, + {name ="lisa summon", interval = 2000, chance = 5, target = false}, + {name ="lisa heal", interval = 1000, chance = 100, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/mad_mage.lua b/data/monster/bosses/mad_mage.lua new file mode 100644 index 00000000000..e810f6820ae --- /dev/null +++ b/data/monster/bosses/mad_mage.lua @@ -0,0 +1,147 @@ +local mType = Game.createMonsterType("Mad Mage") +local monster = {} + +monster.description = "a mad mage" +monster.experience = 1800 +monster.outfit = { + lookType = 394, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2500 +monster.maxHealth = 2500 +monster.race = "blood" +monster.corpse = 13603 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 5000, + chance = 30 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Golden Servant", chance = 10, interval = 1000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Did it not come to your mind that I placed them here for a reason?", yell = false}, + {text = "Now I have to create new servants! Do you want to spread this pest beyond these safe walls?", yell = false}, + {text = "What have you done!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 340}, + {id = 2152, chance = 48000, maxCount = 5}, + {id = 7589, chance = 21000, maxCount = 5}, + {id = 7588, chance = 17000, maxCount = 5}, + {id = 2178, chance = 9000}, + {id = 2165, chance = 6000}, + {id = 7368, chance = 4000, maxCount = 4}, + {id = 2792, chance = 4000, maxCount = 3}, + {id = 5911, chance = 5000}, + {id = 2150, chance = 4000, maxCount = 3}, + {id = 13756, chance = 1680, unique = true}, + {id = 7443, chance = 1100}, + {id = 9941, chance = 740}, + {id = 2195, chance = 2370}, + {id = 12410, chance = 370}, + {id = 2114, chance = 1370}, + {id = 2123, chance = 1370}, + {id = 8901, chance = 2370} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -30}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_FIREDAMAGE, minDamage = 0, maxDamage = -200, range = 7, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="combat", interval = 1400, chance = 24, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -120, range = 6, shootEffect = CONST_ANI_ICE, target = false}, + {name ="firefield", interval = 1600, chance = 20, range = 7, radius = 3, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -100, maxDamage = -200, radius = 4, effect = CONST_ME_BIGCLOUDS, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 35, maxDamage = 80, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -20}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/mad_technomancer.lua b/data/monster/bosses/mad_technomancer.lua new file mode 100644 index 00000000000..d40ebabd5d3 --- /dev/null +++ b/data/monster/bosses/mad_technomancer.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Mad Technomancer") +local monster = {} + +monster.description = "a mad technomancer" +monster.experience = 55 +monster.outfit = { + lookType = 66, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1800 +monster.maxHealth = 1800 +monster.race = "blood" +monster.corpse = 6015 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 500, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 150, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I love the smell of firebombs in the morning.", yell = false}, + {text = "I'm going to make them an offer they can't refuse.", yell = false}, + {text = "My masterplan cannot fail!", yell = false}, + {text = "Gentlemen, you can't fight here! This is the War Room!", yell = false} +} + +monster.loot = { + {id = 7699, chance = 1000000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 40}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -50, maxDamage = -120, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 1000, chance = 34, type = COMBAT_PHYSICALDAMAGE, minDamage = -55, maxDamage = -105, range = 7, shootEffect = CONST_ANI_LARGEROCK, target = false}, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_MANADRAIN, minDamage = -50, maxDamage = -80, range = 7, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 1000, chance = 50, type = COMBAT_HEALING, minDamage = 75, maxDamage = 325, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 60}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/morik_the_gladiator.lua b/data/monster/bosses/morik_the_gladiator.lua new file mode 100644 index 00000000000..5ac96c174c8 --- /dev/null +++ b/data/monster/bosses/morik_the_gladiator.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Morik The Gladiator") +local monster = {} + +monster.description = "Morik The Gladiator" +monster.experience = 160 +monster.outfit = { + lookType = 131, + lookHead = 57, + lookBody = 57, + lookLegs = 95, + lookFeet = 95, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 1235 +monster.maxHealth = 1235 +monster.race = "blood" +monster.corpse = 20454 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = true, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Gladiator", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "To be the one you'll have to beat the one!", yell = false}, + {text = "Where did I put my ultimate health potion again?", yell = false}, + {text = "I am the best!", yell = false}, + {text = "I'll take your ears as a trophy!", yell = false} +} + +monster.loot = { + {id = 9735, chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -110, radius = 3, effect = CONST_ME_HITAREA, target = false}, + {name ="drunk", interval = 3000, chance = 34, range = 7, shootEffect = CONST_ANI_WHIRLWINDSWORD, target = false, duration = 5000} +} + +monster.defenses = { + defense = 22, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -1} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/munster.lua b/data/monster/bosses/munster.lua new file mode 100644 index 00000000000..8a70b70a0c9 --- /dev/null +++ b/data/monster/bosses/munster.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Munster") +local monster = {} + +monster.description = "Munster" +monster.experience = 35 +monster.outfit = { + lookType = 56, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 58 +monster.maxHealth = 58 +monster.race = "blood" +monster.corpse = 2813 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 10000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Rat", chance = 20, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Meep!", yell = false}, + {text = "Meeeeep!", yell = false} +} + +monster.loot = { + {id = 2449, chance = 87000}, + {id = 2148, chance = 71000, maxCount = 22}, + {id = 2696, chance = 56000}, + {id = 3976, chance = 51000, maxCount = 4}, + {id = 2687, chance = 2500, maxCount = 2}, + {id = 5792, chance = 250} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -15} +} + +monster.defenses = { + defense = 4, + armor = 2 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/pythius_the_rotten.lua b/data/monster/bosses/pythius_the_rotten.lua new file mode 100644 index 00000000000..1d3b481738a --- /dev/null +++ b/data/monster/bosses/pythius_the_rotten.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Pythius The Rotten") +local monster = {} + +monster.description = "Pythius The Rotten" +monster.experience = 7000 +monster.outfit = { + lookType = 231, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 9000 +monster.maxHealth = 9000 +monster.race = "undead" +monster.corpse = 7349 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Undead Gladiator", chance = 10, interval = 1000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "YOU'LL NEVER GET MY TREASURE!", yell = true}, + {text = "MINIONS, MEET YOUR NEW BROTHER!", yell = true}, + {text = "YOU WILL REGRET THAT YOU ARE BORN!", yell = true}, + {text = "YOU MADE A HUGE WASTE!", yell = true} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -475}, + {name ="combat", interval = 2000, chance = 16, type = COMBAT_PHYSICALDAMAGE, minDamage = -165, maxDamage = -200, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_EARTHDAMAGE, minDamage = -55, maxDamage = -155, range = 7, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true}, + {name ="combat", interval = 2500, chance = 14, type = COMBAT_EARTHDAMAGE, minDamage = -333, maxDamage = -413, length = 8, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2500, chance = 22, type = COMBAT_MANADRAIN, minDamage = -85, maxDamage = -110, range = 7, radius = 4, shootEffect = CONST_ANI_ICE, target = true}, + {name ="speed", interval = 2000, chance = 20, speedChange = -300, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true, duration = 30000}, + -- curse + {name ="condition", type = CONDITION_CURSED, interval = 2000, chance = 15, range = 7, shootEffect = CONST_ANI_ICE, effect = CONST_ME_ICEATTACK, target = true} +} + +monster.defenses = { + defense = 45, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/raging_mage.lua b/data/monster/bosses/raging_mage.lua new file mode 100644 index 00000000000..ac3b89311b0 --- /dev/null +++ b/data/monster/bosses/raging_mage.lua @@ -0,0 +1,149 @@ +local mType = Game.createMonsterType("Raging mage") +local monster = {} + +monster.description = "a raging mage" +monster.experience = 3250 +monster.outfit = { + lookType = 416, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3500 +monster.maxHealth = 3500 +monster.race = "blood" +monster.corpse = 13834 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Golden Servant", chance = 50, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Behold the all permeating powers I draw from this gate!!", yell = false}, + {text = "ENERGY!!", yell = false}, + {text = "I WILL RETURN!! My death will just be a door to await my homecoming, my physical hull will be... my... argh...", yell = false} +} + +monster.loot = { + {id = 2148, chance = 97000, maxCount = 169}, + {id = 2152, chance = 77400, maxCount = 9}, + {id = 5911, chance = 31100}, + {id = 7591, chance = 26830, maxCount = 5}, + {id = 7590, chance = 23170, maxCount = 5}, + {id = 2178, chance = 9760}, + {id = 7443, chance = 6710, maxCount = 2}, + {id = 8871, chance = 4880}, + {id = 2165, chance = 4880}, + {id = 12410, chance = 4270}, + {id = 2792, chance = 3600, maxCount = 4}, + {id = 7368, chance = 1830, maxCount = 7}, + {id = 2124, chance = 1830}, + {id = 2123, chance = 1830}, + {id = 2146, chance = 1830, maxCount = 5}, + {id = 13940, chance = 1220}, + {id = 2114, chance = 1220}, + {id = 9958, chance = 1220}, + {id = 2195, chance = 610}, + {id = 9980, chance = 610}, + {id = 5741, chance = 610}, + {id = 8902, chance = 610} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -50}, + {name ="thunderstorm", interval = 2000, chance = 35, minDamage = -100, maxDamage = -200, range = 7, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_MANADRAIN, minDamage = -100, maxDamage = -200, range = 7, target = false}, + {name ="energyfield", interval = 2000, chance = 15, range = 7, radius = 2, shootEffect = CONST_ANI_ENERGY, target = true} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -25}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/raxias.lua b/data/monster/bosses/raxias.lua new file mode 100644 index 00000000000..c619d19215d --- /dev/null +++ b/data/monster/bosses/raxias.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Raxias") +local monster = {} + +monster.description = "a raxias" +monster.experience = 900 +monster.outfit = { + lookType = 980, + lookHead = 79, + lookBody = 114, + lookLegs = 82, + lookFeet = 79, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1100 +monster.maxHealth = 1100 +monster.race = "blood" +monster.corpse = 33427 +monster.speed = 50 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "This is a nightmare and you won't wake up!", yell = false}, + {text = "This was your last chance!", yell = false}, + {text = "Blood, fight and rage!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 60}, + {name = "gold coin", chance = 100000, maxCount = 40} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -1}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/renegade_orc.lua b/data/monster/bosses/renegade_orc.lua new file mode 100644 index 00000000000..abb937c4477 --- /dev/null +++ b/data/monster/bosses/renegade_orc.lua @@ -0,0 +1,134 @@ +local mType = Game.createMonsterType("Renegade Orc") +local monster = {} + +monster.description = "a renegade orc" +monster.experience = 270 +monster.outfit = { + lookType = 59, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 450 +monster.maxHealth = 450 +monster.race = "blood" +monster.corpse = 6001 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Harga puchak muhmak!", yell = false} +} + +monster.loot = { + {id = 2667, chance = 30000}, + {id = 2148, chance = 28000, maxCount = 35}, + {id = 12435, chance = 19000}, + {id = 2510, chance = 10000}, + {id = 2410, chance = 9850, maxCount = 4}, + {id = 2789, chance = 9650}, + {id = 2207, chance = 3920}, + {id = 2397, chance = 2800}, + {id = 7378, chance = 2600}, + {id = 2419, chance = 2100}, + {id = 11113, chance = 890}, + {id = 2413, chance = 830}, + {id = 7618, chance = 550}, + {id = 2647, chance = 420}, + {id = 2475, chance = 160} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -130}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -50, range = 7, shootEffect = CONST_ANI_THROWINGKNIFE, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -2} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/robby_the_reckless.lua b/data/monster/bosses/robby_the_reckless.lua new file mode 100644 index 00000000000..686b7d8c184 --- /dev/null +++ b/data/monster/bosses/robby_the_reckless.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("Robby The Reckless") +local monster = {} + +monster.description = "Robby The Reckless" +monster.experience = 110 +monster.outfit = { + lookType = 129, + lookHead = 76, + lookBody = 132, + lookLegs = 118, + lookFeet = 114, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 155 +monster.maxHealth = 155 +monster.race = "blood" +monster.corpse = 20498 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2152, chance = 100000, maxCount = 85}, + {id = 14903, chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -80} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/rukor_zad.lua b/data/monster/bosses/rukor_zad.lua new file mode 100644 index 00000000000..d9650128849 --- /dev/null +++ b/data/monster/bosses/rukor_zad.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Rukor Zad") +local monster = {} + +monster.description = "Rukor Zad" +monster.experience = 380 +monster.outfit = { + lookType = 152, + lookHead = 114, + lookBody = 95, + lookLegs = 95, + lookFeet = 95, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 380 +monster.maxHealth = 380 +monster.race = "blood" +monster.corpse = 20578 +monster.speed = 215 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I can kill a man in a thousand ways. And that`s only with a spoon!", yell = false}, + {text = "You shouldn`t have come here!", yell = false}, + {text = "Haiiii!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 93210, maxCount = 50}, + {id = 2399, chance = 9210, maxCount = 14}, + {id = 7366, chance = 6200, maxCount = 7}, + {id = 2457, chance = 4190}, + {id = 2509, chance = 1940} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -170}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -100, range = 7, shootEffect = CONST_ANI_THROWINGSTAR, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -100, range = 7, shootEffect = CONST_ANI_POISONARROW, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -8, maxDamage = -8, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false}, + {name ="drunk", interval = 3000, chance = 34, range = 7, target = false, duration = 5000} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/smuggler_baron_silvertoe.lua b/data/monster/bosses/smuggler_baron_silvertoe.lua new file mode 100644 index 00000000000..2c3f73eb956 --- /dev/null +++ b/data/monster/bosses/smuggler_baron_silvertoe.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Smuggler Baron Silvertoe") +local monster = {} + +monster.description = "Smuggler Baron Silvertoe" +monster.experience = 170 +monster.outfit = { + lookType = 134, + lookHead = 38, + lookBody = 0, + lookLegs = 94, + lookFeet = 95, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 280 +monster.maxHealth = 280 +monster.race = "blood" +monster.corpse = 20506 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Wild Warrior", chance = 20, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I will make your death look like an accident!", yell = false}, + {text = "You should not have interferred with my bussiness!", yell = false}, + {text = "Bribes are expensive, murder is cheap!", yell = false}, + {text = "I see some profit in your death!", yell = false}, + {text = "I expect you to die!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 80000, maxCount = 30}, + {id = 2406, chance = 10000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -50}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -40, range = 7, shootEffect = CONST_ANI_THROWINGKNIFE, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 10, maxDamage = 50, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/spider_queen.lua b/data/monster/bosses/spider_queen.lua new file mode 100644 index 00000000000..48474835b4a --- /dev/null +++ b/data/monster/bosses/spider_queen.lua @@ -0,0 +1,118 @@ +local mType = Game.createMonsterType("Spider Queen") +local monster = {} + +monster.description = "a spider queen" +monster.experience = 120 +monster.outfit = { + lookType = 219, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "venom" +monster.corpse = 6060 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name = "spider queen wrap", interval = 5000, chance = 100, target = true, range = 1} +} + +monster.defenses = { + defense = 5, + armor = 10, + {name ="speed", interval = 1000, chance = 10, speedChange = 480, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/splasher.lua b/data/monster/bosses/splasher.lua new file mode 100644 index 00000000000..811e47afb25 --- /dev/null +++ b/data/monster/bosses/splasher.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Splasher") +local monster = {} + +monster.description = "Splasher" +monster.experience = 500 +monster.outfit = { + lookType = 72, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1700 +monster.maxHealth = 1700 +monster.race = "blood" +monster.corpse = 6064 +monster.speed = 520 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Qua hah tsh!", yell = false}, + {text = "Teech tsha tshul!", yell = false}, + {text = "Quara tsha Fach!", yell = false}, + {text = "Tssssha Quara!", yell = false}, + {text = "Blubber.", yell = false}, + {text = "Blup.", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -109, condition = {type = CONDITION_POISON, totalDamage = 5, interval = 4000}}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_LIFEDRAIN, minDamage = -106, maxDamage = -169, range = 7, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="combat", interval = 2000, chance = 7, type = COMBAT_LIFEDRAIN, minDamage = -162, maxDamage = -228, length = 8, spread = 3, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_ICEDAMAGE, minDamage = -134, maxDamage = -148, length = 8, spread = 3, effect = CONST_ME_BUBBLES, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_ICEDAMAGE, minDamage = -101, maxDamage = -149, radius = 3, effect = CONST_ME_BUBBLES, target = false}, + {name ="speed", interval = 2000, chance = 20, speedChange = -300, range = 1, effect = CONST_ME_MAGIC_RED, target = false, duration = 3000} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 100, maxDamage = 120, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -25}, + {type = COMBAT_EARTHDAMAGE, percent = -15}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/teleskor.lua b/data/monster/bosses/teleskor.lua new file mode 100644 index 00000000000..780bfa4367e --- /dev/null +++ b/data/monster/bosses/teleskor.lua @@ -0,0 +1,127 @@ +local mType = Game.createMonsterType("Teleskor") +local monster = {} + +monster.description = "Teleskor" +monster.experience = 70 +monster.outfit = { + lookType = 298, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 80 +monster.maxHealth = 80 +monster.race = "undead" +monster.corpse = 5972 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Who Disturbs my slumber?", yell = false}, + {text = "Mourn the dead, do not hunt them!", yell = false} +} + +monster.loot = { + {id = 12437, chance = 100000}, + {id = 2148, chance = 81000, maxCount = 79}, + {id = 2398, chance = 72000}, + {id = 2473, chance = 72000}, + {id = 2511, chance = 45000}, + {id = 2050, chance = 36000}, + {id = 2388, chance = 27000}, + {id = 2376, chance = 27000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -30} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/the_abomination.lua b/data/monster/bosses/the_abomination.lua new file mode 100644 index 00000000000..a35ec805559 --- /dev/null +++ b/data/monster/bosses/the_abomination.lua @@ -0,0 +1,127 @@ +local mType = Game.createMonsterType("The Abomination") +local monster = {} + +monster.description = "the Abomination" +monster.experience = 25000 +monster.outfit = { + lookType = 238, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 38050 +monster.maxHealth = 38050 +monster.race = "venom" +monster.corpse = 6532 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Blubb", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2152, chance = 10000, maxCount = 3}, + {id = 6500, chance = 2857}, + {id = 5944, chance = 2500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 120}, + {name ="speed", interval = 1000, chance = 12, speedChange = -800, radius = 6, effect = CONST_ME_POISONAREA, target = false, duration = 10000}, + {name ="combat", interval = 1000, chance = 9, type = COMBAT_EARTHDAMAGE, minDamage = -200, maxDamage = -650, radius = 4, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 1000, chance = 11, type = COMBAT_LIFEDRAIN, minDamage = -400, maxDamage = -900, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_SOUND_GREEN, target = true}, + {name ="combat", interval = 2000, chance = 19, type = COMBAT_PHYSICALDAMAGE, minDamage = -350, maxDamage = -850, length = 7, spread = 3, shootEffect = CONST_ANI_POISON, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 1000, chance = 75, type = COMBAT_HEALING, minDamage = 505, maxDamage = 605, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/the_astral_source.lua b/data/monster/bosses/the_astral_source.lua new file mode 100644 index 00000000000..0e62a92e616 --- /dev/null +++ b/data/monster/bosses/the_astral_source.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("The Astral Source") +local monster = {} + +monster.description = "the astral source" +monster.experience = 3000 +monster.outfit = { + lookTypeEx = 26896 +} + +monster.health = 150000 +monster.maxHealth = 150000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 390 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "AstralSource" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -330}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -500, range = 7, radius = 6, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_PURPLEENERGY, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -500, range = 7, radius = 6, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -400, length = 5, spread = 3, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_MANADRAIN, minDamage = -200, maxDamage = -400, radius = 5, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.defenses = { + defense = 50, + armor = 50 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/the_blightfather.lua b/data/monster/bosses/the_blightfather.lua new file mode 100644 index 00000000000..ca8029d73e7 --- /dev/null +++ b/data/monster/bosses/the_blightfather.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("The Blightfather") +local monster = {} + +monster.description = "the Blightfather" +monster.experience = 400 +monster.outfit = { + lookType = 348, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 400 +monster.maxHealth = 400 +monster.race = "venom" +monster.corpse = 11375 +monster.speed = 290 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 12 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 80, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 2000, maxCount = 61}, + {id = 2148, chance = 2000, maxCount = 60}, + {id = 10609, chance = 17500}, + {id = 10557, chance = 12500}, + {id = 11372, chance = 7000}, + {id = 11374, chance = 400}, + {id = 2150, chance = 800} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 40, attack = 80} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="invisible", interval = 1000, chance = 10, effect = CONST_ME_MAGIC_RED} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/the_book_of_death.lua b/data/monster/bosses/the_book_of_death.lua new file mode 100644 index 00000000000..905e1dbe684 --- /dev/null +++ b/data/monster/bosses/the_book_of_death.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("The Book of Death") +local monster = {} + +monster.description = "The Book of Death" +monster.experience = 0 +monster.outfit = { + lookType = 1061, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/the_collector.lua b/data/monster/bosses/the_collector.lua new file mode 100644 index 00000000000..ba865ec764b --- /dev/null +++ b/data/monster/bosses/the_collector.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("The Collector") +local monster = {} + +monster.description = "the Collector" +monster.experience = 100 +monster.outfit = { + lookType = 261, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 340 +monster.maxHealth = 340 +monster.race = "undead" +monster.corpse = 10612 +monster.speed = 195 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 50, + targetDistance = 1, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Leave as long as you can.", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 100, attack = 40}, + {name ="speed", interval = 1000, chance = 13, speedChange = -800, length = 8, spread = 3, effect = CONST_ME_ENERGYHIT, target = false, duration = 20000}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -85, range = 7, shootEffect = CONST_ANI_LARGEROCK, target = false}, + {name ="melee", interval = 2000, chance = 15, minDamage = -10, maxDamage = -80} +} + +monster.defenses = { + defense = 26, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/the_evil_eye.lua b/data/monster/bosses/the_evil_eye.lua new file mode 100644 index 00000000000..48e6cd2d65e --- /dev/null +++ b/data/monster/bosses/the_evil_eye.lua @@ -0,0 +1,134 @@ +local mType = Game.createMonsterType("The Evil Eye") +local monster = {} + +monster.description = "the Evil Eye" +monster.experience = 750 +monster.outfit = { + lookType = 210, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1200 +monster.maxHealth = 1200 +monster.race = "blood" +monster.corpse = 6037 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 5 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 3, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "demon skeleton", chance = 13, interval = 1000, max = 5}, + {name = "ghost", chance = 12, interval = 1000, max = 4} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Inferior creatures, bow before my power!", yell = false}, + {text = "653768764!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 45}, + {id = 5898, chance = 5000}, + {id = 2148, chance = 80000, maxCount = 90} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 65, attack = 24}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -60, maxDamage = -130, range = 7, shootEffect = CONST_ANI_ENERGY, target = false}, + {name ="combat", interval = 1000, chance = 13, type = COMBAT_FIREDAMAGE, minDamage = -85, maxDamage = -115, range = 7, shootEffect = CONST_ANI_FIRE, target = false}, + {name ="combat", interval = 1000, chance = 17, type = COMBAT_PHYSICALDAMAGE, minDamage = -135, maxDamage = -175, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -40, maxDamage = -120, range = 7, shootEffect = CONST_ANI_POISON, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_LIFEDRAIN, minDamage = -110, maxDamage = -130, range = 7, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="speed", interval = 1000, chance = 10, speedChange = -850, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000}, + {name ="combat", interval = 1000, chance = 8, type = COMBAT_EARTHDAMAGE, minDamage = -35, maxDamage = -85, length = 8, spread = 3, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="combat", interval = 1000, chance = 6, type = COMBAT_LIFEDRAIN, minDamage = -75, maxDamage = -85, length = 8, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 1000, chance = 9, type = COMBAT_MANADRAIN, minDamage = -150, maxDamage = -250, length = 8, spread = 3, effect = CONST_ME_LOSEENERGY, target = false} +} + +monster.defenses = { + defense = 23, + armor = 19, + {name ="combat", interval = 1000, chance = 9, type = COMBAT_HEALING, minDamage = 1, maxDamage = 219, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -20}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/the_first_dragon.lua b/data/monster/bosses/the_first_dragon.lua new file mode 100644 index 00000000000..99ee6ee64c3 --- /dev/null +++ b/data/monster/bosses/the_first_dragon.lua @@ -0,0 +1,127 @@ +local mType = Game.createMonsterType("The First Dragon") +local monster = {} + +monster.description = "the first dragon" +monster.experience = 9000 +monster.outfit = { + lookType = 947, + lookHead = 94, + lookBody = 80, + lookLegs = 120, + lookFeet = 60, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "blood" +monster.corpse = 27733 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "First Dragon Death" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 120, attack = 130}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -410, maxDamage = -695, range = 5, radius = 5, effect = CONST_ME_FIREAREA, target = true}, + {name ="speed", interval = 2000, chance = 20, speedChange = -600, radius = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 10000}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -1010, maxDamage = -1995, length = 9, spread = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -410, maxDamage = -595, radius = 7, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -150, maxDamage = -280, radius = 6, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 64, + armor = 52, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 1500, maxDamage = 4500, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/the_frog_prince.lua b/data/monster/bosses/the_frog_prince.lua new file mode 100644 index 00000000000..f90b259a6e5 --- /dev/null +++ b/data/monster/bosses/the_frog_prince.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("The Frog Prince") +local monster = {} + +monster.description = "the Frog Prince" +monster.experience = 1 +monster.outfit = { + lookType = 224, + lookHead = 69, + lookBody = 66, + lookLegs = 69, + lookFeet = 66, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 55 +monster.maxHealth = 55 +monster.race = "venom" +monster.corpse = 6079 +monster.speed = 230 +monster.manaCost = 250 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = true, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Don't Kill me!!", yell = false}, + {text = "Have mercy!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 1} +} + +monster.defenses = { + defense = 2, + armor = 3 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 85}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 90}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/verminor.lua b/data/monster/bosses/verminor.lua new file mode 100644 index 00000000000..b1a8b651ed2 --- /dev/null +++ b/data/monster/bosses/verminor.lua @@ -0,0 +1,189 @@ +local mType = Game.createMonsterType("Verminor") +local monster = {} + +monster.description = "Verminor" +monster.experience = 35000 +monster.outfit = { + lookType = 12, + lookHead = 38, + lookBody = 114, + lookLegs = 0, + lookFeet = 94, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 80000 +monster.maxHealth = 80000 +monster.race = "fire" +monster.corpse = 6068 +monster.speed = 380 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "BOW TO THE POWER OF THE RUTHLESS SEVEN!", yell = true}, + {text = "DESTRUCTION!", yell = true}, + {text = "CHAOS!", yell = true}, + {text = "DEATH TO ALL!", yell = true} +} + +monster.loot = { + {id = 2142, chance = 3500}, + {id = 2231, chance = 9000}, + {id = 2144, chance = 15000, maxCount = 15}, + {id = 2158, chance = 1500}, + {id = 2195, chance = 4000}, + {id = 2192, chance = 2500}, + {id = 2125, chance = 1500}, + {id = 2124, chance = 5500}, + {id = 2520, chance = 15500}, + {id = 2462, chance = 11000}, + {id = 2387, chance = 20000}, + {id = 2434, chance = 4500}, + {id = 2167, chance = 13500}, + {id = 2432, chance = 17000}, + {id = 2393, chance = 12500}, + {id = 2148, chance = 99900, maxCount = 100}, + {id = 2148, chance = 88800, maxCount = 100}, + {id = 2148, chance = 77700, maxCount = 100}, + {id = 2148, chance = 66600, maxCount = 100}, + {id = 2179, chance = 8000}, + {id = 2470, chance = 5000}, + {id = 2033, chance = 7500}, + {id = 2418, chance = 4500}, + {id = 2155, chance = 1500}, + {id = 2396, chance = 7500}, + {id = 2177, chance = 1000}, + {id = 2162, chance = 11500}, + {id = 2472, chance = 3000}, + {id = 2514, chance = 7500}, + {id = 2164, chance = 5000}, + {id = 2178, chance = 4000}, + {id = 2186, chance = 3500}, + {id = 2176, chance = 12000}, + {id = 2171, chance = 4500}, + {id = 2200, chance = 4500}, + {id = 1982, chance = 2600}, + {id = 2214, chance = 13000}, + {id = 2123, chance = 3500}, + {id = 2170, chance = 13000}, + {id = 2402, chance = 15500}, + {id = 2436, chance = 5000}, + {id = 2150, chance = 13500, maxCount = 20}, + {id = 2145, chance = 9500, maxCount = 5}, + {id = 2149, chance = 15500, maxCount = 10}, + {id = 2146, chance = 13500, maxCount = 10}, + {id = 2182, chance = 3500}, + {id = 2165, chance = 9500}, + {id = 2197, chance = 4000}, + {id = 2174, chance = 2500}, + {id = 2151, chance = 14000, maxCount = 7}, + {id = 2112, chance = 14500}, + {id = 2421, chance = 13500}, + {id = 2377, chance = 20000}, + {id = 2185, chance = 3500}, + {id = 3955, chance = 100}, + {id = 2188, chance = 2500}, + {id = 2143, chance = 12500, maxCount = 15} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 230, attack = 210}, + {name ="combat", interval = 1000, chance = 8, type = COMBAT_DEATHDAMAGE, minDamage = -800, maxDamage = -1900, radius = 9, effect = CONST_ME_MORTAREA, target = false}, + {name ="speed", interval = 1000, chance = 12, speedChange = -850, radius = 6, effect = CONST_ME_POISONAREA, target = false, duration = 60000}, + {name ="strength", interval = 1000, chance = 10, minDamage = -600, maxDamage = -1450, radius = 5, effect = CONST_ME_HITAREA, target = false}, + {name ="combat", interval = 3000, chance = 13, type = COMBAT_FIREDAMAGE, minDamage = -300, maxDamage = -800, range = 7, radius = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 3000, chance = 8, type = COMBAT_MANADRAIN, minDamage = -600, maxDamage = -700, radius = 10, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_ENERGYDAMAGE, minDamage = -400, maxDamage = -800, length = 8, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 5000, chance = 18, minDamage = -800, maxDamage = -1000, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 2000, chance = 6, type = COMBAT_LIFEDRAIN, minDamage = -600, maxDamage = -1200, radius = 14, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.defenses = { + defense = 145, + armor = 188, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_HEALING, minDamage = 1000, maxDamage = 3000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 8, speedChange = 480, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/visco.lua b/data/monster/bosses/visco.lua new file mode 100644 index 00000000000..ab474607413 --- /dev/null +++ b/data/monster/bosses/visco.lua @@ -0,0 +1,147 @@ +local mType = Game.createMonsterType("Mutated Visco") +local monster = {} + +monster.description = "a mutated visco" +monster.experience = 9800 +monster.outfit = { + lookType = 554, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 28000 +monster.maxHealth = 28000 +monster.race = "blood" +monster.corpse = 21266 +monster.speed = 290 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 1500, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I'm Zulazza, and you won't forget me that fazzt.", yell = false}, + {text = "Oh, HE will take revenge on zzizz azzault when you zztep in front of HIZZ fazze!", yell = false} +} + +monster.loot = { + {id = 7591, chance = 30500}, + {id = 2152, chance = 41325, maxCount = 30}, + {id = 2148, chance = 49650, maxCount = 100}, + {id = 9808, chance = 50500}, + {id = 9971, chance = 33000, maxCount = 4}, + {id = 2158, chance = 30500}, + {id = 2155, chance = 20500}, + {id = 8473, chance = 10500}, + {id = 11118, chance = 5500}, + {id = 5944, chance = 19250, maxCount = 4}, + {id = 2528, chance = 15500}, + {id = 7366, chance = 8100, maxCount = 67}, + {id = 7632, chance = 28000, maxCount = 2}, + {id = 2154, chance = 15500}, + {id = 2156, chance = 10500}, + {id = 7440, chance = 10500}, + {id = 2153, chance = 25500}, + {id = 7590, chance = 20500}, + {id = 8882, chance = 5500}, + {id = 2514, chance = 5500}, + {id = 2127, chance = 10500}, + {id = 8891, chance = 5500}, + {id = 2515, chance = 5500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 200, attack = 200}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_PHYSICALDAMAGE, minDamage = -500, maxDamage = -1500, length = 8, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -1300, radius = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_MANADRAIN, minDamage = -50, maxDamage = -130, range = 7, effect = CONST_ME_MAGIC_GREEN, target = true}, + {name ="speed", interval = 2000, chance = 20, speedChange = -500, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000} +} + +monster.defenses = { + defense = 119, + armor = 96, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 2000, maxDamage = 3000, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 70}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/warlord_ruzad.lua b/data/monster/bosses/warlord_ruzad.lua new file mode 100644 index 00000000000..e60c045f1fc --- /dev/null +++ b/data/monster/bosses/warlord_ruzad.lua @@ -0,0 +1,134 @@ +local mType = Game.createMonsterType("Warlord Ruzad") +local monster = {} + +monster.description = "Warlord Ruzad" +monster.experience = 1700 +monster.outfit = { + lookType = 2, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "blood" +monster.corpse = 6008 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Orc Berserker", chance = 30, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 12435, chance = 25000}, + {id = 2148, chance = 18500, maxCount = 45}, + {id = 2399, chance = 14500, maxCount = 18}, + {id = 2667, chance = 11300, maxCount = 2}, + {id = 2428, chance = 5700}, + {id = 3965, chance = 5700}, + {id = 2463, chance = 5610}, + {id = 2647, chance = 4680}, + {id = 2419, chance = 4050}, + {id = 2200, chance = 2690}, + {id = 2377, chance = 2200}, + {id = 2490, chance = 1900}, + {id = 7891, chance = 750} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300} +} + +monster.defenses = { + defense = 35, + armor = 32 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 2}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/weakened_demon.lua b/data/monster/bosses/weakened_demon.lua new file mode 100644 index 00000000000..5a1b7162c0d --- /dev/null +++ b/data/monster/bosses/weakened_demon.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Weakened Demon") +local monster = {} + +monster.description = "a weakened demon" +monster.experience = 0 +monster.outfit = { + lookType = 12, + lookHead = 92, + lookBody = 0, + lookLegs = 95, + lookFeet = 100, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5 +monster.maxHealth = 5 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "UH?", yell = true} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = 0} +} + +monster.defenses = { + defense = 2, + armor = 2, + {name ="invisible", interval = 2000, chance = 20, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/weakened_shlorg.lua b/data/monster/bosses/weakened_shlorg.lua new file mode 100644 index 00000000000..c1827e71686 --- /dev/null +++ b/data/monster/bosses/weakened_shlorg.lua @@ -0,0 +1,145 @@ +local mType = Game.createMonsterType("Weakened Shlorg") +local monster = {} + +monster.description = "Weakened Shlorg" +monster.experience = 6500 +monster.outfit = { + lookType = 565, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "venom" +monster.corpse = 21299 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Tchhh!", yell = false}, + {text = "Slurp!", yell = false} +} + +monster.loot = { + {id = 21400, chance = 3000}, + {id = 2148, chance = 100000, maxCount = 105}, + {id = 2152, chance = 100000, maxCount = 8}, + {id = 21705, chance = 3000}, + {id = 21706, chance = 3000}, + {id = 2154, chance = 10000}, + {id = 2155, chance = 10000}, + {id = 8473, chance = 10000, maxCount = 3}, + {id = 8472, chance = 10000, maxCount = 3}, + {id = 7590, chance = 10000, maxCount = 3}, + {id = 2149, chance = 10000, maxCount = 5}, + {id = 9970, chance = 10000, maxCount = 5}, + {id = 8872, chance = 20000}, + {id = 5910, chance = 10000}, + {id = 5911, chance = 10000}, + {id = 5914, chance = 10000}, + {id = 2409, chance = 20000}, + {id = 8912, chance = 20000}, + {id = 8891, chance = 10000}, + {id = 10584, chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 150, attack = 50, condition = {type = CONDITION_POISON, totalDamage = 180, interval = 4000}}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -90, maxDamage = -180, length = 4, spread = 3, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -150, radius = 5, effect = CONST_ME_GREEN_RINGS, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 13, minDamage = -360, maxDamage = -440, radius = 5, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="shlorg paralyze", interval = 2000, chance = 11, target = false} +} + +monster.defenses = { + defense = 15, + armor = 10, + {name ="combat", interval = 2000, chance = 35, type = COMBAT_HEALING, minDamage = 95, maxDamage = 150, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/williwasp.lua b/data/monster/bosses/williwasp.lua new file mode 100644 index 00000000000..c8b078711d0 --- /dev/null +++ b/data/monster/bosses/williwasp.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Willi Wasp") +local monster = {} + +monster.description = "a wasp" +monster.experience = 250 +monster.outfit = { + lookType = 44, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 250 +monster.maxHealth = 250 +monster.race = "venom" +monster.corpse = 5989 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 20}, + {id = 5902, chance = 100000, maxCount = 3}, + {id = 2170, chance = 17650}, + {id = 2149, chance = 5880}, + {id = 21400, chance = 5000} +} + +monster.attacks = { + {name ="melee", interval = 1500, chance = 100, skill = 30, attack = 30, condition = {type = CONDITION_POISON, totalDamage = 25, interval = 4000}} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/yaga_the_crone.lua b/data/monster/bosses/yaga_the_crone.lua new file mode 100644 index 00000000000..9994dfd6f88 --- /dev/null +++ b/data/monster/bosses/yaga_the_crone.lua @@ -0,0 +1,137 @@ +local mType = Game.createMonsterType("Yaga The Crone") +local monster = {} + +monster.description = "Yaga The Crone" +monster.experience = 375 +monster.outfit = { + lookType = 54, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 620 +monster.maxHealth = 620 +monster.race = "blood" +monster.corpse = 20587 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Where did I park my hut?", yell = false}, + {text = "You will taste so sweet!", yell = false}, + {text = "Hexipooh, bewitched are you!", yell = false} +} + +monster.loot = { + {name = "cape", chance = 66000}, + {name = "broom", chance = 62500}, + {name = "cookie", chance = 62500, maxCount = 8}, + {name = "gold coin", chance = 29170, maxCount = 55}, + {name = "star herb", chance = 20833}, + {id = 2129, chance = 20833}, + {name = "garlic necklace", chance = 8333}, + {name = "spellbook of mind control", chance = 8333}, + {name = "coat", chance = 4170}, + {name = "necrotic rod", chance = 4170}, + {name = "silver dagger", chance = 4170} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -50}, + {name ="combat", interval = 2500, chance = 50, type = COMBAT_FIREDAMAGE, minDamage = -30, maxDamage = -50, range = 5, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_HITBYFIRE, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 3000, chance = 13, minDamage = -10, maxDamage = -10, range = 5, shootEffect = CONST_ANI_POISON, target = false}, + {name ="firefield", interval = 2000, chance = 13, range = 5, shootEffect = CONST_ANI_FIRE, target = false} +} + +monster.defenses = { + defense = 20, + armor = 15, + {name ="invisible", interval = 2000, chance = 18, effect = CONST_ME_MAGIC_RED}, + {name ="outfit", interval = 4000, chance = 9, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000, outfitMonster = "green frog"} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -1}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 1}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/zamuloshsummom.lua b/data/monster/bosses/zamuloshsummom.lua new file mode 100644 index 00000000000..f11e9159de2 --- /dev/null +++ b/data/monster/bosses/zamuloshsummom.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Zamulosh") +local monster = {} + +monster.description = "a zamulosh" +monster.experience = 50000 +monster.outfit = { + lookType = 862, + lookHead = 17, + lookBody = 12, + lookLegs = 73, + lookFeet = 92, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "blood" +monster.corpse = 8062 +monster.speed = 235 +monster.manaCost = 200 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 100, attack = 150}, + {name ="combat", interval = 1000, chance = 7, type = COMBAT_MANADRAIN, minDamage = -100, maxDamage = -300, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_POFF, target = false}, + {name ="drunk", interval = 1000, chance = 7, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="strength", interval = 1000, chance = 9, range = 7, shootEffect = CONST_ANI_LARGEROCK, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="combat", interval = 1000, chance = 13, type = COMBAT_LIFEDRAIN, minDamage = -50, maxDamage = -100, radius = 8, effect = CONST_ME_LOSEENERGY, target = false}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -50, maxDamage = -100, radius = 8, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="speed", interval = 1000, chance = 12, speedChange = -1900, radius = 6, effect = CONST_ME_POISONAREA, target = false, duration = 60000}, + {name ="strength", interval = 1000, chance = 8, radius = 5, effect = CONST_ME_HITAREA, target = false}, + {name ="combat", interval = 1000, chance = 34, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -300, range = 7, radius = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -100, maxDamage = -250, length = 8, spread = 3, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 160, + armor = 160, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_HEALING, minDamage = 2000, maxDamage = 3000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 1000, chance = 8, speedChange = 1901, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000}, + {name ="invisible", interval = 1000, chance = 17, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/zarabustor.lua b/data/monster/bosses/zarabustor.lua new file mode 100644 index 00000000000..b4b47358f27 --- /dev/null +++ b/data/monster/bosses/zarabustor.lua @@ -0,0 +1,143 @@ +local mType = Game.createMonsterType("Zarabustor") +local monster = {} + +monster.description = "zarabustor" +monster.experience = 8000 +monster.outfit = { + lookType = 130, + lookHead = 0, + lookBody = 77, + lookLegs = 92, + lookFeet = 115, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 5100 +monster.maxHealth = 5100 +monster.race = "blood" +monster.corpse = 20554 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 900, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Warlock", chance = 10, interval = 2000, max = 2}, + {name = "Green Djinn", chance = 10, interval = 2000, max = 3} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Killing is such a splendid diversion from my studies.", yell = false}, + {text = "Time to test my newest spells!", yell = false}, + {text = "Ah, practice time once again!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 32000, maxCount = 80}, + {id = 2411, chance = 9600}, + {id = 2436, chance = 8330}, + {id = 7368, chance = 5500, maxCount = 4}, + {id = 2656, chance = 3390}, + {id = 2146, chance = 3190}, + {id = 7898, chance = 3040}, + {id = 2123, chance = 2420}, + {id = 2466, chance = 2240} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -130}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = 0, maxDamage = -250, range = 7, radius = 3, shootEffect = CONST_ANI_BURSTARROW, effect = CONST_ME_FIREAREA, target = true}, + {name ="firefield", interval = 2000, chance = 10, range = 7, radius = 2, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -250, range = 7, shootEffect = CONST_ANI_ENERGY, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -130, maxDamage = -350, length = 8, spread = 3, effect = CONST_ME_BIGCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -250, range = 7, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -330, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000}, + {name ="warlock skill reducer", interval = 2000, chance = 5, range = 5, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 100, maxDamage = 225, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 20, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 95}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/zavarash.lua b/data/monster/bosses/zavarash.lua new file mode 100644 index 00000000000..6dcacd3a827 --- /dev/null +++ b/data/monster/bosses/zavarash.lua @@ -0,0 +1,155 @@ +local mType = Game.createMonsterType("Zavarash") +local monster = {} + +monster.description = "Zavarash" +monster.experience = 21000 +monster.outfit = { + lookType = 12, + lookHead = 19, + lookBody = 0, + lookLegs = 77, + lookFeet = 79, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 35000 +monster.maxHealth = 35000 +monster.race = "blood" +monster.corpse = 6068 +monster.speed = 440 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "dark torturer", chance = 100, interval = 1000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Harrr, Harrr!", yell = true} +} + +monster.loot = { + {id = 22396, chance = 100000}, + {id = 2148, chance = 100000, maxCount = 197}, + {id = 2152, chance = 100000, maxCount = 50}, + {id = 5954, chance = 100000}, + {id = 22598, chance = 60000}, + {id = 6500, chance = 60000}, + {id = 7632, chance = 40000}, + {id = 18414, chance = 40000, maxCount = 8}, + {id = 7590, chance = 34440, maxCount = 10}, + {id = 8473, chance = 34440, maxCount = 10}, + {id = 8472, chance = 34440, maxCount = 5}, + {id = 18413, chance = 30000, maxCount = 8}, + {id = 18415, chance = 30000, maxCount = 8}, + {id = 2155, chance = 20000}, + {id = 2515, chance = 15030}, + {id = 2427, chance = 15030}, + {id = 2158, chance = 15030}, + {id = 9971, chance = 15030}, + {id = 7428, chance = 15030}, + {id = 2452, chance = 12940}, + {id = 2519, chance = 11540}, + {id = 22610, chance = 10000}, + {id = 8891, chance = 9620}, + {id = 7387, chance = 8390}, + {id = 2520, chance = 6290}, + {id = 2514, chance = 1400}, + {id = 7431, chance = 700}, + {id = 8877, chance = 350}, + {id = 8928, chance = 170} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -600}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -6000, range = 7, shootEffect = CONST_ANI_THROWINGKNIFE, target = false} +} + +monster.defenses = { + defense = 65, + armor = 55, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_HEALING, minDamage = 400, maxDamage = 600, radius = 8, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 18, speedChange = 784, effect = CONST_ME_MAGIC_GREEN, target = false, duration = 7000}, + {name ="invisible", interval = 2000, chance = 20, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/zevelon_duskbringer.lua b/data/monster/bosses/zevelon_duskbringer.lua new file mode 100644 index 00000000000..6db03120b88 --- /dev/null +++ b/data/monster/bosses/zevelon_duskbringer.lua @@ -0,0 +1,138 @@ +local mType = Game.createMonsterType("Zevelon Duskbringer") +local monster = {} + +monster.description = "Zevelon Duskbringer" +monster.experience = 1800 +monster.outfit = { + lookType = 287, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1400 +monster.maxHealth = 1400 +monster.race = "undead" +monster.corpse = 8937 +monster.speed = 310 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 5000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Vampire", chance = 40, interval = 3000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I want Your Blood", yell = false}, + {text = "Come Here!", yell = false}, + {text = "I will be still around when my 'noble' race is gone", yell = false}, + {text = "Human blood is not suitable for drinking!", yell = false}, + {text = "Human blood is a hardly suitable drink.", yell = false}, + {text = "Your short live is coming to an end.", yell = false}, + {text = "Ashari Mortals. Come and stay forever!", yell = false} +} + +monster.loot = { + {id = 7588, chance = 4000}, + {id = 2144, chance = 8000}, + {id = 9020, chance = 100000}, + {id = 2152, chance = 50000, maxCount = 5}, + {id = 2148, chance = 100000, maxCount = 75}, + {id = 2534, chance = 4500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 65, attack = 75}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -200, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="speed", interval = 2000, chance = 15, target = true} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_HEALING, minDamage = 100, maxDamage = 235, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 3000, chance = 25, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -15}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/zoralurk.lua b/data/monster/bosses/zoralurk.lua new file mode 100644 index 00000000000..6027802152d --- /dev/null +++ b/data/monster/bosses/zoralurk.lua @@ -0,0 +1,144 @@ +local mType = Game.createMonsterType("Zoralurk") +local monster = {} + +monster.description = "Zoralurk" +monster.experience = 30000 +monster.outfit = { + lookType = 12, + lookHead = 0, + lookBody = 98, + lookLegs = 86, + lookFeet = 94, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 55000 +monster.maxHealth = 55000 +monster.race = "undead" +monster.corpse = 6068 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 10000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 98, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "demon", chance = 50, interval = 4000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I AM ZORALURK, THE DEMON WITH A THOUSAND FACES!", yell = true}, + {text = "BRING IT, COCKROACHES!", yell = true} +} + +monster.loot = { + {name = "white pearl", chance = 10000, maxCount = 5}, + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 90}, + {name = "boots of haste", chance = 16033}, + {name = "giant sword", chance = 60000}, + {name = "bright sword", chance = 20000}, + {name = "bright sword", chance = 20000}, + {name = "warlord sword", chance = 6000}, + {name = "patched boots", chance = 7000}, + {id = 6530, chance = 16000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1013}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = -600, maxDamage = -900, radius = 7, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_EARTHDAMAGE, minDamage = -400, maxDamage = -800, radius = 7, effect = CONST_ME_SMALLPLANTS, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_MANADRAIN, minDamage = -500, maxDamage = -800, range = 7, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 3000, chance = 35, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -600, range = 7, radius = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true} +} + +monster.defenses = { + defense = 65, + armor = 55, + {name ="combat", interval = 2000, chance = 35, type = COMBAT_HEALING, minDamage = 300, maxDamage = 800, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 4000, chance = 80, speedChange = 440, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000}, + {name ="outfit", interval = 2000, chance = 10, effect = CONST_ME_CRAPS, target = false, duration = 10000, outfitMonster = "behemoth"}, + {name ="outfit", interval = 2000, chance = 10, effect = CONST_ME_CRAPS, target = false, duration = 10000, outfitMonster = "fire devil"}, + {name ="outfit", interval = 2000, chance = 10, effect = CONST_ME_CRAPS, target = false, duration = 10000, outfitMonster = "giant spider"}, + {name ="outfit", interval = 2000, chance = 10, effect = CONST_ME_CRAPS, target = false, duration = 10000, outfitMonster = "undead dragon"}, + {name ="outfit", interval = 2000, chance = 10, effect = CONST_ME_CRAPS, target = false, duration = 10000, outfitMonster = "lost soul"} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/bosses/zushuka.lua b/data/monster/bosses/zushuka.lua new file mode 100644 index 00000000000..5042298f308 --- /dev/null +++ b/data/monster/bosses/zushuka.lua @@ -0,0 +1,162 @@ +local mType = Game.createMonsterType("Zushuka") +local monster = {} + +monster.description = "zushuka" +monster.experience = 9000 +monster.outfit = { + lookType = 149, + lookHead = 86, + lookBody = 12, + lookLegs = 31, + lookFeet = 60, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 15000 +monster.maxHealth = 15000 +monster.race = "blood" +monster.corpse = 20546 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Cool down, will you?", yell = false}, + {text = "Freeze!", yell = false}, + {text = "Is this all you've got?", yell = false}, + {text = "Pay for your ignorance!", yell = false}, + {text = "And stay cool.", yell = false}, + {text = "Your cold dead body will be a marvelous ice statue.", yell = false} +} + +monster.loot = { + {id = 2148, chance = 92000, maxCount = 200}, + {id = 21400, chance = 92000}, + {id = 7290, chance = 57000}, + {id = 7449, chance = 42000}, + {id = 8472, chance = 42000, maxCount = 5}, + {id = 2396, chance = 42000}, + {id = 2168, chance = 42000}, + {id = 7443, chance = 35000}, + {id = 7892, chance = 35000}, + {id = 7440, chance = 35000}, + {id = 2152, chance = 35000}, + {id = 5909, chance = 35000, maxCount = 2}, + {id = 7439, chance = 28000}, + {id = 2158, chance = 28000}, + {id = 2663, chance = 28000}, + {id = 7888, chance = 21000}, + {id = 7590, chance = 21000, maxCount = 5}, + {id = 5912, chance = 14000}, + {id = 2445, chance = 14000}, + {id = 2201, chance = 14000}, + {id = 7896, chance = 14000}, + {id = 7897, chance = 14000}, + {id = 9971, chance = 14000}, + {id = 7591, chance = 14000, maxCount = 5}, + {id = 7459, chance = 14000}, + {id = 2436, chance = 14000}, + {id = 2195, chance = 7000}, + {id = 7902, chance = 7000}, + {id = 5911, chance = 7000}, + {id = 21699, chance = 7000}, + {id = 21700, chance = 3000}, + {id = 7410, chance = 3000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -560}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = 0, maxDamage = -100, length = 8, spread = 3, effect = CONST_ME_ICEATTACK, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ICEDAMAGE, minDamage = 0, maxDamage = -110, range = 7, shootEffect = CONST_ANI_SNOWBALL, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -300, maxDamage = -750, length = 8, spread = 3, effect = CONST_ME_ICEAREA, target = false}, + {name ="outfit", interval = 2000, chance = 10, range = 7, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 4000, outfitItem = 7172}, + {name ="speed", interval = 2000, chance = 15, speedChange = -330, range = 7, effect = CONST_ME_ICETORNADO, target = false, duration = 20000} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 10000, chance = 1, type = COMBAT_HEALING, minDamage = 7500, maxDamage = 7515, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 3000, chance = 15, type = COMBAT_HEALING, minDamage = 200, maxDamage = 500, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/constructs/animated_snowman.lua b/data/monster/constructs/animated_snowman.lua new file mode 100644 index 00000000000..0d786fece9c --- /dev/null +++ b/data/monster/constructs/animated_snowman.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Animated Snowman") +local monster = {} + +monster.description = "an animated snowman" +monster.experience = 400 +monster.outfit = { + lookType = 1159, + lookHead = 19, + lookBody = 10, + lookLegs = 19, + lookFeet = 57, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1751 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Percht Island." + } + +monster.health = 450 +monster.maxHealth = 450 +monster.race = "venom" +monster.corpse = 35162 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 50}, + {name = "Twig Arms", chance = 91770}, + {name = "Shiver Arrow", chance = 7310}, + {name = "Ice Rapier", chance = 4750}, + {name = "Glacier Mask", chance = 4570}, + {name = "Snowball", chance = 4000, maxCount = 5}, + {name = "Hailstorm Rod", chance = 3470}, + {name = "Glacier Mask", chance = 250}, + {name = "Glacier Amulet", chance = 3290}, + {name = "Moonlight Rod", chance = 1830}, + {name = "Glacier Kilt", chance = 1100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -20}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -10, maxDamage = -40, range = 7, radius = 2, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/biting_book.lua b/data/monster/constructs/biting_book.lua new file mode 100644 index 00000000000..a8c82d8c512 --- /dev/null +++ b/data/monster/constructs/biting_book.lua @@ -0,0 +1,117 @@ +local mType = Game.createMonsterType("Biting Book") +local monster = {} + +monster.description = "a biting book" +monster.experience = 9350 +monster.outfit = { + lookType = 1066, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1656 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "The Secret Library. There are also two incarcerated in the Issavi prison, \z + reachable from the city Library." + } + +monster.health = 6500 +monster.maxHealth = 6500 +monster.race = "undead" +monster.corpse = 33353 +monster.speed = 480 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2231, chance = 500, maxCount = 2}, + {name = "Book Page", chance = 500, maxCount = 4}, + {name = "Glowing Rune", chance = 500, maxCount = 2}, + {name = "Platinum Coin", chance = 10000, maxCount = 5}, + {name = "Silken Bookmark", chance = 500, maxCount = 3} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1055}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -1210, radius = 5, effect = CONST_ME_SMOKE, target = false}, + {name ="combat", interval = 1000, chance = 14, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -1210, radius = 3, effect = CONST_ME_BATS, target = false} +} + +monster.defenses = { + defense = 40, + armor = 76 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/clay_guardian.lua b/data/monster/constructs/clay_guardian.lua new file mode 100644 index 00000000000..e22c68f0568 --- /dev/null +++ b/data/monster/constructs/clay_guardian.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Clay Guardian") +local monster = {} + +monster.description = "a clay guardian" +monster.experience = 400 +monster.outfit = { + lookType = 333, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 706 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Horestis Tomb, Middle Spike, Medusa Tower." + } + +monster.health = 625 +monster.maxHealth = 625 +monster.race = "undead" +monster.corpse = 13972 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 60, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "small stone", chance = 10000, maxCount = 10}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 63}, + {name = "blank rune", chance = 25000}, + {name = "earth arrow", chance = 5555, maxCount = 8}, + {name = "small topaz", chance = 320}, + {name = "lump of earth", chance = 25000}, + {name = "clay lump", chance = 1100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -125}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -30, maxDamage = -150, range = 7, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_EARTHDAMAGE, minDamage = -20, maxDamage = -30, radius = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 40, maxDamage = 130, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 40}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/damaged_crystal_golem.lua b/data/monster/constructs/damaged_crystal_golem.lua new file mode 100644 index 00000000000..c1f50e1c030 --- /dev/null +++ b/data/monster/constructs/damaged_crystal_golem.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Damaged Crystal Golem") +local monster = {} + +monster.description = "a damaged crystal golem" +monster.experience = 0 +monster.outfit = { + lookType = 508, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 874 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 1, + Locations = "Golem Workshop in Gnomebase Alpha." + } + +monster.health = 500 +monster.maxHealth = 500 +monster.race = "venom" +monster.corpse = 18466 +monster.speed = 268 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 500, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/damaged_worker_golem.lua b/data/monster/constructs/damaged_worker_golem.lua new file mode 100644 index 00000000000..f8082e8d9b7 --- /dev/null +++ b/data/monster/constructs/damaged_worker_golem.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Damaged Worker Golem") +local monster = {} + +monster.description = "a damaged worker golem" +monster.experience = 95 +monster.outfit = { + lookType = 304, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 524 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Factory Quarter." + } + +monster.health = 260 +monster.maxHealth = 260 +monster.race = "venom" +monster.corpse = 9801 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Klonk klonk klonk", yell = false}, + {text = "Failure! Failure!", yell = false}, + {text = "Good morning citizen. How may I serve you?", yell = false}, + {text = "Target identified: Rat! Termination initiated!", yell = false}, + {text = "Rrrtttarrrttarrrtta", yell = false}, + {text = "Danger will...chrrr! Danger!", yell = false}, + {text = "Self-diagnosis failed.", yell = false}, + {text = "Aw... chhhrrr orders.", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 68810, maxCount = 88}, + {name = "sword ring", chance = 570}, + {name = "iron ore", chance = 400}, + {name = "nail", chance = 1460}, + {name = "heavily rusted armor", chance = 790}, + {name = "gear crystal", chance = 200} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -45}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -45, range = 7, shootEffect = CONST_ANI_SMALLSTONE, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 5, maxDamage = 11, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 25}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/diamond_servant.lua b/data/monster/constructs/diamond_servant.lua new file mode 100644 index 00000000000..53faa84aba0 --- /dev/null +++ b/data/monster/constructs/diamond_servant.lua @@ -0,0 +1,135 @@ +local mType = Game.createMonsterType("Diamond Servant") +local monster = {} + +monster.description = "a diamond servant" +monster.experience = 700 +monster.outfit = { + lookType = 397, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 702 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 50, + Stars = 3, + Occurrence = 3, + Locations = "Edron." + } + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "venom" +monster.corpse = 13485 +monster.speed = 172 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 100, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Error. LOAD 'PROGRAM',8,1", yell = false}, + {text = "Remain. Obedient.", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 44000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 79}, + {name = "yellow gem", chance = 550}, + {name = "might ring", chance = 940}, + {name = "life crystal", chance = 9150}, + {name = "wand of cosmic energy", chance = 530}, + {name = "soul orb", chance = 45000}, + {name = "bonebreaker", chance = 10}, + {name = "mastermind potion", chance = 400}, + {name = "strong health potion", chance = 5790}, + {name = "strong mana potion", chance = 5980}, + {name = "lightning pendant", chance = 710}, + {name = "crystalline armor", chance = 20}, + {name = "gear wheel", chance = 5000}, + {id = 9976, chance = 5320}, + {name = "shockwave amulet", chance = 110}, + {name = "gear crystal", chance = 5000}, + {name = "slime mould", chance = 480} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -80, maxDamage = -120, radius = 3, effect = CONST_ME_YELLOWENERGY, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -125, maxDamage = -170, length = 5, spread = 2, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="drunk", interval = 2000, chance = 10, range = 7, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_STUN, target = true, duration = 3000} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/diamond_servant_replica.lua b/data/monster/constructs/diamond_servant_replica.lua new file mode 100644 index 00000000000..f4151b78ee1 --- /dev/null +++ b/data/monster/constructs/diamond_servant_replica.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Diamond Servant Replica") +local monster = {} + +monster.description = "a diamond servant replica" +monster.experience = 700 +monster.outfit = { + lookType = 397, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1326 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Replica Dungeon." + } + +monster.health = 2000 +monster.maxHealth = 2000 +monster.race = "venom" +monster.corpse = 13485 +monster.speed = 172 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 100, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 10572, chance = 5040}, + {id = 9690, chance = 5070}, + {id = 2148, chance = 94130, maxCount = 179}, + {id = 5944, chance = 44990}, + {id = 2177, chance = 9150}, + {id = 7589, chance = 5980}, + {id = 7588, chance = 5790}, + {id = 9976, chance = 5320}, + {id = 2164, chance = 940}, + {id = 7889, chance = 710}, + {id = 2154, chance = 550}, + {id = 2189, chance = 530}, + {id = 13758, chance = 480}, + {id = 7440, chance = 400}, + {id = 10221, chance = 110}, + {id = 8878, chance = 20}, + {id = 7428, chance = 13} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 40, attack = 40}, + {name ="combat", interval = 2000, chance = 11, type = COMBAT_ENERGYDAMAGE, minDamage = -100, maxDamage = -210, radius = 3, effect = CONST_ME_YELLOWENERGY, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -75, maxDamage = -125, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="wyrm wave", interval = 2000, chance = 9, minDamage = -70, maxDamage = -120, target = false} +} + +monster.defenses = { + defense = 45, + armor = 40, + {name ="combat", interval = 2000, chance = 11, type = COMBAT_HEALING, minDamage = 50, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, effect = CONST_ME_YELLOWENERGY, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/enraged_crystal_golem.lua b/data/monster/constructs/enraged_crystal_golem.lua new file mode 100644 index 00000000000..3cdec1a5a19 --- /dev/null +++ b/data/monster/constructs/enraged_crystal_golem.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Enraged Crystal Golem") +local monster = {} + +monster.description = "an enraged crystal golem" +monster.experience = 550 +monster.outfit = { + lookType = 508, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 873 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Golem Workshop." + } + +monster.health = 700 +monster.maxHealth = 700 +monster.race = "venom" +monster.corpse = 18466 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Crrrrk! Chhhhr!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "crystal sword", chance = 4710}, + {name = "glorious axe", chance = 360}, + {name = "strong health potion", chance = 7140}, + {name = "strong mana potion", chance = 8270}, + {name = "blue crystal splinter", chance = 4120}, + {name = "cyan crystal fragment", chance = 1050}, + {name = "crystalline spikes", chance = 7980} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 15}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/eternal_guardian.lua b/data/monster/constructs/eternal_guardian.lua new file mode 100644 index 00000000000..940b465af5f --- /dev/null +++ b/data/monster/constructs/eternal_guardian.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Eternal Guardian") +local monster = {} + +monster.description = "an eternal guardian" +monster.experience = 1800 +monster.outfit = { + lookType = 345, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 615 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "North-east Muggy Plains, Deeper Banuta." + } + +monster.health = 2500 +monster.maxHealth = 2500 +monster.race = "undead" +monster.corpse = 11300 +monster.speed = 204 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Zzrrkrrch!", yell = false}, + {text = "", yell = false} +} + +monster.loot = { + {name = "small stone", chance = 30230, maxCount = 10}, + {name = "gold coin", chance = 99930, maxCount = 100}, + {name = "platinum coin", chance = 99540, maxCount = 4}, + {name = "guardian halberd", chance = 560}, + {name = "tower shield", chance = 820}, + {name = "iron ore", chance = 1700}, + {name = "ancient stone", chance = 20020}, + {name = "shiny stone", chance = 800}, + {name = "Zaoan sword", chance = 100}, + {name = "Zaoan halberd", chance = 1860}, + {name = "spiked iron ball", chance = 9960}, + {name = "clay lump", chance = 720}, + {name = "piece of marble rock", chance = 430}, + {id = 13757, chance = 400} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 25}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 70}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/glooth_golem.lua b/data/monster/constructs/glooth_golem.lua new file mode 100644 index 00000000000..f6bb03eee18 --- /dev/null +++ b/data/monster/constructs/glooth_golem.lua @@ -0,0 +1,140 @@ +local mType = Game.createMonsterType("Glooth Golem") +local monster = {} + +monster.description = "a glooth golem" +monster.experience = 1606 +monster.outfit = { + lookType = 600, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1038 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Glooth Factory, Underground Glooth Factory, Rathleton Sewers, Jaccus Maxxens Dungeon, \z + Oramond Dungeon (depending on Magistrate votes)." + } + +monster.health = 2700 +monster.maxHealth = 2700 +monster.race = "venom" +monster.corpse = 23343 +monster.speed = 260 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "*slosh*", yell = false}, + {text = "*clank*", yell = false} +} + +monster.loot = { + {id = 5880, chance = 530}, + {id = 23554, chance = 720}, + {id = 23541, chance = 1720}, + {id = 23536, chance = 370}, + {id = 2148, chance = 100000, maxCount = 200}, + {id = 24124, chance = 1470}, + {id = 9690, chance = 690}, + {id = 23514, chance = 1970}, + {id = 2152, chance = 6010, maxCount = 4}, + {id = 23474, chance = 2840}, + {id = 8473, chance = 4470}, + {id = 7590, chance = 9280}, + {id = 23538, chance = 690}, + {id = 23550, chance = 440}, + {id = 23549, chance = 230}, + {id = 23551, chance = 290}, + {id = 2154, chance = 730}, + {id = 9970, chance = 1560, maxCount = 4}, + {id = 2149, chance = 1590, maxCount = 4} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 60, attack = 50}, + {name ="melee", interval = 2000, chance = 2, skill = 86, attack = 100}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -125, maxDamage = -245, range = 7, shootEffect = CONST_ANI_ENERGY, target = false}, + {name ="war golem skill reducer", interval = 2000, chance = 16, target = false}, + {name ="war golem electrify", interval = 2000, chance = 9, range = 7, target = false} +} + +monster.defenses = { + defense = 45, + armor = 40, + {name ="speed", interval = 2000, chance = 13, speedChange = 404, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 15}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/golden_servant.lua b/data/monster/constructs/golden_servant.lua new file mode 100644 index 00000000000..5e272d96887 --- /dev/null +++ b/data/monster/constructs/golden_servant.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Golden Servant") +local monster = {} + +monster.description = "a golden servant" +monster.experience = 450 +monster.outfit = { + lookType = 396, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 701 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 50, + Stars = 3, + Occurrence = 3, + Locations = "Edron." + } + +monster.health = 550 +monster.maxHealth = 550 +monster.race = "venom" +monster.corpse = 13489 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 50, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Error. LOAD 'PROGRAM',8,1", yell = false}, + {text = "Remain. Obedient.", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 40000, maxCount = 100}, + {name = "gold coin", chance = 45000, maxCount = 40}, + {name = "stealth ring", chance = 450}, + {name = "gold ring", chance = 10}, + {name = "halberd", chance = 3003}, + {name = "golden armor", chance = 10}, + {name = "green mushroom", chance = 1450}, + {name = "health potion", chance = 4930}, + {name = "mana potion", chance = 4950}, + {name = "spellbook of enlightenment", chance = 520}, + {name = "gear wheel", chance = 940}, + {name = "slime mould", chance = 340}, + {name = "golden can of oil", chance = 40} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -60, maxDamage = -100, radius = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_YELLOWENERGY, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -80, maxDamage = -110, radius = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -90, maxDamage = -150, length = 5, spread = 2, effect = CONST_ME_YELLOWENERGY, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/golden_servant_replica.lua b/data/monster/constructs/golden_servant_replica.lua new file mode 100644 index 00000000000..dee45c95d00 --- /dev/null +++ b/data/monster/constructs/golden_servant_replica.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Golden Servant Replica") +local monster = {} + +monster.description = "a golden servant replica" +monster.experience = 450 +monster.outfit = { + lookType = 396, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1327 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Replica Dungeon." + } + +monster.health = 2000 +monster.maxHealth = 2000 +monster.race = "venom" +monster.corpse = 13484 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 80, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2796, chance = 1450}, + {id = 9690, chance = 940}, + {id = 2148, chance = 85180, maxCount = 140}, + {id = 7618, chance = 4930}, + {id = 7620, chance = 4950}, + {id = 2381, chance = 3030}, + {id = 8900, chance = 520}, + {id = 2165, chance = 450}, + {id = 13758, chance = 340}, + {id = 13938, chance = 36}, + {id = 2466, chance = 13}, + {id = 2179, chance = 8} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 40, attack = 40}, + {name ="combat", interval = 2000, chance = 11, type = COMBAT_FIREDAMAGE, minDamage = -80, maxDamage = -110, length = 5, spread = 1, effect = CONST_ME_YELLOWENERGY, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -70, maxDamage = -110, range = 7, radius = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_PURPLEENERGY, target = true} +} + +monster.defenses = { + defense = 45, + armor = 40, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_HEALING, minDamage = 40, maxDamage = 70, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/ice_golem.lua b/data/monster/constructs/ice_golem.lua new file mode 100644 index 00000000000..a694494d041 --- /dev/null +++ b/data/monster/constructs/ice_golem.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Ice Golem") +local monster = {} + +monster.description = "an ice golem" +monster.experience = 295 +monster.outfit = { + lookType = 261, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 326 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Formorgar Glacier, Formorgar Mines, Nibelor Ice Cave, Ice Witch Temple, \z + Deeper Banuta, Crystal Caves, Chyllfroest." + } + +monster.health = 385 +monster.maxHealth = 385 +monster.race = "undead" +monster.corpse = 7282 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 50, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Chrrr.", yell = false}, + {text = "Crrrrk.", yell = false}, + {text = "Gnarr.", yell = false} +} + +monster.loot = { + {name = "black pearl", chance = 1612}, + {name = "small diamond", chance = 66}, + {name = "small sapphire", chance = 578}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 3}, + {name = "ice rapier", chance = 400}, + {name = "strange helmet", chance = 444}, + {name = "shard", chance = 266}, + {id = 7441, chance = 5000}, + {name = "crystal sword", chance = 177}, + {name = "strong health potion", chance = 444}, + {name = "glacier mask", chance = 111}, + {name = "frosty heart", chance = 11111} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -220}, + {name ="speed", interval = 1000, chance = 13, speedChange = -800, length = 8, spread = 3, effect = CONST_ME_ENERGYHIT, target = false, duration = 20000}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -50, maxDamage = -85, range = 7, shootEffect = CONST_ANI_SMALLICE, effect = CONST_ME_ICEATTACK, target = false}, + {name ="ice golem skill reducer", interval = 2000, chance = 10, target = false} +} + +monster.defenses = { + defense = 26, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 25}, + {type = COMBAT_ENERGYDAMAGE, percent = -20}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/infected_weeper.lua b/data/monster/constructs/infected_weeper.lua new file mode 100644 index 00000000000..2d8055d0271 --- /dev/null +++ b/data/monster/constructs/infected_weeper.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Infected Weeper") +local monster = {} + +monster.description = "an infected weeper" +monster.experience = 1200 +monster.outfit = { + lookType = 489, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 897 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 1, + Locations = "Warzone 2." + } + +monster.health = 3000 +monster.maxHealth = 3000 +monster.race = "fire" +monster.corpse = 17251 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 6 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 80, + random = 20, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Parasite", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Moooaaan", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 198}, + {name = "platinum coin", chance = 100000, maxCount = 7}, + {id = 8748, chance = 1460} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -280}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -250, maxDamage = -700, length = 5, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_FIREDAMAGE, minDamage = -80, maxDamage = -250, radius = 3, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = -800, length = 5, spread = 3, effect = CONST_ME_BLOCKHIT, target = false, duration = 30000} +} + +monster.defenses = { + defense = 45, + armor = 45, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/iron_servant.lua b/data/monster/constructs/iron_servant.lua new file mode 100644 index 00000000000..105285bca7a --- /dev/null +++ b/data/monster/constructs/iron_servant.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Iron Servant") +local monster = {} + +monster.description = "an iron servant" +monster.experience = 210 +monster.outfit = { + lookType = 395, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 700 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 30, + Stars = 2, + Occurrence = 3, + Locations = "Edron." + } + +monster.health = 350 +monster.maxHealth = 350 +monster.race = "venom" +monster.corpse = 13486 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 50, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Error. LOAD 'PROGRAM',8,1", yell = false}, + {text = "Remain. Obedient.", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 82000, maxCount = 55}, + {name = "halberd", chance = 1000}, + {name = "gear wheel", chance = 4840}, + {id = 9808, chance = 200}, + {name = "slime mould", chance = 310} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -45}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -60, range = 7, shootEffect = CONST_ANI_SMALLSTONE, effect = CONST_ME_EXPLOSIONAREA, target = false}, + {name ="drunk", interval = 2000, chance = 10, range = 7, shootEffect = CONST_ANI_EXPLOSION, effect = CONST_ME_STUN, target = true, duration = 2000} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/iron_servant_replica.lua b/data/monster/constructs/iron_servant_replica.lua new file mode 100644 index 00000000000..82f4f4bec73 --- /dev/null +++ b/data/monster/constructs/iron_servant_replica.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Iron Servant Replica") +local monster = {} + +monster.description = "an iron servant replica" +monster.experience = 210 +monster.outfit = { + lookType = 395, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1325 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Replica Dungeon." + } + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "venom" +monster.corpse = 13483 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 9690, chance = 4840}, + {id = 2148, chance = 82190, maxCount = 55}, + {id = 7618, chance = 1980}, + {id = 2381, chance = 1000}, + {id = 13758, chance = 310} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 20, attack = 30}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -60, range = 7, shootEffect = CONST_ANI_EXPLOSION, effect = CONST_ME_EXPLOSIONAREA, target = false}, + {name ="drunk", interval = 2000, chance = 14, range = 7, shootEffect = CONST_ANI_EXPLOSION, effect = CONST_ME_STUN, target = false, duration = 2000} +} + +monster.defenses = { + defense = 45, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = -5}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 5}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/lava_golem.lua b/data/monster/constructs/lava_golem.lua new file mode 100644 index 00000000000..c93a85351f4 --- /dev/null +++ b/data/monster/constructs/lava_golem.lua @@ -0,0 +1,146 @@ +local mType = Game.createMonsterType("Lava Golem") +local monster = {} + +monster.description = "a lava golem" +monster.experience = 6200 +monster.outfit = { + lookType = 491, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 884 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 1, + Locations = "Warzone 2." + } + +monster.health = 9000 +monster.maxHealth = 9000 +monster.race = "fire" +monster.corpse = 17333 +monster.speed = 420 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 80, + random = 20, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grrrrunt", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 199}, + {name = "platinum coin", chance = 100000, maxCount = 11}, + {name = "yellow gem", chance = 6480}, + {name = "red gem", chance = 1180}, + {name = "wand of inferno", chance = 2950}, + {name = "fire sword", chance = 1710}, + {name = "fire axe", chance = 1560}, + {name = "crown shield", chance = 1180}, + {name = "iron ore", chance = 11570}, + {name = "white piece of cloth", chance = 4810}, + {name = "red piece of cloth", chance = 3530}, + {name = "yellow piece of cloth", chance = 7230}, + {name = "strong health potion", chance = 18830, maxCount = 2}, + {name = "strong mana potion", chance = 18150, maxCount = 2}, + {name = "great mana potion", chance = 16030, maxCount = 2}, + {name = "mana potion", chance = 20720, maxCount = 2}, + {name = "magma amulet", chance = 2900}, + {name = "magma boots", chance = 2650}, + {name = "magma coat", chance = 430}, + {name = "ultimate health potion", chance = 15390}, + {name = "spellbook of mind control", chance = 450}, + {name = "fiery heart", chance = 13510}, + {name = "wand of everblazing", chance = 1390}, + {name = "violet crystal shard", chance = 6200}, + {name = "green crystal splinter", chance = 13990, maxCount = 2}, + {name = "red crystal fragment", chance = 10990}, + {name = "magma clump", chance = 15370, maxCount = 2}, + {name = "blazing bone", chance = 15200}, + {name = "prismatic bolt", chance = 12580, maxCount = 5} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -350, maxDamage = -700, length = 8, spread = 3, effect = CONST_ME_FIREATTACK, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -600, maxDamage = -1300, length = 8, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="lava golem soulfire", interval = 2000, chance = 15, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -220, maxDamage = -350, radius = 4, effect = CONST_ME_FIREAREA, target = true}, + {name ="speed", interval = 2000, chance = 10, speedChange = -800, length = 5, spread = 3, effect = CONST_ME_BLOCKHIT, target = false, duration = 30000}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_FIREDAMAGE, minDamage = -280, maxDamage = -350, radius = 3, effect = CONST_ME_HITBYFIRE, target = false} +} + +monster.defenses = { + defense = 60, + armor = 60 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/magma_crawler.lua b/data/monster/constructs/magma_crawler.lua new file mode 100644 index 00000000000..0259e9b284d --- /dev/null +++ b/data/monster/constructs/magma_crawler.lua @@ -0,0 +1,145 @@ +local mType = Game.createMonsterType("Magma Crawler") +local monster = {} + +monster.description = "a magma crawler" +monster.experience = 2700 +monster.outfit = { + lookType = 492, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 885 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Warzone 2." + } + +monster.health = 4800 +monster.maxHealth = 4800 +monster.race = "fire" +monster.corpse = 17336 +monster.speed = 460 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 80, + random = 20, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Crrroak!", yell = false} +} + +monster.loot = { + {name = "small diamond", chance = 8800, maxCount = 3}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 99}, + {name = "platinum coin", chance = 100000, maxCount = 5}, + {name = "yellow gem", chance = 1030}, + {name = "energy ring", chance = 1650}, + {name = "fire sword", chance = 1680}, + {name = "black shield", chance = 1550}, + {name = "iron ore", chance = 4280}, + {name = "white piece of cloth", chance = 2310}, + {name = "red piece of cloth", chance = 930}, + {name = "yellow piece of cloth", chance = 2980}, + {name = "great mana potion", chance = 6500}, + {name = "great health potion", chance = 7270}, + {name = "magma amulet", chance = 3120}, + {name = "magma boots", chance = 1820}, + {name = "wand of draconia", chance = 4280}, + {name = "fiery heart", chance = 7810}, + {id = 13757, chance = 1675}, + {name = "crystalline arrow", chance = 5950, maxCount = 10}, + {name = "wand of everblazing", chance = 690}, + {name = "blue crystal shard", chance = 3930, maxCount = 2}, + {name = "brown crystal splinter", chance = 8500, maxCount = 2}, + {name = "green crystal fragment", chance = 7000}, + {name = "magma clump", chance = 11600}, + {name = "blazing bone", chance = 11500}, + {name = "blazing bone", chance = 12220} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -203}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -300, maxDamage = -1100, length = 8, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="magma crawler wave", interval = 2000, chance = 15, minDamage = -290, maxDamage = -800, target = false}, + {name ="magma crawler soulfire", interval = 2000, chance = 20, target = false}, + {name ="soulfire", interval = 2000, chance = 10, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -140, maxDamage = -180, radius = 3, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = -800, radius = 2, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000} +} + +monster.defenses = { + defense = 45, + armor = 45, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/metal_gargoyle.lua b/data/monster/constructs/metal_gargoyle.lua new file mode 100644 index 00000000000..cb4ad17a4e8 --- /dev/null +++ b/data/monster/constructs/metal_gargoyle.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Metal Gargoyle") +local monster = {} + +monster.description = "a metal gargoyle" +monster.experience = 1278 +monster.outfit = { + lookType = 601, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1039 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Workshop Quarter, Glooth Factory, Underground Glooth Factory, Abandoned Sewers, \z + Oramond Dungeon (depending on Magistrate votes), Jaccus Maxxens Dungeon." + } + +monster.health = 2100 +monster.maxHealth = 2100 +monster.race = "venom" +monster.corpse = 23347 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "*stomp*", yell = false}, + {text = "clonk", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 200}, + {id = 24124, chance = 1490}, + {id = 23564, chance = 17160}, + {id = 2152, chance = 43280, maxCount = 2}, + {id = 7588, chance = 9700, maxCount = 2}, + {id = 7589, chance = 9700, maxCount = 2}, + {id = 23542, chance = 1490}, + {id = 8910, chance = 1490}, + {id = 2167, chance = 2240}, + {id = 2168, chance = 750}, + {id = 11227, chance = 2240}, + {id = 23540, chance = 1490}, + {id = 23539, chance = 1490}, + {id = 9810, chance = 2990} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 84, attack = 50}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -125, maxDamage = -230, length = 8, spread = 3, effect = CONST_ME_YELLOWENERGY, target = false}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_LIFEDRAIN, minDamage = -85, maxDamage = -150, range = 7, radius = 3, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="metal gargoyle curse", interval = 2000, chance = 13, target = false} +} + +monster.defenses = { + defense = 42, + armor = 21 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 40}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 80} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/orewalker.lua b/data/monster/constructs/orewalker.lua new file mode 100644 index 00000000000..9f9f3c3893c --- /dev/null +++ b/data/monster/constructs/orewalker.lua @@ -0,0 +1,146 @@ +local mType = Game.createMonsterType("Orewalker") +local monster = {} + +monster.description = "an orewalker" +monster.experience = 4800 +monster.outfit = { + lookType = 490, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 883 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 1, + Locations = "Warzone 3." + } + +monster.health = 7200 +monster.maxHealth = 7200 +monster.race = "undead" +monster.corpse = 17256 +monster.speed = 380 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 80, + random = 20, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "CLONK!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 98}, + {name = "platinum coin", chance = 100000, maxCount = 10}, + {name = "yellow gem", chance = 1030}, + {name = "dwarven ring", chance = 4660}, + {name = "knight legs", chance = 1910}, + {name = "crown armor", chance = 370}, + {name = "crown helmet", chance = 890}, + {name = "iron ore", chance = 15000}, + {name = "magic sulphur", chance = 3000}, + {name = "titan axe", chance = 2600}, + {name = "glorious axe", chance = 1870}, + {name = "strong health potion", chance = 15600, maxCount = 2}, + {name = "strong mana potion", chance = 14000, maxCount = 2}, + {name = "great mana potion", chance = 14000, maxCount = 2}, + {name = "mana potion", chance = 14000, maxCount = 4}, + {name = "ultimate health potion", chance = 9500, maxCount = 2}, + {name = "crystalline armor", chance = 560}, + {name = "small topaz", chance = 16500, maxCount = 3}, + {name = "shiny stone", chance = 13700}, + {name = "sulphurous stone", chance = 20700}, + {name = "wand of defiance", chance = 1300}, + {name = "green crystal shard", chance = 8000}, + {name = "blue crystal splinter", chance = 16000, maxCount = 2}, + {name = "cyan crystal fragment", chance = 13000}, + {name = "pulverized ore", chance = 20500}, + {name = "vein of ore", chance = 15000}, + {name = "prismatic bolt", chance = 15500, maxCount = 5}, + {name = "crystal crossbow", chance = 300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + {name ="orewalker wave", interval = 2000, chance = 15, minDamage = -296, maxDamage = -700, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -1500, length = 6, spread = 3, effect = CONST_ME_GROUNDSHAKER, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -800, maxDamage = -1080, radius = 3, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_SMALLPLANTS, target = true}, + {name ="drunk", interval = 2000, chance = 15, radius = 4, effect = CONST_ME_SOUND_PURPLE, target = false, duration = 6000}, + {name ="speed", interval = 2000, chance = 15, speedChange = -800, radius = 2, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000} +} + +monster.defenses = { + defense = 45, + armor = 45 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 65}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/rotten_golem.lua b/data/monster/constructs/rotten_golem.lua new file mode 100644 index 00000000000..77c428c810c --- /dev/null +++ b/data/monster/constructs/rotten_golem.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Rotten Golem") +local monster = {} + +monster.description = "a rotten golem" +monster.experience = 23400 +monster.outfit = { + lookType = 1312, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1939 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 5000, + FirstUnlock = 25, + SecondUnlock = 2500, + CharmsPoints = 100, + Stars = 5, + Occurrence = 0, + Locations = "Rotten Wasteland." + } + +monster.health = 28000 +monster.maxHealth = 28000 +monster.race = "venom" +monster.corpse = 38732 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10 +} + +monster.loot = { + {name = "crystal coin", chance = 70540}, + {name = "great spirit potion", chance = 32220, maxCount = 7}, + {id = 7632, chance = 54560}, -- Giant shimmering pearl + {id = 7633, chance = 54560}, -- Giant shimmering pearl + {name = "terra amulet", chance = 35500}, + {name = "giant sword", chance = 13500}, + {name = "war axe", chance = 9500}, + {name = "mercenary sword", chance = 11500}, + {name = "titan axe", chance = 19500}, + {name = "underworld rod", chance = 35500}, + {name = "sacred tree amulet", chance = 17500}, + {name = "fur armor", chance = 9500}, + {name = "terra mantle", chance = 3500}, + {name = "wood cape", chance = 2500}, + {name = "rubber cap", chance = 1500}, + {name = "stone skin amulet", chance = 2000}, + {id = 38944, chance = 50} -- Bag you desire +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -950}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HOLYDAMAGE, minDamage = -650, maxDamage = -900, range = 7, shootEffect = CONST_ANI_SMALLHOLY, effect = CONST_ME_HOLYAREA, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -750, maxDamage = -1200, radius = 7, effect = CONST_ME_BIGPLANTS, target = false}, + {name ="root", interval = 2000, chance = 10, target = true} + -- Chain: const_me-> CONST_ME_GREEN_ENERGY_SPARK, combat_t->COMBAT_EARTHDAMAGE +} + +monster.defenses = { + defense = 110, + armor = 120 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = -15}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = -25}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = -20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/rustheap_golem.lua b/data/monster/constructs/rustheap_golem.lua new file mode 100644 index 00000000000..c50187a0b72 --- /dev/null +++ b/data/monster/constructs/rustheap_golem.lua @@ -0,0 +1,137 @@ +local mType = Game.createMonsterType("Rustheap Golem") +local monster = {} + +monster.description = "a rustheap golem" +monster.experience = 2100 +monster.outfit = { + lookType = 603, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1041 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Workshop Quarter, Glooth Factory, Underground Glooth Factory, \z + Oramond Dungeon (depending on Magistrate votes), Jaccus Maxxens Dungeon." + } + +monster.health = 2800 +monster.maxHealth = 2800 +monster.race = "venom" +monster.corpse = 23355 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "*clatter*", yell = false}, + {text = "*krrk*", yell = false}, + {text = "*frzzp*", yell = false} +} + +monster.loot = { + {id = 8309, chance = 1950}, + {id = 9930, chance = 5860}, + {id = 23567, chance = 14980}, + {id = 2148, chance = 100000, maxCount = 290}, + {id = 5880, chance = 330}, + {id = 24124, chance = 1950}, + {id = 2152, chance = 58310, maxCount = 3}, + {id = 2143, chance = 1300}, + {id = 2144, chance = 1630}, + {id = 7588, chance = 10100, maxCount = 2}, + {id = 7589, chance = 7170, maxCount = 2}, + {id = 2391, chance = 3580}, + {id = 7452, chance = 330}, + {id = 23542, chance = 330}, + {id = 23541, chance = 2930}, + {id = 9810, chance = 5860}, + {id = 9813, chance = 4230} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 118, attack = 50}, + {name ="rustheap golem electrify", interval = 2000, chance = 11, range = 7, target = false}, + {name ="frazzlemaw paralyze", interval = 2000, chance = 10, target = false}, + {name ="rustheap golem wave", interval = 2000, chance = 9, minDamage = -100, maxDamage = -210, target = false} +} + +monster.defenses = { + defense = 45, + armor = 40, + {name ="speed", interval = 2000, chance = 11, speedChange = 428, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 6000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 70}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/sandstone_scorpion.lua b/data/monster/constructs/sandstone_scorpion.lua new file mode 100644 index 00000000000..2b2baf475d2 --- /dev/null +++ b/data/monster/constructs/sandstone_scorpion.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Sandstone Scorpion") +local monster = {} + +monster.description = "a sandstone scorpion" +monster.experience = 680 +monster.outfit = { + lookType = 398, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 705 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Horestis Tomb." + } + +monster.health = 900 +monster.maxHealth = 900 +monster.race = "undead" +monster.corpse = 13501 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 60, + random = 40, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "*rattle*", yell = false}, + {text = "*tak tak*", yell = false}, + {text = "*tak tak tak*", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 92590, maxCount = 128}, + {name = "small emerald", chance = 1100, maxCount = 2}, + {name = "platinum coin", chance = 10750, maxCount = 2}, + {name = "daramian mace", chance = 5100}, + {name = "steel helmet", chance = 4620}, + {name = "black shield", chance = 1820}, + {name = "fist on a stick", chance = 220} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -193, condition = {type = CONDITION_POISON, totalDamage = 1000, interval = 4000}} +} + +monster.defenses = { + defense = 0, + armor = 42, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 60, maxDamage = 100, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = -1}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/stone_devourer.lua b/data/monster/constructs/stone_devourer.lua new file mode 100644 index 00000000000..f553dee7bcf --- /dev/null +++ b/data/monster/constructs/stone_devourer.lua @@ -0,0 +1,138 @@ +local mType = Game.createMonsterType("Stone Devourer") +local monster = {} + +monster.description = "a stone devourer" +monster.experience = 2900 +monster.outfit = { + lookType = 486, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 879 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 1, + Locations = "Warzone 1." + } + +monster.health = 4200 +monster.maxHealth = 4200 +monster.race = "undead" +monster.corpse = 18375 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Rumble!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "platinum coin", chance = 92000, maxCount = 7}, + {name = "stone skin amulet", chance = 2270}, + {name = "dwarven ring", chance = 2840}, + {name = "giant sword", chance = 570}, + {name = "crystal mace", chance = 850}, + {name = "war axe", chance = 920}, + {name = "sapphire hammer", chance = 1490}, + {name = "spiked squelcher", chance = 1490}, + {name = "glorious axe", chance = 3340}, + {name = "strong health potion", chance = 13840, maxCount = 2}, + {name = "strong mana potion", chance = 14900, maxCount = 2}, + {name = "great mana potion", chance = 15610, maxCount = 2}, + {name = "mana potion", chance = 15050, maxCount = 2}, + {name = "ultimate health potion", chance = 14410}, + {id = 8748, chance = 11360}, + {name = "ancient stone", chance = 12850}, + {name = "crystalline arrow", chance = 9940, maxCount = 10}, + {name = "green crystal splinter", chance = 6960}, + {name = "cyan crystal fragment", chance = 6810}, + {name = "stone nose", chance = 18679}, + {name = "crystalline spikes", chance = 16320} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -990}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -230, maxDamage = -460, range = 7, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_STONES, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -650, range = 7, shootEffect = CONST_ANI_LARGEROCK, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -150, maxDamage = -260, length = 5, spread = 3, effect = CONST_ME_STONES, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 1}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = 1} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/stone_golem.lua b/data/monster/constructs/stone_golem.lua new file mode 100644 index 00000000000..435e87274ba --- /dev/null +++ b/data/monster/constructs/stone_golem.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Stone Golem") +local monster = {} + +monster.description = "a stone golem" +monster.experience = 160 +monster.outfit = { + lookType = 67, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 67 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Maze of Lost Souls, in and around Ashta daramai, Formorgar Mines, \z + Mad Technomancer room, Dark Cathedral, Demona, Goroma, Tarpit Tomb, Peninsula Tomb, \z + Deeper Banuta, Forbidden Lands, Beregar Mines, Farmine Mines, Drillworm Caves, 2 caves on Hrodmir, \z + Orc Fortress (single spawn) and Medusa Tower." + } + +monster.health = 270 +monster.maxHealth = 270 +monster.race = "undead" +monster.corpse = 6005 +monster.speed = 180 +monster.manaCost = 590 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "small stone", chance = 13890, maxCount = 4}, + {id = 2124, chance = 120}, + {name = "gold coin", chance = 90000, maxCount = 40}, + {name = "red gem", chance = 30}, + {name = "power ring", chance = 5070}, + {name = "carlin sword", chance = 2500}, + {name = "iron ore", chance = 1980}, + {name = "ancient stone", chance = 1020}, + {name = "shiny stone", chance = 760}, + {name = "sulphurous stone", chance = 10370}, + {name = "piece of marble rock", chance = 380}, + {id = 13757, chance = 550} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -110} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/walker.lua b/data/monster/constructs/walker.lua new file mode 100644 index 00000000000..51dd9621c39 --- /dev/null +++ b/data/monster/constructs/walker.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Walker") +local monster = {} + +monster.description = "a walker" +monster.experience = 2200 +monster.outfit = { + lookType = 605, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1043 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "A few spawns in the Underground Glooth Factory, Glooth Factory, and Rathleton Sewers." + } + +monster.health = 3000 +monster.maxHealth = 3000 +monster.race = "venom" +monster.corpse = 23343 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 23569, chance = 3548}, + {id = 23541, chance = 1490}, + {id = 2148, chance = 100000, maxCount = 200}, + {id = 2152, chance = 51610, maxCount = 3}, + {id = 9970, chance = 16130, maxCount = 3}, + {id = 2149, chance = 6450, maxCount = 2}, + {id = 8472, chance = 3230}, + {id = 7591, chance = 3230}, + {id = 7590, chance = 2300}, + {id = 23540, chance = 1780}, + {id = 2645, chance = 450} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 70, attack = 50}, + {name ="walker skill reducer", interval = 2000, chance = 21, target = false}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_FIREDAMAGE, minDamage = -125, maxDamage = -245, length = 8, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false} +} + +monster.defenses = { + defense = 45, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 35}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = 40}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/war_golem.lua b/data/monster/constructs/war_golem.lua new file mode 100644 index 00000000000..cd6f596a2ca --- /dev/null +++ b/data/monster/constructs/war_golem.lua @@ -0,0 +1,152 @@ +local mType = Game.createMonsterType("War Golem") +local monster = {} + +monster.description = "a war golem" +monster.experience = 2310 +monster.outfit = { + lookType = 326, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 533 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Factory Quarter." + } + +monster.health = 4300 +monster.maxHealth = 4300 +monster.race = "venom" +monster.corpse = 10005 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Azerus barada nikto!", yell = false}, + {text = "Klonk klonk klonk", yell = false}, + {text = "Engaging Enemy!", yell = false}, + {text = "Threat level processed.", yell = false}, + {text = "Charging weapon systems!", yell = false}, + {text = "Auto repair in progress.", yell = false}, + {text = "The battle is joined!", yell = false}, + {text = "Termination initialized!", yell = false}, + {text = "Rrrtttarrrttarrrtta", yell = false}, + {text = "Eliminated", yell = false} +} + +monster.loot = { + {id = 2148, chance = 37500, maxCount = 90}, + {id = 2148, chance = 375000, maxCount = 80}, + {id = 8309, chance = 5260, maxCount = 5}, + {id = 2377, chance = 5500}, + {id = 2510, chance = 9000}, + {id = 2394, chance = 7000}, + {id = 2513, chance = 6500}, + {id = 8473, chance = 10080}, + {id = 7590, chance = 8860}, + {id = 5880, chance = 1920}, + {id = 7439, chance = 900}, + {id = 2438, chance = 6400}, + {id = 9809, chance = 260}, + {id = 2209, chance = 810}, + {id = 2213, chance = 1210}, + {id = 9980, chance = 130}, + {id = 9978, chance = 1080}, + {id = 7893, chance = 90}, + {id = 2645, chance = 620}, + {id = 7403, chance = 50}, + {id = 7422, chance = 120}, + {id = 7428, chance = 770}, + {id = 2177, chance = 1000}, + {id = 13292, chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -550}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -165, maxDamage = -220, range = 7, shootEffect = CONST_ANI_ENERGY, target = false}, + {name ="outfit", interval = 2000, chance = 1, range = 7, target = false, duration = 3000, outfitMonster = "skeleton"}, + {name ="war golem electrify", interval = 2000, chance = 15, range = 1, target = false}, + {name ="war golem skill reducer", interval = 2000, chance = 10, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="speed", interval = 2000, chance = 15, speedChange = 300, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 25}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 25} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/weeper.lua b/data/monster/constructs/weeper.lua new file mode 100644 index 00000000000..a77408ead42 --- /dev/null +++ b/data/monster/constructs/weeper.lua @@ -0,0 +1,135 @@ +local mType = Game.createMonsterType("Weeper") +local monster = {} + +monster.description = "a weeper" +monster.experience = 4800 +monster.outfit = { + lookType = 489, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 882 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 1, + Locations = "Warzone 2." + } + +monster.health = 6800 +monster.maxHealth = 6800 +monster.race = "fire" +monster.corpse = 17252 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 80, + random = 20, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 570, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Moooaaan", yell = false} +} + +monster.loot = { + {name = "small ruby", chance = 15690, maxCount = 3}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 99}, + {id = 2152, chance = 100000, maxCount = 7}, + {name = "fire sword", chance = 3280}, + {name = "fire axe", chance = 2150}, + {name = "great mana potion", chance = 14800, maxCount = 2}, + {name = "magma legs", chance = 790}, + {name = "magma coat", chance = 790}, + {name = "ultimate health potion", chance = 15440, maxCount = 2}, + {name = "fiery heart", chance = 13570}, + {id = 13757, chance = 1320}, + {name = "wand of everblazing", chance = 1480}, + {name = "violet crystal shard", chance = 5430}, + {name = "brown crystal splinter", chance = 12100, maxCount = 2}, + {name = "red crystal fragment", chance = 8880}, + {name = "magma clump", chance = 13240}, + {name = "blazing bone", chance = 14890}, + {name = "eye of a weeper", chance = 15870}, + {name = "prismatic bolt", chance = 10900, maxCount = 5} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -400, maxDamage = -1000, length = 8, spread = 3, effect = CONST_ME_FIREATTACK, target = false}, + {name ="combat", interval = 3000, chance = 100, type = COMBAT_FIREDAMAGE, minDamage = -80, maxDamage = -250, radius = 3, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = -800, length = 5, spread = 3, effect = CONST_ME_BLOCKHIT, target = false, duration = 30000} +} + +monster.defenses = { + defense = 50, + armor = 50, + {name ="invisible", interval = 2000, chance = 5, effect = CONST_ME_MAGIC_RED} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/constructs/worker_golem.lua b/data/monster/constructs/worker_golem.lua new file mode 100644 index 00000000000..b8e61c48b71 --- /dev/null +++ b/data/monster/constructs/worker_golem.lua @@ -0,0 +1,138 @@ +local mType = Game.createMonsterType("Worker Golem") +local monster = {} + +monster.description = "a worker golem" +monster.experience = 1250 +monster.outfit = { + lookType = 304, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 503 +monster.Bestiary = { + class = "Construct", + race = BESTY_RACE_CONSTRUCT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Factory Quarter." + } + +monster.health = 1470 +monster.maxHealth = 1470 +monster.race = "venom" +monster.corpse = 9801 +monster.speed = 160 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "INTRUDER ALARM!", yell = false}, + {text = "klonk klonk klonk", yell = false}, + {text = "Rrrtttarrrttarrrtta", yell = false}, + {text = "Awaiting orders.", yell = false}, + {text = "Secret objective complete.", yell = false} +} + +monster.loot = { + {name = "small diamond", chance = 1000, maxCount = 2}, + {name = "gold coin", chance = 43000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 40}, + {name = "might ring", chance = 370}, + {name = "life crystal", chance = 890}, + {name = "war hammer", chance = 920}, + {name = "iron ore", chance = 1001}, + {name = "bonebreaker", chance = 130}, + {name = "berserk potion", chance = 820}, + {name = "spiked squelcher", chance = 1003}, + {name = "great mana potion", chance = 1470}, + {name = "great health potion", chance = 2100}, + {name = "nail", chance = 5000, maxCount = 5}, + {name = "great spirit potion", chance = 830}, + {name = "gear wheel", chance = 1007}, + {id = 9809, chance = 200}, + {id = 9812, chance = 50}, + {id = 9979, chance = 2270}, + {name = "gear crystal", chance = 2270} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -240}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -125, range = 7, shootEffect = CONST_ANI_SMALLSTONE, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dawnport/brittle_skeleton.lua b/data/monster/dawnport/brittle_skeleton.lua new file mode 100644 index 00000000000..3ef328096b8 --- /dev/null +++ b/data/monster/dawnport/brittle_skeleton.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Brittle Skeleton") +local monster = {} + +monster.description = "a brittle skeleton" +monster.experience = 35 +monster.outfit = { + lookType = 33, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 50 +monster.maxHealth = 50 +monster.race = "undead" +monster.corpse = 5972 +monster.speed = 146 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2230, chance = 49870}, + {id = 2511, chance = 2920}, + {id = 2148, chance = 100000, maxCount = 5}, + {id = 2388, chance = 4770}, + {id = 2398, chance = 4770}, + {id = 12437, chance = 9280}, + {id = 2484, chance = 2920}, + {id = 2376, chance = 6100}, + {id = 2050, chance = 10610}, + {id = 2473, chance = 3980} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 18}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_LIFEDRAIN, minDamage = -7, maxDamage = -13, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, target = false} +} + +monster.defenses = { + defense = 9, + armor = 2 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dawnport/crazed_dwarf.lua b/data/monster/dawnport/crazed_dwarf.lua new file mode 100644 index 00000000000..7fc805552e1 --- /dev/null +++ b/data/monster/dawnport/crazed_dwarf.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("Crazed Dwarf") +local monster = {} + +monster.description = "a crazed dwarf" +monster.experience = 50 +monster.outfit = { + lookType = 69, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 105 +monster.maxHealth = 105 +monster.race = "blood" +monster.corpse = 6007 +monster.speed = 156 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2386, chance = 12860}, + {id = 2148, chance = 100000, maxCount = 4}, + {id = 2388, chance = 25710}, + {id = 2649, chance = 8570}, + {id = 2597, chance = 4290}, + {id = 2553, chance = 8570}, + {id = 2510, chance = 17140}, + {id = 2484, chance = 8570}, + {id = 2787, chance = 47140} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 26} +} + +monster.defenses = { + defense = 10, + armor = 7 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dawnport/dawn_bat.lua b/data/monster/dawnport/dawn_bat.lua new file mode 100644 index 00000000000..ac0c8009281 --- /dev/null +++ b/data/monster/dawnport/dawn_bat.lua @@ -0,0 +1,97 @@ +local mType = Game.createMonsterType("Dawn Bat") +local monster = {} + +monster.description = "a dawn bat" +monster.experience = 10 +monster.outfit = { + lookType = 122, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 30 +monster.maxHealth = 30 +monster.race = "blood" +monster.corpse = 6053 +monster.speed = 200 +monster.manaCost = 250 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 3, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 5120, maxCount = 3} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -8} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dawnport/dawn_scorpion.lua b/data/monster/dawnport/dawn_scorpion.lua new file mode 100644 index 00000000000..9cb116af5bb --- /dev/null +++ b/data/monster/dawnport/dawn_scorpion.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Dawn Scorpion") +local monster = {} + +monster.description = "a dawn scorpion" +monster.experience = 45 +monster.outfit = { + lookType = 43, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 65 +monster.maxHealth = 65 +monster.race = "venom" +monster.corpse = 5988 +monster.speed = 144 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 5, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 4} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 20, attack = 20, condition = {type = CONDITION_POISON, totalDamage = 40, interval = 4000}}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -10, maxDamage = -20, range = 1, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 5, + armor = 11 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dawnport/dawnfly.lua b/data/monster/dawnport/dawnfly.lua new file mode 100644 index 00000000000..2b5a0108749 --- /dev/null +++ b/data/monster/dawnport/dawnfly.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Dawnfly") +local monster = {} + +monster.description = "a dawnfly" +monster.experience = 35 +monster.outfit = { + lookType = 528, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 90 +monster.maxHealth = 90 +monster.race = "venom" +monster.corpse = 23825 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 23839, chance = 21360, maxCount = 16}, + {id = 2485, chance = 4140}, + {id = 19738, chance = 11940}, + {id = 19743, chance = 10130}, + {id = 2148, chance = 100000, maxCount = 12}, + {id = 7618, chance = 3630}, + {id = 7620, chance = 3800}, + {id = 2545, chance = 14500, maxCount = 8} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 16, condition = {type = CONDITION_POISON, totalDamage = 8, interval = 4000}}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_EARTHDAMAGE, minDamage = -4, maxDamage = -8, range = 7, shootEffect = CONST_ANI_POISONARROW, target = false} +} + +monster.defenses = { + defense = 2, + armor = 1, + {name ="speed", interval = 2000, chance = 11, speedChange = 238, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dawnport/juvenile_cyclops.lua b/data/monster/dawnport/juvenile_cyclops.lua new file mode 100644 index 00000000000..f745e847892 --- /dev/null +++ b/data/monster/dawnport/juvenile_cyclops.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Juvenile Cyclops") +local monster = {} + +monster.description = "a juvenile cyclops" +monster.experience = 130 +monster.outfit = { + lookType = 22, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 260 +monster.maxHealth = 260 +monster.race = "blood" +monster.corpse = 5962 +monster.speed = 160 +monster.manaCost = 490 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2464, chance = 10810}, + {id = 2458, chance = 12160}, + {id = 10574, chance = 4050}, + {id = 2148, chance = 100000, maxCount = 25}, + {id = 2388, chance = 9460}, + {id = 2398, chance = 18920}, + {id = 2666, chance = 30070}, + {id = 2510, chance = 1350}, + {id = 2468, chance = 9460}, + {id = 2376, chance = 21620}, + {id = 2129, chance = 1350} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 20, attack = 30}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -20, range = 7, shootEffect = CONST_ANI_LARGEROCK, target = false} +} + +monster.defenses = { + defense = 22, + armor = 6 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dawnport/lesser_fire_devil.lua b/data/monster/dawnport/lesser_fire_devil.lua new file mode 100644 index 00000000000..5e08b74bf4e --- /dev/null +++ b/data/monster/dawnport/lesser_fire_devil.lua @@ -0,0 +1,103 @@ +local mType = Game.createMonsterType("Lesser Fire Devil") +local monster = {} + +monster.description = "a lesser fire devil" +monster.experience = 110 +monster.outfit = { + lookType = 40, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 175 +monster.maxHealth = 175 +monster.race = "blood" +monster.corpse = 5985 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2260, chance = 21050}, + {id = 2148, chance = 100000, maxCount = 10}, + {id = 12469, chance = 22810}, + {id = 2050, chance = 1750}, + {id = 2050, chance = 1750} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 25}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_FIREDAMAGE, minDamage = -24, maxDamage = -36, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 35, type = COMBAT_FIREDAMAGE, minDamage = -4, maxDamage = -12, range = 7, radius = 2, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREATTACK, target = true} +} + +monster.defenses = { + defense = 9, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dawnport/meadow_strider.lua b/data/monster/dawnport/meadow_strider.lua new file mode 100644 index 00000000000..2a6b0c1e9cf --- /dev/null +++ b/data/monster/dawnport/meadow_strider.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("Meadow Strider") +local monster = {} + +monster.description = "a meadow strider" +monster.experience = 50 +monster.outfit = { + lookType = 530, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 100 +monster.maxHealth = 100 +monster.race = "blood" +monster.corpse = 23821 +monster.speed = 136 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2120, chance = 4530}, + {id = 2148, chance = 100000, maxCount = 10}, + {id = 3976, chance = 14280, maxCount = 2}, + {id = 2667, chance = 25180, maxCount = 2}, + {id = 2666, chance = 25250}, + {id = 19741, chance = 6060}, + {id = 7732, chance = 160}, + {id = 19742, chance = 8980}, + {id = 2397, chance = 7640}, + {id = 2398, chance = 8310}, + {id = 2388, chance = 6660} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 13}, + {name ="combat", interval = 2000, chance = 11, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -10, range = 7, shootEffect = CONST_ANI_SMALLSTONE, effect = CONST_ME_EXPLOSIONAREA, target = false} +} + +monster.defenses = { + defense = 2, + armor = 1, + {name ="speed", interval = 2000, chance = 13, speedChange = 192, effect = CONST_ME_HITAREA, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dawnport/mountain_troll.lua b/data/monster/dawnport/mountain_troll.lua new file mode 100644 index 00000000000..2d9369b4995 --- /dev/null +++ b/data/monster/dawnport/mountain_troll.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("Mountain Troll") +local monster = {} + +monster.description = "a mountain troll" +monster.experience = 12 +monster.outfit = { + lookType = 15, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 30 +monster.maxHealth = 30 +monster.race = "blood" +monster.corpse = 5960 +monster.speed = 110 +monster.manaCost = 290 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 10606, chance = 920}, + {id = 2148, chance = 100000, maxCount = 8}, + {id = 2380, chance = 3590}, + {id = 2467, chance = 4060}, + {id = 2666, chance = 27980}, + {id = 2384, chance = 3470}, + {id = 2120, chance = 7870}, + {id = 2389, chance = 6800}, + {id = 2448, chance = 3510} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 9} +} + +monster.defenses = { + defense = 2, + armor = 1 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dawnport/muglex_clan_assassin.lua b/data/monster/dawnport/muglex_clan_assassin.lua new file mode 100644 index 00000000000..a76dfc8d177 --- /dev/null +++ b/data/monster/dawnport/muglex_clan_assassin.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("Muglex Clan Assassin") +local monster = {} + +monster.description = "a muglex clan assassin" +monster.experience = 48 +monster.outfit = { + lookType = 296, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 75 +monster.maxHealth = 75 +monster.race = "blood" +monster.corpse = 6002 +monster.speed = 140 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 10000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2230, chance = 10760}, + {id = 2449, chance = 4890}, + {id = 2379, chance = 18090}, + {id = 2667, chance = 11000, maxCount = 2}, + {id = 2148, chance = 100000, maxCount = 18}, + {id = 2467, chance = 6460}, + {id = 2461, chance = 8070}, + {id = 2235, chance = 6850}, + {id = 2406, chance = 9780}, + {id = 2559, chance = 9540}, + {id = 1294, chance = 11980, maxCount = 3}, + {id = 2484, chance = 1710} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 15}, + {name ="drunk", interval = 2000, chance = 11, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false, duration = 3000}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -30, range = 6, shootEffect = CONST_ANI_THROWINGKNIFE, target = false} +} + +monster.defenses = { + defense = 5, + armor = 3, + {name ="invisible", interval = 2000, chance = 11, effect = CONST_ME_MAGIC_BLUE}, + {name ="speed", interval = 2000, chance = 10, speedChange = 145, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dawnport/muglex_clan_footman.lua b/data/monster/dawnport/muglex_clan_footman.lua new file mode 100644 index 00000000000..d5f02906358 --- /dev/null +++ b/data/monster/dawnport/muglex_clan_footman.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("Muglex Clan Footman") +local monster = {} + +monster.description = "a muglex clan footman" +monster.experience = 25 +monster.outfit = { + lookType = 61, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 50 +monster.maxHealth = 50 +monster.race = "blood" +monster.corpse = 6002 +monster.speed = 120 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2230, chance = 1410}, + {id = 2449, chance = 9440}, + {id = 2379, chance = 17040}, + {id = 2667, chance = 159200, maxCount = 2}, + {id = 12495, chance = 1130}, + {id = 2148, chance = 100000, maxCount = 6}, + {id = 2467, chance = 6060}, + {id = 2461, chance = 2680}, + {id = 2235, chance = 850}, + {id = 2406, chance = 9720}, + {id = 2559, chance = 7750}, + {id = 1294, chance = 15210} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 10}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -22, range = 7, shootEffect = CONST_ANI_SMALLSTONE, target = false} +} + +monster.defenses = { + defense = 4, + armor = 2 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dawnport/muglex_clan_scavenger.lua b/data/monster/dawnport/muglex_clan_scavenger.lua new file mode 100644 index 00000000000..51bb9744b1b --- /dev/null +++ b/data/monster/dawnport/muglex_clan_scavenger.lua @@ -0,0 +1,111 @@ +local mType = Game.createMonsterType("Muglex Clan Scavenger") +local monster = {} + +monster.description = "a muglex clan scavenger" +monster.experience = 37 +monster.outfit = { + lookType = 297, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 60 +monster.maxHealth = 60 +monster.race = "blood" +monster.corpse = 6002 +monster.speed = 132 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2230, chance = 10820}, + {id = 2449, chance = 11860}, + {id = 2379, chance = 30410}, + {id = 2667, chance = 16750, maxCount = 3}, + {id = 2148, chance = 100000, maxCount = 12}, + {id = 2467, chance = 7990}, + {id = 2461, chance = 7990}, + {id = 2235, chance = 9020}, + {id = 2406, chance = 11860}, + {id = 2559, chance = 15210}, + {id = 1294, chance = 22420, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 10}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -22, range = 7, shootEffect = CONST_ANI_SPEAR, target = false}, + {name ="combat", interval = 2000, chance = 3, type = COMBAT_LIFEDRAIN, minDamage = -20, maxDamage = -30, range = 1, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_MORTAREA, target = false} +} + +monster.defenses = { + defense = 4, + armor = 2, + {name ="combat", interval = 2000, chance = 1, type = COMBAT_HEALING, minDamage = 10, maxDamage = 20, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 5, speedChange = 140, effect = CONST_ME_ENERGYHIT, target = false, duration = 4000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dawnport/sacred_snake.lua b/data/monster/dawnport/sacred_snake.lua new file mode 100644 index 00000000000..94efd0539df --- /dev/null +++ b/data/monster/dawnport/sacred_snake.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Sacred Snake") +local monster = {} + +monster.description = "a sacred snake" +monster.experience = 0 +monster.outfit = { + lookType = 28, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10 +monster.maxHealth = 10 +monster.race = "blood" +monster.corpse = 23843 +monster.speed = 120 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "eggs of a sacred snake", chance = 100000, maxCount = 20} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -8, condition = {type = CONDITION_POISON, totalDamage = 1, interval = 4000}} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 5}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dawnport/salamander_trainer.lua b/data/monster/dawnport/salamander_trainer.lua new file mode 100644 index 00000000000..3b040dad63f --- /dev/null +++ b/data/monster/dawnport/salamander_trainer.lua @@ -0,0 +1,103 @@ +local mType = Game.createMonsterType("Salamander Trainer") +local monster = {} + +monster.description = "a salamander trainer" +monster.experience = 70 +monster.outfit = { + lookType = 15, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 220 +monster.maxHealth = 220 +monster.race = "blood" +monster.corpse = 5960 +monster.speed = 290 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 10606, chance = 1050}, + {id = 2148, chance = 65300, maxCount = 12}, + {id = 2666, chance = 15200}, + {id = 2120, chance = 7960}, + {id = 2389, chance = 12970, maxCount = 3} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 25} +} + +monster.defenses = { + defense = 13, + armor = 8, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 10, maxDamage = 25, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="salamander trainer summon", interval = 2000, chance = 30, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dawnport/scar_tribe_shaman.lua b/data/monster/dawnport/scar_tribe_shaman.lua new file mode 100644 index 00000000000..6ffea635469 --- /dev/null +++ b/data/monster/dawnport/scar_tribe_shaman.lua @@ -0,0 +1,111 @@ +local mType = Game.createMonsterType("Scar Tribe Shaman") +local monster = {} + +monster.description = "an scar tribe shaman" +monster.experience = 85 +monster.outfit = { + lookType = 6, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 115 +monster.maxHealth = 115 +monster.race = "blood" +monster.corpse = 5978 +monster.speed = 156 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 2000, + chance = 50 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Snake", chance = 25, interval = 2000, max = 4} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 12408, chance = 3700}, + {id = 2686, chance = 11110, maxCount = 2}, + {id = 2148, chance = 100000, maxCount = 17}, + {id = 11113, chance = 11110}, + {id = 12434, chance = 3700}, + {id = 2389, chance = 55560}, + {id = 2484, chance = 3700}, + {id = 2468, chance = 11110} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 10}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_ENERGYDAMAGE, minDamage = -10, maxDamage = -25, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_FIREDAMAGE, minDamage = -5, maxDamage = -30, range = 7, radius = 1, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true} +} + +monster.defenses = { + defense = 11, + armor = 4, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 25, maxDamage = 35, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dawnport/scar_tribe_warrior.lua b/data/monster/dawnport/scar_tribe_warrior.lua new file mode 100644 index 00000000000..1b1f14ec784 --- /dev/null +++ b/data/monster/dawnport/scar_tribe_warrior.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("Scar Tribe Warrior") +local monster = {} + +monster.description = "a scar tribe warrior" +monster.experience = 50 +monster.outfit = { + lookType = 7, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 125 +monster.maxHealth = 125 +monster.race = "blood" +monster.corpse = 5979 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Alk!", yell = false}, + {text = "Trak grrrr brik.", yell = false}, + {text = "Grow truk grrrr.", yell = false} +} + +monster.loot = { + {id = 12409, chance = 6740}, + {id = 2464, chance = 5620}, + {id = 2148, chance = 100000, maxCount = 8}, + {id = 2666, chance = 13480}, + {id = 12435, chance = 5620}, + {id = 12436, chance = 1120} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 25} +} + +monster.defenses = { + defense = 10, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dawnport/spidris_elitesumom.lua b/data/monster/dawnport/spidris_elitesumom.lua new file mode 100644 index 00000000000..b58fcb2d97b --- /dev/null +++ b/data/monster/dawnport/spidris_elitesumom.lua @@ -0,0 +1,96 @@ +local mType = Game.createMonsterType("Spidris Elite") +local monster = {} + +monster.description = "a spidris elite" +monster.experience = 4000 +monster.outfit = { + lookType = 457, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5000 +monster.maxHealth = 5000 +monster.race = "venom" +monster.corpse = 15296 +monster.speed = 394 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 75, attack = 82} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dawnport/troll-trained_salamander.lua b/data/monster/dawnport/troll-trained_salamander.lua new file mode 100644 index 00000000000..4d1b3fcc63a --- /dev/null +++ b/data/monster/dawnport/troll-trained_salamander.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("Troll-Trained Salamander") +local monster = {} + +monster.description = "a troll-trained salamander" +monster.experience = 23 +monster.outfit = { + lookType = 529, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 70 +monster.maxHealth = 70 +monster.race = "blood" +monster.corpse = 19707 +monster.speed = 112 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2386, chance = 5080}, + {id = 2449, chance = 4630}, + {id = 23839, chance = 17650, maxCount = 5}, + {id = 2148, chance = 100000, maxCount = 11}, + {id = 2458, chance = 6300}, + {id = 7618, chance = 1520}, + {id = 19737, chance = 34410, maxCount = 5}, + {id = 2666, chance = 9940}, + {id = 2545, chance = 2970, maxCount = 2}, + {id = 2406, chance = 4470}, + {id = 2554, chance = 5080}, + {id = 2482, chance = 4070} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 11, condition = {type = CONDITION_POISON, totalDamage = 5, interval = 4000}}, + {name ="combat", interval = 2000, chance = 11, type = COMBAT_EARTHDAMAGE, minDamage = -4, maxDamage = -6, range = 5, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_HITBYPOISON, target = true} +} + +monster.defenses = { + defense = 0, + armor = 0 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dawnport/troll_marauder.lua b/data/monster/dawnport/troll_marauder.lua new file mode 100644 index 00000000000..8e850860ace --- /dev/null +++ b/data/monster/dawnport/troll_marauder.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Troll Marauder") +local monster = {} + +monster.description = "a troll marauder" +monster.experience = 40 +monster.outfit = { + lookType = 281, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 70 +monster.maxHealth = 70 +monster.race = "blood" +monster.corpse = 7926 +monster.speed = 120 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 23839, chance = 5190, maxCount = 3}, + {id = 10606, chance = 2600}, + {id = 2148, chance = 100000, maxCount = 8}, + {id = 2643, chance = 5190}, + {id = 2666, chance = 24680}, + {id = 2170, chance = 1300}, + {id = 2389, chance = 25970}, + {id = 2448, chance = 10390}, + {id = 2484, chance = 9090}, + {id = 12471, chance = 5190}, + {id = 2512, chance = 11690} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 25} +} + +monster.defenses = { + defense = 4, + armor = 6 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dawnport/weakened_shlorg.lua b/data/monster/dawnport/weakened_shlorg.lua new file mode 100644 index 00000000000..f6e5a308154 --- /dev/null +++ b/data/monster/dawnport/weakened_shlorg.lua @@ -0,0 +1,142 @@ +local mType = Game.createMonsterType("Weakened Shlorg") +local monster = {} + +monster.description = "Weakened Shlorg" +monster.experience = 6500 +monster.outfit = { + lookType = 565, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "venom" +monster.corpse = 21299 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Tchhh!", yell = false}, + {text = "Slurp!", yell = false} +} + +monster.loot = { + {id = 21400, chance = 3000}, + {id = 2148, chance = 100000, maxCount = 105}, + {id = 2152, chance = 100000, maxCount = 8}, + {id = 21705, chance = 3000}, + {id = 21706, chance = 3000}, + {id = 2154, chance = 10000}, + {id = 2155, chance = 10000}, + {id = 8473, chance = 10000, maxCount = 3}, + {id = 8472, chance = 10000, maxCount = 3}, + {id = 7590, chance = 10000, maxCount = 3}, + {id = 2149, chance = 10000, maxCount = 5}, + {id = 9970, chance = 10000, maxCount = 5}, + {id = 8872, chance = 20000}, + {id = 5910, chance = 10000}, + {id = 5911, chance = 10000}, + {id = 5914, chance = 10000}, + {id = 2409, chance = 20000}, + {id = 8912, chance = 20000}, + {id = 8891, chance = 10000}, + {id = 10584, chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 150, attack = 50, condition = {type = CONDITION_POISON, totalDamage = 180, interval = 4000}}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -90, maxDamage = -180, length = 4, spread = 3, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -150, radius = 5, effect = CONST_ME_GREEN_RINGS, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 13, minDamage = -360, maxDamage = -440, radius = 5, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="shlorg paralyze", interval = 2000, chance = 11, target = false} +} + +monster.defenses = { + defense = 15, + armor = 10, + {name ="combat", interval = 2000, chance = 35, type = COMBAT_HEALING, minDamage = 95, maxDamage = 150, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/dawnport/woodling.lua b/data/monster/dawnport/woodling.lua new file mode 100644 index 00000000000..39a5ece9877 --- /dev/null +++ b/data/monster/dawnport/woodling.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Woodling") +local monster = {} + +monster.description = "a woodling" +monster.experience = 40 +monster.outfit = { + lookType = 535, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 80 +monster.maxHealth = 80 +monster.race = "blood" +monster.corpse = 23817 +monster.speed = 130 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 23839, chance = 9450, maxCount = 10}, + {id = 2148, chance = 100000, maxCount = 12}, + {id = 20103, chance = 14500}, + {id = 2120, chance = 5700}, + {id = 2484, chance = 4950}, + {id = 2526, chance = 2670}, + {id = 20102, chance = 20250}, + {id = 2787, chance = 18200, maxCount = 4} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 14}, + {name ="woodling paralyze", interval = 2000, chance = 10, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -4, maxDamage = -9, range = 3, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_INSECTS, target = false} +} + +monster.defenses = { + defense = 2, + armor = 1 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/askarak_demon.lua b/data/monster/demons/askarak_demon.lua new file mode 100644 index 00000000000..eb8b48b8345 --- /dev/null +++ b/data/monster/demons/askarak_demon.lua @@ -0,0 +1,135 @@ +local mType = Game.createMonsterType("Askarak Demon") +local monster = {} + +monster.description = "an askarak demon" +monster.experience = 900 +monster.outfit = { + lookType = 420, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 727 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Demonwar Crypt (teleporter before vampire shield quest)." + } + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "venom" +monster.corpse = 13815 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "DEATH TO THE SHABURAK!", yell = false}, + {text = "GREEN WILL RULE!", yell = false}, + {text = "ONLY WE ARE TRUE DEMONS!", yell = false}, + {text = "RED IS MAD!", yell = false}, + {text = "WE RULE!", yell = false} +} + +monster.loot = { + {name = "piggy bank", chance = 1052}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 40000, maxCount = 35}, + {name = "small emerald", chance = 6250, maxCount = 4}, + {name = "energy ring", chance = 961}, + {name = "brown mushroom", chance = 3846, maxCount = 5}, + {name = "magic sulphur", chance = 102}, + {name = "assassin star", chance = 4761, maxCount = 5}, + {name = "mastermind potion", chance = 431}, + {name = "strong health potion", chance = 5263}, + {name = "strong mana potion", chance = 5263}, + {name = "terra legs", chance = 123}, + {name = "springsprout rod", chance = 512} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -143}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -20, maxDamage = -60, range = 7, radius = 6, shootEffect = CONST_ANI_POISON, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="askarak wave", interval = 2000, chance = 15, minDamage = -75, maxDamage = -140, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -130, maxDamage = -170, length = 4, spread = 0, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = -600, radius = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 15000} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/askarak_lord.lua b/data/monster/demons/askarak_lord.lua new file mode 100644 index 00000000000..c9880fd7d66 --- /dev/null +++ b/data/monster/demons/askarak_lord.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Askarak Lord") +local monster = {} + +monster.description = "an askarak lord" +monster.experience = 1200 +monster.outfit = { + lookType = 410, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 728 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Demonwar Crypt." + } + +monster.health = 2100 +monster.maxHealth = 2100 +monster.race = "venom" +monster.corpse = 13956 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "DEATH TO THE SHABURAK!", yell = false}, + {text = "GREEN WILL RULE!", yell = false}, + {text = "ONLY WE ARE TRUE DEMONS!", yell = false}, + {text = "RED IS MAD!", yell = false}, + {text = "WE RULE!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 90}, + {name = "small emerald", chance = 5882, maxCount = 5}, + {name = "platinum coin", chance = 35333, maxCount = 2}, + {name = "energy ring", chance = 606}, + {name = "brown mushroom", chance = 5263, maxCount = 5}, + {name = "magic sulphur", chance = 620}, + {name = "assassin star", chance = 70, maxCount = 5}, + {name = "dreaded cleaver", chance = 30}, + {name = "mastermind potion", chance = 750}, + {name = "strong health potion", chance = 6250}, + {name = "strong mana potion", chance = 7692}, + {name = "terra mantle", chance = 70}, + {name = "springsprout rod", chance = 1010} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -186}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -40, maxDamage = -80, range = 7, radius = 6, shootEffect = CONST_ANI_POISON, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="askarak wave", interval = 2000, chance = 15, minDamage = -95, maxDamage = -180, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -130, maxDamage = -180, length = 4, spread = 0, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -650, radius = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 15000} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 120, maxDamage = 160, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/askarak_prince.lua b/data/monster/demons/askarak_prince.lua new file mode 100644 index 00000000000..54ab84b0a36 --- /dev/null +++ b/data/monster/demons/askarak_prince.lua @@ -0,0 +1,135 @@ +local mType = Game.createMonsterType("Askarak Prince") +local monster = {} + +monster.description = "an askarak prince" +monster.experience = 1700 +monster.outfit = { + lookType = 419, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 729 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Demonwar Crypt." + } + +monster.health = 2600 +monster.maxHealth = 2600 +monster.race = "venom" +monster.corpse = 13957 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "DEATH TO THE SHABURAK!", yell = false}, + {text = "GREEN WILL RULE!", yell = false}, + {text = "ONLY WE ARE TRUE DEMONS!", yell = false}, + {text = "RED IS MAD!", yell = false}, + {text = "WE RULE!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 86}, + {name = "small emerald", chance = 12500, maxCount = 5}, + {name = "platinum coin", chance = 35333, maxCount = 4}, + {name = "stealth ring", chance = 4545}, + {name = "giant sword", chance = 320}, + {name = "brown mushroom", chance = 6666, maxCount = 5}, + {name = "magic sulphur", chance = 740}, + {name = "mastermind potion", chance = 1315}, + {name = "strong health potion", chance = 14285}, + {name = "strong mana potion", chance = 14285}, + {name = "terra mantle", chance = 840}, + {name = "springsprout rod", chance = 950}, + {name = "demonic finger", chance = 420} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -353}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -70, maxDamage = -250, range = 7, radius = 6, shootEffect = CONST_ANI_POISON, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="askarak wave", interval = 2000, chance = 15, minDamage = -100, maxDamage = -200, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -100, maxDamage = -200, length = 4, spread = 0, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -700, radius = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 15000} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/brachiodemon.lua b/data/monster/demons/brachiodemon.lua new file mode 100644 index 00000000000..469d2aa9305 --- /dev/null +++ b/data/monster/demons/brachiodemon.lua @@ -0,0 +1,142 @@ +local mType = Game.createMonsterType("Brachiodemon") +local monster = {} + +monster.description = "a brachiodemon" +monster.experience = 22880 +monster.outfit = { + lookType = 1299, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1930 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 5000, + FirstUnlock = 25, + SecondUnlock = 2500, + CharmsPoints = 100, + Stars = 5, + Occurrence = 0, + Locations = "Claustrophobic Inferno." + } + +monster.health = 25000 +monster.maxHealth = 25000 +monster.race = "blood" +monster.corpse = 38652 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Feel the heat!", yell = false}, + {text = "Hand over your life.", yell = false}, + {text = "I can give you a hand... or two.", yell = false} +} + +monster.loot = { + {name = "crystal coin", chance = 70540}, + {name = "platinum coin", chance = 90540, maxCount = 32}, + {name = "ultimate health potion", chance = 32220, maxCount = 7}, + {id = 38771, chance = 35560}, -- Hand + {name = "skull staff", chance = 65560}, + {name = "epee", chance = 75560}, + {name = "crystal mace", chance = 25560}, + {name = "noble axe", chance = 8560}, + {name = "spellbook of mind control", chance = 9000}, + {id = 38772, chance = 7500}, -- Head + {name = "fire axe", chance = 13500}, + {name = "royal helmet", chance = 15500}, + {name = "mastermind shield", chance = 9500}, + {name = "assassin dagger", chance = 8500}, + {name = "butcher's axe", chance = 7500}, + {name = "jade hammer", chance = 6500}, + {name = "crystalline sword", chance = 5500}, + {name = "alloy legs", chance = 4500}, + {name = "metal bat", chance = 3500}, + {id = 26187, chance = 8920}, -- Ring of green plasma + {id = 38860, chance = 1550}, -- Diabolic skull + {id = 38944, chance = 50} -- Bag you desire +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -950}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -450, maxDamage = -700, range = 7, radius = 4, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_FIREDAMAGE, minDamage = -450, maxDamage = -900, radius = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 22, type = COMBAT_DEATHDAMAGE, minDamage = -450, maxDamage = -900, radius = 4, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 2000, chance = 24, type = COMBAT_FIREDAMAGE, minDamage = -450, maxDamage = -1000, radius = 4, effect = CONST_ME_EXPLOSIONAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -700, maxDamage = -1150, length = 8, effect = CONST_ME_EXPLOSIONHIT, target = false}, +} + +monster.defenses = { + defense = 90, + armor = 105 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -25}, + {type = COMBAT_HOLYDAMAGE , percent = -35}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) \ No newline at end of file diff --git a/data/monster/demons/dark_torturer.lua b/data/monster/demons/dark_torturer.lua new file mode 100644 index 00000000000..37d9db88d6f --- /dev/null +++ b/data/monster/demons/dark_torturer.lua @@ -0,0 +1,140 @@ +local mType = Game.createMonsterType("Dark Torturer") +local monster = {} + +monster.description = "a dark torturer" +monster.experience = 4650 +monster.outfit = { + lookType = 234, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 285 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Pits of Inferno, Vengoth, Blood Halls, Oramond Dungeon, Roshamuul Prison." + } + +monster.health = 7350 +monster.maxHealth = 7350 +monster.race = "undead" +monster.corpse = 6328 +monster.speed = 370 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You like it, don't you?", yell = false}, + {text = "IahaEhheAie!", yell = false}, + {text = "It's party time!", yell = false}, + {text = "Harrr, Harrr!", yell = false}, + {text = "The torturer is in!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 40000, maxCount = 99}, + {name = "platinum coin", chance = 55000, maxCount = 8}, + {name = "golden legs", chance = 30}, + {id = 2558, chance = 5250}, + {name = "steel boots", chance = 5050}, + {name = "ham", chance = 60000, maxCount = 2}, + {name = "orichalcum pearl", chance = 2760, maxCount = 2}, + {name = "cat's paw", chance = 2222}, + {name = "jewelled backpack", chance = 1192}, + {name = "soul orb", chance = 23000}, + {id = 6300, chance = 2008}, + {name = "demonic essence", chance = 8520}, + {name = "concentrated demonic blood", chance = 33333, maxCount = 3}, + {name = "assassin star", chance = 2222, maxCount = 5}, + {name = "vile axe", chance = 480}, + {name = "butcher's axe", chance = 850}, + {name = "great mana potion", chance = 14830, maxCount = 2}, + {name = "great health potion", chance = 10000, maxCount = 2}, + {name = "gold ingot", chance = 3140} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -500}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -781, range = 7, shootEffect = CONST_ANI_THROWINGKNIFE, target = false}, + {name ="dark torturer skill reducer", interval = 2000, chance = 5, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 90}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/dawnfire_asura.lua b/data/monster/demons/dawnfire_asura.lua new file mode 100644 index 00000000000..a1b9895384a --- /dev/null +++ b/data/monster/demons/dawnfire_asura.lua @@ -0,0 +1,146 @@ +local mType = Game.createMonsterType("Dawnfire Asura") +local monster = {} + +monster.description = "a dawnfire asura" +monster.experience = 4100 +monster.outfit = { + lookType = 150, + lookHead = 114, + lookBody = 94, + lookLegs = 78, + lookFeet = 79, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 1134 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Asura Palace." + } + +monster.health = 2900 +monster.maxHealth = 2900 +monster.race = "blood" +monster.corpse = 24643 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Encounter the flames of destiny!", yell = false}, + {text = "Fire and destruction!", yell = true}, + {text = "May the flames consume you!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 97000, maxCount = 242}, + {id = 2152, chance = 18200, maxCount = 6}, + {id = 6558, chance = 2000}, + {id = 7590, chance = 2000}, + {id = 2150, chance = 210, maxCount = 3}, + {id = 2145, chance = 300, maxCount = 3}, + {id = 2149, chance = 300, maxCount = 3}, + {id = 2147, chance = 350, maxCount = 3}, + {id = 9970, chance = 280, maxCount = 3}, + {id = 2158, chance = 300}, + {id = 6300, chance = 260}, + {id = 6500, chance = 330}, + {id = 8871, chance = 220}, + {id = 24630, chance = 500}, + {id = 7899, chance = 100}, + {id = 2194, chance = 400}, + {id = 2663, chance = 300}, + {id = 24637, chance = 300}, + {id = 24631, chance = 500}, + {id = 5911, chance = 300}, + {id = 2133, chance = 400}, + {id = 5944, chance = 300}, + {id = 8902, chance = 100}, + {id = 2187, chance = 200} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -269}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -70, range = 7, target = false}, + {name ="firefield", interval = 2000, chance = 10, range = 7, radius = 1, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -50, maxDamage = -200, length = 8, spread = 3, effect = CONST_ME_PURPLEENERGY, target = false}, + {name ="energy strike", interval = 2000, chance = 10, minDamage = -10, maxDamage = -100, range = 1, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -100, radius = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 30000} +} + +monster.defenses = { + defense = 55, + armor = 55, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 50, maxDamage = 100, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 320, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -15}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/demon.lua b/data/monster/demons/demon.lua new file mode 100644 index 00000000000..135c0f4d034 --- /dev/null +++ b/data/monster/demons/demon.lua @@ -0,0 +1,166 @@ +local mType = Game.createMonsterType("Demon") +local monster = {} + +monster.description = "a demon" +monster.experience = 6000 +monster.outfit = { + lookType = 35, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 35 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Hero Cave, Ferumbras' Citadel, Goroma, Ghostlands (Warlock area; unreachable), \z + Liberty Bay (hidden underground passage; unreachable), Razzachai, deep in Pits of Inferno \z + (found in every throneroom except Verminor's), deep Formorgar Mines, Demon Forge, \z + Alchemist Quarter, Magician Quarter, Chyllfroest, Oramond Dungeon, Abandoned Sewers." + } + +monster.health = 8200 +monster.maxHealth = 8200 +monster.race = "fire" +monster.corpse = 5995 +monster.speed = 256 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "fire elemental", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Your soul will be mine!", yell = false}, + {text = "MUHAHAHAHA!", yell = false}, + {text = "CHAMEK ATH UTHUL ARAK!", yell = false}, + {text = "I SMELL FEEEEAAAAAR!", yell = false}, + {text = "Your resistance is futile!", yell = false} +} + +monster.loot = { + {name = "purple tome", chance = 1180}, + {name = "gold coin", chance = 60000, maxCount = 100}, + {name = "gold coin", chance = 60000, maxCount = 100}, + {name = "small emerald", chance = 9690, maxCount = 5}, + {name = "small amethyst", chance = 7250, maxCount = 5}, + {name = "small ruby", chance = 7430, maxCount = 5}, + {name = "small topaz", chance = 7470, maxCount = 5}, + {name = "red gem", chance = 2220}, + {name = "demonic essence", chance = 14630}, + {name = "talon", chance = 3430}, + {name = "platinum coin", chance = 90540, maxCount = 8}, + {name = "might ring", chance = 1890}, + {name = "stealth ring", chance = 2170}, + {name = "platinum amulet", chance = 680}, + {name = "orb", chance = 2854}, + {name = "gold ring", chance = 1050}, + {name = "ring of healing", chance = 1990}, + {name = "giant sword", chance = 1980}, + {name = "ice rapier", chance = 1550}, + {name = "golden sickle", chance = 1440}, + {name = "fire axe", chance = 4030}, + {name = "devil helmet", chance = 1180}, + {name = "golden legs", chance = 440}, + {name = "magic plate armor", chance = 130}, + {name = "mastermind shield", chance = 480}, + {name = "demon shield", chance = 740}, + {name = "fire mushroom", chance = 19660, maxCount = 6}, + {name = "demon horn", chance = 14920}, + {name = "assassin star", chance = 12550, maxCount = 10}, + {name = "demonrage sword", chance = 70}, + {id = 7393, chance = 90}, + {name = "great mana potion", chance = 22220, maxCount = 3}, + {name = "ultimate health potion", chance = 19540, maxCount = 3}, + {name = "great spirit potion", chance = 18510, maxCount = 3} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -520}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -120, range = 7, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -150, maxDamage = -250, range = 7, radius = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="firefield", interval = 2000, chance = 10, range = 7, radius = 1, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -300, maxDamage = -490, length = 8, spread = 3, effect = CONST_ME_PURPLEENERGY, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -210, maxDamage = -300, range = 1, shootEffect = CONST_ANI_ENERGY, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -700, radius = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 30000} +} + +monster.defenses = { + defense = 55, + armor = 55, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 180, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 320, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/demon_outcast.lua b/data/monster/demons/demon_outcast.lua new file mode 100644 index 00000000000..56711b5e27c --- /dev/null +++ b/data/monster/demons/demon_outcast.lua @@ -0,0 +1,150 @@ +local mType = Game.createMonsterType("Demon Outcast") +local monster = {} + +monster.description = "a demon outcast" +monster.experience = 6200 +monster.outfit = { + lookType = 590, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1019 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Roshamuul Prison." + } + +monster.health = 6900 +monster.maxHealth = 6900 +monster.race = "blood" +monster.corpse = 22549 +monster.speed = 296 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "energy elemental", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Back in the evil business!", yell = false}, + {text = "This prison break will have casualties!", yell = false}, + {text = "At last someone to hurt", yell = false}, + {text = "No one will imprison me again!", yell = false} +} + +monster.loot = { + {name = "small diamond", chance = 10000, maxCount = 5}, + {name = "small sapphire", chance = 10000, maxCount = 5}, + {name = "small ruby", chance = 12000, maxCount = 5}, + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "small emerald", chance = 10000, maxCount = 5}, + {name = "platinum coin", chance = 100000, maxCount = 6}, + {name = "might ring", chance = 910}, + {name = "stealth ring", chance = 1300}, + {name = "platinum amulet", chance = 1000}, + {name = "ring of healing", chance = 3000}, + {name = "giant sword", chance = 2000}, + {name = "ice rapier", chance = 660}, + {name = "devil helmet", chance = 910}, + {name = "crusader helmet", chance = 740}, + {name = "crown shield", chance = 740}, + {name = "demon shield", chance = 170}, + {name = "fire mushroom", chance = 20600, maxCount = 6}, + {id = 5906, chance = 1000}, + {name = "assassin star", chance = 8340, maxCount = 10}, + {name = "demonrage sword", chance = 350}, + {name = "great mana potion", chance = 18000, maxCount = 2}, + {name = "ultimate health potion", chance = 20500, maxCount = 3}, + {name = "small topaz", chance = 9300, maxCount = 5}, + {name = "cluster of solace", chance = 550} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -250, maxDamage = -450, length = 6, spread = 3, effect = CONST_ME_PURPLEENERGY, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -350, maxDamage = -550, length = 8, spread = 3, effect = CONST_ME_YELLOWENERGY, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -100, maxDamage = -250, radius = 3, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="demon outcast skill reducer", interval = 2000, chance = 10, range = 5, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -80, maxDamage = -150, radius = 4, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 250, maxDamage = 425, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/destroyer.lua b/data/monster/demons/destroyer.lua new file mode 100644 index 00000000000..ad1005e4ce6 --- /dev/null +++ b/data/monster/demons/destroyer.lua @@ -0,0 +1,141 @@ +local mType = Game.createMonsterType("Destroyer") +local monster = {} + +monster.description = "a destroyer" +monster.experience = 2500 +monster.outfit = { + lookType = 236, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 287 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Pits of Inferno, Formorgar Mines, Alchemist Quarter, Oramond Dungeon." + } + +monster.health = 3700 +monster.maxHealth = 3700 +monster.race = "undead" +monster.corpse = 6320 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "COME HERE AND DIE!", yell = false}, + {text = "Destructiooooon!", yell = false}, + {text = "It's a good day to destroy!", yell = false} +} + +monster.loot = { + {name = "crystal necklace", chance = 578}, + {name = "gold coin", chance = 60000, maxCount = 100}, + {name = "gold coin", chance = 40000, maxCount = 100}, + {name = "gold coin", chance = 40000, maxCount = 100}, + {name = "gold coin", chance = 60000, maxCount = 41}, + {name = "small amethyst", chance = 7692, maxCount = 2}, + {name = "platinum coin", chance = 4166, maxCount = 3}, + {name = "mind stone", chance = 564}, + {name = "giant sword", chance = 1694}, + {name = "crowbar", chance = 14285}, + {name = "plate armor", chance = 4347}, + {name = "dark armor", chance = 10000}, + {name = "burst arrow", chance = 12500, maxCount = 12}, + {id = 2553, chance = 6250}, + {name = "steel boots", chance = 992}, + {name = "meat", chance = 50000, maxCount = 6}, + {name = "skull helmet", chance = 108}, + {name = "soul orb", chance = 6666}, + {id = 6300, chance = 144}, + {name = "demonic essence", chance = 20000}, + {name = "dreaded cleaver", chance = 833}, + {name = "chaos mace", chance = 869}, + {name = "great health potion", chance = 1136}, + {name = "metal spike", chance = 7142} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -500}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, range = 7, shootEffect = CONST_ANI_LARGEROCK, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="speed", interval = 2000, chance = 15, speedChange = 420, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 25}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -15}, + {type = COMBAT_HOLYDAMAGE , percent = -3}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/diabolic_imp.lua b/data/monster/demons/diabolic_imp.lua new file mode 100644 index 00000000000..a70a8cbe65d --- /dev/null +++ b/data/monster/demons/diabolic_imp.lua @@ -0,0 +1,139 @@ +local mType = Game.createMonsterType("Diabolic Imp") +local monster = {} + +monster.description = "a diabolic imp" +monster.experience = 2900 +monster.outfit = { + lookType = 237, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 288 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Inquisition, Pits of Inferno, Fenrock, Fury Dungeon and inside the \z + Hellgore volcano on Goroma during the Fire from the Earth Mini World Change." + } + +monster.health = 1950 +monster.maxHealth = 1950 +monster.race = "fire" +monster.corpse = 6364 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 400, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Muahaha!", yell = false}, + {text = "He he he.", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 40000, maxCount = 97}, + {name = "gold coin", chance = 3390, maxCount = 7}, + {name = "small amethyst", chance = 2250, maxCount = 3}, + {name = "stealth ring", chance = 2702}, + {name = "necrotic rod", chance = 830}, + {name = "blank rune", chance = 16666, maxCount = 2}, + {name = "double axe", chance = 1994}, + {id = 2419, chance = 5660}, + {name = "guardian shield", chance = 8130}, + {name = "pitchfork", chance = 50000}, + {name = "cleaver", chance = 8830}, + {name = "soul orb", chance = 7230}, + {id = 6300, chance = 120}, + {name = "demonic essence", chance = 8000}, + {name = "concentrated demonic blood", chance = 25000, maxCount = 2}, + {name = "magma coat", chance = 250}, + {name = "magma monocle", chance = 430} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -240, condition = {type = CONDITION_POISON, totalDamage = 160, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -240, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -300, maxDamage = -430, range = 7, radius = 2, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREATTACK, target = true}, + {name ="diabolic imp skill reducer", interval = 2000, chance = 5, range = 5, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 650, maxDamage = 800, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 800, effect = CONST_ME_MAGIC_RED, target = false, duration = 2000}, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_TELEPORT} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/duskbringer.lua b/data/monster/demons/duskbringer.lua new file mode 100644 index 00000000000..b9619139779 --- /dev/null +++ b/data/monster/demons/duskbringer.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("Duskbringer") +local monster = {} + +monster.description = "a duskbringer" +monster.experience = 2600 +monster.outfit = { + lookType = 300, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 581 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 50, + Stars = 3, + Occurrence = 3, + Locations = "Magician Quarter (Yalahar)." + } + +monster.health = 3550 +monster.maxHealth = 3550 +monster.race = "undead" +monster.corpse = 8955 +monster.speed = 370 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Death!", yell = false}, + {text = "Come a little closer!", yell = false}, + {text = "The end is near!", yell = false} +} + +monster.loot = { + {name = "midnight shard", chance = 10000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -350}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -165, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -350, maxDamage = -720, length = 8, spread = 3, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -300, length = 7, spread = 3, effect = CONST_ME_EXPLOSIONAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -225, maxDamage = -275, radius = 4, target = false} +} + +monster.defenses = { + defense = 42, + armor = 42, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 130, maxDamage = 205, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 450, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -80}, + {type = COMBAT_FIREDAMAGE, percent = -40}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = -30}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/fire_devil.lua b/data/monster/demons/fire_devil.lua new file mode 100644 index 00000000000..35c666e048d --- /dev/null +++ b/data/monster/demons/fire_devil.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Fire Devil") +local monster = {} + +monster.description = "a fire devil" +monster.experience = 145 +monster.outfit = { + lookType = 40, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 40 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Desert Dungeon, Ancient Temple, Magician Tower, Shadow Tomb, Ghostlands, Goroma, \z + Plains of Havoc at Ornamented Shield Quest, Spike Sword Quest." + } + +monster.health = 200 +monster.maxHealth = 200 +monster.race = "blood" +monster.corpse = 5985 +monster.speed = 180 +monster.manaCost = 530 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hot, eh?", yell = false}, + {text = "Hell, oh, hell!", yell = false} +} + +monster.loot = { + {id = 2050, chance = 10000}, + {id = 2050, chance = 1420, maxCount = 2}, + {name = "small amethyst", chance = 300}, + {name = "necrotic rod", chance = 460}, + {name = "blank rune", chance = 10950}, + {name = "double axe", chance = 1500}, + {id = 2419, chance = 3000}, + {name = "guardian shield", chance = 210}, + {name = "cleaver", chance = 1100}, + {name = "small pitchfork", chance = 19770} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -35}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -60, maxDamage = -90, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -20, maxDamage = -50, range = 7, radius = 2, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -20}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/floating_savant.lua b/data/monster/demons/floating_savant.lua new file mode 100644 index 00000000000..b842d3f2d54 --- /dev/null +++ b/data/monster/demons/floating_savant.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Floating Savant") +local monster = {} + +monster.description = "a floating savant" +monster.experience = 8000 +monster.outfit = { + lookType = 1063, + lookHead = 113, + lookBody = 94, + lookLegs = 78, + lookFeet = 78, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1637 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "The Extension Site" + } + +monster.health = 8000 +monster.maxHealth = 8000 +monster.race = "undead" +monster.corpse = 33341 +monster.speed = 330 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Lava Lurker Attendant", chance = 70, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "tssooosh tsoooosh tssoooosh!", yell = false} +} + +monster.loot = { + {name = "small enchanted ruby", chance = 10000, maxCount = 5}, + {name = "Red Crystal Fragment", chance = 10000, maxCount = 2}, + {name = "Red Gem", chance = 10000, maxCount = 3}, + {name = "Red Piece of Cloth", chance = 10000, maxCount = 3}, + {name = "Concentrated Demonic Blood", chance = 12000, maxCount = 5}, + {name = "Demonic Essence", chance = 10000, maxCount = 5}, + {id = 2553, chance = 10000}, + {name = "Sample of Monster Blood", chance = 10000, maxCount = 5} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -200}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -390, maxDamage = -480, range = 7, shootEffect = CONST_ANI_FIRE, target = false}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_ENERGYDAMAGE, minDamage = -390, maxDamage = -480, range = 7, shootEffect = CONST_ANI_ENERGY, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_FIREDAMAGE, minDamage = -300, maxDamage = -400, radius = 3, effect = CONST_ME_EXPLOSIONAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -490, maxDamage = -630, length = 4, spread = 3, effect = CONST_ME_HITBYFIRE, target = false} +} + +monster.defenses = { + defense = 40, + armor = 82 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 30}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/frost_flower_asura.lua b/data/monster/demons/frost_flower_asura.lua new file mode 100644 index 00000000000..744228d0768 --- /dev/null +++ b/data/monster/demons/frost_flower_asura.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("Frost Flower Asura") +local monster = {} + +monster.description = "a frost flower asura" +monster.experience = 4200 +monster.outfit = { + lookType = 150, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 86, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1619 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Asura Palace." + } + +monster.health = 3500 +monster.maxHealth = 3500 +monster.race = "blood" +monster.corpse = 33420 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 3, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 97000, maxCount = 242}, + {id = 2148, chance = 97000, maxCount = 102}, + {id = 2656, chance = 2000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -110, maxDamage = -400}, + {name ="combat", interval = 1300, chance = 14, type = COMBAT_HOLYDAMAGE, minDamage = -185, maxDamage = -210, length = 8, spread = 3, effect = CONST_ME_ICETORNADO, target = false}, + {name ="combat", interval = 1000, chance = 9, type = COMBAT_ICEDAMAGE, minDamage = -120, maxDamage = -200, range = 7, shootEffect = CONST_ANI_SMALLICE, effect = CONST_ME_ICEATTACK, target = true} +} + +monster.defenses = { + defense = 30, + armor = 56, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 90, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = -25}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/fury.lua b/data/monster/demons/fury.lua new file mode 100644 index 00000000000..6f7ab136e8b --- /dev/null +++ b/data/monster/demons/fury.lua @@ -0,0 +1,141 @@ +local mType = Game.createMonsterType("Fury") +local monster = {} + +monster.description = "a fury" +monster.experience = 3600 +monster.outfit = { + lookType = 149, + lookHead = 94, + lookBody = 77, + lookLegs = 96, + lookFeet = 0, + lookAddons = 3, + lookMount = 0 +} + +monster.raceId = 291 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Pits of Inferno (Apocalypse's Throne Room), The Inquisition Quest \z + (The Shadow Nexus, Battlefield), Vengoth, Fury Dungeon, Oramond Fury Dungeon, The Extension Site." + } + +monster.health = 4100 +monster.maxHealth = 4100 +monster.race = "blood" +monster.corpse = 20399 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ahhhhrrrr!", yell = false}, + {text = "Waaaaah!", yell = false}, + {text = "Caaarnaaage!", yell = false}, + {text = "Dieee!", yell = false} +} + +monster.loot = { + {id = 2124, chance = 410}, + {name = "gold coin", chance = 30000, maxCount = 100}, + {name = "gold coin", chance = 30000, maxCount = 100}, + {name = "gold coin", chance = 38000, maxCount = 69}, + {name = "platinum coin", chance = 2800, maxCount = 4}, + {name = "terra rod", chance = 20000}, + {name = "golden legs", chance = 130}, + {name = "steel boots", chance = 790}, + {name = "orichalcum pearl", chance = 1500, maxCount = 4}, + {name = "red piece of cloth", chance = 4000}, + {name = "soul orb", chance = 21500}, + {name = "soul orb", chance = 50}, + {id = 6301, chance = 60}, + {name = "demonic essence", chance = 22500}, + {name = "concentrated demonic blood", chance = 35000, maxCount = 3}, + {name = "assassin dagger", chance = 660}, + {name = "noble axe", chance = 2000}, + {name = "great health potion", chance = 10500}, + {name = "jalapeno pepper", chance = 29280, maxCount = 4} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -510}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -300, length = 8, spread = 3, effect = CONST_ME_EXPLOSIONAREA, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_DEATHDAMAGE, minDamage = -120, maxDamage = -700, length = 8, spread = 3, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -120, maxDamage = -300, radius = 4, target = false}, + {name ="fury skill reducer", interval = 2000, chance = 5, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -120, maxDamage = -300, radius = 3, effect = CONST_ME_HITAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -125, maxDamage = -250, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -800, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = false, duration = 30000} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="speed", interval = 2000, chance = 15, speedChange = 800, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/gozzler.lua b/data/monster/demons/gozzler.lua new file mode 100644 index 00000000000..3a4600716fe --- /dev/null +++ b/data/monster/demons/gozzler.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Gozzler") +local monster = {} + +monster.description = "a gozzler" +monster.experience = 180 +monster.outfit = { + lookType = 313, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 523 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Magician Quarter, cave in Beregar, Farmine Mines." + } + +monster.health = 240 +monster.maxHealth = 240 +monster.race = "undead" +monster.corpse = 9938 +monster.speed = 240 +monster.manaCost = 800 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Huhuhuhuuu!", yell = false}, + {text = "Let the fun begin!", yell = false}, + {text = "Yihahaha!", yell = false}, + {text = "I'll bite you! Nyehehehe!", yell = false}, + {text = "Nyarnyarnyarnyar.", yell = false} +} + +monster.loot = { + {name = "brown flask", chance = 8750}, + {name = "small sapphire", chance = 360}, + {name = "gold coin", chance = 52500, maxCount = 70}, + {name = "dwarven ring", chance = 190}, + {name = "battle axe", chance = 3100}, + {name = "sabre", chance = 8250}, + {name = "morning star", chance = 5000}, + {name = "serpent sword", chance = 250}, + {name = "clerical mace", chance = 900}, + {name = "plate shield", chance = 10000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -110}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -32, maxDamage = -135, range = 1, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 30, maxDamage = 50, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 210, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/grimeleech.lua b/data/monster/demons/grimeleech.lua new file mode 100644 index 00000000000..4ed6f931bf4 --- /dev/null +++ b/data/monster/demons/grimeleech.lua @@ -0,0 +1,153 @@ +local mType = Game.createMonsterType("Grimeleech") +local monster = {} + +monster.description = "a grimeleech" +monster.experience = 7216 +monster.outfit = { + lookType = 855, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1196 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "The Dungeons of The Ruthless Seven." + } + +monster.health = 9500 +monster.maxHealth = 9500 +monster.race = "undead" +monster.corpse = 25436 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 3000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Death... Taste!", yell = true} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 197}, + {name = "platinum coin", chance = 100000, maxCount = 8}, + {name = "great mana potion", chance = 34850, maxCount = 3}, + {name = "great health potion", chance = 34290, maxCount = 3}, + {name = "great spirit potion", chance = 30860, maxCount = 3}, + {name = "concentrated demonic blood", chance = 23400, maxCount = 3}, + {name = "demonic essence", chance = 19240}, + {name = "some grimeleech wings", chance = 19080}, + {name = "fire mushroom", chance = 15360, maxCount = 5}, + {name = "green mushroom", chance = 14800, maxCount = 5}, + {name = "small diamond", chance = 11290, maxCount = 5}, + {name = "small ruby", chance = 10750, maxCount = 5}, + {name = "small topaz", chance = 9660, maxCount = 5}, + {name = "small amethyst", chance = 9640, maxCount = 5}, + {name = "underworld rod", chance = 6890}, + {name = "wand of voodoo", chance = 4810}, + {name = "red gem", chance = 3930}, + {name = "yellow gem", chance = 2900}, + {name = "devil helmet", chance = 1360}, + {name = "magma legs", chance = 1150}, + {name = "demon shield", chance = 1010}, + {name = "nightmare blade", chance = 930}, + {name = "blue gem", chance = 780}, + {name = "rift crossbow", chance = 720}, + {name = "steel boots", chance = 640}, + {name = "rift shield", chance = 620}, + {name = "rift lance", chance = 580}, + {name = "rift bow", chance = 370}, + {name = "abyss hammer", chance = 210}, + {name = "vile axe", chance = 180}, + {name = "magic plate armor", chance = 60} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 70, attack = 80}, + {name ="melee", interval = 2000, chance = 2, skill = 153, attack = 100}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_PHYSICALDAMAGE, minDamage = 100, maxDamage = -565, range = 7, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_DEATHDAMAGE, minDamage = -150, maxDamage = -220, length = 8, spread = 3, target = false}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_DEATHDAMAGE, minDamage = -225, maxDamage = -375, radius = 4, target = false}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -300, length = 8, spread = 3, effect = CONST_ME_EXPLOSIONAREA, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 16, type = COMBAT_HEALING, minDamage = 130, maxDamage = 205, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="effect", interval = 2000, chance = 9, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="effect", interval = 2000, chance = 10, target = false}, + {name ="speed", interval = 2000, chance = 12, speedChange = 532, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 65}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 80} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/hellfire_fighter.lua b/data/monster/demons/hellfire_fighter.lua new file mode 100644 index 00000000000..fb97ddb6ae4 --- /dev/null +++ b/data/monster/demons/hellfire_fighter.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Hellfire Fighter") +local monster = {} + +monster.description = "a hellfire fighter" +monster.experience = 3120 +monster.outfit = { + lookType = 243, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 295 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Pits of Inferno, Demon Forge, Fury Dungeon." + } + +monster.health = 3800 +monster.maxHealth = 3800 +monster.race = "fire" +monster.corpse = 6324 +monster.speed = 330 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 80, + random = 20, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "emerald bangle", chance = 2200}, + {id = 2136, chance = 190}, + {name = "small diamond", chance = 1400}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 40000, maxCount = 100}, + {name = "gold coin", chance = 10000, maxCount = 46}, + {name = "wand of inferno", chance = 9450}, + {name = "burnt scroll", chance = 50000}, + {name = "blank rune", chance = 30000, maxCount = 2}, + {name = "fire sword", chance = 4140}, + {name = "fire axe", chance = 440}, + {name = "soul orb", chance = 12150}, + {name = "demonic essence", chance = 14500}, + {name = "magma legs", chance = 730}, + {name = "magma coat", chance = 470}, + {name = "fiery heart", chance = 9570}, + {name = "piece of hellfire armor", chance = 5060}, + {id = 13757, chance = 670} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -520}, + {name ="firefield", interval = 2000, chance = 10, range = 7, radius = 3, shootEffect = CONST_ANI_FIRE, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -392, maxDamage = -1500, length = 8, spread = 3, effect = CONST_ME_FIREATTACK, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -60, maxDamage = -330, range = 7, radius = 3, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="hellfire fighter soulfire", interval = 2000, chance = 15, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 25}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -25}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/hellflayer.lua b/data/monster/demons/hellflayer.lua new file mode 100644 index 00000000000..1f46008f06e --- /dev/null +++ b/data/monster/demons/hellflayer.lua @@ -0,0 +1,152 @@ +local mType = Game.createMonsterType("Hellflayer") +local monster = {} + +monster.description = "a hellflayer" +monster.experience = 11000 +monster.outfit = { + lookType = 856, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1198 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "The Dungeons of The Ruthless Seven." + } + +monster.health = 14000 +monster.maxHealth = 14000 +monster.race = "blood" +monster.corpse = 25440 +monster.speed = 330 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You should consider bargaining for your life!", yell = false}, + {text = "Your tainted soul belongs to us anyway!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 90000, maxCount = 130}, + {id = 2152, chance = 20000, maxCount = 9}, + {id = 6558, chance = 4000, maxCount = 3}, + {id = 9971, chance = 1300, maxCount = 2}, + {id = 7590, chance = 9600, maxCount = 2}, + {id = 8472, chance = 2300, maxCount = 2}, + {id = 2150, chance = 2000, maxCount = 5}, + {id = 2145, chance = 900, maxCount = 5}, + {id = 2149, chance = 900, maxCount = 5}, + {id = 2147, chance = 2000, maxCount = 5}, + {id = 9970, chance = 900, maxCount = 5}, + {id = 8473, chance = 5300, maxCount = 2}, + {id = 2136, chance = 1000}, + {id = 6500, chance = 1600}, + {id = 7632, chance = 800}, + {id = 2155, chance = 800}, + {id = 7891, chance = 500}, + {id = 7894, chance = 1200}, + {id = 2514, chance = 350}, + {id = 25385, chance = 800}, + {id = 2156, chance = 500}, + {id = 25522, chance = 280}, + {id = 25523, chance = 180}, + {id = 5741, chance = 450}, + {id = 25383, chance = 200}, + {id = 7413, chance = 900}, + {id = 2466, chance = 750}, + {id = 8902, chance = 900}, + {id = 2452, chance = 400} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 200, maxDamage = -869, condition = {type = CONDITION_FIRE, totalDamage = 6, interval = 9000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -170, maxDamage = -300, range = 7, shootEffect = CONST_ANI_POISON, target = false}, + {name ="renegade knight", interval = 2000, chance = 20, target = false}, + {name ="choking fear drown", interval = 2000, chance = 20, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -250, maxDamage = -500, radius = 4, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -50, maxDamage = -200, length = 8, spread = 3, effect = CONST_ME_PURPLEENERGY, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -300, maxDamage = -550, radius = 1, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREATTACK, target = true}, + {name ="warlock skill reducer", interval = 2000, chance = 5, range = 5, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 300, maxDamage = -500, radius = 1, shootEffect = CONST_ANI_EXPLOSION, effect = CONST_ME_SLEEP, target = true} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 80, maxDamage = 95, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/hellhound.lua b/data/monster/demons/hellhound.lua new file mode 100644 index 00000000000..35f3b6ae573 --- /dev/null +++ b/data/monster/demons/hellhound.lua @@ -0,0 +1,161 @@ +local mType = Game.createMonsterType("Hellhound") +local monster = {} + +monster.description = "a hellhound" +monster.experience = 5440 +monster.outfit = { + lookType = 240, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 294 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Infernatil's Throneroom The Inquisition Quest Area, Hellgorge, \z + Roshamuul Prison, Chyllfroest, Oramond Dungeon, The Extension Site and under the Asura Palace." + } + +monster.health = 7500 +monster.maxHealth = 7500 +monster.race = "blood" +monster.corpse = 6332 +monster.speed = 360 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "GROOOOWL!", yell = false} +} + +monster.loot = { + {id = 7426, chance = 2000}, + {id = 7368, chance = 25000, maxCount = 10}, + {id = 2231, chance = 900}, + {id = 2144, chance = 9200, maxCount = 4}, + {id = 18425, chance = 12500}, + {id = 6558, chance = 20000}, + {id = 6558, chance = 20000}, + {id = 6500, chance = 20000}, + {id = 4873, chance = 400}, + {id = 10553, chance = 10000}, + {id = 2392, chance = 7000}, + {id = 2393, chance = 1000}, + {id = 9971, chance = 1500}, + {id = 7590, chance = 30000, maxCount = 3}, + {id = 8472, chance = 20000}, + {id = 2155, chance = 1000}, + {id = 5910, chance = 5000}, + {id = 2671, chance = 30000, maxCount = 6}, + {id = 5925, chance = 10000}, + {id = 10554, chance = 20000}, + {id = 2430, chance = 7500}, + {id = 7890, chance = 3000}, + {id = 7891, chance = 1500}, + {id = 7899, chance = 800}, + {id = 7894, chance = 1000}, + {id = 7900, chance = 900}, + {id = 7421, chance = 1000}, + {id = 2152, chance = 100000, maxCount = 7}, + {id = 2156, chance = 4500}, + {id = 5911, chance = 3000}, + {id = 6553, chance = 1000}, + {id = 2149, chance = 10000, maxCount = 3}, + {id = 2147, chance = 10000, maxCount = 3}, + {id = 9970, chance = 10000, maxCount = 3}, + {id = 5944, chance = 20000}, + {id = 8473, chance = 16000}, + {id = 2187, chance = 7000}, + {id = 2154, chance = 4500}, + {id = 5914, chance = 6000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -520, condition = {type = CONDITION_POISON, totalDamage = 800, interval = 4000}}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -700, length = 8, spread = 3, effect = CONST_ME_CARNIPHILA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -395, maxDamage = -498, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -350, maxDamage = -660, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -350, maxDamage = -976, length = 8, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -403, radius = 1, effect = CONST_ME_HITBYFIRE, target = true}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -549, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="speed", interval = 2000, chance = 15, speedChange = 320, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 220, maxDamage = 425, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/hellspawn.lua b/data/monster/demons/hellspawn.lua new file mode 100644 index 00000000000..82d0b3898a3 --- /dev/null +++ b/data/monster/demons/hellspawn.lua @@ -0,0 +1,141 @@ +local mType = Game.createMonsterType("Hellspawn") +local monster = {} + +monster.description = "a hellspawn" +monster.experience = 2550 +monster.outfit = { + lookType = 322, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 519 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Magician Quarter, Vengoth, Deeper Banuta, Formorgar Mines, Chyllfroest, Oramond Dungeon." + } + +monster.health = 3500 +monster.maxHealth = 3500 +monster.race = "fire" +monster.corpse = 9923 +monster.speed = 344 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Your fragile bones are like toothpicks to me.", yell = false}, + {text = "You little weasel will not live to see another day.", yell = false}, + {text = "I'm just a messenger of what's yet to come.", yell = false}, + {text = "HRAAAAAAAAAAAAAAAARRRR!", yell = true}, + {text = "I'm taking you down with me!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 60000, maxCount = 100}, + {name = "gold coin", chance = 60000, maxCount = 100}, + {name = "gold coin", chance = 60000, maxCount = 36}, + {name = "morning star", chance = 10000}, + {name = "warrior helmet", chance = 1886}, + {name = "knight legs", chance = 3030}, + {name = "red mushroom", chance = 7692, maxCount = 2}, + {name = "demonic essence", chance = 9090}, + {name = "assassin star", chance = 9090, maxCount = 2}, + {name = "onyx flail", chance = 103}, + {name = "berserk potion", chance = 934}, + {name = "spiked squelcher", chance = 970}, + {name = "great health potion", chance = 40333}, + {name = "ultimate health potion", chance = 9090}, + {id = 9809, chance = 3125}, + {id = 9810, chance = 3125}, + {id = 9948, chance = 140}, + {name = "black skull", chance = 151}, + {name = "small topaz", chance = 5882, maxCount = 3}, + {name = "hellspawn tail", chance = 20000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -352}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -150, maxDamage = -175, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREATTACK, target = false}, + {name ="hellspawn soulfire", interval = 2000, chance = 10, range = 5, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 120, maxDamage = 230, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 270, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 40}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/herald_of_gloom.lua b/data/monster/demons/herald_of_gloom.lua new file mode 100644 index 00000000000..1dd33fa2deb --- /dev/null +++ b/data/monster/demons/herald_of_gloom.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Herald of Gloom") +local monster = {} + +monster.description = "a herald of gloom" +monster.experience = 450 +monster.outfit = { + lookType = 320, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 586 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 50, + Stars = 3, + Occurrence = 3, + Locations = "Edron." + } + +monster.health = 340 +monster.maxHealth = 340 +monster.race = "undead" +monster.corpse = 9915 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "The powers of light are waning.", yell = true}, + {text = "You will join us in eternal night!", yell = true}, + {text = "The shadows will engulf the world.", yell = true} +} + +monster.loot = { + {name = "midnight shard", chance = 1886} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -90}, + {name ="speed", interval = 3000, chance = 10, speedChange = -600, range = 7, effect = CONST_ME_MAGIC_RED, target = true, duration = 30000}, + {name ="combat", interval = 2000, chance = 24, type = COMBAT_HOLYDAMAGE, minDamage = -90, maxDamage = -170, range = 4, shootEffect = CONST_ANI_SMALLHOLY, target = false} +} + +monster.defenses = { + defense = 55, + armor = 50, + {name ="speed", interval = 1000, chance = 15, speedChange = 200, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000}, + {name ="invisible", interval = 5000, chance = 20, effect = CONST_ME_MAGIC_RED}, + {name ="outfit", interval = 1500, chance = 20, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 6000, outfitMonster = "nightstalker"}, + {name ="outfit", interval = 1500, chance = 10, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 6000, outfitMonster = "werewolf"}, + {name ="outfit", interval = 1500, chance = 10, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 6000, outfitMonster = "the count"}, + {name ="outfit", interval = 1500, chance = 10, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 6000, outfitMonster = "grim reaper"}, + {name ="outfit", interval = 1500, chance = 10, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 6000, outfitMonster = "tarantula"}, + {name ="outfit", interval = 1500, chance = 10, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 6000, outfitMonster = "ferumbras"} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/infernal_demon.lua b/data/monster/demons/infernal_demon.lua new file mode 100644 index 00000000000..3d44ea28492 --- /dev/null +++ b/data/monster/demons/infernal_demon.lua @@ -0,0 +1,135 @@ +local mType = Game.createMonsterType("Infernal Demon") +local monster = {} + +monster.description = "a infernal demon" +monster.experience = 26000 +monster.outfit = { + lookType = 1313, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1938 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 5000, + FirstUnlock = 25, + SecondUnlock = 2500, + CharmsPoints = 100, + Stars = 5, + Occurrence = 0, + Locations = "Claustrophobic Inferno." + } + +monster.health = 32000 +monster.maxHealth = 32000 +monster.race = "blood" +monster.corpse = 38736 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "The smell of fear follows you.", yell = false}, + {text = "Your soul will burn.", yell = false} +} + +monster.loot = { + {name = "crystal coin", chance = 70540}, + {name = "platinum coin", chance = 90540, maxCount = 50}, + {name = "ultimate health potion", chance = 32220, maxCount = 7}, + {name = "small diamond", chance = 65560, maxCount = 7}, + {name = "gold ingot", chance = 25560}, + {name = "blue crystal splinter", chance = 25560}, + {name = "cyan crystal fragment", chance = 25560}, + {name = "red crystal fragment", chance = 25560}, + {name = "magma boots", chance = 35500}, + {name = "blue gem", chance = 65560}, + {name = "giant sword", chance = 13500}, + {name = "war axe", chance = 9500}, + {name = "mercenary sword", chance = 11500}, + {name = "green crystal fragment", chance = 9500}, + {name = "onyx chip", chance = 7500}, + {id = 38944, chance = 50} -- Bag you desire +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1050}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -750, maxDamage = -1000, radius = 4, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -550, maxDamage = -900, range = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -800, maxDamage = -1250, length = 8, effect = CONST_ME_EXPLOSIONHIT, target = false} + -- Chain: const_me-> CONST_ME_WHITE_ENERGY_SPARK, combat_t->COMBAT_DEATHDAMAGE +} + +monster.defenses = { + defense = 110, + armor = 120, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 650, maxDamage = 1200, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 40}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -20}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) \ No newline at end of file diff --git a/data/monster/demons/juggernaut.lua b/data/monster/demons/juggernaut.lua new file mode 100644 index 00000000000..c17a2286512 --- /dev/null +++ b/data/monster/demons/juggernaut.lua @@ -0,0 +1,150 @@ +local mType = Game.createMonsterType("Juggernaut") +local monster = {} + +monster.description = "a juggernaut" +monster.experience = 11200 +monster.outfit = { + lookType = 244, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 296 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Deep in Pits of Inferno (Apocalypse's throne room), The Dark Path, \z + The Blood Halls, The Vats, The Hive, The Shadow Nexus, a room deep in Formorgar Mines, Roshamuul Prison, Oramond Dungeon, Grounds of Destruction." + } + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "blood" +monster.corpse = 6336 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 60, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "RAAARRR!", yell = false}, + {text = "GRRRRRR!", yell = false}, + {text = "WAHHHH!", yell = false} +} + +monster.loot = { + {id = 2136, chance = 550}, + {name = "small ruby", chance = 20000, maxCount = 4}, + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "small emerald", chance = 20000, maxCount = 5}, + {name = "platinum coin", chance = 100000, maxCount = 15}, + {name = "violet gem", chance = 830}, + {name = "green gem", chance = 869}, + {name = "red gem", chance = 13850}, + {name = "dragon hammer", chance = 9000}, + {name = "heavy mace", chance = 400}, + {name = "war axe", chance = 400}, + {name = "golden armor", chance = 550}, + {name = "golden legs", chance = 500}, + {name = "knight armor", chance = 4990}, + {name = "mastermind shield", chance = 800}, + {id = 2578, chance = 280}, + {name = "ham", chance = 60000, maxCount = 8}, + {name = "soul orb", chance = 33333}, + {name = "demonic essence", chance = 45333}, + {name = "concentrated demonic blood", chance = 25000, maxCount = 4}, + {name = "onyx arrow", chance = 11111, maxCount = 15}, + {name = "assassin star", chance = 25000, maxCount = 10}, + {name = "titan axe", chance = 4430}, + {name = "spiked squelcher", chance = 7761}, + {name = "great mana potion", chance = 35000}, + {name = "great health potion", chance = 32000}, + {name = "skullcracker armor", chance = 400}, + {name = "gold ingot", chance = 7692, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1470}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -780, range = 7, shootEffect = CONST_ANI_LARGEROCK, target = false} +} + +monster.defenses = { + defense = 60, + armor = 60, + {name ="speed", interval = 2000, chance = 15, speedChange = 520, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 400, maxDamage = 900, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 40}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/many_faces.lua b/data/monster/demons/many_faces.lua new file mode 100644 index 00000000000..245f40ba1fa --- /dev/null +++ b/data/monster/demons/many_faces.lua @@ -0,0 +1,140 @@ +local mType = Game.createMonsterType("Many Faces") +local monster = {} + +monster.description = "a many faces" +monster.experience = 28600 +monster.outfit = { + lookType = 1296, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1927 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 5000, + FirstUnlock = 25, + SecondUnlock = 2500, + CharmsPoints = 100, + Stars = 5, + Occurrence = 0, + Locations = "The Mirrored Nightmare." + } + +monster.health = 30000 +monster.maxHealth = 30000 +monster.race = "undead" +monster.corpse = 38640 +monster.speed = 215 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I have a head start.", yell = false}, + {text = "Look into my eyes! No, the other ones!", yell = false}, + {text = "The mirrors can't contain the night!", yell = false} +} + +monster.loot = { + {name = "crystal coin", chance = 70540}, + {name = "platinum coin", chance = 90540, maxCount = 32}, + {name = "ultimate health potion", chance = 32220, maxCount = 7}, + {name = "violet gem", chance = 74560}, + {name = "green gem", chance = 64560}, + {name = "blue gem", chance = 54560}, + {name = "northwind rod", chance = 11920}, + {name = "sacred tree amulet", chance = 21920}, + {id = 38768, chance = 10920}, -- Apron + {name = "glacier shoes", chance = 12920}, + {name = "glacier robe", chance = 22920}, + {name = "stone skin amulet", chance = 8920}, + {id = 26189, chance = 28920}, -- Ring of red plasma + {id = 38767, chance = 5920}, -- Head + {name = "glacial rod", chance = 3920}, + {id = 38859, chance = 450}, -- Gruesome fan + {id = 38944, chance = 50} -- Bag you desire +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -800}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -550, maxDamage = -800, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_ICEATTACK, target = true}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_ICEDAMAGE, minDamage = -500, maxDamage = -900, range = 7, radius = 5, shootEffect = CONST_ANI_ICE, effect = CONST_ME_ICEAREA, target = true}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_HOLYDAMAGE, minDamage = -500, maxDamage = -900, radius = 3, effect = CONST_ME_HOLYAREA, target = false}, + {name ="combat", interval = 3000, chance = 25, type = COMBAT_HOLYDAMAGE, minDamage = -500, maxDamage = -800, radius = 4, effect = CONST_ME_HOLYDAMAGE, target = false}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_HOLYDAMAGE, minDamage = -500, maxDamage = -900, radius = 4, effect = CONST_ME_HOLYAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -600, maxDamage = -1100, radius = 7, effect = CONST_ME_BIGCLOUDS, target = false} + -- Chain: const_me-> CONST_ME_YELLOW_ENERGY_SPARK, combat_t->COMBAT_HOLYDAMAGE + +} + +monster.defenses = { + defense = 90, + armor = 105 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) \ No newline at end of file diff --git a/data/monster/demons/midnight_asura.lua b/data/monster/demons/midnight_asura.lua new file mode 100644 index 00000000000..3140a4cbb75 --- /dev/null +++ b/data/monster/demons/midnight_asura.lua @@ -0,0 +1,152 @@ +local mType = Game.createMonsterType("Midnight Asura") +local monster = {} + +monster.description = "a midnight asura" +monster.experience = 4100 +monster.outfit = { + lookType = 150, + lookHead = 0, + lookBody = 114, + lookLegs = 90, + lookFeet = 90, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 1135 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Asura Palace." + } + +monster.health = 3100 +monster.maxHealth = 3100 +monster.race = "blood" +monster.corpse = 24644 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Death and Darkness!", yell = false}, + {text = "Embrace the night!", yell = false}, + {text = "May night fall upon you!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 97000, maxCount = 242}, + {id = 2152, chance = 18200, maxCount = 6}, + {id = 7368, chance = 2000, maxCount = 2}, + {id = 2144, chance = 2000}, + {id = 6558, chance = 2000}, + {id = 6500, chance = 2210}, + {id = 2145, chance = 800, maxCount = 3}, + {id = 2149, chance = 900, maxCount = 3}, + {id = 2147, chance = 650, maxCount = 3}, + {id = 2146, chance = 580, maxCount = 3}, + {id = 9970, chance = 580, maxCount = 3}, + {id = 7591, chance = 700}, + {id = 2143, chance = 560}, + {id = 7404, chance = 130}, + {id = 2158, chance = 320}, + {id = 2656, chance = 300}, + {id = 9971, chance = 300}, + {id = 24630, chance = 300}, + {id = 2186, chance = 300}, + {id = 2185, chance = 90}, + {id = 24637, chance = 80}, + {id = 24631, chance = 200}, + {id = 8889, chance = 90}, + {id = 2134, chance = 100}, + {id = 2170, chance = 100}, + {id = 5944, chance = 100}, + {id = 8902, chance = 100}, + {id = 3967, chance = 100}, + {id = 8910, chance = 70}, + {id = 2154, chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -269}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -70, range = 7, target = false}, + {name ="firefield", interval = 2000, chance = 10, range = 7, radius = 1, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -50, maxDamage = -200, length = 8, spread = 3, effect = CONST_ME_PURPLEENERGY, target = false}, + {name ="energy strike", interval = 2000, chance = 10, minDamage = -10, maxDamage = -100, range = 1, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -100, radius = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 30000} +} + +monster.defenses = { + defense = 55, + armor = 55, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 50, maxDamage = 100, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 320, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -15}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/nightfiend.lua b/data/monster/demons/nightfiend.lua new file mode 100644 index 00000000000..2775e0de06d --- /dev/null +++ b/data/monster/demons/nightfiend.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("Nightfiend") +local monster = {} + +monster.description = "a nightfiend" +monster.experience = 2100 +monster.outfit = { + lookType = 568, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 973 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 50, + Stars = 3, + Occurrence = 3, + Locations = "Deep under Drefia." + } + +monster.health = 2700 +monster.maxHealth = 2700 +monster.race = "blood" +monster.corpse = 2669 +monster.speed = 224 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 80, + health = 10, + damage = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -45}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = -5, maxDamage = -40, range = 7, shootEffect = CONST_ANI_THROWINGKNIFE, target = false} +} + +monster.defenses = { + defense = 11, + armor = 11 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/plaguesmith.lua b/data/monster/demons/plaguesmith.lua new file mode 100644 index 00000000000..4f7183aa4db --- /dev/null +++ b/data/monster/demons/plaguesmith.lua @@ -0,0 +1,150 @@ +local mType = Game.createMonsterType("Plaguesmith") +local monster = {} + +monster.description = "a plaguesmith" +monster.experience = 3555 +monster.outfit = { + lookType = 247, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 314 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Pits of Inferno, Formorgar Mines, Edron Demon Forge (The Vats, The Foundry), \z + Magician Quarter, Alchemist Quarter, Roshamuul Prison." + } + +monster.health = 8250 +monster.maxHealth = 8250 +monster.race = "venom" +monster.corpse = 6516 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 500, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You are looking a bit feverish!", yell = false}, + {text = "You don't look that good!", yell = false}, + {text = "Hachoo!", yell = false}, + {text = "Cough Cough", yell = false} +} + +monster.loot = { + {name = "emerald bangle", chance = 341}, + {name = "silver brooch", chance = 2000}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 40000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 65}, + {name = "small amethyst", chance = 5000, maxCount = 3}, + {name = "platinum coin", chance = 7142, maxCount = 2}, + {name = "axe ring", chance = 4347}, + {name = "club ring", chance = 4761}, + {name = "piece of iron", chance = 20000}, + {name = "mouldy cheese", chance = 50000}, + {id = 33528, chance = 60000}, + {name = "two handed sword", chance = 20000}, + {name = "war hammer", chance = 2127}, + {name = "morning star", chance = 29000}, + {name = "battle hammer", chance = 20000}, + {name = "hammer of wrath", chance = 952}, + {name = "knight legs", chance = 6250}, + {name = "steel shield", chance = 20000}, + {name = "steel boots", chance = 1123}, + {name = "piece of royal steel", chance = 1234}, + {name = "piece of hell steel", chance = 1010}, + {name = "piece of draconian steel", chance = 1030}, + {name = "soul orb", chance = 11111}, + {name = "demonic essence", chance = 9033}, + {name = "onyx arrow", chance = 7692, maxCount = 4}, + {name = "great health potion", chance = 10000}, + {id = 9810, chance = 540} +} + +monster.attacks = { + {name ="melee", interval = 1500, chance = 100, minDamage = 0, maxDamage = -539, condition = {type = CONDITION_POISON, totalDamage = 200, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -60, maxDamage = -114, radius = 4, effect = CONST_ME_POISONAREA, target = false}, + {name ="plaguesmith wave", interval = 2000, chance = 10, minDamage = -100, maxDamage = -350, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -800, radius = 4, effect = CONST_ME_POISONAREA, target = false, duration = 30000} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 200, maxDamage = 280, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 440, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 1} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/shaburak_demon.lua b/data/monster/demons/shaburak_demon.lua new file mode 100644 index 00000000000..fe5074d6d00 --- /dev/null +++ b/data/monster/demons/shaburak_demon.lua @@ -0,0 +1,135 @@ +local mType = Game.createMonsterType("Shaburak Demon") +local monster = {} + +monster.description = "a shaburak demon" +monster.experience = 900 +monster.outfit = { + lookType = 417, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 724 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Demonwar Crypt." + } + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "fire" +monster.corpse = 13814 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "GREEN IS MEAN!", yell = true}, + {text = "WE RULE!", yell = true}, + {text = "POWER TO THE SHABURAK!", yell = true}, + {text = "DEATH TO THE ASKARAK!", yell = false} +} + +monster.loot = { + {name = "piggy bank", chance = 1030}, + {name = "small ruby", chance = 4761, maxCount = 5}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 50}, + {name = "energy ring", chance = 1052}, + {name = "wand of inferno", chance = 564}, + {name = "brown mushroom", chance = 3846}, + {name = "magic sulphur", chance = 81}, + {name = "royal spear", chance = 10000, maxCount = 6}, + {name = "bullseye potion", chance = 628}, + {name = "strong health potion", chance = 4761}, + {name = "strong mana potion", chance = 5000}, + {name = "magma legs", chance = 155} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -113}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -20, maxDamage = -60, range = 7, radius = 6, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREATTACK, target = false}, + {name ="shaburak wave", interval = 2000, chance = 15, minDamage = -70, maxDamage = -140, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -130, maxDamage = -170, length = 4, spread = 0, effect = CONST_ME_FIREATTACK, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = -600, radius = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 15000} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 100, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = -30}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/shaburak_lord.lua b/data/monster/demons/shaburak_lord.lua new file mode 100644 index 00000000000..2c647762841 --- /dev/null +++ b/data/monster/demons/shaburak_lord.lua @@ -0,0 +1,135 @@ +local mType = Game.createMonsterType("Shaburak Lord") +local monster = {} + +monster.description = "a shaburak lord" +monster.experience = 1200 +monster.outfit = { + lookType = 409, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 725 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Demonwar Crypt." + } + +monster.health = 2100 +monster.maxHealth = 2100 +monster.race = "fire" +monster.corpse = 13958 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "GREEN IS MEAN!", yell = true}, + {text = "WE RULE!", yell = true}, + {text = "POWER TO THE SHABURAK!", yell = true}, + {text = "DEATH TO THE ASKARAK!", yell = false}, + {text = "ONLY WE ARE TRUE DEMONS!", yell = false} +} + +monster.loot = { + {name = "small ruby", chance = 6120, maxCount = 5}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 78}, + {name = "platinum coin", chance = 33333, maxCount = 2}, + {name = "energy ring", chance = 1652}, + {name = "wand of inferno", chance = 800}, + {name = "steel boots", chance = 160}, + {name = "brown mushroom", chance = 5346}, + {name = "magic sulphur", chance = 620}, + {name = "bullseye potion", chance = 400}, + {name = "strong health potion", chance = 7000}, + {name = "strong mana potion", chance = 7000}, + {name = "magma coat", chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -251}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -30, maxDamage = -75, range = 7, radius = 6, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREATTACK, target = false}, + {name ="shaburak wave", interval = 2000, chance = 15, minDamage = -80, maxDamage = -170, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -140, maxDamage = -200, length = 4, spread = 0, effect = CONST_ME_FIREATTACK, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = -650, radius = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 15000} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 100, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = -30}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/shaburak_prince.lua b/data/monster/demons/shaburak_prince.lua new file mode 100644 index 00000000000..88dd71da1ac --- /dev/null +++ b/data/monster/demons/shaburak_prince.lua @@ -0,0 +1,137 @@ +local mType = Game.createMonsterType("Shaburak Prince") +local monster = {} + +monster.description = "a shaburak Prince" +monster.experience = 1700 +monster.outfit = { + lookType = 418, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 726 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Demonwar Crypt." + } + +monster.health = 2600 +monster.maxHealth = 2600 +monster.race = "fire" +monster.corpse = 13969 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "GREEN IS MEAN!", yell = true}, + {text = "WE RULE!", yell = true}, + {text = "POWER TO THE SHABURAK!", yell = true}, + {text = "DEATH TO THE ASKARAK!", yell = false}, + {text = "ONLY WE ARE TRUE DEMONS!", yell = false} +} + +monster.loot = { + {name = "small ruby", chance = 12500, maxCount = 5}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 78}, + {name = "platinum coin", chance = 33333, maxCount = 4}, + {name = "stealth ring", chance = 5000}, + {name = "wand of inferno", chance = 892}, + {name = "steel boots", chance = 89}, + {name = "brown mushroom", chance = 4545}, + {name = "magic sulphur", chance = 534}, + {name = "butcher's axe", chance = 357}, + {name = "bullseye potion", chance = 714}, + {name = "strong health potion", chance = 14285}, + {name = "strong mana potion", chance = 14285}, + {name = "magma coat", chance = 714}, + {name = "demonic finger", chance = 178} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -319}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -40, maxDamage = -90, range = 7, radius = 6, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREATTACK, target = false}, + {name ="shaburak wave", interval = 2000, chance = 15, minDamage = -100, maxDamage = -200, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -150, maxDamage = -250, length = 4, spread = 0, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -700, radius = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 15000} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 100, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = -30}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/shadow_hound.lua b/data/monster/demons/shadow_hound.lua new file mode 100644 index 00000000000..f923da3120c --- /dev/null +++ b/data/monster/demons/shadow_hound.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Shadow Hound") +local monster = {} + +monster.description = "a shadow hound" +monster.experience = 600 +monster.outfit = { + lookType = 322, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 582 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 50, + Stars = 3, + Occurrence = 3, + Locations = "Ramoa." + } + +monster.health = 555 +monster.maxHealth = 555 +monster.race = "blood" +monster.corpse = 9923 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grrrr!", yell = true} +} + +monster.loot = { + {name = "midnight shard", chance = 8333} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -350}, + {name ="combat", interval = 2000, chance = 24, type = COMBAT_FIREDAMAGE, minDamage = -60, maxDamage = -160, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREATTACK, target = false} +} + +monster.defenses = { + defense = 55, + armor = 50, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_HEALING, minDamage = 60, maxDamage = 230, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -20}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/true_dawnfire_asura.lua b/data/monster/demons/true_dawnfire_asura.lua new file mode 100644 index 00000000000..c1421983f24 --- /dev/null +++ b/data/monster/demons/true_dawnfire_asura.lua @@ -0,0 +1,141 @@ +local mType = Game.createMonsterType("True Dawnfire Asura") +local monster = {} + +monster.description = "a true dawnfire asura" +monster.experience = 7475 +monster.outfit = { + lookType = 1068, + lookHead = 79, + lookBody = 94, + lookLegs = 120, + lookFeet = 79, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1620 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Asura Palace." + } + +monster.health = 8500 +monster.maxHealth = 8500 +monster.race = "blood" +monster.corpse = 33404 +monster.speed = 360 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 97000, maxCount = 242}, + {id = 2152, chance = 18200, maxCount = 6}, + {id = 6558, chance = 2000}, + {id = 7590, chance = 2000}, + {id = 2150, chance = 210, maxCount = 3}, + {id = 2145, chance = 300, maxCount = 3}, + {id = 2149, chance = 300, maxCount = 3}, + {id = 2147, chance = 350, maxCount = 3}, + {id = 9970, chance = 280, maxCount = 3}, + {id = 2158, chance = 400}, + {id = 6300, chance = 460}, + {id = 6500, chance = 430}, + {id = 8871, chance = 520}, + {id = 24630, chance = 800}, + {id = 7899, chance = 400}, + {id = 2194, chance = 400}, + {id = 2663, chance = 400}, + {id = 24637, chance = 400}, + {id = 24631, chance = 600}, + {id = 5911, chance = 300}, + {id = 2133, chance = 400}, + {id = 5944, chance = 400}, + {id = 8902, chance = 400}, + {id = 2187, chance = 400} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -269}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -100, range = 7, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -50, maxDamage = -200, length = 4, spread = 2, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = 120, maxDamage = 450, length = 1, spread = 0, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = 150, maxDamage = 350, radius = 3, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = 100, maxDamage = 300, radius = 4, effect = CONST_ME_BLACKSMOKE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -100, radius = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 30000} +} + +monster.defenses = { + defense = 55, + armor = 77, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 50, maxDamage = 100, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 320, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -15}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/true_frost_flower_asura.lua b/data/monster/demons/true_frost_flower_asura.lua new file mode 100644 index 00000000000..33f177308c4 --- /dev/null +++ b/data/monster/demons/true_frost_flower_asura.lua @@ -0,0 +1,139 @@ +local mType = Game.createMonsterType("True Frost Flower Asura") +local monster = {} + +monster.description = "a true frost flower asura" +monster.experience = 7069 +monster.outfit = { + lookType = 1068, + lookHead = 105, + lookBody = 0, + lookLegs = 105, + lookFeet = 8, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1622 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Asura Palace's secret basement." + } + +monster.health = 4000 +monster.maxHealth = 4000 +monster.race = "blood" +monster.corpse = 33408 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 3, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 97000, maxCount = 242}, + {id = 2152, chance = 18200, maxCount = 6}, + {id = 6558, chance = 2000}, + {id = 7590, chance = 2000}, + {id = 2150, chance = 210, maxCount = 3}, + {id = 2145, chance = 300, maxCount = 3}, + {id = 2149, chance = 300, maxCount = 3}, + {id = 2147, chance = 350, maxCount = 3}, + {id = 9970, chance = 280, maxCount = 3}, + {id = 2158, chance = 400}, + {id = 6300, chance = 460}, + {id = 6500, chance = 430}, + {id = 8871, chance = 520}, + {id = 24630, chance = 800}, + {id = 7899, chance = 400}, + {id = 2194, chance = 400}, + {id = 2663, chance = 400}, + {id = 24637, chance = 400}, + {id = 24631, chance = 600}, + {id = 5911, chance = 300}, + {id = 2133, chance = 400}, + {id = 2134, chance = 900}, + {id = 5944, chance = 400}, + {id = 8902, chance = 400} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -269}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -70, range = 7, target = false}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = 100, maxDamage = 400, length = 8, spread = 3, effect = CONST_ME_ICETORNADO, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = 100, maxDamage = 300, length = 8, spread = 3, effect = CONST_ME_PURPLEENERGY, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -100, radius = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 30000} +} + +monster.defenses = { + defense = 55, + armor = 55, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 50, maxDamage = 100, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 320, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -15}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/true_midnight_asura.lua b/data/monster/demons/true_midnight_asura.lua new file mode 100644 index 00000000000..b449277244d --- /dev/null +++ b/data/monster/demons/true_midnight_asura.lua @@ -0,0 +1,147 @@ +local mType = Game.createMonsterType("True Midnight Asura") +local monster = {} + +monster.description = "a true midnight asura" +monster.experience = 7313 +monster.outfit = { + lookType = 1068, + lookHead = 72, + lookBody = 95, + lookLegs = 72, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1621 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Asura Palace." + } + +monster.health = 9000 +monster.maxHealth = 9000 +monster.race = "blood" +monster.corpse = 33360 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 97000, maxCount = 242}, + {id = 2152, chance = 18200, maxCount = 6}, + {id = 7368, chance = 2000, maxCount = 2}, + {id = 2144, chance = 2000}, + {id = 6558, chance = 2000}, + {id = 6500, chance = 2210}, + {id = 2145, chance = 800, maxCount = 3}, + {id = 2149, chance = 900, maxCount = 3}, + {id = 2147, chance = 650, maxCount = 3}, + {id = 2146, chance = 580, maxCount = 3}, + {id = 9970, chance = 580, maxCount = 3}, + {id = 7591, chance = 700}, + {id = 2143, chance = 660}, + {id = 7404, chance = 430}, + {id = 2158, chance = 3420}, + {id = 2656, chance = 3400}, + {id = 9971, chance = 400}, + {id = 24630, chance = 600}, + {id = 2186, chance = 630}, + {id = 2185, chance = 690}, + {id = 24637, chance = 480}, + {id = 24631, chance = 500}, + {id = 8889, chance = 400}, + {id = 2134, chance = 600}, + {id = 2170, chance = 600}, + {id = 5944, chance = 600}, + {id = 8902, chance = 400}, + {id = 3967, chance = 400}, + {id = 8910, chance = 400}, + {id = 2154, chance = 400} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -269}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -70, range = 7, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = 100, maxDamage = 400, length = 8, spread = 3, effect = CONST_ME_PURPLEENERGY, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = 100, maxDamage = 400, length = 8, spread = 3, effect = CONST_ME_BLACKSMOKE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -100, radius = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 30000}, + {name ="drunk", interval = 2000, chance = 10, range = 3, radius = 4, effect = CONST_ME_STUN, target = true, duration = 4000} +} + +monster.defenses = { + defense = 55, + armor = 75, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 50, maxDamage = 100, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 320, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000}, + {name ="invisible", interval = 2000, chance = 20, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -15}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/demons/vexclaw.lua b/data/monster/demons/vexclaw.lua new file mode 100644 index 00000000000..77d3783c9ad --- /dev/null +++ b/data/monster/demons/vexclaw.lua @@ -0,0 +1,156 @@ +local mType = Game.createMonsterType("Vexclaw") +local monster = {} + +monster.description = "a vexclaw" +monster.experience = 6248 +monster.outfit = { + lookType = 854, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1197 +monster.Bestiary = { + class = "Demon", + race = BESTY_RACE_DEMON, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "The Dungeons of The Ruthless Seven." + } + +monster.health = 8500 +monster.maxHealth = 8500 +monster.race = "fire" +monster.corpse = 25432 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Weakness must be culled!", yell = false}, + {text = "Power is miiiiine!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 200}, + {name = "platinum coin", chance = 100000, maxCount = 6}, + {name = "great spirit potion", chance = 26010, maxCount = 5}, + {name = "great mana potion", chance = 25210, maxCount = 5}, + {name = "vexclaw talon", chance = 21500}, + {name = "demonic essence", chance = 20730}, + {name = "ultimate health potion", chance = 19960, maxCount = 5}, + {name = "fire mushroom", chance = 19940, maxCount = 6}, + {name = "golden sickle", chance = 18940}, + {name = "purple tome", chance = 18450}, + {name = "small amethyst", chance = 10090, maxCount = 5}, + {name = "small topaz", chance = 9790, maxCount = 5}, + {name = "small emerald", chance = 9770, maxCount = 5}, + {name = "small ruby", chance = 9590, maxCount = 5}, + {name = "talon", chance = 5400}, + {name = "yellow gem", chance = 5090}, + {name = "wand of voodoo", chance = 4940}, + {name = "red gem", chance = 4730}, + {name = "ice rapier", chance = 4730}, + {name = "fire axe", chance = 3520}, + {name = "might ring", chance = 2250}, + {name = "giant sword", chance = 1880}, + {name = "stealth ring", chance = 1790}, + {name = "energy ring", chance = 1790}, + {name = "rift lance", chance = 1360}, + {name = "ring of healing", chance = 1320}, + {name = "platinum amulet", chance = 940}, + {name = "devil helmet", chance = 520}, + {name = "rift crossbow", chance = 370}, + {name = "magic plate armor", chance = 70}, + {name = "demonrage sword", chance = 30} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 75, attack = 150}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -120, range = 7, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -150, maxDamage = -250, range = 7, radius = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="choking fear drown", interval = 2000, chance = 20, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -150, maxDamage = -400, radius = 4, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -50, maxDamage = -200, length = 8, spread = 3, effect = CONST_ME_PURPLEENERGY, target = false}, + {name ="firefield", interval = 2000, chance = 10, range = 7, radius = 1, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -300, maxDamage = -490, length = 8, spread = 3, effect = CONST_ME_PURPLEENERGY, target = false}, + {name ="energy strike", interval = 2000, chance = 10, minDamage = -210, maxDamage = -300, range = 1, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -300, radius = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 30000} +} + +monster.defenses = { + defense = 55, + armor = 55, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 180, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 320, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dragons/dragon.lua b/data/monster/dragons/dragon.lua new file mode 100644 index 00000000000..5ef6ac4a99c --- /dev/null +++ b/data/monster/dragons/dragon.lua @@ -0,0 +1,144 @@ +local mType = Game.createMonsterType("Dragon") +local monster = {} + +monster.description = "a dragon" +monster.experience = 700 +monster.outfit = { + lookType = 34, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 34 +monster.Bestiary = { + class = "Dragon", + race = BESTY_RACE_DRAGON, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Thais Ancient Temple, Darashia Dragon Lair, Mount Sternum Dragon Cave, Mintwallin, \z + deep in Fibula Dungeon, Kazordoon Dragon Lair (near Dwarf Bridge), Plains of Havoc, Elven Bane castle, \z + Maze of Lost Souls, southern cave and dragon tower in Shadowthorn, Orc Fortress, Venore Dragon Lair, \z + Pits of Inferno, Behemoth Quest room in Edron, Hero Cave, deep Cyclopolis, Edron Dragon Lair, Goroma, \z + Ankrahmun Dragon Lairs, Draconia, Dragonblaze Peaks, some Ankrahmun Tombs, \z + underground of Fenrock (on the way to Beregar), Krailos Steppe and Crystal Lakes." + } + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "blood" +monster.corpse = 2844 +monster.speed = 172 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "GROOAAARRR", yell = true}, + {text = "FCHHHHH", yell = true} +} + +monster.loot = { + {name = "small diamond", chance = 380}, + {name = "gold coin", chance = 47500, maxCount = 70}, + {name = "gold coin", chance = 37500, maxCount = 45}, + {name = "life crystal", chance = 120}, + {name = "wand of inferno", chance = 1005}, + {name = "double axe", chance = 960}, + {name = "longsword", chance = 4000}, + {name = "serpent sword", chance = 420}, + {name = "broadsword", chance = 1950}, + {name = "dragon hammer", chance = 560}, + {name = "crossbow", chance = 10000}, + {name = "steel helmet", chance = 3000}, + {name = "steel shield", chance = 15000}, + {name = "dragon shield", chance = 320}, + {name = "burst arrow", chance = 8060, maxCount = 10}, + {name = "plate legs", chance = 2000}, + {name = "dragon ham", chance = 65500, maxCount = 3}, + {name = "green dragon leather", chance = 1005}, + {name = "green dragon scale", chance = 1000}, + {name = "dragonbone staff", chance = 110}, + {name = "strong health potion", chance = 1000}, + {name = "dragon's tail", chance = 9740} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -120}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -60, maxDamage = -140, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -170, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 40, maxDamage = 70, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dragons/dragon_hatchling.lua b/data/monster/dragons/dragon_hatchling.lua new file mode 100644 index 00000000000..8c82b7815d8 --- /dev/null +++ b/data/monster/dragons/dragon_hatchling.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Dragon Hatchling") +local monster = {} + +monster.description = "a dragon hatchling" +monster.experience = 185 +monster.outfit = { + lookType = 271, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 385 +monster.Bestiary = { + class = "Dragon", + race = BESTY_RACE_DRAGON, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Thais Dragon Lair, beneath Fenrock, Darashia Dragon Lair, Venore Dragon Lair, \z + Edron Dragon Lair, Dragonblaze Peaks, Krailos Steppe. Also summoned by Lizard Dragon Priests." + } + +monster.health = 380 +monster.maxHealth = 380 +monster.race = "blood" +monster.corpse = 7621 +monster.speed = 146 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Fchu?", yell = false}, + {text = "Rooawwrr", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 67500, maxCount = 55}, + {name = "dragon ham", chance = 61000}, + {name = "health potion", chance = 400}, + {name = "dragon's tail", chance = 4300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -55}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -60, maxDamage = -90, length = 5, spread = 2, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -30, maxDamage = -55, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true} +} + +monster.defenses = { + defense = 10, + armor = 10, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 8, maxDamage = 33, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 75}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dragons/dragon_lord.lua b/data/monster/dragons/dragon_lord.lua new file mode 100644 index 00000000000..edb6e894023 --- /dev/null +++ b/data/monster/dragons/dragon_lord.lua @@ -0,0 +1,146 @@ +local mType = Game.createMonsterType("Dragon Lord") +local monster = {} + +monster.description = "a dragon lord" +monster.experience = 2100 +monster.outfit = { + lookType = 39, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 39 +monster.Bestiary = { + class = "Dragon", + race = BESTY_RACE_DRAGON, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Ankrahmun Dragon Lairs, Banshee Quest final room (level 60+ to open the door), \z + Deeper Cyclopolis past the Dragon Spawn (level 30+ to open the door), Draconia, Edron Dragon Lair, \z + Fibula Dungeon (level 50+ to open the door), Maze of Lost Souls (level 30+ to open the door), \z + Pits of Inferno Dragon Lair, Dragon Lord hole in Plains of Havoc, Carlin Dragon Lair, \z + Thais Dragon Lair, Goroma Dragon Lairs, Hot Spot, Venore Dragon Lair, Arena and Zoo Quarter (Yalahar), \z + beneath Fenrock, Darashia Dragon Lair, Razzachai, Dragonblaze Peaks, Ferumbras Citadel, \z + Fury Dungeon, Lower Spike, Krailos Steppe." + } + +monster.health = 1900 +monster.maxHealth = 1900 +monster.race = "blood" +monster.corpse = 5984 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "ZCHHHHHHH", yell = true}, + {text = "YOU WILL BURN!", yell = true} +} + +monster.loot = { + {id = 1976, chance = 9000}, + {name = "golden mug", chance = 3190}, + {name = "small sapphire", chance = 5300}, + {name = "gold coin", chance = 33750, maxCount = 100}, + {name = "gold coin", chance = 33750, maxCount = 100}, + {name = "gold coin", chance = 33750, maxCount = 45}, + {name = "energy ring", chance = 5250}, + {name = "life crystal", chance = 680}, + {name = "fire sword", chance = 290}, + {name = "strange helmet", chance = 360}, + {name = "dragon scale mail", chance = 170}, + {name = "royal helmet", chance = 280}, + {name = "tower shield", chance = 250}, + {name = "power bolt", chance = 6700, maxCount = 7}, + {name = "dragon ham", chance = 80000, maxCount = 5}, + {name = "green mushroom", chance = 12000}, + {name = "red dragon scale", chance = 1920}, + {name = "red dragon leather", chance = 1040}, + {name = "royal spear", chance = 8800, maxCount = 3}, + {name = "dragon lord trophy", chance = 80}, + {name = "dragon slayer", chance = 100}, + {name = "strong health potion", chance = 970} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -230}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -220, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="firefield", interval = 2000, chance = 10, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="combat", interval = 2000, chance = 22, type = COMBAT_FIREDAMAGE, minDamage = -150, maxDamage = -270, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false} +} + +monster.defenses = { + defense = 34, + armor = 34, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 57, maxDamage = 93, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dragons/dragon_lord_hatchling.lua b/data/monster/dragons/dragon_lord_hatchling.lua new file mode 100644 index 00000000000..85f028585da --- /dev/null +++ b/data/monster/dragons/dragon_lord_hatchling.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Dragon Lord Hatchling") +local monster = {} + +monster.description = "a dragon lord hatchling" +monster.experience = 645 +monster.outfit = { + lookType = 272, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 386 +monster.Bestiary = { + class = "Dragon", + race = BESTY_RACE_DRAGON, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Thais Dragon Lair, Venore Dragon Lair, Edron Dragon Lair by the Fire Axe Quest, \z + on the way to Pythius the Rotten, Razzachai, Dragonblaze Peaks." + } + +monster.health = 750 +monster.maxHealth = 750 +monster.race = "blood" +monster.corpse = 7622 +monster.speed = 168 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 30, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Fchu?", yell = false}, + {text = "Rooawwrr", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 33750, maxCount = 90}, + {name = "gold coin", chance = 33750, maxCount = 75}, + {name = "dragon ham", chance = 80000}, + {name = "green mushroom", chance = 560}, + {name = "mana potion", chance = 300}, + {name = "magma boots", chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -90}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -90, maxDamage = -125, length = 5, spread = 2, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -55, maxDamage = -105, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="firefield", interval = 2000, chance = 10, range = 7, radius = 3, shootEffect = CONST_ANI_FIRE, target = true} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 26, maxDamage = 48, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dragons/draken_abomination.lua b/data/monster/dragons/draken_abomination.lua new file mode 100644 index 00000000000..4ef78f3475f --- /dev/null +++ b/data/monster/dragons/draken_abomination.lua @@ -0,0 +1,143 @@ +local mType = Game.createMonsterType("Draken Abomination") +local monster = {} + +monster.description = "a draken abomination" +monster.experience = 3800 +monster.outfit = { + lookType = 357, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 673 +monster.Bestiary = { + class = "Dragon", + race = BESTY_RACE_DRAGON, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Razachai including the Inner Sanctum." + } + +monster.health = 6250 +monster.maxHealth = 6250 +monster.race = "venom" +monster.corpse = 12623 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Death Blob", chance = 10, interval = 2000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Uhhhg!", yell = false}, + {text = "Hmmnn!", yell = false}, + {text = "Aaag!", yell = false}, + {text = "Gll", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 47000, maxCount = 98}, + {name = "platinum coin", chance = 50590, maxCount = 8}, + {name = "meat", chance = 50450, maxCount = 4}, + {name = "great mana potion", chance = 9950, maxCount = 3}, + {name = "terra hood", chance = 8730}, + {name = "great spirit potion", chance = 4905, maxCount = 3}, + {name = "ultimate health potion", chance = 9400, maxCount = 3}, + {name = "wand of voodoo", chance = 1020}, + {name = "small topaz", chance = 2900, maxCount = 4}, + {name = "Zaoan armor", chance = 470}, + {name = "Zaoan helmet", chance = 560}, + {name = "Zaoan legs", chance = 780}, + {name = "eye of corruption", chance = 12110}, + {name = "tail of corruption", chance = 6240}, + {name = "scale of corruption", chance = 10940}, + {name = "shield of corruption", chance = 10}, + {name = "draken boots", chance = 540}, + {name = "snake god's wristguard", chance = 10}, + {name = "bamboo leaves", chance = 360} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -420}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -310, maxDamage = -630, length = 4, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="draken abomination curse", interval = 2000, chance = 10, range = 5, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -170, maxDamage = -370, length = 4, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="drunk", interval = 2000, chance = 15, range = 7, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false, duration = 9000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, range = 7, radius = 3, effect = CONST_ME_HITBYPOISON, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 650, maxDamage = 700, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dragons/draken_elite.lua b/data/monster/dragons/draken_elite.lua new file mode 100644 index 00000000000..7a01f5056ee --- /dev/null +++ b/data/monster/dragons/draken_elite.lua @@ -0,0 +1,141 @@ +local mType = Game.createMonsterType("Draken Elite") +local monster = {} + +monster.description = "a draken elite" +monster.experience = 4200 +monster.outfit = { + lookType = 362, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 672 +monster.Bestiary = { + class = "Dragon", + race = BESTY_RACE_DRAGON, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Razachai, including the Crystal Column chambers in the Inner Sanctum." + } + +monster.health = 5550 +monster.maxHealth = 5550 +monster.race = "blood" +monster.corpse = 12609 +monster.speed = 332 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "For ze emperor!", yell = false}, + {text = "You will die zhouzandz deazhz!", yell = false} +} + +monster.loot = { + {name = "small diamond", chance = 2440, maxCount = 4}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 47000, maxCount = 100}, + {name = "platinum coin", chance = 50360, maxCount = 8}, + {name = "meat", chance = 30175}, + {name = "magic sulphur", chance = 2100}, + {name = "assassin dagger", chance = 980}, + {name = "great mana potion", chance = 9340, maxCount = 3}, + {name = "ultimate health potion", chance = 9250, maxCount = 3}, + {name = "Zaoan armor", chance = 490}, + {name = "Zaoan helmet", chance = 150}, + {name = "Zaoan legs", chance = 770}, + {name = "Zaoan sword", chance = 490}, + {name = "elite draken mail", chance = 110}, + {name = "twiceslicer", chance = 910}, + {name = "draken sulphur", chance = 7600}, + {name = "draken wristbands", chance = 14030}, + {name = "broken draken mail", chance = 16930}, + {name = "broken slicer", chance = 24670}, + {name = "cobra crown", chance = 10}, + {name = "draken boots", chance = 600}, + {name = "snake god's wristguard", chance = 80}, + {name = "blade of corruption", chance = 20} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -354}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -240, maxDamage = -550, length = 4, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -300, range = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -280, maxDamage = -410, radius = 4, effect = CONST_ME_POFF, target = true}, + {name ="soulfire", interval = 2000, chance = 10, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -250, maxDamage = -320, range = 7, shootEffect = CONST_ANI_POISON, target = true} +} + +monster.defenses = { + defense = 45, + armor = 45, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 510, maxDamage = 600, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 40}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dragons/draken_spellweaver.lua b/data/monster/dragons/draken_spellweaver.lua new file mode 100644 index 00000000000..60d4bb4d110 --- /dev/null +++ b/data/monster/dragons/draken_spellweaver.lua @@ -0,0 +1,140 @@ +local mType = Game.createMonsterType("Draken Spellweaver") +local monster = {} + +monster.description = "a draken spellweaver" +monster.experience = 3100 +monster.outfit = { + lookType = 340, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 618 +monster.Bestiary = { + class = "Dragon", + race = BESTY_RACE_DRAGON, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Zao Palace, Razzachai, and Zzaion." + } + +monster.health = 5000 +monster.maxHealth = 5000 +monster.race = "blood" +monster.corpse = 11316 +monster.speed = 336 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Kazzzzzzuuum!", yell = false}, + {text = "Fissziss!", yell = false}, + {text = "Zzzzzooom!", yell = false} +} + +monster.loot = { + {name = "ring of the sky", chance = 370}, + {name = "small ruby", chance = 6910, maxCount = 5}, + {name = "gold coin", chance = 41000, maxCount = 100}, + {name = "gold coin", chance = 58000, maxCount = 100}, + {name = "platinum coin", chance = 25510, maxCount = 5}, + {name = "green gem", chance = 970}, + {name = "wand of inferno", chance = 1660}, + {name = "meat", chance = 30400}, + {name = "great mana potion", chance = 4970}, + {name = "focus cape", chance = 1450}, + {name = "Zaoan shoes", chance = 1980}, + {name = "weaver's wandtip", chance = 19790}, + {name = "draken trophy", chance = 10}, + {name = "spellweaver's robe", chance = 620}, + {name = "Zaoan robe", chance = 770}, + {name = "luminous orb", chance = 1980}, + {name = "draken sulphur", chance = 3930}, + {name = "harness", chance = 30}, + {name = "bamboo leaves", chance = 180} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -252}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -240, maxDamage = -480, length = 4, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -250, range = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -150, maxDamage = -300, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -200, maxDamage = -380, radius = 4, effect = CONST_ME_POFF, target = true}, + {name ="soulfire", interval = 2000, chance = 10, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -280, maxDamage = -360, shootEffect = CONST_ANI_POISON, target = true} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_MAGIC_RED}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 270, maxDamage = 530, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 75} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dragons/draken_warmaster.lua b/data/monster/dragons/draken_warmaster.lua new file mode 100644 index 00000000000..c37d914cbb2 --- /dev/null +++ b/data/monster/dragons/draken_warmaster.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Draken Warmaster") +local monster = {} + +monster.description = "a draken warmaster" +monster.experience = 2400 +monster.outfit = { + lookType = 334, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 617 +monster.Bestiary = { + class = "Dragon", + race = BESTY_RACE_DRAGON, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Zao Palace, Chazorai, Razzachai, and Zzaion." + } + +monster.health = 4150 +monster.maxHealth = 4150 +monster.race = "blood" +monster.corpse = 11107 +monster.speed = 324 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Attack aggrezzively! Dezztroy zze intruderzz!", yell = false}, + {text = "Hizzzzzz!", yell = false} +} + +monster.loot = { + {name = "ring of the sky", chance = 180}, + {name = "small ruby", chance = 1525, maxCount = 5}, + {name = "gold coin", chance = 47000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "platinum coin", chance = 50625, maxCount = 5}, + {name = "tower shield", chance = 2035}, + {name = "meat", chance = 30300}, + {name = "great health potion", chance = 4850, maxCount = 3}, + {name = "ultimate health potion", chance = 4020}, + {name = "Zaoan armor", chance = 790}, + {name = "Zaoan shoes", chance = 1900}, + {name = "Zaoan legs", chance = 960}, + {name = "drakinata", chance = 860}, + {name = "bone shoulderplate", chance = 12010}, + {name = "warmaster's wristguards", chance = 7000}, + {name = "Zaoan halberd", chance = 7925} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -240, maxDamage = -520, length = 4, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 510, maxDamage = 600, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 5}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dragons/elder_wyrm.lua b/data/monster/dragons/elder_wyrm.lua new file mode 100644 index 00000000000..a107439a1d3 --- /dev/null +++ b/data/monster/dragons/elder_wyrm.lua @@ -0,0 +1,139 @@ +local mType = Game.createMonsterType("Elder Wyrm") +local monster = {} + +monster.description = "an elder wyrm" +monster.experience = 2500 +monster.outfit = { + lookType = 561, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 963 +monster.Bestiary = { + class = "Dragon", + race = BESTY_RACE_DRAGON, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Drefia Wyrm Lair, Vandura Wyrm Cave, Glooth Factory (west)." + } + +monster.health = 2700 +monster.maxHealth = 2700 +monster.race = "blood" +monster.corpse = 21283 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 250, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "GRROARR", yell = false}, + {text = "GRRR", yell = false} +} + +monster.loot = { + {name = "small diamond", chance = 4000, maxCount = 5}, + {name = "gold coin", chance = 100000, maxCount = 174}, + {name = "platinum coin", chance = 25150, maxCount = 3}, + {name = "crossbow", chance = 9690}, + {name = "dragon ham", chance = 32420, maxCount = 2}, + {name = "soul orb", chance = 5980}, + {name = "dragonbone staff", chance = 100}, + {name = "shadow sceptre", chance = 310}, + {name = "strong health potion", chance = 17710}, + {name = "strong mana potion", chance = 20930}, + {name = "lightning pendant", chance = 520}, + {name = "lightning boots", chance = 310}, + {name = "lightning legs", chance = 930}, + {name = "lightning robe", chance = 310}, + {name = "composite hornbow", chance = 310}, + {name = "focus cape", chance = 100}, + {name = "wand of starstorm", chance = 410}, + {name = "wand of draconia", chance = 2000}, + {name = "shockwave amulet", chance = 100}, + {name = "wyrm scale", chance = 15980} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -360}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -90, maxDamage = -150, radius = 4, effect = CONST_ME_TELEPORT, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -140, maxDamage = -250, radius = 5, effect = CONST_ME_PURPLEENERGY, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, length = 8, spread = 3, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="elder wyrm wave", interval = 2000, chance = 10, minDamage = -200, maxDamage = -300, target = false} +} + +monster.defenses = { + defense = 45, + armor = 45, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 100, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 25}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dragons/frost_dragon.lua b/data/monster/dragons/frost_dragon.lua new file mode 100644 index 00000000000..09a0f1ed962 --- /dev/null +++ b/data/monster/dragons/frost_dragon.lua @@ -0,0 +1,145 @@ +local mType = Game.createMonsterType("Frost Dragon") +local monster = {} + +monster.description = "a frost dragon" +monster.experience = 2100 +monster.outfit = { + lookType = 248, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 317 +monster.Bestiary = { + class = "Dragon", + race = BESTY_RACE_DRAGON, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Okolnir, Razzachai, Ice Witch Temple, Frost Dragon Tunnel, \z + Yakchal Crypt (only during Yakchal's awakening ritual), Dragonblaze Peaks, Deeper Banuta, Chyllfroest." + } + +monster.health = 1800 +monster.maxHealth = 1800 +monster.race = "undead" +monster.corpse = 7091 +monster.speed = 212 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 250, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "YOU WILL FREEZE!", yell = true}, + {text = "ZCHHHHH!", yell = true}, + {text = "I am so cool.", yell = false}, + {text = "Chill out!", yell = false} +} + +monster.loot = { + {id = 1976, chance = 8500}, + {name = "golden mug", chance = 3000}, + {name = "small sapphire", chance = 5200}, + {name = "gold coin", chance = 33000, maxCount = 100}, + {name = "gold coin", chance = 33000, maxCount = 100}, + {name = "gold coin", chance = 33000, maxCount = 42}, + {name = "energy ring", chance = 5000}, + {name = "life crystal", chance = 520}, + {name = "ice rapier", chance = 350}, + {name = "strange helmet", chance = 450}, + {name = "dragon scale mail", chance = 80}, + {name = "royal helmet", chance = 210}, + {name = "tower shield", chance = 340}, + {name = "power bolt", chance = 6000, maxCount = 6}, + {name = "dragon ham", chance = 80370, maxCount = 5}, + {name = "green mushroom", chance = 12000}, + {name = "shard", chance = 550}, + {name = "dragon slayer", chance = 120}, + {id = 7441, chance = 4000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -225}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -175, maxDamage = -380, length = 8, spread = 3, effect = CONST_ME_POFF, target = false}, + {name ="speed", interval = 2000, chance = 5, speedChange = -700, radius = 3, effect = CONST_ME_POFF, target = false, duration = 12000}, + {name ="speed", interval = 2000, chance = 15, speedChange = -850, length = 7, spread = 3, effect = CONST_ME_ICEATTACK, target = false, duration = 18000}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_ICEDAMAGE, minDamage = -60, maxDamage = -120, radius = 3, effect = CONST_ME_ICETORNADO, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -100, maxDamage = -240, radius = 4, effect = CONST_ME_ICEAREA, target = true}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -220, length = 1, spread = 0, effect = CONST_ME_POFF, target = false}, + {name ="speed", interval = 2000, chance = 20, speedChange = -600, radius = 4, effect = CONST_ME_ICEAREA, target = true, duration = 12000} +} + +monster.defenses = { + defense = 45, + armor = 45, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 150, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 290, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dragons/frost_dragon_hatchling.lua b/data/monster/dragons/frost_dragon_hatchling.lua new file mode 100644 index 00000000000..98b3b7244f2 --- /dev/null +++ b/data/monster/dragons/frost_dragon_hatchling.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Frost Dragon Hatchling") +local monster = {} + +monster.description = "a frost dragon hatchling" +monster.experience = 745 +monster.outfit = { + lookType = 283, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 402 +monster.Bestiary = { + class = "Dragon", + race = BESTY_RACE_DRAGON, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Okolnir, Factory Quarter (Yalahar), Dragonblaze Peaks, Ice Witch Temple, \z + Frost Dragon Tunnel, Chyllfroest." + } + +monster.health = 800 +monster.maxHealth = 800 +monster.race = "undead" +monster.corpse = 7969 +monster.speed = 172 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 80, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Rooawwrr", yell = false}, + {text = "Fchu?", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 86750, maxCount = 55}, + {name = "dragon ham", chance = 79600}, + {name = "health potion", chance = 560}, + {name = "spellbook of enlightenment", chance = 400}, + {name = "frosty heart", chance = 5000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -160}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -60, maxDamage = -110, length = 5, spread = 2, effect = CONST_ME_ICEATTACK, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -60, maxDamage = -110, radius = 4, effect = CONST_ME_ICEAREA, target = true}, + {name ="speed", interval = 2000, chance = 15, speedChange = -600, radius = 4, shootEffect = CONST_ANI_ICE, effect = CONST_ME_ICEAREA, target = true, duration = 12000} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 45, maxDamage = 50, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dragons/ghastly_dragon.lua b/data/monster/dragons/ghastly_dragon.lua new file mode 100644 index 00000000000..100765f89be --- /dev/null +++ b/data/monster/dragons/ghastly_dragon.lua @@ -0,0 +1,148 @@ +local mType = Game.createMonsterType("Ghastly Dragon") +local monster = {} + +monster.description = "a ghastly dragon" +monster.experience = 4600 +monster.outfit = { + lookType = 351, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 643 +monster.Bestiary = { + class = "Dragon", + race = BESTY_RACE_DRAGON, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Ghastly Dragon Lair, Corruption Hole, Razachai including the Inner Sanctum, \z + Zao Palace, Deeper Banuta, Chyllfroest." + } + +monster.health = 7800 +monster.maxHealth = 7800 +monster.race = "undead" +monster.corpse = 11362 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 366, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "EMBRACE MY GIFTS!", yell = true}, + {text = "I WILL FEAST ON YOUR SOUL!", yell = true} +} + +monster.loot = { + {name = "gold coin", chance = 33725, maxCount = 100}, + {name = "gold coin", chance = 33725, maxCount = 100}, + {name = "gold coin", chance = 33725, maxCount = 66}, + {name = "platinum coin", chance = 29840, maxCount = 2}, + {name = "soul orb", chance = 12170}, + {name = "demonic essence", chance = 8920}, + {name = "great mana potion", chance = 30560, maxCount = 2}, + {name = "terra legs", chance = 3130}, + {name = "terra boots", chance = 9510}, + {name = "great spirit potion", chance = 29460, maxCount = 2}, + {name = "ultimate health potion", chance = 24700}, + {id = 9810, chance = 180}, + {name = "shiny stone", chance = 860}, + {name = "guardian boots", chance = 200}, + {name = "Zaoan armor", chance = 870}, + {name = "Zaoan helmet", chance = 150}, + {name = "Zaoan shoes", chance = 870}, + {name = "Zaoan legs", chance = 1400}, + {name = "drakinata", chance = 1470}, + {name = "Zaoan sword", chance = 100}, + {name = "twin hooks", chance = 15100}, + {name = "Zaoan halberd", chance = 15020}, + {name = "spellweaver's robe", chance = 690}, + {name = "ghastly dragon head", chance = 6650}, + {name = "undead heart", chance = 19830}, + {name = "jade hat", chance = 810} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -603}, + {name ="ghastly dragon curse", interval = 2000, chance = 5, range = 5, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -920, maxDamage = -1280, range = 5, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -80, maxDamage = -230, range = 7, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="ghastly dragon wave", interval = 2000, chance = 10, minDamage = -120, maxDamage = -250, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -110, maxDamage = -180, radius = 4, effect = CONST_ME_MORTAREA, target = false}, + {name ="speed", interval = 2000, chance = 20, speedChange = -800, range = 7, effect = CONST_ME_SMALLCLOUDS, target = true, duration = 30000} +} + +monster.defenses = { + defense = 35, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = -15}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dragons/haunted_dragon.lua b/data/monster/dragons/haunted_dragon.lua new file mode 100644 index 00000000000..058bc198f62 --- /dev/null +++ b/data/monster/dragons/haunted_dragon.lua @@ -0,0 +1,139 @@ +local mType = Game.createMonsterType("Haunted Dragon") +local monster = {} + +monster.description = "a haunted dragon" +monster.experience = 6500 +monster.outfit = { + lookType = 231, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1376 +monster.Bestiary = { + class = "Dragon", + race = BESTY_RACE_DRAGON, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 2, + Locations = "The First Dragon's Lair, fourth floor." + } + +monster.health = 6500 +monster.maxHealth = 6500 +monster.race = "undead" +monster.corpse = 6306 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "black pearl", chance = 22780, maxCount = 2}, + {name = "small sapphire", chance = 28370, maxCount = 2}, + {name = "gold coin", chance = 35500, maxCount = 100}, + {name = "gold coin", chance = 55500, maxCount = 98}, + {name = "platinum coin", chance = 52000, maxCount = 5}, + {name = "life crystal", chance = 2500}, + {name = "hardened bone", chance = 14180}, + {id = 6300, chance = 1150}, + {name = "demonic essence", chance = 12460}, + {name = "assassin star", chance = 26650, maxCount = 5}, + {name = "dragon slayer", chance = 860}, + {name = "dragonbone staff", chance = 4000}, + {name = "great mana potion", chance = 21490}, + {name = "great health potion", chance = 21200}, + {name = "skullcracker armor", chance = 290}, + {name = "gold ingot", chance = 570}, + {name = "unholy bone", chance = 33380}, + {name = "spellweaver's robe", chance = 860} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -480}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_PHYSICALDAMAGE, minDamage = -300, maxDamage = -400, range = 7, radius = 4, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -125, maxDamage = -600, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_EARTHDAMAGE, minDamage = -100, maxDamage = -390, range = 7, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -150, maxDamage = -690, length = 8, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -300, maxDamage = -700, length = 8, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -100, maxDamage = -200, radius = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="undead dragon curse", interval = 2000, chance = 10, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dragons/hydra.lua b/data/monster/dragons/hydra.lua new file mode 100644 index 00000000000..3ac4dcbefd2 --- /dev/null +++ b/data/monster/dragons/hydra.lua @@ -0,0 +1,142 @@ +local mType = Game.createMonsterType("Hydra") +local monster = {} + +monster.description = "a hydra" +monster.experience = 2100 +monster.outfit = { + lookType = 121, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 121 +monster.Bestiary = { + class = "Dragon", + race = BESTY_RACE_DRAGON, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Many on the northern Hydra Mountain in east Tiquanda, 3-4 on the southern Hydra Mountain, \z + 1 at the Hydra Egg Quest in Tiquanda, 1 north-east of the Elephant Tusk Quest, \z + 2 above the Forbidden Lands hydra cave here and many inside it, many in Deeper Banuta, \z + many on Talahu surface, a few in Ferumbras Citadel basement on Kharos, \z + 2 on a hill in the Yalahar Arena and Zoo Quarter, 1 deep in the Yalahar Foreigner Quarter (Crystal Lake), \z + many in the Oramond Hydra/Bog Raider Cave." + } + +monster.health = 2350 +monster.maxHealth = 2350 +monster.race = "blood" +monster.corpse = 6048 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "FCHHHHH", yell = false}, + {text = "HISSSS", yell = false} +} + +monster.loot = { + {name = "small sapphire", chance = 5000}, + {name = "gold coin", chance = 34000, maxCount = 100}, + {name = "gold coin", chance = 34000, maxCount = 100}, + {name = "gold coin", chance = 20000, maxCount = 46}, + {name = "platinum coin", chance = 48000, maxCount = 3}, + {name = "life crystal", chance = 570}, + {name = "boots of haste", chance = 130}, + {name = "stone skin amulet", chance = 900}, + {name = "ring of healing", chance = 1190}, + {name = "warrior helmet", chance = 890}, + {name = "knight armor", chance = 1000}, + {name = "royal helmet", chance = 210}, + {name = "medusa shield", chance = 270}, + {name = "ham", chance = 60000, maxCount = 4}, + {name = "hydra egg", chance = 930}, + {name = "strong mana potion", chance = 380}, + {name = "cucumber", chance = 4780}, + {name = "hydra head", chance = 10120} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -270}, + {name ="speed", interval = 2000, chance = 25, speedChange = -700, range = 7, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_GREEN_RINGS, target = true, duration = 15000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -100, maxDamage = -250, length = 8, spread = 3, effect = CONST_ME_LOSEENERGY, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -80, maxDamage = -155, shootEffect = CONST_ANI_SMALLICE, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -66, maxDamage = -320, length = 8, spread = 3, effect = CONST_ME_CARNIPHILA, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 260, maxDamage = 407, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dragons/ice_dragon.lua b/data/monster/dragons/ice_dragon.lua new file mode 100644 index 00000000000..cc79b0de8f7 --- /dev/null +++ b/data/monster/dragons/ice_dragon.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Ice Dragon") +local monster = {} + +monster.description = "an ice dragon" +monster.experience = 2300 +monster.outfit = { + lookType = 947, + lookHead = 9, + lookBody = 9, + lookLegs = 9, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1380 +monster.Bestiary = { + class = "Dragon", + race = BESTY_RACE_DRAGON, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "The First Dragon's Lair." + } + +monster.health = 2500 +monster.maxHealth = 2500 +monster.race = "undead" +monster.corpse = 27853 +monster.speed = 212 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 350, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 26449, chance = 3000}, + {id = 2148, chance = 95070, maxCount = 200}, + {id = 7902, chance = 2000}, + {id = 2492, chance = 280} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 78, attack = 50}, + {name ="speed", interval = 2000, chance = 18, minDamage = 0, maxDamage = -400, range = 7, radius = 4, effect = CONST_ME_ICETORNADO, target = true, duration = 20000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -50, maxDamage = -120, range = 7, radius = 3, effect = CONST_ME_ICETORNADO, target = false}, + {name ="speed", interval = 2000, chance = 12, minDamage = 0, maxDamage = -400, length = 7, spread = 3, effect = CONST_ME_ICEATTACK, target = false, duration = 20000}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_LIFEDRAIN, minDamage = -150, maxDamage = -380, length = 8, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 35, + armor = 22, + {name ="combat", interval = 2000, chance = 16, type = COMBAT_HEALING, minDamage = 150, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/dragons/wyrm.lua b/data/monster/dragons/wyrm.lua new file mode 100644 index 00000000000..0178057ea63 --- /dev/null +++ b/data/monster/dragons/wyrm.lua @@ -0,0 +1,139 @@ +local mType = Game.createMonsterType("Wyrm") +local monster = {} + +monster.description = "a wyrm" +monster.experience = 1550 +monster.outfit = { + lookType = 291, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 461 +monster.Bestiary = { + class = "Dragon", + race = BESTY_RACE_DRAGON, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Drefia Wyrm Lair (after the Medusa Shield Quest room), Darashia Wyrm Hills, Arena and Zoo Quarter, \z + beneath Fenrock, Deeper Razachai, Lower Spike, Vandura Wyrm Cave and Vandura Mountain in Liberty Bay." + } + +monster.health = 1825 +monster.maxHealth = 1825 +monster.race = "blood" +monster.corpse = 8941 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "GRROARR", yell = false}, + {text = "GRRR", yell = false} +} + +monster.loot = { + {name = "small diamond", chance = 750, maxCount = 3}, + {name = "gold coin", chance = 30000, maxCount = 100}, + {name = "gold coin", chance = 30000, maxCount = 100}, + {name = "gold coin", chance = 30000, maxCount = 30}, + {name = "crossbow", chance = 5920}, + {name = "burst arrow", chance = 7650, maxCount = 10}, + {name = "dragon ham", chance = 34800, maxCount = 3}, + {name = "dragonbone staff", chance = 110}, + {name = "strong health potion", chance = 19970}, + {name = "strong mana potion", chance = 15310}, + {name = "lightning pendant", chance = 720}, + {name = "composite hornbow", chance = 90}, + {name = "focus cape", chance = 1250}, + {name = "hibiscus dress", chance = 250}, + {name = "wand of starstorm", chance = 420}, + {name = "wand of draconia", chance = 990}, + {name = "shockwave amulet", chance = 110}, + {name = "wyrm scale", chance = 15360} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -235}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -100, maxDamage = -220, radius = 3, effect = CONST_ME_YELLOWENERGY, target = false}, + {name ="wyrm wave", interval = 2000, chance = 40, minDamage = -130, maxDamage = -200, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -100, maxDamage = -125, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -98, maxDamage = -145, length = 4, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 100, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="effect", interval = 2000, chance = 10, radius = 1, effect = CONST_ME_SOUND_YELLOW, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 75}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/elementals/cliff_strider.lua b/data/monster/elementals/cliff_strider.lua new file mode 100644 index 00000000000..cf0bd6f1267 --- /dev/null +++ b/data/monster/elementals/cliff_strider.lua @@ -0,0 +1,152 @@ +local mType = Game.createMonsterType("Cliff Strider") +local monster = {} + +monster.description = "a cliff strider" +monster.experience = 5700 +monster.outfit = { + lookType = 497, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 889 +monster.Bestiary = { + class = "Elemental", + race = BESTY_RACE_ELEMENTAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 1, + Locations = "Warzone 3." + } + +monster.health = 9400 +monster.maxHealth = 9400 +monster.race = "undead" +monster.corpse = 17420 +monster.speed = 246 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Knorrrr", yell = false} +} + +monster.loot = { + {name = "white pearl", chance = 9630, maxCount = 3}, + {name = "black pearl", chance = 9090}, + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "gold coin", chance = 100000, maxCount = 95}, + {name = "platinum coin", chance = 100000, maxCount = 10}, + {name = "red gem", chance = 6110}, + {name = "blue gem", chance = 830}, + {name = "giant sword", chance = 620}, + {name = "hammer of wrath", chance = 70}, + {name = "knight legs", chance = 830}, + {name = "crown armor", chance = 310}, + {name = "crusader helmet", chance = 410}, + {name = "steel boots", chance = 100}, + {name = "iron ore", chance = 14490}, + {name = "magic sulphur", chance = 1450}, + {name = "soul orb", chance = 17080}, + {name = "sapphire hammer", chance = 1350}, + {name = "spiked squelcher", chance = 1040}, + {name = "great mana potion", chance = 30950, maxCount = 4}, + {name = "ultimate health potion", chance = 25260, maxCount = 2}, + {name = "crystal of balance", chance = 2690}, + {name = "crystal of power", chance = 720}, + {name = "shiny stone", chance = 11280}, + {name = "wand of defiance", chance = 2000}, + {name = "glacial rod", chance = 1240}, + {name = "blue crystal shard", chance = 6520}, + {name = "blue crystal splinter", chance = 7970, maxCount = 2}, + {name = "cyan crystal fragment", chance = 8070}, + {name = "pulverized ore", chance = 15110}, + {name = "cliff strider claw", chance = 15630}, + {name = "vein of ore", chance = 18000, maxCount = 2}, + {name = "prismatic bolt", chance = 9090, maxCount = 8}, + {name = "crystalline sword", chance = 620}, + {name = "crystal crossbow", chance = 830} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -499}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -800, radius = 4, shootEffect = CONST_ANI_LARGEROCK, effect = CONST_ME_STONES, target = true}, + {name ="cliff strider skill reducer", interval = 2000, chance = 10, target = false}, + {name ="cliff strider electrify", interval = 2000, chance = 15, range = 1, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -1000, length = 6, spread = 3, effect = CONST_ME_GROUNDSHAKER, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_MANADRAIN, minDamage = -100, maxDamage = -300, radius = 4, effect = CONST_ME_YELLOWENERGY, target = false} +} + +monster.defenses = { + defense = 55, + armor = 55 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 1}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 1}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 40} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/elementals/earth_elemental.lua b/data/monster/elementals/earth_elemental.lua new file mode 100644 index 00000000000..ed6209dcc13 --- /dev/null +++ b/data/monster/elementals/earth_elemental.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Earth Elemental") +local monster = {} + +monster.description = "an earth elemental" +monster.experience = 450 +monster.outfit = { + lookType = 301, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 458 +monster.Bestiary = { + class = "Elemental", + race = BESTY_RACE_ELEMENTAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Edron Earth Elemental Cave (17 of them on the first floor), Vandura Mountain, \z + Deeper Banuta, Vengoth Castle, Robson Isle, Drillworm Caves, Crystal Grounds, Middle Spike." + } + +monster.health = 650 +monster.maxHealth = 650 +monster.race = "undead" +monster.corpse = 8933 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 80, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Stomp.", yell = false} +} + +monster.loot = { + {name = "small stone", chance = 10000, maxCount = 10}, + {name = "gold coin", chance = 43000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 30}, + {name = "blank rune", chance = 10000}, + {name = "strong mana potion", chance = 1910}, + {name = "earth arrow", chance = 20160, maxCount = 30}, + {id = 9808, chance = 350}, + {name = "small topaz", chance = 620}, + {name = "lump of earth", chance = 20460}, + {name = "clay lump", chance = 570}, + {id = 13757, chance = 470} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -110}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -72, maxDamage = -105, range = 7, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_GREEN_RINGS, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -100, range = 7, radius = 2, shootEffect = CONST_ANI_LARGEROCK, effect = CONST_ME_POFF, target = true}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 20, minDamage = -200, maxDamage = -260, length = 6, spread = 3, effect = CONST_ME_BIGPLANTS, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -100, maxDamage = -140, radius = 5, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = -330, range = 5, effect = CONST_ME_SMALLPLANTS, target = true, duration = 5000} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 60, maxDamage = 80, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -25}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 85}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/elementals/energy_elemental.lua b/data/monster/elementals/energy_elemental.lua new file mode 100644 index 00000000000..fd71a6ebeb2 --- /dev/null +++ b/data/monster/elementals/energy_elemental.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Energy Elemental") +local monster = {} + +monster.description = "an energy elemental" +monster.experience = 550 +monster.outfit = { + lookType = 293, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 457 +monster.Bestiary = { + class = "Elemental", + race = BESTY_RACE_ELEMENTAL, + toKill = 10000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Kha'zeel, Energy Elemental Lair, Vandura Mountain, Vengoth's mountain." + } + +monster.health = 500 +monster.maxHealth = 500 +monster.race = "venom" +monster.corpse = 8966 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2124, chance = 2000}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 70}, + {name = "small amethyst", chance = 5000, maxCount = 2}, + {name = "energy ring", chance = 892}, + {name = "silver amulet", chance = 1020}, + {name = "wand of cosmic energy", chance = 636}, + {name = "throwing star", chance = 9900, maxCount = 5}, + {name = "obsidian lance", chance = 3571}, + {name = "guardian shield", chance = 243}, + {name = "crystal sword", chance = 5882}, + {name = "strong mana potion", chance = 7692}, + {name = "mana potion", chance = 11711}, + {id = 7838, chance = 10000, maxCount = 10} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -175}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -125, maxDamage = -252, range = 7, radius = 2, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -100, maxDamage = -130, range = 7, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="energy elemental electrify", interval = 2000, chance = 20, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 90, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = -15}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/elementals/fire_elemental.lua b/data/monster/elementals/fire_elemental.lua new file mode 100644 index 00000000000..80ee98e4094 --- /dev/null +++ b/data/monster/elementals/fire_elemental.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Fire Elemental") +local monster = {} + +monster.description = "a fire elemental" +monster.experience = 220 +monster.outfit = { + lookType = 49, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 49 +monster.Bestiary = { + class = "Elemental", + race = BESTY_RACE_ELEMENTAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Cyclopolis, Hero Cave in Edron, Ankrahmun tombs, Serpentine Tower, Factory Quarter in Yalahar, \z + Deeper Banuta, Goroma inside the volcano and beneath Fenrock." + } + +monster.health = 280 +monster.maxHealth = 280 +monster.race = "fire" +monster.corpse = 8964 +monster.speed = 190 +monster.manaCost = 690 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 80, + random = 20, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -45, maxDamage = -160, range = 7, radius = 2, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="firefield", interval = 2000, chance = 25, range = 7, radius = 1, shootEffect = CONST_ANI_FIRE, target = true} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -25}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/elementals/high_voltage_elemental.lua b/data/monster/elementals/high_voltage_elemental.lua new file mode 100644 index 00000000000..d2a44f42d6f --- /dev/null +++ b/data/monster/elementals/high_voltage_elemental.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("High Voltage Elemental") +local monster = {} + +monster.description = "a high voltage elemental" +monster.experience = 1500 +monster.outfit = { + lookType = 293, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1116 +monster.Bestiary = { + class = "Elemental", + race = BESTY_RACE_ELEMENTAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "South side of the second floor of Underground Glooth Factory, Warzone 5" + } + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "blood" +monster.corpse = 8966 +monster.speed = 278 +monster.manaCost = 330 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 185}, + {id = 7838, chance = 100000, maxCount = 20}, + {id = 7589, chance = 7142}, + {id = 2150, chance = 7142, maxCount = 2}, + {id = 2124, chance = 7142}, + {id = 2425, chance = 4761}, + {id = 7620, chance = 4761}, + {id = 7449, chance = 4761} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 66, attack = 70}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -205, maxDamage = -497, range = 7, radius = 2, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -201, maxDamage = -277, range = 7, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_ENERGYHIT, target = true} +} + +monster.defenses = { + defense = 11, + armor = 11 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = -1}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 5}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/elementals/ironblight.lua b/data/monster/elementals/ironblight.lua new file mode 100644 index 00000000000..99f88fd7804 --- /dev/null +++ b/data/monster/elementals/ironblight.lua @@ -0,0 +1,144 @@ +local mType = Game.createMonsterType("Ironblight") +local monster = {} + +monster.description = "an ironblight" +monster.experience = 4400 +monster.outfit = { + lookType = 498, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 890 +monster.Bestiary = { + class = "Elemental", + race = BESTY_RACE_ELEMENTAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 1, + Locations = "Warzone 3." + } + +monster.health = 6600 +monster.maxHealth = 6600 +monster.race = "undead" +monster.corpse = 17424 +monster.speed = 286 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 260, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Clonk!", yell = false}, + {text = "Yowl!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 199}, + {name = "small emerald", chance = 10890, maxCount = 3}, + {name = "small amethyst", chance = 15020, maxCount = 3}, + {name = "platinum coin", chance = 100000, maxCount = 8}, + {name = "red gem", chance = 3510}, + {name = "blue gem", chance = 480}, + {name = "epee", chance = 480}, + {name = "magic sulphur", chance = 830}, + {name = "sapphire hammer", chance = 480}, + {name = "great mana potion", chance = 17640}, + {name = "terra legs", chance = 1110}, + {name = "ultimate health potion", chance = 18330}, + {name = "composite hornbow", chance = 210}, + {name = "springsprout rod", chance = 1720}, + {name = "crystal of balance", chance = 4480}, + {name = "crystal of power", chance = 2480}, + {name = "war crystal", chance = 21230}, + {name = "shiny stone", chance = 15230}, + {name = "jade hat", chance = 210}, + {name = "glacial rod", chance = 960}, + {name = "green crystal shard", chance = 5720}, + {name = "brown crystal splinter", chance = 12610, maxCount = 2}, + {name = "red crystal fragment", chance = 10540}, + {name = "crystalline spikes", chance = 18400} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -460, maxDamage = -480, radius = 6, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -260, maxDamage = -350, length = 7, spread = 3, shootEffect = CONST_ANI_ICE, effect = CONST_ME_ICEATTACK, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -180, maxDamage = -250, radius = 2, shootEffect = CONST_ANI_GREENSTAR, effect = CONST_ME_BIGPLANTS, target = true}, + {name ="speed", interval = 2000, chance = 10, speedChange = -800, length = 5, spread = 3, effect = CONST_ME_BLOCKHIT, target = false, duration = 30000} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="invisible", interval = 2000, chance = 20, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 25}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 60}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/elementals/knowledge_elemental.lua b/data/monster/elementals/knowledge_elemental.lua new file mode 100644 index 00000000000..733323666cc --- /dev/null +++ b/data/monster/elementals/knowledge_elemental.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Knowledge Elemental") +local monster = {} + +monster.description = "a knowledge elemental" +monster.experience = 10603 +monster.outfit = { + lookType = 1065, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1670 +monster.Bestiary = { + class = "Elemental", + race = BESTY_RACE_ELEMENTAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 1, + Locations = "Secret Library." + } + +monster.health = 10500 +monster.maxHealth = 10500 +monster.race = "undead" +monster.corpse = 33349 +monster.speed = 460 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 100000, maxCount = 9}, + {name = "Book Page", chance = 10000, maxCount = 6}, + {name = "Small Amethyst", chance = 10000, maxCount = 8}, + {name = "Glowing Rune", chance = 10000, maxCount = 3}, + {name = "Quill", chance = 10000, maxCount = 3}, + {name = "Silken Bookmark", chance = 10000, maxCount = 3}, + {name = "Flash Arrow", chance = 10000, maxCount = 6}, + {name = "Throwing Star", chance = 10000, maxCount = 10}, + {name = "Crystal Sword", chance = 10000}, + {name = "Energy Ring", chance = 10000}, + {name = "Guardian Shield", chance = 10000}, + {name = "Mana Potion", chance = 10000, maxCount = 10}, + {name = "Ultimate Mana Potion", chance = 10000, maxCount = 8}, + {name = "Ultimate Health Potion", chance = 10000, maxCount = 8}, + {name = "Wand of Cosmic Energy", chance = 300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HOLYDAMAGE, minDamage = -200, maxDamage = -680, radius = 3, effect = CONST_ME_HOLYDAMAGE, target = true}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -680, range = 7, shootEffect = CONST_ANI_ENERGY, target = false} +} + +monster.defenses = { + defense = 33, + armor = 76, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_PHYSICALDAMAGE, minDamage = 100, maxDamage = 300, radius = 3, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="combat", interval = 200, chance = 55, type = COMBAT_PHYSICALDAMAGE, minDamage = 100, maxDamage = 300, radius = 3, effect = CONST_ME_ENERGYHIT, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/elementals/lava_lurker.lua b/data/monster/elementals/lava_lurker.lua new file mode 100644 index 00000000000..efebb24d0b1 --- /dev/null +++ b/data/monster/elementals/lava_lurker.lua @@ -0,0 +1,117 @@ +local mType = Game.createMonsterType("Lava Lurker") +local monster = {} + +monster.description = "a lava lurker" +monster.experience = 4000 +monster.outfit = { + lookType = 1041, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1563 +monster.Bestiary = { + class = "Elemental", + race = BESTY_RACE_ELEMENTAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Gnome Deep Hub" + } + +monster.health = 5900 +monster.maxHealth = 5900 +monster.race = "fire" +monster.corpse = 0 +monster.speed = 58 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "hot hot hot!", yell = false}, + {text = "wobble wobble!", yell = false} +} + +monster.loot = { + {id = 7760, chance = 14620, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -70, maxDamage = -300, range = 7, length = 3, spread = 3, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_FIREDAMAGE, minDamage = 0, maxDamage = -100, range = 7, length = 6, spread = 3, effect = CONST_ME_HITBYFIRE, target = false} +} + +monster.defenses = { + defense = 33, + armor = 45 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/elementals/massive_earth_elemental.lua b/data/monster/elementals/massive_earth_elemental.lua new file mode 100644 index 00000000000..98049b863b7 --- /dev/null +++ b/data/monster/elementals/massive_earth_elemental.lua @@ -0,0 +1,135 @@ +local mType = Game.createMonsterType("Massive Earth Elemental") +local monster = {} + +monster.description = "a massive earth elemental" +monster.experience = 950 +monster.outfit = { + lookType = 285, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 455 +monster.Bestiary = { + class = "Elemental", + race = BESTY_RACE_ELEMENTAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Forbidden Lands, on top of a hill in the northern part of the Arena and Zoo Quarter, \z + Lower Spike, Truffels Garden and Mushroom Gardens." + } + +monster.health = 1330 +monster.maxHealth = 1330 +monster.race = "undead" +monster.corpse = 8933 +monster.speed = 370 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "small stone", chance = 25280, maxCount = 10}, + {name = "gold coin", chance = 32000, maxCount = 100}, + {name = "gold coin", chance = 32000, maxCount = 100}, + {name = "gold coin", chance = 32000, maxCount = 41}, + {name = "stone skin amulet", chance = 980}, + {name = "protection amulet", chance = 1580}, + {name = "dwarven ring", chance = 2790}, + {name = "diamond sceptre", chance = 150}, + {name = "terra amulet", chance = 500}, + {id = 9809, chance = 3300}, + {name = "small topaz", chance = 5280, maxCount = 2}, + {name = "lump of earth", chance = 40680}, + {name = "clay lump", chance = 480}, + {id = 13757, chance = 430} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -110}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -99, maxDamage = -145, range = 7, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_GREEN_RINGS, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = -95, maxDamage = -169, range = 7, radius = 2, shootEffect = CONST_ANI_LARGEROCK, effect = CONST_ME_POFF, target = true}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -300, maxDamage = -320, length = 6, spread = 3, effect = CONST_ME_BIGPLANTS, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -200, maxDamage = -220, radius = 5, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false}, + {name ="speed", interval = 2000, chance = 20, speedChange = -330, range = 5, effect = CONST_ME_SMALLPLANTS, target = true, duration = 5000} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 150, maxDamage = 180, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 45} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/elementals/massive_energy_elemental.lua b/data/monster/elementals/massive_energy_elemental.lua new file mode 100644 index 00000000000..a9306c5221f --- /dev/null +++ b/data/monster/elementals/massive_energy_elemental.lua @@ -0,0 +1,127 @@ +local mType = Game.createMonsterType("Massive Energy Elemental") +local monster = {} + +monster.description = "a massive energy elemental" +monster.experience = 950 +monster.outfit = { + lookType = 290, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 456 +monster.Bestiary = { + class = "Elemental", + race = BESTY_RACE_ELEMENTAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "North west of Ankrahmun, you must Levitate to hunt. Two can also be found in the Asura Palace." + } + +monster.health = 1100 +monster.maxHealth = 1100 +monster.race = "venom" +monster.corpse = 8966 +monster.speed = 430 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 91}, + {name = "small amethyst", chance = 3270, maxCount = 3}, + {name = "strong mana potion", chance = 17450}, + {name = "great mana potion", chance = 5450}, + {name = "lightning pendant", chance = 730}, + {name = "lightning legs", chance = 150}, + {name = "spellbook of warding", chance = 360}, + {name = "wand of starstorm", chance = 730}, + {id = 9809, chance = 730}, + {name = "shockwave amulet", chance = 500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -175}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -270, maxDamage = -615, range = 7, radius = 2, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -175, maxDamage = -205, range = 7, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="massive energy elemental electrify", interval = 2000, chance = 20, effect = CONST_ME_BLOCKHIT, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 190, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 70}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = -5}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 25}, + {type = COMBAT_DEATHDAMAGE , percent = 1} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/elementals/massive_fire_elemental.lua b/data/monster/elementals/massive_fire_elemental.lua new file mode 100644 index 00000000000..22689958e93 --- /dev/null +++ b/data/monster/elementals/massive_fire_elemental.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Massive Fire Elemental") +local monster = {} + +monster.description = "a massive fire elemental" +monster.experience = 1400 +monster.outfit = { + lookType = 242, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 313 +monster.Bestiary = { + class = "Elemental", + race = BESTY_RACE_ELEMENTAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Demon Forge, Deeper Banuta, Hero Cave, Hot Spot, Fury Dungeon." + } + +monster.health = 1200 +monster.maxHealth = 1200 +monster.race = "fire" +monster.corpse = 6324 +monster.speed = 238 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 80, + random = 20, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "small ruby", chance = 6100, maxCount = 2}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 25000, maxCount = 100}, + {name = "gold coin", chance = 25000, maxCount = 12}, + {name = "wand of inferno", chance = 2240}, + {name = "fire sword", chance = 530}, + {name = "magma amulet", chance = 1300}, + {name = "magma boots", chance = 560}, + {name = "magma legs", chance = 210}, + {id = 9809, chance = 1330} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + {name ="firefield", interval = 2000, chance = 10, range = 7, radius = 3, shootEffect = CONST_ANI_FIRE, target = false}, + {name ="firefield", interval = 2000, chance = 10, range = 7, radius = 3, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -700, length = 7, spread = 3, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -60, maxDamage = -250, radius = 3, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="massive fire elemental soulfire", interval = 2000, chance = 15, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 40}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/elementals/massive_water_elemental.lua b/data/monster/elementals/massive_water_elemental.lua new file mode 100644 index 00000000000..19b4e5a79d1 --- /dev/null +++ b/data/monster/elementals/massive_water_elemental.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Massive Water Elemental") +local monster = {} + +monster.description = "a massive water elemental" +monster.experience = 1100 +monster.outfit = { + lookType = 11, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 279 +monster.Bestiary = { + class = "Elemental", + race = BESTY_RACE_ELEMENTAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Calassa, Frozen Trench, Water Elemental Dungeon through the water channels, \z + before Zugurosh in The Inquisition Quest." + } + +monster.health = 1250 +monster.maxHealth = 1250 +monster.race = "undead" +monster.corpse = 10499 +monster.speed = 430 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "small diamond", chance = 1900, maxCount = 2}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "small emerald", chance = 1000, maxCount = 2}, + {name = "platinum coin", chance = 20000, maxCount = 2}, + {name = "energy ring", chance = 910}, + {name = "life ring", chance = 1000}, + {id = 2667, chance = 40000, maxCount = 2}, + {name = "rainbow trout", chance = 1340}, + {name = "green perch", chance = 1590}, + {name = "great mana potion", chance = 10400}, + {name = "great health potion", chance = 10000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -220, condition = {type = CONDITION_POISON, totalDamage = 300, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DROWNDAMAGE, minDamage = -330, maxDamage = -450, range = 7, radius = 2, effect = CONST_ME_LOSEENERGY, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ICEDAMAGE, minDamage = -170, maxDamage = -210, range = 7, shootEffect = CONST_ANI_SMALLICE, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 20, minDamage = -355, maxDamage = -420, radius = 5, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 120, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = -25}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/elementals/raging_fire.lua b/data/monster/elementals/raging_fire.lua new file mode 100644 index 00000000000..582ae30a57e --- /dev/null +++ b/data/monster/elementals/raging_fire.lua @@ -0,0 +1,114 @@ +local mType = Game.createMonsterType("Raging Fire") +local monster = {} + +monster.description = "a raging fire" +monster.experience = 1500 +monster.outfit = { + lookType = 242, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1121 +monster.Bestiary = { + class = "Elemental", + race = BESTY_RACE_ELEMENTAL, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 50, + Stars = 3, + Occurrence = 3, + Locations = "Jaccus Maxxen's Dungeon." + } + +monster.health = 1800 +monster.maxHealth = 1800 +monster.race = "fire" +monster.corpse = 24184 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 80, + random = 20, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 60, attack = 100}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_FIREDAMAGE, minDamage = -65, maxDamage = -605, length = 7, spread = 3, target = false}, + {name ="massive fire elemental soulfire", interval = 2000, chance = 12, target = false}, + {name ="firefield", interval = 2000, chance = 11, range = 7, radius = 3, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_EXPLOSIONHIT, target = true}, + {name ="firefield", interval = 2000, chance = 11, radius = 3, effect = CONST_ME_HITBYFIRE, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 25}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -15}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 40} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/elementals/ravenous_lava_lurker.lua b/data/monster/elementals/ravenous_lava_lurker.lua new file mode 100644 index 00000000000..2c02bfc3468 --- /dev/null +++ b/data/monster/elementals/ravenous_lava_lurker.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("Ravenous Lava Lurker") +local monster = {} + +monster.description = "a ravenous lava lurker" +monster.experience = 4000 +monster.outfit = { + lookType = 1041, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1569 +monster.Bestiary = { + class = "Elemental", + race = BESTY_RACE_ELEMENTAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Gnome Deep Hub in the Gnomish area." + } + +monster.health = 5000 +monster.maxHealth = 5000 +monster.race = "fire" +monster.corpse = 0 +monster.speed = 58 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "small enchanted ruby", chance = 14620} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150}, + {name ="ravennouslavalurkerwave", interval = 2000, chance = 15, minDamage = 0, maxDamage = -400, target = false}, + {name ="ravennouslavalurkertarget", interval = 2000, chance = 40, minDamage = 0, maxDamage = -400, target = true} +} + +monster.defenses = { + defense = 33, + armor = 45 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +monster.heals = { + {type = COMBAT_FIREDAMAGE, percent = 100}, +} + +mType:register(monster) diff --git a/data/monster/elementals/turbulent_elemental.lua b/data/monster/elementals/turbulent_elemental.lua new file mode 100644 index 00000000000..a15b55993ba --- /dev/null +++ b/data/monster/elementals/turbulent_elemental.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Turbulent Elemental") +local monster = {} + +monster.description = "a turbulent elemental" +monster.experience = 29900 +monster.outfit = { + lookType = 1314, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1940 +monster.Bestiary = { + class = "Elemental", + race = BESTY_RACE_ELEMENTAL, + toKill = 5000, + FirstUnlock = 25, + SecondUnlock = 2500, + CharmsPoints = 100, + Stars = 5, + Occurrence = 0, + Locations = "Ebb and Flow." + } + +monster.health = 28000 +monster.maxHealth = 28000 +monster.race = "blood" +monster.corpse = 38740 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10 +} + +monster.loot = { + {name = "crystal coin", chance = 70540}, + {name = "platinum coin", chance = 90540, maxCount = 50}, + {name = "ultimate health potion", chance = 32220, maxCount = 7}, + {name = "gold ingot", chance = 65560}, + {name = "glacier robe", chance = 25560}, + {name = "violet gem", chance = 25560}, + {name = "blue gem", chance = 45560}, + {name = "wood cape", chance = 16500}, + {name = "northwind rod", chance = 13500}, + {name = "springsprout rod", chance = 11500}, + {name = "sacred tree amulet", chance = 8500}, + {name = "crystalline armor", chance = 4500}, + {name = "rubber cap", chance = 3500}, + {name = "fur armor", chance = 2500}, + {id = 38944, chance = 50} -- Bag you desire +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -900}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -750, maxDamage = -900, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_ICEATTACK, target = true}, + {name ="combat", interval = 3000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -550, maxDamage = -900, range = 7, shootEffect = CONST_ANI_HUNTINGSPEAR, effect = CONST_ME_DRAWBLOOD, target = true}, + {name ="combat", interval = 4000, chance = 24, type = COMBAT_ICEDAMAGE, minDamage = -750, maxDamage = -1100, radius = 4, effect = CONST_ME_ICETORNADO, target = false}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_ICEDAMAGE, minDamage = -750, maxDamage = -950, radius = 4, effect = CONST_ME_ICEATTACK, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -800, maxDamage = -1050, length = 5, radius = 2, effect = CONST_ME_GREEN_RINGS, target = false} + -- Fear +} + +monster.defenses = { + defense = 90, + armor = 105 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 25}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) \ No newline at end of file diff --git a/data/monster/elementals/water_elemental.lua b/data/monster/elementals/water_elemental.lua new file mode 100644 index 00000000000..6cadb360a55 --- /dev/null +++ b/data/monster/elementals/water_elemental.lua @@ -0,0 +1,135 @@ +local mType = Game.createMonsterType("Water Elemental") +local monster = {} + +monster.description = "a water elemental" +monster.experience = 650 +monster.outfit = { + lookType = 286, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 236 +monster.Bestiary = { + class = "Elemental", + race = BESTY_RACE_ELEMENTAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Water Elemental Cave in Port Hope, Water Elemental Dungeon, Deeper Banuta, Malada, Ramoa, \z + Talahu, Folda (7 spawn on the 3rd floor), Water Elemental Cave in Outlaw Camp (only during the Down the \z + Drain Mini World Change), Krailos Steppe underwater cave." + } + +monster.health = 550 +monster.maxHealth = 550 +monster.race = "undead" +monster.corpse = 10499 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Splish splash", yell = false} +} + +monster.loot = { + {name = "small diamond", chance = 1000}, + {name = "small sapphire", chance = 1000}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "small emerald", chance = 1000, maxCount = 2}, + {name = "platinum coin", chance = 10000}, + {name = "energy ring", chance = 950}, + {name = "life ring", chance = 930}, + {id = 2667, chance = 20000}, + {name = "rainbow trout", chance = 940}, + {name = "green perch", chance = 1050}, + {name = "strong health potion", chance = 10000}, + {name = "strong mana potion", chance = 10000}, + {id = 7632, chance = 800}, + {id = 7633, chance = 800} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -160, condition = {type = CONDITION_POISON, totalDamage = 60, interval = 4000}}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DROWNDAMAGE, minDamage = -125, maxDamage = -235, range = 7, radius = 2, effect = CONST_ME_LOSEENERGY, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ICEDAMAGE, minDamage = -88, maxDamage = -150, range = 7, shootEffect = CONST_ANI_SMALLICE, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -225, maxDamage = -260, radius = 5, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 50, maxDamage = 80, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 300, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 35}, + {type = COMBAT_ENERGYDAMAGE, percent = -25}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/event_creatures/bones.lua b/data/monster/event_creatures/bones.lua new file mode 100644 index 00000000000..309f363fa94 --- /dev/null +++ b/data/monster/event_creatures/bones.lua @@ -0,0 +1,118 @@ +local mType = Game.createMonsterType("Bones") +local monster = {} + +monster.description = "Bones" +monster.experience = 3750 +monster.outfit = { + lookType = 231, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 9500 +monster.maxHealth = 9500 +monster.race = "undead" +monster.corpse = 6306 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Your new name is breakfast.", yell = false}, + {text = "Keep that dog away!", yell = false}, + {text = "Out Fluffy! Out! Bad dog!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 90}, + {name = "sword ring", chance = 10000}, + {name = "broadsword", chance = 4000}, + {name = "magic plate armor", chance = 2000}, + {name = "spectral stone", chance = 800}, + {name = "skull helmet", chance = 50000}, + {name = "soul orb", chance = 10000}, + {id = 6300, chance = 4000}, + {name = "demonic essence", chance = 1538}, + {id = 6570, chance = 5538, maxCount = 3}, + {id = 6571, chance = 1538}, + {name = "dragonbone staff", chance = 50000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -845}, + {name ="combat", interval = 1000, chance = 13, type = COMBAT_LIFEDRAIN, minDamage = -400, maxDamage = -600, radius = 1, target = true}, + {name ="combat", interval = 3000, chance = 34, type = COMBAT_DEATHDAMAGE, minDamage = -180, maxDamage = -500, range = 1, radius = 1, shootEffect = CONST_ANI_DEATH, target = true} +} + +monster.defenses = { + defense = 55, + armor = 50, + {name ="combat", interval = 5000, chance = 25, type = COMBAT_HEALING, minDamage = 60, maxDamage = 100, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/event_creatures/eclipse_knight.lua b/data/monster/event_creatures/eclipse_knight.lua new file mode 100644 index 00000000000..a60ae068c05 --- /dev/null +++ b/data/monster/event_creatures/eclipse_knight.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Eclipse Knight") +local monster = {} + +monster.description = "an eclipse knight" +monster.experience = 4650 +monster.outfit = { + lookType = 234, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 45000 +monster.maxHealth = 45000 +monster.race = "undead" +monster.corpse = 6328 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Yes, flee from me!", yell = false} +} + +monster.loot = { + {name = "Midnight Shard", chance = 25000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -5000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -781, range = 7, shootEffect = CONST_ANI_THROWINGKNIFE, target = false}, + {name ="dark torturer skill reducer", interval = 2000, chance = 5, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/event_creatures/essence_of_darkness.lua b/data/monster/event_creatures/essence_of_darkness.lua new file mode 100644 index 00000000000..353b636e3f3 --- /dev/null +++ b/data/monster/event_creatures/essence_of_darkness.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Essence of Darkness") +local monster = {} + +monster.description = "an essence of darkness" +monster.experience = 30 +monster.outfit = { + lookType = 315, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "undead" +monster.corpse = 9960 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 98}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 80}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/event_creatures/fluffy.lua b/data/monster/event_creatures/fluffy.lua new file mode 100644 index 00000000000..ab44975aab0 --- /dev/null +++ b/data/monster/event_creatures/fluffy.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("Fluffy") +local monster = {} + +monster.description = "Fluffy" +monster.experience = 3550 +monster.outfit = { + lookType = 240, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 4500 +monster.maxHealth = 4500 +monster.race = "blood" +monster.corpse = 6332 +monster.speed = 310 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Wooof!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2148, chance = 100000, maxCount = 20}, + {id = 5944, chance = 5555}, + {id = 6570, chance = 5538, maxCount = 4}, + {id = 6571, chance = 1538}, + {id = 2671, chance = 50000, maxCount = 8}, + {id = 2230, chance = 25000}, + {id = 6500, chance = 7200}, + {id = 2430, chance = 2857}, + {id = 2383, chance = 2500}, + {id = 6558, chance = 8888} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 98, attack = 120}, + {name ="combat", interval = 1500, chance = 300, type = COMBAT_ENERGYDAMAGE, minDamage = -100, maxDamage = -200, length = 8, spread = 3, effect = CONST_ME_LOSEENERGY, target = false}, + {name ="combat", interval = 1000, chance = 150, type = COMBAT_EARTHDAMAGE, minDamage = -120, maxDamage = -300, length = 8, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = -105, maxDamage = -235, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, target = false}, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -135, maxDamage = -255, range = 7, radius = 6, effect = CONST_ME_LOSEENERGY, target = false} +} + +monster.defenses = { + defense = 35, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/event_creatures/grynch_clan_goblin.lua b/data/monster/event_creatures/grynch_clan_goblin.lua new file mode 100644 index 00000000000..755c826dd59 --- /dev/null +++ b/data/monster/event_creatures/grynch_clan_goblin.lua @@ -0,0 +1,169 @@ +local mType = Game.createMonsterType("Grynch Clan Goblin") +local monster = {} + +monster.description = "Grynch Clan Goblin" +monster.experience = 4 +monster.outfit = { + lookType = 61, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 393 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 10, + Stars = 1, + Occurrence = 3, + Locations = "They do not have a set respawn spot. They are announced to be stealing presents from a \z + random Tibian city and spawn in the aforetold city. \z + There are two or three messages that appear on each raid and three massive spawns of goblins." + } + +monster.health = 80 +monster.maxHealth = 80 +monster.race = "blood" +monster.corpse = 6002 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 0, + targetDistance = 11, + runHealth = 80, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "T'was not me hand in your pocket!", yell = false}, + {text = "Look! Cool stuff in house. Let's get it!", yell = false}, + {text = "Uhh! Nobody home! ", yell = false}, + {text = "Me just borrowed it!", yell = false}, + {text = "Me no steal! Me found it!", yell = false}, + {text = "Me had it for five minutes. It's family heirloom now!", yell = false}, + {text = "Nice human won't hurt little, good goblin?", yell = false}, + {text = "Gimmegimme!", yell = false}, + {text = "Invite me in you lovely house plx!", yell = false}, + {text = "Other Goblin stole it!", yell = false}, + {text = "All presents mine!", yell = false}, + {text = "Me got ugly ones purse", yell = false}, + {text = "Free itans plz!", yell = false}, + {text = "Not me! Not me!", yell = false}, + {text = "Guys, help me here! Guys? Guys???", yell = false}, + {text = "That only much dust in me pocket! Honest!", yell = false}, + {text = "Can me have your stuff?", yell = false}, + {text = "Halp, Big dumb one is after me!", yell = false}, + {text = "Uh, So many shiny things!", yell = false}, + {text = "Utani hur hur hur!", yell = false}, + {text = "Mee? Stealing? Never!!!", yell = false}, + {text = "Oh what fun it is to steal a one-horse open sleigh!", yell = false}, + {text = "Must have it! Must have it!", yell = false}, + {text = "Where me put me lockpick?", yell = false}, + {text = "Catch me if you can!", yell = false} +} + +monster.loot = { + {id = 1852, chance = 4000}, + {id = 2072, chance = 5000}, + {id = 2102, chance = 500}, + {name = "snowball", chance = 7000, maxCount = 5}, + {name = "piggy bank", chance = 1000}, + {name = "gold coin", chance = 22500, maxCount = 22}, + {name = "scarab coin", chance = 500, maxCount = 2}, + {id = 2163, chance = 4000}, + {name = "blank rune", chance = 5000}, + {id = 2551, chance = 1500}, + {id = 2560, chance = 1000}, + {name = "scarf", chance = 4000}, + {name = "red apple", chance = 700, maxCount = 3}, + {name = "orange", chance = 7000, maxCount = 3}, + {name = "cherry", chance = 7000, maxCount = 4}, + {name = "cookie", chance = 7000, maxCount = 5}, + {name = "candy cane", chance = 5000, maxCount = 3}, + {id = 2695, chance = 5000, maxCount = 2}, + {name = "explorer brooch", chance = 4000}, + {name = "orichalcum pearl", chance = 500, maxCount = 2}, + {id = 5792, chance = 1000}, + {name = "chicken feather", chance = 4000, maxCount = 5}, + {name = "bat wing", chance = 4000, maxCount = 3}, + {name = "honeycomb", chance = 4000}, + {name = "lump of cake dough", chance = 7000, maxCount = 3}, + {name = "valentine's cake", chance = 1500}, + {name = "christmas present bag", chance = 7000}, + {name = "gingerbreadman", chance = 4000, maxCount = 2}, + {name = "walnut", chance = 3500, maxCount = 5}, + {name = "peanut", chance = 3500, maxCount = 100} +} + +monster.attacks = { +} + +monster.defenses = { + defense = 12, + armor = 10, + {name ="speed", interval = 1000, chance = 15, speedChange = 500, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/event_creatures/hacker.lua b/data/monster/event_creatures/hacker.lua new file mode 100644 index 00000000000..a1fa3df758a --- /dev/null +++ b/data/monster/event_creatures/hacker.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Hacker") +local monster = {} + +monster.description = "a hacker" +monster.experience = 45 +monster.outfit = { + lookType = 8, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 430 +monster.maxHealth = 430 +monster.race = "blood" +monster.corpse = 5980 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 429, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Feel the wrath of me dos attack!", yell = false}, + {text = "You're next!", yell = false}, + {text = "Gimme free gold!", yell = false}, + {text = "Me sooo smart!", yell = false}, + {text = "Me have a cheating link for you!", yell = false}, + {text = "Me is GM!", yell = false}, + {text = "Gimme your password!", yell = false}, + {text = "Me just need the code!", yell = false}, + {text = "Me not stink!", yell = false}, + {text = "Me other char is highlevel!", yell = false} +} + +monster.loot = { + {id = 2044, chance = 6666}, + {name = "gold coin", chance = 100000, maxCount = 12}, + {name = "battle axe", chance = 5000}, + {name = "halberd", chance = 10000}, + {name = "axe", chance = 10000}, + {name = "war hammer", chance = 5000}, + {name = "ham", chance = 50000}, + {id = 6570, chance = 5538}, + {id = 6571, chance = 1538} +} + +monster.attacks = { + {name ="melee", interval = 1000, chance = 100, minDamage = 0, maxDamage = -83} +} + +monster.defenses = { + defense = 12, + armor = 15, + {name ="speed", interval = 1000, chance = 15, speedChange = 290, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000}, + {name ="outfit", interval = 10000, chance = 15, effect = CONST_ME_MAGIC_RED, target = false, duration = 500, outfitMonster = "pig"} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/event_creatures/minishabaal.lua b/data/monster/event_creatures/minishabaal.lua new file mode 100644 index 00000000000..d88ea323a9e --- /dev/null +++ b/data/monster/event_creatures/minishabaal.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Minishabaal") +local monster = {} + +monster.description = "Minishabaal" +monster.experience = 4000 +monster.outfit = { + lookType = 237, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3500 +monster.maxHealth = 3500 +monster.race = "blood" +monster.corpse = 6364 +monster.speed = 700 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 350, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Diabolic Imp", chance = 40, interval = 2000, max = 3} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I had Princess Lumelia as breakfast!", yell = false}, + {text = "Naaa-Nana-Naaa-Naaa!", yell = false}, + {text = "My brother will come and get you for this!", yell = false}, + {text = "Get them Fluffy!", yell = false}, + {text = "He He He!", yell = false}, + {text = "Pftt, Ferumbras such an upstart!", yell = false}, + {text = "My dragon is not that old, it's just second hand!", yell = false}, + {text = "My other dragon is a red one!", yell = false}, + {text = "When I am big I want to become the ruthless eighth!", yell = false}, + {text = "WHERE'S FLUFFY?", yell = false}, + {text = "Muahaha!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 20}, + {id = 2150, chance = 1428, maxCount = 2}, + {id = 2548, chance = 2857}, + {id = 2432, chance = 666}, + {id = 5944, chance = 909}, + {id = 2520, chance = 200}, + {id = 6500, chance = 1000, maxCount = 2}, + {id = 2470, chance = 180}, + {id = 2148, chance = 100000, maxCount = 20}, + {id = 5944, chance = 909}, + {id = 2488, chance = 800}, + {id = 2515, chance = 1333}, + {id = 2136, chance = 909}, + {id = 2542, chance = 500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 70, attack = 95}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -80, maxDamage = -350, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 3000, chance = 34, type = COMBAT_FIREDAMAGE, minDamage = -120, maxDamage = -500, range = 7, radius = 2, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 1000, chance = 50, type = COMBAT_HEALING, minDamage = 155, maxDamage = 255, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 1000, chance = 12, speedChange = 320, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000}, + {name ="invisible", interval = 4000, chance = 50, effect = CONST_ME_MAGIC_RED} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/event_creatures/party_skeleton.lua b/data/monster/event_creatures/party_skeleton.lua new file mode 100644 index 00000000000..76da123214f --- /dev/null +++ b/data/monster/event_creatures/party_skeleton.lua @@ -0,0 +1,97 @@ +local mType = Game.createMonsterType("Party Skeleton") +local monster = {} + +monster.description = "a party skeleton" +monster.experience = 0 +monster.outfit = { + lookType = 33, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 40 +monster.maxHealth = 40 +monster.race = "undead" +monster.corpse = 5972 +monster.speed = 154 +monster.manaCost = 300 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = false, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -20}, + {name ="combat", interval = 1000, chance = 9, type = COMBAT_LIFEDRAIN, minDamage = -7, maxDamage = -13, range = 1, target = false} +} + +monster.defenses = { + defense = 9, + armor = 2 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/event_creatures/pinata_dragon.lua b/data/monster/event_creatures/pinata_dragon.lua new file mode 100644 index 00000000000..01ca4f4a212 --- /dev/null +++ b/data/monster/event_creatures/pinata_dragon.lua @@ -0,0 +1,103 @@ +local mType = Game.createMonsterType("Piñata Dragon") +local monster = {} + +monster.description = "a Pinata Dragon" +monster.experience = 50 +monster.outfit = { + lookTypeEx = 27730 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Demon", chance = 7, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You can't have my treasures!", yell = false}, + {text = "Hit me one more time!", yell = false}, + {text = "Na Nana Naaa Naaa!", yell = false}, + {text = "You'll never get my stuff!", yell = false}, + {text = "Do you really want to hurt me?", yell = false}, + {text = "Bring it on!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { +} + +monster.defenses = { + defense = 1, + armor = 1, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_HEALING, effect = CONST_ME_MORTAREA, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/event_creatures/primitive.lua b/data/monster/event_creatures/primitive.lua new file mode 100644 index 00000000000..2e5d6342035 --- /dev/null +++ b/data/monster/event_creatures/primitive.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Primitive") +local monster = {} + +monster.description = "Primitive" +monster.experience = 45 +monster.outfit = { + lookType = 143, + lookHead = 1, + lookBody = 1, + lookLegs = 1, + lookFeet = 1, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 200 +monster.maxHealth = 200 +monster.race = "blood" +monster.corpse = 6080 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 5, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "We don't need a future!", yell = false}, + {text = "I'll rook you all!", yell = false}, + {text = "They thought they'd beaten us!", yell = false}, + {text = "You are history!", yell = false}, + {text = "There can only be one world!", yell = false}, + {text = "Valor who?", yell = false}, + {text = "Die noob!", yell = false}, + {text = "There are no dragons!", yell = false}, + {text = "I'll quit forever! Again ...", yell = false}, + {text = "You all are noobs!", yell = false}, + {text = "Beware of the cyclops!", yell = false}, + {text = "Just had a disconnect.", yell = false}, + {text = "Magic is only good for girls!", yell = false}, + {text = "We'll be back!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 12500, maxCount = 10}, + {name = "sabre", chance = 10250}, + {name = "axe", chance = 12250}, + {name = "studded helmet", chance = 9500}, + {name = "studded armor", chance = 7000}, + {name = "studded shield", chance = 1200}, + {id = 6570, chance = 500}, + {id = 6571, chance = 500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -32}, + {name ="drunk", interval = 1000, chance = 20, range = 7, shootEffect = CONST_ANI_ENERGY, target = false}, + {name ="combat", interval = 1000, chance = 34, type = COMBAT_FIREDAMAGE, minDamage = -20, maxDamage = -20, range = 7, radius = 3, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="outfit", interval = 1000, chance = 2, radius = 4, effect = CONST_ME_LOSEENERGY, target = false, duration = 10000, outfitMonster = "primitive"} +} + +monster.defenses = { + defense = 25, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/event_creatures/spectral_scum.lua b/data/monster/event_creatures/spectral_scum.lua new file mode 100644 index 00000000000..7fe3687d6ae --- /dev/null +++ b/data/monster/event_creatures/spectral_scum.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Spectral Scum") +local monster = {} + +monster.description = "a spectral scum" +monster.experience = 0 +monster.outfit = { + lookType = 195, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1 +monster.maxHealth = 1 +monster.race = "undead" +monster.corpse = 6070 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Booze! More booze!", yell = false}, + {text = "Harrr! Harrr!", yell = false}, + {text = "", yell = false}, + {text = "", yell = false}, + {text = "Nothing better than plundering and getting plastered!", yell = false}, + {text = "Yarrr!", yell = false}, + {text = "A pirate's unlife for me!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = 0}, + {name ="drunk", interval = 5000, chance = 10, range = 2, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 19, + armor = 18 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/event_creatures/the_halloween_hare.lua b/data/monster/event_creatures/the_halloween_hare.lua new file mode 100644 index 00000000000..3159bf866f7 --- /dev/null +++ b/data/monster/event_creatures/the_halloween_hare.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("The Halloween Hare") +local monster = {} + +monster.description = "The Halloween Hare" +monster.experience = 0 +monster.outfit = { + lookType = 74, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1 +monster.maxHealth = 1 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 95 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 10, + targetDistance = 2, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = 0}, + {name ="outfit", interval = 2000, chance = 6, radius = 3, effect = CONST_ME_BLOCKHIT, target = false, duration = 6000, outfitMonster = "bat"}, + {name ="outfit", interval = 2000, chance = 5, radius = 3, effect = CONST_ME_BLOCKHIT, target = false, duration = 6000, outfitMonster = "Thornback tortoise"}, + {name ="outfit", interval = 2000, chance = 6, radius = 3, effect = CONST_ME_BLOCKHIT, target = false, duration = 6000, outfitMonster = "orc"}, + {name ="outfit", interval = 2000, chance = 5, radius = 3, effect = CONST_ME_BLOCKHIT, target = false, duration = 6000, outfitMonster = "snake"}, + {name ="outfit", interval = 2000, chance = 6, radius = 3, effect = CONST_ME_BLOCKHIT, target = false, duration = 6000, outfitMonster = "warlock"}, + {name ="outfit", interval = 2000, chance = 5, radius = 3, effect = CONST_ME_BLOCKHIT, target = false, duration = 6000, outfitMonster = "witch"}, + {name ="outfit", interval = 2000, chance = 5, radius = 3, effect = CONST_ME_BLOCKHIT, target = false, duration = 6000, outfitMonster = "necromancer"}, + {name ="outfit", interval = 2000, chance = 5, radius = 3, effect = CONST_ME_BLOCKHIT, target = false, duration = 6000, outfitMonster = "dwarf geomancer"}, + {name ="outfit", interval = 2000, chance = 5, radius = 3, effect = CONST_ME_BLOCKHIT, target = false, duration = 6000, outfitMonster = "monk"}, + {name ="outfit", interval = 2000, chance = 5, radius = 3, effect = CONST_ME_BLOCKHIT, target = false, duration = 6000, outfitMonster = "crab"}, + {name ="outfit", interval = 2000, chance = 5, radius = 3, effect = CONST_ME_BLOCKHIT, target = false, duration = 6000, outfitMonster = "ghost"}, + {name ="outfit", interval = 2000, chance = 5, radius = 3, effect = CONST_ME_BLOCKHIT, target = false, duration = 6000, outfitMonster = "minotaur mage"}, + {name ="outfit", interval = 2000, chance = 5, radius = 3, effect = CONST_ME_BLOCKHIT, target = false, duration = 6000, outfitMonster = "green frog"}, + {name ="outfit", interval = 2000, chance = 5, radius = 3, effect = CONST_ME_BLOCKHIT, target = false, duration = 6000, outfitMonster = "parrot"}, + {name ="outfit", interval = 2000, chance = 15, radius = 3, effect = CONST_ME_BLOCKHIT, target = false, duration = 6000, outfitItem = 2096} +} + +monster.defenses = { + defense = 999, + armor = 999, + {name ="combat", interval = 1000, chance = 50, type = COMBAT_HEALING, minDamage = 1500, maxDamage = 2000, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/event_creatures/the_mutated_pumpkin.lua b/data/monster/event_creatures/the_mutated_pumpkin.lua new file mode 100644 index 00000000000..78047d66967 --- /dev/null +++ b/data/monster/event_creatures/the_mutated_pumpkin.lua @@ -0,0 +1,146 @@ +local mType = Game.createMonsterType("The Mutated Pumpkin") +local monster = {} + +monster.description = "The Mutated Pumpkin" +monster.experience = 30000 +monster.outfit = { + lookType = 292, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 500000 +monster.maxHealth = 500000 +monster.race = "undead" +monster.corpse = 8960 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I had the Halloween Hare for breakfast!", yell = false}, + {text = "Your soul will be mine...wait, wrong line", yell = false}, + {text = "Trick or treat? I saw death!", yell = false}, + {text = "No wait! Don't kill me! It's me, your friend!", yell = false}, + {text = "Bunnies, bah! I'm the real thing!", yell = false}, + {text = "Muahahahaha!", yell = false}, + {text = "I've come to avenge all those mutilated pumpkins!", yell = false}, + {text = "Wait until I get you!", yell = false}, + {text = "Fear the spirit of Halloween!", yell = false} +} + +monster.loot = { + {name = "pumpkin", chance = 100000}, + {name = "yummy gummy worm", chance = 100000, maxCount = 20}, + {id = 2688, chance = 1000, maxCount = 50}, + {id = 6569, chance = 1000, maxCount = 50}, + {name = "spiderwebs", chance = 1000}, + {id = 9006, chance = 1000}, + {id = 6492, chance = 1000}, + {id = 6526, chance = 1000}, + {name = "bar of chocolate", chance = 1000}, + {id = 6570, chance = 1000}, + {id = 6571, chance = 1000}, + {id = 2096, chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 105, attack = 85}, + {name ="combat", interval = 3000, chance = 18, type = COMBAT_MANADRAIN, minDamage = -100, maxDamage = -300, range = 7, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -100, maxDamage = -300, radius = 7, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 3000, chance = 14, type = COMBAT_ENERGYDAMAGE, minDamage = -40, maxDamage = -300, radius = 7, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -30, maxDamage = -300, radius = 8, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 3000, chance = 12, type = COMBAT_EARTHDAMAGE, minDamage = -100, maxDamage = -300, length = 8, spread = 3, effect = CONST_ME_PLANTATTACK, target = false}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -100, maxDamage = -400, length = 6, spread = 3, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="outfit", interval = 1000, chance = 2, radius = 8, effect = CONST_ME_LOSEENERGY, target = false, duration = 5000, outfitMonster = "The Mutated Pumpkin"} +} + +monster.defenses = { + defense = 60, + armor = 60, + {name ="combat", interval = 4000, chance = 15, type = COMBAT_HEALING, minDamage = 2000, maxDamage = 2900, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/event_creatures/undead_minion.lua b/data/monster/event_creatures/undead_minion.lua new file mode 100644 index 00000000000..a3b9280632d --- /dev/null +++ b/data/monster/event_creatures/undead_minion.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Undead Minion") +local monster = {} + +monster.description = "Undead Minion" +monster.experience = 550 +monster.outfit = { + lookType = 37, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 850 +monster.maxHealth = 850 +monster.race = "undead" +monster.corpse = 5963 +monster.speed = 230 +monster.manaCost = 620 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 1 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 40}, + {name = "blank rune", chance = 10000}, + {name = "battle hammer", chance = 5000}, + {name = "battle shield", chance = 1000}, + {name = "guardian shield", chance = 5000}, + {id = 6570, chance = 5538}, + {id = 6571, chance = 1538} +} + +monster.attacks = { + {name ="melee", interval = 1000, chance = 100, minDamage = 0, maxDamage = -248}, + {name ="combat", interval = 1000, chance = 13, type = COMBAT_LIFEDRAIN, minDamage = -100, maxDamage = -160, radius = 4, effect = CONST_ME_MORTAREA, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/extra_dimensional/breach_brood.lua b/data/monster/extra_dimensional/breach_brood.lua new file mode 100644 index 00000000000..2b9e8746761 --- /dev/null +++ b/data/monster/extra_dimensional/breach_brood.lua @@ -0,0 +1,134 @@ +local mType = Game.createMonsterType("Breach Brood") +local monster = {} + +monster.description = "a breach brood" +monster.experience = 1760 +monster.outfit = { + lookType = 878, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1235 +monster.Bestiary = { + class = "Extra Dimensional", + race = BESTY_RACE_EXTRA_DIMENSIONAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Otherworld." + } + +monster.health = 3500 +monster.maxHealth = 3500 +monster.race = "venom" +monster.corpse = 26048 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hisss!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2152, chance = 100000, maxCount = 5}, + {id = 26191, chance = 15000}, + {id = 26201, chance = 15000}, + {id = 26174, chance = 15000}, + {id = 7591, chance = 12200}, + {id = 7590, chance = 12000}, + {id = 8472, chance = 11700}, + {id = 26163, chance = 11500}, + {id = 26167, chance = 10600}, + {id = 26170, chance = 9600}, + {id = 26162, chance = 9600}, + {id = 18418, chance = 7400, maxCount = 2}, + {id = 18419, chance = 6500}, + {id = 18413, chance = 4400}, + {id = 18415, chance = 4100}, + {id = 26200, chance = 470}, + {id = 26198, chance = 470}-- collar of blue plasma +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -350}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -400, range = 6, shootEffect = CONST_ANI_FLASHARROW, effect = CONST_ME_STUN, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -150, maxDamage = -350, radius = 5, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="breach brood reducer", interval = 2000, chance = 20, target = false} +} + +monster.defenses = { + defense = 52, + armor = 52 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = -20}, + {type = COMBAT_FIREDAMAGE, percent = 40}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/extra_dimensional/courage_leech.lua b/data/monster/extra_dimensional/courage_leech.lua new file mode 100644 index 00000000000..2f280aa3c40 --- /dev/null +++ b/data/monster/extra_dimensional/courage_leech.lua @@ -0,0 +1,134 @@ +local mType = Game.createMonsterType("Courage Leech") +local monster = {} + +monster.description = "a courage leech" +monster.experience = 23920 +monster.outfit = { + lookType = 1315, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1941 +monster.Bestiary = { + class = "Extra Dimensional", + race = BESTY_RACE_EXTRA_DIMENSIONAL, + toKill = 5000, + FirstUnlock = 25, + SecondUnlock = 2500, + CharmsPoints = 100, + Stars = 5, + Occurrence = 0, + Locations = "Furious Crater." + } + +monster.health = 27000 +monster.maxHealth = 27000 +monster.race = "undead" +monster.corpse = 38744 +monster.speed = 226 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hiss.", yell = false}, + {text = "Zap! Zap!", yell = false} +} + +monster.loot = { + {name = "crystal coin", chance = 70540}, + {name = "lightning legs", chance = 75500}, + {name = "ultimate health potion", chance = 52220, maxCount = 7}, + {name = "lightning pendant", chance = 55500}, + {name = "lightning headband", chance = 25500}, + {name = "gold ring", chance = 13500}, + {name = "jade hammer", chance = 11500}, + {name = "hammer of wrath", chance = 10000}, + {name = "onyx flail", chance = 19500}, + {name = "twiceslicer", chance = 17500}, + {name = "stone skin amulet", chance = 15500}, + {name = "nightmare blade", chance = 9500}, + {name = "demonrage sword", chance = 7500}, + {name = "dreaded cleaver", chance = 2500}, + {name = "butcher's axe", chance = 1500}, + {id = 38944, chance = 50} -- Bag you desire +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1000}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_ENERGYDAMAGE, minDamage = -700, maxDamage = -1100, radius = 4, shootEffect = CONST_ANI_ETHEREALSPEAR, effect = CONST_ME_ENERGYAREA, target = true}, + {name ="combat", interval = 3000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -700, maxDamage = -1100, radius = 4, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HOLYDAMAGE, minDamage = -550, maxDamage = -900, range = 7, shootEffect = CONST_ANI_SMALLHOLY, effect = CONST_ME_HOLYDAMAGE, target = true} + -- Chain: const_me-> CONST_ME_PINK_ENERGY_SPARK, combat_t->COMBAT_ENERGYDAMAGE +} + +monster.defenses = { + defense = 90, + armor = 100 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = -20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = -25} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/extra_dimensional/dread_intruder.lua b/data/monster/extra_dimensional/dread_intruder.lua new file mode 100644 index 00000000000..640b18623bb --- /dev/null +++ b/data/monster/extra_dimensional/dread_intruder.lua @@ -0,0 +1,141 @@ +local mType = Game.createMonsterType("Dread Intruder") +local monster = {} + +monster.description = "a dread intruder" +monster.experience = 2400 +monster.outfit = { + lookType = 882, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1260 +monster.Bestiary = { + class = "Extra Dimensional", + race = BESTY_RACE_EXTRA_DIMENSIONAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Otherworld." + } + +monster.health = 4500 +monster.maxHealth = 4500 +monster.race = "venom" +monster.corpse = 26134 +monster.speed = 330 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Whirr!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2148, chance = 100000, maxCount = 89}, + {id = 2152, chance = 100000, maxCount = 8}, + {id = 26201, chance = 15000}, + {id = 26191, chance = 15000}, + {id = 26175, chance = 15000}, + {id = 26172, chance = 15000}, + {id = 8472, chance = 14000}, + {id = 8473, chance = 13500}, + {id = 7590, chance = 12700}, + {id = 26179, chance = 11800}, + {id = 26166, chance = 9600}, + {id = 18418, chance = 9500}, + {id = 18419, chance = 6200}, + {id = 2147, chance = 5400, maxCount = 2}, + {id = 2146, chance = 5400, maxCount = 2}, + {id = 2150, chance = 5000, maxCount = 2}, + {id = 18414, chance = 4500}, + {id = 2153, chance = 1000}, + {id = 26189, chance = 450}, + {id = 26198, chance = 230},-- collar of blue plasma + {id = 26199, chance = 230}, + {id = 26185, chance = 230} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -500}, + -- energy damage + {name ="condition", type = CONDITION_ENERGY, interval = 2000, chance = 20, minDamage = -400, maxDamage = -600, radius = 5, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_DEATHDAMAGE, minDamage = -250, maxDamage = -400, range = 4, radius = 4, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="dread intruder wave", interval = 2000, chance = 25, minDamage = -350, maxDamage = -550, target = false} +} + +monster.defenses = { + defense = 50, + armor = 50, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 80, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 90}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 80} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/extra_dimensional/instable_breach_brood.lua b/data/monster/extra_dimensional/instable_breach_brood.lua new file mode 100644 index 00000000000..3b1ce69b8db --- /dev/null +++ b/data/monster/extra_dimensional/instable_breach_brood.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Instable Breach Brood") +local monster = {} + +monster.description = "an instable breach brood" +monster.experience = 1100 +monster.outfit = { + lookType = 878, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1265 +monster.Bestiary = { + class = "Extra Dimensional", + race = BESTY_RACE_EXTRA_DIMENSIONAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Otherworld." + } + +monster.health = 2200 +monster.maxHealth = 2200 +monster.race = "venom" +monster.corpse = 26048 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hisss!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2152, chance = 20000, maxCount = 2}, + {id = 26177, chance = 10200}, + {id = 26162, chance = 10100}, + {id = 26201, chance = 4900}, + {id = 8472, chance = 4800}, + {id = 7590, chance = 4400}, + {id = 26191, chance = 4200}, + {id = 7591, chance = 4200}, + {id = 18415, chance = 3400}, + {id = 18419, chance = 3300}, + {id = 18418, chance = 2600}, + {id = 18413, chance = 2100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -240}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -160, maxDamage = -250, range = 6, shootEffect = CONST_ANI_FLASHARROW, effect = CONST_ME_STUN, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -80, maxDamage = -200, radius = 5, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="breach brood reducer", interval = 2000, chance = 20, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = -20}, + {type = COMBAT_FIREDAMAGE, percent = 40}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/extra_dimensional/instable_sparkion.lua b/data/monster/extra_dimensional/instable_sparkion.lua new file mode 100644 index 00000000000..2892c11df12 --- /dev/null +++ b/data/monster/extra_dimensional/instable_sparkion.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Instable Sparkion") +local monster = {} + +monster.description = "an instable sparkion" +monster.experience = 1350 +monster.outfit = { + lookType = 877, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1264 +monster.Bestiary = { + class = "Extra Dimensional", + race = BESTY_RACE_EXTRA_DIMENSIONAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Otherworld." + } + +monster.health = 1900 +monster.maxHealth = 1900 +monster.race = "venom" +monster.corpse = 26044 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Zzing!", yell = false}, + {text = "Frizzle!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2152, chance = 20000}, + {id = 26158, chance = 6000}, + {id = 26201, chance = 4900}, + {id = 8472, chance = 4800}, + {id = 7590, chance = 4400}, + {id = 7591, chance = 4200}, + {id = 26191, chance = 4200}, + {id = 26159, chance = 4000}, + {id = 26160, chance = 4000}, + {id = 26161, chance = 3500}, + {id = 18418, chance = 2600}, + {id = 18413, chance = 2100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -250, maxDamage = -350, length = 6, spread = 3, effect = CONST_ME_GROUNDSHAKER, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -150, maxDamage = -200, range = 5, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_ENERGYHIT, target = true}, + -- energy damage + {name ="condition", type = CONDITION_ENERGY, interval = 2000, chance = 20, minDamage = -300, maxDamage = -600, range = 6, radius = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_PURPLEENERGY, target = true} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="speed", interval = 2000, chance = 10, speedChange = 360, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 50, maxDamage = 80, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = -20}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 5}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/extra_dimensional/reality_reaver.lua b/data/monster/extra_dimensional/reality_reaver.lua new file mode 100644 index 00000000000..2b39790fd4e --- /dev/null +++ b/data/monster/extra_dimensional/reality_reaver.lua @@ -0,0 +1,141 @@ +local mType = Game.createMonsterType("Reality Reaver") +local monster = {} + +monster.description = "a reality reaver" +monster.experience = 2480 +monster.outfit = { + lookType = 879, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1224 +monster.Bestiary = { + class = "Extra Dimensional", + race = BESTY_RACE_EXTRA_DIMENSIONAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Otherworld." + } + +monster.health = 3900 +monster.maxHealth = 3900 +monster.race = "venom" +monster.corpse = 26068 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ssshhh!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2152, chance = 100000, maxCount = 6}, + {id = 26201, chance = 15000}, + {id = 26191, chance = 15000}, + {id = 26164, chance = 15000}, + {id = 26176, chance = 14700}, + {id = 8472, chance = 11400, maxCount = 2}, + {id = 7590, chance = 10300, maxCount = 2}, + {id = 7591, chance = 9700, maxCount = 2}, + {id = 26162, chance = 9700}, + {id = 26171, chance = 9600}, + {id = 18418, chance = 7900}, + {id = 18420, chance = 6000}, + {id = 18414, chance = 4400}, + {id = 18413, chance = 4000}, + {id = 2156, chance = 2600}, + {id = 26199, chance = 630}, + {id = 7901, chance = 520}, + {id = 2153, chance = 370}, + {id = 26185, chance = 370}, + {id = 26200, chance = 300}, + {id = 26187, chance = 220} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -500}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -180, maxDamage = -400, range = 5, radius = 5, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_PURPLEENERGY, target = true}, + {name ="reality reaver wave", interval = 2000, chance = 20, minDamage = -200, maxDamage = -500, target = false}, + -- energy damage + {name ="condition", type = CONDITION_ENERGY, interval = 2000, chance = 20, minDamage = -400, maxDamage = -800, radius = 5, effect = CONST_ME_STUN, target = false} +} + +monster.defenses = { + defense = 50, + armor = 50, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_POFF}, + {name ="speed", interval = 2000, chance = 10, speedChange = 380, effect = CONST_ME_HITAREA, target = false, duration = 8000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 15}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = -20}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/extra_dimensional/sparkion.lua b/data/monster/extra_dimensional/sparkion.lua new file mode 100644 index 00000000000..756635dffbe --- /dev/null +++ b/data/monster/extra_dimensional/sparkion.lua @@ -0,0 +1,143 @@ +local mType = Game.createMonsterType("Sparkion") +local monster = {} + +monster.description = "a sparkion" +monster.experience = 1520 +monster.outfit = { + lookType = 877, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1234 +monster.Bestiary = { + class = "Extra Dimensional", + race = BESTY_RACE_EXTRA_DIMENSIONAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Otherworld." + } + +monster.health = 2700 +monster.maxHealth = 2700 +monster.race = "venom" +monster.corpse = 26044 +monster.speed = 302 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Zzing!", yell = false}, + {text = "Frizzle!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2152, chance = 20000, maxCount = 3}, + {id = 26158, chance = 15000}, + {id = 26201, chance = 15000}, + {id = 26191, chance = 14600}, + {id = 26161, chance = 14100}, + {id = 26160, chance = 11100}, + {id = 7590, chance = 10100, maxCount = 2}, + {id = 8472, chance = 9700, maxCount = 2}, + {id = 7591, chance = 9500, maxCount = 2}, + {id = 26159, chance = 9100}, + {id = 18418, chance = 8600}, + {id = 18419, chance = 6000}, + {id = 2146, chance = 4900, maxCount = 2}, + {id = 18413, chance = 4200}, + {id = 2158, chance = 1000}, + {id = 2189, chance = 920}, + {id = 26187, chance = 370}, + {id = 26189, chance = 370}, + {id = 26185, chance = 240}, + {id = 26199, chance = 240}, + {id = 26198, chance = 240},-- collar of blue plasma + {id = 26200, chance = 200} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -250, maxDamage = -400, length = 6, spread = 3, effect = CONST_ME_GROUNDSHAKER, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -400, range = 5, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_ENERGYHIT, target = true}, + -- energy damage + {name ="condition", type = CONDITION_ENERGY, interval = 2000, chance = 20, minDamage = -300, maxDamage = -600, range = 6, radius = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_PURPLEENERGY, target = true} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="speed", interval = 2000, chance = 10, speedChange = 400, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 50, maxDamage = 180, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = -20}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 5}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/extra_dimensional/stabilizing_dread_intruder.lua b/data/monster/extra_dimensional/stabilizing_dread_intruder.lua new file mode 100644 index 00000000000..9d8f5b4b113 --- /dev/null +++ b/data/monster/extra_dimensional/stabilizing_dread_intruder.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Stabilizing Dread Intruder") +local monster = {} + +monster.description = "a stabilizing dread intruder" +monster.experience = 1900 +monster.outfit = { + lookType = 882, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1267 +monster.Bestiary = { + class = "Extra Dimensional", + race = BESTY_RACE_EXTRA_DIMENSIONAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Otherworld (Edron)" + } + +monster.health = 2800 +monster.maxHealth = 2800 +monster.race = "venom" +monster.corpse = 26134 +monster.speed = 290 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Whirr!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2152, chance = 20000, maxCount = 5}, + {id = 26191, chance = 12200}, + {id = 7590, chance = 10800}, + {id = 26169, chance = 9800}, + {id = 26173, chance = 9400}, + {id = 26178, chance = 9000}, + {id = 8473, chance = 8700}, + {id = 26201, chance = 8700}, + {id = 8472, chance = 8700}, + {id = 2150, chance = 5000, maxCount = 2}, + {id = 18418, chance = 4800}, + {id = 2146, chance = 4400, maxCount = 2}, + {id = 18414, chance = 4200}, + {id = 2147, chance = 3400, maxCount = 2}, + {id = 18419, chance = 3300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_DEATHDAMAGE, minDamage = -200, maxDamage = -300, range = 4, radius = 4, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="dread intruder wave", interval = 2000, chance = 25, minDamage = -350, maxDamage = -450, target = false} +} + +monster.defenses = { + defense = 50, + armor = 50, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 80, maxDamage = 120, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/extra_dimensional/stabilizing_reality_reaver.lua b/data/monster/extra_dimensional/stabilizing_reality_reaver.lua new file mode 100644 index 00000000000..ea4ee7adb0b --- /dev/null +++ b/data/monster/extra_dimensional/stabilizing_reality_reaver.lua @@ -0,0 +1,135 @@ +local mType = Game.createMonsterType("Stabilizing Reality Reaver") +local monster = {} + +monster.description = "a stabilizing reality reaver" +monster.experience = 1950 +monster.outfit = { + lookType = 879, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1266 +monster.Bestiary = { + class = "Extra Dimensional", + race = BESTY_RACE_EXTRA_DIMENSIONAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Otherworld (Edron)" + } + +monster.health = 2500 +monster.maxHealth = 2500 +monster.race = "venom" +monster.corpse = 26068 +monster.speed = 310 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ssshhh!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2152, chance = 100000, maxCount = 4}, + {id = 7591, chance = 14200}, + {id = 8472, chance = 14000}, + {id = 7590, chance = 12700}, + {id = 26201, chance = 11200}, + {id = 26191, chance = 10900}, + {id = 26157, chance = 9900}, + {id = 26180, chance = 8300}, + {id = 26162, chance = 8000}, + {id = 18420, chance = 3400}, + {id = 18414, chance = 3400}, + {id = 18418, chance = 2700, maxCount = 2}, + {id = 18413, chance = 1900}, + {id = 2156, chance = 1500}, + {id = 8920, chance = 1100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -180, maxDamage = -300, range = 5, radius = 5, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_PURPLEENERGY, target = true}, + {name ="reality reaver wave", interval = 2000, chance = 20, minDamage = -200, maxDamage = -350, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -80, maxDamage = -200, radius = 3, effect = CONST_ME_STUN, target = false} +} + +monster.defenses = { + defense = 45, + armor = 45, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_POFF}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 80, maxDamage = 210, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = 330, effect = CONST_ME_HITAREA, target = false, duration = 8000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 15}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = -20}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/extra_dimensional/yielothax.lua b/data/monster/extra_dimensional/yielothax.lua new file mode 100644 index 00000000000..60f12e0efde --- /dev/null +++ b/data/monster/extra_dimensional/yielothax.lua @@ -0,0 +1,137 @@ +local mType = Game.createMonsterType("Yielothax") +local monster = {} + +monster.description = "a yielothax" +monster.experience = 1250 +monster.outfit = { + lookType = 408, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 717 +monster.Bestiary = { + class = "Extra Dimensional", + race = BESTY_RACE_EXTRA_DIMENSIONAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "In another dimension, through a portal in the Raging Mage tower, southern Zao." + } + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "venom" +monster.corpse = 13752 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 75, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "IIEEH!! Iiih iih ih iiih!!!", yell = true}, + {text = "Bsssssssm Bssssssm Bsssssssssssm!", yell = true} +} + +monster.loot = { + {name = "small diamond", chance = 4761, maxCount = 5}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 27}, + {name = "talon", chance = 917}, + {name = "might ring", chance = 3846}, + {name = "wand of cosmic energy", chance = 523}, + {name = "epee", chance = 564}, + {name = "brown mushroom", chance = 9090, maxCount = 3}, + {name = "mastermind potion", chance = 490}, + {name = "strong health potion", chance = 20000}, + {name = "strong mana potion", chance = 20000}, + {name = "lightning pendant", chance = 862}, + {name = "lightning legs", chance = 480}, + {name = "shockwave amulet", chance = 571}, + {name = "broken ring of ending", chance = 261}, + {name = "yielowax", chance = 300}, + {name = "yielocks", chance = 320} +} + +monster.attacks = { + {name ="melee", interval = 1000, chance = 100, minDamage = 0, maxDamage = -203}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -100, maxDamage = -130, length = 4, spread = 3, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -150, maxDamage = -250, radius = 3, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -70, maxDamage = -120, radius = 3, effect = CONST_ME_HITBYPOISON, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -50, maxDamage = -150, length = 4, spread = 3, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 100, maxDamage = 150, effect = CONST_ME_HITBYPOISON, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 25}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/fey/arctic_faun.lua b/data/monster/fey/arctic_faun.lua new file mode 100644 index 00000000000..dbb3b4e13f1 --- /dev/null +++ b/data/monster/fey/arctic_faun.lua @@ -0,0 +1,134 @@ +local mType = Game.createMonsterType("Arctic Faun") +local monster = {} + +monster.description = "an arctic faun" +monster.experience = 300 +monster.outfit = { + lookType = 980, + lookHead = 85, + lookBody = 0, + lookLegs = 0, + lookFeet = 85, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1626 +monster.Bestiary = { + class = "Fey", + race = BESTY_RACE_FEY, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "Arctic Faun's Island." + } + +monster.health = 300 +monster.maxHealth = 300 +monster.race = "blood" +monster.corpse = 33423 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Dance with me!", yell = false}, + {text = "In vino veritas! Hahaha!", yell = false}, + {text = "Wine, women and song!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 105}, + {name = "dandelion seeds", chance = 14870}, + {name = "strong health potion", chance = 11760}, + {name = "fresh fruit", chance = 10290}, + {name = "shimmering beetles", chance = 9330}, + {name = "leaf star", chance = 8720, maxCount = 3}, + {name = "goat grass", chance = 7280}, + {name = "cookie", chance = 6150, maxCount = 5}, + {name = "grapes", chance = 5400}, + {name = "rainbow quartz", chance = 5260, maxCount = 2}, + {name = "small stone", chance = 5260, maxCount = 2}, + {name = "panpipes", chance = 4510}, + {name = "great health potion", chance = 3590}, + {name = "wood cape", chance = 820}, + {name = "leaf legs", chance = 340}, + {name = "wooden spellbook", chance = 210}, + {id = 5792, chance = 140} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 70}, + {type = COMBAT_FIREDAMAGE, percent = -15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 80}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/fey/boogy.lua b/data/monster/fey/boogy.lua new file mode 100644 index 00000000000..fbd4940d4f5 --- /dev/null +++ b/data/monster/fey/boogy.lua @@ -0,0 +1,137 @@ +local mType = Game.createMonsterType("Boogy") +local monster = {} + +monster.description = "a boogy" +monster.experience = 950 +monster.outfit = { + lookType = 981, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1439 +monster.Bestiary = { + class = "Fey", + race = BESTY_RACE_FEY, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Feyrist (night time) and its underground (all day)." + } + +monster.health = 1300 +monster.maxHealth = 1300 +monster.race = "blood" +monster.corpse = 29106 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.respawnType = { + period = RESPAWNPERIOD_NIGHT, + underground = true +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Go to sleep!", yell = false} +} + +monster.loot = { + {id = 27058, chance = 3000, maxCount = 5}, + {id = 7439, chance = 1500}, + {id = 9980, chance = 100}, + {id = 28998, chance = 15000}, + {id = 2148, chance = 100000, maxCount = 200}, + {id = 2418, chance = 900}, + {id = 5015, chance = 100}, + {id = 27630, chance = 2500, maxCount = 2}, + {id = 18420, chance = 3600, maxCount = 2}, + {id = 2802, chance = 3200}, + {id = 7761, chance = 3000, maxCount = 3}, + {id = 7588, chance = 15000}, + {id = 7887, chance = 3200}, + {id = 2791, chance = 4500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450}, + -- bleed + {name ="condition", type = CONDITION_BLEEDING, interval = 3000, chance = 11, minDamage = -100, maxDamage = -300, radius = 6, shootEffect = CONST_ANI_WHIRLWINDCLUB, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -60, maxDamage = -115, range = 7, shootEffect = CONST_ANI_LARGEROCK, effect = CONST_ME_EXPLOSIONAREA, target = true} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="speed", interval = 2000, chance = 15, speedChange = 450, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 0, maxDamage = 110, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 70}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 40}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/fey/dark_faun.lua b/data/monster/fey/dark_faun.lua new file mode 100644 index 00000000000..f4f4d2aeb1d --- /dev/null +++ b/data/monster/fey/dark_faun.lua @@ -0,0 +1,142 @@ +local mType = Game.createMonsterType("Dark Faun") +local monster = {} + +monster.description = "a dark faun" +monster.experience = 900 +monster.outfit = { + lookType = 980, + lookHead = 94, + lookBody = 114, + lookLegs = 57, + lookFeet = 94, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1496 +monster.Bestiary = { + class = "Fey", + race = BESTY_RACE_FEY, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Feyrist (nighttime) and its underground (all day)." + } + +monster.health = 1100 +monster.maxHealth = 1100 +monster.race = "blood" +monster.corpse = 29101 +monster.speed = 216 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10 +} + +monster.respawnType = { + period = RESPAWNPERIOD_NIGHT, + underground = true +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Blood, fight and rage!", yell = false}, + {text = "This will be your last dance!", yell = false}, + {text = "You're a threat to this realm! You have to die!", yell = false}, + {text = "This is a nightmare and you won't wake up!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 30000, maxCount = 112}, + {name = "wood cape", chance = 492}, + {name = "wooden spellbook", chance = 92}, + {name = "mandrake", chance = 50}, + {name = "leaf legs", chance = 492}, + {name = "small stone", chance = 492, maxCount = 4}, + {name = "small enchanted sapphire", chance = 492, maxCount = 2}, + {name = "shimmering beetles", chance = 492}, + {name = "cave turnip", chance = 55000, maxCount = 4}, + {name = "leaf legs", chance = 719}, + {name = "dark mushroom", chance = 719}, + {name = "panpipes", chance = 719}, + {name = "prismatic quartz", chance = 719}, + {name = "leaf star", chance = 10000, maxCount = 8}, + {name = "strong health potion", chance = 6800, maxCount = 2}, + {name = "goat grass", chance = 5155}, + {name = "great health potion", chance = 591} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -515}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -60, maxDamage = -115, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true}, + {name ="drunk", interval = 2000, chance = 11, length = 4, spread = 2, effect = CONST_ME_SOUND_PURPLE, target = false, duration = 25000}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -100, range = 7, shootEffect = CONST_ANI_LEAFSTAR, target = false} +} + +monster.defenses = { + defense = 50, + armor = 50, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 85, maxDamage = 105, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 70}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 40} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/fey/dryad.lua b/data/monster/fey/dryad.lua new file mode 100644 index 00000000000..637c9cd6664 --- /dev/null +++ b/data/monster/fey/dryad.lua @@ -0,0 +1,117 @@ +local mType = Game.createMonsterType("Dryad") +local monster = {} + +monster.description = "a dryad" +monster.experience = 190 +monster.outfit = { + lookType = 137, + lookHead = 80, + lookBody = 59, + lookLegs = 7, + lookFeet = 101, + lookAddons = 3, + lookMount = 0 +} + +monster.raceId = 383 +monster.Bestiary = { + class = "Fey", + race = BESTY_RACE_FEY, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 50, + Stars = 3, + Occurrence = 3, + Locations = "Dryads appear in forest areas of Edron, Port Hope, Carlin and Cormaya during raids in June. \z + There are 5 total waves, the initial one with the raid message and the rest every 15 minutes during next hour." + } + +monster.health = 310 +monster.maxHealth = 310 +monster.race = "blood" +monster.corpse = 20323 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Feel the wrath of mother Tibia!", yell = false}, + {text = "Defiler of nature!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 40000, maxCount = 20} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -40, range = 7, shootEffect = CONST_ANI_THROWINGKNIFE, target = false} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/fey/faun.lua b/data/monster/fey/faun.lua new file mode 100644 index 00000000000..eac7434d088 --- /dev/null +++ b/data/monster/fey/faun.lua @@ -0,0 +1,143 @@ +local mType = Game.createMonsterType("Faun") +local monster = {} + +monster.description = "a faun" +monster.experience = 800 +monster.outfit = { + lookType = 980, + lookHead = 81, + lookBody = 115, + lookLegs = 114, + lookFeet = 81, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1434 +monster.Bestiary = { + class = "Fey", + race = BESTY_RACE_FEY, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Feyrist (daytime)." + } + +monster.health = 900 +monster.maxHealth = 900 +monster.race = "blood" +monster.corpse = 29102 +monster.speed = 210 +monster.manaCost = 450 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.respawnType = { + period = RESPAWNPERIOD_DAY, + underground = false +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Are you posing a threat to this realm? I suppose so.", yell = false}, + {text = "In vino veritas! Hahaha!", yell = false}, + {text = "Wine, women and song!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 30000, maxCount = 136}, + {name = "goat grass", chance = 5155}, + {name = "leaf star", chance = 10000, maxCount = 7}, + {name = "grapes", chance = 30100, maxCount = 2}, + {name = "small enchanted sapphire", chance = 492, maxCount = 2}, + {name = "leaf legs", chance = 492}, + {name = "dandelion seeds", chance = 5800}, + {name = "shimmering beetles", chance = 492}, + {name = "panpipes", chance = 172}, + {name = "cookie", chance = 55000, maxCount = 5}, + {name = "great health potion", chance = 6400, maxCount = 2}, + {name = "wooden spellbook", chance = 92}, + {name = "strong health potion", chance = 6800, maxCount = 2}, + {name = "fresh fruit", chance = 3400, maxCount = 3}, + {name = "rainbow quartz", chance = 1086, maxCount = 4}, + {name = "small stone", chance = 492, maxCount = 3}, + {name = "wood cape", chance = 492}, + {id = 5792, chance = 80}, + {name = "mandrake", chance = 50} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -370}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -60, maxDamage = -115, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true}, + {name ="drunk", interval = 2000, chance = 11, length = 4, spread = 2, effect = CONST_ME_SOUND_PURPLE, target = false, duration = 25000}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -100, range = 7, shootEffect = CONST_ANI_LEAFSTAR, target = false} +} + +monster.defenses = { + defense = 45, + armor = 45, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 75, maxDamage = 90, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 70}, + {type = COMBAT_FIREDAMAGE, percent = -15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/fey/nymph.lua b/data/monster/fey/nymph.lua new file mode 100644 index 00000000000..591f3aefbc1 --- /dev/null +++ b/data/monster/fey/nymph.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Nymph") +local monster = {} + +monster.description = "a nymph" +monster.experience = 850 +monster.outfit = { + lookType = 989, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1485 +monster.Bestiary = { + class = "Fey", + race = BESTY_RACE_FEY, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Feyrist." + } + +monster.health = 900 +monster.maxHealth = 900 +monster.race = "blood" +monster.corpse = 29094 +monster.speed = 228 +monster.manaCost = 450 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Looking at a nymph can blind you. Be careful, mortal being!", yell = false}, + {text = "Come here, sweetheart! I won't hurt you! *giggle*", yell = false}, + {text = "Are you one of those evil nightmare creatures? Leave this realm alone!", yell = false}, + {text = "I'm just protecting nature's beauty!", yell = false} +} + +monster.loot = { + {id = 2745, chance = 400}, + {id = 2195, chance = 150}, + {id = 29000, chance = 12000}, + {id = 2127, chance = 1800}, + {id = 9927, chance = 500}, + {id = 28996, chance = 15000, maxCount = 2}, + {id = 2148, chance = 65000, maxCount = 110}, + {id = 7590, chance = 3000}, + {id = 8873, chance = 650}, + {id = 10219, chance = 1000}, + {id = 7762, chance = 2000, maxCount = 2}, + {id = 9970, chance = 2500, maxCount = 2}, + {id = 7589, chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -205}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -85, maxDamage = -135, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -85, maxDamage = -135, range = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_HEARTS, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -85, maxDamage = -135, range = 7, effect = CONST_ME_HEARTS, target = true} +} + +monster.defenses = { + defense = 60, + armor = 60, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 75, maxDamage = 90, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 60}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 40}, + {type = COMBAT_DEATHDAMAGE , percent = 40} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/fey/pixie.lua b/data/monster/fey/pixie.lua new file mode 100644 index 00000000000..183479cc13a --- /dev/null +++ b/data/monster/fey/pixie.lua @@ -0,0 +1,140 @@ +local mType = Game.createMonsterType("Pixie") +local monster = {} + +monster.description = "a pixie" +monster.experience = 700 +monster.outfit = { + lookType = 982, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1438 +monster.Bestiary = { + class = "Fey", + race = BESTY_RACE_FEY, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Feyrist." + } + +monster.health = 770 +monster.maxHealth = 770 +monster.race = "blood" +monster.corpse = 29098 +monster.speed = 240 +monster.manaCost = 450 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Glamour, glitter, glistering things! Do you have any of those?", yell = false}, + {text = "Sweet dreams!", yell = false}, + {text = "You might be a threat! I'm sorry but I can't allow you to linger here.", yell = false}, + {text = "Let's try a step or two!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 30000, maxCount = 90}, + {name = "rainbow quartz", chance = 1086, maxCount = 5}, + {name = "butterfly ring", chance = 492}, + {name = "wooden spellbook", chance = 92}, + {name = "dream blossom staff", chance = 92}, + {id = 2162, chance = 492}, + {name = "green mushroom", chance = 492}, + {name = "small enchanted amethyst", chance = 492, maxCount = 2}, + {name = "small topaz", chance = 592, maxCount = 2}, + {name = "rainbow quartz", chance = 719, maxCount = 3}, + {name = "colourful snail shell", chance = 719}, + {name = "star herb", chance = 719}, + {name = "leaf star", chance = 10000, maxCount = 5}, + {name = "red rose", chance = 30100}, + {name = "strong mana potion", chance = 6800}, + {name = "wild flowers", chance = 5155}, + {name = "great mana potion", chance = 591}, + {name = "dandelion seeds", chance = 5800}, + {name = "fresh fruit", chance = 3400, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -85, maxDamage = -135, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="speed", interval = 2000, chance = 11, speedChange = -440, length = 4, spread = 2, effect = CONST_ME_MAGIC_GREEN, target = false, duration = 7000}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -100, range = 4, shootEffect = CONST_ANI_LEAFSTAR, target = false}, + {name ="pixie skill reducer", interval = 2000, chance = 20, target = false} +} + +monster.defenses = { + defense = 45, + armor = 50, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 40, maxDamage = 75, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 60}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 60}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/fey/pooka.lua b/data/monster/fey/pooka.lua new file mode 100644 index 00000000000..913b60c3e27 --- /dev/null +++ b/data/monster/fey/pooka.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Pooka") +local monster = {} + +monster.description = "a pooka" +monster.experience = 500 +monster.outfit = { + lookType = 977, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1435 +monster.Bestiary = { + class = "Fey", + race = BESTY_RACE_FEY, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Feyrist (daytime)." + } + +monster.health = 500 +monster.maxHealth = 500 +monster.race = "blood" +monster.corpse = 29110 +monster.speed = 230 +monster.manaCost = 450 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.respawnType = { + period = RESPAWNPERIOD_DAY, + underground = false +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hoppel-di-hopp!", yell = false}, + {text = "Jinx!", yell = false}, + {text = "This was the initial trick, but the second follows quick!", yell = false} +} + +monster.loot = { + {name = "carrot on a stick", chance = 20}, + {name = "dream blossom staff", chance = 20}, + {name = "small stone", chance = 200, maxCount = 5}, + {name = "gold coin", chance = 30000, maxCount = 100}, + {name = "stealth ring", chance = 492}, + {id = 2684, chance = 55000, maxCount = 3}, + {name = "strong health potion", chance = 719}, + {name = "orange mushroom", chance = 10000}, + {name = "fern", chance = 30100}, + {name = "opal", chance = 5155}, + {name = "Shimmering Beetles", chance = 591}, + {name = "Rainbow Quartz", chance = 5800}, + {name = "Small Enchanted Ruby", chance = 3400, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -120}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -50, range = 4, shootEffect = CONST_ANI_SMALLSTONE, effect = CONST_ME_STONES, target = true}, + {name ="drunk", interval = 2000, chance = 11, length = 4, spread = 2, effect = CONST_ME_STUN, target = false, duration = 5000} +} + +monster.defenses = { + defense = 38, + armor = 38, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 40, maxDamage = 60, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 70}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/fey/swan_maiden.lua b/data/monster/fey/swan_maiden.lua new file mode 100644 index 00000000000..a8b788e2e0e --- /dev/null +++ b/data/monster/fey/swan_maiden.lua @@ -0,0 +1,138 @@ +local mType = Game.createMonsterType("Swan Maiden") +local monster = {} + +monster.description = "a swan maiden" +monster.experience = 700 +monster.outfit = { + lookType = 138, + lookHead = 0, + lookBody = 0, + lookLegs = 114, + lookFeet = 97, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1437 +monster.Bestiary = { + class = "Fey", + race = BESTY_RACE_FEY, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "Feyrist Meadows." + } + +monster.health = 800 +monster.maxHealth = 800 +monster.race = "blood" +monster.corpse = 29118 +monster.speed = 234 +monster.manaCost = 450 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Are you stalking me? You will bitterly regret this!", yell = false}, + {text = "Nightmarish monster! This dream is not meant for you!", yell = false}, + {text = "You won't steal my robe! Back off!", yell = false}, + {text = "You are not allowed to lay eyes on me in this shape!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 30000, maxCount = 112}, + {name = "small enchanted emerald", chance = 492, maxCount = 2}, + {name = "green mushroom", chance = 492, maxCount = 2}, + {name = "white pearl", chance = 492, maxCount = 2}, + {name = "opal", chance = 492, maxCount = 2}, + {name = "strong mana potion", chance = 6800}, + {name = "clerical mace", chance = 5155}, + {name = "great mana potion", chance = 591}, + {name = "colourful snail shell", chance = 5800}, + {name = "diamond sceptre", chance = 3400}, + {name = "coral brooch", chance = 3400}, + {name = "flower wreath", chance = 3400}, + {name = "powder herb", chance = 3400}, + {name = "silver brooch", chance = 3400}, + {name = "summer dress", chance = 3400}, + {name = "wild flowers", chance = 3400}, + {name = "boots of haste", chance = 50}, + {name = "butterfly ring", chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -215}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -60, maxDamage = -115, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 2000, chance = 11, type = COMBAT_MANADRAIN, minDamage = -82, maxDamage = -215, range = 7, shootEffect = CONST_ANI_HOLY, effect = CONST_ME_HOLYAREA, target = true}, + {name ="speed", interval = 2000, chance = 11, speedChange = -450, radius = 6, effect = CONST_ME_PIXIE_EXPLOSION, target = false, duration = 5000} +} + +monster.defenses = { + defense = 54, + armor = 54, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 85, maxDamage = 105, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 30}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/fey/twisted_pooka.lua b/data/monster/fey/twisted_pooka.lua new file mode 100644 index 00000000000..a609593e661 --- /dev/null +++ b/data/monster/fey/twisted_pooka.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Twisted Pooka") +local monster = {} + +monster.description = "a twisted pooka" +monster.experience = 600 +monster.outfit = { + lookType = 978, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1436 +monster.Bestiary = { + class = "Fey", + race = BESTY_RACE_FEY, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Feyrist (nighttime) and its underground (all day)." + } + +monster.health = 700 +monster.maxHealth = 700 +monster.race = "blood" +monster.corpse = 29114 +monster.speed = 230 +monster.manaCost = 450 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.respawnType = { + period = RESPAWNPERIOD_NIGHT, + underground = true +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "*sniff sniff* Mhmmm ... mortal flesh.", yell = false}, + {text = "Hoppel-di-hopp!", yell = false}, + {text = "I'll gnaw away your toes!", yell = false} +} + +monster.loot = { + {name = "carrot on a stick", chance = 20}, + {name = "small stone", chance = 200, maxCount = 5}, + {name = "gold coin", chance = 30000, maxCount = 100}, + {name = "stealth ring", chance = 492}, + {id = 2684, chance = 55000, maxCount = 3}, + {name = "strong health potion", chance = 719}, + {name = "orange mushroom", chance = 10000}, + {name = "fairy wings", chance = 30100}, + {name = "orange mushroom", chance = 5155}, + {name = "Shimmering Beetles", chance = 591}, + {name = "Small Enchanted Ruby", chance = 3400, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -120}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -50, range = 4, shootEffect = CONST_ANI_SMALLSTONE, effect = CONST_ME_STONES, target = true}, + -- earth damage + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -50, maxDamage = -100, range = 3, effect = CONST_ME_POISONAREA, target = true}, + {name ="drunk", interval = 2000, chance = 11, length = 4, spread = 2, effect = CONST_ME_STUN, target = false, duration = 5000} +} + +monster.defenses = { + defense = 38, + armor = 38, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 40, maxDamage = 60, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = -20}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/fey/wisp.lua b/data/monster/fey/wisp.lua new file mode 100644 index 00000000000..1d455756837 --- /dev/null +++ b/data/monster/fey/wisp.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("Wisp") +local monster = {} + +monster.description = "a wisp" +monster.experience = 0 +monster.outfit = { + lookType = 294, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 462 +monster.Bestiary = { + class = "Fey", + race = BESTY_RACE_FEY, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "All around Tiquanda and Feyrist. Several groups of Wisps can be found in and around \z + the forests north of Edron. West of Hardek. Inside the Cyclops Camp. North of the triple \z + Wyvern spawn outside Kazordoon. West of Ab'Dendriel. West of Venore Amazon Camp. \z + A few spawns around Venore, 2 spawn on the Formorgar Glacier, and on Krimhorn." + } + +monster.health = 115 +monster.maxHealth = 115 +monster.race = "undead" +monster.corpse = 6324 +monster.speed = 162 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 15, + targetDistance = 7, + runHealth = 115, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Crackle!", yell = false}, + {text = "Tsshh", yell = false} +} + +monster.loot = { + {name = "moon backpack", chance = 220} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -10}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -3, maxDamage = -7, range = 1, effect = CONST_ME_MAGIC_RED, target = true} +} + +monster.defenses = { + defense = 10, + armor = 10, + {name ="speed", interval = 2000, chance = 15, speedChange = 200, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 15, maxDamage = 25, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 3000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 65}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 90}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/giants/behemoth.lua b/data/monster/giants/behemoth.lua new file mode 100644 index 00000000000..4b97afa3f17 --- /dev/null +++ b/data/monster/giants/behemoth.lua @@ -0,0 +1,142 @@ +local mType = Game.createMonsterType("Behemoth") +local monster = {} + +monster.description = "a behemoth" +monster.experience = 2500 +monster.outfit = { + lookType = 55, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 55 +monster.Bestiary = { + class = "Giant", + race = BESTY_RACE_GIANT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Cyclopolis, deepest part of Tarpit Tomb after the flame, Forbidden Lands, Vandura Mountain, \z + Deeper Banuta, Serpentine Tower (unreachable), deep into the Formorgar Mines, Arena and Zoo Quarter, \z + The Dark Path, Lower Spike, Chyllfroest, Medusa Tower and Underground Glooth Factory (west side)." + } + +monster.health = 4000 +monster.maxHealth = 4000 +monster.race = "blood" +monster.corpse = 5999 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You're so little!", yell = false}, + {text = "Human flesh - delicious!", yell = false}, + {text = "Crush the intruders!", yell = false} +} + +monster.loot = { + {id = 2023, chance = 100}, + {name = "crystal necklace", chance = 2530}, + {name = "gold coin", chance = 595300, maxCount = 100}, + {name = "gold coin", chance = 40000, maxCount = 99}, + {name = "small amethyst", chance = 6380, maxCount = 5}, + {name = "platinum coin", chance = 59800, maxCount = 5}, + {name = "strange symbol", chance = 750}, + {id = 2231, chance = 670}, + {name = "two handed sword", chance = 5980}, + {name = "double axe", chance = 10510}, + {name = "giant sword", chance = 1006}, + {name = "crowbar", chance = 100}, + {name = "war axe", chance = 50}, + {name = "plate armor", chance = 3930}, + {name = "dark armor", chance = 4370}, + {id = 2553, chance = 650}, + {name = "steel boots", chance = 380}, + {name = "meat", chance = 30000, maxCount = 6}, + {name = "perfect behemoth fang", chance = 1090}, + {name = "behemoth claw", chance = 430}, + {name = "assassin star", chance = 9750, maxCount = 5}, + {id = 7396, chance = 170}, + {name = "titan axe", chance = 90}, + {name = "great health potion", chance = 5120}, + {name = "battle stone", chance = 14000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, range = 7, shootEffect = CONST_ANI_LARGEROCK, target = false} +} + +monster.defenses = { + defense = 45, + armor = 45, + {name ="speed", interval = 2000, chance = 15, speedChange = 300, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/giants/cyclops.lua b/data/monster/giants/cyclops.lua new file mode 100644 index 00000000000..f19ddfd5c83 --- /dev/null +++ b/data/monster/giants/cyclops.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Cyclops") +local monster = {} + +monster.description = "a cyclops" +monster.experience = 150 +monster.outfit = { + lookType = 22, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 22 +monster.Bestiary = { + class = "Giant", + race = BESTY_RACE_GIANT, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Ab'Dendriel Underground, Cyclopolis, Femor Hills, Kazordoon Prison, Kazordoon Surroundings, \z + Maze of the Lost Souls, Mistrock, Mount Sternum, Outlaw Camp, Plains of Havoc, Shadowthorn, \z + Thais Northern Dungeon, Thais Surroundings, Thais Underground, Ulderek's Rock, Yalahar Foreigner Quarter." + } + +monster.health = 260 +monster.maxHealth = 260 +monster.race = "blood" +monster.corpse = 5962 +monster.speed = 190 +monster.manaCost = 490 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Il lorstok human!", yell = false}, + {text = "Toks utat.", yell = false}, + {text = "Human, uh whil dyh!", yell = false}, + {text = "Youh ah trak!", yell = false}, + {text = "Let da mashing begin!", yell = false} +} + +monster.loot = { + {id = 2129, chance = 190}, + {name = "gold coin", chance = 82000, maxCount = 47}, + {name = "club ring", chance = 90}, + {name = "halberd", chance = 1003}, + {name = "short sword", chance = 8000}, + {name = "dark helmet", chance = 220}, + {name = "plate shield", chance = 2500}, + {name = "battle shield", chance = 1400}, + {name = "meat", chance = 30070}, + {id = 7398, chance = 80}, + {name = "health potion", chance = 210}, + {name = "cyclops toe", chance = 4930}, + {id = 26654, chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -105} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 25}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/giants/cyclops_drone.lua b/data/monster/giants/cyclops_drone.lua new file mode 100644 index 00000000000..068b0135754 --- /dev/null +++ b/data/monster/giants/cyclops_drone.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Cyclops Drone") +local monster = {} + +monster.description = "a cyclops drone" +monster.experience = 200 +monster.outfit = { + lookType = 280, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 391 +monster.Bestiary = { + class = "Giant", + race = BESTY_RACE_GIANT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Cyclopolis, Mount Sternum, Mistrock and in the Cyclops version of the Forsaken Mine." + } + +monster.health = 325 +monster.maxHealth = 325 +monster.race = "blood" +monster.corpse = 7847 +monster.speed = 198 +monster.manaCost = 525 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Fee! Fie! Foe! Fum!", yell = false}, + {text = "Luttl pest!", yell = false}, + {text = "Me makking you pulp!", yell = false}, + {text = "Humy tasy! Hum hum!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 82000, maxCount = 30}, + {name = "club ring", chance = 90}, + {name = "halberd", chance = 680}, + {name = "short sword", chance = 8000}, + {name = "dark helmet", chance = 190}, + {name = "plate shield", chance = 2000}, + {name = "battle shield", chance = 1600}, + {name = "meat", chance = 50430, maxCount = 2}, + {id = 7398, chance = 120}, + {name = "strong health potion", chance = 520}, + {name = "cyclops toe", chance = 6750} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -105}, + {name ="combat", interval = 2000, chance = 35, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -80, range = 7, shootEffect = CONST_ANI_LARGEROCK, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 1}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/giants/cyclops_smith.lua b/data/monster/giants/cyclops_smith.lua new file mode 100644 index 00000000000..2ab113182bc --- /dev/null +++ b/data/monster/giants/cyclops_smith.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Cyclops Smith") +local monster = {} + +monster.description = "a cyclops smith" +monster.experience = 255 +monster.outfit = { + lookType = 277, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 389 +monster.Bestiary = { + class = "Giant", + race = BESTY_RACE_GIANT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Cyclopolis second floor and below, Mistrock, Mount Sternum, \z + Cyclops Camp second floor and in the Cyclops version of the Forsaken Mine." + } + +monster.health = 435 +monster.maxHealth = 435 +monster.race = "blood" +monster.corpse = 7740 +monster.speed = 204 +monster.manaCost = 695 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Outis emoi g' onoma.", yell = false}, + {text = "Whack da humy!", yell = false}, + {text = "Ai humy phary ty kaynon", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 82920, maxCount = 70}, + {name = "club ring", chance = 90}, + {name = "battle axe", chance = 5450}, + {name = "double axe", chance = 880}, + {name = "battle hammer", chance = 5200}, + {name = "heavy machete", chance = 2000}, + {name = "dark helmet", chance = 200}, + {name = "plate shield", chance = 2000}, + {name = "battle shield", chance = 6190}, + {name = "meat", chance = 49950}, + {id = 7398, chance = 140}, + {name = "spiked squelcher", chance = 150}, + {name = "strong health potion", chance = 390}, + {name = "cyclops toe", chance = 10280} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -70, range = 7, shootEffect = CONST_ANI_WHIRLWINDCLUB, target = false}, + {name ="drunk", interval = 2000, chance = 10, shootEffect = CONST_ANI_WHIRLWINDCLUB, effect = CONST_ME_STUN, target = false, duration = 4000} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 1}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/giants/frost_giant.lua b/data/monster/giants/frost_giant.lua new file mode 100644 index 00000000000..57014197a94 --- /dev/null +++ b/data/monster/giants/frost_giant.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Frost Giant") +local monster = {} + +monster.description = "a frost giant" +monster.experience = 150 +monster.outfit = { + lookType = 257, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 324 +monster.Bestiary = { + class = "Giant", + race = BESTY_RACE_GIANT, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Tyrsung (in the Jotunar mountain), Formorgar Glacier (single spawn), \z + Mammoth Shearing Factory, Chyllfroest." + } + +monster.health = 270 +monster.maxHealth = 270 +monster.race = "blood" +monster.corpse = 7330 +monster.speed = 190 +monster.manaCost = 490 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hmm Humansoup!", yell = false}, + {text = "Stand still ya tasy snack!", yell = false}, + {text = "Joh Thun!", yell = false}, + {text = "Br�re Sm�de!", yell = false}, + {text = "H�rre Sjan Flan!", yell = false}, + {text = "Forle Bramma", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 82000, maxCount = 40}, + {name = "club ring", chance = 130}, + {name = "halberd", chance = 560}, + {name = "short sword", chance = 8140}, + {name = "dark helmet", chance = 180}, + {name = "battle shield", chance = 1350}, + {name = "meat", chance = 4970, maxCount = 2}, + {name = "shard", chance = 60}, + {id = 7441, chance = 2180}, + {name = "norse shield", chance = 250}, + {name = "health potion", chance = 819}, + {name = "frost giant pelt", chance = 5000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -110}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -90, range = 7, shootEffect = CONST_ANI_LARGEROCK, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="speed", interval = 2000, chance = 15, speedChange = 300, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/giants/frost_giantess.lua b/data/monster/giants/frost_giantess.lua new file mode 100644 index 00000000000..2c08f4a20bb --- /dev/null +++ b/data/monster/giants/frost_giantess.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Frost Giantess") +local monster = {} + +monster.description = "a frost giantess" +monster.experience = 150 +monster.outfit = { + lookType = 265, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 334 +monster.Bestiary = { + class = "Giant", + race = BESTY_RACE_GIANT, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Tyrsung (in the Jotunar mountain), Formorgar Glacier (single spawn), \z + Mammoth Shearing Factory, Chyllfroest." + } + +monster.health = 275 +monster.maxHealth = 275 +monster.race = "blood" +monster.corpse = 7330 +monster.speed = 194 +monster.manaCost = 490 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 60, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ymirs Mjalle!", yell = false}, + {text = "No run so much, must stay fat!", yell = false}, + {text = "H�rre Sjan Flan!", yell = false}, + {text = "Damned fast food.", yell = false}, + {text = "Come kiss the cook!", yell = false} +} + +monster.loot = { + {name = "small stone", chance = 10360, maxCount = 3}, + {name = "gold coin", chance = 80000, maxCount = 40}, + {name = "club ring", chance = 70}, + {name = "short sword", chance = 7960}, + {name = "dark helmet", chance = 170}, + {name = "battle shield", chance = 1490}, + {name = "ham", chance = 20990, maxCount = 2}, + {name = "shard", chance = 100}, + {id = 7441, chance = 2008}, + {name = "norse shield", chance = 320}, + {name = "mana potion", chance = 950}, + {name = "frost giant pelt", chance = 4800} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -60}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -90, range = 7, shootEffect = CONST_ANI_LARGEROCK, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="speed", interval = 2000, chance = 15, speedChange = 300, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -3} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/giants/ogre_brute.lua b/data/monster/giants/ogre_brute.lua new file mode 100644 index 00000000000..2f8ad04246a --- /dev/null +++ b/data/monster/giants/ogre_brute.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Ogre Brute") +local monster = {} + +monster.description = "an ogre brute" +monster.experience = 800 +monster.outfit = { + lookType = 857, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1161 +monster.Bestiary = { + class = "Giant", + race = BESTY_RACE_GIANT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Krailos Steppe." + } + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "blood" +monster.corpse = 24799 +monster.speed = 204 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You so juicy!", yell = false}, + {text = "You stop! You lunch!", yell = false}, + {text = "Smash you face in!!!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 92000, maxCount = 130}, + {id = 2666, chance = 6200}, + {id = 2147, chance = 4200}, + {id = 2143, chance = 6200, maxCount = 3}, + {id = 12403, chance = 6200}, + {id = 2687, chance = 6200, maxCount = 7}, + {id = 24844, chance = 5200}, + {id = 24845, chance = 1200}, + {id = 24849, chance = 3200, maxCount = 2}, + {id = 24850, chance = 3200, maxCount = 3}, + {id = 2166, chance = 2200}, + {id = 24847, chance = 1200}, + {id = 7588, chance = 6200, maxCount = 3}, + {id = 7428, chance = 500}, + {id = 24827, chance = 800}, + {id = 2562, chance = 500}, + {id = 9820, chance = 200}, + {id = 24848, chance = 300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -269, condition = {type = CONDITION_FIRE, totalDamage = 6, interval = 9000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -70, maxDamage = -180, range = 7, shootEffect = CONST_ANI_POISON, target = false}, + {name ="drunk", interval = 2000, chance = 10, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_TELEPORT, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 80, maxDamage = 95, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/giants/ogre_rowdy.lua b/data/monster/giants/ogre_rowdy.lua new file mode 100644 index 00000000000..c8c89a5087a --- /dev/null +++ b/data/monster/giants/ogre_rowdy.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Ogre Rowdy") +local monster = {} + +monster.description = "an ogre rowdy" +monster.experience = 4200 +monster.outfit = { + lookType = 1213, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1821 +monster.Bestiary = { + class = "Giant", + race = BESTY_RACE_GIANT, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Kilmaresh Central Steppe, Kilmaresh Southern Steppe, Green Belt, Kilmaresh Mountains (underground)." + } + +monster.health = 4500 +monster.maxHealth = 4500 +monster.race = "blood" +monster.corpse = 36366 +monster.speed = 420 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 3}, + {name = "flaming arrow", chance = 22040, maxCount = 19}, + {name = "ogre ear stud", chance = 12900}, + {name = "ogre nose ring", chance = 20970}, + {name = "skull fetish", chance = 12900}, + {name = "wand of inferno", chance = 8600}, + {name = "jalapeno pepper", chance = 3760, maxCount = 3}, + {name = "wand of draconia", chance = 2150}, + {name = "wand of everblazing", chance = 1080}, + {name = "ogre choppa", chance = 540} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_FIREDAMAGE, minDamage = -250, maxDamage = -400, range = 5, radius = 4, shootEffect = CONST_ANI_WHIRLWINDAXE, effect = CONST_ME_EXPLOSIONHIT, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -450, radius = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_FIREDAMAGE, minDamage = -280, maxDamage = -420, range = 3, shootEffect = CONST_ANI_FLAMMINGARROW, target = true} +} + +monster.defenses = { + defense = 98, + armor = 98 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 70}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -30}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/giants/ogre_ruffian.lua b/data/monster/giants/ogre_ruffian.lua new file mode 100644 index 00000000000..43fb48ee3a5 --- /dev/null +++ b/data/monster/giants/ogre_ruffian.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Ogre Ruffian") +local monster = {} + +monster.description = "an ogre ruffian" +monster.experience = 5000 +monster.outfit = { + lookType = 1212, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1820 +monster.Bestiary = { + class = "Giant", + race = BESTY_RACE_GIANT, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Kilmaresh Central Steppe, Kilmaresh Southern Steppe, Green Belt, Kilmaresh Mountains (underground)." + } + +monster.health = 5500 +monster.maxHealth = 5500 +monster.race = "blood" +monster.corpse = 36362 +monster.speed = 430 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 3}, + {name = "ogre ear stud", chance = 17270}, + {name = "ogre nose ring", chance = 15830}, + {name = "pair of iron fists", chance = 2160}, + {name = "meat", chance = 8630, maxCount = 5}, + {name = "diamond sceptre", chance = 5760}, + {name = "war hammer", chance = 2160}, + {name = "metal spats", chance = 1440}, + {name = "skull fetish", chance = 1440}, + {name = "stone skin amulet", chance = 4320} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_PHYSICALDAMAGE, minDamage = -250, maxDamage = -450, radius = 5, effect = CONST_ME_GROUNDSHAKER, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -350, range = 4, radius = 5, shootEffect = CONST_ANI_LARGEROCK, effect = CONST_ME_POFF, target = true} +} + +monster.defenses = { + defense = 102, + armor = 102 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/giants/ogre_sage.lua b/data/monster/giants/ogre_sage.lua new file mode 100644 index 00000000000..f1203f1be04 --- /dev/null +++ b/data/monster/giants/ogre_sage.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Ogre Sage") +local monster = {} + +monster.description = "an ogre sage" +monster.experience = 5500 +monster.outfit = { + lookType = 1214, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1822 +monster.Bestiary = { + class = "Giant", + race = BESTY_RACE_GIANT, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Kilmaresh Central Steppe, Kilmaresh Southern Steppe, Green Belt, Kilmaresh Mountains (underground)." + } + +monster.health = 4800 +monster.maxHealth = 4800 +monster.race = "blood" +monster.corpse = 36370 +monster.speed = 460 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Young Goanna", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 3}, + {name = "ogre ear stud", chance = 7950}, + {name = "ogre nose ring", chance = 15830}, + {name = "shamanic talisman", chance = 10230}, + {name = "broken shamanic staff", chance = 12500}, + {name = "skull fetish", chance = 9090}, + {name = "terra boots", chance = 4550}, + {name = "bone fetish", chance = 2270}, + {name = "sacred tree amulet", chance = 1140} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450}, + {name ="combat", interval = 2000, chance = 24, type = COMBAT_LIFEDRAIN, minDamage = -50, maxDamage = -130, range = 7, shootEffect = CONST_ANI_SMALLSTONE, target = true}, + {name ="combat", interval = 2000, chance = 16, type = COMBAT_ENERGYDAMAGE, minDamage = -100, maxDamage = -165, range = 4, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -115, maxDamage = -200, range = 7, radius = 3, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_EARTHDAMAGE, minDamage = -200, maxDamage = -300, range = 7, radius = 4, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_HITBYPOISON, target = true} +} + +monster.defenses = { + defense = 93, + armor = 93, + {name ="speed", interval = 2000, chance = 15, speedChange = 300, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -30}, + {type = COMBAT_EARTHDAMAGE, percent = 75}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/giants/ogre_savage.lua b/data/monster/giants/ogre_savage.lua new file mode 100644 index 00000000000..527f69e291f --- /dev/null +++ b/data/monster/giants/ogre_savage.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Ogre Savage") +local monster = {} + +monster.description = "an ogre savage" +monster.experience = 950 +monster.outfit = { + lookType = 858, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1162 +monster.Bestiary = { + class = "Giant", + race = BESTY_RACE_GIANT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Krailos Steppe." + } + +monster.health = 1400 +monster.maxHealth = 1400 +monster.race = "blood" +monster.corpse = 24803 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Must! Chop! Food! Raahh!", yell = false}, + {text = "You tasty!", yell = false}, + {text = "UGGA UGGA!!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 92000, maxCount = 130}, + {id = 24849, chance = 3200, maxCount = 2}, + {id = 24850, chance = 3200, maxCount = 3}, + {id = 2687, chance = 2200, maxCount = 7}, + {id = 8844, chance = 1200, maxCount = 2}, + {id = 9970, chance = 1200, maxCount = 2}, + {id = 2147, chance = 1200, maxCount = 2}, + {id = 7439, chance = 1200}, + {id = 2194, chance = 2200}, + {id = 24844, chance = 1200}, + {id = 24845, chance = 1200}, + {id = 24847, chance = 1200}, + {id = 7588, chance = 2200, maxCount = 3}, + {id = 2391, chance = 600}, + {id = 24848, chance = 300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -269, condition = {type = CONDITION_FIRE, totalDamage = 6, interval = 9000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -70, maxDamage = -180, range = 7, shootEffect = CONST_ANI_POISON, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 80, maxDamage = 95, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/giants/ogre_shaman.lua b/data/monster/giants/ogre_shaman.lua new file mode 100644 index 00000000000..6795836dff0 --- /dev/null +++ b/data/monster/giants/ogre_shaman.lua @@ -0,0 +1,145 @@ +local mType = Game.createMonsterType("Ogre Shaman") +local monster = {} + +monster.description = "an ogre shaman" +monster.experience = 625 +monster.outfit = { + lookType = 859, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1163 +monster.Bestiary = { + class = "Giant", + race = BESTY_RACE_GIANT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Krailos Steppe." + } + +monster.health = 800 +monster.maxHealth = 800 +monster.race = "blood" +monster.corpse = 24795 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Dworc Fleshhunter", chance = 30, interval = 1000, max = 1}, + {name = "Terror Bird", chance = 30, interval = 1000, max = 1} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "The spirits hunger!", yell = false}, + {text = "A sacrifice for Great Hunger!", yell = false}, + {text = "Stay here, soul food!", yell = false}, + {text = "You more delicate than clomp!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 92000, maxCount = 130}, + {id = 24850, chance = 1200, maxCount = 3}, + {id = 24841, chance = 6200, maxCount = 2}, + {id = 2147, chance = 2200, maxCount = 2}, + {id = 2144, chance = 1200, maxCount = 2}, + {id = 20111, chance = 3200}, + {id = 12408, chance = 1200}, + {id = 2185, chance = 800}, + {id = 24844, chance = 3200}, + {id = 24845, chance = 2200}, + {id = 24840, chance = 1200}, + {id = 2229, chance = 1200}, + {id = 24847, chance = 1200}, + {id = 7589, chance = 1000, maxCount = 3}, + {id = 2188, chance = 600}, + {id = 2031, chance = 500}, + {id = 24839, chance = 300}, + {id = 24848, chance = 300}, + {id = 3955, chance = 100}, + {id = 3952, chance = 100, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -269, condition = {type = CONDITION_FIRE, totalDamage = 6, interval = 9000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -70, maxDamage = -180, range = 7, shootEffect = CONST_ANI_POISON, target = false}, + {name ="outfit", interval = 2000, chance = 8, range = 7, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 4000, outfitMonster = "chicken"}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -15, maxDamage = -120, length = 8, spread = 3, effect = CONST_ME_CARNIPHILA, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 80, maxDamage = 95, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/giants/orclops_doomhauler.lua b/data/monster/giants/orclops_doomhauler.lua new file mode 100644 index 00000000000..959f413bd45 --- /dev/null +++ b/data/monster/giants/orclops_doomhauler.lua @@ -0,0 +1,139 @@ +local mType = Game.createMonsterType("Orclops Doomhauler") +local monster = {} + +monster.description = "an orclops doomhauler" +monster.experience = 1200 +monster.outfit = { + lookType = 934, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1314 +monster.Bestiary = { + class = "Giant", + race = BESTY_RACE_GIANT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Desecrated Glade, Edron Orc Cave." + } + +monster.health = 1700 +monster.maxHealth = 1700 +monster.race = "blood" +monster.corpse = 27746 +monster.speed = 240 +monster.manaCost = 290 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Me mash!", yell = false}, + {text = "GRRRRR!", yell = false}, + {text = "Muhahaha!", yell = false}, + {text = "Me strong, you weak!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 50320, maxCount = 185}, + {id = 2788, chance = 50320, maxCount = 3}, + {id = 7588, chance = 50320}, + {id = 2194, chance = 20000}, + {id = 2428, chance = 50320}, + {id = 27048, chance = 20000}, + {id = 27049, chance = 4900}, + {id = 27050, chance = 1800, maxCount = 2}, + {id = 2144, chance = 12750, maxCount = 2}, + {id = 2147, chance = 2510, maxCount = 3}, + {id = 7452, chance = 1940}, + {id = 8843, chance = 1000, maxCount = 2}, + {id = 9970, chance = 8870, maxCount = 3}, + {id = 18417, chance = 9700}, + {id = 20108, chance = 15290, maxCount = 3}, + {id = 3953, chance = 910}, + {id = 7439, chance = 910}, + {id = 11374, chance = 910}, + {id = 26479, chance = 300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + {name ="combat", interval = 2000, chance = 35, type = COMBAT_PHYSICALDAMAGE, minDamage = -117, maxDamage = -220, range = 7, shootEffect = CONST_ANI_LARGEROCK, target = true}, + -- curse + {name ="condition", type = CONDITION_CURSED, interval = 2000, chance = 50, minDamage = -100, maxDamage = -200, radius = 4, shootEffect = CONST_ANI_WHIRLWINDCLUB, effect = CONST_ME_EXPLOSIONAREA, target = true} +} + +monster.defenses = { + defense = 25, + armor = 35, + {name ="speed", interval = 2000, chance = 10, speedChange = 336, effect = CONST_ME_MAGIC_RED, target = false, duration = 2000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 30}, + {type = COMBAT_FIREDAMAGE, percent = 15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/giants/orclops_ravager.lua b/data/monster/giants/orclops_ravager.lua new file mode 100644 index 00000000000..d7267fd250c --- /dev/null +++ b/data/monster/giants/orclops_ravager.lua @@ -0,0 +1,137 @@ +local mType = Game.createMonsterType("Orclops Ravager") +local monster = {} + +monster.description = "an orclops ravager" +monster.experience = 1100 +monster.outfit = { + lookType = 935, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1320 +monster.Bestiary = { + class = "Giant", + race = BESTY_RACE_GIANT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Desecrated Glade." + } + +monster.health = 1200 +monster.maxHealth = 1200 +monster.race = "blood" +monster.corpse = 27742 +monster.speed = 260 +monster.manaCost = 290 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "It's clobberin time!", yell = false}, + {text = "Crushing! Smashing! Ripping! Yeah!!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 50320, maxCount = 120}, + {id = 2152, chance = 50320}, + {id = 7588, chance = 50320}, + {id = 2194, chance = 50320}, + {id = 2428, chance = 20000}, + {id = 2788, chance = 50320, maxCount = 3}, + {id = 26479, chance = 6000}, + {id = 27048, chance = 4900}, + {id = 27049, chance = 1800}, + {id = 27050, chance = 12750}, + {id = 2144, chance = 2510, maxCount = 2}, + {id = 2147, chance = 1940, maxCount = 2}, + {id = 7452, chance = 1000}, + {id = 8843, chance = 8870}, + {id = 9970, chance = 9700}, + {id = 18417, chance = 15290, maxCount = 3}, + {id = 20108, chance = 910}, + {id = 3953, chance = 910}, + {id = 7439, chance = 910}, + {id = 7419, chance = 300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -240}, + {name ="combat", interval = 2000, chance = 35, type = COMBAT_PHYSICALDAMAGE, minDamage = -180, maxDamage = -220, range = 7, shootEffect = CONST_ANI_LARGEROCK, target = true} +} + +monster.defenses = { + defense = 25, + armor = 35, + {name ="speed", interval = 2000, chance = 10, speedChange = 336, effect = CONST_ME_MAGIC_RED, target = false, duration = 2000}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_HEALING, minDamage = 80, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/broken_shaper.lua b/data/monster/humanoids/broken_shaper.lua new file mode 100644 index 00000000000..0b648f85d74 --- /dev/null +++ b/data/monster/humanoids/broken_shaper.lua @@ -0,0 +1,140 @@ +local mType = Game.createMonsterType("Broken Shaper") +local monster = {} + +monster.description = "a broken shaper" +monster.experience = 1600 +monster.outfit = { + lookType = 932, + lookHead = 132, + lookBody = 95, + lookLegs = 0, + lookFeet = 121, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1321 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Astral Shaper Dungeon, Old Masonry." + } + +monster.health = 2200 +monster.maxHealth = 2200 +monster.race = "blood" +monster.corpse = 27736 +monster.speed = 310 +monster.manaCost = 290 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 98, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "", yell = false}, + {text = "Raar!!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100320, maxCount = 165}, + {id = 2152, chance = 70320, maxCount = 2}, + {id = 27051, chance = 20000, maxCount = 2}, + {id = 27052, chance = 17000}, + {id = 27053, chance = 20000}, + {id = 27054, chance = 13000}, + {id = 27058, chance = 4000}, + {id = 2260, chance = 15000}, + {id = 2666, chance = 50320, maxCount = 2}, + {id = 5022, chance = 5000, maxCount = 2}, + {id = 5912, chance = 1000, maxCount = 2}, + {id = 5913, chance = 5000, maxCount = 2}, + {id = 5914, chance = 2000, maxCount = 2}, + {id = 2195, chance = 230}, + {id = 7591, chance = 7000}, + {id = 2396, chance = 1000}, + {id = 2162, chance = 1000}, + {id = 24849, chance = 4200}, + {id = 2214, chance = 2000}, + {id = 2147, chance = 3000}, + {id = 2146, chance = 5000}, + {id = 2789, chance = 6500, maxCount = 5} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 2000, chance = 35, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -150, range = 7, shootEffect = CONST_ANI_SMALLSTONE, target = true}, + {name ="combat", interval = 2000, chance = 35, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -100, length = 5, spread = 3, effect = CONST_ME_SOUND_RED, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="speed", interval = 2000, chance = 10, speedChange = 336, effect = CONST_ME_MAGIC_RED, target = false, duration = 2000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 0, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -20}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = -15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/chakoya_toolshaper.lua b/data/monster/humanoids/chakoya_toolshaper.lua new file mode 100644 index 00000000000..feb3f254977 --- /dev/null +++ b/data/monster/humanoids/chakoya_toolshaper.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Chakoya Toolshaper") +local monster = {} + +monster.description = "a chakoya toolshaper" +monster.experience = 40 +monster.outfit = { + lookType = 259, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 328 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Inukaya, Chyllfroest, Chakoya Iceberg." + } + +monster.health = 80 +monster.maxHealth = 80 +monster.race = "blood" +monster.corpse = 7320 +monster.speed = 136 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Chikuva!", yell = false}, + {text = "Jinuma jamjam!", yell = false}, + {text = "Suvituka siq chuqua!", yell = false}, + {text = "Kiyosa sipaju!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 77810, maxCount = 20}, + {name = "mace", chance = 5300}, + {name = "bone shield", chance = 720}, + {id = 2553, chance = 1100}, + {id = 2667, chance = 25060, maxCount = 2}, + {name = "northern pike", chance = 70}, + {name = "rainbow trout", chance = 140}, + {name = "green perch", chance = 70}, + {name = "mammoth whopper", chance = 160}, + {id = 7441, chance = 450}, + {name = "fireproof horn", chance = 390} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -35}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -45, range = 7, radius = 3, shootEffect = CONST_ANI_SMALLSTONE, target = true} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -15}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 40}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/chakoya_tribewarden.lua b/data/monster/humanoids/chakoya_tribewarden.lua new file mode 100644 index 00000000000..84ad4160f63 --- /dev/null +++ b/data/monster/humanoids/chakoya_tribewarden.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Chakoya Tribewarden") +local monster = {} + +monster.description = "a chakoya tribewarden" +monster.experience = 40 +monster.outfit = { + lookType = 259, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 319 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Inukaya, Chyllfroest, Chakoya Iceberg, Nibelor (during a quest)." + } + +monster.health = 68 +monster.maxHealth = 68 +monster.race = "blood" +monster.corpse = 7320 +monster.speed = 124 +monster.manaCost = 305 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Quisavu tukavi!", yell = false}, + {text = "Si siyoqua jamjam!", yell = false}, + {text = "Achuq! jinuma!", yell = false}, + {text = "Si ji jusipa!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 79590, maxCount = 20}, + {name = "short sword", chance = 4810}, + {name = "bone shield", chance = 1030}, + {id = 2667, chance = 19370}, + {name = "northern pike", chance = 60}, + {name = "rainbow trout", chance = 50}, + {name = "green perch", chance = 100}, + {name = "mammoth whopper", chance = 130}, + {name = "fireproof horn", chance = 350} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -30} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -15}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 25}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/chakoya_windcaller.lua b/data/monster/humanoids/chakoya_windcaller.lua new file mode 100644 index 00000000000..2ee6afaeb70 --- /dev/null +++ b/data/monster/humanoids/chakoya_windcaller.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Chakoya Windcaller") +local monster = {} + +monster.description = "a chakoya windcaller" +monster.experience = 48 +monster.outfit = { + lookType = 260, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 329 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Inukaya, Chyllfroest, Chakoya Iceberg." + } + +monster.health = 84 +monster.maxHealth = 84 +monster.race = "blood" +monster.corpse = 7320 +monster.speed = 142 +monster.manaCost = 305 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Mupi! Si siyoqua jinuma!", yell = false}, + {text = "Siqsiq ji jusipa!", yell = false}, + {text = "Jagura taluka taqua!", yell = false}, + {text = "Quatu nguraka!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 71170, maxCount = 27}, + {name = "brass helmet", chance = 4390}, + {name = "bone shield", chance = 960}, + {id = 2667, chance = 30790, maxCount = 3}, + {name = "northern pike", chance = 40}, + {name = "rainbow trout", chance = 40}, + {name = "green perch", chance = 110}, + {name = "fireproof horn", chance = 410} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -22}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -16, maxDamage = -32, range = 7, shootEffect = CONST_ANI_ICE, target = false}, + -- freeze + {name ="condition", type = CONDITION_FREEZING, interval = 2000, chance = 10, minDamage = -130, maxDamage = -160, radius = 3, effect = CONST_ME_ICEAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -9, maxDamage = -30, length = 5, spread = 2, effect = CONST_ME_ICEAREA, target = false} +} + +monster.defenses = { + defense = 10, + armor = 10, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -15}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/corym_charlatan.lua b/data/monster/humanoids/corym_charlatan.lua new file mode 100644 index 00000000000..2df11f4c986 --- /dev/null +++ b/data/monster/humanoids/corym_charlatan.lua @@ -0,0 +1,127 @@ +local mType = Game.createMonsterType("Corym Charlatan") +local monster = {} + +monster.description = "a corym charlatan" +monster.experience = 150 +monster.outfit = { + lookType = 532, + lookHead = 0, + lookBody = 97, + lookLegs = 116, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 916 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Venore Corym Cave, Tiquanda Corym Cave, Corym Black Market, \z + Carlin Corym Cave/Dwarf Mines Diggers Depths Mine, Upper Spike." + } + +monster.health = 250 +monster.maxHealth = 250 +monster.race = "blood" +monster.corpse = 19725 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Mehehe!", yell = false}, + {text = "Beware! Me hexing you!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 35}, + {id = 2696, chance = 10000}, + {name = "bola", chance = 7692}, + {name = "spike shield", chance = 492}, + {name = "ratana", chance = 909}, + {name = "life preserver", chance = 854}, + {name = "cheese cutter", chance = 5882}, + {name = "cheesy figurine", chance = 518}, + {name = "earflap", chance = 7142}, + {name = "soft cheese", chance = 12500}, + {name = "rat cheese", chance = 14285}, + {name = "leather harness", chance = 537} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -105} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 25}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -20}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/corym_skirmisher.lua b/data/monster/humanoids/corym_skirmisher.lua new file mode 100644 index 00000000000..1656f566439 --- /dev/null +++ b/data/monster/humanoids/corym_skirmisher.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Corym Skirmisher") +local monster = {} + +monster.description = "a corym skirmisher" +monster.experience = 260 +monster.outfit = { + lookType = 533, + lookHead = 0, + lookBody = 0, + lookLegs = 101, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 917 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Venore Corym Cave, Tiquanda Corym Cave, Corym Black Market, \z + Carlin Corym Cave/Dwarf Mines Diggers Depths Mine, Upper Spike." + } + +monster.health = 450 +monster.maxHealth = 450 +monster.race = "blood" +monster.corpse = 19726 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Squeak! Squeak!", yell = false}, + {text = " ", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 45}, + {id = 2696, chance = 20000}, + {name = "bola", chance = 7692}, + {name = "spike shield", chance = 645}, + {name = "ratana", chance = 2702}, + {name = "life preserver", chance = 2941}, + {name = "cheese cutter", chance = 8333}, + {name = "cheesy figurine", chance = 854}, + {name = "earflap", chance = 9090}, + {name = "soft cheese", chance = 14285}, + {name = "rat cheese", chance = 16666}, + {name = "rat god doll", chance = 12}, + {name = "leather harness", chance = 561} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -110}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -90, range = 7, shootEffect = CONST_ANI_WHIRLWINDCLUB, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -20}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/corym_vanguard.lua b/data/monster/humanoids/corym_vanguard.lua new file mode 100644 index 00000000000..3270b99a3be --- /dev/null +++ b/data/monster/humanoids/corym_vanguard.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Corym Vanguard") +local monster = {} + +monster.description = "a corym vanguard" +monster.experience = 490 +monster.outfit = { + lookType = 534, + lookHead = 101, + lookBody = 0, + lookLegs = 101, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 918 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Venore Corym Cave, Tiquanda Corym Cave, Corym Black Market, \z + Carlin Corym Cave/Dwarf Mines Diggers Depths Mine, Upper Spike." + } + +monster.health = 700 +monster.maxHealth = 700 +monster.race = "blood" +monster.corpse = 19734 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 50, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Gimme! Gimme!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 120}, + {id = 2696, chance = 20000}, + {name = "bola", chance = 10000}, + {name = "spike shield", chance = 4761}, + {name = "ratana", chance = 5000}, + {name = "life preserver", chance = 5000}, + {name = "cheese cutter", chance = 16666}, + {name = "cheesy figurine", chance = 3846}, + {name = "earflap", chance = 11111}, + {name = "soft cheese", chance = 14285}, + {name = "rat cheese", chance = 14285}, + {name = "rat god doll", chance = 14}, + {name = "leather harness", chance = 1612}, + {name = "spiky club", chance = 3225} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -140}, + {name ="corym vanguard wave", interval = 2000, chance = 10, minDamage = -50, maxDamage = -100, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -40, maxDamage = -70, radius = 4, effect = CONST_ME_MORTAREA, target = true} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 30, maxDamage = 60, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/crazed_summer_rearguard.lua b/data/monster/humanoids/crazed_summer_rearguard.lua new file mode 100644 index 00000000000..8bcd7502841 --- /dev/null +++ b/data/monster/humanoids/crazed_summer_rearguard.lua @@ -0,0 +1,139 @@ +local mType = Game.createMonsterType("Crazed Summer Rearguard") +local monster = {} + +monster.description = "a Crazed Summer Rearguard" +monster.experience = 4700 +monster.outfit = { + lookType = 1136, + lookHead = 1, + lookBody = 94, + lookLegs = 20, + lookFeet = 119, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1733 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 5, + Occurrence = 0, + Locations = "Court of Winter, Dream Labyrinth." + } + +monster.health = 5300 +monster.maxHealth = 5300 +monster.race = "blood" +monster.corpse = 34719 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Is this real life?", yell = false}, + {text = "Weeeuuu weeeuuu!!!", yell = false} +} + +monster.loot = { + {name = "power bolt", chance = 1000000}, + {name = "small enchanted sapphire", chance = 1000000, maxCount = 2}, + {name = "platinum coin", chance = 1000000, maxCount = 5}, + {id = 5921, chance = 1500}, + {name = "dream essence egg", chance = 1155}, + {name = "elvish talisman", chance = 1355}, + {name = "violet crystal shard", chance = 1475}, + {name = "small enchanted ruby", chance = 1755}, + {name = "red crystal fragment", chance = 1565}, + {name = "leaf star", chance = 11100, maxCount = 8}, + {id = 26185, chance = 1000}, + {name = "sun fruit", chance = 25800}, + {id = 26198, chance = 1590},-- collar of blue plasma + {name = "wood cape", chance = 30000}, + {name = "small diamond", chance = 800}, + {name = "yellow gem", chance = 640}, + {name = "crystal crossbow", chance = 600} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -210, maxDamage = -530}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -270, maxDamage = -710, length = 3, spread = 0, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -250, maxDamage = -300, range = 7, shootEffect = CONST_ANI_FIRE, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -350, maxDamage = -380, radius = 5, effect = CONST_ME_EXPLOSIONHIT, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -350, radius = 5, effect = CONST_ME_EXPLOSIONAREA, target = true} +} + +monster.defenses = { + defense = 20, + armor = 70 +} + +monster.reflects = { + {type = COMBAT_FIREDAMAGE, percent = 70} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/crazed_summer_vanguard.lua b/data/monster/humanoids/crazed_summer_vanguard.lua new file mode 100644 index 00000000000..2631205284f --- /dev/null +++ b/data/monster/humanoids/crazed_summer_vanguard.lua @@ -0,0 +1,137 @@ +local mType = Game.createMonsterType("Crazed Summer Vanguard") +local monster = {} + +monster.description = "a Crazed Summer Vanguard" +monster.experience = 5000 +monster.outfit = { + lookType = 1136, + lookHead = 20, + lookBody = 94, + lookLegs = 20, + lookFeet = 81, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 1732 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Court of Winter, Dream Labyrinth." + } + +monster.health = 5500 +monster.maxHealth = 5500 +monster.race = "blood" +monster.corpse = 34715 +monster.speed = 390 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I see colours, all colours! Or are these just illusions?", yell = false}, + {text = "La di da di doo!!", yell = false} +} + +monster.loot = { + {name = "platinum coin", chance = 1000000, maxCount = 13}, + {name = "elven astral observer", chance = 1000000, maxCount = 2}, + {name = "dream essence egg", chance = 15000}, + {name = "belted cape", chance = 11550}, + {name = "two handed sword", chance = 13550}, + {name = "seeds", chance = 14750}, + {id = 2419, chance = 17550}, + {name = "knife", chance = 15650}, + {name = "dragon necklace", chance = 14550}, + {name = "magma amulet", chance = 1655}, + {name = "wand of dragonbreath", chance = 15150}, + {name = "wand of draconia", chance = 1263}, + {name = "magma boots", chance = 11100}, + {name = "sun fruit", chance = 1800}, + {name = "bullseye potion", chance = 800} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -160, maxDamage = -530}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -270, maxDamage = -710, length = 3, spread = 0, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -250, maxDamage = -300, range = 7, shootEffect = CONST_ANI_FIRE, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -350, maxDamage = -380, radius = 5, effect = CONST_ME_EXPLOSIONHIT, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -350, radius = 5, effect = CONST_ME_EXPLOSIONAREA, target = true} +} + +monster.defenses = { + defense = 20, + armor = 70 +} + +monster.reflects = { + {type = COMBAT_FIREDAMAGE, percent = 70} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/crazed_winter_rearguard.lua b/data/monster/humanoids/crazed_winter_rearguard.lua new file mode 100644 index 00000000000..8b1737d48a0 --- /dev/null +++ b/data/monster/humanoids/crazed_winter_rearguard.lua @@ -0,0 +1,138 @@ +local mType = Game.createMonsterType("Crazed Winter Rearguard") +local monster = {} + +monster.description = "a Crazed Winter Rearguard" +monster.experience = 4700 +monster.outfit = { + lookType = 1136, + lookHead = 86, + lookBody = 85, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1731 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Court of Winter, Dream Labyrinth." + } + +monster.health = 5200 +monster.maxHealth = 5200 +monster.race = "blood" +monster.corpse = 34764 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 5}, + {name = "red crystal fragment", chance = 1000000}, + {name = "red gem", chance = 1000000}, + {name = "ice rapier", chance = 15000}, + {name = "ultimate health potion", chance = 21550}, + {name = "great spirit potion", chance = 23550}, + {id = 34696, chance = 14750, maxCount = 2}, + {name = "life crystal", chance = 17550}, + {name = "dream essence egg", chance = 6350}, + {name = "elven astral observer", chance = 14600}, + {name = "glacier mask", chance = 6850}, + {name = "moonlight rod", chance = 11250}, + {name = "small enchanted sapphire", chance = 6850, maxCount = 7}, + {name = "northwind rod", chance = 1000}, + {name = "glacier amulet", chance = 500}, + {name = "hailstorm rod", chance = 1000}, + {name = "glacier robe", chance = 500}, + {name = "cyan crystal fragment", chance = 500}, + {name = "elven amulet", chance = 500}, + {name = "blue gem", chance = 1800} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -110, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -200, maxDamage = -300, radius = 3, effect = CONST_ME_ICEAREA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -250, maxDamage = -300, range = 7, shootEffect = CONST_ANI_ICE, target = false} +} + +monster.defenses = { + defense = 20, + armor = 70 +} + +monster.reflects = { + {type = COMBAT_ICEDAMAGE, percent = 70} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/crazed_winter_vanguard.lua b/data/monster/humanoids/crazed_winter_vanguard.lua new file mode 100644 index 00000000000..190d33ad2af --- /dev/null +++ b/data/monster/humanoids/crazed_winter_vanguard.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Crazed Winter Vanguard") +local monster = {} + +monster.description = "a Crazed Winter Vanguard" +monster.experience = 5400 +monster.outfit = { + lookType = 1136, + lookHead = 0, + lookBody = 123, + lookLegs = 28, + lookFeet = 20, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 1730 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Court of Winter, Dream Labyrinth." + } + +monster.health = 5800 +monster.maxHealth = 5800 +monster.race = "blood" +monster.corpse = 34760 +monster.speed = 380 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 13}, + {name = "red crystal fragment", chance = 1000000}, + {name = "red gem", chance = 1000000}, + {id = 34696, chance = 15000, maxCount = 2}, + {name = "small enchanted ruby", chance = 1155}, + {name = "miraculum", chance = 13550}, + {name = "ultimate health potion", chance = 14750, maxCount = 2}, + {name = "dream essence egg", chance = 17550}, + {name = "tiger eye", chance = 12350}, + {name = "northwind rod", chance = 1460}, + {name = "glacier amulet", chance = 1850}, + {name = "ice rapier", chance = 11250}, + {name = "glacier robe", chance = 800}, + {name = "elven amulet", chance = 500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -150, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -200, maxDamage = -300, radius = 5, effect = CONST_ME_ICEAREA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -240, maxDamage = -300, length = 4, spread = 3, effect = CONST_ME_GIANTICE, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ICEDAMAGE, minDamage = -250, maxDamage = -300, range = 7, shootEffect = CONST_ANI_ICE, target = false} +} + +monster.defenses = { + defense = 20, + armor = 70 +} + +monster.reflects = { + {type = COMBAT_ICEDAMAGE, percent = 70} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/dwarf.lua b/data/monster/humanoids/dwarf.lua new file mode 100644 index 00000000000..20b37df0f8d --- /dev/null +++ b/data/monster/humanoids/dwarf.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Dwarf") +local monster = {} + +monster.description = "a dwarf" +monster.experience = 45 +monster.outfit = { + lookType = 69, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 69 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Kazordoon Dwarf Mines, Dwarf Bridge, deep Elvenbane, Tiquanda Dwarf Cave, Cormaya Dwarf Cave, \z + Island of Destiny (Knights area), Beregar." + } + +monster.health = 90 +monster.maxHealth = 90 +monster.race = "blood" +monster.corpse = 6007 +monster.speed = 170 +monster.manaCost = 320 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hail Durin!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 35000, maxCount = 8}, + {name = "dwarven ring", chance = 100}, + {name = "axe", chance = 15000}, + {name = "hatchet", chance = 25000}, + {name = "studded armor", chance = 8000}, + {name = "copper shield", chance = 10000}, + {id = 2553, chance = 10000}, + {name = "letter", chance = 8000}, + {name = "leather legs", chance = 10000}, + {name = "white mushroom", chance = 50000}, + {name = "iron ore", chance = 700} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -30} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/dwarf_geomancer.lua b/data/monster/humanoids/dwarf_geomancer.lua new file mode 100644 index 00000000000..e6745a5dc6b --- /dev/null +++ b/data/monster/humanoids/dwarf_geomancer.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Dwarf Geomancer") +local monster = {} + +monster.description = "a dwarf geomancer" +monster.experience = 265 +monster.outfit = { + lookType = 66, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 66 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Mount Sternum Undead Cave, Dwarf Mines, Circle Room in Kazordoon, Triangle Tower, \z + Tiquanda Dwarf Cave, Cormaya Dwarven Cave, Beregar Mines." + } + +monster.health = 380 +monster.maxHealth = 380 +monster.race = "blood" +monster.corpse = 6015 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 4, + runHealth = 110, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hail Durin!", yell = false}, + {text = "Earth is the strongest element.", yell = false}, + {text = "Dust to dust.", yell = false} +} + +monster.loot = { + {name = "small sapphire", chance = 710}, + {name = "gold coin", chance = 50000, maxCount = 35}, + {id = 2162, chance = 14000}, + {id = 2175, chance = 360}, + {name = "dwarven ring", chance = 530}, + {name = "blank rune", chance = 33000}, + {name = "clerical mace", chance = 1120}, + {name = "pear", chance = 25000}, + {name = "white mushroom", chance = 60000, maxCount = 2}, + {name = "iron ore", chance = 120}, + {name = "terra boots", chance = 470}, + {name = "geomancer's robe", chance = 8000}, + {name = "geomancer's staff", chance = 7000} +} + +monster.attacks = { + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -50, maxDamage = -110, range = 7, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -50, maxDamage = -80, range = 7, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_HEALING, minDamage = 75, maxDamage = 125, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 60}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -1} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/dwarf_guard.lua b/data/monster/humanoids/dwarf_guard.lua new file mode 100644 index 00000000000..84ea42e84be --- /dev/null +++ b/data/monster/humanoids/dwarf_guard.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Dwarf Guard") +local monster = {} + +monster.description = "a dwarf guard" +monster.experience = 165 +monster.outfit = { + lookType = 70, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 70 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Kazordoon Dwarf Mines, Dwacatra, Ferngrims Gate, Cyclopolis, Mount Sternum Undead Cave, \z + Stonehome Rotworm cave (near Edron), Maze of Lost Souls, Tiquanda Dwarf Cave, Beregar, Cormaya Dwarf Cave." + } + +monster.health = 245 +monster.maxHealth = 245 +monster.race = "blood" +monster.corpse = 6013 +monster.speed = 206 +monster.manaCost = 650 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 20, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hail Durin!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 40000, maxCount = 30}, + {name = "small amethyst", chance = 140}, + {name = "axe ring", chance = 190}, + {name = "double axe", chance = 600}, + {name = "battle hammer", chance = 4000}, + {name = "steel helmet", chance = 1600}, + {name = "scale armor", chance = 9200}, + {name = "battle shield", chance = 6000}, + {name = "leather boots", chance = 40000}, + {name = "white mushroom", chance = 55000, maxCount = 2}, + {name = "iron ore", chance = 510}, + {name = "health potion", chance = 380}, + {id = 13757, chance = 280} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -140} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/dwarf_miner.lua b/data/monster/humanoids/dwarf_miner.lua new file mode 100644 index 00000000000..10fede86f00 --- /dev/null +++ b/data/monster/humanoids/dwarf_miner.lua @@ -0,0 +1,110 @@ +local mType = Game.createMonsterType("Dwarf Miner") +local monster = {} + +monster.description = "a dwarf miner" +monster.experience = 60 +monster.outfit = { + lookType = 160, + lookHead = 77, + lookBody = 101, + lookLegs = 97, + lookFeet = 115, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 120 +monster.maxHealth = 120 +monster.race = "blood" +monster.corpse = 6007 +monster.speed = 170 +monster.manaCost = 420 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Work, work!", yell = false}, + {text = "Intruders in the mines!", yell = false}, + {text = "Mine, all mine!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 33333, maxCount = 10}, + {name = "dwarven ring", chance = 793}, + {name = "axe", chance = 14285}, + {name = "studded armor", chance = 6666}, + {id = 2553, chance = 11111}, + {name = "leather legs", chance = 9090}, + {name = "meat", chance = 3846}, + {name = "iron ore", chance = 793} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -26} +} + +monster.defenses = { + defense = 10, + armor = 7 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/dwarf_soldier.lua b/data/monster/humanoids/dwarf_soldier.lua new file mode 100644 index 00000000000..1f69a016a1a --- /dev/null +++ b/data/monster/humanoids/dwarf_soldier.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Dwarf Soldier") +local monster = {} + +monster.description = "a dwarf soldier" +monster.experience = 70 +monster.outfit = { + lookType = 71, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 71 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Kazordoon Dwarf Mines, Cyclopolis, Dwacatra, Ferngrims Gate, Dwarf Bridge, \z + Mount Sternum Undead Cave, Beregar, Tiquanda Dwarf Cave, Cormaya Dwarf Cave." + } + +monster.health = 135 +monster.maxHealth = 135 +monster.race = "blood" +monster.corpse = 6014 +monster.speed = 176 +monster.manaCost = 360 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hail Durin!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 28000, maxCount = 12}, + {name = "axe ring", chance = 120}, + {name = "battle axe", chance = 2500}, + {name = "crossbow", chance = 3000}, + {name = "chain armor", chance = 8000}, + {name = "soldier helmet", chance = 12000}, + {name = "dwarven shield", chance = 3000}, + {name = "bolt", chance = 40000, maxCount = 7}, + {id = 2554, chance = 10000}, + {name = "white mushroom", chance = 40000, maxCount = 3}, + {name = "iron ore", chance = 300}, + {name = "piercing bolt", chance = 4000, maxCount = 3} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -70}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -60, range = 7, shootEffect = CONST_ANI_BOLT, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/dworc_fleshhunter.lua b/data/monster/humanoids/dworc_fleshhunter.lua new file mode 100644 index 00000000000..605527c4b2f --- /dev/null +++ b/data/monster/humanoids/dworc_fleshhunter.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Dworc Fleshhunter") +local monster = {} + +monster.description = "a dworc fleshhunter" +monster.experience = 40 +monster.outfit = { + lookType = 215, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 215 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "South of Port Hope (Trapwood) on ground level and underground." + } + +monster.health = 85 +monster.maxHealth = 85 +monster.race = "blood" +monster.corpse = 6058 +monster.speed = 148 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 8, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Brak brrretz!", yell = false}, + {text = "Grow truk grrrrr.", yell = false}, + {text = "Prek tars, dekklep zurk.", yell = false} +} + +monster.loot = { + {id = 2050, chance = 4750}, + {name = "gold coin", chance = 69000, maxCount = 13}, + {id = 2229, chance = 3300, maxCount = 3}, + {name = "poison dagger", chance = 2250}, + {name = "bone shield", chance = 1000}, + {name = "cleaver", chance = 9750}, + {name = "ripper lance", chance = 90}, + {name = "hunting spear", chance = 2000}, + {name = "tribal mask", chance = 500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -25, condition = {type = CONDITION_POISON, totalDamage = 20, interval = 4000}}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -15, range = 7, shootEffect = CONST_ANI_THROWINGKNIFE, target = false} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -15} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/dworc_venomsniper.lua b/data/monster/humanoids/dworc_venomsniper.lua new file mode 100644 index 00000000000..8ee5f7cb18b --- /dev/null +++ b/data/monster/humanoids/dworc_venomsniper.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Dworc Venomsniper") +local monster = {} + +monster.description = "a dworc venomsniper" +monster.experience = 35 +monster.outfit = { + lookType = 216, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 216 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "South of Port Hope (Trapwood) on ground level and underground and on Foreigner Quarter of Yalahar." + } + +monster.health = 80 +monster.maxHealth = 80 +monster.race = "blood" +monster.corpse = 6059 +monster.speed = 152 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Brak brrretz!", yell = false}, + {text = "Grow truk grrrrr.", yell = false}, + {text = "Prek tars, dekklep zurk.", yell = false} +} + +monster.loot = { + {id = 2050, chance = 6000}, + {name = "gold coin", chance = 75000, maxCount = 13}, + {name = "bronze amulet", chance = 110}, + {id = 2229, chance = 1000, maxCount = 2}, + {name = "poison dagger", chance = 1500}, + {name = "leather armor", chance = 10000}, + {name = "poison arrow", chance = 5000, maxCount = 3}, + {name = "tribal mask", chance = 510}, + {name = "bast skirt", chance = 100}, + {name = "seeds", chance = 200} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -15}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -20, maxDamage = -40, range = 5, shootEffect = CONST_ANI_POISON, target = false} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -13}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/dworc_voodoomaster.lua b/data/monster/humanoids/dworc_voodoomaster.lua new file mode 100644 index 00000000000..62873c54196 --- /dev/null +++ b/data/monster/humanoids/dworc_voodoomaster.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Dworc Voodoomaster") +local monster = {} + +monster.description = "a dworc voodoomaster" +monster.experience = 55 +monster.outfit = { + lookType = 214, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 214 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "South of Port Hope around Trapwood. There is also a group of 3 voodoomasters \z + and 2 crypt shamblers on the shore east of Trapwood." + } + +monster.health = 80 +monster.maxHealth = 80 +monster.race = "blood" +monster.corpse = 6055 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 4, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Brak brrretz!", yell = false}, + {text = "Grow truk grrrrr.", yell = false}, + {text = "Prek tars, dekklep zurk.", yell = false} +} + +monster.loot = { + {id = 2050, chance = 6000}, + {name = "gold coin", chance = 75000, maxCount = 17}, + {name = "strange symbol", chance = 500}, + {id = 2229, chance = 1950, maxCount = 3}, + {id = 2230, chance = 5800}, + {id = 2231, chance = 3000}, + {name = "poison dagger", chance = 1000}, + {name = "leather armor", chance = 10000}, + {id = 3955, chance = 130}, + {name = "tribal mask", chance = 500}, + {name = "health potion", chance = 600} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -20}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -40, range = 1, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = -800, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000}, + {name ="drunk", interval = 2000, chance = 10, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_TELEPORT, target = false}, + {name ="outfit", interval = 2000, chance = 10, range = 7, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 5000, outfitMonster = "chicken"}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -6, maxDamage = -18, radius = 6, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="poisonfield", interval = 2000, chance = 10, range = 7, radius = 1, shootEffect = CONST_ANI_POISON, target = true} +} + +monster.defenses = { + defense = 10, + armor = 10, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 3, maxDamage = 9, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 200, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000}, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/elf.lua b/data/monster/humanoids/elf.lua new file mode 100644 index 00000000000..0c77443c306 --- /dev/null +++ b/data/monster/humanoids/elf.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Elf") +local monster = {} + +monster.description = "an elf" +monster.experience = 42 +monster.outfit = { + lookType = 62, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 62 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Yalahar Foreigner Quarter and Trade Quarter, Maze of Lost Souls, Orc Fort (unreachable), \z + Hellgate, Shadowthorn, Ab'Dendriel elf caves, Elvenbane, north of Thais." + } + +monster.health = 100 +monster.maxHealth = 100 +monster.race = "blood" +monster.corpse = 6003 +monster.speed = 190 +monster.manaCost = 320 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ulathil beia Thratha!", yell = false}, + {text = "Bahaha aka!", yell = false}, + {text = "You are not welcome here.", yell = false}, + {text = "Flee as long as you can.", yell = false}, + {text = "Death to the Defilers!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 44000, maxCount = 30}, + {name = "longsword", chance = 10800}, + {name = "studded helmet", chance = 13500}, + {name = "studded armor", chance = 8960}, + {name = "plate shield", chance = 9300}, + {name = "arrow", chance = 7060, maxCount = 3}, + {name = "leather boots", chance = 11410}, + {id = 5921, chance = 940}, + {name = "plum", chance = 20000, maxCount = 2}, + {name = "elvish talisman", chance = 2100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -15}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -25, range = 7, shootEffect = CONST_ANI_ARROW, target = false} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -1} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/elf_arcanist.lua b/data/monster/humanoids/elf_arcanist.lua new file mode 100644 index 00000000000..8e1c6042683 --- /dev/null +++ b/data/monster/humanoids/elf_arcanist.lua @@ -0,0 +1,140 @@ +local mType = Game.createMonsterType("Elf Arcanist") +local monster = {} + +monster.description = "an elf arcanist" +monster.experience = 175 +monster.outfit = { + lookType = 63, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 63 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Yalahar Foreigner Quarter, Demona, Shadowthorn, northwest of Ab'Dendriel, Maze of Lost Souls, \z + Cyclopolis, Elvenbane, near Mount Sternum." + } + +monster.health = 220 +monster.maxHealth = 220 +monster.race = "blood" +monster.corpse = 6011 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Feel my wrath!", yell = false}, + {text = "For the Daughter of the Stars!", yell = false}, + {text = "I'll bring balance upon you!", yell = false}, + {text = "Tha'shi Cenath", yell = false}, + {text = "Vihil Ealuel", yell = false} +} + +monster.loot = { + {id = 1949, chance = 31000}, + {name = "candlestick", chance = 2100}, + {name = "gold coin", chance = 37000, maxCount = 47}, + {name = "yellow gem", chance = 50}, + {name = "life crystal", chance = 970}, + {name = "wand of cosmic energy", chance = 1160}, + {name = "elven amulet", chance = 1999}, + {name = "blank rune", chance = 18000}, + {name = "arrow", chance = 6000, maxCount = 3}, + {id = 2600, chance = 1000}, + {name = "sandals", chance = 950}, + {name = "green tunic", chance = 7000}, + {name = "melon", chance = 22000}, + {name = "bread", chance = 14000}, + {name = "grave flower", chance = 880}, + {name = "sling herb", chance = 5000}, + {name = "holy orchid", chance = 2100}, + {name = "strong mana potion", chance = 3000}, + {name = "health potion", chance = 4000}, + {name = "elvish talisman", chance = 10000}, + {name = "elven astral observer", chance = 7710} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -35}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -70, range = 7, shootEffect = CONST_ANI_ARROW, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -30, maxDamage = -50, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -70, maxDamage = -85, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 40, maxDamage = 60, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/elf_scout.lua b/data/monster/humanoids/elf_scout.lua new file mode 100644 index 00000000000..9a6465c14bf --- /dev/null +++ b/data/monster/humanoids/elf_scout.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Elf Scout") +local monster = {} + +monster.description = "an elf scout" +monster.experience = 75 +monster.outfit = { + lookType = 64, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 64 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Yalahar Foreigner Quarter, Shadowthorn, northwest of Ab'Dendriel, north and west of Mount Sternum, \z + Hellgate, Maze of Lost Souls, near Knightwatch Tower in the Plains of Havoc. \z + Two may also spawn when a Desperate White Deer or an Enraged White Deer is killed." + } + +monster.health = 160 +monster.maxHealth = 160 +monster.race = "blood" +monster.corpse = 6012 +monster.speed = 220 +monster.manaCost = 360 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Tha'shi Ab'Dendriel!", yell = false}, + {text = "Feel the sting of my arrows!", yell = false}, + {text = "Thy blood will quench the soil's thirst!", yell = false}, + {text = "Evicor guide my arrow!", yell = false}, + {text = "Your existence will end here!", yell = false} +} + +monster.loot = { + {name = "waterskin", chance = 1350}, + {name = "gold coin", chance = 75000, maxCount = 25}, + {name = "bow", chance = 4000}, + {name = "arrow", chance = 30710, maxCount = 12}, + {name = "poison arrow", chance = 15400, maxCount = 4}, + {name = "sandals", chance = 1180}, + {name = "grapes", chance = 17750}, + {id = 5921, chance = 1130}, + {name = "elvish bow", chance = 140}, + {name = "elvish talisman", chance = 5200}, + {name = "elven scouting glass", chance = 9750} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -30}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -80, range = 7, shootEffect = CONST_ANI_ARROW, target = false} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -1} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/enslaved_dwarf.lua b/data/monster/humanoids/enslaved_dwarf.lua new file mode 100644 index 00000000000..74b70c0a636 --- /dev/null +++ b/data/monster/humanoids/enslaved_dwarf.lua @@ -0,0 +1,146 @@ +local mType = Game.createMonsterType("Enslaved Dwarf") +local monster = {} + +monster.description = "an enslaved dwarf" +monster.experience = 2700 +monster.outfit = { + lookType = 494, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 886 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Caves of the Lost and Lower Spike." + } + +monster.health = 3800 +monster.maxHealth = 3800 +monster.race = "blood" +monster.corpse = 17408 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Bark!", yell = false}, + {text = "Blood!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 99}, + {name = "gold coin", chance = 50000, maxCount = 50}, + {name = "small emerald", chance = 10290, maxCount = 2}, + {name = "small amethyst", chance = 10680, maxCount = 2}, + {name = "platinum coin", chance = 100000, maxCount = 6}, + {name = "axe ring", chance = 1550}, + {name = "war hammer", chance = 5050}, + {name = "warrior helmet", chance = 580}, + {name = "guardian shield", chance = 2300}, + {name = "tower shield", chance = 190}, + {name = "ancient shield", chance = 3690}, + {name = "brown mushroom", chance = 15150, maxCount = 2}, + {name = "iron ore", chance = 11070}, + {name = "titan axe", chance = 1170}, + {name = "sapphire hammer", chance = 80}, + {name = "spiked squelcher", chance = 80}, + {name = "glorious axe", chance = 1940}, + {name = "great mana potion", chance = 6660, maxCount = 2}, + {name = "great health potion", chance = 7960}, + {name = "shiny stone", chance = 4660}, + {id = 13757, chance = 780}, + {name = "green crystal shard", chance = 1750}, + {name = "green crystal splinter", chance = 3110}, + {name = "brown crystal splinter", chance = 5630, maxCount = 2}, + {name = "red crystal fragment", chance = 3690}, + {name = "drill bolt", chance = 3690, maxCount = 5} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -501}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -340, range = 7, shootEffect = CONST_ANI_LARGEROCK, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -250, range = 7, radius = 3, shootEffect = CONST_ANI_EXPLOSION, effect = CONST_ME_EXPLOSIONHIT, target = true}, + {name ="drunk", interval = 2000, chance = 20, radius = 5, effect = CONST_ME_BLOCKHIT, target = false, duration = 6000}, + {name ="enslaved dwarf skill reducer 1", interval = 2000, chance = 5, target = false}, + {name ="enslaved dwarf skill reducer 2", interval = 2000, chance = 5, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 396, maxDamage = 478, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 1}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 1} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/execowtioner.lua b/data/monster/humanoids/execowtioner.lua new file mode 100644 index 00000000000..471aa685e6f --- /dev/null +++ b/data/monster/humanoids/execowtioner.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Execowtioner") +local monster = {} + +monster.description = "an execowtioner" +monster.experience = 2400 +monster.outfit = { + lookType = 609, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1046 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Oramond Mountain Hideout, Oramond Minotaur Camp (northern camp), \z + Underground Glooth Factory, Oramond Dungeon." + } + +monster.health = 3500 +monster.maxHealth = 3500 +monster.race = "blood" +monster.corpse = 23375 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 4 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I'm the one who puts the cute into execute!", yell = false}, + {text = "I'm here to punish!", yell = false}, + {text = "Justice is swift and unavoidable!", yell = false}, + {text = "I'll bring justice!", yell = false}, + {text = "There is excellence in execution!", yell = false}, + {text = "Your sentence is death!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 198}, + {id = 2152, chance = 67610, maxCount = 3}, + {id = 9971, chance = 390}, + {id = 5911, chance = 3230}, + {id = 5878, chance = 14710}, + {id = 12428, chance = 6580, maxCount = 2}, + {id = 23572, chance = 13160}, + {id = 7591, chance = 11480}, + {id = 7590, chance = 10060}, + {id = 2666, chance = 7230}, + {id = 9970, chance = 5810, maxCount = 2}, + {id = 2147, chance = 4520, maxCount = 2}, + {id = 7412, chance = 900}, + {id = 2487, chance = 770}, + {id = 23547, chance = 1420}, + {id = 2430, chance = 770}, + {id = 7413, chance = 390}, + {id = 7401, chance = 520} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 80}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_LIFEDRAIN, minDamage = -135, maxDamage = -280, range = 7, radius = 5, shootEffect = CONST_ANI_WHIRLWINDAXE, target = true}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_PHYSICALDAMAGE, minDamage = -90, maxDamage = -200, range = 7, shootEffect = CONST_ANI_WHIRLWINDAXE, effect = CONST_ME_EXPLOSIONAREA, target = true} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 1}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/firestarter.lua b/data/monster/humanoids/firestarter.lua new file mode 100644 index 00000000000..5c704730cda --- /dev/null +++ b/data/monster/humanoids/firestarter.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Firestarter") +local monster = {} + +monster.description = "a firestarter" +monster.experience = 80 +monster.outfit = { + lookType = 159, + lookHead = 94, + lookBody = 77, + lookLegs = 78, + lookFeet = 79, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 737 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 2, + Locations = "Shadowthorn, during the Thornfire World Change." + } + +monster.health = 180 +monster.maxHealth = 180 +monster.race = "blood" +monster.corpse = 20599 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "FIRE!", yell = true}, + {text = "BURN!", yell = true}, + {text = "Hey, what's that burnt stench... isn't that... YOU?", yell = true}, + {text = "Set everything on fire!!", yell = true}, + {text = "DEATH to the FALSE GOD!!", yell = true}, + {text = "You shall burn in the thornfires!!", yell = false}, + {text = "DOWN with the followers of the bog!!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 79000, maxCount = 35}, + {name = "longsword", chance = 6000}, + {name = "bow", chance = 4000}, + {name = "grapes", chance = 20000}, + {id = 5921, chance = 930}, + {name = "elvish bow", chance = 100}, + {name = "flaming arrow", chance = 30000, maxCount = 12}, + {name = "elvish talisman", chance = 5000}, + {id = 13757, chance = 15280}, + {name = "flintstone", chance = 340} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -15}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = 0, maxDamage = -21, radius = 1, shootEffect = CONST_ANI_BURSTARROW, effect = CONST_ME_EXPLOSIONHIT, target = true}, + {name ="firefield", interval = 2000, chance = 10, radius = 1, shootEffect = CONST_ANI_FIRE, target = true} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -20} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/frost_troll.lua b/data/monster/humanoids/frost_troll.lua new file mode 100644 index 00000000000..475fc7d1229 --- /dev/null +++ b/data/monster/humanoids/frost_troll.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("Frost Troll") +local monster = {} + +monster.description = "a frost troll" +monster.experience = 23 +monster.outfit = { + lookType = 53, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 53 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Ice Islands, Svargrond and Edron." + } + +monster.health = 55 +monster.maxHealth = 55 +monster.race = "blood" +monster.corpse = 5998 +monster.speed = 140 +monster.manaCost = 300 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Brrr", yell = false}, + {text = "Broar!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50840, maxCount = 12}, + {name = "twigs", chance = 8300}, + {name = "rapier", chance = 15500}, + {name = "spear", chance = 21500}, + {id = 2512, chance = 15850}, + {name = "coat", chance = 1200}, + {id = 2667, chance = 18000}, + {name = "frosty ear of a troll", chance = 2000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -20} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -15} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/furious_orc_berserker.lua b/data/monster/humanoids/furious_orc_berserker.lua new file mode 100644 index 00000000000..09bd1539eea --- /dev/null +++ b/data/monster/humanoids/furious_orc_berserker.lua @@ -0,0 +1,96 @@ +local mType = Game.createMonsterType("Furious Orc Berserker") +local monster = {} + +monster.description = "a furious orc berserker" +monster.experience = 0 +monster.outfit = { + lookType = 8, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 210 +monster.maxHealth = 210 +monster.race = "blood" +monster.corpse = 5980 +monster.speed = 250 +monster.manaCost = 220 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "KRAK ORRRRRRK!", yell = false} +} + +monster.loot = {} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = 0} +} + +monster.defenses = { + defense = 2, + armor = 1 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = true} +} + +mType:register(monster) diff --git a/data/monster/humanoids/furious_troll.lua b/data/monster/humanoids/furious_troll.lua new file mode 100644 index 00000000000..68568585c39 --- /dev/null +++ b/data/monster/humanoids/furious_troll.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("Furious Troll") +local monster = {} + +monster.description = "a furious troll" +monster.experience = 185 +monster.outfit = { + lookType = 15, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 540 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 1, + Locations = "Old Beregar mines." + } + +monster.health = 245 +monster.maxHealth = 245 +monster.race = "blood" +monster.corpse = 5960 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Mechanical Fighter", chance = 90, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Slice! Slice!", yell = false}, + {text = "DIE!!!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 93000, maxCount = 146}, + {name = "platinum coin", chance = 6000}, + {name = "war hammer", chance = 750}, + {name = "bunch of troll hair", chance = 4400} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/glooth_powered_minotaur.lua b/data/monster/humanoids/glooth_powered_minotaur.lua new file mode 100644 index 00000000000..b595180ec2c --- /dev/null +++ b/data/monster/humanoids/glooth_powered_minotaur.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Glooth Powered Minotaur") +local monster = {} + +monster.description = "a glooth powered minotaur" +monster.experience = 2600 +monster.outfit = { + lookType = 607, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3200 +monster.maxHealth = 3200 +monster.race = "blood" +monster.corpse = 23367 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "POOOWEEER!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -290}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, radius = 3, effect = CONST_ME_HITAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -100, maxDamage = -225, range = 7, radius = 4, effect = CONST_ME_MAGIC_RED, target = true} +} + +monster.defenses = { + defense = 45, + armor = 40, + {name ="combat", interval = 4000, chance = 15, type = COMBAT_HEALING, minDamage = 50, maxDamage = 145, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 1}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 90}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/goblin.lua b/data/monster/humanoids/goblin.lua new file mode 100644 index 00000000000..9f3fd10ec71 --- /dev/null +++ b/data/monster/humanoids/goblin.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Goblin") +local monster = {} + +monster.description = "a goblin" +monster.experience = 25 +monster.outfit = { + lookType = 61, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 61 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Femor Hills, north east of Carlin, Edron Goblin Cave, Rookgaard (Premium Area), \z + Maze of Lost Souls and Fenrock." + } + +monster.health = 50 +monster.maxHealth = 50 +monster.race = "blood" +monster.corpse = 6002 +monster.speed = 120 +monster.manaCost = 290 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Me have him!", yell = false}, + {text = "Zig Zag! Gobo attack!", yell = false}, + {text = "Help! Goblinkiller!", yell = false}, + {text = "Bugga! Bugga!", yell = false}, + {text = "Me green, me mean!", yell = false} +} + +monster.loot = { + {name = "small stone", chance = 15290, maxCount = 3}, + {name = "gold coin", chance = 50320, maxCount = 9}, + {id = 2230, chance = 1130}, + {name = "mouldy cheese", chance = 1000}, + {name = "dagger", chance = 1800}, + {name = "short sword", chance = 8870}, + {name = "bone club", chance = 4900}, + {name = "leather helmet", chance = 1940}, + {name = "leather armor", chance = 2510}, + {name = "small axe", chance = 9700}, + {id = 2667, chance = 12750}, + {name = "goblin ear", chance = 910} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -10}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -25, range = 7, shootEffect = CONST_ANI_SMALLSTONE, target = false} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -12}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 1}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/goblin_assassin.lua b/data/monster/humanoids/goblin_assassin.lua new file mode 100644 index 00000000000..7ecdd898e49 --- /dev/null +++ b/data/monster/humanoids/goblin_assassin.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Goblin Assassin") +local monster = {} + +monster.description = "a goblin assassin" +monster.experience = 52 +monster.outfit = { + lookType = 296, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 463 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Femor Hills, Edron Goblin Cave and Fenrock." + } + +monster.health = 75 +monster.maxHealth = 75 +monster.race = "blood" +monster.corpse = 6002 +monster.speed = 140 +monster.manaCost = 360 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 10000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Goblin Powahhh!", yell = false}, + {text = "Me kill you!", yell = false}, + {text = "Me green menace!", yell = false}, + {text = "Gobabunga!", yell = false}, + {text = "Gooobliiiins!", yell = false} +} + +monster.loot = { + {name = "small stone", chance = 9900, maxCount = 3}, + {name = "gold coin", chance = 50000, maxCount = 9}, + {id = 2230, chance = 13000}, + {name = "mouldy cheese", chance = 6610}, + {name = "dagger", chance = 17000}, + {name = "short sword", chance = 8820}, + {name = "bone club", chance = 4770}, + {name = "leather helmet", chance = 13000}, + {name = "leather armor", chance = 7240}, + {name = "small axe", chance = 9800}, + {id = 2667, chance = 12400} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -15}, + {name ="drunk", interval = 2000, chance = 10, shootEffect = CONST_ANI_POISON, target = false, duration = 10000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -35, range = 6, shootEffect = CONST_ANI_THROWINGKNIFE, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_MAGIC_BLUE}, + {name ="speed", interval = 2000, chance = 15, speedChange = 100, effect = CONST_ME_MAGIC_RED, target = false, duration = 3000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 1}, + {type = COMBAT_DEATHDAMAGE , percent = -1} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/goblin_leader.lua b/data/monster/humanoids/goblin_leader.lua new file mode 100644 index 00000000000..bb0b42ccecb --- /dev/null +++ b/data/monster/humanoids/goblin_leader.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Goblin Leader") +local monster = {} + +monster.description = "a goblin leader" +monster.experience = 75 +monster.outfit = { + lookType = 61, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 377 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 30, + Stars = 2, + Occurrence = 3, + Locations = "Way to Beregar, below Femor Hills (Tower Defence Quest), near Femor Hills during Goblin raid." + } + +monster.health = 50 +monster.maxHealth = 50 +monster.race = "blood" +monster.corpse = 6002 +monster.speed = 120 +monster.manaCost = 290 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Go go, Gobo attack!!", yell = false}, + {text = "Me the greenest and the meanest!", yell = false}, + {text = "Me have power to crush you!", yell = false}, + {text = "Goblinkiller! Catch him !!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 40000, maxCount = 10}, + {id = 2230, chance = 11500}, + {name = "mouldy cheese", chance = 9000}, + {name = "dagger", chance = 10300}, + {name = "short sword", chance = 15400}, + {name = "bone club", chance = 1300}, + {name = "leather helmet", chance = 16670}, + {name = "leather armor", chance = 5000}, + {name = "small axe", chance = 12800}, + {id = 2667, chance = 15000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -50}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -45, range = 7, shootEffect = CONST_ANI_SMALLSTONE, target = false} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/goblin_scavenger.lua b/data/monster/humanoids/goblin_scavenger.lua new file mode 100644 index 00000000000..78e180b3baa --- /dev/null +++ b/data/monster/humanoids/goblin_scavenger.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Goblin Scavenger") +local monster = {} + +monster.description = "a goblin scavenger" +monster.experience = 37 +monster.outfit = { + lookType = 297, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 464 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Femor Hills, Edron Goblin Cave, and Fenrock." + } + +monster.health = 60 +monster.maxHealth = 60 +monster.race = "blood" +monster.corpse = 6002 +monster.speed = 132 +monster.manaCost = 310 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Shiny, shiny!", yell = false}, + {text = "Gimme gimme!", yell = false}, + {text = "You mean!", yell = false}, + {text = "All mine!", yell = false}, + {text = "Uhh!", yell = false} +} + +monster.loot = { + {name = "small stone", chance = 25560, maxCount = 2}, + {name = "gold coin", chance = 50810, maxCount = 9}, + {id = 2230, chance = 12450}, + {name = "mouldy cheese", chance = 7000}, + {name = "dagger", chance = 18280}, + {name = "short sword", chance = 8900}, + {name = "bone club", chance = 5000}, + {name = "leather helmet", chance = 10180}, + {name = "leather armor", chance = 7700}, + {name = "small axe", chance = 9790}, + {id = 2667, chance = 13640} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -15}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -30, range = 7, shootEffect = CONST_ANI_SPEAR, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_LIFEDRAIN, minDamage = -22, maxDamage = -30, range = 7, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_DEATHDAMAGE, minDamage = -1, maxDamage = -30, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 10, maxDamage = 16, effect = CONST_ME_ENERGYHIT, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 1}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/insane_siren.lua b/data/monster/humanoids/insane_siren.lua new file mode 100644 index 00000000000..32de9b50b05 --- /dev/null +++ b/data/monster/humanoids/insane_siren.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Insane Siren") +local monster = {} + +monster.description = "an insane siren" +monster.experience = 6000 +monster.outfit = { + lookType = 1137, + lookHead = 94, + lookBody = 94, + lookLegs = 79, + lookFeet = 20, + lookAddons = 3, + lookMount = 0 +} + +monster.raceId = 1735 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Court of Summer." + } + +monster.health = 6500 +monster.maxHealth = 6500 +monster.race = "blood" +monster.corpse = 34771 +monster.speed = 420 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Dream or nightmare?", yell = false} +} + +monster.loot = { + {name = "Platinum Coin", chance = 100000, maxCount = 12}, + {name = "Ultimate Health Potion", chance = 14970}, + {name = "Miraculum", chance = 13090}, + {name = "Dream Essence Egg", chance = 11980}, + {name = "Wand of Draconia", chance = 7700}, + {name = "Holy Orchid", chance = 5650}, + {name = "Magma Amulet", chance = 5130}, + {name = "Wand of Inferno", chance = 4360}, + {name = "Fire Axe", chance = 3590}, + {name = "Magma Coat", chance = 3340}, + {name = "Wand of Dragonbreath", chance = 2650}, + {name = "Sun Fruit", chance = 2570}, + {name = "Magma Legs", chance = 1200}, + {name = "Magma Monocle", chance = 260} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -530}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -270, maxDamage = -710, length = 3, spread = 0, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -250, maxDamage = -300, range = 7, shootEffect = CONST_ANI_FIRE, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -350, maxDamage = -380, radius = 5, effect = CONST_ME_EXPLOSIONHIT, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -350, radius = 5, effect = CONST_ME_EXPLOSIONAREA, target = true} +} + +monster.defenses = { + defense = 20, + armor = 70 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 55}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -20}, + {type = COMBAT_HOLYDAMAGE , percent = 25}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/island_troll.lua b/data/monster/humanoids/island_troll.lua new file mode 100644 index 00000000000..84629a327c3 --- /dev/null +++ b/data/monster/humanoids/island_troll.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Island Troll") +local monster = {} + +monster.description = "an island troll" +monster.experience = 20 +monster.outfit = { + lookType = 282, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 277 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Goroma." + } + +monster.health = 50 +monster.maxHealth = 50 +monster.race = "blood" +monster.corpse = 7930 +monster.speed = 126 +monster.manaCost = 290 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hmmm, turtles", yell = false}, + {text = "Hmmm, dogs", yell = false}, + {text = "Hmmm, worms", yell = false}, + {text = "Groar", yell = false}, + {text = "Gruntz!", yell = false} +} + +monster.loot = { + {id = 2120, chance = 8000}, + {name = "gold coin", chance = 60000, maxCount = 10}, + {name = "silver amulet", chance = 70}, + {name = "hand axe", chance = 18000}, + {name = "spear", chance = 20000}, + {name = "studded club", chance = 5000}, + {name = "leather helmet", chance = 10000}, + {id = 2512, chance = 16000}, + {name = "leather boots", chance = 10500}, + {name = "mango", chance = 5000}, + {id = 5901, chance = 30000}, + {name = "marlin", chance = 40} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -10} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/little_corym_charlatan.lua b/data/monster/humanoids/little_corym_charlatan.lua new file mode 100644 index 00000000000..c5284c88e5a --- /dev/null +++ b/data/monster/humanoids/little_corym_charlatan.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("Little Corym Charlatan") +local monster = {} + +monster.description = "a little corym charlatan" +monster.experience = 40 +monster.outfit = { + lookType = 532, + lookHead = 0, + lookBody = 97, + lookLegs = 116, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 920 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 1, + Locations = "Venore marshes." + } + +monster.health = 90 +monster.maxHealth = 90 +monster.race = "blood" +monster.corpse = 19729 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -10} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/lost_basher.lua b/data/monster/humanoids/lost_basher.lua new file mode 100644 index 00000000000..c1b7b5a612e --- /dev/null +++ b/data/monster/humanoids/lost_basher.lua @@ -0,0 +1,142 @@ +local mType = Game.createMonsterType("Lost Basher") +local monster = {} + +monster.description = "a lost basher" +monster.experience = 1800 +monster.outfit = { + lookType = 538, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 925 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Caves of the Lost, Lower Spike and in the Lost Dwarf version of the Forsaken Mine." + } + +monster.health = 2600 +monster.maxHealth = 2600 +monster.race = "blood" +monster.corpse = 19963 +monster.speed = 260 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Yhouuuu!", yell = false} +} + +monster.loot = { + {name = "piggy bank", chance = 4450}, + {name = "gold coin", chance = 60000, maxCount = 100}, + {name = "platinum coin", chance = 70000, maxCount = 2}, + {name = "fire axe", chance = 310}, + {name = "war axe", chance = 120}, + {name = "knight legs", chance = 310}, + {name = "black shield", chance = 3710}, + {name = "brown mushroom", chance = 15170, maxCount = 2}, + {name = "iron ore", chance = 5280}, + {name = "chaos mace", chance = 160}, + {name = "spiked squelcher", chance = 420}, + {name = "great mana potion", chance = 11240}, + {name = "terra boots", chance = 780}, + {name = "ultimate health potion", chance = 10250}, + {name = "small topaz", chance = 10200}, + {id = 13757, chance = 21130}, + {name = "blue crystal shard", chance = 840}, + {name = "lost basher's spike", chance = 17260}, + {name = "lost basher's spike", chance = 14380}, + {name = "bloody dwarven beard", chance = 1730}, + {name = "pair of iron fists", chance = 1410}, + {name = "buckle", chance = 10930}, + {name = "bonecarving knife", chance = 7320}, + {name = "basalt fetish", chance = 8800}, + {name = "basalt figurine", chance = 9470} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -351}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -220, range = 7, radius = 3, shootEffect = CONST_ANI_WHIRLWINDAXE, effect = CONST_ME_EXPLOSIONAREA, target = true}, + {name ="drunk", interval = 2000, chance = 15, radius = 4, shootEffect = CONST_ANI_WHIRLWINDCLUB, effect = CONST_ME_SOUND_RED, target = true, duration = 6000}, + {name ="speed", interval = 2000, chance = 15, speedChange = -650, radius = 2, effect = CONST_ME_ENERGYHIT, target = false, duration = 15000} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 250, maxDamage = 500, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 40}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 1}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 1} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/lost_berserker.lua b/data/monster/humanoids/lost_berserker.lua new file mode 100644 index 00000000000..a35e8b107d8 --- /dev/null +++ b/data/monster/humanoids/lost_berserker.lua @@ -0,0 +1,147 @@ +local mType = Game.createMonsterType("Lost Berserker") +local monster = {} + +monster.description = "a lost berserker" +monster.experience = 4400 +monster.outfit = { + lookType = 496, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 888 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Warzones 2 and 3." + } + +monster.health = 5900 +monster.maxHealth = 5900 +monster.race = "blood" +monster.corpse = 17416 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Kill! Kiill! Kill!", yell = false}, + {text = "Death! Death! Death!", yell = false} +} + +monster.loot = { + {name = "piggy bank", chance = 3920}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "platinum coin", chance = 100000, maxCount = 9}, + {name = "dwarven ring", chance = 2280}, + {name = "knight axe", chance = 2070}, + {name = "fire axe", chance = 380}, + {name = "royal helmet", chance = 150}, + {name = "guardian shield", chance = 1400}, + {name = "tower shield", chance = 1002}, + {name = "black shield", chance = 640}, + {name = "brown mushroom", chance = 15190, maxCount = 2}, + {name = "iron ore", chance = 8490}, + {name = "magic sulphur", chance = 720}, + {name = "chaos mace", chance = 550}, + {name = "spiked squelcher", chance = 810}, + {name = "great mana potion", chance = 13650}, + {name = "great health potion", chance = 13650}, + {name = "terra boots", chance = 640}, + {name = "small topaz", chance = 7970, maxCount = 2}, + {name = "clay lump", chance = 930}, + {id = 13757, chance = 2050}, + {name = "violet crystal shard", chance = 3500}, + {name = "brown crystal splinter", chance = 7540, maxCount = 2}, + {name = "blue crystal splinter", chance = 4610}, + {name = "green crystal fragment", chance = 6870}, + {name = "drill bolt", chance = 8210, maxCount = 10} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -501}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -300, range = 7, shootEffect = CONST_ANI_WHIRLWINDAXE, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -250, range = 7, radius = 3, shootEffect = CONST_ANI_EXPLOSION, effect = CONST_ME_EXPLOSIONAREA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -150, maxDamage = -250, radius = 5, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = -800, radius = 2, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000}, + {name ="drunk", interval = 2000, chance = 10, radius = 4, effect = CONST_ME_STUN, target = true, duration = 6000} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="invisible", interval = 2000, chance = 5, effect = CONST_ME_TELEPORT} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 40}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 40}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/lost_exile.lua b/data/monster/humanoids/lost_exile.lua new file mode 100644 index 00000000000..dd37be1305b --- /dev/null +++ b/data/monster/humanoids/lost_exile.lua @@ -0,0 +1,148 @@ +local mType = Game.createMonsterType("Lost Exile") +local monster = {} + +monster.description = "a lost exile" +monster.experience = 1800 +monster.outfit = { + lookType = 537, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1529 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "South east of the Gnome Deep Hub's entrance." + } + +monster.health = 1600 +monster.maxHealth = 1600 +monster.race = "blood" +monster.corpse = 33430 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "**", yell = false}, + {text = "**", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 200}, + {name = "platinum coin", chance = 60240, maxCount = 2}, + {name = "strong health potion", chance = 10950, maxCount = 2}, + {name = "great mana potion", chance = 8330, maxCount = 2}, + {name = "brown mushroom", chance = 16900, maxCount = 2}, + {id = 13757, chance = 13100}, + {name = "holy ash", chance = 13100}, + {name = "small topaz", chance = 10240}, + {name = "lost husher's staff", chance = 6900}, + {name = "skull shatterer", chance = 7620}, + {name = "wimp tooth chain", chance = 11900}, + {name = "red hair dye", chance = 12620}, + {name = "basalt fetish", chance = 8100}, + {name = "bonecarving knife", chance = 8100}, + {name = "basalt figurine", chance = 8100}, + {name = "bone fetish", chance = 8881}, + {name = "dwarven ring", chance = 1043}, + {name = "guardian shield", chance = 1430}, + {name = "buckle", chance = 1900}, + {name = "clay lump", chance = 710}, + {name = "knight axe", chance = 950}, + {name = "terra boots", chance = 240}, + {name = "suspicious device", chance = 250}, + {name = "tower shield", chance = 240}, + {name = "terra legs", chance = 240}, + {name = "fire axe", chance = 710}, + {name = "skull staff", chance = 480}, + {name = "spiked squelcher", chance = 240} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -120}, + {name ="sudden death", interval = 2000, chance = 15, minDamage = -150, maxDamage = -350, range = 3, length = 6, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_MANADRAIN, minDamage = -150, maxDamage = -250, range = 3, length = 5, spread = 5, effect = CONST_ME_SMOKE, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -150, maxDamage = -290, range = 3, length = 5, spread = 5, shootEffect = CONST_ANI_LARGEROCK, effect = CONST_ME_POISONAREA, target = false}, + {name ="sudden death", interval = 2000, chance = 15, minDamage = -70, maxDamage = -250, range = 7, target = false}, + {name ="drunk", interval = 2000, chance = 10, range = 7, shootEffect = CONST_ANI_ENERGY, target = false, duration = 5000} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 0, maxDamage = 160, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = -30}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/lost_husher.lua b/data/monster/humanoids/lost_husher.lua new file mode 100644 index 00000000000..4be2ad96059 --- /dev/null +++ b/data/monster/humanoids/lost_husher.lua @@ -0,0 +1,141 @@ +local mType = Game.createMonsterType("Lost Husher") +local monster = {} + +monster.description = "a lost husher" +monster.experience = 1800 +monster.outfit = { + lookType = 537, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 924 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Caves of the Lost, Lower Spike and in the Lost Dwarf version of the Forsaken Mine." + } + +monster.health = 1600 +monster.maxHealth = 1600 +monster.race = "blood" +monster.corpse = 19964 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Arr far zwar!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "platinum coin", chance = 58670, maxCount = 2}, + {name = "fire axe", chance = 330}, + {name = "skull staff", chance = 280}, + {name = "guardian shield", chance = 830}, + {name = "tower shield", chance = 440}, + {name = "brown mushroom", chance = 14920, maxCount = 2}, + {name = "spiked squelcher", chance = 50}, + {name = "strong health potion", chance = 11050, maxCount = 3}, + {name = "great mana potion", chance = 10770, maxCount = 2}, + {name = "terra legs", chance = 50}, + {name = "terra boots", chance = 880}, + {name = "small topaz", chance = 9780}, + {name = "clay lump", chance = 500}, + {id = 13757, chance = 10930}, + {name = "buckle", chance = 8180}, + {name = "buckle", chance = 770}, + {name = "bonecarving knife", chance = 8510}, + {name = "wimp tooth chain", chance = 8950}, + {name = "skull shatterer", chance = 12320}, + {name = "red hair dye", chance = 8510}, + {name = "basalt figurine", chance = 8560} +} + +monster.attacks = { + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -150, maxDamage = -300, length = 6, spread = 3, effect = CONST_ME_BLACKSMOKE, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -150, maxDamage = -250, radius = 5, effect = CONST_ME_BLACKSMOKE, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -150, maxDamage = -200, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -150, maxDamage = -250, range = 7, radius = 2, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_MAGIC_GREEN, target = true}, + {name ="drunk", interval = 2000, chance = 10, radius = 4, effect = CONST_ME_SOUND_RED, target = false, duration = 6000} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 75, maxDamage = 92, effect = CONST_ME_YELLOWENERGY, target = false}, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_TELEPORT} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 40}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/lost_thrower.lua b/data/monster/humanoids/lost_thrower.lua new file mode 100644 index 00000000000..fa1ee5b4050 --- /dev/null +++ b/data/monster/humanoids/lost_thrower.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Lost Thrower") +local monster = {} + +monster.description = "a lost thrower" +monster.experience = 1200 +monster.outfit = { + lookType = 539, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 926 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Caves of the Lost, Lower Spike and in the Lost Dwarf version of the Forsaken Mine." + } + +monster.health = 1700 +monster.maxHealth = 1700 +monster.race = "blood" +monster.corpse = 19998 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 37}, + {name = "platinum coin", chance = 70000, maxCount = 2}, + {name = "brown mushroom", chance = 14500, maxCount = 2}, + {name = "iron ore", chance = 9470}, + {name = "great mana potion", chance = 13470}, + {name = "great health potion", chance = 14730}, + {id = 13757, chance = 12180}, + {name = "buckle", chance = 850}, + {name = "broken throwing axe", chance = 1390}, + {name = "helmet of the lost", chance = 13560}, + {name = "lost bracers", chance = 14860}, + {name = "mad froth", chance = 11810}, + {name = "basalt fetish", chance = 6150}, + {name = "basalt figurine", chance = 7900} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -301}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -250, range = 7, radius = 1, shootEffect = CONST_ANI_THROWINGSTAR, effect = CONST_ME_EXPLOSIONAREA, target = true}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_PHYSICALDAMAGE, range = 7, radius = 2, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = -150, maxDamage = -300, range = 7, radius = 2, shootEffect = CONST_ANI_WHIRLWINDCLUB, effect = CONST_ME_STUN, target = true}, + {name ="drunk", interval = 2000, chance = 10, radius = 3, shootEffect = CONST_ANI_WHIRLWINDAXE, effect = CONST_ME_EXPLOSIONAREA, target = true, duration = 6000} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 100, maxDamage = 500, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_TELEPORT} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 40}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/minotaur.lua b/data/monster/humanoids/minotaur.lua new file mode 100644 index 00000000000..44987f086e9 --- /dev/null +++ b/data/monster/humanoids/minotaur.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Minotaur") +local monster = {} + +monster.description = "a minotaur" +monster.experience = 50 +monster.outfit = { + lookType = 25, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 25 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Mino Hell (Rookgaard), Two outside Bear Room Quest, (Rookgaard) and also 2x on the premium side, \z + Mintwallin, Folda, Minotaur Pyramid, Outlaw Camp, Kazordoon minotaur cave, Plains of Havoc, Elven Bane, \z + Deeper Fibula Dungeon (level 50+ to open the door), Ancient Temple, Maze of Lost Souls, \z + Thais Minotaur Camp, Foreigner Quarter." + } + +monster.health = 100 +monster.maxHealth = 100 +monster.race = "blood" +monster.corpse = 5969 +monster.speed = 168 +monster.manaCost = 330 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Kaplar!", yell = false}, + {text = "Hurr", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 67500, maxCount = 25}, + {name = "bronze amulet", chance = 110}, + {id = 2376, chance = 5000}, + {name = "axe", chance = 4000}, + {name = "mace", chance = 12840}, + {name = "brass helmet", chance = 7700}, + {name = "chain armor", chance = 10000}, + {name = "plate shield", chance = 20020}, + {id = 2554, chance = 310}, + {name = "meat", chance = 5000}, + {name = "minotaur leather", chance = 990}, + {name = "minotaur horn", chance = 2090, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -45} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -15}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/minotaur_amazon.lua b/data/monster/humanoids/minotaur_amazon.lua new file mode 100644 index 00000000000..afddf1ebfdd --- /dev/null +++ b/data/monster/humanoids/minotaur_amazon.lua @@ -0,0 +1,142 @@ +local mType = Game.createMonsterType("Minotaur Amazon") +local monster = {} + +monster.description = "a minotaur amazon" +monster.experience = 2200 +monster.outfit = { + lookType = 608, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1045 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Underground Glooth Factory, Oramond Minotaur Camp, Oramond Dungeon." + } + +monster.health = 2600 +monster.maxHealth = 2600 +monster.race = "blood" +monster.corpse = 23371 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 11 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 240, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I'll protect the herd!", yell = false}, + {text = "Never surrender!", yell = false}, + {text = "You won't hurt us!", yell = false} +} + +monster.loot = { + {id = 7368, chance = 3040, maxCount = 5}, + {id = 23575, chance = 19830}, + {id = 2148, chance = 100000, maxCount = 196}, + {id = 2671, chance = 60780}, + {id = 2666, chance = 4920}, + {id = 2152, chance = 62080, maxCount = 3}, + {id = 9971, chance = 290}, + {id = 5878, chance = 17950}, + {id = 7591, chance = 7670}, + {id = 7590, chance = 7380}, + {id = 12428, chance = 6800, maxCount = 2}, + {id = 2214, chance = 3040}, + {id = 2147, chance = 5500, maxCount = 2}, + {id = 9970, chance = 900, maxCount = 2}, + {id = 2150, chance = 970, maxCount = 2}, + {id = 2149, chance = 4050, maxCount = 2}, + {id = 23546, chance = 3040}, + {id = 23545, chance = 1740}, + {id = 5911, chance = 710}, + {id = 2156, chance = 430}, + {id = 2197, chance = 850}, + {id = 2154, chance = 870}, + {id = 2475, chance = 1160}, + {id = 7443, chance = 720} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 50}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -50, maxDamage = -305, length = 8, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 16, type = COMBAT_LIFEDRAIN, minDamage = -50, maxDamage = -150, radius = 4, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 22, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -150, range = 7, shootEffect = CONST_ANI_HUNTINGSPEAR, effect = CONST_ME_EXPLOSIONAREA, target = false}, + -- bleed + {name ="condition", type = CONDITION_BLEEDING, interval = 2000, chance = 40, minDamage = -300, maxDamage = -400, radius = 4, shootEffect = CONST_ANI_THROWINGKNIFE, target = true}, + {name ="minotaur amazon paralyze", interval = 2000, chance = 15, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/minotaur_archer.lua b/data/monster/humanoids/minotaur_archer.lua new file mode 100644 index 00000000000..db47a7ae52e --- /dev/null +++ b/data/monster/humanoids/minotaur_archer.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Minotaur Archer") +local monster = {} + +monster.description = "a minotaur archer" +monster.experience = 65 +monster.outfit = { + lookType = 24, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 24 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Ancient Temple, way to Mintwallin, Folda Underground Cave, Outlaw Camp, Plains of Havoc, \z + Kazordoon Minotaur Tower, Daramian Minotaur Pyramid, Deeper Fibula Dungeon (level 50+ to open the door), \z + Hero Cave, Foreigner Quarter and Elvenbane." + } + +monster.health = 100 +monster.maxHealth = 100 +monster.race = "blood" +monster.corpse = 5982 +monster.speed = 160 +monster.manaCost = 390 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ruan Wihmpy!", yell = false}, + {text = "Kaplar!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 75410, maxCount = 30}, + {name = "crossbow", chance = 830}, + {name = "brass armor", chance = 530}, + {name = "scale armor", chance = 530}, + {name = "bolt", chance = 90450, maxCount = 20}, + {name = "meat", chance = 5000}, + {name = "minotaur leather", chance = 1900}, + {name = "piercing bolt", chance = 12340, maxCount = 4}, + {name = "broken crossbow", chance = 15400}, + {name = "minotaur horn", chance = 1990, maxCount = 2}, + {name = "piece of archer armor", chance = 8260} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -25}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -80, range = 7, shootEffect = CONST_ANI_BOLT, target = false} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -1} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/minotaur_bruiser.lua b/data/monster/humanoids/minotaur_bruiser.lua new file mode 100644 index 00000000000..f45e4add96f --- /dev/null +++ b/data/monster/humanoids/minotaur_bruiser.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Minotaur Bruiser") +local monster = {} + +monster.description = "a minotaur bruiser" +monster.experience = 50 +monster.outfit = { + lookType = 25, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 100 +monster.maxHealth = 100 +monster.race = "blood" +monster.corpse = 5969 +monster.speed = 168 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 65700, maxCount = 15}, + {id = 2510, chance = 20000}, + {id = 2398, chance = 12900}, + {id = 2464, chance = 10000}, + {id = 2460, chance = 7800}, + {id = 2376, chance = 5000}, + {id = 2666, chance = 5000}, + {id = 2386, chance = 4000}, + {id = 12428, chance = 2000, maxCount = 2}, + {id = 5878, chance = 980}, + {id = 2554, chance = 310} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -45} +} + +monster.defenses = { + defense = 15, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/minotaur_cult_follower.lua b/data/monster/humanoids/minotaur_cult_follower.lua new file mode 100644 index 00000000000..3ec784ab3cc --- /dev/null +++ b/data/monster/humanoids/minotaur_cult_follower.lua @@ -0,0 +1,139 @@ +local mType = Game.createMonsterType("Minotaur Cult Follower") +local monster = {} + +monster.description = "a minotaur cult follower" +monster.experience = 960 +monster.outfit = { + lookType = 25, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1508 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Minotaurs Cult Cave." + } + +monster.health = 1600 +monster.maxHealth = 1600 +monster.race = "blood" +monster.corpse = 5969 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Kaplar!", yell = false}, + {text = "Hurr!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 150}, + {name = "cowbell", chance = 22480}, + {name = "cultish robe", chance = 14720}, + {name = "plate shield", chance = 20020}, + {name = "great health potion", chance = 11840}, + {name = "small ruby", chance = 3690, maxCount = 2}, + {name = "small topaz", chance = 3170, maxCount = 2}, + {name = "yellow gem", chance = 280}, + {name = "platinum coin", chance = 65250, maxCount = 3}, + {name = "plate shield", chance = 20710}, + {name = "small emerald", chance = 3410, maxCount = 2}, + {name = "small amethyst", chance = 2950, maxCount = 2}, + {name = "red piece of cloth", chance = 810}, + {name = "ham", chance = 59410}, + {name = "bronze amulet", chance = 15140}, + {name = "mino shield", chance = 12670}, + {name = "ring of healing", chance = 3190}, + {name = "mino lance", chance = 1810}, + {name = "warrior helmet", chance = 570}, + {name = "red gem", chance = 170}, + {name = "meat", chance = 8020}, + {name = "minotaur leather", chance = 11530}, + {name = "minotaur horn", chance = 14550, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -180, maxDamage = -250, range = 7, effect = CONST_ME_EXPLOSIONAREA, target = true} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_HEALING, minDamage = 200, maxDamage = 450, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/minotaur_cult_prophet.lua b/data/monster/humanoids/minotaur_cult_prophet.lua new file mode 100644 index 00000000000..dd937fe49a7 --- /dev/null +++ b/data/monster/humanoids/minotaur_cult_prophet.lua @@ -0,0 +1,138 @@ +local mType = Game.createMonsterType("Minotaur Cult Prophet") +local monster = {} + +monster.description = "a minotaur cult prophet" +monster.experience = 1100 +monster.outfit = { + lookType = 23, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1509 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Minotaurs Cult Cave." + } + +monster.health = 1700 +monster.maxHealth = 1700 +monster.race = "blood" +monster.corpse = 5981 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Learrn tha secrret uf deathhh!", yell = false}, + {text = "Kaplar!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 150}, + {name = "cowbell", chance = 18570}, + {name = "moonlight rod", chance = 8480}, + {name = "cultish robe", chance = 15450}, + {name = "great health potion", chance = 7070}, + {name = "great mana potion", chance = 16810}, + {name = "gold ingot", chance = 1120}, + {name = "small ruby", chance = 7160}, + {name = "small topaz", chance = 7650}, + {name = "yellow gem", chance = 490}, + {name = "platinum coin", chance = 67040, maxCount = 3}, + {name = "small emerald", chance = 11160}, + {name = "small diamond", chance = 2900, maxCount = 2}, + {name = "small amethyst", chance = 6680, maxCount = 2}, + {name = "red piece of cloth", chance = 630}, + {name = "ring of healing", chance = 6730}, + {name = "red gem", chance = 390}, + {name = "meat", chance = 8040}, + {name = "ham", chance = 60140}, + {name = "minotaur leather", chance = 14230}, + {name = "minotaur horn", chance = 18270, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -20, maxDamage = -350, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -50, maxDamage = -300, range = 7, radius = 1, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="heal monster", interval = 2000, chance = 20, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/minotaur_cult_zealot.lua b/data/monster/humanoids/minotaur_cult_zealot.lua new file mode 100644 index 00000000000..d08c3862682 --- /dev/null +++ b/data/monster/humanoids/minotaur_cult_zealot.lua @@ -0,0 +1,134 @@ +local mType = Game.createMonsterType("Minotaur Cult Zealot") +local monster = {} + +monster.description = "a minotaur cult zealot" +monster.experience = 1350 +monster.outfit = { + lookType = 29, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1510 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Minotaurs Cult Cave." + } + +monster.health = 1800 +monster.maxHealth = 1800 +monster.race = "blood" +monster.corpse = 5983 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Kirll Karrrl!", yell = false}, + {text = "Kaplar!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 150}, + {name = "snakebite rod", chance = 11670}, + {name = "taurus mace", chance = 5360}, + {name = "cultish robe", chance = 9200}, + {name = "purple robe", chance = 16230}, + {name = "strong mana potion", chance = 10660, maxCount = 3}, + {name = "small ruby", chance = 2030, maxCount = 2}, + {name = "small topaz", chance = 2680, maxCount = 2}, + {name = "yellow gem", chance = 220}, + {name = "platinum coin", chance = 39350, maxCount = 3}, + {name = "small emerald", chance = 2540, maxCount = 2}, + {name = "small sapphire", chance = 2170, maxCount = 2}, + {name = "small diamond", chance = 2900, maxCount = 2}, + {name = "small amethyst", chance = 2610, maxCount = 2}, + {name = "red piece of cloth", chance = 2460}, + {name = "red gem", chance = 70}, + {name = "minotaur leather", chance = 4780}, + {name = "minotaur horn", chance = 2320, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -180, maxDamage = -230, range = 7, shootEffect = CONST_ANI_WHIRLWINDAXE, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -180, maxDamage = -250, range = 7, effect = CONST_ME_EXPLOSIONHIT, target = true} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/minotaur_guard.lua b/data/monster/humanoids/minotaur_guard.lua new file mode 100644 index 00000000000..d120d448977 --- /dev/null +++ b/data/monster/humanoids/minotaur_guard.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Minotaur Guard") +local monster = {} + +monster.description = "a minotaur guard" +monster.experience = 160 +monster.outfit = { + lookType = 29, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 29 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Ancient Temple, Mintwallin, Minotaur Pyramid, Maze of Lost Souls, Folda, Cyclopolis, \z + Deeper Fibula Dungeon (level 50+ to open the door), Hero Cave, underground of Elvenbane, \z + Plains of Havoc, Kazordoon Minotaur Cave, Foreigner Quarter." + } + +monster.health = 185 +monster.maxHealth = 185 +monster.race = "blood" +monster.corpse = 5983 +monster.speed = 190 +monster.manaCost = 550 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 20, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Kirrl Karrrl!", yell = false}, + {text = "Kaplar", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 59640, maxCount = 20}, + {name = "double axe", chance = 400}, + {name = "chain armor", chance = 2980}, + {name = "brass armor", chance = 4390}, + {name = "battle shield", chance = 2150}, + {name = "fishing rod", chance = 480}, + {name = "minotaur leather", chance = 1000}, + {id = 7401, chance = 80}, + {name = "health potion", chance = 400}, + {name = "minotaur horn", chance = 8330, maxCount = 2}, + {name = "piece of warrior armor", chance = 5040} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/minotaur_hunter.lua b/data/monster/humanoids/minotaur_hunter.lua new file mode 100644 index 00000000000..26b5d35140b --- /dev/null +++ b/data/monster/humanoids/minotaur_hunter.lua @@ -0,0 +1,143 @@ +local mType = Game.createMonsterType("Minotaur Hunter") +local monster = {} + +monster.description = "a minotaur hunter" +monster.experience = 1700 +monster.outfit = { + lookType = 612, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1052 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Oramond/Southern Plains, Minotaur Hills, \z + Oramond Dungeon (depending on Magistrate votes), Underground Glooth Factory." + } + +monster.health = 1400 +monster.maxHealth = 1400 +monster.race = "blood" +monster.corpse = 23466 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 11 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You are marked for death!", yell = false}, + {text = "This time the prey is you!", yell = false}, + {text = "You are hunted!", yell = false}, + {text = "Bullseye!", yell = false}, + {text = "You'll make a fine trophy!", yell = false} +} + +monster.loot = { + {id = 2260, chance = 13600, maxCount = 2}, + {id = 2148, chance = 99500, maxCount = 199}, + {id = 3965, chance = 14880, maxCount = 5}, + {id = 2152, chance = 33890, maxCount = 3}, + {id = 7378, chance = 11410, maxCount = 5}, + {id = 7588, chance = 10350, maxCount = 2}, + {id = 7589, chance = 10620, maxCount = 2}, + {id = 5944, chance = 7430}, + {id = 5878, chance = 5030}, + {id = 12428, chance = 4720, maxCount = 2}, + {id = 2147, chance = 2640, maxCount = 3}, + {id = 2150, chance = 2580, maxCount = 3}, + {id = 2165, chance = 2220}, + {id = 5912, chance = 1670}, + {id = 5910, chance = 1420}, + {id = 5911, chance = 1360}, + {id = 23546, chance = 640}, + {id = 2154, chance = 470}, + {id = 2156, chance = 400}, + {id = 7401, chance = 190}, + {id = 23537, chance = 170} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 50}, + {name ="combat", interval = 2000, chance = 22, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -150, range = 7, shootEffect = CONST_ANI_SPEAR, effect = CONST_ME_EXPLOSIONAREA, target = false}, + -- bleed + {name ="condition", type = CONDITION_BLEEDING, interval = 2000, chance = 40, minDamage = -300, maxDamage = -400, range = 7, radius = 3, shootEffect = CONST_ANI_THROWINGKNIFE, effect = CONST_ME_HITAREA, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -160, maxDamage = -260, range = 7, radius = 2, shootEffect = CONST_ANI_BURSTARROW, effect = CONST_ME_EXPLOSIONHIT, target = true}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_LIFEDRAIN, minDamage = -35, maxDamage = -150, radius = 4, effect = CONST_ME_EXPLOSIONAREA, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 7, type = COMBAT_HEALING, minDamage = 95, maxDamage = 180, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = 520, effect = CONST_ME_POFF, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/minotaur_invader.lua b/data/monster/humanoids/minotaur_invader.lua new file mode 100644 index 00000000000..6424250545b --- /dev/null +++ b/data/monster/humanoids/minotaur_invader.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Minotaur Invader") +local monster = {} + +monster.description = "a minotaur invader" +monster.experience = 1600 +monster.outfit = { + lookType = 29, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1109 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Second floor Glooth Underground Factory, east side during the Minotaurs raid." + } + +monster.health = 1850 +monster.maxHealth = 1850 +monster.race = "blood" +monster.corpse = 5983 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "For the victory!", yell = false}, + {text = "We will crush the enemy!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 59640, maxCount = 160}, + {id = 12428, chance = 8330, maxCount = 2}, + {id = 12438, chance = 5040}, + {id = 5878, chance = 1000}, + {id = 7401, chance = 90} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -350} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/minotaur_mage.lua b/data/monster/humanoids/minotaur_mage.lua new file mode 100644 index 00000000000..aefa244638d --- /dev/null +++ b/data/monster/humanoids/minotaur_mage.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Minotaur Mage") +local monster = {} + +monster.description = "a minotaur mage" +monster.experience = 150 +monster.outfit = { + lookType = 23, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 23 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 250, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Cyclopolis, Mintwallin, Maze of Lost Souls, Dark Pyramid, Folda (hidden cave), \z + Kazordoon (The Horned Fox's hideout), the Plains of Havoc, Point of No Return south of Outlaw Camp, \z + Elvenbane, the depths of Fibula Dungeon (level 50+), cave east from Dwarf Bridge, Foreigner Quarter, \z + Rookgaard Minotaur Hell (not reachable)." + } + +monster.health = 155 +monster.maxHealth = 155 +monster.race = "blood" +monster.corpse = 5981 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Learrn tha secrret uf deathhh!", yell = false}, + {text = "Kaplar!", yell = false} +} + +monster.loot = { + {id = 2050, chance = 4950}, + {name = "gold coin", chance = 85780, maxCount = 35}, + {name = "wand of cosmic energy", chance = 600}, + {name = "leather helmet", chance = 3000}, + {name = "leather legs", chance = 5190}, + {id = 2684, chance = 15003, maxCount = 8}, + {name = "minotaur leather", chance = 2290}, + {name = "taurus mace", chance = 1000}, + {name = "mana potion", chance = 490}, + {name = "minotaur horn", chance = 3020, maxCount = 2}, + {name = "purple robe", chance = 6430, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -20}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -20, maxDamage = -59, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -50, maxDamage = -105, range = 7, radius = 1, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="energyfield", interval = 2000, chance = 10, range = 7, radius = 1, shootEffect = CONST_ANI_ENERGYBALL, target = true} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/minotaur_occultist.lua b/data/monster/humanoids/minotaur_occultist.lua new file mode 100644 index 00000000000..b05059574b0 --- /dev/null +++ b/data/monster/humanoids/minotaur_occultist.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Minotaur Occultist") +local monster = {} + +monster.description = "a minotaur occultist" +monster.experience = 100 +monster.outfit = { + lookType = 23, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 125 +monster.maxHealth = 125 +monster.race = "blood" +monster.corpse = 5981 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 21}, + {id = 2684, chance = 35000, maxCount = 4}, + {id = 20104, chance = 12000}, + {id = 12428, chance = 10000}, + {id = 2649, chance = 9000}, + {id = 7620, chance = 3500}, + {id = 2050, chance = 3500}, + {id = 2461, chance = 1800}, + {id = 12429, chance = 1800} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -10}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -20, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = 0, maxDamage = -20, range = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = false}, + {name ="energyfield", interval = 2000, chance = 10, range = 7, shootEffect = CONST_ANI_ENERGYBALL, target = true} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/minotaur_poacher.lua b/data/monster/humanoids/minotaur_poacher.lua new file mode 100644 index 00000000000..acf5b5ed283 --- /dev/null +++ b/data/monster/humanoids/minotaur_poacher.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Minotaur Poacher") +local monster = {} + +monster.description = "a minotaur poacher" +monster.experience = 55 +monster.outfit = { + lookType = 24, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 125 +monster.maxHealth = 125 +monster.race = "blood" +monster.corpse = 5982 +monster.speed = 160 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 28}, + {name = "bolt", chance = 60660, maxCount = 18}, + {name = "piercing bolt", chance = 60660, maxCount = 4}, + {name = "broken crossbow", chance = 19400}, + {name = "chain armor", chance = 9840}, + {name = "studded armor", chance = 4920}, + {name = "meat", chance = 3280}, + {name = "minotaur leather", chance = 1400}, + {name = "crossbow", chance = 710}, + {name = "minotaur horn", chance = 710} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -15}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -20, range = 7, shootEffect = CONST_ANI_BOLT, target = false} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/minotaur_totem.lua b/data/monster/humanoids/minotaur_totem.lua new file mode 100644 index 00000000000..e400a6ea141 --- /dev/null +++ b/data/monster/humanoids/minotaur_totem.lua @@ -0,0 +1,90 @@ +local mType = Game.createMonsterType("Minotaur Totem") +local monster = {} + +monster.description = "a minotaur totem" +monster.experience = 500 +monster.outfit = { + lookTypeEx = 3802 +} + +monster.health = 6000 +monster.maxHealth = 6000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 78 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 16 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = true, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 4000, chance = 15, type = COMBAT_HEALING, minDamage = 0, maxDamage = 1000, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/mooh'tah_warrior.lua b/data/monster/humanoids/mooh'tah_warrior.lua new file mode 100644 index 00000000000..d7fa253ac67 --- /dev/null +++ b/data/monster/humanoids/mooh'tah_warrior.lua @@ -0,0 +1,137 @@ +local mType = Game.createMonsterType("Mooh'Tah Warrior") +local monster = {} + +monster.description = "a mooh'tah warrior" +monster.experience = 900 +monster.outfit = { + lookType = 611, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1051 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Oramond/Southern Plains, Minotaur Hills, \z + Oramond Dungeon (depending on Magistrate votes), Underground Glooth Factory." + } + +monster.health = 1200 +monster.maxHealth = 1200 +monster.race = "blood" +monster.corpse = 23462 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 4 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Feel the power of the Mooh'Tah!", yell = false}, + {text = "Ommm!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 120}, + {id = 2152, chance = 39860, maxCount = 3}, + {id = 23573, chance = 15030}, + {id = 7589, chance = 7110}, + {id = 7588, chance = 6390}, + {id = 5878, chance = 5530}, + {id = 2147, chance = 5470}, + {id = 2149, chance = 5280}, + {id = 2150, chance = 5200}, + {id = 9970, chance = 4760}, + {id = 12428, chance = 4710, maxCount = 2}, + {id = 23548, chance = 1380}, + {id = 2207, chance = 1110}, + {id = 23537, chance = 1090}, + {id = 2515, chance = 1020}, + {id = 2477, chance = 710}, + {id = 5911, chance = 650}, + {id = 2476, chance = 490}, + {id = 7401, chance = 150} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 45, attack = 80}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_ENERGYDAMAGE, minDamage = -150, maxDamage = -200, length = 4, spread = 3, effect = CONST_ME_YELLOWENERGY, target = false}, + {name ="combat", interval = 2000, chance = 11, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -135, range = 7, shootEffect = CONST_ANI_LARGEROCK, effect = CONST_ME_EXPLOSIONAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -50, maxDamage = -150, radius = 3, effect = CONST_ME_HITAREA, target = false}, + {name ="mooh'tah master skill reducer", interval = 2000, chance = 19, range = 7, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 22, type = COMBAT_HEALING, minDamage = 110, maxDamage = 160, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="haste", interval = 2000, chance = 8, speedChange = 220, effect = CONST_ME_MAGIC_RED, target = false, duration = 1000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 1}, + {type = COMBAT_ENERGYDAMAGE, percent = 3}, + {type = COMBAT_EARTHDAMAGE, percent = 1}, + {type = COMBAT_FIREDAMAGE, percent = 1}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 1} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/moohtant.lua b/data/monster/humanoids/moohtant.lua new file mode 100644 index 00000000000..5561a378fe2 --- /dev/null +++ b/data/monster/humanoids/moohtant.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Moohtant") +local monster = {} + +monster.description = "a moohtant" +monster.experience = 2600 +monster.outfit = { + lookType = 607, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1044 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Oramond Mountain Hideout, Oramond Minotaur Camp (northern camp), \z + Underground Glooth Factory, Oramond Dungeon." + } + +monster.health = 3200 +monster.maxHealth = 3200 +monster.race = "blood" +monster.corpse = 23367 +monster.speed = 260 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 3 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 195}, + {id = 2152, chance = 58160, maxCount = 2}, + {id = 23571, chance = 2740, maxCount = 2}, + {id = 23570, chance = 1770}, + {id = 7591, chance = 7380, maxCount = 3}, + {id = 7590, chance = 7230, maxCount = 3}, + {id = 2666, chance = 6520}, + {id = 2147, chance = 4680, maxCount = 2}, + {id = 5878, chance = 4110}, + {id = 2145, chance = 4400, maxCount = 2}, + {id = 2214, chance = 2410}, + {id = 5911, chance = 900}, + {id = 23544, chance = 860}, + {id = 2154, chance = 710}, + {id = 7452, chance = 430}, + {id = 7427, chance = 280}, + {id = 9971, chance = 280}, + {id = 7401, chance = 280} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 110, attack = 50}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -230, length = 3, spread = 0, effect = CONST_ME_GROUNDSHAKER, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -200, radius = 3, effect = CONST_ME_GROUNDSHAKER, target = false}, + {name ="combat", interval = 2000, chance = 19, type = COMBAT_LIFEDRAIN, minDamage = -50, maxDamage = -225, radius = 5, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -150, maxDamage = -235, range = 7, radius = 4, shootEffect = CONST_ANI_LARGEROCK, effect = CONST_ME_EXPLOSIONAREA, target = true} +} + +monster.defenses = { + defense = 45, + armor = 40, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_HEALING, minDamage = 50, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 1}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 1}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 1} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/orc.lua b/data/monster/humanoids/orc.lua new file mode 100644 index 00000000000..e745a51e501 --- /dev/null +++ b/data/monster/humanoids/orc.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Orc") +local monster = {} + +monster.description = "an orc" +monster.experience = 25 +monster.outfit = { + lookType = 5, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 5 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Ulderek's Rock, Edron Orc Cave, Ancient Temple, Ice Islands, Venore Orc Cave, \z + Rookgaard Orc Fortress, Rookgaard main cave, Fibula Dungeon, Elvenbane, Foreigner Quarter, Zao Orc Land." + } + +monster.health = 70 +monster.maxHealth = 70 +monster.race = "blood" +monster.corpse = 5966 +monster.speed = 150 +monster.manaCost = 300 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grak brrretz!", yell = false}, + {text = "Grow truk grrrrr.", yell = false}, + {text = "Prek tars, dekklep zurk.", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 84810, maxCount = 14}, + {name = "sabre", chance = 5850}, + {name = "axe", chance = 4960}, + {name = "studded helmet", chance = 2950}, + {name = "studded armor", chance = 7860}, + {name = "studded shield", chance = 7300}, + {name = "meat", chance = 10160}, + {name = "orc tooth", chance = 210}, + {name = "orc leather", chance = 590}, + {id = 26654, chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -35} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/orc_berserker.lua b/data/monster/humanoids/orc_berserker.lua new file mode 100644 index 00000000000..2a3fc9373b2 --- /dev/null +++ b/data/monster/humanoids/orc_berserker.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Orc Berserker") +local monster = {} + +monster.description = "an orc berserker" +monster.experience = 195 +monster.outfit = { + lookType = 8, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 8 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Orc Fort, Dwacatra, Orc Peninsula, Elvenbane, Edron Orc Cave, Plains of Havoc, \z + below Point of No Return in Outlaw Camp, Maze of Lost Souls, Cyclopolis, Desert Dungeon, \z + Ancient Temple, Foreigner Quarter, Zao Orc Land." + } + +monster.health = 210 +monster.maxHealth = 210 +monster.race = "blood" +monster.corpse = 5980 +monster.speed = 250 +monster.manaCost = 590 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 60, + health = 40, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "KRAK ORRRRRRK!", yell = true} +} + +monster.loot = { + {id = 2044, chance = 830}, + {name = "gold coin", chance = 54000, maxCount = 12}, + {name = "battle axe", chance = 6110}, + {name = "halberd", chance = 7280}, + {name = "chain armor", chance = 890}, + {name = "ham", chance = 10400}, + {name = "hunting spear", chance = 5000}, + {name = "orc tooth", chance = 3000}, + {name = "orcish gear", chance = 9400}, + {name = "orc leather", chance = 4000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="speed", interval = 2000, chance = 15, speedChange = 290, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/orc_leader.lua b/data/monster/humanoids/orc_leader.lua new file mode 100644 index 00000000000..f407ec48e69 --- /dev/null +++ b/data/monster/humanoids/orc_leader.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Orc Leader") +local monster = {} + +monster.description = "an orc leader" +monster.experience = 270 +monster.outfit = { + lookType = 59, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 59 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Orc Fort, Edron Orc Cave, South of the temple in PoH, Maze of Lost Souls, Cyclopolis, Zao Orc Land." + } + +monster.health = 450 +monster.maxHealth = 450 +monster.race = "blood" +monster.corpse = 6001 +monster.speed = 230 +monster.manaCost = 640 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 15, + damage = 15, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ulderek futgyr human!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 28000, maxCount = 35}, + {name = "sword ring", chance = 3920}, + {name = "longsword", chance = 2800}, + {name = "throwing knife", chance = 9950, maxCount = 4}, + {name = "broadsword", chance = 610}, + {id = 2419, chance = 1860}, + {name = "plate armor", chance = 1650}, + {name = "warrior helmet", chance = 180}, + {name = "brass legs", chance = 3100}, + {name = "plate shield", chance = 1650}, + {name = "plate legs", chance = 440}, + {id = 2667, chance = 29400}, + {name = "brown mushroom", chance = 9650}, + {name = "royal spear", chance = 2400}, + {name = "health potion", chance = 550}, + {name = "orc tooth", chance = 1030}, + {name = "orc leather", chance = 19510}, + {name = "skull belt", chance = 2008} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -185}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -70, range = 7, shootEffect = CONST_ANI_THROWINGKNIFE, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/orc_marauder.lua b/data/monster/humanoids/orc_marauder.lua new file mode 100644 index 00000000000..82ef7b21b3c --- /dev/null +++ b/data/monster/humanoids/orc_marauder.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Orc Marauder") +local monster = {} + +monster.description = "an orc marauder" +monster.experience = 205 +monster.outfit = { + lookType = 342, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 614 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Zao Orc Land." + } + +monster.health = 235 +monster.maxHealth = 235 +monster.race = "blood" +monster.corpse = 11251 +monster.speed = 390 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grrrrrr", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 55000, maxCount = 90}, + {name = "obsidian lance", chance = 1110}, + {name = "orcish axe", chance = 1320}, + {name = "crossbow", chance = 440}, + {name = "bow", chance = 5210}, + {name = "meat", chance = 24600}, + {name = "silkweaver bow", chance = 70}, + {name = "orc tooth", chance = 3890}, + {name = "shaggy tail", chance = 10090}, + {name = "broken crossbow", chance = 4830}, + {name = "orc leather", chance = 3800} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -100, range = 7, shootEffect = CONST_ANI_ONYXARROW, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="speed", interval = 2000, chance = 15, speedChange = 350, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = -5}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 5}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/orc_rider.lua b/data/monster/humanoids/orc_rider.lua new file mode 100644 index 00000000000..521fca712d8 --- /dev/null +++ b/data/monster/humanoids/orc_rider.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Orc Rider") +local monster = {} + +monster.description = "an orc rider" +monster.experience = 110 +monster.outfit = { + lookType = 4, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 4 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Orc Fort, Orc Peninsula, near Dark Cathedral, Zao Orc Land." + } + +monster.health = 180 +monster.maxHealth = 180 +monster.race = "blood" +monster.corpse = 6010 +monster.speed = 260 +monster.manaCost = 490 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 30, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grrrrrrr", yell = false}, + {text = "Orc arga Huummmak!", yell = false} +} + +monster.loot = { + {id = 2050, chance = 980}, + {id = 2129, chance = 10210}, + {name = "gold coin", chance = 46000, maxCount = 81}, + {name = "obsidian lance", chance = 1100}, + {name = "orcish axe", chance = 6880}, + {name = "scale armor", chance = 610}, + {name = "battle shield", chance = 9900}, + {name = "meat", chance = 24000, maxCount = 3}, + {name = "orc tooth", chance = 2000}, + {name = "warwolf fur", chance = 9410}, + {name = "orc leather", chance = 9760} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -130} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="speed", interval = 2000, chance = 15, speedChange = 200, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/orc_shaman.lua b/data/monster/humanoids/orc_shaman.lua new file mode 100644 index 00000000000..2bc9b22193f --- /dev/null +++ b/data/monster/humanoids/orc_shaman.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Orc Shaman") +local monster = {} + +monster.description = "an orc shaman" +monster.experience = 110 +monster.outfit = { + lookType = 6, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 6 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Edron Orc Cave, Temple of Xayepocax, below Point of No Return in Outlaw Camp, Venore Orc Cave, \z + Maze of Lost Souls, Orc Fort, north west of Thais, Elvenbane, Plains Of Havoc, Foreigner Quarter, Zao Orc Land." + } + +monster.health = 115 +monster.maxHealth = 115 +monster.race = "blood" +monster.corpse = 5978 +monster.speed = 140 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Snake", chance = 20, interval = 2000, max = 4} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Huumans stinkk!", yell = false}, + {text = "Grak brrretz gulu.", yell = false} +} + +monster.loot = { + {id = 1958, chance = 520}, + {name = "gold coin", chance = 90000, maxCount = 5}, + {name = "wand of decay", chance = 1000}, + {name = "spear", chance = 4850}, + {name = "chain armor", chance = 8750}, + {name = "corncob", chance = 10600, maxCount = 2}, + {name = "orc tooth", chance = 2100}, + {name = "broken shamanic staff", chance = 10300}, + {name = "shamanic hood", chance = 6860}, + {name = "orc leather", chance = 4300}, + {id = 26654, chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -15}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -20, maxDamage = -31, range = 7, shootEffect = CONST_ANI_ENERGYBALL, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_FIREDAMAGE, minDamage = -5, maxDamage = -43, range = 7, radius = 1, shootEffect = CONST_ANI_FIRE, target = true} +} + +monster.defenses = { + defense = 10, + armor = 10, + {name ="combat", interval = 2000, chance = 60, type = COMBAT_HEALING, minDamage = 27, maxDamage = 43, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 25}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/orc_spearman.lua b/data/monster/humanoids/orc_spearman.lua new file mode 100644 index 00000000000..a67cb193280 --- /dev/null +++ b/data/monster/humanoids/orc_spearman.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Orc Spearman") +local monster = {} + +monster.description = "an orc spearman" +monster.experience = 38 +monster.outfit = { + lookType = 50, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 50 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Orc Fortress, Folda Dungeon, Edron Orc Cave and around it, Ancient Temple, \z + Venore Orc Cave, below the Point of No Return in Outlaw Camp, Plains of Havoc, \z + North of Thais in the Orc Peninsula, Elvenbane and Orc Camp in Foreigner Quarter. \z + Also found in Rookgaard West plains, Zao Orc Land." + } + +monster.health = 105 +monster.maxHealth = 105 +monster.race = "blood" +monster.corpse = 5996 +monster.speed = 176 +monster.manaCost = 310 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ugaar!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 25050, maxCount = 11}, + {name = "spear", chance = 17440}, + {name = "machete", chance = 3000}, + {name = "studded legs", chance = 10000}, + {name = "studded helmet", chance = 9000}, + {name = "meat", chance = 30200}, + {name = "orc tooth", chance = 150}, + {name = "orc leather", chance = 2300}, + {id = 26654, chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -25}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -30, range = 7, shootEffect = CONST_ANI_SPEAR, target = false} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/orc_warlord.lua b/data/monster/humanoids/orc_warlord.lua new file mode 100644 index 00000000000..93c048a1a9f --- /dev/null +++ b/data/monster/humanoids/orc_warlord.lua @@ -0,0 +1,140 @@ +local mType = Game.createMonsterType("Orc Warlord") +local monster = {} + +monster.description = "an orc warlord" +monster.experience = 670 +monster.outfit = { + lookType = 2, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 2 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Orc Fortress, Foreigner Quarter, Zao Orc Land." + } + +monster.health = 950 +monster.maxHealth = 950 +monster.race = "blood" +monster.corpse = 6008 +monster.speed = 234 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 15, + damage = 15, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ranat Ulderek!", yell = false}, + {text = "Orc buta bana!", yell = false}, + {text = "Ikem rambo zambo!", yell = false}, + {text = "Fetchi Maruk Buta", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 18000, maxCount = 45}, + {name = "stealth ring", chance = 90}, + {name = "gold ring", chance = 30}, + {name = "protection amulet", chance = 2190}, + {name = "two handed sword", chance = 1680}, + {name = "throwing star", chance = 13920, maxCount = 18}, + {id = 2419, chance = 3450}, + {name = "orcish axe", chance = 5400}, + {name = "dragon hammer", chance = 320}, + {name = "plate armor", chance = 5210}, + {name = "brass armor", chance = 740}, + {name = "dark helmet", chance = 1260}, + {name = "crusader helmet", chance = 280}, + {name = "plate legs", chance = 4280}, + {id = 2667, chance = 10800, maxCount = 2}, + {name = "hunting spear", chance = 5260}, + {id = 7395, chance = 50}, + {name = "health potion", chance = 470}, + {name = "magma boots", chance = 280}, + {name = "orc tooth", chance = 9640}, + {name = "broken helmet", chance = 24350}, + {name = "orc leather", chance = 20620}, + {name = "skull belt", chance = 4610} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, range = 7, shootEffect = CONST_ANI_THROWINGSTAR, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="invisible", interval = 2000, chance = 5, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/orc_warrior.lua b/data/monster/humanoids/orc_warrior.lua new file mode 100644 index 00000000000..ef2eb2779d4 --- /dev/null +++ b/data/monster/humanoids/orc_warrior.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Orc Warrior") +local monster = {} + +monster.description = "an orc warrior" +monster.experience = 50 +monster.outfit = { + lookType = 7, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 7 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Ancient Temple in Thais, Orc Fort, below Point of No Return in Outlaw Camp and inside a \z + mountain north of it, Orc Peninsula, Folda, Edron Orc cave, Maze of Lost Souls, Elvenbane Castle, \z + Foreigner Quarter, Zao Orc Land." + } + +monster.health = 125 +monster.maxHealth = 125 +monster.race = "blood" +monster.corpse = 5979 +monster.speed = 190 +monster.manaCost = 360 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 11, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grow truk grrrr.", yell = false}, + {text = "Trak grrrr brik.", yell = false}, + {text = "Alk!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 65000, maxCount = 15}, + {name = "poison dagger", chance = 120}, + {name = "chain armor", chance = 7360}, + {name = "copper shield", chance = 560}, + {name = "meat", chance = 15000}, + {name = "orc tooth", chance = 700}, + {name = "broken helmet", chance = 10800}, + {name = "orc leather", chance = 4000}, + {name = "skull belt", chance = 980}, + {id = 26654, chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -60} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/pirat_cutthroat.lua b/data/monster/humanoids/pirat_cutthroat.lua new file mode 100644 index 00000000000..0a31158f958 --- /dev/null +++ b/data/monster/humanoids/pirat_cutthroat.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Pirat Cutthroat") +local monster = {} + +monster.description = "a pirat cutthroat" +monster.experience = 1800 +monster.outfit = { + lookType = 1346, + lookHead = 2, + lookBody = 96, + lookLegs = 78, + lookFeet = 96, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 2036 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Pirate Mine, The Wreckoning." + } + +monster.health = 2600 +monster.maxHealth = 2600 +monster.race = "blood" +monster.corpse = 40207 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 0 +} + +monster.loot = { + {name = "great health potion", chance = 44810, maxCount = 4}, + {name = "ice rapier", chance = 25950}, + {name = "knight axe", chance = 12500}, + {name = "crystal sword", chance = 19420}, + {name = "pirate coin", chance = 17810, maxCount = 10}, + {name = "crowbar", chance = 7810}, + {name = "knight armor", chance = 9550}, + {name = "focus cape", chance = 8250}, + {name = "pirat's tail", chance = 2120}, + {name = "shark fins", chance = 1750} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_PHYSICALDAMAGE, minDamage = -110, maxDamage = -190, length = 4, spread = 3, effect = CONST_ME_GROUNDSHAKER, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -120, maxDamage = -175, radius = 3, effect = CONST_ME_ENERGYHIT, target = false} +} + +monster.defenses = { + defense = 68, + armor = 72 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/pirat_scoundrel.lua b/data/monster/humanoids/pirat_scoundrel.lua new file mode 100644 index 00000000000..cdc18620f98 --- /dev/null +++ b/data/monster/humanoids/pirat_scoundrel.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Pirat Scoundrel") +local monster = {} + +monster.description = "a pirat scoundrel" +monster.experience = 1600 +monster.outfit = { + lookType = 1346, + lookHead = 97, + lookBody = 119, + lookLegs = 80, + lookFeet = 80, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 2037 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Pirate Mine, The Wreckoning." + } + +monster.health = 2200 +monster.maxHealth = 2200 +monster.race = "blood" +monster.corpse = 40215 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 0 +} + +monster.loot = { + {name = "great mana potion", chance = 44810}, + {name = "wand of inferno", chance = 12500}, + {id = 40423, chance = 19420}, + {name = "pirate coin", chance = 17810, maxCount = 10}, + {name = "pirat's tail", chance = 2120}, + {name = "springsprout rod", chance = 9550}, + {name = "wand of starstorm", chance = 1750}, + {name = "wand of voodoo", chance = 1450} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -110, maxDamage = -180, range = 7, radius = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -100, maxDamage = -140, radius = 3, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -90, maxDamage = -120, radius = 3, effect = CONST_ME_ENERGYHIT, target = false} +} + +monster.defenses = { + defense = 45, + armor = 60 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 26}, + {type = COMBAT_EARTHDAMAGE, percent = -30}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/running_elite_orc_guard.lua b/data/monster/humanoids/running_elite_orc_guard.lua new file mode 100644 index 00000000000..3884c1380f1 --- /dev/null +++ b/data/monster/humanoids/running_elite_orc_guard.lua @@ -0,0 +1,96 @@ +local mType = Game.createMonsterType("Running Elite Orc Guard") +local monster = {} + +monster.description = "a running elite orc guard" +monster.experience = 0 +monster.outfit = { + lookType = 2, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 950 +monster.maxHealth = 950 +monster.race = "blood" +monster.corpse = 6008 +monster.speed = 234 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 950, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "UAAAAH FETCHI!", yell = false} +} + +monster.loot = {} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = 0} +} + +monster.defenses = { + defense = 35, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = true} +} + +mType:register(monster) diff --git a/data/monster/humanoids/shaper_matriarch.lua b/data/monster/humanoids/shaper_matriarch.lua new file mode 100644 index 00000000000..26b1c6f4fca --- /dev/null +++ b/data/monster/humanoids/shaper_matriarch.lua @@ -0,0 +1,137 @@ +local mType = Game.createMonsterType("Shaper Matriarch") +local monster = {} + +monster.description = "a shaper matriarch" +monster.experience = 1650 +monster.outfit = { + lookType = 933, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1394 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Old Masonry, small dungeon under the Formorgar Mines." + } + +monster.health = 2000 +monster.maxHealth = 2000 +monster.race = "blood" +monster.corpse = 27739 +monster.speed = 260 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Tar Marra Zik Tazz!", yell = false} +} + +monster.loot = { + {id = 27058, chance = 6000}, + {id = 2144, chance = 2500}, + {id = 27051, chance = 18000, maxCount = 2}, + {id = 27053, chance = 15000}, + {id = 2792, chance = 6800}, + {id = 27060, chance = 4300}, + {id = 2148, chance = 50320, maxCount = 150}, + {id = 2152, chance = 80000, maxCount = 2}, + {id = 27630, chance = 2800}, + {id = 27054, chance = 20000}, + {id = 2214, chance = 1300}, + {id = 9822, chance = 4500}, + {id = 2229, chance = 10000}, + {id = 2147, chance = 4000}, + {id = 2197, chance = 1500}, + {id = 7589, chance = 15000}, + {id = 27055, chance = 15000}, + {id = 2188, chance = 2000}, + {id = 8922, chance = 800}, + {id = 2031, chance = 2000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 15, attack = 25}, + {name ="combat", interval = 2000, chance = 35, type = COMBAT_PHYSICALDAMAGE, minDamage = -35, maxDamage = -160, range = 7, shootEffect = CONST_ANI_EARTH, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 35, type = COMBAT_PHYSICALDAMAGE, minDamage = -35, maxDamage = -160, radius = 3, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 35, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -400, length = 6, spread = 3, effect = CONST_ME_MORTAREA, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 400, maxDamage = 500, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/soul-broken_harbinger.lua b/data/monster/humanoids/soul-broken_harbinger.lua new file mode 100644 index 00000000000..dfec2c053ce --- /dev/null +++ b/data/monster/humanoids/soul-broken_harbinger.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Soul-Broken Harbinger") +local monster = {} + +monster.description = "a Soul-Broken Harbinger" +monster.experience = 5800 +monster.outfit = { + lookType = 1137, + lookHead = 124, + lookBody = 31, + lookLegs = 17, + lookFeet = 81, + lookAddons = 3, + lookMount = 0 +} + +monster.raceId = 1734 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Court of Winter." + } + +monster.health = 6300 +monster.maxHealth = 6300 +monster.race = "blood" +monster.corpse = 34775 +monster.speed = 420 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 100000, maxCount = 12}, + {id = 34696, chance = 15750, maxCount = 3}, + {name = "Dream Essence Egg", chance = 13700}, + {name = "Elvish Talisman", chance = 4790}, + {name = "Knight Legs", chance = 4450}, + {name = "Glacier Kilt", chance = 4110}, + {name = "Glacier Shoes", chance = 3770}, + {name = "Ice Rapier", chance = 3770}, + {name = "Spellbook of Mind Control", chance = 2400}, + {name = "Crown Shield", chance = 1710}, + {name = "Wood Cape", chance = 1710}, + {id = 26185, chance = 1370}, + {name = "Tower Shield", chance = 680}, + {id = 26199, chance = 680} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -240}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -120, range = 7, shootEffect = CONST_ANI_ARROW, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.reflects = { + {type = COMBAT_ICEDAMAGE, percent = 70} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 55}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/swamp_troll.lua b/data/monster/humanoids/swamp_troll.lua new file mode 100644 index 00000000000..44b3851b1a4 --- /dev/null +++ b/data/monster/humanoids/swamp_troll.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Swamp Troll") +local monster = {} + +monster.description = "a swamp troll" +monster.experience = 25 +monster.outfit = { + lookType = 76, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 76 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Port Hope Swamp Trolls, Venore Swamp Troll Cave, all around north area of Port Hope, \z + small spawn north-west of Venore and in cave south-east of Thais, also one in Foreigner Quarter." + } + +monster.health = 55 +monster.maxHealth = 55 +monster.race = "venom" +monster.corpse = 6018 +monster.speed = 128 +monster.manaCost = 320 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grrrr", yell = false}, + {text = "Groar!", yell = false}, + {text = "Me strong! Me ate spinach!", yell = false} +} + +monster.loot = { + {id = 2050, chance = 15000}, + {name = "gold coin", chance = 50300, maxCount = 5}, + {name = "mouldy cheese", chance = 10000}, + {name = "spear", chance = 13000}, + {name = "fishing rod", chance = 60}, + {name = "leather boots", chance = 9500}, + {id = 2667, chance = 60000}, + {name = "troll green", chance = 1200}, + {id = 5901, chance = 2140}, + {name = "swamp grass", chance = 3100}, + {name = "medicine pouch", chance = 2160} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -13, condition = {type = CONDITION_POISON, totalDamage = 1, interval = 4000}} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 5}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/troll.lua b/data/monster/humanoids/troll.lua new file mode 100644 index 00000000000..9a5f1bac304 --- /dev/null +++ b/data/monster/humanoids/troll.lua @@ -0,0 +1,127 @@ +local mType = Game.createMonsterType("Troll") +local monster = {} + +monster.description = "a troll" +monster.experience = 20 +monster.outfit = { + lookType = 15, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 15 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "In many dungeons around Tibia like the troll cave in Thais, south of Carlin (out the east \z + exit and down the hole), Island of Destiny, Edron Troll Cave, and in Ab'Dendriel. Also found in Rookgaard." + } + +monster.health = 50 +monster.maxHealth = 50 +monster.race = "blood" +monster.corpse = 5960 +monster.speed = 126 +monster.manaCost = 290 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grrr", yell = false}, + {text = "Groar", yell = false}, + {text = "Gruntz!", yell = false}, + {text = "Hmmm, bugs", yell = false}, + {text = "Hmmm, dogs", yell = false} +} + +monster.loot = { + {id = 2120, chance = 7950}, + {name = "gold coin", chance = 65300, maxCount = 12}, + {name = "silver amulet", chance = 80}, + {name = "hand axe", chance = 18000}, + {name = "spear", chance = 13000}, + {name = "studded club", chance = 5000}, + {name = "leather helmet", chance = 12000}, + {id = 2512, chance = 4730}, + {name = "leather boots", chance = 10000}, + {name = "meat", chance = 15000}, + {name = "bunch of troll hair", chance = 1000}, + {id = 26654, chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -15} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 25}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/troll_champion.lua b/data/monster/humanoids/troll_champion.lua new file mode 100644 index 00000000000..569a914efa0 --- /dev/null +++ b/data/monster/humanoids/troll_champion.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Troll Champion") +local monster = {} + +monster.description = "a troll champion" +monster.experience = 40 +monster.outfit = { + lookType = 281, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 392 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Edron Troll-Goblin Peninsula, Ab'dendriel Shadow Caves, Thais South-East Troll Caves, \z + Dusalk's Troll Clan Cave, Island of Destiny in Paladin's guild." + } + +monster.health = 75 +monster.maxHealth = 75 +monster.race = "blood" +monster.corpse = 7926 +monster.speed = 138 +monster.manaCost = 340 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Meee maity!", yell = false}, + {text = "Grrrr", yell = false}, + {text = "Whaaaz up!?", yell = false}, + {text = "Gruntz!", yell = false}, + {text = "Groar", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 64000, maxCount = 12}, + {name = "silver amulet", chance = 230}, + {name = "spear", chance = 25000}, + {name = "studded club", chance = 5450}, + {id = 2512, chance = 6000}, + {name = "arrow", chance = 5450, maxCount = 5}, + {name = "leather boots", chance = 9000}, + {name = "meat", chance = 9650}, + {name = "bunch of troll hair", chance = 3000}, + {name = "trollroot", chance = 750} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -35} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/troll_guard.lua b/data/monster/humanoids/troll_guard.lua new file mode 100644 index 00000000000..32c60390cdf --- /dev/null +++ b/data/monster/humanoids/troll_guard.lua @@ -0,0 +1,114 @@ +local mType = Game.createMonsterType("Troll Guard") +local monster = {} + +monster.description = "a troll guard" +monster.experience = 25 +monster.outfit = { + lookType = 281, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 745 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 30, + Stars = 2, + Occurrence = 3, + Locations = "Rookgaard's central cave in the new western Troll tunnel, \z + north-west of Carlin during raids and Thais Knights' Guild arena during raids on Kingsday." + } + +monster.health = 60 +monster.maxHealth = 60 +monster.race = "blood" +monster.corpse = 7926 +monster.speed = 126 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 17, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2120, chance = 10000}, + {name = "gold coin", chance = 58000, maxCount = 12}, + {name = "studded club", chance = 3000}, + {name = "meat", chance = 14000, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -15} +} + +monster.defenses = { + defense = 2, + armor = 1 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/troll_legionnaire.lua b/data/monster/humanoids/troll_legionnaire.lua new file mode 100644 index 00000000000..b3c164cddf6 --- /dev/null +++ b/data/monster/humanoids/troll_legionnaire.lua @@ -0,0 +1,118 @@ +local mType = Game.createMonsterType("Troll Legionnaire") +local monster = {} + +monster.description = "a troll legionnaire" +monster.experience = 140 +monster.outfit = { + lookType = 53, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 541 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Old Beregar mines. In group with Furious Trolls almost all the time." + } + +monster.health = 210 +monster.maxHealth = 210 +monster.race = "blood" +monster.corpse = 5998 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 30, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Attack!", yell = false}, + {text = "Graaaaar!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 92000, maxCount = 155}, + {name = "stealth ring", chance = 560}, + {name = "throwing star", chance = 28000, maxCount = 10}, + {name = "frosty ear of a troll", chance = 5120} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -35}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -130, range = 6, shootEffect = CONST_ANI_THROWINGSTAR, target = true} +} + +monster.defenses = { + defense = 9, + armor = 7, + {name ="invisible", interval = 2000, chance = 18, effect = CONST_ME_MAGIC_BLUE}, + {name ="combat", interval = 2000, chance = 28, type = COMBAT_HEALING, minDamage = 17, maxDamage = 25, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/twisted_shaper.lua b/data/monster/humanoids/twisted_shaper.lua new file mode 100644 index 00000000000..d2e50fc1812 --- /dev/null +++ b/data/monster/humanoids/twisted_shaper.lua @@ -0,0 +1,134 @@ +local mType = Game.createMonsterType("Twisted Shaper") +local monster = {} + +monster.description = "a twisted shaper" +monster.experience = 1750 +monster.outfit = { + lookType = 932, + lookHead = 68, + lookBody = 0, + lookLegs = 0, + lookFeet = 94, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1322 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Astral Shaper Dungeon, Old Masonry, small dungeon under the Formorgar Mines." + } + +monster.health = 2500 +monster.maxHealth = 2500 +monster.race = "blood" +monster.corpse = 27736 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ti Jezz Kur Tar!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 80320, maxCount = 222}, + {id = 2152, chance = 50320, maxCount = 4}, + {id = 2789, chance = 5000, maxCount = 2}, + {id = 2666, chance = 10000, maxCount = 2}, + {id = 27051, chance = 20000, maxCount = 2}, + {id = 5022, chance = 5000, maxCount = 2}, + {id = 2147, chance = 5600, maxCount = 5}, + {id = 24849, chance = 4900}, + {id = 27055, chance = 14580}, + {id = 7591, chance = 7300}, + {id = 2167, chance = 7660}, + {id = 2189, chance = 3810}, + {id = 2171, chance = 370}, + {id = 27052, chance = 17000}, + {id = 27053, chance = 20000}, + {id = 27058, chance = 4000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = -50, maxDamage = -100, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 2000, chance = 35, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -100, length = 5, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -50, maxDamage = -100, radius = 7, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 9, speedChange = -440, effect = CONST_ME_GIANTICE, target = true, duration = 7000} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 400, maxDamage = 500, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -25}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/worm_priestess.lua b/data/monster/humanoids/worm_priestess.lua new file mode 100644 index 00000000000..c69dfc54970 --- /dev/null +++ b/data/monster/humanoids/worm_priestess.lua @@ -0,0 +1,141 @@ +local mType = Game.createMonsterType("Worm Priestess") +local monster = {} + +monster.description = "a worm priestess" +monster.experience = 1500 +monster.outfit = { + lookType = 613, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1053 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Oramond/Southern Plains, Minotaur Hills, \z + Oramond Dungeon (depending on Magistrate votes), Underground Glooth Factory, Oramond Fury Dungeon." + } + +monster.health = 1100 +monster.maxHealth = 1100 +monster.race = "blood" +monster.corpse = 23470 +monster.speed = 198 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 200, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "An enemy of the worm shall become his food!", yell = false}, + {text = "The great worm will swallow you!", yell = false}, + {text = "From the earthy depths he comes and brings freedom!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 150}, + {id = 2152, chance = 41130, maxCount = 3}, + {id = 12429, chance = 15850}, + {id = 7589, chance = 12380, maxCount = 3}, + {id = 2182, chance = 11470}, + {id = 7425, chance = 5210}, + {id = 2050, chance = 4760}, + {id = 5878, chance = 4640}, + {id = 12428, chance = 2940, maxCount = 2}, + {id = 2150, chance = 2500, maxCount = 2}, + {id = 2149, chance = 2370, maxCount = 2}, + {id = 2147, chance = 2200, maxCount = 2}, + {id = 9970, chance = 2460, maxCount = 2}, + {id = 2145, chance = 2430, maxCount = 2}, + {id = 5911, chance = 1350}, + {id = 5910, chance = 1400}, + {id = 5912, chance = 1820}, + {id = 8910, chance = 1590}, + {id = 2154, chance = 560}, + {id = 2156, chance = 430}, + {id = 7401, chance = 160} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 50}, + {name ="combat", interval = 2000, chance = 24, type = COMBAT_LIFEDRAIN, minDamage = -50, maxDamage = -130, range = 7, shootEffect = CONST_ANI_SMALLSTONE, target = true}, + {name ="combat", interval = 2000, chance = 16, type = COMBAT_ENERGYDAMAGE, minDamage = -100, maxDamage = -165, range = 4, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_POISONAREA, target = false}, + {name ="worm priestess paralyze", interval = 2000, chance = 12, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -115, maxDamage = -200, range = 7, radius = 3, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_EARTHDAMAGE, minDamage = -200, maxDamage = -300, range = 7, radius = 4, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_HITBYPOISON, target = true} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_HEALING, minDamage = 100, maxDamage = 150, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="haste", interval = 2000, chance = 9, speedChange = 198, effect = CONST_ME_MAGIC_RED, target = false, duration = 1000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 25}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humanoids/young_troll.lua b/data/monster/humanoids/young_troll.lua new file mode 100644 index 00000000000..247b9734357 --- /dev/null +++ b/data/monster/humanoids/young_troll.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Young Troll") +local monster = {} + +monster.description = "a young troll" +monster.experience = 12 +monster.outfit = { + lookType = 15, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 30 +monster.maxHealth = 30 +monster.race = "blood" +monster.corpse = 5960 +monster.speed = 116 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hmmm, dogs", yell = false}, + {text = "Gruntz!", yell = false} +} + +monster.loot = { + {id = 2120, chance = 10000}, + {name = "gold coin", chance = 58000, maxCount = 12}, + {name = "meat", chance = 14000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -10} +} + +monster.defenses = { + defense = 2, + armor = 1 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/acolyte_of_darkness.lua b/data/monster/humans/acolyte_of_darkness.lua new file mode 100644 index 00000000000..18185cb4c18 --- /dev/null +++ b/data/monster/humans/acolyte_of_darkness.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Acolyte of Darkness") +local monster = {} + +monster.description = "an acolyte of darkness" +monster.experience = 200 +monster.outfit = { + lookType = 9, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 578 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 30, + Stars = 2, + Occurrence = 3, + Locations = "Drefia." + } + +monster.health = 325 +monster.maxHealth = 325 +monster.race = "blood" +monster.corpse = 20455 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Mine is the power of the night!", yell = false}, + {text = "You can not hope to stop us all!", yell = false}, + {text = "The power of darkness is with me!", yell = false} +} + +monster.loot = { + {name = "midnight shard", chance = 1300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -120, condition = {type = CONDITION_POISON, totalDamage = 160, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -60, maxDamage = -120, range = 1, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -65, maxDamage = -120, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 19, + armor = 19, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 50, maxDamage = 80, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 25}, + {type = COMBAT_DEATHDAMAGE , percent = -100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/acolyte_of_the_cult.lua b/data/monster/humans/acolyte_of_the_cult.lua new file mode 100644 index 00000000000..f29bbddd6bf --- /dev/null +++ b/data/monster/humans/acolyte_of_the_cult.lua @@ -0,0 +1,135 @@ +local mType = Game.createMonsterType("Acolyte of the Cult") +local monster = {} + +monster.description = "an acolyte of the cult" +monster.experience = 300 +monster.outfit = { + lookType = 194, + lookHead = 114, + lookBody = 121, + lookLegs = 121, + lookFeet = 57, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 253 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Goroma, Deeper Cult Cave, Formorgar Mines, Magician Quarter, Forbidden Temple." + } + +monster.health = 390 +monster.maxHealth = 390 +monster.race = "blood" +monster.corpse = 20319 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Skeleton", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Praise the voodoo!", yell = false}, + {text = "Power to the cult!", yell = false}, + {text = "Feel the power of the cult!", yell = false} +} + +monster.loot = { + {id = 1962, chance = 730}, + {name = "gold coin", chance = 66940, maxCount = 40}, + {name = "small emerald", chance = 550}, + {name = "life ring", chance = 560}, + {name = "terra rod", chance = 250}, + {name = "dragon necklace", chance = 1050}, + {name = "morning star", chance = 4990}, + {name = "pirate voodoo doll", chance = 1060}, + {id = 6088, chance = 480}, + {name = "cultish robe", chance = 8070}, + {name = "cultish symbol", chance = 40}, + {name = "rope belt", chance = 10420}, + {name = "broken key ring", chance = 60} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100, condition = {type = CONDITION_POISON, totalDamage = 2, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -60, maxDamage = -120, range = 7, radius = 1, shootEffect = CONST_ANI_POISON, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="drunk", interval = 2000, chance = 5, range = 7, radius = 1, shootEffect = CONST_ANI_HOLY, effect = CONST_ME_HOLYDAMAGE, target = true, duration = 3000} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 40, maxDamage = 60, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/adept_of_the_cult.lua b/data/monster/humans/adept_of_the_cult.lua new file mode 100644 index 00000000000..9e20a1257b3 --- /dev/null +++ b/data/monster/humans/adept_of_the_cult.lua @@ -0,0 +1,139 @@ +local mType = Game.createMonsterType("Adept of the Cult") +local monster = {} + +monster.description = "an adept of the cult" +monster.experience = 400 +monster.outfit = { + lookType = 194, + lookHead = 114, + lookBody = 94, + lookLegs = 94, + lookFeet = 57, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 254 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Goroma, Liberty Bay's deeper cult dungeon, Formorgar Mines, Magician Quarter, Forbidden Temple." + } + +monster.health = 430 +monster.maxHealth = 430 +monster.race = "blood" +monster.corpse = 20311 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Ghoul", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Feel the power of the cult!", yell = false}, + {text = "Praise the voodoo!", yell = false}, + {text = "Power to the cult!", yell = false} +} + +monster.loot = { + {id = 1962, chance = 940}, + {name = "small ruby", chance = 320}, + {name = "gold coin", chance = 65520, maxCount = 60}, + {id = 2169, chance = 420}, + {name = "silver amulet", chance = 1020}, + {name = "hailstorm rod", chance = 220}, + {name = "clerical mace", chance = 1260}, + {name = "red robe", chance = 80}, + {name = "pirate voodoo doll", chance = 1730}, + {id = 6089, chance = 700}, + {name = "lunar staff", chance = 120}, + {name = "amber staff", chance = 680}, + {name = "cultish robe", chance = 10080}, + {name = "cultish symbol", chance = 90}, + {name = "rope belt", chance = 10000}, + {name = "broken key ring", chance = 120} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -90, condition = {type = CONDITION_POISON, totalDamage = 2, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -70, maxDamage = -150, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true}, + {name ="drunk", interval = 2000, chance = 10, range = 7, radius = 1, shootEffect = CONST_ANI_HOLY, effect = CONST_ME_HOLYDAMAGE, target = true, duration = 4000} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_HEALING, minDamage = 45, maxDamage = 60, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_YELLOW_RINGS} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/adventurer.lua b/data/monster/humans/adventurer.lua new file mode 100644 index 00000000000..077de69724c --- /dev/null +++ b/data/monster/humans/adventurer.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("Adventurer") +local monster = {} + +monster.description = "an adventurer" +monster.experience = 0 +monster.outfit = { + lookType = 129, + lookHead = 92, + lookBody = 15, + lookLegs = 92, + lookFeet = 82, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 922 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Venore swamp." + } + +monster.health = 65 +monster.maxHealth = 65 +monster.race = "blood" +monster.corpse = 20315 +monster.speed = 106 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 65, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/amazon.lua b/data/monster/humans/amazon.lua new file mode 100644 index 00000000000..13a1c0dea9a --- /dev/null +++ b/data/monster/humans/amazon.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Amazon") +local monster = {} + +monster.description = "an amazon" +monster.experience = 60 +monster.outfit = { + lookType = 137, + lookHead = 113, + lookBody = 120, + lookLegs = 95, + lookFeet = 115, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 77 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Venore Amazon Camp, Carlin Amazon Camp, Amazon Tower, east of Carlin, underneath the Fields of Glory, \z + west of Venore, Oasis Tomb, on the smallest of the Laguna Islands, Foreigner Quarter and Trade Quarter." + } + +monster.health = 110 +monster.maxHealth = 110 +monster.race = "blood" +monster.corpse = 20323 +monster.speed = 172 +monster.manaCost = 390 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Yeeee ha!", yell = false}, + {text = "Your head shall be mine!", yell = false}, + {text = "Your head will be mine!", yell = false} +} + +monster.loot = { + {name = "dagger", chance = 80000}, + {id = 2229, chance = 80000, maxCount = 2}, + {name = "gold coin", chance = 40000, maxCount = 20}, + {name = "brown bread", chance = 30000}, + {name = "sabre", chance = 23000}, + {name = "girlish hair decoration", chance = 10000}, + {name = "protective charm", chance = 5200}, + {id = 2050, chance = 1000}, + {name = "crystal necklace", chance = 260}, + {name = "small ruby", chance = 130} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -45}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -40, range = 5, shootEffect = CONST_ANI_THROWINGKNIFE, target = false} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/angry_adventurer.lua b/data/monster/humans/angry_adventurer.lua new file mode 100644 index 00000000000..a4fec87b187 --- /dev/null +++ b/data/monster/humans/angry_adventurer.lua @@ -0,0 +1,96 @@ +local mType = Game.createMonsterType("Angry Adventurer") +local monster = {} + +monster.description = "an angry adventurer" +monster.experience = 50 +monster.outfit = { + lookType = 129, + lookHead = 92, + lookBody = 15, + lookLegs = 92, + lookFeet = 82, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 65 +monster.maxHealth = 65 +monster.race = "blood" +monster.corpse = 20315 +monster.speed = 195 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -20} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/assassin.lua b/data/monster/humans/assassin.lua new file mode 100644 index 00000000000..7ad79dff658 --- /dev/null +++ b/data/monster/humans/assassin.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Assassin") +local monster = {} + +monster.description = "an assassin" +monster.experience = 105 +monster.outfit = { + lookType = 152, + lookHead = 114, + lookBody = 95, + lookLegs = 95, + lookFeet = 95, + lookAddons = 3, + lookMount = 0 +} + +monster.raceId = 224 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 50, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Dark Cathedral, Trade Quarter, Factory Quarter, Foreigner Quarter." + } + +monster.health = 175 +monster.maxHealth = 175 +monster.race = "blood" +monster.corpse = 20327 +monster.speed = 224 +monster.manaCost = 450 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 20, + damage = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Die!", yell = false}, + {text = "Feel the hand of death!", yell = false}, + {text = "You are on my deathlist!", yell = false} +} + +monster.loot = { + {id = 2050, chance = 29980, maxCount = 2}, + {name = "small diamond", chance = 220}, + {name = "gold coin", chance = 83210, maxCount = 50}, + {name = "gold coin", chance = 7250, maxCount = 14}, + {name = "knife", chance = 9500}, + {name = "combat knife", chance = 4000}, + {name = "steel helmet", chance = 3230}, + {name = "steel shield", chance = 970}, + {name = "plate shield", chance = 1900}, + {name = "battle shield", chance = 1600}, + {name = "leopard armor", chance = 480}, + {name = "horseman helmet", chance = 230}, + {name = "viper star", chance = 4200, maxCount = 7} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -120}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -40, range = 7, shootEffect = CONST_ANI_THROWINGSTAR, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -120, maxDamage = -160, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/bandit.lua b/data/monster/humans/bandit.lua new file mode 100644 index 00000000000..e0d93dd424f --- /dev/null +++ b/data/monster/humans/bandit.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Bandit") +local monster = {} + +monster.description = "a bandit" +monster.experience = 65 +monster.outfit = { + lookType = 129, + lookHead = 58, + lookBody = 59, + lookLegs = 45, + lookFeet = 114, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 223 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Dark Cathedral, Tiquanda Bandit Caves, Outlaw Camp, mountain pass west of Ankrahmun, \z + Tyrsung, Thais Bandit Cave, Formorgar Mines. Also summoned by Gamel." + } + +monster.health = 245 +monster.maxHealth = 245 +monster.race = "blood" +monster.corpse = 20331 +monster.speed = 180 +monster.manaCost = 450 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 25, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Your money or your life!", yell = false}, + {text = "Hand me your purse!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 49000, maxCount = 30}, + {name = "axe", chance = 29900}, + {name = "mace", chance = 10100}, + {name = "chain helmet", chance = 5000}, + {name = "iron helmet", chance = 520}, + {name = "brass armor", chance = 2500}, + {name = "brass shield", chance = 16800}, + {name = "leather legs", chance = 15500}, + {name = "tomato", chance = 7630, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -45} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/barbarian_bloodwalker.lua b/data/monster/humans/barbarian_bloodwalker.lua new file mode 100644 index 00000000000..24ad84610dd --- /dev/null +++ b/data/monster/humans/barbarian_bloodwalker.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Barbarian Bloodwalker") +local monster = {} + +monster.description = "a barbarian bloodwalker" +monster.experience = 195 +monster.outfit = { + lookType = 255, + lookHead = 114, + lookBody = 132, + lookLegs = 132, + lookFeet = 132, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 323 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Krimhorn, Bittermor, Ragnir, Arena and Zoo Quarter inside the Arena." + } + +monster.health = 305 +monster.maxHealth = 305 +monster.race = "blood" +monster.corpse = 20335 +monster.speed = 236 +monster.manaCost = 590 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "YAAAHEEE!", yell = false}, + {text = "SLAUGHTER!", yell = false}, + {text = "CARNAGE!", yell = false}, + {text = "You can run but you can't hide", yell = false} +} + +monster.loot = { + {id = 2044, chance = 8280}, + {name = "gold coin", chance = 55310, maxCount = 12}, + {name = "battle axe", chance = 5910}, + {name = "halberd", chance = 6740}, + {name = "chain helmet", chance = 10520}, + {name = "chain armor", chance = 10420}, + {name = "ham", chance = 4900}, + {name = "beastslayer axe", chance = 380}, + {name = "red piece of cloth", chance = 540}, + {name = "shard", chance = 300}, + {name = "fur boots", chance = 100}, + {name = "health potion", chance = 980} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -240} +} + +monster.defenses = { + defense = 0, + armor = 9, + {name ="speed", interval = 2000, chance = 15, speedChange = 240, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = -5}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/barbarian_brutetamer.lua b/data/monster/humans/barbarian_brutetamer.lua new file mode 100644 index 00000000000..0c5155fa031 --- /dev/null +++ b/data/monster/humans/barbarian_brutetamer.lua @@ -0,0 +1,134 @@ +local mType = Game.createMonsterType("Barbarian Brutetamer") +local monster = {} + +monster.description = "a barbarian brutetamer" +monster.experience = 90 +monster.outfit = { + lookType = 264, + lookHead = 78, + lookBody = 116, + lookLegs = 95, + lookFeet = 121, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 332 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Krimhorn, Bittermor, Ragnir, and Fenrock." + } + +monster.health = 145 +monster.maxHealth = 145 +monster.race = "blood" +monster.corpse = 20339 +monster.speed = 178 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "War Wolf", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "To me, creatures of the wild!", yell = false}, + {text = "Feel the power of the beast!", yell = false}, + {text = "My instincts tell me about your cowardice.", yell = false} +} + +monster.loot = { + {id = 1958, chance = 4750}, + {name = "gold coin", chance = 90230, maxCount = 15}, + {id = 2401, chance = 6550}, + {name = "chain armor", chance = 9300}, + {name = "corncob", chance = 10940, maxCount = 2}, + {name = "hunting spear", chance = 5200}, + {name = "fur bag", chance = 7590}, + {name = "brutetamer's staff", chance = 340}, + {name = "fur boots", chance = 170}, + {name = "mammoth fur cape", chance = 150}, + {name = "mammoth fur shorts", chance = 90}, + {name = "mana potion", chance = 580} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -20}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -34, range = 7, radius = 1, shootEffect = CONST_ANI_SNOWBALL, target = true}, + {name ="barbarian brutetamer skill reducer", interval = 2000, chance = 15, range = 5, target = false} +} + +monster.defenses = { + defense = 0, + armor = 7, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_HEALING, minDamage = 50, maxDamage = 80, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/barbarian_headsplitter.lua b/data/monster/humans/barbarian_headsplitter.lua new file mode 100644 index 00000000000..e9711ce2403 --- /dev/null +++ b/data/monster/humans/barbarian_headsplitter.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Barbarian Headsplitter") +local monster = {} + +monster.description = "a barbarian headsplitter" +monster.experience = 85 +monster.outfit = { + lookType = 253, + lookHead = 115, + lookBody = 105, + lookLegs = 119, + lookFeet = 132, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 333 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Krimhorn, Bittermor, Ragnir, and Fenrock." + } + +monster.health = 100 +monster.maxHealth = 100 +monster.race = "blood" +monster.corpse = 20343 +monster.speed = 168 +monster.manaCost = 450 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I will regain my honor with your blood!", yell = false}, + {text = "Surrender is not option!", yell = false}, + {text = "Its you or me!", yell = false}, + {text = "Die! Die! Die!", yell = false} +} + +monster.loot = { + {id = 2050, chance = 60300}, + {name = "gold coin", chance = 75600, maxCount = 30}, + {name = "life ring", chance = 230}, + {name = "knife", chance = 14890}, + {name = "brass helmet", chance = 20140}, + {name = "viking helmet", chance = 5020}, + {id = 2229, chance = 8000, maxCount = 2}, + {name = "scale armor", chance = 4060}, + {name = "brown piece of cloth", chance = 980}, + {name = "fur boots", chance = 90}, + {name = "krimhorn helmet", chance = 110}, + {name = "health potion", chance = 560} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -50}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -60, range = 7, radius = 1, shootEffect = CONST_ANI_WHIRLWINDAXE, target = true} +} + +monster.defenses = { + defense = 0, + armor = 7 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/barbarian_skullhunter.lua b/data/monster/humans/barbarian_skullhunter.lua new file mode 100644 index 00000000000..1fe868c6425 --- /dev/null +++ b/data/monster/humans/barbarian_skullhunter.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Barbarian Skullhunter") +local monster = {} + +monster.description = "a barbarian skullhunter" +monster.experience = 85 +monster.outfit = { + lookType = 254, + lookHead = 0, + lookBody = 77, + lookLegs = 77, + lookFeet = 114, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 322 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Ragnir, Krimhorn, Bittermor, and Fenrock." + } + +monster.health = 135 +monster.maxHealth = 135 +monster.race = "blood" +monster.corpse = 20347 +monster.speed = 168 +monster.manaCost = 450 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You will become my trophy.", yell = false}, + {text = "Fight harder, coward.", yell = false}, + {text = "Show that you are a worthy opponent.", yell = false} +} + +monster.loot = { + {id = 2050, chance = 6680}, + {name = "gold coin", chance = 8240, maxCount = 30}, + {name = "life ring", chance = 300}, + {id = 2229, chance = 3000}, + {name = "knife", chance = 1067}, + {name = "brass helmet", chance = 2200}, + {name = "viking helmet", chance = 860}, + {name = "scale armor", chance = 440}, + {name = "brown piece of cloth", chance = 500}, + {name = "crystal sword", chance = 100}, + {name = "fur boots", chance = 100}, + {name = "ragnir helmet", chance = 100}, + {name = "health potion", chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -60} +} + +monster.defenses = { + defense = 0, + armor = 8 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/black_sphinx_acolyte.lua b/data/monster/humans/black_sphinx_acolyte.lua new file mode 100644 index 00000000000..c1ef69fe688 --- /dev/null +++ b/data/monster/humans/black_sphinx_acolyte.lua @@ -0,0 +1,127 @@ +local mType = Game.createMonsterType("Black Sphinx Acolyte") +local monster = {} + +monster.description = "a black sphinx acolyte" +monster.experience = 7200 +monster.outfit = { + lookType = 1200, + lookHead = 114, + lookBody = 95, + lookLegs = 94, + lookFeet = 95, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1800 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Issavi Sewers, Kilmaresh Catacombs and Kilmaresh Mountains (above and under ground)." + } + +monster.health = 8100 +monster.maxHealth = 8100 +monster.race = "blood" +monster.corpse = 36258 +monster.speed = 310 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Skeleton Elite Warrior", chance = 10, interval = 2000, max = 1} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Darkness is the mother of all knowledge!", yell = false}, + {text = "Get thee gone, unworthy!", yell = false}, + {text = "The Black Sphinx will prevail!", yell = false} +} + +monster.loot = { + {name = "Platinum Coin", chance = 100000, maxCount = 5}, + {name = "Blue Crystal Shard", chance = 5000}, + {name = "Snakebite Rod", chance = 4700}, + {name = "Underworld Rod", chance = 3400}, + {name = "Violet Gem", chance = 2600}, + {name = "Opal", chance = 2200, maxCount = 2}, + {name = "Wand of Voodoo", chance = 2200}, + {id = 36166, chance = 3400}, + {name = "Small Enchanted Emerald", chance = 1500, maxCount = 3} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -400, radius = 3, effect = CONST_ME_SMALLPLANTS, target = false}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_DEATHDAMAGE, minDamage = -400, maxDamage = -450, range = 4, radius = 3, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true} +} + +monster.defenses = { + defense = 82, + armor = 82 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -30}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/blood_hand.lua b/data/monster/humans/blood_hand.lua new file mode 100644 index 00000000000..ddb5cf08ee2 --- /dev/null +++ b/data/monster/humans/blood_hand.lua @@ -0,0 +1,135 @@ +local mType = Game.createMonsterType("Blood Hand") +local monster = {} + +monster.description = "a blood hand" +monster.experience = 750 +monster.outfit = { + lookType = 552, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 974 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Drefia." + } + +monster.health = 700 +monster.maxHealth = 700 +monster.race = "blood" +monster.corpse = 21257 +monster.speed = 192 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Blood for the dark god!", yell = false}, + {text = "For the Blood God!", yell = false}, + {text = "Die, filth!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 130}, + {name = "necrotic rod", chance = 3000}, + {name = "boots of haste", chance = 210}, + {name = "skull staff", chance = 130}, + {name = "mystic turban", chance = 790}, + {name = "white piece of cloth", chance = 840}, + {name = "red piece of cloth", chance = 500}, + {name = "noble axe", chance = 10}, + {name = "strong mana potion", chance = 5590}, + {name = "spellbook of enlightenment", chance = 790}, + {name = "book of necromantic rituals", chance = 9340}, + {name = "red gem", chance = 710}, + {name = "lancet", chance = 10680}, + {name = "horoscope", chance = 7950}, + {name = "blood tincture in a vial", chance = 15460}, + {name = "incantation notes", chance = 8820}, + {name = "pieces of magic chalk", chance = 6120} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -158, condition = {type = CONDITION_POISON, totalDamage = 80, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -50, maxDamage = -100, radius = 4, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = -600, radius = 4, effect = CONST_ME_BLOCKHIT, target = true, duration = 15000}, + -- bleed + {name ="condition", type = CONDITION_BLEEDING, interval = 2000, chance = 15, minDamage = -120, maxDamage = -160, radius = 6, effect = CONST_ME_HITAREA, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 70, maxDamage = 90, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="effect", interval = 2000, chance = 10, radius = 1, effect = CONST_ME_INSECTS, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/blood_priest.lua b/data/monster/humans/blood_priest.lua new file mode 100644 index 00000000000..cd78e9b0b4b --- /dev/null +++ b/data/monster/humans/blood_priest.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Blood Priest") +local monster = {} + +monster.description = "a blood priest" +monster.experience = 900 +monster.outfit = { + lookType = 553, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 961 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Drefia and Old Fortress." + } + +monster.health = 820 +monster.maxHealth = 820 +monster.race = "blood" +monster.corpse = 21262 +monster.speed = 198 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "The Blood God is thirsty!", yell = false}, + {text = "Give your blood to the Dark God!", yell = false} +} + +monster.loot = { + {name = "small ruby", chance = 3510, maxCount = 2}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 71}, + {name = "boots of haste", chance = 120}, + {name = "skull staff", chance = 180}, + {name = "mystic turban", chance = 2170}, + {name = "white piece of cloth", chance = 3040}, + {name = "red piece of cloth", chance = 640}, + {name = "strong mana potion", chance = 6000}, + {name = "spellbook of warding", chance = 290}, + {name = "spellbook of mind control", chance = 180}, + {name = "underworld rod", chance = 470}, + {name = "book of necromantic rituals", chance = 13550}, + {name = "red gem", chance = 880}, + {name = "lancet", chance = 14410}, + {name = "horoscope", chance = 9270}, + {name = "blood tincture in a vial", chance = 14460}, + {name = "incantation notes", chance = 14660}, + {name = "pieces of magic chalk", chance = 7770} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -80, condition = {type = CONDITION_POISON, totalDamage = 100, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -60, maxDamage = -100, range = 7, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -40, maxDamage = -60, radius = 4, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 3000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -80, maxDamage = -130, range = 1, length = 7, spread = 3, effect = CONST_ME_HITAREA, target = true}, + -- bleed + {name ="condition", type = CONDITION_BLEEDING, interval = 2000, chance = 5, minDamage = -160, maxDamage = -290, range = 1, radius = 1, target = true} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 80, maxDamage = 120, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/burning_gladiator.lua b/data/monster/humans/burning_gladiator.lua new file mode 100644 index 00000000000..4be03f075a2 --- /dev/null +++ b/data/monster/humans/burning_gladiator.lua @@ -0,0 +1,134 @@ +local mType = Game.createMonsterType("Burning Gladiator") +local monster = {} + +monster.description = "a burning gladiator" +monster.experience = 7350 +monster.outfit = { + lookType = 541, + lookHead = 95, + lookBody = 113, + lookLegs = 21, + lookFeet = 21, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 1798 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Issavi Sewers, Kilmaresh Catacombs and Kilmaresh Mountains (above and under ground)." + } + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "blood" +monster.corpse = 36481 +monster.speed = 290 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Burn, infidel!", yell = false}, + {text = "Only the Wild Sun shall shine down on this world!", yell = false}, + {text = "Praised be Fafnar, the Smiter!", yell = false} +} + +monster.loot = { + {name = "Platinum Coin", chance = 100000, maxCount = 3}, + {name = "Fafnar Symbol", chance = 6600}, + {id = 36268, chance = 5600}, + {id = 36270, chance = 5600}, + {id = 36271, chance = 5600}, + {name = "Dragon Necklace", chance = 4700}, + {name = "Lightning Pendant", chance = 4100}, + {name = "Magma Amulet", chance = 3700}, + {name = "Strange Talisman", chance = 3000}, + {name = "Magma Boots", chance = 2700}, + {id = 36166, chance = 2400}, + {name = "Elven Amulet", chance = 2100}, + {name = "Lightning Legs", chance = 2000}, + {name = "Lightning Headband", chance = 1700}, + {name = "Lightning Boots", chance = 1400}, + {name = "Spellweaver's Robe", chance = 850}, + {id = 36204, chance = 570}, + {name = "Sea Horse Figurine", chance = 140} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -550}, + {name ="firering", interval = 2000, chance = 10, minDamage = -300, maxDamage = -500, target = false}, + {name ="firex", interval = 2000, chance = 15, minDamage = -300, maxDamage = -500, target = false}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_FIREDAMAGE, minDamage = -300, maxDamage = -500, radius = 2, effect = CONST_ME_FIREATTACK, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -300, maxDamage = -500, length = 3, spread = 0, effect = CONST_ME_ENERGYHIT, target = false} +} + +monster.defenses = { + defense = 40, + armor = 89 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/cobra_assassin.lua b/data/monster/humans/cobra_assassin.lua new file mode 100644 index 00000000000..fca03cf71b6 --- /dev/null +++ b/data/monster/humans/cobra_assassin.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Cobra Assassin") +local monster = {} + +monster.description = "a cobra assassin" +monster.experience = 8316 +monster.outfit = { + lookType = 1217, + lookHead = 2, + lookBody = 2, + lookLegs = 77, + lookFeet = 1, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 1775 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Cobra Bastion." + } + +monster.health = 8200 +monster.maxHealth = 8200 +monster.race = "blood" +monster.corpse = 36382 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hey, maybe you want to strike a deal... no?", yell = false}, + {text = "Stand and deliver! Your money... AND your life actually!", yell = false}, + {text = "You will not leave this place breathing!", yell = false} +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 3}, + {name = "knife", chance = 10500}, + {name = "cobra crest", chance = 7750}, + {id = 2419, chance = 7750}, + {name = "protection amulet", chance = 7500}, + {name = "heavy machete", chance = 6500}, + {name = "bone sword", chance = 5000}, + {name = "machete", chance = 2250}, + {name = "carlin sword", chance = 2250}, + {id = 26189, chance = 1690} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450}, + {name ="wave t", interval = 2000, chance = 10, minDamage = -300, maxDamage = -380, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -280, maxDamage = -400, radius = 4, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_PHYSICALDAMAGE, minDamage = -250, maxDamage = -400, length = 5, spread = 3, effect = CONST_ME_BLOCKHIT, target = false} +} + +monster.defenses = { + defense = 81, + armor = 81 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/cobra_scout.lua b/data/monster/humans/cobra_scout.lua new file mode 100644 index 00000000000..c22e1e932c3 --- /dev/null +++ b/data/monster/humans/cobra_scout.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Cobra Scout") +local monster = {} + +monster.description = "a cobra scout" +monster.experience = 8712 +monster.outfit = { + lookType = 1217, + lookHead = 1, + lookBody = 1, + lookLegs = 101, + lookFeet = 78, + lookAddons = 2, + lookMount = 0 +} + +monster.raceId = 1776 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Cobra Bastion." + } + +monster.health = 8500 +monster.maxHealth = 8500 +monster.race = "blood" +monster.corpse = 36470 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Think I can't see you? Think again...", yell = false}, + {text = "You don't stand a chance!", yell = false}, + {text = "What are you looking for?", yell = false} +} + +monster.loot = { + {name = "platinum coin", chance = 74000, maxCount = 9}, + {name = "earth arrow", chance = 19490, maxCount = 28}, + {name = "stone skin amulet", chance = 6800}, + {name = "gold ingot", chance = 5750, maxCount = 1}, + {name = "cheesy figurine", chance = 13800}, + {name = "opal", chance = 23800, maxCount = 5}, + {name = "cobra crest", chance = 15450}, + {name = "small emerald", chance = 3000, maxCount = 2}, + {name = "violet gem", chance = 1300}, + {name = "yellow gem", chance = 3060}, + {name = "green gem", chance = 1210}, + {name = "red gem", chance = 4800}, + {name = "sacred tree amulet", chance = 5100}, + {name = "green crystal shard", chance = 2130}, + {id = 26189, chance = 740}-- ring of red plasma +} + + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -500}, + {name ="combat", interval = 2000, chance = 22, type = COMBAT_EARTHDAMAGE, minDamage = -350, maxDamage = -450, shootEffect = CONST_ANI_SNIPERARROW, target = true}, + {name ="combat", interval = 2000, chance = 16, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -420, radius = 4, shootEffect = CONST_ANI_POISONARROW, effect = CONST_ME_GREEN_RINGS, target = true}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_PHYSICALDAMAGE, minDamage = -300, maxDamage = -380, radius = 3, effect = CONST_ME_GROUNDSHAKER, target = false} +} + +monster.defenses = { + defense = 81, + armor = 81 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/cobra_vizier.lua b/data/monster/humans/cobra_vizier.lua new file mode 100644 index 00000000000..bd3b6881961 --- /dev/null +++ b/data/monster/humans/cobra_vizier.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Cobra Vizier") +local monster = {} + +monster.description = "a cobra vizier" +monster.experience = 9108 +monster.outfit = { + lookType = 1217, + lookHead = 19, + lookBody = 19, + lookLegs = 86, + lookFeet = 19, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1824 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Cobra Bastion." + } + +monster.health = 8500 +monster.maxHealth = 8500 +monster.race = "blood" +monster.corpse = 36474 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "COMBINE FORCES MY BRETHEN!", yell = false}, + {text = "Feel the cobras wrath!", yell = false}, + {text = "OH NO, YOU WON'T!", yell = false} +} + +monster.loot = { + {name = "platinum coin", chance = 85480, maxCount = 4}, + {name = "terra rod", chance = 43000}, + {name = "snakebite rod", chance = 20970}, + {name = "cobra crest", chance = 16130}, + {name = "terra hood", chance = 13710}, + {name = "cyan crystal fragment", chance = 10805}, + {name = "terra boots", chance = 9680}, + {id = 7632, chance = 8870}, -- giant shimmering pearl + {name = "red gem", chance = 6450}, + {name = "emerald bangle", chance = 5650}, + {name = "gemmed figurine", chance = 4840}, + {name = "green crystal fragment", chance = 3230}, + {name = "red crystal fragment", chance = 3230}, + {name = "serpent sword", chance = 2420}, + {name = "violet crystal shard", chance = 2420}, + {name = "green gem", chance = 1610}, + {name = "onyx chip", chance = 1610, maxCount = 3} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -480}, + {name ="explosion wave", interval = 2000, chance = 15, minDamage = -280, maxDamage = -400, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_EARTHDAMAGE, minDamage = -350, maxDamage = -520, radius = 4, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_GREEN_RINGS, target = true} +} + +monster.defenses = { + defense = 82, + armor = 82, + {name ="speed", interval = 2000, chance = 8, speedChange = 250, effect = CONST_ME_MAGIC_GREEN, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/crazed_beggar.lua b/data/monster/humans/crazed_beggar.lua new file mode 100644 index 00000000000..27d36437478 --- /dev/null +++ b/data/monster/humans/crazed_beggar.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Crazed Beggar") +local monster = {} + +monster.description = "a crazed beggar" +monster.experience = 35 +monster.outfit = { + lookType = 153, + lookHead = 59, + lookBody = 38, + lookLegs = 38, + lookFeet = 97, + lookAddons = 3, + lookMount = 0 +} + +monster.raceId = 525 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Factory, Foreigner, and Trade Quarters in Yalahar." + } + +monster.health = 100 +monster.maxHealth = 100 +monster.race = "blood" +monster.corpse = 20351 +monster.speed = 154 +monster.manaCost = 300 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hehehe!", yell = false}, + {text = "Raahhh!", yell = false}, + {text = "You are one of THEM! Die!", yell = false}, + {text = "Wanna buy roses??", yell = false}, + {text = "They're coming! They're coming!", yell = false}, + {text = "Make it stop!", yell = false}, + {text = "Gimme money!", yell = false} +} + +monster.loot = { + {name = "small blue pillow", chance = 420}, + {id = 2072, chance = 360}, + {name = "gold coin", chance = 99000, maxCount = 9}, + {name = "dwarven ring", chance = 120}, + {id = 33528, chance = 55000}, + {name = "wooden hammer", chance = 6500}, + {name = "wooden spoon", chance = 9750}, + {id = 2570, chance = 5650}, + {name = "meat", chance = 9500}, + {name = "roll", chance = 22500}, + {name = "red rose", chance = 4700}, + {name = "sling herb", chance = 420}, + {name = "rum flask", chance = 420}, + {id = 6092, chance = 300}, + {id = 9808, chance = 80} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -25} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/crypt_defiler.lua b/data/monster/humans/crypt_defiler.lua new file mode 100644 index 00000000000..1d5fae830d4 --- /dev/null +++ b/data/monster/humans/crypt_defiler.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Crypt Defiler") +local monster = {} + +monster.description = "a crypt defiler" +monster.experience = 70 +monster.outfit = { + lookType = 146, + lookHead = 115, + lookBody = 115, + lookLegs = 61, + lookFeet = 96, + lookAddons = 3, + lookMount = 0 +} + +monster.raceId = 868 +monster.Bestiary = { + class = "Human", + race = dafasdfasdfsadfasdfasd, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 2, + Locations = "Horestis Tomb." + } + +monster.health = 185 +monster.maxHealth = 185 +monster.race = "blood" +monster.corpse = 20359 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I smell gold!", yell = false}, + {text = "You'll make a fine fake-mummy to be sold!", yell = false}, + {text = "Untold riches are awaiting me!", yell = false}, + {text = "I don't like competition!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50900, maxCount = 39}, + {name = "axe", chance = 2730}, + {name = "mace", chance = 1800}, + {name = "iron helmet", chance = 450}, + {name = "brass armor", chance = 2240}, + {name = "steel shield", chance = 450}, + {name = "nomad parchment", chance = 220}, + {name = "potato", chance = 4840, maxCount = 3}, + {name = "dirty turban", chance = 1570}, + {name = "rope belt", chance = 4040} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -90}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -40, range = 7, radius = 1, shootEffect = CONST_ANI_THROWINGSTAR, target = true} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/dark_apprentice.lua b/data/monster/humans/dark_apprentice.lua new file mode 100644 index 00000000000..a000a62bcfc --- /dev/null +++ b/data/monster/humans/dark_apprentice.lua @@ -0,0 +1,127 @@ +local mType = Game.createMonsterType("Dark Apprentice") +local monster = {} + +monster.description = "a dark apprentice" +monster.experience = 100 +monster.outfit = { + lookType = 133, + lookHead = 78, + lookBody = 57, + lookLegs = 95, + lookFeet = 115, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 372 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Magician Tower, Dark Cathedral, Hero Cave, Magician Quarter." + } + +monster.health = 225 +monster.maxHealth = 225 +monster.race = "blood" +monster.corpse = 20363 +monster.speed = 172 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Outch!", yell = false}, + {text = "Oops, I did it again.", yell = false}, + {text = "From the spirits that I called Sir, deliver me!", yell = false}, + {text = "I must dispose of my masters enemies!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 7500, maxCount = 45}, + {name = "wand of decay", chance = 110}, + {name = "wand of dragonbreath", chance = 1980}, + {name = "blank rune", chance = 8125, maxCount = 3}, + {name = "health potion", chance = 2900}, + {name = "mana potion", chance = 2980}, + {name = "reins", chance = 10} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -60}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -2, maxDamage = -26, range = 7, shootEffect = CONST_ANI_FIRE, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -10, maxDamage = -20, range = 7, shootEffect = CONST_ANI_ENERGY, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -24, range = 7, shootEffect = CONST_ANI_SMALLSTONE, target = false}, + {name ="outfit", interval = 2000, chance = 1, range = 3, shootEffect = CONST_ANI_EXPLOSION, target = true, duration = 2000, outfitMonster = "cyclops"}, + {name ="outfit", interval = 2000, chance = 1, radius = 4, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 2000, outfitItem = 2324} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 30, maxDamage = 40, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="outfit", interval = 2000, chance = 5, target = true, duration = 3000, outfitMonster = "green frog"} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/dark_magician.lua b/data/monster/humans/dark_magician.lua new file mode 100644 index 00000000000..0d7eb1f7f10 --- /dev/null +++ b/data/monster/humans/dark_magician.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Dark Magician") +local monster = {} + +monster.description = "a dark magician" +monster.experience = 185 +monster.outfit = { + lookType = 133, + lookHead = 116, + lookBody = 95, + lookLegs = 50, + lookFeet = 132, + lookAddons = 2, + lookMount = 0 +} + +monster.raceId = 371 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Hero Cave (Edron), Magician Tower, Dark Cathedral and Yalahar Academy of Magic in \z + Magician Quarter and a single one on The Witches' Cliff (only accessible during a quest)." + } + +monster.health = 325 +monster.maxHealth = 325 +monster.race = "blood" +monster.corpse = 20367 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Feel the power of my runes!", yell = false}, + {text = "Killing you gets expensive!", yell = false}, + {text = "My secrets are mine alone!", yell = false}, + {text = "Stand still!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 75100, maxCount = 55}, + {name = "blank rune", chance = 10000}, + {name = "strong health potion", chance = 3000}, + {name = "strong mana potion", chance = 2860}, + {name = "health potion", chance = 12000}, + {name = "mana potion", chance = 11900}, + {name = "reins", chance = 20} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -40}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -5, maxDamage = -40, range = 7, shootEffect = CONST_ANI_FIRE, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -20, maxDamage = -30, range = 7, shootEffect = CONST_ANI_ENERGY, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 60, maxDamage = 80, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/dark_monk.lua b/data/monster/humans/dark_monk.lua new file mode 100644 index 00000000000..ebff93e3d0e --- /dev/null +++ b/data/monster/humans/dark_monk.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Dark Monk") +local monster = {} + +monster.description = "a dark monk" +monster.experience = 145 +monster.outfit = { + lookType = 225, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 225 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Dark Cathedral, Vandura (Cult Cave), Foreigner Quarter." + } + +monster.health = 190 +monster.maxHealth = 190 +monster.race = "blood" +monster.corpse = 20562 +monster.speed = 230 +monster.manaCost = 480 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 20, + damage = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You are no match to us!", yell = false}, + {text = "This is where your path will end!", yell = false}, + {text = "Your end has come!", yell = false} +} + +monster.loot = { + {id = 1949, chance = 1790}, + {name = "brown flask", chance = 380}, + {id = 2044, chance = 550}, + {name = "gold coin", chance = 14600, maxCount = 18}, + {name = "power ring", chance = 120}, + {name = "life crystal", chance = 990}, + {name = "ankh", chance = 900}, + {name = "sandals", chance = 890}, + {name = "bread", chance = 20550}, + {name = "mana potion", chance = 790}, + {name = "book of prayers", chance = 1900}, + {name = "dark rosary", chance = 10500}, + {name = "rope belt", chance = 6666}, + {name = "safety pin", chance = 990} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -20, maxDamage = -50, range = 1, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 25, maxDamage = 49, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 300, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -20}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 40} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/enlightened_of_the_cult.lua b/data/monster/humans/enlightened_of_the_cult.lua new file mode 100644 index 00000000000..c5de11fa0fc --- /dev/null +++ b/data/monster/humans/enlightened_of_the_cult.lua @@ -0,0 +1,144 @@ +local mType = Game.createMonsterType("Enlightened of the Cult") +local monster = {} + +monster.description = "an enlightened of the cult" +monster.experience = 500 +monster.outfit = { + lookType = 193, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 252 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Goroma, Formorgar Mines, Magician Quarter, Forbidden Temple." + } + +monster.health = 700 +monster.maxHealth = 700 +monster.race = "blood" +monster.corpse = 20391 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 50, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Crypt Shambler", chance = 10, interval = 2000}, + {name = "Ghost", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Praise to my master Urgith!", yell = false}, + {text = "You will rise as my servant!", yell = false}, + {text = "Praise to my masters! Long live the triangle!", yell = false}, + {text = "You will die in the name of the triangle!", yell = false} +} + +monster.loot = { + {id = 1962, chance = 910}, + {name = "piggy bank", chance = 130}, + {name = "small sapphire", chance = 550}, + {name = "gold coin", chance = 64550, maxCount = 70}, + {name = "energy ring", chance = 450}, + {name = "platinum amulet", chance = 200}, + {name = "wand of inferno", chance = 180}, + {name = "protection amulet", chance = 790}, + {name = "skull staff", chance = 350}, + {name = "blue robe", chance = 40}, + {name = "jewelled backpack", chance = 100}, + {name = "pirate voodoo doll", chance = 430}, + {id = 6090, chance = 490}, + {name = "amber staff", chance = 100}, + {name = "strong mana potion", chance = 740}, + {name = "cultish mask", chance = 10250}, + {name = "cultish symbol", chance = 890}, + {name = "broken key ring", chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100, condition = {type = CONDITION_POISON, totalDamage = 4, interval = 4000}}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_LIFEDRAIN, minDamage = -70, maxDamage = -185, range = 1, radius = 1, shootEffect = CONST_ANI_HOLY, effect = CONST_ME_HOLYAREA, target = true}, + {name ="drunk", interval = 2000, chance = 10, range = 7, shootEffect = CONST_ANI_HOLY, effect = CONST_ME_HOLYDAMAGE, target = true, duration = 5000}, + {name ="speed", interval = 2000, chance = 10, speedChange = -360, range = 7, effect = CONST_ME_MAGIC_RED, target = true, duration = 6000} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 60, maxDamage = 90, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_YELLOW_RINGS} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/feverish_citizen.lua b/data/monster/humans/feverish_citizen.lua new file mode 100644 index 00000000000..98791f29849 --- /dev/null +++ b/data/monster/humans/feverish_citizen.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Feverish Citizen") +local monster = {} + +monster.description = "a feverish citizen" +monster.experience = 30 +monster.outfit = { + lookType = 425, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 719 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 2, + Locations = "Venore." + } + +monster.health = 125 +monster.maxHealth = 125 +monster.race = "blood" +monster.corpse = 20395 +monster.speed = 146 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Arrrgh!", yell = false}, + {text = "I am the king of the world!", yell = false}, + {text = "Die Ferumbras!", yell = false}, + {text = "Tigerblood is running through my veins!", yell = false}, + {text = "You! It's you again!", yell = false}, + {text = "Stand still you tasty morsel!", yell = false}, + {text = "", yell = false}, + {text = "Burn heretic! Burn!", yell = false}, + {text = "Harrr!", yell = false}, + {text = "This is Venore!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 30300, maxCount = 35}, + {id = 2230, chance = 4920}, + {name = "worm", chance = 25730, maxCount = 3}, + {name = "ominous piece of cloth", chance = 1660}, + {name = "dubious piece of cloth", chance = 1720}, + {name = "voluminous piece of cloth", chance = 2290}, + {name = "obvious piece of cloth", chance = 2006}, + {name = "ludicrous piece of cloth", chance = 2060}, + {name = "luminous piece of cloth", chance = 2290} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -18}, + {name ="drunk", interval = 2000, chance = 15, length = 3, spread = 2, effect = CONST_ME_POISONAREA, target = false, duration = 3000} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="outfit", interval = 2000, chance = 1, radius = 3, effect = CONST_ME_GREEN_RINGS, target = false, duration = 5000, outfitMonster = "bog raider"} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 80}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/gang_member.lua b/data/monster/humans/gang_member.lua new file mode 100644 index 00000000000..20da9ae5b5a --- /dev/null +++ b/data/monster/humans/gang_member.lua @@ -0,0 +1,118 @@ +local mType = Game.createMonsterType("Gang Member") +local monster = {} + +monster.description = "a gang member" +monster.experience = 70 +monster.outfit = { + lookType = 151, + lookHead = 114, + lookBody = 19, + lookLegs = 42, + lookFeet = 20, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 526 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Throughout the Foreigner, Factory, and Trade Quarters in Yalahar." + } + +monster.health = 295 +monster.maxHealth = 295 +monster.race = "blood" +monster.corpse = 20403 +monster.speed = 190 +monster.manaCost = 420 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 35, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "This is our territory!", yell = false}, + {text = "Help me guys!", yell = false}, + {text = "I don't like the way you look!", yell = false}, + {text = "You're wearing the wrong colours!", yell = false}, + {text = "Don't mess with us!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50110, maxCount = 30}, + {name = "club ring", chance = 740}, + {name = "studded legs", chance = 5220}, + {name = "leather legs", chance = 15330} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -70} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/gladiator.lua b/data/monster/humans/gladiator.lua new file mode 100644 index 00000000000..e8f33363b59 --- /dev/null +++ b/data/monster/humans/gladiator.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Gladiator") +local monster = {} + +monster.description = "a gladiator" +monster.experience = 90 +monster.outfit = { + lookType = 131, + lookHead = 78, + lookBody = 3, + lookLegs = 79, + lookFeet = 114, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 527 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Trade Quarter, Arena and Zoo Quarter." + } + +monster.health = 185 +monster.maxHealth = 185 +monster.race = "blood" +monster.corpse = 20407 +monster.speed = 196 +monster.manaCost = 470 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You are no match for me!", yell = false}, + {text = "Feel my prowess.", yell = false}, + {text = "Fight!", yell = false}, + {text = "Take this!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 49500, maxCount = 30}, + {id = 2376, chance = 12620}, + {name = "mace", chance = 11160}, + {name = "chain helmet", chance = 5200}, + {name = "iron helmet", chance = 590}, + {name = "brass armor", chance = 2750}, + {name = "steel shield", chance = 840}, + {name = "plate shield", chance = 9950}, + {name = "meat", chance = 19000}, + {name = "belted cape", chance = 340} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -90} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="speed", interval = 2000, chance = 15, speedChange = 215, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 15}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/glooth_bandit.lua b/data/monster/humans/glooth_bandit.lua new file mode 100644 index 00000000000..766b21f4f4f --- /dev/null +++ b/data/monster/humans/glooth_bandit.lua @@ -0,0 +1,141 @@ +local mType = Game.createMonsterType("Glooth Bandit") +local monster = {} + +monster.description = "a glooth bandit" +monster.experience = 2000 +monster.outfit = { + lookType = 129, + lookHead = 115, + lookBody = 80, + lookLegs = 114, + lookFeet = 114, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1119 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Underground Glooth Factory." + } + +monster.health = 2600 +monster.maxHealth = 2600 +monster.race = "blood" +monster.corpse = 24251 +monster.speed = 300 +monster.manaCost = 450 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2152, chance = 100000, maxCount = 3}, + {id = 24185, chance = 9090}, + {id = 7590, chance = 7142}, + {id = 23574, chance = 5555}, + {id = 9970, chance = 5555, maxCount = 2}, + {id = 8472, chance = 5000}, + {id = 7591, chance = 4545}, + {id = 23514, chance = 4000}, + {id = 24183, chance = 3030}, + {id = 23550, chance = 2500}, + {id = 23549, chance = 2500}, + {id = 23536, chance = 2000}, + {id = 2149, chance = 1492, maxCount = 2}, + {id = 23529, chance = 1492}, + {id = 8473, chance = 1492}, + {id = 23517, chance = 1000}, + {id = 2436, chance = 1000}, + {id = 23535, chance = 1000}, + {id = 2155, chance = 1000}, + {id = 23551, chance = 1000}, + {id = 2454, chance = 1000}, + {id = 7884, chance = 1000}, + {id = 3962, chance = 1000}, + {id = 23554, chance = 500}, + {id = 7886, chance = 500}, + {id = 7885, chance = 500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 80, attack = 68}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_PHYSICALDAMAGE, minDamage = -60, maxDamage = -200, range = 8, shootEffect = CONST_ANI_ARROW, target = false} +} + +monster.defenses = { + defense = 32, + armor = 32, + {name ="combat", interval = 3000, chance = 35, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 15}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/glooth_brigand.lua b/data/monster/humans/glooth_brigand.lua new file mode 100644 index 00000000000..e7b2ac5dc4f --- /dev/null +++ b/data/monster/humans/glooth_brigand.lua @@ -0,0 +1,138 @@ +local mType = Game.createMonsterType("Glooth Brigand") +local monster = {} + +monster.description = "a glooth brigand" +monster.experience = 1900 +monster.outfit = { + lookType = 137, + lookHead = 114, + lookBody = 114, + lookLegs = 109, + lookFeet = 114, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1120 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Underground Glooth Factory." + } + +monster.health = 2400 +monster.maxHealth = 2400 +monster.race = "blood" +monster.corpse = 24257 +monster.speed = 320 +monster.manaCost = 450 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2152, chance = 100000, maxCount = 3}, + {id = 23574, chance = 9090}, + {id = 24185, chance = 7692}, + {id = 7590, chance = 5882}, + {id = 23514, chance = 4000}, + {id = 24183, chance = 3030}, + {id = 8472, chance = 2500}, + {id = 23517, chance = 2000}, + {id = 8473, chance = 2000}, + {id = 23549, chance = 1515}, + {id = 23554, chance = 1515}, + {id = 7386, chance = 1000}, + {id = 7884, chance = 1000}, + {id = 7632, chance = 1000}, + {id = 7887, chance = 1000}, + {id = 7412, chance = 1000}, + {id = 2155, chance = 1000}, + {id = 7886, chance = 502}, + {id = 7419, chance = 502}, + {id = 23538, chance = 502}, + {id = 23529, chance = 502}, + {id = 23536, chance = 502}, + {id = 7903, chance = 502} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 80, attack = 68}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_PHYSICALDAMAGE, minDamage = -40, maxDamage = -200, range = 8, shootEffect = CONST_ANI_ARROW, target = false} +} + +monster.defenses = { + defense = 26, + armor = 26, + {name ="combat", interval = 3000, chance = 35, type = COMBAT_HEALING, minDamage = 200, maxDamage = 245, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 25}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/grave_robber.lua b/data/monster/humans/grave_robber.lua new file mode 100644 index 00000000000..ccf2d4ab8f7 --- /dev/null +++ b/data/monster/humans/grave_robber.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Grave Robber") +local monster = {} + +monster.description = "a grave robber" +monster.experience = 65 +monster.outfit = { + lookType = 146, + lookHead = 114, + lookBody = 95, + lookLegs = 76, + lookFeet = 38, + lookAddons = 3, + lookMount = 0 +} + +monster.raceId = 867 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 2, + Locations = "Horestis Tomb." + } + +monster.health = 165 +monster.maxHealth = 165 +monster.race = "blood" +monster.corpse = 20411 +monster.speed = 190 +monster.manaCost = 435 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 54260, maxCount = 38}, + {name = "axe", chance = 2500}, + {name = "mace", chance = 1700}, + {name = "iron helmet", chance = 500}, + {name = "brass armor", chance = 1700}, + {name = "steel shield", chance = 500}, + {name = "nomad parchment", chance = 170}, + {name = "potato", chance = 5680, maxCount = 3}, + {name = "dirty turban", chance = 1700}, + {name = "rope belt", chance = 7510} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -90}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -100, maxDamage = -160, range = 7, radius = 1, shootEffect = CONST_ANI_POISON, target = true} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/hero.lua b/data/monster/humans/hero.lua new file mode 100644 index 00000000000..f3ec73dcfa7 --- /dev/null +++ b/data/monster/humans/hero.lua @@ -0,0 +1,144 @@ +local mType = Game.createMonsterType("Hero") +local monster = {} + +monster.description = "a hero" +monster.experience = 1200 +monster.outfit = { + lookType = 73, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 73 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "In Hero Cave in Edron, it has many rooms with many kinds of monsters and different amounts of Heroes. \z + Also in Magician Quarter, accompanied by other monsters. Old Fortress." + } + +monster.health = 1400 +monster.maxHealth = 1400 +monster.race = "blood" +monster.corpse = 20415 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 80, + health = 10, + damage = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Let's have a fight!", yell = false}, + {text = "Welcome to my battleground!", yell = false}, + {text = "Have you seen princess Lumelia?", yell = false}, + {text = "I will sing a tune at your grave.", yell = false} +} + +monster.loot = { + {id = 1949, chance = 45000}, + {id = 2071, chance = 1640}, + {name = "piggy bank", chance = 80}, + {id = 2120, chance = 2190}, + {name = "wedding ring", chance = 4910}, + {name = "gold coin", chance = 59500, maxCount = 100}, + {name = "might ring", chance = 470}, + {name = "two handed sword", chance = 1500}, + {name = "war hammer", chance = 870}, + {name = "fire sword", chance = 550}, + {name = "bow", chance = 13300}, + {name = "crown armor", chance = 490}, + {name = "crown legs", chance = 660}, + {name = "crown helmet", chance = 450}, + {name = "crown shield", chance = 280}, + {name = "arrow", chance = 26000, maxCount = 13}, + {name = "green tunic", chance = 8000}, + {name = "scarf", chance = 1110}, + {name = "meat", chance = 8200, maxCount = 3}, + {name = "grapes", chance = 19850}, + {name = "red rose", chance = 20450}, + {name = "red piece of cloth", chance = 2006}, + {name = "sniper arrow", chance = 11400, maxCount = 4}, + {name = "great health potion", chance = 720}, + {name = "small notebook", chance = 930}, + {name = "scroll of heroic deeds", chance = 5000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -240}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -120, range = 7, shootEffect = CONST_ANI_ARROW, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 40}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = -20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/hunter.lua b/data/monster/humans/hunter.lua new file mode 100644 index 00000000000..48a2ef4b45a --- /dev/null +++ b/data/monster/humans/hunter.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Hunter") +local monster = {} + +monster.description = "a hunter" +monster.experience = 150 +monster.outfit = { + lookType = 129, + lookHead = 95, + lookBody = 116, + lookLegs = 121, + lookFeet = 115, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 11 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "North of Mount Sternum, Plains of Havoc, Outlaw Camp, Dark Cathedral, Femor Hills, \z + Maze of Lost Souls, north of the Amazon Camp, at the entrance and in the Hero Cave, \z + a castle tower at Elvenbane, Trade Quarter, Smuggler camp on Tyrsung, Formorgar Mines." + } + +monster.health = 150 +monster.maxHealth = 150 +monster.race = "blood" +monster.corpse = 20419 +monster.speed = 210 +monster.manaCost = 530 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Guess who we're hunting, hahaha!", yell = false}, + {text = "Guess who we are hunting!", yell = false}, + {text = "Bullseye!", yell = false}, + {text = "You'll make a nice trophy!", yell = false} +} + +monster.loot = { + {id = 2050, chance = 3300}, + {name = "small ruby", chance = 150}, + {name = "dragon necklace", chance = 3000}, + {name = "bow", chance = 5770}, + {name = "brass helmet", chance = 5050}, + {name = "brass armor", chance = 5070}, + {name = "arrow", chance = 82000, maxCount = 22}, + {name = "poison arrow", chance = 4500, maxCount = 4}, + {name = "burst arrow", chance = 5360, maxCount = 3}, + {name = "orange", chance = 20300, maxCount = 2}, + {name = "roll", chance = 11370, maxCount = 2}, + {name = "sniper gloves", chance = 610}, + {name = "slingshot", chance = 120}, + {id = 7394, chance = 190}, + {id = 7397, chance = 520}, + {id = 7400, chance = 70}, + {name = "hunter's quiver", chance = 10240} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -20}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -100, range = 7, shootEffect = CONST_ANI_ARROW, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/ice_witch.lua b/data/monster/humans/ice_witch.lua new file mode 100644 index 00000000000..d6b587e792b --- /dev/null +++ b/data/monster/humans/ice_witch.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Ice Witch") +local monster = {} + +monster.description = "an ice witch" +monster.experience = 580 +monster.outfit = { + lookType = 149, + lookHead = 0, + lookBody = 47, + lookLegs = 105, + lookFeet = 105, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 331 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Ice Witch Temple, tower in Krimhorn, caves around Hrodmir ('camps' area), \z + Formorgar Glacier deepest mines, Magician Quarter in Yalahar (Level 60 Requirement Door)." + } + +monster.health = 650 +monster.maxHealth = 650 +monster.race = "blood" +monster.corpse = 20423 +monster.speed = 228 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 70, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "So you think you are cool?", yell = false}, + {text = "I hope it is not too cold for you! HeHeHe.", yell = false}, + {text = "Freeze!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 29630, maxCount = 90}, + {name = "clerical mace", chance = 920}, + {name = "mystic turban", chance = 430}, + {name = "green mushroom", chance = 1310}, + {name = "shard", chance = 530}, + {name = "diamond sceptre", chance = 330}, + {id = 7441, chance = 10000}, + {name = "crystal sword", chance = 400}, + {name = "pair of earmuffs", chance = 90}, + {name = "strong mana potion", chance = 820}, + {name = "glacier shoes", chance = 280} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -60}, + {name ="outfit", interval = 2000, chance = 1, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 4000, outfitItem = 7172}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -60, maxDamage = -130, length = 5, spread = 2, effect = CONST_ME_ICETORNADO, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ICEDAMAGE, minDamage = -55, maxDamage = -115, range = 7, shootEffect = CONST_ANI_SMALLICE, effect = CONST_ME_ICEATTACK, target = true}, + {name ="speed", interval = 2000, chance = 15, speedChange = -600, range = 7, shootEffect = CONST_ANI_SMALLICE, effect = CONST_ME_ICETORNADO, target = false, duration = 20000} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 90, maxDamage = 120, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/infernalist.lua b/data/monster/humans/infernalist.lua new file mode 100644 index 00000000000..7c62cb04f61 --- /dev/null +++ b/data/monster/humans/infernalist.lua @@ -0,0 +1,143 @@ +local mType = Game.createMonsterType("Infernalist") +local monster = {} + +monster.description = "an infernalist" +monster.experience = 4000 +monster.outfit = { + lookType = 130, + lookHead = 78, + lookBody = 76, + lookLegs = 94, + lookFeet = 115, + lookAddons = 2, + lookMount = 0 +} + +monster.raceId = 529 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Magician Quarter, Hero Cave, Demona, Fury Dungeon." + } + +monster.health = 3650 +monster.maxHealth = 3650 +monster.race = "blood" +monster.corpse = 20427 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 4, + runHealth = 900, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "fire elemental", chance = 20, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Nothing will remain but your scorched bones!", yell = false}, + {text = "Some like it hot!", yell = false}, + {text = "It's cooking time!", yell = false}, + {text = "Feel the heat of battle!", yell = false} +} + +monster.loot = { + {name = "red tome", chance = 300}, + {name = "piggy bank", chance = 220}, + {name = "gold coin", chance = 56500, maxCount = 100}, + {name = "gold coin", chance = 40000, maxCount = 47}, + {name = "energy ring", chance = 1800}, + {name = "skull staff", chance = 6500}, + {name = "magic sulphur", chance = 600}, + {name = "red piece of cloth", chance = 1420}, + {name = "great mana potion", chance = 19700}, + {name = "great health potion", chance = 1900}, + {name = "small enchanted ruby", chance = 4250}, + {name = "magma boots", chance = 300}, + {name = "raspberry", chance = 8500, maxCount = 5}, + {name = "spellbook of mind control", chance = 370}, + {name = "royal tapestry", chance = 520}, + {name = "black skull", chance = 820}, + {name = "gold ingot", chance = 70}, + {name = "crystal of power", chance = 220} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_FIREDAMAGE, minDamage = -65, maxDamage = -180, range = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_HITBYFIRE, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -90, maxDamage = -180, range = 7, radius = 3, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_MANADRAIN, minDamage = -53, maxDamage = -120, range = 7, radius = 3, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_TELEPORT, target = true}, + {name ="firefield", interval = 2000, chance = 15, range = 7, radius = 3, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -150, maxDamage = -250, length = 8, spread = 3, effect = CONST_ME_FIREATTACK, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -150, radius = 2, effect = CONST_ME_EXPLOSIONAREA, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 60, maxDamage = 230, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 95}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/mad_scientist.lua b/data/monster/humans/mad_scientist.lua new file mode 100644 index 00000000000..b8a0f4971d0 --- /dev/null +++ b/data/monster/humans/mad_scientist.lua @@ -0,0 +1,127 @@ +local mType = Game.createMonsterType("Mad Scientist") +local monster = {} + +monster.description = "a mad scientist" +monster.experience = 205 +monster.outfit = { + lookType = 133, + lookHead = 97, + lookBody = 0, + lookLegs = 38, + lookFeet = 97, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 528 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Magician Quarter, Trade Quarter, Factory Quarter,Isle of Evil, Tiquanda Laboratory." + } + +monster.health = 325 +monster.maxHealth = 325 +monster.race = "blood" +monster.corpse = 20439 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Die in the name of Science!", yell = false}, + {text = "You will regret interrupting my studies!", yell = false}, + {text = "Let me test this!", yell = false}, + {text = "I will study your corpse!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 30000, maxCount = 65}, + {name = "gold coin", chance = 30000, maxCount = 50}, + {id = 2162, chance = 2000}, + {name = "life crystal", chance = 2000}, + {name = "cookie", chance = 1200, maxCount = 5}, + {name = "white mushroom", chance = 8000, maxCount = 3}, + {name = "mastermind potion", chance = 130}, + {name = "health potion", chance = 19000}, + {name = "mana potion", chance = 19000}, + {name = "small enchanted amethyst", chance = 470} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -35}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DROWNDAMAGE, minDamage = -20, maxDamage = -56, range = 7, radius = 3, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_POFF, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -20, maxDamage = -36, shootEffect = CONST_ANI_POISON, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = -300, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_SMALLPLANTS, target = true, duration = 2000} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 10, maxDamage = 30, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/monk.lua b/data/monster/humans/monk.lua new file mode 100644 index 00000000000..1f3fbd77e22 --- /dev/null +++ b/data/monster/humans/monk.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Monk") +local monster = {} + +monster.description = "a monk" +monster.experience = 200 +monster.outfit = { + lookType = 57, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 57 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Edron Hero Cave, Triangle Tower near Thais, Maze of Lost Souls, Deeper Dark Cathedral, \z + Isle of the Kings, Trade Quarter." + } + +monster.health = 240 +monster.maxHealth = 240 +monster.race = "blood" +monster.corpse = 20371 +monster.speed = 240 +monster.manaCost = 600 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 20, + damage = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Repent Heretic!", yell = false}, + {text = "A prayer to the almighty one!", yell = false}, + {text = "I will punish the sinners!", yell = false} +} + +monster.loot = { + {id = 1949, chance = 2000}, + {name = "brown flask", chance = 820}, + {id = 2044, chance = 880}, + {name = "gold coin", chance = 15000, maxCount = 18}, + {name = "power ring", chance = 100}, + {name = "life crystal", chance = 1002}, + {name = "ankh", chance = 2240}, + {id = 2401, chance = 440}, + {name = "sandals", chance = 710}, + {name = "bread", chance = 20000}, + {name = "book of prayers", chance = 4930}, + {name = "rope belt", chance = 2950}, + {name = "safety pin", chance = 1001} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -130} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 30, maxDamage = 50, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 300, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/mutated_human.lua b/data/monster/humans/mutated_human.lua new file mode 100644 index 00000000000..b0234d49ef2 --- /dev/null +++ b/data/monster/humans/mutated_human.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Mutated Human") +local monster = {} + +monster.description = "a mutated human" +monster.experience = 150 +monster.outfit = { + lookType = 323, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 521 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Alchemist Quarter and Factory Quarter (Yalahar), Robson's Isle, Tiquanda Laboratory." + } + +monster.health = 240 +monster.maxHealth = 240 +monster.race = "blood" +monster.corpse = 9107 +monster.speed = 154 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Take that creature off my back!! I can feel it!", yell = false}, + {text = "You will regret interrupting my studies!", yell = false}, + {text = "You will be the next infected one... CRAAAHHH!", yell = false}, + {text = "Science... is a curse.", yell = false}, + {text = "Run as fast as you can.", yell = false}, + {text = "Oh by the gods! What is this... aaaaaargh!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 44000, maxCount = 80}, + {name = "gold coin", chance = 44000, maxCount = 50}, + {name = "strange talisman", chance = 4980}, + {name = "silver amulet", chance = 70}, + {name = "fishbone", chance = 10050}, + {id = 2376, chance = 5030}, + {name = "scale armor", chance = 8080}, + {id = 2696, chance = 8000}, + {name = "fern", chance = 420}, + {name = "worm", chance = 7110, maxCount = 2}, + {name = "peanut", chance = 580}, + {id = 9808, chance = 190}, + {name = "mutated flesh", chance = 19940} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -90, condition = {type = CONDITION_POISON, totalDamage = 60, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -50, maxDamage = -60, length = 3, spread = 1, effect = CONST_ME_POISONAREA, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 20, minDamage = -190, maxDamage = -280, effect = CONST_ME_HITBYPOISON, target = true}, + {name ="speed", interval = 2000, chance = 10, speedChange = -600, range = 7, effect = CONST_ME_STUN, target = true, duration = 30000} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="speed", interval = 2000, chance = 15, speedChange = 220, effect = CONST_ME_GREEN_RINGS, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/necromancer.lua b/data/monster/humans/necromancer.lua new file mode 100644 index 00000000000..a2e6ee7b30e --- /dev/null +++ b/data/monster/humans/necromancer.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Necromancer") +local monster = {} + +monster.description = "a necromancer" +monster.experience = 580 +monster.outfit = { + lookType = 9, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 9 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "All the Tombs, Lich Hell, Drefia, Medusa Shield Quest room, Old Fortress, Old Masonry, \z + beneath Fenrock, Cemetery Quarter and Magician Quarter." + } + +monster.health = 580 +monster.maxHealth = 580 +monster.race = "blood" +monster.corpse = 20455 +monster.speed = 188 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Ghoul", chance = 15, interval = 2000}, + {name = "Ghost", chance = 5, interval = 2000}, + {name = "Mummy", chance = 5, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Your corpse will be mine.", yell = false}, + {text = "Taste the sweetness of death!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 30050, maxCount = 90}, + {name = "boots of haste", chance = 210}, + {name = "clerical mace", chance = 390}, + {name = "skull staff", chance = 100}, + {name = "poison arrow", chance = 15000, maxCount = 5}, + {name = "mystic turban", chance = 500}, + {name = "green mushroom", chance = 1470}, + {name = "noble axe", chance = 10}, + {name = "strong mana potion", chance = 300}, + {name = "spellbook of warding", chance = 130}, + {name = "book of necromantic rituals", chance = 10130}, + {name = "necromantic robe", chance = 1001} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -80, condition = {type = CONDITION_POISON, totalDamage = 160, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -60, maxDamage = -120, range = 1, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -65, maxDamage = -120, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 50, maxDamage = 80, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/necromancer_servant.lua b/data/monster/humans/necromancer_servant.lua new file mode 100644 index 00000000000..5fe8c77acd3 --- /dev/null +++ b/data/monster/humans/necromancer_servant.lua @@ -0,0 +1,97 @@ +local mType = Game.createMonsterType("Necromancer Servant") +local monster = {} + +monster.description = "a necromancer servant" +monster.experience = 590 +monster.outfit = { + lookType = 9, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 600 +monster.maxHealth = 600 +monster.race = "blood" +monster.corpse = 20455 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -45}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = -5, maxDamage = -40, range = 7, shootEffect = CONST_ANI_THROWINGKNIFE, target = false} +} + +monster.defenses = { + defense = 11, + armor = 11 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -8}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -7} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/nomad.lua b/data/monster/humans/nomad.lua new file mode 100644 index 00000000000..f74653e2a88 --- /dev/null +++ b/data/monster/humans/nomad.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Nomad") +local monster = {} + +monster.description = "a nomad" +monster.experience = 60 +monster.outfit = { + lookType = 146, + lookHead = 114, + lookBody = 20, + lookLegs = 22, + lookFeet = 2, + lookAddons = 2, + lookMount = 0 +} + +monster.raceId = 310 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 1, + Locations = "Ankrahmun Pharaoh Tombs, Deeper Drefia, Kha'zeel Mountains, Northern Darama Desert, \z + Southern Darama Desert, Yalahar Foreigner Quarter, Yalahar Trade Quarter." + } + +monster.health = 160 +monster.maxHealth = 160 +monster.race = "blood" +monster.corpse = 20466 +monster.speed = 190 +monster.manaCost = 420 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "We are the true sons of the desert!", yell = false}, + {text = "I will leave your remains to the vultures!", yell = false}, + {text = "Your riches will be mine!", yell = false}, + {text = "We are swift as the wind of the desert!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 56250, maxCount = 40}, + {name = "axe", chance = 2730}, + {name = "mace", chance = 2120}, + {name = "iron helmet", chance = 650}, + {name = "brass armor", chance = 2350}, + {name = "steel shield", chance = 920}, + {name = "nomad parchment", chance = 200}, + {name = "potato", chance = 4840, maxCount = 3}, + {name = "dirty turban", chance = 2160}, + {name = "rope belt", chance = 6420} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -80}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, radius = 1, effect = CONST_ME_SOUND_WHITE, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/nomad_female.lua b/data/monster/humans/nomad_female.lua new file mode 100644 index 00000000000..0c5de033d90 --- /dev/null +++ b/data/monster/humans/nomad_female.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Nomad Female") +local monster = {} + +monster.name = "Nomad" +monster.description = "a nomad" +monster.experience = 60 +monster.outfit = { + lookType = 150, + lookHead = 115, + lookBody = 39, + lookLegs = 59, + lookFeet = 2, + lookAddons = 2, + lookMount = 0 +} + +monster.raceId = 776 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 1, + Locations = "Drefia, Ankrahmun." + } + +monster.health = 160 +monster.maxHealth = 160 +monster.race = "blood" +monster.corpse = 20462 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I will leave your remains to the vultures!", yell = false}, + {text = "We are the true sons of the desert!", yell = false}, + {text = "We are swift as the wind of the desert!", yell = false}, + {text = "Your riches will be mine!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 56000, maxCount = 40}, + {id = 12448, chance = 6420}, + {id = 8838, chance = 4840, maxCount = 3}, + {id = 2386, chance = 2730}, + {id = 2465, chance = 2350}, + {id = 2398, chance = 2150}, + {id = 12412, chance = 2140}, + {id = 2509, chance = 900}, + {id = 2459, chance = 660}, + {id = 8267, chance = 210} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -80}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, radius = 1, effect = CONST_ME_SOUND_WHITE, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/nomadfemale.lua b/data/monster/humans/nomadfemale.lua new file mode 100644 index 00000000000..341cde31903 --- /dev/null +++ b/data/monster/humans/nomadfemale.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Nomad") +local monster = {} + +monster.description = "a nomad" +monster.experience = 60 +monster.outfit = { + lookType = 150, + lookHead = 115, + lookBody = 39, + lookLegs = 59, + lookFeet = 2, + lookAddons = 2, + lookMount = 0 +} + +monster.raceId = 777 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 1, + Locations = "Drefia, Ankrahmun." + } + +monster.health = 160 +monster.maxHealth = 160 +monster.race = "blood" +monster.corpse = 20462 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I will leave your remains to the vultures!", yell = false}, + {text = "We are the true sons of the desert!", yell = false}, + {text = "We are swift as the wind of the desert!", yell = false}, + {text = "Your riches will be mine!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 56000, maxCount = 40}, + {id = 12448, chance = 6420}, + {id = 8838, chance = 4840, maxCount = 3}, + {id = 2386, chance = 2730}, + {id = 2465, chance = 2350}, + {id = 2398, chance = 2150}, + {id = 12412, chance = 2140}, + {id = 2509, chance = 900}, + {id = 2459, chance = 660}, + {id = 8267, chance = 210} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -80}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, effect = CONST_ME_SOUND_WHITE, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/novice_of_the_cult.lua b/data/monster/humans/novice_of_the_cult.lua new file mode 100644 index 00000000000..d68a54665fd --- /dev/null +++ b/data/monster/humans/novice_of_the_cult.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Novice of the Cult") +local monster = {} + +monster.description = "a novice of the cult" +monster.experience = 100 +monster.outfit = { + lookType = 133, + lookHead = 114, + lookBody = 95, + lookLegs = 114, + lookFeet = 114, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 255 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Liberty Bay Cult Cave, Formorgar Mines, Yalahar Magician Quarter, \z + in the caves on top of the Hrodmir mountains." + } + +monster.health = 285 +monster.maxHealth = 285 +monster.race = "blood" +monster.corpse = 20467 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 40, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Chicken", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Fear us!", yell = false}, + {text = "You will not tell anyone what you have seen!", yell = false}, + {text = "Your curiosity will be punished!", yell = false} +} + +monster.loot = { + {id = 1962, chance = 700}, + {name = "small diamond", chance = 210}, + {name = "gold coin", chance = 43380, maxCount = 40}, + {name = "wand of vortex", chance = 450}, + {name = "garlic necklace", chance = 420}, + {name = "dwarven ring", chance = 500}, + {name = "scarf", chance = 2900}, + {name = "pirate voodoo doll", chance = 520}, + {id = 6087, chance = 970}, + {name = "cultish robe", chance = 1030}, + {name = "rope belt", chance = 5910} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -65, condition = {type = CONDITION_POISON, totalDamage = 1, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -20, maxDamage = -80, range = 7, radius = 1, shootEffect = CONST_ANI_POISON, effect = CONST_ME_MAGIC_RED, target = true} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 20, maxDamage = 40, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = -8}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -8} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/pirate_buccaneer.lua b/data/monster/humans/pirate_buccaneer.lua new file mode 100644 index 00000000000..1cb3e17f98b --- /dev/null +++ b/data/monster/humans/pirate_buccaneer.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Pirate Buccaneer") +local monster = {} + +monster.description = "a pirate buccaneer" +monster.experience = 250 +monster.outfit = { + lookType = 97, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 249 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Nargor, Tyrsung (on the ship), Yalahar (Foreign Quarter), Krailos Steppe." + } + +monster.health = 425 +monster.maxHealth = 425 +monster.race = "blood" +monster.corpse = 20471 +monster.speed = 218 +monster.manaCost = 595 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 50, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Give up!", yell = false}, + {text = "Hiyaa", yell = false}, + {text = "Plundeeeeer!", yell = false} +} + +monster.loot = { + {id = 2050, chance = 10190}, + {name = "gold coin", chance = 67740, maxCount = 59}, + {name = "worn leather boots", chance = 9900}, + {name = "sabre", chance = 10100}, + {name = "throwing knife", chance = 9000, maxCount = 5}, + {name = "plate armor", chance = 1130}, + {name = "battle shield", chance = 3850}, + {id = 5091, chance = 1000}, + {name = "rum flask", chance = 120}, + {id = 5792, chance = 40}, + {name = "pirate backpack", chance = 430}, + {name = "pirate shirt", chance = 1200}, + {name = "hook", chance = 450}, + {name = "eye patch", chance = 420}, + {name = "peg leg", chance = 510}, + {name = "strong health potion", chance = 670}, + {name = "compass", chance = 9780} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -160}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -100, range = 4, shootEffect = CONST_ANI_THROWINGKNIFE, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/pirate_corsair.lua b/data/monster/humans/pirate_corsair.lua new file mode 100644 index 00000000000..a8a25784dfc --- /dev/null +++ b/data/monster/humans/pirate_corsair.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Pirate Corsair") +local monster = {} + +monster.description = "a pirate corsair" +monster.experience = 350 +monster.outfit = { + lookType = 98, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 250 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Nargor, Trade Quarter, Foreigner Quarter (Dock), Krailos Steppe." + } + +monster.health = 675 +monster.maxHealth = 675 +monster.race = "blood" +monster.corpse = 20475 +monster.speed = 238 +monster.manaCost = 775 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 40, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Give up!", yell = false}, + {text = "Hiyaa!", yell = false}, + {text = "Plundeeeeer!", yell = false} +} + +monster.loot = { + {name = "piggy bank", chance = 150}, + {name = "gold coin", chance = 50000, maxCount = 88}, + {name = "sabre", chance = 10000}, + {name = "throwing star", chance = 8400, maxCount = 12}, + {name = "dark armor", chance = 1650}, + {name = "dark shield", chance = 1000}, + {name = "pirate boots", chance = 220}, + {name = "rum flask", chance = 130}, + {id = 5813, chance = 130}, + {name = "pirate backpack", chance = 930}, + {name = "pirate hat", chance = 1150}, + {name = "hook", chance = 600}, + {name = "eye patch", chance = 500}, + {name = "peg leg", chance = 600}, + {name = "strong health potion", chance = 820}, + {name = "compass", chance = 11050}, + {name = "compass", chance = 11020} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -170}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -150, range = 7, shootEffect = CONST_ANI_THROWINGSTAR, target = false}, + {name ="pirate corsair skill reducer", interval = 2000, chance = 5, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/pirate_cutthroat.lua b/data/monster/humans/pirate_cutthroat.lua new file mode 100644 index 00000000000..c89554278bb --- /dev/null +++ b/data/monster/humans/pirate_cutthroat.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Pirate Cutthroat") +local monster = {} + +monster.description = "a pirate cutthroat" +monster.experience = 175 +monster.outfit = { + lookType = 96, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 248 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Nargor, Tyrsung (on the ship), Yalahar, Krailos Steppe." + } + +monster.health = 325 +monster.maxHealth = 325 +monster.race = "blood" +monster.corpse = 20479 +monster.speed = 214 +monster.manaCost = 495 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Give up!", yell = false}, + {text = "Hiyaa!", yell = false}, + {text = "Plundeeeeer!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 78000, maxCount = 50}, + {name = "scale armor", chance = 3000}, + {name = "steel shield", chance = 2800}, + {id = 5091, chance = 1000}, + {name = "rum flask", chance = 90}, + {name = "light shovel", chance = 2000}, + {id = 5792, chance = 110}, + {name = "pirate knee breeches", chance = 980}, + {name = "pirate bag", chance = 1000}, + {name = "hook", chance = 550}, + {name = "eye patch", chance = 450}, + {name = "peg leg", chance = 500}, + {name = "compass", chance = 10120} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -170, condition = {type = CONDITION_POISON, totalDamage = 10, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -95, range = 7, radius = 1, shootEffect = CONST_ANI_EXPLOSION, effect = CONST_ME_EXPLOSIONAREA, target = true} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/pirate_marauder.lua b/data/monster/humans/pirate_marauder.lua new file mode 100644 index 00000000000..c397730bb0a --- /dev/null +++ b/data/monster/humans/pirate_marauder.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Pirate Marauder") +local monster = {} + +monster.description = "a pirate marauder" +monster.experience = 125 +monster.outfit = { + lookType = 93, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 247 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Nargor, Tyrsung, Yalahar, Krailos Steppe." + } + +monster.health = 210 +monster.maxHealth = 210 +monster.race = "blood" +monster.corpse = 20483 +monster.speed = 210 +monster.manaCost = 490 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Plundeeeeer!", yell = false}, + {text = "Give up!", yell = false}, + {text = "Hiyaa!", yell = false} +} + +monster.loot = { + {id = 2050, chance = 9880}, + {name = "gold coin", chance = 77670, maxCount = 40}, + {name = "spear", chance = 5140, maxCount = 2}, + {name = "chain armor", chance = 3000}, + {name = "plate shield", chance = 5000}, + {id = 5091, chance = 910}, + {name = "rum flask", chance = 110}, + {id = 5792, chance = 90}, + {name = "bandana", chance = 880}, + {name = "pirate bag", chance = 430}, + {name = "empty goldfish bowl", chance = 80}, + {name = "hook", chance = 520}, + {name = "eye patch", chance = 530}, + {name = "peg leg", chance = 520}, + {name = "compass", chance = 9720} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -140}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -40, range = 7, shootEffect = CONST_ANI_SPEAR, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/poacher.lua b/data/monster/humans/poacher.lua new file mode 100644 index 00000000000..b023bd4ccde --- /dev/null +++ b/data/monster/humans/poacher.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Poacher") +local monster = {} + +monster.description = "a poacher" +monster.experience = 70 +monster.outfit = { + lookType = 129, + lookHead = 115, + lookBody = 119, + lookLegs = 119, + lookFeet = 115, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 376 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "South of Elvenbane and Ab'Dendriel, Ferngrims Gate, Northeast of Carlin, \z + Edron Hunter Camps, Yalahar - Trade Quarter and Foreigner Quarter." + } + +monster.health = 90 +monster.maxHealth = 90 +monster.race = "blood" +monster.corpse = 20487 +monster.speed = 198 +monster.manaCost = 530 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 5, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You will not live to tell anyone!", yell = false}, + {text = "You are my game today!", yell = false}, + {text = "Look what has stepped into my trap!", yell = false} +} + +monster.loot = { + {id = 2050, chance = 4180}, + {name = "bow", chance = 14930}, + {name = "leather helmet", chance = 30600}, + {name = "arrow", chance = 49500, maxCount = 17}, + {name = "poison arrow", chance = 2930, maxCount = 3}, + {id = 2578, chance = 710}, + {name = "leather legs", chance = 26740}, + {name = "roll", chance = 11110, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -35}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -35, range = 7, shootEffect = CONST_ANI_ARROW, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/priestess.lua b/data/monster/humans/priestess.lua new file mode 100644 index 00000000000..cb1a8a34380 --- /dev/null +++ b/data/monster/humans/priestess.lua @@ -0,0 +1,140 @@ +local mType = Game.createMonsterType("Priestess") +local monster = {} + +monster.description = "a priestess" +monster.experience = 420 +monster.outfit = { + lookType = 58, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 58 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Hero Cave, Drefia ruins, Lich Hell, Tombs, Magician Quarter in Yalahar, Vengoth Castle." + } + +monster.health = 390 +monster.maxHealth = 390 +monster.race = "blood" +monster.corpse = 20491 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "ghoul", chance = 10, interval = 2000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Your energy is mine.", yell = false}, + {text = "Now your life is come to the end, hahahaha!", yell = false}, + {text = "Throw the soul on the altar!", yell = false} +} + +monster.loot = { + {id = 1962, chance = 890}, + {id = 2070, chance = 1410}, + {name = "piggy bank", chance = 90}, + {name = "crystal necklace", chance = 640}, + {name = "talon", chance = 750}, + {name = "hailstorm rod", chance = 1100}, + {id = 2192, chance = 1250}, + {id = 2070, chance = 1400}, + {name = "clerical mace", chance = 1500}, + {name = "black shield", chance = 210}, + {name = "red apple", chance = 7500, maxCount = 2}, + {name = "goat grass", chance = 11720}, + {name = "wood mushroom", chance = 3240}, + {name = "sling herb", chance = 13200}, + {name = "powder herb", chance = 5900}, + {name = "mana potion", chance = 850}, + {name = "cultish robe", chance = 1800}, + {name = "black hood", chance = 5230}, + {name = "dark rosary", chance = 9840} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -75}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -55, maxDamage = -120, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_MANADRAIN, minDamage = -2, maxDamage = -170, range = 7, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, range = 7, shootEffect = CONST_ANI_POISON, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 50, maxDamage = 80, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 70}, + {type = COMBAT_FIREDAMAGE, percent = 40}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/priestess_of_the_wild_sun.lua b/data/monster/humans/priestess_of_the_wild_sun.lua new file mode 100644 index 00000000000..ef0d5e28c6b --- /dev/null +++ b/data/monster/humans/priestess_of_the_wild_sun.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Priestess of the Wild Sun") +local monster = {} + +monster.description = "a priestess of the wild sun" +monster.experience = 6400 +monster.outfit = { + lookType = 1199, + lookHead = 114, + lookBody = 78, + lookLegs = 94, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1799 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Issavi Sewers, Kilmaresh Mountains, Kilmaresh Catacombs." + } + +monster.health = 8500 +monster.maxHealth = 8500 +monster.race = "blood" +monster.corpse = 36254 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Fafnar will burn you!", yell = false}, + {text = "Fear the Wild Sun!", yell = false}, + {text = "There is only one true sun!", yell = false} +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 2}, + {name = "fafnar symbol", chance = 7360}, + {id = 36268, chance = 6610}, + {id = 36270, chance = 6610}, + {id = 36271, chance = 6610}, + {id = 36166, chance = 2540}, + {name = "sea horse figurine", chance = 910}, + {id = 36204, chance = 530}, + {name = "wand of decay", chance = 1250}, + {name = "wand of everblazing", chance = 1290}, + {name = "golden sickle", chance = 1250}, + {name = "relic sword", chance = 1390}, + {name = "war axe", chance = 1777} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -350}, + {name ="targetfirering", interval = 2000, chance = 8, minDamage = -300, maxDamage = -500, target = true}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_FIREDAMAGE, minDamage = -350, maxDamage = -500, radius = 2, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_EXPLOSIONHIT, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -250, maxDamage = -400, radius = 3, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = -250, maxDamage = -350, length = 4, spread = 3, effect = CONST_ME_ENERGYHIT, target = false} +} + +monster.defenses = { + defense = 82, + armor = 82 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 85}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -25}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/renegade_knight.lua b/data/monster/humans/renegade_knight.lua new file mode 100644 index 00000000000..a2771bc3279 --- /dev/null +++ b/data/monster/humans/renegade_knight.lua @@ -0,0 +1,137 @@ +local mType = Game.createMonsterType("Renegade Knight") +local monster = {} + +monster.description = "a renegade knight" +monster.experience = 1200 +monster.outfit = { + lookType = 268, + lookHead = 97, + lookBody = 132, + lookLegs = 76, + lookFeet = 98, + lookAddons = 2, + lookMount = 0 +} + +monster.raceId = 1146 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Old Fortress (north of Edron), Old Masonry, Forbidden Temple (Carlin)." + } + +monster.health = 1450 +monster.maxHealth = 1450 +monster.race = "blood" +monster.corpse = 24676 +monster.speed = 270 +monster.manaCost = 390 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I'll teach you a lesson!", yell = false}, + {text = "Take this!", yell = false}, + {text = "Let's see how good you are!", yell = false}, + {text = "Feel my steel!", yell = false}, + {text = "A challenge at last!", yell = false} +} + +monster.loot = { + {id = 2544, chance = 90450, maxCount = 10}, + {id = 2148, chance = 75410, maxCount = 30}, + {id = 2681, chance = 1210}, + {id = 7591, chance = 1210}, + {id = 2666, chance = 1210, maxCount = 2}, + {id = 7364, chance = 1210, maxCount = 4}, + {id = 2487, chance = 210}, + {id = 2491, chance = 310}, + {id = 2519, chance = 210}, + {id = 2488, chance = 110}, + {id = 2392, chance = 310}, + {id = 2381, chance = 1610}, + {id = 2744, chance = 510}, + {id = 2120, chance = 1510}, + {id = 1949, chance = 910}, + {id = 12466, chance = 910}, + {id = 12406, chance = 910}, + {id = 2121, chance = 510} +} + +monster.attacks = { + {name ="renegade knight", interval = 2000, chance = 30, target = false}, + {name ="melee", interval = 2000, chance = 100, minDamage = 10, maxDamage = -175} +} + +monster.defenses = { + defense = 50, + armor = 35, + {name ="combat", interval = 4000, chance = 25, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/shadow_pupil.lua b/data/monster/humans/shadow_pupil.lua new file mode 100644 index 00000000000..93b070e4773 --- /dev/null +++ b/data/monster/humans/shadow_pupil.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Shadow Pupil") +local monster = {} + +monster.description = "a shadow pupil" +monster.experience = 410 +monster.outfit = { + lookType = 551, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 960 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Drefia." + } + +monster.health = 450 +monster.maxHealth = 450 +monster.race = "blood" +monster.corpse = 21254 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Skeleton", chance = 10, interval = 2000}, + {name = "Ghost", chance = 5, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "When I'm finished with you, you'll be a shadow of your former self.", yell = false}, + {text = "The shadows will swallow you...", yell = false}, + {text = "The shadows follow your every step...", yell = false}, + {text = "Come forth from the shadows, my minions...", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 64}, + {name = "boots of haste", chance = 60}, + {name = "clerical mace", chance = 290}, + {name = "mystic turban", chance = 580}, + {name = "brown mushroom", chance = 5170}, + {name = "strong mana potion", chance = 470}, + {name = "spellbook of enlightenment", chance = 290}, + {name = "book of necromantic rituals", chance = 6920}, + {name = "horoscope", chance = 15000}, + {name = "incantation notes", chance = 9130}, + {name = "pieces of magic chalk", chance = 4300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -70, condition = {type = CONDITION_POISON, totalDamage = 90, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -60, maxDamage = -80, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -30, maxDamage = -60, radius = 3, effect = CONST_ME_MORTAREA, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/smuggler.lua b/data/monster/humans/smuggler.lua new file mode 100644 index 00000000000..6268cf90414 --- /dev/null +++ b/data/monster/humans/smuggler.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Smuggler") +local monster = {} + +monster.description = "a smuggler" +monster.experience = 48 +monster.outfit = { + lookType = 134, + lookHead = 95, + lookBody = 0, + lookLegs = 113, + lookFeet = 115, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 222 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Around Dark Cathedral, Tiquanda Bandit Caves, the Outlaw Camp, Tyrsung, Yalahar and Nargor." + } + +monster.health = 130 +monster.maxHealth = 130 +monster.race = "blood" +monster.corpse = 20507 +monster.speed = 176 +monster.manaCost = 390 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I will silence you forever!", yell = false}, + {text = "You saw something you shouldn't!", yell = false} +} + +monster.loot = { + {id = 2050, chance = 30200, maxCount = 2}, + {name = "gold coin", chance = 80000, maxCount = 10}, + {id = 2376, chance = 5000}, + {name = "knife", chance = 9920}, + {name = "combat knife", chance = 4400}, + {name = "short sword", chance = 10000}, + {name = "leather helmet", chance = 10050}, + {name = "leather legs", chance = 14840}, + {name = "ham", chance = 10200}, + {id = 7397, chance = 110}, + {name = "raspberry", chance = 5000, maxCount = 5} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -60} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/stalker.lua b/data/monster/humans/stalker.lua new file mode 100644 index 00000000000..3c016eda489 --- /dev/null +++ b/data/monster/humans/stalker.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Stalker") +local monster = {} + +monster.description = "a stalker" +monster.experience = 90 +monster.outfit = { + lookType = 128, + lookHead = 78, + lookBody = 116, + lookLegs = 95, + lookFeet = 114, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 72 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Triangle Tower, Drefia, Edron Hero Cave in the Warlock room, White Flower Temple, \z + Ghostlands, Shadow Tomb, Ancient Ruins Tomb, Tarpit Tomb, Stone Tomb, Mountain Tomb, Peninsula Tomb, \z + Oasis Tomb, Yalahar Trade Quarter and Isle of the Kings." + } + +monster.health = 120 +monster.maxHealth = 120 +monster.race = "blood" +monster.corpse = 20511 +monster.speed = 260 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 60, + random = 40, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 13000, maxCount = 8}, + {name = "blank rune", chance = 8670}, + {name = "throwing knife", chance = 11170, maxCount = 2}, + {name = "katana", chance = 530}, + {name = "obsidian lance", chance = 1210}, + {name = "brass legs", chance = 3500}, + {name = "brass legs", chance = 5510}, + {name = "miraculum", chance = 1550} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -70}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -20, maxDamage = -30, range = 1, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="invisible", interval = 2000, chance = 40, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -20}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/valkyrie.lua b/data/monster/humans/valkyrie.lua new file mode 100644 index 00000000000..546858aa304 --- /dev/null +++ b/data/monster/humans/valkyrie.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Valkyrie") +local monster = {} + +monster.description = "a valkyrie" +monster.experience = 85 +monster.outfit = { + lookType = 139, + lookHead = 113, + lookBody = 38, + lookLegs = 95, + lookFeet = 96, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 12 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Amazon Camp (Venore), Amazon Camp (Carlin), Amazonia, \z + single respawn to the north west of Thais, Foreigner Quarter in Yalahar." + } + +monster.health = 190 +monster.maxHealth = 190 +monster.race = "blood" +monster.corpse = 20523 +monster.speed = 176 +monster.manaCost = 450 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Another head for me!", yell = false}, + {text = "Head off!", yell = false}, + {text = "Your head will be mine!", yell = false}, + {text = "Stand still!", yell = false}, + {text = "One more head for me!", yell = false} +} + +monster.loot = { + {name = "spear", chance = 55000, maxCount = 3}, + {name = "gold coin", chance = 32000, maxCount = 12}, + {name = "meat", chance = 30000}, + {name = "chain armor", chance = 10000}, + {name = "red apple", chance = 7500, maxCount = 2}, + {name = "girlish hair decoration", chance = 5900}, + {name = "hunting spear", chance = 5155}, + {name = "protective charm", chance = 3200}, + {name = "protection amulet", chance = 1100}, + {name = "plate armor", chance = 830}, + {id = 2229, chance = 760}, + {name = "health potion", chance = 500}, + {name = "double axe", chance = 430}, + {name = "small diamond", chance = 130} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -70}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -50, range = 5, shootEffect = CONST_ANI_SPEAR, target = false} +} + +monster.defenses = { + defense = 12, + armor = 12 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 5}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/vicious_squire.lua b/data/monster/humans/vicious_squire.lua new file mode 100644 index 00000000000..775bee668ca --- /dev/null +++ b/data/monster/humans/vicious_squire.lua @@ -0,0 +1,135 @@ +local mType = Game.createMonsterType("Vicious Squire") +local monster = {} + +monster.description = "a vicious squire" +monster.experience = 900 +monster.outfit = { + lookType = 131, + lookHead = 97, + lookBody = 26, + lookLegs = 71, + lookFeet = 114, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 1145 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Old Fortress (north of Edron), Old Masonry, Forbidden Temple (Carlin)." + } + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "blood" +monster.corpse = 24673 +monster.speed = 260 +monster.manaCost = 390 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I'll cut you a bloody grin!", yell = false}, + {text = "You shouldn't have come here!", yell = false}, + {text = "Your stuff will be mine soon!", yell = false}, + {text = "For hurting me, my sire will kill you!", yell = false} +} + +monster.loot = { + {id = 2543, chance = 90450, maxCount = 10}, + {id = 2148, chance = 75410, maxCount = 30}, + {id = 2681, chance = 15400}, + {id = 7591, chance = 12340, maxCount = 2}, + {id = 2666, chance = 5000}, + {id = 2455, chance = 830}, + {id = 2652, chance = 760}, + {id = 2164, chance = 700, maxCount = 2}, + {id = 2120, chance = 1000}, + {id = 2661, chance = 1000}, + {id = 1949, chance = 830}, + {id = 2145, chance = 830}, + {id = 2391, chance = 130}, + {id = 2381, chance = 830}, + {id = 2515, chance = 330}, + {id = 2477, chance = 230}, + {id = 2475, chance = 200} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 10, maxDamage = -175}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_PHYSICALDAMAGE, minDamage = 10, maxDamage = -100, range = 7, shootEffect = CONST_ANI_BOLT, target = false} +} + +monster.defenses = { + defense = 50, + armor = 35, + {name ="combat", interval = 4000, chance = 25, type = COMBAT_HEALING, minDamage = 20, maxDamage = 80, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/vile_grandmaster.lua b/data/monster/humans/vile_grandmaster.lua new file mode 100644 index 00000000000..2d0087a909c --- /dev/null +++ b/data/monster/humans/vile_grandmaster.lua @@ -0,0 +1,143 @@ +local mType = Game.createMonsterType("Vile Grandmaster") +local monster = {} + +monster.description = "a vile grandmaster" +monster.experience = 1500 +monster.outfit = { + lookType = 268, + lookHead = 97, + lookBody = 0, + lookLegs = 95, + lookFeet = 94, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 1147 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Old Fortress (north of Edron), Old Masonry, Forbidden Temple (Carlin)." + } + +monster.health = 1700 +monster.maxHealth = 1700 +monster.race = "blood" +monster.corpse = 24679 +monster.speed = 280 +monster.manaCost = 390 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I will end this now!", yell = false}, + {text = "I've seen orcs tougher than you!", yell = false}, + {text = "Your gods won't help you!", yell = false}, + {text = "Is that the best, you can throw at me?", yell = false}, + {text = "You'll make a fine trophy!", yell = false} +} + +monster.loot = { + {id = 7364, chance = 1210, maxCount = 4}, + {id = 2148, chance = 75410, maxCount = 30}, + {id = 2152, chance = 75410, maxCount = 2}, + {id = 2681, chance = 1210}, + {id = 2666, chance = 1210, maxCount = 2}, + {id = 7591, chance = 1210}, + {id = 2381, chance = 1610}, + {id = 2744, chance = 510}, + {id = 2120, chance = 1510}, + {id = 12466, chance = 910}, + {id = 12406, chance = 910}, + {id = 2147, chance = 810, maxCount = 2}, + {id = 2146, chance = 810, maxCount = 2}, + {id = 2121, chance = 510}, + {id = 5911, chance = 210}, + {id = 2391, chance = 210}, + {id = 2487, chance = 310}, + {id = 2392, chance = 210}, + {id = 2491, chance = 310}, + {id = 2519, chance = 210}, + {id = 2488, chance = 110}, + {id = 2171, chance = 210} +} + +monster.attacks = { + {name ="vile grandmaster", interval = 2000, chance = 15, target = false}, + {name ="melee", interval = 2000, chance = 100, minDamage = 10, maxDamage = -260}, + -- bleed + {name ="condition", type = CONDITION_BLEEDING, interval = 2000, chance = 20, minDamage = -150, maxDamage = -225, radius = 4, shootEffect = CONST_ANI_THROWINGKNIFE, target = true} +} + +monster.defenses = { + defense = 50, + armor = 35, + {name ="combat", interval = 4000, chance = 15, type = COMBAT_HEALING, minDamage = 220, maxDamage = 280, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/warlock.lua b/data/monster/humans/warlock.lua new file mode 100644 index 00000000000..89820976b2a --- /dev/null +++ b/data/monster/humans/warlock.lua @@ -0,0 +1,151 @@ +local mType = Game.createMonsterType("Warlock") +local monster = {} + +monster.description = "a warlock" +monster.experience = 4000 +monster.outfit = { + lookType = 130, + lookHead = 19, + lookBody = 71, + lookLegs = 128, + lookFeet = 128, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 10 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Demona, Ghostland (Banshee Quest area), Temple of Xayepocax, Oasis Tomb, Kharos, Magician Quarter, \z + beneath Fenrock, The Arcanum." + } + +monster.health = 3500 +monster.maxHealth = 3500 +monster.race = "blood" +monster.corpse = 20527 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 900, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "stone golem", chance = 10, interval = 2000, max = 1} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Learn the secret of our magic! YOUR death!", yell = false}, + {text = "Even a rat is a better mage than you!", yell = false}, + {text = "We don't like intruders!", yell = false} +} + +monster.loot = { + {name = "red tome", chance = 300}, + {name = "candlestick", chance = 1500}, + {name = "piggy bank", chance = 60}, + {name = "ring of the sky", chance = 430}, + {id = 2124, chance = 700}, + {name = "small sapphire", chance = 1190}, + {name = "gold coin", chance = 29340, maxCount = 80}, + {name = "talon", chance = 1150}, + {name = "energy ring", chance = 2200}, + {name = "mind stone", chance = 2000}, + {name = "stone skin amulet", chance = 330}, + {name = "poison dagger", chance = 7600}, + {name = "skull staff", chance = 6370}, + {name = "golden armor", chance = 240}, + {id = 2600, chance = 1000}, + {name = "blue robe", chance = 1410}, + {name = "cherry", chance = 19000, maxCount = 4}, + {name = "bread", chance = 9000}, + {name = "dark mushroom", chance = 3000}, + {name = "assassin star", chance = 3500, maxCount = 4}, + {name = "assassin star", chance = 3470, maxCount = 4}, + {name = "great mana potion", chance = 4760}, + {name = "great health potion", chance = 5190}, + {name = "lightning robe", chance = 1000}, + {name = "luminous orb", chance = 510} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -130}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -90, maxDamage = -180, range = 7, shootEffect = CONST_ANI_ENERGY, target = false}, + {name ="warlock skill reducer", interval = 2000, chance = 5, range = 5, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -120, range = 7, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -50, maxDamage = -180, range = 7, radius = 3, shootEffect = CONST_ANI_BURSTARROW, effect = CONST_ME_FIREAREA, target = true}, + {name ="firefield", interval = 2000, chance = 10, range = 7, radius = 2, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -150, maxDamage = -230, length = 8, spread = 3, effect = CONST_ME_BIGCLOUDS, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -600, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 100, maxDamage = 225, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 20, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 95}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/wild_warrior.lua b/data/monster/humans/wild_warrior.lua new file mode 100644 index 00000000000..d177a295660 --- /dev/null +++ b/data/monster/humans/wild_warrior.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Wild Warrior") +local monster = {} + +monster.description = "a wild warrior" +monster.experience = 60 +monster.outfit = { + lookType = 131, + lookHead = 57, + lookBody = 57, + lookLegs = 57, + lookFeet = 57, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 47 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Dark Cathedral, Outlaw Camp, North of Thais, Cyclopolis, in Edron Hero Cave and around it, \z + the small camp near Femor Hills, in Ghostlands disguised as a statue." + } + +monster.health = 135 +monster.maxHealth = 135 +monster.race = "blood" +monster.corpse = 20531 +monster.speed = 190 +monster.manaCost = 420 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "An enemy!", yell = false}, + {text = "Gimme your money!", yell = false} +} + +monster.loot = { + {id = 2110, chance = 520}, + {name = "gold coin", chance = 49070, maxCount = 30}, + {name = "axe", chance = 30710}, + {name = "mace", chance = 9800}, + {name = "chain helmet", chance = 5250}, + {name = "iron helmet", chance = 580}, + {name = "brass armor", chance = 2540}, + {name = "steel shield", chance = 910}, + {name = "brass shield", chance = 17000}, + {id = 2695, chance = 9730, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -70} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="speed", interval = 2000, chance = 15, speedChange = 200, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/humans/witch.lua b/data/monster/humans/witch.lua new file mode 100644 index 00000000000..ed1b1fc72dd --- /dev/null +++ b/data/monster/humans/witch.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Witch") +local monster = {} + +monster.description = "a witch" +monster.experience = 120 +monster.outfit = { + lookType = 54, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 54 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Vandura, west of the Dwarf Mines in a small house, Amazon Tower north of Carlin, \z + Triangle Tower, Temple of Xayepocax, Green Claw Swamp and Amazon Camp (Venore), \z + Dark Cathedral (2 levels underground), Goroma Volcano (underground), west from Necromant House, \z + Mammoth Shearing Factory, Trade Quarter in Yalahar, The Witches' Cliff (only accessible during a quest)." + } + +monster.health = 300 +monster.maxHealth = 300 +monster.race = "blood" +monster.corpse = 20535 +monster.speed = 204 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 30, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Horax Pokti!", yell = false}, + {text = "Herba budinia ex!", yell = false}, + {text = "Hihihihi!", yell = false} +} + +monster.loot = { + {id = 2129, chance = 10120}, + {name = "gold coin", chance = 64000, maxCount = 40}, + {name = "necrotic rod", chance = 1140}, + {name = "garlic necklace", chance = 1000}, + {name = "silver dagger", chance = 500}, + {name = "sickle", chance = 3910}, + {name = "leather boots", chance = 4950}, + {name = "coat", chance = 2010}, + {name = "cape", chance = 4870}, + {name = "cookie", chance = 29750, maxCount = 8}, + {name = "star herb", chance = 8950}, + {name = "witch broom", chance = 10000}, + {name = "witch hat", chance = 80}, + {name = "stuffed toad", chance = 10}, + {name = "bag of apple slices", chance = 920} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -20}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -30, maxDamage = -75, range = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="firefield", interval = 2000, chance = 10, range = 7, radius = 1, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="outfit", interval = 2000, chance = 1, range = 5, target = true, duration = 2000, outfitMonster = "green frog"} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/lycanthropes/werebadger.lua b/data/monster/lycanthropes/werebadger.lua new file mode 100644 index 00000000000..ccf3567571c --- /dev/null +++ b/data/monster/lycanthropes/werebadger.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Werebadger") +local monster = {} + +monster.description = "a werebadger" +monster.experience = 1600 +monster.outfit = { + lookType = 729, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1144 +monster.Bestiary = { + class = "Lycanthrope", + race = BESTY_RACE_LYCANTHROPE, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Grimvale: -1 floor from ground level, also seen on surface during full moon (12th-14th of every month). \z + Also in the were-beasts cave south-west of Edron and in the Last Sanctum." + } + +monster.health = 1700 +monster.maxHealth = 1700 +monster.race = "blood" +monster.corpse = 24723 +monster.speed = 260 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 275, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "SNUFFLE", yell = false} +} + +monster.loot = { + {id = 2148, chance = 97000, maxCount = 242}, + {id = 2152, chance = 18200, maxCount = 5}, + {id = 8845, chance = 2000}, + {id = 2789, chance = 2000}, + {id = 7620, chance = 2210}, + {id = 7589, chance = 1200}, + {id = 2805, chance = 1900}, + {id = 24707, chance = 950}, + {id = 24711, chance = 780}, + {id = 24742, chance = 200}, + {id = 2171, chance = 160}, + {id = 2214, chance = 430}, + {id = 8910, chance = 220}, + {id = 8922, chance = 200}, + {id = 24739, chance = 150}, + {id = 24716, chance = 200}, + {id = 24757, chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 60, condition = {type = CONDITION_POISON, totalDamage = 140, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -21, maxDamage = -150, range = 7, shootEffect = CONST_ANI_EARTH, effect = CONST_ME_CARNIPHILA, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -10, maxDamage = -100, length = 8, spread = 3, effect = CONST_ME_CARNIPHILA, target = false}, + {name ="speed", interval = 4000, chance = 20, radius = 7, effect = CONST_ME_POFF, target = true} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 50, maxDamage = 100, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 20, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/lycanthropes/werebear.lua b/data/monster/lycanthropes/werebear.lua new file mode 100644 index 00000000000..5a34554c4ed --- /dev/null +++ b/data/monster/lycanthropes/werebear.lua @@ -0,0 +1,138 @@ +local mType = Game.createMonsterType("Werebear") +local monster = {} + +monster.description = "a werebear" +monster.experience = 2100 +monster.outfit = { + lookType = 720, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1142 +monster.Bestiary = { + class = "Lycanthrope", + race = BESTY_RACE_LYCANTHROPE, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Grimvale underground, were-beasts cave south-west of Edron and in the Last Sanctum east of Cormaya." + } + +monster.health = 2400 +monster.maxHealth = 2400 +monster.race = "blood" +monster.corpse = 24666 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 275, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "GROOOWL", yell = false}, + {text = "GRRR", yell = false} +} + +monster.loot = { + {id = 2148, chance = 97000, maxCount = 242}, + {id = 2152, chance = 18200, maxCount = 5}, + {id = 7591, chance = 1200, maxCount = 2}, + {id = 8473, chance = 2210}, + {id = 7590, chance = 1200}, + {id = 5896, chance = 800}, + {id = 2671, chance = 1900, maxCount = 2}, + {id = 5902, chance = 450}, + {id = 24713, chance = 580}, + {id = 7439, chance = 800}, + {id = 24712, chance = 560}, + {id = 2197, chance = 430}, + {id = 7419, chance = 120}, + {id = 24741, chance = 300}, + {id = 7432, chance = 400}, + {id = 24716, chance = 100}, + {id = 7383, chance = 200}, + {id = 7452, chance = 300}, + {id = 2169, chance = 400}, + {id = 24759, chance = 200}, + {id = 24739, chance = 200} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 50, maxDamage = -485}, + {name ="speed", interval = 4000, chance = 20, radius = 7, effect = CONST_ME_POFF, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -65, maxDamage = -335, radius = 4, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 50, maxDamage = 100, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/lycanthropes/wereboar.lua b/data/monster/lycanthropes/wereboar.lua new file mode 100644 index 00000000000..2eeb83c7098 --- /dev/null +++ b/data/monster/lycanthropes/wereboar.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Wereboar") +local monster = {} + +monster.description = "a wereboar" +monster.experience = 2000 +monster.outfit = { + lookType = 721, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1143 +monster.Bestiary = { + class = "Lycanthrope", + race = BESTY_RACE_LYCANTHROPE, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Grimvale underground, were-beasts cave south-west of Edron and in the Last Sanctum east of Cormaya." + } + +monster.health = 2200 +monster.maxHealth = 2200 +monster.race = "blood" +monster.corpse = 24722 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 275, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "GRUNT", yell = false} +} + +monster.loot = { + {id = 2148, chance = 97000, maxCount = 242}, + {id = 2152, chance = 18200, maxCount = 5}, + {id = 2789, chance = 2000}, + {id = 8473, chance = 2210}, + {id = 7588, chance = 1200}, + {id = 24709, chance = 1900}, + {id = 24743, chance = 950}, + {id = 24710, chance = 780}, + {id = 7439, chance = 700}, + {id = 7432, chance = 360}, + {id = 2197, chance = 430}, + {id = 7419, chance = 320}, + {id = 24741, chance = 200}, + {id = 24758, chance = 200}, + {id = 24429, chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 60, condition = {type = CONDITION_POISON, totalDamage = 140, interval = 4000}}, + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -385}, + {name ="speed", interval = 4000, chance = 20, radius = 7, effect = CONST_ME_POFF, target = true} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 50, maxDamage = 100, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 20, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/lycanthropes/werefox.lua b/data/monster/lycanthropes/werefox.lua new file mode 100644 index 00000000000..7bba98e1536 --- /dev/null +++ b/data/monster/lycanthropes/werefox.lua @@ -0,0 +1,139 @@ +local mType = Game.createMonsterType("Werefox") +local monster = {} + +monster.description = "a Werefox" +monster.experience = 1600 +monster.outfit = { + lookType = 1030, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1549 +monster.Bestiary = { + class = "Lycanthrope", + race = BESTY_RACE_LYCANTHROPE, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Were-beasts cave south-west of Edron and in the Last Sanctum east of Cormaya." + } + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "blood" +monster.corpse = 30756 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "fox", chance = 10, interval = 2000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Yelp!", yell = false}, + {text = "Grrrrrr", yell = false} +} + +monster.loot = { + {name = "Gold Coin", chance = 405000, maxCount = 200}, + {name = "Platinum Coin", chance = 4050, maxCount = 2}, + {name = "Fox Paw", chance = 4050, maxCount = 2}, + {name = "Werefox Tail", chance = 4050, maxCount = 2}, + {name = "Strong Mana Potion", chance = 4050, maxCount = 2}, + {name = "Great Mana Potion", chance = 4050, maxCount = 2}, + {name = "Mana Potion", chance = 4050, maxCount = 2}, + {name = "Small Enchanted Emerald", chance = 4050, maxCount = 2}, + {name = "Emerald Bangle", chance = 4050, maxCount = 2}, + {name = "Moonlight Rod", chance = 500}, + {name = "Troll Green", chance = 500, maxCount = 2}, + {name = "Assassin Star", chance = 300, maxCount = 5}, + {name = "Platinum Amulet", chance = 130}, + {name = "Ring of Healing", chance = 200}, + {name = "Werewolf Amulet", chance = 50}, + {id = 30941, chance = 30} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -290}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -200, shootEffect = CONST_ANI_GREENSTAR, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -100, maxDamage = -225, range = 7, radius = 4, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_DEATHDAMAGE, minDamage = -100, maxDamage = -700, length = 5, spread = 3, effect = CONST_ME_MORTAREA, target = false} +} + +monster.defenses = { + defense = 45, + armor = 40, + {name ="combat", interval = 4000, chance = 15, type = COMBAT_HEALING, minDamage = 50, maxDamage = 145, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 20, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 1}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 90}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/lycanthropes/werehyaena.lua b/data/monster/lycanthropes/werehyaena.lua new file mode 100644 index 00000000000..c6c9a998b01 --- /dev/null +++ b/data/monster/lycanthropes/werehyaena.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Werehyaena") +local monster = {} + +monster.description = "a werehyaena" +monster.experience = 2200 +monster.outfit = { + lookType = 1300, + lookHead = 57, + lookBody = 77, + lookLegs = 1, + lookFeet = 1, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1963 +monster.Bestiary = { + class = "Lycanthrope", + race = BESTY_RACE_LYCANTHROPE, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "This monster you can find in Hyaena Lairs." + } + +monster.health = 2700 +monster.maxHealth = monster.health +monster.race = "blood" +monster.corpse = 38656 +monster.speed = 120 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 30, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 0, + chance = 0 +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 3}, + {name = "great health potion", chance = 49970, maxCount = 3}, + {name = "meat", chance = 19070}, + {name = "axe", chance = 16810}, + {name = "knife", chance = 16620}, + {name = "werehyaena nose", chance = 12670}, + {name = "halberd", chance = 11480}, + {name = "red crystal fragment", chance = 9540}, + {name = "small enchanted amethyst", chance = 5760, maxCount = 5}, + {name = "life preserver", chance = 5670}, + {name = "red gem", chance = 5590}, + {name = "yellow gem", chance = 5420}, + {name = "combat knife", chance = 4700}, + {name = "green crystal fragment", chance = 4580}, + {name = "ratana", chance = 4280}, + {name = "werehyaena talisman", chance = 750}, + {name = "werehyaena trophy", chance = 190} +} + +monster.attacks = { + {name = "melee", type = COMBAT_PHYSICALDAMAGE, interval = 2*1000, minDamage = 0, maxDamage = -300}, + {name = "combat", type = COMBAT_EARTHDAMAGE, interval = 2*1000, chance = 17, minDamage = -175, maxDamage = -255, radius = 3, effect = CONST_ME_HITBYPOISON}, + {name = "combat", type = COMBAT_DEATHDAMAGE, interval = 2*1000, chance = 15, minDamage = -330, maxDamage = -370, target = true, range = 5, radius = 1, shootEffect = CONST_ANI_LARGEROCK, effect = CONST_ME_MORTAREA}, + {name = "combat", type = COMBAT_DEATHDAMAGE, interval = 2*1000, chance = 13, minDamage = -225, maxDamage = -275, length = 3, spread = 0, effect = CONST_ME_MORTAREA} +} + +monster.defenses = { + {name = "speed", chance = 15, interval = 2*1000, speed = 200, duration = 5*1000, effect = CONST_ME_MAGIC_BLUE}, + defense = 0, + armor = 38 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 60}, + {type = COMBAT_FIREDAMAGE, percent = 75}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -20}, + {type = COMBAT_HOLYDAMAGE , percent = 95}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = true} +} + +mType:register(monster) diff --git a/data/monster/lycanthropes/werehyaena_shaman.lua b/data/monster/lycanthropes/werehyaena_shaman.lua new file mode 100644 index 00000000000..8c10487c4a1 --- /dev/null +++ b/data/monster/lycanthropes/werehyaena_shaman.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Werehyaena Shaman") +local monster = {} + +monster.description = "a werehyaena shaman" +monster.experience = 2200 +monster.outfit = { + lookType = 1300, + lookHead = 0, + lookBody = 0, + lookLegs = 94, + lookFeet = 95, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1964 +monster.Bestiary = { + class = "Lycanthrope", + race = BESTY_RACE_LYCANTHROPE, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "This monster you can find in Hyaena Lairs." + } + +monster.health = 2500 +monster.maxHealth = monster.health +monster.race = "blood" +monster.corpse = 39024 +monster.speed = 110 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 30, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 0, + chance = 0 +} + +monster.loot = { + {name = "platinum coin", chance = 100000}, + {name = "great mana potion", chance = 20070}, + {name = "werehyaena nose", chance = 15550}, + {name = "small amethyst", chance = 10840}, + {name = "green crystal splinter", chance = 9120}, + {name = "hailstorm rod", chance = 6430}, + {name = "doublet", chance = 5390}, + {name = "brown crystal splinter", chance = 5030}, + {name = "wand of starstorm", chance = 4920}, + {name = "small enchanted emerald", chance = 4630}, + {name = "sword ring", chance = 4490}, + {name = "wand of voodoo", chance = 3990}, + {name = "protection amulet", chance = 2660}, + {name = "werehyaena talisman", chance = 650}, + {name = "moonlight crystals", chance = 610}, + {name = "werehyaena trophy", chance = 140} +} + +monster.attacks = { + {name = "melee", type = COMBAT_PHYSICALDAMAGE, interval = 2*1000, minDamage = 0, maxDamage = -260}, + {name = "combat", type = COMBAT_DEATHDAMAGE, interval = 2*1000, chance = 10, minDamage = -280, maxDamage = -325, radius = 3, effect = CONST_ME_HITBYPOISON}, + {name = "combat", type = COMBAT_EARTHDAMAGE, interval = 2*1000, chance = 17, minDamage = -280, maxDamage = -315, range = 5, radius = 4, target = true, shootEffect = CONST_ANI_EARTH, effect = CONST_ME_GREEN_RINGS}, + {name = "combat", type = COMBAT_DEATHDAMAGE, interval = 2*1000, chance = 15, minDamage = -370, maxDamage = -430, range = 5, radius = 1, target = true, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_MORTAREA}, + {name = "combat", type = COMBAT_DEATHDAMAGE, interval = 2*1000, chance = 13, minDamage = -280, maxDamage = -325, length = 3, spread = 0, effect = CONST_ME_MORTAREA} +} + +monster.defenses = { + {name = "speed", interval = 2*1000, chance = 15, speed = 200, duration = 5*1000, effect = CONST_ME_MAGIC_BLUE}, + defense = 0, + armor = 38 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 60}, + {type = COMBAT_FIREDAMAGE, percent = 75}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -20}, + {type = COMBAT_HOLYDAMAGE , percent = 95}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = true} +} + +mType:register(monster) diff --git a/data/monster/lycanthropes/werelion.lua b/data/monster/lycanthropes/werelion.lua new file mode 100644 index 00000000000..42d6d00b734 --- /dev/null +++ b/data/monster/lycanthropes/werelion.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Werelion") +local monster = {} + +monster.description = "a werelion" +monster.experience = 2400 +monster.outfit = { + lookType = 1301, + lookHead = 58, + lookBody = 2, + lookLegs = 94, + lookFeet = 0, + lookAddons = 3, + lookMount = 0 +} + +monster.raceId = 1965 +monster.Bestiary = { + class = "Lycanthrope", + race = BESTY_RACE_LYCANTHROPE, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 3, + Occurrence = 0, + Locations = "This monster you can find in Hyaena Lairs." + } + +monster.health = 2800 +monster.maxHealth = 2800 +monster.race = "blood" +monster.corpse = 38660 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 20 +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 5, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 1, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 100000, maxCount = 5}, + {name = "Great Spirit Potion", chance = 100000, maxCount = 2}, + {name = "Small Enchanted Ruby", chance = 5000, maxCount = 2}, + {name = "Meat", chance = 5000, maxCount = 2}, + {name = "Crystal Sword", chance = 5000}, + {name = "Lion's Mane", chance = 5000}, + {name = "Silver Brooch", chance = 1500}, + {name = "Small Diamond", chance = 1500, maxCount = 2}, + {name = "War Hammer", chance = 1500}, + {name = "Doublet", chance = 1500}, + {name = "Dark Shield", chance = 1500}, + {name = "Titan Axe", chance = 1500}, + {name = "Spiked Squelcher", chance = 1500}, + {name = "Glorious Axe", chance = 1500}, + {name = "Spirit Cloak", chance = 1500}, + {name = "Onyx Chip", chance = 1500}, + {name = "Coral Brooch", chance = 1500}, + {name = "Ivory Carving", chance = 1500}, + {name = "Rainbow Quartz", chance = 1500}, + {name = "Noble Axe", chance = 500}, + {name = "White Silk Flower", chance = 500}, + {name = "Lion Figurine", chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + {name ="werelion wave", interval = 2000, chance = 20, minDamage = -150, maxDamage = -250, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HOLYDAMAGE, minDamage = -300, maxDamage = -410, range = 3, effect = CONST_ME_HOLYAREA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HOLYDAMAGE, minDamage = -170, maxDamage = -350, range = 3, shootEffect = CONST_ANI_HOLY, target = true} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 100, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 25}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -25}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 45} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/lycanthropes/werelioness.lua b/data/monster/lycanthropes/werelioness.lua new file mode 100644 index 00000000000..b140d4b2377 --- /dev/null +++ b/data/monster/lycanthropes/werelioness.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Werelioness") +local monster = {} + +monster.description = "a werelioness" +monster.experience = 2500 +monster.outfit = { + lookType = 1301, + lookHead = 58, + lookBody = 2, + lookLegs = 94, + lookFeet = 94, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1966 +monster.Bestiary = { + class = "Lycanthrope", + race = BESTY_RACE_LYCANTHROPE, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 3, + Occurrence = 0, + Locations = "This monster we can find in Hyaena Lairs." + } + +monster.health = 3000 +monster.maxHealth = 3000 +monster.race = "blood" +monster.corpse = 39020 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 20 +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 5, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 1, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 100000, maxCount = 5}, + {name = "Gold Coin", chance = 100000, maxCount = 60}, + {name = "Small Enchanted Sapphire", chance = 5000, maxCount = 2}, + {name = "Black Pearl", chance = 5000, maxCount = 2}, + {name = "Ham", chance = 5000, maxCount = 2}, + {name = "Meat", chance = 5000, maxCount = 2}, + {name = "Soul Orb", chance = 5000, maxCount = 2}, + {name = "White Pearl", chance = 1500, maxCount = 2}, + {name = "Ankh", chance = 5000}, + {name = "Crystal Sword", chance = 5000}, + {name = "Serpent Sword", chance = 5000}, + {name = "Rapier", chance = 5000}, + {name = "Lion's Mane", chance = 5000}, + {name = "Lightning Headband", chance = 1500}, + {name = "Steel Helmet", chance = 1500}, + {name = "Doublet", chance = 1500}, + {name = "Ivory Carving", chance = 1500}, + {name = "Magma Legs", chance = 500}, + {name = "Crown Helmet", chance = 500}, + {name = "White Silk Flower", chance = 200}, + {name = "Lion Figurine", chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HOLYDAMAGE, minDamage = -300, maxDamage = -410, range = 3, effect = CONST_ME_HOLYAREA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HOLYDAMAGE, minDamage = -170, maxDamage = -350, range = 3, shootEffect = CONST_ANI_HOLY, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -250, maxDamage = -300, length = 4, spread = 1, effect = CONST_ME_FIREAREA, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 100, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = 35}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 25}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/lycanthropes/werewolf.lua b/data/monster/lycanthropes/werewolf.lua new file mode 100644 index 00000000000..c9c980f85f9 --- /dev/null +++ b/data/monster/lycanthropes/werewolf.lua @@ -0,0 +1,141 @@ +local mType = Game.createMonsterType("Werewolf") +local monster = {} + +monster.description = "a werewolf" +monster.experience = 1900 +monster.outfit = { + lookType = 308, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 510 +monster.Bestiary = { + class = "Lycanthrope", + race = BESTY_RACE_LYCANTHROPE, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Vengoth Castle, Vengoth Werewolf Cave, Grimvale, were-beasts cave south-west of Edron." + } + +monster.health = 1955 +monster.maxHealth = 1955 +monster.race = "blood" +monster.corpse = 20380 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "war wolf", chance = 40, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "GRRR", yell = true}, + {text = "GRROARR", yell = true} +} + +monster.loot = { + {id = 2148, chance = 98000, maxCount = 230}, + {id = 2169, chance = 800}, + {name = "platinum amulet", chance = 870}, + {name = "stone skin amulet", chance = 1000}, + {name = "halberd", chance = 3000}, + {name = "epee", chance = 560}, + {name = "plate shield", chance = 10340}, + {name = "brown mushroom", chance = 6940}, + {name = "troll green", chance = 1900}, + {name = "wolf paw", chance = 5200}, + {name = "relic sword", chance = 480}, + {name = "dreaded cleaver", chance = 160}, + {name = "bonebreaker", chance = 400}, + {name = "berserk potion", chance = 1200}, + {name = "strong health potion", chance = 5000}, + {name = "ultimate health potion", chance = 2400}, + {id = 9809, chance = 210}, + {id = 24708, chance = 15000}, + {name = "werewolf fur", chance = 10650} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -350}, + {name ="outfit", interval = 2000, chance = 1, radius = 1, effect = CONST_ME_SOUND_BLUE, target = true, duration = 2000, outfitMonster = "werewolf"}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -80, maxDamage = -200, length = 4, spread = 2, effect = CONST_ME_SOUND_RED, target = false}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_PHYSICALDAMAGE, radius = 3, effect = CONST_ME_SOUND_WHITE, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, radius = 1, effect = CONST_ME_SOUND_GREEN, target = false}, + {name ="werewolf skill reducer", interval = 2000, chance = 15, range = 1, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 120, maxDamage = 225, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 400, range = 7, effect = CONST_ME_SOUND_PURPLE, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 65}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/animated_feather.lua b/data/monster/magicals/animated_feather.lua new file mode 100644 index 00000000000..f3342d6b698 --- /dev/null +++ b/data/monster/magicals/animated_feather.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Animated Feather") +local monster = {} + +monster.description = "an animated feather" +monster.experience = 9860 +monster.outfit = { + lookType = 1058, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1671 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "The Secret Library." + } + +monster.health = 13000 +monster.maxHealth = 13000 +monster.race = "undead" +monster.corpse = 33325 +monster.speed = 420 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Small Sapphire", chance = 8700, maxCount = 5}, + {name = "Platinum Coin", chance = 87000, maxCount = 50}, + {id = 33317, chance = 500, maxCount = 10}, + {name = "Energy Ring", chance = 8700}, + {id = 7441, chance = 4000}, + {name = "Shard", chance = 250, maxCount = 3}, + {name = "Glacier Mask", chance = 250}, + {name = "Hailstorm Rod", chance = 250}, + {name = "Life Crystal", chance = 8700}, + {name = "Great Mana Potion", chance = 900, maxCount = 6}, + {name = "Golden Mug", chance = 500}, + {name = "Glowing Rune", chance = 500, maxCount = 10}, + {name = "Energy Ring", chance = 8700}, + {name = "Quill", chance = 250}, + {name = "Small Diamond", chance = 500, maxCount = 5} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -100, maxDamage = -200, range = 7, shootEffect = CONST_ANI_ICE, target = false}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -200, maxDamage = -780, range = 7, shootEffect = CONST_ANI_SMALLICE, effect = CONST_ME_ICEATTACK, target = false}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -200, maxDamage = -275, length = 3, spread = 2, effect = CONST_ME_ICEATTACK, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ICEDAMAGE, minDamage = -230, maxDamage = -680, range = 7, radius = 3, shootEffect = CONST_ANI_SMALLICE, effect = CONST_ME_ICETORNADO, target = false} +} + +monster.defenses = { + defense = 40, + armor = 79 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -18}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/arachnophobica.lua b/data/monster/magicals/arachnophobica.lua new file mode 100644 index 00000000000..b4e776c49cd --- /dev/null +++ b/data/monster/magicals/arachnophobica.lua @@ -0,0 +1,147 @@ +local mType = Game.createMonsterType("Arachnophobica") +local monster = {} + +monster.description = "an arachnophobica" +monster.experience = 4700 +monster.outfit = { + lookType = 1135, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1729 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Buried Cathedral, Haunted Cellar, Court of Summer, Court of Winter, Dream Labyrinth." + } + +monster.health = 5000 +monster.maxHealth = 5000 +monster.race = "blood" +monster.corpse = 34711 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Tip tap tip tap!", yell = false} +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 14}, + {name = "great spirit potion", chance = 100000, maxCount = 3}, + {name = "essence of a bad dream", chance = 15000}, + {name = "energy ring", chance = 12050}, + {name = "silver amulet", chance = 15000}, + {name = "sword ring", chance = 11050}, + {name = "spider fangs", chance = 11800}, + {name = "mind stone", chance = 17800}, + {name = "wand of cosmic energy", chance = 17800}, + {name = "magma amulet", chance = 8900}, + {name = "elven amulet", chance = 8100, maxCount = 2}, + {id = 26200, chance = 10590}, + {name = "sacred tree amulet", chance = 7500}, + {name = "spider silk", chance = 6500}, + {name = "life ring", chance = 5560}, + {name = "orb", chance = 7800}, + {name = "underworld rod", chance = 7120}, + {id = 26185, chance = 1000}, + {name = "ring of healing", chance = 9120}, + {name = "strange talisman", chance = 8110}, + {name = "axe ring", chance = 7220}, + {name = "power ring", chance = 6080}, + {id = 6300, chance = 7502}, + {name = "garlic necklace", chance = 7550}, + {name = "platinum amulet", chance = 7650}, + {id = 26199, chance = 10590}, + {name = "Strange Symbol", chance = 2640}, + {name = "stone skin amulet", chance = 2600}, + {name = "necklace of the deep", chance = 1800} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -350}, + {name ="arachnophobicawavedice", interval = 2000, chance = 20, minDamage = -250, maxDamage = -350, target = false}, + {name ="arachnophobicawaveenergy", interval = 2000, chance = 20, minDamage = -250, maxDamage = -350, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = -250, maxDamage = -350, radius = 4, effect = CONST_ME_BLOCKHIT, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -200, maxDamage = -300, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = false} +} + +monster.defenses = { + defense = 0, + armor = 70, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 150, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -40}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/armadile.lua b/data/monster/magicals/armadile.lua new file mode 100644 index 00000000000..755ab356537 --- /dev/null +++ b/data/monster/magicals/armadile.lua @@ -0,0 +1,139 @@ +local mType = Game.createMonsterType("Armadile") +local monster = {} + +monster.description = "an armadile" +monster.experience = 2900 +monster.outfit = { + lookType = 487, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 880 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 1, + Locations = "Warzone 1." + } + +monster.health = 3800 +monster.maxHealth = 3800 +monster.race = "undead" +monster.corpse = 18378 +monster.speed = 440 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Creak!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "gold coin", chance = 100000, maxCount = 98}, + {name = "platinum coin", chance = 95000, maxCount = 7}, + {id = 2169, chance = 1000}, + {name = "tower shield", chance = 620}, + {name = "titan axe", chance = 1540}, + {name = "bonebreaker", chance = 1150}, + {name = "strong health potion", chance = 14285, maxCount = 2}, + {name = "strong mana potion", chance = 15000, maxCount = 2}, + {name = "great mana potion", chance = 15920, maxCount = 2}, + {name = "great health potion", chance = 15000, maxCount = 2}, + {name = "mana potion", chance = 14285, maxCount = 3}, + {name = "terra boots", chance = 2850}, + {name = "crystalline armor", chance = 230}, + {name = "battle stone", chance = 12460}, + {id = 13757, chance = 6000}, + {name = "green crystal splinter", chance = 3920, maxCount = 2}, + {name = "green crystal fragment", chance = 5690, maxCount = 2}, + {name = "crystalline spikes", chance = 14540}, + {name = "drill bolt", chance = 7692, maxCount = 5}, + {name = "envenomed arrow", chance = 10230, maxCount = 10} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150}, + {name ="drunk", interval = 2000, chance = 15, radius = 4, effect = CONST_ME_FIREAREA, target = true, duration = 5000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_MANADRAIN, minDamage = -430, maxDamage = -550, range = 7, effect = CONST_ME_MAGIC_BLUE, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -200, maxDamage = -400, radius = 4, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_MAGIC_RED} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 1}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 15}, + {type = COMBAT_DEATHDAMAGE , percent = 1} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/blue_djinn.lua b/data/monster/magicals/blue_djinn.lua new file mode 100644 index 00000000000..40cb6948d5a --- /dev/null +++ b/data/monster/magicals/blue_djinn.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Blue Djinn") +local monster = {} + +monster.description = "a blue djinn" +monster.experience = 215 +monster.outfit = { + lookType = 80, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 80 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Kha'zeel, Magician Quarter, Forgotten Tomb." + } + +monster.health = 330 +monster.maxHealth = 330 +monster.race = "blood" +monster.corpse = 6020 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Simsalabim", yell = false}, + {text = "Feel the power of my magic, tiny mortal!", yell = false}, + {text = "Be careful what you wish for.", yell = false}, + {text = "Wishes can come true", yell = false} +} + +monster.loot = { + {id = 1963, chance = 2350}, + {name = "small oil lamp", chance = 690}, + {name = "small sapphire", chance = 2560, maxCount = 4}, + {name = "gold coin", chance = 60000, maxCount = 70}, + {name = "gold coin", chance = 70000, maxCount = 45}, + {name = "mystic turban", chance = 70}, + {id = 2684, chance = 23480}, + {name = "blue rose", chance = 440}, + {name = "blue piece of cloth", chance = 1920}, + {name = "royal spear", chance = 4500, maxCount = 2}, + {name = "mana potion", chance = 860}, + {name = "dirty turban", chance = 1890} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -110}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -45, maxDamage = -80, range = 7, shootEffect = CONST_ANI_FIRE, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -60, maxDamage = -105, range = 7, radius = 1, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="drunk", interval = 2000, chance = 10, range = 7, shootEffect = CONST_ANI_ENERGY, target = false, duration = 5000}, + {name ="outfit", interval = 2000, chance = 1, range = 7, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 4000, outfitMonster = "rabbit"}, + {name ="djinn electrify", interval = 2000, chance = 15, range = 5, target = false}, + {name ="djinn cancel invisibility", interval = 2000, chance = 10, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 1}, + {type = COMBAT_DEATHDAMAGE , percent = -12} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/bog_raider.lua b/data/monster/magicals/bog_raider.lua new file mode 100644 index 00000000000..93e4d92cb38 --- /dev/null +++ b/data/monster/magicals/bog_raider.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Bog Raider") +local monster = {} + +monster.description = "a bog raider" +monster.experience = 800 +monster.outfit = { + lookType = 299, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 460 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Underneath Malada and Talahu, Edron Bog Raider Cave in Stonehome, \z + Edron Earth Elemental Cave, Alchemist Quarter, Vengoth Castle, Robson Isle. Oramond Hydra/Bog Raider Cave." + } + +monster.health = 1300 +monster.maxHealth = 1300 +monster.race = "venom" +monster.corpse = 8951 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 60, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Tchhh!", yell = false}, + {text = "Slurp!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 92090, maxCount = 105}, + {name = "plate legs", chance = 200}, + {name = "great health potion", chance = 2030}, + {name = "great spirit potion", chance = 2010}, + {name = "ultimate health potion", chance = 750}, + {name = "belted cape", chance = 580}, + {name = "paladin armor", chance = 140}, + {name = "springsprout rod", chance = 1020}, + {name = "boggy dreads", chance = 9870} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -183, condition = {type = CONDITION_POISON, totalDamage = 80, interval = 4000}}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -90, maxDamage = -140, range = 7, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -100, maxDamage = -175, radius = 3, effect = CONST_ME_BUBBLES, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -96, maxDamage = -110, range = 7, shootEffect = CONST_ANI_SMALLEARTH, target = true}, + {name ="speed", interval = 2000, chance = 15, speedChange = -600, range = 7, effect = CONST_ME_SMALLPLANTS, target = true, duration = 15000} +} + +monster.defenses = { + defense = 0, + armor = 20, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 65, maxDamage = 95, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -20}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 30}, + {type = COMBAT_FIREDAMAGE, percent = 85}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/bonelord.lua b/data/monster/magicals/bonelord.lua new file mode 100644 index 00000000000..26ad237879d --- /dev/null +++ b/data/monster/magicals/bonelord.lua @@ -0,0 +1,144 @@ +local mType = Game.createMonsterType("Bonelord") +local monster = {} + +monster.description = "a bonelord" +monster.experience = 170 +monster.outfit = { + lookType = 17, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 17 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Ancient Temple, Alatar Lake, Mount Sternum Undead Cave, Desert Dungeon, Hellgate, \z + Helheim, Fibula Dungeon, Villa Scapula, Hero Cave before Dragons, Eastern Drefia, Folda hidden cave, \z + Maze of Lost Souls, way to Mintwallin, before Kazordoon city entrance, abandoned building east of Venore, \z + Green Claw Swamp, north of the Venore Amazon Camp, Below Point of No Return in Outlaw Camp, Vandura Bonelord Cave, \z + Triangle Tower, Hidden cave north of Port Hope, Deeper Banuta, Dark Cathedral, Shadow Tomb, Ancient Ruins Tomb, \z + Tarpit Tomb, Mountain Tomb, Peninsula Tomb, Oasis Tomb and beneath Fenrock." + } + +monster.health = 260 +monster.maxHealth = 260 +monster.race = "venom" +monster.corpse = 5992 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 6 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Skeleton", chance = 20, interval = 2000, max = 6} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Eye for eye!", yell = false}, + {text = "Here's looking at you!", yell = false}, + {text = "Let me take a look at you.", yell = false}, + {text = "You've got the look!", yell = false}, + {text = "I've got to look!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 99400, maxCount = 48}, + {id = 2175, chance = 4990}, + {name = "terra rod", chance = 510}, + {name = "two handed sword", chance = 3950}, + {name = "morning star", chance = 7020}, + {name = "longsword", chance = 9060}, + {name = "steel shield", chance = 3980}, + {name = "bonelord shield", chance = 110}, + {name = "bonelord eye", chance = 1010}, + {name = "mana potion", chance = 300}, + {name = "small flask of eyedrops", chance = 5060} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -5}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_ENERGYDAMAGE, minDamage = -15, maxDamage = -45, range = 7, shootEffect = CONST_ANI_ENERGY, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_FIREDAMAGE, minDamage = -25, maxDamage = -45, range = 7, shootEffect = CONST_ANI_FIRE, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_DEATHDAMAGE, minDamage = -30, maxDamage = -50, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_EARTHDAMAGE, minDamage = -5, maxDamage = -45, range = 7, shootEffect = CONST_ANI_POISON, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_DEATHDAMAGE, minDamage = -5, maxDamage = -50, range = 7, shootEffect = CONST_ANI_DEATH, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -45, range = 7, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_MANADRAIN, minDamage = -5, maxDamage = -35, range = 7, target = false} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/brain_squid.lua b/data/monster/magicals/brain_squid.lua new file mode 100644 index 00000000000..4d9e297cbe5 --- /dev/null +++ b/data/monster/magicals/brain_squid.lua @@ -0,0 +1,138 @@ +local mType = Game.createMonsterType("Brain Squid") +local monster = {} + +monster.description = "a brain squid" +monster.experience = 17672 +monster.outfit = { + lookType = 1059, + lookHead = 97, + lookBody = 18, + lookLegs = 61, + lookFeet = 85, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1653 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Secret Library." + } + +monster.health = 18000 +monster.maxHealth = 18000 +monster.race = "undead" +monster.corpse = 33329 +monster.speed = 430 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Violet Crystal Shard", chance = 900, maxCount = 4}, + {name = "Platinum Coin", chance = 100000, maxCount = 12}, + {name = "Glowing Rune", chance = 900, maxCount = 4}, + {name = "Instable Proto Matter", chance = 1200, maxCount = 4}, + {name = "Energy Ball", chance = 1200, maxCount = 4}, + {name = "Energy Bar", chance = 1200, maxCount = 4}, + {name = "Energy Drink", chance = 1200, maxCount = 4}, + {name = "Odd Organ", chance = 1200, maxCount = 4}, + {name = "Frozen Lightning", chance = 1200, maxCount = 4}, + {id = 33315, chance = 1200, maxCount = 3}, + {name = "Small Ruby", chance = 1200, maxCount = 4}, + {name = "Violet Gem", chance = 1200, maxCount = 4}, + {name = "Blue Crystal Splinter", chance = 1200, maxCount = 4}, + {name = "Cyan Crystal Fragment", chance = 1200, maxCount = 4}, + {name = "Ultimate Mana Potion", chance = 1200, maxCount = 4}, + {name = "Piece of Dead Brain", chance = 1200, maxCount = 4}, + {name = "Wand of Defiance", chance = 800}, + {name = "Lightning Headband", chance = 950}, + {name = "Lightning Pendant", chance = 850}, + {name = "Might Ring", chance = 1300}, + {name = "Slime Heart", chance = 1200, maxCount = 4}, + {id = 26200, chance = 560}, + {id = 26198, chance = 560},-- collar of blue plasma + {id = 26199, chance = 560}, + {id = 26189, chance = 560}, + {id = 26185, chance = 560}, + {id = 26187, chance = 560} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -200}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -470, range = 7, shootEffect = CONST_ANI_ENERGY, target = false}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -505, radius = 3, effect = CONST_ME_ENERGYAREA, target = false} +} + +monster.defenses = { + defense = 40, + armor = 82 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 90}, + {type = COMBAT_EARTHDAMAGE, percent = 30}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 70}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/braindeath.lua b/data/monster/magicals/braindeath.lua new file mode 100644 index 00000000000..27eab344193 --- /dev/null +++ b/data/monster/magicals/braindeath.lua @@ -0,0 +1,141 @@ +local mType = Game.createMonsterType("Braindeath") +local monster = {} + +monster.description = "a braindeath" +monster.experience = 985 +monster.outfit = { + lookType = 256, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 321 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Helheim, Demon Forge (The Arcanum), beneath Fenrock, Vandura Bonelord Cave, \z + Alchemist Quarter and Cemetery Quarter." + } + +monster.health = 1225 +monster.maxHealth = 1225 +monster.race = "undead" +monster.corpse = 7256 +monster.speed = 218 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Vampire", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You have disturbed my thoughts!", yell = false}, + {text = "Let me turn you into something more useful!", yell = false}, + {text = "Let me taste your brain!", yell = false}, + {text = "You will be punished!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 99470, maxCount = 89}, + {name = "bone sword", chance = 15130}, + {name = "sniper arrow", chance = 9560, maxCount = 4}, + {name = "steel shield", chance = 5940}, + {name = "piece of dead brain", chance = 5030}, + {name = "bonelord eye", chance = 2990}, + {name = "clerical mace", chance = 1970}, + {name = "haunted blade", chance = 1440}, + {id = 2175, chance = 930}, + {name = "spiked squelcher", chance = 180}, + {name = "bonelord shield", chance = 100}, + {name = "bonelord helmet", chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -93, maxDamage = -170, range = 7, shootEffect = CONST_ANI_ENERGY, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -75, maxDamage = -125, range = 7, shootEffect = CONST_ANI_FIRE, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -85, maxDamage = -170, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -65, maxDamage = -125, range = 7, shootEffect = CONST_ANI_POISON, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -75, maxDamage = -85, range = 7, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -155, range = 7, target = false} +} + +monster.defenses = { + defense = 12, + armor = 12, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 150, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 260, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 15}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = -20}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/burning_book.lua b/data/monster/magicals/burning_book.lua new file mode 100644 index 00000000000..c36a1fee52a --- /dev/null +++ b/data/monster/magicals/burning_book.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Burning Book") +local monster = {} + +monster.description = "a burning book" +monster.experience = 11934 +monster.outfit = { + lookType = 1061, + lookHead = 79, + lookBody = 113, + lookLegs = 78, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1663 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Secret Library." + } + +monster.health = 18000 +monster.maxHealth = 18000 +monster.race = "fire" +monster.corpse = 32454 +monster.speed = 440 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 89960, maxCount = 28}, + {name = "Book Page", chance = 3000, maxCount = 7}, + {name = "Demonic Essence", chance = 3000, maxCount = 5}, + {name = "Concentrated Demonic Blood", chance = 3000, maxCount = 3}, + {name = "Small Amethyst", chance = 2000, maxCount = 4}, + {id = 2419, chance = 3000}, + {name = "Silken Bookmark", chance = 2000, maxCount = 2}, + {name = "Magma Coat", chance = 2000}, + {name = "Guardian Shield", chance = 1500}, + {name = "Soul Orb", chance = 3000, maxCount = 4}, + {name = "Necrotic Rod", chance = 3000}, + {name = "Magma Monocle", chance = 1500}, + {id = 6300, chance = 1200}, + {name = "Stealth Ring", chance = 1800}, + {name = "Shadow Sceptre", chance = 8990} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -200, maxDamage = -700}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -500, maxDamage = -780, range = 7, shootEffect = CONST_ANI_FLAMMINGARROW, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 1500, chance = 12, type = COMBAT_PHYSICALDAMAGE, minDamage = -500, maxDamage = -900, radius = 3, effect = CONST_ME_EXPLOSIONAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -400, maxDamage = -850, length = 5, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_FIREDAMAGE, minDamage = -400, maxDamage = -775, radius = 3, effect = CONST_ME_HITBYFIRE, target = false} +} + +monster.defenses = { + defense = 33, + armor = 82 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/choking_fear.lua b/data/monster/magicals/choking_fear.lua new file mode 100644 index 00000000000..05f563d940a --- /dev/null +++ b/data/monster/magicals/choking_fear.lua @@ -0,0 +1,146 @@ +local mType = Game.createMonsterType("Choking Fear") +local monster = {} + +monster.description = "a choking fear" +monster.experience = 4700 +monster.outfit = { + lookType = 586, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1015 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "All over the surface of Upper Roshamuul and Nightmare Isles." + } + +monster.health = 5800 +monster.maxHealth = 5800 +monster.race = "undead" +monster.corpse = 22493 +monster.speed = 380 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ah, sweet air... don't you miss it?", yell = false}, + {text = "Murr tat muuza!", yell = false}, + {text = "kchh", yell = false}, + {text = "hsssss", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "platinum coin", chance = 100000, maxCount = 8}, + {name = "energy ring", chance = 3000}, + {name = "life ring", chance = 4200}, + {name = "ring of healing", chance = 3000}, + {name = "guardian shield", chance = 1540}, + {name = "beastslayer axe", chance = 3290}, + {name = "brown piece of cloth", chance = 6000}, + {name = "yellow piece of cloth", chance = 3500}, + {name = "great mana potion", chance = 20000, maxCount = 3}, + {name = "terra boots", chance = 720}, + {name = "great spirit potion", chance = 20000, maxCount = 3}, + {name = "ultimate health potion", chance = 19000, maxCount = 3}, + {name = "spellbook of mind control", chance = 720}, + {name = "underworld rod", chance = 720}, + {name = "springsprout rod", chance = 510}, + {name = "green crystal shard", chance = 1540}, + {name = "brown crystal splinter", chance = 52500, maxCount = 2}, + {name = "blue crystal splinter", chance = 10000, maxCount = 3}, + {name = "cluster of solace", chance = 620}, + {name = "dead weight", chance = 14180}, + {name = "hemp rope", chance = 14180} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -499, condition = {type = CONDITION_POISON, totalDamage = 600, interval = 4000}}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -700, maxDamage = -900, length = 5, spread = 3, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -300, radius = 1, shootEffect = CONST_ANI_EXPLOSION, effect = CONST_ME_SLEEP, target = true}, + {name ="speed", interval = 2000, chance = 20, speedChange = -800, radius = 1, shootEffect = CONST_ANI_EXPLOSION, effect = CONST_ME_SLEEP, target = true, duration = 15000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -130, maxDamage = -300, radius = 4, effect = CONST_ME_SOUND_RED, target = false}, + {name ="choking fear drown", interval = 2000, chance = 20, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -250, maxDamage = -500, radius = 4, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 80, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/crypt_warden.lua b/data/monster/magicals/crypt_warden.lua new file mode 100644 index 00000000000..9980901a3d7 --- /dev/null +++ b/data/monster/magicals/crypt_warden.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Crypt Warden") +local monster = {} + +monster.description = "a crypt warden" +monster.experience = 8400 +monster.outfit = { + lookType = 1190, + lookHead = 41, + lookBody = 38, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1805 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Kilmaresh Catacombs." + } + +monster.health = 8300 +monster.maxHealth = 8300 +monster.race = "blood" +monster.corpse = 36485 +monster.speed = 290 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 3}, + {name = "cyan crystal fragment", chance = 13670}, + {name = "green crystal fragment", chance = 1770}, + {name = "lamassu horn", chance = 10770}, + {name = "lamassu hoof", chance = 9700}, + {name = "small amethyst", chance = 8680}, + {name = "gold ingot", chance = 4660}, + {name = "green gem", chance = 1290}, + {name = "elven amulet", chance = 800} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -500}, + {name ="warden x", interval = 2000, chance = 15, minDamage = -250, maxDamage = -430, target = false}, + {name ="warden ring", interval = 2000, chance = 8, minDamage = -250, maxDamage = -380, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_EARTHDAMAGE, minDamage = -200, maxDamage = -480, radius = 2, effect = CONST_ME_GROUNDSHAKER, target = false}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_HOLYDAMAGE, minDamage = -300, maxDamage = -450, length = 5, spread = 3, effect = CONST_ME_HOLYAREA, target = false} +} + +monster.defenses = { + defense = 84, + armor = 84 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 75}, + {type = COMBAT_DEATHDAMAGE , percent = -35} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/crystalcrusher.lua b/data/monster/magicals/crystalcrusher.lua new file mode 100644 index 00000000000..247c0895717 --- /dev/null +++ b/data/monster/magicals/crystalcrusher.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Crystalcrusher") +local monster = {} + +monster.description = "a crystalcrusher" +monster.experience = 500 +monster.outfit = { + lookType = 511, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 869 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Crystal Grounds, Mushroom Farms, Middle Spike." + } + +monster.health = 570 +monster.maxHealth = 570 +monster.race = "venom" +monster.corpse = 18487 +monster.speed = 390 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Creak!", yell = false}, + {text = "Crackle!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 85000, maxCount = 90}, + {name = "crystalline arrow", chance = 5000, maxCount = 3}, + {name = "green crystal splinter", chance = 4920}, + {name = "brown crystal splinter", chance = 5250}, + {name = "blue crystal splinter", chance = 5000}, + {name = "crystalline spikes", chance = 3690} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -167}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -110, maxDamage = -260, radius = 3, effect = CONST_ME_GREEN_RINGS, target = true} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_HEALING, minDamage = 5, maxDamage = 15, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 129, maxDamage = 175, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -3}, + {type = COMBAT_HOLYDAMAGE , percent = -1}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/cursed_book.lua b/data/monster/magicals/cursed_book.lua new file mode 100644 index 00000000000..5554b68f229 --- /dev/null +++ b/data/monster/magicals/cursed_book.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Cursed Book") +local monster = {} + +monster.description = "a cursed book" +monster.experience = 13345 +monster.outfit = { + lookType = 1061, + lookHead = 79, + lookBody = 83, + lookLegs = 113, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1655 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 1, + Locations = "Secret Library." + } + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "undead" +monster.corpse = 33337 +monster.speed = 440 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 33316, chance = 10000, maxCount = 3}, + {name = "Platinum Coin", chance = 10000, maxCount = 10}, + {id = 33313, chance = 10000, maxCount = 3}, + {name = "Small Diamond", chance = 10000, maxCount = 7}, + {name = "Small Stone", chance = 10000, maxCount = 7}, + {name = "Small Topaz", chance = 10000, maxCount = 7}, + {name = "Protection Amulet", chance = 10000}, + {name = "Terra Boots", chance = 350}, + {name = "Terra Hood", chance = 600}, + {name = "Diamond Sceptre", chance = 600}, + {name = "Terra Mantle", chance = 250}, + {name = "Terra Legs", chance = 250}, + {name = "Terra Amulet", chance = 500}, + {name = "Stone Skin Amulet", chance = 350}, + {name = "Springsprout Rod", chance = 350}, + {name = "Sacred Tree Amulet", chance = 350}, + {name = "Swamplair Armor", chance = 250} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -400, maxDamage = -680, range = 7, shootEffect = CONST_ANI_EARTHARROW, target = false}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -400, maxDamage = -575, length = 5, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_PHYSICALDAMAGE, minDamage = -230, maxDamage = -880, range = 7, radius = 3, effect = CONST_ME_GROUNDSHAKER, target = false} +} + +monster.defenses = { + defense = 40, + armor = 82 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/dragonling.lua b/data/monster/magicals/dragonling.lua new file mode 100644 index 00000000000..f54864b016b --- /dev/null +++ b/data/monster/magicals/dragonling.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Dragonling") +local monster = {} + +monster.description = "a dragonling" +monster.experience = 2200 +monster.outfit = { + lookType = 505, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 894 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "Fury Dungeon and Goroma volcano (surface floor, inner volcano) only during the \z + Fire from the Earth Mini World Change." + } + +monster.health = 2600 +monster.maxHealth = 2600 +monster.race = "blood" +monster.corpse = 18438 +monster.speed = 460 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 900, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "FCHHHHH", yell = false}, + {text = "SQUAWK!", yell = false}, + {text = "FIYAH", yell = false}, + {text = "FI?", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 37500, maxCount = 100}, + {name = "gold coin", chance = 37500, maxCount = 100}, + {name = "gold coin", chance = 37500, maxCount = 27}, + {name = "strong health potion", chance = 24480, maxCount = 2}, + {name = "strong mana potion", chance = 16900, maxCount = 2}, + {name = "blazing bone", chance = 12410} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -210}, + {name ="dragonling wave", interval = 2000, chance = 10, minDamage = -120, maxDamage = -250, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -115, maxDamage = -180, radius = 3, effect = CONST_ME_PURPLEENERGY, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -95, maxDamage = -150, radius = 3, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -700, radius = 1, shootEffect = CONST_ANI_EXPLOSION, effect = CONST_ME_STUN, target = true, duration = 16000} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 100, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/efreet.lua b/data/monster/magicals/efreet.lua new file mode 100644 index 00000000000..06a9b483867 --- /dev/null +++ b/data/monster/magicals/efreet.lua @@ -0,0 +1,139 @@ +local mType = Game.createMonsterType("Efreet") +local monster = {} + +monster.description = "an efreet" +monster.experience = 410 +monster.outfit = { + lookType = 103, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 103 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Mal'ouquah, Deeper Banuta, Goromas Cult Cave (in the classroom), Magician Quarter." + } + +monster.health = 550 +monster.maxHealth = 550 +monster.race = "blood" +monster.corpse = 6032 +monster.speed = 234 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "green djinn", chance = 10, interval = 2000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I grant you a deathwish!", yell = false}, + {text = "Good wishes are for fairytales", yell = false} +} + +monster.loot = { + {id = 1860, chance = 2200}, + {name = "small oil lamp", chance = 160}, + {name = "gold coin", chance = 50000, maxCount = 75}, + {name = "gold coin", chance = 60000, maxCount = 50}, + {name = "small emerald", chance = 7000}, + {name = "green gem", chance = 200}, + {name = "wand of inferno", chance = 390}, + {name = "heavy machete", chance = 5000}, + {name = "mystic turban", chance = 160}, + {name = "pear", chance = 9390, maxCount = 5}, + {name = "green piece of cloth", chance = 3000}, + {name = "royal spear", chance = 15570, maxCount = 3}, + {name = "strong mana potion", chance = 3500}, + {name = "magma monocle", chance = 360}, + {name = "jewelled belt", chance = 8540}, + {name = "noble turban", chance = 1130} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -110}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -40, maxDamage = -110, range = 7, shootEffect = CONST_ANI_FIRE, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -30, maxDamage = -90, radius = 3, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -65, maxDamage = -120, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -650, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 15000}, + {name ="drunk", interval = 2000, chance = 10, range = 7, shootEffect = CONST_ANI_ENERGY, target = false, duration = 6000}, + {name ="outfit", interval = 2000, chance = 1, range = 7, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 4000, outfitMonster = "rat"}, + {name ="djinn electrify", interval = 2000, chance = 15, range = 5, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 50, maxDamage = 80, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 60}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = 90}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = -8}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/elder_bonelord.lua b/data/monster/magicals/elder_bonelord.lua new file mode 100644 index 00000000000..8304c8ad46e --- /dev/null +++ b/data/monster/magicals/elder_bonelord.lua @@ -0,0 +1,141 @@ +local mType = Game.createMonsterType("Elder Bonelord") +local monster = {} + +monster.description = "an elder bonelord" +monster.experience = 280 +monster.outfit = { + lookType = 108, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 108 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Hellgate, near the Hellgate Library, Deeper Banuta, behind piano in Cult Cave to the \z + northeast of Liberty Bay, Vandura Bonelord Cave, Goroma, Helheim, \z + underground of Fenrock (on the way to Beregar), Vengoth." + } + +monster.health = 500 +monster.maxHealth = 500 +monster.race = "blood" +monster.corpse = 6037 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 6 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Gazer", chance = 10, interval = 2000}, + {name = "Crypt Shambler", chance = 15, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Let me take a look at you!", yell = false}, + {text = "Inferior creatures, bow before my power!", yell = false}, + {text = "659978 54764!", yell = false}, + {text = "653768764!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 99290, maxCount = 86}, + {name = "elder bonelord tentacle", chance = 20040}, + {name = "small flask of eyedrops", chance = 9720}, + {name = "sniper arrow", chance = 8780, maxCount = 5}, + {name = "two handed sword", chance = 2980}, + {name = "steel shield", chance = 2040}, + {id = 2175, chance = 1030}, + {name = "strong mana potion", chance = 830}, + {name = "giant eye", chance = 460}, + {name = "bonelord shield", chance = 90}, + {name = "bonelord helmet", chance = 90} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -55}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_ENERGYDAMAGE, minDamage = -45, maxDamage = -60, range = 7, shootEffect = CONST_ANI_ENERGY, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_FIREDAMAGE, minDamage = -40, maxDamage = -80, range = 7, shootEffect = CONST_ANI_FIRE, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -45, maxDamage = -90, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -20, maxDamage = -40, range = 7, shootEffect = CONST_ANI_POISON, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_LIFEDRAIN, minDamage = -45, maxDamage = -85, range = 7, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -40, range = 7, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = -600, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000} +} + +monster.defenses = { + defense = 13, + armor = 13 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/energetic_book.lua b/data/monster/magicals/energetic_book.lua new file mode 100644 index 00000000000..a686fc17ab4 --- /dev/null +++ b/data/monster/magicals/energetic_book.lua @@ -0,0 +1,127 @@ +local mType = Game.createMonsterType("Energetic Book") +local monster = {} + +monster.description = "an energetic book" +monster.experience = 12034 +monster.outfit = { + lookType = 1061, + lookHead = 15, + lookBody = 91, + lookLegs = 85, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1665 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Secret Library." + } + +monster.health = 18500 +monster.maxHealth = 18500 +monster.race = "undead" +monster.corpse = 32478 +monster.speed = 440 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 100000, maxCount = 28}, + {id = 33316, chance = 900, maxCount = 8}, + {id = 33317, chance = 900, maxCount = 7}, + {name = "Ultimate Health Potion", chance = 10000, maxCount = 7}, + {name = "Ultimate Mana Potion", chance = 10000, maxCount = 7}, + {name = "Energy Ball", chance = 900, maxCount = 7}, + {id = 33313, chance = 800, maxCount = 7}, + {name = "Lightning Pendant", chance = 500}, + {name = "Lightning Boots", chance = 500}, + {name = "Lightning Headband", chance = 500}, + {name = "Might Ring", chance = 500}, + {name = "Spellweaver's Robe", chance = 350}, + {name = "Wand of Defiance", chance = 350}, + {name = "Haunted Blade", chance = 550}, + {name = "Lightning Legs", chance = 350} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -200}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -680, range = 7, shootEffect = CONST_ANI_ENERGY, target = false}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -505, radius = 3, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="combat", interval = 1500, chance = 30, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -700, length = 8, spread = 3, effect = CONST_ME_STUN, target = false} +} + +monster.defenses = { + defense = 40, + armor = 82 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/energuardian_of_tales.lua b/data/monster/magicals/energuardian_of_tales.lua new file mode 100644 index 00000000000..3f78b7c1703 --- /dev/null +++ b/data/monster/magicals/energuardian_of_tales.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("Energuardian of Tales") +local monster = {} + +monster.description = "an energuardian of tales" +monster.experience = 11361 +monster.outfit = { + lookType = 1063, + lookHead = 66, + lookBody = 85, + lookLegs = 82, + lookFeet = 93, + lookAddons = 3, + lookMount = 0 +} + +monster.raceId = 1666 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "The Secret Library." + } + +monster.health = 14000 +monster.maxHealth = 14000 +monster.race = "undead" +monster.corpse = 32571 +monster.speed = 420 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 33316, chance = 10000, maxCount = 5}, + {id = 33317, chance = 10000, maxCount = 5}, + {name = "Small Amethyst", chance = 10000, maxCount = 5}, + {name = "Flash Arrow", chance = 10000, maxCount = 5}, + {name = "Lightning Legs", chance = 250}, + {name = "Spellbook of Warding", chance = 350}, + {name = "Ultimate Health Potion", chance = 10000, maxCount = 5}, + {name = "Ultimate Mana Potion", chance = 10000, maxCount = 5}, + {name = "Wand of Starstorm", chance = 300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -10, maxDamage = -550}, + {name ="combat", interval = 1000, chance = 13, type = COMBAT_ENERGYDAMAGE, minDamage = -100, maxDamage = -555, radius = 3, effect = CONST_ME_ENERGYAREA, target = false} +} + +monster.defenses = { + defense = 40, + armor = 82 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 30}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/enfeebled_silencer.lua b/data/monster/magicals/enfeebled_silencer.lua new file mode 100644 index 00000000000..37b1a2fd5cc --- /dev/null +++ b/data/monster/magicals/enfeebled_silencer.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Enfeebled Silencer") +local monster = {} + +monster.description = "an enfeebled silencer" +monster.experience = 1100 +monster.outfit = { + lookType = 585, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1443 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Feyrist." + } + +monster.health = 1100 +monster.maxHealth = 1100 +monster.race = "blood" +monster.corpse = 22489 +monster.speed = 330 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Prrrroooaaaah!!! PRROAAAH!!", yell = false}, + {text = "PRRRROOOOOAAAAAHHHH!!!", yell = false}, + {text = "HUUUSSSSSSSSH!!", yell = false}, + {text = "Hussssssh!!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2152, chance = 100000, maxCount = 8}, + {id = 2165, chance = 1200}, + {id = 2195, chance = 360}, + {id = 7368, chance = 7600, maxCount = 10}, + {id = 7387, chance = 960}, + {id = 7407, chance = 2000}, + {id = 7451, chance = 640}, + {id = 7454, chance = 2400}, + {id = 7885, chance = 960}, + {id = 7886, chance = 480}, + {id = 22534, chance = 17000}, + {name = "fairy wings", chance = 30100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 80, attack = 70, condition = {type = CONDITION_POISON, totalDamage = 200, interval = 4000}}, + {name ="silencer skill reducer", interval = 2000, chance = 10, range = 3, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_MANADRAIN, minDamage = -40, maxDamage = -90, radius = 4, shootEffect = CONST_ANI_ONYXARROW, effect = CONST_ME_MAGIC_RED, target = true} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="speed", interval = 2000, chance = 15, speedChange = 450, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 80, maxDamage = 225, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 70} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/fahim_the_wise.lua b/data/monster/magicals/fahim_the_wise.lua new file mode 100644 index 00000000000..7a886dc91cd --- /dev/null +++ b/data/monster/magicals/fahim_the_wise.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Fahim the Wise") +local monster = {} + +monster.description = "a fahim the wise" +monster.experience = 1500 +monster.outfit = { + lookType = 104, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2000 +monster.maxHealth = 2000 +monster.race = "blood" +monster.corpse = 6033 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "blue djinn", chance = 10, interval = 2000, max = 3} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You should know better than to be an enemy of the Marid", yell = false} +} + +monster.loot = { + {name = "blue piece of cloth", chance = 99990, maxCount = 4}, + {name = "jewelled belt", chance = 99990}, + {name = "gold coin", chance = 95240, maxCount = 118}, + {name = "noble turban", chance = 66670}, + {name = "royal spear", chance = 57140, maxCount = 3}, + {name = "shiny stone", chance = 47620}, + {name = "strong mana potion", chance = 42860, maxCount = 3}, + {name = "blueberry", chance = 40480, maxCount = 22}, + {name = "mystic turban", chance = 33330}, + {name = "small sapphire", chance = 14290, maxCount = 2}, + {name = "seeds", chance = 7140}, + {name = "magma monocle", chance = 4760}, + {name = "blue gem", chance = 2380}, + {name = "small oil lamp", chance = 580}, + {id = 2948, chance = 480}, + {name = "heavy machete", chance = 380} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -130}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -100, maxDamage = -300, range = 7, shootEffect = CONST_ANI_ENERGYBALL, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -30, maxDamage = -90, range = 7, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -650, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 1500}, + {name ="drunk", interval = 2000, chance = 10, range = 7, shootEffect = CONST_ANI_ENERGY, target = false, duration = 6000}, + {name ="outfit", interval = 2000, chance = 1, range = 7, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 4000, outfitMonster = "rabbit"}, + {name ="djinn electrify", interval = 2000, chance = 15, range = 5, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -30, maxDamage = -90, radius = 3, effect = CONST_ME_ENERGYHIT, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 50, maxDamage = 80, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -1}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = -1}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/feral_sphinx.lua b/data/monster/magicals/feral_sphinx.lua new file mode 100644 index 00000000000..3e23682bf33 --- /dev/null +++ b/data/monster/magicals/feral_sphinx.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Feral Sphinx") +local monster = {} + +monster.description = "a feral sphinx" +monster.experience = 8800 +monster.outfit = { + lookType = 1188, + lookHead = 76, + lookBody = 75, + lookLegs = 38, + lookFeet = 50, + lookAddons = 2, + lookMount = 0 +} + +monster.raceId = 1807 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Kilmaresh, south of Issavi." + } + +monster.health = 9800 +monster.maxHealth = 9800 +monster.race = "blood" +monster.corpse = 36493 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 3}, + {name = "wand of draconia", chance = 4770}, + {name = "sphinx feather", chance = 3450}, + {name = "fire axe", chance = 2650}, + {id = 36273, chance = 3450}, + {name = "magma legs", chance = 1860}, + {name = "magma monocle", chance = 1590}, + {name = "magma boots", chance = 2120}, + {name = "magma amulet", chance = 7160}, + {name = "wand of inferno", chance = 7690}, + {name = "dragon necklace", chance = 800} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450}, + {name ="fire wave", interval = 2000, chance = 15, minDamage = -350, maxDamage = -500, length = 1, spread = 0, target = true}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = -300, maxDamage = -500, radius = 4, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -350, maxDamage = -550, range = 1, shootEffect = CONST_ANI_FIRE, target = false}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_HOLYDAMAGE, minDamage = -400, maxDamage = -580, length = 6, spread = 3, effect = CONST_ME_HOLYAREA, target = false} +} + +monster.defenses = { + defense = 90, + armor = 90, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 200, maxDamage = 425, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -15}, + {type = COMBAT_HOLYDAMAGE , percent = 80}, + {type = COMBAT_DEATHDAMAGE , percent = -15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/feversleep.lua b/data/monster/magicals/feversleep.lua new file mode 100644 index 00000000000..e8ca0df9902 --- /dev/null +++ b/data/monster/magicals/feversleep.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Feversleep") +local monster = {} + +monster.description = "a feversleep" +monster.experience = 4400 +monster.outfit = { + lookType = 593, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1021 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Roshamuul Mines, Roshamuul Cistern." + } + +monster.health = 5900 +monster.maxHealth = 5900 +monster.race = "blood" +monster.corpse = 22497 +monster.speed = 360 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "small emerald", chance = 11000, maxCount = 2}, + {name = "small amethyst", chance = 12000, maxCount = 3}, + {name = "platinum coin", chance = 100000, maxCount = 9}, + {name = "blue robe", chance = 1500}, + {name = "great mana potion", chance = 40000, maxCount = 2}, + {name = "ultimate health potion", chance = 18000}, + {name = "small topaz", chance = 16000, maxCount = 2}, + {name = "blue crystal shard", chance = 11000}, + {name = "blue crystal splinter", chance = 13000}, + {name = "cyan crystal fragment", chance = 18000}, + {name = "trapped bad dream monster", chance = 17000}, + {name = "bowl of terror sweat", chance = 14000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 20, minDamage = -800, maxDamage = -1000, radius = 7, effect = CONST_ME_YELLOW_RINGS, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -70, maxDamage = -100, radius = 5, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="feversleep skill reducer", interval = 2000, chance = 10, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -250, maxDamage = -300, length = 6, spread = 3, effect = CONST_ME_YELLOWENERGY, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -150, maxDamage = -300, radius = 1, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true} +} + +monster.defenses = { + defense = 45, + armor = 45, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 250, maxDamage = 425, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_HITAREA} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/flying_book.lua b/data/monster/magicals/flying_book.lua new file mode 100644 index 00000000000..2ae2947c205 --- /dev/null +++ b/data/monster/magicals/flying_book.lua @@ -0,0 +1,110 @@ +local mType = Game.createMonsterType("Flying Book") +local monster = {} + +monster.description = "a flying book" +monster.experience = 200 +monster.outfit = { + lookType = 1060, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1654 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "Secret Library." + } + +monster.health = 500 +monster.maxHealth = 500 +monster.race = "undead" +monster.corpse = 33333 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -100, maxDamage = -180, range = 7, shootEffect = CONST_ANI_ICE, target = false} +} + +monster.defenses = { + defense = 45, + armor = 45 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/forest_fury.lua b/data/monster/magicals/forest_fury.lua new file mode 100644 index 00000000000..f1997b4ee69 --- /dev/null +++ b/data/monster/magicals/forest_fury.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Forest Fury") +local monster = {} + +monster.description = "a forest fury" +monster.experience = 235 +monster.outfit = { + lookType = 569, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 980 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Forest Fury Camp and in the Forest Fury version of the Forsaken Mine." + } + +monster.health = 480 +monster.maxHealth = 480 +monster.race = "blood" +monster.corpse = 21359 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "To arms, sisters!", yell = false}, + {text = "Feel the wrath of mother forest!", yell = false}, + {text = "By the power of Greenskull!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 87250, maxCount = 53}, + {name = "crossbow", chance = 2750}, + {name = "bolt", chance = 48270, maxCount = 15}, + {name = "meat", chance = 24930}, + {name = "piercing bolt", chance = 14900, maxCount = 5}, + {name = "elvish bow", chance = 90}, + {name = "small topaz", chance = 470}, + {name = "elven hoof", chance = 7030}, + {name = "venison", chance = 13210} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -125}, + {name ="combat", interval = 1500, chance = 40, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -100, range = 7, radius = 4, shootEffect = CONST_ANI_HUNTINGSPEAR, effect = CONST_ME_MAGIC_GREEN, target = true}, + {name ="forest fury skill reducer", interval = 2000, chance = 20, range = 5, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/frazzlemaw.lua b/data/monster/magicals/frazzlemaw.lua new file mode 100644 index 00000000000..e2f3a1ce776 --- /dev/null +++ b/data/monster/magicals/frazzlemaw.lua @@ -0,0 +1,152 @@ +local mType = Game.createMonsterType("Frazzlemaw") +local monster = {} + +monster.description = "a frazzlemaw" +monster.experience = 3740 +monster.outfit = { + lookType = 594, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1022 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Lower Roshamuul, Guzzlemaw Valley, the entrance to Upper Roshamuul." + } + +monster.health = 4100 +monster.maxHealth = 4100 +monster.race = "blood" +monster.corpse = 22567 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Mwaaaahnducate youuuuuu *gurgle*, mwaaah!", yell = false}, + {text = "Mwaaahgod! Overmwaaaaah! *gurgle*", yell = false}, + {text = "MMMWAHMWAHMWAHMWAAAAH!", yell = false}, + {text = "Mmmwhamwhamwhah, mwaaah!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "platinum coin", chance = 100000, maxCount = 7}, + {name = "banana skin", chance = 9500}, + {name = "piece of iron", chance = 10400}, + {name = "fishbone", chance = 10000}, + {id = 2229, chance = 12680}, + {id = 2230, chance = 10000}, + {id = 2231, chance = 5500}, + {name = "two handed sword", chance = 3200}, + {id = 2667, chance = 6750, maxCount = 3}, + {name = "ham", chance = 6000, maxCount = 2}, + {name = "iron ore", chance = 3000}, + {name = "fish fin", chance = 4700}, + {name = "hardened bone", chance = 5000}, + {id = 5951, chance = 10800}, + {name = "assassin dagger", chance = 1000}, + {name = "haunted blade", chance = 2240}, + {name = "nightmare blade", chance = 1100}, + {name = "great mana potion", chance = 15000, maxCount = 3}, + {name = "great health potion", chance = 15000, maxCount = 2}, + {name = "gold ingot", chance = 2300}, + {name = "sai", chance = 1460}, + {name = "violet crystal shard", chance = 3000}, + {name = "brown crystal splinter", chance = 16000}, + {name = "red crystal fragment", chance = 7600}, + {id = 33539, chance = 10000}, + {name = "cluster of solace", chance = 450}, + {name = "frazzle tongue", chance = 18760}, + {name = "frazzle skin", chance = 16000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + -- bleed + {name ="condition", type = CONDITION_BLEEDING, interval = 2000, chance = 10, minDamage = -300, maxDamage = -400, radius = 3, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -700, length = 5, spread = 3, effect = CONST_ME_EXPLOSIONAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -400, radius = 2, shootEffect = CONST_ANI_LARGEROCK, effect = CONST_ME_STONES, target = true}, + {name ="speed", interval = 2000, chance = 15, speedChange = -600, radius = 5, effect = CONST_ME_MAGIC_RED, target = false, duration = 15000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -80, maxDamage = -150, radius = 4, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 250, maxDamage = 425, effect = CONST_ME_HITBYPOISON, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/gargoyle.lua b/data/monster/magicals/gargoyle.lua new file mode 100644 index 00000000000..0f668379eec --- /dev/null +++ b/data/monster/magicals/gargoyle.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Gargoyle") +local monster = {} + +monster.description = "a gargoyle" +monster.experience = 150 +monster.outfit = { + lookType = 95, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 95 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Meriana Gargoyle Cave, Ankrahmun Tombs, Mal'ouquah, Goroma, Deeper Banuta, \z + Formorgar Mines, Vengoth, Farmine Mines, Upper Spike and Medusa Tower." + } + +monster.health = 250 +monster.maxHealth = 250 +monster.race = "undead" +monster.corpse = 6027 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 30, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Harrrr harrrr!", yell = false}, + {text = "Stone sweet stone.", yell = false}, + {text = "Feel my claws, softskin.", yell = false}, + {text = "Chhhhhrrrrk!", yell = false}, + {text = "There is a stone in your shoe!", yell = false} +} + +monster.loot = { + {id = 2129, chance = 1480}, + {name = "gold coin", chance = 88000, maxCount = 30}, + {name = "club ring", chance = 260}, + {name = "morning star", chance = 2150}, + {name = "steel helmet", chance = 850}, + {name = "dark armor", chance = 300}, + {name = "battle shield", chance = 1000}, + {name = "strawberry", chance = 1810, maxCount = 5}, + {name = "potato", chance = 9220, maxCount = 2}, + {name = "stone wing", chance = 11730}, + {name = "shiny stone", chance = 190}, + {name = "piece of marble rock", chance = 630} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -65} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 5, maxDamage = 15, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 40}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 1} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/gazer.lua b/data/monster/magicals/gazer.lua new file mode 100644 index 00000000000..a4604525ff8 --- /dev/null +++ b/data/monster/magicals/gazer.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Gazer") +local monster = {} + +monster.description = "a gazer" +monster.experience = 90 +monster.outfit = { + lookType = 109, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 109 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Hellgate bonelord cave, Vandura Bonelord Cave, also anywhere Elder Bonelords exist, as summons." + } + +monster.health = 120 +monster.maxHealth = 120 +monster.race = "venom" +monster.corpse = 6036 +monster.speed = 140 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Mommy!?", yell = false}, + {text = "Buuuuhaaaahhaaaaa!", yell = false}, + {text = "Me need mana!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 99350, maxCount = 16}, + {name = "small flask of eyedrops", chance = 3200} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -15}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -25, maxDamage = -35, range = 7, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -10, maxDamage = -35, range = 7, target = false} +} + +monster.defenses = { + defense = 4, + armor = 4 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 11}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/green_djinn.lua b/data/monster/magicals/green_djinn.lua new file mode 100644 index 00000000000..11a251f209e --- /dev/null +++ b/data/monster/magicals/green_djinn.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Green Djinn") +local monster = {} + +monster.description = "a green djinn" +monster.experience = 215 +monster.outfit = { + lookType = 51, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 51 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Mal'ouquah, Oasis Tomb, under the Ankrahmun Library Tomb, \z + Serpentine Tower last floor behind the Magic Walls, Deeper Banuta, Goroma underground, Magician Quarter." + } + +monster.health = 330 +monster.maxHealth = 330 +monster.race = "blood" +monster.corpse = 6016 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I grant you a deathwish!", yell = false}, + {text = "Muahahahahaha", yell = false}, + {text = "I wish you a merry trip to hell!", yell = false}, + {text = "Good wishes are for fairytales", yell = false} +} + +monster.loot = { + {id = 1965, chance = 2280}, + {name = "gold coin", chance = 41000, maxCount = 70}, + {name = "gold coin", chance = 51000, maxCount = 45}, + {name = "small emerald", chance = 2960, maxCount = 4}, + {name = "mystic turban", chance = 140}, + {id = 2696, chance = 23500}, + {name = "grave flower", chance = 1000}, + {name = "green piece of cloth", chance = 2000}, + {name = "royal spear", chance = 4870, maxCount = 2}, + {name = "mana potion", chance = 490}, + {name = "dirty turban", chance = 2210} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -110}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -45, maxDamage = -80, range = 7, shootEffect = CONST_ANI_FIRE, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -50, maxDamage = -105, range = 7, radius = 1, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="drunk", interval = 2000, chance = 10, range = 7, shootEffect = CONST_ANI_ENERGY, target = false, duration = 5000}, + {name ="outfit", interval = 2000, chance = 1, range = 7, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 4000, outfitMonster = "rat"}, + {name ="djinn electrify", interval = 2000, chance = 15, range = 5, target = false}, + {name ="djinn cancel invisibility", interval = 2000, chance = 10, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = -13}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/gryphon.lua b/data/monster/magicals/gryphon.lua new file mode 100644 index 00000000000..cb3cea41229 --- /dev/null +++ b/data/monster/magicals/gryphon.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("Gryphon") +local monster = {} + +monster.description = "a gryphon" +monster.experience = 1000 +monster.outfit = { + lookType = 1220, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1819 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 1, + Locations = "Kilmaresh Mountains." + } + +monster.health = 3200 +monster.maxHealth = 3200 +monster.race = "blood" +monster.corpse = 36233 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 1, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Don't touch our hatchlings!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = 350}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_HOLYDAMAGE, minDamage = -250, maxDamage = -450, radius = 3, effect = CONST_ME_HOLYAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -300, length = 3, spread = 0, effect = CONST_ME_HITBYFIRE, target = false} +} + +monster.defenses = { + defense = 76, + armor = 76 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/guardian_of_tales.lua b/data/monster/magicals/guardian_of_tales.lua new file mode 100644 index 00000000000..3a9f162d140 --- /dev/null +++ b/data/monster/magicals/guardian_of_tales.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Guardian of Tales") +local monster = {} + +monster.description = "a guardian of tales" +monster.experience = 9204 +monster.outfit = { + lookType = 1063, + lookHead = 92, + lookBody = 54, + lookLegs = 0, + lookFeet = 79, + lookAddons = 3, + lookMount = 0 +} + +monster.raceId = 1659 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 1, + Locations = "Secret Library." + } + +monster.health = 15000 +monster.maxHealth = 15000 +monster.race = "undead" +monster.corpse = 32470 +monster.speed = 420 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 10000, maxCount = 10}, + {name = "Book Page", chance = 10000, maxCount = 5}, + {name = "burnt Scroll", chance = 10000, maxCount = 5}, + {name = "Glowing Rune", chance = 10000, maxCount = 5}, + {name = "Small Diamond", chance = 10000, maxCount = 5}, + {name = "Fire Axe", chance = 250}, + {name = "Soul Orb", chance = 260, maxCount = 5}, + {name = "Spellbook of Warding", chance = 250}, + {name = "Wand of Inferno", chance = 250}, + {name = "Fire Sword", chance = 250}, + {name = "Magma Coat", chance = 350}, + {name = "Magma Legs", chance = 250}, + {name = "Piece of Hellfire Armor", chance = 500, maxCount = 5}, + {id = 13757, chance = 10000, maxCount = 5} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -200, maxDamage = -550}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -605, radius = 3, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -375, maxDamage = -500, length = 5, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_FIREDAMAGE, minDamage = -400, maxDamage = -775, radius = 3, effect = CONST_ME_HITBYFIRE, target = false} +} + +monster.defenses = { + defense = 40, + armor = 82 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 30}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/guzzlemaw.lua b/data/monster/magicals/guzzlemaw.lua new file mode 100644 index 00000000000..71fb88021a4 --- /dev/null +++ b/data/monster/magicals/guzzlemaw.lua @@ -0,0 +1,148 @@ +local mType = Game.createMonsterType("Guzzlemaw") +local monster = {} + +monster.description = "a guzzlemaw" +monster.experience = 6050 +monster.outfit = { + lookType = 584, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1013 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Guzzlemaw Valley, and a single spawn in a tower in Upper Roshamuul \z + (south of the Depot and west of the entrance to Roshamuul Prison)." + } + +monster.health = 6400 +monster.maxHealth = 6400 +monster.race = "blood" +monster.corpse = 22485 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "platinum coin", chance = 100000, maxCount = 7}, + {name = "banana skin", chance = 10700}, + {name = "piece of iron", chance = 10500}, + {name = "fishbone", chance = 9500}, + {id = 2229, chance = 10400}, + {id = 2230, chance = 9200}, + {id = 2231, chance = 4500}, + {name = "two handed sword", chance = 2700}, + {id = 2667, chance = 7000, maxCount = 3}, + {name = "ham", chance = 10000}, + {name = "iron ore", chance = 3000}, + {name = "fish fin", chance = 5000}, + {name = "hardened bone", chance = 5700}, + {id = 5951, chance = 9400}, + {name = "assassin dagger", chance = 1000}, + {name = "haunted blade", chance = 2000}, + {name = "nightmare blade", chance = 380}, + {name = "great mana potion", chance = 17000, maxCount = 3}, + {name = "great health potion", chance = 18500, maxCount = 2}, + {name = "sai", chance = 1200}, + {name = "violet crystal shard", chance = 3000}, + {name = "brown crystal splinter", chance = 12000, maxCount = 2}, + {name = "red crystal fragment", chance = 7600}, + {id = 33539, chance = 12000}, + {name = "cluster of solace", chance = 920}, + {name = "frazzle tongue", chance = 15000}, + {name = "frazzle skin", chance = 14000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -499}, + -- bleed + {name ="condition", type = CONDITION_BLEEDING, interval = 2000, chance = 10, minDamage = -500, maxDamage = -1000, radius = 3, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -900, length = 8, spread = 3, effect = CONST_ME_EXPLOSIONAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -500, radius = 2, shootEffect = CONST_ANI_LARGEROCK, effect = CONST_ME_STONES, target = true}, + {name ="speed", interval = 2000, chance = 15, speedChange = -800, radius = 6, effect = CONST_ME_MAGIC_RED, target = false, duration = 15000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -800, length = 8, spread = 3, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 50, + armor = 50, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 250, maxDamage = 425, effect = CONST_ME_HITBYPOISON, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 15}, + {type = COMBAT_FIREDAMAGE, percent = 5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/icecold_book.lua b/data/monster/magicals/icecold_book.lua new file mode 100644 index 00000000000..52662466b57 --- /dev/null +++ b/data/monster/magicals/icecold_book.lua @@ -0,0 +1,134 @@ +local mType = Game.createMonsterType("Icecold Book") +local monster = {} + +monster.description = "an icecold book" +monster.experience = 12750 +monster.outfit = { + lookType = 1061, + lookHead = 87, + lookBody = 85, + lookLegs = 79, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1664 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Secret Library." + } + +monster.health = 21000 +monster.maxHealth = 21000 +monster.race = "undead" +monster.corpse = 32474 +monster.speed = 440 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 100000, maxCount = 8}, + {name = "Book Page", chance = 100000, maxCount = 3}, + {name = "Small Diamond", chance = 100000, maxCount = 8}, + {name = "Small Sapphire", chance = 100000, maxCount = 8}, + {name = "Quill", chance = 100000, maxCount = 8}, + {name = "Ultimate Health Potion", chance = 100000, maxCount = 8}, + {name = "Ultimate Mana Potion", chance = 100000, maxCount = 8}, + {name = "Diamond Sceptre", chance = 100000}, + {name = "Frosty Heart", chance = 100000, maxCount = 8}, + {name = "Glacier Mask", chance = 350}, + {name = "Ice Rapier", chance = 250}, + {name = "Silken Bookmark", chance = 100000, maxCount = 8}, + {name = "Crystal Mace", chance = 250}, + {name = "Glacier Kilt", chance = 250}, + {name = "Glacier Robe", chance = 250}, + {name = "Glacier Shoes", chance = 350}, + {name = "Strange Helmet", chance = 1000}, + {name = "Sapphire Hammer", chance = 300}, + {id = 7441, chance = 100000}, + {name = "Glacial Rod", chance = 150}, + {name = "Crystalline Armor", chance = 250} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -700, maxDamage = -850, range = 7, shootEffect = CONST_ANI_SMALLICE, effect = CONST_ME_ICEATTACK, target = false}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -100, maxDamage = -380, range = 7, shootEffect = CONST_ANI_SMALLICE, effect = CONST_ME_ICEATTACK, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -350, maxDamage = -980, length = 5, spread = 3, shootEffect = CONST_ANI_SMALLICE, effect = CONST_ME_ICEATTACK, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ICEDAMAGE, minDamage = -230, maxDamage = -880, range = 7, radius = 3, shootEffect = CONST_ANI_SMALLICE, effect = CONST_ME_ICETORNADO, target = false} +} + +monster.defenses = { + defense = 40, + armor = 82 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/lamassu.lua b/data/monster/magicals/lamassu.lua new file mode 100644 index 00000000000..e3dfd836202 --- /dev/null +++ b/data/monster/magicals/lamassu.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Lamassu") +local monster = {} + +monster.description = "a lamassu" +monster.experience = 9000 +monster.outfit = { + lookType = 1190, + lookHead = 50, + lookBody = 2, + lookLegs = 0, + lookFeet = 95, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1806 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Kilmaresh." + } + +monster.health = 8700 +monster.maxHealth = 8700 +monster.race = "blood" +monster.corpse = 36229 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 100000}, + {name = "Lamassu Horn", chance = 13400, maxCount = 5}, + {name = "Red Crystal Fragment", chance = 10500}, + {name = "Terra Amulet", chance = 10000}, + {name = "Lamassu Hoof", chance = 7700}, + {name = "Violet Crystal Shard", chance = 6800}, + {name = "Blue Crystal Shard", chance = 6500}, + {name = "Red Gem", chance = 6200}, + {name = "Terra Hood", chance = 5900}, + {name = "Sacred Tree Amulet", chance = 2300}, + {name = "Elven Amulet", chance = 2000}, + {name = "Violet Gem", chance = 1700} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -550}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HOLYDAMAGE, minDamage = -350, maxDamage = -490, radius = 3, effect = CONST_ME_HOLYAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -330, maxDamage = -410, range = 5, radius = 3, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_SMALLPLANTS, target = true} +} + +monster.defenses = { + defense = 82, + armor = 82 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 80}, + {type = COMBAT_DEATHDAMAGE , percent = -30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/lumbering_carnivor.lua b/data/monster/magicals/lumbering_carnivor.lua new file mode 100644 index 00000000000..914d5e4d559 --- /dev/null +++ b/data/monster/magicals/lumbering_carnivor.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Lumbering Carnivor") +local monster = {} + +monster.description = "a Lumbering Carnivor" +monster.experience = 1452 +monster.outfit = { + lookType = 1133, + lookHead = 0, + lookBody = 39, + lookLegs = 86, + lookFeet = 85, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1721 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Carnivora's Rocks." + } + +monster.health = 2600 +monster.maxHealth = 2600 +monster.race = "blood" +monster.corpse = 34703 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 5}, + {name = "Blue Glass Plate", chance = 100000, maxCount = 3}, + {id = 2376, chance = 15000}, + {name = "Axe", chance = 14000}, + {name = "Ice Rapier", chance = 12000}, + {name = "Glorious Axe", chance = 6100}, + {name = "Blue Robe", chance = 4600}, + {name = "Two Handed Sword", chance = 13000}, + {name = "Fur Armor", chance = 5400}, + {id = 7632, chance = 3200}, + {name = "Green Crystal Shard", chance = 3100}, + {name = "Violet Gem", chance = 4000}, + {name = "Green Gem", chance = 4800}, + {name = "Blue Gem", chance = 4000}, + {name = "Focus Cape", chance = 3000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -200, maxDamage = -500}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -150, radius = 4, effect = CONST_ME_GROUNDSHAKER, target = false} +} + +monster.defenses = { + defense = 20, + armor = 71, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 150, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/manticore.lua b/data/monster/magicals/manticore.lua new file mode 100644 index 00000000000..eefc822224d --- /dev/null +++ b/data/monster/magicals/manticore.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Manticore") +local monster = {} + +monster.description = "a manticore" +monster.experience = 5100 +monster.outfit = { + lookType = 1189, + lookHead = 116, + lookBody = 97, + lookLegs = 113, + lookFeet = 20, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1816 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Kilmaresh." + } + +monster.health = 6700 +monster.maxHealth = 6700 +monster.race = "blood" +monster.corpse = 36225 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 3}, + {name = "flaming arrow", chance = 4090, maxCount = 11}, + {name = "royal star", chance = 1120, maxCount = 4}, + {name = "manticore tail", chance = 8550}, + {name = "manticore ear", chance = 6690}, + {name = "magma legs", chance = 740}, + {name = "magma monocle", chance = 1860}, + {name = "magma boots", chance = 370}, + {name = "magma coat", chance = 2970}, + {name = "wand of everblazing", chance = 1120}, + {name = "wand of dragonbreath", chance = 740}, + {name = "wand of draconia", chance = 370} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -500}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_FIREDAMAGE, minDamage = -350, maxDamage = -450, length = 8, spread = 3, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 4000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -400, radius = 3, shootEffect = CONST_ANI_ENVENOMEDARROW, effect = CONST_ME_GREEN_RINGS, target = true}, + {name ="combat", interval = 2000, chance = 22, type = COMBAT_FIREDAMAGE, minDamage = -300, maxDamage = -500, range = 4, shootEffect = CONST_ANI_BURSTARROW, target = true} +} + +monster.defenses = { + defense = 78, + armor = 78 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/marid.lua b/data/monster/magicals/marid.lua new file mode 100644 index 00000000000..7fd7ad92faa --- /dev/null +++ b/data/monster/magicals/marid.lua @@ -0,0 +1,144 @@ +local mType = Game.createMonsterType("Marid") +local monster = {} + +monster.description = "a marid" +monster.experience = 410 +monster.outfit = { + lookType = 104, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 104 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Kha'zeel, Magician Quarter." + } + +monster.health = 550 +monster.maxHealth = 550 +monster.race = "blood" +monster.corpse = 6033 +monster.speed = 234 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "blue djinn", chance = 10, interval = 2000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Simsalabim", yell = false}, + {text = "Feel the power of my magic, tiny mortal!", yell = false}, + {text = "Wishes can come true", yell = false}, + {text = "Be careful what you wish.", yell = false}, + {text = "Djinns will soon again be the greatest!", yell = false} +} + +monster.loot = { + {id = 1872, chance = 2560}, + {name = "small oil lamp", chance = 110}, + {name = "small sapphire", chance = 6200}, + {name = "gold coin", chance = 60000, maxCount = 70}, + {name = "gold coin", chance = 60000, maxCount = 30}, + {name = "blue gem", chance = 110}, + {name = "hailstorm rod", chance = 770}, + {id = 2070, chance = 5000}, + {name = "heavy machete", chance = 4530}, + {name = "mystic turban", chance = 290}, + {name = "blueberry", chance = 65000, maxCount = 29}, + {name = "blue piece of cloth", chance = 3750}, + {name = "royal spear", chance = 15500, maxCount = 3}, + {name = "strong mana potion", chance = 9800}, + {name = "seeds", chance = 2400}, + {name = "magma monocle", chance = 320}, + {name = "jewelled belt", chance = 7880}, + {name = "noble turban", chance = 530} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -90}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -100, maxDamage = -250, range = 7, shootEffect = CONST_ANI_ENERGYBALL, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -30, maxDamage = -90, range = 7, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -650, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 1500}, + {name ="drunk", interval = 2000, chance = 10, range = 7, shootEffect = CONST_ANI_ENERGY, target = false, duration = 6000}, + {name ="outfit", interval = 2000, chance = 1, range = 7, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 4000, outfitMonster = "rabbit"}, + {name ="djinn electrify", interval = 2000, chance = 15, range = 5, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -30, maxDamage = -90, radius = 3, effect = CONST_ME_ENERGYHIT, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 50, maxDamage = 80, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 60}, + {type = COMBAT_EARTHDAMAGE, percent = 1}, + {type = COMBAT_FIREDAMAGE, percent = 90}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -1}, + {type = COMBAT_HOLYDAMAGE , percent = 1}, + {type = COMBAT_DEATHDAMAGE , percent = -1} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/medusa.lua b/data/monster/magicals/medusa.lua new file mode 100644 index 00000000000..76b152eb772 --- /dev/null +++ b/data/monster/magicals/medusa.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Medusa") +local monster = {} + +monster.description = "a medusa" +monster.experience = 4050 +monster.outfit = { + lookType = 330, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 570 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 5, + Occurrence = 0, + Locations = "Vandura Mountain (single spawn), Talahu (Medusa Cave), Deeper Banuta, Medusa Tower." + } + +monster.health = 4500 +monster.maxHealth = 4500 +monster.race = "blood" +monster.corpse = 10524 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 600, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You will make sssuch a fine ssstatue!", yell = false}, + {text = "There isss no chhhanccce of essscape", yell = false}, + {text = "Jussst look at me!", yell = false}, + {text = "Are you tired or why are you moving thhat ssslow ", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 90}, + {name = "small emerald", chance = 3770, maxCount = 4}, + {name = "platinum coin", chance = 74810, maxCount = 6}, + {name = "knight armor", chance = 1840}, + {name = "medusa shield", chance = 3040}, + {name = "titan axe", chance = 1160}, + {name = "great mana potion", chance = 10000, maxCount = 2}, + {name = "terra mantle", chance = 870}, + {name = "terra legs", chance = 420}, + {name = "terra amulet", chance = 4060}, + {name = "ultimate health potion", chance = 9290, maxCount = 2}, + {id = 9810, chance = 500}, + {name = "sacred tree amulet", chance = 850}, + {name = "strand of medusa hair", chance = 9900} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450, condition = {type = CONDITION_POISON, totalDamage = 840, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -21, maxDamage = -350, range = 7, shootEffect = CONST_ANI_EARTH, effect = CONST_ME_CARNIPHILA, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -250, maxDamage = -500, length = 8, spread = 3, effect = CONST_ME_CARNIPHILA, target = false}, + {name ="speed", interval = 2000, chance = 25, radius = 7, effect = CONST_ME_POFF, target = true}, + {name ="outfit", interval = 2000, chance = 1, range = 7, target = true, duration = 3000, outfitMonster = "clay guardian"} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 150, maxDamage = 300, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/menacing_carnivor.lua b/data/monster/magicals/menacing_carnivor.lua new file mode 100644 index 00000000000..50f13c61a9b --- /dev/null +++ b/data/monster/magicals/menacing_carnivor.lua @@ -0,0 +1,142 @@ +local mType = Game.createMonsterType("Menacing Carnivor") +local monster = {} + +monster.description = "a Menacing Carnivor" +monster.experience = 2112 +monster.outfit = { + lookType = 1139, + lookHead = 86, + lookBody = 70, + lookLegs = 81, + lookFeet = 91, + lookAddons = 3, + lookMount = 0 +} + +monster.raceId = 1723 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Carnivora's Rocks." + } + +monster.health = 3500 +monster.maxHealth = 3500 +monster.race = "blood" +monster.corpse = 34741 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 6}, + {name = "Morning Star", chance = 100000}, + {name = "Terra Rod", chance = 15550}, + {name = "Small Ruby", chance = 15000}, + {name = "Crystal Sword", chance = 25000}, + {name = "Ultimate Mana Potion", chance = 50000}, + {name = "Wand of Dragonbreath", chance = 15000}, + {name = "Machete", chance = 30000}, + {name = "Iron Helmet", chance = 20000}, + {name = "Serpent Sword", chance = 18000}, + {name = "Heavy Machete", chance = 17000}, + {name = "Terra Legs", chance = 6000}, + {name = "Knight Legs", chance = 4500}, + {name = "Wand of Starstorm", chance = 8000}, + {name = "Wand of Voodoo", chance = 7100}, + {name = "Violet Glass Plate", chance = 6200}, + {name = "Small Enchanted Ruby", chance = 1400}, + {name = "Green Crystal Fragment", chance = 1600}, + {name = "Onyx Chip", chance = 9800}, + {name = "Opal", chance = 2000}, + {name = "Tiger Eye", chance = 3000}, + {name = "Wand of Decay", chance = 8700} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -300, maxDamage = -450}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -100, maxDamage = -180, length = 4, spread = 3, effect = CONST_ME_SMOKE, target = false}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_LIFEDRAIN, minDamage = -100, maxDamage = -200, length = 4, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -150, maxDamage = -330, radius = 4, effect = CONST_ME_GROUNDSHAKER, target = false} +} + +monster.defenses = { + defense = 0, + armor = 68, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 150, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.reflects = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/midnight_panther.lua b/data/monster/magicals/midnight_panther.lua new file mode 100644 index 00000000000..2f74499f0ae --- /dev/null +++ b/data/monster/magicals/midnight_panther.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Midnight Panther") +local monster = {} + +monster.description = "a midnight panther" +monster.experience = 900 +monster.outfit = { + lookType = 385, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 698 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 50, + Stars = 3, + Occurrence = 3, + Locations = "Tiquanda." + } + +monster.health = 1200 +monster.maxHealth = 1200 +monster.race = "blood" +monster.corpse = 13327 +monster.speed = 580 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Groooooooar", yell = false}, + {text = "MEOW", yell = false}, + {text = "Groarrrrrrrr", yell = false}, + {text = "Purrrrrrr", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 57}, + {name = "life ring", chance = 12500}, + {name = "meat", chance = 25000, maxCount = 4}, + {name = "panther head", chance = 12500}, + {name = "panther paw", chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 1500, chance = 100, minDamage = 0, maxDamage = -90}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -75, maxDamage = -215, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYAREA, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="speed", interval = 2000, chance = 15, speedChange = 370, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 50, maxDamage = 125, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 1}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -1} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/nightmare.lua b/data/monster/magicals/nightmare.lua new file mode 100644 index 00000000000..58b8d7b81f7 --- /dev/null +++ b/data/monster/magicals/nightmare.lua @@ -0,0 +1,140 @@ +local mType = Game.createMonsterType("Nightmare") +local monster = {} + +monster.description = "a nightmare" +monster.experience = 1666 +monster.outfit = { + lookType = 245, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 299 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Pits of Inferno, Formorgar Mines, Cemetery Quarter, Edron \z + (In multiple places during The Inquisition Quest), Alchemist Quarter, Vengoth Castle, Deeper Banuta, Krailos Ruins." + } + +monster.health = 2700 +monster.maxHealth = 2700 +monster.race = "blood" +monster.corpse = 6340 +monster.speed = 464 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Close your eyes... I want to show you something.", yell = false}, + {text = "I will haunt you forever!", yell = false}, + {text = "Pffffrrrrrrrrrrrr.", yell = false}, + {text = "I will make you scream.", yell = false}, + {text = "Take a ride with me.", yell = false}, + {text = "Weeeheeheeeheee!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 55}, + {name = "platinum coin", chance = 2564, maxCount = 3}, + {name = "boots of haste", chance = 337}, + {name = "war axe", chance = 95}, + {name = "knight legs", chance = 961}, + {name = "ancient shield", chance = 990}, + {name = "power bolt", chance = 9090, maxCount = 4}, + {name = "ham", chance = 29000, maxCount = 2}, + {name = "mysterious voodoo skull", chance = 123}, + {name = "soul orb", chance = 20000}, + {id = 6300, chance = 1298}, + {name = "demonic essence", chance = 10000}, + {name = "skeleton decoration", chance = 337}, + {name = "concentrated demonic blood", chance = 19666, maxCount = 2}, + {name = "essence of a bad dream", chance = 15240}, + {name = "scythe leg", chance = 9090} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -120, maxDamage = -170, range = 7, radius = 1, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -150, maxDamage = -350, range = 7, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 60, maxDamage = 100, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 420, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/nightmare_scion.lua b/data/monster/magicals/nightmare_scion.lua new file mode 100644 index 00000000000..01c41e32a39 --- /dev/null +++ b/data/monster/magicals/nightmare_scion.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Nightmare Scion") +local monster = {} + +monster.description = "a nightmare scion" +monster.experience = 1350 +monster.outfit = { + lookType = 321, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 518 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Cemetery Quarter, Alchemist Quarter and in the Arena and Zoo Quarter (unreachable), \z + Vengoth Castle, Formorgar Mines, Lower Spike, Robson Isle (single respawn), Krailos." + } + +monster.health = 1400 +monster.maxHealth = 1400 +monster.race = "blood" +monster.corpse = 9919 +monster.speed = 440 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Weeeheeheee!", yell = false}, + {text = "Pffffrrrrrrrrrrrr.", yell = false}, + {text = "Peak a boo, I killed you!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 53}, + {name = "platinum coin", chance = 961, maxCount = 3}, + {name = "crown helmet", chance = 666}, + {name = "meat", chance = 50000, maxCount = 4}, + {id = 6300, chance = 250}, + {name = "bar of chocolate", chance = 280}, + {name = "diamond sceptre", chance = 340}, + {name = "shadow sceptre", chance = 270}, + {name = "focus cape", chance = 340}, + {name = "crystal of focus", chance = 100}, + {name = "essence of a bad dream", chance = 7692}, + {name = "scythe leg", chance = 4761} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -140}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -115, maxDamage = -180, range = 7, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -70, maxDamage = -130, range = 7, radius = 1, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = true} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 60, maxDamage = 95, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/nightstalker.lua b/data/monster/magicals/nightstalker.lua new file mode 100644 index 00000000000..6f1c0001640 --- /dev/null +++ b/data/monster/magicals/nightstalker.lua @@ -0,0 +1,140 @@ +local mType = Game.createMonsterType("Nightstalker") +local monster = {} + +monster.description = "a nightstalker" +monster.experience = 500 +monster.outfit = { + lookType = 320, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 520 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Cemetery Quarter, Vengoth Castle, Vandura Mountain, Robson Isle." + } + +monster.health = 700 +monster.maxHealth = 700 +monster.race = "undead" +monster.corpse = 9915 +monster.speed = 260 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "The sunlight is so depressing.", yell = false}, + {text = "Come with me, my child.", yell = false}, + {text = "I've been in the shadow under your bed last night.", yell = false}, + {text = "You never know what hides in the night.", yell = false}, + {text = "I remember your face - and I know where you sleep.", yell = false}, + {text = "Only the sweetest and cruelest dreams for you, my love.", yell = false} +} + +monster.loot = { + {id = 2124, chance = 1030}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 10}, + {name = "platinum amulet", chance = 121}, + {name = "boots of haste", chance = 121}, + {name = "protection amulet", chance = 847}, + {name = "shadow herb", chance = 4761}, + {name = "haunted blade", chance = 318}, + {name = "chaos mace", chance = 121}, + {name = "strong mana potion", chance = 1612}, + {name = "spirit cloak", chance = 520}, + {name = "crystal of balance", chance = 127} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -90, condition = {type = CONDITION_POISON, totalDamage = 80, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -60, maxDamage = -170, range = 7, effect = CONST_ME_HOLYAREA, target = true}, + {name ="speed", interval = 2000, chance = 15, speedChange = -600, effect = CONST_ME_SLEEP, target = true, duration = 15000} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="speed", interval = 2000, chance = 15, speedChange = 240, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000}, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_YELLOW_RINGS}, + {name ="outfit", interval = 5000, chance = 10, target = false, duration = 4000, outfitMonster = "nightstalker"}, + {name ="outfit", interval = 5000, chance = 10, target = false, duration = 4000, outfitMonster = "werewolf"}, + {name ="outfit", interval = 5000, chance = 10, target = false, duration = 4000, outfitMonster = "the count"}, + {name ="outfit", interval = 5000, chance = 10, target = false, duration = 4000, outfitMonster = "grim reaper"}, + {name ="outfit", interval = 5000, chance = 10, target = false, duration = 4000, outfitMonster = "tarantula"}, + {name ="outfit", interval = 5000, chance = 1, target = false, duration = 4000, outfitMonster = "ferumbras"} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/phantasm.lua b/data/monster/magicals/phantasm.lua new file mode 100644 index 00000000000..89d4f50997e --- /dev/null +++ b/data/monster/magicals/phantasm.lua @@ -0,0 +1,143 @@ +local mType = Game.createMonsterType("Phantasm") +local monster = {} + +monster.description = "a phantasm" +monster.experience = 4400 +monster.outfit = { + lookType = 241, + lookHead = 20, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 292 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Pits of Inferno, The Inquisition Quest, Deeper Banuta." + } + +monster.health = 3950 +monster.maxHealth = 3950 +monster.race = "undead" +monster.corpse = 6344 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 350, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Phantasm Summon", chance = 20, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Oh my, you forgot to put your pants on!", yell = false}, + {text = "Weeheeheeheehee!", yell = false}, + {text = "Its nothing but a dream.", yell = false}, + {text = "Dream a little dream with me!", yell = false}, + {text = "Give in.", yell = false} +} + +monster.loot = { + {name = "small ruby", chance = 12160, maxCount = 3}, + {name = "gold coin", chance = 30000, maxCount = 100}, + {name = "gold coin", chance = 30000, maxCount = 100}, + {name = "gold coin", chance = 28000, maxCount = 33}, + {name = "small emerald", chance = 10190, maxCount = 3}, + {name = "small amethyst", chance = 14570, maxCount = 3}, + {name = "platinum coin", chance = 87730, maxCount = 4}, + {name = "stealth ring", chance = 550}, + {name = "blank rune", chance = 22500, maxCount = 2}, + {name = "crown armor", chance = 660}, + {name = "shadow herb", chance = 26930, maxCount = 2}, + {id = 6300, chance = 330}, + {name = "demonic essence", chance = 16320}, + {name = "abyss hammer", chance = 110}, + {name = "shadow sceptre", chance = 550}, + {name = "great mana potion", chance = 32750, maxCount = 2}, + {name = "ultimate health potion", chance = 14680}, + {name = "small topaz", chance = 12810, maxCount = 3} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -475}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -250, maxDamage = -610, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_MANADRAIN, minDamage = -5, maxDamage = -80, radius = 3, effect = CONST_ME_YELLOW_RINGS, target = false}, + {name ="phantasm drown", interval = 2000, chance = 15, target = false}, + {name ="drunk", interval = 2000, chance = 15, radius = 5, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000} +} + +monster.defenses = { + defense = 0, + armor = 0, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_HEALING, minDamage = 228, maxDamage = 449, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = 500, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000}, + {name ="invisible", interval = 2000, chance = 25, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/phantasm_summon.lua b/data/monster/magicals/phantasm_summon.lua new file mode 100644 index 00000000000..9fc67429038 --- /dev/null +++ b/data/monster/magicals/phantasm_summon.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Phantasm") +local monster = {} + +monster.description = "a phantasm" +monster.experience = 4400 +monster.outfit = { + lookType = 241, + lookHead = 20, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3950 +monster.maxHealth = 3950 +monster.race = "undead" +monster.corpse = 6344 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Oh my, you forgot to put your pants on!", yell = false}, + {text = "Weeheeheeheehee!", yell = false}, + {text = "Its nothing but a dream.", yell = false}, + {text = "Dream a little dream with me!", yell = false}, + {text = "Give in.", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -50}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -50, maxDamage = -80, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -5, maxDamage = -80, radius = 3, effect = CONST_ME_YELLOW_RINGS, target = false}, + {name ="phantasm drown", interval = 2000, chance = 10, target = false}, + {name ="drunk", interval = 2000, chance = 5, radius = 5, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000} +} + +monster.defenses = { + defense = 0, + armor = 0, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_HEALING, minDamage = 40, maxDamage = 65, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = 500, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000}, + {name ="invisible", interval = 2000, chance = 25, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/rage_squid.lua b/data/monster/magicals/rage_squid.lua new file mode 100644 index 00000000000..ce6ced95fb9 --- /dev/null +++ b/data/monster/magicals/rage_squid.lua @@ -0,0 +1,142 @@ +local mType = Game.createMonsterType("Rage Squid") +local monster = {} + +monster.description = "a rage squid" +monster.experience = 14820 +monster.outfit = { + lookType = 1059, + lookHead = 94, + lookBody = 78, + lookLegs = 78, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1668 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Secret Library." + } + +monster.health = 17000 +monster.maxHealth = 17000 +monster.race = "undead" +monster.corpse = 32482 +monster.speed = 430 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 33317, chance = 10000}, + {name = "great spirit potion", chance = 10000, maxCount = 3}, + {name = "fire mushroom", chance = 10000, maxCount = 6}, + {name = "small amethyst", chance = 90000, maxCount = 5}, + {name = "slime heart", chance = 3000}, + {name = "piece of dead brain", chance = 4900}, + {name = "platinum coin", chance = 100000, maxCount = 6}, + {name = "ultimate health potion", chance = 10000, maxCount = 3}, + {name = "small topaz", chance = 90000, maxCount = 5}, + {name = "small emerald", chance = 90000, maxCount = 5}, + {name = "red gem", chance = 9800, maxCount = 5}, + {name = "orb", chance = 66000, maxCount = 5}, + {name = "purple tome", chance = 6333}, + {name = "great mana potion", chance = 10000, maxCount = 3}, + {name = "demonic essence", chance = 4300}, + {id = 33315, chance = 10000}, + {name = "small ruby", chance = 90000, maxCount = 5}, + {name = "talon", chance = 8990}, + {name = "might ring", chance = 4990}, + {name = "devil helmet", chance = 6990}, + {name = "demonrage sword", chance = 400}, + {id = 7393, chance = 390}, + {name = "giant sword", chance = 250}, + {name = "demon shield", chance = 250}, + {name = "magic plate armor", chance = 150}, + {name = "platinum amulet", chance = 350}, + {name = "wand of everblazing", chance = 300}, + {name = "fire axe", chance = 500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -500}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -280, range = 7, shootEffect = CONST_ANI_FLAMMINGARROW, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -380, range = 7, shootEffect = CONST_ANI_FIRE, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -175, maxDamage = -200, length = 5, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -475, radius = 3, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -475, radius = 2, effect = CONST_ME_FIREAREA, target = false} +} + +monster.defenses = { + defense = 78, + armor = 78 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/retching_horror.lua b/data/monster/magicals/retching_horror.lua new file mode 100644 index 00000000000..02ca36ab63a --- /dev/null +++ b/data/monster/magicals/retching_horror.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Retching Horror") +local monster = {} + +monster.description = "a retching horror" +monster.experience = 4100 +monster.outfit = { + lookType = 588, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1018 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "All over the surface of Upper Roshamuul and Nightmare Isles." + } + +monster.health = 5300 +monster.maxHealth = 5300 +monster.race = "fire" +monster.corpse = 22508 +monster.speed = 360 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Wait for us, little maggot...", yell = false}, + {text = "We will devour you...", yell = false}, + {text = "My little beetles, go forth, eat, feast!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "platinum coin", chance = 100000, maxCount = 9}, + {name = "fire sword", chance = 1240}, + {name = "crown shield", chance = 1700}, + {name = "tower shield", chance = 550}, + {name = "brown mushroom", chance = 14000, maxCount = 2}, + {name = "beastslayer axe", chance = 4260}, + {name = "mercenary sword", chance = 2500}, + {name = "spiked squelcher", chance = 410}, + {name = "great mana potion", chance = 12500}, + {name = "great health potion", chance = 15000}, + {name = "underworld rod", chance = 1800}, + {name = "wand of starstorm", chance = 960}, + {id = 22363, chance = 3700}, + {name = "goosebump leather", chance = 16400}, + {name = "pool of chitinous glue", chance = 14000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="drunk", interval = 2000, chance = 10, length = 4, spread = 3, effect = CONST_ME_MAGIC_GREEN, target = true, duration = 5000}, + {name ="speed", interval = 2000, chance = 15, speedChange = -700, radius = 4, shootEffect = CONST_ANI_WHIRLWINDCLUB, effect = CONST_ME_STUN, target = true, duration = 15000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -110, radius = 4, effect = CONST_ME_HITAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, radius = 1, shootEffect = CONST_ANI_SNIPERARROW, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -350, radius = 1, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREATTACK, target = true} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/rorc.lua b/data/monster/magicals/rorc.lua new file mode 100644 index 00000000000..2f8e7ab5573 --- /dev/null +++ b/data/monster/magicals/rorc.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Rorc") +local monster = {} + +monster.description = "a rorc" +monster.experience = 105 +monster.outfit = { + lookType = 550, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 978 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "South-west of Ulderek's Rock and in the Rorc version of the Forsaken Mine." + } + +monster.health = 260 +monster.maxHealth = 260 +monster.race = "blood" +monster.corpse = 21223 +monster.speed = 176 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Kroaaah!!", yell = false}, + {text = "Butak bana zamar!", yell = false}, + {text = "Krrrooow truaaak kiiiii!", yell = false} +} + +monster.loot = { + {id = 2129, chance = 7410}, + {name = "gold coin", chance = 73640, maxCount = 25}, + {name = "obsidian lance", chance = 930}, + {name = "orcish axe", chance = 2040}, + {name = "plate shield", chance = 6700}, + {name = "rorc feather", chance = 12520}, + {name = "rorc egg", chance = 790}, + {name = "hatched rorc egg", chance = 12670} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 40, maxDamage = 55, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 300, effect = CONST_ME_MAGIC_RED, target = false, duration = 3000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/shiversleep.lua b/data/monster/magicals/shiversleep.lua new file mode 100644 index 00000000000..8d238e24373 --- /dev/null +++ b/data/monster/magicals/shiversleep.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Shiversleep") +local monster = {} + +monster.description = "Shiversleep" +monster.experience = 1900 +monster.outfit = { + lookType = 592, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 4600 +monster.maxHealth = 4600 +monster.race = "blood" +monster.corpse = 22497 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450}, + {name ="combat", interval = 1800, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -685, length = 7, spread = 3, effect = CONST_ME_STONES, target = false}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_EARTHDAMAGE, minDamage = -250, maxDamage = -590, radius = 6, effect = CONST_ME_BIGPLANTS, target = false} +} + +monster.defenses = { + defense = 55, + armor = 55 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/shock_head.lua b/data/monster/magicals/shock_head.lua new file mode 100644 index 00000000000..85d3fe16af3 --- /dev/null +++ b/data/monster/magicals/shock_head.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Shock Head") +local monster = {} + +monster.description = "a shock head" +monster.experience = 2300 +monster.outfit = { + lookType = 579, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1004 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Sparsely in eastern Lower Roshamuu and southern Guzzlemaw Valley." + } + +monster.health = 4200 +monster.maxHealth = 4200 +monster.race = "blood" +monster.corpse = 22392 +monster.speed = 272 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "", yell = false}, + {text = "Thun... Thun... THUNDER!", yell = false} +} + +monster.loot = { + {name = "small sapphire", chance = 5000}, + {id = 2148, chance = 92000, maxCount = 200}, + {name = "royal helmet", chance = 270} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -798}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -200, maxDamage = -300, length = 5, spread = 2, effect = CONST_ME_BLACKSMOKE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -800, length = 8, spread = 3, effect = CONST_ME_PURPLEENERGY, target = false, duration = 7500}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -350, radius = 4, shootEffect = CONST_ANI_EARTH, effect = CONST_ME_STONES, target = true}, + {name ="shock head skill reducer 1", interval = 2000, chance = 5, range = 5, target = false}, + {name ="shock head skill reducer 2", interval = 2000, chance = 5, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 250, maxDamage = 350, effect = CONST_ME_INSECTS, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/sight_of_surrender.lua b/data/monster/magicals/sight_of_surrender.lua new file mode 100644 index 00000000000..d731d5bd09f --- /dev/null +++ b/data/monster/magicals/sight_of_surrender.lua @@ -0,0 +1,146 @@ +local mType = Game.createMonsterType("Sight of Surrender") +local monster = {} + +monster.description = "a sight of surrender" +monster.experience = 17000 +monster.outfit = { + lookType = 583, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1012 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Dark Grounds, Guzzlemaw Valley (if less than 100 Blowing Horns tasks \z + have been done the day before) and the Silencer Plateau (when Silencer Resonating Chambers are used there)." + } + +monster.health = 28000 +monster.maxHealth = 28000 +monster.race = "undead" +monster.corpse = 22478 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "BOW LOW!", yell = false}, + {text = "FEEL THE TRUE MEANING OF VANQUISH!", yell = false}, + {text = "HAHAHAHA DO YOU WANT TO AMUSE YOUR MASTER?", yell = false}, + {text = "NOW YOU WILL SURRENDER!", yell = false} +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 15}, + {name = "might ring", chance = 8000}, + {name = "stone skin amulet", chance = 18000}, + {name = "hammer of wrath", chance = 1380}, + {name = "crystal mace", chance = 5500}, + {name = "magic plate armor", chance = 1380}, + {name = "crown legs", chance = 920}, + {name = "crusader helmet", chance = 920}, + {name = "tower shield", chance = 1380}, + {name = "steel boots", chance = 920}, + {name = "onyx flail", chance = 920}, + {name = "jade hammer", chance = 920}, + {name = "great mana potion", chance = 78000, maxCount = 5}, + {name = "great spirit potion", chance = 72000, maxCount = 5}, + {name = "ultimate health potion", chance = 30000, maxCount = 5}, + {name = "blue crystal shard", chance = 23000, maxCount = 3}, + {name = "violet crystal shard", chance = 32000, maxCount = 3}, + {name = "green crystal shard", chance = 21600, maxCount = 3}, + {name = "green crystal splinter", chance = 30000, maxCount = 5}, + {name = "brown crystal splinter", chance = 30410, maxCount = 5}, + {name = "blue crystal splinter", chance = 40000, maxCount = 5}, + {name = "cluster of solace", chance = 1800}, + {name = "sight of surrender's eye", chance = 100000}, + {name = "broken visor", chance = 100000}, + {id = 22542, chance = 460} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1100}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -500, maxDamage = -800, length = 8, spread = 3, effect = CONST_ME_YELLOWENERGY, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -500, radius = 1, shootEffect = CONST_ANI_LARGEROCK, target = true} +} + +monster.defenses = { + defense = 70, + armor = 70, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_HEALING, minDamage = 550, maxDamage = 1100, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 520, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 40}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = 35}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/silencer.lua b/data/monster/magicals/silencer.lua new file mode 100644 index 00000000000..27a4b10fb98 --- /dev/null +++ b/data/monster/magicals/silencer.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Silencer") +local monster = {} + +monster.description = "a silencer" +monster.experience = 5100 +monster.outfit = { + lookType = 585, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1014 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 100, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "All over the Roshamuul surface and Nightmare Isles." + } + +monster.health = 5400 +monster.maxHealth = 5400 +monster.race = "blood" +monster.corpse = 22489 +monster.speed = 470 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Prrrroooaaaah!!! PRROAAAH!!", yell = false}, + {text = "PRRRROOOOOAAAAAHHHH!!!", yell = false}, + {text = "HUUUSSSSSSSSH!!", yell = false}, + {text = "Hussssssh!!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "platinum coin", chance = 100000, maxCount = 8}, + {name = "stealth ring", chance = 1200}, + {name = "boots of haste", chance = 360}, + {name = "dark shield", chance = 2000}, + {name = "assassin star", chance = 7600, maxCount = 10}, + {name = "diamond sceptre", chance = 960}, + {name = "haunted blade", chance = 2000}, + {name = "titan axe", chance = 2200}, + {name = "shadow sceptre", chance = 640}, + {name = "glorious axe", chance = 2400}, + {name = "terra legs", chance = 960}, + {name = "terra boots", chance = 480}, + {name = "cluster of solace", chance = 560}, + {name = "silencer claws", chance = 17000}, + {name = "silencer resonating chamber", chance = 8410} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -315, condition = {type = CONDITION_POISON, totalDamage = 600, interval = 4000}}, + {name ="silencer skill reducer", interval = 2000, chance = 10, range = 3, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_MANADRAIN, minDamage = -40, maxDamage = -150, radius = 4, shootEffect = CONST_ANI_ONYXARROW, effect = CONST_ME_MAGIC_RED, target = true} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="speed", interval = 2000, chance = 15, speedChange = 450, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 220, maxDamage = 425, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 70} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/sphinx.lua b/data/monster/magicals/sphinx.lua new file mode 100644 index 00000000000..b1a1965ab3d --- /dev/null +++ b/data/monster/magicals/sphinx.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Sphinx") +local monster = {} + +monster.description = "a sphinx" +monster.experience = 7500 +monster.outfit = { + lookType = 1188, + lookHead = 50, + lookBody = 39, + lookLegs = 0, + lookFeet = 3, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 1808 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Nykri Delta, Kilmaresh Central Steppe, Kilmaresh Southern Steppe, Kilmaresh Catacombs." + } + +monster.health = 8500 +monster.maxHealth = 8500 +monster.race = "blood" +monster.corpse = 36221 +monster.speed = 290 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 100000, maxCount = 3}, + {name = "Sphinx Feather", chance = 9300}, + {name = "Magma Amulet", chance = 7000}, + {id = 36273, chance = 5500}, + {name = "Magma Boots", chance = 3600}, + {name = "Lightning Pendant", chance = 3500}, + {name = "Lightning Headband", chance = 3100}, + {name = "Wand of Starstorm", chance = 2900}, + {name = "Wand of Defiance", chance = 1800}, + {name = "Magma Monocle", chance = 1400}, + {name = "Magma Legs", chance = 1300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -500, length = 6, spread = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HOLYDAMAGE, minDamage = -100, maxDamage = -350, range = 5, radius = 3, shootEffect = CONST_ANI_SMALLHOLY, effect = CONST_ME_HOLYAREA, target = true}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -400, radius = 3, effect = CONST_ME_ENERGYAREA, target = false} +} + +monster.defenses = { + defense = 82, + armor = 82 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 90}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -15}, + {type = COMBAT_HOLYDAMAGE , percent = 85}, + {type = COMBAT_DEATHDAMAGE , percent = -20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/spiky_carnivor.lua b/data/monster/magicals/spiky_carnivor.lua new file mode 100644 index 00000000000..c1928976af9 --- /dev/null +++ b/data/monster/magicals/spiky_carnivor.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Spiky Carnivor") +local monster = {} + +monster.description = "a Spiky Carnivor" +monster.experience = 1650 +monster.outfit = { + lookType = 1139, + lookHead = 79, + lookBody = 119, + lookLegs = 57, + lookFeet = 86, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 1722 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Carnivora's Rocks." + } + +monster.health = 2800 +monster.maxHealth = 2800 +monster.race = "blood" +monster.corpse = 34737 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 100000, maxCount = 6}, + {name = "Green Glass Plate", chance = 12000, maxCount = 17}, + {name = "Blue Crystal Splinter", chance = 11500}, + {name = "Brown Crystal Splinter", chance = 11000}, + {name = "Dark Armor", chance = 10000}, + {name = "Guardian Shield", chance = 9000}, + {name = "Rainbow Quartz", chance = 8500}, + {name = "Blue Robe", chance = 8000}, + {name = "Glacier Amulet", chance = 7500}, + {name = "Lightning Pendant", chance = 2200}, + {name = "Prismatic Quartz", chance = 6500}, + {name = "Talon", chance = 6000}, + {name = "Terra Amulet", chance = 5500}, + {name = "Warrior Helmet", chance = 4000}, + {name = "Shockwave Amulet", chance = 2550}, + {name = "Terra Mantle", chance = 4050}, + {name = "Buckle", chance = 250}, + {name = "Doublet", chance = 250} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -200, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = -230, maxDamage = -380, radius = 4, effect = CONST_ME_GROUNDSHAKER, target = false} +} + +monster.defenses = { + defense = 20, + armor = 71, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 150, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.reflects = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/squid_warden.lua b/data/monster/magicals/squid_warden.lua new file mode 100644 index 00000000000..0a97f6a3c50 --- /dev/null +++ b/data/monster/magicals/squid_warden.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Squid Warden") +local monster = {} + +monster.description = "a squid warden" +monster.experience = 15300 +monster.outfit = { + lookType = 1059, + lookHead = 9, + lookBody = 21, + lookLegs = 41, + lookFeet = 85, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1669 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Secret Library." + } + +monster.health = 16500 +monster.maxHealth = 16500 +monster.race = "undead" +monster.corpse = 32486 +monster.speed = 430 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 11000, maxCount = 57}, + {name = "Glowing Rune", chance = 800, maxCount = 4}, + {name = "Small Sapphire", chance = 900, maxCount = 4}, + {name = "Frosty Heart", chance = 11000, maxCount = 4}, + {id = 7441, chance = 20000}, + {id = 33315, chance = 20000}, + {name = "Ultimate Health Potion", chance = 10003, maxCount = 4}, + {name = "Ultimate Mana Potion", chance = 10003, maxCount = 4}, + {name = "Ice Rapier", chance = 500}, + {name = "Glacier Mask", chance = 400}, + {name = "Piece of Dead Brain", chance = 10001, maxCount = 4}, + {name = "Crystal Sword", chance = 300}, + {name = "Glacier Robe", chance = 150}, + {name = "Glacier Kilt", chance = 150}, + {name = "Slime Heart", chance = 10002, maxCount = 4} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -300}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -100, maxDamage = -200, range = 7, shootEffect = CONST_ANI_ICE, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -200, maxDamage = -680, range = 7, shootEffect = CONST_ANI_SMALLICE, effect = CONST_ME_ICEATTACK, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -200, maxDamage = -375, length = 3, spread = 2, effect = CONST_ME_ICEATTACK, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_ICEDAMAGE, minDamage = -230, maxDamage = -480, range = 7, radius = 3, shootEffect = CONST_ANI_SMALLICE, effect = CONST_ME_ICETORNADO, target = false} +} + +monster.defenses = { + defense = 40, + armor = 78 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/terrorsleep.lua b/data/monster/magicals/terrorsleep.lua new file mode 100644 index 00000000000..7ec2e3abf9c --- /dev/null +++ b/data/monster/magicals/terrorsleep.lua @@ -0,0 +1,143 @@ +local mType = Game.createMonsterType("Terrorsleep") +local monster = {} + +monster.description = "a terrorsleep" +monster.experience = 6900 +monster.outfit = { + lookType = 593, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1016 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Roshamuul Mines, Roshamuul Cistern." + } + +monster.health = 7200 +monster.maxHealth = 7200 +monster.race = "blood" +monster.corpse = 22497 +monster.speed = 360 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Aktat Roshok! Marruk!", yell = false}, + {text = "I will eat you in your sleep.", yell = false}, + {text = "I am the darkness around you...", yell = false} +} + +monster.loot = { + {name = "small ruby", chance = 9600, maxCount = 3}, + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "small emerald", chance = 14000}, + {name = "small amethyst", chance = 17000, maxCount = 3}, + {name = "platinum coin", chance = 100000, maxCount = 8}, + {name = "giant sword", chance = 560}, + {name = "warrior helmet", chance = 2820}, + {name = "knight armor", chance = 4000}, + {name = "white piece of cloth", chance = 4520}, + {name = "red piece of cloth", chance = 1130}, + {name = "great mana potion", chance = 36000, maxCount = 2}, + {name = "ultimate health potion", chance = 26000}, + {name = "small topaz", chance = 17000, maxCount = 2}, + {name = "blue crystal shard", chance = 6000}, + {name = "blue crystal splinter", chance = 13000}, + {name = "cyan crystal fragment", chance = 17000}, + {id = 22363, chance = 1130}, + {name = "trapped bad dream monster", chance = 13000}, + {name = "bowl of terror sweat", chance = 18000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 20, minDamage = -1000, maxDamage = -1500, radius = 7, effect = CONST_ME_YELLOW_RINGS, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -100, maxDamage = -300, radius = 5, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="feversleep skill reducer", interval = 2000, chance = 10, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -350, maxDamage = -500, length = 6, spread = 3, effect = CONST_ME_YELLOWENERGY, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -200, maxDamage = -450, radius = 1, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true} +} + +monster.defenses = { + defense = 50, + armor = 50, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 350, maxDamage = 600, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_HITAREA}, + {name ="speed", interval = 2000, chance = 15, speedChange = 300, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/thanatursus.lua b/data/monster/magicals/thanatursus.lua new file mode 100644 index 00000000000..c5360d71eb0 --- /dev/null +++ b/data/monster/magicals/thanatursus.lua @@ -0,0 +1,138 @@ +local mType = Game.createMonsterType("Thanatursus") +local monster = {} + +monster.description = "a Thanatursus" +monster.experience = 6300 +monster.outfit = { + lookType = 1134, + lookHead = 19, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1728 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Haunted Temple, Court of Winter, Dream Labyrinth." + } + +monster.health = 7200 +monster.maxHealth = 7200 +monster.race = "blood" +monster.corpse = 34707 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Uuuuuuuuuaaaaaarg!!!", yell = false}, + {text = "Nobody will ever escape from this place, muwahaha!!!", yell = false} +} + +monster.loot = { + {name = "Platinum Coin", chance = 100000, maxCount = 17}, + {name = "Meat", chance = 90000, maxCount = 3}, + {name = "Great Spirit Potion", chance = 50000, maxCount = 3}, + {name = "Ultimate Health Potion", chance = 50000}, + {name = "Essence of a Bad Dream", chance = 17000}, + {name = "Knight Axe", chance = 14000}, + {name = "Mino Shield", chance = 12000}, + {name = "Terra Boots", chance = 7000}, + {name = "Terra Hood", chance = 6400}, + {name = "Beastslayer Axe", chance = 500}, + {name = "Black Shield", chance = 3500}, + {name = "Bloody Pincers", chance = 4200}, + {name = "Dark Shield", chance = 1500}, + {name = "Obsidian Lance", chance = 1500}, + {name = "Sickle", chance = 1100}, + {name = "Titan Axe", chance = 1100}, + {name = "Wand of Cosmic Energy", chance = 400}, + {name = "Wand of Defiance", chance = 400}, + {name = "Warrior's Axe", chance = 400}, + {name = "Warrior's Shield", chance = 400} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -200, maxDamage = -450}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HOLYDAMAGE, minDamage = -250, maxDamage = -400, radius = 3, effect = CONST_ME_HOLYAREA, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -280, maxDamage = -450, length = 4, spread = 3, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -250, maxDamage = -400, radius = 6, effect = CONST_ME_BLOCKHIT, target = true} +} + +monster.defenses = { + defense = 25, + armor = 78, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_HEALING, minDamage = 150, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -30}, + {type = COMBAT_ENERGYDAMAGE, percent = -50}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -20}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/magicals/weakened_frazzlemaw.lua b/data/monster/magicals/weakened_frazzlemaw.lua new file mode 100644 index 00000000000..40defd065d2 --- /dev/null +++ b/data/monster/magicals/weakened_frazzlemaw.lua @@ -0,0 +1,141 @@ +local mType = Game.createMonsterType("Weakened Frazzlemaw") +local monster = {} + +monster.description = "a weakened frazzlemaw" +monster.experience = 1000 +monster.outfit = { + lookType = 594, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1442 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Feyrist." + } + +monster.health = 1200 +monster.maxHealth = 1200 +monster.race = "blood" +monster.corpse = 22567 +monster.speed = 300 +monster.manaCost = 450 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Mwaaaahnducate youuuuuu *gurgle*, mwaaah!", yell = false}, + {text = "Mwaaahgod! Overmwaaaaah! *gurgle*", yell = false}, + {text = "MMMWAHMWAHMWAHMWAAAAH!", yell = false}, + {text = "Mmmwhamwhamwhah, mwaaah!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2152, chance = 100000, maxCount = 7}, + {id = 2225, chance = 10400}, + {id = 2229, chance = 12680}, + {id = 2230, chance = 10000}, + {id = 2231, chance = 5500}, + {id = 2667, chance = 6750, maxCount = 3}, + {id = 2671, chance = 6000, maxCount = 2}, + {id = 5880, chance = 700}, + {id = 5895, chance = 900}, + {id = 7418, chance = 700}, + {id = 7590, chance = 15000, maxCount = 3}, + {id = 7591, chance = 15000, maxCount = 2}, + {id = 11306, chance = 1460}, + {id = 22396, chance = 450}, + {id = 22532, chance = 18760}, + {id = 22533, chance = 16000}, + {name = "fairy wings", chance = 30100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 80}, + -- bleed + {name ="condition", type = CONDITION_BLEEDING, interval = 2000, chance = 10, minDamage = -80, maxDamage = -200, radius = 3, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, length = 5, spread = 3, effect = CONST_ME_EXPLOSIONAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -100, radius = 2, shootEffect = CONST_ANI_LARGEROCK, effect = CONST_ME_STONES, target = true}, + {name ="speed", interval = 2000, chance = 15, speedChange = -600, radius = 5, effect = CONST_ME_MAGIC_RED, target = false, duration = 15000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -80, maxDamage = -50, radius = 4, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 80, maxDamage = 225, effect = CONST_ME_HITBYPOISON, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/badger.lua b/data/monster/mammals/badger.lua new file mode 100644 index 00000000000..89c2a3ca4e7 --- /dev/null +++ b/data/monster/mammals/badger.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("Badger") +local monster = {} + +monster.description = "a badger" +monster.experience = 5 +monster.outfit = { + lookType = 105, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 105 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Hrodmir, southern Tiquanda, unannounced raid in Ab'Dendriel and Edron." + } + +monster.health = 23 +monster.maxHealth = 23 +monster.race = "blood" +monster.corpse = 6034 +monster.speed = 180 +monster.manaCost = 200 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 11216, chance = 10230}, + {name = "beetroot", chance = 40710}, + {name = "acorn", chance = 5130} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -12} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/bat.lua b/data/monster/mammals/bat.lua new file mode 100644 index 00000000000..654919ff674 --- /dev/null +++ b/data/monster/mammals/bat.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("Bat") +local monster = {} + +monster.description = "a bat" +monster.experience = 10 +monster.outfit = { + lookType = 122, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 122 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Dark Cathedral, Tiquanda, Drefia, Mount Sternum, Folda, Ghostlands, Kazordoon, \z + Femor Hills, Thais Bat Dungeon, Thais Bandit Cave and in many other caves." + } + +monster.health = 30 +monster.maxHealth = 30 +monster.race = "blood" +monster.corpse = 6053 +monster.speed = 230 +monster.manaCost = 250 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 3, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Flap!Flap!", yell = false} +} + +monster.loot = { + {name = "bat wing", chance = 1220} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -8} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = -20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/bear.lua b/data/monster/mammals/bear.lua new file mode 100644 index 00000000000..c3ec79b69e2 --- /dev/null +++ b/data/monster/mammals/bear.lua @@ -0,0 +1,118 @@ +local mType = Game.createMonsterType("Bear") +local monster = {} + +monster.description = "a bear" +monster.experience = 23 +monster.outfit = { + lookType = 16, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 16 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Several spawns near Kazordoon, Femor Hills, north of Thais, near the White Flower Temple, \z + Rookgaard Bear Cave, Bear Room Quest in Rookgaard, Rookgaard Bear Mountain, South of Villa Scapula, \z + Ferngrims Gate, North of Carlin, Fields of Glory, Edron Troll Cave, south of Venore, Desert Dungeon, \z + first floor of the Orc Fort mountain and west of Outlaw Camp." + } + +monster.health = 80 +monster.maxHealth = 80 +monster.race = "blood" +monster.corpse = 5975 +monster.speed = 156 +monster.manaCost = 300 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grrrr", yell = false}, + {text = "Groar", yell = false} +} + +monster.loot = { + {name = "meat", chance = 39750, maxCount = 4}, + {name = "ham", chance = 20000, maxCount = 3}, + {name = "bear paw", chance = 2000}, + {name = "honeycomb", chance = 460} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -25} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/black_sheep.lua b/data/monster/mammals/black_sheep.lua new file mode 100644 index 00000000000..8d2963f0190 --- /dev/null +++ b/data/monster/mammals/black_sheep.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Black Sheep") +local monster = {} + +monster.description = "a black sheep" +monster.experience = 0 +monster.outfit = { + lookType = 13, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 13 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Femor Hills, cultist cave in Liberty Bay, Drefia." + } + +monster.health = 20 +monster.maxHealth = 20 +monster.race = "blood" +monster.corpse = 5994 +monster.speed = 116 +monster.manaCost = 250 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = false, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Maeh", yell = false} +} + +monster.loot = { + {name = "meat", chance = 70860, maxCount = 5}, + {name = "black wool", chance = 1000} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/boar.lua b/data/monster/mammals/boar.lua new file mode 100644 index 00000000000..2555473fe5f --- /dev/null +++ b/data/monster/mammals/boar.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Boar") +local monster = {} + +monster.description = "a boar" +monster.experience = 60 +monster.outfit = { + lookType = 380, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 693 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Forest around Outlaw Camp." + } + +monster.health = 198 +monster.maxHealth = 198 +monster.race = "blood" +monster.corpse = 13308 +monster.speed = 410 +monster.manaCost = 465 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 30, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grunt", yell = false}, + {text = "Grunt! Grunt!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 25000, maxCount = 20}, + {name = "haunch of boar", chance = 20000, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -50} +} + +monster.defenses = { + defense = 35, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/brown_horse.lua b/data/monster/mammals/brown_horse.lua new file mode 100644 index 00000000000..caf063d6d55 --- /dev/null +++ b/data/monster/mammals/brown_horse.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("Brown Horse") +local monster = {} + +monster.name = "Horse" +monster.description = "a horse" +monster.experience = 0 +monster.outfit = { + lookType = 436, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 752 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 1, + Locations = "South-east, east and north-east of Thais depending on the Horse Station World Change." + } + +monster.health = 75 +monster.maxHealth = 75 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 248 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 75, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Weeeeheeeeeee", yell = false}, + {text = "*snort*", yell = false}, + {text = "*Weeeeheeeeaaa*", yell = false} +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/cat.lua b/data/monster/mammals/cat.lua new file mode 100644 index 00000000000..5874847ebe9 --- /dev/null +++ b/data/monster/mammals/cat.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Cat") +local monster = {} + +monster.description = "a cat" +monster.experience = 0 +monster.outfit = { + lookType = 276, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 387 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 25, + FirstUnlock = 5, + SecondUnlock = 10, + CharmsPoints = 1, + Stars = 0, + Occurrence = 0, + Locations = "Carlin, Rookgaard, Factory Quarter, Yalahar, \z + The Witches' Cliff (only accessible during a quest), probably more areas." + } + +monster.health = 20 +monster.maxHealth = 20 +monster.race = "blood" +monster.corpse = 7637 +monster.speed = 124 +monster.manaCost = 220 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = false, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 8, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Mew!", yell = false}, + {text = "Meow!", yell = false}, + {text = "Meow meow!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = 0} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/cave_rat.lua b/data/monster/mammals/cave_rat.lua new file mode 100644 index 00000000000..9b1b315649d --- /dev/null +++ b/data/monster/mammals/cave_rat.lua @@ -0,0 +1,117 @@ +local mType = Game.createMonsterType("Cave Rat") +local monster = {} + +monster.description = "a cave rat" +monster.experience = 10 +monster.outfit = { + lookType = 56, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 56 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Almost everywhere in tibia, they seem to have a nest-like place in Greenshore, \z + a semi-large spawn at the entrance to the Port Hope troll cave and in cave near Ankrahmun ship. \z + Also appears in Rat Plague in Thais and Rat Plague in Rookgaard." + } + +monster.health = 30 +monster.maxHealth = 30 +monster.race = "blood" +monster.corpse = 5964 +monster.speed = 150 +monster.manaCost = 250 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 3, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Meeeeep!", yell = false}, + {text = "Meep!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 85000, maxCount = 2}, + {name = "cookie", chance = 750}, + {id = 2696, chance = 30000}, + {name = "worm", chance = 9700, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -10} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/clomp.lua b/data/monster/mammals/clomp.lua new file mode 100644 index 00000000000..cabe2e29289 --- /dev/null +++ b/data/monster/mammals/clomp.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Clomp") +local monster = {} + +monster.description = "a clomp" +monster.experience = 475 +monster.outfit = { + lookType = 860, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1174 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Krailos Steppe." + } + +monster.health = 900 +monster.maxHealth = 900 +monster.race = "blood" +monster.corpse = 25398 +monster.speed = 430 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Snort!", yell = false}, + {text = "Grunt!", yell = false}, + {text = "Snarl!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 92000, maxCount = 130}, + {id = 24842, chance = 2200}, + {id = 5925, chance = 1200, maxCount = 2}, + {id = 11224, chance = 900}, + {id = 3973, chance = 400}, + {id = 7432, chance = 200} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 40, maxDamage = -289, condition = {type = CONDITION_FIRE, totalDamage = 6, interval = 9000}} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 80, maxDamage = 95, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/crystal_wolf.lua b/data/monster/mammals/crystal_wolf.lua new file mode 100644 index 00000000000..ed977785484 --- /dev/null +++ b/data/monster/mammals/crystal_wolf.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Crystal Wolf") +local monster = {} + +monster.description = "a crystal wolf" +monster.experience = 275 +monster.outfit = { + lookType = 391, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 740 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 50, + Stars = 3, + Occurrence = 3, + Locations = "Shadowthorn." + } + +monster.health = 750 +monster.maxHealth = 750 +monster.race = "undead" +monster.corpse = 13584 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Raaarrr!", yell = false}, + {text = "Aaaauuuuuooooooo!!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 56000, maxCount = 52}, + {name = "hailstorm rod", chance = 7400}, + {name = "meat", chance = 52000, maxCount = 4}, + {name = "wolf paw", chance = 3700}, + {name = "shiver arrow", chance = 11000, maxCount = 10}, + {name = "crystalline armor", chance = 3700} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -80}, + {name ="crystal wolf wave", interval = 2000, chance = 15, minDamage = -60, maxDamage = -130, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -80, maxDamage = -150, range = 6, radius = 3, shootEffect = CONST_ANI_SMALLICE, effect = CONST_ME_GIANTICE, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -25, maxDamage = -80, range = 7, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 15, maxDamage = 55, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/deer.lua b/data/monster/mammals/deer.lua new file mode 100644 index 00000000000..ca1ce22c7cf --- /dev/null +++ b/data/monster/mammals/deer.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Deer") +local monster = {} + +monster.description = "a deer" +monster.experience = 0 +monster.outfit = { + lookType = 31, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 31 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Darama (Devourer, Kha'labal), in most grassy areas of Tibia, also found in \z + Rookgaard and on Tutorial Island. There are also 2 unreachable Deer found near Fiehonja's protection zone." + } + +monster.health = 25 +monster.maxHealth = 25 +monster.race = "blood" +monster.corpse = 5970 +monster.speed = 196 +monster.manaCost = 260 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = false, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 25, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "meat", chance = 80000, maxCount = 4}, + {name = "ham", chance = 50000, maxCount = 2}, + {id = 11214, chance = 870} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/desperate_white_deer.lua b/data/monster/mammals/desperate_white_deer.lua new file mode 100644 index 00000000000..402e8b3fd6e --- /dev/null +++ b/data/monster/mammals/desperate_white_deer.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Desperate White Deer") +local monster = {} + +monster.description = "a desperate white deer" +monster.experience = 35 +monster.outfit = { + lookType = 400, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 55 +monster.maxHealth = 55 +monster.race = "blood" +monster.corpse = 13513 +monster.speed = 225 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 55, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "WhiteDeerScoutsDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "*bell*", yell = false}, + {text = "ROOOAAARR!!", yell = false}, + {text = "*sniff*", yell = false}, + {text = "*wheeze*", yell = false} +} + +monster.loot = { + {name = "ham", chance = 20000, maxCount = 3}, + {name = "white deer antlers", chance = 20000}, + {name = "white deer skin", chance = 20000} +} + +monster.attacks = { +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="speed", interval = 2000, chance = 15, speedChange = 400, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/dog.lua b/data/monster/mammals/dog.lua new file mode 100644 index 00000000000..4c667b2e1fc --- /dev/null +++ b/data/monster/mammals/dog.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Dog") +local monster = {} + +monster.description = "a dog" +monster.experience = 0 +monster.outfit = { + lookType = 32, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 32 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 25, + FirstUnlock = 5, + SecondUnlock = 10, + CharmsPoints = 1, + Stars = 0, + Occurrence = 0, + Locations = "Isle of the Kings, North of the Thais temple, Lubos house, west of Carlin (with sheep), \z + Edron north of castle and one south towards Ivory Towers, Liberty Bay (Silverhand Manor), \z + Mintwallin central park and on the way to the old Mintwallin area, Factory Quarter (Yalahar)." + } + +monster.health = 20 +monster.maxHealth = 20 +monster.race = "blood" +monster.corpse = 5971 +monster.speed = 124 +monster.manaCost = 220 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = false, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 8, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Wuff wuff", yell = false} +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/donkey.lua b/data/monster/mammals/donkey.lua new file mode 100644 index 00000000000..5db00809da7 --- /dev/null +++ b/data/monster/mammals/donkey.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Donkey") +local monster = {} + +monster.description = "a donkey" +monster.experience = 0 +monster.outfit = { + lookType = 387, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 45 +monster.maxHealth = 45 +monster.race = "blood" +monster.corpse = 13509 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 25, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grunt!", yell = false} +} + +monster.loot = { + {name = "meat", chance = 20000, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -5} +} + +monster.defenses = { + defense = 2, + armor = 2 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/doom_deer.lua b/data/monster/mammals/doom_deer.lua new file mode 100644 index 00000000000..917c4d7fc09 --- /dev/null +++ b/data/monster/mammals/doom_deer.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Doom Deer") +local monster = {} + +monster.description = "a doom deer" +monster.experience = 200 +monster.outfit = { + lookType = 31, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 559 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "Isle of Evil." + } + +monster.health = 405 +monster.maxHealth = 405 +monster.race = "blood" +monster.corpse = 5970 +monster.speed = 182 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 25, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I bet it was you who killed my mom!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="combat", interval = 4000, chance = 30, type = COMBAT_ENERGYDAMAGE, minDamage = -35, maxDamage = -55, length = 5, spread = 3, effect = CONST_ME_BIGCLOUDS, target = false} +} + +monster.defenses = { + defense = 35, + armor = 30, + {name ="speed", interval = 3000, chance = 30, speedChange = 400, effect = CONST_ME_MAGIC_RED, target = false, duration = 8000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/dromedary.lua b/data/monster/mammals/dromedary.lua new file mode 100644 index 00000000000..fd022b8ef46 --- /dev/null +++ b/data/monster/mammals/dromedary.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Dromedary") +local monster = {} + +monster.description = "a dromedary" +monster.experience = 0 +monster.outfit = { + lookType = 404, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 733 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 10, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Ankrahmun near way to Darashia, Ankrahmun near sea, also in few places around Darashia." + } + +monster.health = 45 +monster.maxHealth = 45 +monster.race = "blood" +monster.corpse = 13528 +monster.speed = 114 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 45, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Snort", yell = false}, + {text = "Grunt!", yell = false} +} + +monster.loot = { + {name = "meat", chance = 36000, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -8}, + {name ="drunk", interval = 4000, chance = 5, range = 1, shootEffect = CONST_ANI_EXPLOSION, effect = CONST_ME_STUN, target = true, duration = 6000} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/elephant.lua b/data/monster/mammals/elephant.lua new file mode 100644 index 00000000000..897d24c77ad --- /dev/null +++ b/data/monster/mammals/elephant.lua @@ -0,0 +1,118 @@ +local mType = Game.createMonsterType("Elephant") +local monster = {} + +monster.description = "an elephant" +monster.experience = 160 +monster.outfit = { + lookType = 211, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 211 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "East of Port Hope close to Grizzly Adams, deep in the jungle, \z + Arena and Zoo Quarter, Mammoth Shearing Factory." + } + +monster.health = 320 +monster.maxHealth = 320 +monster.race = "blood" +monster.corpse = 6052 +monster.speed = 190 +monster.manaCost = 500 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hooooot-Toooooot!", yell = false}, + {text = "Tooooot!", yell = false}, + {text = "Trooooot!", yell = false} +} + +monster.loot = { + {name = "meat", chance = 39000, maxCount = 4}, + {name = "ham", chance = 30000, maxCount = 3}, + {name = "tusk", chance = 1000, maxCount = 2}, + {name = "tusk shield", chance = 140} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 25}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/enraged_squirrel.lua b/data/monster/mammals/enraged_squirrel.lua new file mode 100644 index 00000000000..78ccf05c054 --- /dev/null +++ b/data/monster/mammals/enraged_squirrel.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Enraged Squirrel") +local monster = {} + +monster.description = "an enraged squirrel" +monster.experience = 15 +monster.outfit = { + lookType = 274, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 35 +monster.maxHealth = 35 +monster.race = "blood" +monster.corpse = 7628 +monster.speed = 300 +monster.manaCost = 220 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 2, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Chchch", yell = false} +} + +monster.loot = { + {id = 7909, chance = 2680} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 10} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/enraged_white_deer.lua b/data/monster/mammals/enraged_white_deer.lua new file mode 100644 index 00000000000..d41a4008d53 --- /dev/null +++ b/data/monster/mammals/enraged_white_deer.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Enraged White Deer") +local monster = {} + +monster.description = "an enraged white deer" +monster.experience = 165 +monster.outfit = { + lookType = 400, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 255 +monster.maxHealth = 255 +monster.race = "blood" +monster.corpse = 13513 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "WhiteDeerScoutsDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "*wheeze*", yell = false}, + {text = "ROOOAAARR!!", yell = false}, + {text = "*sniff*", yell = false}, + {text = "*bell*", yell = false} +} + +monster.loot = { + {name = "ham", chance = 19850, maxCount = 3}, + {name = "white deer antlers", chance = 19520}, + {name = "white deer skin", chance = 20280} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -45} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 4000, chance = 15, type = COMBAT_HEALING, minDamage = 10, maxDamage = 40, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/evil_sheep.lua b/data/monster/mammals/evil_sheep.lua new file mode 100644 index 00000000000..cc7ef2312a8 --- /dev/null +++ b/data/monster/mammals/evil_sheep.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("Evil Sheep") +local monster = {} + +monster.description = "an evil sheep" +monster.experience = 240 +monster.outfit = { + lookType = 14, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 555 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Isle of Evil." + } + +monster.health = 350 +monster.maxHealth = 350 +monster.race = "blood" +monster.corpse = 5991 +monster.speed = 156 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grrrr", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 50} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -90}, + {name ="combat", interval = 4000, chance = 30, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -50, range = 7, shootEffect = CONST_ANI_SNOWBALL, target = true} +} + +monster.defenses = { + defense = 35, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/evil_sheep_lord.lua b/data/monster/mammals/evil_sheep_lord.lua new file mode 100644 index 00000000000..6cb6e8d75f4 --- /dev/null +++ b/data/monster/mammals/evil_sheep_lord.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Evil Sheep Lord") +local monster = {} + +monster.description = "an evil sheep lord" +monster.experience = 340 +monster.outfit = { + lookType = 13, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 556 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "Isle of Evil." + } + +monster.health = 400 +monster.maxHealth = 400 +monster.race = "blood" +monster.corpse = 5994 +monster.speed = 178 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 2000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Evil Sheep", chance = 30, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You can COUNT on us!", yell = false}, + {text = "Maeh!", yell = false}, + {text = "I feel you're getting sleepy! Maeh!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 75000, maxCount = 60} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -118}, + {name ="outfit", interval = 3000, chance = 20, range = 7, effect = CONST_ME_MAGIC_BLUE, target = true, duration = 4000, outfitMonster = "Sheep"} +} + +monster.defenses = { + defense = 35, + armor = 30, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 50, maxDamage = 100, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="outfit", interval = 1500, chance = 50, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 3000, outfitMonster = "Werewolf"} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -20}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/exotic_bat.lua b/data/monster/mammals/exotic_bat.lua new file mode 100644 index 00000000000..a20dba883ec --- /dev/null +++ b/data/monster/mammals/exotic_bat.lua @@ -0,0 +1,118 @@ +local mType = Game.createMonsterType("Exotic Bat") +local monster = {} + +monster.description = "a exotic bat" +monster.experience = 1200 +monster.outfit = { + lookType = 1373, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 2051 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Exotic cave Spider cave." + } + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "venom" +monster.corpse = 40525 +monster.speed = 200 +monster.manaCost = 250 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 0 +} + +monster.loot = { + {name = "platinum coin", chance = 90540, maxCount = 4}, + {name = "great mana potion", chance = 22220, maxCount = 2}, + {name = "terra amulet", chance = 14920}, + {name = "dark mushroom", chance = 13660, maxCount = 6}, + {name = "green mushroom", chance = 14560, maxCount = 5}, + {name = "garlic necklace", chance = 1680}, + {name = "bat wing", chance = 1550, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -80, maxDamage = -150, length = 5, spread = 2, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = -60, maxDamage = -150, range = 7, radius = 3, effect = CONST_ME_YELLOW_RINGS, target = true} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 1}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = 5}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/fox.lua b/data/monster/mammals/fox.lua new file mode 100644 index 00000000000..37867f969e6 --- /dev/null +++ b/data/monster/mammals/fox.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Fox") +local monster = {} + +monster.description = "a fox" +monster.experience = 15 +monster.outfit = { + lookType = 1029, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1548 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "South-west of Edron, possibly other places." + } + +monster.health = 22 +monster.maxHealth = 22 +monster.race = "blood" +monster.corpse = 30752 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Yip! Yip!", yell = false}, + {text = "Grrrrrrr", yell = false} +} + +monster.loot = { + {id = 2666, chance = 49320}, + {name = "Fox Paw", chance = 1350} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -5} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/ghost_wolf.lua b/data/monster/mammals/ghost_wolf.lua new file mode 100644 index 00000000000..332b528b422 --- /dev/null +++ b/data/monster/mammals/ghost_wolf.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("Ghost Wolf") +local monster = {} + +monster.description = "a ghost wolf" +monster.experience = 65 +monster.outfit = { + lookType = 730, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1148 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 2, + Locations = "Poacher Caves/Gloomy." + } + +monster.health = 160 +monster.maxHealth = 160 +monster.race = "blood" +monster.corpse = 6009 +monster.speed = 270 +monster.manaCost = 420 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -50} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = true}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/ghoulish_hyaena.lua b/data/monster/mammals/ghoulish_hyaena.lua new file mode 100644 index 00000000000..5e8154d8745 --- /dev/null +++ b/data/monster/mammals/ghoulish_hyaena.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("Ghoulish Hyaena") +local monster = {} + +monster.description = "a ghoulish hyaena" +monster.experience = 195 +monster.outfit = { + lookType = 94, + lookHead = 20, + lookBody = 30, + lookLegs = 40, + lookFeet = 50, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 704 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Horestis Tomb." + } + +monster.health = 400 +monster.maxHealth = 400 +monster.race = "blood" +monster.corpse = 6026 +monster.speed = 200 +monster.manaCost = 275 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 30, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grawrrr!!", yell = false}, + {text = "Hoouu!", yell = false} +} + +monster.loot = { + {name = "small ruby", chance = 2700, maxCount = 2}, + {name = "gold coin", chance = 89000, maxCount = 40}, + {name = "meat", chance = 51060, maxCount = 3}, + {name = "worm", chance = 65000, maxCount = 7}, + {name = "health potion", chance = 19840} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -112, condition = {type = CONDITION_POISON, totalDamage = 10, interval = 4000}}, + -- poison + {name ="ghoulish hyaena wave", interval = 2000, chance = 15, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="speed", interval = 2000, chance = 15, speedChange = 3000, target = false, duration = 2000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 70}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/gloom_wolf.lua b/data/monster/mammals/gloom_wolf.lua new file mode 100644 index 00000000000..b9462f26704 --- /dev/null +++ b/data/monster/mammals/gloom_wolf.lua @@ -0,0 +1,114 @@ +local mType = Game.createMonsterType("Gloom Wolf") +local monster = {} + +monster.description = "a gloom wolf" +monster.experience = 70 +monster.outfit = { + lookType = 716, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1139 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 1, + Locations = "Tainted Caves, Poacher Caves/Gloomy." + } + +monster.health = 200 +monster.maxHealth = 200 +monster.race = "blood" +monster.corpse = 24639 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 8, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "ham", chance = 20120}, + {id = 2129, chance = 2000}, + {name = "gold coin", chance = 65000, maxCount = 48}, + {name = "meat", chance = 55000, maxCount = 2}, + {name = "wolf paw", chance = 980} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -92} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 35}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 5}, + {type = COMBAT_DEATHDAMAGE , percent = 35} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/gnarlhound.lua b/data/monster/mammals/gnarlhound.lua new file mode 100644 index 00000000000..f36c922309d --- /dev/null +++ b/data/monster/mammals/gnarlhound.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Gnarlhound") +local monster = {} + +monster.description = "a gnarlhound" +monster.experience = 60 +monster.outfit = { + lookType = 341, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 630 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Zao Steppe, Raging Mage Tower, Gnarlhound Caves. \z + Four inaccessible ones can be seen in Telas's basement." + } + +monster.health = 198 +monster.maxHealth = 198 +monster.race = "blood" +monster.corpse = 11250 +monster.speed = 410 +monster.manaCost = 465 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Gnarllll!", yell = false}, + {text = "Grrrrrr!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 48000, maxCount = 30}, + {name = "meat", chance = 39075, maxCount = 3}, + {name = "worm", chance = 33300, maxCount = 3}, + {name = "shaggy tail", chance = 25550} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -70} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/grey_horse.lua b/data/monster/mammals/grey_horse.lua new file mode 100644 index 00000000000..34d70ba204d --- /dev/null +++ b/data/monster/mammals/grey_horse.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("Horse") +local monster = {} + +monster.description = "a horse" +monster.experience = 0 +monster.outfit = { + lookType = 434, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 751 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 2, + Locations = "South-east, east and north-east of Thais depending on the Horse Station World Change; \z + one in the Gardens of Night (here, unreachable); one near Roswitha in Rathleton." + } + +monster.health = 75 +monster.maxHealth = 75 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 248 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 75, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Weeeeheeeeeee", yell = false}, + {text = "*snort*", yell = false}, + {text = "*Weeeeheeeeaaa*", yell = false} +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/horse.lua b/data/monster/mammals/horse.lua new file mode 100644 index 00000000000..418e2c1a416 --- /dev/null +++ b/data/monster/mammals/horse.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("Horse") +local monster = {} + +monster.description = "a horse" +monster.experience = 0 +monster.outfit = { + lookType = 435, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 750 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 1, + Locations = "South-east, east and north-east of Thais depending on the Horse Station World Change; \z + one near Roswitha in Rathleton." + } + +monster.health = 75 +monster.maxHealth = 75 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 248 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 75, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Weeeeheeeeeee", yell = false}, + {text = "*snort*", yell = false}, + {text = "*Weeeeheeeeaaa*", yell = false} +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/hot_dog.lua b/data/monster/mammals/hot_dog.lua new file mode 100644 index 00000000000..7ac539e64c5 --- /dev/null +++ b/data/monster/mammals/hot_dog.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("Hot Dog") +local monster = {} + +monster.description = "a hot dog" +monster.experience = 190 +monster.outfit = { + lookType = 32, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 557 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "Isle of Evil." + } + +monster.health = 505 +monster.maxHealth = 505 +monster.race = "blood" +monster.corpse = 5971 +monster.speed = 150 +monster.manaCost = 220 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Wuff Wuff", yell = false}, + {text = "Grrr Wuff", yell = false}, + {text = "Show me how good you are without some rolled newspaper!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 75} +} + +monster.attacks = { + {name ="melee", interval = 1200, chance = 100, minDamage = 0, maxDamage = -55}, + {name ="hot dog wave", interval = 2000, chance = 30, minDamage = -30, maxDamage = -60, target = false}, + {name ="combat", interval = 1000, chance = 30, type = COMBAT_FIREDAMAGE, minDamage = -50, maxDamage = -50, range = 7, effect = CONST_ME_FIREATTACK, target = true} +} + +monster.defenses = { + defense = 2, + armor = 1 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -20}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/husky.lua b/data/monster/mammals/husky.lua new file mode 100644 index 00000000000..33bc2647fa4 --- /dev/null +++ b/data/monster/mammals/husky.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Husky") +local monster = {} + +monster.description = "a husky" +monster.experience = 0 +monster.outfit = { + lookType = 258, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 325 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 25, + FirstUnlock = 5, + SecondUnlock = 10, + CharmsPoints = 1, + Stars = 0, + Occurrence = 1, + Locations = "Svargrond and Nibelor." + } + +monster.health = 140 +monster.maxHealth = 140 +monster.race = "blood" +monster.corpse = 7316 +monster.speed = 264 +monster.manaCost = 420 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = false, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Yoooohuuuu!", yell = false}, + {text = "Grrrrrrr", yell = false}, + {text = "Ruff, ruff!", yell = false} +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/hyaena.lua b/data/monster/mammals/hyaena.lua new file mode 100644 index 00000000000..fc24bf78850 --- /dev/null +++ b/data/monster/mammals/hyaena.lua @@ -0,0 +1,111 @@ +local mType = Game.createMonsterType("Hyaena") +local monster = {} + +monster.description = "a hyaena" +monster.experience = 20 +monster.outfit = { + lookType = 94, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 94 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Desert areas like those around Ankrahmun and Darashia." + } + +monster.health = 60 +monster.maxHealth = 60 +monster.race = "blood" +monster.corpse = 6026 +monster.speed = 200 +monster.manaCost = 275 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 30, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "meat", chance = 30860, maxCount = 2}, + {name = "worm", chance = 50130, maxCount = 3} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -20} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/killer_rabbit.lua b/data/monster/mammals/killer_rabbit.lua new file mode 100644 index 00000000000..5029f15e150 --- /dev/null +++ b/data/monster/mammals/killer_rabbit.lua @@ -0,0 +1,118 @@ +local mType = Game.createMonsterType("Killer Rabbit") +local monster = {} + +monster.description = "a killer rabbit" +monster.experience = 160 +monster.outfit = { + lookType = 74, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 560 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 1, + Locations = "Isle of Evil." + } + +monster.health = 205 +monster.maxHealth = 205 +monster.race = "blood" +monster.corpse = 6017 +monster.speed = 340 +monster.manaCost = 220 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "killer rabbit", chance = 30, interval = 2000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Who is lunch NOW?", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 90} +} + +monster.attacks = { + {name ="melee", interval = 1200, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -50, range = 1, target = false} +} + +monster.defenses = { + defense = 35, + armor = 30, + {name ="speed", interval = 1000, chance = 40, speedChange = 380, effect = CONST_ME_ENERGYHIT, target = false, duration = 8000}, + {name ="invisible", interval = 2000, chance = 30, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/kongra.lua b/data/monster/mammals/kongra.lua new file mode 100644 index 00000000000..072181cda2c --- /dev/null +++ b/data/monster/mammals/kongra.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Kongra") +local monster = {} + +monster.description = "a kongra" +monster.experience = 115 +monster.outfit = { + lookType = 116, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 116 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "In Banuta, northeast of Port Hope, Arena and Zoo Quarter." + } + +monster.health = 340 +monster.maxHealth = 340 +monster.race = "blood" +monster.corpse = 6043 +monster.speed = 184 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hugah!", yell = false}, + {text = "Ungh! Ungh!", yell = false}, + {text = "Huaauaauaauaa!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 69000, maxCount = 40}, + {name = "power ring", chance = 300}, + {name = "protection amulet", chance = 990}, + {name = "club ring", chance = 230}, + {name = "plate armor", chance = 950}, + {name = "banana", chance = 30000, maxCount = 12}, + {name = "ape fur", chance = 980}, + {name = "health potion", chance = 570}, + {name = "kongra's shoulderpad", chance = 4900} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -60} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="speed", interval = 2000, chance = 15, speedChange = 260, effect = CONST_ME_MAGIC_RED, target = false, duration = 3000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/lion.lua b/data/monster/mammals/lion.lua new file mode 100644 index 00000000000..ef7cee3f2dc --- /dev/null +++ b/data/monster/mammals/lion.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Lion") +local monster = {} + +monster.description = "a lion" +monster.experience = 30 +monster.outfit = { + lookType = 41, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 41 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Jakundaf Desert, Darama, Arena Quarter, Venore Amazon Camp." + } + +monster.health = 80 +monster.maxHealth = 80 +monster.race = "blood" +monster.corpse = 5986 +monster.speed = 190 +monster.manaCost = 320 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Groarrr!", yell = false} +} + +monster.loot = { + {name = "meat", chance = 45000, maxCount = 4}, + {name = "ham", chance = 18430, maxCount = 2}, + {name = "lion's mane", chance = 1400} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -40} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -15}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -8} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/mammoth.lua b/data/monster/mammals/mammoth.lua new file mode 100644 index 00000000000..7c0f7d50520 --- /dev/null +++ b/data/monster/mammals/mammoth.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Mammoth") +local monster = {} + +monster.description = "a mammoth" +monster.experience = 160 +monster.outfit = { + lookType = 199, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 260 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Formorgar Glacier, Tyrsung, around the Barbarian Settlements, Mammoth Shearing Factory, Chyllfroest." + } + +monster.health = 320 +monster.maxHealth = 320 +monster.race = "blood" +monster.corpse = 6074 +monster.speed = 190 +monster.manaCost = 500 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Troooooot!", yell = false}, + {text = "Hooooot-Toooooot!", yell = false}, + {text = "Tooooot.", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 90000, maxCount = 40}, + {name = "meat", chance = 39000}, + {name = "ham", chance = 30000, maxCount = 3}, + {name = "tusk shield", chance = 500}, + {name = "mammoth whopper", chance = 2800}, + {name = "furry club", chance = 500}, + {name = "thick fur", chance = 7280}, + {name = "mammoth tusk", chance = 7500, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -110} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 15}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/merlkin.lua b/data/monster/mammals/merlkin.lua new file mode 100644 index 00000000000..991d429a8be --- /dev/null +++ b/data/monster/mammals/merlkin.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Merlkin") +local monster = {} + +monster.description = "a merlkin" +monster.experience = 145 +monster.outfit = { + lookType = 117, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 117 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Banuta, north-east of Port Hope." + } + +monster.health = 235 +monster.maxHealth = 235 +monster.race = "blood" +monster.corpse = 6044 +monster.speed = 194 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 70, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ugh! Ugh! Ugh!", yell = false}, + {text = "Holy banana!", yell = false}, + {text = "Chakka! Chakka!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 69500, maxCount = 45}, + {name = "small amethyst", chance = 260}, + {id = 2162, chance = 3000}, + {name = "wand of decay", chance = 1050}, + {name = "orange", chance = 1000, maxCount = 5}, + {name = "banana", chance = 30350, maxCount = 12}, + {name = "banana staff", chance = 100}, + {name = "ape fur", chance = 1000}, + {name = "mana potion", chance = 660}, + {name = "banana sash", chance = 1800} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -30}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -60, maxDamage = -90, range = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -15, maxDamage = -45, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="poisonfield", interval = 2000, chance = 15, range = 7, radius = 1, shootEffect = CONST_ANI_POISON, target = true} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 30, maxDamage = 40, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -15}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/modified_gnarlhound.lua b/data/monster/mammals/modified_gnarlhound.lua new file mode 100644 index 00000000000..7e0307c8b10 --- /dev/null +++ b/data/monster/mammals/modified_gnarlhound.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("Modified Gnarlhound") +local monster = {} + +monster.description = "a modified gnarlhound" +monster.experience = 0 +monster.outfit = { + lookType = 515, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 877 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 25, + FirstUnlock = 5, + SecondUnlock = 10, + CharmsPoints = 1, + Stars = 0, + Occurrence = 1, + Locations = "South of Stonehome, deep under Telas's house." + } + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "blood" +monster.corpse = 13528 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 25, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/mole.lua b/data/monster/mammals/mole.lua new file mode 100644 index 00000000000..d48609b2500 --- /dev/null +++ b/data/monster/mammals/mole.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Mole") +local monster = {} + +monster.description = "a mole" +monster.experience = 100 +monster.outfit = { + lookType = 1048, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1570 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Warzone 4 and Warzone 6." + } + +monster.health = 200 +monster.maxHealth = 200 +monster.race = "blood" +monster.corpse = 32012 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 10000, maxCount = 78} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/mushroom_sniffer.lua b/data/monster/mammals/mushroom_sniffer.lua new file mode 100644 index 00000000000..f09d3461bd7 --- /dev/null +++ b/data/monster/mammals/mushroom_sniffer.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Mushroom Sniffer") +local monster = {} + +monster.description = "a mushroom sniffer" +monster.experience = 0 +monster.outfit = { + lookType = 60, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 870 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 25, + FirstUnlock = 5, + SecondUnlock = 10, + CharmsPoints = 1, + Stars = 0, + Occurrence = 0, + Locations = "Truffels Garden." + } + +monster.health = 250 +monster.maxHealth = 250 +monster.race = "blood" +monster.corpse = 2935 +monster.speed = 110 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 25, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Sniff", yell = false}, + {text = "Oink", yell = false}, + {text = "Oink oink", yell = false} +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 90}, + {type = COMBAT_ENERGYDAMAGE, percent = 90}, + {type = COMBAT_EARTHDAMAGE, percent = 90}, + {type = COMBAT_FIREDAMAGE, percent = 90}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 90}, + {type = COMBAT_HOLYDAMAGE , percent = 90}, + {type = COMBAT_DEATHDAMAGE , percent = 90} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/mutated_bat.lua b/data/monster/mammals/mutated_bat.lua new file mode 100644 index 00000000000..066327055d0 --- /dev/null +++ b/data/monster/mammals/mutated_bat.lua @@ -0,0 +1,134 @@ +local mType = Game.createMonsterType("Mutated Bat") +local monster = {} + +monster.description = "a mutated bat" +monster.experience = 615 +monster.outfit = { + lookType = 307, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 509 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Cemetery Quarter (around 10 underground on the west side along with banshees, \z + and 4 bats on the church roof), Alchemist Quarter (4 found on top of roofs), \z + Arena and Zoo Quarter (2 under the arena with other mutated creatures), \z + Razzachai, Northern Zao Plantations, Souleater Mountains, Middle Spike, Vengoth and Vengoth Castle." + } + +monster.health = 900 +monster.maxHealth = 900 +monster.race = "blood" +monster.corpse = 9829 +monster.speed = 186 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Shriiiiiek", yell = false} +} + +monster.loot = { + {name = "black pearl", chance = 720, maxCount = 3}, + {name = "gold coin", chance = 53000, maxCount = 50}, + {name = "gold coin", chance = 40000, maxCount = 70}, + {name = "small amethyst", chance = 500, maxCount = 2}, + {name = "energy ring", chance = 990}, + {name = "battle shield", chance = 7760}, + {name = "black shield", chance = 70}, + {name = "star herb", chance = 7260}, + {name = "star herb", chance = 5060}, + {name = "bat wing", chance = 4900, maxCount = 2}, + {name = "mercenary sword", chance = 110}, + {id = 9808, chance = 12530}, + {id = 9809, chance = 12530, maxCount = 2}, + {name = "batwing hat", chance = 80}, + {name = "mutated bat ear", chance = 4900} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -168, condition = {type = CONDITION_POISON, totalDamage = 120, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -70, maxDamage = -180, range = 7, shootEffect = CONST_ANI_POISON, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DROWNDAMAGE, minDamage = -30, maxDamage = -90, radius = 6, effect = CONST_ME_SOUND_WHITE, target = false}, + {name ="mutated bat curse", interval = 2000, chance = 10, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -190, maxDamage = -240, length = 4, spread = 3, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 80, maxDamage = 95, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/mutated_rat.lua b/data/monster/mammals/mutated_rat.lua new file mode 100644 index 00000000000..7d41e957dc9 --- /dev/null +++ b/data/monster/mammals/mutated_rat.lua @@ -0,0 +1,134 @@ +local mType = Game.createMonsterType("Mutated Rat") +local monster = {} + +monster.description = "a mutated rat" +monster.experience = 450 +monster.outfit = { + lookType = 305, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 502 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Alchemist Quarter, Arena and Zoo Quarter (Inside the arena with other mutated creatures), \z + Razzachai, Vampire Castle on Vengoth, Robson's Isle, Mushroom Gardens, Souleater Mountains, \z + Northern Zao Plantations, Middle Spike." + } + +monster.health = 550 +monster.maxHealth = 550 +monster.race = "blood" +monster.corpse = 9871 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grrrrrrrrrrrrrr!", yell = false}, + {text = "Fcccccchhhhhh", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 38000, maxCount = 65}, + {name = "gold coin", chance = 40000, maxCount = 65}, + {name = "stealth ring", chance = 540}, + {id = 2229, chance = 20240}, + {name = "mouldy cheese", chance = 950}, + {name = "halberd", chance = 2990}, + {name = "plate shield", chance = 3750}, + {name = "tower shield", chance = 50}, + {name = "green mushroom", chance = 1390}, + {name = "stone herb", chance = 4920}, + {name = "health potion", chance = 560}, + {name = "spellbook of enlightenment", chance = 300}, + {name = "mutated rat tail", chance = 3800} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -158, condition = {type = CONDITION_POISON, totalDamage = 100, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -45, maxDamage = -85, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -80, maxDamage = -100, length = 5, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = -600, range = 7, effect = CONST_ME_MAGIC_RED, target = true, duration = 30000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -30, maxDamage = -70, range = 7, radius = 3, effect = CONST_ME_MAGIC_RED, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, range = 7, radius = 3, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 80, maxDamage = 95, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/mutated_tiger.lua b/data/monster/mammals/mutated_tiger.lua new file mode 100644 index 00000000000..91f213a2e29 --- /dev/null +++ b/data/monster/mammals/mutated_tiger.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Mutated Tiger") +local monster = {} + +monster.description = "a mutated tiger" +monster.experience = 750 +monster.outfit = { + lookType = 318, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 516 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Alchemist Quarter, Arena and Zoo Quarter (Inside with other mutated creatures), \z + Muggy Plains, Souleater Mountains and Northern Zao Plantations." + } + +monster.health = 1100 +monster.maxHealth = 1100 +monster.race = "blood" +monster.corpse = 9913 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 100, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "GRAAARRRRRR", yell = false}, + {text = "CHHHHHHHHHHH", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 5}, + {name = "life ring", chance = 5580}, + {name = "guardian shield", chance = 380}, + {name = "meat", chance = 29500, maxCount = 2}, + {name = "angelic axe", chance = 440}, + {name = "glorious axe", chance = 870}, + {name = "strong health potion", chance = 6000}, + {name = "silky tapestry", chance = 730}, + {name = "striped fur", chance = 20130}, + {name = "sabretooth", chance = 10600} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, length = 5, spread = 3, effect = CONST_ME_BLOCKHIT, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_MAGIC_BLUE}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 150, maxDamage = 300, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/noble_lion.lua b/data/monster/mammals/noble_lion.lua new file mode 100644 index 00000000000..4291ed85f3f --- /dev/null +++ b/data/monster/mammals/noble_lion.lua @@ -0,0 +1,118 @@ +local mType = Game.createMonsterType("Noble Lion") +local monster = {} + +monster.description = "a noble lion" +monster.experience = 400 +monster.outfit = { + lookType = 570, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1118 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "Lion's Rock temple." + } + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "blood" +monster.corpse = 24232 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Groarrrr! Rwarrrr", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 68}, + {id = 2666, chance = 25000}, + {id = 2671, chance = 25000}, + {id = 10608, chance = 20000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 70, attack = 40} +} + +monster.defenses = { + defense = 26, + armor = 26, + {name ="speed", interval = 2000, chance = 15, speedChange = 250, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 25}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 25}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/panda.lua b/data/monster/mammals/panda.lua new file mode 100644 index 00000000000..5f3516aae95 --- /dev/null +++ b/data/monster/mammals/panda.lua @@ -0,0 +1,114 @@ +local mType = Game.createMonsterType("Panda") +local monster = {} + +monster.description = "a panda" +monster.experience = 23 +monster.outfit = { + lookType = 123, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 123 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "South of Port Hope around Trapwood, as well as a lone specimen in the Arena Quarter." + } + +monster.health = 80 +monster.maxHealth = 80 +monster.race = "blood" +monster.corpse = 6049 +monster.speed = 156 +monster.manaCost = 300 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grrrr", yell = false}, + {text = "Groar", yell = false} +} + +monster.loot = { + {name = "meat", chance = 70500, maxCount = 4}, + {name = "ham", chance = 39000, maxCount = 2}, + {name = "bamboo stick", chance = 10000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -20} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/pig.lua b/data/monster/mammals/pig.lua new file mode 100644 index 00000000000..698eee08c47 --- /dev/null +++ b/data/monster/mammals/pig.lua @@ -0,0 +1,111 @@ +local mType = Game.createMonsterType("Pig") +local monster = {} + +monster.description = "a pig" +monster.experience = 0 +monster.outfit = { + lookType = 60, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 60 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Rookgaard, Orc Fort, under Femor Hills with Goblins, some farms like The McRonald's Farm, \z + Liberty Bay slums and Nargor, Foreigner Quarter in Yalahar, Isle of the Kings, \z + cells in Tafariel's throneroom in Pits of Inferno, Gardens of Night." + } + +monster.health = 25 +monster.maxHealth = 25 +monster.race = "blood" +monster.corpse = 6000 +monster.speed = 114 +monster.manaCost = 255 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = false, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 25, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Oink oink", yell = false}, + {text = "Oink", yell = false} +} + +monster.loot = { + {name = "meat", chance = 64000, maxCount = 4}, + {name = "pig foot", chance = 950} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/polar_bear.lua b/data/monster/mammals/polar_bear.lua new file mode 100644 index 00000000000..21eaf989a69 --- /dev/null +++ b/data/monster/mammals/polar_bear.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Polar Bear") +local monster = {} + +monster.description = "a polar bear" +monster.experience = 28 +monster.outfit = { + lookType = 42, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 42 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Ice Islands." + } + +monster.health = 85 +monster.maxHealth = 85 +monster.race = "blood" +monster.corpse = 5987 +monster.speed = 156 +monster.manaCost = 315 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 5, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "GROARRR!", yell = true} +} + +monster.loot = { + {name = "meat", chance = 50500, maxCount = 4}, + {name = "ham", chance = 50320, maxCount = 2}, + {name = "polar bear paw", chance = 980} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -30} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 1}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/poodle.lua b/data/monster/mammals/poodle.lua new file mode 100644 index 00000000000..2b8a3658746 --- /dev/null +++ b/data/monster/mammals/poodle.lua @@ -0,0 +1,93 @@ +local mType = Game.createMonsterType("Poodle") +local monster = {} + +monster.description = "a poodle" +monster.experience = 0 +monster.outfit = { + lookType = 473, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 20 +monster.maxHealth = 20 +monster.race = "blood" +monster.corpse = 5971 +monster.speed = 200 +monster.manaCost = 220 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = false, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 8, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Wuff wuff", yell = false} +} + +monster.loot = { +} + +monster.defenses = { + defense = 2, + armor = 1 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/rabbit.lua b/data/monster/mammals/rabbit.lua new file mode 100644 index 00000000000..506d2e15b7f --- /dev/null +++ b/data/monster/mammals/rabbit.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Rabbit") +local monster = {} + +monster.description = "a rabbit" +monster.experience = 0 +monster.outfit = { + lookType = 74, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 74 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "In most grass areas of Tibia, for example on Tutorial Island." + } + +monster.health = 15 +monster.maxHealth = 15 +monster.race = "blood" +monster.corpse = 6017 +monster.speed = 180 +monster.manaCost = 220 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = false, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "meat", chance = 85620, maxCount = 2}, + {id = 2684, chance = 10000, maxCount = 2} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/rat.lua b/data/monster/mammals/rat.lua new file mode 100644 index 00000000000..09e6f80c8bf --- /dev/null +++ b/data/monster/mammals/rat.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Rat") +local monster = {} + +monster.description = "a rat" +monster.experience = 5 +monster.outfit = { + lookType = 21, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 21 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Rookgaard and Mainland, in most sewers and caves near towns. \z + They can be found almost everywhere in Tibia." + } + +monster.health = 20 +monster.maxHealth = 20 +monster.race = "blood" +monster.corpse = 5964 +monster.speed = 134 +monster.manaCost = 200 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 5, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Meep!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 4}, + {id = 2696, chance = 39410} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -10} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 25}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/roaring_lion.lua b/data/monster/mammals/roaring_lion.lua new file mode 100644 index 00000000000..712b6cbe028 --- /dev/null +++ b/data/monster/mammals/roaring_lion.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Roaring Lion") +local monster = {} + +monster.description = "a roaring lion" +monster.experience = 800 +monster.outfit = { + lookType = 570, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 981 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Lion's Rock a few floors down." + } + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "blood" +monster.corpse = 21420 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Groarrrr! Rwarrrr!", yell = false}, + {text = "Growl!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 114}, + {id = 2666, chance = 25000}, + {id = 2671, chance = 25000}, + {id = 10608, chance = 16666}, + {id = 2152, chance = 10000}, + {id = 2147, chance = 7692}, + {id = 2150, chance = 7142}, + {id = 9970, chance = 6666}, + {id = 2146, chance = 5555}, + {id = 2193, chance = 1612}, + {id = 2164, chance = 1204}, + {id = 2491, chance = 1010} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 60, attack = 40} +} + +monster.defenses = { + defense = 28, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 25}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/sheep.lua b/data/monster/mammals/sheep.lua new file mode 100644 index 00000000000..0f69b5c22c6 --- /dev/null +++ b/data/monster/mammals/sheep.lua @@ -0,0 +1,114 @@ +local mType = Game.createMonsterType("Sheep") +local monster = {} + +monster.description = "a sheep" +monster.experience = 0 +monster.outfit = { + lookType = 14, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 14 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "In Rookgaard Sheep field, Greenshore and other farms like the one in Thais, east of Carlin. \z + They can also be found wandering the fields of Edron, and some can be found along with a \z + Black Sheep with the Hunter in Femur Hills." + } + +monster.health = 20 +monster.maxHealth = 20 +monster.race = "blood" +monster.corpse = 5991 +monster.speed = 116 +monster.manaCost = 250 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = false, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Maeh", yell = false} +} + +monster.loot = { + {name = "meat", chance = 70000, maxCount = 4}, + {name = "wool", chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/sibang.lua b/data/monster/mammals/sibang.lua new file mode 100644 index 00000000000..c2918b53d5c --- /dev/null +++ b/data/monster/mammals/sibang.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Sibang") +local monster = {} + +monster.description = "a sibang" +monster.experience = 105 +monster.outfit = { + lookType = 118, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 118 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "In Banuta, north-east of Port Hope." + } + +monster.health = 225 +monster.maxHealth = 225 +monster.race = "blood" +monster.corpse = 6045 +monster.speed = 214 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 70, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Eeeeek! Eeeeek!", yell = false}, + {text = "Huh! Huh! Huh!", yell = false}, + {text = "Ahhuuaaa!", yell = false} +} + +monster.loot = { + {name = "small stone", chance = 30060, maxCount = 3}, + {name = "gold coin", chance = 56000, maxCount = 35}, + {name = "orange", chance = 19840, maxCount = 5}, + {name = "banana", chance = 30000, maxCount = 12}, + {name = "coconut", chance = 1960, maxCount = 3}, + {name = "melon", chance = 1000}, + {name = "ape fur", chance = 1000}, + {name = "banana sash", chance = 5000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -40}, + {name ="combat", interval = 2000, chance = 35, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -55, range = 7, shootEffect = CONST_ANI_SMALLSTONE, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="speed", interval = 2000, chance = 15, speedChange = 380, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 25}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -15}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/silver_rabbit.lua b/data/monster/mammals/silver_rabbit.lua new file mode 100644 index 00000000000..61a0d3fc6c8 --- /dev/null +++ b/data/monster/mammals/silver_rabbit.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Silver Rabbit") +local monster = {} + +monster.description = "a silver rabbit" +monster.experience = 0 +monster.outfit = { + lookType = 262, + lookHead = 69, + lookBody = 66, + lookLegs = 69, + lookFeet = 66, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 327 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "A lot of places on the Ice Islands and one on Rookgaard (unreachable)." + } + +monster.health = 15 +monster.maxHealth = 15 +monster.race = "blood" +monster.corpse = 7338 +monster.speed = 184 +monster.manaCost = 220 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "meat", chance = 86170, maxCount = 2}, + {id = 2684, chance = 11150}, + {name = "silky fur", chance = 28670} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/skunk.lua b/data/monster/mammals/skunk.lua new file mode 100644 index 00000000000..94abaf48c0f --- /dev/null +++ b/data/monster/mammals/skunk.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Skunk") +local monster = {} + +monster.description = "a skunk" +monster.experience = 3 +monster.outfit = { + lookType = 106, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 106 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Unannounced raid in Edron outside the depot, Tiquanda, Shattered Isles, \z + Liberty Bay, south gate of Thais." + } + +monster.health = 20 +monster.maxHealth = 20 +monster.race = "blood" +monster.corpse = 6035 +monster.speed = 120 +monster.manaCost = 200 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 8, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "bulb of garlic", chance = 4910}, + {name = "skunk tail", chance = 920} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -5}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -1, maxDamage = -3, range = 1, target = true} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/squirrel.lua b/data/monster/mammals/squirrel.lua new file mode 100644 index 00000000000..33016de938c --- /dev/null +++ b/data/monster/mammals/squirrel.lua @@ -0,0 +1,110 @@ +local mType = Game.createMonsterType("Squirrel") +local monster = {} + +monster.description = "a squirrel" +monster.experience = 0 +monster.outfit = { + lookType = 274, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 384 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "North of Carlin, Northwest of Thais, East of Kazordoon, Yalahar, Dawnport, \z + Edron Hunters Camp, Plains of Havoc and other Tibian woods." + } + +monster.health = 20 +monster.maxHealth = 20 +monster.race = "blood" +monster.corpse = 7628 +monster.speed = 480 +monster.manaCost = 220 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = false, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Chchch", yell = false} +} + +monster.loot = { + {name = "walnut", chance = 1140}, + {name = "peanut", chance = 980}, + {name = "acorn", chance = 50410} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/starving_wolf.lua b/data/monster/mammals/starving_wolf.lua new file mode 100644 index 00000000000..10edf29a06e --- /dev/null +++ b/data/monster/mammals/starving_wolf.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("starving wolf") +local monster = {} + +monster.description = "a starving wolf" +monster.experience = 65 +monster.outfit = { + lookType = 27, + lookHead = 20, + lookBody = 30, + lookLegs = 40, + lookFeet = 50, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 723 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 2, + Locations = "East, west and south-west of the Femor Hills." + } + +monster.health = 85 +monster.maxHealth = 85 +monster.race = "blood" +monster.corpse = 5968 +monster.speed = 188 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 8, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Gaarrrrrr", yell = false}, + {text = "Gnoorrr", yell = false}, + {text = "Yoooohhuuuu!", yell = false} +} + +monster.loot = { + {id = 220, chance = 64730}, + {name = "meat", chance = 5300, maxCount = 2}, + {name = "wolf paw", chance = 1430} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -25} +} + +monster.defenses = { + defense = 10, + armor = 10, + {name ="effect", interval = 2000, chance = 10, radius = 1, effect = CONST_ME_YELLOW_RINGS, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -30}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/stone_rhino.lua b/data/monster/mammals/stone_rhino.lua new file mode 100644 index 00000000000..b2d4310c198 --- /dev/null +++ b/data/monster/mammals/stone_rhino.lua @@ -0,0 +1,118 @@ +local mType = Game.createMonsterType("Stone Rhino") +local monster = {} + +monster.description = "a Stone Rhino" +monster.experience = 1800 +monster.outfit = { + lookType = 936, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1395 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "Area before final boss of Forgotten Knowledge Quest." + } + +monster.health = 3000 +monster.maxHealth = 3000 +monster.race = "blood" +monster.corpse = 27750 +monster.speed = 290 +monster.manaCost = 290 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "SNIFF!", yell = false} +} + +monster.loot = { + {id = 5925, chance = 50320}, + {id = 27056, chance = 50320}, + {id = 27057, chance = 50320}, + {id = 24842, chance = 50320} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -280} +} + +monster.defenses = { + defense = 10, + armor = 10, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 0, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/terrified_elephant.lua b/data/monster/mammals/terrified_elephant.lua new file mode 100644 index 00000000000..77d6062a229 --- /dev/null +++ b/data/monster/mammals/terrified_elephant.lua @@ -0,0 +1,104 @@ +local mType = Game.createMonsterType("Terrified Elephant") +local monster = {} + +monster.description = "a terrified elephant" +monster.experience = 160 +monster.outfit = { + lookType = 211, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 320 +monster.maxHealth = 320 +monster.race = "blood" +monster.corpse = 6052 +monster.speed = 220 +monster.manaCost = 500 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hooooot-Toooooot!", yell = false}, + {text = "Tooooot!", yell = false}, + {text = "Trooooot!", yell = false} +} + +monster.loot = { + {name = "meat", chance = 40000, maxCount = 4}, + {name = "ham", chance = 27000, maxCount = 9}, + {name = "tusk", chance = 8510, maxCount = 2}, + {name = "tusk shield", chance = 80} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100} +} + +monster.defenses = { + defense = 0, + armor = 0, + {name ="speed", interval = 2000, chance = 15, speedChange = 800, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 25}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/thieving_squirrel.lua b/data/monster/mammals/thieving_squirrel.lua new file mode 100644 index 00000000000..e019263c227 --- /dev/null +++ b/data/monster/mammals/thieving_squirrel.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Thieving Squirrel") +local monster = {} + +monster.description = "a thieving squirrel" +monster.experience = 15 +monster.outfit = { + lookType = 274, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 55 +monster.maxHealth = 55 +monster.race = "blood" +monster.corpse = 7628 +monster.speed = 1000 +monster.manaCost = 220 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = false, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 55, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Chchch", yell = false} +} + +monster.loot = { + {id = 11100, chance = 100000}, + {id = 7910, chance = 4550} +} + +monster.attacks = { +} + +monster.defenses = { + defense = 5, + armor = 5, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/thornfire_wolf.lua b/data/monster/mammals/thornfire_wolf.lua new file mode 100644 index 00000000000..52a35854aa7 --- /dev/null +++ b/data/monster/mammals/thornfire_wolf.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Thornfire Wolf") +local monster = {} + +monster.description = "a thornfire wolf" +monster.experience = 200 +monster.outfit = { + lookType = 414, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 739 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 50, + Stars = 3, + Occurrence = 3, + Locations = "Shadowthorn." + } + +monster.health = 600 +monster.maxHealth = 600 +monster.race = "venom" +monster.corpse = 13859 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hfffff!", yell = true}, + {text = "Rrrrrr!", yell = true}, + {text = "Graaawwwr!", yell = true} +} + +monster.loot = { + {name = "gold coin", chance = 64000, maxCount = 53}, + {name = "meat", chance = 34000}, + {name = "wolf paw", chance = 7900}, + {name = "flaming arrow", chance = 15000, maxCount = 8}, + {name = "fiery heart", chance = 7900} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -68}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -35, maxDamage = -70, range = 1, shootEffect = CONST_ANI_WHIRLWINDSWORD, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -30, maxDamage = -70, range = 7, radius = 2, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_EXPLOSIONHIT, target = true}, + {name ="firefield", interval = 2000, chance = 10, range = 7, radius = 2, target = true} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_HEALING, minDamage = 100, maxDamage = 220, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 1}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/tiger.lua b/data/monster/mammals/tiger.lua new file mode 100644 index 00000000000..64503f71393 --- /dev/null +++ b/data/monster/mammals/tiger.lua @@ -0,0 +1,114 @@ +local mType = Game.createMonsterType("Tiger") +local monster = {} + +monster.description = "a tiger" +monster.experience = 40 +monster.outfit = { + lookType = 125, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 125 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Tiquanda, Meriana, Arena and Zoo Quarter. Three unreachable ones are found in the Rookgaard Academy, \z + below Ankrahmun (during the Nomads Land Quest), and on Charles's ship." + } + +monster.health = 75 +monster.maxHealth = 75 +monster.race = "blood" +monster.corpse = 6051 +monster.speed = 200 +monster.manaCost = 420 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "meat", chance = 35190, maxCount = 4}, + {name = "striped fur", chance = 10830} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -40} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="speed", interval = 2000, chance = 15, speedChange = 200, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -1}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/vampire_pig.lua b/data/monster/mammals/vampire_pig.lua new file mode 100644 index 00000000000..ac14193c380 --- /dev/null +++ b/data/monster/mammals/vampire_pig.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("Vampire Pig") +local monster = {} + +monster.description = "a vampire pig" +monster.experience = 165 +monster.outfit = { + lookType = 60, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 558 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "Isle of Evil on the surface." + } + +monster.health = 305 +monster.maxHealth = 305 +monster.race = "blood" +monster.corpse = 6000 +monster.speed = 110 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 30, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Oink", yell = false}, + {text = "Oink oink", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 90000, maxCount = 40} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_LIFEDRAIN, minDamage = -15, maxDamage = -25, radius = 4, effect = CONST_ME_BATS, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -35, maxDamage = -55, range = 3, target = true} +} + +monster.defenses = { + defense = 35, + armor = 30, + {name ="outfit", interval = 2000, chance = 20, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 1500, outfitMonster = "mutated bat"} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/vulcongra.lua b/data/monster/mammals/vulcongra.lua new file mode 100644 index 00000000000..a299c818caf --- /dev/null +++ b/data/monster/mammals/vulcongra.lua @@ -0,0 +1,135 @@ +local mType = Game.createMonsterType("Vulcongra") +local monster = {} + +monster.description = "a vulcongra" +monster.experience = 1100 +monster.outfit = { + lookType = 509, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 898 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Hot Spot (in Gnomebase Alpha) and Lower Spike." + } + +monster.health = 1600 +monster.maxHealth = 1600 +monster.race = "fire" +monster.corpse = 18476 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 220, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Fuchah! Fuchah!", yell = false}, + {text = "Fuchah!", yell = false}, + {text = "Yag! Yag! Yag!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 7}, + {name = "platinum coin", chance = 14780}, + {name = "wand of inferno", chance = 1000}, + {name = "sword ring", chance = 2920}, + {name = "fire sword", chance = 260}, + {name = "banana", chance = 10420, maxCount = 10}, + {name = "strong health potion", chance = 7100}, + {name = "strong mana potion", chance = 7100}, + {name = "magma amulet", chance = 970}, + {name = "magma coat", chance = 140}, + {name = "fiery heart", chance = 9380}, + {id = 13757, chance = 940}, + {name = "brown crystal splinter", chance = 4850}, + {name = "red crystal fragment", chance = 2280}, + {name = "magma clump", chance = 12440}, + {name = "blazing bone", chance = 8030} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -235}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -195, maxDamage = -340, length = 8, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -200, range = 7, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="vulcongra soulfire", interval = 3000, chance = 100, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/war_wolf.lua b/data/monster/mammals/war_wolf.lua new file mode 100644 index 00000000000..e92953c1c63 --- /dev/null +++ b/data/monster/mammals/war_wolf.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("War Wolf") +local monster = {} + +monster.description = "a war wolf" +monster.experience = 55 +monster.outfit = { + lookType = 3, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 3 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Orc Fort, the Orc Peninsula, Magician Tower and northwest (tower) or south \z + (underground) of Thais, Zao steppe (encaged), Vengoth." + } + +monster.health = 140 +monster.maxHealth = 140 +monster.race = "blood" +monster.corpse = 6009 +monster.speed = 264 +monster.manaCost = 420 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grrrrrrr", yell = false}, + {text = "Yoooohhuuuu!", yell = true} +} + +monster.loot = { + {name = "ham", chance = 35000, maxCount = 2}, + {name = "wolf paw", chance = 710}, + {name = "warwolf fur", chance = 5230} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -50} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = true}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/water_buffalo.lua b/data/monster/mammals/water_buffalo.lua new file mode 100644 index 00000000000..4fb556568fd --- /dev/null +++ b/data/monster/mammals/water_buffalo.lua @@ -0,0 +1,117 @@ +local mType = Game.createMonsterType("Water Buffalo") +local monster = {} + +monster.description = "a water buffalo" +monster.experience = 20 +monster.outfit = { + lookType = 523, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 872 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 30, + Stars = 2, + Occurrence = 3, + Locations = "It raids every four hours, starting at server save, in groups of one to three at \z + various places around Venore swamp, especially near the southern production site." + } + +monster.health = 390 +monster.maxHealth = 390 +monster.race = "blood" +monster.corpse = 19701 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Gnorrr!", yell = false}, + {text = "Gnarrr!", yell = false}, + {text = "", yell = false}, + {text = "Mrrr!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 20}, + {name = "meat", chance = 33600, maxCount = 4}, + {name = "ham", chance = 39200, maxCount = 3} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -30} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/white_deer.lua b/data/monster/mammals/white_deer.lua new file mode 100644 index 00000000000..d373b8caa88 --- /dev/null +++ b/data/monster/mammals/white_deer.lua @@ -0,0 +1,114 @@ +local mType = Game.createMonsterType("White Deer") +local monster = {} + +monster.description = "a white deer" +monster.experience = 0 +monster.outfit = { + lookType = 400, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 720 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 2, + Locations = "Around Ab'Dendriel, Carlin (east from Lothar), Femor Hills and Ferngrims Gate, usually in pairs. \z + They will appear when they're not overhunted." + } + +monster.health = 195 +monster.maxHealth = 195 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 208 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 195, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "WhiteDeerDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "*wheeze*", yell = false}, + {text = "ROOOAAARR!!", yell = false}, + {text = "*sniff*", yell = false}, + {text = "*bell*", yell = false} +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/white_lion.lua b/data/monster/mammals/white_lion.lua new file mode 100644 index 00000000000..5e85ff4d04a --- /dev/null +++ b/data/monster/mammals/white_lion.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("White Lion") +local monster = {} + +monster.description = "a white lion" +monster.experience = 2300 +monster.outfit = { + lookType = 1290, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2700 +monster.maxHealth = 2700 +monster.race = "blood" +monster.corpse = 39080 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 15 +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 5, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 1, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 100000, maxCount = 5}, + {name = "Great Spirit Potion", chance = 5000, maxCount = 2}, + {name = "Lion's Mane", chance = 5000}, + {name = "Green Crystal Shard", chance = 5000, maxCount = 2}, + {name = "Cyan Crystal Fragment", chance = 1500}, + {name = "Green Crystal Fragment", chance = 1500}, + {name = "Terra Boots", chance = 5000}, + {name = "Axe", chance = 5000}, + {name = "Leather Boots", chance = 5000}, + {name = "Twin Hooks", chance = 5000}, + {name = "War Hammer", chance = 1500}, + {name = "Combat Knife", chance = 1500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 0, minDamage = 0, maxDamage = -300}, + {name ="combat", interval = 2000, chance = 0, type = COMBAT_HOLYDAMAGE, minDamage = -300, maxDamage = -400, range = 1, effect = CONST_ME_HOLYAREA, target = false}, + {name ="combat", interval = 2000, chance = 0, type = COMBAT_HOLYDAMAGE, minDamage = -250, maxDamage = -350, range = 1, radius = 2, effect = CONST_ME_HOLYAREA, target = false}, + {name ="combat", interval = 2000, chance = 100, type = COMBAT_PHYSICALDAMAGE, minDamage = -250, maxDamage = -350, range = 1, radius = 2, effect = CONST_ME_EXPLOSIONAREA, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 100, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 30}, + {type = COMBAT_FIREDAMAGE, percent = 25}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -25}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 40} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/wild_dog.lua b/data/monster/mammals/wild_dog.lua new file mode 100644 index 00000000000..9d92032113f --- /dev/null +++ b/data/monster/mammals/wild_dog.lua @@ -0,0 +1,97 @@ +local mType = Game.createMonsterType("Wild Dog") +local monster = {} + +monster.description = "a wild dog" +monster.experience = 0 +monster.outfit = { + lookType = 32, + lookHead = 20, + lookBody = 30, + lookLegs = 40, + lookFeet = 50, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 20 +monster.maxHealth = 20 +monster.race = "blood" +monster.corpse = 5971 +monster.speed = 200 +monster.manaCost = 220 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Wuff wuff", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = 0} +} + +monster.defenses = { + defense = 2, + armor = 1 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/wild_horse.lua b/data/monster/mammals/wild_horse.lua new file mode 100644 index 00000000000..1a80b5fcbe4 --- /dev/null +++ b/data/monster/mammals/wild_horse.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Wild Horse") +local monster = {} + +monster.description = "a wild horse" +monster.experience = 0 +monster.outfit = { + lookType = 393, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 730 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 10, + Stars = 1, + Occurrence = 3, + Locations = "Near the Thais Troll Cave entrance during the Horse Station World Change." + } + +monster.health = 75 +monster.maxHealth = 75 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 248 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 75, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Weeeeheeeeeee", yell = false}, + {text = "*snort*", yell = false}, + {text = "*Weeeeheeeeaaa*", yell = false} +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/winter_wolf.lua b/data/monster/mammals/winter_wolf.lua new file mode 100644 index 00000000000..04ea4be0230 --- /dev/null +++ b/data/monster/mammals/winter_wolf.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("Winter Wolf") +local monster = {} + +monster.description = "a winter wolf" +monster.experience = 20 +monster.outfit = { + lookType = 52, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 52 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Ice Islands." + } + +monster.health = 30 +monster.maxHealth = 30 +monster.race = "blood" +monster.corpse = 5997 +monster.speed = 170 +monster.manaCost = 260 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Yoooohhuuuu!", yell = false} +} + +monster.loot = { + {name = "meat", chance = 30000, maxCount = 2}, + {name = "winter wolf fur", chance = 10000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -20} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 5}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/wolf.lua b/data/monster/mammals/wolf.lua new file mode 100644 index 00000000000..1daed626194 --- /dev/null +++ b/data/monster/mammals/wolf.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Wolf") +local monster = {} + +monster.description = "a wolf" +monster.experience = 18 +monster.outfit = { + lookType = 27, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 27 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "In almost all grass areas in Tibia, also found in Rookgaard and Dawnport." + } + +monster.health = 25 +monster.maxHealth = 25 +monster.race = "blood" +monster.corpse = 5968 +monster.speed = 164 +monster.manaCost = 255 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 8, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Yoooohhuuuu!", yell = false}, + {text = "Grrrrrrr", yell = false} +} + +monster.loot = { + {name = "meat", chance = 55000, maxCount = 2}, + {name = "wolf paw", chance = 980} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -20} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 5}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 5}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/mammals/yeti.lua b/data/monster/mammals/yeti.lua new file mode 100644 index 00000000000..425db29ae3c --- /dev/null +++ b/data/monster/mammals/yeti.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Yeti") +local monster = {} + +monster.description = "a yeti" +monster.experience = 460 +monster.outfit = { + lookType = 110, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 110 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 50, + Stars = 3, + Occurrence = 3, + Locations = "Folda, Chyllfroest, Isle of Merriment." + } + +monster.health = 950 +monster.maxHealth = 950 +monster.race = "blood" +monster.corpse = 6038 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Yooodelaaahooohooo", yell = false}, + {text = "Yooodelaaaheehee", yell = false} +} + +monster.loot = { + {name = "snowball", chance = 10000, maxCount = 22}, + {name = "gold coin", chance = 100000, maxCount = 60}, + {name = "gold coin", chance = 100000, maxCount = 40}, + {name = "bunnyslippers", chance = 1333}, + {name = "meat", chance = 33333, maxCount = 4}, + {name = "ham", chance = 10000, maxCount = 5} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -1}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/nostalgia/old_bear.lua b/data/monster/nostalgia/old_bear.lua new file mode 100644 index 00000000000..c64b348c249 --- /dev/null +++ b/data/monster/nostalgia/old_bear.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Old Bear") +local monster = {} + +monster.name = "Bear" +monster.description = "a bear" +monster.experience = 23 +monster.outfit = { + lookType = 919, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 80 +monster.maxHealth = 80 +monster.race = "blood" +monster.corpse = 5975 +monster.speed = 156 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grrrr", yell = false}, + {text = "Groar", yell = false} +} + +monster.loot = { + {name = "meat", chance = 39750, maxCount = 5}, + {name = "ham", chance = 20000, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -25} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/nostalgia/old_bonelord.lua b/data/monster/nostalgia/old_bonelord.lua new file mode 100644 index 00000000000..2c72f2318c7 --- /dev/null +++ b/data/monster/nostalgia/old_bonelord.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("Old Beholder") +local monster = {} + +monster.name = "Beholder" +monster.description = "a beholder" +monster.experience = 170 +monster.outfit = { + lookType = 924, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 260 +monster.maxHealth = 260 +monster.race = "venom" +monster.corpse = 5992 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 6 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Skeleton", chance = 20, interval = 2000, max = 6} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Olho por Olho!", yell = false}, + {text = "Estou olhando para voce!", yell = false}, + {text = "Deixe-me dar uma olhada em voce!", yell = false}, + {text = "Voce tem o olhar!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 65000, maxCount = 82}, + {id = 2175, chance = 4650}, + {name = "two handed sword", chance = 3840}, + {name = "morning star", chance = 6950}, + {name = "longsword", chance = 8980}, + {name = "steel shield", chance = 4001}, + {name = "bonelord eye", chance = 940} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -5}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_ENERGYDAMAGE, minDamage = -15, maxDamage = -45, range = 7, shootEffect = CONST_ANI_ENERGY, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_FIREDAMAGE, minDamage = -25, maxDamage = -45, range = 7, shootEffect = CONST_ANI_FIRE, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_DEATHDAMAGE, minDamage = -30, maxDamage = -50, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_EARTHDAMAGE, minDamage = -5, maxDamage = -45, range = 7, shootEffect = CONST_ANI_POISON, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_DEATHDAMAGE, minDamage = -5, maxDamage = -50, range = 7, shootEffect = CONST_ANI_DEATH, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -45, range = 7, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_MANADRAIN, minDamage = -5, maxDamage = -35, range = 7, target = false} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/nostalgia/old_bug.lua b/data/monster/nostalgia/old_bug.lua new file mode 100644 index 00000000000..1951105a61d --- /dev/null +++ b/data/monster/nostalgia/old_bug.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Old Bug") +local monster = {} + +monster.name = "Bug" +monster.description = "a bug" +monster.experience = 18 +monster.outfit = { + lookType = 920, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 29 +monster.maxHealth = 29 +monster.race = "venom" +monster.corpse = 5990 +monster.speed = 160 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 51170, maxCount = 6}, + {name = "cherry", chance = 2590, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -23} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/nostalgia/old_giant_spider.lua b/data/monster/nostalgia/old_giant_spider.lua new file mode 100644 index 00000000000..8d994dc9386 --- /dev/null +++ b/data/monster/nostalgia/old_giant_spider.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("Old Giant Spider") +local monster = {} + +monster.name = "Giant Spider" +monster.description = "a giant spider" +monster.experience = 900 +monster.outfit = { + lookType = 910, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1300 +monster.maxHealth = 1300 +monster.race = "venom" +monster.corpse = 5977 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 85}, + {id = 2545, chance = 11900, maxCount = 11}, + {id = 2647, chance = 7933}, + {id = 2463, chance = 10010}, + {id = 2457, chance = 4945}, + {id = 7588, chance = 3571}, + {id = 2477, chance = 850}, + {id = 2171, chance = 280}, + {id = 2476, chance = 500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300, condition = {type = CONDITION_POISON, totalDamage = 160, interval = 4000}}, + {name ="poisonfield", interval = 2000, chance = 10, range = 7, radius = 1, shootEffect = CONST_ANI_POISON, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -40, maxDamage = -70, range = 7, radius = 1, shootEffect = CONST_ANI_POISON, target = true} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="speed", interval = 2000, chance = 15, speedChange = 390, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/nostalgia/old_pig.lua b/data/monster/nostalgia/old_pig.lua new file mode 100644 index 00000000000..4fa7e8f727a --- /dev/null +++ b/data/monster/nostalgia/old_pig.lua @@ -0,0 +1,97 @@ +local mType = Game.createMonsterType("Old Pig") +local monster = {} + +monster.name = "Pig" +monster.description = "a pig" +monster.experience = 0 +monster.outfit = { + lookType = 921, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 25 +monster.maxHealth = 25 +monster.race = "blood" +monster.corpse = 6000 +monster.speed = 114 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 25, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Oink oink", yell = false}, + {text = "Oink", yell = false} +} + +monster.loot = { + {name = "meat", chance = 64000, maxCount = 4}, + {name = "pig foot", chance = 950} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/nostalgia/old_spider.lua b/data/monster/nostalgia/old_spider.lua new file mode 100644 index 00000000000..38e1f6c5d10 --- /dev/null +++ b/data/monster/nostalgia/old_spider.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Old Spider") +local monster = {} + +monster.name = "Spider" +monster.description = "a spider" +monster.experience = 12 +monster.outfit = { + lookType = 922, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 20 +monster.maxHealth = 20 +monster.race = "venom" +monster.corpse = 5961 +monster.speed = 152 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 6, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 65150, maxCount = 5}, + {name = "spider fangs", chance = 960} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -9} +} + +monster.defenses = { + defense = 2, + armor = 2 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/nostalgia/old_wasp.lua b/data/monster/nostalgia/old_wasp.lua new file mode 100644 index 00000000000..ce6015c096a --- /dev/null +++ b/data/monster/nostalgia/old_wasp.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Old Wasp") +local monster = {} + +monster.name = "Wasp" +monster.description = "a wasp" +monster.experience = 24 +monster.outfit = { + lookType = 923, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 35 +monster.maxHealth = 35 +monster.race = "venom" +monster.corpse = 5989 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Bssssss", yell = false} +} + +monster.loot = { + {name = "honeycomb", chance = 3000} +} + +monster.attacks = { + {name ="melee", interval = 1500, chance = 100, minDamage = 0, maxDamage = -20, condition = {type = CONDITION_POISON, totalDamage = 20, interval = 4000}} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/nostalgia/old_wolf.lua b/data/monster/nostalgia/old_wolf.lua new file mode 100644 index 00000000000..f469b6b0fe2 --- /dev/null +++ b/data/monster/nostalgia/old_wolf.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Old Wolf") +local monster = {} + +monster.name = "Wolf" +monster.description = "a wolf" +monster.experience = 18 +monster.outfit = { + lookType = 918, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 25 +monster.maxHealth = 25 +monster.race = "blood" +monster.corpse = 5968 +monster.speed = 164 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 8, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Yoooohhuuuu!", yell = false}, + {text = "Grrrrrrr", yell = false} +} + +monster.loot = { + {name = "meat", chance = 55000, maxCount = 4} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -20} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 5}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 5}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/plants/bane_bringer.lua b/data/monster/plants/bane_bringer.lua new file mode 100644 index 00000000000..83d75e6f648 --- /dev/null +++ b/data/monster/plants/bane_bringer.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Bane Bringer") +local monster = {} + +monster.description = "a bane bringer" +monster.experience = 400 +monster.outfit = { + lookType = 310, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 679 +monster.Bestiary = { + class = "Plant", + race = BESTY_RACE_PLANT, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 50, + Stars = 3, + Occurrence = 3, + Locations = "Green Claw Swamp underground, near the big witches' cauldron." + } + +monster.health = 2500 +monster.maxHealth = 2500 +monster.race = "venom" +monster.corpse = 9867 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You shall not succeed!", yell = false}, + {text = "This time we will prevail!", yell = false} +} + +monster.loot = { + {id = 2250, chance = 15220, maxCount = 96}, + {name = "dry piece of wood", chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150} +} + +monster.defenses = { + defense = 0, + armor = 17 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 90}, + {type = COMBAT_EARTHDAMAGE, percent = 90}, + {type = COMBAT_FIREDAMAGE, percent = 90}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 90}, + {type = COMBAT_HOLYDAMAGE , percent = 90}, + {type = COMBAT_DEATHDAMAGE , percent = 90} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/plants/branchy_crawler.lua b/data/monster/plants/branchy_crawler.lua new file mode 100644 index 00000000000..9635201a5d1 --- /dev/null +++ b/data/monster/plants/branchy_crawler.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Branchy Crawler") +local monster = {} + +monster.description = "a branchy crawler" +monster.experience = 23400 +monster.outfit = { + lookType = 1297, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1931 +monster.Bestiary = { + class = "Plant", + race = BESTY_RACE_PLANT, + toKill = 5000, + FirstUnlock = 25, + SecondUnlock = 2500, + CharmsPoints = 100, + Stars = 5, + Occurrence = 0, + Locations = "Rotten Wasteland." + } + +monster.health = 27000 +monster.maxHealth = 27000 +monster.race = "blood" +monster.corpse = 38644 +monster.speed = 235 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Bones are just sticks. They break easily.", yell = false}, + {text = "Decay!", yell = false}, + {text = "I'll make you crawl, too!", yell = false} +} + +monster.loot = { + {name = "crystal coin", chance = 70540}, + {name = "ultimate health potion", chance = 32220, maxCount = 9}, + {name = "gold ingot", chance = 65560}, + {name = "terra legs", chance = 25560}, + {name = "violet gem", chance = 60000}, + {id = 38817, chance = 35560}, -- Crawler's essence + {name = "green gem", chance = 70000}, + {name = "blue gem", chance = 55000}, + {name = "hammer of wrath", chance = 13500}, + {name = "ruthless axe", chance = 17500}, + {name = "nightmare blade", chance = 9500}, + {name = "twiceslicer", chance = 7500}, + {name = "crystal crossbow", chance = 6500}, + {name = "crystalline sword", chance = 7500}, + {id = 38944, chance = 50} -- Bag you desire +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -900}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HOLYDAMAGE, minDamage = -450, maxDamage = -900, range = 7, shootEffect = CONST_ANI_SMALLHOLY, effect = CONST_ME_HOLYAREA, target = true}, + {name ="combat", interval = 2000, chance = 22, type = COMBAT_EARTHDAMAGE, minDamage = -450, maxDamage = -900, radius = 4, effect = CONST_ME_SMALLPLANTS, target = true}, + {name ="combat", interval = 2000, chance = 22, type = COMBAT_PHYSICALDAMAGE, minDamage = -450, maxDamage = -1000, radius = 4, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 2000, chance = 22, type = COMBAT_HOLYDAMAGE, minDamage = -450, maxDamage = -1000, radius = 4, effect = CONST_ME_HOLYDAMAGE, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -400, maxDamage = -600, range = 7, shootEffect = CONST_ANI_PIERCINGBOLT, effect = CONST_ME_GREEN_RINGS, target = true}, + {name ="root", interval = 2000, chance = 10, target = true} +} + +monster.defenses = { + defense = 90, + armor = 105 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = -9}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 40}, + {type = COMBAT_DEATHDAMAGE , percent = -15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) \ No newline at end of file diff --git a/data/monster/plants/carniphila.lua b/data/monster/plants/carniphila.lua new file mode 100644 index 00000000000..fe8b1111442 --- /dev/null +++ b/data/monster/plants/carniphila.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Carniphila") +local monster = {} + +monster.description = "a carniphila" +monster.experience = 150 +monster.outfit = { + lookType = 120, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 120 +monster.Bestiary = { + class = "Plant", + race = BESTY_RACE_PLANT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Deep inside the Tiquanda Jungle including Tiquanda Laboratory and a small cave, \z + Forbidden Lands, Deeper Banuta, Arena and Zoo quarter in Yalahar." + } + +monster.health = 255 +monster.maxHealth = 255 +monster.race = "venom" +monster.corpse = 6047 +monster.speed = 110 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 60000, maxCount = 40}, + {name = "corncob", chance = 890}, + {name = "dark mushroom", chance = 7692}, + {name = "sling herb", chance = 446, maxCount = 2}, + {name = "shadow herb", chance = 880}, + {name = "seeds", chance = 490}, + {name = "carniphila seeds", chance = 4166}, + {name = "carrot on a stick", chance = 170} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100, condition = {type = CONDITION_POISON, totalDamage = 100, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -60, maxDamage = -95, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -800, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_GREEN_RINGS, target = false, duration = 30000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -40, maxDamage = -130, radius = 3, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 35}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/plants/cloak_of_terror.lua b/data/monster/plants/cloak_of_terror.lua new file mode 100644 index 00000000000..92072e68983 --- /dev/null +++ b/data/monster/plants/cloak_of_terror.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Cloak Of Terror") +local monster = {} + +monster.description = "a cloak of terror" +monster.experience = 24960 +monster.outfit = { + lookType = 1295, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1928 +monster.Bestiary = { + class = "Plant", + race = BESTY_RACE_PLANT, + toKill = 5000, + FirstUnlock = 25, + SecondUnlock = 2500, + CharmsPoints = 100, + Stars = 5, + Occurrence = 0, + Locations = "Furious Crater." + } + +monster.health = 28000 +monster.maxHealth = 28000 +monster.race = "undead" +monster.corpse = 38636 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Power up!", yell = false}, + {text = "Shocked to meet you.", yell = false}, + {text = "You should be more positive!", yell = false} +} + +monster.loot = { + {name = "crystal coin", chance = 70540}, + {name = "ultimate health potion", chance = 32220, maxCount = 7}, + {name = "wand of starstorm", chance = 74560}, + {id = 38769, chance = 55400}, -- Telescope eye + {name = "violet gem", chance = 74560}, + {name = "lightning headband", chance = 11920}, + {name = "green gem", chance = 64560}, + {name = "blue gem", chance = 54560}, + {name = "wand of inferno", chance = 11920}, + {name = "wand of voodoo", chance = 21920}, + {name = "wand of defiance", chance = 10000, maxCount = 3}, + {id = 38770, chance = 4500}, -- Crown + {id = 38858, chance = 850}, -- Brooch of embracement + {id = 38944, chance = 50} -- Bag you desire +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -800}, + {name ="combat", interval = 4000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -800, maxDamage = -1300, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -400, maxDamage = -750, radius = 4, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_HOLYDAMAGE, minDamage = -600, maxDamage = -1000, range = 7, shootEffect = CONST_ANI_SPECTRALBOLT, effect = CONST_ME_HOLYDAMAGE, target = true}, + {name ="combat", interval = 2000, chance = 24, type = COMBAT_HOLYDAMAGE, minDamage = -600, maxDamage = -1000, range = 7, radius = 3, shootEffect = CONST_ANI_SMALLHOLY, effect = CONST_ME_GROUNDSHAKER, target = true} +} + +monster.defenses = { + defense = 90, + armor = 107 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 60}, + {type = COMBAT_EARTHDAMAGE, percent = -5}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 40}, + {type = COMBAT_DEATHDAMAGE , percent = -20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) \ No newline at end of file diff --git a/data/monster/plants/glooth_anemone.lua b/data/monster/plants/glooth_anemone.lua new file mode 100644 index 00000000000..ed7ae09415c --- /dev/null +++ b/data/monster/plants/glooth_anemone.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Glooth Anemone") +local monster = {} + +monster.description = "a glooth anemone" +monster.experience = 1755 +monster.outfit = { + lookType = 604, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1042 +monster.Bestiary = { + class = "Plant", + race = BESTY_RACE_PLANT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Rathleton Sewers, Underground Glooth Factory, Jaccus Maxxen's Dungeon." + } + +monster.health = 2400 +monster.maxHealth = 2400 +monster.race = "venom" +monster.corpse = 23359 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 3 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "*shglib*", yell = false} +} + +monster.loot = { + {id = 23515, chance = 3190}, + {id = 23568, chance = 2020}, + {id = 2796, chance = 3180}, + {id = 23554, chance = 320}, + {id = 2148, chance = 100000, maxCount = 170}, + {id = 7588, chance = 6690, maxCount = 2}, + {id = 7589, chance = 6690, maxCount = 2}, + {id = 8473, chance = 960}, + {id = 2152, chance = 57320, maxCount = 3}, + {id = 9970, chance = 1240, maxCount = 3}, + {id = 2149, chance = 1600, maxCount = 3}, + {id = 2147, chance = 1150, maxCount = 3}, + {id = 23535, chance = 140}, + {id = 23543, chance = 700}, + {id = 23550, chance = 120}, + {id = 23549, chance = 370}, + {id = 23551, chance = 240}, + {id = 23529, chance = 370} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 60, attack = 50}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_EARTHDAMAGE, minDamage = -100, maxDamage = -200, range = 7, radius = 4, shootEffect = CONST_ANI_GLOOTHSPEAR, effect = CONST_ME_HITBYPOISON, target = true}, + {name ="combat", interval = 2000, chance = 7, type = COMBAT_LIFEDRAIN, minDamage = -50, maxDamage = -100, range = 7, radius = 1, shootEffect = CONST_ANI_POISON, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, radius = 5, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 25, + armor = 15, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_HEALING, minDamage = 50, maxDamage = 100, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="glooth anemone summon", interval = 2000, chance = 14, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/plants/haunted_treeling.lua b/data/monster/plants/haunted_treeling.lua new file mode 100644 index 00000000000..e34ed7425bf --- /dev/null +++ b/data/monster/plants/haunted_treeling.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Haunted Treeling") +local monster = {} + +monster.description = "a haunted treeling" +monster.experience = 310 +monster.outfit = { + lookType = 310, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 511 +monster.Bestiary = { + class = "Plant", + race = BESTY_RACE_PLANT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Vengoth surface, Vengoth Castle (Boreth's tower), Northern Zao Plantations, Tiquanda Laboratory, \z + Dryad Gardens." + } + +monster.health = 450 +monster.maxHealth = 450 +monster.race = "undead" +monster.corpse = 9867 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Knarrrz", yell = false}, + {text = "Huuhuuhuuuhuuaarrr", yell = false}, + {text = "Knorrrrrr", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 91920, maxCount = 95}, + {id = 4860, chance = 29190}, + {name = "red mushroom", chance = 7700}, + {name = "health potion", chance = 5130}, + {name = "white mushroom", chance = 5030, maxCount = 2}, + {name = "haunted piece of wood", chance = 4950}, + {name = "orange mushroom", chance = 1800}, + {name = "strong health potion", chance = 1040}, + {name = "dwarven ring", chance = 660}, + {name = "small emerald", chance = 620}, + {name = "bullseye potion", chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_MANADRAIN, minDamage = -30, maxDamage = -100, radius = 4, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -700, length = 5, spread = 3, effect = CONST_ME_SMALLPLANTS, target = false, duration = 15000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -100, range = 7, radius = 1, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_CARNIPHILA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -55, maxDamage = -100, radius = 4, effect = CONST_ME_HITBYPOISON, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, radius = 1, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 0, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = 1} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/plants/hideous_fungus.lua b/data/monster/plants/hideous_fungus.lua new file mode 100644 index 00000000000..f410e780f63 --- /dev/null +++ b/data/monster/plants/hideous_fungus.lua @@ -0,0 +1,145 @@ +local mType = Game.createMonsterType("Hideous Fungus") +local monster = {} + +monster.description = "a hideous fungus" +monster.experience = 2900 +monster.outfit = { + lookType = 499, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 891 +monster.Bestiary = { + class = "Plant", + race = BESTY_RACE_PLANT, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Warzone 1, Rathleton Sewers, unreachable location in Tiquanda Laboratory." + } + +monster.health = 4600 +monster.maxHealth = 4600 +monster.race = "venom" +monster.corpse = 17428 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 275, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "humorless fungus", chance = 10, interval = 2000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Munch munch munch!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 197}, + {name = "platinum coin", chance = 100000, maxCount = 7}, + {name = "war hammer", chance = 4010}, + {name = "white piece of cloth", chance = 6430}, + {name = "green piece of cloth", chance = 3003}, + {name = "red piece of cloth", chance = 1820}, + {name = "blue piece of cloth", chance = 3700}, + {name = "great mana potion", chance = 7692}, + {name = "great health potion", chance = 7220}, + {name = "mana potion", chance = 9090}, + {name = "terra mantle", chance = 800}, + {name = "terra legs", chance = 920}, + {name = "terra boots", chance = 2000}, + {name = "terra amulet", chance = 2000}, + {name = "mushroom backpack", chance = 20}, + {name = "mushroom pie", chance = 14500, maxCount = 3}, + {name = "muck rod", chance = 590}, + {name = "hideous chunk", chance = 14285}, + {name = "envenomed arrow", chance = 14500, maxCount = 15}, + {name = "mycological bow", chance = 60} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -250, maxDamage = -430, range = 7, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_SMALLPLANTS, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -250, maxDamage = -550, length = 8, spread = 3, shootEffect = CONST_ANI_SNOWBALL, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = -600, radius = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 60000}, + {name ="drunk", interval = 2000, chance = 10, range = 7, radius = 5, shootEffect = CONST_ANI_SMALLSTONE, effect = CONST_ME_STUN, target = true, duration = 4000}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -400, maxDamage = -640, range = 7, radius = 3, effect = CONST_ME_HITBYPOISON, target = false} +} + +monster.defenses = { + defense = 0, + armor = 60, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 275, maxDamage = 350, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 5}, + {type = COMBAT_DEATHDAMAGE , percent = 1} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/plants/humongous_fungus.lua b/data/monster/plants/humongous_fungus.lua new file mode 100644 index 00000000000..90649d7b767 --- /dev/null +++ b/data/monster/plants/humongous_fungus.lua @@ -0,0 +1,144 @@ +local mType = Game.createMonsterType("Humongous Fungus") +local monster = {} + +monster.description = "a humongous fungus" +monster.experience = 2600 +monster.outfit = { + lookType = 488, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 881 +monster.Bestiary = { + class = "Plant", + race = BESTY_RACE_PLANT, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Warzone 1, Rathleton Sewers, unreachable location in Tiquanda Laboratory." + } + +monster.health = 3400 +monster.maxHealth = 3400 +monster.race = "blood" +monster.corpse = 18382 +monster.speed = 260 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Munch munch munch!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 200}, + {name = "platinum coin", chance = 999900, maxCount = 6}, + {name = "mushroom pie", chance = 17130, maxCount = 3}, + {name = "brown piece of cloth", chance = 15120}, + {name = "drill bolt", chance = 15120, maxCount = 15}, + {name = "humongous chunk", chance = 10470}, + {name = "white piece of cloth", chance = 10230}, + {name = "strong health potion", chance = 5040, maxCount = 2}, + {name = "great mana potion", chance = 4960, maxCount = 2}, + {name = "great health potion", chance = 4950, maxCount = 2}, + {name = "strong mana potion", chance = 4930, maxCount = 2}, + {name = "mana potion", chance = 4750, maxCount = 3}, + {name = "blue piece of cloth", chance = 4440}, + {name = "red piece of cloth", chance = 2670}, + {name = "terra amulet", chance = 2180}, + {name = "terra boots", chance = 1950}, + {name = "angelic axe", chance = 1420}, + {name = "terra legs", chance = 1160}, + {name = "terra mantle", chance = 870}, + {name = "muck rod", chance = 640}, + {name = "mushroom backpack", chance = 20}, + {name = "mycological bow", chance = 140} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -330}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -180, maxDamage = -350, range = 7, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_SMALLPLANTS, target = false}, + {name ="poisonfield", interval = 2000, chance = 20, radius = 4, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -500, maxDamage = -1000, length = 8, spread = 3, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -130, maxDamage = -260, length = 5, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -400, maxDamage = -640, range = 7, radius = 3, effect = CONST_ME_HITBYPOISON, target = false} +} + +monster.defenses = { + defense = 0, + armor = 70, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 225, maxDamage = 380, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 5}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/plants/leaf_golem.lua b/data/monster/plants/leaf_golem.lua new file mode 100644 index 00000000000..fbdbff7bf45 --- /dev/null +++ b/data/monster/plants/leaf_golem.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Leaf Golem") +local monster = {} + +monster.description = "a leaf golem" +monster.experience = 45 +monster.outfit = { + lookType = 567, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 979 +monster.Bestiary = { + class = "Plant", + race = BESTY_RACE_PLANT, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Leaf dungeon in Hellgate, Lair of the Treeling Witch, Forest Fury Camp and in the \z + Forest Fury version of the Forsaken Mine." + } + +monster.health = 90 +monster.maxHealth = 90 +monster.race = "undead" +monster.corpse = 21358 +monster.speed = 136 +monster.manaCost = 390 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "*crackle*", yell = false}, + {text = "*swwwwishhhh*", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 87460, maxCount = 27}, + {name = "fir cone", chance = 14930}, + {name = "dowser", chance = 12190}, + {name = "swampling club", chance = 5130}, + {name = "white mushroom", chance = 4920, maxCount = 3}, + {name = "small emerald", chance = 950} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -90}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -15, range = 7, shootEffect = CONST_ANI_SMALLSTONE, target = true}, + {name ="speed", interval = 2000, chance = 20, speedChange = -600, radius = 3, effect = CONST_ME_SMALLPLANTS, target = false, duration = 9000} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/plants/omnivora.lua b/data/monster/plants/omnivora.lua new file mode 100644 index 00000000000..c228200d0a2 --- /dev/null +++ b/data/monster/plants/omnivora.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Omnivora") +local monster = {} + +monster.description = "an omnivora" +monster.experience = 750 +monster.outfit = { + lookType = 717, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1141 +monster.Bestiary = { + class = "Plant", + race = BESTY_RACE_PLANT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Tiquanda Medusa Tower." + } + +monster.health = 1200 +monster.maxHealth = 1200 +monster.race = "blood" +monster.corpse = 24651 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 97000, maxCount = 242}, + {id = 2667, chance = 18200, maxCount = 2}, + {id = 18418, chance = 2000}, + {id = 18417, chance = 2000}, + {id = 18416, chance = 2210}, + {id = 2671, chance = 1200}, + {id = 2787, chance = 1900}, + {id = 2168, chance = 950}, + {id = 2409, chance = 780}, + {id = 7887, chance = 700}, + {id = 7886, chance = 560}, + {id = 2185, chance = 430}, + {id = 8900, chance = 320}, + {id = 13298, chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150}, + {name ="speed", interval = 4000, chance = 20, speedChange = -350, range = 7, shootEffect = CONST_ANI_POISON, target = true, duration = 12000}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -80, maxDamage = -100, range = 7, shootEffect = CONST_ANI_POISON, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -50, maxDamage = -100, length = 8, spread = 3, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 250, maxDamage = 400, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/plants/spit_nettle.lua b/data/monster/plants/spit_nettle.lua new file mode 100644 index 00000000000..d04a1f4f066 --- /dev/null +++ b/data/monster/plants/spit_nettle.lua @@ -0,0 +1,118 @@ +local mType = Game.createMonsterType("Spit Nettle") +local monster = {} + +monster.description = "a spit nettle" +monster.experience = 20 +monster.outfit = { + lookType = 221, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 221 +monster.Bestiary = { + class = "Plant", + race = BESTY_RACE_PLANT, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Tiquanda, Trapwood, the outskirts of Chor and Forbidden Lands, Alchemist Quarter in Yalahar, \z + Tiquanda Laboratory." + } + +monster.health = 150 +monster.maxHealth = 150 +monster.race = "venom" +monster.corpse = 6062 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 10750, maxCount = 5}, + {name = "shadow herb", chance = 11080}, + {name = "nettle spit", chance = 9620}, + {name = "sling herb", chance = 5680, maxCount = 2}, + {name = "nettle blossom", chance = 970} +} + +monster.attacks = { + {name ="combat", interval = 1000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -15, maxDamage = -40, range = 7, shootEffect = CONST_ANI_POISON, target = true}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -40, maxDamage = -100, range = 7, shootEffect = CONST_ANI_POISON, target = true} +} + +monster.defenses = { + defense = 0, + armor = 12, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 8, maxDamage = 16, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/plants/swampling.lua b/data/monster/plants/swampling.lua new file mode 100644 index 00000000000..0259001e895 --- /dev/null +++ b/data/monster/plants/swampling.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Swampling") +local monster = {} + +monster.description = "a swampling" +monster.experience = 45 +monster.outfit = { + lookType = 535, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 919 +monster.Bestiary = { + class = "Plant", + race = BESTY_RACE_PLANT, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Venore swamp area, Venore Salamander Cave, Tiquanda Laboratory." + } + +monster.health = 80 +monster.maxHealth = 80 +monster.race = "venom" +monster.corpse = 19902 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Gnark!", yell = false} +} + +monster.loot = { + {id = 2120, chance = 5080}, + {name = "gold coin", chance = 84900, maxCount = 12}, + {name = "white mushroom", chance = 10220, maxCount = 5}, + {name = "swampling club", chance = 7410}, + {name = "swampling moss", chance = 19900}, + {name = "piece of swampling wood", chance = 14870} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -80}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -2, maxDamage = -15, range = 7, shootEffect = CONST_ANI_POISON, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -300, length = 3, spread = 2, effect = CONST_ME_WATERSPLASH, target = false, duration = 5000} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/plants/wilting_leaf_golem.lua b/data/monster/plants/wilting_leaf_golem.lua new file mode 100644 index 00000000000..27f57ae7adc --- /dev/null +++ b/data/monster/plants/wilting_leaf_golem.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Wilting Leaf Golem") +local monster = {} + +monster.description = "a wilting leaf golem" +monster.experience = 145 +monster.outfit = { + lookType = 573, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 982 +monster.Bestiary = { + class = "Plant", + race = BESTY_RACE_PLANT, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Forest Fury Camp, Lair of the Treeling Witch and in the Forest Fury version of the Forsaken Mine." + } + +monster.health = 380 +monster.maxHealth = 380 +monster.race = "blood" +monster.corpse = 21434 +monster.speed = 148 +monster.manaCost = 390 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "*crackle*", yell = false}, + {text = "*swwwwishhhh*", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 97540, maxCount = 45}, + {name = "fir cone", chance = 14950}, + {name = "dowser", chance = 11880}, + {name = "small emerald", chance = 1050}, + {name = "white mushroom", chance = 5040, maxCount = 3}, + {name = "swampling club", chance = 4890} +} + +monster.attacks = { + {name ="melee", interval = 1500, chance = 100, minDamage = 0, maxDamage = -120, condition = {type = CONDITION_POISON, totalDamage = 300, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -50, range = 7, radius = 1, shootEffect = CONST_ANI_LARGEROCK, effect = CONST_ME_EXPLOSIONHIT, target = true}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -150, maxDamage = -200, radius = 4, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="speed", interval = 2000, chance = 20, speedChange = -600, radius = 3, effect = CONST_ME_MAGIC_RED, target = false, duration = 15000} +} + +monster.defenses = { + defense = 0, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ancient_tombs/ashmunrah.lua b/data/monster/quests/ancient_tombs/ashmunrah.lua new file mode 100644 index 00000000000..9b663c5a976 --- /dev/null +++ b/data/monster/quests/ancient_tombs/ashmunrah.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Ashmunrah") +local monster = {} + +monster.description = "Ashmunrah" +monster.experience = 3100 +monster.outfit = { + lookType = 87, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5000 +monster.maxHealth = 5000 +monster.race = "undead" +monster.corpse = 6031 +monster.speed = 430 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Ancient Scarab", chance = 100, interval = 1000, max = 2}, + {name = "Green Djinn", chance = 100, interval = 1000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "No mortal or undead will steal my secrets!", yell = false}, + {text = "Ahhhh all those long years.", yell = false}, + {text = "My traitorous son has thee.", yell = false}, + {text = "Come to me, my allys and underlings.", yell = false}, + {text = "I might be trapped but not without power", yell = false}, + {text = "Ages come, ages go. Ashmunrah remains.", yell = false}, + {text = "You will be history soon.", yell = false} +} + +monster.loot = { + {name = "silver brooch", chance = 7000}, + {name = "holy scarab", chance = 400}, + {name = "gold coin", chance = 50000, maxCount = 80}, + {name = "gold coin", chance = 50000, maxCount = 60}, + {name = "might ring", chance = 1000}, + {name = "crown armor", chance = 80000}, + {name = "great mana potion", chance = 1500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1000, condition = {type = CONDITION_POISON, totalDamage = 55, interval = 4000}}, + {name ="combat", interval = 3000, chance = 7, type = COMBAT_LIFEDRAIN, minDamage = -100, maxDamage = -700, range = 1, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_EARTHDAMAGE, minDamage = -100, maxDamage = -500, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 3000, chance = 12, type = COMBAT_PHYSICALDAMAGE, minDamage = -120, maxDamage = -750, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_MORTAREA, target = false}, + {name ="speed", interval = 3000, chance = 25, speedChange = -650, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 50000}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_LIFEDRAIN, minDamage = -50, maxDamage = -550, length = 8, spread = 3, effect = CONST_ME_YELLOW_RINGS, target = false} +} + +monster.defenses = { + defense = 30, + armor = 25, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_HEALING, minDamage = 200, maxDamage = 400, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 1000, chance = 7, effect = CONST_ME_MAGIC_BLUE}, + {name ="outfit", interval = 1000, chance = 3, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 6000, outfitMonster = "ancient scarab"} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -17}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ancient_tombs/dipthrah.lua b/data/monster/quests/ancient_tombs/dipthrah.lua new file mode 100644 index 00000000000..ab649bd9478 --- /dev/null +++ b/data/monster/quests/ancient_tombs/dipthrah.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Dipthrah") +local monster = {} + +monster.description = "Dipthrah" +monster.experience = 2900 +monster.outfit = { + lookType = 87, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 4200 +monster.maxHealth = 4200 +monster.race = "undead" +monster.corpse = 6031 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Priestess", chance = 15, interval = 2000, max = 3} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You can't escape death forever", yell = false}, + {text = "Come closer to learn the final lesson", yell = false}, + {text = "Undeath will shatter my shackles.", yell = false}, + {text = "You don't need this magic anymore.", yell = false} +} + +monster.loot = { + {name = "small sapphire", chance = 7000, maxCount = 3}, + {name = "gold coin", chance = 50000, maxCount = 80}, + {name = "gold coin", chance = 50000, maxCount = 80}, + {name = "blue gem", chance = 1500}, + {name = "energy ring", chance = 7000}, + {name = "mind stone", chance = 1500}, + {name = "ankh", chance = 500}, + {name = "ornamented ankh", chance = 100000}, + {name = "skull staff", chance = 500}, + {name = "pharaoh sword", chance = 300}, + {name = "great mana potion", chance = 7000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200, condition = {type = CONDITION_POISON, totalDamage = 65, interval = 4000}}, + {name ="combat", interval = 4000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -100, maxDamage = -800, range = 1, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_MANADRAIN, minDamage = -100, maxDamage = -500, range = 7, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="speed", interval = 1000, chance = 15, speedChange = -650, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 50000}, + {name ="drunk", interval = 1000, chance = 12, radius = 7, effect = CONST_ME_LOSEENERGY, target = false}, + {name ="melee", interval = 3000, chance = 34, minDamage = -50, maxDamage = -600} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_HEALING, minDamage = 100, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ancient_tombs/horestis.lua b/data/monster/quests/ancient_tombs/horestis.lua new file mode 100644 index 00000000000..c9a87b57490 --- /dev/null +++ b/data/monster/quests/ancient_tombs/horestis.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Horestis") +local monster = {} + +monster.description = "Horestis" +monster.experience = 3500 +monster.outfit = { + lookType = 88, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 6000 +monster.maxHealth = 6000 +monster.race = "undead" +monster.corpse = 6031 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Sandstone Scorpion", chance = 12, interval = 1000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I might be dead but I'm not gone!", yell = false} +} + +monster.loot = { + {id = 13498, chance = 100000}, + {id = 2148, chance = 95000, maxCount = 243}, + {id = 2152, chance = 36000, maxCount = 5}, + {id = 13472, chance = 17000}, + {id = 2159, chance = 14000, maxCount = 5}, + {id = 13739, chance = 12000}, + {id = 2134, chance = 12000}, + {id = 7590, chance = 10000, maxCount = 3}, + {id = 7591, chance = 5000, maxCount = 4}, + {id = 2446, chance = 5000}, + {id = 11207, chance = 2500}, + {id = 9811, chance = 2500}, + {id = 2447, chance = 2500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_DEATHDAMAGE, minDamage = -200, maxDamage = -750, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 3000, chance = 17, type = COMBAT_LIFEDRAIN, minDamage = -400, maxDamage = -500, length = 8, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="drunk", interval = 3000, chance = 11, radius = 6, effect = CONST_ME_POISONAREA, target = false, duration = 25000}, + {name ="speed", interval = 1000, chance = 25, speedChange = -350, length = 7, spread = 3, effect = CONST_ME_POISONAREA, target = false, duration = 30000}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 30, minDamage = -35, maxDamage = -35, radius = 5, target = false} +} + +monster.defenses = { + defense = 30, + armor = 25, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 200, maxDamage = 400, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ancient_tombs/mahrdis.lua b/data/monster/quests/ancient_tombs/mahrdis.lua new file mode 100644 index 00000000000..5f879f16c14 --- /dev/null +++ b/data/monster/quests/ancient_tombs/mahrdis.lua @@ -0,0 +1,127 @@ +local mType = Game.createMonsterType("Mahrdis") +local monster = {} + +monster.description = "Mahrdis" +monster.experience = 3050 +monster.outfit = { + lookType = 90, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3900 +monster.maxHealth = 3900 +monster.race = "undead" +monster.corpse = 6025 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 80, + health = 10, + damage = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Fire Elemental", chance = 30, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ashes to ashes!", yell = false}, + {text = "Fire, Fire!", yell = false}, + {text = "The eternal flame demands its due!", yell = false}, + {text = "This is why I'm hot.", yell = false}, + {text = "May my flames engulf you!", yell = false}, + {text = "Burnnnnnnnnn!", yell = false} +} + +monster.loot = { + {name = "holy falcon", chance = 500}, + {name = "small ruby", chance = 7000, maxCount = 3}, + {name = "gold coin", chance = 50000, maxCount = 80}, + {name = "gold coin", chance = 50000, maxCount = 70}, + {name = "gold coin", chance = 50000, maxCount = 64}, + {name = "red gem", chance = 1500}, + {name = "life ring", chance = 1500}, + {name = "burning heart", chance = 100000}, + {name = "fire axe", chance = 750}, + {name = "phoenix shield", chance = 300}, + {name = "great health potion", chance = 1500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400, condition = {type = CONDITION_POISON, totalDamage = 65, interval = 4000}}, + {name ="combat", interval = 1600, chance = 7, type = COMBAT_PHYSICALDAMAGE, minDamage = -60, maxDamage = -600, range = 1, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 1000, chance = 7, type = COMBAT_FIREDAMAGE, minDamage = -60, maxDamage = -600, range = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = false}, + {name ="speed", interval = 2000, chance = 13, speedChange = -850, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 50000}, + {name ="combat", interval = 2000, chance = 34, type = COMBAT_FIREDAMAGE, minDamage = -80, maxDamage = -800, radius = 3, effect = CONST_ME_EXPLOSIONAREA, target = false}, + {name ="firefield", interval = 1000, chance = 12, radius = 4, effect = CONST_ME_BLOCKHIT, target = false}, + -- fire + {name ="condition", type = CONDITION_FIRE, interval = 2000, chance = 13, minDamage = -50, maxDamage = -500, length = 8, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false} +} + +monster.defenses = { + defense = 30, + armor = 20, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_HEALING, minDamage = 20, maxDamage = 800, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 45}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -25}, + {type = COMBAT_HOLYDAMAGE , percent = -22}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ancient_tombs/morguthis.lua b/data/monster/quests/ancient_tombs/morguthis.lua new file mode 100644 index 00000000000..cfe357d157f --- /dev/null +++ b/data/monster/quests/ancient_tombs/morguthis.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Morguthis") +local monster = {} + +monster.description = "Morguthis" +monster.experience = 3000 +monster.outfit = { + lookType = 90, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 4800 +monster.maxHealth = 4800 +monster.race = "undead" +monster.corpse = 6025 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 80, + health = 10, + damage = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Hero", chance = 100, interval = 2000, max = 3} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Vengeance!", yell = false}, + {text = "You will make a fine trophy.", yell = false}, + {text = "Come and fight me, cowards!", yell = false}, + {text = "I am the supreme warrior!", yell = false}, + {text = "Let me hear the music of battle.", yell = false}, + {text = "Another one to bite the dust!", yell = false} +} + +monster.loot = { + {id = 2136, chance = 500}, + {name = "black pearl", chance = 7000}, + {name = "gold coin", chance = 50000, maxCount = 80}, + {name = "gold coin", chance = 50000, maxCount = 73}, + {name = "stone skin amulet", chance = 7000}, + {name = "sword hilt", chance = 100000}, + {name = "knight axe", chance = 7000}, + {name = "ravager's axe", chance = 300}, + {name = "steel boots", chance = 500}, + {name = "assassin star", chance = 500, maxCount = 3}, + {name = "great health potion", chance = 1500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1000, condition = {type = CONDITION_POISON, totalDamage = 65, interval = 4000}}, + {name ="combat", interval = 3000, chance = 7, type = COMBAT_LIFEDRAIN, minDamage = -55, maxDamage = -550, range = 1, target = false}, + {name ="speed", interval = 1000, chance = 25, speedChange = -650, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 50000}, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -40, maxDamage = -400, radius = 3, effect = CONST_ME_HITAREA, target = false}, + {name ="combat", interval = 3000, chance = 7, type = COMBAT_PHYSICALDAMAGE, minDamage = -50, maxDamage = -500, radius = 3, effect = CONST_ME_MORTAREA, target = false} +} + +monster.defenses = { + defense = 25, + armor = 35, + {name ="combat", interval = 1000, chance = 13, type = COMBAT_HEALING, minDamage = 200, maxDamage = 300, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 1000, chance = 7, speedChange = 1201, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000}, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 52}, + {type = COMBAT_EARTHDAMAGE, percent = -15}, + {type = COMBAT_FIREDAMAGE, percent = 60}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 62}, + {type = COMBAT_HOLYDAMAGE , percent = -22}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ancient_tombs/omruc.lua b/data/monster/quests/ancient_tombs/omruc.lua new file mode 100644 index 00000000000..02d9f189708 --- /dev/null +++ b/data/monster/quests/ancient_tombs/omruc.lua @@ -0,0 +1,127 @@ +local mType = Game.createMonsterType("Omruc") +local monster = {} + +monster.description = "Omruc" +monster.experience = 2950 +monster.outfit = { + lookType = 90, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 4300 +monster.maxHealth = 4300 +monster.race = "undead" +monster.corpse = 6025 +monster.speed = 370 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 20, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Stalker", chance = 100, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Now chhhou shhhee me ... Now chhhou don't.", yell = false}, + {text = "Chhhhou are marked ashhh my prey.", yell = false}, + {text = "Catchhhh me if chhhou can.", yell = false}, + {text = "Die!", yell = false}, + {text = "Psssst, I am over chhhere.", yell = false} +} + +monster.loot = { + {name = "small diamond", chance = 7000, maxCount = 3}, + {name = "gold coin", chance = 50000, maxCount = 90}, + {name = "gold coin", chance = 50000, maxCount = 70}, + {name = "yellow gem", chance = 5000}, + {name = "stealth ring", chance = 5000}, + {name = "boots of haste", chance = 1500}, + {name = "crystal arrow", chance = 100000}, + {name = "arrow", chance = 10000, maxCount = 21}, + {name = "poison arrow", chance = 10000, maxCount = 20}, + {name = "burst arrow", chance = 10000, maxCount = 15}, + {name = "power bolt", chance = 10000, maxCount = 3}, + {name = "onyx arrow", chance = 10000, maxCount = 2}, + {name = "great health potion", chance = 7000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -120, condition = {type = CONDITION_POISON, totalDamage = 65, interval = 4000}}, + {name ="combat", interval = 5000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -100, maxDamage = -250, range = 1, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -200, maxDamage = -500, shootEffect = CONST_ANI_POISONARROW, target = false}, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -120, maxDamage = -450, range = 3, shootEffect = CONST_ANI_BURSTARROW, effect = CONST_ME_EXPLOSIONAREA, target = false}, + {name ="melee", interval = 3000, chance = 20, minDamage = -150, maxDamage = -500}, + {name ="speed", interval = 1000, chance = 25, speedChange = -900, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 50000} +} + +monster.defenses = { + defense = 35, + armor = 20, + {name ="combat", interval = 1000, chance = 17, type = COMBAT_HEALING, minDamage = 100, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 14, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ancient_tombs/rahemos.lua b/data/monster/quests/ancient_tombs/rahemos.lua new file mode 100644 index 00000000000..8ca868639b6 --- /dev/null +++ b/data/monster/quests/ancient_tombs/rahemos.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Rahemos") +local monster = {} + +monster.description = "Rahemos" +monster.experience = 3100 +monster.outfit = { + lookType = 87, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3700 +monster.maxHealth = 3700 +monster.race = "undead" +monster.corpse = 6031 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 80, + health = 10, + damage = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Demon", chance = 12, interval = 1000, max = 1} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "It's a kind of magic.", yell = false}, + {text = "Abrah Kadabrah!", yell = false}, + {text = "Nothing hidden in my wrappings.", yell = false}, + {text = "It's not a trick, it's Rahemos.", yell = false}, + {text = "Meet my friend from hell!", yell = false}, + {text = "I will make you believe in magic.", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 90}, + {name = "gold coin", chance = 50000, maxCount = 80}, + {name = "gold coin", chance = 50000, maxCount = 60}, + {name = "small amethyst", chance = 7000, maxCount = 3}, + {name = "violet gem", chance = 500}, + {name = "orb", chance = 500}, + {name = "crystal wand", chance = 500}, + {name = "ring of healing", chance = 7000}, + {name = "ancient rune", chance = 100000}, + {name = "twin axe", chance = 200}, + {name = "magician hat", chance = 300}, + {name = "great mana potion", chance = 7000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -750, condition = {type = CONDITION_POISON, totalDamage = 65, interval = 4000}}, + {name ="combat", interval = 3000, chance = 7, type = COMBAT_LIFEDRAIN, minDamage = -75, maxDamage = -750, range = 1, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -60, maxDamage = -600, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -60, maxDamage = -600, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="speed", interval = 1000, chance = 12, speedChange = -650, radius = 6, effect = CONST_ME_POISONAREA, target = false, duration = 60000}, + {name ="drunk", interval = 1000, chance = 8, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="outfit", interval = 1000, chance = 15, range = 7, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 12000, outfitMonster = "pig"} +} + +monster.defenses = { + defense = 35, + armor = 30, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_HEALING, minDamage = 200, maxDamage = 500, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="outfit", interval = 1000, chance = 5, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 4000, outfitMonster = "demon"} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 92}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 94}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ancient_tombs/shredderthrower.lua b/data/monster/quests/ancient_tombs/shredderthrower.lua new file mode 100644 index 00000000000..ebdc56833b5 --- /dev/null +++ b/data/monster/quests/ancient_tombs/shredderthrower.lua @@ -0,0 +1,90 @@ +local mType = Game.createMonsterType("Shredderthrower") +local monster = {} + +monster.description = "a shredderthrower" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 1551 +} + +monster.health = 1 +monster.maxHealth = 1 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = true, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="combat", interval = 2000, chance = 100, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -110, range = 7, shootEffect = CONST_ANI_THROWINGSTAR, target = false} +} + +monster.defenses = { + defense = 1, + armor = 1 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ancient_tombs/thalas.lua b/data/monster/quests/ancient_tombs/thalas.lua new file mode 100644 index 00000000000..13b573b85fd --- /dev/null +++ b/data/monster/quests/ancient_tombs/thalas.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Thalas") +local monster = {} + +monster.description = "Thalas" +monster.experience = 2950 +monster.outfit = { + lookType = 90, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 4100 +monster.maxHealth = 4100 +monster.race = "undead" +monster.corpse = 6025 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 8 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 80, + health = 10, + damage = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Slime", chance = 100, interval = 2000, max = 8} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You will become a feast for my maggots!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 80}, + {name = "gold coin", chance = 50000, maxCount = 80}, + {name = "small emerald", chance = 7000, maxCount = 3}, + {name = "green gem", chance = 500}, + {name = "stealth ring", chance = 1500}, + {id = 2169, chance = 7000}, + {name = "cobrafang dagger", chance = 100000}, + {name = "serpent sword", chance = 500}, + {name = "poison dagger", chance = 7000}, + {name = "djinn blade", chance = 200}, + {name = "great health potion", chance = 1500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -900}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_EARTHDAMAGE, minDamage = -150, maxDamage = -650, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false}, + {name ="melee", interval = 3000, chance = 20, minDamage = -150, maxDamage = -650}, + {name ="speed", interval = 1000, chance = 6, speedChange = -800, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 1000, chance = 15, minDamage = -34, maxDamage = -35, radius = 5, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 3000, chance = 17, type = COMBAT_EARTHDAMAGE, minDamage = -55, maxDamage = -550, length = 8, spread = 3, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 30, + armor = 20, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_HEALING, minDamage = 150, maxDamage = 450, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -23}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ancient_tombs/vashresamun.lua b/data/monster/quests/ancient_tombs/vashresamun.lua new file mode 100644 index 00000000000..fb830cbdfae --- /dev/null +++ b/data/monster/quests/ancient_tombs/vashresamun.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Vashresamun") +local monster = {} + +monster.description = "Vashresamun" +monster.experience = 2950 +monster.outfit = { + lookType = 90, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 4000 +monster.maxHealth = 4000 +monster.race = "undead" +monster.corpse = 6025 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 80, + health = 10, + damage = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Banshee", chance = 20, interval = 2000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Come my maidens, we have visitors!", yell = false}, + {text = "Are you enjoying my music?", yell = false}, + {text = "If music is the food of death, drop dead.", yell = false}, + {text = "Chakka Chakka!", yell = false}, + {text = "Heheheheee!", yell = false} +} + +monster.loot = { + {id = 2072, chance = 7000}, + {id = 2074, chance = 1500}, + {id = 2124, chance = 1500}, + {name = "ancient tiara", chance = 300}, + {name = "white pearl", chance = 7000}, + {name = "gold coin", chance = 50000, maxCount = 90}, + {name = "gold coin", chance = 50000, maxCount = 80}, + {name = "gold coin", chance = 50000, maxCount = 65}, + {name = "blue note", chance = 100000}, + {name = "crystal mace", chance = 500}, + {name = "blue robe", chance = 2500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200, condition = {type = CONDITION_POISON, totalDamage = 65, interval = 4000}}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_LIFEDRAIN, minDamage = -200, maxDamage = -750, radius = 5, effect = CONST_ME_SOUND_PURPLE, target = false} +} + +monster.defenses = { + defense = 35, + armor = 20, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_HEALING, minDamage = 60, maxDamage = 450, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 1000, chance = 12, speedChange = 350, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 30000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/annihilator/angry_demon.lua b/data/monster/quests/annihilator/angry_demon.lua new file mode 100644 index 00000000000..8a7e7a32089 --- /dev/null +++ b/data/monster/quests/annihilator/angry_demon.lua @@ -0,0 +1,146 @@ +local mType = Game.createMonsterType("Angry Demon") +local monster = {} + +monster.description = "an angry demon" +monster.experience = 6000 +monster.outfit = { + lookType = 35, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 8200 +monster.maxHealth = 8200 +monster.race = "fire" +monster.corpse = 5995 +monster.speed = 256 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "fire elemental", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Your soul will be mine!", yell = false}, + {text = "MUHAHAHA", yell = false}, + {text = "CHAMEK ATH UTHUL ARAK!", yell = false}, + {text = "I SMELL FEEEEAAAAAR!", yell = false}, + {text = "Your resistance is futile!", yell = false} +} + +monster.loot = { + {name = "purple tome", chance = 1180}, + {name = "gold coin", chance = 60000, maxCount = 100}, + {name = "platinum coin", chance = 60000, maxCount = 6}, + {name = "small emerald", chance = 9690, maxCount = 5}, + {name = "small amethyst", chance = 7250, maxCount = 5}, + {name = "small ruby", chance = 7430, maxCount = 5}, + {name = "small topaz", chance = 7470, maxCount = 5}, + {name = "red gem", chance = 2220}, + {name = "demonic essence", chance = 14630}, + {name = "talon", chance = 3430}, + {name = "might ring", chance = 1890}, + {name = "stealth ring", chance = 2170}, + {name = "platinum amulet", chance = 680}, + {name = "orb", chance = 2854}, + {name = "gold ring", chance = 1050}, + {name = "ring of healing", chance = 1990}, + {name = "giant sword", chance = 1980}, + {name = "ice rapier", chance = 1550}, + {name = "golden sickle", chance = 1440}, + {name = "fire axe", chance = 4030}, + {name = "devil helmet", chance = 1180}, + {name = "golden legs", chance = 440}, + {name = "magic plate armor", chance = 130}, + {name = "mastermind shield", chance = 480}, + {name = "demon shield", chance = 740}, + {name = "fire mushroom", chance = 19660, maxCount = 6}, + {name = "demon horn", chance = 14920}, + {name = "assassin star", chance = 12550, maxCount = 10}, + {name = "demonrage sword", chance = 70}, + {id = 7393, chance = 90}, + {name = "great mana potion", chance = 22220, maxCount = 3}, + {name = "ultimate health potion", chance = 19540, maxCount = 3}, + {name = "great spirit potion", chance = 18510, maxCount = 3} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -520}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -120, range = 7, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -150, maxDamage = -250, range = 7, radius = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="firefield", interval = 2000, chance = 10, range = 7, radius = 1, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -300, maxDamage = -490, length = 8, spread = 3, effect = CONST_ME_PURPLEENERGY, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -210, maxDamage = -300, range = 1, shootEffect = CONST_ANI_ENERGY, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -700, radius = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 30000} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 180, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 320, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -25}, + {type = COMBAT_ENERGYDAMAGE, percent = -50}, + {type = COMBAT_EARTHDAMAGE, percent = -40}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 12}, + {type = COMBAT_HOLYDAMAGE , percent = 12}, + {type = COMBAT_DEATHDAMAGE , percent = -20} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/bigfoots_burden/bosses/abyssador.lua b/data/monster/quests/bigfoots_burden/bosses/abyssador.lua new file mode 100644 index 00000000000..32846eba7c4 --- /dev/null +++ b/data/monster/quests/bigfoots_burden/bosses/abyssador.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Abyssador") +local monster = {} + +monster.description = "Abyssador" +monster.experience = 50000 +monster.outfit = { + lookType = 495, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 340000 +monster.maxHealth = 340000 +monster.race = "blood" +monster.corpse = 17412 +monster.speed = 460 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "*** STEALTH ***", yell = false}, + {text = "*** TIME ***", yell = false}, + {text = "*** IMPORTANT ***", yell = false}, + {text = "*** BRAINS *** SMALL ***", yell = false}, + {text = "*** DEATH ***", yell = false}, + {text = "*** FIRE *** HOME *** VICTORY ***", yell = false}, + {text = "*** EXISTENCE *** FUTILE ***", yell = false} +} + +monster.loot = { + {id = 18496, chance = 100000}, + {id = 18453, chance = 8333}, + {id = 18451, chance = 7333}, + {id = 18465, chance = 5333}, + {id = 18450, chance = 6666}, + {id = 18454, chance = 6263}, + {id = 18449, chance = 2754}, + {id = 18452, chance = 2754} +} + +monster.attacks = { + {name ="melee", interval = 3000, chance = 100, skill = 300, attack = 150}, + -- energy damage + {name ="condition", type = CONDITION_ENERGY, interval = 1000, chance = 10, minDamage = -800, maxDamage = -800, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_SMALLPLANTS, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -500, maxDamage = -1600, radius = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="abyssador poison wave", interval = 1000, chance = 20, minDamage = -1000, maxDamage = -1800, target = false} +} + +monster.defenses = { + defense = 20, + armor = 15, + {name ="combat", interval = 1000, chance = 1, type = COMBAT_HEALING, minDamage = 0, maxDamage = 300000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 5000, chance = 30, type = COMBAT_HEALING, minDamage = 1000, maxDamage = 1000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 25, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/bigfoots_burden/bosses/deathstrike.lua b/data/monster/quests/bigfoots_burden/bosses/deathstrike.lua new file mode 100644 index 00000000000..75bffb66a18 --- /dev/null +++ b/data/monster/quests/bigfoots_burden/bosses/deathstrike.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("Deathstrike") +local monster = {} + +monster.description = "Deathstrike" +monster.experience = 40000 +monster.outfit = { + lookType = 500, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 200000 +monster.maxHealth = 200000 +monster.race = "blood" +monster.corpse = 18384 +monster.speed = 470 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 50, + targetDistance = 1, + runHealth = 2000, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Deeestructiooon!", yell = false}, + {text = "Maaahhhrrr!", yell = false}, + {text = "I am carnage incarnate!", yell = false}, + {text = "I've seen the light! And it was all engulfing fire!", yell = false}, + {text = "Taaake... this!", yell = false} +} + +monster.loot = { + {id = 18465, chance = 8430}, + {id = 18452, chance = 6570}, + {id = 18450, chance = 10480}, + {id = 18430, chance = 100000}, + {id = 18453, chance = 12380}, + {id = 18451, chance = 7430}, + {id = 18454, chance = 11430} +} + +monster.attacks = { + {name ="melee", interval = 1300, chance = 100, skill = 80, attack = 120}, + {name ="speed", interval = 2000, chance = 20, speedChange = -400, range = 7, shootEffect = CONST_ANI_WHIRLWINDAXE, target = false, duration = 2500}, + {name ="combat", interval = 2000, chance = 100, type = COMBAT_FIREDAMAGE, minDamage = -820, maxDamage = -950, range = 7, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = -350, maxDamage = -800, range = 3, effect = CONST_ME_PURPLEENERGY, target = true} +} + +monster.defenses = { + defense = 35, + armor = 25, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_HEALING, minDamage = 1000, maxDamage = 5500, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 40}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 40}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/bigfoots_burden/bosses/gnomevil.lua b/data/monster/quests/bigfoots_burden/bosses/gnomevil.lua new file mode 100644 index 00000000000..74516fe1774 --- /dev/null +++ b/data/monster/quests/bigfoots_burden/bosses/gnomevil.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("Gnomevil") +local monster = {} + +monster.description = "Gnomevil" +monster.experience = 45000 +monster.outfit = { + lookType = 504, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 250000 +monster.maxHealth = 250000 +monster.race = "blood" +monster.corpse = 18443 +monster.speed = 470 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 50, + targetDistance = 1, + runHealth = 10000, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "No more Mr. Nicegnome!", yell = false}, + {text = "Taste the power of the dark side!", yell = false}, + {text = "I've seen the light! And it was all engulfing fire!", yell = false} +} + +monster.loot = { + {id = 18451, chance = 7030}, + {id = 18453, chance = 9120}, + {id = 18495, chance = 99150}, + {id = 18465, chance = 6690}, + {id = 18454, chance = 8400}, + {id = 18452, chance = 7120}, + {id = 18450, chance = 14100}, + {id = 18449, chance = 3710} +} + +monster.attacks = { + {name ="melee", interval = 1300, chance = 100, skill = 80, attack = 140}, + {name ="speed", interval = 2000, chance = 20, speedChange = -400, range = 7, shootEffect = CONST_ANI_WHIRLWINDAXE, target = false, duration = 2500}, + {name ="combat", interval = 2000, chance = 100, type = COMBAT_FIREDAMAGE, minDamage = -820, maxDamage = -950, range = 7, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_MANADRAIN, minDamage = -230, maxDamage = -500, length = 8, spread = 3, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = -350, maxDamage = -800, range = 3, effect = CONST_ME_PURPLEENERGY, target = true} +} + +monster.defenses = { + defense = 35, + armor = 25, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_HEALING, minDamage = 1000, maxDamage = 4000, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/bigfoots_burden/humorless_fungus.lua b/data/monster/quests/bigfoots_burden/humorless_fungus.lua new file mode 100644 index 00000000000..5b1dba33506 --- /dev/null +++ b/data/monster/quests/bigfoots_burden/humorless_fungus.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Humorless Fungus") +local monster = {} + +monster.description = "a humorless fungus" +monster.experience = 0 +monster.outfit = { + lookType = 517, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2500 +monster.maxHealth = 2500 +monster.race = "venom" +monster.corpse = 17428 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Munch munch munch!", yell = false}, + {text = "Chatter", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -475}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -40, maxDamage = -197, range = 7, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_SMALLPLANTS, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = 0, maxDamage = -525, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_ICEAREA, target = true}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -400, maxDamage = -640, range = 7, radius = 3, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="drunk", interval = 2000, chance = 10, range = 7, radius = 4, effect = CONST_ME_STUN, target = true, duration = 4000} +} + +monster.defenses = { + defense = 0, + armor = 0, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 0, maxDamage = 230, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 5}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/bigfoots_burden/minion_of_versperoth.lua b/data/monster/quests/bigfoots_burden/minion_of_versperoth.lua new file mode 100644 index 00000000000..51b3453bd1a --- /dev/null +++ b/data/monster/quests/bigfoots_burden/minion_of_versperoth.lua @@ -0,0 +1,104 @@ +local mType = Game.createMonsterType("Minion Of Versperoth") +local monster = {} + +monster.description = "a minion of Versperoth" +monster.experience = 6200 +monster.outfit = { + lookType = 491, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 9000 +monster.maxHealth = 9000 +monster.race = "fire" +monster.corpse = 0 +monster.speed = 310 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 80, + random = 20, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grrrrunt", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -390}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -350, maxDamage = -700, length = 8, spread = 3, effect = CONST_ME_FIREATTACK, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -600, maxDamage = -1300, length = 8, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="lava golem soulfire", interval = 2000, chance = 15, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -220, maxDamage = -350, radius = 4, effect = CONST_ME_FIREAREA, target = true}, + {name ="speed", interval = 2000, chance = 10, speedChange = -300, length = 5, spread = 3, effect = CONST_ME_BLOCKHIT, target = false, duration = 10000}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_FIREDAMAGE, minDamage = -280, maxDamage = -350, radius = 3, effect = CONST_ME_HITBYFIRE, target = false} +} + +monster.defenses = { + defense = 60, + armor = 60 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 1}, + {type = COMBAT_ENERGYDAMAGE, percent = 1}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 1} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/bigfoots_burden/strange_slime.lua b/data/monster/quests/bigfoots_burden/strange_slime.lua new file mode 100644 index 00000000000..ac75053cea8 --- /dev/null +++ b/data/monster/quests/bigfoots_burden/strange_slime.lua @@ -0,0 +1,95 @@ +local mType = Game.createMonsterType("Strange Slime") +local monster = {} + +monster.description = "a strange slime" +monster.experience = 0 +monster.outfit = { + lookType = 19, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 15 +monster.maxHealth = 15 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 0, + armor = 0 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/bigfoots_burden/versperoth.lua b/data/monster/quests/bigfoots_burden/versperoth.lua new file mode 100644 index 00000000000..5fe17326be9 --- /dev/null +++ b/data/monster/quests/bigfoots_burden/versperoth.lua @@ -0,0 +1,104 @@ +local mType = Game.createMonsterType("Versperoth") +local monster = {} + +monster.description = "Versperoth" +monster.experience = 30000 +monster.outfit = { + lookType = 295, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 100000 +monster.maxHealth = 100000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "GrrroaR!", yell = false}, + {text = "GROWL!", yell = false}, + {text = "Waaaah!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 1200, chance = 100, skill = 120, attack = 115}, + {name ="combat", interval = 1000, chance = 40, type = COMBAT_FIREDAMAGE, minDamage = -700, maxDamage = -1615, range = 5, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="melee", interval = 1000, chance = 25, minDamage = -750, maxDamage = -950} +} + +monster.defenses = { + defense = 55, + armor = 55 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 90}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/animated_clomp.lua b/data/monster/quests/cults_of_tibia/animated_clomp.lua new file mode 100644 index 00000000000..053883af4aa --- /dev/null +++ b/data/monster/quests/cults_of_tibia/animated_clomp.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Animated Clomp") +local monster = {} + +monster.description = "an animated clomp" +monster.experience = 275 +monster.outfit = { + lookType = 860, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 900 +monster.maxHealth = 900 +monster.race = "blood" +monster.corpse = 25398 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Snort!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 92000, maxCount = 130}, + {id = 24842, chance = 2200}, + {id = 5925, chance = 1200, maxCount = 2}, + {id = 11224, chance = 900}, + {id = 3973, chance = 400}, + {id = 7432, chance = 200} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 40, maxDamage = -289, condition = {type = CONDITION_FIRE, totalDamage = 6, interval = 9000}} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 80, maxDamage = 95, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/animated_cyclops.lua b/data/monster/quests/cults_of_tibia/animated_cyclops.lua new file mode 100644 index 00000000000..93d2a17dabf --- /dev/null +++ b/data/monster/quests/cults_of_tibia/animated_cyclops.lua @@ -0,0 +1,117 @@ +local mType = Game.createMonsterType("Animated Cyclops") +local monster = {} + +monster.description = "an animated cyclops" +monster.experience = 150 +monster.outfit = { + lookType = 22, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 260 +monster.maxHealth = 260 +monster.race = "blood" +monster.corpse = 5962 +monster.speed = 200 +monster.manaCost = 490 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Il lorstok human!", yell = false}, + {text = "Toks utat.", yell = false}, + {text = "Human, uh whil dyh!", yell = false}, + {text = "Youh ah trak!", yell = false}, + {text = "Let da mashing begin!", yell = false} +} + +monster.loot = { + {id = 2129, chance = 190}, + {name = "gold coin", chance = 82000, maxCount = 47}, + {name = "club ring", chance = 90}, + {name = "halberd", chance = 1003}, + {name = "short sword", chance = 8000}, + {name = "dark helmet", chance = 220}, + {name = "plate shield", chance = 2500}, + {name = "battle shield", chance = 1400}, + {name = "meat", chance = 30070}, + {id = 7398, chance = 80}, + {name = "health potion", chance = 210}, + {name = "cyclops toe", chance = 4930}, + {id = 26654, chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -105} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 25}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/animated_guzzlemaw.lua b/data/monster/quests/cults_of_tibia/animated_guzzlemaw.lua new file mode 100644 index 00000000000..91352f17573 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/animated_guzzlemaw.lua @@ -0,0 +1,137 @@ +local mType = Game.createMonsterType("Animated Guzzlemaw") +local monster = {} + +monster.description = "an animated guzzlemaw" +monster.experience = 5500 +monster.outfit = { + lookType = 584, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 6400 +monster.maxHealth = 6400 +monster.race = "blood" +monster.corpse = 22485 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Gmmmooooh! *chomp*", yell = false}, + {text = "MWAAAH! *gurgle*", yell = false}, + {text = "*chomp* Mmmoh! *chomp*", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "platinum coin", chance = 100000, maxCount = 7}, + {name = "banana skin", chance = 10700}, + {name = "piece of iron", chance = 10500}, + {name = "fishbone", chance = 9500}, + {id = 2229, chance = 10400}, + {id = 2230, chance = 9200}, + {id = 2231, chance = 4500}, + {name = "remains of a fish", chance = 10110}, + {name = "two handed sword", chance = 2700}, + {id = 2667, chance = 7000, maxCount = 3}, + {name = "ham", chance = 10000}, + {name = "iron ore", chance = 3000}, + {name = "fish fin", chance = 5000}, + {name = "hardened bone", chance = 5700}, + {name = "assassin dagger", chance = 1000}, + {name = "haunted blade", chance = 2000}, + {name = "nightmare blade", chance = 380}, + {name = "great mana potion", chance = 17000, maxCount = 3}, + {name = "great health potion", chance = 18500, maxCount = 2}, + {name = "sai", chance = 1200}, + {name = "violet crystal shard", chance = 3000}, + {name = "brown crystal splinter", chance = 12000, maxCount = 2}, + {name = "red crystal fragment", chance = 7600}, + {id = 33539, chance = 12000}, + {name = "cluster of solace", chance = 920}, + {name = "frazzle tongue", chance = 15000}, + {name = "frazzle skin", chance = 14000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -499}, + -- bleed + {name ="condition", type = CONDITION_BLEEDING, interval = 2000, chance = 10, minDamage = -500, maxDamage = -1000, radius = 3, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -900, length = 8, spread = 3, effect = CONST_ME_EXPLOSIONAREA, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -500, radius = 2, shootEffect = CONST_ANI_LARGEROCK, effect = CONST_ME_STONES, target = true}, + {name ="speed", interval = 2000, chance = 15, speedChange = -800, radius = 6, effect = CONST_ME_MAGIC_RED, target = false, duration = 15000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -800, length = 8, spread = 3, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 50, + armor = 50, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 250, maxDamage = 425, effect = CONST_ME_HITBYPOISON, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 15}, + {type = COMBAT_FIREDAMAGE, percent = 5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/animated_moohtant.lua b/data/monster/quests/cults_of_tibia/animated_moohtant.lua new file mode 100644 index 00000000000..d5f07506dff --- /dev/null +++ b/data/monster/quests/cults_of_tibia/animated_moohtant.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Animated Moohtant") +local monster = {} + +monster.description = "an animated moohtant" +monster.experience = 2600 +monster.outfit = { + lookType = 607, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3200 +monster.maxHealth = 3200 +monster.race = "blood" +monster.corpse = 23367 +monster.speed = 260 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 3 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "MOOOOH!", yell = true}, + {text = "Grrrr.", yell = false}, + {text = "Raaaargh!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 195}, + {id = 2152, chance = 58160, maxCount = 2}, + {id = 23571, chance = 2740, maxCount = 2}, + {id = 23570, chance = 1770}, + {id = 7591, chance = 7380, maxCount = 3}, + {id = 7590, chance = 7230, maxCount = 3}, + {id = 2666, chance = 6520}, + {id = 2147, chance = 4680, maxCount = 2}, + {id = 5878, chance = 4110}, + {id = 2145, chance = 4400, maxCount = 2}, + {id = 2214, chance = 2410}, + {id = 5911, chance = 900}, + {id = 23544, chance = 860}, + {id = 2154, chance = 710}, + {id = 7452, chance = 430}, + {id = 7427, chance = 280}, + {id = 9971, chance = 280}, + {id = 7401, chance = 280} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 110, attack = 50}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -230, length = 3, spread = 0, effect = CONST_ME_GROUNDSHAKER, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -200, radius = 3, effect = CONST_ME_GROUNDSHAKER, target = false}, + {name ="combat", interval = 2000, chance = 19, type = COMBAT_LIFEDRAIN, minDamage = -50, maxDamage = -225, radius = 5, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -150, maxDamage = -235, range = 7, radius = 4, shootEffect = CONST_ANI_LARGEROCK, effect = CONST_ME_EXPLOSIONAREA, target = true} +} + +monster.defenses = { + defense = 45, + armor = 40, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_HEALING, minDamage = 50, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 1}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 1}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 1} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/animated_mummy.lua b/data/monster/quests/cults_of_tibia/animated_mummy.lua new file mode 100644 index 00000000000..3ff80a2d950 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/animated_mummy.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Animated Mummy") +local monster = {} + +monster.description = "an animated mummy" +monster.experience = 150 +monster.outfit = { + lookType = 65, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 240 +monster.maxHealth = 240 +monster.race = "undead" +monster.corpse = 6004 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I will ssswallow your sssoul!", yell = false}, + {text = "Mort ulhegh dakh visss.", yell = false}, + {text = "Flesssh to dussst!", yell = false}, + {text = "I will tassste life again!", yell = false}, + {text = "Ahkahra exura belil mort!", yell = false}, + {text = "Yohag Sssetham!", yell = false} +} + +monster.loot = { + {id = 2124, chance = 1500}, + {name = "silver brooch", chance = 4000}, + {name = "black pearl", chance = 1000}, + {name = "gold coin", chance = 38000, maxCount = 80}, + {name = "strange talisman", chance = 5000}, + {id = 2162, chance = 5800}, + {name = "silver amulet", chance = 100}, + {name = "poison dagger", chance = 450}, + {name = "black shield", chance = 170}, + {name = "worm", chance = 19000, maxCount = 3}, + {name = "yellow piece of cloth", chance = 900}, + {name = "gauze bandage", chance = 10000}, + {name = "mini mummy", chance = 10}, + {name = "flask of embalming fluid", chance = 11690} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -85, condition = {type = CONDITION_POISON, totalDamage = 4, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -30, maxDamage = -40, range = 1, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="speed", interval = 2000, chance = 15, speedChange = -226, range = 7, effect = CONST_ME_MAGIC_RED, target = true, duration = 10000} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/animated_ogre_brute.lua b/data/monster/quests/cults_of_tibia/animated_ogre_brute.lua new file mode 100644 index 00000000000..d7c3a4db9fd --- /dev/null +++ b/data/monster/quests/cults_of_tibia/animated_ogre_brute.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Animated Ogre Brute") +local monster = {} + +monster.description = "an animated ogre brute" +monster.experience = 800 +monster.outfit = { + lookType = 857, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "blood" +monster.corpse = 24799 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You so juicy!", yell = false}, + {text = "You stop! You lunch!", yell = false}, + {text = "Smash you face in!!!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 92000, maxCount = 130}, + {id = 2666, chance = 6200}, + {id = 2147, chance = 4200}, + {id = 2143, chance = 6200, maxCount = 3}, + {id = 12403, chance = 6200}, + {id = 2687, chance = 6200, maxCount = 7}, + {id = 24844, chance = 5200}, + {id = 24845, chance = 1200}, + {id = 24849, chance = 3200, maxCount = 2}, + {id = 24850, chance = 3200, maxCount = 3}, + {id = 2166, chance = 2200}, + {id = 24847, chance = 1200}, + {id = 7588, chance = 6200, maxCount = 3}, + {id = 7428, chance = 500}, + {id = 24828, chance = 600}, + {id = 24827, chance = 800}, + {id = 2562, chance = 500}, + {id = 9820, chance = 200}, + {id = 24848, chance = 300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -269, condition = {type = CONDITION_FIRE, totalDamage = 6, interval = 9000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -70, maxDamage = -180, range = 7, shootEffect = CONST_ANI_POISON, target = false}, + {name ="drunk", interval = 2000, chance = 10, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_TELEPORT, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 80, maxDamage = 95, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/animated_ogre_savage.lua b/data/monster/quests/cults_of_tibia/animated_ogre_savage.lua new file mode 100644 index 00000000000..68e29cbc6d8 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/animated_ogre_savage.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("Animated Ogre Savage") +local monster = {} + +monster.description = "an animated ogre savage" +monster.experience = 950 +monster.outfit = { + lookType = 858, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1400 +monster.maxHealth = 1400 +monster.race = "blood" +monster.corpse = 24803 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Must! Chop! Food! Raahh!", yell = false}, + {text = "You tasty!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 92000, maxCount = 130}, + {id = 2666, chance = 6200}, + {id = 24849, chance = 3200, maxCount = 2}, + {id = 24850, chance = 3200, maxCount = 3}, + {id = 2687, chance = 2200, maxCount = 7}, + {id = 8844, chance = 1200, maxCount = 2}, + {id = 9970, chance = 1200, maxCount = 2}, + {id = 2147, chance = 1200, maxCount = 2}, + {id = 7439, chance = 1200}, + {id = 2194, chance = 2200}, + {id = 24844, chance = 1200}, + {id = 24845, chance = 1200}, + {id = 24847, chance = 1200}, + {id = 7588, chance = 2200, maxCount = 3}, + {id = 2391, chance = 600}, + {id = 24848, chance = 300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -269, condition = {type = CONDITION_FIRE, totalDamage = 6, interval = 9000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -70, maxDamage = -180, range = 7, shootEffect = CONST_ANI_POISON, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 80, maxDamage = 95, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/animated_ogre_shaman.lua b/data/monster/quests/cults_of_tibia/animated_ogre_shaman.lua new file mode 100644 index 00000000000..3571ad7d617 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/animated_ogre_shaman.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Animated Ogre Shaman") +local monster = {} + +monster.description = "an animated ogre shaman" +monster.experience = 625 +monster.outfit = { + lookType = 859, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 800 +monster.maxHealth = 800 +monster.race = "blood" +monster.corpse = 24795 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Dworc Fleshhunter", chance = 30, interval = 1000, max = 1}, + {name = "Terror Bird", chance = 30, interval = 1000, max = 1} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "The spirits hunger!", yell = false}, + {text = "A sacrifice for Great Hunger!", yell = false}, + {text = "Stay here, soul food!", yell = false}, + {text = "You more delicate than clomp!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 92000, maxCount = 130}, + {id = 24850, chance = 1200, maxCount = 3}, + {id = 24841, chance = 6200, maxCount = 2}, + {id = 2147, chance = 2200, maxCount = 2}, + {id = 2144, chance = 1200, maxCount = 2}, + {id = 20111, chance = 3200}, + {id = 12408, chance = 1200}, + {id = 2687, chance = 2200, maxCount = 7}, + {id = 2185, chance = 800}, + {id = 24844, chance = 3200}, + {id = 24845, chance = 2200}, + {id = 24840, chance = 1200}, + {id = 2229, chance = 1200}, + {id = 24847, chance = 1200}, + {id = 7589, chance = 1000, maxCount = 3}, + {id = 2188, chance = 600}, + {id = 2031, chance = 500}, + {id = 24839, chance = 300}, + {id = 24848, chance = 300}, + {id = 3955, chance = 100}, + {id = 3952, chance = 100, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -269, condition = {type = CONDITION_FIRE, totalDamage = 6, interval = 9000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -70, maxDamage = -180, range = 7, shootEffect = CONST_ANI_POISON, target = false}, + {name ="outfit", interval = 2000, chance = 8, range = 7, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 4000, outfitMonster = "chicken"}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -15, maxDamage = -120, length = 8, spread = 3, effect = CONST_ME_CARNIPHILA, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 80, maxDamage = 95, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/animated_rhino.lua b/data/monster/quests/cults_of_tibia/animated_rhino.lua new file mode 100644 index 00000000000..2b657883cac --- /dev/null +++ b/data/monster/quests/cults_of_tibia/animated_rhino.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Animated Stone Rhino") +local monster = {} + +monster.description = "an animated stone rhino" +monster.experience = 1800 +monster.outfit = { + lookType = 936, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3000 +monster.maxHealth = 3000 +monster.race = "blood" +monster.corpse = 27750 +monster.speed = 150 +monster.manaCost = 290 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Snarl!", yell = false}, + {text = "SNIFF!", yell = false} +} + +monster.loot = { + {id = 5925, chance = 50320}, + {id = 27056, chance = 50320}, + {id = 27057, chance = 50320}, + {id = 24842, chance = 50320} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 10}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = 500, range = 7, shootEffect = CONST_ANI_SMALLSTONE, target = false} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -12}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 1}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/animated_rotworm.lua b/data/monster/quests/cults_of_tibia/animated_rotworm.lua new file mode 100644 index 00000000000..6009b7d4fe1 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/animated_rotworm.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Animated Rotworm") +local monster = {} + +monster.description = "an animated rotworm" +monster.experience = 40 +monster.outfit = { + lookType = 26, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 65 +monster.maxHealth = 65 +monster.race = "blood" +monster.corpse = 5967 +monster.speed = 150 +monster.manaCost = 305 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 71760, maxCount = 17}, + {id = 2376, chance = 3000}, + {name = "mace", chance = 4500}, + {name = "meat", chance = 20000}, + {name = "ham", chance = 20120}, + {name = "worm", chance = 3000, maxCount = 3}, + {name = "lump of dirt", chance = 10000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -40} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/animated_skunk.lua b/data/monster/quests/cults_of_tibia/animated_skunk.lua new file mode 100644 index 00000000000..6fcff7d5a76 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/animated_skunk.lua @@ -0,0 +1,102 @@ +local mType = Game.createMonsterType("Animated Skunk") +local monster = {} + +monster.description = "an animated skunk" +monster.experience = 3 +monster.outfit = { + lookType = 106, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 20 +monster.maxHealth = 20 +monster.race = "blood" +monster.corpse = 6035 +monster.speed = 120 +monster.manaCost = 200 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 8, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "bulb of garlic", chance = 4910}, + {name = "skunk tail", chance = 920} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -5}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -1, maxDamage = -3, range = 1, target = true} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/animated_stone_golem.lua b/data/monster/quests/cults_of_tibia/animated_stone_golem.lua new file mode 100644 index 00000000000..1f6a71efaa9 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/animated_stone_golem.lua @@ -0,0 +1,111 @@ +local mType = Game.createMonsterType("Animated Stone Golem") +local monster = {} + +monster.description = "an animated stone golem" +monster.experience = 160 +monster.outfit = { + lookType = 67, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 270 +monster.maxHealth = 270 +monster.race = "undead" +monster.corpse = 6005 +monster.speed = 180 +monster.manaCost = 590 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "small stone", chance = 13890, maxCount = 4}, + {id = 2124, chance = 120}, + {name = "gold coin", chance = 90000, maxCount = 40}, + {name = "red gem", chance = 30}, + {name = "power ring", chance = 5070}, + {name = "carlin sword", chance = 2500}, + {name = "iron ore", chance = 1980}, + {name = "ancient stone", chance = 1020}, + {name = "shiny stone", chance = 760}, + {name = "sulphurous stone", chance = 10370}, + {name = "piece of marble rock", chance = 380}, + {id = 13757, chance = 550} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -110} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/barkless_devotee.lua b/data/monster/quests/cults_of_tibia/barkless_devotee.lua new file mode 100644 index 00000000000..4dcf5590111 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/barkless_devotee.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Barkless Devotee") +local monster = {} + +monster.description = "a barkless devotee" +monster.experience = 2200 +monster.outfit = { + lookType = 990, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1486 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Barkless Cult Trial Zone (below Ab'Dendriel)." + } + +monster.health = 2800 +monster.maxHealth = 2800 +monster.race = "blood" +monster.corpse = 6012 +monster.speed = 240 +monster.manaCost = 390 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Prepare yourself!", yell = false}, + {text = "You are not loved by this world!", yell = false}, + {text = "Pain and suffering!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 48000, maxCount = 199}, + {id = 29044, chance = 1540}, + {id = 29043, chance = 4050}, + {id = 29045, chance = 970} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -250, maxDamage = -420, range = 7, radius = 4, shootEffect = CONST_ANI_SPEAR, effect = CONST_ME_GREEN_RINGS, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -150, radius = 6, effect = CONST_ME_GREEN_RINGS, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 17}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/barkless_fanatic.lua b/data/monster/quests/cults_of_tibia/barkless_fanatic.lua new file mode 100644 index 00000000000..859028957a8 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/barkless_fanatic.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Barkless Fanatic") +local monster = {} + +monster.description = "a barkless fanatic" +monster.experience = 2500 +monster.outfit = { + lookType = 990, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1488 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Barkless Cult Trial Zone (below Ab'Dendriel)." + } + +monster.health = 3200 +monster.maxHealth = 3200 +monster.race = "blood" +monster.corpse = 6012 +monster.speed = 240 +monster.manaCost = 390 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "DO NOT LEAVE THIS WORLD AS A WIMP!", yell = false}, + {text = "PAIN PURIFIES! PAIN PURIFIES!", yell = false}, + {text = "PROVE YOUR WORTH, BLEED!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 199}, + {id = 29044, chance = 2310}, + {id = 29043, chance = 12690}, + {id = 27629, chance = 6920} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -230}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -220, maxDamage = -450, range = 7, radius = 4, shootEffect = CONST_ANI_SPEAR, effect = CONST_ME_GREEN_RINGS, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -150, radius = 6, effect = CONST_ME_GREEN_RINGS, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 1}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 1}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 1}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 1} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/dorokoll_the_mystic.lua b/data/monster/quests/cults_of_tibia/bosses/dorokoll_the_mystic.lua new file mode 100644 index 00000000000..f8b7fa29c1c --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/dorokoll_the_mystic.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Dorokoll The Mystic") +local monster = {} + +monster.description = "Dorokoll The Mystic" +monster.experience = 0 +monster.outfit = { + lookType = 154, + lookHead = 115, + lookBody = 60, + lookLegs = 19, + lookFeet = 58, + lookAddons = 2, + lookMount = 0 +} + +monster.health = 30000 +monster.maxHealth = 30000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -500, radius = 8, effect = CONST_ME_LOSEENERGY, target = true} +} + +monster.defenses = { + defense = 50, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/dorokoll_the_mystic_stop.lua b/data/monster/quests/cults_of_tibia/bosses/dorokoll_the_mystic_stop.lua new file mode 100644 index 00000000000..a5e96dfe8ab --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/dorokoll_the_mystic_stop.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Dorokoll The Mystic Stop") +local monster = {} + +monster.name = "Dorokoll The Mystic" +monster.description = "Dorokoll The Mystic" +monster.experience = 0 +monster.outfit = { + lookType = 154, + lookHead = 115, + lookBody = 60, + lookLegs = 19, + lookFeet = 58, + lookAddons = 2, + lookMount = 0 +} + +monster.health = 15000 +monster.maxHealth = 15000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -500, radius = 8, effect = CONST_ME_LOSEENERGY, target = false} +} + +monster.defenses = { + defense = 50, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/eliz_the_unyielding.lua b/data/monster/quests/cults_of_tibia/bosses/eliz_the_unyielding.lua new file mode 100644 index 00000000000..df66b7da407 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/eliz_the_unyielding.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Eliz The Unyielding") +local monster = {} + +monster.description = "Eliz The Unyielding" +monster.experience = 0 +monster.outfit = { + lookType = 632, + lookHead = 1, + lookBody = 38, + lookLegs = 38, + lookFeet = 0, + lookAddons = 2, + lookMount = 0 +} + +monster.health = 30000 +monster.maxHealth = 30000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400} +} + +monster.defenses = { + defense = 50, + armor = 35, + {name ="cults of tibia armor buff", interval = 2000, chance = 40, radius = 8, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/eliz_the_unyielding_stop.lua b/data/monster/quests/cults_of_tibia/bosses/eliz_the_unyielding_stop.lua new file mode 100644 index 00000000000..9b8026e7695 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/eliz_the_unyielding_stop.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Eliz The Unyielding Stop") +local monster = {} + +monster.name = "Eliz The Unyielding" +monster.description = "Eliz The Unyielding" +monster.experience = 0 +monster.outfit = { + lookType = 632, + lookHead = 1, + lookBody = 38, + lookLegs = 38, + lookFeet = 0, + lookAddons = 2, + lookMount = 0 +} + +monster.health = 15000 +monster.maxHealth = 15000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400} +} + +monster.defenses = { + defense = 50, + armor = 35, + {name ="cults of tibia armor buff", interval = 2000, chance = 40, radius = 9, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/eshtaba_the_conjurer.lua b/data/monster/quests/cults_of_tibia/bosses/eshtaba_the_conjurer.lua new file mode 100644 index 00000000000..d80303af660 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/eshtaba_the_conjurer.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Eshtaba The Conjurer") +local monster = {} + +monster.description = "Eshtaba The Conjurer" +monster.experience = 0 +monster.outfit = { + lookType = 149, + lookHead = 95, + lookBody = 68, + lookLegs = 68, + lookFeet = 68, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 30000 +monster.maxHealth = 30000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 5 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Dread Minion", chance = 20, interval = 2000}, + {name = "Dread Minion", chance = 30, interval = 2000}, + {name = "Dread Minion", chance = 20, interval = 2000}, + {name = "Dread Minion", chance = 30, interval = 2000}, + {name = "Dread Minion", chance = 20, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400} +} + +monster.defenses = { + defense = 50, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/eshtaba_the_conjurer_stop.lua b/data/monster/quests/cults_of_tibia/bosses/eshtaba_the_conjurer_stop.lua new file mode 100644 index 00000000000..94808957775 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/eshtaba_the_conjurer_stop.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Eshtaba The Conjurer Stop") +local monster = {} + +monster.name = "Eshtaba The Conjurer" +monster.description = "Eshtaba The Conjurer" +monster.experience = 0 +monster.outfit = { + lookType = 149, + lookHead = 95, + lookBody = 68, + lookLegs = 68, + lookFeet = 68, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 15000 +monster.maxHealth = 15000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 5 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Dread Minion", chance = 20, interval = 2000}, + {name = "Dread Minion", chance = 30, interval = 2000}, + {name = "Dread Minion", chance = 20, interval = 2000}, + {name = "Dread Minion", chance = 30, interval = 2000}, + {name = "Dread Minion", chance = 20, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400} +} + +monster.defenses = { + defense = 50, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/essence_of_malice.lua b/data/monster/quests/cults_of_tibia/bosses/essence_of_malice.lua new file mode 100644 index 00000000000..bc6c5d75c9d --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/essence_of_malice.lua @@ -0,0 +1,141 @@ +local mType = Game.createMonsterType("Essence Of Malice") +local monster = {} + +monster.description = "Essence Of Malice" +monster.experience = 4600 +monster.outfit = { + lookType = 351, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 25000 +monster.maxHealth = 25000 +monster.race = "undead" +monster.corpse = 11362 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 366, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "silver token", chance = 2732}, + {name = "gold token", chance = 1530}, + {name = "gold coin", chance = 100000, maxCount = 200}, + {name = "platinum coin", chance = 29840, maxCount = 57}, + {name = "lightning legs", chance = 8723}, + {name = "yellow gem", chance = 29460}, + {name = "demon shield", chance = 2270}, + {name = "shockwave amulet", chance = 15100}, + {name = "witch hat", chance = 9510}, + {name = "mysterious remains", chance = 100000}, + {name = "small amethyst", chance = 14700, maxCount = 10}, + {name = "small amethyst", chance = 12259, maxCount = 10}, + {name = "odd organ", chance = 100000}, + {name = "energy bar", chance = 16872, maxCount = 3}, + {id = 26186, chance = 8762}, + {name = "ultimate health potion", chance = 27652, maxCount = 10}, + {name = "blade of corruption", chance = 3775} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -603}, + {name ="ghastly dragon curse", interval = 2000, chance = 5, range = 5, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -520, maxDamage = -780, range = 5, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -80, maxDamage = -230, range = 7, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -120, maxDamage = -250, length = 8, spread = 3, effect = CONST_ME_LOSEENERGY, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -110, maxDamage = -180, radius = 4, effect = CONST_ME_MORTAREA, target = false}, + {name ="speed", interval = 2000, chance = 20, speedChange = -800, range = 7, effect = CONST_ME_SMALLCLOUDS, target = true, duration = 30000} +} + +monster.defenses = { + defense = 35, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = -30}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/last_planegazer.lua b/data/monster/quests/cults_of_tibia/bosses/last_planegazer.lua new file mode 100644 index 00000000000..d53501ffb30 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/last_planegazer.lua @@ -0,0 +1,111 @@ +local mType = Game.createMonsterType("Last Planegazer") +local monster = {} + +monster.description = "a last planegazer" +monster.experience = 40000 +monster.outfit = { + lookType = 1063, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "blood" +monster.corpse = 27916 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 65700, maxCount = 15}, + {id = 2510, chance = 20000}, + {id = 2398, chance = 12900}, + {id = 2464, chance = 10000}, + {id = 2460, chance = 7800}, + {id = 2376, chance = 5000}, + {id = 2666, chance = 5000}, + {id = 2386, chance = 4000}, + {id = 12428, chance = 2000, maxCount = 2}, + {id = 5878, chance = 980}, + {id = 2554, chance = 310}, + {id = 2172, chance = 120} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -45} +} + +monster.defenses = { + defense = 15, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/leiden.lua b/data/monster/quests/cults_of_tibia/bosses/leiden.lua new file mode 100644 index 00000000000..342830b8adf --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/leiden.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Leiden") +local monster = {} + +monster.description = "Leiden" +monster.experience = 0 +monster.outfit = { + lookType = 988, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 15000 +monster.maxHealth = 30000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 240 +monster.manaCost = 390 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "LeidenHeal" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Barkless Fanatic", chance = 20, interval = 2000}, + {name = "Barkless Fanatic", chance = 30, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Bring me the pain! Make me suffer!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400} +} + +monster.defenses = { + defense = 50, + armor = 35 +} + +monster.reflects = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/malkhar_deathbringer.lua b/data/monster/quests/cults_of_tibia/bosses/malkhar_deathbringer.lua new file mode 100644 index 00000000000..bbf0a94d61c --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/malkhar_deathbringer.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Malkhar Deathbringer") +local monster = {} + +monster.description = "Malkhar Deathbringer" +monster.experience = 0 +monster.outfit = { + lookType = 134, + lookHead = 19, + lookBody = 94, + lookLegs = 41, + lookFeet = 57, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 30000 +monster.maxHealth = 30000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -500, range = 8, radius = 8, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_MORTAREA, target = true} +} + +monster.defenses = { + defense = 50, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/malkhar_deathbringer_stop.lua b/data/monster/quests/cults_of_tibia/bosses/malkhar_deathbringer_stop.lua new file mode 100644 index 00000000000..f413b4bd9af --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/malkhar_deathbringer_stop.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Malkhar Deathbringer Stop") +local monster = {} + +monster.name = "Malkhar Deathbringer" +monster.description = "Malkhar Deathbringer" +monster.experience = 0 +monster.outfit = { + lookType = 134, + lookHead = 19, + lookBody = 94, + lookLegs = 41, + lookFeet = 57, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 15000 +monster.maxHealth = 15000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -500, range = 6, radius = 8, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_MORTAREA, target = true} +} + +monster.defenses = { + defense = 50, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/mezlon_the_defiler.lua b/data/monster/quests/cults_of_tibia/bosses/mezlon_the_defiler.lua new file mode 100644 index 00000000000..70b9d5cc116 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/mezlon_the_defiler.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Mezlon The Defiler") +local monster = {} + +monster.description = "Mezlon The Defiler" +monster.experience = 0 +monster.outfit = { + lookType = 144, + lookHead = 1, + lookBody = 38, + lookLegs = 1, + lookFeet = 60, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 30000 +monster.maxHealth = 30000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400} +} + +monster.defenses = { + defense = 50, + armor = 35, + {name ="heal monster 9x9", interval = 2000, chance = 40, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/mezlon_the_defiler_stop.lua b/data/monster/quests/cults_of_tibia/bosses/mezlon_the_defiler_stop.lua new file mode 100644 index 00000000000..9484e4d90dd --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/mezlon_the_defiler_stop.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Mezlon The Defiler Stop") +local monster = {} + +monster.name = "Mezlon The Defiler" +monster.description = "Mezlon The Defiler" +monster.experience = 0 +monster.outfit = { + lookType = 144, + lookHead = 1, + lookBody = 38, + lookLegs = 1, + lookFeet = 60, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 15000 +monster.maxHealth = 15000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400} +} + +monster.defenses = { + defense = 50, + armor = 35, + {name ="heal monster 9x9", interval = 2000, chance = 40, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/pillars/containment_crystal.lua b/data/monster/quests/cults_of_tibia/bosses/pillars/containment_crystal.lua new file mode 100644 index 00000000000..991557fa874 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/pillars/containment_crystal.lua @@ -0,0 +1,93 @@ +local mType = Game.createMonsterType("Containment Crystal") +local monster = {} + +monster.description = "a containment crystal" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 8633 +} + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="combat", interval = 2000, chance = 40, type = COMBAT_ENERGYDAMAGE, minDamage = -100, maxDamage = -220, radius = 3, effect = CONST_ME_PURPLEENERGY, target = false} +} + +monster.defenses = { + defense = 50, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/pillars/destroyed_pillar.lua b/data/monster/quests/cults_of_tibia/bosses/pillars/destroyed_pillar.lua new file mode 100644 index 00000000000..fd0421ce40e --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/pillars/destroyed_pillar.lua @@ -0,0 +1,89 @@ +local mType = Game.createMonsterType("Destroyed Pillar") +local monster = {} + +monster.description = "a destroyed pillar" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 8639 +} + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 35, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/pillars/pillar_of_death.lua b/data/monster/quests/cults_of_tibia/bosses/pillars/pillar_of_death.lua new file mode 100644 index 00000000000..e40fabcad3a --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/pillars/pillar_of_death.lua @@ -0,0 +1,89 @@ +local mType = Game.createMonsterType("Pillar Of Death") +local monster = {} + +monster.description = "a pillar of death" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 12383 +} + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 50, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/pillars/pillar_of_draining.lua b/data/monster/quests/cults_of_tibia/bosses/pillars/pillar_of_draining.lua new file mode 100644 index 00000000000..8d6ed335154 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/pillars/pillar_of_draining.lua @@ -0,0 +1,89 @@ +local mType = Game.createMonsterType("Pillar Of Draining") +local monster = {} + +monster.description = "a pillar of draining" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 12383 +} + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 50, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/pillars/pillar_of_healing.lua b/data/monster/quests/cults_of_tibia/bosses/pillars/pillar_of_healing.lua new file mode 100644 index 00000000000..f04955e83a4 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/pillars/pillar_of_healing.lua @@ -0,0 +1,89 @@ +local mType = Game.createMonsterType("Pillar Of Healing") +local monster = {} + +monster.description = "a pillar of healing" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 12383 +} + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 50, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/pillars/pillar_of_protection.lua b/data/monster/quests/cults_of_tibia/bosses/pillars/pillar_of_protection.lua new file mode 100644 index 00000000000..2f2002dc28c --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/pillars/pillar_of_protection.lua @@ -0,0 +1,89 @@ +local mType = Game.createMonsterType("Pillar Of Protection") +local monster = {} + +monster.description = "a pillar of protection" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 12383 +} + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 50, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/pillars/pillar_of_summoning.lua b/data/monster/quests/cults_of_tibia/bosses/pillars/pillar_of_summoning.lua new file mode 100644 index 00000000000..e4ecb65cd04 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/pillars/pillar_of_summoning.lua @@ -0,0 +1,89 @@ +local mType = Game.createMonsterType("Pillar Of Summoning") +local monster = {} + +monster.description = "a pillar of summoning" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 12383 +} + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 50, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/ravennous_hunger.lua b/data/monster/quests/cults_of_tibia/bosses/ravennous_hunger.lua new file mode 100644 index 00000000000..2d4c539c061 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/ravennous_hunger.lua @@ -0,0 +1,159 @@ +local mType = Game.createMonsterType("Ravenous Hunger") +local monster = {} + +monster.description = "Ravenous Hunger" +monster.experience = 0 +monster.outfit = { + lookType = 556, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 100000 +monster.maxHealth = 100000 +monster.race = "blood" +monster.corpse = 6324 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "LeidenHeal" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Mutated Bat", chance = 100, interval = 2000}, + {name = "Mutated Bat", chance = 100, interval = 2000}, + {name = "Mutated Bat", chance = 100, interval = 2000}, + {name = "Mutated Bat", chance = 100, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "SU-*burp* SUFFEEER!", yell = false} +} + +monster.loot = { + {name = "bed of nails", chance = 67000}, + {name = "small sapphire", chance = 21000, maxCount = 10}, + {name = "great spirit potion", chance = 33230, maxCount = 5}, + {name = "yellow gem", chance = 12000}, + {id = 7633, chance = 5000}, + {name = "platinum coin", chance = 68299, maxCount = 30}, + {name = "lightning legs", chance = 18000}, + {name = "sacred tree amulet", chance = 15000}, + {name = "wood cape", chance = 9000}, + {name = "gold token", chance = 1532}, + {name = "gold coin", chance = 100000, maxCount = 200}, + {name = "small emerald", chance = 19000, maxCount = 10}, + {name = "great mana potion", chance = 31230, maxCount = 5}, + {name = "red gem", chance = 12000}, + {name = "oriental shoes", chance = 11000}, + {name = "torn shirt", chance = 42000}, + {name = "fig leaf", chance = 32000}, + {name = "luminous orb", chance = 35000}, + {name = "wooden spellbook", chance = 4500}, + {name = "elven legs", chance = 16000}, + {name = "small diamond", chance = 21000, maxCount = 10}, + {name = "ultimate health potion", chance = 28230, maxCount = 5}, + {name = "energy bar", chance = 53000, maxCount = 5}, + {name = "green gem", chance = 12000}, + {name = "broken key ring", chance = 4000}, + {name = "muck rod", chance = 10000}, + {name = "mysterious remains", chance = 100000}, + {name = "cobra crown", chance = 400}, + {name = "silver token", chance = 2500}, + {name = "elven mail", chance = 3000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -900} +} + +monster.defenses = { + defense = 50, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -80} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/summons/dark_soul.lua b/data/monster/quests/cults_of_tibia/bosses/summons/dark_soul.lua new file mode 100644 index 00000000000..7df9d9a0709 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/summons/dark_soul.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Dark Soul") +local monster = {} + +monster.description = "a dark soul" +monster.experience = 0 +monster.outfit = { + lookType = 714, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5000 +monster.maxHealth = 5000 +monster.race = "undead" +monster.corpse = 26397 +monster.speed = 162 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 250, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { +} + +monster.defenses = { + defense = 15, + armor = 10, + {name ="speed", interval = 2000, chance = 8, speedChange = 240, effect = CONST_ME_MAGIC_GREEN, target = false, duration = 20000}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/summons/dread_minion.lua b/data/monster/quests/cults_of_tibia/bosses/summons/dread_minion.lua new file mode 100644 index 00000000000..0e9037dff0f --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/summons/dread_minion.lua @@ -0,0 +1,102 @@ +local mType = Game.createMonsterType("Dread Minion") +local monster = {} + +monster.description = "a dread minion" +monster.experience = 3000 +monster.outfit = { + lookType = 882, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 4500 +monster.maxHealth = 4500 +monster.race = "undead" +monster.corpse = 26213 +monster.speed = 370 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 20000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 30, attack = 50}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_MANADRAIN, minDamage = -100, maxDamage = -400, range = 6, radius = 4, effect = CONST_ME_LOSEENERGY, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -100, maxDamage = -220, range = 6, radius = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_PURPLEENERGY, target = true} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 90, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/summons/enraged_sand_brood.lua b/data/monster/quests/cults_of_tibia/bosses/summons/enraged_sand_brood.lua new file mode 100644 index 00000000000..f96fbfc5812 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/summons/enraged_sand_brood.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Enraged Sand Brood") +local monster = {} + +monster.description = "a enraged sand brood" +monster.experience = 44 +monster.outfit = { + lookType = 82, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2000 +monster.maxHealth = 2000 +monster.race = "venom" +monster.corpse = 6023 +monster.speed = 175 +monster.manaCost = 355 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200, condition = {type = CONDITION_POISON, totalDamage = 15, interval = 4000}} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/summons/freed_soul.lua b/data/monster/quests/cults_of_tibia/bosses/summons/freed_soul.lua new file mode 100644 index 00000000000..70a2ad44ef7 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/summons/freed_soul.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Freed Soul") +local monster = {} + +monster.description = "a freed soul" +monster.experience = 0 +monster.outfit = { + lookType = 294, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 100 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="freed soul spell", interval = 2000, chance = 100, target = false} +} + +monster.defenses = { + defense = 50, + armor = 50 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/summons/liquor_spirit.lua b/data/monster/quests/cults_of_tibia/bosses/summons/liquor_spirit.lua new file mode 100644 index 00000000000..d8b5fa86e8b --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/summons/liquor_spirit.lua @@ -0,0 +1,103 @@ +local mType = Game.createMonsterType("Liquor Spirit") +local monster = {} + +monster.description = "a liquor spirit" +monster.experience = 0 +monster.outfit = { + lookType = 986, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 7000 +monster.maxHealth = 7000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "Evaporate" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400} +} + +monster.defenses = { + defense = 35, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/summons/sand_brood.lua b/data/monster/quests/cults_of_tibia/bosses/summons/sand_brood.lua new file mode 100644 index 00000000000..4562d6e9b74 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/summons/sand_brood.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Sand Brood") +local monster = {} + +monster.description = "a sand brood" +monster.experience = 44 +monster.outfit = { + lookType = 82, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "venom" +monster.corpse = 6023 +monster.speed = 175 +monster.manaCost = 355 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150, condition = {type = CONDITION_POISON, totalDamage = 15, interval = 4000}} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/summons/sand_vortex.lua b/data/monster/quests/cults_of_tibia/bosses/summons/sand_vortex.lua new file mode 100644 index 00000000000..d81be7bbc0c --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/summons/sand_vortex.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("Sand Vortex") +local monster = {} + +monster.description = "a sand vortex" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 26138 +} + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 140 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, radius = 4, effect = CONST_ME_POFF, target = false}, + {name ="speed", interval = 2000, chance = 20, speedChange = -650, radius = 4, effect = CONST_ME_POFF, target = false, duration = 5000}, + {name ="drunk", interval = 2000, chance = 10, range = 1, target = true, duration = 5000} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.reflects = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/summons/security_golem.lua b/data/monster/quests/cults_of_tibia/bosses/summons/security_golem.lua new file mode 100644 index 00000000000..2aa6f06d3d2 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/summons/security_golem.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Security Golem") +local monster = {} + +monster.description = "a secutiry golem" +monster.experience = 2750 +monster.outfit = { + lookType = 326, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 6500 +monster.maxHealth = 6500 +monster.race = "venom" +monster.corpse = 10005 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -550}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -100, maxDamage = -440, length = 6, spread = 4, effect = CONST_ME_PURPLEENERGY, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -100, maxDamage = -320, length = 7, spread = 8, effect = CONST_ME_ENERGYAREA, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/summons/soul_reaper.lua b/data/monster/quests/cults_of_tibia/bosses/summons/soul_reaper.lua new file mode 100644 index 00000000000..5068b72e37b --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/summons/soul_reaper.lua @@ -0,0 +1,103 @@ +local mType = Game.createMonsterType("Soul Reaper") +local monster = {} + +monster.description = "a soul reaper" +monster.experience = 2200 +monster.outfit = { + lookType = 878, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3500 +monster.maxHealth = 3500 +monster.race = "venom" +monster.corpse = 26209 +monster.speed = 290 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hisss!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -350}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -400, range = 6, shootEffect = CONST_ANI_FLASHARROW, effect = CONST_ME_STUN, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -150, maxDamage = -350, radius = 5, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="breach brood reducer", interval = 2000, chance = 20, target = false} +} + +monster.defenses = { + defense = 52, + armor = 52 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = -20}, + {type = COMBAT_FIREDAMAGE, percent = 40}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/summons/sphere_of_wrath.lua b/data/monster/quests/cults_of_tibia/bosses/summons/sphere_of_wrath.lua new file mode 100644 index 00000000000..a753c8c92d6 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/summons/sphere_of_wrath.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Sphere Of Wrath") +local monster = {} + +monster.description = "a sphere of wrath" +monster.experience = 0 +monster.outfit = { + lookType = 979, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 120 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -500}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -500, radius = 4, effect = CONST_ME_ENERGYAREA, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/summons/stolen_soul.lua b/data/monster/quests/cults_of_tibia/bosses/summons/stolen_soul.lua new file mode 100644 index 00000000000..089564fd535 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/summons/stolen_soul.lua @@ -0,0 +1,95 @@ +local mType = Game.createMonsterType("Stolen Soul") +local monster = {} + +monster.description = "a stolen soul" +monster.experience = 0 +monster.outfit = { + lookType = 294, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5000 +monster.maxHealth = 5000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 100 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 50, + armor = 50 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/summons/vermin_swarm.lua b/data/monster/quests/cults_of_tibia/bosses/summons/vermin_swarm.lua new file mode 100644 index 00000000000..6ed3c2ff148 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/summons/vermin_swarm.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Vermin Swarm") +local monster = {} + +monster.description = "a vermin swarm" +monster.experience = 0 +monster.outfit = { + lookType = 349, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5000 +monster.maxHealth = 5000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250, condition = {type = CONDITION_POISON, totalDamage = 16, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -400, range = 4, radius = 5, effect = CONST_ME_SMALLCLOUDS, target = true} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/summons/voidshard.lua b/data/monster/quests/cults_of_tibia/bosses/summons/voidshard.lua new file mode 100644 index 00000000000..dc9fde2d449 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/summons/voidshard.lua @@ -0,0 +1,103 @@ +local mType = Game.createMonsterType("Voidshard") +local monster = {} + +monster.description = "a voidshard" +monster.experience = 0 +monster.outfit = { + lookType = 878, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3500 +monster.maxHealth = 3500 +monster.race = "venom" +monster.corpse = 26209 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -350}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -168, maxDamage = -400, range = 6, radius = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_PURPLEENERGY, target = true}, + {name ="energy strike", interval = 2000, chance = 30, minDamage = -50, maxDamage = -180, range = 1, target = false}, + -- energy damage + {name ="condition", type = CONDITION_ENERGY, interval = 1000, chance = 15, radius = 3, effect = CONST_ME_YELLOWENERGY, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/the_armored_voidborn.lua b/data/monster/quests/cults_of_tibia/bosses/the_armored_voidborn.lua new file mode 100644 index 00000000000..8cb7aad98c6 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/the_armored_voidborn.lua @@ -0,0 +1,114 @@ +local mType = Game.createMonsterType("The Armored Voidborn") +local monster = {} + +monster.description = "The Armored Voidborn" +monster.experience = 0 +monster.outfit = { + lookType = 987, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 50 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -550}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -400, length = 7, spread = 5, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_ENERGYDAMAGE, minDamage = -250, maxDamage = -440, radius = 5, target = false} +} + +monster.defenses = { + defense = 50, + armor = 50 +} + +monster.reflects = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 99}, + {type = COMBAT_ENERGYDAMAGE, percent = 99}, + {type = COMBAT_EARTHDAMAGE, percent = 99}, + {type = COMBAT_FIREDAMAGE, percent = 99}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 99}, + {type = COMBAT_HOLYDAMAGE , percent = 99}, + {type = COMBAT_DEATHDAMAGE , percent = 99} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/the_corruptor_of_souls.lua b/data/monster/quests/cults_of_tibia/bosses/the_corruptor_of_souls.lua new file mode 100644 index 00000000000..21c4e44f8d4 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/the_corruptor_of_souls.lua @@ -0,0 +1,104 @@ +local mType = Game.createMonsterType("The Corruptor Of Souls") +local monster = {} + +monster.description = "The Corruptor Of Souls" +monster.experience = 112000 +monster.outfit = { + lookType = 875, + lookHead = 5, + lookBody = 5, + lookLegs = 5, + lookFeet = 5, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 290000 +monster.maxHealth = 290000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 450 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -150, maxDamage = -500}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -500, length = 9, spread = 7, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="remorseless wave", interval = 2000, chance = 25, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -500, radius = 7, effect = CONST_ME_HITAREA, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -500, length = 9, spread = 3, effect = CONST_ME_STUN, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -500, length = 9, spread = 3, effect = CONST_ME_MORTAREA, target = false} +} + +monster.defenses = { + defense = 100, + armor = 100 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/the_false_god.lua b/data/monster/quests/cults_of_tibia/bosses/the_false_god.lua new file mode 100644 index 00000000000..df0a2a4640b --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/the_false_god.lua @@ -0,0 +1,152 @@ +local mType = Game.createMonsterType("The False God") +local monster = {} + +monster.description = "The False God" +monster.experience = 75000 +monster.outfit = { + lookType = 984, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 300000 +monster.maxHealth = 300000 +monster.race = "blood" +monster.corpse = 25151 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 30 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "CREEEAK!", yell = false} +} + +monster.loot = { + {id = 7633, chance = 26900}, + {name = "magic sulphur", chance = 18920}, + {name = "mino shield", chance = 17620}, + {name = "silver token", chance = 1732}, + {name = "gold token", chance = 1532}, + {name = "gold coin", chance = 100000, maxCount = 200}, + {name = "platinum coin", chance = 29840, maxCount = 30}, + {name = "piece of hell steel", chance = 12370, maxCount = 9}, + {name = "red piece of cloth", chance = 16370, maxCount = 6}, + {name = "yellow gem", chance = 29460}, + {name = "blue gem", chance = 21892}, + {name = "underworld rod", chance = 117270}, + {name = "war axe", chance = 127270}, + {name = "pair of iron fists", chance = 9510}, + {name = "mysterious remains", chance = 100000}, + {name = "small diamond", chance = 12760, maxCount = 10}, + {name = "small amethyst", chance = 14700, maxCount = 10}, + {name = "small topaz", chance = 11520, maxCount = 10}, + {name = "small sapphire", chance = 13790, maxCount = 10}, + {name = "small emerald", chance = 14700, maxCount = 10}, + {name = "small amethyst", chance = 12259, maxCount = 10}, + {name = "energy bar", chance = 16872, maxCount = 3}, + {name = "ultimate health potion", chance = 27652, maxCount = 10}, + {name = "great mana potion", chance = 33721, maxCount = 10}, + {name = "great spirit potion", chance = 25690, maxCount = 5}, + {name = "piece of royal steel", chance = 15890}, + {name = "execowtioner axe", chance = 7890}, + {name = "maimer", chance = 1890}, + {name = "ornate mace", chance = 7890}, + {name = "velvet mantle", chance = 1890}, + {name = "iron ore", chance = 14542}, + {name = "giant sword", chance = 16892} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -500, range = 4, radius = 4, effect = CONST_ME_STONES, target = true}, + {name ="speed", interval = 2000, chance = 20, speedChange = -650, radius = 5, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/the_remorseless_corruptor.lua b/data/monster/quests/cults_of_tibia/bosses/the_remorseless_corruptor.lua new file mode 100644 index 00000000000..46805ca81fe --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/the_remorseless_corruptor.lua @@ -0,0 +1,104 @@ +local mType = Game.createMonsterType("The Remorseless Corruptor") +local monster = {} + +monster.description = "The Remorseless Corruptor" +monster.experience = 0 +monster.outfit = { + lookType = 875, + lookHead = 77, + lookBody = 98, + lookLegs = 3, + lookFeet = 85, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 290000 +monster.maxHealth = 290000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -150, maxDamage = -500}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -500, length = 9, spread = 3, effect = CONST_ME_LOSEENERGY, target = false}, + {name ="remorseless wave", interval = 2000, chance = 25, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -500, radius = 7, effect = CONST_ME_HITAREA, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -500, length = 9, spread = 3, effect = CONST_ME_STUN, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -500, length = 9, spread = 3, effect = CONST_ME_MORTAREA, target = false} +} + +monster.defenses = { + defense = 100, + armor = 100 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 99}, + {type = COMBAT_ENERGYDAMAGE, percent = 99}, + {type = COMBAT_EARTHDAMAGE, percent = 99}, + {type = COMBAT_FIREDAMAGE, percent = 99}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 99}, + {type = COMBAT_HOLYDAMAGE , percent = 99}, + {type = COMBAT_DEATHDAMAGE , percent = 99} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/the_sandking.lua b/data/monster/quests/cults_of_tibia/bosses/the_sandking.lua new file mode 100644 index 00000000000..369aa48876b --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/the_sandking.lua @@ -0,0 +1,157 @@ +local mType = Game.createMonsterType("The Sandking") +local monster = {} + +monster.description = "The Sandking" +monster.experience = 0 +monster.outfit = { + lookType = 1013, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "venom" +monster.corpse = 29142 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 30 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "CREEEAK!", yell = false} +} + +monster.loot = { + {name = "small amethyst", chance = 21000, maxCount = 10}, + {name = "small emerald", chance = 19000, maxCount = 10}, + {name = "red gem", chance = 12000}, + {name = "platinum coin", chance = 68299, maxCount = 30}, + {name = "gold coin", chance = 100000, maxCount = 200}, + {name = "small diamond", chance = 21000, maxCount = 10}, + {name = "green gem", chance = 12000}, + {name = "luminous orb", chance = 35000}, + {name = "great mana potion", chance = 31230, maxCount = 10}, + {name = "ultimate health potion", chance = 28230, maxCount = 10}, + {name = "cobra crown", chance = 400}, + {name = "silver token", chance = 2500}, + {name = "gold token", chance = 1532}, + {name = "small topaz", chance = 11520, maxCount = 10}, + {name = "blue gem", chance = 21892}, + {name = "yellow gem", chance = 29460}, + {name = "magic sulphur", chance = 18920}, + {id = 7440, chance = 2000}, + {id = 22396, chance = 2000, maxCount = 2}, + {name = "Hailstorm Rod", chance = 3470}, + {id = 2153, chance = 1000}, + {name = "ring of healing", chance = 20000}, + {id = 2147, chance = 7360, maxCount = 10}, + {id = 7632, chance = 28540}, + {name = "Skull Staff", chance = 13790}, + {name = "Grasshopper Legs", chance = 13790}, + {name = "Huge Chunk of Crude Iron", chance = 10000, maxCount = 2}, + {id = 7404, chance = 430}, + {name = "runed sword", chance = 6666}, + {name = "djinn blade", chance = 200}, + {id = 18415, chance = 10000, maxCount = 3}, + {id = 18414, chance = 10000, maxCount = 3}, + {id = 18413, chance = 10000, maxCount = 3}, + {id = 8472, chance = 4800}, + {id = 18451, chance = 7030}, + {id = 2453, chance = 200}, + {name = "heart of the mountain", chance = 400} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -500, range = 4, radius = 4, effect = CONST_ME_STONES, target = true}, + {name ="speed", interval = 2000, chance = 20, speedChange = -650, radius = 5, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/the_sandking_fake.lua b/data/monster/quests/cults_of_tibia/bosses/the_sandking_fake.lua new file mode 100644 index 00000000000..31ddc8e5efc --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/the_sandking_fake.lua @@ -0,0 +1,103 @@ +local mType = Game.createMonsterType("The Sandking Fake") +local monster = {} + +monster.name = "The Sandking" +monster.description = "The Sandking" +monster.experience = 0 +monster.outfit = { + lookType = 1013, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "venom" +monster.corpse = 29142 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 30 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "CREEEAK!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -500, range = 4, radius = 4, effect = CONST_ME_STONES, target = true}, + {name ="speed", interval = 2000, chance = 20, speedChange = -650, radius = 5, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/the_sinister_hermit_clean.lua b/data/monster/quests/cults_of_tibia/bosses/the_sinister_hermit_clean.lua new file mode 100644 index 00000000000..945609ded57 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/the_sinister_hermit_clean.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("The Sinister Hermit") +local monster = {} + +monster.description = "The Sinister Hermit" +monster.experience = 0 +monster.outfit = { + lookType = 153, + lookHead = 1, + lookBody = 30, + lookLegs = 30, + lookFeet = 11, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 30000 +monster.maxHealth = 30000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Vermin Swarm", chance = 100, interval = 20000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_EARTHDAMAGE, minDamage = -120, maxDamage = -488, length = 7, spread = 8, effect = CONST_ME_SMALLPLANTS, target = false} +} + +monster.defenses = { + defense = 50, + armor = 35, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 0, maxDamage = 800, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="shock head skill reducer 2", interval = 2000, chance = 30, radius = 8, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/the_sinister_hermit_dirty.lua b/data/monster/quests/cults_of_tibia/bosses/the_sinister_hermit_dirty.lua new file mode 100644 index 00000000000..08e5a07174d --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/the_sinister_hermit_dirty.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("The Sinister Hermit Dirty") +local monster = {} + +monster.name = "The Sinister Hermit" +monster.description = "The Sinister Hermit" +monster.experience = 0 +monster.outfit = { + lookType = 153, + lookHead = 1, + lookBody = 63, + lookLegs = 1, + lookFeet = 63, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 30000 +monster.maxHealth = 30000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Vermin Swarm", chance = 100, interval = 20000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_EARTHDAMAGE, minDamage = -120, maxDamage = -488, length = 7, spread = 8, effect = CONST_ME_SMALLPLANTS, target = false} +} + +monster.defenses = { + defense = 50, + armor = 35, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 0, maxDamage = 800, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="shock head skill reducer 2", interval = 2000, chance = 30, radius = 8, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/the_souldespoiler.lua b/data/monster/quests/cults_of_tibia/bosses/the_souldespoiler.lua new file mode 100644 index 00000000000..8e01eb8ee3f --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/the_souldespoiler.lua @@ -0,0 +1,163 @@ +local mType = Game.createMonsterType("The Souldespoiler") +local monster = {} + +monster.description = "The Souldespoiler" +monster.experience = 0 +monster.outfit = { + lookType = 875, + lookHead = 11, + lookBody = 0, + lookLegs = 94, + lookFeet = 95, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "blood" +monster.corpse = 26220 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 5 + +monster.changeTarget = { + interval = 6000, + chance = 30 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Freed Soul", chance = 5, interval = 5000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Urrg! I will not lose this soul!", yell = false}, + {text = "All souls shall be mine alone!", yell = false} +} + +monster.loot = { + {name = "curious matter", chance = 8920, maxCount = 10}, + {name = "spark sphere", chance = 21200, maxCount = 10}, + {id = 7633, chance = 26900}, + {name = "wand of defiance", chance = 8920}, + {name = "rift lance", chance = 13200}, + {name = "rift crossbow", chance = 7620}, + {name = "haunted blade", chance = 9700}, + {name = "silver token", chance = 2320}, + {name = "gold token", chance = 1532}, + {name = "sapphire hammer", chance = 14000}, + {name = "gold coin", chance = 100000, maxCount = 200}, + {name = "platinum coin", chance = 29840, maxCount = 35}, + {name = "wand of defiance", chance = 8723}, + {name = "yellow gem", chance = 29460}, + {name = "blue gem", chance = 21892}, + {name = "medusa shield", chance = 7270}, + {name = "underworld rod", chance = 9510}, + {name = "mysterious remains", chance = 100000}, + {name = "prismatic quartz", chance = 13390, maxCount = 10}, + {name = "small diamond", chance = 12760, maxCount = 10}, + {name = "small amethyst", chance = 14700, maxCount = 10}, + {name = "small topaz", chance = 11520, maxCount = 10}, + {name = "small sapphire", chance = 13790, maxCount = 10}, + {name = "small emerald", chance = 14700, maxCount = 10}, + {name = "small amethyst", chance = 12259, maxCount = 10}, + {name = "odd organ", chance = 100000}, + {name = "energy bar", chance = 16872, maxCount = 3}, + {name = "ultimate health potion", chance = 27652, maxCount = 10}, + {name = "great mana potion", chance = 33721, maxCount = 10}, + {name = "great spirit potion", chance = 25690, maxCount = 10}, + {name = "blade of corruption", chance = 3775}, + {name = "magma boots", chance = 15890}, + {name = "spellbook of lost souls", chance = 7890}, + {name = "shield of corruption", chance = 150}, + {name = "plasma pearls", chance = 100000}, + {name = "spiked squelcher", chance = 16892, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -783}, + {name ="combat", interval = 2000, chance = 60, type = COMBAT_DEATHDAMAGE, minDamage = -30, maxDamage = -181, range = 7, radius = 3, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_ENERGYDAMAGE, minDamage = -210, maxDamage = -538, length = 7, spread = 2, effect = CONST_ME_PURPLEENERGY, target = false}, + {name ="combat", interval = 3000, chance = 30, type = COMBAT_DROWNDAMAGE, minDamage = -125, maxDamage = -640, length = 9, spread = 3, effect = CONST_ME_LOSEENERGY, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 100, type = COMBAT_HEALING, minDamage = 1000, maxDamage = 7000, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/the_source_of_corruption.lua b/data/monster/quests/cults_of_tibia/bosses/the_source_of_corruption.lua new file mode 100644 index 00000000000..2ac36748d4d --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/the_source_of_corruption.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("The Source Of Corruption") +local monster = {} + +monster.description = "The Source Of Corruption" +monster.experience = 0 +monster.outfit = { + lookType = 979, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 500000 +monster.maxHealth = 500000 +monster.race = "undead" +monster.corpse = 26223 +monster.speed = 120 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1500}, + {name ="source of corruption wave", interval = 2000, chance = 15, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.reflects = { + {type = COMBAT_PHYSICALDAMAGE, percent = 15}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 15}, + {type = COMBAT_FIREDAMAGE, percent = 15}, + {type = COMBAT_LIFEDRAIN, percent = 15}, + {type = COMBAT_MANADRAIN, percent = 15}, + {type = COMBAT_DROWNDAMAGE, percent = 15}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 15}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/the_unarmored_voidborn.lua b/data/monster/quests/cults_of_tibia/bosses/the_unarmored_voidborn.lua new file mode 100644 index 00000000000..9df547b704f --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/the_unarmored_voidborn.lua @@ -0,0 +1,150 @@ +local mType = Game.createMonsterType("The Unarmored Voidborn") +local monster = {} + +monster.description = "The Unarmored Voidborn" +monster.experience = 15000 +monster.outfit = { + lookType = 987, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 250000 +monster.maxHealth = 250000 +monster.race = "undead" +monster.corpse = 29369 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 50 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "CHHRRR!", yell = false} +} + +monster.loot = { + {name = "magic sulphur", chance = 8920, maxCount = 10}, + {name = "gold ingot", chance = 21200, maxCount = 10}, + {id = 7633, chance = 26900}, + {name = "berserker", chance = 8920}, + {name = "abyss hammer", chance = 7620}, + {name = "skull helmet", chance = 9700}, + {name = "silver token", chance = 2732}, + {name = "gold token", chance = 1532}, + {name = "gold coin", chance = 100000, maxCount = 200}, + {name = "platinum coin", chance = 29840, maxCount = 25}, + {name = "yellow gem", chance = 29460}, + {name = "blue gem", chance = 21892}, + {name = "skull fetish", chance = 7270}, + {name = "bonebreaker", chance = 9510}, + {name = "mysterious remains", chance = 100000}, + {name = "small diamond", chance = 12760, maxCount = 10}, + {name = "small amethyst", chance = 14700, maxCount = 10}, + {name = "small topaz", chance = 11520, maxCount = 10}, + {name = "small sapphire", chance = 13790, maxCount = 10}, + {name = "small emerald", chance = 14700, maxCount = 10}, + {name = "small amethyst", chance = 12259, maxCount = 10}, + {name = "energy bar", chance = 16872, maxCount = 3}, + {name = "ultimate health potion", chance = 27652, maxCount = 10}, + {name = "great mana potion", chance = 33721, maxCount = 10}, + {name = "great spirit potion", chance = 25690, maxCount = 5}, + {id = 26198, chance = 12798},-- collar of blue plasma + {name = "piece of royal steel", chance = 15890}, + {name = "shadow sceptre", chance = 7890}, + {id = 26189, chance = 14542}, + {name = "terra hood", chance = 16892} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -550}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -400, length = 7, spread = 5, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_ENERGYDAMAGE, minDamage = -250, maxDamage = -440, radius = 5, target = false} +} + +monster.defenses = { + defense = 50, + armor = 50 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -300}, + {type = COMBAT_ENERGYDAMAGE, percent = -300}, + {type = COMBAT_EARTHDAMAGE, percent = -300}, + {type = COMBAT_FIREDAMAGE, percent = -300}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -300}, + {type = COMBAT_HOLYDAMAGE , percent = -300}, + {type = COMBAT_DEATHDAMAGE , percent = -300} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/wine_cask.lua b/data/monster/quests/cults_of_tibia/bosses/wine_cask.lua new file mode 100644 index 00000000000..acf0e6740f5 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/wine_cask.lua @@ -0,0 +1,93 @@ +local mType = Game.createMonsterType("Wine Cask") +local monster = {} + +monster.description = "a wine cask" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 1773 +} + +monster.health = 30000 +monster.maxHealth = 30000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "Splash" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 35, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -20}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/bosses/zarcorix_of_yalahar.lua b/data/monster/quests/cults_of_tibia/bosses/zarcorix_of_yalahar.lua new file mode 100644 index 00000000000..a00ca02acf8 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/bosses/zarcorix_of_yalahar.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("Zarcorix Of Yalahar") +local monster = {} + +monster.description = "Zarcorix Of Yalahar" +monster.experience = 0 +monster.outfit = { + lookType = 309, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 99999999 +monster.maxHealth = 99999999 +monster.race = "blood" +monster.corpse = 20550 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400} +} + +monster.defenses = { + defense = 0, + armor = 0 +} + +monster.reflects = { + {type = COMBAT_PHYSICALDAMAGE, percent = 300}, + {type = COMBAT_ENERGYDAMAGE, percent = 300}, + {type = COMBAT_EARTHDAMAGE, percent = 300}, + {type = COMBAT_FIREDAMAGE, percent = 300}, + {type = COMBAT_LIFEDRAIN, percent = 300}, + {type = COMBAT_MANADRAIN, percent = 300}, + {type = COMBAT_DROWNDAMAGE, percent = 300}, + {type = COMBAT_ICEDAMAGE, percent = 300}, + {type = COMBAT_HOLYDAMAGE , percent = 300}, + {type = COMBAT_DEATHDAMAGE , percent = 300} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/containment_machine.lua b/data/monster/quests/cults_of_tibia/containment_machine.lua new file mode 100644 index 00000000000..489a280f671 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/containment_machine.lua @@ -0,0 +1,86 @@ +local mType = Game.createMonsterType("Containment Machine") +local monster = {} + +monster.description = "a containment machine" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 9902 +} + +monster.health = 6500 +monster.maxHealth = 6500 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 50, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/cult_believer.lua b/data/monster/quests/cults_of_tibia/cult_believer.lua new file mode 100644 index 00000000000..308c104b86e --- /dev/null +++ b/data/monster/quests/cults_of_tibia/cult_believer.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Cult Believer") +local monster = {} + +monster.description = "a cult believer" +monster.experience = 850 +monster.outfit = { + lookType = 132, + lookHead = 98, + lookBody = 77, + lookLegs = 39, + lookFeet = 57, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 1512 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Forbidden Temple (Carlin)." + } + +monster.health = 975 +monster.maxHealth = 975 +monster.race = "blood" +monster.corpse = 24673 +monster.speed = 260 +monster.manaCost = 390 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Death to the unbelievers!", yell = false} +} + +monster.loot = { + {id = 2543, chance = 90450, maxCount = 10}, + {id = 2148, chance = 75410, maxCount = 30}, + {id = 2681, chance = 15400}, + {id = 7591, chance = 12340, maxCount = 2}, + {id = 2666, chance = 5000}, + {id = 2455, chance = 830}, + {id = 2652, chance = 760}, + {id = 2164, chance = 700, maxCount = 2}, + {id = 2120, chance = 1000}, + {id = 2661, chance = 1000}, + {id = 1949, chance = 830}, + {id = 2145, chance = 830}, + {id = 2391, chance = 130}, + {id = 2381, chance = 830}, + {id = 2515, chance = 330}, + {id = 2477, chance = 230}, + {id = 2475, chance = 200} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 10, maxDamage = -250} +} + +monster.defenses = { + defense = 50, + armor = 35, + {name ="combat", interval = 4000, chance = 25, type = COMBAT_HEALING, minDamage = 150, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -20}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/cult_enforcer.lua b/data/monster/quests/cults_of_tibia/cult_enforcer.lua new file mode 100644 index 00000000000..51490e81850 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/cult_enforcer.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Cult Enforcer") +local monster = {} + +monster.description = "a cult enforcer" +monster.experience = 1000 +monster.outfit = { + lookType = 134, + lookHead = 114, + lookBody = 19, + lookLegs = 76, + lookFeet = 76, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 1513 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Forbidden Temple (Carlin)." + } + +monster.health = 1150 +monster.maxHealth = 1150 +monster.race = "blood" +monster.corpse = 24673 +monster.speed = 260 +monster.manaCost = 390 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "No one will stop us!", yell = false} +} + +monster.loot = { + {id = 2543, chance = 90450, maxCount = 10}, + {id = 2148, chance = 75410, maxCount = 30}, + {id = 2681, chance = 15400}, + {id = 7591, chance = 12340, maxCount = 2}, + {id = 2666, chance = 5000}, + {id = 2455, chance = 830}, + {id = 2652, chance = 760}, + {id = 2164, chance = 700, maxCount = 2}, + {id = 2120, chance = 1000}, + {id = 2661, chance = 1000}, + {id = 1949, chance = 830}, + {id = 2145, chance = 830}, + {id = 2391, chance = 130}, + {id = 2381, chance = 830}, + {id = 2515, chance = 330}, + {id = 2477, chance = 230}, + {id = 2475, chance = 200} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 10, maxDamage = -360} +} + +monster.defenses = { + defense = 50, + armor = 35, + {name ="combat", interval = 4000, chance = 25, type = COMBAT_HEALING, minDamage = 150, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -20}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/cult_scholar.lua b/data/monster/quests/cults_of_tibia/cult_scholar.lua new file mode 100644 index 00000000000..9e621bf71c3 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/cult_scholar.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Cult Scholar") +local monster = {} + +monster.description = "a cult scholar" +monster.experience = 1100 +monster.outfit = { + lookType = 145, + lookHead = 0, + lookBody = 77, + lookLegs = 21, + lookFeet = 21, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 1514 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "Forbidden Temple (Carlin)." + } + +monster.health = 1650 +monster.maxHealth = 1650 +monster.race = "blood" +monster.corpse = 24673 +monster.speed = 260 +monster.manaCost = 390 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "The Secrets are ours alone!", yell = false} +} + +monster.loot = { + {id = 2543, chance = 90450, maxCount = 10}, + {id = 2148, chance = 75410, maxCount = 30}, + {id = 2681, chance = 15400}, + {id = 7591, chance = 12340, maxCount = 2}, + {id = 2666, chance = 5000}, + {id = 2455, chance = 830}, + {id = 2652, chance = 760}, + {id = 2164, chance = 700, maxCount = 2}, + {id = 2120, chance = 1000}, + {id = 2661, chance = 1000}, + {id = 1949, chance = 830}, + {id = 2145, chance = 830}, + {id = 2391, chance = 130}, + {id = 2381, chance = 830}, + {id = 2515, chance = 330}, + {id = 2477, chance = 230}, + {id = 2475, chance = 200} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 10, maxDamage = -580} +} + +monster.defenses = { + defense = 50, + armor = 35, + {name ="combat", interval = 4000, chance = 25, type = COMBAT_HEALING, minDamage = 20, maxDamage = 80, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/goldhanded_cultist.lua b/data/monster/quests/cults_of_tibia/goldhanded_cultist.lua new file mode 100644 index 00000000000..c994d4e6740 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/goldhanded_cultist.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Goldhanded Cultist") +local monster = {} + +monster.description = "a goldhanded cultist" +monster.experience = 2000 +monster.outfit = { + lookType = 132, + lookHead = 95, + lookBody = 79, + lookLegs = 41, + lookFeet = 94, + lookAddons = 2, + lookMount = 0 +} + +monster.raceId = 1481 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "Museum of Tibian Arts." + } + +monster.health = 3000 +monster.maxHealth = 3000 +monster.race = "blood" +monster.corpse = 3058 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Give me your money!", yell = false}, + {text = "Your backpack looks very compelling!", yell = false}, + {text = "You can't ever be rich enough!", yell = false} +} + +monster.loot = { + {name = "golden backpack", chance = 4290}, + {name = "tiger eye", chance = 11430}, + {id = 2148, chance = 41430, maxCount = 235}, + {name = "golden brush", chance = 20000}, + {name = "green gem", chance = 5710}, + {name = "gold ingot", chance = 2860}, + {name = "opal", chance = 11430}, + {name = "yellow gem", chance = 5710}, + {id = 1997, chance = 1430} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250}, + {name ="combat", interval = 3000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -150, radius = 5, target = false}, + {name ="combat", interval = 3000, chance = 10, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -200, effect = CONST_ME_LOSEENERGY, target = true}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -250, range = 5, radius = 2, target = true} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="speed", interval = 2000, chance = 30, speedChange = 290, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -30}, + {type = COMBAT_ENERGYDAMAGE, percent = -20}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/minotaur_idol.lua b/data/monster/quests/cults_of_tibia/minotaur_idol.lua new file mode 100644 index 00000000000..deb714a051d --- /dev/null +++ b/data/monster/quests/cults_of_tibia/minotaur_idol.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Minotaur Idol") +local monster = {} + +monster.description = "a minotaur idol" +monster.experience = 0 +monster.outfit = { + lookType = 1011, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5200 +monster.maxHealth = 5200 +monster.race = "undead" +monster.corpse = 29126 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -300, range = 4, radius = 4, shootEffect = CONST_ANI_WHIRLWINDCLUB, effect = CONST_ME_EXPLOSIONAREA, target = true} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 50, maxDamage = 100, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/misguided_bully.lua b/data/monster/quests/cults_of_tibia/misguided_bully.lua new file mode 100644 index 00000000000..ceaaa1579e6 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/misguided_bully.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Misguided Bully") +local monster = {} + +monster.description = "a misguided bully" +monster.experience = 1200 +monster.outfit = { + lookType = 159, + lookHead = 58, + lookBody = 22, + lookLegs = 41, + lookFeet = 76, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1412 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Misguided Camp accessible via Outlaw Camp's portal." + } + +monster.health = 2000 +monster.maxHealth = 2000 +monster.race = "blood" +monster.corpse = 29361 +monster.speed = 240 +monster.manaCost = 390 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Found one!", yell = false}, + {text = "Fortune brought you here, now let us lead you.", yell = false}, + {text = "You shall be guided.", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 153}, + {id = 28657, chance = 5610}, + {id = 9971, chance = 4930}, + {id = 2158, chance = 4630} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -320}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -180, maxDamage = -230, range = 7, shootEffect = CONST_ANI_SPEAR, target = true} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="heal monster", interval = 2000, chance = 20, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -1}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = -1}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -1}, + {type = COMBAT_HOLYDAMAGE , percent = 1}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/misguided_shadow.lua b/data/monster/quests/cults_of_tibia/misguided_shadow.lua new file mode 100644 index 00000000000..74db01c4d7d --- /dev/null +++ b/data/monster/quests/cults_of_tibia/misguided_shadow.lua @@ -0,0 +1,104 @@ +local mType = Game.createMonsterType("Misguided Shadow") +local monster = {} + +monster.description = "a misguided shadow" +monster.experience = 1200 +monster.outfit = { + lookType = 985, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3000 +monster.maxHealth = 3000 +monster.race = "blood" +monster.corpse = 29361 +monster.speed = 240 +monster.manaCost = 390 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Aiiiiiiieeeeeeeh...", yell = false} +} + +monster.loot = { + {id = 7588, chance = 15000}, + {id = 2156, chance = 6000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -350}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -180, maxDamage = -220, range = 6, length = 6, spread = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYAREA, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_HEALING, minDamage = 200, maxDamage = 450, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/misguided_thief.lua b/data/monster/quests/cults_of_tibia/misguided_thief.lua new file mode 100644 index 00000000000..e54bef4b162 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/misguided_thief.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Misguided Thief") +local monster = {} + +monster.description = "a misguided thief" +monster.experience = 1200 +monster.outfit = { + lookType = 684, + lookHead = 58, + lookBody = 58, + lookLegs = 41, + lookFeet = 76, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1413 +monster.Bestiary = { + class = "Human", + race = BESTY_RACE_HUMAN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Misguided Camp accessible via Outlaw Camp's portal." + } + +monster.health = 1800 +monster.maxHealth = 1800 +monster.race = "blood" +monster.corpse = 29361 +monster.speed = 240 +monster.manaCost = 390 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I spotted you!", yell = false}, + {text = "Let me show you your destiny!", yell = false}, + {text = "There is no escape now, friend.", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 80}, + {id = 7589, chance = 9660}, + {id = 2156, chance = 5680}, + {id = 2671, chance = 58520}, + {id = 7588, chance = 5680}, + {id = 2666, chance = 47160}, + {id = 2154, chance = 6250}, + {id = 28657, chance = 6250}, + {id = 18418, chance = 570} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -225}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -150, range = 7, shootEffect = CONST_ANI_FIRE, target = true} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_HEALING, minDamage = 200, maxDamage = 450, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -1}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = -1}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -1}, + {type = COMBAT_HOLYDAMAGE , percent = 1}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/orc_cult_fanatic.lua b/data/monster/quests/cults_of_tibia/orc_cult_fanatic.lua new file mode 100644 index 00000000000..c8a1954c3c0 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/orc_cult_fanatic.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Orc Cult Fanatic") +local monster = {} + +monster.description = "an orc cult fanatic" +monster.experience = 1100 +monster.outfit = { + lookType = 59, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1506 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "Edron Orc Cave." + } + +monster.health = 1300 +monster.maxHealth = 1300 +monster.race = "blood" +monster.corpse = 6001 +monster.speed = 115 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "WAAARRRG!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 135}, + {name = "sword ring", chance = 7770}, + {name = "plate shield", chance = 16350}, + {name = "plate armor", chance = 5900}, + {name = "brass legs", chance = 2950}, + {name = "plate legs", chance = 4830}, + {id = 2667, chance = 29760}, + {name = "great health potion", chance = 10190}, + {name = "orc tooth", chance = 1340}, + {name = "warrior helmet", chance = 10190}, + {name = "orc leather", chance = 22250}, + {name = "skull belt", chance = 13940}, + {name = "small ruby", chance = 10990, maxCount = 3}, + {name = "brown mushroom", chance = 15820, maxCount = 4}, + {name = "cultish robe", chance = 10460} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -250, maxDamage = -330, range = 7, shootEffect = CONST_ANI_THROWINGKNIFE, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/orc_cult_inquisitor.lua b/data/monster/quests/cults_of_tibia/orc_cult_inquisitor.lua new file mode 100644 index 00000000000..c383b5521d7 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/orc_cult_inquisitor.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Orc Cult Inquisitor") +local monster = {} + +monster.description = "an orc cult inquisitor" +monster.experience = 1150 +monster.outfit = { + lookType = 8, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1505 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Edron Orc Cave." + } + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "blood" +monster.corpse = 5980 +monster.speed = 125 +monster.manaCost = 590 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You unorcish scum will die!", yell = true} +} + +monster.loot = { + {name = "strong health potion", chance = 18390}, + {name = "gold coin", chance = 100000, maxCount = 221}, + {name = "black pearl", chance = 510, maxCount = 2}, + {name = "berserk potion", chance = 2940}, + {name = "small ruby", chance = 4020, maxCount = 5}, + {name = "battle axe", chance = 6340}, + {name = "bug meat", chance = 17160}, + {name = "red mushroom", chance = 7730, maxCount = 3}, + {name = "halberd", chance = 9890}, + {name = "orcish axe", chance = 850}, + {name = "cultish robe", chance = 9890}, + {name = "ham", chance = 8960}, + {name = "orc tooth", chance = 5410}, + {name = "orcish gear", chance = 15460}, + {name = "orc leather", chance = 7730} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -500} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="speed", interval = 2000, chance = 30, speedChange = 290, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/orc_cult_minion.lua b/data/monster/quests/cults_of_tibia/orc_cult_minion.lua new file mode 100644 index 00000000000..e06d3adea92 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/orc_cult_minion.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Orc Cult Minion") +local monster = {} + +monster.description = "an orc cult minion" +monster.experience = 850 +monster.outfit = { + lookType = 50, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1507 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Edron Orc Cave." + } + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "blood" +monster.corpse = 5996 +monster.speed = 105 +monster.manaCost = 310 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Orc powaaa!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 166}, + {name = "strong health potion", chance = 15930}, + {name = "small topaz", chance = 1238, maxCount = 3}, + {name = "orcish axe", chance = 9190}, + {name = "cultish robe", chance = 19360}, + {name = "red mushroom", chance = 6250, maxCount = 3}, + {name = "berserk potion", chance = 860, maxCount = 2}, + {name = "meat", chance = 4780} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -230}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -120, maxDamage = -170, range = 7, shootEffect = CONST_ANI_SPEAR, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/orc_cult_priest.lua b/data/monster/quests/cults_of_tibia/orc_cult_priest.lua new file mode 100644 index 00000000000..cb226a31414 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/orc_cult_priest.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Orc Cult Priest") +local monster = {} + +monster.description = "an orc cult priest" +monster.experience = 1000 +monster.outfit = { + lookType = 6, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1504 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "Edron Orc Cave." + } + +monster.health = 1300 +monster.maxHealth = 1300 +monster.race = "blood" +monster.corpse = 5978 +monster.speed = 70 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "We will crush all opposition!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 176}, + {name = "strong health potion", chance = 16340}, + {name = "small ruby", chance = 12870, maxCount = 6}, + {name = "black pearl", chance = 1980}, + {name = "cultish robe", chance = 18870}, + {name = "orc leather", chance = 8420, maxCount = 3}, + {name = "orc tooth", chance = 5940, maxCount = 2}, + {name = "green piece of cloth", chance = 12380}, + {name = "mysterious fetish", chance = 8910}, + {name = "shamanic hood", chance = 14360}, + {name = "broken shamanic staff", chance = 5940}, + {name = "heavy old tome", chance = 99} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -310, range = 7, shootEffect = CONST_ANI_ENERGYBALL, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -250, range = 7, radius = 1, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="outfit", interval = 4000, chance = 15, target = true, duration = 30000, outfitMonster = "orc warlord"}, + {name ="outfit", interval = 4000, chance = 10, target = true, duration = 30000, outfitMonster = "orc shaman"}, + {name ="outfit", interval = 4000, chance = 20, target = true, duration = 30000, outfitMonster = "orc"} +} + +monster.defenses = { + defense = 27, + armor = 27, + {name ="heal monster", interval = 2000, chance = 20, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/cults_of_tibia/orc_cultist.lua b/data/monster/quests/cults_of_tibia/orc_cultist.lua new file mode 100644 index 00000000000..be94187c849 --- /dev/null +++ b/data/monster/quests/cults_of_tibia/orc_cultist.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Orc Cultist") +local monster = {} + +monster.description = "an orc cultist" +monster.experience = 950 +monster.outfit = { + lookType = 7, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1503 +monster.Bestiary = { + class = "Humanoid", + race = BESTY_RACE_HUMANOID, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "Edron Orc Cave." + } + +monster.health = 1350 +monster.maxHealth = 1350 +monster.race = "blood" +monster.corpse = 5979 +monster.speed = 95 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "All power to the orcs!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 166}, + {name = "strong health potion", chance = 19830}, + {name = "small topaz", chance = 6002, maxCount = 3}, + {name = "orcish axe", chance = 9005}, + {name = "cultish robe", chance = 4960}, + {name = "ham", chance = 7020, maxCount = 3}, + {name = "orc tusk", chance = 8260, maxCount = 2}, + {name = "green piece of cloth", chance = 4960}, + {name = "brown crystal splinter", chance = 4960} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dangerous_depth/aggressive_lava.lua b/data/monster/quests/dangerous_depth/aggressive_lava.lua new file mode 100644 index 00000000000..8d45fcabfd2 --- /dev/null +++ b/data/monster/quests/dangerous_depth/aggressive_lava.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Aggressive Lava") +local monster = {} + +monster.description = "an aggressive lava" +monster.experience = 0 +monster.outfit = { + lookType = 614, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5000 +monster.maxHealth = 5000 +monster.race = "undead" +monster.corpse = 31996 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450}, + {name ="aggresivelavawave", interval = 2000, chance = 30, minDamage = 0, maxDamage = -650, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dangerous_depth/aggressive_matter.lua b/data/monster/quests/dangerous_depth/aggressive_matter.lua new file mode 100644 index 00000000000..376a4facf7c --- /dev/null +++ b/data/monster/quests/dangerous_depth/aggressive_matter.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Aggressive Matter") +local monster = {} + +monster.description = "a agressive matter" +monster.experience = 0 +monster.outfit = { + lookType = 615, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5000 +monster.maxHealth = 5000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 58, attack = 50, condition = {type = CONDITION_POISON, totalDamage = 280, interval = 4000}}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_EARTHDAMAGE, minDamage = -150, maxDamage = -250, range = 7, radius = 3, shootEffect = CONST_ANI_GLOOTHSPEAR, effect = CONST_ME_POISONAREA, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -150, maxDamage = -230, length = 6, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -200, maxDamage = -300, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true}, + {name ="rot elemental paralyze", interval = 2000, chance = 11, target = false} +} + +monster.defenses = { + defense = 15, + armor = 10, + {name ="combat", interval = 2000, chance = 7, type = COMBAT_HEALING, minDamage = 40, maxDamage = 60, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 9, speedChange = 470, effect = CONST_ME_SMOKE, target = false, duration = 7000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dangerous_depth/bosses/ancient_spawn_of_morgathla.lua b/data/monster/quests/dangerous_depth/bosses/ancient_spawn_of_morgathla.lua new file mode 100644 index 00000000000..ea7a56355fc --- /dev/null +++ b/data/monster/quests/dangerous_depth/bosses/ancient_spawn_of_morgathla.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Ancient Spawn of Morgathla") +local monster = {} + +monster.description = "an ancient spawn of morgathla" +monster.experience = 2400 +monster.outfit = { + lookType = 1055, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "blood" +monster.corpse = 23375 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 4 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I'm the one who puts the cute into execute!", yell = false}, + {text = "I'm here to punish!", yell = false}, + {text = "Justice is swift and unavoidable!", yell = false}, + {text = "I'll bring justice!", yell = false}, + {text = "There is excellence in execution!", yell = false}, + {text = "Your sentence is death!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 198}, + {id = 2152, chance = 67610, maxCount = 3}, + {id = 9971, chance = 390}, + {id = 5911, chance = 3230}, + {id = 5878, chance = 14710}, + {id = 12428, chance = 6580, maxCount = 2}, + {id = 23572, chance = 13160}, + {id = 7591, chance = 11480}, + {id = 7590, chance = 10060}, + {id = 2666, chance = 7230}, + {id = 9970, chance = 5810, maxCount = 2}, + {id = 2147, chance = 4520, maxCount = 2}, + {id = 7412, chance = 900}, + {id = 2487, chance = 770}, + {id = 23547, chance = 1420}, + {id = 2430, chance = 770}, + {id = 7413, chance = 390}, + {id = 7401, chance = 520} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 80}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_LIFEDRAIN, minDamage = -135, maxDamage = -280, range = 7, radius = 5, shootEffect = CONST_ANI_WHIRLWINDAXE, target = true}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_PHYSICALDAMAGE, minDamage = -90, maxDamage = -200, range = 7, shootEffect = CONST_ANI_WHIRLWINDAXE, effect = CONST_ME_EXPLOSIONAREA, target = true} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 1}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dangerous_depth/bosses/the_baron_from_below.lua b/data/monster/quests/dangerous_depth/bosses/the_baron_from_below.lua new file mode 100644 index 00000000000..c3a408d8c98 --- /dev/null +++ b/data/monster/quests/dangerous_depth/bosses/the_baron_from_below.lua @@ -0,0 +1,163 @@ +local mType = Game.createMonsterType("The Baron From Below") +local monster = {} + +monster.description = "The Baron From Below" +monster.experience = 40000 +monster.outfit = { + lookType = 1045, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "blood" +monster.corpse = 30868 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Krrrk!", yell = false} +} + +monster.loot = { + {name = "Platinum Coin", chance = 10000, maxCount = 58}, + {name = "crystal coin", chance = 10000, maxCount = 2}, + {name = "gold ingot", chance = 10000, maxCount = 2}, + {name = "great mana potion", chance = 10000, maxCount = 10}, + {name = "great spirit potion", chance = 10000, maxCount = 18}, + {name = "mastermind potion", chance = 10000, maxCount = 2}, + {name = "small diamond", chance = 10000, maxCount = 12}, + {name = "small emerald", chance = 10000, maxCount = 12}, + {name = "small ruby", chance = 10000, maxCount = 12}, + {name = "small topaz", chance = 10000, maxCount = 12}, + {name = "ultimate health potion", chance = 10000, maxCount = 8}, + {name = "violet crystal shard", chance = 10000, maxCount = 3}, + {name = "badger boots", chance = 10000}, + {name = "blue gem", chance = 10000}, + {name = "Calopteryx Cape", chance = 10000}, + {id = 30857, chance = 10000}, + {name = "Crystal Mace", chance = 10000}, + {name = "Fire Sword", chance = 10000}, + {name = "Green Gem", chance = 10000}, + {name = "Huge Chunk of Crude Iron", chance = 10000, maxCount = 2}, + {name = "Huge Shell", chance = 10000}, + {name = "Longing Eyes", chance = 10000}, + {name = "Luminous Orb", chance = 10000}, + {name = "Magic Sulphur", chance = 10000, maxCount = 2}, + {name = "Magma Coat", chance = 10000}, + {name = "Red Gem", chance = 10000}, + {id = 9820, chance = 10000}, + {id = 9814, chance = 10000}, + {name = "Slimy Leg", chance = 10000}, + {name = "Stone Skin Amulet", chance = 10000}, + {name = "Violet Gem", chance = 10000}, + {name = "Wand of Inferno", chance = 10000}, + {name = "Yellow Gem", chance = 10000}, + {name = "Gold Token", chance = 1000}, + {name = "Silver Token", chance = 1000}, + {name = "Mallet Head", chance = 1000}, + {name = "Gnome Shield", chance = 1000}, + {name = "Gnome Sword", chance = 1000}, + {name = "plan for a makeshift armour", chance = 500}, + {name = "Gnome Armor", chance = 500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -550}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -1000, radius = 8, effect = CONST_ME_HITAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -1000, length = 8, spread = 5, effect = CONST_ME_YELLOW_RINGS, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -1000, length = 8, spread = 9, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 2000, chance = 100, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -1000, radius = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -1000, radius = 5, effect = CONST_ME_SMALLPLANTS, target = false} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 60}, + {type = COMBAT_ENERGYDAMAGE, percent = 60}, + {type = COMBAT_EARTHDAMAGE, percent = 60}, + {type = COMBAT_FIREDAMAGE, percent = 60}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 60}, + {type = COMBAT_HOLYDAMAGE , percent = 60}, + {type = COMBAT_DEATHDAMAGE , percent = 60} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/dangerous_depth/bosses/the_count_of_the_core.lua b/data/monster/quests/dangerous_depth/bosses/the_count_of_the_core.lua new file mode 100644 index 00000000000..adec97714cb --- /dev/null +++ b/data/monster/quests/dangerous_depth/bosses/the_count_of_the_core.lua @@ -0,0 +1,164 @@ +local mType = Game.createMonsterType("The Count Of The Core") +local monster = {} + +monster.description = "The Count Of The Core" +monster.experience = 40000 +monster.outfit = { + lookType = 1046, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "blood" +monster.corpse = 30872 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Sluuuurp! Sluuuuurp!", yell = false}, + {text = "Shluush!", yell = false} +} + +monster.loot = { + {name = "Platinum Coin", chance = 10000, maxCount = 36}, + {name = "Great Mana Potion", chance = 10000, maxCount = 18}, + {name = "Great Spirit Potion", chance = 10000, maxCount = 10}, + {name = "Green Crystal Shard", chance = 10000, maxCount = 4}, + {name = "Huge Chunk of Crude Iron", chance = 10000, maxCount = 2}, + {name = "Magic Sulphur", chance = 10000, maxCount = 2}, + {name = "Mastermind Potion", chance = 10000, maxCount = 2}, + {name = "Small Amethyst", chance = 10000, maxCount = 10}, + {name = "Small Diamond", chance = 10000, maxCount = 10}, + {name = "Small Emerald", chance = 10000, maxCount = 12}, + {name = "Small Ruby", chance = 10000, maxCount = 10}, + {name = "Small Topaz", chance = 10000, maxCount = 10}, + {name = "Ultimate Health Potion", chance = 10000, maxCount = 5}, + {name = "Amber Staff", chance = 10000}, + {name = "Blue Gem", chance = 10000}, + {id = 30861, chance = 10000}, + {name = "Crystal Coin", chance = 10000}, + {name = "Crystalline Armor", chance = 5000}, + {name = "Dragon Necklace", chance = 10000}, + {name = "Fire Axe", chance = 10000}, + {name = "Fire Sword", chance = 10000}, + {id = 7632, chance = 10000}, + {name = "Giant Sword", chance = 10000}, + {name = "Guardian Axe", chance = 10000}, + {name = "Gold Token", chance = 10000}, + {name = "Green Gem", chance = 10000}, + {name = "Harpoon of a Giant Snail", chance = 10000}, + {name = "Huge Spiky Snail Shell", chance = 10000}, + {name = "Luminous Orb", chance = 10000}, + {name = "Red Gem", chance = 10000}, + {name = "Silver Token", chance = 1000}, + {name = "Stone Skin Amulet", chance = 1000}, + {name = "Twiceslicer", chance = 1000}, + {name = "Wand of Inferno", chance = 1000}, + {name = "Yellow Gem", chance = 1000}, + {name = "Candle Stump", chance = 1000}, + {name = "Gnome Shield", chance = 1000}, + {name = "Gnome Sword", chance = 1000}, + {name = "Mallet Handle", chance = 1000}, + {name = "Tinged Pot", chance = 1000}, + {name = "Gnome Helmet", chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1500}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -1500, range = 3, length = 9, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -1500, range = 3, length = 9, spread = 4, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -1500, radius = 8, effect = CONST_ME_HITAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -1500, radius = 8, effect = CONST_ME_BLACKSMOKE, target = false} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 60}, + {type = COMBAT_ENERGYDAMAGE, percent = 60}, + {type = COMBAT_EARTHDAMAGE, percent = 60}, + {type = COMBAT_FIREDAMAGE, percent = -100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 60}, + {type = COMBAT_HOLYDAMAGE , percent = 60}, + {type = COMBAT_DEATHDAMAGE , percent = 60} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/dangerous_depth/bosses/the_duke_of_the_depths.lua b/data/monster/quests/dangerous_depth/bosses/the_duke_of_the_depths.lua new file mode 100644 index 00000000000..dbbec64ccb7 --- /dev/null +++ b/data/monster/quests/dangerous_depth/bosses/the_duke_of_the_depths.lua @@ -0,0 +1,154 @@ +local mType = Game.createMonsterType("The Duke Of The Depths") +local monster = {} + +monster.description = "The Duke Of The Depths" +monster.experience = 40000 +monster.outfit = { + lookType = 1047, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "blood" +monster.corpse = 32008 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 50 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2152, chance = 67610, maxCount = 58}, + {id = 2160, chance = 67610}, + {id = 18413, chance = 14710, maxCount = 4}, + {id = 2149, chance = 13160, maxCount = 12}, + {id = 9970, chance = 11480, maxCount = 12}, + {id = 2150, chance = 14520, maxCount = 12}, + {id = 7590, chance = 14520, maxCount = 18}, + {id = 2145, chance = 14520, maxCount = 2}, + {id = 2147, chance = 14520, maxCount = 12}, + {id = 7591, chance = 14520, maxCount = 8}, + {id = 8472, chance = 14520, maxCount = 10}, + {id = 8473, chance = 14520, maxCount = 8}, + {id = 7440, chance = 10060}, + {id = 2156, chance = 14520}, + {id = 2154, chance = 14520}, + {id = 30854, chance = 10000}, + {id = 9814, chance = 17230}, + {id = 5892, chance = 14520}, + {id = 2187, chance = 14520}, + {id = 2432, chance = 15810}, + {id = 2392, chance = 14520}, + {id = 7884, chance = 14520}, + {id = 12410, chance = 14520}, + {id = 2197, chance = 14520}, + {id = 9822, chance = 14520}, + {id = 5904, chance = 14520}, + {id = 30892, chance = 1000}, + {id = 30886, chance = 600}, + {id = 30884, chance = 510}, + {id = 30885, chance = 560}, + {id = 25377, chance = 580}, + {id = 30761, chance = 520}, + {id = 30883, chance = 400} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -800}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = 0, maxDamage = -1000, range = 3, length = 6, spread = 8, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = 0, maxDamage = -1000, range = 3, length = 9, spread = 4, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -135, maxDamage = -1000, radius = 2, effect = CONST_ME_EXPLOSIONAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -1000, radius = 8, effect = CONST_ME_HITAREA, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 60}, + {type = COMBAT_ENERGYDAMAGE, percent = 60}, + {type = COMBAT_EARTHDAMAGE, percent = 60}, + {type = COMBAT_FIREDAMAGE, percent = -100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 60}, + {type = COMBAT_HOLYDAMAGE , percent = 60}, + {type = COMBAT_DEATHDAMAGE , percent = 60} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/dangerous_depth/bosses/the_duke_of_the_depths_immortal.lua b/data/monster/quests/dangerous_depth/bosses/the_duke_of_the_depths_immortal.lua new file mode 100644 index 00000000000..c55370fda51 --- /dev/null +++ b/data/monster/quests/dangerous_depth/bosses/the_duke_of_the_depths_immortal.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("The Duke Of The Depths") +local monster = {} + +monster.description = "The Duke Of The Depths" +monster.experience = 40000 +monster.outfit = { + lookType = 1047, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 100000 +monster.maxHealth = 100000 +monster.race = "blood" +monster.corpse = 32008 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 50 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Chhhhhhh!", yell = false}, + {text = "SzzzzSzzz! SzzzzSzzz!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 198}, + {id = 2152, chance = 67610, maxCount = 3}, + {id = 9971, chance = 390}, + {id = 5911, chance = 3230}, + {id = 5878, chance = 14710}, + {id = 12428, chance = 6580, maxCount = 2}, + {id = 23572, chance = 13160}, + {id = 7591, chance = 11480}, + {id = 7590, chance = 10060}, + {id = 2666, chance = 7230}, + {id = 9970, chance = 5810, maxCount = 2}, + {id = 2147, chance = 4520, maxCount = 2}, + {id = 7412, chance = 900}, + {id = 2487, chance = 770}, + {id = 23547, chance = 1420}, + {id = 2430, chance = 770}, + {id = 7413, chance = 390}, + {id = 7401, chance = 520} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1300}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = 0, maxDamage = -1500, range = 3, length = 6, spread = 8, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = 0, maxDamage = -1500, range = 3, length = 9, spread = 4, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -135, maxDamage = -1500, radius = 2, effect = CONST_ME_EXPLOSIONAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -1500, radius = 8, effect = CONST_ME_HITAREA, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dangerous_depth/bosses/the_hungry_baron_from_below.lua b/data/monster/quests/dangerous_depth/bosses/the_hungry_baron_from_below.lua new file mode 100644 index 00000000000..96876c743a7 --- /dev/null +++ b/data/monster/quests/dangerous_depth/bosses/the_hungry_baron_from_below.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("The Hungry Baron From Below") +local monster = {} + +monster.description = "The Hungry Baron From Below" +monster.experience = 40000 +monster.outfit = { + lookType = 1045, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "blood" +monster.corpse = 30868 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Krrrk!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -550}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -1000, radius = 8, effect = CONST_ME_HITAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -1000, length = 8, spread = 5, effect = CONST_ME_YELLOW_RINGS, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -1000, length = 8, spread = 9, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 2000, chance = 100, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -1000, radius = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -1000, radius = 5, effect = CONST_ME_SMALLPLANTS, target = false} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dangerous_depth/captured_dwarf.lua b/data/monster/quests/dangerous_depth/captured_dwarf.lua new file mode 100644 index 00000000000..535e54adf40 --- /dev/null +++ b/data/monster/quests/dangerous_depth/captured_dwarf.lua @@ -0,0 +1,95 @@ +local mType = Game.createMonsterType("Captured Dwarf") +local monster = {} + +monster.description = "a captured dwarf" +monster.experience = 0 +monster.outfit = { + lookType = 538, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 100 +monster.maxHealth = 100 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 0, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dangerous_depth/ember_beast.lua b/data/monster/quests/dangerous_depth/ember_beast.lua new file mode 100644 index 00000000000..f7fe27033c7 --- /dev/null +++ b/data/monster/quests/dangerous_depth/ember_beast.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Ember Beast") +local monster = {} + +monster.description = "an ember beast" +monster.experience = 0 +monster.outfit = { + lookType = 498, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 4000 +monster.maxHealth = 4000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="emberbeastarea", interval = 1000, chance = 20, minDamage = -200, maxDamage = -450, target = false}, + {name ="emberbeasthur", interval = 2000, chance = 10, minDamage = -200, maxDamage = -450, target = false} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dangerous_depth/fiery_blood.lua b/data/monster/quests/dangerous_depth/fiery_blood.lua new file mode 100644 index 00000000000..fc61b2699ce --- /dev/null +++ b/data/monster/quests/dangerous_depth/fiery_blood.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Fiery Blood") +local monster = {} + +monster.description = "a fiery blood" +monster.experience = 0 +monster.outfit = { + lookType = 49, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5000 +monster.maxHealth = 5000 +monster.race = "undead" +monster.corpse = 8964 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250}, + {name ="aggresivelavawave", interval = 2000, chance = 30, minDamage = 0, maxDamage = -500, target = false}, + {name ="firefield", interval = 2000, chance = 25, range = 7, radius = 3, shootEffect = CONST_ANI_FIRE, target = true} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dangerous_depth/fiery_heart.lua b/data/monster/quests/dangerous_depth/fiery_heart.lua new file mode 100644 index 00000000000..dce319134de --- /dev/null +++ b/data/monster/quests/dangerous_depth/fiery_heart.lua @@ -0,0 +1,93 @@ +local mType = Game.createMonsterType("Fiery Heart") +local monster = {} + +monster.description = "a fiery heart" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 389 +} + +monster.health = 5000 +monster.maxHealth = 5000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 1 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="aggresivelavawave", interval = 2000, chance = 30, minDamage = 0, maxDamage = -550, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dangerous_depth/gnome_pack_crawler.lua b/data/monster/quests/dangerous_depth/gnome_pack_crawler.lua new file mode 100644 index 00000000000..803a7941e2e --- /dev/null +++ b/data/monster/quests/dangerous_depth/gnome_pack_crawler.lua @@ -0,0 +1,96 @@ +local mType = Game.createMonsterType("Gnome Pack Crawler") +local monster = {} + +monster.description = "a gnome pack crawler" +monster.experience = 0 +monster.outfit = { + lookType = 492, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5000 +monster.maxHealth = 5000 +monster.race = "fire" +monster.corpse = 17336 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 199} +} + +monster.defenses = { + defense = 45, + armor = 45 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 1}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dangerous_depth/lava_lurker_attendant.lua b/data/monster/quests/dangerous_depth/lava_lurker_attendant.lua new file mode 100644 index 00000000000..feee970337d --- /dev/null +++ b/data/monster/quests/dangerous_depth/lava_lurker_attendant.lua @@ -0,0 +1,97 @@ +local mType = Game.createMonsterType("Lava Lurker Attendant") +local monster = {} + +monster.description = "a lava lurker attendant" +monster.experience = 0 +monster.outfit = { + lookType = 1041, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3000 +monster.maxHealth = 3000 +monster.race = "fire" +monster.corpse = 31997 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_FIREDAMAGE, minDamage = 90, maxDamage = -175, radius = 4, effect = CONST_ME_FIREAREA, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -1}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dangerous_depth/lost_gnome.lua b/data/monster/quests/dangerous_depth/lost_gnome.lua new file mode 100644 index 00000000000..da83f14ab48 --- /dev/null +++ b/data/monster/quests/dangerous_depth/lost_gnome.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Lost Gnome") +local monster = {} + +monster.description = "a lost gnome" +monster.experience = 0 +monster.outfit = { + lookType = 493, + lookHead = 10, + lookBody = 32, + lookLegs = 15, + lookFeet = 7, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Are we there yet?", yell = false}, + {text = "Think I saw a nice gem back there, I need to...", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 10000, maxCount = 2}, + {name = "heavy old tome", chance = 10000, maxCount = 2} +} + +monster.defenses = { + defense = 33, + armor = 45 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dangerous_depth/makeshift_home.lua b/data/monster/quests/dangerous_depth/makeshift_home.lua new file mode 100644 index 00000000000..45015215307 --- /dev/null +++ b/data/monster/quests/dangerous_depth/makeshift_home.lua @@ -0,0 +1,94 @@ +local mType = Game.createMonsterType("Makeshift Home") +local monster = {} + +monster.description = "a makeshift home" +monster.experience = 1800 +monster.outfit = { + lookTypeEx = 30601 +} + +monster.health = 6900 +monster.maxHealth = 6900 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -120, maxDamage = -200}, + {name ="combat", interval = 2000, chance = 60, type = COMBAT_PHYSICALDAMAGE, minDamage = -70, maxDamage = -230, range = 3, shootEffect = CONST_ANI_ARROW, target = true} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -20} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dangerous_depth/organic_matter.lua b/data/monster/quests/dangerous_depth/organic_matter.lua new file mode 100644 index 00000000000..a04360ea5ac --- /dev/null +++ b/data/monster/quests/dangerous_depth/organic_matter.lua @@ -0,0 +1,95 @@ +local mType = Game.createMonsterType("Organic Matter") +local monster = {} + +monster.description = "an organic matter" +monster.experience = 0 +monster.outfit = { + lookType = 617, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 55, + armor = 55 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dangerous_depth/snail_slime.lua b/data/monster/quests/dangerous_depth/snail_slime.lua new file mode 100644 index 00000000000..b0bd50c8d6e --- /dev/null +++ b/data/monster/quests/dangerous_depth/snail_slime.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Snail Slime") +local monster = {} + +monster.description = "a snail slime" +monster.experience = 160 +monster.outfit = { + lookType = 19, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -600} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dark_trails/canopic_jar.lua b/data/monster/quests/dark_trails/canopic_jar.lua new file mode 100644 index 00000000000..0dcc9c552d4 --- /dev/null +++ b/data/monster/quests/dark_trails/canopic_jar.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Canopic Jar") +local monster = {} + +monster.description = "a canopic jar" +monster.experience = 0 +monster.outfit = { + lookType = 598, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = true, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_HEALING, minDamage = 200, maxDamage = 500, radius = 7, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_HEALING, minDamage = 200, maxDamage = 700, radius = 5, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dark_trails/death_priest_shargon.lua b/data/monster/quests/dark_trails/death_priest_shargon.lua new file mode 100644 index 00000000000..429b8669bcf --- /dev/null +++ b/data/monster/quests/dark_trails/death_priest_shargon.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Death Priest Shargon") +local monster = {} + +monster.description = "Death Priest Shargon" +monster.experience = 20000 +monster.outfit = { + lookType = 278, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 65000 +monster.maxHealth = 65000 +monster.race = "blood" +monster.corpse = 23494 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 6 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "DeathPriestShargonDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Lesser Death Minion", chance = 30, interval = 2000, max = 2}, + {name = "Superior Death Minion", chance = 30, interval = 2000, max = 2}, + {name = "Greater Death Minion", chance = 30, interval = 2000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 99}, + {id = 7591, chance = 100000, maxCount = 3}, + {id = 2185, chance = 100000}, + {id = 2152, chance = 100000, maxCount = 13}, + {id = 7590, chance = 10000, maxCount = 4}, + {id = 9971, chance = 25000}, + {id = 9969, chance = 9090}, + {id = 9447, chance = 9090} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 200, attack = 150}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -660, range = 7, radius = 6, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_HOLYDAMAGE, minDamage = -350, maxDamage = -1000, length = 6, spread = 2, effect = CONST_ME_PURPLEENERGY, target = false} +} + +monster.defenses = { + defense = 30, + armor = 25, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 0, maxDamage = 699, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dark_trails/depowered_minotaur.lua b/data/monster/quests/dark_trails/depowered_minotaur.lua new file mode 100644 index 00000000000..c3be38ecab1 --- /dev/null +++ b/data/monster/quests/dark_trails/depowered_minotaur.lua @@ -0,0 +1,103 @@ +local mType = Game.createMonsterType("Depowered Minotaur") +local monster = {} + +monster.description = "a depowered minotaur" +monster.experience = 1100 +monster.outfit = { + lookType = 25, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "blood" +monster.corpse = 5969 +monster.speed = 212 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I want my power back!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 82}, + {id = 12428, chance = 100000}, + {id = 2152, chance = 100000, maxCount = 4}, + {id = 7588, chance = 25000}, + {id = 5878, chance = 25000}, + {id = 2146, chance = 25000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 80, attack = 45} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dark_trails/greater_canopic_jar.lua b/data/monster/quests/dark_trails/greater_canopic_jar.lua new file mode 100644 index 00000000000..e0ce4dcd69e --- /dev/null +++ b/data/monster/quests/dark_trails/greater_canopic_jar.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Greater Canopic Jar") +local monster = {} + +monster.description = "a greater canopic jar" +monster.experience = 0 +monster.outfit = { + lookType = 599, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 7000 +monster.maxHealth = 7000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = true, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_HEALING, minDamage = 1000, maxDamage = 1500, radius = 7, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dark_trails/greater_death_minion.lua b/data/monster/quests/dark_trails/greater_death_minion.lua new file mode 100644 index 00000000000..0d5f7dec7cb --- /dev/null +++ b/data/monster/quests/dark_trails/greater_death_minion.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Greater Death Minion") +local monster = {} + +monster.description = "a greater death minion" +monster.experience = 0 +monster.outfit = { + lookType = 65, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "undead" +monster.corpse = 6004 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 98, attack = 75} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dark_trails/lesser_death_minion.lua b/data/monster/quests/dark_trails/lesser_death_minion.lua new file mode 100644 index 00000000000..a969914151d --- /dev/null +++ b/data/monster/quests/dark_trails/lesser_death_minion.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Lesser Death Minion") +local monster = {} + +monster.description = "a lesser death minion" +monster.experience = 35 +monster.outfit = { + lookType = 33, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 550 +monster.maxHealth = 550 +monster.race = "undead" +monster.corpse = 5972 +monster.speed = 154 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 70, attack = 80}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_LIFEDRAIN, minDamage = -7, maxDamage = -13, range = 1, target = false} +} + +monster.defenses = { + defense = 9, + armor = 2 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dark_trails/minotaur_invader.lua b/data/monster/quests/dark_trails/minotaur_invader.lua new file mode 100644 index 00000000000..5123a872ec3 --- /dev/null +++ b/data/monster/quests/dark_trails/minotaur_invader.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Minotaur Invader") +local monster = {} + +monster.description = "a minotaur invader" +monster.experience = 1600 +monster.outfit = { + lookType = 29, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1850 +monster.maxHealth = 1850 +monster.race = "blood" +monster.corpse = 5983 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "For the victory!", yell = false}, + {text = "We will crush the enemy!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 175}, + {id = 2152, chance = 100000, maxCount = 4}, + {id = 12428, chance = 14285, maxCount = 2}, + {id = 9970, chance = 10000}, + {id = 12438, chance = 9090}, + {id = 2150, chance = 7692}, + {id = 5878, chance = 5000}, + {id = 2147, chance = 3703}, + {id = 2430, chance = 1250}, + {id = 2515, chance = 1250}, + {id = 2156, chance = 1250}, + {id = 5911, chance = 1250} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 85, attack = 75} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dark_trails/minotaur_totem.lua b/data/monster/quests/dark_trails/minotaur_totem.lua new file mode 100644 index 00000000000..6c2be776662 --- /dev/null +++ b/data/monster/quests/dark_trails/minotaur_totem.lua @@ -0,0 +1,93 @@ +local mType = Game.createMonsterType("Minotaur Totem") +local monster = {} + +monster.description = "a minotaur totem" +monster.experience = 500 +monster.outfit = { + lookTypeEx = 3802 +} + +monster.health = 6000 +monster.maxHealth = 6000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 78 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 16 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = true, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 4000, chance = 15, type = COMBAT_HEALING, minDamage = 0, maxDamage = 1000, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dark_trails/superior_death_minion.lua b/data/monster/quests/dark_trails/superior_death_minion.lua new file mode 100644 index 00000000000..61898bdf9fe --- /dev/null +++ b/data/monster/quests/dark_trails/superior_death_minion.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Superior Death Minion") +local monster = {} + +monster.description = "a superior death minion" +monster.experience = 0 +monster.outfit = { + lookType = 84, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2500 +monster.maxHealth = 2500 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 200 +monster.manaCost = 490 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 125, attack = 90} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dark_trails/the_ravager.lua b/data/monster/quests/dark_trails/the_ravager.lua new file mode 100644 index 00000000000..f7b60eede60 --- /dev/null +++ b/data/monster/quests/dark_trails/the_ravager.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("The Ravager") +local monster = {} + +monster.description = "The Ravager" +monster.experience = 14980 +monster.outfit = { + lookType = 87, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 53500 +monster.maxHealth = 53500 +monster.race = "undead" +monster.corpse = 6031 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 16 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "TheRavagerDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Elder Mummy", chance = 9, interval = 2000, max = 4}, + {name = "Canopic Jar", chance = 9, interval = 2000, max = 4}, + {name = "Greater Canopic Jar", chance = 9, interval = 2000, max = 8} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 95000, maxCount = 243}, + {id = 7590, chance = 10000, maxCount = 5}, + {id = 7591, chance = 5000, maxCount = 5}, + {id = 2152, chance = 37500, maxCount = 5}, + {id = 2159, chance = 15000, maxCount = 5}, + {id = 2440, chance = 5000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 82, attack = 70, condition = {type = CONDITION_POISON, totalDamage = 320, interval = 4000}}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_DEATHDAMAGE, minDamage = -200, maxDamage = -750, range = 7, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_DEATHDAMAGE, minDamage = -700, maxDamage = -880, length = 8, spread = 3, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_LIFEDRAIN, minDamage = -400, maxDamage = -500, length = 7, spread = 3, effect = CONST_ME_SMOKE, target = false} +} + +monster.defenses = { + defense = 30, + armor = 25, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 200, maxDamage = 400, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 35}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/dark_trails/tremor_worm.lua b/data/monster/quests/dark_trails/tremor_worm.lua new file mode 100644 index 00000000000..0f36535c254 --- /dev/null +++ b/data/monster/quests/dark_trails/tremor_worm.lua @@ -0,0 +1,102 @@ +local mType = Game.createMonsterType("tremor worm") +local monster = {} + +monster.description = "a tremor worm" +monster.experience = 80000 +monster.outfit = { + lookType = 295, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 125000 +monster.maxHealth = 125000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 170 +monster.manaCost = 330 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2152, chance = 33000, maxCount = 5}, + {id = 7591, chance = 10000}, + {id = 7590, chance = 10000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 80} +} + +monster.defenses = { + defense = 100, + armor = 100 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 75}, + {type = COMBAT_ENERGYDAMAGE, percent = 75}, + {type = COMBAT_EARTHDAMAGE, percent = 75}, + {type = COMBAT_FIREDAMAGE, percent = 75}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 75}, + {type = COMBAT_HOLYDAMAGE , percent = 75}, + {type = COMBAT_DEATHDAMAGE , percent = 75} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/feaster_of_souls/irgix_the_flimsy.lua b/data/monster/quests/feaster_of_souls/irgix_the_flimsy.lua new file mode 100644 index 00000000000..f9e2405ec00 --- /dev/null +++ b/data/monster/quests/feaster_of_souls/irgix_the_flimsy.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Irgix The Flimsy") +local monster = {} + +monster.description = "Irgix The Flimsy" +monster.experience = 18000 +monster.outfit = { + lookType = 1268, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 24000 +monster.maxHealth = 24000 +monster.race = "undead" +monster.corpse = 37445 +monster.speed = 285 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 10000, maxCount = 8}, + {name = "skull coin", chance = 66670}, + {name = "diamond", chance = 50000}, + {name = "silver hand mirror", chance = 41670, maxCount = 2}, + {name = "white gem", chance = 33333}, + {name = "terra rod", chance = 16670}, + {name = "yellow gem", chance = 16670}, + {name = "red gem", chance = 16670}, + {name = "necklace of the deep", chance = 8330}, + {name = "wand of starstorm", chance = 8330}, + {name = "wand of cosmic energy", chance = 8330}, + {name = "death toll", chance = 8330}, + {name = "pair of nightmare boots", chance = 330} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -500}, + {name ="combat", interval = 1500, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -500, radius = 3, shootEffect = CONST_ANI_ENVENOMEDARROW, target = true}, + {name ="combat", interval = 1500, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -300, maxDamage = -650, length = 4, spread = 3, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 1500, chance = 35, type = COMBAT_DEATHDAMAGE, minDamage = -300, maxDamage = -650, radius = 4, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 1500, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -300, maxDamage = -650, radius = 4, effect = CONST_ME_ENERGYAREA, target = false} +} + +monster.defenses = { + defense = 40, + armor = 82 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/feaster_of_souls/the_fear_feaster.lua b/data/monster/quests/feaster_of_souls/the_fear_feaster.lua new file mode 100644 index 00000000000..6c3f8c42bcb --- /dev/null +++ b/data/monster/quests/feaster_of_souls/the_fear_feaster.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("The Fear Feaster") +local monster = {} + +monster.description = "The Fear Feaster" +monster.experience = 13090 +monster.outfit = { + lookType = 1061, + lookHead = 79, + lookBody = 83, + lookLegs = 113, + lookFeet = 0, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "undead" +monster.corpse = 37572 +monster.speed = 500 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "crystal coin", chance = 96080, maxCount = 2}, + {name = "white gem", chance = 52940, maxCount = 2}, + {name = "moonstone", chance = 52940, maxCount = 2}, + {name = "ultimate mana potion", chance = 43140, maxCount = 6}, + {name = "supreme health potion", chance = 29410, maxCount = 6}, + {name = "silver hand mirror", chance = 27450}, + {name = "berserk potion", chance = 23530, maxCount = 10}, + {name = "ultimate spirit potion", chance = 23530, maxCount = 6}, + {name = "bullseye potion", chance = 19610, maxCount = 10}, + {name = "mastermind potion", chance = 19610, maxCount = 10}, + {name = "death toll", chance = 13730, maxCount = 2}, + {name = "ivory comb", chance = 13730}, + {name = "angel figurine", chance = 11760}, + {name = "diamond", chance = 11760}, + {name = "cursed bone", chance = 7840}, + {name = "soulforged lantern", chance = 7840}, + {name = "grimace", chance = 5880}, + {name = "amber", chance = 5880}, + {name = "amber with a dragonfly", chance = 3920}, + {name = "ghost claw", chance = 1960}, + {name = "bloody tears", chance = 1500}, + {name = "ghost chestplate", chance = 150}, + {name = "spooky hood", chance = 150} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -400, maxDamage = -680, range = 7, shootEffect = CONST_ANI_EARTHARROW, target = false}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -400, maxDamage = -575, length = 5, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_PHYSICALDAMAGE, minDamage = -230, maxDamage = -880, range = 7, radius = 3, effect = CONST_ME_GROUNDSHAKER, target = false} +} + +monster.defenses = { + defense = 40, + armor = 82 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/feaster_of_souls/unaz_the_mean.lua b/data/monster/quests/feaster_of_souls/unaz_the_mean.lua new file mode 100644 index 00000000000..8b83cade945 --- /dev/null +++ b/data/monster/quests/feaster_of_souls/unaz_the_mean.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Unaz the Mean") +local monster = {} + +monster.description = "Unaz the Mean" +monster.experience = 22000 +monster.outfit = { + lookType = 1268, + lookHead = 0, + lookBody = 95, + lookLegs = 0, + lookFeet = 0, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 28000 +monster.maxHealth = 28000 +monster.race = "undead" +monster.corpse = 37445 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 10000, maxCount = 5}, + {name = "ivory comb", chance = 83330}, + {name = "skull coin", chance = 66666}, + {name = "moonstone", chance = 33333, maxCount = 2}, + {name = "diamond", chance = 8300}, + {name = "machete", chance = 8300}, + {name = "pair of nightmare boots", chance = 8300}, + {name = "skull staff", chance = 8300}, + {name = "warrior's axe", chance = 8300}, + {name = "death toll", chance = 150}, + {name = "silver hand mirror", chance = 150}, + {name = "red gem", chance = 150, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -500}, + {name ="combat", interval = 1500, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -500, radius = 3, shootEffect = CONST_ANI_ENVENOMEDARROW, target = true}, + {name ="combat", interval = 1500, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -300, maxDamage = -650, length = 4, spread = 3, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 1500, chance = 35, type = COMBAT_DEATHDAMAGE, minDamage = -300, maxDamage = -650, radius = 4, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 1500, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -300, maxDamage = -650, radius = 4, effect = CONST_ME_ENERGYAREA, target = false} +} + +monster.defenses = { + defense = 40, + armor = 82 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/feaster_of_souls/vok_the_freakish.lua b/data/monster/quests/feaster_of_souls/vok_the_freakish.lua new file mode 100644 index 00000000000..0d4635ecb3a --- /dev/null +++ b/data/monster/quests/feaster_of_souls/vok_the_freakish.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Vok The Freakish") +local monster = {} + +monster.description = "Vok The Freakish" +monster.experience = 26700 +monster.outfit = { + lookType = 1268, + lookHead = 0, + lookBody = 98, + lookLegs = 0, + lookFeet = 0, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 32000 +monster.maxHealth = 32000 +monster.race = "undead" +monster.corpse = 37445 +monster.speed = 285 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 10}, + {name = "cursed bone", chance = 40000, maxCount = 10}, + {name = "skull coin", chance = 40000}, + {name = "white gem", chance = 40000, maxCount = 2}, + {name = "moonstone", chance = 30000}, + {name = "gemmed figurine", chance = 20000}, + {name = "ornate crossbow", chance = 10000}, + {name = "silver hand mirror", chance = 150}, + {name = "death toll", chance = 150}, + {name = "pair of nightmare boots", chance = 150} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -500}, + {name ="combat", interval = 1500, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -500, radius = 3, shootEffect = CONST_ANI_ENVENOMEDARROW, target = true}, + {name ="combat", interval = 1500, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -300, maxDamage = -650, length = 4, spread = 3, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 1500, chance = 35, type = COMBAT_DEATHDAMAGE, minDamage = -300, maxDamage = -650, radius = 4, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 1500, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -650, radius = 4, effect = CONST_ME_GREEN_RINGS, target = true} +} + +monster.defenses = { + defense = 40, + armor = 82 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/bosses/ascending_ferumbras.lua b/data/monster/quests/ferumbras_ascendant/bosses/ascending_ferumbras.lua new file mode 100644 index 00000000000..b787e933247 --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/bosses/ascending_ferumbras.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Ascending Ferumbras") +local monster = {} + +monster.description = "ascending ferumbras" +monster.experience = 12000 +monster.outfit = { + lookType = 844, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 150000 +monster.maxHealth = 150000 +monster.race = "venom" +monster.corpse = 6078 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 200}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_MANADRAIN, minDamage = -425, maxDamage = -810, radius = 9, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 2000, chance = 21, type = COMBAT_ENERGYDAMAGE, minDamage = -400, maxDamage = -650, radius = 9, effect = CONST_ME_ENERGYHIT, target = false} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/bosses/death_dragon.lua b/data/monster/quests/ferumbras_ascendant/bosses/death_dragon.lua new file mode 100644 index 00000000000..f2fef5b8b3e --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/bosses/death_dragon.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Death Dragon") +local monster = {} + +monster.description = "a death dragon" +monster.experience = 7200 +monster.outfit = { + lookType = 231, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 8350 +monster.maxHealth = 8350 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 330 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 700, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "DeathDragon" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "FEEEED MY ETERNAL HUNGER!", yell = true}, + {text = "I SENSE LIFE", yell = true} +} + +monster.loot = { + {id = 6500, chance = 14580}, + {id = 2148, chance = 100000, maxCount = 198}, + {id = 7591, chance = 23740, maxCount = 3}, + {id = 7590, chance = 25660, maxCount = 3}, + {id = 5925, chance = 14580}, + {id = 2152, chance = 49790, maxCount = 5}, + {id = 9971, chance = 1630}, + {id = 11233, chance = 32260}, + {id = 2177, chance = 1140}, + {id = 7430, chance = 4290}, + {id = 2454, chance = 1630}, + {id = 7368, chance = 24630, maxCount = 5}, + {id = 2547, chance = 15720, maxCount = 15}, + {id = 2466, chance = 850}, + {id = 11355, chance = 850}, + {id = 2476, chance = 4930}, + {id = 8885, chance = 500}, + {id = 8889, chance = 530}, + {id = 2144, chance = 21290, maxCount = 2}, + {id = 2146, chance = 27610, maxCount = 2}, + {id = 2158, chance = 1170}, + {id = 2498, chance = 920}, + {id = 6300, chance = 1950}, + {id = 2033, chance = 5040} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 150, attack = 60}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_EARTHDAMAGE, minDamage = -100, maxDamage = -400, range = 7, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_LIFEDRAIN, minDamage = -100, maxDamage = -400, range = 7, radius = 4, shootEffect = CONST_ANI_DEATH, target = true}, + {name ="combat", interval = 2000, chance = 11, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -615, range = 7, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="undead dragon curse", interval = 2000, chance = 9, target = false}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_LIFEDRAIN, minDamage = -200, maxDamage = -700, length = 8, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_DEATHDAMAGE, minDamage = -400, maxDamage = -550, length = 8, spread = 3, effect = CONST_ME_SMALLCLOUDS, target = false} +} + +monster.defenses = { + defense = 63, + armor = 45, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/bosses/destabilized_ferumbras.lua b/data/monster/quests/ferumbras_ascendant/bosses/destabilized_ferumbras.lua new file mode 100644 index 00000000000..36b1ad98335 --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/bosses/destabilized_ferumbras.lua @@ -0,0 +1,117 @@ +local mType = Game.createMonsterType("Destabilized Ferumbras") +local monster = {} + +monster.description = "Destabilized Ferumbras" +monster.experience = 12000 +monster.outfit = { + lookType = 844, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 150000 +monster.maxHealth = 150000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 6 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "FerumbrasMortalShell" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Demon2", chance = 11, interval = 2000, max = 6} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 200}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 20, minDamage = -250, maxDamage = -520, radius = 6, effect = CONST_ME_POISONAREA, target = false}, + {name ="ferumbras electrify", interval = 2000, chance = 18, target = false}, + {name ="combat", interval = 2000, chance = 16, type = COMBAT_MANADRAIN, minDamage = -225, maxDamage = -410, radius = 6, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 21, type = COMBAT_LIFEDRAIN, minDamage = -200, maxDamage = -450, radius = 6, effect = CONST_ME_POFF, target = false}, + {name ="ferumbras soulfire", interval = 2000, chance = 20, range = 7, target = false}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_LIFEDRAIN, minDamage = -590, maxDamage = -1050, length = 8, spread = 3, effect = CONST_ME_HITBYPOISON, target = false} +} + +monster.defenses = { + defense = 120, + armor = 100, + {name ="combat", interval = 2000, chance = 23, type = COMBAT_HEALING, minDamage = 600, maxDamage = 2490, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="combat", interval = 2000, chance = 3, type = COMBAT_HEALING, minDamage = 20000, maxDamage = 35000, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="speed", interval = 2000, chance = 14, speedChange = 700, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 7000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 90}, + {type = COMBAT_ENERGYDAMAGE, percent = 90}, + {type = COMBAT_EARTHDAMAGE, percent = 90}, + {type = COMBAT_FIREDAMAGE, percent = 90}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = -20}, + {type = COMBAT_ICEDAMAGE, percent = 90}, + {type = COMBAT_HOLYDAMAGE , percent = 90}, + {type = COMBAT_DEATHDAMAGE , percent = 90} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/bosses/enraged_soul.lua b/data/monster/quests/ferumbras_ascendant/bosses/enraged_soul.lua new file mode 100644 index 00000000000..91787511ded --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/bosses/enraged_soul.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("Enraged Soul") +local monster = {} + +monster.description = "an enraged soul" +monster.experience = 120 +monster.outfit = { + lookType = 568, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 150 +monster.maxHealth = 150 +monster.race = "undead" +monster.corpse = 21368 +monster.speed = 160 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Huh!", yell = false}, + {text = "Shhhhhh", yell = false}, + {text = "Buuuuuh", yell = false} +} + +monster.loot = { + {id = 2394, chance = 10610}, + {id = 2404, chance = 7020}, + {id = 2804, chance = 14400}, + {id = 2654, chance = 8810}, + {id = 1962, chance = 1310}, + {id = 5909, chance = 1940}, + {id = 10607, chance = 1870}, + {id = 2532, chance = 860}, + {id = 2165, chance = 180} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 30, attack = 40}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -25, maxDamage = -45, range = 1, effect = CONST_ME_MAGIC_RED, target = true} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/bosses/ferumbras_mortal_shell.lua b/data/monster/quests/ferumbras_ascendant/bosses/ferumbras_mortal_shell.lua new file mode 100644 index 00000000000..0633cbed607 --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/bosses/ferumbras_mortal_shell.lua @@ -0,0 +1,194 @@ +local mType = Game.createMonsterType("Ferumbras Mortal Shell") +local monster = {} + +monster.description = "ferumbras mortal shell" +monster.experience = 42000 +monster.outfit = { + lookType = 229, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 500000 +monster.maxHealth = 500000 +monster.race = "venom" +monster.corpse = 6078 +monster.speed = 390 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 2500, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Demon2", chance = 11, interval = 2000, max = 3} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "INSECTS!", yell = true}, + {text = "I' STILL POWERFUL ENOUGH TO CRUSH YOU!", yell = true}, + {text = "If you strike me down, I shall become more powerful than you could possibly imagine!", yell = false} +} + +monster.loot = { + {id = 7895, chance = 800}, + {id = 8869, chance = 400}, + {id = 2146, chance = 10000, maxCount = 10}, + {id = 7416, chance = 800}, + {id = 7427, chance = 800}, + {id = 2466, chance = 800}, + {id = 8930, chance = 400}, + {id = 25429, chance = 800}, + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2149, chance = 10000, maxCount = 10}, + {id = 7632, chance = 1000}, + {id = 2156, chance = 1000}, + {id = 8868, chance = 300}, + {id = 2127, chance = 1000}, + {id = 7423, chance = 300}, + {id = 2150, chance = 10000, maxCount = 10}, + {id = 25420, chance = 800}, + {id = 7422, chance = 800}, + {id = 2143, chance = 10000, maxCount = 5}, + {id = 7418, chance = 600}, + {id = 2539, chance = 800}, + {id = 2520, chance = 800}, + {id = 34784, chance = 150}, + {id = 2148, chance = 100000, maxCount = 100}, + {id = 7896, chance = 800}, + {id = 2472, chance = 400}, + {id = 25414, chance = 100, unique = true}, + {id = 7403, chance = 800}, + {id = 25522, chance = 500}, + {id = 8926, chance = 300}, + {id = 25387, chance = 3000}, + {id = 7410, chance = 800}, + {id = 2158, chance = 800}, + {id = 2152, chance = 100000, maxCount = 25}, + {id = 8928, chance = 400}, + {id = 7414, chance = 800}, + {id = 5903, chance = 100, unique = true}, + {id = 25425, chance = 800}, + {id = 7382, chance = 800}, + {id = 2155, chance = 4000}, + {id = 2514, chance = 600}, + {id = 7435, chance = 800}, + {id = 25172, chance = 1000000, maxCount = 3}, + {id = 2144, chance = 10000, maxCount = 5}, + {id = 2145, chance = 10000, maxCount = 10}, + {id = 25427, chance = 800}, + {id = 9970, chance = 10000, maxCount = 10}, + {id = 25423, chance = 800}, + {id = 25523, chance = 500}, + {id = 8885, chance = 800}, + {id = 2415, chance = 700}, + {id = 2522, chance = 100, unique = true}, + {id = 7894, chance = 800}, + {id = 9971, chance = 800}, + {id = 7405, chance = 800}, + {id = 7411, chance = 400}, + {id = 25393, chance = 3500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 200}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 20, minDamage = -250, maxDamage = -520, radius = 6, effect = CONST_ME_POISONAREA, target = false}, + {name ="ferumbras electrify", interval = 2000, chance = 18, target = false}, + {name ="combat", interval = 2000, chance = 16, type = COMBAT_MANADRAIN, minDamage = -225, maxDamage = -410, radius = 6, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_MANADRAIN, minDamage = -425, maxDamage = -810, radius = 9, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 2000, chance = 21, type = COMBAT_ENERGYDAMAGE, minDamage = -400, maxDamage = -650, radius = 9, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 21, type = COMBAT_LIFEDRAIN, minDamage = -200, maxDamage = -450, radius = 6, effect = CONST_ME_POFF, target = false}, + {name ="ferumbras soulfire", interval = 2000, chance = 20, range = 7, target = false}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_LIFEDRAIN, minDamage = -590, maxDamage = -1050, length = 8, spread = 3, effect = CONST_ME_HITBYPOISON, target = false} +} + +monster.defenses = { + defense = 120, + armor = 100, + {name ="combat", interval = 2000, chance = 23, type = COMBAT_HEALING, minDamage = 600, maxDamage = 2490, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="combat", interval = 2000, chance = 3, type = COMBAT_HEALING, minDamage = 20000, maxDamage = 35000, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="speed", interval = 2000, chance = 14, speedChange = 700, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 7000}, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -50}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 90}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -20}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/bosses/ferumbras_soul_splinter.lua b/data/monster/quests/ferumbras_ascendant/bosses/ferumbras_soul_splinter.lua new file mode 100644 index 00000000000..b14096e8cfd --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/bosses/ferumbras_soul_splinter.lua @@ -0,0 +1,117 @@ +local mType = Game.createMonsterType("Ferumbras Soul Splinter") +local monster = {} + +monster.description = "Ferumbras Soul Splinter" +monster.experience = 12000 +monster.outfit = { + lookType = 843, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 150000 +monster.maxHealth = 150000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 390 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "FerumbrasSoulSplinter" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Demon2", chance = 11, interval = 2000, max = 3} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 200}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 20, minDamage = -250, maxDamage = -520, radius = 6, effect = CONST_ME_POISONAREA, target = false}, + {name ="ferumbras electrify", interval = 2000, chance = 18, target = false}, + {name ="combat", interval = 2000, chance = 16, type = COMBAT_MANADRAIN, minDamage = -225, maxDamage = -410, radius = 6, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 21, type = COMBAT_LIFEDRAIN, minDamage = -200, maxDamage = -450, radius = 6, effect = CONST_ME_POFF, target = false}, + {name ="ferumbras soulfire", interval = 2000, chance = 20, range = 7, target = false}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_LIFEDRAIN, minDamage = -590, maxDamage = -1050, length = 8, spread = 3, effect = CONST_ME_HITBYPOISON, target = false} +} + +monster.defenses = { + defense = 120, + armor = 100, + {name ="combat", interval = 2000, chance = 23, type = COMBAT_HEALING, minDamage = 600, maxDamage = 2490, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="combat", interval = 2000, chance = 3, type = COMBAT_HEALING, minDamage = 20000, maxDamage = 35000, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="speed", interval = 2000, chance = 14, speedChange = 700, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 7000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -50}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 90}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/bosses/mazoran.lua b/data/monster/quests/ferumbras_ascendant/bosses/mazoran.lua new file mode 100644 index 00000000000..67715403e7e --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/bosses/mazoran.lua @@ -0,0 +1,157 @@ +local mType = Game.createMonsterType("Mazoran") +local monster = {} + +monster.description = "mazoran" +monster.experience = 60000 +monster.outfit = { + lookType = 842, + lookHead = 77, + lookBody = 79, + lookLegs = 78, + lookFeet = 94, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 370000 +monster.maxHealth = 370000 +monster.race = "fire" +monster.corpse = 25151 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "ASHES TO ASHES, TASTE MY FIRE!", yell = false}, + {text = "BUUURN!", yell = false}, + {text = "UNLEASH THE FIRE!", yell = false} +} + +monster.loot = { + {id = 25172, chance = 1000000}, + {id = 18419, chance = 23000, maxCount = 5}, + {id = 18420, chance = 23000, maxCount = 5}, + {id = 18421, chance = 23000, maxCount = 5}, + {id = 2143, chance = 12000, maxCount = 8}, + {id = 2146, chance = 12000, maxCount = 9}, + {id = 2148, chance = 98000, maxCount = 200}, + {id = 2150, chance = 10000, maxCount = 5}, + {id = 2152, chance = 8000, maxCount = 58}, + {id = 2155, chance = 1000}, + {id = 2158, chance = 1000}, + {id = 2167, chance = 4000}, + {id = 2432, chance = 3000}, + {id = 25416, chance = 500}, + {id = 2542, chance = 500, unique = true}, + {id = 25522, chance = 500}, + {id = 25523, chance = 500}, + {id = 6500, chance = 11000}, + {id = 7382, chance = 1000}, + {id = 7590, chance = 23000, maxCount = 5}, + {id = 7632, chance = 14000, maxCount = 5}, + {id = 7633, chance = 14000, maxCount = 5}, + {id = 7890, chance = 1000}, + {id = 7894, chance = 1000}, + {id = 7899, chance = 1000}, + {id = 8472, chance = 46100, maxCount = 5}, + {id = 8473, chance = 23000, maxCount = 5}, + {id = 9970, chance = 10000, maxCount = 8}, + {id = 9971, chance = 3000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -1500, maxDamage = -2500}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -500, maxDamage = -1000, length = 10, spread = 3, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="speed", interval = 2000, chance = 25, speedChange = -600, radius = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 15000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -300, maxDamage = -700, radius = 5, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -500, maxDamage = -800, length = 10, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -500, maxDamage = -800, length = 8, spread = 3, effect = CONST_ME_FIREATTACK, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 2090, maxDamage = 4500, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 35, speedChange = 700, effect = CONST_ME_MAGIC_GREEN, target = false, duration = 6000}, + {name ="mazoran fire", interval = 30000, chance = 45, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/bosses/plagirath.lua b/data/monster/quests/ferumbras_ascendant/bosses/plagirath.lua new file mode 100644 index 00000000000..707fb0f7d04 --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/bosses/plagirath.lua @@ -0,0 +1,154 @@ +local mType = Game.createMonsterType("Plagirath") +local monster = {} + +monster.description = "plagirath" +monster.experience = 58000 +monster.outfit = { + lookType = 862, + lookHead = 84, + lookBody = 62, + lookLegs = 60, + lookFeet = 79, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 290000 +monster.maxHealth = 290000 +monster.race = "venom" +monster.corpse = 25151 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "BOOOOOOOMMM!!!!!", yell = false}, + {text = "WITHER AND DIE!", yell = true}, + {text = "DEATH AND DECAY!", yell = true}, + {text = "I CAN SENSE YOUR BODIES ROOTING!", yell = true} +} + +monster.loot = { + {id = 25172, chance = 1000000}, + {id = 11306, chance = 3000}, + {id = 18411, chance = 1820}, + {id = 18419, chance = 23000, maxCount = 6}, + {id = 18420, chance = 23000, maxCount = 6}, + {id = 18421, chance = 23000, maxCount = 6}, + {id = 2143, chance = 12000, maxCount = 8}, + {id = 2146, chance = 12000, maxCount = 9}, + {id = 2148, chance = 98000, maxCount = 200}, + {id = 2150, chance = 10000, maxCount = 5}, + {id = 2152, chance = 8000, maxCount = 58}, + {id = 25383, chance = 800}, + {id = 25415, chance = 500, unique = true}, + {id = 25522, chance = 800}, + {id = 25523, chance = 800}, + {id = 6500, chance = 11000}, + {id = 7386, chance = 5000}, + {id = 7632, chance = 14000, maxCount = 5}, + {id = 7633, chance = 14000, maxCount = 5}, + {id = 7887, chance = 5000}, + {id = 8473, chance = 23000, maxCount = 15}, + {id = 8901, chance = 4000}, + {id = 9970, chance = 10000, maxCount = 8} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -1300, maxDamage = -2250}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -500, maxDamage = -900, radius = 4, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -500, maxDamage = -900, range = 4, radius = 4, effect = CONST_ME_POFF, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -1000, maxDamage = -1200, length = 10, spread = 3, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -1500, maxDamage = -1900, length = 10, spread = 3, effect = CONST_ME_POFF, target = false}, + {name ="speed", interval = 2000, chance = 20, speedChange = -600, radius = 7, effect = CONST_ME_MAGIC_GREEN, target = false, duration = 20000}, + {name ="plagirath bog", interval = 20000, chance = 25, target = false} +} + +monster.defenses = { + defense = 55, + armor = 55, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 3000, maxDamage = 4000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 30, speedChange = 440, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000}, + {name ="plagirath summon", interval = 2000, chance = 15, target = false}, + {name ="plagirath heal", interval = 2000, chance = 17, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/bosses/ragiaz.lua b/data/monster/quests/ferumbras_ascendant/bosses/ragiaz.lua new file mode 100644 index 00000000000..d228b32198a --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/bosses/ragiaz.lua @@ -0,0 +1,157 @@ +local mType = Game.createMonsterType("Ragiaz") +local monster = {} + +monster.description = "ragiaz" +monster.experience = 100000 +monster.outfit = { + lookType = 862, + lookHead = 76, + lookBody = 57, + lookLegs = 19, + lookFeet = 0, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 380000 +monster.maxHealth = 380000 +monster.race = "undead" +monster.corpse = 25151 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 25172, chance = 1000000}, + {id = 6558, chance = 10000}, + {id = 6558, chance = 10000}, + {id = 6558, chance = 10000}, + {id = 6558, chance = 10000}, + {id = 6558, chance = 10000}, + {id = 2154, chance = 1000}, + {id = 18419, chance = 3000, maxCount = 5}, + {id = 18420, chance = 3000, maxCount = 5}, + {id = 18421, chance = 3000, maxCount = 5}, + {id = 2143, chance = 3000, maxCount = 8}, + {id = 2146, chance = 3000, maxCount = 9}, + {id = 2148, chance = 98000, maxCount = 200}, + {id = 2150, chance = 3000, maxCount = 5}, + {id = 2152, chance = 8000, maxCount = 58}, + {id = 2155, chance = 1000}, + {id = 2156, chance = 1000}, + {id = 2158, chance = 1000}, + {id = 2436, chance = 4000}, + {id = 25414, chance = 100, unique = true}, + {id = 25522, chance = 700}, + {id = 25523, chance = 700}, + {id = 6500, chance = 11000}, + {id = 7420, chance = 500}, + {id = 7426, chance = 4000}, + {id = 7590, chance = 3000, maxCount = 5}, + {id = 7591, chance = 3100, maxCount = 5}, + {id = 7632, chance = 3000, maxCount = 5}, + {id = 7633, chance = 3000, maxCount = 5}, + {id = 8472, chance = 3100, maxCount = 5}, + {id = 8473, chance = 3000, maxCount = 5}, + {id = 9970, chance = 3000, maxCount = 8} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -1400, maxDamage = -2300}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -500, maxDamage = -900, radius = 4, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -500, maxDamage = -900, range = 4, radius = 4, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_POFF, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -1000, maxDamage = -1200, length = 10, spread = 3, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -1500, maxDamage = -1900, length = 10, spread = 3, effect = CONST_ME_GROUNDSHAKER, target = false}, + {name ="speed", interval = 2000, chance = 20, speedChange = -600, radius = 7, effect = CONST_ME_POFF, target = false, duration = 20000} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 1000, maxDamage = 2000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 20, speedChange = 600, effect = CONST_ME_MAGIC_GREEN, target = false, duration = 4000}, + {name ="ragiaz transform", interval = 2000, chance = 8, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/bosses/razzagorn.lua b/data/monster/quests/ferumbras_ascendant/bosses/razzagorn.lua new file mode 100644 index 00000000000..9545f4fcae3 --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/bosses/razzagorn.lua @@ -0,0 +1,168 @@ +local mType = Game.createMonsterType("Razzagorn") +local monster = {} + +monster.description = "razzagorn" +monster.experience = 65000 +monster.outfit = { + lookType = 842, + lookHead = 78, + lookBody = 94, + lookLegs = 52, + lookFeet = 126, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 290000 +monster.maxHealth = 290000 +monster.race = "fire" +monster.corpse = 25151 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Eruption of Destruction", chance = 15, interval = 2000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "YOUR FUTILE ATTACKS ONLY FEED MY RAGE!", yell = false}, + {text = "YOU-ARE-WEAK!!", yell = false}, + {text = "DEEESTRUCTIOOON!!", yell = false} +} + +monster.loot = { + {id = 25172, chance = 1000000}, + {id = 6558, chance = 10000}, + {id = 6558, chance = 10000}, + {id = 6558, chance = 10000}, + {id = 6558, chance = 10000}, + {id = 6558, chance = 10000}, + {id = 2148, chance = 98000, maxCount = 200}, + {id = 2143, chance = 12000, maxCount = 8}, + {id = 2146, chance = 12000, maxCount = 9}, + {id = 2150, chance = 10000, maxCount = 5}, + {id = 2152, chance = 8000, maxCount = 58}, + {id = 2153, chance = 1000}, + {id = 2154, chance = 1000}, + {id = 2156, chance = 1000}, + {id = 2158, chance = 1000}, + {id = 2181, chance = 13000}, + {id = 2462, chance = 8000}, + {id = 24849, chance = 46100, maxCount = 5}, + {id = 24850, chance = 46100, maxCount = 5}, + {id = 25410, chance = 500}, + {id = 25418, chance = 500, unique = true}, + {id = 5022, chance = 46100, maxCount = 5}, + {id = 6500, chance = 11000}, + {id = 7439, chance = 8000}, + {id = 7440, chance = 4000}, + {id = 7443, chance = 4000}, + {id = 7590, chance = 23000, maxCount = 5}, + {id = 7591, chance = 46100, maxCount = 5}, + {id = 7632, chance = 14000, maxCount = 5}, + {id = 7633, chance = 14000, maxCount = 5}, + {id = 8472, chance = 46100, maxCount = 10}, + {id = 2522, chance = 100, unique = true}, + {id = 8473, chance = 23000, maxCount = 5}, + {id = 9970, chance = 10000, maxCount = 8} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -1000, maxDamage = -2000}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -500, maxDamage = -1000, length = 10, spread = 3, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="speed", interval = 2000, chance = 25, speedChange = -600, radius = 7, effect = CONST_ME_GREEN_RINGS, target = false, duration = 15000}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -500, maxDamage = -700, radius = 7, effect = CONST_ME_LOSEENERGY, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -300, maxDamage = -700, radius = 5, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -1500, maxDamage = -1800, length = 12, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -500, maxDamage = -800, length = 10, spread = 3, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -500, maxDamage = -800, length = 10, spread = 3, effect = CONST_ME_ENERGYHIT, target = false} +} + +monster.defenses = { + defense = 145, + armor = 188, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 1000, maxDamage = 3000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 8, speedChange = 480, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000}, + {name ="razzagorn summon", interval = 2000, chance = 3, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/bosses/redeemed_soul.lua b/data/monster/quests/ferumbras_ascendant/bosses/redeemed_soul.lua new file mode 100644 index 00000000000..c4d609614bc --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/bosses/redeemed_soul.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Redeemed Soul") +local monster = {} + +monster.description = "a redeemed soul" +monster.experience = 0 +monster.outfit = { + lookType = 714, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1138 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Tainted Caves in the Green Claw Swamp (under the right conditions)." + } + +monster.health = 250 +monster.maxHealth = 250 +monster.race = "undead" +monster.corpse = 24634 +monster.speed = 162 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 250, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ting-a-ling.", yell = false}, + {text = "Free ... finally.", yell = false} +} + +monster.loot = { +} + +monster.attacks = { +} + +monster.defenses = { + defense = 15, + armor = 10, + {name ="speed", interval = 2000, chance = 8, speedChange = 240, effect = CONST_ME_MAGIC_GREEN, target = false, duration = 20000}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 65}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 90}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/bosses/shulgrax.lua b/data/monster/quests/ferumbras_ascendant/bosses/shulgrax.lua new file mode 100644 index 00000000000..af7caac9e9e --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/bosses/shulgrax.lua @@ -0,0 +1,167 @@ +local mType = Game.createMonsterType("Shulgrax") +local monster = {} + +monster.description = "Shulgrax" +monster.experience = 58000 +monster.outfit = { + lookType = 842, + lookHead = 0, + lookBody = 62, + lookLegs = 22, + lookFeet = 87, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 290000 +monster.maxHealth = 290000 +monster.race = "undead" +monster.corpse = 25151 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "DAMMMMNNNNAAATIONN!", yell = false}, + {text = "I WILL FEAST ON YOUR SOUL!", yell = true}, + {text = "YOU ARE ALL DAMNED!", yell = true} +} + +monster.loot = { + {id = 25172, chance = 1000000}, + {id = 6558, chance = 10000}, + {id = 6558, chance = 10000}, + {id = 6558, chance = 10000}, + {id = 6558, chance = 10000}, + {id = 6558, chance = 10000}, + {id = 20118, chance = 1800}, + {id = 2136, chance = 1000}, + {id = 2143, chance = 12000, maxCount = 8}, + {id = 2146, chance = 12000, maxCount = 9}, + {id = 2148, chance = 98000, maxCount = 200}, + {id = 2150, chance = 10000, maxCount = 5}, + {id = 2152, chance = 8000, maxCount = 58}, + {id = 2153, chance = 1000}, + {id = 2154, chance = 1000}, + {id = 2155, chance = 1000}, + {id = 2156, chance = 1000}, + {id = 2472, chance = 700}, + {id = 24849, chance = 46100, maxCount = 5}, + {id = 24850, chance = 46100, maxCount = 5}, + {id = 25382, chance = 700}, + {id = 25383, chance = 700}, + {id = 25412, chance = 500, unique = true}, + {id = 25523, chance = 700}, + {id = 5022, chance = 46100, maxCount = 5}, + {id = 6300, chance = 1300}, + {id = 6500, chance = 11000}, + {id = 7416, chance = 1000}, + {id = 7419, chance = 1300}, + {id = 7427, chance = 1000}, + {id = 7451, chance = 1900}, + {id = 7590, chance = 23000, maxCount = 5}, + {id = 7632, chance = 14000, maxCount = 5}, + {id = 7633, chance = 14000, maxCount = 5}, + {id = 7889, chance = 1000}, + {id = 7895, chance = 1000}, + {id = 8472, chance = 46100, maxCount = 10}, + {id = 8473, chance = 23000, maxCount = 5}, + {id = 9970, chance = 10000, maxCount = 5} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -1500, maxDamage = -2500}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -500, maxDamage = -1000, length = 10, spread = 3, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="speed", interval = 2000, chance = 25, speedChange = -600, radius = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 15000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -300, maxDamage = -700, radius = 5, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -500, maxDamage = -800, length = 10, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -500, maxDamage = -800, length = 8, spread = 3, effect = CONST_ME_FIREATTACK, target = false} +} + +monster.defenses = { + defense = 65, + armor = 55, + {name ="combat", interval = 3000, chance = 35, type = COMBAT_HEALING, minDamage = 400, maxDamage = 6000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="shulgrax summon", interval = 5000, chance = 5, target = false}, + {name ="speed", interval = 4000, chance = 80, speedChange = 440, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/bosses/sin_devourer.lua b/data/monster/quests/ferumbras_ascendant/bosses/sin_devourer.lua new file mode 100644 index 00000000000..dededcd5fdc --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/bosses/sin_devourer.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Sin Devourer") +local monster = {} + +monster.description = "a sin devourer" +monster.experience = 500 +monster.outfit = { + lookType = 320, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2700 +monster.maxHealth = 2700 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 360 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 10, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2804, chance = 4830}, + {id = 2200, chance = 850}, + {id = 2171, chance = 120}, + {id = 2195, chance = 120}, + {id = 7589, chance = 1600}, + {id = 2148, chance = 89840, maxCount = 110}, + {id = 7407, chance = 320}, + {id = 7427, chance = 120}, + {id = 9942, chance = 130}, + {id = 2124, chance = 1030}, + {id = 8870, chance = 520} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 30, condition = {type = CONDITION_POISON, totalDamage = 80, interval = 4000}}, + {name ="nightstalker paralyze", interval = 2000, chance = 19, range = 7, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_LIFEDRAIN, minDamage = -360, maxDamage = -470, range = 1, effect = CONST_ME_HOLYAREA, target = true}, + {name ="speed", interval = 2000, chance = 40, speedChange = -600, range = 6, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_ICEAREA, target = true, duration = 20000}, + {name ="silencer skill reducer", interval = 2000, chance = 30, range = 4, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 35, + armor = 30, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_HEALING, minDamage = 60, maxDamage = 130, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_YELLOW_RINGS} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 40}, + {type = COMBAT_ENERGYDAMAGE, percent = 40}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 40}, + {type = COMBAT_HOLYDAMAGE , percent = 40}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/bosses/tarbaz.lua b/data/monster/quests/ferumbras_ascendant/bosses/tarbaz.lua new file mode 100644 index 00000000000..542fe505b89 --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/bosses/tarbaz.lua @@ -0,0 +1,156 @@ +local mType = Game.createMonsterType("Tarbaz") +local monster = {} + +monster.description = "tarbaz" +monster.experience = 50000 +monster.outfit = { + lookType = 842, + lookHead = 0, + lookBody = 21, + lookLegs = 19, + lookFeet = 3, + lookAddons = 2, + lookMount = 0 +} + +monster.health = 290000 +monster.maxHealth = 290000 +monster.race = "undead" +monster.corpse = 25151 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You are a failure.", yell = false} +} + +monster.loot = { + {id = 25172, chance = 1000000}, + {id = 6558, chance = 10000}, + {id = 6558, chance = 10000}, + {id = 6558, chance = 10000}, + {id = 6558, chance = 10000}, + {id = 6558, chance = 10000}, + {id = 2154, chance = 1000}, + {id = 2148, chance = 98000, maxCount = 184}, + {id = 7590, chance = 23000, maxCount = 10}, + {id = 7632, chance = 14000, maxCount = 5}, + {id = 7633, chance = 14000, maxCount = 5}, + {id = 8472, chance = 46100, maxCount = 10}, + {id = 8473, chance = 23000, maxCount = 10}, + {id = 9970, chance = 10000, maxCount = 8}, + {id = 2146, chance = 12000, maxCount = 9}, + {id = 2143, chance = 12000, maxCount = 8}, + {id = 2155, chance = 1000}, + {id = 7888, chance = 4000}, + {id = 7896, chance = 1000}, + {id = 7897, chance = 1000}, + {id = 2150, chance = 10000, maxCount = 5}, + {id = 2152, chance = 8000, maxCount = 58}, + {id = 18413, chance = 10000, maxCount = 5}, + {id = 18414, chance = 10000, maxCount = 5}, + {id = 18415, chance = 10000, maxCount = 5}, + {id = 2153, chance = 1000}, + {id = 25523, chance = 800}, + {id = 25383, chance = 800}, + {id = 2155, chance = 1000}, + {id = 8910, chance = 4000}, + {id = 25413, chance = 500, unique = true} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -1000, maxDamage = -2000}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -500, maxDamage = -1000, length = 10, spread = 3, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="speed", interval = 2000, chance = 25, speedChange = -600, radius = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 15000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -300, maxDamage = -700, radius = 5, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -500, maxDamage = -800, length = 10, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -500, maxDamage = -800, length = 8, spread = 3, effect = CONST_ME_FIREATTACK, target = false} +} + +monster.defenses = { + defense = 120, + armor = 100, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 900, maxDamage = 3500, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="speed", interval = 3000, chance = 30, speedChange = 460, effect = CONST_ME_MAGIC_RED, target = false, duration = 7000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/bosses/the_lord_of_the_lice.lua b/data/monster/quests/ferumbras_ascendant/bosses/the_lord_of_the_lice.lua new file mode 100644 index 00000000000..6dde6a875fc --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/bosses/the_lord_of_the_lice.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("The Lord of the Lice") +local monster = {} + +monster.description = "the lord of the lice" +monster.experience = 600 +monster.outfit = { + lookType = 305, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 80000 +monster.maxHealth = 80000 +monster.race = "blood" +monster.corpse = 9871 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 170}, + {id = 10585, chance = 100000}, + {id = 2152, chance = 94830, maxCount = 10}, + {id = 8473, chance = 94830, maxCount = 10}, + {id = 7590, chance = 94830, maxCount = 10}, + {id = 7591, chance = 94830, maxCount = 10}, + {id = 2214, chance = 100000}, + {id = 2438, chance = 25860}, + {id = 7884, chance = 86200} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 100, attack = 100, condition = {type = CONDITION_POISON, totalDamage = 100, interval = 4000}}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_EARTHDAMAGE, minDamage = -120, maxDamage = -310, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 22, minDamage = -1000, maxDamage = -1800, length = 8, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -80, maxDamage = -80, radius = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_LIFEDRAIN, minDamage = -300, maxDamage = -420, range = 7, radius = 7, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="mutated rat paralyze", interval = 2000, chance = 20, range = 7, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_HEALING, minDamage = 250, maxDamage = 550, effect = CONST_ME_HITBYPOISON, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/bosses/the_shatterer.lua b/data/monster/quests/ferumbras_ascendant/bosses/the_shatterer.lua new file mode 100644 index 00000000000..73b57a5cbed --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/bosses/the_shatterer.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("The Shatterer") +local monster = {} + +monster.description = "The Shatterer" +monster.experience = 58000 +monster.outfit = { + lookType = 842, + lookHead = 77, + lookBody = 113, + lookLegs = 21, + lookFeet = 94, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 220000 +monster.maxHealth = 220000 +monster.race = "fire" +monster.corpse = 6068 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 2500, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "STOMP! SHAKE! SHATTERER!!", yell = false} +} + +monster.loot = { + {id = 7590, chance = 23000, maxCount = 10}, + {id = 8472, chance = 46100, maxCount = 10}, + {id = 8473, chance = 46100, maxCount = 10}, + {id = 2147, chance = 12000, maxCount = 12}, + {id = 2152, chance = 8000, maxCount = 10}, + {id = 2148, chance = 30000, maxCount = 200} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -200, maxDamage = -3000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -200, maxDamage = -1000, range = 7, target = false}, + {name ="combat", interval = 3000, chance = 44, type = COMBAT_PHYSICALDAMAGE, minDamage = -400, maxDamage = -2000, range = 7, shootEffect = CONST_ANI_WHIRLWINDSWORD, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -400, range = 7, shootEffect = CONST_ANI_THROWINGKNIFE, target = false, duration = 15000}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ICEDAMAGE, minDamage = 0, maxDamage = -800, range = 7, radius = 7, effect = CONST_ME_BIGPLANTS, target = false} +} + +monster.defenses = { + defense = 65, + armor = 55, + {name ="combat", interval = 3000, chance = 35, type = COMBAT_HEALING, minDamage = 400, maxDamage = 6000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 4000, chance = 80, speedChange = 440, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/bosses/zamulosh.lua b/data/monster/quests/ferumbras_ascendant/bosses/zamulosh.lua new file mode 100644 index 00000000000..c66c9e1ae8c --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/bosses/zamulosh.lua @@ -0,0 +1,153 @@ +local mType = Game.createMonsterType("Zamulosh") +local monster = {} + +monster.description = "zamulosh" +monster.experience = 55000 +monster.outfit = { + lookType = 862, + lookHead = 16, + lookBody = 12, + lookLegs = 73, + lookFeet = 55, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 300000 +monster.maxHealth = 300000 +monster.race = "undead" +monster.corpse = 25151 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Zamulosh2", chance = 100, interval = 1000, max = 1} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I AM ZAMULOSH!", yell = false} +} + +monster.loot = { + {id = 25172, chance = 1000000}, + {id = 2148, chance = 98000, maxCount = 200}, + {id = 7632, chance = 14000, maxCount = 5}, + {id = 7633, chance = 14000, maxCount = 5}, + {id = 2146, chance = 12000, maxCount = 9}, + {id = 2143, chance = 12000, maxCount = 8}, + {id = 2150, chance = 10000, maxCount = 5}, + {id = 9970, chance = 10000, maxCount = 8}, + {id = 2152, chance = 8000, maxCount = 58}, + {id = 6500, chance = 11000}, + {id = 18416, chance = 10000, maxCount = 6}, + {id = 18417, chance = 10000, maxCount = 6}, + {id = 18418, chance = 10000, maxCount = 6}, + {id = 2156, chance = 1000}, + {id = 2154, chance = 1000}, + {id = 2155, chance = 1000}, + {id = 2158, chance = 1000}, + {id = 2169, chance = 6000}, + {id = 2214, chance = 6000}, + {id = 25523, chance = 770}, + {id = 8878, chance = 770}, + {id = 25382, chance = 670}, + {id = 25418, chance = 500, unique = true}, + {id = 25211, chance = 500, unique = true} +} + +monster.attacks = { + {name ="melee", interval = 3000, chance = 100, minDamage = -1500, maxDamage = -2300}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -700, maxDamage = -800, length = 12, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_MANADRAIN, minDamage = -2600, maxDamage = -3300, length = 12, spread = 3, effect = CONST_ME_TELEPORT, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -900, maxDamage = -1500, length = 6, spread = 2, effect = CONST_ME_FIREAREA, target = false}, + {name ="speed", interval = 2000, chance = 35, speedChange = -600, radius = 8, effect = CONST_ME_MAGIC_RED, target = false, duration = 15000} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 220, maxDamage = 535, effect = CONST_ME_YELLOW_RINGS, target = false}, + {name ="zamulosh invisible", interval = 2000, chance = 25}, + {name ="zamulosh tp", interval = 2000, chance = 15, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/bosses/zamulosh2.lua b/data/monster/quests/ferumbras_ascendant/bosses/zamulosh2.lua new file mode 100644 index 00000000000..1e086f31e54 --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/bosses/zamulosh2.lua @@ -0,0 +1,148 @@ +local mType = Game.createMonsterType("Zamulosh2") +local monster = {} + +monster.name = "Zamulosh" +monster.description = "zamulosh" +monster.experience = 55000 +monster.outfit = { + lookType = 862, + lookHead = 16, + lookBody = 12, + lookLegs = 73, + lookFeet = 55, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 300000 +monster.maxHealth = 300000 +monster.race = "undead" +monster.corpse = 25151 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I AM ZAMULOSH!", yell = false} +} + +monster.loot = { + {id = 25172, chance = 1000000}, + {id = 2148, chance = 98000, maxCount = 200}, + {id = 7632, chance = 14000, maxCount = 5}, + {id = 7633, chance = 14000, maxCount = 5}, + {id = 2146, chance = 12000, maxCount = 9}, + {id = 2143, chance = 12000, maxCount = 8}, + {id = 2150, chance = 10000, maxCount = 5}, + {id = 9970, chance = 10000, maxCount = 8}, + {id = 2152, chance = 8000, maxCount = 58}, + {id = 6500, chance = 11000}, + {id = 18416, chance = 10000, maxCount = 6}, + {id = 18417, chance = 10000, maxCount = 6}, + {id = 18418, chance = 10000, maxCount = 6}, + {id = 2156, chance = 1000}, + {id = 2154, chance = 1000}, + {id = 2155, chance = 1000}, + {id = 2158, chance = 1000}, + {id = 2169, chance = 6000}, + {id = 2214, chance = 6000}, + {id = 25523, chance = 770}, + {id = 8878, chance = 770}, + {id = 25382, chance = 670}, + {id = 25418, chance = 500, unique = true}, + {id = 25211, chance = 500, unique = true} +} + +monster.attacks = { + {name ="melee", interval = 3000, chance = 100, minDamage = -1500, maxDamage = -2300}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -700, maxDamage = -800, length = 12, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_MANADRAIN, minDamage = -2600, maxDamage = -3300, length = 12, spread = 3, effect = CONST_ME_TELEPORT, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -900, maxDamage = -1500, length = 6, spread = 2, effect = CONST_ME_FIREAREA, target = false}, + {name ="speed", interval = 2000, chance = 35, speedChange = -600, radius = 8, effect = CONST_ME_MAGIC_RED, target = false, duration = 15000} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 220, maxDamage = 535, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/bosses/zamulosh3.lua b/data/monster/quests/ferumbras_ascendant/bosses/zamulosh3.lua new file mode 100644 index 00000000000..8b602b34f54 --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/bosses/zamulosh3.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Zamulosh3") +local monster = {} + +monster.name = "Zamulosh" +monster.description = "Zamulosh" +monster.experience = 55000 +monster.outfit = { + lookType = 862, + lookHead = 16, + lookBody = 12, + lookLegs = 73, + lookFeet = 55, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "undead" +monster.corpse = 25151 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "ZamuloshClone" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I AM ZAMULOSH!", yell = false} +} + +monster.loot = { + {id = 25172, chance = 1000000}, + {id = 2148, chance = 98000, maxCount = 200}, + {id = 7632, chance = 14000, maxCount = 5}, + {id = 7633, chance = 14000, maxCount = 5}, + {id = 2146, chance = 12000, maxCount = 9}, + {id = 2143, chance = 12000, maxCount = 8}, + {id = 2150, chance = 10000, maxCount = 5}, + {id = 9970, chance = 10000, maxCount = 8}, + {id = 2152, chance = 8000, maxCount = 58}, + {id = 6500, chance = 11000}, + {id = 18416, chance = 10000, maxCount = 6}, + {id = 18417, chance = 10000, maxCount = 6}, + {id = 18418, chance = 10000, maxCount = 6}, + {id = 2156, chance = 1000}, + {id = 2154, chance = 1000}, + {id = 2155, chance = 1000}, + {id = 2158, chance = 1000}, + {id = 2169, chance = 6000}, + {id = 2214, chance = 6000}, + {id = 25523, chance = 770}, + {id = 8878, chance = 770}, + {id = 25382, chance = 670}, + {id = 25418, chance = 500, unique = true}, + {id = 25211, chance = 500, unique = true} +} + +monster.attacks = { + {name ="melee", interval = 3000, chance = 100, minDamage = -200, maxDamage = -300}, + {name ="speed", interval = 1000, chance = 10, speedChange = -700, radius = 8, effect = CONST_ME_MAGIC_RED, target = false, duration = 8000} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/damned_soul.lua b/data/monster/quests/ferumbras_ascendant/damned_soul.lua new file mode 100644 index 00000000000..3b2a9bdf8d7 --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/damned_soul.lua @@ -0,0 +1,127 @@ +local mType = Game.createMonsterType("Damned Soul") +local monster = {} + +monster.description = "a damned soul" +monster.experience = 300 +monster.outfit = { + lookType = 232, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 800 +monster.maxHealth = 800 +monster.race = "undead" +monster.corpse = 25354 +monster.speed = 380 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 4 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 800, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Forgive Meeeee!", yell = false}, + {text = "Mouuuurn meeee!", yell = false}, + {text = "Help meee!", yell = false} +} + +monster.loot = { + {id = 2260, chance = 34550, maxCount = 3}, + {id = 6500, chance = 6990}, + {id = 11233, chance = 33070}, + {id = 2148, chance = 99940, maxCount = 198}, + {id = 2152, chance = 99940, maxCount = 3}, + {id = 7590, chance = 14200, maxCount = 2}, + {id = 7591, chance = 8810, maxCount = 2}, + {id = 5944, chance = 15000}, + {id = 2144, chance = 11930, maxCount = 3}, + {id = 2143, chance = 10800, maxCount = 3}, + {id = 9809, chance = 6200}, + {id = 9810, chance = 3350}, + {id = 5806, chance = 4940}, + {id = 2133, chance = 1590}, + {id = 2197, chance = 2560}, + {id = 2156, chance = 2050}, + {id = 2528, chance = 740}, + {id = 5741, chance = 170}, + {id = 2436, chance = 850}, + {id = 7413, chance = 1020}, + {id = 7407, chance = 740}, + {id = 6300, chance = 2160}, + {id = 6526, chance = 1250} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 76, attack = 100}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_DEATHDAMAGE, minDamage = -90, maxDamage = -240, length = 3, spread = 0, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="lost soul paralyze", interval = 2000, chance = 18, target = false} +} + +monster.defenses = { + defense = 35, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = -20}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/desperate_soul.lua b/data/monster/quests/ferumbras_ascendant/desperate_soul.lua new file mode 100644 index 00000000000..8eb24ecb684 --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/desperate_soul.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Desperate Soul") +local monster = {} + +monster.description = "a desperate soul" +monster.experience = 0 +monster.outfit = { + lookType = 262, + lookHead = 69, + lookBody = 66, + lookLegs = 69, + lookFeet = 66, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 15 +monster.maxHealth = 15 +monster.race = "blood" +monster.corpse = 7338 +monster.speed = 670 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { +} + +monster.defenses = { + defense = 7, + armor = 6, + {name ="speed", interval = 2000, chance = 25, speedChange = 1200, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/disgusting_ooze.lua b/data/monster/quests/ferumbras_ascendant/disgusting_ooze.lua new file mode 100644 index 00000000000..5087b3dd3fd --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/disgusting_ooze.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Disgusting Ooze") +local monster = {} + +monster.description = "a disgusting ooze" +monster.experience = 3700 +monster.outfit = { + lookType = 238, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3650 +monster.maxHealth = 3650 +monster.race = "venom" +monster.corpse = 6532 +monster.speed = 260 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 85, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "DisgustingOozeDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Blubb", yell = false}, + {text = "Blubb Blubb", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 272}, + {id = 2152, chance = 95660, maxCount = 6}, + {id = 6500, chance = 20340}, + {id = 5944, chance = 20130}, + {id = 9967, chance = 14190}, + {id = 9968, chance = 11550}, + {id = 2151, chance = 5930}, + {id = 2149, chance = 5400, maxCount = 3}, + {id = 2147, chance = 2750, maxCount = 2}, + {id = 2145, chance = 2650, maxCount = 2}, + {id = 6300, chance = 2440}, + {id = 2156, chance = 1590}, + {id = 2154, chance = 1380}, + {id = 2155, chance = 640}, + {id = 2158, chance = 320} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 80, condition = {type = CONDITION_POISON, totalDamage = 300, interval = 4000}}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_LIFEDRAIN, minDamage = -160, maxDamage = -295, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_HITBYPOISON, target = true}, + {name ="defiler paralyze 3", interval = 2000, chance = 9, target = false}, + {name ="defiler paralyze 1", interval = 2000, chance = 6, target = false}, + {name ="defiler paralyze 2", interval = 2000, chance = 8, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -300, maxDamage = -500, radius = 8, effect = CONST_ME_HITBYPOISON, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -400, maxDamage = -725, length = 8, spread = 3, effect = CONST_ME_SMALLPLANTS, target = false}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_EARTHDAMAGE, minDamage = -120, maxDamage = -170, radius = 3, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 250, maxDamage = 450, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -25}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/ferumbras_essence.lua b/data/monster/quests/ferumbras_ascendant/ferumbras_essence.lua new file mode 100644 index 00000000000..a563d1bf265 --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/ferumbras_essence.lua @@ -0,0 +1,102 @@ +local mType = Game.createMonsterType("Ferumbras Essence") +local monster = {} + +monster.description = "a ferumbras essence" +monster.experience = 0 +monster.outfit = { + lookType = 294, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 115 +monster.maxHealth = 115 +monster.race = "undead" +monster.corpse = 10508 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 9 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -130, maxDamage = -270, range = 1, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_MANADRAIN, minDamage = -110, maxDamage = -270, radius = 9, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.defenses = { + defense = 15, + armor = 10, + {name ="speed", interval = 2000, chance = 8, speedChange = 240, effect = CONST_ME_MAGIC_GREEN, target = false, duration = 20000}, + {name ="combat", interval = 2000, chance = 11, type = COMBAT_HEALING, minDamage = 15, maxDamage = 25, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/lovely/lovely_deer.lua b/data/monster/quests/ferumbras_ascendant/lovely/lovely_deer.lua new file mode 100644 index 00000000000..777594617de --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/lovely/lovely_deer.lua @@ -0,0 +1,102 @@ +local mType = Game.createMonsterType("Lovely Deer") +local monster = {} + +monster.description = "a lovely deer" +monster.experience = 0 +monster.outfit = { + lookType = 31, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 25 +monster.maxHealth = 25 +monster.race = "blood" +monster.corpse = 5970 +monster.speed = 196 +monster.manaCost = 260 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = false, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 11214, chance = 850}, + {id = 2666, chance = 79550, maxCount = 4}, + {id = 2671, chance = 51330, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 2} +} + +monster.defenses = { + defense = 2, + armor = 2 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/lovely/lovely_frazzlemaw.lua b/data/monster/quests/ferumbras_ascendant/lovely/lovely_frazzlemaw.lua new file mode 100644 index 00000000000..93ad38d6568 --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/lovely/lovely_frazzlemaw.lua @@ -0,0 +1,138 @@ +local mType = Game.createMonsterType("Lovely Frazzlemaw") +local monster = {} + +monster.description = "a lovely frazzlemaw" +monster.experience = 3400 +monster.outfit = { + lookType = 594, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 4100 +monster.maxHealth = 4100 +monster.race = "blood" +monster.corpse = 22567 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Mwaaaahnducate youuuuuu *gurgle*, mwaaah!", yell = false}, + {text = "Mmmwahmwahmwahah, mwaaah!", yell = false}, + {text = "MMMWAHMWAHMWAHMWAAAAH!", yell = true} +} + +monster.loot = { + {id = 22396, chance = 490}, + {id = 22532, chance = 18560}, + {id = 2148, chance = 100000, maxCount = 100}, + {id = 7591, chance = 14490, maxCount = 2}, + {id = 7590, chance = 14810, maxCount = 3}, + {id = 2152, chance = 100000, maxCount = 7}, + {id = 2219, chance = 9920}, + {id = 2225, chance = 10210}, + {id = 2226, chance = 10040}, + {id = 2229, chance = 12380}, + {id = 2230, chance = 9510}, + {id = 2231, chance = 5360}, + {id = 2667, chance = 6780, maxCount = 3}, + {id = 2671, chance = 5960, maxCount = 2}, + {id = 5880, chance = 3000}, + {id = 5895, chance = 4650}, + {id = 5925, chance = 5190}, + {id = 5951, chance = 10670}, + {id = 7404, chance = 990}, + {id = 7407, chance = 2110}, + {id = 2377, chance = 3170}, + {id = 7418, chance = 1030}, + {id = 9971, chance = 2330}, + {id = 11306, chance = 1600}, + {id = 18414, chance = 3000}, + {id = 18417, chance = 15640}, + {id = 18420, chance = 5230}, + {id = 18554, chance = 9640}, + {id = 22533, chance = 15990}, + {id = 2240, chance = 9430} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 80}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -400, radius = 3, target = false}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_LIFEDRAIN, minDamage = -100, maxDamage = -700, length = 5, spread = 3, effect = CONST_ME_EXPLOSIONAREA, target = true}, + -- bleed + {name ="condition", type = CONDITION_BLEEDING, interval = 2000, chance = 16, minDamage = -400, maxDamage = -600, radius = 2, shootEffect = CONST_ANI_LARGEROCK, effect = CONST_ME_STONES, target = true}, + {name ="frazzlemaw paralyze", interval = 2000, chance = 15, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_HEALING, minDamage = 250, maxDamage = 425, effect = CONST_ME_HITBYPOISON, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/lovely/lovely_polar_bear.lua b/data/monster/quests/ferumbras_ascendant/lovely/lovely_polar_bear.lua new file mode 100644 index 00000000000..7e8e513c228 --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/lovely/lovely_polar_bear.lua @@ -0,0 +1,104 @@ +local mType = Game.createMonsterType("Lovely Polar Bear") +local monster = {} + +monster.description = "a lovely polar bear" +monster.experience = 28 +monster.outfit = { + lookType = 42, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 85 +monster.maxHealth = 85 +monster.race = "blood" +monster.corpse = 5987 +monster.speed = 156 +monster.manaCost = 315 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 5, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grrrrrr", yell = false}, + {text = "GROARRR!", yell = true} +} + +monster.loot = { + {id = 10567, chance = 930}, + {id = 2671, chance = 50760, maxCount = 2}, + {id = 2666, chance = 51080, maxCount = 4} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 30} +} + +monster.defenses = { + defense = 10, + armor = 7 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/lovely/lovely_rotworm.lua b/data/monster/quests/ferumbras_ascendant/lovely/lovely_rotworm.lua new file mode 100644 index 00000000000..3f5dd176bfe --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/lovely/lovely_rotworm.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Lovely Rotworm") +local monster = {} + +monster.description = "a lovely rotworm" +monster.experience = 40 +monster.outfit = { + lookType = 26, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 65 +monster.maxHealth = 65 +monster.race = "blood" +monster.corpse = 5967 +monster.speed = 116 +monster.manaCost = 305 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 71770, maxCount = 17}, + {id = 3976, chance = 3010, maxCount = 3}, + {id = 2666, chance = 19940}, + {id = 10609, chance = 9990}, + {id = 2671, chance = 20130}, + {id = 2376, chance = 3110}, + {id = 2398, chance = 4540} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 30, attack = 20} +} + +monster.defenses = { + defense = 11, + armor = 8 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/lovely/lovely_scorpion.lua b/data/monster/quests/ferumbras_ascendant/lovely/lovely_scorpion.lua new file mode 100644 index 00000000000..50731ec84c1 --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/lovely/lovely_scorpion.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Lovely Scorpion") +local monster = {} + +monster.description = "a lovely scorpion" +monster.experience = 45 +monster.outfit = { + lookType = 43, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 45 +monster.maxHealth = 45 +monster.race = "venom" +monster.corpse = 5988 +monster.speed = 150 +monster.manaCost = 310 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 5, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 10568, chance = 4970} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 30, attack = 25, condition = {type = CONDITION_POISON, totalDamage = 350, interval = 4000}} +} + +monster.defenses = { + defense = 5, + armor = 14 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/lovely/lovely_snake.lua b/data/monster/quests/ferumbras_ascendant/lovely/lovely_snake.lua new file mode 100644 index 00000000000..129b2589b7e --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/lovely/lovely_snake.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Lovely Snake") +local monster = {} + +monster.description = "a lovely snake" +monster.experience = 10 +monster.outfit = { + lookType = 28, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 15 +monster.maxHealth = 15 +monster.race = "blood" +monster.corpse = 2817 +monster.speed = 120 +monster.manaCost = 205 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Zzzzzzt", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 8, condition = {type = CONDITION_POISON, totalDamage = 20, interval = 4000}} +} + +monster.defenses = { + defense = 1, + armor = 0 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/lovely/lovely_souleater.lua b/data/monster/quests/ferumbras_ascendant/lovely/lovely_souleater.lua new file mode 100644 index 00000000000..8f6b47c6eb9 --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/lovely/lovely_souleater.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Lovely Souleater") +local monster = {} + +monster.description = "a lovely souleater" +monster.experience = 1300 +monster.outfit = { + lookType = 355, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1100 +monster.maxHealth = 1100 +monster.race = "undead" +monster.corpse = 12631 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Life is such a fickle thing!", yell = false}, + {text = "I will devour your soul.", yell = false}, + {text = "Souuuls!", yell = false}, + {text = "I will feed on you.", yell = false}, + {text = "Aaaahh", yell = false} +} + +monster.loot = { + {id = 12637, chance = 1990}, + {id = 12635, chance = 20}, + {id = 2148, chance = 88060, maxCount = 200}, + {id = 12636, chance = 15060}, + {id = 7590, chance = 7960}, + {id = 8473, chance = 9400}, + {id = 2152, chance = 49610, maxCount = 6}, + {id = 2189, chance = 910}, + {id = 2185, chance = 980}, + {id = 6300, chance = 330}, + {id = 5884, chance = 140} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 60, attack = 60}, + {name ="souleater drown", interval = 2000, chance = 9, target = false}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_ICEDAMAGE, minDamage = -50, maxDamage = -100, radius = 1, shootEffect = CONST_ANI_ICE, effect = CONST_ME_ICEATTACK, target = true}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_LIFEDRAIN, minDamage = -10, maxDamage = -60, radius = 4, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="souleater wave", interval = 2000, chance = 12, minDamage = -100, maxDamage = -210, target = false} +} + +monster.defenses = { + defense = 20, + armor = 25, + {name ="invisible", interval = 2000, chance = 12, effect = CONST_ME_POFF}, + {name ="combat", interval = 2000, chance = 16, type = COMBAT_HEALING, minDamage = 130, maxDamage = 205, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/lovely/lovely_yielothax.lua b/data/monster/quests/ferumbras_ascendant/lovely/lovely_yielothax.lua new file mode 100644 index 00000000000..c7877dc076f --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/lovely/lovely_yielothax.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Lovely Yielothax") +local monster = {} + +monster.description = "a lovely yielothax" +monster.experience = 1250 +monster.outfit = { + lookType = 408, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "venom" +monster.corpse = 13752 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "IIEEH!! Iiih iih ih iiih!!!", yell = true}, + {text = "Iiiieeeh iiiieh iiieeh!", yell = true}, + {text = "Bsssmm bssmm bsssmmm", yell = true} +} + +monster.loot = { + {id = 7440, chance = 490}, + {id = 13881, chance = 300}, + {id = 13942, chance = 320}, + {id = 2148, chance = 99800, maxCount = 227}, + {id = 2789, chance = 9930, maxCount = 3}, + {id = 7588, chance = 19910}, + {id = 7589, chance = 19920}, + {id = 2145, chance = 4860, maxCount = 5}, + {id = 2151, chance = 950}, + {id = 2164, chance = 4020}, + {id = 13877, chance = 270}, + {id = 2189, chance = 510}, + {id = 2438, chance = 520}, + {id = 10221, chance = 570}, + {id = 7889, chance = 830}, + {id = 7895, chance = 480} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 70, attack = 50}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_LIFEDRAIN, minDamage = -70, maxDamage = -130, length = 4, spread = 3, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -50, maxDamage = -150, length = 5, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -75, maxDamage = -120, radius = 3, shootEffect = CONST_ANI_EARTH, effect = CONST_ME_HITBYPOISON, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -120, maxDamage = -215, radius = 3, effect = CONST_ME_HITBYPOISON, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 13, minDamage = -50, maxDamage = -50, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_HITBYPOISON, target = true} +} + +monster.defenses = { + defense = 45, + armor = 30, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 100, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/rage_of_mazoran.lua b/data/monster/quests/ferumbras_ascendant/rage_of_mazoran.lua new file mode 100644 index 00000000000..c474881408c --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/rage_of_mazoran.lua @@ -0,0 +1,103 @@ +local mType = Game.createMonsterType("Rage of Mazoran") +local monster = {} + +monster.description = "a rage of mazoran" +monster.experience = 3900 +monster.outfit = { + lookType = 243, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3800 +monster.maxHealth = 3800 +monster.race = "fire" +monster.corpse = 6324 +monster.speed = 330 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 120, attack = 80}, + {name ="firefield", interval = 2000, chance = 11, range = 7, radius = 3, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_FIREDAMAGE, minDamage = -390, maxDamage = -1500, length = 8, spread = 3, effect = CONST_ME_FIREATTACK, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_FIREDAMAGE, minDamage = -65, maxDamage = -330, range = 7, radius = 3, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="hellfire fighter soulfire", interval = 2000, chance = 10, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 25}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -25}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/summons/enthralled_demon.lua b/data/monster/quests/ferumbras_ascendant/summons/enthralled_demon.lua new file mode 100644 index 00000000000..064a3a43d0c --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/summons/enthralled_demon.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Enthralled Demon") +local monster = {} + +monster.description = "an enthralled demon" +monster.experience = 6000 +monster.outfit = { + lookType = 35, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 8200 +monster.maxHealth = 8200 +monster.race = "fire" +monster.corpse = 0 +monster.speed = 256 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "MUHAHAHAHA!", yell = true}, + {text = "I SMELL FEEEEEAAAR!", yell = true}, + {text = "CHAMEK ATH UTHUL ARAK!", yell = true}, + {text = "Your resistance is futile!", yell = false}, + {text = "Your soul will be mine!", yell = true} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 70, attack = 130}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_MANADRAIN, minDamage = -60, maxDamage = -120, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 33, type = COMBAT_FIREDAMAGE, minDamage = -150, maxDamage = -250, range = 7, radius = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_DROWNDAMAGE, minDamage = -350, maxDamage = -450, radius = 7, target = false}, + {name ="combat", interval = 2000, chance = 7, type = COMBAT_ENERGYDAMAGE, minDamage = -210, maxDamage = -300, range = 1, radius = 1, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="firefield", interval = 2000, chance = 14, range = 7, radius = 1, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="demon paralyze", interval = 2000, chance = 10, range = 7, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -300, maxDamage = -480, length = 8, spread = 3, effect = CONST_ME_PURPLEENERGY, target = false} +} + +monster.defenses = { + defense = 65, + armor = 40, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_HEALING, minDamage = 150, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = 388, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/summons/rift_fragment.lua b/data/monster/quests/ferumbras_ascendant/summons/rift_fragment.lua new file mode 100644 index 00000000000..f14348df3de --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/summons/rift_fragment.lua @@ -0,0 +1,95 @@ +local mType = Game.createMonsterType("Rift Fragment") +local monster = {} + +monster.description = "a rift fragment" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 1491 +} + +monster.health = 7200 +monster.maxHealth = 7200 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 1400, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 13}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_DROWNDAMAGE, minDamage = -260, maxDamage = -320, radius = 6, effect = CONST_ME_BUBBLES, target = false}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_DROWNDAMAGE, minDamage = -160, maxDamage = -320, range = 6, effect = CONST_ME_BUBBLES, target = false} +} + +monster.defenses = { + defense = 65, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/summons/rift_invader.lua b/data/monster/quests/ferumbras_ascendant/summons/rift_invader.lua new file mode 100644 index 00000000000..cd465bb10b0 --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/summons/rift_invader.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("Rift Invader") +local monster = {} + +monster.description = "a rift invader" +monster.experience = 6000 +monster.outfit = { + lookType = 290, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 8200 +monster.maxHealth = 8200 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 256 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "RiftInvaderDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 70, attack = 130}, + {name ="combat", interval = 2000, chance = 33, type = COMBAT_ENERGYDAMAGE, minDamage = -450, maxDamage = -550, range = 7, radius = 5, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="combat", interval = 2000, chance = 7, type = COMBAT_ENERGYDAMAGE, minDamage = -210, maxDamage = -300, range = 1, radius = 2, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_DEATHDAMAGE, minDamage = -200, maxDamage = -300, range = 7, radius = 3, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -300, maxDamage = -480, target = true} +} + +monster.defenses = { + defense = 65, + armor = 40, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_HEALING, minDamage = 150, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = 388, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -15}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/traps/bone_capsule.lua b/data/monster/quests/ferumbras_ascendant/traps/bone_capsule.lua new file mode 100644 index 00000000000..e7bd6bd9734 --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/traps/bone_capsule.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Bone Capsule") +local monster = {} + +monster.description = "a bone capsule" +monster.experience = 0 +monster.outfit = { + lookType = 863, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5000 +monster.maxHealth = 5000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "BoneCapsule" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 20, + armor = 22 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/traps/despair.lua b/data/monster/quests/ferumbras_ascendant/traps/despair.lua new file mode 100644 index 00000000000..a3b817443ac --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/traps/despair.lua @@ -0,0 +1,89 @@ +local mType = Game.createMonsterType("Despair") +local monster = {} + +monster.description = "a despair" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 22386 +} + +monster.health = 100000 +monster.maxHealth = 100000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 44, + armor = 22 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/traps/electric_sparks.lua b/data/monster/quests/ferumbras_ascendant/traps/electric_sparks.lua new file mode 100644 index 00000000000..5c93ae080da --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/traps/electric_sparks.lua @@ -0,0 +1,93 @@ +local mType = Game.createMonsterType("Electric Sparks") +local monster = {} + +monster.description = "Electric Sparks" +monster.experience = 320 +monster.outfit = { + lookTypeEx = 460 +} + +monster.health = 2000 +monster.maxHealth = 2000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = true, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="combat", interval = 2000, chance = 50, type = COMBAT_ENERGYDAMAGE, minDamage = -150, maxDamage = -250, range = 1, shootEffect = CONST_ANI_ENERGY, target = false} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/traps/eruption_of_destruction.lua b/data/monster/quests/ferumbras_ascendant/traps/eruption_of_destruction.lua new file mode 100644 index 00000000000..7de072ff402 --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/traps/eruption_of_destruction.lua @@ -0,0 +1,94 @@ +local mType = Game.createMonsterType("Eruption of Destruction") +local monster = {} + +monster.description = "an eruption of destruction" +monster.experience = 320 +monster.outfit = { + lookTypeEx = 389 +} + +monster.health = 4000 +monster.maxHealth = 4000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 120 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="speed", interval = 2000, chance = 25, speedChange = -600, radius = 7, effect = CONST_ME_LOSEENERGY, target = false, duration = 15000}, + {name ="eruption of destruction explosion", interval = 2000, chance = 250, minDamage = -4000, maxDamage = -6000, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/traps/guilt.lua b/data/monster/quests/ferumbras_ascendant/traps/guilt.lua new file mode 100644 index 00000000000..2d95a9d1a3a --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/traps/guilt.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Guilt") +local monster = {} + +monster.description = "Guilt from Tarbaz" +monster.experience = 320 +monster.outfit = { + lookType = 583, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2000 +monster.maxHealth = 2000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="combat", interval = 2000, chance = 50, type = COMBAT_PHYSICALDAMAGE, minDamage = -300, maxDamage = -400, range = 7, shootEffect = CONST_ANI_ENERGY, target = false} +} + +monster.defenses = { + defense = 199, + armor = 199 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/ferumbras_ascendant/traps/void.lua b/data/monster/quests/ferumbras_ascendant/traps/void.lua new file mode 100644 index 00000000000..c331be250bb --- /dev/null +++ b/data/monster/quests/ferumbras_ascendant/traps/void.lua @@ -0,0 +1,93 @@ +local mType = Game.createMonsterType("Void") +local monster = {} + +monster.description = "void" +monster.experience = 320 +monster.outfit = { + lookTypeEx = 460 +} + +monster.health = 2000 +monster.maxHealth = 2000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 10 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = true, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Enthralled Demon", chance = 25, interval = 2000, max = 10} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/animated_sword.lua b/data/monster/quests/forgotten_knowledge/animated_sword.lua new file mode 100644 index 00000000000..4bb0b72c41a --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/animated_sword.lua @@ -0,0 +1,96 @@ +local mType = Game.createMonsterType("Animated Sword") +local monster = {} + +monster.description = "an animated sword" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 26895 +} + +monster.health = 2000 +monster.maxHealth = 2000 +monster.race = "fire" +monster.corpse = 0 +monster.speed = 360 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 50}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_MANADRAIN, minDamage = -40, maxDamage = -160, radius = 6, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="berserk", interval = 2000, chance = 15, minDamage = -40, maxDamage = -160, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -40, maxDamage = -100, length = 4, spread = 3, effect = CONST_ME_ENERGYHIT, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/baby_dragon.lua b/data/monster/quests/forgotten_knowledge/baby_dragon.lua new file mode 100644 index 00000000000..f7067e547ed --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/baby_dragon.lua @@ -0,0 +1,102 @@ +local mType = Game.createMonsterType("Baby Dragon") +local monster = {} + +monster.description = "a baby dragon" +monster.experience = 185 +monster.outfit = { + lookType = 271, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 380 +monster.maxHealth = 380 +monster.race = "blood" +monster.corpse = 7621 +monster.speed = 176 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 30, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 45, attack = 20}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_FIREDAMAGE, minDamage = -60, maxDamage = -90, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_FIREDAMAGE, minDamage = -30, maxDamage = -55, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true} +} + +monster.defenses = { + defense = 38, + armor = 25, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_HEALING, minDamage = 5, maxDamage = 35, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/bosses/dragonking_zyrtarch.lua b/data/monster/quests/forgotten_knowledge/bosses/dragonking_zyrtarch.lua new file mode 100644 index 00000000000..abf8249ccba --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/bosses/dragonking_zyrtarch.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Dragonking Zyrtarch") +local monster = {} + +monster.description = "dragonking zyrtarch" +monster.experience = 1600 +monster.outfit = { + lookType = 938, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 150000 +monster.maxHealth = 150000 +monster.race = "fire" +monster.corpse = 27733 +monster.speed = 280 +monster.manaCost = 290 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 112, attack = 85}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -110, maxDamage = -495, range = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -110, maxDamage = -495, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -110, maxDamage = -495, radius = 5, effect = CONST_ME_BLOCKHIT, target = false}, + -- fire + {name ="condition", type = CONDITION_FIRE, interval = 2000, chance = 15, minDamage = -1100, maxDamage = -1100, radius = 5, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -710, maxDamage = -895, length = 9, spread = 4, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -710, maxDamage = -895, length = 9, spread = 3, effect = CONST_ME_HITBYFIRE, target = false} +} + +monster.defenses = { + defense = 64, + armor = 52 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/bosses/lady_tenebris.lua b/data/monster/quests/forgotten_knowledge/bosses/lady_tenebris.lua new file mode 100644 index 00000000000..85384440d01 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/bosses/lady_tenebris.lua @@ -0,0 +1,163 @@ +local mType = Game.createMonsterType("Lady Tenebris") +local monster = {} + +monster.description = "Lady Tenebris" +monster.experience = 50000 +monster.outfit = { + lookType = 433, + lookHead = 57, + lookBody = 95, + lookLegs = 38, + lookFeet = 94, + lookAddons = 2, + lookMount = 0 +} + +monster.health = 150000 +monster.maxHealth = 150000 +monster.race = "blood" +monster.corpse = 6560 +monster.speed = 370 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 98, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "HealthForgotten" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "May the embrace of darkness kill you!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 10000, maxCount = 50}, + {id = 2152, chance = 10000, maxCount = 50}, + {id = 2150, chance = 10000, maxCount = 10}, + {id = 2145, chance = 10000, maxCount = 10}, + {id = 2147, chance = 10000, maxCount = 10}, + {id = 9970, chance = 10000, maxCount = 10}, + {id = 7590, chance = 10000, maxCount = 100}, + {id = 8472, chance = 10000, maxCount = 100}, + {id = 22396, chance = 2000, maxCount = 2}, + {id = 18413, chance = 2000, maxCount = 3}, + {id = 18415, chance = 5000, maxCount = 5}, + {id = 22396, chance = 2000, maxCount = 2}, + {id = 18414, chance = 5000, maxCount = 3}, + {id = 7632, chance = 6000}, + {id = 2155, chance = 2000}, + {id = 7440, chance = 2000}, + {id = 24851, chance = 2000}, + {id = 2156, chance = 1000}, + {id = 2123, chance = 2000}, + {id = 7451, chance = 2000}, + {id = 8903, chance = 1000}, + {id = 8901, chance = 1000}, + {id = 2436, chance = 1000}, + {id = 2154, chance = 1000}, + {id = 18390, chance = 1000}, + {id = 25377, chance = 100000}, + {id = 25172, chance = 100000}, + {id = 2453, chance = 200}, + {id = 27641, chance = 200}, + {id = 27642, chance = 200}, + {id = 25411, chance = 200}, + {id = 22422, chance = 200}, + {id = 27625, chance = 500, unique = true}, + {id = 2138, chance = 200}, + {id = 22423, chance = 200} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -800, maxDamage = -1300}, + {name ="combat", interval = 6000, chance = 13, type = COMBAT_DEATHDAMAGE, minDamage = -1200, maxDamage = -1500, length = 8, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_DEATHDAMAGE, minDamage = -400, maxDamage = -600, radius = 4, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="tenebris summon", interval = 2000, chance = 14, target = false}, + {name ="tenebris ultimate", interval = 15000, chance = 30, target = false} +} + +monster.defenses = { + defense = 65, + armor = 55, + {name ="combat", interval = 3000, chance = 25, type = COMBAT_HEALING, minDamage = 600, maxDamage = 2700, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 320, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 80}, + {type = COMBAT_DEATHDAMAGE , percent = 80} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/bosses/lloyd.lua b/data/monster/quests/forgotten_knowledge/bosses/lloyd.lua new file mode 100644 index 00000000000..727ab1d25c7 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/bosses/lloyd.lua @@ -0,0 +1,159 @@ +local mType = Game.createMonsterType("Lloyd") +local monster = {} + +monster.description = "Lloyd" +monster.experience = 50000 +monster.outfit = { + lookType = 940, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 64000 +monster.maxHealth = 64000 +monster.race = "venom" +monster.corpse = 27595 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "LloydPrepareDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 97000, maxCount = 200}, + {id = 2152, chance = 90000, maxCount = 30}, + {id = 7590, chance = 22120, maxCount = 3}, + {id = 8473, chance = 19500, maxCount = 3}, + {id = 2493, chance = 1000}, + {id = 18413, chance = 9660, maxCount = 5}, + {id = 18414, chance = 9660, maxCount = 5}, + {id = 18415, chance = 9660, maxCount = 5}, + {id = 2149, chance = 9660, maxCount = 5}, + {id = 2147, chance = 7360, maxCount = 5}, + {id = 9970, chance = 7350, maxCount = 5}, + {id = 2150, chance = 7150, maxCount = 5}, + {id = 5888, chance = 5888, maxCount = 2}, + {id = 5887, chance = 5909, maxCount = 2}, + {id = 7424, chance = 5000}, + {id = 2158, chance = 5000}, + {id = 2155, chance = 5000}, + {id = 2154, chance = 5000}, + {id = 2195, chance = 5000}, + {id = 26182, chance = 5000}, + {id = 5891, chance = 5000}, + {id = 7895, chance = 5000}, + {id = 12410, chance = 5000}, + {id = 7440, chance = 5000}, + {id = 5904, chance = 5000}, + {id = 27627, chance = 500, unique = true}, + {id = 2214, chance = 1970}, + {id = 8920, chance = 1970}, + {id = 8900, chance = 1970}, + {id = 11355, chance = 1970}, + {id = 25383, chance = 1970}, + {id = 25377, chance = 100000}, + {id = 25172, chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -200, maxDamage = -1400}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = -130, maxDamage = -460, length = 6, spread = 3, effect = CONST_ME_PURPLEENERGY, target = false}, + {name ="lloyd wave", interval = 2000, chance = 12, minDamage = -430, maxDamage = -560, target = false}, + {name ="lloyd wave2", interval = 2000, chance = 12, minDamage = -230, maxDamage = -460, target = false}, + {name ="lloyd wave3", interval = 2000, chance = 12, minDamage = -430, maxDamage = -660, target = false} +} + +monster.defenses = { + defense = 55, + armor = 55, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 180, maxDamage = 250, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/bosses/melting_frozen_horror.lua b/data/monster/quests/forgotten_knowledge/bosses/melting_frozen_horror.lua new file mode 100644 index 00000000000..f8ec7958a2c --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/bosses/melting_frozen_horror.lua @@ -0,0 +1,149 @@ +local mType = Game.createMonsterType("Melting Frozen Horror") +local monster = {} + +monster.description = "a melting frozen horror" +monster.experience = 0 +monster.outfit = { + lookType = 261, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 70000 +monster.maxHealth = 70000 +monster.race = "undead" +monster.corpse = 7282 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Chrrrrrk! Chrrrk!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2148, chance = 100000, maxCount = 11}, + {id = 10578, chance = 14111}, + {id = 7441, chance = 5100}, + {id = 2396, chance = 320}, + {id = 7449, chance = 580}, + {id = 2145, chance = 730}, + {id = 18414, chance = 9660, maxCount = 5}, + {id = 2158, chance = 5000}, + {id = 8473, chance = 19500, maxCount = 3}, + {id = 18415, chance = 9660, maxCount = 5}, + {id = 7459, chance = 9660}, + {id = 26174, chance = 9660}, + {id = 2445, chance = 9660}, + {id = 18450, chance = 9660}, + {id = 18465, chance = 200}, + {id = 15644, chance = 200}, + {id = 8887, chance = 500}, + {id = 27626, chance = 500, unique = true}, + {id = 21697, chance = 200}, + {id = 25377, chance = 100000}, + {id = 25172, chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 100, attack = 60}, + {name ="hirintror freeze", interval = 2000, chance = 15, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -75, maxDamage = -150, range = 7, radius = 3, shootEffect = CONST_ANI_ICE, effect = CONST_ME_BLOCKHIT, target = true}, + {name ="ice golem paralyze", interval = 2000, chance = 11, target = false}, + {name ="hirintror skill reducer", interval = 2000, chance = 10, target = false} +} + +monster.defenses = { + defense = 60, + armor = 60, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, radius = 7, effect = CONST_ME_BLOCKHIT, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -50} +} + +monster.heals = { + {type = COMBAT_ICEDAMAGE, percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/bosses/mounted_thorn_knight.lua b/data/monster/quests/forgotten_knowledge/bosses/mounted_thorn_knight.lua new file mode 100644 index 00000000000..cbbbd904d9c --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/bosses/mounted_thorn_knight.lua @@ -0,0 +1,111 @@ +local mType = Game.createMonsterType("Mounted Thorn Knight") +local monster = {} + +monster.description = "mounted thorn knight" +monster.experience = 15000 +monster.outfit = { + lookType = 512, + lookHead = 81, + lookBody = 121, + lookLegs = 121, + lookFeet = 121, + lookAddons = 3, + lookMount = 626 +} + +monster.health = 100000 +monster.maxHealth = 100000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 430 +monster.manaCost = 290 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "ThornKnightDeath", + "HealthForgotten" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -600, maxDamage = -1000}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_LIFEDRAIN, minDamage = -400, maxDamage = -700, length = 4, spread = 3, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_MANADRAIN, minDamage = -1400, maxDamage = -1700, length = 9, spread = 3, effect = CONST_ME_CARNIPHILA, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_DEATHDAMAGE, minDamage = -400, maxDamage = -700, length = 9, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -250, radius = 10, effect = CONST_ME_BLOCKHIT, target = false} +} + +monster.defenses = { + defense = 60, + armor = 60, + {name ="thorn summon", interval = 2000, chance = 20, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 1550, maxDamage = 2550, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 1000, chance = 12, speedChange = 620, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 80}, + {type = COMBAT_ENERGYDAMAGE, percent = 80}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 80}, + {type = COMBAT_HOLYDAMAGE , percent = 80}, + {type = COMBAT_DEATHDAMAGE , percent = 80} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/bosses/solid_frozen_horror.lua b/data/monster/quests/forgotten_knowledge/bosses/solid_frozen_horror.lua new file mode 100644 index 00000000000..e9edf99ab80 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/bosses/solid_frozen_horror.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("Solid Frozen Horror") +local monster = {} + +monster.description = "a solid frozen horror" +monster.experience = 0 +monster.outfit = { + lookType = 261, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 70000 +monster.maxHealth = 70000 +monster.race = "undead" +monster.corpse = 7282 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Chrrrrrk! Chrrrk!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 100, attack = 60}, + {name ="hirintror freeze", interval = 2000, chance = 15, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -75, maxDamage = -150, range = 7, radius = 3, shootEffect = CONST_ANI_ICE, effect = CONST_ME_BLOCKHIT, target = true}, + {name ="ice golem paralyze", interval = 2000, chance = 11, target = false}, + {name ="hirintror skill reducer", interval = 2000, chance = 10, target = false} +} + +monster.defenses = { + defense = 60, + armor = 60, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, radius = 7, effect = CONST_ME_BLOCKHIT, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/bosses/soul_of_dragonking_zyrtarch.lua b/data/monster/quests/forgotten_knowledge/bosses/soul_of_dragonking_zyrtarch.lua new file mode 100644 index 00000000000..33dbc8755c7 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/bosses/soul_of_dragonking_zyrtarch.lua @@ -0,0 +1,159 @@ +local mType = Game.createMonsterType("Soul of Dragonking Zyrtarch") +local monster = {} + +monster.description = "soul of dragonking zyrtarch" +monster.experience = 70700 +monster.outfit = { + lookType = 938, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 150000 +monster.maxHealth = 150000 +monster.race = "fire" +monster.corpse = 27733 +monster.speed = 500 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 25377, chance = 100000}, + {id = 25172, chance = 100000}, + {id = 2148, chance = 97000, maxCount = 100}, + {id = 2148, chance = 97000, maxCount = 100}, + {id = 2154, chance = 1000}, + {id = 5882, chance = 5000}, + {id = 5889, chance = 500}, + {id = 9980, chance = 500}, + {id = 12644, chance = 300}, + {id = 9970, chance = 3000, maxCount = 5}, + {id = 2149, chance = 3000, maxCount = 5}, + {id = 9971, chance = 500}, + {id = 11308, chance = 100}, + {id = 2150, chance = 3000, maxCount = 5}, + {id = 8849, chance = 500}, + {id = 2158, chance = 1000}, + {id = 8472, chance = 3000, maxCount = 3}, + {id = 2506, chance = 15, unique = true}, + {id = 2156, chance = 1000}, + {id = 18414, chance = 3000, maxCount = 5}, + {id = 18415, chance = 3000, maxCount = 5}, + {id = 5887, chance = 500}, + {id = 7590, chance = 3000, maxCount = 3}, + {id = 2155, chance = 1000}, + {id = 5948, chance = 5000}, + {id = 5904, chance = 500}, + {id = 27623, chance = 500, unique = true}, + {id = 18413, chance = 3000, maxCount = 5}, + {id = 7632, chance = 500}, + {id = 8473, chance = 3000, maxCount = 3}, + {id = 8902, chance = 500}, + {id = 12648, chance = 300, unique = true}, + {id = 2152, chance = 90000, maxCount = 6}, + {id = 2147, chance = 3000, maxCount = 5} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 112, attack = 85}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -110, maxDamage = -495, range = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -110, maxDamage = -495, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_MANADRAIN, minDamage = -110, maxDamage = -495, radius = 8, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="charged energy elemental electrify", interval = 2000, chance = 15, minDamage = -1100, maxDamage = -1100, radius = 5, effect = CONST_ME_YELLOWENERGY, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -710, maxDamage = -895, length = 9, spread = 4, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -710, maxDamage = -895, length = 9, spread = 4, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -710, maxDamage = -895, length = 9, spread = 3, effect = CONST_ME_FIREAREA, target = false} +} + +monster.defenses = { + defense = 64, + armor = 52, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 450, maxDamage = 550, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 1}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/bosses/the_blazing_time_guardian.lua b/data/monster/quests/forgotten_knowledge/bosses/the_blazing_time_guardian.lua new file mode 100644 index 00000000000..b6296ce5133 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/bosses/the_blazing_time_guardian.lua @@ -0,0 +1,146 @@ +local mType = Game.createMonsterType("The Blazing Time Guardian") +local monster = {} + +monster.description = "the blazing time guardian" +monster.experience = 50000 +monster.outfit = { + lookType = 944, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 150000 +monster.maxHealth = 150000 +monster.race = "undead" +monster.corpse = 27753 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 8 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "time waster", chance = 3, interval = 2000, max = 8} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2152, chance = 100000, maxCount = 25}, + {id = 9970, chance = 100000, maxCount = 10}, + {id = 7590, chance = 100000, maxCount = 5}, + {id = 8472, chance = 100000, maxCount = 10}, + {id = 18415, chance = 100000, maxCount = 3}, + {id = 18414, chance = 100000, maxCount = 3}, + {id = 12410, chance = 2000}, + {id = 7440, chance = 2000}, + {id = 2214, chance = 2000}, + {id = 2436, chance = 1000}, + {id = 25377, chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 190, attack = 300}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -600, maxDamage = -780, range = 7, radius = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -600, maxDamage = -780, length = 9, spread = 3, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -600, maxDamage = -780, length = 9, spread = 3, effect = CONST_ME_ENERGYAREA, target = false}, + -- energy damage + {name ="condition", type = CONDITION_ENERGY, interval = 2000, chance = 20, minDamage = -2000, maxDamage = -2000, radius = 7, effect = CONST_ME_BLOCKHIT, target = false}, + -- bleed + {name ="condition", type = CONDITION_BLEEDING, interval = 2000, chance = 20, minDamage = -2000, maxDamage = -2000, length = 9, spread = 3, effect = CONST_ME_BLOCKHIT, target = false} +} + +monster.defenses = { + defense = 70, + armor = 70, + {name ="time guardian lost time", interval = 2000, chance = 10, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 70}, + {type = COMBAT_ENERGYDAMAGE, percent = 70}, + {type = COMBAT_EARTHDAMAGE, percent = 70}, + {type = COMBAT_FIREDAMAGE, percent = 70}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -40}, + {type = COMBAT_HOLYDAMAGE , percent = 70}, + {type = COMBAT_DEATHDAMAGE , percent = 70} +} + +monster.heals = { + {type = COMBAT_FIREDAMAGE, percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/bosses/the_enraged_thorn_knight.lua b/data/monster/quests/forgotten_knowledge/bosses/the_enraged_thorn_knight.lua new file mode 100644 index 00000000000..61b989502eb --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/bosses/the_enraged_thorn_knight.lua @@ -0,0 +1,161 @@ +local mType = Game.createMonsterType("The Enraged Thorn Knight") +local monster = {} + +monster.description = "the enraged thorn knight" +monster.experience = 30000 +monster.outfit = { + lookType = 512, + lookHead = 81, + lookBody = 121, + lookLegs = 121, + lookFeet = 121, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "blood" +monster.corpse = 6080 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "HealthForgotten" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 50320, maxCount = 165}, + {id = 2152, chance = 50320, maxCount = 30}, + {id = 18413, chance = 9660, maxCount = 5}, + {id = 18414, chance = 9660, maxCount = 5}, + {id = 18415, chance = 9660, maxCount = 5}, + {id = 2149, chance = 9660, maxCount = 5}, + {id = 2147, chance = 7360, maxCount = 5}, + {id = 9970, chance = 7350, maxCount = 5}, + {id = 2150, chance = 7150, maxCount = 5}, + {id = 5887, chance = 5909, maxCount = 2}, + {id = 7590, chance = 22120, maxCount = 3}, + {id = 8473, chance = 19500, maxCount = 3}, + {id = 8472, chance = 18250, maxCount = 3}, + {id = 2158, chance = 5000}, + {id = 2156, chance = 2200}, + {id = 2155, chance = 5000}, + {id = 2154, chance = 5000}, + {id = 6500, chance = 14460}, + {id = 7439, chance = 14460}, + {id = 7443, chance = 14460}, + {id = 7632, chance = 7000}, + {id = 2407, chance = 20000}, + {id = 7453, chance = 100}, + {id = 27634, chance = 100}, + {id = 5015, chance = 500}, + {id = 2536, chance = 1000}, + {id = 10219, chance = 500}, + {id = 5875, chance = 1000}, + {id = 5884, chance = 1000}, + {id = 8880, chance = 500}, + {id = 22537, chance = 1000}, + {id = 27622, chance = 500, unique = true}, + {id = 25377, chance = 100000}, + {id = 25172, chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -600, maxDamage = -1000}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_LIFEDRAIN, minDamage = -400, maxDamage = -700, length = 4, spread = 3, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_MANADRAIN, minDamage = -1400, maxDamage = -1700, length = 9, spread = 3, effect = CONST_ME_CARNIPHILA, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_DEATHDAMAGE, minDamage = -400, maxDamage = -700, length = 9, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -250, radius = 10, effect = CONST_ME_BLOCKHIT, target = false} +} + +monster.defenses = { + defense = 60, + armor = 60, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 1550, maxDamage = 2550, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 1000, chance = 12, speedChange = 620, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 80}, + {type = COMBAT_ENERGYDAMAGE, percent = 80}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 80}, + {type = COMBAT_HOLYDAMAGE , percent = 80}, + {type = COMBAT_DEATHDAMAGE , percent = 80} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/bosses/the_freezing_time_guardian.lua b/data/monster/quests/forgotten_knowledge/bosses/the_freezing_time_guardian.lua new file mode 100644 index 00000000000..03bdafc3608 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/bosses/the_freezing_time_guardian.lua @@ -0,0 +1,150 @@ +local mType = Game.createMonsterType("The Freezing Time Guardian") +local monster = {} + +monster.description = "the freezing time guardian" +monster.experience = 50000 +monster.outfit = { + lookType = 943, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 150000 +monster.maxHealth = 150000 +monster.race = "undead" +monster.corpse = 27753 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2152, chance = 100000, maxCount = 25}, + {id = 2150, chance = 100000, maxCount = 10}, + {id = 2145, chance = 100000, maxCount = 10}, + {id = 7590, chance = 100000, maxCount = 5}, + {id = 8473, chance = 100000, maxCount = 10}, + {id = 18413, chance = 100000, maxCount = 3}, + {id = 18415, chance = 100000, maxCount = 3}, + {id = 18414, chance = 100000, maxCount = 3}, + {id = 2158, chance = 100000}, + {id = 12410, chance = 2000}, + {id = 7440, chance = 2000}, + {id = 2214, chance = 2000}, + {id = 2153, chance = 2000}, + {id = 2436, chance = 1000}, + {id = 2197, chance = 1000}, + {id = 2539, chance = 100}, + {id = 7417, chance = 100}, + {id = 25377, chance = 100000}, + {id = 25172, chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 190, attack = 300}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -600, maxDamage = -780, range = 7, radius = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -600, maxDamage = -780, length = 9, spread = 3, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -600, maxDamage = -780, length = 9, spread = 3, effect = CONST_ME_ENERGYAREA, target = false}, + -- energy damage + {name ="condition", type = CONDITION_ENERGY, interval = 2000, chance = 20, minDamage = -2000, maxDamage = -2000, radius = 7, effect = CONST_ME_BLOCKHIT, target = false}, + -- bleed + {name ="condition", type = CONDITION_BLEEDING, interval = 2000, chance = 20, minDamage = -2000, maxDamage = -2000, length = 9, spread = 3, effect = CONST_ME_BLOCKHIT, target = false} +} + +monster.defenses = { + defense = 70, + armor = 70, + {name ="time guardian lost time", interval = 2000, chance = 10, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 70}, + {type = COMBAT_ENERGYDAMAGE, percent = 70}, + {type = COMBAT_EARTHDAMAGE, percent = 70}, + {type = COMBAT_FIREDAMAGE, percent = -40}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 70}, + {type = COMBAT_HOLYDAMAGE , percent = 70}, + {type = COMBAT_DEATHDAMAGE , percent = 70} +} + +monster.heals = { + {type = COMBAT_ICEDAMAGE, percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/bosses/the_last_lore_keeper.lua b/data/monster/quests/forgotten_knowledge/bosses/the_last_lore_keeper.lua new file mode 100644 index 00000000000..c3c0caa3f97 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/bosses/the_last_lore_keeper.lua @@ -0,0 +1,149 @@ +local mType = Game.createMonsterType("The Last Lore Keeper") +local monster = {} + +monster.description = "the last lore keeper" +monster.experience = 45000 +monster.outfit = { + lookType = 939, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 750000 +monster.maxHealth = 750000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 450 +monster.manaCost = 0 +monster.maxSummons = 6 + +monster.changeTarget = { + interval = 2000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 340, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "sword of vengeance", chance = 50, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 18413, chance = 3000, maxCount = 3}, + {id = 2148, chance = 50320, maxCount = 200}, + {id = 2152, chance = 50320, maxCount = 35}, + {id = 25377, chance = 3000, maxCount = 3}, + {id = 5909, chance = 3000, maxCount = 4}, + {id = 18414, chance = 3000, maxCount = 3}, + {id = 27758, chance = 500}, + {id = 2154, chance = 1000}, + {id = 2149, chance = 3000, maxCount = 20}, + {id = 7450, chance = 150, unique = true}, + {id = 5880, chance = 3000, maxCount = 2}, + {id = 10549, chance = 1000}, + {id = 2466, chance = 1000}, + {id = 8472, chance = 3000, maxCount = 10}, + {id = 22413, chance = 400}, + {id = 24849, chance = 3000}, + {id = 10577, chance = 1000}, + {id = 5887, chance = 1000}, + {id = 26189, chance = 3000}, + {id = 8473, chance = 3000, maxCount = 5}, + {id = 26031, chance = 3000, maxCount = 5} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 140, attack = 80}, + {name ="combat", interval = 2000, chance = 7, type = COMBAT_PHYSICALDAMAGE, minDamage = -650, maxDamage = -900, length = 8, spread = 3, effect = CONST_ME_EXPLOSIONAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -850, maxDamage = -2260, length = 10, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -640, maxDamage = -800, radius = 5, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -420, maxDamage = -954, length = 8, spread = 3, effect = CONST_ME_PURPLEENERGY, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -640, maxDamage = -800, radius = 5, effect = CONST_ME_STONES, target = true}, + {name ="medusa paralyze", interval = 2000, chance = 20, target = false} +} + +monster.defenses = { + defense = 50, + armor = 50, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 1500, maxDamage = 3000, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/bosses/the_shielded_thorn_knight.lua b/data/monster/quests/forgotten_knowledge/bosses/the_shielded_thorn_knight.lua new file mode 100644 index 00000000000..ac5ae0850ef --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/bosses/the_shielded_thorn_knight.lua @@ -0,0 +1,110 @@ +local mType = Game.createMonsterType("The Shielded Thorn Knight") +local monster = {} + +monster.description = "the shielded thorn knight" +monster.experience = 0 +monster.outfit = { + lookType = 512, + lookHead = 81, + lookBody = 121, + lookLegs = 121, + lookFeet = 121, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 70000 +monster.maxHealth = 70000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 390 +monster.manaCost = 290 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "ThornKnightDeath", + "HealthForgotten" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -600, maxDamage = -1000}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_LIFEDRAIN, minDamage = -400, maxDamage = -700, length = 4, spread = 3, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_MANADRAIN, minDamage = -1400, maxDamage = -1700, length = 9, spread = 3, effect = CONST_ME_CARNIPHILA, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_DEATHDAMAGE, minDamage = -400, maxDamage = -700, length = 9, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -250, radius = 10, effect = CONST_ME_BLOCKHIT, target = false} +} + +monster.defenses = { + defense = 60, + armor = 60, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 1550, maxDamage = 2550, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 1000, chance = 12, speedChange = 620, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 80}, + {type = COMBAT_ENERGYDAMAGE, percent = 80}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 80}, + {type = COMBAT_HOLYDAMAGE , percent = 80}, + {type = COMBAT_DEATHDAMAGE , percent = 80} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/bosses/the_time_guardian.lua b/data/monster/quests/forgotten_knowledge/bosses/the_time_guardian.lua new file mode 100644 index 00000000000..c362fc95fe8 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/bosses/the_time_guardian.lua @@ -0,0 +1,163 @@ +local mType = Game.createMonsterType("The Time Guardian") +local monster = {} + +monster.description = "the time guardian" +monster.experience = 50000 +monster.outfit = { + lookType = 945, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 150000 +monster.maxHealth = 150000 +monster.race = "undead" +monster.corpse = 27753 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "This place is sacred!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2152, chance = 100000, maxCount = 25}, + {id = 2150, chance = 100000, maxCount = 10}, + {id = 2145, chance = 100000, maxCount = 10}, + {id = 2149, chance = 100000, maxCount = 10}, + {id = 2147, chance = 100000, maxCount = 10}, + {id = 9970, chance = 100000, maxCount = 10}, + {id = 7590, chance = 100000, maxCount = 5}, + {id = 8472, chance = 100000, maxCount = 10}, + {id = 8473, chance = 100000, maxCount = 10}, + {id = 18413, chance = 100000, maxCount = 3}, + {id = 18415, chance = 100000, maxCount = 3}, + {id = 18414, chance = 100000, maxCount = 3}, + {id = 7439, chance = 100000}, + {id = 2158, chance = 100000}, + {id = 2155, chance = 100000}, + {id = 13293, chance = 2000}, + {id = 12410, chance = 2000}, + {id = 5904, chance = 2000}, + {id = 7894, chance = 1000}, + {id = 7440, chance = 2000}, + {id = 2214, chance = 2000}, + {id = 2153, chance = 2000}, + {id = 2154, chance = 2000}, + {id = 11240, chance = 1000}, + {id = 2436, chance = 1000}, + {id = 2197, chance = 1000}, + {id = 11240, chance = 1000}, + {id = 27624, chance = 500, unique = true}, + {id = 8904, chance = 1000}, + {id = 5809, chance = 100, unique = true}, + {id = 2539, chance = 100}, + {id = 7417, chance = 100}, + {id = 25377, chance = 100000}, + {id = 25172, chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 190, attack = 300}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -600, maxDamage = -780, range = 7, radius = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -600, maxDamage = -780, length = 9, spread = 3, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -600, maxDamage = -780, length = 9, spread = 3, effect = CONST_ME_ENERGYAREA, target = false}, + -- energy damage + {name ="condition", type = CONDITION_ENERGY, interval = 2000, chance = 20, minDamage = -2000, maxDamage = -2000, radius = 7, effect = CONST_ME_BLOCKHIT, target = false}, + -- bleed + {name ="condition", type = CONDITION_BLEEDING, interval = 2000, chance = 20, minDamage = -2000, maxDamage = -2000, length = 9, spread = 3, effect = CONST_ME_BLOCKHIT, target = false} +} + +monster.defenses = { + defense = 70, + armor = 70, + {name ="time guardian", interval = 2000, chance = 10, target = false}, + {name ="time guardiann", interval = 2000, chance = 10, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 70}, + {type = COMBAT_ENERGYDAMAGE, percent = 70}, + {type = COMBAT_EARTHDAMAGE, percent = 70}, + {type = COMBAT_FIREDAMAGE, percent = 70}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 70}, + {type = COMBAT_HOLYDAMAGE , percent = 70}, + {type = COMBAT_DEATHDAMAGE , percent = 70} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/bosses/thorn_steed.lua b/data/monster/quests/forgotten_knowledge/bosses/thorn_steed.lua new file mode 100644 index 00000000000..7eae90eb75e --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/bosses/thorn_steed.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Thorn Steed") +local monster = {} + +monster.description = "a Thorn Steed" +monster.experience = 0 +monster.outfit = { + lookType = 626, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 350 +monster.manaCost = 290 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 100, attack = 250} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 1}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/bound_astral_power.lua b/data/monster/quests/forgotten_knowledge/bound_astral_power.lua new file mode 100644 index 00000000000..e1a3050e792 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/bound_astral_power.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Bound Astral Power") +local monster = {} + +monster.description = "a bound astral power" +monster.experience = 0 +monster.outfit = { + lookType = 879, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 70000 +monster.maxHealth = 70000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 100, attack = 50}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -400, maxDamage = -500, length = 6, spread = 2, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -300, maxDamage = -450, radius = 5, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYAREA, target = true} +} + +monster.defenses = { + defense = 50, + armor = 50 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/corrupted_soul.lua b/data/monster/quests/forgotten_knowledge/corrupted_soul.lua new file mode 100644 index 00000000000..146ef4809a6 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/corrupted_soul.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Corrupted Soul") +local monster = {} + +monster.description = "a corrupted soul" +monster.experience = 1300 +monster.outfit = { + lookType = 355, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1100 +monster.maxHealth = 1100 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "CorruptedSoul" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 60, attack = 60}, + {name ="souleater drown", interval = 2000, chance = 9, target = false}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_ICEDAMAGE, minDamage = -50, maxDamage = -100, radius = 1, shootEffect = CONST_ANI_ICE, effect = CONST_ME_ICEATTACK, target = true}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_LIFEDRAIN, minDamage = -10, maxDamage = -60, radius = 4, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="souleater wave", interval = 2000, chance = 12, minDamage = -100, maxDamage = -210, target = false} +} + +monster.defenses = { + defense = 20, + armor = 25, + {name ="invisible", interval = 2000, chance = 12, effect = CONST_ME_POFF}, + {name ="combat", interval = 2000, chance = 16, type = COMBAT_HEALING, minDamage = 130, maxDamage = 205, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 70}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/cosmic_energy_prism_a.lua b/data/monster/quests/forgotten_knowledge/cosmic_energy_prism_a.lua new file mode 100644 index 00000000000..73592d3f310 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/cosmic_energy_prism_a.lua @@ -0,0 +1,91 @@ +local mType = Game.createMonsterType("Cosmic Energy Prism A") +local monster = {} + +monster.description = "cosmic energy prism A" +monster.experience = 840 +monster.outfit = { + lookTypeEx = 1548 +} + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "EnergyPrism" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "*Zap!*", yell = false} +} + +monster.loot = { +} + +monster.defenses = { + defense = 50, + armor = 50 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/cosmic_energy_prism_b.lua b/data/monster/quests/forgotten_knowledge/cosmic_energy_prism_b.lua new file mode 100644 index 00000000000..dcca87b8d7e --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/cosmic_energy_prism_b.lua @@ -0,0 +1,91 @@ +local mType = Game.createMonsterType("Cosmic Energy Prism B") +local monster = {} + +monster.description = "cosmic energy prism B" +monster.experience = 840 +monster.outfit = { + lookTypeEx = 1548 +} + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "EnergyPrism" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "*Zap!*", yell = false} +} + +monster.loot = { +} + +monster.defenses = { + defense = 50, + armor = 50 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/cosmic_energy_prism_c.lua b/data/monster/quests/forgotten_knowledge/cosmic_energy_prism_c.lua new file mode 100644 index 00000000000..7df08c342a5 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/cosmic_energy_prism_c.lua @@ -0,0 +1,91 @@ +local mType = Game.createMonsterType("Cosmic Energy Prism C") +local monster = {} + +monster.description = "cosmic energy prism C" +monster.experience = 840 +monster.outfit = { + lookTypeEx = 1548 +} + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "EnergyPrism" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "*Zap!*", yell = false} +} + +monster.loot = { +} + +monster.defenses = { + defense = 50, + armor = 50 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/cosmic_energy_prism_d.lua b/data/monster/quests/forgotten_knowledge/cosmic_energy_prism_d.lua new file mode 100644 index 00000000000..b5885f08072 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/cosmic_energy_prism_d.lua @@ -0,0 +1,91 @@ +local mType = Game.createMonsterType("Cosmic Energy Prism D") +local monster = {} + +monster.description = "cosmic energy prism D" +monster.experience = 840 +monster.outfit = { + lookTypeEx = 1548 +} + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "EnergyPrism" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "*Zap!*", yell = false} +} + +monster.loot = { +} + +monster.defenses = { + defense = 50, + armor = 50 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/dragon_egg.lua b/data/monster/quests/forgotten_knowledge/dragon_egg.lua new file mode 100644 index 00000000000..9f0019fe71a --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/dragon_egg.lua @@ -0,0 +1,91 @@ +local mType = Game.createMonsterType("Dragon Egg") +local monster = {} + +monster.description = "a dragon egg" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 27745 +} + +monster.health = 5000 +monster.maxHealth = 5000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "DragonEggPrepareDeath", + "DragonEggHealthChange" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/dragon_servant.lua b/data/monster/quests/forgotten_knowledge/dragon_servant.lua new file mode 100644 index 00000000000..198e79dfa52 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/dragon_servant.lua @@ -0,0 +1,102 @@ +local mType = Game.createMonsterType("Dragon Servant") +local monster = {} + +monster.description = "a dragon servant" +monster.experience = 2100 +monster.outfit = { + lookType = 39, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1900 +monster.maxHealth = 1900 +monster.race = "blood" +monster.corpse = 5984 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 82}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -200, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_FIREDAMAGE, minDamage = -150, maxDamage = -230, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false} +} + +monster.defenses = { + defense = 48, + armor = 32, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 55, maxDamage = 95, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/frozen_man.lua b/data/monster/quests/forgotten_knowledge/frozen_man.lua new file mode 100644 index 00000000000..657d59063ce --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/frozen_man.lua @@ -0,0 +1,95 @@ +local mType = Game.createMonsterType("Frozen Man") +local monster = {} + +monster.description = "a Frozen Man" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 7311 +} + +monster.health = 100 +monster.maxHealth = 100 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Seeet the eeegg on fiiireee!", yell = false}, + {text = "Slooow the Hooorrorrrr!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { +} + +monster.defenses = { + defense = 1, + armor = 1, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_HEALING, effect = CONST_ME_MORTAREA, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/frozen_minion.lua b/data/monster/quests/forgotten_knowledge/frozen_minion.lua new file mode 100644 index 00000000000..17cb907376a --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/frozen_minion.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Frozen Minion") +local monster = {} + +monster.description = "a frozen minion" +monster.experience = 230 +monster.outfit = { + lookType = 53, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2200 +monster.maxHealth = 2200 +monster.race = "blood" +monster.corpse = 5998 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 50}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -150, maxDamage = -200, shootEffect = CONST_ANI_SNOWBALL, target = true}, + {name ="frozen minion wave", interval = 2000, chance = 25, target = false}, + {name ="frozen minion beam", interval = 2000, chance = 25, target = false} +} + +monster.defenses = { + defense = 9, + armor = 7, + {name ="frozen minion heal", interval = 2000, chance = 15, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -15} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/icicle.lua b/data/monster/quests/forgotten_knowledge/icicle.lua new file mode 100644 index 00000000000..4e7b49e3c26 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/icicle.lua @@ -0,0 +1,96 @@ +local mType = Game.createMonsterType("Icicle") +local monster = {} + +monster.description = "an icicle" +monster.experience = 0 +monster.outfit = { + lookType = 904, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 8200 +monster.maxHealth = 8200 +monster.race = "undead" +monster.corpse = 2253 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { +} + +monster.defenses = { + defense = 199, + armor = 199, + {name ="icecle heal", interval = 2000, chance = 25, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/lost_time.lua b/data/monster/quests/forgotten_knowledge/lost_time.lua new file mode 100644 index 00000000000..ea2a801cbf5 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/lost_time.lua @@ -0,0 +1,94 @@ +local mType = Game.createMonsterType("Lost Time") +local monster = {} + +monster.description = "a lost time" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 27631 +} + +monster.health = 2000 +monster.maxHealth = 2000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 160 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 25}, + {name ="white shade paralyze", interval = 2000, chance = 18, target = false} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/possessed_tree.lua b/data/monster/quests/forgotten_knowledge/possessed_tree.lua new file mode 100644 index 00000000000..e37f3106f6d --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/possessed_tree.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Possessed Tree") +local monster = {} + +monster.description = "a possessed tree" +monster.experience = 1300 +monster.outfit = { + lookType = 310, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2500 +monster.maxHealth = 2500 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "PossessedTree" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 90}, + {name ="haunted treeling paralyze", interval = 2000, chance = 10, target = false}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_EARTHDAMAGE, minDamage = -86, maxDamage = -200, range = 4, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_HITBYPOISON, target = true}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_EARTHDAMAGE, minDamage = -286, maxDamage = -300, length = 4, spread = 3, effect = CONST_ME_CARNIPHILA, target = false} +} + +monster.defenses = { + defense = 55, + armor = 50 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/shadow_fiend.lua b/data/monster/quests/forgotten_knowledge/shadow_fiend.lua new file mode 100644 index 00000000000..3cf0083ddf4 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/shadow_fiend.lua @@ -0,0 +1,104 @@ +local mType = Game.createMonsterType("Shadow Fiend") +local monster = {} + +monster.description = "a shadow fiend" +monster.experience = 500 +monster.outfit = { + lookType = 320, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 4000 +monster.maxHealth = 4000 +monster.race = "undead" +monster.corpse = 26924 +monster.speed = 360 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 10, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 30, condition = {type = CONDITION_POISON, totalDamage = 80, interval = 4000}}, + {name ="nightstalker paralyze", interval = 2000, chance = 19, range = 7, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_LIFEDRAIN, minDamage = -360, maxDamage = -470, radius = 5, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="speed", interval = 2000, chance = 20, speedChange = -600, range = 6, radius = 4, effect = CONST_ME_SMALLCLOUDS, target = false, duration = 20000}, + {name ="silencer skill reducer", interval = 2000, chance = 30, range = 4, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 35, + armor = 30, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_HEALING, minDamage = 160, maxDamage = 230, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 40}, + {type = COMBAT_ENERGYDAMAGE, percent = 40}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 40}, + {type = COMBAT_HOLYDAMAGE , percent = 40}, + {type = COMBAT_DEATHDAMAGE , percent = 40} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/shadow_tentacle.lua b/data/monster/quests/forgotten_knowledge/shadow_tentacle.lua new file mode 100644 index 00000000000..07d0c29b711 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/shadow_tentacle.lua @@ -0,0 +1,104 @@ +local mType = Game.createMonsterType("Shadow Tentacle") +local monster = {} + +monster.description = "a shadow tentacle" +monster.experience = 0 +monster.outfit = { + lookType = 681, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 22500 +monster.maxHealth = 22500 +monster.race = "venom" +monster.corpse = 26924 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 800, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 88, attack = 100}, + {name ="blightwalker curse", interval = 2000, chance = 10, target = false}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_LIFEDRAIN, minDamage = -65, maxDamage = -135, radius = 4, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="drunk", interval = 2000, chance = 20, radius = 7, effect = CONST_ME_HITBYPOISON, target = false, duration = 35000}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_DEATHDAMAGE, minDamage = -165, maxDamage = -535, effect = CONST_ME_MORTAREA, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 225, maxDamage = 850, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = -30}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/soulcatcher.lua b/data/monster/quests/forgotten_knowledge/soulcatcher.lua new file mode 100644 index 00000000000..4cffa5b43ad --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/soulcatcher.lua @@ -0,0 +1,92 @@ +local mType = Game.createMonsterType("Soulcatcher") +local monster = {} + +monster.description = "a soulcatcher" +monster.experience = 320 +monster.outfit = { + lookTypeEx = 12009 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="combat", interval = 2000, chance = 25, type = COMBAT_LIFEDRAIN, minDamage = -300, maxDamage = -400, radius = 3, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 50, + armor = 50, + {name ="soulcatcher summon", interval = 2000, chance = 10, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 100, maxDamage = 145, effect = CONST_ME_HITBYFIRE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 90}, + {type = COMBAT_ENERGYDAMAGE, percent = 90}, + {type = COMBAT_EARTHDAMAGE, percent = 90}, + {type = COMBAT_FIREDAMAGE, percent = 90}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 90}, + {type = COMBAT_HOLYDAMAGE , percent = 90}, + {type = COMBAT_DEATHDAMAGE , percent = 90} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/sword_of_vegeance.lua b/data/monster/quests/forgotten_knowledge/sword_of_vegeance.lua new file mode 100644 index 00000000000..ca394b74a47 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/sword_of_vegeance.lua @@ -0,0 +1,96 @@ +local mType = Game.createMonsterType("Sword of Vengeance") +local monster = {} + +monster.description = "a sword of vegeance" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 26895 +} + +monster.health = 2000 +monster.maxHealth = 2000 +monster.race = "fire" +monster.corpse = 0 +monster.speed = 360 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 50}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_MANADRAIN, minDamage = -40, maxDamage = -160, radius = 6, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="berserk", interval = 2000, chance = 15, minDamage = -40, maxDamage = -160, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -40, maxDamage = -100, length = 4, spread = 3, effect = CONST_ME_ENERGYHIT, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/sword_of_vengeance.lua b/data/monster/quests/forgotten_knowledge/sword_of_vengeance.lua new file mode 100644 index 00000000000..20b96adb4f7 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/sword_of_vengeance.lua @@ -0,0 +1,96 @@ +local mType = Game.createMonsterType("Sword of Vengeance") +local monster = {} + +monster.description = "a sword of vengeance" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 26895 +} + +monster.health = 2000 +monster.maxHealth = 2000 +monster.race = "fire" +monster.corpse = 0 +monster.speed = 360 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 50}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_MANADRAIN, minDamage = -40, maxDamage = -160, radius = 6, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="berserk", interval = 2000, chance = 15, minDamage = -40, maxDamage = -160, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -40, maxDamage = -100, length = 4, spread = 3, effect = CONST_ME_ENERGYHIT, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/the_distorted_astral_source.lua b/data/monster/quests/forgotten_knowledge/the_distorted_astral_source.lua new file mode 100644 index 00000000000..559b6832a90 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/the_distorted_astral_source.lua @@ -0,0 +1,102 @@ +local mType = Game.createMonsterType("The Distorted Astral Source") +local monster = {} + +monster.description = "the distorted astral source" +monster.experience = 3000 +monster.outfit = { + lookTypeEx = 26897 +} + +monster.health = 10000000 +monster.maxHealth = 10000000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 390 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "DistortedSource" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -330}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -500, range = 7, radius = 6, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_PURPLEENERGY, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -500, range = 7, radius = 6, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -400, length = 5, spread = 3, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_MANADRAIN, minDamage = -200, maxDamage = -400, radius = 5, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.defenses = { + defense = 55, + armor = 55, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_HEALING, minDamage = 1000, maxDamage = 1300, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/thorn_minion.lua b/data/monster/quests/forgotten_knowledge/thorn_minion.lua new file mode 100644 index 00000000000..4fa56df6f54 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/thorn_minion.lua @@ -0,0 +1,104 @@ +local mType = Game.createMonsterType("Thorn Minion") +local monster = {} + +monster.description = "a thorn minion" +monster.experience = 1600 +monster.outfit = { + lookType = 717, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3500 +monster.maxHealth = 3500 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 150 +monster.manaCost = 290 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -60, maxDamage = -150, condition = {type = CONDITION_POISON, totalDamage = 500, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -100, maxDamage = -195, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -800, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_GREEN_RINGS, target = false, duration = 30000}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -280, radius = 4, effect = CONST_ME_GROUNDSHAKER, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -200, maxDamage = -400, length = 4, spread = 3, effect = CONST_ME_CARNIPHILA, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="speed", interval = 2000, chance = 30, speedChange = 250, effect = CONST_ME_MAGIC_GREEN, target = false, duration = 4000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -12}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 1}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/time_keeper.lua b/data/monster/quests/forgotten_knowledge/time_keeper.lua new file mode 100644 index 00000000000..226d4077f25 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/time_keeper.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Time Keeper") +local monster = {} + +monster.description = "a time keeper" +monster.experience = 0 +monster.outfit = { + lookType = 560, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 160 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 10, attack = 10}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_LIFEDRAIN, minDamage = -4, maxDamage = -6, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_YALAHARIGHOST, target = false}, + {name ="white shade paralyze", interval = 2000, chance = 18, target = false} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 90}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/time_waster.lua b/data/monster/quests/forgotten_knowledge/time_waster.lua new file mode 100644 index 00000000000..91645a6e873 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/time_waster.lua @@ -0,0 +1,95 @@ +local mType = Game.createMonsterType("Time Waster") +local monster = {} + +monster.description = "a time waster" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 26397 +} + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 100 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 100, attack = 100}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_LIFEDRAIN, minDamage = -40, maxDamage = -60, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_YALAHARIGHOST, target = false}, + {name ="white shade paralyze", interval = 2000, chance = 18, target = false} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/unbound_blightwalker.lua b/data/monster/quests/forgotten_knowledge/unbound_blightwalker.lua new file mode 100644 index 00000000000..2eeaf736557 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/unbound_blightwalker.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Unbound Blightwalker") +local monster = {} + +monster.description = "an unbound blightwalker" +monster.experience = 5850 +monster.outfit = { + lookType = 246, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 7900 +monster.maxHealth = 7900 +monster.race = "undead" +monster.corpse = 6354 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 800, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 88, attack = 100}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_EARTHDAMAGE, minDamage = -220, maxDamage = -405, range = 1, shootEffect = CONST_ANI_POISON, effect = CONST_ME_GREEN_RINGS, target = true}, + {name ="blightwalker curse", interval = 2000, chance = 10, target = false}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_LIFEDRAIN, minDamage = -65, maxDamage = -135, radius = 4, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="drunk", interval = 2000, chance = 12, radius = 3, effect = CONST_ME_HITBYPOISON, target = false, duration = 35000}, + {name ="blightwalker paralyze", interval = 2000, chance = 15, range = 7, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = -30}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/unbound_defiler.lua b/data/monster/quests/forgotten_knowledge/unbound_defiler.lua new file mode 100644 index 00000000000..569a808c950 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/unbound_defiler.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Unbound Defiler") +local monster = {} + +monster.description = "an unbound defiler" +monster.experience = 3700 +monster.outfit = { + lookType = 238, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2650 +monster.maxHealth = 2650 +monster.race = "venom" +monster.corpse = 6532 +monster.speed = 160 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 85, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 80, condition = {type = CONDITION_POISON, totalDamage = 300, interval = 4000}}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_LIFEDRAIN, minDamage = -160, maxDamage = -295, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_HITBYPOISON, target = true}, + {name ="defiler paralyze 3", interval = 2000, chance = 9, target = false}, + {name ="defiler paralyze 1", interval = 2000, chance = 6, target = false}, + {name ="defiler paralyze 2", interval = 2000, chance = 8, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -300, maxDamage = -500, radius = 8, effect = CONST_ME_HITBYPOISON, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -400, maxDamage = -725, length = 8, spread = 3, effect = CONST_ME_SMALLPLANTS, target = false}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_EARTHDAMAGE, minDamage = -120, maxDamage = -170, radius = 3, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 250, maxDamage = 450, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -25}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/unbound_demon.lua b/data/monster/quests/forgotten_knowledge/unbound_demon.lua new file mode 100644 index 00000000000..45dfa1e80a2 --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/unbound_demon.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("Unbound Demon") +local monster = {} + +monster.description = "an unbound demon" +monster.experience = 5000 +monster.outfit = { + lookType = 35, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 7200 +monster.maxHealth = 7200 +monster.race = "fire" +monster.corpse = 5995 +monster.speed = 256 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 70, attack = 130}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_MANADRAIN, minDamage = -60, maxDamage = -120, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 33, type = COMBAT_FIREDAMAGE, minDamage = -150, maxDamage = -250, range = 7, radius = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 7, type = COMBAT_ENERGYDAMAGE, minDamage = -210, maxDamage = -300, range = 1, radius = 1, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="firefield", interval = 2000, chance = 14, range = 7, radius = 1, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="demon paralyze", interval = 2000, chance = 10, range = 7, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -300, maxDamage = -480, length = 8, spread = 3, effect = CONST_ME_PURPLEENERGY, target = false} +} + +monster.defenses = { + defense = 65, + armor = 40, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_HEALING, minDamage = 150, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="demon summon", interval = 2000, chance = 8, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = 388, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/forgotten_knowledge/unbound_demon_outcast.lua b/data/monster/quests/forgotten_knowledge/unbound_demon_outcast.lua new file mode 100644 index 00000000000..084133417bb --- /dev/null +++ b/data/monster/quests/forgotten_knowledge/unbound_demon_outcast.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Unbound Demon Outcast") +local monster = {} + +monster.description = "an unbound demon outcast" +monster.experience = 6200 +monster.outfit = { + lookType = 590, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5900 +monster.maxHealth = 5900 +monster.race = "fire" +monster.corpse = 22549 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "energy elemental", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 80}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -300, length = 6, spread = 3, effect = CONST_ME_PURPLEENERGY, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -250, maxDamage = -350, length = 8, spread = 3, effect = CONST_ME_YELLOWENERGY, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, radius = 3, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_MANADRAIN, minDamage = -50, maxDamage = -100, range = 7, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="demon outcast skill reducer", interval = 2000, chance = 7, range = 5, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 100, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = 468, effect = CONST_ME_MAGIC_RED, target = false, duration = 7000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = -8}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/grave_danger/black_cobra.lua b/data/monster/quests/grave_danger/black_cobra.lua new file mode 100644 index 00000000000..1017159d7ed --- /dev/null +++ b/data/monster/quests/grave_danger/black_cobra.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Black Cobra") +local monster = {} + +monster.description = "a black cobra" +monster.experience = 0 +monster.outfit = { + lookType = 81, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 8200 +monster.maxHealth = 8200 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150, condition = {type = CONDITION_POISON, totalDamage = 200, interval = 4000}}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -20, maxDamage = -40, range = 7, shootEffect = CONST_ANI_POISON, target = false} +} + +monster.defenses = { + defense = 74, + armor = 74 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/grave_danger/bosses/count_vlarkorth.lua b/data/monster/quests/grave_danger/bosses/count_vlarkorth.lua new file mode 100644 index 00000000000..4d3470c5b19 --- /dev/null +++ b/data/monster/quests/grave_danger/bosses/count_vlarkorth.lua @@ -0,0 +1,152 @@ +local mType = Game.createMonsterType("Count Vlarkorth") +local monster = {} + +monster.description = "Count Vlarkorth" +monster.experience = 41300 +monster.outfit = { + lookType = 1221, + lookHead = 10, + lookBody = 19, + lookLegs = 19, + lookFeet = 19, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "venom" +monster.corpse = 36434 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 6 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Soulless Minion", chance = 70, interval = 1800} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", minCount = 1, maxCount = 5, chance = 100000}, + {name = "crystal coin", minCount = 0, maxCount = 2, chance = 50000}, + {name = "supreme health potion", minCount = 0, maxCount = 6, chance = 35000}, + {name = "ultimate mana potion", minCount = 0, maxCount = 20, chance = 32000}, + {name = "ultimate spirit potion", minCount = 0, maxCount = 20, chance = 32000}, + {name = "bullseye potion", minCount = 0, maxCount = 10, chance = 12000}, + {name = "mastermind potion", minCount = 0, maxCount = 10, chance = 12000}, + {name = "silver token", minCount = 0, maxCount = 2, chance = 8000}, + {name = "blue gem", chance = 9000}, + {id = 26198, chance = 5200},-- collar of blue plasma + {id = 26200, chance = 5200},-- collar of red plasma + {name = "blue gem", chance = 8500}, + {name = "gold ingot", minCount = 0, maxCount = 1, chance = 10000}, + {name = "green gem", chance = 8200}, + {name = "magic sulphur", chance = 6500}, + {name = "red gem", chance = 8000}, + {id = 26185, chance = 5000},-- ring of blue plasma + {id = 26189, chance = 5000},-- ring of red plasma + {id = 26187, chance = 5000},-- ring of green plasma + {name = "skull staff", chance = 7000}, + {name = "yellow gem", chance = 8500}, + {name = "young lich worm", chance = 5500}, + {name = "bear skin", chance = 1600}, + {name = "embrace of nature", chance = 1100}, + {name = "giant emerald", chance = 1700}, + {name = "giant ruby", chance = 1900}, + {name = "giant sapphire", chance = 1800}, + {name = "medal of valiance", chance = 1200}, + {name = "terra helmet", chance = 700}, + {name = "final judgement", chance = 400}, +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -200, maxDamage = -600}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_MANADRAIN, minDamage = -400, maxDamage = -1000, length = 7, spread = 3, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_PHYSICALDAMAGE, minDamage = -400, maxDamage = -1000, length = 7, spread = 3, effect = CONST_ME_YELLOW_ENERGY_SPARK, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -300, maxDamage = -500, length = 7, spread = 3, effect = CONST_ME_HITBYFIRE, target = false} +} + +monster.defenses = { + defense = 25, + armor = 78, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_HEALING, minDamage = 150, maxDamage = 350, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/grave_danger/bosses/duke_krule.lua b/data/monster/quests/grave_danger/bosses/duke_krule.lua new file mode 100644 index 00000000000..1159b2b37a9 --- /dev/null +++ b/data/monster/quests/grave_danger/bosses/duke_krule.lua @@ -0,0 +1,141 @@ +local mType = Game.createMonsterType("Duke Krule") +local monster = {} + +monster.description = "a Duke Krule" +monster.experience = 46300 +monster.outfit = { + lookType = 1221, + lookHead = 19, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "venom" +monster.corpse = 36434 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", minCount = 1, maxCount = 5, chance = 100000}, + {name = "crystal coin", minCount = 0, maxCount = 2, chance = 50000}, + {name = "supreme health potion", minCount = 0, maxCount = 6, chance = 35000}, + {name = "ultimate mana potion", minCount = 0, maxCount = 20, chance = 32000}, + {name = "ultimate spirit potion", minCount = 0, maxCount = 20, chance = 32000}, + {name = "bullseye potion", minCount = 0, maxCount = 10, chance = 12000}, + {name = "mastermind potion", minCount = 0, maxCount = 10, chance = 12000}, + {name = "berserk potion", minCount = 0, maxCount = 10, chance = 12000}, + {name = "piece of draconian steel", minCount = 0, maxCount = 3, chance = 9000}, + {name = "green gem", minCount = 0, maxCount = 2, chance = 12000}, + {name = "silver token", minCount = 0, maxCount = 2, chance = 9500}, + {name = "blue gem", chance = 11000}, + {name = "crusader helmet", chance = 6400}, + {name = "gold ingot", minCount = 0, maxCount = 1, chance = 10000}, + {name = "red gem", chance = 11000}, + {name = "terra hood", chance = 7800}, + {name = "yellow gem", chance = 9500}, + {name = "young lich worm", chance = 5800}, + {name = "bear skin", chance = 1800}, + {name = "noble amulet", chance = 1100}, + {name = "rotten heart", chance = 1700}, + {name = "terra helmet", chance = 700}, + {name = "final judgement", chance = 460}, +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -200, maxDamage = -600}, + {name ="combat", interval = 1800, chance = 60, type = COMBAT_MANADRAIN, minDamage = -400, maxDamage = -1000, length = 7, spread = 2, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 1800, chance = 19, type = COMBAT_PHYSICALDAMAGE, minDamage = -400, maxDamage = -1000, length = 7, spread = 3, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="combat", interval = 1800, chance = 40, type = COMBAT_FIREDAMAGE, minDamage = -300, maxDamage = -500, radius = 10, effect = CONST_ME_HITBYFIRE, target = false} +} + +monster.defenses = { + defense = 25, + armor = 78, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_HEALING, minDamage = 150, maxDamage = 350, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/grave_danger/bosses/earl_osam.lua b/data/monster/quests/grave_danger/bosses/earl_osam.lua new file mode 100644 index 00000000000..a142244d9f1 --- /dev/null +++ b/data/monster/quests/grave_danger/bosses/earl_osam.lua @@ -0,0 +1,145 @@ +local mType = Game.createMonsterType("Earl Osam") +local monster = {} + +monster.description = "Earl Osam" +monster.experience = 44200 +monster.outfit = { + lookType = 1223, + lookHead = 95, + lookBody = 38, + lookLegs = 60, + lookFeet = 76, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "venom" +monster.corpse = 36434 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 5 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Frozen Soul", chance = 20, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", minCount = 1, maxCount = 5, chance = 100000}, + {name = "crystal coin", minCount = 0, maxCount = 2, chance = 50000}, + {name = "supreme health potion", minCount = 0, maxCount = 6, chance = 35000}, + {name = "ultimate mana potion", minCount = 0, maxCount = 20, chance = 32000}, + {name = "ultimate spirit potion", minCount = 0, maxCount = 20, chance = 32000}, + {name = "bullseye potion", minCount = 0, maxCount = 10, chance = 12000}, + {name = "mastermind potion", minCount = 0, maxCount = 10, chance = 12000}, + {name = "berserk potion", minCount = 0, maxCount = 10, chance = 12000}, + {name = "piece of draconian steel", minCount = 0, maxCount = 3, chance = 9000}, + {name = "red gem", minCount = 0, maxCount = 2, chance = 12000}, + {name = "silver token", minCount = 0, maxCount = 2, chance = 9500}, + {id = 26198, chance = 5200},-- collar of blue plasma + {id = 26200, chance = 5200},-- collar of red plasma + {id = 26185, chance = 5000},-- ring of blue plasma + {id = 26189, chance = 5000},-- ring of red plasma + {name = "warrior helmet", chance = 11000}, + {name = "guardian axe", chance = 6400}, + {name = "gold ingot", minCount = 0, maxCount = 1, chance = 10000}, + {name = "young lich worm", chance = 5800}, + {name = "embrace of nature", chance = 1600}, + {name = "token of love", chance = 1200}, + {name = "rotten heart", chance = 1700}, + {name = "terra helmet", chance = 730}, + {name = "final judgement", chance = 440} +} + +monster.attacks = { + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -400, maxDamage = -1000, length = 7, spread = 3, effect = CONST_ME_ICEATTACK, target = false}, + {name ="combat", interval = 1800, chance = 25, type = COMBAT_EARTHDAMAGE, minDamage = -400, maxDamage = -1000, length = 7, spread = 2, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_ENERGYDAMAGE, minDamage = -260, maxDamage = -420, range = 3, effect = CONST_ME_BLUE_ENERGY_SPARK, target = true} +} + +monster.defenses = { + defense = 25, + armor = 78, + {name ="combat", interval = 2000, chance = 35, type = COMBAT_HEALING, minDamage = 350, maxDamage = 550, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/grave_danger/bosses/king_zelos.lua b/data/monster/quests/grave_danger/bosses/king_zelos.lua new file mode 100644 index 00000000000..e9454317a14 --- /dev/null +++ b/data/monster/quests/grave_danger/bosses/king_zelos.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("King Zelos") +local monster = {} + +monster.description = "King Zelos" +monster.experience = 251300 +monster.outfit = { + lookType = 1224, + lookHead = 10, + lookBody = 19, + lookLegs = 19, + lookFeet = 19, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 125000 +monster.maxHealth = monster.health +monster.race = "venom" +monster.corpse = 36443 +monster.speed = 425 +monster.maxSummons = 6 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.loot = { + {name = "platinum coin", minCount = 1, maxCount = 5, chance = 100000}, + {name = "crystal coin", minCount = 0, maxCount = 5, chance = 50000}, + {name = "supreme health potion", minCount = 0, maxCount = 20, chance = 45000}, + {name = "ultimate mana potion", minCount = 0, maxCount = 6, chance = 42000}, + {name = "ultimate spirit potion", minCount = 0, maxCount = 14, chance = 42000}, + {name = "bullseye potion", minCount = 0, maxCount = 10, chance = 22000}, + {name = "berserk potion", minCount = 0, maxCount = 10, chance = 22000}, + {name = "gold token", minCount = 0, maxCount = 3, chance = 18000}, + {name = "silver token", minCount = 0, maxCount = 3, chance = 25000}, + {name = "green gem", chance = 19000}, + {name = "red gem", chance = 18500}, + {name = "yellow gem", chance = 18500}, + {name = "giant sapphire", chance = 16800}, + {name = "collar of green plasma", chance = 15200}, + {name = "magma coat", chance = 15200}, + {name = "gold ingot", minCount = 0, maxCount = 1, chance = 18000}, + {name = "red tome", chance = 18200}, + {id = 26185, chance = 12000},-- ring of blue plasma + {id = 26189, chance = 12000},-- ring of red plasma + {name = "young lich worm", chance = 5500}, + {name = "mortal mace", chance = 1300}, + {name = "golden hyena pendant", chance = 1100}, + {name = "bow of cataclysm", chance = 600}, + {name = "galea mortis", chance = 550}, + {name = "shadow cowl", chance = 530}, + {name = "toga mortis", chance = 500}, +} + +monster.attacks = { + {name = "melee", type = COMBAT_PHYSICALDAMAGE, interval = 2000, minDamage = -900, maxDamage = -2700}, + {name = "combat", type = COMBAT_FIREDAMAGE, interval = 2000, chance = 15, length = 8, spread = 0, minDamage = -1200, maxDamage = -3200, effect = CONST_ME_HITBYFIRE}, + {name = "combat", type = COMBAT_LIFEDRAIN, interval = 2000, chance = 10, length = 8, spread = 3, minDamage = -600, maxDamage = -1600, effect = CONST_ME_SMALLCLOUDS}, +} + +monster.defenses = { + defense = 78, + armor = 78, + {name = "combat", type = COMBAT_HEALING, chance = 15, interval = 2000, minDamage = 1450, maxDamage = 5350, effect = CONST_ME_MAGIC_BLUE}, +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 3}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "invisible", condition = true}, +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Feel the power of death unleashed!", yell = false}, + {text = "I will rule again and my realm of death will span the world!", yell = false}, + {text = "My lich-knights will conquer this world for me!", yell = false}, +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) \ No newline at end of file diff --git a/data/monster/quests/grave_danger/bosses/lord_azaram.lua b/data/monster/quests/grave_danger/bosses/lord_azaram.lua new file mode 100644 index 00000000000..bb1897b7cb2 --- /dev/null +++ b/data/monster/quests/grave_danger/bosses/lord_azaram.lua @@ -0,0 +1,149 @@ +local mType = Game.createMonsterType("Lord Azaram") +local monster = {} + +monster.description = "a Lord Azaram" +monster.experience = 41950 +monster.outfit = { + lookType = 1223, + lookHead = 0, + lookBody = 38, + lookLegs = 94, + lookFeet = 82, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "venom" +monster.corpse = 36434 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Condensed Sins", chance = 50, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", minCount = 1, maxCount = 5, chance = 100000}, + {name = "crystal coin", minCount = 0, maxCount = 2, chance = 50000}, + {name = "supreme health potion", minCount = 0, maxCount = 6, chance = 35000}, + {name = "ultimate mana potion", minCount = 0, maxCount = 20, chance = 32000}, + {name = "ultimate spirit potion", minCount = 0, maxCount = 20, chance = 32000}, + {name = "bullseye potion", minCount = 0, maxCount = 10, chance = 12000}, + {name = "berserk potion", minCount = 0, maxCount = 10, chance = 12000}, + {name = "piece of hell steel", minCount = 0, maxCount = 4, chance = 9000}, + {name = "red gem", minCount = 0, maxCount = 2, chance = 12000}, + {name = "blue gem", minCount = 0, maxCount = 2, chance = 12000}, + {name = "silver token", minCount = 0, maxCount = 2, chance = 9500}, + {name = "ancient liche bone", chance = 5200}, + {id = 26198, chance = 5200},-- collar of blue plasma + {id = 26200, chance = 5200},-- collar of red plasma + {name = "collar of green plasma", chance = 5200}, + {name = "giant sapphire", chance = 7000}, + {name = "haunted blade", chance = 9000}, + {name = "huge chunk of crude iron", chance = 4500}, + {name = "knight armor", chance = 15000}, + {name = "violet gem", minCount = 0, maxCount = 1, chance = 10000}, + {name = "yellow gem", minCount = 0, maxCount = 1, chance = 10000}, + {id = 26187, chance = 5000},-- ring of green plasma + {id = 26189, chance = 5000},-- ring of red plasma + {name = "young lich worm", chance = 5800}, + {name = "bear skin", chance = 1600}, + {name = "noble cape", chance = 1500}, + {name = "terra helmet", chance = 720}, + {name = "final judgement", chance = 410}, +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -200, maxDamage = -600}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = -400, maxDamage = -1000, length = 7, spread = 3, effect = CONST_ME_STONES, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -400, maxDamage = -1000, length = 7, spread = 3, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 25, + armor = 78, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_HEALING, minDamage = 150, maxDamage = 550, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/grave_danger/bosses/scarlett_etzel.lua b/data/monster/quests/grave_danger/bosses/scarlett_etzel.lua new file mode 100644 index 00000000000..ded4535814d --- /dev/null +++ b/data/monster/quests/grave_danger/bosses/scarlett_etzel.lua @@ -0,0 +1,154 @@ +local mType = Game.createMonsterType("Scarlett Etzel") +local monster = {} + +monster.description = "a scarlett etzel" +monster.experience = 20000 +monster.outfit = { + lookType = 1201, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 30000 +monster.maxHealth = 30000 +monster.race = "blood" +monster.corpse = 36288 +monster.speed = 175 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Energy Bar", chance = 100000}, + {name = "Platinum Coin", chance = 87000, maxCount = 5}, + {name = "Green Gem", chance = 85000}, + {name = "Supreme Health Potion", chance = 53700, maxCount = 14}, + {name = "Ultimate Mana Potion", chance = 48150, maxCount = 20}, + {name = "Red Gem", chance = 42500}, + {name = "Ultimate Spirit Potion", chance = 34000, maxCount = 6}, + {name = "Yellow Gem", chance = 29600, maxCount = 2}, + {name = "Royal Star", chance = 26600, maxCount = 100}, + {id = 7632, chance = 24000}, + {name = "Berserk Potion", chance = 20300, maxCount = 10}, + {name = "Blue Gem", chance = 18500, maxCount = 2}, + {name = "Bullseye Potion", chance = 18500, maxCount = 10}, + {name = "Magma Coat", chance = 16600}, + {name = "Terra Rod", chance = 1100}, + {name = "Crystal Coin", chance = 9200}, + {name = "Violet Gem", chance = 9000}, + {name = "Terra Legs", chance = 8500}, + {name = "Terra Hood", chance = 7400}, + {name = "Terra Mantle", chance = 7250}, + {name = "Magma Amulet", chance = 5500}, + {name = "Silver Token", chance = 6000, maxCount = 4}, + {name = "Gold Ingot", chance = 5000}, + {name = "Terra Amulet", chance = 4800}, + {name = "Giant Sapphire", chance = 4800}, + {name = "Magma Monocle", chance = 3700}, + {name = "Cobra Club", chance = 700}, + {name = "Cobra Axe", chance = 600}, + {name = "Cobra Crossbow", chance = 600}, + {name = "Cobra Hood", chance = 400}, + {name = "Cobra Rod", chance = 650}, + {name = "Cobra Sword", chance = 650}, + {name = "Cobra Wand", chance = 650}, + {name = "The Cobra Amulet", chance = 350} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -600}, + {name ="sudden death", interval = 2000, chance = 16, minDamage = -400, maxDamage = -600, target = true}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_HOLYDAMAGE, minDamage = -450, maxDamage = -640, length = 7, spread = 3, effect = CONST_ME_HOLYAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -480, maxDamage = -630, radius = 5, effect = CONST_ME_EXPLOSIONHIT, target = false} +} + +monster.defenses = { + defense = 88, + armor = 88 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/grave_danger/bosses/sir_baeloc.lua b/data/monster/quests/grave_danger/bosses/sir_baeloc.lua new file mode 100644 index 00000000000..91262f127eb --- /dev/null +++ b/data/monster/quests/grave_danger/bosses/sir_baeloc.lua @@ -0,0 +1,144 @@ +local mType = Game.createMonsterType("Sir Baeloc") +local monster = {} + +monster.description = "a Sir Baeloc" +monster.experience = 48300 +monster.outfit = { + lookType = 1222, + lookHead = 19, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "venom" +monster.corpse = 36434 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 6 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Retainer of Baeloc", chance = 20, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", minCount = 1, maxCount = 5, chance = 100000}, + {name = "crystal coin", minCount = 0, maxCount = 2, chance = 50000}, + {name = "supreme health potion", minCount = 0, maxCount = 6, chance = 35000}, + {name = "ultimate mana potion", minCount = 0, maxCount = 20, chance = 32000}, + {name = "ultimate spirit potion", minCount = 0, maxCount = 20, chance = 32000}, + {name = "mastermind potion", minCount = 0, maxCount = 10, chance = 12000}, + {name = "berserk potion", minCount = 0, maxCount = 10, chance = 12000}, + {name = "piece of draconian steel", minCount = 0, maxCount = 4, chance = 9000}, + {name = "red gem", minCount = 0, maxCount = 1, chance = 12000}, + {name = "silver token", minCount = 0, maxCount = 2, chance = 9500}, + {id = 26198, chance = 5200},-- collar of blue plasma + {id = 26200, chance = 5200},-- collar of red plasma + {name = "knight legs", chance = 11000}, + {name = "gold ingot", minCount = 0, maxCount = 1, chance = 10000}, + {name = "violet gem", minCount = 0, maxCount = 1, chance = 10000}, + {name = "yellow gem", minCount = 0, maxCount = 1, chance = 10000}, + {id = 26185, chance = 5000},-- ring of blue plasma + {id = 26189, chance = 5000},-- ring of red plasma + {name = "skull staff", chance = 9000}, + {name = "young lich worm", chance = 5800}, + {name = "embrace of nature", chance = 1400}, + {id = 36427, chance = 1800}, + {name = "terra helmet", chance = 750}, + {name = "final judgement", chance = 450}, +} + +monster.attacks = { + {name ="combat", interval = 1800, chance = 40, type = COMBAT_MANADRAIN, minDamage = -300, maxDamage = -500, radius = 5, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 1800, chance = 89, type = COMBAT_PHYSICALDAMAGE, minDamage = -400, maxDamage = -1200, length = 7, spread = 3, target = false} +} + +monster.defenses = { + defense = 25, + armor = 78, + {name ="combat", interval = 2000, chance = 35, type = COMBAT_HEALING, minDamage = 350, maxDamage = 550, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/grave_danger/bosses/sir_nictros.lua b/data/monster/quests/grave_danger/bosses/sir_nictros.lua new file mode 100644 index 00000000000..aaefeb85d59 --- /dev/null +++ b/data/monster/quests/grave_danger/bosses/sir_nictros.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Sir Nictros") +local monster = {} + +monster.description = "a Sir Nictros" +monster.experience = 6300 +monster.outfit = { + lookType = 1222, + lookHead = 19, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "venom" +monster.corpse = 36434 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "Sir_Baeloc_Sir_NictrosCharge" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="combat", interval = 1800, chance = 40, type = COMBAT_MANADRAIN, minDamage = -300, maxDamage = -500, radius = 5, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 1800, chance = 89, type = COMBAT_PHYSICALDAMAGE, minDamage = -400, maxDamage = -1000, length = 7, spread = 3, target = false} +} + +monster.defenses = { + defense = 25, + armor = 78, + {name ="combat", interval = 2000, chance = 35, type = COMBAT_HEALING, minDamage = 350, maxDamage = 550, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/grave_danger/cart_packed_with_gold.lua b/data/monster/quests/grave_danger/cart_packed_with_gold.lua new file mode 100644 index 00000000000..323e4a46340 --- /dev/null +++ b/data/monster/quests/grave_danger/cart_packed_with_gold.lua @@ -0,0 +1,93 @@ +local mType = Game.createMonsterType("Cart Packed with Gold") +local monster = {} + +monster.description = "a cart packed with gold" +monster.experience = 0 +monster.outfit = { + lookType = 1175, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "blood" +monster.corpse = 36093 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Small Diamond", chance = 100000} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/grave_danger/condensed_sins.lua b/data/monster/quests/grave_danger/condensed_sins.lua new file mode 100644 index 00000000000..1b8bb2a1316 --- /dev/null +++ b/data/monster/quests/grave_danger/condensed_sins.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Condensed Sins") +local monster = {} + +monster.description = "a condensed sins" +monster.experience = 0 +monster.outfit = { + lookType = 315, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 750 +monster.maxHealth = 750 +monster.race = "undead" +monster.corpse = 9960 +monster.speed = 160 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -500}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = -350, maxDamage = -600, range = 3, radius = 4, effect = CONST_ME_POFF, target = false}, + {name ="death blob curse", interval = 2000, chance = 5, range = 5, target = false} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/grave_danger/dark_druid.lua b/data/monster/quests/grave_danger/dark_druid.lua new file mode 100644 index 00000000000..cf0aa7b77f3 --- /dev/null +++ b/data/monster/quests/grave_danger/dark_druid.lua @@ -0,0 +1,97 @@ +local mType = Game.createMonsterType("Dark Druid") +local monster = {} + +monster.description = "a Dark Druid" +monster.experience = 0 +monster.outfit = { + lookType = 144, + lookHead = 95, + lookBody = 95, + lookLegs = 95, + lookFeet = 95, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 1800 +monster.maxHealth = 1800 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, range = 7, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 80}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 95}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/grave_danger/dark_knight.lua b/data/monster/quests/grave_danger/dark_knight.lua new file mode 100644 index 00000000000..c76bae9e013 --- /dev/null +++ b/data/monster/quests/grave_danger/dark_knight.lua @@ -0,0 +1,97 @@ +local mType = Game.createMonsterType("Dark Knight") +local monster = {} + +monster.description = "a Dark Knight" +monster.experience = 0 +monster.outfit = { + lookType = 131, + lookHead = 95, + lookBody = 95, + lookLegs = 95, + lookFeet = 95, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 1800 +monster.maxHealth = 1800 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, range = 7, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 80}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 95}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/grave_danger/dark_paladin.lua b/data/monster/quests/grave_danger/dark_paladin.lua new file mode 100644 index 00000000000..33693336a13 --- /dev/null +++ b/data/monster/quests/grave_danger/dark_paladin.lua @@ -0,0 +1,97 @@ +local mType = Game.createMonsterType("Dark Paladin") +local monster = {} + +monster.description = "a Dark Paladin" +monster.experience = 0 +monster.outfit = { + lookType = 129, + lookHead = 95, + lookBody = 95, + lookLegs = 95, + lookFeet = 95, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 1800 +monster.maxHealth = 1800 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, range = 7, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 80}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 95}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/grave_danger/dark_sorcerer.lua b/data/monster/quests/grave_danger/dark_sorcerer.lua new file mode 100644 index 00000000000..9ee766d56a7 --- /dev/null +++ b/data/monster/quests/grave_danger/dark_sorcerer.lua @@ -0,0 +1,97 @@ +local mType = Game.createMonsterType("Dark Sorcerer") +local monster = {} + +monster.description = "a Dark Sorcerer" +monster.experience = 0 +monster.outfit = { + lookType = 130, + lookHead = 95, + lookBody = 95, + lookLegs = 95, + lookFeet = 95, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 1800 +monster.maxHealth = 1800 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, range = 7, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 80}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 95}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/grave_danger/fetter.lua b/data/monster/quests/grave_danger/fetter.lua new file mode 100644 index 00000000000..a2ba498318a --- /dev/null +++ b/data/monster/quests/grave_danger/fetter.lua @@ -0,0 +1,102 @@ +local mType = Game.createMonsterType("Fetter") +local monster = {} + +monster.description = "a Fetter" +monster.experience = 0 +monster.outfit = { + lookType = 235, + lookHead = 20, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 13500 +monster.maxHealth = 13500 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -308, condition = {type = CONDITION_POISON, totalDamage = 300, interval = 4000}}, + {name ="drunk", interval = 2000, chance = 15, radius = 4, effect = CONST_ME_SOUND_PURPLE, target = false, duration = 6000}, + {name ="spectre drown", interval = 2000, chance = 15, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_MANADRAIN, minDamage = -100, maxDamage = -600, range = 7, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -300, maxDamage = -850, range = 7, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 100, maxDamage = 700, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 290, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 90}, + {type = COMBAT_ENERGYDAMAGE, percent = -8}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -8}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 1}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/grave_danger/retainer_of_baeloc.lua b/data/monster/quests/grave_danger/retainer_of_baeloc.lua new file mode 100644 index 00000000000..bd7b30556ad --- /dev/null +++ b/data/monster/quests/grave_danger/retainer_of_baeloc.lua @@ -0,0 +1,97 @@ +local mType = Game.createMonsterType("Retainer of Baeloc") +local monster = {} + +monster.description = "a Retainer of Baeloc" +monster.experience = 0 +monster.outfit = { + lookType = 100, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 170 +monster.manaCost = 580 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -140}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -180, maxDamage = -235, range = 1, target = true} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/grave_danger/risen_soldier.lua b/data/monster/quests/grave_danger/risen_soldier.lua new file mode 100644 index 00000000000..548689ed5f4 --- /dev/null +++ b/data/monster/quests/grave_danger/risen_soldier.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Risen Soldier") +local monster = {} + +monster.description = "an Risen Soldier" +monster.experience = 0 +monster.outfit = { + lookType = 306, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -435, range = 7, shootEffect = CONST_ANI_WHIRLWINDSWORD, target = false} +} + +monster.defenses = { + defense = 45, + armor = 45, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/grave_danger/shard_of_magnor.lua b/data/monster/quests/grave_danger/shard_of_magnor.lua new file mode 100644 index 00000000000..ff7cd1e19ad --- /dev/null +++ b/data/monster/quests/grave_danger/shard_of_magnor.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Shard Of Magnor") +local monster = {} + +monster.description = "a shard of magnor" +monster.experience = 0 +monster.outfit = { + lookType = 1221, + lookHead = 19, + lookBody = 76, + lookLegs = 114, + lookFeet = 76, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -200, maxDamage = -600}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_MANADRAIN, minDamage = -400, maxDamage = -1000, length = 7, spread = 3, effect = CONST_ME_STONES, target = false}, + {name ="combat", interval = 2000, chance = 70, type = COMBAT_PHYSICALDAMAGE, minDamage = -400, maxDamage = -1000, length = 7, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 0, type = COMBAT_ENERGYDAMAGE, minDamage = -400, maxDamage = -650, radius = 3, effect = CONST_ME_GREEN_ENERGY_SPARK, target = true} +} + +monster.defenses = { + defense = 25, + armor = 78, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_HEALING, minDamage = 150, maxDamage = 350, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/grave_danger/soulless_minion.lua b/data/monster/quests/grave_danger/soulless_minion.lua new file mode 100644 index 00000000000..c7c0131218f --- /dev/null +++ b/data/monster/quests/grave_danger/soulless_minion.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Soulless Minion") +local monster = {} + +monster.description = "Soulless Minion" +monster.experience = 0 +monster.outfit = { + lookType = 68, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 475 +monster.maxHealth = 475 +monster.race = "blood" +monster.corpse = 6006 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 30, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -50, maxDamage = -200, range = 1, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="speed", interval = 2000, chance = 15, speedChange = -400, range = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 60000} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="outfit", interval = 4000, chance = 10, effect = CONST_ME_GROUNDSHAKER, target = false, duration = 5000, outfitMonster = "bat"}, + {name ="speed", interval = 2000, chance = 15, speedChange = 300, effect = CONST_ME_MAGIC_RED, target = false, duration = 3000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 15, maxDamage = 25, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 35}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/grave_danger/squire_of_nictros.lua b/data/monster/quests/grave_danger/squire_of_nictros.lua new file mode 100644 index 00000000000..8c8b5ca317f --- /dev/null +++ b/data/monster/quests/grave_danger/squire_of_nictros.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Squire of Nictros") +local monster = {} + +monster.description = "an Squire of Nictros" +monster.experience = 0 +monster.outfit = { + lookType = 306, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -190, maxDamage = -335, range = 7, shootEffect = CONST_ANI_WHIRLWINDSWORD, target = false} +} + +monster.defenses = { + defense = 45, + armor = 45, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/grave_danger/vampiric_blood.lua b/data/monster/quests/grave_danger/vampiric_blood.lua new file mode 100644 index 00000000000..bc90e8bf85b --- /dev/null +++ b/data/monster/quests/grave_danger/vampiric_blood.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Vampiric Blood") +local monster = {} + +monster.description = "a Vampiric Blood" +monster.experience = 0 +monster.outfit = { + lookType = 1041, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5900 +monster.maxHealth = 5900 +monster.race = "fire" +monster.corpse = 0 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -250, maxDamage = -300, range = 7, length = 3, spread = 3, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_FIREDAMAGE, minDamage = 0, maxDamage = -100, range = 7, length = 6, spread = 3, effect = CONST_ME_HITBYFIRE, target = false} +} + +monster.defenses = { + defense = 33, + armor = 45 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/aftershock.lua b/data/monster/quests/heart_of_destruction/aftershock.lua new file mode 100644 index 00000000000..53d3edc7d67 --- /dev/null +++ b/data/monster/quests/heart_of_destruction/aftershock.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Aftershock") +local monster = {} + +monster.description = "Aftershock" +monster.experience = 20000 +monster.outfit = { + lookType = 875, + lookHead = 114, + lookBody = 114, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 105000 +monster.maxHealth = 105000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 380 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 3000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "ShocksDeath", + "AftershockTransform" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -800}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -350, maxDamage = -900, length = 10, spread = 3, effect = CONST_ME_BIGCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -250, maxDamage = -500, radius = 4, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -250, maxDamage = -750, radius = 8, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -150, maxDamage = -400, radius = 5, effect = CONST_ME_MAGIC_BLUE, target = true}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -350, maxDamage = -600, radius = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="aftershock wave", interval = 2000, chance = 15, minDamage = -100, maxDamage = -900, target = false}, + {name ="anomaly break", interval = 2000, chance = 40, target = false} +} + +monster.defenses = { + defense = 100, + armor = 100, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 300, maxDamage = 600, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/anomaly.lua b/data/monster/quests/heart_of_destruction/anomaly.lua new file mode 100644 index 00000000000..b3dca6013a8 --- /dev/null +++ b/data/monster/quests/heart_of_destruction/anomaly.lua @@ -0,0 +1,163 @@ +local mType = Game.createMonsterType("Anomaly") +local monster = {} + +monster.description = "Anomaly" +monster.experience = 50000 +monster.outfit = { + lookType = 876, + lookHead = 19, + lookBody = 98, + lookLegs = 19, + lookFeet = 79, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 290000 +monster.maxHealth = 290000 +monster.race = "venom" +monster.corpse = 26220 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "AnomalyTransform", + "HeartBossDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Brzlll! Brzzzl!", yell = false} +} + +monster.loot = { + {id = 25377, chance = 100000, maxCount = 4}, + {id = 26165, chance = 100000}, + {id = 26166, chance = 100000}, + {id = 2148, chance = 100000, maxCount = 200}, + {id = 2152, chance = 100000, maxCount = 30}, + {id = 18413, chance = 8000, maxCount = 3}, + {id = 18414, chance = 8000, maxCount = 3}, + {id = 18415, chance = 8000, maxCount = 3}, + {id = 2150, chance = 8000, maxCount = 10}, + {id = 2145, chance = 8000, maxCount = 10}, + {id = 9970, chance = 8000, maxCount = 10}, + {id = 7590, chance = 8000, maxCount = 10}, + {id = 8472, chance = 8000, maxCount = 5}, + {id = 8473, chance = 8000, maxCount = 5}, + {id = 26201, chance = 8000, maxCount = 5}, + {id = 2154, chance = 8000}, + {id = 2158, chance = 6000}, + {id = 2155, chance = 6000}, + {id = 26198, chance = 3500},-- collar of blue plasma + {id = 26185, chance = 3500}, + {id = 26187, chance = 3500}, + {id = 26167, chance = 8000}, + {id = 26175, chance = 8000}, + {id = 18450, chance = 4000, unique = true}, + {id = 7901, chance = 4000}, + {id = 7427, chance = 3000}, + {id = 7451, chance = 3000}, + {id = 8901, chance = 3000}, + {id = 7895, chance = 2500}, + {id = 7898, chance = 2500}, + {id = 26130, chance = 1600, unique = true}, + {id = 26133, chance = 1600, unique = true}, + {id = 6553, chance = 1600, unique = true}, + {id = 7633, chance = 1600, maxCount = 3} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -300, maxDamage = -1400}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_DEATHDAMAGE, minDamage = -300, maxDamage = -600, radius = 4, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="anomaly wave", interval = 2000, chance = 25, minDamage = -500, maxDamage = -900, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = -600, maxDamage = -1000, length = 9, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_LIFEDRAIN, minDamage = -300, maxDamage = -600, length = 9, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="anomaly break", interval = 2000, chance = 40, target = false} +} + +monster.defenses = { + defense = 100, + armor = 100, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_HEALING, minDamage = 150, maxDamage = 400, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -20}, + {type = COMBAT_ENERGYDAMAGE, percent = -20}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -20}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/charged_anomaly.lua b/data/monster/quests/heart_of_destruction/charged_anomaly.lua new file mode 100644 index 00000000000..a34c7f26cea --- /dev/null +++ b/data/monster/quests/heart_of_destruction/charged_anomaly.lua @@ -0,0 +1,127 @@ +local mType = Game.createMonsterType("Charged Anomaly") +local monster = {} + +monster.description = "a charged anomaly" +monster.experience = 0 +monster.outfit = { + lookType = 876, + lookHead = 80, + lookBody = 80, + lookLegs = 19, + lookFeet = 80, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 18000 +monster.maxHealth = 18000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 100 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "ChargedAnomalyDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -900, maxDamage = -2100}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -500, maxDamage = -900, radius = 3, effect = CONST_ME_BIGCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -350, maxDamage = -700, length = 7, spread = 3, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -500, maxDamage = -800, length = 7, spread = 3, effect = CONST_ME_YELLOWENERGY, target = false}, + {name ="anomaly break", interval = 2000, chance = 40, target = false}, + {name ="charge vortex", interval = 9000, chance = 100, target = false} +} + +monster.defenses = { + defense = 100, + armor = 100, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, radius = 8, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/charged_disruption.lua b/data/monster/quests/heart_of_destruction/charged_disruption.lua new file mode 100644 index 00000000000..0f4ee6d9f8c --- /dev/null +++ b/data/monster/quests/heart_of_destruction/charged_disruption.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Charged Disruption") +local monster = {} + +monster.description = "a charged disruption" +monster.experience = 400 +monster.outfit = { + lookTypeEx = 1387 +} + +monster.health = 128000 +monster.maxHealth = 128000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 360 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "ChargedDisruptionTransform", + "HeartMinionDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -636}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -150, maxDamage = -500, radius = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true} +} + +monster.defenses = { + defense = 100, + armor = 100, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 0, maxDamage = 311, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/charger.lua b/data/monster/quests/heart_of_destruction/charger.lua new file mode 100644 index 00000000000..3c06878e176 --- /dev/null +++ b/data/monster/quests/heart_of_destruction/charger.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Charger") +local monster = {} + +monster.description = "a charger" +monster.experience = 85 +monster.outfit = { + lookType = 293, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1600 +monster.maxHealth = 1600 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "ChargerSpawn" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -300}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -450, range = 4, radius = 2, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -350, range = 5, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + -- energy damage + {name ="condition", type = CONDITION_ENERGY, interval = 2000, chance = 15, minDamage = -400, maxDamage = -800, radius = 5, effect = CONST_ME_BLOCKHIT, target = false} +} + +monster.defenses = { + defense = 50, + armor = 50 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 80}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 25} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/charging_outburst.lua b/data/monster/quests/heart_of_destruction/charging_outburst.lua new file mode 100644 index 00000000000..a2af0a33f0b --- /dev/null +++ b/data/monster/quests/heart_of_destruction/charging_outburst.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Charging Outburst") +local monster = {} + +monster.description = "Charging Outburst" +monster.experience = 50000 +monster.outfit = { + lookType = 876, + lookHead = 77, + lookBody = 82, + lookLegs = 82, + lookFeet = 0, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 12000 +monster.maxHealth = 12000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "ChargingOutDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -300, maxDamage = -1800}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_DEATHDAMAGE, minDamage = -300, maxDamage = -500, radius = 3, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = -450, maxDamage = -900, radius = 8, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = -600, maxDamage = -1000, length = 8, spread = 3, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="anomaly break", interval = 2000, chance = 40, target = false}, + {name ="outburst explode", interval = 10000, chance = 100, minDamage = -1500, maxDamage = -2000, target = false} +} + +monster.defenses = { + defense = 100, + armor = 100 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -50}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/crackler.lua b/data/monster/quests/heart_of_destruction/crackler.lua new file mode 100644 index 00000000000..0def287983c --- /dev/null +++ b/data/monster/quests/heart_of_destruction/crackler.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Crackler") +local monster = {} + +monster.description = "a crackler" +monster.experience = 0 +monster.outfit = { + lookType = 293, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 15000 +monster.maxHealth = 15000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 3, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "CracklerTransform" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -300}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -100, maxDamage = -300, range = 4, radius = 2, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -100, maxDamage = -300, range = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_YELLOWENERGY, target = true}, + -- energy damage + {name ="condition", type = CONDITION_ENERGY, interval = 2000, chance = 15, minDamage = -400, maxDamage = -800, radius = 5, effect = CONST_ME_BLOCKHIT, target = false} +} + +monster.defenses = { + defense = 50, + armor = 50, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_HEALING, minDamage = 100, maxDamage = 300, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/damage_resonance.lua b/data/monster/quests/heart_of_destruction/damage_resonance.lua new file mode 100644 index 00000000000..fe543fc5d19 --- /dev/null +++ b/data/monster/quests/heart_of_destruction/damage_resonance.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Damage Resonance") +local monster = {} + +monster.description = "Damage Resonance" +monster.experience = 560 +monster.outfit = { + lookTypeEx = 25417 +} + +monster.health = 11000 +monster.maxHealth = 11000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 500 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 40 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 3, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "HeartMinionDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, range = 4, shootEffect = CONST_ANI_INFERNALBOLT, target = true}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, radius = 4, effect = CONST_ME_ENERGYAREA, target = true} +} + +monster.defenses = { + defense = 100, + armor = 100, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 150, maxDamage = 300, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/depolarized_crackler.lua b/data/monster/quests/heart_of_destruction/depolarized_crackler.lua new file mode 100644 index 00000000000..d242d489281 --- /dev/null +++ b/data/monster/quests/heart_of_destruction/depolarized_crackler.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Depolarized Crackler") +local monster = {} + +monster.description = "a depolarized crackler" +monster.experience = 0 +monster.outfit = { + lookType = 290, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 15000 +monster.maxHealth = 15000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 360 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "DepolarizedTransform", + "DepolarizedDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -180, maxDamage = -500, radius = 6, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_LOSEENERGY, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -300, maxDamage = -700, length = 10, spread = 3, effect = CONST_ME_TELEPORT, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -180, maxDamage = -350, radius = 8, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 80, + armor = 80 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/disruption.lua b/data/monster/quests/heart_of_destruction/disruption.lua new file mode 100644 index 00000000000..1f519a7e0b5 --- /dev/null +++ b/data/monster/quests/heart_of_destruction/disruption.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Disruption") +local monster = {} + +monster.description = "a disruption" +monster.experience = 398 +monster.outfit = { + lookTypeEx = 25417 +} + +monster.health = 12000 +monster.maxHealth = 12000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "DisruptionTransform", + "HeartMinionDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -262}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -150, maxDamage = -300, radius = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true} +} + +monster.defenses = { + defense = 100, + armor = 100 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/eradicator.lua b/data/monster/quests/heart_of_destruction/eradicator.lua new file mode 100644 index 00000000000..da8f75d602f --- /dev/null +++ b/data/monster/quests/heart_of_destruction/eradicator.lua @@ -0,0 +1,153 @@ +local mType = Game.createMonsterType("Eradicator") +local monster = {} + +monster.description = "Eradicator" +monster.experience = 50000 +monster.outfit = { + lookType = 875, + lookHead = 79, + lookBody = 3, + lookLegs = 114, + lookFeet = 79, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 290000 +monster.maxHealth = 290000 +monster.race = "venom" +monster.corpse = 26220 +monster.speed = 450 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "HeartBossDeath", + "EradicatorTransform" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 200}, + {id = 2152, chance = 100000, maxCount = 25}, + {id = 18415, chance = 8000, maxCount = 3}, + {id = 7590, chance = 8000, maxCount = 5}, + {id = 8472, chance = 8000, maxCount = 5}, + {id = 2150, chance = 8000, maxCount = 5}, + {id = 2147, chance = 8000, maxCount = 5}, + {id = 9970, chance = 8000, maxCount = 5}, + {id = 8473, chance = 8000, maxCount = 10}, + {id = 18414, chance = 8000, maxCount = 3}, + {id = 26191, chance = 8000}, + {id = 26176, chance = 8000}, + {id = 26174, chance = 8000}, + {id = 25377, chance = 100000}, + {id = 26165, chance = 100000}, + {id = 26166, chance = 100000}, + {id = 2158, chance = 6000}, + {id = 2155, chance = 6000}, + {id = 8901, chance = 6000}, + {id = 2445, chance = 4000}, + {id = 26185, chance = 3500}, + {id = 26187, chance = 3500}, + {id = 26189, chance = 3500}, + {id = 2645, chance = 5000, unique = true}, + {id = 8903, chance = 3000, unique = true} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -300, maxDamage = -1800}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -600, maxDamage = -1000, length = 8, spread = 3, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -600, maxDamage = -1000, length = 8, spread = 3, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -450, maxDamage = -900, radius = 8, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="big energy wave", interval = 2000, chance = 20, minDamage = -700, maxDamage = -1000, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_DEATHDAMAGE, minDamage = -300, maxDamage = -600, radius = 4, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="anomaly break", interval = 2000, chance = 40, target = false} +} + +monster.defenses = { + defense = 100, + armor = 100 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 70}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 30}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/eradicator2.lua b/data/monster/quests/heart_of_destruction/eradicator2.lua new file mode 100644 index 00000000000..2039b29a3a5 --- /dev/null +++ b/data/monster/quests/heart_of_destruction/eradicator2.lua @@ -0,0 +1,153 @@ +local mType = Game.createMonsterType("Eradicator") +local monster = {} + +monster.description = "Eradicator" +monster.experience = 50000 +monster.outfit = { + lookType = 875, + lookHead = 94, + lookBody = 3, + lookLegs = 78, + lookFeet = 94, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 290000 +monster.maxHealth = 290000 +monster.race = "venom" +monster.corpse = 26220 +monster.speed = 450 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "HeartBossDeath", + "EradicatorTransform" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 200}, + {id = 2152, chance = 100000, maxCount = 25}, + {id = 18415, chance = 8000, maxCount = 3}, + {id = 7590, chance = 8000, maxCount = 5}, + {id = 8472, chance = 8000, maxCount = 5}, + {id = 2150, chance = 8000, maxCount = 5}, + {id = 2147, chance = 8000, maxCount = 5}, + {id = 9970, chance = 8000, maxCount = 5}, + {id = 8473, chance = 8000, maxCount = 10}, + {id = 18414, chance = 8000, maxCount = 3}, + {id = 26191, chance = 8000}, + {id = 26176, chance = 8000}, + {id = 26174, chance = 8000}, + {id = 25377, chance = 100000}, + {id = 26165, chance = 100000}, + {id = 26166, chance = 100000}, + {id = 2158, chance = 6000}, + {id = 2155, chance = 6000}, + {id = 8901, chance = 6000}, + {id = 2445, chance = 4000}, + {id = 26185, chance = 3500}, + {id = 26187, chance = 3500}, + {id = 26189, chance = 3500}, + {id = 2645, chance = 5000, unique = true}, + {id = 8903, chance = 3000, unique = true} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -300, maxDamage = -1800}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -600, maxDamage = -1000, length = 8, spread = 3, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -450, maxDamage = -900, radius = 8, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HOLYDAMAGE, minDamage = -300, maxDamage = -600, radius = 4, shootEffect = CONST_ANI_SMALLHOLY, effect = CONST_ME_HOLYDAMAGE, target = true}, + {name ="big lifedrain wave", interval = 2000, chance = 20, minDamage = -700, maxDamage = -1000, target = false}, + {name ="anomaly break", interval = 2000, chance = 40, target = false} +} + +monster.defenses = { + defense = 60, + armor = 60, + {name ="combat", interval = 2000, chance = 100, type = COMBAT_HEALING, minDamage = 500, maxDamage = 1200, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 15}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 15}, + {type = COMBAT_FIREDAMAGE, percent = 15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 15}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/foreshock.lua b/data/monster/quests/heart_of_destruction/foreshock.lua new file mode 100644 index 00000000000..d2f71e8fc12 --- /dev/null +++ b/data/monster/quests/heart_of_destruction/foreshock.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Foreshock") +local monster = {} + +monster.description = "Foreshock" +monster.experience = 20000 +monster.outfit = { + lookType = 875, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 105000 +monster.maxHealth = 105000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 380 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 3000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "ShocksDeath", + "ForeshockTransform" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -400, maxDamage = -1000}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -350, maxDamage = -800, length = 10, spread = 3, effect = CONST_ME_LOSEENERGY, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -400, maxDamage = -1000, radius = 8, effect = CONST_ME_HITAREA, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = -350, maxDamage = -600, length = 10, spread = 3, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HOLYDAMAGE, minDamage = -350, maxDamage = -800, radius = 4, effect = CONST_ME_HOLYDAMAGE, target = true}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = -150, maxDamage = -300, length = 2, spread = 0, effect = CONST_ME_HITAREA, target = false}, + {name ="anomaly break", interval = 2000, chance = 40, target = false} +} + +monster.defenses = { + defense = 100, + armor = 100, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 300, maxDamage = 600, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -20}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/frenzy.lua b/data/monster/quests/heart_of_destruction/frenzy.lua new file mode 100644 index 00000000000..11d9bce4f4b --- /dev/null +++ b/data/monster/quests/heart_of_destruction/frenzy.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Frenzy") +local monster = {} + +monster.description = "Frenzy" +monster.experience = 1313 +monster.outfit = { + lookType = 290, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 8210 +monster.maxHealth = 8210 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 380 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "HeartMinionDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1047}, + {name ="big energy purple wave2", interval = 2000, chance = 100, minDamage = 0, maxDamage = -730, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -464, radius = 4, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, radius = 7, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 100, + armor = 100, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 0, maxDamage = 438, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 40}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = -5}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 25}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/greed.lua b/data/monster/quests/heart_of_destruction/greed.lua new file mode 100644 index 00000000000..ff6a74214d5 --- /dev/null +++ b/data/monster/quests/heart_of_destruction/greed.lua @@ -0,0 +1,103 @@ +local mType = Game.createMonsterType("Greed") +local monster = {} + +monster.description = "Greed" +monster.experience = 0 +monster.outfit = { + lookType = 293, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 380 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -940}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -600, radius = 6, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_LOSEENERGY, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -300, maxDamage = -700, length = 9, spread = 3, effect = CONST_ME_TELEPORT, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, radius = 7, effect = CONST_ME_POFF, target = false}, + {name ="anomaly break", interval = 2000, chance = 40, target = false} +} + +monster.defenses = { + defense = 50, + armor = 50 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/outburst.lua b/data/monster/quests/heart_of_destruction/outburst.lua new file mode 100644 index 00000000000..8015b0f231f --- /dev/null +++ b/data/monster/quests/heart_of_destruction/outburst.lua @@ -0,0 +1,145 @@ +local mType = Game.createMonsterType("Outburst") +local monster = {} + +monster.description = "Outburst" +monster.experience = 50000 +monster.outfit = { + lookType = 876, + lookHead = 79, + lookBody = 0, + lookLegs = 94, + lookFeet = 0, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 290000 +monster.maxHealth = 290000 +monster.race = "venom" +monster.corpse = 26220 +monster.speed = 500 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "HeartBossDeath", + "OutburstCharge" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 200}, + {id = 2152, chance = 100000, maxCount = 10}, + {id = 18413, chance = 8000, maxCount = 3}, + {id = 7590, chance = 8000, maxCount = 10}, + {id = 18415, chance = 8000, maxCount = 3}, + {id = 2150, chance = 8000, maxCount = 10}, + {id = 2146, chance = 8000, maxCount = 5}, + {id = 8473, chance = 8000, maxCount = 5}, + {id = 18414, chance = 8000, maxCount = 3}, + {id = 25377, chance = 100000}, + {id = 26165, chance = 100000}, + {id = 2155, chance = 8000}, + {id = 7427, chance = 6000}, + {id = 26189, chance = 5000}, + {id = 26130, chance = 2000, unique = true}, + {id = 26133, chance = 2000, unique = true}, + {id = 18450, chance = 2000, unique = true} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -300, maxDamage = -1800}, + {name ="big energy purple wave", interval = 2000, chance = 25, minDamage = -700, maxDamage = -1300, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_DEATHDAMAGE, minDamage = -300, maxDamage = -600, radius = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYAREA, target = true}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = -800, maxDamage = -1300, length = 8, spread = 3, effect = CONST_ME_HITAREA, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_LIFEDRAIN, minDamage = -600, maxDamage = -900, length = 8, spread = 3, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="big skill reducer", interval = 2000, chance = 25, target = false}, + {name ="anomaly break", interval = 2000, chance = 40, target = false} +} + +monster.defenses = { + defense = 100, + armor = 100 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/overcharge.lua b/data/monster/quests/heart_of_destruction/overcharge.lua new file mode 100644 index 00000000000..fb5d0fe5e98 --- /dev/null +++ b/data/monster/quests/heart_of_destruction/overcharge.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Overcharge") +local monster = {} + +monster.description = "an overcharge" +monster.experience = 0 +monster.outfit = { + lookType = 290, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 8000 +monster.maxHealth = 8000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 360 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "OverchargeDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -500}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -500, radius = 5, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_LOSEENERGY, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -400, radius = 7, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -300, maxDamage = -670, length = 9, spread = 3, effect = CONST_ME_TELEPORT, target = false} +} + +monster.defenses = { + defense = 80, + armor = 80 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/overcharged_disruption.lua b/data/monster/quests/heart_of_destruction/overcharged_disruption.lua new file mode 100644 index 00000000000..c996b920c42 --- /dev/null +++ b/data/monster/quests/heart_of_destruction/overcharged_disruption.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Overcharged Disruption") +local monster = {} + +monster.description = "an overcharged disruption" +monster.experience = 400 +monster.outfit = { + lookTypeEx = 8058 +} + +monster.health = 128000 +monster.maxHealth = 128000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 380 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "HeartMinionDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -741}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -300, maxDamage = -600, radius = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, radius = 7, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 100, + armor = 100 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/realityquake.lua b/data/monster/quests/heart_of_destruction/realityquake.lua new file mode 100644 index 00000000000..cf1e45ddf98 --- /dev/null +++ b/data/monster/quests/heart_of_destruction/realityquake.lua @@ -0,0 +1,144 @@ +local mType = Game.createMonsterType("Realityquake") +local monster = {} + +monster.description = "Realityquake" +monster.experience = 80000 +monster.outfit = { + lookTypeEx = 1387 +} + +monster.health = 110000 +monster.maxHealth = 110000 +monster.race = "venom" +monster.corpse = 26223 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 3000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "HeartBossDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 200}, + {id = 7590, chance = 8000, maxCount = 5}, + {id = 8472, chance = 8000, maxCount = 5}, + {id = 8473, chance = 8000, maxCount = 5}, + {id = 26191, chance = 8000, maxCount = 5}, + {id = 18413, chance = 8000, maxCount = 3}, + {id = 18415, chance = 8000, maxCount = 3}, + {id = 2149, chance = 8000, maxCount = 5}, + {id = 2147, chance = 8000, maxCount = 5}, + {id = 18414, chance = 8000, maxCount = 3}, + {id = 26163, chance = 8000}, + {id = 26164, chance = 8000}, + {id = 2156, chance = 8000}, + {id = 25377, chance = 100000}, + {id = 26165, chance = 100000}, + {id = 26166, chance = 100000}, + {id = 7632, chance = 4000}, + {id = 7633, chance = 4000}, + {id = 2189, chance = 8000}, + {id = 26187, chance = 6000}, + {id = 26189, chance = 6000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -400, maxDamage = -1000}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -350, maxDamage = -800, length = 10, spread = 3, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = -350, maxDamage = -800, length = 10, spread = 3, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = -240, maxDamage = -600, radius = 5, effect = CONST_ME_POFF, target = true}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HOLYDAMAGE, minDamage = -240, maxDamage = -600, radius = 5, shootEffect = CONST_ANI_HOLY, effect = CONST_ME_HOLYDAMAGE, target = true}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_EARTHDAMAGE, minDamage = -200, maxDamage = -450, length = 4, spread = 2, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_DEATHDAMAGE, minDamage = -240, maxDamage = -600, radius = 5, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="anomaly break", interval = 2000, chance = 40, target = false} +} + +monster.defenses = { + defense = 100, + armor = 100, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, radius = 8, effect = CONST_ME_POFF, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/rupture.lua b/data/monster/quests/heart_of_destruction/rupture.lua new file mode 100644 index 00000000000..cbdea791bfa --- /dev/null +++ b/data/monster/quests/heart_of_destruction/rupture.lua @@ -0,0 +1,148 @@ +local mType = Game.createMonsterType("Rupture") +local monster = {} + +monster.description = "Rupture" +monster.experience = 112000 +monster.outfit = { + lookType = 875, + lookHead = 77, + lookBody = 98, + lookLegs = 3, + lookFeet = 85, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 290000 +monster.maxHealth = 290000 +monster.race = "venom" +monster.corpse = 26220 +monster.speed = 450 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "RuptureResonance", + "RuptureHeal", + "HeartBossDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 200}, + {id = 2152, chance = 100000, maxCount = 10}, + {id = 8473, chance = 8000, maxCount = 5}, + {id = 18413, chance = 8000, maxCount = 3}, + {id = 18415, chance = 8000, maxCount = 3}, + {id = 2150, chance = 8000, maxCount = 10}, + {id = 2146, chance = 8000, maxCount = 5}, + {id = 18414, chance = 8000, maxCount = 3}, + {id = 26191, chance = 8000, maxCount = 5}, + {id = 26162, chance = 8000}, + {id = 26166, chance = 100000}, + {id = 25377, chance = 100000}, + {id = 26165, chance = 100000}, + {id = 2155, chance = 6000}, + {id = 7427, chance = 6000}, + {id = 26187, chance = 4000}, + {id = 26189, chance = 4000}, + {id = 26130, chance = 2000, unique = true}, + {id = 26133, chance = 2000, unique = true} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -250, maxDamage = -1000}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -350, maxDamage = -800, length = 10, spread = 3, effect = CONST_ME_LOSEENERGY, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_DEATHDAMAGE, minDamage = -150, maxDamage = -300, radius = 4, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="rupture wave", interval = 2000, chance = 20, minDamage = -700, maxDamage = -1100, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_LIFEDRAIN, minDamage = -300, maxDamage = -600, length = 9, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="anomaly break", interval = 2000, chance = 40, target = false} +} + +monster.defenses = { + defense = 100, + armor = 100, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 150, maxDamage = 400, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/spark_of_destruction.lua b/data/monster/quests/heart_of_destruction/spark_of_destruction.lua new file mode 100644 index 00000000000..d8d309f562f --- /dev/null +++ b/data/monster/quests/heart_of_destruction/spark_of_destruction.lua @@ -0,0 +1,103 @@ +local mType = Game.createMonsterType("Spark of Destruction") +local monster = {} + +monster.description = "a spark of destruction" +monster.experience = 0 +monster.outfit = { + lookType = 879, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3900 +monster.maxHealth = 3900 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 3000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -436}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -180, maxDamage = -400, range = 5, radius = 5, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_PURPLEENERGY, target = true}, + {name ="reality reaver wave", interval = 2000, chance = 20, minDamage = -100, maxDamage = -400, target = false}, + -- energy damage + {name ="condition", type = CONDITION_ENERGY, interval = 2000, chance = 20, minDamage = -400, maxDamage = -800, radius = 5, effect = CONST_ME_STUN, target = false} +} + +monster.defenses = { + defense = 65, + armor = 65 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/the_destruction.lua b/data/monster/quests/heart_of_destruction/the_destruction.lua new file mode 100644 index 00000000000..511e7251d82 --- /dev/null +++ b/data/monster/quests/heart_of_destruction/the_destruction.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("The Destruction") +local monster = {} + +monster.description = "The Destruction" +monster.experience = 0 +monster.outfit = { + lookType = 876, + lookHead = 78, + lookBody = 80, + lookLegs = 77, + lookFeet = 19, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 250000 +monster.maxHealth = 250000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "HeartMinionDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1393}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -300, maxDamage = -600, radius = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_YELLOWENERGY, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -400, maxDamage = -800, radius = 4, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_EXPLOSIONAREA, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -200, maxDamage = -400, length = 10, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, radius = 8, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -500, maxDamage = -900, length = 10, spread = 3, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -500, maxDamage = -900, length = 10, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="anomaly break", interval = 2000, chance = 40, target = false}, + {name ="destruction summon", interval = 2000, chance = 20, target = false} +} + +monster.defenses = { + defense = 100, + armor = 100, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 0, maxDamage = 546, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/the_hunger.lua b/data/monster/quests/heart_of_destruction/the_hunger.lua new file mode 100644 index 00000000000..c770575dde0 --- /dev/null +++ b/data/monster/quests/heart_of_destruction/the_hunger.lua @@ -0,0 +1,110 @@ +local mType = Game.createMonsterType("The Hunger") +local monster = {} + +monster.description = "The Hunger" +monster.experience = 0 +monster.outfit = { + lookType = 876, + lookHead = 77, + lookBody = 80, + lookLegs = 85, + lookFeet = 94, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 250000 +monster.maxHealth = 250000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "HeartMinionDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -962}, + {name ="practise fire wave", interval = 2000, chance = 20, minDamage = -600, maxDamage = -900, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, radius = 8, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -700, maxDamage = -1100, length = 10, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -200, maxDamage = -400, length = 10, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="anomaly break", interval = 2000, chance = 40, target = false}, + {name ="hunger summon", interval = 2000, chance = 20, target = false} +} + +monster.defenses = { + defense = 100, + armor = 100, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 0, maxDamage = 191, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/the_rage.lua b/data/monster/quests/heart_of_destruction/the_rage.lua new file mode 100644 index 00000000000..5dee6aa79d6 --- /dev/null +++ b/data/monster/quests/heart_of_destruction/the_rage.lua @@ -0,0 +1,111 @@ +local mType = Game.createMonsterType("The Rage") +local monster = {} + +monster.description = "The Rage" +monster.experience = 0 +monster.outfit = { + lookType = 876, + lookHead = 85, + lookBody = 114, + lookLegs = 19, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 250000 +monster.maxHealth = 250000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "HeartMinionDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -740}, + {name ="big death wave", interval = 2000, chance = 20, minDamage = -600, maxDamage = -900, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -200, maxDamage = -400, length = 10, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -300, maxDamage = -600, radius = 4, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="big explosion wave", interval = 2000, chance = 20, minDamage = -600, maxDamage = -900, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, radius = 8, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -600, length = 10, spread = 3, effect = CONST_ME_YELLOW_RINGS, target = false}, + {name ="anomaly break", interval = 2000, chance = 40, target = false}, + {name ="rage summon", interval = 2000, chance = 20, target = false} +} + +monster.defenses = { + defense = 100, + armor = 100 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/unstable_spark.lua b/data/monster/quests/heart_of_destruction/unstable_spark.lua new file mode 100644 index 00000000000..4768ee2a05d --- /dev/null +++ b/data/monster/quests/heart_of_destruction/unstable_spark.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Unstable Spark") +local monster = {} + +monster.description = "an unstable spark" +monster.experience = 1500 +monster.outfit = { + lookType = 290, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10500 +monster.maxHealth = 10500 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 278 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "SparkDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -500}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -180, maxDamage = -500, radius = 6, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_LOSEENERGY, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -300, maxDamage = -700, length = 10, spread = 3, effect = CONST_ME_TELEPORT, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -180, maxDamage = -350, radius = 8, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 80, + armor = 80 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/heart_of_destruction/world_devourer.lua b/data/monster/quests/heart_of_destruction/world_devourer.lua new file mode 100644 index 00000000000..7414a991989 --- /dev/null +++ b/data/monster/quests/heart_of_destruction/world_devourer.lua @@ -0,0 +1,152 @@ +local mType = Game.createMonsterType("World Devourer") +local monster = {} + +monster.description = "World Devourer" +monster.experience = 77700 +monster.outfit = { + lookType = 875, + lookHead = 82, + lookBody = 79, + lookLegs = 81, + lookFeet = 113, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 25000 +monster.maxHealth = 25000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 450 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "HeartBossDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2152, chance = 100000, maxCount = 20}, + {id = 18413, chance = 10000, maxCount = 3}, + {id = 7590, chance = 10000, maxCount = 5}, + {id = 8472, chance = 10000, maxCount = 5}, + {id = 18415, chance = 10000, maxCount = 3}, + {id = 8473, chance = 10000, maxCount = 5}, + {id = 18414, chance = 10000, maxCount = 3}, + {id = 26163, chance = 10000}, + {id = 26164, chance = 10000}, + {id = 7632, chance = 5000}, + {id = 7633, chance = 5000}, + {id = 26166, chance = 10000}, + {id = 26176, chance = 10000}, + {id = 2155, chance = 10000}, + {id = 25377, chance = 100000}, + {id = 7426, chance = 10000}, + {id = 7901, chance = 8000}, + {id = 26189, chance = 8000}, + {id = 2153, chance = 8000}, + {id = 26130, chance = 6000, unique = true}, + {id = 26133, chance = 6000, unique = true}, + {id = 26342, chance = 4000, unique = true}, + {id = 26340, chance = 2000, unique = true} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1600}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -400, maxDamage = -800, length = 10, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -400, maxDamage = -800, radius = 4, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -400, maxDamage = -800, radius = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_YELLOWENERGY, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -600, maxDamage = -1200, length = 10, spread = 3, effect = CONST_ME_LOSEENERGY, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, radius = 8, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="anomaly break", interval = 2000, chance = 40, target = false}, + {name ="devourer summon", interval = 2000, chance = 25, target = false} +} + +monster.defenses = { + defense = 150, + armor = 150 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/hero_of_rathleton/deep_terror.lua b/data/monster/quests/hero_of_rathleton/deep_terror.lua new file mode 100644 index 00000000000..27120325cdc --- /dev/null +++ b/data/monster/quests/hero_of_rathleton/deep_terror.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Deep Terror") +local monster = {} + +monster.description = "Deep Terror" +monster.experience = 35000 +monster.outfit = { + lookType = 676, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 100000 +monster.maxHealth = 100000 +monster.race = "blood" +monster.corpse = 24269 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 24268, chance = 10000, unique = true} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 130, attack = 100}, + {name ="combat", interval = 2000, chance = 32, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -400, radius = 8, effect = CONST_ME_CARNIPHILA, target = false}, + {name ="combat", interval = 2000, chance = 19, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -700, range = 7, radius = 3, shootEffect = CONST_ANI_POISON, effect = CONST_ME_CARNIPHILA, target = true}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = -500, maxDamage = -1000, length = 7, spread = 3, effect = CONST_ME_GROUNDSHAKER, target = false} +} + +monster.defenses = { + defense = 35, + armor = 22, + {name ="combat", interval = 2000, chance = 11, type = COMBAT_HEALING, minDamage = 500, maxDamage = 1000, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/hero_of_rathleton/empowered_glooth_horror.lua b/data/monster/quests/hero_of_rathleton/empowered_glooth_horror.lua new file mode 100644 index 00000000000..5ad7a1522b9 --- /dev/null +++ b/data/monster/quests/hero_of_rathleton/empowered_glooth_horror.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("Empowered Glooth Horror") +local monster = {} + +monster.description = "an empowered glooth horror" +monster.experience = 2150 +monster.outfit = { + lookType = 677, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 25000 +monster.maxHealth = 25000 +monster.race = "venom" +monster.corpse = 24276 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 200, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "GloothHorror" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 24274, chance = 10000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 150, attack = 100}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -400, maxDamage = -600, range = 1, shootEffect = CONST_ANI_POISON, target = true}, + {name ="drunk", interval = 2000, chance = 8, radius = 8, effect = CONST_ME_HITBYPOISON, target = false, duration = 15000}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 12, minDamage = -600, maxDamage = -900, radius = 8, effect = CONST_ME_HITBYPOISON, target = false} +} + +monster.defenses = { + defense = 25, + armor = 15, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 500, maxDamage = 700, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/hero_of_rathleton/energy_pulse.lua b/data/monster/quests/hero_of_rathleton/energy_pulse.lua new file mode 100644 index 00000000000..9a8d939f7e2 --- /dev/null +++ b/data/monster/quests/hero_of_rathleton/energy_pulse.lua @@ -0,0 +1,96 @@ +local mType = Game.createMonsterType("energy pulse") +local monster = {} + +monster.description = "energy pulse" +monster.experience = 0 +monster.outfit = { + lookType = 294, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5000 +monster.maxHealth = 5000 +monster.race = "undead" +monster.corpse = 10508 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="energy pulse explosion", interval = 1000, chance = 100, minDamage = -5000, maxDamage = -6000, target = false} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/hero_of_rathleton/feeble_glooth_horror.lua b/data/monster/quests/hero_of_rathleton/feeble_glooth_horror.lua new file mode 100644 index 00000000000..0e5706269a8 --- /dev/null +++ b/data/monster/quests/hero_of_rathleton/feeble_glooth_horror.lua @@ -0,0 +1,104 @@ +local mType = Game.createMonsterType("Feeble Glooth Horror") +local monster = {} + +monster.description = "feeble glooth horror" +monster.experience = 245 +monster.outfit = { + lookType = 677, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5000 +monster.maxHealth = 5000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 200, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "GloothHorror" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 110, attack = 50} +} + +monster.defenses = { + defense = 25, + armor = 15, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 500, maxDamage = 600, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/hero_of_rathleton/glooth-generator.lua b/data/monster/quests/hero_of_rathleton/glooth-generator.lua new file mode 100644 index 00000000000..50c09a0ad13 --- /dev/null +++ b/data/monster/quests/hero_of_rathleton/glooth-generator.lua @@ -0,0 +1,94 @@ +local mType = Game.createMonsterType("Glooth-Generator") +local monster = {} + +monster.description = "a glooth-generator" +monster.experience = 3000 +monster.outfit = { + lookTypeEx = 23081 +} + +monster.health = 12000 +monster.maxHealth = 12000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="combat", interval = 2000, chance = 18, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -600, radius = 2, effect = CONST_ME_ENERGYAREA, target = false} +} + +monster.defenses = { + defense = 50, + armor = 50, + {name ="glooth-generator summon", interval = 1000, chance = 100, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 25}, + {type = COMBAT_ENERGYDAMAGE, percent = 25}, + {type = COMBAT_EARTHDAMAGE, percent = 25}, + {type = COMBAT_FIREDAMAGE, percent = 25}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 25}, + {type = COMBAT_HOLYDAMAGE , percent = 25}, + {type = COMBAT_DEATHDAMAGE , percent = 25} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/hero_of_rathleton/glooth_horror.lua b/data/monster/quests/hero_of_rathleton/glooth_horror.lua new file mode 100644 index 00000000000..65ddf6d4db2 --- /dev/null +++ b/data/monster/quests/hero_of_rathleton/glooth_horror.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Glooth Horror") +local monster = {} + +monster.description = "glooth horror" +monster.experience = 900 +monster.outfit = { + lookType = 677, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 15000 +monster.maxHealth = 15000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 200, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "GloothHorror" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 110, attack = 100}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_DEATHDAMAGE, minDamage = -300, maxDamage = -700, length = 8, spread = 3, target = false}, + {name ="drunk", interval = 2000, chance = 8, radius = 8, effect = CONST_ME_HITBYPOISON, target = false, duration = 15000} +} + +monster.defenses = { + defense = 25, + armor = 15, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 400, maxDamage = 700, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/hero_of_rathleton/glooth_masher.lua b/data/monster/quests/hero_of_rathleton/glooth_masher.lua new file mode 100644 index 00000000000..0cabc360dcd --- /dev/null +++ b/data/monster/quests/hero_of_rathleton/glooth_masher.lua @@ -0,0 +1,102 @@ +local mType = Game.createMonsterType("Glooth Masher") +local monster = {} + +monster.description = "a glooth masher" +monster.experience = 2200 +monster.outfit = { + lookType = 600, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2700 +monster.maxHealth = 2700 +monster.race = "venom" +monster.corpse = 23343 +monster.speed = 260 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 60, attack = 50}, + {name ="melee", interval = 2000, chance = 2, skill = 86, attack = 100}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -125, maxDamage = -245, range = 7, shootEffect = CONST_ANI_ENERGY, target = false}, + {name ="war golem skill reducer", interval = 2000, chance = 16, target = false}, + {name ="war golem electrify", interval = 2000, chance = 9, range = 7, target = false} +} + +monster.defenses = { + defense = 45, + armor = 40, + {name ="speed", interval = 2000, chance = 13, speedChange = 404, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 15}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/hero_of_rathleton/glooth_slasher.lua b/data/monster/quests/hero_of_rathleton/glooth_slasher.lua new file mode 100644 index 00000000000..1c3191c1666 --- /dev/null +++ b/data/monster/quests/hero_of_rathleton/glooth_slasher.lua @@ -0,0 +1,102 @@ +local mType = Game.createMonsterType("Glooth Slasher") +local monster = {} + +monster.description = "a glooth slasher" +monster.experience = 2200 +monster.outfit = { + lookType = 600, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2700 +monster.maxHealth = 2700 +monster.race = "venom" +monster.corpse = 23343 +monster.speed = 260 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 60, attack = 50}, + {name ="melee", interval = 2000, chance = 2, skill = 86, attack = 100}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -125, maxDamage = -245, range = 7, shootEffect = CONST_ANI_ENERGY, target = false}, + {name ="war golem skill reducer", interval = 2000, chance = 16, target = false}, + {name ="war golem electrify", interval = 2000, chance = 9, range = 7, target = false} +} + +monster.defenses = { + defense = 45, + armor = 40, + {name ="speed", interval = 2000, chance = 13, speedChange = 404, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 15}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/hero_of_rathleton/glooth_trasher.lua b/data/monster/quests/hero_of_rathleton/glooth_trasher.lua new file mode 100644 index 00000000000..c83c441278a --- /dev/null +++ b/data/monster/quests/hero_of_rathleton/glooth_trasher.lua @@ -0,0 +1,102 @@ +local mType = Game.createMonsterType("Glooth Trasher") +local monster = {} + +monster.description = "a glooth trasher" +monster.experience = 2200 +monster.outfit = { + lookType = 600, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2700 +monster.maxHealth = 2700 +monster.race = "venom" +monster.corpse = 23343 +monster.speed = 260 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 60, attack = 50}, + {name ="melee", interval = 2000, chance = 2, skill = 86, attack = 100}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -125, maxDamage = -245, range = 7, shootEffect = CONST_ANI_ENERGY, target = false}, + {name ="war golem skill reducer", interval = 2000, chance = 16, target = false}, + {name ="war golem electrify", interval = 2000, chance = 9, range = 7, target = false} +} + +monster.defenses = { + defense = 45, + armor = 40, + {name ="speed", interval = 2000, chance = 13, speedChange = 404, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 15}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/hero_of_rathleton/professor_maxxen.lua b/data/monster/quests/hero_of_rathleton/professor_maxxen.lua new file mode 100644 index 00000000000..64d1b58c18d --- /dev/null +++ b/data/monster/quests/hero_of_rathleton/professor_maxxen.lua @@ -0,0 +1,138 @@ +local mType = Game.createMonsterType("Professor Maxxen") +local monster = {} + +monster.description = "Professor Maxxen" +monster.experience = 15500 +monster.outfit = { + lookType = 679, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 90000 +monster.maxHealth = 90000 +monster.race = "venom" +monster.corpse = 24279 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 8 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "walker", chance = 10, interval = 2000}, + {name = "glooth trasher", chance = 10, interval = 2000}, + {name = "glooth smasher", chance = 10, interval = 2000}, + {name = "glooth slasher", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 24270, chance = 1000, unique = true}, + {id = 23663, chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 180, attack = 200}, + {name ="combat", interval = 2000, chance = 11, type = COMBAT_ENERGYDAMAGE, minDamage = -250, maxDamage = -500, radius = 8, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_MANADRAIN, minDamage = -450, maxDamage = -1500, length = 8, spread = 3, effect = CONST_ME_TELEPORT, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -450, maxDamage = -500, length = 8, spread = 3, effect = CONST_ME_FIREATTACK, target = false}, + {name ="war golem skill reducer", interval = 2000, chance = 22, target = false}, + {name ="war golem electrify", interval = 2000, chance = 16, range = 2, target = false}, + {name ="glooth fairy skill reducer", interval = 2000, chance = 20, target = false}, + {name ="glooth fairy paralyze", interval = 2000, chance = 9, target = false} +} + +monster.defenses = { + defense = 45, + armor = 40, + {name ="speed", interval = 2000, chance = 13, speedChange = 460, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="generator", interval = 30000, chance = 50, target = false}, + {name ="maxxenteleport", interval = 2000, chance = 5, target = false}, + {name ="glooth fairy healing", interval = 1000, chance = 100, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/hero_of_rathleton/strong_glooth_horror.lua b/data/monster/quests/hero_of_rathleton/strong_glooth_horror.lua new file mode 100644 index 00000000000..79f55b44f01 --- /dev/null +++ b/data/monster/quests/hero_of_rathleton/strong_glooth_horror.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Strong Glooth Horror") +local monster = {} + +monster.description = "a strong glooth horror" +monster.experience = 1500 +monster.outfit = { + lookType = 677, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 200, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "GloothHorror" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 150, attack = 100}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -300, maxDamage = -500, range = 1, shootEffect = CONST_ANI_POISON, target = true}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 12, minDamage = -500, maxDamage = -800, radius = 8, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="drunk", interval = 2000, chance = 8, radius = 8, effect = CONST_ME_HITBYPOISON, target = false, duration = 15000} +} + +monster.defenses = { + defense = 25, + armor = 15, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 500, maxDamage = 700, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/hero_of_rathleton/tentacle_of_the_deep_terror.lua b/data/monster/quests/hero_of_rathleton/tentacle_of_the_deep_terror.lua new file mode 100644 index 00000000000..19599037082 --- /dev/null +++ b/data/monster/quests/hero_of_rathleton/tentacle_of_the_deep_terror.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Tentacle of the Deep Terror") +local monster = {} + +monster.description = "a tentacle of the deep terror" +monster.experience = 5850 +monster.outfit = { + lookType = 681, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 25500 +monster.maxHealth = 25500 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 800, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "TentacleDeep" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 88, attack = 100}, + {name ="blightwalker curse", interval = 2000, chance = 10, target = false}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_LIFEDRAIN, minDamage = -65, maxDamage = -135, radius = 4, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="drunk", interval = 2000, chance = 20, radius = 7, effect = CONST_ME_HITBYPOISON, target = false, duration = 35000} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 225, maxDamage = 850, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = -30}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/hero_of_rathleton/weakened_glooth_horror.lua b/data/monster/quests/hero_of_rathleton/weakened_glooth_horror.lua new file mode 100644 index 00000000000..d01d96395eb --- /dev/null +++ b/data/monster/quests/hero_of_rathleton/weakened_glooth_horror.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Weakened Glooth Horror") +local monster = {} + +monster.description = "a weakened glooth horror" +monster.experience = 245 +monster.outfit = { + lookType = 677, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 200, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "GloothHorror" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 100}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_DEATHDAMAGE, minDamage = -300, maxDamage = -600, length = 8, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 11, type = COMBAT_DEATHDAMAGE, minDamage = -200, maxDamage = -400, range = 1, shootEffect = CONST_ANI_POISON, target = true} +} + +monster.defenses = { + defense = 25, + armor = 15, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 500, maxDamage = 600, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/hidden_threats/cave_spider.lua b/data/monster/quests/hidden_threats/cave_spider.lua new file mode 100644 index 00000000000..684bfb5d4f0 --- /dev/null +++ b/data/monster/quests/hidden_threats/cave_spider.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Cave Spider") +local monster = {} + +monster.description = "a cave spider" +monster.experience = 2000 +monster.outfit = { + lookType = 38, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1800 +monster.maxHealth = 1800 +monster.race = "venom" +monster.corpse = 32053 +monster.speed = 120 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Poison Spider", chance = 10, interval = 2000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 99990, maxCount = 76}, + {name = "strong health potion", chance = 50000}, + {name = "small diamond", chance = 50000, maxCount = 3}, + {name = "black pearl", chance = 16670}, + {name = "spider silk", chance = 16670} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300, condition = {type = CONDITION_POISON, totalDamage = 160, interval = 4000}}, + {name ="poisonfield", interval = 2000, chance = 10, range = 7, radius = 1, shootEffect = CONST_ANI_POISON, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -40, maxDamage = -70, range = 7, radius = 1, shootEffect = CONST_ANI_POISON, target = true} +} + +monster.defenses = { + defense = 0, + armor = 30, + {name ="speed", interval = 2000, chance = 15, speedChange = 390, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/in_service_of_yalahar/azerus.lua b/data/monster/quests/in_service_of_yalahar/azerus.lua new file mode 100644 index 00000000000..09413aaffa6 --- /dev/null +++ b/data/monster/quests/in_service_of_yalahar/azerus.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Azerus") +local monster = {} + +monster.description = "Azerus" +monster.experience = 6000 +monster.outfit = { + lookType = 309, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 26000 +monster.maxHealth = 26000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 286 +monster.manaCost = 0 +monster.maxSummons = 10 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Rift Worm", interval = 30, chance = 3000, max = 8}, + {name = "Rift Brood", interval = 30, chance = 3000, max = 8}, + {name = "Rift Scythe", interval = 30, chance = 3000, max = 8}, + {name = "War Golem", interval = 30, chance = 3000, max = 5} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "The ultimate will finally consume this unworthy existence!", yell = false}, + {text = "My masters and I will tear down barriers and join the ultimate in its realm!", yell = false}, + {text = "The power of the Yalahari will all be mine!", yell = false}, + {text = "He who has returned from beyond has taught me secrets you can't even grasp!", yell = false}, + {text = "You can't hope to penetrate my shields!", yell = false}, + {text = "Do you really think you could beat me?", yell = false}, + {text = "We will open the rift for a new time to come!", yell = false}, + {text = "The end of times has come!", yell = false}, + {text = "The great machinator will make his entrance soon!", yell = false}, + {text = "You might scratch my shields but they will never break!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -900}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -3800, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_BIGCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -524, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -300, maxDamage = -1050, length = 8, spread = 3, effect = CONST_ME_FIREATTACK, target = false} +} + +monster.defenses = { + defense = 65, + armor = 40, + {name ="combat", interval = 2000, chance = 11, type = COMBAT_HEALING, minDamage = 400, maxDamage = 900, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 15}, + {type = COMBAT_FIREDAMAGE, percent = 15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 15}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/in_service_of_yalahar/azerus2.lua b/data/monster/quests/in_service_of_yalahar/azerus2.lua new file mode 100644 index 00000000000..3f4053633e4 --- /dev/null +++ b/data/monster/quests/in_service_of_yalahar/azerus2.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Azerus2") +local monster = {} + +monster.name = "Azerus" +monster.description = "Azerus" +monster.experience = 6000 +monster.outfit = { + lookType = 309, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 26000 +monster.maxHealth = 26000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 286 +monster.manaCost = 0 +monster.maxSummons = 10 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Rift Worm", chance = 30, interval = 3000, max = 8}, + {name = "Rift Brood", chance = 30, interval = 3000, max = 8}, + {name = "Rift Scythe", chance = 30, interval = 3000, max = 8}, + {name = "War Golem", chance = 30, interval = 3000, max = 5} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "The ultimate will finally consume this unworthy existence!", yell = false}, + {text = "My masters and I will tear down barriers and join the ultimate in its realm!", yell = false}, + {text = "The power of the Yalahari will all be mine!", yell = false}, + {text = "He who has returned from beyond has taught me secrets you can't even grasp!", yell = false}, + {text = "You can't hope to penetrate my shields!", yell = false}, + {text = "Do you really think you could beat me?", yell = false}, + {text = "We will open the rift for a new time to come!", yell = false}, + {text = "The end of times has come!", yell = false}, + {text = "The great machinator will make his entrance soon!", yell = false}, + {text = "You might scratch my shields but they will never break!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -900}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -3800, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_BIGCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -524, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -300, maxDamage = -1050, length = 8, spread = 3, effect = CONST_ME_FIREATTACK, target = false} +} + +monster.defenses = { + defense = 65, + armor = 40, + {name ="combat", interval = 2000, chance = 11, type = COMBAT_HEALING, minDamage = 400, maxDamage = 900, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/in_service_of_yalahar/inky.lua b/data/monster/quests/in_service_of_yalahar/inky.lua new file mode 100644 index 00000000000..630b1185bab --- /dev/null +++ b/data/monster/quests/in_service_of_yalahar/inky.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Inky") +local monster = {} + +monster.description = "Inky" +monster.experience = 250 +monster.outfit = { + lookType = 46, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 750 +monster.maxHealth = 750 +monster.race = "blood" +monster.corpse = 6065 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Tssss!", yell = false}, + {text = "Gaaahhh!", yell = false}, + {text = "Gluh! Gluh!", yell = false}, + {text = "Boohaa!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 12000, maxCount = 13} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -156, condition = {type = CONDITION_POISON, totalDamage = 2, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -87, radius = 3, effect = CONST_ME_HITAREA, target = false}, + {name ="combat", interval = 2000, chance = 19, type = COMBAT_ICEDAMAGE, minDamage = 0, maxDamage = -80, radius = 3, shootEffect = CONST_ANI_POISON, target = false}, + {name ="combat", interval = 2000, chance = 7, type = COMBAT_ICEDAMAGE, minDamage = -56, maxDamage = -87, radius = 4, effect = CONST_ME_ICEAREA, target = false}, + {name ="quara constrictor electrify", interval = 2000, chance = 10, range = 1, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 90}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/in_service_of_yalahar/rift_brood.lua b/data/monster/quests/in_service_of_yalahar/rift_brood.lua new file mode 100644 index 00000000000..d1b7262190d --- /dev/null +++ b/data/monster/quests/in_service_of_yalahar/rift_brood.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Rift Brood") +local monster = {} + +monster.description = "a rift brood" +monster.experience = 1600 +monster.outfit = { + lookType = 290, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2950 +monster.maxHealth = 2950 +monster.race = "venom" +monster.corpse = 1495 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 20000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -255}, + {name ="combat", interval = 1000, chance = 90, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -400, range = 3, radius = 2, effect = CONST_ME_PURPLEENERGY, target = true} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 90, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 15}, + {type = COMBAT_DEATHDAMAGE , percent = -20} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/in_service_of_yalahar/rift_lord.lua b/data/monster/quests/in_service_of_yalahar/rift_lord.lua new file mode 100644 index 00000000000..4161f9eeee3 --- /dev/null +++ b/data/monster/quests/in_service_of_yalahar/rift_lord.lua @@ -0,0 +1,95 @@ +local mType = Game.createMonsterType("Rift Lord") +local monster = {} + +monster.description = "a rift lord" +monster.experience = 0 +monster.outfit = { + lookType = 12, + lookHead = 9, + lookBody = 19, + lookLegs = 9, + lookFeet = 85, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5 +monster.maxHealth = 5 +monster.race = "fire" +monster.corpse = 0 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 98, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/in_service_of_yalahar/rift_phantom.lua b/data/monster/quests/in_service_of_yalahar/rift_phantom.lua new file mode 100644 index 00000000000..ecaa45e97a4 --- /dev/null +++ b/data/monster/quests/in_service_of_yalahar/rift_phantom.lua @@ -0,0 +1,92 @@ +local mType = Game.createMonsterType("Rift Phantom") +local monster = {} + +monster.description = "a rift phantom" +monster.experience = 0 +monster.outfit = { + lookType = 48, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 150 +monster.maxHealth = 150 +monster.race = "undead" +monster.corpse = 5993 +monster.speed = 160 +monster.manaCost = 100 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = false, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/in_service_of_yalahar/rift_scythe.lua b/data/monster/quests/in_service_of_yalahar/rift_scythe.lua new file mode 100644 index 00000000000..92329ad0222 --- /dev/null +++ b/data/monster/quests/in_service_of_yalahar/rift_scythe.lua @@ -0,0 +1,104 @@ +local mType = Game.createMonsterType("Rift Scythe") +local monster = {} + +monster.description = "a rift scythe" +monster.experience = 2000 +monster.outfit = { + lookType = 300, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3600 +monster.maxHealth = 3600 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 370 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -979}, + {name ="combat", interval = 2000, chance = 60, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -200, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -600, length = 7, spread = 3, target = false}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -395, radius = 4, target = false}, + {name ="combat", interval = 3000, chance = 60, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -300, length = 7, spread = 3, effect = CONST_ME_EXPLOSIONAREA, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_HEALING, minDamage = 100, maxDamage = 195, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = -20}, + {type = COMBAT_DEATHDAMAGE , percent = 60} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/in_service_of_yalahar/rift_worm.lua b/data/monster/quests/in_service_of_yalahar/rift_worm.lua new file mode 100644 index 00000000000..cc20d561ba6 --- /dev/null +++ b/data/monster/quests/in_service_of_yalahar/rift_worm.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Rift Worm") +local monster = {} + +monster.description = "a rift worm" +monster.experience = 1195 +monster.outfit = { + lookType = 295, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2800 +monster.maxHealth = 2800 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 50, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -160}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -500, maxDamage = -1000, range = 7, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_GROUNDSHAKER} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = -25}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/in_service_of_yalahar/sharptooth.lua b/data/monster/quests/in_service_of_yalahar/sharptooth.lua new file mode 100644 index 00000000000..f768f308206 --- /dev/null +++ b/data/monster/quests/in_service_of_yalahar/sharptooth.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Sharptooth") +local monster = {} + +monster.description = "Sharptooth" +monster.experience = 1600 +monster.outfit = { + lookType = 20, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3100 +monster.maxHealth = 3100 +monster.race = "blood" +monster.corpse = 6067 +monster.speed = 290 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Gnarrr!", yell = false}, + {text = "Tcharrr!", yell = false}, + {text = "Rrrah!", yell = false}, + {text = "Rraaar!", yell = false} +} + +monster.loot = { + {id = 2226, chance = 50000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -500} +} + +monster.defenses = { + defense = 29, + armor = 20, + {name ="speed", interval = 2000, chance = 15, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_HEALING, minDamage = 200, maxDamage = 240, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/in_service_of_yalahar/tormented_ghost.lua b/data/monster/quests/in_service_of_yalahar/tormented_ghost.lua new file mode 100644 index 00000000000..bbf5e17ee37 --- /dev/null +++ b/data/monster/quests/in_service_of_yalahar/tormented_ghost.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Tormented Ghost") +local monster = {} + +monster.description = "a ghost" +monster.experience = 5 +monster.outfit = { + lookType = 48, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 210 +monster.maxHealth = 210 +monster.race = "undead" +monster.corpse = 9741 +monster.speed = 160 +monster.manaCost = 100 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Haaahhh", yell = false}, + {text = "Grrglll", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -280}, + {name ="combat", interval = 3000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -55, maxDamage = -105, range = 1, target = false} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/in_service_of_yalahar/yalahari.lua b/data/monster/quests/in_service_of_yalahar/yalahari.lua new file mode 100644 index 00000000000..119044fad0c --- /dev/null +++ b/data/monster/quests/in_service_of_yalahar/yalahari.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Yalahari") +local monster = {} + +monster.description = "a Yalahari" +monster.experience = 5 +monster.outfit = { + lookType = 309, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 150 +monster.maxHealth = 150 +monster.race = "blood" +monster.corpse = 20550 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Welcome to Yalahar, outsider.", yell = false}, + {text = "Hail Yalahar.", yell = false}, + {text = "You can learn a lot from us.", yell = false}, + {text = "Our wisdom and knowledge are unequalled in this world.", yell = false}, + {text = "That knowledge would overburden your fragile mind.", yell = false}, + {text = "I wouldn't expect you to understand.", yell = false}, + {text = "One day Yalahar will return to its former glory.", yell = false} +} + +monster.loot = { +} + +monster.defenses = { + defense = 0, + armor = 0 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/isle_of_evil/boogey.lua b/data/monster/quests/isle_of_evil/boogey.lua new file mode 100644 index 00000000000..838788e3229 --- /dev/null +++ b/data/monster/quests/isle_of_evil/boogey.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Boogey") +local monster = {} + +monster.description = "Boogey" +monster.experience = 475 +monster.outfit = { + lookType = 300, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 930 +monster.maxHealth = 930 +monster.race = "undead" +monster.corpse = 8955 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Demon Skeleton", chance = 40, interval = 4000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Since you didn't eat your spinach Bogey comes to get you!", yell = true}, + {text = "Too bad you did not eat your lunch, now I have to punish you!", yell = true}, + {text = "Even if you beat me, I'll hide in your closet until you one day drop your guard!", yell = true}, + {text = "You better had believe in me!", yell = true}, + {text = "I'll take you into the darkness ... forever!", yell = true} +} + +monster.loot = { + {id = 10296, chance = 1000}, + {id = 10302, chance = 1000}, + {id = 10301, chance = 1000}, + {id = 10295, chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 1200, chance = 100, minDamage = 0, maxDamage = -120}, + {name ="combat", interval = 1500, chance = 30, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -30, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 1500, chance = 30, type = COMBAT_DEATHDAMAGE, minDamage = -12, maxDamage = -20, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="combat", interval = 1500, chance = 40, type = COMBAT_PHYSICALDAMAGE, minDamage = -20, maxDamage = -30, effect = CONST_ME_MORTAREA, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 80, maxDamage = 120, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 25}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/isle_of_evil/dirtbeard.lua b/data/monster/quests/isle_of_evil/dirtbeard.lua new file mode 100644 index 00000000000..d5bdb3de1b6 --- /dev/null +++ b/data/monster/quests/isle_of_evil/dirtbeard.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("Dirtbeard") +local monster = {} + +monster.description = "Dirtbeard" +monster.experience = 375 +monster.outfit = { + lookType = 98, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 630 +monster.maxHealth = 630 +monster.race = "blood" +monster.corpse = 20478 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 50, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Pirate Marauder", chance = 30, interval = 4000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You are no match for the scourge of the seas!", yell = false}, + {text = "You move like a seasick whale!", yell = false}, + {text = "Yarr, death to all landlubbers!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 2000, maxCount = 95}, + {id = 2152, chance = 30000, maxCount = 9}, + {id = 10292, chance = 1000}, + {id = 10299, chance = 1000}, + {id = 10291, chance = 1000}, + {id = 10318, chance = 2000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -125}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -100, range = 7, shootEffect = CONST_ANI_THROWINGSTAR, target = false}, + {name ="melee", interval = 2000, chance = 30, minDamage = 0, maxDamage = 0}, + {name ="pirate corsair skill reducer", interval = 2000, chance = 5, target = false} +} + +monster.defenses = { + defense = 35, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/isle_of_evil/doctor_perhaps.lua b/data/monster/quests/isle_of_evil/doctor_perhaps.lua new file mode 100644 index 00000000000..7525f6d0b90 --- /dev/null +++ b/data/monster/quests/isle_of_evil/doctor_perhaps.lua @@ -0,0 +1,117 @@ +local mType = Game.createMonsterType("Doctor Perhaps") +local monster = {} + +monster.description = "doctor perhaps" +monster.experience = 325 +monster.outfit = { + lookType = 133, + lookHead = 95, + lookBody = 0, + lookLegs = 94, + lookFeet = 114, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 475 +monster.maxHealth = 475 +monster.race = "blood" +monster.corpse = 20439 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Zombie", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I might use some parts of you in my next creation!", yell = false}, + {text = "You're only a testsubject to me!", yell = false}, + {text = "My creations will kill you!", yell = false}, + {text = "You can't beat what you can't comprehend!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 2000, maxCount = 95}, + {id = 2152, chance = 30000, maxCount = 9}, + {id = 10316, chance = 1000}, + {id = 10289, chance = 1000}, + {id = 10290, chance = 1000}, + {id = 10300, chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -43}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DROWNDAMAGE, minDamage = -17, maxDamage = -55, range = 5, radius = 3, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_LOSEENERGY, target = true}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -20, maxDamage = -40, range = 7, shootEffect = CONST_ANI_POISON, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 10, maxDamage = 30, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/isle_of_evil/evil_mastermind.lua b/data/monster/quests/isle_of_evil/evil_mastermind.lua new file mode 100644 index 00000000000..746431065b3 --- /dev/null +++ b/data/monster/quests/isle_of_evil/evil_mastermind.lua @@ -0,0 +1,117 @@ +local mType = Game.createMonsterType("Evil Mastermind") +local monster = {} + +monster.description = "Evil Mastermind" +monster.experience = 675 +monster.outfit = { + lookType = 256, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1295 +monster.maxHealth = 1295 +monster.race = "undead" +monster.corpse = 7256 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 3, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "vampire", chance = 40, interval = 2000, max = 3} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You won't stop my masterplan to flood the world market with fake Bonelord language dictionaries!", yell = false}, + {text = "My calculations tell me you'll die!", yell = false}, + {text = "You can't stop me!", yell = false}, + {text = "Beware! My evil monolog is coming!", yell = false} +} + +monster.loot = { + {id = 10308, chance = 10000}, + {id = 2148, chance = 100000, maxCount = 95}, + {id = 2152, chance = 93000, maxCount = 3} +} + +monster.attacks = { + {name ="melee", interval = 1200, chance = 100, minDamage = 0, maxDamage = -77}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_PHYSICALDAMAGE, minDamage = -50, maxDamage = -78, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_FIREDAMAGE, minDamage = -66, maxDamage = -72, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_ENERGYDAMAGE, minDamage = -36, maxDamage = -57, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_LIFEDRAIN, minDamage = -70, maxDamage = -73, range = 7, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_MANADRAIN, minDamage = -59, maxDamage = -75, range = 7, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -600, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_HEALING, minDamage = 50, maxDamage = 110, effect = CONST_ME_ENERGYHIT, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = 90}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/isle_of_evil/mephiles.lua b/data/monster/quests/isle_of_evil/mephiles.lua new file mode 100644 index 00000000000..8757b4f236d --- /dev/null +++ b/data/monster/quests/isle_of_evil/mephiles.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Mephiles") +local monster = {} + +monster.description = "Mephiles" +monster.experience = 415 +monster.outfit = { + lookType = 237, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 415 +monster.maxHealth = 415 +monster.race = "blood" +monster.corpse = 6364 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 3, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I have a contract here which you should sign!", yell = false}, + {text = "I sence so much potential in you. It's almost a shame I have to kill you.", yell = false}, + {text = "Yes, slay me for the loot I might have. Give in to your greed.", yell = false}, + {text = "Wealth, Power, it is all at your fingertips. All you have to do is a bit blackmailing and bullying.", yell = false}, + {text = "Come on. being a bit evil won't hurt you.", yell = false} +} + +monster.loot = { + {id = 2148, chance = 2000, maxCount = 95}, + {id = 2152, chance = 30000, maxCount = 9}, + {id = 10293, chance = 1000}, + {id = 10304, chance = 1000}, + {id = 10317, chance = 1000}, + {id = 10294, chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 1200, chance = 100, minDamage = 0, maxDamage = -35}, + {name ="combat", interval = 1500, chance = 70, type = COMBAT_FIREDAMAGE, minDamage = -15, maxDamage = -45, range = 7, radius = 2, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true} +} + +monster.defenses = { + defense = 35, + armor = 30, + {name ="speed", interval = 1000, chance = 40, speedChange = 400, effect = CONST_ME_MAGIC_RED, target = false, duration = 40000}, + {name ="invisible", interval = 4000, chance = 50, effect = CONST_ME_MAGIC_RED} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/isle_of_evil/monstor.lua b/data/monster/quests/isle_of_evil/monstor.lua new file mode 100644 index 00000000000..d38e42b9e7d --- /dev/null +++ b/data/monster/quests/isle_of_evil/monstor.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("Monstor") +local monster = {} + +monster.description = "Monstor" +monster.experience = 575 +monster.outfit = { + lookType = 244, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 960 +monster.maxHealth = 960 +monster.race = "blood" +monster.corpse = 6336 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Acid Blob", chance = 40, interval = 4000, max = 3} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "NO ARMY ME STOPPING! GRARR!", yell = false}, + {text = "ME DESTROY CITY! GROAR!", yell = false}, + {text = "WHARR! MUST ... KIDNAP WOMEN!", yell = false} +} + +monster.loot = { + {id = 10298, chance = 1000}, + {id = 10303, chance = 1000}, + {id = 10297, chance = 1000}, + {id = 10313, chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 1200, chance = 100, minDamage = 0, maxDamage = -167}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_LIFEDRAIN, minDamage = -66, maxDamage = -85, length = 6, spread = 3, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_HEALING, minDamage = 90, maxDamage = 200, effect = CONST_ME_HITBYFIRE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = -7}, + {type = COMBAT_EARTHDAMAGE, percent = 30}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = -3}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/bretzecutioner.lua b/data/monster/quests/killing_in_the_name_of/bretzecutioner.lua new file mode 100644 index 00000000000..a4f1e8c4783 --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/bretzecutioner.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Bretzecutioner") +local monster = {} + +monster.description = "Bretzecutioner" +monster.experience = 3700 +monster.outfit = { + lookType = 236, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5600 +monster.maxHealth = 5600 +monster.race = "undead" +monster.corpse = 6320 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000}, + {id = 2148, chance = 100000, maxCount = 98}, + {id = 2666, chance = 100000}, + {id = 6500, chance = 64000}, + {id = 7368, chance = 100000, maxCount = 10}, + {id = 2489, chance = 68000}, + {id = 2150, chance = 28000, maxCount = 5}, + {id = 2146, chance = 40000, maxCount = 5}, + {id = 2145, chance = 32000, maxCount = 5}, + {id = 11215, chance = 100000}, + {id = 7452, chance = 32000}, + {id = 2152, chance = 100000, maxCount = 8}, + {id = 2393, chance = 24000}, + {id = 7591, chance = 44000, maxCount = 3}, + {id = 7590, chance = 44000, maxCount = 3}, + {id = 8472, chance = 44000, maxCount = 3}, + {id = 7632, chance = 48000}, + {id = 7633, chance = 48000}, + {id = 2645, chance = 4000}, + {id = 7427, chance = 24000}, + {id = 7419, chance = 12000}, + {id = 2125, chance = 24000}, + {id = 2521, chance = 16000}, + {id = 6300, chance = 100000}, + {id = 5741, chance = 4000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -514}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, range = 7, shootEffect = CONST_ANI_LARGEROCK, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="speed", interval = 2000, chance = 15, speedChange = 420, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 25}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -15}, + {type = COMBAT_HOLYDAMAGE , percent = -3}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/bruise_payne.lua b/data/monster/quests/killing_in_the_name_of/bruise_payne.lua new file mode 100644 index 00000000000..07c58b1cfd4 --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/bruise_payne.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("Bruise Payne") +local monster = {} + +monster.description = "Bruise Payne" +monster.experience = 1000 +monster.outfit = { + lookType = 307, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1600 +monster.maxHealth = 1600 +monster.race = "blood" +monster.corpse = 9829 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 5894, chance = 100000, maxCount = 2}, + {id = 2167, chance = 100000}, + {id = 2148, chance = 100000, maxCount = 99}, + {id = 10579, chance = 100000}, + {id = 2150, chance = 100000, maxCount = 5}, + {id = 2800, chance = 100000}, + {id = 2529, chance = 92000}, + {id = 2144, chance = 85000, maxCount = 5}, + {id = 7386, chance = 25000}, + {id = 10016, chance = 16000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -240, condition = {type = CONDITION_POISON, totalDamage = 6, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -70, maxDamage = -180, range = 7, shootEffect = CONST_ANI_POISON, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DROWNDAMAGE, minDamage = -130, maxDamage = -237, radius = 6, effect = CONST_ME_SOUND_WHITE, target = false}, + {name ="mutated bat curse", interval = 2000, chance = 10, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -12, maxDamage = -12, length = 4, spread = 3, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 80, maxDamage = 95, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/deathbine.lua b/data/monster/quests/killing_in_the_name_of/deathbine.lua new file mode 100644 index 00000000000..18ed8d7a8d7 --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/deathbine.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Deathbine") +local monster = {} + +monster.description = "Deathbine" +monster.experience = 340 +monster.outfit = { + lookType = 120, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 525 +monster.maxHealth = 525 +monster.race = "venom" +monster.corpse = 6047 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 11217, chance = 100000}, + {id = 2152, chance = 100000, maxCount = 5}, + {id = 2804, chance = 100000}, + {id = 2149, chance = 100000, maxCount = 4}, + {id = 2792, chance = 50000}, + {id = 7732, chance = 50000}, + {id = 7887, chance = 50000}, + {id = 7886, chance = 50000}, + {id = 8912, chance = 50000}, + {id = 5015, chance = 5555}, + {id = 13307, chance = 2854} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 30, attack = 100, condition = {type = CONDITION_POISON, totalDamage = 5, interval = 4000}}, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_EARTHDAMAGE, minDamage = -60, maxDamage = -90, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="speed", interval = 1000, chance = 34, speedChange = -850, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_HITBYPOISON, target = false, duration = 30000}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_EARTHDAMAGE, minDamage = -40, maxDamage = -130, radius = 3, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 10, + armor = 26 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 35}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/demodras.lua b/data/monster/quests/killing_in_the_name_of/demodras.lua new file mode 100644 index 00000000000..57791497539 --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/demodras.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("Demodras") +local monster = {} + +monster.description = "Demodras" +monster.experience = 6000 +monster.outfit = { + lookType = 204, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 4500 +monster.maxHealth = 4500 +monster.race = "blood" +monster.corpse = 5984 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Dragon", chance = 17, interval = 1000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I WILL SET THE WORLD ON FIRE!", yell = true}, + {text = "I WILL PROTECT MY BROOD!", yell = true} +} + +monster.loot = { + {id = 2672, chance = 20000, maxCount = 2}, + {id = 2033, chance = 1818}, + {id = 1976, chance = 3333}, + {id = 2492, chance = 333}, + {id = 2547, chance = 2222, maxCount = 10}, + {id = 2796, chance = 6666}, + {id = 2392, chance = 1428}, + {id = 2146, chance = 2222, maxCount = 2}, + {id = 5948, chance = 5000}, + {id = 5919, chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -160, maxDamage = -600}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -250, maxDamage = -350, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="firefield", interval = 1000, chance = 10, range = 7, radius = 6, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="combat", interval = 4000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -250, maxDamage = -550, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false} +} + +monster.defenses = { + defense = 25, + armor = 35, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_HEALING, minDamage = 400, maxDamage = 700, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/esmeralda.lua b/data/monster/quests/killing_in_the_name_of/esmeralda.lua new file mode 100644 index 00000000000..2cdb385ea76 --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/esmeralda.lua @@ -0,0 +1,118 @@ +local mType = Game.createMonsterType("Esmeralda") +local monster = {} + +monster.description = "Esmeralda" +monster.experience = 600 +monster.outfit = { + lookType = 305, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 800 +monster.maxHealth = 800 +monster.race = "blood" +monster.corpse = 9871 +monster.speed = 245 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Fcccccchhhhhh", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 170}, + {id = 10585, chance = 100000}, + {id = 2214, chance = 100000}, + {id = 2152, chance = 95000, maxCount = 4}, + {id = 2147, chance = 68000, maxCount = 3}, + {id = 2476, chance = 54000}, + {id = 2528, chance = 34000}, + {id = 2381, chance = 31050}, + {id = 2438, chance = 26000}, + {id = 7884, chance = 8200}, + {id = 2799, chance = 6500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -170, condition = {type = CONDITION_POISON, totalDamage = 5, interval = 4000}}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -110, range = 7, shootEffect = CONST_ANI_POISON, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 22, minDamage = -5, maxDamage = -5, length = 6, spread = 3, effect = CONST_ME_SMALLPLANTS, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -4, maxDamage = -4, radius = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -110, radius = 3, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 30, maxDamage = 50, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/ethershreck.lua b/data/monster/quests/killing_in_the_name_of/ethershreck.lua new file mode 100644 index 00000000000..5c1ce964574 --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/ethershreck.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Ethershreck") +local monster = {} + +monster.description = "Ethershreck" +monster.experience = 5600 +monster.outfit = { + lookType = 351, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 9500 +monster.maxHealth = 9500 +monster.race = "undead" +monster.corpse = 11362 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 366, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "EMBRACE MY GIFTS!", yell = true} +} + +monster.loot = { + {id = 11366, chance = 100000}, + {id = 2148, chance = 100000, maxCount = 230}, + {id = 2152, chance = 100000, maxCount = 15}, + {id = 11367, chance = 100000}, + {id = 6500, chance = 97000}, + {id = 7632, chance = 45000}, + {id = 7633, chance = 45000}, + {id = 9970, chance = 97000, maxCount = 10}, + {id = 11323, chance = 76000}, + {id = 8473, chance = 60000}, + {id = 11227, chance = 45000}, + {id = 11368, chance = 37000}, + {id = 7591, chance = 34000, maxCount = 3}, + {id = 11303, chance = 30000}, + {id = 7590, chance = 26000, maxCount = 3}, + {id = 8472, chance = 26000, maxCount = 3}, + {id = 11355, chance = 21000}, + {id = 11304, chance = 15000}, + {id = 11301, chance = 13000}, + {id = 11302, chance = 13000}, + {id = 11306, chance = 10000}, + {id = 11305, chance = 8700}, + {id = 13938, chance = 2170} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 80, attack = 100}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -80, maxDamage = -230, range = 7, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="ghastly dragon curse", interval = 2000, chance = 10, range = 7, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -920, maxDamage = -1260, range = 7, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -90, maxDamage = -350, range = 7, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_DEATHDAMAGE, minDamage = -70, maxDamage = -180, radius = 4, effect = CONST_ME_MORTAREA, target = false} +} + +monster.defenses = { + defense = 35, + armor = 45, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_HEALING, minDamage = 70, maxDamage = 300, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = -15}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/fazzrah.lua b/data/monster/quests/killing_in_the_name_of/fazzrah.lua new file mode 100644 index 00000000000..f236c36f421 --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/fazzrah.lua @@ -0,0 +1,114 @@ +local mType = Game.createMonsterType("Fazzrah") +local monster = {} + +monster.description = "Fazzrah" +monster.experience = 2600 +monster.outfit = { + lookType = 343, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2955 +monster.maxHealth = 2955 +monster.race = "blood" +monster.corpse = 11284 +monster.speed = 290 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 292}, + {id = 5876, chance = 100000}, + {id = 5881, chance = 100000}, + {id = 2152, chance = 100000, maxCount = 5}, + {id = 7588, chance = 100000}, + {id = 11330, chance = 100000}, + {id = 11331, chance = 100000}, + {id = 7591, chance = 75000, maxCount = 3}, + {id = 11303, chance = 75000}, + {id = 2149, chance = 71000, maxCount = 5}, + {id = 11206, chance = 25000}, + {id = 11304, chance = 6250}, + {id = 11301, chance = 3130} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -260}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_EARTHDAMAGE, minDamage = -220, maxDamage = -270, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_GREEN_RINGS, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 200, maxDamage = 280, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 1}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -1}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/flameborn.lua b/data/monster/quests/killing_in_the_name_of/flameborn.lua new file mode 100644 index 00000000000..419308521d6 --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/flameborn.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Flameborn") +local monster = {} + +monster.description = "Flameborn" +monster.experience = 2550 +monster.outfit = { + lookType = 322, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3500 +monster.maxHealth = 3500 +monster.race = "fire" +monster.corpse = 9923 +monster.speed = 260 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2152, chance = 100000}, + {id = 2152, chance = 100000, maxCount = 13}, + {id = 7591, chance = 75810}, + {id = 11221, chance = 100000}, + {id = 7368, chance = 19350, maxCount = 5}, + {id = 8473, chance = 77420}, + {id = 6500, chance = 35480}, + {id = 2788, chance = 67740, maxCount = 2}, + {id = 9970, chance = 43550, maxCount = 4}, + {id = 2477, chance = 67740}, + {id = 2475, chance = 20970}, + {id = 7452, chance = 6450}, + {id = 7439, chance = 37100}, + {id = 9969, chance = 20970}, + {id = 9948, chance = 1610}, + {id = 7421, chance = 3230}, + {id = 13298, chance = 4840}, + {id = 2519, chance = 29030} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -350}, + {name ="fireball", interval = 2000, chance = 20, minDamage = -150, maxDamage = -175, target = false}, + {name ="hellspawn soulfire", interval = 2000, chance = 10, range = 5, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 120, maxDamage = 230, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 270, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 40}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/fleshcrawler.lua b/data/monster/quests/killing_in_the_name_of/fleshcrawler.lua new file mode 100644 index 00000000000..f55dec24f9a --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/fleshcrawler.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Fleshcrawler") +local monster = {} + +monster.description = "Fleshcrawler" +monster.experience = 1000 +monster.outfit = { + lookType = 79, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1450 +monster.maxHealth = 1450 +monster.race = "venom" +monster.corpse = 6021 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Larva", chance = 10, interval = 2000, max = 3} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2152, chance = 98890, maxCount = 15}, + {id = 2159, chance = 98890, maxCount = 2}, + {id = 2149, chance = 88890, maxCount = 3}, + {id = 2150, chance = 87220, maxCount = 4}, + {id = 10548, chance = 100000}, + {id = 2142, chance = 45560}, + {id = 2135, chance = 52220}, + {id = 7884, chance = 11110}, + {id = 7588, chance = 43330}, + {id = 8912, chance = 75560}, + {id = 2540, chance = 43890}, + {id = 7426, chance = 30560}, + {id = 12424, chance = 14440} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -330}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -150, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -700, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false, duration = 25000}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 30, minDamage = 0, maxDamage = -520, radius = 5, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/gorgo.lua b/data/monster/quests/killing_in_the_name_of/gorgo.lua new file mode 100644 index 00000000000..5f322d1985b --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/gorgo.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("Gorgo") +local monster = {} + +monster.description = "Gorgo" +monster.experience = 7000 +monster.outfit = { + lookType = 330, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 4500 +monster.maxHealth = 4500 +monster.race = "blood" +monster.corpse = 10524 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 600, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2536, chance = 100000}, + {id = 2152, chance = 100000, maxCount = 20}, + {id = 11226, chance = 100000}, + {id = 7590, chance = 87000, maxCount = 2}, + {id = 10219, chance = 60000}, + {id = 8473, chance = 60000, maxCount = 2}, + {id = 2149, chance = 46470, maxCount = 4}, + {id = 7887, chance = 46470}, + {id = 7884, chance = 46470}, + {id = 7885, chance = 33300}, + {id = 7413, chance = 33300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450, condition = {type = CONDITION_POISON, totalDamage = 42, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -21, maxDamage = -350, range = 7, shootEffect = CONST_ANI_EARTH, effect = CONST_ME_CARNIPHILA, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -250, maxDamage = -500, length = 8, spread = 3, effect = CONST_ME_CARNIPHILA, target = false}, + {name ="speed", interval = 2000, chance = 25, radius = 7, effect = CONST_ME_POFF, target = true}, + {name ="outfit", interval = 2000, chance = 1, range = 7, target = true, duration = 3000, outfitMonster = "clay guardian"} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 150, maxDamage = 300, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/hemming.lua b/data/monster/quests/killing_in_the_name_of/hemming.lua new file mode 100644 index 00000000000..2eda5601bf9 --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/hemming.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Hemming") +local monster = {} + +monster.description = "Hemming" +monster.experience = 2850 +monster.outfit = { + lookType = 308, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3000 +monster.maxHealth = 3000 +monster.race = "blood" +monster.corpse = 20570 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "War Wolf", chance = 100, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "GRRR", yell = false}, + {text = "GRROARR", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 99}, + {id = 11234, chance = 100000}, + {id = 5897, chance = 100000}, + {id = 8473, chance = 98000}, + {id = 2789, chance = 94000, maxCount = 5}, + {id = 2152, chance = 94000, maxCount = 10}, + {id = 7439, chance = 82000}, + {id = 2197, chance = 70000}, + {id = 2144, chance = 62000, maxCount = 5}, + {id = 5480, chance = 31000}, + {id = 2805, chance = 21000}, + {id = 11306, chance = 15000}, + {id = 7419, chance = 9800}, + {id = 2169, chance = 6000}, + {id = 7428, chance = 2000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -180, maxDamage = -265, radius = 3, effect = CONST_ME_SOUND_RED, target = false}, + {name ="outfit", interval = 2000, chance = 5, effect = CONST_ME_SOUND_BLUE, target = false, duration = 2000, outfitMonster = "Werewolf"}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_PHYSICALDAMAGE, radius = 3, effect = CONST_ME_SOUND_WHITE, target = false}, + {name ="werewolf skill reducer", interval = 2000, chance = 15, range = 1, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 50, maxDamage = 200, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 300, range = 7, effect = CONST_ME_SOUND_PURPLE, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 65}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/hide.lua b/data/monster/quests/killing_in_the_name_of/hide.lua new file mode 100644 index 00000000000..81e3621b18f --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/hide.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Hide") +local monster = {} + +monster.description = "Hide" +monster.experience = 240 +monster.outfit = { + lookType = 219, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 500 +monster.maxHealth = 500 +monster.race = "venom" +monster.corpse = 6060 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2152, chance = 100000, maxCount = 5}, + {id = 2457, chance = 50000}, + {id = 5879, chance = 50000}, + {id = 7903, chance = 50000}, + {id = 2477, chance = 50000}, + {id = 2169, chance = 33333} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 60, attack = 40, condition = {type = CONDITION_POISON, totalDamage = 80, interval = 4000}} +} + +monster.defenses = { + defense = 40, + armor = 25, + {name ="speed", interval = 2000, chance = 10, speedChange = 340, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 40}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/kerberos.lua b/data/monster/quests/killing_in_the_name_of/kerberos.lua new file mode 100644 index 00000000000..695bf0b3fca --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/kerberos.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("Kerberos") +local monster = {} + +monster.description = "Kerberos" +monster.experience = 10000 +monster.outfit = { + lookType = 240, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 11000 +monster.maxHealth = 11000 +monster.race = "blood" +monster.corpse = 6332 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2152, chance = 100000, maxCount = 18}, + {id = 2144, chance = 96880, maxCount = 5}, + {id = 6558, chance = 100000}, + {id = 6500, chance = 62500}, + {id = 9971, chance = 100000, maxCount = 5}, + {id = 2430, chance = 10810}, + {id = 6553, chance = 6250}, + {id = 10554, chance = 100000}, + {id = 2155, chance = 50000}, + {id = 2392, chance = 46880}, + {id = 4873, chance = 65630}, + {id = 7890, chance = 96880}, + {id = 7590, chance = 96880, maxCount = 3}, + {id = 7453, chance = 3130}, + {id = 2466, chance = 31250} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -508}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -700, length = 8, spread = 3, effect = CONST_ME_CARNIPHILA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -498, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = 0, maxDamage = -662, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -976, length = 8, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -549, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/leviathan.lua b/data/monster/quests/killing_in_the_name_of/leviathan.lua new file mode 100644 index 00000000000..5ee9ba17f6b --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/leviathan.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("Leviathan") +local monster = {} + +monster.description = "Leviathan" +monster.experience = 5000 +monster.outfit = { + lookType = 275, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 6000 +monster.maxHealth = 6000 +monster.race = "blood" +monster.corpse = 8307 +monster.speed = 758 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 50 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 600, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "CHHHRRRR", yell = false}, + {text = "HISSSS", yell = false} +} + +monster.loot = { + {id = 10220, chance = 100000}, + {id = 10529, chance = 100000}, + {id = 9809, chance = 83000}, + {id = 2152, chance = 82000, maxCount = 7}, + {id = 9812, chance = 77000}, + {id = 7428, chance = 58000}, + {id = 2146, chance = 50000, maxCount = 5}, + {id = 7589, chance = 50000}, + {id = 10521, chance = 14000}, + {id = 8887, chance = 1500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -500}, + {name ="combat", interval = 1000, chance = 8, type = COMBAT_EARTHDAMAGE, minDamage = -130, maxDamage = -460, length = 9, spread = 3, effect = CONST_ME_BIGPLANTS, target = false}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -365, maxDamage = -491, length = 9, spread = 3, effect = CONST_ME_ICEAREA, target = false}, + {name ="combat", interval = 1000, chance = 11, type = COMBAT_DROWNDAMAGE, minDamage = -15, maxDamage = -20, radius = 4, effect = CONST_ME_LOSEENERGY, target = true} +} + +monster.defenses = { + defense = 30, + armor = 20, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 50, maxDamage = 350, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -15}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/paiz_the_pauperizer.lua b/data/monster/quests/killing_in_the_name_of/paiz_the_pauperizer.lua new file mode 100644 index 00000000000..16904153032 --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/paiz_the_pauperizer.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Paiz The Pauperizer") +local monster = {} + +monster.description = "Paiz The Pauperizer" +monster.experience = 6300 +monster.outfit = { + lookType = 362, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 8500 +monster.maxHealth = 8500 +monster.race = "blood" +monster.corpse = 12609 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "For ze emperor!", yell = false}, + {text = "You will die zhouzandz deazhz!", yell = false} +} + +monster.loot = { + {id = 12616, chance = 100000}, + {id = 12617, chance = 100000}, + {id = 12614, chance = 100000}, + {id = 12615, chance = 100000}, + {id = 2148, chance = 100000, maxCount = 99}, + {id = 5881, chance = 100000}, + {id = 2666, chance = 100000, maxCount = 5}, + {id = 2152, chance = 100000, maxCount = 10}, + {id = 5904, chance = 43000}, + {id = 7591, chance = 36960, maxCount = 3}, + {id = 2154, chance = 36960}, + {id = 8472, chance = 32610, maxCount = 3}, + {id = 7590, chance = 30430, maxCount = 3}, + {id = 2156, chance = 23910}, + {id = 11306, chance = 23910}, + {id = 2155, chance = 21740}, + {id = 11307, chance = 19570}, + {id = 11301, chance = 15220}, + {id = 2492, chance = 13040}, + {id = 8880, chance = 10870}, + {id = 12613, chance = 10870}, + {id = 2158, chance = 8700}, + {id = 12607, chance = 8700}, + {id = 2149, chance = 8700, maxCount = 8}, + {id = 13294, chance = 4350} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -240, maxDamage = -550, length = 5, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -350, range = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_EARTHDAMAGE, minDamage = -280, maxDamage = -450, range = 4, radius = 4, shootEffect = CONST_ANI_EARTH, effect = CONST_ME_POFF, target = true}, + {name ="soulfire", interval = 2000, chance = 10, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 11, minDamage = -20, maxDamage = -20, range = 7, shootEffect = CONST_ANI_POISON, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 230, maxDamage = 330, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 40}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/ribstride.lua b/data/monster/quests/killing_in_the_name_of/ribstride.lua new file mode 100644 index 00000000000..d3413c13a52 --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/ribstride.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Ribstride") +local monster = {} + +monster.description = "Ribstride" +monster.experience = 1100 +monster.outfit = { + lookType = 101, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "undead" +monster.corpse = 6030 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 11194, chance = 100000}, + {id = 5925, chance = 98910, maxCount = 3}, + {id = 2152, chance = 98910, maxCount = 8}, + {id = 2145, chance = 61960, maxCount = 4}, + {id = 2541, chance = 60000}, + {id = 2796, chance = 60000, maxCount = 4}, + {id = 11161, chance = 29000}, + {id = 5741, chance = 8700}, + {id = 13291, chance = 2000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200, condition = {type = CONDITION_POISON, totalDamage = 5, interval = 4000}}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -25, maxDamage = -47, radius = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -50, maxDamage = -90, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -50, maxDamage = -60, radius = 3, effect = CONST_ME_POISONAREA, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -70, maxDamage = -80, length = 6, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -300, target = true, duration = 13000} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 30, maxDamage = 50, effect = CONST_ME_HITBYPOISON, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -20}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/shardhead.lua b/data/monster/quests/killing_in_the_name_of/shardhead.lua new file mode 100644 index 00000000000..e5c77f2ebe7 --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/shardhead.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Shardhead") +local monster = {} + +monster.description = "Shardhead" +monster.experience = 650 +monster.outfit = { + lookType = 261, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 800 +monster.maxHealth = 800 +monster.race = "undead" +monster.corpse = 7282 +monster.speed = 195 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 50, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 99700, maxCount = 87}, + {id = 7290, chance = 40000}, + {id = 7588, chance = 100000}, + {id = 10578, chance = 40000}, + {id = 7441, chance = 80000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 100, attack = 50}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = 0, maxDamage = -90, range = 7, shootEffect = CONST_ANI_ICE, effect = CONST_ME_ICEATTACK, target = true}, + {name ="speed", interval = 2000, chance = 12, speedChange = -360, length = 8, spread = 3, effect = CONST_ME_ICEAREA, target = false, duration = 5000} +} + +monster.defenses = { + defense = 26, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 25}, + {type = COMBAT_ENERGYDAMAGE, percent = -20}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/stonecracker.lua b/data/monster/quests/killing_in_the_name_of/stonecracker.lua new file mode 100644 index 00000000000..42b628a5e29 --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/stonecracker.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("Stonecracker") +local monster = {} + +monster.description = "Stonecracker" +monster.experience = 3500 +monster.outfit = { + lookType = 55, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 6500 +monster.maxHealth = 6500 +monster.race = "blood" +monster.corpse = 5999 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "HUAHAHA!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 76225, maxCount = 100}, + {id = 5893, chance = 64800}, + {id = 2666, chance = 36200}, + {id = 5930, chance = 50500}, + {id = 7368, chance = 11225, maxCount = 2}, + {id = 2489, chance = 7650}, + {id = 2416, chance = 14800}, + {id = 2150, chance = 7650, maxCount = 2}, + {id = 2387, chance = 7650} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 100}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -280, range = 7, shootEffect = CONST_ANI_LARGEROCK, target = false} +} + +monster.defenses = { + defense = 45, + armor = 40, + {name ="speed", interval = 2000, chance = 10, speedChange = 360, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 500, maxDamage = 600, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 15}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 85}, + {type = COMBAT_FIREDAMAGE, percent = 40}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 35}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/sulphur_scuttler.lua b/data/monster/quests/killing_in_the_name_of/sulphur_scuttler.lua new file mode 100644 index 00000000000..1c2aa0497b6 --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/sulphur_scuttler.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("Sulphur Scuttler") +local monster = {} + +monster.description = "Sulphur Scuttler" +monster.experience = 900 +monster.outfit = { + lookType = 352, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1300 +monster.maxHealth = 1300 +monster.race = "venom" +monster.corpse = 12527 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2152, chance = 98330, maxCount = 10}, + {id = 10557, chance = 50000}, + {id = 11222, chance = 75000}, + {id = 11232, chance = 96670}, + {id = 12659, chance = 100000}, + {id = 7589, chance = 71670}, + {id = 7588, chance = 75000}, + {id = 12658, chance = 100000}, + {id = 2149, chance = 65000, maxCount = 4}, + {id = 5904, chance = 81670}, + {id = 2165, chance = 46670}, + {id = 2171, chance = 20000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="speed", interval = 2000, chance = 20, speedChange = -600, range = 7, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_MORTAREA, target = false, duration = 10000}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -394, radius = 6, effect = CONST_ME_SMALLPLANTS, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -200, length = 6, spread = 3, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -120, length = 8, spread = 3, effect = CONST_ME_YELLOW_RINGS, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/the_bloodtusk.lua b/data/monster/quests/killing_in_the_name_of/the_bloodtusk.lua new file mode 100644 index 00000000000..9d3e604e38b --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/the_bloodtusk.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("The Bloodtusk") +local monster = {} + +monster.description = "the Bloodtusk" +monster.experience = 300 +monster.outfit = { + lookType = 199, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 600 +monster.maxHealth = 600 +monster.race = "blood" +monster.corpse = 6074 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 99}, + {id = 11238, chance = 100000, maxCount = 2}, + {id = 2152, chance = 100000, maxCount = 5}, + {id = 7432, chance = 63000}, + {id = 5911, chance = 60000}, + {id = 3973, chance = 55000}, + {id = 3956, chance = 41000, maxCount = 4}, + {id = 7463, chance = 18000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -120} +} + +monster.defenses = { + defense = 57, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 15}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/the_bloodweb.lua b/data/monster/quests/killing_in_the_name_of/the_bloodweb.lua new file mode 100644 index 00000000000..29bbe39734b --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/the_bloodweb.lua @@ -0,0 +1,114 @@ +local mType = Game.createMonsterType("The Bloodweb") +local monster = {} + +monster.description = "the Bloodweb" +monster.experience = 1450 +monster.outfit = { + lookType = 263, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1750 +monster.maxHealth = 1750 +monster.race = "undead" +monster.corpse = 7344 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 20000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 60, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Screeech!", yell = false} +} + +monster.loot = { + {id = 7589, chance = 100000}, + {id = 5879, chance = 50000}, + {id = 7902, chance = 33333}, + {id = 7896, chance = 33333}, + {id = 11306, chance = 20000}, + {id = 7437, chance = 20000}, + {id = 5801, chance = 7692}, + {id = 2476, chance = 7692}, + {id = 2477, chance = 5555}, + {id = 7290, chance = 3703}, + {id = 2169, chance = 3703} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 40, attack = 100, condition = {type = CONDITION_POISON, totalDamage = 8, interval = 4000}}, + {name ="speed", interval = 2000, chance = 20, speedChange = -850, range = 7, radius = 7, effect = CONST_ME_POFF, target = false, duration = 8000}, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -60, maxDamage = -150, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true} +} + +monster.defenses = { + defense = 20, + armor = 25, + {name ="speed", interval = 3000, chance = 40, speedChange = 380, effect = CONST_ME_MAGIC_RED, target = false, duration = 80000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -20}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/the_many.lua b/data/monster/quests/killing_in_the_name_of/the_many.lua new file mode 100644 index 00000000000..f9d99d1ae06 --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/the_many.lua @@ -0,0 +1,114 @@ +local mType = Game.createMonsterType("The Many") +local monster = {} + +monster.description = "The Many" +monster.experience = 4000 +monster.outfit = { + lookType = 121, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5000 +monster.maxHealth = 5000 +monster.race = "blood" +monster.corpse = 6048 +monster.speed = 260 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2197, chance = 90000}, + {id = 7589, chance = 83000, maxCount = 5}, + {id = 10219, chance = 80000}, + {id = 2475, chance = 79000}, + {id = 2146, chance = 77000, maxCount = 5}, + {id = 9971, chance = 60000, maxCount = 3}, + {id = 2536, chance = 53000}, + {id = 10523, chance = 37000}, + {id = 2498, chance = 20000}, + {id = 2476, chance = 10000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -270}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -65, maxDamage = -320, length = 8, spread = 3, effect = CONST_ME_CARNIPHILA, target = false}, + {name ="speed", interval = 2000, chance = 25, speedChange = -300, range = 7, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_GREEN_RINGS, target = true, duration = 15000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -100, maxDamage = -250, length = 8, spread = 3, effect = CONST_ME_LOSEENERGY, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -70, maxDamage = -155, range = 7, shootEffect = CONST_ANI_ICE, effect = CONST_ME_ICEATTACK, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 260, maxDamage = 407, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/the_noxious_spawn.lua b/data/monster/quests/killing_in_the_name_of/the_noxious_spawn.lua new file mode 100644 index 00000000000..3f637990d4c --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/the_noxious_spawn.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("The Noxious Spawn") +local monster = {} + +monster.description = "The Noxious Spawn" +monster.experience = 6000 +monster.outfit = { + lookType = 220, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 9500 +monster.maxHealth = 9500 +monster.race = "venom" +monster.corpse = 4323 +monster.speed = 360 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 275, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I bring you deathhhh, mortalssss", yell = false} +} + +monster.loot = { + {id = 10611, chance = 100000}, + {id = 11230, chance = 100000}, + {id = 2152, chance = 80000, maxCount = 5}, + {id = 7590, chance = 72000, maxCount = 4}, + {id = 2149, chance = 68000, maxCount = 5}, + {id = 7386, chance = 45000}, + {id = 2528, chance = 43000}, + {id = 7456, chance = 39000}, + {id = 2033, chance = 35000}, + {id = 2487, chance = 29000}, + {id = 7368, chance = 27000, maxCount = 78}, + {id = 2796, chance = 19000}, + {id = 2168, chance = 13000}, + {id = 8902, chance = 13000}, + {id = 2498, chance = 4000}, + {id = 8880, chance = 2000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250}, + {name ="speed", interval = 4000, chance = 20, speedChange = -370, range = 7, shootEffect = CONST_ANI_POISON, target = true, duration = 12000}, + {name ="combat", interval = 2000, chance = 7, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -550, length = 8, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -550, length = 8, spread = 3, effect = CONST_ME_SOUND_RED, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -300, range = 1, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false}, + {name ="outfit", interval = 2000, chance = 11, range = 7, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 4000, outfitItem = 3976} +} + +monster.defenses = { + defense = 25, + armor = 18, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 900, maxDamage = 1000, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/the_old_widow.lua b/data/monster/quests/killing_in_the_name_of/the_old_widow.lua new file mode 100644 index 00000000000..2ff3381bd79 --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/the_old_widow.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("The Old Widow") +local monster = {} + +monster.description = "The Old Widow" +monster.experience = 4200 +monster.outfit = { + lookType = 208, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3200 +monster.maxHealth = 3200 +monster.race = "blood" +monster.corpse = 5977 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 20, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "giant spider", chance = 13, interval = 1000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 99}, + {id = 2152, chance = 100000, maxCount = 10}, + {id = 5879, chance = 100000}, + {id = 2457, chance = 100000}, + {id = 7591, chance = 100000, maxCount = 4}, + {id = 2476, chance = 50000}, + {id = 2165, chance = 33333}, + {id = 2167, chance = 33333}, + {id = 2169, chance = 33333}, + {id = 13307, chance = 33333}, + {id = 2477, chance = 25000}, + {id = 2171, chance = 25000}, + {id = 5886, chance = 25000}, + {id = 7416, chance = 3225}, + {id = 7419, chance = 1639} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -500}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -250, maxDamage = -300, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false}, + {name ="speed", interval = 1000, chance = 20, speedChange = -850, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false, duration = 25000}, + {name ="poisonfield", interval = 1000, chance = 10, range = 7, radius = 4, shootEffect = CONST_ANI_POISON, target = true} +} + +monster.defenses = { + defense = 21, + armor = 17, + {name ="combat", interval = 1000, chance = 17, type = COMBAT_HEALING, minDamage = 225, maxDamage = 275, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 1000, chance = 8, speedChange = 345, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/the_snapper.lua b/data/monster/quests/killing_in_the_name_of/the_snapper.lua new file mode 100644 index 00000000000..d5064a6608a --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/the_snapper.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("The Snapper") +local monster = {} + +monster.description = "The Snapper" +monster.experience = 150 +monster.outfit = { + lookType = 119, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 300 +monster.maxHealth = 300 +monster.race = "blood" +monster.corpse = 6046 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 30, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 178}, + {id = 7618, chance = 80000, maxCount = 5}, + {id = 2149, chance = 75000, maxCount = 4}, + {id = 2647, chance = 44000}, + {id = 2463, chance = 39800}, + {id = 3982, chance = 6000}, + {id = 2476, chance = 400} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -60} +} + +monster.defenses = { + defense = 5, + armor = 13 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 15}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/thul.lua b/data/monster/quests/killing_in_the_name_of/thul.lua new file mode 100644 index 00000000000..84c926c6ec6 --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/thul.lua @@ -0,0 +1,118 @@ +local mType = Game.createMonsterType("Thul") +local monster = {} + +monster.description = "Thul" +monster.experience = 2700 +monster.outfit = { + lookType = 46, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2950 +monster.maxHealth = 2950 +monster.race = "blood" +monster.corpse = 6065 +monster.speed = 520 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 40, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Massive Water Elemental", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Gaaahhh!", yell = false}, + {text = "Boohaa!", yell = false} +} + +monster.loot = { + {id = 5895, chance = 100000}, + {id = 2152, chance = 88000, maxCount = 10}, + {id = 7963, chance = 67000}, + {id = 7590, chance = 46000}, + {id = 2150, chance = 38000, maxCount = 4}, + {id = 7383, chance = 35000}, + {id = 2497, chance = 16000}, + {id = 2487, chance = 10000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -285}, + {name ="combat", interval = 2000, chance = 7, type = COMBAT_ICEDAMAGE, minDamage = -108, maxDamage = -137, radius = 4, effect = CONST_ME_ICEAREA, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -170, radius = 3, effect = CONST_ME_HITAREA, target = false}, + {name ="poisonfield", interval = 2000, chance = 19, radius = 3, shootEffect = CONST_ANI_POISON, target = false}, + {name ="speed", interval = 2000, chance = 18, speedChange = -360, range = 7, shootEffect = CONST_ANI_SNOWBALL, target = false, duration = 5000} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 25, maxDamage = 75, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -15}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/tiquandas_revenge.lua b/data/monster/quests/killing_in_the_name_of/tiquandas_revenge.lua new file mode 100644 index 00000000000..824ee47af08 --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/tiquandas_revenge.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Tiquandas Revenge") +local monster = {} + +monster.description = "Tiquandas Revenge" +monster.experience = 2635 +monster.outfit = { + lookType = 120, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1800 +monster.maxHealth = 1800 +monster.race = "venom" +monster.corpse = 6047 +monster.speed = 440 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 400, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 10}, + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2666, chance = 33333, maxCount = 50}, + {id = 2671, chance = 20000, maxCount = 8}, + {id = 2145, chance = 33333, maxCount = 3}, + {id = 7732, chance = 4000}, + {id = 5015, chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 70, attack = 40, condition = {type = CONDITION_POISON, totalDamage = 95, interval = 4000}}, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_EARTHDAMAGE, minDamage = -60, maxDamage = -200, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="speed", interval = 1000, chance = 34, speedChange = -850, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_HITBYPOISON, target = false, duration = 30000}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_EARTHDAMAGE, minDamage = -40, maxDamage = -130, radius = 3, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 31, + armor = 30, + {name ="ultimate healing", interval = 1200, chance = 35, minDamage = 600, maxDamage = 800, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/tormentor.lua b/data/monster/quests/killing_in_the_name_of/tormentor.lua new file mode 100644 index 00000000000..4c087978f0a --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/tormentor.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Tormentor") +local monster = {} + +monster.description = "Tormentor" +monster.experience = 3200 +monster.outfit = { + lookType = 245, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 4100 +monster.maxHealth = 4100 +monster.race = "blood" +monster.corpse = 6340 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Take a ride with me.", yell = false}, + {text = "Pffffrrrrrrrrrrrr.", yell = false}, + {text = "Close your eyes... I have something for you.", yell = false}, + {text = "I will make you scream.", yell = false} +} + +monster.loot = { + {id = 6558, chance = 100000}, + {id = 6300, chance = 100000}, + {id = 6500, chance = 100000}, + {id = 11223, chance = 100000}, + {id = 2671, chance = 100000, maxCount = 2}, + {id = 2152, chance = 90000, maxCount = 10}, + {id = 11229, chance = 81000}, + {id = 2477, chance = 70000}, + {id = 5669, chance = 40000}, + {id = 6526, chance = 28000}, + {id = 2454, chance = 14000}, + {id = 7418, chance = 10000}, + {id = 2195, chance = 8000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -340}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -130, maxDamage = -170, range = 7, radius = 1, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -250, maxDamage = -400, range = 7, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 60, maxDamage = 100, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 420, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/tromphonyte.lua b/data/monster/quests/killing_in_the_name_of/tromphonyte.lua new file mode 100644 index 00000000000..2cd171b0b44 --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/tromphonyte.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("Tromphonyte") +local monster = {} + +monster.description = "Tromphonyte" +monster.experience = 1300 +monster.outfit = { + lookType = 381, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3000 +monster.maxHealth = 3000 +monster.race = "blood" +monster.corpse = 13312 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 13301, chance = 100000}, + {id = 2476, chance = 100000}, + {id = 2152, chance = 100000, maxCount = 13}, + {id = 9970, chance = 100000, maxCount = 5}, + {id = 13299, chance = 100000}, + {id = 13300, chance = 100000, maxCount = 2}, + {id = 7588, chance = 100000, maxCount = 2}, + {id = 7589, chance = 100000, maxCount = 2}, + {id = 7452, chance = 50000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -215}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -170, maxDamage = -300, radius = 3, effect = CONST_ME_GROUNDSHAKER, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -90, maxDamage = -130, shootEffect = CONST_ANI_SMALLSTONE, target = true}, + {name ="stampor skill reducer", interval = 2000, chance = 10, range = 5, target = false} +} + +monster.defenses = { + defense = 0, + armor = 0, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 90, maxDamage = 120, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/killing_in_the_name_of/zanakeph.lua b/data/monster/quests/killing_in_the_name_of/zanakeph.lua new file mode 100644 index 00000000000..33541598456 --- /dev/null +++ b/data/monster/quests/killing_in_the_name_of/zanakeph.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Zanakeph") +local monster = {} + +monster.description = "Zanakeph" +monster.experience = 9900 +monster.outfit = { + lookType = 231, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 13000 +monster.maxHealth = 13000 +monster.race = "undead" +monster.corpse = 6306 +monster.speed = 330 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 6 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 700, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "FEEEED MY ETERNAL HUNGER!", yell = true}, + {text = "I SENSE LIFE", yell = true} +} + +monster.loot = { + {id = 6300, chance = 100000}, + {id = 7430, chance = 100000}, + {id = 2148, chance = 100000, maxCount = 100}, + {id = 2033, chance = 100000}, + {id = 2152, chance = 100000, maxCount = 10}, + {id = 11233, chance = 100000, maxCount = 3}, + {id = 9971, chance = 78000}, + {id = 6500, chance = 56000}, + {id = 2476, chance = 47270}, + {id = 2491, chance = 40000}, + {id = 8472, chance = 37000, maxCount = 3}, + {id = 5925, chance = 37000, maxCount = 5}, + {id = 11368, chance = 37000}, + {id = 7591, chance = 35000, maxCount = 4}, + {id = 9810, chance = 35000}, + {id = 2149, chance = 33000, maxCount = 5}, + {id = 2146, chance = 33000, maxCount = 5}, + {id = 7590, chance = 25000, maxCount = 3}, + {id = 2466, chance = 13500}, + {id = 13291, chance = 6780}, + {id = 5741, chance = 5000}, + {id = 8885, chance = 3390}, + {id = 2498, chance = 1690} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 96}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_PHYSICALDAMAGE, minDamage = -300, maxDamage = -400, range = 7, radius = 4, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -125, maxDamage = -600, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_EARTHDAMAGE, minDamage = -100, maxDamage = -390, range = 7, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -150, maxDamage = -690, length = 8, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -300, maxDamage = -700, length = 8, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -100, maxDamage = -200, radius = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="undead dragon curse", interval = 2000, chance = 10, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/kilmaresh/a_shielded_astral_glyph.lua b/data/monster/quests/kilmaresh/a_shielded_astral_glyph.lua new file mode 100644 index 00000000000..507074be205 --- /dev/null +++ b/data/monster/quests/kilmaresh/a_shielded_astral_glyph.lua @@ -0,0 +1,95 @@ +local mType = Game.createMonsterType("A Shielded Astral Glyph") +local monster = {} + +monster.description = "a shielded astral glyph" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 26894 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 470 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 100}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -400, radius = 3, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_MANADRAIN, minDamage = -200, maxDamage = -400, radius = 5, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.defenses = { + defense = 199, + armor = 199 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/kilmaresh/an_astral_glyph.lua b/data/monster/quests/kilmaresh/an_astral_glyph.lua new file mode 100644 index 00000000000..9e211e1492b --- /dev/null +++ b/data/monster/quests/kilmaresh/an_astral_glyph.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("An Astral Glyph") +local monster = {} + +monster.description = "an astral glyph" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 26893 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 470 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "AstralGlyphDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 100}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -400, radius = 3, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_MANADRAIN, minDamage = -200, maxDamage = -400, radius = 5, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.defenses = { + defense = 50, + armor = 50 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/kilmaresh/bragrumol.lua b/data/monster/quests/kilmaresh/bragrumol.lua new file mode 100644 index 00000000000..03a29c24f7c --- /dev/null +++ b/data/monster/quests/kilmaresh/bragrumol.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Bragrumol") +local monster = {} + +monster.description = "Bragrumol" +monster.experience = 18000 +monster.outfit = { + lookType = 856, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 38000 +monster.maxHealth = 38000 +monster.race = "fire" +monster.corpse = 13973 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 100000, maxCount = 8}, + {name = "Flaming Arrow", chance = 60000, maxCount = 15}, + {name = "Red Gem", chance = 45000, maxCount = 15}, + {name = "Sea Horse Figurine", chance = 6700}, + {id = 36392, chance = 520}, + {id = 36204, chance = 16500}, + {name = "Winged Boots", chance = 110}, + {id = 35238, chance = 250}, + {name = "Magma Coat", chance = 48000}, + {name = "Stone Skin Amulet", chance = 54000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -600}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_DEATHDAMAGE, minDamage = -300, maxDamage = -600, range = 5, shootEffect = CONST_ANI_SUDDENDEATH, target = false}, + {name ="combat", interval = 2000, chance = 22, type = COMBAT_DEATHDAMAGE, minDamage = -300, maxDamage = -600, range = 5, radius = 4, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -300, maxDamage = -600, range = 5, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_DEATHDAMAGE, minDamage = -300, maxDamage = -600, range = 5, length = 5, spread = 3, effect = CONST_ME_WHITE_ENERGY_SPARK, target = true} +} + +monster.defenses = { + defense = 84, + armor = 84 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/kilmaresh/earworm.lua b/data/monster/quests/kilmaresh/earworm.lua new file mode 100644 index 00000000000..74fe56e1252 --- /dev/null +++ b/data/monster/quests/kilmaresh/earworm.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("Earworm") +local monster = {} + +monster.description = "an earworm" +monster.experience = 2000 +monster.outfit = { + lookType = 26, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 4000 +monster.maxHealth = 4000 +monster.race = "blood" +monster.corpse = 36497 +monster.speed = 155 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 82000, maxCount = 2}, + {name = "Envenomed Arrow", chance = 68000, maxCount = 47}, + {name = "Earth Arrow", chance = 65000, maxCount = 21}, + {name = "Worm", chance = 61500, maxCount = 3}, + {name = "Lump of Dirt", chance = 42000}, + {name = "Green Memory Shard", chance = 35000}, + {name = "Blue Memory Shard", chance = 35000}, + {name = "Violet Memory Shard", chance = 32000}, + {name = "Terra Amulet", chance = 26000}, + {name = "Terra hood", chance = 16500}, + {name = "Sacred Tree Amulet", chance = 12300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -240, condition = {type = CONDITION_POISON, totalDamage = 25, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -320, maxDamage = -450, range = 5, shootEffect = CONST_ANI_POISON, effect = CONST_ME_SOUND_GREEN, target = true}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_EARTHDAMAGE, minDamage = -280, maxDamage = -350, radius = 3, effect = CONST_ME_GROUNDSHAKER, target = false} +} + +monster.defenses = { + defense = 46, + armor = 46 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/kilmaresh/mozradek.lua b/data/monster/quests/kilmaresh/mozradek.lua new file mode 100644 index 00000000000..0dea0d2fbb7 --- /dev/null +++ b/data/monster/quests/kilmaresh/mozradek.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Mozradek") +local monster = {} + +monster.description = "Mozradek" +monster.experience = 21000 +monster.outfit = { + lookType = 240, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 28000 +monster.maxHealth = 28000 +monster.race = "fire" +monster.corpse = 13973 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 100, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Red Gem", chance = 60000}, + {id = 36204, chance = 9000}, + {name = "Sea Horse Figurine", chance = 6000}, + {id = 36392, chance = 3500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -600}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -400, maxDamage = -550, radius = 4, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 16, type = COMBAT_DEATHDAMAGE, minDamage = -450, maxDamage = -600, range = 7, radius = 3, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_FIREDAMAGE, minDamage = -450, maxDamage = -500, range = 7, radius = 1, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_EXPLOSIONHIT, target = true} +} + +monster.defenses = { + defense = 84, + armor = 84 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/kilmaresh/sun-marked_goanna.lua b/data/monster/quests/kilmaresh/sun-marked_goanna.lua new file mode 100644 index 00000000000..d5571faee4c --- /dev/null +++ b/data/monster/quests/kilmaresh/sun-marked_goanna.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("Sun-Marked Goanna") +local monster = {} + +monster.description = "a sun-marked goanna" +monster.experience = 7600 +monster.outfit = { + lookType = 1195, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 7800 +monster.maxHealth = 7800 +monster.race = "blood" +monster.corpse = 36240 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Goanna Hide with Sun Symbol", chance = 100000}, + {name = "Platinum Coin", chance = 100000, maxCount = 3}, + {name = "Envenomed Arrow", chance = 50000, maxCount = 29}, + {name = "Poison Dagger", chance = 50000}, + {name = "Scared Frog", chance = 50000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -350, condition = {type = CONDITION_POISON, totalDamage = 19, interval = 4000}}, + {name ="wave t", interval = 2000, chance = 10, minDamage = -250, maxDamage = -380, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_EARTHDAMAGE, minDamage = -450, maxDamage = -550, range = 3, radius = 1, shootEffect = CONST_ANI_EARTH, effect = CONST_ME_EXPLOSIONHIT, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -210, maxDamage = -300, radius = 5, effect = CONST_ME_GROUNDSHAKER, target = false} +} + +monster.defenses = { + defense = 84, + armor = 84, + {name ="speed", interval = 2000, chance = 5, speedChange = 500, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 75}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/kilmaresh/urmahlullu_the_immaculate.lua b/data/monster/quests/kilmaresh/urmahlullu_the_immaculate.lua new file mode 100644 index 00000000000..0f4ba33f98c --- /dev/null +++ b/data/monster/quests/kilmaresh/urmahlullu_the_immaculate.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Urmahlullu the Immaculate") +local monster = {} + +monster.description = "urmahlullu the immaculate" +monster.experience = 0 +monster.outfit = { + lookType = 1197, + lookHead = 57, + lookBody = 75, + lookLegs = 38, + lookFeet = 86, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 512000 +monster.maxHealth = 512000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "UrmahlulluChanges" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -150, maxDamage = -1300}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -500, maxDamage = -800, radius = 4, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -550, maxDamage = -800, radius = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -550, maxDamage = -800, radius = 3, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="urmahlulluring", interval = 2000, chance = 18, minDamage = -450, maxDamage = -600, target = false} +} + +monster.defenses = { + defense = 84, + armor = 84 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 40}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/kilmaresh/urmahlullu_the_tamed.lua b/data/monster/quests/kilmaresh/urmahlullu_the_tamed.lua new file mode 100644 index 00000000000..b2503530462 --- /dev/null +++ b/data/monster/quests/kilmaresh/urmahlullu_the_tamed.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Urmahlullu the Tamed") +local monster = {} + +monster.description = "urmahlullu the tamed" +monster.experience = 0 +monster.outfit = { + lookType = 1197, + lookHead = 57, + lookBody = 75, + lookLegs = 38, + lookFeet = 86, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 300000 +monster.maxHealth = 512000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "UrmahlulluChanges" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -150, maxDamage = -1300}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -500, maxDamage = -800, radius = 4, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -550, maxDamage = -800, radius = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -550, maxDamage = -800, radius = 3, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="urmahlulluring", interval = 2000, chance = 18, minDamage = -450, maxDamage = -600, target = false} +} + +monster.defenses = { + defense = 84, + armor = 84 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 40}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/kilmaresh/urmahlullu_the_weakened.lua b/data/monster/quests/kilmaresh/urmahlullu_the_weakened.lua new file mode 100644 index 00000000000..513e84ac2d0 --- /dev/null +++ b/data/monster/quests/kilmaresh/urmahlullu_the_weakened.lua @@ -0,0 +1,164 @@ +local mType = Game.createMonsterType("Urmahlullu the Weakened") +local monster = {} + +monster.description = "urmahlullu the weakened" +monster.experience = 85000 +monster.outfit = { + lookType = 1197, + lookHead = 57, + lookBody = 75, + lookLegs = 38, + lookFeet = 86, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 100000 +monster.maxHealth = 512000 +monster.race = "blood" +monster.corpse = 36248 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "WeakenedDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You will regret this!", yell = false} +} + +monster.loot = { + {name = "platinum coin", chance = 96000, maxCount = 6}, + {name = "ultimate mana potion", chance = 51000, maxCount = 20}, + {name = "red gem", chance = 39000, maxCount = 2}, + {name = "berserk potion", chance = 15000, maxCount = 10}, + {name = "flash arrow", chance = 30000, maxCount = 100}, + {name = "crystal coin", chance = 12000, maxCount = 3}, + {name = "silver token", chance = 9000, maxCount = 3}, + {name = "mastermind potion", chance = 12000, maxCount = 10}, + {name = "supreme health potion", chance = 51000, maxCount = 20}, + {name = "ultimate spirit potion", chance = 42000, maxCount = 20}, + {name = "royal star", chance = 30000, maxCount = 100}, + {name = "bullseye potion", chance = 18000, maxCount = 10}, + {name = "lightning pendant", chance = 27000}, + {name = "giant ruby", chance = 6000}, + {name = "urmahlullu's mane", chance = 6000}, + {name = "urmahlullu's paw", chance = 6000}, + {name = "urmahlullu's tail", chance = 6000}, + {name = "tagralt blade", chance = 500}, + {name = "winged boots", chance = 500}, + {name = "energy bar", chance = 93000}, + {name = "yellow gem", chance = 46000}, + {name = "green gem", chance = 21000}, + {name = "magma coat", chance = 6000}, + {id = 7632, chance = 12000}, + {name = "violet gem", chance = 6000}, + {name = "magma monocle", chance = 3000}, + {id = 36392, chance = 3000}, + {name = "blue gem", chance = 12000}, + {name = "magma amulet", chance = 12000}, + {name = "gold ingot", chance = 9000}, + {name = "giant emerald", chance = 6000}, + {id = 36098, chance = 100000}, + {name = "rainbow necklace", chance = 6000}, + {name = "giant sapphire", chance = 6000}, + {name = "winged backpack", chance = 250}, + {name = "rainbow necklace", chance = 160}, + {id = 35238, chance = 160}, + {name = "Sun Medal", chance = 160}, + {name = "Sunray Emblem", chance = 160} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -50, maxDamage = -1100}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -500, maxDamage = -800, radius = 4, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -550, maxDamage = -800, radius = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="urmahlulluring", interval = 2000, chance = 18, minDamage = -450, maxDamage = -600, target = false} +} + +monster.defenses = { + defense = 84, + armor = 84 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 40}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/kilmaresh/wildness_of_urmahlullu.lua b/data/monster/quests/kilmaresh/wildness_of_urmahlullu.lua new file mode 100644 index 00000000000..e61343cefa8 --- /dev/null +++ b/data/monster/quests/kilmaresh/wildness_of_urmahlullu.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Wildness of Urmahlullu") +local monster = {} + +monster.description = "wildness of urmahlullu" +monster.experience = 0 +monster.outfit = { + lookType = 570, + lookHead = 57, + lookBody = 75, + lookLegs = 38, + lookFeet = 86, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 400000 +monster.maxHealth = 512000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "UrmahlulluChanges" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -150, maxDamage = -1300}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -500, maxDamage = -800, radius = 4, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -550, maxDamage = -800, radius = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -550, maxDamage = -800, radius = 3, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="urmahlulluring", interval = 2000, chance = 18, minDamage = -450, maxDamage = -600, target = false} +} + +monster.defenses = { + defense = 84, + armor = 84 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 40}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/kilmaresh/wisdom_of_urmahlullu.lua b/data/monster/quests/kilmaresh/wisdom_of_urmahlullu.lua new file mode 100644 index 00000000000..15aa28704cd --- /dev/null +++ b/data/monster/quests/kilmaresh/wisdom_of_urmahlullu.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Wisdom of Urmahlullu") +local monster = {} + +monster.description = "wisdom of urmahlullu" +monster.experience = 0 +monster.outfit = { + lookType = 1200, + lookHead = 57, + lookBody = 75, + lookLegs = 38, + lookFeet = 86, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 200000 +monster.maxHealth = 512000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "UrmahlulluChanges" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "How can you be that dumb?", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -150, maxDamage = -1300}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -500, maxDamage = -800, radius = 4, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -550, maxDamage = -800, radius = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -550, maxDamage = -800, radius = 3, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="urmahlulluring", interval = 2000, chance = 18, minDamage = -450, maxDamage = -600, target = false} +} + +monster.defenses = { + defense = 84, + armor = 84 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 40}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/kilmaresh/xogixath.lua b/data/monster/quests/kilmaresh/xogixath.lua new file mode 100644 index 00000000000..f359b00b9d4 --- /dev/null +++ b/data/monster/quests/kilmaresh/xogixath.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Xogixath") +local monster = {} + +monster.description = "xogixath" +monster.experience = 22000 +monster.outfit = { + lookType = 842, + lookHead = 3, + lookBody = 16, + lookLegs = 75, + lookFeet = 19, + lookAddons = 2, + lookMount = 0 +} + +monster.health = 28000 +monster.maxHealth = 28000 +monster.race = "fire" +monster.corpse = 13973 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 100000, maxCount = 9}, + {name = "Red Gem", chance = 65000, maxCount = 2}, + {name = "Green Crystal Shard", chance = 16000}, + {name = "Sea Horse Figurine", chance = 2400}, + {name = "Winged Boots", chance = 120}, + {name = "Small Sapphire", chance = 48000, maxCount = 3}, + {name = "Stone Skin Amulet", chance = 54000}, + {id = 36204, chance = 6500}, + {name = "Fire Axe", chance = 34000}, + {id = 36392, chance = 520} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -650}, + {name ="sudden death", interval = 2000, chance = 16, minDamage = -450, maxDamage = -550, range = 5, target = true}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_FIREDAMAGE, minDamage = -400, maxDamage = -480, range = 5, radius = 3, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -400, maxDamage = -550, radius = 4, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_FIREDAMAGE, minDamage = -420, maxDamage = -600, length = 5, spread = 3, effect = CONST_ME_HITBYFIRE, target = false} +} + +monster.defenses = { + defense = 86, + armor = 86 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/liquid_black/jaul.lua b/data/monster/quests/liquid_black/jaul.lua new file mode 100644 index 00000000000..f9175b9fd98 --- /dev/null +++ b/data/monster/quests/liquid_black/jaul.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Jaul") +local monster = {} + +monster.description = "Jaul" +monster.experience = 35000 +monster.outfit = { + lookType = 444, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 95000 +monster.maxHealth = 95000 +monster.race = "blood" +monster.corpse = 15220 +monster.speed = 440 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 50 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 60, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "QJELL AFAR GOU JEY!!", yell = false}, + {text = "DIE!! KENH!!", yell = false} +} + +monster.loot = { + {name = "deepling axe", chance = 1500}, + {name = "depth calcei", chance = 1100}, + {id = 15408, chance = 1400},-- depth galea + {name = "depth lorica", chance = 800}, + {name = "ornate chestplate", chance = 650, unique = true}, + {name = "ornate legs", chance = 740}, + {name = "ornate mace", chance = 1500}, + {name = "ornate shield", chance = 1400} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -2000, condition = {type = CONDITION_POISON, totalDamage = 870, interval = 4000}}, + {name ="combat", interval = 2200, chance = 19, type = COMBAT_FIREDAMAGE, minDamage = 0, maxDamage = -1000, range = 7, radius = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 3000, chance = 32, type = COMBAT_MANADRAIN, minDamage = -200, maxDamage = -800, range = 7, radius = 7, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 1300, chance = 27, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -600, radius = 3, effect = CONST_ME_EXPLOSIONAREA, target = false}, + {name ="combat", interval = 1200, chance = 6, type = COMBAT_DEATHDAMAGE, minDamage = -300, maxDamage = -900, length = 8, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 1000, chance = 5, type = COMBAT_FIREDAMAGE, minDamage = -500, maxDamage = -1000, length = 8, spread = 3, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 1000, chance = 5, type = COMBAT_ICEDAMAGE, minDamage = -1000, maxDamage = -2000, length = 8, spread = 3, effect = CONST_ME_ICEAREA, target = false}, + {name ="combat", interval = 4000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -500, maxDamage = -1000, length = 8, spread = 3, effect = CONST_ME_WATERSPLASH, target = false}, + {name ="speed", interval = 1900, chance = 14, speedChange = -700, range = 7, radius = 1, target = true, duration = 15000} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 5000, chance = 7, type = COMBAT_HEALING, minDamage = 12000, maxDamage = 19000, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 1}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/liquid_black/obujos.lua b/data/monster/quests/liquid_black/obujos.lua new file mode 100644 index 00000000000..e069502d6ce --- /dev/null +++ b/data/monster/quests/liquid_black/obujos.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Obujos") +local monster = {} + +monster.description = "Obujos" +monster.experience = 20000 +monster.outfit = { + lookType = 445, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 33000 +monster.maxHealth = 33000 +monster.race = "blood" +monster.corpse = 15224 +monster.speed = 560 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 50 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 60, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "JN OBU!!", yell = false}, + {text = "QJELL KEJH!!", yell = false} +} + +monster.loot = { + {name = "Deepling Axe", chance = 1300}, + {name = "Depth Scutum", chance = 1185}, + {name = "Ornate Legs", chance = 700, unique = true} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1200, condition = {type = CONDITION_POISON, totalDamage = 360, interval = 4000}}, + {name ="combat", interval = 3000, chance = 23, type = COMBAT_DEATHDAMAGE, minDamage = -200, maxDamage = -800, range = 7, radius = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 3500, chance = 20, type = COMBAT_MANADRAIN, minDamage = -200, maxDamage = -600, range = 7, radius = 6, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_BIGCLOUDS, target = true}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_EARTHDAMAGE, minDamage = -200, maxDamage = -800, range = 7, radius = 1, shootEffect = CONST_ANI_POISONARROW, effect = CONST_ME_GREEN_RINGS, target = true}, + {name ="combat", interval = 1200, chance = 7, type = COMBAT_ICEDAMAGE, minDamage = -600, maxDamage = -1300, length = 8, spread = 3, effect = CONST_ME_GIANTICE, target = false}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_LIFEDRAIN, minDamage = -600, maxDamage = -1600, length = 8, spread = 3, effect = CONST_ME_ICETORNADO, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_HEALING, minDamage = 800, maxDamage = 2200, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 25}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 60}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 60} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/liquid_black/tanjis.lua b/data/monster/quests/liquid_black/tanjis.lua new file mode 100644 index 00000000000..5748cdd874a --- /dev/null +++ b/data/monster/quests/liquid_black/tanjis.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Tanjis") +local monster = {} + +monster.description = "Tanjis" +monster.experience = 15000 +monster.outfit = { + lookType = 446, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 25000 +monster.maxHealth = 25000 +monster.race = "blood" +monster.corpse = 15228 +monster.speed = 560 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 50 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 60, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "JAU QJELL, JAKHN JEH KENH!!", yell = false} +} + +monster.loot = { + {name = "Depth Ocrea", chance = 1200}, + {name = "Ornate Mace", chance = 1100, unique = true}, + {name = "Ornate Shield", chance = 1100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -600}, + {name ="combat", interval = 2500, chance = 20, type = COMBAT_MANADRAIN, minDamage = -200, maxDamage = -600, range = 7, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_CARNIPHILA, target = true}, + {name ="combat", interval = 3500, chance = 27, type = COMBAT_ICEDAMAGE, minDamage = -200, maxDamage = -400, range = 7, radius = 4, shootEffect = CONST_ANI_ICE, effect = CONST_ME_ICEAREA, target = true}, + {name ="combat", interval = 3500, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -100, maxDamage = -400, range = 1, radius = 1, target = true}, + {name ="combat", interval = 2300, chance = 11, type = COMBAT_DROWNDAMAGE, minDamage = -200, maxDamage = -500, range = 7, radius = 4, shootEffect = CONST_ANI_ICE, effect = CONST_ME_WATERSPLASH, target = true}, + {name ="combat", interval = 2300, chance = 14, type = COMBAT_MANADRAIN, minDamage = -200, maxDamage = -600, range = 7, radius = 7, effect = CONST_ME_BUBBLES, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -400, range = 7, radius = 1, shootEffect = CONST_ANI_LARGEROCK, target = true}, + {name ="combat", interval = 1200, chance = 7, type = COMBAT_DEATHDAMAGE, minDamage = -300, maxDamage = -800, length = 8, spread = 3, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -500, length = 8, spread = 3, effect = CONST_ME_PURPLEENERGY, target = false}, + {name ="speed", interval = 2150, chance = 16, speedChange = -600, range = 7, radius = 1, target = true, duration = 15000} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 3000, chance = 40, type = COMBAT_HEALING, minDamage = 800, maxDamage = 1100, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = -5}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 5}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/mysterious_ornate_chest/an_observer_eye.lua b/data/monster/quests/mysterious_ornate_chest/an_observer_eye.lua new file mode 100644 index 00000000000..abb70f8ae4a --- /dev/null +++ b/data/monster/quests/mysterious_ornate_chest/an_observer_eye.lua @@ -0,0 +1,97 @@ +local mType = Game.createMonsterType("An Observer Eye") +local monster = {} + +monster.description = "an observer eye" +monster.experience = 0 +monster.outfit = { + lookType = 925, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 30000 +monster.maxHealth = 30000 +monster.race = "blood" +monster.corpse = 5995 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "lightsphere", chance = 99990} +} + +monster.attacks = { + {name ="combat", interval = 2000, chance = 4, type = COMBAT_ENERGYDAMAGE, minDamage = -3000, maxDamage = -5000, range = 3, shootEffect = CONST_ANI_ENERGY, target = false} +} + +monster.defenses = { + defense = 55, + armor = 55 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/mysterious_ornate_chest/an_observer_eye_(imune).lua b/data/monster/quests/mysterious_ornate_chest/an_observer_eye_(imune).lua new file mode 100644 index 00000000000..0b18ead74b9 --- /dev/null +++ b/data/monster/quests/mysterious_ornate_chest/an_observer_eye_(imune).lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("An Observer Eye") +local monster = {} + +monster.description = "an observer eye" +monster.experience = 0 +monster.outfit = { + lookType = 925, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 30000 +monster.maxHealth = 30000 +monster.race = "blood" +monster.corpse = 27596 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 98, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="combat", interval = 1000, chance = 100, type = COMBAT_ENERGYDAMAGE, minDamage = -3000, maxDamage = -5000, range = 30, shootEffect = CONST_ANI_ENERGY, target = false} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/mysterious_ornate_chest/reflection_of_mawhawk.lua b/data/monster/quests/mysterious_ornate_chest/reflection_of_mawhawk.lua new file mode 100644 index 00000000000..083772abd2e --- /dev/null +++ b/data/monster/quests/mysterious_ornate_chest/reflection_of_mawhawk.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Reflection Of Mawhawk") +local monster = {} + +monster.description = "an reflection of mawhawk" +monster.experience = 9650 +monster.outfit = { + lookType = 595, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 12600 +monster.maxHealth = 12600 +monster.race = "blood" +monster.corpse = 23375 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 4 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I'm the one who puts the cute into execute!", yell = false}, + {text = "I'm here to punish!", yell = false}, + {text = "Justice is swift and unavoidable!", yell = false}, + {text = "I'll bring justice!", yell = false}, + {text = "There is excellence in execution!", yell = false}, + {text = "Your sentence is death!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 198}, + {id = 2152, chance = 67610, maxCount = 3}, + {id = 9971, chance = 390}, + {id = 5911, chance = 3230}, + {id = 5878, chance = 14710}, + {id = 12428, chance = 6580, maxCount = 2}, + {id = 23572, chance = 13160}, + {id = 7591, chance = 11480}, + {id = 7590, chance = 10060}, + {id = 2666, chance = 7230}, + {id = 9970, chance = 5810, maxCount = 2}, + {id = 2147, chance = 4520, maxCount = 2}, + {id = 7412, chance = 900}, + {id = 2487, chance = 770}, + {id = 23547, chance = 1420}, + {id = 2430, chance = 770}, + {id = 7413, chance = 390}, + {id = 7401, chance = 520} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 80}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_LIFEDRAIN, minDamage = -135, maxDamage = -280, range = 7, radius = 5, shootEffect = CONST_ANI_WHIRLWINDAXE, target = true}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_PHYSICALDAMAGE, minDamage = -90, maxDamage = -200, range = 7, shootEffect = CONST_ANI_WHIRLWINDAXE, effect = CONST_ME_EXPLOSIONAREA, target = true} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 1}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/mysterious_ornate_chest/reflection_of_obujos.lua b/data/monster/quests/mysterious_ornate_chest/reflection_of_obujos.lua new file mode 100644 index 00000000000..265bf7f6103 --- /dev/null +++ b/data/monster/quests/mysterious_ornate_chest/reflection_of_obujos.lua @@ -0,0 +1,110 @@ +local mType = Game.createMonsterType("Reflection Of Obujos") +local monster = {} + +monster.description = "an reflection of obujos" +monster.experience = 20000 +monster.outfit = { + lookType = 445, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 33000 +monster.maxHealth = 33000 +monster.race = "blood" +monster.corpse = 15224 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 4 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "JN OBU!!", yell = false}, + {text = "QJELL KEJH!!", yell = false} +} + +monster.loot = { + {id = 15411, chance = 100000}, + {id = 15404, chance = 1285}, + {id = 15412, chance = 1285, unique = true} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1200, condition = {type = CONDITION_POISON, totalDamage = 360, interval = 4000}}, + {name ="combat", interval = 3000, chance = 23, type = COMBAT_DEATHDAMAGE, minDamage = -200, maxDamage = -800, range = 7, radius = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 3500, chance = 20, type = COMBAT_MANADRAIN, minDamage = -200, maxDamage = -600, range = 7, radius = 6, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_BIGCLOUDS, target = true}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_EARTHDAMAGE, minDamage = -200, maxDamage = -800, range = 7, radius = 1, shootEffect = CONST_ANI_POISONARROW, effect = CONST_ME_GREEN_RINGS, target = true}, + {name ="combat", interval = 1200, chance = 7, type = COMBAT_ICEDAMAGE, minDamage = -600, maxDamage = -1300, length = 8, spread = 3, effect = CONST_ME_GIANTICE, target = false}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_LIFEDRAIN, minDamage = -600, maxDamage = -1600, length = 8, spread = 3, effect = CONST_ME_ICETORNADO, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_HEALING, minDamage = 1000, maxDamage = 2100, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -20}, + {type = COMBAT_ENERGYDAMAGE, percent = -20}, + {type = COMBAT_EARTHDAMAGE, percent = -20}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/mysterious_ornate_chest/ugly_monster.lua b/data/monster/quests/mysterious_ornate_chest/ugly_monster.lua new file mode 100644 index 00000000000..0825837fc11 --- /dev/null +++ b/data/monster/quests/mysterious_ornate_chest/ugly_monster.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Ugly Monster") +local monster = {} + +monster.description = "an ugly monster" +monster.experience = 650 +monster.outfit = { + lookType = 1218, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 13000 +monster.maxHealth = 13000 +monster.race = "blood" +monster.corpse = 36386 +monster.speed = 140 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -120}, + {name ="outfit", interval = 2000, chance = 10, range = 5, shootEffect = CONST_ANI_EARTH, target = false, duration = 10000, outfitMonster = "Ugly Monster"}, + {name ="drunk", interval = 2000, chance = 10, range = 5, shootEffect = CONST_ANI_EARTH, target = false, duration = 5000} +} + +monster.defenses = { + defense = 48, + armor = 48, + {name ="invisible", interval = 2000, chance = 8, effect = CONST_ME_HITAREA} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/pits_of_inferno/countess_sorrow.lua b/data/monster/quests/pits_of_inferno/countess_sorrow.lua new file mode 100644 index 00000000000..76dcd999f02 --- /dev/null +++ b/data/monster/quests/pits_of_inferno/countess_sorrow.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Countess Sorrow") +local monster = {} + +monster.description = "Countess Sorrow" +monster.experience = 13000 +monster.outfit = { + lookType = 241, + lookHead = 20, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 6500 +monster.maxHealth = 6500 +monster.race = "undead" +monster.corpse = 6344 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 540, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Phantasm", chance = 7, interval = 2000, max = 3}, + {name = "Phantasm summon", chance = 7, interval = 2000, max = 3} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I'm so sorry ... for youuu!", yell = false}, + {text = "You won't rest in peace! Never ever!", yell = false}, + {text = "Sleep ... for eternity!", yell = false}, + {text = "Dreams can come true. As my dream of killing you.", yell = false} +} + +monster.loot = { + {id = 6536, chance = 100000}, + {id = 6500, chance = 20590}, + {id = 2148, chance = 82350, maxCount = 169}, + {id = 2152, chance = 55880, maxCount = 4}, + {id = 5944, chance = 85290}, + {id = 2656, chance = 32350}, + {id = 2424, chance = 4210}, + {id = 2647, chance = 8820}, + {id = 2200, chance = 23530}, + {id = 2165, chance = 5880}, + {id = 2238, chance = 47060} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 156, attack = 100, condition = {type = CONDITION_POISON, totalDamage = 920, interval = 4000}}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -420, maxDamage = -980, range = 7, radius = 1, shootEffect = CONST_ANI_POISON, effect = CONST_ME_HITBYPOISON, target = true}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_MANADRAIN, minDamage = -45, maxDamage = -90, radius = 3, effect = CONST_ME_YELLOW_RINGS, target = false}, + {name ="phantasm drown", interval = 2000, chance = 20, target = false}, + {name ="drunk", interval = 2000, chance = 15, range = 7, radius = 6, effect = CONST_ME_MAGIC_RED, target = false, duration = 10000} +} + +monster.defenses = { + defense = 20, + armor = 25, + {name ="combat", interval = 2000, chance = 26, type = COMBAT_HEALING, minDamage = 415, maxDamage = 625, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_POFF}, + {name ="speed", interval = 2000, chance = 11, speedChange = 736, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/pits_of_inferno/demon_goblin.lua b/data/monster/quests/pits_of_inferno/demon_goblin.lua new file mode 100644 index 00000000000..bb699e08b9f --- /dev/null +++ b/data/monster/quests/pits_of_inferno/demon_goblin.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("Demon Goblin") +local monster = {} + +monster.description = "a demon goblin" +monster.experience = 25 +monster.outfit = { + lookType = 35, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 50 +monster.maxHealth = 50 +monster.race = "blood" +monster.corpse = 5995 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 40, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "small stone", chance = 15290, maxCount = 3}, + {name = "gold coin", chance = 50320, maxCount = 9}, + {id = 2230, chance = 1130}, + {name = "mouldy cheese", chance = 1000}, + {name = "dagger", chance = 1800}, + {name = "short sword", chance = 8870}, + {name = "bone club", chance = 4900}, + {name = "leather helmet", chance = 1940}, + {name = "leather armor", chance = 2510}, + {name = "small axe", chance = 9700}, + {id = 2667, chance = 12750}, + {name = "goblin ear", chance = 910} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -10}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -25, range = 7, shootEffect = CONST_ANI_SMALLSTONE, target = false} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -12}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 1}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/pits_of_inferno/dracola.lua b/data/monster/quests/pits_of_inferno/dracola.lua new file mode 100644 index 00000000000..cbd0e09cca8 --- /dev/null +++ b/data/monster/quests/pits_of_inferno/dracola.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Dracola") +local monster = {} + +monster.description = "Dracola" +monster.experience = 11000 +monster.outfit = { + lookType = 231, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 16200 +monster.maxHealth = 16200 +monster.race = "undead" +monster.corpse = 6307 +monster.speed = 370 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Your new name is breakfast.", yell = true}, + {text = "I'm bad to the bone.", yell = true}, + {text = "DEATH CAN'T STOP MY HUNGER!", yell = true} +} + +monster.loot = { + {id = 5944, chance = 100000}, + {id = 5741, chance = 9000}, + {id = 7420, chance = 3000}, + {id = 2177, chance = 12000}, + {id = 5925, chance = 5000, maxCount = 3}, + {id = 7590, chance = 9000, maxCount = 4}, + {id = 7591, chance = 9000, maxCount = 4}, + {id = 6300, chance = 14000}, + {id = 2489, chance = 29000}, + {id = 2148, chance = 29000, maxCount = 100}, + {id = 2148, chance = 29000, maxCount = 100}, + {id = 2152, chance = 20000, maxCount = 8}, + {id = 6500, chance = 6000, maxCount = 4}, + {id = 6546, chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -700}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -800, maxDamage = -1000, length = 8, spread = 3, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -120, maxDamage = -750, range = 7, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true}, + -- drown + {name ="condition", type = CONDITION_DROWN, interval = 1000, chance = 20, length = 8, spread = 3, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -300, maxDamage = -870, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="combat", interval = 3000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -750, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 1000, chance = 23, type = COMBAT_EARTHDAMAGE, minDamage = -50, maxDamage = -175, range = 7, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -100, maxDamage = -200, range = 7, target = false} +} + +monster.defenses = { + defense = 39, + armor = 40, + {name ="combat", interval = 4000, chance = 10, type = COMBAT_HEALING, minDamage = 500, maxDamage = 1000, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/pits_of_inferno/flamethrower.lua b/data/monster/quests/pits_of_inferno/flamethrower.lua new file mode 100644 index 00000000000..e20694d688b --- /dev/null +++ b/data/monster/quests/pits_of_inferno/flamethrower.lua @@ -0,0 +1,90 @@ +local mType = Game.createMonsterType("Flamethrower") +local monster = {} + +monster.description = "a flamethrower" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 1551 +} + +monster.health = 1 +monster.maxHealth = 1 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 100, + healthHidden = true, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="combat", interval = 2000, chance = 100, type = COMBAT_FIREDAMAGE, minDamage = 0, maxDamage = -100, range = 7, shootEffect = CONST_ANI_FIRE, target = false} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/pits_of_inferno/massacre.lua b/data/monster/quests/pits_of_inferno/massacre.lua new file mode 100644 index 00000000000..a635c98a439 --- /dev/null +++ b/data/monster/quests/pits_of_inferno/massacre.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Massacre") +local monster = {} + +monster.description = "Massacre" +monster.experience = 20000 +monster.outfit = { + lookType = 244, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 32000 +monster.maxHealth = 32000 +monster.race = "blood" +monster.corpse = 6336 +monster.speed = 430 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "HATE! HATE! KILL! KILL!", yell = true}, + {text = "GRRAAARRRHH!", yell = true}, + {text = "GRRRR!", yell = true} +} + +monster.loot = { + {id = 2231, chance = 5880}, + {id = 6500, chance = 100000}, + {id = 7591, chance = 5880}, + {id = 7590, chance = 5880}, + {id = 2148, chance = 94120, maxCount = 157}, + {id = 2522, chance = 500}, + {id = 2666, chance = 88240, maxCount = 9}, + {id = 5022, chance = 82350, maxCount = 7}, + {id = 2221, chance = 64710}, + {id = 2152, chance = 58820, maxCount = 6}, + {id = 6540, chance = 100000}, + {id = 5944, chance = 100000}, + {id = 2452, chance = 1000}, + {id = 7403, chance = 900}, + {id = 2466, chance = 3500}, + {id = 6104, chance = 1200} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 160, attack = 200}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -1100, range = 7, shootEffect = CONST_ANI_LARGEROCK, effect = CONST_ME_EXPLOSIONAREA, target = false} +} + +monster.defenses = { + defense = 65, + armor = 45, + {name ="speed", interval = 2000, chance = 8, speedChange = 790, effect = CONST_ME_MAGIC_RED, target = false, duration = 10000}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 600, maxDamage = 1090, effect = CONST_ME_HITBYFIRE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -7}, + {type = COMBAT_EARTHDAMAGE, percent = 30}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = -3}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/pits_of_inferno/mr._punish.lua b/data/monster/quests/pits_of_inferno/mr._punish.lua new file mode 100644 index 00000000000..bb2223c1b9d --- /dev/null +++ b/data/monster/quests/pits_of_inferno/mr._punish.lua @@ -0,0 +1,103 @@ +local mType = Game.createMonsterType("Mr. Punish") +local monster = {} + +monster.description = "Mr. Punish" +monster.experience = 9000 +monster.outfit = { + lookType = 234, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 22000 +monster.maxHealth = 22000 +monster.race = "undead" +monster.corpse = 6331 +monster.speed = 470 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 50, + targetDistance = 1, + runHealth = 2000, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I kept my axe sharp, especially for you!", yell = false}, + {text = "Time for a little torturing practice!", yell = false}, + {text = "Scream for me!", yell = false} +} + +monster.loot = { + {id = 6537, chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -660, maxDamage = -1280} +} + +monster.defenses = { + defense = 72, + armor = 64 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/pits_of_inferno/the_handmaiden.lua b/data/monster/quests/pits_of_inferno/the_handmaiden.lua new file mode 100644 index 00000000000..6d3c04ef9f1 --- /dev/null +++ b/data/monster/quests/pits_of_inferno/the_handmaiden.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("The Handmaiden") +local monster = {} + +monster.description = "the Handmaiden" +monster.experience = 7500 +monster.outfit = { + lookType = 230, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 19500 +monster.maxHealth = 19500 +monster.race = "blood" +monster.corpse = 6312 +monster.speed = 450 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 3100, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 6539, chance = 35000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -800}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_MANADRAIN, minDamage = -150, maxDamage = -800, range = 7, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="drunk", interval = 1000, chance = 12, range = 1, target = true} +} + +monster.defenses = { + defense = 35, + armor = 25, + {name ="speed", interval = 3000, chance = 12, speedChange = 380, effect = CONST_ME_MAGIC_RED, target = false, duration = 8000}, + {name ="invisible", interval = 4000, chance = 50, effect = CONST_ME_MAGIC_RED}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_HEALING, minDamage = 100, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 1000, chance = 35, speedChange = 370, effect = CONST_ME_MAGIC_RED, target = false, duration = 30000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/pits_of_inferno/the_imperor.lua b/data/monster/quests/pits_of_inferno/the_imperor.lua new file mode 100644 index 00000000000..f32095c4a61 --- /dev/null +++ b/data/monster/quests/pits_of_inferno/the_imperor.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("The Imperor") +local monster = {} + +monster.description = "The Imperor" +monster.experience = 8000 +monster.outfit = { + lookType = 237, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 15000 +monster.maxHealth = 15000 +monster.race = "blood" +monster.corpse = 6364 +monster.speed = 310 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 1500, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Poke! Poke! ", yell = false}, + {text = "Let me tickle you with my trident!", yell = false} +} + +monster.loot = { + {id = 6500, chance = 100000}, + {id = 2148, chance = 100000, maxCount = 150}, + {id = 6534, chance = 100000}, + {id = 2548, chance = 53850}, + {id = 2432, chance = 11000}, + {id = 2152, chance = 46150, maxCount = 3}, + {id = 5944, chance = 100000}, + {id = 2488, chance = 30770}, + {id = 2470, chance = 7690}, + {id = 2136, chance = 15380}, + {id = 2542, chance = 7690}, + {id = 2515, chance = 15400}, + {id = 7899, chance = 15380}, + {id = 2150, chance = 30770, maxCount = 4}, + {id = 2147, chance = 7690, maxCount = 4} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 100, condition = {type = CONDITION_POISON, totalDamage = 280, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -350, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2500, chance = 12, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -460, range = 7, radius = 2, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREATTACK, target = true}, + {name ="diabolic imp skill reducer", interval = 2000, chance = 10, range = 7, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 35, type = COMBAT_HEALING, minDamage = 275, maxDamage = 840, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="the imperor summon", interval = 2000, chance = 21, target = false}, + {name ="speed", interval = 2000, chance = 12, speedChange = 1496, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000}, + {name ="invisible", interval = 2000, chance = 11, effect = CONST_ME_TELEPORT} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/pits_of_inferno/the_plasmother.lua b/data/monster/quests/pits_of_inferno/the_plasmother.lua new file mode 100644 index 00000000000..9071792f9d6 --- /dev/null +++ b/data/monster/quests/pits_of_inferno/the_plasmother.lua @@ -0,0 +1,117 @@ +local mType = Game.createMonsterType("The Plasmother") +local monster = {} + +monster.description = "The Plasmother" +monster.experience = 12000 +monster.outfit = { + lookType = 238, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 7500 +monster.maxHealth = 7500 +monster.race = "venom" +monster.corpse = 6532 +monster.speed = 310 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5500, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 250, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Defiler", chance = 20, interval = 4000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Blubb", yell = false}, + {text = "Blubb Blubb", yell = false}, + {text = "Blubberdiblubb", yell = false} +} + +monster.loot = { + {id = 2148, chance = 20000, maxCount = 177}, + {id = 2152, chance = 25000, maxCount = 13}, + {id = 6500, chance = 45000}, + {id = 2144, chance = 5000, maxCount = 3}, + {id = 2146, chance = 5000, maxCount = 3}, + {id = 5944, chance = 35000}, + {id = 6535, chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 30, attack = 50}, + {name ="speed", interval = 1000, chance = 8, speedChange = -800, radius = 6, effect = CONST_ME_POISONAREA, target = false, duration = 10000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -200, maxDamage = -350, radius = 4, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 3000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -200, maxDamage = -530, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_HITBYPOISON, target = true} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 1000, chance = 75, type = COMBAT_HEALING, minDamage = 505, maxDamage = 605, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/roshamuul/bad_dream.lua b/data/monster/quests/roshamuul/bad_dream.lua new file mode 100644 index 00000000000..624e272d9ae --- /dev/null +++ b/data/monster/quests/roshamuul/bad_dream.lua @@ -0,0 +1,89 @@ +local mType = Game.createMonsterType("Bad Dream") +local monster = {} + +monster.description = "a bad dream" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 22444 +} + +monster.health = 7200 +monster.maxHealth = 7200 +monster.race = "blood" +monster.corpse = 22497 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/roshamuul/flame_of_omrafir.lua b/data/monster/quests/roshamuul/flame_of_omrafir.lua new file mode 100644 index 00000000000..15ce8ace0d8 --- /dev/null +++ b/data/monster/quests/roshamuul/flame_of_omrafir.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Flame of Omrafir") +local monster = {} + +monster.description = "a flame of omrafir" +monster.experience = 550 +monster.outfit = { + lookType = 49, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 800 +monster.maxHealth = 800 +monster.race = "fire" +monster.corpse = 8964 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="combat", interval = 1000, chance = 13, type = COMBAT_FIREDAMAGE, minDamage = -65, maxDamage = -205, radius = 5, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_FIREDAMAGE, minDamage = -110, maxDamage = -150, range = 7, radius = 5, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="firefield", interval = 1000, chance = 15, range = 7, radius = 1, shootEffect = CONST_ANI_FIRE, target = true} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/roshamuul/gaz'haragoth.lua b/data/monster/quests/roshamuul/gaz'haragoth.lua new file mode 100644 index 00000000000..bebc146b1d3 --- /dev/null +++ b/data/monster/quests/roshamuul/gaz'haragoth.lua @@ -0,0 +1,198 @@ +local mType = Game.createMonsterType("Gaz'Haragoth") +local monster = {} + +monster.description = "Gaz'Haragoth" +monster.experience = 1000000 +monster.outfit = { + lookType = 591, + lookHead = 0, + lookBody = 94, + lookLegs = 79, + lookFeet = 79, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 350000 +monster.maxHealth = 350000 +monster.race = "undead" +monster.corpse = 22562 +monster.speed = 500 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 10000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 98, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "GazHaragothHeal" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Minion of Gaz'haragoth", chance = 33, interval = 4000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "NO ONE WILL ESCAPE ME!", yell = true}, + {text = "I'LL KEEP THE ORDER UP!", yell = true}, + {text = "I've beaten tougher demons then you even know!", yell = true}, + {text = "You puny humans will be my snacks!", yell = true} +} + +monster.loot = { + {id = 2160, chance = 10000, maxCount = 6}, + {id = 18418, chance = 10000, maxCount = 15}, + {id = 7368, chance = 10000, maxCount = 100}, + {id = 22598, chance = 7000, maxCount = 3}, + {id = 6500, chance = 1000, maxCount = 2}, + {id = 8473, chance = 10000, maxCount = 100}, + {id = 7590, chance = 10000, maxCount = 100}, + {id = 8472, chance = 10000, maxCount = 100}, + {id = 22397, chance = 2000, maxCount = 3}, + {id = 22396, chance = 2000, maxCount = 14}, + {id = 2158, chance = 10000, maxCount = 2}, + {id = 18416, chance = 10000, maxCount = 10}, + {id = 18414, chance = 10000, maxCount = 15}, + {id = 6529, chance = 6000}, + {id = 22612, chance = 6000}, + {id = 5914, chance = 6000}, + {id = 5911, chance = 6000}, + {id = 22610, chance = 1100}, + {id = 7632, chance = 6000}, + {id = 5954, chance = 6000}, + {id = 22608, chance = 6000, unique = true}, + {id = 2168, chance = 6000}, + {id = 22614, chance = 6000}, + {id = 22613, chance = 6000}, + {id = 22611, chance = 6000}, + {id = 22398, chance = 800}, + {id = 22401, chance = 1000}, + {id = 22404, chance = 1000}, + {id = 22407, chance = 1000}, + {id = 22413, chance = 1000}, + {id = 22410, chance = 500}, + {id = 22416, chance = 1000}, + {id = 22419, chance = 400}, + {id = 22422, chance = 700}, + {id = 22399, chance = 100}, + {id = 22402, chance = 200}, + {id = 22405, chance = 1000}, + {id = 22408, chance = 500}, + {id = 22414, chance = 1000}, + {id = 22411, chance = 500}, + {id = 22417, chance = 250}, + {id = 22420, chance = 400}, + {id = 22423, chance = 200}, + {id = 22400, chance = 300}, + {id = 22403, chance = 700}, + {id = 22406, chance = 500}, + {id = 22409, chance = 300}, + {id = 22415, chance = 250}, + {id = 22412, chance = 300}, + {id = 22418, chance = 1300}, + {id = 22421, chance = 1000}, + {id = 22424, chance = 140}, + {id = 11262, chance = 6000}, + {id = 11261, chance = 6000}, + {id = 11260, chance = 6000}, + {id = 11259, chance = 6000}, + {id = 11258, chance = 6000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -5000}, + {name ="combat", interval = 3000, chance = 35, type = COMBAT_ICEDAMAGE, minDamage = -900, maxDamage = -1100, range = 7, radius = 7, shootEffect = CONST_ANI_ICE, effect = CONST_ME_ICEAREA, target = true}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_DEATHDAMAGE, minDamage = -100, maxDamage = -1000, length = 8, spread = 3, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 2000, chance = 19, type = COMBAT_DEATHDAMAGE, minDamage = -100, maxDamage = -800, range = 7, radius = 6, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="melee", interval = 1800, chance = 40, minDamage = 0, maxDamage = -1000}, + {name ="combat", interval = 3000, chance = 30, type = COMBAT_FIREDAMAGE, minDamage = -4000, maxDamage = -6000, length = 8, spread = 3, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_FIREDAMAGE, minDamage = -1600, maxDamage = -3400, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2500, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -480, range = 7, radius = 5, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="gaz'haragoth iceball", interval = 2000, chance = 24, minDamage = -1000, maxDamage = -1000, target = false}, + {name ="gaz'haragoth death", interval = 4000, chance = 6, target = false}, + {name ="gaz'haragoth paralyze", interval = 2000, chance = 12, target = false} +} + +monster.defenses = { + defense = 65, + armor = 55, + {name ="combat", interval = 3000, chance = 35, type = COMBAT_HEALING, minDamage = 2500, maxDamage = 3500, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 4000, chance = 80, speedChange = 700, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/roshamuul/horadron.lua b/data/monster/quests/roshamuul/horadron.lua new file mode 100644 index 00000000000..3f2fc9c8566 --- /dev/null +++ b/data/monster/quests/roshamuul/horadron.lua @@ -0,0 +1,144 @@ +local mType = Game.createMonsterType("Horadron") +local monster = {} + +monster.description = "Horadron" +monster.experience = 18000 +monster.outfit = { + lookType = 12, + lookHead = 78, + lookBody = 80, + lookLegs = 110, + lookFeet = 77, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 30000 +monster.maxHealth = 30000 +monster.race = "blood" +monster.corpse = 6068 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Defiler", chance = 12, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Even I fear the wrath of the princes. And the cold touch of those whom they serve! You are not prepared!", yell = false}, + {text = "You foolish mortals with you medding you brought the end upon your world!", yell = false}, + {text = "After all those aeons I smell freedom at last!", yell = false} +} + +monster.loot = { + {id = 22396, chance = 100000}, + {id = 5954, chance = 100000}, + {id = 6500, chance = 100000}, + {id = 22397, chance = 13850}, + {id = 22610, chance = 5380}, + {id = 2148, chance = 100000, maxCount = 200}, + {id = 2152, chance = 100000, maxCount = 50}, + {id = 22598, chance = 100000}, + {id = 8903, chance = 5130}, + {id = 8901, chance = 35900}, + {id = 8902, chance = 10260}, + {id = 3962, chance = 33330}, + {id = 7456, chance = 12820}, + {id = 7453, chance = 2560}, + {id = 7388, chance = 2560}, + {id = 2466, chance = 1220}, + {id = 2656, chance = 1220}, + {id = 2487, chance = 17950}, + {id = 2470, chance = 250}, + {id = 2415, chance = 90}, + {id = 8926, chance = 90}, + {id = 7895, chance = 1750}, + {id = 2477, chance = 1750}, + {id = 2488, chance = 20510}, + {id = 2645, chance = 15380}, + {id = 2145, chance = 17950, maxCount = 25}, + {id = 2150, chance = 5130, maxCount = 25}, + {id = 2149, chance = 10260, maxCount = 25}, + {id = 2146, chance = 28210, maxCount = 25}, + {id = 9970, chance = 15380, maxCount = 25}, + {id = 2147, chance = 20510, maxCount = 25} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 110, attack = 100}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_EARTHDAMAGE, minDamage = -600, maxDamage = -1000, length = 8, spread = 3, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_EARTHDAMAGE, minDamage = -600, maxDamage = -1000, length = 8, spread = 3, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_EARTHDAMAGE, minDamage = -100, maxDamage = -235, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_HITBYPOISON, target = true}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_EARTHDAMAGE, minDamage = -100, maxDamage = -250, radius = 3, effect = CONST_ME_POISONAREA, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 25, minDamage = -300, maxDamage = -450, radius = 3, effect = CONST_ME_HITBYPOISON, target = false} +} + +monster.defenses = { + defense = 65, + armor = 55, + {name ="combat", interval = 2000, chance = 35, type = COMBAT_HEALING, minDamage = 400, maxDamage = 700, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/roshamuul/minion_of_gaz'haragoth.lua b/data/monster/quests/roshamuul/minion_of_gaz'haragoth.lua new file mode 100644 index 00000000000..d36fd66b988 --- /dev/null +++ b/data/monster/quests/roshamuul/minion_of_gaz'haragoth.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Minion of Gaz'haragoth") +local monster = {} + +monster.description = "a minion of Gaz'haragoth" +monster.experience = 0 +monster.outfit = { + lookType = 590, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5500 +monster.maxHealth = 5500 +monster.race = "blood" +monster.corpse = 22549 +monster.speed = 330 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450}, + {name ="combat", interval = 1800, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -685, length = 7, spread = 3, effect = CONST_ME_STONES, target = false}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_EARTHDAMAGE, minDamage = -250, maxDamage = -590, radius = 6, effect = CONST_ME_BIGPLANTS, target = false} +} + +monster.defenses = { + defense = 55, + armor = 55 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/roshamuul/nightmare_of_gaz'haragoth.lua b/data/monster/quests/roshamuul/nightmare_of_gaz'haragoth.lua new file mode 100644 index 00000000000..16467d222d0 --- /dev/null +++ b/data/monster/quests/roshamuul/nightmare_of_gaz'haragoth.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Nightmare of Gaz'haragoth") +local monster = {} + +monster.description = "a nightmare of Gaz'haragoth" +monster.experience = 0 +monster.outfit = { + lookType = 587, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5500 +monster.maxHealth = 5500 +monster.race = "blood" +monster.corpse = 22497 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450}, + {name ="combat", interval = 1800, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -685, length = 7, spread = 3, effect = CONST_ME_STONES, target = false}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_EARTHDAMAGE, minDamage = -250, maxDamage = -590, radius = 6, effect = CONST_ME_BIGPLANTS, target = false} +} + +monster.defenses = { + defense = 55, + armor = 55 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/roshamuul/omrafir.lua b/data/monster/quests/roshamuul/omrafir.lua new file mode 100644 index 00000000000..cad0215b1c9 --- /dev/null +++ b/data/monster/quests/roshamuul/omrafir.lua @@ -0,0 +1,164 @@ +local mType = Game.createMonsterType("Omrafir") +local monster = {} + +monster.description = "Omrafir" +monster.experience = 50000 +monster.outfit = { + lookType = 12, + lookHead = 78, + lookBody = 3, + lookLegs = 79, + lookFeet = 79, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 322000 +monster.maxHealth = 322000 +monster.race = "fire" +monster.corpse = 6068 +monster.speed = 480 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "FIRST I'LL OBLITERATE YOU THEN I BURN THIS PRISON DOWN!!", yell = false}, + {text = "I'M TOO HOT FOR YOU TO HANDLE!", yell = true}, + {text = "FREEDOM FOR PRINCESS", yell = true}, + {text = "THE POWER OF HIS INTERNAL FIRE RENEWS OMRAFIR!", yell = true}, + {text = "OMRAFIR INHALES DEEPLY!", yell = true}, + {text = "OMRAFIR BREATHES INFERNAL FIRE", yell = true}, + {text = "I WILL RULE WHEN THE NEW ORDER IS ESTABLISHED!", yell = true} +} + +monster.loot = { + {id = 18413, chance = 37500, maxCount = 5}, + {id = 22396, chance = 62500, maxCount = 4}, + {id = 18419, chance = 43750, maxCount = 3}, + {id = 5954, chance = 100000}, + {id = 6500, chance = 812500, maxCount = 4}, + {id = 22612, chance = 6250}, + {id = 22397, chance = 81250, maxCount = 2}, + {id = 22610, chance = 3250, unique = true}, + {id = 22613, chance = 2500}, + {id = 7632, chance = 43750}, + {id = 7633, chance = 43750}, + {id = 2148, chance = 18750, maxCount = 100}, + {id = 7590, chance = 6250, maxCount = 8}, + {id = 8472, chance = 56250, maxCount = 8}, + {id = 18421, chance = 37500, maxCount = 3}, + {id = 18415, chance = 18750, maxCount = 5}, + {id = 2155, chance = 18750}, + {id = 7893, chance = 12500}, + {id = 7898, chance = 18750}, + {id = 22616, chance = 12500}, + {id = 22608, chance = 100000, unique = true}, + {id = 2152, chance = 93750, maxCount = 20}, + {id = 22611, chance = 6250}, + {id = 18420, chance = 6250, maxCount = 3}, + {id = 2214, chance = 6250}, + {id = 5741, chance = 6250}, + {id = 2645, chance = 6250}, + {id = 8473, chance = 31250, maxCount = 8}, + {id = 22598, chance = 81250, maxCount = 3}, + {id = 18414, chance = 18750, maxCount = 5} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 390, attack = 500}, + {name ="omrafir wave", interval = 2000, chance = 17, minDamage = -500, maxDamage = -1000, target = false}, + {name ="omrafir beam", interval = 2000, chance = 15, minDamage = -7000, maxDamage = -10000, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -1000, maxDamage = -3000, length = 10, spread = 3, effect = CONST_ME_FIREATTACK, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -400, radius = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 19, type = COMBAT_FIREDAMAGE, minDamage = -150, maxDamage = -300, radius = 4, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, radius = 1, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_HITBYFIRE, target = true}, + {name ="firefield", interval = 2000, chance = 12, radius = 3, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREATTACK, target = true} +} + +monster.defenses = { + defense = 165, + armor = 155, + {name ="combat", interval = 2000, chance = 22, type = COMBAT_HEALING, minDamage = 440, maxDamage = 800, target = false}, + {name ="omrafir summon", interval = 2000, chance = 50, target = false}, + {name ="omrafir healing 2", interval = 2000, chance = 20, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/roshamuul/prince_drazzak.lua b/data/monster/quests/roshamuul/prince_drazzak.lua new file mode 100644 index 00000000000..1583f4d73c6 --- /dev/null +++ b/data/monster/quests/roshamuul/prince_drazzak.lua @@ -0,0 +1,151 @@ +local mType = Game.createMonsterType("Prince Drazzak") +local monster = {} + +monster.description = "Prince Drazzak" +monster.experience = 210000 +monster.outfit = { + lookType = 12, + lookHead = 77, + lookBody = 78, + lookLegs = 94, + lookFeet = 54, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 330000 +monster.maxHealth = 330000 +monster.race = "fire" +monster.corpse = 6068 +monster.speed = 480 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 2000, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "EVEN WITH ALL THAT TIME IN THE PRISON THAT WEAKENED ME, YOU ARE NO MATCH TO ME!", yell = true}, + {text = "DIE!", yell = true}, + {text = "SORCERERS MUST DIE!", yell = true}, + {text = "DRUIDS MUST DIE!", yell = true}, + {text = "PALADINS MUST DIE!", yell = true}, + {text = "KNIGHTS MUST DIE!", yell = true}, + {text = "GET OVER HERE!", yell = true}, + {text = "CRUSH THEM ALL!", yell = true}, + {text = "VARIPHOR WILL RULE!", yell = true}, + {text = "THEY WILL ALL PAY!", yell = true}, + {text = "NOT EVEN AEONS OF IMPRISONMENT WILL STOP ME!", yell = true}, + {text = "They used you fools to escape and they left ME behind!!??", yell = false} +} + +monster.loot = { + {id = 22397, chance = 100000}, + {id = 22396, chance = 100000, maxCount = 2}, + {id = 22598, chance = 93750, maxCount = 3}, + {id = 6500, chance = 100000, maxCount = 2}, + {id = 5954, chance = 50000}, + {id = 2152, chance = 100000, maxCount = 50}, + {id = 8473, chance = 100000, maxCount = 100}, + {id = 8472, chance = 100000, maxCount = 100}, + {id = 7590, chance = 100000, maxCount = 100}, + {id = 22613, chance = 25000}, + {id = 22608, chance = 2500}, + {id = 22611, chance = 25000}, + {id = 22612, chance = 25000}, + {id = 5741, chance = 2500}, + {id = 7417, chance = 2500, unique = true}, + {id = 22610, chance = 7000, unique = true}, + {id = 7418, chance = 1000}, + {id = 7893, chance = 1000}, + {id = 7632, chance = 5000}, + {id = 7633, chance = 5000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 190, attack = 100}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_DEATHDAMAGE, minDamage = -1000, maxDamage = -3000, length = 8, spread = 3, effect = CONST_ME_MORTAREA, target = false} +} + +monster.defenses = { + defense = 65, + armor = 55, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 1500, maxDamage = 3000, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 30}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/roshamuul/terofar.lua b/data/monster/quests/roshamuul/terofar.lua new file mode 100644 index 00000000000..419f3f9e655 --- /dev/null +++ b/data/monster/quests/roshamuul/terofar.lua @@ -0,0 +1,140 @@ +local mType = Game.createMonsterType("Terofar") +local monster = {} + +monster.description = "Terofar" +monster.experience = 24000 +monster.outfit = { + lookType = 12, + lookHead = 19, + lookBody = 0, + lookLegs = 77, + lookFeet = 79, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 40000 +monster.maxHealth = 40000 +monster.race = "blood" +monster.corpse = 6068 +monster.speed = 440 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "IT TOOK AN ARMY OF YOUR KIND TO DEFEAT THE WARDEN. NOW YOU ARE ALONE!", yell = true}, + {text = "FEELS GOOD TO BE BACK IN ACTION!", yell = true}, + {text = "THE WARDS ARE FAILING! MY ESCAPE IS ONLY A MATTER OF TIME!!", yell = true}, + {text = "Terofar cast a greater death curse on you!", yell = true} +} + +monster.loot = { + {id = 22396, chance = 100000}, + {id = 22598, chance = 100000}, + {id = 22397, chance = 100000}, + {id = 6500, chance = 100000}, + {id = 5954, chance = 100000}, + {id = 22610, chance = 3560}, + {id = 2148, chance = 100000, maxCount = 200}, + {id = 2152, chance = 100000, maxCount = 50}, + {id = 7590, chance = 33330, maxCount = 10}, + {id = 8473, chance = 3890, maxCount = 10}, + {id = 8472, chance = 2780, maxCount = 5}, + {id = 18413, chance = 22220, maxCount = 8}, + {id = 18414, chance = 33330, maxCount = 8}, + {id = 18415, chance = 44440, maxCount = 8}, + {id = 9971, chance = 16670}, + {id = 7632, chance = 38890}, + {id = 7633, chance = 38890}, + {id = 2520, chance = 11110}, + {id = 2515, chance = 22220}, + {id = 2519, chance = 11110}, + {id = 2514, chance = 960}, + {id = 8891, chance = 5560}, + {id = 8879, chance = 11110}, + {id = 8877, chance = 6110}, + {id = 2155, chance = 16670}, + {id = 2158, chance = 11110}, + {id = 8882, chance = 410}, + {id = 2472, chance = 610}, + {id = 2645, chance = 910}, + {id = 2498, chance = 910}, + {id = 7886, chance = 2910}, + {id = 2195, chance = 1910}, + {id = 5741, chance = 1910} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 180, attack = 100}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_DEATHDAMAGE, minDamage = -700, maxDamage = -1500, length = 8, spread = 3, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -750, range = 7, radius = 1, shootEffect = CONST_ANI_WHIRLWINDAXE, target = true} +} + +monster.defenses = { + defense = 65, + armor = 55, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_HEALING, minDamage = 300, maxDamage = 500, radius = 8, target = false}, + {name ="speed", interval = 2000, chance = 18, speedChange = 784, effect = CONST_ME_MAGIC_GREEN, target = false, duration = 7000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/soul_war/mirror_image.lua b/data/monster/quests/soul_war/mirror_image.lua new file mode 100644 index 00000000000..f5ad9a8584e --- /dev/null +++ b/data/monster/quests/soul_war/mirror_image.lua @@ -0,0 +1,135 @@ +local mType = Game.createMonsterType("Mirror Image") +local monster = {} + +monster.description = "a mirror image" +monster.experience = 0 +monster.outfit = { + lookType = 136, + lookHead = 76, + lookBody = 114, + lookLegs = 76, + lookFeet = 76, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 35000 +monster.maxHealth = 35000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 235 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Delusional!", yell = false}, + {text = "I'll be your worst nightmare", yell = true}, + {text = "The mirrors can't contain the night.", yell = true}, + {text = "What a lovely reflection.", yell = true} +} + +monster.loot = { +} + +monster.attacks = { + + {name ="combat", interval = 2000, chance = 13, type = COMBAT_ICEDAMAGE, minDamage = -450, maxDamage = -1100, range = 7, radius = 4, shootEffect = CONST_ANI_ICE, effect = CONST_ME_BIGCLOUDS, target = true}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_HOLYDAMAGE, minDamage = -450, maxDamage = -1000, radius = 4, effect = CONST_ME_HOLYAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HOLYDAMAGE, minDamage = -550, maxDamage = -1000, range = 7, shootEffect = CONST_ANI_HOLY, effect = CONST_ME_HOLYDAMAGE, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -450, maxDamage = -1000, range = 7, shootEffect = CONST_ANI_SMALLICE, effect = CONST_ME_ICEATTACK, target = true} + -- Chain: const_me-> CONST_ME_BLUE_ENERGY_SPARK, combat_t->COMBAT_ICEDAMAGE +} + +monster.defenses = { + defense = 75, + armor = 100 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +monster.events = { + "MirrorImageTransform" +} + +mType:register(monster) + +local mirrorImageTransform = CreatureEvent("MirrorImageTransform") + +function mirrorImageTransform.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType) + if attacker:isPlayer() then + local newForm = nil + if attacker:isSorcerer() then + newForm = "Sorcerer's Apparition" + elseif attacker:isDruid() then + newForm = "Druid's Apparition" + elseif attacker:isPaladin() then + newForm = "Paladin's Apparition" + elseif attacker:isKnight() then + newForm = "Knight's Apparition" + end + if newForm then + creature:setType(newForm) + end + end + return primaryDamage, primaryType, secondaryDamage, secondaryType +end + +mirrorImageTransform:register() diff --git a/data/monster/quests/svargrond_arena/greenhorn/achad.lua b/data/monster/quests/svargrond_arena/greenhorn/achad.lua new file mode 100644 index 00000000000..1e712ea52d9 --- /dev/null +++ b/data/monster/quests/svargrond_arena/greenhorn/achad.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Achad") +local monster = {} + +monster.description = "Achad" +monster.experience = 70 +monster.outfit = { + lookType = 146, + lookHead = 93, + lookBody = 93, + lookLegs = 57, + lookFeet = 97, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 185 +monster.maxHealth = 185 +monster.race = "blood" +monster.corpse = 7349 +monster.speed = 185 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 55, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You won't pass me.", yell = false}, + {text = "I have travelled far to fight here.", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -80} +} + +monster.defenses = { + defense = 19, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/greenhorn/axeitus_headbanger.lua b/data/monster/quests/svargrond_arena/greenhorn/axeitus_headbanger.lua new file mode 100644 index 00000000000..09741904a8d --- /dev/null +++ b/data/monster/quests/svargrond_arena/greenhorn/axeitus_headbanger.lua @@ -0,0 +1,103 @@ +local mType = Game.createMonsterType("Axeitus Headbanger") +local monster = {} + +monster.description = "Axeitus Headbanger" +monster.experience = 140 +monster.outfit = { + lookType = 71, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 365 +monster.maxHealth = 365 +monster.race = "blood" +monster.corpse = 7349 +monster.speed = 80 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hicks!", yell = false}, + {text = "Stand still! Both of you! hicks", yell = false}, + {text = "This victory will earn me a casket of beer.", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -80}, + {name ="combat", interval = 1000, chance = 80, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -50, range = 5, radius = 1, shootEffect = CONST_ANI_SMALLSTONE, target = true} +} + +monster.defenses = { + defense = 0, + armor = 18 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/greenhorn/bloodpaw.lua b/data/monster/quests/svargrond_arena/greenhorn/bloodpaw.lua new file mode 100644 index 00000000000..724e4dfb009 --- /dev/null +++ b/data/monster/quests/svargrond_arena/greenhorn/bloodpaw.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Bloodpaw") +local monster = {} + +monster.description = "Bloodpaw" +monster.experience = 50 +monster.outfit = { + lookType = 42, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 100 +monster.maxHealth = 100 +monster.race = "blood" +monster.corpse = 7349 +monster.speed = 156 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -40} +} + +monster.defenses = { + defense = 8, + armor = 3 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/greenhorn/bovinus.lua b/data/monster/quests/svargrond_arena/greenhorn/bovinus.lua new file mode 100644 index 00000000000..05893eaae39 --- /dev/null +++ b/data/monster/quests/svargrond_arena/greenhorn/bovinus.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Bovinus") +local monster = {} + +monster.description = "Bovinus" +monster.experience = 60 +monster.outfit = { + lookType = 25, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 150 +monster.maxHealth = 150 +monster.race = "blood" +monster.corpse = 7349 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -50} +} + +monster.defenses = { + defense = 11, + armor = 9 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/greenhorn/colerian_the_barbarian.lua b/data/monster/quests/svargrond_arena/greenhorn/colerian_the_barbarian.lua new file mode 100644 index 00000000000..19a53a82a97 --- /dev/null +++ b/data/monster/quests/svargrond_arena/greenhorn/colerian_the_barbarian.lua @@ -0,0 +1,103 @@ +local mType = Game.createMonsterType("Colerian The Barbarian") +local monster = {} + +monster.description = "Colerian the Barbarian" +monster.experience = 90 +monster.outfit = { + lookType = 253, + lookHead = 76, + lookBody = 115, + lookLegs = 115, + lookFeet = 43, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 265 +monster.maxHealth = 265 +monster.race = "blood" +monster.corpse = 7349 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Flee, coward!", yell = false}, + {text = "You will lose!", yell = false}, + {text = "Yeehaawh", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -60}, + {name ="combat", interval = 1000, chance = 80, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -40, range = 5, radius = 1, shootEffect = CONST_ANI_PIERCINGBOLT, target = true} +} + +monster.defenses = { + defense = 0, + armor = 8 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/greenhorn/cursed_gladiator.lua b/data/monster/quests/svargrond_arena/greenhorn/cursed_gladiator.lua new file mode 100644 index 00000000000..392b4b4f891 --- /dev/null +++ b/data/monster/quests/svargrond_arena/greenhorn/cursed_gladiator.lua @@ -0,0 +1,102 @@ +local mType = Game.createMonsterType("Cursed Gladiator") +local monster = {} + +monster.description = "a cursed gladiator" +monster.experience = 215 +monster.outfit = { + lookType = 100, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 435 +monster.maxHealth = 435 +monster.race = "undead" +monster.corpse = 7349 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Death where are you?", yell = false}, + {text = "Slay me, end my curse.", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150}, + {name ="combat", interval = 4000, chance = 50, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = 50, range = 5, radius = 1, effect = CONST_ME_MAGIC_RED, target = true} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/greenhorn/frostfur.lua b/data/monster/quests/svargrond_arena/greenhorn/frostfur.lua new file mode 100644 index 00000000000..3a8b60181de --- /dev/null +++ b/data/monster/quests/svargrond_arena/greenhorn/frostfur.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Frostfur") +local monster = {} + +monster.description = "Frostfur" +monster.experience = 35 +monster.outfit = { + lookType = 52, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 65 +monster.maxHealth = 65 +monster.race = "blood" +monster.corpse = 7349 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -30} +} + +monster.defenses = { + defense = 3, + armor = 2 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/greenhorn/orcus_the_cruel.lua b/data/monster/quests/svargrond_arena/greenhorn/orcus_the_cruel.lua new file mode 100644 index 00000000000..377e3926672 --- /dev/null +++ b/data/monster/quests/svargrond_arena/greenhorn/orcus_the_cruel.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Orcus the Cruel") +local monster = {} + +monster.description = "Orcus the cruel" +monster.experience = 280 +monster.outfit = { + lookType = 59, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 480 +monster.maxHealth = 480 +monster.race = "blood" +monster.corpse = 7349 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -180}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -70, range = 5, radius = 1, shootEffect = CONST_ANI_THROWINGKNIFE, target = true} +} + +monster.defenses = { + defense = 40, + armor = 39 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -20}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/greenhorn/rocky.lua b/data/monster/quests/svargrond_arena/greenhorn/rocky.lua new file mode 100644 index 00000000000..50edda777ce --- /dev/null +++ b/data/monster/quests/svargrond_arena/greenhorn/rocky.lua @@ -0,0 +1,102 @@ +local mType = Game.createMonsterType("Rocky") +local monster = {} + +monster.description = "Rocky" +monster.experience = 190 +monster.outfit = { + lookType = 95, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 390 +monster.maxHealth = 390 +monster.race = "undead" +monster.corpse = 7349 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Another little gladiator!", yell = false}, + {text = "Come into my embrace.", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -80} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_HEALING, minDamage = 15, maxDamage = 35, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/greenhorn/the_hairy_one.lua b/data/monster/quests/svargrond_arena/greenhorn/the_hairy_one.lua new file mode 100644 index 00000000000..2c0244c934c --- /dev/null +++ b/data/monster/quests/svargrond_arena/greenhorn/the_hairy_one.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("The Hairy One") +local monster = {} + +monster.description = "The Hairy One" +monster.experience = 115 +monster.outfit = { + lookType = 116, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 325 +monster.maxHealth = 325 +monster.race = "blood" +monster.corpse = 7349 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hugah!", yell = false}, + {text = "Ungh! Ungh!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -70} +} + +monster.defenses = { + defense = 0, + armor = 16 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/scrapper/avalanche.lua b/data/monster/quests/svargrond_arena/scrapper/avalanche.lua new file mode 100644 index 00000000000..6d4a6e06ade --- /dev/null +++ b/data/monster/quests/svargrond_arena/scrapper/avalanche.lua @@ -0,0 +1,104 @@ +local mType = Game.createMonsterType("Avalanche") +local monster = {} + +monster.description = "Avalanche" +monster.experience = 305 +monster.outfit = { + lookType = 261, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 550 +monster.maxHealth = 550 +monster.race = "undead" +monster.corpse = 7349 +monster.speed = 195 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You will pay for imprisoning me here.", yell = false}, + {text = "Puny warmblood.", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -180}, + {name ="combat", interval = 1000, chance = 100, type = COMBAT_DROWNDAMAGE, minDamage = -10, maxDamage = -50, length = 5, spread = 6, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="speed", interval = 4000, chance = 100, speedChange = -400, radius = 3, effect = CONST_ME_POFF, target = false, duration = 10000}, + {name ="combat", interval = 6000, chance = 100, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -40, range = 5, radius = 1, shootEffect = CONST_ANI_LARGEROCK, target = true} +} + +monster.defenses = { + defense = 27, + armor = 26 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/scrapper/drasilla.lua b/data/monster/quests/svargrond_arena/scrapper/drasilla.lua new file mode 100644 index 00000000000..f6bb83e16b1 --- /dev/null +++ b/data/monster/quests/svargrond_arena/scrapper/drasilla.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Drasilla") +local monster = {} + +monster.description = "Drasilla" +monster.experience = 700 +monster.outfit = { + lookType = 34, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1260 +monster.maxHealth = 1260 +monster.race = "blood" +monster.corpse = 7349 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 100, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "FCHHHHHHHH!", yell = false}, + {text = "GROOOOAAAAAAAAR!", yell = false}, + {text = "DIRTY LITTLE HUMANS", yell = false}, + {text = "YOU CAN'T KEEP ME HERE FOREVER", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -120}, + {name ="combat", interval = 6000, chance = 60, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -180, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 3000, chance = 50, type = COMBAT_FIREDAMAGE, minDamage = -70, maxDamage = -115, range = 10, radius = 5, effect = CONST_ME_FIREAREA, target = true} +} + +monster.defenses = { + defense = 33, + armor = 32, + {name ="combat", interval = 6000, chance = 65, type = COMBAT_HEALING, minDamage = 20, maxDamage = 50, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/scrapper/grimgor_guteater.lua b/data/monster/quests/svargrond_arena/scrapper/grimgor_guteater.lua new file mode 100644 index 00000000000..ad02ea60dbf --- /dev/null +++ b/data/monster/quests/svargrond_arena/scrapper/grimgor_guteater.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Grimgor Guteater") +local monster = {} + +monster.description = "Grimgor Guteater" +monster.experience = 670 +monster.outfit = { + lookType = 2, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1115 +monster.maxHealth = 1115 +monster.race = "blood" +monster.corpse = 7349 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Dont run, You're burning off precious fat.", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -230}, + {name ="combat", interval = 4000, chance = 60, type = COMBAT_PHYSICALDAMAGE, minDamage = -55, maxDamage = -130, shootEffect = CONST_ANI_THROWINGSTAR, target = false} +} + +monster.defenses = { + defense = 45, + armor = 45 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -1} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/scrapper/kreebosh_the_exile.lua b/data/monster/quests/svargrond_arena/scrapper/kreebosh_the_exile.lua new file mode 100644 index 00000000000..3c02a7c37ee --- /dev/null +++ b/data/monster/quests/svargrond_arena/scrapper/kreebosh_the_exile.lua @@ -0,0 +1,110 @@ +local mType = Game.createMonsterType("Kreebosh the Exile") +local monster = {} + +monster.description = "Kreebosh the Exile" +monster.experience = 350 +monster.outfit = { + lookType = 103, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 705 +monster.maxHealth = 705 +monster.race = "blood" +monster.corpse = 7349 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Green Djinn", chance = 20, interval = 5000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I bet you wish you weren't here.", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="combat", interval = 6000, chance = 80, type = COMBAT_FIREDAMAGE, minDamage = 0, maxDamage = -120, radius = 3, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="speed", interval = 3500, chance = 35, speedChange = -450, range = 5, radius = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 20000}, + {name ="combat", interval = 6000, chance = 40, type = COMBAT_PHYSICALDAMAGE, minDamage = -20, maxDamage = -100, range = 5, radius = 1, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 5000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -40, maxDamage = -200, range = 5, radius = 1, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_FIREAREA, target = true}, + {name ="drunk", interval = 1000, chance = 20, range = 5, radius = 1, target = true, duration = 30000}, + {name ="outfit", interval = 2000, chance = 50, range = 5, radius = 1, effect = CONST_ME_MAGIC_GREEN, target = true, duration = 60000, outfitMonster = "Rat"} +} + +monster.defenses = { + defense = 40, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 55}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -1} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/scrapper/slim.lua b/data/monster/quests/svargrond_arena/scrapper/slim.lua new file mode 100644 index 00000000000..60452688ef6 --- /dev/null +++ b/data/monster/quests/svargrond_arena/scrapper/slim.lua @@ -0,0 +1,102 @@ +local mType = Game.createMonsterType("Slim") +local monster = {} + +monster.description = "Slim" +monster.experience = 580 +monster.outfit = { + lookType = 101, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1025 +monster.maxHealth = 1025 +monster.race = "undead" +monster.corpse = 7349 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Zhroozzzzs.", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150}, + {name ="poisonfield", interval = 1000, chance = 50, shootEffect = CONST_ANI_POISON, target = false}, + {name ="combat", interval = 3049, chance = 40, type = COMBAT_PHYSICALDAMAGE, minDamage = -10, maxDamage = -50, effect = CONST_ME_HITAREA, target = false} +} + +monster.defenses = { + defense = 38, + armor = 36 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/scrapper/spirit_of_earth.lua b/data/monster/quests/svargrond_arena/scrapper/spirit_of_earth.lua new file mode 100644 index 00000000000..e65dd126a62 --- /dev/null +++ b/data/monster/quests/svargrond_arena/scrapper/spirit_of_earth.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Spirit of Earth") +local monster = {} + +monster.description = "a spirit of earth" +monster.experience = 800 +monster.outfit = { + lookType = 67, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1200 +monster.maxHealth = 1200 +monster.race = "undead" +monster.corpse = 7349 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Show your strengh ... or perish.", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -180} +} + +monster.defenses = { + defense = 0, + armor = 0 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/scrapper/spirit_of_fire.lua b/data/monster/quests/svargrond_arena/scrapper/spirit_of_fire.lua new file mode 100644 index 00000000000..4ba48c45147 --- /dev/null +++ b/data/monster/quests/svargrond_arena/scrapper/spirit_of_fire.lua @@ -0,0 +1,102 @@ +local mType = Game.createMonsterType("Spirit of Fire") +local monster = {} + +monster.description = "a spirit of fire" +monster.experience = 950 +monster.outfit = { + lookType = 242, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2210 +monster.maxHealth = 2210 +monster.race = "blood" +monster.corpse = 7349 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Feel the heat.", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + {name ="firefield", interval = 1000, chance = 15, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -650, maxDamage = -315, range = 7, shootEffect = CONST_ANI_FIRE, target = false} +} + +monster.defenses = { + defense = 0, + armor = 0 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -1}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/scrapper/spirit_of_water.lua b/data/monster/quests/svargrond_arena/scrapper/spirit_of_water.lua new file mode 100644 index 00000000000..5de1d3de3d9 --- /dev/null +++ b/data/monster/quests/svargrond_arena/scrapper/spirit_of_water.lua @@ -0,0 +1,102 @@ +local mType = Game.createMonsterType("Spirit of Water") +local monster = {} + +monster.description = "a spirit of water" +monster.experience = 850 +monster.outfit = { + lookType = 11, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1400 +monster.maxHealth = 1400 +monster.race = "undead" +monster.corpse = 7349 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Blubb", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="poisonfield", interval = 1000, chance = 50, shootEffect = CONST_ANI_POISON, target = false}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_PHYSICALDAMAGE, minDamage = -1, maxDamage = -120, effect = CONST_ME_LOSEENERGY, target = false} +} + +monster.defenses = { + defense = 0, + armor = 0 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/scrapper/the_dark_dancer.lua b/data/monster/quests/svargrond_arena/scrapper/the_dark_dancer.lua new file mode 100644 index 00000000000..747759c5ec8 --- /dev/null +++ b/data/monster/quests/svargrond_arena/scrapper/the_dark_dancer.lua @@ -0,0 +1,110 @@ +local mType = Game.createMonsterType("The Dark Dancer") +local monster = {} + +monster.description = "The Dark Dancer" +monster.experience = 435 +monster.outfit = { + lookType = 58, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 805 +monster.maxHealth = 805 +monster.race = "blood" +monster.corpse = 7349 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Ghoul", chance = 20, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I hope you like my voice!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -45, condition = {type = CONDITION_POISON, totalDamage = 220, interval = 4000}}, + {name ="combat", interval = 3000, chance = 70, type = COMBAT_PHYSICALDAMAGE, minDamage = -60, maxDamage = -95, range = 5, radius = 1, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 6000, chance = 90, type = COMBAT_PHYSICALDAMAGE, minDamage = -60, maxDamage = -95, range = 5, radius = 1, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="speed", interval = 3500, chance = 35, speedChange = -400, range = 5, radius = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 10000}, + {name ="combat", interval = 4000, chance = 30, type = COMBAT_MANADRAIN, minDamage = -2, maxDamage = -110, range = 5, radius = 1, effect = CONST_ME_MAGIC_RED, target = true} +} + +monster.defenses = { + defense = 12, + armor = 11, + {name ="combat", interval = 2000, chance = 45, type = COMBAT_HEALING, minDamage = 75, maxDamage = 135, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 3000, chance = 50, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 40}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 1} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/scrapper/the_hag.lua b/data/monster/quests/svargrond_arena/scrapper/the_hag.lua new file mode 100644 index 00000000000..bcc2df6fde1 --- /dev/null +++ b/data/monster/quests/svargrond_arena/scrapper/the_hag.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("The Hag") +local monster = {} + +monster.description = "The Hag" +monster.experience = 510 +monster.outfit = { + lookType = 264, + lookHead = 78, + lookBody = 97, + lookLegs = 95, + lookFeet = 95, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 935 +monster.maxHealth = 935 +monster.race = "blood" +monster.corpse = 7349 +monster.speed = 205 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 5, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Ghost", chance = 26, interval = 2000}, + {name = "Crypt Shambler", chance = 26, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "If you think I am to old to fight then you're wrong!", yell = false}, + {text = "I've forgotten more things then you have ever learned!", yell = false}, + {text = "Let me teach you a few things youngster!", yell = false}, + {text = "I'll teach you respect for the old!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="drunk", interval = 3000, chance = 35, range = 5, radius = 1, target = true, duration = 15000}, + {name ="speed", interval = 4000, chance = 55, speedChange = -400, range = 5, radius = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 12000} +} + +monster.defenses = { + defense = 25, + armor = 24, + {name ="combat", interval = 2000, chance = 35, type = COMBAT_HEALING, minDamage = 95, maxDamage = 155, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 3000, chance = 50, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/warlord/darakan_the_executioner.lua b/data/monster/quests/svargrond_arena/warlord/darakan_the_executioner.lua new file mode 100644 index 00000000000..8bbb5ef1ab5 --- /dev/null +++ b/data/monster/quests/svargrond_arena/warlord/darakan_the_executioner.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("Darakan the Executioner") +local monster = {} + +monster.description = "Darakan the Executioner" +monster.experience = 1600 +monster.outfit = { + lookType = 255, + lookHead = 78, + lookBody = 114, + lookLegs = 114, + lookFeet = 114, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3480 +monster.maxHealth = 3480 +monster.race = "blood" +monster.corpse = 7349 +monster.speed = 205 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "FIGHT LIKE A BARBARIAN!", yell = true}, + {text = "VICTORY IS MINE!", yell = true}, + {text = "I AM your father!", yell = false}, + {text = "To be the man you have to beat the man!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -210}, + {name ="combat", interval = 1000, chance = 100, type = COMBAT_PHYSICALDAMAGE, minDamage = -72, maxDamage = -130, shootEffect = CONST_ANI_SPEAR, target = false} +} + +monster.defenses = { + defense = 31, + armor = 30, + {name ="combat", interval = 6000, chance = 65, type = COMBAT_HEALING, minDamage = 20, maxDamage = 50, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -1}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 1}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/warlord/deathbringer.lua b/data/monster/quests/svargrond_arena/warlord/deathbringer.lua new file mode 100644 index 00000000000..adb2dac9d4b --- /dev/null +++ b/data/monster/quests/svargrond_arena/warlord/deathbringer.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Deathbringer") +local monster = {} + +monster.description = "Deathbringer" +monster.experience = 5100 +monster.outfit = { + lookType = 231, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 8440 +monster.maxHealth = 8440 +monster.race = "undead" +monster.corpse = 7349 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "YOU FOOLS WILL PAY!", yell = true}, + {text = "YOU ALL WILL DIE!!", yell = true}, + {text = "DEATH, DESTRUCTION!", yell = true}, + {text = "I will eat your soul!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -465}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -80, maxDamage = -120, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="combat", interval = 3000, chance = 17, type = COMBAT_FIREDAMAGE, minDamage = -300, maxDamage = -450, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -450, length = 8, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -80, maxDamage = -100, radius = 6, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 3000, chance = 25, type = COMBAT_LIFEDRAIN, minDamage = -80, maxDamage = -150, range = 7, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = -15}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/warlord/fallen_mooh'tah_master_ghar.lua b/data/monster/quests/svargrond_arena/warlord/fallen_mooh'tah_master_ghar.lua new file mode 100644 index 00000000000..01ff4478f4f --- /dev/null +++ b/data/monster/quests/svargrond_arena/warlord/fallen_mooh'tah_master_ghar.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Fallen Mooh'tah Master Ghar") +local monster = {} + +monster.description = "Fallen Mooh'Tah Master Ghar" +monster.experience = 4400 +monster.outfit = { + lookType = 29, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 7990 +monster.maxHealth = 7990 +monster.race = "blood" +monster.corpse = 7349 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I will finish you!", yell = false}, + {text = "You are no match for a master of the Mooh'Tha!", yell = false}, + {text = "I might be fallen but you will fall before me!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -525, condition = {type = CONDITION_POISON, totalDamage = 18, interval = 4000}}, + {name ="combat", interval = 6000, chance = 30, type = COMBAT_FIREDAMAGE, minDamage = -80, maxDamage = -300, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 3000, chance = 45, type = COMBAT_FIREDAMAGE, minDamage = -80, maxDamage = -400, radius = 5, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="combat", interval = 4000, chance = 30, type = COMBAT_DEATHDAMAGE, minDamage = -80, maxDamage = -270, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_MORTAREA, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 4500, chance = 40, minDamage = -10, maxDamage = -200, range = 10, shootEffect = CONST_ANI_POISON, target = false}, + {name ="combat", interval = 5000, chance = 30, type = COMBAT_EARTHDAMAGE, minDamage = -60, maxDamage = -300, length = 8, spread = 3, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 33, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 60}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/warlord/gnorre_chyllson.lua b/data/monster/quests/svargrond_arena/warlord/gnorre_chyllson.lua new file mode 100644 index 00000000000..552daf73e9d --- /dev/null +++ b/data/monster/quests/svargrond_arena/warlord/gnorre_chyllson.lua @@ -0,0 +1,104 @@ +local mType = Game.createMonsterType("Gnorre Chyllson") +local monster = {} + +monster.description = "Gnorre Chyllson" +monster.experience = 4000 +monster.outfit = { + lookType = 251, + lookHead = 11, + lookBody = 9, + lookLegs = 11, + lookFeet = 85, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 7150 +monster.maxHealth = 7150 +monster.race = "blood" +monster.corpse = 7349 +monster.speed = 370 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I am like the merciless northwind.", yell = false}, + {text = "Snow will be your death shroud.", yell = false}, + {text = "Feel the wrath of father chyll!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -455}, + {name ="melee", interval = 3000, chance = 50, minDamage = -500, maxDamage = -800}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -170, maxDamage = -200, range = 7, shootEffect = CONST_ANI_SNOWBALL, target = false} +} + +monster.defenses = { + defense = 52, + armor = 51 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -1}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 1}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/warlord/norgle_glacierbeard.lua b/data/monster/quests/svargrond_arena/warlord/norgle_glacierbeard.lua new file mode 100644 index 00000000000..14498e2bd91 --- /dev/null +++ b/data/monster/quests/svargrond_arena/warlord/norgle_glacierbeard.lua @@ -0,0 +1,104 @@ +local mType = Game.createMonsterType("Norgle Glacierbeard") +local monster = {} + +monster.description = "Norgle Glacierbeard" +monster.experience = 2100 +monster.outfit = { + lookType = 257, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 4280 +monster.maxHealth = 4280 +monster.race = "blood" +monster.corpse = 7349 +monster.speed = 195 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I'll extinguish you warmbloods.", yell = false}, + {text = "REVENGE!", yell = false}, + {text = "Far too hot.", yell = false}, + {text = "DISGUSTING WARMBLOODS!", yell = false}, + {text = "Revenge is sweetest when served cold.", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -225} +} + +monster.defenses = { + defense = 27, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -1} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/warlord/svoren_the_mad.lua b/data/monster/quests/svargrond_arena/warlord/svoren_the_mad.lua new file mode 100644 index 00000000000..d8c4034208e --- /dev/null +++ b/data/monster/quests/svargrond_arena/warlord/svoren_the_mad.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("Svoren the Mad") +local monster = {} + +monster.description = "Svoren the Mad" +monster.experience = 3000 +monster.outfit = { + lookType = 254, + lookHead = 80, + lookBody = 99, + lookLegs = 118, + lookFeet = 38, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 6310 +monster.maxHealth = 6310 +monster.race = "blood" +monster.corpse = 7349 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "NO mommy NO. Leave me alone!", yell = false}, + {text = "Not that tower again!", yell = false}, + {text = "The cat has grown some horns!!", yell = false}, + {text = "What was I doing here again?", yell = false}, + {text = "Are we there soon mommy?", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -525}, + {name ="speed", interval = 3500, chance = 35, speedChange = -250, range = 1, radius = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 40} +} + +monster.defenses = { + defense = 27, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/warlord/the_masked_marauder.lua b/data/monster/quests/svargrond_arena/warlord/the_masked_marauder.lua new file mode 100644 index 00000000000..220b4893341 --- /dev/null +++ b/data/monster/quests/svargrond_arena/warlord/the_masked_marauder.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("The Masked Marauder") +local monster = {} + +monster.description = "The Masked Marauder" +monster.experience = 3500 +monster.outfit = { + lookType = 234, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 7320 +monster.maxHealth = 7320 +monster.race = "blood" +monster.corpse = 7349 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Didn't you leave your house door open?", yell = false}, + {text = "Oops, your shoelaces are open!", yell = false}, + {text = "Look! It's Ferumbras behind you!", yell = false}, + {text = "Stop! I give up!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -640}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_PHYSICALDAMAGE, minDamage = -38, maxDamage = -150, shootEffect = CONST_ANI_THROWINGKNIFE, target = false} +} + +monster.defenses = { + defense = 35, + armor = 25, + {name ="combat", interval = 1000, chance = 50, type = COMBAT_HEALING, minDamage = 75, maxDamage = 125, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -1}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/warlord/the_obliverator.lua b/data/monster/quests/svargrond_arena/warlord/the_obliverator.lua new file mode 100644 index 00000000000..a51cde69a8c --- /dev/null +++ b/data/monster/quests/svargrond_arena/warlord/the_obliverator.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("The Obliverator") +local monster = {} + +monster.description = "The Obliverator" +monster.experience = 6000 +monster.outfit = { + lookType = 35, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 9020 +monster.maxHealth = 9020 +monster.race = "fire" +monster.corpse = 7349 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "fire elemental", chance = 50, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "NO ONE WILL BEAT ME!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -700}, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -250, range = 5, radius = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 3000, chance = 30, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -500, length = 8, spread = 3, effect = CONST_ME_ENERGYHIT, target = false} +} + +monster.defenses = { + defense = 45, + armor = 40, + {name ="combat", interval = 4000, chance = 5, type = COMBAT_HEALING, minDamage = 50, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -1}, + {type = COMBAT_DEATHDAMAGE , percent = 1} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/warlord/the_pit_lord.lua b/data/monster/quests/svargrond_arena/warlord/the_pit_lord.lua new file mode 100644 index 00000000000..d4af3447a65 --- /dev/null +++ b/data/monster/quests/svargrond_arena/warlord/the_pit_lord.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("The Pit Lord") +local monster = {} + +monster.description = "The Pit Lord" +monster.experience = 2500 +monster.outfit = { + lookType = 55, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5270 +monster.maxHealth = 5270 +monster.race = "blood" +monster.corpse = 7349 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I'LL GET YOU ALL!", yell = true}, + {text = "I won't let you escape!", yell = false}, + {text = "I'll crush you beneath my feet!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -380}, + {name ="combat", interval = 7500, chance = 100, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -250, shootEffect = CONST_ANI_LARGEROCK, target = false} +} + +monster.defenses = { + defense = 44, + armor = 46, + {name ="speed", interval = 5000, chance = 100, speedChange = 500, effect = CONST_ME_MAGIC_RED, target = false, duration = 2500}, + {name ="combat", interval = 6000, chance = 65, type = COMBAT_HEALING, minDamage = 20, maxDamage = 50, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 1}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -1}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/svargrond_arena/warlord/webster.lua b/data/monster/quests/svargrond_arena/warlord/webster.lua new file mode 100644 index 00000000000..7ae083f19af --- /dev/null +++ b/data/monster/quests/svargrond_arena/warlord/webster.lua @@ -0,0 +1,104 @@ +local mType = Game.createMonsterType("Webster") +local monster = {} + +monster.description = "Webster" +monster.experience = 1200 +monster.outfit = { + lookType = 263, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2950 +monster.maxHealth = 2950 +monster.race = "undead" +monster.corpse = 7349 +monster.speed = 290 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You are lost!", yell = false}, + {text = "Come my little morsel.", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250}, + {name ="speed", interval = 3500, chance = 65, speedChange = -500, range = 1, radius = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 40}, + {name ="combat", interval = 3000, chance = 75, type = COMBAT_ENERGYDAMAGE, minDamage = -13, maxDamage = -80, range = 7, shootEffect = CONST_ANI_ENERGY, target = false} +} + +monster.defenses = { + defense = 34, + armor = 29, + {name ="speed", interval = 5000, chance = 100, speedChange = 500, effect = CONST_ME_MAGIC_RED, target = false, duration = 2500} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -20}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_curse_spreads/black_vixen.lua b/data/monster/quests/the_curse_spreads/black_vixen.lua new file mode 100644 index 00000000000..a58d56bebc7 --- /dev/null +++ b/data/monster/quests/the_curse_spreads/black_vixen.lua @@ -0,0 +1,153 @@ +local mType = Game.createMonsterType("Black Vixen") +local monster = {} + +monster.description = "a black vixen" +monster.experience = 3200 +monster.outfit = { + lookType = 1038, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3200 +monster.maxHealth = 3200 +monster.race = "blood" +monster.corpse = 32057 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 3, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "werefox", chance = 20, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You are not clever enough to defeat me!", yell = false}, + {text = "The slyness of foxes will deceive the unwary!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 13600000, maxCount = 100}, + {name = "gold coin", chance = 13600000, maxCount = 100}, + {name = "platinum coin", chance = 13600000, maxCount = 10}, + {name = "assassin star", chance = 13600000, maxCount = 9}, + {name = "black pearl", chance = 13600000, maxCount = 2}, + {name = "great mana potion", chance = 13600000, maxCount = 2}, + {name = "great spirit potion", chance = 13600000, maxCount = 2}, + {name = "small enchanted emerald", chance = 13600000, maxCount = 2}, + {name = "ultimate mana potion", chance = 13600000, maxCount = 2}, + {name = "ultimate spirit potion", chance = 13600000, maxCount = 2}, + {name = "fox paw", chance = 13600000, maxCount = 2}, + {name = "moonlight rod", chance = 13600000}, + {name = "stealth ring", chance = 13600000}, + {name = "werefox tail", chance = 13600000}, + {name = "green gem", chance = 400}, + {name = "troll green", chance = 400}, + {name = "werewolf amulet", chance = 400}, + {name = "composite hornbow", chance = 250}, + {name = "sai", chance = 250}, + {name = "silver token", chance = 250}, + {id = 30941, chance = 250}, + {name = "foxtail", chance = 100}, + {name = "wolf backpack", chance = 100}, + {name = "silver token", chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -290}, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 100, maxDamage = 720, range = 7, shootEffect = CONST_ANI_THROWINGSTAR, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -600, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000}, + {name ="combat", interval = 1000, chance = 14, type = COMBAT_DEATHDAMAGE, minDamage = -100, maxDamage = -700, length = 5, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="outfit", interval = 1000, chance = 1, radius = 1, target = true, duration = 2000, outfitMonster = "werewolf"} +} + +monster.defenses = { + defense = 45, + armor = 40, + {name ="combat", interval = 4000, chance = 15, type = COMBAT_HEALING, minDamage = 150, maxDamage = 345, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -40}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_curse_spreads/bloodback.lua b/data/monster/quests/the_curse_spreads/bloodback.lua new file mode 100644 index 00000000000..f0ccf4910da --- /dev/null +++ b/data/monster/quests/the_curse_spreads/bloodback.lua @@ -0,0 +1,146 @@ +local mType = Game.createMonsterType("Bloodback") +local monster = {} + +monster.description = "a Bloodback" +monster.experience = 4000 +monster.outfit = { + lookType = 1039, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5200 +monster.maxHealth = 5200 +monster.race = "blood" +monster.corpse = 32061 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Wereboar", chance = 20, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You will DIE!", yell = false}, + {text = "The ruthlessness of boars will stamp down the careless!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 13600000, maxCount = 100}, + {name = "gold coin", chance = 13600000, maxCount = 100}, + {name = "platinum coin", chance = 13600000, maxCount = 10}, + {name = "great health potion", chance = 13600000, maxCount = 10}, + {name = "red crystal fragment", chance = 13600000, maxCount = 2}, + {name = "small enchanted ruby", chance = 13600000, maxCount = 3}, + {name = "furry club", chance = 13600000}, + {name = "red gem", chance = 13600000}, + {name = "spiked squelcher", chance = 13600000}, + {name = "stone skin amulet", chance = 13600000}, + {name = "wereboar hooves", chance = 13600000, maxCount = 2}, + {name = "wereboar loincloth", chance = 13600000, maxCount = 2}, + {name = "wereboar tusks", chance = 13600000, maxCount = 2}, + {name = "dreaded cleaver", chance = 400}, + {name = "fur armor", chance = 400}, + {name = "fur boots", chance = 400}, + {id = 24758, chance = 250}, + {name = "silver token", chance = 250}, + {name = "wolf backpack", chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -290}, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -420, range = 7, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -600, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000}, + {name ="combat", interval = 1000, chance = 14, type = COMBAT_DEATHDAMAGE, minDamage = -100, maxDamage = -200, length = 5, spread = 3, target = false} +} + +monster.defenses = { + defense = 45, + armor = 40, + {name ="combat", interval = 4000, chance = 15, type = COMBAT_HEALING, minDamage = 150, maxDamage = 345, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 70}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_curse_spreads/darkfang.lua b/data/monster/quests/the_curse_spreads/darkfang.lua new file mode 100644 index 00000000000..75f1d26f81c --- /dev/null +++ b/data/monster/quests/the_curse_spreads/darkfang.lua @@ -0,0 +1,149 @@ +local mType = Game.createMonsterType("Darkfang") +local monster = {} + +monster.description = "a darkfang" +monster.experience = 4000 +monster.outfit = { + lookType = 308, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 4800 +monster.maxHealth = 4800 +monster.race = "blood" +monster.corpse = 20380 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Gloom Wolf", chance = 20, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "The ferocity of wolves will frighten the fearful! Roarrr!", yell = false}, + {text = "You are my next meal! Grrr!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 13600000, maxCount = 100}, + {name = "gold coin", chance = 13600000, maxCount = 100}, + {name = "platinum coin", chance = 13600000, maxCount = 10}, + {name = "berserk potion", chance = 13600000, maxCount = 3}, + {name = "black pearl", chance = 13600000, maxCount = 3}, + {name = "onyx chip", chance = 13600000, maxCount = 5}, + {name = "small enchanted sapphire", chance = 13600000, maxCount = 10}, + {name = "ultimate health potion", chance = 13600000, maxCount = 5}, + {name = "platinum amulet", chance = 13600000}, + {name = "stone skin amulet", chance = 13600000}, + {id = 2169, chance = 13600000}, + {name = "troll green", chance = 13600000, maxCount = 2}, + {name = "werewolf fur", chance = 13600000, maxCount = 2}, + {name = "wolf paw", chance = 13600000, maxCount = 2}, + {name = "bonebreaker", chance = 400}, + {name = "dreaded cleaver", chance = 400}, + {name = "werewolf amulet", chance = 400}, + {name = "sai", chance = 250}, + {id = 7394, chance = 13600000}, + {name = "silver token", chance = 250}, + {name = "wolf backpack", chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -290}, + {name ="werewolf skill reducer", interval = 2000, chance = 15, range = 1, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -100, maxDamage = -300, radius = 8, effect = CONST_ME_SOUND_RED, target = false}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_PHYSICALDAMAGE, minDamage = 200, maxDamage = 340, radius = 3, effect = CONST_ME_GROUNDSHAKER, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -600, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000} +} + +monster.defenses = { + defense = 45, + armor = 40, + {name ="combat", interval = 4000, chance = 15, type = COMBAT_HEALING, minDamage = 150, maxDamage = 345, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_curse_spreads/feroxa.lua b/data/monster/quests/the_curse_spreads/feroxa.lua new file mode 100644 index 00000000000..37e876c9d61 --- /dev/null +++ b/data/monster/quests/the_curse_spreads/feroxa.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Feroxa") +local monster = {} + +monster.description = "Feroxa" +monster.experience = 0 +monster.outfit = { + lookType = 158, + lookHead = 57, + lookBody = 76, + lookLegs = 77, + lookFeet = 57, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 100000 +monster.maxHealth = 100000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 2 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "FeroxaTransform" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -1400, maxDamage = -1800}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -700, maxDamage = -1250, radius = 6, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_MANADRAIN, minDamage = -700, maxDamage = -1250, radius = 5, effect = CONST_ME_ICETORNADO, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -700, maxDamage = -1250, range = 6, shootEffect = CONST_ANI_ARROW, effect = CONST_ME_EXPLOSIONAREA, target = true} +} + +monster.defenses = { + defense = 55, + armor = 50, + {name ="speed", interval = 2000, chance = 12, speedChange = 1250, effect = CONST_ME_THUNDER, target = false, duration = 10000}, + {name ="feroxa summon", interval = 2000, chance = 20, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 30}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_curse_spreads/feroxa2.lua b/data/monster/quests/the_curse_spreads/feroxa2.lua new file mode 100644 index 00000000000..617110df775 --- /dev/null +++ b/data/monster/quests/the_curse_spreads/feroxa2.lua @@ -0,0 +1,110 @@ +local mType = Game.createMonsterType("Feroxa2") +local monster = {} + +monster.name = "Feroxa" +monster.description = "Feroxa" +monster.experience = 0 +monster.outfit = { + lookType = 731, + lookHead = 57, + lookBody = 76, + lookLegs = 77, + lookFeet = 57, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 2 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "FeroxaTransform" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -1400, maxDamage = -1800}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -700, maxDamage = -1050, radius = 6, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_MANADRAIN, minDamage = -700, maxDamage = -1250, length = 9, spread = 1, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -450, maxDamage = -700, radius = 7, effect = CONST_ME_BLOCKHIT, target = false} +} + +monster.defenses = { + defense = 55, + armor = 50, + {name ="speed", interval = 2000, chance = 12, speedChange = 1250, effect = CONST_ME_MAGIC_RED, target = false, duration = 10000}, + {name ="outfit", interval = 2000, chance = 20, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 5000, outfitMonster = "were wolf"}, + {name ="feroxa summon", interval = 2000, chance = 20, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_curse_spreads/feroxa3.lua b/data/monster/quests/the_curse_spreads/feroxa3.lua new file mode 100644 index 00000000000..f71778f32be --- /dev/null +++ b/data/monster/quests/the_curse_spreads/feroxa3.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("Feroxa3") +local monster = {} + +monster.name = "Feroxa" +monster.description = "Feroxa" +monster.experience = 0 +monster.outfit = { + lookType = 158, + lookHead = 57, + lookBody = 76, + lookLegs = 77, + lookFeet = 57, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 130000 +monster.maxHealth = 130000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 2 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "feroxaDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -1400, maxDamage = -1800}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -700, maxDamage = -1250, radius = 6, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_MANADRAIN, minDamage = -700, maxDamage = -1250, length = 9, spread = 1, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -700, maxDamage = -1250, range = 6, shootEffect = CONST_ANI_ARROW, effect = CONST_ME_EXPLOSIONAREA, target = true} +} + +monster.defenses = { + defense = 55, + armor = 50, + {name ="speed", interval = 2000, chance = 12, speedChange = 1250, effect = CONST_ME_MAGIC_RED, target = false, duration = 10000}, + {name ="feroxa summon", interval = 2000, chance = 20, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 30}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_curse_spreads/feroxa4.lua b/data/monster/quests/the_curse_spreads/feroxa4.lua new file mode 100644 index 00000000000..d8542643186 --- /dev/null +++ b/data/monster/quests/the_curse_spreads/feroxa4.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("Feroxa4") +local monster = {} + +monster.name = "Feroxa" +monster.description = "Feroxa" +monster.experience = 0 +monster.outfit = { + lookType = 716, + lookHead = 57, + lookBody = 76, + lookLegs = 77, + lookFeet = 57, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 130000 +monster.maxHealth = 130000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 2 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "feroxaDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -1400, maxDamage = -1800}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -700, maxDamage = -1250, radius = 6, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_MANADRAIN, minDamage = -700, maxDamage = -1250, length = 9, spread = 1, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -700, maxDamage = -1250, range = 6, shootEffect = CONST_ANI_ARROW, effect = CONST_ME_EXPLOSIONAREA, target = true} +} + +monster.defenses = { + defense = 55, + armor = 50, + {name ="speed", interval = 2000, chance = 12, speedChange = 1250, effect = CONST_ME_MAGIC_RED, target = false, duration = 10000}, + {name ="feroxa summon", interval = 2000, chance = 20, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 30}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_curse_spreads/feroxa5.lua b/data/monster/quests/the_curse_spreads/feroxa5.lua new file mode 100644 index 00000000000..f599023e840 --- /dev/null +++ b/data/monster/quests/the_curse_spreads/feroxa5.lua @@ -0,0 +1,141 @@ +local mType = Game.createMonsterType("Feroxa5") +local monster = {} + +monster.name = "Feroxa" +monster.description = "Feroxa" +monster.experience = 0 +monster.outfit = { + lookType = 731, + lookHead = 57, + lookBody = 76, + lookLegs = 77, + lookFeet = 57, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 150000 +monster.maxHealth = 150000 +monster.race = "blood" +monster.corpse = 24745 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 2 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 18413, chance = 10000, maxCount = 5}, + {id = 18414, chance = 10000, maxCount = 5}, + {id = 18418, chance = 10000, maxCount = 5}, + {id = 2158, chance = 2500}, + {id = 2156, chance = 2500}, + {id = 2195, chance = 1500}, + {id = 2152, chance = 100000, maxCount = 50}, + {id = 8473, chance = 10000, maxCount = 5}, + {id = 7590, chance = 10000, maxCount = 5}, + {id = 7591, chance = 10000, maxCount = 5}, + {id = 24718, chance = 10000, unique = true}, + {id = 24716, chance = 1500}, + {id = 24740, chance = 1500}, + {id = 7436, chance = 1500}, + {id = 7419, chance = 1500}, + {id = 24741, chance = 1500}, + {id = 24742, chance = 1500}, + {id = 24760, chance = 12000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -1400, maxDamage = -1800}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -700, maxDamage = -1050, radius = 6, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_MANADRAIN, minDamage = -700, maxDamage = -1250, length = 9, spread = 1, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -450, maxDamage = -700, radius = 7, effect = CONST_ME_BLOCKHIT, target = false} +} + +monster.defenses = { + defense = 55, + armor = 50, + {name ="speed", interval = 2000, chance = 12, speedChange = 1250, effect = CONST_ME_MAGIC_RED, target = false, duration = 10000}, + {name ="feroxa summon", interval = 2000, chance = 20, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_curse_spreads/shadowpelt.lua b/data/monster/quests/the_curse_spreads/shadowpelt.lua new file mode 100644 index 00000000000..7652926c2b9 --- /dev/null +++ b/data/monster/quests/the_curse_spreads/shadowpelt.lua @@ -0,0 +1,150 @@ +local mType = Game.createMonsterType("Shadowpelt") +local monster = {} + +monster.description = "a shadowpelt" +monster.experience = 4000 +monster.outfit = { + lookType = 1040, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5000 +monster.maxHealth = 5000 +monster.race = "blood" +monster.corpse = 32065 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 2000, + chance = 11 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Werebear", chance = 20, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "The strength of bears will subdue the weak!", yell = false}, + {text = "It was a mistake to enter my cave!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 13600000, maxCount = 200}, + {name = "gold coin", chance = 13600000, maxCount = 100}, + {name = "platinum coin", chance = 13600000, maxCount = 5}, + {name = "black pearl", chance = 13600000, maxCount = 2}, + {name = "ham", chance = 13600000, maxCount = 2}, + {name = "opal", chance = 13600000, maxCount = 2}, + {name = "small enchanted sapphire", chance = 13600000, maxCount = 2}, + {name = "bear paw", chance = 13600000, maxCount = 2}, + {name = "furry club", chance = 13600000}, + {id = 281, chance = 5000}, + {name = "great health potion", chance = 13600000, maxCount = 5}, + {name = "honeycomb", chance = 13600000, maxCount = 2}, + {name = "spiked squelcher", chance = 13600000}, + {name = "ultimate health potion", chance = 13600000, maxCount = 5}, + {name = "werebear fur", chance = 13600000, maxCount = 2}, + {name = "werebear skull", chance = 13600000, maxCount = 2}, + {name = "dreaded cleaver", chance = 550}, + {name = "fur armor", chance = 550}, + {name = "relic sword", chance = 550}, + {name = "silver token", chance = 150}, + {id = 24759, chance = 150}, + {name = "wolf backpack", chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 50}, + {name ="combat", interval = 100, chance = 22, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -310, radius = 3, effect = CONST_ME_EXPLOSIONAREA, target = false}, + {name ="outfit", interval = 1000, chance = 1, radius = 1, target = true, duration = 2000, outfitMonster = "Werebear"}, + {name ="combat", interval = 100, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -100, maxDamage = -200, radius = 3, effect = CONST_ME_SOUND_WHITE, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 7, type = COMBAT_HEALING, minDamage = 120, maxDamage = 310, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 10, speedChange = 520, effect = CONST_ME_POFF, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_curse_spreads/sharpclaw.lua b/data/monster/quests/the_curse_spreads/sharpclaw.lua new file mode 100644 index 00000000000..72afb49f777 --- /dev/null +++ b/data/monster/quests/the_curse_spreads/sharpclaw.lua @@ -0,0 +1,148 @@ +local mType = Game.createMonsterType("Sharpclaw") +local monster = {} + +monster.description = "a sharpclaw" +monster.experience = 3000 +monster.outfit = { + lookType = 1031, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3300 +monster.maxHealth = 3300 +monster.race = "blood" +monster.corpse = 24723 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Werebadger", chance = 20, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "The toughness of badgers will outlast the hostile!", yell = false}, + {text = "Never underestimate a badger!", yell = false} +} + +monster.loot = { + {name = "Gold Coin", chance = 13600000, maxCount = 100}, + {name = "Gold Coin", chance = 13600000, maxCount = 100}, + {name = "Platinum Coin", chance = 13600000, maxCount = 10}, + {name = "Brown Mushroom", chance = 13600000, maxCount = 9}, + {name = "Onyx Chip", chance = 13600000, maxCount = 9}, + {name = "Small Enchanted Amethyst", chance = 13600000, maxCount = 9}, + {name = "Beetroot", chance = 13600000, maxCount = 9}, + {name = "Great Mana Potion", chance = 13600000, maxCount = 9}, + {name = "Platinum Amulet", chance = 13600000}, + {name = "Ring of Healing", chance = 13600000}, + {name = "Troll Green", chance = 13600000, maxCount = 9}, + {name = "Ultimate Mana Potion", chance = 13600000, maxCount = 9}, + {name = "Werebadger Claws", chance = 13600000, maxCount = 9}, + {name = "Werebadger Skull", chance = 13600000, maxCount = 9}, + {name = "Badger Boots", chance = 400}, + {name = "Underworld Rod", chance = 400}, + {name = "Wand of Voodoo", chance = 400}, + {name = "Wolf Backpack", chance = 250} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -290}, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 100, maxDamage = 720, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -600, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000}, + {name ="combat", interval = 1000, chance = 14, type = COMBAT_DEATHDAMAGE, minDamage = -100, maxDamage = -700, length = 5, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="outfit", interval = 1000, chance = 1, radius = 1, target = true, duration = 2000, outfitMonster = "Werebadger"}, + {name ="ghastly dragon curse", interval = 2000, chance = 5, range = 1, target = false} +} + +monster.defenses = { + defense = 45, + armor = 40, + {name ="combat", interval = 4000, chance = 15, type = COMBAT_HEALING, minDamage = 150, maxDamage = 345, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 70}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_dream_courts/bosses/alptramun.lua b/data/monster/quests/the_dream_courts/bosses/alptramun.lua new file mode 100644 index 00000000000..d571ad18f76 --- /dev/null +++ b/data/monster/quests/the_dream_courts/bosses/alptramun.lua @@ -0,0 +1,161 @@ +local mType = Game.createMonsterType("Alptramun") +local monster = {} + +monster.description = "Alptramun" +monster.experience = 55000 +monster.outfit = { + lookType = 1143, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 200000 +monster.maxHealth = 200000 +monster.race = "blood" +monster.corpse = 34793 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "silver token", chance = 100000000, maxCount = 5}, + {name = "skull staff", chance = 100000000, maxCount = 5}, + {name = "energy bar", chance = 100000000, maxCount = 5}, + {name = "Purple Tendril Lantern", chance = 100000000}, + {name = "crystal coin", chance = 100000000, maxCount = 2}, + {name = "blue gem", chance = 100000000}, + {name = "platinum coin", chance = 29580, maxCount = 5}, + {name = "supreme health potion", chance = 21540, maxCount = 20}, + {name = "ultimate spirit potion", chance = 22540, maxCount = 20}, + {name = "royal star", chance = 26540, maxCount = 100}, + {id = 7632, chance = 28540}, + {name = "Gold Token", chance = 15000, maxCount = 2}, + {name = "berserk potion", chance = 8050, maxCount = 10}, + {name = "bullseye potion", chance = 6780, maxCount = 10}, + {id = 26198, chance = 23520},-- collar of blue plasma + {id = 26200, chance = 10590}, + {name = "Gold Ingot", chance = 7630}, + {name = "Huge Chunk of Crude Iron", chance = 8900}, + {name = "Mysterious Remains", chance = 90000}, + {name = "Piggy Bank", chance = 13770, maxCount = 4}, + {name = "green gem", chance = 2740}, + {name = "red gem", chance = 2580}, + {name = "Crunor Idol", chance = 2640}, + {name = "Giant Ruby", chance = 2840}, + {name = "Magic Sulphur", chance = 2740}, + {name = "yellow gem", chance = 2900}, + {name = "mastermind potion", chance = 2900, maxCount = 10}, + {name = "violet gem", chance = 1500}, + {name = "Alptramun's Toothbrush", chance = 520}, + {name = "Dream Shroud", chance = 620}, + {name = "Pair of Dreamwalkers", chance = 720}, + {name = "Soul Stone", chance = 820}, + {id = 26185, chance = 10590}, + {name = "Pomegranate", chance = 880}, + {name = "Dream Shroud", chance = 980}, + {id = 26186, chance = 10590} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -190, maxDamage = -300, range = 7, length = 6, spread = 3, shootEffect = CONST_ANI_POISON, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -70, maxDamage = -160, range = 3, length = 6, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -90, maxDamage = -160, range = 3, length = 6, spread = 3, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="stone shower", interval = 2000, chance = 10, minDamage = -230, maxDamage = -450, range = 7, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.heals = { + {type = COMBAT_DEATHDAMAGE , percent = 500} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_dream_courts/bosses/faceless_bane.lua b/data/monster/quests/the_dream_courts/bosses/faceless_bane.lua new file mode 100644 index 00000000000..47bfc7cd9e2 --- /dev/null +++ b/data/monster/quests/the_dream_courts/bosses/faceless_bane.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Faceless Bane") +local monster = {} + +monster.description = "a Faceless Bane" +monster.experience = 14000 +monster.outfit = { + lookType = 1122, + lookHead = 0, + lookBody = 4, + lookLegs = 95, + lookFeet = 4, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 17000 +monster.maxHealth = 17000 +monster.race = "blood" +monster.corpse = 34651 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Book Backpack", chance = 100000}, + {name = "Ectoplasmic Shield", chance = 100000}, + {name = "Spirit Guide", chance = 100000}, + {id = 34983, chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -5} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 1} +} + +monster.heals = { + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_dream_courts/bosses/izcandar_the_banished.lua b/data/monster/quests/the_dream_courts/bosses/izcandar_the_banished.lua new file mode 100644 index 00000000000..26d00dc6f90 --- /dev/null +++ b/data/monster/quests/the_dream_courts/bosses/izcandar_the_banished.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Izcandar the Banished") +local monster = {} + +monster.description = "Izcandar the Banished" +monster.experience = 6900 +monster.outfit = { + lookType = 1137, + lookHead = 1, + lookBody = 114, + lookLegs = 76, + lookFeet = 0, + lookAddons = 2, + lookMount = 0 +} + +monster.health = 7600 +monster.maxHealth = 7600 +monster.race = "blood" +monster.corpse = 6068 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "berserk potion", chance = 100000, maxCount = 10}, + {name = "crystal coin", chance = 100000}, + {name = "energy bar", chance = 100000}, + {name = "giant sapphire", chance = 100000}, + {name = "gold token", chance = 100000, maxCount = 2}, + {name = "silver token", chance = 100000, maxCount = 2}, + {name = "royal star", chance = 100000, maxCount = 100}, + {name = "green gem", chance = 100000, maxCount = 2}, + {name = "huge chunk of crude iron", chance = 25100}, + {name = "mysterious remains", chance = 25000}, + {name = "piggy bank", chance = 12800}, + {name = "platinum coin", chance = 12000, maxCount = 10}, + {name = "supreme health potion", chance = 12000, maxCount = 10}, + {name = "ultimate mana potion", chance = 12000, maxCount = 20} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -5} +} + +monster.defenses = { + defense = 0, + armor = 76 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_dream_courts/bosses/malofur_mangrinder.lua b/data/monster/quests/the_dream_courts/bosses/malofur_mangrinder.lua new file mode 100644 index 00000000000..7e2de2f4d20 --- /dev/null +++ b/data/monster/quests/the_dream_courts/bosses/malofur_mangrinder.lua @@ -0,0 +1,144 @@ +local mType = Game.createMonsterType("Malofur Mangrinder") +local monster = {} + +monster.description = "Malofur Mangrinder" +monster.experience = 55000 +monster.outfit = { + lookType = 1120, + lookHead = 19, + lookBody = 22, + lookLegs = 76, + lookFeet = 22, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 200000 +monster.maxHealth = 200000 +monster.race = "blood" +monster.corpse = 34655 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "RAAAARGH! I'M MASHING YE TO DUST BOOM!", yell = false}, + {text = "BOOOM!", yell = false}, + {text = "BOOOOM!!!", yell = false}, + {text = "BOOOOOM!!!", yell = false} +} + +monster.loot = { + {name = "Ultimate Spirit Potion", chance = 50000, maxCount = 6}, + {name = "Crystal Coin", chance = 50000}, + {name = "Ultimate Mana Potion", chance = 50000, maxCount = 14}, + {name = "Supreme Health Potion", chance = 50000, maxCount = 6}, + {name = "Gold Token", chance = 50000, maxCount = 2}, + {name = "Silver Token", chance = 100000, maxCount = 2}, + {id = 7632, chance = 100000}, + {name = "Green Gem", chance = 100000}, + {name = "Red Gem", chance = 50000}, + {name = "Blue Gem", chance = 100000}, + {id = 26185, chance = 50000}, + {name = "Platinum Coin", chance = 50000, maxCount = 5}, + {name = "Bullseye Potion", chance = 50000, maxCount = 10}, + {name = "Piggy Bank", chance = 100000}, + {name = "Mysterious Remains", chance = 100000}, + {name = "Energy Bar", chance = 100000}, + {id = 26199, chance = 50000}, + {name = "Ring of the Sky", chance = 100000}, + {name = "Crunor Idol", chance = 100000}, + {name = "Resizer", chance = 100000}, + {name = "Shoulder Plate", chance = 100000}, + {name = "Malofur's Lunchbox", chance = 100000}, + {name = "Pomegranate", chance = 50000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -5} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_dream_courts/bosses/maxxenius.lua b/data/monster/quests/the_dream_courts/bosses/maxxenius.lua new file mode 100644 index 00000000000..0922c7f4944 --- /dev/null +++ b/data/monster/quests/the_dream_courts/bosses/maxxenius.lua @@ -0,0 +1,155 @@ +local mType = Game.createMonsterType("Maxxenius") +local monster = {} + +monster.description = "a Maxxenius" +monster.experience = 55000 +monster.outfit = { + lookType = 1142, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "blood" +monster.corpse = 34789 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 100000, maxCount = 5}, + {name = "Mysterious Remains", chance = 100000}, + {name = "Piggy Bank", chance = 100000}, + {name = "Brain in a Jar", chance = 100000}, + {name = "Maxxenius Head", chance = 100000}, + {name = "Silver Token", chance = 100000, maxCount = 3}, + {name = "Energy Bar", chance = 100000}, + {name = "Crystal Coin", chance = 13790}, + {name = "Gold Ingot", chance = 17240}, + {name = "Bullseye Potion", chance = 24114, maxCount = 10}, + {name = "Mastermind Potion", chance = 17240, maxCount = 10}, + {name = "Royal Star", chance = 100000, maxCount = 100}, + {name = "Supreme Health Potion", chance = 41380, maxCount = 20}, + {name = "Ultimate Spirit Potion", chance = 48280, maxCount = 60}, + {name = "Ultimate Mana Potion", chance = 68970, maxCount = 14}, + {name = "Giant Ruby", chance = 3450}, + {name = "Ornate Locket", chance = 3450}, + {name = "Gold Token", chance = 68970, maxCount = 2}, + {id = 7632, chance = 28540}, + {name = "Pomegranate", chance = 24140}, + {name = "Chaos Mace", chance = 6900}, + {id = 26184, chance = 17240}, + {id = 26199, chance = 13790}, + {name = "Green Gem", chance = 31030}, + {name = "Yellow Gem", chance = 31030}, + {name = "Violet Gem", chance = 6900}, + {name = "Blue Gem", chance = 10340}, + {name = "Huge Chunk of Crude Iron", chance = 17240}, + {id = 26185, chance = 3450}, + {name = "Skull Staff", chance = 13790}, + {name = "Energized Limb", chance = 3450}, + {name = "Purple Tendril Lantern", chance = 1500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1000}, + {name ="energy beam", interval = 2000, chance = 10, minDamage = -500, maxDamage = -1200, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="energy wave", interval = 2000, chance = 10, minDamage = -500, maxDamage = -1200, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYAREA, target = false} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.heals = { + {type = COMBAT_ENERGYDAMAGE, percent = 500} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_dream_courts/bosses/plagueroot.lua b/data/monster/quests/the_dream_courts/bosses/plagueroot.lua new file mode 100644 index 00000000000..1799831cddc --- /dev/null +++ b/data/monster/quests/the_dream_courts/bosses/plagueroot.lua @@ -0,0 +1,165 @@ +local mType = Game.createMonsterType("Plagueroot") +local monster = {} + +monster.description = "a Plagueroot" +monster.experience = 55000 +monster.outfit = { + lookType = 1121, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "venom" +monster.corpse = 34660 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 5}, + {name = "Piggy Bank", chance = 100000}, + {name = "Mysterious Remains", chance = 100000}, + {name = "Energy Bar", chance = 100000}, + {name = "Silver Token", chance = 100000, maxCount = 3}, + {name = "Gold Token", chance = 22000, maxCount = 2}, + {name = "Supreme Health Potion", chance = 23550}, + {name = "Ultimate Mana Potion", chance = 25550}, + {name = "Huge Chunk of Crude Iron", chance = 27550}, + {name = "Royal Star", chance = 15770, maxCount = 100}, + {name = "Green Gem", chance = 12800, maxCount = 2}, + {name = "Yellow Gem", chance = 12000, maxCount = 2}, + {name = "Red Gem", chance = 12700, maxCount = 2}, + {name = "Bullseye Potion", chance = 25000, maxCount = 10}, + {name = "Pomegranate", chance = 8000}, + {name = "Crystal Coin", chance = 7700, maxCount = 2}, + {name = "Skull Staff", chance = 7650}, + {name = "Chaos Mace", chance = 2200}, + {name = "Gold Ingot", chance = 2800}, + {id = 26199, chance = 2500}, + {id = 7632, chance = 2600}, + {name = "Blue Gem", chance = 2500}, + {name = "Violet Gem", chance = 2300, maxCount = 2}, + {name = "Living Armor", chance = 1100}, + {name = "Magic Sulphur", chance = 1000}, + {name = "Mastermind Potion", chance = 800, maxCount = 10}, + {id = 26185, chance = 800}, + {name = "Ring of the Sky", chance = 800}, + {name = "Living Vine Bow", chance = 750}, + {name = "Abyss Hammer", chance = 700}, + {id = 26187, chance = 600}, + {name = "Plagueroot Offshoot", chance = 500}, + {name = "Turquoise Tendril Lantern", chance = 400} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 210, attack = 260}, + -- fire + {name ="condition", type = CONDITION_FIRE, interval = 1000, chance = 7, minDamage = -200, maxDamage = -1000, range = 2, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="combat", interval = 1000, chance = 7, type = COMBAT_PHYSICALDAMAGE, minDamage = -50, maxDamage = -150, radius = 6, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 1000, chance = 50, type = COMBAT_FIREDAMAGE, minDamage = -20, maxDamage = -100, radius = 5, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="firefield", interval = 1000, chance = 4, radius = 8, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 1000, chance = 34, type = COMBAT_FIREDAMAGE, minDamage = -50, maxDamage = -150, range = 7, radius = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 1000, chance = 13, type = COMBAT_FIREDAMAGE, minDamage = -50, maxDamage = -100, length = 8, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -30, maxDamage = -100, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false} +} + +monster.defenses = { + defense = 150, + armor = 165, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_HEALING, minDamage = 500, maxDamage = 1000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_HEALING, minDamage = 200, maxDamage = 300, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 1000, chance = 10, speedChange = 1800, effect = CONST_ME_MAGIC_RED, target = false, duration = 3000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 220}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.heals = { + {type = COMBAT_EARTHDAMAGE, percent = 500} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_dream_courts/bosses/the_nightmare_beast.lua b/data/monster/quests/the_dream_courts/bosses/the_nightmare_beast.lua new file mode 100644 index 00000000000..b70b8a69338 --- /dev/null +++ b/data/monster/quests/the_dream_courts/bosses/the_nightmare_beast.lua @@ -0,0 +1,163 @@ +local mType = Game.createMonsterType("The Nightmare Beast") +local monster = {} + +monster.description = "a The Nightmare Beast" +monster.experience = 255000 +monster.outfit = { + lookType = 1144, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 22 +monster.maxHealth = 22 +monster.race = "blood" +monster.corpse = 34797 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 5}, + {name = "piggy bank", chance = 100000}, + {name = "mysterious remains", chance = 100000}, + {name = "energy bar", chance = 100000}, + {name = "silver token", chance = 97120, maxCount = 4}, + {name = "gold token", chance = 76980, maxCount = 3}, + {name = "ultimate spirit potion", chance = 63310, maxCount = 14}, + {name = "supreme health potion", chance = 53240, maxCount = 6}, + {name = "ultimate spirit potion", chance = 47480, maxCount = 20}, + {name = "huge chunk of crude iron", chance = 40290}, + {name = "red gem", chance = 32370}, + {name = "yellow gem", chance = 28780}, + {name = "royal star", chance = 25900, maxCount = 100}, + {name = "berserk potion", chance = 24460, maxCount = 10}, + {name = "blue gem", chance = 18710}, + {name = "mastermind potion", chance = 17990, maxCount = 10}, + {name = "green gem", chance = 17270}, + {name = "crystal coin", chance = 17270}, + {name = "skull staff", chance = 16550}, + {name = "bullseye potion", chance = 13670, maxCount = 10}, + {name = "ice shield", chance = 13670}, + {name = "chaos mace", chance = 13670}, + {name = "gold ingot", chance = 12950}, + {id = 7633, chance = 10790}, + {id = 26200, chance = 10070}, + {id = 26198, chance = 9350},-- collar of blue plasma + {id = 26187, chance = 8630}, + {name = "ring of the sky", chance = 8630}, + {id = 26199, chance = 7910}, + {name = "beast's nightmare-cushion", chance = 6470}, + {name = "violet gem", chance = 6470}, + {name = "magic sulphur", chance = 6470}, + {name = "purple tendril lantern", chance = 5760}, + {id = 26185, chance = 5040}, + {id = 26189, chance = 5040}, + {name = "soul stone", chance = 5040}, + {name = "dragon figurine", chance = 5040}, + {name = "giant sapphire", chance = 4320}, + {name = "giant emerald", chance = 4320}, + {name = "turquoise tendril lantern", chance = 2880}, + {name = "dark whispers", chance = 2880}, + {name = "arcane staff", chance = 2880}, + {name = "giant ruby", chance = 2880}, + {name = "abyss hammer", chance = 2160}, + {id = 34981, chance = 2160}, + {name = "unicorn figurine", chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_dream_courts/generator.lua b/data/monster/quests/the_dream_courts/generator.lua new file mode 100644 index 00000000000..aef6f8a5a7a --- /dev/null +++ b/data/monster/quests/the_dream_courts/generator.lua @@ -0,0 +1,94 @@ +local mType = Game.createMonsterType("Generator") +local monster = {} + +monster.description = "a Generator" +monster.experience = 3000 +monster.outfit = { + lookTypeEx = 23081 +} + +monster.health = 8000 +monster.maxHealth = 8000 +monster.race = "blood" +monster.corpse = 24309 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -206, maxDamage = -252, radius = 6, effect = CONST_ME_GREEN_RINGS, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 4000, chance = 15, type = COMBAT_HEALING, minDamage = 133, maxDamage = 454, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 1}, + {type = COMBAT_FIREDAMAGE, percent = 25}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 25}, + {type = COMBAT_HOLYDAMAGE , percent = 25}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_dream_courts/horrible_dream.lua b/data/monster/quests/the_dream_courts/horrible_dream.lua new file mode 100644 index 00000000000..0168c53bb1b --- /dev/null +++ b/data/monster/quests/the_dream_courts/horrible_dream.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Horrible Dream") +local monster = {} + +monster.description = "a horrible dream" +monster.experience = 300 +monster.outfit = { + lookType = 315, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 320 +monster.maxHealth = 320 +monster.race = "venom" +monster.corpse = 9960 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Death Blob", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = -35, maxDamage = -60, range = 3, radius = 4, effect = CONST_ME_POFF, target = false}, + {name ="death blob curse", interval = 2000, chance = 5, range = 5, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 20, maxDamage = 30, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_dream_courts/lucifuga_aranea.lua b/data/monster/quests/the_dream_courts/lucifuga_aranea.lua new file mode 100644 index 00000000000..be017633f2a --- /dev/null +++ b/data/monster/quests/the_dream_courts/lucifuga_aranea.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("Lucifuga Aranea") +local monster = {} + +monster.description = "a Lucifuga Aranea" +monster.experience = 10000 +monster.outfit = { + lookType = 263, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 12000 +monster.maxHealth = 12000 +monster.race = "undead" +monster.corpse = 7344 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 100000}, + {name = "Cyan Crystal Fragment", chance = 55000}, + {name = "Poison Gland", chance = 54500}, + {name = "Great Mana Potion", chance = 80000}, + {name = "Plate Armor", chance = 64000}, + {name = "Green Gem", chance = 35000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250, condition = {type = CONDITION_POISON, totalDamage = 160, interval = 4000}}, + {name ="speed", interval = 2000, chance = 15, speedChange = -800, range = 7, radius = 6, effect = CONST_ME_POFF, target = false, duration = 15000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -50, maxDamage = -100, range = 7, shootEffect = CONST_ANI_ICE, effect = CONST_ME_ICEAREA, target = true}, + {name ="speed", interval = 2000, chance = 20, speedChange = -600, range = 7, shootEffect = CONST_ANI_SNOWBALL, target = true, duration = 10000} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="speed", interval = 2000, chance = 15, speedChange = 250, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -20}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_dream_courts/mind-wrecking_dream.lua b/data/monster/quests/the_dream_courts/mind-wrecking_dream.lua new file mode 100644 index 00000000000..b50c4371c09 --- /dev/null +++ b/data/monster/quests/the_dream_courts/mind-wrecking_dream.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("Mind-Wrecking Dream") +local monster = {} + +monster.description = "a mind-wrecking dream" +monster.experience = 5500 +monster.outfit = { + lookType = 300, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3900 +monster.maxHealth = 3900 +monster.race = "undead" +monster.corpse = 8955 +monster.speed = 260 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -320}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -165, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -350, maxDamage = -720, length = 8, spread = 3, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -300, length = 7, spread = 3, effect = CONST_ME_EXPLOSIONAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -225, maxDamage = -275, radius = 4, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 130, maxDamage = 205, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 450, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 65}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 80} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_dream_courts/nightmare_tendril.lua b/data/monster/quests/the_dream_courts/nightmare_tendril.lua new file mode 100644 index 00000000000..4f2859ffa23 --- /dev/null +++ b/data/monster/quests/the_dream_courts/nightmare_tendril.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Nightmare Tendril") +local monster = {} + +monster.description = "a Nightmare Tendril" +monster.experience = 0 +monster.outfit = { + lookType = 681, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2100 +monster.maxHealth = 2100 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 150 +monster.manaCost = 290 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250}, + {name ="drunk", interval = 2000, chance = 8, shootEffect = CONST_ANI_EARTHARROW, effect = CONST_ME_STUN, target = true, duration = 5000}, + {name ="speed", interval = 2000, chance = 7, speedChange = -120, range = 7, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_MAGIC_RED, target = false, duration = 3000} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_dream_courts/nightmarish_dream.lua b/data/monster/quests/the_dream_courts/nightmarish_dream.lua new file mode 100644 index 00000000000..a45272ff024 --- /dev/null +++ b/data/monster/quests/the_dream_courts/nightmarish_dream.lua @@ -0,0 +1,103 @@ +local mType = Game.createMonsterType("Nightmarish Dream") +local monster = {} + +monster.description = "a Nightmarish Dream" +monster.experience = 900 +monster.outfit = { + lookType = 78, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 500, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100, condition = {type = CONDITION_POISON, totalDamage = 3, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -100, maxDamage = -200, radius = 4, effect = CONST_ME_SOUND_RED, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_DEATHDAMAGE, minDamage = -55, maxDamage = -350, range = 1, radius = 1, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="speed", interval = 2000, chance = 10, speedChange = -300, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 15000} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 120, maxDamage = 190, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_dream_courts/plant_abomination.lua b/data/monster/quests/the_dream_courts/plant_abomination.lua new file mode 100644 index 00000000000..4d6688106a0 --- /dev/null +++ b/data/monster/quests/the_dream_courts/plant_abomination.lua @@ -0,0 +1,104 @@ +local mType = Game.createMonsterType("Plant Abomination") +local monster = {} + +monster.description = "a Plant Abomination" +monster.experience = 310 +monster.outfit = { + lookType = 310, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3900 +monster.maxHealth = 3900 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_MANADRAIN, minDamage = -30, maxDamage = -100, radius = 4, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -700, length = 5, spread = 3, effect = CONST_ME_SMALLPLANTS, target = false, duration = 15000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -100, range = 7, radius = 1, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_CARNIPHILA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -55, maxDamage = -100, radius = 4, effect = CONST_ME_HITBYPOISON, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, radius = 1, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = 1} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_dream_courts/plant_attendant.lua b/data/monster/quests/the_dream_courts/plant_attendant.lua new file mode 100644 index 00000000000..78ac0a2307e --- /dev/null +++ b/data/monster/quests/the_dream_courts/plant_attendant.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Plant Attendant") +local monster = {} + +monster.description = "a Plant Attendant" +monster.experience = 45 +monster.outfit = { + lookType = 567, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 90 +monster.maxHealth = 90 +monster.race = "undead" +monster.corpse = 21358 +monster.speed = 140 +monster.manaCost = 390 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -90}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -15, range = 7, shootEffect = CONST_ANI_SMALLSTONE, target = true}, + {name ="speed", interval = 2000, chance = 20, speedChange = -600, radius = 3, effect = CONST_ME_SMALLPLANTS, target = false, duration = 9000} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = -1}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_dream_courts/the_cold_of_winter.lua b/data/monster/quests/the_dream_courts/the_cold_of_winter.lua new file mode 100644 index 00000000000..40469391ef5 --- /dev/null +++ b/data/monster/quests/the_dream_courts/the_cold_of_winter.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("The Cold Of Winter") +local monster = {} + +monster.description = "the cold of winter" +monster.experience = 23 +monster.outfit = { + lookType = 53, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 40 +monster.maxHealth = 40 +monster.race = "blood" +monster.corpse = 5998 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -2} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -15} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_dream_courts/the_heat_of_summer.lua b/data/monster/quests/the_dream_courts/the_heat_of_summer.lua new file mode 100644 index 00000000000..26a599c88c0 --- /dev/null +++ b/data/monster/quests/the_dream_courts/the_heat_of_summer.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("The Heat Of Summer") +local monster = {} + +monster.description = "the heat of summer" +monster.experience = 220 +monster.outfit = { + lookType = 49, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 280 +monster.maxHealth = 280 +monster.race = "fire" +monster.corpse = 8964 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -45, maxDamage = -160, range = 7, radius = 2, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="firefield", interval = 2000, chance = 25, range = 7, radius = 1, shootEffect = CONST_ANI_FIRE, target = true} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -25}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_dream_courts/unpleasant_dream.lua b/data/monster/quests/the_dream_courts/unpleasant_dream.lua new file mode 100644 index 00000000000..7dc3140720c --- /dev/null +++ b/data/monster/quests/the_dream_courts/unpleasant_dream.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Unpleasant Dream") +local monster = {} + +monster.description = "an unpleasant dream" +monster.experience = 15 +monster.outfit = { + lookType = 349, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 50 +monster.maxHealth = 50 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -10, condition = {type = CONDITION_POISON, totalDamage = 16, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -15, range = 1, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_dream_courts/whirling_blades.lua b/data/monster/quests/the_dream_courts/whirling_blades.lua new file mode 100644 index 00000000000..79fc9c11dde --- /dev/null +++ b/data/monster/quests/the_dream_courts/whirling_blades.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Whirling Blades") +local monster = {} + +monster.description = "a Whirling Blades" +monster.experience = 0 +monster.outfit = { + lookType = 102, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1 +monster.maxHealth = 1 +monster.race = "undead" +monster.corpse = 2253 +monster.speed = 78 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -500}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -400, radius = 2, effect = CONST_ME_BLOCKHIT, target = false} +} + +monster.defenses = { + defense = 199, + armor = 199 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_elemental_spheres/blazing_fire_elemental.lua b/data/monster/quests/the_elemental_spheres/blazing_fire_elemental.lua new file mode 100644 index 00000000000..4bb57575e2b --- /dev/null +++ b/data/monster/quests/the_elemental_spheres/blazing_fire_elemental.lua @@ -0,0 +1,104 @@ +local mType = Game.createMonsterType("Blazing Fire Elemental") +local monster = {} + +monster.description = "a blazing fire elemental" +monster.experience = 450 +monster.outfit = { + lookType = 49, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 650 +monster.maxHealth = 650 +monster.race = "fire" +monster.corpse = 8964 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 80, + random = 20, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 10000, maxCount = 40}, + {name = "flaming arrow", chance = 5000, maxCount = 4}, + {name = "glimmering soil", chance = 2500}, + {name = "fiery heart", chance = 5475} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="combat", interval = 1000, chance = 13, type = COMBAT_FIREDAMAGE, minDamage = -65, maxDamage = -205, radius = 5, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_FIREDAMAGE, minDamage = -110, maxDamage = -150, range = 7, radius = 5, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="firefield", interval = 1000, chance = 15, range = 7, radius = 1, shootEffect = CONST_ANI_FIRE, target = true} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_elemental_spheres/blistering_fire_elemental.lua b/data/monster/quests/the_elemental_spheres/blistering_fire_elemental.lua new file mode 100644 index 00000000000..d1ebc817208 --- /dev/null +++ b/data/monster/quests/the_elemental_spheres/blistering_fire_elemental.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Blistering Fire Elemental") +local monster = {} + +monster.description = "a blistering fire elemental" +monster.experience = 1300 +monster.outfit = { + lookType = 242, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "fire" +monster.corpse = 8964 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 80, + random = 20, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "FCHHHRRR", yell = false} +} + +monster.loot = { + {name = "small ruby", chance = 3200, maxCount = 3}, + {name = "gold coin", chance = 12500, maxCount = 65}, + {name = "gold coin", chance = 12500, maxCount = 60}, + {name = "glimmering soil", chance = 2500}, + {name = "wand of draconia", chance = 1250} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -350}, + {name ="combat", interval = 1000, chance = 11, type = COMBAT_FIREDAMAGE, minDamage = -65, maxDamage = -510, length = 7, spread = 3, target = false}, + -- fire + {name ="condition", type = CONDITION_FIRE, interval = 1000, chance = 12, minDamage = -50, maxDamage = -200, radius = 6, effect = CONST_ME_FIREAREA, target = false}, + {name ="firefield", interval = 1000, chance = 15, range = 7, radius = 3, shootEffect = CONST_ANI_FIRE, target = true} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -25}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_elemental_spheres/charged_energy_elemental.lua b/data/monster/quests/the_elemental_spheres/charged_energy_elemental.lua new file mode 100644 index 00000000000..db1ae015110 --- /dev/null +++ b/data/monster/quests/the_elemental_spheres/charged_energy_elemental.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Charged Energy Elemental") +local monster = {} + +monster.description = "a charged energy elemental" +monster.experience = 450 +monster.outfit = { + lookType = 293, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 500 +monster.maxHealth = 500 +monster.race = "undead" +monster.corpse = 8966 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 20000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 22}, + {name = "flash arrow", chance = 6250, maxCount = 3}, + {name = "energy soil", chance = 2063} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -168, maxDamage = -100, range = 6, radius = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_PURPLEENERGY, target = true}, + -- energy damage + {name ="condition", type = CONDITION_ENERGY, interval = 1000, chance = 15, radius = 3, effect = CONST_ME_YELLOWENERGY, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 90, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_elemental_spheres/earth_overlord.lua b/data/monster/quests/the_elemental_spheres/earth_overlord.lua new file mode 100644 index 00000000000..fd78c2d9245 --- /dev/null +++ b/data/monster/quests/the_elemental_spheres/earth_overlord.lua @@ -0,0 +1,110 @@ +local mType = Game.createMonsterType("Earth Overlord") +local monster = {} + +monster.description = "an Earth Overlord" +monster.experience = 2800 +monster.outfit = { + lookType = 285, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 4000 +monster.maxHealth = 4000 +monster.race = "undead" +monster.corpse = 8933 +monster.speed = 330 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 20000, + chance = 30 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "gold coin", chance = 100000, maxCount = 68}, + {name = "platinum coin", chance = 33333, maxCount = 3}, + {name = "terra mantle", chance = 1923}, + {name = "mother soil", chance = 100000}, + {name = "lump of earth", chance = 33333}, + {name = "shiny stone", chance = 8333}, + {id = 13757, chance = 552} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -800, length = 7, spread = 3, effect = CONST_ME_STONES, target = false}, + {name ="combat", interval = 1000, chance = 9, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -490, radius = 6, effect = CONST_ME_BIGPLANTS, target = false}, + {name ="speed", interval = 2000, chance = 20, speedChange = -750, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -25}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_elemental_spheres/energy_overlord.lua b/data/monster/quests/the_elemental_spheres/energy_overlord.lua new file mode 100644 index 00000000000..22a5d405ee5 --- /dev/null +++ b/data/monster/quests/the_elemental_spheres/energy_overlord.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Energy Overlord") +local monster = {} + +monster.description = "an Energy Overlord" +monster.experience = 2800 +monster.outfit = { + lookType = 290, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 4000 +monster.maxHealth = 4000 +monster.race = "undead" +monster.corpse = 8966 +monster.speed = 290 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 20000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 64}, + {name = "platinum coin", chance = 25000, maxCount = 2}, + {name = "pure energy", chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -800, length = 7, spread = 3, effect = CONST_ME_PURPLEENERGY, target = false}, + {name ="combat", interval = 1000, chance = 11, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -200, range = 3, effect = CONST_ME_PURPLEENERGY, target = true}, + {name ="combat", interval = 1000, chance = 9, type = COMBAT_EARTHDAMAGE, minDamage = -50, maxDamage = -200, radius = 5, effect = CONST_ME_BIGPLANTS, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 90, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -1}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_elemental_spheres/fire_overlord.lua b/data/monster/quests/the_elemental_spheres/fire_overlord.lua new file mode 100644 index 00000000000..66f4b515555 --- /dev/null +++ b/data/monster/quests/the_elemental_spheres/fire_overlord.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Fire Overlord") +local monster = {} + +monster.description = "a Fire Overlord" +monster.experience = 2800 +monster.outfit = { + lookType = 243, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 4000 +monster.maxHealth = 4000 +monster.race = "fire" +monster.corpse = 8964 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 75}, + {name = "platinum coin", chance = 50000, maxCount = 3}, + {name = "magma coat", chance = 819}, + {name = "eternal flames", chance = 100000}, + {name = "fiery heart", chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450, condition = {type = CONDITION_FIRE, totalDamage = 650, interval = 9000}}, + {name ="firefield", interval = 2000, chance = 15, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -300, maxDamage = -900, length = 1, spread = 0, effect = CONST_ME_FIREATTACK, target = false}, + {name ="combat", interval = 1000, chance = 13, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -350, radius = 4, effect = CONST_ME_FIREAREA, target = true} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 1}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -25}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_elemental_spheres/ice_overlord.lua b/data/monster/quests/the_elemental_spheres/ice_overlord.lua new file mode 100644 index 00000000000..c8cc50068cf --- /dev/null +++ b/data/monster/quests/the_elemental_spheres/ice_overlord.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("Ice Overlord") +local monster = {} + +monster.description = "an Ice Overlord" +monster.experience = 2800 +monster.outfit = { + lookType = 11, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 4000 +monster.maxHealth = 4000 +monster.race = "undead" +monster.corpse = 8965 +monster.speed = 390 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 20000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 38}, + {name = "platinum coin", chance = 50000, maxCount = 3}, + {name = "flawless ice crystal", chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="speed", interval = 2000, chance = 18, speedChange = -800, radius = 6, effect = CONST_ME_ICETORNADO, target = false, duration = 5000}, + {name ="combat", interval = 1000, chance = 9, type = COMBAT_ICEDAMAGE, minDamage = -50, maxDamage = -400, range = 7, shootEffect = CONST_ANI_SMALLICE, effect = CONST_ME_ICEATTACK, target = true} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 90, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = -25}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_elemental_spheres/jagged_earth_elemental.lua b/data/monster/quests/the_elemental_spheres/jagged_earth_elemental.lua new file mode 100644 index 00000000000..7c093c7fffa --- /dev/null +++ b/data/monster/quests/the_elemental_spheres/jagged_earth_elemental.lua @@ -0,0 +1,110 @@ +local mType = Game.createMonsterType("Jagged Earth Elemental") +local monster = {} + +monster.description = "a jagged earth elemental" +monster.experience = 1300 +monster.outfit = { + lookType = 285, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "undead" +monster.corpse = 8933 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 20000, + chance = 50 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "*STOMP STOMP*", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 27000, maxCount = 90}, + {name = "gold coin", chance = 27000, maxCount = 90}, + {name = "gold coin", chance = 1500, maxCount = 10}, + {name = "small emerald", chance = 3750, maxCount = 2}, + {name = "twigs", chance = 18000}, + {name = "iron ore", chance = 800, maxCount = 2}, + {name = "seeds", chance = 1600}, + {name = "natural soil", chance = 9000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -100, maxDamage = -250, length = 6, spread = 3, effect = CONST_ME_STONES, target = false}, + {name ="combat", interval = 1000, chance = 11, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -200, range = 7, radius = 6, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_POISONAREA, target = true} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -25}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_elemental_spheres/lord_of_the_elements.lua b/data/monster/quests/the_elemental_spheres/lord_of_the_elements.lua new file mode 100644 index 00000000000..0c8cbf8d321 --- /dev/null +++ b/data/monster/quests/the_elemental_spheres/lord_of_the_elements.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Lord of the Elements") +local monster = {} + +monster.description = "Lord of the Elements" +monster.experience = 8000 +monster.outfit = { + lookType = 290, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 8000 +monster.maxHealth = 8000 +monster.race = "undead" +monster.corpse = 9009 +monster.speed = 370 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Blistering Fire Elemental", chance = 50, interval = 4000}, + {name = "Jagged Earth Elemental", chance = 50, interval = 4000}, + {name = "Roaring Water Elemental", chance = 50, interval = 4000}, + {name = "Overcharged Energy Elemental", chance = 50, interval = 4000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "WHO DARES CALLING ME?", yell = true}, + {text = "I'LL FREEZE YOU THEN I CRUSH YOU!", yell = true} +} + +monster.loot = { + {name = "small sapphire", chance = 7142, maxCount = 4}, + {name = "small ruby", chance = 11111, maxCount = 4}, + {name = "small emerald", chance = 11111, maxCount = 4}, + {name = "small amethyst", chance = 11111, maxCount = 3}, + {name = "platinum coin", chance = 50000, maxCount = 9}, + {name = "earthborn titan armor", chance = 2063}, + {name = "gold ingot", chance = 25000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -690} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_HEALING, minDamage = 100, maxDamage = 195, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="outfit", interval = 1500, chance = 40, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 3000, outfitMonster = "Energy Overlord"}, + {name ="outfit", interval = 1500, chance = 40, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 3000, outfitMonster = "Fire Overlord"}, + {name ="outfit", interval = 1500, chance = 40, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 3000, outfitMonster = "Earth Overlord"}, + {name ="outfit", interval = 1500, chance = 40, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 3000, outfitMonster = "Ice Overlord"} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 1}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 45}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_elemental_spheres/muddy_earth_elemental.lua b/data/monster/quests/the_elemental_spheres/muddy_earth_elemental.lua new file mode 100644 index 00000000000..baa88464eea --- /dev/null +++ b/data/monster/quests/the_elemental_spheres/muddy_earth_elemental.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Muddy Earth Elemental") +local monster = {} + +monster.description = "a muddy earth elemental" +monster.experience = 450 +monster.outfit = { + lookType = 301, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 650 +monster.maxHealth = 650 +monster.race = "undead" +monster.corpse = 8933 +monster.speed = 260 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 20000, + chance = 50 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "small stone", chance = 40000, maxCount = 3}, + {name = "gold coin", chance = 24500, maxCount = 80}, + {name = "gold coin", chance = 24500, maxCount = 47}, + {id = 2244, chance = 22000}, + {name = "natural soil", chance = 3750} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -160}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -25, maxDamage = -155, range = 7, radius = 2, effect = CONST_ME_STONES, target = true}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 1000, chance = 10, minDamage = 0, maxDamage = -26, length = 6, spread = 3, effect = CONST_ME_GROUNDSHAKER, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -25}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_elemental_spheres/overcharged_energy_elemental.lua b/data/monster/quests/the_elemental_spheres/overcharged_energy_elemental.lua new file mode 100644 index 00000000000..f549e68a2c3 --- /dev/null +++ b/data/monster/quests/the_elemental_spheres/overcharged_energy_elemental.lua @@ -0,0 +1,110 @@ +local mType = Game.createMonsterType("Overcharged Energy Elemental") +local monster = {} + +monster.description = "an overcharged energy elemental" +monster.experience = 1300 +monster.outfit = { + lookType = 290, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1200 +monster.maxHealth = 1200 +monster.race = "undead" +monster.corpse = 8966 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 20000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "BZZZZZZZZZZ", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 56}, + {name = "small amethyst", chance = 10000, maxCount = 2}, + {name = "berserk potion", chance = 2173}, + {name = "great health potion", chance = 10000}, + {name = "energy soil", chance = 14285} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 11, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -250, radius = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_PURPLEENERGY, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -300, range = 3, effect = CONST_ME_PURPLEENERGY, target = true}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, radius = 4, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 90, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = -20}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_elemental_spheres/roaring_water_elemental.lua b/data/monster/quests/the_elemental_spheres/roaring_water_elemental.lua new file mode 100644 index 00000000000..61722400b03 --- /dev/null +++ b/data/monster/quests/the_elemental_spheres/roaring_water_elemental.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Roaring Water Elemental") +local monster = {} + +monster.description = "a roaring water elemental" +monster.experience = 1300 +monster.outfit = { + lookType = 11, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1750 +monster.maxHealth = 1750 +monster.race = "undead" +monster.corpse = 8965 +monster.speed = 390 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 20000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "BLUB BLUB", yell = false}, + {text = "SWASHHH", yell = false} +} + +monster.loot = { + {name = "small sapphire", chance = 4125, maxCount = 2}, + {name = "gold coin", chance = 27000, maxCount = 90}, + {name = "gold coin", chance = 27000, maxCount = 87}, + {name = "iced soil", chance = 9000}, + {name = "northwind rod", chance = 750} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -225}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -240, maxDamage = -320, radius = 2, shootEffect = CONST_ANI_ICE, effect = CONST_ME_LOSEENERGY, target = true} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 90, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_elemental_spheres/slick_water_elemental.lua b/data/monster/quests/the_elemental_spheres/slick_water_elemental.lua new file mode 100644 index 00000000000..f93784660e8 --- /dev/null +++ b/data/monster/quests/the_elemental_spheres/slick_water_elemental.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("Slick Water Elemental") +local monster = {} + +monster.description = "a slick water elemental" +monster.experience = 450 +monster.outfit = { + lookType = 286, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 550 +monster.maxHealth = 550 +monster.race = "undead" +monster.corpse = 8965 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 20000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "BLUUUUB", yell = false}, + {text = "SPLISH SPLASH", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 22500, maxCount = 70}, + {name = "gold coin", chance = 22500, maxCount = 60}, + {name = "shiver arrow", chance = 2575, maxCount = 3}, + {name = "iced soil", chance = 6000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -175}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -130, range = 7, shootEffect = CONST_ANI_EARTH, target = true}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = 0, maxDamage = -220, range = 6, shootEffect = CONST_ANI_SNOWBALL, target = true}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_ICEDAMAGE, minDamage = 0, maxDamage = -103, range = 4, shootEffect = CONST_ANI_SMALLICE, target = true} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 90, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 40}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_explorer_society/blue_butterfly.lua b/data/monster/quests/the_explorer_society/blue_butterfly.lua new file mode 100644 index 00000000000..4ada9d7d299 --- /dev/null +++ b/data/monster/quests/the_explorer_society/blue_butterfly.lua @@ -0,0 +1,94 @@ +local mType = Game.createMonsterType("Blue Butterfly") +local monster = {} + +monster.name = "Butterfly" +monster.description = "a butterfly" +monster.experience = 0 +monster.outfit = { + lookType = 227, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2 +monster.maxHealth = 2 +monster.race = "venom" +monster.corpse = 4994 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 60, + random = 40, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 6, + runHealth = 2, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_explorer_society/pink_butterfly.lua b/data/monster/quests/the_explorer_society/pink_butterfly.lua new file mode 100644 index 00000000000..4ff3c361306 --- /dev/null +++ b/data/monster/quests/the_explorer_society/pink_butterfly.lua @@ -0,0 +1,93 @@ +local mType = Game.createMonsterType("Pink Butterfly") +local monster = {} + +monster.name = "Butterfly" +monster.description = "a butterfly" +monster.experience = 0 +monster.outfit = { + lookType = 213, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2 +monster.maxHealth = 2 +monster.race = "venom" +monster.corpse = 4313 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 6, + runHealth = 2, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_explorer_society/purple_butterfly.lua b/data/monster/quests/the_explorer_society/purple_butterfly.lua new file mode 100644 index 00000000000..b915f768c0e --- /dev/null +++ b/data/monster/quests/the_explorer_society/purple_butterfly.lua @@ -0,0 +1,94 @@ +local mType = Game.createMonsterType("Purple Butterfly") +local monster = {} + +monster.name = "Butterfly" +monster.description = "a butterfly" +monster.experience = 0 +monster.outfit = { + lookType = 213, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2 +monster.maxHealth = 2 +monster.race = "venom" +monster.corpse = 4993 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 60, + random = 40, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 6, + runHealth = 2, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_explorer_society/red_butterfly.lua b/data/monster/quests/the_explorer_society/red_butterfly.lua new file mode 100644 index 00000000000..7a95c196fb3 --- /dev/null +++ b/data/monster/quests/the_explorer_society/red_butterfly.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("Red Butterfly") +local monster = {} + +monster.name = "Butterfly" +monster.description = "a butterfly" +monster.experience = 0 +monster.outfit = { + lookType = 228, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 228 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 25, + FirstUnlock = 5, + SecondUnlock = 10, + CharmsPoints = 1, + Stars = 0, + Occurrence = 0, + Locations = "Banuta, Carlin Surroundings, Feyrist Meadows, Grimvale, Liberty Bay City, \z + Liberty Bay Surroundings, Meriana, Plains of Havoc, Port Hope Surroundings, \z + Yalahar Arena Quarter, Yalahar Centre, Yalahar Magician Quarter." + } + +monster.health = 2 +monster.maxHealth = 2 +monster.race = "venom" +monster.corpse = 4992 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 60, + random = 40, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 6, + runHealth = 2, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_explorer_society/yellow_butterfly.lua b/data/monster/quests/the_explorer_society/yellow_butterfly.lua new file mode 100644 index 00000000000..a1e0a5608b9 --- /dev/null +++ b/data/monster/quests/the_explorer_society/yellow_butterfly.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("Yellow Butterfly") +local monster = {} + +monster.name = "Butterfly" +monster.description = "a butterfly" +monster.experience = 0 +monster.outfit = { + lookType = 10, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 227 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 25, + FirstUnlock = 5, + SecondUnlock = 10, + CharmsPoints = 1, + Stars = 0, + Occurrence = 0, + Locations = "Ab'Dendriel, Carlin Surroundings, Cormaya, Feyrist Meadows, Grimvale, Issavi, \z + Kazordoon Surroundings, Liberty Bay City, Liberty Bay Surroundings, Meriana, Plains of Havoc, \z + Port Hope Surroundings, Yalahar Arena Quarter, Yalahar Centre, Yalahar Magician Quarter." + } + +monster.health = 2 +monster.maxHealth = 2 +monster.race = "venom" +monster.corpse = 5014 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 60, + random = 40, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 6, + runHealth = 2, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_first_dragon/angry_plant.lua b/data/monster/quests/the_first_dragon/angry_plant.lua new file mode 100644 index 00000000000..8dc937b3994 --- /dev/null +++ b/data/monster/quests/the_first_dragon/angry_plant.lua @@ -0,0 +1,103 @@ +local mType = Game.createMonsterType("Angry Plant") +local monster = {} + +monster.description = "an angry plant" +monster.experience = 0 +monster.outfit = { + lookType = 120, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "venom" +monster.corpse = 9679 +monster.speed = 110 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "Angry Plant Death" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 50, condition = {type = CONDITION_POISON, totalDamage = 95, interval = 4000}} +} + +monster.defenses = { + defense = 20, + armor = 26 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_first_dragon/bosses/fallen_challenger.lua b/data/monster/quests/the_first_dragon/bosses/fallen_challenger.lua new file mode 100644 index 00000000000..d9162e194b7 --- /dev/null +++ b/data/monster/quests/the_first_dragon/bosses/fallen_challenger.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Fallen Challenger") +local monster = {} + +monster.description = "a fallen challenger" +monster.experience = 0 +monster.outfit = { + lookType = 231, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 9000 +monster.maxHealth = 9000 +monster.race = "undead" +monster.corpse = 1397 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "Fallen Death" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 120, attack = 130}, + {name ="combat", interval = 1000, chance = 13, type = COMBAT_LIFEDRAIN, minDamage = -400, maxDamage = -600, radius = 1, target = true}, + {name ="combat", interval = 3000, chance = 34, type = COMBAT_DEATHDAMAGE, minDamage = -180, maxDamage = -500, range = 1, radius = 1, shootEffect = CONST_ANI_DEATH, target = true} +} + +monster.defenses = { + defense = 55, + armor = 50, + {name ="combat", interval = 5000, chance = 25, type = COMBAT_HEALING, minDamage = 60, maxDamage = 100, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_first_dragon/bosses/gelidrazah_the_frozen.lua b/data/monster/quests/the_first_dragon/bosses/gelidrazah_the_frozen.lua new file mode 100644 index 00000000000..941d258fd7d --- /dev/null +++ b/data/monster/quests/the_first_dragon/bosses/gelidrazah_the_frozen.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Gelidrazah the Frozen") +local monster = {} + +monster.description = "gelidrazah the frozen" +monster.experience = 9000 +monster.outfit = { + lookType = 947, + lookHead = 57, + lookBody = 11, + lookLegs = 38, + lookFeet = 38, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "blood" +monster.corpse = 27733 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 400, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 97000, maxCount = 56}, + {id = 2152, chance = 97000, maxCount = 2}, + {id = 27606, chance = 100000}, + {id = 7290, chance = 25000}, + {id = 7888, chance = 25000}, + {id = 7902, chance = 25000}, + {id = 7441, chance = 25000}, + {id = 2672, chance = 25000, maxCount = 5}, + {id = 2146, chance = 25000}, + {id = 2033, chance = 25000}, + {id = 27605, chance = 80000, maxCount = 2}, + {id = 21696, chance = 500}, + {id = 21697, chance = 500}, + {id = 7409, chance = 1500}, + {id = 18412, chance = 1500}, + {id = 27607, chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 112, attack = 85}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ICEDAMAGE, minDamage = -310, maxDamage = -495, range = 5, radius = 5, effect = CONST_ME_ICETORNADO, target = true}, + {name ="speed", interval = 2000, chance = 15, speedChange = -600, length = 9, spread = 3, effect = CONST_ME_ICEATTACK, target = false, duration = 10000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -310, maxDamage = -395, length = 9, spread = 3, effect = CONST_ME_ICEATTACK, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -210, maxDamage = -395, radius = 3, effect = CONST_ME_ICEAREA, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_LIFEDRAIN, minDamage = -150, maxDamage = -280, length = 8, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 64, + armor = 52, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 150, maxDamage = 450, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_first_dragon/bosses/kalyassa.lua b/data/monster/quests/the_first_dragon/bosses/kalyassa.lua new file mode 100644 index 00000000000..48af111dc51 --- /dev/null +++ b/data/monster/quests/the_first_dragon/bosses/kalyassa.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Kalyassa") +local monster = {} + +monster.description = "kalyassa" +monster.experience = 9000 +monster.outfit = { + lookType = 947, + lookHead = 37, + lookBody = 113, + lookLegs = 38, + lookFeet = 95, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "blood" +monster.corpse = 5984 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 800, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Dragon Lord", chance = 20, interval = 2000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 27609, chance = 100000}, + {id = 2672, chance = 75230, maxCount = 9}, + {id = 2152, chance = 99080, maxCount = 9}, + {id = 27605, chance = 80000, maxCount = 2}, + {id = 7591, chance = 8260}, + {id = 7590, chance = 9170}, + {id = 2498, chance = 25000}, + {id = 2492, chance = 25000}, + {id = 27606, chance = 100000}, + {id = 2547, chance = 17430}, + {id = 7365, chance = 26610, maxCount = 10}, + {id = 2392, chance = 25000}, + {id = 2167, chance = 25000}, + {id = 5948, chance = 25000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 112, attack = 85}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -110, maxDamage = -495, range = 7, radius = 5, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -310, maxDamage = -495, length = 9, spread = 4, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -710, maxDamage = -895, length = 9, spread = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="firefield", interval = 2000, chance = 10, range = 7, radius = 7, shootEffect = CONST_ANI_FIRE, target = true} +} + +monster.defenses = { + defense = 70, + armor = 45, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 400, maxDamage = 700, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_first_dragon/bosses/tazhadur.lua b/data/monster/quests/the_first_dragon/bosses/tazhadur.lua new file mode 100644 index 00000000000..de2fe2ff8ff --- /dev/null +++ b/data/monster/quests/the_first_dragon/bosses/tazhadur.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("Tazhadur") +local monster = {} + +monster.description = "tazhadur" +monster.experience = 9000 +monster.outfit = { + lookType = 947, + lookHead = 24, + lookBody = 120, + lookLegs = 38, + lookFeet = 95, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "blood" +monster.corpse = 27733 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 97000, maxCount = 51}, + {id = 5920, chance = 50000}, + {id = 27606, chance = 100000}, + {id = 2492, chance = 25000}, + {id = 2434, chance = 25000}, + {id = 2516, chance = 25000}, + {id = 2201, chance = 25000}, + {id = 2672, chance = 25000}, + {id = 5877, chance = 25000}, + {id = 27605, chance = 80000, maxCount = 2}, + {id = 2387, chance = 25000}, + {id = 27608, chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 112, attack = 85}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -110, maxDamage = -495, range = 7, radius = 5, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -310, maxDamage = -495, length = 9, spread = 4, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -710, maxDamage = -895, length = 9, spread = 3, effect = CONST_ME_FIREAREA, target = false} +} + +monster.defenses = { + defense = 64, + armor = 52, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 150, maxDamage = 450, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_first_dragon/bosses/the_first_dragon.lua b/data/monster/quests/the_first_dragon/bosses/the_first_dragon.lua new file mode 100644 index 00000000000..9b4a2e73ce2 --- /dev/null +++ b/data/monster/quests/the_first_dragon/bosses/the_first_dragon.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("The First Dragon") +local monster = {} + +monster.description = "the first dragon" +monster.experience = 9000 +monster.outfit = { + lookType = 947, + lookHead = 94, + lookBody = 80, + lookLegs = 120, + lookFeet = 60, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "blood" +monster.corpse = 27733 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.events = { + "First Dragon Death" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 120, attack = 130}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -410, maxDamage = -695, range = 5, radius = 5, effect = CONST_ME_FIREAREA, target = true}, + {name ="speed", interval = 2000, chance = 20, speedChange = -600, radius = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 10000}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -1010, maxDamage = -1995, length = 9, spread = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -410, maxDamage = -595, radius = 7, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -150, maxDamage = -280, radius = 6, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 64, + armor = 52, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 1500, maxDamage = 4500, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_first_dragon/bosses/zorvorax.lua b/data/monster/quests/the_first_dragon/bosses/zorvorax.lua new file mode 100644 index 00000000000..1a3d31da26e --- /dev/null +++ b/data/monster/quests/the_first_dragon/bosses/zorvorax.lua @@ -0,0 +1,118 @@ +local mType = Game.createMonsterType("Zorvorax") +local monster = {} + +monster.description = "zorvorax" +monster.experience = 9000 +monster.outfit = { + lookType = 928, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 6306 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 800, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 27610, chance = 100000}, + {id = 2148, chance = 100000, maxCount = 24}, + {id = 7591, chance = 20000, maxCount = 3}, + {id = 8472, chance = 20000, maxCount = 3}, + {id = 13291, chance = 500}, + {id = 2152, chance = 40000, maxCount = 4}, + {id = 5944, chance = 100000}, + {id = 5741, chance = 25000}, + {id = 9971, chance = 25000}, + {id = 2173, chance = 25000}, + {id = 7430, chance = 25000}, + {id = 9810, chance = 26670}, + {id = 6300, chance = 13330}, + {id = 11233, chance = 50000, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 112, attack = 85}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -120, maxDamage = -650, range = 7, radius = 5, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_BLACKSMOKE, target = true}, + {name ="combat", interval = 2000, chance = 11, type = COMBAT_FIREDAMAGE, minDamage = -330, maxDamage = -805, range = 7, shootEffect = CONST_ANI_FIRE, target = false}, + {name ="undead dragon curse", interval = 2000, chance = 10, target = false}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_DEATHDAMAGE, minDamage = -300, maxDamage = -780, length = 8, spread = 3, effect = CONST_ME_SMALLCLOUDS, target = false} +} + +monster.defenses = { + defense = 64, + armor = 52, + {name ="combat", interval = 2000, chance = 55, type = COMBAT_HEALING, minDamage = 450, maxDamage = 550, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_first_dragon/dragon_essence.lua b/data/monster/quests/the_first_dragon/dragon_essence.lua new file mode 100644 index 00000000000..93dc1fb8045 --- /dev/null +++ b/data/monster/quests/the_first_dragon/dragon_essence.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Dragon Essence") +local monster = {} + +monster.description = "a dragon essence" +monster.experience = 0 +monster.outfit = { + lookType = 248, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 30000 +monster.maxHealth = 30000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 250, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "Dragon Essence Death" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 80, attack = 110}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_FIREDAMAGE, minDamage = -850, maxDamage = -1250, length = 8, spread = 3, effect = CONST_ME_ICEAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -450, maxDamage = -720, range = 7, radius = 3, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_FIREDAMAGE, minDamage = -750, maxDamage = -880, length = 8, spread = 3, effect = CONST_ME_HITBYFIRE, target = false} +} + +monster.defenses = { + defense = 35, + armor = 22, + {name ="combat", interval = 2000, chance = 16, type = COMBAT_HEALING, minDamage = 150, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 8, speedChange = 262, effect = CONST_ME_MAGIC_RED, target = false, duration = 7000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_first_dragon/dragon_warden.lua b/data/monster/quests/the_first_dragon/dragon_warden.lua new file mode 100644 index 00000000000..f7f62346b8e --- /dev/null +++ b/data/monster/quests/the_first_dragon/dragon_warden.lua @@ -0,0 +1,94 @@ +local mType = Game.createMonsterType("Dragon Warden") +local monster = {} + +monster.description = "a dragon warden" +monster.experience = 4600 +monster.outfit = { + lookType = 947, + lookHead = 5, + lookBody = 5, + lookLegs = 8, + lookFeet = 8, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2800 +monster.maxHealth = 2800 +monster.race = "blood" +monster.corpse = 27854 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 366, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 80, attack = 80}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_FIREDAMAGE, minDamage = -150, maxDamage = -230, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false} +} + +monster.defenses = { + defense = 35, + armor = 45, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_HEALING, minDamage = 70, maxDamage = 300, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_first_dragon/dragon_wrath.lua b/data/monster/quests/the_first_dragon/dragon_wrath.lua new file mode 100644 index 00000000000..e8d820e198d --- /dev/null +++ b/data/monster/quests/the_first_dragon/dragon_wrath.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Dragon Wrath") +local monster = {} + +monster.description = "a dragon wrath" +monster.experience = 4600 +monster.outfit = { + lookType = 351, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 7800 +monster.maxHealth = 7800 +monster.race = "undead" +monster.corpse = 11362 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 366, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 80, attack = 100}, + {name ="ghastly dragon wave", interval = 2000, chance = 10, minDamage = -50, maxDamage = -250, target = false}, + {name ="ghastly dragon curse", interval = 2000, chance = 10, range = 7, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -920, maxDamage = -1260, range = 7, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="ghastly dragon paralyze", interval = 2000, chance = 9, range = 7, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -90, maxDamage = -250, range = 7, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_DEATHDAMAGE, minDamage = -70, maxDamage = -180, radius = 4, effect = CONST_ME_MORTAREA, target = false} +} + +monster.defenses = { + defense = 35, + armor = 45, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_HEALING, minDamage = 70, maxDamage = 300, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = -15}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_first_dragon/haunted_dragon.lua b/data/monster/quests/the_first_dragon/haunted_dragon.lua new file mode 100644 index 00000000000..06dc54ab668 --- /dev/null +++ b/data/monster/quests/the_first_dragon/haunted_dragon.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Haunted Dragon") +local monster = {} + +monster.description = "a haunted dragon" +monster.experience = 6500 +monster.outfit = { + lookType = 231, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 6500 +monster.maxHealth = 6500 +monster.race = "undead" +monster.corpse = 6306 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "black pearl", chance = 22780, maxCount = 2}, + {name = "small sapphire", chance = 28370, maxCount = 2}, + {name = "gold coin", chance = 35500, maxCount = 100}, + {name = "gold coin", chance = 55500, maxCount = 98}, + {name = "platinum coin", chance = 52000, maxCount = 5}, + {name = "life crystal", chance = 2500}, + {name = "hardened bone", chance = 14180}, + {id = 6300, chance = 1150}, + {name = "demonic essence", chance = 12460}, + {name = "assassin star", chance = 26650, maxCount = 5}, + {name = "dragon slayer", chance = 860}, + {name = "dragonbone staff", chance = 4000}, + {name = "great mana potion", chance = 21490}, + {name = "great health potion", chance = 21200}, + {name = "skullcracker armor", chance = 290}, + {name = "gold ingot", chance = 570}, + {name = "unholy bone", chance = 33380}, + {name = "spellweaver's robe", chance = 860} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -480}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_PHYSICALDAMAGE, minDamage = -300, maxDamage = -400, range = 7, radius = 4, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -125, maxDamage = -600, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_EARTHDAMAGE, minDamage = -100, maxDamage = -390, range = 7, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -150, maxDamage = -690, length = 8, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -300, maxDamage = -700, length = 8, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -100, maxDamage = -200, radius = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="undead dragon curse", interval = 2000, chance = 10, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_first_dragon/ice_dragon.lua b/data/monster/quests/the_first_dragon/ice_dragon.lua new file mode 100644 index 00000000000..ff2b2126606 --- /dev/null +++ b/data/monster/quests/the_first_dragon/ice_dragon.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Ice Dragon") +local monster = {} + +monster.description = "an ice dragon" +monster.experience = 2300 +monster.outfit = { + lookType = 947, + lookHead = 9, + lookBody = 9, + lookLegs = 9, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2500 +monster.maxHealth = 2500 +monster.race = "undead" +monster.corpse = 27853 +monster.speed = 212 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 350, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 26449, chance = 3000}, + {id = 2148, chance = 95070, maxCount = 200}, + {id = 7902, chance = 2000}, + {id = 2492, chance = 280} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 78, attack = 50}, + {name ="speed", interval = 2000, chance = 18, minDamage = 0, maxDamage = -400, range = 7, radius = 4, effect = CONST_ME_ICETORNADO, target = true, duration = 20000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -50, maxDamage = -120, range = 7, radius = 3, effect = CONST_ME_ICETORNADO, target = false}, + {name ="speed", interval = 2000, chance = 12, minDamage = 0, maxDamage = -400, length = 7, spread = 3, effect = CONST_ME_ICEATTACK, target = false, duration = 20000}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_LIFEDRAIN, minDamage = -150, maxDamage = -380, length = 8, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 35, + armor = 22, + {name ="combat", interval = 2000, chance = 16, type = COMBAT_HEALING, minDamage = 150, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_first_dragon/somewhat_beatable.lua b/data/monster/quests/the_first_dragon/somewhat_beatable.lua new file mode 100644 index 00000000000..af0dc888335 --- /dev/null +++ b/data/monster/quests/the_first_dragon/somewhat_beatable.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Somewhat Beatable") +local monster = {} + +monster.description = "a somewhat beatable" +monster.experience = 0 +monster.outfit = { + lookType = 34, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3000 +monster.maxHealth = 3000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "Somewhat Beatable Death" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 40}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_FIREDAMAGE, minDamage = -60, maxDamage = -140, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 11, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -170, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false} +} + +monster.defenses = { + defense = 38, + armor = 25, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_HEALING, minDamage = 40, maxDamage = 70, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_first_dragon/spirit_of_fertility.lua b/data/monster/quests/the_first_dragon/spirit_of_fertility.lua new file mode 100644 index 00000000000..0eeb271d2a4 --- /dev/null +++ b/data/monster/quests/the_first_dragon/spirit_of_fertility.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Spirit of Fertility") +local monster = {} + +monster.description = "a spirit of fertility" +monster.experience = 1100 +monster.outfit = { + lookType = 11, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1250 +monster.maxHealth = 1250 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 130 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 3 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 70, attack = 60, condition = {type = CONDITION_POISON, totalDamage = 300, interval = 4000}}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_DROWNDAMAGE, minDamage = -130, maxDamage = -250, radius = 5, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_LOSEENERGY, target = true} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 60, maxDamage = 75, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_first_dragon/unbeatable_dragon.lua b/data/monster/quests/the_first_dragon/unbeatable_dragon.lua new file mode 100644 index 00000000000..da45efa189c --- /dev/null +++ b/data/monster/quests/the_first_dragon/unbeatable_dragon.lua @@ -0,0 +1,102 @@ +local mType = Game.createMonsterType("Unbeatable Dragon") +local monster = {} + +monster.description = "an unbeatable dragon" +monster.experience = 2100 +monster.outfit = { + lookType = 39, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1900 +monster.maxHealth = 1900 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 82}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -200, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_FIREDAMAGE, minDamage = -150, maxDamage = -230, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false} +} + +monster.defenses = { + defense = 48, + armor = 32, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 55, maxDamage = 95, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_inquisition/a_carved_stone_tile.lua b/data/monster/quests/the_inquisition/a_carved_stone_tile.lua new file mode 100644 index 00000000000..01a9d054e5a --- /dev/null +++ b/data/monster/quests/the_inquisition/a_carved_stone_tile.lua @@ -0,0 +1,90 @@ +local mType = Game.createMonsterType("a carved stone tile") +local monster = {} + +monster.description = "a carved stone tile" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 3169 +} + +monster.health = 100 +monster.maxHealth = 100 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 5 + +monster.changeTarget = { + interval = 5000, + chance = 16 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = true, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Dreadbeast", chance = 25, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_inquisition/annihilon.lua b/data/monster/quests/the_inquisition/annihilon.lua new file mode 100644 index 00000000000..19d024d5016 --- /dev/null +++ b/data/monster/quests/the_inquisition/annihilon.lua @@ -0,0 +1,147 @@ +local mType = Game.createMonsterType("Annihilon") +local monster = {} + +monster.description = "Annihilon" +monster.experience = 15000 +monster.outfit = { + lookType = 12, + lookHead = 19, + lookBody = 104, + lookLegs = 96, + lookFeet = 96, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 46500 +monster.maxHealth = 46500 +monster.race = "fire" +monster.corpse = 6068 +monster.speed = 132 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Flee as long as you can!", yell = false}, + {text = "Annihilon's might will crush you all!", yell = false}, + {text = "I am coming for you!", yell = false} +} + +monster.loot = { + {name = "emerald bangle", chance = 20000}, + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "platinum coin", chance = 16666, maxCount = 30}, + {name = "violet gem", chance = 16666}, + {name = "yellow gem", chance = 20000}, + {name = "green gem", chance = 12500}, + {name = "red gem", chance = 20000}, + {name = "blue gem", chance = 20000}, + {name = "halberd", chance = 20000}, + {name = "guardian halberd", chance = 20000}, + {name = "heavy mace", chance = 25000}, + {name = "mastermind shield", chance = 4166}, + {name = "guardian shield", chance = 7692}, + {name = "crown shield", chance = 11111}, + {name = "demon shield", chance = 4166}, + {name = "tower shield", chance = 9090}, + {name = "power bolt", chance = 16666, maxCount = 94}, + {name = "soul orb", chance = 20000, maxCount = 5}, + {name = "demon horn", chance = 12500, maxCount = 2}, + {name = "infernal bolt", chance = 20000, maxCount = 46}, + {name = "viper star", chance = 16666, maxCount = 70}, + {name = "assassin star", chance = 16666, maxCount = 50}, + {name = "diamond sceptre", chance = 7142}, + {name = "onyx flail", chance = 14285}, + {name = "demonbone", chance = 1234}, + {name = "berserk potion", chance = 16666}, + {name = "mastermind potion", chance = 14285}, + {name = "great mana potion", chance = 11111}, + {name = "great health potion", chance = 14285}, + {id = 7632, chance = 33333, maxCount = 2}, + {name = "flaming arrow", chance = 20000, maxCount = 46}, + {name = "great spirit potion", chance = 14285}, + {name = "ultimate health potion", chance = 14285}, + {name = "lavos armor", chance = 1851}, + {name = "paladin armor", chance = 10000}, + {name = "obsidian truncheon", chance = 1234}, + {id = 9808, chance = 1234}, + {id = 9810, chance = 50000}, + {name = "gold ingot", chance = 20000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1707}, + {name ="combat", interval = 1000, chance = 11, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -600, length = 8, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -200, maxDamage = -700, radius = 4, effect = CONST_ME_ICEAREA, target = false}, + {name ="combat", interval = 3000, chance = 18, type = COMBAT_PHYSICALDAMAGE, minDamage = -50, maxDamage = -255, radius = 5, effect = CONST_ME_GROUNDSHAKER, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -50, maxDamage = -600, radius = 6, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true} +} + +monster.defenses = { + defense = 55, + armor = 60, + {name ="combat", interval = 1000, chance = 14, type = COMBAT_HEALING, minDamage = 400, maxDamage = 900, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="speed", interval = 1000, chance = 4, speedChange = 500, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 7000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 96}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 95} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_inquisition/dreadbeast.lua b/data/monster/quests/the_inquisition/dreadbeast.lua new file mode 100644 index 00000000000..afd0b595e32 --- /dev/null +++ b/data/monster/quests/the_inquisition/dreadbeast.lua @@ -0,0 +1,110 @@ +local mType = Game.createMonsterType("Dreadbeast") +local monster = {} + +monster.description = "a dreadbeast" +monster.experience = 250 +monster.outfit = { + lookType = 101, + lookHead = 20, + lookBody = 30, + lookLegs = 40, + lookFeet = 50, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 800 +monster.maxHealth = 800 +monster.race = "undead" +monster.corpse = 3031 +monster.speed = 136 +monster.manaCost = 800 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 11690, maxCount = 88}, + {id = 2230, chance = 8230}, + {name = "plate armor", chance = 2810}, + {id = 2229, chance = 2810}, + {id = 2231, chance = 1950}, + {name = "bone club", chance = 1520}, + {name = "bone shield", chance = 1520}, + {name = "health potion", chance = 870}, + {name = "green mushroom", chance = 650}, + {name = "hardened bone", chance = 650} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="dreadbeast skill reducer", interval = 3000, chance = 15, range = 1, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_YELLOWENERGY, target = true}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_DROWNDAMAGE, minDamage = -70, maxDamage = -90, range = 1, shootEffect = CONST_ANI_ICE, effect = CONST_ME_LOSEENERGY, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -150, maxDamage = -250, radius = 1, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_PURPLEENERGY, target = true} +} + +monster.defenses = { + defense = 36, + armor = 34, + {name ="combat", interval = 5000, chance = 20, type = COMBAT_HEALING, minDamage = 35, maxDamage = 65, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 55}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 75}, + {type = COMBAT_ICEDAMAGE, percent = 40}, + {type = COMBAT_HOLYDAMAGE , percent = -50}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_inquisition/eye_of_the_seven.lua b/data/monster/quests/the_inquisition/eye_of_the_seven.lua new file mode 100644 index 00000000000..53bf7881b6e --- /dev/null +++ b/data/monster/quests/the_inquisition/eye_of_the_seven.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Eye of the Seven") +local monster = {} + +monster.description = "an eye of the seven" +monster.experience = 0 +monster.outfit = { + lookType = 109, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1 +monster.maxHealth = 1 +monster.race = "venom" +monster.corpse = 6036 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 100, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="combat", interval = 2000, chance = 100, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -500, range = 7, shootEffect = CONST_ANI_ENERGY, target = false} +} + +monster.defenses = { + defense = 1, + armor = 1 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_inquisition/golgordan.lua b/data/monster/quests/the_inquisition/golgordan.lua new file mode 100644 index 00000000000..414627d6bb4 --- /dev/null +++ b/data/monster/quests/the_inquisition/golgordan.lua @@ -0,0 +1,137 @@ +local mType = Game.createMonsterType("Golgordan") +local monster = {} + +monster.description = "Golgordan" +monster.experience = 10000 +monster.outfit = { + lookType = 12, + lookHead = 108, + lookBody = 100, + lookLegs = 105, + lookFeet = 114, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 40000 +monster.maxHealth = 40000 +monster.race = "fire" +monster.corpse = 8721 +monster.speed = 390 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 7000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Latrivan, you fool!", yell = true}, + {text = "We are the right hand and the left hand of the seven!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 273}, + {id = 7591, chance = 55000}, + {id = 2387, chance = 30000}, + {id = 6300, chance = 25000}, + {id = 2214, chance = 25000}, + {id = 2144, chance = 20000, maxCount = 13}, + {id = 2149, chance = 20000, maxCount = 10}, + {id = 2396, chance = 15000}, + {id = 2162, chance = 15000}, + {id = 2170, chance = 15000}, + {id = 2146, chance = 15000, maxCount = 10}, + {id = 2143, chance = 15000, maxCount = 13}, + {id = 2520, chance = 10000}, + {id = 6500, chance = 10000}, + {id = 2167, chance = 10000}, + {id = 2393, chance = 10000}, + {id = 9971, chance = 10000}, + {id = 2179, chance = 10000}, + {id = 2470, chance = 10000}, + {id = 2158, chance = 5000}, + {id = 2462, chance = 5000}, + {id = 2432, chance = 5000}, + {id = 2155, chance = 5000}, + {id = 2164, chance = 5000}, + {id = 2402, chance = 5000}, + {id = 2150, chance = 15000, maxCount = 12}, + {id = 2182, chance = 5000}, + {id = 2165, chance = 5000}, + {id = 2197, chance = 5000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -500}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -60, maxDamage = -200, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 1000, chance = 11, minDamage = -30, maxDamage = -30, length = 5, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 3000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -50, maxDamage = -600, length = 8, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -600, range = 4, radius = 1, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = 0, maxDamage = -600, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 1000, chance = 8, type = COMBAT_PHYSICALDAMAGE, minDamage = -50, maxDamage = -60, radius = 6, effect = CONST_ME_GROUNDSHAKER, target = false} +} + +monster.defenses = { + defense = 54, + armor = 48 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 1}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -1}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -1}, + {type = COMBAT_HOLYDAMAGE , percent = 1}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_inquisition/hellgorak.lua b/data/monster/quests/the_inquisition/hellgorak.lua new file mode 100644 index 00000000000..dadf2fad328 --- /dev/null +++ b/data/monster/quests/the_inquisition/hellgorak.lua @@ -0,0 +1,154 @@ +local mType = Game.createMonsterType("Hellgorak") +local monster = {} + +monster.description = "Hellgorak" +monster.experience = 10000 +monster.outfit = { + lookType = 12, + lookHead = 19, + lookBody = 96, + lookLegs = 21, + lookFeet = 81, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 25850 +monster.maxHealth = 25850 +monster.race = "blood" +monster.corpse = 6068 +monster.speed = 330 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I'll sacrifice yours souls to seven!", yell = false}, + {text = "I'm bad news for you mortals!", yell = false}, + {text = "No man can defeat me!", yell = false}, + {text = "Your puny skills are no match for me.", yell = false}, + {text = "I smell your fear.", yell = false}, + {text = "Delicious!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 200}, + {id = 9813, chance = 49920}, + {id = 8473, chance = 41750, maxCount = 2}, + {id = 8901, chance = 31010}, + {id = 9810, chance = 30560}, + {id = 3962, chance = 29950}, + {id = 2152, chance = 21790, maxCount = 30}, + {id = 8472, chance = 21180}, + {id = 7591, chance = 20570}, + {id = 2487, chance = 19670}, + {id = 7590, chance = 16190}, + {id = 2144, chance = 14070, maxCount = 25}, + {id = 2143, chance = 13920, maxCount = 25}, + {id = 7456, chance = 12860}, + {id = 2145, chance = 12860, maxCount = 25}, + {id = 2147, chance = 13010, maxCount = 5}, + {id = 2125, chance = 12710}, + {id = 2150, chance = 12410, maxCount = 25}, + {id = 2133, chance = 11800}, + {id = 2146, chance = 11650, maxCount = 25}, + {id = 7894, chance = 11350}, + {id = 9970, chance = 11200, maxCount = 25}, + {id = 2149, chance = 10740, maxCount = 25}, + {id = 2645, chance = 10740}, + {id = 8871, chance = 10590}, + {id = 2488, chance = 10140}, + {id = 8870, chance = 10140}, + {id = 2130, chance = 9680}, + {id = 2477, chance = 9530}, + {id = 5954, chance = 9230, maxCount = 2}, + {id = 8902, chance = 8770}, + {id = 8903, chance = 8620}, + {id = 2656, chance = 8170}, + {id = 2466, chance = 2870}, + {id = 7412, chance = 2720}, + {id = 7388, chance = 1970}, + {id = 8904, chance = 1360}, + {id = 7453, chance = 610}, + {id = 8926, chance = 450}, + {id = 2470, chance = 450}, + {id = 8879, chance = 450}, + {id = 8918, chance = 300}, + {id = 2136, chance = 150}, + {id = 2415, chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -910}, + {name ="combat", interval = 1000, chance = 11, type = COMBAT_ENERGYDAMAGE, minDamage = -250, maxDamage = -819, length = 8, spread = 3, effect = CONST_ME_PURPLEENERGY, target = false}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_MANADRAIN, minDamage = -90, maxDamage = -500, radius = 5, effect = CONST_ME_STUN, target = false}, + {name ="combat", interval = 1000, chance = 11, type = COMBAT_FIREDAMAGE, minDamage = -50, maxDamage = -520, radius = 5, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -150, radius = 7, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 65, + armor = 70, + {name ="combat", interval = 1000, chance = 11, type = COMBAT_HEALING, minDamage = 400, maxDamage = 900, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 98}, + {type = COMBAT_ENERGYDAMAGE, percent = 98}, + {type = COMBAT_EARTHDAMAGE, percent = 98}, + {type = COMBAT_FIREDAMAGE, percent = 98}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = -305}, + {type = COMBAT_ICEDAMAGE, percent = 98}, + {type = COMBAT_HOLYDAMAGE , percent = 95}, + {type = COMBAT_DEATHDAMAGE , percent = 98} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_inquisition/latrivan.lua b/data/monster/quests/the_inquisition/latrivan.lua new file mode 100644 index 00000000000..0c335bb05f7 --- /dev/null +++ b/data/monster/quests/the_inquisition/latrivan.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Latrivan") +local monster = {} + +monster.description = "Latrivan" +monster.experience = 10000 +monster.outfit = { + lookType = 12, + lookHead = 120, + lookBody = 128, + lookLegs = 121, + lookFeet = 111, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 25000 +monster.maxHealth = 25000 +monster.race = "fire" +monster.corpse = 8721 +monster.speed = 390 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I might reward you for killing my brother ~ with a swift death!", yell = true}, + {text = "Colateral damage is so fun!", yell = false}, + {text = "Golgordan you fool!", yell = false}, + {text = "We are the brothers of fear!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 273}, + {id = 7591, chance = 55000}, + {id = 2387, chance = 30000}, + {id = 6300, chance = 25000}, + {id = 2214, chance = 25000}, + {id = 2144, chance = 20000, maxCount = 13}, + {id = 2149, chance = 20000, maxCount = 10}, + {id = 2396, chance = 15000}, + {id = 2162, chance = 15000}, + {id = 2170, chance = 15000}, + {id = 2146, chance = 15000, maxCount = 10}, + {id = 2143, chance = 15000, maxCount = 13}, + {id = 2520, chance = 10000}, + {id = 6500, chance = 10000}, + {id = 2167, chance = 10000}, + {id = 2393, chance = 10000}, + {id = 9971, chance = 10000}, + {id = 2179, chance = 10000}, + {id = 2470, chance = 10000}, + {id = 2158, chance = 5000}, + {id = 2462, chance = 5000}, + {id = 2432, chance = 5000}, + {id = 2155, chance = 5000}, + {id = 2164, chance = 5000}, + {id = 2402, chance = 5000}, + {id = 2150, chance = 15000, maxCount = 12}, + {id = 2182, chance = 5000}, + {id = 2165, chance = 5000}, + {id = 2197, chance = 5000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = 0, maxDamage = -850, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -50, maxDamage = -250, length = 7, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -600, range = 4, radius = 1, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -60, maxDamage = -200, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = false} +} + +monster.defenses = { + defense = 45, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 1}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -1}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_inquisition/madareth.lua b/data/monster/quests/the_inquisition/madareth.lua new file mode 100644 index 00000000000..0dc005c29b6 --- /dev/null +++ b/data/monster/quests/the_inquisition/madareth.lua @@ -0,0 +1,150 @@ +local mType = Game.createMonsterType("Madareth") +local monster = {} + +monster.description = "Madareth" +monster.experience = 10000 +monster.outfit = { + lookType = 12, + lookHead = 77, + lookBody = 116, + lookLegs = 82, + lookFeet = 79, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 75000 +monster.maxHealth = 75000 +monster.race = "fire" +monster.corpse = 8721 +monster.speed = 165 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 1200, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I am going to play with yourself!", yell = true}, + {text = "Feel my wrath!", yell = false}, + {text = "No one matches my battle prowess!", yell = false}, + {text = "You will all die!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 150}, + {id = 9813, chance = 59000}, + {id = 9810, chance = 40000}, + {id = 7443, chance = 33000}, + {id = 7591, chance = 30000}, + {id = 8472, chance = 30000}, + {id = 7440, chance = 28000}, + {id = 7439, chance = 23000}, + {id = 7590, chance = 21000}, + {id = 6300, chance = 19000}, + {id = 2183, chance = 19000}, + {id = 2370, chance = 19000}, + {id = 2152, chance = 19000, maxCount = 26}, + {id = 2377, chance = 19000}, + {id = 7404, chance = 16000}, + {id = 2208, chance = 16000}, + {id = 8473, chance = 16000}, + {id = 8910, chance = 16000}, + {id = 2209, chance = 14000}, + {id = 6500, chance = 14000}, + {id = 7407, chance = 14000}, + {id = 2071, chance = 14000}, + {id = 7418, chance = 14000}, + {id = 8912, chance = 14000}, + {id = 3953, chance = 14000}, + {id = 2187, chance = 11000}, + {id = 8922, chance = 11000}, + {id = 7416, chance = 9500}, + {id = 7449, chance = 9500}, + {id = 2214, chance = 9500}, + {id = 5954, chance = 7000, maxCount = 2}, + {id = 2168, chance = 7000}, + {id = 7383, chance = 7000}, + {id = 2169, chance = 7000}, + {id = 8920, chance = 7000}, + {id = 2079, chance = 7000}, + {id = 2070, chance = 7000}, + {id = 3952, chance = 4700}, + {id = 2213, chance = 4700}, + {id = 2396, chance = 4700}, + {id = 7386, chance = 4700}, + {id = 2207, chance = 4700} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -2000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -180, maxDamage = -660, radius = 4, effect = CONST_ME_PURPLEENERGY, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -600, maxDamage = -850, length = 5, spread = 2, effect = CONST_ME_BLACKSMOKE, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -200, radius = 4, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -250, radius = 5, effect = CONST_ME_MAGIC_RED, target = true} +} + +monster.defenses = { + defense = 46, + armor = 48, + {name ="combat", interval = 3000, chance = 14, type = COMBAT_HEALING, minDamage = 400, maxDamage = 900, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 99}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 95} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_inquisition/the_count.lua b/data/monster/quests/the_inquisition/the_count.lua new file mode 100644 index 00000000000..118295cd2db --- /dev/null +++ b/data/monster/quests/the_inquisition/the_count.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("The Count") +local monster = {} + +monster.description = "the Count" +monster.experience = 450 +monster.outfit = { + lookType = 287, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1250 +monster.maxHealth = 1250 +monster.race = "undead" +monster.corpse = 8937 +monster.speed = 370 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 5000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Banshee", chance = 50, interval = 4000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 40000, maxCount = 98}, + {id = 8752, chance = 100000}, + {id = 2391, chance = 2300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -80, maxDamage = -135}, + {name ="combat", interval = 1000, chance = 9, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -300, radius = 4, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_HEALING, minDamage = 100, maxDamage = 195, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 3000, chance = 30, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -20}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_inquisition/the_weakened_count.lua b/data/monster/quests/the_inquisition/the_weakened_count.lua new file mode 100644 index 00000000000..ef4a3e4cd03 --- /dev/null +++ b/data/monster/quests/the_inquisition/the_weakened_count.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("The Weakened Count") +local monster = {} + +monster.description = "The Weakened Count" +monster.experience = 450 +monster.outfit = { + lookType = 68, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 740 +monster.maxHealth = 740 +monster.race = "undead" +monster.corpse = 6006 +monster.speed = 370 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "1... 2... 2... Uh, can't concentrate.", yell = false} +} + +monster.loot = { + {id = 2148, chance = 40000, maxCount = 98}, + {id = 8752, chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -50, maxDamage = -75}, + {name ="combat", interval = 1000, chance = 9, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -100, radius = 4, effect = CONST_ME_SMALLCLOUDS, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_HEALING, minDamage = 50, maxDamage = 105, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 3000, chance = 30, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -20}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_inquisition/ungreez.lua b/data/monster/quests/the_inquisition/ungreez.lua new file mode 100644 index 00000000000..0945d1312fe --- /dev/null +++ b/data/monster/quests/the_inquisition/ungreez.lua @@ -0,0 +1,110 @@ +local mType = Game.createMonsterType("Ungreez") +local monster = {} + +monster.description = "Ungreez" +monster.experience = 500 +monster.outfit = { + lookType = 35, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 8200 +monster.maxHealth = 8200 +monster.race = "blood" +monster.corpse = 5995 +monster.speed = 240 +monster.manaCost = 10000 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I teach you that even heroes can die!", yell = true}, + {text = "You will die begging like the others did!", yell = true} +} + +monster.loot = { + {id = 2148, chance = 21000, maxCount = 90}, + {id = 2795, chance = 10000, maxCount = 6}, + {id = 7590, chance = 20000}, + {id = 7591, chance = 20000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 70, attack = 120}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -110, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, target = false}, + {name ="combat", interval = 1000, chance = 14, type = COMBAT_FIREDAMAGE, minDamage = -150, maxDamage = -250, range = 7, radius = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -400, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_PURPLEENERGY, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = -300, maxDamage = -380, length = 8, spread = 3, effect = CONST_ME_PURPLEENERGY, target = false} +} + +monster.defenses = { + defense = 55, + armor = 55, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 90, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 25}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_inquisition/ushuriel.lua b/data/monster/quests/the_inquisition/ushuriel.lua new file mode 100644 index 00000000000..b5c51d9a100 --- /dev/null +++ b/data/monster/quests/the_inquisition/ushuriel.lua @@ -0,0 +1,147 @@ +local mType = Game.createMonsterType("Ushuriel") +local monster = {} + +monster.description = "Ushuriel" +monster.experience = 10000 +monster.outfit = { + lookType = 12, + lookHead = 0, + lookBody = 95, + lookLegs = 19, + lookFeet = 112, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 31500 +monster.maxHealth = 31500 +monster.race = "fire" +monster.corpse = 6068 +monster.speed = 440 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You can't run or hide forever!", yell = false}, + {text = "I'm the executioner of the Seven!", yell = false}, + {text = "The final punishment awaits you!", yell = false}, + {text = "The judgement is guilty! The sentence is death!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 190}, + {name = "platinum coin", chance = 20000, maxCount = 26}, + {name = "orb", chance = 16666}, + {name = "life crystal", chance = 16666}, + {name = "mind stone", chance = 20000}, + {name = "spike sword", chance = 9090}, + {name = "fire sword", chance = 14285}, + {name = "giant sword", chance = 7692}, + {id = 2419, chance = 11111}, + {name = "warrior helmet", chance = 20000}, + {name = "strange helmet", chance = 8333}, + {name = "crown helmet", chance = 6250}, + {name = "royal helmet", chance = 20000}, + {name = "brown mushroom", chance = 50000, maxCount = 30}, + {name = "mysterious voodoo skull", chance = 12500}, + {name = "skull helmet", chance = 20000}, + {name = "iron ore", chance = 33333}, + {name = "spirit container", chance = 4761}, + {name = "flask of warrior's sweat", chance = 5555}, + {name = "enchanted chicken wing", chance = 7692}, + {name = "huge chunk of crude iron", chance = 14285}, + {name = "hardened bone", chance = 25000, maxCount = 20}, + {name = "demon horn", chance = 8333, maxCount = 2}, + {id = 6103, chance = 2063}, + {name = "demonic essence", chance = 100000}, + {id = 7385, chance = 10000}, + {name = "thaian sword", chance = 25000}, + {name = "dragon slayer", chance = 8333}, + {name = "runed sword", chance = 6666}, + {name = "great mana potion", chance = 20000}, + {name = "great health potion", chance = 20000}, + {name = "great spirit potion", chance = 20000}, + {name = "ultimate health potion", chance = 20000}, + {id = 9808, chance = 20000}, + {name = "gold ingot", chance = 16666} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1088}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = -250, maxDamage = -500, length = 10, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 1000, chance = 8, type = COMBAT_DEATHDAMAGE, minDamage = -30, maxDamage = -760, radius = 5, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_EARTHDAMAGE, minDamage = -200, maxDamage = -585, length = 8, spread = 3, effect = CONST_ME_SMALLPLANTS, target = false}, + {name ="combat", interval = 1000, chance = 8, type = COMBAT_ICEDAMAGE, minDamage = 0, maxDamage = -430, radius = 6, effect = CONST_ME_ICETORNADO, target = false}, + {name ="drunk", interval = 3000, chance = 11, radius = 6, effect = CONST_ME_SOUND_PURPLE, target = false}, + -- energy damage + {name ="condition", type = CONDITION_ENERGY, interval = 2000, chance = 15, minDamage = -250, maxDamage = -250, radius = 4, effect = CONST_ME_ENERGYHIT, target = false} +} + +monster.defenses = { + defense = 45, + armor = 50, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_HEALING, minDamage = 400, maxDamage = 600, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="speed", interval = 1000, chance = 4, speedChange = 400, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 7000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 30}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_inquisition/zugurosh.lua b/data/monster/quests/the_inquisition/zugurosh.lua new file mode 100644 index 00000000000..2a878b677c2 --- /dev/null +++ b/data/monster/quests/the_inquisition/zugurosh.lua @@ -0,0 +1,138 @@ +local mType = Game.createMonsterType("Zugurosh") +local monster = {} + +monster.description = "Zugurosh" +monster.experience = 10000 +monster.outfit = { + lookType = 12, + lookHead = 2, + lookBody = 35, + lookLegs = 57, + lookFeet = 91, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 90500 +monster.maxHealth = 90500 +monster.race = "fire" +monster.corpse = 8721 +monster.speed = 330 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 4500, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You will run out of resources soon enough!", yell = true}, + {text = "One little mistake and you're all are mine!", yell = false}, + {text = "I sense your strength fading!", yell = false}, + {text = "I know you will show a weakness!", yell = false}, + {text = "Your fear will make you prone to mistakes!", yell = false} +} + +monster.loot = { + {id = 6500, chance = 100000}, + {id = 2148, chance = 100000, maxCount = 194}, + {id = 9813, chance = 54000}, + {id = 9810, chance = 45000}, + {id = 7590, chance = 27000}, + {id = 8472, chance = 26000}, + {id = 7591, chance = 23000}, + {id = 8473, chance = 22000}, + {id = 9971, chance = 21000}, + {id = 2152, chance = 21000, maxCount = 30}, + {id = 6104, chance = 21000}, + {id = 5944, chance = 21000, maxCount = 10}, + {id = 2151, chance = 18000, maxCount = 30}, + {id = 5911, chance = 17000, maxCount = 10}, + {id = 2134, chance = 17000}, + {id = 5912, chance = 15000, maxCount = 10}, + {id = 5909, chance = 15000, maxCount = 10}, + {id = 5910, chance = 14000, maxCount = 10}, + {id = 5914, chance = 14000, maxCount = 10}, + {id = 5913, chance = 12000, maxCount = 10}, + {id = 5954, chance = 9700, maxCount = 2}, + {id = 2195, chance = 8700}, + {id = 2173, chance = 6000}, + {id = 2645, chance = 4500}, + {id = 2646, chance = 1500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -800}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -500, range = 4, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -500, length = 7, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -100, radius = 4, effect = CONST_ME_SMALLCLOUDS, target = false}, + -- fire + {name ="condition", type = CONDITION_FIRE, interval = 3000, chance = 20, minDamage = -10, maxDamage = -10, radius = 4, effect = CONST_ME_EXPLOSIONHIT, target = true}, + {name ="combat", interval = 1000, chance = 13, type = COMBAT_MANADRAIN, minDamage = -60, maxDamage = -200, radius = 5, effect = CONST_ME_WATERSPLASH, target = false} +} + +monster.defenses = { + defense = 55, + armor = 45, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_HEALING, minDamage = 40, maxDamage = 60, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_HEALING, minDamage = 400, maxDamage = 600, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="invisible", interval = 1000, chance = 5, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 25}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_new_frontier/baron_brute.lua b/data/monster/quests/the_new_frontier/baron_brute.lua new file mode 100644 index 00000000000..1b22f7d6f89 --- /dev/null +++ b/data/monster/quests/the_new_frontier/baron_brute.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Baron Brute") +local monster = {} + +monster.description = "Baron Brute" +monster.experience = 3000 +monster.outfit = { + lookType = 2, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5025 +monster.maxHealth = 5025 +monster.race = "blood" +monster.corpse = 6008 +monster.speed = 290 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Mash'n!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -474} +} + +monster.defenses = { + defense = 35, + armor = 22 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_new_frontier/coldheart.lua b/data/monster/quests/the_new_frontier/coldheart.lua new file mode 100644 index 00000000000..c4f88ae96e1 --- /dev/null +++ b/data/monster/quests/the_new_frontier/coldheart.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Coldheart") +local monster = {} + +monster.description = "Coldheart" +monster.experience = 3500 +monster.outfit = { + lookType = 261, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 7000 +monster.maxHealth = 7000 +monster.race = "undead" +monster.corpse = 7282 +monster.speed = 195 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 9 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 50, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 100, attack = 40}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ICEDAMAGE, minDamage = 0, maxDamage = -710, length = 8, spread = 3, effect = CONST_ME_ICEAREA, target = false} +} + +monster.defenses = { + defense = 26, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_new_frontier/doomhowl.lua b/data/monster/quests/the_new_frontier/doomhowl.lua new file mode 100644 index 00000000000..939a75b2ad4 --- /dev/null +++ b/data/monster/quests/the_new_frontier/doomhowl.lua @@ -0,0 +1,102 @@ +local mType = Game.createMonsterType("Doomhowl") +local monster = {} + +monster.description = "Doomhowl" +monster.experience = 3750 +monster.outfit = { + lookType = 308, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 8500 +monster.maxHealth = 8500 +monster.race = "blood" +monster.corpse = 20607 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -645, radius = 3, target = false}, + {name ="combat", interval = 4000, chance = 20, type = COMBAT_PHYSICALDAMAGE, effect = CONST_ME_SOUND_GREEN, target = false} +} + +monster.defenses = { + defense = 55, + armor = 50, + {name ="speed", interval = 2000, chance = 10, speedChange = 390, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 15}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_new_frontier/dreadwing.lua b/data/monster/quests/the_new_frontier/dreadwing.lua new file mode 100644 index 00000000000..8a154876290 --- /dev/null +++ b/data/monster/quests/the_new_frontier/dreadwing.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Dreadwing") +local monster = {} + +monster.description = "Dreadwing" +monster.experience = 3750 +monster.outfit = { + lookType = 307, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 8500 +monster.maxHealth = 8500 +monster.race = "blood" +monster.corpse = 9829 +monster.speed = 245 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 100, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "More blood! More!", yell = true} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -240, condition = {type = CONDITION_POISON, totalDamage = 6, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -70, maxDamage = -180, range = 7, shootEffect = CONST_ANI_POISON, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DROWNDAMAGE, minDamage = -130, maxDamage = -237, radius = 6, effect = CONST_ME_SOUND_WHITE, target = false}, + {name ="mutated bat curse", interval = 2000, chance = 10, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -12, maxDamage = -12, length = 4, spread = 3, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 80, maxDamage = 95, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_new_frontier/fatality.lua b/data/monster/quests/the_new_frontier/fatality.lua new file mode 100644 index 00000000000..3fa84f112ce --- /dev/null +++ b/data/monster/quests/the_new_frontier/fatality.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Fatality") +local monster = {} + +monster.description = "Fatality" +monster.experience = 3250 +monster.outfit = { + lookType = 113, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 6000 +monster.maxHealth = 6000 +monster.race = "blood" +monster.corpse = 4251 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 31, attack = 100} +} + +monster.defenses = { + defense = 19, + armor = 16 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_new_frontier/haunter.lua b/data/monster/quests/the_new_frontier/haunter.lua new file mode 100644 index 00000000000..f0b978963a0 --- /dev/null +++ b/data/monster/quests/the_new_frontier/haunter.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("Haunter") +local monster = {} + +monster.description = "Haunter" +monster.experience = 4000 +monster.outfit = { + lookType = 320, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 8500 +monster.maxHealth = 8500 +monster.race = "blood" +monster.corpse = 9915 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 9 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Surrender and I'll end it quick.", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 50, attack = 50}, + {name ="combat", interval = 2000, chance = 16, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -130, radius = 3, effect = CONST_ME_ENERGYHIT, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 16, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true} +} + +monster.defenses = { + defense = 20, + armor = 25, + {name ="combat", interval = 2000, chance = 16, type = COMBAT_HEALING, minDamage = 100, maxDamage = 155, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 16, speedChange = 360, effect = CONST_ME_MAGIC_RED, target = false, duration = 80000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_new_frontier/incineron.lua b/data/monster/quests/the_new_frontier/incineron.lua new file mode 100644 index 00000000000..0fff1c8d5cc --- /dev/null +++ b/data/monster/quests/the_new_frontier/incineron.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Incineron") +local monster = {} + +monster.description = "Incineron" +monster.experience = 3500 +monster.outfit = { + lookType = 243, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 7000 +monster.maxHealth = 7000 +monster.race = "fire" +monster.corpse = 6324 +monster.speed = 260 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 9 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="combat", interval = 2000, chance = 35, type = COMBAT_FIREDAMAGE, minDamage = -700, maxDamage = -1025, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 35, type = COMBAT_FIREDAMAGE, minDamage = 0, maxDamage = -395, range = 7, radius = 7, effect = CONST_ME_FIREAREA, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_new_frontier/menace.lua b/data/monster/quests/the_new_frontier/menace.lua new file mode 100644 index 00000000000..7b971064ffe --- /dev/null +++ b/data/monster/quests/the_new_frontier/menace.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Menace") +local monster = {} + +monster.description = "Menace" +monster.experience = 3250 +monster.outfit = { + lookType = 113, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 6000 +monster.maxHealth = 6000 +monster.race = "blood" +monster.corpse = 4251 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 9 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 33, attack = 100} +} + +monster.defenses = { + defense = 19, + armor = 16 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_new_frontier/mooh'tah_master.lua b/data/monster/quests/the_new_frontier/mooh'tah_master.lua new file mode 100644 index 00000000000..85c55c36ae0 --- /dev/null +++ b/data/monster/quests/the_new_frontier/mooh'tah_master.lua @@ -0,0 +1,103 @@ +local mType = Game.createMonsterType("Mooh'Tah Master") +local monster = {} + +monster.description = "a mooh'tah master" +monster.experience = 0 +monster.outfit = { + lookType = 611, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 185 +monster.maxHealth = 185 +monster.race = "blood" +monster.corpse = 23462 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Kirll Karrrl!", yell = false}, + {text = "Kaplar!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="energy beam", interval = 2000, chance = 10, minDamage = 0, maxDamage = -500, range = 1, target = false}, + {name ="berserk", interval = 2000, chance = 10, minDamage = 0, maxDamage = -100, range = 1, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_new_frontier/rocko.lua b/data/monster/quests/the_new_frontier/rocko.lua new file mode 100644 index 00000000000..f40f44ebab1 --- /dev/null +++ b/data/monster/quests/the_new_frontier/rocko.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Rocko") +local monster = {} + +monster.description = "Rocko" +monster.experience = 3400 +monster.outfit = { + lookType = 67, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "blood" +monster.corpse = 6005 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 9 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 28, attack = 100}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -125, length = 8, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -411, length = 8, spread = 3, effect = CONST_ME_GROUNDSHAKER, target = false} +} + +monster.defenses = { + defense = 18, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 15}, + {type = COMBAT_ENERGYDAMAGE, percent = 25}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_new_frontier/shard_of_corruption.lua b/data/monster/quests/the_new_frontier/shard_of_corruption.lua new file mode 100644 index 00000000000..217ce22c4aa --- /dev/null +++ b/data/monster/quests/the_new_frontier/shard_of_corruption.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Shard Of Corruption") +local monster = {} + +monster.description = "a shard of corruption" +monster.experience = 5 +monster.outfit = { + lookType = 67, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 600 +monster.maxHealth = 600 +monster.race = "undead" +monster.corpse = 6005 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -115, range = 7, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_GREEN_RINGS, target = true} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 60}, + {type = COMBAT_ENERGYDAMAGE, percent = 25}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = -15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_new_frontier/the_axeorcist.lua b/data/monster/quests/the_new_frontier/the_axeorcist.lua new file mode 100644 index 00000000000..c3edb257cbd --- /dev/null +++ b/data/monster/quests/the_new_frontier/the_axeorcist.lua @@ -0,0 +1,104 @@ +local mType = Game.createMonsterType("The Axeorcist") +local monster = {} + +monster.description = "the Axeorcist" +monster.experience = 3000 +monster.outfit = { + lookType = 8, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5100 +monster.maxHealth = 5100 +monster.race = "blood" +monster.corpse = 5980 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 9 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "DEESTRUCTIOON!", yell = true}, + {text = "Blood! Carnage! Muhahaha!", yell = true} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -276}, + {name ="combat", interval = 3000, chance = 34, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -230, range = 7, shootEffect = CONST_ANI_WHIRLWINDAXE, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -200, radius = 3, effect = CONST_ME_BLOCKHIT, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="speed", interval = 2000, chance = 15, speedChange = 290, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_new_frontier/the_dreadorian.lua b/data/monster/quests/the_new_frontier/the_dreadorian.lua new file mode 100644 index 00000000000..bca2000fbc2 --- /dev/null +++ b/data/monster/quests/the_new_frontier/the_dreadorian.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("The Dreadorian") +local monster = {} + +monster.description = "the Dreadorian" +monster.experience = 4000 +monster.outfit = { + lookType = 234, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 9000 +monster.maxHealth = 9000 +monster.race = "blood" +monster.corpse = 6328 +monster.speed = 370 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 64, attack = 100} +} + +monster.defenses = { + defense = 35, + armor = 25, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_HEALING, minDamage = 100, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 90}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_new_frontier/tirecz.lua b/data/monster/quests/the_new_frontier/tirecz.lua new file mode 100644 index 00000000000..6a15acdeb25 --- /dev/null +++ b/data/monster/quests/the_new_frontier/tirecz.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("Tirecz") +local monster = {} + +monster.description = "Tirecz" +monster.experience = 6000 +monster.outfit = { + lookType = 334, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 25000 +monster.maxHealth = 25000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hissss!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 72, attack = 100}, + {name ="invisible", interval = 2000, chance = 25, effect = CONST_ME_FIREAREA}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_FIREDAMAGE, minDamage = -120, maxDamage = -460, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -290, radius = 3, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="combat", interval = 3000, chance = 30, type = COMBAT_ENERGYDAMAGE, minDamage = -80, maxDamage = -345, length = 8, spread = 3, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -370, radius = 7, target = false} +} + +monster.defenses = { + defense = 19, + armor = 16 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 30}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_new_frontier/tremorak.lua b/data/monster/quests/the_new_frontier/tremorak.lua new file mode 100644 index 00000000000..7c09bbb8075 --- /dev/null +++ b/data/monster/quests/the_new_frontier/tremorak.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("Tremorak") +local monster = {} + +monster.description = "Tremorak" +monster.experience = 1300 +monster.outfit = { + lookType = 285, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 8933 +monster.speed = 290 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "*STOMP STOMP*", yell = true} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 36, attack = 50}, + {name ="combat", interval = 2000, chance = 16, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -255, radius = 7, effect = CONST_ME_GROUNDSHAKER, target = false}, + {name ="combat", interval = 2000, chance = 16, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -405, length = 8, spread = 3, effect = CONST_ME_GROUNDSHAKER, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 16, range = 7, shootEffect = CONST_ANI_POISON, target = true} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 16, type = COMBAT_HEALING, minDamage = 75, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 85}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 45} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_percht_queens_island/baleful_bunny.lua b/data/monster/quests/the_percht_queens_island/baleful_bunny.lua new file mode 100644 index 00000000000..084a9fd3f1c --- /dev/null +++ b/data/monster/quests/the_percht_queens_island/baleful_bunny.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Baleful Bunny") +local monster = {} + +monster.description = "an baleful bunny" +monster.experience = 450 +monster.outfit = { + lookType = 1157, + lookHead = 95, + lookBody = 42, + lookLegs = 19, + lookFeet = 57, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1742 +monster.Bestiary = { + class = "Mammal", + race = BESTY_RACE_MAMMAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Percht Island." + } + +monster.health = 500 +monster.maxHealth = 500 +monster.race = "blood" +monster.corpse = 35137 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Borborygmus... borborygmus...", yell = false} +} + +monster.loot = { + {name = "platinum coin", chance = 100000}, + {name = "terra amulet", chance = 8480}, + {name = "snakebite rod", chance = 7420}, + {name = "leaf star", chance = 7120, maxCount = 2}, + {name = "lightning pendant", chance = 6820}, + {name = "strange talisman", chance = 5760}, + {name = "sacred tree amulet", chance = 2730}, + {name = "yetislippers", chance = 450} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -200}, + {name ="combat", interval = 2000, chance = 1, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -150, radius = 4, effect = CONST_ME_POFF, target = true}, + {name ="combat", interval = 2000, chance = 1, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -150, radius = 1, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="combat", interval = 2000, chance = 111, type = COMBAT_LIFEDRAIN, minDamage = -100, maxDamage = -150, radius = 4, target = true} +} + +monster.defenses = { + defense = 35, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 5}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_percht_queens_island/bonny_bunny.lua b/data/monster/quests/the_percht_queens_island/bonny_bunny.lua new file mode 100644 index 00000000000..079ada9bf9f --- /dev/null +++ b/data/monster/quests/the_percht_queens_island/bonny_bunny.lua @@ -0,0 +1,97 @@ +local mType = Game.createMonsterType("Bonny Bunny") +local monster = {} + +monster.description = "an bonny bunny" +monster.experience = 0 +monster.outfit = { + lookType = 1158, + lookHead = 95, + lookBody = 42, + lookLegs = 19, + lookFeet = 57, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 200 +monster.maxHealth = 200 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -200}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_FIREDAMAGE, minDamage = -90, maxDamage = -150, length = 4, spread = 3, effect = CONST_ME_HEARTS, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_percht_queens_island/bright_percht_sleigh.lua b/data/monster/quests/the_percht_queens_island/bright_percht_sleigh.lua new file mode 100644 index 00000000000..68e77f1730b --- /dev/null +++ b/data/monster/quests/the_percht_queens_island/bright_percht_sleigh.lua @@ -0,0 +1,92 @@ +local mType = Game.createMonsterType("Bright Percht Sleigh") +local monster = {} + +monster.description = "a bright percht sleigh" +monster.experience = 500 +monster.outfit = { + lookType = 1164, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2300 +monster.maxHealth = 2300 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 40, + armor = 79 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_percht_queens_island/cold_percht_sleigh.lua b/data/monster/quests/the_percht_queens_island/cold_percht_sleigh.lua new file mode 100644 index 00000000000..36526aaa233 --- /dev/null +++ b/data/monster/quests/the_percht_queens_island/cold_percht_sleigh.lua @@ -0,0 +1,92 @@ +local mType = Game.createMonsterType("Cold Percht Sleigh") +local monster = {} + +monster.description = "a cold percht sleigh" +monster.experience = 500 +monster.outfit = { + lookType = 1163, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2300 +monster.maxHealth = 2300 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 40, + armor = 79 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_percht_queens_island/dark_percht_sleigh.lua b/data/monster/quests/the_percht_queens_island/dark_percht_sleigh.lua new file mode 100644 index 00000000000..a06a9454647 --- /dev/null +++ b/data/monster/quests/the_percht_queens_island/dark_percht_sleigh.lua @@ -0,0 +1,92 @@ +local mType = Game.createMonsterType("Dark Percht Sleigh") +local monster = {} + +monster.description = "a dark percht sleigh" +monster.experience = 500 +monster.outfit = { + lookType = 1165, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2300 +monster.maxHealth = 2300 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 40, + armor = 79 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_percht_queens_island/percht.lua b/data/monster/quests/the_percht_queens_island/percht.lua new file mode 100644 index 00000000000..ef181735f2e --- /dev/null +++ b/data/monster/quests/the_percht_queens_island/percht.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Percht") +local monster = {} + +monster.description = "an percht" +monster.experience = 600 +monster.outfit = { + lookType = 1161, + lookHead = 95, + lookBody = 42, + lookLegs = 19, + lookFeet = 57, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1740 +monster.Bestiary = { + class = "Fey", + race = BESTY_RACE_FEY, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Percht Island." + } + +monster.health = 620 +monster.maxHealth = 620 +monster.race = "blood" +monster.corpse = 35125 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 50, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Krikik krikik!", yell = false}, + {text = "Shzzzp shzzzp shzzp!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 60}, + {name = "fireworks capsule", chance = 12360}, + {name = "percht horns", chance = 9790}, + {name = "grainy fireworks powder", chance = 6640}, + {name = "broken bell", chance = 5390}, + {name = "versicolour fireworks powder", chance = 4220}, + {id = 35152, chance = 3190}, + {name = "green fireworks powder", chance = 2790}, + {name = "purple fireworks powder", chance = 2090}, + {name = "turquoise fireworks powder", chance = 1980}, + {name = "orange fireworks powder", chance = 1870}, + {name = "yellow fireworks powder", chance = 1870}, + {name = "red fireworks powder", chance = 1830}, + {name = "magma amulet", chance = 1320}, + {name = "magma coat", chance = 1320}, + {name = "magma monocle", chance = 950}, + {name = "magma legs", chance = 510} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -200}, + {name ="combat", interval = 2000, chance = 70, type = COMBAT_ICEDAMAGE, minDamage = -100, maxDamage = -125, range = 7, shootEffect = CONST_ANI_SNOWBALL, target = false}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_ICEDAMAGE, minDamage = -90, maxDamage = -250, length = 3, spread = 0, effect = CONST_ME_GIANTICE, target = false}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -250, radius = 3, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -250, radius = 4, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -250, length = 3, spread = 0, effect = CONST_ME_FIREATTACK, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -20}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_percht_queens_island/percht_minion.lua b/data/monster/quests/the_percht_queens_island/percht_minion.lua new file mode 100644 index 00000000000..914bb228a33 --- /dev/null +++ b/data/monster/quests/the_percht_queens_island/percht_minion.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Percht Minion") +local monster = {} + +monster.description = "a percht minion" +monster.experience = 0 +monster.outfit = { + lookType = 53, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 55 +monster.maxHealth = 55 +monster.race = "blood" +monster.corpse = 5998 +monster.speed = 160 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Brrr", yell = false}, + {text = "Broar!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -20} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_percht_queens_island/schiach.lua b/data/monster/quests/the_percht_queens_island/schiach.lua new file mode 100644 index 00000000000..9c1bafd2c80 --- /dev/null +++ b/data/monster/quests/the_percht_queens_island/schiach.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Schiach") +local monster = {} + +monster.description = "an schiach" +monster.experience = 580 +monster.outfit = { + lookType = 1162, + lookHead = 19, + lookBody = 10, + lookLegs = 19, + lookFeet = 57, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1741 +monster.Bestiary = { + class = "Fey", + race = BESTY_RACE_FEY, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Percht Island." + } + +monster.health = 600 +monster.maxHealth = 600 +monster.race = "blood" +monster.corpse = 35127 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 50, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Krik Krik!", yell = false}, + {text = "Psh psh psh!!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 50}, + {name = "fireworks capsule", chance = 13220}, + {name = "broken bell", chance = 11070}, + {name = "grainy fireworks powder", chance = 7700}, + {name = "versicolour fireworks powder", chance = 4290}, + {name = "percht horns", chance = 3960}, + {name = "bright bell", chance = 2920}, + {name = "green fireworks powder", chance = 2550}, + {name = "purple fireworks powder", chance = 2440}, + {name = "turquoise fireworks powder", chance = 40}, + {name = "orange fireworks powder", chance = 2260}, + {name = "yellow fireworks powder", chance = 2180}, + {name = "red fireworks powder", chance = 1780}, + {name = "glacier kilt", chance = 1180}, + {name = "glacier robe", chance = 630} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -200}, + {name ="combat", interval = 2000, chance = 70, type = COMBAT_ICEDAMAGE, minDamage = -100, maxDamage = -125, range = 7, shootEffect = CONST_ANI_SNOWBALL, target = false}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_ICEDAMAGE, minDamage = -90, maxDamage = -250, length = 3, spread = 0, effect = CONST_ME_GIANTICE, target = false}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -250, radius = 3, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -250, radius = 4, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -250, length = 3, spread = 0, effect = CONST_ME_FIREATTACK, target = false} +} + +monster.defenses = { + defense = 43, + armor = 43 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = -20}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_percht_queens_island/the_percht_queen.lua b/data/monster/quests/the_percht_queens_island/the_percht_queen.lua new file mode 100644 index 00000000000..f65032e0cce --- /dev/null +++ b/data/monster/quests/the_percht_queens_island/the_percht_queen.lua @@ -0,0 +1,140 @@ +local mType = Game.createMonsterType("The Percht Queen") +local monster = {} + +monster.description = "The Percht Queen" +monster.experience = 500 +monster.outfit = { + lookTypeEx = 35168 +} + +monster.health = 2300 +monster.maxHealth = 2300 +monster.race = "undead" +monster.corpse = 35101 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "piggy bank", chance = 80000}, + {name = "royal star", chance = 80000, maxCount = 100}, + {name = "platinum coin", chance = 80000, maxCount = 5}, + {name = "energy bar", chance = 75000}, + {name = "supreme health potion", chance = 65000, maxCount = 20}, + {name = "huge chunk of crude iron", chance = 64000}, + {name = "mysterious remains", chance = 63000}, + {name = "ultimate spirit potion", chance = 62000, maxCount = 20}, + {name = "ultimate mana potion", chance = 61000, maxCount = 20}, + {name = "bullseye potion", chance = 25500, maxCount = 10}, + {name = "chaos mace", chance = 25000}, + {id = 35108, chance = 24500}, + {name = "berserk potion", chance = 23000, maxCount = 10}, + {name = "red gem", chance = 22500}, + {name = "soul stone", chance = 224000}, + {id = 35104, chance = 25000}, + {name = "flames of the percht queen", chance = 18000}, + {name = "small ladybug", chance = 24980}, + {name = "gold ingot", chance = 22480}, + {name = "crystal coin", chance = 24890, maxCount = 2}, + {id = 7632, chance = 21580}, + {name = "skull staff", chance = 19850}, + {name = "magic sulphur", chance = 25480}, + {name = "percht queen's frozen heart", chance = 26800}, + {name = "percht skull", chance = 25842}, + {id = 35106, chance = 25840}, + {name = "silver token", chance = 5480, maxCount = 5}, + {name = "percht handkerchief", chance = 5808}, + {name = "ring of the sky", chance = 5100}, + {id = 26185, chance = 8486}, + {id = 35148, chance = 4848}, + {name = "percht broom", chance = 6485}, + {name = "ice hatchet", chance = 5485}, + {id = 26189, chance = 4858}, + {id = 26187, chance = 3485}, + {name = "yellow gem", chance = 5485}, + {name = "violet gem", chance = 6485}, + {id = 26200, chance = 7848}, + {id = 26199, chance = 5485}, + {name = "green gem", chance = 5485}, + {name = "blue gem", chance = 5845}, + {name = "frozen chain", chance = 5485}, + {id = 26198, chance = 5158},-- collar of blue plasma + {name = "horseshoe", chance = 1250}, + {name = "golden horseshoe", chance = 2510}, + {name = "abyss hammer", chance = 1480}, + {name = "golden bell", chance = 2548}, + {name = "golden cotton reel", chance = 1254}, + {name = "lucky pig", chance = 2540} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -100, maxDamage = -200, range = 7, shootEffect = CONST_ANI_ICE, target = false} +} + +monster.defenses = { + defense = 40, + armor = 79 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 90}, + {type = COMBAT_ENERGYDAMAGE, percent = 80}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 70}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 80}, + {type = COMBAT_DEATHDAMAGE , percent = 90} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_percht_queens_island/warm_fire.lua b/data/monster/quests/the_percht_queens_island/warm_fire.lua new file mode 100644 index 00000000000..201f43d1860 --- /dev/null +++ b/data/monster/quests/the_percht_queens_island/warm_fire.lua @@ -0,0 +1,92 @@ +local mType = Game.createMonsterType("Warm Fire") +local monster = {} + +monster.description = "a warm fire" +monster.experience = 220 +monster.outfit = { + lookType = 49, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 200 +monster.maxHealth = 200 +monster.race = "fire" +monster.corpse = 8964 +monster.speed = 95 +monster.manaCost = 690 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -25}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/biting_cold.lua b/data/monster/quests/the_secret_library/biting_cold.lua new file mode 100644 index 00000000000..dd33420eac5 --- /dev/null +++ b/data/monster/quests/the_secret_library/biting_cold.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Biting Cold") +local monster = {} + +monster.description = "Biting Cold" +monster.experience = 0 +monster.outfit = { + lookType = 53, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "blood" +monster.corpse = 5998 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/bone_jaw.lua b/data/monster/quests/the_secret_library/bone_jaw.lua new file mode 100644 index 00000000000..3c42d9c421c --- /dev/null +++ b/data/monster/quests/the_secret_library/bone_jaw.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Bone Jaw") +local monster = {} + +monster.description = "a bone jaw" +monster.experience = 0 +monster.outfit = { + lookType = 384, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 13323 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/bosses/brokul.lua b/data/monster/quests/the_secret_library/bosses/brokul.lua new file mode 100644 index 00000000000..09cc83994e1 --- /dev/null +++ b/data/monster/quests/the_secret_library/bosses/brokul.lua @@ -0,0 +1,139 @@ +local mType = Game.createMonsterType("Brokul") +local monster = {} + +monster.description = "Brokul" +monster.experience = 23000 +monster.outfit = { + lookType = 1076, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "blood" +monster.corpse = 33376 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 5 + +monster.changeTarget = { + interval = 1000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = true, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 60, + targetDistance = 1, + runHealth = 60, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "neutral deepling warrior", chance = 70, interval = 1000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "small sapphire", chance = 2854, maxCount = 10}, + {name = "gold coin", chance = 70000, maxCount = 60}, + {name = "platinum coin", chance = 80000, maxCount = 10}, + {name = "Gold Ingot", chance = 3448, maxCount = 10}, + {name = "Broccoli", chance = 2439, maxCount = 10}, + {name = "Small Diamond", chance = 498, maxCount = 10}, + {name = "Blue Gem", chance = 2500}, + {name = "Red Gem", chance = 2000}, + {name = "Deepling Ceremonial Dagger", chance = 200}, + {name = "Deepling Fork", chance = 200}, + {name = "True Book of Death", chance = 70000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -500}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_HOLYDAMAGE, minDamage = -100, maxDamage = -700, length = 8, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_PHYSICALDAMAGE, minDamage = -300, maxDamage = -700, radius = 4, effect = CONST_ME_EXPLOSIONAREA, target = false}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_FIREDAMAGE, minDamage = -300, maxDamage = -840, length = 8, spread = 3, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_HOLYDAMAGE, minDamage = -300, maxDamage = -700, length = 8, spread = 3, effect = CONST_ME_HOLYAREA, target = false}, + {name ="combat", interval = 2000, chance = 29, type = COMBAT_ICEDAMAGE, minDamage = -300, maxDamage = -840, range = 7, radius = 4, effect = CONST_ME_FIREAREA, target = true} +} + +monster.defenses = { + defense = 60, + armor = 86, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_HEALING, minDamage = 200, maxDamage = 500, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_HEALING, minDamage = 500, maxDamage = 1000, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -20}, + {type = COMBAT_EARTHDAMAGE, percent = -20}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/bosses/ghulosh.lua b/data/monster/quests/the_secret_library/bosses/ghulosh.lua new file mode 100644 index 00000000000..99494720b28 --- /dev/null +++ b/data/monster/quests/the_secret_library/bosses/ghulosh.lua @@ -0,0 +1,151 @@ +local mType = Game.createMonsterType("Ghulosh") +local monster = {} + +monster.description = "Ghulosh" +monster.experience = 100000 +monster.outfit = { + lookType = 1062, + lookHead = 79, + lookBody = 94, + lookLegs = 94, + lookFeet = 94, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 300000 +monster.maxHealth = 300000 +monster.race = "blood" +monster.corpse = 29369 +monster.speed = 100 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 4 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 98, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 90000, maxCount = 53}, + {name = "crystal coin", chance = 90000, maxCount = 12}, + {name = "great spirit potion", chance = 90000, maxCount = 8}, + {name = "supreme health potion", chance = 90000, maxCount = 8}, + {name = "ultimate mana potion", chance = 90000, maxCount = 10}, + {name = "ultimate spirit potion", chance = 90000, maxCount = 8}, + {name = "silver token", chance = 90000, maxCount = 6}, + {name = "bullseye potion", chance = 90000}, + {name = "demon horn", chance = 90000}, + {name = "magic sulphur", chance = 90000}, + {name = "red gem", chance = 90000}, + {name = "stone skin amulet", chance = 90000}, + {name = "yellow gem", chance = 90000}, + {name = "wand of voodoo", chance = 90000}, + {name = "mastermind potion", chance = 30000, maxCount = 2}, + {name = "onyx chip", chance = 30000, maxCount = 12}, + {name = "small diamond", chance = 30000, maxCount = 12}, + {name = "small emerald", chance = 30000, maxCount = 12}, + {name = "small ruby", chance = 30000, maxCount = 12}, + {name = "small topaz", chance = 30000, maxCount = 12}, + {name = "blue gem", chance = 30000}, + {name = "solid rage", chance = 30000}, + {name = "gold token", chance = 1000}, + {name = "butcher's axe", chance = 1000}, + {name = "dreaded cleaver", chance = 1000}, + {name = "mercenary sword", chance = 1000}, + {id = 33094, chance = 1000}, + {id = 9814, chance = 1000}, + {id = 9820, chance = 1000}, + {name = "epaulette", chance = 500}, + {name = "giant emerald", chance = 500}, + {name = "unliving demonbone", chance = 500} +} + +monster.attacks = { + {name ="melee", interval = 1000, chance = 100, skill = 150, attack = 280}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_DEATHDAMAGE, minDamage = -900, maxDamage = -1500, length = 8, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_DEATHDAMAGE, minDamage = -210, maxDamage = -600, length = 8, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_DEATHDAMAGE, minDamage = -210, maxDamage = -600, range = 7, radius = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 250}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_LIFEDRAIN, minDamage = -1500, maxDamage = -2000, range = 7, radius = 3, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 1}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/bosses/gorzindel.lua b/data/monster/quests/the_secret_library/bosses/gorzindel.lua new file mode 100644 index 00000000000..e90a66035fd --- /dev/null +++ b/data/monster/quests/the_secret_library/bosses/gorzindel.lua @@ -0,0 +1,160 @@ +local mType = Game.createMonsterType("Gorzindel") +local monster = {} + +monster.description = "Gorzindel" +monster.experience = 100000 +monster.outfit = { + lookType = 1062, + lookHead = 94, + lookBody = 100, + lookLegs = 0, + lookFeet = 0, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 300000 +monster.maxHealth = 300000 +monster.race = "blood" +monster.corpse = 25151 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 4 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "THE STOLEN POWERS HEAL GORZINDEL!", yell = false}, + {text = "GORZINDEL USES THE POWERS OF STOLEN SPELLS!", yell = false}, + {text = "GORZINDEL UNLEASHES THE STOLEN POWERS OF DEATH!", yell = false} +} + +monster.loot = { + {name = "platinum coin", chance = 90000}, + {name = "crystal coin", chance = 90000, maxCount = 8}, + {name = "small amethyst", chance = 90000, maxCount = 12}, + {name = "small diamond", chance = 90000, maxCount = 12}, + {name = "small emerald", chance = 90000, maxCount = 12}, + {name = "small ruby", chance = 90000, maxCount = 12}, + {name = "small topaz", chance = 90000, maxCount = 12}, + {name = "onyx chip", chance = 90000, maxCount = 12}, + {name = "great spirit potion", chance = 90000, maxCount = 8}, + {name = "supreme health potion", chance = 90000, maxCount = 12}, + {name = "Ultimate health potion", chance = 90000, maxCount = 18}, + {name = "Ultimate mana potion", chance = 90000, maxCount = 8}, + {name = "Ultimate spirit potion", chance = 90000, maxCount = 12}, + {name = "berserk potion", chance = 90000, maxCount = 2}, + {name = "bullseye potion", chance = 90000, maxCount = 2}, + {name = "mastermind potion", chance = 90000, maxCount = 2}, + {name = "chaos mace", chance = 30000}, + {name = "crown armor", chance = 30000}, + {name = "curious matter", chance = 30000}, + {name = "demon horn", chance = 30000}, + {name = "dreaded cleaver", chance = 30000}, + {id = 7632, chance = 30000}, + {name = "gold token", chance = 1000, maxCount = 6}, + {name = "green gem", chance = 1000}, + {name = "knowledgeable book", chance = 1000}, + {name = "ominous book", chance = 1000}, + {name = "magic sulphur", chance = 1000, maxCount = 2}, + {name = "muck rod", chance = 1000}, + {name = "red gem", chance = 1000}, + {id = 9820, chance = 1000}, + {id = 9814, chance = 1000}, + {name = "silver Token", chance = 1000, maxCount = 6}, + {name = "sinister book", chance = 1000}, + {name = "spellbook of warding", chance = 1000}, + {name = "steel boots", chance = 1000}, + {name = "stone skin amulet", chance = 1000}, + {name = "wand of cosmic Energy", chance = 1000}, + {name = "yellow gem", chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 100, attack = 100}, + {name ="melee", interval = 2000, chance = 15, minDamage = -600, maxDamage = -2800}, + {name ="melee", interval = 1000, chance = 15, minDamage = -800, maxDamage = -1300}, + {name ="melee", interval = 1000, chance = 15, minDamage = -800, maxDamage = -1000}, + {name ="melee", interval = 1000, chance = 15, minDamage = -200, maxDamage = -800}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -200, maxDamage = -600, radius = 9, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 1}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/bosses/grand_canon_dominus.lua b/data/monster/quests/the_secret_library/bosses/grand_canon_dominus.lua new file mode 100644 index 00000000000..ed93916b2ee --- /dev/null +++ b/data/monster/quests/the_secret_library/bosses/grand_canon_dominus.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Grand Canon Dominus") +local monster = {} + +monster.description = "Grand Canon Dominus" +monster.experience = 11000 +monster.outfit = { + lookType = 1071, + lookHead = 57, + lookBody = 75, + lookLegs = 77, + lookFeet = 86, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 15000 +monster.maxHealth = 15000 +monster.race = "blood" +monster.corpse = 32437 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 5}, + {name = "great health potion", chance = 100000, maxCount = 3}, + {name = "assassin star", chance = 100000, maxCount = 2}, + {name = "small amethyst", chance = 100000, maxCount = 2}, + {name = "golden armor", chance = 1700}, + {name = "mastermind shield", chance = 1100}, + {name = "patch of fine cloth", chance = 1000}, + {name = "red gem", chance = 1800}, + {name = "violet gem", chance = 1850}, + {name = "falcon bow", chance = 180}, + {name = "falcon wand", chance = 180}, + {name = "falcon plate", chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -150, maxDamage = -700}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -720, range = 7, shootEffect = CONST_ANI_ETHEREALSPEAR, target = false}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_HOLYDAMAGE, minDamage = -100, maxDamage = -1000, length = 8, spread = 3, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -200, maxDamage = -700, range = 5, radius = 3, effect = CONST_ME_HOLYAREA, target = false}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -200, maxDamage = -700, range = 5, radius = 3, effect = CONST_ME_SMALLCLOUDS, target = false} +} + +monster.defenses = { + defense = 50, + armor = 82, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 200, maxDamage = 550, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 1000, chance = 10, speedChange = 220, effect = CONST_ME_POFF, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/bosses/grand_chaplain_gaunder.lua b/data/monster/quests/the_secret_library/bosses/grand_chaplain_gaunder.lua new file mode 100644 index 00000000000..97839d666da --- /dev/null +++ b/data/monster/quests/the_secret_library/bosses/grand_chaplain_gaunder.lua @@ -0,0 +1,137 @@ +local mType = Game.createMonsterType("Grand Chaplain Gaunder") +local monster = {} + +monster.description = "Grand Chaplain Gaunder" +monster.experience = 14000 +monster.outfit = { + lookType = 1071, + lookHead = 57, + lookBody = 75, + lookLegs = 38, + lookFeet = 86, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 15000 +monster.maxHealth = 15000 +monster.race = "blood" +monster.corpse = 32433 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 3000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "concentrated demonic blood", chance = 50000, maxCount = 2}, + {name = "ham", chance = 50000, maxCount = 2}, + {name = "onyx arrow", chance = 35000, maxCount = 3}, + {name = "small diamond", chance = 30000, maxCount = 3}, + {name = "small emerald", chance = 30000, maxCount = 3}, + {name = "small enchanted amethyst", chance = 20000, maxCount = 3}, + {name = "damaged armor plates", chance = 2350, maxCount = 3}, + {id = 7632, chance = 12000, maxCount = 1}, -- giant shimmering pearl + {name = "knight armor", chance = 7000}, + {name = "patch of fine cloth", chance = 1800}, + {name = "spiked squelcher", chance = 3200}, + {name = "titan axe", chance = 2400}, + {name = "falcon battleaxe", chance = 200}, + {name = "falcon longsword", chance = 200}, + {name = "falcon mace", chance = 210}, + {name = "falcon plate", chance = 100}, + {name = "falcon shield", chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -150, maxDamage = -850}, + {name ="combat", interval = 1500, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -380, maxDamage = -890, range = 4, radius = 4, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -290, maxDamage = -720, range = 7, shootEffect = CONST_ANI_ETHEREALSPEAR, target = false}, + {name ="combat", interval = 1500, chance = 14, type = COMBAT_HOLYDAMAGE, minDamage = -300, maxDamage = -1000, length = 8, spread = 3, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -200, maxDamage = -700, range = 5, radius = 3, effect = CONST_ME_SMALLCLOUDS, target = false} +} + +monster.defenses = { + defense = 50, + armor = 82, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 200, maxDamage = 550, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 1000, chance = 10, speedChange = 220, effect = CONST_ME_POFF, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 55}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 15}, + {type = COMBAT_FIREDAMAGE, percent = 15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 40} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/bosses/grand_commander_soeren.lua b/data/monster/quests/the_secret_library/bosses/grand_commander_soeren.lua new file mode 100644 index 00000000000..c507bc78154 --- /dev/null +++ b/data/monster/quests/the_secret_library/bosses/grand_commander_soeren.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Grand Commander Soeren") +local monster = {} + +monster.description = "Grand Commander Soeren" +monster.experience = 10000 +monster.outfit = { + lookType = 1071, + lookHead = 38, + lookBody = 94, + lookLegs = 38, + lookFeet = 86, + lookAddons = 2, + lookMount = 0 +} + +monster.health = 17000 +monster.maxHealth = 17000 +monster.race = "blood" +monster.corpse = 32426 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Small Enchanted Amethyst", chance = 15000, maxCount = 3},--done + {name = "Platinum Coin", chance = 50000, maxCount = 3},--done + {name = "Great Health Potion", chance = 50000, maxCount = 3},--done + {name = "Small Ruby", chance = 12700, maxCount = 3},--done + {name = "Onyx Arrow", chance = 30000, maxCount = 3},--done + {name = "Golden Armor", chance = 1000}, + {name = "Green Gem", chance = 1300},--done + {name = "Damaged Armor Plates", chance = 1800, maxCount = 3},--done + {name = "Falcon Crest", chance = 400, maxCount = 3},--done + {name = "Patch of Fine Cloth", chance = 2500},--done + {name = "Falcon Coif", chance = 200},--done + {name = "Falcon Bow", chance = 200}--done +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -150, maxDamage = -700}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -720, range = 7, shootEffect = CONST_ANI_ROYALSPEAR, target = false}, + {name ="combat", interval = 1000, chance = 14, type = COMBAT_HOLYDAMAGE, minDamage = -500, maxDamage = -1000, length = 8, spread = 3, effect = CONST_ME_BLOCKHIT, target = false} +} + +monster.defenses = { + defense = 50, + armor = 82, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 200, maxDamage = 650, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/bosses/grand_master_oberon.lua b/data/monster/quests/the_secret_library/bosses/grand_master_oberon.lua new file mode 100644 index 00000000000..3524cf986f8 --- /dev/null +++ b/data/monster/quests/the_secret_library/bosses/grand_master_oberon.lua @@ -0,0 +1,221 @@ +local asking = { + [1] = {msg = "You appear like a worm among men!"}, + [2] = {msg = "The world will suffer for its iddle laziness!"}, + [3] = {msg = "People fall at my feet when they see me coming!"}, + [4] = {msg = "This will be the end of mortal man!"}, + [5] = {msg = "I will remove you from this plane of existence!"}, + [6] = {msg = "Dragons will soon rule this world, I am their herald!"}, + [7] = {msg = "The true virtue of chivalry are my belief!"}, + [8] = {msg = "I lead the most honourable and formidable following of knights!"}, + [9] = {msg = "ULTAH SALID'AR, ESDO LO!"}, +} + +local responses = { + [1] = {msg = "How appropriate, you look like something worms already got the better of!"}, + [2] = {msg = "Are you ever going to fight or do you prefer talking!"}, + [3] = {msg = "Even before they smell your breath?"}, + [4] = {msg = "Then let me show you the concept of mortality before it!"}, + [5] = {msg = "Too bad you barely exist at all!"}, + [6] = {msg = "Excuse me but I still do not get the message!"}, + [7] = {msg = "Dare strike up a Minnesang and you will receive your last accolade!"}, + [8] = {msg = "Then why are we fighting alone right now?"}, + [9] = {msg = "SEHWO ASIMO, TOLIDO ESD!"}, +} + +local config = { + storage = { + asking = 1, + life = 2, + exhaust = 3, + }, + monster = { + "Falcon Knight", + "Falcon Paladin" + }, + amount_life = 3 +} + +local function heal(monster) + local storage = monster:getStorageValue(config.storage.life) + monster:setStorageValue(config.storage.life, storage + 1) + monster:addHealth(monster:getMaxHealth()) + +end + +local function sendAsking(monster) + monster:registerEvent('OberonImmunity') + local random = math.random(#asking) + monster:say(asking[random].msg, TALKTYPE_MONSTER_SAY) + monster:setStorageValue(config.storage.asking, random) + heal(monster) + Game.createMonster(config.monster[math.random(#config.monster)], monster:getPosition(), true, true) +end + +local immunity = CreatureEvent("OberonImmunity") + +function immunity.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin) + if creature:isMonster() then + creature:getPosition():sendMagicEffect(CONST_ME_HOLYAREA) + end + return true +end + +immunity:register() + +local mType = Game.createMonsterType("Grand Master Oberon") +local monster = {} + +monster.description = "Grand Master Oberon" +monster.experience = 20000 +monster.outfit = { + lookType = 1072, + lookHead = 57, + lookBody = 75, + lookLegs = 38, + lookFeet = 86, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 30000 +monster.maxHealth = 30000 +monster.race = "blood" +monster.corpse = 33368 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2230, chance = 30000, maxCount = 1}, + {name = "brass shield", chance = 30000, maxCount = 1}, + {name = "spatial warp almanac", chance = 25000, maxCount = 1}, + {name = "viking helmet", chance = 23000, maxCount = 1}, + {name = "falcon battleaxe", chance = 500, maxCount = 1}, + {name = "falcon longsword", chance = 500, maxCount = 1}, + {name = "falcon mace", chance = 500, maxCount = 1}, + {name = "grant of arms", chance = 500, maxCount = 1}, + {name = "falcon bow", chance = 350, maxCount = 1}, + {name = "falcon circlet", chance = 350, maxCount = 1}, + {name = "falcon coif", chance = 350, maxCount = 1}, + {name = "falcon rod", chance = 350, maxCount = 1}, + {name = "falcon wand", chance = 350, maxCount = 1}, + {name = "falcon shield", chance = 200, maxCount = 1}, + {name = "falcon greaves", chance = 200, maxCount = 1}, + {name = "falcon plate", chance = 200, maxCount = 1}, +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1200}, + {name ="combat", interval = 6000, chance = 80, type = COMBAT_HOLYDAMAGE, minDamage = -1000, maxDamage = -2250, length = 8, spread = 3, effect = CONST_ME_HOLYAREA, target = false}, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -820, maxDamage = -1450, radius = 5, effect = CONST_ME_HITAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -860, maxDamage = -1500, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false} +} + +monster.defenses = { + defense = 60, + armor = 82, + {name ="speed", interval = 1000, chance = 10, speedChange = 180, effect = CONST_ME_POFF, target = false, duration = 4000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 5}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) + if monster:getStorageValue(config.storage.life) <= config.amount_life then + local percentageHealth = (monster:getHealth()*100)/monster:getMaxHealth() + if percentageHealth <= 20 then + sendAsking(monster) + end + end +end + +mType.onAppear = function(monster, creature) + if monster:getId() == creature:getId() then + monster:setStorageValue(config.storage.asking, 1) + monster:setStorageValue(config.storage.life, 1) + end + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) + local exhaust = config.storage.exhaust + if creature:isPlayer() and monster:getStorageValue(exhaust) <= os.time() then + message = message:lower() + monster:setStorageValue(exhaust, os.time() + 1) + for i, v in pairs(responses) do + if message == v.msg:lower() then + local asking_storage = monster:getStorageValue(config.storage.asking) + if asking[i].msg:lower() == asking[asking_storage].msg:lower() then + monster:unregisterEvent('OberonImmunity') + end + end + end + end +end + +mType:register(monster) \ No newline at end of file diff --git a/data/monster/quests/the_secret_library/bosses/preceptor_lazare.lua b/data/monster/quests/the_secret_library/bosses/preceptor_lazare.lua new file mode 100644 index 00000000000..f20affd0948 --- /dev/null +++ b/data/monster/quests/the_secret_library/bosses/preceptor_lazare.lua @@ -0,0 +1,142 @@ +local mType = Game.createMonsterType("Preceptor Lazare") +local monster = {} + +monster.description = "Preceptor Lazare" +monster.experience = 9200 +monster.outfit = { + lookType = 1078, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 15000 +monster.maxHealth = 15000 +monster.race = "blood" +monster.corpse = 33384 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 90}, + {name = "gold coin", chance = 100000, maxCount = 45}, + {name = "platinum coin", chance = 100000, maxCount = 3}, + {name = "great mana potion", chance = 100000, maxCount = 3}, + {name = "demonic essence", chance = 100000, maxCount = 5}, + {name = "red gem", chance = 700, maxCount = 3}, + {name = "assassin star", chance = 100000, maxCount = 5}, + {name = "concentrated demonic blood", chance = 100000, maxCount = 3}, + {name = "ham", chance = 100000, maxCount = 2}, + {name = "small emerald", chance = 100000, maxCount = 5}, + {name = "small diamond", chance = 100000, maxCount = 4}, + {name = "small amethyst", chance = 100000, maxCount = 3}, + {name = "knight armor", chance = 3100}, + {name = "golden armor", chance = 2200}, + {name = "patch of fine cloth", chance = 1800, maxCount = 3}, + {name = "violet gem", chance = 1800}, + {name = "titan axe", chance = 1600}, + {name = "war axe", chance = 1400}, + {name = "demonbone amulet", chance = 800}, + {name = "heavy mace", chance = 600}, + {name = "mastermind shield", chance = 500}, + {name = "falcon rod", chance = 200}, + {name = "falcon greaves", chance = 110} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -200, maxDamage = -700}, + {name ="combat", interval = 1400, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -800, range = 7, shootEffect = CONST_ANI_INFERNALBOLT, target = false}, + {name ="combat", interval = 1500, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -300, maxDamage = -1100, range = 7, shootEffect = CONST_ANI_POWERBOLT, target = false}, + {name ="combat", interval = 1600, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -720, range = 7, shootEffect = CONST_ANI_ENERGYBALL, target = false}, + {name ="combat", interval = 1500, chance = 14, type = COMBAT_HOLYDAMAGE, minDamage = -300, maxDamage = -1000, range = 7, radius = 4, effect = CONST_ME_HOLYDAMAGE, target = false} +} + +monster.defenses = { + defense = 60, + armor = 86, + {name ="combat", interval = 1500, chance = 20, type = COMBAT_HEALING, minDamage = 200, maxDamage = 800, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/bosses/thawing_dragon_lord.lua b/data/monster/quests/the_secret_library/bosses/thawing_dragon_lord.lua new file mode 100644 index 00000000000..28c42a5832c --- /dev/null +++ b/data/monster/quests/the_secret_library/bosses/thawing_dragon_lord.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Thawing Dragon Lord") +local monster = {} + +monster.description = "a thawing dragon lord" +monster.experience = 2100 +monster.outfit = { + lookType = 1077, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 25000 +monster.maxHealth = 25000 +monster.race = "fire" +monster.corpse = 33381 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = true, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 9971, chance = 50000, maxCount = 4}, + {id = 8571, chance = 5560}, + {id = 7377, chance = 5560}, + {id = 15515, chance = 50} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + {name ="ice crystal bomb", interval = 2000, chance = 30, minDamage = -600, maxDamage = -700, target = true}, + {name ="fire wave", interval = 2000, chance = 30, minDamage = -800, maxDamage = -1200, length = 1, spread = 0, target = true}, + {name ="speed", interval = 1000, chance = 12, speedChange = -250, radius = 6, effect = CONST_ME_HITBYFIRE, target = false, duration = 60000}, + {name ="firefield", interval = 1000, chance = 10, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, target = true} +} + +monster.defenses = { + defense = 40, + armor = 80 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 40}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/bosses/the_scourge_of_oblivion.lua b/data/monster/quests/the_secret_library/bosses/the_scourge_of_oblivion.lua new file mode 100644 index 00000000000..34125848353 --- /dev/null +++ b/data/monster/quests/the_secret_library/bosses/the_scourge_of_oblivion.lua @@ -0,0 +1,192 @@ +local mType = Game.createMonsterType("The Scourge Of Oblivion") +local monster = {} + +monster.description = "The Scourge Of Oblivion" +monster.experience = 50000 +monster.outfit = { + lookType = 875, + lookHead = 79, + lookBody = 79, + lookLegs = 60, + lookFeet = 79, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 800000 +monster.maxHealth = 800000 +monster.race = "venom" +monster.corpse = 26217 +monster.speed = 450 +monster.manaCost = 0 +monster.maxSummons = 8 + +monster.changeTarget = { + interval = 2000, + chance = 25 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Charger", chance = 15, interval = 1000, max = 3}, + {name = "Spark of Destruction", chance = 15, interval = 1000, max = 5} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I AM DEVOURER!", yell = true} +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 15}, + {name = "crystal coin", chance = 100000, maxCount = 7}, + {name = "green crystal shard", chance = 100000, maxCount = 3}, + {name = "violet crystal shard", chance = 100000, maxCount = 3}, + {name = "spark sphere", chance = 100000}, + {name = "plasmatic lightning", chance = 100000}, + {name = "emerald bangle", chance = 100000}, + {name = "royal star", chance = 66666, maxCount = 100}, + {name = "small amethyst", chance = 66666, maxCount = 12}, + {name = "silver token", chance = 66666, maxCount = 12}, + {name = "mastermind potion", chance = 66666, maxCount = 10}, + {name = "ultimate mana potion", chance = 66666, maxCount = 6}, + {name = "giant emerald", chance = 66666}, + {name = "red gem", chance = 66666}, + {name = "small ruby", chance = 33333, maxCount = 12}, + {name = "bullseye potion", chance = 33333, maxCount = 10}, + {name = "gold token", chance = 33333, maxCount = 8}, + {name = "supreme health potion", chance = 33333, maxCount = 6}, + {name = "blue crystal shard", chance = 33333, maxCount = 3}, + {name = "giant sapphire", chance = 33333}, + {name = "green gem", chance = 33333}, + {id = 26198, chance = 33333},-- collar of blue plasma + {name = "huge chunk of crude iron", chance = 33333}, + {name = "magic sulphur", chance = 33333}, + {name = "ring of the sky", chance = 33333}, + {name = "ultimate spirit potion", chance = 15000, maxCount = 20}, + {name = "small diamond", chance = 15000, maxCount = 12}, + {name = "small emerald", chance = 15000, maxCount = 12}, + {name = "rift shield", chance = 5000}, + {id = 7632, chance = 5000}, + {name = "arcane staff", chance = 5000}, + {name = "skullcracker armor", chance = 5000}, + {name = "chaos mace", chance = 5000}, + {name = "cat's paw", chance = 5000}, + {name = "piggy bank", chance = 5000}, + {name = "mysterious remains", chance = 5000}, + {name = "energy bar", chance = 5000}, + {name = "library ticket", chance = 500, unique = true}, + {name = "calamity", chance = 500, unique = true} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 250, attack = 350}, + {name ="combat", interval = 1000, chance = 7, type = COMBAT_MANADRAIN, minDamage = -900, maxDamage = -1500, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_POFF, target = false}, + {name ="drunk", interval = 2000, chance = 20, radius = 5, effect = CONST_ME_SMALLCLOUDS, target = false, duration = 9000}, + {name ="strength", interval = 1000, chance = 9, range = 7, shootEffect = CONST_ANI_LARGEROCK, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="energy strike", interval = 2000, chance = 30, minDamage = -2000, maxDamage = -2700, range = 1, target = false}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_FIREDAMAGE, minDamage = -1550, maxDamage = -2550, range = 7, radius = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -1075, maxDamage = -2405, range = 7, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -600, maxDamage = -1500, radius = 8, effect = CONST_ME_LOSEENERGY, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -750, maxDamage = -1200, length = 8, spread = 3, effect = CONST_ME_PURPLEENERGY, target = false}, + {name ="renegade knight", interval = 2000, chance = 30, target = false}, + {name ="choking fear drown", interval = 2000, chance = 20, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -450, maxDamage = -1400, radius = 4, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -800, maxDamage = -2300, radius = 8, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="speed", interval = 1000, chance = 12, speedChange = -1900, radius = 6, effect = CONST_ME_POISONAREA, target = false, duration = 60000}, + {name ="strength", interval = 1000, chance = 8, radius = 5, effect = CONST_ME_HITAREA, target = false}, + {name ="combat", interval = 1000, chance = 34, type = COMBAT_FIREDAMAGE, minDamage = -100, maxDamage = -700, range = 7, radius = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -300, maxDamage = -950, length = 8, spread = 3, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 160, + armor = 160, + {name ="combat", interval = 6000, chance = 25, type = COMBAT_HEALING, minDamage = 2000, maxDamage = 5000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 1000, chance = 8, speedChange = 1901, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000}, + {name ="invisible", interval = 1000, chance = 4, effect = CONST_ME_MAGIC_BLUE}, + {name ="invisible", interval = 1000, chance = 17, effect = CONST_ME_MAGIC_BLUE} +} + +monster.reflects = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/brother_chill.lua b/data/monster/quests/the_secret_library/brother_chill.lua new file mode 100644 index 00000000000..5c617dfc844 --- /dev/null +++ b/data/monster/quests/the_secret_library/brother_chill.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Brother Chill") +local monster = {} + +monster.description = "Brother Chill" +monster.experience = 0 +monster.outfit = { + lookType = 261, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "blood" +monster.corpse = 7282 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/brother_freeze.lua b/data/monster/quests/the_secret_library/brother_freeze.lua new file mode 100644 index 00000000000..c91bd902881 --- /dev/null +++ b/data/monster/quests/the_secret_library/brother_freeze.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Brother Freeze") +local monster = {} + +monster.description = "Brother Freeze" +monster.experience = 0 +monster.outfit = { + lookType = 261, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 7282 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/concentrated_death.lua b/data/monster/quests/the_secret_library/concentrated_death.lua new file mode 100644 index 00000000000..b6c0b8cdbab --- /dev/null +++ b/data/monster/quests/the_secret_library/concentrated_death.lua @@ -0,0 +1,101 @@ +local mType = Game.createMonsterType("Concentrated Death") +local monster = {} + +monster.description = "Concentrated Death" +monster.experience = 0 +monster.outfit = { + lookType = 315, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 33345 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/dark_knowledge.lua b/data/monster/quests/the_secret_library/dark_knowledge.lua new file mode 100644 index 00000000000..510f67bf23a --- /dev/null +++ b/data/monster/quests/the_secret_library/dark_knowledge.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Dark Knowledge") +local monster = {} + +monster.description = "a dark knowledge" +monster.experience = 0 +monster.outfit = { + lookType = 1061, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 50 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 100, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -400, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/dazed_leaf_golem.lua b/data/monster/quests/the_secret_library/dazed_leaf_golem.lua new file mode 100644 index 00000000000..641ee51bd52 --- /dev/null +++ b/data/monster/quests/the_secret_library/dazed_leaf_golem.lua @@ -0,0 +1,102 @@ +local mType = Game.createMonsterType("Dazed Leaf Golem") +local monster = {} + +monster.description = "a dazed leaf golem" +monster.experience = 8000 +monster.outfit = { + lookType = 567, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 21358 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 0, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 437} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/demon_blood.lua b/data/monster/quests/the_secret_library/demon_blood.lua new file mode 100644 index 00000000000..abbecbff07d --- /dev/null +++ b/data/monster/quests/the_secret_library/demon_blood.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Demon blood") +local monster = {} + +monster.description = "a demon blood" +monster.experience = 0 +monster.outfit = { + lookType = 1041, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 31997 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/demon_slave.lua b/data/monster/quests/the_secret_library/demon_slave.lua new file mode 100644 index 00000000000..b011a26ca6f --- /dev/null +++ b/data/monster/quests/the_secret_library/demon_slave.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Demon Slave") +local monster = {} + +monster.description = "a demon slave" +monster.experience = 0 +monster.outfit = { + lookType = 35, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "fire" +monster.corpse = 5995 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/force_field.lua b/data/monster/quests/the_secret_library/force_field.lua new file mode 100644 index 00000000000..c703efed6d1 --- /dev/null +++ b/data/monster/quests/the_secret_library/force_field.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Force Field") +local monster = {} + +monster.description = "a force field" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 11098 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.reflects = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 20}, + {type = COMBAT_MANADRAIN, percent = 20}, + {type = COMBAT_DROWNDAMAGE, percent = 20}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/furious_scorpion.lua b/data/monster/quests/the_secret_library/furious_scorpion.lua new file mode 100644 index 00000000000..4297a0e2e64 --- /dev/null +++ b/data/monster/quests/the_secret_library/furious_scorpion.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Furious Scorpion") +local monster = {} + +monster.description = "a furious scorpion" +monster.experience = 12000 +monster.outfit = { + lookType = 398, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 15000 +monster.maxHealth = 15000 +monster.race = "undead" +monster.corpse = 13501 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 70}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/ghulosh'_deathgaze.lua b/data/monster/quests/the_secret_library/ghulosh'_deathgaze.lua new file mode 100644 index 00000000000..a83a51668e3 --- /dev/null +++ b/data/monster/quests/the_secret_library/ghulosh'_deathgaze.lua @@ -0,0 +1,96 @@ +local mType = Game.createMonsterType("Ghulosh' Deathgaze") +local monster = {} + +monster.description = "Ghulosh' Deathgaze" +monster.experience = 0 +monster.outfit = { + lookType = 1063, + lookHead = 57, + lookBody = 57, + lookLegs = 57, + lookFeet = 57, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 300000 +monster.maxHealth = 300000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 30 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/imp_intruder.lua b/data/monster/quests/the_secret_library/imp_intruder.lua new file mode 100644 index 00000000000..96310b325e1 --- /dev/null +++ b/data/monster/quests/the_secret_library/imp_intruder.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Imp Intruder") +local monster = {} + +monster.description = "an imp intruder" +monster.experience = 100 +monster.outfit = { + lookType = 237, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "fire" +monster.corpse = 6364 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/invading_demon.lua b/data/monster/quests/the_secret_library/invading_demon.lua new file mode 100644 index 00000000000..8db6492b3a8 --- /dev/null +++ b/data/monster/quests/the_secret_library/invading_demon.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Invading Demon") +local monster = {} + +monster.description = "an invading demon" +monster.experience = 100 +monster.outfit = { + lookType = 35, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "fire" +monster.corpse = 5995 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/jailer.lua b/data/monster/quests/the_secret_library/jailer.lua new file mode 100644 index 00000000000..043b01e8b45 --- /dev/null +++ b/data/monster/quests/the_secret_library/jailer.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Jailer") +local monster = {} + +monster.description = "Jailer" +monster.experience = 45 +monster.outfit = { + lookType = 298, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 65 +monster.maxHealth = 65 +monster.race = "undead" +monster.corpse = 5972 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = true, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 60}, + {name = "gold coin", chance = 100000, maxCount = 40} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/knowledge_raider.lua b/data/monster/quests/the_secret_library/knowledge_raider.lua new file mode 100644 index 00000000000..6233d34bf1f --- /dev/null +++ b/data/monster/quests/the_secret_library/knowledge_raider.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Knowledge Raider") +local monster = {} + +monster.description = "a knowledge raider" +monster.experience = 0 +monster.outfit = { + lookType = 878, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="melee", interval = 2000, chance = 20, minDamage = -300, maxDamage = -490}, + {name ="melee", interval = 2000, chance = 10, minDamage = -300, maxDamage = -490} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/librarian.lua b/data/monster/quests/the_secret_library/librarian.lua new file mode 100644 index 00000000000..5d89661c939 --- /dev/null +++ b/data/monster/quests/the_secret_library/librarian.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Librarian") +local monster = {} + +monster.description = "a librarian" +monster.experience = 0 +monster.outfit = { + lookType = 1067, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 33357 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 5, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 33 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/lokathmor.lua b/data/monster/quests/the_secret_library/lokathmor.lua new file mode 100644 index 00000000000..3fdebec78b2 --- /dev/null +++ b/data/monster/quests/the_secret_library/lokathmor.lua @@ -0,0 +1,150 @@ +local mType = Game.createMonsterType("Lokathmor") +local monster = {} + +monster.description = "Lokathmor" +monster.experience = 100000 +monster.outfit = { + lookType = 1062, + lookHead = 22, + lookBody = 22, + lookLegs = 79, + lookFeet = 97, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 300000 +monster.maxHealth = 300000 +monster.race = "blood" +monster.corpse = 8721 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 5 + +monster.changeTarget = { + interval = 2000, + chance = 4 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 98, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "demon blood", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 90000, maxCount = 63}, + {name = "crystal coin", chance = 70000, maxCount = 4}, + {name = "great mana potion", chance = 70000, maxCount = 18}, + {name = "great spirit potion", chance = 70000, maxCount = 18}, + {name = "ultimate mana potion", chance = 70000, maxCount = 12}, + {name = "ultimate health potion", chance = 70000, maxCount = 18}, + {name = "mastermind potion", chance = 70000, maxCount = 2}, + {name = "onyx chip", chance = 70000, maxCount = 12}, + {name = "small emerald", chance = 70000, maxCount = 12}, + {name = "small amethyst", chance = 70000, maxCount = 12}, + {name = "small diamond", chance = 70000, maxCount = 12}, + {name = "small ruby", chance = 70000, maxCount = 12}, + {name = "blue gem", chance = 70000}, + {name = "demon horn", chance = 70000}, + {name = "demonic essence", chance = 70000}, + {id = 7632, chance = 70000}, + {name = "green gem", chance = 70000}, + {name = "magic sulphur", chance = 70000}, + {name = "stone skin amulet", chance = 70000}, + {name = "silver token", chance = 30000, maxCount = 4}, + {name = "blue robe", chance = 30000}, + {name = "dreaded cleaver", chance = 30000}, + {id = 9814, chance = 30000}, + {name = "wand of inferno", chance = 30000}, + {id = 33094, chance = 1000}, + {name = "sturdy book", chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 150, attack = 250}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_LIFEDRAIN, minDamage = -1100, maxDamage = -2800, range = 7, radius = 5, shootEffect = CONST_ANI_WHIRLWINDAXE, target = true}, + {name ="combat", interval = 1000, chance = 8, type = COMBAT_DEATHDAMAGE, minDamage = -800, maxDamage = -1900, radius = 9, effect = CONST_ME_MORTAREA, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 5000, chance = 18, minDamage = -1100, maxDamage = -2500, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -1000, maxDamage = -255, range = 7, radius = 6, effect = CONST_ME_LOSEENERGY, target = false}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_PHYSICALDAMAGE, minDamage = -90, maxDamage = -200, range = 7, shootEffect = CONST_ANI_WHIRLWINDAXE, effect = CONST_ME_EXPLOSIONAREA, target = true} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 1}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/lokathmor_stuck.lua b/data/monster/quests/the_secret_library/lokathmor_stuck.lua new file mode 100644 index 00000000000..9c7c1ccc59a --- /dev/null +++ b/data/monster/quests/the_secret_library/lokathmor_stuck.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Lokathmor") +local monster = {} + +monster.description = "Lokathmor" +monster.experience = 0 +monster.outfit = { + lookType = 1062, + lookHead = 22, + lookBody = 22, + lookLegs = 79, + lookFeet = 97, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 300000 +monster.maxHealth = 300000 +monster.race = "blood" +monster.corpse = 33964 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 4 +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 150, attack = 250}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_LIFEDRAIN, minDamage = -2500, maxDamage = -2800, range = 7, radius = 5, shootEffect = CONST_ANI_WHIRLWINDAXE, target = true}, + {name ="combat", interval = 1000, chance = 8, type = COMBAT_DEATHDAMAGE, minDamage = -1500, maxDamage = -1900, radius = 9, effect = CONST_ME_MORTAREA, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 5000, chance = 18, minDamage = -2000, maxDamage = -2500, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -1000, maxDamage = -255, range = 7, radius = 6, effect = CONST_ME_LOSEENERGY, target = false}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_PHYSICALDAMAGE, minDamage = -170, maxDamage = -200, range = 7, shootEffect = CONST_ANI_WHIRLWINDAXE, effect = CONST_ME_EXPLOSIONAREA, target = true} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/malicious_minion.lua b/data/monster/quests/the_secret_library/malicious_minion.lua new file mode 100644 index 00000000000..e25f8c7a522 --- /dev/null +++ b/data/monster/quests/the_secret_library/malicious_minion.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Malicious Minion") +local monster = {} + +monster.description = "a malicious minion" +monster.experience = 0 +monster.outfit = { + lookType = 40, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 5985 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/mazzinor.lua b/data/monster/quests/the_secret_library/mazzinor.lua new file mode 100644 index 00000000000..43ee7929ab9 --- /dev/null +++ b/data/monster/quests/the_secret_library/mazzinor.lua @@ -0,0 +1,141 @@ +local mType = Game.createMonsterType("Mazzinor") +local monster = {} + +monster.description = "a mazzinor" +monster.experience = 100000 +monster.outfit = { + lookType = 1062, + lookHead = 85, + lookBody = 27, + lookLegs = 0, + lookFeet = 0, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 300000 +monster.maxHealth = 300000 +monster.race = "blood" +monster.corpse = 25151 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 4 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 98, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 90000, maxCount = 38}, + {name = "crystal coin", chance = 70000, maxCount = 5}, + {name = "ultimate mana potion", chance = 70000, maxCount = 8}, + {name = "ultimate spirit potion", chance = 70000, maxCount = 4}, + {name = "supreme health potion", chance = 70000, maxCount = 4}, + {name = "berserk potion", chance = 70000, maxCount = 2}, + {name = "mastermind potion", chance = 70000, maxCount = 2}, + {name = "onyx chip", chance = 70000, maxCount = 12}, + {name = "small emerald", chance = 70000, maxCount = 12}, + {name = "demon horn", chance = 70000}, + {name = "lightning boots", chance = 70000}, + {name = "Red Gem", chance = 70000}, + {name = "violet gem", chance = 70000}, + {name = "stone skin amulet", chance = 70000}, + {name = "wand of starstorm", chance = 70000}, + {name = "gold token", chance = 30000, maxCount = 4}, + {name = "assassin dagger", chance = 30000}, + {name = "crystalline armor", chance = 30000}, + {name = "dreaded cleaver", chance = 30000}, + {name = "frozen lightning", chance = 30000}, + {name = "sinister book", chance = 1000}, + {name = "wand of dimensions", chance = 10} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 80}, + {name ="divine missile", interval = 2000, chance = 10, minDamage = -135, maxDamage = -700, target = true}, + {name ="berserk", interval = 2000, chance = 20, minDamage = -90, maxDamage = -500, range = 7, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -135, maxDamage = -280, range = 7, radius = 5, effect = CONST_ME_MAGIC_BLUE, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -210, maxDamage = -600, length = 8, spread = 3, effect = CONST_ME_ENERGYAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HOLYDAMAGE, minDamage = -210, maxDamage = -700, length = 8, spread = 3, effect = CONST_ME_HOLYAREA, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 1}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/mean_minion.lua b/data/monster/quests/the_secret_library/mean_minion.lua new file mode 100644 index 00000000000..a16d60ca578 --- /dev/null +++ b/data/monster/quests/the_secret_library/mean_minion.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Mean Minion") +local monster = {} + +monster.description = "a mean minion" +monster.experience = 400 +monster.outfit = { + lookType = 237, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "blood" +monster.corpse = 6364 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -1}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/neutral_deepling_warrior.lua b/data/monster/quests/the_secret_library/neutral_deepling_warrior.lua new file mode 100644 index 00000000000..a37580ff139 --- /dev/null +++ b/data/monster/quests/the_secret_library/neutral_deepling_warrior.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Neutral deepling warrior") +local monster = {} + +monster.description = "a neutral deepling warrior" +monster.experience = 1500 +monster.outfit = { + lookType = 441, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1600 +monster.maxHealth = 1600 +monster.race = "blood" +monster.corpse = 15175 +monster.speed = 290 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 30, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -290, range = 7, shootEffect = CONST_ANI_WHIRLWINDAXE, target = true} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 50, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = -20}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/oberons_bile.lua b/data/monster/quests/the_secret_library/oberons_bile.lua new file mode 100644 index 00000000000..38f1851ad0d --- /dev/null +++ b/data/monster/quests/the_secret_library/oberons_bile.lua @@ -0,0 +1,94 @@ +local mType = Game.createMonsterType("Oberon's Bile") +local monster = {} + +monster.description = "a Oberon's Bile" +monster.experience = 20000 +monster.outfit = { + lookTypeEx = 11936 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 1400, chance = 100, minDamage = 150, maxDamage = 800} +} + +monster.defenses = { + defense = 50, + armor = 82, + {name ="combat", interval = 1400, chance = 20, type = COMBAT_HEALING, minDamage = 400, maxDamage = 550, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/oberons_hate.lua b/data/monster/quests/the_secret_library/oberons_hate.lua new file mode 100644 index 00000000000..f19968962e3 --- /dev/null +++ b/data/monster/quests/the_secret_library/oberons_hate.lua @@ -0,0 +1,94 @@ +local mType = Game.createMonsterType("Oberon's Hate") +local monster = {} + +monster.description = "a Oberon's Hate" +monster.experience = 20000 +monster.outfit = { + lookTypeEx = 11936 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 1400, chance = 100, minDamage = 150, maxDamage = 800} +} + +monster.defenses = { + defense = 50, + armor = 82, + {name ="combat", interval = 1400, chance = 20, type = COMBAT_HEALING, minDamage = 400, maxDamage = 550, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/oberons_ire.lua b/data/monster/quests/the_secret_library/oberons_ire.lua new file mode 100644 index 00000000000..53a909205f7 --- /dev/null +++ b/data/monster/quests/the_secret_library/oberons_ire.lua @@ -0,0 +1,94 @@ +local mType = Game.createMonsterType("Oberon's Ire") +local monster = {} + +monster.description = "a Oberon's Ire" +monster.experience = 20000 +monster.outfit = { + lookTypeEx = 12167 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 1400, chance = 100, minDamage = 150, maxDamage = 800} +} + +monster.defenses = { + defense = 50, + armor = 82, + {name ="combat", interval = 1400, chance = 20, type = COMBAT_HEALING, minDamage = 400, maxDamage = 550, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/oberons_spite.lua b/data/monster/quests/the_secret_library/oberons_spite.lua new file mode 100644 index 00000000000..a8f578140da --- /dev/null +++ b/data/monster/quests/the_secret_library/oberons_spite.lua @@ -0,0 +1,94 @@ +local mType = Game.createMonsterType("Oberon's Spite") +local monster = {} + +monster.description = "a Oberon's Spite" +monster.experience = 20000 +monster.outfit = { + lookTypeEx = 12168 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 1400, chance = 100, minDamage = 150, maxDamage = 800} +} + +monster.defenses = { + defense = 50, + armor = 82, + {name ="combat", interval = 1400, chance = 20, type = COMBAT_HEALING, minDamage = 400, maxDamage = 550, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/ravenous_beyondling.lua b/data/monster/quests/the_secret_library/ravenous_beyondling.lua new file mode 100644 index 00000000000..7b489f2caee --- /dev/null +++ b/data/monster/quests/the_secret_library/ravenous_beyondling.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Ravenous Beyondling") +local monster = {} + +monster.description = "a ravenous beyondling" +monster.experience = 0 +monster.outfit = { + lookType = 876, + lookHead = 77, + lookBody = 80, + lookLegs = 85, + lookFeet = 94, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 33 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/rift_breacher.lua b/data/monster/quests/the_secret_library/rift_breacher.lua new file mode 100644 index 00000000000..87535efeaad --- /dev/null +++ b/data/monster/quests/the_secret_library/rift_breacher.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Rift Breacher") +local monster = {} + +monster.description = "a rift breacher" +monster.experience = 0 +monster.outfit = { + lookType = 875, + lookHead = 0, + lookBody = 38, + lookLegs = 91, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 33349 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/rift_minion.lua b/data/monster/quests/the_secret_library/rift_minion.lua new file mode 100644 index 00000000000..41591c15640 --- /dev/null +++ b/data/monster/quests/the_secret_library/rift_minion.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Rift Minion") +local monster = {} + +monster.description = "a rift minion" +monster.experience = 0 +monster.outfit = { + lookType = 882, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 26134 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/rift_spawn.lua b/data/monster/quests/the_secret_library/rift_spawn.lua new file mode 100644 index 00000000000..cba5ce78c7b --- /dev/null +++ b/data/monster/quests/the_secret_library/rift_spawn.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Rift Spawn") +local monster = {} + +monster.description = "a rift spawn" +monster.experience = 0 +monster.outfit = { + lookType = 12, + lookHead = 9, + lookBody = 0, + lookLegs = 9, + lookFeet = 85, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 6068 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/spawn_of_havoc.lua b/data/monster/quests/the_secret_library/spawn_of_havoc.lua new file mode 100644 index 00000000000..75ea112f500 --- /dev/null +++ b/data/monster/quests/the_secret_library/spawn_of_havoc.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Spawn of Havoc") +local monster = {} + +monster.description = "a spawn of havoc" +monster.experience = 0 +monster.outfit = { + lookType = 49, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "fire" +monster.corpse = 8964 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/stolen_knowledge_of_armor.lua b/data/monster/quests/the_secret_library/stolen_knowledge_of_armor.lua new file mode 100644 index 00000000000..19737505fa1 --- /dev/null +++ b/data/monster/quests/the_secret_library/stolen_knowledge_of_armor.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Stolen Knowledge of Armor") +local monster = {} + +monster.description = "stolen knowledge of armor" +monster.experience = 0 +monster.outfit = { + lookType = 1061, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/stolen_knowledge_of_healing.lua b/data/monster/quests/the_secret_library/stolen_knowledge_of_healing.lua new file mode 100644 index 00000000000..128cfeec809 --- /dev/null +++ b/data/monster/quests/the_secret_library/stolen_knowledge_of_healing.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Stolen Knowledge of Healing") +local monster = {} + +monster.description = "stolen knowledge of healing" +monster.experience = 0 +monster.outfit = { + lookType = 1061, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/stolen_knowledge_of_lifesteal.lua b/data/monster/quests/the_secret_library/stolen_knowledge_of_lifesteal.lua new file mode 100644 index 00000000000..26319bce997 --- /dev/null +++ b/data/monster/quests/the_secret_library/stolen_knowledge_of_lifesteal.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Stolen Knowledge of Lifesteal") +local monster = {} + +monster.description = "stolen knowledge of lifesteal" +monster.experience = 0 +monster.outfit = { + lookType = 1061, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/stolen_knowledge_of_spells.lua b/data/monster/quests/the_secret_library/stolen_knowledge_of_spells.lua new file mode 100644 index 00000000000..a6e731df597 --- /dev/null +++ b/data/monster/quests/the_secret_library/stolen_knowledge_of_spells.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Stolen Knowledge of Spells") +local monster = {} + +monster.description = "stolen knowledge of spells" +monster.experience = 0 +monster.outfit = { + lookType = 1061, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/stolen_knowledge_of_summoning.lua b/data/monster/quests/the_secret_library/stolen_knowledge_of_summoning.lua new file mode 100644 index 00000000000..d5ddfd443b9 --- /dev/null +++ b/data/monster/quests/the_secret_library/stolen_knowledge_of_summoning.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Stolen Knowledge of Summoning") +local monster = {} + +monster.description = "stolen knowledge of summoning" +monster.experience = 0 +monster.outfit = { + lookType = 1061, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/stolen_tome_of_portals.lua b/data/monster/quests/the_secret_library/stolen_tome_of_portals.lua new file mode 100644 index 00000000000..7e87276a080 --- /dev/null +++ b/data/monster/quests/the_secret_library/stolen_tome_of_portals.lua @@ -0,0 +1,90 @@ +local mType = Game.createMonsterType("Stolen Tome of Portals") +local monster = {} + +monster.description = "stolen tome of portals" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 26653 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "gorzindelDeath" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/supercharged_mazzinor.lua b/data/monster/quests/the_secret_library/supercharged_mazzinor.lua new file mode 100644 index 00000000000..67a794c1f17 --- /dev/null +++ b/data/monster/quests/the_secret_library/supercharged_mazzinor.lua @@ -0,0 +1,92 @@ +local mType = Game.createMonsterType("Supercharged Mazzinor") +local monster = {} + +monster.description = "Supercharged Mazzinor" +monster.experience = 0 +monster.outfit = { + lookType = 979, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 300000 +monster.maxHealth = 300000 +monster.race = "undead" +monster.corpse = 25151 +monster.speed = 120 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -500} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 1}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/the_blazing_rose.lua b/data/monster/quests/the_secret_library/the_blazing_rose.lua new file mode 100644 index 00000000000..11d3fffc33e --- /dev/null +++ b/data/monster/quests/the_secret_library/the_blazing_rose.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("The Blazing Rose") +local monster = {} + +monster.description = "the blazing rose" +monster.experience = 0 +monster.outfit = { + lookType = 1068, + lookHead = 95, + lookBody = 94, + lookLegs = 57, + lookFeet = 79, + lookAddons = 2, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 32494 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/the_book_of_secrets.lua b/data/monster/quests/the_secret_library/the_book_of_secrets.lua new file mode 100644 index 00000000000..1ca67a177e8 --- /dev/null +++ b/data/monster/quests/the_secret_library/the_book_of_secrets.lua @@ -0,0 +1,92 @@ +local mType = Game.createMonsterType("The Book of Secrets") +local monster = {} + +monster.description = "the book of secrets" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 25411 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/the_devourer_of_secrets.lua b/data/monster/quests/the_secret_library/the_devourer_of_secrets.lua new file mode 100644 index 00000000000..129273c734c --- /dev/null +++ b/data/monster/quests/the_secret_library/the_devourer_of_secrets.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("The Devourer of Secrets") +local monster = {} + +monster.description = "the devourer of secrets" +monster.experience = 0 +monster.outfit = { + lookType = 309, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "blood" +monster.corpse = 20550 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/the_diamond_blossom.lua b/data/monster/quests/the_secret_library/the_diamond_blossom.lua new file mode 100644 index 00000000000..ca8629e67ea --- /dev/null +++ b/data/monster/quests/the_secret_library/the_diamond_blossom.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("The Diamond Blossom") +local monster = {} + +monster.description = "the diamond blossom" +monster.experience = 10000 +monster.outfit = { + lookType = 1068, + lookHead = 85, + lookBody = 0, + lookLegs = 86, + lookFeet = 79, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 25000 +monster.maxHealth = 25000 +monster.race = "undead" +monster.corpse = 32499 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/the_lily_of_night.lua b/data/monster/quests/the_secret_library/the_lily_of_night.lua new file mode 100644 index 00000000000..a1c3cf36be9 --- /dev/null +++ b/data/monster/quests/the_secret_library/the_lily_of_night.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("The Lily of Night") +local monster = {} + +monster.description = "a the lily of night" +monster.experience = 0 +monster.outfit = { + lookType = 1068, + lookHead = 90, + lookBody = 38, + lookLegs = 90, + lookFeet = 79, + lookAddons = 2, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 32499 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/the_scion_of_havoc.lua b/data/monster/quests/the_secret_library/the_scion_of_havoc.lua new file mode 100644 index 00000000000..d68bae5e670 --- /dev/null +++ b/data/monster/quests/the_secret_library/the_scion_of_havoc.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("The Scion of Havoc") +local monster = {} + +monster.description = "the scion of havoc" +monster.experience = 0 +monster.outfit = { + lookType = 875, + lookHead = 94, + lookBody = 79, + lookLegs = 79, + lookFeet = 79, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "venom" +monster.corpse = 26220 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/the_spellstealer.lua b/data/monster/quests/the_secret_library/the_spellstealer.lua new file mode 100644 index 00000000000..2d4d80c6378 --- /dev/null +++ b/data/monster/quests/the_secret_library/the_spellstealer.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("The Spellstealer") +local monster = {} + +monster.description = "the spellstealer" +monster.experience = 0 +monster.outfit = { + lookType = 12, + lookHead = 81, + lookBody = 100, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 6068 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/war_servant.lua b/data/monster/quests/the_secret_library/war_servant.lua new file mode 100644 index 00000000000..8e0bca2736b --- /dev/null +++ b/data/monster/quests/the_secret_library/war_servant.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("War Servant") +local monster = {} + +monster.description = "a war servant" +monster.experience = 0 +monster.outfit = { + lookType = 326, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 10005 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/wild_knowledge.lua b/data/monster/quests/the_secret_library/wild_knowledge.lua new file mode 100644 index 00000000000..10b82e9dcb8 --- /dev/null +++ b/data/monster/quests/the_secret_library/wild_knowledge.lua @@ -0,0 +1,97 @@ +local mType = Game.createMonsterType("Wild Knowledge") +local monster = {} + +monster.description = "a wild knowledge" +monster.experience = 0 +monster.outfit = { + lookType = 293, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2000 +monster.maxHealth = 2000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 50 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -705, shootEffect = CONST_ANI_ENERGYBALL, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/the_secret_library/yalahari_despoiler.lua b/data/monster/quests/the_secret_library/yalahari_despoiler.lua new file mode 100644 index 00000000000..1e25f227f93 --- /dev/null +++ b/data/monster/quests/the_secret_library/yalahari_despoiler.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Yalahari Despoiler") +local monster = {} + +monster.description = "a yalahari despoiler" +monster.experience = 200 +monster.outfit = { + lookType = 309, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "blood" +monster.corpse = 20550 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = 0, maxDamage = -175, length = 3, spread = 3, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 33, + armor = 28 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/wrath_of_the_emperor/fury_of_the_emperor.lua b/data/monster/quests/wrath_of_the_emperor/fury_of_the_emperor.lua new file mode 100644 index 00000000000..0d80e5716ce --- /dev/null +++ b/data/monster/quests/wrath_of_the_emperor/fury_of_the_emperor.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Fury Of The Emperor") +local monster = {} + +monster.description = "a fury of the emperor" +monster.experience = 550 +monster.outfit = { + lookType = 351, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 51000 +monster.maxHealth = 51000 +monster.race = "undead" +monster.corpse = 12317 +monster.speed = 450 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 366, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Draken Warmaster", chance = 10, interval = 2000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 85, attack = 145}, + {name ="combat", interval = 3000, chance = 17, type = COMBAT_PHYSICALDAMAGE, minDamage = -250, maxDamage = -450, length = 8, spread = 3, effect = CONST_ME_LOSEENERGY, target = false}, + {name ="combat", interval = 3000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -700, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="speed", interval = 1000, chance = 10, speedChange = -600, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000}, + {name ="combat", interval = 2000, chance = 21, type = COMBAT_LIFEDRAIN, minDamage = -400, maxDamage = -650, radius = 6, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 55, + armor = 65 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = -15}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/wrath_of_the_emperor/lizard_abomination.lua b/data/monster/quests/wrath_of_the_emperor/lizard_abomination.lua new file mode 100644 index 00000000000..9b12bbd1e24 --- /dev/null +++ b/data/monster/quests/wrath_of_the_emperor/lizard_abomination.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Lizard Abomination") +local monster = {} + +monster.description = "a lizard abomination" +monster.experience = 9700 +monster.outfit = { + lookType = 364, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 95000 +monster.maxHealth = 95000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "NOOOO! NOW YOU HERETICS WILL FACE MY GODLY WRATH!", yell = true}, + {text = "RAAARRRR! I WILL DEVOL YOU!", yell = true}, + {text = "I WILL MAKE YOU ZHEE!", yell = true} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -550}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -980, radius = 3, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_LIFEDRAIN, minDamage = -200, maxDamage = -300, length = 8, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="speed", interval = 2000, chance = 20, radius = 3, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 60, + armor = 55, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 50, maxDamage = 350, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 15}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/wrath_of_the_emperor/mutated_zalamon.lua b/data/monster/quests/wrath_of_the_emperor/mutated_zalamon.lua new file mode 100644 index 00000000000..37ac1003cdd --- /dev/null +++ b/data/monster/quests/wrath_of_the_emperor/mutated_zalamon.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Mutated Zalamon") +local monster = {} + +monster.description = "Mutated Zalamon" +monster.experience = 10980 +monster.outfit = { + lookType = 356, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 155000 +monster.maxHealth = 155000 +monster.race = "venom" +monster.corpse = 12385 +monster.speed = 238 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -815, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -100, maxDamage = -300, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true}, + {name ="speed", interval = 4000, chance = 20, speedChange = -350, range = 7, shootEffect = CONST_ANI_POISON, target = true, duration = 12000} +} + +monster.defenses = { + defense = 65, + armor = 70, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_HEALING, minDamage = 20, maxDamage = 560, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="outfit", interval = 2000, chance = 10, effect = CONST_ME_ENERGYHIT, target = false, duration = 10000, outfitMonster = "Lizard Snakecharmer"}, + {name ="outfit", interval = 2000, chance = 10, effect = CONST_ME_ENERGYHIT, target = false, duration = 10000, outfitMonster = "Lizard Abomination"}, + {name ="outfit", interval = 2000, chance = 10, effect = CONST_ME_ENERGYHIT, target = false, duration = 10000, outfitMonster = "Serpent Spawn"}, + {name ="outfit", interval = 2000, chance = 10, effect = CONST_ME_ENERGYHIT, target = false, duration = 10000, outfitMonster = "Draken Abomination"}, + {name ="outfit", interval = 2000, chance = 10, effect = CONST_ME_ENERGYHIT, target = false, duration = 10000, outfitMonster = "Mutated Zalamon"} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/wrath_of_the_emperor/scorn_of_the_emperor.lua b/data/monster/quests/wrath_of_the_emperor/scorn_of_the_emperor.lua new file mode 100644 index 00000000000..fa57215b13e --- /dev/null +++ b/data/monster/quests/wrath_of_the_emperor/scorn_of_the_emperor.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Scorn Of The Emperor") +local monster = {} + +monster.description = "a scorn of the emperor" +monster.experience = 450 +monster.outfit = { + lookType = 351, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 45000 +monster.maxHealth = 45000 +monster.race = "undead" +monster.corpse = 12317 +monster.speed = 410 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 366, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Draken Warmaster", chance = 10, interval = 2000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 55, attack = 115}, + {name ="combat", interval = 3000, chance = 17, type = COMBAT_PHYSICALDAMAGE, minDamage = -150, maxDamage = -250, length = 8, spread = 3, effect = CONST_ME_LOSEENERGY, target = false}, + {name ="combat", interval = 3000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -500, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="speed", interval = 1000, chance = 10, speedChange = -600, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000}, + {name ="combat", interval = 2000, chance = 21, type = COMBAT_LIFEDRAIN, minDamage = -200, maxDamage = -450, radius = 6, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 35, + armor = 45 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = -15}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/wrath_of_the_emperor/snake_god_essence.lua b/data/monster/quests/wrath_of_the_emperor/snake_god_essence.lua new file mode 100644 index 00000000000..b56aea0b8d6 --- /dev/null +++ b/data/monster/quests/wrath_of_the_emperor/snake_god_essence.lua @@ -0,0 +1,104 @@ +local mType = Game.createMonsterType("Snake God Essence") +local monster = {} + +monster.description = "Snake God Essence" +monster.experience = 7410 +monster.outfit = { + lookType = 356, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 65000 +monster.maxHealth = 65000 +monster.race = "blood" +monster.corpse = 0 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "AHHH ZHE POWER...", yell = true}, + {text = "ZHE TIME OF ZHE SNAKE HAZ COME!", yell = true} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -600}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -300, length = 8, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_EARTHDAMAGE, minDamage = -150, maxDamage = -270, radius = 6, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.defenses = { + defense = 65, + armor = 70, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 150, maxDamage = 450, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/wrath_of_the_emperor/snake_thing.lua b/data/monster/quests/wrath_of_the_emperor/snake_thing.lua new file mode 100644 index 00000000000..a4a0eccfe99 --- /dev/null +++ b/data/monster/quests/wrath_of_the_emperor/snake_thing.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("Snake Thing") +local monster = {} + +monster.description = "Snake Thing" +monster.experience = 8400 +monster.outfit = { + lookType = 220, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 70000 +monster.maxHealth = 70000 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "POWER! I SEED MORE POWER!", yell = true} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 35, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -500, length = 8, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -2398, length = 8, spread = 3, effect = CONST_ME_SOUND_RED, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 30, minDamage = -30, maxDamage = -60, radius = 6, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 30, + armor = 45, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 150, maxDamage = 450, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/wrath_of_the_emperor/spite_of_the_emperor.lua b/data/monster/quests/wrath_of_the_emperor/spite_of_the_emperor.lua new file mode 100644 index 00000000000..47532a6db35 --- /dev/null +++ b/data/monster/quests/wrath_of_the_emperor/spite_of_the_emperor.lua @@ -0,0 +1,107 @@ +local mType = Game.createMonsterType("Spite Of The Emperor") +local monster = {} + +monster.description = "a spite of the emperor" +monster.experience = 500 +monster.outfit = { + lookType = 351, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 48000 +monster.maxHealth = 48000 +monster.race = "undead" +monster.corpse = 12317 +monster.speed = 410 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 366, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Draken Warmaster", chance = 10, interval = 2000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 55, attack = 115}, + {name ="combat", interval = 3000, chance = 17, type = COMBAT_PHYSICALDAMAGE, minDamage = -150, maxDamage = -250, length = 8, spread = 3, effect = CONST_ME_LOSEENERGY, target = false}, + {name ="combat", interval = 3000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -500, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="speed", interval = 1000, chance = 10, speedChange = -600, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000}, + {name ="combat", interval = 2000, chance = 21, type = COMBAT_LIFEDRAIN, minDamage = -200, maxDamage = -450, radius = 6, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 35, + armor = 45 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = -15}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/wrath_of_the_emperor/the_keeper.lua b/data/monster/quests/wrath_of_the_emperor/the_keeper.lua new file mode 100644 index 00000000000..f6215cdf235 --- /dev/null +++ b/data/monster/quests/wrath_of_the_emperor/the_keeper.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("The Keeper") +local monster = {} + +monster.description = "The Keeper" +monster.experience = 3205 +monster.outfit = { + lookType = 220, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 40000 +monster.maxHealth = 40000 +monster.race = "venom" +monster.corpse = 12316 +monster.speed = 290 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 275, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250}, + {name ="speed", interval = 4000, chance = 20, speedChange = -350, range = 7, shootEffect = CONST_ANI_POISON, target = true, duration = 12000}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -80, maxDamage = -300, range = 7, shootEffect = CONST_ANI_POISON, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -200, maxDamage = -500, length = 8, spread = 3, effect = CONST_ME_SOUND_RED, target = false}, + {name ="outfit", interval = 2000, chance = 1, range = 7, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 3000, outfitItem = 3976}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -200, maxDamage = -500, length = 8, spread = 3, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 250, maxDamage = 400, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/quests/wrath_of_the_emperor/wrath_of_the_emperor.lua b/data/monster/quests/wrath_of_the_emperor/wrath_of_the_emperor.lua new file mode 100644 index 00000000000..a4d0c24849e --- /dev/null +++ b/data/monster/quests/wrath_of_the_emperor/wrath_of_the_emperor.lua @@ -0,0 +1,111 @@ +local mType = Game.createMonsterType("Wrath Of The Emperor") +local monster = {} + +monster.description = "Wrath Of The Emperor" +monster.experience = 600 +monster.outfit = { + lookType = 351, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 55000 +monster.maxHealth = 55000 +monster.race = "undead" +monster.corpse = 12317 +monster.speed = 410 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 366, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Draken Warmaster", chance = 10, interval = 2000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "YOU DON'T EVEN UNDERSTAND WHOM YOU ARE SERVING!", yell = false}, + {text = "FLEE AND NEVER RETURN!", yell = false}, + {text = "YOU HAVE BEEN USED AND FOOLED!", yell = false}, + {text = "I WILL STOP YOU ONCE AND FOR ALL!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 55, attack = 115}, + {name ="combat", interval = 3000, chance = 17, type = COMBAT_PHYSICALDAMAGE, minDamage = -150, maxDamage = -250, length = 8, spread = 3, effect = CONST_ME_LOSEENERGY, target = false}, + {name ="combat", interval = 3000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -500, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="speed", interval = 1000, chance = 10, speedChange = -600, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000}, + {name ="combat", interval = 2000, chance = 21, type = COMBAT_LIFEDRAIN, minDamage = -200, maxDamage = -450, radius = 6, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 35, + armor = 45 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = -15}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/arachir_the_ancient_one.lua b/data/monster/raids/arachir_the_ancient_one.lua new file mode 100644 index 00000000000..e3e0516edf1 --- /dev/null +++ b/data/monster/raids/arachir_the_ancient_one.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Arachir The Ancient One") +local monster = {} + +monster.description = "Arachir The Ancient One" +monster.experience = 1800 +monster.outfit = { + lookType = 287, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1600 +monster.maxHealth = 1600 +monster.race = "undead" +monster.corpse = 8937 +monster.speed = 286 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Lich", chance = 100, interval = 9000}, + {name = "Lich", chance = 100, interval = 9000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I was the shadow that haunted the cradle of humanity!", yell = false}, + {text = "I exist since eons and you want to defy me?", yell = false}, + {text = "Can you feel the passage of time, mortal?", yell = false}, + {text = "Your worthles existence will nourish something greater!", yell = false} +} + +monster.loot = { + {id = 7416, chance = 1200}, + {id = 7588, chance = 10000}, + {id = 2229, chance = 10000}, + {id = 2148, chance = 100000, maxCount = 98}, + {id = 9020, chance = 100000}, + {id = 2152, chance = 50000, maxCount = 5}, + {id = 2534, chance = 6300}, + {id = 2144, chance = 8980} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 70, attack = 95}, + {name ="combat", interval = 9000, chance = 100, type = COMBAT_DEATHDAMAGE, minDamage = -120, maxDamage = -300, radius = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -120, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_HEALING, minDamage = 100, maxDamage = 235, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 3000, chance = 25, effect = CONST_ME_MAGIC_BLUE}, + {name ="outfit", interval = 4500, chance = 30, target = false, duration = 4000, outfitMonster = "bat"} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -15}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/barbaria.lua b/data/monster/raids/barbaria.lua new file mode 100644 index 00000000000..1751a88c789 --- /dev/null +++ b/data/monster/raids/barbaria.lua @@ -0,0 +1,114 @@ +local mType = Game.createMonsterType("Barbaria") +local monster = {} + +monster.description = "Barbaria" +monster.experience = 355 +monster.outfit = { + lookType = 264, + lookHead = 78, + lookBody = 116, + lookLegs = 95, + lookFeet = 121, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 345 +monster.maxHealth = 345 +monster.race = "blood" +monster.corpse = 20339 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "War Wolf", chance = 40, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "To me, creatures of the wild!", yell = false}, + {text = "My instincts tell me about your cowardice.", yell = false} +} + +monster.loot = { + {id = 2148, chance = 48000, maxCount = 35}, + {id = 2464, chance = 11000}, + {id = 3965, chance = 12500}, + {id = 7343, chance = 1000}, + {id = 2050, chance = 25000}, + {id = 1958, chance = 15000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 60, attack = 20}, + {name ="combat", interval = 2000, chance = 34, type = COMBAT_PHYSICALDAMAGE, minDamage = -30, maxDamage = -80, range = 7, radius = 1, shootEffect = CONST_ANI_SNOWBALL, target = true}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -35, maxDamage = -70, range = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_ENERGYHIT, target = false} +} + +monster.defenses = { + defense = 10, + armor = 10, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_HEALING, minDamage = 50, maxDamage = 80, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -20}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/battlemaster_zunzu.lua b/data/monster/raids/battlemaster_zunzu.lua new file mode 100644 index 00000000000..f996ceba2ef --- /dev/null +++ b/data/monster/raids/battlemaster_zunzu.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("Battlemaster Zunzu") +local monster = {} + +monster.description = "Battlemaster Zunzu" +monster.experience = 2500 +monster.outfit = { + lookType = 343, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 4000 +monster.maxHealth = 4000 +monster.race = "blood" +monster.corpse = 11281 +monster.speed = 420 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 150, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hissss!", yell = false} +} + +monster.loot = { + {name = "great health potion", chance = 2775, maxCount = 2}, + {name = "red lantern", chance = 100000}, + {name = "Zaoan armor", chance = 1050}, + {name = "Zaoan shoes", chance = 3150}, + {name = "Zaoan legs", chance = 2625}, + {name = "zaogun flag", chance = 11250}, + {name = "zaogun shoulderplates", chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_EARTHDAMAGE, minDamage = -115, maxDamage = -350, range = 1, radius = 1, effect = CONST_ME_POISONAREA, target = true} +} + +monster.defenses = { + defense = 35, + armor = 45, + {name ="combat", interval = 1000, chance = 18, type = COMBAT_HEALING, minDamage = 200, maxDamage = 400, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 15}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 25}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/brutus_bloodbeard.lua b/data/monster/raids/brutus_bloodbeard.lua new file mode 100644 index 00000000000..ba974d843c9 --- /dev/null +++ b/data/monster/raids/brutus_bloodbeard.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Brutus Bloodbeard") +local monster = {} + +monster.description = "Brutus Bloodbeard" +monster.experience = 795 +monster.outfit = { + lookType = 98, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1555 +monster.maxHealth = 1555 +monster.race = "blood" +monster.corpse = 20478 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 6099, chance = 100000}, + {id = 2148, chance = 100000, maxCount = 200}, + {id = 2229, chance = 75000, maxCount = 2}, + {id = 2379, chance = 25000}, + {id = 2476, chance = 25000}, + {id = 2666, chance = 25000}, + {id = 2463, chance = 25000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -175}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -175, range = 7, shootEffect = CONST_ANI_THROWINGSTAR, target = false}, + {name ="drunk", interval = 2000, chance = 10, length = 3, spread = 2, effect = CONST_ME_POFF, target = false, duration = 5000} +} + +monster.defenses = { + defense = 50, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -1}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -1}, + {type = COMBAT_HOLYDAMAGE , percent = 1}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/captain_jones.lua b/data/monster/raids/captain_jones.lua new file mode 100644 index 00000000000..5a640ee9d8e --- /dev/null +++ b/data/monster/raids/captain_jones.lua @@ -0,0 +1,109 @@ +local mType = Game.createMonsterType("Captain Jones") +local monster = {} + +monster.description = "Captain Jones" +monster.experience = 620 +monster.outfit = { + lookType = 196, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 555 +monster.maxHealth = 555 +monster.race = "undead" +monster.corpse = 5566 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 150}, + {id = 2165, chance = 33000}, + {id = 2488, chance = 5070}, + {id = 8871, chance = 3070}, + {id = 2655, chance = 1110}, + {id = 2383, chance = 1110} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -95, condition = {type = CONDITION_POISON, totalDamage = 2, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -30, maxDamage = -80, radius = 1, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -130, maxDamage = -150, range = 1, radius = 1, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="outfit", interval = 2000, chance = 5, range = 3, shootEffect = CONST_ANI_EXPLOSION, target = true, duration = 4000, outfitMonster = "Skeleton"} +} + +monster.defenses = { + defense = 0, + armor = 0, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 40, maxDamage = 70, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -15}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/chayenne.lua b/data/monster/raids/chayenne.lua new file mode 100644 index 00000000000..943d1c9948d --- /dev/null +++ b/data/monster/raids/chayenne.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Chayenne") +local monster = {} + +monster.description = "Chayenne" +monster.experience = 0 +monster.outfit = { + lookType = 155, + lookHead = 78, + lookBody = 0, + lookLegs = 105, + lookFeet = 99, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 200000 +monster.maxHealth = 200000 +monster.race = "blood" +monster.corpse = 6081 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "We don't stop playing because we grow old, we grow old because we stop playing.", yell = false}, + {text = "Oooh dang, he's hot *-*", yell = false}, + {text = "Oh came on, take it easy.", yell = false}, + {text = "Work hard, play harder!", yell = false}, + {text = "They are doing WHAT with my quest?!", yell = false} +} + +monster.loot = { + {id = 6571, chance = 100000, maxCount = 2}, + {id = 7632, chance = 100000}, + {id = 16014, chance = 100000}, + {id = 16015, chance = 100000, unique = true} +} + +monster.attacks = { + {name ="melee", interval = 3000, chance = 100, skill = 300, attack = 150}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -1500, range = 1, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -1250, range = 7, effect = CONST_ME_MAGIC_RED, target = true} +} + +monster.defenses = { + defense = 20, + armor = 15, + {name ="combat", interval = 1000, chance = 1, type = COMBAT_HEALING, minDamage = 0, maxDamage = 10000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 3500, chance = 30, type = COMBAT_HEALING, minDamage = 1000, maxDamage = 1000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="outfit", interval = 2000, chance = 10, effect = CONST_ME_ENERGYHIT, target = false, duration = 10000, outfitMonster = "Devovorga"}, + {name ="outfit", interval = 2000, chance = 10, effect = CONST_ME_ENERGYHIT, target = false, duration = 10000, outfitMonster = "Chayenne"} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/raids/chizzoron_the_distorter.lua b/data/monster/raids/chizzoron_the_distorter.lua new file mode 100644 index 00000000000..0a96bfba973 --- /dev/null +++ b/data/monster/raids/chizzoron_the_distorter.lua @@ -0,0 +1,137 @@ +local mType = Game.createMonsterType("Chizzoron The Distorter") +local monster = {} + +monster.description = "Chizzoron The Distorter" +monster.experience = 4000 +monster.outfit = { + lookType = 340, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 16000 +monster.maxHealth = 16000 +monster.race = "blood" +monster.corpse = 11316 +monster.speed = 260 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Lizard Dragon Priest", chance = 10, interval = 2000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Humanzzz! Leave Zzaion at onzzzze!", yell = false}, + {text = "I pray to my mazzterzz, the mighty dragonzzz!", yell = false}, + {text = "You are not worzzy to touch zzizz zzacred ground!", yell = false} +} + +monster.loot = { + {id = 9971, chance = 71550, maxCount = 2}, + {id = 2148, chance = 69825, maxCount = 100}, + {id = 2148, chance = 69825, maxCount = 10}, + {id = 2149, chance = 5750}, + {id = 5881, chance = 100000}, + {id = 2155, chance = 16300}, + {id = 2169, chance = 11025}, + {id = 7591, chance = 5750}, + {id = 2492, chance = 5750} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 60, attack = 130}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -430, range = 7, radius = 1, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = 0, maxDamage = -874, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -300, maxDamage = -646, radius = 3, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -148, maxDamage = -250, range = 7, effect = CONST_ME_MAGIC_RED, target = true} +} + +monster.defenses = { + defense = 85, + armor = 70 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/raids/control_tower.lua b/data/monster/raids/control_tower.lua new file mode 100644 index 00000000000..60928c060d8 --- /dev/null +++ b/data/monster/raids/control_tower.lua @@ -0,0 +1,92 @@ +local mType = Game.createMonsterType("Control Tower") +local monster = {} + +monster.description = "a control tower" +monster.experience = 3000 +monster.outfit = { + lookTypeEx = 23265 +} + +monster.health = 7500 +monster.maxHealth = 7500 +monster.race = "venom" +monster.corpse = 24309 +monster.speed = 0 +monster.manaCost = 330 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = true, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2152, chance = 100000, maxCount = 5}, + {id = 7590, chance = 14285}, + {id = 7591, chance = 14285} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 55}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 55}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 55}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/deadeye_devious.lua b/data/monster/raids/deadeye_devious.lua new file mode 100644 index 00000000000..eed90e2bc23 --- /dev/null +++ b/data/monster/raids/deadeye_devious.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Deadeye Devious") +local monster = {} + +monster.description = "Deadeye Devious" +monster.experience = 750 +monster.outfit = { + lookType = 151, + lookHead = 115, + lookBody = 76, + lookLegs = 35, + lookFeet = 117, + lookAddons = 2, + lookMount = 0 +} + +monster.health = 1450 +monster.maxHealth = 1450 +monster.race = "blood" +monster.corpse = 20378 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 50, + targetDistance = 3, + runHealth = 150, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Let's kill 'em", yell = false}, + {text = "Arrrgh!", yell = false}, + {text = "You'll never take me alive!", yell = false}, + {text = "You won't get me alive!", yell = false}, + {text = "§%§&§! #*$§$!!", yell = false} +} + +monster.loot = { + {id = 6102, chance = 100000}, + {id = 2148, chance = 100000, maxCount = 140}, + {id = 2229, chance = 85000, maxCount = 2}, + {id = 2463, chance = 78000}, + {id = 2666, chance = 42000, maxCount = 3}, + {id = 2476, chance = 28000}, + {id = 2379, chance = 21000}, + {id = 2145, chance = 14000}, + {id = 2387, chance = 7000}, + {id = 5926, chance = 7000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150}, + {name ="combat", interval = 4000, chance = 60, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -350, shootEffect = CONST_ANI_THROWINGKNIFE, target = false} +} + +monster.defenses = { + defense = 50, + armor = 35, + {name ="combat", interval = 4000, chance = 25, type = COMBAT_HEALING, minDamage = 50, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/draptor.lua b/data/monster/raids/draptor.lua new file mode 100644 index 00000000000..d57cab18279 --- /dev/null +++ b/data/monster/raids/draptor.lua @@ -0,0 +1,127 @@ +local mType = Game.createMonsterType("Draptor") +local monster = {} + +monster.description = "a draptor" +monster.experience = 2400 +monster.outfit = { + lookType = 382, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 695 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 50, + Stars = 3, + Occurrence = 3, + Locations = "Zao, north east of Dragonblaze Peaks during raid. There are up to 10 draptors per raid, \z + while 6 of them may also appear in mission 8 of Wrath of the Emperor Quest." + } + +monster.health = 3000 +monster.maxHealth = 3000 +monster.race = "blood" +monster.corpse = 13316 +monster.speed = 680 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 350, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "EEHEEHEEHEEH", yell = false}, + {text = "SCREEEEECH", yell = false}, + {text = "GRRR", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 33750, maxCount = 90}, + {name = "gold coin", chance = 33750, maxCount = 60}, + {name = "strong health potion", chance = 3150}, + {name = "strong mana potion", chance = 4150}, + {name = "dragon robe", chance = 950}, + {name = "draptor scales", chance = 6650} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150}, + {name ="combat", interval = 3000, chance = 30, type = COMBAT_ENERGYDAMAGE, minDamage = -130, maxDamage = -310, radius = 3, effect = CONST_ME_YELLOWENERGY, target = false}, + {name ="combat", interval = 3000, chance = 35, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -300, range = 7, shootEffect = CONST_ANI_ENERGY, target = false}, + {name ="combat", interval = 2500, chance = 17, type = COMBAT_FIREDAMAGE, minDamage = -70, maxDamage = -250, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false} +} + +monster.defenses = { + defense = 37, + armor = 23, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_HEALING, minDamage = 57, maxDamage = 93, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 12, speedChange = 457, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/fernfang.lua b/data/monster/raids/fernfang.lua new file mode 100644 index 00000000000..d1b9694e8a9 --- /dev/null +++ b/data/monster/raids/fernfang.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Fernfang") +local monster = {} + +monster.description = "Fernfang" +monster.experience = 600 +monster.outfit = { + lookType = 206, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 400 +monster.maxHealth = 400 +monster.race = "blood" +monster.corpse = 20566 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 50, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "War Wolf", chance = 13, interval = 1000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You desacrated this place!", yell = false}, + {text = "I will cleanse this isle!", yell = false}, + {text = "Grrrrrrr", yell = false}, + {text = "Yoooohuuuu!", yell = true} +} + +monster.loot = { + {id = 10563, chance = 100000}, + {id = 2148, chance = 100000, maxCount = 95}, + {id = 2152, chance = 93000, maxCount = 3}, + {id = 2800, chance = 86000}, + {id = 12448, chance = 53000}, + {id = 2166, chance = 40000}, + {id = 12449, chance = 40000}, + {id = 2154, chance = 33000}, + {id = 2015, chance = 20000}, + {id = 7589, chance = 20000}, + {id = 2044, chance = 13000}, + {id = 2401, chance = 13000}, + {id = 5786, chance = 13000}, + {id = 2260, chance = 7000}, + {id = 2689, chance = 7000}, + {id = 2652, chance = 7000}, + {id = 2177, chance = 7000}, + {id = 2802, chance = 7000}, + {id = 2129, chance = 7000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -50}, + {name ="combat", interval = 1000, chance = 13, type = COMBAT_HOLYDAMAGE, minDamage = -65, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SMALLHOLY, effect = CONST_ME_HOLYDAMAGE, target = false}, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_MANADRAIN, minDamage = -20, maxDamage = -45, range = 7, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 10, + armor = 15, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 10, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 1000, chance = 7, speedChange = 280, effect = CONST_ME_MAGIC_RED, target = false, duration = 10000}, + {name ="outfit", interval = 1000, chance = 5, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 14000, outfitMonster = "War Wolf"} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 70}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/ferumbras.lua b/data/monster/raids/ferumbras.lua new file mode 100644 index 00000000000..b97d8d20b82 --- /dev/null +++ b/data/monster/raids/ferumbras.lua @@ -0,0 +1,182 @@ +local mType = Game.createMonsterType("Ferumbras") +local monster = {} + +monster.description = "Ferumbras" +monster.experience = 12000 +monster.outfit = { + lookType = 229, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "venom" +monster.corpse = 6078 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 2, + runHealth = 2500, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Demon", chance = 12, interval = 3000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "NO ONE WILL STOP ME THIS TIME!", yell = true}, + {text = "THE POWER IS MINE!", yell = true}, + {text = "I returned from death and you dream about defeating me?", yell = false}, + {text = "Witness the first seconds of my eternal world domination!", yell = false}, + {text = "Even in my weakened state I will crush you all!", yell = false} +} + +monster.loot = { + {id = 5903, chance = 100000, unique = true}, + {id = 2148, chance = 98000, maxCount = 184}, + {id = 9971, chance = 75000, maxCount = 2}, + {id = 2522, chance = 26000, unique = true}, + {id = 8903, chance = 26000}, + {id = 2466, chance = 24000}, + {id = 2470, chance = 22000}, + {id = 8902, chance = 22000}, + {id = 8868, chance = 22000}, + {id = 2520, chance = 20000}, + {id = 8885, chance = 20000}, + {id = 7894, chance = 20000}, + {id = 2542, chance = 20000}, + {id = 2127, chance = 18000}, + {id = 7896, chance = 18000}, + {id = 7895, chance = 18000}, + {id = 2539, chance = 18000}, + {id = 8918, chance = 18000}, + {id = 7885, chance = 18000}, + {id = 8930, chance = 16000}, + {id = 7405, chance = 16000}, + {id = 7451, chance = 16000}, + {id = 2149, chance = 16000, maxCount = 100}, + {id = 7632, chance = 14000, maxCount = 5}, + {id = 7633, chance = 14000, maxCount = 5}, + {id = 2472, chance = 14000}, + {id = 2514, chance = 14000}, + {id = 7417, chance = 14000}, + {id = 8904, chance = 14000}, + {id = 7427, chance = 12000}, + {id = 8926, chance = 12000}, + {id = 8869, chance = 12000}, + {id = 2146, chance = 12000, maxCount = 98}, + {id = 2143, chance = 12000, maxCount = 88}, + {id = 7407, chance = 10000}, + {id = 8924, chance = 10000}, + {id = 7411, chance = 10000}, + {id = 2150, chance = 10000, maxCount = 54}, + {id = 9970, chance = 10000, maxCount = 87}, + {id = 7382, chance = 8000}, + {id = 7422, chance = 8000}, + {id = 2152, chance = 8000, maxCount = 58}, + {id = 7423, chance = 8000}, + {id = 5944, chance = 8000, maxCount = 9} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -350}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_MANADRAIN, minDamage = -500, maxDamage = -700, range = 7, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_LIFEDRAIN, minDamage = -300, maxDamage = -450, length = 8, spread = 3, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 2000, chance = 21, type = COMBAT_LIFEDRAIN, minDamage = -450, maxDamage = -500, radius = 6, effect = CONST_ME_POFF, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -20, maxDamage = -40, range = 7, shootEffect = CONST_ANI_POISON, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -900, maxDamage = -1000, range = 4, radius = 3, target = false}, + -- energy damage + {name ="condition", type = CONDITION_ENERGY, interval = 2000, chance = 18, minDamage = -300, maxDamage = -400, radius = 6, effect = CONST_ME_ENERGYHIT, target = false}, + -- fire + {name ="condition", type = CONDITION_FIRE, interval = 3000, chance = 20, minDamage = -500, maxDamage = -600, range = 7, radius = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true} +} + +monster.defenses = { + defense = 120, + armor = 100, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 900, maxDamage = 1500, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="invisible", interval = 4000, chance = 20, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 90}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/raids/fleabringer.lua b/data/monster/raids/fleabringer.lua new file mode 100644 index 00000000000..e32c284de15 --- /dev/null +++ b/data/monster/raids/fleabringer.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Fleabringer") +local monster = {} + +monster.description = "a fleabringer" +monster.experience = 100 +monster.outfit = { + lookType = 341, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 265 +monster.maxHealth = 265 +monster.race = "blood" +monster.corpse = 11250 +monster.speed = 280 +monster.manaCost = 465 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "meat", chance = 25000, maxCount = 3}, + {name = "worm", chance = 75000, maxCount = 3}, + {name = "shaggy tail", chance = 99990} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -90} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/foreman_kneebiter.lua b/data/monster/raids/foreman_kneebiter.lua new file mode 100644 index 00000000000..dd5b3a1a140 --- /dev/null +++ b/data/monster/raids/foreman_kneebiter.lua @@ -0,0 +1,103 @@ +local mType = Game.createMonsterType("Foreman Kneebiter") +local monster = {} + +monster.description = "Foreman Kneebiter" +monster.experience = 445 +monster.outfit = { + lookType = 70, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 570 +monster.maxHealth = 570 +monster.race = "blood" +monster.corpse = 6013 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "By Durin's beard!", yell = true} +} + +monster.loot = { + {id = 5880, chance = 2500, maxCount = 2}, + {id = 2148, chance = 90000, maxCount = 100}, + {id = 2513, chance = 6666} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -60, maxDamage = -200} +} + +monster.defenses = { + defense = 22, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 90}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/frost_servant.lua b/data/monster/raids/frost_servant.lua new file mode 100644 index 00000000000..2a7a92d311e --- /dev/null +++ b/data/monster/raids/frost_servant.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Frost Servant") +local monster = {} + +monster.description = "a frost servant" +monster.experience = 295 +monster.outfit = { + lookType = 261, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 385 +monster.maxHealth = 385 +monster.race = "undead" +monster.corpse = 7282 +monster.speed = 95 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Gnarr.", yell = false}, + {text = "Crrrrk.", yell = false}, + {text = "Chrrr.", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 140, attack = 40} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="hirintror summon", interval = 2000, chance = 18, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/furyosa.lua b/data/monster/raids/furyosa.lua new file mode 100644 index 00000000000..4e2007572e6 --- /dev/null +++ b/data/monster/raids/furyosa.lua @@ -0,0 +1,148 @@ +local mType = Game.createMonsterType("Furyosa") +local monster = {} + +monster.description = "Furyosa" +monster.experience = 11500 +monster.outfit = { + lookType = 149, + lookHead = 94, + lookBody = 77, + lookLegs = 96, + lookFeet = 0, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 25000 +monster.maxHealth = 25000 +monster.race = "blood" +monster.corpse = 20399 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Fury", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "MUHAHA!", yell = false}, + {text = "Back in black!", yell = false}, + {text = "Die!", yell = false}, + {text = "Dieeee!", yell = false}, + {text = "Caaarnaaage!", yell = false}, + {text = "Ahhhhrrrr!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 200}, + {id = 8844, chance = 100000, maxCount = 5}, + {id = 21400, chance = 45000}, + {id = 2152, chance = 85000, maxCount = 25}, + {id = 6558, chance = 35000, maxCount = 3}, + {id = 6500, chance = 22500}, + {id = 5911, chance = 4000}, + {id = 5944, chance = 21500}, + {id = 5944, chance = 50}, + {id = 2124, chance = 410}, + {id = 6301, chance = 60}, + {id = 2539, chance = 100}, + {id = 21725, chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -625}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -260, maxDamage = -310, radius = 6, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -50, maxDamage = -210, length = 8, spread = 3, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -300, length = 8, spread = 3, effect = CONST_ME_EXPLOSIONAREA, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_DEATHDAMAGE, minDamage = -300, maxDamage = -800, length = 8, spread = 3, target = false}, + {name ="combat", interval = 3000, chance = 18, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -150, radius = 5, effect = CONST_ME_GROUNDSHAKER, target = true}, + {name ="fury skill reducer", interval = 2000, chance = 5, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_MAGIC_BLUE}, + {name ="combat", interval = 7000, chance = 20, type = COMBAT_HEALING, minDamage = 500, maxDamage = 700, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 40}, + {type = COMBAT_HOLYDAMAGE , percent = 40}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/raids/ghazbaran.lua b/data/monster/raids/ghazbaran.lua new file mode 100644 index 00000000000..1fa959f38f4 --- /dev/null +++ b/data/monster/raids/ghazbaran.lua @@ -0,0 +1,178 @@ +local mType = Game.createMonsterType("Ghazbaran") +local monster = {} + +monster.description = "Ghazbaran" +monster.experience = 15000 +monster.outfit = { + lookType = 12, + lookHead = 0, + lookBody = 123, + lookLegs = 97, + lookFeet = 94, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 60000 +monster.maxHealth = 60000 +monster.race = "undead" +monster.corpse = 6068 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 10000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 98, + targetDistance = 1, + runHealth = 3500, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Deathslicer", chance = 20, interval = 4000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "COME AND GIVE ME SOME AMUSEMENT", yell = false}, + {text = "IS THAT THE BEST YOU HAVE TO OFFER, TIBIANS?", yell = true}, + {text = "I AM GHAZBARAN OF THE TRIANGLE... AND I AM HERE TO CHALLENGE YOU ALL.", yell = true}, + {text = "FLAWLESS VICTORY!", yell = true} +} + +monster.loot = { + {name = "blue tome", chance = 20000}, + {name = "teddy bear", chance = 12500}, + {id = 2124, chance = 8333}, + {name = "white pearl", chance = 25000, maxCount = 15}, + {name = "black pearl", chance = 11111, maxCount = 14}, + {name = "small diamond", chance = 25000, maxCount = 5}, + {name = "small sapphire", chance = 25000, maxCount = 10}, + {name = "small emerald", chance = 25000, maxCount = 10}, + {name = "small amethyst", chance = 25000, maxCount = 17}, + {name = "talon", chance = 12500, maxCount = 7}, + {name = "platinum coin", chance = 100000, maxCount = 69}, + {name = "green gem", chance = 20000}, + {name = "blue gem", chance = 14285}, + {name = "might ring", chance = 12500}, + {name = "stealth ring", chance = 12500}, + {name = "strange symbol", chance = 11111}, + {name = "life crystal", chance = 12500}, + {name = "mind stone", chance = 20000}, + {name = "gold ring", chance = 20000}, + {name = "ring of healing", chance = 20000}, + {name = "twin axe", chance = 11111}, + {name = "golden armor", chance = 8333}, + {name = "magic plate armor", chance = 8333}, + {name = "demon shield", chance = 12500}, + {name = "golden boots", chance = 8333}, + {name = "demon horn", chance = 33333, maxCount = 2}, + {id = 6300, chance = 25000}, + {name = "demonic essence", chance = 100000}, + {name = "ruthless axe", chance = 14285}, + {name = "assassin star", chance = 12500, maxCount = 44}, + {name = "havoc blade", chance = 16666}, + {name = "ravenwing", chance = 14285}, + {name = "great mana potion", chance = 20000}, + {name = "great health potion", chance = 20000}, + {name = "glacier kilt", chance = 8333}, + {name = "great spirit potion", chance = 25000}, + {name = "ultimate health potion", chance = 25000}, + {name = "oceanborn leviathan armor", chance = 16666}, + {name = "frozen plate", chance = 8333}, + {name = "spellbook of warding", chance = 20000}, + {name = "spellbook of mind control", chance = 11111}, + {name = "spellbook of lost souls", chance = 16666}, + {name = "spellscroll of prophecies", chance = 25000}, + {name = "spellbook of dark mysteries", chance = 20000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -2191}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_PHYSICALDAMAGE, minDamage = -250, maxDamage = -500, range = 7, radius = 6, effect = CONST_ME_HITAREA, target = false}, + {name ="combat", interval = 3000, chance = 34, type = COMBAT_PHYSICALDAMAGE, minDamage = -120, maxDamage = -500, range = 7, radius = 1, shootEffect = CONST_ANI_WHIRLWINDSWORD, target = true}, + {name ="combat", interval = 4000, chance = 30, type = COMBAT_ENERGYDAMAGE, minDamage = -100, maxDamage = -800, length = 8, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -480, range = 14, radius = 5, effect = CONST_ME_POFF, target = false}, + {name ="combat", interval = 4000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -650, range = 7, radius = 13, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="combat", interval = 4000, chance = 18, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -600, radius = 14, effect = CONST_ME_LOSEENERGY, target = false}, + {name ="combat", interval = 3000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -750, range = 7, radius = 4, effect = CONST_ME_ENERGYAREA, target = false} +} + +monster.defenses = { + defense = 65, + armor = 55, + {name ="combat", interval = 3000, chance = 35, type = COMBAT_HEALING, minDamage = 300, maxDamage = 800, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 4000, chance = 80, speedChange = 440, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 1}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = -1}, + {type = COMBAT_DEATHDAMAGE , percent = 1} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/raids/giant_spider_wyda.lua b/data/monster/raids/giant_spider_wyda.lua new file mode 100644 index 00000000000..f959eddaf64 --- /dev/null +++ b/data/monster/raids/giant_spider_wyda.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("Giant Spider Wyda") +local monster = {} + +monster.name = "Giant Spider" +monster.description = "a giant spider" +monster.experience = 12 +monster.outfit = { + lookType = 38, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 20 +monster.maxHealth = 20 +monster.race = "venom" +monster.corpse = 5977 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 20, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 6, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.events = { + "Wyda" +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 65150, maxCount = 5}, + {name = "spider fangs", chance = 960} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -9} +} + +monster.defenses = { + defense = 2, + armor = 2 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/glooth_battery.lua b/data/monster/raids/glooth_battery.lua new file mode 100644 index 00000000000..7708053359e --- /dev/null +++ b/data/monster/raids/glooth_battery.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Glooth Battery") +local monster = {} + +monster.description = "a glooth battery" +monster.experience = 3000 +monster.outfit = { + lookTypeEx = 23081 +} + +monster.health = 8000 +monster.maxHealth = 8000 +monster.race = "blood" +monster.corpse = 24309 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2152, chance = 33000, maxCount = 5}, + {id = 7591, chance = 10000}, + {id = 9977, chance = 1500}, + {id = 23540, chance = 1000} +} + +monster.attacks = { + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -206, maxDamage = -252, radius = 6, effect = CONST_ME_GREEN_RINGS, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 4000, chance = 15, type = COMBAT_HEALING, minDamage = 133, maxDamage = 454, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 25}, + {type = COMBAT_EARTHDAMAGE, percent = 1}, + {type = COMBAT_FIREDAMAGE, percent = 25}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 25}, + {type = COMBAT_HOLYDAMAGE , percent = 25}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/glooth_bomb.lua b/data/monster/raids/glooth_bomb.lua new file mode 100644 index 00000000000..732b5730213 --- /dev/null +++ b/data/monster/raids/glooth_bomb.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Glooth Bomb") +local monster = {} + +monster.description = "a glooth bomb" +monster.experience = 2600 +monster.outfit = { + lookType = 680, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 250000 +monster.maxHealth = 250000 +monster.race = "blood" +monster.corpse = 24256 +monster.speed = 80 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 3 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 23541, chance = 5000}, + {id = 24275, chance = 10000}, + {id = 2148, chance = 100000, maxCount = 50}, + {id = 7591, chance = 100000, maxCount = 13}, + {id = 7590, chance = 100000, maxCount = 13}, + {id = 8472, chance = 100000, maxCount = 13}, + {id = 23571, chance = 83300, maxCount = 2}, + {id = 2152, chance = 100000, maxCount = 30}, + {id = 5911, chance = 16670}, + {id = 2214, chance = 16670}, + {id = 2145, chance = 16670, maxCount = 5}, + {id = 2147, chance = 50000}, + {id = 9970, chance = 16670, maxCount = 3}, + {id = 2154, chance = 33330} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 110, attack = 50}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -230, length = 3, spread = 0, effect = CONST_ME_GROUNDSHAKER, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -200, radius = 3, effect = CONST_ME_GROUNDSHAKER, target = false}, + {name ="combat", interval = 2000, chance = 19, type = COMBAT_LIFEDRAIN, minDamage = -50, maxDamage = -225, radius = 5, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -150, maxDamage = -235, range = 7, radius = 4, shootEffect = CONST_ANI_LARGEROCK, effect = CONST_ME_EXPLOSIONAREA, target = true} +} + +monster.defenses = { + defense = 45, + armor = 40, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_HEALING, minDamage = 50, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 85}, + {type = COMBAT_ENERGYDAMAGE, percent = 85}, + {type = COMBAT_EARTHDAMAGE, percent = 85}, + {type = COMBAT_FIREDAMAGE, percent = 85}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 85}, + {type = COMBAT_HOLYDAMAGE , percent = 85}, + {type = COMBAT_DEATHDAMAGE , percent = 85} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/raids/glooth_fairy.lua b/data/monster/raids/glooth_fairy.lua new file mode 100644 index 00000000000..b41e1a8b927 --- /dev/null +++ b/data/monster/raids/glooth_fairy.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Glooth Fairy") +local monster = {} + +monster.description = "a glooth fairy" +monster.experience = 19000 +monster.outfit = { + lookType = 600, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 59000 +monster.maxHealth = 59000 +monster.race = "blood" +monster.corpse = 23363 +monster.speed = 600 +monster.manaCost = 490 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 80 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 199}, + {id = 2152, chance = 37170, maxCount = 14}, + {id = 23474, chance = 14630}, + {id = 7590, chance = 11270}, + {id = 23514, chance = 10550}, + {id = 9970, chance = 4320, maxCount = 2}, + {id = 2149, chance = 3600, maxCount = 2}, + {id = 23554, chance = 2400}, + {id = 9690, chance = 1920}, + {id = 23551, chance = 1200}, + {id = 23529, chance = 1200}, + {id = 23538, chance = 1200}, + {id = 2154, chance = 960}, + {id = 23550, chance = 720}, + {id = 23549, chance = 480}, + {id = 23536, chance = 480}, + {id = 2156, chance = 980}, + {id = 23663, chance = 480}, + {id = 5880, chance = 980}, + {id = 23515, chance = 280} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 210, attack = 260}, + -- fire + {name ="condition", type = CONDITION_FIRE, interval = 1000, chance = 7, minDamage = -200, maxDamage = -1000, range = 2, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="combat", interval = 1000, chance = 7, type = COMBAT_PHYSICALDAMAGE, minDamage = -50, maxDamage = -150, radius = 6, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 1000, chance = 50, type = COMBAT_FIREDAMAGE, minDamage = -20, maxDamage = -100, radius = 5, effect = CONST_ME_BLOCKHIT, target = false}, + {name ="firefield", interval = 1000, chance = 4, radius = 8, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 1000, chance = 34, type = COMBAT_FIREDAMAGE, minDamage = -50, maxDamage = -150, range = 7, radius = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 1000, chance = 13, type = COMBAT_FIREDAMAGE, minDamage = -50, maxDamage = -100, length = 8, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 1000, chance = 10, type = COMBAT_FIREDAMAGE, minDamage = -30, maxDamage = -100, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false} +} + +monster.defenses = { + defense = 150, + armor = 165, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_HEALING, minDamage = 500, maxDamage = 1000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_HEALING, minDamage = 200, maxDamage = 300, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 1000, chance = 10, speedChange = 1800, effect = CONST_ME_MAGIC_RED, target = false, duration = 3000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 25}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/grand_mother_foulscale.lua b/data/monster/raids/grand_mother_foulscale.lua new file mode 100644 index 00000000000..4909ddad0d4 --- /dev/null +++ b/data/monster/raids/grand_mother_foulscale.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Grand Mother Foulscale") +local monster = {} + +monster.description = "Grand Mother Foulscale" +monster.experience = 1400 +monster.outfit = { + lookType = 34, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1850 +monster.maxHealth = 1850 +monster.race = "blood" +monster.corpse = 5973 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 400, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "dragon hatchlings", chance = 40, interval = 4000, max = 4} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "GROOAAARRR!", yell = true} +} + +monster.loot = { + {id = 2148, chance = 37500, maxCount = 70}, + {id = 2148, chance = 37500, maxCount = 50}, + {id = 2546, chance = 4000, maxCount = 12}, + {id = 2672, chance = 15500, maxCount = 3}, + {id = 2406, chance = 25000}, + {id = 2398, chance = 21500}, + {id = 2509, chance = 14000}, + {id = 2455, chance = 10000}, + {id = 2397, chance = 5000}, + {id = 2457, chance = 3000}, + {id = 2647, chance = 2000}, + {id = 2413, chance = 2000}, + {id = 2387, chance = 1333}, + {id = 2187, chance = 1800}, + {id = 5920, chance = 100000}, + {id = 2434, chance = 600}, + {id = 5877, chance = 100000}, + {id = 2516, chance = 500}, + {id = 7430, chance = 650} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -20, maxDamage = -170}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -45, maxDamage = -85, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_FIREDAMAGE, minDamage = -90, maxDamage = -150, length = 8, spread = 3, effect = CONST_ME_FIREAREA, target = false} +} + +monster.defenses = { + defense = 20, + armor = 27, + {name ="combat", interval = 1000, chance = 17, type = COMBAT_HEALING, minDamage = 34, maxDamage = 66, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/grorlam.lua b/data/monster/raids/grorlam.lua new file mode 100644 index 00000000000..5447ffcc262 --- /dev/null +++ b/data/monster/raids/grorlam.lua @@ -0,0 +1,103 @@ +local mType = Game.createMonsterType("Grorlam") +local monster = {} + +monster.description = "Grorlam" +monster.experience = 2400 +monster.outfit = { + lookType = 205, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 3000 +monster.maxHealth = 3000 +monster.race = "blood" +monster.corpse = 6005 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 3 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 20}, + {id = 2483, chance = 10000}, + {id = 1294, chance = 20000, maxCount = 5}, + {id = 2395, chance = 2500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 75, attack = 60}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -150, maxDamage = -200, range = 7, shootEffect = CONST_ANI_LARGEROCK, target = false} +} + +monster.defenses = { + defense = 25, + armor = 15, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_HEALING, minDamage = 100, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 1000, chance = 6, speedChange = 270, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/hirintror.lua b/data/monster/raids/hirintror.lua new file mode 100644 index 00000000000..e8626867eb7 --- /dev/null +++ b/data/monster/raids/hirintror.lua @@ -0,0 +1,141 @@ +local mType = Game.createMonsterType("Hirintror") +local monster = {} + +monster.description = "Hirintror" +monster.experience = 800 +monster.outfit = { + lookType = 261, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "undead" +monster.corpse = 7282 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Srk.", yell = false}, + {text = "Krss!", yell = false}, + {text = "Chrrk! Krk!", yell = false} +} + +monster.loot = { + {id = 21697, chance = 200}, + {id = 2148, chance = 70000, maxCount = 100}, + {id = 21400, chance = 200}, + {id = 21696, chance = 200}, + {id = 2479, chance = 1200}, + {id = 2396, chance = 2200}, + {id = 7290, chance = 4200}, + {id = 7441, chance = 2200}, + {id = 7892, chance = 3200}, + {id = 7902, chance = 1200}, + {id = 7449, chance = 900}, + {id = 5912, chance = 900}, + {id = 7589, chance = 20000, maxCount = 5}, + {id = 7588, chance = 2000, maxCount = 5}, + {id = 2145, chance = 2000, maxCount = 5}, + {id = 2152, chance = 20000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 140, attack = 40}, + {name ="hirintror freeze", interval = 2000, chance = 15, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -75, maxDamage = -150, range = 7, radius = 3, shootEffect = CONST_ANI_ICE, effect = CONST_ME_BLOCKHIT, target = true}, + {name ="ice golem paralyze", interval = 2000, chance = 11, target = false}, + {name ="hirintror skill reducer", interval = 2000, chance = 10, target = false} +} + +monster.defenses = { + defense = 26, + armor = 25, + {name ="hirintror summon", interval = 2000, chance = 18, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = -20}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/raids/lethal_lissy.lua b/data/monster/raids/lethal_lissy.lua new file mode 100644 index 00000000000..ced417b56eb --- /dev/null +++ b/data/monster/raids/lethal_lissy.lua @@ -0,0 +1,114 @@ +local mType = Game.createMonsterType("Lethal Lissy") +local monster = {} + +monster.description = "Lethal Lissy" +monster.experience = 500 +monster.outfit = { + lookType = 155, + lookHead = 77, + lookBody = 0, + lookLegs = 76, + lookFeet = 132, + lookAddons = 3, + lookMount = 0 +} + +monster.health = 1450 +monster.maxHealth = 1450 +monster.race = "blood" +monster.corpse = 20438 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 50, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Pirate Cutthroat", chance = 50, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "small diamond", chance = 12500}, + {name = "meat", chance = 18750, maxCount = 3}, + {name = "gold coin", chance = 50000, maxCount = 60}, + {name = "gold coin", chance = 50000, maxCount = 61}, + {id = 2229, chance = 81250, maxCount = 2}, + {name = "pirate backpack", chance = 6250}, + {name = "plate armor", chance = 56250}, + {name = "knight armor", chance = 12500}, + {name = "very old piece of paper", chance = 25000}, + {id = 6100, chance = 100000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250} +} + +monster.defenses = { + defense = 50, + armor = 35, + {name ="combat", interval = 6000, chance = 65, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/man_in_the_cave.lua b/data/monster/raids/man_in_the_cave.lua new file mode 100644 index 00000000000..3a5f5324801 --- /dev/null +++ b/data/monster/raids/man_in_the_cave.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Man In The Cave") +local monster = {} + +monster.description = "man in the cave" +monster.experience = 777 +monster.outfit = { + lookType = 128, + lookHead = 77, + lookBody = 59, + lookLegs = 20, + lookFeet = 116, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 485 +monster.maxHealth = 485 +monster.race = "blood" +monster.corpse = 20446 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 50, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Monk", chance = 20, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "THE MONKS ARE MINE!", yell = true}, + {text = "I will rope you up! All of you!", yell = false}, + {text = "You have been roped up!", yell = false}, + {text = "A MIC to rule them all!", yell = false} +} + +monster.loot = { + {id = 2120, chance = 100000, maxCount = 3}, + {id = 7386, chance = 38000}, + {id = 5913, chance = 30000}, + {id = 2148, chance = 30000, maxCount = 39}, + {id = 7458, chance = 15000}, + {id = 7290, chance = 8000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -62}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -95, range = 7, shootEffect = CONST_ANI_SMALLSTONE, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="speed", interval = 2000, chance = 12, speedChange = 250, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HEALING, minDamage = 10, maxDamage = 50, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/mawhawk.lua b/data/monster/raids/mawhawk.lua new file mode 100644 index 00000000000..585627672ba --- /dev/null +++ b/data/monster/raids/mawhawk.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Mawhawk") +local monster = {} + +monster.description = "Mawhawk" +monster.experience = 14000 +monster.outfit = { + lookType = 595, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 45000 +monster.maxHealth = 45000 +monster.race = "blood" +monster.corpse = 22629 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 22396, chance = 30000, maxCount = 2}, + {id = 22532, chance = 30000}, + {id = 22598, chance = 30000, maxCount = 2, unique = true}, + {id = 2148, chance = 10000, maxCount = 100}, + {id = 2152, chance = 10000, maxCount = 25}, + {id = 2392, chance = 10000}, + {id = 5880, chance = 10000}, + {id = 5895, chance = 10000}, + {id = 5911, chance = 10000}, + {id = 5925, chance = 10000}, + {id = 7404, chance = 10000}, + {id = 7407, chance = 10000}, + {id = 7418, chance = 10000}, + {id = 18414, chance = 10000, maxCount = 3}, + {id = 18415, chance = 10000, maxCount = 3}, + {id = 18416, chance = 10000, maxCount = 5}, + {id = 18418, chance = 10000, maxCount = 5} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 90}, + {name ="combat", interval = 1800, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -685, length = 7, spread = 3, effect = CONST_ME_STONES, target = false}, + {name ="combat", interval = 2000, chance = 9, type = COMBAT_EARTHDAMAGE, minDamage = -250, maxDamage = -590, radius = 6, effect = CONST_ME_BIGPLANTS, target = false} +} + +monster.defenses = { + defense = 55, + armor = 55 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/raids/morgaroth.lua b/data/monster/raids/morgaroth.lua new file mode 100644 index 00000000000..b5b3fab846b --- /dev/null +++ b/data/monster/raids/morgaroth.lua @@ -0,0 +1,192 @@ +local mType = Game.createMonsterType("Morgaroth") +local monster = {} + +monster.description = "Morgaroth" +monster.experience = 15000 +monster.outfit = { + lookType = 12, + lookHead = 0, + lookBody = 94, + lookLegs = 79, + lookFeet = 79, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 55000 +monster.maxHealth = 55000 +monster.race = "fire" +monster.corpse = 6068 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 6 + +monster.changeTarget = { + interval = 10000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 98, + targetDistance = 1, + runHealth = 100, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Demon", chance = 33, interval = 4000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I AM MORGAROTH, LORD OF THE TRIANGLE... AND YOU ARE LOST!", yell = true}, + {text = "MY SEED IS FEAR AND MY HARVEST ARE YOUR SOULS!", yell = true}, + {text = "ZATHROTH! LOOK AT THE DESTRUCTION I AM CAUSING IN YOUR NAME!", yell = true}, + {text = "THE TRIANGLE OF TERROR WILL RISE!", yell = true} +} + +monster.loot = { + {name = "platinum coin", chance = 95000, maxCount = 74}, + {name = "demonic essence", chance = 95000, maxCount = 5}, + {name = "green gem", chance = 50000}, + {name = "great mana potion", chance = 45000}, + {name = "small amethyst", chance = 36000, maxCount = 18}, + {name = "devileye", chance = 36000}, + {name = "small emerald", chance = 27000, maxCount = 7}, + {name = "small sapphire", chance = 27000, maxCount = 9}, + {name = "red tome", chance = 27000}, + {name = "ultimate health potion", chance = 27000}, + {name = "talon", chance = 22000, maxCount = 7}, + {name = "demon horn", chance = 22000, maxCount = 2}, + {id = 6300, chance = 22000}, + {name = "ring of healing", chance = 22000}, + {name = "chain bolter", chance = 22000}, + {name = "dark lord's cape", chance = 22000}, + {name = "ironworker", chance = 25000}, + {name = "double axe", chance = 18000}, + {name = "great spirit potion", chance = 18000}, + {name = "magic plate armor", chance = 18000}, + {name = "might ring", chance = 18000}, + {name = "mind stone", chance = 18000}, + {name = "stealth ring", chance = 18000}, + {name = "fireborn giant armor", chance = 18000}, + {name = "royal crossbow", chance = 18000}, + {name = "teddy bear", chance = 18000}, + {name = "white pearl", chance = 13000, maxCount = 11}, + {name = "black pearl", chance = 13000, maxCount = 13}, + {name = "assassin star", chance = 13000, maxCount = 35}, + {name = "demonbone", chance = 13000}, + {name = "golden mug", chance = 13000}, + {name = "Morgaroth's heart", chance = 13000}, + {name = "obsidian truncheon", chance = 13000}, + {name = "stomper", chance = 13000}, + {name = "blue gem", chance = 9000}, + {name = "gold ring", chance = 9000}, + {name = "demon shield", chance = 9000}, + {name = "energy ring", chance = 9000}, + {name = "giant sword", chance = 9000}, + {name = "golden legs", chance = 9000}, + {name = "life crystal", chance = 9000}, + {id = 2162, chance = 9000}, + {name = "orb", chance = 9000}, + {name = "strange symbol", chance = 9000}, + {name = "steel boots", chance = 9000}, + {name = "thunder hammer", chance = 9000}, + {name = "small diamond", chance = 4500, maxCount = 5}, + {id = 2124, chance = 4500}, + {name = "fire axe", chance = 4500}, + {name = "great health potion", chance = 4500}, + {name = "mastermind shield", chance = 4500}, + {name = "dragon robe", chance = 4500}, + {name = "molten plate", chance = 4500}, + {name = "great shield", chance = 500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -2250}, + {name ="combat", interval = 3000, chance = 35, type = COMBAT_FIREDAMAGE, minDamage = -500, maxDamage = -1210, range = 7, radius = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 1800, chance = 40, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -580, range = 7, radius = 5, effect = CONST_ME_HITAREA, target = false}, + {name ="combat", interval = 3000, chance = 30, type = COMBAT_ENERGYDAMAGE, minDamage = -300, maxDamage = -1450, length = 8, spread = 3, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 2500, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -480, range = 7, radius = 5, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -250, maxDamage = -500, range = 7, radius = 13, effect = CONST_ME_SOUND_RED, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -450, radius = 14, effect = CONST_ME_LOSEENERGY, target = false}, + {name ="combat", interval = 3000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -200, range = 7, radius = 3, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -400, range = 7, effect = CONST_ME_SOUND_RED, target = false, duration = 20000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_MANADRAIN, minDamage = -70, maxDamage = -320, radius = 3, effect = CONST_ME_HITAREA, target = true}, + {name ="dark torturer skill reducer", interval = 2000, chance = 5, target = false} +} + +monster.defenses = { + defense = 65, + armor = 55, + {name ="combat", interval = 3000, chance = 35, type = COMBAT_HEALING, minDamage = 800, maxDamage = 1100, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 9000, chance = 15, type = COMBAT_HEALING, minDamage = 3800, maxDamage = 4000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 4000, chance = 80, speedChange = 470, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 80}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 80} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/raids/necropharus.lua b/data/monster/raids/necropharus.lua new file mode 100644 index 00000000000..a764bdab42b --- /dev/null +++ b/data/monster/raids/necropharus.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Necropharus") +local monster = {} + +monster.description = "Necropharus" +monster.experience = 1050 +monster.outfit = { + lookType = 209, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 750 +monster.maxHealth = 750 +monster.race = "blood" +monster.corpse = 20574 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Ghoul", chance = 20, interval = 1000}, + {name = "Ghost", chance = 17, interval = 1000}, + {name = "Mummy", chance = 15, interval = 1000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You will rise as my servant!", yell = false}, + {text = "Praise to my master Urgith!", yell = false} +} + +monster.loot = { + {id = 11237, chance = 100000}, + {id = 2148, chance = 100000, maxCount = 99}, + {id = 12431, chance = 100000}, + {id = 5809, chance = 100000}, + {id = 2423, chance = 52000}, + {id = 2436, chance = 47000}, + {id = 2449, chance = 38000}, + {id = 2229, chance = 19000}, + {id = 2796, chance = 14000}, + {id = 2186, chance = 14000}, + {id = 2231, chance = 9500}, + {id = 2541, chance = 9500}, + {id = 2195, chance = 4700}, + {id = 2663, chance = 4700}, + {id = 7589, chance = 4700} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -80, condition = {type = CONDITION_POISON, totalDamage = 8, interval = 4000}}, + {name ="combat", interval = 3000, chance = 70, type = COMBAT_PHYSICALDAMAGE, minDamage = -60, maxDamage = -217, range = 5, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 1000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -80, maxDamage = -120, range = 1, target = false}, + {name ="combat", interval = 1000, chance = 17, type = COMBAT_FIREDAMAGE, minDamage = -50, maxDamage = -140, range = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="combat", interval = 1000, chance = 17, type = COMBAT_ENERGYDAMAGE, minDamage = -50, maxDamage = -140, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 0, maxDamage = 300, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/ocyakao.lua b/data/monster/raids/ocyakao.lua new file mode 100644 index 00000000000..c2534bbbe8a --- /dev/null +++ b/data/monster/raids/ocyakao.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Ocyakao") +local monster = {} + +monster.description = "Ocyakao" +monster.experience = 490 +monster.outfit = { + lookType = 259, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 700 +monster.maxHealth = 700 +monster.race = "blood" +monster.corpse = 7320 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 60 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Chikuva!", yell = false}, + {text = "Grrrr! Kisavuta!", yell = false}, + {text = "Aiiee!", yell = false}, + {text = "Jinuma jamjam!", yell = false}, + {text = "Suvituka siq chuqua!", yell = false}, + {text = "Kiyosa sipaju!", yell = false} +} + +monster.loot = { + {id = 21400, chance = 200}, + {id = 2148, chance = 100000, maxCount = 20}, + {id = 2667, chance = 100000, maxCount = 5}, + {id = 2143, chance = 100000}, + {id = 5909, chance = 100000}, + {id = 2398, chance = 37500}, + {id = 21703, chance = 200, unique = true}, + {id = 2541, chance = 37570}, + {id = 7381, chance = 25050}, + {id = 7441, chance = 62570}, + {id = 7159, chance = 12500}, + {id = 2669, chance = 12520} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 25, attack = 50}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 70, maxDamage = -185, range = 7, radius = 3, shootEffect = CONST_ANI_SMALLSTONE, target = true} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -15}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 40}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/raids/orc_armor.lua b/data/monster/raids/orc_armor.lua new file mode 100644 index 00000000000..37fb0180609 --- /dev/null +++ b/data/monster/raids/orc_armor.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Orc Armor") +local monster = {} + +monster.name = "Orc Warlord" +monster.description = "an orc warlord" +monster.experience = 670 +monster.outfit = { + lookType = 2, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 950 +monster.maxHealth = 950 +monster.race = "blood" +monster.corpse = 6008 +monster.speed = 234 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ranat Ulderek!", yell = false}, + {text = "Orc buta bana!", yell = false}, + {text = "Ikem rambo zambo!", yell = false}, + {text = "Fetchi Maruk Buta", yell = false} +} + +monster.loot = { + {id = 12409, chance = 25000}, + {id = 12435, chance = 20000}, + {id = 2148, chance = 18000, maxCount = 45}, + {id = 2399, chance = 14000, maxCount = 18}, + {id = 2667, chance = 10800, maxCount = 2}, + {id = 11113, chance = 9500}, + {id = 2428, chance = 5200}, + {id = 3965, chance = 5200}, + {id = 2463, chance = 5110}, + {id = 12436, chance = 4610}, + {id = 2647, chance = 4180}, + {id = 2419, chance = 3550}, + {id = 2200, chance = 2190}, + {id = 2377, chance = 1800}, + {id = 2490, chance = 1400}, + {id = 2465, chance = 670}, + {id = 7618, chance = 420}, + {id = 2497, chance = 340}, + {id = 2434, chance = 290}, + {id = 7891, chance = 250}, + {id = 7395, chance = 80}, + {id = 2165, chance = 80}, + {id = 2500, chance = 5000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, range = 7, shootEffect = CONST_ANI_THROWINGSTAR, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="invisible", interval = 2000, chance = 5, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/orc_helmet.lua b/data/monster/raids/orc_helmet.lua new file mode 100644 index 00000000000..79b4f63913f --- /dev/null +++ b/data/monster/raids/orc_helmet.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Orc Helmet") +local monster = {} + +monster.name = "Orc Warlord" +monster.description = "an orc warlord" +monster.experience = 670 +monster.outfit = { + lookType = 2, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 950 +monster.maxHealth = 950 +monster.race = "blood" +monster.corpse = 6008 +monster.speed = 234 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ranat Ulderek!", yell = false}, + {text = "Orc buta bana!", yell = false}, + {text = "Ikem rambo zambo!", yell = false}, + {text = "Fetchi Maruk Buta", yell = false} +} + +monster.loot = { + {id = 12409, chance = 25000}, + {id = 12435, chance = 20000}, + {id = 2148, chance = 18000, maxCount = 45}, + {id = 2399, chance = 14000, maxCount = 18}, + {id = 2667, chance = 10800, maxCount = 2}, + {id = 11113, chance = 9500}, + {id = 2428, chance = 5200}, + {id = 3965, chance = 5200}, + {id = 2463, chance = 5110}, + {id = 12436, chance = 4610}, + {id = 2647, chance = 4180}, + {id = 2419, chance = 3550}, + {id = 2200, chance = 2190}, + {id = 2377, chance = 1800}, + {id = 2490, chance = 1400}, + {id = 2465, chance = 670}, + {id = 7618, chance = 420}, + {id = 2497, chance = 340}, + {id = 2434, chance = 290}, + {id = 7891, chance = 250}, + {id = 7395, chance = 80}, + {id = 2165, chance = 80}, + {id = 2499, chance = 5000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, range = 7, shootEffect = CONST_ANI_THROWINGSTAR, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="invisible", interval = 2000, chance = 5, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/orc_sambackpack.lua b/data/monster/raids/orc_sambackpack.lua new file mode 100644 index 00000000000..26a8987d5cb --- /dev/null +++ b/data/monster/raids/orc_sambackpack.lua @@ -0,0 +1,111 @@ +local mType = Game.createMonsterType("Orc Sambackpack") +local monster = {} + +monster.name = "Orc" +monster.description = "an orc" +monster.experience = 25 +monster.outfit = { + lookType = 5, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 70 +monster.maxHealth = 70 +monster.race = "blood" +monster.corpse = 5966 +monster.speed = 150 +monster.manaCost = 300 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grak brrretz!", yell = false}, + {text = "Grow truk grrrrr.", yell = false}, + {text = "Prek tars, dekklep zurk.", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 84810, maxCount = 14}, + {name = "old and used backpack", chance = 100000}, + {name = "sabre", chance = 5850}, + {name = "axe", chance = 4960}, + {name = "studded helmet", chance = 2950}, + {name = "studded armor", chance = 7860}, + {name = "studded shield", chance = 7300}, + {name = "meat", chance = 10160}, + {name = "orc tooth", chance = 210}, + {name = "orc leather", chance = 590}, + {id = 26654, chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -35} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/orc_shield.lua b/data/monster/raids/orc_shield.lua new file mode 100644 index 00000000000..e2ee6bdf015 --- /dev/null +++ b/data/monster/raids/orc_shield.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Orc Shield") +local monster = {} + +monster.name = "Orc Warlord" +monster.description = "an orc warlord" +monster.experience = 670 +monster.outfit = { + lookType = 2, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 950 +monster.maxHealth = 950 +monster.race = "blood" +monster.corpse = 6008 +monster.speed = 234 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ranat Ulderek!", yell = false}, + {text = "Orc buta bana!", yell = false}, + {text = "Ikem rambo zambo!", yell = false}, + {text = "Fetchi Maruk Buta", yell = false} +} + +monster.loot = { + {id = 12409, chance = 25000}, + {id = 12435, chance = 20000}, + {id = 2148, chance = 18000, maxCount = 45}, + {id = 2399, chance = 14000, maxCount = 18}, + {id = 2667, chance = 10800, maxCount = 2}, + {id = 11113, chance = 9500}, + {id = 2428, chance = 5200}, + {id = 3965, chance = 5200}, + {id = 2463, chance = 5110}, + {id = 12436, chance = 4610}, + {id = 2647, chance = 4180}, + {id = 2419, chance = 3550}, + {id = 2200, chance = 2190}, + {id = 2377, chance = 1800}, + {id = 2490, chance = 1400}, + {id = 2465, chance = 670}, + {id = 7618, chance = 420}, + {id = 2497, chance = 340}, + {id = 2434, chance = 290}, + {id = 7891, chance = 250}, + {id = 7395, chance = 80}, + {id = 2165, chance = 80}, + {id = 2537, chance = 5000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, range = 7, shootEffect = CONST_ANI_THROWINGSTAR, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="invisible", interval = 2000, chance = 5, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/orshabaal.lua b/data/monster/raids/orshabaal.lua new file mode 100644 index 00000000000..f9f974aa13d --- /dev/null +++ b/data/monster/raids/orshabaal.lua @@ -0,0 +1,181 @@ +local mType = Game.createMonsterType("Orshabaal") +local monster = {} + +monster.description = "Orshabaal" +monster.experience = 10000 +monster.outfit = { + lookType = 201, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 22500 +monster.maxHealth = 22500 +monster.race = "fire" +monster.corpse = 5995 +monster.speed = 380 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 2500, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "demon", chance = 10, interval = 1000, max = 4} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "PRAISED BE MY MASTERS, THE RUTHLESS SEVEN!", yell = false}, + {text = "YOU ARE DOOMED!", yell = false}, + {text = "ORSHABAAL IS BACK!", yell = false}, + {text = "Be prepared for the day my masters will come for you!", yell = false}, + {text = "SOULS FOR ORSHABAAL!", yell = false} +} + +monster.loot = { + {name = "purple tome", chance = 20000}, + {name = "golden mug", chance = 12500}, + {name = "crystal necklace", chance = 20000}, + {name = "white pearl", chance = 33333, maxCount = 15}, + {name = "black pearl", chance = 25000, maxCount = 8}, + {name = "small diamond", chance = 20000, maxCount = 5}, + {name = "small sapphire", chance = 33333, maxCount = 8}, + {name = "small emerald", chance = 25000, maxCount = 7}, + {name = "small amethyst", chance = 20000, maxCount = 17}, + {name = "talon", chance = 20000, maxCount = 3}, + {name = "platinum coin", chance = 100000, maxCount = 69}, + {name = "green gem", chance = 6666}, + {name = "blue gem", chance = 20000}, + {id = 2162, chance = 6666}, + {name = "might ring", chance = 6666}, + {name = "silver amulet", chance = 20000}, + {name = "platinum amulet", chance = 12500}, + {name = "strange symbol", chance = 20000}, + {name = "orb", chance = 6666}, + {name = "life crystal", chance = 12500}, + {name = "mind stone", chance = 20000}, + {name = "boots of haste", chance = 12500}, + {name = "protection amulet", chance = 20000}, + {name = "ring of healing", chance = 33333}, + {name = "two handed sword", chance = 12500}, + {name = "giant sword", chance = 25000}, + {name = "silver dagger", chance = 6666}, + {name = "golden sickle", chance = 6666}, + {name = "fire axe", chance = 12500}, + {name = "dragon hammer", chance = 6666}, + {name = "devil helmet", chance = 33333}, + {name = "golden legs", chance = 12500}, + {name = "magic plate armor", chance = 6666}, + {name = "mastermind shield", chance = 6666}, + {name = "demon shield", chance = 25000}, + {name = "Orshabaal's brain", chance = 6666}, + {name = "thunder hammer", chance = 6666}, + {name = "demon horn", chance = 50000}, + {id = 6300, chance = 50000}, + {name = "demonic essence", chance = 100000}, + {name = "assassin star", chance = 12500, maxCount = 42}, + {name = "great mana potion", chance = 33333}, + {name = "great health potion", chance = 20000}, + {name = "great spirit potion", chance = 12500}, + {name = "ultimate health potion", chance = 33333}, + {name = "gold ingot", chance = 6666} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1990}, + {name ="combat", interval = 1000, chance = 13, type = COMBAT_MANADRAIN, minDamage = -300, maxDamage = -600, range = 7, target = false}, + {name ="combat", interval = 1000, chance = 6, type = COMBAT_MANADRAIN, minDamage = -150, maxDamage = -350, radius = 5, effect = CONST_ME_POISONAREA, target = false}, + {name ="effect", interval = 1000, chance = 6, radius = 5, effect = CONST_ME_HITAREA, target = false}, + {name ="combat", interval = 1000, chance = 34, type = COMBAT_FIREDAMAGE, minDamage = -310, maxDamage = -600, range = 7, radius = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="firefield", interval = 1000, chance = 10, range = 7, radius = 4, shootEffect = CONST_ANI_FIRE, target = true}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -500, maxDamage = -850, length = 8, spread = 3, effect = CONST_ME_ENERGYHIT, target = false} +} + +monster.defenses = { + defense = 111, + armor = 90, + {name ="combat", interval = 1000, chance = 9, type = COMBAT_HEALING, minDamage = 1500, maxDamage = 2500, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 1000, chance = 17, type = COMBAT_HEALING, minDamage = 600, maxDamage = 1000, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 1000, chance = 5, speedChange = 1901, effect = CONST_ME_MAGIC_RED, target = false, duration = 7000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -1}, + {type = COMBAT_HOLYDAMAGE , percent = -1}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/raids/ron_the_ripper.lua b/data/monster/raids/ron_the_ripper.lua new file mode 100644 index 00000000000..ce958839abf --- /dev/null +++ b/data/monster/raids/ron_the_ripper.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("Ron The Ripper") +local monster = {} + +monster.description = "Ron The Ripper" +monster.experience = 500 +monster.outfit = { + lookType = 151, + lookHead = 95, + lookBody = 94, + lookLegs = 117, + lookFeet = 97, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "blood" +monster.corpse = 20502 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 50, + targetDistance = 1, + runHealth = 250, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Muahaha!", yell = false} +} + +monster.loot = { + {id = 6101, chance = 100000}, + {id = 2148, chance = 100000, maxCount = 128}, + {id = 2229, chance = 81000, maxCount = 2}, + {id = 2463, chance = 63000}, + {id = 2379, chance = 45000}, + {id = 7591, chance = 18000}, + {id = 2476, chance = 18000}, + {id = 2666, chance = 18000}, + {id = 5926, chance = 18000}, + {id = 2145, chance = 9000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250}, + {name ="combat", interval = 4000, chance = 60, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -160, shootEffect = CONST_ANI_THROWINGKNIFE, target = false} +} + +monster.defenses = { + defense = 50, + armor = 35, + {name ="combat", interval = 4000, chance = 25, type = COMBAT_HEALING, minDamage = 50, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/rottie_the_rotworm.lua b/data/monster/raids/rottie_the_rotworm.lua new file mode 100644 index 00000000000..925b8d48f35 --- /dev/null +++ b/data/monster/raids/rottie_the_rotworm.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Rottie The Rotworm") +local monster = {} + +monster.description = "Rottie The Rotworm" +monster.experience = 40 +monster.outfit = { + lookType = 26, + lookHead = 20, + lookBody = 30, + lookLegs = 40, + lookFeet = 50, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 65 +monster.maxHealth = 65 +monster.race = "blood" +monster.corpse = 5967 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 6230, maxCount = 30}, + {id = 2530, chance = 2850}, + {id = 2666, chance = 3260, maxCount = 2}, + {id = 3976, chance = 32500, maxCount = 5}, + {id = 2398, chance = 3335}, + {id = 2671, chance = 3160, maxCount = 2}, + {id = 2376, chance = 3335}, + {id = 2412, chance = 900}, + {id = 2480, chance = 1250} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 30, attack = 30} +} + +monster.defenses = { + defense = 11, + armor = 8 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/rotworm_queen.lua b/data/monster/raids/rotworm_queen.lua new file mode 100644 index 00000000000..80c439470c0 --- /dev/null +++ b/data/monster/raids/rotworm_queen.lua @@ -0,0 +1,102 @@ +local mType = Game.createMonsterType("Rotworm Queen") +local monster = {} + +monster.description = "a rotworm queen" +monster.experience = 75 +monster.outfit = { + lookType = 295, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 105 +monster.maxHealth = 105 +monster.race = "blood" +monster.corpse = 8947 +monster.speed = 126 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 50, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 47}, + {id = 8971, chance = 3333}, + {id = 3976, chance = 20000, maxCount = 45} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -5, maxDamage = -80} +} + +monster.defenses = { + defense = 15, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/sir_valorcrest.lua b/data/monster/raids/sir_valorcrest.lua new file mode 100644 index 00000000000..bb68660f66f --- /dev/null +++ b/data/monster/raids/sir_valorcrest.lua @@ -0,0 +1,117 @@ +local mType = Game.createMonsterType("Sir Valorcrest") +local monster = {} + +monster.description = "Sir Valorcrest" +monster.experience = 1800 +monster.outfit = { + lookType = 287, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1600 +monster.maxHealth = 1600 +monster.race = "undead" +monster.corpse = 8937 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 5000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Vampire", chance = 30, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I challenge you!", yell = false}, + {text = "A battle makes the blood so hot and sweet.", yell = false} +} + +monster.loot = { + {id = 7427, chance = 250}, + {id = 9020, chance = 100000}, + {id = 7588, chance = 1500}, + {id = 2207, chance = 1400}, + {id = 2229, chance = 15000}, + {id = 9020, chance = 100000}, + {id = 2152, chance = 50000, maxCount = 5}, + {id = 2148, chance = 100000, maxCount = 93}, + {id = 2534, chance = 6300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 70, attack = 95}, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -190, radius = 4, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true} +} + +monster.defenses = { + defense = 35, + armor = 38, + {name ="combat", interval = 1000, chance = 12, type = COMBAT_HEALING, minDamage = 100, maxDamage = 235, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 3000, chance = 25, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -15}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/the_horned_fox.lua b/data/monster/raids/the_horned_fox.lua new file mode 100644 index 00000000000..ec3e5e86f45 --- /dev/null +++ b/data/monster/raids/the_horned_fox.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("The Horned Fox") +local monster = {} + +monster.description = "the Horned Fox" +monster.experience = 300 +monster.outfit = { + lookType = 29, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 265 +monster.maxHealth = 265 +monster.race = "blood" +monster.corpse = 5983 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 6 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 20, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Minotaur Archer", chance = 13, interval = 1000, max = 2}, + {name = "Minotaur Guard", chance = 13, interval = 1000, max = 2}, + {name = "Minotaur Mage", chance = 13, interval = 1000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "You will never get me!", yell = false}, + {text = "I'll be back!", yell = false}, + {text = "Catch me, if you can!", yell = false}, + {text = "Help me, Boys!", yell = false} +} + +monster.loot = { + {id = 5804, chance = 100000}, + {id = 2148, chance = 96000, maxCount = 99}, + {id = 5878, chance = 96000}, + {id = 12428, chance = 92590, maxCount = 2}, + {id = 12438, chance = 85000}, + {id = 7363, chance = 48000, maxCount = 14}, + {id = 2465, chance = 25000}, + {id = 2666, chance = 18000, maxCount = 2}, + {id = 2513, chance = 14000}, + {id = 2502, chance = 5000}, + {id = 2580, chance = 7410}, + {id = 7588, chance = 7410}, + {id = 2387, chance = 3700} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -20, range = 7, shootEffect = CONST_ANI_BOLT, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 1000, chance = 17, range = 7, shootEffect = CONST_ANI_POISON, target = false} +} + +monster.defenses = { + defense = 16, + armor = 17, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_HEALING, minDamage = 25, maxDamage = 75, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="invisible", interval = 1000, chance = 10, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/the_pale_count.lua b/data/monster/raids/the_pale_count.lua new file mode 100644 index 00000000000..7b2e0ed66ad --- /dev/null +++ b/data/monster/raids/the_pale_count.lua @@ -0,0 +1,158 @@ +local mType = Game.createMonsterType("The Pale Count") +local monster = {} + +monster.description = "The Pale Count" +monster.experience = 28000 +monster.outfit = { + lookType = 557, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 50000 +monster.maxHealth = 50000 +monster.race = "blood" +monster.corpse = 21270 +monster.speed = 500 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Nightfiend", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Feel the hungry kiss of death!", yell = false}, + {text = "The monsters in the mirror will come eat your dreams.", yell = false}, + {text = "Your pitiful life has come to an end!", yell = false}, + {text = "I will squish you like a maggot and suck you dry!", yell = false}, + {text = "Yield to the inevitable!", yell = false}, + {text = "Some day I shall see my beautiful face in a mirror again.", yell = false} +} + +monster.loot = { + {id = 9020, chance = 100000}, + {id = 21244, chance = 100000}, + {id = 21253, chance = 5000}, + {id = 21252, chance = 5000}, + {id = 12405, chance = 50000}, + {id = 10602, chance = 50000}, + {id = 21400, chance = 5000}, + {id = 2148, chance = 1000000, maxCount = 100}, + {id = 2152, chance = 100000, maxCount = 5}, + {id = 7589, chance = 50000, maxCount = 3}, + {id = 7588, chance = 50000, maxCount = 3}, + {id = 2165, chance = 10000}, + {id = 2214, chance = 10000}, + {id = 5909, chance = 10000}, + {id = 5911, chance = 10000}, + {id = 5912, chance = 10000}, + {id = 7427, chance = 5000}, + {id = 2438, chance = 10000}, + {id = 7419, chance = 5000}, + {id = 8903, chance = 5000}, + {id = 21707, chance = 5000}, + {id = 2534, chance = 5000}, + {id = 21708, chance = 5000}, + {id = 2145, chance = 50000, maxCount = 5}, + {id = 2144, chance = 50000, maxCount = 5}, + {id = 2146, chance = 50000, maxCount = 5}, + {id = 2149, chance = 50000, maxCount = 5}, + {id = 2153, chance = 10000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 80, attack = 120}, + {name ="speed", interval = 1000, chance = 17, speedChange = -600, range = 7, radius = 4, target = true, duration = 1500}, + {name ="combat", interval = 2000, chance = 21, type = COMBAT_ICEDAMAGE, minDamage = -130, maxDamage = -350, range = 6, radius = 2, shootEffect = CONST_ANI_SMALLICE, effect = CONST_ME_GIANTICE, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_MANADRAIN, minDamage = -60, maxDamage = -120, range = 7, shootEffect = CONST_ANI_EARTH, effect = CONST_ME_CARNIPHILA, target = false} +} + +monster.defenses = { + defense = 75, + armor = 75 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/raids/the_voice_of_ruin.lua b/data/monster/raids/the_voice_of_ruin.lua new file mode 100644 index 00000000000..10e105c2607 --- /dev/null +++ b/data/monster/raids/the_voice_of_ruin.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("The Voice of Ruin") +local monster = {} + +monster.description = "a the voice of ruin" +monster.experience = 3500 +monster.outfit = { + lookType = 344, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5500 +monster.maxHealth = 5500 +monster.race = "blood" +monster.corpse = 11288 +monster.speed = 460 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 40 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 50, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 33000, maxCount = 100}, + {id = 2148, chance = 32000, maxCount = 100}, + {id = 2148, chance = 32000, maxCount = 36}, + {id = 11326, chance = 5800}, + {id = 2152, chance = 2920, maxCount = 5}, + {id = 11327, chance = 3800}, + {id = 9971, chance = 3800}, + {id = 11325, chance = 3800}, + {id = 11303, chance = 3800} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 80, attack = 100}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -440, maxDamage = -820, length = 3, spread = 2, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -290, maxDamage = -540, radius = 3, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -190, maxDamage = -480, length = 8, spread = 3, effect = CONST_ME_GREEN_RINGS, target = false} +} + +monster.defenses = { + defense = 45, + armor = 45, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 475, maxDamage = 625, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/the_welter.lua b/data/monster/raids/the_welter.lua new file mode 100644 index 00000000000..9f7cad1faf0 --- /dev/null +++ b/data/monster/raids/the_welter.lua @@ -0,0 +1,152 @@ +local mType = Game.createMonsterType("The Welter") +local monster = {} + +monster.description = "The Welter" +monster.experience = 11000 +monster.outfit = { + lookType = 563, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 25000 +monster.maxHealth = 25000 +monster.race = "blood" +monster.corpse = 21291 +monster.speed = 256 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "egg2", chance = 16, interval = 2000}, + {name = "spawn of the welter", chance = 16, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "FCHHHHH", yell = true} +} + +monster.loot = { + {id = 21400, chance = 200}, + {id = 21690, chance = 200}, + {id = 2475, chance = 2000}, + {id = 21691, chance = 500}, + {id = 2195, chance = 1000}, + {id = 2536, chance = 2000}, + {id = 2396, chance = 2000}, + {id = 2146, chance = 20000, maxCount = 2}, + {id = 2476, chance = 3000}, + {id = 7588, chance = 20000, maxCount = 2}, + {id = 10219, chance = 1000}, + {id = 2197, chance = 20000}, + {id = 9971, chance = 800}, + {id = 2498, chance = 500}, + {id = 7632, chance = 600}, + {id = 4850, chance = 2000}, + {id = 7589, chance = 20000, maxCount = 2}, + {id = 2152, chance = 20000, maxCount = 10}, + {id = 2148, chance = 20000, maxCount = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 90, attack = 100}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 17, minDamage = -500, maxDamage = -660, length = 8, spread = 3, effect = CONST_ME_SMALLPLANTS, target = false}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_DEATHDAMAGE, minDamage = -200, maxDamage = -450, length = 8, spread = 3, effect = CONST_ME_BLACKSMOKE, target = false}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_ICEDAMAGE, minDamage = -150, maxDamage = -270, range = 7, radius = 4, shootEffect = CONST_ANI_ICE, effect = CONST_ME_ICEATTACK, target = true}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_ICEDAMAGE, minDamage = -120, maxDamage = -230, range = 1, radius = 1, shootEffect = CONST_ANI_ICE, effect = CONST_ME_ICEATTACK, target = true}, + {name ="the welter paralyze", interval = 2000, chance = 9, target = false} +} + +monster.defenses = { + defense = 45, + armor = 27, + {name ="combat", interval = 2000, chance = 32, type = COMBAT_HEALING, minDamage = 250, maxDamage = 600, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_HEALING, minDamage = 150, maxDamage = 700, radius = 5, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="the welter summon2", interval = 2000, chance = 9, target = false}, + {name ="the welter heal", interval = 2000, chance = 8, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = 30}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/raids/tyrn.lua b/data/monster/raids/tyrn.lua new file mode 100644 index 00000000000..8e78a2efc8f --- /dev/null +++ b/data/monster/raids/tyrn.lua @@ -0,0 +1,148 @@ +local mType = Game.createMonsterType("Tyrn") +local monster = {} + +monster.description = "Tyrn" +monster.experience = 6900 +monster.outfit = { + lookType = 562, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 12000 +monster.maxHealth = 12000 +monster.race = "blood" +monster.corpse = 21287 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "GRRR", yell = false}, + {text = "GRROARR", yell = false} +} + +monster.loot = { + {id = 21400, chance = 5000}, + {id = 21695, chance = 3000}, + {id = 2672, chance = 55000, maxCount = 3}, + {id = 2268, chance = 15000}, + {id = 2148, chance = 100000, maxCount = 50}, + {id = 2152, chance = 60000, maxCount = 8}, + {id = 7368, chance = 30000, maxCount = 5}, + {id = 7588, chance = 25000, maxCount = 5}, + {id = 7589, chance = 25000, maxCount = 5}, + {id = 10582, chance = 100000}, + {id = 2156, chance = 9000}, + {id = 2154, chance = 9000}, + {id = 2153, chance = 9000}, + {id = 2515, chance = 9000}, + {id = 8873, chance = 9000}, + {id = 2145, chance = 15000, maxCount = 5}, + {id = 2150, chance = 15000, maxCount = 5}, + {id = 2149, chance = 15000, maxCount = 5}, + {id = 2146, chance = 15000, maxCount = 5}, + {id = 9970, chance = 15000, maxCount = 5}, + {id = 2147, chance = 15000, maxCount = 5} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 70, attack = 130}, + {name ="drunk", interval = 2000, chance = 8, radius = 8, effect = CONST_ME_SOUND_YELLOW, target = false, duration = 25000}, + {name ="combat", interval = 2000, chance = 33, type = COMBAT_ENERGYDAMAGE, minDamage = -100, maxDamage = -190, range = 7, shootEffect = CONST_ANI_ENERGYBALL, effect = CONST_ME_ENERGYAREA, target = true}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -300, range = 7, radius = 4, shootEffect = CONST_ANI_EXPLOSION, effect = CONST_ME_EXPLOSIONHIT, target = true}, + {name ="tyrn electrify", interval = 2000, chance = 11, target = false}, + {name ="tyrn skill reducer", interval = 2000, chance = 14, target = false} +} + +monster.defenses = { + defense = 68, + armor = 58, + {name ="combat", interval = 2000, chance = 33, type = COMBAT_HEALING, minDamage = 200, maxDamage = 300, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 11, effect = CONST_ME_ENERGYHIT}, + {name ="tyrn heal", interval = 1000, chance = 100, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 10}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/raids/white_pale.lua b/data/monster/raids/white_pale.lua new file mode 100644 index 00000000000..9764bdf94e7 --- /dev/null +++ b/data/monster/raids/white_pale.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("White Pale") +local monster = {} + +monster.description = "White Pale" +monster.experience = 390 +monster.outfit = { + lookType = 564, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 500 +monster.maxHealth = 500 +monster.race = "blood" +monster.corpse = 21295 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 21400, chance = 200}, + {id = 2148, chance = 80000, maxCount = 100}, + {id = 2148, chance = 70000, maxCount = 100}, + {id = 21693, chance = 500}, + {id = 21692, chance = 500}, + {id = 2168, chance = 1000}, + {id = 2145, chance = 7000}, + {id = 2666, chance = 70000, maxCount = 4}, + {id = 10609, chance = 70000}, + {id = 2439, chance = 70000}, + {id = 11192, chance = 70000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 45, attack = 40}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_EARTHDAMAGE, minDamage = -100, maxDamage = -110, radius = 5, effect = CONST_ME_SMALLPLANTS, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 12, minDamage = -200, maxDamage = -300, radius = 3, effect = CONST_ME_HITAREA, target = false}, + {name ="white pale paralyze", interval = 2000, chance = 11, target = false} +} + +monster.defenses = { + defense = 11, + armor = 8, + {name ="white pale summon", interval = 2000, chance = 12, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/raids/xenia.lua b/data/monster/raids/xenia.lua new file mode 100644 index 00000000000..10ba556170e --- /dev/null +++ b/data/monster/raids/xenia.lua @@ -0,0 +1,105 @@ +local mType = Game.createMonsterType("Xenia") +local monster = {} + +monster.description = "Xenia" +monster.experience = 255 +monster.outfit = { + lookType = 137, + lookHead = 95, + lookBody = 115, + lookLegs = 115, + lookFeet = 95, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 200 +monster.maxHealth = 200 +monster.race = "blood" +monster.corpse = 20542 +monster.speed = 176 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2229, chance = 100000, maxCount = 2}, + {name = "gold coin", chance = 66666, maxCount = 34}, + {name = "sabre", chance = 33000}, + {name = "studded shield", chance = 33000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -50}, + {name ="drunk", interval = 2000, chance = 10, length = 3, spread = 2, effect = CONST_ME_SOUND_RED, target = false, duration = 5000} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="speed", interval = 2000, chance = 15, speedChange = 320, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -6}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 7}, + {type = COMBAT_DEATHDAMAGE , percent = -7} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/yakchal.lua b/data/monster/raids/yakchal.lua new file mode 100644 index 00000000000..128ea3e0765 --- /dev/null +++ b/data/monster/raids/yakchal.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Yakchal") +local monster = {} + +monster.description = "Yakchal" +monster.experience = 4400 +monster.outfit = { + lookType = 149, + lookHead = 8, + lookBody = 0, + lookLegs = 85, + lookFeet = 85, + lookAddons = 1, + lookMount = 0 +} + +monster.health = 5750 +monster.maxHealth = 5750 +monster.race = "blood" +monster.corpse = 20546 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 2000, + chance = 5 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 50, + targetDistance = 4, + runHealth = 100, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Ice Golem", chance = 13, interval = 1000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "YOU BETTER DIE TO MY MINIONS BECAUSE YOU'LL WISH YOU DID IF I COME FOR YOU!", yell = false}, + {text = "DESTROY THE INFIDELS", yell = false}, + {text = "You are mine!", yell = false}, + {text = "I will make you all pay!", yell = false}, + {text = "No one will stop my plans!", yell = false}, + {text = "You are responsible for this!", yell = false} +} + +monster.loot = { + {id = 7290, chance = 100000}, + {id = 2148, chance = 97000, maxCount = 283}, + {id = 5912, chance = 74000}, + {id = 7440, chance = 65000}, + {id = 9971, chance = 33000}, + {id = 7449, chance = 22000}, + {id = 2201, chance = 15000}, + {id = 7896, chance = 12000}, + {id = 7590, chance = 9500}, + {id = 7443, chance = 8000}, + {id = 7897, chance = 8000}, + {id = 2436, chance = 8000}, + {id = 7459, chance = 6350}, + {id = 7439, chance = 4700}, + {id = 2168, chance = 4700}, + {id = 7410, chance = 4700}, + {id = 2195, chance = 1500}, + {id = 2796, chance = 1500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -389}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_ICEDAMAGE, minDamage = 0, maxDamage = -430, radius = 4, shootEffect = CONST_ANI_SMALLICE, effect = CONST_ME_ICEAREA, target = true}, + {name ="combat", interval = 3000, chance = 34, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -300, range = 7, radius = 3, shootEffect = CONST_ANI_SNOWBALL, target = true}, + {name ="speed", interval = 2000, chance = 10, speedChange = -300, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000} +} + +monster.defenses = { + defense = 20, + armor = 15, + {name ="combat", interval = 1000, chance = 25, type = COMBAT_HEALING, minDamage = 50, maxDamage = 100, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/zomba.lua b/data/monster/raids/zomba.lua new file mode 100644 index 00000000000..a024dc16870 --- /dev/null +++ b/data/monster/raids/zomba.lua @@ -0,0 +1,104 @@ +local mType = Game.createMonsterType("Zomba") +local monster = {} + +monster.description = "Zomba" +monster.experience = 300 +monster.outfit = { + lookType = 41, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 300 +monster.maxHealth = 300 +monster.race = "blood" +monster.corpse = 5986 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Groarrrr! Rwarrrr!", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 25}, + {id = 10608, chance = 100000, maxCount = 2}, + {id = 2152, chance = 25000}, + {id = 2168, chance = 12500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 30, attack = 20} +} + +monster.defenses = { + defense = 13, + armor = 6 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -15}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = -8} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/raids/zulazza_the_corruptor.lua b/data/monster/raids/zulazza_the_corruptor.lua new file mode 100644 index 00000000000..14493a9a216 --- /dev/null +++ b/data/monster/raids/zulazza_the_corruptor.lua @@ -0,0 +1,149 @@ +local mType = Game.createMonsterType("Zulazza The Corruptor") +local monster = {} + +monster.description = "Zulazza The Corruptor" +monster.experience = 10000 +monster.outfit = { + lookType = 334, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 46500 +monster.maxHealth = 46500 +monster.race = "blood" +monster.corpse = 11107 +monster.speed = 290 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = true, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 1500, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I'm Zulazza, and you won't forget me that fazzt.", yell = false}, + {text = "Zzaion is our last zztand! I will not leave wizzout a fight!", yell = false}, + {text = "Behind zze Great Gate liezz your doom!", yell = false}, + {text = "Oh, HE will take revenge on zzizz azzault when you zztep in front of HIZZ fazze!", yell = false} +} + +monster.loot = { + {id = 7591, chance = 30500}, + {id = 2152, chance = 41325, maxCount = 30}, + {id = 2148, chance = 49650, maxCount = 100}, + {id = 9808, chance = 50500}, + {id = 9971, chance = 33000, maxCount = 4}, + {id = 2158, chance = 30500}, + {id = 2155, chance = 20500}, + {id = 8473, chance = 10500}, + {id = 11118, chance = 5500}, + {id = 5944, chance = 19250, maxCount = 4}, + {id = 2528, chance = 15500}, + {id = 7366, chance = 8100, maxCount = 67}, + {id = 7632, chance = 28000, maxCount = 2}, + {id = 2154, chance = 15500}, + {id = 2156, chance = 10500}, + {id = 7440, chance = 10500}, + {id = 2153, chance = 25500}, + {id = 7590, chance = 20500}, + {id = 8882, chance = 5500}, + {id = 2514, chance = 5500}, + {id = 2127, chance = 10500}, + {id = 8891, chance = 5500}, + {id = 2515, chance = 5500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 200, attack = 200}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_PHYSICALDAMAGE, minDamage = -500, maxDamage = -800, length = 8, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -800, radius = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_MANADRAIN, minDamage = -50, maxDamage = -130, range = 7, effect = CONST_ME_MAGIC_GREEN, target = true}, + {name ="speed", interval = 2000, chance = 20, speedChange = -500, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000} +} + +monster.defenses = { + defense = 119, + armor = 96, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 2000, maxDamage = 3000, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 70}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = 30} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType.onThink = function(monster, interval) +end + +mType.onAppear = function(monster, creature) + if monster:getType():isRewardBoss() then + monster:setReward(true) + end +end + +mType.onDisappear = function(monster, creature) +end + +mType.onMove = function(monster, creature, fromPosition, toPosition) +end + +mType.onSay = function(monster, creature, type, message) +end + +mType:register(monster) diff --git a/data/monster/reptiles/adult_goanna.lua b/data/monster/reptiles/adult_goanna.lua new file mode 100644 index 00000000000..9c133b9c02a --- /dev/null +++ b/data/monster/reptiles/adult_goanna.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Adult Goanna") +local monster = {} + +monster.description = "an adult goanna" +monster.experience = 6650 +monster.outfit = { + lookType = 1195, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1818 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Kilmaresh Central Steppe, Kilmaresh Southern Steppe, Green Belt." + } + +monster.health = 8300 +monster.maxHealth = 8300 +monster.race = "blood" +monster.corpse = 36240 +monster.speed = 420 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 100000, maxCount = 3}, + {name = "Envenomed Arrow", chance = 55360, maxCount = 8}, + {name = "Earth Arrow", chance = 16800, maxCount = 29}, + {name = "Terra Rod", chance = 11000}, + {name = "Goanna Meat", chance = 12140}, + {name = "Goanna Claw", chance = 4290}, + {name = "Lizard Heart", chance = 1400}, + {name = "Red Goanna Scale", chance = 10000}, + {name = "Fur Armor", chance = 3200}, + {name = "Serpent Sword", chance = 3600}, + {name = "Terra Amulet", chance = 4650}, + {name = "Terra Hood", chance = 7100}, + {name = "Wood Cape", chance = 1800}, + {name = "Scared Frog", chance = 2100}, + {name = "Sacred Tree Amulet", chance = 2500}, + {name = "Small Tortoise", chance = 1800} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -350, condition = {type = CONDITION_POISON, totalDamage = 19, interval = 4000}}, + {name ="wave t", interval = 2000, chance = 10, minDamage = -250, maxDamage = -380, target = false}, + {name ="combat", interval = 2000, chance = 12, type = COMBAT_EARTHDAMAGE, minDamage = -450, maxDamage = -550, range = 3, radius = 1, shootEffect = CONST_ANI_EARTH, effect = CONST_ME_EXPLOSIONHIT, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -210, maxDamage = -300, radius = 5, effect = CONST_ME_GROUNDSHAKER, target = false} +} + +monster.defenses = { + defense = 84, + armor = 84, + {name ="speed", interval = 2000, chance = 5, speedChange = 500, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 75}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/cobra.lua b/data/monster/reptiles/cobra.lua new file mode 100644 index 00000000000..826265ec1bd --- /dev/null +++ b/data/monster/reptiles/cobra.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("Cobra") +local monster = {} + +monster.description = "a cobra" +monster.experience = 30 +monster.outfit = { + lookType = 81, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 81 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Ankrahmun Library Tomb, Tarpit Tomb, Mountain Tomb, Peninsula Tomb, Darama, Tiquanda, \z + Drefia, Forbidden Lands, Arena Quarter, Lion's Rock." + } + +monster.health = 65 +monster.maxHealth = 65 +monster.race = "blood" +monster.corpse = 3007 +monster.speed = 120 +monster.manaCost = 275 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Zzzzzz", yell = false}, + {text = "Fsssss", yell = false} +} + +monster.loot = { + {name = "cobra tongue", chance = 5000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = 0, condition = {type = CONDITION_POISON, totalDamage = 100, interval = 4000}}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -20, maxDamage = -40, range = 7, shootEffect = CONST_ANI_POISON, target = false} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/crocodile.lua b/data/monster/reptiles/crocodile.lua new file mode 100644 index 00000000000..5eb81dadcf6 --- /dev/null +++ b/data/monster/reptiles/crocodile.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("Crocodile") +local monster = {} + +monster.description = "a crocodile" +monster.experience = 40 +monster.outfit = { + lookType = 119, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 119 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "In the crocodile cave and the jungle east of Port Hope as well as the swamp to the north, \z + Fenrock, Arena and Zoo Quarter, Trade Quarter, Talahu, also located on Meriana and Laguna Islands." + } + +monster.health = 105 +monster.maxHealth = 105 +monster.race = "blood" +monster.corpse = 6046 +monster.speed = 78 +monster.manaCost = 350 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 10}, + {name = "ham", chance = 40000}, + {name = "crocodile boots", chance = 100}, + {name = "piece of crocodile leather", chance = 20180} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -40} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/dreadmaw.lua b/data/monster/reptiles/dreadmaw.lua new file mode 100644 index 00000000000..328268c0d6e --- /dev/null +++ b/data/monster/reptiles/dreadmaw.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Dreadmaw") +local monster = {} + +monster.description = "a dreadmaw" +monster.experience = 1500 +monster.outfit = { + lookType = 119, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 2000 +monster.maxHealth = 2000 +monster.race = "blood" +monster.corpse = 6046 +monster.speed = 190 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 99990, maxCount = 10}, + {name = "gold ingot", chance = 99990}, + {name = "ham", chance = 50000}, + {name = "piece of crocodile leather", chance = 99990} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/killer_caiman.lua b/data/monster/reptiles/killer_caiman.lua new file mode 100644 index 00000000000..d3357bb9978 --- /dev/null +++ b/data/monster/reptiles/killer_caiman.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Killer Caiman") +local monster = {} + +monster.description = "a killer caiman" +monster.experience = 900 +monster.outfit = { + lookType = 358, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 627 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Northern Zao Plantations, Souleater Mountains, Muggy Plains, \z + Killer Caiman Cave in the Zao Steppe, Chyllfroest." + } + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "blood" +monster.corpse = 11430 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 80}, + {name = "small emerald", chance = 10150, maxCount = 5}, + {name = "obsidian lance", chance = 4975}, + {name = "ham", chance = 40100}, + {name = "crocodile boots", chance = 510}, + {id = 7632, chance = 1130}, + {name = "piece of crocodile leather", chance = 25430}, + {name = "bunch of ripe rice", chance = 4800, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -180} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="speed", interval = 2000, chance = 15, speedChange = 700, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/lizard_chosen.lua b/data/monster/reptiles/lizard_chosen.lua new file mode 100644 index 00000000000..3df3b165ae0 --- /dev/null +++ b/data/monster/reptiles/lizard_chosen.lua @@ -0,0 +1,134 @@ +local mType = Game.createMonsterType("Lizard Chosen") +local monster = {} + +monster.description = "a lizard chosen" +monster.experience = 2200 +monster.outfit = { + lookType = 344, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 620 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Temple of Equilibrium (Zao) Hidden stairs, Fire Dragon Dojo, Corruption Hole, Razzachai." + } + +monster.health = 3050 +monster.maxHealth = 3050 +monster.race = "blood" +monster.corpse = 11288 +monster.speed = 272 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 50, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grzzzzzzz!", yell = false}, + {text = "Garrrblarrrrzzzz!", yell = false}, + {text = "Kzzzzzzz!", yell = false} +} + +monster.loot = { + {name = "small diamond", chance = 2550, maxCount = 5}, + {name = "gold coin", chance = 33000, maxCount = 100}, + {name = "gold coin", chance = 32000, maxCount = 100}, + {name = "gold coin", chance = 32000, maxCount = 36}, + {name = "platinum coin", chance = 2920, maxCount = 5}, + {name = "tower shield", chance = 1100}, + {name = "lizard leather", chance = 2000}, + {name = "lizard scale", chance = 980, maxCount = 3}, + {name = "great health potion", chance = 5350, maxCount = 3}, + {name = "Zaoan armor", chance = 980}, + {name = "Zaoan helmet", chance = 140}, + {name = "Zaoan shoes", chance = 810}, + {name = "Zaoan legs", chance = 940}, + {name = "spiked iron ball", chance = 9890}, + {name = "corrupted flag", chance = 3350}, + {name = "cursed shoulder spikes", chance = 5800}, + {name = "scale of corruption", chance = 2870} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -360}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -240, maxDamage = -320, length = 3, spread = 2, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -190, maxDamage = -340, radius = 3, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -90, maxDamage = -180, length = 8, spread = 3, effect = CONST_ME_GREEN_RINGS, target = false} +} + +monster.defenses = { + defense = 45, + armor = 28, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 75, maxDamage = 125, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/lizard_dragon_priest.lua b/data/monster/reptiles/lizard_dragon_priest.lua new file mode 100644 index 00000000000..9fd3faacfa0 --- /dev/null +++ b/data/monster/reptiles/lizard_dragon_priest.lua @@ -0,0 +1,137 @@ +local mType = Game.createMonsterType("Lizard Dragon Priest") +local monster = {} + +monster.description = "a lizard dragon priest" +monster.experience = 1320 +monster.outfit = { + lookType = 339, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 623 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Zzaion, Zao Palace and its antechambers, Muggy Plains, Corruption Hole, Razachai, \z + Temple of Equilibrium, Northern Zao Plantations." + } + +monster.health = 1450 +monster.maxHealth = 1450 +monster.race = "blood" +monster.corpse = 11280 +monster.speed = 256 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 50, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Dragon Hatchling", chance = 20, interval = 2000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I ssssmell warm blood!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 5000, maxCount = 100}, + {name = "gold coin", chance = 4400, maxCount = 88}, + {name = "small amethyst", chance = 4900, maxCount = 3}, + {name = "platinum coin", chance = 4090, maxCount = 2}, + {name = "yellow gem", chance = 1000}, + {name = "life ring", chance = 770}, + {name = "terra rod", chance = 1001}, + {name = "wand of inferno", chance = 1480}, + {name = "lizard leather", chance = 980}, + {name = "lizard scale", chance = 1130}, + {name = "strong mana potion", chance = 12110}, + {name = "great mana potion", chance = 7940}, + {name = "focus cape", chance = 660}, + {name = "bunch of ripe rice", chance = 960}, + {name = "Zaoan shoes", chance = 450}, + {name = "Zaoan robe", chance = 300}, + {name = "dragon priest's wandtip", chance = 9910} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -50}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -125, maxDamage = -190, range = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREATTACK, target = true}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -320, maxDamage = -400, range = 7, radius = 1, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_HEALING, minDamage = 200, maxDamage = 300, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 45}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/lizard_high_guard.lua b/data/monster/reptiles/lizard_high_guard.lua new file mode 100644 index 00000000000..79aa2649217 --- /dev/null +++ b/data/monster/reptiles/lizard_high_guard.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Lizard High Guard") +local monster = {} + +monster.description = "a lizard high guard" +monster.experience = 1450 +monster.outfit = { + lookType = 337, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 625 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Zzaion, Zao Palace and its antechambers, Muggy Plains, Zao Orc Land (single spawn in fort), \z + Corruption Hole, Razachai, Temple of Equilibrium, Northern Zao Plantations." + } + +monster.health = 1800 +monster.maxHealth = 1800 +monster.race = "blood" +monster.corpse = 11272 +monster.speed = 238 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hizzzzzzz!", yell = false}, + {text = "To armzzzz!", yell = false}, + {text = "Engage zze aggrezzor!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 32000, maxCount = 100}, + {name = "gold coin", chance = 32000, maxCount = 100}, + {name = "gold coin", chance = 32000, maxCount = 27}, + {name = "small emerald", chance = 2520, maxCount = 4}, + {name = "platinum coin", chance = 4900, maxCount = 2}, + {name = "tower shield", chance = 1040}, + {name = "lizard leather", chance = 1000}, + {name = "lizard scale", chance = 970}, + {name = "strong health potion", chance = 11925}, + {name = "great health potion", chance = 7070}, + {name = "red lantern", chance = 1220}, + {name = "bunch of ripe rice", chance = 4950}, + {name = "Zaoan armor", chance = 80}, + {name = "Zaoan shoes", chance = 700}, + {name = "Zaoan legs", chance = 720}, + {name = "spiked iron ball", chance = 7000}, + {name = "high guard flag", chance = 2990}, + {name = "high guard shoulderplates", chance = 8150} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -306} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 25, maxDamage = 75, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 45}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/lizard_legionnaire.lua b/data/monster/reptiles/lizard_legionnaire.lua new file mode 100644 index 00000000000..0e91d352600 --- /dev/null +++ b/data/monster/reptiles/lizard_legionnaire.lua @@ -0,0 +1,127 @@ +local mType = Game.createMonsterType("Lizard Legionnaire") +local monster = {} + +monster.description = "a lizard legionnaire" +monster.experience = 1100 +monster.outfit = { + lookType = 338, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 624 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Zzaion, Zao Palace and its antechambers, Muggy Plains, Zao Orc Land (in fort), \z + Corruption Hole, Razachai, Temple of Equilibrium, Northern Zao Plantations." + } + +monster.health = 1400 +monster.maxHealth = 1400 +monster.race = "blood" +monster.corpse = 11276 +monster.speed = 266 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Tssss!", yell = false} +} + +monster.loot = { + {name = "small diamond", chance = 1001, maxCount = 2}, + {name = "gold coin", chance = 44000, maxCount = 100}, + {name = "gold coin", chance = 54000, maxCount = 65}, + {name = "lizard leather", chance = 970}, + {name = "lizard scale", chance = 980, maxCount = 3}, + {name = "strong health potion", chance = 3880}, + {name = "red lantern", chance = 530}, + {name = "bunch of ripe rice", chance = 1950}, + {name = "Zaoan armor", chance = 70}, + {name = "Zaoan shoes", chance = 460}, + {name = "drakinata", chance = 710}, + {name = "Zaoan halberd", chance = 960}, + {name = "legionnaire flags", chance = 1940}, + {name = "broken halberd", chance = 14940}, + {name = "lizard trophy", chance = 20} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -180}, + {name ="combat", interval = 2000, chance = 40, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -200, range = 7, shootEffect = CONST_ANI_SPEAR, target = true} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 45}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/lizard_magistratus.lua b/data/monster/reptiles/lizard_magistratus.lua new file mode 100644 index 00000000000..8407736cca6 --- /dev/null +++ b/data/monster/reptiles/lizard_magistratus.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Lizard Magistratus") +local monster = {} + +monster.description = "a lizard magistratus" +monster.experience = 2000 +monster.outfit = { + lookType = 115, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 655 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Razzachai." + } + +monster.health = 6250 +monster.maxHealth = 6250 +monster.race = "blood" +monster.corpse = 6041 +monster.speed = 256 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Shhhhhhhh.", yell = false}, + {text = "I can't work wizh zuch dizturbancez!", yell = false} +} + +monster.loot = { + {name = "small ruby", chance = 8970, maxCount = 5}, + {name = "gold coin", chance = 77230, maxCount = 50}, + {name = "platinum coin", chance = 13400, maxCount = 19}, + {name = "lizard leather", chance = 220}, + {name = "lizard scale", chance = 450}, + {name = "strong mana potion", chance = 6280}, + {name = "great mana potion", chance = 4480} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -60}, + {name ="lizard magistratus curse", interval = 2000, chance = 10, range = 5, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/lizard_noble.lua b/data/monster/reptiles/lizard_noble.lua new file mode 100644 index 00000000000..78411f98551 --- /dev/null +++ b/data/monster/reptiles/lizard_noble.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Lizard Noble") +local monster = {} + +monster.description = "a lizard noble" +monster.experience = 2000 +monster.outfit = { + lookType = 115, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 656 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Razzachai." + } + +monster.health = 7000 +monster.maxHealth = 7000 +monster.race = "blood" +monster.corpse = 6041 +monster.speed = 256 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Where are zhe guardz when you need zhem!", yell = false} +} + +monster.loot = { + {name = "small ruby", chance = 7100, maxCount = 5}, + {name = "gold coin", chance = 91300, maxCount = 100}, + {name = "platinum coin", chance = 10000, maxCount = 20}, + {name = "lizard leather", chance = 220}, + {name = "lizard scale", chance = 650}, + {name = "strong health potion", chance = 2550}, + {name = "great health potion", chance = 2900} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -30}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_EARTHDAMAGE, minDamage = -120, maxDamage = -250, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -100, range = 7, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 90}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/lizard_sentinel.lua b/data/monster/reptiles/lizard_sentinel.lua new file mode 100644 index 00000000000..9a08b17ddd5 --- /dev/null +++ b/data/monster/reptiles/lizard_sentinel.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Lizard Sentinel") +local monster = {} + +monster.description = "a lizard sentinel" +monster.experience = 110 +monster.outfit = { + lookType = 114, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 114 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Chor, Zzaion and Foreigner Quarter." + } + +monster.health = 265 +monster.maxHealth = 265 +monster.race = "blood" +monster.corpse = 6040 +monster.speed = 180 +monster.manaCost = 560 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Tssss!", yell = false} +} + +monster.loot = { + {name = "small diamond", chance = 190}, + {name = "gold coin", chance = 89000, maxCount = 80}, + {name = "halberd", chance = 510}, + {name = "spear", chance = 8750, maxCount = 3}, + {name = "obsidian lance", chance = 1120}, + {name = "chain armor", chance = 8560}, + {name = "scale armor", chance = 7730}, + {name = "hunting spear", chance = 4700}, + {name = "sentinel shield", chance = 320}, + {name = "lizard leather", chance = 990}, + {name = "lizard scale", chance = 960}, + {name = "health potion", chance = 590} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -45}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -70, range = 7, shootEffect = CONST_ANI_SPEAR, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/lizard_snakecharmer.lua b/data/monster/reptiles/lizard_snakecharmer.lua new file mode 100644 index 00000000000..a2070a5566c --- /dev/null +++ b/data/monster/reptiles/lizard_snakecharmer.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Lizard Snakecharmer") +local monster = {} + +monster.description = "a lizard snakecharmer" +monster.experience = 210 +monster.outfit = { + lookType = 115, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 115 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Chor." + } + +monster.health = 325 +monster.maxHealth = 325 +monster.race = "blood" +monster.corpse = 6041 +monster.speed = 184 +monster.manaCost = 0 +monster.maxSummons = 6 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 4, + runHealth = 15, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "cobra", chance = 20, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I smeeeel warm blood!", yell = false}, + {text = "Shhhhhhh", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 83740, maxCount = 55}, + {name = "small amethyst", chance = 520}, + {name = "yellow gem", chance = 150}, + {name = "life ring", chance = 340}, + {name = "life crystal", chance = 1430}, + {name = "terra rod", chance = 920}, + {name = "snakebite rod", chance = 230}, + {name = "cape", chance = 8640}, + {name = "charmer's tiara", chance = 230}, + {name = "lizard leather", chance = 1320}, + {name = "lizard scale", chance = 860}, + {name = "mana potion", chance = 860} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -30}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -100, maxDamage = -200, range = 7, shootEffect = CONST_ANI_POISON, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -50, maxDamage = -110, range = 7, radius = 1, shootEffect = CONST_ANI_POISON, effect = CONST_ME_GREEN_RINGS, target = true} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_HEALING, minDamage = 50, maxDamage = 100, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -20}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/lizard_templar.lua b/data/monster/reptiles/lizard_templar.lua new file mode 100644 index 00000000000..e8be1eec52a --- /dev/null +++ b/data/monster/reptiles/lizard_templar.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Lizard Templar") +local monster = {} + +monster.description = "a lizard templar" +monster.experience = 155 +monster.outfit = { + lookType = 113, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 113 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Chor, the lizard city south-east from Port Hope. They can also be found in Yalahar's \z + Foreigner Quarter and in Zzaion." + } + +monster.health = 410 +monster.maxHealth = 410 +monster.race = "blood" +monster.corpse = 4251 +monster.speed = 174 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hissss!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 84000, maxCount = 60}, + {name = "small emerald", chance = 250}, + {id = 2376, chance = 4000}, + {name = "morning star", chance = 1990}, + {name = "short sword", chance = 9500}, + {name = "steel helmet", chance = 2000}, + {name = "plate armor", chance = 1000}, + {name = "templar scytheblade", chance = 500}, + {name = "salamander shield", chance = 110}, + {name = "lizard leather", chance = 880}, + {name = "lizard scale", chance = 990}, + {name = "health potion", chance = 890} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -70} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/lizard_zaogun.lua b/data/monster/reptiles/lizard_zaogun.lua new file mode 100644 index 00000000000..6324b4b6dba --- /dev/null +++ b/data/monster/reptiles/lizard_zaogun.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Lizard Zaogun") +local monster = {} + +monster.description = "a lizard zaogun" +monster.experience = 1700 +monster.outfit = { + lookType = 343, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 616 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Zzaion, Zao Palace, Muggy Plains, Zao Orc Land (in fort), Razzachai, Temple of Equilibrium." + } + +monster.health = 2955 +monster.maxHealth = 2955 +monster.race = "blood" +monster.corpse = 11284 +monster.speed = 276 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Hissss!", yell = false}, + {text = "Cowardzz!", yell = false}, + {text = "Softzzkinzz from zze zzouzz!", yell = false}, + {text = "Zztand and fight!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 31500, maxCount = 100}, + {name = "gold coin", chance = 31500, maxCount = 100}, + {name = "gold coin", chance = 31000, maxCount = 68}, + {name = "small emerald", chance = 4830, maxCount = 5}, + {name = "platinum coin", chance = 48900, maxCount = 2}, + {name = "tower shield", chance = 1000}, + {name = "lizard leather", chance = 14360}, + {name = "lizard scale", chance = 12520}, + {name = "strong health potion", chance = 1900}, + {name = "great health potion", chance = 7000, maxCount = 3}, + {name = "red lantern", chance = 2170}, + {name = "Zaoan armor", chance = 530}, + {name = "Zaoan shoes", chance = 1000}, + {name = "Zaoan legs", chance = 1001}, + {name = "zaogun flag", chance = 8280}, + {name = "zaogun shoulderplates", chance = 14980} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -349}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -220, maxDamage = -375, range = 7, radius = 1, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 175, maxDamage = 275, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 45}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/sea_serpent.lua b/data/monster/reptiles/sea_serpent.lua new file mode 100644 index 00000000000..0c1d52752f9 --- /dev/null +++ b/data/monster/reptiles/sea_serpent.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Sea Serpent") +local monster = {} + +monster.description = "a sea serpent" +monster.experience = 2300 +monster.outfit = { + lookType = 275, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 438 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Sea Serpent Area and Seacrest Grounds." + } + +monster.health = 1950 +monster.maxHealth = 1950 +monster.race = "blood" +monster.corpse = 8307 +monster.speed = 480 +monster.manaCost = 390 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "CHHHRRRR", yell = false}, + {text = "HISSSS", yell = false} +} + +monster.loot = { + {name = "small sapphire", chance = 5600, maxCount = 3}, + {name = "gold coin", chance = 38000, maxCount = 100}, + {name = "gold coin", chance = 30000, maxCount = 100}, + {name = "gold coin", chance = 30000, maxCount = 36}, + {name = "platinum coin", chance = 25000, maxCount = 3}, + {name = "stealth ring", chance = 400}, + {name = "ring of healing", chance = 1100}, + {name = "serpent sword", chance = 4200}, + {name = "plate legs", chance = 7150}, + {name = "dragon ham", chance = 60000, maxCount = 2}, + {name = "strong health potion", chance = 5500}, + {name = "strong mana potion", chance = 3850}, + {name = "great mana potion", chance = 920}, + {name = "glacier amulet", chance = 880}, + {name = "glacier kilt", chance = 430}, + {name = "spirit cloak", chance = 2900}, + {name = "focus cape", chance = 370}, + {name = "crystalline armor", chance = 90}, + {name = "northwind rod", chance = 930}, + {name = "sea serpent scale", chance = 10200} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -60, maxDamage = -300, length = 7, spread = 2, effect = CONST_ME_SMALLPLANTS, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -101, maxDamage = -300, length = 7, spread = 2, effect = CONST_ME_ICEATTACK, target = false}, + {name ="sea serpent drown", interval = 2000, chance = 15, range = 5, target = false} +} + +monster.defenses = { + defense = 45, + armor = 45, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_HEALING, minDamage = 70, maxDamage = 273, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 400, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -15}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/seacrest_serpent.lua b/data/monster/reptiles/seacrest_serpent.lua new file mode 100644 index 00000000000..eb429aef1be --- /dev/null +++ b/data/monster/reptiles/seacrest_serpent.lua @@ -0,0 +1,140 @@ +local mType = Game.createMonsterType("Seacrest Serpent") +local monster = {} + +monster.description = "a seacrest serpent" +monster.experience = 2600 +monster.outfit = { + lookType = 675, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1096 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 2, + Locations = "Seacrest Grounds." + } + +monster.health = 3000 +monster.maxHealth = 3000 +monster.race = "venom" +monster.corpse = 24262 +monster.speed = 500 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 9 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "LEAVE THESE GROUNDS...", yell = false}, + {text = "THE DARK TIDE WILL SWALLOW YOU...", yell = false} +} + +monster.loot = { + {id = 2672, chance = 13040}, + {id = 24170, chance = 12040}, + {id = 7839, chance = 7020, maxCount = 17}, + {id = 7902, chance = 2680}, + {id = 24261, chance = 400}, + {id = 2152, chance = 100000, maxCount = 5}, + {id = 7588, chance = 7020, maxCount = 2}, + {id = 7589, chance = 10370, maxCount = 2}, + {id = 24116, chance = 10030}, + {id = 2143, chance = 3680, maxCount = 2}, + {id = 2144, chance = 2340, maxCount = 3}, + {id = 7632, chance = 1000}, + {id = 5944, chance = 3340}, + {id = 2145, chance = 5020, maxCount = 3}, + {id = 24169, chance = 17390}, + {id = 7888, chance = 670}, + {id = 7896, chance = 3680}, + {id = 7892, chance = 3010}, + {id = 18390, chance = 670}, + {id = 8921, chance = 670} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 120, attack = 82}, + {name ="combat", interval = 2000, chance = 7, type = COMBAT_DEATHDAMAGE, minDamage = -200, maxDamage = -260, range = 7, shootEffect = CONST_ANI_EARTH, effect = CONST_ME_SOUND_RED, target = true}, + {name ="combat", interval = 2000, chance = 11, type = COMBAT_LIFEDRAIN, minDamage = -200, maxDamage = -285, radius = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="seacrest serpent wave", interval = 2000, chance = 30, minDamage = 0, maxDamage = -284, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -300, length = 4, spread = 3, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.defenses = { + defense = 31, + armor = 22, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 145, maxDamage = 200, effect = CONST_ME_SOUND_BLUE, target = false}, + {name ="melee", interval = 2000, chance = 10, minDamage = 0, maxDamage = 0} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 15}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/serpent_spawn.lua b/data/monster/reptiles/serpent_spawn.lua new file mode 100644 index 00000000000..f52408971bd --- /dev/null +++ b/data/monster/reptiles/serpent_spawn.lua @@ -0,0 +1,146 @@ +local mType = Game.createMonsterType("Serpent Spawn") +local monster = {} + +monster.description = "a serpent spawn" +monster.experience = 3050 +monster.outfit = { + lookType = 220, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 220 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Deeper Banuta, Forbidden Islands: Talahu (Medusa Cave) and Kharos (at level -1), Razzachai, \z + Deep below the Crystal Lakes in Foreigner Quarter, Cult's cave in the Magician Quarter, Medusa Tower." + } + +monster.health = 3000 +monster.maxHealth = 3000 +monster.race = "venom" +monster.corpse = 6061 +monster.speed = 234 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 30, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 275, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Sssssouls for the one", yell = false}, + {text = "HISSSS", yell = true}, + {text = "Tsssse one will risssse again", yell = false}, + {text = "I bring you deathhhh, mortalssss", yell = false} +} + +monster.loot = { + {name = "golden mug", chance = 2870}, + {name = "small sapphire", chance = 12000}, + {name = "gold coin", chance = 32300, maxCount = 100}, + {name = "gold coin", chance = 32300, maxCount = 100}, + {name = "gold coin", chance = 32300, maxCount = 39}, + {name = "energy ring", chance = 590}, + {name = "life ring", chance = 6250}, + {name = "life crystal", chance = 800}, + {name = "snakebite rod", chance = 930}, + {name = "warrior helmet", chance = 560}, + {name = "strange helmet", chance = 670}, + {name = "crown armor", chance = 510}, + {name = "royal helmet", chance = 140}, + {name = "tower shield", chance = 920}, + {name = "power bolt", chance = 6200}, + {name = "green mushroom", chance = 18200}, + {name = "charmer's tiara", chance = 180}, + {name = "mercenary sword", chance = 2070}, + {name = "noble axe", chance = 750}, + {name = "great mana potion", chance = 2000}, + {name = "swamplair armor", chance = 90}, + {name = "spellbook of mind control", chance = 90}, + {name = "snake skin", chance = 14800}, + {name = "winged tail", chance = 960} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -252}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -80, maxDamage = -300, range = 7, shootEffect = CONST_ANI_POISON, target = false}, + {name ="outfit", interval = 2000, chance = 1, range = 7, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 3000, outfitItem = 3976}, + {name ="speed", interval = 2000, chance = 25, speedChange = -850, range = 7, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_GREEN_RINGS, target = true, duration = 12000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -200, maxDamage = -500, length = 8, spread = 3, effect = CONST_ME_SOUND_RED, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -200, maxDamage = -500, length = 8, spread = 3, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 250, maxDamage = 500, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 340, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/snake.lua b/data/monster/reptiles/snake.lua new file mode 100644 index 00000000000..20f70c46d43 --- /dev/null +++ b/data/monster/reptiles/snake.lua @@ -0,0 +1,110 @@ +local mType = Game.createMonsterType("Snake") +local monster = {} + +monster.description = "a snake" +monster.experience = 10 +monster.outfit = { + lookType = 28, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 28 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "In almost all grassy areas of Tibia. Also found in Rookgaard." + } + +monster.health = 15 +monster.maxHealth = 15 +monster.race = "blood" +monster.corpse = 2817 +monster.speed = 120 +monster.manaCost = 205 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Zzzzzzt", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -8, condition = {type = CONDITION_POISON, totalDamage = 15, interval = 4000}} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 5}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/stampor.lua b/data/monster/reptiles/stampor.lua new file mode 100644 index 00000000000..867cf64c66d --- /dev/null +++ b/data/monster/reptiles/stampor.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Stampor") +local monster = {} + +monster.description = "a stampor" +monster.experience = 780 +monster.outfit = { + lookType = 381, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 694 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Stampor Cave on the Muggy Plains, Chyllfroest." + } + +monster.health = 1200 +monster.maxHealth = 1200 +monster.race = "blood" +monster.corpse = 13312 +monster.speed = 440 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "KRRRRRNG", yell = true} +} + +monster.loot = { + {name = "gold coin", chance = 30000, maxCount = 242}, + {name = "platinum coin", chance = 9920, maxCount = 2}, + {name = "war hammer", chance = 1010}, + {name = "knight armor", chance = 870}, + {name = "spiked squelcher", chance = 160}, + {name = "strong health potion", chance = 5000, maxCount = 2}, + {name = "strong mana potion", chance = 5000, maxCount = 2}, + {name = "small topaz", chance = 7940, maxCount = 2}, + {name = "stampor horn", chance = 4920}, + {name = "stampor talons", chance = 9950, maxCount = 2}, + {name = "hollow stampor hoof", chance = 3020} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -130}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -150, maxDamage = -280, radius = 3, effect = CONST_ME_GROUNDSHAKER, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -75, maxDamage = -100, shootEffect = CONST_ANI_SMALLSTONE, target = true}, + {name ="stampor skill reducer", interval = 2000, chance = 10, range = 5, target = false} +} + +monster.defenses = { + defense = 0, + armor = 0, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 90, maxDamage = 120, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 50}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/stonerefiner.lua b/data/monster/reptiles/stonerefiner.lua new file mode 100644 index 00000000000..8d403c4d25c --- /dev/null +++ b/data/monster/reptiles/stonerefiner.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Stonerefiner") +local monster = {} + +monster.description = "a Stonerefiner" +monster.experience = 500 +monster.outfit = { + lookType = 1032, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1525 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Corym Mines." + } + +monster.health = 800 +monster.maxHealth = 800 +monster.race = "blood" +monster.corpse = 30771 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "knak knak knak", yell = false}, + {text = "nomnomnom", yell = false} +} + +monster.loot = { + {name = "platinum coin", chance = 50930, maxCount = 4}, + {name = "rare earth", chance = 39750, maxCount = 2}, + {id = 13757, chance = 27980, maxCount = 5}, + {name = "glob of acid slime", chance = 23680}, + {name = "stonerefiner's skull", chance = 20110}, + {name = "poisonous slime", chance = 20040, maxCount = 3}, + {name = "half-digested stones", chance = 15210, maxCount = 5} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="berserk", interval = 2000, chance = 15, minDamage = 0, maxDamage = -70, target = false}, + {name ="stone shower", interval = 2000, chance = 10, minDamage = -40, maxDamage = -80, range = 7, target = false} +} + +monster.defenses = { + defense = 45, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 1}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 90}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/thornback_tortoise.lua b/data/monster/reptiles/thornback_tortoise.lua new file mode 100644 index 00000000000..876bd8482ab --- /dev/null +++ b/data/monster/reptiles/thornback_tortoise.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Thornback Tortoise") +local monster = {} + +monster.description = "a thornback tortoise" +monster.experience = 150 +monster.outfit = { + lookType = 198, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 259 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Laguna Islands and one on Nargor." + } + +monster.health = 300 +monster.maxHealth = 300 +monster.race = "blood" +monster.corpse = 6073 +monster.speed = 200 +monster.manaCost = 490 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "white pearl", chance = 1600}, + {name = "black pearl", chance = 800}, + {name = "gold coin", chance = 89500, maxCount = 48}, + {name = "war hammer", chance = 260}, + {id = 2667, chance = 10800, maxCount = 2}, + {name = "white mushroom", chance = 1200}, + {name = "brown mushroom", chance = 700}, + {name = "tortoise egg", chance = 790, maxCount = 3}, + {name = "turtle shell", chance = 800}, + {name = "health potion", chance = 1600}, + {name = "thorn", chance = 15980} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -110, condition = {type = CONDITION_POISON, totalDamage = 40, interval = 4000}} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 45}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/tortoise.lua b/data/monster/reptiles/tortoise.lua new file mode 100644 index 00000000000..fc8c8d9994d --- /dev/null +++ b/data/monster/reptiles/tortoise.lua @@ -0,0 +1,117 @@ +local mType = Game.createMonsterType("Tortoise") +local monster = {} + +monster.description = "a tortoise" +monster.experience = 90 +monster.outfit = { + lookType = 197, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 258 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Laguna Islands, Fenrock, Port Hope and also can be found behind a wall below the \z + center of Liberty Bay. These cannot be reached." + } + +monster.health = 185 +monster.maxHealth = 185 +monster.race = "blood" +monster.corpse = 6072 +monster.speed = 200 +monster.manaCost = 445 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 59000, maxCount = 30}, + {name = "battle hammer", chance = 730}, + {name = "plate shield", chance = 2850}, + {id = 2667, chance = 4600}, + {name = "tortoise egg", chance = 770, maxCount = 2}, + {name = "turtle shell", chance = 1300}, + {name = "tortoise shield", chance = 200} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -50} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 35}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/wyvern.lua b/data/monster/reptiles/wyvern.lua new file mode 100644 index 00000000000..638c1466bc1 --- /dev/null +++ b/data/monster/reptiles/wyvern.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Wyvern") +local monster = {} + +monster.description = "a wyvern" +monster.experience = 515 +monster.outfit = { + lookType = 239, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 290 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Beregar, Black Knight's Villa, Chor, Ghostlands, Chyllfroest, Crystal Gardens, \z + Crystal Grounds, Dragon Lair (Edron), Drillworm Cave, Folda, Hero Fortress, Kazordoon, \z + Green Djinn Tower, Mushroom Fields,Paradox Tower, Plains of Havoc, Plague Spike, \z + Poachers' Camp (Ferngrims Gate), Stonehome, Tiquanda, Truffels Garden, \z + Vandura Mountain, Vega, Venore, Wyvern Cave (Ferngrims Gate), Wyvern Hill and Wyvern Ulderek's Rock Cave." + } + +monster.health = 795 +monster.maxHealth = 795 +monster.race = "blood" +monster.corpse = 6302 +monster.speed = 186 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Shriiiek", yell = true} +} + +monster.loot = { + {name = "emerald bangle", chance = 540}, + {name = "small sapphire", chance = 5000}, + {name = "gold coin", chance = 100000, maxCount = 90}, + {name = "wand of inferno", chance = 810}, + {name = "power bolt", chance = 3400, maxCount = 2}, + {name = "dragon ham", chance = 60500, maxCount = 3}, + {name = "wyvern fang", chance = 410}, + {name = "strong health potion", chance = 2500}, + {name = "wyvern talisman", chance = 12300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -120, condition = {type = CONDITION_POISON, totalDamage = 480, interval = 4000}}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -240, maxDamage = -240, length = 8, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="drunk", interval = 2000, chance = 10, length = 3, spread = 2, effect = CONST_ME_SOUND_RED, target = false, duration = 5000} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 45, maxDamage = 65, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 300, effect = CONST_ME_MAGIC_GREEN, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/young_goanna.lua b/data/monster/reptiles/young_goanna.lua new file mode 100644 index 00000000000..6f5c9c4e4cb --- /dev/null +++ b/data/monster/reptiles/young_goanna.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Young Goanna") +local monster = {} + +monster.description = "a young goanna" +monster.experience = 6100 +monster.outfit = { + lookType = 1196, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1817 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Kilmaresh Central Steppe, Kilmaresh Southern Steppe, Green Belt." + } + +monster.health = 6200 +monster.maxHealth = 6200 +monster.race = "blood" +monster.corpse = 36244 +monster.speed = 380 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 10, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 100000, maxCount = 3}, + {name = "Envenomed Arrow", chance = 68000, maxCount = 35}, + {name = "Terra Rod", chance = 10900}, + {name = "Goanna Meat", chance = 9800}, + {name = "Snakebite Rod", chance = 9000}, + {name = "Blue Goanna Scale", chance = 7900}, + {name = "Goanna Claw", chance = 4300}, + {name = "Serpent Sword", chance = 4000}, + {name = "Leaf Star", chance = 3800, maxCount = 3}, + {name = "Silver Amulet", chance = 3800}, + {name = "Springsprout Rod", chance = 2700}, + {name = "Scared Frog", chance = 2100}, + {name = "Terra Amulet", chance = 1100}, + {name = "Lizard Heart", chance = 800}, + {name = "Sacred Tree Amulet", chance = 800}, + {name = "Small Tortoise", chance = 550}, + {name = "Fur Armor", chance = 270}, + {name = "Terra Hood", chance = 250} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -230, condition = {type = CONDITION_POISON, totalDamage = 15, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -490, range = 3, radius = 1, shootEffect = CONST_ANI_EARTH, effect = CONST_ME_EXPLOSIONHIT, target = true} +} + +monster.defenses = { + defense = 78, + armor = 78, + {name ="speed", interval = 2000, chance = 5, speedChange = 350, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -20}, + {type = COMBAT_EARTHDAMAGE, percent = 80}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/reptiles/young_sea_serpent.lua b/data/monster/reptiles/young_sea_serpent.lua new file mode 100644 index 00000000000..52dca48b20c --- /dev/null +++ b/data/monster/reptiles/young_sea_serpent.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Young Sea Serpent") +local monster = {} + +monster.description = "a young sea serpent" +monster.experience = 1000 +monster.outfit = { + lookType = 317, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 439 +monster.Bestiary = { + class = "Reptile", + race = BESTY_RACE_REPTILE, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Sea Serpent Area." + } + +monster.health = 1050 +monster.maxHealth = 1050 +monster.race = "blood" +monster.corpse = 9879 +monster.speed = 480 +monster.manaCost = 390 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 400, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "CHHHRRRR", yell = false}, + {text = "HISSSS", yell = false} +} + +monster.loot = { + {name = "small sapphire", chance = 1900, maxCount = 2}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 48000, maxCount = 74}, + {name = "stealth ring", chance = 1000}, + {name = "life crystal", chance = 300}, + {name = "battle axe", chance = 8000}, + {name = "morning star", chance = 40000}, + {name = "battle hammer", chance = 5000}, + {name = "strong health potion", chance = 5000}, + {name = "strong mana potion", chance = 4000}, + {id = 9808, chance = 7940}, + {id = 9809, chance = 7940}, + {name = "sea serpent scale", chance = 5000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -10, maxDamage = -250, length = 7, spread = 2, effect = CONST_ME_SMALLPLANTS, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -80, maxDamage = -250, length = 7, spread = 2, effect = CONST_ME_ICEATTACK, target = false}, + {name ="young sea serpent drown", interval = 2000, chance = 15, range = 5, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_HEALING, minDamage = 25, maxDamage = 175, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 400, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -15}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/slimes/acid_blob.lua b/data/monster/slimes/acid_blob.lua new file mode 100644 index 00000000000..f958ed37eef --- /dev/null +++ b/data/monster/slimes/acid_blob.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Acid Blob") +local monster = {} + +monster.description = "an acid blob" +monster.experience = 250 +monster.outfit = { + lookType = 314, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 513 +monster.Bestiary = { + class = "Slime", + race = BESTY_RACE_SLIME, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Alchemist Quarter, Deeper Banuta." + } + +monster.health = 250 +monster.maxHealth = 250 +monster.race = "venom" +monster.corpse = 9962 +monster.speed = 120 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Acid Blob", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Kzzchhhh", yell = false} +} + +monster.loot = { + {name = "glob of acid slime", chance = 18520} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -80}, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_EARTHDAMAGE, minDamage = -10, maxDamage = -20, radius = 4, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -40, maxDamage = -60, length = 5, spread = 3, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, range = 7, shootEffect = CONST_ANI_POISON, target = true} +} + +monster.defenses = { + defense = 1, + armor = 1 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/slimes/death_blob.lua b/data/monster/slimes/death_blob.lua new file mode 100644 index 00000000000..de80b3f1e9d --- /dev/null +++ b/data/monster/slimes/death_blob.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Death Blob") +local monster = {} + +monster.description = "a death blob" +monster.experience = 300 +monster.outfit = { + lookType = 315, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 514 +monster.Bestiary = { + class = "Slime", + race = BESTY_RACE_SLIME, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Alchemist Quarter, Drefia, Razzachai, Souleater Mountains, \z + Northern Zao Plantations and Raging Mage tower." + } + +monster.health = 320 +monster.maxHealth = 320 +monster.race = "undead" +monster.corpse = 9960 +monster.speed = 160 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Death Blob", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Shlorz", yell = false} +} + +monster.loot = { + {name = "glob of tar", chance = 18470} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = -35, maxDamage = -60, range = 3, radius = 4, effect = CONST_ME_POFF, target = false}, + {name ="death blob curse", interval = 2000, chance = 5, range = 5, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 20, maxDamage = 30, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/slimes/defiler.lua b/data/monster/slimes/defiler.lua new file mode 100644 index 00000000000..cb3f7d1f839 --- /dev/null +++ b/data/monster/slimes/defiler.lua @@ -0,0 +1,139 @@ +local mType = Game.createMonsterType("Defiler") +local monster = {} + +monster.description = "a defiler" +monster.experience = 3700 +monster.outfit = { + lookType = 238, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 289 +monster.Bestiary = { + class = "Slime", + race = BESTY_RACE_SLIME, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Pits of Inferno, The Vats - Edron." + } + +monster.health = 3650 +monster.maxHealth = 3650 +monster.race = "venom" +monster.corpse = 6532 +monster.speed = 160 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 85, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Blubb", yell = false}, + {text = "Blubb Blubb", yell = false} +} + +monster.loot = { + {name = "small diamond", chance = 2439, maxCount = 2}, + {name = "small ruby", chance = 3000, maxCount = 2}, + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "gold coin", chance = 100000, maxCount = 72}, + {name = "small emerald", chance = 5366, maxCount = 3}, + {name = "talon", chance = 5710}, + {name = "platinum coin", chance = 95000, maxCount = 6}, + {name = "yellow gem", chance = 1219}, + {name = "green gem", chance = 613}, + {name = "red gem", chance = 1538}, + {name = "blue gem", chance = 300}, + {name = "soul orb", chance = 20000}, + {id = 6300, chance = 3030}, + {name = "demonic essence", chance = 20320}, + {name = "glob of acid slime", chance = 14210}, + {name = "glob of tar", chance = 12000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -240, condition = {type = CONDITION_POISON, totalDamage = 150, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -160, maxDamage = -270, range = 7, shootEffect = CONST_ANI_POISON, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -400, maxDamage = -640, range = 7, radius = 7, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -120, maxDamage = -170, radius = 3, effect = CONST_ME_POISONAREA, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -500, maxDamage = -1000, length = 8, spread = 3, effect = CONST_ME_SMALLPLANTS, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -700, length = 8, spread = 3, effect = CONST_ME_SMALLCLOUDS, target = false, duration = 15000} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 280, maxDamage = 350, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -25}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/slimes/devourer.lua b/data/monster/slimes/devourer.lua new file mode 100644 index 00000000000..a6dbccabca9 --- /dev/null +++ b/data/monster/slimes/devourer.lua @@ -0,0 +1,143 @@ +local mType = Game.createMonsterType("Devourer") +local monster = {} + +monster.description = "a devourer" +monster.experience = 1755 +monster.outfit = { + lookType = 617, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1056 +monster.Bestiary = { + class = "Slime", + race = BESTY_RACE_SLIME, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Rathleton Sewers, Lower Rathleton, Oramond/Western Plains, \z + Underground Glooth Factory, Jaccus Maxxen's Dungeon." + } + +monster.health = 1900 +monster.maxHealth = 1900 +monster.race = "venom" +monster.corpse = 23484 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "*gulp*", yell = false}, + {text = "*Bruaarrr!*", yell = false}, + {text = "*omnnommm nomm*", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 165}, + {id = 2152, chance = 9100, maxCount = 2}, + {id = 23553, chance = 1670}, + {id = 2151, chance = 940}, + {id = 2146, chance = 1170, maxCount = 3}, + {id = 2150, chance = 1030, maxCount = 3}, + {id = 9970, chance = 1030, maxCount = 3}, + {id = 2149, chance = 1170, maxCount = 3}, + {id = 2147, chance = 1190, maxCount = 3}, + {id = 2145, chance = 1050, maxCount = 3}, + {id = 2154, chance = 1090}, + {id = 2155, chance = 100}, + {id = 23535, chance = 210}, + {id = 23554, chance = 130}, + {id = 23550, chance = 350}, + {id = 23549, chance = 510}, + {id = 23551, chance = 390}, + {id = 23529, chance = 370}, + {id = 8912, chance = 250}, + {id = 2181, chance = 260} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 62, attack = 50, condition = {type = CONDITION_POISON, totalDamage = 360, interval = 4000}}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -40, maxDamage = -125, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="combat", interval = 2000, chance = 8, type = COMBAT_EARTHDAMAGE, minDamage = -50, maxDamage = -160, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_GREEN_RINGS, target = true}, + {name ="devourer wave", interval = 2000, chance = 5, minDamage = -50, maxDamage = -150, target = false}, + {name ="devourer paralyze", interval = 2000, chance = 9, target = false}, + {name ="combat", interval = 2000, chance = 11, type = COMBAT_EARTHDAMAGE, minDamage = -50, maxDamage = -150, length = 1, spread = 0, effect = CONST_ME_SMOKE, target = false}, + {name ="combat", interval = 2000, chance = 7, type = COMBAT_EARTHDAMAGE, minDamage = -120, maxDamage = -135, radius = 4, effect = CONST_ME_GREEN_RINGS, target = false} +} + +monster.defenses = { + defense = 25, + armor = 15, + {name ="combat", interval = 2000, chance = 6, type = COMBAT_HEALING, minDamage = 100, maxDamage = 150, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/slimes/glooth_blob.lua b/data/monster/slimes/glooth_blob.lua new file mode 100644 index 00000000000..3bcf6edb089 --- /dev/null +++ b/data/monster/slimes/glooth_blob.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Glooth Blob") +local monster = {} + +monster.description = "a glooth blob" +monster.experience = 700 +monster.outfit = { + lookType = 614, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1054 +monster.Bestiary = { + class = "Slime", + race = BESTY_RACE_SLIME, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Oramond/Western Plains, Lower Rathleton, Glooth Factory, Underground Glooth Factory, Rathleton Sewers." + } + +monster.health = 750 +monster.maxHealth = 750 +monster.race = "venom" +monster.corpse = 23479 +monster.speed = 160 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Glooth Blob", chance = 6, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 70}, + {id = 23553, chance = 15410}, + {id = 2146, chance = 3310, maxCount = 2}, + {id = 9970, chance = 3420, maxCount = 2}, + {id = 23554, chance = 400}, + {id = 23550, chance = 510}, + {id = 23549, chance = 580}, + {id = 23551, chance = 560} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 45, attack = 40, condition = {type = CONDITION_POISON, totalDamage = 280, interval = 4000}}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 13, minDamage = -400, maxDamage = -480, radius = 4, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 11, type = COMBAT_EARTHDAMAGE, minDamage = -85, maxDamage = -180, radius = 3, shootEffect = CONST_ANI_ENVENOMEDARROW, effect = CONST_ME_GREEN_RINGS, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -60, maxDamage = -105, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/slimes/ink_blob.lua b/data/monster/slimes/ink_blob.lua new file mode 100644 index 00000000000..27c65f1a98d --- /dev/null +++ b/data/monster/slimes/ink_blob.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Ink Blob") +local monster = {} + +monster.description = "an ink blob" +monster.experience = 14450 +monster.outfit = { + lookType = 1064, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1658 +monster.Bestiary = { + class = "Slime", + race = BESTY_RACE_SLIME, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Secret Library." + } + +monster.health = 9500 +monster.maxHealth = 9500 +monster.race = "undead" +monster.corpse = 33345 +monster.speed = 380 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 120000, maxCount = 4}, + {name = "Envenomed Arrow", chance = 1200, maxCount = 14}, + {id = 33315, chance = 1200, maxCount = 4}, + {name = "Poisonous Slime", chance = 1200, maxCount = 4}, + {name = "Small Diamond", chance = 1200, maxCount = 4}, + {name = "Small Topaz", chance = 1200, maxCount = 4}, + {id = 7633, chance = 900, maxCount = 4}, + {name = "Blue Gem", chance = 950, maxCount = 4}, + {name = "Terra Boots", chance = 850, maxCount = 4}, + {name = "Terra Hood", chance = 980, maxCount = 4}, + {name = "Protection Amulet", chance = 1200, maxCount = 4}, + {name = "Sacred Tree Amulet", chance = 1200, maxCount = 4}, + {name = "Springsprout Rod", chance = 790, maxCount = 4}, + {name = "Stone Skin Amulet", chance = 1200, maxCount = 4}, + {name = "Terra Legs", chance = 650, maxCount = 4}, + {name = "Terra Mantle", chance = 550, maxCount = 4}, + {name = "Clay Lump", chance = 1200, maxCount = 4}, + {name = "Terra Amulet", chance = 1200, maxCount = 4} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 45, attack = 40, condition = {type = CONDITION_POISON, totalDamage = 280, interval = 4000}}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 13, minDamage = -400, maxDamage = -580, radius = 4, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 11, type = COMBAT_EARTHDAMAGE, minDamage = -285, maxDamage = -480, radius = 3, shootEffect = CONST_ANI_ENVENOMEDARROW, effect = CONST_ME_GREEN_RINGS, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -260, maxDamage = -505, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 20, maxDamage = 30, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/slimes/mercury_blob.lua b/data/monster/slimes/mercury_blob.lua new file mode 100644 index 00000000000..9ceeb67af35 --- /dev/null +++ b/data/monster/slimes/mercury_blob.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Mercury Blob") +local monster = {} + +monster.description = "a mercury blob" +monster.experience = 180 +monster.outfit = { + lookType = 316, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 515 +monster.Bestiary = { + class = "Slime", + race = BESTY_RACE_SLIME, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Alchemist Quarter." + } + +monster.health = 150 +monster.maxHealth = 150 +monster.race = "undead" +monster.corpse = 9961 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Mercury Blob", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Crackle", yell = false} +} + +monster.loot = { + {name = "glob of mercury", chance = 18750} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -75}, + {name ="drunk", interval = 2000, chance = 10, range = 7, shootEffect = CONST_ANI_HOLY, effect = CONST_ME_STUN, target = true, duration = 3000}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -10, maxDamage = -30, range = 7, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYHIT, target = true} +} + +monster.defenses = { + defense = 1, + armor = 1, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 20, maxDamage = 30, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 65}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 80}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 15}, + {type = COMBAT_HOLYDAMAGE , percent = 65}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/slimes/midnight_spawn.lua b/data/monster/slimes/midnight_spawn.lua new file mode 100644 index 00000000000..5ae05c6f79f --- /dev/null +++ b/data/monster/slimes/midnight_spawn.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Midnight Spawn") +local monster = {} + +monster.description = "a midnight spawn" +monster.experience = 900 +monster.outfit = { + lookType = 315, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 584 +monster.Bestiary = { + class = "Slime", + race = BESTY_RACE_SLIME, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 50, + Stars = 3, + Occurrence = 3, + Locations = "Forbidden Lands." + } + +monster.health = 2000 +monster.maxHealth = 2000 +monster.race = "undead" +monster.corpse = 9960 +monster.speed = 340 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 85, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "midnight shard", chance = 8333} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 99}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 99}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 99} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/slimes/slime.lua b/data/monster/slimes/slime.lua new file mode 100644 index 00000000000..94f1c76fc2a --- /dev/null +++ b/data/monster/slimes/slime.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("Slime") +local monster = {} + +monster.description = "a slime" +monster.experience = 160 +monster.outfit = { + lookType = 19, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 19 +monster.Bestiary = { + class = "Slime", + race = BESTY_RACE_SLIME, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Ancient Temple under the Rotworm area, under White Flower Temple, \z + Mount Sternum Undead Cave on the last floor, Thais Troll Cave, Bonelord cave in Drefia, \z + Green Claw Swamp, Dwarf Mines, Villa Scapula, Ankrahmun Tombs, Dark Cathedral, north of Port Hope, \z + Deeper Banuta, on Folda on the floor above the Water Elementals, Hellgate, Vengoth, Alchemist Quarter, \z + Yalahar and Carlin sewers, Ghostlands, Desert Dungeon, Dusalk's Troll Clan Cave, Nargor, \z + and in a cave northeast of Ab'Dendriel." + } + +monster.health = 150 +monster.maxHealth = 150 +monster.race = "venom" +monster.corpse = 8062 +monster.speed = 120 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Slime", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Blubb", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -110} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/slimes/son_of_verminor.lua b/data/monster/slimes/son_of_verminor.lua new file mode 100644 index 00000000000..f6c0c1f10d9 --- /dev/null +++ b/data/monster/slimes/son_of_verminor.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Son of Verminor") +local monster = {} + +monster.description = "a son of verminor" +monster.experience = 5900 +monster.outfit = { + lookType = 19, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 265 +monster.Bestiary = { + class = "Slime", + race = BESTY_RACE_SLIME, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Deep in the Pits of Inferno, in Verminor's throne room. Also in the Demon Forge (The Vats and The Hive)." + } + +monster.health = 8500 +monster.maxHealth = 8500 +monster.race = "venom" +monster.corpse = 1490 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Blubb.", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -473, condition = {type = CONDITION_POISON, totalDamage = 450, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -150, maxDamage = -200, range = 7, shootEffect = CONST_ANI_POISON, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -350, maxDamage = -390, radius = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -220, maxDamage = -270, radius = 3, effect = CONST_ME_SMALLCLOUDS, target = false} +} + +monster.defenses = { + defense = 0, + armor = 48, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 250, maxDamage = 350, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="outfit", interval = 5000, chance = 10, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 6000, outfitMonster = "rat"}, + {name ="outfit", interval = 5000, chance = 10, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 6000, outfitMonster = "larva"}, + {name ="outfit", interval = 5000, chance = 10, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 6000, outfitMonster = "scorpion"}, + {name ="outfit", interval = 5000, chance = 10, effect = CONST_ME_MAGIC_BLUE, target = false, duration = 6000, outfitMonster = "slime"} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/slimes/squidgy_slime.lua b/data/monster/slimes/squidgy_slime.lua new file mode 100644 index 00000000000..06276ad6f48 --- /dev/null +++ b/data/monster/slimes/squidgy_slime.lua @@ -0,0 +1,117 @@ +local mType = Game.createMonsterType("Squidgy Slime") +local monster = {} + +monster.description = "a slime" +monster.experience = 55 +monster.outfit = { + lookType = 19, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 20 +monster.Bestiary = { + class = "Slime", + race = BESTY_RACE_SLIME, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 50, + CharmsPoints = 15, + Stars = 2, + Occurrence = 2, + Locations = "Horestis Tomb." + } + +monster.health = 150 +monster.maxHealth = 150 +monster.race = "venom" +monster.corpse = 8062 +monster.speed = 120 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Squidgy Slime", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Blubb", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 45, attack = 40} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/summons/druid_familiar.lua b/data/monster/summons/druid_familiar.lua new file mode 100644 index 00000000000..ceb91de2fa5 --- /dev/null +++ b/data/monster/summons/druid_familiar.lua @@ -0,0 +1,103 @@ +local mType = Game.createMonsterType("Druid familiar") +local monster = {} + +monster.description = "a druid familiar" +monster.experience = 0 +monster.outfit = { + --lookType = 993, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 309 +monster.manaCost = 3000 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = true +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -230, maxDamage = -260, range = 5, shootEffect = CONST_ANI_EARTH, effect = CONST_ME_STONES, target = true}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_EARTHDAMAGE, minDamage = -90, maxDamage = -150, length = 2, spread = 0, effect = CONST_ME_GROUNDSHAKER, target = false}, + {name ="summon challenge", interval = 2000, chance = 40, target = false} +} + +monster.defenses = { + defense = 55, + armor = 55, + {name ="combat", interval = 2000, chance = 75, type = COMBAT_HEALING, minDamage = 600, maxDamage = 600, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/summons/knight_familiar.lua b/data/monster/summons/knight_familiar.lua new file mode 100644 index 00000000000..f67e59c34dd --- /dev/null +++ b/data/monster/summons/knight_familiar.lua @@ -0,0 +1,106 @@ +local mType = Game.createMonsterType("Knight familiar") +local monster = {} + +monster.description = "a knight familiar" +monster.experience = 0 +monster.outfit = { + --lookType = 991, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 10000 +monster.maxHealth = 10000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 309 +monster.manaCost = 1000 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = true +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="sudden death", interval = 2000, chance = 17, minDamage = -300, maxDamage = -350, range = 7, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -200, maxDamage = -250, range = 6, radius = 2, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 3000, chance = 25, type = COMBAT_DEATHDAMAGE, minDamage = -180, maxDamage = -250, range = 5, radius = 3, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 3000, chance = 25, type = COMBAT_ICEDAMAGE, minDamage = -180, maxDamage = -250, range = 5, radius = 3, effect = CONST_ME_ICEAREA, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -200, maxDamage = -250, range = 6, radius = 2, effect = CONST_ME_ICETORNADO, target = true}, + {name ="ice strike", interval = 2000, chance = 17, minDamage = -300, maxDamage = -350, range = 5, target = true} +} + +monster.defenses = { + defense = 55, + armor = 55, + {name ="combat", interval = 2000, chance = 75, type = COMBAT_HEALING, minDamage = 400, maxDamage = 400, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/summons/paladin_familiar.lua b/data/monster/summons/paladin_familiar.lua new file mode 100644 index 00000000000..099a7320c86 --- /dev/null +++ b/data/monster/summons/paladin_familiar.lua @@ -0,0 +1,104 @@ +local mType = Game.createMonsterType("Paladin familiar") +local monster = {} + +monster.description = "a paladin familiar" +monster.experience = 0 +monster.outfit = { + --lookType = 992, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 15000 +monster.maxHealth = 15000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 309 +monster.manaCost = 2000 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 2, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = true +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_HOLYDAMAGE, minDamage = -200, maxDamage = -270, range = 5, radius = 3, shootEffect = CONST_ANI_HOLY, effect = CONST_ME_HOLYAREA, target = true}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -270, range = 5, radius = 3, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREATTACK, target = true}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_FIREDAMAGE, minDamage = -170, maxDamage = -230, range = 5, radius = 5, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREATTACK, target = true}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_HOLYDAMAGE, minDamage = -170, maxDamage = -230, range = 5, radius = 5, shootEffect = CONST_ANI_HOLY, effect = CONST_ME_HOLYAREA, target = true} +} + +monster.defenses = { + defense = 55, + armor = 55, + {name ="combat", interval = 2000, chance = 75, type = COMBAT_HEALING, minDamage = 380, maxDamage = 380, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/summons/sorcerer_familiar.lua b/data/monster/summons/sorcerer_familiar.lua new file mode 100644 index 00000000000..4057bde3617 --- /dev/null +++ b/data/monster/summons/sorcerer_familiar.lua @@ -0,0 +1,103 @@ +local mType = Game.createMonsterType("Sorcerer familiar") +local monster = {} + +monster.description = "a sorcerer familiar" +monster.experience = 0 +monster.outfit = { + --lookType = 994, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 20000 +monster.maxHealth = 20000 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 309 +monster.manaCost = 3000 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = true +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_LIFEDRAIN, minDamage = -90, maxDamage = -150, length = 2, spread = 0, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -190, maxDamage = -210, length = 2, spread = 0, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="summon challenge", interval = 2000, chance = 40, target = false} +} + +monster.defenses = { + defense = 55, + armor = 55, + {name ="combat", interval = 2000, chance = 75, type = COMBAT_HEALING, minDamage = 600, maxDamage = 600, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/traps/deathslicer.lua b/data/monster/traps/deathslicer.lua new file mode 100644 index 00000000000..1ff32995b64 --- /dev/null +++ b/data/monster/traps/deathslicer.lua @@ -0,0 +1,97 @@ +local mType = Game.createMonsterType("Deathslicer") +local monster = {} + +monster.description = "a deathslicer" +monster.experience = 0 +monster.outfit = { + lookType = 102, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1 +monster.maxHealth = 1 +monster.race = "undead" +monster.corpse = 2253 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -500}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -200, maxDamage = -400, radius = 2, effect = CONST_ME_BLOCKHIT, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/traps/deaththrower.lua b/data/monster/traps/deaththrower.lua new file mode 100644 index 00000000000..1978c6785b8 --- /dev/null +++ b/data/monster/traps/deaththrower.lua @@ -0,0 +1,90 @@ +local mType = Game.createMonsterType("Deaththrower") +local monster = {} + +monster.description = "a deaththrower" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 1551 +} + +monster.health = 100 +monster.maxHealth = 100 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 16 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = true, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="dark torturer skill reducer", interval = 2000, chance = 15, range = 6, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_POFF, target = false} +} + +monster.defenses = { + defense = 1, + armor = 1 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/traps/demon_summoner.lua b/data/monster/traps/demon_summoner.lua new file mode 100644 index 00000000000..5c7541274c8 --- /dev/null +++ b/data/monster/traps/demon_summoner.lua @@ -0,0 +1,94 @@ +local mType = Game.createMonsterType("Demon Summoner") +local monster = {} + +monster.description = "bones" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 460 +} + +monster.health = 100 +monster.maxHealth = 100 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = true, + staticAttackChance = 100, + targetDistance = 1, + runHealth = 0, + healthHidden = true, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Demon", chance = 100, interval = 1000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { +} + +monster.defenses = { + defense = 0, + armor = 0, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_HEALING, effect = CONST_ME_MORTAREA, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/traps/floor_blob.lua b/data/monster/traps/floor_blob.lua new file mode 100644 index 00000000000..d1f8fbd61f1 --- /dev/null +++ b/data/monster/traps/floor_blob.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Floor Blob") +local monster = {} + +monster.description = "a floor blob" +monster.experience = 0 +monster.outfit = { + lookType = 459, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1 +monster.maxHealth = 1 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = 0} +} + +monster.defenses = { + defense = 11, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/traps/hell_hole.lua b/data/monster/traps/hell_hole.lua new file mode 100644 index 00000000000..dcff7df017a --- /dev/null +++ b/data/monster/traps/hell_hole.lua @@ -0,0 +1,90 @@ +local mType = Game.createMonsterType("Hell Hole") +local monster = {} + +monster.description = "a hell hole" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 389 +} + +monster.health = 100 +monster.maxHealth = 100 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 1 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = true, + staticAttackChance = 100, + targetDistance = 1, + runHealth = 0, + healthHidden = true, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Deathspawn", chance = 25, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/traps/hive_pore.lua b/data/monster/traps/hive_pore.lua new file mode 100644 index 00000000000..eab642727be --- /dev/null +++ b/data/monster/traps/hive_pore.lua @@ -0,0 +1,96 @@ +local mType = Game.createMonsterType("Hive Pore") +local monster = {} + +monster.description = "a hive pore" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 15467 +} + +monster.health = 1 +monster.maxHealth = 1 +monster.race = "venom" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 355 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Lesser Swarmer", chance = 100, interval = 30000}, + {name = "Lesser Swarmer", chance = 100, interval = 30000}, + {name = "Lesser Swarmer", chance = 100, interval = 30000} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { +} + +monster.defenses = { + defense = 0, + armor = 0, + {name ="effect", interval = 30000, chance = 100, radius = 3, effect = CONST_ME_HITBYPOISON, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/traps/lavahole.lua b/data/monster/traps/lavahole.lua new file mode 100644 index 00000000000..b7c1ede73c4 --- /dev/null +++ b/data/monster/traps/lavahole.lua @@ -0,0 +1,90 @@ +local mType = Game.createMonsterType("Lavahole") +local monster = {} + +monster.description = "a lavahole" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 389 +} + +monster.health = 1 +monster.maxHealth = 1 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = true, + staticAttackChance = 100, + targetDistance = 1, + runHealth = 0, + healthHidden = true, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="combat", interval = 2000, chance = 50, type = COMBAT_FIREDAMAGE, minDamage = 0, maxDamage = -100, range = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = false} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/traps/magic_pillar.lua b/data/monster/traps/magic_pillar.lua new file mode 100644 index 00000000000..b32611bfb59 --- /dev/null +++ b/data/monster/traps/magic_pillar.lua @@ -0,0 +1,90 @@ +local mType = Game.createMonsterType("Magic Pillar") +local monster = {} + +monster.description = "a magic pillar" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 1551 +} + +monster.health = 1 +monster.maxHealth = 1 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 100, + healthHidden = true, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Demon", chance = 7, interval = 2000, max = 3} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 1, + armor = 1 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/traps/magicthrower.lua b/data/monster/traps/magicthrower.lua new file mode 100644 index 00000000000..6663d92211e --- /dev/null +++ b/data/monster/traps/magicthrower.lua @@ -0,0 +1,90 @@ +local mType = Game.createMonsterType("Magicthrower") +local monster = {} + +monster.description = "a magicthrower" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 1551 +} + +monster.health = 1 +monster.maxHealth = 1 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 100, + healthHidden = true, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="combat", interval = 2000, chance = 100, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -100, range = 7, shootEffect = CONST_ANI_POISON, target = false} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/traps/mechanical_fighter.lua b/data/monster/traps/mechanical_fighter.lua new file mode 100644 index 00000000000..9fe68c45de0 --- /dev/null +++ b/data/monster/traps/mechanical_fighter.lua @@ -0,0 +1,100 @@ +local mType = Game.createMonsterType("Mechanical Fighter") +local monster = {} + +monster.description = "a mechanical fighter" +monster.experience = 255 +monster.outfit = { + lookType = 102, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 420 +monster.maxHealth = 420 +monster.race = "undead" +monster.corpse = 2253 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 4860, chance = 87460} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -500} +} + +monster.defenses = { + defense = 199, + armor = 199 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 50}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/traps/mimic.lua b/data/monster/traps/mimic.lua new file mode 100644 index 00000000000..ac765602b78 --- /dev/null +++ b/data/monster/traps/mimic.lua @@ -0,0 +1,92 @@ +local mType = Game.createMonsterType("Mimic") +local monster = {} + +monster.description = "a mimic" +monster.experience = 0 +monster.outfit = { + lookType = 92, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 30 +monster.maxHealth = 30 +monster.race = "blood" +monster.corpse = 1740 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 0, + targetDistance = 5, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 3, + armor = 2 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/traps/pillar.lua b/data/monster/traps/pillar.lua new file mode 100644 index 00000000000..c1ad726ed50 --- /dev/null +++ b/data/monster/traps/pillar.lua @@ -0,0 +1,86 @@ +local mType = Game.createMonsterType("Pillar") +local monster = {} + +monster.description = "a pillar" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 1551 +} + +monster.health = 100 +monster.maxHealth = 100 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = true, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 1, + armor = 1 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/traps/plaguethrower.lua b/data/monster/traps/plaguethrower.lua new file mode 100644 index 00000000000..96c997bb129 --- /dev/null +++ b/data/monster/traps/plaguethrower.lua @@ -0,0 +1,90 @@ +local mType = Game.createMonsterType("Plaguethrower") +local monster = {} + +monster.description = "a plaguethrower" +monster.experience = 0 +monster.outfit = { + lookTypeEx = 1551 +} + +monster.health = 1 +monster.maxHealth = 1 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 0 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 100, + healthHidden = true, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="combat", interval = 2000, chance = 100, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -100, range = 7, shootEffect = CONST_ANI_POISON, target = false} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 100}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 100}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/bane_of_light.lua b/data/monster/undeads/bane_of_light.lua new file mode 100644 index 00000000000..503f7c598ab --- /dev/null +++ b/data/monster/undeads/bane_of_light.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("Bane of Light") +local monster = {} + +monster.description = "a bane of light" +monster.experience = 750 +monster.outfit = { + lookType = 68, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 580 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 50, + Stars = 3, + Occurrence = 3, + Locations = "Svargrond." + } + +monster.health = 1100 +monster.maxHealth = 1100 +monster.race = "blood" +monster.corpse = 6006 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 30, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "midnight shard", chance = 6930} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -366}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -50, maxDamage = -200, range = 1, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="speed", interval = 2000, chance = 15, speedChange = -400, range = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 60000} +} + +monster.defenses = { + defense = 38, + armor = 38, + {name ="outfit", interval = 4000, chance = 10, effect = CONST_ME_GROUNDSHAKER, target = false, duration = 5000, outfitMonster = "bat"}, + {name ="speed", interval = 2000, chance = 15, speedChange = 300, effect = CONST_ME_MAGIC_RED, target = false, duration = 3000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 15, maxDamage = 25, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -20}, + {type = COMBAT_FIREDAMAGE, percent = -100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/banshee.lua b/data/monster/undeads/banshee.lua new file mode 100644 index 00000000000..ebc3db51e22 --- /dev/null +++ b/data/monster/undeads/banshee.lua @@ -0,0 +1,147 @@ +local mType = Game.createMonsterType("Banshee") +local monster = {} + +monster.description = "a banshee" +monster.experience = 900 +monster.outfit = { + lookType = 78, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 78 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Single one under the White Flower Temple in Thais (respawn takes about 20-25 minutes), \z + Banshee Quest area in Ghostlands (also accesible by Isle of the Kings), Demon Quest Room, Drefia, \z + Ancient Ruins Tomb, Desert Dungeon (unreachable), Pits of Inferno in Tafariel's Throne room, \z + Cemetery Quarter in Yalahar, Vengoth Castle, one in Robson Isle." + } + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "undead" +monster.corpse = 6019 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 80, + health = 10, + damage = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 500, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Dance for me your dance of death!", yell = false}, + {text = "Let the music play!", yell = false}, + {text = "I will mourn your death!", yell = false}, + {text = "Are you ready to rock?", yell = false}, + {text = "Feel my gentle kiss of death.", yell = false}, + {text = "That's what I call easy listening!", yell = false}, + {text = "IIIIEEEeeeeeehhhHHHH!", yell = true} +} + +monster.loot = { + {name = "candlestick", chance = 70000}, + {name = "wedding ring", chance = 460}, + {id = 2124, chance = 60}, + {name = "silver brooch", chance = 1250}, + {name = "white pearl", chance = 1010}, + {name = "black pearl", chance = 2030}, + {name = "gold coin", chance = 30000, maxCount = 80}, + {name = "silver amulet", chance = 8700}, + {id = 2175, chance = 520}, + {name = "life crystal", chance = 70}, + {name = "stone skin amulet", chance = 820}, + {name = "ring of healing", chance = 730}, + {id = 2372, chance = 910}, + {name = "poison dagger", chance = 1350}, + {name = "red robe", chance = 150}, + {name = "blue robe", chance = 700}, + {name = "simple dress", chance = 6050}, + {name = "strong mana potion", chance = 680}, + {name = "terra mantle", chance = 340}, + {name = "petrified scream", chance = 4150}, + {name = "hair of a banshee", chance = 4810}, + {name = "sweet smelling bait", chance = 40} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100, condition = {type = CONDITION_POISON, totalDamage = 3, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -100, maxDamage = -200, radius = 4, effect = CONST_ME_SOUND_RED, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_DEATHDAMAGE, minDamage = -55, maxDamage = -350, range = 1, radius = 1, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="speed", interval = 2000, chance = 10, speedChange = -300, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 15000} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 120, maxDamage = 190, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/betrayed_wraith.lua b/data/monster/undeads/betrayed_wraith.lua new file mode 100644 index 00000000000..7d3e9d40d80 --- /dev/null +++ b/data/monster/undeads/betrayed_wraith.lua @@ -0,0 +1,134 @@ +local mType = Game.createMonsterType("Betrayed Wraith") +local monster = {} + +monster.description = "a betrayed wraith" +monster.experience = 3500 +monster.outfit = { + lookType = 233, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 284 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Pits of Inferno, Helheim, The Inquisition Quest, Roshamuul Prison." + } + +monster.health = 4200 +monster.maxHealth = 4200 +monster.race = "undead" +monster.corpse = 6316 +monster.speed = 346 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 300, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Rrrah!", yell = false}, + {text = "Gnarr!", yell = false}, + {text = "Tcharrr!", yell = false} +} + +monster.loot = { + {name = "small diamond", chance = 11800, maxCount = 4}, + {name = "gold coin", chance = 100000, maxCount = 200}, + {name = "platinum coin", chance = 100000, maxCount = 8}, + {name = "power bolt", chance = 50000, maxCount = 5}, + {name = "orichalcum pearl", chance = 8000, maxCount = 2}, + {name = "skull helmet", chance = 390}, + {name = "golden figurine", chance = 160}, + {name = "soul orb", chance = 10000}, + {id = 6300, chance = 390}, + {name = "demonic essence", chance = 19430}, + {name = "concentrated demonic blood", chance = 65250}, + {name = "assassin star", chance = 10780, maxCount = 5}, + {name = "mercenary sword", chance = 1890}, + {name = "bloody edge", chance = 80}, + {name = "great mana potion", chance = 15000, maxCount = 3}, + {name = "ultimate health potion", chance = 15410}, + {name = "unholy bone", chance = 18410} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450}, + {name ="betrayed wraith skill reducer", interval = 2000, chance = 10, target = false}, + {name ="speed", interval = 2000, chance = 20, speedChange = -600, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = true, duration = 3000} +} + +monster.defenses = { + defense = 55, + armor = 55, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_HEALING, minDamage = 350, maxDamage = 600, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="invisible", interval = 2000, chance = 10}, + {name ="speed", interval = 2000, chance = 15, speedChange = 460, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = -20}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/blightwalker.lua b/data/monster/undeads/blightwalker.lua new file mode 100644 index 00000000000..e5bb8e1f7cb --- /dev/null +++ b/data/monster/undeads/blightwalker.lua @@ -0,0 +1,143 @@ +local mType = Game.createMonsterType("Blightwalker") +local monster = {} + +monster.description = "a blightwalker" +monster.experience = 5850 +monster.outfit = { + lookType = 246, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 298 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Pits of Inferno, Edron (In the Vats during The Inquisition Quest), Roshamuul Prison." + } + +monster.health = 8900 +monster.maxHealth = 8900 +monster.race = "undead" +monster.corpse = 6354 +monster.speed = 350 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 80, + health = 10, + damage = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 800, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I can see you decaying!", yell = false}, + {text = "Let me taste your mortality!", yell = false}, + {text = "Your lifeforce is waning!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 197}, + {name = "platinum coin", chance = 100000, maxCount = 5}, + {name = "amulet of loss", chance = 120}, + {name = "gold ring", chance = 1870}, + {name = "hailstorm rod", chance = 10000}, + {name = "garlic necklace", chance = 2050}, + {name = "blank rune", chance = 26250, maxCount = 2}, + {name = "golden sickle", chance = 350}, + {name = "skull staff", chance = 1520}, + {name = "scythe", chance = 3000}, + {name = "bunch of wheat", chance = 50000}, + {name = "soul orb", chance = 23720}, + {id = 6300, chance = 1410}, + {name = "demonic essence", chance = 28000}, + {name = "assassin star", chance = 5900, maxCount = 10}, + {name = "great mana potion", chance = 31360, maxCount = 3}, + {id = 7632, chance = 4450}, + {id = 7633, chance = 4450}, + {name = "seeds", chance = 4300}, + {name = "terra mantle", chance = 1050}, + {name = "terra legs", chance = 2500}, + {name = "ultimate health potion", chance = 14720, maxCount = 2}, + {name = "gold ingot", chance = 5270}, + {name = "bundle of cursed straw", chance = 15000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -490}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -220, maxDamage = -405, range = 7, radius = 1, shootEffect = CONST_ANI_POISON, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -65, maxDamage = -135, radius = 4, effect = CONST_ME_MAGIC_GREEN, target = false}, + {name ="drunk", interval = 2000, chance = 10, radius = 3, effect = CONST_ME_HITBYPOISON, target = false, duration = 5000}, + {name ="blightwalker curse", interval = 2000, chance = 15, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -300, range = 7, shootEffect = CONST_ANI_POISON, target = true, duration = 30000} +} + +monster.defenses = { + defense = 50, + armor = 50 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = -30}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/blood_beast.lua b/data/monster/undeads/blood_beast.lua new file mode 100644 index 00000000000..9a8362401eb --- /dev/null +++ b/data/monster/undeads/blood_beast.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Blood Beast") +local monster = {} + +monster.description = "a blood beast" +monster.experience = 1000 +monster.outfit = { + lookType = 602, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1040 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Oramond/Southern Plains, Lower Rathleton, Oramond/Western Plains, \z + Underground Glooth Factory, Jaccus Maxxen's Dungeon." + } + +monster.health = 1600 +monster.maxHealth = 1600 +monster.race = "venom" +monster.corpse = 23351 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 4 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Roarr!", yell = false} +} + +monster.loot = { + {id = 23549, chance = 2010}, + {id = 10557, chance = 3080}, + {id = 23517, chance = 2720}, + {id = 2148, chance = 100000, maxCount = 139}, + {id = 23565, chance = 1040}, + {id = 7588, chance = 7710}, + {id = 7366, chance = 1290, maxCount = 5}, + {id = 23554, chance = 250}, + {id = 23550, chance = 210}, + {id = 23549, chance = 210}, + {id = 23551, chance = 250}, + {id = 23529, chance = 280} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 82, attack = 50, condition = {type = CONDITION_POISON, totalDamage = 260, interval = 4000}}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -65, maxDamage = -105, range = 5, shootEffect = CONST_ANI_GREENSTAR, effect = CONST_ME_POISONAREA, target = true}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 17, minDamage = -300, maxDamage = -400, radius = 4, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.defenses = { + defense = 36, + armor = 23, + {name ="speed", interval = 2000, chance = 8, speedChange = 314, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000}, + {name ="combat", interval = 2000, chance = 7, type = COMBAT_HEALING, minDamage = 80, maxDamage = 120, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/bonebeast.lua b/data/monster/undeads/bonebeast.lua new file mode 100644 index 00000000000..0fdc30f4b7d --- /dev/null +++ b/data/monster/undeads/bonebeast.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Bonebeast") +local monster = {} + +monster.description = "a bonebeast" +monster.experience = 580 +monster.outfit = { + lookType = 101, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 101 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Old Fortress, Ankrahmun Tombs, Helheim, Ramoa, Lich Hell, beneath Fenrock, Deeper Banuta, \z + Vengoth Castle, Vandura Mountain, Robson's Isle, Middle Spike, Lion's Rock, Mother of Scarabs Lair, Caverna Exanima." + } + +monster.health = 515 +monster.maxHealth = 515 +monster.race = "undead" +monster.corpse = 6030 +monster.speed = 218 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Cccchhhhhhhhh!", yell = false}, + {text = "Knooorrrrr!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 14000, maxCount = 50}, + {name = "gold coin", chance = 16000, maxCount = 40}, + {id = 2229, chance = 20000}, + {id = 2230, chance = 47750}, + {name = "bone club", chance = 4950}, + {name = "plate armor", chance = 8000}, + {name = "bone shield", chance = 2000}, + {name = "green mushroom", chance = 1350}, + {name = "hardened bone", chance = 960}, + {name = "health potion", chance = 540}, + {name = "bonebeast trophy", chance = 120}, + {name = "bony tail", chance = 9780} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200, condition = {type = CONDITION_POISON, totalDamage = 100, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -50, maxDamage = -90, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -25, maxDamage = -47, radius = 3, effect = CONST_ME_MAGIC_RED, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -50, maxDamage = -60, radius = 3, effect = CONST_ME_POISONAREA, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -70, maxDamage = -80, length = 6, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -600, target = true, duration = 13000} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 50, maxDamage = 60, effect = CONST_ME_HITBYPOISON, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -20}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/bony_sea_devil.lua b/data/monster/undeads/bony_sea_devil.lua new file mode 100644 index 00000000000..f568b3d69c9 --- /dev/null +++ b/data/monster/undeads/bony_sea_devil.lua @@ -0,0 +1,139 @@ +local mType = Game.createMonsterType("Bony Sea Devil") +local monster = {} + +monster.description = "a bony sea devil" +monster.experience = 32500 +monster.outfit = { + lookType = 1294, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1926 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 5000, + FirstUnlock = 25, + SecondUnlock = 2500, + CharmsPoints = 100, + Stars = 5, + Occurrence = 0, + Locations = "Ebb and Flow." + } + +monster.health = 24000 +monster.maxHealth = 24000 +monster.race = "undead" +monster.corpse = 38632 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Bling.", yell = false}, + {text = "Clank.", yell = false} +} + +monster.loot = { + {name = "crystal coin", chance = 70540}, + {name = "platinum coin", chance = 90540, maxCount = 32}, + {name = "ultimate health potion", chance = 72220, maxCount = 7}, + {id = 7632, chance = 54560}, -- Giant shimmering pearl + {id = 7633, chance = 54560}, -- Giant shimmering pearl + {name = "gold ingot", chance = 34920}, + {name = "glacier kilt", chance = 12920}, + {name = "northwind rod", chance = 11920}, + {name = "wand of voodoo", chance = 14000}, + {name = "glacial rod", chance = 13450}, + {name = "green crystal fragment", chance = 22920}, + {name = "onyx chip", chance = 20000}, + {name = "rainbow quartz", chance = 13660, maxCount = 2}, + {id = 38764, chance = 14560}, -- Rod + {id = 38849, chance = 14560}, -- Jaws + {name = "skullcracker armor", chance = 1680}, + {name = "goblet of gloom", chance = 880}, + {id = 38944, chance = 50} -- Bag you desire +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -600}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -550, maxDamage = -1100, length = 5, spread = 3, effect = CONST_ME_GROUNDSHAKER, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -400, maxDamage = -1000, radius = 7, effect = CONST_ME_BIGCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ICEDAMAGE, minDamage = -550, maxDamage = -1000, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_ICEATTACK, target = true}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ICEDAMAGE, minDamage = -300, maxDamage = -700, range = 7, radius = 5, shootEffect = CONST_ANI_ICE, effect = CONST_ME_ICEAREA, target = true} + -- Fear + -- Chain: const_me-> CONST_ME_ICEATTACK, combat_t->COMBAT_ICEDAMAGE + +} + +monster.defenses = { + defense = 80, + armor = 100 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 60}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/burster_spectre.lua b/data/monster/undeads/burster_spectre.lua new file mode 100644 index 00000000000..3c4572ca139 --- /dev/null +++ b/data/monster/undeads/burster_spectre.lua @@ -0,0 +1,143 @@ +local mType = Game.createMonsterType("Burster Spectre") +local monster = {} + +monster.description = "a Burster Spectre" +monster.experience = 6000 +monster.outfit = { + lookType = 1122, + lookHead = 7, + lookBody = 19, + lookLegs = 86, + lookFeet = 19, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1726 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Haunted Tomb west of Darashia, Buried Cathedral." + } + +monster.health = 6500 +monster.maxHealth = 6500 +monster.race = "blood" +monster.corpse = 34801 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "We came tooo thiiiiss wooorld to... get youuu!", yell = false} +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 7}, + {name = "great spirit potion", chance = 100000, maxCount = 3}, + {name = "protection amulet", chance = 15000}, + {name = "life crystal", chance = 12050}, + {name = "silver amulet", chance = 15000}, + {name = "wand of voodoo", chance = 11050}, + {name = "wand of cosmic energy", chance = 11800}, + {name = "dragon necklace", chance = 16600}, + {name = "stone skin amulet", chance = 8860}, + {id = 34720, chance = 15600}, + {name = "glacier amulet", chance = 16890}, + {name = "orb", chance = 18980}, + {name = "hailstorm rod", chance = 17550}, + {name = "elven amulet", chance = 1800}, + {name = "garlic necklace", chance = 2640}, + {name = "platinum amulet", chance = 2600}, + {name = "mind stone", chance = 1800}, + {name = "glacial rod", chance = 520}, + {name = "shockwave amulet", chance = 620}, + {name = "strange symbol", chance = 720}, + {name = "hexagonal ruby", chance = 480} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -400, maxDamage = -580}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_LIFEDRAIN, minDamage = -270, maxDamage = -390, radius = 4, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ICEDAMAGE, minDamage = -280, maxDamage = -410, radius = 4, effect = CONST_ME_ICEAREA, target = true}, + {name ="combat", interval = 2000, chance = 5200, type = COMBAT_ICEDAMAGE, minDamage = -280, maxDamage = -370, effect = CONST_ME_ICEATTACK, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_ICEDAMAGE, minDamage = -200, maxDamage = -290, length = 5, spread = 3, effect = CONST_ME_ICEATTACK, target = false} +} + +monster.defenses = { + defense = 70, + armor = 70, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_HEALING, minDamage = 150, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.reflects = { + {type = COMBAT_ICEDAMAGE, percent = 133} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 70}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/capricious_phantom.lua b/data/monster/undeads/capricious_phantom.lua new file mode 100644 index 00000000000..9b693954fbb --- /dev/null +++ b/data/monster/undeads/capricious_phantom.lua @@ -0,0 +1,135 @@ +local mType = Game.createMonsterType("Capricious Phantom") +local monster = {} + +monster.description = "a capricious phantom" +monster.experience = 29900 +monster.outfit = { + lookType = 1298, + lookHead = 81, + lookBody = 114, + lookLegs = 85, + lookFeet = 83, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1932 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 5000, + FirstUnlock = 25, + SecondUnlock = 2500, + CharmsPoints = 100, + Stars = 5, + Occurrence = 0, + Locations = "Ebb and Flow." + } + +monster.health = 30000 +monster.maxHealth = 30000 +monster.race = "undead" +monster.corpse = 38956 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I hope you can't swim.", yell = false}, + {text = "Troubled Water. Troubled you!", yell = false}, + {text = "You should shiver!", yell = false}, + {text = "You will leak blood.", yell = false} +} + +monster.loot = { + {name = "crystal coin", chance = 70540}, + {name = "platinum coin", chance = 82220, maxCount = 32}, + {name = "great spirit potion", chance = 32220, maxCount = 7}, + {name = "blue gem", chance = 54560}, + {name = "gold ingot", chance = 54560}, + {name = "violet gem", chance = 74560}, + {name = "wood cape", chance = 21920}, + {name = "ornate crossbow", chance = 20020}, + {name = "glacial rod", chance = 21920}, + {name = "fur armor", chance = 18920}, + {id = 38973, chance = 14560}, -- Capricious heart + {id = 38980, chance = 11560}, -- Capricious robe + {id = 26185, chance = 28920}, -- Ring of blue plasma + {id = 26198, chance = 24920}, -- Collar of blue plasma + {id = 38944, chance = 50} -- Bag you desire +} + +monster.attacks = { + {name ="combat", interval = 3000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -650, maxDamage = -1000, range = 7, radius = 3, shootEffect = CONST_ANI_POISONARROW, effect = CONST_ME_GREEN_RINGS, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -600, maxDamage = -1050, length = 6, spread = 4, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_ICEDAMAGE, minDamage = -650, maxDamage = -900, radius = 3, effect = CONST_ME_ICETORNADO, target = false}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_ICEDAMAGE, minDamage = -650, maxDamage = -900, range = 7, radius = 4, effect = CONST_ME_ICEATTACK, target = true} + -- Chain: const_me-> CONST_ME_ICEATTACK, combat_t->COMBAT_ICEDAMAGE +} + +monster.defenses = { + defense = 75, + armor = 100 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) \ No newline at end of file diff --git a/data/monster/undeads/crypt_shambler.lua b/data/monster/undeads/crypt_shambler.lua new file mode 100644 index 00000000000..25ea5f94267 --- /dev/null +++ b/data/monster/undeads/crypt_shambler.lua @@ -0,0 +1,127 @@ +local mType = Game.createMonsterType("Crypt Shambler") +local monster = {} + +monster.description = "a crypt shambler" +monster.experience = 195 +monster.outfit = { + lookType = 100, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 100 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Ankrahmun Tombs, Trapwood, Ramoa, Hellgate, Helheim, Mount Sternum Undead Cave, Deeper Catacombs, \z + Cemetery Quarter, Treasure Island, Upper Spike, Lion's Rock." + } + +monster.health = 330 +monster.maxHealth = 330 +monster.race = "undead" +monster.corpse = 6029 +monster.speed = 140 +monster.manaCost = 580 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Aaaaahhhh!", yell = false}, + {text = "Hoooohhh!", yell = false}, + {text = "Uhhhhhhh!", yell = false}, + {text = "Chhhhhhh!", yell = false} +} + +monster.loot = { + {name = "small diamond", chance = 510}, + {name = "gold coin", chance = 57000, maxCount = 55}, + {name = "rotten meat", chance = 1850}, + {id = 2230, chance = 5000}, + {name = "throwing star", chance = 910, maxCount = 3}, + {name = "bone sword", chance = 1000}, + {name = "iron helmet", chance = 2130}, + {name = "iron helmet", chance = 2000}, + {name = "bone shield", chance = 1000}, + {name = "worm", chance = 9000, maxCount = 10}, + {name = "half-digested piece of meat", chance = 5000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -140}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -28, maxDamage = -55, range = 1, target = true} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/cursed_prospector.lua b/data/monster/undeads/cursed_prospector.lua new file mode 100644 index 00000000000..ec5697737f9 --- /dev/null +++ b/data/monster/undeads/cursed_prospector.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Cursed Prospector") +local monster = {} + +monster.description = "Cursed Prospector" +monster.experience = 5250 +monster.outfit = { + lookType = 1268, + lookHead = 0, + lookBody = 19, + lookLegs = 0, + lookFeet = 0, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 1880 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Barren Drift." + } + +monster.health = 3900 +monster.maxHealth = 3900 +monster.race = "undead" +monster.corpse = 37445 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 3, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 5}, + {name = "flash arrow", chance = 17700, maxCount = 10}, + {name = "great spirit potion", chance = 15190, maxCount = 2}, + {name = "spectral silver nugget", chance = 11520}, + {name = "spectral gold nugget", chance = 5680}, + {name = "emerald bangle", chance = 1340}, + {name = "lightning boots", chance = 1340}, + {name = "diamond", chance = 1000}, + {name = "lightning robe", chance = 1000}, + {name = "elven amulet", chance = 1000}, + {name = "lightning legs", chance = 830}, + {name = "shockwave amulet", chance = 500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -200}, + {name ="combat", interval = 1700, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -550, radius = 3, shootEffect = CONST_ANI_ENVENOMEDARROW, target = true}, + {name ="combat", interval = 1700, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -150, maxDamage = -550, length = 4, spread = 3, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 1700, chance = 35, type = COMBAT_DEATHDAMAGE, minDamage = -150, maxDamage = -550, radius = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 1700, chance = 35, type = COMBAT_HOLYDAMAGE, minDamage = -250, maxDamage = -550, radius = 3, effect = CONST_ME_HOLYAREA, target = false}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_ENERGYDAMAGE, minDamage = -400, maxDamage = -550, range = 4, radius = 4, effect = CONST_ME_ENERGYAREA, target = true} +} + +monster.defenses = { + defense = 40, + armor = 85 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 60}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/death_priest.lua b/data/monster/undeads/death_priest.lua new file mode 100644 index 00000000000..351795d1bcf --- /dev/null +++ b/data/monster/undeads/death_priest.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Death Priest") +local monster = {} + +monster.description = "a death priest" +monster.experience = 750 +monster.outfit = { + lookType = 99, + lookHead = 95, + lookBody = 116, + lookLegs = 119, + lookFeet = 115, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 710 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Horestis Tomb." + } + +monster.health = 800 +monster.maxHealth = 800 +monster.race = "undead" +monster.corpse = 13975 +monster.speed = 204 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 80, + health = 10, + damage = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "white pearl", chance = 3000}, + {name = "gold coin", chance = 70000, maxCount = 144}, + {name = "scarab coin", chance = 10000, maxCount = 3}, + {id = 2175, chance = 6800}, + {name = "ring of healing", chance = 1000}, + {name = "orichalcum pearl", chance = 6000, maxCount = 4}, + {name = "health potion", chance = 15000}, + {name = "mana potion", chance = 15000}, + {id = 13739, chance = 27000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -80}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -120, maxDamage = -250, range = 7, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_MORTAREA, target = true} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 80, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 75}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/demon_skeleton.lua b/data/monster/undeads/demon_skeleton.lua new file mode 100644 index 00000000000..ee28cf7b65d --- /dev/null +++ b/data/monster/undeads/demon_skeleton.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Demon Skeleton") +local monster = {} + +monster.description = "a demon skeleton" +monster.experience = 240 +monster.outfit = { + lookType = 37, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 37 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Triangle Tower, Hellgate, Draconia, Plains of Havoc, Pits of Inferno, Thais Ancient Temple, \z + Fibula Dungeon, Mintwallin, Mount Sternum hidden cave, Drefia, Ghost Ship, Edron Hero Cave, Shadowthorn, \z + Elvenbane, Ghostlands, Femor Hills, White Flower Temple, Isle of the Kings, Dark Cathedral, Ankrahmun Tombs, \z + Ramoa, Helheim, Vengoth, Upper Spike, Lion's Rock." + } + +monster.health = 400 +monster.maxHealth = 400 +monster.race = "undead" +monster.corpse = 5963 +monster.speed = 180 +monster.manaCost = 620 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2050, chance = 5270}, + {name = "black pearl", chance = 2900}, + {name = "small ruby", chance = 1400}, + {name = "gold coin", chance = 97000, maxCount = 75}, + {name = "mind stone", chance = 520}, + {name = "mysterious fetish", chance = 690}, + {name = "throwing star", chance = 10000, maxCount = 3}, + {name = "battle hammer", chance = 4000}, + {name = "iron helmet", chance = 3450}, + {name = "battle shield", chance = 5000}, + {name = "guardian shield", chance = 100}, + {name = "health potion", chance = 10120, maxCount = 2}, + {name = "health potion", chance = 10000, maxCount = 2}, + {name = "mana potion", chance = 5300}, + {name = "demonic skeletal hand", chance = 12600} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -185}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -30, maxDamage = -50, range = 1, radius = 1, effect = CONST_ME_SMALLCLOUDS, target = true} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/distorted_phantom.lua b/data/monster/undeads/distorted_phantom.lua new file mode 100644 index 00000000000..e1547bbba7a --- /dev/null +++ b/data/monster/undeads/distorted_phantom.lua @@ -0,0 +1,134 @@ +local mType = Game.createMonsterType("Distorted Phantom") +local monster = {} + +monster.description = "a distorted phantom" +monster.experience = 28600 +monster.outfit = { + lookType = 1298, + lookHead = 113, + lookBody = 94, + lookLegs = 132, + lookFeet = 76, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1962 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 5000, + FirstUnlock = 25, + SecondUnlock = 2500, + CharmsPoints = 100, + Stars = 5, + Occurrence = 0, + Locations = "Mirrored Nightmare." + } + +monster.health = 26000 +monster.maxHealth = 26000 +monster.race = "undead" +monster.corpse = 38968 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I'm not here. I am there.", yell = false}, + {text = "The night is coming for you.", yell = false}, + {text = "Too late... No turning back now.", yell = false} +} + +monster.loot = { + {name = "crystal coin", chance = 70540}, + {name = "platinum coin", chance = 81920, maxCount = 33}, + {name = "great spirit potion", chance = 51920, maxCount = 8}, + {name = "violet gem", chance = 74560}, + {name = "spellbook of warding", chance = 41920}, + {name = "underworld rod", chance = 31920}, + {name = "springsprout rod", chance = 28920}, + {name = "gold ingot", chance = 54560}, + {name = "glacial rod", chance = 44560}, + {id = 26185, chance = 28920}, -- Ring of blue plasma + {id = 26187, chance = 28920}, -- Ring of green plasma + {id = 26189, chance = 28920}, -- Ring of red plasma + {id = 38977, chance = 18920}, -- Distorted hearth + {id = 38984, chance = 11920}, -- Distorted robe + {id = 38944, chance = 50} -- Bag you desire +} + +monster.attacks = { + {name ="combat", interval = 2000, chance = 17, type = COMBAT_ICEDAMAGE, minDamage = -600, maxDamage = -1100, range = 7, shootEffect = CONST_ANI_FLASHARROW, effect = CONST_ME_GROUNDSHAKER, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HOLYDAMAGE, minDamage = -700, maxDamage = -1100, range = 7, shootEffect = CONST_ANI_SMALLHOLY, effect = CONST_ME_HOLYDAMAGE, target = true}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_HOLYDAMAGE, minDamage = -650, maxDamage = -900, radius = 4, effect = CONST_ME_EXPLOSIONHIT, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_ICEDAMAGE, minDamage = -600, maxDamage = -1000, range = 7, shootEffect = CONST_ANI_ICE, effect = CONST_ME_ICETORNADO, target = true} + -- Chain: const_me-> CONST_ME_BLUE_ENERGY_SPARK, combat_t->COMBAT_ICEDAMAGE +} + +monster.defenses = { + defense = 75, + armor = 100 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) \ No newline at end of file diff --git a/data/monster/undeads/druid's_apparition.lua b/data/monster/undeads/druid's_apparition.lua new file mode 100644 index 00000000000..58a2e5aba92 --- /dev/null +++ b/data/monster/undeads/druid's_apparition.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Druid's Apparition") +local monster = {} + +monster.description = "a druid's apparition" +monster.experience = 28600 +monster.outfit = { + lookType = 148, + lookHead = 114, + lookBody = 48, + lookLegs = 114, + lookFeet = 95, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1946 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 5000, + FirstUnlock = 25, + SecondUnlock = 2500, + CharmsPoints = 100, + Stars = 5, + Occurrence = 0, + Locations = "Mirrored Nightmare." + } + +monster.health = 25000 +monster.maxHealth = 25000 +monster.race = "blood" +monster.corpse = 6081 +monster.speed = 235 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Healing is what I do best.", yell = false}, + {text = "I'll take your place when you are gone.", yell = false} +} + +monster.loot = { + {name = "crystal coin", chance = 70540}, + {name = "platinum coin", chance = 81920, maxCount = 33}, + {name = "great mana potion", chance = 71920, maxCount = 5}, + {name = "green gem", chance = 64560}, + {name = "terra rod", chance = 41920}, + {name = "stone skin amulet", chance = 31920}, + {name = "magma amulet", chance = 21920}, + {name = "glacier robe", chance = 15920}, + {name = "platinum amulet", chance = 13920}, + {name = "underworld rod", chance = 18920}, + {name = "springsprout rod", chance = 14920}, + {name = "sacred tree amulet", chance = 19920}, + {id = 26200, chance = 29000} -- Collar of red plasma +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1000}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_ICEDAMAGE, minDamage = -650, maxDamage = -1000, range = 7, radius = 4, shootEffect = CONST_ANI_ICE, effect = CONST_ME_BIGCLOUDS, target = true}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_HOLYDAMAGE, minDamage = -450, maxDamage = -900, radius = 4, effect = CONST_ME_HOLYAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HOLYDAMAGE, minDamage = -750, maxDamage = -900, range = 7, shootEffect = CONST_ANI_HOLY, effect = CONST_ME_HOLYDAMAGE, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -550, maxDamage = -1000, range = 7, shootEffect = CONST_ANI_SMALLICE, effect = CONST_ME_ICEATTACK, target = true}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_ICEDAMAGE, minDamage = -750, maxDamage = -1000, radius = 4, effect = CONST_ME_ICEATTACK, target = false} + -- Chain: const_me-> CONST_ME_BLUE_ENERGY_SPARK, combat_t->COMBAT_ICEDAMAGE +} + +monster.defenses = { + defense = 75, + armor = 100 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 40}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) \ No newline at end of file diff --git a/data/monster/undeads/elder_mummy.lua b/data/monster/undeads/elder_mummy.lua new file mode 100644 index 00000000000..f94215a0946 --- /dev/null +++ b/data/monster/undeads/elder_mummy.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Elder Mummy") +local monster = {} + +monster.description = "an elder mummy" +monster.experience = 560 +monster.outfit = { + lookType = 65, + lookHead = 20, + lookBody = 30, + lookLegs = 40, + lookFeet = 50, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 711 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Horestis Tomb." + } + +monster.health = 850 +monster.maxHealth = 850 +monster.race = "undead" +monster.corpse = 6004 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 80, + health = 10, + damage = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2124, chance = 1650}, + {name = "silver brooch", chance = 4000}, + {name = "black pearl", chance = 1340}, + {name = "gold coin", chance = 87000, maxCount = 160}, + {name = "scarab coin", chance = 10000, maxCount = 3}, + {name = "strange talisman", chance = 4500}, + {id = 2162, chance = 6000}, + {name = "poison dagger", chance = 380}, + {name = "worm", chance = 20000, maxCount = 3}, + {name = "gauze bandage", chance = 10000}, + {name = "flask of embalming fluid", chance = 12600}, + {id = 13472, chance = 2400} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -120, condition = {type = CONDITION_POISON, totalDamage = 3, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = 0, maxDamage = -130, range = 1, effect = CONST_ME_MORTAREA, target = true}, + {name ="speed", interval = 2000, chance = 15, speedChange = -300, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 15000} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/evil_prospector.lua b/data/monster/undeads/evil_prospector.lua new file mode 100644 index 00000000000..0b645ba638e --- /dev/null +++ b/data/monster/undeads/evil_prospector.lua @@ -0,0 +1,122 @@ +local mType = Game.createMonsterType("Evil Prospector") +local monster = {} + +monster.description = "Evil Prospector" +monster.experience = 7500 +monster.outfit = { + lookType = 1268, + lookHead = 0, + lookBody = 13, + lookLegs = 0, + lookFeet = 0, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 1885 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Barren Drift." + } + +monster.health = 8500 +monster.maxHealth = 8500 +monster.race = "undead" +monster.corpse = 37445 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 3, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 5}, + {name = "spectral silver nugget", chance = 17110, maxCount = 2}, + {name = "wand of starstorm", chance = 13160, maxCount = 10}, + {name = "lightning pendant", chance = 9210}, + {name = "emerald bangle", chance = 3950}, + {name = "strange talisman", chance = 2630}, + {name = "wand of defiance", chance = 2630}, + {name = "lightning headband", chance = 1320} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -500}, + {name ="combat", interval = 1700, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -250, maxDamage = -550, radius = 3, shootEffect = CONST_ANI_ENVENOMEDARROW, target = true}, + {name ="combat", interval = 1700, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -250, maxDamage = -550, length = 4, spread = 3, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 1700, chance = 35, type = COMBAT_DEATHDAMAGE, minDamage = -250, maxDamage = -550, radius = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 1700, chance = 35, type = COMBAT_HOLYDAMAGE, minDamage = -250, maxDamage = -400, radius = 3, effect = CONST_ME_HOLYAREA, target = false}, + {name ="combat", interval = 1700, chance = 13, type = COMBAT_ENERGYDAMAGE, minDamage = -400, maxDamage = -450, range = 4, radius = 4, effect = CONST_ME_ENERGYAREA, target = true} +} + +monster.defenses = { + defense = 40, + armor = 100 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 60}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/falcon_knight.lua b/data/monster/undeads/falcon_knight.lua new file mode 100644 index 00000000000..8f16a2c3230 --- /dev/null +++ b/data/monster/undeads/falcon_knight.lua @@ -0,0 +1,138 @@ +local mType = Game.createMonsterType("Falcon Knight") +local monster = {} + +monster.description = "a falcon knight" +monster.experience = 5985 +monster.outfit = { + lookType = 1071, + lookHead = 57, + lookBody = 75, + lookLegs = 38, + lookFeet = 86, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 1646 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Falcon Bastion." + } + +monster.health = 9000 +monster.maxHealth = 9000 +monster.race = "blood" +monster.corpse = 33364 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Mmmhaarrrgh!", yell = false} +} + +monster.loot = { + {id = 2671, chance = 70080, maxCount = 8}, + {name = "Soul Orb", chance = 35000}, + {name = "Great Mana Potion", chance = 33000, maxCount = 3}, + {name = "Great Health Potion", chance = 33000, maxCount = 3}, + {name = "Concentrated Demonic Blood", chance = 30000, maxCount = 4}, + {name = "Small Amethyst", chance = 24950, maxCount = 3}, + {name = "Assassin Star", chance = 24670, maxCount = 10}, + {name = "Small Diamond", chance = 15700, maxCount = 3}, + {name = "Small Ruby", chance = 15333, maxCount = 3}, + {name = "Small Emerald", chance = 15110, maxCount = 3}, + {name = "Onyx Arrow", chance = 14480, maxCount = 15}, + {name = "Small Topaz", chance = 4580, maxCount = 3}, + {name = "Titan Axe", chance = 3000}, + {id = 7633, chance = 3000}, + {name = "Spiked Squelcher", chance = 2200}, + {name = "Knight Armor", chance = 1980}, + {name = "Falcon Crest", chance = 1250}, + {name = "War Axe", chance = 1230}, + {name = "Violet Gem", chance = 1060}, + {name = "Damaged Armor Plates", chance = 990}, + {name = "Green Gem", chance = 880}, + {name = "Golden Armor", chance = 840}, + {name = "Mastermind Shield", chance = 620}, + {name = "Heavy Mace", chance = 460}, + {id = 2578, chance = 370}, + {id = 2136, chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="combat", interval = 2000, chance = 18, type = COMBAT_EARTHDAMAGE, minDamage = -400, maxDamage = -500, radius = 2, effect = CONST_ME_GROUNDSHAKER, target = false}, + {name ="combat", interval = 2000, chance = 14, type = COMBAT_HOLYDAMAGE, minDamage = -290, maxDamage = -360, length = 5, spread = 3, effect = CONST_ME_BLOCKHIT, target = false} +} + +monster.defenses = { + defense = 86, + armor = 86 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 30}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 55} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/falcon_paladin.lua b/data/monster/undeads/falcon_paladin.lua new file mode 100644 index 00000000000..e8be2d7b24e --- /dev/null +++ b/data/monster/undeads/falcon_paladin.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Falcon Paladin") +local monster = {} + +monster.description = "a falcon paladin" +monster.experience = 6544 +monster.outfit = { + lookType = 1071, + lookHead = 57, + lookBody = 94, + lookLegs = 38, + lookFeet = 86, + lookAddons = 2, + lookMount = 0 +} + +monster.raceId = 1647 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Falcon Bastion." + } + +monster.health = 8500 +monster.maxHealth = 8500 +monster.race = "blood" +monster.corpse = 32558 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Uuunngh!", yell = false} +} + +monster.loot = { + {name = "Platinum Coin", chance = 90000, maxCount = 5}, + {name = "Small Diamond", chance = 41000, maxCount = 2}, + {name = "Great Spirit Potion", chance = 41000, maxCount = 2}, + {name = "Small Emerald", chance = 40000, maxCount = 2}, + {name = "Small Amethyst", chance = 40000, maxCount = 3}, + {name = "Assassin Star", chance = 25700, maxCount = 10}, + {name = "Small Ruby", chance = 20700, maxCount = 2}, + {name = "Small Topaz", chance = 20100, maxCount = 2}, + {name = "Onyx Arrow", chance = 14000, maxCount = 15}, + {name = "Red Gem", chance = 7500, maxCount = 3}, + {name = "Green Gem", chance = 4880}, + {name = "Violet Gem", chance = 4180}, + {id = 7633, chance = 2260}, + {name = "Damaged Armor Plates", chance = 1120}, + {name = "Falcon Crest", chance = 730}, + {name = "Golden Armor", chance = 310}, + {name = "Mastermind Shield", chance = 310} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250}, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_PHYSICALDAMAGE, minDamage = -400, maxDamage = -550, range = 5, shootEffect = CONST_ANI_ROYALSPEAR, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = 500, range = 5, shootEffect = CONST_ANI_BOLT, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -350, maxDamage = -450, range = 7, radius = 2, shootEffect = CONST_ANI_POWERBOLT, effect = CONST_ME_ENERGYHIT, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -250, maxDamage = -350, length = 5, spread = 3, effect = CONST_ME_PURPLEENERGY, target = false} +} + +monster.defenses = { + defense = 50, + armor = 82 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 55} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/flimsy_lost_soul.lua b/data/monster/undeads/flimsy_lost_soul.lua new file mode 100644 index 00000000000..04e74561662 --- /dev/null +++ b/data/monster/undeads/flimsy_lost_soul.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Flimsy Lost Soul") +local monster = {} + +monster.description = "Flimsy Lost Soul" +monster.experience = 4500 +monster.outfit = { + lookType = 1268, + lookHead = 0, + lookBody = 26, + lookLegs = 0, + lookFeet = 0, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 1864 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Brain Grounds, Netherworld, Zarganash." + } + +monster.health = 4000 +monster.maxHealth = 4000 +monster.race = "undead" +monster.corpse = 37445 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 2}, + {name = "lost soul", chance = 30300}, + {name = "wand of cosmic energy", chance = 5220}, + {name = "springsprout rod", chance = 3830}, + {name = "death toll", chance = 3540}, + {name = "terra rod", chance = 3030}, + {name = "hailstorm rod", chance = 2830}, + {name = "ensouled essence", chance = 2260}, + {name = "necklace of the deep", chance = 1760}, + {name = "cursed bone", chance = 1570}, + {name = "wand of starstorm", chance = 1520}, + {name = "glacial rod", chance = 960}, + {name = "wand of voodoo", chance = 330} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -500}, + {name ="combat", interval = 1700, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -150, maxDamage = -550, radius = 3, shootEffect = CONST_ANI_ENVENOMEDARROW, target = true}, + {name ="combat", interval = 1700, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -150, maxDamage = -550, length = 4, spread = 3, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 1700, chance = 35, type = COMBAT_DEATHDAMAGE, minDamage = -150, maxDamage = -550, radius = 3, effect = CONST_ME_MORTAREA, target = false} +} + +monster.defenses = { + defense = 40, + armor = 79 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -20}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/freakish_lost_soul.lua b/data/monster/undeads/freakish_lost_soul.lua new file mode 100644 index 00000000000..a76d7ba8970 --- /dev/null +++ b/data/monster/undeads/freakish_lost_soul.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Freakish Lost Soul") +local monster = {} + +monster.description = "Freakish Lost Soul" +monster.experience = 7020 +monster.outfit = { + lookType = 1268, + lookHead = 0, + lookBody = 112, + lookLegs = 0, + lookFeet = 0, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 1866 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Brain Grounds, Netherworld, Zarganash." + } + +monster.health = 7000 +monster.maxHealth = 7000 +monster.race = "undead" +monster.corpse = 37445 +monster.speed = 260 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 10000, maxCount = 3}, + {name = "lost soul", chance = 45240}, + {name = "death toll", chance = 6250}, + {name = "emerald bangle", chance = 5980}, + {name = "gemmed figurine", chance = 3800}, + {name = "ensouled essence", chance = 2720}, + {id = 26185, chance = 1220}, + {name = "silver hand mirror", chance = 1090}, + {name = "ornate crossbow", chance = 1090}, + {name = "crystal crossbow", chance = 270} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -500}, + {name ="combat", interval = 1700, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -550, radius = 3, shootEffect = CONST_ANI_ENVENOMEDARROW, target = true}, + {name ="combat", interval = 1700, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -150, maxDamage = -550, length = 4, spread = 3, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 1700, chance = 35, type = COMBAT_DEATHDAMAGE, minDamage = -150, maxDamage = -550, radius = 4, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 1700, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -150, maxDamage = -550, radius = 4, effect = CONST_ME_ENERGYAREA, target = false} +} + +monster.defenses = { + defense = 40, + armor = 82 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 60}, + {type = COMBAT_ENERGYDAMAGE, percent = 35}, + {type = COMBAT_EARTHDAMAGE, percent = 70}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -40}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/gazer_spectre.lua b/data/monster/undeads/gazer_spectre.lua new file mode 100644 index 00000000000..025c9f5afd2 --- /dev/null +++ b/data/monster/undeads/gazer_spectre.lua @@ -0,0 +1,139 @@ +local mType = Game.createMonsterType("Gazer Spectre") +local monster = {} + +monster.description = "a Gazer Spectre" +monster.experience = 4200 +monster.outfit = { + lookType = 1122, + lookHead = 94, + lookBody = 20, + lookLegs = 77, + lookFeet = 20, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1725 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Haunted Temple, Buried Cathedral." + } + +monster.health = 4500 +monster.maxHealth = 4500 +monster.race = "blood" +monster.corpse = 34805 +monster.speed = 390 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Deathhh... is... a.... doooor!!", yell = false}, + {text = "Tiiimeee... is... a... windowww!", yell = false} +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 5}, + {name = "Brown Crystal Splinter", chance = 900}, + {name = "Red Crystal Fragment", chance = 8500}, + {name = "Small Enchanted Ruby", chance = 7500}, + {name = "Small Diamond", chance = 6000}, + {name = "Small Sapphire", chance = 5000}, + {name = "Red Gem", chance = 4000}, + {name = "Yellow Gem", chance = 3000}, + {id = 33938, chance = 1100}, + {name = "Wand of Draconia", chance = 3500}, + {name = "Wand of Inferno", chance = 1100}, + {id = 34722, chance = 700}, + {name = "Magma Coat", chance = 900}, + {name = "Prismatic Quartz", chance = 1500}, + {name = "Small Enchanted Emerald", chance = 800}, + {name = "Onyx Chip", chance = 770}, + {name = "Hexagonal Ruby", chance = 500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -250, maxDamage = -480}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -350, range = 7, shootEffect = CONST_ANI_FIRE, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -200, maxDamage = -350, radius = 3, effect = CONST_ME_FIREATTACK, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -250, maxDamage = -430, length = 4, spread = 3, effect = CONST_ME_YELLOWENERGY, target = false} +} + +monster.defenses = { + defense = 78, + armor = 78, + {name ="combat", interval = 2000, chance = 30, type = COMBAT_HEALING, minDamage = 150, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.reflects = { + {type = COMBAT_FIREDAMAGE, percent = 133} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 85}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 70}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -30}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/ghost.lua b/data/monster/undeads/ghost.lua new file mode 100644 index 00000000000..85a5c6c5ff9 --- /dev/null +++ b/data/monster/undeads/ghost.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Ghost") +local monster = {} + +monster.description = "a ghost" +monster.experience = 120 +monster.outfit = { + lookType = 48, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 48 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Ghost Ship, Drefia, Ankrahmun Tombs, Mount Sternum Undead Cave between Thais and Kazordoon, \z + Dark Cathedral, under Treasure Island, Isle of the Kings, Grothmok tunnels (in Dwarven Mines), Goroma, \z + Ramoa, Lich Hell, Upper Spike." + } + +monster.health = 150 +monster.maxHealth = 150 +monster.race = "undead" +monster.corpse = 5993 +monster.speed = 160 +monster.manaCost = 100 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Huh!", yell = false}, + {text = "Shhhhhh", yell = false}, + {text = "Buuuuuh", yell = false} +} + +monster.loot = { + {id = 1962, chance = 1310}, + {name = "stealth ring", chance = 180}, + {name = "morning star", chance = 10610}, + {name = "combat knife", chance = 7002}, + {name = "ancient shield", chance = 860}, + {name = "cape", chance = 8800}, + {name = "shadow herb", chance = 14400}, + {name = "white piece of cloth", chance = 1940}, + {name = "ghostly tissue", chance = 1870} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -80}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -20, maxDamage = -45, range = 1, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/ghoul.lua b/data/monster/undeads/ghoul.lua new file mode 100644 index 00000000000..dc6d240ed92 --- /dev/null +++ b/data/monster/undeads/ghoul.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Ghoul") +local monster = {} + +monster.description = "a ghoul" +monster.experience = 85 +monster.outfit = { + lookType = 18, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 18 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Ancient Temple in the Skeleton area, way to Mintwallin, Old Mintwallin Quest, \z + Alatar Lake, Magician Tower, Mount Sternum Undead Cave, Ghostlands, Hellgate, \z + Maze of Lost Souls, below Point of No Return in Outlaw Camp, Plains of Havoc in Necromant House, \z + Drefia and Drefia's underground caves, Edron ghoul hill, Venore Amazon Camp underground, \z + Venore Swamp Troll cave, Ghostship between Venore and Darashia, Triangle Tower, Dark Cathedral, \z + Ankrahmun tombs, Isle of the Kings, Treasure Island, Nargor Undead Cave, Helheim, Lion's Rock, \z + The Witches' Cliff (only accessible during a quest) and a cave northeast of Ab'Dendriel. \z + Also found behind a wall in both Rookgaard and Paradox Tower, although they cannot be reached." + } + +monster.health = 100 +monster.maxHealth = 100 +monster.race = "blood" +monster.corpse = 5976 +monster.speed = 144 +monster.manaCost = 450 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2050, chance = 5000}, + {name = "gold coin", chance = 68000, maxCount = 30}, + {name = "life ring", chance = 180}, + {id = 2229, chance = 240}, + {name = "viking helmet", chance = 990}, + {name = "scale armor", chance = 1000}, + {name = "worm", chance = 9600, maxCount = 2}, + {name = "brown piece of cloth", chance = 1000}, + {name = "rotten piece of cloth", chance = 14470}, + {name = "ghoul snack", chance = 5130}, + {name = "pile of grave earth", chance = 950}, + {id = 26654, chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -70}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -15, maxDamage = -27, range = 1, radius = 1, effect = CONST_ME_SMALLCLOUDS, target = true} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 9, maxDamage = 15, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/grave_guard.lua b/data/monster/undeads/grave_guard.lua new file mode 100644 index 00000000000..b92412eee61 --- /dev/null +++ b/data/monster/undeads/grave_guard.lua @@ -0,0 +1,121 @@ +local mType = Game.createMonsterType("Grave Guard") +local monster = {} + +monster.description = "a grave guard" +monster.experience = 485 +monster.outfit = { + lookType = 234, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 707 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Horestis Tomb." + } + +monster.health = 720 +monster.maxHealth = 720 +monster.race = "undead" +monster.corpse = 13975 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 30}, + {name = "scarab coin", chance = 4166}, + {name = "daramian waraxe", chance = 1170}, + {name = "grave flower", chance = 70000}, + {id = 6300, chance = 1754}, + {name = "health potion", chance = 20000}, + {name = "mana potion", chance = 20000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -147}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_PHYSICALDAMAGE, radius = 1, effect = CONST_ME_SOUND_BLUE, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/gravedigger.lua b/data/monster/undeads/gravedigger.lua new file mode 100644 index 00000000000..f96cdcae991 --- /dev/null +++ b/data/monster/undeads/gravedigger.lua @@ -0,0 +1,135 @@ +local mType = Game.createMonsterType("Gravedigger") +local monster = {} + +monster.description = "a gravedigger" +monster.experience = 950 +monster.outfit = { + lookType = 558, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 975 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Around the higher level areas of Drefia, \z + including the Drefia Grim Reaper Dungeons and the Drefia Vampire Crypt." + } + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "blood" +monster.corpse = 21279 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 200, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "High Five!", yell = false}, + {text = "scrabble", yell = false}, + {text = "Put it there!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 137}, + {name = "platinum coin", chance = 24470}, + {name = "yellow gem", chance = 800}, + {name = "wand of inferno", chance = 5590}, + {name = "sudden death rune", chance = 7300}, + {name = "skull staff", chance = 130}, + {name = "mysterious voodoo skull", chance = 100}, + {id = 6300, chance = 800}, + {name = "strong health potion", chance = 2260, maxCount = 2}, + {name = "strong mana potion", chance = 3600, maxCount = 2}, + {name = "unholy bone", chance = 9570}, + {name = "pile of grave earth", chance = 6650}, + {name = "safety pin", chance = 6000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -320, condition = {type = CONDITION_POISON, totalDamage = 180, interval = 4000}}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -40, maxDamage = -250, range = 1, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -175, maxDamage = -300, range = 1, shootEffect = CONST_ANI_DEATH, target = false}, + {name ="drunk", interval = 2000, chance = 10, radius = 5, effect = CONST_ME_SMALLCLOUDS, target = false, duration = 4000} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_MAGIC_RED}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 100, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 420, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = -5}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/grim_reaper.lua b/data/monster/undeads/grim_reaper.lua new file mode 100644 index 00000000000..386304c179f --- /dev/null +++ b/data/monster/undeads/grim_reaper.lua @@ -0,0 +1,139 @@ +local mType = Game.createMonsterType("Grim Reaper") +local monster = {} + +monster.description = "a grim reaper" +monster.experience = 5500 +monster.outfit = { + lookType = 300, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 465 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Drefia Grim Reaper Dungeons, deep in Drefia Wyrm Lair (after the Medusa Shield Quest), \z + Edron (Hero Cave), Yalahar (Cemetery Quarter), Oramond Dungeon, \z + Abandoned Sewers and optionally in the Demon Oak Quest." + } + +monster.health = 3900 +monster.maxHealth = 3900 +monster.race = "undead" +monster.corpse = 8955 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 80, + health = 10, + damage = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Death!", yell = false}, + {text = "Come a little closer!", yell = false}, + {text = "The end is near!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 99000, maxCount = 263}, + {name = "platinum coin", chance = 5200, maxCount = 4}, + {id = 2162, chance = 4850}, + {name = "dark shield", chance = 3000}, + {name = "scythe", chance = 9000}, + {name = "orichalcum pearl", chance = 1400, maxCount = 4}, + {id = 6300, chance = 330}, + {name = "demonic essence", chance = 10600}, + {name = "concentrated demonic blood", chance = 35000}, + {name = "nightmare blade", chance = 880}, + {name = "great mana potion", chance = 10000}, + {name = "glacier kilt", chance = 330}, + {name = "ultimate health potion", chance = 9600}, + {name = "skullcracker armor", chance = 270}, + {name = "underworld rod", chance = 910}, + {id = 9810, chance = 2500}, + {name = "mystical hourglass", chance = 5300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -320}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -165, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -350, maxDamage = -720, length = 8, spread = 3, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -300, length = 7, spread = 3, effect = CONST_ME_EXPLOSIONAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -225, maxDamage = -275, radius = 4, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 130, maxDamage = 205, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 450, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 40}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 65}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 80} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/hand_of_cursed_fate.lua b/data/monster/undeads/hand_of_cursed_fate.lua new file mode 100644 index 00000000000..ebfde3be9e2 --- /dev/null +++ b/data/monster/undeads/hand_of_cursed_fate.lua @@ -0,0 +1,146 @@ +local mType = Game.createMonsterType("Hand of Cursed Fate") +local monster = {} + +monster.description = "a hand of cursed fate" +monster.experience = 5000 +monster.outfit = { + lookType = 230, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 281 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Pits of Inferno, The Battlefield, The Arcanum, The Blood Halls and The Crystal Caves." + } + +monster.health = 7500 +monster.maxHealth = 7500 +monster.race = "blood" +monster.corpse = 6312 +monster.speed = 260 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 20, + targetDistance = 1, + runHealth = 3500, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "emerald bangle", chance = 3500}, + {name = "small sapphire", chance = 11000, maxCount = 4}, + {name = "gold coin", chance = 60000, maxCount = 100}, + {name = "gold coin", chance = 60000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 67}, + {name = "platinum coin", chance = 100000, maxCount = 7}, + {name = "violet gem", chance = 700}, + {name = "yellow gem", chance = 5940}, + {name = "energy ring", chance = 3150}, + {name = "platinum amulet", chance = 1005}, + {name = "mind stone", chance = 9090}, + {name = "wand of inferno", chance = 5590}, + {name = "boots of haste", chance = 540}, + {name = "protection amulet", chance = 8740}, + {name = "sudden death rune", chance = 4200, maxCount = 8}, + {name = "skull staff", chance = 700}, + {name = "knight armor", chance = 4550}, + {name = "crown armor", chance = 1400}, + {name = "mysterious voodoo skull", chance = 247}, + {name = "soul orb", chance = 31111}, + {id = 6300, chance = 1750}, + {name = "demonic essence", chance = 12000}, + {name = "concentrated demonic blood", chance = 30000, maxCount = 4}, + {name = "assassin star", chance = 7692, maxCount = 5}, + {name = "abyss hammer", chance = 495}, + {name = "great mana potion", chance = 19990, maxCount = 2}, + {name = "ultimate health potion", chance = 18000}, + {name = "gold ingot", chance = 700} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -520, condition = {type = CONDITION_POISON, totalDamage = 380, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -920, range = 1, target = false}, + {name ="drunk", interval = 2000, chance = 10, radius = 4, effect = CONST_ME_SMALLCLOUDS, target = false, duration = 3000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -220, maxDamage = -880, range = 1, effect = CONST_ME_SMALLCLOUDS, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="speed", interval = 2000, chance = 15, speedChange = 1000, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000}, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_MAGIC_BLUE}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 100, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/honour_guard.lua b/data/monster/undeads/honour_guard.lua new file mode 100644 index 00000000000..92d6e2d74ab --- /dev/null +++ b/data/monster/undeads/honour_guard.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Honour Guard") +local monster = {} + +monster.description = "an honour guard" +monster.experience = 55 +monster.outfit = { + lookType = 298, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 712 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 2, + Locations = "Desert north of Ankrahmun." + } + +monster.health = 85 +monster.maxHealth = 85 +monster.race = "undead" +monster.corpse = 2843 +monster.speed = 154 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Horestis curse upon you!", yell = false}, + {text = "Vengeance!", yell = false}, + {text = "Thy punishment is at hand!", yell = false}, + {text = "For the pharao!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 15}, + {name = "scarab coin", chance = 2600}, + {name = "mace", chance = 3760}, + {id = 2419, chance = 1640}, + {name = "brown mushroom", chance = 6120, maxCount = 2}, + {name = "pelvis bone", chance = 8700} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -40}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -5, maxDamage = -13, range = 1, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 5}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/infernal_phantom.lua b/data/monster/undeads/infernal_phantom.lua new file mode 100644 index 00000000000..1569c0794ae --- /dev/null +++ b/data/monster/undeads/infernal_phantom.lua @@ -0,0 +1,134 @@ +local mType = Game.createMonsterType("Infernal Phantom") +local monster = {} + +monster.description = "a infernal phantom" +monster.experience = 22880 +monster.outfit = { + lookType = 1298, + lookHead = 114, + lookBody = 80, + lookLegs = 94, + lookFeet = 78, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1933 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 5000, + FirstUnlock = 25, + SecondUnlock = 2500, + CharmsPoints = 100, + Stars = 5, + Occurrence = 0, + Locations = "Claustrophobic Inferno." + } + +monster.health = 26000 +monster.maxHealth = 26000 +monster.race = "undead" +monster.corpse = 38960 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ashes to ashes.", yell = false}, + {text = "Burn, baby! Burn!", yell = false} +} + +monster.loot = { + {name = "crystal coin", chance = 70540}, + {name = "platinum coin", chance = 82220, maxCount = 32}, + {name = "terra rod", chance = 21920}, + {name = "ultimate health potion", chance = 32220, maxCount = 7}, + {name = "hailstorm rod", chance = 71920}, + {name = "fire axe", chance = 18920}, + {name = "titan axe", chance = 18920}, + {name = "chaos mace", chance = 12920}, + {name = "glorious axe", chance = 22920}, + {name = "underworld rod", chance = 32920}, + {name = "springsprout rod", chance = 36920}, + {name = "wand of starstorm", chance = 36920}, + {name = "wand of voodoo", chance = 24920}, + {name = "warrior's axe", chance = 17920}, + {id = 38974, chance = 11560}, -- Infernal hearth + {id = 38981, chance = 7560}, -- Infernal robe + {id = 38944, chance = 50} -- Bag you desire +} + +monster.attacks = { + {name ="combat", interval = 3000, chance = 24, type = COMBAT_DEATHDAMAGE, minDamage = -550, maxDamage = -1000, range = 7, radius = 3, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -650, maxDamage = -1000, range = 7, shootEffect = CONST_ANI_FIRE, effect = CONST_ME_FIREAREA, target = true}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -450, maxDamage = -1100, radius = 4, effect = CONST_ME_FIREAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -800, maxDamage = -1250, length = 6, effect = CONST_ME_EXPLOSIONHIT, target = false}, +} + +monster.defenses = { + defense = 75, + armor = 100 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 1}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -20}, + {type = COMBAT_HOLYDAMAGE , percent = -20}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) \ No newline at end of file diff --git a/data/monster/undeads/knight's_apparition.lua b/data/monster/undeads/knight's_apparition.lua new file mode 100644 index 00000000000..0a01de75774 --- /dev/null +++ b/data/monster/undeads/knight's_apparition.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Knight's Apparition") +local monster = {} + +monster.description = "a knight's apparition" +monster.experience = 28600 +monster.outfit = { + lookType = 131, + lookHead = 19, + lookBody = 76, + lookLegs = 74, + lookFeet = 114, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1947 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 5000, + FirstUnlock = 25, + SecondUnlock = 2500, + CharmsPoints = 100, + Stars = 5, + Occurrence = 0, + Locations = "Mirrored Nightmare." + } + +monster.health = 25000 +monster.maxHealth = 25000 +monster.race = "blood" +monster.corpse = 6080 +monster.speed = 235 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I am you. Just better!", yell = false}, + {text = "I'll take your place when you are gone.", yell = false} +} + +monster.loot = { + {name = "crystal coin", chance = 70540}, + {name = "platinum coin", chance = 81920, maxCount = 33}, + {name = "green gem", chance = 64560}, + {name = "epee", chance = 31920}, + {name = "ultimate health potion", chance = 71920, maxCount = 5}, + {name = "violet gem", chance = 44560}, + {name = "giant sword", chance = 25920}, + {name = "crystal mace", chance = 22920}, + {name = "crown shield", chance = 18920}, + {name = "jade hammer", chance = 15920} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1000}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_ICEDAMAGE, minDamage = -450, maxDamage = -1000, range = 7, radius = 4, shootEffect = CONST_ANI_ICE, effect = CONST_ME_BIGCLOUDS, target = true}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_HOLYDAMAGE, minDamage = -550, maxDamage = -900, radius = 4, effect = CONST_ME_HOLYAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HOLYDAMAGE, minDamage = -750, maxDamage = -1100, range = 7, shootEffect = CONST_ANI_HOLY, effect = CONST_ME_HOLYDAMAGE, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -750, maxDamage = -1100, range = 7, shootEffect = CONST_ANI_SMALLICE, effect = CONST_ME_ICEATTACK, target = true}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_PHYSICALDAMAGE, minDamage = -550, maxDamage = -900, radius = 3, effect = CONST_ME_GROUNDSHAKER, target = false} + -- Chain: const_me-> CONST_ME_BLUE_ENERGY_SPARK, combat_t->COMBAT_ICEDAMAGE +} + +monster.defenses = { + defense = 75, + armor = 100 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 50}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = 40}, + {type = COMBAT_DEATHDAMAGE , percent = -20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) \ No newline at end of file diff --git a/data/monster/undeads/lich.lua b/data/monster/undeads/lich.lua new file mode 100644 index 00000000000..26b957d2334 --- /dev/null +++ b/data/monster/undeads/lich.lua @@ -0,0 +1,150 @@ +local mType = Game.createMonsterType("Lich") +local monster = {} + +monster.description = "a lich" +monster.experience = 900 +monster.outfit = { + lookType = 99, + lookHead = 95, + lookBody = 116, + lookLegs = 119, + lookFeet = 115, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 99 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Ankrahmun Library Tomb, Ancient Ruins Tomb, Oasis Tomb, Mountain Tomb, Drefia, Kharos, \z + Pits of Inferno, Lich Hell in Ramoa, Cemetery Quarter in Yalahar, underground of Fenrock (on the way to Beregar). \z + Can also be seen during an undead raid in Darashia or Carlin." + } + +monster.health = 880 +monster.maxHealth = 880 +monster.race = "undead" +monster.corpse = 6028 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 4 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 80, + health = 10, + damage = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Bonebeast", chance = 10, interval = 2000} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Doomed be the living!", yell = false}, + {text = "Death awaits all!", yell = false}, + {text = "Thy living flesh offends me!", yell = false}, + {text = "Death and Decay!", yell = false}, + {text = "You will endure agony beyond thy death!", yell = false}, + {text = "Pain sweet pain!", yell = false}, + {text = "Come to me my children!", yell = false} +} + +monster.loot = { + {name = "white pearl", chance = 5000}, + {name = "black pearl", chance = 5960, maxCount = 3}, + {name = "gold coin", chance = 100000, maxCount = 139}, + {name = "small emerald", chance = 2230, maxCount = 3}, + {name = "platinum coin", chance = 19720}, + {name = "yellow gem", chance = 690}, + {name = "platinum amulet", chance = 450}, + {id = 2175, chance = 10000}, + {name = "mind stone", chance = 350}, + {name = "ring of healing", chance = 1540}, + {name = "skull staff", chance = 550}, + {name = "strange helmet", chance = 740}, + {name = "ancient shield", chance = 2422}, + {name = "castle shield", chance = 350}, + {name = "blue robe", chance = 150}, + {name = "strong mana potion", chance = 7500}, + {name = "lightning boots", chance = 200}, + {name = "small topaz", chance = 2430, maxCount = 3}, + {name = "maxilla maximus", chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -75}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -140, maxDamage = -190, length = 7, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -300, maxDamage = -400, length = 7, spread = 3, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -200, maxDamage = -245, range = 1, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="speed", interval = 2000, chance = 15, speedChange = -300, range = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 30000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -130, maxDamage = -195, radius = 3, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 80, maxDamage = 100, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 80}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/lost_soul.lua b/data/monster/undeads/lost_soul.lua new file mode 100644 index 00000000000..c0c6cf7ba5c --- /dev/null +++ b/data/monster/undeads/lost_soul.lua @@ -0,0 +1,137 @@ +local mType = Game.createMonsterType("Lost Soul") +local monster = {} + +monster.description = "a lost soul" +monster.experience = 4000 +monster.outfit = { + lookType = 232, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 283 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Pits of Inferno, Formorgar Mines, Helheim, \z + Roshamuul Prison and in The Arcanum (Part of the Inquisition quest)." + } + +monster.health = 5800 +monster.maxHealth = 5800 +monster.race = "undead" +monster.corpse = 6310 +monster.speed = 380 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 450, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Forgive Meee!", yell = false}, + {text = "Mouuuurn meeee!", yell = false}, + {text = "Help meee!", yell = false} +} + +monster.loot = { + {name = "ruby necklace", chance = 1500}, + {name = "white pearl", chance = 10000, maxCount = 3}, + {name = "black pearl", chance = 12000, maxCount = 3}, + {name = "gold coin", chance = 100000, maxCount = 198}, + {name = "platinum coin", chance = 100000, maxCount = 7}, + {name = "red gem", chance = 15000}, + {name = "stone skin amulet", chance = 2780}, + {name = "blank rune", chance = 35250, maxCount = 3}, + {name = "skull staff", chance = 850}, + {name = "tower shield", chance = 740}, + {name = "skull helmet", chance = 170}, + {name = "silver goblet", chance = 4950}, + {name = "soul orb", chance = 15000}, + {id = 6300, chance = 2170}, + {name = "demonic essence", chance = 7500}, + {name = "skeleton decoration", chance = 1250}, + {name = "haunted blade", chance = 740}, + {name = "titan axe", chance = 1000}, + {name = "great mana potion", chance = 14200, maxCount = 2}, + {name = "great health potion", chance = 8800, maxCount = 2}, + {id = 9810, chance = 3500}, + {name = "unholy bone", chance = 33010} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -420}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -40, maxDamage = -210, length = 3, spread = 0, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="speed", interval = 2000, chance = 20, speedChange = -800, radius = 6, effect = CONST_ME_SMALLCLOUDS, target = false, duration = 4000} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = -20}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/mean_lost_soul.lua b/data/monster/undeads/mean_lost_soul.lua new file mode 100644 index 00000000000..cdad53b86a4 --- /dev/null +++ b/data/monster/undeads/mean_lost_soul.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Mean Lost Soul") +local monster = {} + +monster.description = "Mean Lost Soul" +monster.experience = 5580 +monster.outfit = { + lookType = 1268, + lookHead = 0, + lookBody = 14, + lookLegs = 0, + lookFeet = 0, + lookAddons = 1, + lookMount = 0 +} + +monster.raceId = 1865 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Brain Grounds, Netherworld, Zarganash." + } + +monster.health = 5000 +monster.maxHealth = 5000 +monster.race = "undead" +monster.corpse = 37445 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 56040}, + {name = "lost soul", chance = 36220}, + {name = "death toll", chance = 4890}, + {name = "skull staff", chance = 4540}, + {name = "machete", chance = 3520}, + {name = "ensouled essence", chance = 2760}, + {name = "fire axe", chance = 1400}, + {name = "ivory comb", chance = 1200}, + {name = "mercenary sword", chance = 1050}, + {name = "haunted blade", chance = 960}, + {name = "warrior's axe", chance = 730}, + {name = "twiceslicer", chance = 310} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -500}, + {name ="combat", interval = 1700, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -300, maxDamage = -550, radius = 3, shootEffect = CONST_ANI_ENVENOMEDARROW, target = true}, + {name ="combat", interval = 1700, chance = 25, type = COMBAT_ENERGYDAMAGE, minDamage = -300, maxDamage = -550, length = 4, spread = 3, effect = CONST_ME_ENERGYHIT, target = false}, + {name ="combat", interval = 1700, chance = 35, type = COMBAT_DEATHDAMAGE, minDamage = -300, maxDamage = -550, radius = 3, effect = CONST_ME_MORTAREA, target = false} +} + +monster.defenses = { + defense = 40, + armor = 82 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 55}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -30}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/mould_phantom.lua b/data/monster/undeads/mould_phantom.lua new file mode 100644 index 00000000000..04eade2edc7 --- /dev/null +++ b/data/monster/undeads/mould_phantom.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Mould Phantom") +local monster = {} + +monster.description = "a mould phantom" +monster.experience = 23920 +monster.outfit = { + lookType = 1298, + lookHead = 106, + lookBody = 60, + lookLegs = 131, + lookFeet = 116, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1945 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 5000, + FirstUnlock = 25, + SecondUnlock = 2500, + CharmsPoints = 100, + Stars = 5, + Occurrence = 0, + Locations = "Rotten Wasteland." + } + +monster.health = 28000 +monster.maxHealth = 28000 +monster.race = "undead" +monster.corpse = 38968 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Everything decomposes.", yell = false}, + {text = "I love the smell of rotten flesh.", yell = false}, + {text = "The earth will take you back.", yell = false} +} + +monster.loot = { + {name = "crystal coin", chance = 70540}, + {name = "gold ingot", chance = 54560}, + {name = "violet gem", chance = 74560}, + {name = "green gem", chance = 64560}, + {name = "blue gem", chance = 54560}, + {name = "wand of starstorm", chance = 31920}, + {name = "wand of voodoo", chance = 21920}, + {name = "ornate crossbow", chance = 41920}, + {name = "wand of defiance", chance = 21920, maxCount = 3}, + {id = 26185, chance = 28920}, + {id = 26198, chance = 28920}, + {id = 38976, chance = 12920}, + {name = "crystal crossbow", chance = 1920}, + {id = 38944, chance = 50} +} + +monster.attacks = { + {name ="combat", interval = 3000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -650, maxDamage = -1000, radius = 4, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -650, maxDamage = -1000, range = 7, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_SMALLPLANTS, target = true}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HOLYDAMAGE, minDamage = -800, maxDamage = -1100, range = 7, shootEffect = CONST_ANI_SMALLHOLY, effect = CONST_ME_HOLYDAMAGE, target = true} + -- Chain: const_me-> CONST_ME_GREEN_ENERGY_SPARK, combat_t->COMBAT_EARTHDAMAGE +} + +monster.defenses = { + defense = 75, + armor = 100 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) \ No newline at end of file diff --git a/data/monster/undeads/mummy.lua b/data/monster/undeads/mummy.lua new file mode 100644 index 00000000000..07e6122c56f --- /dev/null +++ b/data/monster/undeads/mummy.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Mummy") +local monster = {} + +monster.description = "a mummy" +monster.experience = 150 +monster.outfit = { + lookType = 65, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 65 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Drefia, Darama's Dark Pyramid, Draconia, Mount Sternum Undead Cave, Green Claw Swamp, \z + Venore Amazon Camp underground, Helheim, Upper Spike, all Tombs, Dark Cathedral, Lion's Rock." + } + +monster.health = 240 +monster.maxHealth = 240 +monster.race = "undead" +monster.corpse = 6004 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I will ssswallow your sssoul!", yell = false}, + {text = "Mort ulhegh dakh visss.", yell = false}, + {text = "Flesssh to dussst!", yell = false}, + {text = "I will tassste life again!", yell = false}, + {text = "Ahkahra exura belil mort!", yell = false}, + {text = "Yohag Sssetham!", yell = false} +} + +monster.loot = { + {id = 2124, chance = 1500}, + {name = "silver brooch", chance = 4000}, + {name = "black pearl", chance = 1000}, + {name = "gold coin", chance = 38000, maxCount = 80}, + {name = "strange talisman", chance = 5000}, + {id = 2162, chance = 5800}, + {name = "silver amulet", chance = 100}, + {name = "poison dagger", chance = 450}, + {name = "black shield", chance = 170}, + {name = "worm", chance = 19000, maxCount = 3}, + {name = "yellow piece of cloth", chance = 900}, + {name = "gauze bandage", chance = 10000}, + {name = "mini mummy", chance = 10}, + {name = "flask of embalming fluid", chance = 11690} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -85, condition = {type = CONDITION_POISON, totalDamage = 4, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -30, maxDamage = -40, range = 1, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="speed", interval = 2000, chance = 15, speedChange = -226, range = 7, effect = CONST_ME_MAGIC_RED, target = true, duration = 10000} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/paladin's_apparition.lua b/data/monster/undeads/paladin's_apparition.lua new file mode 100644 index 00000000000..9521de0b7f7 --- /dev/null +++ b/data/monster/undeads/paladin's_apparition.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Paladin's Apparition") +local monster = {} + +monster.description = "a paladin's apparition" +monster.experience = 28600 +monster.outfit = { + lookType = 129, + lookHead = 57, + lookBody = 42, + lookLegs = 114, + lookFeet = 114, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1948 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 5000, + FirstUnlock = 25, + SecondUnlock = 2500, + CharmsPoints = 100, + Stars = 5, + Occurrence = 0, + Locations = "Mirrored Nightmare." + } + +monster.health = 25000 +monster.maxHealth = 25000 +monster.race = "blood" +monster.corpse = 6080 +monster.speed = 235 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I could be your evil twin!", yell = false}, + {text = "I'll take your place when you are gone.", yell = false} +} + +monster.loot = { + {name = "crystal coin", chance = 70540}, + {name = "platinum coin", chance = 81920, maxCount = 33}, + {name = "violet gem", chance = 64560}, + {name = "green gem", chance = 54560}, + {name = "blue gem", chance = 44560}, + {name = "warrior helmet", chance = 31920}, + {name = "great spirit potion", chance = 71920, maxCount = 5}, + {name = "glacier mask", chance = 31920}, + {name = "wood cape", chance = 21920}, + {name = "skull helmet", chance = 18920}, + {id = 26185, chance = 29000} -- Ring of blue plasma +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -800}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_ICEDAMAGE, minDamage = -750, maxDamage = -1000, range = 7, radius = 4, shootEffect = CONST_ANI_ICE, effect = CONST_ME_BIGCLOUDS, target = true}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_HOLYDAMAGE, minDamage = -750, maxDamage = -1000, radius = 4, effect = CONST_ME_HOLYAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HOLYDAMAGE, minDamage = -650, maxDamage = -1100, range = 7, shootEffect = CONST_ANI_HOLY, effect = CONST_ME_HOLYDAMAGE, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -550, maxDamage = -1100, range = 7, shootEffect = CONST_ANI_SMALLICE, effect = CONST_ME_ICEATTACK, target = true}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_PHYSICALDAMAGE, minDamage = -650, maxDamage = -900, range = 7, shootEffect = CONST_ANI_DIAMONDARROW, effect = CONST_ME_DRAWBLOOD, target = true} + -- Chain: const_me-> CONST_ME_BLUE_ENERGY_SPARK, combat_t->COMBAT_ICEDAMAGE +} + +monster.defenses = { + defense = 75, + armor = 100 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 20}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -11}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 40}, + {type = COMBAT_DEATHDAMAGE , percent = -20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) \ No newline at end of file diff --git a/data/monster/undeads/pirate_ghost.lua b/data/monster/undeads/pirate_ghost.lua new file mode 100644 index 00000000000..a59a0cf170d --- /dev/null +++ b/data/monster/undeads/pirate_ghost.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Pirate Ghost") +local monster = {} + +monster.description = "a pirate ghost" +monster.experience = 250 +monster.outfit = { + lookType = 196, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 257 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Drefia, Goroma, Nargor Undead Cave, hidden caves under Treasure Island, \z + single spawn at Liberty Bay ruins, Chyllfroest (unreachable)." + } + +monster.health = 275 +monster.maxHealth = 275 +monster.race = "undead" +monster.corpse = 5566 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Yooh Ho Hooh Ho!", yell = false}, + {text = "Hell is waiting for You!", yell = false}, + {text = "It's alive!", yell = false}, + {text = "The curse! Aww the curse!", yell = false}, + {text = "You will not get my treasure!", yell = false} +} + +monster.loot = { + {id = 1951, chance = 910}, + {name = "gold coin", chance = 48000, maxCount = 67}, + {name = "stealth ring", chance = 650}, + {name = "spike sword", chance = 130}, + {name = "red robe", chance = 130}, + {name = "tattered piece of robe", chance = 4300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100, condition = {type = CONDITION_POISON, totalDamage = 40, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -40, maxDamage = -80, radius = 1, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -50, maxDamage = -65, range = 7, radius = 3, effect = CONST_ME_SOUND_RED, target = true} +} + +monster.defenses = { + defense = 0, + armor = 0, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 40, maxDamage = 70, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/pirate_skeleton.lua b/data/monster/undeads/pirate_skeleton.lua new file mode 100644 index 00000000000..cc7da2ab2f4 --- /dev/null +++ b/data/monster/undeads/pirate_skeleton.lua @@ -0,0 +1,117 @@ +local mType = Game.createMonsterType("Pirate Skeleton") +local monster = {} + +monster.description = "a pirate skeleton" +monster.experience = 85 +monster.outfit = { + lookType = 195, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 256 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Nargor Undead Cave, Goroma, Treasure Island, Drefia, The Cave, Chyllfroest." + } + +monster.health = 190 +monster.maxHealth = 190 +monster.race = "undead" +monster.corpse = 6070 +monster.speed = 176 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 20, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 48000, maxCount = 25}, + {id = 2229, chance = 4460}, + {id = 2230, chance = 4250}, + {id = 2231, chance = 5140}, + {id = 2376, chance = 550}, + {name = "short sword", chance = 1003}, + {name = "bone club", chance = 960}, + {name = "spooky blue eye", chance = 4730} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -50} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/putrid_mummy.lua b/data/monster/undeads/putrid_mummy.lua new file mode 100644 index 00000000000..68851fdec1e --- /dev/null +++ b/data/monster/undeads/putrid_mummy.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Putrid Mummy") +local monster = {} + +monster.description = "a putrid mummy" +monster.experience = 900 +monster.outfit = { + lookType = 976, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1415 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Caverna Exanima." + } + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "undead" +monster.corpse = 6004 +monster.speed = 150 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Come to mummy!", yell = false}, + {text = "We will make you one of us!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 60870, maxCount = 62}, + {id = 13472, chance = 3840}, + {name = "black pearl", chance = 1280}, + {name = "little bowl of myrrh", chance = 13550}, + {name = "single human eye", chance = 8950}, + {name = "green gem", chance = 3070}, + {name = "green bandage", chance = 1100}, + {name = "scarab coin", chance = 8180, maxCount = 3}, + {name = "poison dagger", chance = 1530} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -100, maxDamage = -150, range = 1, shootEffect = CONST_ANI_EARTH, effect = CONST_ME_CARNIPHILA, target = true}, + {name ="speed", interval = 2000, chance = 15, speedChange = -226, range = 7, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_MORTAREA, target = true, duration = 10000} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 100, maxDamage = 150, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/ripper_spectre.lua b/data/monster/undeads/ripper_spectre.lua new file mode 100644 index 00000000000..7a370bcb398 --- /dev/null +++ b/data/monster/undeads/ripper_spectre.lua @@ -0,0 +1,135 @@ +local mType = Game.createMonsterType("Ripper Spectre") +local monster = {} + +monster.description = "a ripper spectre" +monster.experience = 3500 +monster.outfit = { + lookType = 1119, + lookHead = 101, + lookBody = 39, + lookLegs = 61, + lookFeet = 39, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1724 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Haunted Cellar, Buried Cathedral." + } + +monster.health = 3800 +monster.maxHealth = 3800 +monster.race = "blood" +monster.corpse = 34664 +monster.speed = 380 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 100000, maxCount = 5}, + {name = "Great Spirit Potion", chance = 30910, maxCount = 2}, + {name = "Two Handed Sword", chance = 16500}, + {name = "Terra Rod", chance = 4780}, + {name = "Silver Brooch", chance = 15190}, + {name = "Emerald Bangle", chance = 14740}, + {name = "Twin Hooks", chance = 1170}, + {name = "Springsprout Rod", chance = 1210}, + {id = 34721, chance = 1890}, + {name = "Coral Brooch", chance = 1330}, + {name = "Serpent Sword", chance = 1950}, + {name = "Hexagonal Ruby", chance = 800}, + {name = "Assassin Dagger", chance = 970}, + {name = "Spike Sword", chance = 530}, + {name = "Wyvern Fang", chance = 120} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -370}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -200, maxDamage = -390, radius = 4, effect = CONST_ME_GREEN_RINGS, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -320, maxDamage = -460, radius = 4, effect = CONST_ME_EXPLOSIONAREA, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -200, maxDamage = -340, length = 3, spread = 0, effect = CONST_ME_GROUNDSHAKER, target = false} +} + +monster.defenses = { + defense = 69, + armor = 69, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 150, maxDamage = 200, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.reflects = { + {type = COMBAT_EARTHDAMAGE, percent = 133} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/rot_elemental.lua b/data/monster/undeads/rot_elemental.lua new file mode 100644 index 00000000000..0ebb04bf91c --- /dev/null +++ b/data/monster/undeads/rot_elemental.lua @@ -0,0 +1,134 @@ +local mType = Game.createMonsterType("Rot Elemental") +local monster = {} + +monster.description = "a rot elemental" +monster.experience = 750 +monster.outfit = { + lookType = 615, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1055 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Rathleton Sewers, Glooth Factory, Lower Rathleton, Oramond/Western Plains, Jaccus Maxxen's Dungeon." + } + +monster.health = 850 +monster.maxHealth = 850 +monster.race = "venom" +monster.corpse = 23481 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 2 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "*glibb*", yell = false}, + {text = "*splib*", yell = false} +} + +monster.loot = { + {id = 2148, chance = 100000, maxCount = 80}, + {id = 2152, chance = 10390}, + {id = 7588, chance = 10310}, + {id = 7589, chance = 9990}, + {id = 23553, chance = 4320}, + {id = 2168, chance = 1630}, + {id = 2146, chance = 1110}, + {id = 9970, chance = 1140, maxCount = 2}, + {id = 2149, chance = 940, maxCount = 2}, + {id = 2155, chance = 80}, + {id = 23554, chance = 130}, + {id = 23551, chance = 60}, + {id = 23529, chance = 460} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, skill = 58, attack = 50, condition = {type = CONDITION_POISON, totalDamage = 280, interval = 4000}}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_EARTHDAMAGE, minDamage = -150, maxDamage = -250, range = 7, radius = 3, shootEffect = CONST_ANI_GLOOTHSPEAR, effect = CONST_ME_POISONAREA, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -150, maxDamage = -230, length = 6, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -200, maxDamage = -300, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true}, + {name ="rot elemental paralyze", interval = 2000, chance = 11, target = false} +} + +monster.defenses = { + defense = 15, + armor = 10, + {name ="combat", interval = 2000, chance = 7, type = COMBAT_HEALING, minDamage = 40, maxDamage = 60, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 9, speedChange = 470, effect = CONST_ME_SMOKE, target = false, duration = 7000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 20}, + {type = COMBAT_DEATHDAMAGE , percent = 20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/skeleton.lua b/data/monster/undeads/skeleton.lua new file mode 100644 index 00000000000..ec026e582b3 --- /dev/null +++ b/data/monster/undeads/skeleton.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Skeleton") +local monster = {} + +monster.description = "a skeleton" +monster.experience = 35 +monster.outfit = { + lookType = 33, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 33 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "In many dungeons around Tibia, like the Ancient Temple and Ghostlands. \z + Also found in Rookgaard tombs and north east of Port Hope, in the jungle of Tiquanda, \z + beneath Fenrock and in the desert Tombs, Vengoth Castle." + } + +monster.health = 50 +monster.maxHealth = 50 +monster.race = "undead" +monster.corpse = 5972 +monster.speed = 154 +monster.manaCost = 300 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {id = 2050, chance = 10000}, + {id = 2050, chance = 9880}, + {name = "gold coin", chance = 43900, maxCount = 10}, + {id = 2230, chance = 49100}, + {id = 2376, chance = 1940}, + {name = "hatchet", chance = 4850}, + {name = "mace", chance = 4850}, + {name = "viking helmet", chance = 7520}, + {name = "brass shield", chance = 2090}, + {name = "pelvis bone", chance = 9940}, + {id = 26654, chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -20}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -7, maxDamage = -13, range = 1, target = false} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/skeleton_elite_warrior.lua b/data/monster/undeads/skeleton_elite_warrior.lua new file mode 100644 index 00000000000..bbb00cbf8ed --- /dev/null +++ b/data/monster/undeads/skeleton_elite_warrior.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Skeleton Elite Warrior") +local monster = {} + +monster.description = "a skeleton elite warrior" +monster.experience = 4500 +monster.outfit = { + lookType = 298, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1674 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Deep Desert." + } + +monster.health = 7800 +monster.maxHealth = 7800 +monster.race = "undead" +monster.corpse = 5972 +monster.speed = 155 +monster.manaCost = 350 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 43500, maxCount = 15}, + {id = 2230, chance = 50000}, + {name = "white mushroom", chance = 24000, maxCount = 3}, + {name = "Soul Orb", chance = 43500, maxCount = 5}, + {name = "Knight Axe", chance = 3250}, + {name = "pelvis bone", chance = 2630, maxCount = 10}, + {name = "Unholy Bone", chance = 2630, maxCount = 5}, + {name = "Skull Helmet", chance = 350}, + {name = "Ruthless Axe", chance = 150} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = -100, maxDamage = -700}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -300, maxDamage = -480, range = 1, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 1500, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -380, maxDamage = -520, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false} +} + +monster.defenses = { + defense = 15, + armor = 75 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/skeleton_warrior.lua b/data/monster/undeads/skeleton_warrior.lua new file mode 100644 index 00000000000..33135b0b2a0 --- /dev/null +++ b/data/monster/undeads/skeleton_warrior.lua @@ -0,0 +1,117 @@ +local mType = Game.createMonsterType("Skeleton Warrior") +local monster = {} + +monster.description = "a skeleton warrior" +monster.experience = 45 +monster.outfit = { + lookType = 298, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 446 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Island of Destiny, Drefia, Ghostland and beneath Fenrock." + } + +monster.health = 65 +monster.maxHealth = 65 +monster.race = "undead" +monster.corpse = 5972 +monster.speed = 154 +monster.manaCost = 350 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 43500, maxCount = 10}, + {id = 2230, chance = 50000}, + {id = 2376, chance = 1500}, + {name = "mace", chance = 2000}, + {name = "white mushroom", chance = 24000, maxCount = 3}, + {name = "brown mushroom", chance = 1700}, + {name = "pelvis bone", chance = 10630} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -30}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -7, maxDamage = -13, range = 1, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/sorcerer's_apparition.lua b/data/monster/undeads/sorcerer's_apparition.lua new file mode 100644 index 00000000000..d223b00a96f --- /dev/null +++ b/data/monster/undeads/sorcerer's_apparition.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Sorcerer's Apparition") +local monster = {} + +monster.description = "a sorcerer's apparition" +monster.experience = 28600 +monster.outfit = { + lookType = 138, + lookHead = 95, + lookBody = 114, + lookLegs = 52, + lookFeet = 76, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1949 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 5000, + FirstUnlock = 25, + SecondUnlock = 2500, + CharmsPoints = 100, + Stars = 5, + Occurrence = 0, + Locations = "Mirrored Nightmare." + } + +monster.health = 25000 +monster.maxHealth = 25000 +monster.race = "blood" +monster.corpse = 6081 +monster.speed = 235 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I'll take your place when you are gone.", yell = false} +} + +monster.loot = { + {name = "crystal coin", chance = 70540}, + {name = "platinum coin", chance = 81920, maxCount = 33}, + {name = "great mana potion", chance = 71920, maxCount = 5}, + {id = 7632, chance = 54560}, -- Giant shimmering pearl + {id = 7633, chance = 54560}, -- Giant shimmering pearl + {name = "blue gem", chance = 64560}, + {id = 26189, chance = 29000}, -- Ring of red plasma + {name = "wand of voodoo", chance = 31920}, + {name = "wand of defiance", chance = 25920}, + {name = "wand of everblazing", chance = 20920}, + {name = "alloy legs", chance = 17920}, + {id = 26185, chance = 29000}, -- Ring of blue plasma + {id = 26187, chance = 29000}, -- Ring of green plasma + {name = "wand of starstorm", chance = 11920} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -800}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_ICEDAMAGE, minDamage = -750, maxDamage = -900, range = 7, radius = 4, shootEffect = CONST_ANI_ICE, effect = CONST_ME_BIGCLOUDS, target = true}, + {name ="combat", interval = 2000, chance = 17, type = COMBAT_HOLYDAMAGE, minDamage = -750, maxDamage = -900, radius = 4, effect = CONST_ME_HOLYAREA, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HOLYDAMAGE, minDamage = -750, maxDamage = -1100, range = 7, shootEffect = CONST_ANI_HOLY, effect = CONST_ME_HOLYDAMAGE, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -750, maxDamage = -1100, range = 7, shootEffect = CONST_ANI_SMALLICE, effect = CONST_ME_ICEATTACK, target = true}, + {name ="combat", interval = 2000, chance = 13, type = COMBAT_ICEDAMAGE, minDamage = -750, maxDamage = -900, radius = 3, effect = CONST_ME_ICEATTACK, target = false} + -- Chain: const_me-> CONST_ME_BLUE_ENERGY_SPARK, combat_t->COMBAT_ICEDAMAGE +} + +monster.defenses = { + defense = 75, + armor = 100 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -20}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 30}, + {type = COMBAT_HOLYDAMAGE , percent = 40}, + {type = COMBAT_DEATHDAMAGE , percent = -20} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) \ No newline at end of file diff --git a/data/monster/undeads/souleater.lua b/data/monster/undeads/souleater.lua new file mode 100644 index 00000000000..c004b199422 --- /dev/null +++ b/data/monster/undeads/souleater.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Souleater") +local monster = {} + +monster.description = "a souleater" +monster.experience = 1300 +monster.outfit = { + lookType = 355, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 675 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Razzachai, Northern Zao Plantations, Souleater Mountains, Deeper Banuta." + } + +monster.health = 1100 +monster.maxHealth = 1100 +monster.race = "undead" +monster.corpse = 12631 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Life is such a fickle thing!", yell = false}, + {text = "I will devour your soul.", yell = false}, + {text = "Souuuls!", yell = false}, + {text = "I will feed on you.", yell = false}, + {text = "Aaaahh", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 33400, maxCount = 100}, + {name = "gold coin", chance = 33400, maxCount = 100}, + {name = "platinum coin", chance = 49610, maxCount = 6}, + {name = "necrotic rod", chance = 980}, + {name = "wand of cosmic energy", chance = 910}, + {name = "spirit container", chance = 140}, + {id = 6300, chance = 300}, + {name = "great mana potion", chance = 8000}, + {name = "ultimate health potion", chance = 9400}, + {name = "souleater trophy", chance = 20}, + {name = "lizard essence", chance = 15250}, + {name = "ectoplasmic sushi", chance = 2000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -210}, + {name ="combat", interval = 2000, chance = 100, type = COMBAT_ICEDAMAGE, minDamage = -50, maxDamage = -100, range = 7, shootEffect = CONST_ANI_SMALLICE, target = true}, + {name ="souleater drown", interval = 2000, chance = 10, target = false}, + {name ="souleater wave", interval = 2000, chance = 10, minDamage = -100, maxDamage = -200, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_LIFEDRAIN, minDamage = -30, maxDamage = -60, radius = 4, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="invisible", interval = 2000, chance = 5, effect = CONST_ME_MAGIC_BLUE}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 120, maxDamage = 125, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 70}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/spectre.lua b/data/monster/undeads/spectre.lua new file mode 100644 index 00000000000..c36cea64111 --- /dev/null +++ b/data/monster/undeads/spectre.lua @@ -0,0 +1,138 @@ +local mType = Game.createMonsterType("Spectre") +local monster = {} + +monster.description = "a spectre" +monster.experience = 2100 +monster.outfit = { + lookType = 235, + lookHead = 20, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 286 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Pits of Inferno, The Crystal Caves and The Soul Well in The Inquisition Quest, \z + Drefia Grim Reaper Dungeons, as well in Vengoth." + } + +monster.health = 1350 +monster.maxHealth = 1350 +monster.race = "undead" +monster.corpse = 6348 +monster.speed = 280 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Revenge ... is so ... sweet.", yell = false}, + {text = "Life...force! Feed me your... lifeforce", yell = false}, + {text = "Mor... tals!", yell = false}, + {text = "Buuuuuh", yell = false} +} + +monster.loot = { + {id = 2071, chance = 9620}, + {name = "silver brooch", chance = 850}, + {name = "silver brooch", chance = 110}, + {id = 2136, chance = 110}, + {name = "gold coin", chance = 33000, maxCount = 100}, + {name = "gold coin", chance = 33000, maxCount = 100}, + {name = "gold coin", chance = 33000, maxCount = 97}, + {name = "platinum coin", chance = 3850, maxCount = 7}, + {name = "stealth ring", chance = 190}, + {name = "wand of cosmic energy", chance = 9800}, + {name = "blank rune", chance = 30310, maxCount = 2}, + {name = "white piece of cloth", chance = 3800}, + {name = "soul orb", chance = 6005}, + {id = 6300, chance = 280}, + {name = "demonic essence", chance = 6270}, + {name = "relic sword", chance = 700}, + {name = "great mana potion", chance = 920}, + {name = "shiny stone", chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -308, condition = {type = CONDITION_POISON, totalDamage = 300, interval = 4000}}, + {name ="drunk", interval = 2000, chance = 15, radius = 4, effect = CONST_ME_SOUND_PURPLE, target = false, duration = 6000}, + {name ="spectre drown", interval = 2000, chance = 15, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_MANADRAIN, minDamage = -100, maxDamage = -400, range = 7, target = false}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -300, maxDamage = -550, range = 7, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_HEALING, minDamage = 100, maxDamage = 700, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 290, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 90}, + {type = COMBAT_ENERGYDAMAGE, percent = -8}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -8}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 1}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/tarnished_spirit.lua b/data/monster/undeads/tarnished_spirit.lua new file mode 100644 index 00000000000..22b996860c7 --- /dev/null +++ b/data/monster/undeads/tarnished_spirit.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Tarnished Spirit") +local monster = {} + +monster.description = "a tarnished spirit" +monster.experience = 120 +monster.outfit = { + lookType = 566, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 976 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Drefia." + } + +monster.health = 150 +monster.maxHealth = 150 +monster.race = "undead" +monster.corpse = 21366 +monster.speed = 160 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Huh!", yell = false} +} + +monster.loot = { + {id = 1962, chance = 1310}, + {name = "stealth ring", chance = 180}, + {name = "morning star", chance = 10610}, + {name = "combat knife", chance = 7002}, + {name = "ancient shield", chance = 860}, + {name = "cape", chance = 8800}, + {name = "shadow herb", chance = 14400}, + {name = "white piece of cloth", chance = 1940}, + {name = "ghostly tissue", chance = 1870} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -80}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -20, maxDamage = -45, range = 1, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 100}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/tomb_servant.lua b/data/monster/undeads/tomb_servant.lua new file mode 100644 index 00000000000..925c7005553 --- /dev/null +++ b/data/monster/undeads/tomb_servant.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Tomb Servant") +local monster = {} + +monster.description = "a tomb servant" +monster.experience = 215 +monster.outfit = { + lookType = 100, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 708 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Horestis Tomb." + } + +monster.health = 475 +monster.maxHealth = 475 +monster.race = "undead" +monster.corpse = 6029 +monster.speed = 156 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 80, + health = 10, + damage = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Chaarr!!", yell = false}, + {text = "Ngl..Nglll...Gll", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 82350, maxCount = 108}, + {name = "scarab coin", chance = 8210}, + {name = "rotten meat", chance = 2000}, + {id = 2230, chance = 49000}, + {name = "longsword", chance = 6560}, + {name = "bone shield", chance = 5300}, + {name = "worm", chance = 25325, maxCount = 12}, + {name = "half-digested piece of meat", chance = 1000}, + {name = "fist on a stick", chance = 230} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -130}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -40, maxDamage = -55, range = 7, effect = CONST_ME_MAGIC_RED, target = true} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/undead_cavebear.lua b/data/monster/undeads/undead_cavebear.lua new file mode 100644 index 00000000000..894e3a6ed36 --- /dev/null +++ b/data/monster/undeads/undead_cavebear.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("Undead Cavebear") +local monster = {} + +monster.description = "an undead cavebear" +monster.experience = 600 +monster.outfit = { + lookType = 384, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 696 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 50, + Stars = 3, + Occurrence = 3, + Locations = "Lich Hell." + } + +monster.health = 450 +monster.maxHealth = 450 +monster.race = "undead" +monster.corpse = 13323 +monster.speed = 218 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Grrrrrrrrrrrr", yell = false}, + {text = "Groooowl", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 31820, maxCount = 80}, + {name = "maxilla", chance = 13640}, + {name = "cavebear skull", chance = 2600}, + {name = "health potion", chance = 1300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400} +} + +monster.defenses = { + defense = 27, + armor = 23 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/undead_dragon.lua b/data/monster/undeads/undead_dragon.lua new file mode 100644 index 00000000000..04eae6d55f9 --- /dev/null +++ b/data/monster/undeads/undead_dragon.lua @@ -0,0 +1,150 @@ +local mType = Game.createMonsterType("Undead Dragon") +local monster = {} + +monster.description = "an undead dragon" +monster.experience = 7200 +monster.outfit = { + lookType = 231, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 282 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Helheim (single, isolated spawn), Pits of Inferno (Ashfalor's throneroom), \z + Demon Forge (The Shadow Nexus and The Arcanum), under Razachai (including the Inner Sanctum), \z + Chyllfroest, Oramond Fury Dungeon." + } + +monster.health = 8350 +monster.maxHealth = 8350 +monster.race = "undead" +monster.corpse = 6306 +monster.speed = 330 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "FEEEED MY ETERNAL HUNGER!", yell = true}, + {text = "I SENSE LIFE", yell = true} +} + +monster.loot = { + {name = "golden mug", chance = 6002}, + {name = "black pearl", chance = 22780, maxCount = 2}, + {name = "small sapphire", chance = 28370, maxCount = 2}, + {name = "gold coin", chance = 35500, maxCount = 100}, + {name = "gold coin", chance = 55500, maxCount = 98}, + {name = "platinum coin", chance = 52000, maxCount = 5}, + {name = "life crystal", chance = 2500}, + {name = "war axe", chance = 1290}, + {name = "golden armor", chance = 860}, + {name = "knight armor", chance = 5500}, + {name = "royal helmet", chance = 1720}, + {name = "power bolt", chance = 15190, maxCount = 15}, + {name = "hardened bone", chance = 14180}, + {id = 6300, chance = 1150}, + {name = "demonic essence", chance = 12460}, + {name = "assassin star", chance = 26650, maxCount = 5}, + {name = "dragon slayer", chance = 860}, + {name = "dragonbone staff", chance = 4000}, + {name = "great mana potion", chance = 21490}, + {name = "great health potion", chance = 21200}, + {name = "divine plate", chance = 430}, + {name = "skullcracker armor", chance = 290}, + {name = "gold ingot", chance = 570}, + {name = "unholy bone", chance = 33380}, + {name = "spellweaver's robe", chance = 860} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -480}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_PHYSICALDAMAGE, minDamage = -300, maxDamage = -400, range = 7, radius = 4, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -125, maxDamage = -600, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_SMALLCLOUDS, target = false}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_EARTHDAMAGE, minDamage = -100, maxDamage = -390, range = 7, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -180, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -150, maxDamage = -690, length = 8, spread = 3, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -300, maxDamage = -700, length = 8, spread = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -100, maxDamage = -200, radius = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="undead dragon curse", interval = 2000, chance = 10, target = false} +} + +monster.defenses = { + defense = 40, + armor = 40, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 200, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 50}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/undead_elite_gladiator.lua b/data/monster/undeads/undead_elite_gladiator.lua new file mode 100644 index 00000000000..620c34c53aa --- /dev/null +++ b/data/monster/undeads/undead_elite_gladiator.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Undead Elite Gladiator") +local monster = {} + +monster.description = "an undead elite gladiator" +monster.experience = 4740 +monster.outfit = { + lookType = 306, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1675 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Deep Desert." + } + +monster.health = 8000 +monster.maxHealth = 8000 +monster.race = "undead" +monster.corpse = 9823 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "Platinum Coin", chance = 44000, maxCount = 40}, + {name = "Belted Cape", chance = 500}, + {name = "Ultimate Health Potion", chance = 500, maxCount = 2}, + {name = "Throwing Star", chance = 500, maxCount = 18}, + {name = "Knight Axe", chance = 250}, + {id = 2419, chance = 500}, + {name = "protection amulet", chance = 250}, + {name = "hunting spear", chance = 250}, + {name = "broken gladiator shield", chance = 250}, + {name = "dark helmet", chance = 250}, + {name = "flask of warrior's sweat", chance = 250}, + {name = "plate armor", chance = 250}, + {name = "plate legs", chance = 250}, + {name = "two handed sword", chance = 250}, + {name = "Great Health Potion", chance = 250, maxCount = 2}, + {name = "stealth ring", chance = 230}, + {name = "crusader helmet", chance = 150}, + {name = "Relic Sword", chance = 150} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 100, maxDamage = 550}, + {name ="combat", interval = 1500, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 300, maxDamage = 550, range = 7, shootEffect = CONST_ANI_WHIRLWINDSWORD, target = false}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = 300, maxDamage = 500, range = 5, radius = 3, effect = CONST_ME_HITAREA, target = false} +} + +monster.defenses = { + defense = 45, + armor = 85, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/undead_gladiator.lua b/data/monster/undeads/undead_gladiator.lua new file mode 100644 index 00000000000..4007dae0f72 --- /dev/null +++ b/data/monster/undeads/undead_gladiator.lua @@ -0,0 +1,135 @@ +local mType = Game.createMonsterType("Undead Gladiator") +local monster = {} + +monster.description = "an undead gladiator" +monster.experience = 800 +monster.outfit = { + lookType = 306, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 508 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Arena and Zoo Quarter, Krailos." + } + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "undead" +monster.corpse = 9823 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Let's battle it out in a duel!", yell = false}, + {text = "Bring it!", yell = false}, + {text = "I'll fight here in eternity and beyond.", yell = false}, + {text = "I will not give up!", yell = false}, + {text = "Another foolish adventurer who tries to beat me.", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 44000, maxCount = 100}, + {name = "gold coin", chance = 50500, maxCount = 48}, + {name = "stealth ring", chance = 30}, + {name = "protection amulet", chance = 2200}, + {name = "two handed sword", chance = 1900}, + {name = "throwing star", chance = 15700, maxCount = 18}, + {id = 2419, chance = 11280}, + {name = "knight axe", chance = 280}, + {name = "plate armor", chance = 1700}, + {name = "brass armor", chance = 4700}, + {name = "brass legs", chance = 5500}, + {name = "dark helmet", chance = 1460}, + {name = "crusader helmet", chance = 100}, + {name = "plate legs", chance = 2444}, + {name = "hunting spear", chance = 4200}, + {name = "flask of warrior's sweat", chance = 210}, + {name = "health potion", chance = 350}, + {name = "belted cape", chance = 5000}, + {name = "broken gladiator shield", chance = 5200} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -135, range = 7, shootEffect = CONST_ANI_WHIRLWINDSWORD, target = false} +} + +monster.defenses = { + defense = 45, + armor = 45, + {name ="invisible", interval = 2000, chance = 15, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 80}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/undead_mine_worker.lua b/data/monster/undeads/undead_mine_worker.lua new file mode 100644 index 00000000000..baa2403d467 --- /dev/null +++ b/data/monster/undeads/undead_mine_worker.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("Undead Mine Worker") +local monster = {} + +monster.description = "an undead mine worker" +monster.experience = 45 +monster.outfit = { + lookType = 33, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 594 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 1, + Locations = "West of Edron in the Lost Mines." + } + +monster.health = 65 +monster.maxHealth = 65 +monster.race = "undead" +monster.corpse = 5972 +monster.speed = 154 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Ahrrr... uhmmm... hmm...", yell = false}, + {text = "Grrr...", yell = false}, + {text = "Urrrgh... gnarrr...", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 73000, maxCount = 10}, + {id = 2230, chance = 42000}, + {id = 2376, chance = 3850}, + {name = "mace", chance = 26900}, + {name = "white mushroom", chance = 15400, maxCount = 3}, + {name = "brown mushroom", chance = 3850} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -30}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -7, maxDamage = -13, range = 1, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/undead_prospector.lua b/data/monster/undeads/undead_prospector.lua new file mode 100644 index 00000000000..cc0a16929fd --- /dev/null +++ b/data/monster/undeads/undead_prospector.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Undead Prospector") +local monster = {} + +monster.description = "an undead prospector" +monster.experience = 85 +monster.outfit = { + lookType = 18, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 595 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 1, + Locations = "West of Edron, in a some Lost Mines." + } + +monster.health = 100 +monster.maxHealth = 100 +monster.race = "blood" +monster.corpse = 5976 +monster.speed = 144 +monster.manaCost = 440 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 80, + health = 10, + damage = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Our mine... leave us alone.", yell = false}, + {text = "Turn back...", yell = false}, + {text = "These mine is ours... you shall not pass.", yell = false} +} + +monster.loot = { + {id = 2050, chance = 46150}, + {name = "gold coin", chance = 53850, maxCount = 30}, + {name = "life ring", chance = 200}, + {id = 2229, chance = 240}, + {name = "knife", chance = 15380}, + {name = "brass helmet", chance = 23000}, + {name = "viking helmet", chance = 1000}, + {name = "scale armor", chance = 1000}, + {name = "worm", chance = 92310, maxCount = 6}, + {name = "brown piece of cloth", chance = 1000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -50} +} + +monster.defenses = { + defense = 0, + armor = 0, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 5, maxDamage = 15, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 10}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/vampire.lua b/data/monster/undeads/vampire.lua new file mode 100644 index 00000000000..5e6c9bf4b1e --- /dev/null +++ b/data/monster/undeads/vampire.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Vampire") +local monster = {} + +monster.description = "a vampire" +monster.experience = 305 +monster.outfit = { + lookType = 68, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 68 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Drefia, Ghost Ship between Venore and Darashia, some Ankrahmun Tombs, Lich Hell, \z + Serpentine Tower (unreachable), Ghostlands (unreachable). House between Plains of Havoc and Dark Cathedral, \z + Hellgate (only during Zevelon Duskbringer raid), Edron Undead Cave, Vengoth Castle (and mountains before door), \z + Edron Vampire Crypt." + } + +monster.health = 475 +monster.maxHealth = 475 +monster.race = "blood" +monster.corpse = 6006 +monster.speed = 238 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 30, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 30, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "BLOOD!", yell = true}, + {text = "Let me kiss your neck", yell = false}, + {text = "I smell warm blood!", yell = false}, + {text = "I call you, my bats! Come!", yell = false} +} + +monster.loot = { + {name = "emerald bangle", chance = 230}, + {name = "black pearl", chance = 1800}, + {name = "gold coin", chance = 90230, maxCount = 60}, + {name = "bronze amulet", chance = 220}, + {id = 2229, chance = 1000}, + {name = "spike sword", chance = 1000}, + {name = "ice rapier", chance = 420}, + {name = "katana", chance = 1560}, + {name = "strange helmet", chance = 420}, + {name = "vampire shield", chance = 230}, + {name = "grave flower", chance = 1910}, + {name = "strong health potion", chance = 1500}, + {name = "vampire teeth", chance = 7600}, + {name = "blood preservation", chance = 5100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -50, maxDamage = -200, range = 1, effect = CONST_ME_SMALLCLOUDS, target = true}, + {name ="speed", interval = 2000, chance = 15, speedChange = -400, range = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 60000} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="outfit", interval = 4000, chance = 10, effect = CONST_ME_GROUNDSHAKER, target = false, duration = 5000, outfitMonster = "bat"}, + {name ="speed", interval = 2000, chance = 15, speedChange = 300, effect = CONST_ME_MAGIC_RED, target = false, duration = 3000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 15, maxDamage = 25, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 35}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -25}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/vampire_bride.lua b/data/monster/undeads/vampire_bride.lua new file mode 100644 index 00000000000..8081a4cf39b --- /dev/null +++ b/data/monster/undeads/vampire_bride.lua @@ -0,0 +1,138 @@ +local mType = Game.createMonsterType("Vampire Bride") +local monster = {} + +monster.description = "a vampire bride" +monster.experience = 1050 +monster.outfit = { + lookType = 312, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 483 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Drefia and Vampire Castle on Vengoth, Edron Vampire Crypt." + } + +monster.health = 1200 +monster.maxHealth = 1200 +monster.race = "blood" +monster.corpse = 9660 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 80, + health = 10, + damage = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Kneel before your Mistress!", yell = false}, + {text = "Dead is the new alive.", yell = false}, + {text = "Come, let me kiss you, darling. Oh wait, I meant kill.", yell = false}, + {text = "Enjoy the pain - I know you love it.", yell = false}, + {text = "Are you suffering nicely enough?", yell = false}, + {text = "You won't regret you came to me, sweetheart.", yell = false} +} + +monster.loot = { + {name = "emerald bangle", chance = 1100}, + {name = "small diamond", chance = 1020, maxCount = 2}, + {name = "gold coin", chance = 90000, maxCount = 149}, + {name = "platinum coin", chance = 9910}, + {name = "moonlight rod", chance = 5500}, + {name = "boots of haste", chance = 220}, + {name = "strong health potion", chance = 5000}, + {name = "strong mana potion", chance = 10210}, + {id = 7733, chance = 200}, + {name = "hibiscus dress", chance = 1030}, + {name = "blood goblet", chance = 60}, + {id = 9809, chance = 1010}, + {id = 9837, chance = 970}, + {name = "vampire teeth", chance = 10000}, + {name = "blood preservation", chance = 4950}, + {name = "leather whip", chance = 20} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -190}, + {name ="combat", interval = 3000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -60, maxDamage = -130, range = 1, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -60, maxDamage = -150, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = true}, + {name ="combat", interval = 4000, chance = 5, type = COMBAT_DEATHDAMAGE, minDamage = -60, maxDamage = -150, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_HEARTS, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -60, maxDamage = -150, range = 7, shootEffect = CONST_ANI_ENERGY, target = true} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 40, maxDamage = 80, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 10}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/vampire_viscount.lua b/data/monster/undeads/vampire_viscount.lua new file mode 100644 index 00000000000..e9328a65bcf --- /dev/null +++ b/data/monster/undeads/vampire_viscount.lua @@ -0,0 +1,133 @@ +local mType = Game.createMonsterType("Vampire Viscount") +local monster = {} + +monster.description = "a vampire viscount" +monster.experience = 800 +monster.outfit = { + lookType = 555, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 958 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Drefia, Edron Vampire Crypt." + } + +monster.health = 1200 +monster.maxHealth = 1200 +monster.race = "blood" +monster.corpse = 21278 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 80, + health = 10, + damage = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Prepare to BLEED!", yell = false}, + {text = "Don't struggle. We don't want to waste a drop of blood now, do we?", yell = false}, + {text = "Ah, refreshments have arrived!", yell = false}, + {text = "Bloody good thing you came!", yell = false} +} + +monster.loot = { + {name = "black pearl", chance = 2500}, + {name = "small ruby", chance = 3040, maxCount = 2}, + {name = "gold coin", chance = 83000, maxCount = 50}, + {name = "red gem", chance = 540}, + {name = "ice rapier", chance = 810}, + {name = "vampire shield", chance = 200}, + {name = "red piece of cloth", chance = 70}, + {name = "strong health potion", chance = 7100}, + {name = "strong mana potion", chance = 8180}, + {name = "vampire teeth", chance = 7200}, + {name = "blood preservation", chance = 2910}, + {name = "tooth file", chance = 6560}, + {name = "vampire's cape chain", chance = 4460} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -50, maxDamage = -100, range = 6, radius = 3, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_MORTAREA, target = true}, + -- bleed + {name ="condition", type = CONDITION_BLEEDING, interval = 2000, chance = 10, minDamage = -320, maxDamage = -560, radius = 6, effect = CONST_ME_BATS, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35, + {name ="outfit", interval = 2000, chance = 10, target = false, duration = 4000, outfitMonster = "Vicious Manbat"}, + {name ="speed", interval = 2000, chance = 15, speedChange = 300, effect = CONST_ME_MAGIC_RED, target = false, duration = 4000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/vibrant_phantom.lua b/data/monster/undeads/vibrant_phantom.lua new file mode 100644 index 00000000000..12086a6dc8b --- /dev/null +++ b/data/monster/undeads/vibrant_phantom.lua @@ -0,0 +1,134 @@ +local mType = Game.createMonsterType("Vibrant Phantom") +local monster = {} + +monster.description = "a vibrant phantom" +monster.experience = 24960 +monster.outfit = { + lookType = 1298, + lookHead = 85, + lookBody = 85, + lookLegs = 88, + lookFeet = 91, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1929 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 5000, + FirstUnlock = 25, + SecondUnlock = 2500, + CharmsPoints = 100, + Stars = 5, + Occurrence = 0, + Locations = "Furious Crater." + } + +monster.health = 27000 +monster.maxHealth = 27000 +monster.race = "undead" +monster.corpse = 38648 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "All this beautiful lightning.", yell = false}, + {text = "Feel the vibration!", yell = false} +} + +monster.loot = { + {name = "crystal coin", chance = 70540}, + {name = "ultimate health potion", chance = 32220, maxCount = 7}, + {id = 7632, chance = 54560}, -- Giant shimmering pearl + {name = "violet gem", chance = 74560}, + {name = "terra rod", chance = 21920}, + {name = "hailstorm rod", chance = 21920}, + {name = "gold ingot", chance = 54560}, + {name = "green gem", chance = 64560}, + {name = "blue gem", chance = 54560}, + {name = "underworld rod", chance = 24920}, + {name = "springsprout rod", chance = 18920}, + {name = "blue crystal shard", chance = 11920}, + {name = "violet crystal shard", chance = 11920}, + {id = 26185, chance = 28920}, -- Ring of blue plasma + {id = 38978, chance = 3500}, -- Vibrant hearth + {id = 38979, chance = 4500}, -- Vibrant robe + {id = 38944, chance = 50} -- Bag you desire +} + +monster.attacks = { + {name ="combat", interval = 2000, chance = 25, type = COMBAT_HOLYDAMAGE, minDamage = -700, maxDamage = -1100, range = 7, shootEffect = CONST_ANI_SMALLHOLY, effect = CONST_ME_HOLYDAMAGE, target = true}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -650, maxDamage = -1100, range = 7, radius = 4, shootEffect = CONST_ANI_ENERGY, effect = CONST_ME_ENERGYAREA, target = true}, + {name ="combat", interval = 3000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -650, maxDamage = -1100, range = 7, radius = 4, effect = CONST_ME_ENERGYAREA, target = false} + -- Chain: const_me-> CONST_ME_PINK_ENERGY_SPARK, combat_t->COMBAT_HOLYDAMAGE +} + +monster.defenses = { + defense = 75, + armor = 100 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -10}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = -10}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = -10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) \ No newline at end of file diff --git a/data/monster/undeads/vicious_manbat.lua b/data/monster/undeads/vicious_manbat.lua new file mode 100644 index 00000000000..ddc17ec26af --- /dev/null +++ b/data/monster/undeads/vicious_manbat.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Vicious Manbat") +local monster = {} + +monster.description = "a vicious manbat" +monster.experience = 1200 +monster.outfit = { + lookType = 554, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 959 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 5, + FirstUnlock = 2, + SecondUnlock = 3, + CharmsPoints = 50, + Stars = 3, + Occurrence = 3, + Locations = "Deep under Drefia." + } + +monster.health = 1700 +monster.maxHealth = 1700 +monster.race = "blood" +monster.corpse = 21266 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 80, + health = 10, + damage = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -215}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -100, maxDamage = -250, radius = 3, target = false}, + {name ="speed", interval = 2000, chance = 15, radius = 1, effect = CONST_ME_BATS, target = true}, + -- bleed + {name ="condition", type = CONDITION_BLEEDING, interval = 2000, chance = 20, minDamage = -400, maxDamage = -600, radius = 2, target = false} +} + +monster.defenses = { + defense = 35, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 5}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/white_shade.lua b/data/monster/undeads/white_shade.lua new file mode 100644 index 00000000000..e6fa62a4413 --- /dev/null +++ b/data/monster/undeads/white_shade.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("White Shade") +local monster = {} + +monster.description = "a white shade" +monster.experience = 120 +monster.outfit = { + lookType = 560, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 962 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Drefia." + } + +monster.health = 260 +monster.maxHealth = 260 +monster.race = "undead" +monster.corpse = 21376 +monster.speed = 160 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 4, + runHealth = 30, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Leave this place... save yourself...", yell = false}, + {text = "The dark ones.. must be stopped... unholy, twisted, EVIL!", yell = false}, + {text = "No... don't go further stranger... danger lies in every step...", yell = false} +} + +monster.loot = { + {name = "white piece of cloth", chance = 3370} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -8}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -4, maxDamage = -6, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_YALAHARIGHOST, target = false}, + {name ="speed", interval = 2000, chance = 5, speedChange = -400, radius = 4, effect = CONST_ME_HITAREA, target = false, duration = 3000} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="invisible", interval = 2000, chance = 5, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 90}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/undeads/zombie.lua b/data/monster/undeads/zombie.lua new file mode 100644 index 00000000000..1886c9aa22e --- /dev/null +++ b/data/monster/undeads/zombie.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Zombie") +local monster = {} + +monster.description = "a zombie" +monster.experience = 280 +monster.outfit = { + lookType = 311, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 512 +monster.Bestiary = { + class = "Undead", + race = BESTY_RACE_UNDEAD, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Cemetery Quarter, Drefia, Vampire Castle, Treasure Island, Isle of Evil, Upper Spike." + } + +monster.health = 500 +monster.maxHealth = 500 +monster.race = "undead" +monster.corpse = 9875 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 80, + health = 10, + damage = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Mst.... klll....", yell = false}, + {text = "Whrrrr... ssss.... mmm.... grrrrl", yell = false}, + {text = "Dnnnt... cmmm... clsrrr....", yell = false}, + {text = "Httt.... hmnnsss...", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 82000, maxCount = 65}, + {name = "halberd", chance = 3750}, + {name = "mace", chance = 7250}, + {name = "battle hammer", chance = 7000}, + {name = "steel helmet", chance = 4600}, + {name = "brass helmet", chance = 9400}, + {name = "simple dress", chance = 560}, + {name = "mana potion", chance = 740}, + {id = 9808, chance = 5680}, + {name = "half-eaten brain", chance = 10000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -130}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -14, maxDamage = -23, range = 1, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -15, maxDamage = -24, range = 7, effect = CONST_ME_MAGIC_RED, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -30, maxDamage = -49, range = 1, effect = CONST_ME_SMALLCLOUDS, target = true} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 100}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 50}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 100}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/ancient_scarab.lua b/data/monster/vermins/ancient_scarab.lua new file mode 100644 index 00000000000..0b54ca0c09a --- /dev/null +++ b/data/monster/vermins/ancient_scarab.lua @@ -0,0 +1,136 @@ +local mType = Game.createMonsterType("Ancient Scarab") +local monster = {} + +monster.description = "an ancient scarab" +monster.experience = 720 +monster.outfit = { + lookType = 79, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 79 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Ankrahmun Library Tomb, Stone Tomb, Peninsula Tomb, Mother of Scarabs Lair, \z + Kha'zeel Scarab Lair, deep in Larva Caves (found beneath steps underground), Lion's Rock, \z + Arena and Zoo Quarter and beneath Fenrock." + } + +monster.health = 1000 +monster.maxHealth = 1000 +monster.race = "venom" +monster.corpse = 6021 +monster.speed = 218 +monster.manaCost = 0 +monster.maxSummons = 3 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 20, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Larva", chance = 10, interval = 2000, max = 3} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "scarab amulet", chance = 3410}, + {name = "ancient amulet", chance = 2570}, + {name = "gold coin", chance = 50000, maxCount = 90}, + {name = "gold coin", chance = 50000, maxCount = 97}, + {name = "small emerald", chance = 4810, maxCount = 3}, + {name = "small amethyst", chance = 5000, maxCount = 4}, + {name = "scarab coin", chance = 7692, maxCount = 2}, + {id = 2162, chance = 11480}, + {name = "daramian waraxe", chance = 420}, + {name = "plate armor", chance = 10300}, + {name = "scarab shield", chance = 480}, + {name = "strong health potion", chance = 660}, + {name = "terra hood", chance = 490}, + {name = "scarab pincers", chance = 3571} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -130, condition = {type = CONDITION_POISON, totalDamage = 56, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -15, maxDamage = -145, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -700, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false, duration = 25000}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 30, minDamage = -440, maxDamage = -520, radius = 5, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="speed", interval = 2000, chance = 15, speedChange = 380, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 10}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/brimstone_bug.lua b/data/monster/vermins/brimstone_bug.lua new file mode 100644 index 00000000000..3442d1dc621 --- /dev/null +++ b/data/monster/vermins/brimstone_bug.lua @@ -0,0 +1,127 @@ +local mType = Game.createMonsterType("Brimstone Bug") +local monster = {} + +monster.description = "a brimstone bug" +monster.experience = 900 +monster.outfit = { + lookType = 352, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 674 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Beneath Razzachai, Northern Zao Plantations, Brimstone Bug Caves, Chyllfroest, Krailos Spider Lair." + } + +monster.health = 1300 +monster.maxHealth = 1300 +monster.race = "venom" +monster.corpse = 12527 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Chrrr!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "small emerald", chance = 2702, maxCount = 4}, + {name = "stealth ring", chance = 892}, + {name = "platinum amulet", chance = 110}, + {name = "magic sulphur", chance = 1639}, + {name = "strong health potion", chance = 9003}, + {name = "strong mana potion", chance = 9025}, + {name = "poisonous slime", chance = 50000}, + {name = "lump of earth", chance = 20000}, + {name = "sulphurous stone", chance = 14970}, + {name = "brimstone fangs", chance = 5710}, + {name = "brimstone shell", chance = 10000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -213, condition = {type = CONDITION_POISON, totalDamage = 400, interval = 4000}}, + {name ="speed", interval = 2000, chance = 20, speedChange = -600, range = 7, shootEffect = CONST_ANI_DEATH, effect = CONST_ME_MORTAREA, target = false, duration = 10000}, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_EARTHDAMAGE, minDamage = -140, maxDamage = -310, radius = 6, effect = CONST_ME_SMALLPLANTS, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -130, maxDamage = -200, length = 6, spread = 3, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="brimstone bug wave", interval = 2000, chance = 15, minDamage = -80, maxDamage = -120, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = -10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/bug.lua b/data/monster/vermins/bug.lua new file mode 100644 index 00000000000..9b65dc707d2 --- /dev/null +++ b/data/monster/vermins/bug.lua @@ -0,0 +1,111 @@ +local mType = Game.createMonsterType("Bug") +local monster = {} + +monster.description = "a bug" +monster.experience = 18 +monster.outfit = { + lookType = 45, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 45 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "In many parts around Tibia, including Rookgaard." + } + +monster.health = 29 +monster.maxHealth = 29 +monster.race = "venom" +monster.corpse = 5990 +monster.speed = 160 +monster.manaCost = 250 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 51170, maxCount = 6}, + {name = "cherry", chance = 2590, maxCount = 3} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -23} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/burrowing_beetle.lua b/data/monster/vermins/burrowing_beetle.lua new file mode 100644 index 00000000000..f92d713b1b8 --- /dev/null +++ b/data/monster/vermins/burrowing_beetle.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Burrowing Beetle") +local monster = {} + +monster.description = "a burrowing beetle" +monster.experience = 165 +monster.outfit = { + lookType = 83, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 450 +monster.maxHealth = 450 +monster.race = "venom" +monster.corpse = 6024 +monster.speed = 170 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 80, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -95}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -45, range = 1, shootEffect = CONST_ANI_POISON, target = false}, + {name ="poisonfield", interval = 2000, chance = 10, radius = 1, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="speed", interval = 2000, chance = 15, speedChange = 200, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/butterfly.lua b/data/monster/vermins/butterfly.lua new file mode 100644 index 00000000000..38ae11a565d --- /dev/null +++ b/data/monster/vermins/butterfly.lua @@ -0,0 +1,108 @@ +local mType = Game.createMonsterType("Butterfly") +local monster = {} + +monster.description = "a butterfly" +monster.experience = 0 +monster.outfit = { + lookType = 227, + lookHead = 20, + lookBody = 30, + lookLegs = 40, + lookFeet = 50, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 213 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 25, + FirstUnlock = 5, + SecondUnlock = 10, + CharmsPoints = 1, + Stars = 0, + Occurrence = 0, + Locations = "Ab'Dendriel, Ab'Dendriel Surroundings, Carlin, Cormaya, Edron Surroundings, \z + Feyrist Meadows, Fibula, Fields of Glory, Green Claw Swamp, Issavi, Kazordoon Surroundings, Meriana, \z + Outlaw Camp, Port Hope Surroundings, Stonehome, Thais Surroundings, Venore Southern Swamp, Venore Surroundings." + } + +monster.health = 2 +monster.maxHealth = 2 +monster.race = "venom" +monster.corpse = 4313 +monster.speed = 320 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 60, + random = 40, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 8, + runHealth = 2, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/carrion_worm.lua b/data/monster/vermins/carrion_worm.lua new file mode 100644 index 00000000000..3d1335d8f6b --- /dev/null +++ b/data/monster/vermins/carrion_worm.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Carrion Worm") +local monster = {} + +monster.description = "a carrion worm" +monster.experience = 70 +monster.outfit = { + lookType = 192, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 251 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Edron, Cormaya, Drillworm Caves, Venore Swamps, Liberty Bay, Vandura, \z + Hellgate, Fibula Dungeon, Stonehome, Kazordoon, Darashia Rotworm Caves, Port Hope, \z + Ancient Temple, Fenrock, Arena and Zoo Quarter." + } + +monster.health = 145 +monster.maxHealth = 145 +monster.race = "blood" +monster.corpse = 6069 +monster.speed = 130 +monster.manaCost = 380 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 45}, + {name = "meat", chance = 9460, maxCount = 2}, + {name = "worm", chance = 2100, maxCount = 2}, + {name = "carrion worm fang", chance = 10000}, + {id = 13757, chance = 210} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -45} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/cave_devourer.lua b/data/monster/vermins/cave_devourer.lua new file mode 100644 index 00000000000..ad6d56dcce2 --- /dev/null +++ b/data/monster/vermins/cave_devourer.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Cave Devourer") +local monster = {} + +monster.description = "a cave devourer" +monster.experience = 2380 +monster.outfit = { + lookType = 1036, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1544 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Warzone 5." + } + +monster.health = 5400 +monster.maxHealth = 5400 +monster.race = "blood" +monster.corpse = 30794 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "*grrruuuuuuuuaaaaaaaar*", yell = false}, + {text = "*roooooo*", yell = false} +} + +monster.loot = { + {name = "Cave Devourer Eyes", chance = 24580}, + {name = "Cave Devourer Maw", chance = 27540}, + {name = "Small Enchanted Sapphire", chance = 8050}, + {name = "Small Enchanted Ruby", chance = 6780}, + {name = "Crystalline Arrow", chance = 23520, maxCount = 40}, + {name = "Blue Crystal Shard", chance = 10590}, + {name = "Violet Crystal Shard", chance = 7630}, + {name = "Green Crystal Shard", chance = 8900}, + {name = "Cyan Crystal Fragment", chance = 5720}, + {name = "Slime Heart", chance = 13770, maxCount = 4}, + {name = "Cave Devourer Legs", chance = 17160}, + {name = "Stealth Ring", chance = 2540}, + {name = "Suspicious Device", chance = 420} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="stalagmite", interval = 2000, chance = 15, minDamage = -190, maxDamage = -300, range = 7, length = 6, spread = 3, shootEffect = CONST_ANI_POISON, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -70, maxDamage = -160, range = 3, length = 6, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -90, maxDamage = -160, range = 3, length = 6, spread = 3, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="stone shower", interval = 2000, chance = 10, minDamage = -230, maxDamage = -450, range = 7, target = false} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -30}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/centipede.lua b/data/monster/vermins/centipede.lua new file mode 100644 index 00000000000..4448d22da3b --- /dev/null +++ b/data/monster/vermins/centipede.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Centipede") +local monster = {} + +monster.description = "a centipede" +monster.experience = 34 +monster.outfit = { + lookType = 124, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 124 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "All around Port Hope and Tiquanda, Dark Cathedral, Vandura, Meriana, Razzachai, \z + and Slime cave east of Venore, Arena and Zoo Quarter, Gnarlhound Caves." + } + +monster.health = 70 +monster.maxHealth = 70 +monster.race = "venom" +monster.corpse = 6050 +monster.speed = 166 +monster.manaCost = 335 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 80000, maxCount = 15}, + {name = "centipede leg", chance = 10300} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -45, condition = {type = CONDITION_POISON, totalDamage = 20, interval = 4000}} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/chasm_spawn.lua b/data/monster/vermins/chasm_spawn.lua new file mode 100644 index 00000000000..c01150ff802 --- /dev/null +++ b/data/monster/vermins/chasm_spawn.lua @@ -0,0 +1,135 @@ +local mType = Game.createMonsterType("Chasm Spawn") +local monster = {} + +monster.description = "a chasm spawn" +monster.experience = 3500 +monster.outfit = { + lookType = 1037, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1546 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Warzone 4." + } + +monster.health = 4000 +monster.maxHealth = 4000 +monster.race = "blood" +monster.corpse = 30798 +monster.speed = 115 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 8 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "tzzzz tzzzz tzzzz!", yell = false}, + {text = "sloap sloap sloap!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 10000, maxCount = 78}, + {name = "Wood Mushroom", chance = 27200, maxCount = 5}, + {name = "Chasm Spawn Head", chance = 33390}, + {name = "Chasm Spawn Abdomen", chance = 24710}, + {name = "Chasm Spawn Tail", chance = 64890}, + {name = "Small Enchanted Emerald", chance = 11040, maxCount = 3}, + {name = "Small Enchanted Amethyst", chance = 8170, maxCount = 3}, + {name = "Brown Mushroom", chance = 19680, maxCount = 5}, + {name = "Orange Mushroom", chance = 15140}, + {name = "Blue Crystal Shard", chance = 7850}, + {name = "Green Crystal Shard", chance = 7850}, + {name = "Violet Crystal Shard", chance = 4690}, + {name = "Mushroom Backpack", chance = 610}, + {name = "Suspicious Device", chance = 520} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -5, maxDamage = -16, range = 7, shootEffect = CONST_ANI_POISON, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -30, maxDamage = -60, range = 7, shootEffect = CONST_ANI_DEATH, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -70, maxDamage = -160, range = 3, length = 3, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="explosion", interval = 2000, chance = 15, minDamage = -50, maxDamage = -170, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -40, maxDamage = -60, range = 7, target = false}, + {name ="stone shower", interval = 2000, chance = 10, minDamage = -70, maxDamage = -140, range = 7, target = false}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -70, maxDamage = -140, length = 3, spread = 3, effect = CONST_ME_PLANTATTACK, target = false} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/cockroach.lua b/data/monster/vermins/cockroach.lua new file mode 100644 index 00000000000..68395cc6871 --- /dev/null +++ b/data/monster/vermins/cockroach.lua @@ -0,0 +1,93 @@ +local mType = Game.createMonsterType("Cockroach") +local monster = {} + +monster.description = "a cockroach" +monster.experience = 0 +monster.outfit = { + lookType = 284, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1 +monster.maxHealth = 1 +monster.race = "venom" +monster.corpse = 8593 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 60000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 50, + targetDistance = 5, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "cockroach leg", chance = 100000} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/crawler.lua b/data/monster/vermins/crawler.lua new file mode 100644 index 00000000000..876e8bf6e51 --- /dev/null +++ b/data/monster/vermins/crawler.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Crawler") +local monster = {} + +monster.description = "a crawler" +monster.experience = 1000 +monster.outfit = { + lookType = 456, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 786 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Hive, Hive Outpost." + } + +monster.health = 1450 +monster.maxHealth = 1450 +monster.race = "venom" +monster.corpse = 15292 +monster.speed = 250 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 40, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 90}, + {name = "yellow gem", chance = 530}, + {name = "war hammer", chance = 2070}, + {name = "great mana potion", chance = 9300}, + {name = "great health potion", chance = 6200}, + {name = "springsprout rod", chance = 710}, + {name = "small topaz", chance = 10040, maxCount = 2}, + {name = "crawler head plating", chance = 18430}, + {name = "compound eye", chance = 14640}, + {name = "grasshopper legs", chance = 100} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -228, condition = {type = CONDITION_POISON, totalDamage = 80, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -100, maxDamage = -180, range = 7, shootEffect = CONST_ANI_SMALLEARTH, target = false} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="speed", interval = 2000, chance = 15, speedChange = 300, effect = CONST_ME_MAGIC_RED, target = false, duration = 3000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/crystal_spider.lua b/data/monster/vermins/crystal_spider.lua new file mode 100644 index 00000000000..8591e548084 --- /dev/null +++ b/data/monster/vermins/crystal_spider.lua @@ -0,0 +1,135 @@ +local mType = Game.createMonsterType("Crystal Spider") +local monster = {} + +monster.description = "a crystal spider" +monster.experience = 900 +monster.outfit = { + lookType = 263, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 330 +monster.Bestiary = { + class = "Magical", + race = BESTY_RACE_MAGICAL, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Atop of the Formorgar Glacier and deep inside Formorgar Mines, Frost Dragon Tunnel, \z + Ice Witch Temple, Nibelor Ice Cave, the Crystal Caves in The Inquisition Quest, Mushroom Gardens." + } + +monster.health = 1250 +monster.maxHealth = 1250 +monster.race = "venom" +monster.corpse = 7344 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 15 +} + +monster.strategiesTarget = { + nearest = 70, + health = 20, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 80, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Screeech!", yell = false} +} + +monster.loot = { + {id = 2124, chance = 1560}, + {name = "crystal necklace", chance = 1640}, + {name = "gold coin", chance = 99998, maxCount = 100}, + {name = "gold coin", chance = 99998, maxCount = 92}, + {id = 2169, chance = 1480}, + {name = "platinum amulet", chance = 130}, + {name = "steel helmet", chance = 5200}, + {name = "plate armor", chance = 9993}, + {name = "knight armor", chance = 560}, + {name = "knight legs", chance = 760}, + {name = "jewelled backpack", chance = 80}, + {name = "spider silk", chance = 2010}, + {name = "shard", chance = 740}, + {name = "sniper arrow", chance = 5840, maxCount = 6}, + {name = "sapphire hammer", chance = 140}, + {name = "crystal sword", chance = 2490}, + {name = "strong mana potion", chance = 14950}, + {name = "glacier mask", chance = 670} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -250, condition = {type = CONDITION_POISON, totalDamage = 160, interval = 4000}}, + {name ="speed", interval = 2000, chance = 15, speedChange = -800, range = 7, radius = 6, effect = CONST_ME_POFF, target = false, duration = 15000}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -50, maxDamage = -100, range = 7, shootEffect = CONST_ANI_ICE, effect = CONST_ME_ICEAREA, target = true}, + {name ="speed", interval = 2000, chance = 20, speedChange = -600, range = 7, shootEffect = CONST_ANI_SNOWBALL, target = true, duration = 10000} +} + +monster.defenses = { + defense = 0, + armor = 43, + {name ="speed", interval = 2000, chance = 15, speedChange = 250, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -20}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 100}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/deepworm.lua b/data/monster/vermins/deepworm.lua new file mode 100644 index 00000000000..1a55850449b --- /dev/null +++ b/data/monster/vermins/deepworm.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Deepworm") +local monster = {} + +monster.description = "a deepworm" +monster.experience = 230 +monster.outfit = { + lookType = 1033, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1531 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Gnome Deep Hub." + } + +monster.health = 4500 +monster.maxHealth = 4500 +monster.race = "blood" +monster.corpse = 30780 +monster.speed = 204 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "*bluuuuuure*", yell = false}, + {text = "*slurp slurp ... slurp*", yell = false} +} + +monster.loot = { + {name = "Deepworm Jaws", chance = 24010}, + {name = "Life Ring", chance = 7320}, + {name = "Meat", chance = 19660, maxCount = 4}, + {name = "Ham", chance = 19660, maxCount = 4}, + {name = "Wood Mushroom", chance = 22280}, + {name = "Dark Mushroom", chance = 14960}, + {name = "Green Mushroom", chance = 18520}, + {name = "Green Crystal Shard", chance = 5360}, + {id = 30828, chance = 13210, maxCount = 2}, + {name = "Deepworm Spikes", chance = 9880}, + {name = "Small Enchanted Amethyst", chance = 3430, maxCount = 2}, + {name = "Terra Amulet", chance = 5060}, + {name = "Springsprout Rod", chance = 1120}, + {name = "Sacred Tree Amulet", chance = 2390}, + {id = 7632, chance = 860}, + {name = "Suspicious Device", chance = 530} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -190, maxDamage = -300, range = 7, length = 6, spread = 2, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -200, maxDamage = -400, length = 3, spread = 3, effect = CONST_ME_POISONAREA, target = false} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 30}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/diremaw.lua b/data/monster/vermins/diremaw.lua new file mode 100644 index 00000000000..b79643cbc65 --- /dev/null +++ b/data/monster/vermins/diremaw.lua @@ -0,0 +1,132 @@ +local mType = Game.createMonsterType("Diremaw") +local monster = {} + +monster.description = "a diremaw" +monster.experience = 2500 +monster.outfit = { + lookType = 1034, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1532 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Gnome Deep Hub (north and south tasking areas), Warzone 6." + } + +monster.health = 4500 +monster.maxHealth = 4500 +monster.race = "blood" +monster.corpse = 30729 +monster.speed = 300 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "uuaarrrrrrr", yell = false}, + {text = "clic clic clic", yell = false} +} + +monster.loot = { + {name = "Ham", chance = 40080, maxCount = 4}, + {name = "Diremaw Brainpan", chance = 24120}, + {name = "Poisonous Slime", chance = 11930, maxCount = 5}, + {name = "Blue Crystal Shard", chance = 9660}, + {name = "Violet Crystal Shard", chance = 8180}, + {name = "Green Crystal Shard", chance = 8030}, + {name = "Onyx Chip", chance = 8560, maxCount = 4}, + {name = "Diremaw Legs", chance = 9650, maxCount = 2}, + {name = "Small Enchanted Emerald", chance = 2940, maxCount = 2}, + {name = "Small Emerald", chance = 5080, maxCount = 2}, + {name = "Gold Ingot", chance = 2970}, + {id = 7632, chance = 3100}, + {name = "Suspicious Device", chance = 600}, + {name = "Mycological Bow", chance = 1200}, + {name = "Mushroom Backpack", chance = 1500} +} + +monster.attacks = { + {name ="combat", interval = 2000, chance = 25, type = COMBAT_EARTHDAMAGE, minDamage = -150, maxDamage = -200, range = 7, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 25, type = COMBAT_EARTHDAMAGE, minDamage = -150, maxDamage = -250, range = 7, radius = 4, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POFF, target = true}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 21, minDamage = -200, maxDamage = -310, radius = 4, effect = CONST_ME_GREEN_RINGS, target = false} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/drillworm.lua b/data/monster/vermins/drillworm.lua new file mode 100644 index 00000000000..dca626769d3 --- /dev/null +++ b/data/monster/vermins/drillworm.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Drillworm") +local monster = {} + +monster.description = "a drillworm" +monster.experience = 858 +monster.outfit = { + lookType = 527, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 878 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Drillworm Caves, Lower Spike and in the Lost Dwarf version of the Forsaken Mine." + } + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "venom" +monster.corpse = 19705 +monster.speed = 220 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 20 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Knarrrk!", yell = false}, + {text = "Krrrk!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 50}, + {id = 2553, chance = 5280}, + {name = "worm", chance = 4580, maxCount = 5}, + {name = "iron ore", chance = 1750}, + {name = "spiked squelcher", chance = 540}, + {name = "terra amulet", chance = 2360}, + {name = "lump of earth", chance = 15000}, + {name = "clay lump", chance = 700}, + {id = 13757, chance = 12130}, + {name = "green crystal splinter", chance = 9780}, + {name = "brown crystal splinter", chance = 9260}, + {name = "blue crystal splinter", chance = 9610}, + {name = "pulverized ore", chance = 5400}, + {name = "vein of ore", chance = 7280}, + {name = "drill bolt", chance = 4870, maxCount = 2} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300, condition = {type = CONDITION_POISON, totalDamage = 100, interval = 4000}}, + {name ="speed", interval = 2000, chance = 15, speedChange = -600, length = 8, spread = 3, effect = CONST_ME_MAGIC_RED, target = false, duration = 15000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -150, maxDamage = -300, length = 8, spread = 3, effect = CONST_ME_HITBYPOISON, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -100, maxDamage = -150, radius = 3, effect = CONST_ME_POISONAREA, target = true} +} + +monster.defenses = { + defense = 35, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 15}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 16}, + {type = COMBAT_HOLYDAMAGE , percent = 25}, + {type = COMBAT_DEATHDAMAGE , percent = 15} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/emerald_damselfly.lua b/data/monster/vermins/emerald_damselfly.lua new file mode 100644 index 00000000000..eeb34ce4f75 --- /dev/null +++ b/data/monster/vermins/emerald_damselfly.lua @@ -0,0 +1,119 @@ +local mType = Game.createMonsterType("Emerald Damselfly") +local monster = {} + +monster.description = "an emerald damselfly" +monster.experience = 35 +monster.outfit = { + lookType = 528, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 912 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Venore Salamander Cave, Dryad Gardens." + } + +monster.health = 90 +monster.maxHealth = 90 +monster.race = "venom" +monster.corpse = 19706 +monster.speed = 200 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Bzzzzz!", yell = false} +} + +monster.loot = { + {id = 2120, chance = 4300}, + {name = "gold coin", chance = 90000, maxCount = 18}, + {name = "arrow", chance = 7570, maxCount = 5}, + {name = "health potion", chance = 3580}, + {name = "mana potion", chance = 3550}, + {name = "damselfly wing", chance = 11830}, + {name = "damselfly eye", chance = 9970} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -4, condition = {type = CONDITION_POISON, totalDamage = 10, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -12, range = 7, shootEffect = CONST_ANI_POISON, target = false} +} + +monster.defenses = { + defense = 10, + armor = 10, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 4, maxDamage = 10, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/exotic_cave_spider.lua b/data/monster/vermins/exotic_cave_spider.lua new file mode 100644 index 00000000000..8cfd14e2e1a --- /dev/null +++ b/data/monster/vermins/exotic_cave_spider.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Exotic Cave Spider") +local monster = {} + +monster.description = "a exotic cave spider" +monster.experience = 1400 +monster.outfit = { + lookType = 1344, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 2024 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Exotic cave spider cave." + } + +monster.health = 1900 +monster.maxHealth = 1900 +monster.race = "venom" +monster.corpse = 40193 +monster.speed = 264 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 20, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "platinum coin", chance = 62220}, + {name = "great health potion", chance = 45500}, + {name = "poison arrow", chance = 33330}, + {name = "terra boots", chance = 10550}, + {name = "silver amulet", chance = 5680}, + {name = "spider silk", chance = 4580}, + {name = "terra mantle", chance = 850} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450, condition = {type = CONDITION_POISON, totalDamage = 250, interval = 4000}}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, range = 7, radius = 1, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -90, maxDamage = -150, range = 7, radius = 3, effect = CONST_ME_POISONAREA, target = true} +} + +monster.defenses = { + defense = 40, + armor = 40 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = true}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/giant_spider.lua b/data/monster/vermins/giant_spider.lua new file mode 100644 index 00000000000..1968de537fc --- /dev/null +++ b/data/monster/vermins/giant_spider.lua @@ -0,0 +1,141 @@ +local mType = Game.createMonsterType("Giant Spider") +local monster = {} + +monster.description = "a giant spider" +monster.experience = 900 +monster.outfit = { + lookType = 38, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 38 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Plains of Havoc, Point of no Return in Outlaw Camp, Ghostlands, Hellgate, \z + Mintwallin Secret Laboratory, Mad Mage Room deep below Ancient Temple, \z + Mount Sternum Undead Cave, Green Claw Swamp, Maze of Lost Souls, \z + Crusader Helmet Quest in the Dwarf Mines, Mushroom Gardens, \z + west drillworm cave, Edron Hero Cave, Edron Orc Cave, \z + on a hill near Drefia, on a hill north-west of Ankrahmun (inaccessible), \z + Forbidden Lands, Deeper Banuta, Malada, Ramoa, Arena and Zoo Quarter, \z + second floor up of Cemetery Quarter, beneath Fenrock, Vengoth Castle, \z + Vandura Mountain, in a cave in Robson Isle, Chyllfroest, Spider Caves, \z + Second floor of Krailos Spider Lair , Caverna Exanima." + } + +monster.health = 1300 +monster.maxHealth = 1300 +monster.race = "venom" +monster.corpse = 5977 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 20, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Poison Spider", chance = 10, interval = 2000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 99990, maxCount = 100}, + {name = "gold coin", chance = 99990, maxCount = 95}, + {id = 2169, chance = 710}, + {name = "platinum amulet", chance = 280}, + {name = "two handed sword", chance = 5100}, + {name = "steel helmet", chance = 4980}, + {name = "plate armor", chance = 9980}, + {name = "knight armor", chance = 500}, + {name = "knight legs", chance = 840}, + {name = "poison arrow", chance = 11950, maxCount = 12}, + {name = "plate legs", chance = 8333}, + {name = "spider silk", chance = 1990}, + {name = "strong health potion", chance = 3550}, + {name = "lightning headband", chance = 270} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -300, condition = {type = CONDITION_POISON, totalDamage = 160, interval = 4000}}, + {name ="poisonfield", interval = 2000, chance = 10, range = 7, radius = 1, shootEffect = CONST_ANI_POISON, target = true}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -40, maxDamage = -70, range = 7, radius = 1, shootEffect = CONST_ANI_POISON, target = true} +} + +monster.defenses = { + defense = 0, + armor = 30, + {name ="speed", interval = 2000, chance = 15, speedChange = 390, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/hibernal_moth.lua b/data/monster/vermins/hibernal_moth.lua new file mode 100644 index 00000000000..4efc929bc21 --- /dev/null +++ b/data/monster/vermins/hibernal_moth.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("Hibernal Moth") +local monster = {} + +monster.description = "a Hibernal Moth" +monster.experience = 700 +monster.outfit = { + lookType = 1149, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1737 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "Court of Winter at night." + } + +monster.health = 850 +monster.maxHealth = 850 +monster.race = "blood" +monster.corpse = 34817 +monster.speed = 400 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -5} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/hive_overseer.lua b/data/monster/vermins/hive_overseer.lua new file mode 100644 index 00000000000..53a071c103e --- /dev/null +++ b/data/monster/vermins/hive_overseer.lua @@ -0,0 +1,139 @@ +local mType = Game.createMonsterType("Hive Overseer") +local monster = {} + +monster.description = "a hive overseer" +monster.experience = 5500 +monster.outfit = { + lookType = 458, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 801 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 2, + Locations = "The Hive towers: on the highest floor of each tower, \z + and in many of the closed rooms accessed with pheromones; \z + many in the large underground room of the west tower. \z + Liberty Bay Hive Outpost: one spawn on the second floor underground." + } + +monster.health = 7500 +monster.maxHealth = 7500 +monster.race = "venom" +monster.corpse = 15354 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 2 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 4, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.summons = { + {name = "Spidris Elite", chance = 40, interval = 2000, max = 2} +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Zopp!", yell = false}, + {text = "Kropp!", yell = false} +} + +monster.loot = { + {name = "small ruby", chance = 16000, maxCount = 2}, + {name = "gold coin", chance = 40000, maxCount = 100}, + {name = "gold coin", chance = 58000, maxCount = 98}, + {name = "platinum coin", chance = 84000, maxCount = 6}, + {name = "steel boots", chance = 550}, + {name = "great mana potion", chance = 18000}, + {id = 7632, chance = 6000}, + {name = "ultimate health potion", chance = 12000}, + {name = "gold ingot", chance = 29000}, + {name = "kollos shell", chance = 28000}, + {name = "compound eye", chance = 16000}, + {name = "calopteryx cape", chance = 830}, + {name = "carapace shield", chance = 920}, + {name = "hive scythe", chance = 1650}, + {name = "gooey mass", chance = 13000, maxCount = 2}, + {name = "hive bow", chance = 830} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -60, maxDamage = -80, radius = 4, effect = CONST_ME_POISONAREA, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 20, minDamage = -600, maxDamage = -1000, radius = 4, effect = CONST_ME_GREEN_RINGS, target = false} +} + +monster.defenses = { + defense = 45, + armor = 45, + {name ="combat", interval = 2000, chance = 50, type = COMBAT_HEALING, minDamage = 50, maxDamage = 100, effect = CONST_ME_MAGIC_BLUE, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 500, maxDamage = 700, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 60}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 70}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/insect_swarm.lua b/data/monster/vermins/insect_swarm.lua new file mode 100644 index 00000000000..58e8376c887 --- /dev/null +++ b/data/monster/vermins/insect_swarm.lua @@ -0,0 +1,111 @@ +local mType = Game.createMonsterType("Insect Swarm") +local monster = {} + +monster.description = "an insect swarm" +monster.experience = 40 +monster.outfit = { + lookType = 349, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 621 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Zao Steppe, Northern Zao Plantations and the Horestis Tomb \z + (only when the curse of Horestis is not active)." + } + +monster.health = 50 +monster.maxHealth = 50 +monster.race = "undead" +monster.corpse = 11320 +monster.speed = 236 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -10, condition = {type = CONDITION_POISON, totalDamage = 16, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -15, range = 1, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/insectoid_scout.lua b/data/monster/vermins/insectoid_scout.lua new file mode 100644 index 00000000000..3f85eaac346 --- /dev/null +++ b/data/monster/vermins/insectoid_scout.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("Insectoid Scout") +local monster = {} + +monster.description = "an insectoid scout" +monster.experience = 150 +monster.outfit = { + lookType = 403, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 732 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 2, + Locations = "West and south of Greenshore." + } + +monster.health = 230 +monster.maxHealth = 230 +monster.race = "venom" +monster.corpse = 13514 +monster.speed = 202 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Chrrr! Chrr!", yell = false}, + {text = "Klk! Klk!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 80000, maxCount = 80}, + {name = "club ring", chance = 100}, + {name = "ripper lance", chance = 850}, + {name = "health potion", chance = 280} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -74, condition = {type = CONDITION_POISON, totalDamage = 60, interval = 4000}} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 50}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/insectoid_worker.lua b/data/monster/vermins/insectoid_worker.lua new file mode 100644 index 00000000000..a3021f8013e --- /dev/null +++ b/data/monster/vermins/insectoid_worker.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("Insectoid Worker") +local monster = {} + +monster.description = "an insectoid worker" +monster.experience = 650 +monster.outfit = { + lookType = 403, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 796 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Hive, Hive Outpost." + } + +monster.health = 950 +monster.maxHealth = 950 +monster.race = "venom" +monster.corpse = 13514 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 90}, + {name = "small emerald", chance = 2880}, + {name = "epee", chance = 560}, + {name = "health potion", chance = 5090}, + {name = "compound eye", chance = 15380}, + {id = 15622, chance = 14990} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -163, condition = {type = CONDITION_POISON, totalDamage = 160, interval = 4000}} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/kollos.lua b/data/monster/vermins/kollos.lua new file mode 100644 index 00000000000..36f5645c548 --- /dev/null +++ b/data/monster/vermins/kollos.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Kollos") +local monster = {} + +monster.description = "a kollos" +monster.experience = 2400 +monster.outfit = { + lookType = 458, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 788 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Hive, Hive Outpost." + } + +monster.health = 3800 +monster.maxHealth = 3800 +monster.race = "venom" +monster.corpse = 15354 +monster.speed = 230 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Kropp!", yell = false}, + {text = "Flzlzlzlzlzlzlz!", yell = false} +} + +monster.loot = { + {name = "small ruby", chance = 8180, maxCount = 2}, + {name = "gold coin", chance = 49000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 97}, + {name = "platinum coin", chance = 66000, maxCount = 3}, + {name = "ring of healing", chance = 3270}, + {name = "steel boots", chance = 130}, + {name = "great mana potion", chance = 8950, maxCount = 4}, + {id = 7632, chance = 2600}, + {name = "ultimate health potion", chance = 4000, maxCount = 3}, + {name = "gold ingot", chance = 5160}, + {name = "kollos shell", chance = 15390}, + {name = "compound eye", chance = 15720}, + {name = "calopteryx cape", chance = 360}, + {name = "carapace shield", chance = 310}, + {name = "hive scythe", chance = 700}, + {name = "buggy backpack", chance = 460}, + {name = "tarsal arrow", chance = 10210, maxCount = 5} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -315}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -500, range = 7, radius = 3, shootEffect = CONST_ANI_EXPLOSION, effect = CONST_ME_EXPLOSIONHIT, target = true} +} + +monster.defenses = { + defense = 35, + armor = 35 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 30}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = -5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/lacewing_moth.lua b/data/monster/vermins/lacewing_moth.lua new file mode 100644 index 00000000000..97cec774f77 --- /dev/null +++ b/data/monster/vermins/lacewing_moth.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("Lacewing Moth") +local monster = {} + +monster.description = "a Lacewing Moth" +monster.experience = 800 +monster.outfit = { + lookType = 1148, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1736 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 1, + Locations = "ourt of Summer at day." + } + +monster.health = 900 +monster.maxHealth = 900 +monster.race = "blood" +monster.corpse = 34813 +monster.speed = 380 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -5} +} + +monster.defenses = { + defense = 0, + armor = 76 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/ladybug.lua b/data/monster/vermins/ladybug.lua new file mode 100644 index 00000000000..c8494080a21 --- /dev/null +++ b/data/monster/vermins/ladybug.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Ladybug") +local monster = {} + +monster.description = "a ladybug" +monster.experience = 70 +monster.outfit = { + lookType = 448, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 778 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 2, + Locations = "The Hive surface during the Hive Born World Change's third stage." + } + +monster.health = 255 +monster.maxHealth = 255 +monster.race = "venom" +monster.corpse = 15272 +monster.speed = 104 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 60, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Nee Pah!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 65000, maxCount = 40} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -4}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -20, range = 1, shootEffect = CONST_ANI_POISON, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -20, range = 7, shootEffect = CONST_ANI_POISON, target = false} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 5}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/lancer_beetle.lua b/data/monster/vermins/lancer_beetle.lua new file mode 100644 index 00000000000..d1f99f73bf0 --- /dev/null +++ b/data/monster/vermins/lancer_beetle.lua @@ -0,0 +1,124 @@ +local mType = Game.createMonsterType("Lancer Beetle") +local monster = {} + +monster.description = "a lancer beetle" +monster.experience = 275 +monster.outfit = { + lookType = 348, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 633 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Zao Wailing Widow Cave, Muggy Plains (during raid), Razzachai, \z + Northern Zao Plantations, Northern Brimstone Bug Cave, Chyllfroest." + } + +monster.health = 400 +monster.maxHealth = 400 +monster.race = "venom" +monster.corpse = 11375 +monster.speed = 266 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 30, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Crump!", yell = true} +} + +monster.loot = { + {name = "gold coin", chance = 60000, maxCount = 61}, + {name = "gold coin", chance = 60000, maxCount = 79}, + {name = "small amethyst", chance = 247}, + {name = "poisonous slime", chance = 8333}, + {name = "lump of dirt", chance = 4166}, + {name = "lancer beetle shell", chance = 16666}, + {name = "beetle necklace", chance = 1123} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -115}, + {name ="poisonfield", interval = 2000, chance = 10, radius = 4, effect = CONST_ME_POISONAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = 0, maxDamage = -90, length = 7, spread = 3, effect = CONST_ME_HITBYPOISON, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -40, maxDamage = -80, range = 7, shootEffect = CONST_ANI_POISON, target = false}, + {name ="lancer beetle curse", interval = 2000, chance = 5, range = 5, target = false} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="invisible", interval = 2000, chance = 10, effect = CONST_ME_GROUNDSHAKER} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 100}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 50} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/larva.lua b/data/monster/vermins/larva.lua new file mode 100644 index 00000000000..fee254ce022 --- /dev/null +++ b/data/monster/vermins/larva.lua @@ -0,0 +1,113 @@ +local mType = Game.createMonsterType("Larva") +local monster = {} + +monster.description = "a larva" +monster.experience = 44 +monster.outfit = { + lookType = 82, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 82 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Ankrahmun Pharaoh Tombs, Ashta'daramai, Daramian Mountain Scarab Lair, \z + Daramian Scarab Caves, Daramian Scarab Lairs, Deeper Drefia, Kha'zeel Mountains, Lion's Rock, \z + Northern Darama Desert, Port Hope Surroundings, Treasure Island, Yalahar Factory Quarter." + } + +monster.health = 70 +monster.maxHealth = 70 +monster.race = "venom" +monster.corpse = 6023 +monster.speed = 124 +monster.manaCost = 355 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 63000, maxCount = 15}, + {name = "meat", chance = 14666} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -35, condition = {type = CONDITION_POISON, totalDamage = 15, interval = 4000}} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/lesser_swarmer.lua b/data/monster/vermins/lesser_swarmer.lua new file mode 100644 index 00000000000..7e3c7648cfe --- /dev/null +++ b/data/monster/vermins/lesser_swarmer.lua @@ -0,0 +1,97 @@ +local mType = Game.createMonsterType("Lesser Swarmer") +local monster = {} + +monster.description = "a lesser swarmer" +monster.experience = 0 +monster.outfit = { + lookType = 460, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 230 +monster.maxHealth = 230 +monster.race = "venom" +monster.corpse = 15388 +monster.speed = 180 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -77, condition = {type = CONDITION_POISON, totalDamage = 60, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -15, maxDamage = -70, range = 5, effect = CONST_ME_MAGIC_RED, target = true} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/parasite.lua b/data/monster/vermins/parasite.lua new file mode 100644 index 00000000000..f4ab86d4a9c --- /dev/null +++ b/data/monster/vermins/parasite.lua @@ -0,0 +1,96 @@ +local mType = Game.createMonsterType("Parasite") +local monster = {} + +monster.description = "a parasite" +monster.experience = 0 +monster.outfit = { + lookType = 82, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 550 +monster.maxHealth = 550 +monster.race = "venom" +monster.corpse = 6023 +monster.speed = 175 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100, condition = {type = CONDITION_POISON, totalDamage = 40, interval = 4000}} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 100}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -20}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/poison_spider.lua b/data/monster/vermins/poison_spider.lua new file mode 100644 index 00000000000..7e2917b8527 --- /dev/null +++ b/data/monster/vermins/poison_spider.lua @@ -0,0 +1,111 @@ +local mType = Game.createMonsterType("Poison Spider") +local monster = {} + +monster.description = "a poison spider" +monster.experience = 22 +monster.outfit = { + lookType = 36, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 36 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Found in various caves and plains around Tibia (including Rookgaard)." + } + +monster.health = 26 +monster.maxHealth = 26 +monster.race = "venom" +monster.corpse = 5974 +monster.speed = 160 +monster.manaCost = 270 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 6, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 75000, maxCount = 4}, + {name = "poison spider shell", chance = 1140} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -20, condition = {type = CONDITION_POISON, totalDamage = 30, interval = 4000}} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/rotworm.lua b/data/monster/vermins/rotworm.lua new file mode 100644 index 00000000000..449926b48d6 --- /dev/null +++ b/data/monster/vermins/rotworm.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Rotworm") +local monster = {} + +monster.description = "a rotworm" +monster.experience = 40 +monster.outfit = { + lookType = 26, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 26 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Almost everywhere, like Ancient Temple, Vandura, Folda dungeon, Fibula Dungeon, \z + caves connecting Edron and Cormaya, Venore Swamp Troll cave, Thais Troll cave, Ferngrims Gate, \z + Dwarf Mines, Hellgate, below the graves in eastern Rookgaard, spider cave in western Rookgaard, \z + cave northeast of Ab'Dendriel, Darashia Rotworm Caves, Liberty Bay, Fenrock, \z + below Green Claw Swamp and some other places." + } + +monster.health = 65 +monster.maxHealth = 65 +monster.race = "blood" +monster.corpse = 5967 +monster.speed = 116 +monster.manaCost = 305 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 70, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 71760, maxCount = 17}, + {id = 2376, chance = 3000}, + {name = "mace", chance = 4500}, + {name = "meat", chance = 20000}, + {name = "ham", chance = 20120}, + {name = "worm", chance = 3000, maxCount = 3}, + {name = "lump of dirt", chance = 10000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -40} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/sacred_spider.lua b/data/monster/vermins/sacred_spider.lua new file mode 100644 index 00000000000..f4f6fb56f1b --- /dev/null +++ b/data/monster/vermins/sacred_spider.lua @@ -0,0 +1,118 @@ +local mType = Game.createMonsterType("Sacred Spider") +local monster = {} + +monster.description = "a sacred spider" +monster.experience = 330 +monster.outfit = { + lookType = 219, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 709 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Horestis Tomb (third floor and lower)." + } + +monster.health = 550 +monster.maxHealth = 550 +monster.race = "venom" +monster.corpse = 6060 +monster.speed = 244 +monster.manaCost = 485 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 20, + random = 10, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 89790, maxCount = 100}, + {name = "gold coin", chance = 89790, maxCount = 19}, + {name = "scarab coin", chance = 6710, maxCount = 4}, + {name = "plate armor", chance = 5050}, + {name = "spider fangs", chance = 25380}, + {name = "gold ingot", chance = 60} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -160, condition = {type = CONDITION_POISON, totalDamage = 80, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -50, maxDamage = -80, range = 7, shootEffect = CONST_ANI_POISON, target = false} +} + +monster.defenses = { + defense = 0, + armor = 27 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/sandcrawler.lua b/data/monster/vermins/sandcrawler.lua new file mode 100644 index 00000000000..7c18a421ace --- /dev/null +++ b/data/monster/vermins/sandcrawler.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("Sandcrawler") +local monster = {} + +monster.description = "a sandcrawler" +monster.experience = 20 +monster.outfit = { + lookType = 350, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 641 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Zao Steppe, Raging Mage tower, Ankrahmun Desert, Darashia Desert, Drefia." + } + +monster.health = 30 +monster.maxHealth = 30 +monster.race = "venom" +monster.corpse = 11357 +monster.speed = 160 +monster.manaCost = 250 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Chrk chrk!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 33333, maxCount = 6}, + {name = "sandcrawler shell", chance = 2173} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -3} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/scarab.lua b/data/monster/vermins/scarab.lua new file mode 100644 index 00000000000..d0642a70435 --- /dev/null +++ b/data/monster/vermins/scarab.lua @@ -0,0 +1,120 @@ +local mType = Game.createMonsterType("Scarab") +local monster = {} + +monster.description = "a scarab" +monster.experience = 120 +monster.outfit = { + lookType = 83, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 83 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Ankrahmun Tombs, the sand around Ankrahmun (use a shovel), deep in Larva caves, \z + the path leading to Chor, beneath Fenrock, Lion's Rock." + } + +monster.health = 320 +monster.maxHealth = 320 +monster.race = "venom" +monster.corpse = 6024 +monster.speed = 160 +monster.manaCost = 395 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 80, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 86800, maxCount = 52}, + {name = "small emerald", chance = 413}, + {name = "small amethyst", chance = 540}, + {name = "scarab coin", chance = 1098}, + {name = "daramian mace", chance = 245}, + {name = "meat", chance = 40000, maxCount = 2}, + {name = "piece of scarab shell", chance = 4950} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -75}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = 0, maxDamage = -35, range = 1, shootEffect = CONST_ANI_POISON, target = false}, + {name ="poisonfield", interval = 2000, chance = 10, radius = 1, target = false} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="speed", interval = 2000, chance = 15, speedChange = 200, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 15}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -18}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 20}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/scorpion.lua b/data/monster/vermins/scorpion.lua new file mode 100644 index 00000000000..afc33236ef0 --- /dev/null +++ b/data/monster/vermins/scorpion.lua @@ -0,0 +1,115 @@ +local mType = Game.createMonsterType("Scorpion") +local monster = {} + +monster.description = "a scorpion" +monster.experience = 45 +monster.outfit = { + lookType = 43, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 43 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Near Thais Troll Cave, Plague Spike, Drefia, Jakundaf Desert, \z + Green Claw Swamp, beneath Folda, Maze of Lost Souls, Plains of Havoc, \z + Venore and Ankrahmun Dragon Lairs, beneath Edron Graveyard, Ancient Temple, \z + Hellgate, Mad Mage Room, Ankrahmun Tombs, Treasure Island, Mal'ouquah, Ramoa, \z + Cyclopolis, Ghostlands, Vengoth, Lion's Rock." + } + +monster.health = 45 +monster.maxHealth = 45 +monster.race = "venom" +monster.corpse = 5988 +monster.speed = 150 +monster.manaCost = 310 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 60, + random = 40, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 5, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "scorpion tail", chance = 4930} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -50, condition = {type = CONDITION_POISON, totalDamage = 340, interval = 4000}} +} + +monster.defenses = { + defense = 5, + armor = 5 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/slug.lua b/data/monster/vermins/slug.lua new file mode 100644 index 00000000000..31370dac6f6 --- /dev/null +++ b/data/monster/vermins/slug.lua @@ -0,0 +1,114 @@ +local mType = Game.createMonsterType("Slug") +local monster = {} + +monster.description = "a slug" +monster.experience = 70 +monster.outfit = { + lookType = 407, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 731 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "South-east of Venore, Swamp Troll Cave." + } + +monster.health = 255 +monster.maxHealth = 255 +monster.race = "venom" +monster.corpse = 13515 +monster.speed = 104 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Sluuuurp", yell = false}, + {text = "Sluuurz", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 62000, maxCount = 40}, + {name = "worm", chance = 5000, maxCount = 3} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -44}, + {name ="combat", interval = 1000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -5, maxDamage = -40, range = 7, shootEffect = CONST_ANI_POISON, target = true} +} + +monster.defenses = { + defense = 15, + armor = 15 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 20}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 7} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/spider.lua b/data/monster/vermins/spider.lua new file mode 100644 index 00000000000..e9bf88c9746 --- /dev/null +++ b/data/monster/vermins/spider.lua @@ -0,0 +1,112 @@ +local mType = Game.createMonsterType("Spider") +local monster = {} + +monster.description = "a spider" +monster.experience = 12 +monster.outfit = { + lookType = 30, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 30 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "Almost everywhere, in grass areas, sewers like Carlin sewers, \z + caves like as Ancient Temple, Rookgaard and the Tiquanda Tarantula Caves." + } + +monster.health = 20 +monster.maxHealth = 20 +monster.race = "venom" +monster.corpse = 5961 +monster.speed = 152 +monster.manaCost = 210 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 6, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 65150, maxCount = 5}, + {name = "spider fangs", chance = 960} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -9} +} + +monster.defenses = { + defense = 2, + armor = 2 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = -20}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/spidris.lua b/data/monster/vermins/spidris.lua new file mode 100644 index 00000000000..bd0303a399d --- /dev/null +++ b/data/monster/vermins/spidris.lua @@ -0,0 +1,128 @@ +local mType = Game.createMonsterType("Spidris") +local monster = {} + +monster.description = "a spidris" +monster.experience = 2600 +monster.outfit = { + lookType = 457, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 787 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "Hive, Hive Outpost." + } + +monster.health = 3700 +monster.maxHealth = 3700 +monster.race = "venom" +monster.corpse = 15296 +monster.speed = 390 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Eeeeeeyyyyh!", yell = false}, + {text = "Iiiiieeeeeeh!", yell = false} +} + +monster.loot = { + {name = "small ruby", chance = 11900, maxCount = 5}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "platinum coin", chance = 45000, maxCount = 4}, + {name = "violet gem", chance = 770}, + {id = 6300, chance = 2700}, + {name = "titan axe", chance = 920}, + {name = "great mana potion", chance = 11500, maxCount = 2}, + {id = 7632, chance = 1700}, + {name = "ultimate health potion", chance = 6250, maxCount = 2}, + {name = "spidris mandible", chance = 14960}, + {name = "compound eye", chance = 12500}, + {name = "calopteryx cape", chance = 370}, + {name = "carapace shield", chance = 720}, + {name = "hive scythe", chance = 690} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -298}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -150, maxDamage = -310, range = 7, radius = 3, shootEffect = CONST_ANI_POISON, effect = CONST_ME_GREEN_RINGS, target = true} +} + +monster.defenses = { + defense = 30, + armor = 30, + {name ="speed", interval = 2000, chance = 15, speedChange = 450, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/spidris_elite.lua b/data/monster/vermins/spidris_elite.lua new file mode 100644 index 00000000000..5bfc1a8316b --- /dev/null +++ b/data/monster/vermins/spidris_elite.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Spidris Elite") +local monster = {} + +monster.description = "a spidris elite" +monster.experience = 4000 +monster.outfit = { + lookType = 457, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 797 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 2, + Locations = "The Hive: east tower (beyond gates), west tower (including beyond gates), \z + also anywhere Hive Overseers are found (as summons), Hive Outpost." + } + +monster.health = 5000 +monster.maxHealth = 5000 +monster.race = "venom" +monster.corpse = 15296 +monster.speed = 394 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "small ruby", chance = 23280, maxCount = 5}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "platinum coin", chance = 45000, maxCount = 6}, + {name = "violet gem", chance = 1120}, + {id = 6300, chance = 4480}, + {name = "titan axe", chance = 1440}, + {name = "great mana potion", chance = 20400, maxCount = 2}, + {id = 7632, chance = 3040}, + {name = "ultimate health potion", chance = 9250, maxCount = 2}, + {name = "spidris mandible", chance = 27440}, + {name = "compound eye", chance = 13210}, + {name = "calopteryx cape", chance = 1280}, + {name = "carapace shield", chance = 1170}, + {name = "hive scythe", chance = 1390} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -349} +} + +monster.defenses = { + defense = 30, + armor = 30 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -10}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/spitter.lua b/data/monster/vermins/spitter.lua new file mode 100644 index 00000000000..e7b5019bedb --- /dev/null +++ b/data/monster/vermins/spitter.lua @@ -0,0 +1,130 @@ +local mType = Game.createMonsterType("Spitter") +local monster = {} + +monster.description = "a spitter" +monster.experience = 1100 +monster.outfit = { + lookType = 461, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 791 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "The Hive, Hive Outpost." + } + +monster.health = 1500 +monster.maxHealth = 1500 +monster.race = "venom" +monster.corpse = 15392 +monster.speed = 270 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 40, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Spotz!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 90}, + {name = "small amethyst", chance = 8000, maxCount = 2}, + {name = "platinum coin", chance = 75250}, + {name = "green gem", chance = 210}, + {id = 2169, chance = 2400}, + {name = "platinum amulet", chance = 260}, + {name = "crusader helmet", chance = 230}, + {name = "brown mushroom", chance = 7500, maxCount = 3}, + {name = "mastermind potion", chance = 310}, + {name = "crystal sword", chance = 2000}, + {name = "great mana potion", chance = 8000}, + {name = "great health potion", chance = 5000}, + {name = "spitter nose", chance = 18000}, + {name = "compound eye", chance = 15000}, + {name = "calopteryx cape", chance = 240}, + {name = "grasshopper legs", chance = 130} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150, condition = {type = CONDITION_POISON, totalDamage = 240, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -100, maxDamage = -160, range = 7, radius = 3, shootEffect = CONST_ANI_POISON, effect = CONST_ME_POISONAREA, target = true}, + {name ="speed", interval = 2000, chance = 15, speedChange = -600, range = 7, shootEffect = CONST_ANI_POISON, target = true, duration = 15000} +} + +monster.defenses = { + defense = 20, + armor = 20, + {name ="speed", interval = 2000, chance = 15, speedChange = 400, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -5}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/swarmer.lua b/data/monster/vermins/swarmer.lua new file mode 100644 index 00000000000..b1e1ea8993a --- /dev/null +++ b/data/monster/vermins/swarmer.lua @@ -0,0 +1,118 @@ +local mType = Game.createMonsterType("Swarmer") +local monster = {} + +monster.description = "a swarmer" +monster.experience = 350 +monster.outfit = { + lookType = 460, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 790 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "The Hive, Hive Outpost." + } + +monster.health = 460 +monster.maxHealth = 460 +monster.race = "venom" +monster.corpse = 15388 +monster.speed = 256 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 50, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Flzlzlzlzlzlzlz!", yell = false}, + {text = "Rzlrzlrzlrzlrzlrzl!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 75}, + {name = "small emerald", chance = 920}, + {name = "epee", chance = 450}, + {name = "swarmer antenna", chance = 15300}, + {name = "compound eye", chance = 12500} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -102, condition = {type = CONDITION_POISON, totalDamage = 80, interval = 4000}}, + {name ="combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -50, maxDamage = -110, range = 7, effect = CONST_ME_MAGIC_RED, target = true} +} + +monster.defenses = { + defense = 10, + armor = 10, + {name ="speed", interval = 2000, chance = 15, speedChange = 220, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 75}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -1}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/swarmer_hatchling.lua b/data/monster/vermins/swarmer_hatchling.lua new file mode 100644 index 00000000000..2555cc904ed --- /dev/null +++ b/data/monster/vermins/swarmer_hatchling.lua @@ -0,0 +1,98 @@ +local mType = Game.createMonsterType("Swarmer Hatchling") +local monster = {} + +monster.description = "a swarmer hatchling" +monster.experience = 0 +monster.outfit = { + lookType = 460, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 5 +monster.maxHealth = 5 +monster.race = "blood" +monster.corpse = 15388 +monster.speed = 560 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 2000, + chance = 50 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Flzlzlzlzlzlzlz?", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -99}, + {name ="combat", interval = 1000, chance = 11, type = COMBAT_DROWNDAMAGE, minDamage = -15, maxDamage = -100, range = 5, shootEffect = CONST_ANI_SPEAR, effect = CONST_ME_LOSEENERGY, target = true} +} + +monster.defenses = { + defense = 20, + armor = 12 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/tarantula.lua b/data/monster/vermins/tarantula.lua new file mode 100644 index 00000000000..f580182576c --- /dev/null +++ b/data/monster/vermins/tarantula.lua @@ -0,0 +1,123 @@ +local mType = Game.createMonsterType("Tarantula") +local monster = {} + +monster.description = "a tarantula" +monster.experience = 120 +monster.outfit = { + lookType = 219, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 219 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Tiquanda Tarantula Caves, Spider Caves, Trapwood ground level and underground, \z + in 2 small caves South of Thais, Dark Cathedral, single spawn on top of Crocodile den north of Port Hope, \z + Plains of Havoc, underground Liberty Bay, Nargor Undead Cave and other constituents of the Shattered Isles, \z + Green Claw Swamp, first floor up in the big building in the Cemetery Quarter, Robson Isle, Vengoth. \z + After the summer update of 2008, tarantulas can be seen on the beginner's island of Rookgaard." + } + +monster.health = 225 +monster.maxHealth = 225 +monster.race = "venom" +monster.corpse = 6060 +monster.speed = 214 +monster.manaCost = 485 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 79000, maxCount = 40}, + {id = 2169, chance = 120}, + {name = "steel helmet", chance = 990}, + {name = "brass legs", chance = 3050}, + {name = "plate shield", chance = 2000}, + {name = "spider fangs", chance = 4820}, + {name = "tarantula egg", chance = 10000} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -90, condition = {type = CONDITION_POISON, totalDamage = 40, interval = 4000}}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, range = 1, radius = 1, shootEffect = CONST_ANI_POISON, effect = CONST_ME_CARNIPHILA, target = true} +} + +monster.defenses = { + defense = 10, + armor = 10, + {name ="speed", interval = 2000, chance = 15, speedChange = 220, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 10}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -15}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -10}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = true}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/terramite.lua b/data/monster/vermins/terramite.lua new file mode 100644 index 00000000000..7ca18deeece --- /dev/null +++ b/data/monster/vermins/terramite.lua @@ -0,0 +1,116 @@ +local mType = Game.createMonsterType("Terramite") +local monster = {} + +monster.description = "a terramite" +monster.experience = 160 +monster.outfit = { + lookType = 346, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 631 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 500, + FirstUnlock = 25, + SecondUnlock = 250, + CharmsPoints = 15, + Stars = 2, + Occurrence = 0, + Locations = "Steppe of Zao, Lion's Rock, Zao Terramite Caves, Darama Terramite Cave, \z + Terramite Breeding Tunnels. Also raids desert north of Ankrahmun." + } + +monster.health = 365 +monster.maxHealth = 365 +monster.race = "venom" +monster.corpse = 11347 +monster.speed = 222 +monster.manaCost = 505 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 5000, + chance = 0 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Zrp zrp!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 97520, maxCount = 45}, + {name = "terramite shell", chance = 7730}, + {name = "terramite eggs", chance = 4680, maxCount = 3}, + {name = "terramite legs", chance = 14880} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -100}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -5, maxDamage = -16, range = 7, shootEffect = CONST_ANI_POISON, target = true} +} + +monster.defenses = { + defense = 20, + armor = 20 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 5}, + {type = COMBAT_ENERGYDAMAGE, percent = -5}, + {type = COMBAT_EARTHDAMAGE, percent = 20}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/tunnel_tyrant.lua b/data/monster/vermins/tunnel_tyrant.lua new file mode 100644 index 00000000000..5905e329385 --- /dev/null +++ b/data/monster/vermins/tunnel_tyrant.lua @@ -0,0 +1,129 @@ +local mType = Game.createMonsterType("Tunnel Tyrant") +local monster = {} + +monster.description = "a tunnel tyrant" +monster.experience = 3400 +monster.outfit = { + lookType = 1035, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 1545 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 2500, + FirstUnlock = 100, + SecondUnlock = 1000, + CharmsPoints = 50, + Stars = 4, + Occurrence = 0, + Locations = "Warzone 5." + } + +monster.health = 6400 +monster.maxHealth = 6400 +monster.race = "blood" +monster.corpse = 30790 +monster.speed = 240 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 10000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = true, + canWalkOnFire = true, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "naps naps naps!", yell = false} +} + +monster.loot = { + {name = "Small Enchanted Sapphire", chance = 11910}, + {name = "Small Enchanted Ruby", chance = 9040}, + {name = "Violet Gem", chance = 7750}, + {name = "Lump of Dirt", chance = 10190}, + {name = "Tunnel Tyrant Head", chance = 24100}, + {name = "Tunnel Tyrant Shell", chance = 12480}, + {name = "Green Gem", chance = 2300}, + {name = "Blue Gem", chance = 3010}, + {name = "Crystal Mace", chance = 1580}, + {name = "Energy Vein", chance = 3010}, + {name = "Crystalline Armor", chance = 860}, + {name = "Suspicious Device", chance = 1290} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400}, + {name ="stalagmite", interval = 2000, chance = 15, minDamage = -190, maxDamage = -300, range = 7, length = 6, spread = 3, shootEffect = CONST_ANI_POISON, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -70, maxDamage = -160, range = 3, length = 6, spread = 3, effect = CONST_ME_MORTAREA, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -90, maxDamage = -160, range = 3, length = 6, spread = 3, effect = CONST_ME_HITBYFIRE, target = false}, + {name ="stone shower", interval = 2000, chance = 10, minDamage = -230, maxDamage = -450, range = 7, target = false} +} + +monster.defenses = { + defense = 5, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 30}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = -30}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/wailing_widow.lua b/data/monster/vermins/wailing_widow.lua new file mode 100644 index 00000000000..c423a3bb78d --- /dev/null +++ b/data/monster/vermins/wailing_widow.lua @@ -0,0 +1,126 @@ +local mType = Game.createMonsterType("Wailing Widow") +local monster = {} + +monster.description = "a wailing widow" +monster.experience = 450 +monster.outfit = { + lookType = 347, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 632 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Zao Wailing Widow Cave, Northern Zao Plantations, Northern Brimstone Bug Cave, \z + Razzachai, Chyllfroest, Krailos Spider Lair." + } + +monster.health = 850 +monster.maxHealth = 850 +monster.race = "venom" +monster.corpse = 11310 +monster.speed = 254 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = true, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { + {name = "gold coin", chance = 50000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 37}, + {name = "halberd", chance = 4460}, + {name = "plate shield", chance = 2854}, + {name = "green mushroom", chance = 3208}, + {name = "health potion", chance = 4761}, + {name = "mana potion", chance = 4785}, + {name = "Zaoan halberd", chance = 2210}, + {name = "widow's mandibles", chance = 20950}, + {name = "wailing widow's necklace", chance = 900} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -120, condition = {type = CONDITION_POISON, totalDamage = 160, interval = 4000}}, + {name ="drunk", interval = 2000, chance = 20, range = 7, radius = 4, effect = CONST_ME_SOUND_RED, target = false, duration = 4000}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -40, maxDamage = -70, radius = 3, effect = CONST_ME_MAGIC_RED, target = false}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -60, maxDamage = -110, range = 7, shootEffect = CONST_ANI_POISON, target = false} +} + +monster.defenses = { + defense = 0, + armor = 0, + {name ="combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 70, maxDamage = 100, effect = CONST_ME_SOUND_WHITE, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = 820, effect = CONST_ME_SOUND_YELLOW, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 10}, + {type = COMBAT_DEATHDAMAGE , percent = 100} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/wasp.lua b/data/monster/vermins/wasp.lua new file mode 100644 index 00000000000..5a57c55f6a5 --- /dev/null +++ b/data/monster/vermins/wasp.lua @@ -0,0 +1,114 @@ +local mType = Game.createMonsterType("Wasp") +local monster = {} + +monster.description = "a wasp" +monster.experience = 24 +monster.outfit = { + lookType = 44, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 44 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 250, + FirstUnlock = 10, + SecondUnlock = 100, + CharmsPoints = 5, + Stars = 1, + Occurrence = 0, + Locations = "South of Thais, west of Ab'Dendriel, northeastern Cormaya, \z + Green Claw Swamp between Kazordoon and Venore, Wasp Tower in Rookgaard, \z + Wasp Towers in Darashia, all over Tiquanda, and all over Vandura." + } + +monster.health = 35 +monster.maxHealth = 35 +monster.race = "venom" +monster.corpse = 5989 +monster.speed = 320 +monster.manaCost = 280 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 60, + random = 40, +} + +monster.flags = { + summonable = true, + attackable = true, + hostile = true, + convinceable = true, + pushable = true, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Bssssss", yell = false} +} + +monster.loot = { + {name = "honeycomb", chance = 3000} +} + +monster.attacks = { + {name ="melee", interval = 1500, chance = 100, minDamage = 0, maxDamage = -20, condition = {type = CONDITION_POISON, totalDamage = 20, interval = 4000}} +} + +monster.defenses = { + defense = 10, + armor = 10 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/waspoid.lua b/data/monster/vermins/waspoid.lua new file mode 100644 index 00000000000..e7011e74198 --- /dev/null +++ b/data/monster/vermins/waspoid.lua @@ -0,0 +1,125 @@ +local mType = Game.createMonsterType("Waspoid") +local monster = {} + +monster.description = "Waspoid" +monster.experience = 830 +monster.outfit = { + lookType = 462, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 792 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "The Hive, Hive Outpost." + } + +monster.health = 1100 +monster.maxHealth = 1100 +monster.race = "venom" +monster.corpse = 15396 +monster.speed = 310 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 100, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 95, + targetDistance = 1, + runHealth = 0, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Peeex!", yell = false}, + {text = "Bzzzzzzzrrrrzzzzzzrrrrr!", yell = false} +} + +monster.loot = { + {name = "emerald bangle", chance = 2040}, + {name = "black pearl", chance = 4230}, + {name = "gold coin", chance = 40000, maxCount = 100}, + {name = "gold coin", chance = 50000, maxCount = 35}, + {name = "platinum coin", chance = 40430}, + {name = "yellow gem", chance = 1040}, + {name = "waspoid claw", chance = 9096}, + {name = "waspoid wing", chance = 13890}, + {name = "compound eye", chance = 6060}, + {name = "grasshopper legs", chance = 230}, + {name = "carapace shield", chance = 120}, + {name = "hive scythe", chance = 330} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -248, condition = {type = CONDITION_POISON, totalDamage = 400, interval = 4000}}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -110, maxDamage = -180, radius = 3, effect = CONST_ME_POISONAREA, target = true}, + {name ="combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -80, maxDamage = -100, range = 7, shootEffect = CONST_ANI_POISON, target = false} +} + +monster.defenses = { + defense = 25, + armor = 25 +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = -5}, + {type = COMBAT_ENERGYDAMAGE, percent = 25}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -10}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = -5}, + {type = COMBAT_DEATHDAMAGE , percent = 5} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/vermins/wiggler.lua b/data/monster/vermins/wiggler.lua new file mode 100644 index 00000000000..8693900b2a5 --- /dev/null +++ b/data/monster/vermins/wiggler.lua @@ -0,0 +1,131 @@ +local mType = Game.createMonsterType("Wiggler") +local monster = {} + +monster.description = "a wiggler" +monster.experience = 900 +monster.outfit = { + lookType = 510, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.raceId = 899 +monster.Bestiary = { + class = "Vermin", + race = BESTY_RACE_VERMIN, + toKill = 1000, + FirstUnlock = 50, + SecondUnlock = 500, + CharmsPoints = 25, + Stars = 3, + Occurrence = 0, + Locations = "Can be found in Truffels Garden as well as the Mushroom Gardens." + } + +monster.health = 1200 +monster.maxHealth = 1200 +monster.race = "venom" +monster.corpse = 18483 +monster.speed = 360 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + damage = 30, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + pushable = false, + rewardBoss = false, + illusionable = true, + canPushItems = true, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 359, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = true, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "Zzzrp", yell = false}, + {text = "Crick! Crick!", yell = false} +} + +monster.loot = { + {name = "gold coin", chance = 100000, maxCount = 100}, + {name = "platinum coin", chance = 14790}, + {name = "terra rod", chance = 850}, + {name = "serpent sword", chance = 1360}, + {name = "black shield", chance = 1320}, + {name = "white mushroom", chance = 7142, maxCount = 5}, + {name = "blue piece of cloth", chance = 2080}, + {name = "yellow piece of cloth", chance = 2160}, + {name = "strong health potion", chance = 4930}, + {name = "strong mana potion", chance = 5250}, + {name = "crystalline arrow", chance = 15540, maxCount = 5}, + {name = "green crystal splinter", chance = 3600}, + {name = "green crystal fragment", chance = 2070}, + {name = "drill bolt", chance = 15260, maxCount = 5} +} + +monster.attacks = { + {name ="melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -200, condition = {type = CONDITION_POISON, totalDamage = 500, interval = 4000}}, + {name ="combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -180, maxDamage = -270, length = 4, spread = 3, target = false}, + -- poison + {name ="condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -160, maxDamage = -200, range = 7, shootEffect = CONST_ANI_POISONARROW, effect = CONST_ME_SMALLPLANTS, target = false}, + {name ="speed", interval = 2000, chance = 15, speedChange = -700, length = 3, spread = 2, effect = CONST_ME_HITAREA, target = false, duration = 30000} +} + +monster.defenses = { + defense = 15, + armor = 15, + {name ="speed", interval = 2000, chance = 15, speedChange = 510, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 5}, + {type = COMBAT_EARTHDAMAGE, percent = 100}, + {type = COMBAT_FIREDAMAGE, percent = -5}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 10} +} + +monster.immunities = { + {type = "paralyze", condition = true}, + {type = "outfit", condition = false}, + {type = "invisible", condition = true}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/wild_magics/wild_fire_magic.lua b/data/monster/wild_magics/wild_fire_magic.lua new file mode 100644 index 00000000000..71a21be40a1 --- /dev/null +++ b/data/monster/wild_magics/wild_fire_magic.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Wild Fire Magic") +local monster = {} + +monster.description = "a wild fire magic" +monster.experience = 0 +monster.outfit = { + lookType = 0, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1 +monster.maxHealth = 1 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { +} + +monster.defenses = { + defense = 0, + armor = 0, + {name ="effect", interval = 100, chance = 100, radius = 1, effect = CONST_ME_FIREWORK_YELLOW, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/wild_magics/wild_fury_magic.lua b/data/monster/wild_magics/wild_fury_magic.lua new file mode 100644 index 00000000000..0b54b5e084b --- /dev/null +++ b/data/monster/wild_magics/wild_fury_magic.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Wild Fury Magic") +local monster = {} + +monster.description = "a wild fury magic" +monster.experience = 0 +monster.outfit = { + lookType = 0, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1 +monster.maxHealth = 1 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { +} + +monster.defenses = { + defense = 0, + armor = 0, + {name ="effect", interval = 100, chance = 100, radius = 1, effect = CONST_ME_MAGIC_RED, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/wild_magics/wild_nature_magic.lua b/data/monster/wild_magics/wild_nature_magic.lua new file mode 100644 index 00000000000..cb20e1221c2 --- /dev/null +++ b/data/monster/wild_magics/wild_nature_magic.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Wild Nature Magic") +local monster = {} + +monster.description = "a wild nature magic" +monster.experience = 0 +monster.outfit = { + lookType = 0, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1 +monster.maxHealth = 1 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { +} + +monster.defenses = { + defense = 0, + armor = 0, + {name ="effect", interval = 100, chance = 100, radius = 1, effect = CONST_ME_MAGIC_GREEN, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/monster/wild_magics/wild_water_magic.lua b/data/monster/wild_magics/wild_water_magic.lua new file mode 100644 index 00000000000..e651a2dfd4e --- /dev/null +++ b/data/monster/wild_magics/wild_water_magic.lua @@ -0,0 +1,99 @@ +local mType = Game.createMonsterType("Wild Water Magic") +local monster = {} + +monster.description = "a wild water magic" +monster.experience = 0 +monster.outfit = { + lookType = 0, + lookHead = 0, + lookBody = 0, + lookLegs = 0, + lookFeet = 0, + lookAddons = 0, + lookMount = 0 +} + +monster.health = 1 +monster.maxHealth = 1 +monster.race = "undead" +monster.corpse = 0 +monster.speed = 210 +monster.manaCost = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 4000, + chance = 10 +} + +monster.strategiesTarget = { + nearest = 70, + health = 10, + damage = 10, + random = 10, +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = false, + convinceable = false, + pushable = true, + rewardBoss = false, + illusionable = false, + canPushItems = false, + canPushCreatures = false, + staticAttackChance = 90, + targetDistance = 1, + runHealth = 1, + healthHidden = false, + isBlockable = false, + canWalkOnEnergy = false, + canWalkOnFire = false, + canWalkOnPoison = false, + pet = false +} + +monster.light = { + level = 0, + color = 0 +} + +monster.voices = { + interval = 5000, + chance = 10, +} + +monster.loot = { +} + +monster.attacks = { +} + +monster.defenses = { + defense = 0, + armor = 0, + {name ="effect", interval = 100, chance = 100, radius = 1, effect = CONST_ME_MAGIC_BLUE, target = false} +} + +monster.elements = { + {type = COMBAT_PHYSICALDAMAGE, percent = 0}, + {type = COMBAT_ENERGYDAMAGE, percent = 0}, + {type = COMBAT_EARTHDAMAGE, percent = 0}, + {type = COMBAT_FIREDAMAGE, percent = 0}, + {type = COMBAT_LIFEDRAIN, percent = 0}, + {type = COMBAT_MANADRAIN, percent = 0}, + {type = COMBAT_DROWNDAMAGE, percent = 0}, + {type = COMBAT_ICEDAMAGE, percent = 0}, + {type = COMBAT_HOLYDAMAGE , percent = 0}, + {type = COMBAT_DEATHDAMAGE , percent = 0} +} + +monster.immunities = { + {type = "paralyze", condition = false}, + {type = "outfit", condition = false}, + {type = "invisible", condition = false}, + {type = "bleed", condition = false} +} + +mType:register(monster) diff --git a/data/npc/....xml b/data/npc/....xml new file mode 100644 index 00000000000..3a5025af4aa --- /dev/null +++ b/data/npc/....xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/data/npc/a_bearded_woman.xml b/data/npc/a_bearded_woman.xml new file mode 100644 index 00000000000..4d9d5566f55 --- /dev/null +++ b/data/npc/a_bearded_woman.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_beautiful_girl.xml b/data/npc/a_beautiful_girl.xml new file mode 100644 index 00000000000..a3f55dd93ab --- /dev/null +++ b/data/npc/a_beautiful_girl.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/a_beggar.xml b/data/npc/a_beggar.xml new file mode 100644 index 00000000000..76ce103a8ca --- /dev/null +++ b/data/npc/a_beggar.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_behemoth.xml b/data/npc/a_behemoth.xml new file mode 100644 index 00000000000..6da2d889e83 --- /dev/null +++ b/data/npc/a_behemoth.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_confused_frog.xml b/data/npc/a_confused_frog.xml new file mode 100644 index 00000000000..7ff12598b31 --- /dev/null +++ b/data/npc/a_confused_frog.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_dark_priestess.xml b/data/npc/a_dark_priestess.xml new file mode 100644 index 00000000000..05aa08a6bd3 --- /dev/null +++ b/data/npc/a_dark_priestess.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_dead_bureaucrat1.xml b/data/npc/a_dead_bureaucrat1.xml new file mode 100644 index 00000000000..71e8dac56ab --- /dev/null +++ b/data/npc/a_dead_bureaucrat1.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_dead_bureaucrat2.xml b/data/npc/a_dead_bureaucrat2.xml new file mode 100644 index 00000000000..0e9989fa4fe --- /dev/null +++ b/data/npc/a_dead_bureaucrat2.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_dead_bureaucrat3.xml b/data/npc/a_dead_bureaucrat3.xml new file mode 100644 index 00000000000..35f841cce90 --- /dev/null +++ b/data/npc/a_dead_bureaucrat3.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_dead_bureaucrat4.xml b/data/npc/a_dead_bureaucrat4.xml new file mode 100644 index 00000000000..50f321b6833 --- /dev/null +++ b/data/npc/a_dead_bureaucrat4.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_dragon_lord.xml b/data/npc/a_dragon_lord.xml new file mode 100644 index 00000000000..de02f6104d1 --- /dev/null +++ b/data/npc/a_dragon_lord.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_dragon_mother.xml b/data/npc/a_dragon_mother.xml new file mode 100644 index 00000000000..538267eac9a --- /dev/null +++ b/data/npc/a_dragon_mother.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/data/npc/a_drillworm.xml b/data/npc/a_drillworm.xml new file mode 100644 index 00000000000..92fa3af3471 --- /dev/null +++ b/data/npc/a_drillworm.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_dwarven_ghost.xml b/data/npc/a_dwarven_ghost.xml new file mode 100644 index 00000000000..2ccbee3cdfc --- /dev/null +++ b/data/npc/a_dwarven_ghost.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_fading_memory.xml b/data/npc/a_fading_memory.xml new file mode 100644 index 00000000000..44c885207a4 --- /dev/null +++ b/data/npc/a_fading_memory.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_fluffy_squirrel.xml b/data/npc/a_fluffy_squirrel.xml new file mode 100644 index 00000000000..7cb5100f313 --- /dev/null +++ b/data/npc/a_fluffy_squirrel.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/data/npc/a_frog.xml b/data/npc/a_frog.xml new file mode 100644 index 00000000000..9248633e456 --- /dev/null +++ b/data/npc/a_frog.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_ghostly_guardian.xml b/data/npc/a_ghostly_guardian.xml new file mode 100644 index 00000000000..af4a41cbfac --- /dev/null +++ b/data/npc/a_ghostly_guardian.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_ghostly_knight.xml b/data/npc/a_ghostly_knight.xml new file mode 100644 index 00000000000..a57389ba034 --- /dev/null +++ b/data/npc/a_ghostly_knight.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_ghostly_sage.xml b/data/npc/a_ghostly_sage.xml new file mode 100644 index 00000000000..02d8686c407 --- /dev/null +++ b/data/npc/a_ghostly_sage.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_ghostly_woman.xml b/data/npc/a_ghostly_woman.xml new file mode 100644 index 00000000000..956126f77c8 --- /dev/null +++ b/data/npc/a_ghostly_woman.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_ghostly_woman_ghostland.xml b/data/npc/a_ghostly_woman_ghostland.xml new file mode 100644 index 00000000000..6fe760f2432 --- /dev/null +++ b/data/npc/a_ghostly_woman_ghostland.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_goblin_exile.xml b/data/npc/a_goblin_exile.xml new file mode 100644 index 00000000000..1ea4a909ca6 --- /dev/null +++ b/data/npc/a_goblin_exile.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_grumpy_cyclops.xml b/data/npc/a_grumpy_cyclops.xml new file mode 100644 index 00000000000..324cdb4b675 --- /dev/null +++ b/data/npc/a_grumpy_cyclops.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_lost_basher.xml b/data/npc/a_lost_basher.xml new file mode 100644 index 00000000000..545bfc66f2b --- /dev/null +++ b/data/npc/a_lost_basher.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_lost_husher.xml b/data/npc/a_lost_husher.xml new file mode 100644 index 00000000000..d25ebbde071 --- /dev/null +++ b/data/npc/a_lost_husher.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_lost_soul.xml b/data/npc/a_lost_soul.xml new file mode 100644 index 00000000000..b8dbdac9dd1 --- /dev/null +++ b/data/npc/a_lost_soul.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_lost_thrower.xml b/data/npc/a_lost_thrower.xml new file mode 100644 index 00000000000..2b827a8d55c --- /dev/null +++ b/data/npc/a_lost_thrower.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_majestic_warwolf.xml b/data/npc/a_majestic_warwolf.xml new file mode 100644 index 00000000000..b2c1e42c9cd --- /dev/null +++ b/data/npc/a_majestic_warwolf.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_nightmare_scion.xml b/data/npc/a_nightmare_scion.xml new file mode 100644 index 00000000000..647817d4e02 --- /dev/null +++ b/data/npc/a_nightmare_scion.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_prisoner.xml b/data/npc/a_prisoner.xml new file mode 100644 index 00000000000..6e86a478484 --- /dev/null +++ b/data/npc/a_prisoner.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_restless_soul.xml b/data/npc/a_restless_soul.xml new file mode 100644 index 00000000000..afedb95e6f4 --- /dev/null +++ b/data/npc/a_restless_soul.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/a_sleeping_dragon.xml b/data/npc/a_sleeping_dragon.xml new file mode 100644 index 00000000000..ac62b9cf550 --- /dev/null +++ b/data/npc/a_sleeping_dragon.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_starving_dog.xml b/data/npc/a_starving_dog.xml new file mode 100644 index 00000000000..8b594039f70 --- /dev/null +++ b/data/npc/a_starving_dog.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/a_strange_chalice.xml b/data/npc/a_strange_chalice.xml new file mode 100644 index 00000000000..b0406b1b57f --- /dev/null +++ b/data/npc/a_strange_chalice.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/a_strange_fellow.xml b/data/npc/a_strange_fellow.xml new file mode 100644 index 00000000000..3626f1bba3b --- /dev/null +++ b/data/npc/a_strange_fellow.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_swan.xml b/data/npc/a_swan.xml new file mode 100644 index 00000000000..e155f25dec1 --- /dev/null +++ b/data/npc/a_swan.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/a_sweaty_cyclops.xml b/data/npc/a_sweaty_cyclops.xml new file mode 100644 index 00000000000..18ba7f9be4e --- /dev/null +++ b/data/npc/a_sweaty_cyclops.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_tainted_soul.xml b/data/npc/a_tainted_soul.xml new file mode 100644 index 00000000000..c037ed2d68f --- /dev/null +++ b/data/npc/a_tainted_soul.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_tortured_soul.xml b/data/npc/a_tortured_soul.xml new file mode 100644 index 00000000000..a821a3ffff0 --- /dev/null +++ b/data/npc/a_tortured_soul.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_vulcongra.xml b/data/npc/a_vulcongra.xml new file mode 100644 index 00000000000..de5c61409be --- /dev/null +++ b/data/npc/a_vulcongra.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_weakened_forest_fury.xml b/data/npc/a_weakened_forest_fury.xml new file mode 100644 index 00000000000..13d03e75bc2 --- /dev/null +++ b/data/npc/a_weakened_forest_fury.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_wrinkled_bonelord.xml b/data/npc/a_wrinkled_bonelord.xml new file mode 100644 index 00000000000..dbec013c55c --- /dev/null +++ b/data/npc/a_wrinkled_bonelord.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/a_wyrm.xml b/data/npc/a_wyrm.xml new file mode 100644 index 00000000000..d0cd7f6f557 --- /dev/null +++ b/data/npc/a_wyrm.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/abran_ironeye.xml b/data/npc/abran_ironeye.xml new file mode 100644 index 00000000000..05cb9919332 --- /dev/null +++ b/data/npc/abran_ironeye.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/data/npc/admiral_wyrmslicer.xml b/data/npc/admiral_wyrmslicer.xml new file mode 100644 index 00000000000..d1ee0c953f8 --- /dev/null +++ b/data/npc/admiral_wyrmslicer.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/adrenius.xml b/data/npc/adrenius.xml new file mode 100644 index 00000000000..b5b21ac652b --- /dev/null +++ b/data/npc/adrenius.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ahmet.xml b/data/npc/ahmet.xml new file mode 100644 index 00000000000..f1815688b17 --- /dev/null +++ b/data/npc/ahmet.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + diff --git a/data/npc/ajax.xml b/data/npc/ajax.xml new file mode 100644 index 00000000000..79570568033 --- /dev/null +++ b/data/npc/ajax.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/al_dee.xml b/data/npc/al_dee.xml new file mode 100644 index 00000000000..226349e7eac --- /dev/null +++ b/data/npc/al_dee.xml @@ -0,0 +1,22 @@ + + + + + + + + + + diff --git a/data/npc/alaistar.xml b/data/npc/alaistar.xml new file mode 100644 index 00000000000..965779c40f6 --- /dev/null +++ b/data/npc/alaistar.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + diff --git a/data/npc/albert.xml b/data/npc/albert.xml new file mode 100644 index 00000000000..79f688a946e --- /dev/null +++ b/data/npc/albert.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/albinius.xml b/data/npc/albinius.xml new file mode 100644 index 00000000000..728d011411d --- /dev/null +++ b/data/npc/albinius.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/aldo.xml b/data/npc/aldo.xml new file mode 100644 index 00000000000..e2232ed5fe9 --- /dev/null +++ b/data/npc/aldo.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + diff --git a/data/npc/alesar.xml b/data/npc/alesar.xml new file mode 100644 index 00000000000..050e98c67c2 --- /dev/null +++ b/data/npc/alesar.xml @@ -0,0 +1,39 @@ + + + + + + + + + + diff --git a/data/npc/alexander.xml b/data/npc/alexander.xml new file mode 100644 index 00000000000..ba8e2080d0c --- /dev/null +++ b/data/npc/alexander.xml @@ -0,0 +1,56 @@ + + + + + + + + + + diff --git a/data/npc/alia.xml b/data/npc/alia.xml new file mode 100644 index 00000000000..5ca6da4496c --- /dev/null +++ b/data/npc/alia.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/alissa.xml b/data/npc/alissa.xml new file mode 100644 index 00000000000..223f32edce4 --- /dev/null +++ b/data/npc/alissa.xml @@ -0,0 +1,26 @@ + + + + + + + + + \ No newline at end of file diff --git a/data/npc/alkestios.xml b/data/npc/alkestios.xml new file mode 100644 index 00000000000..beba583529d --- /dev/null +++ b/data/npc/alkestios.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/allen.xml b/data/npc/allen.xml new file mode 100644 index 00000000000..05bdb157cd2 --- /dev/null +++ b/data/npc/allen.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + diff --git a/data/npc/alternative_rock.xml b/data/npc/alternative_rock.xml new file mode 100644 index 00000000000..680ab9e01b6 --- /dev/null +++ b/data/npc/alternative_rock.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/alwin.xml b/data/npc/alwin.xml new file mode 100644 index 00000000000..b336a6460d5 --- /dev/null +++ b/data/npc/alwin.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/data/npc/alyxo.xml b/data/npc/alyxo.xml new file mode 100644 index 00000000000..93e6bc1b7fe --- /dev/null +++ b/data/npc/alyxo.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/amanda.xml b/data/npc/amanda.xml new file mode 100644 index 00000000000..e7a2a090566 --- /dev/null +++ b/data/npc/amanda.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/amarie.xml b/data/npc/amarie.xml new file mode 100644 index 00000000000..a3b93f26d61 --- /dev/null +++ b/data/npc/amarie.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ambassador_of_rathleton.xml b/data/npc/ambassador_of_rathleton.xml new file mode 100644 index 00000000000..f07f376c281 --- /dev/null +++ b/data/npc/ambassador_of_rathleton.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/amber.xml b/data/npc/amber.xml new file mode 100644 index 00000000000..01dadb8034b --- /dev/null +++ b/data/npc/amber.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/an_ancient_priest.xml b/data/npc/an_ancient_priest.xml new file mode 100644 index 00000000000..8e1967c1997 --- /dev/null +++ b/data/npc/an_ancient_priest.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/an_apparition.xml b/data/npc/an_apparition.xml new file mode 100644 index 00000000000..7dbe2ae50f2 --- /dev/null +++ b/data/npc/an_apparition.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/an_imprisoned_goblin.xml b/data/npc/an_imprisoned_goblin.xml new file mode 100644 index 00000000000..aff8ca35481 --- /dev/null +++ b/data/npc/an_imprisoned_goblin.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/an_old_dragon_lord.xml b/data/npc/an_old_dragon_lord.xml new file mode 100644 index 00000000000..3861818369d --- /dev/null +++ b/data/npc/an_old_dragon_lord.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/an_orc_guard.xml b/data/npc/an_orc_guard.xml new file mode 100644 index 00000000000..ffca181e373 --- /dev/null +++ b/data/npc/an_orc_guard.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/anderson.xml b/data/npc/anderson.xml new file mode 100644 index 00000000000..8e7b64ad871 --- /dev/null +++ b/data/npc/anderson.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/andrew_lyze.xml b/data/npc/andrew_lyze.xml new file mode 100644 index 00000000000..2385cf4d3bb --- /dev/null +++ b/data/npc/andrew_lyze.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/anerui.xml b/data/npc/anerui.xml new file mode 100644 index 00000000000..2cce9df4560 --- /dev/null +++ b/data/npc/anerui.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/data/npc/aneus.xml b/data/npc/aneus.xml new file mode 100644 index 00000000000..0a75eb0407b --- /dev/null +++ b/data/npc/aneus.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/angelina.xml b/data/npc/angelina.xml new file mode 100644 index 00000000000..13c5eb03c80 --- /dev/null +++ b/data/npc/angelina.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/angelo.xml b/data/npc/angelo.xml new file mode 100644 index 00000000000..fc306e47e1c --- /dev/null +++ b/data/npc/angelo.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/angus.xml b/data/npc/angus.xml new file mode 100644 index 00000000000..896e178ef4c --- /dev/null +++ b/data/npc/angus.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + diff --git a/data/npc/appaloosa.xml b/data/npc/appaloosa.xml new file mode 100644 index 00000000000..bc977e2fc51 --- /dev/null +++ b/data/npc/appaloosa.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/archery.xml b/data/npc/archery.xml new file mode 100644 index 00000000000..5742f1b52ab --- /dev/null +++ b/data/npc/archery.xml @@ -0,0 +1,39 @@ + + + + + + + + + diff --git a/data/npc/archery_rook.xml b/data/npc/archery_rook.xml new file mode 100644 index 00000000000..b45a9d59284 --- /dev/null +++ b/data/npc/archery_rook.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/ariella.xml b/data/npc/ariella.xml new file mode 100644 index 00000000000..036e913e28c --- /dev/null +++ b/data/npc/ariella.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + diff --git a/data/npc/arito.xml b/data/npc/arito.xml new file mode 100644 index 00000000000..dd177d4fd03 --- /dev/null +++ b/data/npc/arito.xml @@ -0,0 +1,19 @@ + + + + + + + + + + diff --git a/data/npc/arkarra.xml b/data/npc/arkarra.xml new file mode 100644 index 00000000000..4b714cfa787 --- /dev/null +++ b/data/npc/arkarra.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/arkhothep.xml b/data/npc/arkhothep.xml new file mode 100644 index 00000000000..70c2aa692a5 --- /dev/null +++ b/data/npc/arkhothep.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/arkulius.xml b/data/npc/arkulius.xml new file mode 100644 index 00000000000..165bd6604d4 --- /dev/null +++ b/data/npc/arkulius.xml @@ -0,0 +1,18 @@ + + + + + + + + + diff --git a/data/npc/armenius_npc.xml b/data/npc/armenius_npc.xml new file mode 100644 index 00000000000..214a368b219 --- /dev/null +++ b/data/npc/armenius_npc.xml @@ -0,0 +1,18 @@ + + + + + + + + + diff --git a/data/npc/arnold.xml b/data/npc/arnold.xml new file mode 100644 index 00000000000..490062577f9 --- /dev/null +++ b/data/npc/arnold.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/data/npc/aruda.xml b/data/npc/aruda.xml new file mode 100644 index 00000000000..a068ecce40f --- /dev/null +++ b/data/npc/aruda.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ashari.xml b/data/npc/ashari.xml new file mode 100644 index 00000000000..975b73bb5e4 --- /dev/null +++ b/data/npc/ashari.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ashtamor.xml b/data/npc/ashtamor.xml new file mode 100644 index 00000000000..33278c211c5 --- /dev/null +++ b/data/npc/ashtamor.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/data/npc/asima.xml b/data/npc/asima.xml new file mode 100644 index 00000000000..2d460eba064 --- /dev/null +++ b/data/npc/asima.xml @@ -0,0 +1,70 @@ + + + + + + + + + + diff --git a/data/npc/asnarus.xml b/data/npc/asnarus.xml new file mode 100644 index 00000000000..ce0371315fe --- /dev/null +++ b/data/npc/asnarus.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + diff --git a/data/npc/asrak.xml b/data/npc/asrak.xml new file mode 100644 index 00000000000..41323e34fc6 --- /dev/null +++ b/data/npc/asrak.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/asralius.xml b/data/npc/asralius.xml new file mode 100644 index 00000000000..e8ea41cc9a9 --- /dev/null +++ b/data/npc/asralius.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/atrad.xml b/data/npc/atrad.xml new file mode 100644 index 00000000000..e85f99f4f6f --- /dev/null +++ b/data/npc/atrad.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/data/npc/atur.xml b/data/npc/atur.xml new file mode 100644 index 00000000000..391eee1904c --- /dev/null +++ b/data/npc/atur.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/aurita.xml b/data/npc/aurita.xml new file mode 100644 index 00000000000..00e7a7c924f --- /dev/null +++ b/data/npc/aurita.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/auron.xml b/data/npc/auron.xml new file mode 100644 index 00000000000..3198e865cb5 --- /dev/null +++ b/data/npc/auron.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + diff --git a/data/npc/avar_tar.xml b/data/npc/avar_tar.xml new file mode 100644 index 00000000000..e7d2fffcef0 --- /dev/null +++ b/data/npc/avar_tar.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/awarness_of_the_emperor.xml b/data/npc/awarness_of_the_emperor.xml new file mode 100644 index 00000000000..09dba32b8c7 --- /dev/null +++ b/data/npc/awarness_of_the_emperor.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/azalea.xml b/data/npc/azalea.xml new file mode 100644 index 00000000000..0fc94f937e7 --- /dev/null +++ b/data/npc/azalea.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/azil.xml b/data/npc/azil.xml new file mode 100644 index 00000000000..bb9b184d2da --- /dev/null +++ b/data/npc/azil.xml @@ -0,0 +1,73 @@ + + + + + + + + + + diff --git a/data/npc/baa_leal.xml b/data/npc/baa_leal.xml new file mode 100644 index 00000000000..60738de4a3d --- /dev/null +++ b/data/npc/baa_leal.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/baltim.xml b/data/npc/baltim.xml new file mode 100644 index 00000000000..e3f3587d260 --- /dev/null +++ b/data/npc/baltim.xml @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + diff --git a/data/npc/bambi_bonecrusher.xml b/data/npc/bambi_bonecrusher.xml new file mode 100644 index 00000000000..510389d8ed3 --- /dev/null +++ b/data/npc/bambi_bonecrusher.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/barazbaz.xml b/data/npc/barazbaz.xml new file mode 100644 index 00000000000..8cb63a5c2e1 --- /dev/null +++ b/data/npc/barazbaz.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/barbara.xml b/data/npc/barbara.xml new file mode 100644 index 00000000000..835856025c6 --- /dev/null +++ b/data/npc/barbara.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/barnabas_dee.xml b/data/npc/barnabas_dee.xml new file mode 100644 index 00000000000..cfafe3593d5 --- /dev/null +++ b/data/npc/barnabas_dee.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/barney.xml b/data/npc/barney.xml new file mode 100644 index 00000000000..3ff2a729d9d --- /dev/null +++ b/data/npc/barney.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/barry.xml b/data/npc/barry.xml new file mode 100644 index 00000000000..0368ac1290d --- /dev/null +++ b/data/npc/barry.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/bashira.xml b/data/npc/bashira.xml new file mode 100644 index 00000000000..85c685b233b --- /dev/null +++ b/data/npc/bashira.xml @@ -0,0 +1,49 @@ + + + + + + + + + + diff --git a/data/npc/basilisk.xml b/data/npc/basilisk.xml new file mode 100644 index 00000000000..82c8e14b272 --- /dev/null +++ b/data/npc/basilisk.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/baxter.xml b/data/npc/baxter.xml new file mode 100644 index 00000000000..9246f04c89e --- /dev/null +++ b/data/npc/baxter.xml @@ -0,0 +1,18 @@ + + + + + + + + + + diff --git a/data/npc/beatrice.xml b/data/npc/beatrice.xml new file mode 100644 index 00000000000..0dad32cb6d4 --- /dev/null +++ b/data/npc/beatrice.xml @@ -0,0 +1,46 @@ + + + + + + + + + + diff --git a/data/npc/benevola.xml b/data/npc/benevola.xml new file mode 100644 index 00000000000..b7031ca9c5c --- /dev/null +++ b/data/npc/benevola.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/benjamin.xml b/data/npc/benjamin.xml new file mode 100644 index 00000000000..fe3d9564a59 --- /dev/null +++ b/data/npc/benjamin.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + diff --git a/data/npc/berenice.xml b/data/npc/berenice.xml new file mode 100644 index 00000000000..2a7c4521886 --- /dev/null +++ b/data/npc/berenice.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/data/npc/bertha.xml b/data/npc/bertha.xml new file mode 100644 index 00000000000..b96d850c136 --- /dev/null +++ b/data/npc/bertha.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + diff --git a/data/npc/bertram.xml b/data/npc/bertram.xml new file mode 100644 index 00000000000..44815061138 --- /dev/null +++ b/data/npc/bertram.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/bezil.xml b/data/npc/bezil.xml new file mode 100644 index 00000000000..ae4f761c456 --- /dev/null +++ b/data/npc/bezil.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + diff --git a/data/npc/bigfoot_soldier.xml b/data/npc/bigfoot_soldier.xml new file mode 100644 index 00000000000..982a969bc13 --- /dev/null +++ b/data/npc/bigfoot_soldier.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/bill_the_worker.xml b/data/npc/bill_the_worker.xml new file mode 100644 index 00000000000..25cf6578f9f --- /dev/null +++ b/data/npc/bill_the_worker.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/billy.xml b/data/npc/billy.xml new file mode 100644 index 00000000000..5fce633acca --- /dev/null +++ b/data/npc/billy.xml @@ -0,0 +1,23 @@ + + + + + + + + + + diff --git a/data/npc/black_bert.xml b/data/npc/black_bert.xml new file mode 100644 index 00000000000..884b804fd77 --- /dev/null +++ b/data/npc/black_bert.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/blind_orc.xml b/data/npc/blind_orc.xml new file mode 100644 index 00000000000..238d0f83145 --- /dev/null +++ b/data/npc/blind_orc.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/blossom_bonecrusher.xml b/data/npc/blossom_bonecrusher.xml new file mode 100644 index 00000000000..0a711839d41 --- /dev/null +++ b/data/npc/blossom_bonecrusher.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/bo_ques.xml b/data/npc/bo_ques.xml new file mode 100644 index 00000000000..ad841ccc98b --- /dev/null +++ b/data/npc/bo_ques.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/bob_the_worker.xml b/data/npc/bob_the_worker.xml new file mode 100644 index 00000000000..3158c3e9a72 --- /dev/null +++ b/data/npc/bob_the_worker.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/bolfona.xml b/data/npc/bolfona.xml new file mode 100644 index 00000000000..99e5ee909a0 --- /dev/null +++ b/data/npc/bolfona.xml @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/data/npc/bonifacius.xml b/data/npc/bonifacius.xml new file mode 100644 index 00000000000..cf25cb1a1f0 --- /dev/null +++ b/data/npc/bonifacius.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + diff --git a/data/npc/boozer.xml b/data/npc/boozer.xml new file mode 100644 index 00000000000..63d1565d6c5 --- /dev/null +++ b/data/npc/boozer.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + diff --git a/data/npc/borkas.xml b/data/npc/borkas.xml new file mode 100644 index 00000000000..c25cb0aaf99 --- /dev/null +++ b/data/npc/borkas.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + diff --git a/data/npc/boveas.xml b/data/npc/boveas.xml new file mode 100644 index 00000000000..14fcc7f8a19 --- /dev/null +++ b/data/npc/boveas.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/bozarn.xml b/data/npc/bozarn.xml new file mode 100644 index 00000000000..ad5160a5528 --- /dev/null +++ b/data/npc/bozarn.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/bozo.xml b/data/npc/bozo.xml new file mode 100644 index 00000000000..678d19ab415 --- /dev/null +++ b/data/npc/bozo.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/braden.xml b/data/npc/braden.xml new file mode 100644 index 00000000000..988231cc64f --- /dev/null +++ b/data/npc/braden.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/bradford.xml b/data/npc/bradford.xml new file mode 100644 index 00000000000..82847f06cd8 --- /dev/null +++ b/data/npc/bradford.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/data/npc/brasith.xml b/data/npc/brasith.xml new file mode 100644 index 00000000000..840f5e5648c --- /dev/null +++ b/data/npc/brasith.xml @@ -0,0 +1,24 @@ + + + + + + + + + diff --git a/data/npc/brengus.xml b/data/npc/brengus.xml new file mode 100644 index 00000000000..04deae3a5a0 --- /dev/null +++ b/data/npc/brengus.xml @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + diff --git a/data/npc/brewster.xml b/data/npc/brewster.xml new file mode 100644 index 00000000000..e9eab417f69 --- /dev/null +++ b/data/npc/brewster.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/briasol.xml b/data/npc/briasol.xml new file mode 100644 index 00000000000..e3f1f9baa35 --- /dev/null +++ b/data/npc/briasol.xml @@ -0,0 +1,73 @@ + + + + + + + + + + diff --git a/data/npc/bright_percht_sleigh.xml b/data/npc/bright_percht_sleigh.xml new file mode 100644 index 00000000000..2f1fa70914a --- /dev/null +++ b/data/npc/bright_percht_sleigh.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/brodrosch.xml b/data/npc/brodrosch.xml new file mode 100644 index 00000000000..0580d0404fc --- /dev/null +++ b/data/npc/brodrosch.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/broken_servant_sentry.xml b/data/npc/broken_servant_sentry.xml new file mode 100644 index 00000000000..ae3f1a45b49 --- /dev/null +++ b/data/npc/broken_servant_sentry.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/brom.xml b/data/npc/brom.xml new file mode 100644 index 00000000000..0924c79525c --- /dev/null +++ b/data/npc/brom.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/bron.xml b/data/npc/bron.xml new file mode 100644 index 00000000000..b84f6ac412f --- /dev/null +++ b/data/npc/bron.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/bruce.xml b/data/npc/bruce.xml new file mode 100644 index 00000000000..bfbd538da1c --- /dev/null +++ b/data/npc/bruce.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/bruno.xml b/data/npc/bruno.xml new file mode 100644 index 00000000000..356c41451d9 --- /dev/null +++ b/data/npc/bruno.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/brutus.xml b/data/npc/brutus.xml new file mode 100644 index 00000000000..600b88ab523 --- /dev/null +++ b/data/npc/brutus.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/buddel.xml b/data/npc/buddel.xml new file mode 100644 index 00000000000..559417ce832 --- /dev/null +++ b/data/npc/buddel.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/data/npc/buddel_helheim.xml b/data/npc/buddel_helheim.xml new file mode 100644 index 00000000000..697e9535436 --- /dev/null +++ b/data/npc/buddel_helheim.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/data/npc/buddel_okolnir.xml b/data/npc/buddel_okolnir.xml new file mode 100644 index 00000000000..9b75f0b1916 --- /dev/null +++ b/data/npc/buddel_okolnir.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/data/npc/buddel_raider_camp.xml b/data/npc/buddel_raider_camp.xml new file mode 100644 index 00000000000..e073284fb13 --- /dev/null +++ b/data/npc/buddel_raider_camp.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/data/npc/buddel_tyrsung.xml b/data/npc/buddel_tyrsung.xml new file mode 100644 index 00000000000..1bee4e78620 --- /dev/null +++ b/data/npc/buddel_tyrsung.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/data/npc/budrik.xml b/data/npc/budrik.xml new file mode 100644 index 00000000000..fe54bc17c75 --- /dev/null +++ b/data/npc/budrik.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/bunny_bonecrusher.xml b/data/npc/bunny_bonecrusher.xml new file mode 100644 index 00000000000..2780e98ffb3 --- /dev/null +++ b/data/npc/bunny_bonecrusher.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/busty_bonecrusher.xml b/data/npc/busty_bonecrusher.xml new file mode 100644 index 00000000000..ad9212537ab --- /dev/null +++ b/data/npc/busty_bonecrusher.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/cael.xml b/data/npc/cael.xml new file mode 100644 index 00000000000..32e0260a8c4 --- /dev/null +++ b/data/npc/cael.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/cameron.xml b/data/npc/cameron.xml new file mode 100644 index 00000000000..ef65c944f62 --- /dev/null +++ b/data/npc/cameron.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/captain_bluebear.xml b/data/npc/captain_bluebear.xml new file mode 100644 index 00000000000..f5edb266112 --- /dev/null +++ b/data/npc/captain_bluebear.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/captain_breezelda.xml b/data/npc/captain_breezelda.xml new file mode 100644 index 00000000000..3cb85e7e1ab --- /dev/null +++ b/data/npc/captain_breezelda.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/captain_chelop.xml b/data/npc/captain_chelop.xml new file mode 100644 index 00000000000..eb4cce17ae5 --- /dev/null +++ b/data/npc/captain_chelop.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/captain_cookie.xml b/data/npc/captain_cookie.xml new file mode 100644 index 00000000000..549c5194893 --- /dev/null +++ b/data/npc/captain_cookie.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/captain_dreadnought.xml b/data/npc/captain_dreadnought.xml new file mode 100644 index 00000000000..68858e41c58 --- /dev/null +++ b/data/npc/captain_dreadnought.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/captain_fearless.xml b/data/npc/captain_fearless.xml new file mode 100644 index 00000000000..a0f5f6539b7 --- /dev/null +++ b/data/npc/captain_fearless.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/captain_greyhound.xml b/data/npc/captain_greyhound.xml new file mode 100644 index 00000000000..f0c1080a1af --- /dev/null +++ b/data/npc/captain_greyhound.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/captain_gulliver.xml b/data/npc/captain_gulliver.xml new file mode 100644 index 00000000000..27d44c685fc --- /dev/null +++ b/data/npc/captain_gulliver.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/captain_haba.xml b/data/npc/captain_haba.xml new file mode 100644 index 00000000000..6e7a98afeef --- /dev/null +++ b/data/npc/captain_haba.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/captain_haba_open_sea.xml b/data/npc/captain_haba_open_sea.xml new file mode 100644 index 00000000000..cfd2c0aec0c --- /dev/null +++ b/data/npc/captain_haba_open_sea.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/data/npc/captain_harava.xml b/data/npc/captain_harava.xml new file mode 100644 index 00000000000..630a4277b04 --- /dev/null +++ b/data/npc/captain_harava.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/captain_jack.xml b/data/npc/captain_jack.xml new file mode 100644 index 00000000000..17463c1d0e2 --- /dev/null +++ b/data/npc/captain_jack.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/captain_kurt.xml b/data/npc/captain_kurt.xml new file mode 100644 index 00000000000..aff7eb11a3f --- /dev/null +++ b/data/npc/captain_kurt.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/captain_max.xml b/data/npc/captain_max.xml new file mode 100644 index 00000000000..4a4ec7bd8f9 --- /dev/null +++ b/data/npc/captain_max.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/captain_max_calassa.xml b/data/npc/captain_max_calassa.xml new file mode 100644 index 00000000000..4f1256d97fc --- /dev/null +++ b/data/npc/captain_max_calassa.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/captain_pelagia.xml b/data/npc/captain_pelagia.xml new file mode 100644 index 00000000000..bdf5c26b18d --- /dev/null +++ b/data/npc/captain_pelagia.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/captain_seagull.xml b/data/npc/captain_seagull.xml new file mode 100644 index 00000000000..bf2d69ecc83 --- /dev/null +++ b/data/npc/captain_seagull.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/captain_seahorse.xml b/data/npc/captain_seahorse.xml new file mode 100644 index 00000000000..0bad556f5cc --- /dev/null +++ b/data/npc/captain_seahorse.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/captain_sinbeard.xml b/data/npc/captain_sinbeard.xml new file mode 100644 index 00000000000..0aa1ce0e23c --- /dev/null +++ b/data/npc/captain_sinbeard.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/captain_tiberius.xml b/data/npc/captain_tiberius.xml new file mode 100644 index 00000000000..07047586aa9 --- /dev/null +++ b/data/npc/captain_tiberius.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/captain_waverider.xml b/data/npc/captain_waverider.xml new file mode 100644 index 00000000000..4a5b1cbb9d3 --- /dev/null +++ b/data/npc/captain_waverider.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/captain_waverider_island.xml b/data/npc/captain_waverider_island.xml new file mode 100644 index 00000000000..dd141542d16 --- /dev/null +++ b/data/npc/captain_waverider_island.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/caramellia.xml b/data/npc/caramellia.xml new file mode 100644 index 00000000000..9d12fce0dd0 --- /dev/null +++ b/data/npc/caramellia.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/carina.xml b/data/npc/carina.xml new file mode 100644 index 00000000000..33efa543341 --- /dev/null +++ b/data/npc/carina.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + diff --git a/data/npc/carlos.xml b/data/npc/carlos.xml new file mode 100644 index 00000000000..f73c58ae0e0 --- /dev/null +++ b/data/npc/carlos.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/carlson.xml b/data/npc/carlson.xml new file mode 100644 index 00000000000..cf4191dbf8d --- /dev/null +++ b/data/npc/carlson.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/cassino.xml b/data/npc/cassino.xml new file mode 100644 index 00000000000..f7e48af1489 --- /dev/null +++ b/data/npc/cassino.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/cedrik.xml b/data/npc/cedrik.xml new file mode 100644 index 00000000000..79d2331ff68 --- /dev/null +++ b/data/npc/cedrik.xml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + diff --git a/data/npc/ceiron.xml b/data/npc/ceiron.xml new file mode 100644 index 00000000000..c16241e993b --- /dev/null +++ b/data/npc/ceiron.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/cerdras.xml b/data/npc/cerdras.xml new file mode 100644 index 00000000000..62226027ebd --- /dev/null +++ b/data/npc/cerdras.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/cerebrir.xml b/data/npc/cerebrir.xml new file mode 100644 index 00000000000..bea93e28326 --- /dev/null +++ b/data/npc/cerebrir.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/chantalle.xml b/data/npc/chantalle.xml new file mode 100644 index 00000000000..cc5dcdad760 --- /dev/null +++ b/data/npc/chantalle.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + diff --git a/data/npc/charles.xml b/data/npc/charles.xml new file mode 100644 index 00000000000..c828ee30440 --- /dev/null +++ b/data/npc/charles.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/charlotta.xml b/data/npc/charlotta.xml new file mode 100644 index 00000000000..7d6946c5e57 --- /dev/null +++ b/data/npc/charlotta.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/charos.xml b/data/npc/charos.xml new file mode 100644 index 00000000000..7471939ede1 --- /dev/null +++ b/data/npc/charos.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/chartan.xml b/data/npc/chartan.xml new file mode 100644 index 00000000000..6247b120e84 --- /dev/null +++ b/data/npc/chartan.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + diff --git a/data/npc/chatterbone.xml b/data/npc/chatterbone.xml new file mode 100644 index 00000000000..b148e0b978b --- /dev/null +++ b/data/npc/chatterbone.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/chavis.xml b/data/npc/chavis.xml new file mode 100644 index 00000000000..475c89ce160 --- /dev/null +++ b/data/npc/chavis.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/chemar.xml b/data/npc/chemar.xml new file mode 100644 index 00000000000..4f83feb2f02 --- /dev/null +++ b/data/npc/chemar.xml @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/data/npc/chephan.xml b/data/npc/chephan.xml new file mode 100644 index 00000000000..6e678382b2b --- /dev/null +++ b/data/npc/chephan.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + diff --git a/data/npc/chester_kahs.xml b/data/npc/chester_kahs.xml new file mode 100644 index 00000000000..b517dd46ca5 --- /dev/null +++ b/data/npc/chester_kahs.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/chief_grarkharok.xml b/data/npc/chief_grarkharok.xml new file mode 100644 index 00000000000..8ab6811421d --- /dev/null +++ b/data/npc/chief_grarkharok.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/chondur.xml b/data/npc/chondur.xml new file mode 100644 index 00000000000..f740662e1e4 --- /dev/null +++ b/data/npc/chondur.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + diff --git a/data/npc/chrak.xml b/data/npc/chrak.xml new file mode 100644 index 00000000000..316c8593a1f --- /dev/null +++ b/data/npc/chrak.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/chraknpc.xml b/data/npc/chraknpc.xml new file mode 100644 index 00000000000..316c8593a1f --- /dev/null +++ b/data/npc/chraknpc.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/christine.xml b/data/npc/christine.xml new file mode 100644 index 00000000000..a158bfc0bfc --- /dev/null +++ b/data/npc/christine.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/data/npc/christoph.xml b/data/npc/christoph.xml new file mode 100644 index 00000000000..6675144a1d6 --- /dev/null +++ b/data/npc/christoph.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/data/npc/chrystal.xml b/data/npc/chrystal.xml new file mode 100644 index 00000000000..6e2c4bde2d9 --- /dev/null +++ b/data/npc/chrystal.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/data/npc/chuck_the_worker.xml b/data/npc/chuck_the_worker.xml new file mode 100644 index 00000000000..ae361b85d91 --- /dev/null +++ b/data/npc/chuck_the_worker.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/chuckles.xml b/data/npc/chuckles.xml new file mode 100644 index 00000000000..427849bd7bc --- /dev/null +++ b/data/npc/chuckles.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + diff --git a/data/npc/cillia.xml b/data/npc/cillia.xml new file mode 100644 index 00000000000..0ca0fcf81a3 --- /dev/null +++ b/data/npc/cillia.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/cipfried.xml b/data/npc/cipfried.xml new file mode 100644 index 00000000000..91a3eb2e5f3 --- /dev/null +++ b/data/npc/cipfried.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/clark.xml b/data/npc/clark.xml new file mode 100644 index 00000000000..53bf14b7849 --- /dev/null +++ b/data/npc/clark.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/cledwyn.xml b/data/npc/cledwyn.xml new file mode 100644 index 00000000000..34651f15d74 --- /dev/null +++ b/data/npc/cledwyn.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/clyde.xml b/data/npc/clyde.xml new file mode 100644 index 00000000000..6a2e6fdda1f --- /dev/null +++ b/data/npc/clyde.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + diff --git a/data/npc/cobranpc.xml b/data/npc/cobranpc.xml new file mode 100644 index 00000000000..63b801ab670 --- /dev/null +++ b/data/npc/cobranpc.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/cold_percht_sleigh.xml b/data/npc/cold_percht_sleigh.xml new file mode 100644 index 00000000000..1d82c195cce --- /dev/null +++ b/data/npc/cold_percht_sleigh.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/coltrayne.xml b/data/npc/coltrayne.xml new file mode 100644 index 00000000000..ad48b009dd5 --- /dev/null +++ b/data/npc/coltrayne.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + diff --git a/data/npc/commander_stone.xml b/data/npc/commander_stone.xml new file mode 100644 index 00000000000..404967b74ae --- /dev/null +++ b/data/npc/commander_stone.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/cornelia.xml b/data/npc/cornelia.xml new file mode 100644 index 00000000000..1a9da5b707a --- /dev/null +++ b/data/npc/cornelia.xml @@ -0,0 +1,73 @@ + + + + + + + + + + diff --git a/data/npc/cornell.xml b/data/npc/cornell.xml new file mode 100644 index 00000000000..9aca13c70ee --- /dev/null +++ b/data/npc/cornell.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/corym_ratter.xml b/data/npc/corym_ratter.xml new file mode 100644 index 00000000000..fab38adcf00 --- /dev/null +++ b/data/npc/corym_ratter.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/corym_servant.xml b/data/npc/corym_servant.xml new file mode 100644 index 00000000000..e9e2b672f92 --- /dev/null +++ b/data/npc/corym_servant.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/costello.xml b/data/npc/costello.xml new file mode 100644 index 00000000000..d08aca9c2ac --- /dev/null +++ b/data/npc/costello.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/cranky_lizard_crone.xml b/data/npc/cranky_lizard_crone.xml new file mode 100644 index 00000000000..a61a0f3b97a --- /dev/null +++ b/data/npc/cranky_lizard_crone.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/crowned_tree.xml b/data/npc/crowned_tree.xml new file mode 100644 index 00000000000..ee71d0ec364 --- /dev/null +++ b/data/npc/crowned_tree.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/cruleo.xml b/data/npc/cruleo.xml new file mode 100644 index 00000000000..70550c2d247 --- /dev/null +++ b/data/npc/cruleo.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/data/npc/curos.xml b/data/npc/curos.xml new file mode 100644 index 00000000000..e0ec114c921 --- /dev/null +++ b/data/npc/curos.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/dabui.xml b/data/npc/dabui.xml new file mode 100644 index 00000000000..432b2b45b20 --- /dev/null +++ b/data/npc/dabui.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/dagomir.xml b/data/npc/dagomir.xml new file mode 100644 index 00000000000..535dd9195c8 --- /dev/null +++ b/data/npc/dagomir.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/dalbrect.xml b/data/npc/dalbrect.xml new file mode 100644 index 00000000000..8ebbc4c3155 --- /dev/null +++ b/data/npc/dalbrect.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/dallheim.xml b/data/npc/dallheim.xml new file mode 100644 index 00000000000..4e08da4d660 --- /dev/null +++ b/data/npc/dallheim.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/dane.xml b/data/npc/dane.xml new file mode 100644 index 00000000000..4c3cec5ea41 --- /dev/null +++ b/data/npc/dane.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/data/npc/daniel_steelsoul.xml b/data/npc/daniel_steelsoul.xml new file mode 100644 index 00000000000..68e1c69552c --- /dev/null +++ b/data/npc/daniel_steelsoul.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/dankwart.xml b/data/npc/dankwart.xml new file mode 100644 index 00000000000..d850483000d --- /dev/null +++ b/data/npc/dankwart.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + diff --git a/data/npc/danlon.xml b/data/npc/danlon.xml new file mode 100644 index 00000000000..d5d579a6708 --- /dev/null +++ b/data/npc/danlon.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/dario.xml b/data/npc/dario.xml new file mode 100644 index 00000000000..7657a0470d7 --- /dev/null +++ b/data/npc/dario.xml @@ -0,0 +1,39 @@ + + + + + + + + + + diff --git a/data/npc/dark_percht_sleigh.xml b/data/npc/dark_percht_sleigh.xml new file mode 100644 index 00000000000..2804ee1ece7 --- /dev/null +++ b/data/npc/dark_percht_sleigh.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/dedoras.xml b/data/npc/dedoras.xml new file mode 100644 index 00000000000..a2688c93f6e --- /dev/null +++ b/data/npc/dedoras.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/demon_skeleton_npc.xml b/data/npc/demon_skeleton_npc.xml new file mode 100644 index 00000000000..d5ea01cd89b --- /dev/null +++ b/data/npc/demon_skeleton_npc.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/demonguard.xml b/data/npc/demonguard.xml new file mode 100644 index 00000000000..3d4b651ef25 --- /dev/null +++ b/data/npc/demonguard.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/denominator.xml b/data/npc/denominator.xml new file mode 100644 index 00000000000..b573487f05a --- /dev/null +++ b/data/npc/denominator.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/dermot.xml b/data/npc/dermot.xml new file mode 100644 index 00000000000..df31d3441f8 --- /dev/null +++ b/data/npc/dermot.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/digger.xml b/data/npc/digger.xml new file mode 100644 index 00000000000..55cebe3d930 --- /dev/null +++ b/data/npc/digger.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + diff --git a/data/npc/dixi.xml b/data/npc/dixi.xml new file mode 100644 index 00000000000..db02c8d15a7 --- /dev/null +++ b/data/npc/dixi.xml @@ -0,0 +1,38 @@ + + + + + + + + + + diff --git a/data/npc/djema.xml b/data/npc/djema.xml new file mode 100644 index 00000000000..6854d58fd6b --- /dev/null +++ b/data/npc/djema.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/doctor_gnomedix.xml b/data/npc/doctor_gnomedix.xml new file mode 100644 index 00000000000..dece36e226d --- /dev/null +++ b/data/npc/doctor_gnomedix.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/donald_mcronald.xml b/data/npc/donald_mcronald.xml new file mode 100644 index 00000000000..b7c152fbfa3 --- /dev/null +++ b/data/npc/donald_mcronald.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + diff --git a/data/npc/dorbin.xml b/data/npc/dorbin.xml new file mode 100644 index 00000000000..d8dfa76ca4a --- /dev/null +++ b/data/npc/dorbin.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + diff --git a/data/npc/dorian.xml b/data/npc/dorian.xml new file mode 100644 index 00000000000..1970a473cab --- /dev/null +++ b/data/npc/dorian.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/doubleday.xml b/data/npc/doubleday.xml new file mode 100644 index 00000000000..393e5a48634 --- /dev/null +++ b/data/npc/doubleday.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/doug.xml b/data/npc/doug.xml new file mode 100644 index 00000000000..f538e4b9b43 --- /dev/null +++ b/data/npc/doug.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/dove.xml b/data/npc/dove.xml new file mode 100644 index 00000000000..44044a13df7 --- /dev/null +++ b/data/npc/dove.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/npc/dr_merlay.xml b/data/npc/dr_merlay.xml new file mode 100644 index 00000000000..1ba91a0951a --- /dev/null +++ b/data/npc/dr_merlay.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/dreadeye.xml b/data/npc/dreadeye.xml new file mode 100644 index 00000000000..1c8179cccf5 --- /dev/null +++ b/data/npc/dreadeye.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/dream_butterfly.xml b/data/npc/dream_butterfly.xml new file mode 100644 index 00000000000..7608e281392 --- /dev/null +++ b/data/npc/dream_butterfly.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/dregor.xml b/data/npc/dregor.xml new file mode 100644 index 00000000000..85a23331e49 --- /dev/null +++ b/data/npc/dregor.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/drog.xml b/data/npc/drog.xml new file mode 100644 index 00000000000..03abcac55f3 --- /dev/null +++ b/data/npc/drog.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/dronk.xml b/data/npc/dronk.xml new file mode 100644 index 00000000000..8447d96830b --- /dev/null +++ b/data/npc/dronk.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/druid_yandur.xml b/data/npc/druid_yandur.xml new file mode 100644 index 00000000000..1afc8c2d70d --- /dev/null +++ b/data/npc/druid_yandur.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/drystan_wildweed.xml b/data/npc/drystan_wildweed.xml new file mode 100644 index 00000000000..4ad48e4026b --- /dev/null +++ b/data/npc/drystan_wildweed.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/dukosch.xml b/data/npc/dukosch.xml new file mode 100644 index 00000000000..eb956d0acb8 --- /dev/null +++ b/data/npc/dukosch.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/duncan.xml b/data/npc/duncan.xml new file mode 100644 index 00000000000..9967489f203 --- /dev/null +++ b/data/npc/duncan.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/data/npc/duria.xml b/data/npc/duria.xml new file mode 100644 index 00000000000..e93e166d3aa --- /dev/null +++ b/data/npc/duria.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/dustrunner.xml b/data/npc/dustrunner.xml new file mode 100644 index 00000000000..20e5235ab0a --- /dev/null +++ b/data/npc/dustrunner.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/eathar.xml b/data/npc/eathar.xml new file mode 100644 index 00000000000..f9de86a0b41 --- /dev/null +++ b/data/npc/eathar.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ebenizer.xml b/data/npc/ebenizer.xml new file mode 100644 index 00000000000..a93286be0c2 --- /dev/null +++ b/data/npc/ebenizer.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/eclesius.xml b/data/npc/eclesius.xml new file mode 100644 index 00000000000..695906c039c --- /dev/null +++ b/data/npc/eclesius.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/edala.xml b/data/npc/edala.xml new file mode 100644 index 00000000000..fc91eb507b7 --- /dev/null +++ b/data/npc/edala.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/eddy.xml b/data/npc/eddy.xml new file mode 100644 index 00000000000..ab84b53df91 --- /dev/null +++ b/data/npc/eddy.xml @@ -0,0 +1,91 @@ + + + + + + + + + diff --git a/data/npc/edgar-ellen.xml b/data/npc/edgar-ellen.xml new file mode 100644 index 00000000000..d73c5597daa --- /dev/null +++ b/data/npc/edgar-ellen.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/edmund.xml b/data/npc/edmund.xml new file mode 100644 index 00000000000..e858b614b46 --- /dev/null +++ b/data/npc/edmund.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + diff --git a/data/npc/edoch.xml b/data/npc/edoch.xml new file mode 100644 index 00000000000..af4d9b90c82 --- /dev/null +++ b/data/npc/edoch.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + diff --git a/data/npc/edowir.xml b/data/npc/edowir.xml new file mode 100644 index 00000000000..9f76000d441 --- /dev/null +++ b/data/npc/edowir.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/edron_guardsman.xml b/data/npc/edron_guardsman.xml new file mode 100644 index 00000000000..c09b1c04aed --- /dev/null +++ b/data/npc/edron_guardsman.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/edvard.xml b/data/npc/edvard.xml new file mode 100644 index 00000000000..7ec362a40bb --- /dev/null +++ b/data/npc/edvard.xml @@ -0,0 +1,94 @@ + + + + + + + + + diff --git a/data/npc/eighty.xml b/data/npc/eighty.xml new file mode 100644 index 00000000000..44bab1227f6 --- /dev/null +++ b/data/npc/eighty.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/eirik.xml b/data/npc/eirik.xml new file mode 100644 index 00000000000..82c80b2b20b --- /dev/null +++ b/data/npc/eirik.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/elane.xml b/data/npc/elane.xml new file mode 100644 index 00000000000..237ae439af6 --- /dev/null +++ b/data/npc/elane.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/elathriel.xml b/data/npc/elathriel.xml new file mode 100644 index 00000000000..7fb99bf56c3 --- /dev/null +++ b/data/npc/elathriel.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/elbert.xml b/data/npc/elbert.xml new file mode 100644 index 00000000000..cf55428c683 --- /dev/null +++ b/data/npc/elbert.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/eleonore.xml b/data/npc/eleonore.xml new file mode 100644 index 00000000000..22ea1e59cfb --- /dev/null +++ b/data/npc/eleonore.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/elf_guard.xml b/data/npc/elf_guard.xml new file mode 100644 index 00000000000..be35dba35bc --- /dev/null +++ b/data/npc/elf_guard.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/elgar.xml b/data/npc/elgar.xml new file mode 100644 index 00000000000..d7fb92945c9 --- /dev/null +++ b/data/npc/elgar.xml @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/data/npc/eliyas.xml b/data/npc/eliyas.xml new file mode 100644 index 00000000000..364805cb71d --- /dev/null +++ b/data/npc/eliyas.xml @@ -0,0 +1,39 @@ + + + + + + + + + + diff --git a/data/npc/eliza.xml b/data/npc/eliza.xml new file mode 100644 index 00000000000..0b15b3d7315 --- /dev/null +++ b/data/npc/eliza.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/elliott.xml b/data/npc/elliott.xml new file mode 100644 index 00000000000..81a9953c76a --- /dev/null +++ b/data/npc/elliott.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/elvith.xml b/data/npc/elvith.xml new file mode 100644 index 00000000000..e70f2daaffc --- /dev/null +++ b/data/npc/elvith.xml @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/data/npc/elyen_ravenlock.xml b/data/npc/elyen_ravenlock.xml new file mode 100644 index 00000000000..a86de3df7a4 --- /dev/null +++ b/data/npc/elyen_ravenlock.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/emberwing.xml b/data/npc/emberwing.xml new file mode 100644 index 00000000000..894a99b74d9 --- /dev/null +++ b/data/npc/emberwing.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/emily.xml b/data/npc/emily.xml new file mode 100644 index 00000000000..3d905fe1ba2 --- /dev/null +++ b/data/npc/emily.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/emma.xml b/data/npc/emma.xml new file mode 100644 index 00000000000..cef1e5ec829 --- /dev/null +++ b/data/npc/emma.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/emperor_kruzak.xml b/data/npc/emperor_kruzak.xml new file mode 100644 index 00000000000..e7c5904419a --- /dev/null +++ b/data/npc/emperor_kruzak.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/emperor_rehal.xml b/data/npc/emperor_rehal.xml new file mode 100644 index 00000000000..e20da351939 --- /dev/null +++ b/data/npc/emperor_rehal.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/eranth.xml b/data/npc/eranth.xml new file mode 100644 index 00000000000..398c84eebc1 --- /dev/null +++ b/data/npc/eranth.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/erayo.xml b/data/npc/erayo.xml new file mode 100644 index 00000000000..6f1a9d68e02 --- /dev/null +++ b/data/npc/erayo.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/eremo.xml b/data/npc/eremo.xml new file mode 100644 index 00000000000..95445cc3b8a --- /dev/null +++ b/data/npc/eremo.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/data/npc/eroth.xml b/data/npc/eroth.xml new file mode 100644 index 00000000000..3c94189b7e4 --- /dev/null +++ b/data/npc/eroth.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/eruaran.xml b/data/npc/eruaran.xml new file mode 100644 index 00000000000..90f448f1f02 --- /dev/null +++ b/data/npc/eruaran.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/eshaya.xml b/data/npc/eshaya.xml new file mode 100644 index 00000000000..e129b26e682 --- /dev/null +++ b/data/npc/eshaya.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/esrik.xml b/data/npc/esrik.xml new file mode 100644 index 00000000000..2fe04f88415 --- /dev/null +++ b/data/npc/esrik.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ethan.xml b/data/npc/ethan.xml new file mode 100644 index 00000000000..fe865221a70 --- /dev/null +++ b/data/npc/ethan.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/etzel.xml b/data/npc/etzel.xml new file mode 100644 index 00000000000..9a1368182dd --- /dev/null +++ b/data/npc/etzel.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/eva.xml b/data/npc/eva.xml new file mode 100644 index 00000000000..0e694e1aa05 --- /dev/null +++ b/data/npc/eva.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/evan.xml b/data/npc/evan.xml new file mode 100644 index 00000000000..67200605a87 --- /dev/null +++ b/data/npc/evan.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/data/npc/ezean.xml b/data/npc/ezean.xml new file mode 100644 index 00000000000..eae0c7a02ec --- /dev/null +++ b/data/npc/ezean.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/data/npc/ezebeth.xml b/data/npc/ezebeth.xml new file mode 100644 index 00000000000..6080fa4d4da --- /dev/null +++ b/data/npc/ezebeth.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/fa_hradin.xml b/data/npc/fa_hradin.xml new file mode 100644 index 00000000000..3dcb1022c98 --- /dev/null +++ b/data/npc/fa_hradin.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/fadil.xml b/data/npc/fadil.xml new file mode 100644 index 00000000000..334596e7c89 --- /dev/null +++ b/data/npc/fadil.xml @@ -0,0 +1,40 @@ + + + + + + + + + diff --git a/data/npc/falk.xml b/data/npc/falk.xml new file mode 100644 index 00000000000..72a80c8fdb9 --- /dev/null +++ b/data/npc/falk.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/falonzo.xml b/data/npc/falonzo.xml new file mode 100644 index 00000000000..1f850d19740 --- /dev/null +++ b/data/npc/falonzo.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/faloriel.xml b/data/npc/faloriel.xml new file mode 100644 index 00000000000..c27b2681930 --- /dev/null +++ b/data/npc/faloriel.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/data/npc/faluae.xml b/data/npc/faluae.xml new file mode 100644 index 00000000000..2ba80380cd8 --- /dev/null +++ b/data/npc/faluae.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/fayla.xml b/data/npc/fayla.xml new file mode 100644 index 00000000000..574b6d0a990 --- /dev/null +++ b/data/npc/fayla.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + diff --git a/data/npc/feizuhl.xml b/data/npc/feizuhl.xml new file mode 100644 index 00000000000..ad38d54e0af --- /dev/null +++ b/data/npc/feizuhl.xml @@ -0,0 +1,94 @@ + + + + + + + + + diff --git a/data/npc/fenbala.xml b/data/npc/fenbala.xml new file mode 100644 index 00000000000..fc9b5458b51 --- /dev/null +++ b/data/npc/fenbala.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/fenech.xml b/data/npc/fenech.xml new file mode 100644 index 00000000000..274e8b50a80 --- /dev/null +++ b/data/npc/fenech.xml @@ -0,0 +1,54 @@ + + + + + + + + + + diff --git a/data/npc/fergus.xml b/data/npc/fergus.xml new file mode 100644 index 00000000000..b719eea94fa --- /dev/null +++ b/data/npc/fergus.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ferks.xml b/data/npc/ferks.xml new file mode 100644 index 00000000000..0f562fa1241 --- /dev/null +++ b/data/npc/ferks.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ferryman_kamil.xml b/data/npc/ferryman_kamil.xml new file mode 100644 index 00000000000..b810f1cffe0 --- /dev/null +++ b/data/npc/ferryman_kamil.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/data/npc/ferryman_kamilmeluna.xml b/data/npc/ferryman_kamilmeluna.xml new file mode 100644 index 00000000000..6a34efcd171 --- /dev/null +++ b/data/npc/ferryman_kamilmeluna.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/data/npc/ferus.xml b/data/npc/ferus.xml new file mode 100644 index 00000000000..ce25dc0b66c --- /dev/null +++ b/data/npc/ferus.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/fillias.xml b/data/npc/fillias.xml new file mode 100644 index 00000000000..a61969caba0 --- /dev/null +++ b/data/npc/fillias.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/finarfin.xml b/data/npc/finarfin.xml new file mode 100644 index 00000000000..96107889f2b --- /dev/null +++ b/data/npc/finarfin.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/fiona.xml b/data/npc/fiona.xml new file mode 100644 index 00000000000..eb7befaf339 --- /dev/null +++ b/data/npc/fiona.xml @@ -0,0 +1,90 @@ + + + + + + + + + diff --git a/data/npc/flint.xml b/data/npc/flint.xml new file mode 100644 index 00000000000..926c0645fb6 --- /dev/null +++ b/data/npc/flint.xml @@ -0,0 +1,155 @@ + + + + + + + + + + diff --git a/data/npc/flora.xml b/data/npc/flora.xml new file mode 100644 index 00000000000..c37fba403cf --- /dev/null +++ b/data/npc/flora.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/florentine.xml b/data/npc/florentine.xml new file mode 100644 index 00000000000..65a50458beb --- /dev/null +++ b/data/npc/florentine.xml @@ -0,0 +1,15 @@ + + + + + + + + + diff --git a/data/npc/frafnar.xml b/data/npc/frafnar.xml new file mode 100644 index 00000000000..972117e103f --- /dev/null +++ b/data/npc/frafnar.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/frank_the_plank.xml b/data/npc/frank_the_plank.xml new file mode 100644 index 00000000000..15e862a4e3b --- /dev/null +++ b/data/npc/frank_the_plank.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/frans.xml b/data/npc/frans.xml new file mode 100644 index 00000000000..fd95f2fed60 --- /dev/null +++ b/data/npc/frans.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + diff --git a/data/npc/frederik.xml b/data/npc/frederik.xml new file mode 100644 index 00000000000..710ba6604b6 --- /dev/null +++ b/data/npc/frederik.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + diff --git a/data/npc/freezhild.xml b/data/npc/freezhild.xml new file mode 100644 index 00000000000..f6a591b048b --- /dev/null +++ b/data/npc/freezhild.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/frodo.xml b/data/npc/frodo.xml new file mode 100644 index 00000000000..49524d77553 --- /dev/null +++ b/data/npc/frodo.xml @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/data/npc/frok_the_guard.xml b/data/npc/frok_the_guard.xml new file mode 100644 index 00000000000..619d4a5629f --- /dev/null +++ b/data/npc/frok_the_guard.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/frosty.xml b/data/npc/frosty.xml new file mode 100644 index 00000000000..2726927d6a3 --- /dev/null +++ b/data/npc/frosty.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/fynn.xml b/data/npc/fynn.xml new file mode 100644 index 00000000000..fd17f224b28 --- /dev/null +++ b/data/npc/fynn.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/fyodor.xml b/data/npc/fyodor.xml new file mode 100644 index 00000000000..fbbf0a7820e --- /dev/null +++ b/data/npc/fyodor.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/data/npc/gabel.xml b/data/npc/gabel.xml new file mode 100644 index 00000000000..0cafdf8c218 --- /dev/null +++ b/data/npc/gabel.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/gail.xml b/data/npc/gail.xml new file mode 100644 index 00000000000..cc50ca2b0c8 --- /dev/null +++ b/data/npc/gail.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + diff --git a/data/npc/galuna.xml b/data/npc/galuna.xml new file mode 100644 index 00000000000..b05d3875b16 --- /dev/null +++ b/data/npc/galuna.xml @@ -0,0 +1,18 @@ + + + + + + + + + + diff --git a/data/npc/gamel.xml b/data/npc/gamel.xml new file mode 100644 index 00000000000..323b8171763 --- /dev/null +++ b/data/npc/gamel.xml @@ -0,0 +1,90 @@ + + + + + + + + + + diff --git a/data/npc/gamon.xml b/data/npc/gamon.xml new file mode 100644 index 00000000000..2eb2413ba42 --- /dev/null +++ b/data/npc/gamon.xml @@ -0,0 +1,93 @@ + + + + + + + + + diff --git a/data/npc/garamond.xml b/data/npc/garamond.xml new file mode 100644 index 00000000000..b9f745c6913 --- /dev/null +++ b/data/npc/garamond.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/gareth.xml b/data/npc/gareth.xml new file mode 100644 index 00000000000..ddb7205086b --- /dev/null +++ b/data/npc/gareth.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/gate_guardian.xml b/data/npc/gate_guardian.xml new file mode 100644 index 00000000000..5667672fae4 --- /dev/null +++ b/data/npc/gate_guardian.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/gederas.xml b/data/npc/gederas.xml new file mode 100644 index 00000000000..13aa67f7cc5 --- /dev/null +++ b/data/npc/gederas.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/gelagos.xml b/data/npc/gelagos.xml new file mode 100644 index 00000000000..096341ca05b --- /dev/null +++ b/data/npc/gelagos.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/gelidrazahs_thirst.xml b/data/npc/gelidrazahs_thirst.xml new file mode 100644 index 00000000000..5d5a1bf6a63 --- /dev/null +++ b/data/npc/gelidrazahs_thirst.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/george_the_boyscout.xml b/data/npc/george_the_boyscout.xml new file mode 100644 index 00000000000..ef96ca57a7d --- /dev/null +++ b/data/npc/george_the_boyscout.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/gerimor.xml b/data/npc/gerimor.xml new file mode 100644 index 00000000000..de899742f31 --- /dev/null +++ b/data/npc/gerimor.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/gewen.xml b/data/npc/gewen.xml new file mode 100644 index 00000000000..3e58f32e532 --- /dev/null +++ b/data/npc/gewen.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ghorza.xml b/data/npc/ghorza.xml new file mode 100644 index 00000000000..eb6252d4877 --- /dev/null +++ b/data/npc/ghorza.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + diff --git a/data/npc/ghost_of_a_priest.xml b/data/npc/ghost_of_a_priest.xml new file mode 100644 index 00000000000..26723ba2c67 --- /dev/null +++ b/data/npc/ghost_of_a_priest.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/ghostly_wolf.xml b/data/npc/ghostly_wolf.xml new file mode 100644 index 00000000000..b2021d7b4f7 --- /dev/null +++ b/data/npc/ghostly_wolf.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/gladys.xml b/data/npc/gladys.xml new file mode 100644 index 00000000000..414949a53a7 --- /dev/null +++ b/data/npc/gladys.xml @@ -0,0 +1,53 @@ + + + + + + + + + + diff --git a/data/npc/gnomad.xml b/data/npc/gnomad.xml new file mode 100644 index 00000000000..a63805b5fa8 --- /dev/null +++ b/data/npc/gnomad.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/gnomailion.xml b/data/npc/gnomailion.xml new file mode 100644 index 00000000000..b2a30fc07ea --- /dev/null +++ b/data/npc/gnomailion.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + diff --git a/data/npc/gnomally.xml b/data/npc/gnomally.xml new file mode 100644 index 00000000000..e0f50c396b3 --- /dev/null +++ b/data/npc/gnomally.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/gnomargery.xml b/data/npc/gnomargery.xml new file mode 100644 index 00000000000..03dd0135cc3 --- /dev/null +++ b/data/npc/gnomargery.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/gnomaticus.xml b/data/npc/gnomaticus.xml new file mode 100644 index 00000000000..c9e140e1c61 --- /dev/null +++ b/data/npc/gnomaticus.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/gnombold.xml b/data/npc/gnombold.xml new file mode 100644 index 00000000000..966b1b413c2 --- /dev/null +++ b/data/npc/gnombold.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/gnome.xml b/data/npc/gnome.xml new file mode 100644 index 00000000000..45bae85b974 --- /dev/null +++ b/data/npc/gnome.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/gnome_trooper.xml b/data/npc/gnome_trooper.xml new file mode 100644 index 00000000000..645afdbce5f --- /dev/null +++ b/data/npc/gnome_trooper.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/gnomegica.xml b/data/npc/gnomegica.xml new file mode 100644 index 00000000000..de846ae27c2 --- /dev/null +++ b/data/npc/gnomegica.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + diff --git a/data/npc/gnomejam.xml b/data/npc/gnomejam.xml new file mode 100644 index 00000000000..d2852b96c78 --- /dev/null +++ b/data/npc/gnomejam.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/data/npc/gnomelvis.xml b/data/npc/gnomelvis.xml new file mode 100644 index 00000000000..74700bb6d48 --- /dev/null +++ b/data/npc/gnomelvis.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/gnomenursey.xml b/data/npc/gnomenursey.xml new file mode 100644 index 00000000000..7730007bf71 --- /dev/null +++ b/data/npc/gnomenursey.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/gnomeral.xml b/data/npc/gnomeral.xml new file mode 100644 index 00000000000..d90f1c21d25 --- /dev/null +++ b/data/npc/gnomeral.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/gnomercy.xml b/data/npc/gnomercy.xml new file mode 100644 index 00000000000..02daf7f6cc3 --- /dev/null +++ b/data/npc/gnomercy.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/gnomerik.xml b/data/npc/gnomerik.xml new file mode 100644 index 00000000000..42854557deb --- /dev/null +++ b/data/npc/gnomerik.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/gnomerrow.xml b/data/npc/gnomerrow.xml new file mode 100644 index 00000000000..4a7f03bf372 --- /dev/null +++ b/data/npc/gnomerrow.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + diff --git a/data/npc/gnomespector.xml b/data/npc/gnomespector.xml new file mode 100644 index 00000000000..ad2b5c85e33 --- /dev/null +++ b/data/npc/gnomespector.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/gnomette.xml b/data/npc/gnomette.xml new file mode 100644 index 00000000000..8a805e517ae --- /dev/null +++ b/data/npc/gnomette.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/data/npc/gnomewart.xml b/data/npc/gnomewart.xml new file mode 100644 index 00000000000..f3b778733de --- /dev/null +++ b/data/npc/gnomewart.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/gnomillion.xml b/data/npc/gnomillion.xml new file mode 100644 index 00000000000..acf94d6b8d4 --- /dev/null +++ b/data/npc/gnomillion.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/gnomilly.xml b/data/npc/gnomilly.xml new file mode 100644 index 00000000000..26078fd0853 --- /dev/null +++ b/data/npc/gnomilly.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/gnomincia.xml b/data/npc/gnomincia.xml new file mode 100644 index 00000000000..1fe0a20c913 --- /dev/null +++ b/data/npc/gnomincia.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/data/npc/gnominus.xml b/data/npc/gnominus.xml new file mode 100644 index 00000000000..0d732c39749 --- /dev/null +++ b/data/npc/gnominus.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/gnomission.xml b/data/npc/gnomission.xml new file mode 100644 index 00000000000..3988bfecb24 --- /dev/null +++ b/data/npc/gnomission.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + diff --git a/data/npc/gnommander.xml b/data/npc/gnommander.xml new file mode 100644 index 00000000000..06281aa8783 --- /dev/null +++ b/data/npc/gnommander.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/gnomole.xml b/data/npc/gnomole.xml new file mode 100644 index 00000000000..754efe430d4 --- /dev/null +++ b/data/npc/gnomole.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/gnomus.xml b/data/npc/gnomus.xml new file mode 100644 index 00000000000..f8081115b27 --- /dev/null +++ b/data/npc/gnomus.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/gnomux.xml b/data/npc/gnomux.xml new file mode 100644 index 00000000000..80811daf287 --- /dev/null +++ b/data/npc/gnomux.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/golem_guardian.xml b/data/npc/golem_guardian.xml new file mode 100644 index 00000000000..83411943fe2 --- /dev/null +++ b/data/npc/golem_guardian.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/gordon.xml b/data/npc/gordon.xml new file mode 100644 index 00000000000..66555413f6d --- /dev/null +++ b/data/npc/gordon.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/gorn.xml b/data/npc/gorn.xml new file mode 100644 index 00000000000..35ec861f338 --- /dev/null +++ b/data/npc/gorn.xml @@ -0,0 +1,61 @@ + + + + + + + + + + diff --git a/data/npc/graham.xml b/data/npc/graham.xml new file mode 100644 index 00000000000..63a6be5301e --- /dev/null +++ b/data/npc/graham.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/graubart.xml b/data/npc/graubart.xml new file mode 100644 index 00000000000..f20e7f8177d --- /dev/null +++ b/data/npc/graubart.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/gree_dee.xml b/data/npc/gree_dee.xml new file mode 100644 index 00000000000..5c9f761144c --- /dev/null +++ b/data/npc/gree_dee.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + diff --git a/data/npc/gregor.xml b/data/npc/gregor.xml new file mode 100644 index 00000000000..0e81f3f1fbc --- /dev/null +++ b/data/npc/gregor.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/grizzly_adams.xml b/data/npc/grizzly_adams.xml new file mode 100644 index 00000000000..7f6e90f7305 --- /dev/null +++ b/data/npc/grizzly_adams.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/grodrik.xml b/data/npc/grodrik.xml new file mode 100644 index 00000000000..bae74ad4dab --- /dev/null +++ b/data/npc/grodrik.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/grof_the_guard.xml b/data/npc/grof_the_guard.xml new file mode 100644 index 00000000000..1ace5a034c5 --- /dev/null +++ b/data/npc/grof_the_guard.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/grombur.xml b/data/npc/grombur.xml new file mode 100644 index 00000000000..01f40d6696b --- /dev/null +++ b/data/npc/grombur.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/grubokk.xml b/data/npc/grubokk.xml new file mode 100644 index 00000000000..abcb4faf293 --- /dev/null +++ b/data/npc/grubokk.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/grumpy_stone.xml b/data/npc/grumpy_stone.xml new file mode 100644 index 00000000000..0a941eee78b --- /dev/null +++ b/data/npc/grumpy_stone.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/guard_bazaya.xml b/data/npc/guard_bazaya.xml new file mode 100644 index 00000000000..0041a997966 --- /dev/null +++ b/data/npc/guard_bazaya.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/guard_inurta.xml b/data/npc/guard_inurta.xml new file mode 100644 index 00000000000..212252fcf0f --- /dev/null +++ b/data/npc/guard_inurta.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/guard_saros.xml b/data/npc/guard_saros.xml new file mode 100644 index 00000000000..64129342ea4 --- /dev/null +++ b/data/npc/guard_saros.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/guard_senet.xml b/data/npc/guard_senet.xml new file mode 100644 index 00000000000..d725c7e2317 --- /dev/null +++ b/data/npc/guard_senet.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/guardian_of_the_deep_seas.xml b/data/npc/guardian_of_the_deep_seas.xml new file mode 100644 index 00000000000..7fa36d83a9f --- /dev/null +++ b/data/npc/guardian_of_the_deep_seas.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/guide_alexena.xml b/data/npc/guide_alexena.xml new file mode 100644 index 00000000000..39cd9d0e18a --- /dev/null +++ b/data/npc/guide_alexena.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/guide_behil.xml b/data/npc/guide_behil.xml new file mode 100644 index 00000000000..496bbcc10c1 --- /dev/null +++ b/data/npc/guide_behil.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/guide_davina.xml b/data/npc/guide_davina.xml new file mode 100644 index 00000000000..a7d66c4169b --- /dev/null +++ b/data/npc/guide_davina.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/guide_edna.xml b/data/npc/guide_edna.xml new file mode 100644 index 00000000000..05c5375bb2f --- /dev/null +++ b/data/npc/guide_edna.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/guide_elena.xml b/data/npc/guide_elena.xml new file mode 100644 index 00000000000..7c0e614f7dc --- /dev/null +++ b/data/npc/guide_elena.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/guide_jonathan.xml b/data/npc/guide_jonathan.xml new file mode 100644 index 00000000000..fad3a5ba5d6 --- /dev/null +++ b/data/npc/guide_jonathan.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/guide_kroak.xml b/data/npc/guide_kroak.xml new file mode 100644 index 00000000000..85751772479 --- /dev/null +++ b/data/npc/guide_kroak.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/guide_kunibert.xml b/data/npc/guide_kunibert.xml new file mode 100644 index 00000000000..da26322c0a8 --- /dev/null +++ b/data/npc/guide_kunibert.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/guide_luke.xml b/data/npc/guide_luke.xml new file mode 100644 index 00000000000..c3ab5b69cac --- /dev/null +++ b/data/npc/guide_luke.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/guide_meruka.xml b/data/npc/guide_meruka.xml new file mode 100644 index 00000000000..8a3e9d32170 --- /dev/null +++ b/data/npc/guide_meruka.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/guide_rahlkora.xml b/data/npc/guide_rahlkora.xml new file mode 100644 index 00000000000..b33c7700738 --- /dev/null +++ b/data/npc/guide_rahlkora.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/guide_thelandil.xml b/data/npc/guide_thelandil.xml new file mode 100644 index 00000000000..eefec753873 --- /dev/null +++ b/data/npc/guide_thelandil.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/guide_tiko.xml b/data/npc/guide_tiko.xml new file mode 100644 index 00000000000..33731120be7 --- /dev/null +++ b/data/npc/guide_tiko.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/gundralph.xml b/data/npc/gundralph.xml new file mode 100644 index 00000000000..9cd5f3ec386 --- /dev/null +++ b/data/npc/gundralph.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/gurbasch.xml b/data/npc/gurbasch.xml new file mode 100644 index 00000000000..650324c2336 --- /dev/null +++ b/data/npc/gurbasch.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/h.l..xml b/data/npc/h.l..xml new file mode 100644 index 00000000000..fa6cfad41ef --- /dev/null +++ b/data/npc/h.l..xml @@ -0,0 +1,134 @@ + + + + + + + + + diff --git a/data/npc/habdel.xml b/data/npc/habdel.xml new file mode 100644 index 00000000000..20337b13beb --- /dev/null +++ b/data/npc/habdel.xml @@ -0,0 +1,75 @@ + + + + + + + + + + diff --git a/data/npc/hagor.xml b/data/npc/hagor.xml new file mode 100644 index 00000000000..8e5b27e6f71 --- /dev/null +++ b/data/npc/hagor.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/hairycles.xml b/data/npc/hairycles.xml new file mode 100644 index 00000000000..820764a1b14 --- /dev/null +++ b/data/npc/hairycles.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/data/npc/hal.xml b/data/npc/hal.xml new file mode 100644 index 00000000000..01106732713 --- /dev/null +++ b/data/npc/hal.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/halif.xml b/data/npc/halif.xml new file mode 100644 index 00000000000..d4a53034508 --- /dev/null +++ b/data/npc/halif.xml @@ -0,0 +1,48 @@ + + + + + + + + + + diff --git a/data/npc/halvar.xml b/data/npc/halvar.xml new file mode 100644 index 00000000000..fa4cde7bc86 --- /dev/null +++ b/data/npc/halvar.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/hamilton.xml b/data/npc/hamilton.xml new file mode 100644 index 00000000000..19497eb14db --- /dev/null +++ b/data/npc/hamilton.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/hamish.xml b/data/npc/hamish.xml new file mode 100644 index 00000000000..c65a7c4b310 --- /dev/null +++ b/data/npc/hamish.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + diff --git a/data/npc/hanna.xml b/data/npc/hanna.xml new file mode 100644 index 00000000000..115fd48ca77 --- /dev/null +++ b/data/npc/hanna.xml @@ -0,0 +1,73 @@ + + + + + + + + + + diff --git a/data/npc/hardek.xml b/data/npc/hardek.xml new file mode 100644 index 00000000000..f41a332551d --- /dev/null +++ b/data/npc/hardek.xml @@ -0,0 +1,135 @@ + + + + + + + + + + diff --git a/data/npc/harkath_bloodblade.xml b/data/npc/harkath_bloodblade.xml new file mode 100644 index 00000000000..d1fa9d5294d --- /dev/null +++ b/data/npc/harkath_bloodblade.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/harlow.xml b/data/npc/harlow.xml new file mode 100644 index 00000000000..1b0cb600091 --- /dev/null +++ b/data/npc/harlow.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/harlow_vengoth.xml b/data/npc/harlow_vengoth.xml new file mode 100644 index 00000000000..e23d4dccdb8 --- /dev/null +++ b/data/npc/harlow_vengoth.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/harlowtrade.xml b/data/npc/harlowtrade.xml new file mode 100644 index 00000000000..e569510dd74 --- /dev/null +++ b/data/npc/harlowtrade.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/data/npc/harog.xml b/data/npc/harog.xml new file mode 100644 index 00000000000..7fe9bca9cba --- /dev/null +++ b/data/npc/harog.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/haroun.xml b/data/npc/haroun.xml new file mode 100644 index 00000000000..06c7245a6fd --- /dev/null +++ b/data/npc/haroun.xml @@ -0,0 +1,43 @@ + + + + + + + + + + diff --git a/data/npc/harsky.xml b/data/npc/harsky.xml new file mode 100644 index 00000000000..8dd3cd280dc --- /dev/null +++ b/data/npc/harsky.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/hawkyr.xml b/data/npc/hawkyr.xml new file mode 100644 index 00000000000..135ba666bb1 --- /dev/null +++ b/data/npc/hawkyr.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/heavenly_messenger.xml b/data/npc/heavenly_messenger.xml new file mode 100644 index 00000000000..b2d8e98e796 --- /dev/null +++ b/data/npc/heavenly_messenger.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/helor.xml b/data/npc/helor.xml new file mode 100644 index 00000000000..9985ab507c8 --- /dev/null +++ b/data/npc/helor.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/hemor_the_guard.xml b/data/npc/hemor_the_guard.xml new file mode 100644 index 00000000000..b2d8e98e796 --- /dev/null +++ b/data/npc/hemor_the_guard.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/henricus.xml b/data/npc/henricus.xml new file mode 100644 index 00000000000..59059e2d201 --- /dev/null +++ b/data/npc/henricus.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/herbert.xml b/data/npc/herbert.xml new file mode 100644 index 00000000000..42bfc01bec3 --- /dev/null +++ b/data/npc/herbert.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + diff --git a/data/npc/hexel.xml b/data/npc/hexel.xml new file mode 100644 index 00000000000..14780037571 --- /dev/null +++ b/data/npc/hexel.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/hireling.xml b/data/npc/hireling.xml new file mode 100644 index 00000000000..60439dc30da --- /dev/null +++ b/data/npc/hireling.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/hjaern.xml b/data/npc/hjaern.xml new file mode 100644 index 00000000000..22c8ecb60d4 --- /dev/null +++ b/data/npc/hjaern.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/hofech.xml b/data/npc/hofech.xml new file mode 100644 index 00000000000..5c5729b8edc --- /dev/null +++ b/data/npc/hofech.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/hoggle.xml b/data/npc/hoggle.xml new file mode 100644 index 00000000000..c08f9e51b7c --- /dev/null +++ b/data/npc/hoggle.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/hugo.xml b/data/npc/hugo.xml new file mode 100644 index 00000000000..92e6f543616 --- /dev/null +++ b/data/npc/hugo.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/humgolf.xml b/data/npc/humgolf.xml new file mode 100644 index 00000000000..8fad031f4e5 --- /dev/null +++ b/data/npc/humgolf.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/humnog_the_guard.xml b/data/npc/humnog_the_guard.xml new file mode 100644 index 00000000000..bc5dcafda2e --- /dev/null +++ b/data/npc/humnog_the_guard.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/humphrey.xml b/data/npc/humphrey.xml new file mode 100644 index 00000000000..d5666ba59e1 --- /dev/null +++ b/data/npc/humphrey.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/huntsman.xml b/data/npc/huntsman.xml new file mode 100644 index 00000000000..3bf3418f132 --- /dev/null +++ b/data/npc/huntsman.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/hyacinth.xml b/data/npc/hyacinth.xml new file mode 100644 index 00000000000..37e57499058 --- /dev/null +++ b/data/npc/hyacinth.xml @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/data/npc/ikassis.xml b/data/npc/ikassis.xml new file mode 100644 index 00000000000..ee5774da07b --- /dev/null +++ b/data/npc/ikassis.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/imalas.xml b/data/npc/imalas.xml new file mode 100644 index 00000000000..baa797b5048 --- /dev/null +++ b/data/npc/imalas.xml @@ -0,0 +1,21 @@ + + + + + + + + + diff --git a/data/npc/imbul.xml b/data/npc/imbul.xml new file mode 100644 index 00000000000..4b95b92ddb3 --- /dev/null +++ b/data/npc/imbul.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/inigo.xml b/data/npc/inigo.xml new file mode 100644 index 00000000000..b342d023a29 --- /dev/null +++ b/data/npc/inigo.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/inkaef.xml b/data/npc/inkaef.xml new file mode 100644 index 00000000000..a558641608a --- /dev/null +++ b/data/npc/inkaef.xml @@ -0,0 +1,84 @@ + + + + + + + + + diff --git a/data/npc/iptar-sin.xml b/data/npc/iptar-sin.xml new file mode 100644 index 00000000000..94ff0c67e49 --- /dev/null +++ b/data/npc/iptar-sin.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/irea.xml b/data/npc/irea.xml new file mode 100644 index 00000000000..b9ccce214f4 --- /dev/null +++ b/data/npc/irea.xml @@ -0,0 +1,18 @@ + + + + + + + + + + diff --git a/data/npc/iriana.xml b/data/npc/iriana.xml new file mode 100644 index 00000000000..16c8852f95e --- /dev/null +++ b/data/npc/iriana.xml @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/data/npc/irmana.xml b/data/npc/irmana.xml new file mode 100644 index 00000000000..c1d6b0794e1 --- /dev/null +++ b/data/npc/irmana.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + diff --git a/data/npc/irvin.xml b/data/npc/irvin.xml new file mode 100644 index 00000000000..518ebd2c70c --- /dev/null +++ b/data/npc/irvin.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ishebad.xml b/data/npc/ishebad.xml new file mode 100644 index 00000000000..8dccec26160 --- /dev/null +++ b/data/npc/ishebad.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ishina.xml b/data/npc/ishina.xml new file mode 100644 index 00000000000..ad0505c360d --- /dev/null +++ b/data/npc/ishina.xml @@ -0,0 +1,73 @@ + + + + + + + + + + diff --git a/data/npc/isimov.xml b/data/npc/isimov.xml new file mode 100644 index 00000000000..2d9754748f8 --- /dev/null +++ b/data/npc/isimov.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/iskan.xml b/data/npc/iskan.xml new file mode 100644 index 00000000000..e741282157e --- /dev/null +++ b/data/npc/iskan.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/isolde.xml b/data/npc/isolde.xml new file mode 100644 index 00000000000..fbc573f879b --- /dev/null +++ b/data/npc/isolde.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ivalisse.xml b/data/npc/ivalisse.xml new file mode 100644 index 00000000000..810740a7192 --- /dev/null +++ b/data/npc/ivalisse.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/iwan.xml b/data/npc/iwan.xml new file mode 100644 index 00000000000..c54bbc7ab36 --- /dev/null +++ b/data/npc/iwan.xml @@ -0,0 +1,73 @@ + + + + + + + + + + diff --git a/data/npc/iwar.xml b/data/npc/iwar.xml new file mode 100644 index 00000000000..8ab05e51ab4 --- /dev/null +++ b/data/npc/iwar.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + diff --git a/data/npc/iyad.xml b/data/npc/iyad.xml new file mode 100644 index 00000000000..97c7dd3b0f2 --- /dev/null +++ b/data/npc/iyad.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/izsh.xml b/data/npc/izsh.xml new file mode 100644 index 00000000000..fbc44c3dc4a --- /dev/null +++ b/data/npc/izsh.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/jack.xml b/data/npc/jack.xml new file mode 100644 index 00000000000..1e9bfcdbecc --- /dev/null +++ b/data/npc/jack.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/jack_drone.xml b/data/npc/jack_drone.xml new file mode 100644 index 00000000000..9347df44f49 --- /dev/null +++ b/data/npc/jack_drone.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/jack_fate.xml b/data/npc/jack_fate.xml new file mode 100644 index 00000000000..493772bdb8f --- /dev/null +++ b/data/npc/jack_fate.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/jack_fate_goroma.xml b/data/npc/jack_fate_goroma.xml new file mode 100644 index 00000000000..1453f220a33 --- /dev/null +++ b/data/npc/jack_fate_goroma.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/jack_the_worker.xml b/data/npc/jack_the_worker.xml new file mode 100644 index 00000000000..b9431dd58c5 --- /dev/null +++ b/data/npc/jack_the_worker.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/jacob.xml b/data/npc/jacob.xml new file mode 100644 index 00000000000..d880a0eacd3 --- /dev/null +++ b/data/npc/jacob.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/jagran.xml b/data/npc/jagran.xml new file mode 100644 index 00000000000..84753404a72 --- /dev/null +++ b/data/npc/jagran.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/jakahr.xml b/data/npc/jakahr.xml new file mode 100644 index 00000000000..9652f478bdb --- /dev/null +++ b/data/npc/jakahr.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/data/npc/james.xml b/data/npc/james.xml new file mode 100644 index 00000000000..3558d73cecf --- /dev/null +++ b/data/npc/james.xml @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/data/npc/jamesfrancis.xml b/data/npc/jamesfrancis.xml new file mode 100644 index 00000000000..6605741630f --- /dev/null +++ b/data/npc/jamesfrancis.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/janz.xml b/data/npc/janz.xml new file mode 100644 index 00000000000..13bd32f7098 --- /dev/null +++ b/data/npc/janz.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + diff --git a/data/npc/jason.xml b/data/npc/jason.xml new file mode 100644 index 00000000000..13bc36977b2 --- /dev/null +++ b/data/npc/jason.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/jean_claude.xml b/data/npc/jean_claude.xml new file mode 100644 index 00000000000..acb3ba2ca85 --- /dev/null +++ b/data/npc/jean_claude.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/data/npc/jean_pierre.xml b/data/npc/jean_pierre.xml new file mode 100644 index 00000000000..9f6f1699873 --- /dev/null +++ b/data/npc/jean_pierre.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/jefrey.xml b/data/npc/jefrey.xml new file mode 100644 index 00000000000..1b7f05ff318 --- /dev/null +++ b/data/npc/jefrey.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/jerom.xml b/data/npc/jerom.xml new file mode 100644 index 00000000000..ebd67562c02 --- /dev/null +++ b/data/npc/jerom.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/jeronimo.xml b/data/npc/jeronimo.xml new file mode 100644 index 00000000000..184d55a4948 --- /dev/null +++ b/data/npc/jeronimo.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/jessica.xml b/data/npc/jessica.xml new file mode 100644 index 00000000000..3fa9c8c528f --- /dev/null +++ b/data/npc/jessica.xml @@ -0,0 +1,80 @@ + + + + + + + + + + diff --git a/data/npc/jezzara.xml b/data/npc/jezzara.xml new file mode 100644 index 00000000000..591fd255fad --- /dev/null +++ b/data/npc/jezzara.xml @@ -0,0 +1,24 @@ + + + + + + + + + diff --git a/data/npc/jimbin.xml b/data/npc/jimbin.xml new file mode 100644 index 00000000000..5a9ea0cccbe --- /dev/null +++ b/data/npc/jimbin.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/jimmy.xml b/data/npc/jimmy.xml new file mode 100644 index 00000000000..a6d602a080e --- /dev/null +++ b/data/npc/jimmy.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/john.xml b/data/npc/john.xml new file mode 100644 index 00000000000..3658963ad4d --- /dev/null +++ b/data/npc/john.xml @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/data/npc/jondrin.xml b/data/npc/jondrin.xml new file mode 100644 index 00000000000..4de77853310 --- /dev/null +++ b/data/npc/jondrin.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/jorge.xml b/data/npc/jorge.xml new file mode 100644 index 00000000000..1cd1c7cba91 --- /dev/null +++ b/data/npc/jorge.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/jossel.xml b/data/npc/jossel.xml new file mode 100644 index 00000000000..f77931009bf --- /dev/null +++ b/data/npc/jossel.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/julian.xml b/data/npc/julian.xml new file mode 100644 index 00000000000..4a0f5db4918 --- /dev/null +++ b/data/npc/julian.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + diff --git a/data/npc/julius.xml b/data/npc/julius.xml new file mode 100644 index 00000000000..7c7313d9acd --- /dev/null +++ b/data/npc/julius.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + diff --git a/data/npc/junkar_mines.xml b/data/npc/junkar_mines.xml new file mode 100644 index 00000000000..6401ec33a8b --- /dev/null +++ b/data/npc/junkar_mines.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/junkar_robsons.xml b/data/npc/junkar_robsons.xml new file mode 100644 index 00000000000..9d871d6c3a6 --- /dev/null +++ b/data/npc/junkar_robsons.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/junkar_thais.xml b/data/npc/junkar_thais.xml new file mode 100644 index 00000000000..84b0b245efe --- /dev/null +++ b/data/npc/junkar_thais.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/kais.xml b/data/npc/kais.xml new file mode 100644 index 00000000000..d9322ad418b --- /dev/null +++ b/data/npc/kais.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/kallimae.xml b/data/npc/kallimae.xml new file mode 100644 index 00000000000..e8de3324757 --- /dev/null +++ b/data/npc/kallimae.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/kalvin.xml b/data/npc/kalvin.xml new file mode 100644 index 00000000000..be816ac556e --- /dev/null +++ b/data/npc/kalvin.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/karith.xml b/data/npc/karith.xml new file mode 100644 index 00000000000..f278424a915 --- /dev/null +++ b/data/npc/karith.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/karl.xml b/data/npc/karl.xml new file mode 100644 index 00000000000..604ca6492e6 --- /dev/null +++ b/data/npc/karl.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/data/npc/kasmir.xml b/data/npc/kasmir.xml new file mode 100644 index 00000000000..faf914f93f2 --- /dev/null +++ b/data/npc/kasmir.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/kawill.xml b/data/npc/kawill.xml new file mode 100644 index 00000000000..5059d63fdc9 --- /dev/null +++ b/data/npc/kawill.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/kaya.xml b/data/npc/kaya.xml new file mode 100644 index 00000000000..a80b56f5869 --- /dev/null +++ b/data/npc/kaya.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/kazzan.xml b/data/npc/kazzan.xml new file mode 100644 index 00000000000..e61291d2a9b --- /dev/null +++ b/data/npc/kazzan.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/kendra.xml b/data/npc/kendra.xml new file mode 100644 index 00000000000..1d8203a3650 --- /dev/null +++ b/data/npc/kendra.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/kendra_thais.xml b/data/npc/kendra_thais.xml new file mode 100644 index 00000000000..6f98402808f --- /dev/null +++ b/data/npc/kendra_thais.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/kepar.xml b/data/npc/kepar.xml new file mode 100644 index 00000000000..f650087aa8c --- /dev/null +++ b/data/npc/kepar.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/kevin.xml b/data/npc/kevin.xml new file mode 100644 index 00000000000..038d2ac6d2b --- /dev/null +++ b/data/npc/kevin.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/khanna.xml b/data/npc/khanna.xml new file mode 100644 index 00000000000..488a5fb57f0 --- /dev/null +++ b/data/npc/khanna.xml @@ -0,0 +1,75 @@ + + + + + + + + + + diff --git a/data/npc/kihil_the_guard.xml b/data/npc/kihil_the_guard.xml new file mode 100644 index 00000000000..ce85e061975 --- /dev/null +++ b/data/npc/kihil_the_guard.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/king_tibianus.xml b/data/npc/king_tibianus.xml new file mode 100644 index 00000000000..c6efd7006c4 --- /dev/null +++ b/data/npc/king_tibianus.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/kjesse.xml b/data/npc/kjesse.xml new file mode 100644 index 00000000000..a8ad0769c99 --- /dev/null +++ b/data/npc/kjesse.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/klaus.xml b/data/npc/klaus.xml new file mode 100644 index 00000000000..6de7374618c --- /dev/null +++ b/data/npc/klaus.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/klesar.xml b/data/npc/klesar.xml new file mode 100644 index 00000000000..f164e3a8893 --- /dev/null +++ b/data/npc/klesar.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/klom_stonecutter.xml b/data/npc/klom_stonecutter.xml new file mode 100644 index 00000000000..675ce6f4f20 --- /dev/null +++ b/data/npc/klom_stonecutter.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/knight_hykrion.xml b/data/npc/knight_hykrion.xml new file mode 100644 index 00000000000..355e619ecb3 --- /dev/null +++ b/data/npc/knight_hykrion.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/kratos.xml b/data/npc/kratos.xml new file mode 100644 index 00000000000..39c495745c1 --- /dev/null +++ b/data/npc/kratos.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/kromrek.xml b/data/npc/kromrek.xml new file mode 100644 index 00000000000..2d44ddb9e7f --- /dev/null +++ b/data/npc/kromrek.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/kroox.xml b/data/npc/kroox.xml new file mode 100644 index 00000000000..60c6d0b263d --- /dev/null +++ b/data/npc/kroox.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + diff --git a/data/npc/kulag_the_guard.xml b/data/npc/kulag_the_guard.xml new file mode 100644 index 00000000000..b3f3d700eb2 --- /dev/null +++ b/data/npc/kulag_the_guard.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/lailene.xml b/data/npc/lailene.xml new file mode 100644 index 00000000000..f092a2aaac6 --- /dev/null +++ b/data/npc/lailene.xml @@ -0,0 +1,20 @@ + + + + + + + + + + diff --git a/data/npc/lardoc_bashsmite.xml b/data/npc/lardoc_bashsmite.xml new file mode 100644 index 00000000000..e1b606f8c14 --- /dev/null +++ b/data/npc/lardoc_bashsmite.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/larek.xml b/data/npc/larek.xml new file mode 100644 index 00000000000..4bac2aac210 --- /dev/null +++ b/data/npc/larek.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + diff --git a/data/npc/larfion_the_shaman.xml b/data/npc/larfion_the_shaman.xml new file mode 100644 index 00000000000..1cb2ee0e6df --- /dev/null +++ b/data/npc/larfion_the_shaman.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/lavirias.xml b/data/npc/lavirias.xml new file mode 100644 index 00000000000..32f5b51bbe6 --- /dev/null +++ b/data/npc/lavirias.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/lazaran.xml b/data/npc/lazaran.xml new file mode 100644 index 00000000000..d5a0a74c0d9 --- /dev/null +++ b/data/npc/lazaran.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/lea.xml b/data/npc/lea.xml new file mode 100644 index 00000000000..4b242934e79 --- /dev/null +++ b/data/npc/lea.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/lector.xml b/data/npc/lector.xml new file mode 100644 index 00000000000..b2513974470 --- /dev/null +++ b/data/npc/lector.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/data/npc/lee_delle.xml b/data/npc/lee_delle.xml new file mode 100644 index 00000000000..073e0fcd35f --- /dev/null +++ b/data/npc/lee_delle.xml @@ -0,0 +1,75 @@ + + + + + + + + + + diff --git a/data/npc/leeland.xml b/data/npc/leeland.xml new file mode 100644 index 00000000000..a0ac5b4f0e3 --- /dev/null +++ b/data/npc/leeland.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/legola.xml b/data/npc/legola.xml new file mode 100644 index 00000000000..d4cf88604c1 --- /dev/null +++ b/data/npc/legola.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/data/npc/lesser_messenger_of_heaven.xml b/data/npc/lesser_messenger_of_heaven.xml new file mode 100644 index 00000000000..fe844fc4b93 --- /dev/null +++ b/data/npc/lesser_messenger_of_heaven.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/liane.xml b/data/npc/liane.xml new file mode 100644 index 00000000000..ce832a44caa --- /dev/null +++ b/data/npc/liane.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/data/npc/lib/npc.lua b/data/npc/lib/npc.lua new file mode 100644 index 00000000000..9e832943105 --- /dev/null +++ b/data/npc/lib/npc.lua @@ -0,0 +1,120 @@ +-- Including the Advanced NPC System +dofile('data/npc/lib/npcsystem/npcsystem.lua') +dofile('data/npc/lib/npcsystem/customModules.lua') + +isPlayerPremiumCallback = Player.isPremium + +function msgcontains(message, keyword) + local message, keyword = message:lower(), keyword:lower() + if message == keyword then + return true + end + + return message:find(keyword) and not message:find('(%w+)' .. keyword) +end + +function doNpcSellItem(cid, itemId, amount, subType, ignoreCap, inBackpacks, backpack) + local amount = amount or 1 + local subType = subType or 0 + local item = 0 + local player = Player(cid) + + if ItemType(itemId):isStackable() then + local stuff + if inBackpacks then + stuff = Game.createItem(backpack, 1) + item = stuff:addItem(itemId, math.min(100, amount)) + else + stuff = Game.createItem(itemId, math.min(100, amount)) + end + + return player:addItemEx(stuff, ignoreCap) ~= RETURNVALUE_NOERROR and 0 or amount, 0 + end + + local a = 0 + if inBackpacks then + local container, b = Game.createItem(backpack, 1), 1 + for i = 1, amount do + local item = container:addItem(itemId, subType) + if table.contains({(ItemType(backpack):getCapacity() * b), amount}, i) then + if player:addItemEx(container, ignoreCap) ~= RETURNVALUE_NOERROR then + b = b - 1 + break + end + + a = i + if amount > i then + container = Game.createItem(backpack, 1) + b = b + 1 + end + end + end + + return a, b + end + + for i = 1, amount do -- normal method for non-stackable items + local item = Game.createItem(itemId, subType) + if player:addItemEx(item, ignoreCap) ~= RETURNVALUE_NOERROR then + break + end + a = i + end + return a, 0 +end + +local func = function(cid, text, type, e, pcid) + local npc = Npc(cid) + if not npc then + return + end + + local player = Player(pcid) + if player:isPlayer() then + local creature = Creature(cid) + creature:say(text, type, false, pcid, creature:getPosition()) + e.done = true + end +end + +function doCreatureSayWithDelay(cid, text, type, delay, e, pcid) + if Player(pcid):isPlayer() then + e.done = false + e.event = addEvent(func, delay < 1 and 1000 or delay, cid, text, type, e, pcid) + end +end + +function doPlayerSellItem(cid, itemid, count, cost) + local player = Player(cid) + if player:removeItem(itemid, count) then + if not player:addMoney(cost) then + error('Could not add money to ' .. player:getName() .. '(' .. cost .. 'gp)') + end + return true + end + return false +end + +function doPlayerBuyItemContainer(cid, containerid, itemid, count, cost, charges) + local player = Player(cid) + if not player:removeMoney(cost) then + return false + end + + for i = 1, count do + local container = Game.createItem(containerid, 1) + for x = 1, ItemType(containerid):getCapacity() do + container:addItem(itemid, charges) + end + + if player:addItemEx(container, true) ~= RETURNVALUE_NOERROR then + return false + end + end + return true +end + +function getCount(string) + local b, e = string:find("%d+") + return b and e and tonumber(string:sub(b, e)) or -1 +end diff --git a/data/npc/lib/npcsystem/customModules.lua b/data/npc/lib/npcsystem/customModules.lua new file mode 100644 index 00000000000..b1d0b8796d3 --- /dev/null +++ b/data/npc/lib/npcsystem/customModules.lua @@ -0,0 +1,272 @@ +-- Custom Modules, created to help us in this datapack +local travelDiscounts = { + ['postman'] = {price = 10, storage = Storage.Postman.Rank, value = 3}, + ['new frontier'] = {price = 50, storage = Storage.TheNewFrontier.Mission03, value = 1} +} + +function StdModule.travelDiscount(player, discounts) + local discountPrice, discount = 0 + if type(discounts) == 'string' then + discount = travelDiscounts[discounts] + if discount and player:getStorageValue(discount.storage) >= discount.value then + return discount.price + end + else + for i = 1, #discounts do + discount = travelDiscounts[discounts[i]] + if discount and player:getStorageValue(discount.storage) >= discount.value then + discountPrice = discountPrice + discount.price + end + end + end + + return discountPrice +end + +function StdModule.kick(cid, message, keywords, parameters, node) + local npcHandler = parameters.npcHandler + if npcHandler == nil then + error("StdModule.travel called without any npcHandler instance.") + end + + if not npcHandler:isFocused(cid) then + return false + end + + npcHandler:releaseFocus(cid) + npcHandler:say(parameters.text or "Off with you!", cid) + + local destination = parameters.destination + if type(destination) == 'table' then + destination = destination[math.random(#destination)] + end + + Player(cid):teleportTo(destination, true) + + npcHandler:resetNpc(cid) + return true +end + +local GreetModule = {} +function GreetModule.greet(cid, message, keywords, parameters) + if not parameters.npcHandler:isInRange(cid) then + return true + end + + if parameters.npcHandler:isFocused(cid) then + return true + end + + local parseInfo = { [TAG_PLAYERNAME] = Player(cid):getName() } + parameters.npcHandler:say(parameters.npcHandler:parseMessage(parameters.text, parseInfo), cid, true) + parameters.npcHandler:addFocus(cid) + return true +end + +function GreetModule.farewell(cid, message, keywords, parameters) + if not parameters.npcHandler:isFocused(cid) then + return false + end + + local parseInfo = { [TAG_PLAYERNAME] = Player(cid):getName() } + parameters.npcHandler:say(parameters.npcHandler:parseMessage(parameters.text, parseInfo), cid, true) + parameters.npcHandler:resetNpc(cid) + parameters.npcHandler:releaseFocus(cid) + return true +end + +-- Adds a keyword which acts as a greeting word +function KeywordHandler:addGreetKeyword(keys, parameters, condition, action) + local keys = keys + keys.callback = FocusModule.messageMatcherDefault + return self:addKeyword(keys, GreetModule.greet, parameters, condition, action) +end + +-- Adds a keyword which acts as a farewell word +function KeywordHandler:addFarewellKeyword(keys, parameters, condition, action) + local keys = keys + keys.callback = FocusModule.messageMatcherDefault + return self:addKeyword(keys, GreetModule.farewell, parameters, condition, action) +end + +-- Adds a keyword which acts as a spell word +function KeywordHandler:addSpellKeyword(keys, parameters) + local keys = keys + keys.callback = FocusModule.messageMatcherDefault + + local npcHandler, spellName, price, vocationId = parameters.npcHandler, parameters.spellName, parameters.price, parameters.vocation + local spellKeyword = self:addKeyword(keys, StdModule.say, {npcHandler = npcHandler, text = string.format("Do you want to learn the spell '%s' for %s?", spellName, price > 0 and price .. ' gold' or 'free')}, + function(player) + -- This will register for all client id vocations + local vocationClientId = player:getVocation():getClientId() + if type(vocationId) == 'table' then + return table.contains(vocationId, vocationClientId) + else + return vocationId == vocationClientId + end + end + ) + + spellKeyword:addChildKeyword({'yes'}, StdModule.learnSpell, {npcHandler = npcHandler, spellName = spellName, level = parameters.level, price = price}) + spellKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'Maybe next time.', reset = true}) +end + +local hints = { + [-1] = 'If you don\'t know the meaning of an icon on the right side, move the mouse cursor on it and wait a moment.', + [0] = 'Send private messages to other players by right-clicking on the player or the player\'s name and select \'Message to ....\'. You can also open a \'private message channel\' and type in the name of the player.', + [1] = 'Use the shortcuts \'SHIFT\' to look, \'CTRL\' for use and \'ALT\' for attack when clicking on an object or player.', + [2] = 'If you already know where you want to go, click on the automap and your character will walk there automatically if the location is reachable and not too far away.', + [3] = 'To open or close skills, battle or VIP list, click on the corresponding button to the right.', + [4] = '\'Capacity\' restricts the amount of things you can carry with you. It raises with each level.', + [5] = 'Always have a look on your health bar. If you see that you do not regenerate health points anymore, eat something.', + [6] = 'Always eat as much food as possible. This way, you\'ll regenerate health points for a longer period of time.', + [7] = 'After you have killed a monster, you have 10 seconds in which the corpse is not moveable and no one else but you can loot it.', + [8] = 'Be careful when you approach three or more monsters because you only can block the attacks of two. In such a situation even a few rats can do severe damage or even kill you.', + [9] = 'There are many ways to gather food. Many creatures drop food but you can also pick blueberries or bake your own bread. If you have a fishing rod and worms in your inventory, you can also try to catch a fish.', + [10] = {'Baking bread is rather complex. First of all you need a scythe to harvest wheat. Then you use the wheat with a millstone to get flour. ...', 'This can be be used on water to get dough, which can be used on an oven to bake bread. Use milk instead of water to get cake dough.'}, + [11] = 'Dying hurts! Better run away than risk your life. You are going to lose experience and skill points when you die.', + [12] = 'When you switch to \'Offensive Fighting\', you deal out more damage but you also get hurt more easily.', + [13] = 'When you are on low health and need to run away from a monster, switch to \'Defensive Fighting\' and the monster will hit you less severely.', + [14] = 'Many creatures try to run away from you. Select \'Chase Opponent\' to follow them.', + [15] = 'The deeper you enter a dungeon, the more dangerous it will be. Approach every dungeon with utmost care or an unexpected creature might kill you. This will result in losing experience and skill points.', + [16] = 'Due to the perspective, some objects in Tibia are not located at the spot they seem to appear (ladders, windows, lamps). Try clicking on the floor tile the object would lie on.', + [17] = 'If you want to trade an item with another player, right-click on the item and select \'Trade with ...\', then click on the player with whom you want to trade.', + [18] = 'Stairs, ladders and dungeon entrances are marked as yellow dots on the automap.', + [19] = 'You can get food by killing animals or monsters. You can also pick blueberries or bake your own bread. If you are too lazy or own too much money, you can also buy food.', + [20] = 'Quest containers can be recognised easily. They don\'t open up regularly but display a message \'You have found ....\'. They can only be opened once.', + [21] = 'Better run away than risk to die. You\'ll lose experience and skill points each time you die.', + [22] = 'You can form a party by right-clicking on a player and selecting \'Invite to Party\'. The party leader can also enable \'Shared Experience\' by right-clicking on him- or herself.', + [23] = 'You can assign spells, the use of items, or random text to \'hotkeys\'. You find them under \'Options\'.', + [24] = 'You can also follow other players. Just right-click on the player and select \'Follow\'.', + [25] = 'You can found a party with your friends by right-clicking on a player and selecting \'Invite to Party\'. If you are invited to a party, right-click on yourself and select \'Join Party\'.', + [26] = 'Only found parties with people you trust. You can attack people in your party without getting a skull. This is helpful for training your skills, but can be abused to kill people without having to fear negative consequences.', + [27] = 'The leader of a party has the option to distribute gathered experience among all players in the party. If you are the leader, right-click on yourself and select \'Enable Shared Experience\'.', + [28] = 'There is nothing more I can tell you. If you are still in need of some {hints}, I can repeat them for you.' +} + +function StdModule.rookgaardHints(cid, message, keywords, parameters, node) + local npcHandler = parameters.npcHandler + if npcHandler == nil then + error("StdModule.say called without any npcHandler instance.") + end + + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + local hintId = player:getStorageValue(Storage.RookgaardHints) + npcHandler:say(hints[hintId], cid) + if hintId >= #hints then + player:setStorageValue(Storage.RookgaardHints, -1) + else + player:setStorageValue(Storage.RookgaardHints, hintId + 1) + end + return true +end + +-- VoiceModule +VoiceModule = { + voices = nil, + voiceCount = 0, + lastVoice = 0, + timeout = nil, + chance = nil, + npcHandler = nil +} + +-- Creates a new instance of VoiceModule +function VoiceModule:new(voices, timeout, chance) + local obj = {} + setmetatable(obj, self) + self.__index = self + + obj.voices = voices + for i = 1, #obj.voices do + local voice = obj.voices[i] + if voice.yell then + voice.yell = nil + voice.talktype = TALKTYPE_YELL + else + voice.talktype = TALKTYPE_SAY + end + end + + obj.voiceCount = #voices + obj.timeout = timeout or 10 + obj.chance = chance or 25 + return obj +end + +function VoiceModule:init(handler) + return true +end + +function VoiceModule:callbackOnThink() + if self.lastVoice < os.time() then + self.lastVoice = os.time() + self.timeout + if math.random(100) < self.chance then + local voice = self.voices[math.random(self.voiceCount)] + Npc():say(voice.text, voice.talktype) + end + end + return true +end + +function Player.removeMoneyNpc(self, amount) + + if type(amount) == 'string' then + amount = tonumber(amount) + end + + local moneyCount = self:getMoney() + local bankCount = self:getBankBalance() + + -- The player have all the money with him + if amount <= moneyCount then + -- Removes player inventory money + self:removeMoney(amount) + + self:sendTextMessage(MESSAGE_TRADE, ("Paid %d gold from inventory."):format(amount)) + return true + + -- The player doens't have all the money with him + elseif amount <= (moneyCount + bankCount) then + + -- Check if the player has some money + if moneyCount ~= 0 then + -- Removes player inventory money + self:removeMoney(moneyCount) + local remains = amount - moneyCount + + -- Removes player bank money + self:setBankBalance(bankCount - remains) + + self:sendTextMessage(MESSAGE_TRADE, ("Paid %d from inventory and %d gold from bank account. Your account balance is now %d gold."):format(moneyCount, amount - moneyCount, self:getBankBalance())) + return true + + else + self:setBankBalance(bankCount - amount) + self:sendTextMessage(MESSAGE_TRADE, ("Paid %d gold from bank account. Your account balance is now %d gold."):format(amount, self:getBankBalance())) + return true + end + end + + return false +end + +local function getPlayerMoney(cid) + local player = Player(cid) + if player then + return player:getMoney() + player:getBankBalance() + end + return 0 +end + +local function doPlayerRemoveMoney(cid, amount) + local player = Player(cid) + if player then + return player:removeMoneyNpc(amount) + end + return false +end diff --git a/data/npc/lib/npcsystem/keywordhandler.lua b/data/npc/lib/npcsystem/keywordhandler.lua new file mode 100644 index 00000000000..97dbf7a48a3 --- /dev/null +++ b/data/npc/lib/npcsystem/keywordhandler.lua @@ -0,0 +1,230 @@ +-- Advanced NPC System by Jiddo + +if KeywordHandler == nil then + + KeywordNode = { + keywords = nil, + callback = nil, + parameters = nil, + children = nil, + parent = nil, + condition = nil, + action = nil + } + + -- Created a new keywordnode with the given keywords, callback function and parameters and without any childNodes. + function KeywordNode:new(keys, func, param, condition, action) + local obj = {} + obj.keywords = keys + obj.callback = func + obj.parameters = param + obj.children = {} + obj.condition = condition + obj.action = action + setmetatable(obj, self) + self.__index = self + return obj + end + + -- Calls the underlying callback function if it is not nil. + function KeywordNode:processMessage(cid, message) + return (self.callback == nil or self.callback(cid, message, self.keywords, self.parameters, self)) + end + + function KeywordNode:processAction(cid, message) + if not self.action then + return + end + + local player = Player(cid) + if not player then + return + end + + self.action(player, self.parameters.npcHandler, message) + end + + -- Returns true if message contains all patterns/strings found in keywords. + function KeywordNode:checkMessage(cid, message) + if self.keywords.callback ~= nil then + local ret, data = self.keywords.callback(self.keywords, message) + if not ret then + return false + end + + if self.condition and not self.condition(Player(cid), data) then + return false + end + return true + end + + local data = {} + local last = 0 + for _, keyword in ipairs(self.keywords) do + if type(keyword) == 'string' then + local a, b = string.find(message, keyword) + if a == nil or b == nil or a < last then + return false + end + if keyword:sub(1, 1) == '%' then + data[#data + 1] = tonumber(message:sub(a, b)) or nil + end + last = a + end + end + + if self.condition and not self.condition(Player(cid), data) then + return false + end + return true + end + + -- Returns the parent of this node or nil if no such node exists. + function KeywordNode:getParent() + return self.parent + end + + -- Returns an array of the callback function parameters assosiated with this node. + function KeywordNode:getParameters() + return self.parameters + end + + -- Returns an array of the triggering keywords assosiated with this node. + function KeywordNode:getKeywords() + return self.keywords + end + + -- Adds a childNode to this node. Creates the childNode based on the parameters (k = keywords, c = callback, p = parameters) + function KeywordNode:addChildKeyword(keywords, callback, parameters, condition, action) + local new = KeywordNode:new(keywords, callback, parameters, condition, action) + return self:addChildKeywordNode(new) + end + + function KeywordNode:addAliasKeyword(keywords) + if #self.children == 0 then + Spdlog.error('[KeywordNode:addAliasKeyword] - No previous node found') + return false + end + + local prevNode = self.children[#self.children] + local new = KeywordNode:new(keywords, prevNode.callback, prevNode.parameters, prevNode.condition, prevNode.action) + for i = 1, #prevNode.children do + new:addChildKeywordNode(prevNode.children[i]) + end + return self:addChildKeywordNode(new) + end + + -- Adds a pre-created childNode to this node. Should be used for example if several nodes should have a common child. + function KeywordNode:addChildKeywordNode(childNode) + self.children[#self.children + 1] = childNode + childNode.parent = self + return childNode + end + + KeywordHandler = { + root = nil, + lastNode = nil + } + + -- Creates a new keywordhandler with an empty rootnode. + function KeywordHandler:new() + local obj = {} + obj.root = KeywordNode:new(nil, nil, nil) + obj.lastNode = {} + setmetatable(obj, self) + self.__index = self + return obj + end + + -- Resets the lastNode field, and this resetting the current position in the node hierarchy to root. + function KeywordHandler:reset(cid) + if self.lastNode[cid] then + self.lastNode[cid] = nil + end + end + + -- Makes sure the correct childNode of lastNode gets a chance to process the message. + function KeywordHandler:processMessage(cid, message) + local node = self:getLastNode(cid) + if node == nil then + error('No root node found.') + return false + end + + local ret = self:processNodeMessage(node, cid, message) + if ret then + return true + end + + if node:getParent() then + node = node:getParent() -- Search through the parent. + local ret = self:processNodeMessage(node, cid, message) + if ret then + return true + end + end + + if node ~= self:getRoot() then + node = self:getRoot() -- Search through the root. + local ret = self:processNodeMessage(node, cid, message) + if ret then + return true + end + end + return false + end + + -- Tries to process the given message using the node parameter's children and calls the node's callback function if found. + -- Returns the childNode which processed the message or nil if no such node was found. + function KeywordHandler:processNodeMessage(node, cid, message) + local messageLower = message:lower() + for _, childNode in pairs(node.children) do + if childNode:checkMessage(cid, messageLower) then + local oldLast = self.lastNode[cid] + self.lastNode[cid] = childNode + childNode.parent = node -- Make sure node is the parent of childNode (as one node can be parent to several nodes). + if childNode:processMessage(cid, message) then + childNode:processAction(cid, message) + return true + end + self.lastNode[cid] = oldLast + end + end + return false + end + + -- Returns the root keywordnode + function KeywordHandler:getRoot() + return self.root + end + + -- Returns the last processed keywordnode or root if no last node is found. + function KeywordHandler:getLastNode(cid) + return self.lastNode[cid] or self:getRoot() + end + + -- Adds a new keyword to the root keywordnode. Returns the new node. + function KeywordHandler:addKeyword(keys, callback, parameters, condition, action) + return self:getRoot():addChildKeyword(keys, callback, parameters, condition, action) + end + + -- Adds an alias keyword for the previous node. + function KeywordHandler:addAliasKeyword(keys) + return self:getRoot():addAliasKeyword(keys) + end + + -- Moves the current position in the keyword hierarchy count steps upwards. Count defalut value = 1. + -- This function MIGHT not work properly yet. Use at your own risk. + function KeywordHandler:moveUp(cid, steps) + if steps == nil or type(steps) ~= "number" then + steps = 1 + end + for i = 1, steps do + if self.lastNode[cid] == nil then + return nil + end + self.lastNode[cid] = self.lastNode[cid]:getParent() or self:getRoot() + end + return self.lastNode[cid] + end +end diff --git a/data/npc/lib/npcsystem/modules.lua b/data/npc/lib/npcsystem/modules.lua new file mode 100644 index 00000000000..aaaf1d83630 --- /dev/null +++ b/data/npc/lib/npcsystem/modules.lua @@ -0,0 +1,1326 @@ +-- Advanced NPC System by Jiddo + +if Modules == nil then + -- default words for greeting and ungreeting the npc. Should be a table containing all such words. + FOCUS_GREETWORDS = {"hi", "hello"} + FOCUS_FAREWELLWORDS = {"bye", "farewell"} + + -- The words for requesting trade window. + SHOP_TRADEREQUEST = {"trade"} + + -- The word for accepting/declining an offer. CAN ONLY CONTAIN ONE FIELD! Should be a table with a single string value. + SHOP_YESWORD = {"yes"} + SHOP_NOWORD = {"no"} + + -- Pattern used to get the amount of an item a player wants to buy/sell. + PATTERN_COUNT = "%d+" + + -- Constants used to separate buying from selling. + SHOPMODULE_SELL_ITEM = 1 + SHOPMODULE_BUY_ITEM = 2 + SHOPMODULE_BUY_ITEM_CONTAINER = 3 + + -- Constants used for shop mode. Notice: addBuyableItemContainer is working on all modes + SHOPMODULE_MODE_TALK = 1 -- Old system used before client version 8.2: sell/buy item name + SHOPMODULE_MODE_TRADE = 2 -- Trade window system introduced in client version 8.2 + SHOPMODULE_MODE_BOTH = 3 -- Both working at one time + + -- Used shop mode + SHOPMODULE_MODE = SHOPMODULE_MODE_BOTH + + Modules = { + parseableModules = {} + } + + StdModule = {} + + -- These callback function must be called with parameters.npcHandler = npcHandler in the parameters table or they will not work correctly. + -- Notice: The members of StdModule have not yet been tested. If you find any bugs, please report them to me. + -- Usage: + -- keywordHandler:addKeyword({"offer"}, StdModule.say, {npcHandler = npcHandler, text = "I sell many powerful melee weapons."}) + function StdModule.say(cid, message, keywords, parameters, node) + local npcHandler = parameters.npcHandler + if npcHandler == nil then + error("StdModule.say called without any npcHandler instance.") + end + + if parameters.onlyFocus == true and parameters.onlyUnfocus == true then + error("StdModule.say conflicting parameters 'onlyFocus' and 'onlyUnfocus' both true") + end + + local onlyFocus = (parameters.onlyFocus == nil or parameters.onlyFocus == true) + if not npcHandler:isFocused(cid) and onlyFocus then + return false + end + + if npcHandler:isFocused(cid) and parameters.onlyUnfocus == true then + return false + end + + local player = Player(cid) + local cost, costMessage = parameters.cost, '%d gold' + if cost and cost > 0 then + if parameters.discount then + cost = cost - StdModule.travelDiscount(player, parameters.discount) + end + + costMessage = cost > 0 and string.format(costMessage, cost) or 'free' + else + costMessage = 'free' + end + + local parseInfo = {[TAG_PLAYERNAME] = player:getName(), [TAG_TIME] = getFormattedWorldTime(), [TAG_BLESSCOST] = getBlessingsCost(player:getLevel()), [TAG_PVPBLESSCOST] = getPvpBlessingCost(player:getLevel()), [TAG_TRAVELCOST] = costMessage} + if parameters.text then + npcHandler:say(npcHandler:parseMessage(parameters.text, parseInfo), cid, parameters.publicize and true) + end + + if parameters.ungreet then + npcHandler:resetNpc(cid) + npcHandler:releaseFocus(cid) + elseif parameters.reset then + local parseInfo = {[TAG_PLAYERNAME] = Player(cid):getName()} + npcHandler:say(npcHandler:parseMessage(parameters.text or parameters.message, parseInfo), cid, parameters.publicize and true) + if parameters.reset then + npcHandler:resetNpc(cid) + elseif parameters.moveup then + npcHandler.keywordHandler:moveUp(cid, parameters.moveup) + end + end + + return true + end + + --Usage: + -- local node1 = keywordHandler:addKeyword({"promot"}, StdModule.say, {npcHandler = npcHandler, text = "I can promote you for 20000 gold coins. Do you want me to promote you?"}) + -- node1:addChildKeyword({"yes"}, StdModule.promotePlayer, {npcHandler = npcHandler, cost = 20000, level = 20}, text = "Congratulations! You are now promoted.") + -- node1:addChildKeyword({"no"}, StdModule.say, {npcHandler = npcHandler, text = "Allright then. Come back when you are ready."}, reset = true) + function StdModule.promotePlayer(cid, message, keywords, parameters, node) + local npcHandler = parameters.npcHandler + if npcHandler == nil then + error("StdModule.promotePlayer called without any npcHandler instance.") + end + + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if player:isPremium() or not parameters.premium then + local promotion = player:getVocation():getPromotion() + if player:getStorageValue(STORAGEVALUE_PROMOTION) == 1 then + npcHandler:say("You are already promoted!", cid) + elseif player:getLevel() < parameters.level then + npcHandler:say("I am sorry, but I can only promote you once you have reached level " .. parameters.level .. ".", cid) + elseif not player:removeMoneyNpc(parameters.cost) then + npcHandler:say("You do not have enough money!", cid) + else + npcHandler:say(parameters.text, cid) + player:setVocation(promotion) + player:setStorageValue(STORAGEVALUE_PROMOTION, 1) + end + else + npcHandler:say("You need a premium account in order to get promoted.", cid) + end + npcHandler:resetNpc(cid) + return true + end + + function StdModule.learnSpell(cid, message, keywords, parameters, node) + local npcHandler = parameters.npcHandler + if npcHandler == nil then + error("StdModule.learnSpell called without any npcHandler instance.") + end + + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if player:isPremium() or not parameters.premium then + if player:hasLearnedSpell(parameters.spellName) then + npcHandler:say("You already know this spell.", cid) + elseif not player:canLearnSpell(parameters.spellName) then + npcHandler:say("You cannot learn this spell.", cid) + elseif not player:removeMoneyNpc(parameters.price) then + npcHandler:say("You do not have enough money, this spell costs " .. parameters.price .. " gold.", cid) + else + npcHandler:say("You have learned " .. parameters.spellName .. ".", cid) + player:learnSpell(parameters.spellName) + end + else + npcHandler:say("You need a premium account in order to buy " .. parameters.spellName .. ".", cid) + end + + npcHandler:resetNpc(cid) + return true + end + + function StdModule.bless(cid, message, keywords, parameters, node) + local npcHandler = parameters.npcHandler + if npcHandler == nil then + error("StdModule.bless called without any npcHandler instance.") + end + + if not npcHandler:isFocused(cid) or Game.getWorldType() == WORLD_TYPE_PVP_ENFORCED then + return false + end + + local player = Player(cid) + local parseInfo = {[TAG_BLESSCOST] = getBlessingsCost(player:getLevel()), [TAG_PVPBLESSCOST] = getPvpBlessingCost(player:getLevel())} + if player:hasBlessing(parameters.bless) then + npcHandler:say("You already possess this blessing.", cid) + elseif parameters.bless == 3 and player:getStorageValue(Storage.KawillBlessing) ~= 1 then + npcHandler:say("You need the blessing of the great geomancer first.", cid) + elseif parameters.bless == 1 and #player:getBlessings() == 0 and not player:getItemById(2173, true) then + npcHandler:say("You don't have any of the other blessings nor an amulet of loss, so it wouldn't make sense to bestow this protection on you now. Remember that it can only protect you from the loss of those!", cid) + elseif not player:removeMoneyNpc(type(parameters.cost) == "string" and npcHandler:parseMessage(parameters.cost, parseInfo) or parameters.cost) then + npcHandler:say("Oh. You do not have enough money.", cid) + else + npcHandler:say(parameters.text or "You have been blessed by one of the seven gods!", cid) + if parameters.bless == 3 then + player:setStorageValue(Storage.KawillBlessing, 0) + end + player:addBlessing(parameters.bless, 1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + end + + npcHandler:resetNpc(cid) + return true + end + + function StdModule.travel(cid, message, keywords, parameters, node) + local npcHandler = parameters.npcHandler + if npcHandler == nil then + error("StdModule.travel called without any npcHandler instance.") + end + + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + local cost = parameters.cost + if cost and cost > 0 then + if parameters.discount then + cost = cost - StdModule.travelDiscount(player, parameters.discount) + + if cost < 0 then + cost = 0 + end + end + else + cost = 0 + end + + if parameters.premium and not player:isPremium() then + npcHandler:say("I'm sorry, but you need a premium account in order to travel onboard our ships.", cid) + elseif parameters.level and player:getLevel() < parameters.level then + npcHandler:say("You must reach level " .. parameters.level .. " before I can let you go there.", cid) + elseif player:isPzLocked() then + npcHandler:say("First get rid of those blood stains! You are not going to ruin my vehicle!", cid) + elseif not player:removeMoneyNpc(cost) then + npcHandler:say("You don't have enough money.", cid) + elseif os.time() < getPlayerStorageValue(cid, Storage.NpcExhaust) then + npcHandler:say('Sorry, but you need to wait three seconds before travel again.', cid) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + else + npcHandler:releaseFocus(cid) + npcHandler:say(parameters.text or "Set the sails!", cid) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + + local destination = parameters.destination + if type(destination) == 'function' then + destination = destination(player) + end + + player:teleportTo(destination) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + + setPlayerStorageValue(cid, StorageNpcExhaust, 3 + os.time()) + player:teleportTo(destination) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + + -- What a foolish Quest - Mission 3 + if player:getStorageValue(Storage.WhatAFoolish.PieBoxTimer) > os.time() then + if destination ~= Position(32660, 31957, 15) then -- kazordoon steamboat + player:setStorageValue(Storage.WhatAFoolish.PieBoxTimer, 1) + end + end + end + + npcHandler:resetNpc(cid) + return true + end + + FocusModule = { + npcHandler = nil, + greetWords = nil, + farewellWords = nil, + greetCallback = nil, + farewellCallback = nil + } + + -- Creates a new instance of FocusModule without an associated NpcHandler. + function FocusModule:new() + local obj = {} + setmetatable(obj, self) + self.__index = self + return obj + end + + -- Inits the module and associates handler to it. + function FocusModule:init(handler) + self.npcHandler = handler + for i, word in pairs(FOCUS_GREETWORDS) do + local obj = {} + obj[#obj + 1] = word + obj.callback = FOCUS_GREETWORDS.callback or FocusModule.messageMatcher + handler.keywordHandler:addKeyword(obj, FocusModule.onGreet, {module = self}) + end + + for i, word in pairs(FOCUS_FAREWELLWORDS) do + local obj = {} + obj[#obj + 1] = word + obj.callback = FOCUS_FAREWELLWORDS.callback or FocusModule.messageMatcher + handler.keywordHandler:addKeyword(obj, FocusModule.onFarewell, {module = self}) + end + + return true + end + + -- Set custom greeting messages + function FocusModule:addGreetMessage(message) + if not self.greetWords then + self.greetWords = {} + end + + + if type(message) == 'string' then + table.insert(self.greetWords, message) + else + for i = 1, #message do + table.insert(self.greetWords, message[i]) + end + end + end + + -- Set custom farewell messages + function FocusModule:addFarewellMessage(message) + if not self.farewellWords then + self.farewellWords = {} + end + + if type(message) == 'string' then + table.insert(self.farewellWords, message) + else + for i = 1, #message do + table.insert(self.farewellWords, message[i]) + end + end + end + + -- Set custom greeting callback + function FocusModule:setGreetCallback(callback) + self.greetCallback = callback + end + + -- Set custom farewell callback + function FocusModule:setFarewellCallback(callback) + self.farewellCallback = callback + end + + -- Greeting callback function. + function FocusModule.onGreet(cid, message, keywords, parameters) + parameters.module.npcHandler:onGreet(cid, message) + return true + end + + -- UnGreeting callback function. + function FocusModule.onFarewell(cid, message, keywords, parameters) + if parameters.module.npcHandler:isFocused(cid) then + parameters.module.npcHandler:onFarewell(cid) + return true + else + return false + end + end + + -- Custom message matching callback function for greeting messages. + function FocusModule.messageMatcher(keywords, message) + for i, word in pairs(keywords) do + if type(word) == "string" then + if string.find(message, word) and not string.find(message, "[%w+]" .. word) and not string.find(message, word .. "[%w+]") then + return true + end + end + end + return false + end + + KeywordModule = { + npcHandler = nil + } + -- Add it to the parseable module list. + Modules.parseableModules["module_keywords"] = KeywordModule + + function KeywordModule:new() + local obj = {} + setmetatable(obj, self) + self.__index = self + return obj + end + + function KeywordModule:init(handler) + self.npcHandler = handler + return true + end + + -- Parses all known parameters. + function KeywordModule:parseParameters() + local ret = NpcSystem.getParameter("keywords") + if ret then + self:parseKeywords(ret) + end + end + + function KeywordModule:parseKeywords(data) + local n = 1 + for keys in string.gmatch(data, "[^;]+") do + local i = 1 + + local keywords = {} + for temp in string.gmatch(keys, "[^,]+") do + keywords[#keywords + 1] = temp + i = i + 1 + end + + if i ~= 1 then + local reply = NpcSystem.getParameter("keyword_reply" .. n) + if reply then + self:addKeyword(keywords, reply) + else + Spdlog.warn(string.format("[KeywordModule:parseKeywords] - %s] NpcSystem: Parameter keyword_reply [%d] missing. Skipping...", + Npc():getName(), n)) + end + else + Spdlog.warn(string.format("[KeywordModule:parseKeywords] - %s] NpcSystem: No keywords found for keyword set [%d]. Skipping...", + Npc():getName(), n)) + end + + n = n + 1 + end + end + + function KeywordModule:addKeyword(keywords, reply) + self.npcHandler.keywordHandler:addKeyword(keywords, StdModule.say, {npcHandler = self.npcHandler, onlyFocus = true, text = reply, reset = true}) + end + + TravelModule = { + npcHandler = nil, + destinations = nil, + yesNode = nil, + noNode = nil, + } + + -- Add it to the parseable module list. + Modules.parseableModules["module_travel"] = TravelModule + + function TravelModule:new() + local obj = {} + setmetatable(obj, self) + self.__index = self + return obj + end + + function TravelModule:init(handler) + self.npcHandler = handler + self.yesNode = KeywordNode:new(SHOP_YESWORD, TravelModule.onConfirm, {module = self}) + self.noNode = KeywordNode:new(SHOP_NOWORD, TravelModule.onDecline, {module = self}) + self.destinations = {} + return true + end + + -- Parses all known parameters. + function TravelModule:parseParameters() + local ret = NpcSystem.getParameter("travel_destinations") + if ret then + self:parseDestinations(ret) + + self.npcHandler.keywordHandler:addKeyword({"destination"}, TravelModule.listDestinations, {module = self}) + self.npcHandler.keywordHandler:addKeyword({"where"}, TravelModule.listDestinations, {module = self}) + self.npcHandler.keywordHandler:addKeyword({"travel"}, TravelModule.listDestinations, {module = self}) + + end + end + + function TravelModule:parseDestinations(data) + for destination in string.gmatch(data, "[^;]+") do + local i = 1 + + local name = nil + local x = nil + local y = nil + local z = nil + local cost = nil + local premium = false + + for temp in string.gmatch(destination, "[^,]+") do + if i == 1 then + name = temp + elseif i == 2 then + x = tonumber(temp) + elseif i == 3 then + y = tonumber(temp) + elseif i == 4 then + z = tonumber(temp) + elseif i == 5 then + cost = tonumber(temp) + elseif i == 6 then + premium = temp == "true" + else + Spdlog.warn(string.format("[TravelModule:parseDestinations] - %s] NpcSystem: Unknown parameter found in travel destination parameter. temp[%d], destination[%s]", + Npc():getName(), temp, destination)) + end + i = i + 1 + end + + if name and x and y and z and cost then + self:addDestination(name, {x=x, y=y, z=z}, cost, premium) + else + Spdlog.warn("[TravelModule:parseDestinations] - " .. Npc():getName() .. "] NpcSystem: Parameter(s) missing for travel destination:", name, x, y, z, cost, premium) + end + end + end + + function TravelModule:addDestination(name, position, price, premium) + self.destinations[#self.destinations + 1] = name + + local parameters = { + cost = price, + destination = position, + premium = premium, + module = self + } + local keywords = {} + keywords[#keywords + 1] = name + + local keywords2 = {} + keywords2[#keywords2 + 1] = "bring me to " .. name + local node = self.npcHandler.keywordHandler:addKeyword(keywords, TravelModule.travel, parameters) + self.npcHandler.keywordHandler:addKeyword(keywords2, TravelModule.bringMeTo, parameters) + node:addChildKeywordNode(self.yesNode) + node:addChildKeywordNode(self.noNode) + + if npcs_loaded_travel[getNpcCid()] == nil then + npcs_loaded_travel[getNpcCid()] = getNpcCid() + self.npcHandler.keywordHandler:addKeyword({'yes'}, TravelModule.onConfirm, {module = self}) + self.npcHandler.keywordHandler:addKeyword({'no'}, TravelModule.onDecline, {module = self}) + end + end + + function TravelModule.travel(cid, message, keywords, parameters, node) + local module = parameters.module + if not module.npcHandler:isFocused(cid) then + return false + end + + local npcHandler = module.npcHandler + + shop_destination[cid] = parameters.destination + shop_cost[cid] = parameters.cost + shop_premium[cid] = parameters.premium + shop_npcuid[cid] = getNpcCid() + + local cost = parameters.cost + local destination = parameters.destination + local premium = parameters.premium + + module.npcHandler:say("Do you want to travel to " .. keywords[1] .. " for " .. cost .. " gold coins?", cid) + return true + end + + function TravelModule.onConfirm(cid, message, keywords, parameters, node) + local module = parameters.module + if not module.npcHandler:isFocused(cid) then + return false + end + + if shop_npcuid[cid] ~= Npc().uid then + return false + end + + local npcHandler = module.npcHandler + + local cost = shop_cost[cid] + local destination = Position(shop_destination[cid]) + + local player = Player(cid) + if player:isPremium() or not shop_premium[cid] then + if not player:removeMoneyNpc(cost) then + npcHandler:say("You do not have enough money!", cid) + elseif player:isPzLocked(cid) then + npcHandler:say("Get out of there with this blood.", cid) + else + npcHandler:say("It was a pleasure doing business with you.", cid) + npcHandler:releaseFocus(cid) + + local position = player:getPosition() + player:teleportTo(destination) + + position:sendMagicEffect(CONST_ME_TELEPORT) + destination:sendMagicEffect(CONST_ME_TELEPORT) + end + else + npcHandler:say("I can only allow premium players to travel there.", cid) + end + + npcHandler:resetNpc(cid) + return true + end + + -- onDecline keyword callback function. Generally called when the player sais "no" after wanting to buy an item. + function TravelModule.onDecline(cid, message, keywords, parameters, node) + local module = parameters.module + if not module.npcHandler:isFocused(cid) or shop_npcuid[cid] ~= getNpcCid() then + return false + end + local parentParameters = node:getParent():getParameters() + local parseInfo = { [TAG_PLAYERNAME] = Player(cid):getName() } + local msg = module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_DECLINE), parseInfo) + module.npcHandler:say(msg, cid) + module.npcHandler:resetNpc(cid) + return true + end + + function TravelModule.bringMeTo(cid, message, keywords, parameters, node) + local module = parameters.module + if not module.npcHandler:isFocused(cid) then + return false + end + + local cost = parameters.cost + local destination = Position(parameters.destination) + + local player = Player(cid) + if player:isPremium() or not parameters.premium then + if player:removeMoneyNpc(cost) then + local position = player:getPosition() + player:teleportTo(destination) + + position:sendMagicEffect(CONST_ME_TELEPORT) + destination:sendMagicEffect(CONST_ME_TELEPORT) + end + end + return true + end + + function TravelModule.listDestinations(cid, message, keywords, parameters, node) + local module = parameters.module + if not module.npcHandler:isFocused(cid) then + return false + end + + local msg = "I can bring you to " + --local i = 1 + local maxn = #module.destinations + for i, destination in pairs(module.destinations) do + msg = msg .. destination + if i == maxn - 1 then + msg = msg .. " and " + elseif i == maxn then + msg = msg .. "." + else + msg = msg .. ", " + end + i = i + 1 + end + + module.npcHandler:say(msg, cid) + module.npcHandler:resetNpc(cid) + return true + end + + ShopModule = { + npcHandler = nil, + yesNode = nil, + noNode = nil, + noText = "", + maxCount = 100, + amount = 0 + } + + -- Add it to the parseable module list. + Modules.parseableModules["module_shop"] = ShopModule + + -- Creates a new instance of ShopModule + function ShopModule:new() + local obj = {} + setmetatable(obj, self) + self.__index = self + return obj + end + + -- Parses all known parameters. + function ShopModule:parseParameters() + local ret = NpcSystem.getParameter("shop_buyable") + if ret then + self:parseBuyable(ret) + end + + local ret = NpcSystem.getParameter("shop_sellable") + if ret then + self:parseSellable(ret) + end + + local ret = NpcSystem.getParameter("shop_buyable_containers") + if ret then + self:parseBuyableContainers(ret) + end + end + + -- Parse a string contaning a set of buyable items. + function ShopModule:parseBuyable(data) + for item in string.gmatch(data, "[^;]+") do + local i = 1 + + local name = nil + local itemid = nil + local cost = nil + local subType = nil + local realName = nil + + for temp in string.gmatch(item, "[^,]+") do + if i == 1 then + name = temp + elseif i == 2 then + itemid = tonumber(temp) + elseif i == 3 then + cost = tonumber(temp) + elseif i == 4 then + subType = tonumber(temp) + elseif i == 5 then + realName = temp + else + Spdlog.warn("[ShopModule:parseBuyable] - " .. Npc():getName() .. "] NpcSystem: Unknown parameter found in buyable items parameter.", temp, item) + end + i = i + 1 + end + + local it = ItemType(itemid) + if subType == nil and it:getCharges() ~= 0 then + subType = it:getCharges() + end + + if SHOPMODULE_MODE == SHOPMODULE_MODE_TRADE then + if itemid and cost then + if subType == nil and it:isFluidContainer() then + Spdlog.warn("[ShopModule:parseBuyable] - " .. Npc():getName() .. "] NpcSystem: SubType missing for parameter item:", item) + else + self:addBuyableItem(nil, itemid, cost, subType, realName) + end + else + Spdlog.warn("[ShopModule:parseBuyable] - " .. Npc():getName() .. "] NpcSystem: Parameter(s) missing for item:", itemid, cost) + end + else + if name and itemid and cost then + local VIAL = 2006 + if subType == nil and it:isFluidContainer() then + Spdlog.warn("[ShopModule:parseBuyable] - " .. Npc():getName() .. "] NpcSystem: SubType missing for parameter item:", item) + elseif itemid == VIAL then + local vials = {"vial of water","vial of blood", nil, "vial of slime", nil, nil, nil, nil, nil, nil, "vial of oil", nil, "vial of urine", nil, "vial of oil"} + self:addBuyableItem(nil, itemid, cost, subType, vials[subType]) + else + local names = {} + names[#names + 1] = name + self:addBuyableItem(names, itemid, cost, subType, realName) + end + else + Spdlog.warn("[ShopModule:parseBuyable] - " .. Npc():getName() .. "] NpcSystem: Parameter(s) missing for item:", name, itemid, cost) + end + end + end + end + + -- Parse a string contaning a set of sellable items. + function ShopModule:parseSellable(data) + for item in string.gmatch(data, "[^;]+") do + local i = 1 + + local name = nil + local itemid = nil + local cost = nil + local realName = nil + local subType = nil + + for temp in string.gmatch(item, "[^,]+") do + if i == 1 then + name = temp + elseif i == 2 then + itemid = tonumber(temp) + elseif i == 3 then + cost = tonumber(temp) + elseif i == 4 then + realName = temp + elseif i == 5 then + subType = tonumber(temp) + else + Spdlog.warn("[ShopModule:parseSellable] - " .. Npc():getName() .. "] NpcSystem: Unknown parameter found in sellable items parameter.", temp, item) + end + i = i + 1 + end + + if SHOPMODULE_MODE == SHOPMODULE_MODE_TRADE then + if itemid and cost then + self:addSellableItem(nil, itemid, cost, realName, subType) + else + Spdlog.warn("[ShopModule:parseSellable] - " .. Npc():getName() .. "] NpcSystem: Parameter(s) missing for item:", itemid, cost) + end + else + if name and itemid and cost then + local names = {} + names[#names + 1] = name + self:addSellableItem(names, itemid, cost, realName, subType) + else + Spdlog.warn("[ShopModule:parseSellable] - " .. Npc():getName() .. "] NpcSystem: Parameter(s) missing for item:", name, itemid, cost) + end + end + end + end + + -- Parse a string contaning a set of buyable items. + function ShopModule:parseBuyableContainers(data) + for item in string.gmatch(data, "[^;]+") do + local i = 1 + + local name = nil + local container = nil + local itemid = nil + local cost = nil + local subType = nil + local realName = nil + + for temp in string.gmatch(item, "[^,]+") do + if i == 1 then + name = temp + elseif i == 2 then + itemid = tonumber(temp) + elseif i == 3 then + itemid = tonumber(temp) + elseif i == 4 then + cost = tonumber(temp) + elseif i == 5 then + subType = tonumber(temp) + elseif i == 6 then + realName = temp + else + Spdlog.warn("[ShopModule:parseBuyableContainers] - " .. Npc():getName() .. "] NpcSystem: Unknown parameter found in buyable items parameter.", temp, item) + end + i = i + 1 + end + + if name and container and itemid and cost then + if subType == nil and ItemType(itemid):isFluidContainer() then + Spdlog.warn("[ShopModule:parseBuyableContainers] - " .. Npc():getName() .. "] NpcSystem: SubType missing for parameter item:", item) + else + local names = {} + names[#names + 1] = name + self:addBuyableItemContainer(names, container, itemid, cost, subType, realName) + end + else + Spdlog.warn("[ShopModule:parseBuyableContainers] - " .. Npc():getName() .. "] NpcSystem: Parameter(s) missing for item:", name, container, itemid, cost) + end + end + end + + -- Initializes the module and associates handler to it. + function ShopModule:init(handler) + self.npcHandler = handler + self.yesNode = KeywordNode:new(SHOP_YESWORD, ShopModule.onConfirm, {module = self}) + self.noNode = KeywordNode:new(SHOP_NOWORD, ShopModule.onDecline, {module = self}) + self.noText = handler:getMessage(MESSAGE_DECLINE) + + if SHOPMODULE_MODE ~= SHOPMODULE_MODE_TALK then + for i, word in pairs(SHOP_TRADEREQUEST) do + local obj = {} + obj[#obj + 1] = word + obj.callback = SHOP_TRADEREQUEST.callback or ShopModule.messageMatcher + handler.keywordHandler:addKeyword(obj, ShopModule.requestTrade, {module = self}) + end + end + + return true + end + + -- Custom message matching callback function for requesting trade messages. + function ShopModule.messageMatcher(keywords, message) + for i, word in pairs(keywords) do + if type(word) == "string" then + if string.find(message, word) and not string.find(message, "[%w+]" .. word) and not string.find(message, word .. "[%w+]") then + return true + end + end + end + + return false + end + + -- Resets the module-specific variables. + function ShopModule:reset() + self.amount = 0 + end + + -- Function used to match a number value from a string. + function ShopModule:getCount(message) + local ret = 1 + local b, e = string.find(message, PATTERN_COUNT) + if b and e then + ret = tonumber(string.sub(message, b, e)) + end + + if ret <= 0 then + ret = 1 + elseif ret > self.maxCount then + ret = self.maxCount + end + + return ret + end + + -- Adds a new buyable item. + -- names = A table containing one or more strings of alternative names to this item. Used only for old buy/sell system. + -- itemid = The itemid of the buyable item + -- cost = The price of one single item + -- subType - The subType of each rune or fluidcontainer item. Can be left out if it is not a rune/fluidcontainer. Default value is 1. + -- realName - The real, full name for the item. Will be used as ITEMNAME in MESSAGE_ONBUY and MESSAGE_ONSELL if defined. Default value is nil (ItemType(itemId):getName() will be used) + function ShopModule:addBuyableItem(names, itemid, cost, itemSubType, realName) + if SHOPMODULE_MODE ~= SHOPMODULE_MODE_TALK then + if itemSubType == nil then + itemSubType = 1 + end + + local shopItem = self:getShopItem(itemid, itemSubType) + if shopItem == nil then + self.npcHandler.shopItems[#self.npcHandler.shopItems + 1] = {id = itemid, buy = cost, sell = -1, subType = itemSubType, name = realName or ItemType(itemid):getName()} + else + shopItem.buy = cost + end + end + + if names and SHOPMODULE_MODE ~= SHOPMODULE_MODE_TRADE then + for i, name in pairs(names) do + local parameters = { + itemid = itemid, + cost = cost, + eventType = SHOPMODULE_BUY_ITEM, + module = self, + realName = realName or ItemType(itemid):getName(), + subType = itemSubType or 1 + } + + keywords = {} + keywords[#keywords + 1] = "buy" + keywords[#keywords + 1] = name + local node = self.npcHandler.keywordHandler:addKeyword(keywords, ShopModule.tradeItem, parameters) + node:addChildKeywordNode(self.yesNode) + node:addChildKeywordNode(self.noNode) + end + end + + if npcs_loaded_shop[getNpcCid()] == nil then + npcs_loaded_shop[getNpcCid()] = getNpcCid() + self.npcHandler.keywordHandler:addKeyword({'yes'}, ShopModule.onConfirm, {module = self}) + self.npcHandler.keywordHandler:addKeyword({'no'}, ShopModule.onDecline, {module = self}) + end + end + + function ShopModule:getShopItem(itemId, itemSubType) + if ItemType(itemId):isFluidContainer() then + for i = 1, #self.npcHandler.shopItems do + local shopItem = self.npcHandler.shopItems[i] + if shopItem.id == itemId and shopItem.subType == itemSubType then + return shopItem + end + end + else + for i = 1, #self.npcHandler.shopItems do + local shopItem = self.npcHandler.shopItems[i] + if shopItem.id == itemId then + return shopItem + end + end + end + return nil + end + + -- Adds a new buyable container of items. + -- names = A table containing one or more strings of alternative names to this item. + -- container = Backpack, bag or any other itemid of container where bought items will be stored + -- itemid = The itemid of the buyable item + -- cost = The price of one single item + -- subType - The subType of each rune or fluidcontainer item. Can be left out if it is not a rune/fluidcontainer. Default value is 1. + -- realName - The real, full name for the item. Will be used as ITEMNAME in MESSAGE_ONBUY and MESSAGE_ONSELL if defined. Default value is nil (ItemType(itemId):getName() will be used) + function ShopModule:addBuyableItemContainer(names, container, itemid, cost, subType, realName) + if names then + for i, name in pairs(names) do + local parameters = { + container = container, + itemid = itemid, + cost = cost, + eventType = SHOPMODULE_BUY_ITEM_CONTAINER, + module = self, + realName = realName or ItemType(itemid):getName(), + subType = subType or 1 + } + + keywords = {} + keywords[#keywords + 1] = "buy" + keywords[#keywords + 1] = name + local node = self.npcHandler.keywordHandler:addKeyword(keywords, ShopModule.tradeItem, parameters) + node:addChildKeywordNode(self.yesNode) + node:addChildKeywordNode(self.noNode) + end + end + end + + -- Adds a new sellable item. + -- names = A table containing one or more strings of alternative names to this item. Used only by old buy/sell system. + -- itemid = The itemid of the sellable item + -- cost = The price of one single item + -- realName - The real, full name for the item. Will be used as ITEMNAME in MESSAGE_ONBUY and MESSAGE_ONSELL if defined. Default value is nil (ItemType(itemId):getName() will be used) + function ShopModule:addSellableItem(names, itemid, cost, realName, itemSubType) + if SHOPMODULE_MODE ~= SHOPMODULE_MODE_TALK then + if itemSubType == nil then + itemSubType = 0 + end + + local shopItem = self:getShopItem(itemid, itemSubType) + if shopItem == nil then + self.npcHandler.shopItems[#self.npcHandler.shopItems + 1] = {id = itemid, buy = -1, sell = cost, subType = itemSubType, name = realName or ItemType(itemid):getName()} + else + shopItem.sell = cost + end + end + + if names and SHOPMODULE_MODE ~= SHOPMODULE_MODE_TRADE then + for i, name in pairs(names) do + local parameters = { + itemid = itemid, + cost = cost, + eventType = SHOPMODULE_SELL_ITEM, + module = self, + realName = realName or ItemType(itemid):getName() + } + + keywords = {} + keywords[#keywords + 1] = "sell" + keywords[#keywords + 1] = name + + local node = self.npcHandler.keywordHandler:addKeyword(keywords, ShopModule.tradeItem, parameters) + node:addChildKeywordNode(self.yesNode) + node:addChildKeywordNode(self.noNode) + end + end + end + + -- onModuleReset callback function. Calls ShopModule:reset() + function ShopModule:callbackOnModuleReset() + self:reset() + return true + end + + -- Callback onBuy() function. If you wish, you can change certain Npc to use your onBuy(). + function ShopModule:callbackOnBuy(cid, itemid, subType, amount, ignoreCap, inBackpacks) + local shopItem = self:getShopItem(itemid, subType) + if shopItem == nil then + error("[ShopModule.onBuy] shopItem == nil") + return false + end + + if shopItem.buy == -1 then + error("[ShopModule.onSell] attempt to buy a non-buyable item") + return false + end + + local totalCost = amount * shopItem.buy + if inBackpacks then + totalCost = isItemStackable(itemid) == TRUE and totalCost + 20 or totalCost + (math.max(1, math.floor(amount / getContainerCapById(ITEM_SHOPPING_BAG))) * 20) + end + + local player = Player(cid) + local parseInfo = { + [TAG_PLAYERNAME] = player:getName(), + [TAG_ITEMCOUNT] = amount, + [TAG_TOTALCOST] = totalCost, + [TAG_ITEMNAME] = shopItem.name + } + + if player:getMoney() + player:getBankBalance() < totalCost then + local msg = self.npcHandler:getMessage(MESSAGE_NEEDMONEY) + msg = self.npcHandler:parseMessage(msg, parseInfo) + player:sendCancelMessage(msg) + return false + end + + local subType = shopItem.subType or 1 + local a, b = doNpcSellItem(cid, itemid, amount, subType, ignoreCap, inBackpacks, ITEM_SHOPPING_BAG) + if a < amount then + local msgId = MESSAGE_NEEDMORESPACE + if a == 0 then + msgId = MESSAGE_NEEDSPACE + end + + local msg = self.npcHandler:getMessage(msgId) + parseInfo[TAG_ITEMCOUNT] = a + msg = self.npcHandler:parseMessage(msg, parseInfo) + player:sendCancelMessage(msg) + self.npcHandler.talkStart[cid] = os.time() + + if a > 0 then + if not player:removeMoneyNpc((a * shopItem.buy) + (b * 20)) then + return false + end + return true + end + + return false + else + local msg = self.npcHandler:getMessage(MESSAGE_BOUGHT) + msg = self.npcHandler:parseMessage(msg, parseInfo) + if not player:removeMoneyNpc(totalCost) then + return false + end + player:sendTextMessage(MESSAGE_TRADE, msg) + self.npcHandler.talkStart[cid] = os.time() + return true + end + end + + -- Callback onSell() function. If you wish, you can change certain Npc to use your onSell(). + function ShopModule:callbackOnSell(cid, itemid, subType, amount, ignoreEquipped, _) + local shopItem = self:getShopItem(itemid, subType) + if shopItem == nil then + error("[ShopModule.onSell] items[itemid] == nil") + return false + end + + if shopItem.sell == -1 then + error("[ShopModule.onSell] attempt to sell a non-sellable item") + return false + end + + local player = Player(cid) + local parseInfo = { + [TAG_PLAYERNAME] = player:getName(), + [TAG_ITEMCOUNT] = amount, + [TAG_TOTALCOST] = amount * shopItem.sell, + [TAG_ITEMNAME] = shopItem.name + } + + if not isItemFluidContainer(itemid) then + subType = -1 + elseif subType == 0 then + subType = -1 + end + + if player:removeItem(itemid, amount, subType, ignoreEquipped) then + local msg = self.npcHandler:getMessage(MESSAGE_SOLD) + msg = self.npcHandler:parseMessage(msg, parseInfo) + player:sendTextMessage(MESSAGE_TRADE, msg) + player:addMoney(amount * shopItem.sell) + self.npcHandler.talkStart[cid] = os.time() + return true + else + local msg = self.npcHandler:getMessage(MESSAGE_NEEDITEM) + msg = self.npcHandler:parseMessage(msg, parseInfo) + player:sendCancelMessage(msg) + self.npcHandler.talkStart[cid] = os.time() + return false + end + end + + -- Callback for requesting a trade window with the NPC. + function ShopModule.requestTrade(cid, message, keywords, parameters, node) + local module = parameters.module + if not module.npcHandler:isFocused(cid) then + return false + end + + if not module.npcHandler:onTradeRequest(cid) then + return false + end + + local itemWindow = {} + for i = 1, #module.npcHandler.shopItems do + itemWindow[#itemWindow + 1] = module.npcHandler.shopItems[i] + end + + if itemWindow[1] == nil then + local parseInfo = { [TAG_PLAYERNAME] = Player(cid):getName() } + local msg = module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_NOSHOP), parseInfo) + module.npcHandler:say(msg, cid) + return true + end + + local parseInfo = { [TAG_PLAYERNAME] = Player(cid):getName() } + local msg = module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_SENDTRADE), parseInfo) + openShopWindow(cid, itemWindow, + function(cid, itemid, subType, amount, ignoreCap, inBackpacks) module.npcHandler:onBuy(cid, itemid, subType, amount, ignoreCap, inBackpacks) end, + function(cid, itemid, subType, amount, ignoreCap, inBackpacks) module.npcHandler:onSell(cid, itemid, subType, amount, ignoreCap, inBackpacks) end) + module.npcHandler:say(msg, cid) + return true + end + + -- onConfirm keyword callback function. Sells/buys the actual item. + function ShopModule.onConfirm(cid, message, keywords, parameters, node) + local module = parameters.module + if not module.npcHandler:isFocused(cid) or shop_npcuid[cid] ~= getNpcCid() then + return false + end + shop_npcuid[cid] = 0 + + local parentParameters = node:getParent():getParameters() + local player = Player(cid) + local parseInfo = { + [TAG_PLAYERNAME] = player:getName(), + [TAG_ITEMCOUNT] = shop_amount[cid], + [TAG_TOTALCOST] = shop_cost[cid] * shop_amount[cid], + [TAG_ITEMNAME] = shop_rlname[cid] + } + + if shop_eventtype[cid] == SHOPMODULE_SELL_ITEM then + local ret = doPlayerSellItem(cid, shop_itemid[cid], shop_amount[cid], shop_cost[cid] * shop_amount[cid]) + if ret == true then + local msg = module.npcHandler:getMessage(MESSAGE_ONSELL) + msg = module.npcHandler:parseMessage(msg, parseInfo) + module.npcHandler:say(msg, cid) + else + local msg = module.npcHandler:getMessage(MESSAGE_MISSINGITEM) + msg = module.npcHandler:parseMessage(msg, parseInfo) + module.npcHandler:say(msg, cid) + end + elseif shop_eventtype[cid] == SHOPMODULE_BUY_ITEM then + local cost = shop_cost[cid] * shop_amount[cid] + if player:getMoney() + player:getBankBalance() < cost then + local msg = module.npcHandler:getMessage(MESSAGE_MISSINGMONEY) + msg = module.npcHandler:parseMessage(msg, parseInfo) + module.npcHandler:say(msg, cid) + return false + end + + local a, b = doNpcSellItem(cid, shop_itemid[cid], shop_amount[cid], shop_subtype[cid], false, false, ITEM_SHOPPING_BAG) + if a < shop_amount[cid] then + local msgId = MESSAGE_NEEDMORESPACE + if a == 0 then + msgId = MESSAGE_NEEDSPACE + end + + local msg = module.npcHandler:getMessage(msgId) + msg = module.npcHandler:parseMessage(msg, parseInfo) + module.npcHandler:say(msg, cid) + if a > 0 then + if not player:removeMoneyNpc(a * shop_cost[cid]) then + return false + end + if shop_itemid[cid] == ITEM_PARCEL then + doNpcSellItem(cid, ITEM_LABEL, shop_amount[cid], shop_subtype[cid], true, false, ITEM_SHOPPING_BAG) + end + return true + end + return false + else + local msg = module.npcHandler:getMessage(MESSAGE_ONBUY) + msg = module.npcHandler:parseMessage(msg, parseInfo) + module.npcHandler:say(msg, cid) + if not player:removeMoneyNpc(cost) then + return false + end + if shop_itemid[cid] == ITEM_PARCEL then + doNpcSellItem(cid, ITEM_LABEL, shop_amount[cid], shop_subtype[cid], true, false, ITEM_SHOPPING_BAG) + end + return true + end + elseif shop_eventtype[cid] == SHOPMODULE_BUY_ITEM_CONTAINER then + local ret = doPlayerBuyItemContainer(cid, shop_container[cid], shop_itemid[cid], shop_amount[cid], shop_cost[cid] * shop_amount[cid], shop_subtype[cid]) + if ret == true then + local msg = module.npcHandler:getMessage(MESSAGE_ONBUY) + msg = module.npcHandler:parseMessage(msg, parseInfo) + module.npcHandler:say(msg, cid) + else + local msg = module.npcHandler:getMessage(MESSAGE_MISSINGMONEY) + msg = module.npcHandler:parseMessage(msg, parseInfo) + module.npcHandler:say(msg, cid) + end + end + + module.npcHandler:resetNpc(cid) + return true + end + + -- onDecline keyword callback function. Generally called when the player sais "no" after wanting to buy an item. + function ShopModule.onDecline(cid, message, keywords, parameters, node) + local module = parameters.module + if not module.npcHandler:isFocused(cid) or shop_npcuid[cid] ~= getNpcCid() then + return false + end + shop_npcuid[cid] = 0 + + local parentParameters = node:getParent():getParameters() + local parseInfo = { + [TAG_PLAYERNAME] = Player(cid):getName(), + [TAG_ITEMCOUNT] = shop_amount[cid], + [TAG_TOTALCOST] = shop_cost[cid] * shop_amount[cid], + [TAG_ITEMNAME] = shop_rlname[cid] + } + + local msg = module.npcHandler:parseMessage(module.noText, parseInfo) + module.npcHandler:say(msg, cid) + module.npcHandler:resetNpc(cid) + return true + end + + -- tradeItem callback function. Makes the npc say the message defined by MESSAGE_BUY or MESSAGE_SELL + function ShopModule.tradeItem(cid, message, keywords, parameters, node) + local module = parameters.module + if not module.npcHandler:isFocused(cid) then + return false + end + + if not module.npcHandler:onTradeRequest(cid) then + return true + end + + local count = module:getCount(message) + module.amount = count + + shop_amount[cid] = module.amount + shop_cost[cid] = parameters.cost + shop_rlname[cid] = parameters.realName + shop_itemid[cid] = parameters.itemid + shop_container[cid] = parameters.container + shop_npcuid[cid] = getNpcCid() + shop_eventtype[cid] = parameters.eventType + shop_subtype[cid] = parameters.subType + + local parseInfo = { + [TAG_PLAYERNAME] = Player(cid):getName(), + [TAG_ITEMCOUNT] = shop_amount[cid], + [TAG_TOTALCOST] = shop_cost[cid] * shop_amount[cid], + [TAG_ITEMNAME] = shop_rlname[cid] + } + + if shop_eventtype[cid] == SHOPMODULE_SELL_ITEM then + local msg = module.npcHandler:getMessage(MESSAGE_SELL) + msg = module.npcHandler:parseMessage(msg, parseInfo) + module.npcHandler:say(msg, cid) + elseif shop_eventtype[cid] == SHOPMODULE_BUY_ITEM then + local msg = module.npcHandler:getMessage(MESSAGE_BUY) + msg = module.npcHandler:parseMessage(msg, parseInfo) + module.npcHandler:say(msg, cid) + elseif shop_eventtype[cid] == SHOPMODULE_BUY_ITEM_CONTAINER then + local msg = module.npcHandler:getMessage(MESSAGE_BUY) + msg = module.npcHandler:parseMessage(msg, parseInfo) + module.npcHandler:say(msg, cid) + end + return true + end +end diff --git a/data/npc/lib/npcsystem/npchandler.lua b/data/npc/lib/npcsystem/npchandler.lua new file mode 100644 index 00000000000..bb2f3e79043 --- /dev/null +++ b/data/npc/lib/npcsystem/npchandler.lua @@ -0,0 +1,663 @@ +-- Advanced NPC System by Jiddo + +if NpcHandler == nil then + local storage = Storage.NpcExhaustOnBuy + local duration = 1 + -- Constant talkdelay behaviors. + TALKDELAY_NONE = 0 -- No talkdelay. Npc will reply immedeatly. + TALKDELAY_ONTHINK = 1 -- Talkdelay handled through the onThink callback function. (Default) + TALKDELAY_EVENT = 2 -- Not yet implemented + + -- Currently applied talkdelay behavior. TALKDELAY_ONTHINK is default. + NPCHANDLER_TALKDELAY = TALKDELAY_ONTHINK + + -- Constant indexes for defining default messages. + MESSAGE_GREET = 1 -- When the player greets the npc. + MESSAGE_FAREWELL = 2 -- When the player unGreets the npc. + MESSAGE_BUY = 3 -- When the npc asks the player if he wants to buy something. + MESSAGE_ONBUY = 4 -- When the player successfully buys something via talk. + MESSAGE_BOUGHT = 5 -- When the player bought something through the shop window. + MESSAGE_SELL = 6 -- When the npc asks the player if he wants to sell something. + MESSAGE_ONSELL = 7 -- When the player successfully sells something via talk. + MESSAGE_SOLD = 8 -- When the player sold something through the shop window. + MESSAGE_MISSINGMONEY = 9 -- When the player does not have enough money. + MESSAGE_NEEDMONEY = 10 -- Same as above, used for shop window. + MESSAGE_MISSINGITEM = 11 -- When the player is trying to sell an item he does not have. + MESSAGE_NEEDITEM = 12 -- Same as above, used for shop window. + MESSAGE_NEEDSPACE = 13 -- When the player don't have any space to buy an item + MESSAGE_NEEDMORESPACE = 14 -- When the player has some space to buy an item, but not enough space + MESSAGE_IDLETIMEOUT = 15 -- When the player has been idle for longer then idleTime allows. + MESSAGE_WALKAWAY = 16 -- When the player walks out of the talkRadius of the npc. + MESSAGE_DECLINE = 17 -- When the player says no to something. + MESSAGE_SENDTRADE = 18 -- When the npc sends the trade window to the player + MESSAGE_NOSHOP = 19 -- When the npc's shop is requested but he doesn't have any + MESSAGE_ONCLOSESHOP = 20 -- When the player closes the npc's shop window + MESSAGE_ALREADYFOCUSED = 21 -- When the player already has the focus of this npc. + MESSAGE_WALKAWAY_MALE = 22 -- When a male player walks out of the talkRadius of the npc. + MESSAGE_WALKAWAY_FEMALE = 23 -- When a female player walks out of the talkRadius of the npc. + + -- Constant indexes for callback functions. These are also used for module callback ids. + CALLBACK_CREATURE_APPEAR = 1 + CALLBACK_CREATURE_DISAPPEAR = 2 + CALLBACK_CREATURE_SAY = 3 + CALLBACK_ONTHINK = 4 + CALLBACK_GREET = 5 + CALLBACK_FAREWELL = 6 + CALLBACK_MESSAGE_DEFAULT = 7 + CALLBACK_PLAYER_ENDTRADE = 8 + CALLBACK_PLAYER_CLOSECHANNEL = 9 + CALLBACK_ONBUY = 10 + CALLBACK_ONSELL = 11 + CALLBACK_ONADDFOCUS = 18 + CALLBACK_ONRELEASEFOCUS = 19 + CALLBACK_ONTRADEREQUEST = 20 + + -- Addidional module callback ids + CALLBACK_MODULE_INIT = 12 + CALLBACK_MODULE_RESET = 13 + + -- Constant strings defining the keywords to replace in the default messages. + TAG_PLAYERNAME = "|PLAYERNAME|" + TAG_ITEMCOUNT = "|ITEMCOUNT|" + TAG_TOTALCOST = "|TOTALCOST|" + TAG_ITEMNAME = "|ITEMNAME|" + TAG_TIME = "|TIME|" + TAG_BLESSCOST = "|BLESSCOST|" + TAG_PVPBLESSCOST = "|PVPBLESSCOST|" + TAG_TRAVELCOST = "|TRAVELCOST|" + + NpcHandler = { + keywordHandler = nil, + focuses = nil, + talkStart = nil, + idleTime = 120, + talkRadius = 3, + talkDelayTime = 1, -- Seconds to delay outgoing messages. + talkDelay = nil, + callbackFunctions = nil, + modules = nil, + shopItems = nil, -- They must be here since ShopModule uses 'static' functions + eventSay = nil, + eventDelayedSay = nil, + topic = nil, + messages = { + -- These are the default replies of all npcs. They can/should be changed individually for each npc. + -- Leave empty for no send message + [MESSAGE_GREET] = "Greetings, |PLAYERNAME|.", + [MESSAGE_FAREWELL] = "Good bye, |PLAYERNAME|.", + [MESSAGE_BUY] = "Do you want to buy |ITEMCOUNT| |ITEMNAME| for |TOTALCOST| gold coins?", + [MESSAGE_ONBUY] = "Here you are.", + [MESSAGE_BOUGHT] = "Bought |ITEMCOUNT|x |ITEMNAME| for |TOTALCOST| gold.", + [MESSAGE_SELL] = "Do you want to sell |ITEMCOUNT| |ITEMNAME| for |TOTALCOST| gold coins?", + [MESSAGE_ONSELL] = "Here you are, |TOTALCOST| gold.", + [MESSAGE_SOLD] = "Sold |ITEMCOUNT|x |ITEMNAME| for |TOTALCOST| gold.", + [MESSAGE_MISSINGMONEY] = "You don't have enough money.", + [MESSAGE_NEEDMONEY] = "You don't have enough money.", + [MESSAGE_MISSINGITEM] = "You don't have so many.", + [MESSAGE_NEEDITEM] = "You do not have this object.", + [MESSAGE_NEEDSPACE] = "There is not enought room.", + [MESSAGE_NEEDMORESPACE] = "You do not have enough capacity for all items.", + [MESSAGE_IDLETIMEOUT] = "Good bye.", + [MESSAGE_WALKAWAY] = "", + [MESSAGE_DECLINE] = "Then not.", + [MESSAGE_SENDTRADE] = "Of course, just browse through my wares.", + [MESSAGE_NOSHOP] = "Sorry, I'm not offering anything.", + [MESSAGE_ONCLOSESHOP] = "Thank you, come back whenever you're in need of something else.", + [MESSAGE_ALREADYFOCUSED] = "|PLAYERNAME|, I am already talking to you.", + [MESSAGE_WALKAWAY_MALE] = "", + [MESSAGE_WALKAWAY_FEMALE] = "" + } + } + + -- Creates a new NpcHandler with an empty callbackFunction stack. + function NpcHandler:new(keywordHandler) + local obj = {} + obj.callbackFunctions = {} + obj.modules = {} + obj.eventSay = {} + obj.eventDelayedSay = {} + obj.topic = {} + obj.focuses = {} + obj.talkStart = {} + obj.talkDelay = {} + obj.keywordHandler = keywordHandler + obj.messages = {} + obj.shopItems = {} + + setmetatable(obj.messages, self.messages) + self.messages.__index = self.messages + + setmetatable(obj, self) + self.__index = self + return obj + end + + -- Re-defines the maximum idle time allowed for a player when talking to this npc. + function NpcHandler:setMaxIdleTime(newTime) + self.idleTime = newTime + end + + -- Attackes a new keyword handler to this npchandler + function NpcHandler:setKeywordHandler(newHandler) + self.keywordHandler = newHandler + end + + -- Function used to change the focus of this npc. + function NpcHandler:addFocus(newFocus) + if self:isFocused(newFocus) then + return + end + + self.focuses[#self.focuses + 1] = newFocus + self.topic[newFocus] = 0 + local callback = self:getCallback(CALLBACK_ONADDFOCUS) + if callback == nil or callback(newFocus) then + self:processModuleCallback(CALLBACK_ONADDFOCUS, newFocus) + end + self:updateFocus() + end + + -- Function used to verify if npc is focused to certain player + function NpcHandler:isFocused(focus) + for _, v in pairs(self.focuses) do + if v == focus then + return true + end + end + return false + end + + -- This function should be called on each onThink and makes sure the npc faces the player it is talking to. + -- Should also be called whenever a new player is focused. + function NpcHandler:updateFocus() + for _, focus in pairs(self.focuses) do + if focus ~= nil then + doNpcSetCreatureFocus(focus) + return + end + end + doNpcSetCreatureFocus(0) + end + + -- Used when the npc should un-focus the player. + function NpcHandler:releaseFocus(focus) + if shop_cost[focus] ~= nil then + shop_amount[focus] = nil + shop_cost[focus] = nil + shop_rlname[focus] = nil + shop_itemid[focus] = nil + shop_container[focus] = nil + shop_npcuid[focus] = nil + shop_eventtype[focus] = nil + shop_subtype[focus] = nil + shop_destination[focus] = nil + shop_premium[focus] = nil + end + + if self.eventDelayedSay[focus] then + self:cancelNPCTalk(self.eventDelayedSay[focus]) + end + + if not self:isFocused(focus) then + return + end + + local pos = nil + for k, v in pairs(self.focuses) do + if v == focus then + pos = k + end + end + + self.focuses[pos] = nil + + self.eventSay[focus] = nil + self.eventDelayedSay[focus] = nil + self.talkStart[focus] = nil + self.topic[focus] = nil + + local callback = self:getCallback(CALLBACK_ONRELEASEFOCUS) + if callback == nil or callback(focus) then + self:processModuleCallback(CALLBACK_ONRELEASEFOCUS, focus) + end + + if Player(focus) ~= nil then + closeShopWindow(focus) --Even if it can not exist, we need to prevent it. + self:updateFocus() + end + end + + -- Returns the callback function with the specified id or nil if no such callback function exists. + function NpcHandler:getCallback(id) + local ret = nil + if self.callbackFunctions ~= nil then + ret = self.callbackFunctions[id] + end + return ret + end + + -- Changes the callback function for the given id to callback. + function NpcHandler:setCallback(id, callback) + if self.callbackFunctions ~= nil then + self.callbackFunctions[id] = callback + end + end + + -- Adds a module to this npchandler and inits it. + function NpcHandler:addModule(module) + if self.modules ~= nil then + self.modules[#self.modules + 1] = module + module:init(self) + end + end + + -- Calls the callback function represented by id for all modules added to this npchandler with the given arguments. + function NpcHandler:processModuleCallback(id, ...) + local ret = true + for _, module in pairs(self.modules) do + local tmpRet = true + if id == CALLBACK_CREATURE_APPEAR and module.callbackOnCreatureAppear ~= nil then + tmpRet = module:callbackOnCreatureAppear(...) + elseif id == CALLBACK_CREATURE_DISAPPEAR and module.callbackOnCreatureDisappear ~= nil then + tmpRet = module:callbackOnCreatureDisappear(...) + elseif id == CALLBACK_CREATURE_SAY and module.callbackOnCreatureSay ~= nil then + tmpRet = module:callbackOnCreatureSay(...) + elseif id == CALLBACK_PLAYER_ENDTRADE and module.callbackOnPlayerEndTrade ~= nil then + tmpRet = module:callbackOnPlayerEndTrade(...) + elseif id == CALLBACK_PLAYER_CLOSECHANNEL and module.callbackOnPlayerCloseChannel ~= nil then + tmpRet = module:callbackOnPlayerCloseChannel(...) + elseif id == CALLBACK_ONBUY and module.callbackOnBuy ~= nil then + tmpRet = module:callbackOnBuy(...) + elseif id == CALLBACK_ONSELL and module.callbackOnSell ~= nil then + tmpRet = module:callbackOnSell(...) + elseif id == CALLBACK_ONTRADEREQUEST and module.callbackOnTradeRequest ~= nil then + tmpRet = module:callbackOnTradeRequest(...) + elseif id == CALLBACK_ONADDFOCUS and module.callbackOnAddFocus ~= nil then + tmpRet = module:callbackOnAddFocus(...) + elseif id == CALLBACK_ONRELEASEFOCUS and module.callbackOnReleaseFocus ~= nil then + tmpRet = module:callbackOnReleaseFocus(...) + elseif id == CALLBACK_ONTHINK and module.callbackOnThink ~= nil then + tmpRet = module:callbackOnThink(...) + elseif id == CALLBACK_GREET and module.callbackOnGreet ~= nil then + tmpRet = module:callbackOnGreet(...) + elseif id == CALLBACK_FAREWELL and module.callbackOnFarewell ~= nil then + tmpRet = module:callbackOnFarewell(...) + elseif id == CALLBACK_MESSAGE_DEFAULT and module.callbackOnMessageDefault ~= nil then + tmpRet = module:callbackOnMessageDefault(...) + elseif id == CALLBACK_MODULE_RESET and module.callbackOnModuleReset ~= nil then + tmpRet = module:callbackOnModuleReset(...) + end + if not tmpRet then + ret = false + break + end + end + return ret + end + + -- Returns the message represented by id. + function NpcHandler:getMessage(id) + local ret = nil + if self.messages ~= nil then + ret = self.messages[id] + end + return ret + end + + -- Changes the default response message with the specified id to newMessage. + function NpcHandler:setMessage(id, newMessage) + if self.messages ~= nil then + self.messages[id] = newMessage + end + end + + -- Translates all message tags found in msg using parseInfo + function NpcHandler:parseMessage(msg, parseInfo) + local ret = msg + if type(ret) == 'string' then + for search, replace in pairs(parseInfo) do + ret = string.gsub(ret, search, replace) + end + else + for i = 1, #ret do + for search, replace in pairs(parseInfo) do + ret[i] = string.gsub(ret[i], search, replace) + end + end + end + return ret + end + + -- Makes sure the npc un-focuses the currently focused player + function NpcHandler:unGreet(cid) + if not self:isFocused(cid) then + return + end + + local callback = self:getCallback(CALLBACK_FAREWELL) + if callback == nil or callback(cid) then + if self:processModuleCallback(CALLBACK_FAREWELL) then + local msg = self:getMessage(MESSAGE_FAREWELL) + local player = Player(cid) + local playerName = player and player:getName() or -1 + local parseInfo = { [TAG_PLAYERNAME] = playerName } + self:resetNpc(cid) + msg = self:parseMessage(msg, parseInfo) + self:say(msg, cid, true) + self:releaseFocus(cid) + end + end + end + + -- Greets a new player. + function NpcHandler:greet(cid, message) + if cid ~= 0 then + local callback = self:getCallback(CALLBACK_GREET) + if callback == nil or callback(cid, message) then + if self:processModuleCallback(CALLBACK_GREET, cid) then + local msg = self:getMessage(MESSAGE_GREET) + local player = Player(cid) + local playerName = player and player:getName() or -1 + local parseInfo = { [TAG_PLAYERNAME] = playerName } + msg = self:parseMessage(msg, parseInfo) + self:say(msg, cid, true) + else + return + end + else + return + end + end + self:addFocus(cid) + end + + -- Handles onCreatureAppear events. If you with to handle this yourself, please use the CALLBACK_CREATURE_APPEAR callback. + function NpcHandler:onCreatureAppear(creature) + local cid = creature.uid + if cid == getNpcCid() then + local npc = Npc() + if next(self.shopItems) then + local speechBubble = npc:getSpeechBubble() + if speechBubble == 3 then + npc:setSpeechBubble(4) + else + npc:setSpeechBubble(2) + end + else + if self:getMessage(MESSAGE_GREET) and npc:getSpeechBubble() < 1 then + npc:setSpeechBubble(1) + end + end + end + + local callback = self:getCallback(CALLBACK_CREATURE_APPEAR) + if callback == nil or callback(cid) then + if self:processModuleCallback(CALLBACK_CREATURE_APPEAR, cid) then + -- + end + end + end + + -- Handles onCreatureDisappear events. If you with to handle this yourself, please use the CALLBACK_CREATURE_DISAPPEAR callback. + function NpcHandler:onCreatureDisappear(creature) + local cid = creature.uid + if getNpcCid() == cid then + return + end + + local callback = self:getCallback(CALLBACK_CREATURE_DISAPPEAR) + if callback == nil or callback(cid) then + if self:processModuleCallback(CALLBACK_CREATURE_DISAPPEAR, cid) then + if self:isFocused(cid) then + self:unGreet(cid) + end + end + end + end + + -- Handles onCreatureSay events. If you with to handle this yourself, please use the CALLBACK_CREATURE_SAY callback. + function NpcHandler:onCreatureSay(creature, msgtype, msg) + local cid = creature.uid + local callback = self:getCallback(CALLBACK_CREATURE_SAY) + if callback == nil or callback(cid, msgtype, msg) then + if self:processModuleCallback(CALLBACK_CREATURE_SAY, cid, msgtype, msg) then + if not self:isInRange(cid) then + return + end + + if self.keywordHandler ~= nil then + if self:isFocused(cid) and msgtype == TALKTYPE_PRIVATE_PN or not self:isFocused(cid) then + local ret = self.keywordHandler:processMessage(cid, msg) + if not ret then + local callback = self:getCallback(CALLBACK_MESSAGE_DEFAULT) + if callback ~= nil and callback(cid, msgtype, msg) then + self.talkStart[cid] = os.time() + end + else + self.talkStart[cid] = os.time() + end + end + end + end + end + end + + -- Handles onPlayerEndTrade events. If you wish to handle this yourself, use the CALLBACK_PLAYER_ENDTRADE callback. + function NpcHandler:onPlayerEndTrade(creature) + local cid = creature.uid + local callback = self:getCallback(CALLBACK_PLAYER_ENDTRADE) + if callback == nil or callback(cid) then + if self:processModuleCallback(CALLBACK_PLAYER_ENDTRADE, cid, msgtype, msg) then + if self:isFocused(cid) then + local player = Player(cid) + local playerName = player and player:getName() or -1 + local parseInfo = { [TAG_PLAYERNAME] = playerName } + local msg = self:parseMessage(self:getMessage(MESSAGE_ONCLOSESHOP), parseInfo) + self:say(msg, cid) + end + end + end + end + + -- Handles onPlayerCloseChannel events. If you wish to handle this yourself, use the CALLBACK_PLAYER_CLOSECHANNEL callback. + function NpcHandler:onPlayerCloseChannel(creature) + local cid = creature.uid + local callback = self:getCallback(CALLBACK_PLAYER_CLOSECHANNEL) + if callback == nil or callback(cid) then + if self:processModuleCallback(CALLBACK_PLAYER_CLOSECHANNEL, cid, msgtype, msg) then + if self:isFocused(cid) then + self:unGreet(cid) + end + end + end + end + + -- Handles onBuy events. If you wish to handle this yourself, use the CALLBACK_ONBUY callback. + function NpcHandler:onBuy(creature, itemid, subType, amount, ignoreCap, inBackpacks) + local cid = creature.uid + if (os.time() - getPlayerStorageValue(cid, storage)) >= duration then + setPlayerStorageValue(cid, storage, os.time()) -- Delay for buy + local callback = self:getCallback(CALLBACK_ONBUY) + if callback == nil or callback(cid, itemid, subType, amount, ignoreCap, inBackpacks) then + if self:processModuleCallback(CALLBACK_ONBUY, cid, itemid, subType, amount, ignoreCap, inBackpacks) then + -- + end + end + else + return false + end + end + + -- Handles onSell events. If you wish to handle this yourself, use the CALLBACK_ONSELL callback. + function NpcHandler:onSell(creature, itemid, subType, amount, ignoreCap, inBackpacks) + local cid = creature.uid + local callback = self:getCallback(CALLBACK_ONSELL) + if callback == nil or callback(cid, itemid, subType, amount, ignoreCap, inBackpacks) then + if self:processModuleCallback(CALLBACK_ONSELL, cid, itemid, subType, amount, ignoreCap, inBackpacks) then + -- + end + end + end + + -- Handles onTradeRequest events. If you wish to handle this yourself, use the CALLBACK_ONTRADEREQUEST callback. + function NpcHandler:onTradeRequest(cid) + local callback = self:getCallback(CALLBACK_ONTRADEREQUEST) + if callback == nil or callback(cid) then + if self:processModuleCallback(CALLBACK_ONTRADEREQUEST, cid) then + return true + end + end + return false + end + + -- Handles onThink events. If you wish to handle this yourself, please use the CALLBACK_ONTHINK callback. + function NpcHandler:onThink() + local callback = self:getCallback(CALLBACK_ONTHINK) + if callback == nil or callback() then + if NPCHANDLER_TALKDELAY == TALKDELAY_ONTHINK then + for cid, talkDelay in pairs(self.talkDelay) do + if talkDelay.time ~= nil and talkDelay.message ~= nil and os.time() >= talkDelay.time then + selfSay(talkDelay.message, cid, talkDelay.publicize and true or false) + self.talkDelay[cid] = nil + end + end + end + + if self:processModuleCallback(CALLBACK_ONTHINK) then + for _, focus in pairs(self.focuses) do + if focus ~= nil then + if not self:isInRange(focus) then + self:onWalkAway(focus) + elseif self.talkStart[focus] ~= nil and (os.time() - self.talkStart[focus]) > self.idleTime then + self:unGreet(focus) + else + self:updateFocus() + end + end + end + end + end + end + + -- Tries to greet the player with the given cid. + function NpcHandler:onGreet(cid, message) + if self:isInRange(cid) then + if not self:isFocused(cid) then + self:greet(cid, message) + return + end + end + end + + -- Simply calls the underlying unGreet function. + function NpcHandler:onFarewell(cid) + self:unGreet(cid) + end + + -- Should be called on this npc's focus if the distance to focus is greater then talkRadius. + function NpcHandler:onWalkAway(cid) + if self:isFocused(cid) then + local callback = self:getCallback(CALLBACK_CREATURE_DISAPPEAR) + if callback == nil or callback() then + if self:processModuleCallback(CALLBACK_CREATURE_DISAPPEAR, cid) then + local msg = self:getMessage(MESSAGE_WALKAWAY) + local player = Player(cid) + local playerName = player and player:getName() or -1 + local playerSex = player and player:getSex() or 0 + + local parseInfo = { [TAG_PLAYERNAME] = playerName } + local message = self:parseMessage(msg, parseInfo) + + local msg_male = self:getMessage(MESSAGE_WALKAWAY_MALE) + local message_male = self:parseMessage(msg_male, parseInfo) + local msg_female = self:getMessage(MESSAGE_WALKAWAY_FEMALE) + local message_female = self:parseMessage(msg_female, parseInfo) + if message_female ~= message_male then + if playerSex == PLAYERSEX_FEMALE then + selfSay(message_female) + else + selfSay(message_male) + end + elseif message ~= "" then + selfSay(message) + end + self:resetNpc(cid) + self:releaseFocus(cid) + end + end + end + end + + -- Returns true if cid is within the talkRadius of this npc. + function NpcHandler:isInRange(cid) + local distance = Player(cid) ~= nil and getDistanceTo(cid) or -1 + if distance == -1 then + return false + end + + return distance <= self.talkRadius + end + + -- Resets the npc into its initial state (in regard of the keywordhandler). + -- All modules are also receiving a reset call through their callbackOnModuleReset function. + function NpcHandler:resetNpc(cid) + if self:processModuleCallback(CALLBACK_MODULE_RESET) then + self.keywordHandler:reset(cid) + end + end + + function NpcHandler:cancelNPCTalk(events) + for aux = 1, #events do + stopEvent(events[aux].event) + end + events = nil + end + + function NpcHandler:doNPCTalkALot(msgs, interval, pcid) + if self.eventDelayedSay[pcid] then + self:cancelNPCTalk(self.eventDelayedSay[pcid]) + end + + self.eventDelayedSay[pcid] = {} + local ret = {} + for aux = 1, #msgs do + self.eventDelayedSay[pcid][aux] = {} + doCreatureSayWithDelay(getNpcCid(), msgs[aux], TALKTYPE_PRIVATE_NP, ((aux-1) * (interval or 4000)) + 700, self.eventDelayedSay[pcid][aux], pcid) + ret[#ret + 1] = self.eventDelayedSay[pcid][aux] + end + return(ret) + end + + -- Makes the npc represented by this instance of NpcHandler say something. + -- This implements the currently set type of talkdelay. + -- shallDelay is a boolean value. If it is false, the message is not delayed. Default value is true. + function NpcHandler:say(message, focus, publicize, shallDelay, delay) + if type(message) == "table" then + return self:doNPCTalkALot(message, delay or 6000, focus) + end + + if self.eventDelayedSay[focus] then + self:cancelNPCTalk(self.eventDelayedSay[focus]) + end + + local shallDelay = not shallDelay and true or shallDelay + if NPCHANDLER_TALKDELAY == TALKDELAY_NONE or shallDelay == false then + selfSay(message, focus, publicize and true or false) + return + end + + stopEvent(self.eventSay[focus]) + self.eventSay[focus] = addEvent(function(npcId, message, focusId) + local npc = Npc(npcId) + if npc == nil then + return + end + + local player = Player(focusId) + if player then + local parseInfo = {[TAG_PLAYERNAME] = player:getName(), [TAG_TIME] = getFormattedWorldTime(), [TAG_BLESSCOST] = getBlessingsCost(player:getLevel()), [TAG_PVPBLESSCOST] = getPvpBlessingCost(player:getLevel())} + npc:say(self:parseMessage(message, parseInfo), TALKTYPE_PRIVATE_NP, false, player, npc:getPosition()) + end + end, self.talkDelayTime * 1000, Npc().uid, message, focus) + end +end diff --git a/data/npc/lib/npcsystem/npcsystem.lua b/data/npc/lib/npcsystem/npcsystem.lua new file mode 100644 index 00000000000..bb3239f1c75 --- /dev/null +++ b/data/npc/lib/npcsystem/npcsystem.lua @@ -0,0 +1,181 @@ +-- Advanced NPC System by Jiddo + +shop_amount = {} +shop_cost = {} +shop_rlname = {} +shop_itemid = {} +shop_container = {} +shop_npcuid = {} +shop_eventtype = {} +shop_subtype = {} +shop_destination = {} +shop_premium = {} + +npcs_loaded_shop = {} +npcs_loaded_travel = {} + +if NpcSystem == nil then + -- Loads the underlying classes of the npcsystem. + dofile('data/npc/lib/npcsystem/keywordhandler.lua') + dofile('data/npc/lib/npcsystem/npchandler.lua') + dofile('data/npc/lib/npcsystem/modules.lua') + + -- Global npc constants: + + -- Greeting and unGreeting keywords. For more information look at the top of modules.lua + FOCUS_GREETWORDS = {'hi', 'hello'} + FOCUS_FAREWELLWORDS = {'bye', 'farewell'} + + -- The word for requesting trade window. For more information look at the top of modules.lua + SHOP_TRADEREQUEST = {'trade'} + + -- The word for accepting/declining an offer. CAN ONLY CONTAIN ONE FIELD! For more information look at the top of modules.lua + SHOP_YESWORD = {'yes'} + SHOP_NOWORD = {'no'} + + -- Pattern used to get the amount of an item a player wants to buy/sell. + PATTERN_COUNT = '%d+' + + -- Talkdelay behavior. For more information, look at the top of npchandler.lua. + NPCHANDLER_TALKDELAY = TALKDELAY_ONTHINK + + -- Constant strings defining the keywords to replace in the default messages. + -- For more information, look at the top of npchandler.lua... + TAG_PLAYERNAME = '|PLAYERNAME|' + TAG_ITEMCOUNT = '|ITEMCOUNT|' + TAG_TOTALCOST = '|TOTALCOST|' + TAG_ITEMNAME = '|ITEMNAME|' + TAG_TIME = '|TIME|' + TAG_BLESSCOST = '|BLESSCOST|' + TAG_PVPBLESSCOST = '|PVPBLESSCOST|' + TAG_TRAVELCOST = '|TRAVELCOST|' + + NpcSystem = {} + + -- Gets an npcparameter with the specified key. Returns nil if no such parameter is found. + function NpcSystem.getParameter(key) + local ret = getNpcParameter(tostring(key)) + if (type(ret) == 'number' and ret == 0) or ret == nil then + return nil + else + return ret + end + end + + -- Parses all known parameters for the npc. Also parses parseable modules. + function NpcSystem.parseParameters(npcHandler) + local ret = NpcSystem.getParameter('idletime') + if ret ~= nil then + npcHandler.idleTime = tonumber(ret) + end + local ret = NpcSystem.getParameter('talkradius') + if ret ~= nil then + npcHandler.talkRadius = tonumber(ret) + end + local ret = NpcSystem.getParameter('message_greet') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_GREET, ret) + end + local ret = NpcSystem.getParameter('message_farewell') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_FAREWELL, ret) + end + local ret = NpcSystem.getParameter('message_decline') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_DECLINE, ret) + end + local ret = NpcSystem.getParameter('message_needmorespace') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_NEEDMORESPACE, ret) + end + local ret = NpcSystem.getParameter('message_needspace') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_NEEDSPACE, ret) + end + local ret = NpcSystem.getParameter('message_sendtrade') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_SENDTRADE, ret) + end + local ret = NpcSystem.getParameter('message_noshop') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_NOSHOP, ret) + end + local ret = NpcSystem.getParameter('message_oncloseshop') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_ONCLOSESHOP, ret) + end + local ret = NpcSystem.getParameter('message_onbuy') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_ONBUY, ret) + end + local ret = NpcSystem.getParameter('message_onsell') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_ONSELL, ret) + end + local ret = NpcSystem.getParameter('message_missingmoney') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_MISSINGMONEY, ret) + end + local ret = NpcSystem.getParameter('message_needmoney') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_NEEDMONEY, ret) + end + local ret = NpcSystem.getParameter('message_missingitem') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_MISSINGITEM, ret) + end + local ret = NpcSystem.getParameter('message_needitem') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_NEEDITEM, ret) + end + local ret = NpcSystem.getParameter('message_idletimeout') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_IDLETIMEOUT, ret) + end + local ret = NpcSystem.getParameter('message_walkaway') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_WALKAWAY, ret) + end + local ret = NpcSystem.getParameter('message_alreadyfocused') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_ALREADYFOCUSED, ret) + end + local ret = NpcSystem.getParameter('message_buy') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_BUY, ret) + end + local ret = NpcSystem.getParameter('message_sell') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_SELL, ret) + end + local ret = NpcSystem.getParameter('message_bought') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_BOUGHT, ret) + end + local ret = NpcSystem.getParameter('message_sold') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_SOLD, ret) + end + local ret = NpcSystem.getParameter('message_walkaway_male') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_WALKAWAY_MALE, ret) + end + local ret = NpcSystem.getParameter('message_walkaway_female') + if ret ~= nil then + npcHandler:setMessage(MESSAGE_WALKAWAY_FEMALE, ret) + end + + -- Parse modules. + for parameter, module in pairs(Modules.parseableModules) do + local ret = NpcSystem.getParameter(parameter) + if ret ~= nil then + local number = tonumber(ret) + if number ~= 0 and module.parseParameters ~= nil then + local instance = module:new() + npcHandler:addModule(instance) + instance:parseParameters() + end + end + end + end +end diff --git a/data/npc/lightfoot.xml b/data/npc/lightfoot.xml new file mode 100644 index 00000000000..5492f796be1 --- /dev/null +++ b/data/npc/lightfoot.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/lily.xml b/data/npc/lily.xml new file mode 100644 index 00000000000..b399a84c614 --- /dev/null +++ b/data/npc/lily.xml @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/data/npc/lisander.xml b/data/npc/lisander.xml new file mode 100644 index 00000000000..fe5da00c5cc --- /dev/null +++ b/data/npc/lisander.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/livielle.xml b/data/npc/livielle.xml new file mode 100644 index 00000000000..3b18f2ab9b9 --- /dev/null +++ b/data/npc/livielle.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + diff --git a/data/npc/lizard_tunnel_guard.xml b/data/npc/lizard_tunnel_guard.xml new file mode 100644 index 00000000000..dfa17420bc3 --- /dev/null +++ b/data/npc/lizard_tunnel_guard.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/llathriel.xml b/data/npc/llathriel.xml new file mode 100644 index 00000000000..b085bd91f6f --- /dev/null +++ b/data/npc/llathriel.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/lokur.xml b/data/npc/lokur.xml new file mode 100644 index 00000000000..9480d5173b8 --- /dev/null +++ b/data/npc/lokur.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/data/npc/lora.xml b/data/npc/lora.xml new file mode 100644 index 00000000000..10b6125b164 --- /dev/null +++ b/data/npc/lora.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/lorbas.xml b/data/npc/lorbas.xml new file mode 100644 index 00000000000..e806ae1909a --- /dev/null +++ b/data/npc/lorbas.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/data/npc/lorek.xml b/data/npc/lorek.xml new file mode 100644 index 00000000000..ed08e69105a --- /dev/null +++ b/data/npc/lorek.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/loria.xml b/data/npc/loria.xml new file mode 100644 index 00000000000..d8df21a0d42 --- /dev/null +++ b/data/npc/loria.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/lorietta.xml b/data/npc/lorietta.xml new file mode 100644 index 00000000000..8593e32817c --- /dev/null +++ b/data/npc/lorietta.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/lothar.xml b/data/npc/lothar.xml new file mode 100644 index 00000000000..fead54aba8d --- /dev/null +++ b/data/npc/lothar.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/lou_toose.xml b/data/npc/lou_toose.xml new file mode 100644 index 00000000000..5c16abb674f --- /dev/null +++ b/data/npc/lou_toose.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/loui.xml b/data/npc/loui.xml new file mode 100644 index 00000000000..857e925e287 --- /dev/null +++ b/data/npc/loui.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/lubo.xml b/data/npc/lubo.xml new file mode 100644 index 00000000000..500254ddbb2 --- /dev/null +++ b/data/npc/lubo.xml @@ -0,0 +1,41 @@ + + + + + + + + + + diff --git a/data/npc/lucius.xml b/data/npc/lucius.xml new file mode 100644 index 00000000000..fcef11de785 --- /dev/null +++ b/data/npc/lucius.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/lugri.xml b/data/npc/lugri.xml new file mode 100644 index 00000000000..f35fadb8b18 --- /dev/null +++ b/data/npc/lugri.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/lukosch.xml b/data/npc/lukosch.xml new file mode 100644 index 00000000000..fb984946ae2 --- /dev/null +++ b/data/npc/lukosch.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/luna.xml b/data/npc/luna.xml new file mode 100644 index 00000000000..0b362704416 --- /dev/null +++ b/data/npc/luna.xml @@ -0,0 +1,40 @@ + + + + + + + + + + diff --git a/data/npc/lunch.xml b/data/npc/lunch.xml new file mode 100644 index 00000000000..b1d3d258285 --- /dev/null +++ b/data/npc/lunch.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/data/npc/lungelen.xml b/data/npc/lungelen.xml new file mode 100644 index 00000000000..0028139f8e6 --- /dev/null +++ b/data/npc/lungelen.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/lurik.xml b/data/npc/lurik.xml new file mode 100644 index 00000000000..8aff05af73d --- /dev/null +++ b/data/npc/lurik.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/data/npc/lynda.xml b/data/npc/lynda.xml new file mode 100644 index 00000000000..39acb3e7057 --- /dev/null +++ b/data/npc/lynda.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/data/npc/lyonel.xml b/data/npc/lyonel.xml new file mode 100644 index 00000000000..65f2dfdb50c --- /dev/null +++ b/data/npc/lyonel.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/data/npc/maealil.xml b/data/npc/maealil.xml new file mode 100644 index 00000000000..df807084a9f --- /dev/null +++ b/data/npc/maealil.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/maelyrra.xml b/data/npc/maelyrra.xml new file mode 100644 index 00000000000..66229d326fa --- /dev/null +++ b/data/npc/maelyrra.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/maeryn.xml b/data/npc/maeryn.xml new file mode 100644 index 00000000000..f37688dfe08 --- /dev/null +++ b/data/npc/maeryn.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/malor.xml b/data/npc/malor.xml new file mode 100644 index 00000000000..e6f0909a039 --- /dev/null +++ b/data/npc/malor.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/malunga.xml b/data/npc/malunga.xml new file mode 100644 index 00000000000..dcf2dac6e95 --- /dev/null +++ b/data/npc/malunga.xml @@ -0,0 +1,82 @@ + + + + + + + + + diff --git a/data/npc/marcus.xml b/data/npc/marcus.xml new file mode 100644 index 00000000000..0f87f8abe0c --- /dev/null +++ b/data/npc/marcus.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/maria.xml b/data/npc/maria.xml new file mode 100644 index 00000000000..b94b1e9113a --- /dev/null +++ b/data/npc/maria.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + diff --git a/data/npc/marina.xml b/data/npc/marina.xml new file mode 100644 index 00000000000..c7d643be65c --- /dev/null +++ b/data/npc/marina.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/maris.xml b/data/npc/maris.xml new file mode 100644 index 00000000000..9a8069e0e47 --- /dev/null +++ b/data/npc/maris.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/maris_fenrock.xml b/data/npc/maris_fenrock.xml new file mode 100644 index 00000000000..3f11891fc3c --- /dev/null +++ b/data/npc/maris_fenrock.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/maris_mistrock.xml b/data/npc/maris_mistrock.xml new file mode 100644 index 00000000000..199276a0f5c --- /dev/null +++ b/data/npc/maris_mistrock.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/maritima.xml b/data/npc/maritima.xml new file mode 100644 index 00000000000..bec0c30dbe8 --- /dev/null +++ b/data/npc/maritima.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/markwin.xml b/data/npc/markwin.xml new file mode 100644 index 00000000000..37e4de85b38 --- /dev/null +++ b/data/npc/markwin.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/marlene.xml b/data/npc/marlene.xml new file mode 100644 index 00000000000..e09786740c6 --- /dev/null +++ b/data/npc/marlene.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/maro.xml b/data/npc/maro.xml new file mode 100644 index 00000000000..e67b9466285 --- /dev/null +++ b/data/npc/maro.xml @@ -0,0 +1,54 @@ + + + + + + + + + + diff --git a/data/npc/marvik.xml b/data/npc/marvik.xml new file mode 100644 index 00000000000..09c797c13d8 --- /dev/null +++ b/data/npc/marvik.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/marvin.xml b/data/npc/marvin.xml new file mode 100644 index 00000000000..44cd9885d93 --- /dev/null +++ b/data/npc/marvin.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/maryza.xml b/data/npc/maryza.xml new file mode 100644 index 00000000000..dbf33e72502 --- /dev/null +++ b/data/npc/maryza.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + diff --git a/data/npc/maun.xml b/data/npc/maun.xml new file mode 100644 index 00000000000..b7de732fe28 --- /dev/null +++ b/data/npc/maun.xml @@ -0,0 +1,96 @@ + + + + + + + + + + diff --git a/data/npc/mazarius.xml b/data/npc/mazarius.xml new file mode 100644 index 00000000000..284dd4737ef --- /dev/null +++ b/data/npc/mazarius.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/mehkesh.xml b/data/npc/mehkesh.xml new file mode 100644 index 00000000000..cf1918aa9bf --- /dev/null +++ b/data/npc/mehkesh.xml @@ -0,0 +1,26 @@ + + + + + + + + + + diff --git a/data/npc/melchior.xml b/data/npc/melchior.xml new file mode 100644 index 00000000000..93dbcdaf03e --- /dev/null +++ b/data/npc/melchior.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/melfar.xml b/data/npc/melfar.xml new file mode 100644 index 00000000000..20452282a27 --- /dev/null +++ b/data/npc/melfar.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/melian.xml b/data/npc/melian.xml new file mode 100644 index 00000000000..82fbe449ccf --- /dev/null +++ b/data/npc/melian.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/memech.xml b/data/npc/memech.xml new file mode 100644 index 00000000000..decfc8af134 --- /dev/null +++ b/data/npc/memech.xml @@ -0,0 +1,137 @@ + + + + + + + + + + diff --git a/data/npc/menacing_mummy.xml b/data/npc/menacing_mummy.xml new file mode 100644 index 00000000000..1a5e1dc586f --- /dev/null +++ b/data/npc/menacing_mummy.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/menesto.xml b/data/npc/menesto.xml new file mode 100644 index 00000000000..d0eb4cabbd4 --- /dev/null +++ b/data/npc/menesto.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/meraya.xml b/data/npc/meraya.xml new file mode 100644 index 00000000000..764233cc692 --- /dev/null +++ b/data/npc/meraya.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/messenger_of_heaven.xml b/data/npc/messenger_of_heaven.xml new file mode 100644 index 00000000000..1a0362b5aaa --- /dev/null +++ b/data/npc/messenger_of_heaven.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/messenger_of_santa.xml b/data/npc/messenger_of_santa.xml new file mode 100644 index 00000000000..53593a519d5 --- /dev/null +++ b/data/npc/messenger_of_santa.xml @@ -0,0 +1,21 @@ + + + + + + + + + diff --git a/data/npc/miles_the_guard.xml b/data/npc/miles_the_guard.xml new file mode 100644 index 00000000000..4cc54a2872f --- /dev/null +++ b/data/npc/miles_the_guard.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/milos.xml b/data/npc/milos.xml new file mode 100644 index 00000000000..0afa060a24a --- /dev/null +++ b/data/npc/milos.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/mirabell.xml b/data/npc/mirabell.xml new file mode 100644 index 00000000000..ec4d1ea7620 --- /dev/null +++ b/data/npc/mirabell.xml @@ -0,0 +1,17 @@ + + + + + + + + + diff --git a/data/npc/miraia.xml b/data/npc/miraia.xml new file mode 100644 index 00000000000..d91ffa22dfc --- /dev/null +++ b/data/npc/miraia.xml @@ -0,0 +1,18 @@ + + + + + + + + + + diff --git a/data/npc/moe.xml b/data/npc/moe.xml new file mode 100644 index 00000000000..3fab443fb89 --- /dev/null +++ b/data/npc/moe.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/morax.xml b/data/npc/morax.xml new file mode 100644 index 00000000000..6753acc7b06 --- /dev/null +++ b/data/npc/morax.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/mordecai.xml b/data/npc/mordecai.xml new file mode 100644 index 00000000000..3f1be001c3c --- /dev/null +++ b/data/npc/mordecai.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + diff --git a/data/npc/morgan.xml b/data/npc/morgan.xml new file mode 100644 index 00000000000..0175235cd3d --- /dev/null +++ b/data/npc/morgan.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/morpel.xml b/data/npc/morpel.xml new file mode 100644 index 00000000000..87ed6e37c5e --- /dev/null +++ b/data/npc/morpel.xml @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + diff --git a/data/npc/mortimer.xml b/data/npc/mortimer.xml new file mode 100644 index 00000000000..ef201b9cc07 --- /dev/null +++ b/data/npc/mortimer.xml @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/data/npc/mortis.xml b/data/npc/mortis.xml new file mode 100644 index 00000000000..f6e7ca3a6c8 --- /dev/null +++ b/data/npc/mortis.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/morun.xml b/data/npc/morun.xml new file mode 100644 index 00000000000..94f8f904c42 --- /dev/null +++ b/data/npc/morun.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/mother_of_jack.xml b/data/npc/mother_of_jack.xml new file mode 100644 index 00000000000..97de7943ce3 --- /dev/null +++ b/data/npc/mother_of_jack.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/mr._west.xml b/data/npc/mr._west.xml new file mode 100644 index 00000000000..99518da46ee --- /dev/null +++ b/data/npc/mr._west.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/mr_brandon.xml b/data/npc/mr_brandon.xml new file mode 100644 index 00000000000..1557c680999 --- /dev/null +++ b/data/npc/mr_brandon.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/mr_morris.xml b/data/npc/mr_morris.xml new file mode 100644 index 00000000000..6fc6d029d42 --- /dev/null +++ b/data/npc/mr_morris.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/mugluf.xml b/data/npc/mugluf.xml new file mode 100644 index 00000000000..1063e2c9af9 --- /dev/null +++ b/data/npc/mugluf.xml @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/data/npc/mugruu.xml b/data/npc/mugruu.xml new file mode 100644 index 00000000000..d16cc4ad943 --- /dev/null +++ b/data/npc/mugruu.xml @@ -0,0 +1,47 @@ + + + + + + + + + + diff --git a/data/npc/muhad.xml b/data/npc/muhad.xml new file mode 100644 index 00000000000..2562d6043bf --- /dev/null +++ b/data/npc/muhad.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/muriel.xml b/data/npc/muriel.xml new file mode 100644 index 00000000000..bd0ad056345 --- /dev/null +++ b/data/npc/muriel.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/murim.xml b/data/npc/murim.xml new file mode 100644 index 00000000000..f81a7921944 --- /dev/null +++ b/data/npc/murim.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/data/npc/muzir.xml b/data/npc/muzir.xml new file mode 100644 index 00000000000..f15fafd5f2e --- /dev/null +++ b/data/npc/muzir.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/myra.xml b/data/npc/myra.xml new file mode 100644 index 00000000000..ba50f500879 --- /dev/null +++ b/data/npc/myra.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/mysterious_ornate_chest.xml b/data/npc/mysterious_ornate_chest.xml new file mode 100644 index 00000000000..52fbcc6f30d --- /dev/null +++ b/data/npc/mysterious_ornate_chest.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/nah_bob.xml b/data/npc/nah_bob.xml new file mode 100644 index 00000000000..274a1fa675e --- /dev/null +++ b/data/npc/nah_bob.xml @@ -0,0 +1,42 @@ + + + + + + + + + + diff --git a/data/npc/naji.xml b/data/npc/naji.xml new file mode 100644 index 00000000000..c4ba6fb125b --- /dev/null +++ b/data/npc/naji.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/narsai.xml b/data/npc/narsai.xml new file mode 100644 index 00000000000..3d2d0a47495 --- /dev/null +++ b/data/npc/narsai.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/navigator.xml b/data/npc/navigator.xml new file mode 100644 index 00000000000..bdc88aeca70 --- /dev/null +++ b/data/npc/navigator.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/neill.xml b/data/npc/neill.xml new file mode 100644 index 00000000000..7f7df8905fb --- /dev/null +++ b/data/npc/neill.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/nelliem.xml b/data/npc/nelliem.xml new file mode 100644 index 00000000000..c82b8596c76 --- /dev/null +++ b/data/npc/nelliem.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + diff --git a/data/npc/nelly.xml b/data/npc/nelly.xml new file mode 100644 index 00000000000..d8cb700c4c4 --- /dev/null +++ b/data/npc/nelly.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + diff --git a/data/npc/nemal.xml b/data/npc/nemal.xml new file mode 100644 index 00000000000..fd2040308d1 --- /dev/null +++ b/data/npc/nemal.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/nezil.xml b/data/npc/nezil.xml new file mode 100644 index 00000000000..1a25e786b44 --- /dev/null +++ b/data/npc/nezil.xml @@ -0,0 +1,47 @@ + + + + + + + + + + diff --git a/data/npc/nibble.xml b/data/npc/nibble.xml new file mode 100644 index 00000000000..1b67eaa982b --- /dev/null +++ b/data/npc/nibble.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/nicholas.xml b/data/npc/nicholas.xml new file mode 100644 index 00000000000..ef0a2708e71 --- /dev/null +++ b/data/npc/nicholas.xml @@ -0,0 +1,95 @@ + + + + + + + + + diff --git a/data/npc/nielson.xml b/data/npc/nielson.xml new file mode 100644 index 00000000000..b40a9a4c71a --- /dev/null +++ b/data/npc/nielson.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/nienna.xml b/data/npc/nienna.xml new file mode 100644 index 00000000000..9ef38b33c1b --- /dev/null +++ b/data/npc/nienna.xml @@ -0,0 +1,31 @@ + + + + + + + + + diff --git a/data/npc/nilsor.xml b/data/npc/nilsor.xml new file mode 100644 index 00000000000..8ccdf681ec2 --- /dev/null +++ b/data/npc/nilsor.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/nina.xml b/data/npc/nina.xml new file mode 100644 index 00000000000..7a7c1b24fa2 --- /dev/null +++ b/data/npc/nina.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ninev.xml b/data/npc/ninev.xml new file mode 100644 index 00000000000..a2570b753b3 --- /dev/null +++ b/data/npc/ninev.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ninos.xml b/data/npc/ninos.xml new file mode 100644 index 00000000000..a2d1701b883 --- /dev/null +++ b/data/npc/ninos.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + diff --git a/data/npc/nokmir.xml b/data/npc/nokmir.xml new file mode 100644 index 00000000000..745a49598f5 --- /dev/null +++ b/data/npc/nokmir.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/nomadnpc.xml b/data/npc/nomadnpc.xml new file mode 100644 index 00000000000..251f91e97bd --- /dev/null +++ b/data/npc/nomadnpc.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/noodles.xml b/data/npc/noodles.xml new file mode 100644 index 00000000000..58db52ea3b7 --- /dev/null +++ b/data/npc/noodles.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/noozer.xml b/data/npc/noozer.xml new file mode 100644 index 00000000000..a95518bdc6c --- /dev/null +++ b/data/npc/noozer.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/nor.xml b/data/npc/nor.xml new file mode 100644 index 00000000000..b1bc819bcb9 --- /dev/null +++ b/data/npc/nor.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/norbert.xml b/data/npc/norbert.xml new file mode 100644 index 00000000000..610a8b5c673 --- /dev/null +++ b/data/npc/norbert.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + diff --git a/data/npc/norf.xml b/data/npc/norf.xml new file mode 100644 index 00000000000..8f76d0bf7d3 --- /dev/null +++ b/data/npc/norf.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/norma.xml b/data/npc/norma.xml new file mode 100644 index 00000000000..6197fafe440 --- /dev/null +++ b/data/npc/norma.xml @@ -0,0 +1,17 @@ + + + + + + + + + diff --git a/data/npc/norman_the_foreman.xml b/data/npc/norman_the_foreman.xml new file mode 100644 index 00000000000..609a21170b8 --- /dev/null +++ b/data/npc/norman_the_foreman.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/normod.xml b/data/npc/normod.xml new file mode 100644 index 00000000000..d2519d78557 --- /dev/null +++ b/data/npc/normod.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/norris.xml b/data/npc/norris.xml new file mode 100644 index 00000000000..83a07aa0e1b --- /dev/null +++ b/data/npc/norris.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/nurik.xml b/data/npc/nurik.xml new file mode 100644 index 00000000000..d9932e3879c --- /dev/null +++ b/data/npc/nurik.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/nydala.xml b/data/npc/nydala.xml new file mode 100644 index 00000000000..64908ef0fc5 --- /dev/null +++ b/data/npc/nydala.xml @@ -0,0 +1,95 @@ + + + + + + + + + diff --git a/data/npc/nymph_challenging.xml b/data/npc/nymph_challenging.xml new file mode 100644 index 00000000000..bd06d8fea4f --- /dev/null +++ b/data/npc/nymph_challenging.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/oberon's_bile.xml b/data/npc/oberon's_bile.xml new file mode 100644 index 00000000000..06a38b6548e --- /dev/null +++ b/data/npc/oberon's_bile.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/oberon's_hate.xml b/data/npc/oberon's_hate.xml new file mode 100644 index 00000000000..02bda01ef85 --- /dev/null +++ b/data/npc/oberon's_hate.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/oberon's_ire.xml b/data/npc/oberon's_ire.xml new file mode 100644 index 00000000000..3536408a6f5 --- /dev/null +++ b/data/npc/oberon's_ire.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/oberon's_spite.xml b/data/npc/oberon's_spite.xml new file mode 100644 index 00000000000..bb2425cfda9 --- /dev/null +++ b/data/npc/oberon's_spite.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/obi.xml b/data/npc/obi.xml new file mode 100644 index 00000000000..e9c9b68a840 --- /dev/null +++ b/data/npc/obi.xml @@ -0,0 +1,35 @@ + + + + + + + + + + diff --git a/data/npc/oblivion.xml b/data/npc/oblivion.xml new file mode 100644 index 00000000000..7d2b3eb7539 --- /dev/null +++ b/data/npc/oblivion.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ocelus.xml b/data/npc/ocelus.xml new file mode 100644 index 00000000000..fda5ec0beeb --- /dev/null +++ b/data/npc/ocelus.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/odemara.xml b/data/npc/odemara.xml new file mode 100644 index 00000000000..ec257e99787 --- /dev/null +++ b/data/npc/odemara.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + diff --git a/data/npc/oiriz.xml b/data/npc/oiriz.xml new file mode 100644 index 00000000000..64a5e0e861b --- /dev/null +++ b/data/npc/oiriz.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + diff --git a/data/npc/old_adall.xml b/data/npc/old_adall.xml new file mode 100644 index 00000000000..82df2f6bbdd --- /dev/null +++ b/data/npc/old_adall.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/old_rock_boy.xml b/data/npc/old_rock_boy.xml new file mode 100644 index 00000000000..b1ef207eef8 --- /dev/null +++ b/data/npc/old_rock_boy.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/oldrak.xml b/data/npc/oldrak.xml new file mode 100644 index 00000000000..b7cbe81a0f4 --- /dev/null +++ b/data/npc/oldrak.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/oliver.xml b/data/npc/oliver.xml new file mode 100644 index 00000000000..499ec2e10b9 --- /dev/null +++ b/data/npc/oliver.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/olrik.xml b/data/npc/olrik.xml new file mode 100644 index 00000000000..171aafb65ce --- /dev/null +++ b/data/npc/olrik.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/data/npc/omrabas.xml b/data/npc/omrabas.xml new file mode 100644 index 00000000000..2b88b103073 --- /dev/null +++ b/data/npc/omrabas.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/omur.xml b/data/npc/omur.xml new file mode 100644 index 00000000000..471019c0af6 --- /dev/null +++ b/data/npc/omur.xml @@ -0,0 +1,17 @@ + + + + + + + + + diff --git a/data/npc/one_eyed_joe.xml b/data/npc/one_eyed_joe.xml new file mode 100644 index 00000000000..9ae78354518 --- /dev/null +++ b/data/npc/one_eyed_joe.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ongulf.xml b/data/npc/ongulf.xml new file mode 100644 index 00000000000..2ebe47b9a85 --- /dev/null +++ b/data/npc/ongulf.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/orc_berserker_npc.xml b/data/npc/orc_berserker_npc.xml new file mode 100644 index 00000000000..bff4bc21c67 --- /dev/null +++ b/data/npc/orc_berserker_npc.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/oressa.xml b/data/npc/oressa.xml new file mode 100644 index 00000000000..0eec508bd3b --- /dev/null +++ b/data/npc/oressa.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ormuhn.xml b/data/npc/ormuhn.xml new file mode 100644 index 00000000000..2738469be5c --- /dev/null +++ b/data/npc/ormuhn.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/orockle.xml b/data/npc/orockle.xml new file mode 100644 index 00000000000..62bfc597a7e --- /dev/null +++ b/data/npc/orockle.xml @@ -0,0 +1,15 @@ + + + + + + + + + diff --git a/data/npc/ortheus.xml b/data/npc/ortheus.xml new file mode 100644 index 00000000000..2b13417c885 --- /dev/null +++ b/data/npc/ortheus.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/oswald.xml b/data/npc/oswald.xml new file mode 100644 index 00000000000..b622dc0791b --- /dev/null +++ b/data/npc/oswald.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ottokar.xml b/data/npc/ottokar.xml new file mode 100644 index 00000000000..34478a666b7 --- /dev/null +++ b/data/npc/ottokar.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/data/npc/padreia.xml b/data/npc/padreia.xml new file mode 100644 index 00000000000..d6ecca40833 --- /dev/null +++ b/data/npc/padreia.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/paladin_narai.xml b/data/npc/paladin_narai.xml new file mode 100644 index 00000000000..bd553877ae3 --- /dev/null +++ b/data/npc/paladin_narai.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/palimuth.xml b/data/npc/palimuth.xml new file mode 100644 index 00000000000..37cb04c21e8 --- /dev/null +++ b/data/npc/palimuth.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/palomino.xml b/data/npc/palomino.xml new file mode 100644 index 00000000000..664f2b42f87 --- /dev/null +++ b/data/npc/palomino.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/paolo.xml b/data/npc/paolo.xml new file mode 100644 index 00000000000..717473a714f --- /dev/null +++ b/data/npc/paolo.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/parlan.xml b/data/npc/parlan.xml new file mode 100644 index 00000000000..dbf42696bdb --- /dev/null +++ b/data/npc/parlan.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/partos.xml b/data/npc/partos.xml new file mode 100644 index 00000000000..6c11a51bf08 --- /dev/null +++ b/data/npc/partos.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/pat_the_worker.xml b/data/npc/pat_the_worker.xml new file mode 100644 index 00000000000..7ad0849e9ec --- /dev/null +++ b/data/npc/pat_the_worker.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/paulie.xml b/data/npc/paulie.xml new file mode 100644 index 00000000000..6e9e8019377 --- /dev/null +++ b/data/npc/paulie.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/peaceful_pooka.xml b/data/npc/peaceful_pooka.xml new file mode 100644 index 00000000000..061da2e0574 --- /dev/null +++ b/data/npc/peaceful_pooka.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/peggy.xml b/data/npc/peggy.xml new file mode 100644 index 00000000000..4ee0da1a797 --- /dev/null +++ b/data/npc/peggy.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + diff --git a/data/npc/pemaret.xml b/data/npc/pemaret.xml new file mode 100644 index 00000000000..b639c38ac69 --- /dev/null +++ b/data/npc/pemaret.xml @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/data/npc/penny.xml b/data/npc/penny.xml new file mode 100644 index 00000000000..ed5dacc9b85 --- /dev/null +++ b/data/npc/penny.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/data/npc/perac.xml b/data/npc/perac.xml new file mode 100644 index 00000000000..52696c1924b --- /dev/null +++ b/data/npc/perac.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + diff --git a/data/npc/percy_silverhand.xml b/data/npc/percy_silverhand.xml new file mode 100644 index 00000000000..745eeb5ec09 --- /dev/null +++ b/data/npc/percy_silverhand.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/percybald.xml b/data/npc/percybald.xml new file mode 100644 index 00000000000..967610d4750 --- /dev/null +++ b/data/npc/percybald.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/peremin.xml b/data/npc/peremin.xml new file mode 100644 index 00000000000..922abded313 --- /dev/null +++ b/data/npc/peremin.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/perod.xml b/data/npc/perod.xml new file mode 100644 index 00000000000..f474905dd9a --- /dev/null +++ b/data/npc/perod.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + diff --git a/data/npc/peter.xml b/data/npc/peter.xml new file mode 100644 index 00000000000..f487589ea73 --- /dev/null +++ b/data/npc/peter.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/petros.xml b/data/npc/petros.xml new file mode 100644 index 00000000000..f623ea76ad0 --- /dev/null +++ b/data/npc/petros.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/phillip.xml b/data/npc/phillip.xml new file mode 100644 index 00000000000..5a2c6005a90 --- /dev/null +++ b/data/npc/phillip.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/pig_npc.xml b/data/npc/pig_npc.xml new file mode 100644 index 00000000000..986e00cdb12 --- /dev/null +++ b/data/npc/pig_npc.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/pino.xml b/data/npc/pino.xml new file mode 100644 index 00000000000..b20c34ce888 --- /dev/null +++ b/data/npc/pino.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/plunderpurse.xml b/data/npc/plunderpurse.xml new file mode 100644 index 00000000000..0a9b91e2455 --- /dev/null +++ b/data/npc/plunderpurse.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/polly.xml b/data/npc/polly.xml new file mode 100644 index 00000000000..7adc23ce3c3 --- /dev/null +++ b/data/npc/polly.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/pompan.xml b/data/npc/pompan.xml new file mode 100644 index 00000000000..4bf9765dd56 --- /dev/null +++ b/data/npc/pompan.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/prezil.xml b/data/npc/prezil.xml new file mode 100644 index 00000000000..d81ecaf4570 --- /dev/null +++ b/data/npc/prezil.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/prisoner.xml b/data/npc/prisoner.xml new file mode 100644 index 00000000000..977aeb9d929 --- /dev/null +++ b/data/npc/prisoner.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/puffels.xml b/data/npc/puffels.xml new file mode 100644 index 00000000000..aca86810ee7 --- /dev/null +++ b/data/npc/puffels.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/pugwah.xml b/data/npc/pugwah.xml new file mode 100644 index 00000000000..908b73b7be5 --- /dev/null +++ b/data/npc/pugwah.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + diff --git a/data/npc/pukosch.xml b/data/npc/pukosch.xml new file mode 100644 index 00000000000..9975f89ac13 --- /dev/null +++ b/data/npc/pukosch.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/pydar.xml b/data/npc/pydar.xml new file mode 100644 index 00000000000..5f0e03fab60 --- /dev/null +++ b/data/npc/pydar.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/pyro_peter.xml b/data/npc/pyro_peter.xml new file mode 100644 index 00000000000..08179677f12 --- /dev/null +++ b/data/npc/pyro_peter.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/pyromental.xml b/data/npc/pyromental.xml new file mode 100644 index 00000000000..ba6e4201fc4 --- /dev/null +++ b/data/npc/pyromental.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/pythius_the_rottennpc.xml b/data/npc/pythius_the_rottennpc.xml new file mode 100644 index 00000000000..2073690ddfc --- /dev/null +++ b/data/npc/pythius_the_rottennpc.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/data/npc/quandons_ghost.xml b/data/npc/quandons_ghost.xml new file mode 100644 index 00000000000..b6d5126eb1e --- /dev/null +++ b/data/npc/quandons_ghost.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/queen_eloise.xml b/data/npc/queen_eloise.xml new file mode 100644 index 00000000000..84464a9be19 --- /dev/null +++ b/data/npc/queen_eloise.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/quentin.xml b/data/npc/quentin.xml new file mode 100644 index 00000000000..be00b4788df --- /dev/null +++ b/data/npc/quentin.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/quero.xml b/data/npc/quero.xml new file mode 100644 index 00000000000..07fe6df7fa2 --- /dev/null +++ b/data/npc/quero.xml @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/data/npc/rabaz.xml b/data/npc/rabaz.xml new file mode 100644 index 00000000000..8a97177e41c --- /dev/null +++ b/data/npc/rabaz.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + diff --git a/data/npc/rachel.xml b/data/npc/rachel.xml new file mode 100644 index 00000000000..ff620196f5d --- /dev/null +++ b/data/npc/rachel.xml @@ -0,0 +1,60 @@ + + + + + + + + + + diff --git a/data/npc/raffael.xml b/data/npc/raffael.xml new file mode 100644 index 00000000000..3be7e626d4d --- /dev/null +++ b/data/npc/raffael.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/rafzan.xml b/data/npc/rafzan.xml new file mode 100644 index 00000000000..a12181d1b7b --- /dev/null +++ b/data/npc/rafzan.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + diff --git a/data/npc/rahkem.xml b/data/npc/rahkem.xml new file mode 100644 index 00000000000..0eca4e6efb3 --- /dev/null +++ b/data/npc/rahkem.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ramina.xml b/data/npc/ramina.xml new file mode 100644 index 00000000000..1ab0aab4ce9 --- /dev/null +++ b/data/npc/ramina.xml @@ -0,0 +1,23 @@ + + + + + + + + + + diff --git a/data/npc/rapanaio.xml b/data/npc/rapanaio.xml new file mode 100644 index 00000000000..d93b5e984cc --- /dev/null +++ b/data/npc/rapanaio.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/rapanaioboat.xml b/data/npc/rapanaioboat.xml new file mode 100644 index 00000000000..87dc6c6520d --- /dev/null +++ b/data/npc/rapanaioboat.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/rapanaioisleofevil.xml b/data/npc/rapanaioisleofevil.xml new file mode 100644 index 00000000000..efa3ab5cbdd --- /dev/null +++ b/data/npc/rapanaioisleofevil.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/rashid.xml b/data/npc/rashid.xml new file mode 100644 index 00000000000..1dc3fec271c --- /dev/null +++ b/data/npc/rashid.xml @@ -0,0 +1,166 @@ + + + + + + + + + diff --git a/data/npc/rashid_custom.xml b/data/npc/rashid_custom.xml new file mode 100644 index 00000000000..5c2ea1f06f5 --- /dev/null +++ b/data/npc/rashid_custom.xml @@ -0,0 +1,166 @@ + + + + + + + + + diff --git a/data/npc/rata_mari.xml b/data/npc/rata_mari.xml new file mode 100644 index 00000000000..4077c357f28 --- /dev/null +++ b/data/npc/rata_mari.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ray.xml b/data/npc/ray.xml new file mode 100644 index 00000000000..aec70abd3f7 --- /dev/null +++ b/data/npc/ray.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + diff --git a/data/npc/raymond_striker.xml b/data/npc/raymond_striker.xml new file mode 100644 index 00000000000..04ab601c006 --- /dev/null +++ b/data/npc/raymond_striker.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/razan.xml b/data/npc/razan.xml new file mode 100644 index 00000000000..a9d9261c95c --- /dev/null +++ b/data/npc/razan.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/rebel.xml b/data/npc/rebel.xml new file mode 100644 index 00000000000..ab4c34449bd --- /dev/null +++ b/data/npc/rebel.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/red_lilly.xml b/data/npc/red_lilly.xml new file mode 100644 index 00000000000..b5c844ea81b --- /dev/null +++ b/data/npc/red_lilly.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/data/npc/redward.xml b/data/npc/redward.xml new file mode 100644 index 00000000000..876ea233572 --- /dev/null +++ b/data/npc/redward.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + diff --git a/data/npc/reed.xml b/data/npc/reed.xml new file mode 100644 index 00000000000..b916d0f65e6 --- /dev/null +++ b/data/npc/reed.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/rehon.xml b/data/npc/rehon.xml new file mode 100644 index 00000000000..689fd48dd47 --- /dev/null +++ b/data/npc/rehon.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/repenter.xml b/data/npc/repenter.xml new file mode 100644 index 00000000000..f0ecee40ac8 --- /dev/null +++ b/data/npc/repenter.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/richard.xml b/data/npc/richard.xml new file mode 100644 index 00000000000..b94b310a2fa --- /dev/null +++ b/data/npc/richard.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/riddler.xml b/data/npc/riddler.xml new file mode 100644 index 00000000000..dd4db24638f --- /dev/null +++ b/data/npc/riddler.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/robert.xml b/data/npc/robert.xml new file mode 100644 index 00000000000..f2556f62f01 --- /dev/null +++ b/data/npc/robert.xml @@ -0,0 +1,165 @@ + + + + + + + + + + diff --git a/data/npc/robin.xml b/data/npc/robin.xml new file mode 100644 index 00000000000..eddd4eb51e9 --- /dev/null +++ b/data/npc/robin.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/robson.xml b/data/npc/robson.xml new file mode 100644 index 00000000000..244cece6802 --- /dev/null +++ b/data/npc/robson.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/rock_in_a_hard_place.xml b/data/npc/rock_in_a_hard_place.xml new file mode 100644 index 00000000000..d288d657ba6 --- /dev/null +++ b/data/npc/rock_in_a_hard_place.xml @@ -0,0 +1,278 @@ + + + + + + + + + + + + + diff --git a/data/npc/rock_steady.xml b/data/npc/rock_steady.xml new file mode 100644 index 00000000000..758c3e128cf --- /dev/null +++ b/data/npc/rock_steady.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/rock_with_a_soft_spot.xml b/data/npc/rock_with_a_soft_spot.xml new file mode 100644 index 00000000000..c146ae052d8 --- /dev/null +++ b/data/npc/rock_with_a_soft_spot.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/roderick.xml b/data/npc/roderick.xml new file mode 100644 index 00000000000..aae2977f2e9 --- /dev/null +++ b/data/npc/roderick.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/rodney.xml b/data/npc/rodney.xml new file mode 100644 index 00000000000..64d28c9917a --- /dev/null +++ b/data/npc/rodney.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + diff --git a/data/npc/roger_the_worker.xml b/data/npc/roger_the_worker.xml new file mode 100644 index 00000000000..4bfcb58c8d9 --- /dev/null +++ b/data/npc/roger_the_worker.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/rokyn.xml b/data/npc/rokyn.xml new file mode 100644 index 00000000000..dfa4e0823b4 --- /dev/null +++ b/data/npc/rokyn.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/romella.xml b/data/npc/romella.xml new file mode 100644 index 00000000000..f84a21bdafb --- /dev/null +++ b/data/npc/romella.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + diff --git a/data/npc/romir.xml b/data/npc/romir.xml new file mode 100644 index 00000000000..6fb0b0a7ef5 --- /dev/null +++ b/data/npc/romir.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + diff --git a/data/npc/rose.xml b/data/npc/rose.xml new file mode 100644 index 00000000000..2d88c3a1e59 --- /dev/null +++ b/data/npc/rose.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + diff --git a/data/npc/rosemarie.xml b/data/npc/rosemarie.xml new file mode 100644 index 00000000000..dda0776989e --- /dev/null +++ b/data/npc/rosemarie.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ross.xml b/data/npc/ross.xml new file mode 100644 index 00000000000..592c5557d63 --- /dev/null +++ b/data/npc/ross.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/roswitha.xml b/data/npc/roswitha.xml new file mode 100644 index 00000000000..32cc3f6cc11 --- /dev/null +++ b/data/npc/roswitha.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/rotem_valos.xml b/data/npc/rotem_valos.xml new file mode 100644 index 00000000000..0b9be26187c --- /dev/null +++ b/data/npc/rotem_valos.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/rottin_wood.xml b/data/npc/rottin_wood.xml new file mode 100644 index 00000000000..334f84a6f50 --- /dev/null +++ b/data/npc/rottin_wood.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/roughington.xml b/data/npc/roughington.xml new file mode 100644 index 00000000000..8c64b4c1e92 --- /dev/null +++ b/data/npc/roughington.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/rowenna.xml b/data/npc/rowenna.xml new file mode 100644 index 00000000000..7c967396c36 --- /dev/null +++ b/data/npc/rowenna.xml @@ -0,0 +1,74 @@ + + + + + + + + + + diff --git a/data/npc/rudolph.xml b/data/npc/rudolph.xml new file mode 100644 index 00000000000..6377b131204 --- /dev/null +++ b/data/npc/rudolph.xml @@ -0,0 +1,19 @@ + + + + + + + + + + diff --git a/data/npc/runtel_blackspark.xml b/data/npc/runtel_blackspark.xml new file mode 100644 index 00000000000..dae837c3565 --- /dev/null +++ b/data/npc/runtel_blackspark.xml @@ -0,0 +1,54 @@ + + + + + + + + + diff --git a/data/npc/ruprecht.xml b/data/npc/ruprecht.xml new file mode 100644 index 00000000000..7959a4069b8 --- /dev/null +++ b/data/npc/ruprecht.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/saideh.xml b/data/npc/saideh.xml new file mode 100644 index 00000000000..95e2324891d --- /dev/null +++ b/data/npc/saideh.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/salbra.xml b/data/npc/salbra.xml new file mode 100644 index 00000000000..e72e6045f4f --- /dev/null +++ b/data/npc/salbra.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/sam.xml b/data/npc/sam.xml new file mode 100644 index 00000000000..68ef8c75058 --- /dev/null +++ b/data/npc/sam.xml @@ -0,0 +1,136 @@ + + + + + + + + + + diff --git a/data/npc/samir.xml b/data/npc/samir.xml new file mode 100644 index 00000000000..7e1f0bd625e --- /dev/null +++ b/data/npc/samir.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/sandomo.xml b/data/npc/sandomo.xml new file mode 100644 index 00000000000..c8f8fd2342d --- /dev/null +++ b/data/npc/sandomo.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/sandra.xml b/data/npc/sandra.xml new file mode 100644 index 00000000000..b8ac185407e --- /dev/null +++ b/data/npc/sandra.xml @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/data/npc/sane_mage.xml b/data/npc/sane_mage.xml new file mode 100644 index 00000000000..967246686cb --- /dev/null +++ b/data/npc/sane_mage.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/santa_claus.xml b/data/npc/santa_claus.xml new file mode 100644 index 00000000000..0f03ff53ab1 --- /dev/null +++ b/data/npc/santa_claus.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/santiago.xml b/data/npc/santiago.xml new file mode 100644 index 00000000000..00bf3a4532c --- /dev/null +++ b/data/npc/santiago.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/sarina.xml b/data/npc/sarina.xml new file mode 100644 index 00000000000..ffd8aeba916 --- /dev/null +++ b/data/npc/sarina.xml @@ -0,0 +1,48 @@ + + + + + + + + + + diff --git a/data/npc/satsu.xml b/data/npc/satsu.xml new file mode 100644 index 00000000000..e8f70ee2400 --- /dev/null +++ b/data/npc/satsu.xml @@ -0,0 +1,19 @@ + + + + + + + + + + diff --git a/data/npc/scott.xml b/data/npc/scott.xml new file mode 100644 index 00000000000..6901bddc378 --- /dev/null +++ b/data/npc/scott.xml @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/data/npc/scott_the_scout.xml b/data/npc/scott_the_scout.xml new file mode 100644 index 00000000000..230ccf46188 --- /dev/null +++ b/data/npc/scott_the_scout.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/scripts/....lua b/data/npc/scripts/....lua new file mode 100644 index 00000000000..6528e326950 --- /dev/null +++ b/data/npc/scripts/....lua @@ -0,0 +1,45 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.DesperateSoul) ~= 1 then + npcHandler:setMessage(MESSAGE_GREET, "Hello my friend, I saw that you send my soul here.") + return true + end + return false +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "mission") and player:getStorageValue(Storage.FerumbrasAscension.TarbazNotes) >= 2 then + npcHandler.topic[cid] = 1 + npcHandler:say("Oh, are you talking about {Tevon}?", cid) + elseif msgcontains(msg, "tevon") and npcHandler.topic[cid] == 1 then + npcHandler.topic[cid] = 0 + npcHandler:say("Ok, sure, now you may pass the door.", cid) + player:setStorageValue(Storage.FerumbrasAscension.TarbazDoor, 1) + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_bearded_woman.lua b/data/npc/scripts/a_bearded_woman.lua new file mode 100644 index 00000000000..f2ae66aa092 --- /dev/null +++ b/data/npc/scripts/a_bearded_woman.lua @@ -0,0 +1,103 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'I am a MAN! Get me out you drunken fools!' }, + { text = 'GET ME OUT OF HERE!' }, + { text = 'Get me out! It was all part of the plan, you fools!' }, + { text = 'If I ever get out of here, I\'ll kill you all! All of you!' }, + { text = 'I am NOT Princess Lumelia, you fools!' }, + { text = 'Get a locksmith and free me or you will regret it, you foolish pirates!' }, + { text = 'I am not a princess, I am an actor!' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am a great and famous actor! Not a princess, at all. I was only PRETENDING to be a princess. But try explaining that to those stupid pirates."}) +keywordHandler:addKeyword({'actor'}, StdModule.say, {npcHandler = npcHandler, text = "Stage acting was a waste of my immense talent. Not only am I a born leader, my talent is more profitable when it is used for conning people."}) +keywordHandler:addKeyword({'stage'}, StdModule.say, {npcHandler = npcHandler, text = "Stage acting was a waste of my immense talent. Not only am I a born leader, my talent is more profitable when it is used for conning people."}) +keywordHandler:addKeyword({'kid'}, StdModule.say, {npcHandler = npcHandler, text = "He was always a fool with a heart too soft to become a feared pirate."}) +keywordHandler:addKeyword({'princess'}, StdModule.say, {npcHandler = npcHandler, text = "Me playing a princess was just part of a cunning plan we had."}) +keywordHandler:addKeyword({'cell'}, StdModule.say, {npcHandler = npcHandler, text = "If you find some way to release me I might even let you live as reward! So you'd better do your best or I'll kill you!"}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "How dare you? I left to rot in this dirty cell and you have nothing better to do than chit chat?"}) +keywordHandler:addKeyword({'rot'}, StdModule.say, {npcHandler = npcHandler, text = "YOU .. YOU .. You are as good as dead! I will get you! Do you hear me? I will have your head! On a platter!"}) +keywordHandler:addKeyword({'pirate'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'In a just world, I would be captain of a grand ship, ...', + 'Those pirates out there would now be my minions, and we would brave the seas and become the terror of the coastal towns! ...', + 'If only our plan had worked!' + }} +) +keywordHandler:addKeyword({'ship'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'Captain Kid sold his ship to buy pointless things like those insanely expensive locks for the cell doors. ...', + 'He said the canoes would do for a while. ...', + 'I got the impression he was not overly sad to part with the ship because he was known to suffer a lot from seasickness.' + }} +) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'I\'d have been a much better captain then Kid was. I played several captains on stage and I was good! ...', + 'Where Kid longed for the appreciation of his men, I would rule by fear and with an iron fist!' + }} +) +keywordHandler:addKeyword({'plan'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'It was all captain Kid\'s idea. You see, he hated his name and planned to become known by the name captain Kidnap. ...', + 'All he needed was someone famous to kidnap. ...', + 'Given his men\'s dismal lack of talent and intelligence that would have been quite a feat. ...', + 'We knew each other from a few scams we did together in the past, so he contacted me. ...', + 'I was to impersonate the famous Princess Lumelia. You know, the one everyone was looking for. ...', + 'That would show his men and the other pirates what a great kidnapper he was. ...', + 'He promised me that I would become his second in command and lead a wonderful life of plundering, robbing and pillaging. ...', + 'So I agreed to impersonate the Princess for a while and it worked fine at first. ...', + 'He returned with me dressed as the Princess from a raid on his own and was instantaneously the hero of the day for his men. ...', + 'Things went bad when they decided to have a victory party. ...', + 'As far as I could make out from the mumblings of the pirates, Kid lost the key to my cell while relieving himself in the underground river. ...', + 'The fool decided to dive after it .. never to be seen again. ...', + 'When I found out about Kid\'s demise I tried to convince the pirates it was a hoax, but they just won\'t believe me!' + }} +) +keywordHandler:addKeyword({'kidnap'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'Ah kidnapping is so much fun. That is, if you\'re not on the receiving end. ...', + 'It\'s easy money and you have a chance to frighten and torture someone who can\'t fight back!' + }} +) +keywordHandler:addKeyword({'scams'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'The more stupid the people are, the easier it is to con them. ...', + 'And the poorer they are the less means they have to get revenge. Har Har! ...', + 'So I make sure I ruin those I scam. Then they have other things to worry about than getting revenge on me.' + }} +) +keywordHandler:addKeyword({'key'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'The key was lost in the underground river and has probably washed into the seven seas by now! ...', + 'If that stupid Kid hadn\'t been so obsessed with kidnapping he\'d not have sold his ship to buy the most expensive and complicated locks for his cells!' + }} +) +keywordHandler:addKeyword({'plundering'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'As long as we stick to undefended coastal towns we can make an easy fortune. Har Har! ...', + 'As soon as I get out of here I\'ll finally become a pirate captain on my own. I don\'t need Captain Kid!' + }} +) + +npcHandler:setMessage(MESSAGE_GREET, "GET ME OUT OF HERE! NOW!") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_beautiful_girl.lua b/data/npc/scripts/a_beautiful_girl.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/a_beautiful_girl.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_beggar.lua b/data/npc/scripts/a_beggar.lua new file mode 100644 index 00000000000..71f580e16df --- /dev/null +++ b/data/npc/scripts/a_beggar.lua @@ -0,0 +1,50 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "want") then + if player:getStorageValue(Storage.DarkTrails.Mission01) == 1 then + npcHandler:say("The guys from the magistrate sent you here, didn't they?", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "Thought so. You'll have to talk to the king though. The beggar king that is. The king does not grant an audience to just everyone. You know how those kings are, don't you? ... ", + "However, to get an audience with the king, you'll have to help his subjects a bit. ... ", + "His subjects that would be us, the poor, you know? ... ", + "So why don't you show your dedication to the poor? Go and help Chavis at the poor house. He's collecting food for people like us. ... ", + "If you brought enough of the stuff you'll see that the king will grant you entrance in his {palace}." + }, cid, false, true, 10) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.DarkTrails.Mission01, 2) -- Mission 1 end + player:setStorageValue(Storage.DarkTrails.Mission02, 1) -- Mission 2 start + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Hi! What is it, what d'ye {want}?") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_confused_frog.lua b/data/npc/scripts/a_confused_frog.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/a_confused_frog.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_dark_priestess.lua b/data/npc/scripts/a_dark_priestess.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/a_dark_priestess.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_dead_bureaucrat1.lua b/data/npc/scripts/a_dead_bureaucrat1.lua new file mode 100644 index 00000000000..7a195e7f5b2 --- /dev/null +++ b/data/npc/scripts/a_dead_bureaucrat1.lua @@ -0,0 +1,98 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Now where did I put that form?' }, + { text = 'Hail Pumin. Yes, hail.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local config = { + [VOCATION.CLIENT_ID.SORCERER] = "wand", + [VOCATION.CLIENT_ID.DRUID] = "rod", + [VOCATION.CLIENT_ID.PALADIN] = "bow", + [VOCATION.CLIENT_ID.KNIGHT] = "sword" +} + +local function greetCallback(cid) + npcHandler:setMessage(MESSAGE_GREET, "Hello " .. (Player(cid):getSex() == PLAYERSEX_FEMALE and "beautiful lady" or "handsome gentleman") .. ", welcome to the atrium of Pumin's Domain. We require some information from you before we can let you pass. Where do you want to go?") + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + local vocation = player:getVocation() + local vocationId = vocation:getId() + local vocationClientId = vocation:getClientId() + + if msgcontains(msg, "pumin") then + if npcHandler.topic[cid] == 0 and player:getStorageValue(Storage.PitsOfInferno.ThronePumin) < 1 then + npcHandler:say("Sure, where else. Everyone likes to meet my master, he is a great demon, isn't he? Your name is ...?", cid) + npcHandler.topic[cid] = 1 + elseif npcHandler.topic[cid] == 3 then + player:setStorageValue(Storage.PitsOfInferno.ThronePumin, 1) + npcHandler:say("How very interesting. I need to tell that to my master immediately. Please go to my colleagues and ask for Form 356. You will need it in order to proceed.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, player:getName()) then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Alright |PLAYERNAME|. Vocation?", cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, Vocation(vocationId):getName()) then + if npcHandler.topic[cid] == 2 then + npcHandler:say("Huhu, please don't hurt me with your " .. config[vocationClientId] .. "! Reason of your visit?", cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, "411") then + if player:getStorageValue(Storage.PitsOfInferno.ThronePumin) == 3 then + npcHandler:say("Form 411? You need Form 287 to get that! Do you have it?", cid) + npcHandler.topic[cid] = 4 + elseif player:getStorageValue(Storage.PitsOfInferno.ThronePumin) == 5 then + npcHandler:say("Form 411? You need Form 287 to get that! Do you have it?", cid) + npcHandler.topic[cid] = 5 + end + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] == 4 then + player:setStorageValue(Storage.PitsOfInferno.ThronePumin, 4) + npcHandler:say("Oh, what a pity. Go see one of my colleagues. I give you the permission to get Form 287. Bye!", cid) + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 5 then + player:setStorageValue(Storage.PitsOfInferno.ThronePumin, 6) + npcHandler:say("Great. Here you are. Form 411. Come back anytime you want to talk. Bye.", cid) + end + elseif msgcontains(msg, "356") then + if player:getStorageValue(Storage.PitsOfInferno.ThronePumin) == 8 then + player:setStorageValue(Storage.PitsOfInferno.ThronePumin, 9) + npcHandler:say("INCREDIBLE, you did it!! Have fun at Pumin's Domain!", cid) + end + end + return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye and don't forget me!") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye and don't forget me!") + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_dead_bureaucrat2.lua b/data/npc/scripts/a_dead_bureaucrat2.lua new file mode 100644 index 00000000000..bed984c2bb5 --- /dev/null +++ b/data/npc/scripts/a_dead_bureaucrat2.lua @@ -0,0 +1,50 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Now where did I put that form?' }, + { text = 'Hail Pumin. Yes, hail.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local function greetCallback(cid) + npcHandler:setMessage(MESSAGE_GREET, "Hello " .. (Player(cid):getSex() == PLAYERSEX_FEMALE and "beautiful lady" or "handsome gentleman") .. ", welcome to the atrium of Pumin's Domain. We require some information from you before we can let you pass. Where do you want to go?") + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, "287") then + local player = Player(cid) + if player:getStorageValue(Storage.PitsOfInferno.ThronePumin) == 4 then + player:setStorageValue(Storage.PitsOfInferno.ThronePumin, 5) + npcHandler:say("Sure, you can get it from me. Here you are. Bye", cid) + end + end + return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye and don't forget me!") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye and don't forget me!") + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_dead_bureaucrat3.lua b/data/npc/scripts/a_dead_bureaucrat3.lua new file mode 100644 index 00000000000..2acd9a32701 --- /dev/null +++ b/data/npc/scripts/a_dead_bureaucrat3.lua @@ -0,0 +1,71 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Now where did I put that form?' }, + { text = 'Hail Pumin. Yes, hail.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local function greetCallback(cid) + npcHandler:setMessage(MESSAGE_GREET, "Hello " .. (Player(cid):getSex() == PLAYERSEX_FEMALE and "beautiful lady" or "handsome gentleman") .. ", welcome to the atrium of Pumin's Domain. We require some information from you before we can let you pass. Where do you want to go?") + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + local vocation = Vocation(player:getVocation():getBase():getId()) + + if msgcontains(msg, "pumin") then + if player:getStorageValue(Storage.PitsOfInferno.ThronePumin) == 2 then + npcHandler:say("Tell me if you liked it when you come back. What is your name?", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, player:getName()) then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Alright |PLAYERNAME|. Vocation?", cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, vocation:getName()) then + if npcHandler.topic[cid] == 2 then + npcHandler:say("I was a " .. vocation:getName() .. ", too, before I died!! What do you want from me?", cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, "145") then + if npcHandler.topic[cid] == 3 then + player:setStorageValue(Storage.PitsOfInferno.ThronePumin, 3) + npcHandler:say("That's right, you can get Form 145 from me. However, I need Form 411 first. Come back when you have it.", cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.PitsOfInferno.ThronePumin) == 6 then + player:setStorageValue(Storage.PitsOfInferno.ThronePumin, 7) + npcHandler:say("Well done! You have form 411!! Here is Form 145. Have fun with it.", cid) + end + end + return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye and don't forget me!") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye and don't forget me!") + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_dead_bureaucrat4.lua b/data/npc/scripts/a_dead_bureaucrat4.lua new file mode 100644 index 00000000000..b03eabe3d03 --- /dev/null +++ b/data/npc/scripts/a_dead_bureaucrat4.lua @@ -0,0 +1,80 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Now where did I put that form?' }, + { text = 'Hail Pumin. Yes, hail.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local config = { + [VOCATION.CLIENT_ID.SORCERER] = "S O R C E R E R", + [VOCATION.CLIENT_ID.DRUID] = "D R U I D", + [VOCATION.CLIENT_ID.PALADIN] = "P A L A D I N", + [VOCATION.CLIENT_ID.KNIGHT] = "K N I G H T" +} + +local function greetCallback(cid) + npcHandler:setMessage(MESSAGE_GREET, "Hello " .. (Player(cid):getSex() == PLAYERSEX_FEMALE and "beautiful lady" or "handsome gentleman") .. ", welcome to the atrium of Pumin's Domain. We require some information from you before we can let you pass. Where do you want to go?") + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + local vocation = player:getVocation() + local vocationId = vocation:getId() + local vocationClientId = vocation:getClientId() + + if msgcontains(msg, "pumin") then + if player:getStorageValue(Storage.PitsOfInferno.ThronePumin) < 1 then + npcHandler:say("I'm not sure if you know what you are doing but anyway. Your name is?", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, player:getName()) then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Alright |PLAYERNAME|. Vocation?", cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, Vocation(vocationId):getName()) then + if npcHandler.topic[cid] == 2 then + npcHandler:say(config[vocationClientId] .. ", is that right?! What do you want from me?", cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, "356") then + if npcHandler.topic[cid] == 3 then + player:setStorageValue(Storage.PitsOfInferno.ThronePumin, 2) + npcHandler:say("Sorry, you need Form 145 to get Form 356. Come back when you have it", cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.PitsOfInferno.ThronePumin) == 7 then + player:setStorageValue(Storage.PitsOfInferno.ThronePumin, 8) + npcHandler:say("You are better than I thought! Congratulations, here you are: Form 356!", cid) + end + end + return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye and don't forget me!") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye and don't forget me!") + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_dragon_mother.lua b/data/npc/scripts/a_dragon_mother.lua new file mode 100644 index 00000000000..9fd3bf0b12f --- /dev/null +++ b/data/npc/scripts/a_dragon_mother.lua @@ -0,0 +1,87 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.ForgottenKnowledge.BabyDragon) < 1 then + npcHandler:setMessage(MESSAGE_GREET, "Greetings humans! Consider yourselfs lucky, I'm in need of {help}.") + npcHandler.topic[cid] = 1 + return true + elseif player:getStorageValue(Storage.ForgottenKnowledge.AccessMachine) == 1 then + npcHandler:setMessage(MESSAGE_GREET, 'Grrr.') + return true + elseif player:getStorageValue(Storage.ForgottenKnowledge.HorrorKilled) >= 1 then + npcHandler:setMessage(MESSAGE_GREET, 'You have done me a favour and the knowledge you are seeking shall be yours. I melted the ice for you, you can pass now.') + player:setStorageValue(Storage.ForgottenKnowledge.AccessMachine, 1) + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "help") then + npcHandler:say({ + "I'm aware what you are looking for. Usually I would rather devour you, but due to unfortunate circumstances, I need your {assistance}.", + }, cid) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, "assistance") then + if npcHandler.topic[cid] == 2 then + npcHandler:say({ + "Wretched creatures of ice have stolen my egg that was close to hatching. ...", + " Since I'm to huge to enter those lower Tunnels I have to ask you to take care of my {egg}. Will you do this?" + }, cid) + npcHandler.topic[cid] = 3 + end + end + + if msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 3 then + npcHandler:say({ + "So return to the upper tunnels where cultists and ice golems dwell. Somewhere in these tunnels you will find a small prison haunted by a ghost. South of this prison cell there is a tunnel that will lead you eastwards. ...", + "Follow the tunnel until you reach a small cave. Step down and down until you see a blue energy field. It will lead you to my egg. It is sealed so that not everyone may enter the room. But you have the permission now." + }, cid) + player:setStorageValue(Storage.ForgottenKnowledge.BabyDragon, 1) + npcHandler.topic[cid] = 4 + end + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] == 3 then + npcHandler:say({ + "Grrr." + }, cid) + npcHandler.topic[cid] = 1 + end + end + + if msgcontains(msg, "egg") then + if npcHandler.topic[cid] == 4 then + npcHandler:say({ + "As I told you, fiendish ice creatures dragged my egg into the lower caves. ...", + " Without enough heat the egg will die soon. Venture there and save my hatchling and the knowledge you seeek shall be yours!" + }, cid) + player:setStorageValue(Storage.ForgottenKnowledge.BabyDragon, 1) + end + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_dwarven_ghost.lua b/data/npc/scripts/a_dwarven_ghost.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/a_dwarven_ghost.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_fading_memory.lua b/data/npc/scripts/a_fading_memory.lua new file mode 100644 index 00000000000..35eaeccdb7c --- /dev/null +++ b/data/npc/scripts/a_fading_memory.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:setMessage(MESSAGE_GREET, 'Oh...') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_fluffy_squirrel.lua b/data/npc/scripts/a_fluffy_squirrel.lua new file mode 100644 index 00000000000..2bb5f729ce6 --- /dev/null +++ b/data/npc/scripts/a_fluffy_squirrel.lua @@ -0,0 +1,28 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Chchch'} } +npcHandler:addModule(VoiceModule:new(voices)) + +keywordHandler:addKeyword({'acorn'}, StdModule.say, {npcHandler = npcHandler, text = "Chh? Chhh?? "}) + +npcHandler:setMessage(MESSAGE_GREET, "Chhchh?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Chh...") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Chh...") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Chchch. Chh! ") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_frog.lua b/data/npc/scripts/a_frog.lua new file mode 100644 index 00000000000..5762195dbe5 --- /dev/null +++ b/data/npc/scripts/a_frog.lua @@ -0,0 +1,30 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'prince'}, StdModule.say, {npcHandler = npcHandler, text = "If another prince comes to kiss me, I'll kick his ass so bad that he'll need a sedan chair to get away."}) +keywordHandler:addKeyword({'princess'}, StdModule.say, {npcHandler = npcHandler, text = "If another prince comes to kiss me, I'll kick his ass so bad that he'll need a sedan chair to get away."}) +keywordHandler:addKeyword({'kiss'}, StdModule.say, {npcHandler = npcHandler, text = "Don't even try to kiss me or I'll rondhouse kick you!"}) +keywordHandler:addKeyword({'talk'}, StdModule.say, {npcHandler = npcHandler, text = "Talking frogs don't exist, idiot. It's your fucking imagination tricking you. And now your imagination commands you to walk away."}) +keywordHandler:addKeyword({'frog'}, StdModule.say, {npcHandler = npcHandler, text = "Finally someone notices I'm a FROG. Congratulations, you're VERY observant... *sigh*"}) +keywordHandler:addKeyword({'quest'}, StdModule.say, {npcHandler = npcHandler, text = "A quest? Yeah I got a quest! Go and tell King Tibianus his son tried to kiss me again!"}) +keywordHandler:addKeyword({'pyrale'}, StdModule.say, {npcHandler = npcHandler, text = "Pyrale? That idiot transformed me into an human once. But my wife came and kissed me, so I'm a frog again."}) +keywordHandler:addKeyword({'ribbit'}, StdModule.say, {npcHandler = npcHandler, text = "Pyrale? That idiot transformed me into an human once. But my wife came and kissed me, so I'm a frog again."}) + +npcHandler:setMessage(MESSAGE_GREET, "*sigh* Yet another dumb adventurer.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Yeah, good bye and don't come again!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Hah! That idiot finally left.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_ghostly_guardian.lua b/data/npc/scripts/a_ghostly_guardian.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/a_ghostly_guardian.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_ghostly_knight.lua b/data/npc/scripts/a_ghostly_knight.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/a_ghostly_knight.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_ghostly_sage.lua b/data/npc/scripts/a_ghostly_sage.lua new file mode 100644 index 00000000000..86ae8991cf3 --- /dev/null +++ b/data/npc/scripts/a_ghostly_sage.lua @@ -0,0 +1,29 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local travelNode = keywordHandler:addKeyword({'teleport'}, StdModule.say, {npcHandler = npcHandler, text = 'You will now be travelled out of here. Are you sure that you want to face that teleport?'}) + travelNode:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, destination = Position(32834, 32275, 9) }) + travelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, reset = true, text = 'Then stay here in these ghostly halls.'}) + +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'I can offer you a {teleport}.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'Dont mind me.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Ah, I feel a mortal walks these ancient halls again. Pardon me, I barely notice you. I am so lost in my thoughts.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Farewell then.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_ghostly_woman.lua b/data/npc/scripts/a_ghostly_woman.lua new file mode 100644 index 00000000000..b63cfaa50bd --- /dev/null +++ b/data/npc/scripts/a_ghostly_woman.lua @@ -0,0 +1,28 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Alone ... so alone. So cold.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "Once I was a member of the order of the nightmare knights. Now I am but a shadow who walks these cold halls."}) +keywordHandler:addKeyword({'boots'}, StdModule.say, {npcHandler = npcHandler, text = "The north has a puzzle to complete."}) + +npcHandler:setMessage(MESSAGE_GREET, "I feel you. I hear your thoughts. You are ... alive.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Alone ... so alone. So cold.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Alone ... so alone. So cold.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_ghostly_woman_ghostland.lua b/data/npc/scripts/a_ghostly_woman_ghostland.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/a_ghostly_woman_ghostland.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_goblin_exile.lua b/data/npc/scripts/a_goblin_exile.lua new file mode 100644 index 00000000000..e88e935b7eb --- /dev/null +++ b/data/npc/scripts/a_goblin_exile.lua @@ -0,0 +1,20 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_lost_soul.lua b/data/npc/scripts/a_lost_soul.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/a_lost_soul.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_majestic_warwolf.lua b/data/npc/scripts/a_majestic_warwolf.lua new file mode 100644 index 00000000000..2d3e8f7f1dc --- /dev/null +++ b/data/npc/scripts/a_majestic_warwolf.lua @@ -0,0 +1,52 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + if Player(cid):getStorageValue(Storage.OutfitQuest.DruidHatAddon) < 9 then + npcHandler:say('GRRRRRRRRRRRRR', cid) + return false + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if isInArray({'addon', 'outfit'}, msg) then + if player:getStorageValue(Storage.OutfitQuest.DruidHatAddon) == 9 then + npcHandler:say('I can see in your eyes that you are a honest and friendly person, |PLAYERNAME|. You were patient enough to learn our language and I will grant you a special gift. Will you accept it?', cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, 'yes') and npcHandler.topic[cid] == 1 then + player:setStorageValue(Storage.OutfitQuest.DruidHatAddon, 10) + player:addOutfitAddon(148, 2) + player:addOutfitAddon(144, 2) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + npcHandler:say(player:getSex() == PLAYERSEX_FEMALE and 'From now on, you shall be known as |PLAYERNAME|, the wolf girl. You shall be fast and smart as Morgrar, the great white wolf. He shall guide your path.' or 'From now on, you shall be known as |PLAYERNAME|, the bear warrior. You shall be strong and proud as Angros, the great dark bear. He shall guide your path.', cid) + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "Interesting. A human who can speak the language of wolves.") +npcHandler:setMessage(MESSAGE_FAREWELL, "YOOOOUHHOOOUU!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "YOOOOUHHOOOUU!") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_prisoner.lua b/data/npc/scripts/a_prisoner.lua new file mode 100644 index 00000000000..2450a2d511f --- /dev/null +++ b/data/npc/scripts/a_prisoner.lua @@ -0,0 +1,99 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + -- Mad mage room quest + if msgcontains(msg, "riddle") then + if player:getStorageValue(Storage.Quest.MadMageRoom.APrisoner) ~= 1 then + npcHandler:say("Great riddle, isn't it? If you can tell me the correct answer, \z + I will give you something. Hehehe!", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "PD-D-KS-P-PD") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Hurray! For that I will give you my key for - hmm - let's say ... some apples. Interested?", cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 2 then + if player:removeItem(2674, 7) then + npcHandler:say("Mnjam - excellent apples. Now - about that key. You are sure want it?", cid) + npcHandler.topic[cid] = 3 + else + npcHandler:say("Get some more apples first!", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 3 then + npcHandler:say("Really, really?", cid) + npcHandler.topic[cid] = 4 + elseif npcHandler.topic[cid] == 4 then + npcHandler:say("Really, really, really, really?", cid) + npcHandler.topic[cid] = 5 + elseif npcHandler.topic[cid] == 5 then + player:setStorageValue(Storage.Quest.MadMageRoom.APrisoner, 1) + npcHandler:say("Then take it and get happy - or die, hehe.", cid) + local key = player:addItem(2088, 1) + if key then + key:setActionId(Storage.Quest.Key.ID3666) + end + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "no") then + npcHandler:say("Then go away!", cid) + end + -- The paradox tower quest + if msgcontains(msg, "math") then + if player:getStorageValue(Storage.Quest.TheParadoxTower.Mathemagics) < 1 then + npcHandler:say("My surreal numbers are based on astonishing facts. \z + Are you interested in learning the secret of mathemagics?", cid) + npcHandler.topic[cid] = 6 + else + npcHandler:say("You already know the secrets of mathemagics! Now go and use them to learn.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 6 then + npcHandler:say("But first tell me your favourite colour please!", cid) + npcHandler.topic[cid] = 7 + elseif msgcontains(msg, "green") and npcHandler.topic[cid] == 7 then + npcHandler:say("Very interesting. So are you ready to proceed in your lesson in mathemagics?", cid) + npcHandler.topic[cid] = 8 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 8 then + if player:getStorageValue(Storage.Quest.TheParadoxTower.Mathemagics) < 1 then + player:setStorageValue(Storage.Quest.TheParadoxTower.Mathemagics, 1) + player:addAchievement("Mathemagician") + npcHandler:say("So know that everything is based on the simple fact that 1 + 1 = 1!", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say(" I think you are not in touch with yourself, come back if you have tuned in on your own feelings.", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, "Wait! Don't leave! I want to tell you about my surreal numbers.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye! Don't forget about the secrets of mathemagics.") +npcHandler:setMessage(MESSAGE_GREET, "Huh? What? I can see! Wow! A non-mino. Did they {capture} you as well?") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_restless_soul.lua b/data/npc/scripts/a_restless_soul.lua new file mode 100644 index 00000000000..f3616563d7d --- /dev/null +++ b/data/npc/scripts/a_restless_soul.lua @@ -0,0 +1,50 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.TheIceIslands.Questline) < 37 then + npcHandler:say("Uhhhh...", cid) + return false + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, "story") then + local player = Player(cid) + if player:getStorageValue(Storage.TheIceIslands.Questline) == 37 then + npcHandler:say({ + "I was captured and tortured to death by the cultists here. They worship a being that they call Ghazbaran ...", + "In his name they have claimed the mines and started to melt the ice to free an army of vile demons that have been frozen here for ages ...", + "Their plan is to create a new demon army for their master to conquer the world. Hjaern and the other shamans must learn about it! Hurry before its too late." + }, cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 38) + player:setStorageValue(Storage.TheIceIslands.Mission10, 2) -- Questlog The Ice Islands Quest, Formorgar Mines 2: Ghostwhisperer + player:setStorageValue(Storage.TheIceIslands.Mission11, 1) -- Questlog The Ice Islands Quest, Formorgar Mines 3: The Secret + end + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_sleeping_dragon.lua b/data/npc/scripts/a_sleeping_dragon.lua new file mode 100644 index 00000000000..d5de337bf9e --- /dev/null +++ b/data/npc/scripts/a_sleeping_dragon.lua @@ -0,0 +1,204 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + if Player(cid):getStorageValue(Storage.WrathoftheEmperor.Questline) == 27 then + npcHandler:setMessage(MESSAGE_GREET, "ZzzzZzzZz...chrrr...") + else + npcHandler:setMessage(MESSAGE_GREET, "Greetings, {wayfarer}.") + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 27 then + if(msg == "SOLOSARASATIQUARIUM") and player:getStorageValue(Storage.WrathoftheEmperor.InterdimensionalPotion) == 1 then + npcHandler:say({ + "Dragon dreams are golden. ...", + "A broad darkness surrounds you as if a heavy curtain is closing before your eyes. After what seems like minutes of floating through emptiness, you get the feeling as if a hole opens in the dark before you. ...", + "The hole grows larger, you cannot close your eyes. An unimaginable black. Deeper and darker than any nothingness you could possibly imagine drags you into it. ...", + "You feel as if you cannot breathe anymore. The very second you let loose of your consciousness, you sense all heaviness around you lifted. ...", + "You dive into an ocean of emerald light. Feeling like born anew the colour around you is almost overwhelming. Countless objects of all shapes and sizes are dashing past you. Racing against each other, millions are clashing in the distance. ..", + "The loudness of the gargantuan spectacle around you bursts your hearing, yet you absorb all the sounds around you. ...", + "As several large obstacles move aside directly in front of you, an intense bright centre leaps into your view. Though you cannot perceive how fast you are, your pace seems too slow. ...", + "Ever decelerating, you ultimately approach a middle in this chaos of tones of green. ...", + "As you come closer to it, yellowish shades of orange embrace you, softer shapes emerge and you almost forget the mayhem before. In warm comfort you see what lies in the heart of it all. ...", + "A majestic dragon in his sleep is surrounded by what seems the warmth and energy of a thousand suns. The tranquillity of its sight makes you smile gently. ...", + "You feel a perfect mixture of joy, compassion and sudden peacefulness. Bright xanthous impressions of topaz, orange and white welcome you at the final halt of your journey. ...", + "Dragon dreams are golden. ...", + "You find yourself inside the dragon's dream. You can {look} around or {go} into a specific direction. You can also {take} or {use} an object. Enter {help} to display this information at any time." + }, cid) + npcHandler.topic[cid] = 1 + elseif(msg:lower() == "help" and npcHandler.topic[cid] > 0 and npcHandler.topic[cid] < 34) then + npcHandler:say("You find yourself inside the dragon's dream. You can {look} around or {go} into a specific direction. You can also {take} or {use} an object. Enter {help} to display this information at any time.", cid) + elseif(msg:lower() == "west" and npcHandler.topic[cid] == 1) then + npcHandler:say("Advancing to the west, you recognise an increase of onyx on the ground.", cid) + npcHandler.topic[cid] = 2 + elseif(msg:lower() == "take attachment" and npcHandler.topic[cid] == 2) then + npcHandler:say("You carefully lift the onyx attachment from its socket. It is lighter than you expected.", cid) + npcHandler.topic[cid] = 3 + elseif(msg:lower() == "east" and npcHandler.topic[cid] == 3) then + npcHandler:say("You return to the plateau in the east.", cid) + npcHandler.topic[cid] = 4 + elseif(msg:lower() == "south" and npcHandler.topic[cid] == 4) then + npcHandler:say("You wander to the south, passing large obelisks of emerald to your left and sprawling trees of topaz to your right. ", cid) + npcHandler.topic[cid] = 5 + elseif(msg:lower() == "take stand" and npcHandler.topic[cid] == 5) then + npcHandler:say("As you rip the solid stand out of its socket and take it with you, the large gate opens with a deafening rumble. ", cid) + npcHandler.topic[cid] = 6 + elseif(msg:lower() == "east" and npcHandler.topic[cid] == 6) then + npcHandler:say("You gasp at the size of the large open gate as you walk through to head further to the east.", cid) + npcHandler.topic[cid] = 7 + elseif(msg:lower() == "take model" and npcHandler.topic[cid] == 7) then + npcHandler:say("You reach for a small solitary arrangement of combined small houses and put it in your pocket.", cid) + npcHandler.topic[cid] = 8 + elseif(msg:lower() == "take emeralds" and npcHandler.topic[cid] == 8) then + npcHandler:say("You take an emerald from the pile. ", cid) + npcHandler.topic[cid] = 9 + elseif(msg:lower() == "west" and npcHandler.topic[cid] == 9) then + npcHandler:say("You return through the semi-translucent gate to the west. ", cid) + npcHandler.topic[cid] = 10 + elseif(msg:lower() == "north" and npcHandler.topic[cid] == 10) then + npcHandler:say("You head back north to the plateau. ", cid) + npcHandler.topic[cid] = 11 + elseif(msg:lower() == "east" and npcHandler.topic[cid] == 11) then + npcHandler:say("You travel east across several large emerald bluffs and edges. All sorts of gems are scattered alongside your path. ", cid) + npcHandler.topic[cid] = 12 + elseif(msg:lower() == "take rubies" and npcHandler.topic[cid] == 12) then + npcHandler:say("You take a rather large ruby out of a pile before you. ", cid) + npcHandler.topic[cid] = 13 + elseif(msg:lower() == "north" and npcHandler.topic[cid] == 13) then + npcHandler:say("You head north passing countless stones in the crimson sea of stones beneath your feet.", cid) + npcHandler.topic[cid] = 14 + elseif(msg:lower() == "use attachment" and npcHandler.topic[cid] == 14) then + npcHandler:say({ + "Avoiding the bright light, you carefully put the attachment on top of the strange socket. ...", + "As your eyes adjust to the sudden reduction of brightness, you see the giant wings of the gate before you move to the side. You can also make out something shiny on the ground." + }, cid) + npcHandler.topic[cid] = 15 + elseif(msg:lower() == "take mirror" and npcHandler.topic[cid] == 15) then + npcHandler:say("You pick the mirror from the ground.", cid) + npcHandler.topic[cid] = 16 + elseif(msg:lower() == "north" and npcHandler.topic[cid] == 16) then + npcHandler:say({ + "Your path to the north is open. You pass the gigantic gate wings to your left and right as you advance. After about an hour of travel you hear a slight rustling in the distance. You head further into that direction. ...", + "The rustling gets louder until you come to a small dune. Behind it you find the source of the noise." + }, cid) + npcHandler.topic[cid] = 17 + elseif(msg:lower() == "use model" and npcHandler.topic[cid] == 17) then + npcHandler:say({ + "You lunge out and throw the model far into the water. As nothing happens, you turn your back to the ocean. ...", + "The very moment you walk down the dune to head back south, rays of light burst over your head in a shock wave that makes you tumble down the rest of the hill. ...", + "You can also hear a deep loud scraping for several minutes somewhere far in the west." + }, cid) + npcHandler.topic[cid] = 18 + elseif(msg:lower() == "south" and npcHandler.topic[cid] == 18) then + npcHandler:say("You travel all the way back down the dune and through the gate to the south. ", cid) + npcHandler.topic[cid] = 19 + elseif(msg:lower() == "south" and npcHandler.topic[cid] == 19) then + npcHandler:say("You return to the crimson sea of rubies in the south. ", cid) + npcHandler.topic[cid] = 20 + elseif(msg:lower() == "west" and npcHandler.topic[cid] == 20) then + npcHandler:say("You travel back to the plateau in the west. ", cid) + npcHandler.topic[cid] = 21 + elseif(msg:lower() == "west" and npcHandler.topic[cid] == 21) then + npcHandler:say("Advancing to the west, you recognise an increase of onyx on the ground. ", cid) + npcHandler.topic[cid] = 22 + elseif(msg:lower() == "north" and npcHandler.topic[cid] == 22) then + npcHandler:say("You continue travelling the barren sea of gemstones to the north. ", cid) + npcHandler.topic[cid] = 23 + elseif(msg:lower() == "west" and npcHandler.topic[cid] == 23) then + npcHandler:say("You leave the massive open gate behind you and go to the west. ", cid) + npcHandler.topic[cid] = 24 + elseif(msg:lower() == "bastesh" and npcHandler.topic[cid] == 24) then + npcHandler:say("This huge statue of Bastesh is made from onyx, and thrones on a large plateau which can be reached by a sprawling stairway. She holds a large {sapphire} in her hands. ", cid) + npcHandler.topic[cid] = 25 + elseif(msg:lower() == "take sapphire" and npcHandler.topic[cid] == 25) then + npcHandler:say("You carefully remove the sapphire from Bastesh's grasp. ", cid) + npcHandler.topic[cid] = 26 + elseif(msg:lower() == "east" and npcHandler.topic[cid] == 26) then + npcHandler:say("You head back to the east and to the plateau. ", cid) + npcHandler.topic[cid] = 27 + elseif(msg:lower() == "south" and npcHandler.topic[cid] == 27) then + npcHandler:say("You head back south to the site with the onyx lookout. ", cid) + npcHandler.topic[cid] = 28 + elseif(msg:lower() == "east" and npcHandler.topic[cid] == 28) then + npcHandler:say("You return to the plateau in the east. ", cid) + npcHandler.topic[cid] = 29 + elseif(msg:lower() == "use stand" and npcHandler.topic[cid] == 29) then + npcHandler:say("You put the stand into a small recess you find near the middle of the plateau. ", cid) + npcHandler.topic[cid] = 30 + elseif(msg:lower() == "use ruby" and npcHandler.topic[cid] == 30) then + npcHandler:say("As the ruby slips into the notch, the strong red of the stone intensifies a thousandfold. You fear to hurt your eyes and turn away immediately. The ray seems to be directed to the centre of the plateau with astounding precision. ", cid) + npcHandler.topic[cid] = 31 + elseif(msg:lower() == "use sapphire" and npcHandler.topic[cid] == 31) then + npcHandler:say("As the sapphire slips into the notch, the deep blue of the stone intensifies a thousandfold. You fear to hurt your eyes and turn away immediately. The ray seems to be directed to the centre of the plateau with astounding precision. ", cid) + npcHandler.topic[cid] = 32 + elseif(msg:lower() == "use emerald" and npcHandler.topic[cid] == 32) then + npcHandler:say("As the emerald slips into the notch, the vibrant green of the stone intensifies a thousandfold. You fear to hurt your eyes and turn away immediately. The ray seems to be directed to the centre of the plateau with astounding precision. ", cid) + npcHandler.topic[cid] = 33 + elseif(msg:lower() == "use mirror" and npcHandler.topic[cid] == 33) then + npcHandler:say({ + "With your eyes covered and avoiding direct sight of the rays, you put the mirror into the stand. ...", + "Instinctively you run to a larger emerald bluff near the raise to find cover. Mere seconds after you claimed the sturdy shelter, a deep dark humming starts to swirl through the air. ...", + "Seconds pass as the hum gets louder. The noise is maddening, drowning all other sounds around you. As you cover your ears in pain, the humming explodes into a deafening growl. ...", + "You raise your head above the edge of the emerald to catch a glimpse of what's happening. ...", + "The hand seems to have grown into a fist. In the distance you can now see a blurry scheme of a creature too large for your eyes to get a sharper view of its head. ...", + "Blending the rays, the mirror directs pure white light directly towards the part where you assume the face of the creature. ...", + "The growl transforms into a scream, everything around you seems to compress. As you press yourself tightly against the bluff, everything falls silent and in a split second, the dark being dissolves into bursts of blackness. You wake." + }, cid) + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 28) + player:setStorageValue(Storage.WrathoftheEmperor.Mission09, 2) --Questlog, Wrath of the Emperor "Mission 09: The Sleeping Dragon" + npcHandler.topic[cid] = 0 + end + elseif player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 28 then + if(msgcontains(msg, "wayfarer")) then + npcHandler:say("I call you the wayfarer. You travelled through my dreams. You ultimately freed my mind. My mind accepted you and so will I.", cid) + npcHandler.topic[cid] = 40 + elseif(msgcontains(msg, "mission") and npcHandler.topic[cid] == 40) then + npcHandler:say({ + "Aaaah... free at last. Hmmm. ...", + "I assume you need to get through the gate to reach the evildoer. I can help you if you trust me, wayfarer. I will share a part of my mind with you which should enable you to step through the gate. ...", + "This procedure may be exhausting. Are you prepared to receive my key?" + }, cid) + npcHandler.topic[cid] = 41 + elseif(msgcontains(msg, "yes") and npcHandler.topic[cid] == 41) then + npcHandler:say({ + "SAETHELON TORILUN GARNUM. ...", + "SLEEP. ...", + "GAIN. ...", + "RISE. ...", + "The transfer was successful. ...", + "You are now prepared to enter the realm of the evildoer. I am grateful for your help, wayfarer. Should you seek my council, use this charm I cede to you. For my spirit will guide you wherever you are. May you enjoy a sheltered future, you shall prevail." + }, cid) + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 29) + player:setStorageValue(Storage.WrathoftheEmperor.Mission10, 1) --Questlog, Wrath of the Emperor "Mission 10: A Message of Freedom" + player:addItem(11260, 1) + player:addAchievement('Wayfarer') + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_starving_dog.lua b/data/npc/scripts/a_starving_dog.lua new file mode 100644 index 00000000000..d55fc96c4f8 --- /dev/null +++ b/data/npc/scripts/a_starving_dog.lua @@ -0,0 +1,42 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "sniffler") then + if player:getStorageValue(Storage.TheIceIslands.Questline) == 1 then + npcHandler:say("!", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "meat") then + if npcHandler.topic[cid] == 1 then + if player:removeItem(2666, 1) then + npcHandler:say("", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 2) + player:setStorageValue(Storage.TheIceIslands.Mission01, 2) -- Questlog The Ice Islands Quest, Befriending the Musher + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_strange_chalice.lua b/data/npc/scripts/a_strange_chalice.lua new file mode 100644 index 00000000000..ebe15632abc --- /dev/null +++ b/data/npc/scripts/a_strange_chalice.lua @@ -0,0 +1,88 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Don't forget npcHandler = npcHandler in the parameters. It is required for all StdModule functions! +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "'Alice the chalice'... Hmpf, of course I won't TELL you my name, I am UNDERCOVER! Now be quiet or they will hear you."}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "Well, I am drinking most of the time. Er, no I mean - trying to hold my fluids... ah, wait that came out wrong: I am doing research. Let's just keep it at that."}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "chalice") and player:getStorageValue(Storage.ForgottenKnowledge.Chalice) == 1 then + npcHandler:say({ + "Finally. That's what I... oh wait, you're still talking to me - you will blow my cover! What do you want? Oh wait, did my {daughter} send you? It has been some time now, indeed." + }, cid) + npcHandler.topic[cid] = 1 + end + + if msgcontains(msg, "daughter") and npcHandler.topic[cid] == 1 then + npcHandler:say({ + "Well, besides being a renowned sorcerer and scholar at the magic academy in Edron, I am also the proud father of a beautiful daughter, Ivalisse. My little endeavour here must have troubled the poor thing all the time since I left. ...", + "Tell her I love her and that I will take care. I have to press on! My research is most valuable to the 'Edron-Zaoan Exploration Division'. You don't happen to have some water, do you? Ah nevermind. It's a long {story}." + }, cid) + npcHandler.topic[cid] = 2 + end + + if msgcontains(msg, "story") and npcHandler.topic[cid] == 2 then + npcHandler:say({ + "No water then? Ah drat - er, don't worry, no problem. So, from the day I received news of the discovery of Zao, I wanted to study its inhabitants, wildlife, plants and geography. ...", + "The academy instated the 'Edron-Zaoan Exploration Division' shortly after. I was a founding member and head of the 'Draken' research branch. ...", + "Since my valued and practical oriented colleague and mentor Spectulus did not join us, there is only one member of the academy exploration division to actually venture out to see the place - me. ...", + "You must know, most things in the academy happen 'inside', behind closed doors. But some of us simply refuse to let theory reign over practical experience in science. ...", + "Well, basically Spectulus is the only one likeminded so far. In fact, he incited me to work in the field in first place. So here I am! {Disguised} as a chalice." + }, cid) + npcHandler.topic[cid] = 3 + end + + if msgcontains(msg, "disguised") and npcHandler.topic[cid] == 3 then + npcHandler:say({ + "Oh yes, so since I wanted to study the Draken up close, I came up with an idea. Based on my research, and some slight bruises and a scar, the perfect hiding place is often right in the middle of subjects. ...", + "If I could enter their lair unseen and establish a forward camp, I would be able to study the draken in peace - or so I thought. Turns out the whole place was empty. I set up my camp and waited. ...", + "Then something happened, lizardfolk started to appear, searching the place. I had to retreat from my hiding place and advance through a safer position. ...", + "I needed to get close and blend in. So I came up with the ultimate disguise: a chalice. I could establish foothold right in their midst, would never be identified as an intruder and could even analyse their drinks! ...", + "I quickly dug a tunnel to get into what I assume is a throne room and waited for them to pick me up an carry me around! ...", + "They also 'used' me a bit, you don't want to go into any details here. I am really {thirsty}." + }, cid) + npcHandler.topic[cid] = 4 + end + + if msgcontains(msg, "thirsty") and npcHandler.topic[cid] == 4 then + npcHandler:say({ + "Ah did I say that? Nevermind, I'm not really thirsty. It's part of this illusion. Somehow, I've been in hiding for so long, I started to... become... a vessel. ...", + "I don't know, I have that constant urge to drink but in this form I would not need to, there is no mouth, no stomach, no flesh and no actual need to eat, drink or sleep. ...", + "I basically communicate by making the metal of this goblet vibrate and using its form as a body of sound. Like a real voice, don't you think?? Yes, alright I know it's creepy. ...", + "I am still in the middle of my research and do not want to go home, so please tell my daughter to not worry about my - this will be a breakthrough! I already {learned} a lot!" + }, cid) + npcHandler.topic[cid] = 5 + end + + if msgcontains(msg, "learned") and npcHandler.topic[cid] == 5 then + npcHandler:say({ + "Yes, well for instance I tried for some time to figure out how to enter the fiery portal in this complex. Most of the draken never come up here. They rather hide somewhere down there, planning and plotting. ...", + " I already know how to enter it, you need to step in and yell 'zzubaran'. Unfortunately they never took me with them. ...", + " I heard them say it once, when a seemingly drunk guard yelled it in front of a wall mounted torch, hitting his head against it afterwards. He spilt all my contents on the floor, hmpf." + }, cid) + player:setStorageValue(Storage.ForgottenKnowledge.AccessLavaTeleport, 1) + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_strange_fellow.lua b/data/npc/scripts/a_strange_fellow.lua new file mode 100644 index 00000000000..8683a6c206a --- /dev/null +++ b/data/npc/scripts/a_strange_fellow.lua @@ -0,0 +1,64 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if player:getStorageValue(Storage.Postman.Mission03) ~= 1 then + return true + end + if msgcontains(msg, "bill") then + if npcHandler.topic[cid] == 6 then + npcHandler:say("A bill? Oh boy so you are delivering another bill to poor me?", cid) + npcHandler.topic[cid] = 7 + end + elseif msgcontains(msg, "yes") then + if player:removeItem(2329, 1) and npcHandler.topic[cid] == 7 then + npcHandler:say("Ok, ok, I'll take it. I guess I have no other choice anyways. And now leave me alone in my misery please.", cid) + player:setStorageValue(Storage.Postman.Mission03, 2) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "hat") then + if npcHandler.topic[cid] < 1 then + npcHandler:say("Uh? What do you want?!", cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say("What? My hat?? Theres... nothing special about it!", cid) + npcHandler.topic[cid] = 3 + elseif npcHandler.topic[cid] == 3 then + npcHandler:say("Stop bugging me about that hat, do you listen?", cid) + npcHandler.topic[cid] = 4 + elseif npcHandler.topic[cid] == 4 then + npcHandler:say("Hey! Don't touch that hat! Leave it alone!!! Don't do this!!!!", cid) + npcHandler.topic[cid] = 5 + elseif npcHandler.topic[cid] == 5 then + for i = 1, 5 do + Game.createMonster("Rabbit", Npc():getPosition()) + end + npcHandler:say("Noooooo! Argh, ok, ok, I guess I can't deny it anymore, I am David Brassacres, the magnificent, so what do you want?", cid) + npcHandler.topic[cid] = 6 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_swan.lua b/data/npc/scripts/a_swan.lua new file mode 100644 index 00000000000..ada7ffd79e9 --- /dev/null +++ b/data/npc/scripts/a_swan.lua @@ -0,0 +1,67 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'mission') then + if (player:getStorageValue(Storage.ThreatenedDreams.TroubledMission01) == 12) then + npcHandler:say({ + "My sister Ikassis sent you? Blessed be her soul! Yes, it is true: I need help. Listen, I will tell you a secret but please don't break it. As you might already suspect I'm not really a swan but a fae. ...", + "But other than many of my siblings I did not take over a swan's body. I'm a swan maiden and this is one of my two aspects. I can take the shape of a swan as well as that of a young maiden. ...", + "But to do so I need a magical artefact: a cloak made of swan feathers. If I lose this cloak - or someone steals it from me - I'm stuck to the form of a swan and can't change shape anymore. And this is exactly what happened: ...", + "A troll stalked me while I was bathing in the river and he stole my cloak. Now I am trapped in the form of a swan. Please, can you find the thief and bring back the cloak?" + }, cid) + npcHandler.topic[cid] = 1 + elseif (player:getStorageValue(Storage.ThreatenedDreams.TroubledMission01) == 15) then + if player:getItemCount(28605) >= 5 then + player:removeItem(28605, 5) + player:setStorageValue(Storage.ThreatenedDreams.TroubledMission01, 16) + npcHandler:say({ + "This is everything that remained of my cloak? That's terrible! However, I guess I can put the feathers together again. Yes, that should be enough feathers. ...", + "Please give them to me so I can restore my cloak. But don't watch me! Swan maidens don't like to be observed. Nature's blessings, human being. I will tell Ikassis that you have been of great assistance." + }, cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You need to deliver me like 5 feathers.", cid) + end + else + npcHandler:say("You are not on that mission.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, "yes") then + npcHandler:say({ + "Thank you, human being! I guess the thieving troll headed to the mountains east of here. As far as I know you can only reach these mountain tops by diving into a small cave. ...", + "The connecting tunnels will lead you to a mountain where you may discover him. I heard a man named Jerom talking about this when he passed by this river. Perhaps he knows more about it." + }, cid) + player:setStorageValue(Storage.ThreatenedDreams.TroubledMission01, 13) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "I salute you, mortal being.") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) + + diff --git a/data/npc/scripts/a_sweaty_cyclops.lua b/data/npc/scripts/a_sweaty_cyclops.lua new file mode 100644 index 00000000000..d7beaf8ae5e --- /dev/null +++ b/data/npc/scripts/a_sweaty_cyclops.lua @@ -0,0 +1,240 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Hum hum, huhum' }, + { text = 'Silly lil\' human' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "melt") then + npcHandler:say("Can melt gold ingot for lil' one. You want?", cid) + npcHandler.topic[cid] = 10 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 10 then + if player:removeItem(9971,1) then + npcHandler:say("whoooosh There!", cid) + player:addItem(13941, 1) + else + npcHandler:say("There is no gold ingot with you.", cid) + end + npcHandler.topic[cid] = 0 + end + + if msgcontains(msg, "amulet") then + if player:getStorageValue(Storage.SweetyCyclops.AmuletStatus) < 1 then + npcHandler:say("Me can do unbroken but Big Ben want gold 5000 and Big Ben need a lil' time to make it unbroken. Yes or no??", cid) + npcHandler.topic[cid] = 9 + elseif player:getStorageValue(Storage.SweetyCyclops.AmuletStatus) == 1 then + npcHandler:say("Ahh, lil' one wants amulet. Here! Have it! Mighty, mighty amulet lil' one has. Don't know what but mighty, mighty it is!!!", cid) + player:addItem(8266, 1) + player:setStorageValue(Storage.SweetyCyclops.AmuletStatus, 2) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Wait. Me work no cheap is. Do favour for me first, yes?", cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say("Me need gift for woman. We dance, so me want to give her bast skirt. But she big is. So I need many to make big one. Bring three okay? Me wait.", cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.FriendsandTraders.DefaultStart, 1) + player:setStorageValue(Storage.FriendsandTraders.TheSweatyCyclops, 1) + elseif npcHandler.topic[cid] == 3 then + if player:removeItem(3983, 3) then + npcHandler:say("Good good! Woman happy will be. Now me happy too and help you.", cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.FriendsandTraders.TheSweatyCyclops, 2) + end + -- Crown Armor + elseif npcHandler.topic[cid] == 4 then + if player:removeItem(2487, 1) then + npcHandler:say("Cling clang!", cid) + npcHandler.topic[cid] = 0 + player:addItem(5887, 1) + end + -- Dragon Shield + elseif npcHandler.topic[cid] == 5 then + if player:removeItem(2516, 1) then + npcHandler:say("Cling clang!", cid) + npcHandler.topic[cid] = 0 + player:addItem(5889, 1) + end + -- Devil Helmet + elseif npcHandler.topic[cid] == 6 then + if player:removeItem(2462, 1) then + npcHandler:say("Cling clang!", cid) + npcHandler.topic[cid] = 0 + player:addItem(5888, 1) + end + -- Giant Sword + elseif npcHandler.topic[cid] == 7 then + if player:removeItem(2393, 1) then + npcHandler:say("Cling clang!", cid) + npcHandler.topic[cid] = 0 + player:addItem(5892, 1) + end + -- Soul Orb + elseif npcHandler.topic[cid] == 8 then + if player:getItemCount(5944) > 0 then + local count = player:getItemCount(5944) + for i = 1, count do + if math.random(100) <= 1 then + player:addItem(6529, 6) + player:removeItem(5944, 1) + else + player:addItem(6529, 3) + player:removeItem(5944, 1) + end + end + npcHandler:say("Cling clang!", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You dont have soul orbs!", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 9 then + if player:getItemCount(8262) > 0 and player:getItemCount(8263) > 0 and player:getItemCount(8264) > 0 and player:getItemCount(8265) > 0 and player:getMoney() + player:getBankBalance() >= 5000 then + player:removeItem(8262, 1) + player:removeItem(8263, 1) + player:removeItem(8264, 1) + player:removeItem(8265, 1) + player:removeMoneyNpc(5000) + player:setStorageValue(Storage.SweetyCyclops.AmuletTimer, os.time()) + player:setStorageValue(Storage.SweetyCyclops.AmuletStatus, 1) + npcHandler:say("Well, well, I do that! Big Ben makes lil' amulet unbroken with big hammer in big hands! No worry! Come back after sun hits the horizon 24 times and ask me for amulet.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 11 then + if player:removeItem(5880, 1) then + player:setStorageValue(Storage.HiddenCityOfBeregar.GearWheel, player:getStorageValue(Storage.HiddenCityOfBeregar.GearWheel) + 1) + player:addItem(9690, 1) + npcHandler:say("Cling clang!", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Lil' one does not have any iron ores.", cid) + end + npcHandler.topic[cid] = 0 + end + + -- Crown Armor + elseif msgcontains(msg, "uth'kean") then + if player:getStorageValue(Storage.FriendsandTraders.TheSweatyCyclops) < 1 then + npcHandler:say("Very noble. Shiny. Me like. But breaks so fast. Me can make from shiny armour. Lil' one want to trade?", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.FriendsandTraders.TheSweatyCyclops) == 1 then + npcHandler:say("Lil' one bring three bast skirts?", cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.FriendsandTraders.TheSweatyCyclops) == 2 then + npcHandler:say("Very noble. Shiny. Me like. But breaks so fast. Me can make from shiny armour. Lil' one want to trade?", cid) + npcHandler.topic[cid] = 4 + end + -- Dragon Shield + elseif msgcontains(msg, "uth'lokr") then + if player:getStorageValue(Storage.FriendsandTraders.TheSweatyCyclops) < 1 then + npcHandler:say("Firy steel it is. Need green ones' breath to melt. Or red even better. Me can make from shield. Lil' one want to trade?", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.FriendsandTraders.TheSweatyCyclops) == 1 then + npcHandler:say("Lil' one bring three bast skirts?", cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.FriendsandTraders.TheSweatyCyclops) == 2 then + npcHandler:say("Firy steel it is. Need green ones' breath to melt. Or red even better. Me can make from shield. Lil' one want to trade?", cid) + npcHandler.topic[cid] = 5 + end + -- Devil Helmet + elseif msgcontains(msg, "za'ralator") then + if player:getStorageValue(Storage.FriendsandTraders.TheSweatyCyclops) < 1 then + npcHandler:say("Hellsteel is. Cursed and evil. Dangerous to work with. Me can make from evil helmet. Lil' one want to trade?", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.FriendsandTraders.TheSweatyCyclops) == 1 then + npcHandler:say("Lil' one bring three bast skirts?", cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.FriendsandTraders.TheSweatyCyclops) == 2 then + npcHandler:say("Hellsteel is. Cursed and evil. Dangerous to work with. Me can make from evil helmet. Lil' one want to trade?", cid) + npcHandler.topic[cid] = 6 + end + -- Giant Sword + elseif msgcontains(msg, "uth'prta") then + if player:getStorageValue(Storage.FriendsandTraders.TheSweatyCyclops) < 1 then + npcHandler:say("Good iron is. Me friends use it much for fight. Me can make from weapon. Lil' one want to trade?", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.FriendsandTraders.TheSweatyCyclops) == 1 then + npcHandler:say("Lil' one bring three bast skirts?", cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.FriendsandTraders.TheSweatyCyclops) == 2 then + npcHandler:say("Good iron is. Me friends use it much for fight. Me can make from weapon. Lil' one want to trade?", cid) + npcHandler.topic[cid] = 7 + end + -- Soul Orb + elseif msgcontains(msg, "soul orb") then + if player:getStorageValue(Storage.FriendsandTraders.TheSweatyCyclops) < 1 then + npcHandler:say("Uh. Me can make some nasty lil' bolt from soul orbs. Lil' one want to trade all?", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.FriendsandTraders.TheSweatyCyclops) == 1 then + npcHandler:say("Lil' one bring three bast skirts?", cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.FriendsandTraders.TheSweatyCyclops) == 2 then + npcHandler:say("Uh. Me can make some nasty lil' bolt from soul orbs. Lil' one want to trade all?", cid) + npcHandler.topic[cid] = 8 + end + elseif msgcontains(msg, "gear wheel") then + if player:getStorageValue(Storage.HiddenCityOfBeregar.GoingDown) > 0 and player:getStorageValue(Storage.HiddenCityOfBeregar.GearWheel) > 3 then + npcHandler:say("Uh. Me can make some gear wheel from iron ores. Lil' one want to trade?", cid) + npcHandler.topic[cid] = 11 + end + end + return true +end + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am smith."}) +keywordHandler:addKeyword({'smith'}, StdModule.say, {npcHandler = npcHandler, text = "Working steel is my profession."}) +keywordHandler:addKeyword({'steel'}, StdModule.say, {npcHandler = npcHandler, text = "Manny kinds of. Like {Mesh Kaha Rogh'}, {Za'Kalortith}, {Uth'Byth}, {Uth'Morc}, {Uth'Amon}, {Uth'Maer}, {Uth'Doon}, and {Zatragil}."}) +keywordHandler:addKeyword({'zatragil'}, StdModule.say, {npcHandler = npcHandler, text = "Most ancients use dream silver for different stuff. Now ancients most gone. Most not know about."}) +keywordHandler:addKeyword({'uth\'doon'}, StdModule.say, {npcHandler = npcHandler, text = "It's high steel called. Only lil' lil' ones know how make."}) +keywordHandler:addKeyword({'za\'kalortith'}, StdModule.say, {npcHandler = npcHandler, text = "It's evil. Demon iron is. No good cyclops goes where you can find and need evil flame to melt."}) +keywordHandler:addKeyword({'mesh kaha rogh'}, StdModule.say, {npcHandler = npcHandler, text = "Steel that is singing when forged. No one knows where find today."}) +keywordHandler:addKeyword({'uth\'byth'}, StdModule.say, {npcHandler = npcHandler, text = "Not good to make stuff off. Bad steel it is. But eating magic, so useful is."}) +keywordHandler:addKeyword({'uth\'maer'}, StdModule.say, {npcHandler = npcHandler, text = "Brightsteel is. Much art made with it. Sorcerers too lazy and afraid to enchant much."}) +keywordHandler:addKeyword({'uth\'amon'}, StdModule.say, {npcHandler = npcHandler, text = "Heartiron from heart of big old mountain, found very deep. Lil' lil ones fiercely defend. Not wanting to have it used for stuff but holy stuff."}) +keywordHandler:addKeyword({'ab\'dendriel'}, StdModule.say, {npcHandler = npcHandler, text = "Me parents live here before town was. Me not care about lil' ones."}) +keywordHandler:addKeyword({'lil\' lil\''}, StdModule.say, {npcHandler = npcHandler, text = "Lil' lil' ones are so fun. We often chat."}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = "One day I'll go and look."}) +keywordHandler:addKeyword({'teshial'}, StdModule.say, {npcHandler = npcHandler, text = "Is one of elven family or such thing. Me not understand lil' ones and their business."}) +keywordHandler:addKeyword({'cenath'}, StdModule.say, {npcHandler = npcHandler, text = "Is one of elven family or such thing. Me not understand lil' ones and their business."}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "I called Bencthyclthrtrprr by me people. Lil' ones me call Big Ben."}) +keywordHandler:addKeyword({'god'}, StdModule.say, {npcHandler = npcHandler, text = "You shut up. Me not want to hear."}) +keywordHandler:addKeyword({'fire sword'}, StdModule.say, {npcHandler = npcHandler, text = "Do lil' one want to trade a fire sword?"}) +keywordHandler:addKeyword({'dragon shield'}, StdModule.say, {npcHandler = npcHandler, text = "Do lil' one want to trade a dragon shield?"}) +keywordHandler:addKeyword({'sword of valor'}, StdModule.say, {npcHandler = npcHandler, text = "Do lil' one want to trade a sword of valor?"}) +keywordHandler:addKeyword({'warlord sword'}, StdModule.say, {npcHandler = npcHandler, text = "Do lil' one want to trade a warlord sword?"}) +keywordHandler:addKeyword({'minotaurs'}, StdModule.say, {npcHandler = npcHandler, text = "They were friend with me parents. Long before elves here, they often made visit. No longer come here."}) +keywordHandler:addKeyword({'elves'}, StdModule.say, {npcHandler = npcHandler, text = "Me not fight them, they not fight me."}) +keywordHandler:addKeyword({'excalibug'}, StdModule.say, {npcHandler = npcHandler, text = "Me wish I could make weapon like it."}) +keywordHandler:addKeyword({'cyclops'}, StdModule.say, {npcHandler = npcHandler, text = "Me people not live here much. Most are far away."}) + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:setMessage(MESSAGE_GREET, "Hum Humm! Welcume lil' |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye lil' one.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_tainted_soul.lua b/data/npc/scripts/a_tainted_soul.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/a_tainted_soul.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_tortured_soul.lua b/data/npc/scripts/a_tortured_soul.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/a_tortured_soul.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_weakened_forest_fury.lua b/data/npc/scripts/a_weakened_forest_fury.lua new file mode 100644 index 00000000000..2c7215708ae --- /dev/null +++ b/data/npc/scripts/a_weakened_forest_fury.lua @@ -0,0 +1,100 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Don't forget npcHandler = npcHandler in the parameters. It is required for all StdModule functions! +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = ' My name is now known only to the wind and it shall remain like this until I will return to my kin.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I was a guardian of this glade. I am the last one... everyone had to leave.'}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = "This glade's time is growing short if nothing will be done soon."}) +keywordHandler:addKeyword({'forest fury'}, StdModule.say, {npcHandler = npcHandler, text = "Take care, guardian."}) +keywordHandler:addKeyword({'orclops'}, StdModule.say, {npcHandler = npcHandler, text = "Cruel beings. Large and monstrous, with a single eye, staring at their prey. "}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "distress") or msgcontains(msg, "mission") then + npcHandler:say({ + "My pride is great but not greater than reason. I am not too proud to ask for help as this is a dark hour. ... ", + "This glade has been desecrated. We kept it secret for centuries, yet evil has found a way to sully and destroy what was our most sacred. ...", + "There is only one way to reinvigorate its spirits, a guardian must venture down there and bring life back into the forest. ... ", + "Stolen {seeds} need to be wrested from the {intruders} and planted where the soil still hungers. ... ", + "The purest {water} from the purest well needs to be brought there and poured and {birds} that give life need to be brought back to the inner sanctum of the glade. ...", + "Will you be our guardian?" + }, cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "Indeed, you will. Take one of these cages, which have been crafted generations ago to rob a creature of its freedom for that it may earn it again truthfully. Return the birds back to their home in the glade. ...", + "You will find {phials} for water near this sacred well which will take you safely to the glade. No seeds are left, they are in the hands of the intruders now. Have faith in yourself, guardian." + }, cid) + player:setStorageValue(Storage.ForgottenKnowledge.BirdCage, 1) + player:addItem(26480, 1) + end + elseif msgcontains(msg, "seeds") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "Seeds to give life to strong trees, blooming and proud. The {intruders} robbed us from them." + }, cid) + end + elseif msgcontains(msg, "intruders") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "The intruders appeared in the blink of an eye. Out of thin air, as if they came from nowhere. They overrun the glade within ours and drove away what was remaining from us within the day." + }, cid) + end + elseif msgcontains(msg, "water") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "The purest water flows through this well. For centuries we concealed it, for other beings to not lay their eyes on it." + }, cid) + end + elseif msgcontains(msg, "birds") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "Take care, guardian." + }, cid) + end + elseif msgcontains(msg, "phials") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "Phials for the purest water from our sacred well. They are finely crafted and very fragile. We keep a small supply up here around the well. Probably the only thing the intruders did not care for." + }, cid) + end + end + if msgcontains(msg, "cages") and player:getStorageValue(Storage.ForgottenKnowledge.BirdCage) == 1 then + npcHandler:say({ + "Crafted generations ago to rob a creature of its freedom for that it may earn it again truthfully. You will need them if you plan on returning the birds to their rightful home in the glade. ... ", + "Are you in need of another one? " + }, cid) + npcHandler.topic[cid] = 2 + end + if msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 2 then + npcHandler:say({ + "I already handed a cage to you. If you are in need of another one, you will have to return to me later." + }, cid) + end + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/a_wrinkled_bonelord.lua b/data/npc/scripts/a_wrinkled_bonelord.lua new file mode 100644 index 00000000000..c4348292b55 --- /dev/null +++ b/data/npc/scripts/a_wrinkled_bonelord.lua @@ -0,0 +1,49 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = '485611800364197.' }, + { text = '78572611857643646724.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +keywordHandler:addKeyword({'death'}, StdModule.say, {npcHandler = npcHandler, text = "Yes, yes, I will kill you soon enough, now let me continue my investigation on you."}) +keywordHandler:addKeyword({'god'}, StdModule.say, {npcHandler = npcHandler, text = "They will mourn the day they abandoned us."}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am the great librarian."}) +keywordHandler:addKeyword({'library'}, StdModule.say, {npcHandler = npcHandler, text = "It's a fine library, isn't it?"}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "I am 486486 and NOT 'Blinky' as some people called me ... before they died."}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = "It's 1, not 'Tibia', silly."}) +keywordHandler:addKeyword({'cyclops'}, StdModule.say, {npcHandler = npcHandler, text = "Uglyness incarnate. One eye! Imagine that! Horrible!"}) +keywordHandler:addKeyword({'elves'}, StdModule.say, {npcHandler = npcHandler, text = "These fools and their superstitious life cult don't understand anything of importance."}) +keywordHandler:addKeyword({'excalibug'}, StdModule.say, {npcHandler = npcHandler, text = "Only inferior species need weapons."}) +keywordHandler:addKeyword({'ab\'dendriel'}, StdModule.say, {npcHandler = npcHandler, text = "I heard that elves moved in upstairs."}) +keywordHandler:addKeyword({'numbers'}, StdModule.say, {npcHandler = npcHandler, text = "Numbers are essential. They are the secret behind the scenes. If you are a master of mathematics you are a master over life and death."}) +keywordHandler:addKeyword({'books'}, StdModule.say, {npcHandler = npcHandler, text = "Our books are written in 469, of course you can't understand them."}) +keywordHandler:addKeyword({'0'}, StdModule.say, {npcHandler = npcHandler, text = "Go and wash your eyes for using this obscene number!"}) +keywordHandler:addKeyword({'469'}, StdModule.say, {npcHandler = npcHandler, text = "The language of my kind. Superior to any other language and only to be spoken by entities with enough eyes to blink it."}) +keywordHandler:addKeyword({'orcs'}, StdModule.say, {npcHandler = npcHandler, text = "Noisy pests."}) +keywordHandler:addKeyword({'minotaurs'}, StdModule.say, {npcHandler = npcHandler, text = "Their mages are so close to the truth. Closer then they know and closer then it's good for them."}) +keywordHandler:addKeyword({'humans'}, StdModule.say, {npcHandler = npcHandler, text = "Good tools to work with ... After their death, that is."}) +keywordHandler:addKeyword({'eyes'}, StdModule.say, {npcHandler = npcHandler, text = "You pitiful two-eyed creatures. In our eyes, you look weird. It is pathetic how much you depend on hands and legs. Since we bonelords have more eyes than any creature in the world, it is obvious that you can determine the value of a species by the number of its eyes. "}) +keywordHandler:addKeyword({'bonelord'}, StdModule.say, {npcHandler = npcHandler, text = "Our race is very old. Over the time, we have been given many different names by other races. The term bonelord sticks to us for quite a while now. In our language the name of our race is not fix but a complex formula, and as such it always changes for the subjective viewer. "}) +keywordHandler:addKeyword({'language'}, StdModule.say, {npcHandler = npcHandler, text = "Our language is beyond comprehension by your lesser beings. It heavily relies on mathemagic. Your brain is not suited for the mathemagical processing necessary to understand our language.To decipher even our most basic texts, it would need a genius that can calculate numbers within seconds in his brain. "}) + +npcHandler:setMessage(MESSAGE_GREET, "What is this? An optically challenged entity called |PLAYERNAME|. How fascinating!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Wait right there. I will eat you after writing down what I found out.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Wait right there. I will eat you after writing down what I found out.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/abran_ironeye.lua b/data/npc/scripts/abran_ironeye.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/abran_ironeye.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/admiral_wyrmslicer.lua b/data/npc/scripts/admiral_wyrmslicer.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/admiral_wyrmslicer.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/adrenius.lua b/data/npc/scripts/adrenius.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/adrenius.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ahmet.lua b/data/npc/scripts/ahmet.lua new file mode 100644 index 00000000000..ad0702f562f --- /dev/null +++ b/data/npc/scripts/ahmet.lua @@ -0,0 +1,101 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'documents') then + if player:getStorageValue(Storage.ThievesGuild.Mission04) == 2 then + player:setStorageValue(Storage.ThievesGuild.Mission04, 3) + npcHandler:say({ + 'You need some forged documents? But I will only forge something for a friend. ...', + 'The nomads at the northern oasis killed someone dear to me. Go and kill at least one of them, then we talk about your document.' + }, cid) + elseif player:getStorageValue(Storage.ThievesGuild.Mission04) == 4 then + npcHandler:say('The slayer of my enemies is my friend! For a mere 1000 gold I will create the documents you need. Are you interested?', cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, 'mission') or msgcontains(msg, 'quest') then + if player:getStorageValue(Storage.QuestChests.StealFromThieves) < 1 then + npcHandler:say({ + "What are you talking about?? I was robbed!!!! Someone catch those filthy thieves!!!!! GUARDS! ...", + ".... Like usual, they hide at the slightest sign of trouble! YOU! Want to earn some quick money?" + }, cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(Storage.QuestChests.StealFromThieves) == 1 or player:getStorageValue(Storage.QuestChests.StealFromThieves) == 2 then + npcHandler:say('Did you find my stuff?', cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, 'book') then + npcHandler:say('I see: You want me to add an additional story to this book. A legend about how it brings ill luck to kill a white deer. I could do that, yes. It costs 5000 gold, however. Are you still interested?', cid) + npcHandler.topic[cid] = 5 + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + if player:removeMoneyNpc(1000) then + player:addItem(8694, 1) + player:setStorageValue(Storage.ThievesGuild.Mission04, 5) + npcHandler:say('And here they are! Now forget where you got them from.', cid) + else + npcHandler:say('You don\'t have enough money.', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say({ + "Of course you do! Go hunt down the thieves and bring back the stuff they have stolen from me. ...", + " I saw them running out of town and then to the north. Maybe they hide at the oasis." + }, cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.QuestChests.StealFromThieves, 1) + elseif npcHandler.topic[cid] == 3 then + if player:removeItem(7587, 1) then + npcHandler:say('GREAT! If you ever need a job as my personal security guard, let me know. Here is the reward I promised you.', cid) + player:setStorageValue(Storage.QuestChests.StealFromThieves, 3) + player:addItem(2148, 100) + player:addItem(2789, 100) + npcHandler.topic[cid] = 0 + else + npcHandler:say('Come back when you find my stuff.', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 5 then + if (player:getStorageValue(Storage.ThreatenedDreams.TroubledMission01) == 2) then + if ( (player:getItemCount(28596) >= 1) and (player:getMoney() > 5000) )then + player:removeMoney(5000) + npcHandler:say({ + "Well then. Here, take the book, I added the story. Oh, just a piece of advice: Not to inflame prejudice but poachers are of rather simple disposition. I doubt they are ardent readers. ...", + "So if you want to make sure they read this anytime soon, perhaps don't hide the book in a shelf or chest. Make sure to place it somewhere where they will find it easily, like very obviously on a table or something." + }, cid) + player:setStorageValue(Storage.ThreatenedDreams.TroubledMission01, 3) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You need 5000 gps and book with ancient legends.", cid) + end + else + npcHandler:say("You have already completed this mission.", cid) + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ajax.lua b/data/npc/scripts/ajax.lua new file mode 100644 index 00000000000..08fe9d8b807 --- /dev/null +++ b/data/npc/scripts/ajax.lua @@ -0,0 +1,159 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.OutfitQuest.BarbarianAddon) == 1 or player:getStorageValue(Storage.OutfitQuest.BarbarianAddon) > 3 then + npcHandler:setMessage(MESSAGE_GREET, "Whatcha do in my place?") + elseif player:getStorageValue(Storage.OutfitQuest.BarbarianAddon) == 2 and player:getStorageValue(Storage.OutfitQuest.BarbarianAddonWaitTimer) < os.time() then + npcHandler:setMessage(MESSAGE_GREET, "You back. You know, you right. Brother is right. Fist not always good. Tell him that!") + player:setStorageValue(Storage.OutfitQuest.BarbarianAddon, 3) + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + -- PREQUEST + if msgcontains(msg, "mine") then + if player:getStorageValue(Storage.OutfitQuest.BarbarianAddon) == 1 then + npcHandler:say("YOURS? WHAT IS YOURS! NOTHING IS YOURS! IS MINE! GO AWAY, YES?!", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("YOU STUPID! STUBBORN! I KILL YOU! WILL LEAVE NOW?!", cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say("ARRRRRRRRRR! YOU ME DRIVE MAD! HOW I MAKE YOU GO??", cid) + npcHandler.topic[cid] = 3 + elseif npcHandler.topic[cid] == 3 then + npcHandler:say("I GIVE YOU NO!", cid) + npcHandler.topic[cid] = 4 + end + elseif msgcontains(msg, "please") then + if npcHandler.topic[cid] == 4 then + npcHandler:say("Please? What you mean please? Like I say please you say bye? Please?", cid) + npcHandler.topic[cid] = 5 + end + -- OUTFIT + elseif msgcontains(msg, "gelagos") then + if player:getStorageValue(Storage.OutfitQuest.BarbarianAddon) == 4 then + npcHandler:say("Annoying kid. Bro hates him, but talking no help. Bro needs {fighting spirit}!", cid) + npcHandler.topic[cid] = 6 + end + elseif msgcontains(msg, "fighting spirit") then + if npcHandler.topic[cid] == 6 then + npcHandler:say("If you want to help bro, bring him fighting spirit. Magic fighting spirit. Ask Djinn.", cid) + player:setStorageValue(Storage.OutfitQuest.BarbarianAddon, 5) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "present") then + if player:getStorageValue(Storage.OutfitQuest.BarbarianAddon) == 11 then + npcHandler:say("Bron gave me present. Ugly, but nice from him. Me want to give present too. You help me?", cid) + npcHandler.topic[cid] = 6 + end + elseif msgcontains(msg, "ore") then + if player:getStorageValue(Storage.OutfitQuest.BarbarianAddon) == 12 then + npcHandler:say("You bring 100 iron ore?", cid) + npcHandler.topic[cid] = 8 + end + elseif msgcontains(msg, "iron") then + if player:getStorageValue(Storage.OutfitQuest.BarbarianAddon) == 13 then + npcHandler:say("You bring crude iron?", cid) + npcHandler.topic[cid] = 9 + end + elseif msgcontains(msg, "fangs") then + if player:getStorageValue(Storage.OutfitQuest.BarbarianAddon) == 14 then + npcHandler:say("You bring 50 behemoth fangs?", cid) + npcHandler.topic[cid] = 10 + end + elseif msgcontains(msg, "leather") then + if player:getStorageValue(Storage.OutfitQuest.BarbarianAddon) == 15 then + npcHandler:say("You bring 50 lizard leather?", cid) + npcHandler.topic[cid] = 11 + end + elseif msgcontains(msg, "axe") then + if player:getStorageValue(Storage.OutfitQuest.BarbarianAddon) == 16 and player:getStorageValue(Storage.OutfitQuest.BarbarianAddonWaitTimer) < os.time() then + npcHandler:say("Axe is done! For you. Take. Wear like me.", cid) + player:setStorageValue(Storage.OutfitQuest.BarbarianAddon, 17) + player:addOutfitAddon(147, 1) + player:addOutfitAddon(143, 1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:addAchievement('Brutal Politeness') + else + npcHandler:say("Axe is not done yet!", cid) + end + -- OUTFIT + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 5 then + npcHandler:say("Oh. Easy. Okay. Please is good. Now don't say anything. Head aches. ", cid) + local condition = Condition(CONDITION_FIRE) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + condition:addDamage(10, 2000, -10) + player:addCondition(condition) + player:setStorageValue(Storage.OutfitQuest.BarbarianAddon, 2) + player:setStorageValue(Storage.OutfitQuest.BarbarianAddonWaitTimer, os.time() + 60 * 60) -- 1 hour + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + elseif npcHandler.topic[cid] == 6 then + npcHandler:say({ + "Good! Me make shiny weapon. If you help me, I make one for you too. Like axe I wear. I need stuff. Listen. ...", + "Me need 100 iron ore. Then need crude iron. Then after that 50 behemoth fangs. And 50 lizard leather. You understand?", + "Help me yes or no?" + }, cid) + npcHandler.topic[cid] = 7 + elseif npcHandler.topic[cid] == 7 then + npcHandler:say("Good. You get 100 iron ore first. Come back.", cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.OutfitQuest.BarbarianAddon, 12) + elseif npcHandler.topic[cid] == 8 then + if player:removeItem(5880, 100) then + npcHandler:say("Good! Now bring crude iron.", cid) + player:setStorageValue(Storage.OutfitQuest.BarbarianAddon, 13) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 9 then + if player:removeItem(5892, 1) then + npcHandler:say("Good! Now bring 50 behemoth fangs.", cid) + player:setStorageValue(Storage.OutfitQuest.BarbarianAddon, 14) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 10 then + if player:removeItem(5893, 50) then + npcHandler:say("Good! Now bring 50 lizard leather.", cid) + player:setStorageValue(Storage.OutfitQuest.BarbarianAddon, 15) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 11 then + if player:removeItem(5876, 50) then + npcHandler:say("Ah! All stuff there. I will start making axes now. Come later and ask me for axe.", cid) + player:setStorageValue(Storage.OutfitQuest.BarbarianAddon, 16) + player:setStorageValue(Storage.OutfitQuest.BarbarianAddonWaitTimer, os.time() + 2 * 60 * 60) -- 2 hours + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/al_dee.lua b/data/npc/scripts/al_dee.lua new file mode 100644 index 00000000000..d206f8a7ce4 --- /dev/null +++ b/data/npc/scripts/al_dee.lua @@ -0,0 +1,117 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Are you looking for the best trades? Come to my shop!' }, + { text = 'Feeling lost? You can always ask me about general hints!' }, + { text = 'Tools and general equipment at Al Dee\'s!' }, + { text = 'Don\'t head for adventure without a rope and torches! Buy your supplies here!' } +} +npcHandler:addModule(VoiceModule:new(voices)) + +-- Basic Keywords +keywordHandler:addKeyword({'hint'}, StdModule.rookgaardHints, {npcHandler = npcHandler}) +keywordHandler:addKeyword({'sell'}, StdModule.say, {npcHandler = npcHandler, text = 'Just ask me for a {trade} to see what I buy from you.'}) +keywordHandler:addKeyword({'stuff'}, StdModule.say, {npcHandler = npcHandler, text = 'Just ask me for a {trade} to see my offers.'}) +keywordHandler:addAliasKeyword({'wares'}) +keywordHandler:addAliasKeyword({'offer'}) +keywordHandler:addAliasKeyword({'buy'}) + +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'If you need general {equipment}, just ask me for a {trade}. I can also provide you with some general {hints} about the game.'}) +keywordHandler:addAliasKeyword({'information'}) + +keywordHandler:addKeyword({'equip'}, StdModule.say, {npcHandler = npcHandler, text = 'As an adventurer, you should always have at least a {backpack}, a {rope}, a {shovel}, a {weapon}, an {armor} and a {shield}.'}) +keywordHandler:addAliasKeyword({'tools'}) + +keywordHandler:addKeyword({'how', 'are', 'you'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m fine. I\'m so glad to have you here as my customer.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m a merchant. Just ask me for a {trade} to see my offers.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Al Dee, but you can call me Al. Can I interest you in a {trade}?'}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = 'It\'s about |TIME|. I\'m so sorry, I have no watches to sell. Do you want to buy something else?'}) +keywordHandler:addKeyword({'monster'}, StdModule.say, {npcHandler = npcHandler, text = 'If you want to challenge monsters in the {dungeons}, you need some {weapons} and {armor} from the local {merchants}.'}) +keywordHandler:addKeyword({'dungeon'}, StdModule.say, {npcHandler = npcHandler, text = 'If you want to explore the dungeons such as the {sewers}, you have to {equip} yourself with the vital stuff I am selling. It\'s {vital} in the deepest sense of the word.'}) +keywordHandler:addKeyword({'sewer'}, StdModule.say, {npcHandler = npcHandler, text = 'Oh, our sewer system is very primitive - it\'s so primitive that it\'s overrun by {rats}. But the stuff I sell is safe from them. Just ask me for a {trade} to see it!'}) +keywordHandler:addKeyword({'king'}, StdModule.say, {npcHandler = npcHandler, text = 'The king encouraged salesmen to travel here, but only I dared to take the risk, and a risk it was!'}) +keywordHandler:addKeyword({'bug'}, StdModule.say, {npcHandler = npcHandler, text = 'Bugs plague this isle, but my wares are bug-free, totally bug-free.'}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = 'One day I will return to the continent as a rich, a very rich man!'}) +keywordHandler:addKeyword({'thais'}, StdModule.say, {npcHandler = npcHandler, text = 'Thais is a crowded town.'}) +keywordHandler:addKeyword({'mainland'}, StdModule.say, {npcHandler = npcHandler, text = 'Have you ever wondered what that \'main\' is people are talking about? Well, once you\'ve reached level 8, you should talk to the {oracle}. You can choose a {profession} afterwards and explore much more of Tibia.'}) +keywordHandler:addKeyword({'weapon'}, StdModule.say, {npcHandler = npcHandler, text = 'Oh, I\'m sorry, but I don\'t deal with weapons. That\'s {Obi\'s} or {Lee\'Delle\'s} business. I could offer you a {pick} in exchange for a {small axe} if you should happen to own one.'}) +keywordHandler:addKeyword({'armor'}, StdModule.say, {npcHandler = npcHandler, text = 'Armor and shields can be bought at {Dixi\'s} or at {Lee\'Delle\'s}. Dixi runs that shop near {Obi\'s}.'}) +keywordHandler:addKeyword({'shield'}, StdModule.say, {npcHandler = npcHandler, text = 'Armor and shields can be bought at {Dixi\'s} or at {Lee\'Delle\'s}. Dixi runs that shop near {Obi\'s}.'}) +keywordHandler:addKeyword({'cooki'}, StdModule.say, {npcHandler = npcHandler, text = 'I you want to find someone who may want to buy your cookies, you should meet Lily.'}) +keywordHandler:addKeyword({'blueberr'}, StdModule.say, {npcHandler = npcHandler, text = 'Blueberries grow on bushes. They\'re quite common in Tibia. Just pick them from a bush if you need a snack!'}) +keywordHandler:addKeyword({'potion'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, I don\'t sell potions. You should visit {Lily} for that.'}) +keywordHandler:addKeyword({'food'}, StdModule.say, {npcHandler = npcHandler, text = 'Hmm, the best address to look for food might be {Willie} or {Billy}. {Norma} also has some snacks for sale.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'A bank is quite useful. You can deposit your money safely there. This way you don\'t have to carry it around with you all the time. You could also invest your money in my {wares}!'}) +keywordHandler:addKeyword({'academy'}, StdModule.say, {npcHandler = npcHandler, text = 'The big building in the centre of Rookgaard. They have a library, a training centre, a {bank} and the room of the {oracle}. {Seymour} is the teacher there.'}) +keywordHandler:addKeyword({'temple'}, StdModule.say, {npcHandler = npcHandler, text = 'The monk {Cipfried} takes care of our temple. He can heal you if you\'re badly injured or poisoned.'}) +keywordHandler:addKeyword({'premium'}, StdModule.say, {npcHandler = npcHandler, text = 'As a premium adventurer you have many advantages. You really should check them out!'}) +keywordHandler:addKeyword({'citizen'}, StdModule.say, {npcHandler = npcHandler, text = 'If you tell me the name of a citizen, I\'ll tell you what I know about him or her.'}) +keywordHandler:addKeyword({'merchant'}, StdModule.say, {npcHandler = npcHandler, text = 'To view the offers of a merchant, simply talk to him or her and ask for a {trade}. They will gladly show you their offers and also the things they buy from you.'}) +keywordHandler:addKeyword({'profession'}, StdModule.say, {npcHandler = npcHandler, text = 'You will learn everything you need to know about professions once you\'ve reached the {Island of Destiny}.'}) +keywordHandler:addKeyword({'destiny'}, StdModule.say, {npcHandler = npcHandler, text = 'The Island of Destiny can be reached via the {oracle} once you are level 8. This trip will help you choose your {profession}!'}) + +keywordHandler:addKeyword({'torch'}, StdModule.say, {npcHandler = npcHandler, text = 'No thank you. I can already overstock the market with torches.'}) +keywordHandler:addKeyword({'fishing'}, StdModule.say, {npcHandler = npcHandler, text = 'I sell fishing rods and worms if you want to fish. Simply ask me for a {trade}.'}) +keywordHandler:addKeyword({'shovel'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes, I am selling that. Simply ask me for a {trade} to view all my offers.'}) +keywordHandler:addAliasKeyword({'rope'}) +keywordHandler:addAliasKeyword({'backpack'}) + +-- Names +keywordHandler:addKeyword({'cipfried'}, StdModule.say, {npcHandler = npcHandler, text = 'He is just an old monk. However, he can heal you if you are badly injured or poisoned.'}) +keywordHandler:addKeyword({'zirella'}, StdModule.say, {npcHandler = npcHandler, text = 'Poor old woman, her son {Tom} never visits her.'}) +keywordHandler:addKeyword({'santiago'}, StdModule.say, {npcHandler = npcHandler, text = 'He dedicated his life to welcome newcomers to this island.'}) +keywordHandler:addKeyword({'loui'}, StdModule.say, {npcHandler = npcHandler, text = 'No idea who that is.'}) +keywordHandler:addKeyword({'al', 'dee'}, StdModule.say, {npcHandler = npcHandler, text = 'Yep, that\'s me. Smart of you to notice that!'}) +keywordHandler:addKeyword({'paulie'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s the local {bank} clerk.'}) +keywordHandler:addKeyword({'hyacinth'}, StdModule.say, {npcHandler = npcHandler, text = 'He mostly stays by himself. He\'s a hermit outside of town - good luck finding him.'}) +keywordHandler:addKeyword({'dixi'}, StdModule.say, {npcHandler = npcHandler, text = 'She\'s {Obi\'s} granddaughter and deals with {armors} and {shields}. Her shop is south west of town, close to the {temple}.'}) +keywordHandler:addKeyword({'obi'}, StdModule.say, {npcHandler = npcHandler, text = 'He sells {weapons}. His shop is south west of town, close to the {temple}.'}) +keywordHandler:addKeyword({'lee\'delle'}, StdModule.say, {npcHandler = npcHandler, text = 'If you are a {premium} adventurer, you should check out {Lee\'Delle\'s} shop. She lives in the western part of town, just across the bridge.'}) +keywordHandler:addKeyword({'tom'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s the local tanner. You could try selling fresh corpses or leather to him.'}) +keywordHandler:addKeyword({'amber'}, StdModule.say, {npcHandler = npcHandler, text = 'She\'s currently recovering from her travels in the {academy}. It\'s always nice to chat with her!'}) +keywordHandler:addKeyword({'oracle'}, StdModule.say, {npcHandler = npcHandler, text = 'You can find the oracle on the top floor of the {academy}, just above {Seymour}. Go there when you are level 8.'}) +keywordHandler:addKeyword({'seymour'}, StdModule.say, {npcHandler = npcHandler, text = 'Seymour is a teacher running the {academy}. He has many important {information} about Tibia.'}) +keywordHandler:addKeyword({'lily'}, StdModule.say, {npcHandler = npcHandler, text = 'She sells health {potions} and antidote potions. Also, she buys {blueberries} and {cookies} in case you find any.'}) +keywordHandler:addKeyword({'willie'}, StdModule.say, {npcHandler = npcHandler, text = 'This is a local farmer. If you need fresh {food} to regain your health, it\'s a good place to go. However, many monsters also carry food such as meat or cheese. Or you could simply pick {blueberries}.'}) +keywordHandler:addKeyword({'billy'}, StdModule.say, {npcHandler = npcHandler, text = 'This is a local farmer. If you need fresh {food} to regain your health, it\'s a good place to go. He\'s only trading with {premium} adventurers though.'}) +keywordHandler:addKeyword({'norma'}, StdModule.say, {npcHandler = npcHandler, text = 'She used to sell equipment, but I think she has opened a small bar now. Talks about changing her name to \'Mary\' and such, strange girl.'}) +keywordHandler:addKeyword({'zerbrus'}, StdModule.say, {npcHandler = npcHandler, text = 'Some call him a hero. He protects the town from {monsters}.'}) +keywordHandler:addAliasKeyword({'dallheim'}) + +-- Pick quest +local pickKeyword = keywordHandler:addKeyword({'pick'}, StdModule.say, {npcHandler = npcHandler, text = 'Picks are hard to come by. I trade them only in exchange for high quality small axes. Would you like to make that deal?'}) + pickKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Splendid! Here, take your pick.', reset = true}, + function(player) return player:getItemCount(2559) > 0 end, + function(player) + player:removeItem(2559, 1) + player:addItem(2553, 1) + end + ) + pickKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, I am looking for a SMALL axe.', reset = true}) + pickKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Well, then don\'t.', reset = true}) +keywordHandler:addAliasKeyword({'small', 'axe'}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Bye, bye.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Bye, bye |PLAYERNAME|.') +npcHandler:setMessage(MESSAGE_SENDTRADE, 'Take a look in the trade window to your left.') +npcHandler:setMessage(MESSAGE_GREET, { + 'Hello, hello, |PLAYERNAME|! Please come in, look, and buy! I\'m a specialist for all sorts of {tools}. Just ask me for a {trade} to see my offers! You can also ask me for general {hints} about the game. ...', + 'You can also ask me about each {citizen} of the isle.' +}) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/alaistar.lua b/data/npc/scripts/alaistar.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/alaistar.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/albert.lua b/data/npc/scripts/albert.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/albert.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/albinius.lua b/data/npc/scripts/albinius.lua new file mode 100644 index 00000000000..a4227b5f196 --- /dev/null +++ b/data/npc/scripts/albinius.lua @@ -0,0 +1,242 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) +local talkState = {} + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "I am Albinius, a worshipper of the {Astral Shapers}."}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = "Precisely time."}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I find ways to unveil the secrets of the stars. Judging by this question, I doubt you follow my weekly publications concerning this research."}) + +local runes = { + {runeid = 27622}, + {runeid = 27623}, + {runeid = 27624}, + {runeid = 27625}, + {runeid = 27626}, + {runeid = 27627} +} + +local function getTable() + local itemsList = { + {name = "heavy old tome", id = 26654, sell = 30} + } + return itemsList +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "shapers") then + npcHandler:say({ + "The {Shapers} were an advanced civilisation, well versed in art, construction, language and exploration of our world in their time. ...", + "The foundations of this {temple} are testament to their genius and advanced understanding of complex problems. They were master craftsmen and excelled in magic." + }, cid) + end + + if msgcontains(msg, 'temple') then + npcHandler:say({ + "The temple has been restored to its former glory, yet we strife to live and praise in the {Shaper} ways. Do you still need me to take some old {tomes} from you my child?" + }, cid) + npcHandler.topic[cid] = 1 + end + if msgcontains(msg, "yes") and npcHandler.topic[cid] == 1 then + if (player:getStorageValue(Storage.ForgottenKnowledge.Tomes) == 1) then + npcHandler:say('You already offered enough tomes for us to study and rebuild this temple. Thank you, my child.', cid) + npcHandler.topic[cid] = 0 + else + if (player:getItemCount(26654) >= 5) then + player:removeItem(26654, 5) + npcHandler:say('Thank you very much for your contribution, child. Your first step in the ways of the {Shapers} has been taken.', cid) + player:setStorageValue(Storage.ForgottenKnowledge.Tomes, 1) + else + npcHandler:say('You need 5 heavy old tome.', cid) + end + end + elseif msgcontains(msg, "no") and npcHandler.topic[cid] == 1 then + npcHandler:say('I understand. Return to me if you change your mind, my child.', cid) + npcHandler:releaseFocus(cid) + end + + if msgcontains(msg, 'tomes') and player:getStorageValue(Storage.ForgottenKnowledge.Tomes) < 1 then + npcHandler:say({ + "If you have some old shaper tomes I would {buy} them." + }, cid) + npcHandler.topic[cid] = 7 + end + + if msgcontains(msg, 'buy') then + npcHandler:say("I'm sorry, I don't buy anything. My main concern right now is the bulding of this temple.", cid) + openShopWindow(cid, getTable(), onBuy, onSell) + end + + --- ##Astral Shaper Rune## + if msgcontains(msg, 'astral shaper rune') then + if player:getStorageValue(Storage.ForgottenKnowledge.LastLoreKilled) >= 1 then + npcHandler:say('Do you wish to merge your rune parts into an astral shaper rune?', cid) + npcHandler.topic[cid] = 8 + else + npcHandler:say("I'm sorry but you lack the needed rune parts.", cid) + end + end + + if msgcontains(msg, 'yes') and npcHandler.topic[cid] == 8 then + local haveParts = false + for k = 1, #runes do + if player:removeItem(runes[k].runeid, 1) then + haveParts = true + end + end + if haveParts then + npcHandler:say('As you wish.', cid) + player:addItem(27628, 1) + npcHandler:releaseFocus(cid) + end + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] == 8 then + npcHandler:say('ok.', cid) + npcHandler:releaseFocus(cid) + end + + --- ####PORTALS### + -- Ice Portal + if msgcontains(msg, 'ice portal') then + if player:getStorageValue(Storage.ForgottenKnowledge.Tomes) == 1 then + npcHandler:say({ + "You may pass this portal if you have 50 fish as offering. Do you have the fish with you?" + }, cid) + npcHandler.topic[cid] = 2 + else + npcHandler:say('Sorry, first you need to bring my Heavy Old Tomes.', cid) + end + end + + if msgcontains(msg, 'yes') and npcHandler.topic[cid] == 2 then + if player:getStorageValue(Storage.ForgottenKnowledge.AccessIce) < 1 and player:getItemCount(2667) >= 50 then + player:removeItem(2667, 50) + npcHandler:say('Thank you for your offering. You may pass the Portal to the Powers of Ice now.', cid) + player:setStorageValue(Storage.ForgottenKnowledge.AccessIce, 1) + else + npcHandler:say("I'm sorry, you don't have enough fish. Return if you can offer fifty of them.", cid) + end + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] == 2 then + npcHandler:say("In this case I'm sorry, you may not pass this portal.", cid) + end + + -- Holy Portal + if msgcontains(msg, 'holy portal') then + if player:getStorageValue(Storage.ForgottenKnowledge.Tomes) == 1 then + npcHandler:say({ + "You may pass this portal if you have 50 incantation notes as offering. Do you have the incantation notes with you?" + }, cid) + npcHandler.topic[cid] = 3 + else + npcHandler:say('Sorry, first you need to bring my Heavy Old Tomes.', cid) + end + end + + if msgcontains(msg, 'yes') and npcHandler.topic[cid] == 3 then + if player:getStorageValue(Storage.ForgottenKnowledge.AccessGolden) < 1 and player:getItemCount(21246) >= 50 then + player:removeItem(21246, 50) + npcHandler:say('Thank you for your offering. You may pass the Portal to the Powers of Holy now.', cid) + player:setStorageValue(Storage.ForgottenKnowledge.AccessGolden, 1) + else + npcHandler:say("I'm sorry, you don't have enough incantation notes. Return if you can offer fifty of them.", cid) + end + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] == 3 then + npcHandler:say("In this case I'm sorry, you may not pass this portal.", cid) + end + + -- Energy Portal + if msgcontains(msg, 'energy portal') then + if player:getStorageValue(Storage.ForgottenKnowledge.Tomes) == 1 then + npcHandler:say({ + "You may pass this portal if you have 50 marsh stalker feathers as offering. Do you have the marsh stalker feathers with you?" + }, cid) + npcHandler.topic[cid] = 4 + else + npcHandler:say('Sorry, first you need to bring my Heavy Old Tomes.', cid) + end + end + + if msgcontains(msg, 'yes') and npcHandler.topic[cid] == 4 then + if player:getStorageValue(Storage.ForgottenKnowledge.AccessViolet) < 1 and player:getItemCount(19742) >= 50 then + player:removeItem(19742, 50) + npcHandler:say('Thank you for your offering. You may pass the Portal to the Powers of Energy now.', cid) + player:setStorageValue(Storage.ForgottenKnowledge.AccessViolet, 1) + else + npcHandler:say("I'm sorry, you don't have enough marsh stalker feathers. Return if you can offer fifty of them.", cid) + end + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] == 4 then + npcHandler:say("In this case I'm sorry, you may not pass this portal.", cid) + end + + -- Earth Portal + if msgcontains(msg, 'earth portal') then + if player:getStorageValue(Storage.ForgottenKnowledge.Tomes) == 1 then + npcHandler:say({ + "You may pass this portal if you have 50 acorns as offering. Do you have the acorns with you?" + }, cid) + npcHandler.topic[cid] = 5 + else + npcHandler:say('Sorry, first you need to bring my Heavy Old Tomes.', cid) + end + end + + if msgcontains(msg, 'yes') and npcHandler.topic[cid] == 5 then + if player:getStorageValue(Storage.ForgottenKnowledge.AccessEarth) < 1 and player:getItemCount(11213) >= 50 then + player:removeItem(11213, 50) + npcHandler:say('Thank you for your offering. You may pass the Portal to the Powers of Earth now.', cid) + player:setStorageValue(Storage.ForgottenKnowledge.AccessEarth, 1) + else + npcHandler:say("I'm sorry, you don't have enough acorns. Return if you can offer fifty of them.", cid) + end + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] == 5 then + npcHandler:say("In this case I'm sorry, you may not pass this portal.", cid) + end + + -- Death Portal + if msgcontains(msg, 'death portal') then + if player:getStorageValue(Storage.ForgottenKnowledge.Tomes) == 1 then + npcHandler:say({ + "You may pass this portal if you have 50 pelvis bones as offering. Do you have the pelvis bones with you?" + }, cid) + npcHandler.topic[cid] = 6 + else + npcHandler:say('Sorry, first you need to bring my Heavy Old Tomes.', cid) + end + end + + if msgcontains(msg, 'yes') and npcHandler.topic[cid] == 6 then + if player:getStorageValue(Storage.ForgottenKnowledge.AccessDeath) < 1 and player:getItemCount(12437) >= 50 then + player:removeItem(12437, 50) + npcHandler:say('Thank you for your offering. You may pass the Portal to the Powers of Death now.', cid) + player:setStorageValue(Storage.ForgottenKnowledge.AccessDeath, 1) + else + npcHandler:say("I'm sorry, you don't have enough pelvis bones. Return if you can offer fifty of them.", cid) + end + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] == 6 then + npcHandler:say("In this case I'm sorry, you may not pass this portal.", cid) + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Greetings, pilgrim. Welcome to the halls of hope. We are the keepers of this {temple} and welcome everyone willing to contribute.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Oh... farewell, child.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/aldo.lua b/data/npc/scripts/aldo.lua new file mode 100644 index 00000000000..57c7f70e782 --- /dev/null +++ b/data/npc/scripts/aldo.lua @@ -0,0 +1,52 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if isInArray({"soft boots", "repair", "soft", "boots"}, msg) then + npcHandler:say("Do you want to repair your worn soft boots for 10000 gold coins?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, 'yes') and npcHandler.topic[cid] == 1 then + npcHandler.topic[cid] = 0 + if player:getItemCount(10021) == 0 then + npcHandler:say("Sorry, you don't have the item.", cid) + return true + end + + if not player:removeMoneyNpc(10000) then + npcHandler:say("Sorry, you don't have enough gold.", cid) + return true + end + + player:removeItem(10021, 1) + player:addItem(6132, 1) + npcHandler:say("Here you are.", cid) + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] == 1 then + npcHandler.topic[cid] = 0 + npcHandler:say("Ok then.", cid) + + + end + + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/alesar.lua b/data/npc/scripts/alesar.lua new file mode 100644 index 00000000000..4267c335f68 --- /dev/null +++ b/data/npc/scripts/alesar.lua @@ -0,0 +1,108 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + local missionProgress = player:getStorageValue(Storage.DjinnWar.EfreetFaction.Mission02) + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.DjinnWar.EfreetFaction.Mission01) == 3 then + if missionProgress < 1 then + npcHandler:say({ + "So Baa'leal thinks you are up to do a mission for us? ...", + "I think he is getting old, entrusting human scum such as you are with an important mission like that. ...", + "Personally, I don't understand why you haven't been slaughtered right at the gates. ...", + "Anyway. Are you prepared to embark on a dangerous mission for us?" + }, cid) + npcHandler.topic[cid] = 1 + + elseif isInArray({1, 2}, missionProgress) then + npcHandler:say("Did you find the tear of Daraman?", cid) + npcHandler.topic[cid] = 2 + else + npcHandler:say("Don't forget to talk to Malor concerning your next mission.", cid) + end + end + + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, "yes") then + npcHandler:say({ + "All right then, human. Have you ever heard of the {'Tears of Daraman'}? ...", + "They are precious gemstones made of some unknown blue mineral and possess enormous magical power. ...", + "If you want to learn more about these gemstones don't forget to visit our library. ...", + "Anyway, one of them is enough to create thousands of our mighty djinn blades. ...", + "Unfortunately my last gemstone broke and therefore I'm not able to create new blades anymore. ...", + "To my knowledge there is only one place where you can find these gemstones - I know for a fact that the Marid have at least one of them. ...", + "Well... to cut a long story short, your mission is to sneak into Ashta'daramai and to steal it. ...", + "Needless to say, the Marid won't be too eager to part with it. Try not to get killed until you have delivered the stone to me." + }, cid) + player:setStorageValue(Storage.DjinnWar.EfreetFaction.Mission02, 1) + player:setStorageValue(Storage.DjinnWar.EfreetFaction.DoorToMaridTerritory, 1) + + elseif msgcontains(msg, "no") then + npcHandler:say("Then not.", cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, "yes") then + if player:getItemCount(2346) == 0 or missionProgress ~= 2 then + npcHandler:say("As I expected. You haven't got the stone. Shall I explain your mission again?", cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say({ + "So you have made it? You have really managed to steal a Tear of Daraman? ...", + "Amazing how you humans are just impossible to get rid of. Incidentally, you have this character trait in common with many insects and with other vermin. ...", + "Nevermind. I hate to say it, but it you have done us a favour, human. That gemstone will serve us well. ...", + "Baa'leal, wants you to talk to Malor concerning some new mission. ...", + "Looks like you have managed to extended your life expectancy - for just a bit longer." + }, cid) + player:removeItem(2346, 1) + player:setStorageValue(Storage.DjinnWar.EfreetFaction.Mission02, 3) + npcHandler.topic[cid] = 0 + end + + elseif msgcontains(msg, "no") then + npcHandler:say("As I expected. You haven't got the stone. Shall I explain your mission again?", cid) + npcHandler.topic[cid] = 1 + end + end + return true +end + +local function onTradeRequest(cid) + local player = Player(cid) + if player:getStorageValue(Storage.DjinnWar.EfreetFaction.Mission03) ~= 3 then + npcHandler:say("I'm sorry, but you don't have Malor's permission to trade with me.", cid) + return false + end + + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "What do you want from me, |PLAYERNAME|?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Finally.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Finally.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "At your service, just browse through my wares.") + +npcHandler:setCallback(CALLBACK_ONTRADEREQUEST, onTradeRequest) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/alexander.lua b/data/npc/scripts/alexander.lua new file mode 100644 index 00000000000..f4c20ab59ba --- /dev/null +++ b/data/npc/scripts/alexander.lua @@ -0,0 +1,65 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Selling all sorts of magic equipment. Come and have a look'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local items = { + [VOCATION.CLIENT_ID.SORCERER] = 2190, + [VOCATION.CLIENT_ID.DRUID] = 2182 +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'first rod') or msgcontains(msg, 'first wand') then + if player:isMage() then + local itemId = items[player:getVocation():getClientId()] + if player:getStorageValue(Storage.firstMageWeapon) == -1 then + npcHandler:say('So you ask me for a {' .. ItemType(itemId):getName() .. '} to begin your adventure?', cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say('What? I have already gave you one {' .. ItemType(itemId):getName() .. '}!', cid) + end + else + npcHandler:say('Sorry, you aren\'t a druid either a sorcerer.', cid) + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + player:addItem(itemId, 1) + npcHandler:say('Here you are young adept, take care yourself.', cid) + player:setStorageValue(Storage.firstMageWeapon, 1) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] == 1 then + npcHandler:say('Ok then.', cid) + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'magic'}, StdModule.say, {npcHandler = npcHandler, text = "I'm selling runes, life rings, wands, rods and crystal balls. I also buy powerful spellbooks. If you like to see my offers, ask me for a {trade}."}) + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "Hi there |PLAYERNAME|, and welcome to the {magic} store.") +npcHandler:setMessage(MESSAGE_FAREWELL, "See you, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "See you, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Of course, just browse through my wares. Or do you want to look only at {runes} or {wands}?") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/alia.lua b/data/npc/scripts/alia.lua new file mode 100644 index 00000000000..98d74790c50 --- /dev/null +++ b/data/npc/scripts/alia.lua @@ -0,0 +1,95 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Twist of Fate +local blessKeyword = keywordHandler:addKeyword({'twist of fate'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'This is a special blessing I can bestow upon you once you have obtained at least one of the other blessings and which functions a bit differently. ...', + 'It only works when you\'re killed by other adventurers, which means that at least half of the damage leading to your death was caused by others, not by monsters or the environment. ...', + 'The {twist of fate} will not reduce the death penalty like the other blessings, but instead prevent you from losing your other blessings as well as the amulet of loss, should you wear one. It costs the same as the other blessings. ...', + 'Would you like to receive that protection for a sacrifice of |PVPBLESSCOST| gold, child?' + }}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the protection of the twist of fate, pilgrim.', cost = '|PVPBLESSCOST|', bless = 1}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Adventurer Stone +keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Keep your adventurer\'s stone well.'}, function(player) return player:getItemById(18559, true) end) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for free?'}, function(player) return player:getStorageValue(Storage.AdventurersGuild.FreeStone.Alia) ~= 1 end) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, nil, function(player) player:addItem(18559, 1) player:setStorageValue(Storage.AdventurersGuild.FreeStone.Alia, 1) end) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for 30 gold?'}) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, + function(player) return player:getMoney() + player:getBankBalance() >= 30 end, + function(player) if player:removeMoneyNpc(30) then player:addItem(18559, 1) end end + ) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, you don\'t have enough money.', reset = true}) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.'}, function(player) return player:hasBlessing(2) end) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin will provide you with the embrace of Tibia.'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, young |PLAYERNAME|! If you are heavily wounded or poisoned, I can {heal} you for free.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Remember: If you are heavily wounded or poisoned, I can heal you for free.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'May the gods bless you, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/alissa.lua b/data/npc/scripts/alissa.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/alissa.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/alkestios.lua b/data/npc/scripts/alkestios.lua new file mode 100644 index 00000000000..8fa965ffbba --- /dev/null +++ b/data/npc/scripts/alkestios.lua @@ -0,0 +1,90 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "mission") then + if (player:getStorageValue(Storage.ThreatenedDreams.TroubledMission01) == 4) then + npcHandler:say({ + "You succeeded! It seems the poachers have read your little faked story about killing white deer and the ensuing doom. They stopped chasing me. Thank you! ...", + "You proved yourself trustworthy - at least as far as I am concerned. But as I told you I'm actually not a real animal. If you want to enter our hidden island, you must prove that you are also willing to help real animals. Would you do that?" + }, cid) + npcHandler.topic[cid] = 2 + elseif (player:getStorageValue(Storage.ThreatenedDreams.TroubledMission01) == 16) then + npcHandler:say({ + "I'm very happy that you could help fae and animals alike. You earned our trust and may now visit our secret realm. I marked you with an arcane fae seal. Hereby you will be able to use the elemental shrines strewn about Tibia. ...", + "There are fire, ice, energy and earth shrines. If you don't know their locations you can also reach them by most temples in this world. The elemental shrines will transport you to Feyrist now that you bear the magical seal." + }, cid) + player:setStorageValue(Storage.ThreatenedDreams.TroubledMission01, 17) + else + npcHandler:say({ + "I indeed have some troubles since I'm travelling this part of the world. When I took over the body of a white deer I wasn't aware that such an animal is a sought after quarry for hunters and poachers. ...", + "Now I'm living in the constant danger of being caught and killed. Of course, I could just take over another animal but this deer has really grown on me. I'd like to help this beautiful stag but I need your assistance. Are you willing to help me?" + }, cid) + npcHandler.topic[cid] = 1 + end + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, "yes") then + if (player:getStorageValue(Storage.ThreatenedDreams.Start) == 1) then + npcHandler:say("You have already started this mission.", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say({ + "Your decision honours you. However, if you consider killing the poachers in question I ask you to halt. We, the fae, are rather peaceful beings and abhor bloodshed. Therefore, we must find another way to solve this problem. ...", + "I already have an idea: Some birds told me that poachers are a superstitious lot. Perhaps we can get them with their own misbelief. I know that the poachers have a kind of camp north of the Green Claw Swamps. ...", + "Please search it out and examine it closely. Perhaps you will find something you can use against them in order to stop them from hunting white deer." + }, cid) + player:setStorageValue(Storage.ThreatenedDreams.Start, 1) + player:setStorageValue(Storage.ThreatenedDreams.TroubledMission01, 1) + end + elseif msgcontains(msg, "no") then + npcHandler:say("Then not.", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say({ + "I heard there is a problem with a wolf mother and her whelps. However, I don't know more about it. One of my sisters, Ikassis, has taken over the body of a snake. ...", + "She knows more about the wolf. Seek her out in the north-west of Edron, near a circle of standing stones." + }, cid) + player:setStorageValue(Storage.ThreatenedDreams.TroubledMission01, 5) + end + return true +end + +keywordHandler:addKeyword({'deer'}, StdModule.say, {npcHandler = npcHandler, text = "Outside of our secret {realm} my siblings and I can't keep our true shape. If we want to travel other parts of the world, we must take over the bodies of animals. But we are causing them no harm and we just take control if necessary."}) +keywordHandler:addKeyword({'realm'}, StdModule.say, {npcHandler = npcHandler, text = "We call it Feyrist and it is a secret, hidden place. Just few mortals get permission to enter it. A long time ago, we learned how to hide our realm from the outside world. Only if you gain our trust I will tell you how to reach it."}) +keywordHandler:addKeyword({'siblings'}, StdModule.say, {npcHandler = npcHandler, text = "We call ourselves the fae. Some name us nature spirits or peri but we prefer the former term. Most of us are rather reclusive and live peaceful lives in our secret realm. We only leave it in order to {protect} our home. ..."}) +keywordHandler:addKeyword({'kind'}, StdModule.say, {npcHandler = npcHandler, text = "We call ourselves the fae. Some name us nature spirits or peri but we prefer the former term. Most of us are rather reclusive and live peaceful lives in our secret realm. We only leave it in order to {protect} our home. ..."}) +keywordHandler:addKeyword({'protect'}, StdModule.say, {npcHandler = npcHandler, text = "I can sense a kind of dark energy lately. It is pervading this world, more and more every day. Yet I don't know where it arises from nor what we could do to dispel it."}) +keywordHandler:addKeyword({'energy'}, StdModule.say, {npcHandler = npcHandler, text = "It is rather subversive, so most creatures won't sense it ... yet. But its corrosive power has already begun to affect my kind and our hidden realm in unpleasant ways."}) +keywordHandler:addKeyword({'fae'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'Some call us nature spirits or peri but we prefer the term fae. Most of us are rather reclusive and live peaceful lives in our secret realm. We only leave it in order to protect our home. ...', + 'We tend to be secretive about our true nature, but I guess there was once an elven sage who visited our realm and put his experiences down on paper. There might be a book about the fae in the library of Ab\'Dendriel.' + }} +) + +npcHandler:setMessage(MESSAGE_GREET, "Nature's blessing, traveller! |PLAYERNAME|!") +npcHandler:setMessage(MESSAGE_FAREWELL, "May your path always be even.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "May your path always be even.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/allen.lua b/data/npc/scripts/allen.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/allen.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/alternative_rock.lua b/data/npc/scripts/alternative_rock.lua new file mode 100644 index 00000000000..368c0f144d8 --- /dev/null +++ b/data/npc/scripts/alternative_rock.lua @@ -0,0 +1,37 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +--local voices = { {text = 'Passages to Tibia, Folda and Vega.'} } +--npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +--local function addTravelKeyword(keyword, text, cost, destination) +-- local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you want to sail ' .. text, cost = cost}) + -- travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, destination = destination}) + -- travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +--end + +--addTravelKeyword('tibia', 'back to Tibia?', 0, Position(32235, 31674, 7)) +--addTravelKeyword('vega', 'to Vega for |TRAVELCOST|?', 10, Position(32020, 31692, 7)) +--addTravelKeyword('folda', 'to Folda for |TRAVELCOST|?', 10, Position(32046, 31578, 7)) + +-- Basic +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'Find the Golden Anchor and click there, after talk with Navigator.'}) +--keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) +--keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/alwin.lua b/data/npc/scripts/alwin.lua new file mode 100644 index 00000000000..e160dd39add --- /dev/null +++ b/data/npc/scripts/alwin.lua @@ -0,0 +1,38 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(10, 1000, -10) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if isInArray({"fuck", "idiot", "asshole", "ass", "fag", "stupid", "tyrant", "shit", "lunatic"}, msg) then + npcHandler:say("Take this!", cid) + local player = Player(cid) + player:getPosition():sendMagicEffect(CONST_ME_EXPLOSIONAREA) + player:addCondition(condition) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/alyxo.lua b/data/npc/scripts/alyxo.lua new file mode 100644 index 00000000000..df631ea4807 --- /dev/null +++ b/data/npc/scripts/alyxo.lua @@ -0,0 +1,185 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.Kilmaresh.First.Access) < 1 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + npcHandler.topic[cid] = 1 + elseif (player:getStorageValue(Storage.Kilmaresh.First.JamesfrancisTask) >= 0 and player:getStorageValue(Storage.Kilmaresh.First.JamesfrancisTask) <= 50) + and player:getStorageValue(Storage.Kilmaresh.First.Mission) < 3 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + npcHandler.topic[cid] = 15 + elseif player:getStorageValue(Storage.Kilmaresh.First.Mission) == 4 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + player:setStorageValue(Storage.Kilmaresh.First.Mission, 5) + npcHandler.topic[cid] = 20 + end + npcHandler:addFocus(cid) + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + -- Mission 3 Steal The Ambassador Ring + if msgcontains(msg, "mission") and player:getStorageValue(Storage.Kilmaresh.Twelve.Boss) == 1 then + if player:getStorageValue(Storage.Kilmaresh.Twelve.Boss) == 1 then + npcHandler:say({"Could you kill 3 bosses for me?"}, cid) -- needs review, this is not the speech of the global + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 1 and player:getStorageValue(Storage.Kilmaresh.Twelve.Boss) == 1 then + if player:getStorageValue(Storage.Kilmaresh.Twelve.Boss) == 1 then + npcHandler:say({"Come back as soon as you kill all 3 bosses."}, cid) -- needs review, this is not the speech of the global + player:setStorageValue(Storage.Kilmaresh.Twelve.Boss, 2) + player:setStorageValue(Storage.Kilmaresh.Twelve.Bragrumol, 1) + player:setStorageValue(Storage.Kilmaresh.Twelve.Mozradek, 1) + player:setStorageValue(Storage.Kilmaresh.Twelve.Xogixath, 1) + npcHandler.topic[cid] = 2 + else + npcHandler:say({"Sorry."}, cid) + npcHandler.topic[cid] = 0 + end + end + -- Mission 3 Steal The Ambassador Ring + if msgcontains(msg, "mission") and player:getStorageValue(Storage.Kilmaresh.Twelve.Boss) == 2 then + if player:getStorageValue(Storage.Kilmaresh.Twelve.Boss) == 2 then + npcHandler:say({"Did you manage to face all 3 bosses?"}, cid)-- needs review, this is not the speech of the global + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 3 and player:getStorageValue(Storage.Kilmaresh.Twelve.Boss) == 2 then + if player:getStorageValue(Storage.Kilmaresh.Twelve.Bragrumol) == 2 and player:getStorageValue(Storage.Kilmaresh.Twelve.Mozradek) == 2 and player:getStorageValue(Storage.Kilmaresh.Twelve.Xogixath) == 2 then + npcHandler:say({"I am very satisfied."}, cid)-- needs review, this is not the speech of the global + player:setStorageValue(Storage.Kilmaresh.Twelve.Boss, 3) + npcHandler.topic[cid] = 4 + else + npcHandler:say({"Sorry."}, cid) + npcHandler.topic[cid] = 0 + end + end + if msgcontains(msg, "mission") and player:getStorageValue(Storage.Kilmaresh.Twelve.Boss) == 3 then + if player:getStorageValue(Storage.Kilmaresh.Twelve.Boss) == 3 then + npcHandler:say({"Could you help me with some more work?"}, cid)-- needs review, this is not the speech of the global + npcHandler.topic[cid] = 5 + npcHandler.topic[cid] = 5 + end + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 5 and player:getStorageValue(Storage.Kilmaresh.Twelve.Boss) == 3 then + if player:getStorageValue(Storage.Kilmaresh.Twelve.Boss) == 3 then + npcHandler:say({"Kill 300 members of the Fafnar cult, help me find Ivory Lyre and help me find an animal to stone."}, cid)-- needs review, this is not the speech of the global + player:setStorageValue(Storage.Kilmaresh.Twelve.Boss, 4) + player:setStorageValue(Storage.Kilmaresh.Thirteen.Fafnar, 1) + player:setStorageValue(Storage.Kilmaresh.Thirteen.Lyre, 1) + player:setStorageValue(Storage.Kilmaresh.Thirteen.Presente, 1) + npcHandler.topic[cid] = 6 + else + npcHandler:say({"Sorry."}, cid) + npcHandler.topic[cid] = 0 + end + end + if msgcontains(msg, "report") and player:getStorageValue(Storage.Kilmaresh.Thirteen.Fafnar) == 300 then + if player:getStorageValue(Storage.Kilmaresh.Thirteen.Fafnar) == 300 then + npcHandler:say({"Have you finished killing the 300 members of Fafnar's cult?"}, cid)-- needs review, this is not the speech of the global + npcHandler.topic[cid] = 7 + end + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 7 and player:getStorageValue(Storage.Kilmaresh.Thirteen.Fafnar) == 300 then + if player:getStorageValue(Storage.Kilmaresh.Thirteen.Fafnar) == 300 then + npcHandler:say({"Thanks. You killed the 300 members of the Fafnar cult."}, cid)-- needs review, this is not the speech of the global + player:setStorageValue(Storage.Kilmaresh.Thirteen.Fafnar, 301) + npcHandler.topic[cid] = 8 + else + npcHandler:say({"Sorry."}, cid) + npcHandler.topic[cid] = 0 + end + end + if msgcontains(msg, "report") and player:getStorageValue(Storage.Kilmaresh.Thirteen.Lyre) == 3 then + if player:getStorageValue(Storage.Kilmaresh.Thirteen.Lyre) == 3 then + npcHandler:say({"Did you manage to find Lyre?"}, cid)-- needs review, this is not the speech of the global + npcHandler.topic[cid] = 9 + end + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 9 and player:getStorageValue(Storage.Kilmaresh.Thirteen.Lyre) == 3 then + if player:getStorageValue(Storage.Kilmaresh.Thirteen.Lyre) == 3 and player:getItemById(36282, 1) then + player:removeItem(36282, 1) + npcHandler:say({"Thanks. I was looking for Lyre for a long time."}, cid)-- needs review, this is not the speech of the global + player:setStorageValue(Storage.Kilmaresh.Thirteen.Lyre, 4) + else + npcHandler:say({"Sorry."}, cid) + npcHandler.topic[cid] = 0 + end + end + if msgcontains(msg, "report") and player:getStorageValue(Storage.Kilmaresh.Thirteen.Presente) == 2 then + if player:getStorageValue(Storage.Kilmaresh.Thirteen.Presente) == 2 then + npcHandler:say({"Did you manage to find Small Tortoise?"}, cid)-- needs review, this is not the speech of the global + npcHandler.topic[cid] = 11 + end + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 11 and player:getStorageValue(Storage.Kilmaresh.Thirteen.Presente) == 2 then + if player:getStorageValue(Storage.Kilmaresh.Thirteen.Presente) == 2 and player:getItemById(36280, 1) then + player:removeItem(36280, 1) + npcHandler:say({"Thanks. I was looking for Small Tortoise."}, cid)-- needs review, this is not the speech of the global + player:setStorageValue(Storage.Kilmaresh.Thirteen.Presente, 3) + npcHandler.topic[cid] = 12 + else + npcHandler:say({"Sorry."}, cid) + npcHandler.topic[cid] = 0 + end + end + if msgcontains(msg, "small tortoise") then + if player:getItemById(36280, 1) then + npcHandler:say({"Do you want me to stone a small tortoise?"}, cid)-- needs review, this is not the speech of the global + npcHandler.topic[cid] = 15 + end + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 15 then + if player:getItemById(36280, 1) then + player:removeItem(36280, 1) + player:addItem(36281, 1) + npcHandler:say({"Here's your Small Petrified Tortoise."}, cid)-- needs review, this is not the speech of the global + npcHandler.topic[cid] = 16 + else + npcHandler:say({"Sorry."}, cid) + npcHandler.topic[cid] = 0 + end + end + if msgcontains(msg, "mission") and player:getStorageValue(Storage.Kilmaresh.Thirteen.Fafnar) == 301 then + if player:getStorageValue(Storage.Kilmaresh.Thirteen.Fafnar) == 301 then + npcHandler:say({"Did you finish the 3 jobs I gave you?"}, cid)-- needs review, this is not the speech of the global + npcHandler.topic[cid] = 13 + end + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 13 and player:getStorageValue(Storage.Kilmaresh.Thirteen.Fafnar) == 301 then + if player:getStorageValue(Storage.Kilmaresh.Thirteen.Fafnar) == 301 then + player:addAchievement(462, "Congratulations! You earned the achievement \"Sculptor Apprentice\".") + player:addItem(36409, 1) + npcHandler:say({"Congratulations, you have completed the 3 jobs I gave you."}, cid)-- needs review, this is not the speech of the global + player:setStorageValue(Storage.Kilmaresh.Fourteen.Remains, 1) + npcHandler.topic[cid] = 14 + else + npcHandler:say({"Sorry."}, cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/amanda.lua b/data/npc/scripts/amanda.lua new file mode 100644 index 00000000000..d4bcc175862 --- /dev/null +++ b/data/npc/scripts/amanda.lua @@ -0,0 +1,135 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Mission (Tibia Tales: Rest In Hallowed Ground) +local startMissionKeyword = keywordHandler:addKeyword({'mission'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, I would do it myself but I can\'t leave town for a longer time. Would you be so kind to bring me a vial of holy water from the White Raven Monastery?'}, function(player) return player:getStorageValue(Storage.TibiaTales.RestInHallowedGround.Questline) == -1 end) + startMissionKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'I thank you a lot in advance. The power of the holy water from the White Raven Monastery is legendary. For my task it is indispensable. We talk about that when you get back.', reset = true}, nil, function(player) player:setStorageValue(Storage.TibiaTales.RestInHallowedGround.Questline, 1) end) + startMissionKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'It\'s your decision. I will ask the next believing mind that visits the temple of Banor\'s blood.', reset = true}) + +local function addMissionKeyword(text, value, newValue, addItem) + keywordHandler:addKeyword({'mission'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getStorageValue(Storage.TibiaTales.RestInHallowedGround.Questline) == value end, + function(player) + if newValue then + player:setStorageValue(Storage.TibiaTales.RestInHallowedGround.Questline, newValue) + end + + if addItem then + player:addItem(7498, 1) + end + end + ) +end + +addMissionKeyword('First of all, you have to find a way to enter the Isle of the Kings and get some holy water from the White Raven Monastery.', 1) +addMissionKeyword('Have you heard about the unholy graveyard north of Edron? Go there and spill some holy water on every grave. Once you are done, come back to me.', 2, 3) +addMissionKeyword('I feel that the spirits have not come to a rest yet. There must still be some graves left to sanctify.', 3) +addMissionKeyword('I appreciate your help. May Banor be always on your side. Here, your reward is this package which contains five mana and five health potions.', 4, 5, true) + +keywordHandler:addKeyword({'mission'}, StdModule.say, {npcHandler = npcHandler, text = 'Your mission here on Tibia is to be polite and friendly. The gods will reward you, I promise!'}) + +-- Twist of Fate +local blessKeyword = keywordHandler:addKeyword({'twist of fate'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'This is a special blessing I can bestow upon you once you have obtained at least one of the other blessings and which functions a bit differently. ...', + 'It only works when you\'re killed by other adventurers, which means that at least half of the damage leading to your death was caused by others, not by monsters or the environment. ...', + 'The {twist of fate} will not reduce the death penalty like the other blessings, but instead prevent you from losing your other blessings as well as the amulet of loss, should you wear one. It costs the same as the other blessings. ...', + 'Would you like to receive that protection for a sacrifice of |PVPBLESSCOST| gold, child?' + } + }) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the protection of the twist of fate, pilgrim.', cost = '|PVPBLESSCOST|', bless = 1}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Adventurer Stone +keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Keep your adventurer\'s stone well.'}, function(player) return player:getItemById(18559, true) end) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for free?'}, function(player) return player:getStorageValue(Storage.AdventurersGuild.FreeStone.Amanda) ~= 1 end) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, nil, function(player) player:addItem(18559, 1) player:setStorageValue(Storage.AdventurersGuild.FreeStone.Amanda, 1) end) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for 30 gold?'}) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, + function(player) return player:getMoney() + player:getBankBalance() >= 30 end, + function(player) if player:removeMoneyNpc(30) then player:addItem(18559, 1) end end + ) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, you don\'t have enough money.', reset = true}) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +-- Wooden Stake +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'I think you have forgotten to bring your stake, my child.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 6 and player:getItemCount(5941) == 0 end) + +local stakeKeyword = keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes, I was informed what to do. Are you prepared to receive my line of the prayer?'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 6 end) + stakeKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'So receive my prayer: \'Wicked curses shall be broken\'. Now, bring your stake to Kasmir in Darashia for the next line of the prayer. I will inform him what to do.', reset = true}, nil, + function(player) player:setStorageValue(Storage.FriendsandTraders.TheBlessedStake, 7) player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) end + ) + stakeKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'I\'ll wait for you.', reset = true}) + +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You should visit Kasmir in Darashia now, my child.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 7 end) +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You already received my line of the prayer.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) > 7 end) +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'A blessed stake? That\'s a strange request. Maybe Quentin knows more, he is one of the oldest monks after all.'}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.'}, function(player) return player:hasBlessing(2) end) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin will provide you with the embrace of Tibia.'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, young |PLAYERNAME|! If you are heavily wounded or poisoned, I can {heal} you for free.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Remember: If you are heavily wounded or poisoned, I can heal you for free.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'May the gods bless you, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/amarie.lua b/data/npc/scripts/amarie.lua new file mode 100644 index 00000000000..06c14248e95 --- /dev/null +++ b/data/npc/scripts/amarie.lua @@ -0,0 +1,26 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local voices = { {text = 'Please leave me alone... I have to study.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Greeting message +keywordHandler:addGreetKeyword({"ashari"}, {npcHandler = npcHandler, text = "Greetings, |PLAYERNAME|."}) +--Farewell message +keywordHandler:addFarewellKeyword({"asgha thrazi"}, {npcHandler = npcHandler, text = "Good bye, |PLAYERNAME|."}) + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/ambassador_of_rathleton.lua b/data/npc/scripts/ambassador_of_rathleton.lua new file mode 100644 index 00000000000..c7d830f247c --- /dev/null +++ b/data/npc/scripts/ambassador_of_rathleton.lua @@ -0,0 +1,50 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local voices = { + {text = "What a beautiful palace. The Kilmareshians are highly skilful architects."}, + {text = "The new treaty of amity and commerce with Kilmaresh is of utmost importance."}, + {text = "The pending freight from the saffron coasts is overdue."} +} + +keywordHandler:addKeyword( + {"present"}, StdModule.say, { npcHandler = npcHandler, + text = "This is a very beautiful ring. Thank you for this generous present!"}, + function (player) return player:getStorageValue(Storage.Kilmaresh.Third.Recovering) == 2 and player:getItemById(36098, true) end, + function (player) + player:removeItem(36098, 1) + player:setStorageValue(Storage.Kilmaresh.Fourth.Moe, 1) + player:setStorageValue(Storage.Kilmaresh.Third.Recovering, 3) + end +) + +keywordHandler:addKeyword( + {"present"}, StdModule.say, { npcHandler = npcHandler, + text = "Didn't you bring my gift?"}, + function (player) return player:getStorageValue(Storage.Kilmaresh.Third.Recovering) == 2 end +) + + +npcHandler:setMessage(MESSAGE_GREET, "Greetings, friend.") +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(VoiceModule:new(voices)) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/amber.lua b/data/npc/scripts/amber.lua new file mode 100644 index 00000000000..76eb49923e3 --- /dev/null +++ b/data/npc/scripts/amber.lua @@ -0,0 +1,571 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = "I wish I could eat some salmon right now... best prepared in Liberty Bay style... yummy." }, + { text = "Wow, I'm tired. I really should get some sleep... zzzz." }, + { text = "What was that word again in Orcish language... hmm." }, + { text = "Hey you! Are you an adventurer, too?" }, + { text = " Stormy weathers, stormy weathers... stormy weathers on the sea!" } +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + local addonProgress = player:getStorageValue(Storage.OutfitQuest.Citizen.AddonBackpack) + if msgcontains(msg, "addon") or msgcontains(msg, "outfit") + or (addonProgress == 1 and msgcontains(msg, "leather")) + or ((addonProgress == 1 or addonProgress == 2) and msgcontains(msg, "backpack")) then + if addonProgress < 1 then + npcHandler:say("Sorry, the backpack I wear is not for sale. It's handmade from rare minotaur leather.", cid) + npcHandler.topic[cid] = 1 + elseif addonProgress == 1 then + npcHandler:say("Ah, right, almost forgot about the backpack! \z + Have you brought me 100 pieces of minotaur leather as requested?", cid) + npcHandler.topic[cid] = 3 + elseif addonProgress == 2 then + if player:getStorageValue(Storage.OutfitQuest.Citizen.AddonBackpackTimer) < os.time() then + npcHandler:say("Just in time! Your backpack is finished. Here you go, I hope you like it.", cid) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:setStorageValue(Storage.OutfitQuest.Ref, math.min(0, player:getStorageValue(Storage.OutfitQuest.Ref) - 1)) + player:setStorageValue(Storage.OutfitQuest.Citizen.MissionBackpack, 0) + player:setStorageValue(Storage.OutfitQuest.Citizen.AddonBackpack, 3) + + player:addOutfitAddon(136, 1) + player:addOutfitAddon(128, 1) + else + npcHandler:say("Uh... I didn't expect you to return that early. \z + Sorry, but I'm not finished yet with your backpack. \z + I'm doing the best I can, promised.", cid) + end + elseif addonProgress == 3 then + npcHandler:say("Sorry, but I can only make one backpack per person, \z + else I'd have to close my shop and open a leather manufactory.", cid) + end + return true + end + + if npcHandler.topic[cid] == 1 then + if msgcontains(msg, "backpack") or msgcontains(msg, "minotaur") or msgcontains(msg, "leather") then + npcHandler:say("Well, if you really like this backpack, I could make one for you, \z + but minotaur leather is hard to come by these days. Are you willing to put some work into this?", cid) + npcHandler.topic[cid] = 2 + end + + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, "yes") then + player:setStorageValue(Storage.OutfitQuest.Ref, math.max(0, player:getStorageValue(Storage.OutfitQuest.Ref)) + 1) + player:setStorageValue(Storage.OutfitQuest.Citizen.AddonBackpack, 1) + player:setStorageValue(Storage.OutfitQuest.Citizen.MissionBackpack, 1) + npcHandler:say("Alright then, if you bring me 100 pieces of fine minotaur leather I will \z + see what I can do for you. You probably have to kill really many minotaurs though... so good luck!", cid) + npcHandler:releaseFocus(cid) + else + npcHandler:say("Sorry, but I don't run a welfare office, you know... no pain, no gain.", cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 3 then + if msgcontains(msg, "yes") then + if player:getItemCount(5878) < 100 then + npcHandler:say("Sorry, but that's not enough leather yet to make one of these backpacks. \z + Would you rather like to buy a normal backpack for 10 gold?", cid) + else + npcHandler:say("Great! Alright, I need a while to finish this backpack for you. Come ask me later, okay?", cid) + + player:removeItem(5878, 100) + + player:setStorageValue(Storage.OutfitQuest.Citizen.MissionBackpack, 2) + player:setStorageValue(Storage.OutfitQuest.Citizen.AddonBackpack, 2) + player:setStorageValue(Storage.OutfitQuest.Citizen.AddonBackpackTimer, os.time() + 2 * 60 * 60) + end + else + npcHandler:say("I know, it's quite some work... don't lose heart, \z + just keep killing minotaurs and you'll eventually get lucky. \z + Would you rather like to buy a normal backpack for 10 gold?", cid) + end + npcHandler.topic[cid] = 0 + end +end + +npcHandler:addModule(VoiceModule:new(voices)) + +-- Basic keywords +keywordHandler:addKeyword({"hint"}, StdModule.rookgaardHints, {npcHandler = npcHandler}) +keywordHandler:addKeyword({"how", "are", "you"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I'm recovering from a {sea} passage." + } +) +keywordHandler:addKeyword({"job"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I'm an {explorer} who seeks {adventures}." + } +) +keywordHandler:addKeyword({"explore"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I've been almost everywhere in {Tibia}." + } +) +keywordHandler:addKeyword({"adventure"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I fought fierce {monsters}, climbed the highest mountains, explored the deepest {dungeons} \z + and crossed the {sea} on a {raft}." + } +) +keywordHandler:addKeyword({"sea"}, StdModule.say, + { + npcHandler = npcHandler, + text = "My voyage on the sea was exhausting. \z + The weather was bad, the waves high and my raft quite simple. \z + There's a certain excitement to it, though." + } +) +keywordHandler:addKeyword({"time"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Sorry, I lost my watch in a storm." + } +) +keywordHandler:addKeyword({"help"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Well, I can give you general {hints} or tell you about my {adventures} and many other topics. \z + Oh, and if you are bored, I might have a small {quest} for you." + } +) +keywordHandler:addKeyword({"information"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Well, I can give you general {hints} or tell you about my {adventures} and many other topics. \z + Oh, and if you are bored, I might have a small {quest} for you." + } +) +keywordHandler:addKeyword({"dungeon"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I had no time to explore the dungeons of this isle yet, \z + but I've seen two big caves in the East, and there is a ruined tower to the north-west. \z + Oh, and there're the {sewers}." + } +) +keywordHandler:addKeyword({"sewer"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I like sewers. I made my very first battle experience in the sewers below {Thais}. \z + The small sewer system of {Rookgaard} has some nasty rats to fight." + } +) +keywordHandler:addKeyword({"monster"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Oh, I fought {orcs}, {cyclopses}, {minotaurs}, even {dragons}, and many other creatures." + } +) +keywordHandler:addKeyword({"cyclops"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I don't like the way they look at you. Their eye seems to pierce right through you. Creepy!" + } +) +keywordHandler:addKeyword({"minotaur"}, StdModule.say, + { + npcHandler = npcHandler, + text = "They are nasty monsters, particularly as they have distance fighters and mages in their clans. \z + My {backpack} is handmade from minotaur leather." + } +) +keywordHandler:addKeyword({"dragon"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Their breath is so hot! I had to cut my hair after my last encounter with \z + a dragon because the ends were all burnt. That's what you gotta deal with as a female adventurer!" + } +) +keywordHandler:addKeyword({"raft"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I left my raft at the south-eastern shore. I forgot my private {notebook} on it. \z + If you could return it to me, I would be very grateful." + } +) +keywordHandler:addKeyword({"quest"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I left my raft at the south-eastern shore. I forgot my private {notebook} on it. \z + If you could return it to me, I would be very grateful." + } +) +keywordHandler:addKeyword({"mission"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I left my raft at the south-eastern shore. I forgot my private {notebook} on it. \z + If you could return it to me, I would be very grateful." + } +) +keywordHandler:addKeyword({"seymour"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I think this poor guy was a bad choice as head of the {academy}." + } +) +keywordHandler:addKeyword({"academy"}, StdModule.say, + { + npcHandler = npcHandler, + text = "A fine institution, but it needs definitely more funds from the {king}." + } +) +keywordHandler:addKeyword({"king"}, StdModule.say, + { + npcHandler = npcHandler, + text = "King Tibianus is the ruler of {Thais}. The island of {Rookgaard} belongs to his kingdom." + } +) +keywordHandler:addKeyword({"thais"}, StdModule.say, + { + npcHandler = npcHandler, + text = "A fine city, but the {king} has some problems enforcing the law." + } +) +keywordHandler:addKeyword({"weapon"}, StdModule.say, + { + npcHandler = npcHandler, + text = "The best weapons on this isle are just toothpicks \z + compared with the weapons warriors wield on the {mainland}." + } +) +keywordHandler:addKeyword({"magic"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Spells are only taught in the guildhalls of the mainland." + } +) +keywordHandler:addKeyword({"tibia"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I'm trying to explore each spot of Tibia, and one day I'll have seen it all." + } +) +keywordHandler:addKeyword({"castle"}, StdModule.say, + { + npcHandler = npcHandler, + text = "If you travel to Thais, you really should visit the marvelous castle there." + } +) +keywordHandler:addKeyword({"mainland"}, StdModule.say, + { + npcHandler = npcHandler, + text = "You'll be surprised once you leave this island. The world outside there is gigantic." + } +) +keywordHandler:addKeyword({"tools"}, StdModule.say, + { + npcHandler = npcHandler, + text = "The most important tools you need are a {rope}, a {shovel} and maybe a {torch}." + } +) +keywordHandler:addKeyword({"rope"}, StdModule.say, + { + npcHandler = npcHandler, + text = "One day I fell into a hole without having a rope. I was yelling for help for three whole days! \z + Eventually a fisherman passed by and pulled me out with his own rope, lucky me." + } +) +keywordHandler:addKeyword({"shovel"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Sometimes I have the strong urge to use it to knock someone out." + } +) +keywordHandler:addKeyword({"torch"}, StdModule.say, + { + npcHandler = npcHandler, + text = "You know, on mainland you will be able to cast magic spells which provide you with light. \z + You won't really need torches anymore." + } +) +keywordHandler:addKeyword({"bank"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I have almost no money with me anyway, so no need to deposit any at the bank." + } +) +keywordHandler:addKeyword({"destiny"}, StdModule.say, + { + npcHandler = npcHandler, + text = "You will find your destiny. I'm sure it's something big and important." + } +) +keywordHandler:addKeyword({"academy"}, StdModule.say, + { + npcHandler = npcHandler, + text = "A fine institution, but it needs definitely more funds from the {king}." + } +) +keywordHandler:addKeyword({"trade"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Oh, I'm sorry, but I'm not interested in buying or selling anything." + } +) +keywordHandler:addKeyword({"premium"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I wouldn't want to miss being a premium adventurer. Everything is so much easier!" + } +) + +-- Names +keywordHandler:addKeyword({"al", "dee"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I don't have much to say about him. I think he sells {tools}." + } +) +keywordHandler:addKeyword({"loui"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Never seen him around." + } +) +keywordHandler:addKeyword({"zirella"}, StdModule.say, + { + npcHandler = npcHandler, + text = "She seriously asked me if she could have the remains of my {raft} as fire wood! Can you imagine that??" + } +) +keywordHandler:addKeyword({"santiago"}, StdModule.say, + { + npcHandler = npcHandler, + text = "He promised to repair my {raft}." + } +) +keywordHandler:addKeyword({"amber"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Did you know my name is also the name of a gem?" + } +) +keywordHandler:addKeyword({"tom"}, StdModule.say, + { + npcHandler = npcHandler, + text = "To me he seems a bit rude, but maybe that's just my impression." + } +) +keywordHandler:addKeyword({"lee'delle"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I heard her offers are extraordinarily good." + } +) +keywordHandler:addKeyword({"oracle"}, StdModule.say, + { + npcHandler = npcHandler, + text = "The oracle is said to show you your {destiny} once you are level 8." + } +) +keywordHandler:addKeyword({"norma"}, StdModule.say, + { + npcHandler = npcHandler, + text = "She has changed a lot since I last saw her." + } +) +keywordHandler:addKeyword({"seymour"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I think this poor guy was a bad choice as head of the {academy}." + } +) +keywordHandler:addKeyword({"lily"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Hm, I think I haven't met her yet." + } +) +keywordHandler:addKeyword({"billy"}, StdModule.say, + { + npcHandler = npcHandler, + text = "He brought me some of his famous rat stew. I really didn't want to insult him, \z + but I simply can't eat something like that. So I told him I'm a vegetarian and I only eat fish. " + } +) +keywordHandler:addKeyword({"willie"}, StdModule.say, + { + npcHandler = npcHandler, + text = "He's funny in his own way." + } +) +keywordHandler:addKeyword({"paulie"}, StdModule.say, + { + npcHandler = npcHandler, + text = "No, I didn't go to the {bank} yet." + } +) +keywordHandler:addKeyword({"cipfried"}, StdModule.say, + { + npcHandler = npcHandler, + text = "A gentle person. You should visit him if you have questions or need healing." + } +) +keywordHandler:addKeyword({"hyacinth"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Hyacinth is a great healer. He lives somewhere hidden on this isle." + } +) +keywordHandler:addKeyword({"obi"}, StdModule.say, + { + npcHandler = npcHandler, + text = "He's a funny little man." + } +) +keywordHandler:addKeyword({"dixi"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I don't really know her, but she seems to be a nice girl." + } +) +keywordHandler:addKeyword({"zerbrus"}, StdModule.say, + { + npcHandler = npcHandler, + text = "An extraordinary warrior. He's the first and last line of defense of {Rookgaard}." + } +) +keywordHandler:addAliasKeyword({"dallheim"}) + +-- Orc language +keywordHandler:addKeyword({"orc"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Not the nicest guys you can encounter. \z + I had some clashes with them and finally ended up being their {prisoner} for a few months." + } +) +local prisonerKeyword = keywordHandler:addKeyword({"prisoner"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I speak some Orcish words, not many though, just a few basics like '{yes}' and '{no}'." + } +) + prisonerKeyword:addChildKeyword({"yes"}, StdModule.say, + { + npcHandler = npcHandler, + text = "It's 'mok' in Orcish. I tell you more if you bring me some {food}.", + reset = true + } +) + prisonerKeyword:addChildKeyword({"no"}, StdModule.say, + { + npcHandler = npcHandler, + text = "In Orcish that's 'burp'. I tell you more if you bring me some {food}.", + reset = true + } +) +keywordHandler:addAliasKeyword({"language"}) + +-- Food (Salmon) +keywordHandler:addKeyword({"food"}, StdModule.say, + { + npcHandler = npcHandler, + text = "My favorite dish is {salmon}. Oh please, bring me some." + } +) +local salmonKeyword = keywordHandler:addKeyword({"salmon"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Yeah! If you give me some salmon, I'll tell you another Orcish word. Okay?" + } +) +salmonKeyword:addChildKeyword({"yes"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Thank you. Orcs call arrows 'pixo'.", + reset = true + }, + function(player) + return player:getItemCount(2668) > 0 + end, + function(player) + player:removeItem(2668, 1) + end + ) +salmonKeyword:addChildKeyword({"yes"}, StdModule.say, + { + npcHandler = npcHandler, + text = "You don't have any salmon!", + reset = true + } +) +salmonKeyword:addChildKeyword({""}, StdModule.say, + { + npcHandler = npcHandler, + text = "Ok, then I won't tell you another Orcish word.", + reset = true + } +) + +-- Logbook Quest +local bookKeyword = keywordHandler:addKeyword({"book"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Do you bring me my notebook?" + } +) +bookKeyword:addChildKeyword({"yes"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Excellent. Here, take this short sword as a reward.", + reset = true + }, + function(player) + return player:getItemCount(1955) > 0 + end, + function(player) + player:addItem(2406, 1) player:removeItem(1955, 1) + end + ) +bookKeyword:addChildKeyword({"yes"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Mhm, whatever you have there, it is not my notebook.", + reset = true + } +) +bookKeyword:addChildKeyword({""}, StdModule.say, + { + npcHandler = npcHandler, + text = "Too bad.", + reset = true + } +) +keywordHandler:addAliasKeyword({"notebook"}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, "Yeah, see you later.") +npcHandler:setMessage(MESSAGE_FAREWELL, "See you later, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_GREET, "Oh hello, nice to see you |PLAYERNAME|. \z + Are you here to hear some stories of my {adventures} or do you need {help}?") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/an_ancient_priest.lua b/data/npc/scripts/an_ancient_priest.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/an_ancient_priest.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/an_apparition.lua b/data/npc/scripts/an_apparition.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/an_apparition.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/an_imprisoned_goblin.lua b/data/npc/scripts/an_imprisoned_goblin.lua new file mode 100644 index 00000000000..dcdab86022c --- /dev/null +++ b/data/npc/scripts/an_imprisoned_goblin.lua @@ -0,0 +1,20 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/an_old_dragon_lord.lua b/data/npc/scripts/an_old_dragon_lord.lua new file mode 100644 index 00000000000..26db3d6f049 --- /dev/null +++ b/data/npc/scripts/an_old_dragon_lord.lua @@ -0,0 +1,46 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onCreatureSay(creature, type, msg) + if not (msgcontains(msg, 'hi') or msgcontains(msg, 'hello')) then + npcHandler:say('LEAVE THE DRAGONS\' CEMETERY AT ONCE!', creature.uid) + end + npcHandler:onCreatureSay(creature, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'AHHHH THE PAIN OF AGESSS! THE PAIN!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.Dragonfetish) == 1 then + npcHandler:say('LEAVE THE DRAGONS\' CEMETERY AT ONCE!', cid) + return false + end + + if not player:removeItem(2787, 1) then + npcHandler:say('AHHHH THE PAIN OF AGESSS! I NEED MUSSSSHRROOOMSSS TO EASSSE MY PAIN! BRRRING ME MUSHRRROOOMSSS!', cid) + return false + end + + player:setStorageValue(Storage.Dragonfetish, 1) + player:addItem(2319, 1) + npcHandler:say('AHHH MUSHRRROOOMSSS! NOW MY PAIN WILL BE EASSSED FOR A WHILE! TAKE THISS AND LEAVE THE DRAGONSSS\' CEMETERY AT ONCE!', cid) + return false +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/an_orc_guard.lua b/data/npc/scripts/an_orc_guard.lua new file mode 100644 index 00000000000..66329e4fd5c --- /dev/null +++ b/data/npc/scripts/an_orc_guard.lua @@ -0,0 +1,22 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Grrrr.' }, + { text = 'Fetchi maruk buta.' } +} +npcHandler:addModule(VoiceModule:new(voices)) diff --git a/data/npc/scripts/anderson.lua b/data/npc/scripts/anderson.lua new file mode 100644 index 00000000000..8fb11bf5494 --- /dev/null +++ b/data/npc/scripts/anderson.lua @@ -0,0 +1,80 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + {text = 'Passages to Tibia, Folda and Vega.'} +} + +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, cost, destination) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, + { + npcHandler = npcHandler, + text = "Do you want a passage to " .. keyword:titleCase() .. " for |TRAVELCOST|?", + cost = cost, + discount = "postman" + } + ) + travelKeyword:addChildKeyword({"yes"}, StdModule.travel, + { + npcHandler = npcHandler, + text = "Have a nice trip!", + premium = false, + cost = cost, + discount = "postman", + destination = destination + } + ) + travelKeyword:addChildKeyword({"no"}, StdModule.say, + { + npcHandler = npcHandler, + text = "You shouldn't miss the experience.", + reset = true + } + ) +end + +addTravelKeyword("tibia", 0, {x = 32235, y = 31674, z = 7}) +addTravelKeyword("vega", 20, {x = 32020, y = 31692, z = 7}) +addTravelKeyword("folda", 20, {x = 32046, y = 31578, z = 7}) + +-- Basic +keywordHandler:addKeyword({"passage"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Where do you want to go today? We serve the routes to Senja, {Folda} and {Vega} and back to {Tibia}." + } +) +keywordHandler:addKeyword({"job"}, StdModule.say, + { + npcHandler = npcHandler, + text = "We are ferrymen. We transport goods and passengers to the Ice Islands." + } +) +keywordHandler:addKeyword({"captain"}, StdModule.say, + { + npcHandler = npcHandler, + text = "We are ferrymen. We transport goods and passengers to the Ice Islands." + } +) + +npcHandler:setMessage(MESSAGE_GREET, "Ahoi, young man |PLAYERNAME| and welcome to the Nordic Tibia Ferries. If you need a {passage}, let me know.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye. You are welcome.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/andrew_lyze.lua b/data/npc/scripts/andrew_lyze.lua new file mode 100644 index 00000000000..ebc9894831d --- /dev/null +++ b/data/npc/scripts/andrew_lyze.lua @@ -0,0 +1,84 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local shopModule = ShopModule:new() +npcHandler:addModule(shopModule) + +shopModule:addBuyableItem({"broken compass"}, 29047, 10000) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "monument") then + npcHandler:say({ + "Well, a while ago powerful magic devices were used all around Tibia. These are chargeable compasses. There was but one problem: they offered the possibility to make people rich in a quite easy way. ...", + "Therefore, these instruments were very coveted. People tried to get their hands on them at all costs. And so it happened what everybody feared - bloody battles forged ahead. ...", + "To put an end to these cruel escalations, eventually all of the devices were collected and destroyed. The remains were buried {deep} in the earth." + }, cid, false, true, 10) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "deep") then + npcHandler:say("As far as I know it is a place of helish heat with bloodthirsty monsters of all kinds.", cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "sarcophagus") then + npcHandler:say("This sarcophagus seals the entrance to the caves down there. Only here you can get all the {materials} you need for a working compass of this kind. So no entrance here - no further magic compasses in Tibia. In theory.", cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "materials") then + if player:getStorageValue(Storage.Quest.TheDreamCourts.AndrewDoor) ~= 1 then + player:setStorageValue(Storage.Quest.TheDreamCourts.AndrewDoor, 1) + end + npcHandler:say({ + "Only in the cave down there you will find the materials you need to repair the compass. Now you know why the entrance is sealed. There's the seal, but I have a deal for you: ...", + "I can repair the compass for you if you deliver what I need. Besides the broken compass you have to bring me the following materials: 50 blue glas plates, 15 green glas plates and 5 violet glas plates. ...", + "They all can be found in this closed cave in front of you. I should have destroyed this seal key but things have changed. The entrance is opened now, go down and do what has to be done."}, cid, false, true, 10) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, "down") then + npcHandler:say("On first glance, this cave does not look very spectacular, but the things you find in there, are. You have to know that this is the only place where you can find the respective materials to build the {compass}.", cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "compass") then + npcHandler:say("It was decided to collect all of the compasses, destroy them and throw them in the fiery {depths} of Tibia. I still have some of them here. I {sell} them for a low price if you want.", cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "depths") then + npcHandler:say("As far as I know it is a place of helish heat with bloodthirsty monsters of all kinds.", cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "sell") then + npcHandler:say("Would you like to buy a broken compass for 10.000 gold?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 1 then + local message = "You have bought a compass" + if not checkWeightAndBackpackRoom(player, 80, message) then + npcHandler:say("You not have room or capacity to take it.", cid) + return true + end + if player:getMoney() + player:getBankBalance() >= 5000 then + player:removeMoneyNpc(5000) + player:addItem(11219, 1) + end + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:setMessage(MESSAGE_GREET, "Hello, I am the warden of this {monument}. The {sarcophagus} in front of you was established to prevent people from going {down} there. But I {doubt} that this step is sufficient.") + +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/anerui.lua b/data/npc/scripts/anerui.lua new file mode 100644 index 00000000000..5878aaeca12 --- /dev/null +++ b/data/npc/scripts/anerui.lua @@ -0,0 +1,45 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am the mistress of the hunt. At this place you may buy the food our hunts provide."}) +keywordHandler:addKeyword({'hunt'}, StdModule.say, {npcHandler = npcHandler, text = "Hunting is an art, practiced too often by diletantes. Every fool with a bow or a spear considers himself a hunter."}) +keywordHandler:addKeyword({'bow'}, StdModule.say, {npcHandler = npcHandler, text = "Bow, arrow, and spear are the hunters' best friends. In the northeast of the town one of us may sell such tools."}) +keywordHandler:addKeyword({'hunter'}, StdModule.say, {npcHandler = npcHandler, text = "Hunters live a life of freedom and closeness to nature, unlike a simple farmer or bugherder."}) +keywordHandler:addKeyword({'nature'}, StdModule.say, {npcHandler = npcHandler, text = "Nature is not a friend but an unforgiving teacher, and the lessons we have to learn are endless."}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = "Watch the sky, it will tell you."}) +keywordHandler:addKeyword({'crunor'}, StdModule.say, {npcHandler = npcHandler, text = "I guess it's a human god for the human sight of nature. I have not much knowledge of this entity."}) +keywordHandler:addKeyword({'teshial'}, StdModule.say, {npcHandler = npcHandler, text = "If they ever existed they are gone now."}) +keywordHandler:addKeyword({'kuridai'}, StdModule.say, {npcHandler = npcHandler, text = "The Kuridai are too agressive not only to people but also to the enviroment. They lack any understanding of the balance that we know as nature."}) +keywordHandler:addKeyword({'balance'}, StdModule.say, {npcHandler = npcHandler, text = "The balance of nature, of course. It's everywhere, so don't ask but observe and learn."}) +keywordHandler:addKeyword({'deraisim'}, StdModule.say, {npcHandler = npcHandler, text = "We try to live in harmony with the forces of nature, may they be living or unliving."}) +keywordHandler:addKeyword({'human'}, StdModule.say, {npcHandler = npcHandler, text = "The humans are a loud and ugly race. They lack any grace and are more kin to the orcs then to us."}) +keywordHandler:addKeyword({'death'}, StdModule.say, {npcHandler = npcHandler, text = "Life and death are significant parts of the balance."}) +keywordHandler:addKeyword({'life'}, StdModule.say, {npcHandler = npcHandler, text = "Life and death are significant parts of the balance."}) +keywordHandler:addKeyword({'troll'}, StdModule.say, {npcHandler = npcHandler, text = "I despise their presence in our town, but it may be a necessary evil."}) +keywordHandler:addKeyword({'elf'}, StdModule.say, {npcHandler = npcHandler, text = "That is the race to which I belong."}) +keywordHandler:addKeyword({'cenath'}, StdModule.say, {npcHandler = npcHandler, text = "The magic they wield is all that matters to them."}) + +-- Greeting message +keywordHandler:addGreetKeyword({"ashari"}, {npcHandler = npcHandler, text = "Ashari, |PLAYERNAME|."}) +-- Farewell message +keywordHandler:addFarewellKeyword({"asgha thrazi"}, {npcHandler = npcHandler, text = "Asha Thrazi."}) + +npcHandler:setMessage(MESSAGE_GREET, "Ashari |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Asha Thrazi.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Asha Thrazi.") + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/aneus.lua b/data/npc/scripts/aneus.lua new file mode 100644 index 00000000000..305e8505d83 --- /dev/null +++ b/data/npc/scripts/aneus.lua @@ -0,0 +1,93 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'soldiers'}, StdModule.say, {npcHandler = npcHandler, text = "It was the elite of the whole army. They were called the Red Legion (also known as the bloody legion)."}) +keywordHandler:addKeyword({'orcs'}, StdModule.say, {npcHandler = npcHandler, text = "The orcs attacked the workers from time to time and so they disturbed the WORKS on the city."}) +keywordHandler:addKeyword({'cruelty'}, StdModule.say, {npcHandler = npcHandler, text = "The soldiers treated the workers like slaves."}) +keywordHandler:addKeyword({'island'}, StdModule.say, {npcHandler = npcHandler, text = "The General of the Red Legion became very angry about these attacks and after some months he STROKE back!"}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + elseif msgcontains(msg, "story") then + npcHandler:say({ + 'Ok, sit down and listen. Back in the early days, one of the ancestors ... ', + '... of our king Tibianus III wanted to build the best CITY in whole of Tibia.' + }, cid) + elseif msgcontains(msg, "city") then + npcHandler:say({ + 'The works on this new city began and the king sent his best ... ', + '... SOLDIERS to protect the workers from ORCS and to make them WORK HARDER.' + }, cid) + elseif msgcontains(msg, "works") then + npcHandler:say({ + 'The development of the city was fine. Also a giant castle was build ... ', + '... northeast of the city. But more and more workers started to REBEL because of the bad conditions.' + }, cid) + elseif msgcontains(msg, "rebel") then + npcHandler:say({ + 'All rebels were brought to the giant castle. Guarded by the Red Legion, ... ', + '... they had to work and live in even worser conditions. Also some FRIENDS of the king\'s sister were brought there.' + }, cid) + elseif msgcontains(msg, "friends") then + npcHandler:say({ + 'The king\'s sister was pretty upset about the situation there but her brother ... ', + '... didn\'t want to do anything about this matter. So she made a PLAN to destroy the Red Legion for their CRUELTY forever.' + }, cid) + elseif msgcontains(msg, "plan") then + npcHandler:say({ + 'She ordered her loyal druids and hunters to disguise themselves ... ', + '... as orcs from the near ISLAND and to ATTACK the Red Legion by night over and over again.' + }, cid) + elseif msgcontains(msg, "stroke") then + npcHandler:say({ + 'Most of the Red Legion went to the island by night. The orcs ... ', + '... were not prepared and the Red Legion killed hundreds of orcs ... ', + '... with nearly no loss. After they were satisfied they WALKED BACK to the castle.' + }, cid) + elseif msgcontains(msg, "walked back") then + npcHandler:say({ + 'It is said that the orcish shamans cursed the Red Legion. ', + 'Nobody knows. But one third of the soldiers died by a disease on the way back. ', + 'And the orcs wanted to take revenge, and after some days they stroke back! ', + 'The orcs and many allied cyclopses and minotaurs from all ...', + '... over Tibia came to avenge their friends, and they killed nearly all ... ', + '... workers and soldiers in the castle. The HELP of the king\'s sister came too late.' + }, cid) + elseif msgcontains(msg, "help") then + npcHandler:say({ + 'She tried to rescue the workers but it was too late. The orcs ... ', + '... started immediately to attack her troops, too. Her royal troops ... ', + '... went back to the city. A TRICK saved the city from DESTRUCTION.' + }, cid) + elseif msgcontains(msg, "destruction") then + npcHandler:say({ + 'They used the same trick as against the Red Legion and the orcs ... ', + '... started to fight their non-orcish-allies. After a bloody long fight ... ', + '... the orcs went back to their cities. The city of Carlin was rescued. ', + 'Since then, a woman has always been ruling over Carlin and this statue ... ', + '... was made to remind us of their great tactics against the orcs ... ', + '... and the Red Legion. So that was the story of Carlin and these Fields of Glory. I hope you liked it. *He smiles*' + }, cid) + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Greetings adventurer |PLAYERNAME|. What leads you to me?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye and take care of you!") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/angelina.lua b/data/npc/scripts/angelina.lua new file mode 100644 index 00000000000..c14358590b2 --- /dev/null +++ b/data/npc/scripts/angelina.lua @@ -0,0 +1,49 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.OutfitQuest.MageSummoner.AddonWand) < 1 then + npcHandler:setMessage(MESSAGE_GREET, "The gods must be praised that I am finally saved. I do not have many worldly possessions, but please accept a small reward, do you?") + elseif player:getStorageValue(Storage.OutfitQuest.MageSummoner.AddonWand) >= 1 then + npcHandler:setMessage(MESSAGE_GREET, "Thanks for saving my life! Should I teleport you out of the Dark Cathedral?") + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "Yes") then + if player:getStorageValue(Storage.OutfitQuest.MageSummoner.AddonWand) < 1 then + npcHandler:say("I will tell you a small secret now. My friend Lynda in Thais can create a blessed wand. Greet her from me, maybe she will aid you.", cid) + player:setStorageValue(Storage.OutfitQuest.MageSummoner.AddonWand, 1) + player:setStorageValue(Storage.OutfitQuest.DefaultStart, 1) --this for default start of Outfit and Addon Quests + elseif player:getStorageValue(Storage.OutfitQuest.MageSummoner.AddonWand) >= 1 then + player:teleportTo(Position(32659, 32340, 7)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/angelo.lua b/data/npc/scripts/angelo.lua new file mode 100644 index 00000000000..0b8e9987ded --- /dev/null +++ b/data/npc/scripts/angelo.lua @@ -0,0 +1,148 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local playerTopic = {} +local function greetCallback(cid) + + local player = Player(cid) + + -- Se estiver na 1º missão + if player:getStorageValue(Storage.CultsOfTibia.Life.Mission) == 1 then + npcHandler:setMessage(MESSAGE_GREET, "The Druid of Crunor? He told you that a new cave appeared here? That's right. I'm the head of a {project} that tries to find out more about this new {area}.") + playerTopic[cid] = 1 + -- Se já tiver após a 1º missão + elseif player:getStorageValue(Storage.CultsOfTibia.Life.Mission) > 1 then + npcHandler:setMessage(MESSAGE_GREET, "How is your {mission} going?") + playerTopic[cid] = 6 + end + npcHandler:addFocus(cid) + return true +end + + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + npcHandler.topic[cid] = playerTopic[cid] + local player = Player(cid) + +-- Sequência para pegar a quest +if npcHandler.topic[cid] == 1 and msgcontains(msg, "project") then + npcHandler:say({"The project is called 'Sandy {Cave} Project' and is funded by the {MoTA}. Its goal is the investigation of this {cave}."}, cid) + playerTopic[cid] = 2 + + elseif npcHandler.topic[cid] == 2 and msgcontains(msg, "mota") then + npcHandler:say({"MoTA is short for the recently founded Museum of Tibian Arts. We work together in close collaboration. New {results} are communicated to the museum instantly."}, cid) + playerTopic[cid] = 3 + + elseif npcHandler.topic[cid] == 3 and msgcontains(msg, "results") then + npcHandler:say({"We have no scientific results so far to reach our {goal}, because my workers aren't back yet. Should I be {worried}?"}, cid) + playerTopic[cid] = 4 + + elseif npcHandler.topic[cid] == 4 and msgcontains(msg, "yes") then + npcHandler:say({"Alright. I have to find out why they don't return. But I'm old and my back aches. Would you like to go there and look for my workers?"}, cid) + playerTopic[cid] = 5 + + elseif npcHandler.topic[cid] == 5 and msgcontains(msg, "yes") then + npcHandler:say({"Fantastic! Go there and then tell me what you've seen. I've oppened the door for you. Take care of yourself!"}, cid) + player:setStorageValue(Storage.CultsOfTibia.Life.Mission, 2) + player:setStorageValue(Storage.CultsOfTibia.Life.AccessDoor, 1) + playerTopic[cid] = 0 + + -- Inútil + elseif npcHandler.topic[cid] == 2 and msgcontains(msg, "cave") then + npcHandler:say({"We don't know exactly why this cave has now exposed an entry via the {dark pyramid}. It seems that the cave already existed for a long time, however, without a connection to our world. Maybe some smaller earth movements have changed the situation."}, cid) + playerTopic[cid] = 11 + + elseif npcHandler.topic[cid] == 11 and msgcontains(msg, "dark pyramid") then + npcHandler:say({"We don't know yet to wich extent the cave and the dark pyramid belong together. Thisi s what we try to find out. Maybe the history of this place has to be rewritten."}, cid) + playerTopic[cid] = 0 +end + + + + -- Depois de encontrar o Oasis +if player:getStorageValue(Storage.CultsOfTibia.Life.Mission) == 3 then + if msgcontains(msg, "mission") and npcHandler.topic[cid] == 6 then + npcHandler:say({"The scientists are still missing? You just found some strange green shining mummies and a big oasis? I give you this analysis tool for the water of the oasis. Maybe that's the key. Could you bring me a sample of this water?"}, cid) + playerTopic[cid] = 15 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 15 then + npcHandler:say({"Very good. Hopefully analysing this sample will get us closer to the solution of this mistery."}, cid) + player:addItem(28666, 1) + player:setStorageValue(Storage.CultsOfTibia.Life.Mission, 4) + end +end + +-- Depois de usar o analyzing tool +if player:getStorageValue(Storage.CultsOfTibia.Life.Mission) == 5 then + if msgcontains(msg, "mission") and npcHandler.topic[cid] == 6 then + npcHandler:say({"Do you have the sample I asked you for?"}, cid) + playerTopic[cid] = 16 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 16 then + npcHandler:say({"Thanks a lot. Let me check the result. Well, I think you need the counteragent. Please apply it to the oasis!"}, cid) + player:addItem(28665, 1) + player:setStorageValue(Storage.CultsOfTibia.Life.Mission, 6) + end +end + +-- Depois de usar o conteragent +if player:getStorageValue(Storage.CultsOfTibia.Life.Mission) == 7 then + if msgcontains(msg, "mission") and npcHandler.topic[cid] == 6 then + npcHandler:say({"What has happened? You applied the counteragent to the oasis and then it was destroyed by a sandstorm? Keep on investigating the place."}, cid) + playerTopic[cid] = 17 + end +end + +-- after killing the boss the sandking +if player:getStorageValue(Storage.CultsOfTibia.Life.Mission) == 8 then + npcHandler:setMessage(MESSAGE_GREET, "Just get out of my way! You killed this beautiful creature. I have nothing more to say. Damn druid of Crunor!") + player:setStorageValue(Storage.CultsOfTibia.Life.Mission, 9) +end + + +----------------------------------------- MOTA ------------------------------- + -- Pedindo o Magnifier de Gareth +if player:getStorageValue(Storage.CultsOfTibia.MotA.Mission) == 6 then + if msgcontains(msg, "magnifier") then + npcHandler:say({"{Gareth} told you that there are rumours about fake artefacts in the MoTA? And it is your task to check that with a magnifier? I see. I don't need one right now, so you can have one of mine. You find one in the crate over there."}, cid) + player:setStorageValue(Storage.CultsOfTibia.MotA.Mission, 7) + end + end + + -- Pedindo a pintura de Gareth para Angelo +if player:getStorageValue(Storage.CultsOfTibia.MotA.Mission) == 10 then + if msgcontains(msg, "picture") then + npcHandler:say({"So you found out that one artefact in the MoTA is fake? And {Gareth} sent you to me to get a new artefact as a replacement? Sorry, I hardly know you so I don't trust you. I won't help you with that!"}, cid) + player:setStorageValue(Storage.CultsOfTibia.MotA.Mission, 11) + end + end + + return true +end + + + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/angus.lua b/data/npc/scripts/angus.lua new file mode 100644 index 00000000000..330165d3141 --- /dev/null +++ b/data/npc/scripts/angus.lua @@ -0,0 +1,667 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + -- Joining + if msgcontains(msg, "join") then + if player:getStorageValue(Storage.ExplorerSociety.JoiningTheExplorers) < 1 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) < 1 then + npcHandler:say("Do you want to join the explorer society?", cid) + npcHandler.topic[cid] = 1 + end + -- The new frontier + elseif msgcontains(msg, "farmine") then + if player:getStorageValue(Storage.TheNewFrontier.Questline) <= 15 + and player:getStorageValue(Storage.TheNewFrontier.BribeExplorerSociety) < 1 then + npcHandler:say("Oh yes, an interesting topic. We had vivid discussions about this discovery. But what is it that you want?", cid) + npcHandler.topic[cid] = 30 + end + elseif msgcontains(msg, "bluff") then + if npcHandler.topic[cid] == 30 then + if player:getStorageValue(Storage.TheNewFrontier.BribeExplorerSociety) < 1 then + npcHandler:say({ + "Those stories are just amazing! Men with faces on their stomach instead of heads you say? And hens that lay golden eggs? Whereas, most amazing is this fountain of youth you've mentioned! ...", + "I'll immediately send some of our most dedicated explorers to check those things out!" + }, cid) + player:setStorageValue(Storage.TheNewFrontier.BribeExplorerSociety, 1) + --Questlog, The New Frontier Quest "Mission 05: Getting Things Busy" + player:setStorageValue(Storage.TheNewFrontier.Mission05, player:getStorageValue(Storage.TheNewFrontier.Mission05) + 1) + end + end + + -- Mission check + elseif msgcontains(msg, "mission") then + if player:getStorageValue(Storage.ExplorerSociety.JoiningTheExplorers) > 3 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) > 3 + and player:getStorageValue(Storage.ExplorerSociety.ThePlantCollection) < 26 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) < 26 + or player:getStorageValue(Storage.ExplorerSociety.TheIceDelivery) == 7 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 7 + or player:getStorageValue(Storage.ExplorerSociety.TheButterflyHunt) == 16 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 16 + or player:getStorageValue(Storage.ExplorerSociety.JoiningTheExplorers) == 4 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 4 then + npcHandler:say("The missions available for your rank are the {butterfly hunt}, {plant collection} and {ice delivery}.", cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.ExplorerSociety.ThePlantCollection) > 25 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) > 35 + and player:getStorageValue(Storage.ExplorerSociety.TheOrcPowder) < 35 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) < 35 + or player:getStorageValue(Storage.ExplorerSociety.ThePlantCollection) == 26 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 26 + or player:getStorageValue(Storage.ExplorerSociety.TheLizardUrn) == 29 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 29 + or player:getStorageValue(Storage.ExplorerSociety.TheBonelordSecret) == 32 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 32 then + npcHandler:say("The missions available for your rank are {lizard urn}, {bonelord secrets} and {orc powder}.", cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.ExplorerSociety.TheOrcPowder) > 34 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) > 34 + and player:getStorageValue(Storage.ExplorerSociety.TheRuneWritings) < 44 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) < 44 + or player:getStorageValue(Storage.ExplorerSociety.TheOrcPowder) == 35 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 35 + or player:getStorageValue(Storage.ExplorerSociety.TheElvenPoetry) == 38 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 38 + or player:getStorageValue(Storage.ExplorerSociety.TheMemoryStone) == 41 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 41 then + npcHandler:say("The missions available for your rank are {elven poetry}, {memory stone} and {rune writings}.", cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.ExplorerSociety.TheRuneWritings) == 44 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 44 then + npcHandler:say("The explorer society needs a great deal of help in the research of astral travel. Are you willing to help?", cid) + npcHandler.topic[cid] = 27 + elseif player:getStorageValue(Storage.ExplorerSociety.TheEctoplasm) == 46 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 46 then + npcHandler:say("Do you have some collected ectoplasm with you?", cid) + npcHandler.topic[cid] = 29 + elseif player:getStorageValue(Storage.ExplorerSociety.TheEctoplasm) == 47 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 47 then + npcHandler:say({ + "The research on ectoplasm makes good progress. Now we need some spectral article. Our scientists think a spectral dress would be a perfect object for their studies ...", + "The bad news is that the only source to got such a dress is the queen of the banshees. Do you dare to seek her out?" + }, cid) + npcHandler.topic[cid] = 30 + elseif player:getStorageValue(Storage.ExplorerSociety.TheSpectralDress) == 49 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 48 then + npcHandler:say("Did you bring the dress?", cid) + npcHandler.topic[cid] = 31 + -- Spectral stone + elseif player:getStorageValue(Storage.ExplorerSociety.TheSpectralDress) == 50 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 50 then + npcHandler:say({ + "With the objects you've provided our researchers will make steady progress. Still we are missing some test results from fellow explorers ...", + "Please travel to our base in Northport and ask them to mail us their latest research reports. Then return here and ask about new missions." + }, cid) + player:setStorageValue(Storage.ExplorerSociety.TheSpectralStone, 51) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 51) + player:setStorageValue(Storage.ExplorerSociety.SpectralStone, 1) + elseif player:getStorageValue(Storage.ExplorerSociety.TheSpectralStone) == 51 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 51 + and player:getStorageValue(Storage.ExplorerSociety.SpectralStone) == 2 then + npcHandler:say("Oh, yes! Tell our fellow explorer that the papers are in the mail already.", cid) + player:setStorageValue(Storage.ExplorerSociety.TheSpectralStone, 52) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 52) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.ExplorerSociety.TheSpectralStone) == 52 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 52 + and player:getStorageValue(Storage.ExplorerSociety.SpectralStone) == 1 then + npcHandler:say("The reports from Northport have already arrived here and our progress is astonishing. We think it is possible to create an astral bridge between our bases. Are you interested to assist us with this?", cid) + npcHandler.topic[cid] = 32 + -- Spectral stone + -- Astral portals + elseif player:getStorageValue(Storage.ExplorerSociety.TheSpectralStone) == 55 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 55 then + npcHandler:say({ + "Both carvings are now charged and harmonised. In theory you should be able to travel in zero time from one base to the other ...", + "However, you will need to have an orichalcum pearl in your possession to use it as power source. It will be destroyed during the process. I will give you 6 of such pearls and you can buy new ones in our bases ...", + "In addition, you need to be a premium explorer to use the astral travel. ...", + "And remember: it's a small teleport for you, but a big teleport for all Tibians! Here is a small present for your efforts!" + }, cid) + player:setStorageValue(Storage.ExplorerSociety.TheAstralPortals, 56) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 56) + player:addItem(5022, 6) -- Orichalcum pearl + player:addItem(10522, 1) -- Crown backpack + -- Astral portals + end + -- Mission check + -- Pickaxe mission + elseif msgcontains(msg, "pickaxe") then + if player:getStorageValue(Storage.ExplorerSociety.JoiningTheExplorers) < 4 + or player:getStorageValue(Storage.ExplorerSociety.JoiningTheExplorers) > 1 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) < 1 + or player:getStorageValue(Storage.ExplorerSociety.QuestLine) > 1 then + npcHandler:say("Did you get the requested pickaxe from Uzgod in Kazordoon?", cid) + npcHandler.topic[cid] = 3 + end + -- Pickaxe mission + -- Ice delivery + elseif msgcontains(msg, "ice delivery") then + if player:getStorageValue(Storage.ExplorerSociety.JoiningTheExplorers) == 4 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 4 then + npcHandler:say({ + "Our finest minds came up with the theory that deep beneath the ice island of Folda ice can be found that is ancient. To prove this theory we would need a sample of the aforesaid ice ...", + "Of course the ice melts away quickly so you would need to hurry to bring it here ...", + "Would you like to accept this mission?" + }, cid) + npcHandler.topic[cid] = 4 + elseif player:getStorageValue(Storage.ExplorerSociety.TheIceDelivery) == 6 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 6 then + npcHandler:say("Did you get the ice we are looking for?", cid) + npcHandler.topic[cid] = 5 + end + -- Ice delivery + -- Butterfly hunt + elseif msgcontains(msg, "butterfly hunt") then + if player:getStorageValue(Storage.ExplorerSociety.TheIceDelivery) == 7 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 7 then + npcHandler:say("The mission asks you to collect some species of butterflies, are you interested?", cid) + npcHandler.topic[cid] = 7 + elseif player:getStorageValue(Storage.ExplorerSociety.TheButterflyHunt) == 9 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 9 then + npcHandler:say("Did you acquire the purple butterfly we are looking for?", cid) + npcHandler.topic[cid] = 8 + elseif player:getStorageValue(Storage.ExplorerSociety.TheButterflyHunt) == 10 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 10 then + npcHandler:say({ + "This preparation kit will allow you to collect a blue butterfly you have killed ...", + "Just use it on the fresh corpse of a blue butterfly, return the prepared butterfly to me and give me a report of your butterfly hunt." + }, cid) + npcHandler.topic[cid] = 0 + player:addItem(4865, 1) + player:setStorageValue(Storage.ExplorerSociety.TheButterflyHunt, 11) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 11) + elseif player:getStorageValue(Storage.ExplorerSociety.TheButterflyHunt) == 12 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 12 then + npcHandler:say("Did you acquire the blue butterfly we are looking for?", cid) + npcHandler.topic[cid] = 9 + elseif player:getStorageValue(Storage.ExplorerSociety.TheButterflyHunt) == 13 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 13 then + npcHandler:say({ + "This preparation kit will allow you to collect a red butterfly you have killed ...", + "Just use it on the fresh corpse of a red butterfly, return the prepared butterfly to me and give me a report of your butterfly hunt." + }, cid) + npcHandler.topic[cid] = 0 + player:addItem(4865, 1) + player:setStorageValue(Storage.ExplorerSociety.TheButterflyHunt, 14) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 14) + elseif player:getStorageValue(Storage.ExplorerSociety.TheButterflyHunt) == 15 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 15 then + npcHandler:say("Did you acquire the red butterfly we are looking for?", cid) + npcHandler.topic[cid] = 10 + end + -- Butterfly Hunt + -- Plant Collection + elseif msgcontains(msg, "plant collection") then + if player:getStorageValue(Storage.ExplorerSociety.TheButterflyHunt) == 16 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 16 then + npcHandler:say("In this mission we require you to get us some plant samples from Tiquandan plants. Would you like to fulfil this mission?", cid) + npcHandler.topic[cid] = 11 + elseif player:getStorageValue(Storage.ExplorerSociety.ThePlantCollection) == 18 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 18 then + npcHandler:say("Did you acquire the sample of the jungle bells plant we are looking for?", cid) + npcHandler.topic[cid] = 12 + elseif player:getStorageValue(Storage.ExplorerSociety.ThePlantCollection) == 19 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 19 then + npcHandler:say("Use this botanist's container on a witches cauldron to collect a sample for us. Bring it here and report about your plant collection.", cid) + npcHandler.topic[cid] = 0 + player:addItem(4869, 1) + player:setStorageValue(Storage.ExplorerSociety.ThePlantCollection, 20) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 20) + elseif player:getStorageValue(Storage.ExplorerSociety.ThePlantCollection) == 21 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 21 then + npcHandler:say("Did you acquire the sample of the witches cauldron we are looking for?", cid) + npcHandler.topic[cid] = 13 + elseif player:getStorageValue(Storage.ExplorerSociety.ThePlantCollection) == 22 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 22 then + npcHandler:say("Use this botanist\'s container on a giant jungle rose to obtain a sample for us. Bring it here and report about your plant collection.", cid) + npcHandler.topic[cid] = 0 + player:addItem(4869, 1) + player:setStorageValue(Storage.ExplorerSociety.ThePlantCollection, 23) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 23) + elseif player:getStorageValue(Storage.ExplorerSociety.ThePlantCollection) == 24 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 24 then + npcHandler:say("Did you acquire the sample of the giant jungle rose we are looking for?", cid) + npcHandler.topic[cid] = 14 + end + -- Plant Collection + -- Lizard Urn + elseif msgcontains(msg, "lizard urn") then + if player:getStorageValue(Storage.ExplorerSociety.ThePlantCollection) == 26 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 26 then + npcHandler:say("The explorer society would like to acquire an ancient urn which is some sort of relic to the lizard people of Tiquanda. Would you like to accept this mission?", cid) + npcHandler.topic[cid] = 15 + elseif player:getStorageValue(Storage.ExplorerSociety.TheLizardUrn) == 28 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 27 then + npcHandler:say("Did you manage to get the ancient urn?", cid) + npcHandler.topic[cid] = 16 + end + -- Lizard Urn + -- Bonelords + elseif msgcontains(msg, "bonelord secrets") then + if player:getStorageValue(Storage.ExplorerSociety.TheLizardUrn) == 29 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 29 then + npcHandler:say({ + "We want to learn more about the ancient race of bonelords. We believe the black pyramid north east of Darashia was originally built by them ...", + "We ask you to explore the ruins of the black pyramid and look for any signs that prove our theory. You might probably find some document with the numeric bonelord language ...", + "That would be sufficient proof. Would you like to accept this mission?" + }, cid) + npcHandler.topic[cid] = 17 + elseif player:getStorageValue(Storage.ExplorerSociety.TheBonelordSecret) == 31 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 30 then + npcHandler:say("Have you found any proof that the pyramid was built by bonelords?", cid) + npcHandler.topic[cid] = 18 + end + -- Bonelords + -- Orc Powder + elseif msgcontains(msg, "orc powder") then + if player:getStorageValue(Storage.ExplorerSociety.TheBonelordSecret) == 32 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 32 then + npcHandler:say({ + "It is commonly known that orcs of Uldereks Rock use some sort of powder to increase the fierceness of their war wolves and berserkers ...", + "What we do not know are the ingredients of this powder and its effect on humans ...", + "So we would like you to get a sample of the aforesaid powder. Do you want to accept this mission?" + }, cid) + npcHandler.topic[cid] = 19 + elseif player:getStorageValue(Storage.ExplorerSociety.TheOrcPowder) == 34 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 33 then + npcHandler:say("Did you acquire some of the orcish powder?", cid) + npcHandler.topic[cid] = 20 + end + -- Orc Powder + -- Elven Poetry + elseif msgcontains(msg, "elven poetry") then + if player:getStorageValue(Storage.ExplorerSociety.TheOrcPowder) == 35 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 35 then + npcHandler:say({ + "Some high ranking members would like to study elven poetry. They want the rare book 'Songs of the Forest' ...", + "For sure someone in Ab'Dendriel will own a copy. So you would just have to ask around there. Are you willing to accept this mission?" + }, cid) + npcHandler.topic[cid] = 21 + elseif player:getStorageValue(Storage.ExplorerSociety.TheElvenPoetry) == 37 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 36 then + npcHandler:say("Did you acquire a copy of 'Songs of the Forest' for us?", cid) + npcHandler.topic[cid] = 22 + end + -- ELVEN POETRY + + -- MEMORY STONE + elseif msgcontains(msg, "memory stone") then + if player:getStorageValue(Storage.ExplorerSociety.TheElvenPoetry) == 38 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 38 then + npcHandler:say({ + "We acquired some knowledge about special magic stones. Some lost civilisations used it to store knowledge and lore, just like we use books ...", + "The wisdom in such stones must be immense, but so are the dangers faced by every person who tries to obtain one...", + "As far as we know the ruins found in the north-west of Edron were once inhabited by beings who used such stones. Do you have the heart to go there and to get us such a stone?" + }, cid) + npcHandler.topic[cid] = 23 + elseif player:getStorageValue(Storage.ExplorerSociety.TheMemoryStone) == 40 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 39 then + npcHandler:say("Were you able to acquire a memory stone for our society?", cid) + npcHandler.topic[cid] = 24 + end + -- Memory Stone + -- Rune Writings + elseif msgcontains(msg, "rune writings") then + if player:getStorageValue(Storage.ExplorerSociety.TheMemoryStone) == 41 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 41 then + npcHandler:say({ + "We would like to study some ancient runes that were used by the lizard race. We suspect some relation of the lizards to the founders of Ankrahmun ...", + "Somewhere under the ape infested city of Banuta, one can find dungeons that were once inhabited by lizards...", + "Look there for an atypical structure that would rather fit to Ankrahmun and its Ankrahmun Tombs. Copy the runes you will find on this structure...", + "Are you up to that challenge?" + }, cid) + npcHandler.topic[cid] = 25 + elseif player:getStorageValue(Storage.ExplorerSociety.TheRuneWritings) == 43 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 43 then + npcHandler:say("Did you create a copy of the ancient runes as requested?", cid) + npcHandler.topic[cid] = 26 + end + -- Rune Writings + -- Answer Yes + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "Fine, though it takes more then a mere lip service to join our ranks. To prove your dedication to the cause you will have to acquire an item for us ...", + "The mission should be simple to fulfil. For our excavations we have ordered a sturdy pickaxe in Kazordoon. You would have to seek out this trader Uzgod and get the pickaxe for us ...", + "Simple enough? Are you interested in this task?" + }, cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say("We will see if you can handle this simple task. Get the pickaxe from Uzgod in Kazordoon and bring it to one of our bases. Report there about the pickaxe.", cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.ExplorerSociety.JoiningTheExplorers, 1) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 1) + elseif npcHandler.topic[cid] == 3 then + if player:removeItem(4874, 1) then + player:setStorageValue(Storage.ExplorerSociety.JoiningTheExplorers, 4) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 4) + npcHandler:say({ + "Excellent, you brought just the tool we need! Of course it was only a simple task. However ...", + "I officially welcome you to the explorer society. From now on you can ask for missions to improve your rank." + }, cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 4 then + player:setStorageValue(Storage.ExplorerSociety.TheIceDelivery, 5) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 5) + npcHandler:say({ + "So listen please: Take this ice pick and use it on a block of ice in the caves beneath Folda. Get some ice and bring it here as fast as you can ...", + "Should the ice melt away, report on your ice delivery mission anyway. I will then tell you if the time is right to start another mission." + }, cid) + npcHandler.topic[cid] = 0 + player:addItem(4856, 1) + elseif npcHandler.topic[cid] == 5 then + if player:removeItem(4848, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheIceDelivery, 7) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 7) + npcHandler:say("Just in time. Sadly not much ice is left over but it will do. Thank you again.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 6 then + player:setStorageValue(Storage.ExplorerSociety.TheIceDelivery, 5) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 5) + npcHandler:say("*Sigh* I think the time is right to grant you another chance to get that ice. Hurry up this time.", cid) + npcHandler.topic[cid] = 0 + + -- Butterfly Hunt + elseif npcHandler.topic[cid] == 7 then + player:setStorageValue(Storage.ExplorerSociety.TheButterflyHunt, 8) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 8) + npcHandler:say({ + "This preparation kit will allow you to collect a purple butterfly you have killed ...", + "Just use it on the fresh corpse of a purple butterfly, return the prepared butterfly to me and give me a report of your butterfly hunt." + }, cid) + npcHandler.topic[cid] = 0 + player:addItem(4865, 1) + elseif npcHandler.topic[cid] == 8 then + if player:removeItem(4866, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheButterflyHunt, 10) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 10) + npcHandler:say("A little bit battered but it will do. Thank you! If you think you are ready, ask for another butterfly hunt.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 9 then + if player:removeItem(4867, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheButterflyHunt, 13) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 13) + npcHandler:say("A little bit battered but it will do. Thank you! If you think you are ready, ask for another butterfly hunt.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 10 then + if player:removeItem(4868, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheButterflyHunt, 16) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 16) + npcHandler:say("That is an extraordinary species you have brought. Thank you! That was the last butterfly we needed.", cid) + npcHandler.topic[cid] = 0 + end + -- Butterfly Hunt + -- Plant Collection + elseif npcHandler.topic[cid] == 11 then + player:setStorageValue(Storage.ExplorerSociety.ThePlantCollection, 17) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 17) + npcHandler:say("Fine! Here take this botanist's container. Use it on a jungle bells plant to collect a sample for us. Report about your plant collection when you have been successful.", cid) + npcHandler.topic[cid] = 0 + player:addItem(4869, 1) + elseif npcHandler.topic[cid] == 12 then + if player:removeItem(4870, 1) then + player:setStorageValue(Storage.ExplorerSociety.ThePlantCollection, 19) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 19) + npcHandler:say("I see. It seems you've got some quite useful sample by sheer luck. Thank you! Just tell me when you are ready to continue with the plant collection.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 13 then + if player:removeItem(4871, 1) then + player:setStorageValue(Storage.ExplorerSociety.ThePlantCollection, 22) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 22) + npcHandler:say("Ah, finally. I started to wonder what took you so long. But thank you! Another fine sample, indeed. Just tell me when you are ready to continue with the plant collection.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 14 then + if player:removeItem(4872, 1) then + player:setStorageValue(Storage.ExplorerSociety.ThePlantCollection, 26) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 26) + npcHandler:say("What a lovely sample! With that you have finished your plant collection missions.", cid) + npcHandler.topic[cid] = 0 + end + -- Plant Collection + -- Lizard Urn + elseif npcHandler.topic[cid] == 15 then + player:setStorageValue(Storage.ExplorerSociety.TheLizardUrn, 27) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 27) + player:setStorageValue(Storage.ExplorerSociety.ChorurnDoor, 1) + npcHandler:say({ + "You have indeed the spirit of an adventurer! In the south-east of Tiquanda is a small settlement of the lizard people ...", + "Beneath the newly constructed temple there, the lizards hide the said urn. Our attempts to acquire this item were without success ...", + "Perhaps you are more successful." + }, cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 16 then + if player:removeItem(4858, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheLizardUrn, 29) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 29) + npcHandler:say("Yes, that is the prized relic we have been looking for so long. You did a great job, thank you.", cid) + npcHandler.topic[cid] = 0 + end + -- Lizard Urn + -- Bonelords + elseif npcHandler.topic[cid] == 17 then + player:setStorageValue(Storage.ExplorerSociety.TheBonelordSecret, 30) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 30) + player:setStorageValue(Storage.ExplorerSociety.BonelordsDoor, 1) + npcHandler:say({ + "Excellent! So travel to the city of Darashia and then head north-east for the pyramid ...", + "If any documents are left, you probably find them in the catacombs beneath. Good luck!" + }, cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 18 then + if player:removeItem(4857, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheBonelordSecret, 32) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 32) + npcHandler:say("You did it! Excellent! The scientific world will be shaken by this discovery!", cid) + npcHandler.topic[cid] = 0 + end + -- Bonelords + -- Orc Powder + elseif npcHandler.topic[cid] == 19 then + player:setStorageValue(Storage.ExplorerSociety.TheOrcPowder, 33) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 33) + player:setStorageValue(Storage.ExplorerSociety.OrcDoor, 1) + npcHandler:say({ + "You are a brave soul. As far as we can tell, the orcs maintain some sort of training facility in some hill in the north-east of their city ...", + "There you should find lots of their war wolves and hopefully also some of the orcish powder. Good luck!" + }, cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 20 then + if player:removeItem(15389, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheOrcPowder, 35) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 35) + npcHandler:say("You really got it? Amazing! Thank you for your efforts.", cid) + npcHandler.topic[cid] = 0 + end + -- Orc Powder + -- Elven Poetry + elseif npcHandler.topic[cid] == 21 then + player:setStorageValue(Storage.ExplorerSociety.TheElvenPoetry, 36) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 36) + player:setStorageValue(Storage.ExplorerSociety.ElvenDoor, 1) + npcHandler:say("Excellent. This mission is easy but nonetheless vital. Travel to Ab'Dendriel and get the book.", cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 22 then + if player:removeItem(4855, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheElvenPoetry, 38) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 38) + npcHandler:say("Let me have a look! Yes, that's what we wanted. A copy of 'Songs of the Forest'. I won't ask any questions about those bloodstains.", cid) + npcHandler.topic[cid] = 0 + end + -- Elven Poetry + -- Memory Stone + elseif npcHandler.topic[cid] == 23 then + player:setStorageValue(Storage.ExplorerSociety.TheMemoryStone, 39) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 39) + player:setStorageValue(Storage.ExplorerSociety.MemoryStoneDoor, 1) + npcHandler:say("In the ruins of north-western Edron you should be able to find a memory stone. Good luck.", cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 24 then + if player:removeItem(4852, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheMemoryStone, 41) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 41) + npcHandler:say("A flawless memory stone! Incredible! It will take years even to figure out how it works but what an opportunity for science, thank you!", cid) + npcHandler.topic[cid] = 0 + end + -- Memory Stone + -- Rune Writings + elseif npcHandler.topic[cid] == 25 then + player:setStorageValue(Storage.ExplorerSociety.TheRuneWritings, 42) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 42) + npcHandler:say("Excellent! Here, take this tracing paper and use it on the object you will find there to create a copy of the ancient runes.", cid) + npcHandler.topic[cid] = 0 + player:addItem(4853, 1) + elseif npcHandler.topic[cid] == 26 then + if player:removeItem(4854, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheRuneWritings, 44) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 44) + npcHandler:say("It's a bit wrinkled but it will do. Thanks again.", cid) + npcHandler.topic[cid] = 0 + end + -- Rune Writings + -- Ectoplasm + elseif npcHandler.topic[cid] == 27 then + npcHandler:say({ + "Fine. The society is looking for new means to travel. Some of our most brilliant minds have some theories about astral travel that they want to research further ...", + "Therefore we need you to collect some ectoplasm from the corpse of a ghost. We will supply you with a collector that you can use on the body of a slain ghost ...", + "Do you think you are ready for that mission?" + }, cid) + npcHandler.topic[cid] = 28 + elseif npcHandler.topic[cid] == 28 then + npcHandler:say("Good! Take this container and use it on a ghost that was recently slain. Return with the collected ectoplasm and hand me that container ...", cid) + npcHandler:say("Don't lose the container. They are expensive!", cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.ExplorerSociety.TheEctoplasm, 45) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 45) + player:addItem(4863, 1) + elseif npcHandler.topic[cid] == 29 then + if player:removeItem(8182, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheEctoplasm, 47) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 47) + npcHandler:say("Phew, I had no idea that ectoplasm would smell that ... oh, it's you, well, sorry. Thank you for the ectoplasm.", cid) + npcHandler.topic[cid] = 0 + end + -- Ectoplasm + -- Spectral Dress + elseif npcHandler.topic[cid] == 30 then + npcHandler:say({ + "That is quite courageous. We know, it's much we are asking for. The queen of the banshees lives in the so called Ghostlands, south west of Carlin. It is rumoured that her lair is located in the deepest dungeons beneath that cursed place ...", + "Any violence will probably be futile, you will have to negotiate with her. Try to get a spectral dress from her. Good luck." + }, cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.ExplorerSociety.TheSpectralDress, 48) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 48) + elseif npcHandler.topic[cid] == 31 then + if player:removeItem(4847, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheSpectralDress, 50) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 50) + npcHandler:say("Good! Ask me for another mission.", cid) + npcHandler.topic[cid] = 0 + end + -- Spectral Dress + + -- Spectral Stone + elseif npcHandler.topic[cid] == 32 then + npcHandler:say({ + "Good, just take this spectral essence and use it on the strange carving in this building as well as on the corresponding tile in our base at Northport ...", + "As soon as you have charged the portal tiles that way, report about the spectral portals." + }, cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.ExplorerSociety.TheSpectralStone, 53) + player:setStorageValue(Storage.ExplorerSociety.SpectralStoneDoor, 1) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 53) + player:addItem(4851, 1) -- Spectral stone + -- Spectral Stone + -- Skull Of Ratha / Giant Smithhammer + elseif npcHandler.topic[cid] == 33 then + if player:removeItem(2320, 1) then + npcHandler:say("Poor Ratha. Thank you for returning this skull to the society. We will see to a honourable burial of Ratha.", cid) + player:setStorageValue(Storage.ExplorerSociety.SkullOfRatha, 1) + player:addItem(2152, 2) + player:addItem(2148, 50) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Come back when you find any information.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 34 then + if player:removeItem(2321, 1) then + npcHandler:say("Marvellous! You brought a giant smith hammer for the explorer society!", cid) + player:setStorageValue(Storage.ExplorerSociety.GiantSmithHammer, 1) + player:addItem(2152, 2) + player:addItem(2148, 50) + npcHandler.topic[cid] = 0 + else + npcHandler:say("No you don\'t.", cid) + npcHandler.topic[cid] = 0 + end + -- Skull Of Ratha / Giant Smithhammer + end + -- Answer Yes + -- Answer No + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] == 5 then + npcHandler:say("Did it melt away?", cid) + npcHandler.topic[cid] = 6 + elseif npcHandler.topic[cid] == 33 then + npcHandler:say("Come back when you find any information.", cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 34 then + npcHandler:say("Come back when you find one.", cid) + npcHandler.topic[cid] = 0 + end + -- Answer No + -- Skull Of Ratha / Giant Smithhammer + elseif msgcontains(msg, "skull of ratha") + and player:getStorageValue(Storage.ExplorerSociety.SkullOfRatha) < 1 then + npcHandler:say({ + "Ratha was a great explorer and even greater ladies' man. Sadly he never returned from a visit to the amazons. Probably he is dead ...", + "The society offers a substantial reward for the retrieval of Ratha or his remains. Do you have any news about Ratha?" + }, cid) + npcHandler.topic[cid] = 33 + elseif msgcontains(msg, "giant smith hammer") + and player:getStorageValue(Storage.ExplorerSociety.GiantSmithHammer) < 1 then + npcHandler:say("The explorer society is looking for a genuine giant smith hammer for our collection. It is rumoured the cyclopses of the Plains of Havoc might be using one. Did you by chance obtain such a hammer?", cid) + npcHandler.topic[cid] = 34 + -- Skull Of Ratha / Giant Smithhammer + end + return true +end + +local function onTradeRequest(cid) + if Player(cid):getStorageValue(Storage.ExplorerSociety.TheAstralPortals) ~= 56 then + return false + end + + return true +end + +npcHandler:setCallback(CALLBACK_ONTRADEREQUEST, onTradeRequest) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/appaloosa.lua b/data/npc/scripts/appaloosa.lua new file mode 100644 index 00000000000..fcfb7b56d85 --- /dev/null +++ b/data/npc/scripts/appaloosa.lua @@ -0,0 +1,75 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, 'transport') then + npcHandler:say('We can bring you to Thais with one of our coaches for 125 gold. Are you interested?', cid) + npcHandler.topic[cid] = 1 + elseif isInArray({'rent', 'horses'}, msg) then + npcHandler:say('Do you want to rent a horse for one day at a price of 500 gold?', cid) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, 'yes') then + local player = Player(cid) + if npcHandler.topic[cid] == 1 then + if player:isPzLocked() then + npcHandler:say('First get rid of those blood stains!', cid) + return true + end + + if not player:removeMoneyNpc(125) then + npcHandler:say('You don\'t have enough money.', cid) + return true + end + + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + local destination = Position(32449, 32226, 7) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + npcHandler:say('Have a nice trip!', cid) + elseif npcHandler.topic[cid] == 2 then + if player:getStorageValue(Storage.RentedHorseTimer) >= os.time() then + npcHandler:say('You already have a horse.', cid) + return true + end + + if not player:removeMoneyNpc(500) then + npcHandler:say('You do not have enough money to rent a horse!', cid) + return true + end + + local mountId = {22, 25, 26} + player:addMount(mountId[math.random(#mountId)]) + player:setStorageValue(Storage.RentedHorseTimer, os.time() + 86400) + player:addAchievement('Natural Born Cowboy') + npcHandler:say('I\'ll give you one of our experienced ones. Take care! Look out for low hanging branches.', cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] > 0 then + npcHandler:say('Then not.', cid) + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, 'Salutations, |PLAYERNAME| I guess you are here for the {horses}.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/archery.lua b/data/npc/scripts/archery.lua new file mode 100644 index 00000000000..94936e30523 --- /dev/null +++ b/data/npc/scripts/archery.lua @@ -0,0 +1,29 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Come into my tavern and share some stories!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Basic + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am the owner of this saloon. I call it Archery's Hut. I am also {selling} ammunitions."}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome to Archery's shop.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Please come back from time to time.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Please come back from time to time.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/archeryrook.lua b/data/npc/scripts/archeryrook.lua new file mode 100644 index 00000000000..3c571a74e6c --- /dev/null +++ b/data/npc/scripts/archeryrook.lua @@ -0,0 +1,29 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Come into my tavern and share some stories!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Basic + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am the owner of this saloon. I call it Archery's Hut. I am also {selling} ammunitions."}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome to Archery's Rook shop.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Please come back from time to time.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Please come back from time to time.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ariella.lua b/data/npc/scripts/ariella.lua new file mode 100644 index 00000000000..41a292d15c3 --- /dev/null +++ b/data/npc/scripts/ariella.lua @@ -0,0 +1,142 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = {{text = "Have a drink in Meriana's only tavern!"}} +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "cookie") then + if player:getStorageValue(Storage.WhatAFoolish.Questline) == 31 and + player:getStorageValue(Storage.WhatAFoolish.CookieDelivery.Ariella) ~= 1 then + npcHandler:say("So you brought a cookie to a pirate?", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "addon") and player:getStorageValue(Storage.OutfitQuest.PirateBaseOutfit) == 1 then + npcHandler:say( + "To get pirate hat you need give me Brutus Bloodbeard's Hat, \ + Lethal Lissy's Shirt, Ron the Ripper's Sabre and Deadeye Devious' Eye Patch. Do you have them with you?", + cid) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, "mission") then + if player:getStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven) == 1 then + npcHandler:say( + "You know, we have plenty of rum here but we lack some basic food. \ + Especially food that easily becomes mouldy is a problem. Bring me 100 breads and you will help me a lot.", + cid) + player:setStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven, 2) + elseif player:getStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven) == 2 then + npcHandler:say("Are you here to bring me the 100 pieces of bread that I requested?", cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven) == 10 then + npcHandler:say( + { + "The sailors always tell tales about the famous beer of Carlin. \ + You must know, alcohol is forbidden in that city. ...", + "The beer is served in a secret whisper bar anyway. \ + Bring me a sample of the whisper beer, NOT the usual beer but whisper beer. I hope you are listening." + }, + cid) + player:setStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven, 11) + elseif player:getStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven) == 12 then + npcHandler:say("Did you get a sample of the whisper beer from Carlin?", cid) + npcHandler.topic[cid] = 4 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + if not player:removeItem(8111, 1) then + npcHandler:say("You have no cookie that I'd like.", cid) + npcHandler.topic[cid] = 0 + return true + end + + player:setStorageValue(Storage.WhatAFoolish.CookieDelivery.Ariella, 1) + if player:getCookiesDelivered() == 10 then + player:addAchievement("Allow Cookies?") + end + + Npc():getPosition():sendMagicEffect(CONST_ME_GIFT_WRAPS) + npcHandler:say( + "How sweet of you ... Uhh ... OH NO ... Bozo did it again. Tell this prankster I'll pay him back.", + cid) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + elseif npcHandler.topic[cid] == 2 then + if player:getStorageValue(Storage.OutfitQuest.PirateHatAddon) == -1 then + if player:getItemCount(6101) > 0 and player:getItemCount(6102) > 0 and player:getItemCount(6100) > 0 and + player:getItemCount(6099) > 0 + then + if + player:removeItem(6101, 1) and player:removeItem(6102, 1) and player:removeItem(6100, 1) and + player:removeItem(6099, 1) + then + npcHandler:say("Ah, right! The pirate hat! Here you go.", cid) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + player:setStorageValue(Storage.OutfitQuest.PirateHatAddon, 1) + player:addOutfitAddon(155, 2) + player:addOutfitAddon(151, 2) + end + else + npcHandler:say("You do not have all the required items.", cid) + npcHandler.topic[cid] = 0 + end + else + npcHandler:say("It seems you already have this addon, don't you try to mock me son!", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 3 then + if player:getStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven) == 2 then + if player:removeItem(2689, 100) then + npcHandler:say("What a joy. At least for a few days adequate supply is ensured.", cid) + player:setStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven, 3) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Come back when you got all neccessary items.", cid) + npcHandler.topic[cid] = 0 + end + end + elseif npcHandler.topic[cid] == 4 then + if player:getStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven) == 12 then + if player:removeItem(6106, 1) then + npcHandler:say("Thank you very much. I will test this beauty in privacy.", cid) + player:setStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven, 14) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Come back when you got the neccessary item.", cid) + npcHandler.topic[cid] = 0 + end + end + end + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("I see.", cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say("Alright then. Come back when you got all neccessary items.", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/arito.lua b/data/npc/scripts/arito.lua new file mode 100644 index 00000000000..852b97a3dbc --- /dev/null +++ b/data/npc/scripts/arito.lua @@ -0,0 +1,56 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + local AritosTask = player:getStorageValue(Storage.TibiaTales.AritosTask) + -- START TASK + if msgcontains(msg, "nomads") then + if player:getStorageValue(Storage.TibiaTales.AritosTask) <= 0 and player:getItemCount(8267) >= 0 then + npcHandler:say({ + 'What?? My name on a deathlist which you retrieved from a nomad?? Show me!! ...', + 'Oh my god! They found me! You must help me! Please !!!!' + }, cid) + if player:getStorageValue(Storage.TibiaTales.DefaultStart) <= 0 then + player:setStorageValue(Storage.TibiaTales.DefaultStart, 1) + end + player:setStorageValue(Storage.TibiaTales.AritosTask, 1) + -- END TASK + elseif player:getStorageValue(Storage.TibiaTales.AritosTask) == 2 then + npcHandler:say({ + 'These are great news!! Thank you for your help! I don\'t have much, but without you I wouldn\'t have anything so please take this as a reward.' + }, cid) + player:setStorageValue(Storage.TibiaTales.AritosTask, 3) + player:addItem(2152, 50) + end + return true + end +end + +local voices = { {text = 'Come in, have a drink and something to eat.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "Be mourned, pilgrim in flesh. Be mourned in my tavern.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Do visit us again.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Do visit us again.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Sure, browse through my offers.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/arkarra.lua b/data/npc/scripts/arkarra.lua new file mode 100644 index 00000000000..51edc6f2e04 --- /dev/null +++ b/data/npc/scripts/arkarra.lua @@ -0,0 +1,25 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Krrrrrng.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "...") +npcHandler:setMessage(MESSAGE_FAREWELL, "...") +npcHandler:setMessage(MESSAGE_WALKAWAY, "...") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/arkhothep.lua b/data/npc/scripts/arkhothep.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/arkhothep.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/arkulius.lua b/data/npc/scripts/arkulius.lua new file mode 100644 index 00000000000..0d823866470 --- /dev/null +++ b/data/npc/scripts/arkulius.lua @@ -0,0 +1,143 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = "...the arithmetical paradox has the same value in a metaphysical way, then..." }, + { text = "Oh my! Alverus!! Did you really...?!?! I have to recalculate it to make sure that I made no mistake." }, + { text = "" }, + { text = "...the minimum square deviation could cause a dislocation, in a matter of fact..." }, + { text = "...it could be possible to bring the sphere to a destination where..." }, + { text = "Yes, that's it! The elementary particle are corresponding to the... the ... UNBELIEVEABLE!!!" } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local greetMsg = { + "...if the expected constant is higher than... Hmmm, who are you?? What do you want?", + "...then I could transform a spell to bend... How can anyone expect me to work under these conditions?? What do you want?", + "...if my calculations are correct, I will be able to revive... Arrgghh!! What do you want?" +} + +local function greetCallback(cid) + npcHandler:setMessage(MESSAGE_GREET, greetMsg[math.random(#greetMsg)]) + npcHandler.topic[cid] = 0 + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "alverus") then + npcHandler:say({ + "It happened while he carried out an experiment concerning the creation of the elemental {shrines}. I still get goose bumps just by thinking of it. ...", + "You need to know about the process of creating an elemental shrine to understand it completely, but I don't want to go into detail now. ...", + "Anyway, his spell had a different outcome than he had planned. He accidentally created an Ice Overlord, pure living elemental ice, who froze him in a blink of an eye." + }, cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "shrine") then + npcHandler:say({ + "The creation of the elemental shrines is a really complex matter. They are actually nodes, locations where the matching elemental sphere is very close. ...", + "The shrine itself is like a portal between our world and the elemental {sphere} and enables us to use the elemental energy emerging from it." + }, cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "sphere") and player:getLevel() >= 80 then + npcHandler:say({ + "There are four spheres we know of: ice, fire, earth and energy. .... Hmmm, should I ask or not?....The heck with it! Now that you know about the spheres ...", + "I found a way to visit them. It's VERY dangerous and there is a decent chance that you won't come back BUT if you succeed you'll write history!!! Ask me about that {mission} if you're interested." + }, cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "mission") or msgcontains(msg, "quest") then + local value = player:getStorageValue(Storage.ElementalSphere.QuestLine) + if value < 1 then + if player:getLevel() >= 80 then + if player:isSorcerer() then + npcHandler:say({ + "Okay, listen closely: First of all, you need to gather 20 enchanted rubies in order to go to the fire sphere. Deep under the academy, one floor below the elemental shrines, there is a machine. Put the gems in there and activate it. ...", + "Once you got there, find a way to gather elemental fire in any form. You will face fire elementals, that's for sure, but I don't know how the fire is stored. ...", + "Anyway, there should be a way to use that elemental fire and strengthen one of the elementals. If my calculations are right, you will create a Fire Overlord who hopefully will consist of some sort of 'concentrated' fire or something similar. ...", + "THAT'S what we need!! Are you in on it?" + }, cid) + elseif player:isDruid() then + npcHandler:say({ + "Okay, listen closely: First of all, you need to gather 20 enchanted emeralds in order to go to the earth sphere. Deep under the academy, one floor below the elemental shrines, there is a machine. Put the gems in there and activate it. ...", + "Once you got there, find a way to gather elemental earth in any form. You will face earth elementals, that's for sure, but I don't know how the earth is stored. ...", + "Anyway, there should be a way to use that elemental earth and strengthen one of the elementals. If my calculations are right, you will create an Earth Overlord who hopefully will consist of some sort of 'concentrated' earth or something similar. ...", + "THAT'S what we need!! Are you in on it?" + }, cid) + elseif player:isPaladin() then + npcHandler:say({ + "Okay, listen closely: First of all, you need to gather 20 enchanted sapphires in order to go to the ice sphere. Deep under the academy, one floor below the elemental shrines, there is a machine. Put the gems in there and activate it. ...", + "Once you got there, find a way to gather elemental ice in any form. You will face ice elementals, that's for sure, but I don't know how the ice is stored. ...", + "Anyway, there should be a way to use that elemental ice and strengthen one of the elementals. If my calculations are right, you will create an Ice Overlord who hopefully will consist of some sort of 'concentrated' ice or something similar. ...", + "THAT'S what we need!! Are you in on it?" + }, cid) + elseif player:isKnight() then + npcHandler:say({ + "Okay, listen closely: First of all, you need to gather 20 enchanted amethysts in order to go to the energy sphere. Deep under the academy, one floor below the elemental shrines, there is a machine. Put the gems in there and activate it. ...", + "Once you got there, find a way to gather elemental energy in any form. You will face energy elementals, that's for sure, but I don't know how the energy is stored. ...", + "Anyway, there should be a way to use that energy and strengthen one of the elementals. If my calculations are right, you will create an Energy Overlord who hopefully will consist of some sort of 'concentrated' energy. ...", + "THAT'S what we need!! Are you in on it?" + }, cid) + end + else + npcHandler:say("I'm sorry this task is highly dangerous and I need experienced people for it.", cid) + npcHandler.topic[cid] = 0 + return false + end + npcHandler.topic[cid] = 1 + elseif value == 1 then + if player:getItemCount(player:isSorcerer() and 8304 or player:isDruid() and 8305 or player:isPaladin() and 8300 or player:isKnight() and 8306) > 0 then + player:setStorageValue(Storage.ElementalSphere.QuestLine, 2) + npcHandler:say({ + "Impressive!! Let me take a look.......Ahh, " .. (player:isSorcerer() and "an ETERNAL FLAME! Now you need to find a knight, a druid, and a paladin who also completed this first task. ..." or player:isDruid() and "MOTHER SOIL! Now you need to find a knight, a paladin, and a sorcerer who also completed this first task. ..." or player:isPaladin() and "a FLAWLESS ICE CRYSTAL! Now you need to find a knight, a druid, and a sorcerer who also completed this first task. ..." or player:isKnight() and "PURE ENERGY! Now you need to find a druid, a paladin, and a sorcerer who also completed this first task. ..."), + "Go down in the cellar again. I prepared a room under the academy where it should be safe. Your task is to charge the machines with the elemental substances and summon the LORD OF THE ELEMENTS. ...", + "When you use an obsidian knife on it's corpse you hopefully get some of the precious neutral matter. It's the only way to revive my dear friend Alverus!!" + }, cid) + else + npcHandler:say("You need some kind of pure elemental soil from the " .. (player:isSorcerer() and "Fire" or player:isDruid() and "Earth" or player:isPaladin() and "Ice" or player:isKnight() and "Energy") .. " Overlord. Come back when you've got it.", cid) + end + npcHandler.topic[cid] = 0 + elseif value == 2 then + if player:removeItem(8310, 1) and player:getStorageValue(Storage.ElementalSphere.QuestLine) < 3 then + npcHandler:say("AMAZING!! I'm going to start immediately with the research. If it turns out the way I expect it, Alverus will be revived soon!! Here, take this as a reward and try to collect more of this substance. I'll make you a good offer, I promise. ", cid) + player:addItem(player:isSorcerer() and 8867 or player:isDruid() and 8869 or player:isPaladin() and 8853 or player:isKnight() and 8883, 1) + player:setStorageValue(Storage.ElementalSphere.QuestLine, 3) + end + end + elseif npcHandler.topic[cid] == 1 and msgcontains(msg, "yes") then + player:setStorageValue(Storage.ElementalSphere.QuestLine, 1) + npcHandler:say("Good, don't waste time! Come back here when you have the elemental object!", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "How dare you asking me this?!? I'm Arkulius - Master of Elements, the HEADMASTER of this academy!!"}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "I'm Arkulius - Master of Elements, the headmaster of this academy."}) +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = "I have better things to do than helping you. See that ice statue over there? My dear friend Alverus needs to be revived!"}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = "Time is an illusion and completely irrelevant to me."}) +keywordHandler:addKeyword({'weapon'}, StdModule.say, {npcHandler = npcHandler, text = "Weapons are for those people who aren't able to use their heads or better what's INSIDE their heads. No offence ."}) -- < Knight; FIXME !!! +keywordHandler:addKeyword({'pits of inferno'}, StdModule.say, {npcHandler = npcHandler, text = "Yeye, I believe you almost feel like home among all those brainless creatures!"}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye and please stay away, okay?") +npcHandler:setMessage(MESSAGE_FAREWELL, "At last! Good things come to those who wait.") +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/armenius_npc.lua b/data/npc/scripts/armenius_npc.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/armenius_npc.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/arnold.lua b/data/npc/scripts/arnold.lua new file mode 100644 index 00000000000..e160dd39add --- /dev/null +++ b/data/npc/scripts/arnold.lua @@ -0,0 +1,38 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(10, 1000, -10) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if isInArray({"fuck", "idiot", "asshole", "ass", "fag", "stupid", "tyrant", "shit", "lunatic"}, msg) then + npcHandler:say("Take this!", cid) + local player = Player(cid) + player:getPosition():sendMagicEffect(CONST_ME_EXPLOSIONAREA) + player:addCondition(condition) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/aruda.lua b/data/npc/scripts/aruda.lua new file mode 100644 index 00000000000..2807c760c1b --- /dev/null +++ b/data/npc/scripts/aruda.lua @@ -0,0 +1,219 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +local Price = {} + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Hey there, up for a chat?'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local function greetCallback(cid) + if Player(cid):getSex() == PLAYERSEX_FEMALE then + npcHandler:setMessage(MESSAGE_GREET, "Oh, hello |PLAYERNAME|, your hair looks great! Who did it for you?") + npcHandler.topic[cid] = 1 + else + npcHandler:setMessage(MESSAGE_GREET, "Oh, hello, handsome! It's a pleasure to meet you, |PLAYERNAME|. Gladly I have the time to {chat} a bit.") + npcHandler.topic[cid] = nil + end + Price[cid] = nil + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + local Sex = player:getSex() + if npcHandler.topic[cid] == 1 then + npcHandler:say("I would never have guessed that.", cid) + npcHandler.topic[cid] = nil + elseif npcHandler.topic[cid] == 2 then + if player:removeMoneyNpc(Price[cid]) then + npcHandler:say("Oh, sorry, I was distracted, what did you say?", cid) + else + npcHandler:say("Oh, I just remember I have some work to do, sorry. Bye!", cid) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + npcHandler.topic[cid] = nil + Price[cid] = nil + elseif npcHandler.topic[cid] == 3 and player:removeItem(2036, 1) then + npcHandler:say("Take some time to talk to me!", cid) + npcHandler.topic[cid] = nil + elseif npcHandler.topic[cid] == 4 and (msgcontains(msg, "spouse") or msgcontains(msg, "girlfriend")) then + npcHandler:say("Well ... I have met him for a little while .. but this was nothing serious.", cid) + npcHandler.topic[cid] = 5 + elseif npcHandler.topic[cid] == 5 and msgcontains(msg, "fruit") then + npcHandler:say("I remember that grapes were his favourites. He was almost addicted to them.", cid) + npcHandler.topic[cid] = nil + elseif msgcontains(msg, "how") and msgcontains(msg, "are") and msgcontains(msg, "you") then + npcHandler:say("Thank you very much. How kind of you to care about me. I am fine, thank you.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "sell") then + npcHandler:say("Sorry, I have nothing to sell.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "job") or msgcontains(msg, "chat") then + npcHandler:say("I do some work now and then. Nothing unusual, though. So I have plenty time to chat. If you are interested in any topic just ask me.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "name") then + if Sex == PLAYERSEX_FEMALE then + npcHandler:say("I am Aruda.", cid) + else + npcHandler:say("I am a little sad, that you seem to have forgotten me, handsome. I am Aruda.", cid) + end + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "aruda") then + if Sex == PLAYERSEX_FEMALE then + npcHandler:say("Yes, that's me!", cid) + else + npcHandler:say("Oh, I like it, how you say my name.", cid) + end + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "time") then + npcHandler:say("Please don't be so rude to look for the time if you are talking to me.", cid) + npcHandler.topic[cid] = 3 + elseif msgcontains(msg, "help") then + npcHandler:say("I am deeply sorry, I can't help you.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "monster") or msgcontains(msg, "dungeon") then + npcHandler:say("UH! What a terrifying topic. Please let us speak about something more pleasant, I am a weak and small woman after all.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "sewer") then + npcHandler:say("What gives you the impression, I am the kind of women, you find in sewers?", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "god") then + npcHandler:say("You should ask about that in one of the temples.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "king") then + npcHandler:say("The king, that lives in this fascinating castle? I think he does look kind of cute in his luxurious robes, doesn't he?", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 10 + elseif msgcontains(msg, "sam") then + if Sex == PLAYERSEX_FEMALE then + npcHandler:say("He is soooo strong! What muscles! What a body! Did you ask him for a date?", cid) + else + npcHandler:say("He is soooo strong! What muscles! What a body! On the other hand, compared to you he looks quite puny.", cid) + end + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "benjamin") then + npcHandler:say("He is a little simple minded but always nice and well dressed.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "gorn") then + npcHandler:say("He should really sell some stylish gowns or something like that. We Tibians never get some clothing of the latest fashion. It's a shame.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "quentin") then + npcHandler:say("I don't understand this lonely monks. I love company too much to become one. Hehehe!", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "bozo") then + npcHandler:say("Oh, isn't he funny? I could listen to him the whole day.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "oswald") then + npcHandler:say("As far as I know, he is working in the castle.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "rumour") or msgcontains(msg, "rumor") or msgcontains(msg, "gossip") then + npcHandler:say("I am a little shy and so don't hear many rumors.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "kiss") and Sex == PLAYERSEX_MALE then + npcHandler:say("Oh, you little devil, stop talking like that! ", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 20 + elseif msgcontains(msg, "weapon") then + npcHandler:say("I know only little about weapons. Can you tell me something about them, please?", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "magic") then + npcHandler:say("I believe that love is stronger than magic, don't you agree?", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "thief") or msgcontains(msg, "theft") then + npcHandler:say("Oh, sorry, I have to hurry, bye!", cid) + npcHandler.topic[cid] = nil + Price[cid] = nil + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + elseif msgcontains(msg, "tibia") then + npcHandler:say("I would like to visit the beach more often, but I guess it's too dangerous.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "castle") then + npcHandler:say("I love this castle! It's so beautiful.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "muriel") then + npcHandler:say("Powerful sorcerers frighten me a little.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "elane") then + npcHandler:say("I personally think it's inappropriate for a woman to become a warrior, what do you think about that?", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "marvik") then + npcHandler:say("Druids seldom visit a town, what do you know about druids?", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "gregor") then + npcHandler:say("I like brave fighters like him.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "noodles") then + npcHandler:say("Oh, he is sooooo cute!", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "dog") or msgcontains(msg, "poodle") then + npcHandler:say("I like dogs, the little ones at least. Do you like dogs, too?", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "excalibug") then + npcHandler:say("Oh, I am just a girl and know nothing about magic swords and such things.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 10 + elseif msgcontains(msg, "partos") then + npcHandler:say("I ... don't know someone named like that.", cid) + npcHandler.topic[cid] = 4 + Price[cid] = nil + elseif msgcontains(msg, "yenny") then + npcHandler:say("Yenny? I know no Yenny, nor have I ever used that name! You have mistook me with someone else.", cid) + npcHandler.topic[cid] = nil + Price[cid] = nil + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, "I hope to see you soon.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye, |PLAYERNAME|. I really hope we'll talk again soon.") + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ashari.lua b/data/npc/scripts/ashari.lua new file mode 100644 index 00000000000..befaf43ae71 --- /dev/null +++ b/data/npc/scripts/ashari.lua @@ -0,0 +1,21 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:setMessage(MESSAGE_GREET, "Hello, stranger! These caves must seem strange to you. I wonder what brings you here... maybe you are interested in some work? There are several tasks I could need a hand with.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Bye!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Bye!") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ashtamor.lua b/data/npc/scripts/ashtamor.lua new file mode 100644 index 00000000000..3c2a488df45 --- /dev/null +++ b/data/npc/scripts/ashtamor.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'The passage to the afterlife is filled with obstacles, but I can help you with my wares.'} } +npcHandler:addModule(VoiceModule:new(voices)) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/asima.lua b/data/npc/scripts/asima.lua new file mode 100644 index 00000000000..bb7ede08a59 --- /dev/null +++ b/data/npc/scripts/asima.lua @@ -0,0 +1,56 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local items = { + [VOCATION.CLIENT_ID.SORCERER] = 2190, + [VOCATION.CLIENT_ID.DRUID] = 2182 +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'first rod') or msgcontains(msg, 'first wand') then + if player:isMage() then + local itemId = items[player:getVocation():getClientId()] + if player:getStorageValue(Storage.firstMageWeapon) == -1 then + npcHandler:say('So you ask me for a {' .. ItemType(itemId):getName() .. '} to begin your adventure?', cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say('What? I have already gave you one {' .. ItemType(itemId):getName() .. '}!', cid) + end + else + npcHandler:say('Sorry, you aren\'t a druid either a sorcerer.', cid) + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + player:addItem(itemId, 1) + npcHandler:say('Here you are young adept, take care yourself.', cid) + player:setStorageValue(Storage.firstMageWeapon, 1) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] == 1 then + npcHandler:say('Ok then.', cid) + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/asnarus.lua b/data/npc/scripts/asnarus.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/asnarus.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/asrak.lua b/data/npc/scripts/asrak.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/asrak.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/asralius.lua b/data/npc/scripts/asralius.lua new file mode 100644 index 00000000000..0c14951b13c --- /dev/null +++ b/data/npc/scripts/asralius.lua @@ -0,0 +1,22 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Let me speak a few words to you.' }, + { text = 'Death comes to the best of us, but this time you had no chance.' } +} +npcHandler:addModule(VoiceModule:new(voices)) diff --git a/data/npc/scripts/atrad.lua b/data/npc/scripts/atrad.lua new file mode 100644 index 00000000000..e0162fec748 --- /dev/null +++ b/data/npc/scripts/atrad.lua @@ -0,0 +1,68 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function greetCallback(cid) + local player = Player(cid) + local fire = player:getCondition(CONDITION_FIRE) + + if fire and (player:hasOutfit(156) or player:hasOutfit(152)) then + return true + end + return false +end + +function creatureSayCallback(cid, type, msg) + if(not npcHandler:isFocused(cid)) then + return false + end + + if(msgcontains(msg, "addon") or msgcontains(msg, "outfit")) then + if(getPlayerStorageValue(cid, Storage.Atrad) < 1) then + npcHandler:say("You managed to deceive Erayo? Impressive. Well, I guess, since you have come that far, I might as well give you a task too, eh?", cid) + npcHandler.topic[cid] = 2 + end + elseif(msgcontains(msg, "nose ring") or msgcontains(msg, "ring")) then + if(getPlayerStorageValue(cid, Storage.Atrad) == 1) then + if(getPlayerItemCount(cid, 5804) >= 1) and getPlayerItemCount(cid, 5930) >= 1 then + npcHandler:say("I see you brought my stuff. Good. I'll keep my promise: Here's katana in return.", cid) + doPlayerRemoveItem(cid, 5804, 1) + doPlayerRemoveItem(cid, 5930, 1) + doPlayerAddOutfit(cid, getPlayerSex(cid) == 0 and 156 or 152, 2) + setPlayerStorageValue(cid, Storage.Atrad, 2) -- exaust + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have it...", cid) + npcHandler.topic[cid] = 0 + end + end + elseif(msgcontains(msg, "yes")) then + if(npcHandler.topic[cid] == 2) then + npcHandler:say("Okay, listen up. I don't have a list of stupid objects, I just want two things. A behemoth claw and a nose ring. Got that?", cid) + npcHandler.topic[cid] = 3 + elseif(npcHandler.topic[cid] == 3) then + npcHandler:say("Good. Come back then you have BOTH. Should be clear where to get a behemoth claw from. There's a horned fox who wears a nose ring. Good luck.", cid) + setPlayerStorageValue(cid, Storage.Atrad, 1) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/aurita.lua b/data/npc/scripts/aurita.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/aurita.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/auron.lua b/data/npc/scripts/auron.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/auron.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/avar_tar.lua b/data/npc/scripts/avar_tar.lua new file mode 100644 index 00000000000..68ae721da2f --- /dev/null +++ b/data/npc/scripts/avar_tar.lua @@ -0,0 +1,114 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if npcHandler.topic[cid] == 0 then + if msgcontains(msg, 'outfit') then + npcHandler:say({ + 'I\'m tired of all these young unskilled wannabe heroes. Every Tibian can show his skills or actions by wearing a special outfit. To prove oneself worthy of the demon outfit, this is how it goes: ...', + 'The base outfit will be granted for completing the annihilator quest, which isn\'t much of a challenge nowadays, in my opinion. Anyway ...', + 'The shield however will only be granted to those adventurers who have finished the demon helmet quest. ...', + 'Well, the helmet is for those who really are tenacious and have hunted down all 6666 demons and finished the demon oak as well. ...', + 'Are you interested?' + }, cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, 'cookie') then + if player:getStorageValue(Storage.WhatAFoolish.Questline) == 31 + and player:getStorageValue(Storage.WhatAFoolish.CookieDelivery.AvarTar) ~= 1 then + npcHandler:say('Do you really think you could bribe a hero like me with a meagre cookie?', cid) + npcHandler.topic[cid] = 3 + end + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + npcHandler:say('So you want to have the demon outfit, hah! Let\'s have a look first if you really deserve it. Tell me: {base}, {shield} or {helmet}?', cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 3 then + if not player:removeItem(8111, 1) then + npcHandler:say('You have no cookie that I\'d like.', cid) + npcHandler.topic[cid] = 0 + return true + end + + player:setStorageValue(Storage.WhatAFoolish.CookieDelivery.AvarTar, 1) + if player:getCookiesDelivered() == 10 then + player:addAchievement('Allow Cookies?') + end + + Npc():getPosition():sendMagicEffect(CONST_ME_GIFT_WRAPS) + npcHandler:say('Well, you won\'t! Though it looks tasty ...What the ... WHAT DO YOU THINK YOU ARE? THIS IS THE ULTIMATE INSULT! GET LOST!', cid) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + elseif msgcontains(msg, 'no') then + if npcHandler.topic[cid] == 3 then + npcHandler:say('I see.', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, 'base') then + if player:getStorageValue(Storage.Quest.TheAnnihilator.Reward) == 1 then + player:addOutfit(541) + player:addOutfit(542) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:setStorageValue(Storage.Quest.TheAnnihilator.Reward, 2) + npcHandler:say('Receive the base outfit, |PLAYERNAME|.', cid) + else + npcHandler:say('You need to complete annihilator quest first, |PLAYERNAME|.', cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, 'shield') then + if player:getStorageValue(Storage.Quest.TheAnnihilator.Reward) == 2 + and player:getStorageValue(Storage.Quest.DemonHelmet.DemonHelmet) == 1 then + player:addOutfitAddon(541, 1) + player:addOutfitAddon(542, 1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:setStorageValue(Storage.Quest.DemonHelmet.DemonHelmet, 2) + npcHandler:say('Receive the shield, |PLAYERNAME|.', cid) + else + npcHandler:say('The shield will only be granted to those adventurers who have finished the demon helmet quest, |PLAYERNAME|.', cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, 'helmet') then + if player:getStorageValue(Storage.Quest.TheAnnihilator.Reward) == 2 + and player:getStorageValue(Storage.DemonOak.Done) == 3 then + player:addOutfitAddon(541, 2) + player:addOutfitAddon(542, 2) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:setStorageValue(Storage.DemonOak.Done, 4) + npcHandler:say('Receive the helmet, |PLAYERNAME|.', cid) + else + npcHandler:say('The helmet is for those who have hunted down all 6666 demons and finished the demon oak as well, |PLAYERNAME|.', cid) + npcHandler.topic[cid] = 2 + end + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, 'Greetings, traveller |PLAYERNAME|!') +npcHandler:setMessage(MESSAGE_FAREWELL, 'See you later, |PLAYERNAME|.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'See you later, |PLAYERNAME|.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/awareness_of_the_emperor.lua b/data/npc/scripts/awareness_of_the_emperor.lua new file mode 100644 index 00000000000..5e7e216364b --- /dev/null +++ b/data/npc/scripts/awareness_of_the_emperor.lua @@ -0,0 +1,59 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, "mission") then + local player = Player(cid) + if player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 30 and player:getStorageValue(Storage.WrathoftheEmperor.BossStatus) == 5 then + npcHandler:say({ + "The amplified force of the snake god is tearing the land apart. It is using my crystals in a reverse way to drain the vital force from the land and its inhabitants to fuel its power. ...", + "I will withstand its influence as good as possible and slow this process. You will have to fight its worldly incarnation though. ...", + "It is still weak and disoriented. You might stand a chance - this is our only chance. I will send you to the point to where the vital force is channelled. I have no idea where that might be though. ...", + "You will probably have to fight some sort of vessel the snake god uses. Even if you defeat it, it is likely that it only weakens the snake. ...", + "You might have to fight several incarnations until the snake god is worn out enough. Then use the power of the snake's own sceptre against it. Use it on its corpse to claim your victory. ...", + "Be prepared for the fight of your life! Are you ready?" + }, cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 32 then + npcHandler:say({ + "So you have mastered the crisis you invoked with your foolishness. I should crush you for your involvement right here and now. ...", + "But such an act would bring me down to your own barbaric level and only fuel the corruption that destroys the land that I own. Therefore I will not only spare your miserable life but show your the generosity of the dragon emperor. ...", + "I will reward you beyond your wildest dreams! ...", + "I grant you three chests - filled to the lid with platinum coins, a house in the city in which you may reside, a set of the finest armor Zao has to offer, and a casket of never-ending mana. ...", + "Speak with magistrate Izsh in the ministry about your reward. And now leave before I change my mind!" + }, cid) + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 33) + player:setStorageValue(Storage.WrathoftheEmperor.Mission12, 0) --Questlog, Wrath of the Emperor "Mission 12: Just Rewards" + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + local player = Player(cid) + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 31) + player:setStorageValue(Storage.WrathoftheEmperor.Mission11, 1) --Questlog, Wrath of the Emperor "Mission 11: Payback Time" + npcHandler:say("So be it!", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/azalea.lua b/data/npc/scripts/azalea.lua new file mode 100644 index 00000000000..98d74790c50 --- /dev/null +++ b/data/npc/scripts/azalea.lua @@ -0,0 +1,95 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Twist of Fate +local blessKeyword = keywordHandler:addKeyword({'twist of fate'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'This is a special blessing I can bestow upon you once you have obtained at least one of the other blessings and which functions a bit differently. ...', + 'It only works when you\'re killed by other adventurers, which means that at least half of the damage leading to your death was caused by others, not by monsters or the environment. ...', + 'The {twist of fate} will not reduce the death penalty like the other blessings, but instead prevent you from losing your other blessings as well as the amulet of loss, should you wear one. It costs the same as the other blessings. ...', + 'Would you like to receive that protection for a sacrifice of |PVPBLESSCOST| gold, child?' + }}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the protection of the twist of fate, pilgrim.', cost = '|PVPBLESSCOST|', bless = 1}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Adventurer Stone +keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Keep your adventurer\'s stone well.'}, function(player) return player:getItemById(18559, true) end) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for free?'}, function(player) return player:getStorageValue(Storage.AdventurersGuild.FreeStone.Alia) ~= 1 end) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, nil, function(player) player:addItem(18559, 1) player:setStorageValue(Storage.AdventurersGuild.FreeStone.Alia, 1) end) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for 30 gold?'}) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, + function(player) return player:getMoney() + player:getBankBalance() >= 30 end, + function(player) if player:removeMoneyNpc(30) then player:addItem(18559, 1) end end + ) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, you don\'t have enough money.', reset = true}) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.'}, function(player) return player:hasBlessing(2) end) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin will provide you with the embrace of Tibia.'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, young |PLAYERNAME|! If you are heavily wounded or poisoned, I can {heal} you for free.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Remember: If you are heavily wounded or poisoned, I can heal you for free.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'May the gods bless you, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/azil.lua b/data/npc/scripts/azil.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/azil.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/baa_leal.lua b/data/npc/scripts/baa_leal.lua new file mode 100644 index 00000000000..ebe2a4926c9 --- /dev/null +++ b/data/npc/scripts/baa_leal.lua @@ -0,0 +1,120 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(150, 2000, -10) + +local function greetCallback(cid, message) + local player = Player(cid) + if not player:getCondition(CONDITION_FIRE) and not msgcontains(message, "djanni'hah") then + player:getPosition():sendMagicEffect(CONST_ME_EXPLOSIONAREA) + player:addCondition(condition) + npcHandler:say('Take this!', cid) + return false + end + + if player:getStorageValue(Storage.DjinnWar.EfreetFaction.Mission01) < 1 then + npcHandler:setMessage(MESSAGE_GREET, 'You know the code human! Very well then... What do you want, |PLAYERNAME|?') + else + npcHandler:setMessage(MESSAGE_GREET, 'You are still alive, |PLAYERNAME|? Well, what do you want?') + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + local missionProgress = player:getStorageValue(Storage.DjinnWar.EfreetFaction.Mission01) + if msgcontains(msg, 'mission') then + if missionProgress < 1 then + npcHandler:say({ + 'Each mission and operation is a crucial step towards our victory! ...', + 'Now that we speak of it ...', + 'Since you are no djinn, there is something you could help us with. Are you interested, human?' + }, cid) + npcHandler.topic[cid] = 1 + + elseif isInArray({1, 2}, missionProgress) then + npcHandler:say('Did you find the thief of our supplies?', cid) + npcHandler.topic[cid] = 2 + else + npcHandler:say('Did you already talk to Alesar? He has another mission for you!', cid) + end + + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, 'yes') then + npcHandler:say({ + 'Well ... All right. You may only be a human, but you do seem to have the right spirit. ...', + 'Listen! Since our base of operations is set in this isolated spot we depend on supplies from outside. These supplies are crucial for us to win the war. ...', + 'Unfortunately, it has happened that some of our supplies have disappeared on their way to this fortress. At first we thought it was the Marid, but intelligence reports suggest a different explanation. ...', + 'We now believe that a human was behind the theft! ...', + 'His identity is still unknown but we have been told that the thief fled to the human settlement called Carlin. I want you to find him and report back to me. Nobody messes with the Efreet and lives to tell the tale! ...', + 'Now go! Travel to the northern city Carlin! Keep your eyes open and look around for something that might give you a clue!' + }, cid) + player:setStorageValue(Storage.DjinnWar.EfreetFaction.Start, 1) + player:setStorageValue(Storage.DjinnWar.EfreetFaction.Mission01, 1) + + elseif msgcontains(msg, 'no') then + npcHandler:say('After all, you\'re just a human.', cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, 'yes') then + npcHandler:say('Finally! What is his name then?', cid) + npcHandler.topic[cid] = 3 + + elseif msgcontains(msg, 'no') then + npcHandler:say('Then go to Carlin and search for him! Look for something that might give you a clue!', cid) + npcHandler.topic[cid] = 0 + end + + elseif npcHandler.topic[cid] == 3 then + if msgcontains(msg, 'partos') then + if missionProgress ~= 2 then + npcHandler:say('Hmmm... I don\'t think so. Return to Thais and continue your search!', cid) + else + npcHandler:say({ + 'You found the thief! Excellent work, soldier! You are doing well - for a human, that is. Here - take this as a reward. ...', + 'Since you have proven to be a capable soldier, we have another mission for you. ...', + 'If you are interested go to Alesar and ask him about it.' + }, cid) + player:addMoney(600) + player:setStorageValue(Storage.DjinnWar.EfreetFaction.Mission01, 3) + end + + else + npcHandler:say('Hmmm... I don\'t think so. Return to Thais and continue your search!', cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +-- Greeting message +keywordHandler:addGreetKeyword({"djanni'hah"}, {npcHandler = npcHandler, text = "What do you want from me, |PLAYERNAME|?"}) + +npcHandler:setMessage(MESSAGE_FAREWELL, 'Stand down, soldier!') + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/baltim.lua b/data/npc/scripts/baltim.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/baltim.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/bambi_bonecrusher.lua b/data/npc/scripts/bambi_bonecrusher.lua new file mode 100644 index 00000000000..d4f730797e5 --- /dev/null +++ b/data/npc/scripts/bambi_bonecrusher.lua @@ -0,0 +1,42 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(10, 1000, -10) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if isInArray({"fuck", "idiot", "asshole", "ass", "fag", "stupid", "tyrant", "shit", "lunatic"}, msg) then + npcHandler:say("Take this!", cid) + local player = Player(cid) + player:getPosition():sendMagicEffect(CONST_ME_EXPLOSIONAREA) + player:addCondition(condition) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "LONG LIVE THE QUEEN!") +npcHandler:setMessage(MESSAGE_FAREWELL, "LONG LIVE THE QUEEN!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "LONG LIVE THE QUEEN!") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/bank.lua b/data/npc/scripts/bank.lua new file mode 100644 index 00000000000..94c243ea182 --- /dev/null +++ b/data/npc/scripts/bank.lua @@ -0,0 +1,649 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +local count = {} +local transfer = {} + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local voices = { {text = 'Don\'t forget to deposit your money here in the Global Bank before you head out for adventure.'} } +if VoiceModule then + npcHandler:addModule(VoiceModule:new(voices)) +end +--------------------------------guild bank----------------------------------------------- +local receiptFormat = 'Date: %s\nType: %s\nGold Amount: %d\nReceipt Owner: %s\nRecipient: %s\n\n%s' +local function getReceipt(info) + local receipt = Game.createItem(info.success and 24301 or 24302) + receipt:setAttribute(ITEM_ATTRIBUTE_TEXT, receiptFormat:format(os.date('%d. %b %Y - %H:%M:%S'), info.type, info.amount, info.owner, info.recipient, info.message)) + + return receipt +end + +local function getGuildIdByName(name, func) + db.asyncStoreQuery('SELECT `id` FROM `guilds` WHERE `name` = ' .. db.escapeString(name), + function(resultId) + if resultId then + func(result.getNumber(resultId, 'id')) + result.free(resultId) + else + func(nil) + end + end + ) +end + +local function getGuildBalance(id) + local guild = Guild(id) + if guild then + return guild:getBankBalance() + else + local balance + local resultId = db.storeQuery('SELECT `balance` FROM `guilds` WHERE `id` = ' .. id) + if resultId then + balance = result.getNumber(resultId, 'balance') + result.free(resultId) + end + + return balance + end +end + +local function setGuildBalance(id, balance) + local guild = Guild(id) + if guild then + guild:setBankBalance(balance) + else + db.query('UPDATE `guilds` SET `balance` = ' .. balance .. ' WHERE `id` = ' .. id) + end +end + +local function transferFactory(playerName, amount, fromGuildId, info) + return function(toGuildId) + if not toGuildId then + local player = Player(playerName) + if player then + info.success = false + info.message = 'We are sorry to inform you that we could not fulfil your request, because we could not find the recipient guild.' + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + end + else + local fromBalance = getGuildBalance(fromGuildId) + if fromBalance < amount then + info.success = false + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your guild account.' + else + info.success = true + info.message = 'We are happy to inform you that your transfer request was successfully carried out.' + setGuildBalance(fromGuildId, fromBalance - amount) + setGuildBalance(toGuildId, getGuildBalance(toGuildId) + amount) + end + + local player = Player(playerName) + if player then + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + end + end + end +end +--------------------------------guild bank----------------------------------------------- + +local function greetCallback(cid) + count[cid], transfer[cid] = nil, nil + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) +---------------------------- help ------------------------ + if msgcontains(msg, 'bank account') then + npcHandler:say({ + 'Every citizen has one. The big advantage is that you can access your money in every branch of the Global Bank! ...', + 'Would you like to know more about the {basic} functions of your bank account, the {advanced} functions, or are you already bored, perhaps?' + }, cid) + npcHandler.topic[cid] = 0 + return true +---------------------------- balance --------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild balance') then + npcHandler.topic[cid] = 0 + if not player:getGuild() then + npcHandler:say('You are not a member of a guild.', cid) + return false + end + npcHandler:say('Your guild account balance is ' .. player:getGuild():getBankBalance() .. ' gold.', cid) + return true +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'balance') then + npcHandler.topic[cid] = 0 + if player:getBankBalance() >= 100000000 then + npcHandler:say('I think you must be one of the richest inhabitants in the world! Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + elseif player:getBankBalance() >= 10000000 then + npcHandler:say('You have made ten millions and it still grows! Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + elseif player:getBankBalance() >= 1000000 then + npcHandler:say('Wow, you have reached the magic number of a million gp!!! Your account balance is ' .. player:getBankBalance() .. ' gold!', cid) + return true + elseif player:getBankBalance() >= 100000 then + npcHandler:say('You certainly have made a pretty penny. Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + else + npcHandler:say('Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + end +---------------------------- deposit --------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild deposit') then + if not player:getGuild() then + npcHandler:say('You are not a member of a guild.', cid) + npcHandler.topic[cid] = 0 + return false + end + -- count[cid] = player:getMoney() + -- if count[cid] < 1 then + -- npcHandler:say('You do not have enough gold.', cid) + -- npcHandler.topic[cid] = 0 + -- return false + --end + if string.match(msg, '%d+') then + count[cid] = getMoneyCount(msg) + if count[cid] < 1 then + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return false + end + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold to your {guild account}?', cid) + npcHandler.topic[cid] = 23 + return true + else + npcHandler:say('Please tell me how much gold it is you would like to deposit.', cid) + npcHandler.topic[cid] = 22 + return true + end + elseif npcHandler.topic[cid] == 22 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold to your {guild account}?', cid) + npcHandler.topic[cid] = 23 + return true + else + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return true + end + elseif npcHandler.topic[cid] == 23 then + if msgcontains(msg, 'yes') then + npcHandler:say('Alright, we have placed an order to deposit the amount of ' .. count[cid] .. ' gold to your guild account. Please check your inbox for confirmation.', cid) + local guild = player:getGuild() + local info = { + type = 'Guild Deposit', + amount = count[cid], + owner = player:getName() .. ' of ' .. guild:getName(), + recipient = guild:getName() + } + local playerBalance = player:getBankBalance() + if playerBalance < tonumber(count[cid]) then + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your bank account.' + info.success = false + else + info.message = 'We are happy to inform you that your transfer request was successfully carried out.' + info.success = true + guild:setBankBalance(guild:getBankBalance() + tonumber(count[cid])) + player:setBankBalance(playerBalance - tonumber(count[cid])) + end + + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish. Is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 + return true +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'deposit') then + count[cid] = player:getMoney() + if count[cid] < 1 then + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return false + end + if msgcontains(msg, 'all') then + count[cid] = player:getMoney() + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid) + npcHandler.topic[cid] = 2 + return true + else + if string.match(msg,'%d+') then + count[cid] = getMoneyCount(msg) + if count[cid] < 1 then + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return false + end + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid) + npcHandler.topic[cid] = 2 + return true + else + npcHandler:say('Please tell me how much gold it is you would like to deposit.', cid) + npcHandler.topic[cid] = 1 + return true + end + end + if not isValidMoney(count[cid]) then + npcHandler:say('Sorry, but you can\'t deposit that much.', cid) + npcHandler.topic[cid] = 0 + return false + end + elseif npcHandler.topic[cid] == 1 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid) + npcHandler.topic[cid] = 2 + return true + else + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return true + end + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, 'yes') then + if player:depositMoney(count[cid]) then + npcHandler:say('Alright, we have added the amount of ' .. count[cid] .. ' gold to your {balance}. You can {withdraw} your money anytime you want to.', cid) + else + npcHandler:say('You do not have enough gold.', cid) + end + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish. Is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 + return true +---------------------------- withdraw -------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild withdraw') then + if not player:getGuild() then + npcHandler:say('I am sorry but it seems you are currently not in any guild.', cid) + npcHandler.topic[cid] = 0 + return false + elseif player:getGuildLevel() < 2 then + npcHandler:say('Only guild leaders or vice leaders can withdraw money from the guild account.', cid) + npcHandler.topic[cid] = 0 + return false + end + + if string.match(msg,'%d+') then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your guild account?', cid) + npcHandler.topic[cid] = 25 + else + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + end + return true + else + npcHandler:say('Please tell me how much gold you would like to withdraw from your guild account.', cid) + npcHandler.topic[cid] = 24 + return true + end + elseif npcHandler.topic[cid] == 24 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your guild account?', cid) + npcHandler.topic[cid] = 25 + else + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + end + return true + elseif npcHandler.topic[cid] == 25 then + if msgcontains(msg, 'yes') then + local guild = player:getGuild() + local balance = guild:getBankBalance() + npcHandler:say('We placed an order to withdraw ' .. count[cid] .. ' gold from your guild account. Please check your inbox for confirmation.', cid) + local info = { + type = 'Guild Withdraw', + amount = count[cid], + owner = player:getName() .. ' of ' .. guild:getName(), + recipient = player:getName() + } + if balance < tonumber(count[cid]) then + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your guild account.' + info.success = false + else + info.message = 'We are happy to inform you that your transfer request was successfully carried out.' + info.success = true + guild:setBankBalance(balance - tonumber(count[cid])) + local playerBalance = player:getBankBalance() + player:setBankBalance(playerBalance + tonumber(count[cid])) + end + + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish. Is there something else I can do for you?', cid) + npcHandler.topic[cid] = 0 + end + return true +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'withdraw') then + if string.match(msg,'%d+') then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your bank account?', cid) + npcHandler.topic[cid] = 7 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + return true + else + npcHandler:say('Please tell me how much gold you would like to withdraw.', cid) + npcHandler.topic[cid] = 6 + return true + end + elseif npcHandler.topic[cid] == 6 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your bank account?', cid) + npcHandler.topic[cid] = 7 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + return true + elseif npcHandler.topic[cid] == 7 then + if msgcontains(msg, 'yes') then + if player:getFreeCapacity() >= getMoneyWeight(count[cid]) then + if not player:withdrawMoney(count[cid]) then + npcHandler:say('There is not enough gold on your account.', cid) + else + npcHandler:say('Here you are, ' .. count[cid] .. ' gold. Please let me know if there is something else I can do for you.', cid) + end + else + npcHandler:say('Whoah, hold on, you have no room in your inventory to carry all those coins. I don\'t want you to drop it on the floor, maybe come back with a cart!', cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') then + npcHandler:say('The customer is king! Come back anytime you want to if you wish to {withdraw} your money.', cid) + npcHandler.topic[cid] = 0 + end + return true +---------------------------- transfer -------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild transfer') then + if not player:getGuild() then + npcHandler:say('I am sorry but it seems you are currently not in any guild.', cid) + npcHandler.topic[cid] = 0 + return false + elseif player:getGuildLevel() < 2 then + npcHandler:say('Only guild leaders or vice leaders can transfer money from the guild account.', cid) + npcHandler.topic[cid] = 0 + return false + end + + if string.match(msg, '%d+') then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + transfer[cid] = string.match(msg, 'to%s*(.+)$') + if transfer[cid] then + npcHandler:say('So you would like to transfer ' .. count[cid] .. ' gold from your guild account to guild ' .. transfer[cid] .. '?', cid) + npcHandler.topic[cid] = 28 + else + npcHandler:say('Which guild would you like to transfer ' .. count[cid] .. ' gold to?', cid) + npcHandler.topic[cid] = 27 + end + else + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + end + else + npcHandler:say('Please tell me the amount of gold you would like to transfer.', cid) + npcHandler.topic[cid] = 26 + end + return true + elseif npcHandler.topic[cid] == 26 then + count[cid] = getMoneyCount(msg) + if player:getGuild():getBankBalance() < count[cid] then + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + return true + end + if isValidMoney(count[cid]) then + npcHandler:say('Which guild would you like to transfer ' .. count[cid] .. ' gold to?', cid) + npcHandler.topic[cid] = 27 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + return true + elseif npcHandler.topic[cid] == 27 then + transfer[cid] = msg + if player:getGuild():getName() == transfer[cid] then + npcHandler:say('Fill in this field with person who receives your gold!', cid) + npcHandler.topic[cid] = 0 + return true + end + npcHandler:say('So you would like to transfer ' .. count[cid] .. ' gold from your guild account to guild ' .. transfer[cid] .. '?', cid) + npcHandler.topic[cid] = 28 + return true + elseif npcHandler.topic[cid] == 28 then + if msgcontains(msg, 'yes') then + npcHandler:say('We have placed an order to transfer ' .. count[cid] .. ' gold from your guild account to guild ' .. transfer[cid] .. '. Please check your inbox for confirmation.', cid) + local guild = player:getGuild() + local balance = guild:getBankBalance() + local info = { + type = 'Guild to Guild Transfer', + amount = count[cid], + owner = player:getName() .. ' of ' .. guild:getName(), + recipient = transfer[cid] + } + if balance < tonumber(count[cid]) then + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your guild account.' + info.success = false + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + else + getGuildIdByName(transfer[cid], transferFactory(player:getName(), tonumber(count[cid]), guild:getId(), info)) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') then + npcHandler:say('Alright, is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'transfer') then + npcHandler:say('Please tell me the amount of gold you would like to transfer.', cid) + npcHandler.topic[cid] = 11 + elseif npcHandler.topic[cid] == 11 then + count[cid] = getMoneyCount(msg) + if player:getBankBalance() < count[cid] then + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + return true + end + if isValidMoney(count[cid]) then + npcHandler:say('Who would you like transfer ' .. count[cid] .. ' gold to?', cid) + npcHandler.topic[cid] = 12 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 12 then + transfer[cid] = msg + if player:getName() == transfer[cid] then + npcHandler:say('Fill in this field with person who receives your gold!', cid) + npcHandler.topic[cid] = 0 + return true + end + if playerExists(transfer[cid]) then + local arrayDenied = {"accountmanager", "rooksample", "druidsample", "sorcerersample", "knightsample", "paladinsample"} + if isInArray(arrayDenied, string.gsub(transfer[cid]:lower(), " ", "")) then + npcHandler:say('This player does not exist.', cid) + npcHandler.topic[cid] = 0 + return true + end + npcHandler:say('So you would like to transfer ' .. count[cid] .. ' gold to ' .. transfer[cid] .. '?', cid) + npcHandler.topic[cid] = 13 + else + npcHandler:say('This player does not exist.', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 13 then + if msgcontains(msg, 'yes') then + if not player:transferMoneyTo(transfer[cid], count[cid]) then + npcHandler:say("I'm afraid this character only holds a junior account at our bank. Do not worry, though. Once he has chosen his vocation or is no longer on Dawnport, his account will be upgraded.", cid) + else + npcHandler:say('Very well. You have transferred ' .. count[cid] .. ' gold to ' .. transfer[cid] ..'.', cid) + transfer[cid] = nil + end + elseif msgcontains(msg, 'no') then + npcHandler:say('Alright, is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 +---------------------------- money exchange -------------- + elseif msgcontains(msg, 'change gold') then + npcHandler:say('How many platinum coins would you like to get?', cid) + npcHandler.topic[cid] = 14 + elseif npcHandler.topic[cid] == 14 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough gold coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] * 100 .. ' of your gold coins into ' .. count[cid] .. ' platinum coins?', cid) + npcHandler.topic[cid] = 15 + end + elseif npcHandler.topic[cid] == 15 then + if msgcontains(msg, 'yes') then + if player:removeItem(2148, count[cid] * 100) then + player:addItem(2152, count[cid]) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough gold coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'change platinum') then + npcHandler:say('Would you like to change your platinum coins into gold or crystal?', cid) + npcHandler.topic[cid] = 16 + elseif npcHandler.topic[cid] == 16 then + if msgcontains(msg, 'gold') then + npcHandler:say('How many platinum coins would you like to change into gold?', cid) + npcHandler.topic[cid] = 17 + elseif msgcontains(msg, 'crystal') then + npcHandler:say('How many crystal coins would you like to get?', cid) + npcHandler.topic[cid] = 19 + else + npcHandler:say('Well, can I help you with something else?', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 17 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] .. ' of your platinum coins into ' .. count[cid] * 100 .. ' gold coins for you?', cid) + npcHandler.topic[cid] = 18 + end + elseif npcHandler.topic[cid] == 18 then + if msgcontains(msg, 'yes') then + if player:removeItem(2152, count[cid]) then + player:addItem(2148, count[cid] * 100) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 19 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] * 100 .. ' of your platinum coins into ' .. count[cid] .. ' crystal coins for you?', cid) + npcHandler.topic[cid] = 20 + end + elseif npcHandler.topic[cid] == 20 then + if msgcontains(msg, 'yes') then + if player:removeItem(2152, count[cid] * 100) then + player:addItem(2160, count[cid]) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'change crystal') then + npcHandler:say('How many crystal coins would you like to change into platinum?', cid) + npcHandler.topic[cid] = 21 + elseif npcHandler.topic[cid] == 21 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough crystal coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] .. ' of your crystal coins into ' .. count[cid] * 100 .. ' platinum coins for you?', cid) + npcHandler.topic[cid] = 22 + end + elseif npcHandler.topic[cid] == 22 then + if msgcontains(msg, 'yes') then + if player:removeItem(2160, count[cid]) then + player:addItem(2152, count[cid] * 100) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough crystal coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'money'}, StdModule.say, {npcHandler = npcHandler, text = 'We can {change} money for you. You can also access your {bank account}.'}) +keywordHandler:addKeyword({'change'}, StdModule.say, {npcHandler = npcHandler, text = 'There are three different coin types in Global Bank: 100 gold coins equal 1 platinum coin, 100 platinum coins equal 1 crystal coin. So if you\'d like to change 100 gold into 1 platinum, simply say \'{change gold}\' and then \'1 platinum\'.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'We can {change} money for you. You can also access your {bank account}.'}) +keywordHandler:addKeyword({'advanced'}, StdModule.say, {npcHandler = npcHandler, text = 'Your bank account will be used automatically when you want to {rent} a house or place an offer on an item on the {market}. Let me know if you want to know about how either one works.'}) +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'You can check the {balance} of your bank account, {deposit} money or {withdraw} it. You can also {transfer} money to other characters, provided that they have a vocation.'}) +keywordHandler:addKeyword({'functions'}, StdModule.say, {npcHandler = npcHandler, text = 'You can check the {balance} of your bank account, {deposit} money or {withdraw} it. You can also {transfer} money to other characters, provided that they have a vocation.'}) +keywordHandler:addKeyword({'basic'}, StdModule.say, {npcHandler = npcHandler, text = 'You can check the {balance} of your bank account, {deposit} money or {withdraw} it. You can also {transfer} money to other characters, provided that they have a vocation.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I work in this bank. I can change money for you and help you with your bank account.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Yes? What may I do for you, |PLAYERNAME|? Bank business, perhaps?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Have a nice day.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Have a nice day.") +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/barazbaz.lua b/data/npc/scripts/barazbaz.lua new file mode 100644 index 00000000000..a200298e506 --- /dev/null +++ b/data/npc/scripts/barazbaz.lua @@ -0,0 +1,59 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "ritual") and player:getStorageValue(Storage.DarkTrails.Mission06) == 1 then + npcHandler:say({ + "Ancient structures in the sewers you say? Well, our city has had a certain bloody past, even before it has \z + been city at all. But to investigate the archives for what you may have found is a time-consuming process. ...", + "Usually, I'm too much bound to my duties to the city to sacrifice time for such an endeavour. ...", + "But on the other hand, just now is the time of an important decision of the magistrate concerning the funding of the archives. It is a matter easily overlooked by our good citizens. ...", + "If you'd be so kind to place just one of your votes for the funding of the archives, I would be inclined to take the time for your investigation in turn. ...", + "Just go to Marvin in the magistrate and vote for a greater funding of the archives. Afterwards, I might be able to present you with some first results of my investigations on your behalf." + }, 10, false, true, cid) + player:setStorageValue(Storage.DarkTrails.Mission07, 1) + elseif msgcontains(msg, "abandoned sewers") and player:getStorageValue(Storage.DarkTrails.Mission08) == 1 then + npcHandler:say({ + "Excellent! Concerning the ancient ruins that you have found, well, if you are not familiar with the city's history, feel free to browse a few books here. I will only refer to some basics here, so I don't waste your time. ...", + "The first humans that lived here and that we have any records of lived in slavery of an ancient evil. ...", + "The nature of this evil is up to debate, but there are hints that this evil predated the settlement of men and that it perhaps was part of a more ancient civilisation or caused the downfall of the latter. ...", + "After that evil had been overcome, much was sealed away. Some say that only forbidden knowledge had been sealed, but others like me were always worried that more had been hidden. ...", + "Something like the ruins you have found. What you have seen there hints to a new incident, though. As if someone or something was searching for something. In the past, when those ruins were buried, people were primitive and superstitious. ...", + "Today, we have advanced far more and could have the ruins investigated in a far more efficient way. And that is what I would just recommend you to do: get a necrometer from magistrate Jondrin upstairs and investigate the ruins thoroughly." + }, 10, false, true, cid) + player:setStorageValue(Storage.DarkTrails.Mission09, 1) + elseif(msgcontains(msg, "notebook")) and (player:getStorageValue(Storage.DarkTrails.Mission11) == 1 and getPlayerItemCount(cid, 12406) == 1) then + npcHandler:say({ + " I know that handwriting you describe! It belongs to a traveller from far away. Magistrate Sholley introduced him to me and she was quite excited to learn more about our city's past. ...", + "I should have thought of him right in the beginning when I heard the stuff you mentioned. But I haven't seen him for a while. You should ask Sholley about her friend to learn about his whereabouts." + }, 10, false, true, cid) + player:setStorageValue(Storage.DarkTrails.Mission12, 1) + doPlayerRemoveItem(cid,12406, 1) + else + npcHandler:say("You need to kill the {The Ravager}, click on statue and then come here say {ritual}, {abandoned sewers}, {notebook} and after this find Roswitha and talk with she.", cid) + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/barbara.lua b/data/npc/scripts/barbara.lua new file mode 100644 index 00000000000..8e7e1e28770 --- /dev/null +++ b/data/npc/scripts/barbara.lua @@ -0,0 +1,52 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +keywordHandler:addKeyword({'hi'}, StdModule.say, {npcHandler = npcHandler, onlyUnfocus = true, text = "MIND YOUR MANNERS COMMONER! To address the queen greet with her title!"}) +keywordHandler:addKeyword({'hello'}, StdModule.say, {npcHandler = npcHandler, onlyUnfocus = true, text = "MIND YOUR MANNERS COMMONER! To address the queen greet with her title!"}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if isInArray({'fuck', 'idiot', 'asshole', 'ass', 'fag', 'stupid', 'tyrant', 'shit', 'lunatic'}, msg) then + local player = Player(cid) + local conditions = { CONDITION_POISON, CONDITION_FIRE, CONDITION_ENERGY, CONDITION_BLEEDING, CONDITION_PARALYZE, CONDITION_DROWN, CONDITION_FREEZING, CONDITION_DAZZLED, CONDITION_CURSED } + for i = 1, #conditions do + if player:getCondition(conditions[i]) then + player:removeCondition(conditions[i]) + end + end + player:getPosition():sendMagicEffect(CONST_ME_EXPLOSIONAREA) + player:addHealth(1 - player:getHealth()) + npcHandler:say('Take this!', cid) + Npc():getPosition():sendMagicEffect(CONST_ME_YELLOW_RINGS) + end + return true +end + +-- Greeting +keywordHandler:addGreetKeyword({'hail queen'}, {npcHandler = npcHandler, text = 'HAIL TO THE QUEEN!'}) +keywordHandler:addGreetKeyword({'salutations queen'}, {npcHandler = npcHandler, text = 'HAIL TO THE QUEEN!'}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'LONG LIVE THE QUEEN!') +npcHandler:setMessage(MESSAGE_FAREWELL, 'LONG LIVE THE QUEEN! You may leave now!') +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/barnabas_dee.lua b/data/npc/scripts/barnabas_dee.lua new file mode 100644 index 00000000000..b3e9221ea10 --- /dev/null +++ b/data/npc/scripts/barnabas_dee.lua @@ -0,0 +1,99 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function creatureSayCallback(cid, type, msg) + if(not(npcHandler:isFocused(cid))) then + return false + end + + local player = Player(cid) + if (msgcontains(msg, "mission")) then + if player:getStorageValue(Storage.Oramond.PeppermoonBell) < 1 then + npcHandler:say({ + "I am afraid my supplies of peppermoon bell powder have gone flat again. Please provide me with the pollen of this flower. ...", + "It only blooms underground in a cavern to the northwest. I will need 15 units of pollen. Bring them to me and we shall conduct a séance."}, cid) + player:setStorageValue(Storage.Oramond.PeppermoonBell, 1) + player:setStorageValue(Storage.Oramond.PeppermoonBellCount, 0) + npcHandler.topic[cid] = 0 + if player:getStorageValue(Storage.Oramond.QuestLine) < 1 then + player:setStorageValue(Storage.Oramond.QuestLine, 1) + end + elseif player:getStorageValue(Storage.Oramond.PeppermoonBell) == 1 then + npcHandler:say("Ah! Did you bring me the peppermoon bell pollen I asked for?", cid) + npcHandler.topic[cid] = 1 + end + end + if (msgcontains(msg, "yes")) then + if npcHandler.topic[cid] == 1 then + if player:getStorageValue(Storage.Oramond.PeppermoonBellCount) >= 15 then + if player:getStorageValue(Storage.DarkTrails.Mission15) == 1 then + npcHandler:say("Ah! Well done! Now we shall proceed with the seance, yes?", cid) + player:setStorageValue(Storage.Oramond.PeppermoonBell, -1) + player:setStorageValue(Storage.Oramond.PeppermoonBellCount, -15) + player:setStorageValue(Storage.DarkTrails.Mission15, 2) + player:removeItem(23460, 15) + npcHandler.topic[cid] = 2 + else + npcHandler:say("Ah! Well done! These 15 doses will suffice for now. Here, take this vote for your effort.", cid) + player:setStorageValue(Storage.Oramond.PeppermoonBell, -1) + player:setStorageValue(Storage.Oramond.PeppermoonBellCount, -15) + player:setStorageValue(Storage.Oramond.VotingPoints, player:getStorageValue(Storage.Oramond.VotingPoints) + 1) + player:removeItem(23460, 15) + npcHandler.topic[cid] = 0 + end + else + npcHandler:say("No no no, I need 15 doses of freshly harvested pollen! Please, harvest those 15 doses yourself, to make absolutely sure you have first-rate quality. I am afraid nothing less will do.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 2 then + npcHandler:say("Splendid. Let me make the final preparations... There. Are you ready, too?", cid) + npcHandler.topic[cid] = 3 + elseif npcHandler.topic[cid] == 3 then + npcHandler:say({ + "So let us begin. Please concentrate with me. Concentrate! ...", + "Concentrate! ...", + "Concentrate! ...", + "Concentrate! ...", + "Concentrate! ...", + "Do you feel something?"}, cid) + npcHandler.topic[cid] = 4 + elseif npcHandler.topic[cid] == 4 then + npcHandler:say("Yes, take care, the gate is opening! Can you see a bright light?", cid) + npcHandler.topic[cid] = 5 + elseif npcHandler.topic[cid] == 5 then + npcHandler:say("Ahhhhhhhh! ", cid) + player:setStorageValue(Storage.DarkTrails.Mission15, 3) + player:teleportTo(Position(33490, 32037, 8)) + player:getPosition():sendMagicEffect(CONST_ME_ENERGYHIT) + npcHandler.topic[cid] = 0 + end + elseif (msgcontains(msg, "seance")) then + if player:getStorageValue(Storage.DarkTrails.Mission15) == 3 then + npcHandler:say("Splendid. Let me make the final preparations... There. Are you ready, too?", cid) + npcHandler.topic[cid] = 3 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome to my humble abode. If you come for new sorcerer {spells}, you have come to the right place.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Take care, child") +npcHandler:setMessage(MESSAGE_WALKAWAY, "'The impetuosity of youth', as my friend Mordecai would say.") + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/barney.lua b/data/npc/scripts/barney.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/barney.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/barry.lua b/data/npc/scripts/barry.lua new file mode 100644 index 00000000000..a770b3097cb --- /dev/null +++ b/data/npc/scripts/barry.lua @@ -0,0 +1,50 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, 'report') then + local player = Player(cid) + if isInArray({9, 11}, player:getStorageValue(Storage.InServiceofYalahar.Questline)) then + npcHandler:say('Oh my, where to begin with .. .', cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, player:getStorageValue(Storage.InServiceofYalahar.Questline) + 1) + player:setStorageValue(Storage.InServiceofYalahar.Mission02, player:getStorageValue(Storage.InServiceofYalahar.Mission02) + 1) -- StorageValue for Questlog 'Mission 02: Watching the Watchmen' + end + elseif msgcontains(msg, 'pass') then + npcHandler:say('You can {pass} either to the {Magician Quarter} or {Sunken Quarter}. Which one will it be?', cid) + npcHandler.topic[cid] = 1 + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, 'magician') then + local destination = Position(32885, 31157, 7) + Player(cid):teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'sunken') then + local destination = Position(32884, 31162, 7) + Player(cid):teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/bashira.lua b/data/npc/scripts/bashira.lua new file mode 100644 index 00000000000..bb5427c5aef --- /dev/null +++ b/data/npc/scripts/bashira.lua @@ -0,0 +1,31 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local voices = { {text = 'Welcome to Ab\'Dendriel\'s store for general goods.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Greeting message +keywordHandler:addGreetKeyword({"ashari"}, {npcHandler = npcHandler, text = "Greetings, |PLAYERNAME|."}) +--Farewell message +keywordHandler:addFarewellKeyword({"asgha thrazi"}, {npcHandler = npcHandler, text = "Good bye, |PLAYERNAME|."}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good Bye, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "May God show you the path, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Of course, just browse through my offers.") + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/basilisk.lua b/data/npc/scripts/basilisk.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/basilisk.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/baxter.lua b/data/npc/scripts/baxter.lua new file mode 100644 index 00000000000..6089ced148b --- /dev/null +++ b/data/npc/scripts/baxter.lua @@ -0,0 +1,30 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'People of Thais, bring honour to your king by fighting in the orc war!' }, + { text = 'The orcs are preparing for war!!!' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "LONG LIVE KING TIBIANUS!") +npcHandler:setMessage(MESSAGE_FAREWELL, "LONG LIVE THE KING!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "LONG LIVE THE KING!") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Do you bring freshly killed rats for a bounty of 1 gold each? By the way, I also buy orc teeth and other stuff you ripped from their bloody corp... I mean... well, you know what I mean.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/beatrice.lua b/data/npc/scripts/beatrice.lua new file mode 100644 index 00000000000..c599efb7a90 --- /dev/null +++ b/data/npc/scripts/beatrice.lua @@ -0,0 +1,48 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Selling general goods and paperware! Come to my shop!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if msgcontains(msg, "football") then + npcHandler:say("Do you want to buy a football for 111 gold?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + local player = Player(cid) + if player:getMoney() + player:getBankBalance() >= 111 then + npcHandler:say("Here it is.", cid) + player:addItem(2109, 1) + player:removeMoneyNpc(111) + else + npcHandler:say("You don't have enough money.", cid) + end + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_FAREWELL, "See you later, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "See you later, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Of course, just browse through my wares.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/benevola.lua b/data/npc/scripts/benevola.lua new file mode 100644 index 00000000000..37fecabb970 --- /dev/null +++ b/data/npc/scripts/benevola.lua @@ -0,0 +1,25 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Nature is in pain.' }, + { text = 'The weather is fine today.' }, + { text = 'I can hear the call of the forest.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/benjamin.lua b/data/npc/scripts/benjamin.lua new file mode 100644 index 00000000000..aca0ad77bb7 --- /dev/null +++ b/data/npc/scripts/benjamin.lua @@ -0,0 +1,51 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Welcome to the post office!' }, + { text = 'If you need help with letters or parcels, just ask me. I can explain everything.' }, + { text = 'Hey, send a letter to your friend now and then. Keep in touch, you know.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, "measurements") then + local player = Player(cid) + if player:getStorageValue(Storage.Postman.Mission07) >= 1 and player:getStorageValue(Storage.Postman.MeasurementsBenjamin) ~= 1 then + npcHandler:say("Oh they don't change that much since in the old days as... ", cid) + player:setStorageValue(Storage.Postman.Mission07, player:getStorageValue(Storage.Postman.Mission07) + 1) + player:setStorageValue(Storage.Postman.MeasurementsBenjamin, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("...", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Hello. How may I help you |PLAYERNAME|? Ask me for a {trade} if you want to buy something. I can also explain the {mail} system.") +npcHandler:setMessage(MESSAGE_FAREWELL, "It was a pleasure to help you, |PLAYERNAME|.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/berenice.lua b/data/npc/scripts/berenice.lua new file mode 100644 index 00000000000..4dc3b36531d --- /dev/null +++ b/data/npc/scripts/berenice.lua @@ -0,0 +1,74 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.ExplorerSociety.CalassaQuest) == 2 then + npcHandler:say("OH! So you have safely returned from Calassa! Congratulations, were you able to retrieve the logbook?", cid) + npcHandler.topic[cid] = 5 + elseif player:getStorageValue(Storage.ExplorerSociety.TheOrcPowder) > 34 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) > 34 then + npcHandler:say("The most important mission we currently have is an expedition to {Calassa}.", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "calassa") then + if npcHandler.topic[cid] == 1 and player:getStorageValue(Storage.ExplorerSociety.CalassaQuest) < 1 then + npcHandler:say("Ah! So you have heard about our special mission to investigate the Quara race in their natural surrounding! Would you like to know more about it?", cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 4 then + npcHandler:say("Captain Max will bring you to Calassa whenever you are ready. Please try to retrieve the missing logbook which must be in one of the sunken shipwrecks.", cid) + player:setStorageValue(Storage.ExplorerSociety.CalassaDoor, 1) + player:setStorageValue(Storage.ExplorerSociety.CalassaQuest, 1) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.ExplorerSociety.CalassaQuest) == 2 then + npcHandler:say("OH! So you have safely returned from Calassa! Congratulations, were you able to retrieve the logbook?", cid) + npcHandler.topic[cid] = 5 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 2 then + npcHandler:say({ + "Since you have already proved to be a valuable member of our society, I will happily entrust you with this mission, but there are a few things which you need to know, so listen carefully. ...", + "Calassa is an underwater settlement, so you are in severe danger of drowning unless you are well-prepared. ...", + "We have developed a new device called 'Helmet of the Deep' which will enable you to breathe even in the depths of the ocean. ...", + "I will instruct Captain Max to bring you to Calassa and to lend one of these helmets to you. These helmets are very valuable, so there is a deposit of 5000 gold pieces on it. ...", + "While in Calassa, do not take the helmet off under any circumstances. If you have any questions, don't hesitate to ask Captain Max. ...", + "Your mission there, apart from observing the Quara, is to retrieve a special logbook from one of the shipwrecks buried there. ...", + "One of our last expeditions there failed horribly and the ship sank, but we still do not know the exact reason. ...", + "If you could retrieve the logbook, we'd finally know what happened. Have you understood your task and are willing to take this risk?" + }, cid) + npcHandler.topic[cid] = 3 + elseif npcHandler.topic[cid] == 3 then + npcHandler:say("Excellent! I will immediately inform Captain Max to bring you to {Calassa} whenever you are ready. Don't forget to make thorough preparations!", cid) + npcHandler.topic[cid] = 4 + elseif npcHandler.topic[cid] == 5 then + if player:removeItem(6124, 1) then + player:setStorageValue(Storage.ExplorerSociety.CalassaQuest, 3) + npcHandler:say("Yes! That's the logbook! However... it seems that the water has already destroyed many of the pages. This is not your fault though, you did your best. Thank you!", cid) + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/bertha.lua b/data/npc/scripts/bertha.lua new file mode 100644 index 00000000000..dbe6e7ab2fb --- /dev/null +++ b/data/npc/scripts/bertha.lua @@ -0,0 +1,51 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Hey there, need some general goods or paperware?'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if msgcontains(msg, "football") then + npcHandler:say("Do you want to buy a football for 111 gold?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + local player = Player(cid) + if player:getMoney() + player:getBankBalance() >= 111 then + npcHandler:say("Here it is.", cid) + player:addItem(2109, 1) + player:removeMoneyNpc(111) + else + npcHandler:say("You don't have enough money.", cid) + end + npcHandler.topic[cid] = 0 + end + end + return true +end + +keywordHandler:addKeyword({'equipment'}, StdModule.say, {npcHandler = npcHandler, text = "I sell equipment for your adventure! Just ask me for a {trade} to see my wares."}) + +npcHandler:setMessage(MESSAGE_GREET, "Oh, please come in, |PLAYERNAME|. What can I do for you? If you need adventure equipment, ask me for a {trade}.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Of course, just browse through my wares. {Footballs} have to be purchased separately.") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/bertram.lua b/data/npc/scripts/bertram.lua new file mode 100644 index 00000000000..2844161845a --- /dev/null +++ b/data/npc/scripts/bertram.lua @@ -0,0 +1,41 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, 'key') then + if player:getStorageValue(Storage.ThievesGuild.Mission06) == 1 + and player:getSex() == PLAYERSEX_FEMALE then + local headItem = player:getSlotItem(CONST_SLOT_HEAD) + if headItem and headItem.itemid == 2665 and player:getStorageValue(Storage.Postman.Rank) == 5 then + player:addItem(8762, 1) + player:setStorageValue(Storage.ThievesGuild.Mission06, 2) + npcHandler:say('Oh my! You look so great in your uniform! \z + You archpostwomen are not only daring but also beautiful. \z + Here take it, that\'s the key you wanted. Just promise to visit me now and then!', cid) + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/bezil.lua b/data/npc/scripts/bezil.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/bezil.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/bigfoot_soldier.lua b/data/npc/scripts/bigfoot_soldier.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/bigfoot_soldier.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/bill_the_worker.lua b/data/npc/scripts/bill_the_worker.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/bill_the_worker.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/billy.lua b/data/npc/scripts/billy.lua new file mode 100644 index 00000000000..14e149d8f1d --- /dev/null +++ b/data/npc/scripts/billy.lua @@ -0,0 +1,114 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Add one fresh dead rat and stir it well... ' }, + { text = 'Argh, if I only had a pan!' }, + { text = 'Bread, cheese, ham and meat! All fresh!' }, + { text = 'Buying fresh dead rats!' }, + { text = 'Buying many types of food and ingredients, too!' }, + { text = 'Hmm, hmm, now which ingredients do I need...' }, + { text = 'Need food? I have plenty for sale!' } +} +npcHandler:addModule(VoiceModule:new(voices)) + +-- Basic keywords +keywordHandler:addKeyword({'hint'}, StdModule.rookgaardHints, {npcHandler = npcHandler}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'Billy.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m a farmer and a {cook}. I\'d love to make pancakes, but I\'m lacking a good {pan}.'}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = 'I came here for peace and leisure, so leave me alone with \'time\'.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'Rather give your {money} to me than leaving it at the bank. Hehe.'}) +keywordHandler:addKeyword({'how', 'are', 'you'}, StdModule.say, {npcHandler = npcHandler, text = 'Thank you, I\'m fine.'}) +keywordHandler:addKeyword({'information'}, StdModule.say, {npcHandler = npcHandler, text = 'If you need information, I can provide you with general {hints}.'}) +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m a cook, not a priest. If you need information, I can provide you with general {hints}.'}) +keywordHandler:addKeyword({'cook'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m the best cook around. You can sell most types of {food} to me. Just ask me for a {trade} to see what I buy from you as well as my offers.'}) +keywordHandler:addKeyword({'citizen'}, StdModule.say, {npcHandler = npcHandler, text = 'Which citizen?'}) +keywordHandler:addKeyword({'rat'}, StdModule.say, {npcHandler = npcHandler, text = 'If you bring me a fresh rat for my famous stew, ask me for a {trade}.'}) +keywordHandler:addKeyword({'shop'}, StdModule.say, {npcHandler = npcHandler, text = 'Nah, this is not a real shop. I have some offers, though. If you\'re interested, just ask me for a {trade}. There are other {merchants} on {Rookgaard} as well.'}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = 'There is so much to explore! Better hurry to get to the continent! Once you\'re level 8, look for the {oracle}.'}) +keywordHandler:addKeyword({'equipment'}, StdModule.say, {npcHandler = npcHandler, text = 'As an adventurer, you should always have at least a {backpack}, a {rope}, a {shovel}, a {weapon}, an {armor} and a {shield}.'}) +keywordHandler:addKeyword({'academy'}, StdModule.say, {npcHandler = npcHandler, text = 'There are lots and lots of dusty books. You can read them for some basic knowledge about the world. Then again, you could also ask around in the village.'}) +keywordHandler:addKeyword({'king'}, StdModule.say, {npcHandler = npcHandler, text = 'The king and his tax collectors are far away. You\'ll meet them soon enough.'}) +keywordHandler:addKeyword({'weapon'}, StdModule.say, {npcHandler = npcHandler, text = 'Ask {Obi} or {Lee\'Delle}. They make a fortune here with all those wannabe heroes.'}) +keywordHandler:addKeyword({'rookgaard'}, StdModule.say, {npcHandler = npcHandler, text = 'This island will prepare you for the main continent of {Tibia}. Learn to fight and grow stronger!'}) +keywordHandler:addKeyword({'monster'}, StdModule.say, {npcHandler = npcHandler, text = 'Don\'t be scared, you should be safe as long as you stay in town. Dangerous monsters are roaming the {dungeons}.'}) +keywordHandler:addKeyword({'dungeon'}, StdModule.say, {npcHandler = npcHandler, text = 'You\'ll find a lot of dungeons if you look around. One example are the {sewers} below Rookgaard.'}) +keywordHandler:addKeyword({'sewer'}, StdModule.say, {npcHandler = npcHandler, text = 'The local sewers are invested by {rats}. Fresh rats give a good stew, you can sell them to me.'}) +keywordHandler:addKeyword({'sell'}, StdModule.say, {npcHandler = npcHandler, text = 'Just ask me for a {trade} to see what I buy from you. Food of almost any kind!'}) +keywordHandler:addKeyword({'merchant'}, StdModule.say, {npcHandler = npcHandler, text = 'To view the offers of a merchant, simply talk to him or her and ask for a {trade}.'}) +keywordHandler:addKeyword({'god'}, StdModule.say, {npcHandler = npcHandler, text = 'That\'s right, I\'m the god of cooking!'}) +keywordHandler:addKeyword({'recipe'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'d love to make pancakes, but I\'m lacking a decent {pan}. If you get me one, I\'ll reward you.'}) + +keywordHandler:addKeyword({'armor'}, StdModule.say, {npcHandler = npcHandler, text = 'Armor and shields can be bought at {Dixi\'s} or at {Lee\'Delle\'s}. Dixi runs that shop near {Obi\'s}.'}) +keywordHandler:addAliasKeyword({'shield'}) + +keywordHandler:addKeyword({'backpack'}, StdModule.say, {npcHandler = npcHandler, text = 'Get that from {Al Dee} or {Lee\'Delle}.'}) +keywordHandler:addAliasKeyword({'shovel'}) +keywordHandler:addAliasKeyword({'rope'}) +keywordHandler:addAliasKeyword({'fishing'}) + +keywordHandler:addKeyword({'money'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, no gold, no deal. Earn gold by fighting {monsters} and picking up the things they carry. Sell it to {merchants} to make profit!'}) +keywordHandler:addAliasKeyword({'gold'}) + +keywordHandler:addKeyword({'magic'}, StdModule.say, {npcHandler = npcHandler, text = 'I can spell but I don\'t know any spells.'}) +keywordHandler:addAliasKeyword({'spell'}) + +keywordHandler:addKeyword({'food'}, StdModule.say, {npcHandler = npcHandler, text = 'Just ask me for a {trade} to see my offers.'}) +keywordHandler:addAliasKeyword({'buy'}) +keywordHandler:addAliasKeyword({'stuff'}) +keywordHandler:addAliasKeyword({'offer'}) + +-- Names +keywordHandler:addKeyword({'obi'}, StdModule.say, {npcHandler = npcHandler, text = 'I like him, we usually have a drink or two once a week and share stories about {Willie}.'}) +keywordHandler:addKeyword({'norma'}, StdModule.say, {npcHandler = npcHandler, text = 'That girl is all about party now. I think she was fed up with {equipment} selling.'}) +keywordHandler:addKeyword({'loui'}, StdModule.say, {npcHandler = npcHandler, text = 'Now that\'s one crazy fellow. I usually hear him scream about some hole.'}) +keywordHandler:addKeyword({'santiago'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s a fisherman and somehow his hut is always infested with cockroaches.'}) +keywordHandler:addKeyword({'zirella'}, StdModule.say, {npcHandler = npcHandler, text = 'That old hag always finds someone to do her work. I have no clue how she is doing that.'}) +keywordHandler:addKeyword({'al', 'dee'}, StdModule.say, {npcHandler = npcHandler, text = 'Decent guy. He sells general equipment such as {ropes}, {shovels} and so on.'}) +keywordHandler:addKeyword({'amber'}, StdModule.say, {npcHandler = npcHandler, text = 'She\'s pretty indeed! I wonder if she likes bearded men.'}) +keywordHandler:addKeyword({'billy'}, StdModule.say, {npcHandler = npcHandler, text = 'Gotta love that name.'}) +keywordHandler:addKeyword({'willie'}, StdModule.say, {npcHandler = npcHandler, text = 'Don\'t listen to this old wannabe, I\'m the best cook around.'}) +keywordHandler:addKeyword({'cipfried'}, StdModule.say, {npcHandler = npcHandler, text = 'He never leaves the temple. He spends his time caring for those who newly arrive here. You can ask him for a heal if you are badly injured or poisoned.'}) +keywordHandler:addKeyword({'dixi'}, StdModule.say, {npcHandler = npcHandler, text = 'That\'s {Obi\'s} granddaughter. She helps him out by selling {armors} and {shields}. I think she\'ll be a beauty when she\'s grown up.'}) +keywordHandler:addKeyword({'hyacinth'}, StdModule.say, {npcHandler = npcHandler, text = 'I never see that guy around.'}) +keywordHandler:addKeyword({'lee\'delle'}, StdModule.say, {npcHandler = npcHandler, text = 'Her shop is super-duper exclusive. If you\'re a premium adventurer, check it out in the western part of town. Lotsa nice offers there.'}) +keywordHandler:addKeyword({'lily'}, StdModule.say, {npcHandler = npcHandler, text = 'She lives in the very south of this town, selling her potions. Sweet - well, sweet-loving girl.'}) +keywordHandler:addKeyword({'oracle'}, StdModule.say, {npcHandler = npcHandler, text = 'You can find the oracle on the top floor of the {academy}, just above {Seymour}. Go there when you are level 8.'}) +keywordHandler:addKeyword({'paulie'}, StdModule.say, {npcHandler = npcHandler, text = 'He must have the most boring job there is.'}) +keywordHandler:addKeyword({'seymour'}, StdModule.say, {npcHandler = npcHandler, text = 'I don\'t like his headmaster behaviour. Then again, he IS the headmaster of the {academy}.'}) +keywordHandler:addKeyword({'tom'}, StdModule.say, {npcHandler = npcHandler, text = 'Tom the tanner buys what\'s too nasty or too old to eat, animal-wise. Dead wolves and such.'}) +keywordHandler:addKeyword({'dallheim'}, StdModule.say, {npcHandler = npcHandler, text = 'He is one of the king\'s best men and here to protect us.'}) +keywordHandler:addAliasKeyword({'zerbrus'}) + +-- Health Potion Quest +local panKeyword = keywordHandler:addKeyword({'pan'}, StdModule.say, {npcHandler = npcHandler, text = 'Have you found a pan for me?'}) + panKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'A pan! At last! Take this in case you eat something my cousin has cooked.', reset = true}, + function(player) return player:getItemCount(2563) > 0 end, + function(player) + player:removeItem(2563, 1) + player:addItem(8704, 1) + end + ) + panKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Hey! You don\'t have one!', reset = true}) + panKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Then go and look for one!', reset = true}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'HOW RUDE!') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Bye.') +npcHandler:setMessage(MESSAGE_SENDTRADE, 'Sure.') +npcHandler:setMessage(MESSAGE_GREET, 'Howdy |PLAYERNAME|. I\'m a farmer and cook, maybe I can interest you in a {trade} with food? You can also ask me for general {hints} about the game.') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/black_bert.lua b/data/npc/scripts/black_bert.lua new file mode 100644 index 00000000000..501f24c008d --- /dev/null +++ b/data/npc/scripts/black_bert.lua @@ -0,0 +1,114 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local shopModule = ShopModule:new() +npcHandler:addModule(shopModule) + +shopModule:addBuyableItem({"almanac of magic"}, 10942, 600, 1) +shopModule:addBuyableItem({"animal fetish"}, 10154, 10000, 1) +shopModule:addBuyableItem({"baby rotworm"}, 10943, 600, 1) +shopModule:addBuyableItem({"bale of white cloth"}, 7500, 6000, 1) +shopModule:addBuyableItem({"bill"}, 2329, 8000, 1) +shopModule:addBuyableItem({"blood crystal"}, 9369, 50000, 1) +shopModule:addBuyableItem({"bloodkiss flower"}, 10159, 10000, 1) +shopModule:addBuyableItem({"bundle of rags"}, 10109, 5000, 1) +shopModule:addBuyableItem({"carrying device"}, 10615, 1000, 1) +shopModule:addBuyableItem({"cigar"}, 7499, 2000, 1) +shopModule:addBuyableItem({"cookbook"}, 2347, 150, 1) +shopModule:addBuyableItem({"damaged logbook"}, 14338, 40000, 1) +shopModule:addBuyableItem({"dark essence"}, 14352, 17000, 1) +shopModule:addBuyableItem({"deep crystal"}, 10158, 13000, 1) +shopModule:addBuyableItem({"elemental crystal"}, 10169, 8000, 1) +shopModule:addBuyableItem({"empty beer bottle"}, 11397, 600, 1) +shopModule:addBuyableItem({"exploding cookie"}, 8111, 100, 1) +shopModule:addBuyableItem({"exquisite silk"}, 12501, 4000, 1) +shopModule:addBuyableItem({"exquisite wood"}, 12503, 4000, 1) +shopModule:addBuyableItem({"faded last will"}, 12500, 600, 1) +shopModule:addBuyableItem({"family brooch"}, 4845, 1000, 1) +shopModule:addBuyableItem({"family signet ring"}, 7708, 15000, 1) +shopModule:addBuyableItem({"fan club membership card"}, 10308, 10000, 1) +shopModule:addBuyableItem({"filled carrying device"}, 10616, 1000, 1) +shopModule:addBuyableItem({"fishnapped goldfish"}, 8766, 7000, 1) +shopModule:addBuyableItem({"flask of crown polisher"}, 10926, 700, 1) +shopModule:addBuyableItem({"flask of extra greasy oil"}, 11106, 1000, 1) +shopModule:addBuyableItem({"flask of poison"}, 10760, 1000, 1) +shopModule:addBuyableItem({"flexible dragon scale"}, 12506, 4000, 1) +shopModule:addBuyableItem({"formula for a memory potion"}, 14351, 5000, 1) +shopModule:addBuyableItem({"funeral urn"}, 4858, 6000, 1) +shopModule:addBuyableItem({"ghost charm"}, 9737, 20000, 1) +shopModule:addBuyableItem({"ghost's tear"}, 9662, 50000, 1) +shopModule:addBuyableItem({"giant ape's hair"}, 4843, 24000, 1) +shopModule:addBuyableItem({"golem blueprint"}, 10165, 13500, 1) +shopModule:addBuyableItem({"golem head"}, 10173, 25000, 1) +shopModule:addBuyableItem({"headache pill"}, 10454, 350, 1) +shopModule:addBuyableItem({"ivory lyre"}, 36282, 5000, 1) +shopModule:addBuyableItem({"letterbag"}, 2330, 8000, 1) +shopModule:addBuyableItem({"lump of clay"}, 12285, 1000, 1) +shopModule:addBuyableItem({"machine crate"}, 10307, 8500, 1) +shopModule:addBuyableItem({"magic crystal"}, 12508, 4000, 1) +shopModule:addBuyableItem({"mago mechanic core"}, 10167, 13000, 1) +shopModule:addBuyableItem({"map to the unknown"}, 10928, 650, 1) +shopModule:addBuyableItem({"memory crystal"}, 7281, 500, 1) +shopModule:addBuyableItem({"memory stone"}, 4852, 3000, 1) +shopModule:addBuyableItem({"mystic root"}, 12507, 4000, 1) +shopModule:addBuyableItem({"nautical map"}, 10225, 5250, 1) +shopModule:addBuyableItem({"old iron"}, 12505, 4000, 1) +shopModule:addBuyableItem({"old power core"}, 10170, 13000, 1) +shopModule:addBuyableItem({"plans for a strange device"}, 10613, 1000, 1) +shopModule:addBuyableItem({"rare crystal"}, 11104, 1000, 1) +shopModule:addBuyableItem({"sacred earth"}, 12297, 1000, 1) +shopModule:addBuyableItem({"sceptre of sun and sea"}, 36249, 50000, 1) +shopModule:addBuyableItem({"shadow orb"}, 10155, 12500, 1) +shopModule:addBuyableItem({"sheet of tracing paper"}, 4854, 500, 1) +shopModule:addBuyableItem({"suspicious signet ring"}, 7697, 15000, 1) +shopModule:addBuyableItem({"snake destroyer"}, 4846, 8000, 1) +shopModule:addBuyableItem({"soul contract"}, 10945, 666, 1) +shopModule:addBuyableItem({"special flask"}, 14323, 5000, 1) +shopModule:addBuyableItem({"spectral cloth"}, 12502, 4000, 1) +shopModule:addBuyableItem({"spectral dress"}, 4847, 15000, 1) +shopModule:addBuyableItem({"spyreport"}, 2345, 3000, 1) +shopModule:addBuyableItem({"stabilizer"}, 10166, 12500, 1) +shopModule:addBuyableItem({"strange powder"}, 15389, 5000, 1) +shopModule:addBuyableItem({"strong sinew"}, 12504, 4000, 1) +shopModule:addBuyableItem({"tear of daraman"}, 2346, 16000, 1) +shopModule:addBuyableItem({"technomancer beard"}, 7699, 5000, 1) +shopModule:addBuyableItem({"the alchemists' formulas"}, 9733, 8000, 1) +shopModule:addBuyableItem({"the ring of the count"}, 8752, 10000, 1) +shopModule:addBuyableItem({"toy mouse"}, 7487, 16000, 1) +shopModule:addBuyableItem({"universal tool"}, 10944, 550, 1) +shopModule:addBuyableItem({"unworked sacred wood"}, 12295, 1000, 1) +shopModule:addBuyableItem({"whisper moss"}, 4838, 18000, 1) +shopModule:addBuyableItem({"worm queen tooth"}, 10157, 12500, 1) +shopModule:addBuyableItem({"wrinkled parchment"}, 14336, 4000, 1) +shopModule:addBuyableItem({"wolf tooth chain"}, 5940, 10000, 1) + +local function onTradeRequest(cid) + local player = Player(cid) + if player:getStorageValue(Storage.ThievesGuild.Mission08) ~= 3 then + npcHandler:say("I don't know you and I don't have any dealings with people whom I don't trust.", cid) + return false + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Hi there, |PLAYERNAME|! You look like you are eager to {trade}!") +npcHandler:setMessage(MESSAGE_FAREWELL, "Bye, |PLAYERNAME|") + +npcHandler:setCallback(CALLBACK_ONTRADEREQUEST, onTradeRequest) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/blind_orc.lua b/data/npc/scripts/blind_orc.lua new file mode 100644 index 00000000000..93a882a58f4 --- /dev/null +++ b/data/npc/scripts/blind_orc.lua @@ -0,0 +1,77 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local function addBuyableKeyword(keywords, itemid, amount, price, text) + local keyword + if type(keywords) == 'table' then + keyword = keywordHandler:addKeyword({'goshak', keywords[1], keywords[2]}, StdModule.say, {npcHandler = npcHandler, text = text}) + else + keyword = keywordHandler:addKeyword({'goshak', keywords}, StdModule.say, {npcHandler = npcHandler, text = text}) + end + + keyword:addChildKeyword({'mok'}, StdModule.say, {npcHandler = npcHandler, text = 'Maruk rambo zambo!', reset = true}, + function(player) return player:getMoney() + player:getBankBalance() >= price end, + function(player) + if player:removeMoneyNpc(price) then + player:addItem(itemid, amount) + end + end + ) + keyword:addChildKeyword({'mok'}, StdModule.say, {npcHandler = npcHandler, text = 'Maruk nixda!', reset = true}) + keyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Buta maruk klamuk!', reset = true}) +end + +-- Greeting and Farewell +keywordHandler:addGreetKeyword({'charach'}, {npcHandler = npcHandler, text = 'Ikem Charach maruk.'}) +keywordHandler:addFarewellKeyword({'futchi'}, {npcHandler = npcHandler, text = 'Futchi!'}) + +keywordHandler:addKeyword({''}, StdModule.say, {npcHandler = npcHandler, onlyUnfocus = true, text = 'Buta humak!'}) + +keywordHandler:addKeyword({'ikem', 'goshak'}, StdModule.say, {npcHandler = npcHandler, text = 'Ikem pashak porak, bata, dora. Ba goshak maruk?'}) +keywordHandler:addKeyword({'goshak', 'porak'}, StdModule.say, {npcHandler = npcHandler, text = 'Ikem pashak charcha, burka, burka bata, hakhak. Ba goshak maruk?'}) +keywordHandler:addKeyword({'goshak', 'bata'}, StdModule.say, {npcHandler = npcHandler, text = 'Ikem pashak aka bora, tulak bora, grofa. Ba goshak maruk?'}) +keywordHandler:addKeyword({'goshak', 'dora'}, StdModule.say, {npcHandler = npcHandler, text = 'Ikem pashak donga. Ba goshak maruk?'}) + +-- Bow +addBuyableKeyword('batuk', 2456, 1, 400, 'Ahhhh, maruk, goshak batuk?') +-- 10 Arrows +addBuyableKeyword('pixo', 2544, 10, 30, 'Maruk goshak tefar pixo ul batuk?') + +-- Brass Shield +addBuyableKeyword('donga', 2511, 1, 65, 'Maruk goshak ta?') + +-- Leather Armor +addBuyableKeyword('bora', 2467, 1, 25, 'Maruk goshak ta?') +-- Studded Armor +addBuyableKeyword({'tulak', 'bora'}, 2484, 1, 90, 'Maruk goshak ta?') +-- Studded Helmet +addBuyableKeyword('grofa', 2482, 1, 60, 'Maruk goshak ta?') + +-- Sabre +addBuyableKeyword('charcha', 2385, 1, 25, 'Maruk goshak ta?') +-- Sword +addBuyableKeyword({'burka', 'bata'}, 2376, 1, 85, 'Maruk goshak ta?') +-- Short Sword +addBuyableKeyword('burka', 2406, 1, 30, 'Maruk goshak ta?') +-- Hatchet +addBuyableKeyword('hakhak', 2388, 1, 85, 'Maruk goshak ta?') + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Futchi.') + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/blossom_bonecrusher.lua b/data/npc/scripts/blossom_bonecrusher.lua new file mode 100644 index 00000000000..9e297043c0a --- /dev/null +++ b/data/npc/scripts/blossom_bonecrusher.lua @@ -0,0 +1,42 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(10, 1000, -10) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if isInArray({"fuck", "idiot", "asshole", "ass", "fag", "stupid", "tyrant", "shit", "lunatic"}, msg) then + npcHandler:say("Take this!", cid) + local player = Player(cid) + player:getPosition():sendMagicEffect(CONST_ME_EXPLOSIONAREA) + player:addCondition(condition) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "LONG LIVE THE QUEEN!") +npcHandler:setMessage(MESSAGE_FAREWELL, "LONG LIVE THE QUEEN!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "LONG LIVE THE QUEEN!") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/bo_ques.lua b/data/npc/scripts/bo_ques.lua new file mode 100644 index 00000000000..cc4d5a3ac7a --- /dev/null +++ b/data/npc/scripts/bo_ques.lua @@ -0,0 +1,98 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local voices = { {text = 'Now, where was I...'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + local missionProgress = player:getStorageValue(Storage.DjinnWar.MaridFaction.Mission01) + if msgcontains(msg, 'recipe') or msgcontains(msg, 'mission') then + if missionProgress < 1 then + npcHandler:say({ + 'My collection of recipes is almost complete. There are only but a few that are missing. ...', + 'Hmmm... now that we talk about it. There is something you could help me with. Are you interested?' + }, cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say('I already told you about the recipes I am missing, now please try to find a cookbook of the dwarven kitchen.', cid) + end + + elseif msgcontains(msg, 'cookbook') then + if missionProgress == -1 then + npcHandler:say({ + 'I\'m preparing the food for all djinns in Ashta\'daramai. ...', + 'Therefore, I\'m what is commonly called a cook, although I do not like that word too much. It is vulgar. I prefer to call myself \'chef\'.' + }, cid) + elseif missionProgress == 1 then + npcHandler:say('Do you have the cookbook of the dwarven kitchen with you? Can I have it?', cid) + npcHandler.topic[cid] = 2 + else + npcHandler:say('Thanks again, for bringing me that book!', cid) + end + + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, 'yes') then + npcHandler:say({ + 'Fine! Even though I know so many recipes, I\'m looking for the description of some dwarven meals. ...', + 'So, if you could bring me a cookbook of the dwarven kitchen, I\'ll reward you well.' + }, cid) + player:setStorageValue(Storage.DjinnWar.MaridFaction.Start, 1) + player:setStorageValue(Storage.DjinnWar.MaridFaction.Mission01, 1) + + elseif msgcontains(msg, 'no') then + npcHandler:say('Well, too bad.', cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, 'yes') then + if not player:removeItem(2347, 1) then + npcHandler:say('Too bad. I must have this book.', cid) + return true + end + + npcHandler:say({ + 'The book! You have it! Let me see! ...', + 'Dragon Egg Omelette, Dwarven beer sauce... it\'s all there. This is great! Here is your well-deserved reward. ...', + 'Incidentally, I have talked to Fa\'hradin about you during dinner. I think he might have some work for you. Why don\'t you talk to him about it?' + }, cid) + player:setStorageValue(Storage.DjinnWar.MaridFaction.Mission01, 2) + player:addItem(2146, 3) + + elseif msgcontains(msg, 'no') then + npcHandler:say('Too bad. I must have this book.', cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +-- Greeting +keywordHandler:addGreetKeyword({"djanni'hah"}, {npcHandler = npcHandler, text = "Hey! A human! What are you doing in my kitchen, |PLAYERNAME|?"}) + +npcHandler:setMessage(MESSAGE_FAREWELL, 'Goodbye. I am sure you will come back for more. They all do.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Goodbye. I am sure you will come back for more. They all do.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/bob_the_worker.lua b/data/npc/scripts/bob_the_worker.lua new file mode 100644 index 00000000000..d0c68ddbca1 --- /dev/null +++ b/data/npc/scripts/bob_the_worker.lua @@ -0,0 +1,18 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/bolfona.lua b/data/npc/scripts/bolfona.lua new file mode 100644 index 00000000000..13e6e489839 --- /dev/null +++ b/data/npc/scripts/bolfona.lua @@ -0,0 +1,62 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "chocolate cake") then + if player:getStorageValue(Storage.HiddenCityOfBeregar.SweetAsChocolateCake) == 1 and player:getItemCount(8847) >= 1 then + npcHandler:say("Is that for me?", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.HiddenCityOfBeregar.SweetAsChocolateCake) == 2 then + npcHandler:say("So did you tell her that the cake came from me?", cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + if player:removeItem(8847, 1) then + npcHandler:say("Err, thanks. I doubt it's from you. Who sent it?", cid) + npcHandler.topic[cid] = 2 + player:setStorageValue(Storage.HiddenCityOfBeregar.SweetAsChocolateCake, 2) + else + npcHandler:say("Oh, I thought you have one.", cid) + npcHandler.topic[cid] = 0 + end + end + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, "Frafnar") then + npcHandler:say("Oh, Frafnar. That's so nice of him. I gotta invite him for a beer.", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Never heard that name. Well, I don't mind, thanks for the cake.", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, "See you my friend.") +npcHandler:setMessage(MESSAGE_FAREWELL, "See you my friend.") + +npcHandler:setMessage(MESSAGE_GREET, "Are you talking to me? Well, go on chatting but don't expect an answer.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/bonifacius.lua b/data/npc/scripts/bonifacius.lua new file mode 100644 index 00000000000..d0c68ddbca1 --- /dev/null +++ b/data/npc/scripts/bonifacius.lua @@ -0,0 +1,18 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/boozer.lua b/data/npc/scripts/boozer.lua new file mode 100644 index 00000000000..dbf69205858 --- /dev/null +++ b/data/npc/scripts/boozer.lua @@ -0,0 +1,48 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.TibiaTales.ultimateBoozeQuest) == 2 and player:removeItem(7495, 1) then + player:setStorageValue(Storage.TibiaTales.ultimateBoozeQuest, 3) + npcHandler.topic[cid] = 0 + player:addItem(5710, 1) + player:addItem(2152, 10) + player:addExperience(100, true) + npcHandler:say("Yessss! Now I only need to build my own small brewery, figure out the secret recipe, duplicate the dwarvish brew and BANG I'll be back in business! Here take this as a reward.", cid) + elseif player:getStorageValue(Storage.TibiaTales.ultimateBoozeQuest) < 1 then + npcHandler.topic[cid] = 1 + npcHandler:say("Shush!! I don't want everybody to know what I am up to. Listen, things are not going too well, I need a new attraction. Do you want to help me?", cid) + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + player:setStorageValue(Storage.TibiaTales.DefaultStart, 1) + player:setStorageValue(Storage.TibiaTales.ultimateBoozeQuest, 1) + player:addItem(7496, 1) + npcHandler:say("Good! Listen closely. Take this bottle and go to Kazordoon. I need a sample of their very special brown ale. You may find a cask in their brewery. Come back as soon as you got it.", cid) + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/borkas.lua b/data/npc/scripts/borkas.lua new file mode 100644 index 00000000000..d0c68ddbca1 --- /dev/null +++ b/data/npc/scripts/borkas.lua @@ -0,0 +1,18 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/boveas.lua b/data/npc/scripts/boveas.lua new file mode 100644 index 00000000000..b99de8e67a7 --- /dev/null +++ b/data/npc/scripts/boveas.lua @@ -0,0 +1,21 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:setMessage(MESSAGE_GREET, "Hi! I hope you're not going to kill me!") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye, |PLAYERNAME|.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/bozarn.lua b/data/npc/scripts/bozarn.lua new file mode 100644 index 00000000000..e88e935b7eb --- /dev/null +++ b/data/npc/scripts/bozarn.lua @@ -0,0 +1,20 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/bozo.lua b/data/npc/scripts/bozo.lua new file mode 100644 index 00000000000..01c47791a05 --- /dev/null +++ b/data/npc/scripts/bozo.lua @@ -0,0 +1,863 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + {text = 'Come chat with ol\' Bozo!'}, + {text = 'Do you know the one with the dragon? Where - and then ... hahahaha! Oh no, I guess I ruined it.'}, + {text = 'The fools\' guild? Are you serious? No, of course not! Hahaha!'}, + {text = 'Welcome, welcome, step closer!'} +} +npcHandler:addModule(VoiceModule:new(voices, 10, 20)) + +local config = { + [1] = { + text = { + [1] = 'Do you have a fitting flower for me?', + [2] = 'You don\'t have a fitting flower! Why do only fools apply for the fools guild?', + [3] = 'Indeed. This flower will do the trick, so to say. Just ask me about another mission whenever you\'re ready.' + }, + yes = true, + removeItem = {itemId = 7476}, + updateStorages = { + {key = Storage.WhatAFoolish.Mission1, value = 2}, + {key = Storage.WhatAFoolish.Questline, value = 2} + } + }, + [2] = { + text = { + [1] = { + 'The next task will be a bit more difficult. I pride myself on being the major manufacturer of stink bombs in whole Tibia. Stop chuckling you fool aspirant ...', + 'The worst part is getting the perfect stench. Whenever a slime dies, it leaves a noxious gas cloud ...', + 'If you are able to collect its scent in the first few seconds after the slime\'s death, we have the ideal substance to create dozens of stink bombs ...', + 'Take this special vial and fill it with the perfect stench. Then return here and we will talk about your mission.' + } + }, + addItem = {itemId = 7478}, + updateStorages = { + {key = Storage.WhatAFoolish.Mission2, value = 1}, + {key = Storage.WhatAFoolish.Questline, value = 3} + } + }, + [3] = { + text = { + [1] = 'Do you have acquired the exquisite stench we need?', + [2] = 'No, you haven\'t! Why do only fools apply for the fools guild?', + [3] = 'Ugh. You got some efficient stuff there. I have to admit you have a talent for such distasteful matters. Perhaps you feel ready for another mission. Just ask me about it.' + }, + yes = true, + removeItem = {itemId = 7477}, + updateStorages = { + {key = Storage.WhatAFoolish.Mission2, value = 2}, + {key = Storage.WhatAFoolish.Questline, value = 4} + } + }, + [4] = { + text = { + [1] = { + 'I think you\'re ready for a small promotion. Provided that you finish another mission, that is ...', + 'As you might know, nothing helps you to break the ice so easily when you meet new people as a pie thrown in the face ...', + 'Of course, this habit leads to a dramatic shortage of pies now and then. And that\'s what we need you for. Mirabell in Edron creates the most creamy and sticky pies in the world ...', + 'Get me a dozen of them, this means 12, you fool. Then report to me about your mission.' + } + }, + updateStorages = { + {key = Storage.WhatAFoolish.Mission3, value = 1}, + {key = Storage.WhatAFoolish.Questline, value = 5} + } + }, + [5] = { + text = { + [1] = 'So do you bring me a box full of pies?', + [2] = 'No, you don\'t! Why do only fools apply for the fools guild?', + [3] = { + 'Excellent. Poor Harsky, poor Stutch. They will mourn the day they dared to yawn during a performance of the magnificent Bozo ...', + 'However, I grant you the title of \'Fool in Training\' for your efforts. Just don\'t let it go to your head and don\'t use this highly spiritual title to show off ...', + 'If you are interested in another mission, talk to me.' + } + }, + yes = true, + removeItem = {itemId = 7484}, + pie = true, + updateStorages = { + {key = Storage.WhatAFoolish.Mission3, value = 2}, + {key = Storage.WhatAFoolish.Questline, value = 6} + } + }, + [6] = { + text = { + [1] = { + 'Ah, the fool in training wants to see some action? Fine with me. I think you are ready for a big prank. But first I need 18 vials filled with wine ...', + 'Get them and report here about your mission.' + } + }, + updateStorages = { + {key = Storage.WhatAFoolish.Mission4, value = 1}, + {key = Storage.WhatAFoolish.Questline, value = 7} + } + }, + [7] = { + text = { + [1] = 'Do you have 18 vials of wine?', + [2] = 'No, you haven\'t! Why do only fools apply for the fools guild?', + [3] = { + 'So lets see. I put them into this crate which looks just like the ones in which old Xodet gets his mana potions [1]ed ...', + 'Here take this crate and bring it to Xodet\'s shop. In front of the shop, you should see the latest [1]y. Just use this crate on the other one to exchange them ...', + 'Bring me the interchanged crate and talk to me about your mission.' + } + }, + yes = true, + removeItem = {itemId = 2006, count = 18, subType = 15}, + updateStorages = { + {key = Storage.WhatAFoolish.Mission4, value = 2}, + {key = Storage.WhatAFoolish.Questline, value = 8} + }, + addItem = {itemId = 7482} + }, + [8] = { + text = { + [1] = 'Do you bring me Xodet\'s exchanged crate?', + [2] = 'No, you don\'t! Why do only fools apply for the fools guild?', + [3] = 'I see. I guess we can expect a few drunken mages soon! Am I mistaken or are you up for some more challenging missions? Just ask me about if you feel foolish enough.' + }, + yes = true, + removeItem = {itemId = 7483}, + updateStorages = { + {key = Storage.WhatAFoolish.Mission4, value = 3}, + {key = Storage.WhatAFoolish.Questline, value = 9} + } + }, + [9] = { + text = { + [1] = { + 'I have a fine prank in mind but without proper preparation, you\'d end up hacked in pieces by the dwarfs. By chance I found out about an artefact that might save the day ...', + 'There is a mysterious tower, known as Triangle Tower, north of Jakundaf Desert. In this tower, you will find a magic watch that we need for our dangerous fun ...', + 'Well, I\'ll have the fun and you\'ll have the danger but you can view it from a positive side - view it from my side for instance. Now get that watch and report about your mission.' + } + }, + updateStorages = { + {key = Storage.WhatAFoolish.Mission5, value = 1}, + {key = Storage.WhatAFoolish.TriangleTowerDoor, value = 1}, + {key = Storage.WhatAFoolish.Questline, value = 10} + } + }, + [10] = { + text = { + [1] = 'Did you get the watch?', + [2] = 'No you have not! Why do only fools apply to the fools guild?', + [3] = { + 'Oh boy, you will have so much fun with that watch if they don\'t catch and kill you. I envy you so much ... Bozo: So listen my little fool, this watch has the power to advance you in time. It will come in handy when you are stealing the beard of the dwarven emperor ...', + 'Oh, come on, don\'t faint like some baby. It\'s perfectly safe with that watch ... well, almost. You sneak into the emperor\'s bedroom when it\'s empty. Use the watch directly beside the bed\'s pillow ...', + 'This should advance you in time. You will appear next to the sleeping emperor. His guards will be outside so they shouldn\'t bother you. Use a sharp kitchen knife to cut off his beard ...', + 'Then quickly use the watch again to advance in time once more. You should appear at a time when everybody has left the room...', + 'Sneak out and come here to report about your mission. As the watch will only work those 2 times, make sure that you\'ve got the beard when returning here.' + } + }, + yes = true, + checkItemCount = 8187, + updateStorages = { + {key = Storage.WhatAFoolish.Mission5, value = 2}, + {key = Storage.WhatAFoolish.Questline, value = 11} + } + }, + [11] = { + text = { + [1] = 'Did you get the beard?', + [2] = 'No, you don\'t! Why do only fools apply for the fools guild?', + [3] = { + 'You got the beard and survived. I think for the first time in my whole life I\'m impressed, no wait, it was just a stone in my shoe ...', + 'Still, as a small recognition of your accomplishments I\'m willing to tell you how to get your own jester outfit. If you are interested in more fun and adventures, ask me for more missions.' + } + }, + yes = true, + checkStorage = Storage.WhatAFoolish.EmperorBeardShave, + removeItem = {itemId = 7479}, + updateStorages = { + {key = Storage.WhatAFoolish.Mission5, value = 3}, + {key = Storage.WhatAFoolish.Questline, value = 12} + } + }, + [12] = { + text = { + [1] = 'I can\'t think of anything right now. Maybe you should try to get your jester outfit.' + } + }, + [13] = { + text = { + [1] = 'You know, nothing has brought more fun and joy to humanity than the whoopee cushion. Its creation is a delicate matter though. Bring me 4 pieces of minotaur leather first and then lets talk about this mission.' + }, + updateStorages = { + {key = Storage.WhatAFoolish.Mission6, value = 1}, + {key = Storage.WhatAFoolish.Questline, value = 14} + } + }, + [14] = { + text = { + [1] = 'Do you have the four minotaur leathers?', + [2] = 'No, you don\'t! Why do only fools apply for the fools guild?', + [3] = 'Good, this was the first part. Now it gets difficult. To sew it together, we need a very fine yarn, as fine as the silk of a giant spider. Bring me some giant spider silk and talk to me about your mission.' + }, + yes = true, + removeItem = {itemId = 5878, count = 4}, + updateStorages = { + {key = Storage.WhatAFoolish.Mission6, value = 2}, + {key = Storage.WhatAFoolish.Questline, value = 15} + } + }, + [15] = { + text = { + [1] = 'Do you have the spider silk with you?', + [2] = 'No, you don\'t! Why do only fools apply for the fools guild?', + [3] = 'Let\'s see, a stitch here, a stitch there. Hey Presto! A whoopee cushion! Are you ready for the fun part? Then talk to me about your next mission.' + }, + yes = true, + removeItem = {itemId = 5879}, + updateStorages = { + {key = Storage.WhatAFoolish.Mission6, value = 3}, + {key = Storage.WhatAFoolish.Questline, value = 16} + }, + effect = CONST_ME_POFF + }, + [16] = { + text = { + [1] = { + 'Now that we have this whoopee cushion it would be a waste not to use it, don\'t you agree ...', + 'Don\'t speak! I already know what you have in your impish mind my friend and I agree fully. You will bring this cushion to Carlin and place it right on Queen Eloise\'s throne! Then return here and talk to me about your mission.' + } + }, + addItem = {itemId = 7485}, + updateStorages = { + {key = Storage.WhatAFoolish.Mission6, value = 4}, + {key = Storage.WhatAFoolish.Questline, value = 17} + } + }, + [17] = { + text = { + [1] = 'Have you placed the whoopee cushion on the throne in Carlin?', + [2] = 'No, you haven\'t! Why do only fools apply for the fools guild?', + [3] = 'This will cause quite a commotion in Carlin. I think we should play some pranks in many more places to spread humour all over the world. Talk to me about your next mission to learn more about it.' + + }, + yes = true, + checkStorage = Storage.WhatAFoolish.WhoopeeCushion, + updateStorages = { + {key = Storage.WhatAFoolish.Mission6, value = 5}, + {key = Storage.WhatAFoolish.Questline, value = 18} + } + }, + [18] = { + text = { + [1] = { + 'The time has come to play a prank on some arrogant Venorean. I found out that Carina, the jeweller, is terribly afraid of mice ...', + 'Your task is quite easy. Steal the toy mouse of Queen Eloise\'s cat and show it to Carina in Venore to scare her to death. Then report about your mission.' + } + }, + updateStorages = { + {key = Storage.WhatAFoolish.Mission7, value = 1}, + {key = Storage.WhatAFoolish.QueenEloiseCatDoor, value = 1}, + {key = Storage.WhatAFoolish.Questline, value = 19} + } + }, + [19] = { + text = { + [1] = 'Have you been to Venore and scared Carina as I asked you to?', + [2] = 'No, you haven\'t! Why do only fools apply for the fools guild?', + [3] = 'Excellent. The Venoreans have been safe from my pranks far too long. If you are ready for another mission, talk to me.' + + }, + yes = true, + checkStorage = Storage.WhatAFoolish.ScaredCarina, + updateStorages = { + {key = Storage.WhatAFoolish.Mission7, value = 2}, + {key = Storage.WhatAFoolish.Questline, value = 20} + } + }, + [20] = { + text = { + [1] = { + 'These Venoreans think they are safe from us. They couldn\'t be more wrong. Let them feel the wrath of the fools! Get a spoon and collect some sulphur from an inactive lava hole ...', + 'Be very careful when you get the easily inflammable substance. Then let\'s talk about the next part of your mission.' + } + }, + updateStorages = { + {key = Storage.WhatAFoolish.Mission8, value = 1}, + {key = Storage.WhatAFoolish.Questline, value = 21} + } + }, + [21] = { + text = { + [1] = 'Have you collected the sulphur?', + [2] = 'No, you haven\'t! Why do only fools apply for the fools guild?', + [3] = 'So much for part one of my foolish master plan. Now travel to Tiquanda and use a kitchen knife to cut some leaves of the jungle dweller bush for me. Bring them with you when you report about your mission.' + }, + yes = true, + removeItem = {itemId = 8204}, + updateStorages = { + {key = Storage.WhatAFoolish.Mission8, value = 2}, + {key = Storage.WhatAFoolish.Questline, value = 22} + } + }, + [22] = { + text = { + [1] = 'Do you have the leaves with you?', + [2] = 'No, you don\'t! Why do only fools apply for the fools guild?', + [3] = 'So far so good. I will prepare some nasty surprise for your next mission. Talk to me about it whenever you feel ready.' + }, + yes = true, + removeItem = {itemId = 8109}, + updateStorages = { + {key = Storage.WhatAFoolish.Mission8, value = 3}, + {key = Storage.WhatAFoolish.Questline, value = 23} + } + }, + [23] = { + text = { + [1] = { + 'Now look at this, someone has made exploding cigars out of the sulphur and the leaves! Coincidentally I have a great idea how wecould use them ...', + 'Take this cigar and give it to Theodore Loveless, the Venorean representative in Liberty Bay. After you [1]ed our little\'present\', report here about the outcome of your mission.' + } + }, + addItem = {itemId = 7499}, + updateStorages = { + {key = Storage.WhatAFoolish.Mission8, value = 4}, + {key = Storage.WhatAFoolish.Questline, value = 24} + } + }, + [24] = { + text = { + [1] = 'Have you [1]ed the exploding cigar to Theodore Loveless?', + [2] = 'No, you haven\'t! Why do only fools apply for the fools guild?', + [3] = 'You\'re hell of a guy, I bet you enjoyed it. As you represent everything a fool stands for, I give you this fool\'s sceptre to spiceup your jester outfit. If you are interested, there are even more missions for a fool like yourself. Just ask about them.' + }, + yes = true, + checkStorage = Storage.WhatAFoolish.Cigar, + updateStorages = { + {key = Storage.WhatAFoolish.Mission8, value = 5}, + {key = Storage.WhatAFoolish.Questline, value = 25} + }, + addItem = {itemId = 7958}, + addon = 1 + }, + [25] = { + text = { + [1] = { + 'Well, I think as a true fool you have to think big. So our next little prank will be on a grand scale. Of course, this will need some preparation ...', + 'Firstly, take this vial and use it on a dead stalker immediately after his death to collect his warm blood. Report about your mission when you are done.' + } + }, + updateStorages = { + {key = Storage.WhatAFoolish.Mission9, value = 1}, + {key = Storage.WhatAFoolish.Questline, value = 26} + }, + addItem = {itemId = 7478} + }, + [26] = { + text = { + [1] = 'Have you gotten the blood that we need?', + [2] = 'No, you haven\'t! Why do only fools apply for the fools guild?', + [3] = { + 'Congratulations! Now let\'s talk about the complicated part. We need the ink of a quara constrictor. Use this vial on a fresh corpse to get the ink ...', + 'Stop making these grimaces! I know it\'s a foolish task, but after all that\'s also the fun about it. Get the ink and report to me about your mission.' + } + }, + yes = true, + removeItem = {itemId = 7488}, + updateStorages = { + {key = Storage.WhatAFoolish.Mission9, value = 2}, + {key = Storage.WhatAFoolish.Questline, value = 27} + }, + addItem = {itemId = 7478} + }, + [27] = { + text = { + [1] = 'Have you acquired the constrictor\'s ink?', + [2] = 'No, you haven\'t! Why do only fools apply for the fools guild?', + [3] = 'Excellent. As a true fool you have of course no clue what these ingredients are good for, but I will enlighten you. Just ask about your next mission and I\'ll tell you everything you need to know.' + }, + yes = true, + removeItem = {itemId = 7489}, + updateStorages = { + {key = Storage.WhatAFoolish.Mission9, value = 3}, + {key = Storage.WhatAFoolish.Questline, value = 28} + } + }, + [28] = { + text = { + [1] = { + 'Blood of a stalker and ink of a quara are the main ingredients of the prop for our next prank. Mix it together to obtain some nice vanishing ink ...', + 'It looks exactly like normal ink, however, exposed to air it will vanish within minutes. I\'m sure you understand how useful this ink can be ...', + 'Now, listen to my plan. Go to Sam and order 2000 steel shields. He will never agree to it if you do not sign a contract ...', + 'Use the vanishing ink to sign the contract and then hand the paper back to him. This will keep this humourless doter busy for a while. Talk to me about your mission when you are done.' + } + }, + updateStorages = { + {key = Storage.WhatAFoolish.Mission9, value = 4}, + {key = Storage.WhatAFoolish.Questline, value = 29} + }, + addItem = {itemId = 7490} + }, + [29] = { + text = { + [1] = 'So have you fooled the old Sam yet?', + [2] = 'No, you haven\'t! Why do only fools apply for the fools guild?', + [3] = 'What a splendid prank! If you are ready for more, ask me about the next mission.' + }, + yes = true, + checkStorage = Storage.WhatAFoolish.Contract, + updateStorages = { + {key = Storage.WhatAFoolish.Mission9, value = 5}, + {key = Storage.WhatAFoolish.Questline, value = 30} + } + }, + [30] = { + text = { + [1] = { + 'This time I have no real mission for you, rather a small errand. I bet you had expected some dangerous and exhausting quest but since I like you so much, I make it veeeeery easy for you ...', + 'Here are some cookies. Beware though, those are exploding confetti cookies. You will have to [1] them to 10 special persons, then return to me and report about your mission. Seems easy, doesn\'t it? Are you going to accept this mission?' + }, + [3] = { + 'Great! That\'s the word of a true fool! Maybe you want to write the names down. Here we go: [1] a cookie to: ...', + 'The pompous hero Avar Tar in Edron, Simon the greedy beggar on Fibula, the pirate Ariella on the Shattered Isles, the dubious Lorbas next to the ruins of the Dark Cathedral, King Markwin in the underground city Mintwalin ...', + 'The shaman Hjaern on the ice island Nibelor, the witch Wyda in the Green Claw Swamp, the ape Hairycles in the jungle city Banuta ...', + 'The orc king in the orc fortress Uldrek\'s Rock and the last one to EITHER Yaman, the green djinn, OR, Nah\'Bob, the blue djinn ...', + 'A piece of cake isn\'t it? Did you take notes? If you need the list again, just ask me for it. Otherwise leave now and report about the mission whenever you\'re done.' + } + }, + yes = true, + updateStorages = { + {key = Storage.WhatAFoolish.Mission10, value = 1}, + {key = Storage.WhatAFoolish.Questline, value = 31} + }, + addItem = {itemId = 8111, count = 10} + }, + [31] = { + text = { + [1] = 'Are you done with your little delivery mission?', + [3] = 'Indeed, you\'re done. By the way, you look a little bit tired and dirty. However, if you still have some power left, ask me about the next mission.' + }, + yes = true, + cookiesDelivery = true, + updateStorages = { + {key = Storage.WhatAFoolish.Mission10, value = 2}, + {key = Storage.WhatAFoolish.Questline, value = 32} + } + }, + [32] = { + text = { + [1] = { + 'I\'m sure you\'re wondering how many tiring missions old Bozo has still in store for you! Don\'t worry! You\'re almost done, only one final mission left ...', + 'Well, that is after you got the needed material. First of all, bring me 5 pieces of white cloth. Then we talk more about your mission.' + } + }, + updateStorages = { + {key = Storage.WhatAFoolish.Mission11, value = 1}, + {key = Storage.WhatAFoolish.Questline, value = 33} + } + }, + [33] = { + text = { + [1] = 'Have you been able to get hold of 5 pieces of white cloth?', + [2] = 'No, you haven\'t! Why do only fools apply for the fools guild?', + [3] = { + 'Well done. Anyway, I reeeally hate to tell you but ... as white as it\'s now we have no use for it. Don\'t worry though. There is a way to give it an old and worn look ...', + 'The unforgiving desert sun combined with the noxious fumes of the Plague Spike in Darama will do the trick ...', + 'Travel to Darama, climb the Plague Spike and look for a nice spot to let mother nature do the work. Perhaps something like an altar would be useful. Once you\'re done, return here and learn about the next step of your mission.' + } + }, + yes = true, + removeItem = {itemId = 5909, count = 5}, + updateStorages = { + {key = Storage.WhatAFoolish.Mission11, value = 2}, + {key = Storage.WhatAFoolish.Questline, value = 34} + }, + addItem = {itemId = 7500} + }, + [34] = { + text = { + [1] = 'Do you have a piece of old and worn cloth?', + [2] = 'No, you don\'t! Why do only fools apply for the fools guild?', + [3] = { + 'Fine, fine. Now let\'s do the last step of our foolish plan. Smart as I am, I used a pair of scissors to create some old and worn bands from the cloth you have brought me. DON\'T touch it yet ...', + 'Travel to Darashia and visit caliph Kazzan. Use the bands made of the worn cloth to disguise yourself as a mummy ...', + 'Finally, talk to the caliph to give him the scare of his lifetime. Afterwards come back here and tell me about the fun you had with this mission.' + } + }, + yes = true, + removeItem = {itemId = 7501}, + updateStorages = { + {key = Storage.WhatAFoolish.Mission11, value = 3}, + {key = Storage.WhatAFoolish.Questline, value = 35} + }, + addItem = {itemId = 7502} + }, + [35] = { + text = { + [1] = 'Well, my diligent pupil, have you scared the caliph yet?', + [2] = 'No, you don\'t! Why do only fools apply for the fools guild?', + [3] = 'By Kurik, I knew you have it in you. You are a fool after my fancy. Take this jester hat, you deserve it. It will go nicely with your jester costume.' + }, + yes = true, + checkStorage = Storage.WhatAFoolish.ScaredKazzan, + updateStorages = { + {key = Storage.WhatAFoolish.Mission11, value = 4}, + {key = Storage.WhatAFoolish.Questline, value = 36} + }, + addItem = {itemId = 7957}, + addon = 2, + last = true + }, + [36] = { + text = { + [1] = 'You are a fully trained fool now who has developed to an accomplished jester. Your final mission is to bring fun and joy to the whole world.' + } + } +} + +local jesterOutfit = { + [-1] = { + text = { + [1] = 'First we will need one piece of red cloth. Do you have it with you?', + [2] = 'Ok, now we need one piece of blue cloth. Do you have one with you by chance?' + }, + removeItemId = 5911, + newValue = 1, + choice = 1 + }, + [1] = { + text = { + [1] = 'Now we need one piece of blue cloth. Do you have one with you by chance?', + [2] = 'Ok, now we need one piece of green cloth. Do you have one with you by chance?' + }, + removeItemId = 5912, + newValue = 2, + choice = 2 + }, + [2] = { + text = { + [1] = 'Now we need one piece of green cloth. Do you have one with you by chance?', + [2] = 'At last we need one piece of yellow cloth. Do you have one with you by chance?' + }, + removeItemId = 5910, + newValue = 3, + choice = 3 + }, + [3] = { + text = { + [1] = 'Now we need one piece of yellow cloth. Do you have one with you by chance?', + [2] = 'That\'s it. Here is your jester outfit. It\'s admittedly a bit basic but maybe you\'ll earn some nice accessories soon. At least you are more fittingly dressed for your next missions now.' + }, + removeItemId = 5914, + newValue = 4, + addOutfit = true, + last = true + } +} + +local value = {} + +local function greetCallback(cid) + if Player(cid):getSex() == PLAYERSEX_MALE then + npcHandler:setMessage(MESSAGE_GREET, 'Hi there, how\'s it hanging, |PLAYERNAME|! What brings you {here}?') + else + npcHandler:setMessage(MESSAGE_GREET, 'Hello, hello, hello, little lady |PLAYERNAME|! What brings you {here}?') + end + value[cid] = nil + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'join') then + if player:getStorageValue(Storage.WhatAFoolish.Questline) ~= -1 then + npcHandler:say('Wow, your stupidity would be pride and joy for every fool. You\'ve already applied as a member. Let\'s rather talk about your current mission.', cid) + return true + end + + npcHandler:say('Do you wish to become a jester and join the fools guild?', cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, 'mission') then + local targetValue = config[player:getStorageValue(Storage.WhatAFoolish.Questline)] + if not targetValue then + return true + end + + if not targetValue.yes then + if targetValue.updateStorages then + for i = 1, #targetValue.updateStorages do + local storage = targetValue.updateStorages[i] + player:setStorageValue(storage.key, storage.value) + end + end + + if targetValue.addItem then + player:addItem(targetValue.addItem.itemId, targetValue.addItem.count or 1) + end + end + + npcHandler:say(targetValue.text[1], cid) + if targetValue.yes then + npcHandler.topic[cid] = 3 + value[cid] = targetValue + end + elseif msgcontains(msg, 'jester outfit') then + if player:getStorageValue(Storage.WhatAFoolish.Questline) == 12 then + local targetValue = jesterOutfit[player:getStorageValue(Storage.WhatAFoolish.JesterOutfit)] + if not targetValue then + return true + end + + npcHandler:say(targetValue.text[1], cid) + npcHandler.topic[cid] = 4 + value[cid] = targetValue + else + npcHandler:say('I\'m sure it suits you well.', cid) + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + 'So you want to make a total fool of yourself? Fine with me, but note that becoming a real fool means more than being just an ordinary fool ...', + 'You will have to master a whole series of challenging, lengthy and, above all, totally foolish quests ...', + 'Are you sure you want to waste a part of your limited lifetime on a quest that makes a fool of yourself and which might award you with the prestigious title of a grand fool in a far away future?' + }, cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + player:setStorageValue(Storage.WhatAFoolish.Questline, 1) + player:setStorageValue(Storage.WhatAFoolish.Questlog, 1) + player:setStorageValue(Storage.WhatAFoolish.Mission1, 1) + npcHandler:say({ + 'What a foolish decision! You are indeed a worthy candidate! But let\'s talk about business ...', + 'Being a jester is not just about telling jokes. A good jester heavily relies on requisites ...', + 'Getting some requisites will be your first job. First of all we need a good supply of water squirt flowers ...', + 'I\'m making them on my own in my spare time but I need the right material. South of Thais, next to the Whiteflower Temple, you will find the ideal flowers ...', + 'Take a kitchen knife, cut the thickest and healthiest flower and bring it here. Then talk to me about your mission.' + }, cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + local targetValue = value[cid] + if targetValue.checkStorage then + if player:getStorageValue(targetValue.checkStorage) ~= 1 then + npcHandler:say(targetValue.text[2], cid) + npcHandler.topic[cid] = 0 + return true + end + end + + if targetValue.removeItem then + if not player:removeItem(targetValue.removeItem.itemId, targetValue.removeItem.count or 1, targetValue.removeItem.subType or -1) then + npcHandler:say(targetValue.text[2], cid) + npcHandler.topic[cid] = 0 + return true + end + end + + if targetValue.checkItemCount then + if player:getItemCount(targetValue.checkItemCount) == 0 then + npcHandler:say(targetValue.text[2], cid) + npcHandler.topic[cid] = 0 + return true + end + end + + if targetValue.cookiesDeliveryy then + if player:getCookiesDelivered() ~= 10 then + npcHandler:say('No, you aren\'t! Why do only fools apply for the fools guild?', cid) + npcHandler.topic[cid] = 0 + return true + end + end + + if targetValue.pie then + if player:getStorageValue(Storage.WhatAFoolish.PieBoxTimer) > 0 + and player:getStorageValue(Storage.WhatAFoolish.PieBoxTimer) < os.time() then + npcHandler:say('Eeeek! What have you done?? These pies are crawling with bugs! Those must be the infamous parcel bugs! Get some new pies at once you wannabe fool, and this time without any bugs!', cid) + npcHandler.topic[cid] = 0 + return true + end + end + + if targetValue.updateStorages then + for i = 1, #targetValue.updateStorages do + local storage = targetValue.updateStorages[i] + player:setStorageValue(storage.key, storage.value) + end + end + + if targetValue.addItem then + player:addItem(targetValue.addItem.itemId, targetValue.addItem.count or 1) + end + + if targetValue.addon then + player:addOutfitAddon(270, targetValue.addon) + player:addOutfitAddon(273, targetValue.addon) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + end + + if targetValue.effect then + Npc():getPosition():sendMagicEffect(targetValue.effect) + end + + if targetValue.last then + player:addAchievement('Perfect Fool') + player:addAchievement('Fool at Heart') + end + + npcHandler:say(targetValue.text[3], cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 4 then + local targetValue = value[cid] + if not player:removeItem(targetValue.removeItemId, 1) then + npcHandler:say('No, you don\'t! Why do only fools apply for the fools guild?', cid) + npcHandler.topic[cid] = 0 + return true + end + + player:setStorageValue(Storage.WhatAFoolish.JesterOutfit, targetValue.newValue) + if targetValue.addOutfit then + player:addOutfit(270) + player:addOutfit(273) + player:setStorageValue(Storage.WhatAFoolish.Questline, 13) + end + npcHandler:say(targetValue.text[2], cid) + if not targetValue.last then + value[cid] = jesterOutfit[targetValue.choice] + else + npcHandler.topic[cid] = 0 + end + end + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] ~= 0 then + if isInArray({1, 2}, npcHandler.topic[cid]) then + npcHandler:say('Too bad, I\'m convinced you have it in you.', cid) + elseif isInArray({3, 4}, npcHandler.topic[cid]) then + if player:getStorageValue(Storage.WhatAFoolish.Questline) == 11 + and player:getStorageValue(Storage.WhatAFoolish.EmperorBeardShave) == 1 then + player:setStorageValue(Storage.WhatAFoolish.Questline, 12) + player:setStorageValue(Storage.WhatAFoolish.Mission5, 3) + npcHandler:say({ + 'You shaved the emperor, but lost the beard? What kind of fool are you? Well, at least he will have a nice surprise when he wakes up ...', + 'Still, as a small recognition of your accomplishments I\'m willing to tell you how to get your own jester outfit. If you are interested in more fun and adventures, ask me for more missions.' + }, cid) + elseif player:getStorageValue(Storage.WhatAFoolish.Questline) == 30 then + npcHandler:say('You won\'t be successful in the fool\'s world with such an attitude.', cid) + elseif player:getStorageValue(Storage.WhatAFoolish.Questline) == 35 + and player:getStorageValue(Storage.WhatAFoolish.LostDisguise) ~= 1 then + player:addItem(7502, 1) + player:setStorageValue(Storage.WhatAFoolish.LostDisguise, 1) + npcHandler:say('You wasted the disguise?? Why do only fools apply for the fools guild? Here... try again, but be wittier this time.', cid) + else + npcHandler:say('Oh boy, why do only fools apply for the fools guild?', cid) + end + end + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'sorcerer'}, StdModule.say, {npcHandler = npcHandler, text = 'I wanted to become a sorcerer, too, but I was overqualified!'}, function(player) return player:isSorcerer() end) +keywordHandler:addKeyword({'druid'}, StdModule.say, {npcHandler = npcHandler, text = 'I wanted to become a druid, too, but I was overqualified!'}, function(player) return player:isDruid() end) +keywordHandler:addKeyword({'paladin'}, StdModule.say, {npcHandler = npcHandler, text = 'I wanted to become a paladin, too, but I was overqualified!'}, function(player) return player:isPaladin() end) +keywordHandler:addKeyword({'knight'}, StdModule.say, {npcHandler = npcHandler, text = 'I wanted to become a knight, too, but I was overqualified!'}, function(player) return player:isKnight() end) +keywordHandler:addKeyword({'sorcerer'}, StdModule.say, {npcHandler = npcHandler, text = 'The good thing about them is that they can\'t be at two places at the same time.'}) +keywordHandler:addKeyword({'druid'}, StdModule.say, {npcHandler = npcHandler, text = 'I wonder if they love my water squirt flowers as much as all other plants.'}) +keywordHandler:addKeyword({'paladin'}, StdModule.say, {npcHandler = npcHandler, text = 'They are the king\'s favourites, because they know how to \'bow\'.'}) +keywordHandler:addKeyword({'knight'}, StdModule.say, {npcHandler = npcHandler, text = 'Did you notice that old knights have their scars just on their backs?'}) + +keywordHandler:addKeyword({'here'}, StdModule.say, {npcHandler = npcHandler, text = 'A fitting place for a {jester}. I guess there are worse {jobs} around.'}) +keywordHandler:addKeyword({'king'}, StdModule.say, {npcHandler = npcHandler, text = 'Bozo: Nah, no jests about His Royal Highness.'}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = 'I rarely leave the castle. It\'s really stressful to be as popular as me.'}) +keywordHandler:addKeyword({'castle'}, StdModule.say, {npcHandler = npcHandler, text = 'This castle is my home. A fitting place for a jester and all other fools. Feel welcome.'}) +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m a jester, not a doctor!'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Bozo. But it\'s more than a name, it\'s a lifestyle for me!'}) +keywordHandler:addKeyword({'bozo'}, StdModule.say, {npcHandler = npcHandler, text = 'That\'s me: Bozo, the jester!'}) +keywordHandler:addKeyword({'guild'}, StdModule.say, {npcHandler = npcHandler, text = 'Ever since the first guild was created, there is a great demand of jesters and fools to join them.'}) +keywordHandler:addKeyword({'sell'}, StdModule.say, {npcHandler = npcHandler, text = 'Sell? Hmm, I know a little about magic and by chance I can sell you a truly unusual {weapon}.'}) +keywordHandler:addKeyword({'joke'}, StdModule.say, {npcHandler = npcHandler, text = 'I know some \'monstrous\' jokes!'}) +keywordHandler:addKeyword({'news'}, StdModule.say, {npcHandler = npcHandler, text = 'I know the newest jokes in tibia.'}) +keywordHandler:addKeyword({'how', 'are', 'you'}, StdModule.say, {npcHandler = npcHandler, text = 'Thank you, I\'m fine, the gods are with me.'}) +keywordHandler:addKeyword({'necromant', 'nectar'}, StdModule.say, {npcHandler = npcHandler, text = 'Pheeew! That sounds disgusting! Are you a cook at Frodo\'s?'}) +keywordHandler:addKeyword({'necromant'}, StdModule.say, {npcHandler = npcHandler, text = 'Don\'t feed the necromants.'}) +keywordHandler:addKeyword({'dog'}, StdModule.say, {npcHandler = npcHandler, text = 'Are we talking about Noodles?'}) +keywordHandler:addKeyword({'poodle'}, StdModule.say, {npcHandler = npcHandler, text = 'Are we talking about Noodles?'}) +keywordHandler:addKeyword({'noodles'}, StdModule.say, {npcHandler = npcHandler, text = 'Hey, the little one is almost as funny as me!'}) +keywordHandler:addKeyword({'muriel'}, StdModule.say, {npcHandler = npcHandler, text = 'Better don\'t mess with sorcerers!'}) +keywordHandler:addKeyword({'elane'}, StdModule.say, {npcHandler = npcHandler, text = 'She\'s pretty but too serious for my taste.'}) +keywordHandler:addKeyword({'marvik'}, StdModule.say, {npcHandler = npcHandler, text = 'Humourless old guy! Once, he turned me into a frog for painting his distasteful cave in pink.'}) +keywordHandler:addKeyword({'gregor'}, StdModule.say, {npcHandler = npcHandler, text = 'A man of steel with a stomach of wax. Never offer him a beer!'}) +keywordHandler:addKeyword({'quentin'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s my baby brother. If you tell him I sent you, he will grant you an extra spell or two.'}) +keywordHandler:addKeyword({'gorn'}, StdModule.say, {npcHandler = npcHandler, text = 'He sells spell scrolls each day at midnight, but you have to address him that very second.'}) +keywordHandler:addKeyword({'god'}, StdModule.say, {npcHandler = npcHandler, text = 'I better make no jokes about THIS matter.'}) +keywordHandler:addKeyword({'sam'}, StdModule.say, {npcHandler = npcHandler, text = 'Did you know that he sells a \'power axe of doom\' now? Run and buy it, he only has got three in store.'}) +keywordHandler:addKeyword({'benjamin'}, StdModule.say, {npcHandler = npcHandler, text = 'He would make a fine jester, too.'}) +keywordHandler:addKeyword({'monster'}, StdModule.say, {npcHandler = npcHandler, text = 'I know a lot of monster jokes. Just tell me a monster\'s name, come on.'}) +keywordHandler:addKeyword({'demon'}, StdModule.say, {npcHandler = npcHandler, text = 'Why are the experienced heroes quicker than others? ... The demons love fast food!'}) +keywordHandler:addKeyword({'ghoul'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do ghouls buy their robes? ... In a boooohtique!'}) +keywordHandler:addKeyword({'dragon'}, StdModule.say, {npcHandler = npcHandler, text = 'Why do dragons breathe fire? ... They ate too many sorcerers in chilli sauce!'}) +keywordHandler:addKeyword({'orc'}, StdModule.say, {npcHandler = npcHandler, text = 'Why do orcs have green skin? ... They ate at Frodo\'s!'}) +keywordHandler:addKeyword({'cyclops'}, StdModule.say, {npcHandler = npcHandler, text = 'How many eyes does a cyclops have? ... One for each IQ point they have!'}) +keywordHandler:addKeyword({'oswald'}, StdModule.say, {npcHandler = npcHandler, text = 'If you believe half the rumours he\'s spreading, you will get in a lot of trouble.'}) +keywordHandler:addKeyword({'dungeon'}, StdModule.say, {npcHandler = npcHandler, text = 'If you are a bad jester, you get a chance to visit them now and then.'}) +keywordHandler:addKeyword({'mino'}, StdModule.say, {npcHandler = npcHandler, text = 'What do all little minotaurs want to become when they are grown-ups? ... Cowboys, of course!'}) +keywordHandler:addKeyword({'troll'}, StdModule.say, {npcHandler = npcHandler, text = 'Why do trolls live underground? ... Because there are so many pks on the surface!'}) +keywordHandler:addKeyword({'bonelord'}, StdModule.say, {npcHandler = npcHandler, text = 'Why are bonelords so ugly? ... Because their mom and dad were bonelords, too!'}) +keywordHandler:addKeyword({'rat'}, StdModule.say, {npcHandler = npcHandler, text = 'Why does the rat have a wooden leg? ... Because it is a former pirate!'}) +keywordHandler:addKeyword({'spider'}, StdModule.say, {npcHandler = npcHandler, text = 'Why did the spider cross the road? ... Because it ... oh you already know this one!?'}) +keywordHandler:addKeyword({'hugo'}, StdModule.say, {npcHandler = npcHandler, text = 'I had a cousin named like that.'}) +keywordHandler:addKeyword({'cousin'}, StdModule.say, {npcHandler = npcHandler, text = 'He died some years ago.'}) +keywordHandler:addKeyword({'durin'}, StdModule.say, {npcHandler = npcHandler, text = 'Isn\'t he the author of the book \'Fun with Demons\'?'}) +keywordHandler:addKeyword({'stephan'}, StdModule.say, {npcHandler = npcHandler, text = 'He is kind of a father figure to me. Of course he denies all kinship to me.'}) +keywordHandler:addKeyword({'steve'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s a smart one. I heared he hid in a foreign country as the first bugs showed up.'}) +keywordHandler:addKeyword({'excalibug'}, StdModule.say, {npcHandler = npcHandler, text = 'I am not foolish enough to believe in the existence of this weapon.'}) +keywordHandler:addKeyword({'wall', 'carving'}, StdModule.say, {npcHandler = npcHandler, text = 'Oh, I saw some demon carvings in the dungeons as I hid there after a little joke on old Stutch.'}) +keywordHandler:addKeyword({'demon', 'carving'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes, they showed demons, seven actually, dancing around a sword! In something like a flaming pit.'}) +keywordHandler:addKeyword({'flaming', 'pit'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, don\'t ask me! Usually mages and mystics know more about such stuff.'}) + +local jobKeyword = keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m the royal jes ... uhm ... the royal tax-collector! Do you want to pay your taxes?'}) + jobKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Come back, when you have enough money.', reset = true}, function(player) return player:getMoney() < 50 end) + jobKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Thank you very much. I will have a drink or two on your health!', reset = true}, nil, function(player) if player:removeMoneyNpc(50) then end end) + jobKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Well, perhaps later.', reset = true}) + +local magicKeyword = keywordHandler:addKeyword({'magic'}, StdModule.say, {npcHandler = npcHandler, text = 'I actually know some spells! Do you want to learn how to \'lessen your load\' for 200 gold?'}) + magicKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Come back, when you have enough money.', reset = true}, function(player) return player:getMoney() < 200 end) + magicKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are, I already lessened your load.', reset = true}, nil, function(player) if player:removeMoneyNpc(200) then end end) + magicKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'You don\'t know what offer you are missing!', reset = true}) +keywordHandler:addAliasKeyword({'spell'}) + +local weaponKeyword = keywordHandler:addKeyword({'weapon'}, StdModule.say, {npcHandler = npcHandler, text = 'Do you want to buy a \'mace of the fury\' for 250 gold?'}) + weaponKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Come back, when you have enough money.', reset = true}, function(player) return player:getMoney() < 250 end) + weaponKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'And here it is, it suits you well!', reset = true}, nil, function(player) if player:removeMoneyNpc(250) then player:addItem(2570, 1) end end) + weaponKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'You dont know what offer you have passed!', reset = true}) + +keywordHandler:addKeyword({'kiss'}, StdModule.say, {npcHandler = npcHandler, text = 'Uh, go away!', ungreet = true}, function(player) return player:getSex() == PLAYERSEX_MALE end) + +local kissKeyword = keywordHandler:addKeyword({'kiss'}, StdModule.say, {npcHandler = npcHandler, text = 'Do you want to kiss me?'}) + kissKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Uh, oh! ... I am seeing stars!', reset = true}, nil, function(player) player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) end) + kissKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Pah, I didn\'t want to kiss you anyway!', reset = true}) + +keywordHandler:addKeyword({'lady'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, women don\'t behave necessarily in a ladylike way just because they dress like one!'}, function(player) return player:getSex() == PLAYERSEX_MALE end) + +local ladyKeyword = keywordHandler:addKeyword({'lady'}, StdModule.say, {npcHandler = npcHandler, text = 'Has any man said to you that you\'re not only beautiful but also intelligent?'}) + ladyKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'This is a world of fantasy and full of surprises!', reset = true}) + ladyKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Well, think about it!', reset = true}) + +npcHandler:setMessage(MESSAGE_FAREWELL, 'Remember: A joke a day keeps the ghouls away!') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Hey! Fools have feelings too.') + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/braden.lua b/data/npc/scripts/braden.lua new file mode 100644 index 00000000000..d0c68ddbca1 --- /dev/null +++ b/data/npc/scripts/braden.lua @@ -0,0 +1,18 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/bradford.lua b/data/npc/scripts/bradford.lua new file mode 100644 index 00000000000..d0c68ddbca1 --- /dev/null +++ b/data/npc/scripts/bradford.lua @@ -0,0 +1,18 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/brasith.lua b/data/npc/scripts/brasith.lua new file mode 100644 index 00000000000..0a9fbed370d --- /dev/null +++ b/data/npc/scripts/brasith.lua @@ -0,0 +1,32 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "You may buy all the things we grow or gather at this place."}) +keywordHandler:addKeyword({'crunor'}, StdModule.say, {npcHandler = npcHandler, text = "We abandoned the gods a long time ago. A short time after they abandoned us."}) +keywordHandler:addKeyword({'teshial'}, StdModule.say, {npcHandler = npcHandler, text = "They are lost, and if they still exist they are alone in the cold and the darkness."}) +keywordHandler:addKeyword({'kuridai'}, StdModule.say, {npcHandler = npcHandler, text = "The Kuridai left the true path and can't see their error. Their way of living may have been suitable in the past, but if they don't come back to us, their path will lead into darkness."}) +keywordHandler:addKeyword({'deraisim'}, StdModule.say, {npcHandler = npcHandler, text = "We have still much to learn but we are on the correct path at least."}) +keywordHandler:addKeyword({'cenath'}, StdModule.say, {npcHandler = npcHandler, text = "The Cenath forgot as many as they learned. I doubt they find the wisdom they are looking for without the things they neglected in their pursuit of knowledge."}) +keywordHandler:addKeyword({'troll'}, StdModule.say, {npcHandler = npcHandler, text = "I don't claim to understand this creatures but sometimes they are more close to the roots than we are."}) +keywordHandler:addKeyword({'human'}, StdModule.say, {npcHandler = npcHandler, text = "They are so many, so planless, so divided. They choose a path I do not want for my own race."}) +keywordHandler:addKeyword({'plants'}, StdModule.say, {npcHandler = npcHandler, text = "Life takes many forms. Plants are a very basic form of life. Its simplicity makes them close to the core of nature."}) +keywordHandler:addKeyword({'tree'}, StdModule.say, {npcHandler = npcHandler, text = "Life takes many forms. Plants are a very basic form of life. Its simplicity makes them close to the core of nature."}) + +npcHandler:setMessage(MESSAGE_GREET, "Ashari, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Asha Thrazi.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Asha Thrazi.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/brengus.lua b/data/npc/scripts/brengus.lua new file mode 100644 index 00000000000..d0c68ddbca1 --- /dev/null +++ b/data/npc/scripts/brengus.lua @@ -0,0 +1,18 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/brewster.lua b/data/npc/scripts/brewster.lua new file mode 100644 index 00000000000..5a8c2afa4d5 --- /dev/null +++ b/data/npc/scripts/brewster.lua @@ -0,0 +1,108 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Twist of Fate +local blessKeyword = keywordHandler:addKeyword({'twist of fate'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'This is a special blessing I can bestow upon you once you have obtained at least one of the other blessings and which functions a bit differently. ...', + 'It only works when you\'re killed by other adventurers, which means that at least half of the damage leading to your death was caused by others, not by monsters or the environment. ...', + 'The {twist of fate} will not reduce the death penalty like the other blessings, but instead prevent you from losing your other blessings as well as the amulet of loss, should you wear one. It costs the same as the other blessings. ...', + 'Would you like to receive that protection for a sacrifice of |PVPBLESSCOST| gold, child?' + }}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the protection of the twist of fate, pilgrim.', cost = '|PVPBLESSCOST|', bless = 1}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Adventurer Stone +keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Keep your adventurer\'s stone well.'}, function(player) return player:getItemById(18559, true) end) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for free?'}, function(player) return player:getStorageValue(Storage.AdventurersGuild.FreeStone.Brewster) ~= 1 end) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, nil, function(player) player:addItem(18559, 1) player:setStorageValue(Storage.AdventurersGuild.FreeStone.Brewster, 1) end) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for 30 gold?'}) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, + function(player) return player:getMoney() + player:getBankBalance() >= 30 end, + function(player) if player:removeMoneyNpc(30) then player:addItem(18559, 1) end end + ) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, you don\'t have enough money.', reset = true}) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +-- Wooden Stake +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'I think you have forgotten to bring your stake, pilgrim.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 9 and player:getItemCount(5941) == 0 end) + +local stakeKeyword = keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes, I have been informed and haven\'t yet drunk enough to forget, so you can count yourself lucky. Are you prepared to receive my line of the prayer?'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 9 end) + stakeKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'So receive my prayer: \'Your hand shall be guided - your feet shall walk in harmony\'. Now, take your stake to Tyrias in Liberty Bay for the next line of the prayer. I shall let him know what he is to do.', reset = true}, nil, + function(player) player:setStorageValue(Storage.FriendsandTraders.TheBlessedStake, 10) player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) end + ) + stakeKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'I\'ll wait for you.', reset = true}) + +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You should visit Tyrias in Liberty Bay now.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 10 end) +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You have already received my line of the prayer. Don\'t make me do more work than necessary!'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) > 10 end) +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'A blessed stake? That\'s a strange request. Maybe Quentin knows more, he is one of the oldest monks after all.'}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.'}, function(player) return player:hasBlessing(2) end) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin will provide you with the embrace of Tibia.'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, young |PLAYERNAME|! If you are heavily wounded or poisoned, I can {heal} you for free.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Remember: If you are heavily wounded or poisoned, I can heal you for free.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'May the gods bless you, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/briasol.lua b/data/npc/scripts/briasol.lua new file mode 100644 index 00000000000..76d33f8f2f1 --- /dev/null +++ b/data/npc/scripts/briasol.lua @@ -0,0 +1,58 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local voices = { {text = 'Come and take a look at the finest gems in the lands of Tibia.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "fine vase") then + if player:getStorageValue(Storage.TravellingTrader.Mission04) == 1 then + npcHandler:say({ + "Rashid sent you, I suppose. Before I sell you that vase, one word of advice. ...", + "Make room in your backpack so that I can place the vase carefully inside it. If it falls to the floor, it will most likely shatter or break if you try to pick it up again. ...", + "This vase it not meant to be touched by human hands, so just keep your hands off it. Are you ready to buy that vase for 1000 gold?" + }, cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + if player:getMoney() + player:getBankBalance() >= 1000 then + npcHandler:say("Here it is.", cid) + player:setStorageValue(Storage.TravellingTrader.Mission04, 2) + player:addItem(7582, 1) + player:removeMoneyNpc(1000) + else + npcHandler:say("You don't have enought money.", cid) + end + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +-- Greeting message +keywordHandler:addGreetKeyword({"ashari"}, {npcHandler = npcHandler, text = "Greetings, |PLAYERNAME|."}) +--Farewell message +keywordHandler:addFarewellKeyword({"asgha thrazi"}, {npcHandler = npcHandler, text = "Good bye, |PLAYERNAME|."}) + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/bright_percht_sleigh.lua b/data/npc/scripts/bright_percht_sleigh.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/bright_percht_sleigh.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/brodrosch.lua b/data/npc/scripts/brodrosch.lua new file mode 100644 index 00000000000..26e8a9bfef4 --- /dev/null +++ b/data/npc/scripts/brodrosch.lua @@ -0,0 +1,87 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Passage to Cormaya! Unforgettable steamboat ride!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, 'ticket') then + if Player(cid):getStorageValue(Storage.WagonTicket) >= os.time() then + npcHandler:say('Your weekly ticket is still valid. Would be a waste of money to purchase a second one', cid) + return true + end + + npcHandler:say('Do you want to purchase a weekly ticket for the ore wagons? With it you can travel freely and swiftly through Kazordoon for one week. 250 gold only. Deal?', cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, 'yes') and npcHandler.topic[cid] > 0 then + local player = Player(cid) + if npcHandler.topic[cid] == 1 then + if not player:removeMoneyNpc(250) then + npcHandler:say('You don\'t have enough money.', cid) + npcHandler.topic[cid] = 0 + return true + end + + player:setStorageValue(Storage.WagonTicket, os.time() + 7 * 24 * 60 * 60) + npcHandler:say('Here is your stamp. It can\'t be transferred to another person and will last one week from now. You\'ll get notified upon using an ore wagon when it isn\'t valid anymore.', cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] > 0 then + npcHandler:say('No then.', cid) + npcHandler.topic[cid] = 0 + end + return true +end + +local function addTravelKeyword(keyword, cost, discount, destination, action) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a ride to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = discount}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, text = 'Full steam ahead!', cost = cost, discount = discount, destination = destination}, nil, action) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('farmine', 210, {'postman', 'new frontier'}, +function(player) + local destination = Position(33025, 31553, 14) + if player:getStorageValue(Storage.TheNewFrontier.Mission05) == 7 then --if The New Frontier Quest 'Mission 05: Getting Things Busy' complete then Stage 3 + destination.z = 10 + elseif player:getStorageValue(Storage.TheNewFrontier.Mission03) >= 2 then --if The New Frontier Quest 'Mission 03: Strangers in the Night' complete then Stage 2 + destination.z = 12 + end + + return destination +end +) +addTravelKeyword('cormaya', 160, 'postman', Position(33311, 31989, 15), +function(player) + if player:getStorageValue(Storage.Postman.Mission01) == 4 then + player:setStorageValue(Storage.Postman.Mission01, 5) + end +end +) + +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Do you want me take you to {Cormaya} or {Farmine}?'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, |PLAYERNAME|! May earth protect you on the rocky grounds. If you need a {passage}, I can help you.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye then.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/broken_servant_sentry.lua b/data/npc/scripts/broken_servant_sentry.lua new file mode 100644 index 00000000000..1fa8346ba8d --- /dev/null +++ b/data/npc/scripts/broken_servant_sentry.lua @@ -0,0 +1,91 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function creatureSayCallback(cid, type, msg) + if(not npcHandler:isFocused(cid)) then + return false + end + + if(msgcontains(msg, "slime") or msgcontains(msg, "mould") or msgcontains(msg, "fungus") or msgcontains(msg, "sample")) then + if(getPlayerStorageValue(cid, Storage.ElementalistQuest1) < 1) then + npcHandler:say("If. You. Bring. Slime. Fungus. Samples. Fro-Fro-Fro-Frrrr*chhhhchrk*From. Other. Tower. You. Must. Be. The. Master. Are. You. There. Master?", cid) + npcHandler.topic[cid] = 1 + elseif(getPlayerStorageValue(cid, Storage.ElementalistQuest1) == 1) then + npcHandler:say("If. You. Bring. Slime. Fungus. Samples. Fro-Fro-Fro-Frrrr*chhhhchrk*From. Other. Tower. You. Must. Be. The. Master. Are. You. There. Master?", cid) + npcHandler.topic[cid] = 3 + end + + elseif(msgcontains(msg, "cap") or msgcontains(msg, "mage")) then + if(getPlayerItemCount(cid, 13756) >= 1 and getPlayerStorageValue(cid, Storage.ElementalistQuest1) == 2) and getPlayerStorageValue(cid, Storage.ElementalistQuest2) < 1 then + selfSay("Yo-Yo-Your*chhhrk*. Cap. Is. Slimed. I. Can. Clean. It. *chhhhrrrkchrk* ...", cid) + npcHandler:say("Here. You. Are. *chhhrrrrkchrk*", cid) + doPlayerRemoveItem(cid, 13756, 1) + setPlayerStorageValue(cid, Storage.ElementalistQuest2, 1) + doPlayerAddOutfit(cid, 432, 1) + doPlayerAddOutfit(cid, 433, 1) + npcHandler.topic[cid] = 0 + elseif(getPlayerStorageValue(cid, Storage.ElementalistQuest2) == 1) then + selfSay("You already have this outfit!", cid) + npcHandler.topic[cid] = 0 + end + + + elseif(msgcontains(msg, "staff") or msgcontains(msg, "spike")) then + if(getPlayerItemCount(cid, 13940) >= 1 and getPlayerStorageValue(cid, Storage.ElementalistQuest1) == 2) and getPlayerStorageValue(cid, Storage.ElementalistQuest3) < 1 then + npcHandler:say({"Yo-Yo-Your*chhhrk*. Cap. Is. Slimed. I. Can. Clean. It. *chhhhrrrkchrk* ...", + "Here. You. Are. *chhhrrrrkchrk*"}, cid, 0, 1, 4000) + doPlayerRemoveItem(cid, 13940, 1) + setPlayerStorageValue(cid, Storage.ElementalistQuest3, 1) + doPlayerAddOutfit(cid, 432, 2) + doPlayerAddOutfit(cid, 433, 2) + npcHandler.topic[cid] = 0 + elseif(getPlayerStorageValue(cid, Storage.ElementalistQuest3) == 1) then + selfSay("You already have this outfit!", cid) + npcHandler.topic[cid] = 0 + end + + elseif(msgcontains(msg, "yes")) then + if(npcHandler.topic[cid] == 1) then + npcHandler:say("I. Greet. You. Ma-Ma-Ma-ster! Did. You. Bring. Mo-Mo-Mo-M*chhhhrrrk*ore. Samples. For. Me. To-To-To. Analyse-lyse-lyse?", cid) + npcHandler.topic[cid] = 2 + elseif(npcHandler.topic[cid] == 2) then + npcHandler:say("Thank. I. Will. Start. Analysing. No-No-No-No*chhrrrk*Now.", cid) + setPlayerStorageValue(cid, Storage.ElementalistQuest1, 1) + setPlayerStorageValue(cid, Storage.ElementalistOutfitStart, 1) --this for default start of Outfit and Addon Quests + npcHandler.topic[cid] = 0 + elseif(npcHandler.topic[cid] == 3) then + npcHandler:say("I. Greet. You. Ma-Ma-Ma-ster! Did. You. Bring. Mo-Mo-Mo-M*chhhhrrrk*ore. Samples. For. Me. To-To-To. Analyse-lyse-lyse?", cid) + npcHandler.topic[cid] = 4 + elseif(npcHandler.topic[cid] == 4) and getPlayerItemCount(cid, 13758) >= 20 then + npcHandler:say({"Please. Wait. I. Can. Not. Han-Han-Han*chhhhhrrrchrk*Handle. *chhhhrchrk* This. Is. Enough. Material. *chrrrchhrk* ...", + "I. Have-ve-ve-veee*chrrrck*. Also. Cleaned. Your. Clothes. Master. It. Is. No-No-No*chhrrrrk*Now. Free. Of. Sample. Stains."}, cid, 0, 1, 4000) + doPlayerRemoveItem(cid, 13758, 20) + setPlayerStorageValue(cid, Storage.ElementalistQuest1, 2) + doPlayerAddOutfit(cid, 432, 0) + doPlayerAddOutfit(cid, 433, 0) + npcHandler.topic[cid] = 0 + else + selfSay("You do not have all the required items.", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/brom.lua b/data/npc/scripts/brom.lua new file mode 100644 index 00000000000..e88e935b7eb --- /dev/null +++ b/data/npc/scripts/brom.lua @@ -0,0 +1,20 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/bron.lua b/data/npc/scripts/bron.lua new file mode 100644 index 00000000000..0d9d2643cdb --- /dev/null +++ b/data/npc/scripts/bron.lua @@ -0,0 +1,153 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.OutfitQuest.BarbarianAddon) == 6 then + npcHandler:setMessage(MESSAGE_GREET, "Oh no! Was that really me? This is so embarassing, I have no idea what has gotten into me. Was that the fighting spirit you gave me?") + end + return true +end + +keywordHandler:addKeyword({'gelagos'}, StdModule.say, {npcHandler = npcHandler, text = "This... person... makes me want to... say something bad... must... control myself. "}) + +local function creatureSayCallback(cid, type, msg) + if(not npcHandler:isFocused(cid)) then + return false + end + + local player = Player(cid) + if isInArray({"recruitment", "violence", "outfit", "addon"}, msg) then + if player:getStorageValue(Storage.OutfitQuest.BarbarianAddon) < 1 then + npcHandler:say({ + "Convincing Ajax that it is not always necessary to use brute force... this would be such an achievement. Definitely a hard task though. ...", + "Listen, I simply have to ask, maybe a stranger can influence him better than I can. Would you help me with my brother?" + }, cid) + npcHandler.topic[cid] = 1 + end + elseif(msgcontains(msg, "fist")) then + if player:getStorageValue(Storage.OutfitQuest.BarbarianAddon) == 3 then + npcHandler:say("Oh! He really said that? I am so proud of you, |PLAYERNAME|. These are really good news. Everything would be great... if only there wasn't this {person} near my house.", cid) + npcHandler.topic[cid] = 3 + end + elseif(msgcontains(msg, "person")) then + if(npcHandler.topic[cid] == 3) then + npcHandler:say({ + "This... person... makes me want to... say something bad... must... control myself. I really don't know what to do anymore. ...", + "I wonder if Ajax has an idea. Could you ask him about Gelagos?" + }, cid) + npcHandler.topic[cid] = 4 + end + elseif(msgcontains(msg, "fighting spirit")) then + if player:getStorageValue(Storage.OutfitQuest.BarbarianAddon) == 5 then + if player:removeItem(5884, 1) then + player:setStorageValue(Storage.OutfitQuest.BarbarianAddon, 6) + npcHandler:say("Fighting spirit? What am I supposed to do with this fi... - oh! I feel strange... ME MIGHTY! ME WILL CHASE OFF ANNOYING KIDS!GROOOAARR!! RRRRRRRRRRRRAAAAAAAGE!!", cid) + npcHandler.topic[cid] = 0 + end + end + elseif(msgcontains(msg, "cloth")) then + if player:getStorageValue(Storage.OutfitQuest.BarbarianAddon) == 7 then + npcHandler:say("Have you really managed to fulfil the task and brought me 50 pieces of red cloth and 50 pieces of green cloth?", cid) + npcHandler.topic[cid] = 8 + end + elseif(msgcontains(msg, "silk")) then + if player:getStorageValue(Storage.OutfitQuest.BarbarianAddon) == 8 then + npcHandler:say("Oh, did you bring 10 rolls of spider silk yarn for me?", cid) + npcHandler.topic[cid] = 9 + end + elseif(msgcontains(msg, "sweat")) then + if player:getStorageValue(Storage.OutfitQuest.BarbarianAddon) == 9 then + npcHandler:say("Were you able to get hold of a flask with pure warrior's sweat?", cid) + npcHandler.topic[cid] = 10 + end + elseif(msgcontains(msg, "yes")) then + if(npcHandler.topic[cid] == 1) then + npcHandler:say({ + "Really! That is such an incredibly nice offer! I already have a plan. You have to teach him that sometimes words are stronger than fists. ...", + "Maybe you can provoke him with something to get angry, like saying... 'MINE!' or something. But beware, I'm sure that he will try to hit you. ...", + "Don't do this if you feel weak or ill. He will probably want to make you leave by using violence, but just stay strong and refuse to give up. ...", + "If he should ask what else is necessary to make you leave, tell him to 'say please'. Afterwards, do leave and return to him one hour later. ...", + "This way he might learn that violence doesn't always help, but that a friendly word might just do the trick. ...", + "Have you understood everything I told you and are really willing to take this risk?" + }, cid) + npcHandler.topic[cid] = 2 + elseif(npcHandler.topic[cid] == 2) then + npcHandler:say("You are indeed not only well educated, but also very courageous. I wish you good luck, you are my last hope.", cid) + player:setStorageValue(Storage.OutfitQuest.BarbarianAddon, 1) + player:setStorageValue(Storage.OutfitQuest.DefaultStart, 1) --this for default start of Outfit and Addon Quests + npcHandler.topic[cid] = 0 + elseif(npcHandler.topic[cid] == 4) then + npcHandler:say("Again, I have to thank you for your selfless offer to help me. I hope that Ajax can come up with something, now that he has experienced the power of words.", cid) + player:setStorageValue(Storage.OutfitQuest.BarbarianAddon, 4) + npcHandler.topic[cid] = 0 + elseif(player:getStorageValue(Storage.OutfitQuest.BarbarianAddon) == 6 and npcHandler.topic[cid] == 0) then + npcHandler:say({ + "I'm impressed... I am sure this was Ajax' idea. I would love to give him a present, but if I leave my hut to gather ingredients, hewill surely notice. ...", + "Would you maybe help me again, one last time, my friend? I assure you that your efforts will not be in vain." + }, cid) + npcHandler.topic[cid] = 6 + elseif(npcHandler.topic[cid] == 6) then + npcHandler:say({ + "Great! You see, I really would love to sew a nice shirt for him. I just need a few things for that, so please listen closely: ...", + "He loves green and red, so I will need about 50 pieces of red cloth - like the material heroes make their capes of - and 50 pieces of the green cloth Djinns like. ...", + "Secondly, I need about 10 rolls of spider silk yarn. I think mermaids can yarn silk of large spiders to create a smooth thread. ...", + "The only remaining thing needed would be a bottle of warrior's sweat to spray it over the shirt... he just loves this smell. ...", + "Have you understood everything I told you and are willing to handle this task?" + }, cid) + npcHandler.topic[cid] = 7 + elseif(npcHandler.topic[cid] == 7) then + npcHandler:say("Thank you, my friend! Come back to me once you have collected 50 pieces of red cloth and 50 pieces of green cloth.", cid) + player:setStorageValue(Storage.OutfitQuest.BarbarianAddon, 7) + npcHandler.topic[cid] = 0 + elseif(npcHandler.topic[cid] == 8) then + if player:getItemCount(5910) >= 50 and player:getItemCount(5911) >= 50 then + npcHandler:say("Terrific! I will start to trim it while you gather 10 rolls of spider silk. I'm sure that Ajax will love it.", cid) + player:removeItem(5910, 50) + player:removeItem(5911, 50) + player:setStorageValue(Storage.OutfitQuest.BarbarianAddon, 8) + npcHandler.topic[cid] = 0 + end + elseif(npcHandler.topic[cid] == 9) then + if player:removeItem(5886, 10) then + npcHandler:say("I'm impressed! You really managed to get spider silk yarn for me! I will immediately start to work on this shirt. Please don't forget to bring me warrior's sweat!", cid) + player:setStorageValue(Storage.OutfitQuest.BarbarianAddon, 9) + npcHandler.topic[cid] = 0 + end + elseif(npcHandler.topic[cid] == 10) then + if player:removeItem(5885, 1) then + npcHandler:say("Good work, |PLAYERNAME|! Now I can finally finish this present for Ajax. Because you were such a great help, I have also a present for you. Will you accept it?", cid) + player:setStorageValue(Storage.OutfitQuest.BarbarianAddon, 10) + npcHandler.topic[cid] = 0 + end + elseif player:getStorageValue(Storage.OutfitQuest.BarbarianAddon) == 10 then + npcHandler:say("I have kept this traditional barbarian wig safe for many years now. It is now yours! I hope you will wear it proudly, friend.", cid) + player:setStorageValue(Storage.OutfitQuest.BarbarianAddon, 11) + player:addOutfitAddon(147, 2) + player:addOutfitAddon(143, 2) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_FAREWELL, "Take care, |PLAYERNAME|!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Take care!") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/bruce.lua b/data/npc/scripts/bruce.lua new file mode 100644 index 00000000000..608431099c0 --- /dev/null +++ b/data/npc/scripts/bruce.lua @@ -0,0 +1,50 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, 'report') then + local player = Player(cid) + if isInArray({9, 11}, player:getStorageValue(Storage.InServiceofYalahar.Questline)) then + npcHandler:say('Well, .. .', cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, player:getStorageValue(Storage.InServiceofYalahar.Questline) + 1) + player:setStorageValue(Storage.InServiceofYalahar.Mission02, player:getStorageValue(Storage.InServiceofYalahar.Mission02) + 1) -- StorageValue for Questlog 'Mission 02: Watching the Watchmen' + end + elseif msgcontains(msg, 'pass') then + npcHandler:say('You can {pass} either to the {Alchemist Quarter} or {Cemetery Quarter}. Which one will it be?', cid) + npcHandler.topic[cid] = 1 + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, 'alchemist') then + local destination = Position(32738, 31113, 7) + Player(cid):teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'cemetery') then + local destination = Position(32743, 31113, 7) + Player(cid):teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/bruno.lua b/data/npc/scripts/bruno.lua new file mode 100644 index 00000000000..22f2265b7e0 --- /dev/null +++ b/data/npc/scripts/bruno.lua @@ -0,0 +1,29 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'offer'}, StdModule.say, {npcHandler = npcHandler, text = "Well, I sell freshly caught fish. You like some? Of course, you can buy more than one at once. *grin* Just ask me for a {trade}."}) +keywordHandler:addKeyword({'buy'}, StdModule.say, {npcHandler = npcHandler, text = "Well, I sell freshly caught fish. You like some? Of course, you can buy more than one at once. *grin* Just ask me for a {trade}."}) +keywordHandler:addKeyword({'fish'}, StdModule.say, {npcHandler = npcHandler, text = "Well, I sell freshly caught fish. You like some? Of course, you can buy more than one at once. *grin* Just ask me for a {trade}."}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "My name is Bruno."}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "My job is to catch fish and to sell them here."}) +keywordHandler:addKeyword({'marlene'}, StdModule.say, {npcHandler = npcHandler, text = "Ah yes, my lovely wife. God forgive her, but she can't stop talking. So my work is a great rest for my poor ears. *laughs loudly*"}) +keywordHandler:addKeyword({'graubart'}, StdModule.say, {npcHandler = npcHandler, text = "I like this old salt. I learned much from him. Whatever. You like some fish? *grin*"}) + +npcHandler:setMessage(MESSAGE_GREET, "Ahoi, |PLAYERNAME|. You want to buy some fresh fish?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye and come again!") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Buy all the fish you want. It's fresh and healthy, promised.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/brutus.lua b/data/npc/scripts/brutus.lua new file mode 100644 index 00000000000..e88e935b7eb --- /dev/null +++ b/data/npc/scripts/brutus.lua @@ -0,0 +1,20 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/buddel.lua b/data/npc/scripts/buddel.lua new file mode 100644 index 00000000000..0767b4e0b7d --- /dev/null +++ b/data/npc/scripts/buddel.lua @@ -0,0 +1,42 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Travel +local function addTravelKeyword(keyword, text, destination, condition) + if condition then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'No, no, no, you even are no barb....barba...er.. one of us!!!! Talk to the Jarl first! '}, condition) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = text, cost = 50, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = 50, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'You shouldn\'t miss the experience.', reset = true}) +end + +addTravelKeyword('okolnir', 'It\'s nice there. Except of the ice dragons which are not very companionable.', Position(32225, 31381, 7), function(player) return player:getStorageValue(Storage.BarbarianTest.Questline) < 8 end) +addTravelKeyword('helheim', 'T\'at is a small island to the east.', Position(32462, 31174, 7), function(player) return player:getStorageValue(Storage.BarbarianTest.Questline) < 8 end) +addTravelKeyword('tyrsung', '*HICKS* Big, big island east of here. Venorian hunters settled there ..... I could bring you north of their camp.', Position(32333, 31227, 7), function(player) return player:getStorageValue(Storage.BarbarianTest.Questline) < 8 end) +addTravelKeyword('camp', 'Both of you look like you could defend yourself! If you want to go there, ask me for a passage.', Position(32021, 31294, 7), function(player) return player:getStorageValue(Storage.BarbarianTest.Questline) < 8 end) + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, text = 'Get out o\' here!*HICKS*', destination = {Position(32255, 31193, 7), Position(32256, 31193, 7), Position(32257, 31193, 7)}}) + +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = "Where are we at the moment? Is this Svargrond? Ahh yes!*HICKS* Where do you want to go?"}) +keywordHandler:addKeyword({'trip'}, StdModule.say, {npcHandler = npcHandler, text = "Where are we at the moment? Is this Svargrond? Ahh yes!*HICKS* Where do you want to go?"}) +keywordHandler:addKeyword({'go'}, StdModule.say, {npcHandler = npcHandler, text = "Where are we at the moment? Is this Svargrond? Ahh yes!*HICKS* Where do you want to go?"}) +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = "Where are we at the moment? Is this Svargrond? Ahh yes!*HICKS* Where do you want to go?"}) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/buddel_helheim.lua b/data/npc/scripts/buddel_helheim.lua new file mode 100644 index 00000000000..27d51055c75 --- /dev/null +++ b/data/npc/scripts/buddel_helheim.lua @@ -0,0 +1,42 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Travel +local function addTravelKeyword(keyword, text, destination, condition) + if condition then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'No, no, no, you even are no barb....barba...er.. one of us!!!! Talk to the Jarl first! '}, condition) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = text, cost = 50, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = 50, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'You shouldn\'t miss the experience.', reset = true}) +end + +addTravelKeyword('svargrond', 'You know a town nicer than this? NICER DICER! Apropos, don\'t play dice when you are drunk ...', Position(32255, 31197, 7)) +addTravelKeyword('okolnir', 'It\'s nice there. Except of the ice dragons which are not very companionable.', Position(32225, 31381, 7), function(player) return player:getStorageValue(Storage.BarbarianTest.Questline) < 8 end) +addTravelKeyword('tyrsung', '*HICKS* Big, big island east of here. Venorian hunters settled there ..... I could bring you north of their camp.', Position(32333, 31227, 7), function(player) return player:getStorageValue(Storage.BarbarianTest.Questline) < 8 end) +addTravelKeyword('camp', 'Both of you look like you could defend yourself! If you want to go there, ask me for a passage.', Position(32021, 31294, 7), function(player) return player:getStorageValue(Storage.BarbarianTest.Questline) < 8 end) + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, text = 'Get out o\' here!*HICKS*', destination = {Position(32468, 31176, 7)}}) + +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = "Where are we at the moment? Is this Svargrond? Ahh yes!*HICKS* Where do you want to go?"}) +keywordHandler:addKeyword({'trip'}, StdModule.say, {npcHandler = npcHandler, text = "Where are we at the moment? Is this Svargrond? Ahh yes!*HICKS* Where do you want to go?"}) +keywordHandler:addKeyword({'go'}, StdModule.say, {npcHandler = npcHandler, text = "Where are we at the moment? Is this Svargrond? Ahh yes!*HICKS* Where do you want to go?"}) +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = "Where are we at the moment? Is this Svargrond? Ahh yes!*HICKS* Where do you want to go?"}) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/buddel_okolnir.lua b/data/npc/scripts/buddel_okolnir.lua new file mode 100644 index 00000000000..a33b8c6e39c --- /dev/null +++ b/data/npc/scripts/buddel_okolnir.lua @@ -0,0 +1,42 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Travel +local function addTravelKeyword(keyword, text, destination, condition) + if condition then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'No, no, no, you even are no barb....barba...er.. one of us!!!! Talk to the Jarl first! '}, condition) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = text, cost = 50, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = 50, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'You shouldn\'t miss the experience.', reset = true}) +end + +addTravelKeyword('svargrond', 'You know a town nicer than this? NICER DICER! Apropos, don\'t play dice when you are drunk ...', Position(32255, 31197, 7)) +addTravelKeyword('camp', 'Both of you look like you could defend yourself! If you want to go there, ask me for a passage.', Position(32021, 31294, 7), function(player) return player:getStorageValue(Storage.BarbarianTest.Questline) < 8 end) +addTravelKeyword('helheim', 'T\'at is a small island to the east.', Position(32462, 31174, 7), function(player) return player:getStorageValue(Storage.BarbarianTest.Questline) < 8 end) +addTravelKeyword('tyrsung', '*HICKS* Big, big island east of here. Venorian hunters settled there ..... I could bring you north of their camp.', Position(32333, 31227, 7), function(player) return player:getStorageValue(Storage.BarbarianTest.Questline) < 8 end) + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, text = 'Get out o\' here!*HICKS*', destination = {Position(32228, 31386, 7)}}) + +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = "Where are we at the moment? Is this Svargrond? Ahh yes!*HICKS* Where do you want to go?"}) +keywordHandler:addKeyword({'trip'}, StdModule.say, {npcHandler = npcHandler, text = "Where are we at the moment? Is this Svargrond? Ahh yes!*HICKS* Where do you want to go?"}) +keywordHandler:addKeyword({'go'}, StdModule.say, {npcHandler = npcHandler, text = "Where are we at the moment? Is this Svargrond? Ahh yes!*HICKS* Where do you want to go?"}) +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = "Where are we at the moment? Is this Svargrond? Ahh yes!*HICKS* Where do you want to go?"}) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/buddel_raider_camp.lua b/data/npc/scripts/buddel_raider_camp.lua new file mode 100644 index 00000000000..51ccda7e508 --- /dev/null +++ b/data/npc/scripts/buddel_raider_camp.lua @@ -0,0 +1,42 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Travel +local function addTravelKeyword(keyword, text, destination, condition) + if condition then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'No, no, no, you even are no barb....barba...er.. one of us!!!! Talk to the Jarl first! '}, condition) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = text, cost = 50, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = 50, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'You shouldn\'t miss the experience.', reset = true}) +end + +addTravelKeyword('svargrond', 'You know a town nicer than this? NICER DICER! Apropos, don\'t play dice when you are drunk ...', Position(32255, 31197, 7)) +addTravelKeyword('okolnir', 'It\'s nice there. Except of the ice dragons which are not very companionable.', Position(32225, 31381, 7), function(player) return player:getStorageValue(Storage.BarbarianTest.Questline) < 8 end) +addTravelKeyword('helheim', 'T\'at is a small island to the east.', Position(32462, 31174, 7), function(player) return player:getStorageValue(Storage.BarbarianTest.Questline) < 8 end) +addTravelKeyword('tyrsung', '*HICKS* Big, big island east of here. Venorian hunters settled there ..... I could bring you north of their camp.', Position(32333, 31227, 7), function(player) return player:getStorageValue(Storage.BarbarianTest.Questline) < 8 end) + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, text = 'Get out o\' here!*HICKS*', destination = {Position(32020, 31297, 7), Position(32021, 31297, 7), Position(32022, 31297, 7)}}) + +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = "Where are we at the moment? Is this Svargrond? Ahh yes!*HICKS* Where do you want to go?"}) +keywordHandler:addKeyword({'trip'}, StdModule.say, {npcHandler = npcHandler, text = "Where are we at the moment? Is this Svargrond? Ahh yes!*HICKS* Where do you want to go?"}) +keywordHandler:addKeyword({'go'}, StdModule.say, {npcHandler = npcHandler, text = "Where are we at the moment? Is this Svargrond? Ahh yes!*HICKS* Where do you want to go?"}) +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = "Where are we at the moment? Is this Svargrond? Ahh yes!*HICKS* Where do you want to go?"}) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/buddel_tyrsung.lua b/data/npc/scripts/buddel_tyrsung.lua new file mode 100644 index 00000000000..ddb91a0a93a --- /dev/null +++ b/data/npc/scripts/buddel_tyrsung.lua @@ -0,0 +1,42 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Travel +local function addTravelKeyword(keyword, text, destination, condition) + if condition then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'No, no, no, you even are no barb....barba...er.. one of us!!!! Talk to the Jarl first! '}, condition) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = text, cost = 50, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = 50, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'You shouldn\'t miss the experience.', reset = true}) +end + +addTravelKeyword('svargrond', 'You know a town nicer than this? NICER DICER! Apropos, don\'t play dice when you are drunk ...', Position(32255, 31197, 7)) +addTravelKeyword('okolnir', 'It\'s nice there. Except of the ice dragons which are not very companionable.', Position(32225, 31381, 7), function(player) return player:getStorageValue(Storage.BarbarianTest.Questline) < 8 end) +addTravelKeyword('helheim', 'T\'at is a small island to the east.', Position(32462, 31174, 7), function(player) return player:getStorageValue(Storage.BarbarianTest.Questline) < 8 end) +addTravelKeyword('camp', 'Both of you look like you could defend yourself! If you want to go there, ask me for a passage.', Position(32021, 31294, 7), function(player) return player:getStorageValue(Storage.BarbarianTest.Questline) < 8 end) + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, text = 'Get out o\' here!*HICKS*', destination = {Position(32332, 31232, 7)}}) + +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = "Where are we at the moment? Is this Svargrond? Ahh yes!*HICKS* Where do you want to go?"}) +keywordHandler:addKeyword({'trip'}, StdModule.say, {npcHandler = npcHandler, text = "Where are we at the moment? Is this Svargrond? Ahh yes!*HICKS* Where do you want to go?"}) +keywordHandler:addKeyword({'go'}, StdModule.say, {npcHandler = npcHandler, text = "Where are we at the moment? Is this Svargrond? Ahh yes!*HICKS* Where do you want to go?"}) +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = "Where are we at the moment? Is this Svargrond? Ahh yes!*HICKS* Where do you want to go?"}) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/budrik.lua b/data/npc/scripts/budrik.lua new file mode 100644 index 00000000000..80998db0667 --- /dev/null +++ b/data/npc/scripts/budrik.lua @@ -0,0 +1,108 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.toOutfoxAFoxQuest) < 1 then + npcHandler:say({ + "Funny that you are asking me for a mission! There is indeed something you can do for me. Ever heard about The Horned Fox? Anyway, yesterday his gang has stolen my mining helmet during a raid. ...", + "It belonged to my father and before that to my grandfather. That helmet is at least 600 years old! I need it back. Are you willing to help me?" + }, cid) + npcHandler.topic[cid] = 1 + + elseif player:getStorageValue(Storage.toOutfoxAFoxQuest) == 1 then + if player:removeItem(7497, 1) then + player:setStorageValue(Storage.toOutfoxAFoxQuest, 2) + player:addItem(7939, 1) + npcHandler:say("I always said it to the others 'This brave fellow will bring me my mining helmet back' and here you are with it!! Here take my spare helmet, I don't need it anymore!", cid) + else + npcHandler:say("We presume the hideout of The Horned Fox is somewhere in the south-west near the coast, good luck finding my mining helmet!", cid) + end + npcHandler.topic[cid] = 0 + else npcHandler:say("Hum... what, {task}?", cid) + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + player:setStorageValue(Storage.toOutfoxAFoxQuest, 1) + npcHandler:say("I knew you have the guts for that task! We presume the hideout of The Horned Fox somewhere in the south-west near the coast. Good luck!", cid) + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 2 then + npcHandler:say("Hussah! Let's bring war to those hoof-legged, dirt-necked, bull-headed minotaurs!! Come back to me when you are done with your mission.", cid) + player:setStorageValue(JOIN_STOR, 1) + player:setStorageValue(Storage.KillingInTheNameOf.BudrikMinos, 1) + player:setStorageValue(Storage.KillingInTheNameOf.BudrikMinosCount, 0) + npcHandler.topic[cid] = 0 + + + else npcHandler:say("Zzz...", cid) + + end + elseif msgcontains(msg, "task") then + -- AQUI + if player:getStorageValue(Storage.KillingInTheNameOf.BudrikMinos) <= 0 then + npcHandler:say({ + "I am so angry I could spit grit! That damn Horned Fox and his attacks! Let's show those bull-heads that they have messed with the wrong people....", + "I want you to kill {5000 minotaurs} - no matter where - for me and all the dwarfs of Kazordoon! Are you willing to do that?" + }, cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(Storage.KillingInTheNameOf.BudrikMinos) == 1 then + if player:getStorageValue(Storage.KillingInTheNameOf.BudrikMinosCount) >= 5000 then + npcHandler:say({ + "By all that is holy! You are a truly great warrior! With much patience! I have just found out the location the hideout of {The Horned Fox}! I have marked the spot on your map so you can find it. Go there and slay him!! Good luck!" + }, cid) + player:setStorageValue(17522, 1) + player:setStorageValue(Storage.KillingInTheNameOf.BudrikMinos, 2) + else + npcHandler:say("Come back when you have slain {5000 minotaurs!}", cid) + end + elseif player:getStorageValue(Storage.KillingInTheNameOf.BudrikMinos) == 2 then + npcHandler:say({ + "It was very decent of you to help me, and I am thankful, really I am, but now I have to get back to my duties as a foreman." + }, cid) + player:setStorageValue(Storage.KillingInTheNameOf.BudrikMinos, 3) + elseif player:getStorageValue(Storage.KillingInTheNameOf.BudrikMinos) == 3 then + npcHandler:say("You already done this task.", cid) + npcHandler.topic[cid] = 0 + else npcHandler:say("You need to do the {To Outfox a Fox Quest} before.", cid) + end + -- AQUI + + -- YES AQUI + + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] > 1 then + npcHandler:say("Then no.", cid) + npcHandler.topic[cid] = 0 + end + end + -- YES AQUI + + return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, "Bye, bye.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Bye, bye.") +npcHandler:setMessage(MESSAGE_GREET, "Hiho, hiho |PLAYERNAME|.") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/bunny_bonecrusher.lua b/data/npc/scripts/bunny_bonecrusher.lua new file mode 100644 index 00000000000..7e88f20e83b --- /dev/null +++ b/data/npc/scripts/bunny_bonecrusher.lua @@ -0,0 +1,35 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'hail general'}, StdModule.say, {npcHandler = npcHandler, text = "Salutations, commoner |PLAYERNAME|!"}) +keywordHandler:addKeyword({'how', 'are', 'you'}, StdModule.say, {npcHandler = npcHandler, text = "We are in constant training and in perfect health."}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am the general of the queen's army. I don't have time to explain this concept to you."}) +keywordHandler:addKeyword({'bonecrusher'}, StdModule.say, {npcHandler = npcHandler, text = "Our family has been serving the Carlin army since countless generations!"}) +keywordHandler:addKeyword({'sister'}, StdModule.say, {npcHandler = npcHandler, text = "Our family has been serving the Carlin army since countless generations!"}) +keywordHandler:addKeyword({'family'}, StdModule.say, {npcHandler = npcHandler, text = "She is one of my beloved sisters and serves Carlin as a town guard."}) +keywordHandler:addKeyword({'queen'}, StdModule.say, {npcHandler = npcHandler, text = "HAIL TO QUEEN ELOISE, OUR NOBLE {LEADER}!"}) +keywordHandler:addKeyword({'leader'}, StdModule.say, {npcHandler = npcHandler, text = "Queen Eloise is a fine leader for our fair town, indeed!"}) +keywordHandler:addKeyword({'army'}, StdModule.say, {npcHandler = npcHandler, text = "The army protects the defenceless males of our {city}. Our elite forces are the {Green Ferrets}."}) +keywordHandler:addKeyword({'city'}, StdModule.say, {npcHandler = npcHandler, text = "Our city blends in with the nature surrounding it. Our {druids} take care of that."}) +keywordHandler:addKeyword({'druids'}, StdModule.say, {npcHandler = npcHandler, text = "They are our main magic support and play a major role in our battle {tactics}."}) +keywordHandler:addKeyword({'tactics'}, StdModule.say, {npcHandler = npcHandler, text = "Our tactic is to kiss."}) +keywordHandler:addKeyword({'kiss'}, StdModule.say, {npcHandler = npcHandler, text = "K.I.S.S.! Keep It Simple, Stupid! Complicated tactics are too easy to be crushed by a twist of fate."}) +keywordHandler:addKeyword({'green ferrets'}, StdModule.say, {npcHandler = npcHandler, text = "Our elite forces are trained by rangers and druids. In the woods they come a close second to elves."}) +keywordHandler:addKeyword({'join'}, StdModule.say, {npcHandler = npcHandler, text = "Join what?"}) +keywordHandler:addKeyword({'join army'}, StdModule.say, {npcHandler = npcHandler, text = "Sorry, we don't recruit foreigners. Maybe you can join if you prove yourself in a mission for the queen."}) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/busty_bonecrusher.lua b/data/npc/scripts/busty_bonecrusher.lua new file mode 100644 index 00000000000..38381e59c2d --- /dev/null +++ b/data/npc/scripts/busty_bonecrusher.lua @@ -0,0 +1,44 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Behave yourself as long as you are in Carlin, commoner!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(10, 1000, -10) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if isInArray({"fuck", "idiot", "asshole", "ass", "fag", "stupid", "tyrant", "shit", "lunatic"}, msg) then + npcHandler:say("Take this!", cid) + local player = Player(cid) + player:getPosition():sendMagicEffect(CONST_ME_EXPLOSIONAREA) + player:addCondition(condition) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "LONG LIVE THE QUEEN!") +npcHandler:setMessage(MESSAGE_FAREWELL, "LONG LIVE THE QUEEN!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "LONG LIVE THE QUEEN!") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/cael.lua b/data/npc/scripts/cael.lua new file mode 100644 index 00000000000..953e4b7c50d --- /dev/null +++ b/data/npc/scripts/cael.lua @@ -0,0 +1,366 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function getTable(player) + local itemsList = { + {name="Didgeridoo", id=3952, buy=5,000}, + {name="War Drum", id=3953, buy=1,000} + } + return itemsList +end + +local function setNewTradeTable(table) + local items, item = {} + for i = 1, #table do + item = table[i] + items[item.id] = {itemId = item.id, buyPrice = item.buy, sellPrice = item.sell, subType = 0, realName = item.name} + end + return items +end + +local function onBuy(cid, item, subType, amount, ignoreCap, inBackpacks) + local player = Player(cid) + local items = setNewTradeTable(getTable(player)) + if not ignoreCap and player:getFreeCapacity() < ItemType(items[item].itemId):getWeight(amount) then + return player:sendTextMessage(MESSAGE_FAILURE, 'You don\'t have enough cap.') + end + if not doPlayerRemoveMoney(cid, items[item].buyPrice * amount) then + selfSay("You don't have enough money.", cid) + else + player:addItem(items[item].itemId, amount) + return player:sendTextMessage(MESSAGE_TRADE, 'Bought '..amount..'x '..items[item].realName..' for '..items[item].buyPrice * amount..' gold coins.') + end + return true +end + +local function onSell(cid, item, subType, amount, ignoreCap, inBackpacks) + local player = Player(cid) + local items = setNewTradeTable(getTable(player)) + if items[item].sellPrice and player:removeItem(items[item].itemId, amount) then + player:addMoney(items[item].sellPrice * amount) + return player:sendTextMessage(MESSAGE_TRADE, 'Sold '..amount..'x '..items[item].realName..' for '..items[item].sellPrice * amount..' gold coins.') + else + selfSay("You don't have item to sell.", cid) + end + return true +end + +local function creatureSayCallback(cid, type, msg) + local player = Player(cid) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, "tome") or msgcontains(msg, "knowledge") then + --The first 8 missions of The New Frontier Quest completed to be able to trade 6 Tomes of Knowledge with NPC Cael. + if player:getStorageValue(Storage.TheNewFrontier.Mission08) == 2 then + if player:getStorageValue(Storage.TheNewFrontier.TomeofKnowledge) < 1 then --tome1 + npcHandler:say("Oh! That sounds fascinating. Have you found a Tome of Knowledge for me to read?", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.TheNewFrontier.TomeofKnowledge) >= 1 and player:getStorageValue(Storage.TheNewFrontier.TomeofKnowledge) <= 5 then --tome2 - tome6 + npcHandler:say("Oh! That sounds fascinating. Have you found a new Tome of Knowledge for me to read?", cid) + npcHandler.topic[cid] = player:getStorageValue(Storage.TheNewFrontier.TomeofKnowledge)+1 + elseif player:getStorageValue(Storage.TheNewFrontier.TomeofKnowledge) >= 6 and player:getStorageValue(Storage.TheNewFrontier.TomeofKnowledge) <= 11 then --tome7 - tome12 + --The New Frontier Quest completed to trade more Tomes of Knowledge with NPC Cael. + if player:getStorageValue(Storage.TheNewFrontier.Mission10) == 1 then + npcHandler:say("Oh! That sounds fascinating. Have you found a new Tome of Knowledge for me to read?", cid) + npcHandler.topic[cid] = player:getStorageValue(Storage.TheNewFrontier.TomeofKnowledge)+1 + else + npcHandler:say("I'm sorry I'm busy. Speak with Ongulf to get some missions!", cid) + end + elseif player:getStorageValue(Storage.TheNewFrontier.TomeofKnowledge) >= 12 then -- more then 12 tomes + npcHandler:say("Oh! That sounds fascinating. Have you found a Tome of Knowledge for me to read? I have the feeling though that I can only share some of my experience with you now. Is that alright with you?", cid) + npcHandler.topic[cid] = 13 + end + else + npcHandler:say("I'm sorry I'm busy. Speak with Ongulf to get some missions!", cid) + end + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] >= 1 and npcHandler.topic[cid] <= 13 then + if player:removeItem(11134, 1) then --remove tome + if npcHandler.topic[cid] == 1 then --tome1 + npcHandler:say("Thank you! I look forward to reading this interesting discovery of yours and learn a few things about {Zao}.", cid) + player:setStorageValue(Storage.TheNewFrontier.TomeofKnowledge, 1) + npcHandler.topic[cid] = 21 + elseif npcHandler.topic[cid] >= 2 and npcHandler.topic[cid] <= 12 then --tome2 - tome12 + npcHandler:say("Thank you! I look forward to reading this interesting discovery of yours and learn a few things about {Zao}.", cid) + player:setStorageValue(Storage.TheNewFrontier.TomeofKnowledge, player:getStorageValue(Storage.TheNewFrontier.TomeofKnowledge) + 1) + npcHandler.topic[cid] = player:getStorageValue(Storage.TheNewFrontier.TomeofKnowledge)+20 + elseif npcHandler.topic[cid] == 13 then -- more then 12 tomes + player:addExperience(5000, true) + npcHandler:say("Thank you! I look forward to reading this interesting discovery of yours and learn a few things about {Zao}. Let me share some experience with you.", cid) + npcHandler.topic[cid] = 33 + end + else + npcHandler:say("You dont have one!", cid) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "zao")) then + if npcHandler.topic[cid] == 21 then --tome1 + npcHandler:say("I've learnt more about the {lizard} culture. It's really fascinating.", cid) + npcHandler.topic[cid] = 40 + elseif npcHandler.topic[cid] == 22 then --tome2 + npcHandler:say("I've learnt more about the {minotaur} culture. It's really fascinating.", cid) + npcHandler.topic[cid] = 41 + elseif npcHandler.topic[cid] == 23 then --tome3 + npcHandler:say("I've learnt more about the {Draken} culture by now. It's really fascinating.", cid) + npcHandler.topic[cid] = 42 + elseif npcHandler.topic[cid] == 24 then --tome4 + npcHandler:say("I've learnt something interesting about a certain {food} that the lizardmen apparently prepare.", cid) + npcHandler.topic[cid] = 43 + elseif npcHandler.topic[cid] == 25 then --tome5 + npcHandler:say("I've learnt something interesting about a city called {Zzaion}.", cid) + npcHandler.topic[cid] = 44 + elseif npcHandler.topic[cid] == 26 then --tome6 + npcHandler:say("I've learnt a few things about the primitive {human} culture on this continent.", cid) + npcHandler.topic[cid] = 45 + elseif npcHandler.topic[cid] == 27 then --tome7 + npcHandler:say("I've learnt something interesting about the Zao {steppe}.", cid) + npcHandler.topic[cid] = 46 + elseif npcHandler.topic[cid] == 28 then --tome8 + npcHandler:say("I've learnt a few things about an illness, or how I prefer to call it, {corruption} of this land.", cid) + npcHandler.topic[cid] = 47 + elseif npcHandler.topic[cid] == 29 then --tome9 + npcHandler:say("I've learnt something interesting about the Draken {origin}.", cid) + npcHandler.topic[cid] = 48 + elseif npcHandler.topic[cid] == 30 then --tome10 + npcHandler:say("This book actually IS about Zao. Not about the continent, but about the mythical {founder} of the lizard dynasty.", cid) + npcHandler.topic[cid] = 49 + elseif npcHandler.topic[cid] == 31 then --tome11 + npcHandler:say("I've learnt something interesting about {dragons} and their symbolism.", cid) + npcHandler.topic[cid] = 50 + elseif npcHandler.topic[cid] == 32 then --tome12 + npcHandler:say("The last tome contained a lot of information about status symbols and insignia - such as {thrones} - and reveals some of the power structures in Zao.", cid) + npcHandler.topic[cid] = 51 + elseif npcHandler.topic[cid] == 33 then --more than tome12 + npcHandler:say("I've learnt many things from your books. Still, I guess that's just a fragment of what I could still discover about this interesting continent.", cid) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "lizard")) then --tome1 + if npcHandler.topic[cid] == 40 then + npcHandler:say({ + "Did you know that the lizardmen were among the first races roaming this continent? They were waging war against the orcs, minotaurs and humans on Zao and for a long time it seemed that the forces were even. ...", + "However, a while later, also a race of dragons arrived on this continent. Seeing the lizards as distant relatives, they decided to support their war, and together they drove all other races back into the steppe. ...", + "It turned out though that the dragonkin didn't really view the lizards as allies but as servants and demanded gold and slaves for their help. Part of the lizard population agreed and obeyed their new masters, the others stirred up a violent rebellion. ...", + "It doesn't really say what happened afterwards, but in the book were also pictures of special symbols the lizards use for their flags and banners. I've given this to Pompan. Maybe he can find a way to use it." + }, cid) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "minotaur")) then --tome2 + if npcHandler.topic[cid] == 41 then + npcHandler:say({ + "Did you know that most of the minotaurs you might have met by now do not originally come from Zao? The original minotaur race stood no chance against the united force of dragons and lizards. ...", + "Most of them were killed and captured, but a few of them were able to flee the continent. They found other minotaurs, mighty Mooh'Tah masters, and told them their story. ...", + "The Mooh'Tah masters actually found the continent Zao and started to look for their lost brothers, but it doesn't say whether they actually found any survivors. ...", + "In the tome, there was also a really nice pattern of a carrying device that might have been used by minotaurs. Or maybe by enemies of minotaurs. I've given it to Pompan. ...", + "Maybe he can find a way to use it... we dwarfs are not that skilled when it comes to fashion." + }, cid) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "draken")) then --tome3 + if npcHandler.topic[cid] == 42 then + npcHandler:say({ + "According to what I've read in that tome, the Draken seem to be a crossbreed between lizards and dragons, combining the dragons' strength with the lizards' swiftness. They seem to be the main figures in the dragons' internal quarrels. ...", + "They can't fly and are stuck with walking on two feet, but else they combine the best of two worlds - they are intelligent, powerful and both strong magic users and skilled weapon wielders. ...", + "Have you been to one of their settlements yet? They seem to have really beautifully adorned weapon racks. I've given a construction plan of such a rack to Esrik. Maybe he can recreate it." + }, cid) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "food")) then --tome4 + if npcHandler.topic[cid] == 43 then + npcHandler:say({ + "I discovered an interesting recipe in this Tome of Knowledge. Maybe you've seen the large rice terraces in Muggy Plains - that is how the lizardmen apparently call that region. ...", + "The book is a lot of blabla about how they cultivate and harvest their rice, but there's something we could actually learn, and that is a certain way to prepare that rice. ...", + "If you ever come across a ripe rice plant, bring it to Swolt in the tavern and he might help you prepare it - grumpily." + }, cid) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "zzaion")) then --tome5 + if npcHandler.topic[cid] == 44 then + npcHandler:say({ + "Have you ever seen the towers of the large lizard city south-east of Zao? It's the last one south of the mountains and who knows how long they are able to hold it. ...", + "It's under constant and heavy siege by the steppe orcs and minotaurs. Sometimes they manage to crush the gates and storm the city. Watch out, you probably don't want to stumble right into the middle of a war. Or maybe you do? ...", + "Anyway, I found another nice pattern in this book. It's for a lizard carrying device. I've given it to Pompan, just in case you're interested." + }, cid) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "human")) then --tome6 + if npcHandler.topic[cid] == 45 then + npcHandler:say({ + "Well, to be honest it doesn't say much about humans in this book. However, it seems that the humans on this continent used to live in the steppe. ...", + "In the great war against dragons and lizards, they didn't stand the slightest chance due to lack of equipment and well, let's face it, intelligence. The other races were superior in every way. ...", + "They were driven back into the mountains and survived by growing mushrooms, collecting herbs and probably hunting smaller animals. Today, the orcs pose a major threat to them, so I guess they need every help they can possibly get. ...", + "Anyway! The humans seem to make a so-called 'great hunt' now and then, and for that they play war instruments. If you're interested in drums or a didgeridoo and want to trade, let me know. I've recreated a few, they don't actually sound bad!" + }, cid) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "steppe")) then --tome7 + if npcHandler.topic[cid] == 46 then + npcHandler:say({ + "Maybe you don't know that the great steppe was once a fertile ground. Well, to be precise - in the distant past it probably did not look any different from what it looks today. ...", + "But when the lizard civilisation was at its peak, they apparently developed advanced irrigation systems to water the steppe and used this area as major source for their supplies on rice and other food. ...", + "Back in those times, the lizard population was immense and their need of supplies tremendous. Therefore, they did not allow other races to co-exist and exterminated most of them almost completely. ...", + "Some relics of the settlements of the pre-lizard cultures can still be found. Most of them were probably converted by the victorious lizardmen into something that suited their purposes better. ...", + "All that talk about relics reminds me about something I've recently seen when getting some fresh air up in the mountains. Right next to the carpet pilot - may earth protect me from ever having to step on that thing - was an old lizard relic. ...", + "Incredible how far their realm might have stretched at the peak of their civilisation! Time left its marks on the relic and I suppose it looks rather dangerous, but I am convinced that it is safe. You should try it out sometime." + }, cid) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "corruption")) then --tome8 + if npcHandler.topic[cid] == 47 then + npcHandler:say({ + "You know, while all this talk about growing and preparing rice might sound boring, there are actually some bits of vital information hidden in all those lists. ...", + "It seems that not only the loss of the southern area hampered the rice harvest of the lizards. ...", + "Ever since the dragon kings established their reign, the harvest constantly got worse. And this is not all! It's reported that everything that is growing in this land experienced a fertility decrease. ...", + "Even the lizards themselves seem to suffer from a population decline. It's widely blamed to a plague that ravaged the land in the past, but that seems unlikely given the fact that also plants and various animals were affected. ...", + "Additionally, several plants changed in shape and became poisonous or toxic. Also, some new-born lizards seem to be affected by this. ...", + "According to the descriptions, I'd call them mentally unstable, but their people see them as 'blessed by the dragon emperor'. I assume there are strange forces at work in this land, and I have a bad feeling about it. ...", + "Anyway, you know what else was mentioned in this book? A path down to a hidden cave system below the Muggy Plains. ...", + "Apparently, at first this system was used to hide - or rather to get rid of - new-born lizards that carried the sign of corruption - before the lizards decided to view it as a blessing. ...", + "Who knows what happens down there now - maybe it's worth a look, maybe not. Maybe you won't even discover anything. In any case, be careful." + }, cid) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "origin")) then --tome9 + if npcHandler.topic[cid] == 48 then + npcHandler:say({ + "I think the origin of the Draken sheds some new light on certain aspects of the lizard society. It is obvious from the books that the Draken appeared only after the dragon kings revealed themselves to the lizards. ...", + "It is specifically mentioned that the tide of the battle turned when they joined the army of the lizards. Parts of the tome were obviously erased and later overwritten. ...", + "In the parts of the original text that I was able to reconstruct with the help of some alchemy, there were some references to lizard spawns that were sighted in the Tiquanda area and linked to the snake god. ...", + "Admittedly, it is just a hypothesis that is based on a few hints in these tomes and my correspondence about serpent spawns with the sage Edowir... ...", + "...However, considering everything that I could figure out about their origin, they seem to hatch from the same eggs like ordinary lizardmen. ...", + "It seems that some of those eggs are imbued with spiritual or magical power and as a result bear a serpent spawn. It appears that this changed when the dragon emperor became the ruler of this land. ...", + "Unlike serpent spawns, the Draken hatched from some of the eggs in the hatcheries. ...", + "I can only imagine what this might imply. As I said, it's only a theory, but I think a quite valid one and I'd treasure any additional information about that topic. ...", + "In the meantime, I've also talked to Esrik about some information that I found in the tome concerning weaponry and armory. Knowing this dwarf, he might have some interesting offers for you by now." + }, cid) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "founder")) then --tome10 + if npcHandler.topic[cid] == 49 then + npcHandler:say({ + "It seems that some parts of the tome are just copies from other sources and rather unrelated to each other. As far as I could piece them together, there was a mythical founder of the lizard civilisation. ...", + "His name was Zao and his deeds and exploits are immortalised in lizard folklore. Some of the earliest records in the tomes suggest a slightly different story though. ...", + "Many records talk about an early lizard dynasty, but I doubt that Zao was a single person born into that dynasty. ...", + "My guess is that several members of this dynasty are responsible for or connected to the feats that were attributed to the mythical 'Zao'. ...", + "The improbable lifespan of 'Zao' can thus be explained with the time the Zao dynasty reigned. On the other hand, we all know larger-than-life heroes did exist and some of them had an extremely long lifespan. ...", + "Most likely, he also had children which could explain the mentioning of a Zao family. I think even the lizardmen don't know for sure what happened in such distant past and so this might be one of those riddles that will never be solved. ...", + "It seems that the origin of the Zao dynasty was somewhere in the Dragonblaze Peaks, or rather under them. Legends tell of a large fortress, once erected up the highest peak, but now buried deep underground. Who knows, maybe you'll find answers there?" + }, cid) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "dragons")) then --tome11 + if npcHandler.topic[cid] == 50 then + npcHandler:say({ + "Dragons are of great symbolism for this land. Even before the dragons came here and took control over Zao, the lizards worshipped the dragons as strong mythical beasts. ...", + "When the future dragon kings came here - seemingly from a distant and foreign land - they probably took some advantage of this cult. ...", + "Another symbol - that of the snake - that must have been much more popular than the dragon, faded into unimportance over the years. ...", + "I think in the past, the lizardmen of this country might have worshipped a snake god or goddess just like their brethren in Tiquanda if we can believe the reports from this area. The dragons replaced the snake worship at some point of history. ...", + "The reference to heretics and their extermination suggests that there might have been a rebellion against the dragons, which in turn hints at some close link between lizards and dragons, maybe a forced one. ...", + "While reading this tome, I discovered a drawing of this beautiful statue. I was a skilled sculptor in the past, so I can't resist. ...", + "I'm probably not that good anymore, but if you're interested and find me a red lantern, I could make one of those for you." + }, cid) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "thrones")) then --tome12 + if npcHandler.topic[cid] == 51 then + npcHandler:say({ + "In the modern lizard culture thrones seem to be only a reminiscent of the past. Whereas in the past the rulers of the lizardmen used thrones and other insignia to show their status, in our days they are ruled by dragon kings. ...", + "Those kings seem to be massive dragons of immense power. Of course they do not actually 'use' thrones anymore, but claim them nonetheless as symbol for their position. ...", + "From what I can tell, the lizards are bound to those dragon kings by some kind of magic. I'm not sure what this magic does, but I guess it ensures their loyalty to some extent. ...", + "On an interesting side note - there were some hints in the tome that the dragon kings themselves are somehow bound to the dragon emperor through the same kind of magic. ...", + "It seems this kind of liege system was formed sometime after the arrival of the dragons in this land. It's definitely an interesting field of research and shows us how much we still have to learn and to discover. ...", + "Well, I've certainly learnt how the great old thrones look like. If you bring me some red cloth, I could probably try and reconstruct one for you." + }, cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "lantern") then + if player:getStorageValue(Storage.TheNewFrontier.TomeofKnowledge) >= 11 then + npcHandler:say("Have you brought me a red lantern for a dragon statue?", cid) + npcHandler.topic[cid] = 65 + end + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 65 then + if player:removeItem(11206, 1) then + player:addItem(11133,1) + npcHandler:say("Let's put this little lantern here.. there you go. I wrap it up for you, just unwrap it in your house again!", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have a red lantern.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "cloth") then + if player:getStorageValue(Storage.TheNewFrontier.TomeofKnowledge) >= 12 then + npcHandler:say("Have you brought me a piece of red cloth? I can make that throne for you if you want. But remember, I won't do that all the time - so try and don't destroy it, okay?", cid) + npcHandler.topic[cid] = 66 + end + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 66 then + if player:removeItem(5911, 1) then + player:addItem(11205,1) + npcHandler:say("Let's put this cloth over the seat.. there you go. I wrap it up for you, just unwrap it in your house again!", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have a red cloth.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "crest") then + if player:hasOutfit(player:getSex() == PLAYERSEX_FEMALE and 336 or 335) and player:getItemCount(11116) > 0 then + npcHandler:say("Oh, wow! Now THAT is an interesting relic! Can I have that serpent crest?", cid) + npcHandler.topic[cid] = 60 + elseif player:hasOutfit(player:getSex() == PLAYERSEX_FEMALE and 336 or 335) and player:getItemCount(11115) > 0 then + npcHandler:say("Oh, wow! Now THAT is an interesting relic! Can I have that tribal crest?", cid) + npcHandler.topic[cid] = 61 + else + npcHandler:say("You don't have a Warmaster Outfit or the crest to get the Addons.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] >= 60 and npcHandler.topic[cid] <= 61 then + if npcHandler.topic[cid] == 60 then + if not player:hasOutfit(player:getSex() == PLAYERSEX_FEMALE and 336 or 335, 1) and player:removeItem(11116, 1) then + player:addOutfitAddon(335, 1) + player:addOutfitAddon(336, 1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + npcHandler:say("Thank you! Let me reward you with something I stumbled across recently and which might fit your warmaster outfit perfectly.", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have a crest or already have this Outfitaddon.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 61 then + if not player:hasOutfit(player:getSex() == PLAYERSEX_FEMALE and 336 or 335, 2) and player:removeItem(11115, 1) then + player:addOutfitAddon(335, 2) + player:addOutfitAddon(336, 2) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + npcHandler:say("Thank you! Let me reward you with something I stumbled across recently and which might fit your warmaster outfit perfectly.", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have a crest or already have this Outfitaddon.", cid) + npcHandler.topic[cid] = 0 + end + end + elseif msgcontains(msg, "trade") then + if player:getStorageValue(Storage.TheNewFrontier.TomeofKnowledge) >= 6 then + local player = Player(cid) + local items = setNewTradeTable(getTable(player)) + openShopWindow(cid, getTable(player), onBuy, onSell) + npcHandler:say("Keep in mind you won't find better offers here. Just browse through my wares.", cid) + else + npcHandler:say("Sorry, I don't have Items to trade now.", cid) + end + end + return true +end +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/cameron.lua b/data/npc/scripts/cameron.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/cameron.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/captain_bluebear.lua b/data/npc/scripts/captain_bluebear.lua new file mode 100644 index 00000000000..ee881d6655b --- /dev/null +++ b/data/npc/scripts/captain_bluebear.lua @@ -0,0 +1,87 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Passages to Carlin, Ab\'Dendriel, Edron, Venore, Port Hope, Liberty Bay, Yalahar, Roshamuul, Krailos, Oramond and Svargrond.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, cost, destination, action, condition) + if condition then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sorry but I don\'t sail there.'}, condition) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, discount = 'postman', destination = destination}, nil, action) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('carlin', 110, Position(32387, 31820, 6), +function(player) + if player:getStorageValue(Storage.Postman.Mission01) == 1 then + player:setStorageValue(Storage.Postman.Mission01, 2) + end +end) + +addTravelKeyword('ab\'dendriel', 130, Position(32734, 31668, 6)) +addTravelKeyword('edron', 160, Position(33175, 31764, 6)) +addTravelKeyword('venore', 170, Position(32954, 32022, 6)) +addTravelKeyword('port hope', 160, Position(32527, 32784, 6)) +addTravelKeyword('roshamuul', 210, Position(33494, 32567, 7)) +addTravelKeyword('svargrond', 180, Position(32341, 31108, 6)) +addTravelKeyword('liberty bay', 180, Position(32285, 32892, 6)) +addTravelKeyword('yalahar', 200, Position(32816, 31272, 6), nil, +function(player) + return player:getStorageValue(Storage.SearoutesAroundYalahar.Thais) ~= 1 + and player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) < 5 +end) +addTravelKeyword('oramond', 150, Position(33479, 31985, 7)) +addTravelKeyword('krailos', 230, Position(33492, 31712, 6)) + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, destination = {Position(32320, 32219, 6), Position(32321, 32210, 6)}}) + +-- Basic +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Captain Bluebear from the Royal Tibia Line.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this sailing-ship.'}) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this sailing-ship.'}) +keywordHandler:addKeyword({'ship'}, StdModule.say, {npcHandler = npcHandler, text = 'The Royal Tibia Line connects all seaside towns of Tibia.'}) +keywordHandler:addKeyword({'line'}, StdModule.say, {npcHandler = npcHandler, text = 'The Royal Tibia Line connects all seaside towns of Tibia.'}) +keywordHandler:addKeyword({'company'}, StdModule.say, {npcHandler = npcHandler, text = 'The Royal Tibia Line connects all seaside towns of Tibia.'}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = 'The Royal Tibia Line connects all seaside towns of Tibia.'}) +keywordHandler:addKeyword({'good'}, StdModule.say, {npcHandler = npcHandler, text = 'We can transport everything you want.'}) +keywordHandler:addKeyword({'passenger'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to welcome you on board.'}) +keywordHandler:addKeyword({'trip'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Carlin}, {Ab\'Dendriel}, {Venore}, {Port Hope}, {Liberty Bay}, {Svargrond}, {Yalahar}, {Roshamuul}, {Oramond} or {Edron}?'}) +keywordHandler:addKeyword({'route'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Carlin}, {Ab\'Dendriel}, {Venore}, {Port Hope}, {Liberty Bay}, {Svargrond}, {Yalahar}, {Roshamuul}, {Oramond} or {Edron}?'}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Carlin}, {Ab\'Dendriel}, {Venore}, {Port Hope}, {Liberty Bay}, {Svargrond}, {Yalahar}, {Roshamuul}, {Oramond} or {Edron}?'}) +keywordHandler:addKeyword({'town'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Carlin}, {Ab\'Dendriel}, {Venore}, {Port Hope}, {Liberty Bay}, {Svargrond}, {Yalahar}, {Roshamuul}, {Oramond} or {Edron}?'}) +keywordHandler:addKeyword({'destination'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Carlin}, {Ab\'Dendriel}, {Venore}, {Port Hope}, {Liberty Bay}, {Svargrond}, {Yalahar}, {Roshamuul}, {Oramond} or {Edron}?'}) +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Carlin}, {Ab\'Dendriel}, {Venore}, {Port Hope}, {Liberty Bay}, {Svargrond}, {Yalahar}, {Roshamuul}, {Oramond} or {Edron}?'}) +keywordHandler:addKeyword({'go'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Carlin}, {Ab\'Dendriel}, {Venore}, {Port Hope}, {Liberty Bay}, {Svargrond}, {Yalahar}, {Roshamuul}, {Oramond} or {Edron}?'}) +keywordHandler:addKeyword({'ice'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sorry, but we don\'t serve the routes to the Ice Islands.'}) +keywordHandler:addKeyword({'senja'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sorry, but we don\'t serve the routes to the Ice Islands.'}) +keywordHandler:addKeyword({'folda'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sorry, but we don\'t serve the routes to the Ice Islands.'}) +keywordHandler:addKeyword({'vega'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sorry, but we don\'t serve the routes to the Ice Islands.'}) +keywordHandler:addKeyword({'darashia'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m not sailing there. This route is afflicted by a ghostship! However I\'ve heard that Captain Fearless from Venore sails there.'}) +keywordHandler:addKeyword({'darama'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m not sailing there. This route is afflicted by a ghostship! However I\'ve heard that Captain Fearless from Venore sails there.'}) +keywordHandler:addKeyword({'ghost'}, StdModule.say, {npcHandler = npcHandler, text = 'Many people who sailed to Darashia never returned because they were attacked by a ghostship! I\'ll never sail there!'}) +keywordHandler:addKeyword({'thais'}, StdModule.say, {npcHandler = npcHandler, text = 'This is Thais. Where do you want to go?'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome on board, |PLAYERNAME|. Where can I {sail} you today?') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye. Recommend us if you were satisfied with our service.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye then.') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/captain_breezelda.lua b/data/npc/scripts/captain_breezelda.lua new file mode 100644 index 00000000000..f3ce67d029e --- /dev/null +++ b/data/npc/scripts/captain_breezelda.lua @@ -0,0 +1,42 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Travel +local function addTravelKeyword(keyword, cost, destination) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('thais', 110, Position(32310, 32210, 6)) +addTravelKeyword('carlin', 180, Position(32387, 31820, 6)) +addTravelKeyword('venore', 150, Position(32954, 32022, 6)) + +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Carlin}, {Venore} or {Thais}?'}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Carlin}, {Venore} or {Thais}?'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) +keywordHandler:addKeyword({'svargrond'}, StdModule.say, {npcHandler = npcHandler, text = 'This is Svargrond. Where do you want to go?'}) + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, destination = {Position(32337, 31115, 7)}}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome on board, |PLAYERNAME|. Where can I {sail} you today?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye. Recommend us if you were satisfied with our service.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye then.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/captain_chelop.lua b/data/npc/scripts/captain_chelop.lua new file mode 100644 index 00000000000..f019d863b01 --- /dev/null +++ b/data/npc/scripts/captain_chelop.lua @@ -0,0 +1,40 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'By direct edict of the honorable Henricus, we are ordered to give passage for all recruits to Thais.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local travelKeyword = keywordHandler:addKeyword({'thais'}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to Thais for |TRAVELCOST|?', cost = 210, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = 210, discount = 'postman', destination = Position(32310, 32210, 6)}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'By direct edict of the honorable Henricus himself... well, you know.', reset = true}) +keywordHandler:addAliasKeyword({'town'}) + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, destination = {Position(33495, 32564, 7), Position(33495, 32563, 7), Position(33496, 32562, 7)}}) + +-- Basic +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = "I can bring you back to {Thais} if you are weary or you can stay and fight. What shall it be?"}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "My name is Chelop and I am a captain of this {inquisition} ship."}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "Can't you see? I'm captain of the Pesadilla, the proud {inquisition} ship which anchors here."}) +keywordHandler:addKeyword({'inquisition'}, StdModule.say, {npcHandler = npcHandler, text = "By edict of the honorable Henricus himself, we are ordered to give passage to all recruits of the Roshamuul mission for a small fee."}) +keywordHandler:addKeyword({'roshamuul'}, StdModule.say, {npcHandler = npcHandler, text = "This is the island you are currently on, just in case you forgot."}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome on board, recruit |PLAYERNAME|. Where can I {sail} you today?") +npcHandler:setMessage(MESSAGE_FAREWELL, "On behalf of the inquisition, I bid you farewell.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye then.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/captain_cookie.lua b/data/npc/scripts/captain_cookie.lua new file mode 100644 index 00000000000..6c334e4b24c --- /dev/null +++ b/data/npc/scripts/captain_cookie.lua @@ -0,0 +1,32 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Travel +local travelKeyword = keywordHandler:addKeyword({'liberty bay'}, StdModule.say, {npcHandler = npcHandler, text = 'I can bring you to our base in Liberty Bay for |TRAVELCOST|. Is that what you want?', cost = 400, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = 400, discount = 'postman', destination = Position(32285, 32892, 6)}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +keywordHandler:addAliasKeyword({'passage'}) + +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = 'I can take you to {Liberty Bay}.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) +keywordHandler:addKeyword({'yalahar'}, StdModule.say, {npcHandler = npcHandler, text = 'I travelled here, hoping to find the cockaigne. Imagine my disappointment when I discovered I was wrong.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Greetings, daring adventurer. If you need a {passage}, let me know.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/captain_dreadnought.lua b/data/npc/scripts/captain_dreadnought.lua new file mode 100644 index 00000000000..33e693094a1 --- /dev/null +++ b/data/npc/scripts/captain_dreadnought.lua @@ -0,0 +1,456 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + {text = "No smuggling aboard this ship! Only 20 pieces of any creature product allowed!"}, + {text = "No fear! The Sea Cat will ship you safely to the mainland!"}, + {text = "All aboard! Prepare to sail!"}, + {text = "Come hell or high water, we'll reach any port I sail you to!"}, + {text = "This island is too small. I need sea water around me."} +} + +npcHandler:addModule(VoiceModule:new(voices)) + +-- List of all towns to ask about and to sail to +local towns = { + [TOWNS_LIST.AB_DENDRIEL] = { + name = "Ab'dendriel", + about = { + "Main city of the elves - lots of trees, bug milk and stuff that easily burns ...", + "... Sorry, just thinking aloud. Ahem. Very cosy and safe I guess if you're fond of nature." + }, + canBeSailed = true, + isPremium = false, + message = "So it's Ab'Dendriel, the tree city of the elves you chose as your new home?", + destination = {x = 32734, y = 31668, z = 6} + }, + [TOWNS_LIST.ANKRAHMUN] = { + name = "Ankrahmun", + about = {"Desert pyramid city close to the ocean, some underground tombs where I heard it's not bad hunting."}, + canBeSailed = true, + isPremium = true, + message = "So it's Ankrahmun, the city you chose as your new home?", + destination = {x = 33092, y = 32883, z = 6} + }, + [TOWNS_LIST.CARLIN] = { + name = "Carlin", + about = { + "A city ruled by forthright independent women. \z + Very clean and safe, but also very strict on the booze, alas. But if that's what you like..." + }, + canBeSailed = true, + isPremium = false, + message = "So it's Carlin, the city under women's rule, a rival to Thais you chose as your new home?", + destination = {x = 32387, y = 31820, z = 6} + }, + [TOWNS_LIST.DARASHIA] = { + name = "Darashia", + about = { + "One of the two desert cities. \z + Built around a lovely oasis. Lions, dragons... decent location for a newcomer." + }, + canBeSailed = true, + isPremium = true, + message = "So it's Darashia, the city you chose as your new home?", + destination = {x = 33289, y = 32481, z = 6} + }, + [TOWNS_LIST.EDRON] = { + name = "Edron", + about = { + "Quiet little castle city on an island in the north-eastern part of Tibia. \z + Trolls, goblins, rotworms... good place for starters, too." + }, + canBeSailed = true, + isPremium = true, + message = "So it's Edron, the city you chose as your new home?", + destination = {x = 33175, y = 31764, z = 6} + }, + [TOWNS_LIST.KAZORDOON] = { + name = "Kazordoon", + about = {"The underground dwarven city. Doesn't have a real harbour, so I can't bring you there, sorry."}, + canBeSailed = false + }, + [TOWNS_LIST.LIBERTY_BAY] = { + name = "Liberty Bay", + about = { + "Liberty Bay is on an island group in the South Seas. Ah, home sweet home. Err. I mean, \z + it's pirates galore. Good deal of tortoises, too. Just be careful, then it's a good hunting location." + }, + canBeSailed = true, + isPremium = true, + message = "So it's Liberty Bay, the city you chose as your new home?", + destination = {x = 32285, y = 32892, z = 6} + }, + [TOWNS_LIST.PORT_HOPE] = { + name = "Port Hope", + about = { + "Port Hope is an outpost right in the middle of the jungle. ...", + "Apes, bananas, hydras, tarantulas... Who'd want to go there? \z + Except for crazy adventurers like these guys here on the island, obviously." + }, + canBeSailed = true, + isPremium = true, + message = "So it's Port Hope, the city you chose as your new home?", + destination = {x = 32527, y = 32784, z = 6} + }, + [TOWNS_LIST.SVARGROND] = { + name = "Svargrond", + about = { + "Negative, can't bring you there. You gotta pass some sort of Barbarian test \z + before they let you live there. Still, you should go there sometime, I heard it's quite interesting." + }, + canBeSailed = false + }, + [TOWNS_LIST.THAIS] = { + name = "Thais", + about = { + "Old-school city. Actually the oldest main city in Tibia. \z + Be careful on those streets, there are bandits everywhere." + }, + canBeSailed = true, + isPremium = false, + message = "So it's Thais, the oldest of the human kingdoms you chose as your new home?", + destination = {x = 32310, y = 32210, z = 6} + }, + [TOWNS_LIST.VENORE] = { + name = "Venore", + about = { + "Hohoh, one of the richest cities, filled with merchants and LOOT! Err. \z + I mean, it is HIGHLY recommendable for unexperienced and first-time adventurers. \z + Don't know why they built it over a stinking swamp though." + }, + canBeSailed = true, + isPremium = false, + message = + "So it's Venore, \z + the rich swamp city of traders, recommended for new heroes, that you chose as your new home?", + destination = {x = 32954, y = 32022, z = 6} + }, + [TOWNS_LIST.YALAHAR] = { + name = "Yalahar", + about = { + "Now that must be one of the biggest cities I've ever seen. \z + Might be not cosy for a newcomer like yourself, though. And I can't sail there anyway... \z + they don't let everyone enter their fine pretty harbour, they're a bit particular." + }, + canBeSailed = false + } +} + +local defaultTown = TOWNS_LIST.VENORE +local townNames = {all = "", free = "", premium = ""} + +-- Function to build town names strings and adds additional data to sailable/premium towns about +function buildStrings() + local townsList = {all = {}, free = {}, premium = {}} + for id, town in pairs(towns) do + if town.canBeSailed then + if town.isPremium then + table.insert(townsList.premium, "{" .. town.name .. "}") + town.about[1] = "Only for {premium} travellers! " .. town.about[1] + else + table.insert(townsList.premium, "{" .. town.name .. "}") + table.insert(townsList.free, "{" .. town.name .. "}") + end + town.about[#town.about] = town.about[#town.about] .. " I can {sail} there if you like." + end + table.insert(townsList.all, "{" .. town.name .. "}") + end + for list, townList in pairs(townsList) do + if #townList == 1 then + townNames[list] = townList[1] + elseif #townList > 1 then + table.sort(townList, function(a, b) return a:upper() < b:upper() end) + local lastTown = table.remove(townList, #townList) + townNames[list] = table.concat(townList, ", ") .. " or " .. lastTown + end + end +end + +buildStrings() + +-- Function to handle donations and its messages +local function donationHandler(cid, message, keywords, parameters, node) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if (parameters.confirm ~= true) and (parameters.decline ~= true) then + npcHandler:say( + "So you want to donate " .. (player:getMoney() - 500) .. " gold coins? \z + The little kiddies are going to appreciate it.", + cid + ) + elseif (parameters.confirm == true) then + if player:getMoney() > 500 then + player:removeMoney((player:getMoney() - 500)) + npcHandler:say( + "Well, that's really generous of you. That'll feed a lot of hungry mouths for a while. \z + Right, now which {city} did you say you wanted to go to?", + cid + ) + npcHandler:resetNpc(cid) + else + npcHandler:say("Well, har har. Very funny. Come on, pick up the gold you just dropped.", cid) + end + elseif (parameters.decline == true) then + if player:getMoney() > 500 then + npcHandler:say( + "By tempest! What's all this gold weighing us down? Don't you think that's a little risky with all \z + these pirates around? You can take 500 with you, but that's it. Drop the rest or {donate} it to the \z + Adventurers' Orphans Fund, really.", + cid + ) + end + end + return true +end + +-- Function to handle town travel and its messages +local function townTravelHandler(cid, message, keywords, parameters, node) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if (parameters.confirm ~= true) and (parameters.decline ~= true) and parameters.townId then + local town = towns[parameters.townId] + if town.canBeSailed == false then + if player:isPremium() then + npcHandler:say("What? Whatever that is, it's not a port I sail to. " .. townNames.premium .. "?", cid) + else + npcHandler:say("What? Whatever that is, it's not a port I sail to. " .. townNames.free .. "?", cid) + end + elseif town.isPremium == true and not player:isPremium() then + npcHandler:say( + "Negative, can't bring you there without a premium account. \z + You should be glad you get to travel by ship - usually that's a premium service too, you know.", + cid + ) + else + npcHandler:say(town.message .. " What do you say, {yes} or {no}?", cid) + end + elseif (parameters.confirm == true) then + -- Handle money excess at confirm or it may be dropped and picked up in previous steps + if player:getMoney() > 500 then + npcHandler:say( + "By tempest! What's all this gold weighing us down? Don't you think that's a little risky with all \z + these pirates around? You can take 500 with you, but that's it. Drop the rest or {donate} it to the \z + Adventurers' Orphans Fund, really.", + cid + ) + return true + end + local parentNode = node:getParent() + local parentParameters = parentNode:getParameters() + local townId = parentParameters.townId or parameters.townId + local town = Town(townId) + player:setTown(town) + player:teleportTo(towns[townId].destination) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:setStorageValue(Storage.Dawnport.Mainland, 1) + npcHandler:say( + "Cast off! Don't forget to talk to the guide at the port for directions to nearest bars... err, shops and \z + bank and such!", + cid + ) + npcHandler:resetNpc(cid) + npcHandler:releaseFocus(cid) + elseif (parameters.decline == true) then + if player:isPremium() then + npcHandler:say("Changed your mind? Which city do you want to head to, " .. townNames.premium .. "?", cid) + else + npcHandler:say("Changed your mind? Which city do you want to head to, " .. townNames.free .. "?", cid) + end + npcHandler.keywordHandler:moveUp(cid, 1) + elseif (parameters.sailableTowns == true) and parameters.text then + if player:isPremium() then + npcHandler:say(string.gsub(parameters.text, "|TOWNS|", townNames.premium), cid) + else + npcHandler:say(string.gsub(parameters.text, "|TOWNS|", townNames.free), cid) + end + end + return true +end +-- Other topics +keywordHandler:addKeyword({"name"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Ruby Dreadnought. But it's Captain Dreadnought to you!" +}) +keywordHandler:addKeyword({"job"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "I'm captain of this little sloop here, the Sea Cat." +}) +keywordHandler:addKeyword({"ship"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "She's pretty, isn't she? Will ship you safely to any port. Though a young landlubber such as you should \z + consider to travel to Venore first. The travel is for free. Just once though! You have to ask for a {passage}." +}) +keywordHandler:addKeyword({"mainland"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "You chose a peaceful world. Not much danger from other adventurers. Just beware the monsters. \z + Want go there, ask for a {passage}." +}) +keywordHandler:addKeyword({"rookgaard"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "That old place? Sorry, I don't sail there, no loot to be had." +}) +keywordHandler:addKeyword({"adventurers guild"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "Those fellows help still green adventurers like you, so you learn the lay of the Tibian Mainlands. \z + With the adventurer's stone you can reach their guild hall from all major temples. ...", + "I recommend you travel there as soon as possible." + } +}) +keywordHandler:addKeyword({"premium"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Some regions in the world can't be accessed by everyone. Gotta pay, you know? \z + If you spend some real cash for premium time, I can bring you to much more challenging locations." +}) +keywordHandler:addKeyword({"tibia"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "That's what the whole place is called." +}) +-- Main topic nodes +local readyNode = keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Good. Got all you want to take to the mainland, {yes}? Gear, limbs, loot?" +}) +local notReadyNode = keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "What? Then what DO you want? Learn about the main Tibian {cities}?" +}) +-- Main subtopic nodes +-- hi, yes, ... +local defaultTownNode = readyNode:addChildKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "Quick learner, good answer. For inexperienced newcomers, \z + I'd recommend the city of {" .. towns[defaultTown].name .. "}. Great place to start! ...", + "Though I can tell you about the other main Tibian {cities} too, if you wish. \z + So, ready to set sail for {" .. towns[defaultTown].name .. "}?" + } +}) +readyNode:addChildKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "While you take time to ponder, I will just stroll over there and pretend not to listen to you thinking.", + ungreet = true +}) +-- hi, no, ... +local aboutTownsNode = notReadyNode:addChildKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Well, I can tell you stuff about " .. townNames.all .. "." +}) +local aboutSailNode = notReadyNode:addChildKeyword({"no"}, townTravelHandler, +{ + sailableTowns = true, + text = "So you know it all, huh? Where do you want me to bring you to, kid? |TOWNS|?" +}) +-- hi, yes, yes, ... +defaultTownNode:addChildKeyword({"yes"}, townTravelHandler, {confirm = true, townId = defaultTown}) +defaultTownNode:addAliasKeyword({towns[defaultTown].name:lower()}) +defaultTownNode:addChildKeyword({"no"}, townTravelHandler, {decline = true}) +-- Towns topic nodes +local townsNode = keywordHandler:addKeyword({"cities"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Do you want to know about " .. townNames.all .. "?" +}) +for id, town in pairs(towns) do + local townNode = KeywordNode:new({town.name:lower()}, StdModule.say, {npcHandler = npcHandler, text = town.about}) + townsNode:addChildKeywordNode(townNode) + aboutTownsNode:addChildKeywordNode(townNode) +end +keywordHandler:addAliasKeyword({"city"}) +-- Sail topic nodes +local sailNode = keywordHandler:addKeyword({"sail"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "So, you've decided on your new home city? Which one will it be?" +}) +local confirmNode = KeywordNode:new({"yes"}, townTravelHandler, {confirm = true}) +local declineNode = KeywordNode:new({"no"}, townTravelHandler, {decline = true}) +for id, town in pairs(towns) do + local townSailNode = KeywordNode:new({town.name:lower()}, townTravelHandler, {townId = id}) + townSailNode:addChildKeywordNode(confirmNode) + townSailNode:addChildKeywordNode(declineNode) + sailNode:addChildKeywordNode(townSailNode) + aboutSailNode:addChildKeywordNode(townSailNode) +end +keywordHandler:addAliasKeyword({"passage"}) +keywordHandler:addAliasKeyword({"travel"}) +-- Donate topic nodes +local donateNode = keywordHandler:addKeyword({"donate"}, donationHandler, {}, +function(player) return player:getMoney() > 500 end +) +donateNode:addChildKeywordNode(KeywordNode:new({"yes"}, donationHandler, {confirm = true})) +donateNode:addChildKeywordNode(KeywordNode:new({"no"}, donationHandler, {decline = true})) + +local function greetCallback(cid) + local player = Player(cid) + npcHandler:setMessage( + MESSAGE_GREET, + "Well, well, a new " .. player:getVocation():getName():lower() .. "! Want me to bring you somewhere nice? \z + Just say {yes}." + ) + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local currentNode = keywordHandler:getLastNode(cid) + -- Handle other words for nodes while still handling (bye, farewell) keywords + if #currentNode.children == 0 then + npcHandler:say( + "Kid, listen. Answering with a clear {yes} or {no} will get you much further in Tibia. \z + Most people are not as sharp-eared as I am. Got that?", + cid + ) + elseif currentNode == readyNode then + npcHandler:say("Errr... was that a foreign language? Could you just answer with a clear {yes} or {no}?", cid) + elseif currentNode == notReadyNode then + npcHandler:say( + "Aw, come on! Talk to me in human words! {Yes}, {no}, or mention a city's name, that kind of stuff.", + cid + ) + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage( + MESSAGE_FAREWELL, + "You sure you want to spend time on this piece of rock? I can show you the world! Huh." +) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/captain_fearless.lua b/data/npc/scripts/captain_fearless.lua new file mode 100644 index 00000000000..d92e13ffe29 --- /dev/null +++ b/data/npc/scripts/captain_fearless.lua @@ -0,0 +1,69 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) + +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Passages to Thais, Carlin, Ab\'Dendriel, Krailos, Port Hope, Edron, Darashia, Liberty Bay, Svargrond, Gray Island, Yalahar and Ankrahmun.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, cost, destination, condition) + if condition then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sorry but I don\'t sail there.'}, condition) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('thais', 170, Position(32310, 32210, 6)) +addTravelKeyword('krailos', 185, Position(33493, 31712, 6)) -- {x = 33493, y = 31712, z = 6} +addTravelKeyword('carlin', 130, Position(32387, 31820, 6)) +addTravelKeyword('gray island', 150, Position(33196, 31984, 7)) +addTravelKeyword('ab\'dendriel', 90, Position(32734, 31668, 6)) +addTravelKeyword('edron', 40, Position(33173, 31764, 6)) +addTravelKeyword('port hope', 160, Position(32527, 32784, 6)) +addTravelKeyword('svargrond', 150, Position(32341, 31108, 6)) +addTravelKeyword('liberty bay', 180, Position(32285, 32892, 6)) +addTravelKeyword('yalahar', 185, Position(32816, 31272, 6), function(player) return player:getStorageValue(Storage.SearoutesAroundYalahar.Venore) ~= 1 and player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) < 5 end) +addTravelKeyword('ankrahmun', 150, Position(33092, 32883, 6)) +addTravelKeyword('travora', 1000, Position(32055, 32368, 6)) +addTravelKeyword('issavi', 130, Position(33900, 31463, 6)) + +-- Darashia +local travelNode = keywordHandler:addKeyword({'darashia'}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to Darashia for |TRAVELCOST|?', cost = 60, discount = 'postman'}) + local childTravelNode = travelNode:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'I warn you! This route is haunted by a ghostship. Do you really want to go there?'}) + childTravelNode:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = 60, discount = 'postman', destination = function(player) return math.random(10) == 1 and Position(33324, 32173, 6) or Position(33289, 32481, 6) end}) + childTravelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, reset = true, text = 'We would like to serve you some time.'}) + travelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, reset = true, text = 'We would like to serve you some time.'}) + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, destination = {Position(32952, 32031, 6), Position(32955, 32031, 6), Position(32957, 32032, 6)}}) + +-- Basic +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Issavi}, {krailos}, {Thais}, {Carlin}, {Ab\'Dendriel}, {Port Hope}, {Edron}, {Darashia}, {Liberty Bay}, {Svargrond}, {Yalahar}, {Gray Island} or {Ankrahmun}?'}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Issavi} {krailos}, {Thais}, {Carlin}, {Ab\'Dendriel}, {Port Hope}, {Edron}, {Darashia}, {Liberty Bay}, {Svargrond}, {Yalahar}, {Gray Island} or {Ankrahmun}?'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) +keywordHandler:addKeyword({'venore'}, StdModule.say, {npcHandler = npcHandler, text = 'This is Venore. Where do you want to go?'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Captain Fearless from the Royal Tibia Line.'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome on board, |PLAYERNAME|. Where can I {sail} you today?') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye. Recommend us if you were satisfied with our service.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye then.') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/captain_greyhound.lua b/data/npc/scripts/captain_greyhound.lua new file mode 100644 index 00000000000..432c73b996e --- /dev/null +++ b/data/npc/scripts/captain_greyhound.lua @@ -0,0 +1,68 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Travel +local function addTravelKeyword(keyword, cost, destination, condition) + if condition then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sorry but I don\'t sail there.'}, condition) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('thais', 110, Position(32310, 32210, 6)) +addTravelKeyword('ab\'dendriel', 80, Position(32734, 31668, 6)) +addTravelKeyword('edron', 110, Position(33175, 31764, 6)) +addTravelKeyword('venore', 130, Position(32954, 32022, 6)) +addTravelKeyword('svargrond', 110, Position(32341, 31108, 6)) +addTravelKeyword('yalahar', 185, Position(32816, 31272, 6), function(player) return player:getStorageValue(Storage.SearoutesAroundYalahar.Carlin) ~= 1 and player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) < 5 end) + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, destination = {Position(32384, 31815, 6), Position(32387, 31815, 6), Position(32390, 31815, 6)}}) + +-- Basic +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "My name is Captain Greyhound from the Royal Tibia Line."}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am the captain of this sailing-ship."}) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = "I am the captain of this sailing-ship."}) +keywordHandler:addKeyword({'ship'}, StdModule.say, {npcHandler = npcHandler, text = "The Royal Tibia Line connects all seaside towns of Tibia."}) +keywordHandler:addKeyword({'line'}, StdModule.say, {npcHandler = npcHandler, text = "The Royal Tibia Line connects all seaside towns of Tibia."}) +keywordHandler:addKeyword({'company'}, StdModule.say, {npcHandler = npcHandler, text = "The Royal Tibia Line connects all seaside towns of Tibia."}) +keywordHandler:addKeyword({'route'}, StdModule.say, {npcHandler = npcHandler, text = "The Royal Tibia Line connects all seaside towns of Tibia."}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = "The Royal Tibia Line connects all seaside towns of Tibia."}) +keywordHandler:addKeyword({'good'}, StdModule.say, {npcHandler = npcHandler, text = "We can transport everything you want."}) +keywordHandler:addKeyword({'passenger'}, StdModule.say, {npcHandler = npcHandler, text = "We would like to welcome you on board."}) +keywordHandler:addKeyword({'trip'}, StdModule.say, {npcHandler = npcHandler, text = "Where do you want to go? To {Thais}, {Ab\'Dendriel}, {Venore}, {Svargrond}, {Yalahar} or {Edron?}"}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = "Where do you want to go? To {Thais}, {Ab\'Dendriel}, {Venore}, {Svargrond}, {Yalahar} or {Edron?}"}) +keywordHandler:addKeyword({'town'}, StdModule.say, {npcHandler = npcHandler, text = "Where do you want to go? To {Thais}, {Ab\'Dendriel}, {Venore}, {Svargrond}, {Yalahar} or {Edron?}"}) +keywordHandler:addKeyword({'destination'}, StdModule.say, {npcHandler = npcHandler, text = "Where do you want to go? To {Thais}, {Ab\'Dendriel}, {Venore}, {Svargrond}, {Yalahar} or {Edron?}"}) +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = "Where do you want to go? To {Thais}, {Ab\'Dendriel}, {Venore}, {Svargrond}, {Yalahar} or {Edron?}"}) +keywordHandler:addKeyword({'go'}, StdModule.say, {npcHandler = npcHandler, text = "Where do you want to go? To {Thais}, {Ab\'Dendriel}, {Venore}, {Svargrond}, {Yalahar} or {Edron?}"}) +keywordHandler:addKeyword({'ice'}, StdModule.say, {npcHandler = npcHandler, text = "I'm sorry, but we don't serve the routes to the Ice Islands."}) +keywordHandler:addKeyword({'senja'}, StdModule.say, {npcHandler = npcHandler, text = "I'm sorry, but we don't serve the routes to the Ice Islands."}) +keywordHandler:addKeyword({'folda'}, StdModule.say, {npcHandler = npcHandler, text = "I'm sorry, but we don't serve the routes to the Ice Islands."}) +keywordHandler:addKeyword({'vega'}, StdModule.say, {npcHandler = npcHandler, text = "I'm sorry, but we don't serve the routes to the Ice Islands."}) +keywordHandler:addKeyword({'darashia'}, StdModule.say, {npcHandler = npcHandler, text = "I'm not sailing there. This route is afflicted by a ghost ship! However I've heard that Captain Fearless from Venore sails there."}) +keywordHandler:addKeyword({'darama'}, StdModule.say, {npcHandler = npcHandler, text = "I'm not sailing there. This route is afflicted by a ghost ship! However I've heard that Captain Fearless from Venore sails there."}) +keywordHandler:addKeyword({'ghost'}, StdModule.say, {npcHandler = npcHandler, text = "Many people who sailed to Darashia never returned because they were attacked by a ghostship! I'll never sail there!"}) +keywordHandler:addKeyword({'carlin'}, StdModule.say, {npcHandler = npcHandler, text = "This is Carlin. Where do you want to go?"}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome on board, |PLAYERNAME|. Where can I {sail} you today?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye. Recommend us if you were satisfied with our service.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye then.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/captain_gulliver.lua b/data/npc/scripts/captain_gulliver.lua new file mode 100644 index 00000000000..5e2b7c16121 --- /dev/null +++ b/data/npc/scripts/captain_gulliver.lua @@ -0,0 +1,58 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Passages to Thais and Krailos! Visit the strange lands!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, cost, destination, action) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, discount = 'postman', destination = destination}, nil, action) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('thais', 150, Position(32311, 32210, 6)) +addTravelKeyword('krailos', 180, Position(33493, 31712, 6)) +addTravelKeyword('travora', 1000, Position(32055, 32368, 6)) +addTravelKeyword('issavi', 130, Position(33902, 31462, 6)) + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, destination = {Position(33487, 31986, 7), Position(33486, 31984, 7)}}) + +-- Basic +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you may not have heard of me. I am Captain Gulliver, the first Oramondian for a hundred years to have sailed through the mist to your strange lands.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of the \'Sea Goddess\', the splendid and beautiful ship you see over there.'}) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of the \'Sea Goddess\', the splendid and beautiful ship you see over there.'}) +keywordHandler:addKeyword({'ship'}, StdModule.say, {npcHandler = npcHandler, text = 'The \'Sea Goddess\' is the most beautiful in Oramond, a whole new model of ship, elegant, sure and swift. There\'s no weather she can\'t take!'}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, your lands are quite a sight! I have only visited Thais so far, but I think of navigating to more cities, when the time - and public demand - comes.'}) +keywordHandler:addKeyword({'good'}, StdModule.say, {npcHandler = npcHandler, text = 'I will gladly take on board everything you wish to transport. No pets, though.'}) +keywordHandler:addKeyword({'passenger'}, StdModule.say, {npcHandler = npcHandler, text = ' I would be delighted to have you on board.'}) + +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = 'You would like to book a passage for {Thais} or {Krailos}?'}) +keywordHandler:addKeyword({'route'}, StdModule.say, {npcHandler = npcHandler, text = 'You would like to book a passage for {Thais} or {Krailos}?'}) +keywordHandler:addKeyword({'trip'}, StdModule.say, {npcHandler = npcHandler, text = 'You would like to book a passage for {Thais} or {Krailos}?'}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'You would like to book a passage for {Thais} or {Krailos}?'}) +keywordHandler:addKeyword({'town'}, StdModule.say, {npcHandler = npcHandler, text = 'You would like to book a passage for {Thais} or {Krailos}?'}) +keywordHandler:addKeyword({'destination'}, StdModule.say, {npcHandler = npcHandler, text = 'You would like to book a passage for {Thais} or {Krailos}?'}) +keywordHandler:addKeyword({'go'}, StdModule.say, {npcHandler = npcHandler, text = 'You would like to book a passage for {Thais} or {Krailos}?'}) + +keywordHandler:addKeyword({'oramond'}, StdModule.say, {npcHandler = npcHandler, text = 'This is the only safe landing place on Oramond. The cliffs surrounding the isle are too dangerous, you see.'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome on board, Sir |PLAYERNAME|. Where can I {sail} you today?') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye. Recommend us if you were satisfied with our service.') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/captain_haba.lua b/data/npc/scripts/captain_haba.lua new file mode 100644 index 00000000000..965caedaa02 --- /dev/null +++ b/data/npc/scripts/captain_haba.lua @@ -0,0 +1,82 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.TheHuntForTheSeaSerpent.CaptainHaba) <= 1 then + npcHandler:say("Ya wanna join the hunt fo' the sea serpent? Be warned ya may pay with ya life! Are ya in to it?", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("A'right, we are here to resupply our stock of baits to catch the sea serpent. Your first task is to bring me 5 fish they are easy to catch. When you got them ask me for the bait again.", cid) + player:setStorageValue(Storage.TheHuntForTheSeaSerpent.CaptainHaba, 2) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 7 then + npcHandler:say("Let's go fo' a hunt and bring the beast down!", cid) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(Position(31947, 31045, 6), false) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 8 + end + elseif msgcontains(msg, "bait") then + if player:getStorageValue(Storage.TheHuntForTheSeaSerpent.CaptainHaba) == 2 then + if player:removeItem(2667, 5) then + npcHandler:say("Excellent, now bring me 5 northern pike.", cid) + player:setStorageValue(Storage.TheHuntForTheSeaSerpent.CaptainHaba, 3) + npcHandler.topic[cid] = 3 + end + elseif player:getStorageValue(Storage.TheHuntForTheSeaSerpent.CaptainHaba) == 3 then + if player:removeItem(2669, 5) then + npcHandler:say("Excellent, now bring me 5 green perch.", cid) + player:setStorageValue(Storage.TheHuntForTheSeaSerpent.CaptainHaba, 4) + npcHandler.topic[cid] = 4 + end + elseif player:getStorageValue(Storage.TheHuntForTheSeaSerpent.CaptainHaba) == 4 then + if player:removeItem(7159, 5) then + npcHandler:say("Excellent, now bring me 5 rainbow trout.", cid) + player:setStorageValue(Storage.TheHuntForTheSeaSerpent.CaptainHaba, 5) + npcHandler.topic[cid] = 5 + end + elseif player:getStorageValue(Storage.TheHuntForTheSeaSerpent.CaptainHaba) == 5 then + if player:removeItem(7158, 5) then + npcHandler:say("Excellent, that should be enough fish to make the bait. Tell me when ya're ready fo' the hunt.", cid) + player:setStorageValue(Storage.TheHuntForTheSeaSerpent.CaptainHaba, 6) + npcHandler.topic[cid] = 6 + end + end + elseif msgcontains(msg, "hunt") then + if player:getStorageValue(Storage.TheHuntForTheSeaSerpent.CaptainHaba) == 6 then + npcHandler:say("A'right, wanna put out to sea?", cid) + npcHandler.topic[cid] = 7 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:setMessage(MESSAGE_GREET, "Harrr, landlubber wha'd ya want?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Bye.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/captain_haba_open_sea.lua b/data/npc/scripts/captain_haba_open_sea.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/captain_haba_open_sea.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/captain_harava.lua b/data/npc/scripts/captain_harava.lua new file mode 100644 index 00000000000..442a3933b9e --- /dev/null +++ b/data/npc/scripts/captain_harava.lua @@ -0,0 +1,53 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Come on board! The winds are prosperous!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, cost, destination, action, condition) + if condition then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sorry but I don\'t sail there.'}, condition) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, discount = 'postman', destination = destination}, nil, action) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('darashia', 80, Position(33289, 32481, 6)) +addTravelKeyword('venore', 80, Position(32954, 32022, 6)) +addTravelKeyword('oramond', 100, Position(33479, 31985, 7)) +addTravelKeyword('krailos', 80, Position(33492, 31712, 6)) + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, destination = {Position(33897, 31471, 6), Position(33901, 31471, 6)}}) + +-- Basic +keywordHandler:addKeyword({'trip'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m ready to bring you to {Oramond}, {Krailos}, {Venore} or {Darashia}.'}) +keywordHandler:addKeyword({'route'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m ready to bring you to {Oramond}, {Krailos}, {Venore} or {Darashia}.'}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m ready to bring you to {Oramond}, {Krailos}, {Venore} or {Darashia}.'}) +keywordHandler:addKeyword({'town'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m ready to bring you to {Oramond}, {Krailos}, {Venore} or {Darashia}.'}) +keywordHandler:addKeyword({'destination'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m ready to bring you to {Oramond}, {Krailos}, {Venore} or {Darashia}.'}) +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m ready to bring you to {Oramond}, {Krailos}, {Venore} or {Darashia}.'}) +keywordHandler:addKeyword({'go'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m ready to bring you to {Oramond}, {Krailos}, {Venore} or {Darashia}.'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome on board, traveller. Where can I {sail} you today?') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye. Recommend us if you were satisfied with our service.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye then.') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/captain_jack.lua b/data/npc/scripts/captain_jack.lua new file mode 100644 index 00000000000..104ad379c1a --- /dev/null +++ b/data/npc/scripts/captain_jack.lua @@ -0,0 +1,25 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local travelNode = keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage back to Tibia?'}) + travelNode:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, level = 0, cost = 0, destination = Position(32204, 31756, 6) }) + travelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, reset = true, text = 'We would like to serve you some time.'}) + + keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'I can travel you to {Tibia}.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I can travel you to {Tibia}.'}) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/captain_kurt.lua b/data/npc/scripts/captain_kurt.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/captain_kurt.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/captain_max.lua b/data/npc/scripts/captain_max.lua new file mode 100644 index 00000000000..8599a7b4e3a --- /dev/null +++ b/data/npc/scripts/captain_max.lua @@ -0,0 +1,49 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Whoah. That was a large shadow passing by.'} } +npcHandler:addModule(VoiceModule:new(voices)) + + + +local function addTravelKeyword(keyword, text, cost, destination) + if keyword == 'calassa' then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sorry but we don\'t serve this route.'}, function(player) return player:getStorageValue(Storage.ExplorerSociety.CalassaQuest) < 1 end) + end + + if keyword == 'yalahar' then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sorry but we don\'t serve this route.'}, function(player) return player:getStorageValue(Storage.TheWayToYalahar.QuestLine) < 1 end) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = text, cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, text = 'Hold on!', cost = cost, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'You shouldn\'t miss the experience.', reset = true}) + +end + +addTravelKeyword('calassa', 'Should I bring you to Calassa for 200 gold?', 200, Position(31911, 32710, 6)) +addTravelKeyword('yalahar', 'That is quite a long unprofitable travel. I\'ll bring you to Yalahar for 400 gold though. Is that ok with you?', 400, Position(32816, 31272, 6)) + +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = 'Welcome on board, noble |PLAYERNAME|. I can bring you to {Calassa} or {Yalahar}, but only if you have the according mission from {Berenice} or {Wyrdin}.'}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Welcome on board, noble |PLAYERNAME|. I can bring you to {Calassa} or {Yalahar}, but only if you have the according mission from {Berenice} or {Wyrdin}.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Ahoy, |PLAYERNAME|. On a mission for the explorer society, eh?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/captain_max_calassa.lua b/data/npc/scripts/captain_max_calassa.lua new file mode 100644 index 00000000000..11ec2e61da2 --- /dev/null +++ b/data/npc/scripts/captain_max_calassa.lua @@ -0,0 +1,33 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Whoah. That was a large shadow passing by.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local travelNode = keywordHandler:addKeyword({'liberty bay'}, StdModule.say, {npcHandler = npcHandler, text = 'Do you want go back to Liberty Bay?'}) + travelNode:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, level = 0, cost = 0, destination = Position(32298, 32895, 6) }) + travelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, reset = true, text = 'Maybe another time, then.'}) + +keywordHandler:addKeyword({'back'}, StdModule.say, {npcHandler = npcHandler, text = 'Do you want go back to {Liberty Bay}?'}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Welcome on board, noble |PLAYERNAME|. I can bring you back to {Liberty Bay}. Do you want me to do it?'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Ahoy, |PLAYERNAME|. On a mission for the explorer society, eh?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/captain_pelagia.lua b/data/npc/scripts/captain_pelagia.lua new file mode 100644 index 00000000000..cf206c06dfd --- /dev/null +++ b/data/npc/scripts/captain_pelagia.lua @@ -0,0 +1,58 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) + +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Passages to Edron, Darashia, Oramond, Thais and Venore.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, cost, destination) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('venore', 120, Position(32954, 32022, 6)) -- {x = 32954, y = 32022, z = 6} +addTravelKeyword('edron', 110, Position(33176, 31765, 6)) -- {x = 33176, y = 31765, z = 6} +addTravelKeyword('oramond', 70, Position(33479, 31985, 7)) -- {x = 33479, y = 31985, z = 7} +addTravelKeyword('darashia', 120, Position(33289, 32481, 6)) -- {x = 33289, y = 32481, z = 6} +addTravelKeyword('thais', 130, Position(32310, 32210, 6)) -- +addTravelKeyword('issavi', 130, Position(33902, 31464, 6)) + +-- Darashia +local travelNode = keywordHandler:addKeyword({'darashia'}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to Darashia for |TRAVELCOST|?', cost = 0, discount = 'postman'}) + local childTravelNode = travelNode:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'I warn you! This route is haunted by a ghostship. Do you really want to go there?'}) + childTravelNode:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = 0, discount = 'postman', destination = function(player) return math.random(10) == 1 and Position(33324, 32173, 6) or Position(33289, 32481, 6) end}) + childTravelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, reset = true, text = 'We would like to serve you some time.'}) + travelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, reset = true, text = 'We would like to serve you some time.'}) + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, destination = {Position(33498, 31711, 6)}}) + +-- Basic +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Edron}, {Darashia}, {Oramond} or {Venore}?'}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Edron}, {Darashia}, {Oramond} or {Venore}?'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) +keywordHandler:addKeyword({'venore'}, StdModule.say, {npcHandler = npcHandler, text = 'This is Venore. Where do you want to go?'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Captain Pelagia from the Royal Tibia Line.'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome on board, |PLAYERNAME|. Where can I {sail} you today?') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye. Recommend us if you were satisfied with our service.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye then.') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/captain_seagull.lua b/data/npc/scripts/captain_seagull.lua new file mode 100644 index 00000000000..94a6f7c8d23 --- /dev/null +++ b/data/npc/scripts/captain_seagull.lua @@ -0,0 +1,71 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Travel +local function addTravelKeyword(keyword, cost, destination, condition) + if condition then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sorry but I don\'t sail there.'}, condition) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('thais', 130, Position(32310, 32210, 6)) +addTravelKeyword('carlin', 80, Position(32387, 31820, 6)) +addTravelKeyword('gray island', 150, Position(33196, 31984, 7)) +addTravelKeyword('edron', 70, Position(33175, 31764, 6)) +addTravelKeyword('venore', 90, Position(32954, 32022, 6)) +addTravelKeyword('yalahar', 160, Position(32816, 31272, 6), function(player) return player:getStorageValue(Storage.SearoutesAroundYalahar.AbDendriel) ~= 1 and player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) < 5 end) + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, destination = {Position(32724, 31669, 6), Position(32726, 31665, 6)}}) + +-- Basic +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "My name is Captain Seagull from the Royal Tibia Line."}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am the captain of this sailing-ship."}) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = "I am the captain of this sailing-ship."}) +keywordHandler:addKeyword({'ship'}, StdModule.say, {npcHandler = npcHandler, text = "The Royal Tibia Line connects all seaside towns of Tibia."}) +keywordHandler:addKeyword({'line'}, StdModule.say, {npcHandler = npcHandler, text = "The Royal Tibia Line connects all seaside towns of Tibia."}) +keywordHandler:addKeyword({'company'}, StdModule.say, {npcHandler = npcHandler, text = "The Royal Tibia Line connects all seaside towns of Tibia."}) +keywordHandler:addKeyword({'route'}, StdModule.say, {npcHandler = npcHandler, text = "The Royal Tibia Line connects all seaside towns of Tibia."}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = "The Royal Tibia Line connects all seaside towns of Tibia."}) +keywordHandler:addKeyword({'good'}, StdModule.say, {npcHandler = npcHandler, text = "We can transport everything you want."}) +keywordHandler:addKeyword({'passanger'}, StdModule.say, {npcHandler = npcHandler, text = "We would like to welcome you on board."}) +keywordHandler:addKeyword({'trip'}, StdModule.say, {npcHandler = npcHandler, text = "Where do you want to go? To {Thais}, {Carlin}, {Venore}, {Yalahar}, {Edron} or {Gray Island}?"}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = "WWhere do you want to go? To {Thais}, {Carlin}, {Venore}, {Yalahar}, {Edron} or {Gray Island}?"}) +keywordHandler:addKeyword({'town'}, StdModule.say, {npcHandler = npcHandler, text = "Where do you want to go? To {Thais}, {Carlin}, {Venore}, {Yalahar}, {Edron} or {Gray Island}?"}) +keywordHandler:addKeyword({'destination'}, StdModule.say, {npcHandler = npcHandler, text = "Where do you want to go? To {Thais}, {Carlin}, {Venore}, {Yalahar}, {Edron} or {Gray Island}?"}) +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = "Where do you want to go? To {Thais}, {Carlin}, {Venore}, {Yalahar}, {Edron} or {Gray Island}?"}) +keywordHandler:addKeyword({'go'}, StdModule.say, {npcHandler = npcHandler, text = "Where do you want to go? To {Thais}, {Carlin}, {Venore}, {Yalahar}, {Edron} or {Gray Island}?"}) +keywordHandler:addKeyword({'ice'}, StdModule.say, {npcHandler = npcHandler, text = "I'm sorry, but we don't serve the routes to the Ice Islands."}) +keywordHandler:addKeyword({'senja'}, StdModule.say, {npcHandler = npcHandler, text = "I'm sorry, but we don't serve the routes to the Ice Islands."}) +keywordHandler:addKeyword({'folda'}, StdModule.say, {npcHandler = npcHandler, text = "I'm sorry, but we don't serve the routes to the Ice Islands."}) +keywordHandler:addKeyword({'vega'}, StdModule.say, {npcHandler = npcHandler, text = "I'm sorry, but we don't serve the routes to the Ice Islands."}) +keywordHandler:addKeyword({'ankrahmun'}, StdModule.say, {npcHandler = npcHandler, text = "I'm sorry, but we don't serve this route."}) +keywordHandler:addKeyword({'tiquanda'}, StdModule.say, {npcHandler = npcHandler, text = "I'm sorry, but we don't serve this route."}) +keywordHandler:addKeyword({'port hope'}, StdModule.say, {npcHandler = npcHandler, text = "I'm sorry, but we don't serve this route."}) +keywordHandler:addKeyword({'darashia'}, StdModule.say, {npcHandler = npcHandler, text = "I'm not sailing there. This route is afflicted by a ghost ship! However I've heard that Captain Fearless from Venore sails there."}) +keywordHandler:addKeyword({'darama'}, StdModule.say, {npcHandler = npcHandler, text = "I'm not sailing there. This route is afflicted by a ghost ship! However I've heard that Captain Fearless from Venore sails there."}) +keywordHandler:addKeyword({'ghost'}, StdModule.say, {npcHandler = npcHandler, text = "Many people who sailed to Darashia never returned because they were attacked by a ghostship! I'll never sail there!"}) +keywordHandler:addKeyword({'ab\'dendriel'}, StdModule.say, {npcHandler = npcHandler, text = "This is Ab\'Dendriel. Where do you want to go?"}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome on board, |PLAYERNAME|. Where can I {sail} you today?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye. Recommend us if you were satisfied with our service.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/captain_seahorse.lua b/data/npc/scripts/captain_seahorse.lua new file mode 100644 index 00000000000..602a5ab8c43 --- /dev/null +++ b/data/npc/scripts/captain_seahorse.lua @@ -0,0 +1,56 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Travel +local function addTravelKeyword(keyword, cost, destination, action) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a seek a passage to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, discount = 'postman', destination = destination}, nil, action) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('venore', 40, Position(32954, 32022, 6), +function(player) + if player:getStorageValue(Storage.Postman.Mission01) == 3 then + player:setStorageValue(Storage.Postman.Mission01, 4) + end +end) +addTravelKeyword('thais', 160, Position(32310, 32210, 6)) +addTravelKeyword('carlin', 110, Position(32387, 31820, 6)) +addTravelKeyword('krailos', 185, Position(33493, 31712, 6)) +addTravelKeyword('ab\'dendriel', 70, Position(32734, 31668, 6)) +addTravelKeyword('gray island', 190, Position(33196, 31984, 7)) +addTravelKeyword('port hope', 150, Position(32527, 32784, 6)) +addTravelKeyword('liberty bay', 170, Position(32285, 32892, 6)) +addTravelKeyword('ankrahmun', 160, Position(33092, 32883, 6)) +addTravelKeyword('cormaya', 20, Position(33288, 31956, 6)) +addTravelKeyword('oramond', 200, Position(33479, 31985, 7)) + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, destination = {Position(33174, 31773, 6), Position(33175, 31771, 6), Position(33177, 31772, 6)}}) + +-- Basic +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Krailos}, {Thais}, {Carlin}, {Ab\'Dendriel}, {Venore}, {Port Hope}, {Ankrahmun}, {Liberty Bay}, {Gray Island} or the isle {Cormaya}?'}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Krailos}, {Thais}, {Carlin}, {Ab\'Dendriel}, {Venore}, {Port Hope}, {Ankrahmun}, {Liberty Bay}, {Gray Island} or the isle {Cormaya}?'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Captain Seahorse from the Royal Tibia Line.'}) +keywordHandler:addKeyword({'edron'}, StdModule.say, {npcHandler = npcHandler, text = 'This is Edron. Where do you want to go?'}) +keywordHandler:addKeyword({'yalahar'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sorry, but we don\'t serve this route. However, I heard that Wyrdin here in Edron is looking for adventurers to go on a trip to Yalahar for him.'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome on board, |PLAYERNAME|. Where may I {sail} you today?') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye. Recommend us if you were satisfied with our service.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye then.') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/captain_sinbeard.lua b/data/npc/scripts/captain_sinbeard.lua new file mode 100644 index 00000000000..7fd60b6ba06 --- /dev/null +++ b/data/npc/scripts/captain_sinbeard.lua @@ -0,0 +1,64 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Travel +local function addTravelKeyword(keyword, cost, destination, condition) + if condition then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sorry but I don\'t sail there.'}, condition) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('edron', 160, Position(33175, 31764, 6)) +addTravelKeyword('venore', 150, Position(32954, 32022, 6)) +addTravelKeyword('port hope', 80, Position(32527, 32784, 6)) +addTravelKeyword('liberty bay', 90, Position(32285, 32892, 6)) +addTravelKeyword('darashia', 100, Position(33289, 32480, 6)) +addTravelKeyword('yalahar', 230, Position(32816, 31272, 6), function(player) return player:getStorageValue(Storage.SearoutesAroundYalahar.Ankrahmun) ~= 1 and player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) < 5 end) + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, destination = {Position(33082, 32879, 6), Position(33085, 32879, 6), Position(33085, 32881, 6)}}) + +-- Basic +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "I'm known all over the world as Captain Sinbeard"}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I'm the captain of this sailing ship"}) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = "I'm the captain of this sailing ship"}) +keywordHandler:addKeyword({'ship'}, StdModule.say, {npcHandler = npcHandler, text = "My ship is the fastest in the whole world."}) +keywordHandler:addKeyword({'line'}, StdModule.say, {npcHandler = npcHandler, text = "My ship is the fastest in the whole world."}) +keywordHandler:addKeyword({'company'}, StdModule.say, {npcHandler = npcHandler, text = "My ship is the fastest in the whole world."}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = "My ship is the fastest in the whole world."}) +keywordHandler:addKeyword({'god'}, StdModule.say, {npcHandler = npcHandler, text = "Where do you want to go? To {Darashia}, {Venore}, {Liberty Bay}, {Port Hope}, {Yalahar} or {Edron}? Or to {Travora} - the island between the worlds?"}) +keywordHandler:addKeyword({'passanger'}, StdModule.say, {npcHandler = npcHandler, text = "We would like to welcome you on board."}) +keywordHandler:addKeyword({'trip'}, StdModule.say, {npcHandler = npcHandler, text = "Where do you want to go? To {Darashia}, {Venore}, {Liberty Bay}, {Port Hope}, {Yalahar} or {Edron}? Or to {Travora} - the island between the worlds?"}) +keywordHandler:addKeyword({'route'}, StdModule.say, {npcHandler = npcHandler, text = "Where do you want to go? To {Darashia}, {Venore}, {Liberty Bay}, {Port Hope}, {Yalahar} or {Edron}? Or to {Travora} - the island between the worlds?"}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = "Where do you want to go? To {Darashia}, {Venore}, {Liberty Bay}, {Port Hope}, {Yalahar} or {Edron}? Or to {Travora} - the island between the worlds?"}) +keywordHandler:addKeyword({'town'}, StdModule.say, {npcHandler = npcHandler, text = "Where do you want to go? To {Darashia}, {Venore}, {Liberty Bay}, {Port Hope}, {Yalahar} or {Edron}? Or to {Travora} - the island between the worlds?"}) +keywordHandler:addKeyword({'destination'}, StdModule.say, {npcHandler = npcHandler, text = "Where do you want to go? To {Darashia}, {Venore}, {Liberty Bay}, {Port Hope}, {Yalahar} or {Edron}? Or to {Travora} - the island between the worlds?"}) +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = "Where do you want to go? To {Darashia}, {Venore}, {Liberty Bay}, {Port Hope}, {Yalahar} or {Edron}? Or to {Travora} - the island between the worlds?"}) +keywordHandler:addKeyword({'go'}, StdModule.say, {npcHandler = npcHandler, text = "Where do you want to go? To {Darashia}, {Venore}, {Liberty Bay}, {Port Hope}, {Yalahar} or {Edron}? Or to {Travora} - the island between the worlds?"}) +keywordHandler:addKeyword({'thais'}, StdModule.say, {npcHandler = npcHandler, text = "I'm sorry but I don't sail there."}) +keywordHandler:addKeyword({'carlin'}, StdModule.say, {npcHandler = npcHandler, text = "I'm sorry but I don't sail there."}) +keywordHandler:addKeyword({'ab\'dendriel'}, StdModule.say, {npcHandler = npcHandler, text = "I'm sorry but I don't sail there."}) +keywordHandler:addKeyword({'ankrahmun'}, StdModule.say, {npcHandler = npcHandler, text = "That's where we are."}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome on board, Sir |PLAYERNAME|. Where can I {sail} you today?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye. Recommend us if you were satisfied with our service.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye then.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/captain_tiberius.lua b/data/npc/scripts/captain_tiberius.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/captain_tiberius.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/captain_waverider.lua b/data/npc/scripts/captain_waverider.lua new file mode 100644 index 00000000000..0448335d7a3 --- /dev/null +++ b/data/npc/scripts/captain_waverider.lua @@ -0,0 +1,69 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function creatureSayCallback(cid, type, msg) + if(not npcHandler:isFocused(cid)) then + return false + end + + local player = Player(cid) + + if(msgcontains(msg, "peg leg")) then + if player:getStorageValue(Storage.TheShatteredIsles.AccessToMeriana) == 1 then + npcHandler:say("Ohhhh. So... you know who sent you so I sail you to you know where. It will cost 50 gold to cover my expenses. Is it that what you wish?", cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say("Sorry, my old ears can't hear you.", cid) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "passage")) then + npcHandler:say(" I knew someone else would claim all the treasure someday. But at least it will be you and not some greedy and selfish person. For a small fee of 200 gold pieces I will sail you to your rendezvous with fate. Do we have a deal?", cid) + npcHandler.topic[cid] = 2 + elseif(msgcontains(msg, "no")) then + npcHandler:say("I have to admit this leaves me a bit puzzled.", cid) + npcHandler.topic[cid] = 0 + elseif(msgcontains(msg, "yes")) then + if(npcHandler.topic[cid] == 1) then + if player:removeMoneyNpc(50) then + npcHandler:say("And there we go!", cid) + player:teleportTo(Position(32346, 32625, 7)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have enough money.", cid) + npcHandler.topic[cid] = 0 + end + elseif(npcHandler.topic[cid] == 2) then + if player:removeMoneyNpc(200) then + npcHandler:say("And there we go!", cid) + player:teleportTo(Position(32131, 32913, 7)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have enough money.", cid) + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Greetings, daring adventurer. If you need a {passage}, let me know.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Oh well.") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/captain_waverider_island.lua b/data/npc/scripts/captain_waverider_island.lua new file mode 100644 index 00000000000..8acac61f7f0 --- /dev/null +++ b/data/npc/scripts/captain_waverider_island.lua @@ -0,0 +1,29 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local travelNode = keywordHandler:addKeyword({'liberty bay'}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage back to Liberty Bay for |TRAVELCOST|?', cost = 0, discount = 'postman'}) + travelNode:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = 50, discount = 'postman', destination = Position(32349, 32856, 7) }) + travelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, reset = true, text = 'We would like to serve you some time.'}) + +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Liberty bay}?'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Greetings, daring adventurer. If you need a return {passage}, let me know.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Oh well.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/caramellia.lua b/data/npc/scripts/caramellia.lua new file mode 100644 index 00000000000..a169fcadbb0 --- /dev/null +++ b/data/npc/scripts/caramellia.lua @@ -0,0 +1,62 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Can I finally have some peace...?' }, + { text = 'Please leave me alone in my mourning.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +keywordHandler:addKeyword({'mourning'}, StdModule.say, {npcHandler = npcHandler, text = "All is lost. With {Winfred} dead, my love has died and I'm only an empty shell without hope or purpose."}) +keywordHandler:addKeyword({'port hope'}, StdModule.say, {npcHandler = npcHandler, text = "We put all our hope in this far away colony. Sadly, we never made it there and I will never know what our life would have been like in Port Hope."}) +keywordHandler:addKeyword({'druid'}, StdModule.say, {npcHandler = npcHandler, text = "I guess he was the one that put my father up to the whole thing. He spied on Winfred and me and it was certainly him that suggested my {imprisonment} in this tower."}) +keywordHandler:addKeyword({'imprisonment'}, StdModule.say, {npcHandler = npcHandler, text = "This forsaken place seems as remote from the rest of the world as my heart is."}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "Please leave me alone in my mourning."}) +keywordHandler:addKeyword({'thais'}, StdModule.say, {npcHandler = npcHandler, text = "The bustling streets of Thais are all but a faint memory to me."}) +keywordHandler:addKeyword({'carlin'}, StdModule.say, {npcHandler = npcHandler, text = "Carlin is a lovely and green city as far as I remember."}) +keywordHandler:addKeyword({'venore'}, StdModule.say, {npcHandler = npcHandler, text = "My father wanted me to marry a wealthy Venorean. He understood so little about love and the ways of the heart."}) +keywordHandler:addKeyword({'ab\'dendriel'}, StdModule.say, {npcHandler = npcHandler, text = "The city of the elves is an exotic wonder."}) +keywordHandler:addKeyword({'kazordoon'}, StdModule.say, {npcHandler = npcHandler, text = "The city is like the dwarfs that built it. Stony, never-changing and hard to understand for an outsider."}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + elseif msgcontains(msg, "winfred") then + npcHandler:say({ + 'He was my one and only true love. He was a mere commoner and so my {father} forbid me to see him ...', + 'We met anyway, we had plans to flee to {Port Hope} and to start a new life there ...', + 'A {druid}, in service of my father, had spied on us. So they brought me here and locked me into this {tower}. The druid cast a spell on the plants at the entrance which kept everyone from entering the tower ...', + 'I could see Winfred from the window but he could not come to me. One day he disappeared. I knew immediately that something horrible had happened to him.' + }, cid) + elseif msgcontains(msg, "father") then + npcHandler:say({ + 'He wasn\'t a bad man. He was only misguided by false friends who told him what society expected of him ...', + 'By trying to uphold a respectable image in society, he ruined not only my life but also his own.' + }, cid) + elseif msgcontains(msg, "tower") then + npcHandler:say({ + 'Once, this tower has been my prison but after the death of Winfred it has become my refuge from the rest of the world. ...', + 'I welcome the loneliness here because it mirrors the state of my heart.' + }, cid) + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Hello, |PLAYERNAME|. Please leave me alone in my {mourning}.") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/carina.lua b/data/npc/scripts/carina.lua new file mode 100644 index 00000000000..e1017509ef5 --- /dev/null +++ b/data/npc/scripts/carina.lua @@ -0,0 +1,62 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'precious necklace') then + if player:getItemCount(8768) > 0 then + npcHandler:say('Would you like to buy my precious necklace for 5000 gold?', cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, 'mouse') then + npcHandler:say('Wha ... What??? Are you saying you\'ve seen a mouse here??', cid) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + if player:removeMoneyNpc(5000) then + player:removeItem(8768, 1) + player:addItem(8767, 1) + npcHandler:say('Here you go kind sir.', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 2 then + if not player:removeItem(7487, 1) then + npcHandler:say('There is no mouse here! Stop talking foolish things about serious issues!', cid) + npcHandler.topic[cid] = 0 + return true + end + + player:setStorageValue(Storage.WhatAFoolish.ScaredCarina, 1) + npcHandler:say('IIIEEEEEK!', cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'no') then + if npcHandler.topic[cid] == 2 then + npcHandler:say('Thank goodness!', cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/carlos.lua b/data/npc/scripts/carlos.lua new file mode 100644 index 00000000000..837406e11bd --- /dev/null +++ b/data/npc/scripts/carlos.lua @@ -0,0 +1,206 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Hmm, we should do something about your outfit.' }, + { text = 'Ah, another adventurer. Let\'s talk a little.' }, + { text = 'Psst! Come over here for a little trade.' }, + { text = 'Hello, hello! Don\'t be shy, I don\'t bite.' }, + { text = 'By the way, if you want to look at old hints again, find the \'Help\' button near your inventory and select \'Tutorial Hints\'.' } +} +npcHandler:addModule(VoiceModule:new(voices)) + +local function setNewTradeTable(table) + local items, item = {} + for i = 1, #table do + item = table[i] + items[item.id] = {itemId = item.id, buyPrice = item.buy, sellPrice = item.sell, subType = 0, realName = item.name} + end + return items +end + +local function getTable() + local itemsList = { + {name="meat", id=2666, sell=2}, + {name="ham", id=2671, sell=2}, + } + return itemsList +end + +local storeTalkCid = {} +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.RookgaardTutorialIsland.CarlosNpcGreetStorage) < 1 then + npcHandler:setMessage(MESSAGE_GREET, "Be greeted, |PLAYERNAME|! As a tailor and merchant I have to say - we need to do something about your {outfit}, shall we?") + player:setStorageValue(Storage.RookgaardTutorialIsland.CarlosNpcGreetStorage, 1) + player:setStorageValue(Storage.RookgaardTutorialIsland.CarlosQuestLog, 1) + storeTalkCid[cid] = 1 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.CarlosNpcGreetStorage) == 1 then + npcHandler:setMessage(MESSAGE_GREET, "Hey, I thought you were going to run away, but luckily you came back. I'll show you how to change your {outfit}, okay?") + storeTalkCid[cid] = 1 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.CarlosNpcGreetStorage) == 2 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back! You know, after providing my little outfit service, I like to ask a little favour of you. Can you {help} me?") + storeTalkCid[cid] = 2 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.CarlosNpcGreetStorage) == 3 then + npcHandler:setMessage(MESSAGE_GREET, "Oh hey |PLAYERNAME|, you didn't answer my question yet - could you help me get some {food}? I'll even give you some gold for it.") + storeTalkCid[cid] = 3 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.CarlosNpcGreetStorage) == 4 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back |PLAYERNAME|, I hope you changed your mind and will bring me some {meat}? I'll even give you some gold for it.") + storeTalkCid[cid] = 4 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.CarlosNpcGreetStorage) == 5 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back, |PLAYERNAME|! Did you have a successful hunt and carry a piece of {meat} or ham with you?") + storeTalkCid[cid] = 5 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.CarlosNpcGreetStorage) == 6 then + if player:getItemCount(2666) > 0 or player:getItemCount(2671) > 0 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back, Isleth Eagonst! Do you still have that piece of meat or ham? If so, please ask me for a {trade} and I'll give you some gold for it.") + storeTalkCid[cid] = 6 + else + npcHandler:setMessage(MESSAGE_GREET, "Welcome back, |PLAYERNAME|! Where did you put that delicious piece of food? Did you eat it yourself? Well, if you find another one, please come back.") + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.CarlosNpcGreetStorage) == 7 then + npcHandler:setMessage(MESSAGE_GREET, "Hey there, |PLAYERNAME|! Well, that's how trading with NPCs like me works. I think you are ready now to cross the bridge to Rookgaard! Take care!") + player:setStorageValue(Storage.RookgaardTutorialIsland.CarlosQuestLog, 7) + player:setStorageValue(Storage.RookgaardTutorialIsland.CarlosNpcGreetStorage, 8) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.CarlosNpcGreetStorage) == 8 then + npcHandler:setMessage(MESSAGE_GREET, "Hello again, |PLAYERNAME|! What are you still doing here? You should head over the bridge to Rookgaard village now!") + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + return true +end + +local function releasePlayer(cid) + if not Player(cid) then + return + end + + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if isInArray({"yes", "help", "ok"}, msg) then + if storeTalkCid[cid] == 1 then + npcHandler:say("Very well. Just choose an outfit and a colour combination that suits you. You can open this dialogue anytime by right-clicking on yourself and selecting 'Set Outfit'. Just try it and then talk to me again!", cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.CarlosNpcGreetStorage, 2) + player:setStorageValue(Storage.RookgaardTutorialIsland.CarlosQuestLog, 2) + player:sendTutorial(12) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + elseif storeTalkCid[cid] == 2 then + npcHandler:say("You see, I'm quite hungry from standing here all day. Could you get me some {food}?", cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.CarlosNpcGreetStorage, 3) + player:setStorageValue(Storage.RookgaardTutorialIsland.CarlosQuestLog, 3) + storeTalkCid[cid] = 3 + elseif storeTalkCid[cid] == 3 then + npcHandler:say("Thank you! I would do it myself, but I don't have a weapon. Just kill a few rabbits or deer, loot food from them and bring me one piece of {meat} or ham, will you?", cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.CarlosNpcGreetStorage, 4) + player:setStorageValue(Storage.RookgaardTutorialIsland.CarlosQuestLog, 4) + storeTalkCid[cid] = 4 + elseif storeTalkCid[cid] == 4 then + npcHandler:say("Splendid. I'll be awaiting your return eagerly. Don't forget that you can click on the 'Chase Opponent' button to run after those fast creatures. Good {bye} for now!", cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.CarlosNpcGreetStorage, 5) + player:setStorageValue(Storage.RookgaardTutorialIsland.CarlosQuestLog, 5) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + elseif storeTalkCid[cid] == 5 then + if player:getItemCount(2666) > 0 or player:getItemCount(2671) > 0 then + npcHandler:say("What's that delicious smell? That must be a piece of meat! Please hurry, simply ask me for a {trade} and I'll give you two gold pieces for it!", cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.CarlosQuestLog, 6) + player:setStorageValue(Storage.RookgaardTutorialIsland.CarlosNpcGreetStorage, 6) + storeTalkCid[cid] = 6 + else + npcHandler:say("Hmm. No, I don't think you have something with you that I'd like to eat. Please come back once you looted a piece of meat or a piece of ham from a rabbit or deer.", cid) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + elseif storeTalkCid[cid] == 7 then + npcHandler:say({ + "Well, that's how trading with NPCs like me works. I think you are ready now to cross the bridge to Rookgaard, just follow the path to the northwest. Good luck, |PLAYERNAME|! ...", + "And by the way: if you thought all of this was boring and you'd rather skip the tutorial with your next character, just say 'skip tutorial' to Santiago. ...", + "Then you'll miss out on those nice items and experience though. Hehehe! It's your choice. Well, take care for now!" + }, cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.CarlosQuestLog, 7) + player:setStorageValue(Storage.RookgaardTutorialIsland.CarlosNpcGreetStorage, 8) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + elseif msgcontains(msg, "outfit") then + if storeTalkCid[cid] == 1 then + npcHandler:say({ + "Well, that's how trading with NPCs like me works. I think you are ready now to cross the bridge to Rookgaard, just follow the path to the northwest. Good luck, |PLAYERNAME|! ...", + "And by the way: if you thought all of this was boring and you'd rather skip the tutorial with your next character, just say 'skip tutorial' to Santiago. ...", + "Then you'll miss out on those nice items and experience though. Hehehe! It's your choice. Well, take care for now!" + }, cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.CarlosQuestLog, 7) + player:setStorageValue(Storage.RookgaardTutorialIsland.CarlosNpcGreetStorage, 8) + addEvent(releasePlayer, 1000, cid) + end + elseif msgcontains(msg, "trade") then + if storeTalkCid[cid] == 6 then + npcHandler:say("Very nice! Food for me! Sell it to me, fast! Once you sold your food to me, just say {ready} to let me know you are done.", cid) + player:sendTutorial(13) + player:setStorageValue(Storage.RookgaardTutorialIsland.CarlosNpcGreetStorage, 7) + storeTalkCid[cid] = 7 + local items = setNewTradeTable(getTable()) + local function onSell(cid, item, subType, amount, ignoreEquipped) + if items[item].sellPrice and player:removeItem(items[item].itemId, amount, -1, ignoreEquipped) then + player:addMoney(items[item].sellPrice * amount) + return player:sendTextMessage(MESSAGE_TRADE, 'You sold '..amount..'x '..items[item].realName..' for '..items[item].sellPrice * amount..' gold coins.') + else + selfSay("You don't have item to sell.", cid) + end + return true + end + openShopWindow(cid, getTable(), onBuy, onSell) + end + elseif msgcontains(msg, "ready") then + if storeTalkCid[cid] == 7 then + npcHandler:say({ + "Well, that's how trading with NPCs like me works. I think you are ready now to cross the bridge to Rookgaard, just follow the path to the northwest. Good luck, |PLAYERNAME|! ...", + "And by the way: if you thought all of this was boring and you'd rather skip the tutorial with your next character, just say 'skip tutorial' to Santiago. ...", + "Then you'll miss out on those nice items and experience though. Hehehe! It's your choice. Well, take care for now!" + }, cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.CarlosQuestLog, 7) + player:setStorageValue(Storage.RookgaardTutorialIsland.CarlosNpcGreetStorage, 8) + addEvent(releasePlayer, 5000, cid) + end + end + return true +end + +local function onReleaseFocus(cid) + storeTalkCid[cid] = nil +end + +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye |PLAYERNAME|!.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye traveller and enjoy your stay on Rookgaard.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/carlson.lua b/data/npc/scripts/carlson.lua new file mode 100644 index 00000000000..1878a364b8b --- /dev/null +++ b/data/npc/scripts/carlson.lua @@ -0,0 +1,32 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Travel +local function addTravelKeyword(keyword, text, cost, destination) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you want to sail ' .. text, cost = cost}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('tibia', 'back to Tibia?', 0, Position(32235, 31674, 7)) +addTravelKeyword('senja', 'Senja for |TRAVELCOST|?', 20, Position(32128, 31664, 7)) +addTravelKeyword('folda', 'Folda for |TRAVELCOST|?', 20, Position(32046, 31578, 7)) + +-- Basic +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Folda}, {Senja} or {Tibia}?'}) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/cedrik.lua b/data/npc/scripts/cedrik.lua new file mode 100644 index 00000000000..98d74790c50 --- /dev/null +++ b/data/npc/scripts/cedrik.lua @@ -0,0 +1,95 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Twist of Fate +local blessKeyword = keywordHandler:addKeyword({'twist of fate'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'This is a special blessing I can bestow upon you once you have obtained at least one of the other blessings and which functions a bit differently. ...', + 'It only works when you\'re killed by other adventurers, which means that at least half of the damage leading to your death was caused by others, not by monsters or the environment. ...', + 'The {twist of fate} will not reduce the death penalty like the other blessings, but instead prevent you from losing your other blessings as well as the amulet of loss, should you wear one. It costs the same as the other blessings. ...', + 'Would you like to receive that protection for a sacrifice of |PVPBLESSCOST| gold, child?' + }}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the protection of the twist of fate, pilgrim.', cost = '|PVPBLESSCOST|', bless = 1}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Adventurer Stone +keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Keep your adventurer\'s stone well.'}, function(player) return player:getItemById(18559, true) end) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for free?'}, function(player) return player:getStorageValue(Storage.AdventurersGuild.FreeStone.Alia) ~= 1 end) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, nil, function(player) player:addItem(18559, 1) player:setStorageValue(Storage.AdventurersGuild.FreeStone.Alia, 1) end) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for 30 gold?'}) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, + function(player) return player:getMoney() + player:getBankBalance() >= 30 end, + function(player) if player:removeMoneyNpc(30) then player:addItem(18559, 1) end end + ) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, you don\'t have enough money.', reset = true}) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.'}, function(player) return player:hasBlessing(2) end) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin will provide you with the embrace of Tibia.'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, young |PLAYERNAME|! If you are heavily wounded or poisoned, I can {heal} you for free.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Remember: If you are heavily wounded or poisoned, I can heal you for free.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'May the gods bless you, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ceiron.lua b/data/npc/scripts/ceiron.lua new file mode 100644 index 00000000000..4dd61fe01f8 --- /dev/null +++ b/data/npc/scripts/ceiron.lua @@ -0,0 +1,165 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if isInArray({"addon", "outfit"}, msg) then + if player:getStorageValue(Storage.OutfitQuest.DruidHatAddon) < 1 then + npcHandler:say("What are you thinking! I would never allow you to slay my beloved friends for the sake of your narcism. Only {Faolan} can grant you a fur like this one.", cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, "faolan") then + if npcHandler.topic[cid] == 2 then + npcHandler:say("I know where the great wolf mother lives, but I will not tell that to just anyone. You have to earn my respect first. Are you willing to help me?", cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.OutfitQuest.DruidHatAddon) == 8 then + npcHandler:say("Right, I will keep my promise. Faolan roams Tibia freely, but her favourite sleeping cave is on Cormaya. I will now enchant you so you will be able to speak the wolf language.", cid) + player:setStorageValue(Storage.OutfitQuest.DruidHatAddon, 9) + npcHandler.topic[cid] = 0 + end + elseif isInArray({"griffinclaw", "container"}, msg) then + if player:getStorageValue(Storage.OutfitQuest.DruidHatAddon) == 1 then + npcHandler:say("Were you able to obtain a sample of the Griffinclaw?", cid) + npcHandler.topic[cid] = 5 + end + elseif msgcontains(msg, "task") then + if player:getStorageValue(Storage.OutfitQuest.DruidHatAddon) == 2 then + npcHandler:say({ + "Listen, my next task for you is not exactly easy either. ...", + "In the mountains between Ankrahmun and Tiquanda are two hydra lairs. The nothern one has many waterfalls whereas the southern one has just tiny water trickles. ...", + "However, these trickles are said to contain water as pure and clean as nowhere else in Tibia. ...", + "If you could reach one of these trickles and retrieve a water sample for me, it would be a great help. ...", + "It is important that you take the water directly from the trickle, not from the pond - else it will not be as pure anymore. ...", + "Have you understood everything I told you and will fulfil this task for me?" + }, cid) + npcHandler.topic[cid] = 6 + elseif player:getStorageValue(Storage.OutfitQuest.DruidHatAddon) == 4 then + npcHandler:say({ + "I'm glad that you are still with me, |PLAYERNAME|. Especially because my next task might require even more patience from your side than the ones before. ...", + "Demons... these unholy creatures should have never been able to walk the earth. They are a brood fueled only by hatred and malice. ...", + "Even if slain, their evil spirit is not fully killed. It needs a blessed stake to release their last bit of fiendishness and turn them into dust. ...", + "It does not work all the time, but if you succeed, their vicious spirit is finally defeated. ...", + "I want proof that you are on the right side, against Zathroth. Bring me 100 ounces of demon dust and I shall be convinced. ...", + "You will probably need to ask a priest for help to obtain a blessed stake. ...", + "Have you understood everything I told you and will fulfil this task for me?" + }, cid) + npcHandler.topic[cid] = 8 + elseif player:getStorageValue(Storage.OutfitQuest.DruidHatAddon) == 6 then + npcHandler:say({ + "I have one final task for you, |PLAYERNAME|. Many months ago, I was trying to free the war wolves which are imprisoned inside the orc fortress.", + "Unfortunately, my intrusion was discovered and I had to run for my life. During my escape, I lost my favourite wolf tooth chain.", + "It should still be somewhere in the fortress, if the orcs did not try to eat it. I really wish you could retrieve it for me.", + "It has the letter 'C' carved into one of the teeth. Please look for it.", + "Have you understood everything I told you and will fulfil this task for me?" + }, cid) + npcHandler.topic[cid] = 10 + end + elseif msgcontains(msg, "waterskin") or msgcontains(msg, "water skin") then + if player:getStorageValue(Storage.OutfitQuest.DruidHatAddon) == 3 then + npcHandler:say("Did you bring me a sample of water from the hydra cave?", cid) + npcHandler.topic[cid] = 7 + end + elseif msgcontains(msg, "dust") or msgcontains(msg, "demon dust") then + if player:getStorageValue(Storage.OutfitQuest.DruidHatAddon) == 5 then + npcHandler:say("Were you really able to collect 100 ounces of demon dust?", cid) + npcHandler.topic[cid] = 9 + end + elseif msgcontains(msg, "chain") or msgcontains(msg, "wolf tooth chain") then + if player:getStorageValue(Storage.OutfitQuest.DruidHatAddon) == 7 then + npcHandler:say("Have you really found my wolf tooth chain??", cid) + npcHandler.topic[cid] = 11 + end + elseif msgcontains(msg, "ceiron's waterskin") then + if player:getStorageValue(Storage.OutfitQuest.DruidHatAddon) == 3 then + npcHandler:say("Have you lost my waterskin?", cid) + npcHandler.topic[cid] = 12 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 3 then + npcHandler:say({ + "I hope that I am not asking too much of you with this task. I heard of a flower which is currently unique in Tibia and can survive at only one place. ...", + "This place is somewhere in the bleak mountains of Nargor. I would love to have a sample of its blossom, but the problem is that it seldom actually blooms. ...", + "I cannot afford to travel there each day just to check whether the time has already come, besides I have no idea where to start looking. ...", + "I would be deeply grateful if you could support me in this matter and collect a sample of the blooming Griffinclaw for me. ...", + "Have you understood everything I told you and will fullfil this task for me?" + }, cid) + npcHandler.topic[cid] = 4 + elseif npcHandler.topic[cid] == 4 then + npcHandler:say("Alright then. Take this botanist's container and return to me once you were able to retrieve a sample. Don't lose patience!", cid) + player:setStorageValue(Storage.OutfitQuest.DruidHatAddon, 1) + player:setStorageValue(Storage.OutfitQuest.DefaultStart, 1) --this for default start of Outfit and Addon Quests + player:addItem(4869, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 5 then + if player:removeItem(5937, 1) then + npcHandler:say("Crunor be praised! The Griffinclaw really exists! Now, I will make sure that it will not become extinct. If you are ready to help me again, just ask me for a {task}.", cid) + player:setStorageValue(Storage.OutfitQuest.DruidHatAddon, 2) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 6 then + npcHandler:say("Great! Here, take my waterskin and try to fill it with water from this special trickle. Don't lose my waterskin, I will not accept some random dirty waterskin.", cid) + player:setStorageValue(Storage.OutfitQuest.DruidHatAddon, 3) + player:addItem(5938, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 7 then + if player:removeItem(5939, 1) then + npcHandler:say("Good work, |PLAYERNAME|! This water looks indeed extremely clear. I will examine it right away. If you are ready to help me again, just ask me for a {task}.", cid) + player:setStorageValue(Storage.OutfitQuest.DruidHatAddon, 4) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 8 then + npcHandler:say("Good! I will eagerly await your return.", cid) + player:setStorageValue(Storage.OutfitQuest.DruidHatAddon, 5) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 9 then + if player:removeItem(5906, 100) then + npcHandler:say("I'm very impressed, |PLAYERNAME|. With this task you have proven that you are on the right side and are powerful as well. If you are ready to help me again, just ask me for a {task}.", cid) + player:setStorageValue(Storage.OutfitQuest.DruidHatAddon, 6) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 10 then + npcHandler:say("Thank you so much. I can't wait to wear it around my neck again, it was a special present from Faolan.", cid) + player:setStorageValue(Storage.OutfitQuest.DruidHatAddon, 7) + player:setStorageValue(Storage.OutfitQuest.DruidAmuletDoor, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 11 then + if player:removeItem(5940, 1) then + npcHandler:say("Crunor be praised! You found my beloved chain! |PLAYERNAME|, you really earned my respect and I consider you as a friend from now on. Remind me to tell you about {Faolan} sometime.", cid) + player:setStorageValue(Storage.OutfitQuest.DruidHatAddon, 8) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 12 then + npcHandler:say("I can give you a new one, but I fear that I have to take a small fee for it. Would you like to buy a waterskin for 1000 gold?", cid) + npcHandler.topic[cid] = 13 + elseif npcHandler.topic[cid] == 13 then + if player:removeMoneyNpc(1000) then + player:addItem(5938, 1) + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "Always nice to meet a fellow druid, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_FAREWELL, "May Crunor bless and guide you, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "May Crunor bless and guide you, |PLAYERNAME|.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/cerdras.lua b/data/npc/scripts/cerdras.lua new file mode 100644 index 00000000000..6513bee1f44 --- /dev/null +++ b/data/npc/scripts/cerdras.lua @@ -0,0 +1,47 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I'm merely a humble druid like so many others here. I may not be the most talented of healers, but I am gifted with a special atunement to the elements."}) +keywordHandler:addKeyword({'nature'}, StdModule.say, {npcHandler = npcHandler, text = "For me, nature is the harmony of the elements. This harmony can be disturbed by certain events, but nature always finds its way back to harmony in the end."}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + elseif msgcontains(msg, "elements") then + npcHandler:say({ + 'How can I explain my connection to the elements so that you can understand it? Hmmm, it is like a faint melody, a song, that is always there. ...', + 'I hear that melody shifting in time with the shifts in the elements. With so many years of listening, I have learned to interpret these shifts and so come to a deeper understanding of the elements. ...', + 'It was a natural step for me to become responsible for researching elemental lore. I try to learn as much as I can and share it with my fellow druids. ...', + 'Unfortunately, much of my understanding is instinctive, and our language just doesn\'t contain the right words for me to express the things I feel adequately.' + }, cid) + elseif msgcontains(msg, "song") then + npcHandler:say({ + 'It is hard to explain. Of course, it\'s not a real song as you would understand it. I don\'t hear it with my ears, but rather, I feel it deep inside of me. ...', + 'Calling it a song or melody is the best I can do to describe it to those who don\'t share this kind of perception. ...', + 'It also helps me to express and understand something for which our language has no appropriate expression. ...', + 'You know, we are so dependent on words that we can\'t think about concepts when we don\'t have words for them. ...', + 'I sometimes think words have become just as much of a hindrance as a help. ...', + 'Perhaps we would fare better if only we forgot words and dealt purely in feelings. Then perhaps all of us could hear the wonderful melody of nature.' + }, cid) + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "Greetings my friend!") +npcHandler:setMessage(MESSAGE_FAREWELL, "May Crunor bless and guide you, |PLAYERNAME|.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/cerebrir.lua b/data/npc/scripts/cerebrir.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/cerebrir.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/chantalle.lua b/data/npc/scripts/chantalle.lua new file mode 100644 index 00000000000..3e9fc376bc7 --- /dev/null +++ b/data/npc/scripts/chantalle.lua @@ -0,0 +1,45 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'key') then + if player:getStorageValue(Storage.ThievesGuild.Mission06) == 1 then + local headItem = player:getSlotItem(CONST_SLOT_HEAD) + if headItem and headItem.itemid == 2665 and player:getStorageValue(Storage.Postman.Rank) == 5 and player:getSex() ~= PLAYERSEX_FEMALE then + player:addItem(8762) + player:setStorageValue(Storage.ThievesGuild.Mission06, 2) + npcHandler:say('Oh my! You look so great in your uniform! You archpostmen are not only daring but also handsome. Here take it, that\'s the key you wanted. Just promise to visit me now and then!', cid) + elseif player:removeItem(8767, 1) then + player:addItem(8762) + player:setStorageValue(Storage.ThievesGuild.Mission06, 2) + npcHandler:say('Oh my, such a lovely necklace! Here take it, that\'s the key you wanted. Now let me admire my precious necklace alone.', cid) + else + npcHandler:say('I am sorry, I am not interested in your money. Maybe you should try your luck with Herbert, the postman instead.', cid) + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/charles.lua b/data/npc/scripts/charles.lua new file mode 100644 index 00000000000..189e869699b --- /dev/null +++ b/data/npc/scripts/charles.lua @@ -0,0 +1,57 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Passages to Thais, Darashia, Edron, Venore, Ankrahmun, Liberty Bay and Yalahar.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, cost, destination, condition) + if condition then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sorry but I don\'t sail there.'}, condition) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('edron', 150, Position(33173, 31764, 6)) +addTravelKeyword('venore', 160, Position(32954, 32022, 6)) +addTravelKeyword('yalahar', 260, Position(32816, 31272, 6), function(player) return player:getStorageValue(Storage.SearoutesAroundYalahar.PortHope) ~= 1 and player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) < 5 end) +addTravelKeyword('ankrahmun', 110, Position(33092, 32883, 6)) +addTravelKeyword('darashia', 180, Position(33289, 32480, 6)) +addTravelKeyword('thais', 160, Position(32310, 32210, 6)) +addTravelKeyword('liberty bay', 50, Position(32285, 32892, 6)) +addTravelKeyword('carlin', 120, Position(32387, 31820, 6)) +addTravelKeyword('shortcut', 100, Position(32029, 32466, 7), function(player) return player:getStorageValue(Storage.TheSecretLibrary.PinkTel) == 2 and player:getStorageValue(Storage.TheSecretLibrary.Mota) == 12 end) + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, destination = {Position(32535, 32792, 6), Position(32536, 32778, 6)}}) + +-- Basic +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go - {Thais}, {Darashia}, {Venore}, {Liberty Bay}, {Ankrahmun}, {Yalahar} or {Edron?}'}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go - {Thais}, {Darashia}, {Venore}, {Liberty Bay}, {Ankrahmun}, {Yalahar} or {Edron?}'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'Im the captain of the Poodle, the proudest ship on all oceans.'}) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) +keywordHandler:addKeyword({'port hope'}, StdModule.say, {npcHandler = npcHandler, text = "That's where we are."}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'It\'s Charles.'}) +keywordHandler:addKeyword({'svargrond'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sorry, but we don\'t serve the routes to the Ice Islands.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Ahoy. Where can I sail you today?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Bye.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/charlotta.lua b/data/npc/scripts/charlotta.lua new file mode 100644 index 00000000000..6bcfb75dbcc --- /dev/null +++ b/data/npc/scripts/charlotta.lua @@ -0,0 +1,52 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "errand") or msgcontains(msg, "gold") then + if player:getStorageValue(Storage.TheShatteredIsles.TheErrand) == 1 then + npcHandler:say("Oh, so you brought some gold from Eleonore to me?", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + if player:removeMoneyNpc(200) then + npcHandler:say("Hmm, it seems that Eleonore does trust you. Perhaps she is even right. However. Since we need some help right now I guess we can't be too picky. Return to Eleonore and tell her the secret password: 'peg leg'. She will tell you more about her problem.", cid) + player:setStorageValue(Storage.TheShatteredIsles.TheErrand, 2) + npcHandler.topic[cid] = 2 + else + npcHandler:say("You don't have enough...", cid) + end + end + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] >= 1 then + npcHandler:say("Then no.", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Ah, welcome! Welcome |PLAYERNAME|! If you need druid spells, you've come to the right place. Otherwise it's just nice to have a visitor.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Oh well.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/charos.lua b/data/npc/scripts/charos.lua new file mode 100644 index 00000000000..64441dc56e3 --- /dev/null +++ b/data/npc/scripts/charos.lua @@ -0,0 +1,78 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local config = { + towns = { + ["venore"] = TOWNS_LIST.VENORE, + ["thais"] = TOWNS_LIST.THAIS, + ["kazordoon"] = TOWNS_LIST.KAZORDOON, + ["carlin"] = TOWNS_LIST.CARLAIN, + ["ab'dendriel"] = TOWNS_LIST.AB_DENDRIEL, + ["liberty bay"] = TOWNS_LIST.LIBERTY_BAY, + ["port hope"] = TOWNS_LIST.PORT_HOPE, + ["ankrahmun"] = TOWNS_LIST.ANKRAHMUN, + ["darashia"] = TOWNS_LIST.DARASHIA, + ["edron"] = TOWNS_LIST.EDRON + }, +} + +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.AdventurersGuild.CharosTrav) > 6 then + npcHandler:say("Sorry, you have traveled a lot.", cid) + npcHandler:resetNpc(cid) + return false + else + npcHandler:setMessage(MESSAGE_GREET, "Hello young friend! I can attune you to a city of your choice. \z + If you step to the teleporter here you will not appear in the city you came from as usual, \z + but the city of your choice. Is it what you wish?") + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if npcHandler.topic[cid] == 0 then + if msgcontains(msg, "yes") then + npcHandler:say("Fine. You have ".. -player:getStorageValue(Storage.AdventurersGuild.CharosTrav)+7 .." \z + attunements left. What is the new city of your choice? Thais, Carlin, Ab'Dendriel, Kazordoon, Venore, \z + Ankrahmun, Edron, Darashia, Liberty Bay or Port Hope?", cid) + npcHandler.topic[cid] = 1 + end + elseif npcHandler.topic[cid] == 1 then + local cityTable = config.towns[msg:lower()] + if cityTable then + player:setStorageValue(Storage.AdventurersGuild.CharosTrav, + player:getStorageValue(Storage.AdventurersGuild.CharosTrav)+1) + player:setStorageValue(Storage.AdventurersGuild.Stone, cityTable) + npcHandler:say("Goodbye traveler!", cid) + else + npcHandler:say("Sorry, I don't know about this place.", cid) + end + end + return true +end + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/chartan.lua b/data/npc/scripts/chartan.lua new file mode 100644 index 00000000000..13bce441c61 --- /dev/null +++ b/data/npc/scripts/chartan.lua @@ -0,0 +1,74 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 2 then + npcHandler:say("Mhm, what are you doing here. Who zent you? ", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 3 then + npcHandler:say("Zo are you ready to get zomezing done?", cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 5 then + npcHandler:say("Zo? Did you find a way to reztore ze teleporter? ", cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, "zalamon") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "I zee. Zalamon zent word of ze arrival of a zoftzkin quite zome time ago. Zat muzt be you zen. ... ", + "Well, I exzpected zomeone more - imprezzive. However, we will zee how far you can get. You've got newz from ze zouz? ... ", + "Hm, I underztand. ... ", + "Oh you did. ... ", + "I zee. Interezting. ... ", + "You being here meanz we have eztablished connectionz to ze zouz. Finally. And you are going to help uz. Well, zere iz zertainly a lot for you to do. Zo better get ztarted. " + }, cid) + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 3) + player:setStorageValue(Storage.WrathoftheEmperor.Mission01, 3) --Questlog, Wrath of the Emperor "Mission 01: Catering the Lions Den" + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 2 then + npcHandler:say({ + "Alright. Well, az you might not be aware of it yet - we are on top of an old temple complex. It haz been abandoned and it haz crumbled over time. ...", + "Ze teleporter over zere uzed to work juzt fine to get uz back to ze zouz. But it haz ztopped operating for quite zome time. ... ", + "My men believe it iz a dizturbanze cauzed by ze corruption zat zpreadz everywhere. Zey are too zcared to go down zere. And zat'z where you come in. ... ", + "Zere were meanz to activate teleporterz zomewhere in ze complex. But zinze you cannot reach all ze roomz, I guezz you will have to improvize. ... ", + "Here iz ze key to ze entranze to ze complex. Figure zomezing out, reztore ze teleporter zo we can get back to ze plainz in ze zouz. " + }, cid) + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 4) + player:setStorageValue(Storage.WrathoftheEmperor.Mission02, 1) --Questlog, Wrath of the Emperor "Mission 02: First Contact" + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + npcHandler:say({ + "You did it! Zere waz zome kind of zparkle and I zink it iz working again - oh pleaze feel free to try it, I uhm, I will wait here and be ready juzt in caze zomezing uhm happenz to you. ... ", + "And if you head to Zalamon, be zure to inform him about our zituation. Food rationz are running low and we are ztill not well equipped. We need to eztablish a working zupply line. " + }, cid) + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 6) + player:setStorageValue(Storage.WrathoftheEmperor.Mission02, 3) --Questlog, Wrath of the Emperor "Mission 02: First Contact" + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/chatterbone.lua b/data/npc/scripts/chatterbone.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/chatterbone.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/chavis.lua b/data/npc/scripts/chavis.lua new file mode 100644 index 00000000000..3132be83069 --- /dev/null +++ b/data/npc/scripts/chavis.lua @@ -0,0 +1,78 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + -- START TASK + if msgcontains(msg, "food") then + if player:getStorageValue(Storage.Oramond.MissionToTakeRoots) <= 0 then + npcHandler:say({ + "Hey there, just to let you know - I am not a man of many words. I prefer 'deeds', you see? The poor of this city will not feed themselves. ...", + "So in case you've got nothing better to do - and it sure looks that way judging by how long you\'re already loitering around in front of my nose - please help us. ...", + "If you can find some of the nutritious, juicy {roots} in the outskirts of Rathleton, bring them here. We will gladly take bundles of five roots each, and hey - helping us, helps you in the long term, trust me." + }, cid, false, true, 10) + if player:getStorageValue(Storage.Oramond.QuestLine) <= 0 then + player:setStorageValue(Storage.Oramond.QuestLine, 1) + end + player:setStorageValue(Storage.Oramond.MissionToTakeRoots, 1) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.Oramond.MissionToTakeRoots) == 1 then + if player:getStorageValue(Storage.Oramond.HarvestedRootCount) < 5 then + npcHandler:say("I am sorry, you didn't harvest enough roots. You need to harvest a bundle of at least five roots - and please try doing it yourself.", cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.Oramond.HarvestedRootCount) >= 5 then + npcHandler:say("Yes? You brought some juicy roots? How nice of you - that's one additional voice in the {magistrate} of {Rathleton} for you! ...", cid) + npcHandler.topic[cid] = 1 + end + end + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 1 then + npcHandler:say("Spend it wisely, though, put in a word for the poor, will ye? Sure you will.", cid) + player:setStorageValue(Storage.Oramond.VotingPoints, + player:getStorageValue(Storage.Oramond.VotingPoints) + 1) + + player:setStorageValue(Storage.Oramond.HarvestedRootCount, + player:getStorageValue(Storage.Oramond.HarvestedRootCount) - 5) + player:removeItem(23662, 5) + + player:setStorageValue(Storage.Oramond.MissionToTakeRoots, 0) + player:setStorageValue(Storage.Oramond.DoorBeggarKing, 1) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "root") then + npcHandler:say("They are nutritious, cost nothing and are good for the body hair. If you can bring us bundles of five juicy roots each - we will make it worth your while for the {magistrate}.", cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "magistrate") then + npcHandler:say("They act so important but it is us common people who keep things going. There is a lot you can do in this city to earn a right to vote in the magistrate, though. So keep an eye out for everyone who needs help.", cid) + elseif msgcontains(msg, "rathleton") then + npcHandler:say({ + "Don't be fooled, we have here masters and servants like everywhere else. The whole system is a scam to subdue the masses, to fool them about what is really happening. ...", + "The system only ensures that the rich have a better control and the labourers are only used." + }, cid, false, true, 10) + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, 'Hey there! You don\'t happen to have some {food} on you, you\'re willing to share? Well, where are my manners, a warm welcome for now.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Take care out there!') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/chemar.lua b/data/npc/scripts/chemar.lua new file mode 100644 index 00000000000..430ad09d85c --- /dev/null +++ b/data/npc/scripts/chemar.lua @@ -0,0 +1,48 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Ask me if you need letters or parcels. I\'ll deliver them via airmail, of course!' }, + { text = 'Feel the wind in your hair during one of my carpet rides!' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, cost, destination) + if keyword == 'farmine' then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Never heard about a place like this.'}, function(player) return player:getStorageValue(Storage.TheNewFrontier.Mission10) ~= 1 end) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a ride to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, text = 'Hold on!', cost = cost, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'You shouldn\'t miss the experience.', reset = true}) +end + +addTravelKeyword('farmine', 60, Position(32983, 31539, 1)) +addTravelKeyword('edron', 40, Position(33193, 31784, 3)) +addTravelKeyword('svargrond', 60, Position(32253, 31097, 4)) +addTravelKeyword('femor hills', 60, Position(32536, 31837, 4)) +addTravelKeyword('kazordoon', 80, Position(32588, 31941, 0)) +addTravelKeyword('hills', 60, Position(32536, 31837, 4)) +addTravelKeyword('issavi', 100, Position(33957, 31515, 0)) + +npcHandler:setMessage(MESSAGE_GREET, 'Daraman\'s blessings, traveller |PLAYERNAME|.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'It was a pleasure to help you, |PLAYERNAME|.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'It was a pleasure to help you, |PLAYERNAME|.') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/chephan.lua b/data/npc/scripts/chephan.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/chephan.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/chester_kahs.lua b/data/npc/scripts/chester_kahs.lua new file mode 100644 index 00000000000..b5c6d6d57fe --- /dev/null +++ b/data/npc/scripts/chester_kahs.lua @@ -0,0 +1,273 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Too many possibilities to become a servant of darkness to trust ANYONE!' }, + { text = 'Don\'t tell me I didn\'t warn you.' }, + { text = 'It\'s all a big conspiracy, mark my words.' }, + { text = 'Not everything that walks our streets is human ... or even living.' }, + { text = 'We are surrounded by myths, living and dead.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local fire = Condition(CONDITION_FIRE) +fire:setParameter(CONDITION_PARAM_DELAYED, true) +fire:setParameter(CONDITION_PARAM_FORCEUPDATE, true) +fire:addDamage(25, 9000, -10) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'gamel') and msgcontains(msg, 'rebel') then + npcHandler:say('Are you saying that Gamel is a member of the rebellion?', cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + npcHandler:say('Do you know what his plans are about?', cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 3 then + if player:removeItem(2177, 1) then + npcHandler:say('Thank you! Take this ring. If you ever need a healing, come, bring the scroll, and ask me to {heal}.', cid) + player:addItem(2168, 1) + else + npcHandler:say('Sorry, but you have none.', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 4 then + if player:removeItem(2168, 1) then + npcHandler:say('So be healed!', cid) + player:addHealth(player:getMaxHealth()) + Npc():getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + else + npcHandler:say('Sorry, you are not worthy!', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 5 then + player:setStorageValue(Storage.SecretService.Quest, 1) + npcHandler:say('Then I welcome you to the TBI. This is a great moment for you, remember it well. Talk to me about your missions whenever you feel ready.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 6 then + player:setStorageValue(Storage.SecretService.TBIMission01, 3) + player:setStorageValue(Storage.SecretService.Quest, 3) + npcHandler:say('I think they understood the warning the way it was meant. If not, you will have to visit Venore soon again. But for now it\'s settled.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 7 then + if player:removeItem(7696, 1) then + player:setStorageValue(Storage.SecretService.TBIMission02, 2) + player:setStorageValue(Storage.SecretService.Quest, 5) + npcHandler:say('Thank you, we can finally let them have some closure regarding this.', cid) + else + npcHandler:say('Please bring me some proof of his whereabouts.', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 8 then + if player:removeItem(14324, 1) then + player:setStorageValue(Storage.SecretService.TBIMission03, 3) + player:setStorageValue(Storage.SecretService.Quest, 7) + npcHandler:say('I can only hope that this information are as valuable as we expected it. A good man died for them.', cid) + else + npcHandler:say('Please bring me some valuable information!', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 9 then + if player:removeItem(14325, 1) then + player:setStorageValue(Storage.SecretService.TBIMission04, 2) + player:setStorageValue(Storage.SecretService.Quest, 9) + npcHandler:say('Ah yes, very interesting. Almost as I suspected. It\'s a good thing that we got those documents in our hands.', cid) + else + npcHandler:say('We need those intelligence reports, do whatever you need to do agent!', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 10 then + player:setStorageValue(Storage.SecretService.TBIMission05, 3) + player:setStorageValue(Storage.SecretService.Quest, 11) + npcHandler:say('Now that Venore is of nearly no importance anymore, there is only Carlin left to deal with.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 11 then + player:setStorageValue(Storage.SecretService.TBIMission06, 3) + player:setStorageValue(Storage.SecretService.Quest, 13) + npcHandler:say('I already heard that our little trick worked quite well. Several officials of Carlin are already on their way to repair the damage done to their diplomatic efforts. It will not only cost them much money but also quite some time.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 12 then + if player:removeMoneyNpc(1000) then + player:addItem(7700, 1) + npcHandler:say('Here you are. Better don\'t loose it again.', cid) + else + npcHandler:say('You don\'t have enough money', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 13 then + if player:removeItem(7699, 1) then + player:setStorageValue(Storage.SecretService.Mission07, 2) + player:setStorageValue(Storage.SecretService.Quest, 15) + player:addItem(7960, 1) + npcHandler:say('You have done superb work agent, I grant you the title of Top Agent! Here\'s a little gift you might find useful.', cid) + else + npcHandler:say('Please bring me proof of the mad technomancers defeat!', cid) + end + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'no') then + if npcHandler.topic[cid] == 1 then + npcHandler:say('Then don\'t bother me with it. I\'m a busy man.', cid) + elseif npcHandler.topic[cid] == 3 then + npcHandler:say('Traitor!', cid) + player:addCondition(fire) + player:getPosition():sendMagicEffect(CONST_ME_EXPLOSIONHIT) + Npc():getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + player:removeItem(2177, 1) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + else + npcHandler:say('As you wish.', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, 'magic') and msgcontains(msg, 'crystal') and msgcontains(msg, 'lugri') and msgcontains(msg, 'deathcurse') then + npcHandler:say('That\'s terrible! Will you give me the crystal?', cid) + npcHandler.topic[cid] = 3 + else + npcHandler:say('Tell me precisely what he asked you to do! It\'s important!', cid) + end + elseif msgcontains(msg, 'heal') then + npcHandler:say('Do you need the healing now?', cid) + npcHandler.topic[cid] = 4 + elseif msgcontains(msg, 'join') then + if player:getStorageValue(Storage.SecretService.Quest) < 1 then + npcHandler:say({ + 'Our bureau is an old and traditional branch of the Thaian government. It takes more than lip service to join our ranks ...', + 'Absolute loyalty to the crown and the Thaian cause as well as courage face-to-face with the enemy is the least we expect from our members ...', + 'You will swear allegiance to Thais alone and abandon the service of any other city. So is it really your wish to become one of our field agents?' + }, cid) + npcHandler.topic[cid] = 5 + end + elseif msgcontains(msg, 'mission') then + if player:getStorageValue(Storage.SecretService.Quest) == 1 and player:getStorageValue(Storage.SecretService.AVINMission01) < 1 and player:getStorageValue(Storage.SecretService.CGBMission01) < 1 then + player:setStorageValue(Storage.SecretService.Quest, 2) + player:setStorageValue(Storage.SecretService.TBIMission01, 1) + npcHandler:say({ + 'Your first task is to deliver a warning. Illegally, the Venoreans are crafting more ships than the Thaian authorities have allowed them ...', + 'Our sources have told us that those ships often end up in the hands of pirates or smugglers ...', + 'An official note would strain the relationship between Thais and Venore too much as this would mean that we had to admit officially that we know about those activities ...', + 'Still, we can\'t allow them to continue like this. It will be your task to let them know that we do not tolerate such behaviour. Get a fire bug from Liberty Bay and set their shipyard on fire ...', + 'Use the fire bug on some flammable material there to start the fire. It might take a while to find some wood that\'s dry enough for the fire to spread. Just keep trying ... ', + 'If you get captured or killed during your mission, we will deny any contact with you.' + }, cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.SecretService.TBIMission01) == 2 then + npcHandler:say('Have you fulfilled your current mission?', cid) + npcHandler.topic[cid] = 6 + elseif player:getStorageValue(Storage.SecretService.TBIMission01) == 3 and player:getStorageValue(Storage.SecretService.Quest) == 3 then + player:setStorageValue(Storage.SecretService.Quest, 4) + player:setStorageValue(Storage.SecretService.TBIMission02, 1) + npcHandler:say({ + 'Your next mission concerns an internal matter for our agency. Some decades ago, one of our most talented field agents vanished in the Green Claw Swamp ...', + 'Nowadays, that more and more adventurers are swarming this area, there is an increasing number of reports on some sinister goings-on and mysterious ruins in the middle of the swamp ...', + 'We got some credible clues that there might be a connection between the ruins and the disappearance of our agent ...', + 'As he is already missing since decades it is unlikely that he is still alive. Nevertheless, we want you to find out something about the whereabouts of our agent in the ruins in the Green Claw Swamp, north west of Venore ...', + 'He used to write diaries, maybe you can find one of those, or some other hints, or even his remains. You have to understand that he was a member of a prestigious Thaian family. Very influential people are interested in his whereabouts ...', + 'The Green Claw Swamp is treacherous and dangerous. You will have a hard time to find any clues ...', + 'As a small incentive I think its worthy to mention that he was wearing a quite impressive armor. You may keep it for yourself if you stumble across it.' + }, cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.SecretService.TBIMission02) == 1 then + npcHandler:say('Have you fulfilled your current mission?', cid) + npcHandler.topic[cid] = 7 + elseif player:getStorageValue(Storage.SecretService.TBIMission02) == 2 and player:getStorageValue(Storage.SecretService.Quest) == 5 then + player:setStorageValue(Storage.SecretService.Quest, 6) + player:setStorageValue(Storage.SecretService.TBIMission03, 1) + npcHandler:say({ + 'One of our agents is missing. He was investigating the cause for the slow growth of our colony Port Hope ...', + 'You will continue these investigations at the point where the information that the lost agent has sent us ends. Some of the traders in Port Hope must have connections to persons who are interested in sabotaging our efforts in Tiquanda ...', + 'Search their personal belongings to find some sort of evidence that we could need!' + }, cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.SecretService.TBIMission03) == 2 then + npcHandler:say('Have you fulfilled your current mission?', cid) + npcHandler.topic[cid] = 8 + elseif player:getStorageValue(Storage.SecretService.TBIMission03) == 3 and player:getStorageValue(Storage.SecretService.Quest) == 7 then + player:setStorageValue(Storage.SecretService.Quest, 8) + player:setStorageValue(Storage.SecretService.TBIMission04, 1) + npcHandler:say({ + 'Just recently we were able to secretly help our elven friends to exposure an agitator sent by Carlin to poison our connections with them. The elves\' reaction wasswift and without compromise ...', + 'They banished the delinquent in a place they call \'Hellgate\'. Unfortunately, we learnt later that the convict was sent there with several of his belongings and it is very likely that he took vital papers with him ...', + 'These papers can tell us much about Carlin\'s plans in the North. We need you to enter \'Hellgate\' and to retrieve the papers for us ...', + 'We don\'t care how you get them. Do whatever you think is necessary.' + }, cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.SecretService.TBIMission04) == 1 then + npcHandler:say('Have you fulfilled your current mission?', cid) + npcHandler.topic[cid] = 9 + elseif player:getStorageValue(Storage.SecretService.TBIMission04) == 2 and player:getStorageValue(Storage.SecretService.Quest) == 9 then + player:setStorageValue(Storage.SecretService.Quest, 10) + player:setStorageValue(Storage.SecretService.TBIMission05, 1) + player:addItem(7697, 1) + npcHandler:say({ + 'It\'s bad enough that Carlin got a solid foothold in the far North but now the Venoreans also try to move in. They try to gain influence on the barbarian raiders by bribing their leaders or making them great promises ...', + 'We want you to cause some bad blood in this relationship. Travel to their most southern camp, enter the ice tower of their leaders and kill some of them ...', + 'Here is a signet ring that the Venorean emissaries use to wear. \'Lose\' the ring in the north-western corner of the highest level of the tower. They will surely find it there.' + }, cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.SecretService.TBIMission05) == 2 then + npcHandler:say('Have you fulfilled your current mission?', cid) + npcHandler.topic[cid] = 10 + elseif player:getStorageValue(Storage.SecretService.TBIMission05) == 3 and player:getStorageValue(Storage.SecretService.Quest) == 11 then + player:setStorageValue(Storage.SecretService.Quest, 12) + player:setStorageValue(Storage.SecretService.TBIMission06, 1) + player:addItem(7700, 1) + npcHandler:say({ + 'The women of Carlin have the northern city Svargrond in the firm grip of her manicured hands. At the moment, there is little we can do about it but there is one thing that plays into our hands ...', + 'The barbarians have surely at least heard about the fact that alcohol is outlawed in Carlin ...', + 'If some amazonian warrior would smash a beer or ale cask in front of some witnesses, the relationship would surely suffer a bit. So go and disguise yourself as an amazon. Then use a crowbar to destroy a cask.' + }, cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.SecretService.TBIMission06) == 2 then + npcHandler:say('Have you fulfilled your current mission?', cid) + npcHandler.topic[cid] = 11 + elseif player:getStorageValue(Storage.SecretService.TBIMission06) == 3 and player:getStorageValue(Storage.SecretService.Quest) == 13 then + player:setStorageValue(Storage.SecretService.Quest, 14) + player:setStorageValue(Storage.SecretService.Mission07, 1) + npcHandler:say({ + 'Great, you are here. We need your service in a mission of utmost urgency ...', + 'A mad dwarven technomancer that listens to the name of Blowbeard sent us a blackmailing letter. He demands to deliver all of Thais\'s gold to him. Else he will destroy the city with an artificial earthquake caused by one of his machines! ...', + 'We need you to find his base in Kazordoon and to kill him before he can use his infernal machine. Bring us his beard as proof of your success.' + }, cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.SecretService.TBIMission06) == 3 and player:getStorageValue(Storage.SecretService.Mission07) == 1 then + npcHandler:say('Have you fulfilled your current mission?', cid) + npcHandler.topic[cid] = 13 + end + elseif msgcontains(msg, 'disguise') then + if player:getStorageValue(Storage.SecretService.TBIMission06) == 1 then + npcHandler:say('If you lost or wasted your disguise kit I can replace it. It will cost you 1000 gold though since you lost royal property. Is that ok for you?', cid) + npcHandler.topic[cid] = 12 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Salutations, stranger.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Take care out there!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Take care out there!") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/chief_grarkharok.lua b/data/npc/scripts/chief_grarkharok.lua new file mode 100644 index 00000000000..86b5ad126fa --- /dev/null +++ b/data/npc/scripts/chief_grarkharok.lua @@ -0,0 +1,51 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Grarkharok\'s bestest troll tribe! Yeee, good name!' }, + { text = 'Grarkharok make new tribe here! Me Chief now!' }, + { text = 'Me like to throw rocks, me also like frogs! Yumyum!' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'cloak') then + if (player:getStorageValue(Storage.ThreatenedDreams.TroubledMission01) == 13) then + player:setStorageValue(Storage.ThreatenedDreams.TroubledMission01, 14) + npcHandler:say("Hahaha! Grarkharok take cloak from pretty girl. Then ... girl is swan. Grarkharok wants eat but flies away. Grarkharok not understand. Not need cloak, too many feathers. Give cloak to To ... Ta ... Tereban in Edron. Getting shiny coins and meat.", cid) + else + npcHandler:say("You are not on that mission.", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Me Chief Grarkharok! No do {nothing}!") +npcHandler:setMessage(MESSAGE_FAREWELL, "Grarkharok be {chief}!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Grarkharok be {chief}!") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) + diff --git a/data/npc/scripts/chondur.lua b/data/npc/scripts/chondur.lua new file mode 100644 index 00000000000..5242cdaf914 --- /dev/null +++ b/data/npc/scripts/chondur.lua @@ -0,0 +1,550 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'stampor') or msgcontains(msg, 'mount') then + if not player:hasMount(11) then + npcHandler:say( + 'You did bring all the items I requqested, cuild. Good. \ + Shall I travel to the spirit realm and try finding a stampor compasion for you?', + cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say('You already have stampor mount.', cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'mission') then + if player:getStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven) == 8 then + npcHandler:say( + 'The evil cult has placed a curse on one of the captains here. \ + I need at least five of their pirate voodoo dolls to lift that curse.', + cid) + player:setStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven, 9) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven) == 9 then + npcHandler:say('Did you bring five pirate voodoo dolls?', cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + if player:removeItem(13299, 50) and player:removeItem(13301, 30) and player:removeItem(13300, 100) then + npcHandler:say( + { + 'Ohhhhh Mmmmmmmmmmmm Ammmmmgggggggaaaaaaa ...', + 'Aaaaaaaaaahhmmmm Mmmaaaaaaaaaa Kaaaaaamaaaa ...', + "Brrt! I think it worked! It's a male stampor. \ + I linked this spirit to yours. You can probably already summon him to you ...", + 'So, since me are done here... I need to prepare another ritual, so please let me work, cuild.' + }, + cid) + player:addMount(11) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + else + npcHandler:say("Sorry you don't have the necessary items.", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + if player:getStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven) == 9 then + if player:removeItem(5810, 5) then + npcHandler:say('Finally I can put an end to that curse. I thank you so much.', cid) + player:setStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven, 10) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have it...", cid) + npcHandler.topic[cid] = 0 + end + end + end + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] > 2 then + npcHandler:say('Maybe next time.', cid) + npcHandler.topic[cid] = 0 + end + return true +end + +-- Shaman Addons +-- If the player can't wear shaman outfit +local function notReadyKeyword(keyword, text) + keywordHandler:addKeyword( + {keyword}, + StdModule.say, + {npcHandler = npcHandler, text = text}, + function(player) + return not player:hasOutfit(player:getSex() == PLAYERSEX_FEMALE and 158 or 154) + end + ) +end + +notReadyKeyword( + 'outfit', + { + "Hum? Sorry, but I don't sense enough spiritual wisdom in you to even allow \ + you to touch the mask and staff I'm wearing... yet. ...", + 'I know of a really wise ape healer, though, who might be able to bless you with shamanic energy. \ + You should become his apprentice first if you desire to become mine.' + } +) +notReadyKeyword( + 'addon', + { + "Hum? Sorry, but I don't sense enough spiritual wisdom in you to even allow \ + you to touch the mask and staff I'm wearing... yet. ...", + 'I know of a really wise ape healer, though, who might be able to bless you with shamanic energy. \ + You should become his apprentice first if you desire to become mine.' + } +) +notReadyKeyword('task', "The time hasn't come yet, my child. Believe and learn.") + +-- Start task +local function addTaskKeyword(text, value, missionStorage) + local taskKeyword = + keywordHandler:addKeyword( + {'task'}, + StdModule.say, + {npcHandler = npcHandler, text = text[1]}, + function(player) + return player:getStorageValue(Storage.OutfitQuest.Shaman.AddonStaffMask) == value + end + ) + local yesKeyword = taskKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = text[2]}) + + yesKeyword:addChildKeyword( + {'yes'}, + StdModule.say, + {npcHandler = npcHandler, text = text[3], reset = true}, + nil, + function(player) + player:setStorageValue( + Storage.OutfitQuest.Shaman.AddonStaffMask, + math.max(0, player:getStorageValue(Storage.OutfitQuest.Shaman.AddonStaffMask)) + 1 + ) + player:setStorageValue(missionStorage, 1) + player:setStorageValue(Storage.OutfitQuest.Ref, math.max(0, player:getStorageValue(Storage.OutfitQuest.Ref)) + 1) + end + ) + yesKeyword:addChildKeyword( + {'no'}, + StdModule.say, + {npcHandler = npcHandler, text = 'Would you like me to repeat the task requirements then?', moveup = 2} + ) + + taskKeyword:addChildKeyword( + {'no'}, + StdModule.say, + {npcHandler = npcHandler, text = "Well, it seems you aren't ready yet.", reset = true} + ) + keywordHandler:addAliasKeyword({'addon'}) + keywordHandler:addAliasKeyword({'outfit'}) +end + +-- Staff +addTaskKeyword( + { + "If you fulfil a task for me, I'll grant you a staff like the one I'm wearing. \ + Do you want to hear the requirements?", + { + 'Deep in the Tiquandian jungle a monster lurks which is seldom seen. \ + It is the revenge of the jungle against humankind. ...', + 'This monster, if slain, carries a rare root called Mandrake. If you find it, bring it to me. \ + Also, gather 5 of the voodoo dolls used by the mysterious dworc voodoomasters. ...', + 'If you manage to fulfil this task, I will grant you your own staff. \ + Have you understood everything and are ready for this test?' + }, + "Good! Come back once you've found a mandrake and collected 5 dworcish voodoo dolls." + }, + -1, + Storage.OutfitQuest.Shaman.MissionStaff +) + +-- Mask +addTaskKeyword( + { + "You have successfully passed the first task. \ + If you can fulfil my second task, I'll grant you a mask like the one I'm wearing. \ + Do you want to hear the requirements?", + { + "The dworcs of Tiquanda like to wear certain tribal masks which I'd like to take a look at. \ + Please bring me 5 of these masks. ...", + "Secondly, the high ape magicians of Banuta use banana staffs. \ + I'd love to learn more about theses staffs, so please bring me 5 of them, too. ...", + "If you manage to fulfil this task, I'll grant you your own mask. \ + Have you understood everything and are you ready for this test?" + }, + 'Good! Come back once you have collected 5 tribal masks and 5 banana staffs.' + }, + 2, + Storage.OutfitQuest.Shaman.MissionMask +) + +-- Hand in task items +local function addItemKeyword(keyword, aliasKeyword, text, value, item, addonId, missionStorage, achievement) + local itemKeyword = + keywordHandler:addKeyword( + {keyword}, + StdModule.say, + {npcHandler = npcHandler, text = text[1]}, + function(player) + return player:getStorageValue(Storage.OutfitQuest.Shaman.AddonStaffMask) == value + end + ) + itemKeyword:addChildKeyword( + {'yes'}, + StdModule.say, + {npcHandler = npcHandler, text = text[2], reset = true}, + function(player) + return player:getItemCount(item[1].itemId) < item[1].count or player:getItemCount(item[2].itemId) < item[2].count + end + ) + + itemKeyword:addChildKeyword( + {'yes'}, + StdModule.say, + {npcHandler = npcHandler, text = text[3], reset = true}, + function(player) + return player:getItemCount(item[1].itemId) >= item[1].count and player:getItemCount(item[2].itemId) >= item[2].count + end, + function(player) + player:removeItem(item[1].itemId, item[1].count) + player:removeItem(item[2].itemId, item[2].count) + player:addOutfitAddon(158, addonId) + player:addOutfitAddon(154, addonId) + player:setStorageValue( + Storage.OutfitQuest.Shaman.AddonStaffMask, + player:getStorageValue(Storage.OutfitQuest.Shaman.AddonStaffMask) + 1 + ) + player:setStorageValue(Storage.OutfitQuest.Ref, math.min(0, player:getStorageValue(Storage.OutfitQuest.Ref) - 1)) + player:setStorageValue(missionStorage, 0) + if achievement then + player:addAchievement('Way of the Shaman') + end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end + ) + itemKeyword:addChildKeyword( + {'no'}, + StdModule.say, + {npcHandler = npcHandler, text = "Well, it seems you aren't ready yet.", reset = true} + ) + keywordHandler:addAliasKeyword({aliasKeyword}) + keywordHandler:addKeyword( + {keyword}, + StdModule.say, + {npcHandler = npcHandler, text = aliasKeyword and text[4] or text[3]} + ) +end + +addItemKeyword( + 'mandrake', + 'voodoo doll', + { + 'Have you gathered the mandrake and the 5 voodoo dolls from the dworcs?', + "I'm proud of you my child, excellent work. This staff shall be yours from now on!", + 'A rare root with mysterious powers.', + { + 'Together with the spirits of the ancestors, I seek for wisdom. \ + Together we can change the flow of magic to do things that are beyond the limits of ordinary magic. ...', + 'In conversations with the spirits, I gain insight into secrets that would have been lost otherwise.' + } + }, + 1, + {{itemId = 5015, count = 1}, {itemId = 3955, count = 5}}, + 2, + Storage.OutfitQuest.Shaman.MissionStaff +) +addItemKeyword( + 'tribal mask', + 'banana staff', + { + 'Have you gathered the 5 tribal masks and the 5 banana staffs?', + 'Well done, my child! I hereby grant you the right to wear a shamanic mask. Do it proudly.', + 'Sometimes dworcs are seen with these masks.', + 'A banana staff is the sign of a high ape magician.' + }, + 3, + {{itemId = 3966, count = 5}, {itemId = 3967, count = 5}}, + 1, + Storage.OutfitQuest.Shaman.MissionMask, + true +) + +-- Task status +local function addTaskStatusKeyword(keyword, text, value) + keywordHandler:addKeyword( + {keyword}, + StdModule.say, + {npcHandler = npcHandler, text = text}, + function(player) + return player:getStorageValue(Storage.OutfitQuest.Shaman.AddonStaffMask) == value + end + ) + if keyword == 'addon' then + keywordHandler:addAliasKeyword({'outfit'}) + end +end + +addTaskStatusKeyword( + 'task', + 'Your task is to retrieve a mandrake from the Tiquandan jungle and 5 dworcish voodoo dolls.', + 1 +) +addTaskStatusKeyword( + 'task', + 'Your task is to retrieve 5 tribal masks from the dworcs and 5 banana staffs from the apes.', + 3 +) +addTaskStatusKeyword( + 'task', + 'You have successfully passed all of my tasks. There are no further things I can teach you right now.', + 4 +) + +addTaskStatusKeyword( + 'addon', + 'The time has come, my child. I sense great spiritual wisdom in you and I shall grant you a \ + sign of your progress if you can fulfil my task.', + 1 +) +addTaskStatusKeyword('addon', 'I shall grant you a sign of your progress as a shaman if you can fulfil my task.', 3) +addTaskStatusKeyword( + 'addon', + 'You have successfully passed all of my tasks. There are no further things I can teach you right now.', + 4 +) +-- End Shaman Addons + +-- Wooden Stake +keywordHandler:addKeyword( + {'stake'}, + StdModule.say, + { + npcHandler = npcHandler, + text = "Ten prayers for a blessed stake? Don't tell me they made you travel whole Tibia for it! \ + Listen, child, if you bring me a wooden stake, I'll bless it for you. " + }, + function(player) + return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 11 + end, + function(player) + player:setStorageValue(Storage.FriendsandTraders.TheBlessedStake, 12) + player:addAchievement('Blessed!') + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + end +) + +local stakeKeyword = + keywordHandler:addKeyword( + {'stake'}, + StdModule.say, + {npcHandler = npcHandler, text = 'Would you like to receive a spiritual prayer to bless your stake?'}, + function(player) + return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 12 + end +) + +stakeKeyword:addChildKeyword( + {'yes'}, + StdModule.say, + {npcHandler = npcHandler, text = "You don't have a wooden stake.", reset = true}, + function(player) + return player:getItemCount(5941) == 0 + end +) + +stakeKeyword:addChildKeyword( + {'yes'}, + StdModule.say, + { + npcHandler = npcHandler, + text = "Sorry, but I'm still exhausted from the last ritual. Please come back later.", + reset = true + }, + function(player) + return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStakeWaitTime) >= os.time() + end +) + +stakeKeyword:addChildKeyword( + {'yes'}, + StdModule.say, + {npcHandler = npcHandler, text = ' Sha Kesh Mar!', reset = true}, + function(player) + return player:getItemCount(5941) > 0 + end, + function(player) + player:setStorageValue(Storage.FriendsandTraders.TheBlessedStakeWaitTime, os.time() + 7 * 86400) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:removeItem(5941, 1) + player:addItem(5942, 1) + end +) +stakeKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Maybe another time.', reset = true}) + +-- Counterspell +keywordHandler:addKeyword( + {'counterspell'}, + StdModule.say, + {npcHandler = npcHandler, text = "You should not talk about things you don't know anything about."}, + function(player) + return player:getStorageValue(Storage.TheShatteredIsles.DragahsSpellbook) == -1 + end +) +keywordHandler:addAliasKeyword({'energy field'}) + +-- Start mission +local startcounterspellKeyword = + keywordHandler:addKeyword( + {'counterspell'}, + StdModule.say, + { + npcHandler = npcHandler, + text = 'You mean, you are interested in a counterspell to cross the energy barrier on Goroma?' + }, + function(player) + return player:getStorageValue(Storage.TheShatteredIsles.TheCounterspell) == -1 + end +) +local acceptKeyword = + startcounterspellKeyword:addChildKeyword( + {'yes'}, + StdModule.say, + { + npcHandler = npcHandler, + text = 'This is really not advisable. Behind this barrier, strong forces are raging violently. \ + Are you sure that you want to go there?' + } +) +acceptKeyword:addChildKeyword( + {'yes'}, + StdModule.say, + { + npcHandler = npcHandler, + text = { + "I guess I cannot stop you then. Since you told me about my apprentice, it's my turn to help you. \ + I'll perform a ritual for you, but I need a few ingredients. ...", + 'Bring me one fresh dead chicken, one fresh dead rat and one fresh dead black sheep, in that order.' + }, + reset = true + }, + nil, + function(player) + player:setStorageValue(Storage.TheShatteredIsles.TheCounterspell, 1) + end +) +acceptKeyword:addChildKeyword( + {'no'}, + StdModule.say, + {npcHandler = npcHandler, text = "It's much safer for you to stay here anyway, trust me.", reset = true} +) + +startcounterspellKeyword:addChildKeyword( + {'no'}, + StdModule.say, + {npcHandler = npcHandler, text = "It's much safer for you to stay here anyway, trust me.", reset = true} +) + +-- Deliver in corpses +local function addCounterspellKeyword(text, value, itemId) + local counterspellKeyword = + keywordHandler:addKeyword( + {'counterspell'}, + StdModule.say, + {npcHandler = npcHandler, text = text[1]}, + function(player) + return player:getStorageValue(Storage.TheShatteredIsles.TheCounterspell) == value + end + ) + counterspellKeyword:addChildKeyword( + {'yes'}, + StdModule.say, + {npcHandler = npcHandler, text = text[2], reset = true}, + function(player) + return player:getItemCount(itemId) > 0 + end, + function(player) + player:removeItem(itemId, 1) + player:setStorageValue(Storage.TheShatteredIsles.TheCounterspell, value + 1) + end + ) +end + +addCounterspellKeyword( + { + 'Did you bring the fresh dead chicken?', + "Very good! 'Your soul shall be protected!' Now, I need a fresh dead rat." + }, + 1, + 4265 +) +addCounterspellKeyword( + { + 'Did you bring the fresh dead rat?', + "Very good! 'You shall face black magic without fear!' Now, I need a fresh dead black sheep." + }, + 2, + 2813 +) +addCounterspellKeyword( + { + 'Did you bring the fresh dead black sheep?', + "Very good! 'EVIL POWERS SHALL NOT KEEP YOU ANYMORE! SO BE IT!'" + }, + 3, + 2914 +) + +-- Completed the Counterspell +keywordHandler:addKeyword( + {'counterspell'}, + StdModule.say, + { + npcHandler = npcHandler, + text = "Hm. I don't think you need another one of my counterspells to cross the barrier on Goroma." + } +) + +-- Spellbook +keywordHandler:addKeyword( + {'spellbook'}, + StdModule.say, + {npcHandler = npcHandler, text = "Ah, thank you very much! I'll honour his memory."}, + function(player) + return player:getItemCount(6120) > 0 + end, + function(player) + player:removeItem(6120, 1) + player:setStorageValue(Storage.TheShatteredIsles.DragahsSpellbook, 1) + end +) + +-- Energy Field +keywordHandler:addKeyword( + {'energy field'}, + StdModule.say, + { + npcHandler = npcHandler, + text = "Ah, the energy barrier set up by the cult is maintained by lousy magic, but it's still effective. \ + Without a proper counterspell, you won't be able to pass it." + } +) + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/chrak.lua b/data/npc/scripts/chrak.lua new file mode 100644 index 00000000000..59608e50a2c --- /dev/null +++ b/data/npc/scripts/chrak.lua @@ -0,0 +1,57 @@ + +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "battle") then + if player:getStorageValue(Storage.TheNewFrontier.Questline) == 24 then + npcHandler:say({ + "Zo you want to enter ze arena, you know ze rulez and zat zere will be no ozer option zan deaz or victory? ...", + "My mazter wantz to zurprize hiz opponentz by an unexpected move. He will uze warriorz from ze outzide, zomeone zat no one can azzezz. ...", + "One of ziz warriorz could be you. Or you could ztay here and rot in ze dungeon. Are you interezted in ziz deal?" + }, cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "mission") then + if player:getStorageValue(Storage.TheNewFrontier.Questline) == 26 then + npcHandler:say({ + "You have done ze impozzible and beaten ze champion. Your mazter will be pleazed. Hereby I cleanze ze poizon from your body. You are now allowed to leave. ...", + "For now ze mazter will zee zat you and your alliez are zpared of ze wraz of ze dragon emperor az you are unimportant for hiz goalz. ...", + "You may crawl back to your alliez and warn zem of ze gloriouz might of ze dragon emperor and hiz minionz." + }, cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 27) + player:setStorageValue(Storage.TheNewFrontier.Mission09, 3) --Questlog, The New Frontier Quest "Mission 09: Mortal Combat" + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Asss you wishzz.", cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 25) + player:setStorageValue(Storage.TheNewFrontier.Mission08, 2) --Questlog, The New Frontier Quest "Mission 08: An Offer You Can't Refuse" + player:setStorageValue(Storage.TheNewFrontier.Mission09, 1) --Questlog, The New Frontier Quest "Mission 09: Mortal Combat" + npcHandler.topic[cid] = 0 + end + end + return true +end +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/chraknpc.lua b/data/npc/scripts/chraknpc.lua new file mode 100644 index 00000000000..59608e50a2c --- /dev/null +++ b/data/npc/scripts/chraknpc.lua @@ -0,0 +1,57 @@ + +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "battle") then + if player:getStorageValue(Storage.TheNewFrontier.Questline) == 24 then + npcHandler:say({ + "Zo you want to enter ze arena, you know ze rulez and zat zere will be no ozer option zan deaz or victory? ...", + "My mazter wantz to zurprize hiz opponentz by an unexpected move. He will uze warriorz from ze outzide, zomeone zat no one can azzezz. ...", + "One of ziz warriorz could be you. Or you could ztay here and rot in ze dungeon. Are you interezted in ziz deal?" + }, cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "mission") then + if player:getStorageValue(Storage.TheNewFrontier.Questline) == 26 then + npcHandler:say({ + "You have done ze impozzible and beaten ze champion. Your mazter will be pleazed. Hereby I cleanze ze poizon from your body. You are now allowed to leave. ...", + "For now ze mazter will zee zat you and your alliez are zpared of ze wraz of ze dragon emperor az you are unimportant for hiz goalz. ...", + "You may crawl back to your alliez and warn zem of ze gloriouz might of ze dragon emperor and hiz minionz." + }, cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 27) + player:setStorageValue(Storage.TheNewFrontier.Mission09, 3) --Questlog, The New Frontier Quest "Mission 09: Mortal Combat" + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Asss you wishzz.", cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 25) + player:setStorageValue(Storage.TheNewFrontier.Mission08, 2) --Questlog, The New Frontier Quest "Mission 08: An Offer You Can't Refuse" + player:setStorageValue(Storage.TheNewFrontier.Mission09, 1) --Questlog, The New Frontier Quest "Mission 09: Mortal Combat" + npcHandler.topic[cid] = 0 + end + end + return true +end +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/christine.lua b/data/npc/scripts/christine.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/christine.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/christoph.lua b/data/npc/scripts/christoph.lua new file mode 100644 index 00000000000..e160dd39add --- /dev/null +++ b/data/npc/scripts/christoph.lua @@ -0,0 +1,38 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(10, 1000, -10) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if isInArray({"fuck", "idiot", "asshole", "ass", "fag", "stupid", "tyrant", "shit", "lunatic"}, msg) then + npcHandler:say("Take this!", cid) + local player = Player(cid) + player:getPosition():sendMagicEffect(CONST_ME_EXPLOSIONAREA) + player:addCondition(condition) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/chrystal.lua b/data/npc/scripts/chrystal.lua new file mode 100644 index 00000000000..a303a1f5fcd --- /dev/null +++ b/data/npc/scripts/chrystal.lua @@ -0,0 +1,45 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "measurements") then + if player:getStorageValue(Storage.Postman.Mission07) >= 1 and player:getStorageValue(Storage.Postman.MeasurementsChrystal) ~= 1 then + npcHandler:say("If its necessary ... ", cid) + player:setStorageValue(Storage.Postman.Mission07, player:getStorageValue(Storage.Postman.Mission07) + 1) + player:setStorageValue(Storage.Postman.MeasurementsChrystal, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("...", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:setMessage(MESSAGE_GREET, "At your service |PLAYERNAME| and welcome to the post office.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Who is next?") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Who is next?") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Here. Don't forget that you need to buy a label too if you want to send a parcel. Always write the name of the {receiver} in the first line.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/chuck_the_worker.lua b/data/npc/scripts/chuck_the_worker.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/chuck_the_worker.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/chuckles.lua b/data/npc/scripts/chuckles.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/chuckles.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/cillia.lua b/data/npc/scripts/cillia.lua new file mode 100644 index 00000000000..d7c76925979 --- /dev/null +++ b/data/npc/scripts/cillia.lua @@ -0,0 +1,44 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, 'yes') then + local player = Player(cid) + if not player:removeMoneyNpc(50) then + npcHandler:say('The exhibition is not for free. You have to pay 50 Gold to get in. Next please!', cid) + return true + end + + npcHandler:say('And here we go!', cid) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + local exhibitionPosition = Position(32390, 32195, 8) + player:teleportTo(exhibitionPosition) + exhibitionPosition:sendMagicEffect(CONST_ME_TELEPORT) + else + npcHandler:say('Then not.', cid) + end + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/cipfried.lua b/data/npc/scripts/cipfried.lua new file mode 100644 index 00000000000..4906153a729 --- /dev/null +++ b/data/npc/scripts/cipfried.lua @@ -0,0 +1,142 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Feeling lost, my child? Ask me for hints or help!' }, + { text = 'Come to me if you need healing!' }, + { text = 'Welcome to the temple of Rookgaard!' }, + { text = 'Don\'t despair! Help is near!' } +} +npcHandler:addModule(VoiceModule:new(voices)) + +local function greetCallback(cid) + local player = Player(cid) + local health = player:getHealth() + local lowHealth = health < 65 + local poisoned = player:getCondition(CONDITION_POISON) + if lowHealth or poisoned then + npcHandler:setMessage(MESSAGE_GREET, 'Hello, |PLAYERNAME|! You are looking really bad. Let me heal your wounds. It\'s my job after all.') + if lowHealth then player:addHealth(65 - health) end + if poisoned then player:removeCondition(CONDITION_POISON) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + else + npcHandler:setMessage(MESSAGE_GREET, 'Hello, |PLAYERNAME|! I\'ll {heal} you if you are injured or poisoned. Feel free to ask me for {help} or general {hints}.') + end + return true +end + +-- Basic keywords +keywordHandler:addKeyword({'hint'}, StdModule.rookgaardHints, {npcHandler = npcHandler}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Cipfried.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'Me? Oh, I\'m just a humble {monk}. Ask me if you need {help} or {healing}.'}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = 'Now it is |TIME|, my child.'}) +keywordHandler:addKeyword({'monk'}, StdModule.say, {npcHandler = npcHandler, text = 'I have sacrificed my life to serve the good gods of {Tibia} and to help newcomers in this world.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'You can deposit your money at the bank. That way you won\'t lose it if you get {killed}. The bank is just under the academy and to the right.'}) +keywordHandler:addKeyword({'destiny'}, StdModule.say, {npcHandler = npcHandler, text = 'Your near destiny will be to choose a {vocation} once you are level 8. Whether you will become a {knight}, {sorcerer}, {paladin} or {druid} is a big decision!'}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = 'That\'s where we are - the world of Tibia, in a village called {Rookgaard}, to be precise, with many {monsters}, {quests} and {citizens} around.'}) +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'How can I help you? I can tell you about specific {citizens} if you tell me their name. I can also give you general {hints} about {Tibia}. '}) +keywordHandler:addKeyword({'citizen'}, StdModule.say, {npcHandler = npcHandler, text = 'Only a few people live in our village, most of them are {merchants}. You can either ask them for a {trade} or about various other topics, like the names of other citizens, their {job} or Tibia in general.'}) +keywordHandler:addKeyword({'trade'}, StdModule.say, {npcHandler = npcHandler, text = 'I don\'t have any goods for trade, but if you ask one of the {merchants}, he or she will gladly show you what you can buy or sell.'}) +keywordHandler:addKeyword({'rat'}, StdModule.say, {npcHandler = npcHandler, text = 'A single rat doesn\'t pose a grave danger to you, but be careful not to get cornered by many of them. They could still {kill} you.'}) +keywordHandler:addKeyword({'spider'}, StdModule.say, {npcHandler = npcHandler, text = 'If you face spiders, beware of the {poisonous} ones. If you are poisoned, you will constantly lose health. Come to me and I\'ll heal you from poison.'}) +keywordHandler:addKeyword({'kill'}, StdModule.say, {npcHandler = npcHandler, text = 'If you get killed, you will revive in this temple. However, you will lose experience and also equipment, which can be quite painful. Take good care of yourself!'}) +keywordHandler:addKeyword({'poison'}, StdModule.say, {npcHandler = npcHandler, text = 'Poison is very dangerous! Don\'t ever drink green liquids, they are poisonous and will make you lose health!'}) +keywordHandler:addKeyword({'vocation'}, StdModule.say, {npcHandler = npcHandler, text = 'There are four vocations in Tibia: {knight}, {sorcerer}, {paladin} or {druid}. Each vocation has its unique special abilities.'}) +keywordHandler:addKeyword({'knight'}, StdModule.say, {npcHandler = npcHandler, text = 'Knights are close combat fighters. They usually wield melee weapons such as swords, axes or clubs.'}) +keywordHandler:addKeyword({'druid'}, StdModule.say, {npcHandler = npcHandler, text = 'Druids are nature magicians. Their speciality is casting ice and earth magic, as well as providing healing for others.'}) +keywordHandler:addKeyword({'paladin'}, StdModule.say, {npcHandler = npcHandler, text = 'Paladins are well-trained distance fighters and can cast holy magic. You will usually see them wearing bows or crossbows.'}) +keywordHandler:addKeyword({'sorcerer'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorcerers are elemental magicians. They have mastered fire, energy and death magic.'}) +keywordHandler:addKeyword({'shop'}, StdModule.say, {npcHandler = npcHandler, text = 'You can buy and sell goods from merchants. To do so, simply talk to them and ask them for a {trade}. They will gladly show you their offers and also the things they buy from you.'}) +keywordHandler:addKeyword({'equip'}, StdModule.say, {npcHandler = npcHandler, text = 'You can buy equipment from the {merchants} in this village once you earned some {gold}. Some {monsters} also carry equipment pieces with them.'}) +keywordHandler:addKeyword({'shovel'}, StdModule.say, {npcHandler = npcHandler, text = 'Shovels are very useful. There may be a hidden entrance under a loose pile of stone and without a shovel, how would you know?'}) +keywordHandler:addKeyword({'rope'}, StdModule.say, {npcHandler = npcHandler, text = 'Never go adventuring without a rope! If you don\'t have one when you fall through a hole in the ground, you won\'t be able to leave without a rope.'}) +keywordHandler:addKeyword({'weapon'}, StdModule.say, {npcHandler = npcHandler, text = 'To defend yourself against enemies, you will need a weapon. You can purchase weapons at {Obi}\'s shop.'}) +keywordHandler:addKeyword({'food'}, StdModule.say, {npcHandler = npcHandler, text = 'Food is very important for your health. If you are hurt in a fight with a {monster}, select \'Use\' on food such as cheese, ham or meat to eat it. This will slowly refill your health.'}) +keywordHandler:addKeyword({'premium'}, StdModule.say, {npcHandler = npcHandler, text = 'As a premium adventurer, you are an official tax payer and thus privileged in many ways. For example, you can travel by {ship} and get better deals from {merchants}.'}) +keywordHandler:addKeyword({'ship'}, StdModule.say, {npcHandler = npcHandler, text = {'Ships are a comfortable way of travelling to distant cities. At any harbour, you can board the ship and ask its captain where he sails to.', 'Travelling by ship will cost you some gold, though, so be sure to have money with you.'}}) +keywordHandler:addKeyword({'potion'}, StdModule.say, {npcHandler = npcHandler, text = 'Potions will come in handy once you are in a fight deep in a dungeon. If you aren\'t in immediate danger, you can simply eat {food} to regain health, though.'}) +keywordHandler:addKeyword({'academy'}, StdModule.say, {npcHandler = npcHandler, text = 'The academy is just north of here. You can learn helpful things there from {Seymour}, if you wish to!'}) +keywordHandler:addKeyword({'king'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, King Tibianus of course. The island of {Rookgaard} belongs to his kingdom.'}) +keywordHandler:addKeyword({'rookgaard'}, StdModule.say, {npcHandler = npcHandler, text = 'The {gods} have chosen this isle as the point of arrival for newborn souls. The {citizens} will help you if you ask them.'}) +keywordHandler:addKeyword({'god'}, StdModule.say, {npcHandler = npcHandler, text = 'They created {Tibia} and all life on it. Visit our {academy} and learn about them.'}) +keywordHandler:addKeyword({'monster'}, StdModule.say, {npcHandler = npcHandler, text = 'Monsters are a constant threat to this village. You would tremendously help us by fighting them, starting with {rats} in the {sewers}, then turning to {spiders} or {wolves}.'}) +keywordHandler:addKeyword({'merchant'}, StdModule.say, {npcHandler = npcHandler, text = 'You can buy and sell goods from merchants. To do so, simply talk to them and ask them for a {trade}. They will gladly show you their offers and also the things they buy from you.'}) +keywordHandler:addKeyword({'sewer'}, StdModule.say, {npcHandler = npcHandler, text = 'The sewers are right below this village. North of this temple, you find a sewer grate which leads down, but there are also many small huts in the village which are connected to the sewers.'}) + +keywordHandler:addKeyword({'buy'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sorry, but I\'m not interested in worldly goods. If you want to buy or sell something, you should ask a local merchant for a trade.'}) +keywordHandler:addAliasKeyword({'sell'}) + +keywordHandler:addKeyword({'shield'}, StdModule.say, {npcHandler = npcHandler, text = 'To defend yourself against enemies, you will need armor and shields. You can purchase both at {Dixi}\'s shop.'}) +keywordHandler:addAliasKeyword({'armor'}) + +keywordHandler:addKeyword({'money'}, StdModule.say, {npcHandler = npcHandler, text = 'You can earn a fair amount of gold by fighting {monsters} and picking up the things they carry. Many {citizens} are buying some of that loot, simply ask around.'}) +keywordHandler:addAliasKeyword({'gold'}) + +keywordHandler:addKeyword({'quest'}, StdModule.say, {npcHandler = npcHandler, text = 'Oh, I can handle my tasks myself, thank you. If you are looking for something to do, you should listen to the local {citizens} and ask them for {quests}. You could also help us fight {monsters}.'}) +keywordHandler:addAliasKeyword({'mission'}) + +keywordHandler:addKeyword({'wolf'}, StdModule.say, {npcHandler = npcHandler, text = 'Wolves can only be found outside of the village. If you want to know where their dens are, best talk to {Dallheim} or {Zerbrus} at the bridges.'}) +keywordHandler:addAliasKeyword({'wolves'}) + +keywordHandler:addKeyword({'adventure'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see a bright future for you... you will soon embark on a very big adventure and explore the world of {Tibia} - maybe even influence history!'}) +keywordHandler:addAliasKeyword({'explore'}) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are poisoned. I will help you.'}, + function(player) return player:getCondition(CONDITION_POISON) end, + function(player) + local health = player:getHealth() + if health < 65 then player:addHealth(65 - health) end + player:removeCondition(CONDITION_POISON) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'Let me heal your wounds.'}, + function(player) return player:getHealth() < 185 and player:getHealth() < player:getBaseMaxHealth() end, + function(player) + local health = player:getHealth() + player:addHealth(185 - health) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking really bad, |PLAYERNAME|. I can only help in cases of real emergencies. Raise your health simply by eating {food}.'}) + +-- Names +keywordHandler:addKeyword({'obi'}, StdModule.say, {npcHandler = npcHandler, text = 'Obi\'s {shop} is to the north-east of this humble temple. He sells {weapons}, and his granddaughter {Dixi} sells {armor} and {shields} upstairs.'}) +keywordHandler:addKeyword({'norma'}, StdModule.say, {npcHandler = npcHandler, text = 'She recently opened a little bar north of this village.'}) +keywordHandler:addKeyword({'loui'}, StdModule.say, {npcHandler = npcHandler, text = 'That\'s a sad story. He used to help me guard this temple, but for some reason he went out of his mind.'}) +keywordHandler:addKeyword({'santiago'}, StdModule.say, {npcHandler = npcHandler, text = 'I absolutely appreciate what he\'s doing. He has helped me a lot since he took up the job of welcoming newcomers to this island.'}) +keywordHandler:addKeyword({'zirella'}, StdModule.say, {npcHandler = npcHandler, text = 'That old lady hasn\'t had an easy life. Her son {Tom} completely abandoned her, but I have no idea why.'}) +keywordHandler:addKeyword({'al', 'dee'}, StdModule.say, {npcHandler = npcHandler, text = 'In Al Dee\'s shop you\'ll find important general equipment such as {ropes}, {shovels} and torches.'}) +keywordHandler:addKeyword({'amber'}, StdModule.say, {npcHandler = npcHandler, text = 'Amber is such a lovely girl, and also a very experienced {explorer} and {adventurer}. It\'s always interesting to chat with her.'}) +keywordHandler:addKeyword({'billy'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s a farmer, just like his cousin {Willie}. He doesn\'t talk to everybody, though.'}) +keywordHandler:addKeyword({'willie'}, StdModule.say, {npcHandler = npcHandler, text = 'Willie is a farmer, just like his cousin {Billy}. His farm is located left of the temple. You can buy and sell {food} there.'}) +keywordHandler:addKeyword({'cipfried'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes? How can I {help} you?'}) +keywordHandler:addKeyword({'dixi'}, StdModule.say, {npcHandler = npcHandler, text = 'That\'s {Obi\'s} granddaughter. Her counter is just upstairs from Obi\'s shop. She helps him by selling {armor} and {shields}.'}) +keywordHandler:addKeyword({'hyacinth'}, StdModule.say, {npcHandler = npcHandler, text = 'Hyacinth is a close friend of mine. He left the village many years ago to live in solitude. I think all this bustle here simply was too much for him.'}) +keywordHandler:addKeyword({'lee\'delle'}, StdModule.say, {npcHandler = npcHandler, text = 'Lee\'Delle\'s shop is on the {premium} side of the village. You should visit her!'}) +keywordHandler:addKeyword({'lily'}, StdModule.say, {npcHandler = npcHandler, text = 'You must have passed the house of Lily on your way here. She sells {potions}. If you pick blueberries or find cookies, she\'ll buy them from you.'}) +keywordHandler:addKeyword({'oracle'}, StdModule.say, {npcHandler = npcHandler, text = 'You can find the oracle on the top floor of the {academy}, just above {Seymour}. Go there when you are level 8 to find your {destiny}.'}) +keywordHandler:addKeyword({'paulie'}, StdModule.say, {npcHandler = npcHandler, text = 'He is the {bank} clerk, making sure your {money} remains safe.'}) +keywordHandler:addKeyword({'seymour'}, StdModule.say, {npcHandler = npcHandler, text = 'Seymour is a loyal follower of the {king} and a teacher in the {academy}.'}) +keywordHandler:addKeyword({'tom'}, StdModule.say, {npcHandler = npcHandler, text = 'Tom is the main provider for leather armor in this village. You can sell fresh corpses or even minotaur leather to him.'}) +keywordHandler:addKeyword({'dallheim'}, StdModule.say, {npcHandler = npcHandler, text = 'May the gods bless our loyal guardsmen! Day and night they stand watch on our bridges, ensuring that it is not passed by dangerous {monsters}!'}) +keywordHandler:addAliasKeyword({'zerbrus'}) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Farewell, |PLAYERNAME|!') +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/clark.lua b/data/npc/scripts/clark.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/clark.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/cledwyn.lua b/data/npc/scripts/cledwyn.lua new file mode 100644 index 00000000000..80f2f3c90d5 --- /dev/null +++ b/data/npc/scripts/cledwyn.lua @@ -0,0 +1,192 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) +local talkState = {} + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local shop = { + {id=25177, buy=100, sell=0, name='earthheart cuirass'}, + {id=25178, buy=100, sell=0, name='earthheart hauberk'}, + {id=25179, buy=100, sell=0, name='earthheart platemail'}, + {id=25191, buy=100, sell=0, name='earthmind raiment'}, + {id=25187, buy=100, sell=0, name='earthsoul tabard'}, + {id=25174, buy=100, sell=0, name='fireheart cuirass'}, + {id=25175, buy=100, sell=0, name='fireheart hauberk'}, + {id=25176, buy=100, sell=0, name='fireheart platemail'}, + {id=25190, buy=100, sell=0, name='firemind raiment'}, + {id=25186, buy=100, sell=0, name='firesoul tabard'}, + {id=25183, buy=100, sell=0, name='frostheart cuirass'}, + {id=25184, buy=100, sell=0, name='frostheart hauberk'}, + {id=25185, buy=100, sell=0, name='frostheart platemail'}, + {id=25193, buy=100, sell=0, name='frostmind raiment'}, + {id=25189, buy=100, sell=0, name='frostsoul tabard'}, + {id=40398, buy=1, sell=0, name='magic shield potion'}, + {id=25180, buy=100, sell=0, name='thunderheart cuirass'}, + {id=25181, buy=100, sell=0, name='thunderheart hauberk'}, + {id=25182, buy=100, sell=0, name='thunderheart platemail'}, + {id=25192, buy=100, sell=0, name='thundermind raiment'}, + {id=25188, buy=100, sell=0, name='thundersoul tabard'}, +} + +local function setNewTradeTable(table) + local items, item = {} + for i = 1, #table do + item = table[i] + items[item.id] = {id = item.id, buy = item.buy, sell = item.sell, subType = 0, name = item.name} + end + return items +end + +local function onBuy(cid, item, subType, amount, ignoreCap, inBackpacks) + local player = Player(cid) + local itemsTable = setNewTradeTable(shop) + if not ignoreCap and player:getFreeCapacity() < ItemType(itemsTable[item].id):getWeight(amount) then + return player:sendTextMessage(MESSAGE_FAILURE, "You don't have enough cap.") + end + if itemsTable[item].buy then + if player:removeItem(Npc():getCurrency(), amount * itemsTable[item].buy) then + if amount > 1 then + currencyName = ItemType(Npc():getCurrency()):getPluralName():lower() + else + currencyName = ItemType(Npc():getCurrency()):getName():lower() + end + player:addItem(itemsTable[item].id, amount) + return player:sendTextMessage(MESSAGE_TRADE, + "Bought "..amount.."x "..itemsTable[item].name.." for "..itemsTable[item].buy * amount.." "..currencyName..".") + else + return player:sendTextMessage(MESSAGE_FAILURE, "You don't have enough "..currencyName..".") + end + end + + return true +end + +local function onSell(cid, item, subType, amount, ignoreCap, inBackpacks) + return true +end + +local chargeItem = { + ['pendulet'] = {noChargeID = 34067, ChargeID = 34983}, + ['sleep shawl'] = {noChargeID = 34066, ChargeID = 34981}, + ['blister ring'] = {noChargeID = 36392, ChargeID = 36456}, + ['theurgic amulet'] = {noChargeID = 35236, ChargeID = 35238}, + ['ring of souls'] = {noChargeID = 37456, ChargeID = 37471} +} + +local function greetCallback(cid) + return true +end + +local voices = { + { text = 'Trading tokens! First-class bargains!' }, + { text = 'Bespoke armor for all vocations! For the cost of some tokens only!' }, + { text = 'Tokens! Bring your tokens!' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if not player then + return false + end + if msgcontains(msg, 'token') or msgcontains(msg, 'tokens') then + npcHandler:say("If you have any {silver} tokens with you, let's have a look! Maybe I can offer you something in exchange.", cid) + elseif msgcontains(msg, 'information') then + npcHandler:say("With pleasure. I trade {token}s. There are several ways to obtain the {token}s I am interested in - killing certain bosses, for example. In exchange for a certain amount of tokens, I can offer you some first-class items.", cid) + elseif msgcontains(msg, 'talk') then + npcHandler:say({"Why, certainly! I'm always up for some small talk. ...", + "The weather continues just fine here, don't you think? Just the day for a little walk around the town! ...", + "Actually, I haven't been around much yet, but I'm looking forward to exploring the city once I've finished trading {token}s."}, cid) + elseif msgcontains(msg, 'silver') then + openShopWindow(cid, shop, onBuy, onSell) + npcHandler:say({"Here's the deal, " .. player:getName() .. ". For 100 of your silver tokens, I can offer you some first-class torso armor. These armors provide a solid boost to your main attack skill, as well as ...", + "some elemental protection of your choice! I also sell a magic shield potion for one silver token. So these are my offers."}, cid) + elseif msgcontains(msg, 'enchant') then + npcHandler:say("The following items can be enchanted: {pendulet}, {sleep shawl}, {blister ring}, {theurgic amulet}. Make you choice!", cid) + npcHandler.topic[cid] = 1 + elseif isInArray({'pendulet', 'sleep shawl', 'blister ring', 'theurgic amulet'}, msg:lower()) and npcHandler.topic[cid] == 1 then + npcHandler:say("Should I enchant the item pendulet for 2 ".. ItemType(Npc():getCurrency()):getPluralName():lower() .."?", cid) + charge = msg:lower() + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, 'yes') then + if not chargeItem[charge] then + npcHandler:say("Sorry, you don't have an unenchanted ".. charge ..".",cid) + else + if (player:getItemCount(Npc():getCurrency()) >= 2) and (player:getItemCount(chargeItem[charge].noChargeID) >= 1) then + player:removeItem(Npc():getCurrency(), 2) + player:removeItem(chargeItem[charge].noChargeID, 1) + local itemAdd = player:addItem(chargeItem[charge].ChargeID, 1) + npcHandler:say("Ah, excellent. Here is your " .. itemAdd:getName():lower() .. ".", cid) + else + npcHandler:say("Sorry, friend, but one good turn deserves another. Bring enough ".. ItemType(Npc():getCurrency()):getPluralName():lower() .." and it's a deal.", cid) + end + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'no') then + npcHandler:say("Alright, come back if you have changed your mind.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'addon') then + if player:hasOutfit(846, 0) or player:hasOutfit(845, 0) then + npcHandler:say("Ah, very good. Now choose your addon: {first} or {second}.", cid) + npcHandler.topic[cid] = 3 + else + npcHandler:say("Sorry, friend, but one good turn deserves another. You need to obtain the rift warrior outfit first.", cid) + end + elseif isInArray({'first', 'second'}, msg:lower()) and npcHandler.topic[cid] == 3 then + if msg:lower() == 'first' then + if not(player:hasOutfit(846, 1)) and not(player:hasOutfit(845, 1)) then + if player:removeItem(25172, 100) then + npcHandler:say("Ah, excellent. Obtain the first addon for your rift warrior outfit.", cid) + player:addOutfitAddon(846, 1) + player:addOutfitAddon(845, 1) + if (player:hasOutfit(846, 1) or player:hasOutfit(845, 1)) and (player:hasOutfit(846, 2) or player:hasOutfit(845, 2)) then + player:addAchievement("Rift Warrior") + end + else + npcHandler:say("Sorry, friend, but one good turn deserves another. Bring enough ".. ItemType(Npc():getCurrency()):getPluralName():lower() .." and it's a deal.", cid) + end + else + npcHandler:say("Sorry, friend, you already have the first Rift Warrior addon.", cid) + end + elseif msg:lower() == 'second' then + if not(player:hasOutfit(846, 2)) and not(player:hasOutfit(845, 2)) then + if player:removeItem(25172, 100) then + npcHandler:say("Ah, excellent. Obtain the second addon for your rift warrior outfit.", cid) + player:addOutfitAddon(846, 2) + player:addOutfitAddon(845, 2) + if (player:hasOutfit(846, 1) or player:hasOutfit(845, 1)) and (player:hasOutfit(846, 2) or player:hasOutfit(845, 2)) then + player:addAchievement("Rift Warrior") + end + else + npcHandler:say("Sorry, friend, but one good turn deserves another. Bring enough ".. ItemType(Npc():getCurrency()):getPluralName():lower() .." and it's a deal.", cid) + end + else + npcHandler:say("Sorry, friend, you already have the second Rift Warrior addon.", cid) + end + end + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/clyde.lua b/data/npc/scripts/clyde.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/clyde.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/cobra.lua b/data/npc/scripts/cobra.lua new file mode 100644 index 00000000000..703ae7551e2 --- /dev/null +++ b/data/npc/scripts/cobra.lua @@ -0,0 +1,34 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + local player = Player(cid) + if player:getCondition(CONDITION_POISON) then + player:sendTextMessage(MESSAGE_GAME_HIGHLIGHT, "Venture the path of decay!") + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(Position(33396, 32836, 14)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return false + else + npcHandler:say("Begone! Hissssss! You bear not the mark of the cobra!", cid) + return false + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/cold_percht_sleigh.lua b/data/npc/scripts/cold_percht_sleigh.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/cold_percht_sleigh.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/coltrayne.lua b/data/npc/scripts/coltrayne.lua new file mode 100644 index 00000000000..f165cc7fdec --- /dev/null +++ b/data/npc/scripts/coltrayne.lua @@ -0,0 +1,110 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + {text = "Team up with others to defeat monsters!"}, + {text = "Get your gear and help us defend Dawnport against the monsters!"}, + {text = "Better weapons equal more damage - get yourself some gear right here!"}, + {text = "Gird youselves! Chain mail, bows, spears, swords - we've got it all!"}, + {text = "Skill comes with practice - get out there and kill some beasts!"} +} + +npcHandler:addModule(VoiceModule:new(voices)) + +keywordHandler:addKeyword({'name'}, StdModule.say, + { + npcHandler = npcHandler, + text = "Coltrayne Daggard. Just ask me for a trade to see the latest in chain mail and weapons." + } +) +keywordHandler:addKeyword({'job'}, StdModule.say, + { + npcHandler = npcHandler, + text = "I'm a blacksmith by trade. Want to keep our lads and lasses safe and equipped with a sharp blade, me." + } +) +keywordHandler:addKeyword({'rookgaard'}, StdModule.say, + { + npcHandler = npcHandler, + text = "You mean to imply I am an inexperienced guardian? Get out of here." + } +) +keywordHandler:addKeyword({'coltrayne'}, StdModule.say, + { + npcHandler = npcHandler, + text = " Yes. You wish to trade I guess. At least, you look like you could use some good gear, kid." + } +) +keywordHandler:addKeyword({'hamish'}, StdModule.say, + { + npcHandler = npcHandler, + text = "Good at potions. Likes experimenting. Can kit you out with magical equipment for a hunt." + } +) +keywordHandler:addKeyword({'inigo'}, StdModule.say, + { + npcHandler = npcHandler, + text = "Gives newcomers hints how we do things here in Tibia. Don't know how to use something? Ask Inigo." + } +) +keywordHandler:addKeyword({'garamond'}, StdModule.say, + { + npcHandler = npcHandler, + text = "Don't have much to say about him. Barely know him. Seems a decent spell teacher for mages." + } +) +keywordHandler:addKeyword({'ser tybald'}, StdModule.say, + { + npcHandler = npcHandler, + text = "I'm sure I've seen his face before somewhere... \z + never mind. Anyway, he's the knight and paladin spell teacher around here, letting you try them out for free. \z + Don't underestimate the use of spells, even if you're not a mage." + } +) +keywordHandler:addKeyword({'richard'}, StdModule.say, + { + npcHandler = npcHandler, + text = "He's just in the next shop to the left, selling food and equipment \z + like ropes and shovels and fishing rods and such." + } +) +keywordHandler:addKeyword({'mr morris'}, StdModule.say, + { + npcHandler = npcHandler, + text = "He had a plan, as usual. Came here, set up the outpost, managed everything. \z + Looking for a task or quest? He's your man." + } +) +keywordHandler:addKeyword({'oressa'}, StdModule.say, + { + npcHandler = npcHandler, + text = "She's our local healer. Downstairs in the temple and oracle room, that's where she is. \z + Just say 'heal' or 'help' and she'll help ya if you really need it." + } +) +keywordHandler:addKeyword({'plunderpurse'}, StdModule.say, + { + npcHandler = npcHandler, + text = "Pirates and gold, you get the rest. Hoards gold now for young adventurers - \z + keeps it safe while you go out hunting." + } +) + +npcHandler:setMessage(MESSAGE_GREET, "Hey there. Need some armor or weapon? Then ask me for a {trade}.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Yeah, bye..") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/commander_stone.lua b/data/npc/scripts/commander_stone.lua new file mode 100644 index 00000000000..09cfb0978fc --- /dev/null +++ b/data/npc/scripts/commander_stone.lua @@ -0,0 +1,200 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if(msgcontains(msg, "mission")) then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) == 25 then + npcHandler:say({"Two missions are available for your {rank}: crystal {keeper} and {spark} hunting. You can undertake each mission but you can turn in a specific mission only once each 20 hours. ...", + "If you lose a mission item you can probably buy it from Gnomally."}, cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.BigfootBurden.QuestLine) >= 26 then + npcHandler:say({"For your {rank} there are four missions avaliable: crystal {keeper}, {spark} hunting, monster {extermination} and mushroom {digging}. By the way, you {rank} now allows you to take aditional missions from {Gnomeral} in {Gnomebase Alpha}. ... ", "If you lose a mission item you can probably buy it from Gnomally."}, cid) + npcHandler.topic[cid] = 0 + end + + -- Crystal Kepper + elseif msgcontains(msg, "keeper") then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) >= 25 then + if player:getStorageValue(Storage.BigfootBurden.MissionCrystalKeeper) < 1 and player:getStorageValue(Storage.BigfootBurden.CrystalKeeperTimout) < os.time() then + npcHandler:say("You will have to repair some damaged crystals. Go into the Crystal grounds and repair them, using this harmonic crystal. Repair five of them and return to me. ", cid) + player:setStorageValue(Storage.BigfootBurden.MissionCrystalKeeper, 1) + player:setStorageValue(Storage.BigfootBurden.RepairedCrystalCount, 0) + player:addItem(18219, 1) --- taking missions + elseif player:getStorageValue(Storage.BigfootBurden.CrystalKeeperTimout) > os.time() then -- trying to take mission while in cooldown + npcHandler:say("Sorry, you will have to wait before you can undertake this mission again.", cid) + elseif player:getStorageValue(Storage.BigfootBurden.MissionCrystalKeeper) > 0 then -- reporting mission + if player:getStorageValue(Storage.BigfootBurden.RepairedCrystalCount) >= 5 then -- can report missions + player:removeItem(18219, 1) + player:setStorageValue(Storage.BigfootBurden.Rank, player:getStorageValue(Storage.BigfootBurden.Rank) + 5) + player:addItem(18422, 1) + player:addItem(18215, 1) + player:setStorageValue(Storage.BigfootBurden.MissionCrystalKeeper, 0) + player:setStorageValue(Storage.BigfootBurden.CrystalKeeperTimout, os.time() + 20 * 60 * 60) + player:setStorageValue(Storage.BigfootBurden.RepairedCrystalCount, -1) + player:addAchievement('Crystal Keeper') + player:checkGnomeRank() + npcHandler:say("You did well. That will help us a lot. Take your {token} and this gnomish supply package as a reward. ", cid) + npcHandler.topic[cid] = 0 + else -- haven't finished + if npcHandler.topic[cid] >= 1 then + npcHandler:say("You are not done yet.", cid) -- is reporting + else + npcHandler:say("You already have accepted this mission. Don't forget to {report} to me when you are done.", cid) -- se nao tiver reportando + end + npcHandler.topic[cid] = 0 + end + end + else + npcHandler:say("Sorry, you do have not have the required rank to undertake this mission.", cid) + end + -- Crystal Keeper + + -- Raiders of the Lost Spark + elseif msgcontains(msg, "spark") then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) >= 25 then + if player:getStorageValue(Storage.BigfootBurden.MissionRaidersOfTheLostSpark) < 1 and player:getStorageValue(Storage.BigfootBurden.RaidersOfTheLostSparkTimeout) < os.time() then + npcHandler:say({"Take this extractor and drive it into a body of a slain crystal crusher. This will charge your own body with energy sparks. Charge it with seven sparks and return to me. ...", + "Don't worry. The gnomes assured me you'd be save. That is if nothing strange or unusual occurs! "}, cid) + player:setStorageValue(Storage.BigfootBurden.MissionRaidersOfTheLostSpark, 1) + player:setStorageValue(Storage.BigfootBurden.ExtractedCount, 0) + player:addItem(18213, 1) --- taking missions + elseif player:getStorageValue(Storage.BigfootBurden.RaidersOfTheLostSparkTimeout) > os.time() then -- trying to take mission while in cooldown + npcHandler:say("Sorry, you will have to wait before you can undertake this mission again.", cid) + elseif player:getStorageValue(Storage.BigfootBurden.MissionRaidersOfTheLostSpark) > 0 then -- reporting mission + if player:getStorageValue(Storage.BigfootBurden.ExtractedCount) >= 7 then -- can report missions + player:setStorageValue(Storage.BigfootBurden.Rank, player:getStorageValue(Storage.BigfootBurden.Rank) + 5) + player:removeItem(18213, 1) + player:addItem(18422, 1) + player:addItem(18215, 1) + player:setStorageValue(Storage.BigfootBurden.MissionRaidersOfTheLostSpark, 0) + player:setStorageValue(Storage.BigfootBurden.ExtractedCount, -1) + player:setStorageValue(Storage.BigfootBurden.RaidersOfTheLostSparkTimeout, os.time() + 20 * 60 * 60) + player:addAchievement('Call Me Sparky') + player:checkGnomeRank() + npcHandler:say("You did well. That will help us a lot. Take your {token} and this gnomish supply package as a reward. ", cid) + npcHandler.topic[cid] = 0 + else -- haven't finished + if npcHandler.topic[cid] >= 1 then + npcHandler:say("You did not draw enough energy from Crystal Crushers or you have not asked for this task.", cid) -- is reporting + else + npcHandler:say("You already have accepted this mission. Don't forget to {report} to me when you are done.", cid) -- se nao tiver reportando + end + npcHandler.topic[cid] = 0 + end + end + else + npcHandler:say("Sorry, you do have not have the required rank to undertake this mission.", cid) + end + -- Raiders of the Lost Spark + + -- Exterminators + elseif msgcontains(msg, "extermination") then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) >= 26 then + if player:getStorageValue(Storage.BigfootBurden.MissionExterminators) < 1 and player:getStorageValue(Storage.BigfootBurden.ExterminatorsTimeout) < os.time() then + npcHandler:say("The wigglers have become a pest that threaten our resources and supplies. Kill 10 wigglers in the caves like the mushroon gardens or the truffles ground. {Report} back to me when you are done. ", cid) + player:setStorageValue(Storage.BigfootBurden.MissionExterminators, 1) + player:setStorageValue(Storage.BigfootBurden.ExterminatedCount, 0) --- taking missions + elseif player:getStorageValue(Storage.BigfootBurden.ExterminatorsTimeout) > os.time() then -- trying to take mission while in cooldown + npcHandler:say("Sorry, you will have to wait before you can undertake this mission again.", cid) + elseif player:getStorageValue(Storage.BigfootBurden.MissionExterminators) > 0 then -- reporting mission + if player:getStorageValue(Storage.BigfootBurden.ExterminatedCount) >= 10 then -- can report missions + player:setStorageValue(Storage.BigfootBurden.Rank, player:getStorageValue(Storage.BigfootBurden.Rank) + 5) + player:addItem(18422, 1) + player:addItem(18215, 1) + player:setStorageValue(Storage.BigfootBurden.MissionExterminators, 0) + player:setStorageValue(Storage.BigfootBurden.ExterminatedCount, -1) + player:setStorageValue(Storage.BigfootBurden.ExterminatorsTimeout, os.time() + 20 * 60 * 60) + player:addAchievement('One Foot Vs. Many') + player:checkGnomeRank() + npcHandler:say("You did well. That will help us a lot. Take your {token} and this gnomish supply package as a reward. ", cid) + npcHandler.topic[cid] = 0 + else -- haven't finished + if npcHandler.topic[cid] >= 1 then + npcHandler:say("You are not done yet.", cid) -- is reporting + else + npcHandler:say("You already have accepted this mission. Don't forget to {report} to me when you are done.", cid) -- se nao tiver reportando + end + npcHandler.topic[cid] = 0 + end + end + else + npcHandler:say("Sorry, you do have not have the required rank to undertake this mission.", cid) + end + -- Exterminators + + -- Mushroom Digger + elseif msgcontains(msg, "digging") then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) >= 26 then + if player:getStorageValue(Storage.BigfootBurden.MissionMushroomDigger) < 1 and player:getStorageValue(Storage.BigfootBurden.MushroomDiggerTimeout) < os.time() then + npcHandler:say({ + "Take this little piggy here. It will one day become a great mushroom hunter for sure. For now it is depended on you and other pigs. ...", + "Well, other pigs like it is one, I mean. I was of course not comparing you with a pig! Go to the truffles area and follow the truffle pigs there. If they dig up some truffles, let the little pig eat the mushrooms. ...", + "You'll have to feed it three times. Then return it to me. ...", + "Keep in mind that the pig has to be returned to his mother after a while. If you don't do this, the gnomes will call it back via teleport crystals." + }, cid) + player:setStorageValue(Storage.BigfootBurden.MissionMushroomDigger, 1) + player:setStorageValue(Storage.BigfootBurden.MushroomCount, 0) + player:addItem(18339, 1) --- taking missions + elseif player:getStorageValue(Storage.BigfootBurden.MushroomDiggerTimeout) > os.time() then -- trying to take mission while in cooldown + npcHandler:say("Sorry, you will have to wait before you can undertake this mission again.", cid) + elseif player:getStorageValue(Storage.BigfootBurden.MissionMushroomDigger) > 0 then -- reporting mission + if player:getStorageValue(Storage.BigfootBurden.MushroomCount) >= 3 then -- can report missions + player:removeItem(18339, 1) + player:setStorageValue(Storage.BigfootBurden.Rank, player:getStorageValue(Storage.BigfootBurden.Rank) + 5) + player:addItem(18422, 1) + player:addItem(18215, 1) + player:setStorageValue(Storage.BigfootBurden.MissionMushroomDigger, 0) + player:setStorageValue(Storage.BigfootBurden.MushroomCount, -1) + player:setStorageValue(Storage.BigfootBurden.MushroomDiggerTimeout, os.time() + 20 * 60 * 60) + player:addAchievement('The Picky Pig') + player:checkGnomeRank() + npcHandler:say("You did well. That will help us a lot. Take your {token} and this gnomish supply package as a reward. ", cid) + npcHandler.topic[cid] = 0 + else -- haven't finished + if npcHandler.topic[cid] >= 1 then + npcHandler:say("You are not done yet.", cid) -- is reporting + else + npcHandler:say("You already have accepted this mission. Don't forget to {report} to me when you are done.", cid) -- se nao tiver reportando + end + npcHandler.topic[cid] = 0 + end + end + else + npcHandler:say("Sorry, you do have not have the required rank to undertake this mission.", cid) + end + -- Mushroom Digger + + elseif(msgcontains(msg, "report")) then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) == 25 then + npcHandler:say("Which mission do you want to report: crystal {keeper}, {spark} hunting?", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.BigfootBurden.QuestLine) >= 26 then + npcHandler:say("Which mission do you want to report: crystal {keeper}, {spark} hunting, monster {extermination} or mushroom {digging}?", cid) + npcHandler.topic[cid] = 2 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/cornelia.lua b/data/npc/scripts/cornelia.lua new file mode 100644 index 00000000000..6b199ac6163 --- /dev/null +++ b/data/npc/scripts/cornelia.lua @@ -0,0 +1,55 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Quality armors for sale!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I run this armoury. If you want to protect your life, you better buy my wares."}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if isInArray({"addon", "armor"}, msg) then + if player:getStorageValue(Storage.OutfitQuest.WarriorShoulderAddon) == 5 then + player:setStorageValue(Storage.OutfitQuest.WarriorShoulderAddon, 6) + player:setStorageValue(Storage.OutfitQuest.WarriorShoulderTimer, os.time() + (player:getSex() == PLAYERSEX_FEMALE and 3600 or 7200)) + npcHandler:say('Ah, you must be the hero Trisha talked about. I\'ll prepare the shoulder spikes for you. Please give me some time to finish.', cid) + elseif player:getStorageValue(Storage.OutfitQuest.WarriorShoulderAddon) == 6 then + if player:getStorageValue(Storage.OutfitQuest.WarriorShoulderTimer) > os.time() then + npcHandler:say('I\'m not done yet. Please be as patient as you are courageous.', cid) + elseif player:getStorageValue(Storage.OutfitQuest.WarriorShoulderTimer) > 0 and player:getStorageValue(Storage.OutfitQuest.WarriorShoulderTimer) < os.time() then + player:addOutfitAddon(142, 1) + player:addOutfitAddon(134, 1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:setStorageValue(Storage.OutfitQuest.WarriorShoulderAddon, 7) + player:addAchievementProgress('Wild Warrior', 2) + npcHandler:say('Finished! Since you are a man, I thought you probably wanted two. Men always want that little extra status symbol. ', cid) + else + npcHandler:say('I\'m selling leather armor, chain armor, and brass armor. Ask me for a {trade} if you like to take a look.', cid) + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "Welcome to the finest {armor} shop in the land, |PLAYERNAME|!") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye. Come back soon.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/cornell.lua b/data/npc/scripts/cornell.lua new file mode 100644 index 00000000000..a4d21d7e156 --- /dev/null +++ b/data/npc/scripts/cornell.lua @@ -0,0 +1,39 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Passage to Grimvale and Edron.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, cost, destination, action) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, discount = 'postman', destination = destination}, nil, action) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('grimvale', 100, Position(33341, 31691, 7)) +addTravelKeyword('edron', 100, Position(33304, 31719, 7)) + +-- Kick + +-- Basic +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = 'I can travel you to {Grimvale} or {Edron}.'}) +npcHandler:setMessage(MESSAGE_GREET, 'Welcome on board, |PLAYERNAME|. Where can I {sail} you today, to {Grimvale} or {Edron}?') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye. Recommend us if you were satisfied with our service.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye then.') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/corym_ratter.lua b/data/npc/scripts/corym_ratter.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/corym_ratter.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/corym_servant.lua b/data/npc/scripts/corym_servant.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/corym_servant.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/costello.lua b/data/npc/scripts/costello.lua new file mode 100644 index 00000000000..089435df8de --- /dev/null +++ b/data/npc/scripts/costello.lua @@ -0,0 +1,86 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'fugio') then + if player:getStorageValue(Storage.Quest.SimpleChest.FamilyBrooch) == 1 then + npcHandler:say('To be honest, I fear the omen in my dreams may be true. \z + Perhaps Fugio is unable to see the danger down there. \z + Perhaps ... you are willing to investigate this matter?', cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, 'diary') then + if player:getStorageValue(Storage.WhiteRavenMonastery.Diary) == 1 then + npcHandler:say('Do you want me to inspect a diary?', cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, 'holy water') then + local cStorage = player:getStorageValue(Storage.TibiaTales.RestInHallowedGround.Questline) + if cStorage == 1 then + npcHandler:say('Who are you to demand holy water from the White Raven Monastery? Who sent you??', cid) + npcHandler.topic[cid] = 3 + elseif cStorage == 2 then + npcHandler:say('I already filled your vial with holy water.', cid) + end + elseif msgcontains(msg, 'amanda') and npcHandler.topic[cid] == 0 then + if player:getStorageValue(Storage.TibiaTales.RestInHallowedGround.Questline) == 1 then + npcHandler:say('Ahh, Amanda from Edron sent you! I hope she\'s doing well. So why did she send you here?', cid) + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + npcHandler:say('Thank you very much! From now on you may open the warded doors to the catacombs.', cid) + player:setStorageValue(Storage.WhiteRavenMonastery.Diary, 1) + player:setStorageValue(Storage.WhiteRavenMonastery.Door, 1) + elseif npcHandler.topic[cid] == 2 then + if not player:removeItem(2325, 1) then + npcHandler:say('Uhm, as you wish.', cid) + return true + end + + npcHandler:say('By the gods! This is brother Fugio\'s handwriting and what I read is horrible indeed! You have done our order a great favour by giving this diary to me! Take this blessed Ankh. May it protect you in even your darkest hours.', cid) + player:addItem(2327, 1) + player:setStorageValue(Storage.WhiteRavenMonastery.Diary, 2) + end + elseif npcHandler.topic[cid] == 3 then + if not msgcontains(msg, 'amanda') then + npcHandler:say('I never heard that name and you won\'t get holy water for some stranger.', cid) + npcHandler.topic[cid] = 0 + return true + end + + player:addItem(7494, 1) + player:setStorageValue(Storage.TibiaTales.RestInHallowedGround.Questline, 2) + npcHandler:say('Ohh, why didn\'t you tell me before? Sure you get some holy water if it\'s for Amanda! Here you are.', cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') and isInArray({1, 2}, npcHandler.topic[cid]) then + npcHandler:say('Uhm, as you wish.', cid) + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Welcome, |PLAYERNAME|! Feel free to tell me what has brought you here.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye. Come back soon.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/cranky_lizard_crone.lua b/data/npc/scripts/cranky_lizard_crone.lua new file mode 100644 index 00000000000..d1d295fa8df --- /dev/null +++ b/data/npc/scripts/cranky_lizard_crone.lua @@ -0,0 +1,100 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Storage IDs -- +storage = Storage.WayfarerOutfit + +newaddon = 'Here you are, enjoy your brand new addon!' +noitems = 'You do not have all the required items.' +noitems2 = 'You do not have all the required items or you do not have the first addon, which by the way, is a requirement for this addon.' +already = 'It seems you already have this addon, don\'t you try to mock me son!' + + +--WAYFARER START -- +function WayfarerFirst(cid, message, keywords, parameters, node) + if(not npcHandler:isFocused(cid)) then + return false + end + + if isPremium(cid) then + addon = getPlayerStorageValue(cid,storage) + if addon == -1 then + if getPlayerItemCount(cid,12657) >= 1 then + if doPlayerRemoveItem(cid,12657,1) then + npcHandler:say(newaddon, cid) + doSendMagicEffect(getCreaturePosition(cid), 13) + doPlayerAddOutfit(cid, 366, 1) + doPlayerAddOutfit(cid, 367, 1) + setPlayerStorageValue(cid,storage,1) + end + else + npcHandler:say(noitems, cid) + end + else + npcHandler:say(already, cid) + end + end +end + +function WayfarerSecond(cid, message, keywords, parameters, node) + if(not npcHandler:isFocused(cid)) then + return false + end + + if isPremium(cid) then + addon = getPlayerStorageValue(cid,storage+1) + if addon == -1 then + if getPlayerItemCount(cid,12656) >= 1 then + if doPlayerRemoveItem(cid,12656,1) then + npcHandler:say(newaddon, cid) + doSendMagicEffect(getCreaturePosition(cid), 13) + doPlayerAddOutfit(cid, 366, 2) + doPlayerAddOutfit(cid, 367, 2) + setPlayerStorageValue(cid,storage + 1, 1) + end + else + npcHandler:say(noitems, cid) + end + else + npcHandler:say(already, cid) + end + end + +end +-- WAYFARER END -- + + +keywordHandler:addKeyword({'addons'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = "I can offer you first & second addons of the following outfit: {Wayfarer}."}) + +keywordHandler:addKeyword({'storage'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = "Ask about {first addon} or {second addon}."}) + +keywordHandler:addKeyword({'outfit'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = "Ask about {first addon} or {second addon}."}) + +keywordHandler:addKeyword({'mission'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = "Ask about {first addon} or {second addon}."}) + +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = "llected all the required pieces, say 'yes' and voila - you got yourself an addon!"}) + + node1 = keywordHandler:addKeyword({'first addon'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'To achieve the first storage addon you need to give me the Old Cape. Do you have them with you?'}) + node1:addChildKeyword({'yes'}, WayfarerFirst, {}) + node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Alright then. Come back when you got all neccessary items.', reset = true}) + + node2 = keywordHandler:addKeyword({'second addon'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'To achieve the second storage addon you need to give me the Sedge Hat. Do you have them with you?'}) + node2:addChildKeyword({'yes'}, WayfarerSecond, {}) + node2:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Alright then. Come back when you got all neccessary items.', reset = true}) + + + npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/crowned_tree.lua b/data/npc/scripts/crowned_tree.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/crowned_tree.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/cruleo.lua b/data/npc/scripts/cruleo.lua new file mode 100644 index 00000000000..70ebd3639ca --- /dev/null +++ b/data/npc/scripts/cruleo.lua @@ -0,0 +1,25 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = '' }, + { text = 'This will earn me some handsome amount of gold!' }, + { text = 'Muhahaha!' } +} + +npcHandler:addModule(VoiceModule:new(voices)) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/curos.lua b/data/npc/scripts/curos.lua new file mode 100644 index 00000000000..96d81afcdfc --- /dev/null +++ b/data/npc/scripts/curos.lua @@ -0,0 +1,53 @@ + +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if(msgcontains(msg, "mission")) then + if(player:getStorageValue(Storage.TheNewFrontier.Questline) == 17) then + npcHandler:say("You come here to ask us to spare your people? This land has no tolerance for the weak, we have it neither. If you want us to consider you as useful for us, you'll have to prove it in a {test} of strength and courage. ", cid) + npcHandler.topic[cid] = 1 + elseif(player:getStorageValue(Storage.TheNewFrontier.Questline) == 19) then + npcHandler:say({ + "We have seen that you can fight and survive. Yet, it will also need cleverness and courage to survive in these lands. We might see later if you've got what it takes. ...", + "However, I stand to my word - our hordes will spare your insignificant piece of rock for now. Time will tell if you are worthy living next to us. ...", + "Still, it will take years until we might consider you as an ally, but this is a start at least." + }, cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 20) + player:setStorageValue(Storage.TheNewFrontier.Mission06, 3) --Questlog, The New Frontier Quest "Mission 06: Days Of Doom" + end + elseif(msgcontains(msg, "test")) then + if(npcHandler.topic[cid] == 1) then + npcHandler:say({ + "First we will test your strength and endurance. You'll have to face one of the most experienced Mooh'Tah masters. As you don't stand a chance to beat such an opponent, your test will be simply to survive. ...", + "Face him in a battle and survive for two minutes. If you do, we will be willing to assume that your are prepared for the life in these lands. Enter the ring of battle, close to my quarter. Return to me after you have passed this test." + }, cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.TheNewFrontier.Questline, 18) + player:setStorageValue(Storage.TheNewFrontier.Mission06, 2) --Questlog, The New Frontier Quest "Mission 06: Days Of Doom" + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/custom/cassino.lua b/data/npc/scripts/custom/cassino.lua new file mode 100644 index 00000000000..471848bdb1b --- /dev/null +++ b/data/npc/scripts/custom/cassino.lua @@ -0,0 +1,225 @@ +local config = { + bet = { + min = 10000, -- gold coins // 30k + max = 10000000000, + win = 180, -- 170% high/low + winNum = 500, -- 300% numbers + }, + playerPosition = Position(32352, 32226, 7), -- NpcPos(x-2) player must stay on this position to talk with npc + dicerCounter = Position(32352, 32225, 7), -- NpcPos(x-1, y-1) counter position + diePos = Position(32354, 32225, 7) --NpcPos(y-1) +} + +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end + +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end + +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end + +function onThink() + npcHandler:onThink() + local tile = Tile(config.playerPosition) + if tile then + local player = tile:getTopCreature() + if not player then + npcHandler.focuses = {} + npcHandler:updateFocus() + end + end +end + +local function getCoinValue(id) + if id == 2160 then + return 10000 + elseif id == 2152 then + return 100 + elseif id == 2148 then + return 1 + end + return 0 +end + +local function getBetValue() + local value = 0 + local tile = Tile(config.dicerCounter) + if tile then + local items = tile:getItems() + if not items or #items == 0 then + return 0 + end + + local tempMoney = {} + for _, item in pairs(items) do + if table.contains({2160, 2152, 2148}, item:getId()) then + value = value + getCoinValue(item:getId()) * item:getCount() + tempMoney[#tempMoney + 1] = item + end + end + + if value >= config.bet.min and value <= config.bet.max then -- valid bet + for _, item in pairs(tempMoney) do + item:remove() + end + return value + end + end + return nil +end + +local function createMoney(money) + local table = {} + local currentMoney = money + local crystals = math.floor(currentMoney / 10000) + currentMoney = currentMoney - crystals * 10000 + while crystals > 0 do + local count = math.min(100, crystals) + table[#table + 1] = {2160, count} + crystals = crystals - count + end + + local platinums = math.floor(currentMoney / 100) + if platinums ~= 0 then + table[#table + 1] = {2152, platinums} + currentMoney = currentMoney - platinums * 100 + end + + if currentMoney ~= 0 then + table[#table + 1] = {2148, currentMoney} + end + return table +end + +local function greetCallback(cid) + local player = Player(cid) + if player:getPosition() ~= config.playerPosition then + npcHandler:say("If you want to play with me please come near me.", cid) + return false + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if player:getPosition() ~= config.playerPosition then + npcHandler:unGreet(cid) + return false + end + local thisNpc = Npc(getNpcCid()) + if table.contains({"low", "high", "h", "l", "1", "2", "3", "4", "5", "6", "odd", "impar", "par", "even"}, msg) then + local bet = getBetValue() + if not bet then + npcHandler:say("Your bet is lower than the min {".. config.bet.min .."}gps or higher than the max {"..config.bet.max.."}gps bet.", cid) + npcHandler.topic[cid] = 0 + return true + end +player:say(msg, TALKTYPE_SAY, false, true, player:getPosition()) + local number = math.random(6) + +local dadimid = {5792, 5793, 5794, 5795, 5796, 5797} +local daddd = 0 +local haveDie = false + for x = 1, 6 do + daddd = Tile(config.diePos):getItemById(dadimid[x]) + if daddd then + haveDie = true + break + end + end + if haveDie then + daddd:transform(dadimid[number]) + else + Game.createItem((5791+number), 1, config.diePos) + end + thisNpc:say(thisNpc:getName() .. " rolled a ".. number .. ".", TALKTYPE_MONSTER_SAY, false, true, config.diePos) + config.diePos:sendMagicEffect(CONST_ME_CRAPS) + if table.contains({"low", "l"}, msg) then + if table.contains({1, 2, 3}, number) then + local wonMoney = math.ceil(bet * (config.bet.win / 100)) + thisNpc:say("You won! Here's your ".. wonMoney .." gold coins.", TALKTYPE_SAY) + config.dicerCounter:sendMagicEffect(math.random(29, 31)) + for _, coin in pairs(createMoney(wonMoney)) do + Game.createItem(coin[1], coin[2], config.dicerCounter) + end + else + + thisNpc:say("You have lost your "..bet.." gold coins.", TALKTYPE_SAY) + + end + elseif table.contains({"high", "h"}, msg) then + if table.contains({4, 5, 6}, number) then + local wonMoney = math.ceil(bet * (config.bet.win / 100)) + thisNpc:say("You won! Here's your ".. wonMoney .." gold coins.", TALKTYPE_SAY) + config.dicerCounter:sendMagicEffect(math.random(29, 31)) + for _, coin in pairs(createMoney(wonMoney)) do + Game.createItem(coin[1], coin[2], config.dicerCounter) + end + else + + thisNpc:say("You have lost your "..bet.." gold coins.", TALKTYPE_SAY) + + end + elseif table.contains({"odd", "impar"}, msg) then + if table.contains({1, 3, 5}, number) then + local wonMoney = math.ceil(bet * (config.bet.win / 100)) + thisNpc:say("You won! Here's your ".. wonMoney .." gold coins.", TALKTYPE_SAY) + config.dicerCounter:sendMagicEffect(math.random(29, 31)) + for _, coin in pairs(createMoney(wonMoney)) do + Game.createItem(coin[1], coin[2], config.dicerCounter) + end + else + + thisNpc:say("You have lost your "..bet.." gold coins.", TALKTYPE_SAY) + + end + elseif table.contains({"par", "even"}, msg) then + if table.contains({2, 4, 6}, number) then + local wonMoney = math.ceil(bet * (config.bet.win / 100)) + thisNpc:say("You won! Here's your ".. wonMoney .." gold coins.", TALKTYPE_SAY) + config.dicerCounter:sendMagicEffect(math.random(29, 31)) + for _, coin in pairs(createMoney(wonMoney)) do + Game.createItem(coin[1], coin[2], config.dicerCounter) + end + else + + thisNpc:say("You have lost your "..bet.." gold coins.", TALKTYPE_SAY) + + end + elseif table.contains({"1", "2", "3", "4", "5", "6"}, msg) then + if number == tonumber(msg) then + local wonMoney = math.ceil(bet * (config.bet.winNum / 100)) + thisNpc:say("You won! Here's your ".. wonMoney .." gold coins.", TALKTYPE_SAY) + config.dicerCounter:sendMagicEffect(math.random(29, 31)) + for _, coin in pairs(createMoney(wonMoney)) do + Game.createItem(coin[1], coin[2], config.dicerCounter) + end + else + + thisNpc:say("You have lost your "..bet.." gold coins.", TALKTYPE_SAY) + + end + end + end + return true +end +npcHandler:setMessage(MESSAGE_GREET, "Welcome to the Cassino! Here we play with: \n [PAYOUT 180%] {HIGH / LOW}: High for 4, 5, 6 and Low for 1, 2, and 3 - {ODD / EVEN }: Odd for 1, 3, 5 and Even for 2, 4 and 6 \n [PAYOUT 500%] {NUMBERS}: You choose the number, and if you get it right ... {$$$$$}") +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye.') + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/dabui.lua b/data/npc/scripts/dabui.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/dabui.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/dagomir.lua b/data/npc/scripts/dagomir.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/dagomir.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/dalbrect.lua b/data/npc/scripts/dalbrect.lua new file mode 100644 index 00000000000..9ef0476bcac --- /dev/null +++ b/data/npc/scripts/dalbrect.lua @@ -0,0 +1,175 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, "brooch") then + if player:getStorageValue(Storage.WhiteRavenMonastery.Passage) == 1 then + npcHandler:say("You have recovered my brooch! I shall forever be in your debt, my friend!", cid) + return true + end + + npcHandler:say("What? You want me to examine a brooch?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + if player:getItemCount(2318) == 0 then + npcHandler:say("What are you talking about? I am too poor to be interested in jewelry.", cid) + npcHandler.topic[cid] = 0 + return true + end + + npcHandler:say("Can it be? I recognise my family's arms! You have found a treasure indeed! \z + I am poor and all I can offer you is my friendship, but ... please ... give that brooch to me?", cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + npcHandler.topic[cid] = 0 + if not player:removeItem(2318, 1) then + npcHandler:say("I should have known better than to ask for an act of kindness in this cruel, selfish, world!", cid) + return true + end + + npcHandler:say("Thank you! I shall consider you my friend from now on! \z + Just let me know if you {need} something!", cid) + player:setStorageValue(Storage.WhiteRavenMonastery.QuestLog, 1) -- Quest log + player:setStorageValue(Storage.WhiteRavenMonastery.Passage, 1) + end + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Then stop being a fool. I am poor and I have to work the whole day through!", cid) + elseif npcHandler.topic[cid] == 2 then + npcHandler:say("I should have known better than to ask for an act of kindness in this cruel, selfish, world!", cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({"passage"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I have only sailed to the isle of the kings once or twice. \z + I dare not anger the monks by bringing travelers there without their permission." + }, + +function(player) + return player:getStorageValue(Storage.WhiteRavenMonastery.Passage) ~= 1 +end) + +local travelNode = keywordHandler:addKeyword({"passage"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Do you seek a passage to the isle of the kings for 10 gold coins?" + } +) + travelNode:addChildKeyword({"yes"}, StdModule.travel, + { + npcHandler = npcHandler, + premium = false, + text = "Have a nice trip!", + cost = 10, + destination = Position(32190, 31957, 6) + } + ) + travelNode:addChildKeyword({"no"}, StdModule.say, + { + npcHandler = npcHandler, reset = true, + text = "Well, I'll be here if you change your mind." + } + ) + +keywordHandler:addKeyword({"name"}, StdModule.say, + { + npcHandler = npcHandler, + text = "My name is Dalbrect Windtrouser, of the once proud Windtrouser family." + } +) +keywordHandler:addKeyword({"hut"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I am merely a humble fisher now that nothing is left of my noble {legacy}." + } +) +keywordHandler:addKeyword({"legacy"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Once my family was once noble and wealthy, but {fate} turned against us and threw us into poverty." + + } +) +keywordHandler:addKeyword({"poverty"}, StdModule.say, + { + npcHandler = npcHandler, + text = "When Carlin tried to colonize the region now known as the ghostlands, \z + my ancestors put their fortune in that {project}." + } +) +keywordHandler:addKeyword({"fate"}, StdModule.say, + { + npcHandler = npcHandler, + text = "When Carlin tried to colonize the region now known as the ghostlands, \z + my ancestors put their fortune in that {project}." + } +) +keywordHandler:addKeyword({"ghostlands"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Our family fortune was lost when the colonization of those cursed lands failed. \z + Now nothing is left of our fame or our fortune. \z + If I only had something as a reminder of those better times. " + } +) +keywordHandler:addKeyword({"project"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Our family fortune was lost when the colonization of those cursed lands failed. \z + Now nothing is left of our fame or our fortune. \z + If I only had something as a reminder of those better times. " + } +) +keywordHandler:addKeyword({"carlin"}, StdModule.say, + { + npcHandler = npcHandler, + text = "To think my family used to belong to the local nobility! And now those arrogant women are in charge!" + } +) +keywordHandler:addKeyword({"need"}, StdModule.say, + { + npcHandler = npcHandler, + text = "There is little I can offer you but a trip with my boat. \z + Are you looking for a {passage} to the isle of kings perhaps?" + } +) +keywordHandler:addKeyword({"ship"}, StdModule.say, + { + npcHandler = npcHandler, + text = "My ship is my only pride and joy." + } +) + +npcHandler:setMessage(MESSAGE_GREET, "Be greeted, traveller |PLAYERNAME|. Welcome to my {hut}.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye. You are welcome.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/dallheim.lua b/data/npc/scripts/dallheim.lua new file mode 100644 index 00000000000..76361d0510e --- /dev/null +++ b/data/npc/scripts/dallheim.lua @@ -0,0 +1,182 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'The most dangerous monsters of Rookgaard are on the other side of this bridge.' }, + { text = 'Want to know what monsters are good for you at your level? Just ask me!' }, + { text = 'I\'ll crush all monsters who dare to attack our base.' }, + { text = 'Are you injured or poisoned? I can help you.' }, + { text = 'For Rookgaard! For Tibia!' } +} +npcHandler:addModule(VoiceModule:new(voices)) + +-- Greeting and Farewell +keywordHandler:addGreetKeyword({'hi'}, {npcHandler = npcHandler, text = 'Greetings, |PLAYERNAME|! You\'re looking really bad. Let me heal your wounds.'}, + function(player) return player:getHealth() < 65 or player:getCondition(CONDITION_POISON) ~= nil end, + function(player) + local health = player:getHealth() + if health < 65 then player:addHealth(65 - health) end + player:removeCondition(CONDITION_POISON) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + end +) +keywordHandler:addAliasKeyword({'hello'}) + +keywordHandler:addGreetKeyword({'hi'}, {npcHandler = npcHandler, text = ' At your service, |PLAYERNAME|, protecting the {village} from {monsters}.'}, function(player) return player:getSex() == PLAYERSEX_FEMALE end) +keywordHandler:addAliasKeyword({'hello'}) + +keywordHandler:addFarewellKeyword({'bye'}, {npcHandler = npcHandler, text = 'Bye, |PLAYERNAME|.'}) +keywordHandler:addAliasKeyword({'farewell'}) + +local function addMonsterKeyword(level, text, marks) + local keyword = keywordHandler:addKeyword({'monster'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getLevel() >= level end, + function(player) + if marks then + for i = 1, #marks do + player:addMapMark(marks[i].position, marks[i].type, marks[i].description) + end + end + end + ) +end + +-- Monster +keywordHandler:addKeyword({'monster'}, StdModule.say, {npcHandler = npcHandler, text = 'Hmm, |PLAYERNAME|. I really don\'t know if you should go into the wilderness without a shield. You should earn some money by hunting rats under the village first until you can afford at least a wooden shield.'}, function(player) return not player:hasRookgaardShield() end) + +addMonsterKeyword(10, 'It looks like you have mastered the drill.') +addMonsterKeyword(8, 'It looks like you have mastered the drill. Talk to the {oracle} to travel to other places and start getting some real battle experience.') +addMonsterKeyword(7, 'You are almost strong enough to leave this island. If you\'d like to go somewhere new, why don\'t you try skeletons? I\'ll mark a cave on your map, but be careful, there are lots of other creatures on the way.', + {{position = Position(31972, 32130, 7), type = MAPMARK_GREENSOUTH, description = 'Skeleton Cave'}} +) +addMonsterKeyword(6, 'Nice job out there, |PLAYERNAME|. Have you already explored the whole North Ruin? If you are courageous enough, you could test your skills on wasps. But be careful, they are fast and poisonous! I\'ll mark them for you.', + {{position = Position(32000, 32139, 7), type = MAPMARK_GREENNORTH, description = 'Wasps\' Nest'}, {position = Position(32000, 32137, 6), type = MAPMARK_GREENNORTH, description = 'Wasp Hive'}} +) +addMonsterKeyword(5, 'Are you already tired of the North Ruin? You could try some bears, but be careful, they hit hard. I\'ll mark a cave on your map.', + {{position = Position(32146, 32207, 7), type = MAPMARK_GREENSOUTH, description = 'Bear Cave'}} +) +addMonsterKeyword(4, 'You\'re halfway on leaving this island. I guess you might be ready for some stronger monsters such as {trolls} or {orcs}. Check out the North Ruin which I\'ll mark on your map right now, but don\'t go too deep.', + {{position = Position(32094, 32137, 7), type = MAPMARK_GREENSOUTH, description = 'North Ruin'}} +) +addMonsterKeyword(3, 'Well, you can still stay with {spiders} or {snakes}, but maybe you\'d like to try fighting a {bug} or even a {wolf}? I\'ll mark a den that I know on your map right now. Don\'t forget torch and rope!', + {{position = Position(32155, 32122, 7), type = MAPMARK_GREENSOUTH, description = 'Wolf Den'}} +) +addMonsterKeyword(2, 'You still look a little wimpy. If you want to kill something other than {rats}, you may leave town to hunt {spiders} or {snakes}. I\'ll mark some spawns on your map right now. Don\'t forget torch and rope!', + {{position = Position(32027, 32171, 7), type = MAPMARK_GREENSOUTH, description = 'Snake Swamp'}, {position = Position(31967, 32169, 7), type = MAPMARK_GREENSOUTH, description = 'Spiderweb Hole'}} +) +addMonsterKeyword(1, 'You are much too young and inexperienced to cross the bridge. Stay in the sewers. I\'ll mark an entrance on your map right now.', + {{position = Position(32097, 32205, 7), type = MAPMARK_GREENSOUTH, description = 'Sewer Entrance'}} +) + +-- Basic keywords +keywordHandler:addKeyword({'hint'}, StdModule.rookgaardHints, {npcHandler = npcHandler}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'Dallheim, at your service.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m the guard of this bridge. I defend Rookgaard against the beasts of the {wilderness} and the {dungeons}, and even of the stinking {sewers}.'}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = 'My duty is eternal. Time is of no importance.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'Before you fight monsters, deposit your money there. If you die, you won\'t lose it if it\'s save in the bank.'}) +keywordHandler:addKeyword({'how', 'are', 'you'}, StdModule.say, {npcHandler = npcHandler, text = 'Fine.'}) +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'I have to stay here, sorry. But I can heal you if you are wounded. I have also valuable information about {monsters}.'}) +keywordHandler:addKeyword({'information'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m an expert concerning the wildlife and {monsters} on this island.'}) +keywordHandler:addKeyword({'citizen'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'ll protect all citizens alike. That is my {job} and duty.'}) +keywordHandler:addKeyword({'rat'}, StdModule.say, {npcHandler = npcHandler, text = 'Did you know that rats are among the most dangerous animals in whole Tibia? Each day, they kill many people who are overestimating their powers. Don\'t be one of them!'}) +keywordHandler:addKeyword({'spider'}, StdModule.say, {npcHandler = npcHandler, text = 'There are two types of spiders on this island: normal spiders and poison spiders. As their name says, the latter ones can poison you which will cause a constant loss of your health. Beware of them!'}) +keywordHandler:addKeyword({'troll'}, StdModule.say, {npcHandler = npcHandler, text = 'Once you have upgraded your starter {equipment} a little - maybe leather stuff - and got a better weapon as well as a shield, you should be able to kill trolls.'}) +keywordHandler:addKeyword({'wolf'}, StdModule.say, {npcHandler = npcHandler, text = 'You need a stronger weapon than the starter club to kill wolves. Maybe a {sabre} or a short {sword} will do.'}) +keywordHandler:addAliasKeyword({'wolves'}) +keywordHandler:addKeyword({'orc'}, StdModule.say, {npcHandler = npcHandler, text = 'Orcs are a constant menace. There are even stronger species of orcs on the main continent.'}) +keywordHandler:addKeyword({'minotaur'}, StdModule.say, {npcHandler = npcHandler, text = 'Minotaurs are very strong. You will need a group of people or at least level 6 and good equipment to be able to kill them.'}) +keywordHandler:addKeyword({'bug'}, StdModule.say, {npcHandler = npcHandler, text = 'They are a little tougher than they look like, but they\'re still good beginner monsters.'}) +keywordHandler:addKeyword({'skeleton'}, StdModule.say, {npcHandler = npcHandler, text = 'The skeletons on this island are usually fairly hidden. They are often found near graves and always underground. Beware of their evil life drain.'}) +keywordHandler:addKeyword({'bear'}, StdModule.say, {npcHandler = npcHandler, text = 'A bear can easily kill you if you don\'t pay attention.'}) +keywordHandler:addKeyword({'wasp'}, StdModule.say, {npcHandler = npcHandler, text = 'Wasps are the fastest monsters on this island and they poison you. If you ever run into one and are already low of health, fear for your life!'}) +keywordHandler:addKeyword({'snake'}, StdModule.say, {npcHandler = npcHandler, text = 'Snakes can poison you, too, but their poison is usually not as dangerous as that of poison spiders. Just be careful and kill them fast.'}) +keywordHandler:addKeyword({'premium'}, StdModule.say, {npcHandler = npcHandler, text = 'Premium warriors pay. They gain many advantages this way.'}) +keywordHandler:addKeyword({'king'}, StdModule.say, {npcHandler = npcHandler, text = 'HAIL TO THE KING!'}) +keywordHandler:addKeyword({'academy'}, StdModule.say, {npcHandler = npcHandler, text = 'All that theory won\'t help you without some real battle practice.'}) +keywordHandler:addKeyword({'temple'}, StdModule.say, {npcHandler = npcHandler, text = 'A place of protection. Nothing can harm you there.'}) +keywordHandler:addKeyword({'dungeon'}, StdModule.say, {npcHandler = npcHandler, text = 'I can mark you some dungeons on your map if you ask me about {monsters} suited for your level.'}) +keywordHandler:addKeyword({'sewer'}, StdModule.say, {npcHandler = npcHandler, text = 'The sewers are crowded with {rats}. They make fine targets for young heroes.'}) +keywordHandler:addKeyword({'wilderness'}, StdModule.say, {npcHandler = npcHandler, text = 'There are {wolves}, {bears}, {snakes}, {deer}, and {spiders} in the wilderness past this bridge.'}) +keywordHandler:addKeyword({'god'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m a follower of {Banor}.'}) +keywordHandler:addKeyword({'banor'}, StdModule.say, {npcHandler = npcHandler, text = 'The heavenly warrior! Hail to him!'}) +keywordHandler:addKeyword({'magic'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m not interested in such party tricks.'}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = 'A nice place for a hero, but nothing for whelps.'}) + +keywordHandler:addKeyword({'rookgaard'}, StdModule.say, {npcHandler = npcHandler, text = 'It\'s my duty to protect this village and its {citizens}.'}) +keywordHandler:addAliasKeyword({'village'}) + +keywordHandler:addKeyword({'monster'}, StdModule.say, {npcHandler = npcHandler, text = 'It looks like you have mastered the drill.'}) + +keywordHandler:addKeyword({'trade'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, I don\'t trade. Ask the shop owners for a trade instead.'}) +keywordHandler:addAliasKeyword({'offer'}) +keywordHandler:addAliasKeyword({'stuff'}) +keywordHandler:addAliasKeyword({'wares'}) +keywordHandler:addAliasKeyword({'sell'}) +keywordHandler:addAliasKeyword({'buy'}) +keywordHandler:addAliasKeyword({'sword'}) +keywordHandler:addAliasKeyword({'sabre'}) +keywordHandler:addAliasKeyword({'equip'}) +keywordHandler:addAliasKeyword({'weapon'}) +keywordHandler:addAliasKeyword({'armor'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addAliasKeyword({'food'}) +keywordHandler:addAliasKeyword({'potion'}) + +-- Names +keywordHandler:addKeyword({'norma'}, StdModule.say, {npcHandler = npcHandler, text = 'I don\'t approve of her opening a bar. Those drunken adventurers stumbling over the bridge at nighttime are not especially helpful in improving the situation.'}) +keywordHandler:addKeyword({'loui'}, StdModule.say, {npcHandler = npcHandler, text = 'Zerbrus tells me such strange stories about him. Well, he sees him all day from the west bridge.'}) +keywordHandler:addKeyword({'santiago'}, StdModule.say, {npcHandler = npcHandler, text = 'He dedicated his life to welcoming newcomers to this island.'}) +keywordHandler:addKeyword({'zirella'}, StdModule.say, {npcHandler = npcHandler, text = 'Nice old lady.'}) +keywordHandler:addKeyword({'al', 'dee'}, StdModule.say, {npcHandler = npcHandler, text = 'He has been on this island as long as me.'}) +keywordHandler:addKeyword({'amber'}, StdModule.say, {npcHandler = npcHandler, text = 'I don\'t trust her.'}) +keywordHandler:addKeyword({'cipfried'}, StdModule.say, {npcHandler = npcHandler, text = 'He guards the temple and can heal you if you are badly injured or poisoned, just like me.'}) +keywordHandler:addKeyword({'dixi'}, StdModule.say, {npcHandler = npcHandler, text = 'She\'s {Obi\'s} granddaughter and deals with {armors} and {shields}. Her shop is south west of town, close to the temple.'}) +keywordHandler:addKeyword({'hyacinth'}, StdModule.say, {npcHandler = npcHandler, text = 'Strange fellow, hides somewhere in the mountains of the isle.'}) +keywordHandler:addKeyword({'lee\'delle'}, StdModule.say, {npcHandler = npcHandler, text = 'Her shop is on the {premium} side of town. Best offers around.'}) +keywordHandler:addKeyword({'lily'}, StdModule.say, {npcHandler = npcHandler, text = 'Sometimes I wish I had an easy job like her, selling {potions} all day.'}) +keywordHandler:addKeyword({'oracle'}, StdModule.say, {npcHandler = npcHandler, text = 'You can find the oracle on the top floor of the {academy}, just above Seymour. Go there when you are level 8.'}) +keywordHandler:addKeyword({'paulie'}, StdModule.say, {npcHandler = npcHandler, text = 'The local bank clerk.'}) +keywordHandler:addKeyword({'seymour'}, StdModule.say, {npcHandler = npcHandler, text = 'Leave me alone with this wimp.'}) +keywordHandler:addKeyword({'tom'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s the local tanner. You could try selling fresh corpses or leather to him.'}) +keywordHandler:addKeyword({'dallheim'}, StdModule.say, {npcHandler = npcHandler, text = 'At your service.'}) +keywordHandler:addKeyword({'zerbrus'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s guarding the west bridge. Not that a real threat would lurk on the other side.'}) +keywordHandler:addKeyword({'billy'}, StdModule.say, {npcHandler = npcHandler, text = 'He is a fine cook and farmer. He buys and sells {food}.'}) +keywordHandler:addAliasKeyword({'willie'}) + +-- Healing +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are poisoned. I will help you.'}, + function(player) return player:getCondition(CONDITION_POISON) ~= nil end, + function(player) + local health = player:getHealth() + if health < 65 then player:addHealth(65 - health) end + player:removeCondition(CONDITION_POISON) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are looking really bad. Let me heal your wounds.'}, + function(player) return player:getHealth() < 65 end, + function(player) + local health = player:getHealth() + if health < 65 then player:addHealth(65 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking really bad. Eat some food to regain strength.'}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Hm.') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/dane.lua b/data/npc/scripts/dane.lua new file mode 100644 index 00000000000..6eef0a04ac3 --- /dev/null +++ b/data/npc/scripts/dane.lua @@ -0,0 +1,29 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am the owner of this place of relaxation."}) +keywordHandler:addKeyword({'wave cellar'}, StdModule.say, {npcHandler = npcHandler, text = "It's pretty, isn't it?"}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "I am Dane."}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = "It is exactly |TIME|."}) +keywordHandler:addKeyword({'offer'}, StdModule.say, {npcHandler = npcHandler, text = "I can offer you milk, water, and lemonade."}) +keywordHandler:addKeyword({'alcohol'}, StdModule.say, {npcHandler = npcHandler, text = "Alcohol makes people too aggressive. We don't need such stuff in Carlin."}) +keywordHandler:addKeyword({'beer'}, StdModule.say, {npcHandler = npcHandler, text = "Alcohol makes people too aggressive. We don't need such stuff in Carlin."}) +keywordHandler:addKeyword({'wine'}, StdModule.say, {npcHandler = npcHandler, text = "Alcohol makes people too aggressive. We don't need such stuff in Carlin."}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome to the wave cellar, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Please come back from time to time.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/daniel_steelsoul.lua b/data/npc/scripts/daniel_steelsoul.lua new file mode 100644 index 00000000000..1d84409bcc1 --- /dev/null +++ b/data/npc/scripts/daniel_steelsoul.lua @@ -0,0 +1,63 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(14, 1000, -10) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if isInArray({"fuck", "idiot", "asshole", "ass", "fag", "stupid", "tyrant", "shit", "lunatic"}, msg) then + npcHandler:say("Take this!", cid) + player:getPosition():sendMagicEffect(CONST_ME_EXPLOSIONAREA) + player:addCondition(condition) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + elseif msgcontains(msg, "mission") then + if player:getStorageValue(Storage.TibiaTales.AgainstTheSpiderCult) < 1 then + npcHandler.topic[cid] = 1 + npcHandler:say("Very good, we need heroes like you to go on a suici.....er....to earn respect of the authorities here AND in addition get a great reward for it. Are you interested in the job?", cid) + elseif player:getStorageValue(Storage.TibiaTales.AgainstTheSpiderCult) == 5 then + player:setStorageValue(Storage.TibiaTales.AgainstTheSpiderCult, 6) + npcHandler.topic[cid] = 0 + player:addItem(7887, 1) + npcHandler:say("What? YOU DID IT?!?! That's...that's...er.... like I expected!! Here is your reward.", cid) + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + player:setStorageValue(Storage.TibiaTales.DefaultStart, 1) + player:setStorageValue(Storage.TibiaTales.AgainstTheSpiderCult, 1) + npcHandler:say({ + "Very well, maybe you know that the orcs here in Edron learnt to raise giant spiders. It is going to become a serious threat. ...", + "The mission is simple: go to the orcs and destroy all spider eggs that are hatched by the giant spider they have managed to catch. The orcs are located in the south of the western part of the island." + }, cid) + end + end + return true +end + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am the governor of this isle, Edron, and grandmaster of the Knights of Banor's Blood."}) +keywordHandler:addKeyword({'king'}, StdModule.say, {npcHandler = npcHandler, text = "LONG LIVE THE KING!"}) + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "Greetings and Banor be with you, |PLAYERNAME|!") +npcHandler:setMessage(MESSAGE_FAREWELL, "PRAISE TO BANOR!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "PRAISE TO BANOR!") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/dankwart.lua b/data/npc/scripts/dankwart.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/dankwart.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/danlon.lua b/data/npc/scripts/danlon.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/danlon.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/dario.lua b/data/npc/scripts/dario.lua new file mode 100644 index 00000000000..0e1338d4e23 --- /dev/null +++ b/data/npc/scripts/dario.lua @@ -0,0 +1,34 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local voices = { + { text = 'Increase your knowledge of spells here, young paladin.' }, + { text = 'Need ammunition, bows or crossbows? Have a look at my wares.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +-- Greeting message +keywordHandler:addGreetKeyword({"ashari"}, {npcHandler = npcHandler, text = "Ashari, |PLAYERNAME|. If you're a distance fighter, you might want to have a look at my wares and spells."}) +--Farewell message +keywordHandler:addFarewellKeyword({"asgha thrazi"}, {npcHandler = npcHandler, text = "Asha Thrazi, |PLAYERNAME|."}) + +npcHandler:setMessage(MESSAGE_GREET, "Ashari, |PLAYERNAME|. If you're a distance fighter, you might want to have a look at my wares and spells.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Asha Thrazi, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Asha Thrazi, |PLAYERNAME|.") + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/dark_percht_sleigh.lua b/data/npc/scripts/dark_percht_sleigh.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/dark_percht_sleigh.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/dedoras.lua b/data/npc/scripts/dedoras.lua new file mode 100644 index 00000000000..2549a80ce5c --- /dev/null +++ b/data/npc/scripts/dedoras.lua @@ -0,0 +1,74 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local playerTopic = {} +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.Kilmaresh.First.Access) < 1 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + playerTopic[cid] = 1 + elseif (player:getStorageValue(Storage.Kilmaresh.First.JamesfrancisTask) >= 0 and player:getStorageValue(Storage.Kilmaresh.First.JamesfrancisTask) <= 50) + and player:getStorageValue(Storage.Kilmaresh.First.Mission) < 3 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + playerTopic[cid] = 15 + elseif player:getStorageValue(Storage.Kilmaresh.First.Mission) == 4 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + player:setStorageValue(Storage.Kilmaresh.First.Mission, 5) + playerTopic[cid] = 20 + end + npcHandler:addFocus(cid) + return true +end + +local function creatureSayCallback(cid, type, msg) +if not npcHandler:isFocused(cid) then + return false +end +npcHandler.topic[cid] = playerTopic[cid] +local player = Player(cid) + +if msgcontains(msg, "report") and player:getStorageValue(Storage.TheSecretLibrary.PinkTel) == 1 then + npcHandler:say({"Talk to Captain Charles in Port Hope. He told me that he once ran ashore on a small island where he discovered a small ruin. The architecture was like nothing he had seen before."}, cid) + player:setStorageValue(Storage.TheSecretLibrary.PinkTel, 2) + npcHandler.topic[cid] = 1 + playerTopic[cid] = 1 +end + +if msgcontains(msg, "check") and player:getStorageValue(Storage.TheSecretLibrary.HighDry) == 5 then + npcHandler:say({"Marvellous! With this information combined we have all that's needed! ...", + "So let me see. ...", + "Hmm, interesting. And we shouldn't forget about the chant! Yes, excellent! ...", + "So listen: To enter the veiled library, travel to the white raven monastery on the Isle of Kings and enter its main altar room. ...", + "There, use an ordinary scythe on the right of the two monuments, while concentrating on this glyph here and chant the words: Chamek Athra Thull Zathroth ...", + "Oh, and one other thing. For your efforts I want to reward you with one of my old outfits, back from my adventuring days. May it suit you well! ...", + "Hurry now my friend. Time is of essence!"}, cid) + player:setStorageValue(Storage.TheSecretLibrary.HighDry, 6) + npcHandler.topic[cid] = 1 + playerTopic[cid] = 1 +end + + + +return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/default.lua b/data/npc/scripts/default.lua new file mode 100644 index 00000000000..90c025f5816 --- /dev/null +++ b/data/npc/scripts/default.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/demonguard.lua b/data/npc/scripts/demonguard.lua new file mode 100644 index 00000000000..e160dd39add --- /dev/null +++ b/data/npc/scripts/demonguard.lua @@ -0,0 +1,38 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(10, 1000, -10) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if isInArray({"fuck", "idiot", "asshole", "ass", "fag", "stupid", "tyrant", "shit", "lunatic"}, msg) then + npcHandler:say("Take this!", cid) + local player = Player(cid) + player:getPosition():sendMagicEffect(CONST_ME_EXPLOSIONAREA) + player:addCondition(condition) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/denominator.lua b/data/npc/scripts/denominator.lua new file mode 100644 index 00000000000..895dda3bb17 --- /dev/null +++ b/data/npc/scripts/denominator.lua @@ -0,0 +1,217 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local playerTopic = {} +local playerLastResp = {} +local function greetCallback(cid) + + local player = Player(cid) + if player:getStorageValue(Storage.CultsOfTibia.MotA.Mission) == 13 then + npcHandler:setMessage(MESSAGE_GREET, "Enter answers for the following {questions}:") + playerTopic[cid] = 1 + else + npcHandler:setMessage(MESSAGE_GREET, "Greetings.") + end + npcHandler:addFocus(cid) + return true +end + +local quiz1 = { + [1] = {p ="The sum of first and second digit?", r = function(player)player:setStorageValue(Storage.CultsOfTibia.MotA.Answer, player:getStorageValue(Storage.CultsOfTibia.MotA.Stone1) + player:getStorageValue(Storage.CultsOfTibia.MotA.Stone2))return player:getStorageValue(Storage.CultsOfTibia.MotA.Answer)end}, + [2] = {p ="The sum of second and third digit?", r = function(player)player:setStorageValue(Storage.CultsOfTibia.MotA.Answer, player:getStorageValue(Storage.CultsOfTibia.MotA.Stone2) + player:getStorageValue(Storage.CultsOfTibia.MotA.Stone3))return player:getStorageValue(Storage.CultsOfTibia.MotA.Answer)end}, + [3] = {p ="The sum of first and third digit?", r = function(player)player:setStorageValue(Storage.CultsOfTibia.MotA.Answer, player:getStorageValue(Storage.CultsOfTibia.MotA.Stone1) + player:getStorageValue(Storage.CultsOfTibia.MotA.Stone3))return player:getStorageValue(Storage.CultsOfTibia.MotA.Answer)end}, + [4] = {p ="The digit sum?", r = function(player)player:setStorageValue(Storage.CultsOfTibia.MotA.Answer, player:getStorageValue(Storage.CultsOfTibia.MotA.Stone1) + player:getStorageValue(Storage.CultsOfTibia.MotA.Stone2) + player:getStorageValue(Storage.CultsOfTibia.MotA.Stone3))return player:getStorageValue(Storage.CultsOfTibia.MotA.Answer)end}, +} + +local quiz2 = { + [1] = {p = "Is the number prime?", r = + function(player) + local stg = player:getStorageValue(Storage.CultsOfTibia.MotA.Answer) + if stg < 1 then + return 0 + end + if stg == 1 or stg == 2 then + return 1 + end + local incr = 0 + for i = 1, stg do + if(stg % i == 0)then + incr = incr + 1 + end + end + return (incr == 2 and 1 or 0) + end + }, + [2] = {p = "Does the number belong to a prime twing?", r = + function(player) + local stg = player:getStorageValue(Storage.CultsOfTibia.MotA.Answer) + if stg < 2 then + return 0 + end + if stg == 1 or stg == 2 then + return 1 + end + local incr = 0 + for i = 1, stg do + if(stg % i == 0)then + incr = incr + 1 + end + end + return (incr == 2 and 1 or 0) + end + }, + -- [2] = {p = "", r = ""}, +} + +local quiz3 = { + [1] = {p = "Is the number divisible by 3?", r = function(player)return (player:getStorageValue(Storage.CultsOfTibia.MotA.Answer) % 3 == 0 and 1 or 0)end}, + [2] = {p = "Is the number divisible by 2?", r = function(player)return (player:getStorageValue(Storage.CultsOfTibia.MotA.Answer) % 2 == 0 and 1 or 0)end}, +} + + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + npcHandler.topic[cid] = playerTopic[cid] + local player = Player(cid) + -- Começou a quest + if msgcontains(msg, "questions") and npcHandler.topic[cid] == 1 then + npcHandler:say("Ready to {start}?", cid) + npcHandler.topic[cid] = 2 + playerTopic[cid] = 2 + elseif msgcontains(msg, "start") and npcHandler.topic[cid] == 2 then + local perguntaid = math.random(#quiz1) + player:setStorageValue(Storage.CultsOfTibia.MotA.QuestionId, perguntaid) + npcHandler:say(quiz1[perguntaid].p, cid) + npcHandler.topic[cid] = 3 + playerTopic[cid] = 3 + elseif (npcHandler.topic[cid] == 3) then + npcHandler:say(string.format("Your answer is %s, do you want to continue?", msg), cid) + playerLastResp[cid] = tonumber(msg) + npcHandler.topic[cid] = 4 + playerTopic[cid] = 4 + elseif (npcHandler.topic[cid] == 4) then + if msgcontains(msg, "yes") then + local resposta = quiz1[player:getStorageValue(Storage.CultsOfTibia.MotA.QuestionId)].r + if playerLastResp[cid] ~= (tonumber(resposta(player))) then + npcHandler:say("Wrong. SHUT DOWN.", cid) + npcHandler:resetNpc(cid) + npcHandler:releaseFocus(cid) + return false + else + npcHandler:say("Correct. {Next} question?", cid) + npcHandler.topic[cid] = 5 + playerTopic[cid] = 5 + end + elseif msgcontains(msg, "no") then + npcHandler:say("SHUT DOWN.", cid) + npcHandler:resetNpc(cid) + npcHandler:releaseFocus(cid) + return false + end + elseif msgcontains(msg, "next") and npcHandler.topic[cid] == 5 then + local perguntaid = math.random(#quiz2) + player:setStorageValue(Storage.CultsOfTibia.MotA.QuestionId, perguntaid) + npcHandler:say(quiz2[perguntaid].p, cid) + npcHandler.topic[cid] = 6 + playerTopic[cid] = 6 + elseif npcHandler.topic[cid] == 6 then + local resp = 0 + if msgcontains(msg, "no") then + resp = 0 + elseif msgcontains(msg, "yes") then + resp = 1 + end + local resposta = quiz2[player:getStorageValue(Storage.CultsOfTibia.MotA.QuestionId)].r + if resp == resposta(player) then + npcHandler:say("Correct. {Next} question?", cid) + npcHandler.topic[cid] = 7 + playerTopic[cid] = 7 + else + npcHandler:say("Wrong. SHUT DOWN.", cid) + npcHandler:resetNpc(cid) + npcHandler:releaseFocus(cid) + return false + end + elseif npcHandler.topic[cid] == 7 and msgcontains(msg, "next") then + local perguntaid = math.random(#quiz3) + player:setStorageValue(Storage.CultsOfTibia.MotA.QuestionId, perguntaid) + npcHandler:say(quiz3[perguntaid].p, cid) + npcHandler.topic[cid] = 8 + playerTopic[cid] = 8 + elseif npcHandler.topic[cid] == 8 then + local resp = 0 + if msgcontains(msg, "no") then + resp = 0 + elseif msgcontains(msg, "yes") then + resp = 1 + end + local resposta = quiz3[player:getStorageValue(Storage.CultsOfTibia.MotA.QuestionId)].r + if resp == resposta(player) then + npcHandler:say("Correct. {Last} question?", cid) + npcHandler.topic[cid] = 9 + playerTopic[cid] = 9 + else + npcHandler:say("Wrong. SHUT DOWN.", cid) + npcHandler:resetNpc(cid) + npcHandler:releaseFocus(cid) + return false + end + elseif npcHandler.topic[cid] == 9 and msgcontains(msg, "last") then + npcHandler:say("Tell me the correct number?", cid) + npcHandler.topic[cid] = 10 + playerTopic[cid] = 10 + elseif npcHandler.topic[cid] == 10 then + npcHandler:say(string.format("Your answer is %s, do you want to continue?", msg), cid) + playerLastResp[cid] = tonumber(msg) + npcHandler.topic[cid] = 11 + playerTopic[cid] = 11 + elseif npcHandler.topic[cid] == 11 then + if msgcontains(msg, "yes") then + local correct = string.format("%d%d%d", player:getStorageValue(Storage.CultsOfTibia.MotA.Stone1), player:getStorageValue(Storage.CultsOfTibia.MotA.Stone2), player:getStorageValue(Storage.CultsOfTibia.MotA.Stone3)) + if tonumber(playerLastResp[cid]) ~= (tonumber(correct)) then + npcHandler:say("Wrong. SHUT DOWN.", cid) + npcHandler:resetNpc(cid) + npcHandler:releaseFocus(cid) + return false + else + npcHandler:say("Correct. The lower door is now open. The druid of Crunor lies.", cid) + player:setStorageValue(Storage.CultsOfTibia.MotA.Mission, player:getStorageValue(Storage.CultsOfTibia.MotA.Mission) + 1) + player:setStorageValue(Storage.CultsOfTibia.MotA.AccessDoorDenominator) + end + elseif msgcontains(msg, "no") then + npcHandler:say("SHUT DOWN.", cid) + npcHandler:resetNpc(cid) + npcHandler:releaseFocus(cid) + return false + end + end + + return true +end + + + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/dermot.lua b/data/npc/scripts/dermot.lua new file mode 100644 index 00000000000..3ca6c002d9e --- /dev/null +++ b/data/npc/scripts/dermot.lua @@ -0,0 +1,67 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "present") then + if player:getStorageValue(Storage.Postman.Mission05) == 2 then + npcHandler:say("You have a present for me?? Realy?", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "key") then + npcHandler:say("Do you want to buy the dungeon key for 2000 gold?", cid) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + if player:removeItem(2331, 1) then + npcHandler:say("Thank you very much!", cid) + player:setStorageValue(Storage.Postman.Mission05, 3) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 2 then + if player:removeMoneyNpc(2000) then + npcHandler:say("Here it is.", cid) + local key = player:addItem(2087, 1) + if key then + key:setActionId(3940) + end + else + npcHandler:say("You don't have enough money.", cid) + end + npcHandler.topic[cid] = 0 + end + end + return true +end + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am the magistrate of this isle."}) +keywordHandler:addKeyword({'magistrate'}, StdModule.say, {npcHandler = npcHandler, text = "Thats me."}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "I am Dermot, the magistrate of this isle."}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = "Time is not important on Fibula."}) +keywordHandler:addKeyword({'fibula'}, StdModule.say, {npcHandler = npcHandler, text = "You are at Fibula. This isle is not very dangerous. Just the wolves bother outside the village."}) +keywordHandler:addKeyword({'dungeon'}, StdModule.say, {npcHandler = npcHandler, text = "Oh, my god. In the dungeon of Fibula are a lot of monsters. That's why we have sealed it with a solid door."}) +keywordHandler:addKeyword({'monsters'}, StdModule.say, {npcHandler = npcHandler, text = "Oh, my god. In the dungeon of Fibula are a lot of monsters. That's why we have sealed it with a solid door."}) + +npcHandler:setMessage(MESSAGE_GREET, "Hello, traveller |PLAYERNAME|. How can I help you?") +npcHandler:setMessage(MESSAGE_FAREWELL, "See you again.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "See you again.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/digger.lua b/data/npc/scripts/digger.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/digger.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/dixi.lua b/data/npc/scripts/dixi.lua new file mode 100644 index 00000000000..5f34e5c9d0c --- /dev/null +++ b/data/npc/scripts/dixi.lua @@ -0,0 +1,107 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = ' Get your armor and shields heeeeeeere! Upstairs!', yell = true }, + { text = 'Need some help? Just ask me, I can show you around!' }, + { text = 'Don\'t forget to protect yourself with a shield!' }, + { text = 'Selling the finest armors on Rookgaard!' }, + { text = 'Don\'t let these mean monsters hurt you - get better equipment now!' } +} +npcHandler:addModule(VoiceModule:new(voices)) + +-- Greeting and Farewell +keywordHandler:addGreetKeyword({'hi'}, {npcHandler = npcHandler, text = 'Good day, Ma\'am. How may I help you, |PLAYERNAME|? If you like to see my offers, simply ask me for a trade!'}, function(player) return player:getSex() == PLAYERSEX_FEMALE end) +keywordHandler:addAliasKeyword({'hello'}) +keywordHandler:addGreetKeyword({'hi'}, {npcHandler = npcHandler, text = 'Good day, Sir. How may I help you, |PLAYERNAME|? If you like to see my offers, simply ask me for a trade!'}, function(player) return player:getSex() == PLAYERSEX_FEMALE end) +keywordHandler:addAliasKeyword({'hello'}) +keywordHandler:addFarewellKeyword({'bye'}, {npcHandler = npcHandler, text = 'Good bye, Ma\'am.'}, function(player) return player:getSex() == PLAYERSEX_FEMALE end) +keywordHandler:addAliasKeyword({'farewell'}) +keywordHandler:addFarewellKeyword({'bye'}, {npcHandler = npcHandler, text = 'Good bye, Sir.'}) +keywordHandler:addAliasKeyword({'farewell'}) + +-- Basic keywords +keywordHandler:addKeyword({'hint'}, StdModule.rookgaardHints, {npcHandler = npcHandler}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m Dixi.'}) +keywordHandler:addKeyword({'citizen'}, StdModule.say, {npcHandler = npcHandler, text = ' I love gossiping - err, I mean providing valuable information of course, just tell me a name! '}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m helping my grandfather {Obi} with this shop. If you like to see my offers, simply ask me for a {trade}!'}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = 'It\'s |TIME|.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'You can deposit your {money} there to keep it safe. However, you still need cash to buy something here.'}) +keywordHandler:addKeyword({'destiny'}, StdModule.say, {npcHandler = npcHandler, text = 'The Island of Destiny can be reached via the {oracle} once you are level 8. This trip will help you choose your {profession}!'}) +keywordHandler:addKeyword({'profession'}, StdModule.say, {npcHandler = npcHandler, text = 'You will learn everything you need to know about professions once you reach the {Island of Destiny}.'}) +keywordHandler:addKeyword({'premium'}, StdModule.say, {npcHandler = npcHandler, text = 'As a premium adventurer you can visit different regions on this island, trade with {Lee\'Delle} and much more.'}) +keywordHandler:addKeyword({'equipment'}, StdModule.say, {npcHandler = npcHandler, text = 'As an adventurer, you should always have at least a {backpack}, a {rope}, a {shovel}, a {weapon}, an {armor} and a {shield}.'}) +keywordHandler:addKeyword({'torch'}, StdModule.say, {npcHandler = npcHandler, text = 'If you need a torch, go see {Al Dee}\'s store.'}) +keywordHandler:addKeyword({'weapon'}, StdModule.say, {npcHandler = npcHandler, text = 'Oh, I\'m sorry, but my grandfather {Obi} doesn\'t like seeing me waving around with pointy things. He sells weapons himself, just go downstairs!'}) +keywordHandler:addKeyword({'food'}, StdModule.say, {npcHandler = npcHandler, text = 'Are you hungry? Then you should visit {Willie} or {Billy} in the West of town. {Norma} also has yummy stuff! Oh, and you could pick {blueberries} or eat the food some {monsters} carry with them.'}) +keywordHandler:addKeyword({'potion'}, StdModule.say, {npcHandler = npcHandler, text = '{Lily} sells effective health potions and antidote potions against poison.'}) +keywordHandler:addKeyword({'academy'}, StdModule.say, {npcHandler = npcHandler, text = 'The big building in the centre of Rookgaard. They have a library, a training centre, a {bank} and the room of the {oracle}. {Seymore} is the teacher there.'}) +keywordHandler:addKeyword({'king'}, StdModule.say, {npcHandler = npcHandler, text = 'King Tibianus is a wise and noble monarch. This island of {Rookgaard} belongs to his kingdom.'}) +keywordHandler:addKeyword({'rookgaard'}, StdModule.say, {npcHandler = npcHandler, text = 'Our lovely village will provide shelter for you. Once you are level 8, you can travel to {mainland} and choose a {profession}.'}) +keywordHandler:addKeyword({'mainland'}, StdModule.say, {npcHandler = npcHandler, text = 'If you want to fight monsters in {dungeons}, you definitely need some good {equipment} such as a {weapon}, an {armor} and a {shield}.'}) +keywordHandler:addKeyword({'buy'}, StdModule.say, {npcHandler = npcHandler, text = 'Just ask me for a {trade} to check out my offers.'}) +keywordHandler:addKeyword({'sell'}, StdModule.say, {npcHandler = npcHandler, text = 'Just ask me for a {trade} to see what I buy from you.'}) +keywordHandler:addKeyword({'merchant'}, StdModule.say, {npcHandler = npcHandler, text = 'To view the offers of a merchant, simply talk to him or her and ask for a {trade}.'}) +keywordHandler:addKeyword({'blueberr'}, StdModule.say, {npcHandler = npcHandler, text = 'There are many blueberry bushes in and around this village. Just use them to your liking!'}) +keywordHandler:addKeyword({'dungeon'}, StdModule.say, {npcHandler = npcHandler, text = 'You need to make sure you have some basic {equipment} before you head into dungeons such as the {sewers}.'}) +keywordHandler:addKeyword({'sewer'}, StdModule.say, {npcHandler = npcHandler, text = 'There is a sewer grate which you can use to enter the sewers just left of this building. Eww, this smell!'}) +keywordHandler:addKeyword({'how', 'are', 'you'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m fine, thank you.'}) + +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'How can I help you? I can give you general {hints}, information about {citizens} or talk about many other topics. Just ask me!'}) +keywordHandler:addAliasKeyword({'information'}) + +keywordHandler:addKeyword({'money'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sorry honey, but I can\'t lend you gold. Earn it yourself by fighting {monsters} and picking up the things they carry. Sell it to {merchants} to make profit!'}) +keywordHandler:addAliasKeyword({'gold'}) + +keywordHandler:addKeyword({'backpack'}, StdModule.say, {npcHandler = npcHandler, text = 'You should never embark on an adventure without it. Ask {Al Dee} or {Lee\'Delle} for it!'}) +keywordHandler:addAliasKeyword({'rope'}) +keywordHandler:addAliasKeyword({'shovel'}) +keywordHandler:addAliasKeyword({'fishing'}) + +keywordHandler:addKeyword({'armor'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes, I can sell that to you. Just ask me for a {trade} to see what I buy from you.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addAliasKeyword({'helmet'}) + +keywordHandler:addKeyword({'offer'}, StdModule.say, {npcHandler = npcHandler, text = 'Me and my grandfather {Obi} sell {equipment} of all kinds. Just ask him or me for a {trade} if you like to see our offers.'}) +keywordHandler:addAliasKeyword({'stuff'}) +keywordHandler:addAliasKeyword({'wares'}) + +-- Names +keywordHandler:addKeyword({'norma'}, StdModule.say, {npcHandler = npcHandler, text = 'Norma used to sell {equipment}, but she finally earned enough {money} to fulfil one of her dreams - her own bar!'}) +keywordHandler:addKeyword({'loui'}, StdModule.say, {npcHandler = npcHandler, text = 'I never understand what he\'s talking about.'}) +keywordHandler:addKeyword({'santiago'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m glad that he\'s here. He does a great job!'}) +keywordHandler:addKeyword({'zirella'}, StdModule.say, {npcHandler = npcHandler, text = 'Sometimes, I help Zirella collecting wood. Her old back aches all the time. It\'s a shame her son Tom doesn\'t help her.'}) +keywordHandler:addKeyword({'al', 'dee'}, StdModule.say, {npcHandler = npcHandler, text = 'In Al Dee\'s shop you will find important general equipment such as {ropes}, {shovels} and torches.'}) +keywordHandler:addKeyword({'amber'}, StdModule.say, {npcHandler = npcHandler, text = 'One day, I want to become a brave adventurer like her and leave this town!'}) +keywordHandler:addKeyword({'billy'}, StdModule.say, {npcHandler = npcHandler, text = 'Billy can be kind of scary. He swears a lot and doesn\'t talk to everybody.'}) +keywordHandler:addKeyword({'willie'}, StdModule.say, {npcHandler = npcHandler, text = 'Uncle Willie and {Billy} are farmers, which means they are a good place to sell and buy {food}.'}) +keywordHandler:addKeyword({'cipfried'}, StdModule.say, {npcHandler = npcHandler, text = 'He can heal you if you\'re injured or poisoned.'}) +keywordHandler:addKeyword({'dixi'}, StdModule.say, {npcHandler = npcHandler, text = 'Did I hear my name somewhere?'}) +keywordHandler:addKeyword({'hyacinth'}, StdModule.say, {npcHandler = npcHandler, text = 'I think he\'s a bit strange, living alone outside this village. How can he dislike to chat with everybody here?'}) +keywordHandler:addKeyword({'lee\'delle'}, StdModule.say, {npcHandler = npcHandler, text = 'Lee\'Delle\'s shop is on the {premium} side of the village. You should visit it!'}) +keywordHandler:addKeyword({'lily'}, StdModule.say, {npcHandler = npcHandler, text = 'I always give my cookies and blueberries to Lily. She loves them! Also, she sells {potions}.'}) +keywordHandler:addKeyword({'oracle'}, StdModule.say, {npcHandler = npcHandler, text = 'You can find the oracle on the top floor of the {academy}, just above {Seymour}. Go there when you are level 8 to find your {destiny}.'}) +keywordHandler:addKeyword({'paulie'}, StdModule.say, {npcHandler = npcHandler, text = 'He is the local {bank} clerk.'}) +keywordHandler:addKeyword({'seymour'}, StdModule.say, {npcHandler = npcHandler, text = 'Seymour is a loyal follower of the {king} and a teacher in the {academy}.'}) +keywordHandler:addKeyword({'tom'}, StdModule.say, {npcHandler = npcHandler, text = 'I wish he would talk to his mother {Zirella} again. I feel so sorry for her. Anyway, as Tom is a tanner, you can sell leather and fresh corpses to him.'}) +keywordHandler:addKeyword({'dallheim'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s one of our reliable guardsmen. Without them, many {monsters} would roam the village of {Rookgaard}!'}) +keywordHandler:addAliasKeyword({'zerbrus'}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Um yeah, good day.') +npcHandler:setMessage(MESSAGE_SENDTRADE, 'Here, take a look and choose something nice for you!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/djema.lua b/data/npc/scripts/djema.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/djema.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/doctor_gnomedix.lua b/data/npc/scripts/doctor_gnomedix.lua new file mode 100644 index 00000000000..ac1a3bd819d --- /dev/null +++ b/data/npc/scripts/doctor_gnomedix.lua @@ -0,0 +1,31 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + local player = Player(cid) + if player:getStorageValue(Storage.BigfootBurden.QuestLine) == 5 then + npcHandler:setMessage(MESSAGE_GREET, "Stand still on the examination platform |PLAYERNAME|.") + player:setStorageValue(Storage.BigfootBurden.QuestLine, 6) + end + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if(not npcHandler:isFocused(cid)) then + return false + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/donald_mcronald.lua b/data/npc/scripts/donald_mcronald.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/donald_mcronald.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/dorbin.lua b/data/npc/scripts/dorbin.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/dorbin.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/dorian.lua b/data/npc/scripts/dorian.lua new file mode 100644 index 00000000000..239114a0648 --- /dev/null +++ b/data/npc/scripts/dorian.lua @@ -0,0 +1,196 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.ThievesGuild.Quest) == 1 and player:getStorageValue(Storage.ThievesGuild.Mission01) < 1 then + player:setStorageValue(Storage.ThievesGuild.Mission01, 1) + npcHandler:say({ + 'Your first job is quite easy. The Thaian officials are unwilling to share the wealth they\'ve accumulated in their new town Port Hope. ...', + 'They insist that most resources belong to the crown. This is quite sad, especially ivory is in high demand. Collect 10 elephant tusks and bring them to me.' + }, cid) + elseif player:getStorageValue(Storage.ThievesGuild.Mission01) == 1 then + npcHandler:say('Have you finished your mission?', cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(Storage.ThievesGuild.Quest) == 2 and player:getStorageValue(Storage.ThievesGuild.Mission02) < 1 then + player:setStorageValue(Storage.ThievesGuild.Mission02, 1) + npcHandler:say({ + 'A client of our guild would like to get a certain vase. Unfortunately, it\'s not for sale. Well, by the original owner, that is. ...', + 'We, on the other hand, would gladly sell him the vase. Therefore, it would come in handy if we get this vase in our hands. ...', + 'Luckily, the walls of the owner\'s house are covered with vines, that will make a burglary quite easy. ...', + 'You\'ll still need some lock picks to get the chest open in which the vase is stored. Must be your lucky day, as I\'m selling lock picks for a fair price. ...', + 'You might need some of them to get that chest open. The soon to be ex-owner of that vase is Sarina, the proprietor of Carlin\'s general store.' + }, cid) + elseif player:getStorageValue(Storage.ThievesGuild.Mission02) == 2 then + npcHandler:say('Have you finished your mission?', cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.ThievesGuild.Quest) == 3 and player:getStorageValue(Storage.ThievesGuild.Mission03) < 1 then + player:setStorageValue(Storage.ThievesGuild.Mission03, 1) + npcHandler:say({ + 'Our beloved king will hold a great festivity at the end of the month. Unfortunately he forgot to invite one of our guild\'s representatives. ...', + 'Of course it would be rude to point out this mistake to the king. It will be your job to get us an invitation to the ball. ...', + 'Moreover, It will be a great chance to check the castle for, well, opportunities. I\'m sure you understand. However, it\'s up to that pest Oswald to give out invitations, so he\'s the man you\'re looking for.' + }, cid) + elseif player:getStorageValue(Storage.ThievesGuild.Mission03) == 2 then + npcHandler:say('Have you finished your mission?', cid) + npcHandler.topic[cid] = 4 + elseif player:getStorageValue(Storage.ThievesGuild.Quest) == 4 and player:getStorageValue(Storage.ThievesGuild.Mission04) < 1 then + player:setStorageValue(Storage.ThievesGuild.Mission04, 1) + npcHandler:say({ + 'Your next mission is somewhat bigger and I\'m sure much fun for you. Some new-rich merchant is being a bit more greedy than it\'s good for him. ...', + 'The good thing is he\'s as stupid as greedy, so we have a little but cunning plan. We arranged the boring correspondence in advance, so you\'ll come in when the fun starts. ...', + 'You\'ll disguise yourself as the dwarven ambassador and sell that fool the old dwarven bridge, south of Kazordoon. ...', + 'Well, actually it is a bit more complicated than that. Firstly, you\'ll have to get forged documents. Ask around in the criminal camp to find a forger. ...', + 'Secondly, you\'ll need a disguise. Percybald in Carlin is an eccentric actor that might help you with that. ...', + 'As soon as you got both things, travel to Venore and find the merchant Nurik. Trade the false documents for the famous painting of Mina Losa and bring it to me.' + }, cid) + elseif player:getStorageValue(Storage.ThievesGuild.Mission04) == 7 then + npcHandler:say('Have you finished your mission?', cid) + npcHandler.topic[cid] = 5 + elseif player:getStorageValue(Storage.ThievesGuild.Quest) == 5 and player:getStorageValue(Storage.ThievesGuild.Mission05) < 1 then + player:setStorageValue(Storage.ThievesGuild.Mission05, 1) + npcHandler:say('Some smugglers underneath Tiquanda, north west of Port Hope owe us some debts. Go there and steal their Golden Goblet and bring it to me.', cid) + elseif player:getStorageValue(Storage.ThievesGuild.Mission05) == 1 then + npcHandler:say('Have you finished your mission?', cid) + npcHandler.topic[cid] = 6 + elseif player:getStorageValue(Storage.ThievesGuild.Quest) == 6 and player:getStorageValue(Storage.ThievesGuild.Mission06) < 1 then + player:setStorageValue(Storage.ThievesGuild.Mission06, 1) + npcHandler:say({ + 'Your next job will be kidnapping. You\'ll get us the only creature that this scrupulous trader Theodore Loveless in Liberty Bay holds dear. ...', + 'His little goldfish! To get that fish, you\'ll have to get in his room somehow. ...', + 'As you might know I sell lock picks, but I fear unless you\'re extremely lucky, you won\'t crack this expensive masterpiece of a lock. However, get us that fish, regardless how.' + }, cid) + elseif player:getStorageValue(Storage.ThievesGuild.Mission06) == 3 then + npcHandler:say('Have you finished your mission?', cid) + npcHandler.topic[cid] = 7 + elseif player:getStorageValue(Storage.ThievesGuild.Quest) == 7 and player:getStorageValue(Storage.ThievesGuild.Mission07) < 1 then + player:setStorageValue(Storage.ThievesGuild.Mission07, 1) + npcHandler:say({ + 'We\'d like to ease our lives somewhat. Therefore, we would appreciate the cooperation with one of the Venore city guards. ...', + 'Find some dirt about one of them. It\'s unimportant what it is. As soon as we have a foothold, we\'ll convince him to cooperate. Bring me whatever you may find.' + }, cid) + elseif player:getStorageValue(Storage.ThievesGuild.Mission07) == 1 then + npcHandler:say('Have you finished your mission?', cid) + npcHandler.topic[cid] = 8 + elseif player:getStorageValue(Storage.ThievesGuild.Quest) == 8 and player:getStorageValue(Storage.ThievesGuild.Mission08) < 1 then + player:setStorageValue(Storage.ThievesGuild.Mission08, 1) + player:addItem(8701, 1) + npcHandler:say({ + 'Competition might be an interesting challenge but our guild isn\'t really keen on competition. ...', + 'Unfortunately, we are lacking some good fighters, which is quite a disadvantage against certain other organisations. However, I think you\'re a really good fighter ...', + 'Travel to the Plains of Havoc and find the base of our competitors under the ruins of the dark cathedral ...', + 'On the lowest level, you\'ll find a wall with two trophies. Place a message of our guild on the wall, right between the trophies. On your way, get rid of as many of our competitors as you can.' + }, cid) + elseif player:getStorageValue(Storage.ThievesGuild.Mission08) == 2 then + npcHandler:say('Have you finished your mission?', cid) + npcHandler.topic[cid] = 9 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + player:setStorageValue(Storage.ThievesGuild.Quest, 1) + npcHandler:say({ + 'Excellent. You\'ll learn this trade from scratch. Our operations cover many fields of work. Some aren\'t even illegal. ...', + 'Well, as long as you don\'t get caught at least. Ask me for a mission whenever you\'re ready.' + }, cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + if player:removeItem(3956, 10) then + player:setStorageValue(Storage.ThievesGuild.Mission01, 2) + player:setStorageValue(Storage.ThievesGuild.Quest, 2) + npcHandler:say('What a fine material. That will be worth a coin or two. So far, so good. Ask me for another mission if you\'re ready for it.', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 3 then + if player:removeItem(8760, 1) then + player:setStorageValue(Storage.ThievesGuild.Mission02, 3) + player:setStorageValue(Storage.ThievesGuild.Quest, 3) + npcHandler:say('What an ugly vase. But who am I to question the taste of our customers? Anyway, I might have another mission in store for you.', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 4 then + if player:removeItem(8761, 1) then + player:setStorageValue(Storage.ThievesGuild.Mission03, 3) + player:setStorageValue(Storage.ThievesGuild.Quest, 4) + npcHandler:say({ + 'Ah, the key to untold riches. Don\'t worry, we\'ll make sure that no one will connect you to the disappearance of certain royal possessions. ...', + 'You\'re too valuable to us. Speaking about your value, I might have some other mission for you.' + }, cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 5 then + if player:removeItem(8699, 1) then + player:setStorageValue(Storage.ThievesGuild.Mission04, 8) + player:setStorageValue(Storage.ThievesGuild.Quest, 5) + npcHandler:say('Excellent, that serves this fool right. I fear in your next mission, you\'ll have to get your hands dirty. Just ask me to learn more about it.', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 6 then + if player:removeItem(8698, 1) then + player:setStorageValue(Storage.ThievesGuild.Mission05, 2) + player:setStorageValue(Storage.ThievesGuild.Quest, 6) + npcHandler:say('That goblet is hardly worth all this trouble but we had to insist on our payment. However, I assume you are eager for more missions, so just ask.', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 7 then + if player:removeItem(8766, 1) then + player:setStorageValue(Storage.ThievesGuild.Mission06, 4) + player:setStorageValue(Storage.ThievesGuild.Quest, 7) + npcHandler:say('This little goldfish will bring us a hefty ransom! Just ask me if you\'re ready for another mission.', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 8 then + if player:removeItem(8763, 1) then + player:setStorageValue(Storage.ThievesGuild.Mission07, 2) + player:setStorageValue(Storage.ThievesGuild.Quest, 8) + npcHandler:say({ + 'Excellent, that little letter will do the trick for sure ...', + 'I think you\'re really capable and if you finish another mission, I\'ll allow you full access to our black market of lost and found items. Just ask me to learn more about that mission.' + }, cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 9 then + player:setStorageValue(Storage.ThievesGuild.Mission08, 3) + player:setStorageValue(Storage.ThievesGuild.Quest, 9) + player:setStorageValue(Storage.ThievesGuild.Door, 1) + npcHandler:say({ + 'Once again you\'ve finished your job, and I\'ll keep my promise. From now on, you can trade with old Black Bert somewhere upstairs to get access to certain items that mightbe of value to someone like you. ...', + 'If you like, you can also enter the room to the left and pick one item of your choice.' + }, cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'thieves') or msgcontains(msg, 'join') then + if player:getStorageValue(Storage.ThievesGuild.Quest) < 1 then + npcHandler:say('Hm. Well, we could use some fresh blood. Ahum. Do you want to join the thieves guild, |PLAYERNAME|?', cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, 'lock pick') then + npcHandler:say('Yes, I sell lock picks. Ask me for a trade.', cid) + end + return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye, |PLAYERNAME|!') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye, |PLAYERNAME|!') +npcHandler:setMessage(MESSAGE_GREET, 'Greetings, |PLAYERNAME|!') +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/doubleday.lua b/data/npc/scripts/doubleday.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/doubleday.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/doug.lua b/data/npc/scripts/doug.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/doug.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/dove.lua b/data/npc/scripts/dove.lua new file mode 100644 index 00000000000..e6321c7a252 --- /dev/null +++ b/data/npc/scripts/dove.lua @@ -0,0 +1,48 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "measurements") then + if player:getStorageValue(Storage.Postman.Mission07) >= 1 and player:getStorageValue(Storage.Postman.MeasurementsDove) ~= 1 then + npcHandler:say("Oh no! I knew that day would come! I am slightly above the allowed weight and if you can't supply me with some grapes to slim down I will get fired. Do you happen to have some grapes with you? ", cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say("...", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + if player:removeItem(2681, 1) then + npcHandler:say("Oh thank you! Thank you so much! So listen ... ", cid) + player:setStorageValue(Storage.Postman.Mission07, player:getStorageValue(Storage.Postman.Mission07) + 1) + player:setStorageValue(Storage.Postman.MeasurementsDove, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Oh, you don\'t have it.", cid) + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/dr_merlay.lua b/data/npc/scripts/dr_merlay.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/dr_merlay.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/dreadeye.lua b/data/npc/scripts/dreadeye.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/dreadeye.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/dream_butterfly.lua b/data/npc/scripts/dream_butterfly.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/dream_butterfly.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/dregor.lua b/data/npc/scripts/dregor.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/dregor.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/drog.lua b/data/npc/scripts/drog.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/drog.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/dronk.lua b/data/npc/scripts/dronk.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/dronk.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/druid_yandur.lua b/data/npc/scripts/druid_yandur.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/druid_yandur.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/drystan_wildweed.lua b/data/npc/scripts/drystan_wildweed.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/drystan_wildweed.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/dukosch.lua b/data/npc/scripts/dukosch.lua new file mode 100644 index 00000000000..e752a19dda7 --- /dev/null +++ b/data/npc/scripts/dukosch.lua @@ -0,0 +1,56 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + -- WAGON TICKET + if(msgcontains(msg, "ticket")) then + if player:getStorageValue(Storage.WagonTicket) < os.time() then + npcHandler:say("Do you want to purchase a weekly ticket for the ore wagons? With it you can travel freely and swiftly through Kazordoon for one week. 250 gold only. Deal?", cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say("Your weekly ticket is still valid. Would be a waste of money to purchase a second one", cid) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "yes")) then + if(npcHandler.topic[cid] == 1) then + if player:getMoney() + player:getBankBalance() >= 250 then + player:removeMoneyNpc(250) + player:setStorageValue(Storage.WagonTicket, os.time() + 7 * 24 * 60 * 60) + npcHandler:say("Here is your stamp. It can't be transferred to another person and will last one week from now. You'll get notified upon using an ore wagon when it isn't valid anymore.", cid) + else + npcHandler:say("You don't have enough money.", cid) + end + npcHandler.topic[cid] = 0 + end + elseif(npcHandler.topic[cid] == 1) then + if(msgcontains(msg, "no")) then + npcHandler:say("No then.", cid) + npcHandler.topic[cid] = 0 + end + -- WAGON TICKET + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "Welcome, |PLAYERNAME|! Do you feel adventurous? Do you want a weekly {ticket} for the ore wagon system here? You can use it right here to get to the centre of Kazordoon!") +npcHandler:setMessage(MESSAGE_FAREWELL, "Hope to see you again.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/duncan.lua b/data/npc/scripts/duncan.lua new file mode 100644 index 00000000000..949d8d00079 --- /dev/null +++ b/data/npc/scripts/duncan.lua @@ -0,0 +1,177 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + local storage = Storage.OutfitQuest.PirateSabreAddon + + if isInArray({'outfit', 'addon'}, msg) and player:getStorageValue(Storage.OutfitQuest.PirateBaseOutfit) == 1 then + npcHandler:say( + "You're talking about my sabre? Well, even though you earned our trust, \ + you'd have to fulfill a task first before you are granted to wear such a sabre.", + cid) + elseif msgcontains(msg, 'mission') then + if player:getStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven) == 6 then + npcHandler:say( + 'I need a new quality atlas for our captains. Only one of the best will do it. \ + I heard the explorers society sells the best, but only to members of a certain rank. \ + You will have to get this rank or ask a high ranking member to buy it for you.', + cid) + player:setStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven, 7) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven) == 7 then + npcHandler:say('Did you get an atlas of the explorers society as I requested?', cid) + npcHandler.topic[cid] = 6 + elseif + player:getStorageValue(Storage.TheShatteredIsles.RaysMission2) > 0 and + player:getStorageValue(Storage.TheShatteredIsles.TortoiseEggNargorDoor) < 0 + then + npcHandler:say( + 'You did some impressive things. I think people here start considering you as one of us. \ + But these are dire times and everyone of us is expected to give his best and even exceed himself. \ + Do you think you can handle that?', + cid) + npcHandler.topic[cid] = 7 + elseif player:getStorageValue(Storage.TheShatteredIsles.TortoiseEggNargorDoor) == 1 then + npcHandler:say('Did you rescue one of those poor soon-to-be baby tortoises from Nargor?', cid) + npcHandler.topic[cid] = 8 + end + elseif msgcontains(msg, 'task') then + if player:getStorageValue(storage) < 1 then + npcHandler:say( + "Are you up to the task which I'm going to give you and willing to prove you're worthy of wearing such a sabre?", + cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, 'eye patches') then + if player:getStorageValue(storage) == 1 then + npcHandler:say('Have you gathered 100 eye patches?', cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, 'peg legs') then + if player:getStorageValue(storage) == 2 then + npcHandler:say('Have you gathered 100 peg legs?', cid) + npcHandler.topic[cid] = 4 + end + elseif msgcontains(msg, 'hooks') then + if player:getStorageValue(storage) == 3 then + npcHandler:say('Have you gathered 100 hooks?', cid) + npcHandler.topic[cid] = 5 + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + npcHandler:say( + { + 'Listen, the task is not that hard. Simply prove that you are with us and not with the \ + pirates from Nargor by bringingme some of their belongings. ...', + 'Bring me 100 of their eye patches, 100 of their peg legs and 100 of their hooks, in that order. ...', + 'Have you understood everything I told you and are willing to handle this task?' + }, + cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + player:setStorageValue(storage, 1) + player:setStorageValue(Storage.OutfitQuest.DefaultStart, 1) --this for default start of Outfit and Addon Quests + npcHandler:say('Good! Come back to me once you have gathered 100 eye patches.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + if player:removeItem(6098, 100) then + player:setStorageValue(storage, 2) + npcHandler:say('Good job. Alright, now bring me 100 peg legs.', cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have it...", cid) + end + elseif npcHandler.topic[cid] == 4 then + if player:removeItem(6126, 100) then + player:setStorageValue(storage, 3) + npcHandler:say('Nice. Lastly, bring me 100 pirate hooks. That should be enough to earn your sabre.', cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have it...", cid) + end + elseif npcHandler.topic[cid] == 5 then + if player:removeItem(6097, 100) then + player:setStorageValue(storage, 4) + npcHandler:say( + "I see, I see. Well done. Go to Morgan and tell him this codeword: 'firebird'. He'll know what to do.", + cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have it...", cid) + end + elseif npcHandler.topic[cid] == 6 then + if player:getStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven) == 7 then + if player:removeItem(6108, 1) then + npcHandler:say('Indeed, what a fine work... the book I mean. Your work was acceptable all in all.', cid) + player:setStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven, 8) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have it...", cid) + npcHandler.topic[cid] = 0 + end + end + elseif npcHandler.topic[cid] == 7 then + if player:getStorageValue(Storage.TheShatteredIsles.TortoiseEggNargorDoor) < 0 then + npcHandler:say( + { + 'I am glad to hear this. Please listen. The pirates on Nargor are breeding tortoises. \ + They think eating tortoises makes a hard man even harder. ...', + "However I am quite fond of tortoises and can't stand the thought of them being eaten. \ + So I convinced Captain Striker that I can train them to help us. As a substitute for rafts and such ...", + 'All I need is one tortoise egg from Nargor. \ + This is the opportunity to save a tortoise from a gruesome fate! ...', + 'I will ask Sebastian to bring you there. \ + Travel to Nargor, find their tortoise eggs and bring me at least one of them.' + }, + cid) + player:setStorageValue(Storage.TheShatteredIsles.TortoiseEggNargorDoor, 1) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 8 then + if player:getStorageValue(Storage.TheShatteredIsles.TortoiseEggNargorDoor) == 1 then + if player:removeItem(6125, 1) then + npcHandler:say( + 'A real tortoise egg ... I guess you are more accustomed to rescue some \ + noblewoman in distress but you did something goodtoday.', + cid + ) + player:setStorageValue(Storage.TheShatteredIsles.TortoiseEggNargorDoor, 2) + player:addAchievement('Animal Activist') + player:setStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven, 16) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have it...", cid) + npcHandler.topic[cid] = 0 + end + end + end + elseif msgcontains(msg, 'no') then + if npcHandler.topic[cid] >= 1 then + npcHandler:say('Then no.', cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/duria.lua b/data/npc/scripts/duria.lua new file mode 100644 index 00000000000..8e97fa70fe7 --- /dev/null +++ b/data/npc/scripts/duria.lua @@ -0,0 +1,32 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addSpellKeyword({'find', 'person'}, {npcHandler = npcHandler, spellName = 'Find Person', price = 80, level = 8, vocation = VOCATION.CLIENT_ID.KNIGHT}) +keywordHandler:addSpellKeyword({'light'}, {npcHandler = npcHandler, spellName = 'Light', price = 0, level = 8, vocation = VOCATION.CLIENT_ID.KNIGHT}) +keywordHandler:addSpellKeyword({'cure', 'poison'}, {npcHandler = npcHandler, spellName = 'Cure Poison', price = 150, level = 10, vocation = VOCATION.CLIENT_ID.KNIGHT}) +keywordHandler:addSpellKeyword({'wound', 'cleansing'}, {npcHandler = npcHandler, spellName = 'Wound Cleansing', price = 0, level = 8, vocation = VOCATION.CLIENT_ID.KNIGHT}) +keywordHandler:addSpellKeyword({'great', 'light'}, {npcHandler = npcHandler, spellName = 'Great Light', price = 500, level = 13, vocation = VOCATION.CLIENT_ID.KNIGHT}) + +keywordHandler:addKeyword({'healing', 'spells'}, StdModule.say, {npcHandler = npcHandler, text = "In this category I have '{Wound Cleansing}' and '{Cure Poison}'."}) +keywordHandler:addKeyword({'support', 'spells'}, StdModule.say, {npcHandler = npcHandler, text = "In this category I have '{Light}', '{Find Person}' and '{Great Light}'."}) +keywordHandler:addKeyword({'spells'}, StdModule.say, {npcHandler = npcHandler, text = 'I can teach you {healing spells} and {support spells}. What kind of spell do you wish to learn? You can also tell me for which level you would like to learn a spell, if you prefer that.'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Hiho, fellow knight |PLAYERNAME|!') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Goodbye.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Be carefull out there, jawoll.') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/dustrunner.lua b/data/npc/scripts/dustrunner.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/dustrunner.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/eathar.lua b/data/npc/scripts/eathar.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/eathar.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/eclesius.lua b/data/npc/scripts/eclesius.lua new file mode 100644 index 00000000000..222520c550f --- /dev/null +++ b/data/npc/scripts/eclesius.lua @@ -0,0 +1,31 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = "I'm looking for a new assistant!" }, + { text = "Err, what was it again that I wanted...?" }, + { text = "Do come in! Mind the step of the magical door, though." }, + { text = "I'm so sorry... I promise it won't happen again. Problem is, I can't remember where I made the error..." }, + { text = "Actually, I STILL prefer inexperienced assistants. They're easier to keep an eye on and don't tend to backstab you." }, + { text = "So much to do, so much to do... uh... where should I start?" } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "Who are you? What do you want? You seem too experienced to become my assistant. Please leave.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/edala.lua b/data/npc/scripts/edala.lua new file mode 100644 index 00000000000..8561cc97284 --- /dev/null +++ b/data/npc/scripts/edala.lua @@ -0,0 +1,107 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local config = { + [1] = 'Ashari, |PLAYERNAME|. How... nice to see a human taking interest in a beautiful art such as music.', + [2] = 'Ashari, |PLAYERNAME|... that sound was.. interesting.', + [3] = 'Ashari, |PLAYERNAME|. You\'ve made some... progress playing the lyre, haven\'t you..? I want to believe you have.', + [4] = '|PLAYERNAME|. My regular visitor. I certainly... appreciate your efforts to entertain me, but let me assure you, I\'m quite comfortable up here by myself. Alone. In silence.', + [5] = 'Ashari, |PLAYERNAME|. I\'m starting to feel a little sorry... for your lyre. Being forced to produce such noise must be a tragic fate.', + [6] = '|PLAYERNAME|! You\'re driving me insane! I beg you, take your lyre away from this sacred and peaceful place.', + [7] = '|PLAYERNAME|! My ears! I\'d prefer listening to drunken dwarves rambling all day to the sound of your lyre! Please, at least get it tuned. Here, you can have this elvish diapason.' +} + +local function greetCallback(cid) + local player = Player(cid) + local lyreProgress = player:getStorageValue(Storage.Diapason.Lyre) + local greetMessage = config[lyreProgress] + if greetMessage + and player:getStorageValue(Storage.Diapason.Edala) == 1 + and player:getStorageValue(Storage.Diapason.EdalaTimer) < os.time() then + player:setStorageValue(Storage.Diapason.Edala, 0) + player:setStorageValue(Storage.Diapason.EdalaTimer, os.time() + 86400) + if lyreProgress == 7 then + player:setStorageValue(Storage.Diapason.Lyre, 8) + player:addItem(13536, 1) + end + npcHandler:setMessage(MESSAGE_GREET, greetMessage) + else + npcHandler:setMessage(MESSAGE_GREET, 'Ashari, |PLAYERNAME|.') + end + return true +end + +-- Fire of the Suns +local blessKeyword = keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'Would you like to receive that protection for a sacrifice of |BLESSCOST| gold, child?'}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the fire of the suns, pilgrim.', cost = '|BLESSCOST|', bless = 4}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) +keywordHandler:addAliasKeyword({'fire'}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.'}, function(player) return player:hasBlessing(2) end) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin will provide you with the embrace of Tibia.'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +-- Greeting message +keywordHandler:addGreetKeyword({"ashari"}, {npcHandler = npcHandler, text = "Greetings, |PLAYERNAME|."}) +--Farewell message +keywordHandler:addFarewellKeyword({"asgha thrazi"}, {npcHandler = npcHandler, text = "Asha Thrazi, |PLAYERNAME|."}) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Asha Thrazi, |PLAYERNAME|!') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Asha Thrazi, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/eddy.lua b/data/npc/scripts/eddy.lua new file mode 100644 index 00000000000..a3c9887ec3b --- /dev/null +++ b/data/npc/scripts/eddy.lua @@ -0,0 +1,26 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Have you moved to a new home? I\'m the specialist for equipping it.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +keywordHandler:addKeyword({'furniture'}, StdModule.say, {npcHandler = npcHandler, text = "I have {beds}, {chairs}, {containers}, {decoration}, {flowers}, {instruments}, {pillows}, {pottery}, {statues}, {tapestries} and {tables}. Which of those would you like to see?"}) + +npcHandler:setMessage(MESSAGE_GREET, "Hello |PLAYERNAME|! Do you need some equipment for your house?") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Have a look. Most furniture comes in handy kits. Just use them in your house to assemble the furniture. Do you want to see only a certain {type} of furniture?") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/edgar-ellen.lua b/data/npc/scripts/edgar-ellen.lua new file mode 100644 index 00000000000..0b0e3bc9cf1 --- /dev/null +++ b/data/npc/scripts/edgar-ellen.lua @@ -0,0 +1,51 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Orshabaal was out of his maze to make us suffer for many days. In Calmera, a knight with blue beard from his hideout appeared. He fought bravely supported by mages, the demon ran and is gone for ages.' }, + { text = 'A knight from Guardia needed Chayenne\'s key. His friend dropped the item on the floor, hoping no one would see. But, at the same moment, a man crossed their way and all the knight\'s dreams faded away.' }, + { text = 'A knight from Candia was dining at Frodo\'s hut, devouring plates full of meat and whatnot. Suddenly, he was called to fight. He wanted to put his armor on but it was too tight.' }, + { text = 'The druid entered a Premian pyramid intent on the kill, \'Oh, that djinn will die, it will!\' Down and up the stairs she hopped like a cat... When, Oops! She moved the wrong way, and died a drunk rat.' }, + { text = 'Hoping to find a strange orc in his spawn, a Zaneran knight logged on before dawn. A sudden heart attack left him surprised as Sam\'s old backpack he had recognised.' }, + { text = 'The world I shall save\', an Olympian knight proclaimed! But from a visit to the bar he could not abstain! He woke up in pain, it all was in vain. From Venorian beer he will forever refrain.' }, + { text = 'During the dark and scary night, when others sleep he goes to fight, banishing demons, that feels right, purging the evil on the sight, fearlessly waiting for daylight, Zeluna\'s bravest elite knight.' }, + { text = 'A druid from Celesta once talked with a girl, he even bought her a necklace with a huge white pearl. Every time he went home, without money and fame, I guess this girl is cursed, Aruda is the name.' }, + { text = 'A story of a knight untold, on Rowana the dice she rolled. She lured players from afar. Who could resist a shining star? She promised gold and many items, then stole their heart with cunning kindness.' }, + { text = 'Do you think it\'s just a game? Don\'t you fear the dragon\'s flame? If you are as brave as bright, if you do not stray from fight, you may want to hear tonight, the tale of Guardia\'s lonely knight.' }, + { text = 'For a knight from Yanara 10,000 gold were a lot. So he ventured with a team into the desert to win that pot. He solved all the riddles, strongly willed. But on his journey home he sadly was killed.' }, + { text = 'A great mage from Celesta went dungeon down deep, he was very brave but his wand was cheap. Among white skeletons one of them was red. Last what he saw were the words: \'You are dead!\'' }, + { text = 'A young sorcerer born and raised on Astera when dragons were scary, it was that kind of era. Walking all the way to the city of Venore, he stole from the dwarven bridge nothing less than an iron ore.' }, + { text = 'A druid from Eternia just bought his first boots of haste, to finally have his leather boots replaced. Catching a backpack of fish was now his dream, but he ended up swinging his new boots upstream.' }, + { text = 'A sorcerer from Efidia took his horse and got it saddled, and set out for battle. His horse lost control and threw him into a hole. Now his team lost all hope, because he forgot to bring a rope.' }, + { text = 'A knight in Guardia was feeling bored. He wanted to show a dragon lord the taste of his new carlin sword. To its lair then he did go. But before he saw his foe, he met his end by a one hit K.O.' }, + { text = 'On Secura a confident knight levelled to main, 840 rats he had slain. \'I am going to kill dragons,\' he said while pounding his breastplate. The next thing he saw was: \'You have met a sad fate.\'' }, + { text = 'One morning frosty fresh and nice, a knight was fishing on the ice. Catching some pikes for soup, but a dire penguin ate his loot. His angry wife said in the house: Now whole Beneva will laugh at us!' }, + { text = 'A paladin slaying dragons on Antica\'s soil, when a lord charges on to make the adventurer\'s blood boil. It puts up a strong fight, but to no avail. It gets slain and drops a dragon scale mail!' }, + { text = 'Through Rookgaard\'s sewer there swarmed no fewer than a hundred screeching rats. Wading through mud, and covered in blood, two young men fought back-to-back. To Trimera\'s end; a knight, and a friend.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = "Our world, our home, our very own plane of existence. We have to protect it, mind you. Underneath all the battles, challenges and monsters there still resides a majestic, yet vulnerable being. A mother to us all."}) +keywordHandler:addKeyword({'king'}, StdModule.say, {npcHandler = npcHandler, text = "A king and a beggar know more than a king alone... ahem, except for King Tibianus. He most certainly would. All hail King Tibianus etc. etc."}) +keywordHandler:addKeyword({'mission'}, StdModule.say, {npcHandler = npcHandler, text = "So, you're on a mission. Aren't we all? A quest to savour the important moments, the valuable memories? To fight for love and happiness, heroically and against all odds? Yes, we are indeed."}) +keywordHandler:addKeyword({'quest'}, StdModule.say, {npcHandler = npcHandler, text = "So, you're on a mission. Aren't we all? A quest to savour the important moments, the valuable memories? To fight for love and happiness, heroically and against all odds? Yes, we are indeed."}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "Rather a calling. The weight of words is something not easily lifted by some, yet it can be a mighty weapon to others. ..."}) -- Need to add the rest in a second delayed msg --It is my duty to see to it that the words of mighty poets all over Tibia are spread and carried with the heart and prowess they deserve. + +npcHandler:setMessage(MESSAGE_GREET, "This world is nothing without poetry, don't you think? It gives us hope, it envokes love. It's inciting and invigorating all the same.") +npcHandler:setMessage(MESSAGE_FAREWELL, " Goodbye and farewell, my friend.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/edmund.lua b/data/npc/scripts/edmund.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/edmund.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/edoch.lua b/data/npc/scripts/edoch.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/edoch.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/edowir.lua b/data/npc/scripts/edowir.lua new file mode 100644 index 00000000000..800bc5039a0 --- /dev/null +++ b/data/npc/scripts/edowir.lua @@ -0,0 +1,27 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'I\'m just an old man, but I know a lot about Tibia.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I gather wisdom and knowledge. I am also an astrologer."}) + +npcHandler:setMessage(MESSAGE_GREET, "Oh, hello |PLAYERNAME|! How nice of you to visit an old man like me.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Come back whenever you're in need of wisdom.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Come back whenever you're in need of wisdom.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/edron_guardsman.lua b/data/npc/scripts/edron_guardsman.lua new file mode 100644 index 00000000000..dcb301f7969 --- /dev/null +++ b/data/npc/scripts/edron_guardsman.lua @@ -0,0 +1,26 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + npcHandler:say('Move on!', cid) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + return false +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/edvard.lua b/data/npc/scripts/edvard.lua new file mode 100644 index 00000000000..9f0fd513f13 --- /dev/null +++ b/data/npc/scripts/edvard.lua @@ -0,0 +1,25 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Have you moved to a new home? I\'m the specialist for equipping it.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +keywordHandler:addKeyword({'furniture'}, StdModule.say, {npcHandler = npcHandler, text = "Well, as you can see, I sell furniture. Ask me for a {trade} if you're interested to see my wares."}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome to Edron Furniture Store, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Have a look. Most furniture comes in handy kits. Just use them in your house to assemble the furniture. Do you want to see only a certain {type} of furniture?") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/eirik.lua b/data/npc/scripts/eirik.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/eirik.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/elane.lua b/data/npc/scripts/elane.lua new file mode 100644 index 00000000000..68909e998a3 --- /dev/null +++ b/data/npc/scripts/elane.lua @@ -0,0 +1,190 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "addon") or msgcontains(msg, "outfit") then + if player:getStorageValue(Storage.OutfitQuest.HunterHatAddon) < 1 then + npcHandler:say("Oh, my winged tiara? Those are traditionally awarded after having completed a difficult {task} for our guild, only to female aspirants though. Male warriors will receive a hooded cloak.", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "task") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("So you are saying that you would like to prove that you deserve to wear such a hooded cloak?", cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, "crossbow") then + if player:getStorageValue(Storage.OutfitQuest.HunterHatAddon) == 1 then + npcHandler:say("I'm so excited! Have you really found my crossbow?", cid) + npcHandler.topic[cid] = 4 + end + elseif msgcontains(msg, "leather") then + if player:getStorageValue(Storage.OutfitQuest.HunterHatAddon) == 2 then + npcHandler:say("Did you bring me 100 pieces of lizard leather and 100 pieces of red dragon leather?", cid) + npcHandler.topic[cid] = 5 + end + elseif msgcontains(msg, "chicken wing") then + if player:getStorageValue(Storage.OutfitQuest.HunterHatAddon) == 3 then + npcHandler:say("Were you able to get hold of 5 enchanted chicken wings?", cid) + npcHandler.topic[cid] = 6 + end + elseif msgcontains(msg, "steel") then + if player:getStorageValue(Storage.OutfitQuest.HunterHatAddon) == 4 then + npcHandler:say("Ah, have you brought one piece of royal steel, draconian steel and hell steel each?", cid) + npcHandler.topic[cid] = 7 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 2 then + npcHandler:say({ + "Alright, I will give you a chance. Pay close attention to what I'm going to tell you now. ...", + "Recently, one of our members moved to Liberty Bay out of nowhere, talking about some strange cult. That is not the problem, but he took my favourite crossbow with him. ...", + "Please find my crossbow. It has my name engraved on it and is very special to me. ...", + "Secondly, we need a lot of leather for new quivers. 100 pieces of lizard leather and 100 pieces of red dragon leather should suffice. ...", + "Third, since we are giving out tiaras, we are always in need of enchanted chicken wings. Please bring me 5, that would help us tremendously. ...", + "Lastly, for our arrow heads we need a lot of steel. Best would be one piece of royal steel, one piece of draconian steel and one piece of hell steel. ...", + "Did you understand everything I told you and are willing to handle this task?" + }, cid) + npcHandler.topic[cid] = 3 + elseif npcHandler.topic[cid] == 3 then + npcHandler:say("That's the spirit! I hope you will find my crossbow, |PLAYERNAME|!", cid) + player:setStorageValue(Storage.OutfitQuest.HunterHatAddon, 1) + player:setStorageValue(Storage.OutfitQuest.DefaultStart, 1) --this for default start of Outfit and Addon Quests + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 4 then + if player:removeItem(5947, 1) then + npcHandler:say("Yeah! I could kiss you right here and there! Besides, you're a handsome one. Please bring me 100 pieces of lizard leather and 100 pieces of red dragon leather now!", cid) + player:setStorageValue(Storage.OutfitQuest.HunterHatAddon, 2) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have it...", cid) + end + elseif npcHandler.topic[cid] == 5 then + if player:getItemCount(5876) >= 100 and player:getItemCount(5948) >= 100 then + npcHandler:say("Good work, |PLAYERNAME|! That is enough leather for a lot of sturdy quivers. Now, please bring me 5 enchanted chicken wings.", cid) + player:removeItem(5876, 100) + player:removeItem(5948, 100) + player:setStorageValue(Storage.OutfitQuest.HunterHatAddon, 3) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have it...", cid) + end + elseif npcHandler.topic[cid] == 6 then + if player:removeItem(5891, 5) then + npcHandler:say("Great! Now we can create a few more Tiaras. If only they weren't that expensive... Well anyway, please obtain one piece of royal steel, draconian steel and hell steel each.", cid) + player:setStorageValue(Storage.OutfitQuest.HunterHatAddon, 4) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have it...", cid) + end + elseif npcHandler.topic[cid] == 7 then + if player:getItemCount(5887) >= 1 and player:getItemCount(5888) >= 1 and player:getItemCount(5889) >= 1 then + npcHandler:say("Wow, I'm impressed, |PLAYERNAME|. Your really are a valuable member of our paladin guild. I shall grant you your reward now. Wear it proudly!", cid) + player:removeItem(5887, 1) + player:removeItem(5888, 1) + player:removeItem(5889, 1) + player:setStorageValue(Storage.OutfitQuest.HunterHatAddon, 5) + player:addOutfitAddon(129, 1) + player:addOutfitAddon(137, 2) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have it...", cid) + end + end + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] > 1 then + npcHandler:say("Then no.", cid) + npcHandler.topic[cid] = 0 + end + return true + end +end + +-- Sniper Gloves +keywordHandler:addKeyword({'sniper gloves'}, StdModule.say, {npcHandler = npcHandler, text = 'We are always looking for sniper gloves. They are supposed to raise accuracy. If you find a pair, bring them here. Maybe I can offer you a nice trade.'}, function(player) return player:getItemCount(5875) == 0 end) + +local function addGloveKeyword(text, condition, action) + local gloveKeyword = keywordHandler:addKeyword({'sniper gloves'}, StdModule.say, {npcHandler = npcHandler, text = text[1]}, condition) + gloveKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = text[2], reset = true}, function(player) return player:getItemCount(5875) == 0 end) + gloveKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = text[3], reset = true}, nil, action) + gloveKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = text[2], reset = true}) +end + +-- Free Account +addGloveKeyword({ + 'You found sniper gloves?! Incredible! I would love to grant you the sniper gloves accessory, but I can only do that for premium warriors. However, I would pay you 2000 gold pieces for them. How about it?', + 'Maybe another time.', + 'Alright! Here is your money, thank you very much.' + }, function(player) return not player:isPremium() end, function(player) player:removeItem(5875, 1) player:addMoney(2000) end +) + +-- Premium account with addon +addGloveKeyword({ + 'Did you find sniper gloves AGAIN?! Incredible! I cannot grant you other accessories, but would you like to sell them to me for 2000 gold pieces?', + 'Maybe another time.', + 'Alright! Here is your money, thank you very much.' + }, function(player) return player:getStorageValue(Storage.OutfitQuest.Hunter.AddonGlove) == 1 end, function(player) player:removeItem(5875, 1) player:addMoney(2000) end +) + +-- If you don't have the addon +addGloveKeyword({ + 'You found sniper gloves?! Incredible! Listen, if you give them to me, I will grant you the right to wear the sniper gloves accessory. How about it?', + 'No problem, maybe another time.', + 'Great! I hereby grant you the right to wear the sniper gloves as an accessory. Congratulations!' + }, function(player) return player:getStorageValue(Storage.OutfitQuest.Hunter.AddonGlove) == -1 end, function(player) player:removeItem(5875, 1) player:setStorageValue(Storage.OutfitQuest.Hunter.AddonGlove, 1) player:addOutfitAddon(129, 2) player:addOutfitAddon(137, 1) player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) end +) + +-- Basic +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = "I am the leader of the Paladins. I help our members."}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am the leader of the Paladins. I help our members."}) +keywordHandler:addKeyword({'paladins'}, StdModule.say, {npcHandler = npcHandler, text = "Paladins are great warriors and magicians. Besides that we are excellent missile fighters. Many people in Tibia want to join us."}) +keywordHandler:addKeyword({'warriors'}, StdModule.say, {npcHandler = npcHandler, text = "Of course, we aren't as strong as knights, but no druid or sorcerer will ever defeat a paladin with a sword."}) +keywordHandler:addKeyword({'magicians'}, StdModule.say, {npcHandler = npcHandler, text = "There are many magic spells and runes paladins can use."}) +keywordHandler:addKeyword({'missile'}, StdModule.say, {npcHandler = npcHandler, text = "Paladins are the best missile fighters in Tibia!"}) +keywordHandler:addKeyword({'news'}, StdModule.say, {npcHandler = npcHandler, text = "I am a paladin, not a storyteller."}) +keywordHandler:addKeyword({'members'}, StdModule.say, {npcHandler = npcHandler, text = "Every paladin profits from his vocation. It has many advantages to be a paladin."}) +keywordHandler:addKeyword({'advantages'}, StdModule.say, {npcHandler = npcHandler, text = "We will help you to improve your skills. Besides I offer spells for paladins."}) +keywordHandler:addKeyword({'general'}, StdModule.say, {npcHandler = npcHandler, text = "Harkath Bloodblade is the royal general."}) +keywordHandler:addKeyword({'army'}, StdModule.say, {npcHandler = npcHandler, text = "Some paladins serve in the kings army."}) +keywordHandler:addKeyword({'baxter'}, StdModule.say, {npcHandler = npcHandler, text = "He has some potential."}) +keywordHandler:addKeyword({'bozo'}, StdModule.say, {npcHandler = npcHandler, text = "How spineless do you have to be to become a jester?"}) +keywordHandler:addKeyword({'mcronald'}, StdModule.say, {npcHandler = npcHandler, text = "The McRonalds are simple farmers."}) +keywordHandler:addKeyword({'eclesius'}, StdModule.say, {npcHandler = npcHandler, text = "He must have been skilled before he became the way he is now. Such a pity."}) +keywordHandler:addKeyword({'elane'}, StdModule.say, {npcHandler = npcHandler, text = "Yes?"}) +keywordHandler:addKeyword({'frodo'}, StdModule.say, {npcHandler = npcHandler, text = "The alcohol he sells shrouds the mind and the eye."}) +keywordHandler:addKeyword({'galuna'}, StdModule.say, {npcHandler = npcHandler, text = "One of the most important members of our guild. She makes all the bows and arrows we need."}) +keywordHandler:addKeyword({'gorn'}, StdModule.say, {npcHandler = npcHandler, text = "He sells a lot of useful equipment."}) +keywordHandler:addKeyword({'gregor'}, StdModule.say, {npcHandler = npcHandler, text = "He and his guildfellows lack the grace of a true warrior."}) +keywordHandler:addKeyword({'harkath bloodblade'}, StdModule.say, {npcHandler = npcHandler, text = "A fine warrior and a skilled general."}) +keywordHandler:addKeyword({'king tibianus'}, StdModule.say, {npcHandler = npcHandler, text = "King Tibianus is a wise ruler."}) +keywordHandler:addKeyword({'lugri'}, StdModule.say, {npcHandler = npcHandler, text = "A follower of evil that will get what he deserves one day."}) +keywordHandler:addKeyword({'lynda'}, StdModule.say, {npcHandler = npcHandler, text = "Mhm, a little too nice for my taste. Still, it's amazing how she endures all those men stalking her, especially this creepy Oswald."}) +keywordHandler:addKeyword({'marvik'}, StdModule.say, {npcHandler = npcHandler, text = "A skilled healer, that's for sure."}) +keywordHandler:addKeyword({'muriel'}, StdModule.say, {npcHandler = npcHandler, text = "Just another arrogant sorcerer."}) +keywordHandler:addKeyword({'oswald'}, StdModule.say, {npcHandler = npcHandler, text = "If there wouldn't be higher powers to protect him..."}) +keywordHandler:addKeyword({'quentin'}, StdModule.say, {npcHandler = npcHandler, text = "A humble monk and a wise man."}) +keywordHandler:addKeyword({'sam'}, StdModule.say, {npcHandler = npcHandler, text = "Strong man. But a little shy."}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome to the paladins' guild, |PLAYERNAME|! How can I help you?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Bye, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Bye, |PLAYERNAME|.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/elathriel.lua b/data/npc/scripts/elathriel.lua new file mode 100644 index 00000000000..2bf6b32b383 --- /dev/null +++ b/data/npc/scripts/elathriel.lua @@ -0,0 +1,273 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({"business"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I am the leader of the Kuridai and the Az'irel of Ab'Dendriel. \z + Humans would call it {sheriff}, executioner, or avenger." + } +) +keywordHandler:addKeyword({"sheriff"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Sometimes people get imprisoned for some time. \z + True criminals will be cast out and for committing the worst crimes offenders are thrown into the hellgate." + } +) +keywordHandler:addKeyword({"executioner"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Sometimes people get imprisoned for some time. \z + True criminals will be cast out and for committing the worst crimes offenders are thrown into the hellgate." + } +) +keywordHandler:addKeyword({"avenger"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Sometimes people get imprisoned for some time. \z + True criminals will be cast out and for committing the worst crimes offenders are thrown into the hellgate." + } +) +keywordHandler:addKeyword({"hellgate"}, StdModule.say, + { + npcHandler = npcHandler, + text = "It was here among other structures, like the depot tower, before our people came here. \z + It's secured by a sealed door." + } +) +keywordHandler:addKeyword({"sealed"}, StdModule.say, + { + npcHandler = npcHandler, + text = "For safety we keep the door to the hellgate locked all times. I have the {keys} to open it when needed." + } +) +keywordHandler:addKeyword({"door"}, StdModule.say, + { + npcHandler = npcHandler, + text = "For safety we keep the door to the hellgate locked all times. I have the {keys} to open it when needed." + } +) +keywordHandler:addKeyword({"name"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Not that I like to talk to you, but I am Elathriel Shadowslayer." + } +) +keywordHandler:addKeyword({"army"}, StdModule.say, + { + npcHandler = npcHandler, + text = "It's one of the more useful concepts we can learn from the other races." + } +) +keywordHandler:addKeyword({"king"}, StdModule.say, + { + npcHandler = npcHandler, + text = "It's hard for some of my people to grasp the true concept of a strong leader." + } +) +keywordHandler:addKeyword({"magic"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I mastered some battle spells." + } +) +keywordHandler:addKeyword({"time"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I couldn't care less." + } +) +keywordHandler:addKeyword({"eloise"}, StdModule.say, + { + npcHandler = npcHandler, + text = "A human weakling, not much more." + } +) +keywordHandler:addKeyword({"tibianus"}, StdModule.say, + { + npcHandler = npcHandler, + text = "A human weakling, not much more." + } +) +keywordHandler:addKeyword({"druid"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Druidic magic is too peaceful for my taste." + } +) +keywordHandler:addKeyword({"sorcerer"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I have seen human sorcerers doing some impressive things ... before they died." + } +) +keywordHandler:addKeyword({"dwarfs"}, StdModule.say, + { + npcHandler = npcHandler, + text = "We might use the shelter earth and hills provide us, but their obsession for metal is a waste of time." + } +) +keywordHandler:addKeyword({"trolls"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Like all inferior races, they can be at least of use for something good. \z + The other castes are just jealous of us making use of them." + } +) +keywordHandler:addKeyword({"excalibug"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I still doubt it exists." + } +) +keywordHandler:addKeyword({"ferumbras"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Even if he'd walk through the town above, the other castes would not see the necessity to follow OUR way." + } +) +keywordHandler:addKeyword({"elves"}, StdModule.say, + { + npcHandler = npcHandler, + text = "My people are divided in castes in these times, until they comprehend \z + that only the way of the Kuridai can save us all." + } +) +keywordHandler:addKeyword({"cenath"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Arrogant bastards, but they wield quite powerful magic." + } +) +keywordHandler:addKeyword({"teshial"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Dreamers are of no practical use. I don't mourn their demise." + } +) +keywordHandler:addKeyword({"deraisim"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Confused cowards. For all their skill, they still tend to hide and run. What a waste." + } +) +keywordHandler:addKeyword({"kuridai"}, StdModule.say, + { + npcHandler = npcHandler, + text = "We are the heart of the elven society. We forge, we build, and we don't allow our people to be pushed around." + } +) +keywordHandler:addKeyword({"carlin"}, StdModule.say, + { + npcHandler = npcHandler, + text = "We watch this city and the actions of its inhabitants closely." + } +) +keywordHandler:addKeyword({"venore"}, StdModule.say, + { + npcHandler = npcHandler, + text = "The merchants of venore provide us with some useful goods. \z + Still I an convinced that they get more out of our bargain then we do." + } +) +keywordHandler:addKeyword({"thais"}, StdModule.say, + { + npcHandler = npcHandler, + text = "The Thaian kingdom and we share some enemies, so it's only logical to cooperate in a few areas." + } +) +keywordHandler:addKeyword({"carlin"}, StdModule.say, + { + npcHandler = npcHandler, + text = "" + } +) +keywordHandler:addKeyword({"offer"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I offer hardly anything except for knowledge of {spells}." + } +) +keywordHandler:addKeyword({"buy"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I offer hardly anything except for knowledge of {spells}." + } +) +keywordHandler:addKeyword({"sell"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I offer hardly anything except for knowledge of {spells}." + } +) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, "key") then + npcHandler:say("If you are that curious, do you want to buy a key for 5000 gold? \z + Don't blame me if you get sucked in.", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + local player = Player(cid) + if player:removeMoneyNpc(5000) then + npcHandler:say("Here it is.", cid) + local key = player:addItem(2089, 1) + if key then + key:setActionId(3012) + end + else + npcHandler:say("Come back when you have enough money.", cid) + end + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Believe me, it's better for you that way.", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + + +-- Greeting message +keywordHandler:addGreetKeyword({"ashari"}, + { + npcHandler = npcHandler, + text = "Be greeted |PLAYERNAME|. What is your {business} near the {hellgate}?" + } +) +--Farewell message +keywordHandler:addFarewellKeyword({"asgha thrazi"}, + { + npcHandler = npcHandler, + text = "Asha Thrazi, |PLAYERNAME|." + } +) + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:setMessage(MESSAGE_GREET, "Be greeted |PLAYERNAME|. What is your {business} near the {hellgate}?") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Asha Thrazi, stranger!") +npcHandler:setMessage(MESSAGE_FAREWELL, "Asha Thrazi, stranger!") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/eleonore.lua b/data/npc/scripts/eleonore.lua new file mode 100644 index 00000000000..06a61c26c0f --- /dev/null +++ b/data/npc/scripts/eleonore.lua @@ -0,0 +1,112 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "ring") or msgcontains(msg, "mission") then + if player:getStorageValue(Storage.TheShatteredIsles.TheGovernorDaughter) < 1 then + npcHandler:say({ + "My ring was stolen by a parrot, directly from my dressing table near the window. It flew to the nearby mountains and I fear my ring will be lost forever. Whoever returns it to me will be rewarded generously. ...", + "I guess that evil parrot hid the ring somewhere on a high tree or a rock so that you might need a rake to get it." + }, cid) + player:setStorageValue(Storage.TheShatteredIsles.DefaultStart, 1) + player:setStorageValue(Storage.TheShatteredIsles.TheGovernorDaughter, 1) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheShatteredIsles.TheGovernorDaughter) == 2 then + npcHandler:say("Oh, my beloved ring! Have you found it and want to return it to me?", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.TheShatteredIsles.TheGovernorDaughter) == 3 and player:getStorageValue(Storage.TheShatteredIsles.TheErrand) < 1 then + npcHandler:say("I would need some help in another matter. It is only a small errand. Are you interested?", cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, "errand") then + if player:getStorageValue(Storage.TheShatteredIsles.TheErrand) == 2 then + npcHandler:say("Great, thank you! As promised, here are your 5 gold pieces. Is there ... anything left that you might want to discuss with me?", cid) + player:addMoney(5) + player:setStorageValue(Storage.TheShatteredIsles.TheErrand, 3) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "peg leg") then + if player:getStorageValue(Storage.TheShatteredIsles.TheErrand) == 3 then + npcHandler:say("You have returned my ring and proven yourself as trustworthy. There is something I have to discuss with you. Are you willing to listen?", cid) + npcHandler.topic[cid] = 4 + end + elseif msgcontains(msg, "raymond striker") then + if player:getStorageValue(Storage.TheShatteredIsles.AccessToLagunaIsland) == 1 then + npcHandler:say(" Oh, he is so wonderful. A very special man with a special place in my heart.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "mermaid") then + if player:getStorageValue(Storage.TheShatteredIsles.AccessToLagunaIsland) == 1 then + npcHandler:say("I can't thank you enough for freeing my beloved Ray from that evil spell. I am still shocked that a mermaid could steal his love that easily.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + if player:removeItem(6093, 1) then + player:addMoney(150) + npcHandler:say("Oh, thank you so much! Take this gold as a reward. ... which reminds me, I would need some help in another matter. It is only a small errand. Are you interested?", cid) + player:setStorageValue(Storage.TheShatteredIsles.TheGovernorDaughter, 3) + npcHandler.topic[cid] = 2 + else + player:addMoney(150) + npcHandler:say({ + "Ahh, now I understand... One of my suitors - a real chicken-heart - just brought back my ring. I was really surprised. Suddenly he shows brave attitude. But... It seems you lost it and he tries to take advantage. ...", + "Thanks a lot anyways and take this gold as a reward. By the way, I would need some help in another matter. It is only a small errand. Are you interested?" + }, cid) + player:setStorageValue(Storage.TheShatteredIsles.TheGovernorDaughter, 3) + npcHandler.topic[cid] = 2 + end + elseif npcHandler.topic[cid] == 2 then + npcHandler:say("Thank you! It is not a difficult matter but a rather urgent one. I need to send some money to a person in town. Would you be willing to run this small errand for me?", cid) + npcHandler.topic[cid] = 3 + elseif npcHandler.topic[cid] == 3 then + player:addMoney(200) + npcHandler:say("I was hoping that you'd agree. Please deliver these 200 gold pieces to the herbalist Charlotta in the south-western part of the town. If you return from this errand, I will grant you 5 gold pieces as reward for your efforts.", cid) + player:setStorageValue(Storage.TheShatteredIsles.TheErrand, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 4 then + npcHandler:say({ + "I am glad to hear that. So please listen: Due to circumstances too complicated to explain now, I met Captain Ray Striker. He is ... a freedom fighter and would not find my father's acceptance, but we fell in love ...", + "Even though he had to hide for a while, we have stayed in contact for a long time now. And our love grew even further against all odds ...", + "However, recently we lost contact. I don't know what has happened to him and fear the worst ...", + "We always have been aware that something terrible might happen to him due to his lifestyle. But perhaps there is a harmless explanation for the absence of messages . I have arranged a passage for you to Ray's hiding place ...", + "Contact Captain Waverider, the old fisherman, and tell him the secret word 'peg leg'. He will make sure that you arrive safely ...", + "Please look for Ray and find out what happened to him and why he was not able to answer. Return to me as soon as you have found something out. I wish you a good journey." + }, cid) + player:setStorageValue(Storage.TheShatteredIsles.TheErrand, 4) + player:setStorageValue(Storage.TheShatteredIsles.AccessToMeriana, 1) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] >= 1 then + npcHandler:say("Then no.", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Be greeted. What brings you {here}?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Oh well.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/elf_guard.lua b/data/npc/scripts/elf_guard.lua new file mode 100644 index 00000000000..3162833f931 --- /dev/null +++ b/data/npc/scripts/elf_guard.lua @@ -0,0 +1,36 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +keywordHandler:addKeyword({'elf'}, StdModule.say, {npcHandler = npcHandler, text = "The elves of this city are the casts of the Cenath, the Kuridai, and the Deraisim."}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am a guardian of this town. I have no time to chat!"}) +keywordHandler:addKeyword({'cenath'}, StdModule.say, {npcHandler = npcHandler, text = "The Cenath are magic users. Look for them on the upper levels of the town."}) +keywordHandler:addKeyword({'deraisim'}, StdModule.say, {npcHandler = npcHandler, text = "The Deraisim are scouts and hunters. You may find them on the groundlevel of the city."}) +keywordHandler:addKeyword({'teshial'}, StdModule.say, {npcHandler = npcHandler, text = "There are no Teshial."}) +keywordHandler:addKeyword({'weapon'}, StdModule.say, {npcHandler = npcHandler, text = "If you are looking for that kind of equipment you should ask a Kuridai."}) +keywordHandler:addKeyword({'magic'}, StdModule.say, {npcHandler = npcHandler, text = "Ask around in Ab'Dendriel. Many elves can teach you something about magic. The Cenath love magic most of all."}) +keywordHandler:addKeyword({'thais'}, StdModule.say, {npcHandler = npcHandler, text = "The city of the humans lies somewhere far to the south beyond the mountains of the dwarfs."}) + +-- Greeting message +keywordHandler:addGreetKeyword({"ashari"}, {npcHandler = npcHandler, text = "Ashari, |PLAYERNAME|."}) +--Farewell message +keywordHandler:addFarewellKeyword({"asgha thrazi"}, {npcHandler = npcHandler, text = "Asha Thrazi, |PLAYERNAME|."}) + +npcHandler:setMessage(MESSAGE_GREET, "Ashari |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Asha Thrazi, |PLAYERNAME|!') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Asha Thrazi, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/eliyas.lua b/data/npc/scripts/eliyas.lua new file mode 100644 index 00000000000..c98d28ffe5e --- /dev/null +++ b/data/npc/scripts/eliyas.lua @@ -0,0 +1,88 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, 'outfit') then + if player:getSex() == PLAYERSEX_MALE then + npcHandler:say('My jewelled belt? That\'s not very manly. Maybe you\'d prefer a scimitar like Habdel has.', cid) + return true + end + + if player:getStorageValue(Storage.OutfitQuest.firstOrientalAddon) < 1 then + npcHandler:say('My jewelled belt? Of course I could make one for you, but I have a small request. Would you fulfil a task for me?', cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, 'comb') then + if player:getSex() == PLAYERSEX_MALE then + npcHandler:say('Comb? This is a jewellery shop.', cid) + return true + end + + if player:getStorageValue(Storage.OutfitQuest.firstOrientalAddon) == 1 then + npcHandler:say('Have you brought me a mermaid\'s comb?', cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + 'Listen, um... I have been wanting a comb for a long time... not just any comb, but a mermaid\'s comb. Having a mermaid\'s comb means never having split ends again! ...', + 'You know what that means to a girl! Could you please bring me such a comb? I really would appreciate it.' + }, cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + player:setStorageValue(Storage.OutfitQuest.DefaultStart, 1) + player:setStorageValue(Storage.OutfitQuest.firstOrientalAddon, 1) + npcHandler:say('Yay! I will wait for you to return with a mermaid\'s comb then.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + if not player:removeItem(5945, 1) then + npcHandler:say('No... that\'s not it.', cid) + npcHandler.topic[cid] = 0 + return true + end + + player:setStorageValue(Storage.OutfitQuest.firstOrientalAddon, 2) + player:addOutfitAddon(150, 1) + player:addOutfitAddon(146, 1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + npcHandler:say('Yeah! That\'s it! I can\'t wait to comb my hair! Oh - but first, I\'ll fulfil my promise: Here is your jewelled belt! Thanks again!', cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] ~= 0 then + npcHandler:say('Oh... okay.', cid) + npcHandler.topic[cid] = 0 + end + + return true +end + +keywordHandler:addKeyword({'need'}, StdModule.say, {npcHandler = npcHandler, text = 'I am a jeweller. Maybe you want to have a look at my wonderful {offers}.'}) +keywordHandler:addKeyword({'offers'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, I sell gems and {goblets}. If you\'d like to see my offers, ask me for a {trade}.'}) +keywordHandler:addKeyword({'goblets'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, our newest import! We have golden goblets, silver goblets and bronze goblets. All of them have space for a hand-written dedication.'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Be greeted, |PLAYERNAME|. Which of my fine gems do you {need}?') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Daraman\'s blessings and good bye.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Daraman\'s blessings and good bye.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/eliza.lua b/data/npc/scripts/eliza.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/eliza.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/elliott.lua b/data/npc/scripts/elliott.lua new file mode 100644 index 00000000000..a4b9cc334d2 --- /dev/null +++ b/data/npc/scripts/elliott.lua @@ -0,0 +1,89 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + -- Mission 3 start + if msgcontains(msg, "abandoned sewers") then + if player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) < 21 then + npcHandler:say("You want to enter the abandoned sewers? That's rather dangerous and not a good idea, man. That part of the sewers was not sealed off for nothing, you know? ...", cid) + npcHandler:say("But hey, it's your life, bro. So here's the deal. I'll let you into the abandoned sewers if you help me with our {mission}.", cid) + npcHandler.topic[cid] = 0 + -- Mission 3 end + elseif player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) == 21 then + npcHandler:say("Wow, you already did it, that's fast. I'm used to a more laid-back attitude from most people. It's a shame to risk losing you to some collapsing tunnels, but a deal is a deal. ...", cid) + npcHandler:say("I hereby grant you the perMission to enter the abandoned part of the sewers. Take care, man! ...", cid) + npcHandler:say("If you find something interesting, come back to talk about the {abandoned sewers}.", cid) + player:setStorageValue(Storage.DarkTrails.Mission04, 1) + player:setStorageValue(Storage.Oramond.DoorAbandonedSewer, 1) + npcHandler.topic[cid] = 7 + elseif player:getStorageValue(Storage.DarkTrails.Mission05) == 1 then + npcHandler:say("I'm glad to see you back alive and healthy. Did you find anything interesting that you want to {report}?", cid) + npcHandler.topic[cid] = 7 + end + -- Mission 3 start + elseif msgcontains(msg, "mission") then + if npcHandler.topic[cid] == 0 then + npcHandler:say("The sewers need repair. You in?", cid) + npcHandler.topic[cid] = 2 + -- Mission 3 end + elseif player:getStorageValue(Storage.DarkTrails.Mission03) == 1 then + npcHandler:say("Elliott's keeps calling it that. It's just another job! You fixed some broken pipes and stuff? Let me check, {ok}?", cid) + npcHandler.topic[cid] = 3 + end + -- Mission 3 start - sewer access + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 2 then + npcHandler:say("Good. Broken pipe and generator pieces, there's smoke evading. That's how you recognise them. See how you can fix them using your hands. Need about, oh, twenty of them at least repaired. Report to me or Jacob", cid) + player:setStorageValue(Storage.Oramond.DoorAbandonedSewer, 1) + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer, 0) + npcHandler.topic[cid] = 0 + end + -- Task: The Ancient Sewers + elseif msgcontains(msg, "ok") then + if npcHandler.topic[cid] == 3 then + npcHandler:say("Good. Thanks, man. That's one vote you got for helping us with this.", cid) + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer, 21) --goto Mission 3 end + npcHandler.topic[cid] = 0 + end + -- Final Mission 5 + elseif msgcontains(msg, "report") then + if player:getStorageValue(Storage.DarkTrails.Mission05) == 1 then + if npcHandler.topic[cid] == 7 then + npcHandler:say("A sacrificial site? Damn, sounds like some freakish cult or something. Just great. And this ancient structure you talked about that's not part of the sewers? You'd better see the local historian about that, man. ...", cid) + npcHandler:say("He can make more sense of what you found there. His name is Barazbaz. He should be in the magistrate building.", cid) + player:setStorageValue(Storage.DarkTrails.Mission06, 1) -- start Mission 6 + npcHandler.topic[cid] = 0 + else + npcHandler:say("You already reported this Mission, go to the next.", cid) + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "") +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye!') -- Need revision + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/elvith.lua b/data/npc/scripts/elvith.lua new file mode 100644 index 00000000000..0238b5a873a --- /dev/null +++ b/data/npc/scripts/elvith.lua @@ -0,0 +1,74 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I sell musical instruments of many kinds.'}) +keywordHandler:addKeyword({'instruments'}, StdModule.say, {npcHandler = npcHandler, text = 'I sell lyres, lutes, drums, and simple fanfares.'}) +keywordHandler:addKeyword({'music'}, StdModule.say, {npcHandler = npcHandler, text = 'Music is an attempt to condensate emotions in harmonies and save them for the times to come.'}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = 'Time has its own song. Close your eyes and listen to the symphony of the seasons.'}) +keywordHandler:addKeyword({'song'}, StdModule.say, {npcHandler = npcHandler, text = 'Everything is a song. Life, death, history ... everything. To listen to the song of something is the first step to understand it.'}) +keywordHandler:addKeyword({'melody'}, StdModule.say, {npcHandler = npcHandler, text = 'Everything is a song. Life, death, history ... everything. To listen to the song of something is the first step to understand it.'}) +keywordHandler:addKeyword({'elf'}, StdModule.say, {npcHandler = npcHandler, text = 'We are the most graceful of all races. We feel the music of the universe in our hearts and souls.'}) +keywordHandler:addKeyword({'kuridai'}, StdModule.say, {npcHandler = npcHandler, text = 'They could dig some halls for a big musical event, but they won\'t listen to me about that matter.'}) +keywordHandler:addKeyword({'teshial'}, StdModule.say, {npcHandler = npcHandler, text = 'I bet they were great musicians.'}) +keywordHandler:addKeyword({'crunor'}, StdModule.say, {npcHandler = npcHandler, text = 'That is some god the humans worship. Our pople are not interested in this gods anymore.'}) +keywordHandler:addKeyword({'human'}, StdModule.say, {npcHandler = npcHandler, text = 'They are too loud and don\'t even understand the concept of a melody.'}) +keywordHandler:addKeyword({'deraisim'}, StdModule.say, {npcHandler = npcHandler, text = 'The other deraisim are too much concerned with mastering the nature so they don\'t listen to its music anymore.'}) +keywordHandler:addKeyword({'cenath'}, StdModule.say, {npcHandler = npcHandler, text = 'The Cenath think they know the \'art\' but the only true art is the music.'}) +keywordHandler:addKeyword({'troll'}, StdModule.say, {npcHandler = npcHandler, text = 'I went down to the mines and tried to lighten up their spirit, the foolish creatures did not listen to my songs, though.'}) +keywordHandler:addKeyword({'magic'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, I don\'t feel like teaching magic today.'}) +keywordHandler:addKeyword({'hellgate'}, StdModule.say, {npcHandler = npcHandler, text = 'For the worst of crimes, criminals are cast into hellgate. It is said no one can return from there. Since it is not actually forbidden to enter hellgate, you might convince Elathriel to grant you entrance.'}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, 'songs of the forest') then + npcHandler:say({ + 'The last issue I had was bought by Randor Swiftfinger. He was banished through the hellgate and probably took the book with him ...', + 'I would not recommend seeking him or the book there, but of course it is possible.' + }, cid) + elseif msgcontains(msg, 'love poem') then + npcHandler:say('Do you want to buy a poem scroll for 200 gold?', cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + npcHandler.topic[cid] = 0 + local player = Player(cid) + if not player:removeMoneyNpc(200) then + npcHandler:say('You don\'t have enough money.', cid) + return true + end + + player:addItem(8189, 1) + npcHandler:say('Here it is.', cid) + end + end + return true +end + +-- Greeting message +keywordHandler:addGreetKeyword({"ashari"}, {npcHandler = npcHandler, text = "Ashari, |PLAYERNAME|."}) +--Farewell message +keywordHandler:addFarewellKeyword({"asgha thrazi"}, {npcHandler = npcHandler, text = "Asha Thrazi, |PLAYERNAME|."}) + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:setMessage(MESSAGE_GREET, 'Ashari |PLAYERNAME|.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Asha Thrazi, |PLAYERNAME|!') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Asha Thrazi, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/elyen_ravenlock.lua b/data/npc/scripts/elyen_ravenlock.lua new file mode 100644 index 00000000000..1ecd615455d --- /dev/null +++ b/data/npc/scripts/elyen_ravenlock.lua @@ -0,0 +1,74 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = '' }, + { text = ' Re Ha, Omrah, Tan Ra...' }, + { text = 'The rats... the rats in the walls...' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if(msgcontains(msg, 'scroll') or msgcontains(msg, 'mission')) and player:getStorageValue(Storage.GravediggerOfDrefia.Mission60) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission61) < 1 then + npcHandler:say("Hello, brother. You come with a question to me, I believe?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, 'yes') and npcHandler.topic[cid] == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission60) == 1 then + npcHandler:say("And what is it you want? Do you bring news from the undead, or do you seek a dark {artefact}?", cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission45, 1) + npcHandler.topic[cid] = 2 + elseif(msgcontains(msg, 'artefact') or msgcontains(msg, 'yes')) and npcHandler.topic[cid] == 2 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission60) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission61) < 1 then + npcHandler:say({ + "The scroll piece there? The symbols look promising, but it is incomplete. ...", + "It is of little use to us. But it seems to be of interest to you ...", + "In exchange for the scroll piece, you must assist me with something. {Agreed}?" + }, cid) + npcHandler.topic[cid] = 3 + elseif(msgcontains(msg, 'agreed') or msgcontains(msg, 'yes')) and npcHandler.topic[cid] == 3 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission60) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission61) < 1 then + npcHandler:say({ + "I would have to sing to the Dark Shrines, but I cannot. ...", + "I... cannot bear Urgith's breed. Everywhere, I hear them - scrabbling, squeaking ...", + "Take this bone flute and play it in front of the five Dark Shrines so that they answer with song in return. You will find them in the Gardens of Night. ...", + "If you have done that, you may have the scroll piece. Now go." + }, cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission61, 1) + player:addItem(21249, 1) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'mission') and player:getStorageValue(Storage.GravediggerOfDrefia.Mission66) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission67) < 1 then + npcHandler:say("Hello, brother. You have finished the dance?", cid) + npcHandler.topic[cid] = 4 + elseif(msgcontains(msg, 'yes')) and npcHandler.topic[cid] == 4 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission66) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission67) < 1 then + npcHandler:say({ + "You have indeed. The shrines have sung back to you. Well done, brother. Not many men take such an interest in our art. ...", + "I will take the flute back. Our bargain stands. You may take the scroll." + }, cid) + player:removeItem(21249, 1) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission67, 1) + npcHandler.topic[cid] = 0 + else npcHandler:say({"Time is money, hurry."}, cid) + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "A shadow preceded you. You wish a {scroll} or a {mission}?") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/emily.lua b/data/npc/scripts/emily.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/emily.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/emma.lua b/data/npc/scripts/emma.lua new file mode 100644 index 00000000000..dabfe936a9b --- /dev/null +++ b/data/npc/scripts/emma.lua @@ -0,0 +1,209 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +local fire = Condition(CONDITION_FIRE) +fire:setParameter(CONDITION_PARAM_DELAYED, true) +fire:setParameter(CONDITION_PARAM_FORCEUPDATE, true) +fire:addDamage(25, 9000, -10) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + player:setStorageValue(Storage.SecretService.Quest, 1) + npcHandler:say('I am still a bit sceptical, but well, welcome to the girls brigade.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + if player:removeItem(8190, 1) then + player:setStorageValue(Storage.SecretService.CGBMission01, 2) + player:setStorageValue(Storage.SecretService.Quest, 3) + npcHandler:say('How unnecessarily complicated, but that\'s the way those Thaians are. In the end we got what we wanted and they can\'t do anything about it.', cid) + else + npcHandler:say('Bring me the spellbook.', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + if player:removeItem(7736, 1) then + player:setStorageValue(Storage.SecretService.CGBMission02, 2) + player:setStorageValue(Storage.SecretService.Quest, 5) + npcHandler:say('I think the druids will be pleased to hear that the immediate threat has been averted.', cid) + else + npcHandler:say('Bring me the heart as proof.', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 4 then + player:setStorageValue(Storage.SecretService.CGBMission03, 3) + player:setStorageValue(Storage.SecretService.Quest, 7) + npcHandler:say('Great! This blow strikes them where it hurts most: profit.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 5 then + if player:removeItem(7702, 1) then + player:setStorageValue(Storage.SecretService.CGBMission04, 2) + player:setStorageValue(Storage.SecretService.Quest, 9) + npcHandler:say('I hope our craftsmen can do something with this stuff. For me it makes hardly any sense.', cid) + else + npcHandler:say('You need to bring me those plans!', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 6 then + if player:removeItem(7703, 1) then + player:setStorageValue(Storage.SecretService.CGBMission05, 2) + player:setStorageValue(Storage.SecretService.Quest, 11) + npcHandler:say('I will have this correspondence examined by our specialists. I am sure they are quite revealing.', cid) + else + npcHandler:say('Bring me back some hints or something!', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 7 then + if player:removeItem(7704, 1) then + player:setStorageValue(Storage.SecretService.CGBMission06, 2) + player:setStorageValue(Storage.SecretService.Quest, 13) + npcHandler:say('I hope this old book will do those researches any good. Personally I see little use to proof some bloodlines after we cut all ties to Thais.', cid) + else + npcHandler:say('You need to bring us that book of family trees!', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 8 then + if player:removeItem(7699, 1) then + player:setStorageValue(Storage.SecretService.Mission07, 2) + player:setStorageValue(Storage.SecretService.Quest, 15) + player:addItem(7961, 1) + npcHandler:say({ + 'Excellent. The queen was not amused about this threat. It\'s a good thing that you have saved the city ...', + 'Unfortunately, as we are secret agents we can\'t parade for you or something like that, but let me express our gratitude for everything you have done for our city ...', + 'Take this token of gratitude. You will know when to use it!' + }, cid) + else + npcHandler:say('Please bring me proof of the mad technomancers defeat!', cid) + end + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish.', cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'join') then + if player:getStorageValue(Storage.SecretService.Quest) < 1 then + npcHandler:say({ + player:getSex() == PLAYERSEX_FEMALE and + 'The girls brigade is the foremost front on which we fight the numerous enemies of our city ...', + 'It\'s a constant race to stay ahead of our enemies. Absolute loyalty and the willingness to put ones life at stake are attributes that are vital for this brigade ...', + 'If you join, you dedicate your service to Carlin alone! Do you truly think that you are girl enough to join the brigade?' + or + 'A man in the girls brigade? Come on this is hilarious, this is outright stupid, this is ...', + 'exactly what no one would expect. Mhm, on second thought the element of surprise might offset your male inferiority.', + 'If you join, you dedicate your service to Carlin alone! Do you truly think that you are girl enough to join the brigade?' + }, cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, 'mission') then + if player:getStorageValue(Storage.SecretService.Quest) == 1 and player:getStorageValue(Storage.SecretService.TBIMission01) < 1 and player:getStorageValue(Storage.SecretService.CGBMission01) < 1 then + player:setStorageValue(Storage.SecretService.Quest, 2) + player:setStorageValue(Storage.SecretService.CGBMission01, 1) + npcHandler:say({ + 'Our relations with Thais can be called strained at best. Therefore, it\'s not really astounding that the Thaian financed Edron\'s academy but refuse to share some knowledge with our druids ..', + 'But we won\'t accept this so easily. With the help of divination, we learnt that the knowledge our druids are looking for is found in a certain book ...', + 'It will be your task to enter the academy and to steal this book for us.' + }, cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.SecretService.CGBMission01) == 1 then + npcHandler:say('Have you been successful?', cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(Storage.SecretService.CGBMission01) == 2 and player:getStorageValue(Storage.SecretService.Quest) == 3 then + player:setStorageValue(Storage.SecretService.Quest, 4) + player:setStorageValue(Storage.SecretService.CGBMission02, 1) + npcHandler:say({ + 'The druids have asked the brigade for a favour. Given that we heavily rely on their resources and they are important supporters of our cities, we can\'t deny them the request ...', + 'A wandering druid has recently visited the Green Claw Swamp, located north west of that corrupted hell hole Venore. While gathering herbs, he noticed some malignant presence in the said area ...', + 'Searching for the source of evil there, he detected some old ruin. Suddenly, he was attacked by bonelords and their undead minions. He barely managed to escape alive ...', + 'The evidence he found let him conclude that the bonelords in the ruins were raising so-called death trees.These trees are full of negative energy and slowly but steadily corrupt their surrounding ...', + 'After the druid\'s return to Carlin, divination confirmed his upsetting assumptions about the existence of these trees ...', + 'Over the years, hundreds have fallen victim to the swamp, conserved by mud and water for eternity. With the help of the death trees, the bonelords strive for an army of undeads. This cannot be tolerated ...', + 'Travel to Green Claw Swamp and rip out the heart out of the master tree. Without it, the unnatural trees will wither soon. Bring me the heart as proof.' + }, cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.SecretService.CGBMission02) == 1 then + npcHandler:say('Have you been successful?', cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.SecretService.CGBMission02) == 2 and player:getStorageValue(Storage.SecretService.Quest) == 5 then + player:setStorageValue(Storage.SecretService.Quest, 6) + player:setStorageValue(Storage.SecretService.CGBMission03, 1) + player:addItem(7698, 1) + npcHandler:say({ + 'The scheming Venoreans are a constant thorn in our side. They supply our enemies with all kind of equipment to boost the threat they pose to our freedom. It will be your task to hinder future weapon deliveries significantly ...', + 'The druids have supplied us with some exotic bugs. They are called rust bugs and they did not receive this name for their colour ...', + 'Take this box of rust bugs and use them on the keyhole of the smithy in the Ironhouse. These \'pets\' will ruin all metal there and it will take them a while to get rid of them.' + }, cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.SecretService.CGBMission03) == 2 then + npcHandler:say('Have you been successful?', cid) + npcHandler.topic[cid] = 4 + elseif player:getStorageValue(Storage.SecretService.CGBMission03) == 3 and player:getStorageValue(Storage.SecretService.Quest) == 7 then + player:setStorageValue(Storage.SecretService.Quest, 8) + player:setStorageValue(Storage.SecretService.CGBMission04, 1) + npcHandler:say({ + 'Venore has plans for a new kind of ship. It will be faster and more resilient than any other known ship. It will surely improve their dominance over the sea trade. Unless we get those plans for ourselves ...', + 'And this is where you come into play. Find the ship plans in the Venorean shipyard or perhaps at the harbour and bring them here immediately.' + }, cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.SecretService.CGBMission04) == 1 then + npcHandler:say('Have you been successful?', cid) + npcHandler.topic[cid] = 5 + elseif player:getStorageValue(Storage.SecretService.CGBMission04) == 2 and player:getStorageValue(Storage.SecretService.Quest) == 9 then + player:setStorageValue(Storage.SecretService.Quest, 10) + player:setStorageValue(Storage.SecretService.CGBMission05, 1) + npcHandler:say({ + 'Ruins of some ancient cathedral are found south west of Venore. It was a project that the Thaians never finished. However, our scouts reported some suspicious activities there ...', + 'There is a continual coming and going which hints on something big hiding there. We ask you to enter the ruins of the cathedral and to find out what all these people are doing there ...', + 'You might find several hints there, but I am sure you will know exactly when you have found what we are looking for.' + }, cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.SecretService.CGBMission05) == 1 then + npcHandler:say('Have you been successful?', cid) + npcHandler.topic[cid] = 6 + elseif player:getStorageValue(Storage.SecretService.CGBMission05) == 2 and player:getStorageValue(Storage.SecretService.Quest) == 11 then + player:setStorageValue(Storage.SecretService.Quest, 12) + player:setStorageValue(Storage.SecretService.CGBMission06, 1) + npcHandler:say({ + 'As you might know, once the old aristocracy of our city shared blood-ties with the noblemen of Thais. There are many unresolved claims for titles and family heirlooms and Thais does little to help in this matter ...', + 'Therefore, we will take matters into our own hands. There is a grave in the crypts on the Isle of the Kings in which we assume a book containing ancient family histories and family trees ...', + 'We need this book! We will not ask how you acquired it.' + }, cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.SecretService.CGBMission06) == 1 then + npcHandler:say('Have you been successful?', cid) + npcHandler.topic[cid] = 7 + elseif player:getStorageValue(Storage.SecretService.CGBMission06) == 2 and player:getStorageValue(Storage.SecretService.Quest) == 13 then + player:setStorageValue(Storage.SecretService.Quest, 14) + player:setStorageValue(Storage.SecretService.Mission07, 1) + npcHandler:say({ + 'I have bad news: a mad dwarf threatens to destroy our beloved city. He claims to have invented some device that enables him to destroy the whole city ...', + 'He has a laboratory somewhere in Kazordoon, probably somewhere near the technomancer hall. Find him and kill him! Bring me his beard as a proof!' + }, cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.SecretService.CGBMission06) == 2 and player:getStorageValue(Storage.SecretService.Mission07) == 1 then + npcHandler:say('Have you been successful?', cid) + npcHandler.topic[cid] = 8 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/emperor_kruzak.lua b/data/npc/scripts/emperor_kruzak.lua new file mode 100644 index 00000000000..463b8218626 --- /dev/null +++ b/data/npc/scripts/emperor_kruzak.lua @@ -0,0 +1,148 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if(msgcontains(msg, "outfit")) or (msgcontains(msg, "addon")) then + selfSay("In exchange for a truly generous donation, I will offer a special outfit. Do you want to make a donation?", cid) + npcHandler.topic[cid] = 1 + elseif(msgcontains(msg, "yes")) then + -- vamos tratar todas condições para YES aqui + if npcHandler.topic[cid] == 1 then + -- para o primeiro Yes, o npc deve explicar como obter o outfit + selfSay("Excellent! Now, let me explain. If you donate 1.000.000.000 gold pieces, you will be entitled to wear a unique outfit. ...", cid) + selfSay("You will be entitled to wear the {armor} for 500.000.000 gold pieces, {helmet} for an additional 250.000.000 and the {boots} for another 250.000.000 gold pieces. ...", cid) + selfSay("What will it be?", cid) + npcHandler.topic[cid] = 2 + -- O NPC só vai oferecer os addons se o player já tiver escolhido. + elseif npcHandler.topic[cid] == 2 then + -- caso o player repita o yes, resetamos o tópico para começar de novo? + selfSay("In that case, return to me once you made up your mind.", cid) + npcHandler.topic[cid] = 0 + -- Inicio do outfit + elseif npcHandler.topic[cid] == 3 then -- ARMOR/OUTFIT + if player:getStorageValue(Storage.OutfitQuest.GoldenOutfit) < 1 then + if player:getMoney() + player:getBankBalance() >= 500000000 then + local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX) + if inbox and inbox:getEmptySlots() > 0 then + local decoKit = inbox:addItem(26054, 1) + local decoItemName = ItemType(36345):getName() + decoKit:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, "You bought this item in the Store.\nUnwrap it in your own house to create a " .. decoItemName .. ".") + decoKit:setActionId(36345) + selfSay("Take this armor as a token of great gratitude. Let us forever remember this day, my friend!", cid) + player:removeMoneyNpc(500000000) + player:addOutfit(1211) + player:addOutfit(1210) + player:getPosition():sendMagicEffect(171) + player:setStorageValue(Storage.OutfitQuest.GoldenOutfit, 1) + else + selfSay("Please make sure you have free slots in your store inbox.", cid) + end + else + selfSay("You do not have enough money to donate that amount.", cid) + end + else + selfSay("You alread have that addon.", cid) + end + npcHandler.topic[cid] = 2 + -- Fim do outfit + -- Inicio do helmet + elseif npcHandler.topic[cid] == 4 then + if player:getStorageValue(Storage.OutfitQuest.GoldenOutfit) == 1 then + if player:getStorageValue(Storage.OutfitQuest.GoldenOutfit) < 2 then + if player:getMoney() + player:getBankBalance() >= 250000000 then + selfSay("Take this helmet as a token of great gratitude. Let us forever remember this day, my friend. ", cid) + player:removeMoneyNpc(250000000) + player:addOutfitAddon(1210, 1) + player:addOutfitAddon(1211, 1) + player:getPosition():sendMagicEffect(171) + player:setStorageValue(Storage.OutfitQuest.GoldenOutfit, 2) + npcHandler.topic[cid] = 2 + else + selfSay("You do not have enough money to donate that amount.", cid) + npcHandler.topic[cid] = 2 + end + else + selfSay("You alread have that outfit.", cid) + npcHandler.topic[cid] = 2 + end + else + selfSay("You need to donate {armor} outfit first.", cid) + npcHandler.topic[cid] = 2 + end + npcHandler.topic[cid] = 2 + -- Fim do helmet + -- Inicio da boots + elseif npcHandler.topic[cid] == 5 then + if player:getStorageValue(Storage.OutfitQuest.GoldenOutfit) == 2 then + if player:getStorageValue(Storage.OutfitQuest.GoldenOutfit) < 3 then + if player:getMoney() + player:getBankBalance() >= 250000000 then + selfSay("Take this boots as a token of great gratitude. Let us forever remember this day, my friend. ", cid) + player:removeMoneyNpc(250000000) + player:addOutfitAddon(1210, 2) + player:addOutfitAddon(1211, 2) + player:getPosition():sendMagicEffect(171) + player:setStorageValue(Storage.OutfitQuest.GoldenOutfit, 3) + npcHandler.topic[cid] = 2 + else + selfSay("You do not have enough money to donate that amount.", cid) + npcHandler.topic[cid] = 2 + end + else + selfSay("You alread have that outfit.", cid) + npcHandler.topic[cid] = 2 + end + else + selfSay("You need to donate {helmet} addon first.", cid) + npcHandler.topic[cid] = 2 + end + -- Fim da boots + npcHandler.topic[cid] = 2 + end + --inicio das opções armor/helmet/boots + -- caso o player não diga YES, dirá alguma das seguintes palavras: + elseif(msgcontains(msg, "armor")) and npcHandler.topic[cid] == 2 then + selfSay("So you wold like to donate 500.000.000 gold pieces which in return will entitle you to wear a unique armor?", cid) + npcHandler.topic[cid] = 3 -- alterando o tópico para que no próximo YES ele faça o outfit + elseif(msgcontains(msg, "helmet")) and npcHandler.topic[cid] == 2 then + selfSay("So you would like to donate 250.000.000 gold pieces which in return will entitle you to wear unique helmet?", cid) + npcHandler.topic[cid] = 4 -- alterando o tópico para que no próximo YES ele faça o helmet + elseif(msgcontains(msg, "boots")) and npcHandler.topic[cid] == 2 then + selfSay("So you would like to donate 250.000.000 gold pieces which in return will entitle you to wear a unique boots?", cid) + npcHandler.topic[cid] = 5 -- alterando o tópico para que no próximo YES ele faça a boots + end + -- fim das opções armor/helmet/boots +end + +-- Promotion +local node1 = keywordHandler:addKeyword({'promot'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'I can promote you for 20000 gold coins. Do you want me to promote you?'}) + node1:addChildKeyword({'yes'}, StdModule.promotePlayer, {npcHandler = npcHandler, cost = 20000, level = 20, text = 'Congratulations! You are now promoted.'}) + node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Alright then, come back when you are ready.', reset = true}) + +-- Greeting message +keywordHandler:addGreetKeyword({"hail emperor"}, {npcHandler = npcHandler, text = "Hiho, may fire and earth bless you, my child. Are you looking for a promotion?"}) +keywordHandler:addGreetKeyword({"salutations emperor"}, {npcHandler = npcHandler, text = "Hiho, may fire and earth bless you, my child. Are you looking for a promotion?"}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Farewell, |PLAYERNAME|, my child!') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/emperor_rehal.lua b/data/npc/scripts/emperor_rehal.lua new file mode 100644 index 00000000000..e3e7f535793 --- /dev/null +++ b/data/npc/scripts/emperor_rehal.lua @@ -0,0 +1,83 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +keywordHandler:addKeyword({'hi'}, StdModule.say, {npcHandler = npcHandler, onlyUnfocus = true}) +keywordHandler:addKeyword({'hello'}, StdModule.say, {npcHandler = npcHandler, onlyUnfocus = true}) + +function creatureSayCallback(cid, type, msg) + if(not(npcHandler:isFocused(cid))) then + return false + end + + local player = Player(cid) + if (msgcontains(msg, "nokmir")) then + if player:getStorageValue(Storage.HiddenCityOfBeregar.JusticeForAll) == 1 then + npcHandler:say("I always liked him and I still can't believe that he really stole that ring.", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.HiddenCityOfBeregar.JusticeForAll) == 4 and player:removeItem(14348, 1) then + npcHandler:say("Interesting. The fact that you have the ring means that Nokmir can't have stolen it. Combined with the information Grombur gave you, the case appears in a completely different light. ...", cid) + npcHandler:say("Let there be justice for all. Nokmir is innocent and acquitted from all charges! And Rerun... I want him in prison for this malicious act!", cid) + player:setStorageValue(Storage.HiddenCityOfBeregar.JusticeForAll, 5) + end + elseif (msgcontains(msg, "grombur")) then + if npcHandler.topic[cid] == 1 then + npcHandler:say("He's very ambitious and always volunteers for the long shifts.", cid) + player:setStorageValue(Storage.HiddenCityOfBeregar.JusticeForAll, 2) + npcHandler.topic[cid] = 0 + end + elseif (msgcontains(msg, "mission")) then + if player:getStorageValue(Storage.HiddenCityOfBeregar.RoyalRescue) < 1 and player:getStorageValue(Storage.HiddenCityOfBeregar.JusticeForAll) > 4 then + npcHandler:say("As you have proven yourself trustworthy I\'m going to assign you a special mission. Are you interested?", cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(Storage.HiddenCityOfBeregar.RoyalRescue) == 5 then + npcHandler:say("My son was captured by trolls? Doesn\'t sound like him, but if you say so. Now you want a reward, huh? ...", cid) + npcHandler.topic[cid] = 3 + end + elseif (msgcontains(msg, "yes")) then + if npcHandler.topic[cid] == 2 then + npcHandler:say("Splendid! My son Rehon set off on an expedition to the deeper mines. He and a group of dwarfs were to search for new veins of crystal. Unfortunately they have been missing for 2 weeks now. ...", cid) + npcHandler:say("Find my son and if he's alive bring him back. You will find a reactivated ore wagon tunnel at the entrance of the great citadel which leades to the deeper mines. If you encounter problems within the tunnel go ask Xorlosh, he can help you.", cid) + player:setStorageValue(Storage.HiddenCityOfBeregar.RoyalRescue, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + npcHandler:say("Look at these dwarven legs. They were forged years ago by a dwarf who was rather tall for our kind. I want you to have them. Thank you for rescuing my son |PLAYERNAME|.", cid) + player:addItem(2504, 1) + player:setStorageValue(Storage.HiddenCityOfBeregar.RoyalRescue, 6) + npcHandler.topic[cid] = 0 + end + elseif (msgcontains(msg, "no")) then + if npcHandler.topic[cid] == 1 or npcHandler.topic[cid] == 2 then + npcHandler:say("Alright then, come back when you are ready.", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +local node1 = keywordHandler:addKeyword({'promot'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'I can promote you for 20000 gold coins. Do you want me to promote you?'}) +node1:addChildKeyword({'yes'}, StdModule.promotePlayer, {npcHandler = npcHandler, cost = 20000, level = 20, promotion = 1, text = 'Congratulations! You are now promoted.'}) +node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Alright then, come back when you are ready.', reset = true}) + +-- Greeting message +keywordHandler:addGreetKeyword({"hail emperor"}, {npcHandler = npcHandler, text = "May fire and earth bless you, stranger. What leads you to Beregar, the dwarven city?"}) +keywordHandler:addGreetKeyword({"salutations emperor"}, {npcHandler = npcHandler, text = "May fire and earth bless you, stranger. What leads you to Beregar, the dwarven city?"}) + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/eranth.lua b/data/npc/scripts/eranth.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/eranth.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/erayo.lua b/data/npc/scripts/erayo.lua new file mode 100644 index 00000000000..2149a8a29a1 --- /dev/null +++ b/data/npc/scripts/erayo.lua @@ -0,0 +1,97 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local message = {} + +local config = { + ['blue cloth'] = {storageValue = 1, text = {'Brought the 50 pieces of blue cloth?', 'Good. Get me 50 pieces of green cloth now.'}, itemId = 5912, count = 50}, + ['green cloth'] = {storageValue = 2, text = {'Brought the 50 pieces of green cloth?', 'Good. Get me 50 pieces of red cloth now.'}, itemId = 5910, count = 50}, + ['red cloth'] = {storageValue = 3, text = {'Brought the 50 pieces of red cloth?', 'Good. Get me 50 pieces of brown cloth now.'}, itemId = 5911, count = 50}, + ['brown cloth'] = {storageValue = 4, text = {'Brought the 50 pieces of brown cloth?', 'Good. Get me 50 pieces of yellow cloth now.'}, itemId = 5913, count = 50}, + ['yellow cloth'] = {storageValue = 5, text = {'Brought the 50 pieces of yellow cloth?', 'Good. Get me 50 pieces of white cloth now.'}, itemId = 5914, count = 50}, + ['white cloth'] = {storageValue = 6, text = {'Brought the 50 pieces of white cloth?', 'Good. Get me 10 spools of yarn now.'}, itemId = 5909, count = 50}, + ['spools of yarn'] = {storageValue = 7, text = {'Brought the 10 spools of yarn?', 'Thanks. That\'s it, you\'re done. Good job, |PLAYERNAME|. I keep my promise. Here\'s my old assassin head piece.'}, itemId = 5886, count = 10}, + ['yarn'] = {storageValue = 7, text = {'Brought the 10 spools of yarn?', 'Thanks. That\'s it, you\'re done. Good job, |PLAYERNAME|. I keep my promise. Here\'s my old assassin head piece.'}, itemId = 5886, count = 10} +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, 'addon') then + if player:hasOutfit(player:getSex() == PLAYERSEX_FEMALE and 156 or 152) and player:getStorageValue(Storage.OutfitQuest.AssassinFirstAddon) < 1 then + npcHandler:say('Vescu gave you an assassin outfit? Haha. Noticed it lacks the head piece? You look a bit silly. Want my old head piece?', cid) + npcHandler.topic[cid] = 1 + end + elseif config[msg] and npcHandler.topic[cid] == 0 then + if player:getStorageValue(Storage.OutfitQuest.AssassinFirstAddon) == config[msg].storageValue then + npcHandler:say(config[msg].text[1], cid) + npcHandler.topic[cid] = 3 + message[cid] = msg + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + 'Thought so. Could use some help anyway. Listen, I need stuff. Someone gave me a strange assignment - sneak into Thais castle at night and shroud it with cloth without anyone noticing it. ...', + 'I wonder why anyone would want to shroud a castle, but as long as long as the guy pays, no problem, I\'ll do the sneaking part. Need a lot of cloth though. ...', + 'Gonna make it colourful. Bring me 50 pieces of {blue cloth}, 50 pieces of {green cloth}, 50 pieces of {red cloth}, 50 pieces of {brown cloth}, 50 pieces of {yellow cloth} and 50 pieces of {white cloth}. ...', + 'Besides, gonna need 10 {spools of yarn}. Understood?' + }, cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + if player:getStorageValue(Storage.OutfitQuest.DefaultStart) ~= 1 then + player:setStorageValue(Storage.OutfitQuest.DefaultStart, 1) + end + player:setStorageValue(Storage.OutfitQuest.AssassinFirstAddon, 1) + npcHandler:say('Good. Start with the blue cloth. I\'ll wait.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + local targetMessage = config[message[cid]] + if not player:removeItem(targetMessage.itemId, targetMessage.count) then + npcHandler:say('You don\'t have the required items.', cid) + npcHandler.topic[cid] = 0 + return true + end + + player:setStorageValue(Storage.OutfitQuest.AssassinFirstAddon, player:getStorageValue(Storage.OutfitQuest.AssassinFirstAddon) + 1) + if player:getStorageValue(Storage.OutfitQuest.AssassinFirstAddon) == 8 then + player:addOutfitAddon(156, 1) + player:addOutfitAddon(152, 1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + end + npcHandler:say(targetMessage.text[2], cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] > 0 then + npcHandler:say('Maybe another time.', cid) + npcHandler.topic[cid] = 0 + end + return true +end + +local function onReleaseFocus(cid) + message[cid] = nil +end + +npcHandler:setMessage(MESSAGE_GREET, 'What the... I mean, of course I sensed you.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/eremo.lua b/data/npc/scripts/eremo.lua new file mode 100644 index 00000000000..e3071f0e75b --- /dev/null +++ b/data/npc/scripts/eremo.lua @@ -0,0 +1,240 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'letter') then + if player:getStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven) == 4 then + if player:getItemCount(8188) > 0 then + if player:removeItem(8188, 1) then + npcHandler:say( + 'A letter from that youngster Morgan? I believed him dead since years. \ + These news are good news indeed. Thank you very much, my friend.', + cid) + player:setStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven, 5) + end + end + end + end + return true +end + +-- Wisdom of Solitude +local blessKeyword = keywordHandler:addKeyword({'solitude'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'Would you like to receive that protection for a sacrifice of |BLESSCOST| gold, child?' + } +) +blessKeyword:addChildKeyword({'yes'}, StdModule.bless, + { + npcHandler = npcHandler, + text = 'So receive the wisdom of solitude, pilgrim.', + cost = '|BLESSCOST|', + bless = 2 + } +) +blessKeyword:addChildKeyword({''}, StdModule.say, + { + npcHandler = npcHandler, + text = 'Fine. You are free to decline my offer.', + reset = true + } +) +keywordHandler:addAliasKeyword({'wisdom'}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, + { + npcHandler = npcHandler, + text = text + }, + function(player) + return player:getCondition(condition) ~= nil + end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end +) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', +CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'You are hurt, my child. I will heal your wounds.' + }, + function(player) + return player:getHealth() < 40 + end, + function(player) + local health = player:getHealth() + if health < 40 then + player:addHealth(40 - health) + end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) +end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional \ + protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.' + } +) + +-- Teleport back +local teleportKeyword = keywordHandler:addKeyword({'cormaya'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'Should I teleport you back to Pemaret?' + } +) +teleportKeyword:addChildKeyword({'yes'}, StdModule.travel, + { + npcHandler = npcHandler, + text = 'Here you go!', + premium = false, + destination = Position(33288, 31956, 6) + } +) +teleportKeyword:addChildKeyword({''}, StdModule.say, + { + npcHandler = npcHandler, + text = 'Maybe later.', ungreet = true + } +) + +keywordHandler:addAliasKeyword({'back'}) +keywordHandler:addAliasKeyword({'passage'}) +keywordHandler:addAliasKeyword({'pemaret'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a \ + chance that you lose some of your equipment. With every single of the five {blessings} you have, \ + this damage and chance of loss will be reduced.' + } +) +keywordHandler:addKeyword({'blessings'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'There are five blessings available in five sacred places: the {spiritual} shielding, \ + the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. \ + Additionally, you can receive the {twist of fate} here.' + } +) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.' + }, + function(player) + return player:hasBlessing(1) + end +) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.' + }, + function(player) + return player:hasBlessing(2) + end +) +keywordHandler:addKeyword({'suns'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.' + }, + function(player) + return player:hasBlessing(3) + end +) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'I can sense that the spark of the phoenix already was given to you by \ + the dwarven priests of earth and fire in Kazordoon.' + }, + function(player) + return player:hasBlessing(4) + end +) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.' + } +) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'The druids north of Carlin will provide you with the embrace of Tibia.' + } +) +keywordHandler:addKeyword({'suns'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.' + } +) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.' + } +) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'job'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'I teach some spells, provide one of the five blessings, and sell some amulets. \ + Ask me for a trade if you like.' + } +) +keywordHandler:addKeyword({'name'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'I am Eremo, an old man who has seen many things.' + } +) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome to my little garden, adventurer |PLAYERNAME|!') +npcHandler:setMessage(MESSAGE_FAREWELL, 'It was a pleasure to help you, |PLAYERNAME|.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'It was a pleasure to help you, |PLAYERNAME|.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/eroth.lua b/data/npc/scripts/eroth.lua new file mode 100644 index 00000000000..65987e52140 --- /dev/null +++ b/data/npc/scripts/eroth.lua @@ -0,0 +1,37 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am the leader of the Cenath caste."}) +keywordHandler:addKeyword({'kuridai'}, StdModule.say, {npcHandler = npcHandler, text = "The Kuridai are aggressive and victims of their instincts. Without our help they would surely die in a foolish war."}) +keywordHandler:addKeyword({'crunor'}, StdModule.say, {npcHandler = npcHandler, text = "Gods are for the weak. We will master the world on our own. We need no gods."}) +keywordHandler:addKeyword({'deraisim'}, StdModule.say, {npcHandler = npcHandler, text = "They lack the understanding of unity. We are keeping them together and prevent them from being slaughtered one by one."}) +keywordHandler:addKeyword({'cenath'}, StdModule.say, {npcHandler = npcHandler, text = "We are the shepherds of our people. The other castes need our guidance."}) +keywordHandler:addKeyword({'magic'}, StdModule.say, {npcHandler = npcHandler, text = "Magic comes almost naturally to the Cenath. We keep the secrets of ages."}) +keywordHandler:addKeyword({'spell'}, StdModule.say, {npcHandler = npcHandler, text = "I can teach the spells 'magic shield', 'destroy field', 'creature illusion', 'chameleon', 'convince creature', and 'summon creature'."}) + +-- Greeting message +keywordHandler:addGreetKeyword({"ashari"}, {npcHandler = npcHandler, text = "I greet thee, outsider."}) +--Farewell message +keywordHandler:addFarewellKeyword({"asgha thrazi"}, {npcHandler = npcHandler, text = "Asha Thrazi. Go, where you have to go."}) + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:setMessage(MESSAGE_GREET, "I greet thee, outsider.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Asha Thrazi. Go, where you have to go.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Asha Thrazi.") + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/eruaran.lua b/data/npc/scripts/eruaran.lua new file mode 100644 index 00000000000..3b79a4623a3 --- /dev/null +++ b/data/npc/scripts/eruaran.lua @@ -0,0 +1,403 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local storage = Storage.DreamOutfit + +local action = {} +local weapon = {} +local weapon_sub = {} + +local Config = { + Create = { + Clusters = 20, + DreamMatter = 1, + Chance = 70 --70% + }, + Improve = { + Clusters = 75, + Chance = 55, --55% + BreakChance = 50 --50% of chance that when failing the improvement, the weapons is destroyed but you keep the clusters. Else, you keep the weapon and lose the clusters + }, + Transform = { + Clusters = 150, + Chance = 45, --45% + BreakChance = 50 --50% of chance that when failing the transforming, the weapon is destroyed but you keep all the clusters. Else, the weapon is downgraded to crude piece and you lose half of clusters. + } +} + +local IDS = { + DREAM_MATTER = 22397, + CLUSTER_OF_SOLACE = 22396, + + --weapons + CRUDE_UMBRAL_BLADE = 22398, + UMBRAL_BLADE = 22399, + UMBRAL_MASTER_BLADE = 22400, + + CRUDE_UMBRAL_SLAYER = 22401, + UMBRAL_SLAYER = 22402, + UMBRAL_MASTER_SLAYER = 22403, + + CRUDE_UMBRAL_AXE = 22404, + UMBRAL_AXE = 22405, + UMBRAL_MASTER_AXE = 22406, + + CRUDE_UMBRAL_CHOPPER = 22407, + UMBRAL_CHOPPER = 22408, + UMBRAL_MASTER_CHOPPER = 22409, + + CRUDE_UMBRAL_MACE = 22410, + UMBRAL_MACE = 22411, + UMBRAL_MASTER_MACE = 22412, + + CRUDE_UMBRAL_HAMMER = 22413, + UMBRAL_HAMMER = 22414, + UMBRAL_MASTER_HAMMER = 22415, + + CRUDE_UMBRAL_BOW = 22416, + UMBRAL_BOW = 22417, + UMBRAL_MASTER_BOW = 22418, + + CRUDE_UMBRAL_CROSSBOW = 22419, + UMBRAL_CROSSBOW = 22420, + UMBRAL_MASTER_CROSSBOW = 22421, + + CRUDE_UMBRAL_SPELLBOOK = 22422, + UMBRAL_SPELLBOOK = 22423, + UMBRAL_MASTER_SPELLBOOK = 22424 +} + +local TYPES = { + SWORD = 1, + AXE = 2, + CLUB = 3, + BOW = 4, + CROSSBOW = 5, + SPELLBOOK = 6 +} + +local SUB_TYPES = { + BLADE = 1, + SLAYER = 2, + AXE = 3, + CHOPPER = 4, + MACE = 5, + HAMMER = 6, + BOW = 7, + CROSSBOW = 8, + SPELLBOOK = 9 +} + +local ACTION = { + CREATE = 1, + IMPROVE = 2, + TRANSFORM = 3 +} + +-- dream START -- +function dreamFirst(cid, message, keywords, parameters, node) + + if(not npcHandler:isFocused(cid)) then + return false + end + + if isPremium(cid) then + addon = getPlayerStorageValue(cid, storage) + if addon == -1 then + if getPlayerItemCount(cid,22610) >= 1 then + if doPlayerRemoveItem(cid,22610,1) then + selfSay(newaddon, cid) + + doSendMagicEffect(getCreaturePosition(cid), 13) + doPlayerAddOutfit(cid, 577, 1) + doPlayerAddOutfit(cid, 578, 1) + setPlayerStorageValue(cid, storage,1) + end + else + selfSay(noitems, cid) + end + else + selfSay(already, cid) + end + end + +end + +function dreamSecond(cid, message, keywords, parameters, node) + + if(not npcHandler:isFocused(cid)) then + return false + end + + if isPremium(cid) then + addon = getPlayerStorageValue(cid, storage+1) + if addon == -1 then + if getPlayerItemCount(cid,22609) >= 1 then + if doPlayerRemoveItem(cid,22609,1) then + selfSay(newaddon, cid) + + doSendMagicEffect(getCreaturePosition(cid), 13) + doPlayerAddOutfit(cid, 577, 2) + doPlayerAddOutfit(cid, 578, 2) + setPlayerStorageValue(cid, storage+1,1) + end + else + selfSay(noitems, cid) + end + else + selfSay(already, cid) + end + end + +end +-- dream END -- + +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.EruaranGreeting) > 0 then + npcHandler:setMessage(MESSAGE_GREET, "Ashari Lillithy, so we meet {again}! What brings you here this time, general {information}, {transform}, {improve}, {create}, {outfit}, or {talk}?") + else + npcHandler:setMessage(MESSAGE_GREET, 'Welcome |PLAYERNAME|.') + player:setStorageValue(Storage.EruaranGreeting, 1) + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "create") then + npcHandler:say("You can try to create {sword}s, {axe}s, {club}s, {bow}s, {crossbow}s and {spellbook}s.", cid) + npcHandler.topic[cid] = 1 + action[cid] = ACTION.CREATE + elseif msgcontains(msg, "improve") then + npcHandler:say("The raw object is nothing but a pale of shadow of its potential. As unsafe and unpredictable the imporvement is, it might boot the powers of your item immensely. You can try to improve {sword}s, {axe}s, {club}s, {bow}s, {crossbow}s and {spellbook}s.", cid) + npcHandler.topic[cid] = 1 + action[cid] = ACTION.IMPROVE + elseif msgcontains(msg, "transform") then + npcHandler:say("From time to time fate smiles upon those who take great risks and have strong dreams! If you have the {ingredients}, we can try to give the ultimate refinement to {sword}s, {axe}s, {club}s, {bow}s, {crossbow}s and {spellbook}s.", cid) + npcHandler.topic[cid] = 1 + action[cid] = ACTION.TRANSFORM + elseif msgcontains(msg, "sword") and npcHandler.topic[cid] == 1 then + weapon[cid] = TYPES.SWORD + if action[cid] == ACTION.CREATE then + npcHandler:say("Do you want to create a crude umbral {blade} or crude umbral {slayer}?", cid) + npcHandler.topic[cid] = 2 + elseif action[cid] == ACTION.IMPROVE then + npcHandler:say("Do you want to improve a crude umbral {blade} or crude umbral {slayer}?", cid) + npcHandler.topic[cid] = 2 + elseif action[cid] == ACTION.TRANSFORM then + npcHandler:say("Do you want to transform an umbral {blade} or umbral {slayer}?", cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, "blade") or msgcontains(msg, "slayer") and npcHandler.topic[cid] == 2 then + weapon_sub[cid] = (msgcontains(msg, "blade") and SUB_TYPES.BLADE or SUB_TYPES.SLAYER) + if action[cid] == ACTION.CREATE then + npcHandler:say("Do you want to spend " .. (Config.Create.DreamMatter == 1 and "your" or Config.Create.DreamMatter) .. " dream matter with " .. (Config.Create.Clusters > 1 and "those" or "your") .. " " .. Config.Create.Clusters .. " clusters of {solace} and give a shot. {Yes} or {no}", cid) + npcHandler.topic[cid] = 3 + elseif action[cid] == ACTION.IMPROVE then + npcHandler:say("Do you want to spend your crude umbral " .. (weapon_sub[cid] == SUB_TYPES.BLADE and "blade" or "slayer") .. " with " .. (Config.Improve.Clusters > 1 and "those" or "your") .. " " .. Config.Improve.Clusters .. " clusters of {solace} and give a shot. {Yes} or {no}?", cid) + npcHandler.topic[cid] = 3 + elseif action[cid] == ACTION.TRANSFORM then + npcHandler:say("Do you want to spend your umbral " .. (weapon_sub[cid] == SUB_TYPES.BLADE and "blade" or "slayer") .. " with " .. (Config.Transform.Clusters > 1 and "those" or "your") .. " " .. Config.Transform.Clusters .. " clusters of {solace} and give it a shot. {Yes} or {no}?", cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, "axe") and npcHandler.topic[cid] == 1 then + weapon[cid] = TYPES.AXE + if action[cid] == ACTION.CREATE then + npcHandler:say("Do you want to create a crude umbral {axe} or crude umbral {chopper}?", cid) + npcHandler.topic[cid] = 2 + elseif action[cid] == ACTION.IMPROVE then + npcHandler:say("Do you want to improve a crude umbral {axe} or crude umbral {chopper}?", cid) + npcHandler.topic[cid] = 2 + elseif action[cid] == ACTION.TRANSFORM then + npcHandler:say("Do you want to transform an umbral {axe} or umbral {chopper}?", cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, "axe") or msgcontains(msg, "chopper") and npcHandler.topic[cid] == 2 then + weapon_sub[cid] = (msgcontains(msg, "axe") and SUB_TYPES.AXE or SUB_TYPES.CHOPPER) + if action[cid] == ACTION.CREATE then + npcHandler:say("Do you want to spend your dream matter with those 25 clusters of {solace} and give a shot. {Yes} or {no}", cid) + npcHandler.topic[cid] = 3 + elseif action[cid] == ACTION.IMPROVE then + npcHandler:say("Do you want to spend your crude umbral " .. (weapon_sub[cid] == SUB_TYPES.AXE and "axe" or "chopper") .. " with " .. (Config.Improve.Clusters > 1 and "those" or "your") .. " " .. Config.Improve.Clusters .. " clusters of {solace} and give a shot. {Yes} or {no}?", cid) + npcHandler.topic[cid] = 3 + elseif action[cid] == ACTION.TRANSFORM then + npcHandler:say("Do you want to spend your umbral " .. (weapon_sub[cid] == SUB_TYPES.AXE and "axe" or "chopper") .. " with " .. (Config.Transform.Clusters > 1 and "those" or "your") .. " " .. Config.Transform.Clusters .. " clusters of {solace} and give it a shot. {Yes} or {no}?", cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, "club") and npcHandler.topic[cid] == 1 then + weapon[cid] = TYPES.CLUB + if action[cid] == ACTION.CREATE then + npcHandler:say("Do you want to create a crude umbral {mace} or crude umbral {hammer}?", cid) + npcHandler.topic[cid] = 2 + elseif action[cid] == ACTION.IMPROVE then + npcHandler:say("Do you want to improve a crude umbral {mace} or crude umbral {hammer}?", cid) + npcHandler.topic[cid] = 2 + elseif action[cid] == ACTION.TRANSFORM then + npcHandler:say("Do you want to transform an umbral {mace} or umbral {hammer}?", cid) + npcHandler.topic[cid] = 2 + end + elseif isInArray({"mace", "hammer"}, msg) and npcHandler.topic[cid] == 2 then + weapon_sub[cid] = (msgcontains(msg, "mace") and SUB_TYPES.MACE or SUB_TYPES.HAMMER) + if action[cid] == ACTION.CREATE then + npcHandler:say("Do you want to spend your dream matter with " .. (Config.Create.Clusters > 1 and "those" or "your") .. " " .. Config.Create.Clusters .. " clusters of {solace} and give a shot. {Yes} or {no}", cid) + npcHandler.topic[cid] = 3 + elseif action[cid] == ACTION.IMPROVE then + npcHandler:say("Do you want to spend your crude umbral " .. (weapon_sub[cid] == SUB_TYPES.MACE and "mace" or "hammer") .. " with " .. (Config.Improve.Clusters > 1 and "those" or "your") .. " " .. Config.Improve.Clusters .. " clusters of {solace} and give a shot. {Yes} or {no}?", cid) + npcHandler.topic[cid] = 3 + elseif action[cid] == ACTION.TRANSFORM then + npcHandler:say("Do you want to spend your umbral " .. (weapon_sub[cid] == SUB_TYPES.MACE and "mace" or "hammer") .. " with " .. (Config.Transform.Clusters > 1 and "those" or "your") .. " " .. Config.Transform.Clusters .. " clusters of {solace} and give it a shot. {Yes} or {no}?", cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, "bow") and npcHandler.topic[cid] == 1 then + weapon[cid] = TYPES.BOW + if action[cid] == ACTION.CREATE then + npcHandler:say("Do you want to spend your dream matter with " .. (Config.Create.Clusters > 1 and "those" or "your") .. " " .. Config.Create.Clusters .. " clusters of {solace} and give a shot. {Yes} or {no}", cid) + npcHandler.topic[cid] = 3 + elseif action[cid] == ACTION.IMPROVE then + npcHandler:say("Do you want to spend your crude umbral bow with " .. (Config.Improve.Clusters > 1 and "those" or "your") .. " " .. Config.Improve.Clusters .. " clusters of {solace} and give a shot. {Yes} or {no}?", cid) + npcHandler.topic[cid] = 3 + elseif action[cid] == ACTION.TRANSFORM then + npcHandler:say("Do you want to spend your umbral bow with " .. (Config.Transform.Clusters > 1 and "those" or "your") .. " " .. Config.Transform.Clusters .. " clusters of {solace} and give it a shot. {Yes} or {no}?", cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, "crossbow") and npcHandler.topic[cid] == 1 then + weapon[cid] = TYPES.CROSSBOW + if action[cid] == ACTION.CREATE then + npcHandler:say("Do you want to spend your dream matter with " .. (Config.Create.Clusters > 1 and "those" or "your") .. " " .. Config.Create.Clusters .. " clusters of {solace} and give a shot. {Yes} or {no}", cid) + npcHandler.topic[cid] = 3 + elseif action[cid] == ACTION.IMPROVE then + npcHandler:say("Do you want to spend your crude umbral crossbow with " .. (Config.Improve.Clusters > 1 and "those" or "your") .. " " .. Config.Improve.Clusters .. " clusters of {solace} and give a shot. {Yes} or {no}?", cid) + npcHandler.topic[cid] = 3 + elseif action[cid] == ACTION.TRANSFORM then + npcHandler:say("Do you want to spend your umbral crossbow with " .. (Config.Transform.Clusters > 1 and "those" or "your") .. " " .. Config.Transform.Clusters .. " clusters of {solace} and give it a shot. {Yes} or {no}?", cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, "spellbook") and npcHandler.topic[cid] == 1 then + weapon[cid] = TYPES.SPELLBOOK + if action[cid] == ACTION.CREATE then + npcHandler:say("Do you want to spend your dream matter with " .. (Config.Create.Clusters > 1 and "those" or "your") .. " " .. Config.Create.Clusters .. " clusters of {solace} and give a shot. {Yes} or {no}", cid) + npcHandler.topic[cid] = 3 + elseif action[cid] == ACTION.IMPROVE then + npcHandler:say("Do you want to spend your crude umbral spellbook with " .. (Config.Improve.Clusters > 1 and "those" or "your") .. " " .. Config.Improve.Clusters .. " clusters of {solace} and give a shot. {Yes} or {no}?", cid) + npcHandler.topic[cid] = 3 + elseif action[cid] == ACTION.TRANSFORM then + npcHandler:say("Do you want to spend your umbral spellbook with " .. (Config.Transform.Clusters > 1 and "those" or "your") .. " " .. Config.Transform.Clusters .. " clusters of {solace} and give it a shot. {Yes} or {no}?", cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 3 then + + if action[cid] == ACTION.CREATE then --create + if player:getItemCount(IDS.DREAM_MATTER) >= 1 and player:getItemCount(IDS.CLUSTER_OF_SOLACE) >= Config.Create.Clusters then + if math.random(100) <= Config.Create.Chance then + local newItemId = (weapon[cid] == TYPES.SWORD and (weapon_sub[cid] == SUB_TYPES.BLADE and IDS.CRUDE_UMBRAL_BLADE or IDS.CRUDE_UMBRAL_SLAYER) or weapon[cid] == TYPES.AXE and (weapon_sub[cid] == SUB_TYPES.AXE and IDS.CRUDE_UMBRAL_AXE or IDS.CRUDE_UMBRAL_CHOPPER) or weapon[cid] == TYPES.CLUB and (weapon_sub[cid] == SUB_TYPES.MACE and IDS.CRUDE_UMBRAL_MACE or IDS.CRUDE_UMBRAL_HAMMER) or weapon[cid] == TYPES.BOW and IDS.CRUDE_UMBRAL_BOW or weapon[cid] == TYPES.CROSSBOW and IDS.CRUDE_UMBRAL_CROSSBOW or weapon[cid] == TYPES.SPELLBOOK and IDS.CRUDE_UMBRAL_SPELLBOOK or false) + if newItemId then + player:addItem(newItemId) + player:removeItem(IDS.DREAM_MATTER, Config.Create.DreamMatter) + player:removeItem(IDS.CLUSTER_OF_SOLACE, Config.Create.Clusters) + npcHandler:say("Your dreams are strong, the creation was successful. Take your " .. ItemType(newItemId):getName() .. ".", cid) + else + npcHandler:say("Something weird happened! You should contact a gamemaster.", cid) + end + else + npcHandler:say("Oh no! The process failed.", cid) + player:removeItem(IDS.DREAM_MATTER, 1) + end + else + npcHandler:say("Sorry, you don't have the required ingredients.", cid) + end + elseif action[cid] == ACTION.IMPROVE then --improve + local oldItemId = (weapon[cid] == TYPES.SWORD and (weapon_sub[cid] == SUB_TYPES.BLADE and IDS.CRUDE_UMBRAL_BLADE or IDS.CRUDE_UMBRAL_SLAYER) or weapon[cid] == TYPES.AXE and (weapon_sub[cid] == SUB_TYPES.AXE and IDS.CRUDE_UMBRAL_AXE or IDS.CRUDE_UMBRAL_CHOPPER) or weapon[cid] == TYPES.CLUB and (weapon_sub[cid] == SUB_TYPES.MACE and IDS.CRUDE_UMBRAL_MACE or IDS.CRUDE_UMBRAL_HAMMER) or weapon[cid] == TYPES.BOW and IDS.CRUDE_UMBRAL_BOW or weapon[cid] == TYPES.CROSSBOW and IDS.CRUDE_UMBRAL_CROSSBOW or weapon[cid] == TYPES.SPELLBOOK and IDS.CRUDE_UMBRAL_SPELLBOOK or false) + local newItemId = (oldItemId and oldItemId + 1 or false) + if player:getItemCount(IDS.CLUSTER_OF_SOLACE) >= Config.Improve.Clusters then + if newItemId and oldItemId then + if player:getItemCount(oldItemId) > 0 then + if math.random(100) <= Config.Improve.Chance then + player:removeItem(oldItemId, 1) + player:addItem(newItemId) + player:removeItem(IDS.CLUSTER_OF_SOLACE, Config.Improve.Clusters) + npcHandler:say("Your dreams are strong, the improvement was successful. Take your " .. ItemType(newItemId):getName() .. ".", cid) + else + npcHandler:say("Oh no! The process failed.", cid) + local rand = math.random(100) + player:removeItem((rand <= Config.Improve.BreakChance and oldItemId or IDS.CLUSTER_OF_SOLACE), (rand <= Config.Improve.BreakChance and 1 or Config.Improve.Clusters)) + end + else + npcHandler:say("You do not have " .. ItemType(oldItemId):getArticle() .. " " .. ItemType(oldItemId):getName() .. " with you.", cid) + end + else + npcHandler:say("Something weird happened! You should contact a gamemaster.", cid) + end + end + elseif action[cid] == ACTION.TRANSFORM then --transform + local oldItemId = (weapon[cid] == TYPES.SWORD and (weapon_sub[cid] == SUB_TYPES.BLADE and IDS.UMBRAL_BLADE or IDS.UMBRAL_SLAYER) or weapon[cid] == TYPES.AXE and (weapon_sub[cid] == SUB_TYPES.AXE and IDS.UMBRAL_AXE or IDS.UMBRAL_CHOPPER) or weapon[cid] == TYPES.CLUB and (weapon_sub[cid] == SUB_TYPES.MACE and IDS.UMBRAL_MACE or IDS.UMBRAL_HAMMER) or weapon[cid] == TYPES.BOW and IDS.UMBRAL_BOW or weapon[cid] == TYPES.CROSSBOW and IDS.UMBRAL_CROSSBOW or weapon[cid] == TYPES.SPELLBOOK and IDS.UMBRAL_SPELLBOOK or false) + local newItemId = (oldItemId and oldItemId + 1 or false) + if player:getItemCount(IDS.CLUSTER_OF_SOLACE) >= Config.Transform.Clusters then + if newItemId and oldItemId then + if player:getItemCount(oldItemId) > 0 then + if math.random(100) <= Config.Transform.Chance then + player:removeItem(oldItemId, 1) + player:addItem(newItemId) + player:removeItem(IDS.CLUSTER_OF_SOLACE, Config.Transform.Clusters) + npcHandler:say("Your dreams are strong, the transforming was successful. Take your " .. ItemType(newItemId):getName() .. ".", cid) + else + npcHandler:say("Oh no! The process failed.", cid) + local rand = math.random(100) + if Config.Transform.BreakChance <= rand then + player:removeItem(oldItemId, 1) + else + player:removeItem(oldItemId, 1) + player:addItem(oldItemId - 1, 1) + player:removeItem(IDS.CLUSTER_OF_SOLACE, Config.Transform.Clusters / 2) + end + end + else + npcHandler:say("You do not have " .. ItemType(oldItemId):getArticle() .. " " .. ItemType(oldItemId):getName() .. " with you.", cid) + end + else + npcHandler:say("Something weird happened! You should contact a gamemaster.", cid) + end + end + end + npcHandler:releaseFocus(cid) + npcHandler:resetNpc() + end +end + +keywordHandler:addKeyword({'outfit'}, StdModule.say, {npcHandler = npcHandler, text = 'What addon you are looking? I need for first addon: {dream warden claw} and for second {dream warden mask}.'}) + node1 = keywordHandler:addKeyword({'dream warden mask'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'To achieve the first dream addon you need to give me 1 dream warden claw. Do you have them with you?'}) + node1:addChildKeyword({'yes'}, dreamFirst, {}) + node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Alright then. Come back when you got all neccessary items.', reset = true}) + + node2 = keywordHandler:addKeyword({'dream warden claw'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'To achieve the second dream addon you need to give me 1 dream warden mask. Do you have them with you?'}) + node2:addChildKeyword({'yes'}, dreamSecond, {}) + node2:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Alright then. Come back when you got all neccessary items.', reset = true}) + +-- Greeting message +keywordHandler:addGreetKeyword({"ashari"}, {npcHandler = npcHandler, text = "Greetings, |PLAYERNAME|."}) +--Farewell message +keywordHandler:addFarewellKeyword({"asgha thrazi"}, {npcHandler = npcHandler, text = "Goodbye, |PLAYERNAME|."}) + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye!") + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/eshaya.lua b/data/npc/scripts/eshaya.lua new file mode 100644 index 00000000000..52f3fd349bd --- /dev/null +++ b/data/npc/scripts/eshaya.lua @@ -0,0 +1,101 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local voices = { + {text = "Praised be Suon and Bastesh."}, + {text = "I should talk to Kallimae soon."}, + {text = "Issavi\'s safety is my first concern."} +} + +-- First + +local firstMission = keywordHandler:addKeyword( + {"mission"}, StdModule.say, { npcHandler = npcHandler, + text = "I\'m willing to admit that I need help. And the help of someone who is not from {Issavi} at that. But the task could be dangerous and you would become embroiled in the politics and court intrigues of {Kilmaresh}. Will you help me anyhow?"}, + function (player) return player:getStorageValue(Storage.Kilmaresh.Second.Investigating) == -1 end, + function (player) player:setStorageValue(Storage.Kilmaresh.First.Title, 1) end +) + + firstMission:addChildKeyword( + {"yes"}, StdModule.say, { npcHandler = npcHandler, + text = { + "You are a noble soul! So listen: for many decades, over a century actually, the city of {Rathleton} had an Ambassador here in {Issavi}. ...", + "Kilmaresh and Oramond maintain important commercial relations, and for this reason Rathleton has an envoy here. In the past, the relations were good but now ...", + "I hate to admit it but I heavily suspect that the current Ambassador is a traitor and consorts with the forbidden cult of Fafnar. I have several hints and Kallimae saw it in one of her visions ...", + "But the vision of a Kilmareshian seer is no proof they will ever accept in Rathleton. And without proof we can\'t banish the Ambassador, this would cause major diplomatic fallout or even a war. I can\'t risk that. ...", + "I need unequivocal evidence that the Ambassador conspires with the Fafnar cultists. Please go to his residence in the eastern part of the city and search for letters, journals ... anything that could prove him guilty." + }}, + nil, + function (player) player:setStorageValue(Storage.Kilmaresh.Second.Investigating, 1) end + ) + +-- Second + +keywordHandler:addKeyword( + {"mission"}, StdModule.say, { npcHandler = npcHandler, + text = { + "It seems that he destroyed every visible evidence of his treason. That\'s very unfortunate and I see only one remaining possibility: You need to see the {Ambassador}\'s memories. ...", + "But there is only one way to achieve this: You have to find a Ring of {Secret Thoughts}. Legend has it that a monstrous being called {Urmahlullu} has such a ring. If the myths are true you can find this creature in a subterranean tomb south of Issavi." + }}, + function (player) return player:getStorageValue(Storage.Kilmaresh.Second.Investigating) == 5 end, + function (player) + player:setStorageValue(Storage.Kilmaresh.Second.Investigating, 6) + player:setStorageValue(Storage.Kilmaresh.Third.Recovering, 1) + end +) + +keywordHandler:addKeyword( + {"mission"}, StdModule.say, { npcHandler = npcHandler, + text = "You haven\'t investigated all the evidence." }, + function (player) + return player:getStorageValue(Storage.Kilmaresh.Second.Investigating) >= 0 and + player:getStorageValue(Storage.Kilmaresh.Second.Investigating) < 5 + end +) + +-- Third + +keywordHandler:addKeyword( + {"ring"}, StdModule.say, { npcHandler = npcHandler, + text = "You found the Ring of {Secret Thoughts}! Well done! Now give it to the {Ambassador} as a present. He\'s a peacock and will accept such a precious gift for sure. As soon as he wears it, his memories will be stored in the ring."}, + function (player) return player:getStorageValue(Storage.Kilmaresh.Third.Recovering) == 1 and player:getItemById(36098, true) end, + function (player) player:setStorageValue(Storage.Kilmaresh.Third.Recovering, 2) end +) + +keywordHandler:addKeyword( + {"ring"}, StdModule.say, { npcHandler = npcHandler, + text = "You don't have the ring I need."}, + function (player) return player:getStorageValue(Storage.Kilmaresh.Third.Recovering) == 1 end +) + +-- Fifth + +keywordHandler:addKeyword( + {"mission"}, StdModule.say, { npcHandler = npcHandler, + text = "This is the proof we need! Very well done! You have to report this to our {Empress}. She will grant you an audience now."}, + function (player) return player:getStorageValue(Storage.Kilmaresh.Fifth.Memories) == 4 end, + function (player) player:setStorageValue(Storage.Kilmaresh.Fifth.Memories, 5) end +) + +npcHandler:setMessage(MESSAGE_GREET, "Suon\'s and Bastesh\'s blessing, dear guest!") +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(VoiceModule:new(voices)) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/esrik.lua b/data/npc/scripts/esrik.lua new file mode 100644 index 00000000000..fa48e65bd20 --- /dev/null +++ b/data/npc/scripts/esrik.lua @@ -0,0 +1,217 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function getTable(player) + local itemsList = { + {name="durable exercise axe", id=40115, buy=945000, subType = 1800}, + {name="durable exercise bow", id=40117, buy=945000, subType = 1800}, + {name="durable exercise club", id=40116, buy=945000, subType = 1800}, + {name="durable exercise sword", id=40114, buy=945000, subType = 1800}, + {name="exercise sword", id=32384, buy=262500, subType = 500}, + {name="exercise axe", id=32385, buy=262500, subType = 500}, + {name="exercise club", id=32386, buy=262500, subType = 500}, + {name="exercise bow", id=32387, buy=262500, subType = 500}, + {name="lasting exercise axe", id=40121, buy=7560000, subType = 14400}, + {name="lasting exercise bow", id=40123, buy=7560000, subType = 14400}, + {name="lasting exercise club", id=40122, buy=7560000, subType = 14400}, + {name="lasting exercise sword", id=40120, buy=7560000, subType = 14400}, + {name="axe", id=2386, buy=20, sell=7}, + {name="battle axe", id=2378, buy=235, sell=80}, + {name="battle hammer", id=2417, buy=350, sell=120}, + {name="battle shield", id=2417, sell=95}, + {name="brass armor", id=2465, buy=450, sell=150}, + {name="brass helmet", id=2460, buy=120, sell=30}, + {name="brass legs", id=2478, buy=195, sell=49}, + {name="brass shield", id=2511, buy=65, sell=25}, + {name="carlin sword", id=2395, buy=473, sell=118}, + {name="chain armor", id=2464, buy=200, sell=70}, + {name="chain helmet", id=2458, buy=52, sell=17}, + {name="chain legs", id=2648, buy=80, sell=25}, + {name="club", id=2382, buy=5, sell=1}, + {name="coat", id=2651, buy=8, sell=1}, + {name="crowbar", id=2416, buy=260, sell=50}, + {name="dagger", id=2379, buy=5, sell=2}, + {name="doublet", id=2485, buy=16, sell=3}, + {name="dwarven shield", id=2525, buy=500, sell=100}, + {name="hand axe", id=2380, buy=8, sell=4}, + {name="leather armor", id=2467, buy=35, sell=12}, + {name="leather boots", id=2643, buy=10, sell=2}, + {name="leather helmet", id=2461, buy=12, sell=9}, + {name="leather legs", id=2649, buy=10, sell=9}, + {name="longsword", id=2397, buy=160, sell=51}, + {name="mace", id=2398, buy=90, sell=30}, + {name="morning star", id=2394, buy=430, sell=100}, + {name="plate armor", id=2463, buy=1200, sell=400}, + {name="plate shield", id=2510, buy=125, sell=45}, + {name="rapier", id=2384, buy=15, sell=5}, + {name="sabre", id=2385, buy=35, sell=12}, + {name="scale armor", id=2483, buy=260, sell=75}, + {name="spear", id=2389, buy=10, sell=3}, + {name="short sword", id=2406, buy=26, sell=10}, + {name="sickle", id=2405, buy=7, sell=3}, + {name="soldier helmet", id=2481, buy=110, sell=16}, + {name="spike sword", id=2383, buy=8000, sell=240}, + {name="steel helmet", id=2457, buy=580, sell=293}, + {name="steel shield", id=2509, buy=240, sell=80}, + {name="studded armor", id=2484, buy=90, sell=25}, + {name="studded helmet", id=2482, buy=63, sell=20}, + {name="studded legs", id=2468, buy=50, sell=15}, + {name="studded shield", id=2526, buy=50, sell=16}, + {name="swampling club", id=20104, sell=40}, + {name="sword", id=2376, buy=85, sell=25}, + {name="throwing knife", id=2410, buy=25}, + {name="wooden shield", id=2512, buy=15, sell=3}, + {name="two handed sword", id=2377, sell=450}, + {name="bone shoulderplate", id=11321, sell=150}, + {name="broken draken mail", id=12616, sell=340}, + {name="broken halberd", id=11335, sell=100}, + {name="broken slicer", id=12617, sell=120}, + {name="cursed shoulder spikes", id=11327, sell=320}, + {name="drachaku", id=11308, sell=10000}, + {name="draken boots", id=12646, sell=40000}, + {name="draken wristbands", id=12615, sell=430}, + {name="drakinata", id=11305, sell=10000}, + {name="elite draken mail", id=12607, sell=50000}, + {name="guardian boots", id=11240, sell=35000}, + {name="high guard's shoulderplates", id=11333, sell=130}, + {name="sais", id=11306, sell=16500}, + {name="spiked iron ball", id=11325, sell=100}, + {name="twiceslicer", id=12613, sell=28000}, + {name="twin hooks", id=11309, buy=1100, sell=500}, + {name="wailing widow's necklace", id=11329, sell=3000}, + {name="warmaster's wristguards", id=11322, sell=200}, + {name="zaoan armor", id=11301, sell=14000}, + {name="zaoan halberd", id=11323, buy=1200, sell=500}, + {name="zaoan helmet", id=11302, sell=45000}, + {name="zaoan legs", id=11304, sell=14000}, + {name="zaoan shoes", id=11303, sell=5000}, + {name="zaoan sword", id=11307, sell=30000}, + {name="zaogun's shoulderplates", id=11331, sell=150} +} + + local tomes = { + { + -- 3 tomes + {name="lizard weapon rack kit", id=11126, buy=500} + }, + { + -- 9 tomes + {name="bone shoulderplate", id=11321, sell=150}, + {name="broken draken mail", id=12616, sell=340}, + {name="broken halberd", id=11335, sell=100}, + {name="Broken Slicer", id=12617, sell=120}, + {name="cursed shoulder spikes", id=11327, sell=320}, + {name="drachaku", id=11308, sell=10000}, + {name="draken boots", id=12646, sell=40000}, + {name="draken wristbands", id=12615, sell=430}, + {name="drakinata", id=11305, sell=10000}, + {name="Elite Draken Mail", id=12607, sell=50000}, + {name="guardian boots", id=11240, sell=35000}, + {name="high guard's shoulderplates", id=11333, sell=130}, + {name="sais", id=11306, sell=16500}, + {name="spiked iron ball", id=11325, sell=100}, + {name="twiceslicer", id=12613, sell=28000}, + {name="twin hooks", id=11309, buy=1100, sell=500}, + {name="wailing widow's necklace", id=11329, sell=3000}, + {name="warmaster's wristguards", id=11322, sell=200}, + {name="zaoan armor", id=11301, sell=14000}, + {name="zaoan halberd", id=11323, buy=1200, sell=500}, + {name="zaoan helmet", id=11302, sell=45000}, + {name="zaoan legs", id=11304, sell=14000}, + {name="zaoan shoes", id=11303, sell=5000}, + {name="zaoan sword", id=11307, sell=30000}, + {name="zaogun's shoulderplates", id=11331, sell=150} + } +} + + if player:getStorageValue(Storage.TheNewFrontier.TomeofKnowledge) >= 3 then + -- 3 tomes + for i = 1, #tomes[1] do + itemsList[#itemsList] = tomes[1][i] + end + end + + if player:getStorageValue(Storage.TheNewFrontier.TomeofKnowledge) >= 9 then + -- 9 tomes + for i = 1, #tomes[2] do + itemsList[#itemsList] = tomes[2][i] + end + end + + return itemsList +end + +local function setNewTradeTable(table) + local items, item = {} + for i = 1, #table do + item = table[i] + items[item.id] = {itemId = item.id, buyPrice = item.buy, sellPrice = item.sell, subType = item.subType, realName = item.name} + end + return items +end + +local function onBuy(cid, item, subType, amount, ignoreCap, inBackpacks) + local player = Player(cid) + local items = setNewTradeTable(getTable(player)) + local backpack = player:getSlotItem(CONST_SLOT_BACKPACK) + if not backpack or backpack:getEmptySlots(true) < 1 then + player:sendCancelMessage(RETURNVALUE_NOTENOUGHROOM) + return false + end + if not ignoreCap and player:getFreeCapacity() < ItemType(items[item].itemId):getWeight(amount) then + return player:sendTextMessage(MESSAGE_FAILURE, 'You don\'t have enough cap.') + end + if not player:removeMoneyNpc(items[item].buyPrice * amount) then + selfSay("You don't have enough money.", cid) + else + player:addItem(items[item].itemId, amount, true, subType) + return player:sendTextMessage(MESSAGE_TRADE, 'Bought '..amount..'x '..items[item].realName..' for '..items[item].buyPrice * amount..' gold coins.') + end + return true +end + +local function onSell(cid, item, subType, amount, ignoreCap, inBackpacks) + local player = Player(cid) + local items = setNewTradeTable(getTable(player)) + if items[item].sellPrice and player:removeItem(items[item].itemId, amount) then + player:addMoney(items[item].sellPrice * amount) + return player:sendTextMessage(MESSAGE_TRADE, 'Sold '..amount..'x '..items[item].realName..' for '..items[item].sellPrice * amount..' gold coins.') + else + selfSay("You don't have item to sell.", cid) + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, "trade") then + local player = Player(cid) + local items = setNewTradeTable(getTable(player)) + openShopWindow(cid, getTable(player), onBuy, onSell) + npcHandler:say("Of course, just browse through my wares.", cid) + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, 'Hello, |PLAYERNAME| and welcome to my little forge.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Bye.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ethan.lua b/data/npc/scripts/ethan.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/ethan.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/etzel.lua b/data/npc/scripts/etzel.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/etzel.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/evan.lua b/data/npc/scripts/evan.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/evan.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ezean.lua b/data/npc/scripts/ezean.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/ezean.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ezebeth.lua b/data/npc/scripts/ezebeth.lua new file mode 100644 index 00000000000..d821a202b1d --- /dev/null +++ b/data/npc/scripts/ezebeth.lua @@ -0,0 +1,62 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.DarkTrails.Mission01) == -1 then + npcHandler:say("Well, there is little where we need help beyond the normal tasks you can do for the city. However, there is one thing out of the ordinary where some {assistance} would be appreciated.", cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say("You already asked for a mission, go to the next.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "assistance") then + if npcHandler.topic[cid] == 1 then + npcHandler:say(" It's nothing really important, so no one has yet found the time to look it up. It concerns the towns beggars that have started to behave {strange} lately.", cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, "strange") then + if npcHandler.topic[cid] == 2 then + npcHandler:say("They usually know better than to show up in the streets and harass our citizens, but lately they've grown more bold or desperate or whatever. I ask you to investigate what they are up to. If necessary, you may scare them away a bit.", cid) + player:setStorageValue(Storage.DarkTrails.Mission01, 1) -- Mission 1 start + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "outfit") then + if player:getStorageValue(Storage.DarkTrails.Mission18) == 1 then + npcHandler:say("Nice work, take your outfit.", cid) + player:setStorageValue(Storage.DarkTrails.Outfit, 1) + doPlayerAddOutfit(610, 1) + doPlayerAddOutfit(618, 1) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.DarkTrails.Outfit) == 1 then + npcHandler:say("You already have the outfit.", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Hello! I guess you are here for a {mission}.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/fa_hradin.lua b/data/npc/scripts/fa_hradin.lua new file mode 100644 index 00000000000..ba80c4be43d --- /dev/null +++ b/data/npc/scripts/fa_hradin.lua @@ -0,0 +1,85 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + local missionProgress = player:getStorageValue(Storage.DjinnWar.MaridFaction.Mission02) + if msgcontains(msg, 'spy report') or msgcontains(msg, 'mission') then + if player:getStorageValue(Storage.DjinnWar.MaridFaction.Mission01) ~= 2 then + npcHandler:say('Looking for work, are you? Well, it\'s very tempting, you know, but I\'m afraid we do not really employ beginners. Perhaps our cook could need a helping hand in the kitchen.', cid) + + elseif missionProgress < 1 then + npcHandler:say({ + 'I have heard some good things about you from Bo\'ques. But I don\'t know. ...', + 'Well, all right. I do have a job for you. ...', + 'In order to stay informed about our enemy\'s doings, we have managed to plant a spy in Mal\'ouquah. ...', + 'He has kept the Efreet and Malor under surveillance for quite some time. ...', + 'But unfortunately, I have lost contact with him months ago. ...', + 'I do not fear for his safety because his cover is foolproof, but I cannot contact him either. This is where you come in. ...', + 'I need you to infiltrate Mal\'ouqhah, contact our man there and get his latest spyreport. The password is {PIEDPIPER}. Remember it well! ...', + 'I do not have to add that this is a dangerous mission, do I? If you are discovered expect to be attacked! So goodluck, human!' + }, cid) + player:setStorageValue(Storage.DjinnWar.MaridFaction.Mission02, 1) + player:setStorageValue(Storage.DjinnWar.MaridFaction.DoorToEfreetTerritory, 1) + + elseif missionProgress == 1 then + npcHandler:say('Did you already retrieve the spyreport?', cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say('Did you already talk to Gabel about the report? I think he will have further instructions for you.', cid) + end + + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, 'yes') then + if player:getStorageValue(Storage.DjinnWar.MaridFaction.RataMari) ~= 2 or not player:removeItem(2345, 1) then + npcHandler:say({ + 'Don\'t waste any more time. We need the spyreport of our man in Mal\'ouquah as soon as possible! ...', + 'Also don\'t forget the password to contact our man: PIEDPIPER!' + }, cid) + else + npcHandler:say({ + 'You really have made it? You have the report? How come you did not get slaughtered? I must say I\'m impressed. Your race will never cease to surprise me. ...', + 'Well, let\'s see. ...', + 'I think I need to talk to Gabel about this. I am sure he will know what to do. Perhaps you should have a word with him, too.' + }, cid) + player:setStorageValue(Storage.DjinnWar.MaridFaction.Mission02, 2) + end + + elseif msgcontains(msg, 'no') then + npcHandler:say({ + 'Don\'t waste any more time. We need the spyreport of our man in Mal\'ouquah as soon as possible! ...', + 'Also don\'t forget the password to contact our man: PIEDPIPER!' + }, cid) + end + end + return true +end + +-- Greeting +keywordHandler:addGreetKeyword({"djanni'hah"}, {npcHandler = npcHandler, text = "Aaaah... what have we here. A human - interesting. And such an ugly specimen, too... All right, human |PLAYERNAME|. How can I help you?"}) + +npcHandler:setMessage(MESSAGE_FAREWELL, 'Farewell, human. I will always remember you. Unless I forget you, of course.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Farewell, human. I will always remember you. Unless I forget you, of course.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/fadil.lua b/data/npc/scripts/fadil.lua new file mode 100644 index 00000000000..e88e935b7eb --- /dev/null +++ b/data/npc/scripts/fadil.lua @@ -0,0 +1,20 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/falk.lua b/data/npc/scripts/falk.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/falk.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/falonzo.lua b/data/npc/scripts/falonzo.lua new file mode 100644 index 00000000000..8fdd90abdf6 --- /dev/null +++ b/data/npc/scripts/falonzo.lua @@ -0,0 +1,94 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword( + {"name"}, StdModule.say, { npcHandler = npcHandler, + text = "I\'m professor Falonzo from the mage\'s guild." } +) + +keywordHandler:addKeyword( + {"job"}, StdModule.say, { npcHandler = npcHandler, + text = "I\'m a researcher of scientific council of the mage guild and I came to that {place} to study this {anomaly}." } +) + +keywordHandler:addKeyword( + {"place"}, StdModule.say, { npcHandler = npcHandler, + text = { + "This {plane} is now inhabited by {intruders} and creatures that accidentally became {dragged} in. ...", + "It is neither completely of our world nor is it still that disconnected and unreachable as it used to be. I fear it\'s only a harbinger of something more dangerous and more {sinister}." + }} +) + +keywordHandler:addKeyword( + {"anomaly"}, StdModule.say, { npcHandler = npcHandler, + text = { + "Well, the whole place here is an anomaly so to say. You can hardly have missed the fact that you arrived here through a mystical gate. ...", + "Well actually it\'s no gate at all but a rift in the fabric of nature. It is this minor {plane} trying to reconnect to our world." + }} +) + +keywordHandler:addKeyword( + {"plane"}, StdModule.say, { npcHandler = npcHandler, + text = "This is a lesser plane of tarnished, elemental fire that once belonged to the world that we know. It was despoiled in the wars of the gods and broke loose from our world. {Lost} and drifting through the void, without a connection to our plane." } +) + +keywordHandler:addKeyword( + {"intruders"}, StdModule.say, { npcHandler = npcHandler, + text = "Infernalists were the first who found their way into this sphere. Hoping to tap its rotten power somehow. Yet this sphere created creatures of its own and draw others here from other planes." } +) + +keywordHandler:addKeyword( + {"dragged"}, StdModule.say, { npcHandler = npcHandler, + text = { + "This place became a fiery trap to certain beings with an affinity to fire. Somehow it reconnects randomly with the known world, to which it once belonged ...", + "but also to other places that it shares some affinity with like hellish places of unspeakable evil that spawn infernal creatures." + }} +) + +keywordHandler:addKeyword( + {"sinister"}, StdModule.say, { npcHandler = npcHandler, + text = { + "Something is tearing at the fabric of reality. I can\'t tell what is it but the {boundaries} between worlds are fading. ...", + "A process that what watched for over a century but which has extremely grown in momentum over the last few years. Something is happening and it\'s for sure nothing good. ...", + "Be it as it may, the plane trying to reconnect was only a side effect. It still might teach us about what is happening and it has for sure attracted some {attention} already." + }} +) +keywordHandler:addAliasKeyword({'changed'}) + +keywordHandler:addKeyword( + {"lost"}, StdModule.say, { npcHandler = npcHandler, + text = "Well, that was how it used to be. Lost and without any connection to our world. But that was before things ... have {changed}." } +) + +keywordHandler:addKeyword( + {"boundaries"}, StdModule.say, { npcHandler = npcHandler, + text = { + "We know about other planes of existence but in all history it has never been as easy to reach them as it is now. ...", + "Sometimes world seem to overlap and we can identify more and more such planes and worlds. More then we ever had imagined. All we can tell is, that something is changing. And not for the good." + }} +) + +keywordHandler:addKeyword( + {"attention"}, StdModule.say, { npcHandler = npcHandler, + text = "Such an anomaly can\'t go unnoticed for long. That lead to the presence to unwanted {intruders} and other entities were {dragged} into by the nature of the sphere." } +) + +npcHandler:setMessage(MESSAGE_GREET, "Greetings, adventurer!") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Well, bye then.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/faloriel.lua b/data/npc/scripts/faloriel.lua new file mode 100644 index 00000000000..14daab0aa6d --- /dev/null +++ b/data/npc/scripts/faloriel.lua @@ -0,0 +1,53 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local voices = { + {text = "Health potions! Mana potions! Buy them here!"}, + {text = "All kinds of potions available here!"} +} + +local potionTalk = keywordHandler:addKeyword( + {"ring"}, StdModule.say, { npcHandler = npcHandler, + text = "So, the Librarian sent you. Well, yes, I have a vial of the hallucinogen you need. I'll give it to you for 1000 gold. Do you agree?"}, + function (player) return player:getStorageValue(Storage.Kilmaresh.Fifth.Memories) == 1 end +) + + potionTalk:addChildKeyword( + {"yes"}, StdModule.say, { npcHandler = npcHandler, + text = "Great. Here, take it."}, + function (player) return player:getMoney() + player:getBankBalance() >= 1000 end, + function (player) + player:removeMoneyNpc(1000) + player:addItem(36185, 1) -- flask of hallucinogen + end + ) + + potionTalk:addChildKeyword( + {"yes"}, StdModule.say, { npcHandler = npcHandler, + text = "You do not have enough money."}, + function (player) return player:getMoney() + player:getBankBalance() < 1000 end + ) + +npcHandler:setMessage(MESSAGE_GREET, 'Greetings, dear guest and welcome to my {potion} shop.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(VoiceModule:new(voices)) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/faluae.lua b/data/npc/scripts/faluae.lua new file mode 100644 index 00000000000..eac508821e8 --- /dev/null +++ b/data/npc/scripts/faluae.lua @@ -0,0 +1,25 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +-- Greeting message +keywordHandler:addGreetKeyword({"ashari"}, {npcHandler = npcHandler, text = "Greetings, |PLAYERNAME|."}) +--Farewell message +keywordHandler:addFarewellKeyword({"asgha thrazi"}, {npcHandler = npcHandler, text = "Goodbye, |PLAYERNAME|."}) + +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye!") + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/fayla.lua b/data/npc/scripts/fayla.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/fayla.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/feizuhl.lua b/data/npc/scripts/feizuhl.lua new file mode 100644 index 00000000000..72dbf504691 --- /dev/null +++ b/data/npc/scripts/feizuhl.lua @@ -0,0 +1,23 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'I sell furniture both to the mourned and the enlightened.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "Be mourned pilgrim in flesh and welcome to the furniture store.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Have a look. Most furniture comes in handy kits. Just use them in your house to assemble the furniture. Do you want to see only a certain type of furniture?") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/fenbala.lua b/data/npc/scripts/fenbala.lua new file mode 100644 index 00000000000..a395e4204c0 --- /dev/null +++ b/data/npc/scripts/fenbala.lua @@ -0,0 +1,52 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +keywordHandler:addKeyword({'hi'}, StdModule.say, {npcHandler = npcHandler, onlyUnfocus = true, text = "MIND YOUR MANNERS COMMONER! To address the queen greet with her title!"}) +keywordHandler:addKeyword({'hello'}, StdModule.say, {npcHandler = npcHandler, onlyUnfocus = true, text = "MIND YOUR MANNERS COMMONER! To address the queen greet with her title!"}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if isInArray({'fuck', 'idiot', 'asshole', 'ass', 'fag', 'stupid', 'tyrant', 'shit', 'lunatic'}, msg) then + local player = Player(cid) + local conditions = { CONDITION_POISON, CONDITION_FIRE, CONDITION_ENERGY, CONDITION_BLEEDING, CONDITION_PARALYZE, CONDITION_DROWN, CONDITION_FREEZING, CONDITION_DAZZLED, CONDITION_CURSED } + for i = 1, #conditions do + if player:getCondition(conditions[i]) then + player:removeCondition(conditions[i]) + end + end + player:getPosition():sendMagicEffect(CONST_ME_EXPLOSIONAREA) + player:addHealth(1 - player:getHealth()) + npcHandler:say('Take this!', cid) + Npc():getPosition():sendMagicEffect(CONST_ME_YELLOW_RINGS) + end + return true +end + +-- Greeting +keywordHandler:addGreetKeyword({'hail queen'}, {npcHandler = npcHandler, text = 'HAIL TO THE QUEEN!'}) +keywordHandler:addGreetKeyword({'salutations queen'}, {npcHandler = npcHandler, text = 'HAIL TO THE QUEEN!'}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'LONG LIVE THE QUEEN!') +npcHandler:setMessage(MESSAGE_FAREWELL, 'LONG LIVE THE QUEEN! You may leave now!') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/fenech.lua b/data/npc/scripts/fenech.lua new file mode 100644 index 00000000000..8acb591c520 --- /dev/null +++ b/data/npc/scripts/fenech.lua @@ -0,0 +1,63 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Offering all sorts of magic equipment.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local items = { + [VOCATION.CLIENT_ID.SORCERER] = 2190, + [VOCATION.CLIENT_ID.DRUID] = 2182 +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'first rod') or msgcontains(msg, 'first wand') then + if player:isMage() then + local itemId = items[player:getVocation():getClientId()] + if player:getStorageValue(Storage.firstMageWeapon) == -1 then + npcHandler:say('So you ask me for a {' .. ItemType(itemId):getName() .. '} to begin your adventure?', cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say('What? I have already gave you one {' .. ItemType(itemId):getName() .. '}!', cid) + end + else + npcHandler:say('Sorry, you aren\'t a druid either a sorcerer.', cid) + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + player:addItem(itemId, 1) + npcHandler:say('Here you are young adept, take care yourself.', cid) + player:setStorageValue(Storage.firstMageWeapon, 1) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] == 1 then + npcHandler:say('Ok then.', cid) + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "Be mourned pilgrim in flesh and welcome to the magic store.") +npcHandler:setMessage(MESSAGE_FAREWELL, "May enlightenment be your path.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "May enlightenment be your path.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Of course, just browse through my wares. Or do you want to look only at wands or runes?") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/fergus.lua b/data/npc/scripts/fergus.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/fergus.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ferryman_kamil.lua b/data/npc/scripts/ferryman_kamil.lua new file mode 100644 index 00000000000..489e93e7a2f --- /dev/null +++ b/data/npc/scripts/ferryman_kamil.lua @@ -0,0 +1,23 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Don't forget npcHandler = npcHandler in the parameters. It is required for all StdModule functions! +local travelNode = keywordHandler:addKeyword({'meluna'}, StdModule.say, {npcHandler = npcHandler, text = 'You want me to transport you and your spouse to Honeymoon Island {Meluna}?'}) + travelNode:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, level = 0, cost = 0, destination = Position(32088, 32470, 7) }) + travelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, reset = true, text = 'You shouldn\'t miss the experience.'}) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ferryman_kamil_meluna.lua b/data/npc/scripts/ferryman_kamil_meluna.lua new file mode 100644 index 00000000000..3ddb3685101 --- /dev/null +++ b/data/npc/scripts/ferryman_kamil_meluna.lua @@ -0,0 +1,26 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + +-- Don't forget npcHandler = npcHandler in the parameters. It is required for all StdModule functions! +local travelNode = keywordHandler:addKeyword({'fibula'}, StdModule.say, {npcHandler = npcHandler, text = 'You want me to transport you and your spouse back to {Fibula}?'}) + travelNode:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, level = 0, cost = 0, destination = Position(32153, 32457, 7) }) + travelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, reset = true, text = 'You shouldn\'t miss the experience.'}) + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ferus.lua b/data/npc/scripts/ferus.lua new file mode 100644 index 00000000000..98d74790c50 --- /dev/null +++ b/data/npc/scripts/ferus.lua @@ -0,0 +1,95 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Twist of Fate +local blessKeyword = keywordHandler:addKeyword({'twist of fate'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'This is a special blessing I can bestow upon you once you have obtained at least one of the other blessings and which functions a bit differently. ...', + 'It only works when you\'re killed by other adventurers, which means that at least half of the damage leading to your death was caused by others, not by monsters or the environment. ...', + 'The {twist of fate} will not reduce the death penalty like the other blessings, but instead prevent you from losing your other blessings as well as the amulet of loss, should you wear one. It costs the same as the other blessings. ...', + 'Would you like to receive that protection for a sacrifice of |PVPBLESSCOST| gold, child?' + }}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the protection of the twist of fate, pilgrim.', cost = '|PVPBLESSCOST|', bless = 1}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Adventurer Stone +keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Keep your adventurer\'s stone well.'}, function(player) return player:getItemById(18559, true) end) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for free?'}, function(player) return player:getStorageValue(Storage.AdventurersGuild.FreeStone.Alia) ~= 1 end) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, nil, function(player) player:addItem(18559, 1) player:setStorageValue(Storage.AdventurersGuild.FreeStone.Alia, 1) end) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for 30 gold?'}) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, + function(player) return player:getMoney() + player:getBankBalance() >= 30 end, + function(player) if player:removeMoneyNpc(30) then player:addItem(18559, 1) end end + ) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, you don\'t have enough money.', reset = true}) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.'}, function(player) return player:hasBlessing(2) end) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin will provide you with the embrace of Tibia.'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, young |PLAYERNAME|! If you are heavily wounded or poisoned, I can {heal} you for free.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Remember: If you are heavily wounded or poisoned, I can heal you for free.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'May the gods bless you, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/fillias.lua b/data/npc/scripts/fillias.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/fillias.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/fiona.lua b/data/npc/scripts/fiona.lua new file mode 100644 index 00000000000..77e2f2e69a9 --- /dev/null +++ b/data/npc/scripts/fiona.lua @@ -0,0 +1,27 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'The Edron academy is always in need of magical ingredients!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +keywordHandler:addKeyword({'magical ingredients'}, StdModule.say, {npcHandler = npcHandler, text = "Oof, there are too many to list. Magical ingredients can sometimes be found when you defeat a monster, for example bat wings. I buy many of these things if you don't want to use them for quests, just ask me for a {trade}."}) + +npcHandler:setMessage(MESSAGE_GREET, "Good day, |PLAYERNAME|. I hope you bring a lot of {magical ingredients} with you.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye and please come back soon.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye and please come back soon.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Sure, take a look. Apart from those, I also buy some of the possessions from famous demonlords and bosses. Ask me about it if you found anything interesting.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/flint.lua b/data/npc/scripts/flint.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/flint.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/flora.lua b/data/npc/scripts/flora.lua new file mode 100644 index 00000000000..1cda1acd95d --- /dev/null +++ b/data/npc/scripts/flora.lua @@ -0,0 +1,55 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +--Feito por Master Viciado 18/08/2016 + +local function greetCallback(cid) + npcHandler:setMessage(MESSAGE_GREET, "Greetings, " .. Player(cid):getName() .. ". Well, we all know what time it is. Always when we meet, the citizens of rathleton voted for the {Glooth Fairy}! ... Well, the rules are as simples as always. Ask me for a {fight} and I\'ll teleport you into the room with the lever, therefore I\'ll charge one voting right. ... From this room there is no way back to me. Pull the trigger and after one minute you and your buddies will face the {Glooth Fairy}.", cid) + npcHandler.topic[cid] = 0 + return true +end + +local function creatureSayCallback(cid, type, msg) + if(not npcHandler:isFocused(cid)) then + return false + end + + if(msgcontains(msg, "fight")) then + npcHandler:say("Do you really want to enter the Glooth Fairy\'s hideout. There is no chickening out and I also have to charge one voting right! {Yes} or {no}?", cid) + npcHandler.topic[cid] = 1 + elseif(msgcontains(msg, "yes")) then + if(npcHandler.topic[cid] == 1) then + npcHandler:say("Here you go!", cid) + local pos = {x=33660, y=31936, z=9} + doTeleportThing(cid, pos) + doSendMagicEffect(pos, CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "no")) then + if(npcHandler.topic[cid] == 1) then + npcHandler:say("Okay...", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_FAREWELL, 'Come back soon.') +npcHandler:setMessage(MESSAGE_WALKAWAY, '') +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/florentine.lua b/data/npc/scripts/florentine.lua new file mode 100644 index 00000000000..b0b9d543b8e --- /dev/null +++ b/data/npc/scripts/florentine.lua @@ -0,0 +1,23 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Embellish your home with flowers!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome, |PLAYERNAME|. What can I do for you?") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Of course, just browse through my wares.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/frafnar.lua b/data/npc/scripts/frafnar.lua new file mode 100644 index 00000000000..ad689fc84fb --- /dev/null +++ b/data/npc/scripts/frafnar.lua @@ -0,0 +1,52 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.HiddenCityOfBeregar.SweetAsChocolateCake) < 1 then + npcHandler:say("There is indeed something you could do for me. You must know, I'm in love with Bolfana. I'm sure she'd have a beer with me if I got her a chocolate cake. Problem is that I can't leave this door as I'm on duty. Would you be so kind and help me?", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.HiddenCityOfBeregar.SweetAsChocolateCake) == 2 then + npcHandler:say("So did you tell her that the cake came from me?", cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + player:setStorageValue(Storage.HiddenCityOfBeregar.SweetAsChocolateCake, 1) + player:setStorageValue(Storage.HiddenCityOfBeregar.DefaultStart, 1) + npcHandler:say("Great! She works in the tavern of Beregar. It's situated in the western part of the city. Bring her a chocolate cake and tell her that it was me who sent it.", cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + player:setStorageValue(Storage.HiddenCityOfBeregar.SweetAsChocolateCake, 3) + player:setStorageValue(Storage.HiddenCityOfBeregar.DoorWestMine, 1) + npcHandler:say("Great! That's my breakthrough. Now she can't refuse to go out with me. I grant you access to the western part of the mine.", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, "See you my friend.") +npcHandler:setMessage(MESSAGE_FAREWELL, "See you my friend.") +npcHandler:setMessage(MESSAGE_GREET, "Don't you see that I'm trying to write a poem? So what's the matter?") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/frank_the_plank.lua b/data/npc/scripts/frank_the_plank.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/frank_the_plank.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/frans.lua b/data/npc/scripts/frans.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/frans.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/frederik.lua b/data/npc/scripts/frederik.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/frederik.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/freezhild.lua b/data/npc/scripts/freezhild.lua new file mode 100644 index 00000000000..eb94c8b5c57 --- /dev/null +++ b/data/npc/scripts/freezhild.lua @@ -0,0 +1,48 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, "weapons") then + if player:getStorageValue(Storage.SecretService.AVINMission06) == 1 then + npcHandler:say("Crate of weapons you say.. for me?", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + if player:removeItem(7707, 1) then + player:setStorageValue(Storage.SecretService.AVINMission06, 2) + npcHandler:say("Why thank you |PLAYERNAME|.", cid) + else + npcHandler:say("You don't have any crate of weapons!", cid) + end + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, "I hope you have a cold day, friend.") +npcHandler:setMessage(MESSAGE_FAREWELL, "I hope you have a cold day, friend.") +npcHandler:setMessage(MESSAGE_GREET, "Welcome, to my cool home.") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/frodo.lua b/data/npc/scripts/frodo.lua new file mode 100644 index 00000000000..f261a7e33e6 --- /dev/null +++ b/data/npc/scripts/frodo.lua @@ -0,0 +1,73 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Come into my tavern and share some stories!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Basic +keywordHandler:addKeyword({'hut'}, StdModule.say, {npcHandler = npcHandler, text = "I hope you like it. Would you like some {food}?"}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am the owner of this saloon. I call it Frodo's Hut. I am also {selling} food."}) +keywordHandler:addAliasKeyword({'saloon'}) +keywordHandler:addKeyword({'food'}, StdModule.say, {npcHandler = npcHandler, text = "I can offer you bread, cheese, ham, or meat. If you'd like to see my offers, ask me for a trade."}) +keywordHandler:addKeyword({'news'}, StdModule.say, {npcHandler = npcHandler, text = "Some travelers from Edron told about a great treasure guarded by cruel demons in the dungeons there."}) +keywordHandler:addKeyword({'king'}, StdModule.say, {npcHandler = npcHandler, text = "Oh, our beloved king! Thanks to him, alcohol is so cheap."}) +keywordHandler:addAliasKeyword({'tibianus'}) +keywordHandler:addKeyword({'general'}, StdModule.say, {npcHandler = npcHandler, text = "Harkath Bloodblade is the royal general."}) +keywordHandler:addKeyword({'army'}, StdModule.say, {npcHandler = npcHandler, text = "Hehe. Great customers."}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "Just call me Frodo."}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = "It is exactly |TIME|."}) +keywordHandler:addKeyword({'dungeons'}, StdModule.say, {npcHandler = npcHandler, text = "Ah yes, the graveyard dungeon. All I know is this riddle: His Grave to the south, the tree above, his soul in the shade. No idea what that means, though!"}) +keywordHandler:addAliasKeyword({'graveyard'}) +keywordHandler:addKeyword({'riddle'}, StdModule.say, {npcHandler = npcHandler, text = " I heard it when I was a child."}) +keywordHandler:addKeyword({'one eyed stranger'}, StdModule.say, {npcHandler = npcHandler, text = "Yes, I remember him. His name was Berfasmur."}) +keywordHandler:addKeyword({'berfasmur'}, StdModule.say, {npcHandler = npcHandler, text = "Sorry, he spoke only very little. I know nothing more about him."}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = "Come on! You know that our world is called Tibia."}) +keywordHandler:addKeyword({'excalibug'}, StdModule.say, {npcHandler = npcHandler, text = "Nothing more than a tale for warriors."}) +keywordHandler:addKeyword({'ferumbras'}, StdModule.say, {npcHandler = npcHandler, text = "Uhm, do not mention him. It may scare customers away."}) +keywordHandler:addKeyword({'cropwell'}, StdModule.say, {npcHandler = npcHandler, text = "No idea who that is, but maybe you'll find something in the Royal Archives..."}) +keywordHandler:addKeyword({'royal archives'}, StdModule.say, {npcHandler = npcHandler, text = "Oh, the Royal Archives are in Rain Castle!"}) +keywordHandler:addKeyword({'rain castle'}, StdModule.say, {npcHandler = npcHandler, text = "The king's residence has been renovated lately."}) +keywordHandler:addKeyword({'carlin'}, StdModule.say, {npcHandler = npcHandler, text = "Many travellers tell funny stories about all the emancipated women in this northern town."}) +keywordHandler:addKeyword({'thais'}, StdModule.say, {npcHandler = npcHandler, text = "Here in Thais is the center of Tibia."}) +keywordHandler:addKeyword({'donald'}, StdModule.say, {npcHandler = npcHandler, text = "He is a little shy. In his youth he dreamed to become a druid."}) +keywordHandler:addKeyword({'baxter'}, StdModule.say, {npcHandler = npcHandler, text = "He's able to drink a bottle or two."}) +keywordHandler:addKeyword({'bozo'}, StdModule.say, {npcHandler = npcHandler, text = "I am trying to hire him for an evening or two."}) +keywordHandler:addKeyword({'eclesius'}, StdModule.say, {npcHandler = npcHandler, text = "Oh, that old guy! He's a good customer, that's for sure."}) +keywordHandler:addKeyword({'elane'}, StdModule.say, {npcHandler = npcHandler, text = "Can you believe that she actually told her guildfellows that alcohol is a bad thing?"}) +keywordHandler:addKeyword({'galuna'}, StdModule.say, {npcHandler = npcHandler, text = "She makes excellent arrows and bows."}) +keywordHandler:addKeyword({'gorn'}, StdModule.say, {npcHandler = npcHandler, text = "Many of his customers visit my Hut, too."}) +keywordHandler:addKeyword({'gregor'}, StdModule.say, {npcHandler = npcHandler, text = "The knights have sometimes parties here after some arena fights."}) +keywordHandler:addKeyword({'harkath bloodblade'}, StdModule.say, {npcHandler = npcHandler, text = "Too disciplined to enjoy life."}) +keywordHandler:addKeyword({'hugo'}, StdModule.say, {npcHandler = npcHandler, text = "I think some time ago a stranger from Fibula with that name stayed here for some nights."}) +keywordHandler:addKeyword({'lugri'}, StdModule.say, {npcHandler = npcHandler, text = "I overheard some conversations about his evilness. That's enough to hope, that I never ever meet him."}) +keywordHandler:addKeyword({'lungelen'}, StdModule.say, {npcHandler = npcHandler, text = "A sorceress, you can find her in their guild sitting befor a book - always!"}) +keywordHandler:addKeyword({'lynda'}, StdModule.say, {npcHandler = npcHandler, text = "Just between you and me: What a babe!"}) +keywordHandler:addKeyword({'marvik'}, StdModule.say, {npcHandler = npcHandler, text = "Marvik seldom leaves his guildhall at all."}) +keywordHandler:addKeyword({'mcronald'}, StdModule.say, {npcHandler = npcHandler, text = "The McRonalds are a nice couple. Donald is a dear friend of mine."}) +keywordHandler:addAliasKeyword({'sherry'}) +keywordHandler:addKeyword({'muriel'}, StdModule.say, {npcHandler = npcHandler, text = "Muriel has never visited this place."}) +keywordHandler:addKeyword({'oswald'}, StdModule.say, {npcHandler = npcHandler, text = "I hate him. Each of his visits here ends with a bar brawl."}) +keywordHandler:addKeyword({'quentin'}, StdModule.say, {npcHandler = npcHandler, text = "He hardly visits my humble tavern."}) +keywordHandler:addKeyword({'samuel'}, StdModule.say, {npcHandler = npcHandler, text = "A loud neighbour, I get a lot of complaints about him."}) +keywordHandler:addKeyword({'todd'}, StdModule.say, {npcHandler = npcHandler, text = "That fellow is filthy rich. He rented a room upstairs for months in advance and always orders the best beer and wine i serve."}) +keywordHandler:addKeyword({'xodet'}, StdModule.say, {npcHandler = npcHandler, text = "I don't know where he gets these fluids. If I could sell them here, the hut would be crowded."}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome to Frodo's Hut. You heard about the {news}?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Please come back from time to time.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Please come back from time to time.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/frosty.lua b/data/npc/scripts/frosty.lua new file mode 100644 index 00000000000..22f2224f7dd --- /dev/null +++ b/data/npc/scripts/frosty.lua @@ -0,0 +1,128 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +local talkState = {} +local rtnt = {} +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'carrot'}, StdModule.say, {npcHandler = npcHandler, text = "What about 'no' do you not understand, hrm? You are more annoying than any {percht} around here! Not to mention those bothersome {bunnies} who try to graw away my nose!"}) +keywordHandler:addKeyword({'percht skull'}, StdModule.say, {npcHandler = npcHandler, text = "Well why didn't you say that rightaway, if you give me such a skull I can give you one of my {sleighs}."}) +keywordHandler:addKeyword({'bunnies'}, StdModule.say, {npcHandler = npcHandler, text = "Always trying to eat my nose!"}) + +npcHandler:setMessage(MESSAGE_GREET, "No, you can't have my nose! If you're in need of a {carrot}, go to the market or just dig up one! Or did you come to bring me a {percht skull}?") + + +sleighinfo = { +['bright percht sleigh'] = {cost = 0, items = {{35051,1}}, mount = 133, storageID = Storage.Percht1}, +['cold percht sleigh'] = {cost = 0, items = {{35051,1}}, mount = 132, storageID = Storage.Percht2}, +['dark percht sleigh'] = {cost = 0, items = {{35051,1}}, mount = 134, storageID = Storage.Percht3}, +} + +local monsterName = {'bright percht sleigh', 'cold percht sleigh', 'dark percht sleigh'} + +function creatureSayCallback(cid, type, msg) +local talkUser = cid +local player = Player(cid) + + if(not npcHandler:isFocused(cid)) then + return false + end + + if sleighinfo[msg] ~= nil then + if (getPlayerStorageValue(cid, sleighinfo[msg].storageID) ~= -1) then + npcHandler:say('You already have this sleigh!', cid) + npcHandler:resetNpc() + else + local itemsTable = sleighinfo[msg].items + local items_list = '' + if table.maxn(itemsTable) > 0 then + for i = 1, table.maxn(itemsTable) do + local item = itemsTable[i] + items_list = items_list .. item[2] .. ' ' .. ItemType(item[1]):getName() + if i ~= table.maxn(itemsTable) then + items_list = items_list .. ', ' + end + end + end + local text = '' + if (sleighinfo[msg].cost > 0) then + text = sleighinfo[msg].cost .. ' gp' + elseif table.maxn(sleighinfo[msg].items) then + text = items_list + elseif (sleighinfo[msg].cost > 0) and table.maxn(sleighinfo[msg].items) then + text = items_list .. ' and ' .. sleighinfo[msg].cost .. ' gp' + end + npcHandler:say('For a ' .. msg .. ' you will need ' .. text .. '. Do you have it with you?', cid) + rtnt[talkUser] = msg + talkState[talkUser] = sleighinfo[msg].storageID + return true + end + elseif msg:lower() == 'percht' then + npcHandler:say('Nasty creatures especially their queen that sits frozzen on her throne beneath this island.', cid) + elseif msgcontains(msg, "yes") then + if (talkState[talkUser] >= Storage.Percht1 and talkState[talkUser] <= Storage.Percht3) then + local items_number = 0 + if table.maxn(sleighinfo[rtnt[talkUser]].items) > 0 then + for i = 1, table.maxn(sleighinfo[rtnt[talkUser]].items) do + local item = sleighinfo[rtnt[talkUser]].items[i] + if (getPlayerItemCount(cid,item[1]) >= item[2]) then + items_number = items_number + 1 + end + end + end + if(player:removeMoneyNpc(sleighinfo[rtnt[talkUser]].cost) and (items_number == table.maxn(sleighinfo[rtnt[talkUser]].items))) then + if table.maxn(sleighinfo[rtnt[talkUser]].items) > 0 then + for i = 1, table.maxn(sleighinfo[rtnt[talkUser]].items) do + local item = sleighinfo[rtnt[talkUser]].items[i] + doPlayerRemoveItem(cid,item[1],item[2]) + end + end + doPlayerAddMount(cid, sleighinfo[rtnt[talkUser]].mount) + setPlayerStorageValue(cid,sleighinfo[rtnt[talkUser]].storageID,1) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('You do not have needed items!', cid) + end + rtnt[talkUser] = nil + talkState[talkUser] = 0 + npcHandler:resetNpc() + return true + end + elseif msgcontains(msg, "mount") or msgcontains(msg, "mounts") or msgcontains(msg, "sleigh") or msgcontains(msg, "sleighs") then + npcHandler:say('I can give you one of the following sleighs: {' .. table.concat(monsterName, "}, {") .. '}.', cid) + rtnt[talkUser] = nil + talkState[talkUser] = 0 + npcHandler:resetNpc() + return true + elseif msgcontains(msg, "help") then + npcHandler:say('Just tell me which {sleigh} you want to know more about.', cid) + rtnt[talkUser] = nil + talkState[talkUser] = 0 + npcHandler:resetNpc() + return true + else + if talkState[talkUser] ~= nil then + if talkState[talkUser] > 0 then + npcHandler:say('Come back when you get these items.', cid) + rtnt[talkUser] = nil + talkState[talkUser] = 0 + npcHandler:resetNpc() + return true + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/fynn.lua b/data/npc/scripts/fynn.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/fynn.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/fyodor.lua b/data/npc/scripts/fyodor.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/fyodor.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gabel.lua b/data/npc/scripts/gabel.lua new file mode 100644 index 00000000000..5d1a12142bb --- /dev/null +++ b/data/npc/scripts/gabel.lua @@ -0,0 +1,97 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + local missionProgress = player:getStorageValue(Storage.DjinnWar.MaridFaction.Mission03) + if msgcontains(msg, 'mission') then + if player:getStorageValue(Storage.DjinnWar.MaridFaction.Mission02) ~= 2 then + npcHandler:say({ + 'So you would like to fight for us, would you. Hmm. ...', + 'That is a noble resolution you have made there, human, but I\'m afraid I cannot accept your generous offer at this point of time. ...', + 'Do not get me wrong, but I am not the kind of guy to send an inexperienced soldier into certain death! So you might ask around here for a more suitable mission.' + }, cid) + + elseif missionProgress < 1 then + npcHandler:say({ + 'Sooo. Fa\'hradin has told me about your extraordinary exploit, and I must say I am impressed. ...', + 'Your fragile human form belies your courage and your fighting spirit. ...', + 'I hardly dare to ask you because you have already done so much for us, but there is a task to be done, and I cannot think of anybody else who would be better suited to fulfill it than you. ...', + 'Think carefully, human, for this mission will bring you into real danger. Are you prepared to do us that final favour?' + }, cid) + npcHandler.topic[cid] = 1 + + elseif missionProgress == 1 then + npcHandler:say('You haven\'t finished your final mission yet. Shall I explain it again to you?', cid) + npcHandler.topic[cid] = 1 + + elseif missionProgress == 2 then + npcHandler:say('Have you found Fa\'hradin\'s lamp and placed it in Malor\'s personal chambers?', cid) + npcHandler.topic[cid] = 2 + else + npcHandler:say('There\'s no mission left for you, friend of the Marid. However, I have a task for you.', cid) + end + + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, 'yes') then + npcHandler:say({ + 'All right. Listen! Thanks to Rata\'mari\'s report we now know what Malor is up to: he wants to do to me what I have done to him - he wants to imprison me in Fa\'hradin\'s lamp! ...', + 'Of course, that won\'t happen. Now, we know his plans. ...', + 'But I am aiming at something different. We have learnt one important thing: At this point of time, Malor does not have the lamp yet, which means it is still where he left it. We need that lamp! If we get it back we can imprison him again! ...', + 'From all we know the lamp is still in the Orc King\'s possession! Therefore I want to ask you to enter thewell guarded halls over at Ulderek\'s Rock and find the lamp. ...', + 'Once you have acquired the lamp you must enter Mal\'ouquah again. Sneak into Malor\'s personal chambersand exchange his sleeping lamp with Fa\'hradin\'s lamp! ...', + 'If you succeed, the war could be over one night later! I and all djinn will be in your debt forever! May Daraman watch over you!' + }, cid) + player:setStorageValue(Storage.DjinnWar.MaridFaction.Mission03, 1) + + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish.', cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, 'yes') then + npcHandler:say({ + 'Daraman shall bless you and all humans! You have done us all a huge service! Soon, this awful war will be over! ...', + 'Know, that from now on you are considered one of us and are welcome to trade with Haroun and Nah\'bob whenever you want to!' + }, cid) + player:setStorageValue(Storage.DjinnWar.MaridFaction.Mission03, 3) + player:setStorageValue(Storage.DjinnWar.MaridFaction.DoorToEfreetTerritory, 1) + player:addAchievement('Marid Ally') + + elseif msgcontains(msg, 'no') then + npcHandler:say('Don\'t give up! May Daraman watch over you!', cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +-- Greeting +keywordHandler:addGreetKeyword({"djanni'hah"}, {npcHandler = npcHandler, text = "Welcome, human |PLAYERNAME|, to our humble abode."}) + +npcHandler:setMessage(MESSAGE_FAREWELL, "Farewell, stranger. May Uman open your minds and your hearts to Daraman's wisdom!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Farewell, stranger. May Uman open your minds and your hearts to Daraman's wisdom!") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/gail.lua b/data/npc/scripts/gail.lua new file mode 100644 index 00000000000..484f5e706fe --- /dev/null +++ b/data/npc/scripts/gail.lua @@ -0,0 +1,61 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local playerTopic = {} +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.Kilmaresh.First.Access) < 1 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + playerTopic[cid] = 1 + elseif (player:getStorageValue(Storage.Kilmaresh.First.JamesfrancisTask) >= 0 and player:getStorageValue(Storage.Kilmaresh.First.JamesfrancisTask) <= 50) + and player:getStorageValue(Storage.Kilmaresh.First.Mission) < 3 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + playerTopic[cid] = 15 + elseif player:getStorageValue(Storage.Kilmaresh.First.Mission) == 4 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + player:setStorageValue(Storage.Kilmaresh.First.Mission, 5) + playerTopic[cid] = 20 + end + npcHandler:addFocus(cid) + return true +end + +local function creatureSayCallback(cid, type, msg) +if not npcHandler:isFocused(cid) then + return false +end +npcHandler.topic[cid] = playerTopic[cid] +local player = Player(cid) + +if msgcontains(msg, "daughter") and player:getStorageValue(Storage.TheSecretLibrary.Peacock) == 1 then + npcHandler:say({"I always feared that I lost her. And yet, all those years, I still had a gleam of hope. I'm devastated to learn about her fate - but at least I have certainty now. Thank you for telling me."}, cid) + player:setStorageValue(Storage.TheSecretLibrary.Peacock, 2) + npcHandler.topic[cid] = 1 + playerTopic[cid] = 1 +end + + + +return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/galuna.lua b/data/npc/scripts/galuna.lua new file mode 100644 index 00000000000..18f3e6f9038 --- /dev/null +++ b/data/npc/scripts/galuna.lua @@ -0,0 +1,25 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Bows, crossbows and ammunition on special sale today.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "Oh, please come in, |PLAYERNAME|. What do you need? Distance weapons? I sell lots of them.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gamel.lua b/data/npc/scripts/gamel.lua new file mode 100644 index 00000000000..50437901cf2 --- /dev/null +++ b/data/npc/scripts/gamel.lua @@ -0,0 +1,67 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Pssst!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local function greetCallback(cid) + local player = Player(cid) + + if player:getStorageValue(Storage.SecretService.AVINMission01) == 1 and player:getItemCount(14326) > 0 then + player:setStorageValue(Storage.SecretService.AVINMission01, 2) + npcHandler:say("I don't like the way you look. Help me boys!", cid) + for i = 1, 2 do + Game.createMonster("Bandit", Npc():getPosition()) + end + npcHandler.topic[cid] = 0 + else + npcHandler:setMessage(MESSAGE_GREET, "Pssst! Be silent. Do you wish to {buy} something?") + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, "letter") then + if player:getStorageValue(Storage.SecretService.AVINMission01) == 2 then + npcHandler:say("You have a letter for me?", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + if player:removeItem(14326, 1) then + player:setStorageValue(Storage.SecretService.AVINMission01, 3) + npcHandler:say("Oh well. I guess I am still on the hook. Tell your 'uncle' I will proceed as he suggested.", cid) + else + npcHandler:say("You don't have any letter!", cid) + end + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, "Bye. Tell others about... my little shop here.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Bye. Tell others about... my little shop here.") +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gamon.lua b/data/npc/scripts/gamon.lua new file mode 100644 index 00000000000..9eecdefac91 --- /dev/null +++ b/data/npc/scripts/gamon.lua @@ -0,0 +1,40 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Any time\'s a good time to buy some furniture!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Wooden Stake +local stakeKeyword = keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'Making a stake from a chair? Are you insane??! I won\'t waste my chairs on you for free! You will have to pay for it, but since I consider your plan a blasphemy, it will cost 5000 gold pieces. Okay?'}, + function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) ~= -1 end + ) + + stakeKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Argh... my heart aches! Alright... a promise is a promise. Here - take this wooden stake, and now get lost.', ungreet = true}, + function(player) return player:getMoney() + player:getBankBalance() >= 5000 end, + function(player) player:removeMoneyNpc(5000) player:addItem(5941, 1) end + ) + + stakeKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'You can\'t even pay for that.', reset = true}) + stakeKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Phew. No chair-killing.', reset = true}) + +-- Others +npcHandler:setMessage(MESSAGE_GREET, 'Nice to meet you, Mister |PLAYERNAME|! Looking for furniture? You\'ve come to the right place!') +npcHandler:setMessage(MESSAGE_FAREWELL, 'You\'ll come back. They all do.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye.') +npcHandler:setMessage(MESSAGE_SENDTRADE, 'Have a look. Most furniture comes in handy kits. Just use them in your house to assemble the furniture. Do you want to see only a certain type of furniture?') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/garamond.lua b/data/npc/scripts/garamond.lua new file mode 100644 index 00000000000..0307d0d0c69 --- /dev/null +++ b/data/npc/scripts/garamond.lua @@ -0,0 +1,451 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- spells for druid and sorcerer +keywordHandler:addSpellKeyword({"findperson"}, + { + npcHandler = npcHandler, + spellName = "Find Person", + price = 0, + level = 8, + vocation = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID + } + } +) +keywordHandler:addSpellKeyword({"apprenticesstrike"}, + { + npcHandler = npcHandler, + spellName = "Apprentice's Strike", + price = 0, + level = 8, + vocation = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID + } + } +) +keywordHandler:addSpellKeyword({"lighthealing"}, + { + npcHandler = npcHandler, + spellName = "Light Healing", + price = 0, + level = 8, + vocation = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID + } + } +) +keywordHandler:addSpellKeyword({"light"}, + { + npcHandler = npcHandler, + spellName = "Light", + price = 0, + level = 8, + vocation = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID + } + } +) +keywordHandler:addSpellKeyword({"magicrope"}, + { + npcHandler = npcHandler, + spellName = "Magic Rope", + price = 0, + level = 9, + vocation = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID + } + } +) +keywordHandler:addSpellKeyword({"curepoison"}, + { + npcHandler = npcHandler, + spellName = "Cure Poison", + price = 0, + level = 10, + vocation = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID + } + } +) +keywordHandler:addSpellKeyword({"energystrike"}, + { + npcHandler = npcHandler, + spellName = "Energy Strike", + price = 0, + level = 12, + vocation = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID + } + } +) +keywordHandler:addSpellKeyword({"levitate"}, + { + npcHandler = npcHandler, + spellName = "Levitate", + price = 0, + level = 12, + vocation = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID + } + } +) +keywordHandler:addSpellKeyword({"greatlight"}, + { + npcHandler = npcHandler, + spellName = "Great Light", + price = 0, + level = 13, + vocation = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID + } + } +) +keywordHandler:addSpellKeyword({"terrastrike"}, + { + npcHandler = npcHandler, + spellName = "Terra Strike", + price = 0, + level = 13, + vocation = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID + } + } +) +keywordHandler:addSpellKeyword({"haste"}, + { + npcHandler = npcHandler, + spellName = "Haste", + price = 0, + level = 14, + vocation = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID + } + } +) +keywordHandler:addSpellKeyword({"flamestrike"}, + { + npcHandler = npcHandler, + spellName = "Flame Strike", + price = 0, + level = 14, + vocation = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID + } + } +) +keywordHandler:addSpellKeyword({"icestrike"}, + { + npcHandler = npcHandler, + spellName = "Ice Strike", + price = 0, + level = 15, + vocation = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID + } + } +) +keywordHandler:addSpellKeyword({"poisonfield"}, + { + npcHandler = npcHandler, + spellName = "Poison Field", + price = 0, + level = 14, + vocation = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID + } + } +) +keywordHandler:addSpellKeyword({"firefield"}, + { + npcHandler = npcHandler, + spellName = "Fire Field", + price = 0, + level = 15, + vocation = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID + } + } +) +keywordHandler:addSpellKeyword({"lightmagicmissile"}, + { + npcHandler = npcHandler, + spellName = "Light Magic Missile", + price = 0, + level = 15, + vocation = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID + } + } +) +keywordHandler:addSpellKeyword({"energyfield"}, + { + npcHandler = npcHandler, + spellName = "Energy Field", + price = 0, + level = 18, + vocation = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID + } + } +) +-- spells for sorcerer +keywordHandler:addSpellKeyword({"deathstrike"}, + { + npcHandler = npcHandler, + spellName = "Death Strike", + price = 0, + level = 16, + vocation = VOCATION.CLIENT_ID.SORCERER + } +) +keywordHandler:addSpellKeyword({"firewave"}, + { + npcHandler = npcHandler, + spellName = "Fire Wave", + price = 0, + level = 18, + vocation = VOCATION.CLIENT_ID.SORCERER + } +) +-- spells for druid +keywordHandler:addSpellKeyword({"icewave"}, + { + npcHandler = npcHandler, + spellName = "Ice Wave", + price = 0, + level = 18, + vocation = VOCATION.CLIENT_ID.DRUID + } +) +keywordHandler:addSpellKeyword({"physicalstrike"}, + { + npcHandler = npcHandler, + spellName = "Physical Strike", + price = 0, + level = 16, + vocation = VOCATION.CLIENT_ID.DRUID + } +) +keywordHandler:addSpellKeyword({"healfriend"}, + { + npcHandler = npcHandler, + spellName = "Heal Friend", + price = 0, + level = 18, + vocation = VOCATION.CLIENT_ID.DRUID + } +) + +keywordHandler:addKeyword({"healing spells"}, StdModule.say, + { + npcHandler = npcHandler, + text = "In this category I have '{Lighthealing}', '{Healfriend}', and '{Curepoison}'." + } +) +keywordHandler:addKeyword({"support spells"}, StdModule.say, + { + npcHandler = npcHandler, + text = "In this category I have '{Findperson}', '{Magicrope}', '{Levitate}', '{Light}', \z + '{Greatlight}', '{Haste}', '{Poisonfield}', '{Firefield}', '{Lightmagicmissile}' and '{Energyfield}'." + } +) +keywordHandler:addKeyword({"attack spells"}, StdModule.say, + { + npcHandler = npcHandler, + text = "In this category I have '{Deathstrike}', '{Firewave}', '{Apprenticesstrike}', '{Energystrike}', \z + '{Terrastrike}', '{Flamestrike}', '{Icestrike}', '{Physicalstrike}', '{Icewave}'." + } +) +keywordHandler:addKeyword({"spells"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I can teach you {healing spells}, {support spells} and {attack spells}. \z + What kind of spell do you wish to learn?" + } +) + +keywordHandler:addKeyword({"name"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I am Garamond Starstream." + } +) +keywordHandler:addKeyword({"job"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Did you not listen? I am the teacher of druid and sorcerer spells for level 8 to 18. \z + I teach young adventurers spells they can use once they have the proper vocation - druid or sorcerer." + } +) +keywordHandler:addKeyword({"rookgaard"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I have an old friend there. Haven't heard from him in a while." + } +) +keywordHandler:addKeyword({"dawnport"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Oh, it's not too bad here, believe me. At least I always get young and enthusiast disciples! \z + Though I must confess I miss the vastness of the Tibian plains. " + } +) +keywordHandler:addKeyword({"inigo"}, StdModule.say, + { + npcHandler = npcHandler, + text = "A kind old hunter. He loves to see young life around, taking on the ways and lays of the land. \z + If you have any question, ask Inigo for help." + } +) +keywordHandler:addKeyword({"coltrayne"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Roughened and toughened by life's tragedies. A good man, but somber." + } +) +keywordHandler:addKeyword({"garamond"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Yes, child. If you wish to learn a spell, tell me." + } +) +keywordHandler:addKeyword({"hamish"}, StdModule.say, + { + npcHandler = npcHandler, + text = "A very headstrong young man, though I appreciate his devotion to the craft of potion-making. \z + No respect for senior authority or age at all! Except maybe for a little soft spot for Mr Morris." + } +) +keywordHandler:addKeyword({"mr morris"}, StdModule.say, + { + npcHandler = npcHandler, + text = "A strange young man. He seems driven, to my mind. By what force, I do not know. \z + I take it the world needs adventurers such as him." + } +) +keywordHandler:addKeyword({"plunderpurse"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Redeeming one's soul by becoming a clerk? Not very likely. Once a pirate, always a pirate. \z + But he's a charming old rogue." + } +) +keywordHandler:addKeyword({"richard"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Not a half bad cook, truly. Must have been that squirrel diet, it seems to have lead him to \z + discover a new cuisine - everything to forget the bad taste of squirrels, he said." + } +) +keywordHandler:addKeyword({"ser tybald"}, StdModule.say, + { + npcHandler = npcHandler, + text = "He is proficient in the martial arts. A very skilled teacher of spells for knights and paladins. \z + If that is your vocation, you should talk to Ser Tybald." + } +) +keywordHandler:addKeyword({"wentworth"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Ah, yes. Travelled with Plunderpurse a lot as I recall. Captain Plunderpurse, then. \z + Got his head full of numbers and statistics, that boy." + } +) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "magic") then + npcHandler:say( + { + "Spells are very useful in combat - not only for mages, though of course we particularly \z + rely on them for much of our damage output. ...", + "There's a broad variety of what spells can do, as you will see as you progress further. \z + The next spells you can buy with level 8 and on. ...", + "Some attack spells can be directed at a single target while others affect an area, having \z + an effect either over time or instantaneous. Even other spells protect you, or can be used to create runes. ...", + "Each vocation has its own individual spells that none of the other vocations can use. \z + You can only learn spells at a spell trainer of your vocation. ...", + "The spells here on Dawnport are for trying out only, and you will forget them once \z + you choose your definite vocation and leave for the Mainland. ...", + "There, you can go to a spell teacher in a city to permanently learn a spell." + }, + cid) + elseif msgcontains(msg, "mainland") then + npcHandler:say( + { + "The Mainland offers many more adventures, dangers and quests than this small isle, \z + and also has spell teachers where you can permanently learn a spell for your vocation. ...", + "Once you reach level 8 you may choose your definite vocation and leave for Main. Go to a city \z + and seek out the spell trainer of your vocation to learn a spell. And make sure you have enough gold! ...", + "The art of spell teaching is complex and dangerous, and we will only impart our valuable \z + knowledge of a spell to a novice if they can pay the price." + }, + cid) + elseif msgcontains(msg, "tibian") then + npcHandler:say( + { + "Ah, the beauty of our world! It is vast and extraordinarily diverse. Strange islands, beautiful cities \z + and fierce monsters that roam the wildernesses. Mysteries, adventures, danger around every corner. ...", + "Once you have reached level 8, you are ready to choose a vocation and go to the Tibian Mainland." + }, + cid) + elseif msgcontains(msg, "vocation") then + npcHandler:say( + { + "Your choice of vocation will determine your life in Tibia, and the skills and fighting techniques you may use. ...", + "There are four vocation: knight, druid, paladin and sorcerer. If you want to know more about them, \z + talk to Oressa in the temple. ...", + "I myself teach try-out spells for both the magical classes, \z + whereas Tybald in the next room specialises in knight and paladin spells." + }, + cid) + elseif msgcontains(msg, "oressa") then + npcHandler:say( + { + "A very intelligent girl. Prefers to listen to wild animals' noises instead of humans', \z + which is quite understandable when you think about it. ...", + "However, she's also a very apt healer and can give you advice on your choice of vocation." + }, + cid) + end +end + +npcHandler:setMessage(MESSAGE_GREET, "Welcome, child. Have you come to learn about {magic}? \z + Then you are in the right place. I can teach you many useful {spells}.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gareth.lua b/data/npc/scripts/gareth.lua new file mode 100644 index 00000000000..d633c38d8f7 --- /dev/null +++ b/data/npc/scripts/gareth.lua @@ -0,0 +1,168 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local playerTopic = {} +local function greetCallback(cid) + + local player = Player(cid) + + if player:getStorageValue(Storage.CultsOfTibia.MotA.Mission) == 1 then + npcHandler:setMessage(MESSAGE_GREET, "The Druid of Crunor has sent you? He seems to know that this new museum shines like a diamond. Enjoy your stay! If you like to {support} this place, talk to me.") + playerTopic[cid] = 1 + elseif player:getStorageValue(Storage.CultsOfTibia.MotA.Mission) > 1 and player:getStorageValue(Storage.CultsOfTibia.MotA.Mission) < 14 then + npcHandler:setMessage(MESSAGE_GREET, "How is your {mission} going?") + playerTopic[cid] = 1 + elseif player:getStorageValue(Storage.CultsOfTibia.MotA.Mission) == 14 then + npcHandler:setMessage(MESSAGE_GREET, "You again? How could you flee from the last floor. The cultists should have 'dealt' with you! That beats me. You have to leave this place right now. There's nothing more to say.") + playerTopic[cid] = 0 + end + npcHandler:addFocus(cid) + return true +end + + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + npcHandler.topic[cid] = playerTopic[cid] + local player = Player(cid) + local valor = 10000 + + -- Começou a quest +if player:getStorageValue(Storage.CultsOfTibia.MotA.Mission) < 2 then + if msgcontains(msg, "support") and npcHandler.topic[cid] == 1 then + npcHandler:say({"If you like to, you can pay some gold to become a patron of the arts for this wonderful museum. The price is 10,000 gold. Your personal gain will be priceless. Do you want to pay?"}, cid) + npcHandler.topic[cid] = 2 + playerTopic[cid] = 2 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 2 then + if (player:getMoney() + player:getBankBalance()) >= valor then + npcHandler:say({"This is a very wise decision. You won't regret it. Congratulations! As your first task I like you to investigate the crime scene of a theft wich occurred last night. ...", + "A very varuable artefact has been stolen. I open the door for you. You can find the room on the same floor as we are right now."}, cid) + npcHandler.topic[cid] = 3 + playerTopic[cid] = 3 + player:removeMoneyNpc(valor) + player:addItem(28995, 1) + player:setStorageValue(Storage.CultsOfTibia.MotA.Mission, 2) + player:setStorageValue(Storage.CultsOfTibia.MotA.AccessDoorInvestigation, 1) + if player:getStorageValue(Storage.CultsOfTibia.Questline) < 1 then + player:setStorageValue(Storage.CultsOfTibia.Questline, 1) + end + else + npcHandler:say({"You don't have enough money."}, cid) + npcHandler.topic[cid] = 1 + playerTopic[cid] = 1 + end + end + + -- Reportando sobre o document + elseif msgcontains(msg, "mission") and player:getStorageValue(Storage.CultsOfTibia.MotA.Mission) == 3 then + npcHandler:say({"They want us to buy the picture back. Unfortunately this artefact is so important that I don't see an alternative. Please got to Iwar in Kazordoon and pay the money."}, cid) + player:setStorageValue(Storage.CultsOfTibia.MotA.Mission, 4) + npcHandler.topic[cid] = 1 + playerTopic[cid] = 1 + + -- Depois de ter pago o Iwar + elseif msgcontains(msg, "mission") and player:getStorageValue(Storage.CultsOfTibia.MotA.Mission) == 5 then + npcHandler:say({"Nice! I'm really happy to have the picture back. First of all I have to check if everything's fine. Then I'll put it back on its place. For now, I'd like you to find out if some rumours about fake pictures in the MOTA are true. ...", + "Some say one of the small pictures in the entrance hall here is fake. For this reason you have to go to my friend {Angelo} and ask him to get a {magnifier} for the investigation.", + "Then do your job here in the museum and come back."}, cid) + player:setStorageValue(Storage.CultsOfTibia.MotA.Mission, 6) + npcHandler.topic[cid] = 1 + playerTopic[cid] = 1 + + + + -- Depois de ter visto a pintura falsa + elseif msgcontains(msg, "mission") and player:getStorageValue(Storage.CultsOfTibia.MotA.Mission) == 9 then + npcHandler:say({"So the rumours are true. How could this happen? I'll keep the picture at its place until we've got a replacement. Please fo to {Angelo} and ask him if he has a new artefact for our museum."}, cid) + player:setStorageValue(Storage.CultsOfTibia.MotA.Mission, 10) + npcHandler.topic[cid] = 1 + playerTopic[cid] = 1 + + elseif msgcontains(msg, "mission") and player:getStorageValue(Storage.CultsOfTibia.MotA.Mission) == 11 then + npcHandler:say({"You're back, nice. Angelo's team hasn't found an artefact yet? I thought the progress would be faster. Anyway thanks for you efforts. ...", + "I have no work for you right now. If you like to, you can have a look at the last floor. I open the door for you."}, cid) + player:setStorageValue(Storage.CultsOfTibia.MotA.Mission, 12) + player:setStorageValue(Storage.CultsOfTibia.MotA.AccessDoorGareth, 1) + npcHandler.topic[cid] = 1 + playerTopic[cid] = 1 + + --------------------------------------- FALHAS ---------------------------------------------------------- + -- Se ainda não tiver visto a pintura falsa + elseif msgcontains(msg, "mission") and player:getStorageValue(Storage.CultsOfTibia.MotA.Mission) == 8 then + npcHandler:say({"You didn't investigate the pictures yet. Do your job and then come back."}, cid) + end + + if msgcontains(msg, "extension") and player:getStorageValue(Storage.TheSecretLibrary.LiquidDeath) == 11 then + if player:getStorageValue(Storage.TheSecretLibrary.LiquidDeath) == 11 then + npcHandler:say({"It is planned to extend the MOTA. But this will take time, because our workers have faced a little problem."}, cid) + npcHandler.topic[cid] = 11 + playerTopic[cid] = 11 + end + elseif msgcontains(msg, "problem") and npcHandler.topic[cid] == 11 then + if npcHandler.topic[cid] == 11 then + npcHandler:say({"Well, the situation is this: We have explored a portal, I would say a very aggressive, capriciously and dangerous one. Through this gate monsters entered the construction site and attacked our workers. ...", + "With enormous effort they could have been dispersed. When my fellows tried to fill up the portal, it appeared again and again. So the only thing they could do was to stop working for the moment. Are you eventually interested in further investigations?"}, cid) + npcHandler.topic[cid] = 12 + playerTopic[cid] = 12 + end + + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 12 then + if npcHandler.topic[cid] == 12 then + npcHandler:say({"You are a true patron of the arts! I have opened the construction site for you. Start your work right now!"}, cid) + player:setStorageValue(Storage.TheSecretLibrary.Mota, 1) + player:setStorageValue(Storage.TheSecretLibrary.LiquidDeath, 12) + npcHandler.topic[cid] = 13 + playerTopic[cid] = 13 + end + end + + if msgcontains(msg, "bone") and player:getStorageValue(Storage.TheSecretLibrary.Mota) == 2 then + npcHandler:say({"Hmm, interesting. Several years ago I have read some books dealing with strange locking mechanisms. I think what you have found here is a bone lever of category 3. ...", + "Normally this is not used because it is not secure. The production failed and the lever can always be activated as follows: back, back, up, right, left. Just have a try, it should work."}, cid) + player:setStorageValue(Storage.TheSecretLibrary.Mota, 3) + npcHandler.topic[cid] = 14 + playerTopic[cid] = 14 + end + + if msgcontains(msg, "extension") and player:getStorageValue(Storage.TheSecretLibrary.Mota) == 11 then + npcHandler:say({"You have found an inscription I would like to translate for you. The tibianus cipher was used: ...", + "Those who are accorded the honour to visit this exclusive place will smash their blindness and face the truth. ...", + "Astonishingly, Dedoras from Cormaya has recently asked me for these kinds of inscriptions. For sure he is able to bring light into the darkness. You should visit him. "}, cid) + player:setStorageValue(Storage.TheSecretLibrary.Mota, 12) + player:setStorageValue(Storage.TheSecretLibrary.TheLament, 1) + npcHandler.topic[cid] = 15 + playerTopic[cid] = 15 + end + + + + return true +end + + + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gate_guardian.lua b/data/npc/scripts/gate_guardian.lua new file mode 100644 index 00000000000..0693cb82bfc --- /dev/null +++ b/data/npc/scripts/gate_guardian.lua @@ -0,0 +1,43 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "mission") or msgcontains(msg, "pass") then + if player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 13 then + npcHandler:say("You want entranzzze to zzze zzzity?", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Mh, zzzezzze paperzzz zzzeem legit, I have orderzzz to let you pazzz. Zzzo be it.", cid) + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 22) + player:setStorageValue(Storage.WrathoftheEmperor.Mission05, 2) --Questlog, Wrath of the Emperor "Mission 05: New in Town" + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(Position(33114, 31197, 7), false) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gederas.lua b/data/npc/scripts/gederas.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/gederas.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gelagos.lua b/data/npc/scripts/gelagos.lua new file mode 100644 index 00000000000..6d47a012eda --- /dev/null +++ b/data/npc/scripts/gelagos.lua @@ -0,0 +1,28 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "Barbarians are stupid."}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "Bronbronbronbronbron. Bronnnn!"}) +keywordHandler:addKeyword({'outfit'}, StdModule.say, {npcHandler = npcHandler, text = "Can I have free outfits?"}) +keywordHandler:addKeyword({'gelagos'}, StdModule.say, {npcHandler = npcHandler, text = "That's me."}) +keywordHandler:addKeyword({'brother'}, StdModule.say, {npcHandler = npcHandler, text = "Ajax is even more stupid."}) +keywordHandler:addKeyword({'savage'}, StdModule.say, {npcHandler = npcHandler, text = "You are as stupid as Bron."}) +keywordHandler:addKeyword({'cyclops'}, StdModule.say, {npcHandler = npcHandler, text = "Any cyclops is smarter than Bron."}) + +npcHandler:setMessage(MESSAGE_GREET, "Hehehe.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Hope you die and lose it.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gelidrazahs_thirst.lua b/data/npc/scripts/gelidrazahs_thirst.lua new file mode 100644 index 00000000000..3065ccf6a12 --- /dev/null +++ b/data/npc/scripts/gelidrazahs_thirst.lua @@ -0,0 +1,55 @@ +local keywordHandler = KeywordHandler:new() +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, "yes") and npcHandler.topic[cid] == 0 then + npcHandler:say({ + "There are three questions. First: What is the name of the princess who fell in love with a Thaian nobleman during the regency of pharaoh Uthemath? Second: Who is the author of the book ,The Language of the Wolves'? ...", + "Third: Which ancient Tibian race reportedly travelled the sky in cloud ships? Can you answer these questions?" + }, cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 1 then + npcHandler:say("So I ask you: What is the name of the princess who fell in love with a Thaian nobleman during the regency of pharaoh Uthemath?", cid) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, "Tahmehe") and npcHandler.topic[cid] == 2 then + npcHandler:say("That's right. Listen to the second question: Who is the author of the book ,The Language of the Wolves'?", cid) + npcHandler.topic[cid] = 3 + elseif msgcontains(msg, "Ishara") and npcHandler.topic[cid] == 3 then + npcHandler:say("That's right. Listen to the third question: Which ancient Tibian race reportedly travelled the sky in cloud ships?", cid) + npcHandler.topic[cid] = 4 + elseif msgcontains(msg, "Svir") and npcHandler.topic[cid] == 4 then + npcHandler:say("That is correct. You satisfactorily answered all questions. You may pass and enter Gelidrazah's lair.", cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.FirstDragon.GelidrazahAccess, 1) + else + npcHandler:say('I don\'t know what you are talking about.', cid) + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "Have you come to answer Gelidrazah's questions?") +npcHandler:setMessage(MESSAGE_FAREWELL, "See you, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "See you, |PLAYERNAME|.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/george_the_boyscout.lua b/data/npc/scripts/george_the_boyscout.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/george_the_boyscout.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gerimor.lua b/data/npc/scripts/gerimor.lua new file mode 100644 index 00000000000..d0a3510ce42 --- /dev/null +++ b/data/npc/scripts/gerimor.lua @@ -0,0 +1,539 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + local player = Player(cid) + if player then + npcHandler:setMessage(MESSAGE_GREET, "Greeting, |PLAYERNAME|! I welcome you to this sacred {place}. \z + If you are interested in {missions} just ask.") + end + npcHandler:addFocus(cid) + return true +end + +-- Keywords +keywordHandler:addKeyword({"place"}, StdModule.say, + { + npcHandler = npcHandler, + text = "This place is a sanctuary of Crunor and provides me with a opportunity of spiritual contemplation." + } +) + +keywordHandler:addKeyword({"me"}, StdModule.say, + { + npcHandler = npcHandler, + text = { + "I'm a member of a circle of persons, that joined wisdom and resources for a common purpose. \z + Let's say, we have an eye on the greater picture in the matters of our world. ...", + "We are watching and evaluating what is happening in our world. \z + Trying to avert the worst and offering a helping hand where we deem it needed. ...", + "We usually avoid to interfere directly in the affairs of the world and vain politics are not our concern at all." + } + } +) + +keywordHandler:addKeyword({"circle"}, StdModule.say, + { + npcHandler = npcHandler, + text = "We focus our interest on this we see as threatening for live and the laws of nature itself." + } +) + +keywordHandler:addKeyword({"persons"}, StdModule.say, + { + npcHandler = npcHandler, + text = { + "Well, while I focus more on the matters of life, some of my peers have different approaches \z + and emphasize other aspects of the world more in their observations. ...", + "Regardless we share a common goal of balance and harmony." + } + } +) + +keywordHandler:addKeyword({"approaches"}, StdModule.say, + { + npcHandler = npcHandler, + text = "We might not be many but we are diverse. \z + Our rather informal order came together in the dawn of time, when the wars of the gods ravaged the world." + } +) + +keywordHandler:addKeyword({"dawn"}, StdModule.say, + { + npcHandler = npcHandler, + text = { + "Even we know the individual that was somewhat of our funder, only as the wise man. ...", + "He was the first to bring bright and dedicated minds together, \z + to bring at least a little order and guidance into troubled and chaotic times. ...", + "The order predates mankind and never bothered to give itself a name. \z + Such assumptions of pretence and vanity have no place in our mindset." + } + } +) + +keywordHandler:addKeyword({"guidance"}, StdModule.say, + { + npcHandler = npcHandler, + text = { + "Most times we are silent watchers and keeper of knowledge that share what they have learned with each other. \z + We are more concerned about knowledge and wisdom and power means little to us. ...", + "To solve problems we usually try to convince the right people to do the right thing. \z + We usually even lack the means for a more direct interference." + } + } +) + +keywordHandler:addKeyword({"direct"}, StdModule.say, + { + npcHandler = npcHandler, + text = { + "Sometimes it's necessary to do something about a situation that became threatening to the world itself. ...", + "It is gladly a rare occurrence and usually it is sufficient to somewhat offer a guiding hand to \z + avert a course that would lead to more dire consequences. Nonetheless sometimes we have to interfere." + } + } +) + +keywordHandler:addKeyword({"interfere"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Interference comes in different forms. \z + In this particular case there is sadly little time for subtlety and a more direct approach is necessary." + } +) + +keywordHandler:addKeyword({"feyrist"}, StdModule.say, + { + npcHandler = npcHandler, + text = "The fae granted me permission to enter their hidden realm. \z + As a druid I'm in close touch with nature so I could gain their trust. \z + The nature spirits are inhabiting this peninsula for ages." + } +) + +keywordHandler:addKeyword({"fae"}, StdModule.say, + { + npcHandler = npcHandler, + text = { + "The fae vary greatly in size and appearance. \z + There are different kinds of fae like fauns, pixies, pookas, swan maidens, nymphs and boogies. \z + Those mystical creatures are wielding power in magic and elementals. ...", + "Most of them are rather reclusive and live peaceful lives in their secret realm. \z + Sometimes they are called the 'children of dreams' or 'the dream born' \z + because the fae are born from the mortals' dreams." + } + } +) + +keywordHandler:addKeyword({"fauns"}, StdModule.say, + { + npcHandler = npcHandler, + text = { + "Fauns are half-human, half-beast nature spirits inhabiting the woods and mountains of Feyrist. \z + They are a slightly roguish but cheerful folk, lovers of wine and dancing. ...", + "Fauns show a youthful and graceful aspect but they are also brave and fearless \z + when it comes to defend themselves. As Maelyrra told me, they emerge from mortals' \z + dreams about celebrations, music and dancing. ...", + "Lately, some fauns on Feyrist are tainted by the mysterious, sinister force that is \z + threatening Feyrist as well as the rest of Tibia." + } + } +) + +keywordHandler:addKeyword({"pixies"}, StdModule.say, + { + npcHandler = npcHandler, + text = { + "Pixies are small nature spirits and mythical creatures inhabiting the forests and plains of Feyrist. \z + They are generally benign, but at times, they may also display mischievous traits. ...", + "Like most of the fae, pixies love dancing and are often gathering in larger groups \z + to dance on secluded glades. Pixies love flowers, butterflies, shimmering beetles, \z + gems and other colourful things. ...", + "They also love the taste of honey, sweetened oat and ripe grapes. \z + As Maelyrra told me, pixies emerge from mortals' dreams about friends and family." + } + } +) + +keywordHandler:addKeyword({"pookas"}, StdModule.say, + { + npcHandler = npcHandler, + text = { + "Pookas are nature spirits in animal form, looking like big hares with a faintly glittering fur. \z + They are benign but mischievous, for sure with good reason regarded as the tricksters among the fae. ...", + "Pookas love to play pranks on others, snitching and hiding things or telling made-up stories. \z + They are capricious and fickle creatures. \z + Pookas emerge from mortals' dreams about gems, treasures and gold. ...", + "Lately, some pookas on Feyrist are tainted by a mysterious, sinister force that is \z + threatening Feyrist as well as the rest of Tibia." + } + } +) + +keywordHandler:addKeyword({"swan maidens"}, StdModule.say, + { + npcHandler = npcHandler, + text = { + "Swan maidens are fae who can shapeshift from human form to swan form. \z + The magical item allowing this transformation is a swan feather cloak, a garment with swan feathers attached. ...", + "Here on Feyrist it is always hard to tell whether a swan swimming on a lake \z + is an ordinary animal or a swan maiden in her bird shape. ...", + "They protect the wilds of their secret realm from every intruder and live in small \z + flocks along secluded lakeshores. As Maelyrra told me, swan maidens emerge from mortals' dreams about flying." + } + } +) + +keywordHandler:addKeyword({"nymphs"}, StdModule.say, + { + npcHandler = npcHandler, + text = { + "Nymphs are female nature spirits and usually take the form of beautiful, \z + young maidens who love to dance and sing. They dwell in the hills and forests of Feyrist, \z + often near lakes and streams and they can't die of old age nor illness. ...", + "They have a special, strong bond to the plants and animals of their domain and are very \z + protective of Feyrist's flora and fauna. As Maelyrra told me, nymphs emerge from mortals' dreams about love." + } + } +) + +keywordHandler:addKeyword({"boogies"}, StdModule.say, + { + npcHandler = npcHandler, + text = { + "Boogies are a rather twisted kind of fae. Other than pixies, nymphs or fauns they favour \z + underground caves and tunnels over forests or lush meadows. ...", + "Only at night, they are roaming the surface, chasing other fae and visitors to Feyrist alike. \z + They were once clumsy yet peaceful fae, but they are now twisted and tainted by a mysterious, sinister force." + } + } +) + +keywordHandler:addKeyword({"maelyrra"}, StdModule.say, + { + npcHandler = npcHandler, + text = { + "She's the queen of a fae court. You can find her on a glade in the deep forest. \z + It was queen Maelyrra who granted me permission to stay here in Feyrist. ...", + "I promised to inform her about anything I find out about the abominable force that threatens this world." + } + } +) + +keywordHandler:addKeyword({"fae court"}, StdModule.say, + { + npcHandler = npcHandler, + text = { + "The fae vary greatly in size and appearance. \z + There are different kinds of fae like fauns, pixies, pookas, swan maidens, nymphs and boogies. \z + Those mystical creatures are wielding power in magic and elementals. ...", + "Most of them are rather reclusive and live peaceful lives in their secret realm. \z + Sometimes they are called the ,children of dreams' or ,the dream born' \z + because the fae are born from the mortals' dreams." + } + } +) + +keywordHandler:addKeyword({"cults"}, StdModule.say, + { + npcHandler = npcHandler, + text = { + "It doesn't seem that the cults share a common theme or object of reverence but there has to \z + be some connection beyond being at the centre of culminations of disruptive power from beyond. ...", + "The connection is of second thought though. Connected or not, they further the death of our world. \z + That alone makes it imperative to dig those cults out and destroy their cores. ...", + "We won't be able to rout our each and any movement but if we manage to neutralize the worst, \z + we gain some time and deny the enemy much of its leverage on the future of our world." + } + } +) + +keywordHandler:addKeyword({"worst"}, StdModule.say, + { + npcHandler = npcHandler, + text = { + "We have located some of the worst culminations of otherworldly presence and our sources \z + returned information about them with different results of success. ...", + "Some information I can provide you will be rather sparse and much is left to speculation \z + but you should have at least some lead where to go and investigate." + } + } +) + +keywordHandler:addKeyword({"investigate"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Those cults have to be stopped by any means possible. \z + These are desperate times and they demand desperate actions." + } +) +keywordHandler:addKeyword({"actions"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Spare lives where you see it fit but the cults may not be allowed to exist and disrupt \z + the fabric of the world even more." + } +) +keywordHandler:addKeyword({"fabric"}, StdModule.say, + { + npcHandler = npcHandler, + text = "The weakened fabric of our reality still repels the unnatural intruder. The cults provide the \z + thing a hold and supply it with more power, even if we couldn't figure out yet, how this works at all." + } +) + +keywordHandler:addKeyword({"works"}, StdModule.say, + { + npcHandler = npcHandler, + text = { + "We haven't completely figured out what our enemy exactly is. \z + For one, this thing defies all laws of nature and comprehension, ...", + "that understanding it is either impossible or twist a mind in ways that are not meant to be. \z + Also the Yalahari who figured out way too much about the thing, became tainted and changed by this knowledge ...", + "And ultimately not only fell and became his, they also provided the thing with something of their own, \z + be it knowledge, understanding or even direction, purpose. ...", + "In some way their tainted knowledge brought the unthinkable into a resemblance of existence. ...", + "That is why we cant dabble too much in figuring this out and rather concentrate on our \z + fight to severe its ties to our world." + } + } +) + +keywordHandler:addKeyword({"ties"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I have several missions available that deal with servering the ties of the corrupting influence on our world." + } +) + +local config = { + missions = { + ["minotaurs"] = { + text = { + "This is an animal-like cult. Only minotaurs can be found there, \z + but no idea what there are expecting and what they are worshipping. ...", + "Maybe they are a bit different to the creatures you already know. Would you like to dinf out more for me?" + }, + completeText = { + "Then you got it. Thank you. Here is your reward." + }, + storage = Storage.CultsOfTibia.Minotaurs.Mission, + value = 5, + rewardExp = 25000, + + }, + ["prosperity"] = { + text = { + "The alleged incentive to follow this cult is infinite prosperity. \z + Therefore most of the worshippers are already very rich citizens of Tibia. ...", + "This cult is abandoned in the recently opened new museum in Thais. \z + This can be entered in the Thais exhibition. Would you like to have a look at this cult?" + }, + completeText = { + "Then you got it. Thank you. Here is your reward." + }, + storage = Storage.CultsOfTibia.MotA.Mission, + value = 14, + rewardExp = 50000, + }, + ["barkless"] = { + text = { + "However, recently they became more prominent as their leader seems to hava taken a turn for the worse. \z + Rumors of violent acts and disappearing people are linked to this cult. ...", + "Someone... Should look into that, don't you think?" + }, + completeText = { + "Then you got it. Thank you. Here is your reward." + }, + storage = Storage.CultsOfTibia.Barkless.Mission, + value = 6, + rewardExp = 50000, + }, + ["orcs"] = { + text = { + "Several Edron orcs have taken to a dangerous idol it seems. \z + It may not be too late to stop them if you act quickly. \z + A powerful cult of orcs with a broad following could prove unsurmountable in the end. ..." + }, + completeText = { + "Then you got it. Thank you. Here is your reward.", + "Are you prepared to investigate?" + }, + storage = Storage.CultsOfTibia.Orcs.Mission, + value = 2, + rewardExp = 25000, + }, + ["life"] = { + text = { + "Its worshippers wish for eternal, life free of pain and sorrow. \z + The entrance to this cult can be found in the dark pyramid. Would you life to investigate it for me?" + }, + completeText = { + "Then you got it. Thank you. Here is your reward." + }, + storage = Storage.CultsOfTibia.Life.Mission, + value = 9, + rewardExp = 50000, + + }, + ["misguided"] = { + text = { + "There's a camp of outlaws to the east of Thais. \z + Rumour has it that people are going missing but it's not linked to the bandits. ...", + "Lights have been seen at night in the abandoned ruin in the vicinity of the camp, \z + somewhere to the south-west. Brave enough to check it out?" + }, + completeText = { + "Then you got it. Thank you. Here is your reward." + }, + storage = Storage.CultsOfTibia.Misguided.Mission, + value = 4, + rewardExp = 50000, + }, + ["humans"] = { + text = { + "It's a forbidden and abandoned place but... There is an ancient temple of Zathroth beneath Carlin. \z + Some say it's not that abandoned anymore. ...", + "Voices, flickering lights in the dead of night, and even a strange gate like sphere wich leads to \z + who knows where. I can't really request this from you but... Someone should take a look, or not?" + }, + completeText = { + "Then you got it. Thank you. Here is your reward." + }, + storage = Storage.CultsOfTibia.Humans.Mission, + value = 2, + rewardExp = 25000, + } + } +} + +local storage = {} +local value = {} +local rewardExperience = {} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "missions") then + -- Final boss check + if player:getStorageValue(Storage.CultsOfTibia.FinalBoss.Mission) > 2 then + npcHandler:say("You have already fulfilled your job to my full satisfaction. \z + The cults are investigated and the final boss is eliminated. \z + I have nothing more for you to do. Fare you well!", cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.CultsOfTibia.Minotaurs.Mission) == 6 + and player:getStorageValue(Storage.CultsOfTibia.Life.Mission) == 10 + and player:getStorageValue(Storage.CultsOfTibia.MotA.Mission) == 15 + and player:getStorageValue(Storage.CultsOfTibia.Barkless.Mission) == 7 + and player:getStorageValue(Storage.CultsOfTibia.Misguided.Mission) == 5 + and player:getStorageValue(Storage.CultsOfTibia.Orcs.Mission) == 3 + and player:getStorageValue(Storage.CultsOfTibia.Humans.Mission) == 3 + and player:getStorageValue(Storage.CultsOfTibia.FinalBoss.Mission) < 2 then + npcHandler:say("It seems to me that you have done all the missions I gave you. \z + All the cults have been revealed and now you can kill their leader, the final boss, \z + to save the world from a possible catastrophe.", cid) + npcHandler.topic[cid] = 0 + if player:getStorageValue(Storage.CultsOfTibia.FinalBoss.Mission) < 1 then + player:setStorageValue(Storage.CultsOfTibia.FinalBoss.Mission, 1) + player:setStorageValue(Storage.CultsOfTibia.FinalBoss.AccessDoor, 1) + end + elseif player:getStorageValue(Storage.CultsOfTibia.FinalBoss.Mission) == 2 then + npcHandler:say("You did it! You put an end to the cults, and as a return, here's your reward.", cid) + npcHandler.topic[cid] = 9 + local item = "" + if player:getVocation():getClientId() == VOCATION.CLIENT_ID.SORCERER then + player:addItem(29426) + item = "reflecting crown" + end + if player:getVocation():getClientId() == VOCATION.CLIENT_ID.DRUID then + player:addItem(29423) + item = "leaf crown" + end + if player:getVocation():getClientId() == VOCATION.CLIENT_ID.PALADIN then + player:addItem(29425) + item = "incandescent crown" + end + if player:getVocation():getClientId() == VOCATION.CLIENT_ID.KNIGHT then + player:addItem(29424) + item = "iron crown" + end + player:addExperience(50000) + player:addItem(29422) + player:setStorageValue(Storage.CultsOfTibia.FinalBoss.Mission, 3) + player:sendTextMessage(MESSAGE_EXPERIENCE, "You gained 50000 experience points.") + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You gained a mystery box.") + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You gained a " .. item .. ".") + else + npcHandler:say("In wich of the following topics are you interested in? Cult of {Life}, \z + Cult of {Prosperity}, Cult of the {Minotaurs}, Cult of the {Barkless}, Cult of the {Misguided}, \z + Cult of {Orcs} or Cult of the {Humans}?", cid) + npcHandler.topic[cid] = 2 + end + -- General + elseif npcHandler.topic[cid] == 2 then + local missionsTable = config.missions[msg:lower()] + if missionsTable then + storage[cid] = missionsTable.storage + value[cid] = missionsTable.value + rewardExperience[cid] = missionsTable.rewardExp + if player:getStorageValue(storage[cid]) > 0 and player:getStorageValue(storage[cid]) == value[cid] then + npcHandler:say(missionsTable.completeText, cid) + player:setStorageValue(storage[cid], player:getStorageValue(storage[cid]) + 1) + player:addExperience(rewardExperience[cid]) + player:sendTextMessage(MESSAGE_EXPERIENCE, "You gained " .. rewardExperience[cid] .. " experience points.") + npcHandler.topic[cid] = 0 + + elseif player:getStorageValue(storage[cid]) > 0 and player:getStorageValue(storage[cid]) > value[cid] then + npcHandler:say({"You already done this mission."}, cid) + npcHandler.topic[cid] = 2 + else + npcHandler:say(missionsTable.text, cid) + npcHandler.topic[cid] = 3 + end + end + -- Accept mission + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 3 then + if player:getStorageValue(storage[cid]) < 1 then + npcHandler:say("Very nice! Come back if you have found what's going on in this cult.", cid) + player:setStorageValue(storage[cid], 1) + if player:getStorageValue(Storage.CultsOfTibia.Questline) < 1 then + player:setStorageValue(Storage.CultsOfTibia.Questline, 1) + end + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(storage[cid]) > 0 then + npcHandler:say("You have not finished your work yet. Come back when you're done.", cid) + npcHandler.topic[cid] = 2 + end + -- Recuse mission + elseif msgcontains(msg, "no") and npcHandler.topic[cid] == 3 then + npcHandler:say("What a pitty! You can come back, when ever you want, if you have changed your opinion.", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, "Farewell, |PLAYERNAME|.") + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gewen.lua b/data/npc/scripts/gewen.lua new file mode 100644 index 00000000000..cb8f437b465 --- /dev/null +++ b/data/npc/scripts/gewen.lua @@ -0,0 +1,76 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Nothing beats the feeling of flying with a carpet!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'ticket') then + if player:getStorageValue(Storage.WagonTicket) >= os.time() then + npcHandler:say('Your weekly ticket is still valid. Would be a waste of money to purchase a second one', cid) + return true + end + + npcHandler:say('Do you want to purchase a weekly ticket for the ore wagons? With it you can travel freely and swiftly through Kazordoon for one week. 250 gold only. Deal?', cid) + npcHandler.topic[cid] = 1 + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, 'yes') then + if not player:removeMoneyNpc(250) then + npcHandler:say('You don\'t have enough money.', cid) + return true + end + + player:setStorageValue(Storage.WagonTicket, os.time() + 7 * 24 * 60 * 60) + npcHandler:say('Here is your stamp. It can\'t be transferred to another person and will last one week from now. You\'ll get notified upon using an ore wagon when it isn\'t valid anymore.', cid) + elseif msgcontains(msg, 'no') then + npcHandler:say('No then.', cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +-- Travel +local function addTravelKeyword(keyword, text, cost, destination) + if keyword == 'farmine' then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Never heard about a place like this.'}, function(player) return player:getStorageValue(Storage.TheNewFrontier.Mission10) ~= 1 end) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a ride to ' .. text .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, text = 'Hold on!', cost = cost, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'You shouldn\'t miss the experience.', reset = true}) +end + +addTravelKeyword('farmine', 'Farmine', 60, Position(32983, 31539, 1)) +addTravelKeyword('darashia', 'Darashia on Darama', 40, Position(33270, 32441, 6)) +addTravelKeyword('svargrond', 'Svargrond', 60, Position(32253, 31097, 4)) +addTravelKeyword('femor hills', 'the Femor Hills', 60, Position(32536, 31837, 4)) +addTravelKeyword('edron', 'Edron', 40, Position(33193, 31784, 3)) +addTravelKeyword('hills', 'the Femor Hills', 60, Position(32536, 31837, 4)) +addTravelKeyword('issavi', 'Issavi', 100, Position(33957, 31515, 0)) + +npcHandler:setMessage(MESSAGE_GREET, "Greetings, traveller |PLAYERNAME|. Where do you want me to {fly} you? Or do you need a weekly ticket for the Kazordoon public lorry transport?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye!") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ghorza.lua b/data/npc/scripts/ghorza.lua new file mode 100644 index 00000000000..e88e935b7eb --- /dev/null +++ b/data/npc/scripts/ghorza.lua @@ -0,0 +1,20 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ghost_of_a_priest.lua b/data/npc/scripts/ghost_of_a_priest.lua new file mode 100644 index 00000000000..e40267510fb --- /dev/null +++ b/data/npc/scripts/ghost_of_a_priest.lua @@ -0,0 +1,86 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 10 then + if player:getPosition().z == 12 and player:getStorageValue(Storage.WrathoftheEmperor.GhostOfAPriest01) < 1 and npcHandler.topic[cid] ~= 1 then + npcHandler:say({ + "Although we are willing to hand this item to you, there is something you have to understand: There is no such thing as 'the' sceptre. ...", + "Those sceptres are created for special purposes each time anew. Therefore you will have to create one on your own. It will be your {mission} to find us three keepers and to get the three parts of the holy sceptre. ...", + "Then go to the holy altar and create a new one." + }, cid) + npcHandler.topic[cid] = 1 + elseif npcHandler.topic[cid] == 1 then + npcHandler:say({ + "Even though we are spirits, we can't create anything out of thin air. You will have to donate some precious metal which we can drain for energy and substance. ...", + "The equivalent of 5000 gold will do. Are you willing to make such a donation?" + }, cid) + npcHandler.topic[cid] = 2 + elseif player:getPosition().z == 13 and player:getStorageValue(Storage.WrathoftheEmperor.GhostOfAPriest02) < 1 then + npcHandler:say({ + "Even though we are spirits, we can't create anything out of thin air. You will have to donate some precious metal which we can drain for energy and substance. ...", + "The equivalent of 5000 gold will do. Are you willing to make such a donation?" + }, cid) + npcHandler.topic[cid] = 3 + elseif player:getPosition().z == 14 and player:getStorageValue(Storage.WrathoftheEmperor.GhostOfAPriest03) < 1 then + npcHandler:say({ + "Even though we are spirits, we can't create anything out of thin air. You will have to donate some precious metal which we can drain for energy and substance. ...", + "The equivalent of 5000 gold will do. Are you willing to make such a donation?" + }, cid) + npcHandler.topic[cid] = 4 + end + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 2 then + if player:getMoney() + player:getBankBalance() >= 5000 then + player:setStorageValue(Storage.WrathoftheEmperor.GhostOfAPriest01, 1) + player:removeMoneyNpc(5000) + player:addItem(12324, 1) + npcHandler:say("So be it! Here is my part of the sceptre. Combine it with the other parts on the altar of the Great Snake in the depths of this temple.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 3 then + if player:getMoney() + player:getBankBalance() >= 5000 then + player:setStorageValue(Storage.WrathoftheEmperor.GhostOfAPriest02, 1) + player:removeMoneyNpc(5000) + player:addItem(12325, 1) + npcHandler:say("So be it! Here is my part of the sceptre. Combine it with the other parts on the altar of the Great Snake in the depths of this temple.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 4 then + if player:getMoney() + player:getBankBalance() >= 5000 then + player:setStorageValue(Storage.WrathoftheEmperor.GhostOfAPriest03, 1) + player:removeMoneyNpc(5000) + player:addItem(12326, 1) + npcHandler:say("So be it! Here is my part of the sceptre. Combine it with the other parts on the altar of the Great Snake in the depths of this temple.", cid) + npcHandler.topic[cid] = 0 + end + end + elseif msgcontains(msg, "no") and npcHandler.topic[cid] then + npcHandler:say("No deal then.", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ghostly_wolf.lua b/data/npc/scripts/ghostly_wolf.lua new file mode 100644 index 00000000000..c2cfb46d424 --- /dev/null +++ b/data/npc/scripts/ghostly_wolf.lua @@ -0,0 +1,58 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "mission") then + if (player:getStorageValue(Storage.ThreatenedDreams.TroubledMission01) == 6) then + npcHandler:say({ + "I'm heartbroken, traveler. Some months ago, I was taking care of my three newborn whelps. They just opened their eyes and started exploring the wilderness as a hunter came by. ...", + "He shot me and took my three puppies with him. I have no idea where he brought them or whether they are still alive. This uncertainty harrows me and thus I'm unable to find peace. Will you help me?" + }, cid) + npcHandler.topic[cid] = 1 + elseif (player:getStorageValue(Storage.ThreatenedDreams.TroubledMission01) == 10) then + player:setStorageValue(Storage.ThreatenedDreams.TroubledMission01, 11) + npcHandler:say("I guess I will stick around for a time to watch over the grave. After this final watch I will find peace, I can feel this. Thank you, human being. You redeemed me.", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You are not on that mission.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, "yes") then + npcHandler:say({ + "I didn't dare hope for it! The man told something about selling my babies to the orcs so they could train them as war wolves. ...", + "I guess he mentioned Ulderek's Rock. Please search for them and - be they alive or not - return and tell me what happened to them." + }, cid) + player:setStorageValue(Storage.ThreatenedDreams.TroubledMission01, 7) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") then + npcHandler:say("Then not.", cid) + npcHandler.topic[cid] = 0 + end + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "You are speaking the language of animals? I'm surprised. But I'm not in the right mood for a chat.") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gladys.lua b/data/npc/scripts/gladys.lua new file mode 100644 index 00000000000..d0c68ddbca1 --- /dev/null +++ b/data/npc/scripts/gladys.lua @@ -0,0 +1,18 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnomad.lua b/data/npc/scripts/gnomad.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/gnomad.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnomailion.lua b/data/npc/scripts/gnomailion.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/gnomailion.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnomally.lua b/data/npc/scripts/gnomally.lua new file mode 100644 index 00000000000..1bd93696e91 --- /dev/null +++ b/data/npc/scripts/gnomally.lua @@ -0,0 +1,199 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local t = {} +local renown = {} + +local config = { + ['supply'] = {itemid = 18215, token = {type = 'minor', id = 18422, count = 2}}, + ['muck'] = {itemid = 18395, token = {type = 'minor', id = 18422, count = 8}}, + ['mission'] = {itemid = 18509, token = {type = 'minor', id = 18422, count = 10}}, + ['lamp'] = {itemid = 18388, token = {type = 'minor', id = 18422, count = 15}}, + ['backpack'] = {itemid = 18393, token = {type = 'minor', id = 18422, count = 15}}, + ['addition to the soil guardian outfit'] = {itemid = 18518, token = {type = 'minor', id = 18422, count = 70}}, + ['addition to the crystal warlord armor outfit'] = {itemid = 18521, token = {type = 'minor', id = 18422, count = 70}}, + ['gill gugel'] = {itemid = 18398, token = {type = 'major', id = 18423, count = 10}}, + ['gill coat'] = {itemid = 18399, token = {type = 'major', id = 18423, count = 10}}, + ['gill legs'] = {itemid = 18400, token = {type = 'major', id = 18423, count = 10}}, + ['spellbook'] = {itemid = 18401, token = {type = 'major', id = 18423, count = 10}}, + ['prismatic helmet'] = {itemid = 18403, token = {type = 'major', id = 18423, count = 10}}, + ['prismatic armor'] = {itemid = 18404, token = {type = 'major', id = 18423, count = 10}}, + ['prismatic legs'] = {itemid = 18405, token = {type = 'major', id = 18423, count = 10}}, + ['prismatic boots'] = {itemid = 18406, token = {type = 'major', id = 18423, count = 10}}, + ['prismatic shield'] = {itemid = 18410, token = {type = 'major', id = 18423, count = 10}}, + ['basic soil guardian outfit'] = {itemid = 18517, token = {type = 'major', id = 18423, count = 20}}, + ['basic crystal warlord outfit'] = {itemid = 18520, token = {type = 'major', id = 18423, count = 20}}, + ['iron loadstone'] = {itemid = 18447, token = {type = 'major', id = 18423, count = 20}}, + ['glow wine'] = {itemid = 18448, token = {type = 'major', id = 18423, count = 20}} +} + +local function getTable() + local itemsList = { + {name = "bell", id = 18343, buy = 50}, + {name = "gnomish crystal package", id = 18313, buy = 1000}, + {name = "gnomish extraction crystal", id = 18213, buy = 50}, + {name = "gnomish repair crystal", id = 18219, buy = 50}, + {name = "gnomish spore gatherer", id = 18328, buy = 50}, + {name = "little pig", id = 18339, buy = 150} + } + return itemsList +end + +local function setNewTradeTable(table) + local items, item = {} + for i = 1, #table do + item = table[i] + items[item.id] = {itemId = item.id, buyPrice = item.buy, sellPrice = item.sell, subType = 0, realName = item.name} + end + return items +end + +local function onBuy(cid, item, subType, amount, ignoreCap, inBackpacks) + local player = Player(cid) + local items = setNewTradeTable(getTable(player)) + if not ignoreCap and player:getFreeCapacity() < ItemType(items[item].itemId):getWeight(amount) then + return player:sendTextMessage(MESSAGE_FAILURE, 'You don\'t have enough cap.') + end + if not player:removeMoneyNpc(items[item].buyPrice * amount) then + selfSay("You don't have enough money.", cid) + else + player:addItem(items[item].itemId, amount) + return player:sendTextMessage(MESSAGE_TRADE, 'Bought '..amount..'x '..items[item].realName..' for '..items[item].buyPrice * amount..' gold coins.') + end + return true +end + +local function onSell(cid, item, subType, amount, ignoreCap, inBackpacks) + local player = Player(cid) + local items = setNewTradeTable(getTable(player)) + if items[item].sellPrice and player:removeItem(items[item].itemId, amount) then + player:addMoney(items[item].sellPrice * amount) + return player:sendTextMessage(MESSAGE_TRADE, 'Sold '..amount..'x '..items[item].realName..' for '..items[item].sellPrice * amount..' gold coins.') + else + selfSay("You don't have item to sell.", cid) + end + return true +end + +local function greetCallback(cid) + npcHandler:setMessage(MESSAGE_GREET, 'Oh, hello! I\'m the gnome-human relations assistant. I am here for you to trade your tokens for {equipment}, resupply you with mission {items} and talk to you about your {relations} to us gnomes! ...') + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, 'equipment') then + npcHandler:say({ + 'You can buy different equipment for minor or for major tokens. So, which is the equipment you are interested in, the one for {minor} or {major} tokens? ...', + 'By the way, if you want to have a look on the prismatic and gill items first, just head over to the depot and check the market.' + }, cid) + elseif msgcontains(msg, 'major') then + npcHandler:say({ + 'For ten major tokens, I can offer you a {gill gugel}, a {gill coat}, {gill legs}, a {spellbook} of vigilance, a {prismatic helmet}, a {prismatic armor}, {prismatic legs}, {prismatic boots} or a {prismatic shield} ...', + 'For twenty major tokens, I can offer you a {basic soil guardian outfit}, a {basic crystal warlord outfit}, an {iron loadstone} or a {glow wine}.' + }, cid) + elseif msgcontains(msg, 'minor') then + npcHandler:say({ + 'For two minor tokens, you can buy one gnomish {supply} package! For eight tokens, you can buy a {muck} remover! For ten tokens, you can buy a {mission} crystal. For fifteen tokens, you can buy a crystal {lamp} or a mushroom {backpack}. ...', + 'For seventy tokens, I can offer you a voucher for an {addition to the soil guardian outfit}, or a voucher for an {addition to the crystal warlord armor outfit}.' + }, cid) + elseif config[msg] then + local itemType = ItemType(config[msg].itemid) + npcHandler:say(string.format('Do you want to trade %s %s for %d %s tokens?', (itemType:getArticle() ~= "" and itemType:getArticle() or ""), itemType:getName(), config[msg].token.count, config[msg].token.type), cid) + npcHandler.topic[cid] = 1 + t[cid] = msg + elseif msgcontains(msg, 'relations') then + local player = Player(cid) + if player:getStorageValue(Storage.BigfootBurden.QuestLine) >= 25 then + npcHandler:say('Our relations improve with every mission you undertake on our behalf. Another way to improve your relations with us gnomes is to trade in minor crystal tokens. ...', cid) + npcHandler:say('Your renown amongst us gnomes is currently {' .. math.max(0, player:getStorageValue(Storage.BigfootBurden.Rank)) .. '}. Do you want to improve your standing by sacrificing tokens? One token will raise your renown by 5 points. ', cid) + npcHandler.topic[cid] = 2 + else + npcHandler:say('You are not even a recruit of the Bigfoots. Sorry I can\'t help you.', cid) + end + elseif npcHandler.topic[cid] == 3 then + local amount = getMoneyCount(msg) + if amount > 0 then + npcHandler:say('Do you really want to trade ' .. amount .. ' minor tokens for ' .. amount * 5 .. ' renown?', cid) + renown[cid] = amount + npcHandler.topic[cid] = 4 + end + elseif msgcontains(msg, 'items') then + npcHandler:say('Do you need to buy any mission items?', cid) + npcHandler.topic[cid] = 5 + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + local player, targetTable = Player(cid), config[t[cid]] + if player:getItemCount(targetTable.token.id) < targetTable.token.count then + npcHandler:say('Sorry, you don\'t have enough ' .. targetTable.token.type .. ' tokens with you.', cid) + npcHandler.topic[cid] = 0 + return true + end + + local item = Game.createItem(targetTable.itemid, 1) + local weight = 0 + weight = ItemType(item.itemid):getWeight(item:getCount()) + + if player:addItemEx(item) ~= RETURNVALUE_NOERROR then + if player:getFreeCapacity() < weight then + npcHandler:say('First make sure you have enough capacity to hold it.', cid) + else + npcHandler:say('First make sure you have enough space in your inventory.', cid) + end + npcHandler.topic[cid] = 0 + return true + end + + player:removeItem(targetTable.token.id, targetTable.token.count) + npcHandler:say('Here have one of our ' .. item:getPluralName() .. '.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say("How many tokens do you want to trade?", cid) + npcHandler.topic[cid] = 3 + elseif npcHandler.topic[cid] == 4 then + local player = Player(cid) + if player:removeItem(18422, renown[cid]) then + player:setStorageValue(Storage.BigfootBurden.Rank, math.max(0, player:getStorageValue(Storage.BigfootBurden.Rank)) + renown[cid] * 5) + player:checkGnomeRank() + npcHandler:say('As you wish! Your new renown is {' .. player:getStorageValue(Storage.BigfootBurden.Rank) .. '}.', cid) + else + npcHandler:say('You don\'t have these many tokens.', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 5 then + openShopWindow(cid, getTable(), onBuy, onSell) + npcHandler:say('Let us see if I have what you need.', cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'no') and isInArray({1, 3, 4, 5}, npcHandler.topic[cid]) then + npcHandler:say('As you like.', cid) + npcHandler.topic[cid] = 0 + end + return true +end + +local function onReleaseFocus(cid) + t[cid], renown[cid] = nil, nil +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnomargery.lua b/data/npc/scripts/gnomargery.lua new file mode 100644 index 00000000000..2a624c326f2 --- /dev/null +++ b/data/npc/scripts/gnomargery.lua @@ -0,0 +1,248 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) +local talkState = {} +local level = 80 + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, 'job') then + return npcHandler:say('I\'m the officer responsible for this area. I give out missions, accept mission reports and oversee our defences.', cid) + end + + if msgcontains(msg, 'gnome') then + return npcHandler:say('It\'s good to be a gnome for sure!', cid) + end + + if msgcontains(msg, 'area') then + return npcHandler:say({ + "On the levels outside, we encountered the first serious resistance of our true enemy. As evidenced by the unnatural heat in an area with little volcanic activity, there is 'something' strange going on here. ...", + "Even the lava pools we have found here are not actually lava, but rock that was molten pretty much recently without any reasonable connection to some natural heat source. And for all we can tell, the heat is growing, slowly but steadily. ...", + "This is the first time ever that we can witness our enemy at work. Here we can learn a lot about its operations. ...", + "How they work, and possibly how to stop them. But therefore expeditions into the depths are necessary. The areas around us are highly dangerous, and a lethal threat to us and the Spike as a whole. ... ", + "Our first object is to divert the forces of the enemy and weaken them as good as we can while gathering as much information as possible about them and their movements. Only highly skilled adventurers stand a chance to help us down here. ..." + }, cid) + end + + if msgcontains(msg, 'spike') then + return npcHandler:say('Now that\'s gnomish ingenuity given shape! Who but a gnome would come up with such a plan to defeat our enemies. ', cid) + end + + if msgcontains(msg, 'mission') then + if player:getLevel() < level then + npcHandler:say('Sorry, but no! Your expertise could be put to better use elsewhere. You are desperately needed in the upper levels of the Spike. Report there immediately. ', cid) + else + npcHandler:say('I can offer you several missions: to {deliver} parcels to our boys and girls in the battlefield, to get reports from our {undercover} gnomes, to do some {temperature} measuring and to {kill} some drillworms.', cid) + end + return + end + + if msgcontains(msg, 'report') then + talkState[cid] = 'report' + return npcHandler:say(' What mission do you want to report about: the {delivery} of parcels, the {undercover} reports, the {temperature} measuring or {kill} of drillworms?', cid) + end + + if talkState[cid] == 'report' then + if msgcontains(msg, 'delivery') then + if player:getStorageValue(SPIKE_LOWER_PARCEL_MAIN) == -1 then + npcHandler:say('You have not started that mission.', cid) + elseif player:getStorageValue(SPIKE_LOWER_PARCEL_MAIN) == 4 then + npcHandler:say('You have done well. Here, take your reward.', cid) + player:addFamePoint() + player:addExperience(3500, true) + player:setStorageValue(SPIKE_LOWER_PARCEL_MAIN, -1) + player:setStorageValue(SPIKE_LOWER_PARCEL_DAILY, 86400) + else + npcHandler:say('Gnowful! Deliver the four parcels to some of our far away outposts in the caverns.', cid) + end + elseif msgcontains(msg, 'undercover') then + if player:getStorageValue(SPIKE_LOWER_UNDERCOVER_MAIN) == -1 then + npcHandler:say('You have not started that mission.', cid) + elseif player:getStorageValue(SPIKE_LOWER_UNDERCOVER_MAIN) == 3 then + npcHandler:say('You have done well. Here, take your reward.', cid) + player:addFamePoint() + player:addExperience(3500, true) + player:setStorageValue(SPIKE_LOWER_UNDERCOVER_MAIN, -1) + player:setStorageValue(SPIKE_LOWER_UNDERCOVER_DAILY, 86400) + else + npcHandler:say('Gnowful! Get three reports from our undercover agents posing as monsters in the caves around us.', cid) + end + elseif msgcontains(msg, 'temperature') then + if player:getStorageValue(SPIKE_LOWER_LAVA_MAIN) == -1 then + npcHandler:say('You have not started that mission.', cid) + elseif player:getStorageValue(SPIKE_LOWER_LAVA_MAIN) == 1 then + npcHandler:say('You have done well. Here, take your reward.', cid) + player:addFamePoint() + player:addExperience(3500, true) + player:setStorageValue(SPIKE_LOWER_LAVA_MAIN, -1) + player:setStorageValue(SPIKE_LOWER_LAVA_DAILY, 86400) + else + npcHandler:say('Gnowful! Use the gnomish temperature measurement device to locate the hottest spot at the lava pools in the cave.', cid) + end + elseif msgcontains(msg, 'kill') then + if player:getStorageValue(SPIKE_LOWER_KILL_MAIN) == -1 then + npcHandler:say('You have not started that mission.', cid) + elseif player:getStorageValue(SPIKE_LOWER_KILL_MAIN) == 7 then + npcHandler:say('You have done well. Here, take your reward.', cid) + player:addFamePoint() + player:addExperience(3500, true) + player:setStorageValue(SPIKE_LOWER_KILL_MAIN, -1) + player:setStorageValue(SPIKE_LOWER_KILL_DAILY, 86400) + else + npcHandler:say('Gnowful! Just go out to the caves and kill at least seven drillworms.', cid) + end + else + npcHandler:say('That\'s not a valid mission name.', cid) + end + talkState[cid] = nil + return + end + + --[[/////////////////// + ////PARCEL DELIVERY//// + /////////////////////]] + if msgcontains(msg, 'deliver') then + if player:getStorageValue(SPIKE_LOWER_PARCEL_DAILY) >= os.time() then + return npcHandler:say('Sorry, you have to wait ' .. string.diff(player:getStorageValue(SPIKE_LOWER_PARCEL_DAILY)-os.time()) .. ' before this task gets available again.', cid) + end + + if player:getLevel() < level then + return npcHandler:say('Sorry, you are not on the required minimum level [' .. level ..'].', cid) + end + + if player:getStorageValue(SPIKE_LOWER_PARCEL_MAIN) == -1 then + npcHandler:say('We need someone to bring four parcels to some of our far away outposts in the caverns. If you are interested, I can give you some more {information} about it. Are you willing to accept this mission?', cid) + talkState[cid] = 'delivery' + else + npcHandler:say('You have already started that mission.', cid) + end + end + + if talkState[cid] == 'delivery' then + if msgcontains(msg, 'yes') then + player:addItem(21569, 4) + player:setStorageValue(SPIKE_LOWER_PARCEL_MAIN, 0) + npcHandler:say({'Gnometastic! Here are the parcels. Regrettably, the labels got lost during transport; but I guess those lonely gnomes won\'t mind as long as they get ANY parcel at all.','If you lose the parcels, you\'ll have to get new ones. Gnomux sells all the equipment that is required for our missions.'}, cid) + talkState[cid] = nil + elseif msgcontains(msg, 'no') then + npcHandler:say('Ok then.', cid) + talkState[cid] = nil + end + end + + --[[////////////// + ////UNDERCOVER//// + ////////////////]] + if msgcontains(msg, 'undercover') then + if player:getStorageValue(SPIKE_LOWER_UNDERCOVER_DAILY) >= os.time() then + return npcHandler:say('Sorry, you have to wait ' .. string.diff(player:getStorageValue(SPIKE_LOWER_UNDERCOVER_DAILY)-os.time()) .. ' before this task gets available again.', cid) + end + + if player:getLevel() < level then + return npcHandler:say('Sorry, you are not on the required minimum level [' .. level ..'].', cid) + end + + if player:getStorageValue(SPIKE_LOWER_UNDERCOVER_MAIN) == -1 then + npcHandler:say('Someone is needed to get three reports from our undercover agents posing as monsters in the caves around us. If you are interested, I can give you some more {information} about it. Are you willing to accept this mission?', cid) + talkState[cid] = 'undercover' + else + npcHandler:say('You have already started that mission.', cid) + end + end + + if talkState[cid] == 'undercover' then + if msgcontains(msg, 'yes') then + player:setStorageValue(SPIKE_LOWER_UNDERCOVER_MAIN, 0) + npcHandler:say('Gnometastic! Get three reports from our agents. You can find them anywhere in the caves around us. Just keep looking for monsters that behave strangely and give you a wink.', cid) + talkState[cid] = nil + elseif msgcontains(msg, 'no') then + npcHandler:say('Ok then.', cid) + talkState[cid] = nil + end + end + + --[[//////////////// + ////TEMPERATURE///// + //////////////////]] + if msgcontains(msg, 'temperature') then + if player:getStorageValue(SPIKE_LOWER_LAVA_DAILY) >= os.time() then + return npcHandler:say('Sorry, you have to wait ' .. string.diff(player:getStorageValue(SPIKE_LOWER_LAVA_DAILY)-os.time()) .. ' before this task gets available again.', cid) + end + + if player:getLevel() < level then + return npcHandler:say('Sorry, you are not on the required minimum level [' .. level ..'].', cid) + end + + if player:getStorageValue(SPIKE_LOWER_LAVA_MAIN) == -1 then + npcHandler:say('Your task would be to use a gnomish temperature measurement device - short GTMD - to locate the hottest spot at the lava pools in the caves. If you are interested, I can give you some more information about it. Are you willing to accept this mission?', cid) + talkState[cid] = 'temperature' + else + npcHandler:say('You have already started that mission.', cid) + end + end + + if talkState[cid] == 'temperature' then + if msgcontains(msg, 'yes') then + player:addItem(21556, 1) + player:setStorageValue(SPIKE_LOWER_LAVA_MAIN, 0) + npcHandler:say('Gnometastic! Find the hottest spot of the lava pools in the caves. If you lose the GTMD before you find the hot spot, you\'ll have to get yourself a new one. Gnomux sells all the equipment that is required for our missions.', cid) + talkState[cid] = nil + elseif msgcontains(msg, 'no') then + npcHandler:say('Ok then.', cid) + talkState[cid] = nil + end + end + + --[[///////// + ////KILL///// + ///////////]] + if msgcontains(msg, 'kill') then + if player:getStorageValue(SPIKE_LOWER_KILL_DAILY) >= os.time() then + return npcHandler:say('Sorry, you have to wait ' .. string.diff(player:getStorageValue(SPIKE_LOWER_KILL_DAILY)-os.time()) .. ' before this task gets available again.', cid) + end + + if player:getLevel() < level then + return npcHandler:say('Sorry, you are not on the required minimum level [' .. level ..'].', cid) + end + + if player:getStorageValue(SPIKE_LOWER_KILL_MAIN) == -1 then + npcHandler:say('This mission will require you to kill some drillworms for us. If you are interested, I can give you some more {information} about it. Are you willing to accept this mission?', cid) + talkState[cid] = 'kill' + else + npcHandler:say('You have already started that mission.', cid) + end + end + + if talkState[cid] == 'kill' then + if msgcontains(msg, 'yes') then + player:setStorageValue(SPIKE_LOWER_KILL_MAIN, 0) + npcHandler:say('Gnometastic! You should have no trouble finding enough drillworms.', cid) + talkState[cid] = nil + elseif msgcontains(msg, 'no') then + npcHandler:say('Ok then.', cid) + talkState[cid] = nil + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnomaticus.lua b/data/npc/scripts/gnomaticus.lua new file mode 100644 index 00000000000..386dcfd38af --- /dev/null +++ b/data/npc/scripts/gnomaticus.lua @@ -0,0 +1,55 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, "again") then + player:setStorageValue(Storage.BigfootBurden.QuestLine, 19) + end + + if msgcontains(msg, "shooting") then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) == 11 then + npcHandler:say({ + "To the left you see our shooting range. Grab a cannon and shoot at the targets. You need five hits to succeed. ...", + "Shoot at the villain targets that will pop up. DON'T shoot innocent civilians since this will reset your score and you have to start all over. Report to me afterwards." + }, cid) + player:setStorageValue(Storage.BigfootBurden.QuestLine, 13) -- tirar do questlog + player:setStorageValue(Storage.BigfootBurden.Shooting, 0) + elseif player:getStorageValue(Storage.BigfootBurden.QuestLine) == 13 then + npcHandler:say("Shoot at the villain targets that will pop up. DON'T shoot innocent civilians since this will reset your score and you have to start all over. {Report} to me afterwards.", cid) + end + elseif msgcontains(msg, "report") then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) == 14 then + npcHandler:say("You are showing some promise! Now continue with the recruitment and talk to Gnomewart to the south for your endurance test!", cid) + player:setStorageValue(Storage.BigfootBurden.Shooting, player:getStorageValue(Storage.BigfootBurden.Shooting) + 1) + player:setStorageValue(Storage.BigfootBurden.QuestLine, 15) + elseif player:getStorageValue(Storage.BigfootBurden.QuestLine) == 13 then + npcHandler:say("Sorry you are not done yet.", cid) + elseif player:getStorageValue(Storage.BigfootBurden.QuestLine) <= 12 then + npcHandler:say("You have nothing to report at all.", cid) + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnombold.lua b/data/npc/scripts/gnombold.lua new file mode 100644 index 00000000000..666faa81cba --- /dev/null +++ b/data/npc/scripts/gnombold.lua @@ -0,0 +1,246 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) +local talkState = {} +local levels = {50, 79} + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, 'job') then + return npcHandler:say('I\'m the officer responsible for this area. I give out missions, accept mission reports and oversee our defences.', cid) + end + + if msgcontains(msg, 'gnome') then + return npcHandler:say('Gnomes have lived autonomous for so long that it still feels odd to work with strangers for many of us.', cid) + end + + if msgcontains(msg, 'area') then + return npcHandler:say({ + "The levels around us are... well, they are strange. We are still not entirely sure how they were created. It seems obvious that they are artificial, but they seem not to be burrowed or the like. ... ", + "We found strange stone formations that were not found on other layers around the Spike, but there is no clue at all if they are as natural as they look. It seems someone used some geomantic force to move the earth. ...", + "For what reason this has been done we can't tell as we found no clues of colonisation. ...", + "There are theories that the caves are some kind of burrow of some extinct creature or even creatures that are still around us, but exist as some form of invisible energy; but those theories are far-fetched and not supported by any discoveries. ...", + "Be that as it may, whatever those caves were meant for, these days they are crawling with creatures of different kinds and all are hostile towards us. The competition for food is great down here, and everything is seen as prey by the cave dwellers. ...", + "Some would like to feast on the crystal of the Spike, others would prefer a diet of gnomes. What they have in common is that they are a threat. If we can't keep them under control their constant attacks and raids on the Spike will wear us down. ...", + "That's where adventurers fit in to save the day. ", + }, cid) + end + + if msgcontains(msg, 'mission') then + if player:getLevel() > levels[2] then + npcHandler:say('Sorry, but no! Your expertise could be put to better use elsewhere. Here awaits you no challenge. You are desperately needed in the deeper levels of the Spike. Report there immediately. ', cid) + else + npcHandler:say(' I can offer you several missions: to gather geomantic {charges}, to {fertilise} the mushroom caves, to destroy monster {nests} and to {kill} some crystal crushers.', cid) + end + return + end + + if msgcontains(msg, 'report') then + talkState[cid] = 'report' + return npcHandler:say('What mission do you want to report about: gathering the geomantic {charges}, the {fertilisation} of the mushroom caves, about destroying monster {nests} and the {killing} of crystal crushers?', cid) + end + + if talkState[cid] == 'report' then + if msgcontains(msg, 'charges') then + if player:getStorageValue(SPIKE_MIDDLE_CHARGE_MAIN) == -1 then + npcHandler:say('You have not started that mission.', cid) + elseif player:getStorageValue(SPIKE_MIDDLE_CHARGE_MAIN) == 2 then + npcHandler:say('You have done well. Here, take your reward.', cid) + player:addFamePoint() + player:addExperience(2000, true) + player:setStorageValue(SPIKE_MIDDLE_CHARGE_MAIN, -1) + player:setStorageValue(SPIKE_MIDDLE_CHARGE_DAILY, 86400) + else + npcHandler:say('Gnowful! Charge this magnet at three monoliths in the cave system. With three charges, the magnet will disintegrate and charge you with its gathered energies. Step on the magnetic extractor here to deliver the charge to us, then report to me.', cid) + end + elseif msgcontains(msg, 'fertilisation') then + if player:getStorageValue(SPIKE_MIDDLE_MUSHROOM_MAIN) == -1 then + npcHandler:say('You have not started that mission.', cid) + elseif player:getStorageValue(SPIKE_MIDDLE_MUSHROOM_MAIN) == 4 then + npcHandler:say('You have done well. Here, take your reward.', cid) + player:addFamePoint() + player:addExperience(2000, true) + player:setStorageValue(SPIKE_MIDDLE_MUSHROOM_MAIN, -1) + player:setStorageValue(SPIKE_MIDDLE_MUSHROOM_DAILY, 86400) + else + npcHandler:say('Gnowful! Use the fertiliser on four gardener mushroom in the caves.', cid) + end + elseif msgcontains(msg, 'nests') then + if player:getStorageValue(SPIKE_MIDDLE_NEST_MAIN) == -1 then + npcHandler:say('You have not started that mission.', cid) + elseif player:getStorageValue(SPIKE_MIDDLE_NEST_MAIN) == 8 then + npcHandler:say('You have done well. Here, take your reward.', cid) + player:addFamePoint() + player:addExperience(2000, true) + player:setStorageValue(SPIKE_MIDDLE_NEST_MAIN, -1) + player:setStorageValue(SPIKE_MIDDLE_NEST_DAILY, 86400) + else + npcHandler:say('Gnowful! Step into the transformer and destroy eight monster nests.', cid) + end + elseif msgcontains(msg, 'killing') then + if player:getStorageValue(SPIKE_MIDDLE_KILL_MAIN) == -1 then + npcHandler:say('You have not started that mission.', cid) + elseif player:getStorageValue(SPIKE_MIDDLE_KILL_MAIN) == 7 then + npcHandler:say('You have done well. Here, take your reward.', cid) + player:addFamePoint() + player:addExperience(2000, true) + player:setStorageValue(SPIKE_MIDDLE_KILL_MAIN, -1) + player:setStorageValue(SPIKE_MIDDLE_KILL_DAILY, 86400) + else + npcHandler:say('Gnowful! Just go out to the caves and kill at least seven crystalcrushers.', cid) + end + else + npcHandler:say('That\'s not a valid mission name.', cid) + end + talkState[cid] = nil + return + end + + --[[///////////////////// + ////GEOMANTIC CHARGES//// + ///////////////////////]] + if msgcontains(msg, 'charges') then + if player:getStorageValue(SPIKE_MIDDLE_CHARGE_DAILY) >= os.time() then + return npcHandler:say('Sorry, you have to wait ' .. string.diff(player:getStorageValue(SPIKE_MIDDLE_CHARGE_DAILY)-os.time()) .. ' before this task gets available again.', cid) + end + + if (player:getLevel() < levels[1]) or (player:getLevel() > levels[2]) then + return npcHandler:say('Sorry, you are not on the required range of levels [' .. levels[1] ..'-' .. levels[2] ..'].', cid) + end + + if player:getStorageValue(SPIKE_MIDDLE_CHARGE_MAIN) == -1 then + npcHandler:say({'Our mission for you is to use a magnet on three different monoliths in the cave system here. After the magnet evaporates on the last charge, enter the magnetic extractor here to deliver your charge.', 'If you are interested, I can give you some more {information} about it. Are you willing to accept this mission?'}, cid) + talkState[cid] = 'charges' + else + npcHandler:say('You have already started that mission.', cid) + end + end + + if talkState[cid] == 'charges' then + if msgcontains(msg, 'yes') then + player:addItem(21557, 1) + player:setStorageValue(SPIKE_MIDDLE_CHARGE_MAIN, 0) + npcHandler:say({'Gnometastic! Charge this magnet at three monoliths in the cave system. With three charges, the magnet will disintegrate and charge you with its gathered energies. Step on the magnetic extractor here to deliver the charge to us, then report to me.','If you lose the magnet you\'ll have to bring your own. Gnomux sells all the equipment that is required for our missions.'}, cid) + talkState[cid] = nil + elseif msgcontains(msg, 'no') then + npcHandler:say('Ok then.', cid) + talkState[cid] = nil + end + end + + --[[///////////// + ////FERTILISE//// + ///////////////]] + if msgcontains(msg, 'fertilise') then + if player:getStorageValue(SPIKE_MIDDLE_MUSHROOM_DAILY) >= os.time() then + return npcHandler:say('Sorry, you have to wait ' .. string.diff(player:getStorageValue(SPIKE_MIDDLE_MUSHROOM_DAILY)-os.time()) .. ' before this task gets available again.', cid) + end + + if (player:getLevel() < levels[1]) or (player:getLevel() > levels[2]) then + return npcHandler:say('Sorry, you are not on the required range of levels [' .. levels[1] ..'-' .. levels[2] ..'].', cid) + end + + if player:getStorageValue(SPIKE_MIDDLE_MUSHROOM_MAIN) == -1 then + npcHandler:say('Your mission would be to seek out gardener mushrooms in the caves and use some fertiliser on them. If you are interested, I can give you some more information about it. Are you willing to accept this mission?', cid) + talkState[cid] = 'fertilise' + else + npcHandler:say('You have already started that mission.', cid) + end + end + + if talkState[cid] == 'fertilise' then + if msgcontains(msg, 'yes') then + player:addItem(21564) + player:setStorageValue(SPIKE_MIDDLE_MUSHROOM_MAIN, 0) + npcHandler:say('Gnometastic! And here is your fertiliser - use it on four gardener mushroom in the caves. If you lose the fertiliser you\'ll have to bring your own. Gnomux sells all the equipment that is required for our missions.', cid) + talkState[cid] = nil + elseif msgcontains(msg, 'no') then + npcHandler:say('Ok then.', cid) + talkState[cid] = nil + end + end + + --[[////////////////// + ////DESTROY NESTS///// + ////////////////////]] + if msgcontains(msg, 'nests') then + if player:getStorageValue(SPIKE_MIDDLE_NEST_DAILY) >= os.time() then + return npcHandler:say('Sorry, you have to wait ' .. string.diff(player:getStorageValue(SPIKE_MIDDLE_NEST_DAILY)-os.time()) .. ' before this task gets available again.', cid) + end + + if (player:getLevel() < levels[1]) or (player:getLevel() > levels[2]) then + return npcHandler:say('Sorry, you are not on the required range of levels [' .. levels[1] ..'-' .. levels[2] ..'].', cid) + end + + if player:getStorageValue(SPIKE_MIDDLE_NEST_MAIN) == -1 then + npcHandler:say('Our mission for you is to step into the gnomish transformer and then destroy eight monster nests in the caves. If you are interested, I can give you some more information about it. Are you willing to accept this mission?', cid) + talkState[cid] = 'nests' + else + npcHandler:say('You have already started that mission.', cid) + end + end + + if talkState[cid] == 'nests' then + if msgcontains(msg, 'yes') then + player:setStorageValue(SPIKE_MIDDLE_NEST_MAIN, 0) + npcHandler:say('Gnometastic! Don\'t forget to step into the transformer before you go out and destroy five monster nests. If your transformation runs out, return to the transformer to get another illusion.', cid) + talkState[cid] = nil + elseif msgcontains(msg, 'no') then + npcHandler:say('Ok then.', cid) + talkState[cid] = nil + end + end + + --[[///////// + ////KILL///// + ///////////]] + if msgcontains(msg, 'kill') then + if player:getStorageValue(SPIKE_MIDDLE_KILL_DAILY) >= os.time() then + return npcHandler:say('Sorry, you have to wait ' .. string.diff(player:getStorageValue(SPIKE_MIDDLE_KILL_DAILY)-os.time()) .. ' before this task gets available again.', cid) + end + + if (player:getLevel() < levels[1]) or (player:getLevel() > levels[2]) then + return npcHandler:say('Sorry, you are not on the required range of levels [' .. levels[1] ..'-' .. levels[2] ..'].', cid) + end + + if player:getStorageValue(SPIKE_MIDDLE_KILL_MAIN) == -1 then + npcHandler:say('This mission will require you to kill some crystal crushers for us. If you are interested, I can give you some more information about it. Are you willing to accept this mission?', cid) + talkState[cid] = 'kill' + else + npcHandler:say('You have already started that mission.', cid) + end + end + + if talkState[cid] == 'kill' then + if msgcontains(msg, 'yes') then + player:setStorageValue(SPIKE_MIDDLE_KILL_MAIN, 0) + npcHandler:say('Gnometastic! You should have no trouble to find enough crystal crushers. Killing seven of them should be enough.', cid) + talkState[cid] = nil + elseif msgcontains(msg, 'no') then + npcHandler:say('Ok then.', cid) + talkState[cid] = nil + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnome.lua b/data/npc/scripts/gnome.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/gnome.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnome_trooper.lua b/data/npc/scripts/gnome_trooper.lua new file mode 100644 index 00000000000..037a0949ca3 --- /dev/null +++ b/data/npc/scripts/gnome_trooper.lua @@ -0,0 +1,71 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) +local response = { + [0] = "It's a pipe! What can be more relaxing for a gnome than to smoke his pipe after a day of duty at the front. At least it's a chance to do something really dangerous after all!", + [1] = "Ah, a letter from home! Oh - I had no idea she felt that way! This is most interesting!", + [2] = "It's a model of the gnomebase Alpha! For self-assembly! With toothpicks...! Yeeaah...! I guess.", + [3] = "A medal of honour! At last they saw my true worth!" +} + +if not DELIVERED_PARCELS then + DELIVERED_PARCELS = {} +end + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function greetCallback(cid) + local player = Player(cid) + if isInArray({-1, 4}, player:getStorageValue(SPIKE_LOWER_PARCEL_MAIN)) then + return false + end + if isInArray(DELIVERED_PARCELS[player:getGuid()], Creature(getNpcCid()):getId()) then + return false + end + return true +end + +function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + local status = player:getStorageValue(SPIKE_LOWER_PARCEL_MAIN) + + if not DELIVERED_PARCELS[player:getGuid()] then + DELIVERED_PARCELS[player:getGuid()] = {} + end + + if msgcontains(msg, 'something') and not isInArray({-1, 4}, status) then + if isInArray(DELIVERED_PARCELS[player:getGuid()], Creature(getNpcCid()):getId()) then + return true + end + + if not player:removeItem(21569, 1) then + npcHandler:say("But you don't have it...", cid) + return npcHandler:releaseFocus(cid) + end + + npcHandler:say(response[player:getStorageValue(SPIKE_LOWER_PARCEL_MAIN)], cid) + player:setStorageValue(SPIKE_LOWER_PARCEL_MAIN, status + 1) + table.insert(DELIVERED_PARCELS[player:getGuid()], Creature(getNpcCid()):getId()) + npcHandler:releaseFocus(cid) + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnomegica.lua b/data/npc/scripts/gnomegica.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/gnomegica.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnomejam.lua b/data/npc/scripts/gnomejam.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/gnomejam.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnomelvis.lua b/data/npc/scripts/gnomelvis.lua new file mode 100644 index 00000000000..c6a36ed4057 --- /dev/null +++ b/data/npc/scripts/gnomelvis.lua @@ -0,0 +1,66 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, "looking") then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) >= 19 or player:getStorageValue(Storage.BigfootBurden.QuestLine) <= 22 then + npcHandler:say("I'm the gnomish {musical} supervisor!", cid) + end + + elseif msgcontains(msg, "musical") then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) == 19 then + npcHandler:say({ + "Ah well. Everyone has a very personal melody in his soul. Only if you know your soul melody then you know yourself. And only if you know yourself will you be admitted to the Bigfoot company. ...", + "So what you have to do is to find your soul melody. Do you see the huge crystals in this room? Those are harmonic crystals. Use them to deduce your soul melody. Simply use them to create a sound sequence. ...", + "Every soul melody consists of seven sound sequences. You will have to figure out your correct soul melody by trial and error. If you hit a wrong note, you will have to start over." + }, cid) + player:setStorageValue(Storage.BigfootBurden.QuestLine, 21) + player:setStorageValue(Storage.BigfootBurden.MelodyStatus, 1) + if player:getStorageValue(Storage.BigfootBurden.MelodyTone1) < 1 then + for i = 0, 6 do + player:setStorageValue(Storage.BigfootBurden.MelodyTone1 + i, math.random(3124, 3127)) + end + end + elseif player:getStorageValue(Storage.BigfootBurden.QuestLine) == 21 then + npcHandler:say("What you have to do is to find your soul melody. Use the harmonic crystals to deduce your soul melody. Every soul melody consists of seven sound sequences. ...", cid) + npcHandler:say("You will have to figure out your correct soul melody by trial and error.", cid) + elseif player:getStorageValue(Storage.BigfootBurden.QuestLine) == 22 then + npcHandler:say({ + "Congratulations on finding your soul melody. And a pretty one as far as I can tell. Now you are a true recruit of the Bigfoot company! Commander Stone might have some tasks for you to do! ...", + "Look for him in the central chamber. I marked your map where you will find him." + }, cid) + player:setStorageValue(Storage.BigfootBurden.QuestLine, 25) + player:setStorageValue(Storage.BigfootBurden.QuestLineComplete, 2) + player:setStorageValue(Storage.BigfootBurden.Rank) + player:addAchievement('Becoming a Bigfoot') + + elseif player:getStorageValue(Storage.BigfootBurden.QuestLine) == 25 then + npcHandler:say("Congratulations on finding your soul melody.", cid) + end + end + + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnomenursey.lua b/data/npc/scripts/gnomenursey.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/gnomenursey.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnomeral.lua b/data/npc/scripts/gnomeral.lua new file mode 100644 index 00000000000..ccf878537bd --- /dev/null +++ b/data/npc/scripts/gnomeral.lua @@ -0,0 +1,216 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if not player then + return false + end + + if(msgcontains(msg, "mission")) then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) == 27 then + npcHandler:say("For your rank there are two missions available: {matchmaker} and golem {repair}. You can undertake each mission, but you can turn in a specific mission only once every 20 hours. ", cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.BigfootBurden.QuestLine) >= 28 then + npcHandler:say("For your rank there are four missions available: {matchmaker}, golem {repair}, {spore} gathering and {grindstone} hunt. You can undertake each mission, but you can turn in a specific mission only once every 20 hours.", cid) + npcHandler.topic[cid] = 0 + end + + -- Matchmaker + elseif msgcontains(msg, "matchmaker") then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) >= 27 then + if player:getStorageValue(Storage.BigfootBurden.MissionMatchmaker) < 1 and player:getStorageValue(Storage.BigfootBurden.MatchmakerTimeout) < os.time() then + npcHandler:say({ + "You will have to find a lonely crystal a perfect match. I don't understand the specifics but the gnomes told me that even crystals need a mate to produce offspring. ...", + "Be that as it may, in this package you'll find a crystal. Take it out of the package and go to the crystal caves to find it a mate. Just look out for huge red crystals and try your luck. ...", + "They should look like one of those seen in your soul melody test. You will find them in the crystal grounds. {Report} back to me when you are done." + }, cid) + player:setStorageValue(Storage.BigfootBurden.MissionMatchmaker, 1) + player:setStorageValue(Storage.BigfootBurden.MatchmakerStatus, 0) + player:setStorageValue(Storage.BigfootBurden.MatchmakerIdNeeded, math.random(18320, 18326)) + player:addItem(18313, 1) --- taking missions + elseif player:getStorageValue(Storage.BigfootBurden.MatchmakerTimeout) > os.time() then -- trying to take mission while in cooldown + npcHandler:say("Sorry, you will have to wait before you can undertake this mission again.", cid) + elseif player:getStorageValue(Storage.BigfootBurden.MissionMatchmaker) > 0 then -- reporting mission + if player:getStorageValue(Storage.BigfootBurden.MatchmakerStatus) == 1 then -- can report missions + player:setStorageValue(Storage.BigfootBurden.Rank, player:getStorageValue(Storage.BigfootBurden.Rank) + 10) + player:addItem(18422, 2) + player:addItem(18215, 1) + player:setStorageValue(Storage.BigfootBurden.MissionMatchmaker, 0) + player:setStorageValue(Storage.BigfootBurden.MatchmakerStatus, -1) + player:setStorageValue(Storage.BigfootBurden.MatchmakerIdNeeded, -1) + player:setStorageValue(Storage.BigfootBurden.MatchmakerTimeout, os.time() + 72000) + player:addAchievement('Crystals in Love') + player:checkGnomeRank() + npcHandler:say("Gnomo arigato |PLAYERNAME|! You did well. That will help us a lot. Take your tokens and this gnomish supply package as a reward. ", cid) + npcHandler.topic[cid] = 0 + else -- haven't finished + if npcHandler.topic[cid] >= 1 then + npcHandler:say("You are not done yet.", cid) -- is reporting + else + npcHandler:say("You already have accepted this mission. Don't forget to {report} to me when you are done.", cid) -- se nao tiver reportando + end + npcHandler.topic[cid] = 0 + end + end + else + npcHandler:say("Sorry, you do have not have the required rank to undertake this mission.", cid) + end + -- Matchmaker + + -- Golem Repair + elseif msgcontains(msg, "repair") then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) >= 27 then + if player:getStorageValue(Storage.BigfootBurden.MissionTinkersBell) < 1 and player:getStorageValue(Storage.BigfootBurden.TinkerBellTimeout) < os.time() then + npcHandler:say("Our gnomish crystal golems sometimes go nuts. A recent earthquake has disrupted the entire production of a golem factory. ... ", cid) + npcHandler:say({ + "I'm no expert on how those golems work, but it seems that when the crystals of the golems get out of harmony, they do as they please and even sometimes become violent. The violent ones are lost. ...", + "Don't bother with them, though you may decide to kill some to get rid of them. The others can be repaired, but to recall them to the workshops, the golems have to be put into a specific resonance. ...", + "Use the bell I gave you on the golems, so the gnomes can recall them to their workshops. Getting four of them should be enough for now. Report back when you are ready." + }, cid) + player:setStorageValue(Storage.BigfootBurden.MissionTinkersBell, 1) + player:setStorageValue(Storage.BigfootBurden.GolemCount, 0) + player:addItem(18343, 1) --- taking missions + elseif player:getStorageValue(Storage.BigfootBurden.TinkerBellTimeout) > os.time() then -- trying to take mission while in cooldown + npcHandler:say("Sorry, you will have to wait before you can undertake this mission again.", cid) + elseif player:getStorageValue(Storage.BigfootBurden.MissionTinkersBell) > 0 then -- reporting mission + if player:getStorageValue(Storage.BigfootBurden.GolemCount) >= 4 then -- can report missions + player:removeItem(18343, 1) + player:setStorageValue(Storage.BigfootBurden.Rank, player:getStorageValue(Storage.BigfootBurden.Rank) + 10) + player:addItem(18422, 2) + player:addItem(18215, 1) + player:setStorageValue(Storage.BigfootBurden.MissionTinkersBell, 0) + player:setStorageValue(Storage.BigfootBurden.GolemCount, -1) + player:setStorageValue(Storage.BigfootBurden.TinkerBellTimeout, os.time() + 72000) + player:addAchievement('Substitute Tinker') + player:checkGnomeRank() + npcHandler:say("Gnomo arigato |PLAYERNAME|! You did well. That will help us a lot. Take your tokens and this gnomish supply package as a reward. ", cid) + npcHandler.topic[cid] = 0 + else -- haven't finished + if npcHandler.topic[cid] >= 1 then + npcHandler:say("You are not done yet.", cid) -- is reporting + else + npcHandler:say("You already have accepted this mission. Don't forget to {report} to me when you are done.", cid) -- se nao tiver reportando + end + npcHandler.topic[cid] = 0 + end + end + else + npcHandler:say("Sorry, you do have not have the required rank to undertake this mission.", cid) + end + -- Golem Repair + + -- Spore Gathering + elseif msgcontains(msg, "spore") then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) >= 28 then + if player:getStorageValue(Storage.BigfootBurden.MissionSporeGathering) < 1 and player:getStorageValue(Storage.BigfootBurden.SporeGatheringTimeout) < os.time() then + npcHandler:say({ + "We gnomes want you to gather a special collection of spores. All you have to do is use a puffball mushroom and use the spore gathering kit I gave you to gather the spores. ...", + "There is a catch though. You need to collect different spores in a specific sequence to fill your gathering kit. If you mix the spores in the wrong way, you ruin your collection and have to start over. ...", + "You have to gather them in this sequence: red, green, blue and yellow. You can see on your kit what is required next." + }, cid) + player:setStorageValue(Storage.BigfootBurden.MissionSporeGathering, 1) + player:setStorageValue(Storage.BigfootBurden.SporeCount, 0) + player:addItem(18328, 1) + npcHandler.topic[cid] = 0 --- taking missions + elseif player:getStorageValue(Storage.BigfootBurden.SporeGatheringTimeout) > os.time() then -- trying to take mission while in cooldown + npcHandler:say("Sorry, you will have to wait before you can undertake this mission again.", cid) + elseif player:getStorageValue(Storage.BigfootBurden.MissionSporeGathering) > 0 then -- reporting mission + if player:getStorageValue(Storage.BigfootBurden.SporeCount) == 4 then -- can report missions + player:removeItem(18332, 1) + player:setStorageValue(Storage.BigfootBurden.Rank, player:getStorageValue(Storage.BigfootBurden.Rank) + 10) + player:addItem(18422, 2) + player:addItem(18215, 1) + player:setStorageValue(Storage.BigfootBurden.MissionSporeGathering, 0) + player:setStorageValue(Storage.BigfootBurden.SporeCount, -1) + player:setStorageValue(Storage.BigfootBurden.SporeGatheringTimeout, os.time() + 72000) + player:addAchievement('Spore Hunter') + player:checkGnomeRank() + npcHandler:say("Gnomo arigato |PLAYERNAME|! You did well. That will help us a lot. Take your tokens and this gnomish supply package as a reward. ", cid) + npcHandler.topic[cid] = 0 + else -- haven't finished + if npcHandler.topic[cid] >= 1 then + npcHandler:say("You are not done yet.", cid) -- is reporting + else + npcHandler:say("You already have accepted this mission. Don't forget to {report} to me when you are done.", cid) -- se nao tiver reportando + end + npcHandler.topic[cid] = 0 + end + end + else + npcHandler:say("Sorry, you do have not have the required rank to undertake this mission.", cid) + end + -- Spore Gathering + + -- Grindstone Hunt + elseif msgcontains(msg, "grindstone") then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) >= 28 then + if player:getStorageValue(Storage.BigfootBurden.MissionGrindstoneHunt) < 1 and player:getStorageValue(Storage.BigfootBurden.GrindstoneTimeout) < os.time() then + npcHandler:say({ + "We gnomes need some special grindstones to cut and polish specific crystals. The thing is, they can only be found in a quite dangerous lava cave full of vile monsters. You'll reach it via the hot spot teleporter. ...", + "It will be your task to get one such grindstone and bring it back to me." + }, cid) + player:setStorageValue(Storage.BigfootBurden.MissionGrindstoneHunt, 1) + player:setStorageValue(Storage.BigfootBurden.GrindstoneStatus, 0) + npcHandler.topic[cid] = 0 --- taking missions + elseif player:getStorageValue(Storage.BigfootBurden.GrindstoneTimeout) > os.time() then -- trying to take mission while in cooldown + npcHandler:say("Sorry, you will have to wait before you can undertake this mission again.", cid) + elseif player:getStorageValue(Storage.BigfootBurden.MissionGrindstoneHunt) > 0 then -- reporting mission + if player:getStorageValue(Storage.BigfootBurden.GrindstoneStatus) == 1 then -- can report missions + player:removeItem(18337, 1) + player:setStorageValue(Storage.BigfootBurden.Rank, player:getStorageValue(Storage.BigfootBurden.Rank) + 10) + player:addItem(18422, 2) + player:addItem(18215, 1) + player:setStorageValue(Storage.BigfootBurden.MissionGrindstoneHunt, 0) + player:setStorageValue(Storage.BigfootBurden.GrindstoneStatus, -1) + player:setStorageValue(Storage.BigfootBurden.GrindstoneTimeout, os.time() + 72000) + player:addAchievement('Grinding Again') + player:checkGnomeRank() + npcHandler:say("Gnomo arigato |PLAYERNAME|! You did well. That will help us a lot. Take your tokens and this gnomish supply package as a reward. ", cid) + npcHandler.topic[cid] = 0 + else -- haven't finished + if npcHandler.topic[cid] >= 1 then + npcHandler:say("You are not done yet.", cid) -- is reporting + else + npcHandler:say("You already have accepted this mission. Don't forget to {report} to me when you are done.", cid) -- se nao tiver reportando + end + npcHandler.topic[cid] = 0 + end + end + else + npcHandler:say("Sorry, you do have not have the required rank to undertake this mission.", cid) + end + -- Grindstone Hunt + + elseif(msgcontains(msg, "report")) then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) == 27 then + npcHandler:say("Which mission do you want to report: {matchmaker}, golem {repair}?", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.BigfootBurden.QuestLine) >= 28 then + npcHandler:say("Which mission do you want to report: {matchmaker}, golem {repair}, {spore} gathering or {grindstone} hunt?", cid) + npcHandler.topic[cid] = 2 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnomercy.lua b/data/npc/scripts/gnomercy.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/gnomercy.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnomerik.lua b/data/npc/scripts/gnomerik.lua new file mode 100644 index 00000000000..11d72948f79 --- /dev/null +++ b/data/npc/scripts/gnomerik.lua @@ -0,0 +1,277 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addGreetKeyword({'hi'}, {npcHandler = npcHandler, text = 'Hello and welcome in the gnomish {recruitment} office.'}, + function (player) + if player:getStorageValue(Storage.BigfootBurden.QuestLine) == 1 then + + player:setStorageValue(Storage.BigfootBurden.QuestLine, 3) + end + end +) +keywordHandler:addAliasKeyword({'hello'}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + + if player:getStorageValue(Storage.BigfootBurden.NeedsBeer) == 1 then + if msgcontains(msg, "recruit") or msgcontains(msg, "test") or msgcontains(msg, "result") then + npcHandler:say({"I suggest you relax a bit with a fresh mushroom beer and we can talk after that. ...", "Gnominus... He is the one you need right now, find him."}, cid) + end + return + end + + if msgcontains(msg, "recruit") then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) == 5 then + npcHandler:say("Yes... Yes... . We already talked about that. I can't remember if you have already tried the {test}, so lets get going.", cid) + elseif player:getStorageValue(Storage.BigfootBurden.QuestLine) == 3 then + npcHandler:say("We are hiring people to fight in our so called Bigfoot company against the foes of gnomekind. Are you interested in joining?", cid) + npcHandler.topic[cid] = 1 + end + + -- TEST + elseif msgcontains(msg, "test") then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) == 5 then + if npcHandler.topic[cid] < 1 then + player:setStorageValue(Storage.BigfootBurden.Test, 0) + npcHandler:say({ + "Imagine, during your travels you come upon a rare and unknown mushroom. Would you {A}) note down its specifics and location and look for a gnome to take care of it. ...", + "Or would you {B}) smash it to an unrecognisable pulp. Or would you {C}) pluck it to take it with you for further examination. Or would you {D}) try to become friends with the mushroom by singing questionable bar-room songs?" + }, cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 3 then + npcHandler:say({ + "Imagine you wake up one morning and discover you have forgotten how to knot your shoelaces. Would you {A}) admit defeat and go to bed once more. ...", + "{B}) look for a gnome that can remind you how to do it. {C}) Despite the risk of injuring yourself, try to figure it out on your own. {D}) Use some pottery instead of shoes." + }, cid) + npcHandler.topic[cid] = 4 + elseif npcHandler.topic[cid] == 5 then + npcHandler:say({ + "Now let us assume you see a gnome in danger. Would you {A}) not care because you must be imagining things. {B}) Save the gnome despite all odds and risk to your own life. ...", + "{C}) Inspire the gnome by singing the gnomish national anthem. {D}) Hide and loot his corpse if he dies." + }, cid) + npcHandler.topic[cid] = 6 + elseif npcHandler.topic[cid] == 7 then + npcHandler:say({ + "Imagine you were participating in a gnome-throwing competition. Would you {A}) do some physical calculations in advance to increase your chances of winning. ...", + "{B}) throw the gnome as safely as you can to ensure his safety. {C}) Sabotage the throwing gnomes of your competitors. {D}) Never participate in such an abominable competition." + }, cid) + npcHandler.topic[cid] = 8 + elseif npcHandler.topic[cid] == 9 then + npcHandler:say({ + "Now imagine you were given the order to guard a valuable and unique mushroom. You guard it for days and no one shows up to release you and you grow hungry. ...", + "Would you {A}) eat your boots. {B}) eat the mushroom. {C}) eat a bit of the mushroom. {D}) stick to your duty and continue starving." + }, cid) + npcHandler.topic[cid] = 10 + elseif npcHandler.topic[cid] == 11 then + npcHandler:say("What do you think describes gnomish society best? {A}) Ingenuity {B}) Bravery {C}) Humility {D}) All of the above.", cid) + npcHandler.topic[cid] = 12 + elseif npcHandler.topic[cid] == 13 then + npcHandler:say({ + "How many bigfoot does it take to change a light crystal? {A}) Only one since it's a piece of mushroom cake. {B}) Light crystals are delicate products of gnomish science and should only be handled by certified gnomish experts. ...", + "{C}) Three. One to hold the crystal and two to turn him around. {D}) Five. A light crystal turner, a light crystal picker, a light crystal exchanger, a light crystal changing manager and finally a light crystal changing manager assistant." + }, cid) + npcHandler.topic[cid] = 14 + elseif npcHandler.topic[cid] == 15 then + npcHandler:say({ + "What is a pollyfluxed quantumresonator? {A}) Something funny. {B}) Something important. {C}) Something to be destroyed. ...", + "{D}) Sadly I am not a gnome and lack the intelligence and education to know about even the simplest of gnomish inventions." + }, cid) + npcHandler.topic[cid] = 16 + elseif npcHandler.topic[cid] == 17 then + npcHandler:say({ + "If your mushroom patch is infested with cave worms, would you {A}) place some green light crystals to drive them away. {B}) place some disharmonic crystals to drive them away. ...", + "{C}) burn everything down. {D}) switch your diet to cave worms." + }, cid) + npcHandler.topic[cid] = 18 + elseif npcHandler.topic[cid] == 19 then + npcHandler:say("What is the front part of a spear? Is it {A}) the pointed one. {B}) The blunt one. {C}) Whatever causes the most damage {D}) A spear is no weapon but a fruit that grows on surface trees.", cid) + npcHandler.topic[cid] = 20 + elseif npcHandler.topic[cid] == 21 then + npcHandler:say({ + "On a military campaign what piece of equipment would you need most? ...", + "Is it {A}) some tasty mushroom beer to keep the morale high. {B}) A large backpack to carry all the loot. {C}) A mighty weapon to vanquish the foes. {D}) Mushroom earplugs to be spared of the cries of agony of your opponents?" + }, cid) + npcHandler.topic[cid] = 22 + elseif npcHandler.topic[cid] == 23 then + npcHandler:say("What comes first? {A}) safety {B}) I {C}) duty {D}) George", cid) + npcHandler.topic[cid] = 24 + elseif npcHandler.topic[cid] == 25 then + npcHandler:say("In case of emergency {A}) break glass {B}) break a leg {C}) have a break {D}) call a gnome?", cid) + npcHandler.topic[cid] = 26 + elseif npcHandler.topic[cid] == 27 then + npcHandler:say("The greatest disaster I can imagine is ... {A}) to fail the gnomes {B}) a ruined mushroom pie {C}) accidentally hammering my finger {D}) having some work to do", cid) + npcHandler.topic[cid] = 28 + elseif npcHandler.topic[cid] == 29 then + npcHandler:say("What would your favourite pet be? {A}) A Krazzelzak of course. {B}) An Uxmoff to be honest. {C}) Montpiffs were always my favourite. {D}) A Humdrella and nothing else!", cid) + npcHandler.topic[cid] = 30 + elseif npcHandler.topic[cid] == 31 then + npcHandler:say("Why do you want to become a bigfoot? {A}) To become rich and famous. {B}) To become famous and rich. {C}) To become rich or famous. {D}) To serve the gnomish community in their struggle?", cid) + npcHandler.topic[cid] = 32 + end + end + -- ANSWERS + elseif msg:lower() == "a" then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) == 5 then + if (npcHandler.topic[cid] % 2) == 0 then + if npcHandler.topic[cid] == 2 then + npcHandler:say("Indeed an excellent and smart decision for an ungnomish lifeform. But let us continue with the {test}.", cid) + player:setStorageValue(Storage.BigfootBurden.Test, player:getStorageValue(Storage.BigfootBurden.Test) + 7) + npcHandler.topic[cid] = npcHandler.topic[cid] + 1 + elseif npcHandler.topic[cid] == 18 then + npcHandler:say("A well thought out answer I have to admit. But let us continue with the {test}.", cid) + player:setStorageValue(Storage.BigfootBurden.Test, player:getStorageValue(Storage.BigfootBurden.Test) + 7) + npcHandler.topic[cid] = npcHandler.topic[cid] + 1 + elseif npcHandler.topic[cid] == 20 then + npcHandler:say("Ah, we have a true warrior here I guess. But let us continue with the {test}.", cid) + player:setStorageValue(Storage.BigfootBurden.Test, player:getStorageValue(Storage.BigfootBurden.Test) + 7) + npcHandler.topic[cid] = npcHandler.topic[cid] + 1 + elseif npcHandler.topic[cid] == 28 then + npcHandler:say("Fear not. We don't expect too much of you anyway. But let us continue with the {test}.", cid) + player:setStorageValue(Storage.BigfootBurden.Test, player:getStorageValue(Storage.BigfootBurden.Test) + 7) + npcHandler.topic[cid] = npcHandler.topic[cid] + 1 + elseif npcHandler.topic[cid] == 30 then + npcHandler:say("Ha! A Krazzelzak would for sure fit someone like you! But let us continue with the {test}.", cid) + player:setStorageValue(Storage.BigfootBurden.Test, player:getStorageValue(Storage.BigfootBurden.Test) + 7) + npcHandler.topic[cid] = npcHandler.topic[cid] + 1 + else + if npcHandler.topic[cid] < 33 then + npcHandler:say("Wrong answer!", cid) + npcHandler.topic[cid] = npcHandler.topic[cid] + 1 + if npcHandler.topic[cid] >= 33 then + npcHandler:say("Stop it! The test is over, you can ask me for your {results}.", cid) + end + end + end + end + end + elseif msg:lower() == "b" then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) == 5 then + if (npcHandler.topic[cid] % 2) == 0 then + if npcHandler.topic[cid] == 6 then + npcHandler:say("Although chances are the gnome will end up rescuing you instead, it is the attempt that counts. But let us continue with the {test}.", cid) + player:setStorageValue(Storage.BigfootBurden.Test, player:getStorageValue(Storage.BigfootBurden.Test) + 7) + npcHandler.topic[cid] = npcHandler.topic[cid] + 1 + elseif npcHandler.topic[cid] == 14 then + npcHandler:say("I knew this question was too easy. But let us continue with the {test}.", cid) + player:setStorageValue(Storage.BigfootBurden.Test, player:getStorageValue(Storage.BigfootBurden.Test) + 7) + npcHandler.topic[cid] = npcHandler.topic[cid] + 1 + else + if npcHandler.topic[cid] < 33 then + npcHandler:say("Wrong answer!", cid) + npcHandler.topic[cid] = npcHandler.topic[cid] + 1 + if npcHandler.topic[cid] >= 33 then + npcHandler:say("Stop it! The test is over, you can ask me for your {results}.") + end + end + end + end + end + elseif msg:lower() == "c" then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) == 5 then + if (npcHandler.topic[cid] % 2) == 0 then + if npcHandler.topic[cid] == 4 then + npcHandler:say("That's the spirit! Initiative is always a good thing. Well most of the time. But let us continue with the {test}.", cid) + player:setStorageValue(Storage.BigfootBurden.Test, player:getStorageValue(Storage.BigfootBurden.Test) + 7) + npcHandler.topic[cid] = npcHandler.topic[cid] + 1 + elseif npcHandler.topic[cid] == 22 then + npcHandler:say("You have no idea how many answer this question wrong. But let us continue with the {test}.", cid) + player:setStorageValue(Storage.BigfootBurden.Test, player:getStorageValue(Storage.BigfootBurden.Test) + 7) + npcHandler.topic[cid] = npcHandler.topic[cid] + 1 + elseif npcHandler.topic[cid] == 24 then + npcHandler:say("That's the spirit! But let us continue with the {test}.", cid) + player:setStorageValue(Storage.BigfootBurden.Test, player:getStorageValue(Storage.BigfootBurden.Test) + 7) + npcHandler.topic[cid] = npcHandler.topic[cid] + 1 + else + if npcHandler.topic[cid] < 33 then + npcHandler:say("Wrong answer!", cid) + npcHandler.topic[cid] = npcHandler.topic[cid] + 1 + if npcHandler.topic[cid] >= 33 then + npcHandler:say("Stop it! The test is over, you can ask me for your {results}.", cid) + end + end + end + end + end + elseif msg:lower() == "d" then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) == 5 then + if (npcHandler.topic[cid] % 2) == 0 then + if npcHandler.topic[cid] == 8 then + npcHandler:say("Of COURSE you wouldn't! NO ONE would! But let us continue with the {test}.", cid) + player:setStorageValue(Storage.BigfootBurden.Test, player:getStorageValue(Storage.BigfootBurden.Test) + 7) + npcHandler.topic[cid] = npcHandler.topic[cid] + 1 + elseif npcHandler.topic[cid] == 10 then + npcHandler:say("I can only hope that is your honest opinion. But let us continue with the test.", cid) + player:setStorageValue(Storage.BigfootBurden.Test, player:getStorageValue(Storage.BigfootBurden.Test) + 7) + npcHandler.topic[cid] = npcHandler.topic[cid] + 1 + elseif npcHandler.topic[cid] == 12 then + npcHandler:say("Oh, you silver tongued devil almost made me blush. But of course you're right. But let us continue with the {test}.", cid) + player:setStorageValue(Storage.BigfootBurden.Test, player:getStorageValue(Storage.BigfootBurden.Test) + 7) + npcHandler.topic[cid] = npcHandler.topic[cid] + 1 + elseif npcHandler.topic[cid] == 16 then + npcHandler:say("How true. How true. *sigh* But fear not! We gnomes are here to help! But let us continue with the {test}.", cid) + player:setStorageValue(Storage.BigfootBurden.Test, player:getStorageValue(Storage.BigfootBurden.Test) + 7) + npcHandler.topic[cid] = npcHandler.topic[cid] + 1 + elseif npcHandler.topic[cid] == 26 then + npcHandler:say("That's just what I'd do - if I weren't a gnome already, that is. But let us continue with the {test}.", cid) + player:setStorageValue(Storage.BigfootBurden.Test, player:getStorageValue(Storage.BigfootBurden.Test) + 7) + npcHandler.topic[cid] = npcHandler.topic[cid] + 1 + elseif npcHandler.topic[cid] == 32 then + npcHandler:say("Excellent! Well this concludes the test. Now let us see your {results}.", cid) + player:setStorageValue(Storage.BigfootBurden.Test, player:getStorageValue(Storage.BigfootBurden.Test) + 7) + npcHandler.topic[cid] = npcHandler.topic[cid] + 1 + else + if npcHandler.topic[cid] < 33 then + npcHandler:say("Wrong answer!", cid) + npcHandler.topic[cid] = npcHandler.topic[cid] + 1 + if npcHandler.topic[cid] >= 33 then + npcHandler:say("Stop it! The test is over, you can ask me for your {results}.", cid) + end + end + end + end + end + -- TEST + + elseif msgcontains(msg, "result") then + if npcHandler.topic[cid] == 33 then + if player:getStorageValue(Storage.BigfootBurden.Test) < 100 then + player:setStorageValue(Storage.BigfootBurden.NeedsBeer, 1) + npcHandler:say({ + "You have failed the test with " .. player:getStorageValue(Storage.BigfootBurden.Test) .. " of 112 possible points. You probably were just too nervous. ...", + "I suggest you relax a bit with a fresh mushroom beer and we'll start over after that. Gnominus sells some beer. You should find him somewhere in the central chamber." + }, cid) + else + npcHandler:say("You have passed the test with " .. player:getStorageValue(Storage.BigfootBurden.Test) .. " of 112 possible points. Congratulations. You are ready to proceed with the more physical parts of your examination! Go and talk to Gnomespector about it.", cid) + player:setStorageValue(Storage.BigfootBurden.QuestLine, 6) + end + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Excellent! Now let us begin with the gnomish aptitude test. Just tell me when you feel ready for the {test}!", cid) + player:setStorageValue(Storage.BigfootBurden.QuestLine, 5) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnomerrow.lua b/data/npc/scripts/gnomerrow.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/gnomerrow.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnomespector.lua b/data/npc/scripts/gnomespector.lua new file mode 100644 index 00000000000..4021b9709d2 --- /dev/null +++ b/data/npc/scripts/gnomespector.lua @@ -0,0 +1,45 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if not player then + return false + end + + if msgcontains(msg, "recruit") then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) == 6 then + npcHandler:say({ + "Your examination is quite easy. Just step through the green crystal {apparatus} in the south! We will examine you with what we call g-rays. Where g stands for gnome of course ...", + "Afterwards walk up to Gnomedix for your ear examination." + }, cid) + player:setStorageValue(Storage.BigfootBurden.QuestLine, 8) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "apparatus") and npcHandler.topic[cid] == 1 then + npcHandler:say("Don't be afraid. It won't hurt! Just step in!", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnomette.lua b/data/npc/scripts/gnomette.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/gnomette.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnomewart.lua b/data/npc/scripts/gnomewart.lua new file mode 100644 index 00000000000..640d2b44568 --- /dev/null +++ b/data/npc/scripts/gnomewart.lua @@ -0,0 +1,47 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "endurance") then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) == 15 then + npcHandler:say({ + "Ah, the test is a piece of mushroomcake! Just take the teleporter over there in the south and follow the hallway. ...", + "You'll need to run quite a bit. It is important that you don't give up! Just keep running and running and running and ... I guess you got the idea. ...", + "At the end of the hallway you'll find a teleporter. Step on it and you are done! I'm sure you'll do a true gnomerun! Afterwards talk to me." + }, cid) + player:setStorageValue(Storage.BigfootBurden.QuestLine, 17) + elseif player:getStorageValue(Storage.BigfootBurden.QuestLine) == 17 then + npcHandler:say("Just take the teleporter over there to the south and follow the hallway. At the end of the hallway you'll find a teleporter. Step on it and you are done!", cid) + elseif player:getStorageValue(Storage.BigfootBurden.QuestLine) == 18 then + npcHandler:say("You have passed the test and are ready to create your soul melody. Talk to Gnomelvis in the east about it.", cid) + player:setStorageValue(Storage.BigfootBurden.QuestLine, 19) + elseif player:getStorageValue(Storage.BigfootBurden.QuestLine) < 15 then + npcHandler:say("Your endurance will be tested here when the time comes. For the moment please continue with the other phases of your recruitment.", cid) + elseif player:getStorageValue(Storage.BigfootBurden.QuestLine) >= 19 then + npcHandler:say("You have passed the test. If you consider what huge feet you have to move it's quite impressive.", cid) + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnomilly.lua b/data/npc/scripts/gnomilly.lua new file mode 100644 index 00000000000..d60b22c9096 --- /dev/null +++ b/data/npc/scripts/gnomilly.lua @@ -0,0 +1,247 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) +local talkState = {} +local levels = {25, 49} + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, 'job') then + return npcHandler:say('I\'m the officer responsible for this area. I give out missions, accept mission reports and oversee our defences.', cid) + end + + if msgcontains(msg, 'gnome') then + return npcHandler:say('We are the only protectors of the world against the enemies below. With small stature comes great responsibilities, as they say.', cid) + end + + if msgcontains(msg, 'area') then + return npcHandler:say({ + "On these levels we found evidence of some monumental battle that has taken place here centuries ago. We also found some grave sites, but oddly enough no clues of any form of settlement. ...", + "Some evidence we have found suggests that at least one of the battles here was fought for many, many years. People came here, lived here, fought here and died here. ...", + "The battles continued until someone or something literally ploughed through the battlefields, turning everything upside down. All this killing and death soaked the area with negative energy. ...", + "Necromantic forces are running wild all over the place and we are hard-pressed to drive all these undead, spirits and ghosts, away from the Spike. ...", + "Unless we can secure that area somehow, the Spike operation is threatened to become crippled by the constant attacks of the undead. ...", + "The whole growing downwards could come to a halt, leaving us exposed to even more attacks, counter attacks, and giving the enemy time to prepare their defences. There's a lot to do for aspiring adventurers." + }, cid) + end + + if msgcontains(msg, 'mission') then + if player:getLevel() > levels[2] then + npcHandler:say('Sorry, but no! Your expertise could be put to better use elsewhere. Here awaits you no challenge. You are desperately needed in the deeper levels of the Spike. Report there immediately. ', cid) + else + npcHandler:say('I can offer you several missions: to recharge our ghost {pacifiers}, to {release} the spiritual anger, to {track} an evil presence and to {kill} some demon skeletons.', cid) + end + return + end + + if msgcontains(msg, 'report') then + talkState[cid] = 'report' + return npcHandler:say('What mission do you want to report about: recharging the ghost {pacifiers}, the {release} of the spiritual anger, about {tracking} an evil presence and the {killing} of demon skeletons?', cid) + end + + if talkState[cid] == 'report' then + if msgcontains(msg, 'pacifiers') then + if player:getStorageValue(SPIKE_UPPER_PACIFIER_MAIN) == -1 then + npcHandler:say('You have not started that mission.', cid) + elseif player:getStorageValue(SPIKE_UPPER_PACIFIER_MAIN) == 7 then + npcHandler:say('You have done well. Here, take your reward.', cid) + player:addFamePoint() + player:addExperience(1000, true) + player:setStorageValue(SPIKE_UPPER_PACIFIER_MAIN, -1) + player:setStorageValue(SPIKE_UPPER_PACIFIER_DAILY, 86400) + else + npcHandler:say('Gnowful! Take the resonance charger and use it on seven of the pacifiers in the cave.', cid) + end + elseif msgcontains(msg, 'release') then + if player:getStorageValue(SPIKE_UPPER_MOUND_MAIN) == -1 then + npcHandler:say('You have not started that mission.', cid) + elseif player:getStorageValue(SPIKE_UPPER_MOUND_MAIN) == 4 then + npcHandler:say('You have done well. Here, take your reward.', cid) + player:addFamePoint() + player:addExperience(1000, true) + player:setStorageValue(SPIKE_UPPER_MOUND_MAIN, -1) + player:setStorageValue(SPIKE_UPPER_MOUND_DAILY, 86400) + else + npcHandler:say('Gnowful! Take the spirit shovel use it on four graves in the cave system.', cid) + end + elseif msgcontains(msg, 'tracking') then + if player:getStorageValue(SPIKE_UPPER_TRACK_MAIN) == -1 then + npcHandler:say('You have not started that mission.', cid) + elseif player:getStorageValue(SPIKE_UPPER_TRACK_MAIN) == 3 then + npcHandler:say('You have done well. Here, take your reward.', cid) + player:addFamePoint() + player:addExperience(1000, true) + player:setStorageValue(SPIKE_UPPER_TRACK_MAIN, -1) + player:setStorageValue(SPIKE_UPPER_TRACK_DAILY, 86400) + else + npcHandler:say('Gnowful! Take the tracking device in the caves and locate the residual spirit energy.', cid) + end + elseif msgcontains(msg, 'killing') then + if player:getStorageValue(SPIKE_UPPER_KILL_MAIN) == -1 then + npcHandler:say('You have not started that mission.', cid) + elseif player:getStorageValue(SPIKE_UPPER_KILL_MAIN) == 7 then + npcHandler:say('You have done well. Here, take your reward.', cid) + player:addFamePoint() + player:addExperience(1000, true) + player:setStorageValue(SPIKE_UPPER_KILL_MAIN, -1) + player:setStorageValue(SPIKE_UPPER_KILL_DAILY, 86400) + else + npcHandler:say('Gnowful! Just go out to the caves and kill at least seven demon skeletons.', cid) + end + else + npcHandler:say('That\'s not a valid mission name.', cid) + end + talkState[cid] = nil + return + end + + --[[/////////////////// + ////GHOST PACIFIERS//// + /////////////////////]] + if msgcontains(msg, 'pacifiers') then + if player:getStorageValue(SPIKE_UPPER_PACIFIER_DAILY) >= os.time() then + return npcHandler:say('Sorry, you have to wait ' .. string.diff(player:getStorageValue(SPIKE_UPPER_PACIFIER_DAILY)-os.time()) .. ' before this task gets available again.', cid) + end + + if (player:getLevel() < levels[1]) or (player:getLevel() > levels[2]) then + return npcHandler:say('Sorry, you are not on the required range of levels [' .. levels[1] ..'-' .. levels[2] ..'].', cid) + end + + if player:getStorageValue(SPIKE_UPPER_PACIFIER_MAIN) == -1 then + npcHandler:say({'We need you to recharge our ghost pacifiers. They are placed at several strategic points in the caves around us and should be easy to find. Your mission would be to charge seven of them.', 'If you are interested, I can give you some more {information} about it. Are you willing to accept this mission?'}, cid) + talkState[cid] = 'pacifiers' + else + npcHandler:say('You have already started that mission.', cid) + end + end + + if talkState[cid] == 'pacifiers' then + if msgcontains(msg, 'yes') then + player:addItem(21554, 1) + player:setStorageValue(SPIKE_UPPER_PACIFIER_MAIN, 0) + npcHandler:say('Gnometastic! Take this resonance charger and use it on seven of the pacifiers in the cave. If you lose the charger, you\'ll have to bring your own. Gnomux sells all the equipment that is required for our missions.', cid) + talkState[cid] = nil + elseif msgcontains(msg, 'no') then + npcHandler:say('Ok then.', cid) + talkState[cid] = nil + end + end + + --[[/////////////////// + ////SPIRIT RELEASE///// + /////////////////////]] + if msgcontains(msg, 'release') then + if player:getStorageValue(SPIKE_UPPER_MOUND_DAILY) >= os.time() then + return npcHandler:say('Sorry, you have to wait ' .. string.diff(player:getStorageValue(SPIKE_UPPER_MOUND_DAILY)-os.time()) .. ' before this task gets available again.', cid) + end + + if (player:getLevel() < levels[1]) or (player:getLevel() > levels[2]) then + return npcHandler:say('Sorry, you are not on the required range of levels [' .. levels[1] ..'-' .. levels[2] ..'].', cid) + end + + if player:getStorageValue(SPIKE_UPPER_MOUND_MAIN) == -1 then + npcHandler:say('Your task would be to use a spirit shovel to release some spirit\'s anger from graves that can be found all around here. If you are interested, I can give you some more information about it. Are you willing to accept this mission?', cid) + talkState[cid] = 'release' + else + npcHandler:say('You have already started that mission.', cid) + end + end + + if talkState[cid] == 'release' then + if msgcontains(msg, 'yes') then + player:addItem(21553, 1) + player:setStorageValue(SPIKE_UPPER_MOUND_MAIN, 0) + npcHandler:say('Gnometastic! Take this spirit shovel and use it on four graves in the cave system. If you lose the shovel you\'ll have to bring your own. Gnomux sells all the equipment that is required for our missions.', cid) + talkState[cid] = nil + elseif msgcontains(msg, 'no') then + npcHandler:say('Ok then.', cid) + talkState[cid] = nil + end + end + + --[[///////////////// + ////TRACK GHOSTS///// + ///////////////////]] + if msgcontains(msg, 'track') then + if player:getStorageValue(SPIKE_UPPER_TRACK_DAILY) >= os.time() then + return npcHandler:say('Sorry, you have to wait ' .. string.diff(player:getStorageValue(SPIKE_UPPER_TRACK_DAILY)-os.time()) .. ' before this task gets available again.', cid) + end + + if (player:getLevel() < levels[1]) or (player:getLevel() > levels[2]) then + return npcHandler:say('Sorry, you are not on the required range of levels [' .. levels[1] ..'-' .. levels[2] ..'].', cid) + end + + if player:getStorageValue(SPIKE_UPPER_TRACK_MAIN) == -1 then + npcHandler:say({'You\'d be given the highly important task to track down an enormously malevolent spiritual presence in the cave system. Use your tracking device to find out how close you are to the presence.','Use that information to find the residual energy and use the tracker there. If you are interested, I can give you some more information about it. Are you willing to accept this mission?'}, cid) + talkState[cid] = 'track' + else + npcHandler:say('You have already started that mission.', cid) + end + end + + if talkState[cid] == 'track' then + if msgcontains(msg, 'yes') then + GHOST_DETECTOR_MAP[player:getGuid()] = Position.getFreeSand() + player:addItem(21555, 1) + player:setStorageValue(SPIKE_UPPER_TRACK_MAIN, 0) + npcHandler:say('Gnometastic! Use this tracking device in the caves and locate the residual spirit energy. If you lose the tracking device, you\'ll have to bring your own. Gnomux sells all the equipment that is required for our missions.', cid) + talkState[cid] = nil + elseif msgcontains(msg, 'no') then + npcHandler:say('Ok then.', cid) + talkState[cid] = nil + end + end + + --[[///////// + ////KILL///// + ///////////]] + if msgcontains(msg, 'kill') then + if player:getStorageValue(SPIKE_UPPER_KILL_DAILY) >= os.time() then + return npcHandler:say('Sorry, you have to wait ' .. string.diff(player:getStorageValue(SPIKE_UPPER_KILL_DAILY)-os.time()) .. ' before this task gets available again.', cid) + end + + if (player:getLevel() < levels[1]) or (player:getLevel() > levels[2]) then + return npcHandler:say('Sorry, you are not on the required range of levels [' .. levels[1] ..'-' .. levels[2] ..'].', cid) + end + + if player:getStorageValue(SPIKE_UPPER_KILL_MAIN) == -1 then + npcHandler:say('We need someone to reduce the steadily growing number of demon skeletons in the caves. If you are interested, I can give you some more information about it. Are you willing to accept this mission?', cid) + talkState[cid] = 'kill' + else + npcHandler:say('You have already started that mission.', cid) + end + end + + if talkState[cid] == 'kill' then + if msgcontains(msg, 'yes') then + player:setStorageValue(SPIKE_UPPER_KILL_MAIN, 0) + npcHandler:say('Gnometastic! Just go out and kill them. You should find more of them than you like.', cid) + talkState[cid] = nil + elseif msgcontains(msg, 'no') then + npcHandler:say('Ok then.', cid) + talkState[cid] = nil + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnomincia.lua b/data/npc/scripts/gnomincia.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/gnomincia.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnominus.lua b/data/npc/scripts/gnominus.lua new file mode 100644 index 00000000000..b3421e36852 --- /dev/null +++ b/data/npc/scripts/gnominus.lua @@ -0,0 +1,63 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- transcript for buying fresh mushroom beer is probably wrong except for the case where you buy it +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, 'recruitment') then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) == 3 then + npcHandler:say('Your examination is quite easy. Just step through the green crystal apparatus in the south! We will examine you with what we call g-rays. Where g stands for gnome of course ...', cid) + npcHandler:say('Afterwards walk up to Gnomedix for your ear examination.', cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, 'tavern') then + npcHandler:say('I provide the population with some fresh alcohol-free mushroom {beer}!', cid) + elseif msgcontains(msg, 'beer') then + npcHandler:say('Do you want some mushroom beer for 10 gold?', cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, 'apparatus') then + npcHandler:say('Don\'t be afraid. It won\'t hurt! Just step in!', cid) + player:setStorageValue(Storage.BigfootBurden.QuestLine, 4) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, 'yes') then + if player:getMoney() + player:getBankBalance() >= 10 then + npcHandler:say('And here it is! Drink it quick, it gets stale quite fast!', cid) + player:removeMoneyNpc(10) + local beerItem = player:addItem(18305) + if beerItem then + beerItem:decay() + end + else + npcHandler:say('You do not have enough money.', cid) + end + else + npcHandler:say('Come back later.', cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, 'Hi there! Welcome to my little {tavern}.') +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnomission.lua b/data/npc/scripts/gnomission.lua new file mode 100644 index 00000000000..2975bbf2b4f --- /dev/null +++ b/data/npc/scripts/gnomission.lua @@ -0,0 +1,133 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if(not npcHandler:isFocused(cid)) then + return false + end + local player = Player(cid) + + if(msgcontains(msg, "warzones")) then + npcHandler:say({ + "There are three warzones. In each warzone you will find fearsome foes. At the end you'll find their mean master. The masters is well protected though. ...", + "Make sure to talk to our gnomish agent in there for specifics of its' protection. ...", + "Oh, and to be able to enter the second warzone you have to best the first. To enter the third you have to best the second. ...", + "And you can enter each one only once every twenty hours. Your normal teleport crystals won't work on these teleporters. You will have to get mission crystals from Gnomally." + }, cid) + npcHandler.topic[cid] = 1 + elseif(msgcontains(msg, "job")) then + npcHandler:say("I am responsible for our war {missions}, to {trade} with seasoned soldiers and rewarding war {heroes}. You have to be rank 4 to enter the {warzones}.", cid) + npcHandler.topic[cid] = 2 + elseif(msgcontains(msg, "heroes")) then + if npcHandler.topic[cid] == 2 then + npcHandler:say({ + "You can trade special spoils of war to get a permission to use the war teleporters to the area of the corresponding boss without need of mission crystals. ...", + "Which one would you like to trade: the deathstrike's {snippet}, gnomevil's {hat} or the abyssador {lash}?" + }, cid) + npcHandler.topic[cid] = 3 + end + elseif(msgcontains(msg, "snippet")) then + if npcHandler.topic[cid] == 3 then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) < 30 then + npcHandler:say("It seems you did not even set one big foot into the warzone, I am sorry.") + else + if player:getStorageValue(Storage.BigfootBurden.Warzone1Access) < 1 then + if player:removeItem(18430, 1) then + player:setStorageValue(Storage.BigfootBurden.Warzone1Access, 1) + npcHandler:say("As a war hero you are allowed to use the warzone teleporter one for free!", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("I can't let you enter the warzone teleporter one for free, unless you handle me a Deathstrike's snippet. But can still always use a red teleport crystal.", cid) + end + else + npcHandler:say("We've already talked about that.", cid) + end + end + end + elseif(msgcontains(msg, "lash")) then + if npcHandler.topic[cid] == 3 then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) < 30 then + npcHandler:say("It seems you did not even set one big foot into the warzone, I am sorry.") + else + if player:getStorageValue(Storage.BigfootBurden.Warzone3Access) < 1 then + if player:getStorageValue(Storage.BigfootBurden.WarzoneStatus) >= 3 then + if player:removeItem(18496, 1) then + player:setStorageValue(Storage.BigfootBurden.Warzone3Access, 1) + npcHandler:say("As a war hero you are allowed to use the warzone teleporter three for free!", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("I can't let you enter the warzone teleporter two for free, unless you handle me an Abyssador's lash. But can still always use a red teleport crystal.", cid) + end + else + npcHandler:say("You need to defeat the first warzone boss to be able to get free access to the second warzone.", cid) + end + else + npcHandler:say("We've already talked about that.", cid) + end + end + end + elseif(msgcontains(msg, "hat")) then + if npcHandler.topic[cid] == 3 then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) < 30 then + npcHandler:say("It seems you did not even set one big foot into the warzone, I am sorry.") + else + if player:getStorageValue(Storage.BigfootBurden.Warzone2Access) < 1 then + if player:getStorageValue(Storage.BigfootBurden.WarzoneStatus) >= 2 then + if player:removeItem(18495, 1) then + player:setStorageValue(Storage.BigfootBurden.Warzone2Access, 1) + npcHandler:say("As a war hero you are allowed to use the warzone teleporter second for free!", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("I can't let you enter the warzone teleporter three for free, unless you handle me a Gnomevil's hat. But can still always use a red teleport crystal.", cid) + end + else + npcHandler:say("You need to defeat the second warzone boss to be able to get free access to the third warzone.", cid) + end + else + npcHandler:say("We've already talked about that.", cid) + end + end + end + elseif(msgcontains(msg, "mission")) then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) >= 30 then + if player:getStorageValue(Storage.BigfootBurden.WarzoneStatus) < 1 then + npcHandler:say("Fine, I grant you the permission to enter the warzones. Be warned though, this will be not a picnic. Better bring some friends with you. Bringing a lot of them sounds like a good idea.", cid) + player:setStorageValue(Storage.BigfootBurden.WarzoneStatus, 1) + else + npcHandler:say("You have already accepted this mission.", cid) + end + npcHandler.topic[cid] = 0 + else + npcHandler:say("Sorry, you have not yet earned enough renown that we would risk your life in such a dangerous mission.", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +local function onTradeRequest(cid) + if Player(cid):getStorageValue(Storage.BigfootBurden.BossKills) < 20 then + npcHandler:say('Only if you have killed 20 of our major enemies in the warzones I am allowed to trade with you.', cid) + return false + end + + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setCallback(CALLBACK_ONTRADEREQUEST, onTradeRequest) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnommander.lua b/data/npc/scripts/gnommander.lua new file mode 100644 index 00000000000..a4694862364 --- /dev/null +++ b/data/npc/scripts/gnommander.lua @@ -0,0 +1,147 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) +local talkState = {} +local speech = { + "I'm the operating commander of the Spike, the latest great accomplishment of the gnomish race.", + "The Spike is a crystal structure, created by our greatest crystal experts. It has grown from a crystal the size of my fist to the structure you see here and now.", + "Of course this did not happen from one day to the other. It's the fruit of the work of several gnomish generations. Its purpose has changed in the course of time.", + "At first it was conceived as a fast growing resource node. Then it was planned to become the prototype of a new type of high security base.", + "Now it has become a military base and a weapon. With our foes occupied elsewhere, we can prepare our strike into the depths of the earth.", + "This crystal can withstand extreme pressure and temperature, and it's growing deeper and deeper even as we speak.", + "The times of the fastest growth have come to an end, however, and we have to slow down in order not to risk the structural integrity of the Spike. But we are on our way and have to do everything possible to defend the Spike." +} + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, 'commander') then + return npcHandler:say('I\'m responsible for the security and reward heroes to our cause. If you are looking for missions, talk to Gnomilly, Gnombold and Gnomagery.', cid) + end + + if msgcontains(msg, 'reward') then + return npcHandler:say('I can sell special outfit parts. If your fame is high enough, you might be {worthy} of such a reward.', cid) + end + + if msgcontains(msg, 'spike') then + return npcHandler:say(speech, cid) + end + + if msgcontains(msg, 'worthy') then + if player:getFamePoints() < 100 then + return npcHandler:say('You are not worthy of a special reward yet.', cid) + end + + talkState[cid] = 'worthy' + return npcHandler:say('You can acquire the {basic} outfit for 1000 Gold, the {first} addon for 2000 gold and the {second} addon for 3000 gold. Which do you want to buy?', cid) + end + + if talkState[cid] == 'worthy' then + if msgcontains(msg, 'basic') then + if getPlayerLevel(cid) < 25 then + talkState[cid] = nil + return npcHandler:say('You do not have enough level yet.', cid) + end + + if player:hasOutfit(player:getSex() == 0 and 575 or 574) then + talkState[cid] = nil + return npcHandler:say('You already have that outfit.', cid) + end + + talkState[cid] = 'basic' + return npcHandler:say('Do you want to buy the basic outfit for 1000 Gold?', cid) + elseif msgcontains(msg, 'first') then + if getPlayerLevel(cid) < 50 then + talkState[cid] = nil + return npcHandler:say('You do not have enough level yet.', cid) + end + + if not player:hasOutfit(player:getSex() == 0 and 575 or 574) then + talkState[cid] = nil + return npcHandler:say('You do not have the Cave Explorer outfit.', cid) + end + + if player:hasOutfit(player:getSex() == 0 and 575 or 574, 1) then + talkState[cid] = nil + return npcHandler:say('You already have that addon.', cid) + end + + talkState[cid] = 'first' + return npcHandler:say('Do you want to buy the first addon for 2000 Gold?', cid) + elseif msgcontains(msg, 'second') then + if getPlayerLevel(cid) < 80 then + talkState[cid] = nil + return npcHandler:say('You do not have enough level yet.', cid) + end + + if not player:hasOutfit(player:getSex() == 0 and 575 or 574) then + talkState[cid] = nil + return npcHandler:say('You do not have the Cave Explorer outfit.', cid) + end + + if player:hasOutfit(player:getSex() == 0 and 575 or 574, 2) then + talkState[cid] = nil + return npcHandler:say('You already have that addon.', cid) + end + + talkState[cid] = 'second' + return npcHandler:say('Do you want to buy the second addon for 3000 Gold?', cid) + end + end + + if talkState[cid] == 'basic' then + if msgcontains(msg, 'yes') then + if not player:removeMoney(1000) then + talkState[cid] = nil + return npcHandler:say('You do not have that money.', cid) + end + end + player:removeFamePoints(100) + player:addOutfit(player:getSex() == 0 and 575 or 574) + talkState[cid] = nil + return npcHandler:say('Here it is.', cid) + elseif talkState[cid] == 'first' then + if msgcontains(msg, 'yes') then + if not player:removeMoney(2000) then + talkState[cid] = nil + return npcHandler:say('You do not have that money.', cid) + end + end + player:removeFamePoints(100) + player:addOutfitAddon(player:getSex() == 0 and 575 or 574, 1) + talkState[cid] = nil + return npcHandler:say('Here it is.', cid) + elseif talkState[cid] == 'second' then + if msgcontains(msg, 'yes') then + if not player:removeMoney(3000) then + talkState[cid] = nil + return npcHandler:say('You do not have that money.', cid) + end + end + player:removeFamePoints(100) + player:addOutfitAddon(player:getSex() == 0 and 575 or 574, 2) + talkState[cid] = nil + return npcHandler:say('Here it is.', cid) + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnomole.lua b/data/npc/scripts/gnomole.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/gnomole.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnomus.lua b/data/npc/scripts/gnomus.lua new file mode 100644 index 00000000000..71b66cd3210 --- /dev/null +++ b/data/npc/scripts/gnomus.lua @@ -0,0 +1,317 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local playerTopic = {} +local quantidade = {} + +local function greetCallback(cid) + local player = Player(cid) + if player then + npcHandler:setMessage(MESSAGE_GREET, {"Greetings, member of the Bigfoot Brigade. We could really use some {help} from you right now. You should prove {worthy} to our alliance."}) + playerTopic[cid] = 1 + end + npcHandler:addFocus(cid) + return true +end + +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'If you\'re willing to help us, we could need an escort for arriving {ordnance}, help with {charting} the cave system and someone needs to get some heat {measurements} fast.'}) +keywordHandler:addKeyword({'worthy'}, StdModule.say, {npcHandler = npcHandler, text = {'You\'re already known amongst the gnomes, member of the Bigfoot Brigade. I will make sure that the alliance learns of your deeds but you\'ll still need to help the dwarves and gnomes of this outpost to show your worth. ...', + 'We also found {suspicious devices} carried by all kinds of creatures down here. Down here, they are of extreme worth to us since they could contain the key to what\'s happening all around us. ...', + 'If you can aquire any, return them to me and I make sure to tell the others of your generosity. Return to me afterwards to check on your current {status}.'}}) +keywordHandler:addKeyword({'base'}, StdModule.say, {npcHandler = npcHandler, text = {'Gnomish supplies and ingenuity have helped to establish and fortify this outpost. ...', + 'Our knowledge of the enemy and it\'s tactics would be of more use if the dwarves would listen to us somewhat more. But gnomes have learned to live with the imperfection of the other races.'}}) +keywordHandler:addKeyword({'efforts'}, StdModule.say, {npcHandler = npcHandler, text = {'Our surveys of the area showed us some spikes in heat and seismic activity at very specific places. ...', + 'We conclude this is no coincidence and the enemy is using devices to pump up the lava to flood the area. We have seen it before and had to retreat each time. ...', + 'This time though we might have a counter prepared - given me manage to pierce their defences.'}}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Gnomus.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m the main gnomish contact for this base. I coordinate our efforts with those of the dwarves to ensure everything is running smoothly.'}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + npcHandler.topic[cid] = playerTopic[cid] + local player = Player(cid) + npc = Npc(cid) + + local tempo = 20*60*60 + + -- missão measurements + if msgcontains(msg, "measurements") and npcHandler.topic[cid] == 1 then + if player:getStorageValue(Storage.DangerousDepths.Gnomes.Measurements ) == 2 and player:getStorageValue(Storage.DangerousDepths.Gnomes.TimeTaskMeasurements) > 0 then -- Ainda não se passaram as 20h + npcHandler:say({"I don't need your help for now. Come back later."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + if player:getStorageValue(Storage.DangerousDepths.Gnomes.Measurements) == 2 and player:getStorageValue(Storage.DangerousDepths.Gnomes.TimeTaskMeasurements) <= 0 then -- Vai fazer a missão após 20h + npcHandler:say({"The heat down here is not the only problem we have but one of our greatest concerns. Not only is it almost unbearable for us, it also seems to be rising. ...", + "We need to find out if this is true and what that means for this place - and for us gnomes. You can help us do this by grabbing one of our trignometres and collecting as much as data from the heat in this area as possible. ...", + "We'd need at least 5 measurements. Are you willing to do this?"}, cid) + playerTopic[cid] = 2 + npcHandler.topic[cid] = 2 + end + if player:getStorageValue(Storage.DangerousDepths.Gnomes.Measurements) < 1 then -- Não possuía a missão, agora possui! + npcHandler:say({"The heat down here is not the only problem we have but one of our greatest concerns. Not only is it almost unbearable for us, it also seems to be rising. ...", + "We need to find out if this is true and what that means for this place - and for us gnomes. You can help us do this by grabbing one of our trignometres and collecting as much as data from the heat in this area as possible. ...", + "We'd need at least 5 measurements. Are you willing to do this?"}, cid) + playerTopic[cid] = 2 + npcHandler.topic[cid] = 2 + elseif (player:getStorageValue(Storage.DangerousDepths.Gnomes.Measurements) == 1) and (player:getStorageValue(Storage.DangerousDepths.Gnomes.LocationCount) < 5) then -- Está na missão porém não terminou a task! + npcHandler:say({"Come back when you have finished your job."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.DangerousDepths.Gnomes.Measurements) == 1 and player:getStorageValue(Storage.DangerousDepths.Gnomes.LocationCount) == 5 then -- Não possuía a missão, agora possui! + npcHandler:say({"Excellent, you returned with more data! Let me see... hmm. ...", + "Well, we need more data on this but first I will have to show this to our grand horticulturist. Thank you for getting this for us!"}, cid) + player:setStorageValue(Storage.DangerousDepths.Gnomes.TimeTaskMeasurements, os.time() + tempo) + player:addItem(32014, 1) + player:setStorageValue(Storage.DangerousDepths.Gnomes.Status, player:getStorageValue(Storage.DangerousDepths.Gnomes.Status) + 1) + player:setStorageValue(Storage.DangerousDepths.Gnomes.Measurements, 2) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + elseif npcHandler.topic[cid] == 2 and msgcontains(msg, "yes") then + npcHandler:say({"How fortunate! There are some trignometres lying around next to that device behind me. Take one and hold it next to high temperature heat sources. ...", + "If you gathered enough data, you will actually smell it from the device. ...", + "Return to me with the results afterwards. Best of luck, we count on you!"}, cid) + if player:getStorageValue(Storage.DangerousDepths.Questline) < 1 then + player:setStorageValue(Storage.DangerousDepths.Questline, 1) + end + player:setStorageValue(Storage.DangerousDepths.Gnomes.Measurements, 1) + player:setStorageValue(Storage.DangerousDepths.Gnomes.GnomeChartChest, 1) -- Permissão para usar o baú + player:setStorageValue(Storage.DangerousDepths.Gnomes.LocationCount, 0) -- Garantindo que a task não inicie com -1 + player:setStorageValue(Storage.DangerousDepths.Gnomes.LocationA, 0) -- Garantindo que a task não inicie com -1 + player:setStorageValue(Storage.DangerousDepths.Gnomes.LocationB, 0) -- Garantindo que a task não inicie com -1 + player:setStorageValue(Storage.DangerousDepths.Gnomes.LocationC, 0) -- Garantindo que a task não inicie com -1 + player:setStorageValue(Storage.DangerousDepths.Gnomes.LocationD, 0) -- Garantindo que a task não inicie com -1 + player:setStorageValue(Storage.DangerousDepths.Gnomes.LocationE, 0) -- Garantindo que a task não inicie com -1 + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + + -- missão ordnance + if msgcontains(msg, "ordnance") and npcHandler.topic[cid] == 1 then + if player:getStorageValue(Storage.DangerousDepths.Gnomes.Ordnance) == 3 and player:getStorageValue(Storage.DangerousDepths.Gnomes.TimeTaskOrdnance) > 0 then -- Ainda não se passaram as 20h + npcHandler:say({"I don't need your help for now. Come back later."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + if player:getStorageValue(Storage.DangerousDepths.Gnomes.Ordnance) == 3 and player:getStorageValue(Storage.DangerousDepths.Gnomes.TimeTaskOrdnance) <= 0 then -- Vai fazer a missão após 20h + npcHandler:say({"I am constantly waiting for ordnance to arrive. A lot of gnomes intend to travel out here to help us but the main access path to our base is not safe anymore. ...", + "Tragically we lost several gnomes after an outbreak of what I can only describe as a force from below. We were completely surprised by their onslaught and retreated to this outpost. ...", + "All our reinforcements arrive at the crystal teleporter to the east of the cave system. We need someone to navigate the new arrivals through the hazards of the dangerous caves. ...", + "Hideous creatures and hot lava makes travelling extremely dangerous. And on top of that there is also the constant danger from falling rocks in the area. ...", + "Are you willing to help?"}, cid) + playerTopic[cid] = 22 + npcHandler.topic[cid] = 22 + end + if player:getStorageValue(Storage.DangerousDepths.Gnomes.Ordnance) < 1 then -- Não possuía a missão, agora possui! + npcHandler:say({"I am constantly waiting for ordnance to arrive. A lot of gnomes intend to travel out here to help us but the main access path to our base is not safe anymore. ...", + "Tragically we lost several gnomes after an outbreak of what I can only describe as a force from below. We were completely surprised by their onslaught and retreated to this outpost. ...", + "All our reinforcements arrive at the crystal teleporter to the east of the cave system. We need someone to navigate the new arrivals through the hazards of the dangerous caves. ...", + "Hideous creatures and hot lava makes travelling extremely dangerous. And on top of that there is also the constant danger from falling rocks in the area. ...", + "Are you willing to help?"}, cid) + playerTopic[cid] = 22 + npcHandler.topic[cid] = 22 + elseif (player:getStorageValue(Storage.DangerousDepths.Gnomes.Ordnance) == 1) or (player:getStorageValue(Storage.DangerousDepths.Gnomes.Ordnance) == 2 and player:getStorageValue(Storage.DangerousDepths.Gnomes.GnomesCount) < 5) then -- Está na missão porém não terminou a task! + npcHandler:say({"Come back when you have finished your job."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.DangerousDepths.Gnomes.Ordnance) == 2 and player:getStorageValue(Storage.DangerousDepths.Gnomes.GnomesCount) >= 5 then -- Não possuía a missão, agora possui! + if player:getStorageValue(Storage.DangerousDepths.Gnomes.CrawlersCount) >= 3 then + npcHandler:say({"AMAZING! Not only did you salve all our friends - you also rescued the animals! Here is your reward and bonus! ...", + "The other are already telling stories about you. Please return to me later if you want to help out some more!"}, cid) + player:setStorageValue(Storage.DangerousDepths.Gnomes.TimeTaskOrdnance, os.time() + tempo) + player:addItem(32014, 2) + player:setStorageValue(Storage.DangerousDepths.Gnomes.Status, player:getStorageValue(Storage.DangerousDepths.Gnomes.Status) + 2) + player:setStorageValue(Storage.DangerousDepths.Gnomes.Ordnance, 3) + else + npcHandler:say({"The other are already telling stories about you. Please return to me later if you want to help out some more!"}, cid) + player:setStorageValue(Storage.DangerousDepths.Gnomes.TimeTaskOrdnance, os.time() + tempo) + player:addItem(32014, 1) + player:setStorageValue(Storage.DangerousDepths.Gnomes.Status, player:getStorageValue(Storage.DangerousDepths.Gnomes.Status) + 1) + player:setStorageValue(Storage.DangerousDepths.Gnomes.Ordnance, 3) + end + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + elseif npcHandler.topic[cid] == 22 and msgcontains(msg, "yes") then + npcHandler:say({"Excellent, just follow the path to east until you reach a dead end, there is a hole that leads to a small cave underneath which will bring you right to the old trail. ...", + "Help whoever you can and return them to the save cave exit - oh, and while you're at it... some of them will have pack animals. If you can rescue those as well, I'll hand you a bonus. Good luck!"}, cid) + if player:getStorageValue(Storage.DangerousDepths.Questline) < 1 then + player:setStorageValue(Storage.DangerousDepths.Questline, 1) + end + player:setStorageValue(Storage.DangerousDepths.Gnomes.Ordnance, 1) + player:setStorageValue(Storage.DangerousDepths.Gnomes.GnomesCount, 0) -- Garantindo que a task não inicie com -1 + player:setStorageValue(Storage.DangerousDepths.Gnomes.CrawlersCount, 0) -- Garantindo que a task não inicie com -1 + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + + -- missão charting + if msgcontains(msg, "charting") and npcHandler.topic[cid] == 1 then + if player:getStorageValue(Storage.DangerousDepths.Gnomes.Charting) == 2 and player:getStorageValue(Storage.DangerousDepths.Gnomes.TimeTaskCharting) > 0 then -- Ainda não se passaram as 20h + npcHandler:say({"I don't need your help for now. Come back later."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + if player:getStorageValue(Storage.DangerousDepths.Gnomes.Charting) == 2 and player:getStorageValue(Storage.DangerousDepths.Gnomes.TimeTaskCharting) <= 0 then -- Vai fazer a missão após 20h + npcHandler:say({"While exploring these caves to find places to collect spores and grow mushrooms, we found several strange structures. I am convinced that this system was once home to intelligent beings. ...", + "However, the creatures from below are now disturbing our research as well as some particularly pesky dwarves who just would not leave us alone. ...", + "As we have our hands full with a lot of things right now, we could need someone to chart the unknown parts of this underground labyrinth ...", + "I am especially interested in the scattered dark structures around these parts. Would you do that?"}, cid) + playerTopic[cid] = 33 + npcHandler.topic[cid] = 33 + end + if player:getStorageValue(Storage.DangerousDepths.Gnomes.Charting) < 1 then -- Não possuía a missão, agora possui! + npcHandler:say({"While exploring these caves to find places to collect spores and grow mushrooms, we found several strange structures. I am convinced that this system was once home to intelligent beings. ...", + "However, the creatures from below are now disturbing our research as well as some particularly pesky dwarves who just would not leave us alone. ...", + "As we have our hands full with a lot of things right now, we could need someone to chart the unknown parts of this underground labyrinth ...", + "I am especially interested in the scattered dark structures around these parts. Would you do that?"}, cid) + playerTopic[cid] = 33 + npcHandler.topic[cid] = 33 + elseif (player:getStorageValue(Storage.DangerousDepths.Gnomes.Charting) == 1) and (player:getStorageValue(Storage.DangerousDepths.Gnomes.ChartingCount) < 3) then -- Está na missão porém não terminou a task! + npcHandler:say({"Come back when you have finished your job."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + if player:getStorageValue(Storage.DangerousDepths.Gnomes.Charting) == 1 and player:getStorageValue(Storage.DangerousDepths.Gnomes.ChartingCount) >= 3 then -- Não possuía a missão, agora possui! + npcHandler:say({"Thank you very much! With those structures mapped out we will be able to complete the puzzle in no time!"}, cid) + if player:getStorageValue(Storage.DangerousDepths.Gnomes.ChartingCount) == 6 then + player:addItem(32014, 2) + player:setStorageValue(Storage.DangerousDepths.Gnomes.Status, player:getStorageValue(Storage.DangerousDepths.Gnomes.Status) + 2) + else + player:addItem(32014, 1) + player:setStorageValue(Storage.DangerousDepths.Gnomes.Status, player:getStorageValue(Storage.DangerousDepths.Gnomes.Status) + 1) + end + player:setStorageValue(Storage.DangerousDepths.Gnomes.Charting, 2) + player:setStorageValue(Storage.DangerousDepths.Gnomes.TimeTaskCharting, os.time() + tempo) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + elseif npcHandler.topic[cid] == 33 and msgcontains(msg, "yes") then + npcHandler:say({"Very good. We prepared a lot of maps as the complete mapping of this system will probably take a lot of research. ...", + "Take one from the stack here next to me and map as many structures as possible. However, we need at least three locations to make any sense of this ancient layout at all. ...", + "If you manage to map one of each structure around these parts - I assume there must be at least two times as many around here - I will hand you a bonus!"}, cid) + if player:getStorageValue(Storage.DangerousDepths.Questline) < 1 then + player:setStorageValue(Storage.DangerousDepths.Questline, 1) + end + player:setStorageValue(Storage.DangerousDepths.Gnomes.Charting, 1) + player:setStorageValue(Storage.DangerousDepths.Gnomes.ChartingCount, 0) -- Garantindo que a task não inicie com -1 + player:setStorageValue(Storage.DangerousDepths.Gnomes.GnomeChartPaper, 1) -- Permissão para usar o papel + player:setStorageValue(Storage.DangerousDepths.Gnomes.OldGate, 0) -- Garantindo que a task não inicie com -1 + player:setStorageValue(Storage.DangerousDepths.Gnomes.TheGaze, 0) -- Garantindo que a task não inicie com -1 + player:setStorageValue(Storage.DangerousDepths.Gnomes.LostRuin, 0) -- Garantindo que a task não inicie com -1 + player:setStorageValue(Storage.DangerousDepths.Gnomes.Outpost, 0) -- Garantindo que a task não inicie com -1 + player:setStorageValue(Storage.DangerousDepths.Gnomes.Bastion, 0) -- Garantindo que a task não inicie com -1 + player:setStorageValue(Storage.DangerousDepths.Gnomes.BrokenTower, 0) -- Garantindo que a task não inicie com -1 + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + + + local plural = "" + if msgcontains(msg, "suspicious devices") or msgcontains(msg, "suspicious device") then + npcHandler:say({"If you bring me any suspicious devices on creatures you slay down here, I'll make it worth your while by telling the others of your generosity. How many do you want to offer? "}, cid) + playerTopic[cid] = 55 + npcHandler.topic[cid] = 55 + elseif npcHandler.topic[cid] == 55 then + quantidade[cid] = tonumber(msg) + if quantidade[cid] then + if quantidade[cid] > 1 then + plural = plural .. "s" + end + npcHandler:say({"You want to offer " .. quantidade[cid] .. " suspicious device" ..plural.. ". Which leader shall have it, (Gnomus) of the {gnomes}, (Klom Stonecutter) of the {dwarves} or the {scouts} (Lardoc Bashsmite)?"}, cid) + playerTopic[cid] = 56 + npcHandler.topic[cid] = 56 + else + npcHandler:say({"Don't waste my time."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "gnomes") and npcHandler.topic[cid] == 56 then + if player:getItemCount(30888) >= quantidade[cid] then + npcHandler:say({"Done."}, cid) + if quantidade[cid] > 1 then + plural = plural .. "s" + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You earned ".. quantidade[cid] .." point"..plural.." on the gnomes mission.") + player:removeItem(30888, quantidade[cid]) + player:setStorageValue(Storage.DangerousDepths.Gnomes.Status, player:getStorageValue(Storage.DangerousDepths.Gnomes.Status) + quantidade[cid]) + else + npcHandler:say({"You don't have enough suspicious devices."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "dwarves") and npcHandler.topic[cid] == 56 then + if player:getItemCount(30888) >= quantidade[cid] then + npcHandler:say({"Done."}, cid) + if quantidade[cid] > 1 then + plural = plural .. "s" + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You earned ".. quantidade[cid] .." point"..plural.." on the dwarves mission.") + player:removeItem(30888, quantidade[cid]) + player:setStorageValue(Storage.DangerousDepths.Dwarves.Status, player:getStorageValue(Storage.DangerousDepths.Dwarves.Status) + quantidade[cid]) + else + npcHandler:say({"You don't have enough suspicious devices."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "scouts") and npcHandler.topic[cid] == 56 then + if player:getItemCount(30888) >= quantidade[cid] then + npcHandler:say({"Done."}, cid) + if quantidade[cid] > 1 then + plural = plural .. "s" + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You earned ".. quantidade[cid] .." point"..plural.." on the scouts mission.") + player:removeItem(30888, quantidade[cid]) + player:setStorageValue(Storage.DangerousDepths.Scouts.Status, player:getStorageValue(Storage.DangerousDepths.Scouts.Status) + quantidade[cid]) + else + npcHandler:say({"You don't have enough suspicious devices."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + end + + + + -- Início checagem de pontos de tasks!! + if msgcontains(msg, "status") then + npcHandler:say({"So you want to know what we all think about your deeds? What leader\'s opinion are you interested in, the {gnomes} (Gnomus), the {dwarves} (Klom Stonecutter) or the {scouts} (Lardoc Bashsmite)?"}, cid) + playerTopic[cid] = 5 + npcHandler.topic[cid] = 5 + elseif msgcontains(msg, "gnomes") and npcHandler.topic[cid] == 5 then + npcHandler:say({'The gnomes are still in need of your help, member of Bigfoot\'s Brigade. Prove your worth by answering their calls! (' .. math.max(player:getStorageValue(Storage.DangerousDepths.Gnomes.Status), 0) .. '/10)'}, cid) + elseif msgcontains(msg, "dwarves") and npcHandler.topic[cid] == 5 then + npcHandler:say({'The dwarves are still in need of your help, member of Bigfoot\'s Brigade. Prove your worth by answering their calls! (' .. math.max(player:getStorageValue(Storage.DangerousDepths.Dwarves.Status), 0) .. '/10)'}, cid) + elseif msgcontains(msg, "scouts") and npcHandler.topic[cid] == 5 then + npcHandler:say({'The scouts are still in need of your help, member of Bigfoot\'s Brigade. Prove your worth by answering their calls! (' .. math.max(player:getStorageValue(Storage.DangerousDepths.Scouts.Status), 0) .. '/10)'}, cid) + end + return true +end + + + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gnomux.lua b/data/npc/scripts/gnomux.lua new file mode 100644 index 00000000000..f88ea019c7a --- /dev/null +++ b/data/npc/scripts/gnomux.lua @@ -0,0 +1,79 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) +local talkState = {} + +local spike_items = { + [21564] = {250, 4, SPIKE_MIDDLE_MUSHROOM_MAIN}, + [21555] = {150, 3, SPIKE_UPPER_TRACK_MAIN}, + [21569] = {100, 4, SPIKE_LOWER_PARCEL_MAIN}, + [21557] = {250, 1, SPIKE_MIDDLE_CHARGE_MAIN}, + [21553] = {150, 4, SPIKE_UPPER_MOUND_MAIN}, + [21556] = {500, 1, SPIKE_LOWER_LAVA_MAIN}, + [21554] = {150, 7, SPIKE_UPPER_PACIFIER_MAIN} +} + +local onBuy = function(cid, item, subType, amount, ignoreCap, inBackpacks) + if not doPlayerRemoveMoney(cid, spike_items[item][1] * amount) then + selfSay("You don't have enough money.", cid) + else + doPlayerAddItem(cid, item, amount) + selfSay("Here you are!", cid) + end + return true +end + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function creatureSayCallback(cid, type, msg) + + if not npcHandler:isFocused(cid) then + return false + end + + local player, canBuy, shopWindow = Player(cid), false, {} + + for itemid, data in pairs(spike_items) do + if not isInArray({-1, data[2]}, player:getStorageValue(data[3])) then + canBuy = true + table.insert(shopWindow, {id = itemid, subType = 0, buy = data[1], sell = 0, name = ItemType(itemid):getName()}) + end + end + + if msgcontains(msg, 'trade') then + if canBuy then + openShopWindow(cid, shopWindow, onBuy, onSell) + return npcHandler:say("Here you are.", cid) + else + return npcHandler:say("Sorry, there's nothing for you right now.", cid) + end + return true + end + + if msgcontains(msg, 'job') then + npcHandler:say("I'm responsible for resupplying foolish adventurers with equipment that they may have lost. If you're one of them, just ask me about a {trade}. ", cid) + end + + if msgcontains(msg, 'gnome') then + npcHandler:say("What could I say about gnomes that anyone would not know? I mean, we're interesting if not fascinating, after all.", cid) + end + + if msgcontains(msg, 'spike') then + npcHandler:say({"I came here as a crystal farmer and know the Spike all the way back to when it was a little baby crystal. I admit I feel a little fatherly pride in how big and healthy it has become.","When most other crystal experts left for new assignments, I decided to stay and help here a bit."}, cid) + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gordon.lua b/data/npc/scripts/gordon.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/gordon.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gorn.lua b/data/npc/scripts/gorn.lua new file mode 100644 index 00000000000..1c4ffd205c2 --- /dev/null +++ b/data/npc/scripts/gorn.lua @@ -0,0 +1,74 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'General goods and paperware for sale!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if msgcontains(msg, "football") then + npcHandler:say("Do you want to buy a football for 111 gold?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + local player = Player(cid) + if player:getMoney() + player:getBankBalance() >= 111 then + npcHandler:say("Here it is.", cid) + player:addItem(2109, 1) + player:removeMoneyNpc(111) + else + npcHandler:say("You don't have enough money.", cid) + end + npcHandler.topic[cid] = 0 + end + end + return true +end + +-- Basic +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am selling equipment of all kinds. Do you need anything?"}) +keywordHandler:addKeyword({'king'}, StdModule.say, {npcHandler = npcHandler, text = "The king supports Tibia's economy a lot."}) +keywordHandler:addAliasKeyword({'tibianus'}) +keywordHandler:addKeyword({'magic'}, StdModule.say, {npcHandler = npcHandler, text = "Magic? Ask a sorcerer or druid about that."}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "I am Gorn. My goods are known all over Tibia."}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = "It is exactly |TIME|. Maybe you want to buy a watch?"}) +keywordHandler:addKeyword({'druids'}, StdModule.say, {npcHandler = npcHandler, text = "This druids are nice people, you will find them in the east of the town."}) +keywordHandler:addKeyword({'knights'}, StdModule.say, {npcHandler = npcHandler, text = "Even the strong knights need my equipment on their travels though Tibia."}) +keywordHandler:addKeyword({'sorcerers'}, StdModule.say, {npcHandler = npcHandler, text = "You can find him in the sorcerer guild."}) +keywordHandler:addKeyword({'elane'}, StdModule.say, {npcHandler = npcHandler, text = "She's the leader of the paladin guild."}) +keywordHandler:addKeyword({'baxter'}, StdModule.say, {npcHandler = npcHandler, text = "Old Baxter was a rowdy, once. In our youth we shared some adventures and women."}) +keywordHandler:addKeyword({'bozo'}, StdModule.say, {npcHandler = npcHandler, text = "Bah! Go away with this bozoguy."}) +keywordHandler:addKeyword({'frodo'}, StdModule.say, {npcHandler = npcHandler, text = "Frodo is a jolly fellow."}) +keywordHandler:addKeyword({'ferumbras'}, StdModule.say, {npcHandler = npcHandler, text = "We had a clash or two in the old days."}) +keywordHandler:addKeyword({'gregor'}, StdModule.say, {npcHandler = npcHandler, text = "Even the strong knights need my equipment on their travels though Tibia."}) +keywordHandler:addKeyword({'lynda'}, StdModule.say, {npcHandler = npcHandler, text = "That's a pretty one."}) +keywordHandler:addKeyword({'mcronald'}, StdModule.say, {npcHandler = npcHandler, text = "I hardly know the McRonalds."}) +keywordHandler:addKeyword({'muriel'}, StdModule.say, {npcHandler = npcHandler, text = "You can find him in the sorcerer guild."}) +keywordHandler:addKeyword({'oswald'}, StdModule.say, {npcHandler = npcHandler, text = "This Oswald has not enough to work and too much time to spread rumours."}) +keywordHandler:addKeyword({'quentin'}, StdModule.say, {npcHandler = npcHandler, text = "He advices newcomers to buy at my store. I love that guy!"}) +keywordHandler:addKeyword({'sam'}, StdModule.say, {npcHandler = npcHandler, text = "Strong as an ox, could armwrestle a minotaur, I bet."}) +keywordHandler:addKeyword({'xodet'}, StdModule.say, {npcHandler = npcHandler, text = "He owns the magic shop here. But be aware: The prices are enormous."}) + + +npcHandler:setMessage(MESSAGE_GREET, "Oh, please come in, |PLAYERNAME|. What do you need?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Of course, just browse through my wares. {Footballs} have to be purchased separately.") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/graham.lua b/data/npc/scripts/graham.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/graham.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/graubart.lua b/data/npc/scripts/graubart.lua new file mode 100644 index 00000000000..e260f9af357 --- /dev/null +++ b/data/npc/scripts/graubart.lua @@ -0,0 +1,32 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "My name is Graubart, captain of the great SeaHawk!"}) +keywordHandler:addKeyword({'ship'}, StdModule.say, {npcHandler = npcHandler, text = "Ah, my whole proud: My ship named SeaHawk. We rode out so many stormy nights together. I think I couldn't live without it."}) +keywordHandler:addKeyword({'seahawk'}, StdModule.say, {npcHandler = npcHandler, text = "Ah, my whole proud: My ship named SeaHawk. We rode out so many stormy nights together. I think I couldn't live without it."}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I'm a merchant. I sail all over the world with my ship and trade with many different races!"}) +keywordHandler:addKeyword({'merchant'}, StdModule.say, {npcHandler = npcHandler, text = "A merchant is someone who trades goods with other people and tries to make a little profit. *laughs*"}) +keywordHandler:addKeyword({'trade'}, StdModule.say, {npcHandler = npcHandler, text = "I trade nearly everything, for example weapons, food, water, and even magic runes."}) +keywordHandler:addKeyword({'races'}, StdModule.say, {npcHandler = npcHandler, text = "You know; elves, dwarfs, lizardmen, minotaurs and many others."}) +keywordHandler:addKeyword({'water'}, StdModule.say, {npcHandler = npcHandler, text = "Sorry, sold out."}) +keywordHandler:addKeyword({'marlene'}, StdModule.say, {npcHandler = npcHandler, text = "Pssst. Marlene is not near right now...? You know... she is a lovely woman, but she talks too much! So I always try to keep distance from her because she can't stop talking."}) +keywordHandler:addKeyword({'bruno'}, StdModule.say, {npcHandler = npcHandler, text = "Bruno is one of the best sailors I know. He is nearly as good as me. *laughs loudly*"}) + +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye and don't forget me!") +npcHandler:setMessage(MESSAGE_GREET, "Ahoi, young man |PLAYERNAME|. Looking for work on my ship?") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gree_dee.lua b/data/npc/scripts/gree_dee.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/gree_dee.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gregor.lua b/data/npc/scripts/gregor.lua new file mode 100644 index 00000000000..60fb8b9e1fd --- /dev/null +++ b/data/npc/scripts/gregor.lua @@ -0,0 +1,404 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + {text = "Gather around me, young knights! I'm going to teach you some spells!"} +} +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + local addonProgress = player:getStorageValue(Storage.OutfitQuest.Knight.AddonHelmet) + if msgcontains(msg, "task") then + if not player:isPremium() then + npcHandler:say("Sorry, but our tasks are only for premium warriors.", cid) + return true + end + + if addonProgress < 1 then + npcHandler:say("You mean you would like to prove that you deserve to wear such a helmet?", cid) + npcHandler.topic[cid] = 1 + elseif addonProgress == 1 then + npcHandler:say("Your current task is to bring me 100 perfect behemoth fangs, |PLAYERNAME|.", cid) + elseif addonProgress == 2 then + npcHandler:say("Your current task is to retrieve the helmet of Ramsay the Reckless from Banuta, |PLAYERNAME|.", cid) + elseif addonProgress == 3 then + npcHandler:say("Your current task is to obtain a flask of warrior's sweat, |PLAYERNAME|.", cid) + elseif addonProgress == 4 then + npcHandler:say("Your current task is to bring me royal steel, |PLAYERNAME|.", cid) + elseif addonProgress == 5 then + npcHandler:say("Please talk to Sam and tell him I sent you. \z + I'm sure he will be glad to refine your helmet, |PLAYERNAME|.", cid) + else + npcHandler:say("You've already completed the task and can consider yourself a mighty warrior, |PLAYERNAME|.", cid) + end + + elseif msgcontains(msg, "behemoth fang") then + if addonProgress == 1 then + npcHandler:say("Have you really managed to fulfil the task and brought me 100 perfect behemoth fangs?", cid) + npcHandler.topic[cid] = 3 + else + npcHandler:say("You're not serious asking that, are you? They come from behemoths, of course. \z + Unless there are behemoth rabbits. Duh.", cid) + end + + elseif msgcontains(msg, "ramsay") then + if addonProgress == 2 then + npcHandler:say("Did you recover the helmet of Ramsay the Reckless?", cid) + npcHandler.topic[cid] = 4 + else + npcHandler:say("These pesky apes steal everything they can get their dirty hands on.", cid) + end + + elseif msgcontains(msg, "sweat") then + if addonProgress == 3 then + npcHandler:say("Were you able to get hold of a flask with pure warrior's sweat?", cid) + npcHandler.topic[cid] = 5 + else + npcHandler:say("Warrior's sweat can be magically extracted from headgear worn by a true warrior, \z + but only in small amounts. Djinns are said to be good at magical extractions.", cid) + end + + elseif msgcontains(msg, "royal steel") then + if addonProgress == 4 then + npcHandler:say("Ah, have you brought the royal steel?", cid) + npcHandler.topic[cid] = 6 + else + npcHandler:say("Royal steel can only be refined by very skilled smiths.", cid) + end + + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, "yes") then + npcHandler:say( + { + "Well then, listen closely. First, you will have to prove that you are a fierce and \z + restless warrior by bringing me 100 perfect behemoth fangs. ...", + "Secondly, please retrieve a helmet for us which has been lost a long time ago. \z + The famous Ramsay the Reckless wore it when exploring an ape settlement. ...", + "Third, we need a new flask of warrior's sweat. We've run out of it recently, \z + but we need a small amount for the show battles in our arena. ...", + "Lastly, I will have our smith refine your helmet if you bring me royal steel, an especially noble metal. ...", + "Did you understand everything I told you and are willing to handle this task?" + }, + cid, true, false, 100) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, "no") then + npcHandler:say("Bah. Then you will have to wait for the day these helmets are sold in shops, \z + but that will not happen before hell freezes over.", cid) + npcHandler.topic[cid] = 0 + end + + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, "yes") then + player:setStorageValue(Storage.OutfitQuest.Ref, math.max(0, player:getStorageValue(Storage.OutfitQuest.Ref)) + 1) + player:setStorageValue(Storage.OutfitQuest.Knight.AddonHelmet, 1) + player:setStorageValue(Storage.OutfitQuest.Knight.MissionHelmet, 1) + npcHandler:say("Alright then. Come back to me once you have collected 100 perfect behemoth fangs.", cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") then + npcHandler:say("Would you like me to repeat the task requirements then?", cid) + npcHandler.topic[cid] = 1 + end + + elseif npcHandler.topic[cid] == 3 then + if msgcontains(msg, "yes") then + if not player:removeItem(5893, 100) then + npcHandler:say("Lying is not exactly honourable, |PLAYERNAME|. Shame on you.", cid) + return true + end + + player:setStorageValue(Storage.OutfitQuest.Knight.AddonHelmet, 2) + player:setStorageValue(Storage.OutfitQuest.Knight.MissionHelmet, 2) + player:setStorageValue(Storage.OutfitQuest.Knight.RamsaysHelmetDoor, 1) + npcHandler:say("I'm deeply impressed, brave Knight |PLAYERNAME|. I expected nothing less from you. \z + Now, please retrieve Ramsay's helmet.", cid) + elseif msgcontains(msg, "no") then + npcHandler:say("There is no need to rush anyway.", cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 4 then + if msgcontains(msg, "yes") then + if not player:removeItem(5924, 1) then + npcHandler:say("Lying is not exactly honourable, |PLAYERNAME|. Shame on you.", cid) + return true + end + + player:setStorageValue(Storage.OutfitQuest.Knight.AddonHelmet, 3) + player:setStorageValue(Storage.OutfitQuest.Knight.MissionHelmet, 3) + npcHandler:say("Good work, brave Knight |PLAYERNAME|! Even though it is damaged, \z + it has a lot of sentimental value. Now, please bring me warrior's sweat.", cid) + elseif msgcontains(msg, "no") then + npcHandler:say("There is no need to rush anyway.", cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 5 then + if msgcontains(msg, "yes") then + if not player:removeItem(5885, 1) then + npcHandler:say("Lying is not exactly honourable, |PLAYERNAME|. Shame on you.", cid) + return true + end + + player:setStorageValue(Storage.OutfitQuest.Knight.AddonHelmet, 4) + player:setStorageValue(Storage.OutfitQuest.Knight.MissionHelmet, 4) + npcHandler:say("Now that is a pleasant surprise, brave Knight |PLAYERNAME|! \z + There is only one task left now: Obtain royal steel to have your helmet refined.", cid) + elseif msgcontains(msg, "no") then + npcHandler:say("There is no need to rush anyway.", cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 6 then + if msgcontains(msg, "yes") then + if not player:removeItem(5887, 1) then + npcHandler:say("Lying is not exactly honourable, |PLAYERNAME|. Shame on you.", cid) + return true + end + + player:setStorageValue(Storage.OutfitQuest.Knight.AddonHelmet, 5) + player:setStorageValue(Storage.OutfitQuest.Knight.MissionHelmet, 5) + npcHandler:say("You truly deserve to wear an adorned helmet, brave Knight |PLAYERNAME|. \z + Please talk to Sam and tell him I sent you. I'm sure he will be glad to refine your helmet.", cid) + elseif msgcontains(msg, "no") then + npcHandler:say("There is no need to rush anyway.", cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addSpellKeyword({"find", "person"}, + { + npcHandler = npcHandler, + spellName = "Find Person", + price = 80, + level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"light"}, + { + npcHandler = npcHandler, + spellName = "Light", + price = 0, + level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"cure", "poison"}, + { + npcHandler = npcHandler, + spellName = "Cure Poison", + price = 150, + level = 10, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"wound", "cleansing"}, + { + npcHandler = npcHandler, + spellName = "Wound Cleansing", + price = 0, + level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"great", "light"}, + { + npcHandler = npcHandler, + spellName = "Great Light", + price = 500, + level = 13, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) + +keywordHandler:addKeyword({"healing", "spells"}, StdModule.say, + { + npcHandler = npcHandler, + text = "In this category I have '{Wound Cleansing}' and '{Cure Poison}'." + } +) +keywordHandler:addKeyword({"support", "spells"}, StdModule.say, + { + npcHandler = npcHandler, + text = "In this category I have '{Light}', '{Find Person}' and '{Great Light}'." + } +) +keywordHandler:addKeyword({"spells"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I can teach you {healing spells} and {support spells}. \z + What kind of spell do you wish to learn? You can also tell me for which level \z + you would like to learn a spell, if you prefer that." + } +) + +keywordHandler:addKeyword({"job"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I am the first knight. I trained some of the greatest heroes of Tibia." + } +) +keywordHandler:addKeyword({"heroes"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Of course, you heard of them. Knights are the best fighters in Tibia." + } +) +keywordHandler:addKeyword({"king"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Hail to our King!" + } +) +keywordHandler:addKeyword({"name"}, StdModule.say, + { + npcHandler = npcHandler, + text = "You are joking, eh? Of course, you know me. I am Gregor, the first knight." + } +) +keywordHandler:addKeyword({"gregor"}, StdModule.say, + { + npcHandler = npcHandler, + text = "A great name, isn't it?" + } +) +keywordHandler:addKeyword({"tibia"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Beautiful Tibia. And with our help everyone is save." + } +) +keywordHandler:addKeyword({"time"}, StdModule.say, + { + npcHandler = npcHandler, + text = "It is time to join the Knights!" + } +) +keywordHandler:addKeyword({"knights"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Knights are the warriors of Tibia. Without us, no one would be safe. \z + Every brave and strong man or woman can join us." + } +) +keywordHandler:addKeyword({"bozo"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Some day someone will make something happen to him..." + } +) +keywordHandler:addKeyword({"elane"}, StdModule.say, + { + npcHandler = npcHandler, + text = "A bow might be a fine weapon for someone not strong enough to wield a REAL weapon." + } +) +keywordHandler:addKeyword({"frodo"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I and my students often share a cask of beer or wine at Frodo's hut." + } +) +keywordHandler:addKeyword({"gorn"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Always concerned with his profit. What a loss! He was adventuring with baxter in the old days." + } +) +keywordHandler:addKeyword({"baxter"}, StdModule.say, + { + npcHandler = npcHandler, + text = "He was an adventurer once." + } +) +keywordHandler:addKeyword({"lynda"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Before she became a priest she won the Miss Tibia contest three times in a row." + } +) +keywordHandler:addKeyword({"mcronald"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Peaceful farmers." + } +) +keywordHandler:addKeyword({"ferumbras"}, StdModule.say, + { + npcHandler = npcHandler, + text = "A fine game to hunt. But be careful, he cheats!" + } +) +keywordHandler:addKeyword({"muriel"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Bah, go away with these sorcerer tricks. Only cowards use tricks." + } +) +keywordHandler:addKeyword({"oswald"}, StdModule.say, + { + npcHandler = npcHandler, + text = "What an idiot." + } +) +keywordHandler:addKeyword({"quentin"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I will never understand this peaceful monks and priests." + } +) +keywordHandler:addKeyword({"sam"}, StdModule.say, + { + npcHandler = npcHandler, + text = "He has the muscles, but lacks the guts." + } +) +keywordHandler:addKeyword({"tibianus"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Hail to our King!" + } +) +keywordHandler:addKeyword({"outfit"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Only the bravest warriors may wear adorned helmets. \z + They are traditionally awarded after having completed a difficult task for our guild." + } +) +keywordHandler:addKeyword({"helmet"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Only the bravest warriors may wear adorned helmets. \z + They are traditionally awarded after having completed a difficult task for our guild." + } +) + +npcHandler:setMessage(MESSAGE_GREET, "Greetings, |PLAYERNAME|. What do you want?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Be careful on your journeys.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Be careful on your journeys.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/grizzly_adams.lua b/data/npc/scripts/grizzly_adams.lua new file mode 100644 index 00000000000..178bb9b21eb --- /dev/null +++ b/data/npc/scripts/grizzly_adams.lua @@ -0,0 +1,470 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local choose = {} +local cancel = {} + +local grizzlyAdamsConfig = { + ranks = { + huntsMan_rank = { + -- SELL OFFERS + {id=11214, buy=0, sell=50, name="antlers"}, + {id=10550, buy=0, sell=100, name="bloody pincers"}, + {id=11189, buy=0, sell=35, name="crab pincers"}, + {id=10574, buy=0, sell=55, name="cyclops toe"}, + {id=13303, buy=0, sell=550, name="cavebear skull"}, + {id=20098, buy=0, sell=150, name="cheesy figurine"}, + {id=12470, buy=0, sell=110, name="colourful feather"}, + {id=7398, buy=0, sell=500, name="cyclops trophy"}, + {id=11315, buy=0, sell=15000, name="draken trophy"}, + {id=13296, buy=0, sell=800, name="draptor scales"}, + {id=21311, buy=0, sell=115, name="elven hoof"}, + {id=10565, buy=0, sell=30, name="frosty ear of a troll"}, + {id=13304, buy=0, sell=950, name="giant crab pincer"}, + {id=12495, buy=0, sell=20, name="goblin ear"}, + {id=13301, buy=0, sell=400, name="hollow stampor hoof"}, + {id=11199, buy=0, sell=600, name="hydra head"}, + {id=11372, buy=0, sell=80, name="lancer beetle shell"}, + {id=11336, buy=0, sell=8000, name="lizard trophy"}, + {id=12445, buy=0, sell=280, name="mantassin tail"}, + {id=19741, buy=0, sell=65, name="marsh stalker beak"}, + {id=19742, buy=0, sell=50, name="marsh stalker feather"}, + {id=13302, buy=0, sell=250, name="maxilla"}, + {id=7401, buy=0, sell=500, name="minotaur trophy"}, + {id=10579, buy=0, sell=420, name="mutated bat ear"}, + {id=13026, buy=0, sell=750, name="panther head"}, + {id=13027, buy=0, sell=300, name="panther paw"}, + {id=12447, buy=0, sell=500, name="quara bone"}, + {id=12447, buy=0, sell=350, name="quara eye"}, + {id=12446, buy=0, sell=410, name="quara pincers"}, + {id=12443, buy=0, sell=140, name="quara tentacle"}, + {id=13159, buy=0, sell=50, name="rabbit's foot"}, + {id=21310, buy=0, sell=70, name="rorc feather"}, + {id=11228, buy=0, sell=400, name="sabretooth"}, + {id=11373, buy=0, sell=20, name="sandcrawler shell"}, + {id=10548, buy=0, sell=280, name="scarab pincers"}, + {id=13299, buy=0, sell=280, name="stampor horn"}, + {id=13300, buy=0, sell=150, name="stampor talons"}, + {id=11371, buy=0, sell=60, name="terramite legs"}, + {id=11369, buy=0, sell=170, name="terramite shell"}, + {id=11190, buy=0, sell=95, name="terrorbird beak"}, + -- BUY OFFERS + {id=5907, buy=35000, sell=0, name="slingshot"} + }, + + bigGameHunter_rank = { + {id=11161, buy=0, sell=6000, name="bonebeast trophy"}, + {id=7397, buy=0, sell=3000, name="deer trophy"}, + {id=7400, buy=0, sell=3000, name="lion trophy"}, + {id=7395, buy=0, sell=1000, name="orc trophy"}, + {id=7394, buy=0, sell=3000, name="wolf trophy"} + }, + + trophyHunter_rank = { + -- SELL OFFERS + {id=7396, buy=0, sell=20000, name="behemoth trophy"}, + {id=7393, buy=0, sell=40000, name="demon trophy"}, + {id=7399, buy=0, sell=10000, name="dragon lord trophy"}, + {id=11338, buy=0, sell=3000, name="disgusting trophy"}, + {id=24757, buy=0, sell=9000, name="werebadger trophy"}, + {id=24758, buy=0, sell=10000, name="wereboar trophy"}, + {id=24759, buy=0, sell=11000, name="werebear trophy"}, + {id=30941, buy=0, sell=9000, name="werefox trophy"}, + {id=39054, buy=0, sell=12000, name="werehyaena trophy"}, + -- BUY OFFERS + {id=10518, buy=1000, sell=0, name="demon backpack"} + }, + } +} + +local items, data = {} +for i = 1, #grizzlyAdamsConfig.ranks.huntsMan_rank do + data = grizzlyAdamsConfig.ranks.huntsMan_rank[i] + items[data.id] = {id = data.id, buy = data.buy, sell = data.sell, name = ItemType(data.id):getName():lower()} +end +for i = 1, #grizzlyAdamsConfig.ranks.bigGameHunter_rank do + data = grizzlyAdamsConfig.ranks.bigGameHunter_rank[i] + items[data.id] = {id = data.id, buy = data.buy, sell = data.sell, name = ItemType(data.id):getName():lower()} +end +for i = 1, #grizzlyAdamsConfig.ranks.trophyHunter_rank do + data = grizzlyAdamsConfig.ranks.trophyHunter_rank[i] + items[data.id] = {id = data.id, buy = data.buy, sell = data.sell, name = ItemType(data.id):getName():lower()} +end + +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(JOIN_STOR) == -1 then + npcHandler:setMessage(MESSAGE_GREET, + "Hi there, do you want to to join the 'Paw and Fur - Hunting Elite'?") + else + npcHandler:setMessage(MESSAGE_GREET, + "Welcome to the 'Paw and Fur - Hunting Elite' |PLAYERNAME|. ".. + "Feel free to do {tasks} for us.") + end + return true +end + +local function joinTables(old, new) + for k, v in pairs(new) do + old[k] = v + end + return old +end + +local function onBuy(cid, item, subType, amount, ignoreCap, inBackpacks) + local player = Player(cid) + if not ignoreCap and player:getFreeCapacity() < ItemType(items[item].id):getWeight(amount) then + return player:sendTextMessage(MESSAGE_FAILURE, "You don't have enough cap.") + end + if items[item].buy then + if player:removeMoneyNpc(amount * items[item].buy) then + player:addItem(items[item].id, amount) + return player:sendTextMessage(MESSAGE_TRADE, + "Bought "..amount.."x "..items[item].name.." for "..items[item].buy * amount.." gold coins.") + else + return player:sendTextMessage(MESSAGE_FAILURE, "You don't have enough money.") + end + end + return true +end + +local function onSell(cid, item, subType, amount, ignoreCap, inBackpacks) + local player = Player(cid) + if items[item].sell then + if player:removeItem(items[item].id, amount) then + player:addMoney(items[item].sell * amount) + return player:sendTextMessage(MESSAGE_TRADE, + "Sold "..amount.."x "..items[item].name.." for "..items[item].sell * amount.." gold coins.") + else + return player:sendTextMessage(MESSAGE_TRADE, "You don't have the items you're trying to sell.") + end + end + return true +end + +local function startTrade(cid, player) + if player:getPawAndFurRank() >= 2 then + local tradeItems = grizzlyAdamsConfig.ranks.huntsMan_rank + if player:getPawAndFurRank() >= 4 then + tradeItems = joinTables(tradeItems, grizzlyAdamsConfig.ranks.bigGameHunter_rank) + end + if player:getPawAndFurRank() >= 6 then + tradeItems = joinTables(tradeItems, grizzlyAdamsConfig.ranks.trophyHunter_rank) + end + openShopWindow(cid, tradeItems, onBuy, onSell) + return npcHandler:say("It's my offer.", cid) + else + return npcHandler:say("You don't have any rank.", cid) + end +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + msg = msg:gsub("(%l)(%w*)", function(a,b) return string.upper(a)..b end) + + if msgcontains("trade", msg) then + startTrade(cid, player) + elseif (msgcontains("join", msg) or msgcontains("yes", msg)) + and npcHandler.topic[cid] == 0 + and player:getStorageValue(JOIN_STOR) ~= 1 then + player:setStorageValue(JOIN_STOR, 1) + npcHandler:say("Great! " .. + "A warm welcome to our newest member: |PLAYERNAME|! " .. + "Ask me for a {task} if you want to go on a hunt.", cid) + elseif isInArray({"tasks", "task", "mission"}, msg:lower()) then + if player:getStorageValue(JOIN_STOR) == -1 then + return npcHandler:say("You'll have to {join}, to get any {tasks}.",cid) + end + + local can = player:getTasks() + + if #can > 0 then + local text = "" + local sep = ", " + table.sort(can, function(a, b) return a < b end) + local t = 0 + local id + for i = 1, #can do + id = can[i] + t = t + 1 + if t == #can - 1 then + sep = " and " + elseif t == #can then + sep = "." + end + text = text .. "{" .. (tasks[id].name or tasks[id].raceName) .. "}" .. sep + end + npcHandler:say("The current task" .. + (#can > 1 and "s" or "") .. " that you can choose " .. + (#can > 1 and "are" or "is") .. " " .. text, cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("I don't have any task for you right now.", cid) + end + elseif msg ~= "" and player:canStartTask(msg) then + if #player:getStartedTasks() >= tasksByPlayer then + npcHandler:say("Sorry, but you already started " .. tasksByPlayer .. " tasks.".. + " ".."You can check their {status}, {cancel} or {report} a task.", cid) + return true + end + local task = getTaskByName(msg) + if task and player:getStorageValue(QUESTSTORAGE_BASE + task) > 0 then + return false + end + npcHandler:say("In this task you must defeat " .. tasks[task].killsRequired .. " " .. tasks[task].raceName .. ".".. + " ".."Are you sure that you want to start this task?", cid) + choose[cid] = task + npcHandler.topic[cid] = 1 + elseif msg:lower() == "yes" and npcHandler.topic[cid] == 1 then + player:setStorageValue(QUESTSTORAGE_BASE + choose[cid], 1) + player:setStorageValue(KILLSSTORAGE_BASE + choose[cid], 0) + npcHandler:say("Excellent! You can check the {status} of your task saying {report} to me.".. + " ".."Also you can {cancel} tasks to.", cid) + choose[cid] = nil + npcHandler.topic[cid] = 0 + elseif msgcontains("status", msg) then + local started = player:getStartedTasks() + if started and #started > 0 then + local text = "" + table.sort(started, (function(a, b) return (a < b) end)) + local t = 0 + local id + for i = 1, #started do + id = started[i] + t = t + 1 + text = text .. "Task name: " .. tasks[id].raceName .. ". ".. + "Current kills: " .. player:getStorageValue(KILLSSTORAGE_BASE + id) .. ".\n" + end + npcHandler:say({"The status of your current tasks is:\n" .. text}, cid) + else + npcHandler:say("You haven't started any task yet.", cid) + end + elseif msgcontains("report", msg) then + local started = player:getStartedTasks() + local finishedAtLeastOne = false + local finished = 0 + if started and #started > 0 then + local id, reward + for i = 1, #started do + id = started[i] + if player:getStorageValue(KILLSSTORAGE_BASE + id) >= tasks[id].killsRequired then + for j = 1, #tasks[id].rewards do + reward = tasks[id].rewards[j] + local deny = false + if reward.storage then + if player:getStorageValue(reward.storage[1]) >= reward.storage[2] then + deny = true + end + end + if isInArray({REWARD_MONEY, "money"}, reward.type:lower()) and not deny then + player:addMoney(reward.value[1]) + elseif isInArray({REWARD_EXP, "exp", "experience"}, reward.type:lower()) and not deny then + player:addExperience(reward.value[1], true) + elseif isInArray({REWARD_ACHIEVEMENT, "achievement", "ach"}, reward.type:lower()) and not deny then + player:addAchievement(reward.value[1]) + elseif isInArray({REWARD_STORAGE, "storage", "stor"}, reward.type:lower()) and not deny then + player:setStorageValue(reward.value[1], reward.value[2]) + elseif isInArray({REWARD_POINT, "points", "point"}, reward.type:lower()) and not deny then + player:setStorageValue(POINTSSTORAGE, getPlayerTasksPoints(cid) + reward.value[1]) + elseif isInArray({REWARD_ITEM, "item", "items", "object"}, reward.type:lower()) and not deny then + player:addItem(reward.value[1], reward.value[2]) + end + + if reward.storage then + player:setStorageValue(reward.storage[1], reward.storage[2]) + end + end + + player:setStorageValue(QUESTSTORAGE_BASE + id, (tasks[id].norepeatable and 2 or 0)) + player:setStorageValue(KILLSSTORAGE_BASE + id, -1) + player:setStorageValue(REPEATSTORAGE_BASE + id, math.max(player:getStorageValue(REPEATSTORAGE_BASE + id), 0)) + player:setStorageValue(REPEATSTORAGE_BASE + id, player:getStorageValue(REPEATSTORAGE_BASE + id) + 1) + finishedAtLeastOne = true + finished = finished + 1 + end + end + if not finishedAtLeastOne then + local started = player:getStartedTasks() + if started and #started > 0 then + local text = "" + local sep = ", " + table.sort(started, (function(a, b) return (a < b) end)) + local t = 0 + local id + for i = 1, #started do + id = started[i] + t = t + 1 + if (t == #started - 1) then + sep = " and " + elseif (t == #started) then + sep = "." + end + text = text .. "{" .. (tasks[id].name or tasks[id].raceName) .. "}" .. sep + end + npcHandler:say("The current task" .. (#started > 1 and "s" or "") .. + " that you started " .. (#started > 1 and "are" or "is") .. " " .. text, cid) + end + else + npcHandler:say("Awesome! ".. + "You finished "..(finished > 1 and "various" or "a").." task"..(finished > 1 and "s" or "")..".".. + "Talk to me again if you want to start a {task}.", cid) + end + else + npcHandler:say("You haven't started any task yet.", cid) + end + elseif msg:lower() == "started" then + local started = player:getStartedTasks() + if started and #started > 0 then + local text = "" + local sep = ", " + table.sort(started, (function(a, b) return (a < b) end)) + local t = 0 + local id + for i = 1, #started do + id = started[i] + t = t + 1 + if t == #started - 1 then + sep = " and " + elseif t == #started then + sep = "." + end + text = text .. "{" .. (tasks[id].name or tasks[id].raceName) .. "}" .. sep + end + + npcHandler:say("The current task" .. (#started > 1 and "s" or "") .. " that you started" .. + " " .. (#started > 1 and "are" or "is") .. " " .. text, cid) + else + npcHandler:say("You haven't started any task yet.", cid) + end + elseif msg:lower() == "cancel" then + local started = player:getStartedTasks() + local text = "" + local sep = ", " + table.sort(started, (function(a, b) return (a < b) end)) + local t = 0 + local id + for i = 1, #started do + id = started[i] + t = t + 1 + if t == #started - 1 then + sep = " or " + elseif t == #started then + sep = "?" + end + text = text .. "{" .. (tasks[id].name or tasks[id].raceName) .. "}" .. sep + end + if started and #started > 0 then + npcHandler:say("Canceling a task will make the counter restart. " .. + "Which of these tasks you want cancel?" .. (#started > 1 and "" or "") .. " " .. text, cid) + npcHandler.topic[cid] = 2 + else + npcHandler:say("You haven't started any task yet.", cid) + end + elseif ((getTaskByName(msg)) and + (npcHandler.topic[cid] == 2) and + (isInArray(getPlayerStartedTasks(cid), getTaskByName(msg)))) then + local task = getTaskByName(msg) + if player:getStorageValue(KILLSSTORAGE_BASE + task) > 0 then + npcHandler:say("You currently killed " .. player:getStorageValue(KILLSSTORAGE_BASE + task) .. "/" .. + tasks[task].killsRequired .. " " .. tasks[task].raceName .. ".".. + " ".."Canceling this task will restart the count.".. + " ".."Are you sure you want to cancel this task?", cid) + else + npcHandler:say("Are you sure you want to cancel this task?", cid) + end + npcHandler.topic[cid] = 3 + cancel[cid] = task + elseif ((getTaskByName(msg)) and + (npcHandler.topic[cid] == 1) and + (isInArray(getPlayerStartedTasks(cid), getTaskByName(msg)))) then + local task = getTaskByName(msg) + if player:getStorageValue(KILLSSTORAGE_BASE + task) > 0 then + npcHandler:say("You currently killed " .. + player:getStorageValue(KILLSSTORAGE_BASE + task) .. "/" .. + tasks[task].killsRequired .. " " .. + tasks[task].raceName .. ".", cid) + else + npcHandler:say("You currently killed 0/" .. tasks[task].killsRequired .. " " .. tasks[task].raceName .. ".", cid) + end + npcHandler.topic[cid] = 0 + elseif msg:lower() == "yes" and npcHandler.topic[cid] == 3 then + player:setStorageValue(QUESTSTORAGE_BASE + cancel[cid], -1) + player:setStorageValue(KILLSSTORAGE_BASE + cancel[cid], -1) + npcHandler:say("You have canceled the task " .. + (tasks[cancel[cid]].name or tasks[cancel[cid]].raceName) .. ".", cid) + npcHandler.topic[cid] = 0 + elseif isInArray({"points", "rank"}, msg:lower()) then + npcHandler:say("At this time, you have " .. player:getPawAndFurPoints() .. " Paw & Fur points. You " .. + (player:getPawAndFurRank() == 6 and "are an Elite Hunter" or + player:getPawAndFurRank() == 5 and "are a Trophy Hunter" or + player:getPawAndFurRank() == 4 and "are a Big Game Hunter" or + player:getPawAndFurRank() == 3 and "are a Ranger" or + player:getPawAndFurRank() == 2 and "are a Huntsman" or + player:getPawAndFurRank() == 1 and "are a Member" or + "haven't been ranked yet") .. ".", cid) + npcHandler.topic[cid] = 0 + elseif isInArray({"special task"}, msg:lower()) then + if (player:getPawAndFurPoints() >= 70) then + if ((player:getLevel() > 90) and + (player:getStorageValue(Storage.KillingInTheNameOf.MissionTiquandasRevenge) == 1) and + (player:getStorageValue(Storage.KillingInTheNameOf.TiquandasRevengeTeleport) ~= 0)) then + npcHandler:say("You have already started the task. Go find Tiquandas Revenge and take revenge yourself!", cid) + else + npcHandler:say({"Have you heard about Tiquandas Revenge? " .. + "It is said that the jungle itself is alive and takes revenge for all the bad things people have done to it." .. + "...", + "I myself believe that there is some truth in this clap trap." .. + "Something 'real' which therefore must have a hideout somewhere." .. + "Go find it and take revenge yourself!"}, cid) + player:setStorageValue(Storage.KillingInTheNameOf.TiquandasRevengeTeleport, 1) + player:setStorageValue(Storage.KillingInTheNameOf.MissionTiquandasRevenge, 1) + end + + if ((player:getLevel() > 100) and + (player:getStorageValue(Storage.KillingInTheNameOf.MissionDemodras) == 1) and + (player:getStorageValue(Storage.KillingInTheNameOf.DemodrasTeleport) ~= 0)) then + npcHandler:say("You have already started the special task. Find Demodras and kill it.", cid) + else + if ((player:getStorageValue(Storage.KillingInTheNameOf.MissionTiquandasRevenge) == 1) and + (player:getStorageValue(Storage.KillingInTheNameOf.TiquandasRevengeTeleport) == 0)) then + npcHandler:say("This task is a very dangerous one. I want you to look for Demodras' hideout. ".. + "It might be somewhere under the Plains of Havoc. Good luck, old chap.", cid) + player:setStorageValue(Storage.KillingInTheNameOf.DemodrasTeleport, 1) + player:setStorageValue(Storage.KillingInTheNameOf.MissionDemodras, 1) + + end + end + + if (player:getStorageValue(Storage.KillingInTheNameOf.MissionDemodras) == 1 and + player:getStorageValue(Storage.KillingInTheNameOf.DemodrasTeleport) == 0 and + player:getStorageValue(Storage.KillingInTheNameOf.MissionTiquandasRevenge) == 1 and + player:getStorageValue(Storage.KillingInTheNameOf.TiquandasRevengeTeleport) == 0) then + npcHandler:say("You have already finished all special tasks.", cid) + end + npcHandler.topic[cid] = 0 + end + end +end + +npcHandler:setMessage(MESSAGE_FAREWELL, "Happy hunting, old chap!") +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/grodrik.lua b/data/npc/scripts/grodrik.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/grodrik.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/grof_the_guard.lua b/data/npc/scripts/grof_the_guard.lua new file mode 100644 index 00000000000..9e0c0daf3a4 --- /dev/null +++ b/data/npc/scripts/grof_the_guard.lua @@ -0,0 +1,47 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "trouble") and player:getStorageValue(Storage.TheInquisition.GrofGuard) < 1 and player:getStorageValue(Storage.TheInquisition.Mission01) ~= -1 then + npcHandler:say("I think it'll rain soon and I left some laundry out for drying.", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "authorities") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Yes I'm pretty sure they have failed to send the laundry police to take care of it, you fool.", cid) + npcHandler.topic[cid] = 0 + if player:getStorageValue(Storage.TheInquisition.GrofGuard) < 1 then + player:setStorageValue(Storage.TheInquisition.GrofGuard, 1) + player:setStorageValue(Storage.TheInquisition.Mission01, player:getStorageValue(Storage.TheInquisition.Mission01) + 1) -- The Inquisition Questlog- "Mission 1: Interrogation" + player:getPosition():sendMagicEffect(CONST_ME_HOLYAREA) + end + end + end + return true +end + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "It's my duty to protect the city."}) + +npcHandler:setMessage(MESSAGE_GREET, "LONG LIVE THE KING!") +npcHandler:setMessage(MESSAGE_FAREWELL, "LONG LIVE THE KING!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "LONG LIVE THE KING!") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/grombur.lua b/data/npc/scripts/grombur.lua new file mode 100644 index 00000000000..132ba89602e --- /dev/null +++ b/data/npc/scripts/grombur.lua @@ -0,0 +1,60 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, "nokmir") then + if player:getStorageValue(Storage.HiddenCityOfBeregar.JusticeForAll) == 2 then + npcHandler:say("Oh well, I liked Nokmir. He used to be a good dwarf until that day on which he stole the ring from {Rerun}.", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "rerun") then + if npcHandler.topic[cid] == 1 then + player:setStorageValue(Storage.HiddenCityOfBeregar.JusticeForAll, 3) + npcHandler:say("Yeah, he's the lucky guy in this whole story. I heard rumours that emperor Rehal had plans to promote Nokmir, but after this whole thievery story, he might pick Rerun instead.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "mission") then + if player:getStorageValue(Storage.HiddenCityOfBeregar.TheGoodGuard) < 1 then + npcHandler:say("Got any dwarven brown ale?? I DON'T THINK SO....and Bolfana, the tavern keeper, won't sell you anything. I'm sure about that...she doesn't like humans... I tell you what, if you get me a cask of dwarven brown ale, I allow you to enter the mine. Alright?", cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(Storage.HiddenCityOfBeregar.TheGoodGuard) == 1 and player:removeItem(9689, 1) then + player:setStorageValue(Storage.HiddenCityOfBeregar.TheGoodGuard, 2) + player:setStorageValue(Storage.HiddenCityOfBeregar.DoorSouthMine, 1) + npcHandler:say("HOW?....WHERE?....AHHHH, I don't mind....SLUUUUUURP....tastes a little flat but I had worse. Thank you. Just don't tell anyone that I let you in.", cid) + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 2 then + player:setStorageValue(Storage.HiddenCityOfBeregar.TheGoodGuard, 1) + player:setStorageValue(Storage.HiddenCityOfBeregar.DefaultStart, 1) + npcHandler:say("Haha, fine! Don't waste time and get me the ale. See you.", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, "See you my friend.") +npcHandler:setMessage(MESSAGE_FAREWELL, "See you my friend.") +npcHandler:setMessage(MESSAGE_GREET, "STOP RIGHT THERE!..... Oh, just a human. What's up big guy?") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/grubokk.lua b/data/npc/scripts/grubokk.lua new file mode 100644 index 00000000000..e88e935b7eb --- /dev/null +++ b/data/npc/scripts/grubokk.lua @@ -0,0 +1,20 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/grumpy_stone.lua b/data/npc/scripts/grumpy_stone.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/grumpy_stone.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/guard_bazaya.lua b/data/npc/scripts/guard_bazaya.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/guard_bazaya.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/guard_inurta.lua b/data/npc/scripts/guard_inurta.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/guard_inurta.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/guard_saros.lua b/data/npc/scripts/guard_saros.lua new file mode 100644 index 00000000000..598f3ed6bb4 --- /dev/null +++ b/data/npc/scripts/guard_saros.lua @@ -0,0 +1,219 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +local Price = {} + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Praised be Suon, the Benevolent King!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local function greetCallback(cid) + if Player(cid):getSex() == PLAYERSEX_FEMALE then + npcHandler:setMessage(MESSAGE_GREET, "Suon's and Bastesh's blessings! Welcome to {Issavi}, traveller.") + npcHandler.topic[cid] = 1 + else + npcHandler:setMessage(MESSAGE_GREET, "Suon's and Bastesh's blessings! Welcome to {Issavi}, traveller.") + npcHandler.topic[cid] = nil + end + Price[cid] = nil + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + local Sex = player:getSex() + if npcHandler.topic[cid] == 1 then + npcHandler:say("I would never have guessed that.", cid) + npcHandler.topic[cid] = nil + elseif npcHandler.topic[cid] == 2 then + if player:removeMoneyNpc(Price[cid]) then + npcHandler:say("Oh, sorry, I was distracted, what did you say?", cid) + else + npcHandler:say("Oh, I just remember I have some work to do, sorry. Bye!", cid) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + npcHandler.topic[cid] = nil + Price[cid] = nil + elseif npcHandler.topic[cid] == 3 and player:removeItem(2036, 1) then + npcHandler:say("Take some time to talk to me!", cid) + npcHandler.topic[cid] = nil + elseif npcHandler.topic[cid] == 4 and (msgcontains(msg, "spouse") or msgcontains(msg, "girlfriend")) then + npcHandler:say("Well ... I have met him for a little while .. but this was nothing serious.", cid) + npcHandler.topic[cid] = 5 + elseif npcHandler.topic[cid] == 5 and msgcontains(msg, "fruit") then + npcHandler:say("I remember that grapes were his favourites. He was almost addicted to them.", cid) + npcHandler.topic[cid] = nil + elseif msgcontains(msg, "how") and msgcontains(msg, "are") and msgcontains(msg, "you") then + npcHandler:say("Thank you very much. How kind of you to care about me. I am fine, thank you.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "sell") then + npcHandler:say("This is the continent you are currently visiting. You will find vast, dry steppes here as well as high mountains, the river Nykri and the big city {Issavi}.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "job") or msgcontains(msg, "issavi") then + npcHandler:say("Issavi is the capital of {Kilmaresh}, also called the Golden City. This city has a motto: An open gate for those of peace. This means, anyone is welcome here as long as they respect our laws, be it humans, elves, minotaurs or even a medusa.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "name") then + if Sex == PLAYERSEX_FEMALE then + npcHandler:say("I am Aruda.", cid) + else + npcHandler:say("I am a little sad, that you seem to have forgotten me, handsome. I am Aruda.", cid) + end + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "aruda") then + if Sex == PLAYERSEX_FEMALE then + npcHandler:say("Yes, that's me!", cid) + else + npcHandler:say("Oh, I like it, how you say my name.", cid) + end + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "time") then + npcHandler:say("Please don't be so rude to look for the time if you are talking to me.", cid) + npcHandler.topic[cid] = 3 + elseif msgcontains(msg, "help") then + npcHandler:say("I am deeply sorry, I can't help you.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "monster") or msgcontains(msg, "dungeon") then + npcHandler:say("UH! What a terrifying topic. Please let us speak about something more pleasant, I am a weak and small woman after all.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "sewer") then + npcHandler:say("What gives you the impression, I am the kind of women, you find in sewers?", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "god") then + npcHandler:say("You should ask about that in one of the temples.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "king") then + npcHandler:say("The king, that lives in this fascinating castle? I think he does look kind of cute in his luxurious robes, doesn't he?", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 10 + elseif msgcontains(msg, "sam") then + if Sex == PLAYERSEX_FEMALE then + npcHandler:say("He is soooo strong! What muscles! What a body! Did you ask him for a date?", cid) + else + npcHandler:say("He is soooo strong! What muscles! What a body! On the other hand, compared to you he looks quite puny.", cid) + end + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "benjamin") then + npcHandler:say("He is a little simple minded but always nice and well dressed.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "gorn") then + npcHandler:say("He should really sell some stylish gowns or something like that. We Tibians never get some clothing of the latest fashion. It's a shame.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "quentin") then + npcHandler:say("I don't understand this lonely monks. I love company too much to become one. Hehehe!", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "bozo") then + npcHandler:say("Oh, isn't he funny? I could listen to him the whole day.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "oswald") then + npcHandler:say("As far as I know, he is working in the castle.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "rumour") or msgcontains(msg, "rumor") or msgcontains(msg, "gossip") then + npcHandler:say("I am a little shy and so don't hear many rumors.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "kiss") and Sex == PLAYERSEX_MALE then + npcHandler:say("Oh, you little devil, stop talking like that! ", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 20 + elseif msgcontains(msg, "weapon") then + npcHandler:say("I know only little about weapons. Can you tell me something about them, please?", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "magic") then + npcHandler:say("I believe that love is stronger than magic, don't you agree?", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "thief") or msgcontains(msg, "theft") then + npcHandler:say("Oh, sorry, I have to hurry, bye!", cid) + npcHandler.topic[cid] = nil + Price[cid] = nil + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + elseif msgcontains(msg, "tibia") then + npcHandler:say("I would like to visit the beach more often, but I guess it's too dangerous.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "castle") then + npcHandler:say("I love this castle! It's so beautiful.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "muriel") then + npcHandler:say("Powerful sorcerers frighten me a little.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "elane") then + npcHandler:say("I personally think it's inappropriate for a woman to become a warrior, what do you think about that?", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "marvik") then + npcHandler:say("Druids seldom visit a town, what do you know about druids?", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "gregor") then + npcHandler:say("I like brave fighters like him.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "noodles") then + npcHandler:say("Oh, he is sooooo cute!", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "dog") or msgcontains(msg, "poodle") then + npcHandler:say("I like dogs, the little ones at least. Do you like dogs, too?", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 5 + elseif msgcontains(msg, "excalibug") then + npcHandler:say("Oh, I am just a girl and know nothing about magic swords and such things.", cid) + npcHandler.topic[cid] = 2 + Price[cid] = 10 + elseif msgcontains(msg, "partos") then + npcHandler:say("I ... don't know someone named like that.", cid) + npcHandler.topic[cid] = 4 + Price[cid] = nil + elseif msgcontains(msg, "yenny") then + npcHandler:say("Yenny? I know no Yenny, nor have I ever used that name! You have mistook me with someone else.", cid) + npcHandler.topic[cid] = nil + Price[cid] = nil + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, "I hope to see you soon.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye, |PLAYERNAME|. I really hope we'll talk again soon.") + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/guard_senet.lua b/data/npc/scripts/guard_senet.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/guard_senet.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/guardian_of_the_deep_seas.lua b/data/npc/scripts/guardian_of_the_deep_seas.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/guardian_of_the_deep_seas.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/guide_alexena.lua b/data/npc/scripts/guide_alexena.lua new file mode 100644 index 00000000000..844a7bb1302 --- /dev/null +++ b/data/npc/scripts/guide_alexena.lua @@ -0,0 +1,71 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Free escort to the depot for newcomers!' }, + { text = 'Hello, is this your first visit to Carlin? I can show you around a little.' }, + { text = 'I can tell you all about the status this world is in.' }, + { text = 'Talk to me if you need directions.' }, + { text = 'Need some help finding your way through Carlin?' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local configMarks = { + {mark = "shops", position = Position(32335, 31803, 7), markId = MAPMARK_BAG, description = "Shops"}, + {mark = "depot", position = Position(32331, 31782, 7), markId = MAPMARK_LOCK, description = "Depot"}, + {mark = "temple", position = Position(32360, 31782, 7), markId = MAPMARK_TEMPLE, description = "Temple"} +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if isInArray({"map", "marks"}, msg) then + npcHandler:say("Would you like me to mark locations like - for example - the depot, bank and shops on your map?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 1 then + npcHandler:say("Here you go.", cid) + local mark + for i = 1, #configMarks do + mark = configMarks[i] + player:addMapMark(mark.position, mark.markId, mark.description) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") and npcHandler.topic[cid] >= 1 then + npcHandler:say("Well, nothing wrong about exploring the town on your own. Let me know if you need something!", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'information'}, StdModule.say, {npcHandler = npcHandler, text = 'Currently, I can tell you all about the town, its temple, the bank, shops, spell trainers and the depot, as well as about the world status.'}) +keywordHandler:addKeyword({'temple'}, StdModule.say, {npcHandler = npcHandler, text = 'The temple can be found in one of the uptown districts. Look for stairs up from the lower city, you\'ll find the temple in the northwest of the upper city.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'The bank is on the left side of the depot. Eva will be at your service there.'}) +keywordHandler:addKeyword({'shops'}, StdModule.say, {npcHandler = npcHandler, text = 'You can buy weapons, armor, tools, gems, magical equipment, furniture, spells and food here.'}) +keywordHandler:addKeyword({'depot'}, StdModule.say, {npcHandler = npcHandler, text = 'The depot is a place where you can safely store your belongings. You are also protected against attacks there. I escort newcomers there.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'ll help you find your way through Carlin, the amazon town. I can mark important locations on your map and give you some information about the town and the world status.'}) +keywordHandler:addKeyword({'town'}, StdModule.say, {npcHandler = npcHandler, text = 'This city is ruled by Queen Eloise with the help of her female brigade. We have a lot of shops here as well as the usual facilities like depot, temple and so on.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m Alexena, at your service!'}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome to Carlin, |PLAYERNAME| Would you like some information and a map guide?") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye and enjoy your stay in Carlin, |PLAYERNAME|") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/guide_behil.lua b/data/npc/scripts/guide_behil.lua new file mode 100644 index 00000000000..592532844c2 --- /dev/null +++ b/data/npc/scripts/guide_behil.lua @@ -0,0 +1,69 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Hello, is this your first visit to Darashia? I can show you around a little.' }, + { text = 'I\'m well informed about the status of the world despite all the recent changes.'}, + { text = 'Need some help finding your way through Darashia? Let me assist you.' }, + { text = 'Free escort to the depot for newcomers!' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local configMarks = { + {mark = "shops", position = Position(33223, 32422, 7), markId = MAPMARK_BAG, description = "Shops"}, + {mark = "depottp", position = Position(33214, 32453, 7), markId = MAPMARK_LOCK, description = "Depot and Temple"} +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if isInArray({"map", "marks"}, msg) then + npcHandler:say("Would you like me to mark locations like - for example - the depot, bank and shops on your map?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 1 then + npcHandler:say("Here you go.", cid) + local mark + for i = 1, #configMarks do + mark = configMarks[i] + player:addMapMark(mark.position, mark.markId, mark.description) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") and npcHandler.topic[cid] >= 1 then + npcHandler:say("Well, nothing wrong about exploring the town on your own. Let me know if you need something!", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'information'}, StdModule.say, {npcHandler = npcHandler, text = 'Currently, I can tell you all about the town, its temple, the bank, shops, spell trainers and the depot, as well as about the world status.'}) +keywordHandler:addKeyword({'temple'}, StdModule.say, {npcHandler = npcHandler, text = 'The temple is a few floors over the depot. Just walk up the numerous stairs there.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'Muzir takes care of our bank business. His office is in the north-western part of the caliph\'s palace.'}) +keywordHandler:addKeyword({'shops'}, StdModule.say, {npcHandler = npcHandler, text = 'You can buy weapons, armor, tools, gems, magical equipment, furniture, spells and food here.'}) +keywordHandler:addKeyword({'depot'}, StdModule.say, {npcHandler = npcHandler, text = 'The depot is a place where you can safely store your belongings. You are also protected against attacks there. I escort newcomers there.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'ll show you around Darashia if you like. I can mark important locations on your map and give you some information about the town and the world status.'}) +keywordHandler:addKeyword({'town'}, StdModule.say, {npcHandler = npcHandler, text = 'Darashia is an oriental settlement ruled by Caliph Kazzan Ibn Gadral. We have a lot of shops, carpet travel and a rotworm plague, that sums it about up.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Behil. Glad to be your guide.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Daraman's blessings, Black Sabbatth, welcome to Darashia! Would you like some information and a map guide?") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Daraman's blessings, enjoy your stay in Darashia, |PLAYERNAME|") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/guide_davina.lua b/data/npc/scripts/guide_davina.lua new file mode 100644 index 00000000000..5b5d00b4c5e --- /dev/null +++ b/data/npc/scripts/guide_davina.lua @@ -0,0 +1,70 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'I\'m informed about the status the world is in. If you have questions, let me know.' }, + { text = 'Need some help finding your way through Liberty Bay? Let me assist you.' }, + { text = 'Free escort to the depot for newcomers!' }, + { text = 'Hello, is this your first visit to Liberty Bay? I can show you around the town.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local configMarks = { + {mark = "shops", position = Position(32293, 32824, 7), markId = MAPMARK_BAG, description = "Shops"}, + {mark = "depot", position = Position(32336, 32838, 7), markId = MAPMARK_LOCK, description = "Depot"}, + {mark = "temple", position = Position(32317, 32826, 7), markId = MAPMARK_TEMPLE, description = "Temple"} +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if isInArray({"map", "marks"}, msg) then + npcHandler:say("Would you like me to mark locations like - for example - the depot, bank and shops on your map?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 1 then + npcHandler:say("Here you go.", cid) + local mark + for i = 1, #configMarks do + mark = configMarks[i] + player:addMapMark(mark.position, mark.markId, mark.description) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") and npcHandler.topic[cid] >= 1 then + npcHandler:say("Well, nothing wrong about exploring the town on your own. Let me know if you need something!", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'information'}, StdModule.say, {npcHandler = npcHandler, text = 'Currently, I can tell you all about the town, its temple, the bank, shops, spell trainers and the depot, as well as about the world status.'}) +keywordHandler:addKeyword({'temple'}, StdModule.say, {npcHandler = npcHandler, text = 'The temple is just north west of the depot. You can\'t miss it.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'Jefrey, our bank clerk, can be found inside the depot. Easy to find.'}) +keywordHandler:addKeyword({'shops'}, StdModule.say, {npcHandler = npcHandler, text = 'You can buy weapons, armor, tools, gems, magical equipment, furniture and food here.'}) +keywordHandler:addKeyword({'depot'}, StdModule.say, {npcHandler = npcHandler, text = 'The depot is a place where you can safely store your belongings. You are also protected against attacks there. I escort newcomers there.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, I\'m a guide. I can mark important locations on your map and give you some information about the town. I do this for free, but I\'m always happy about a small donation if you can spare some money.'}) +keywordHandler:addKeyword({'town'}, StdModule.say, {npcHandler = npcHandler, text = 'This city has three main districts - a noble district, a merchant district and the slums. The class difference is clearly visible here. Most shops are in the merchant district. There are also large sugarcane plantations.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m Davina. Glad to help you today.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Hello there, |PLAYERNAME| and welcome to Liberty Bay! Would you like some information and a map guide?") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye and enjoy your stay in Liberty Bay, |PLAYERNAME|") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/guide_edna.lua b/data/npc/scripts/guide_edna.lua new file mode 100644 index 00000000000..7664d6b5013 --- /dev/null +++ b/data/npc/scripts/guide_edna.lua @@ -0,0 +1,67 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Want to know the status of all the world changes? Ask me.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local configMarks = { + {mark = "shops", position = Position(32827, 31239, 7), markId = MAPMARK_BAG, description = "Weapons and Amror"}, + {mark = "depot", position = Position(32786, 31248, 7), markId = MAPMARK_LOCK, description = "Depot"}, + {mark = "temple", position = Position(32786, 31276, 7), markId = MAPMARK_TEMPLE, description = "Temple"} +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if isInArray({"map", "marks"}, msg) then + npcHandler:say("Would you like me to mark locations like - for example - the depot, bank and shops on your map?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 1 then + npcHandler:say("Here you go.", cid) + local mark + for i = 1, #configMarks do + mark = configMarks[i] + player:addMapMark(mark.position, mark.markId, mark.description) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") and npcHandler.topic[cid] >= 1 then + npcHandler:say("Well, nothing wrong about exploring the town on your own. Let me know if you need something!", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'information'}, StdModule.say, {npcHandler = npcHandler, text = 'Currently, I can tell you all about the town, its temple, the bank, shops, spell trainers and the depot, as well as about the world status.'}) +keywordHandler:addKeyword({'temple'}, StdModule.say, {npcHandler = npcHandler, text = 'The temple is just south west of here. Actually, it\'s a temple raft and the priestess is somewhat... meow... you\'ll see what I mean.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'Our bank clerk Znozel is somewhat... special. You can find him north of this harbour and then to the right, past the tavern.'}) +keywordHandler:addKeyword({'shops'}, StdModule.say, {npcHandler = npcHandler, text = 'You can buy weapons, armor, tools, gems, magical equipment, furniture, spells and food here.'}) +keywordHandler:addKeyword({'depot'}, StdModule.say, {npcHandler = npcHandler, text = 'The depot is a place where you can safely store your belongings. You are also protected against attacks there. I escort newcomers there, but it\'s just north of here.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m the only feline guide in Tibia. I might not have fingers anymore, but with my paw I can still mark important locations on your map and give you some information about the town and the world status.'}) +keywordHandler:addKeyword({'town'}, StdModule.say, {npcHandler = npcHandler, text = 'Yalahar is a very old city of gigantic size, consisting of a city centre and eight quarters. The beings that are closest to be called rulers of the city are the Yalahari.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m Jonathan. Pleased to meet you.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Meow, welcome to Yalahar |PLAYERNAME|! Even though I might not look like it, I can give you {information} and a {map} guide. Need some?") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Enjoy your stay in Yalahar, |PLAYERNAME|. Meow.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/guide_elena.lua b/data/npc/scripts/guide_elena.lua new file mode 100644 index 00000000000..8e33f104664 --- /dev/null +++ b/data/npc/scripts/guide_elena.lua @@ -0,0 +1,74 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'I can inform you about the status of this world, if you\'re interested.' }, + { text = 'Hello, is this your first visit to Venore? I can show you around a little.' }, + { text = 'Talk to me if you need directions.' }, + { text = 'Need some help finding your way through Venore? Let me assist you.' }, + { text = 'Free escort to the depot for newcomers!' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local configMarks = { + {mark = "shops1", position = Position(32976, 32083, 6), markId = MAPMARK_BAG, description = "Magic Bazar"}, + {mark = "depot", position = Position(32919, 32071, 6), markId = MAPMARK_LOCK, description = "Depot"}, + {mark = "temple", position = Position(32958, 32078, 6), markId = MAPMARK_TEMPLE, description = "Temple"}, + {mark = "shop2", position = Position(32908, 32123, 6), markId = MAPMARK_TEMPLE, description = "Armors and Weapons"}, + {mark = "bank", position = Position(33011, 32053, 6), markId = MAPMARK_TEMPLE, description = "Bank"}, + {mark = "shop3", position = Position(32976, 32045, 6), markId = MAPMARK_TEMPLE, description = "Foods and Plants"} +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if isInArray({"map", "marks"}, msg) then + npcHandler:say("Would you like me to mark locations like - for example - the depot, bank and shops on your map?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 1 then + npcHandler:say("Here you go.", cid) + local mark + for i = 1, #configMarks do + mark = configMarks[i] + player:addMapMark(mark.position, mark.markId, mark.description) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") and npcHandler.topic[cid] >= 1 then + npcHandler:say("Well, nothing wrong about exploring the town on your own. Let me know if you need something!", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'information'}, StdModule.say, {npcHandler = npcHandler, text = 'Currently, I can tell you all about the town, its temple, the bank, shops - well, warehouses - spell trainers and the depot, as well as about the adventurer\'s guild, hunting grounds, quests and the world status.'}) +keywordHandler:addKeyword({'temple'}, StdModule.say, {npcHandler = npcHandler, text = 'The temple is pretty much in the middle of Venore. If you go south from this harbour, you can\'t miss it.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'The bank as well as jewel stores can be found in the House of Wealth, in the north-eastern part of Venore. I can mark it on your map if you want.'}) +keywordHandler:addKeyword({'shops'}, StdModule.say, {npcHandler = npcHandler, text = 'You can buy almost everything here! Visit one of our warehouses for weapons, armors, magical equipment, spells, gems, tools, furniture and everything else you can imagine.'}) +keywordHandler:addKeyword({'depot'}, StdModule.say, {npcHandler = npcHandler, text = 'The depot is a place where you can safely store your belongings. You are also protected against attacks there. I escort newcomers there.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I will help you find your way in the buzzing city of Venore. I can mark important locations on your map and give you some information about the town and the world status.'}) +keywordHandler:addKeyword({'town'}, StdModule.say, {npcHandler = npcHandler, text = 'This trading city has been built directly over a swamp and basically stands on stone pillars. We have many large warehouses here. To speak of \'shops\' would be an understatement.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m Elena, sweetheart. I love your name, |PLAYERNAME|.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome to Venore, |PLAYERNAME| Would you like some information and a map guide?") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye and enjoy your stay in Venore, |PLAYERNAME|.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/guide_jonathan.lua b/data/npc/scripts/guide_jonathan.lua new file mode 100644 index 00000000000..97fd041703a --- /dev/null +++ b/data/npc/scripts/guide_jonathan.lua @@ -0,0 +1,69 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Free escort to the depot for newcomers!' }, + { text = 'Hello, is this your first visit to Thais? I can show you around a little.' }, + { text = 'Need some help finding your way through Thais? Let me assist you.' }, + { text = 'Talk to me if you need directions.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local configMarks = { + {mark = "shops", position = Position(33210, 31818, 7), markId = MAPMARK_BAG, description = "Shops"}, + {mark = "depot", position = Position(33173, 31812, 7), markId = MAPMARK_LOCK, description = "Depot"}, + {mark = "temple", position = Position(33210, 31814, 7), markId = MAPMARK_TEMPLE, description = "Temple"} +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if isInArray({"map", "marks"}, msg) then + npcHandler:say("Would you like me to mark locations like - for example - the depot, bank and shops on your map?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 1 then + npcHandler:say("Here you go.", cid) + local mark + for i = 1, #configMarks do + mark = configMarks[i] + player:addMapMark(mark.position, mark.markId, mark.description) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") and npcHandler.topic[cid] >= 1 then + npcHandler:say("Well, nothing wrong about exploring the town on your own. Let me know if you need something!", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'information'}, StdModule.say, {npcHandler = npcHandler, text = 'Currently, I can tell you all about the town, its temple, the bank, shops, spell trainers and the depot, as well as about the world status.'}) +keywordHandler:addKeyword({'temple'}, StdModule.say, {npcHandler = npcHandler, text = 'The temple is near the shop area in the eastern part of the castle. Just go downstairs.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'Our local bank clerk is called Ebenizer. You can find him north of the depot, near the food shop.'}) +keywordHandler:addKeyword({'shops'}, StdModule.say, {npcHandler = npcHandler, text = 'You can buy weapons, armor, tools, gems, magical equipment, furniture, spells and food here.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m your guide to the beautiful town Edron. I can mark important locations on your map and give you some information about the town and the world status.'}) +keywordHandler:addKeyword({'town'}, StdModule.say, {npcHandler = npcHandler, text = 'The town of Edron with its shops and facilities is built inside strong castle walls. Another remarkable building is the magic academy.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m Jonathan. Pleased to meet you.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Hello there, |PLAYERNAME| and welcome to Edron! Would you like some {information} and a {map} guide?") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye and enjoy your stay in Edron, |PLAYERNAME|.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/guide_kroak.lua b/data/npc/scripts/guide_kroak.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/guide_kroak.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/guide_kunibert.lua b/data/npc/scripts/guide_kunibert.lua new file mode 100644 index 00000000000..672cfa163b4 --- /dev/null +++ b/data/npc/scripts/guide_kunibert.lua @@ -0,0 +1,68 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Talk to me if you need directions.' }, + { text = 'Hello, is this your first visit to Rathleton? I can show you around a little.' }, + { text = 'Free escort to the depot for newcomers!' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local configMarks = { + {mark = "depot", position = Position(33625, 31894, 6), markId = MAPMARK_LOCK, description = "Depot"}, + {mark = "temple", position = Position(33594, 31899, 6), markId = MAPMARK_TEMPLE, description = "Temple"} +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if isInArray({"map", "marks"}, msg) then + npcHandler:say("Would you like me to mark locations like - for example - the depot, bank and shops on your map?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 1 then + npcHandler:say("Here you go.", cid) + local mark + for i = 1, #configMarks do + mark = configMarks[i] + player:addMapMark(mark.position, mark.markId, mark.description) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") and npcHandler.topic[cid] >= 1 then + npcHandler:say("Well, nothing wrong about exploring the town on your own. Let me know if you need something!", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'information'}, StdModule.say, {npcHandler = npcHandler, text = 'Currently, I can tell you all about the town, its temple, the bank, shops, spell trainers and the depot, as well as about the world status.'}) +keywordHandler:addKeyword({'temple'}, StdModule.say, {npcHandler = npcHandler, text = 'The temple can be found in one of the uptown districts. Look for stairs up from the lower city, you\'ll find the temple in the northwest of the upper city.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'The First Oramond Bank is an important part of Rathleton, and is situated in the centre of the upper city. I can mark it on your map if you want.'}) +keywordHandler:addKeyword({'shops'}, StdModule.say, {npcHandler = npcHandler, text = 'You can buy almost everything here! Visit one of our shops for weapons, armors, magical equipment, spells, gems, tools, furnitureand everything else you can imagine.'}) +keyworkHandler:addKeyword({'depot'}, StdModule.say, {npcHandler = npcHandler, text = 'The depot is a place where you can safely store your belongings. You are also protected against attacks there. I escort newcomers there.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = ' I will help you find your way in the marvellous city of Rathleton. I can mark important locations on your map and give you someinformation about the town and the world status.'}) +keywordHandler:addKeyword({'town'}, StdModule.say, {npcHandler = npcHandler, text = 'This city is a modern marvel of progress. The city\'s wealth and industry is based on the famous glooth. The magistrate runs the city according to the wishes of its inhabitants.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m Kunibert, of course.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome to Rathleton, |PLAYERNAME|! Looking for a transport to the main isle of Oramond or would you like some information and a mapguide?") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye and enjoy your stay in Rathleton, |PLAYERNAME|") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/guide_luke.lua b/data/npc/scripts/guide_luke.lua new file mode 100644 index 00000000000..6b137097c9a --- /dev/null +++ b/data/npc/scripts/guide_luke.lua @@ -0,0 +1,70 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Free escort to the depot for newcomers!' }, + { text = 'Hello, is this your first visit to Thais? I can show you around a little.' }, + { text = 'Need some help finding your way through Thais? Let me assist you.' }, + { text = 'Talk to me if you need directions.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local configMarks = { + {mark = "shops", position = Position(32367, 32197, 7), markId = MAPMARK_BAG, description = "Shops"}, + {mark = "depot", position = Position(32321, 32212, 7), markId = MAPMARK_LOCK, description = "Depot"}, + {mark = "temple", position = Position(32369, 32241, 7), markId = MAPMARK_TEMPLE, description = "Temple"} +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if isInArray({"map", "marks"}, msg) then + npcHandler:say("Would you like me to mark locations like - for example - the depot, bank and shops on your map?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 1 then + npcHandler:say("Here you go.", cid) + local mark + for i = 1, #configMarks do + mark = configMarks[i] + player:addMapMark(mark.position, mark.markId, mark.description) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") and npcHandler.topic[cid] >= 1 then + npcHandler:say("Well, nothing wrong about exploring the town on your own. Let me know if you need something!", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'information'}, StdModule.say, {npcHandler = npcHandler, text = 'I can tell you all about the {town}, its {temple}, the {bank}, {shops}, {spell trainers} and the {depot}, as well as about the {world status}.'}) +keywordHandler:addKeyword({'temple'}, StdModule.say, {npcHandler = npcHandler, text = 'The temple is in the centre of Thais. Walk east from the harbour and pass by the {depot} until you reach the infamous crossroads, then turn south.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'We have two bankers, Suzy and Naji. Naji is right in the depot. For Suzi, exit the {depot} to the west and walk south-west. Don\'t forget that I can {mark} important locations on your map.'}) +keywordHandler:addKeyword({'shops'}, StdModule.say, {npcHandler = npcHandler, text = 'You can buy {weapons}, {armor}, {tools}, {gems}, {magical} equipment, {furniture} and {food} here.'}) +keywordHandler:addKeyword({'depot'}, StdModule.say, {npcHandler = npcHandler, text = 'The depot is a place where you can safely store your belongings. You are also protected against attacks there. I {escort} newcomers there.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m a guide, overworked and underpaid. I can mark important locations on your map and give you some information about the town and the world status.'}) +keywordHandler:addKeyword({'thais'}, StdModule.say, {npcHandler = npcHandler, text = 'Thais is the oldest settlement in Tibia. You can hear its history whisper when walking through the streets. Beware of criminals, but else it\'s a fine city.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m Luke. No jokes, please, I heard them all!'}) + +npcHandler:setMessage(MESSAGE_GREET, "Hello there, |PLAYERNAME| and welcome to Thais! Would you like some {information} and a {map} guide?") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye and enjoy your stay in Thais, |PLAYERNAME|.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/guide_meruka.lua b/data/npc/scripts/guide_meruka.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/guide_meruka.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/guide_rahlkora.lua b/data/npc/scripts/guide_rahlkora.lua new file mode 100644 index 00000000000..d5c36d2138c --- /dev/null +++ b/data/npc/scripts/guide_rahlkora.lua @@ -0,0 +1,71 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Need some help finding your way through Ankrahmun? Let me assist you.' }, + { text = 'Free escort to the depot for newcomers!' }, + { text = 'Need to know something about the status of this world? Let me answer your questions.' }, + { text = 'Hello, is this your first visit to Ankrahmun? I can show you around a little.' }, + { text = 'Talk to me if you need directions.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local configMarks = { + {mark = "shops", position = Position(33130, 32815, 7), markId = MAPMARK_BAG, description = "Shops"}, + {mark = "depot", position = Position(33126, 32841, 7), markId = MAPMARK_LOCK, description = "Depot"}, + {mark = "temple", position = Position(33195, 32852, 7), markId = MAPMARK_TEMPLE, description = "Temple"} +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if isInArray({"map", "marks"}, msg) then + npcHandler:say("Would you like me to mark locations like - for example - the depot, bank and shops on your map?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 1 then + npcHandler:say("Here you go.", cid) + local mark + for i = 1, #configMarks do + mark = configMarks[i] + player:addMapMark(mark.position, mark.markId, mark.description) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") and npcHandler.topic[cid] >= 1 then + npcHandler:say("Well, nothing wrong about exploring the town on your own. Let me know if you need something!", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'information'}, StdModule.say, {npcHandler = npcHandler, text = 'Currently, I can tell you all about the town, its temple, the bank, shops, spell trainers and the depot.'}) +keywordHandler:addKeyword({'temple'}, StdModule.say, {npcHandler = npcHandler, text = 'The temple is in the south-eastern part of town. If you exit the depot to the south and walk east - slightly south-east - you can\'t miss it.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'Tesha is in charge of both the bank and the gem store. You can find her on the market pyramid. Just exit the depot on the north side and walk up the next pyramid.'}) +keywordHandler:addKeyword({'shops'}, StdModule.say, {npcHandler = npcHandler, text = 'You can buy weapons, armor, tools, gems, magical equipment, furniture, spells and food here.'}) +keywordHandler:addKeyword({'depot'}, StdModule.say, {npcHandler = npcHandler, text = 'The depot is a place where you can safely store your belongings. You are also protected against attacks there. I escort newcomers there.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I will help you to find your way around Ankrahmun. I can mark important locations on your map and give you some information about the town.'}) +keywordHandler:addKeyword({'town'}, StdModule.say, {npcHandler = npcHandler, text = 'Ankrahmun consists almost completely of pyramids. You can walk up and down those pyramids just like you\'d climb up stairs. Most shops are on the upper floors.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Rahlkora. I\'m a guide.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome to Ankrahmun, |PLAYERNAME| This city can be a bit confusing at first. Would you like some information and a map guide?") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye and enjoy your stay in Ankrahmun, |PLAYERNAME|") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/guide_thelandil.lua b/data/npc/scripts/guide_thelandil.lua new file mode 100644 index 00000000000..8cce2b8fae2 --- /dev/null +++ b/data/npc/scripts/guide_thelandil.lua @@ -0,0 +1,67 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Hello, is this your first visit to Ab\'Dendriel? I can show you around a little.' }, + { text = 'Talk to me if you need directions.' }, + { text = 'Free escort to the depot for newcomers!' }, + { text = 'If you want to know something about the status of this world, talk to me.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local configMarks = { + {mark = "depot", position = Position(32681, 31686, 7), markId = MAPMARK_LOCK, description = "Depot and Shops"}, + {mark = "temple", position = Position(32732, 31634, 7), markId = MAPMARK_TEMPLE, description = "Temple"} +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if isInArray({"map", "marks"}, msg) then + npcHandler:say("Would you like me to mark locations like - for example - the depot, bank and shops on your map?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 1 then + npcHandler:say("Here you go.", cid) + local mark + for i = 1, #configMarks do + mark = configMarks[i] + player:addMapMark(mark.position, mark.markId, mark.description) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") and npcHandler.topic[cid] >= 1 then + npcHandler:say("Well, nothing wrong about exploring the town on your own. Let me know if you need something!", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'information'}, StdModule.say, {npcHandler = npcHandler, text = 'Currently, I can tell you all about the town, its temple, the bank, shops, spell trainers and the depot, as well as about the world status.'}) +keywordHandler:addKeyword({'temple'}, StdModule.say, {npcHandler = npcHandler, text = 'The temple is built around the elves\' holy tree. You can find it north of this harbour.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'Finarfin is in charge of the bank. You can find him on the lowest floor of the depot.'}) +keywordHandler:addKeyword({'shops'}, StdModule.say, {npcHandler = npcHandler, text = 'You can buy weapons, armor, tools, gems, magical equipment, instruments, furniture, spells and food here.'}) +keywordHandler:addKeyword({'depot'}, StdModule.say, {npcHandler = npcHandler, text = 'The depot is a place where you can safely store your belongings. You are also protected against attacks there. I escort newcomers there.'}) +keywordHandler:addKeyword({'town'}, StdModule.say, {npcHandler = npcHandler, text = 'The elves have constructed Ab\'Dendriel mainly in and on trees. There is also a large underground cave system with shops, a prison and troll caves.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Hello there, |PLAYERNAME| and welcome to Ab'Dendriel! Would you like some information and a map guide?") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye and enjoy your stay in Ab'Dendriel, |PLAYERNAME|") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/guide_tiko.lua b/data/npc/scripts/guide_tiko.lua new file mode 100644 index 00000000000..a67e1eb319b --- /dev/null +++ b/data/npc/scripts/guide_tiko.lua @@ -0,0 +1,70 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Free escort to the depot for newcomers!' }, + { text = 'Hello, is this your first visit to Port Hope? I can show you around a little.' }, + { text = 'Talk to me if you need directions.' }, + { text = 'Ask me if you want to know something about the world status!' }, + { text = 'Need some help finding your way through Port Hope? Let me assist you.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local configMarks = { + {mark = "depot", position = Position(32631, 32742, 7), markId = MAPMARK_LOCK, description = "Depot"}, + {mark = "temple", position = Position(32594, 32745, 7), markId = MAPMARK_TEMPLE, description = "Temple"} +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if isInArray({"map", "marks"}, msg) then + npcHandler:say("Would you like me to mark locations like - for example - the depot, bank and shops on your map?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 1 then + npcHandler:say("Here you go.", cid) + local mark + for i = 1, #configMarks do + mark = configMarks[i] + player:addMapMark(mark.position, mark.markId, mark.description) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") and npcHandler.topic[cid] >= 1 then + npcHandler:say("Well, nothing wrong about exploring the town on your own. Let me know if you need something!", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'information'}, StdModule.say, {npcHandler = npcHandler, text = 'Currently, I can tell you all about the town, its temple, the bank, shops, spell trainers and the depot, as well as about the world status.'}) +keywordHandler:addKeyword({'temple'}, StdModule.say, {npcHandler = npcHandler, text = 'The temple is in the north-eastern part of town, left of the depot. The priest there has a little alcohol problem, though. It\'s sad.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'Our bank can be found one floor above the depot. Just talk to Ferks.'}) +keywordHandler:addKeyword({'shops'}, StdModule.say, {npcHandler = npcHandler, text = 'The shops here are very close to one another. I can mark them for you if you\'d like.'}) +keywordHandler:addKeyword({'depot'}, StdModule.say, {npcHandler = npcHandler, text = 'The depot is a place where you can safely store your belongings. You are also protected against attacks there. I escort newcomers there.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'ll help you not to get lost in Port Hope. I can mark important locations on your map and give you some information about the town and the world status.'}) +keywordHandler:addKeyword({'town'}, StdModule.say, {npcHandler = npcHandler, text = 'The inhabitants of Port Hope are bravely facing the constant threat from the jungle. The town is built on pile dwellings and most shops are close to each other.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m Tiko and your guide today. Have a good day!'}) + +npcHandler:setMessage(MESSAGE_GREET, "Hello there, and welcome to Port Hope! Would you like some information and a map guide?") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye and enjoy your stay in Port Hope, |PLAYERNAME|") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gundralph.lua b/data/npc/scripts/gundralph.lua new file mode 100644 index 00000000000..084a61fc306 --- /dev/null +++ b/data/npc/scripts/gundralph.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Utevo vis lux!'} } +npcHandler:addModule(VoiceModule:new(voices)) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/gurbasch.lua b/data/npc/scripts/gurbasch.lua new file mode 100644 index 00000000000..c2a705d64c8 --- /dev/null +++ b/data/npc/scripts/gurbasch.lua @@ -0,0 +1,48 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Passages to Kazordoon! Gotta try the beer there.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, text, cost, discount, destination) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = text[1], cost = cost, discount = discount}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, text = text[2], cost = cost, discount = discount, destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = text[3], reset = true}) +end + +addTravelKeyword('farmine', {'Do you seek a ride to Farmine for |TRAVELCOST|?', 'Hold on!', 'You shouldn\'t miss the experience.'}, 110, {'postman', 'new frontier'}, + function(player) + local destination = Position(33025, 31553, 14) + if player:getStorageValue(Storage.TheNewFrontier.Mission05) == 7 then --if The New Frontier Quest 'Mission 05: Getting Things Busy' complete then Stage 3 + destination.z = 10 + elseif player:getStorageValue(Storage.TheNewFrontier.Mission03) >= 2 then --if The New Frontier Quest 'Mission 03: Strangers in the Night' complete then Stage 2 + destination.z = 12 + end + + return destination + end +) +addTravelKeyword('kazordoon', {'Do you want to go to Kazordoon to try the beer there? |TRAVELCOST|?', 'Set the sails!', 'Then not.'}, 160, 'postman', Position(32660, 31957, 15)) + +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Do you want me take you to {Kazordoon} or {Farmine}?'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, |PLAYERNAME|! May Earth protect you, even whilst sailing!') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Until next time.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Until next time.') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/h.l..lua b/data/npc/scripts/h.l..lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/h.l..lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/habdel.lua b/data/npc/scripts/habdel.lua new file mode 100644 index 00000000000..d78062d3315 --- /dev/null +++ b/data/npc/scripts/habdel.lua @@ -0,0 +1,80 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, 'outfit') then + if player:getSex() == PLAYERSEX_FEMALE then + npcHandler:say('My scimitar? Well, mylady, I do not want to sound rude, but I don\'t think a scimitar would fit to your beautiful outfit. If you are looking for an accessory, why don\'t you talk to Ishina?', cid) + return true + end + if player:getStorageValue(Storage.OutfitQuest.firstOrientalAddon) < 1 then + npcHandler:say('My scimitar? Yes, that is a true masterpiece. Of course I could make one for you, but I have a small request. Would you fulfil a task for me?', cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, 'comb') then + if player:getSex() == PLAYERSEX_FEMALE then + npcHandler:say('Comb? This is a weapon shop.', cid) + return true + end + if player:getStorageValue(Storage.OutfitQuest.firstOrientalAddon) == 1 then + npcHandler:say('Have you brought a mermaid\'s comb for Ishina?', cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + 'Listen, um... I know that Ishina has been wanting a comb for a long time... not just any comb, but a mermaid\'s comb. She said it prevents split ends... or something. ...', + 'Do you think you could get one for me so I can give it to her? I really would appreciate it.' + }, cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + player:setStorageValue(Storage.OutfitQuest.DefaultStart, 1) + player:setStorageValue(Storage.OutfitQuest.firstOrientalAddon, 1) + npcHandler:say('Brilliant! I will wait for you to return with a mermaid\'s comb then.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + if not player:removeItem(5945, 1) then + npcHandler:say('No... that\'s not it.', cid) + npcHandler.topic[cid] = 0 + return true + end + player:setStorageValue(Storage.OutfitQuest.firstOrientalAddon, 2) + player:addOutfitAddon(150, 1) + player:addOutfitAddon(146, 1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + npcHandler:say('Yeah! That\'s it! I can\'t wait to give it to her! Oh - but first, I\'ll fulfil my promise: Here is your scimitar! Thanks again!', cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] ~= 0 then + npcHandler:say('Ah well. Doesn\'t matter.', cid) + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'weapons'}, StdModule.say, {npcHandler = npcHandler, text = 'I sell the finest weapons in town. If you\'d like to see my offers, ask me for a {trade}.'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome |PLAYERNAME|! See the fine {weapons} I sell.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye. Come back soon.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye. Come back soon.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/hagor.lua b/data/npc/scripts/hagor.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/hagor.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/hairycles.lua b/data/npc/scripts/hairycles.lua new file mode 100644 index 00000000000..f0cf5bb55e3 --- /dev/null +++ b/data/npc/scripts/hairycles.lua @@ -0,0 +1,490 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + if Player(cid):getStorageValue(Storage.TheApeCity.Questline) < 12 then + npcHandler:setMessage(MESSAGE_GREET, 'Oh! Hello! Hello! Did not notice! So {busy}.') + else + npcHandler:setMessage(MESSAGE_GREET, 'Be greeted, friend of the ape people. If you want to {trade}, just ask for my offers. If you are injured, ask for healing.') + end + return true +end + +local function releasePlayer(cid) + if not Player(cid) then + return + end + + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + local questProgress = player:getStorageValue(Storage.TheApeCity.Questline) + if msgcontains(msg, 'mission') then + if questProgress < 1 then + npcHandler:say('These are dire times for our people. Problems plenty are in this times. But me people not grant trust easy. Are you willing to prove you friend of ape people?', cid) + npcHandler.topic[cid] = 1 + + elseif questProgress == 1 then + if player:getStorageValue(Storage.QuestChests.WhisperMoss) == 1 then + npcHandler:say('Oh, you brought me whisper moss? Good hairless ape you are! Can me take it?', cid) + npcHandler.topic[cid] = 3 + else + npcHandler:say('Please hurry. Bring me whisper moss from dworc lair. Make sure it is from dworc lair! Take it yourself only! If you need to hear background of all again, ask Hairycles for {background}.', cid) + end + + elseif questProgress == 2 then + npcHandler:say({ + 'Whisper moss strong is, but me need liquid that humans have to make it work ...', + 'Our raiders brought it from human settlement, it\'s called cough syrup. Go ask healer there for it.' + }, cid) + player:setStorageValue(Storage.TheApeCity.Questline, 3) + + elseif questProgress == 3 then + npcHandler:say('You brought me that cough syrup from human healer me asked for?', cid) + npcHandler.topic[cid] = 4 + + elseif questProgress == 4 then + npcHandler:say('Little ape should be healthy soon. Me so happy is. Thank you again! But me suspect we in more trouble than we thought. Will you help us again?', cid) + npcHandler.topic[cid] = 5 + + elseif questProgress == 5 then + npcHandler:say('You got scroll from lizard village in south east?', cid) + npcHandler.topic[cid] = 7 + + elseif questProgress == 6 then + npcHandler:say({ + 'Ah yes that scroll. Sadly me not could read it yet. But the holy banana me insight gave! In dreams Hairycles saw where to find solution. ...', + 'Me saw a stone with lizard signs and other signs at once. If you read signs and tell Hairycles, me will know how to read signs. ...', + 'You go east to big desert. In desert there city. East of city under sand hidden tomb is. You will have to dig until you find it, so take shovel. ...', + 'Go down in tomb until come to big level and then go down another. There you find a stone with signs between two huge red stones. ...', + 'Read it and return to me. Are you up to that challenge?' + }, cid) + npcHandler.topic[cid] = 8 + + elseif questProgress == 7 then + if player:getStorageValue(Storage.TheApeCity.ParchmentDecyphering) == 1 then + npcHandler:say('Ah yes, you read the signs in tomb? Good! May me look into your mind to see what you saw?', cid) + npcHandler.topic[cid] = 9 + else + npcHandler:say('You still don\'t know signs on stone, go and look for it in tomb east in desert.', cid) + end + + elseif questProgress == 8 then + npcHandler:say({ + 'So much there is to do for Hairycles to prepare charm that will protect all ape people. ...', + 'You can help more. To create charm of life me need mighty token of life! Best is egg of a regenerating beast as a hydra is. ...', + 'Bring me egg of hydra please. You may find it in lair of Hydra at little lake south east of our lovely city Banuta! You think you can do?' + }, cid) + npcHandler.topic[cid] = 10 + + elseif questProgress == 9 then + npcHandler:say('You bring Hairycles egg of hydra?', cid) + npcHandler.topic[cid] = 11 + + elseif questProgress == 10 then + npcHandler:say({ + 'Last ingredient for charm of life is thing to lure magic. Only thing me know like that is mushroom called witches\' cap. Me was told it be found in isle called Fibula, where humans live. ...', + 'Hidden under Fibula is a secret dungeon. There you will find witches\' cap. Are you willing to go there for good ape people?' + }, cid) + npcHandler.topic[cid] = 12 + + elseif questProgress == 11 then + npcHandler:say('You brought Hairycles witches\' cap from Fibula?', cid) + npcHandler.topic[cid] = 13 + + elseif questProgress == 12 then + npcHandler:say({ + 'Mighty life charm is protecting us now! But my people are still in danger. Danger from within. ...', + 'Some of my people try to mimic lizards to become strong. Like lizards did before, this cult drinks strange fluid that lizards left when fled. ...', + 'Under the city still the underground temple of lizards is. There you find casks with red fluid. Take crowbar and destroy three of them to stop this madness. Are you willing to do that?' + }, cid) + npcHandler.topic[cid] = 14 + + elseif questProgress == 13 then + if player:getStorageValue(Storage.TheApeCity.Casks) == 3 then + npcHandler:say('You do please Hairycles again, friend. Me hope madness will not spread further now. Perhaps you are ready for other mission.', cid) + player:setStorageValue(Storage.TheApeCity.Questline, 14) + else + npcHandler:say('Please destroy three casks in the complex beneath Banuta, so my people will come to senses again.', cid) + end + + elseif questProgress == 14 then + npcHandler:say({ + 'Now that the false cult was stopped, we need to strengthen the spirit of my people. We need a symbol of our faith that ape people can see and touch. ...', + 'Since you have proven a friend of the ape people I will grant you permission to enter the forbidden land. ...', + 'To enter the forbidden land in the north-east of the jungle, look for a cave in the mountains east of it. There you will find the blind prophet. ...', + 'Tell him Hairycles you sent and he will grant you entrance. ...', + 'Forbidden land is home of Bong. Holy giant ape big as mountain. Don\'t annoy him in any way but look for a hair of holy ape. ...', + 'You might find at places he has been, should be easy to see them since Bong is big. ...', + 'Return a hair of the holy ape to me. Will you do this for Hairycles?' + }, cid) + npcHandler.topic[cid] = 15 + + elseif questProgress == 15 then + if player:getStorageValue(Storage.TheApeCity.HolyApeHair) == 1 then + npcHandler:say('You brought hair of holy ape?', cid) + npcHandler.topic[cid] = 16 + else + npcHandler:say('Get a hair of holy ape from forbidden land in east. Speak with blind prophet in cave.', cid) + end + + elseif questProgress == 16 then + npcHandler:say({ + 'You have proven yourself a friend, me will grant you permission to enter the deepest catacombs under Banuta which we have sealed in the past. ...', + 'Me still can sense the evil presence there. We did not dare to go deeper and fight creatures of evil there. ...', + 'You may go there, fight the evil and find the monument of the serpent god and destroy it with hammer me give to you. ...', + 'Only then my people will be safe. Please tell Hairycles, will you go there?' + }, cid) + npcHandler.topic[cid] = 17 + + elseif questProgress == 17 then + if player:getStorageValue(Storage.TheApeCity.SnakeDestroyer) == 1 then + npcHandler:say({ + 'Finally my people are safe! You have done incredible good for ape people and one day even me brethren will recognise that. ...', + 'I wish I could speak for all when me call you true friend but my people need time to get accustomed to change. ...', + 'Let us hope one day whole Banuta will greet you as a friend. Perhaps you want to check me offers for special friends... or shamanic powers.' + }, cid) + player:setStorageValue(Storage.TheApeCity.Questline, 18) + player:addAchievement('Friend of the Apes') + else + npcHandler:say('Me know its much me asked for but go into the deepest catacombs under Banuta and destroy the monument of the serpent god.', cid) + end + + else + npcHandler:say('No more missions await you right now, friend. Perhaps you want to check me offers for special friends... or shamanic powers.', cid) + end + + elseif msgcontains(msg, 'background') then + if questProgress == 1 + and player:getStorageValue(Storage.QuestChests.WhisperMoss) ~= 1 then + npcHandler:say({ + 'So listen, little ape was struck by plague. Hairycles not does know what plague it is. That is strange. Hairycles should know. But Hairycles learnt lots and lots ...', + 'Me sure to make cure so strong to drive away all plague. But to create great cure me need powerful components ...', + 'Me need whisper moss. Whisper moss growing south of human settlement is. Problem is, evil little dworcs harvest all whisper moss immediately ...', + 'Me know they hoard some in their underground lair. My people raided dworcs often before humans came. So we know the moss is hidden in east of upper level of dworc lair ...', + 'You go there and take good moss from evil dworcs. Talk with me about mission when having moss.' + }, cid) + end + + elseif msgcontains(msg, 'outfit') or msgcontains(msg, 'shamanic') then + if questProgress == 18 then + if player:getStorageValue(Storage.TheApeCity.ShamanOutfit) ~= 1 then + npcHandler:say('Me truly proud of you, friend. You learn many about plants, charms and ape people. Me want grant you shamanic power now. You ready?', cid) + npcHandler.topic[cid] = 18 + else + npcHandler:say('You already are shaman and doctor. Me proud of you.', cid) + end + else + npcHandler:say('You not have finished journey for wisdom yet, young human.', cid) + end + + elseif msgcontains(msg, 'heal') then + if questProgress > 11 then + if player:getHealth() < 50 then + player:addHealth(50 - player:getHealth()) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + elseif player:getCondition(CONDITION_FIRE) then + player:removeCondition(CONDITION_FIRE) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + elseif player:getCondition(CONDITION_POISON) then + player:removeCondition(CONDITION_POISON) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + else + npcHandler:say('You look for food and rest.', cid) + end + else + npcHandler:say('You look for food and rest.', cid) + end + + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, 'yes') then + npcHandler:say('To become friend of ape people a long and difficult way is. We do not trust easy but help is needed. Will you listen to story of Hairycles?', cid) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, 'no') then + npcHandler:say('Hairycles sad is now. But perhaps you will change mind one day.', cid) + npcHandler.topic[cid] = 0 + end + + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, 'yes') then + npcHandler:say({ + 'So listen, little ape was struck by plague. Hairycles not does know what plague it is. That is strange. Hairycles should know. But Hairycles learnt lots and lots ...', + 'Me sure to make cure so strong to drive away all plague. But to create great cure me need powerful components ...', + 'Me need whisper moss. Whisper moss growing south of human settlement is. Problem is, evil little dworcs harvest all whisper moss immediately ...', + 'Me know they hoard some in their underground lair. My people raided dworcs often before humans came. So we know the moss is hidden in east of upper level of dworc lair ...', + 'You go there and take good moss from evil dworcs. Talk with me about mission when having moss.' + }, cid) + player:setStorageValue(Storage.TheApeCity.Started, 1) + player:setStorageValue(Storage.TheApeCity.Questline, 1) + player:setStorageValue(Storage.TheApeCity.DworcDoor, 1) + elseif msgcontains(msg, 'no') then + npcHandler:say('Hairycles thought better of you.', cid) + addEvent(releasePlayer, 1000, cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 3 then + if msgcontains(msg, 'yes') then + if not player:removeItem(4838, 1) then + npcHandler:say('Stupid, you no have the moss me need. Go get it. It\'s somewhere in dworc lair. If you lost it, they might restocked it meanwhile. If you need to hear background of all again, ask Hairycles for {background}.', cid) + player:setStorageValue(Storage.QuestChests.WhisperMoss, -1) + return true + end + + npcHandler:say('Ah yes! That\'s it. Thank you for bringing mighty whisper moss to Hairycles. It will help but still much is to be done. Just ask for other mission if you ready.', cid) + player:setStorageValue(Storage.TheApeCity.Questline, 2) + elseif msgcontains(msg, 'no') then + npcHandler:say('Strange being you are! Our people need help!', cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 4 then + if msgcontains(msg, 'yes') then + if not player:removeItem(4839, 1) then + npcHandler:say('No no, not right syrup you have. Go get other, get right health syrup.', cid) + return true + end + + npcHandler:say('You so good! Brought syrup to me! Thank you, will prepare cure now. Just ask for {mission} if you want help again.', cid) + player:setStorageValue(Storage.TheApeCity.Questline, 4) + elseif msgcontains(msg, 'no') then + npcHandler:say('Please hurry, urgent it is!', cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 5 then + if msgcontains(msg, 'yes') then + npcHandler:say({ + 'So listen, please. Plague was not ordinary plague. That\'s why Hairycles could not heal at first. It is new curse of evil lizard people ...', + 'I think curse on little one was only a try. We have to be prepared for big strike ...', + 'Me need papers of lizard magician! For sure you find it in his hut in their dwelling. It\'s south east of jungle. Go look there please! Are you willing to go?' + }, cid) + npcHandler.topic[cid] = 6 + elseif msgcontains(msg, 'no') then + npcHandler:say('Me sad. Me expected better from you!', cid) + addEvent(releasePlayer, 1000, cid) + npcHandler.topic[cid] = 0 + end + + elseif npcHandler.topic[cid] == 6 then + if msgcontains(msg, 'yes') then + npcHandler:say('Good thing that is! Report about your mission when have scroll.', cid) + player:setStorageValue(Storage.TheApeCity.Questline, 5) + player:setStorageValue(Storage.TheApeCity.ChorDoor, 1) + elseif msgcontains(msg, 'no') then + npcHandler:say('Me sad. Me expected better from you!', cid) + addEvent(releasePlayer, 1000, cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 7 then + if msgcontains(msg, 'yes') then + if not player:removeItem(5956, 1) then + if player:getStorageValue(Storage.QuestChests.OldParchment) == 1 then + npcHandler:say('That\'s bad news. If you lost it, only way to get other is to kill holy serpents. But you can\'t go there so you must ask adventurers who can.', cid) + else + npcHandler:say('No! That not scroll me looking for. Silly hairless ape you are. Go to village of lizards and get it there on your own!', cid) + end + return true + end + + npcHandler:say('You brought scroll with lizard text? Good! I will see what text tells me! Come back when ready for other mission.', cid) + player:setStorageValue(Storage.TheApeCity.Questline, 6) + elseif msgcontains(msg, 'no') then + npcHandler:say('That\'s bad news. If you lost it, only way to get other is to kill holy serpents. But you can\'t go there so you must ask adventurers who can.', cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 8 then + if msgcontains(msg, 'yes') then + npcHandler:say('Good thing that is! Report about mission when you have read those signs.', cid) + player:setStorageValue(Storage.TheApeCity.Questline, 7) + elseif msgcontains(msg, 'no') then + npcHandler:say('Me sad. Me expected better from you!', cid) + addEvent(releasePlayer, 1000, cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 9 then + if msgcontains(msg, 'yes') then + npcHandler:say('Oh, so clear is all now! Easy it will be to read the signs now! Soon we will know what to do! Thank you again! Ask for mission if you feel ready.', cid) + player:setStorageValue(Storage.TheApeCity.Questline, 8) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + elseif msgcontains(msg, 'no') then + npcHandler:say('Me need to see it in your mind, other there is no way to proceed.', cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 10 then + if msgcontains(msg, 'yes') then + npcHandler:say('You brave hairless ape! Get me hydra egg. If you lose egg, you probably have to fight many, many hydras to get another.', cid) + player:setStorageValue(Storage.TheApeCity.Questline, 9) + elseif msgcontains(msg, 'no') then + npcHandler:say('Me sad. Me expected better from you!', cid) + addEvent(releasePlayer, 1000, cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 11 then + if msgcontains(msg, 'yes') then + if not player:removeItem(4850, 1) then + npcHandler:say('You not have egg of hydra. Please get one!', cid) + return true + end + + npcHandler:say('Ah, the egg! Mighty warrior you be! Thank you. Hairycles will put it at safe place immediately.', cid) + player:setStorageValue(Storage.TheApeCity.Questline, 10) + elseif msgcontains(msg, 'no') then + npcHandler:say('Please hurry. Hairycles not knows when evil lizards strike again.', cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 12 then + if msgcontains(msg, 'yes') then + npcHandler:say('Long journey it will take, good luck to you.', cid) + player:setStorageValue(Storage.TheApeCity.Questline, 11) + player:setStorageValue(Storage.TheApeCity.FibulaDoor, 1) + elseif msgcontains(msg, 'no') then + npcHandler:say('Me sad. Me expected better from you!', cid) + addEvent(releasePlayer, 1000, cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 13 then + if msgcontains(msg, 'yes') then + if not player:removeItem(4840, 1) then + npcHandler:say('Not right mushroom you have. Find me a witches\' cap on Fibula!', cid) + return true + end + + npcHandler:say('Incredible, you brought a witches\' cap! Now me can prepare mighty charm of life. Yet still other {missions} will await you, friend.', cid) + player:setStorageValue(Storage.TheApeCity.Questline, 12) + player:setStorageValue(Storage.TheApeCity.FibulaDoor, -1) + elseif msgcontains(msg, 'no') then + npcHandler:say('Please try to find me a witches\' cap on Fibula.', cid) + addEvent(releasePlayer, 1000, cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 14 then + if msgcontains(msg, 'yes') then + npcHandler:say('Hairycles sure you will make it. Good luck, friend.', cid) + player:setStorageValue(Storage.TheApeCity.Questline, 13) + player:setStorageValue(Storage.TheApeCity.CasksDoor, 1) + elseif msgcontains(msg, 'no') then + npcHandler:say('Me sad. Please reconsider.', cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 15 then + if msgcontains(msg, 'yes') then + npcHandler:say('Hairycles proud of you. Go and find holy hair. Good luck, friend.', cid) + player:setStorageValue(Storage.TheApeCity.Questline, 15) + elseif msgcontains(msg, 'no') then + npcHandler:say('Me sad. Please reconsider.', cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 16 then + if msgcontains(msg, 'yes') then + if not player:removeItem(4843, 1) then + npcHandler:say('You no have hair. You lost it? Go and look again.', cid) + player:setStorageValue(Storage.TheApeCity.HolyApeHair, -1) + return true + end + + npcHandler:say('Incredible! You got a hair of holy Bong! This will raise the spirit of my people. You are truly a friend. But one last mission awaits you.', cid) + player:setStorageValue(Storage.TheApeCity.Questline, 16) + elseif msgcontains(msg, 'no') then + npcHandler:say('You no have hair. You lost it? Go and look again.', cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 17 then + if msgcontains(msg, 'yes') then + npcHandler:say('Hairycles sure you will make it. Just use hammer on all that looks like snake or lizard. Tell Hairycles if you succeed with mission.', cid) + player:setStorageValue(Storage.TheApeCity.Questline, 17) + player:addItem(4846, 1) + elseif msgcontains(msg, 'no') then + npcHandler:say('Me sad. Please reconsider.', cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 18 then + if msgcontains(msg, 'yes') then + npcHandler:say('Friend of the ape people! Take my gift and become me apprentice! Here is shaman clothing for you!', cid) + player:addOutfit(154) + player:addOutfit(158) + player:setStorageValue(Storage.TheApeCity.ShamanOutfit, 1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + elseif msgcontains(msg, 'no') then + npcHandler:say('Come back if change mind.', cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 19 then + if msgcontains(msg, 'yes') then + if not player:removeItem(8111, 1) then + npcHandler:say('You have no cookie that I\'d like.', cid) + return true + end + + player:setStorageValue(Storage.WhatAFoolish.CookieDelivery.Hairycles, 1) + if player:getCookiesDelivered() == 10 then + player:addAchievement('Allow Cookies?') + end + + Npc():getPosition():sendMagicEffect(CONST_ME_GIFT_WRAPS) + npcHandler:say('Thank you, you are ... YOU SON OF LIZARD!', cid) + addEvent(releasePlayer, 1000, cid) + elseif msgcontains(msg, 'no') then + npcHandler:say('I see.', cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'busy'}, StdModule.say, {npcHandler = npcHandler, text = 'Me great {wizard}. Me great doctor of {ape people}. Me know many plants. Me old and me have seen many things.'}) +keywordHandler:addKeyword({'wizard'}, StdModule.say, {npcHandler = npcHandler, text = 'We see many things and learning quick. Merlkin magic learn quick, quick. We just watch and learn. Sometimes we try and learn.'}) +keywordHandler:addKeyword({'things'}, StdModule.say, {npcHandler = npcHandler, text = 'Things not good now. Need helper to do {mission} for me people.'}) +keywordHandler:addKeyword({'ape people'}, StdModule.say, {npcHandler = npcHandler, text = 'We be {kongra}, {sibang} and {merlkin}. Strange hairless ape people live in city called Port Hope.'}) +keywordHandler:addKeyword({'kongra'}, StdModule.say, {npcHandler = npcHandler, text = 'Kongra verry strong. Kongra verry angry verry fast. Take care when kongra comes. Better climb on highest tree.'}) +keywordHandler:addKeyword({'sibang'}, StdModule.say, {npcHandler = npcHandler, text = 'Sibang verry fast and funny. Sibang good gather food. Sibang know {jungle} well.'}) +keywordHandler:addKeyword({'merlkin'}, StdModule.say, {npcHandler = npcHandler, text = 'Merlkin we are. Merlkin verry wise, merlkin learn many things quick. Teach other apes things a lot. Making {heal} and making {magic}.'}) +keywordHandler:addKeyword({'magic'}, StdModule.say, {npcHandler = npcHandler, text = 'We see many things and learning quick. Merlkin magic learn quick, quick. We just watch and learn. Sometimes we try and learn.'}) +keywordHandler:addKeyword({'jungle'}, StdModule.say, {npcHandler = npcHandler, text = 'Jungle is dangerous. Jungle also provides us food. Take care when in jungle and safe you be.'}) + +local function onTradeRequest(cid) + if Player(cid):getStorageValue(Storage.TheApeCity.Questline) < 18 then + return false + end + + return true +end + +npcHandler:setCallback(CALLBACK_ONTRADEREQUEST, onTradeRequest) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/hal.lua b/data/npc/scripts/hal.lua new file mode 100644 index 00000000000..fcae2980f7e --- /dev/null +++ b/data/npc/scripts/hal.lua @@ -0,0 +1,53 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if(msgcontains(msg, "report")) then + if(player:getStorageValue(Storage.InServiceofYalahar.Questline) == 8 or player:getStorageValue(Storage.InServiceofYalahar.Questline) == 12) then + npcHandler:say("Hicks! I... I... . ", cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, player:getStorageValue(Storage.InServiceofYalahar.Questline) + 1) + player:setStorageValue(Storage.InServiceofYalahar.Mission02, player:getStorageValue(Storage.InServiceofYalahar.Mission02) + 1) -- StorageValue for Questlog "Mission 02: Watching the Watchmen" + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "pass")) then + npcHandler:say("You can {pass} either to the {Arena Quarter} or {Alchemist Quarter}. Which one will it be?", cid) + npcHandler.topic[cid] = 1 + elseif(msgcontains(msg, "arena")) then + if(npcHandler.topic[cid] == 1) then + local destination = Position(32688, 31193, 7) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "alchemist")) then + if(npcHandler.topic[cid] == 1) then + local destination = Position(32688, 31188, 7) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/halif.lua b/data/npc/scripts/halif.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/halif.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/halvar.lua b/data/npc/scripts/halvar.lua new file mode 100644 index 00000000000..3f269c29e3c --- /dev/null +++ b/data/npc/scripts/halvar.lua @@ -0,0 +1,85 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'rules'}, StdModule.say, {npcHandler = npcHandler, text = 'What do you want to know? Something about the three different {difficulties}, the {general} rules or the {prices}? Maybe you also want to know what happens when you {die}?'}) +keywordHandler:addKeyword({'difficulties'}, StdModule.say, {npcHandler = npcHandler, text = 'There are three difficulties: Greenhorn, Scrapper and Warlord. On each challenge you will be confronted with ten monsters increasing in strength.'}) +keywordHandler:addKeyword({'levels'}, StdModule.say, {npcHandler = npcHandler, text = 'There are three difficulties: Greenhorn, Scrapper and Warlord. On each challenge you will be confronted with ten monsters increasing in strength.'}) +keywordHandler:addKeyword({'difficulty'}, StdModule.say, {npcHandler = npcHandler, text = 'There are three difficulties: Greenhorn, Scrapper and Warlord. On each challenge you will be confronted with ten monsters increasing in strength.'}) +keywordHandler:addKeyword({'greenhorn'}, StdModule.say, {npcHandler = npcHandler, text = 'That is the easiest way in our arena. The {fee} is 1000 gold. We were setting this up for of our children to challenge some easy monsters and train them for the future.'}) +keywordHandler:addKeyword({'scrapper'}, StdModule.say, {npcHandler = npcHandler, text = 'The most common difficulty for us. The {fee} is 5000 gold. So if you are experienced in fighting middle class monsters this is your challenge!'}) +keywordHandler:addKeyword({'warlord'}, StdModule.say, {npcHandler = npcHandler, text = 'Only the strongest among us will take this challenge. The {fee} is 10000 gold. If you pass that I promise you the respect of all citizens here. You will be a hero!'}) +keywordHandler:addKeyword({'fee'}, StdModule.say, {npcHandler = npcHandler, text = 'The fee is either 1000, 5000 or 10000 gold for one try. Remember that if you {die}, it is YOUR problem and you won\'t be able to get back to your corpse and your backpack.'}) +keywordHandler:addKeyword({'die'}, StdModule.say, {npcHandler = npcHandler, text = 'It would be better not to die! In every pit there is an emergency exit, the portal to the south. If you die in a pit... well... your corpse and backpack are gone, so you enter the arena at your own risk.'}) +keywordHandler:addKeyword({'general'}, StdModule.say, {npcHandler = npcHandler, text = 'Basically you pay me a {fee}, and you are sent into an arena with 10 different stages. If you succeed you will be rewarded accordingly.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'My job is to explain about the rules and to get the fee from the competitors.'}) +keywordHandler:addKeyword({'mission'}, StdModule.say, {npcHandler = npcHandler, text = 'Well I would rather call it an {Ultimate Challenge} than a mission.'}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + local arenaId = player:getStorageValue(Storage.SvargrondArena.Arena) + if msgcontains(msg, 'fight') or msgcontains(msg, 'pit') or msgcontains(msg, 'challenge') or msgcontains(msg, 'arena') then + if player:getStorageValue(Storage.SvargrondArena.PitDoor) == 1 then + npcHandler:say('You already paid the fee, go and fight!', cid) + return true + end + + if arenaId < 1 then + arenaId = 1 + player:setStorageValue(Storage.SvargrondArena.Arena, arenaId) + end + + if ARENA[arenaId] then + npcHandler:say('So you agree with the {rules} and want to participate in the {challenge}? The {fee} for one try in {' .. ARENA[arenaId].name .. '} is ' .. ARENA[arenaId].price .. ' gold pieces. Do you really want to participate and pay the {fee}?', cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say('You\'ve already completed the arena in all {difficulty levels}.', cid) + npcHandler.topic[cid] = 0 + end + + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, 'yes') then + if not ARENA[arenaId] then + npcHandler.topic[cid] = 0 + return true + end + + if player:removeMoneyNpc(ARENA[arenaId].price) then + player:setStorageValue(Storage.SvargrondArena.PitDoor, 1) + npcHandler:say('As you wish! You can pass the door now and enter the teleporter to the pits.', cid) + + local cStorage = ARENA[arenaId].questLog + if player:getStorageValue(cStorage) ~= 1 then + player:setStorageValue(cStorage, 1) + end + else + npcHandler:say('You do not have enough money.', cid) + end + else + npcHandler:say('Come back when you are ready then.', cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, 'Hello competitor! Do you want to {fight} in the arena or shall I explain the {rules} first?') +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/hamilton.lua b/data/npc/scripts/hamilton.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/hamilton.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/hamish.lua b/data/npc/scripts/hamish.lua new file mode 100644 index 00000000000..e3c7aefe0ed --- /dev/null +++ b/data/npc/scripts/hamish.lua @@ -0,0 +1,149 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + {text = "Health potions to refill your health in combat!"}, + {text = "Potions! Wand! Runes! Get them here!"}, + {text = "Pack of monsters give you trouble? Throw an area rune at them!"}, + {text = "Careful with that! That's a highly reactive potion you have there!"}, + {text = "Run out of mana or a little kablooie? Come to me to resupply!"} +} + +npcHandler:addModule(VoiceModule:new(voices)) + +keywordHandler:addKeyword({'name'}, StdModule.say, + { + npcHandler = npcHandler, + text = "Hamish MacGuffin, at your disposal." + } +) +keywordHandler:addKeyword({'job'}, StdModule.say, + { + npcHandler = npcHandler, + text = "I craft highly efficient runes, wands and potions - always handy when you're in a fight against monsters! \z + Ask me for a trade to browse through my stock." + } +) +keywordHandler:addKeyword({'rookgaard'}, StdModule.say, + { + npcHandler = npcHandler, + text = "Nope. Doesn't sound familiar." + } +) +keywordHandler:addKeyword({'coltrayne'}, StdModule.say, + { + npcHandler = npcHandler, + text = "Never asked about his past. Seems it's a pretty gloomy one. \z + But he's an excellent blacksmith and seems content enough with his work here." + } +) +keywordHandler:addKeyword({'inigo'}, StdModule.say, + { + npcHandler = npcHandler, + text = "Inigo taught me a trick or two since I joined Mr Morris' little crowd. \z + Quite a nice old chap who's seen much of the world and knows his way around here. \z + You should definitely ask him if you need help." + } +) +keywordHandler:addKeyword({'garamond'}, StdModule.say, + { + npcHandler = npcHandler, + text = "Can be quite feisty if you doubt his seniorship. \z + Knows a thing or two about spells, though. Useful knowledge." + } +) +keywordHandler:addKeyword({'wentworth'}, StdModule.say, + { + npcHandler = npcHandler, + text = "Keeran? He's a bit like Plunderpurse's shadow, isn't he? \z + Loves numbers, but I believe underneath it all he always wanted to break out of his boring little job in the city." + } +) +keywordHandler:addKeyword({'richard'}, StdModule.say, + { + npcHandler = npcHandler, + text = "Seems good-natured enough a guy. Nimble with his hands, be it cooking or carpentering. \z + Seems to want to keep his mind off something, so he's always busy fixing stuff or cooking something up." + } +) +keywordHandler:addKeyword({'mr morris'}, StdModule.say, + { + npcHandler = npcHandler, + text = "If it wasn't for Mr Morris, maybe none of us would be alive. Or at least, none of us would be here. \z + He's been everywhere and gathered some adventurers around him to investigate the secrets of Dawnport." + } +) +keywordHandler:addKeyword({'oressa'}, StdModule.say, + { + npcHandler = npcHandler, + text = "Our druid, down in the temple. Just appeared out of the blue one day. Keeps to herself. \z + She must have some reason to stay with us rather than roam the bigger Mainland. Well, we all have our reasons." + } +) +keywordHandler:addKeyword({'plunderpurse'}, StdModule.say, + { + npcHandler = npcHandler, + text = "Now there's someone who has lived life to the full! Don't know though \z + whether I should really believe that he's a clerk now." + } +) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "dawnport") then + npcHandler:say( + { + "Small and deceptively friendly-looking island. Well, I used to study the plants and herbs here for my potions.", + "Nowadays, I leave that to Oressa, she has a better way with that horrible wildlife here. \z + I prefer to distil potions in the quiet of my lab. \z + If you need some potions, runes or other magic equipment, ask for a trade." + }, + cid, true, false, 200) + elseif msgcontains(msg, "mainland") then + npcHandler:say( + { + "Dawnport is not far off from the coast of the Tibian Mainland. Lots of cities, monsters, bandits, \z + brigands, mean folk and people of low understanding with no sense of respect towards alchemical genius. \z + ", + "Ahem. Once you're level 8, you should be experienced enough to choose your definite vocation and leave \z + Dawnport for Main - and Tibia definitely needs more skilled adventurers to keep those monsters in check \z + which roam our lands!" + }, + cid, true, false, 200) + elseif msgcontains(msg, "ser tybald") then + npcHandler:say( + { + "I wish I had thought of changing my name to that of a hero. Would have smoothed my way no end!", + "Anyway, whatever he was before he joined, Tybald now fits the bill of the legendary hero. \z + He even has a crush on lady Oressa. Cute. " + }, + cid, true, false, 200) + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Hi there, fellow adventurer. \z + What's your need? Say {trade} and we'll soon get you fixed up. Or ask me about potions, wands, or runes.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Use your runes wisely!") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/hanna.lua b/data/npc/scripts/hanna.lua new file mode 100644 index 00000000000..e05e87ef29e --- /dev/null +++ b/data/npc/scripts/hanna.lua @@ -0,0 +1,92 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Gems and jewellery! Best prices in town!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "addon") or msgcontains(msg, "outfit") or msgcontains(msg, "hat") then + local addonProgress = player:getStorageValue(Storage.OutfitQuest.Citizen.AddonHat) + if addonProgress < 1 then + npcHandler:say("Pretty, isn't it? My friend Amber taught me how to make it, but I could help you with one if you like. What do you say?", cid) + npcHandler.topic[cid] = 1 + elseif addonProgress == 1 then + npcHandler:say("Oh, you're back already? Did you bring a legion helmet, 100 chicken feathers and 50 honeycombs?", cid) + npcHandler.topic[cid] = 2 + elseif addonProgress == 2 then + npcHandler:say('Pretty hat, isn\'t it?', cid) + end + return true + end + + if npcHandler.topic[cid] == 1 then + if msgcontains(msg, 'yes') then + player:setStorageValue(Storage.OutfitQuest.Ref, math.max(0, player:getStorageValue(Storage.OutfitQuest.Ref)) + 1) + player:setStorageValue(Storage.OutfitQuest.Citizen.AddonHat, 1) + player:setStorageValue(Storage.OutfitQuest.Citizen.MissionHat, 1) + npcHandler:say('Okay, here we go, listen closely! I need a few things... a basic hat of course, maybe a legion helmet would do. Then about 100 chicken feathers... and 50 honeycombs as glue. That\'s it, come back to me once you gathered it!', cid) + else + npcHandler:say('Aw, I guess you don\'t like feather hats. No big deal.', cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, 'yes') then + if player:getItemCount(2480) < 1 then + npcHandler:say('Sorry, but I can\'t see a legion helmet.', cid) + elseif player:getItemCount(5890) < 100 then + npcHandler:say('Sorry, but you don\'t enough chicken feathers.', cid) + elseif player:getItemCount(5902) < 50 then + npcHandler:say('Sorry, but you don\'t have enough honeycombs.', cid) + else + npcHandler:say('Great job! That must have taken a lot of work. Okay, you put it like this... then glue like this... here!', cid) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + + player:removeItem(2480, 1) + player:removeItem(5902, 50) + player:removeItem(5890, 100) + + player:addOutfitAddon(136, 2) + player:addOutfitAddon(128, 2) + + player:setStorageValue(Storage.OutfitQuest.Ref, math.min(0, player:getStorageValue(Storage.OutfitQuest.Ref) - 1)) + player:setStorageValue(Storage.OutfitQuest.Citizen.MissionHat, 0) + player:setStorageValue(Storage.OutfitQuest.Citizen.AddonHat, 2) + end + else + npcHandler:say('Maybe another time.', cid) + end + npcHandler.topic[cid] = 0 + end + + return true +end + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am a jeweler. Maybe you want to have a look at my wonderful offers.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'I am Hanna.'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Oh, please come in, |PLAYERNAME|. What do you need? Have a look at my wonderful {offers} in gems and jewellery.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/hardek.lua b/data/npc/scripts/hardek.lua new file mode 100644 index 00000000000..3707720d15f --- /dev/null +++ b/data/npc/scripts/hardek.lua @@ -0,0 +1,27 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Buying and selling all sorts of weapons and armors!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am buying some weapons and armors."}) + +npcHandler:setMessage(MESSAGE_GREET, "Hello |PLAYERNAME|! Do you need my services?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye. Visit me whenever you want to sell something.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye. Visit me whenever you want to sell something.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/harkath_bloodblade.lua b/data/npc/scripts/harkath_bloodblade.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/harkath_bloodblade.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/harlow.lua b/data/npc/scripts/harlow.lua new file mode 100644 index 00000000000..7fc6795f5a0 --- /dev/null +++ b/data/npc/scripts/harlow.lua @@ -0,0 +1,26 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local travelNode = keywordHandler:addKeyword({'vengoth'}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to Vengoth for |TRAVELCOST|?', cost = 0}) + travelNode:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = 100, destination = Position(32858, 31549, 7) }) + travelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, reset = true, text = 'Oh well.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Can I interest you in a trip to {Vengoth}?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye then.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/harlow_vengoth.lua b/data/npc/scripts/harlow_vengoth.lua new file mode 100644 index 00000000000..fbaeb58e29a --- /dev/null +++ b/data/npc/scripts/harlow_vengoth.lua @@ -0,0 +1,26 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local travelNode = keywordHandler:addKeyword({'yalahar'}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to Yalahar for |TRAVELCOST|?', cost = 0}) + travelNode:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = 0, destination = Position(32837, 31366, 7) }) + travelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, reset = true, text = 'Oh well.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Want to go back to {Yalahar} for 50 gold? Just ask me.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye then.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/harlowtrade.lua b/data/npc/scripts/harlowtrade.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/harlowtrade.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/harog.lua b/data/npc/scripts/harog.lua new file mode 100644 index 00000000000..e6ce63bbc2b --- /dev/null +++ b/data/npc/scripts/harog.lua @@ -0,0 +1,92 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function getTable(player) + local itemsList = { + {name="metal fitting", id=10034, buy=500}, + {name="nail", id=8309, sell=10}, + {name="flask of rust remover", id=9930, buy=50} + } + + local rustremover = { + {name="flask of rust remover", id=9930, buy=50}, + } + + if player:getStorageValue(Storage.HiddenCityOfBeregar.JusticeForAll) == 6 then + for i = 1, #rustremover do + itemsList[#itemsList] = rustremover[i] + end + end + + return itemsList +end + +local function setNewTradeTable(table) + local items, item = {} + for i = 1, #table do + item = table[i] + items[item.id] = {itemId = item.id, buyPrice = item.buy, sellPrice = item.sell, subType = 0, realName = item.name} + end + return items +end + +local function onBuy(cid, item, subType, amount, ignoreCap, inBackpacks) + local player = Player(cid) + local items = setNewTradeTable(getTable(player)) + if not ignoreCap and player:getFreeCapacity() < ItemType(items[item].itemId):getWeight(amount) then + return player:sendTextMessage(MESSAGE_FAILURE, 'You don\'t have enough cap.') + end + if not player:removeMoneyNpc(items[item].buyPrice * amount) then + selfSay("You don't have enough money.", cid) + else + player:addItem(items[item].itemId, amount) + return player:sendTextMessage(MESSAGE_TRADE, 'Bought '..amount..'x '..items[item].realName..' for '..items[item].buyPrice * amount..' gold coins.') + end + return true +end + +local function onSell(cid, item, subType, amount, ignoreCap, inBackpacks) + local player = Player(cid) + local items = setNewTradeTable(getTable(player)) + if items[item].sellPrice and player:removeItem(items[item].itemId, amount) then + player:addMoney(items[item].sellPrice * amount) + return player:sendTextMessage(MESSAGE_TRADE, 'Sold '..amount..'x '..items[item].realName..' for '..items[item].sellPrice * amount..' gold coins.') + else + selfSay("You don't have item to sell.", cid) + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, "trade") then + local player = Player(cid) + local items = setNewTradeTable(getTable(player)) + openShopWindow(cid, getTable(player), onBuy, onSell) + npcHandler:say("Keep in mind you won't find better offers here. Just browse through my wares.", cid) + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, 'Hello.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'It was a pleasure to help you, |PLAYERNAME|.') +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/haroun.lua b/data/npc/scripts/haroun.lua new file mode 100644 index 00000000000..f60bba5e207 --- /dev/null +++ b/data/npc/scripts/haroun.lua @@ -0,0 +1,79 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if isInArray({"enchanted chicken wing", "boots of haste"}, msg) then + npcHandler:say('Do you want to trade Boots of haste for Enchanted Chicken Wing?', cid) + npcHandler.topic[cid] = 1 + elseif isInArray({"warrior sweat", "warrior helmet"}, msg) then + npcHandler:say('Do you want to trade 4 Warrior Helmet for Warrior Sweat?', cid) + npcHandler.topic[cid] = 2 + elseif isInArray({"fighting spirit", "royal helmet"}, msg) then + npcHandler:say('Do you want to trade 2 Royal Helmet for Fighting Spirit', cid) + npcHandler.topic[cid] = 3 + elseif isInArray({"magic sulphur", "fire sword"}, msg) then + npcHandler:say('Do you want to trade 3 Fire Sword for Magic Sulphur', cid) + npcHandler.topic[cid] = 4 + elseif isInArray({"job", "items"}, msg) then + npcHandler:say('I trade Enchanted Chicken Wing for Boots of Haste, Warrior Sweat for 4 Warrior Helmets, Fighting Spirit for 2 Royal Helmet Magic Sulphur for 3 Fire Swords', cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg,'yes') and npcHandler.topic[cid] <= 4 and npcHandler.topic[cid] >= 1 then + local trade = { + { NeedItem = 2195, Ncount = 1, GiveItem = 5891, Gcount = 1}, -- Enchanted Chicken Wing + { NeedItem = 2475, Ncount = 4, GiveItem = 5885, Gcount = 1}, -- Flask of Warrior's Sweat + { NeedItem = 2498, Ncount = 2, GiveItem = 5884, Gcount = 1}, -- Spirit Container + { NeedItem = 2392, Ncount = 3, GiveItem = 5904, Gcount = 1} -- Magic Sulphur + } + if player:getItemCount(trade[npcHandler.topic[cid]].NeedItem) >= trade[npcHandler.topic[cid]].Ncount then + player:removeItem(trade[npcHandler.topic[cid]].NeedItem, trade[npcHandler.topic[cid]].Ncount) + player:addItem(trade[npcHandler.topic[cid]].GiveItem, trade[npcHandler.topic[cid]].Gcount) + return npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry but you don\'t have the item.', cid) + end + elseif msgcontains(msg,'no') and (npcHandler.topic[cid] >= 1 and npcHandler.topic[cid] <= 5) then + npcHandler:say('Ok then.', cid) + npcHandler.topic[cid] = 0 + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + return true +end + +local function onTradeRequest(cid) + local player = Player(cid) + + if player:getStorageValue(Storage.DjinnWar.MaridFaction.Mission03) ~= 3 then + npcHandler:say('I\'m sorry, human. But you need Gabel\'s permission to trade with me.', cid) + return false + end + + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Be greeted, human |PLAYERNAME|. How can a humble djinn be of service?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Farewell! May the serene light of the enlightened one rest shine on your travels.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Farewell, human.") +npcHandler:setMessage(MESSAGE_SENDTRADE, 'At your service, just browse through my wares.') + +npcHandler:setCallback(CALLBACK_ONTRADEREQUEST, onTradeRequest) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/harsky.lua b/data/npc/scripts/harsky.lua new file mode 100644 index 00000000000..b2c9e0881b2 --- /dev/null +++ b/data/npc/scripts/harsky.lua @@ -0,0 +1,52 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +keywordHandler:addKeyword({'hi'}, StdModule.say, {npcHandler = npcHandler, onlyUnfocus = true, text = "MIND YOUR MANNERS COMMONER! To address the king greet with his title!"}) +keywordHandler:addKeyword({'hello'}, StdModule.say, {npcHandler = npcHandler, onlyUnfocus = true, text = "MIND YOUR MANNERS COMMONER! To address the king greet with his title!"}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if isInArray({'fuck', 'idiot', 'asshole', 'ass', 'fag', 'stupid', 'tyrant', 'shit', 'lunatic'}, msg) then + local player = Player(cid) + local conditions = { CONDITION_POISON, CONDITION_FIRE, CONDITION_ENERGY, CONDITION_BLEEDING, CONDITION_PARALYZE, CONDITION_DROWN, CONDITION_FREEZING, CONDITION_DAZZLED, CONDITION_CURSED } + for i = 1, #conditions do + if player:getCondition(conditions[i]) then + player:removeCondition(conditions[i]) + end + end + player:getPosition():sendMagicEffect(CONST_ME_EXPLOSIONAREA) + player:addHealth(1 - player:getHealth()) + npcHandler:say('Take this!', cid) + Npc():getPosition():sendMagicEffect(CONST_ME_YELLOW_RINGS) + end + return true +end + +-- Greeting +keywordHandler:addGreetKeyword({'hail king'}, {npcHandler = npcHandler, text = 'HAIL TO THE KING!'}) +keywordHandler:addGreetKeyword({'salutations king'}, {npcHandler = npcHandler, text = 'HAIL TO THE KING!'}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'LONG LIVE THE KING!') +npcHandler:setMessage(MESSAGE_FAREWELL, 'LONG LIVE THE KING! You may leave now!') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/hawkyr.lua b/data/npc/scripts/hawkyr.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/hawkyr.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/helor.lua b/data/npc/scripts/helor.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/helor.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/hemor_the_guard.lua b/data/npc/scripts/hemor_the_guard.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/hemor_the_guard.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/henricus.lua b/data/npc/scripts/henricus.lua new file mode 100644 index 00000000000..a25a5d25188 --- /dev/null +++ b/data/npc/scripts/henricus.lua @@ -0,0 +1,333 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local flaskCost = 1000 + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + local missing, totalBlessPrice = Blessings.getInquisitionPrice(player) + + if msgcontains(msg, "inquisitor") then + npcHandler:say("The churches of the gods entrusted me with the enormous and responsible task to lead the inquisition. I leave the field work to inquisitors who I recruit from fitting people that cross my way.", cid) + elseif msgcontains(msg, "join") then + if player:getStorageValue(Storage.TheInquisition.Questline) < 1 then + npcHandler:say("Do you want to join the inquisition?", cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, "blessing") or msgcontains(msg, "bless") then + if player:getStorageValue(Storage.TheInquisition.Questline) == 25 then --if quest is done + npcHandler:say("Do you want to receive the blessing of the inquisition - which means ".. (missing == 5 and "all five available" or missing ) .." blessings - for " .. totalBlessPrice .. " gold?", cid) + npcHandler.topic[cid] = 7 + else + npcHandler:say("You cannot get this blessing unless you have completed The Inquisition Quest.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "flask") or msgcontains(msg, "special flask") then + if player:getStorageValue(Storage.TheInquisition.Questline) >= 12 then -- give player the ability to purchase the flask. + npcHandler:say("Do you want to buy the special flask of holy water for " .. flaskCost .. " gold?" , cid) + npcHandler.topic[cid] = 8 + else + npcHandler:say("You do not need this flask right now.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "mission") or msgcontains(msg, "report") then + if player:getStorageValue(Storage.TheInquisition.Questline) < 1 then + npcHandler:say("Do you want to join the inquisition?", cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(Storage.TheInquisition.Questline) == 1 then + npcHandler:say({ + "Let's see if you are worthy. Take an inquisitor's field guide from the box in the back room. ...", + "Follow the instructions in the guide to talk to the Thaian guards that protect the walls and gates of the city and test their loyalty. Then report to me about your {mission}." + }, cid) + player:setStorageValue(Storage.TheInquisition.Questline, 2) + player:setStorageValue(Storage.TheInquisition.Mission01, 1) -- The Inquisition Questlog- "Mission 1: Interrogation" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheInquisition.Questline) == 2 then + npcHandler:say("Your current mission is to investigate the reliability of certain guards. Are you done with that mission?", cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.TheInquisition.Questline) == 3 then + npcHandler:say({ + "Listen, we have information about a heretic coven that hides in a mountain called the Big Old One. The witches reach this cursed place on flying brooms and think they are safe there. ...", + "I've arranged a flying carpet that will bring you to their hideout. Travel to Femor Hills and tell the carpet pilot the codeword 'eclipse' ...", + "He'll bring you to your destination. At their meeting place, you'll find a cauldron in which they cook some forbidden brew ...", + "Use this vial of holy water to destroy the brew. Also steal their grimoire and bring it to me." + }, cid) + player:setStorageValue(Storage.TheInquisition.Questline, 4) + player:setStorageValue(Storage.TheInquisition.Mission02, 1) -- The Inquisition Questlog- "Mission 2: Eclipse" + player:addItem(7494, 1) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheInquisition.Questline) == 5 then + if player:removeItem(8702, 1) then + npcHandler:say({ + "I think it's time to truly test your abilities. One of our allies has requested assistance. I think you are just the right person to help him ...", + "Storkus is an old and grumpy dwarf who works as a vampire hunter since many, many decades. He's quite successful but even hehas his limits. ...", + "So occasionally, we send him help. In return he trains and tests our recruits. It's an advantageous agreement for both sides ...", + "You'll find him in his cave at the mountain outside of Kazordoon. He'll tell you about your next mission." + }, cid) + player:setStorageValue(Storage.TheInquisition.Questline, 6) + player:setStorageValue(Storage.TheInquisition.Mission02, 3) -- The Inquisition Questlog- "Mission 2: Eclipse" + player:setStorageValue(Storage.TheInquisition.Mission03, 1) -- The Inquisition Questlog- "Mission 3: Vampire Hunt" + else + npcHandler:say("You need bring me the witches' grimoire.", cid) + end + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheInquisition.Questline) > 5 and player:getStorageValue(Storage.TheInquisition.Questline) < 11 then + npcHandler:say("Your current mission is to help the vampire hunter Storkus. Are you done with that mission? ", cid) + npcHandler.topic[cid] = 4 + elseif player:getStorageValue(Storage.TheInquisition.Questline) == 11 then + npcHandler:say({ + "We've got a report about an abandoned and haunted house in Liberty Bay. I want you to examine this house. It's the only ruin in Liberty Bay so you should have no trouble finding it. ...", + "There's an evil being somewhere. I assume that it will be easier to find the right spot at night. Use this vial of holy water on that spot to drive out the evil being." + }, cid) + player:setStorageValue(Storage.TheInquisition.Questline, 12) + player:setStorageValue(Storage.TheInquisition.Mission04, 1) -- The Inquisition Questlog- "Mission 4: The Haunted Ruin" + player:addItem(7494, 1) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheInquisition.Questline) == 12 or player:getStorageValue(Storage.TheInquisition.Questline) == 13 then + npcHandler:say("Your current mission is to exorcise an evil being from a house in Liberty Bay. Are you done with that mission? ", cid) + npcHandler.topic[cid] = 5 + elseif player:getStorageValue(Storage.TheInquisition.Questline) == 14 then + npcHandler:say({ + "You've handled heretics, witches, vampires and ghosts. Now be prepared to face the most evil creatures we are fighting - demons. Your new task is extremely simple, though far from easy. ...", + "Go and slay demonic creatures wherever you find them. Bring me 20 of their essences as a proof of your accomplishments." + }, cid) + player:setStorageValue(Storage.TheInquisition.Questline, 15) + player:setStorageValue(Storage.TheInquisition.Mission05, 1) -- The Inquisition Questlog- "Mission 5: Essential Gathering" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheInquisition.Questline) == 15 then + if player:removeItem(6500, 20) then + npcHandler:say({ + "You're indeed a dedicated protector of the true believers. Don't stop now. Kill as many of these creatures as you can. ...", + "I also have a reward for your great efforts. Talk to me about your {demon hunter outfit} anytime from now on. Afterwards, let's talk about the next mission that's awaiting you." + }, cid) + player:setStorageValue(Storage.TheInquisition.Questline, 16) + player:setStorageValue(Storage.TheInquisition.Mission05, 2) -- The Inquisition Questlog- "Mission 5: Essential Gathering" + else + npcHandler:say("You need 20 of them.", cid) + end + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheInquisition.Questline) == 17 then + npcHandler:say({ + "We've got information about something very dangerous going on on the isle of Edron. The demons are preparing something there ...", + "Something that is a threat to all of us. Our investigators were able to acquire vital information before some of them were slain by a demon named Ungreez. ...", + "It'll be your task to take revenge and to kill that demon. You'll find him in the depths of Edron. Good luck." + }, cid) + player:setStorageValue(Storage.TheInquisition.Questline, 18) + player:setStorageValue(Storage.TheInquisition.Mission06, 1) -- The Inquisition Questlog- "Mission 6: The Demon Ungreez" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheInquisition.Questline) == 19 then + npcHandler:say({ + "So the beast is finally dead! Thank the gods. At least some things work out in our favour ...", + "Our other operatives were not that lucky, though. But you will learn more about that in your next {mission}." + }, cid) + player:setStorageValue(Storage.TheInquisition.Questline, 20) + player:setStorageValue(Storage.TheInquisition.Mission06, 3) -- The Inquisition Questlog- "Mission 6: The Demon Ungreez" + player:addOutfitAddon(288, 1) + player:addOutfitAddon(289, 1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheInquisition.Questline) == 20 then + npcHandler:say("Destroy the shadow nexus using this vial of holy water and kill all demon lords.", cid) + player:setStorageValue(Storage.TheInquisition.Questline, 21) + player:setStorageValue(Storage.TheInquisition.Mission07, 1) -- The Inquisition Questlog- "Mission 7: The Shadow Nexus" + player:addItem(7494, 1) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheInquisition.Questline) == 21 or player:getStorageValue(Storage.TheInquisition.Questline) == 22 then + npcHandler:say("Your current mission is to destroy the shadow nexus in the Demon Forge. Are you done with that mission?", cid) + npcHandler.topic[cid] = 6 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 2 then + npcHandler:say("So be it. Now you are a member of the inquisition. You might ask me for a {mission} to raise in my esteem.", cid) + player:setStorageValue(Storage.TheInquisition.Questline, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + if player:getStorageValue(Storage.TheInquisition.WalterGuard) == 1 and player:getStorageValue(Storage.TheInquisition.KulagGuard) == 1 and player:getStorageValue(Storage.TheInquisition.GrofGuard) == 1 and player:getStorageValue(Storage.TheInquisition.MilesGuard) == 1 and player:getStorageValue(Storage.TheInquisition.TimGuard) == 1 then + npcHandler:say({ + "Indeed, this is exactly what my other sources told me. Of course I knew the outcome of this investigation in advance. This was just a test. ...", + "Well, now that you've proven yourself as useful, you can ask me for another mission. Let's see if you can handle some field duty, too." + }, cid) + player:setStorageValue(Storage.TheInquisition.Questline, 3) + player:setStorageValue(Storage.TheInquisition.Mission01, 7) -- The Inquisition Questlog- "Mission 1: Interrogation" + else + npcHandler:say("You haven't done your mission yet.", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 4 then + if player:getStorageValue(Storage.TheInquisition.Questline) == 10 then + npcHandler:say("Good, you've returned. Your skill in practical matters seems to be useful. If you're ready for a further mission, just ask. ", cid) + player:setStorageValue(Storage.TheInquisition.Questline, 11) + player:setStorageValue(Storage.TheInquisition.Mission03, 6) -- The Inquisition Questlog- "Mission 3: Vampire Hunt" + else + npcHandler:say("You haven't done your mission with {Storkus} yet.", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 5 then + if player:getStorageValue(Storage.TheInquisition.Questline) == 13 then + npcHandler:say("Well, this was an easy task, but your next mission will be much more challenging. ", cid) + player:setStorageValue(Storage.TheInquisition.Questline, 14) + player:setStorageValue(Storage.TheInquisition.Mission04, 3) -- The Inquisition Questlog- "Mission 4: The Haunted Ruin" + else + npcHandler:say("You haven't done your mission with {Storkus} yet.", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 6 then + if player:getStorageValue(Storage.TheInquisition.Questline) == 22 then + npcHandler:say({ + "Incredible! You're a true defender of faith! I grant you the title of a High Inquisitor for your noble deeds. From now on you can obtain the blessing of the inquisition which makes the pilgrimage of ashes obsolete ...", + "The blessing of the inquisition will bestow upon you all available blessings for the price of 110000 gold. Also, don't forget to ask me about your {outfit} to receive the final addon as demon hunter." + }, cid) + player:setStorageValue(Storage.TheInquisition.Questline, 23) + player:setStorageValue(Storage.TheInquisition.Mission07, 3) -- The Inquisition Questlog- "Mission 7: The Shadow Nexus" + player:addAchievement('High Inquisitor') + else + npcHandler:say("Come back when you have destroyed the shadow nexus.", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 8 then + if player:removeMoneyNpc(flaskCost) then + npcHandler:say("Here is your new flask!, |PLAYERNAME|.", cid) + player:addItem(7494, 1) + else + npcHandler:say("Come back when you have enough money.", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 7 then + if missing == 0 then + npcHandler:say("You already have been blessed!", cid) + elseif player:removeMoneyNpc(totalBlessPrice) then + npcHandler:say("You have been blessed by all of five gods!, |PLAYERNAME|.", cid) + player:addMissingBless(false) + player:getPosition():sendMagicEffect(CONST_ME_HOLYAREA) + else + npcHandler:say("Come back when you have enough money.", cid) + end + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] > 0 then + npcHandler:say("Then no.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "outfit") then + if player:getStorageValue(Storage.TheInquisition.Questline) == 16 then + npcHandler:say("Here is your demon hunter outfit. You deserve it. Unlock more addons by completing more missions.", cid) + player:setStorageValue(Storage.TheInquisition.Questline, 17) + player:setStorageValue(Storage.TheInquisition.Mission05, 3) -- The Inquisition Questlog- "Mission 5: Essential Gathering" + player:addOutfit(288, 0) + player:addOutfit(289, 0) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheInquisition.Questline) == 23 then + npcHandler:say("Here is the final addon for your demon hunter outfit. Congratulations!", cid) + player:setStorageValue(Storage.TheInquisition.Questline, 24) + player:setStorageValue(Storage.TheInquisition.Mission07, 4) -- The Inquisition Questlog- "Mission 7: The Shadow Nexus" + player:setStorageValue(Storage.TheInquisition.RewardDoor, 1) + player:addOutfitAddon(288, 1) + player:addOutfitAddon(289, 1) + player:addOutfitAddon(288, 2) + player:addOutfitAddon(289, 2) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:addAchievement('Demonbane') + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'dark') then + npcHandler:say({ + 'The dark powers are always present. If a human shows only the slightest weakness, they try to corrupt him and to lure him into their service. ...', + 'We must be constantly aware of evil that comes in many disguises.' + }, cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'king') then + npcHandler:say({ + 'The Thaian kings are crowned by a representative of the churches. This means they reign in the name of the gods of good and are part of the godly plan for humanity. ...', + 'As nominal head of the church of Banor, the kings aren\'t only worldly but also spiritual authorities. ...', + 'The kings fund the inquisition and sometimes provide manpower in matters of utmost importance. The inquisition, in return, protects the realm from heretics and individuals that aim to undermine the holy reign of the kings.' + }, cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'banor') then + npcHandler:say({ + 'In the past, the order of Banor was the only order of knighthood in existence. In the course of time, the order concentrated more and more on spiritual matters rather than on worldly ones. ...', + 'Nowadays, the order of Banor sanctions new orders and offers spiritual guidance to the fighters of good.' + }, cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'fardos') then + npcHandler:say('The priests of Fardos are often mystics who have secluded themselves from worldly matters. Others provide guidance and healing to people in need in the temples.', cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'uman') then + npcHandler:say({ + 'The church of Uman oversees the education of the masses as well as the doings of the sorcerer and druid guilds. It decides which lines of research are in accordance with the will of Uman and which are not. ...', + 'Concerned, the inquisition watches the attempts of these guilds to become more and more independent and to make own decisions. ...', + 'Unfortunately, the sorcerer guild has become dangerously influential and so the hands of our priests are tied due to political matters ...', + 'The druids lately claim that they are serving Crunor\'s will and not Uman\'s. Such heresy could only become possible with the independence of Carlin from the Thaian kingdom. ...', + 'The spiritual centre of the druids switched to Carlin where they have much influence and cannot be supervised by the inquisition.' + }, cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'fafnar') then + npcHandler:say({ + 'Fafnar is mostly worshipped by the peasants and farmers in rural areas. ...', + 'The inquisition has a close eye on these activities. Simply people tend to mix local superstitions with the teachings of the gods. This again may lead to heretical subcults.' + }, cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'edron') then + npcHandler:say({ + 'Edron illustrates perfectly why the inquisition is needed and why we need more funds and manpower. ...', + 'Our agents were on their way to investigate certain occurrences there when some faithless knights fled to some unholy ruins. ...', + 'We were unable to wipe them out and the local order of knighthood was of little help. ...', + 'It\'s almost sure that something dangerous is going on there, so we have to continue our efforts.' + }, cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'ankrahmun') then + npcHandler:say({ + 'Even though they claim differently, this city is in the firm grip of Zathroth and his evil minions. Their whole twisted religion is a mockery of the teachings of our gods ...', + 'As soon as we have gathered the strength, we should crush this city once and for all.' + }, cid) + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'paladin'}, StdModule.say, {npcHandler = npcHandler, text = 'It\'s a shame that only a few paladins still use their abilities to further the cause of the gods of good. Too many paladins have become selfish and greedy.'}) +keywordHandler:addKeyword({'knight'}, StdModule.say, {npcHandler = npcHandler, text = 'Nowadays, most knights seem to have forgotten the noble cause to which all knights were bound in the past. Only a few have remained pious, serve the gods and follow their teachings.'}) +keywordHandler:addKeyword({'sorcerer'}, StdModule.say, {npcHandler = npcHandler, text = 'Those who wield great power have to resist great temptations. We have the burden to eliminate all those who give in to the temptations.'}) +keywordHandler:addKeyword({'druid'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids here still follow the old rules. Sadly, the druids of Carlin have left the right path in the last years.'}) +keywordHandler:addKeyword({'dwarf'}, StdModule.say, {npcHandler = npcHandler, text = 'The dwarfs are allied with Thais but follow their own obscure religion. Although dwarfs keep mostly to themselves, we have to observe this alliance closely.'}) +keywordHandler:addKeyword({'kazordoon'}, StdModule.say, {npcHandler = npcHandler, text = 'The dwarfs are allied with Thais but follow their own obscure religion. Although dwarfs keep mostly to themselves, we have to observe this alliance closely.'}) +keywordHandler:addKeyword({'elves'}, StdModule.say, {npcHandler = npcHandler, text = 'Those elves are hardly any more civilised than orcs. They can become a threat to mankind at any time.'}) +keywordHandler:addKeyword({'ab\'dendriel'}, StdModule.say, {npcHandler = npcHandler, text = 'Those elves are hardly any more civilised than orcs. They can become a threat to mankind at any time.'}) +keywordHandler:addKeyword({'venore'}, StdModule.say, {npcHandler = npcHandler, text = 'Venore is somewhat difficult to handle. The merchants have a close eye on our activities in their city and our authority is limited there. However, we will use all of our influence to prevent a second Carlin.'}) +keywordHandler:addKeyword({'drefia'}, StdModule.say, {npcHandler = npcHandler, text = 'Drefia used to be a city of sin and heresy, just like Carlin nowadays. One day, the gods decided to destroy this town and to erase all evil there.'}) +keywordHandler:addKeyword({'darashia'}, StdModule.say, {npcHandler = npcHandler, text = 'Darashia is a godless town full of mislead fools. One day, it will surely share the fate of its sister town Drefia.'}) +keywordHandler:addKeyword({'demon'}, StdModule.say, {npcHandler = npcHandler, text = 'Demons exist in many different shapes and levels of power. In general, they are servants of the dark gods and command great powers of destruction.'}) +keywordHandler:addKeyword({'carlin'}, StdModule.say, {npcHandler = npcHandler, text = 'Carlin is a city of sin and heresy. After the reunion of Carlin with the kingdom, the inquisition will have much work to purify the city and its inhabitants.'}) +keywordHandler:addKeyword({'zathroth'}, StdModule.say, {npcHandler = npcHandler, text = 'We can see his evil influence almost everywhere. Keep your eyes open or the dark one will lead you on the wrong way and destroy you.'}) +keywordHandler:addKeyword({'crunor'}, StdModule.say, {npcHandler = npcHandler, text = 'The church of Crunor works closely together with the druid guild. This makes a cooperation sometimes difficult.'}) +keywordHandler:addKeyword({'gods'}, StdModule.say, {npcHandler = npcHandler, text = 'We owe to the gods of good our creation and continuing existence. If it weren\'t for them, we would surely fall prey to the minions of the vile and dark gods.'}) +keywordHandler:addKeyword({'church'}, StdModule.say, {npcHandler = npcHandler, text = 'The churches of the gods united to fight heresy and dark magic. They are the shield of the true believers, while the inquisition is the sword that fights all enemies of virtuousness.'}) +keywordHandler:addKeyword({'inquisitor'}, StdModule.say, {npcHandler = npcHandler, text = 'The churches of the gods entrusted me with the enormous and responsible task to lead the inquisition. I leave the field work to inquisitors who I recruit from fitting people that cross my way.'}) +keywordHandler:addKeyword({'believer'}, StdModule.say, {npcHandler = npcHandler, text = 'Belive on the gods and they will show you the path.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'By edict of the churches I\'m the Lord Inquisitor.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m Henricus, the Lord Inquisitor.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Greetings, fellow {believer} |PLAYERNAME|!") +npcHandler:setMessage(MESSAGE_FAREWELL, "Always be on guard, |PLAYERNAME|!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "This ungraceful haste is most suspicious!") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/herbert.lua b/data/npc/scripts/herbert.lua new file mode 100644 index 00000000000..8f4e319a762 --- /dev/null +++ b/data/npc/scripts/herbert.lua @@ -0,0 +1,46 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, 'letter') then + if player:getStorageValue(Storage.ThievesGuild.Mission06) == 1 then + npcHandler:say('You would like Chantalle\'s letter? only if you are willing to pay a price. {gold} maybe?', cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, 'gold') then + if npcHandler.topic[cid] == 1 then + npcHandler:say('Are you willing to pay 1000 gold for this letter?', cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 2 then + if player:removeMoneyNpc(1000) then + player:addItem(8768, 1) + npcHandler:say('Here you go kind sir.', cid) + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/hexel.lua b/data/npc/scripts/hexel.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/hexel.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/hireling.lua b/data/npc/scripts/hireling.lua new file mode 100644 index 00000000000..97b1fe90fe8 --- /dev/null +++ b/data/npc/scripts/hireling.lua @@ -0,0 +1,1089 @@ +--[[ + Created By Leonardo "Leu" Pereira (jlcvp@github) +]] +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +local hireling = nil +local count = {} -- for banking +local transfer = {} -- for banking + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) + + if not hireling then + local creature = Creature(cid) + local position = creature:getPosition() + + hireling = getHirelingByPosition(position) + hireling:setCreature(cid) + end +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local TOPIC = { + NONE = 1000, + LAMP = 1001, + SERVICES = 1100, + BANK = 1200, + FOOD = 1300, + GOODS = 1400 +} + +local TOPIC_FOOD = { + SKILL_CHOOSE = 1301 +} + +local TOPIC_GOODS = { + VARIOUS = 1401, + EQUIPMENT = 1402, + DISTANCE = 1403, + WANDS = 1404, + RODS = 1405, + POTIONS = 1406, + RUNES = 1407, + SUPPLIES = 1408, + TOOLS = 1409, + POSTAL = 1410 +} + +local GREETINGS = { + BANK = "Alright! What can I do for you and your bank business, |PLAYERNAME|?", + FOOD = "Hmm, yes! A variety of fine food awaits! However, a small expense of 15000 gold is expected to make these delicious masterpieces happen. Shall I?", + STASH = "Of course, here is your stash! Well-maintained and neatly sorted for your convenience!" +} + +local function setTopic(cid, topic) + npcHandler.topic[cid] = topic +end + +local function getHirelingSkills() + + local skills = {} + if hireling:hasSkill(HIRELING_SKILLS.BANKER) then + table.insert(skills,HIRELING_SKILLS.BANKER) + end + if hireling:hasSkill(HIRELING_SKILLS.COOKING) then + table.insert(skills,HIRELING_SKILLS.COOKING) + end + if hireling:hasSkill(HIRELING_SKILLS.STEWARD) then + table.insert(skills,HIRELING_SKILLS.STEWARD) + end + -- ignoring trader skills as it shows the same message about {goods} + return skills +end + +local function getHirelingServiceString(cid) + local skills = getHirelingSkills() + local str = "Do you want to see my {goods}" + + for i=1,#skills do + if i == #skills then + str = str .. ' or ' + else + str = str .. ', ' + end + + if skills[i]== HIRELING_SKILLS.BANKER then + str = str .. 'to access your {bank} account' -- TODO: this setence is not official + elseif skills[i]== HIRELING_SKILLS.COOKING then + str = str .. 'to order {food}' + elseif skills[i]== HIRELING_SKILLS.STEWARD then + str = str .. 'to open your {stash}' + end + end + str = str .. "?" + + local player = Player(cid) + if player:getGuid() == hireling:getOwnerId() then + str = str .. " If you want, I can go back to my {lamp} or maybe change my {outfit}." + end + return str +end + +local function getTopic(cid) + return npcHandler.topic[cid] and npcHandler.topic[cid] > 0 and npcHandler.topic[cid] or TOPIC.SERVICES +end + +local function sendSkillNotLearned(cid, SKILL) + local message = "Sorry, but I do not have mastery in this skill yet." + local profession + if SKILL == HIRELING_SKILLS.BANKER then + profession = "banker" + elseif SKILL == HIRELING_SKILLS.COOKING then + profession = "cooker" + elseif SKILL == HIRELING_SKILLS.STEWARD then + profession = "steward" + elseif SKILL == HIRELING_SKILLS.TRADER then + profession = "trader" + end + + if profession then + message = string.format("I'm not a %s and would not know how to help you with that, sorry. I can start a %s apprenticeship if you buy it for me in the store!", profession, profession) + end + + npcHandler:say(message, cid) +end +-- ----------------------[[ END STEWARD FUNCTIONS ]] ------------------------------ +--[[ +############################################################################ +############################################################################ +############################################################################ +]] +-- ----------------------[[ BANKING FUNCTIONS ]] ------------------------------ +-------------------------------- guild bank ----------------------------------------------- +local receiptFormat = 'Date: %s\nType: %s\nGold Amount: %d\nReceipt Owner: %s\nRecipient: %s\n\n%s' +local function getReceipt(info) + local receipt = Game.createItem(info.success and 24301 or 24302) + receipt:setAttribute(ITEM_ATTRIBUTE_TEXT, receiptFormat:format(os.date('%d. %b %Y - %H:%M:%S'), info.type, info.amount, info.owner, info.recipient, info.message)) + + return receipt +end + +local function getGuildIdByName(name, func) + db.asyncStoreQuery('SELECT `id` FROM `guilds` WHERE `name` = ' .. db.escapeString(name), + function(resultId) + if resultId then + func(result.getNumber(resultId, 'id')) + result.free(resultId) + else + func(nil) + end + end + ) +end + +local function getGuildBalance(id) + local guild = Guild(id) + if guild then + return guild:getBankBalance() + else + local balance + local resultId = db.storeQuery('SELECT `balance` FROM `guilds` WHERE `id` = ' .. id) + if resultId then + balance = result.getNumber(resultId, 'balance') + result.free(resultId) + end + + return balance + end +end + +local function setGuildBalance(id, balance) + local guild = Guild(id) + if guild then + guild:setBankBalance(balance) + else + db.query('UPDATE `guilds` SET `balance` = ' .. balance .. ' WHERE `id` = ' .. id) + end +end + +local function transferFactory(playerName, amount, fromGuildId, info) + return function(toGuildId) + if not toGuildId then + local player = Player(playerName) + if player then + info.success = false + info.message = 'We are sorry to inform you that we could not fulfil your request, because we could not find the recipient guild.' + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + end + else + local fromBalance = getGuildBalance(fromGuildId) + if fromBalance < amount then + info.success = false + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your guild account.' + else + info.success = true + info.message = 'We are happy to inform you that your transfer request was successfully carried out.' + setGuildBalance(fromGuildId, fromBalance - amount) + setGuildBalance(toGuildId, getGuildBalance(toGuildId) + amount) + end + + local player = Player(playerName) + if player then + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + end + end + end +end +--------------------------------end guild bank----------------------------------------------- +local function handleBankActions(cid, msg) + local player = Player(cid) +---------------------------- help ------------------------ + if msgcontains(msg, 'bank account') then + npcHandler:say({ + 'Every citizen has one. The big advantage is that you can access your money in every branch of the Global Bank! ...', + 'Would you like to know more about the {basic} functions of your bank account, the {advanced} functions, or are you already bored, perhaps?' + }, cid) + npcHandler.topic[cid] = 1200 + return true +---------------------------- balance --------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild balance') then + npcHandler.topic[cid] = 1200 + if not player:getGuild() then + npcHandler:say('You are not a member of a guild.', cid) + return false + end + npcHandler:say('Your guild account balance is ' .. player:getGuild():getBankBalance() .. ' gold.', cid) + return true +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'balance') then + npcHandler.topic[cid] = 1200 + if player:getBankBalance() >= 100000000 then + npcHandler:say('I think you must be one of the richest inhabitants in the world! Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + elseif player:getBankBalance() >= 10000000 then + npcHandler:say('You have made ten millions and it still grows! Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + elseif player:getBankBalance() >= 1000000 then + npcHandler:say('Wow, you have reached the magic number of a million gp!!! Your account balance is ' .. player:getBankBalance() .. ' gold!', cid) + return true + elseif player:getBankBalance() >= 100000 then + npcHandler:say('You certainly have made a pretty penny. Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + else + npcHandler:say('Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + end +---------------------------- deposit --------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild deposit') then + if not player:getGuild() then + npcHandler:say('You are not a member of a guild.', cid) + npcHandler.topic[cid] = 1200 + return false + end + -- count[cid] = player:getMoney() + -- if count[cid] < 1 then + -- npcHandler:say('You do not have enough gold.', cid) + -- npcHandler.topic[cid] = 1200 + -- return false + --end + if string.match(msg, '%d+') then + count[cid] = getMoneyCount(msg) + if count[cid] < 1 then + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 1200 + return false + end + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold to your {guild account}?', cid) + npcHandler.topic[cid] = 1223 + return true + else + npcHandler:say('Please tell me how much gold it is you would like to deposit.', cid) + npcHandler.topic[cid] = 1222 + return true + end + elseif npcHandler.topic[cid] == 1222 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold to your {guild account}?', cid) + npcHandler.topic[cid] = 1223 + return true + else + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 1200 + return true + end + elseif npcHandler.topic[cid] == 1223 then + if msgcontains(msg, 'yes') then + npcHandler:say('Alright, we have placed an order to deposit the amount of ' .. count[cid] .. ' gold to your guild account. Please check your inbox for confirmation.', cid) + local guild = player:getGuild() + local info = { + type = 'Guild Deposit', + amount = count[cid], + owner = player:getName() .. ' of ' .. guild:getName(), + recipient = guild:getName() + } + local playerBalance = player:getBankBalance() + if playerBalance < tonumber(count[cid]) then + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your bank account.' + info.success = false + else + info.message = 'We are happy to inform you that your transfer request was successfully carried out.' + info.success = true + guild:setBankBalance(guild:getBankBalance() + tonumber(count[cid])) + player:setBankBalance(playerBalance - tonumber(count[cid])) + end + + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish. Is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 1200 + return true +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'deposit') then + count[cid] = player:getMoney() + if count[cid] < 1 then + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 1200 + return false + end + if msgcontains(msg, 'all') then + count[cid] = player:getMoney() + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid) + npcHandler.topic[cid] = 1202 + return true + else + if string.match(msg,'%d+') then + count[cid] = getMoneyCount(msg) + if count[cid] < 1 then + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 1200 + return false + end + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid) + npcHandler.topic[cid] = 1202 + return true + else + npcHandler:say('Please tell me how much gold it is you would like to deposit.', cid) + npcHandler.topic[cid] = 1201 + return true + end + end + if not isValidMoney(count[cid]) then + npcHandler:say('Sorry, but you can\'t deposit that much.', cid) + npcHandler.topic[cid] = 1200 + return false + end + elseif npcHandler.topic[cid] == 1201 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid) + npcHandler.topic[cid] = 1202 + return true + else + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 1200 + return true + end + elseif npcHandler.topic[cid] == 1202 then + if msgcontains(msg, 'yes') then + if player:depositMoney(count[cid]) then + npcHandler:say('Alright, we have added the amount of ' .. count[cid] .. ' gold to your {balance}. You can {withdraw} your money anytime you want to.', cid) + else + npcHandler:say('You do not have enough gold.', cid) + end + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish. Is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 1200 + return true +---------------------------- withdraw -------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild withdraw') then + if not player:getGuild() then + npcHandler:say('I am sorry but it seems you are currently not in any guild.', cid) + npcHandler.topic[cid] = 1200 + return false + elseif player:getGuildLevel() < 2 then + npcHandler:say('Only guild leaders or vice leaders can withdraw money from the guild account.', cid) + npcHandler.topic[cid] = 1200 + return false + end + + if string.match(msg,'%d+') then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your guild account?', cid) + npcHandler.topic[cid] = 1225 + else + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 1200 + end + return true + else + npcHandler:say('Please tell me how much gold you would like to withdraw from your guild account.', cid) + npcHandler.topic[cid] = 1224 + return true + end + elseif npcHandler.topic[cid] == 1224 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your guild account?', cid) + npcHandler.topic[cid] = 1225 + else + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 1200 + end + return true + elseif npcHandler.topic[cid] == 1225 then + if msgcontains(msg, 'yes') then + local guild = player:getGuild() + local balance = guild:getBankBalance() + npcHandler:say('We placed an order to withdraw ' .. count[cid] .. ' gold from your guild account. Please check your inbox for confirmation.', cid) + local info = { + type = 'Guild Withdraw', + amount = count[cid], + owner = player:getName() .. ' of ' .. guild:getName(), + recipient = player:getName() + } + if balance < tonumber(count[cid]) then + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your guild account.' + info.success = false + else + info.message = 'We are happy to inform you that your transfer request was successfully carried out.' + info.success = true + guild:setBankBalance(balance - tonumber(count[cid])) + local playerBalance = player:getBankBalance() + player:setBankBalance(playerBalance + tonumber(count[cid])) + end + + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + npcHandler.topic[cid] = 1200 + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish. Is there something else I can do for you?', cid) + npcHandler.topic[cid] = 1200 + end + return true +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'withdraw') then + if string.match(msg,'%d+') then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your bank account?', cid) + npcHandler.topic[cid] = 1207 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 1200 + end + return true + else + npcHandler:say('Please tell me how much gold you would like to withdraw.', cid) + npcHandler.topic[cid] = 1206 + return true + end + elseif npcHandler.topic[cid] == 1206 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your bank account?', cid) + npcHandler.topic[cid] = 1207 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 1200 + end + return true + elseif npcHandler.topic[cid] == 1207 then + if msgcontains(msg, 'yes') then + if player:getFreeCapacity() >= getMoneyWeight(count[cid]) then + if not player:withdrawMoney(count[cid]) then + npcHandler:say('There is not enough gold on your account.', cid) + else + npcHandler:say('Here you are, ' .. count[cid] .. ' gold. Please let me know if there is something else I can do for you.', cid) + end + else + npcHandler:say('Whoah, hold on, you have no room in your inventory to carry all those coins. I don\'t want you to drop it on the floor, maybe come back with a cart!', cid) + end + npcHandler.topic[cid] = 1200 + elseif msgcontains(msg, 'no') then + npcHandler:say('The customer is king! Come back anytime you want to if you wish to {withdraw} your money.', cid) + npcHandler.topic[cid] = 1200 + end + return true +---------------------------- transfer -------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild transfer') then + if not player:getGuild() then + npcHandler:say('I am sorry but it seems you are currently not in any guild.', cid) + npcHandler.topic[cid] = 1200 + return false + elseif player:getGuildLevel() < 2 then + npcHandler:say('Only guild leaders or vice leaders can transfer money from the guild account.', cid) + npcHandler.topic[cid] = 1200 + return false + end + + if string.match(msg, '%d+') then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + transfer[cid] = string.match(msg, 'to%s*(.+)$') + if transfer[cid] then + npcHandler:say('So you would like to transfer ' .. count[cid] .. ' gold from your guild account to guild ' .. transfer[cid] .. '?', cid) + npcHandler.topic[cid] = 1228 + else + npcHandler:say('Which guild would you like to transfer ' .. count[cid] .. ' gold to?', cid) + npcHandler.topic[cid] = 1227 + end + else + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 1200 + end + else + npcHandler:say('Please tell me the amount of gold you would like to transfer.', cid) + npcHandler.topic[cid] = 1226 + end + return true + elseif npcHandler.topic[cid] == 1226 then + count[cid] = getMoneyCount(msg) + if player:getGuild():getBankBalance() < count[cid] then + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 1200 + return true + end + if isValidMoney(count[cid]) then + npcHandler:say('Which guild would you like to transfer ' .. count[cid] .. ' gold to?', cid) + npcHandler.topic[cid] = 1227 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 1200 + end + return true + elseif npcHandler.topic[cid] == 1227 then + transfer[cid] = msg + if player:getGuild():getName() == transfer[cid] then + npcHandler:say('Fill in this field with person who receives your gold!', cid) + npcHandler.topic[cid] = 1200 + return true + end + npcHandler:say('So you would like to transfer ' .. count[cid] .. ' gold from your guild account to guild ' .. transfer[cid] .. '?', cid) + npcHandler.topic[cid] = 1228 + return true + elseif npcHandler.topic[cid] == 1228 then + if msgcontains(msg, 'yes') then + npcHandler:say('We have placed an order to transfer ' .. count[cid] .. ' gold from your guild account to guild ' .. transfer[cid] .. '. Please check your inbox for confirmation.', cid) + local guild = player:getGuild() + local balance = guild:getBankBalance() + local info = { + type = 'Guild to Guild Transfer', + amount = count[cid], + owner = player:getName() .. ' of ' .. guild:getName(), + recipient = transfer[cid] + } + if balance < tonumber(count[cid]) then + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your guild account.' + info.success = false + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + else + getGuildIdByName(transfer[cid], transferFactory(player:getName(), tonumber(count[cid]), guild:getId(), info)) + end + npcHandler.topic[cid] = 1200 + elseif msgcontains(msg, 'no') then + npcHandler:say('Alright, is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 1200 +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'transfer') then + npcHandler:say('Please tell me the amount of gold you would like to transfer.', cid) + npcHandler.topic[cid] = 1211 + elseif npcHandler.topic[cid] == 1211 then + count[cid] = getMoneyCount(msg) + if player:getBankBalance() < count[cid] then + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 1200 + return true + end + if isValidMoney(count[cid]) then + npcHandler:say('Who would you like transfer ' .. count[cid] .. ' gold to?', cid) + npcHandler.topic[cid] = 1212 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 1200 + end + elseif npcHandler.topic[cid] == 1212 then + transfer[cid] = msg + if player:getName() == transfer[cid] then + npcHandler:say('Fill in this field with person who receives your gold!', cid) + npcHandler.topic[cid] = 1200 + return true + end + if playerExists(transfer[cid]) then + local arrayDenied = {"accountmanager", "rooksample", "druidsample", "sorcerersample", "knightsample", "paladinsample"} + if isInArray(arrayDenied, string.gsub(transfer[cid]:lower(), " ", "")) then + npcHandler:say('This player does not exist.', cid) + npcHandler.topic[cid] = 1200 + return true + end + npcHandler:say('So you would like to transfer ' .. count[cid] .. ' gold to ' .. transfer[cid] .. '?', cid) + npcHandler.topic[cid] = 1213 + else + npcHandler:say('This player does not exist.', cid) + npcHandler.topic[cid] = 1200 + end + elseif npcHandler.topic[cid] == 1213 then + if msgcontains(msg, 'yes') then + if not player:transferMoneyTo(transfer[cid], count[cid]) then + npcHandler:say('You cannot transfer money to this account.', cid) + else + npcHandler:say('Very well. You have transferred ' .. count[cid] .. ' gold to ' .. transfer[cid] ..'.', cid) + transfer[cid] = nil + end + elseif msgcontains(msg, 'no') then + npcHandler:say('Alright, is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 1200 +---------------------------- money exchange -------------- + elseif msgcontains(msg, 'change gold') then + npcHandler:say('How many platinum coins would you like to get?', cid) + npcHandler.topic[cid] = 1214 + elseif npcHandler.topic[cid] == 1214 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough gold coins.', cid) + npcHandler.topic[cid] = 1200 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] * 100 .. ' of your gold coins into ' .. count[cid] .. ' platinum coins?', cid) + npcHandler.topic[cid] = 1215 + end + elseif npcHandler.topic[cid] == 1215 then + if msgcontains(msg, 'yes') then + if player:removeItem(2148, count[cid] * 100) then + player:addItem(2152, count[cid]) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough gold coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 1200 + elseif msgcontains(msg, 'change platinum') then + npcHandler:say('Would you like to change your platinum coins into gold or crystal?', cid) + npcHandler.topic[cid] = 1216 + elseif npcHandler.topic[cid] == 1216 then + if msgcontains(msg, 'gold') then + npcHandler:say('How many platinum coins would you like to change into gold?', cid) + npcHandler.topic[cid] = 1217 + elseif msgcontains(msg, 'crystal') then + npcHandler:say('How many crystal coins would you like to get?', cid) + npcHandler.topic[cid] = 1219 + else + npcHandler:say('Well, can I help you with something else?', cid) + npcHandler.topic[cid] = 1200 + end + elseif npcHandler.topic[cid] == 1217 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + npcHandler.topic[cid] = 1200 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] .. ' of your platinum coins into ' .. count[cid] * 100 .. ' gold coins for you?', cid) + npcHandler.topic[cid] = 1218 + end + elseif npcHandler.topic[cid] == 1218 then + if msgcontains(msg, 'yes') then + if player:removeItem(2152, count[cid]) then + player:addItem(2148, count[cid] * 100) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 1200 + elseif npcHandler.topic[cid] == 1219 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + npcHandler.topic[cid] = 1200 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] * 100 .. ' of your platinum coins into ' .. count[cid] .. ' crystal coins for you?', cid) + npcHandler.topic[cid] = 1220 + end + elseif npcHandler.topic[cid] == 1220 then + if msgcontains(msg, 'yes') then + if player:removeItem(2152, count[cid] * 100) then + player:addItem(2160, count[cid]) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 1200 + elseif msgcontains(msg, 'change crystal') then + npcHandler:say('How many crystal coins would you like to change into platinum?', cid) + npcHandler.topic[cid] = 1221 + elseif npcHandler.topic[cid] == 1221 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough crystal coins.', cid) + npcHandler.topic[cid] = 1200 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] .. ' of your crystal coins into ' .. count[cid] * 100 .. ' platinum coins for you?', cid) + npcHandler.topic[cid] = 1222 + end + elseif npcHandler.topic[cid] == 1222 then + if msgcontains(msg, 'yes') then + if player:removeItem(2160, count[cid]) then + player:addItem(2152, count[cid] * 100) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough crystal coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 1200 + elseif msgcontains(msg, 'money') then + npcHandler:say('We can {change} money for you. You can also access your {bank account}.', cid) + elseif msgcontains(msg, 'change') then + npcHandler:say('There are three different coin types in Global Bank: 100 gold coins equal 1 platinum coin, 100 platinum coins equal 1 crystal coin. So if you\'d like to change 100 gold into 1 platinum, simply say \'{change gold}\' and then \'1 platinum\'.', cid) + elseif msgcontains(msg, 'bank') then + npcHandler:say('We can {change} money for you. You can also access your {bank account}.', cid) + elseif msgcontains(msg, 'advanced') then + npcHandler:say('Your bank account will be used automatically when you want to {rent} a house or place an offer on an item on the {market}. Let me know if you want to know about how either one works.', cid) + elseif msgcontains(msg, 'help') then + npcHandler:say('You can check the {balance} of your bank account, {deposit} money or {withdraw} it. You can also {transfer} money to other characters, provided that they have a vocation.', cid) + elseif msgcontains(msg, 'functions') then + npcHandler:say('You can check the {balance} of your bank account, {deposit} money or {withdraw} it. You can also {transfer} money to other characters, provided that they have a vocation.', cid) + elseif msgcontains(msg, 'basic') then + npcHandler:say('You can check the {balance} of your bank account, {deposit} money or {withdraw} it. You can also {transfer} money to other characters, provided that they have a vocation.', cid) + elseif msgcontains(msg, 'job') then + npcHandler:say('I work in this house. I can change money for you and help you with your bank account.', cid) + end + return true +end +-- ======================[[ END BANKING FUNCTIONS ]] ======================== -- +--[[ +############################################################################ +############################################################################ +############################################################################ +]] +-- ========================[[ TRADER FUNCTIONS ]] ========================== -- + +local function getGoodsGreetingMessage() + local str + if not hireling:hasSkill(HIRELING_SKILLS.TRADER) then + str = "While I'm not a trader, I still have a collection of {various} items to sell if you like!" + else + str = "I sell a {selection} of {various} items, {equipment}, " .. + "{distance} weapons, {wands} and {rods}, {potions}, {runes}, " .. + "{supplies}, {tools} and {postal} goods. Just ask!" + end + return str +end + +local function getTable(cid) + local topic = getTopic(cid) + if topic == TOPIC_GOODS.VARIOUS then + return HIRELING_GOODS.VARIOUS + elseif topic == TOPIC_GOODS.EQUIPMENT then + return HIRELING_GOODS.EQUIPMENT + elseif topic == TOPIC_GOODS.DISTANCE then + return HIRELING_GOODS.DISTANCE + elseif topic == TOPIC_GOODS.WANDS then + return HIRELING_GOODS.WANDS + elseif topic == TOPIC_GOODS.RODS then + return HIRELING_GOODS.RODS + elseif topic == TOPIC_GOODS.POTIONS then + return HIRELING_GOODS.POTIONS + elseif topic == TOPIC_GOODS.RUNES then + return HIRELING_GOODS.RUNES + elseif topic == TOPIC_GOODS.SUPPLIES then + return HIRELING_GOODS.SUPPLIES + elseif topic == TOPIC_GOODS.TOOLS then + return HIRELING_GOODS.TOOLS + elseif topic == TOPIC_GOODS.POSTAL then + return HIRELING_GOODS.POSTAL + end +end + +local function setNewTradeTable(table) + local items, item = {} + for i = 1, #table do + item = table[i] + items[item.id] = {itemId = item.id, buyPrice = item.buy, sellPrice = item.sell, subType = item.subType, realName = item.name} + end + return items +end + +local function onBuy(cid, item, subType, amount, ignoreCap, inBackpacks) + local player = Player(cid) + local creatureId = Creature(cid):getId() + local items = setNewTradeTable(getTable(creatureId)) + local itemType = ItemType(items[item].itemId) + if itemType:getWrapableTo() ~= 0 then + itemType = ItemType(itemType:getWrapableTo()) + end + local backpack = player:getSlotItem(CONST_SLOT_BACKPACK) + if not backpack or backpack:getEmptySlots(true) < 1 then + player:sendCancelMessage(RETURNVALUE_NOTENOUGHROOM) + return false + end + if not ignoreCap and player:getFreeCapacity() < itemType:getWeight(amount) then + return player:sendTextMessage(MESSAGE_FAILURE, 'You don\'t have enough cap.') + end + if not player:removeMoneyNpc(items[item].buyPrice * amount) then + selfSay("You don't have enough money.", cid) + else + player:addItem(itemType:getId(), amount, true, subType) + return player:sendTextMessage(MESSAGE_LOOK, 'Bought '..amount..'x '..items[item].realName..' for '..items[item].buyPrice * amount..' gold coins.') + end + return true +end + +local function getTradeMessage(cid) + local topic = getTopic(cid) + local msg = "Here you go!" + + if topic == TOPIC_GOODS.EQUIPMENT then + msg = "Alright, here's all the equipment I can order for you!" + elseif topic == TOPIC_GOODS.DISTANCE then + msg = "Great, here are the distance weapons I can order for you!" + elseif topic == TOPIC_GOODS.WANDS then + msg = "Ok, here are the wands I can order for you!" + elseif topic == TOPIC_GOODS.RODS then + msg = "Nice, here are the rods I can order for you!" + elseif topic == TOPIC_GOODS.POTIONS then + msg = "Sure, here are all the potions I can order for you!" + elseif topic == TOPIC_GOODS.RUNES then + msg = "With pleasure, here are all the runes I can order for you!" + elseif topic == TOPIC_GOODS.SUPPLIES then + msg = "Here are some supplies to get you through the day!" + elseif topic == TOPIC_GOODS.TOOLS then + msg = "All the handy tools you'll ever need!" + elseif topic == TOPIC_GOODS.POSTAL then + msg = "I have all the necessary items to properly enhance your communication, feel free to browse!" + end + + return msg +end + +local function sendTradeWindow(cid) + openShopWindow(cid, getTable(cid), onBuy, onSell) + local response = getTradeMessage() + npcHandler:say(response, cid) +end + + +local function handleGoodsActions(cid, msg) + if msgcontains(msg, "various") then + setTopic(cid, TOPIC_GOODS.VARIOUS) + elseif msgcontains(msg, "equipment") then + setTopic(cid, TOPIC_GOODS.EQUIPMENT) + elseif msgcontains(msg, "distance") then + setTopic(cid, TOPIC_GOODS.DISTANCE) + elseif msgcontains(msg, "wands") then + setTopic(cid, TOPIC_GOODS.WANDS) + elseif msgcontains(msg, "rods") then + setTopic(cid, TOPIC_GOODS.RODS) + elseif msgcontains(msg, "potions") then + setTopic(cid, TOPIC_GOODS.POTIONS) + elseif msgcontains(msg, "runes") then + setTopic(cid, TOPIC_GOODS.RUNES) + elseif msgcontains(msg, "supplies") then + setTopic(cid, TOPIC_GOODS.SUPPLIES) + elseif msgcontains(msg, "tools") then + setTopic(cid, TOPIC_GOODS.TOOLS) + elseif msgcontains(msg, "postal") then + setTopic(cid, TOPIC_GOODS.POSTAL) + end + + + if table.contains(TOPIC_GOODS, getTopic(cid)) then + sendTradeWindow(cid) + end +end + +-- ======================[[ END TRADER FUNCTIONS ]] ======================== -- +--[[ +############################################################################ +############################################################################ +############################################################################ +]] +-- ========================[[ COOKER FUNCTIONS ]] ========================== -- + +local function getDeliveredMessageByFoodId(food_id) -- remove the hardcoded food ids + local msg = "" + + + if food_id == 35172 then + msg = "Oh yes, a tasty roasted wings to make you even tougher and skilled with the defensive arts." + elseif food_id == 35173 then + msg = "Divine! Carrot is a well known nourishment that makes the eyes see even more sharply." + elseif food_id == 35174 then + msg = "Magnifique! A tiger meat that has been marinated for several hours in magic spices." + elseif food_id == 35175 then + msg = "Aaah, the beauty of the simple dishes! A delicate salad made of selected ingredients, capable of bring joy to the hearts of bravest warriors and their weapons." + elseif food_id == 35176 then + msg = "Oh yes, very spicy chilly combined with delicious minced carniphila meat and a side dish of fine salad!" + elseif food_id == 35177 then + msg = "Aaah, the northern cuisine! A catch of fresh salmon right from the coast Svargrond is the base of this extraordinary fish dish." + elseif food_id == 35178 then + msg = "A traditional and classy meal. A beefy casserole which smells far better than it sounds!" + elseif food_id == 35179 then + msg = "A tasty chunk of juicy beef with an aromatic sauce and parsley potatoes, mmh!" + elseif food_id == 35180 then + msg = "Oooh, well... that one didn't quite turn out as it was supposed to be, I'm sorry." + end + + return msg +end + +local function deliverFood(cid, food_id) + local player = Player(cid) + local itType = ItemType(food_id) + local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX) + + if player:getFreeCapacity() < itType:getWeight(1) then + npcHandler:say("Sorry, but you don't have enough capacity.", cid) + elseif not inbox or inbox:getEmptySlots() == 0 then + player:getPosition():sendMagicEffect(CONST_ME_POFF) + npcHandler:say("Sorry, you don't have enough room on your inbox", cid) + elseif not player:removeMoneyNpc(15000) then + npcHandler:say("Sorry, you don't have enough money.", cid) + else + local msg = getDeliveredMessageByFoodId(food_id) + npcHandler:say(msg, cid) + inbox:addItem(food_id, 1, INDEX_WHEREEVER, FLAG_NOLIMIT) + end + setTopic(cid, TOPIC.SERVICES) +end + +local function cookFood(cid) + local random = math.random(6) + if random == 6 then + -- ask for preferred skill + setTopic(cid, TOPIC_FOOD.SKILL_CHOOSE) + npcHandler:say("Yay! I have the ingredients to make a skill boost dish. Would you rather like to boost your {magic}, {melee}, {shielding} or {distance} skill?", cid) + else -- deliver the random generated index + deliverFood(cid, HIRELING_FOODS[random]) + end +end + +local function handleFoodActions(cid, msg) + local topic = getTopic(cid) + + if topic == TOPIC.FOOD then --initial node + if msgcontains(msg, "yes") then + cookFood(cid) + elseif msgcontains(msg, "no") then + setTopic(cid, TOPIC.SERVICES) + npcHandler:say("Alright then, ask me for other {services}, if you want.", cid) + else --invalid word + + end + elseif topic == TOPIC_FOOD.SKILL_CHOOSE then + if msgcontains(msg, "magic") then + deliverFood(cid, HIRELING_FOODS_BOOST.MAGIC) + elseif msgcontains(msg,"melee") then + deliverFood(cid, HIRELING_FOODS_BOOST.MELEE) + elseif msgcontains(msg,"shielding") then + deliverFood(cid, HIRELING_FOODS_BOOST.SHIELDING) + elseif msgcontains(msg,"distance") then + deliverFood(cid, HIRELING_FOODS_BOOST.DISTANCE) + else + npcHandler:say("Sorry, but you must choose a valid skill class. Would you like to boost your {magic}, {melee}, {shielding} or {distance} skill?", cid) + end + end +end + +-- ======================[[ END COOKER FUNCTIONS ]] ======================== -- +local function creatureSayCallback(cid, type, msg) + if (not npcHandler:isFocused(cid)) then + return false + end + + local player = Player(cid) + + if not hireling:canTalkTo(player) then + return false + end + + -- roleplay + if msgcontains(msg,"sword of fury") then + npcHandler:say("In my youth I dreamt to wield it! Now I wield the broom of... brooming. I guess that's the next best thing!", cid) + elseif msgcontains(msg,"rookgaard") then + npcHandler:say("What an uncivilised place without any culture.", cid) + elseif msgcontains(msg,"excalibug") then + npcHandler:say("I'll keep an eye open for it when cleaning up the things you brought home!", cid) + -- end roleplay + elseif(msgcontains(msg, "service")) then + setTopic(cid,TOPIC.SERVICES) + local servicesMsg = getHirelingServiceString(cid) + npcHandler:say(servicesMsg, cid) + elseif(getTopic(cid) == TOPIC.SERVICES) then + if msgcontains(msg, "bank") then + if hireling:hasSkill(HIRELING_SKILLS.BANKER) then + setTopic(cid, TOPIC.BANK) + count[cid], transfer[cid] = nil, nil + npcHandler:say(GREETINGS.BANK, cid) + else + sendSkillNotLearned(cid, HIRELING_SKILLS.BANKER) + end + elseif msgcontains(msg, "food") then + if hireling:hasSkill(HIRELING_SKILLS.COOKING) then + setTopic(cid, TOPIC.FOOD) + npcHandler:say(GREETINGS.FOOD, cid) + else + sendSkillNotLearned(cid, HIRELING_SKILLS.COOKING) + end + elseif msgcontains(msg, "stash") then + if hireling:hasSkill(HIRELING_SKILLS.STEWARD) then + npcHandler:say(GREETINGS.STASH, cid) + player:openStash(true) + else + sendSkillNotLearned(cid, HIRELING_SKILLS.STEWARD) + end + elseif msgcontains(msg, "goods") or msgcontains(msg, "trade") then + setTopic(cid, TOPIC.GOODS) + local goodsMsg = getGoodsGreetingMessage() + npcHandler:say(goodsMsg, cid) + elseif msgcontains(msg, "lamp") then + setTopic(cid, TOPIC.LAMP) + if player:getGuid() == hireling:getOwnerId() then + npcHandler:say("Are you sure you want me to go back to my lamp?", cid) + else + return false + end + elseif msgcontains(msg, "outfit") then + if player:getGuid() == hireling:getOwnerId() then + hireling:requestOutfitChange() + npcHandler:say("As you wish!", cid) + else + return false + end + end + elseif(getTopic(cid) == TOPIC.LAMP) then + if msgcontains(msg, "yes") then + npcHandler:say("As you wish!", cid) + hireling:returnToLamp(player:getGuid()) + else + setTopic(cid, TOPIC.SERVICES) + npcHandler:say("Alright then, I will be here.", cid) + end + elseif(getTopic(cid) >= TOPIC.BANK and getTopic(cid) < TOPIC.FOOD) then + handleBankActions(cid, msg) + elseif(getTopic(cid) >= TOPIC.FOOD and getTopic(cid) < TOPIC.GOODS) then + handleFoodActions(cid, msg) + elseif(getTopic(cid) >= TOPIC.GOODS) then + if msgcontains(msg, "goods") or msgcontains(msg, "trade") then + setTopic(cid, TOPIC.GOODS) + local goodsMsg = getGoodsGreetingMessage() + npcHandler:say(goodsMsg, cid) + else + handleGoodsActions(cid, msg) + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "It is good to see you. I'm always at your {service}") +npcHandler:setMessage(MESSAGE_FAREWELL, "Farewell, |PLAYERNAME|, I'll be here if you need me again.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Come back soon!") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/hjaern.lua b/data/npc/scripts/hjaern.lua new file mode 100644 index 00000000000..35f85a2c297 --- /dev/null +++ b/data/npc/scripts/hjaern.lua @@ -0,0 +1,204 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.TheIceIslands.Questline) == 3 then + if player:getStorageValue(Storage.TheIceIslands.Mission02) < 1 then + npcHandler:say({ + "We could indeed need some help. These are very cold times. The ice is growing and becoming thicker everywhere ...", + "The problem is that the chakoyas may use the ice for a passage to the west and attack Svargrond ...", + "We need you to get a pick and to destroy the ice at certain places to the east. You will quickly recognise those spots by their unstable look ...", + "Use the pickaxe on at least three of these places and the chakoyas probably won't be able to pass the ice. Once you are done, return here and report about your mission." + }, cid) + player:setStorageValue(Storage.TheIceIslands.Mission02, 1) -- Questlog The Ice Islands Quest, Nibelor 1: Breaking the Ice + npcHandler.topic[cid] = 0 + end + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 4 then + npcHandler:say("The spirits are at peace now. The threat of the chakoyas is averted for now. I thank you for your help. Perhaps you should ask Silfind if you can help her in some matters. ", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 5) + player:setStorageValue(Storage.TheIceIslands.Mission02, 5) -- Questlog The Ice Islands Quest, Nibelor 1: Breaking the Ice + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 29 then + npcHandler:say({ + "There is indeed an important mission. For a long time, the spirits have been worried and have called us for help. It seems that some of our dead have not reached the happy hunting grounds of after life ...", + "Everything we were able to find out leads to a place where none of our people is allowed to go. Just like we would never allow a stranger to go to that place ...", + "But you, you are different. You are not one of our people, yet you have proven worthy to be one us. You are special, the child of two worlds ...", + "We will grant you permission to travel to that isle of Helheim. Our legends say that this is the entrance to the dark world. The dark world is the place where the evil and lost souls roam in eternal torment ...", + "There you find for sure the cause for the unrest of the spirits. Find someone in Svargrond who can give you a passage to Helheim and seek for the cause. Are you willing to do that?" + }, cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 31 then + npcHandler:say({ + "There is no need to report about your mission. To be honest, Ive sent a divination spirit with you as well as a couple of destruction spirits that were unleashed when you approached the altar ...", + "Forgive me my secrecy but you are not familiar with the spirits and you might have get frightened. The spirits are at work now, destroying the magic with that those evil creatures have polluted Helheim ...", + "I cant thank you enough for what you have done for the spirits of my people. Still I have to ask: Would you do us another favour?" + }, cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 38 then + npcHandler:say({ + "These are alarming news and we have to act immediately. Take this spirit charm of cold. Travel to the mines and find four special obelisks to mark them with the charm ...", + "I can feel their resonance in the spirits world but we cant reach them with our magic yet. They have to get into contact with us in a spiritual way first ...", + "This will help us to concentrate all our frost magic on this place. I am sure this will prevent to melt any significant number of demons from the ice ...", + "Report about your mission when you are done. Then we can begin with the great ritual of summoning the children of Chyll ...", + "I will also inform Lurik about the events. Now go, fast!" + }, cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 39) + player:setStorageValue(Storage.TheIceIslands.Mission11, 2) -- Questlog The Ice Islands Quest, Formorgar Mines 3: The Secret + player:setStorageValue(Storage.TheIceIslands.Mission12, 1) -- Questlog The Ice Islands Quest, Formorgar Mines 4: Retaliation + player:addItem(7289, 1) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 39 + and player:getStorageValue(Storage.TheIceIslands.Obelisk01) == 5 + and player:getStorageValue(Storage.TheIceIslands.Obelisk02) == 5 + and player:getStorageValue(Storage.TheIceIslands.Obelisk03) == 5 + and player:getStorageValue(Storage.TheIceIslands.Obelisk04) == 5 then + if player:removeItem(7289, 1) then + player:setStorageValue(Storage.TheIceIslands.Questline, 40) + player:setStorageValue(Storage.TheIceIslands.yakchalDoor, 1) + player:setStorageValue(Storage.TheIceIslands.Mission12, 6) -- Questlog The Ice Islands Quest, Formorgar Mines 4: Retaliation + player:setStorageValue(Storage.OutfitQuest.NorsemanAddon, 1) -- Questlog Norseman Outfit Quest + player:setStorageValue(Storage.OutfitQuest.DefaultStart, 1) --this for default start of Outfit and Addon Quests + player:addOutfit(251, 0) + player:addOutfit(252, 0) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + npcHandler:say({ + "Yes, I can feel it! The spirits are in touch with the obelisks. We will begin to channel a spell of ice on the caves. That will prevent the melting of the ice there ...", + "If you would like to help us, you can turn in frostheart shards from now on. We use them to fuel our spell with the power of ice. ...", + "Oh, and before I forget it - since you have done a lot to help us and spent such a long time in this everlasting winter, I have a special present for you. ...", + "Take this outfit to keep your warm during your travels in this frozen realm!" + }, cid) + end + npcHandler.topic[cid] = 0 + else + npcHandler:say("I have now no mission for you.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "shard") then + if player:getStorageValue(Storage.TheIceIslands.Questline) == 40 then + npcHandler:say("Do you bring frostheart shards for our spell?", cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 42 then + npcHandler:say("Do you bring frostheart shards for our spell? ", cid) + npcHandler.topic[cid] = 4 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 44 then + npcHandler:say("Do you want to sell all your shards for 2000 gold coins per each? ", cid) + npcHandler.topic[cid] = 5 + end + elseif msgcontains(msg, "reward") then + if player:getStorageValue(Storage.TheIceIslands.Questline) == 41 then + npcHandler:say("Take this. It might suit your Nordic outfit fine. ", cid) + player:addOutfitAddon(252, 1) + player:addOutfitAddon(251, 1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:setStorageValue(Storage.TheIceIslands.Questline, 42) + player:setStorageValue(Storage.OutfitQuest.NorsemanAddon, 2) -- Questlog Norseman Outfit Quest + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 43 then + player:addOutfitAddon(252, 2) + player:addOutfitAddon(251, 2) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + npcHandler:say("Take this. It might suit your Nordic outfit fine. From now on we only can give you 2000 gold pieces for each shard. ", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 44) + player:setStorageValue(Storage.OutfitQuest.NorsemanAddon, 3) -- Questlog Norseman Outfit Quest + npcHandler.topic[cid] = 4 + end + elseif msgcontains(msg, "tylaf") then + if player:getStorageValue(Storage.TheIceIslands.Questline) == 36 then + npcHandler:say({ + "You encountered the restless ghost of my apprentice Tylaf in the old mines? We must find out what has happened to him. I enable you to talk to his spirit ...", + "Talk to him and then report to me about your mission." + }, cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 37) + player:setStorageValue(Storage.TheIceIslands.Mission10, 1) -- Questlog The Ice Islands Quest, Formorgar Mines 2: Ghostwhisperer + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'cookie') then + if player:getStorageValue(Storage.WhatAFoolish.Questline) == 31 + and player:getStorageValue(Storage.WhatAFoolish.CookieDelivery.Hjaern) ~= 1 then + npcHandler:say('You want to sacrifice a cookie to the spirits?', cid) + npcHandler.topic[cid] = 6 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("This is good news. As I explained, travel to Helheim, seek the reason for the unrest there and then report to me about your mission. ", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 30) + player:setStorageValue(Storage.TheIceIslands.Mission07, 2) -- Questlog The Ice Islands Quest, The Secret of Helheim + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say({ + "Thank you my friend. The local representative of the explorers society has asked for our help ...", + "You know their ways better than my people do and are probably best suited to represent us in this matter.", + "Search for Lurik and talk to him about aprobable mission he might have for you." + }, cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 32) + player:setStorageValue(Storage.TheIceIslands.Mission08, 1) -- Questlog The Ice Islands Quest, The Contact + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + if player:removeItem(7290, 5) then + npcHandler:say("Excellent, you collected 5 of them. If you have collected 5 or more, talk to me about your {reward}. ", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 41) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 4 then + if player:removeItem(7290, 10) then + npcHandler:say("Excellent, you collected 10 of them. If you have collected 15 or more, talk to me about your {reward}. ", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 43) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 5 then + if player:getItemCount(7290) > 0 then + local count = player:getItemCount(7290) + player:addMoney(count * 2000) + player:removeItem(7290, count) + npcHandler:say("Here your are. " .. count * 2000 .. " gold coins for " .. count .. " shards.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 6 then + if not player:removeItem(8111, 1) then + npcHandler:say('You have no cookie that I\'d like.', cid) + npcHandler.topic[cid] = 0 + return true + end + + player:setStorageValue(Storage.WhatAFoolish.CookieDelivery.Hjaern, 1) + if player:getCookiesDelivered() == 10 then + player:addAchievement('Allow Cookies?') + end + + Npc():getPosition():sendMagicEffect(CONST_ME_GIFT_WRAPS) + npcHandler:say('In the name of the spirits I accept this offer ... UHNGH ... The spirits are not amused!', cid) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + elseif msgcontains(msg, 'no') then + if npcHandler.topic[cid] == 6 then + npcHandler:say('I see.', cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/hofech.lua b/data/npc/scripts/hofech.lua new file mode 100644 index 00000000000..d124774871c --- /dev/null +++ b/data/npc/scripts/hofech.lua @@ -0,0 +1,106 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local shopModule = ShopModule:new() +npcHandler:addModule(shopModule) + +shopModule:addBuyableItem({'amphora'}, 2023, 4) +shopModule:addBuyableItem({'armor rack kit'}, 6114, 90) +shopModule:addBuyableItem({'barrel kit'}, 3919, 12) +shopModule:addBuyableItem({'big table kit'}, 3911, 30) +shopModule:addBuyableItem({'birdcage kit'}, 3922, 50) +shopModule:addBuyableItem({'blue bed kit'}, 7907, 80) +shopModule:addBuyableItem({'blue pillow'}, 1686, 25) +shopModule:addBuyableItem({'blue tapestry'}, 1872, 25) +shopModule:addBuyableItem({'bookcase kit'}, 6373, 70) +shopModule:addBuyableItem({'box'}, 1738, 10) +shopModule:addBuyableItem({'chest'}, 1740, 10) +shopModule:addBuyableItem({'chimney kit'}, 8692, 200) +shopModule:addBuyableItem({'coal basin kit'}, 3932, 25) +shopModule:addBuyableItem({'crate'}, 1739, 10) +shopModule:addBuyableItem({'cuckoo clock'}, 1877, 40) +shopModule:addBuyableItem({'drawer kit'}, 3915, 18) +shopModule:addBuyableItem({'dresser kit'}, 3916, 25) +shopModule:addBuyableItem({'flower bowl'}, 2102, 6) +shopModule:addBuyableItem({'globe kit'}, 3926, 50) +shopModule:addBuyableItem({'goblin statue kit'}, 3930, 50) +shopModule:addBuyableItem({'god flowers'}, 2100, 5) +shopModule:addBuyableItem({'goldfish bowl'}, 5928, 50) +shopModule:addBuyableItem({'green bed kit'}, 7904, 80) +shopModule:addBuyableItem({'green cushioned chair kit'}, 3902, 40) +shopModule:addBuyableItem({'green pillow'}, 1688, 25) +shopModule:addBuyableItem({'green tapestry'}, 1860, 25) +shopModule:addBuyableItem({'harp kit'}, 3934, 50) +shopModule:addBuyableItem({'heart pillow'}, 1685, 30) +shopModule:addBuyableItem({'honey flower'}, 2103, 5) +shopModule:addBuyableItem({'indoor plant kit'}, 3937, 8) +shopModule:addBuyableItem({'knight statue kit'}, 3928, 50) +shopModule:addBuyableItem({'large amphora kit'}, 3931, 50) +shopModule:addBuyableItem({'locker kit'}, 3917, 30) +shopModule:addBuyableItem({'minotaur statue kit'}, 3929, 50) +shopModule:addBuyableItem({'orange tapestry'}, 1866, 25) +shopModule:addBuyableItem({'oven kit'}, 6372, 80) +shopModule:addBuyableItem({'pendulum clock kit'}, 3927, 75) +shopModule:addBuyableItem({'piano kit'}, 3933, 200) +shopModule:addBuyableItem({'picture'}, 1852, 50) +shopModule:addBuyableItem({'picture'}, 1854, 50) +shopModule:addBuyableItem({'picture'}, 1853, 50) +shopModule:addBuyableItem({'potted flower'}, 2104, 5) +shopModule:addBuyableItem({'purple tapestry'}, 1857, 25) +shopModule:addBuyableItem({'red bed kit'}, 7906, 80) +shopModule:addBuyableItem({'red cushioned chair kit'}, 3901, 40) +shopModule:addBuyableItem({'red pillow'}, 1687, 25) +shopModule:addBuyableItem({'red tapestry'}, 1869, 25) +shopModule:addBuyableItem({'rocking chair kit'}, 3904, 25) +shopModule:addBuyableItem({'rocking horse kit'}, 3926, 30) +shopModule:addBuyableItem({'round blue pillow'}, 1690, 25) +shopModule:addBuyableItem({'round purple pillow'}, 1692, 25) +shopModule:addBuyableItem({'round red pillow'}, 1691, 25) +shopModule:addBuyableItem({'round table kit'}, 14328, 25) +shopModule:addBuyableItem({'round turquoise pillow'}, 1693, 25) +shopModule:addBuyableItem({'small blue pillow'}, 1681, 20) +shopModule:addBuyableItem({'small green pillow'}, 1679, 20) +shopModule:addBuyableItem({'small orange pillow'}, 1682, 20) +shopModule:addBuyableItem({'small purple pillow'}, 1678, 20) +shopModule:addBuyableItem({'small red pillow'}, 1680, 20) +shopModule:addBuyableItem({'small table kit'}, 3908, 20) +shopModule:addBuyableItem({'small turquoise pillow'}, 1683, 20) +shopModule:addBuyableItem({'small white pillow'}, 1684, 20) +shopModule:addBuyableItem({'sofa chair kit'}, 3905, 55) +shopModule:addBuyableItem({'square table kit'}, 14329, 25) +shopModule:addBuyableItem({'table lamp kit'}, 3924, 35) +shopModule:addBuyableItem({'telescope kit'}, 3925, 70) +shopModule:addBuyableItem({'treasure chest'}, 1746, 1000) +shopModule:addBuyableItem({'trophy stand'}, 7936, 50) +shopModule:addBuyableItem({'trough kit'}, 3918, 7) +shopModule:addBuyableItem({'trunk kit'}, 3920, 10) +shopModule:addBuyableItem({'vase'}, 2008, 3) +shopModule:addBuyableItem({'venorean cabinet kit'}, 20254, 90) +shopModule:addBuyableItem({'venorean drawer kit'}, 20257, 40) +shopModule:addBuyableItem({'venorean wardrobe kit'}, 20255, 50) +shopModule:addBuyableItem({'wall mirror'}, 1851, 40) +shopModule:addBuyableItem({'wall mirror'}, 1848, 40) +shopModule:addBuyableItem({'wall mirror'}, 1845, 40) +shopModule:addBuyableItem({'water pipe'}, 2099, 40) +shopModule:addBuyableItem({'weapon rack kit'}, 6115, 90) +shopModule:addBuyableItem({'white tapestry'}, 1880, 25) +shopModule:addBuyableItem({'wooden chair kit'}, 3903, 15) +shopModule:addBuyableItem({'yellow bed kit'}, 7905, 80) +shopModule:addBuyableItem({'yellow pillow'}, 1689, 25) +shopModule:addBuyableItem({'yellow tapestry'}, 1863, 25) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/hoggle.lua b/data/npc/scripts/hoggle.lua new file mode 100644 index 00000000000..bf4ff123ca4 --- /dev/null +++ b/data/npc/scripts/hoggle.lua @@ -0,0 +1,25 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Oh, this misery...'} } +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome to my humble home!") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/hugo.lua b/data/npc/scripts/hugo.lua new file mode 100644 index 00000000000..d2e5be80b05 --- /dev/null +++ b/data/npc/scripts/hugo.lua @@ -0,0 +1,184 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local config = { + ['20 brown pieces of cloth'] = { + itemId = 5913, + count = 20, + value = 1, + messages = { + done = 'Ghouls sometimes carry it with them. My assistant Irmana can also fabricate cloth from secondhand clothing.', + deliever = 'Ah! Have you brought 20 pieces of brown cloth?', + notEnough = 'Uh, that is not even enough cloth for a poor dwarf\'s look.', + success = 'Yes, yes, that\'s it! Very well, now I need 50 pieces of minotaur leather to continue.' + } + }, + ['50 minotaur leathers'] = { + itemId = 5878, + count = 50, + value = 2, + messages = { + done = 'If you don\'t know how to obtain minotaur leather, ask my apprentice Kalvin. I\'m far too busy for these trivial matters.', + deliever = 'Were you able to obtain 50 pieces of minotaur leather?', + notEnough = 'Uh, that is not even enough leather for a poor dwarf\'s look.', + success = 'Great! This leather will suffice. Now, please, the 10 bat wings.' + } + }, + ['10 bat wings'] = { + itemId = 5894, + count = 10, + value = 3, + messages = { + done = 'Well, what do you expect? Bat wings come from bats, of course.', + deliever = 'Did you get me the 10 bat wings?', + notEnough = 'No, no. I need more bat wings! I said, 10!', + success = 'Hooray! These bat wings are ugly enough. Now the last thing: Please bring me 30 heaven blossoms to neutralise the ghoulish stench.' + } + }, + ['30 heaven blossoms'] = { + itemId = 5921, + count = 30, + value = 4, + messages = { + done = 'A flower favoured by almost all elves.', + deliever = 'Is this the lovely smell of 30 heaven blossoms?', + notEnough = 'These few flowers are not enough to neutralise the ghoulish stench.', + success = 'This is it! I will immediately start to work on this outfit. Come back in a day or something... then my new creation will be born!' + }, + lastItem = true + } +} + +local message = {} + +local function greetCallback(cid) + message[cid] = nil + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "uniforms") then + if player:getStorageValue(Storage.Postman.Mission06) == 1 then + npcHandler:say("A new uniform for the post officers? I am sorry but my dog ate the last dress pattern we used. You need to supply us with a new dress pattern.", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "dress pattern") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("It was ... wonderous beyond wildest imaginations! I have no clue where Kevin Postner got it from. Better ask him.", cid) + player:setStorageValue(Storage.Postman.Mission06, 2) + elseif player:getStorageValue(Storage.Postman.Mission06) == 11 then + npcHandler:say("By the gods of fashion! Didn't it do that I fed the last dress pattern to my poor dog? Will this mocking of all which is taste and fashion never stop?? Ok, ok, you will get those ugly, stinking uniforms and now get lost, fashion terrorist.", cid) + player:setStorageValue(Storage.Postman.Mission06, 12) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'outfit') then + if not player:isPremium() then + npcHandler:say('Sorry, but my time is currently reserved for premium matters.', cid) + return true + end + + if player:getStorageValue(Storage.OutfitQuest.BeggarOutfit) < 1 then + npcHandler:say({ + 'I think I\'m having an innovative vision! I feel that people are getting tired of attempting to look wealthy and of displaying their treasures. ...', + 'A really new and innovative look would be - the \'poor man\'s look\'! I can already see it in front of me... yes... a little ragged... but not too shabby! ...', + 'I need material right now! Argh - the vision starts to fade... please hurry, can you bring me some stuff?' + }, cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(Storage.OutfitQuest.BeggarOutfit) > 0 and player:getStorageValue(Storage.OutfitQuest.BeggarOutfit) < 5 then + npcHandler:say('I am so excited! This poor man\'s look will be an outfit like the world has never seen before.', cid) + elseif player:getStorageValue(Storage.OutfitQuest.BeggarOutfit) == 5 then + if player:getStorageValue(Storage.OutfitQuest.BeggarOutfitTimer) > os.time() then + npcHandler:say('Sorry, but I am not done with the outfit yet. Venore wasn\'t built in a day.', cid) + elseif player:getStorageValue(Storage.OutfitQuest.BeggarOutfitTimer) > 0 and player:getStorageValue(Storage.OutfitQuest.BeggarOutfitTimer) < os.time() then + npcHandler:say('Eureka! Alas, the poor man\'s outfit is finished, but... to be honest... it turned out much less appealing than I expected. However, you can have it if you want, okay?', cid) + npcHandler.topic[cid] = 5 + end + elseif player:getStorageValue(Storage.OutfitQuest.BeggarOutfit) == 6 then + npcHandler:say('I guess my vision wasn\'t that grand after all. I hope there are still people who enjoy it.', cid) + end + elseif config[msg:lower()] then + local targetMessage = config[msg:lower()] + if player:getStorageValue(Storage.OutfitQuest.BeggarOutfit) ~= targetMessage.value then + npcHandler:say(targetMessage.messages.done, cid) + return true + end + + npcHandler:say(targetMessage.messages.deliever, cid) + npcHandler.topic[cid] = 4 + message[cid] = targetMessage + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 2 then + npcHandler:say({ + 'Good! Listen, I need the following material - first, 20 pieces of brown cloth, like the worn and ragged ghoul clothing. ...', + 'Secondly, 50 pieces of minotaur leather. Third, I need bat wings, maybe 10. And 30 heaven blossoms, the flowers elves cultivate. ...', + 'Have you noted down everything and will help me gather the material?' + }, cid) + npcHandler.topic[cid] = 3 + elseif npcHandler.topic[cid] == 3 then + if player:getStorageValue(Storage.OutfitQuest.DefaultStart) ~= 1 then + player:setStorageValue(Storage.OutfitQuest.DefaultStart, 1) + end + player:setStorageValue(Storage.OutfitQuest.BeggarOutfit, 1) + npcHandler:say('Terrific! What are you waiting for?! Start right away gathering 20 pieces of brown cloth and come back once you have them!', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 4 then + local targetMessage = message[cid] + if not player:removeItem(targetMessage.itemId, targetMessage.count) then + npcHandler:say(targetMessage.messages.notEnough, cid) + return true + end + + player:setStorageValue(Storage.OutfitQuest.BeggarOutfit, player:getStorageValue(Storage.OutfitQuest.BeggarOutfit) + 1) + if targetMessage.lastItem then + player:setStorageValue(Storage.OutfitQuest.BeggarOutfitTimer, os.time() + 86400) + end + npcHandler:say(targetMessage.messages.success, cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 5 then + player:addOutfit(153) + player:addOutfit(157) + player:setStorageValue(Storage.OutfitQuest.BeggarOutfit, 6) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + npcHandler:say('Here you go. Maybe you enjoy if after all.', cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'no') then + if npcHandler.topic[cid] == 2 then + npcHandler:say('Argh! I guess this awesome idea has to remain unimplemented. What a pity.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + npcHandler:say('Do you want me to repeat the task requirements?', cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 4 then + npcHandler:say('Hurry! I am at my creative peak right now!', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 5 then + npcHandler:say('Well, if you should change your mind, just ask me for the beggar outfit.', cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/humgolf.lua b/data/npc/scripts/humgolf.lua new file mode 100644 index 00000000000..9d2ae19df44 --- /dev/null +++ b/data/npc/scripts/humgolf.lua @@ -0,0 +1,42 @@ + +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if(msgcontains(msg, "farmine")) then + if(player:getStorageValue(Storage.TheNewFrontier.Questline) == 15) then + npcHandler:say("Bah, Farmine here, Farmine there. Is there nothing else than Farmine to talk about these days? Hrmpf, whatever. So what do you want?", cid) + npcHandler.topic[cid] = 1 + end + elseif(msgcontains(msg, "flatter")) then + if(npcHandler.topic[cid] == 1) then + if(player:getStorageValue(Storage.TheNewFrontier.BribeHumgolf) < 1) then + npcHandler:say("Yeah, of course they can't do without my worms. Mining and worms go hand in hand. Well, in the case of the worms it is only an imaginary hand of course. I'll send them some of my finest worms.", cid) + player:setStorageValue(Storage.TheNewFrontier.BribeHumgolf, 1) + player:setStorageValue(Storage.TheNewFrontier.Mission05, player:getStorageValue(Storage.TheNewFrontier.Mission05) + 1) --Questlog, The New Frontier Quest "Mission 05: Getting Things Busy" + end + end + end + return true +end +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/humnog_the_guard.lua b/data/npc/scripts/humnog_the_guard.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/humnog_the_guard.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/humphrey.lua b/data/npc/scripts/humphrey.lua new file mode 100644 index 00000000000..dfd1fd1313a --- /dev/null +++ b/data/npc/scripts/humphrey.lua @@ -0,0 +1,72 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Embrace of Tibia +local blessKeyword = keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'Would you like to receive that protection for a sacrifice of |BLESSCOST| gold, child?'}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the embrace of Tibia, pilgrim.', cost = '|BLESSCOST|', bless = 6}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, noble |PLAYERNAME|') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good Bye, noble |PLAYERNAME|') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good Bye, noble |PLAYERNAME|') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/huntsman.lua b/data/npc/scripts/huntsman.lua new file mode 100644 index 00000000000..b168696aae8 --- /dev/null +++ b/data/npc/scripts/huntsman.lua @@ -0,0 +1,72 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, "huntsman") then + npcHandler:say("I hunt game of all sorts to earn a living. I respect the {balance} of nature though and take only as much as I need.", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "balance") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "To be honest, I don't care too much about that spiritual balance thing. Better talk to {Benevola} about such things. ...", + "As a matter of fact though, if too many animals are killed, things might rapidly change for the worse. ...", + "So it's only practical thinking to keep the balance in mind as long as I can afford it." + }, cid) + npcHandler.topic[cid] = 2 + end + + elseif msgcontains(msg, "benevola") then + if npcHandler.topic[cid] == 2 then + player:addMapMark(Position(32596, 31746, 7), MAPMARK_FLAG, "Benevola's Hut") + npcHandler:say("She is a bit overly concerned about that nature and balance stuff but she has a good heart. She is living in the woods between Carlin and Ab'Dendriel. I'll mark her hut on your map.", cid) + npcHandler.topic[cid] = 0 + end + + elseif msgcontains(msg, "white deer") then + npcHandler:say("The white deer are somewhat sacred to the elves. Though their fur and antlers are rumoured to earn a decent amount of {gold} on the market, it's probably not worth the trouble.", cid) + npcHandler.topic[cid] = 3 + + elseif msgcontains(msg, "gold") then + if npcHandler.topic[cid] == 3 then + npcHandler:say("Just between you and me, I heard a guy named {Cruleo} is offering some handsome cash for the trophies of a white deer.", cid) + npcHandler.topic[cid] = 4 + end + elseif msgcontains(msg, "cruleo") then + if npcHandler.topic[cid] == 4 then + player:addMapMark(Position(32723, 31793, 7), MAPMARK_FLAG, "Cruleo's Hut") + npcHandler:say("He has a house in the wilderness. Just between Ab'Dendriel and the orcland. I'll mark his hut on your map.", cid) + npcHandler.topic[cid] = 0 + end + end + + return true +end + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m just a simple {huntsman}.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, I don\'t think telling a stranger your name is a smart thing to do.'}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye. Take care.") +npcHandler:setMessage(MESSAGE_FAREWELL, "I can still see you.") +npcHandler:setMessage(MESSAGE_GREET, "Howdy partner.") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/hyacinth.lua b/data/npc/scripts/hyacinth.lua new file mode 100644 index 00000000000..8c969e19cec --- /dev/null +++ b/data/npc/scripts/hyacinth.lua @@ -0,0 +1,198 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.TheRookieGuard.Mission04) == 2 then + npcHandler:setMessage(MESSAGE_GREET, "Greetings, traveller |PLAYERNAME|. You must be the one sent by Lily. Do you have a sack of {herbs} for me?") + elseif player:getStorageValue(Storage.TheRookieGuard.Mission04) == 3 or player:getStorageValue(Storage.TheRookieGuard.Mission04) == 4 then + npcHandler:setMessage(MESSAGE_GREET, "Greetings, traveller |PLAYERNAME|. I still have a present for you! Would you like to have it now?") + else + npcHandler:setMessage(MESSAGE_GREET, 'Greetings, traveller |PLAYERNAME|. As you have found the way to my hut, how can I {help} you?') + end + return true +end + +-- The Rookie Guard Quest - Mission 04: Home-Brewed + +-- Mission 4: Confirm (Give herbs) +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Thank you so much! I'm just too old to walk into the village each day, and the herbs must be fresh. Say, would you like to have a sample of my potions as reward?" +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission04) == 2 and player:getItemCount(13827) >= 1 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission04, 3) + player:removeItem(13827, 1) +end +) +keywordHandler:addAliasKeyword({"herbs"}) + +-- Mission 4: Decline (Give herbs) +local mission4LostHerbs = keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Well, then I must have mistaken you with someone else. Or did you lose it on the way?" +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission04) == 2 end +) + +-- Mission 4: Confirm (Lost herbs) +mission4LostHerbs:addChildKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "That's too bad... but I'm sure Lily could give you another one. Just walk back and talk to her again.", + reset = true +}) + +-- Mission 4: Decline (Lost herbs) +mission4LostHerbs:addChildKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Alright then. Good luck on your travels.", + ungreet = true +}) + +-- Mission 4: Accept (First reward) +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "Here you go - two small health potions. If you use them on yourself, they will recover some of your hitpoints. ...", + "I recommend setting them on a hotkey so you don't have to search for them in a case of emergency. ...", + "Once you are a bit more experienced and have chosen a vocation, you'll have access to many different potions and also spells to restore your health. ...", + "Oh, and I also have another present for you! Do you still have some space in your inventory?" + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission04) == 3 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission04, 4) + player:addItemEx(Game.createItem(8704, 2), true, CONST_SLOT_BACKPACK) +end +) + +-- Mission 4: Accept (Second reward) +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "Take this star ring. When you wear it in your ring slot, it will improve the effect of food that you have eaten for a limited time. So as long as you're not hungry, you will have increased hitpoint regeneration. ...", + "It makes sense to undress it when you have full hitpoints, so that the effect of the ring won't be wasted. ...", + "There are a lot of different rings in Tibia, but this one only works as long as you haven't learnt a vocation, so don't be afraid to use it. ...", + "Anyway, thanks so much for your help. I can brew a lot of potions from these herbs. If you're in the area and find yourself in need of potions, don't hesitate to drop by and ask me for a {trade}. ...", + "Anyway, this old man has taken enough of your time. Why don't you go back to the village and talk to Vascalir? If you stay on the path, you should be safe. Don't forget your potions!" + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission04) == 4 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission04, 5) + player:addItemEx(Game.createItem(13825, 1), true, CONST_SLOT_BACKPACK) +end +) + +-- Mission 4: Decline (First reward) +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Oh, but I insist! After all you made the long way. Please, take my reward!" +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission04) == 3 end +) + +-- Mission 4: Decline (Second reward) +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Well, make some space and then talk to me again. I give you something really useful." +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission04) == 4 end +) + +-- Basic Keywords +keywordHandler:addKeyword({'hint'}, StdModule.rookgaardHints, {npcHandler = npcHandler}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = 'Time doesn\'t matter to me.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m Hyacinth.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m a {druid} and healer, a follower of {Crunor}.'}) +keywordHandler:addKeyword({'crunor'}, StdModule.say, {npcHandler = npcHandler, text = 'May Crunor bless you and protect you on your journeys!'}) +keywordHandler:addKeyword({'druid'}, StdModule.say, {npcHandler = npcHandler, text = 'There are only two other druids on Rookgaard, {Lily} and {Cipfried}.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'Storage for worldly wealth.'}) +keywordHandler:addKeyword({'destiny'}, StdModule.say, {npcHandler = npcHandler, text = 'Who knows what it will be? Only time will show.'}) +keywordHandler:addKeyword({'how', 'are', 'you'}, StdModule.say, {npcHandler = npcHandler, text = 'Thank the gods, I\'m fine.'}) +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'What help do you seek? I sell health potions, ask me for a {trade} if you need one.'}) +keywordHandler:addKeyword({'spell'}, StdModule.say, {npcHandler = npcHandler, text = 'I can\'t teach you magic. On the {mainland} you will learn spells early enough.'}) +keywordHandler:addKeyword({'magic'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m one of the few magic users on this isle. I can sense a follower of the dark path of magic hiding somewhere in the depths of the dungeons.'}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = 'It is shaped by the will of the gods, so we don\'t have to question it.'}) +keywordHandler:addKeyword({'temple'}, StdModule.say, {npcHandler = npcHandler, text = 'I used to be there with my old friend Cipfried to heal adventurers. After all these years, I prefer solitude now.'}) +keywordHandler:addKeyword({'god'}, StdModule.say, {npcHandler = npcHandler, text = 'Teaching you about the gods would require too much time. But you can always read the books in the {library}.'}) +keywordHandler:addKeyword({'library'}, StdModule.say, {npcHandler = npcHandler, text = 'The library is in the {academy}, north of the {temple}.'}) +keywordHandler:addKeyword({'academy'}, StdModule.say, {npcHandler = npcHandler, text = 'A place to learn about {Tibia}.'}) +keywordHandler:addKeyword({'food'}, StdModule.say, {npcHandler = npcHandler, text = 'Are you hungry? I\'m sorry, I have no food here.'}) +keywordHandler:addKeyword({'potion'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes, I sell small health potions. Ask me for a trade if you need one.'}) +keywordHandler:addKeyword({'king'}, StdModule.say, {npcHandler = npcHandler, text = 'I don\'t care about kings, queens, and the like.'}) +keywordHandler:addKeyword({'rookgaard'}, StdModule.say, {npcHandler = npcHandler, text = 'I rarely visit the town. It\'s much better here.'}) +keywordHandler:addKeyword({'main'}, StdModule.say, {npcHandler = npcHandler, text = 'There\'s a huge world waiting for you.'}) +keywordHandler:addKeyword({'monster'}, StdModule.say, {npcHandler = npcHandler, text = 'Most of the so-called monsters of this isle are only creatures of the gods. There are some beasts that are truly monstrous on the {mainland}.'}) +keywordHandler:addKeyword({'blueberr'}, StdModule.say, {npcHandler = npcHandler, text = 'Are you hungry? I\'m sorry, I have no food here.'}) +keywordHandler:addKeyword({'dungeon'}, StdModule.say, {npcHandler = npcHandler, text = 'The dungeons are dangerous for inexperienced adventurers.'}) + +keywordHandler:addKeyword({'offer'}, StdModule.say, {npcHandler = npcHandler, text = 'Just ask me for a {trade} to check out my offers. I have only small health potions for sale, though.'}) +keywordHandler:addAliasKeyword({'stuff'}) +keywordHandler:addAliasKeyword({'wares'}) +keywordHandler:addAliasKeyword({'buy'}) +keywordHandler:addAliasKeyword({'sell'}) + +keywordHandler:addKeyword({'equipment'}, StdModule.say, {npcHandler = npcHandler, text = 'You\'ll have to buy that from the merchants in town. I\'m just a simple druid and healer.'}) +keywordHandler:addAliasKeyword({'rope'}) +keywordHandler:addAliasKeyword({'backpack'}) +keywordHandler:addAliasKeyword({'shovel'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addAliasKeyword({'armor'}) +keywordHandler:addAliasKeyword({'helmet'}) + +keywordHandler:addKeyword({'deposit'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'ll pay you 5 gold for every empty vial and potion flask. Just ask me for a {trade}.'}) +keywordHandler:addAliasKeyword({'flask'}) +keywordHandler:addAliasKeyword({'vial'}) + +-- Names +keywordHandler:addKeyword({'obi'}, StdModule.say, {npcHandler = npcHandler, text = 'A greedy and annoying person just like most people are.'}) +keywordHandler:addKeyword({'norma'}, StdModule.say, {npcHandler = npcHandler, text = 'Now she has completely gotten out of her mind.'}) +keywordHandler:addKeyword({'loui'}, StdModule.say, {npcHandler = npcHandler, text = 'He was a promising young druid when something happened to his mind. It\'s a sad story.'}) +keywordHandler:addKeyword({'santiago'}, StdModule.say, {npcHandler = npcHandler, text = 'He does a good job out there.'}) +keywordHandler:addKeyword({'zirella'}, StdModule.say, {npcHandler = npcHandler, text = 'I know her since she was little.'}) +keywordHandler:addKeyword({'al', 'dee'}, StdModule.say, {npcHandler = npcHandler, text = 'One of these greedy merchants.'}) +keywordHandler:addKeyword({'amber'}, StdModule.say, {npcHandler = npcHandler, text = 'I saw her stranding with her raft.'}) +keywordHandler:addKeyword({'billy'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s a farmer and behaves a little better than his cousin.'}) +keywordHandler:addKeyword({'willie'}, StdModule.say, {npcHandler = npcHandler, text = 'An unpleasant person.'}) +keywordHandler:addKeyword({'cipfried'}, StdModule.say, {npcHandler = npcHandler, text = 'His healing powers equal mine.'}) +keywordHandler:addKeyword({'dixi'}, StdModule.say, {npcHandler = npcHandler, text = 'I think she\'s under bad influence.'}) +keywordHandler:addKeyword({'hyacinth'}, StdModule.say, {npcHandler = npcHandler, text = 'That\'s my name.'}) +keywordHandler:addKeyword({'lee\'delle'}, StdModule.say, {npcHandler = npcHandler, text = 'She\'s actually quite nice.'}) +keywordHandler:addKeyword({'lily'}, StdModule.say, {npcHandler = npcHandler, text = 'She\'s a druid. Since she started selling health potions, people visit me only rarely. Which is a good thing, but of course I\'ll help if I\'m needed.'}) +keywordHandler:addKeyword({'oracle'}, StdModule.say, {npcHandler = npcHandler, text = 'The oracle will lead you to your {destiny} once you are level 8.'}) +keywordHandler:addKeyword({'paulie'}, StdModule.say, {npcHandler = npcHandler, text = 'I think that guy is new. He\'s a {bank} clerk.'}) +keywordHandler:addKeyword({'seymour'}, StdModule.say, {npcHandler = npcHandler, text = 'He has some inner devils that torture him.'}) +keywordHandler:addKeyword({'tom'}, StdModule.say, {npcHandler = npcHandler, text = 'Tom is the local tanner. That means he always needs fresh corpses or leather.'}) +keywordHandler:addKeyword({'dallheim'}, StdModule.say, {npcHandler = npcHandler, text = 'A man of the sword.'}) +keywordHandler:addAliasKeyword({'zerbrus'}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'May Crunor bless you.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'May Crunor bless you.') +npcHandler:setMessage(MESSAGE_SENDTRADE, 'Here. Don\'t forget, if you buy potions, there\'s a {deposit} of 5 gold on the empty flask.') +npcHandler:setCallback(CALLBACK_GREET, greetCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ikassis.lua b/data/npc/scripts/ikassis.lua new file mode 100644 index 00000000000..c1c3da097b4 --- /dev/null +++ b/data/npc/scripts/ikassis.lua @@ -0,0 +1,58 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "mission") then + if (player:getStorageValue(Storage.ThreatenedDreams.TroubledMission01) == 5) then + npcHandler:say({ + "One of my sisters, in the disguise of a nightingale, told me that Alkestios would send you. There is a problem which is not concerning me but a wolf mother on the small island Cormaya. ...", + "As we, the fae, consider ourselves guardians and protectors of plants and animals, it is important for me to help this wolf. Unfortunately, I can't do it myself because at the moment I'm bound to this vessel, this snake. ...", + "Thus I can't cross the ocean to reach Cormaya. Will you help me?" + }, cid) + npcHandler.topic[cid] = 1 + elseif (player:getStorageValue(Storage.ThreatenedDreams.TroubledMission01) == 11) then + player:setStorageValue(Storage.ThreatenedDreams.TroubledMission01, 12) + npcHandler:say("The wolf's ghost has found peace. Thank you, human being. However, there is someone else who needs help: A sister of mine who's bereft of something very precious. You'll find her in the guise of a swan at a small river south-east of here.", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You are not on that mission.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, "yes") then + npcHandler:say({ + "Nature's blessings! You may find the desperate wolf mother in the south of Cormaya. You will know the place because there is a big stone that looks like a grumpy face. ...", + "At night it will weep bloody tears and only at night you will meet the ghost there. Take this talisman so you may be able to talk with animals and even plants and stones. Just don't expect that all of them will answer you." + }, cid) + player:setStorageValue(Storage.ThreatenedDreams.TroubledMission01, 6) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") then + npcHandler:say("Then not.", cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Nature's blessing, traveler!") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/imalas.lua b/data/npc/scripts/imalas.lua new file mode 100644 index 00000000000..af075ecf2fe --- /dev/null +++ b/data/npc/scripts/imalas.lua @@ -0,0 +1,22 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'food'}, StdModule.say, {npcHandler = npcHandler, text = "I offer quite a lot of food. Ask me for a {trade} if you're hungry"}) + +npcHandler:setMessage(MESSAGE_GREET, "Hello |PLAYERNAME|! What do you need? If it's {food}, you've come to the right place.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Yep, take a good look.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/imbul.lua b/data/npc/scripts/imbul.lua new file mode 100644 index 00000000000..fdb551b9530 --- /dev/null +++ b/data/npc/scripts/imbul.lua @@ -0,0 +1,31 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Travel +local function addTravelKeyword(keyword, text, cost, destination) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to the ' .. text .. ' for |TRAVELCOST|?', cost = cost}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'Maybe another time.', reset = true}) +end + +addTravelKeyword('east', 'east end', 7, Position(32679, 32777, 7)) +addTravelKeyword('centre', 'centre', 7, Position(32628, 32771, 7)) + +-- Basic +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'I can bring you either to the {east} end of Port Hope or to the {centre} of the town, where would you like to go?'}) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/inigo.lua b/data/npc/scripts/inigo.lua new file mode 100644 index 00000000000..3a9c687699e --- /dev/null +++ b/data/npc/scripts/inigo.lua @@ -0,0 +1,651 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local hints = { + [1] = "If you don't know the meaning of an icon on the minimap, move the mouse cursor on it and wait a moment.", + [2] = "If you seek more information, look at or click on objects near you, like wall signs, \z + blackboards or books in book cases - many of them have useful information on {Tibia} or maybe \z + even a quest you are doing. By the way, to receive more of my hints, just say {hints} again.", + [3] = "If you want to attack a monster, simply click on it in your battle list. \z + A red frame around a monster shows you are attacking it.", + [4] = "If you already know where you want to go, click on the automap and your character \z + will walk there automatically if the location is reachable and not too far away.", + [5] = "Always have a {rope} with you! If you fall into a hole and are surrounded by {monsters}, \z + quickly use the rope with the ropespot to get back up and out.", + [6] = "'Capacity' restricts the amount of things you can carry with you. It raises with each level.", + [7] = "Always have a look on your health bar. \z + If you see that you do not regenerate health points anymore, eat something. ", + [8] = "Always eat as much {food} as possible. \z + This way, you'll regenerate health points for a longer period of time.", + [9] = "After you have killed a monster, you have 10 seconds in which the corpse \z + is not moveable and no one else but you can loot it.", + [10] = "Be careful when you approach three or more {monsters} because you only can block the attacks of two! \z + In such a situation, even a few salamanders can do severe damage or even kill you.", + [11] = "There are many ways to gather {food}. Many creatures drop food but you can also pick blueberries or \z + bake your own bread. If you have a {fishing rod} and worms in your inventory, you can also try to catch a fish.", + [12] = "Baking bread is rather complex. First of all you need a scythe to harvest wheat. \z + Then you use the wheat with a millstone to get flour. This can be be used on water to get dough, \z + which can be used on an oven to bake bread. Use milk instead of water to get cake dough.", + [13] = "{Dying} hurts! Better run away than risk your life. \z + You are going to lose experience and skill points when you die. \z + And anyone can loot your corpse if you are not blessed.", + [14] = "When you switch to '{Offensive} {Fighting}', you deal out more damage but you also get hurt more easily.", + [15] = "When you are on low health and need to run away from a monster, \z + switch to '{Defensive} {Fighting}' and the monster will hit you less severely.", + [16] = "Many creatures try to run away from you. Select 'Chase Opponent' to follow them.", + [17] = "The deeper you enter a dungeon, the more dangerous it will be. \z + Approach every dungeon with utmost care or an unexpected creature might kill you. \z + This will result in losing experience and skill points.", + [18] = "Due to the perspective, some objects in {Tibia} are not located at the spot they seem to appear \z + (ladders, windows, lamps). Try clicking on the floor tile the object would lie on.", + [19] = "Almost as important as a {rope} is a {shovel}. Many things can be dug out of the sand, and a pile \z + of loose stones might hide a secret entrance. But if you go down an unknown hole, make sure you have a \z + rope with you to get you out quickly if necessary!", + [20] = "Stairs, ladders and dungeon entrances are marked as yellow dots on the automap.", + [21] = "You can get {food} by killing animals or {monsters}. You can also pick blueberries or bake your own bread. \z + If you are too lazy or own too much money, you can also buy food.", + [22] = "Quest containers can be recognised easily. They don't open up regularly but display a message \z + 'You have found ....'. They can only be opened once.", + [23] = "Better run away than risk to die. You'll lose experience and skill points each time you die.", + [24] = "You can form a party by right-clicking on a player and selecting 'Invite to Party'. \z + The party leader can also enable 'Shared Experience' by right-clicking on him- or herself.", + [25] = "You can assign {spells}, the use of items, or random text to 'hotkeys'. You find them under 'Options'.", + [26] = "You can also follow other {players}. Just right-click on the player and select 'Follow'.", + [27] = "You can found a party with your friends by right-clicking on a player and selecting 'Invite to Party'. \z + If you are invited to a party, right-click on yourself and select 'Join Party'.", + [28] = "Only found parties with people you trust! You can attack people in your party without getting a {skull}. \z + This is helpful for training your {skills}, \z + but can be abused to kill people without having to fear negative consequences.", + [29] = "The leader of a party has the option to distribute gathered experience among all {players} in the party. \z + If you are the leader, right-click on yourself and select 'Enable Shared Experience'.", + [30] = "If you see someone with a {skull} symbol next to their name, it means he or she has attacked \z + or even killed another player. Be careful around such people, as their next target might be you.", + [31] = "A brown frame around a player means he or she is in a {PvP} situation.", + [32] = "To open or close {skills}, battle or VIP list, click on the corresponding button. \z + The buttons are displayed to the left or right of your game window.", + [33] = "If you want to trade an item with another player, right-click on the item and select \z + 'Trade with ...', then click on the player with whom you want to trade.", + [34] = "Send private messages to other {players} by right-clicking on the player or the player's name and select \z + 'Message to ....'. You can also open a 'private message channel' and type in the name of the player.", + [35] = "There is nothing more I can tell you. If you are still in need of some {hints}, I can repeat them for you." +} +local voices = { + {text = "I know the ways and lays of Dawnport. Talk to me if you want to know more!"}, + {text = "Troll hair, wolf fur, lumps of dirt - bring them to me!"}, + {text = "Come to me if you need help!"}, + {text = "Hey there, young adventurer! Need a hint?"}, + {text = "You came through the portal? Talk to me!"}, + {text = "You're going out? Make sure you have a rope with you!"}, + {text = "Buying all sorts of creature products!"}, + {text = "You're looking thoughtful. Maybe I can help you?"} +} + +npcHandler:addModule(VoiceModule:new(voices)) +npcHandler:setMessage(MESSAGE_GREET, "You came through the {portal}! \z + Though it must be different from where you came from, I'm sure you can help us. But first, I can {help} YOU.") + +keywordHandler:addKeyword({"name"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Ah, back in the old days, I was called Inigo Verasquiriz, but I doubt my family would acknowledge me. \z + Those that are still alive, that is." + } +) +keywordHandler:addKeyword({"job"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I used to be a hunter and trapper, but these bones have grown weary. \z + I now tan furs and hides and {trade} in creature products. And I can help you find your way if you need directions." + } +) +keywordHandler:addKeyword({"tibia"}, StdModule.say, + { + npcHandler = npcHandler, + text = "That's where we are - the world of Tibia. \z + We're on a small island called {Dawnport}, not far from the coast of the Tibian {Mainland}, to be precise." + } +) +keywordHandler:addKeyword({"questing"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Oh, I can handle my tasks myself, thank you. \z + If you are looking for something to do, you should go to Morris and ask him for quests. \z + You can also help us fight {monsters}." + } +) +keywordHandler:addKeyword({"people"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Well, the other fellows you see here, selling stuff and so forth. \z + Say a name and I'll tell you what I know of him or her." + } +) +keywordHandler:addKeyword({"monsters"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Marvellous specimen we have here on {Dawnport}! \z + Just be careful when you go hunting them, {dying} hurts in {Tibia}! \z + I will happily buy any creature products you may find." + } +) +keywordHandler:addKeyword({"garamond"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Used to be a professor at the magic academy in Edron, I believe. \z + Likes to see different places, so he joined our illustrous little group. \z + Sells {sorcerer} and {druid} {spells} to our trainees." + } +) +keywordHandler:addKeyword({"tybald"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I'm not sure that's his actual name, but I guess he has good reasons to stay incognito here. \z + In any case, he's a formidable fighter and knows usefull {spells} for knights and paladins." + } +) +keywordHandler:addKeyword({"richard"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Richard came here as a shipwrecked carpenter, and now sells {tools} and {food} to all adventurers. \z + If you need a {rope} or {shovel}, {fishing rod} or some provisions for a hunt, you should trade with him!" + } +) +keywordHandler:addKeyword({"knight"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Knights are close combat fighters, the toughest vocation of all. \z + They usually wield melee weapons such as swords, axes or clubs." + } +) +keywordHandler:addKeyword({"druid"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Druids are nature magicians. \z + Their speciality is casting ice and earth magic, as well as providing healing for others." + } +) +keywordHandler:addKeyword({"paladin"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Paladins are well-trained distance fighters and can cast holy magic. \z + You will usually see them wearing bows or crossbows." + } +) +keywordHandler:addKeyword({"sorcerer"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Sorcerers are elemental magicians. They have mastered fire, energy and death magic." + } +) +keywordHandler:addKeyword({"tools"}, StdModule.say, + { + npcHandler = npcHandler, + text = "In {Tibia}, you can use different tools with your environment, or for quests. \z + The most important tools are {rope} and {shovel}. \z + A {fishing rod}'s also good when you need to eat, and are near a river or the sea." + } +) +keywordHandler:addKeyword({"food"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Food is very important for your health and mana. \z + If you are hurt in a fight with a monster, select 'USE' on food such as cheese, ham or meat to eat it. \z + This will slowly refill your health and mana. Here at the outpost, you can buy food from {Richard}." + } +) +keywordHandler:addKeyword({"fishing rod"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Use a fishing rod on a patch of water to see if you can catch fish! \z + Eating is essential in {Tibia} - if you don't eat when you're hungry, you won't regenerate health or mana. \z + So you should aways have some {food} with you." + } +) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "portal") then + npcHandler:say( + { + "It seems to emanate a magical call or pulse that draws all sorts of creatures to it - no offense meant. \z + When we first found it, we were flabbergasted - we thought maybe a mad sorcerer had built it, \z + or a cult, to summon something evil. ...", + "But we didn't find any conclusive hints. \z + {Menesto} and a few others volunteered to guard the portal from the {monsters} of this isle. \z + You say you came through it from your world! Astounding. ...", + "You couldn't have chosen a better time. \z + We really need help against the monsters that swarm this island, and the whole world of {Tibia}. \z + If you're unsure on how to {help} exactly, I can give you directions." + }, + cid, false, true, 10) + elseif msgcontains(msg, "menesto") then + npcHandler:say( + { + "Hasn't been with us for very long. Very interested in all things mystical, \z + so Menesto was sent down to guard the strange crystal {portal} we found here. ...", + "... But of course, you met him. ... So it really is a portal, and you came through it \z + from another plane of existence! I never quite believed the tales of old, not really. \z + But now... it's wonderful, truly wonderful. ...", + "Well, if you have any questions as to THIS plane of existence, which we call {Tibia}, just ask me. \z + I can give directions, {hints}, you name it. " + }, + cid, false, true, 10) + elseif msgcontains(msg, "play") then + npcHandler:say( + { + "Our world {Tibia} is swarmed by many dangerous {monsters}, so {fighting} is something you will \z + have to learn and master quickly. You can fight as a {sorcerer}, druid, {paladin} or {knight}. ...", + "We need your help in keeping the monsters at bay - walk out of one of the four gates here, \z + and you will receive one of the four {vocations} and its gear to try out and fight monsters. ...", + "{Dawnport} is just a small, but dangerous island. You will have to reach level 8 at least and \z + choose your definite vocation before you can leave for the {mainland}. To reach level 8, you \z + will have to fight some monsters in order to progress. ... ", + "Fighting is essential in Tibia, and though Dawnport is quite safe in comparison to the mainland, \z + be careful not to die, as {dying} HURTS. ...", + "If you have any other questions, tell me." + }, + cid, false, true, 10) + elseif msgcontains(msg, "combat") then + npcHandler:say( + { + "There are many dangers in {Tibia}. You may have to defend yourself not only against {monsters}, \z + but if {PvP} is allowed, against other {players}, too. ...", + "To attack, click on your chosen target in the battle list. \z + A red frame will show you which target you are currently attacking. ...", + "To automatically follow your target, click on 'Chase Opponent' in your combat controls - the top left button. ...", + "You can also define your attack and defense mode, by selecting {offensive}, {balanced} or {defensive} fighting." + }, + cid, false, true, 10) + elseif msgcontains(msg, "pvp") then + npcHandler:say( + { + "Depending on the world you chose in {Tibia}, {players} may attack you at all times or only if you consent. ...", + "On an Optional PvP world, PvP is only possible if both players consent to it; \z + but on Open PvP or Hardcore PvP worlds, any player may always attack you, so be watchful. ...", + "A brown frame around a player indicates he or she is in a PvP situation. \z + A {skull} next to a player name means he or she attacked or killed another player. ...", + "Here on {Dawnport}, PvP is not allowed inside the outpost, \z + and not possible until you have reached level 8 at least. If you have any other questions, tell me." + }, + cid, false, true, 10) + elseif msgcontains(msg, "players") then + npcHandler:say( + { + "To chat with other players, you can click on one of the chat channels and see who is posting in there. ...", + "If you want to message a specific player, right-click on his or her name and select \z + 'Message to '. This will open up a chat channel where you can type in your message to him or her." + }, + cid, false, true, 10) + elseif msgcontains(msg, "npc") then + npcHandler:say( + { + "NPC means someone like me or {Hamish} or {Coltrayne}, for example. \z + You can easily discern us from {players} like you, because there is a speech bubble next to our {name}. ...", + "We all have our different ways, but normally, addressing an NPC with 'hi' or \z + 'hello' will open a conversation. ...", + "Some NPCs will have secret words that they react to that are not highlighted in their conversation. \z + In that case, you need to type in your question. ...", + "To do so, open the NPC Chat Channel and click on the empty space below the NPCs dialogue, and start typing. ...", + "You can try this out by asking an NPC about their {job}, as this is a keyword most will react to. \z + If you have any other questions, tell me." + }, + cid, false, true, 10) + elseif msgcontains(msg, "spells") then + npcHandler:say( + { + "Every vocation has specific spells that can only be used if you have that vocation. \z + Sorcerers and druids of course rely heavily on spells, while knights only have a few at their disposal. ...", + "As an adventurer in training, you have a few spells at your disposal at the beginning, \z + but more will become available as you progress. ...", + "Once you're level 8, new spells become available upstairs at the spell trainers {Garamond} and {Tybald}. \z + They can tell you more." + }, + cid, false, true, 10) + elseif msgcontains(msg, "shovel") then + npcHandler:say( + { + "Second best thing to a rope - a shovel will reveal secret entrances buried \z + under loose stone piles, or under sand, or earth... you will see! ...", + "Shovels can be bought at {Richard}'s, like the other equipment, or food. \z + If you don't have the money yet, go out and kill some {monsters} outside - \z + and maybe you'll even find a shovel, who knows!" + }, + cid, false, true, 10) + elseif msgcontains(msg, "dawnport") then + npcHandler:say( + { + "We found the island following a strange glow we saw at night, close before dawn. \z + We were looking for a source of unknown, powerful magic, and it seemed that this island was its source. ...", + "When we arrived, we found goblins, minotaurs, trolls and undead warring on this island. \z + We wondered why. Then they seemed to reach an agreement, and settled down in the caves. \z + We decided to investigate. ...", + "That is when we found the strange crystal {portal}, through which you came. \z + Perhaps this is why the {monsters} battle, but won't leave. ...", + "It certainly is a place of power, so {Menesto}'s group was sent down to guard it. \z + However, we are but few, so we need every help we can get to defend and maintain the outpost on this isle. ...", + "That is why we need your help - choose the vocation that suits you, take up its arms and help us \z + defend this place against the evil that wants to claim it! If you need any help in how to do these things, ask me." + }, + cid, false, true, 10) + elseif msgcontains(msg, "mainland") then + npcHandler:say( + { + "The mainland harbours the most ancient cities of {Tibia}, and many dangers and adventures as well. \z + When you have helped us defend {Dawnport}, and learned enough of the ways of Tibia to \z + reach level 8 at least, you should leave for the mainland. ...", + "There you can continue to battle evil - and believe me, there is much of that in our world, alas. ...", + "Premium adventurers can also sail to the many islands that surround the mainland, which offer many more dangers \z + and mysteries to be explored; and you can do quests to ride mounts, and dress in a variety of new outfits." + }, + cid, false, true, 10) + elseif msgcontains(msg, "figthing") then + npcHandler:say( + { + "Go through one of the open gates on this floor and you will be equipped with \z + training weapons and {spells} of a specific vocation. ...", + "There are four vocations in Tibia: {knight}, {druid}, {paladin} and {sorcerer}. \z + Each one has its unique abilities, strengths and weaknesses. \z + Just try them out to see which one suits you best. ...", + "We need your help in our battle. Fight {monsters} to gain experience and better {skills}, \z + until you reach level 8 at least. Make sure you always have not only a weapon, \z + but a {rope} with you, as well! ...", + "Once you reached level 8 or more, you have to choose one vocation as your definite vocation \z + before you can leave for the Tibian {mainland}, where more dangers await you. ... ", + "To choose your definite vocation, talk to {Oressa} downstairs in the {temple}. \z + She can also heal you if you are severely wounded or poisoned - just say 'heal' or 'help' to her. ...", + "If you have any other questions, tell me." + }, + cid, false, true, 10) + elseif msgcontains(msg, "vocations") then + npcHandler:say( + { + "A vocation is your profession and chosen destiny, rolled into one. \z + There are four vocations in {Tibia}: {knight}, {sorcerer}, {paladin} or {druid}. \z + Each vocation has its unique special abilities with which to fight evil. ...", + "You need to choose your vocation before you can leave {Dawnport} to go to the {Mainland}. \z + But first, you have to gain enough experience to reach level 8 in order to do so. ...", + "Once you've reached level 8 and want to choose your definite vocation, \z + talk to {Oressa} downstairs in the temple. She can also heal you if you are hurt or poisoned. ...", + "If you have any other questions, tell me." + }, + cid, false, true, 10) + elseif msgcontains(msg, "help") then + npcHandler:say( + { + "I can give you directions how to {play}, some basic survival and {combat} tips, or explain {PvP}, ...", + "I can also tell you how to talk with other {players} or {NPC}s, \z + or can inform you about {questing} or {spells}. ...", + "I also have a list of small {hints} if you prefer that, and can tell you something of the {people} here. \z + Just tell me what you want to know. ...", + "Oh, but first that help I mentioned - you should get yourself a {shovel}, friend. \z + It will come in handy when you set about finding secret entrances to dungeons or hidden treasures - \z + many useful things lie hidden beneath earth, sand or stones! " + }, + cid, false, true, 10) + elseif msgcontains(msg, "offensive") then + npcHandler:say( + { + "Offensive {fighting} means you deal harder attacks, but have a weaker defense. \z + Magical damage you deal is not affected by this. ...", + "You should switch to offensive only if you want to finish off a monster quickly \z + and are sure you can survive its harder attacks. \z + I can also tell you something about {balanced} and {defensive} fighting." + }, + cid, false, true, 10) + elseif msgcontains(msg, "balanced") then + npcHandler:say( + { + "Balanced {fighting} balances out your attack strength as well as your defense strength. \z + Magical damage you deal is not affected by this. ...", + "I can also tell you something about {offensive} and {defensive} fighting." + }, + cid, false, true, 10) + elseif msgcontains(msg, "defensive") then + npcHandler:say( + { + "Defensive {fighting} increases your defense but reduces your attack strength. \z + The magical damage you deal is not affected by this. ...", + "I can also tell you something about {offensive} and {balanced} fighting." + }, + cid, false, true, 10) + elseif msgcontains(msg, "skull") then + npcHandler:say( + { + "A white skull means that this player attacked and maybe killed another player without justification. ...", + "A red skull means someone has killed many other {players}, while a black skull depicts \z + someone on a serious killing spree - so watch out!" + }, + cid, false, true, 10) + elseif msgcontains(msg, "hamish") then + npcHandler:say( + { + "Some sort of misguided genius, I think. Brilliant with potions and runes, \z + but couldn't get on with his master or with the other students. \z + Ran away and set up his own little lab, selling to travellers along the road. ...", + "Was robbed and left for dead by some plunderers, when Morris found him. \z + {Morris} patched him up and said he could use him, so Hamish came here. \z + If you need a wand, rune or potion, Hamish's your man." + }, + cid, false, true, 10) + elseif msgcontains(msg, "coltrayne") then + npcHandler:say( + { + "Coltrayne doesn't say much about himself. What I gathered from the 15 years \z + I've known him is that he was raised by a blacksmith as a foundling. ...", + "When a fire destroyed his foster family's home, he took up an unsteady life, always wandering around. \z + Then he met {Morris} and decided to go adventuring with him." + }, + cid, false, true, 10) + elseif msgcontains(msg, "morris") then + npcHandler:say( + { + "Ah, there are lots of stories about Morris. Likes to insist on the 'Mr'. Nobody knows his first name, \z + and the telling goes that he has gambled with a demon and lost his first name to him. ...", + "The demon is said to have set Morris free so he can reclaim him at the end of his life, \z + meanwhile having fun watching Morris struggle through hardship and adventures. ...", + "Anyway. One way or another, Morris picked us all up and gathered us here. \z + Not sure that sending others on missions is really all it's about for him, \z + but if you're looking for a quest, go ask Morris for one." + }, + cid, false, true, 10) + elseif msgcontains(msg, "skills") then + npcHandler:say( + { + "Not your level, but your skill with your weapon determines how much damage you make. \z + With a distance weapon like a bow, you {train} your distance {fighting} skill, \z + with a sword your sword fighting, etc. ...", + "Druids and sorcerers train their magic level by using their mana through {spells} and runes. \z + Their wand or rod damage is not affected by their magic level. If you have any other questions, tell me." + }, + cid, false, true, 10) + elseif msgcontains(msg, "rope") then + npcHandler:say( + { + "You should never leave without a rope. NEVER. A rope can save your life. \z + I once fell down into a poison spider lair - without a rope, I wouldn't be standing here today! ...", + "You can buy a rope over at {Richard}'s shop. \z + If you don't have the money, kill and loot a few {monsters} - maybe one of them \z + even has a rope with it, that sort of thing happens." + }, + cid, false, true, 10) + elseif msgcontains(msg, "oressa") then + npcHandler:say( + { + "Our local healer. Don't know why that druid girl decided she wanted the unsteady life of an \z + adventurer, but she's quite hardy, to tell the truth. I once saw her confront a polar bear.... \z + but I'm getting carried away. ...", + "If you need healing, go see her. Oressa can also help you decide if you want to \z + choose your vocation to leave for the {Mainland}." + }, + cid, false, true, 10) + elseif msgcontains(msg, "temple") then + npcHandler:say( + { + "When you die, you will be resurrected in the temple of the city you chose as your home. \z + Temple {NPC}s, like {Oressa} here on {Dawnport}, can heal you if you're wounded or poisoned. \z + Some special temple NPCs can also {bless} you. ...", + "To be fully blessed, you should start the Pilgrimage of Ashes at a local guide in the \z + harbour once you have reached the {mainland}." + }, + cid, false, true, 10) + elseif msgcontains(msg, "dying") then + npcHandler:say( + { + "Don't be deceived by its sweet looks - {Tibia} is a rough world. \z + If you die, you will lose skill and experience and perhaps even some items, \z + and other {players} can rob your corpse. ...", + "On the {Mainland}, you can buy blessings from {temple} {NPC}s to prevent item loss, \z + but you will always lose some {skills} and experience, so be careful. ...", + "Always have a {rope} with you, for a start. A rope is essential." + }, + cid, false, true, 10) + elseif msgcontains(msg, "druid spells") then + npcHandler:say( + { + "Every vocation has specific {spells} that can only be used if you have that vocation. \z + Sorcerers and druids of course rely heavily on spells, \z + while knights only have a few at their disposal. ...", + "As an adventurer in training, you have a few spells at your disposal at the beginning, \z + but more will become available as you progress. ...", + "Once you're level 8, new spells become available upstairs at the spell trainers {Garamond} and {Tybald}. \z + They can tell you more." + }, + cid, false, true, 10) + elseif msgcontains(msg, "train") then + npcHandler:say( + { + "Go through one of the open gates on this floor and you will be equipped with \z + training weapons and {spells} of a specific vocation. ...", + "There are four {vocations} in Tibia: {knight}, {sorcerer}, {paladin} or {druid}. \z + Each one has its unique abilities, strengths and weaknesses. \z + Just try them out to see which one suits you best. ...", + "We need your help in our battle. \z + Fight {monsters} to gain experience and better {skills}, until you reach level 8 at least. \z + Make sure you always have not only a weapon, but a {rope} with you, as well! ...", + "Once you reached level 8 or more, you have to choose one vocation as your definite \z + vocation before you can leave for the Tibian {mainland}, where more dangers await you. ...", + "To choose your definite vocation, talk to {Oressa} downstairs in the {temple}. \z + She can also heal you if you are severely wounded or poisoned - just say 'heal' or 'help' to her. ...", + "If you have any other questions, tell me." + }, + cid, false, true, 10) + elseif msgcontains(msg, "bless") then + npcHandler:say( + { + "The blessings of the gods will protect you from item loss and alleviate the skill \z + and experience loss when you die. \z + But you will have to undertake the Pilgrimage of Ashes on the {mainland} to get the blessings. ...", + "If you die in a fight from a monster's attack, your blessings will be lost, \z + and you will have to get them again. ...", + "There is also a blessing that will protect you specifically from losses in a {PvP} fight. \z + This blessing you will need to get again when you have been killed in a PvP fight. ...", + "Here on {Dawnport}, you are protected from losses in a PvP fight by the Adventurer's Blessing - \z + unless you attack another player. If you attack another player or reach level 20, you will lose this blessing." + }, + cid, false, true, 10) + elseif msgcontains(msg, "hints") then + for i = 0,35,1 do + if i <= 35 then + npcHandler:say({hints[i]}) + elseif i == 35 then + i = 0 + end + end + + elseif msgcontains(msg, "rookgaard") and player:getLevel() <= 9 then + if Player.getAccountStorage(player, accountId, Storage.Dawnport.Mainland, true) == 1 then + npcHandler:say("Hmmm. Long time I visited that isle. Not very exciting place. \z + Why do you ask? Do you wish to go there?", cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say( + "I'm sorry, but I cannot let you go there, you'll get much better training here than on that ancient isle.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 1 then + npcHandler:say({ + "Careful, careful, it's a one-way ticket only! \z + You can never come back here if you leave now, and you will loso all your Dawnport equipment and products! ...", + "Are you {SURE} you want to {LEAVE} Dawnport for ROOKGAARD?" + }, cid, false, true, 10) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 and msgcontains(msg, "yes") + or msgcontains(msg, "sure") or msgcontains(msg, "leave") then + local town = Town(TOWNS_LIST.ROOKGAARD) + player:setTown(town) + -- Change to none vocation, convert magic level and skills and set proper stats + player:changeVocation(VOCATION.ID.NONE) + player:teleportTo(town:getTemplePosition()) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + + local slots = { + 1, 2, 4, 5, 6, 7, 8, 9, 10 + } + -- Cycle through the slots table and store the slot id in slot + for index, value in pairs(slots) do + -- Get the player's slot item and store it in item + local item = player:getSlotItem(value) + -- If the item exists meaning its not nil then continue + if item and not table.contains({1987, 1988, 2050, 2461, 2651, 2649}, item:getId()) then + item:remove() + end + end + local container = player:getSlotItem(CONST_SLOT_BACKPACK) + local toBeDeleted = {} + local allowedIds = { + 1987, 2050, 2120, 2148 + } + if container and container:getSize() > 0 then + for i = 0, container:getSize() do + if player:getMoney() > 1500 then + player:removeMoney(math.abs(1500 - player:getMoney())) + end + local item = container:getItem(i) + if item then + if not table.contains(allowedIds, item:getId()) then + toBeDeleted[#toBeDeleted + 1] = item.uid + end + end + end + if #toBeDeleted > 0 then + for i, v in pairs(toBeDeleted) do + local item = Item(v) + if item then + item:remove() + end + end + end + end + player:addItem(2382, 1) + player:addItem(1987, 1) + player:addItem(2050, 1) + player:addItem(2674, 1) + player:addItem(2650, 1) + npcHandler:say("Then so be it. I'm sorry to see you go, but if this is what you want, step this way... right. \z + Now, cover your eyes... GO!", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/inkaef.lua b/data/npc/scripts/inkaef.lua new file mode 100644 index 00000000000..527e84a4e49 --- /dev/null +++ b/data/npc/scripts/inkaef.lua @@ -0,0 +1,57 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local items = { + [VOCATION.CLIENT_ID.SORCERER] = 2190, + [VOCATION.CLIENT_ID.DRUID] = 2182 +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'first rod') or msgcontains(msg, 'first wand') then + if player:isMage() then + local itemId = items[player:getVocation():getClientId()] + if player:getStorageValue(Storage.firstMageWeapon) == -1 then + npcHandler:say('So you ask me for a {' .. ItemType(itemId):getName() .. '} to begin your adventure?', cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say('What? I have already gave you one {' .. ItemType(itemId):getName() .. '}!', cid) + end + else + npcHandler:say('Sorry, you aren\'t a druid either a sorcerer.', cid) + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + player:addItem(itemId, 1) + npcHandler:say('Here you are young adept, take care yourself.', cid) + player:setStorageValue(Storage.firstMageWeapon, 1) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] == 1 then + npcHandler:say('Ok then.', cid) + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/iptar-sin.lua b/data/npc/scripts/iptar-sin.lua new file mode 100644 index 00000000000..c7ae04a91a6 --- /dev/null +++ b/data/npc/scripts/iptar-sin.lua @@ -0,0 +1,118 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Wooden Stake Quest +local stakeKeyword = keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'A blessed stake to defeat evil spirits? I do know an old prayer which is said to grant sacred power and to be able to bind this power to someone, or something. ...', + 'However, this prayer needs the combined energy of ten priests. Each of them has to say one line of the prayer. ...', + 'I could start with the prayer, but since the next priest has to be in a different location, you probably will have to travel a lot. ...', + 'Is this stake really important enough to you so that you are willing to take this burden?', + }}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == -1 end + ) + stakeKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Alright, I guess you need a stake first. Maybe Gamon can help you, the leg of a chair or something could just do. Try asking him for a stake, and if you have one, bring it back to me.', reset = true, ungreet = true}, nil, function(player) player:setStorageValue(Storage.FriendsandTraders.DefaultStart, 1) player:setStorageValue(Storage.FriendsandTraders.TheBlessedStake, 1) end) + +-- First prayer +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'I guess you couldn\'t convince Gamon to give you a stake, eh?'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 1 and player:getItemCount(5941) == 0 end) + +local stakeKeyword = keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes, I was informed what to do. Are you prepared to receive my line of the prayer?'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 1 end) + stakeKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'So receive my prayer: \'Light shall be near - and darkness afar\'. Now, bring your stake to Tibra in the Carlin church for the next line of the prayer. I will inform her what to do.', reset = true}, nil, + function(player) player:setStorageValue(Storage.FriendsandTraders.TheBlessedStake, 2) player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) end + ) + stakeKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'I will wait for you.', reset = true}) + +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You should visit Tibra in the Carlin church now.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 2 end) +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You already received my line of the prayer.'}) + +-- Twist of Fate +local blessKeyword = keywordHandler:addKeyword({'twist of fate'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'This is a special blessing I can bestow upon you once you have obtained at least one of the other blessings and which functions a bit differently. ...', + 'It only works when you\'re killed by other adventurers, which means that at least half of the damage leading to your death was caused by others, not by monsters or the environment. ...', + 'The {twist of fate} will not reduce the death penalty like the other blessings, but instead prevent you from losing your other blessings as well as the amulet of loss, should you wear one. It costs the same as the other blessings. ...', + 'Would you like to receive that protection for a sacrifice of |PVPBLESSCOST| gold, child?' + }}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the protection of the twist of fate, pilgrim.', cost = '|PVPBLESSCOST|', bless = 1}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Adventurer Stone +keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Keep your adventurer\'s stone well.'}, function(player) return player:getItemById(18559, true) end) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for free?'}, function(player) return player:getStorageValue(Storage.AdventurersGuild.FreeStone.Quentin) ~= 1 end) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, nil, function(player) player:addItem(18559, 1) player:setStorageValue(Storage.AdventurersGuild.FreeStone.Quentin, 1) end) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for 30 gold?'}) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, + function(player) return player:getMoney() + player:getBankBalance() >= 30 end, + function(player) if player:removeMoneyNpc(30) then player:addItem(18559, 1) end end + ) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, you don\'t have enough money.', reset = true}) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.'}, function(player) return player:hasBlessing(2) end) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin will provide you with the embrace of Tibia.'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, young |PLAYERNAME|! If you are heavily wounded or poisoned, I can {heal} you for free or you want the {adventurer stone}?') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Remember: If you are heavily wounded or poisoned, I can heal you for free.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'May the gods bless you, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/irea.lua b/data/npc/scripts/irea.lua new file mode 100644 index 00000000000..14df28d7d63 --- /dev/null +++ b/data/npc/scripts/irea.lua @@ -0,0 +1,25 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +-- Greeting message +keywordHandler:addGreetKeyword({"ashari"}, {npcHandler = npcHandler, text = "Greetings, |PLAYERNAME|."}) +--Farewell message +keywordHandler:addFarewellKeyword({"asgha thrazi"}, {npcHandler = npcHandler, text = "Goodbye, |PLAYERNAME|."}) + +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye!") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/iriana.lua b/data/npc/scripts/iriana.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/iriana.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/irmana.lua b/data/npc/scripts/irmana.lua new file mode 100644 index 00000000000..66819b4cde5 --- /dev/null +++ b/data/npc/scripts/irmana.lua @@ -0,0 +1,137 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function creatureSayCallback(cid, type, msg) + if(not npcHandler:isFocused(cid)) then + return false + end + + local player = Player(cid) + if (msgcontains(msg, "fur")) then + if (player:getStorageValue(Storage.ThreatenedDreams.TroubledMission01) == 8) then + npcHandler:say({ + "A wolf whelp fur? Well, some months ago a hunter came here - a rather scruffy, smelly guy. I would have thrown him out instantly, but he had to offer some fine pelts. One of them was the fur of a very young wolf. ...", + "I was not delighted that he obviously killed such a young animal. When I confronted him, he said he wanted to raise it as a companion but it unfortunately died. A sad story. In the end, I bought some of his pelts, among them the whelp fur. ...", + "You can have it if this is important for you. I would sell it for 1000 gold. Are you interested?" + }, cid) + npcHandler.topic[cid] = 8 + else + npcHandler:say("You are not on that mission.", cid) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "addon")) then + if(getPlayerStorageValue(cid, Storage.Irmana1) < 1) then + npcHandler:say("Currently we are offering accessories for the nobleman - and, of course, noblewoman - outfit. Would you like to hear more about our offer?", cid) + npcHandler.topic[cid] = 1 + elseif getPlayerStorageValue(cid, Storage.Irmana2) < 1 then + npcHandler:say("Currently we are offering accessories for the nobleman - and, of course, noblewoman - outfit. Would you like to hear more about our offer?", cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say("You have already bought the two addons.", cid) + end + elseif(msgcontains(msg, "yes")) then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Especially for you, mylady, we are offering a pretty {hat} and a beautiful {dress} like the ones I wear. Which one are you interested in?", cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 3 then + if(doPlayerRemoveMoney(cid, 150000) and getPlayerStorageValue(cid, Storage.Irmana1) < 1) then + npcHandler:say("Congratulations! Here is your brand-new accessory, I hope you like it. Please visit us again! ", cid) + npcHandler.topic[cid] = 0 + player:addOutfitAddon(140, 2) + player:addOutfitAddon(132, 2) + setPlayerStorageValue(cid, Storage.Irmana1, 1) + if player:getStorageValue(Storage.Irmana1) == 1 and player:getStorageValue(Storage.Irmana2) == 1 then + player:addAchievement(226) -- Achievement Aristocrat + end + end + elseif npcHandler.topic[cid] == 4 then + if(doPlayerRemoveMoney(cid, 150000) and getPlayerStorageValue(cid, Storage.Irmana2) < 1) then + npcHandler:say("Congratulations! Here is your brand-new accessory, I hope you like it. Please visit us again! ", cid) + npcHandler.topic[cid] = 0 + player:addOutfitAddon(140, 1) + player:addOutfitAddon(132, 1) + setPlayerStorageValue(cid, Storage.Irmana2, 1) + if player:getStorageValue(Storage.Irmana1) == 1 and player:getStorageValue(Storage.Irmana2) == 1 then + player:addAchievement(226) -- Achievement Aristocrat + end + end + elseif npcHandler.topic[cid] == 5 then + if getPlayerItemCount(cid,2655) >= 1 then + doPlayerRemoveItem(cid,2655,1) + npcHandler:say("A {Red Robe}! Great. Here, take this red piece of cloth, I don\'t need it anyway.", cid) + doPlayerAddItem(cid,5911,1) + npcHandler.topic[cid] = 0 + else + npcHandler:say('Are you trying to mess with me?!', cid) + end + elseif npcHandler.topic[cid] == 6 then + if getPlayerItemCount(cid,2663) >= 1 then + doPlayerRemoveItem(cid,2663,1) + npcHandler:say("A {Mystic Turban}! Great. Here, take this blue piece of cloth, I don\'t need it anyway.", cid) + doPlayerAddItem(cid,5912,1) + npcHandler.topic[cid] = 0 + else + npcHandler:say('Are you trying to mess with me?!', cid) + end + elseif npcHandler.topic[cid] == 7 then + if getPlayerItemCount(cid,2652) >= 150 then + doPlayerRemoveItem(cid,2652,150) + npcHandler:say("A 150 {Green Tunic}! Great. Here, take this green piece of cloth, I don\'t need it anyway.", cid) + doPlayerAddItem(cid,5910,1) + npcHandler.topic[cid] = 0 + else + npcHandler:say('Are you trying to mess with me?!', cid) + end + elseif npcHandler.topic[cid] == 8 then + if player:getMoney() >= 1000 then + player:removeMoney(1000) + player:addItem(28599, 1) -- Fur of a Wolf Whelp + npcHandler:say("Alright. Here is the fur.", cid) + player:setStorageValue(Storage.ThreatenedDreams.TroubledMission01, 9) + npcHandler.topic[cid] = 0 + else + npcHandler:say('Are you trying to mess with me?!', cid) + end + end + elseif(msgcontains(msg, "hat") or msgcontains(msg, "accessory")) and (npcHandler.topic[cid] == 2 and getPlayerStorageValue(cid, Storage.Irmana1) < 1) then + selfSay("This accessory requires a small fee of 150000 gold pieces. Of course, we do not want to put you at any risk to be attacked while carrying this huge amount of money. ...", cid) + selfSay("This is why we have established our brand-new instalment sale. You can choose to either pay the price at once, or if you want to be safe, by instalments of 10000 gold pieces. ...", cid) + selfSay("I also have to inform you that once you started paying for one of the accessories, you have to finish the payment first before you can start paying for the other one, of course. ...", cid) + npcHandler:say("Are you interested in purchasing this accessory?", cid) + npcHandler.topic[cid] = 3 + elseif(msgcontains(msg, "dress") or msgcontains(msg, "coat")) and (npcHandler.topic[cid] == 2 and getPlayerStorageValue(cid, Storage.Irmana2) < 1) then + selfSay("This accessory requires a small fee of 150000 gold pieces. Of course, we do not want to put you at any risk to be attacked while carrying this huge amount of money. ...", cid) + selfSay("This is why we have established our brand-new instalment sale. You can choose to either pay the price at once, or if you want to be safe, by instalments of 10000 gold pieces. ...", cid) + selfSay("I also have to inform you that once you started paying for one of the accessories, you have to finish the payment first before you can start paying for the other one, of course. ...", cid) + npcHandler:say("Are you interested in purchasing this accessory?", cid) + npcHandler.topic[cid] = 4 + elseif(msgcontains(msg, "red robe")) then + npcHandler:say("Have you found a {Red Robe} for me?", cid) + npcHandler.topic[cid] = 5 + elseif(msgcontains(msg, "mystic turban")) then + npcHandler:say("Have you found a {Mystic Turban} for me?", cid) + npcHandler.topic[cid] = 6 + elseif(msgcontains(msg, "green tunic")) then + npcHandler:say("Have you found {150 Green Tunic} for me?", cid) + npcHandler.topic[cid] = 7 + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/irvin.lua b/data/npc/scripts/irvin.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/irvin.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ishebad.lua b/data/npc/scripts/ishebad.lua new file mode 100644 index 00000000000..d0487a1b5ae --- /dev/null +++ b/data/npc/scripts/ishebad.lua @@ -0,0 +1,27 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Promotion +local promoteKeyword = keywordHandler:addKeyword({'promot'}, StdModule.say, {npcHandler = npcHandler, text = 'Do you want to be promoted in your vocation for 20000 gold?'}) + promoteKeyword:addChildKeyword({'yes'}, StdModule.promotePlayer, {npcHandler = npcHandler, level = 20, cost = 20000}) + promoteKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Ok, whatever.', reset = true}) + +npcHandler:setMessage(MESSAGE_GREET, 'Be mourned, pilgrim in flesh. Are you looking for a promotion?') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye, |PLAYERNAME|!') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ishina.lua b/data/npc/scripts/ishina.lua new file mode 100644 index 00000000000..c98d28ffe5e --- /dev/null +++ b/data/npc/scripts/ishina.lua @@ -0,0 +1,88 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, 'outfit') then + if player:getSex() == PLAYERSEX_MALE then + npcHandler:say('My jewelled belt? That\'s not very manly. Maybe you\'d prefer a scimitar like Habdel has.', cid) + return true + end + + if player:getStorageValue(Storage.OutfitQuest.firstOrientalAddon) < 1 then + npcHandler:say('My jewelled belt? Of course I could make one for you, but I have a small request. Would you fulfil a task for me?', cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, 'comb') then + if player:getSex() == PLAYERSEX_MALE then + npcHandler:say('Comb? This is a jewellery shop.', cid) + return true + end + + if player:getStorageValue(Storage.OutfitQuest.firstOrientalAddon) == 1 then + npcHandler:say('Have you brought me a mermaid\'s comb?', cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + 'Listen, um... I have been wanting a comb for a long time... not just any comb, but a mermaid\'s comb. Having a mermaid\'s comb means never having split ends again! ...', + 'You know what that means to a girl! Could you please bring me such a comb? I really would appreciate it.' + }, cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + player:setStorageValue(Storage.OutfitQuest.DefaultStart, 1) + player:setStorageValue(Storage.OutfitQuest.firstOrientalAddon, 1) + npcHandler:say('Yay! I will wait for you to return with a mermaid\'s comb then.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + if not player:removeItem(5945, 1) then + npcHandler:say('No... that\'s not it.', cid) + npcHandler.topic[cid] = 0 + return true + end + + player:setStorageValue(Storage.OutfitQuest.firstOrientalAddon, 2) + player:addOutfitAddon(150, 1) + player:addOutfitAddon(146, 1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + npcHandler:say('Yeah! That\'s it! I can\'t wait to comb my hair! Oh - but first, I\'ll fulfil my promise: Here is your jewelled belt! Thanks again!', cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] ~= 0 then + npcHandler:say('Oh... okay.', cid) + npcHandler.topic[cid] = 0 + end + + return true +end + +keywordHandler:addKeyword({'need'}, StdModule.say, {npcHandler = npcHandler, text = 'I am a jeweller. Maybe you want to have a look at my wonderful {offers}.'}) +keywordHandler:addKeyword({'offers'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, I sell gems and {goblets}. If you\'d like to see my offers, ask me for a {trade}.'}) +keywordHandler:addKeyword({'goblets'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, our newest import! We have golden goblets, silver goblets and bronze goblets. All of them have space for a hand-written dedication.'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Be greeted, |PLAYERNAME|. Which of my fine gems do you {need}?') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Daraman\'s blessings and good bye.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Daraman\'s blessings and good bye.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/isimov.lua b/data/npc/scripts/isimov.lua new file mode 100644 index 00000000000..eb687b6d528 --- /dev/null +++ b/data/npc/scripts/isimov.lua @@ -0,0 +1,109 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Twist of Fate +local blessKeyword = keywordHandler:addKeyword({'twist of fate'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'This is a special blessing I can bestow upon you once you have obtained at least one of the other blessings and which functions a bit differently. ...', + 'It only works when you\'re killed by other adventurers, which means that at least half of the damage leading to your death was caused by others, not by monsters or the environment. ...', + 'The {twist of fate} will not reduce the death penalty like the other blessings, but instead prevent you from losing your other blessings as well as the amulet of loss, should you wear one. It costs the same as the other blessings. ...', + 'Would you like to receive that protection for a sacrifice of |PVPBLESSCOST| gold, child?' + } + }) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the protection of the twist of fate, pilgrim.', cost = '|PVPBLESSCOST|', bless = 6}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Adventurer Stone +keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Keep your adventurer\'s stone well.'}, function(player) return player:getItemById(18559, true) end) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for free?'}, function(player) return player:getStorageValue(Storage.AdventurersGuild.FreeStone.Isimov) ~= 1 end) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, nil, function(player) player:addItem(18559, 1) player:setStorageValue(Storage.AdventurersGuild.FreeStone.Isimov, 1) end) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for 30 gold?'}) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, + function(player) return player:getMoney() + player:getBankBalance() >= 30 end, + function(player) if player:removeMoneyNpc(30) then player:addItem(18559, 1) end end + ) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, you don\'t have enough money.', reset = true}) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +-- Wooden Stake +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'I think you have forgotten to bring your stake, kid.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 5 and player:getItemCount(5941) == 0 end) + +local stakeKeyword = keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes, I was informed what to do. Are you prepared to receive my line of the prayer?'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 5 end) + stakeKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'So receive my prayer: \'Unclean spirits shall be repelled\'. Now, bring your stake to Amanda in Edron for the next line of the prayer. I will inform her what to do.', reset = true}, nil, + function(player) player:setStorageValue(Storage.FriendsandTraders.TheBlessedStake, 6) player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) end + ) + stakeKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'I will wait for you.', reset = true}) + +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You should visit Amanda in Edron now, kid.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 6 end) +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You already received my line of the prayer.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) > 6 end) +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'A blessed stake? That\'s a strange request. Maybe Quentin knows more, he is one of the oldest monks after all.'}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.'}, function(player) return player:hasBlessing(2) end) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin will provide you with the embrace of Tibia.'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, young |PLAYERNAME|! If you are heavily wounded or poisoned, I can {heal} you for free.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Remember: If you are heavily wounded or poisoned, I can heal you for free.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'May the gods bless you, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/iskan.lua b/data/npc/scripts/iskan.lua new file mode 100644 index 00000000000..64753df416e --- /dev/null +++ b/data/npc/scripts/iskan.lua @@ -0,0 +1,73 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "do for you") then + npcHandler:say("I run the dog sled service from this city to {Nibelor}.", cid) + elseif msgcontains(msg, "Nibelor") or msgcontains(msg, "passage") then + npcHandler:say("Do you want to Nibelor?", cid) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, "mission") then + if player:getStorageValue(Storage.BarbarianTest.Questline) >= 8 then -- if Barbarian Test absolved + if player:getStorageValue(Storage.TheIceIslands.Questline) < 1 then + npcHandler:say({ + "Well, one of the boys has run away. I think he got the scent of some beast. He's young and inexperienced so I can't blame the cub ...", + "I would like you to see after him. He should be somewhere north west of the town. He is probably marking his territory so you should be able to find his trace. Are you willing to do that?" + }, cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 2 then + npcHandler:say("You are a friend of mine and the boys now. I tell you something. If you ever need to go to the isle of Nibelor, just ask me for a {passage}.", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 3) + player:setStorageValue(Storage.TheIceIslands.Mission01, 3) -- Questlog The Ice Islands Quest, Befriending the Musher + npcHandler.topic[cid] = 0 + else + npcHandler:say("I have now no mission for you.", cid) + npcHandler.topic[cid] = 0 + end + else + npcHandler:say("Sorry but I only give missions to those who are considered a true Barbarian. ", cid) + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "That's surprising. Take a piece of meat. If you find the boy, feed it to him. That will give him enough strength and incentive to return to his pack ...", + "Talk to him by calling his name 'Sniffler' and tell him you got meat for him. After he has eaten the meat, return here to talk to me about your mission." + }, cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 1) + player:setStorageValue(Storage.TheIceIslands.Mission01, 1) -- Questlog The Ice Islands Quest, Befriending the Musher + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + --if player:getStorageValue(Storage.TheIceIslands.Questline) >= 3 then + player:teleportTo(Position(32325, 31049, 7)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + --else + --npcHandler:say("Sorry, first time you have to do a mission for me.", cid) + --npcHandler.topic[cid] = 0 + --end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/isolde.lua b/data/npc/scripts/isolde.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/isolde.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ivalisse.lua b/data/npc/scripts/ivalisse.lua new file mode 100644 index 00000000000..ee2b98e5e84 --- /dev/null +++ b/data/npc/scripts/ivalisse.lua @@ -0,0 +1,107 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Don't forget npcHandler = npcHandler in the parameters. It is required for all StdModule functions! +keywordHandler:addKeyword({'silus'}, StdModule.say, {npcHandler = npcHandler, text = "My {father}, can you tell me if he's alright?"}) +keywordHandler:addKeyword({'thais'}, StdModule.say, {npcHandler = npcHandler, text = "Alright then, you are very welcome to explore the temple!"}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "My name is Ivalisse."}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = "There is always time to make a change."}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "Besides my various {duties} in the temple, I also take care of visitors. Well, I would but right now I can't get my mind of how my {father}'s doing. I am sorry."}) +keywordHandler:addKeyword({'duties'}, StdModule.say, {npcHandler = npcHandler, text = " I help linking the portals of this temple to other ancient sites of the {Astral Shapers}."}) +keywordHandler:addKeyword({'duties'}, StdModule.say, {npcHandler = npcHandler, text = " I help linking the portals of this temple to other ancient sites of the {Astral Shapers}."}) +keywordHandler:addKeyword({'mission'}, StdModule.say, {npcHandler = npcHandler, text = "Besides my various {duties} in the temple, I also take care of visitors. Well, I would but right now I can't get my mind of how my {father}'s doing. I am sorry."}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "temple") then + npcHandler:say({ + "Well, I hope you like it here. We tried to rebuild in the {Shaper}'s will. I am a bit preoccupied at the moment because of the absence of my {father}. I may not be the best of help currently, sorry." + }, cid) + npcHandler.topic[cid] = 1 + end + + if msgcontains(msg, "imbuing") or msgcontains(msg, "imbuements") then + npcHandler:say({ + "The astral Shapers had many ways to shape and refine weapons and equipment. They built shrines dedicated to this world's energies, focussing it and utilising it like a tool to enhance objects. ...", + "They called this process imbuing and perfected it throughout time. Remains of these shrines are scattered all over Tibia. ...", + "If you truly want to master this art, you will need to visit the various ancient sites related to the original Shaper imbuements. There is one for each element and we know of at least one other besides these. ...", + "The discovery of the foundations of this very temple we are standing in, was the key to access their legacy. It is now the center of all our efforts in getting closer to the astral predecessors. ...", + "They found ways to connect various sites with a system of gates, all concentrating energy to allow travel to far away places. The more we learn, the more we can restore of these ancient gateways. ...", + "We see the gates as an invitation, use them to your advantage and follow the ways of the Shapers. Access to one of these ancient shrines is the only way to learn additional imbuements. ...", + "But beware, as far as we know, some of them have been claimed by other ancient beings and there is now way for us to prepare you what lies beyond any of those gates." + }, cid) + end + + if msgcontains(msg, "father") and npcHandler.topic[cid] == 1 then + npcHandler:say({ + "Papa- my father has recently started an adventure on his own. His name is Silus, he is a member of the Edron academy. ...", + "Ever since he has joined what he called a 'special research division', he went on and on about Zao and how venturing there would help him get ahead. ...", + "You must know he lives for science, especially concerning far-away lands and cultures. He talked about the importance of practical field studies but, frankly, he isn't particularly cut out for that. ...", + "I know he has to focus to get his research done right now and I simply cannot leave my duties in the temple. You seem like a person who travels a lot, would you be willing to help me?", + }, cid) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, "father") and npcHandler.topic[cid] == 1 and player:getStorageValue(Storage.ForgottenKnowledge.Ivalisse) == 1 or player:getStorageValue(Storage.ForgottenKnowledge.Chalice) == 1 then + npcHandler:say({ + "Well, I hope you like it here. We tried to rebuild in the Shaper's will. I am a bit preoccupied at the moment because of the absence of my father. I may not be the best of help currently, sorry.", + }, cid) + elseif msgcontains(msg, "father") and npcHandler.topic[cid] == 1 and player:getStorageValue(Storage.ForgottenKnowledge.DragonkingKilled) == 1 then + npcHandler:say({ + "What? You're telling me you found father? How is he, what did papa say? A chalice? As a disguise? The whole time? ...", + "Well, I am not as much surprised as I am happy to hear that he's alright. You know, after the incident with the duck and the umbrella - it doesn't get to me that easily anymore. ...", + "Thank you very much for doing all this for me, I will be forever grateful. I have nothing to repay you with but you are already blessed to have been able to lay eyes on the sacred shaper ruins." + }, cid) + player:setStorageValue(Storage.ForgottenKnowledge.Ivalisse, 1) + end + + if msgcontains(msg, "yes") and npcHandler.topic[cid] == 2 then + npcHandler:say({ + "Thank you! He told me the other researchers in his team discovered a bridge leading to a cave with a dragon sculpture somewhere in a muggy, grassy area. ...", + "The cave is said to lead to a temple complex underground which is ued as a gathering place for a race called 'draken'. He left right away and tried to enter Zao on his own. ...", + "I was even more worried when he explained the route he chose. he wanted to head straight through a giant steppe and through a massive mountainous ridge to reach the grassy plains of lower Zao. ...", + "If you're interested: I know that the Shapers where active in all corners of Tibia. If you happen to find Shaper ruins there, you may even be able to gather some of their lost knowledge. ...", + "I may have been a bit stubborn and angry the day he left, I even refused to say farewell. And now I worry if he is safe. ...", + "I can not do much to help you but I can open a portal to get you quite close to his last known location in Zao. What do you say, will you help me find my father?", + }, cid) + npcHandler.topic[cid] = 3 + elseif msgcontains(msg, "no") and npcHandler.topic[cid] == 2 then + npcHandler:say({ + "Oh nevermind, I am sorry I asked you for this.", + }, cid) + end + + if msgcontains(msg, "yes") and npcHandler.topic[cid] == 3 then + npcHandler:say({ + "You would? That's great! Thank you! If you can find my father, tell him I understand and that I really miss him!", + }, cid) + player:setStorageValue(Storage.ForgottenKnowledge.AccessFire, 1) + player:setStorageValue(Storage.ForgottenKnowledge.Chalice, 1) + elseif msgcontains(msg, "no") and npcHandler.topic[cid] == 3 then + npcHandler:say({ + "Oh nevermind, I am sorry I asked you for this.", + }, cid) + end + return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, "Oh... farewell, child.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/iwan.lua b/data/npc/scripts/iwan.lua new file mode 100644 index 00000000000..483d7aca0d7 --- /dev/null +++ b/data/npc/scripts/iwan.lua @@ -0,0 +1,25 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Gems of all kinds! Precious jewellery!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "Feel welcome to my gem store, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Bye, bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Bye, bye.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Here, take a look.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/iwar.lua b/data/npc/scripts/iwar.lua new file mode 100644 index 00000000000..019ae80bf57 --- /dev/null +++ b/data/npc/scripts/iwar.lua @@ -0,0 +1,68 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local playerTopic = {} +local function greetCallback(cid) + + local player = Player(cid) + npcHandler:addFocus(cid) + return true +end + + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + npcHandler.topic[cid] = playerTopic[cid] + local player = Player(cid) + local valorPicture = 10000 + + -- Começou a quest + if msgcontains(msg, "has the cat got your tongue?") and player:getStorageValue(Storage.CultsOfTibia.MotA.Mission) == 4 then + npcHandler:say({"Nice. You like your picture, haa? Give me 10,000 gold and I will deliver it to the museum. Do you {pay}?"}, cid) + npcHandler.topic[cid] = 2 + playerTopic[cid] = 2 + elseif msgcontains(msg, "pay") or msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 2 then + if (player:getMoney() + player:getBankBalance()) >= valorPicture then + npcHandler:say({"Well done. The picture will be delivered to the museum as last as possible."}, cid) + npcHandler.topic[cid] = 0 + playerTopic[cid] = 0 + player:removeMoneyNpc(valorPicture) + player:setStorageValue(Storage.CultsOfTibia.MotA.Mission, 5) + else + npcHandler:say({"You don't have enough money."}, cid) + npcHandler.topic[cid] = 1 + playerTopic[cid] = 1 + end + end + end + return true +end + + + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/iyad.lua b/data/npc/scripts/iyad.lua new file mode 100644 index 00000000000..9b87f389d73 --- /dev/null +++ b/data/npc/scripts/iyad.lua @@ -0,0 +1,48 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'A... aargh. I wish I had some e... earmuffs to put over this useless t... turban.' }, + { text = 'Oh p.. please. P... lease let me fly us out of this c... cold.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, text, cost, destination) + if keyword == 'farmine' then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Never heard about a place like this.'}, function(player) return player:getStorageValue(Storage.TheNewFrontier.Mission10) ~= 1 end) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a ride to ' .. text .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, text = 'Hold on!', cost = cost, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'You shouldn\'t miss the experience.', reset = true}) +end + +addTravelKeyword('farmine', 'Farmine', 60, Position(32983, 31539, 1)) +addTravelKeyword('darashia', 'Darashia on Darama', 40, Position(33270, 32441, 6)) +addTravelKeyword('kazordoon', 'Kazordoon', 60, Position(32588, 31941, 0)) +addTravelKeyword('femor hills', 'the Femor Hills', 40, Position(32536, 31837, 4)) +addTravelKeyword('edron', 'Edron', 60, Position(33193, 31784, 3)) +addTravelKeyword('hills', 'the Femor Hills', 40, Position(32536, 31837, 4)) +addTravelKeyword('issavi', 'Issavi', 100, Position(33957, 31515, 0)) + +npcHandler:setMessage(MESSAGE_GREET, "Greetings, traveller |PLAYERNAME|. Where do you want me to {fly} you?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye!") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/izsh.lua b/data/npc/scripts/izsh.lua new file mode 100644 index 00000000000..b1e8a1c3e5f --- /dev/null +++ b/data/npc/scripts/izsh.lua @@ -0,0 +1,50 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, 'mission') then + if Player(cid):getStorageValue(Storage.WrathoftheEmperor.Questline) == 33 then + npcHandler:say('Oh yez, let me zee ze documentz. Here we go: zree cheztz filled wiz platinum, one houze, a zet of elite armor, and an unending mana cazket. Iz ziz correct?', cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, 'yes') and npcHandler.topic[cid] == 1 then + npcHandler:say({ + 'Fine, zo let\'z prozeed. You uzed forged documentz to enter our zity, killed zeveral guardz who enjoyed a quite excluzive and expenzive training, deztroyed rare magical devizez in ze pozzezzion of ze emperor. ...', + 'Ze good newz iz, your zree cheztz of platinum should be nearly enough to pay ze finez. Lucky you, ziz could have left you broke. ...', + 'Zere are alzo zertain noble familiez complaining about ze murder of zeveral of zeir beloved onez. ...', + 'I zink I can make a deal wiz ze noblez by zelling zem your property in ze zity. Your prezenze would ruin ze houze prizez zere anyway. ...', + 'Of courze zat will not zuffize to compenzate zeir grief, zo I guezz you\'ll have to part wiz zat elite armor, too. Zadly, prizez for armor are on an all time low right now. ...', + 'But luckily you ztill have zat mana cazket. Well, you had it. Now we have to zell it. ...', + 'But not all iz lozt my blank-zkinned vizitor. According to my calculationz, zere iz ztill a bit left. ...', + 'I zink we can zave you zome gold and zome treazurez, and you can keep one pieze of your elite armor at leazt. ...', + 'You will find your rewardz in one of ze old zupply zellarz. Beware of ze ratz zough. ...', + 'Ze rednezz of your faze and ze zound you make wiz your teez iz obviouzly a zign of gratitude of your zpeziez! I am flattered, but pleaze leave now az I have to attend to zome important buzinezz.' + }, cid) + Player(cid):setStorageValue(Storage.WrathoftheEmperor.Questline, 34) + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, 'Greetingz zcalelezz being.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/jack.lua b/data/npc/scripts/jack.lua new file mode 100644 index 00000000000..55205dd95a6 --- /dev/null +++ b/data/npc/scripts/jack.lua @@ -0,0 +1,203 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + local player = Player(cid) + + if player:getStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine) == 7 then + npcHandler:setMessage( + MESSAGE_GREET, + "You!! What have you told my family? They are mad at me and I don't even know why! \z + They think I lied to them about working in Edron in secrecy! Why should I even do that!" + ) + elseif player:getStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine) == 8 then + npcHandler:setMessage( + MESSAGE_GREET, + { + "What did you do to my SCULPTURE? You simply DESTROYED it? Why? You... you ruined everything... \z + my house, my hobby, my life. My family even refuses to talk to me anymore. ...", + "Alright, alright you win. I am done for. You... you must be right, yes. Yes, I was working as an \z + intern... in the academy in Edron... yes... Just... tell this Spectulus guy I want to see him. \z + I have nothing left. I am ready." + } + ) + player:setStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine, 9) + elseif player:getStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine) == 10 then + npcHandler:setMessage( + MESSAGE_GREET, + "So, you've returned to Spectulus? What did he say, is anything wrong? You have this strange expression \z + on your face - is there anything wrong? You DID tell me the truth here, didn't you?" + ) + else + npcHandler:setMessage(MESSAGE_GREET, "Yes? What can I do for you? I hope this won't take long, though.") + end + + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "spectulus") then + if (player:getStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine) == 1) then + npcHandler:say("Gesundheit! Are you alright? Did you... want to tell me something by that?", cid) + npcHandler.topic[cid] = 1 + elseif (player:getStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine) == 3) then + if npcHandler.topic[cid] == 3 then + npcHandler:say( + { + "So it's that name again. You are really determined, aren't you. ...", + "So if he thinks I'm someone he knew who is now 'lost' and needs to come back or whatever - \z + tell him he is WRONG. I always lived here with my mother and sister, I'm happy here and I \z + certainly don't want to go to that academy of yours." + }, + cid + ) + player:setStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine, 4) + end + end + elseif msgcontains(msg, "furniture") then + if (player:getStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine) == 3) then + if + (player:getStorageValue(Storage.TibiaTales.JackFutureQuest.Furniture01) == 1) and + (player:getStorageValue(Storage.TibiaTales.JackFutureQuest.Furniture02) == 1) and + (player:getStorageValue(Storage.TibiaTales.JackFutureQuest.Furniture03) == 1) and + (player:getStorageValue(Storage.TibiaTales.JackFutureQuest.Furniture04) == 1) and + (player:getStorageValue(Storage.TibiaTales.JackFutureQuest.Furniture05) == 1) + then + npcHandler:say( + "What have you done? What are all these pieces of furniture doing here? Those are ugly at \z + best and - hey! Stop! Leave the wallpaper alone! Alright, alright! Just tell me, why are you \z + doing this? Who's behind all this?", + cid + ) + npcHandler.topic[cid] = 3 + end + end + elseif msgcontains(msg, "no") then + if player:getStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine) == 10 then + if (npcHandler.topic[cid] == 0) then + npcHandler:say("WHAT?? No way, I ask you again - you DID tell me the TRUTH here... right?", cid) + npcHandler.topic[cid] = 5 + elseif (npcHandler.topic[cid] == 5) then + npcHandler:say( + { + "So... so this wasn't EVEN REAL? You brought all this ugly furniture here, you destroyed \z + my sculpture... and on top of that you actually CONVINCED mother and my sister!? How can \z + I possibly explain all that? ...", + "I... I... Well, at least you told me the truth. I don't know if I can accept this as an \z + excuse but it's a start. Now let me return to my work, I need to fix this statue and then \z + the rest of this... mess." + }, + cid + ) + player:addAchievement("Truth Be Told") + player:setStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine, 11) + player:setStorageValue(Storage.TibiaTales.JackFutureQuest.LastMissionState, 1) + npcHandler.topic[cid] = 0 + end + end + elseif msgcontains(msg, "yes") then + if (npcHandler.topic[cid] == 1) then + npcHandler:say( + { + "Oh hm, I've got a handkerchief here somewhere - ah, oh no it's already used, I'm sorry. \z + So, you say that's a real person? Spectulus? I mean - what kind of weirdo thinks \z + of a name like that anyway. ...", + "And he does what? Hm. Here in Edron? I see. And I was - what? No way. Where? What! \z + Why? And you say you are telling the truth?" + }, + cid + ) + npcHandler.topic[cid] = 2 + elseif (npcHandler.topic[cid] == 2) then + npcHandler:say( + { + "I see. Well for starters, I think you're crazy. If I would have 'travelled' in some \z + kind of - device? - that thing should be around here somewhere, or not? ...", + "What? 'Dimensional fold?' Well, thanks for the information and please close the door \z + behind you when you leave my house. Now." + }, + cid + ) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine, 2) + end + + if player:getStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine) == 10 then + if (npcHandler.topic[cid] == 0) then + npcHandler:say("So that's it? Really?", cid) + npcHandler.topic[cid] = 6 + elseif (npcHandler.topic[cid] == 6) then + npcHandler:say( + "Yeah, yeah... so what are you still doing here? I guess I... will have to seek out this \z + Spectulus now, see what he has to say. There is nothing left for me in this place.", + cid + ) + player:addAchievement("You Don't Know Jack") + player:setStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine, 11) + player:setStorageValue(Storage.TibiaTales.JackFutureQuest.LastMissionState, 2) + npcHandler.topic[cid] = 0 + end + end + elseif msgcontains(msg, "hobbies") or msgcontains(msg, "hobby") then + if (player:getStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine) == 7) then + if (player:getStorageValue(Storage.TibiaTales.JackFutureQuest.Statue) < 1) then + npcHandler:say( + { + "Ah, also a keen lover of arts I assume? You might have already caught a glimpse of that \z + humble masterpiece over there in the corner - I sculpt sulky sculptures! ...", + "Sculpting sculptures was my passion since childhood... ...and it was there at my first \z + sandcastle when... ...and it formed... ...and it developed into... ...years of enduring \z + sculpting... ...carved of something like... ...sulky... ...", + "And that's what I like to do to this very day - hey, hey will you wake up? Were you even \z + listening to me?" + }, + cid, + false, + true, + 200 + ) + player:setStorageValue(Storage.TibiaTales.JackFutureQuest.Statue, 1) + npcHandler.topic[cid] = 0 + end + elseif (player:getStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine) == 8) then + npcHandler:say( + "I... was... sculpting sulky sculptures. For all my life. Until you came in here and DESTROYED \z + MY MASTERPIECE. Go away. I don't like you.", + cid + ) + npcHandler.topic[cid] = 0 + end + end + return true +end + +local voices = { + {text = "Now I need to clean up everything again."}, + {text = "So much to do, so little time, they say..."}, + {text = "Could it be...? No. No way."}, + {text = "Mh..."} +} + +npcHandler:addModule(VoiceModule:new(voices)) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/jack_drone.lua b/data/npc/scripts/jack_drone.lua new file mode 100644 index 00000000000..2abdf051480 --- /dev/null +++ b/data/npc/scripts/jack_drone.lua @@ -0,0 +1,29 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local travelNode = keywordHandler:addKeyword({'thais'}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage back to thais?'}) + travelNode:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, level = 0, cost = 0, destination = Position(32310, 32218, 5) }) + travelNode:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, reset = true, text = 'We would like to serve you some time.'}) + + keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'I can travel you to {thais}.'}) + keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I can travel you to {thais}.'}) + keywordHandler:addKeyword({'travel'}, StdModule.say, {npcHandler = npcHandler, text = 'I can travel you to {thais}.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome on board, |PLAYERNAME|. Where can I {sail} you today? I can travel you back to {thais}.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye. Recommend us if you were satisfied with our service.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye then.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/jack_fate.lua b/data/npc/scripts/jack_fate.lua new file mode 100644 index 00000000000..d8b00ea75a3 --- /dev/null +++ b/data/npc/scripts/jack_fate.lua @@ -0,0 +1,63 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Passages to Edron, Thais, Venore, Darashia, Ankrahmun, Yalahar and Port Hope.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, cost, destination, text, condition) + if condition then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sorry but I don\'t sail there.'}, condition) + end + + if keyword == 'goroma' then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Never heard about a place like this.'}, function(player) return player:getStorageValue(Storage.TheShatteredIsles.AccessToGoroma) ~= 1 end) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = text or 'Do you seek a passage to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('edron', 170, Position(33173,31764, 6)) +addTravelKeyword('venore', 180, Position(32954,32022, 6)) +addTravelKeyword('port hope', 50, Position(32527,32784, 6)) +addTravelKeyword('darashia', 200, Position(33289,32480, 6)) +addTravelKeyword('ankrahmun', 90, Position(33092,32883, 6)) +addTravelKeyword('goroma', 0, Position(32161,32558, 6), 'Ugh. You really want to go back to Goroma? I\'ll surely have to repair my ship afterwards, so I won\'t charge. Okay?') +addTravelKeyword('yalahar', 275, Position(32816,31272, 6), nil, function(player) return player:getStorageValue(Storage.SearoutesAroundYalahar.LibertyBay) ~= 1 and player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) < 5 end) + +-- Thais +local travelKeyword = keywordHandler:addKeyword({'thais'}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to Thais for |TRAVELCOST|?', cost = 180, discount = 'postman'}) + local childTravelKeyword = travelKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'I have to warn you - we might get into a tropical storm on that route. I\'m not sure if my ship will withstand it. Do you really want to travel to Thais?'}) + childTravelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = 180, discount = 'postman', destination = function(player) return math.random(8) == 1 and Position(32161, 32558, 6) or Position(32310, 32210, 6) end}) + childTravelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, reset = true, text = 'We would like to serve you some time.'}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, reset = true, text = 'We would like to serve you some time.'}) + +-- Basic +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Edron}, {Thais}, {Venore}, {Darashia}, {Ankrahmun}, {Yalahar} or {Port Hope}?'}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Edron}, {Thais}, {Venore}, {Darashia}, {Ankrahmun}, {Yalahar} or {Port Hope}?'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Jack Fate from the Royal Tibia Line.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m the captain of this sailing ship.'}) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m the captain of this sailing ship.'}) +keywordHandler:addKeyword({'liberty bay'}, StdModule.say, {npcHandler = npcHandler, text = 'That\'s where we are.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome on board, Sir |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye. Recommend us if you were satisfied with our service.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye then.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/jack_fate_goroma.lua b/data/npc/scripts/jack_fate_goroma.lua new file mode 100644 index 00000000000..89b09afe7ad --- /dev/null +++ b/data/npc/scripts/jack_fate_goroma.lua @@ -0,0 +1,84 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if (msg) then + msg = msg:lower() + end + + if isInArray({"sail", "passage", "wreck", "liberty bay", "ship"}, msg) then + if player:getStorageValue(Storage.TheShatteredIsles.AccessToGoroma) ~= 1 then + if player:getStorageValue(Storage.TheShatteredIsles.Shipwrecked) < 1 then + npcHandler:say('I\'d love to bring you back to Liberty Bay, but as you can see, my ship is ruined. I also hurt my leg and can barely move. Can you help me?', cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.TheShatteredIsles.Shipwrecked) == 1 then + npcHandler:say('Have you brought 30 pieces of wood so that I can repair the ship?', cid) + npcHandler.topic[cid] = 3 + end + else + npcHandler:say('Do you want to travel back to Liberty Bay?', cid) + npcHandler.topic[cid] = 4 + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "Thank you. Luckily the damage my ship has taken looks more severe than it is, so I will only need a few wooden boards. ...", + "I saw some lousy trolls running away with some parts of the ship. It might be a good idea to follow them and check if they have some more wood. ...", + "We will need 30 pieces of wood, no more, no less. Did you understand everything?" + }, cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say('Good! Please return once you have gathered 30 pieces of wood.', cid) + player:setStorageValue(Storage.TheShatteredIsles.DefaultStart, 1) + player:setStorageValue(Storage.TheShatteredIsles.Shipwrecked, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + if player:removeItem(5901, 30) then + npcHandler:say("Excellent! Now we can leave this godforsaken place. Thank you for your help. Should you ever want to return to this island, ask me for a passage to Goroma.", cid) + player:setStorageValue(Storage.TheShatteredIsles.Shipwrecked, 2) + player:setStorageValue(Storage.TheShatteredIsles.AccessToGoroma, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have enough...", cid) + end + elseif npcHandler.topic[cid] == 4 then + player:teleportTo(Position(32285, 32892, 6), false) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + npcHandler:say('Set the sails!', cid) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + end + end + return true +end + +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Jack Fate from the Royal Tibia Line.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m the captain of this - well, wreck. Argh.'}) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m the captain of this - well, wreck. Argh'}) +keywordHandler:addKeyword({'goroma'}, StdModule.say, {npcHandler = npcHandler, text = 'This is where we are... the volcano island Goroma. There are many rumours about this place.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Hello, Sir |PLAYERNAME|. Where can I {sail} you today?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye then.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/jack_the_worker.lua b/data/npc/scripts/jack_the_worker.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/jack_the_worker.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/jacob.lua b/data/npc/scripts/jacob.lua new file mode 100644 index 00000000000..16664fff099 --- /dev/null +++ b/data/npc/scripts/jacob.lua @@ -0,0 +1,83 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function creatureSayCallback(cid, type, msg) + if(not(npcHandler:isFocused(cid))) then + return false + end + + local player = Player(cid) + -- Mission 3 start + if(msgcontains(msg, "abandoned sewers")) then + if player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) < 21 then + npcHandler:say("You want to enter the abandoned sewers? That's rather dangerous and not a good idea, man. That part of the sewers was not sealed off for nothing, you know? ...", cid) + npcHandler:say("But hey, it's your life, bro. So here's the deal. I'll let you into the abandoned sewers if you help me with our {mission}.", cid) + -- Mission 3 end + elseif player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) == 21 then + npcHandler:say("Wow, you already did it, that's fast. I'm used to a more laid-back attitude from most people. It's a shame to risk losing you to some collapsing tunnels, but a deal is a deal. ...", cid) + npcHandler:say("I hereby grant you the permission to enter the abandoned part of the sewers. Take care, man! ...", cid) + npcHandler:say("If you find something interesting, come back to talk about the {abandoned sewers}.", cid) + npcHandler.topic[cid] = 7 + player:setStorageValue(Storage.DarkTrails.Mission04, 1) + player:setStorageValue(Storage.Oramond.DoorAbandonedSewer, 1) + elseif player:getStorageValue(Storage.DarkTrails.Mission05) == 1 then + npcHandler:say("I'm glad to see you back alive and healthy. Did you find anything interesting that you want to {report}?", cid) + npcHandler.topic[cid] = 7 + end + -- Mission 3 start + elseif(msgcontains(msg, "mission")) then + if(npcHandler.topic[cid] == 0) then + npcHandler:say("The sewers need repair. You in?", cid) + npcHandler.topic[cid] = 2 + -- Mission 3 end + elseif player:getStorageValue(Storage.DarkTrails.Mission03) == 1 then + npcHandler:say("Elliott's keeps calling it that. It's just another job! You fixed some broken pipes and stuff? Let me check, {ok}?", cid) + npcHandler.topic[cid] = 3 + end + -- Mission 3 start - sewer access + elseif(msgcontains(msg, "yes")) then + if(npcHandler.topic[cid] == 2) then + npcHandler:say("Good. Broken pipe and generator pieces, there's smoke evading. That's how you recognise them. See how you can fix them using your hands. Need about, oh, twenty of them at least repaired. Report to me or Jacob", cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.Oramond.AbandonedSewer, 1) + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer, 0) + end + -- Task: The Ancient Sewers + elseif(msgcontains(msg, "ok")) then + if(npcHandler.topic[cid] == 3) then + npcHandler:say("Good. Thanks, man. That's one vote you got for helping us with this.", cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer, 21) -- Mission 3 end + end + -- Final mission 5 + elseif(msgcontains(msg, "report")) then + if player:getStorageValue(Storage.DarkTrails.Mission05) == 1 then + if(npcHandler.topic[cid] == 7) then + npcHandler:say("A sacrificial site? Damn, sounds like some freakish cult or something. Just great. And this ancient structure you talked about that's not part of the sewers? You'd better see the local historian about that, man. ...", cid) + npcHandler:say("He can make more sense of what you found there. His name is Barazbaz. He should be in the magistrate building.", cid) + player:setStorageValue(Storage.DarkTrails.Mission06, 1) -- Start mission 6 + npcHandler.topic[cid] = 0 + else npcHandler:say("You already reported this mission, go to the next.", cid) + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/jagran.lua b/data/npc/scripts/jagran.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/jagran.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/jakahr.lua b/data/npc/scripts/jakahr.lua new file mode 100644 index 00000000000..9fac6f32c52 --- /dev/null +++ b/data/npc/scripts/jakahr.lua @@ -0,0 +1,22 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:setMessage(MESSAGE_GREET, "Hello, mourned pilgrim. How may I help you |PLAYERNAME|?") +npcHandler:setMessage(MESSAGE_FAREWELL, "It was an honour to serve you, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "It was an honour to serve you.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Here. Don't forget that you need to buy a label too if you want to send a parcel. Always write the name of the {receiver} in the first line.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/james.lua b/data/npc/scripts/james.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/james.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/jamesfrancis.lua b/data/npc/scripts/jamesfrancis.lua new file mode 100644 index 00000000000..bd9b92089c5 --- /dev/null +++ b/data/npc/scripts/jamesfrancis.lua @@ -0,0 +1,90 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + + local player = Player(cid) + if player:getStorageValue(Storage.CultsOfTibia.Minotaurs.Access) < 1 then + npcHandler:setMessage(MESSAGE_GREET, "Gerimor is right. As an expert for minotaurs I am researching these creatures for years. I thought I already knew a lot but the monsters in this cave are {different}. It's a big {mystery}.") + npcHandler.topic[cid] = 1 + elseif (player:getStorageValue(Storage.CultsOfTibia.Minotaurs.JamesfrancisTask) >= 0 and player:getStorageValue(Storage.CultsOfTibia.Minotaurs.JamesfrancisTask) <= 50) + and player:getStorageValue(Storage.CultsOfTibia.Minotaurs.Mission) < 3 then + npcHandler:setMessage(MESSAGE_GREET, "How is your {mission} going?") + npcHandler.topic[cid] = 5 + elseif player:getStorageValue(Storage.CultsOfTibia.Minotaurs.Mission) == 4 then + npcHandler:setMessage(MESSAGE_GREET, {"You say the minotaurs were controlled by a very powerful boss they worshipped. This explains why they had so much more power than the normal ones. ...", + "I'm very thankful. Please go to the Druid of Crunor and tell him what you've seen. He might be interested in that."}) + player:setStorageValue(Storage.CultsOfTibia.Minotaurs.Mission, 5) + npcHandler.topic[cid] = 10 + end + npcHandler:addFocus(cid) + return true +end + + +local voices = { + { text = 'Don\'t enter this area if you are an inexperienced fighter! It would be your end!' } +} +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + -- Start quest + if msgcontains(msg, "mystery") and npcHandler.topic[cid] == 1 then + npcHandler:say({"The minotaurs I faced in the cave are much stronger than the normal ones. What I were able to see before I had to flee: all of them seem to belong to a cult worshipping their god. Could you do me a {favour}?"}, cid) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, "favour") and npcHandler.topic[cid] == 2 then + npcHandler:say({"I'd like to work in this cave researching the minotaurs. But right now there are too many of hem and what is more, they are too powerful for me. Could you enter the cave and kill at least 50 of these creatures?"}, cid) + npcHandler.topic[cid] = 3 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 3 then + if player:getStorageValue(Storage.CultsOfTibia.Questline) < 1 then + player:setStorageValue(Storage.CultsOfTibia.Questline, 1) + end + npcHandler:say({"Very nice. Return to me if you've finished your job."}, cid) + player:setStorageValue(Storage.CultsOfTibia.Minotaurs.Mission, 2) + player:setStorageValue(Storage.CultsOfTibia.Minotaurs.JamesfrancisTask, 0) + player:setStorageValue(Storage.CultsOfTibia.Minotaurs.EntranceAccessDoor, 1) + npcHandler.topic[cid] = 0 + -- Delivering the quest + elseif msgcontains(msg, "mission") and npcHandler.topic[cid] == 5 then + if player:getStorageValue(Storage.CultsOfTibia.Minotaurs.JamesfrancisTask) >= 50 then + npcHandler:say({"Great job! You have killed at least 50 of these monsters. I give this key to you to open the door to the inner area. Go there and find out what's going on."}, cid) + player:setStorageValue(Storage.CultsOfTibia.Minotaurs.Mission, 3) + player:setStorageValue(Storage.CultsOfTibia.Minotaurs.AccessDoor, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say({"Come back when you have killed enough minotaurs."}, cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + + + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/janz.lua b/data/npc/scripts/janz.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/janz.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/jason.lua b/data/npc/scripts/jason.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/jason.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/jean_claude.lua b/data/npc/scripts/jean_claude.lua new file mode 100644 index 00000000000..e160dd39add --- /dev/null +++ b/data/npc/scripts/jean_claude.lua @@ -0,0 +1,38 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(10, 1000, -10) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if isInArray({"fuck", "idiot", "asshole", "ass", "fag", "stupid", "tyrant", "shit", "lunatic"}, msg) then + npcHandler:say("Take this!", cid) + local player = Player(cid) + player:getPosition():sendMagicEffect(CONST_ME_EXPLOSIONAREA) + player:addCondition(condition) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/jean_pierre.lua b/data/npc/scripts/jean_pierre.lua new file mode 100644 index 00000000000..b4dd4d54016 --- /dev/null +++ b/data/npc/scripts/jean_pierre.lua @@ -0,0 +1,525 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local ingredients = { + [1] = {{2666, 2}, {8838, 20}, {8843, 1}, {9114, 1}, {2692, 5}, {2006, 2, 3}}, + [2] = {{7250, 2}, {2685, 2}, {8842, 1}, {2695, 2}, {2805, 1}, {2006, 1, 15}}, + [3] = {{4298, 1}, {8844, 3}, {2691, 5}, {2695, 2}, {2803, 1}, {2788, 5}}, + [4] = {{4265, 1}, {8841, 2}, {2675, 2}, {5097, 2}, {2006, 2, 14}, {2799, 1}}, + [5] = {{6574, 1}, {7966, 1}, {2676, 2}, {2006, 2, 6}, {2802, 1}, {2800, 1}}, + [6] = {{2684, 2}, {2685, 2}, {2686, 2}, {8842, 2}, {8843, 1}, {9114, 1}, {2696, 1}, {2787, 20}, {2789, 5}}, + [7] = {{8844, 10}, {2696, 2}, {2805, 1}, {2804, 1}, {2006, 1, 43}, {2695, 2}}, + [8] = {{2671, 1}, {8839, 5}, {8843, 1}, {8845, 2}, {2683, 1}, {8844, 2}}, + [9] = {{2669, 1}, {7158, 1}, {7159, 1}, {2670, 5}, {2690, 2}, {2801, 1}}, + [10] = {{2684, 5}, {2006, 1, 6}, {8841, 1}, {2692, 10}, {2695, 2}, {2687, 10}, {7910, 2}}, + [11] = {{2006, 5, 14}, {2789, 5}, {2788, 5}, {11246, 10}, {2670, 10}}, + [12] = {{11373, 5}, {2006, 2, 1}, {2684, 20}, {8838, 10}, {8844, 3}}, + [13] = {{6569, 3}, {2688, 3}, {6574, 2}, {6501, 15}, {6558, 1}}, + [14] = {{2695, 40}, {5097, 20}, {5902, 10}, {9674, 1}, {5942, 1}} +} + +local function playerHasIngredients(cid) + local player = Player(cid) + local table = ingredients[player:getStorageValue(Storage.HotCuisineQuest.CurrentDish)] + if table then + for i = 1, #table do + local itemCount = player:getItemCount(table[i][1], table[i][3] or -1) + if itemCount < table[i][2] then + itemCount = table[i][2] - itemCount + return false + end + end + end + + for i = 1, #table do + player:removeItem(unpack(table[i])) + end + return true +end + + +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.HotCuisineQuest.QuestStart) < 1 then + npcHandler:setMessage(MESSAGE_GREET, "Greetings, |PLAYERNAME|. What are you doing out here?") + else + npcHandler:setMessage(MESSAGE_GREET, "Hello there again, |PLAYERNAME|! I guess you're back for some cooking - let's get going then!") + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "cook") then + if player:getStorageValue(Storage.HotCuisineQuest.QuestStart) < 1 then + npcHandler:say("Well, I'm not a simple cook. I travel the whole Tibian continent for the most artfully seasoned {recipes} and constantly develop new ones.", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "recipe") or msgcontains(msg, "menu") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("You're interested in my recipes? Well. They are not for sale, but if you want to become my {apprentice}, I'll share my knowledge with you.", cid) + npcHandler.topic[cid] = 2 + end + if player:getStorageValue(Storage.HotCuisineQuest.QuestStart) == 1 then + if player:getStorageValue(Storage.HotCuisineQuest.CurrentDish) == 1 then + npcHandler:say({ + "The first dish we are going to prepare together is called {Rotworm Stew}. Now, don't be scared off. Of course we won't eat those nasty and dirty earth-crawlers! ...", + "The name is just for the effect it has on people. Bring me the following ingredients and I'll show you how it's done. ...", + "Two pieces of meat, two vials of beer, twenty potatoes, one onion, one bulb of garlic and five ounces of flour. Make sure that the ingredients are fresh and smell good." + }, cid) + npcHandler.topic[cid] = 4 + elseif player:getStorageValue(Storage.HotCuisineQuest.CurrentDish) == 2 then + npcHandler:say({ + "The next dish we are going to prepare together is called {Hydra Tongue Salad}. The common hydra tongue is a pest plant with an surprisingly aromatic taste. ...", + "We'll add some other vegetables and spices for the delicate and distinctive taste. Bring me the following ingredients and I'll show you how it's done. ...", + "Two hydra tongue plants, two tomatoes, one cucumber, two eggs, one troll green and one vial of wine." + }, cid) + npcHandler.topic[cid] = 6 + elseif player:getStorageValue(Storage.HotCuisineQuest.CurrentDish) == 3 then + npcHandler:say({ + "The next dish we are going to prepare together is called {Roasted Dragon Wings}. Oh, don't give me that look! Of course you don't have to bring a whole dragon up here. ...", + "The 'dragon' part derives from the fiery afterburn of this meal, but the wings we use are much smaller, though similar in shape. Bring me the following ingredients and I'll show you how it's done. ...", + "One fresh dead bat, three jalapeño peppers, five brown breads, two eggs, one powder herb and five red mushrooms." + }, cid) + npcHandler.topic[cid] = 8 + elseif player:getStorageValue(Storage.HotCuisineQuest.CurrentDish) == 4 then + npcHandler:say({ + "The next dish we are going to prepare together is called {Tropical Fried Terrorbird}. You might have guessed it, we're not going to use a terrorbird. But! ...", + "The dish is quite fried and tropical. Bring me the following ingredients and we're going to prepare it: One fresh dead chicken, two lemons, two oranges, two mangos, one stone herb and two vials of coconut milk." + }, cid) + npcHandler.topic[cid] = 10 + elseif player:getStorageValue(Storage.HotCuisineQuest.CurrentDish) == 5 then + npcHandler:say({ + "The next dish we are going to prepare together is called {Banana Chocolate Shake}. After all those spicy dishes you should treat your guests with a sweet surprise. ...", + "Bring me the following ingredients and we'll make one hell of a drink: one bar of chocolate, one cream cake, two bananas, two vials of milk, one sling herb and one star herb." + }, cid) + npcHandler.topic[cid] = 12 + elseif player:getStorageValue(Storage.HotCuisineQuest.CurrentDish) == 6 then + npcHandler:say({ + "The next dish we are going to prepare together is called {Veggie Casserole}. This one is going to be your masterpiece so far, I'm telling you. ...", + "It's also quite healthy! - Well, that's what I keep telling me when I eat the third serving, hehehe. Bring me the following ingredients and I'll show you how it's done. ...", + "Two carrots, two tomatoes, two corncobs, two cucumbers, one onion, one bulb of garlic, one piece of cheese, twenty white mushrooms and five brown mushrooms." + }, cid) + npcHandler.topic[cid] = 14 + elseif player:getStorageValue(Storage.HotCuisineQuest.CurrentDish) == 7 then + npcHandler:say({ + "The next dish we are going to prepare together is called {Filled Jalapeño Peppers}. It's a great snack and quite spicy, for those who like it hot. ...", + "Bring me the following ingredients and I'll show you how it's done: Ten jalapeño peppers, two pieces of cheese, one troll green, one shadow herb, one vial of mead and two eggs." + }, cid) + npcHandler.topic[cid] = 16 + elseif player:getStorageValue(Storage.HotCuisineQuest.CurrentDish) == 8 then + npcHandler:say({ + "The next dish we are going to prepare together is called {Blessed Steak}. I'm sorry, I couldn't resist the pun with this one. ...", + "Don't worry, there's no temple trip awaiting you. Just bring me the following: one piece of ham, five plums, one onion, two beetroots, one pumpkin and two jalapeño peppers." + }, cid) + npcHandler.topic[cid] = 18 + elseif player:getStorageValue(Storage.HotCuisineQuest.CurrentDish) == 9 then + npcHandler:say({ + "The next dish we are going to prepare together is called {Northern Fishburger}. I hope you like fish, not everyone does. This one is a specialty I picked up in Svargrond. ...", + "Bring me the following ingredients and I'll show you how it's done: one northern pike, one rainbow trout, one green perch, five shrimps, two rolls and one fern." + }, cid) + npcHandler.topic[cid] = 20 + elseif player:getStorageValue(Storage.HotCuisineQuest.CurrentDish) == 10 then + npcHandler:say({ + "The last dish we are going to prepare together is called {Carrot Cake}. Yes, it's a real cake, we need a tasty desert to complete our cooking course. ...", + "Bring me the following ingredients and I'll lead you through it: five carrots, one vial of milk, one lemon, ten ounces of flour, two eggs, ten cookies and two peanuts." + }, cid) + npcHandler.topic[cid] = 22 + elseif player:getStorageValue(Storage.HotCuisineQuest.CurrentDish) == 11 then + npcHandler:say({ + "Yes, you heard that right! Even though I was laying sick on my divan for weeks, I have some new dishes for you. Ehem. Of course I couldn't have done it without my little helpers travelling around the world and discovering recipes. ...", + "So... ... each good menu needs an amazing starter to awaken and stimulate all the little taste buds on your tongue. We're going to cook a nice portion of {Coconut Shrimp Bake}! ...", + "This is an exotic rice dish with hints of mushrooms and shrimps, topped with sweet coconut goodness - brought to me by a beautiful druid lady a few days ago. My mouth starts watering already! ...", + "... because of the dish, I mean, of course. Ehem. Bring me the following ingredients and we'll get started: Five vials of coconut milk, five brown mushrooms, five red mushrooms, ten rice balls and ten shrimps." + }, cid) + npcHandler.topic[cid] = 24 + elseif player:getStorageValue(Storage.HotCuisineQuest.CurrentDish) == 12 then + npcHandler:say({ + "After this wonderful and tasty starter we're all set for a special dish I learnt from a brave adventurer who almost starved when he got lost in the mountains between Ankrahmun and Port Hope, or so he told me. ...", + "Luckily, he was saved by nomads - can you imagine? - and they fed him a special local dish that's very cheap and easy to prepare, yet rich in vitamins and spending energy for hours. ...", + "Now don't be shocked, but - they do put sandcrawlers in there. When I tried to prepare that dish at first, I was repelled by its awful appearance, but since it smelled so good I did take a sip and was pleasantly surprised of the great taste. ...", + "According to the adventurer, this meal works well with any kind of vegetables or any kind of edible creepy-crawlers, depending on what the nomads get their hands on, but we'll stick to the original for now! ...", + "Bring me the following ingredients - if you dare - and I'll show you the secret of {Blackjack}: Five sandcrawler shells, two vials of water, twenty carrots, ten potatoes and three jalapeño peppers." + }, cid) + npcHandler.topic[cid] = 26 + elseif player:getStorageValue(Storage.HotCuisineQuest.CurrentDish) == 13 then + npcHandler:say({ + "Weren't you surprised by the great taste of our main dish? In case you still have some space left in your tummy, we're in for a sweet and fun dessert - but beware unwanted side effects! ...", + "It was introduced to me by a fearless knight who invented this recipe rather by accident when a bottle of demonic blood broke in his backpack and spilled its contents over his bag of candy balls. ...", + "Curiously, he tried one and red steam came out of his ears - but it tasted so great that he instantly popped another one in his mouth, and then another, and another. ...", + "Each one seemed to cause a different effect and he was never really sure what the next one would do. Seems safer to be careful with them and not to eat them in dangerous situations! ...", + "In any case, bring me the following ingredients and we'll make some {Demonic Candy Balls}, if you like: Three candies, three candy canes, two bars of chocolate, fifteen gingerbread men and one concentrated demonic blood." + }, cid) + npcHandler.topic[cid] = 28 + elseif player:getStorageValue(Storage.HotCuisineQuest.CurrentDish) == 14 then + npcHandler:say({ + "Did you dare eat all of your Demonic Candy Balls...? Hehehe! Well, I almost forgot one of the most essential parts for a perfect dinner. A drink! I have one for you, almost a designer drink you could say. ...", + "Its inventor seems to have done some scientific research in order to achieve his desired effect, which is - charging magical rings. You have to drink it while you're wearing one for a miraculous effect! ...", + "Bring me the following ingredients and we'll get started: Fourty eggs, twenty mangos, ten honeycombs, one bottle of bug milk and one blessed wooden stake. ...", + "Oh yes, I understand your worries about the eggs, but just make sure they're fresh and all should be fine for our {Sweet Mangonaise Elixir}!" + }, cid) + npcHandler.topic[cid] = 30 + end + elseif player:getStorageValue(Storage.HotCuisineQuest.QuestStart) == 2 then + npcHandler:say("You can now cook any dish you want from this list: {Rotworm Stew, Hydra Tongue Salad, Roasted Dragon Wings, Tropical Fried Terrorbird, Banana Chocolate Shake, Veggie Casserole, Filled Jalapeno Peppers, Blessed Steak, Northern Fishburger, Carrot Cake, Coconut Shrimp Bake, Blackjack, Demonic Candy Balls, Sweet Mangonaise Elixir}.", cid) + end + elseif msgcontains(msg, "apprentice") then + if npcHandler.topic[cid] == 2 then + npcHandler:say("Hmm. You look quite promising. Can't hurt to give it a try, I guess. Would you like to become my apprentice, |PLAYERNAME|?", cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 3 then + npcHandler:say("Fine, young human. Ask me for a {recipe} anytime and I'll teach you what I know.", cid) + player:setStorageValue(Storage.HotCuisineQuest.QuestStart, 1) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 1) + player:setStorageValue(Storage.HotCuisineQuest.QuestLog, 1) + elseif npcHandler.topic[cid] == 5 then + if playerHasIngredients(cid) then + npcHandler:say({ + "Aah, so let's see! We cook the meat in a large pot together with the chopped onion until it's separated from the bones. Now we also have a fine meat broth! ...", + "Cut the potatoes into small pieces and add them to the pot. Add some flour to thicken the stew. Finally, spice it up with some garlic and add beer for the typical dwarvish taste! ...", + "And voilà, we're done. I developed this recipe while talking to Maryza in the Jolly Axeman. She said to eat it when one's health is low. Enjoy!" + }, cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 2) + player:setStorageValue(Storage.HotCuisineQuest.QuestLog, 2) + player:addItem(9992, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Make sure that you have all the ingredients, with you.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 7 then + if playerHasIngredients(cid) then + npcHandler:say({ + "Okay, here we go! This one is easy, just chop the hydra tongues, tomatoes and cucumber into tiny pieces. ...", + "Now for the sauce - our base is wine, in which we mix the raw eggs until it got a nice smooth consistency. Add grinded troll green, whose flavour is quite similar to basil and shake the sauce in a mug. ...", + "Pour it over the salad, and voilà, we're done! This is a Venorean recipe and very tasty. I recommend eating it when you're suffering from some kind of dangerous condition. Enjoy!" + }, cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 3) + player:setStorageValue(Storage.HotCuisineQuest.QuestLog, 3) + player:addItem(9993, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Make sure that you have all the ingredients, with you.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 9 then + if playerHasIngredients(cid) then + npcHandler:say({ + "Let's get started! The trick with this one is the crunchy crust around the wings. ...", + "First, we grate the dry brown bread into very small crumbs and mix that with the two eggs. Add grinded peppers for the spicy taste and the powder herb for a hint of curry flavour. ...", + "Carefully separate the bat wings, clean them of any possible hairs and coat them in our mixture. Roast them in a pan together with sliced mushrooms and serve. ...", + "Voilà, we're done! This recipe is from the area around Thais and should help you protect yourself in your battles. Enjoy!" + }, cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 4) + player:setStorageValue(Storage.HotCuisineQuest.QuestLog, 4) + player:addItem(9994, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Make sure that you have all the ingredients, with you.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 11 then + if playerHasIngredients(cid) then + npcHandler:say({ + "This is a recipe right from the jungles of Tiquanda! Grind the stone herb and mix it with the coconut milk, then bathe the chicken in it for a while. ...", + "In the meantime, peel the oranges and mangos, chop them into pieces and add them to the mix. Take the chicken out of its bath and fry it, preferably over open fire. ...", + "Take the fruits out of the spicy coconut milk and heat them on an oven. Once the chicken is fried, add the fruits and spray some squeezed lemon over it. ...", + "Voilà, we're done! They say that this dish has magical abilities and can awaken secret powers in you during your battles. Enjoy!" + }, cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 5) + player:setStorageValue(Storage.HotCuisineQuest.QuestLog, 5) + player:addItem(9995, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Make sure that you have all the ingredients, with you.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 13 then + if playerHasIngredients(cid) then + npcHandler:say({ + "Great! Let's get it done! An easy one again, but you'll get right into holiday mood, like the Meriana beach dwellers I got that recipe from. ...", + "Melt the chocolate in a hot-water bath and add the grinded herbs - did you know, those herbs have a flavour like cinnamon and vanilla, yummy! Keep at gentle heat and add the milk. ...", + "Mash the banana and stir it really well into the chocolate-milk mixture. Gosh, do you smell that? Pure goodness! Now finally, we take just a bit of the creamcake and fold it in. ...", + "Voilà, we're done! To be honest, I don't know what this drink does, but at least it makes me really happy. Drink together with a loved one and enjoy!" + }, cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 6) + player:setStorageValue(Storage.HotCuisineQuest.QuestLog, 6) + player:addItem(9996, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Make sure that you have all the ingredients, with you.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 15 then + if playerHasIngredients(cid) then + npcHandler:say({ + "So let's start! This is a dish especially famous in the area around Ab'Dendriel! Chop the onions into little cubes and sweat them in a pan until they are glassy. ...", + "Add garlic and mushrooms and fry gently until the mushrooms have shrunk up. Now, we add the peeled tomatoes and corn and have it all nicely cook together. ...", + "Put in carrot pieces and cucumber at the very end, so they will stay crisp! Finally put the cheese over it like a little blanket have it melt on the oven until it's slightly brownish. ...", + "And voilà, we're done! This dish will help you in your battles and supply you with enough power to hit really hard! Enjoy!" + }, cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 7) + player:setStorageValue(Storage.HotCuisineQuest.QuestLog, 7) + player:addItem(9997, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Make sure that you have all the ingredients, with you.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 17 then + if playerHasIngredients(cid) then + npcHandler:say({ + "Okay! So after all of these heavy dishes, we're going to create a fast little snack. ...", + "First of all, remove the top of the jalapeño peppers and clean their inside, so that you have space for the filling. Now for the filling, we grate the cheese and mix it with the mead and the eggs, until it has a nice consistency. ...", + "We add the grinded herbs and blend it well. Push a spoonful in each jalapeño pepper until they are nicely stuffed. Now, we shortly fry the jalapeño peppers in a pan to heat them up. ...", + "The filling will melt nicely, just be careful that it doesn't drip out! And voilà, we're done! ...", + "This famous dish from Ankrahmun is quite hot and spicy, so only eat one at a time. It's also possible that you get the urge to run really fast afterwards. Enjoy!" + }, cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 8) + player:setStorageValue(Storage.HotCuisineQuest.QuestLog, 8) + player:addItem(9998, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Make sure that you have all the ingredients, with you.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 19 then + if playerHasIngredients(cid) then + npcHandler:say({ + "Here we go! This will break through the meat fibres, making our steak more tender for this fine Daramanian dish. ...", + "It's easy to prepare, just chop and sweat the onions and add small pieces of pumpkin, beetroot, plums and peppers. Put the steak into the pan too to let it absorb some of the sweet and fruity flavour. ...", + "Finally, remove the fruits and onions from the pan and fry the steak from both sides until it's crisp and crusty. Put on a plate and decorate with the fruit mix. ...", + "The people of Darashia say that it has magical abilities and will help you if you feel totally drained. Enjoy!" + }, cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 9) + player:setStorageValue(Storage.HotCuisineQuest.QuestLog, 9) + player:addItem(9999, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Make sure that you have all the ingredients, with you.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 21 then + if playerHasIngredients(cid) then + npcHandler:say({ + "Great! After all this meat, we shouldn't neglect to prepare some fish. ...", + "This easy dish from Svargrond is what you'd call fast food, but its outstanding taste justifies to put it in my book about {Hot Cuisine}. ...", + "Simply cut the rolls in half, shortly fry one slice of each fish type, put in the shrimps and spice up with grinded fern, which, by the way, tastes slightly like dill. ...", + "Nicely decorate it on a plate, and voilr, we're done already! Can't tell you much about the effects, but fishermen in Svargrond seem to love it. Enjoy!" + }, cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 10) + player:setStorageValue(Storage.HotCuisineQuest.QuestLog, 10) + player:addItem(10001, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Make sure that you have all the ingredients, with you.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 23 then + if playerHasIngredients(cid) then + npcHandler:say({ + "So, now for our final dish - a grand dessert from the amazon girls at Carlin! ...", + "It's easy as it can be - mix a normal cake dough with milk, flour and eggs, then add some cookie crumbs for the crunchy effect later on. ...", + "Stir in the grated carrots and tiny peanut pieces and bake it for about thirty minutes! Now we'll make a great topping with sugar and lemon juice, pour it over the cake and decorate it. ...", + "And voilà, we're done! The girls of Carlin swear that it sharpens their eyesight, at least for a while. I'm sure it will somehow aid you in your battles. Enjoy! ...", + "Oh, which reminds me - my little apprentice, we are finished with our cooking course. I think you did great and if it was my decision, you could open your own tavern. ...", + "But anyway, it's up to you what you make of your newly discovered skills! In case you forget my recipes, please feel free to take a copy of the cookbook upstairs. ...", + "You can drop by and practice cooking those dishes, at least during the time that I'm at home. I promise that I will cook each dish once with you, but then I have to take care of my other apprentices. Cheers to you!" + }, cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 11) + player:setStorageValue(Storage.HotCuisineQuest.QuestLog, 11) + player:setStorageValue(Storage.HotCuisineQuest.CookbookDoor, 1) + player:addItem(10000, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Make sure that you have all the ingredients, with you.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 25 then + if playerHasIngredients(cid) then + npcHandler:say({ + "Yum! Just the thought of it makes me drool. ...", + "I see you brought real Zaoan rice balls! That saves us a lot of time as we don't have to cook the rice anymore. Now we just flatten them out nice and medium thick on this baking tray. ...", + "In the meantime, our shrimps have absorbed some of the coconut milk and we can now add them on top of the rice. ...", + "Now we just need to add the mushrooms , pour the rest of the coconut milk over it and put it into the oven! ...", + "... dum di dum ... ...", + "Aaaaaaand there you go! Sweet coconut goodness! And psst - the shrimps add some submarine flavour to this dish. You should definitely eat it while walking underwater and wearing a helmet of the deep. Just in case. Enjoy!" + }, cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 12) + player:setStorageValue(Storage.HotCuisineQuest.QuestLog, 13) + player:addItem(12540, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Make sure that you have all the ingredients, with you.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 27 then + if playerHasIngredients(cid) then + npcHandler:say({ + "Awesome! Let's go! Let's start with preparing the sandcrawlers ...", + "I understand your scepticism, but believe me, all will be well! As you can see, they change colour from dark to light red, and that's when they also start turning soft. ...", + "Now add whole potatoes and let everything cook at high temperature until the potatoes are so soft they're basically falling apart. ...", + "Yes yes, I know, don't give me that look! You'll be surprised! Now just add the chopped carrots and chili for a healthy portion of vitamins and spices, keep stiring and mashing and let it simmer for about an hour. ...", + "You're wondering why I chose a simple recipe like that for my famous menu? You'll know when you taste it! ...", + "Heeeeeere you are - just a few spoons of this great stew make you so full that the bowl I give you will last for a long time until it's finally depleted. Enjoy!" + }, cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 13) + player:setStorageValue(Storage.HotCuisineQuest.QuestLog, 14) + player:addItem(12542, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Make sure that you have all the ingredients, with you.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 29 then + if playerHasIngredients(cid) then + npcHandler:say({ + "Very nice! I'm ready for action! ...", + "After having crushed all those sweets, we need to melt the chocolate into a thick liquid... ...", + "... and form little balls together with the sweets! ...", + "Now, carefully, we add the demonic blood... ...", + "Here you go, but beware possible side effects! You never know for sure what will happen and so far all of those I tried had awesome effects, so of course I don't hope for nasty surprises! Enjoy!" + }, cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 14) + player:setStorageValue(Storage.HotCuisineQuest.QuestLog, 15) + player:addItem(12543, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Make sure that you have all the ingredients, with you.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 31 then + if playerHasIngredients(cid) then + npcHandler:say({ + "Time to have a sweet drink! Let's pour the bug milk into my cauldron and heat it over fire until it's boiling... there! ...", + "Now we're breaking all of the eggs into there - 1, 2, 10, 20, 40 crumble the honeycombs and toss the sliced mangoes into the hot mix. ...", + "Now we just have to let it simmer and stir using a blessed wooden stake for thirty minutes. ...", + "By now, the power of the blessed wooden stake will have been transferred into our elixir, so let's put out the fire and let it cool down. ...", + " There! Its inventor said it had amazing effects on the ring you're wearing, as long as the ring is based on time, not on charges. Enjoy! ...", + "And by the way... since those were all the recipes from this year and you cooked them so nicely, you may take the cookbook containing them from upstairs, if you like!" + }, cid) + player:setStorageValue(Storage.HotCuisineQuest.QuestStart, 2) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 15) + player:setStorageValue(Storage.HotCuisineQuest.QuestLog, 16) + player:addItem(12544, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Make sure that you have all the ingredients, with you.", cid) + npcHandler.topic[cid] = 0 + end + end + --Dishes first time + elseif msgcontains(msg, "rotworm stew") then + if npcHandler.topic[cid] == 4 or player:getStorageValue(Storage.HotCuisineQuest.QuestStart) == 2 then + npcHandler:say("Did you gather all necessary ingredients to cook Rotworm Stew with me?", cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 1) + npcHandler.topic[cid] = 5 + end + elseif msgcontains(msg, "hydra tongue salad") then + if npcHandler.topic[cid] == 6 or player:getStorageValue(Storage.HotCuisineQuest.QuestStart) == 2 then + npcHandler:say("Did you gather all necessary ingredients to prepare a Hydra Tongue Salad with me?", cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 2) + npcHandler.topic[cid] = 7 + end + elseif msgcontains(msg, "roasted dragon wings") then + if npcHandler.topic[cid] == 8 or player:getStorageValue(Storage.HotCuisineQuest.QuestStart) == 2 then + npcHandler:say("Did you gather all necessary ingredients to prepare Roasted Dragon Wings with me?", cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 3) + npcHandler.topic[cid] = 9 + end + elseif msgcontains(msg, "tropical fried terrorbird") then + if npcHandler.topic[cid] == 10 or player:getStorageValue(Storage.HotCuisineQuest.QuestStart) == 2 then + npcHandler:say("Did you gather all necessary ingredients to prepare a Tropical Fried Terrorbird with me?", cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 4) + npcHandler.topic[cid] = 11 + end + elseif msgcontains(msg, "banana chocolate shake") then + if npcHandler.topic[cid] == 12 or player:getStorageValue(Storage.HotCuisineQuest.QuestStart) == 2 then + npcHandler:say("Did you gather all necessary ingredients to make a Banana Chocolate Shake with me?", cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 5) + npcHandler.topic[cid] = 13 + end + elseif msgcontains(msg, "veggie casserole") then + if npcHandler.topic[cid] == 14 or player:getStorageValue(Storage.HotCuisineQuest.QuestStart) == 2 then + npcHandler:say("Did you gather all necessary ingredients to cook a Veggie Casserole with me?", cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 6) + npcHandler.topic[cid] = 15 + end + elseif msgcontains(msg, "filled jalapeño peppers") then + if npcHandler.topic[cid] == 16 or player:getStorageValue(Storage.HotCuisineQuest.QuestStart) == 2 then + npcHandler:say("Did you gather all necessary ingredients to prepare Filled Jalapeño Peppers with me?", cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 7) + npcHandler.topic[cid] = 17 + end + elseif msgcontains(msg, "blessed steak") then + if npcHandler.topic[cid] == 18 or player:getStorageValue(Storage.HotCuisineQuest.QuestStart) == 2 then + npcHandler:say("Did you gather all necessary ingredients to prepare a Blessed Steak with me?", cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 8) + npcHandler.topic[cid] = 19 + end + elseif msgcontains(msg, "northern fishburger") then + if npcHandler.topic[cid] == 20 or player:getStorageValue(Storage.HotCuisineQuest.QuestStart) == 2 then + npcHandler:say("Did you gather all necessary ingredients to make a Northern Fishburger with me?", cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 9) + npcHandler.topic[cid] = 21 + end + elseif msgcontains(msg, "carrot cake") then + if npcHandler.topic[cid] == 22 or player:getStorageValue(Storage.HotCuisineQuest.QuestStart) == 2 then + npcHandler:say("Did you gather all necessary ingredients to bake a Carrot Cake with me?", cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 10) + npcHandler.topic[cid] = 23 + end + elseif msgcontains(msg, "coconut shrimp bake") then + if npcHandler.topic[cid] == 24 or player:getStorageValue(Storage.HotCuisineQuest.QuestStart) == 2 then + npcHandler:say("Did you gather all necessary ingredients to prepare a Coconut Shrimp Bake with me?", cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 11) + npcHandler.topic[cid] = 25 + end + elseif msgcontains(msg, "blackjack") then + if npcHandler.topic[cid] == 26 or player:getStorageValue(Storage.HotCuisineQuest.QuestStart) == 2 then + npcHandler:say("Did you gather all necessary ingredients to cook a Blackjack with me?", cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 12) + npcHandler.topic[cid] = 27 + end + elseif msgcontains(msg, "demonic candy ball") then + if npcHandler.topic[cid] == 28 or player:getStorageValue(Storage.HotCuisineQuest.QuestStart) == 2 then + npcHandler:say("Did you gather all necessary ingredients to make Demonic Candy Balls with me?", cid) + player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 13) + npcHandler.topic[cid] = 29 + end + --elseif msgcontains(msg, "sweet mangonaise elixir") then + -- if npcHandler.topic[cid] == 30 or player:getStorageValue(Storage.HotCuisineQuest.QuestStart) == 2 then + -- npcHandler:say("Did you gather all necessary ingredients to mix Sweet Mangonaise Elixir with me?", cid) + -- player:setStorageValue(Storage.HotCuisineQuest.CurrentDish, 14) + -- npcHandler.topic[cid] = 31 + --end + elseif msgcontains(msg, "no") then + npcHandler:say("No?, come back when you are ready to cook.", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/jerom.lua b/data/npc/scripts/jerom.lua new file mode 100644 index 00000000000..2ae857d2067 --- /dev/null +++ b/data/npc/scripts/jerom.lua @@ -0,0 +1,27 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'My house! Uahahahaha .' }, + { text = 'Dear gods! My precious house, DESTROYED!!' }, + { text = 'Oh no!! What am I supposed to do now?!?' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "Hello. Sorry, but I'm not in the best {mood} today.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/jeronimo.lua b/data/npc/scripts/jeronimo.lua new file mode 100644 index 00000000000..49ea9c1186d --- /dev/null +++ b/data/npc/scripts/jeronimo.lua @@ -0,0 +1,76 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- ID, Count, Price +local eventShopItems = { + ["small stamina refill"] = {22473, 1, 100}, + ["zaoan chess box"] = {20620, 1, 100}, + ["pannier backpack"] = {21475, 1, 70}, + ["green light"] = {23588, 1, 70}, + ["blood herb"] = {2798, 3, 10}, + ["draken doll"] = {13031, 1, 70}, + ["bear doll"] = {3954, 1, 70} +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + msg = string.lower(msg) + if (msg == "event shop") then + npcHandler:say("In our website enter in {Events} => {Events Shop}.", cid) + end + + if (eventShopItems[msg]) then + npcHandler.topic[cid] = 0 + local itemId, itemCount, itemPrice = eventShopItems[msg][1], eventShopItems[msg][2], eventShopItems[msg][3] + if (player:getItemCount(15515) > 0) then + npcHandler:say("You want buy {" ..msg.. "} for " ..itemPrice.. "x?", cid) + npcHandler.topic[cid] = msg + else + npcHandler:say("You don't have " ..itemPrice.. " {Bar of Gold(s)}!", cid) + return true + end + end + + if (eventShopItems[npcHandler.topic[cid]]) then + local itemId, itemCount, itemPrice = eventShopItems[npcHandler.topic[cid]][1], eventShopItems[npcHandler.topic[cid]][2], eventShopItems[npcHandler.topic[cid]][3] + if (msg == "no" or + msg == "n�o") then + npcHandler:say("So... what you want?", cid) + npcHandler.topic[cid] = 0 + elseif (msg == "yes" or + msg == "sim") then + if (player:getItemCount(15515) >= itemPrice) then + npcHandler:say("You bought {" ..npcHandler.topic[cid].."} " ..itemCount.. "x for " ..itemPrice.. " {Bar of Gold(s)}!", cid) + player:removeItem(15515, itemPrice) + player:addItem(itemId, itemCount) + else + npcHandler:say("You don't have enough bar's.", cid) + return true + end + end + end +end + +local voices = { {text = 'Change your Bar of Gold\'s for Items here!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/jezzara.lua b/data/npc/scripts/jezzara.lua new file mode 100644 index 00000000000..6bc3b18dd8d --- /dev/null +++ b/data/npc/scripts/jezzara.lua @@ -0,0 +1,25 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Food of various kinds, have a look.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "Be mourned pilgrim in flesh. Talking of flesh, maybe you'd enjoy some {food}?") +npcHandler:setMessage(MESSAGE_FAREWELL, "May enlightenment be your path.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "May enlightenment be your path.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Sure, take a look at my offers.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/jimbin.lua b/data/npc/scripts/jimbin.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/jimbin.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/jimmy.lua b/data/npc/scripts/jimmy.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/jimmy.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/john.lua b/data/npc/scripts/john.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/john.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/jondrin.lua b/data/npc/scripts/jondrin.lua new file mode 100644 index 00000000000..ed6bab7d82d --- /dev/null +++ b/data/npc/scripts/jondrin.lua @@ -0,0 +1,45 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function creatureSayCallback(cid, type, msg) + if(not(npcHandler:isFocused(cid))) then + return false + end + + local player = Player(cid) + if(msgcontains(msg, "necrometer")) then + --[[if player:getStorageValue(Storage.Oramond.TaskProbing == 1) then + --for this mission is needed script of the npc Doubleday]] + npcHandler:say("A necrometer? Have you any idea how rare and expensive a necrometer is? There is no way I could justify giving a necrometer to an inexperienced adventurer. Hm, although ... if you weren't inexperienced that would be a different matter. ...", cid) + npcHandler:say("Did you do any measuring task for Doubleday lately?", cid) + npcHandler.topic[cid] = 1 + --end + elseif(msgcontains(msg, "yes")) then + if(npcHandler.topic[cid] == 1) and player:getStorageValue(Storage.DarkTrails.Mission09) == 1 then + npcHandler:say("Indeed I heard you did a good job out there. I guess that means I can hand you one of our necrometers. Handle it with care", cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.DarkTrails.Mission10, 1) + player:addItem(23495,1) + else + npcHandler:say("You already got the Necrometer.", cid) + end + end + return true +end +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/jorge.lua b/data/npc/scripts/jorge.lua new file mode 100644 index 00000000000..167719daf93 --- /dev/null +++ b/data/npc/scripts/jorge.lua @@ -0,0 +1,90 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local items = { + [1] = {name = "Abacus", id = 21467}, + [2] = {name = "Assassin Doll", id = 32594}, + [3] = {name = "Bag of Oriental Spices", id = 26338}, + [4] = {name = "Bookworm Doll", id = 32592}, + [5] = {name = "Cateroides Doll", id = 29217}, + [6] = {name = "Doll of Durin the Almighty", id = 26335}, + [7] = {name = "Dragon Eye", id = 24683}, + [8] = {name = "Dragon Goblet", id = 36100}, + [9] = {name = "Draken Doll", id = 29215}, + [10] = {name = "Encyclopedia", id = 26334}, + [11] = {name = "Friendship Amulet", id = 21469}, + [12] = {name = "Frozen Heart", id = 21472}, + [13] = {name = "Golden Falcon", id = 32593}, + [14] = {name = "Golden Newspaper", id = 26337}, + [15] = {name = "Hand Puppets", id = 26332}, + [16] = {name = "Imortus", id = 26339}, + [17] = {name = "Jade Amulet", id = 36103}, + [18] = {name = "Key of Numerous Locks", id = 21468}, + [19] = {name = "Loremaster Doll", id = 36102}, + [20] = {name = "Mathmaster Shield", id = 29218}, + [21] = {name = "Medusa Skull", id = 26336}, + [22] = {name = "Music Box", id = 26333}, + [23] = {name = "Noble Sword", id = 18551}, + [24] = {name = "Norsemal Doll", id = 21466}, + [25] = {name = "Old Radio", id = 32591}, + [26] = {name = "Orcs Jaw Shredder", id = 21471}, + [27] = {name = "Pigeon Trophy", id = 36101}, + [28] = {name = "Phoenix Statue", id = 24682}, + [29] = {name = "The Mexcalibur", id = 21470}, + [30] = {name = "TibiaHispano Emblem", id = 29216}, + [31] = {name = "Goromaphone", id = 39045} +} + +local function greetCallback(cid) + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msg then + for i = 1, #items do + if msgcontains(msg, items[i].name) then + if getPlayerItemCount(cid, 21400) >= 20 then + doPlayerRemoveItem(cid, 21400, 20) + doPlayerAddItem(cid, items[i].id, 1) + selfSay('You just swapped 20 silver raid tokens for 1 '.. getItemName(items[i].name) ..'.', cid) + else + selfSay('You need 20 silver raid tokens.', cid) + end + end + end + end + return true +end + +local function onAddFocus(cid) +end + +local function onReleaseFocus(cid) +end + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/jossel.lua b/data/npc/scripts/jossel.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/jossel.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/julian.lua b/data/npc/scripts/julian.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/julian.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/julius.lua b/data/npc/scripts/julius.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/julius.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/junkar_mines.lua b/data/npc/scripts/junkar_mines.lua new file mode 100644 index 00000000000..e9a3c4894ea --- /dev/null +++ b/data/npc/scripts/junkar_mines.lua @@ -0,0 +1,42 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'So much to do. So many things to be fixed.' }, + { text = 'Still so much work.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, cost, destination) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = text or 'So you wish for a trip to ' .. keyword:titleCase() .. '? |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, text = 'Full steam ahead!', cost = cost, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, then you stay here, simple as that.', reset = true}) +end + +addTravelKeyword('kazordoon', 10, Position(32660, 31957, 15)) +addTravelKeyword('thais', 90, Position(32370, 32180, 13)) +addTravelKeyword('robsons isle', 70, Position(32527, 32036, 14)) + +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want me to take you? To {Kazordoon}, {Thais} or to {Robsons Isle}?'}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome, |PLAYERNAME|! You are lucky that the service is running right now. Save your coal for the days to come though!") +npcHandler:setMessage(MESSAGE_FAREWELL, "See you next time!") +npcHandler:setMessage(MESSAGE_WALKAWAY, " No patience!") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/junkar_robsons.lua b/data/npc/scripts/junkar_robsons.lua new file mode 100644 index 00000000000..30635654b68 --- /dev/null +++ b/data/npc/scripts/junkar_robsons.lua @@ -0,0 +1,42 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'So much to do. So many things to be fixed.' }, + { text = 'Still so much work.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, cost, destination) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = text or 'So you wish for a trip to ' .. keyword:titleCase() .. '? |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, text = 'Full speed ahead!', cost = cost, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, then you stay here, simple as that.', reset = true}) +end + +addTravelKeyword('kazordoon', 80, Position(32660, 31957, 15)) +addTravelKeyword('thais', 80, Position(32370, 32180, 13)) +addTravelKeyword('mines', 70, Position(32555, 32069, 10)) + +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want me to take you? To {Kazordoon} or to {Thais}? Occasionally we can even reach the {mines} if they are cleared.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome, |PLAYERNAME|! You are lucky that the service is running right now. Save your coal for the days to come though!") +npcHandler:setMessage(MESSAGE_FAREWELL, "See you next time!") +npcHandler:setMessage(MESSAGE_WALKAWAY, " No patience!") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/junkar_thais.lua b/data/npc/scripts/junkar_thais.lua new file mode 100644 index 00000000000..80d39c22c20 --- /dev/null +++ b/data/npc/scripts/junkar_thais.lua @@ -0,0 +1,42 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'So much to do. So many things to be fixed.' }, + { text = 'Still so much work.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, cost, destination) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = text or 'So you wish for a trip to ' .. keyword:titleCase() .. '? |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, text = 'Full steam ahead!', cost = cost, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, then you stay here, simple as that.', reset = true}) +end + +addTravelKeyword('kazordoon', 100, Position(32660, 31957, 15)) +addTravelKeyword('robsons isle', 80, Position(32527, 32036, 14)) +addTravelKeyword('mines', 90, Position(32555, 32069, 10)) + +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want me to take you? To {Kazordoon} or to {Robsons Isle}? Occasionally we can even reach the {mines} if they are cleared.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome, |PLAYERNAME|! You are lucky that the service is running right now. Save your coal for the days to come though!") +npcHandler:setMessage(MESSAGE_FAREWELL, "See you next time!") +npcHandler:setMessage(MESSAGE_WALKAWAY, " No patience!") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/kais.lua b/data/npc/scripts/kais.lua new file mode 100644 index 00000000000..6f8e13f92c5 --- /dev/null +++ b/data/npc/scripts/kais.lua @@ -0,0 +1,72 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Blood of the Mountain +local blessKeyword = keywordHandler:addKeyword({'blood'}, StdModule.say, {npcHandler = npcHandler, text = 'Would you like to receive that protection for a sacrifice of |BLESSCOST| gold, child?'}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the Blood of the Mountain, pilgrim.', cost = '|BLESSCOST|', bless = 7}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, noble |PLAYERNAME|') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good Bye, noble |PLAYERNAME|') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good Bye, noble |PLAYERNAME|') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/kallimae.lua b/data/npc/scripts/kallimae.lua new file mode 100644 index 00000000000..d3228ef8a94 --- /dev/null +++ b/data/npc/scripts/kallimae.lua @@ -0,0 +1,106 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local playerTopic = {} +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.Kilmaresh.First.Access) < 1 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + playerTopic[cid] = 1 + elseif (player:getStorageValue(Storage.Kilmaresh.First.JamesfrancisTask) >= 0 and player:getStorageValue(Storage.Kilmaresh.First.JamesfrancisTask) <= 50) + and player:getStorageValue(Storage.Kilmaresh.First.Mission) < 3 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + playerTopic[cid] = 15 + elseif player:getStorageValue(Storage.Kilmaresh.First.Mission) == 4 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + player:setStorageValue(Storage.Kilmaresh.First.Mission, 5) + playerTopic[cid] = 20 + end + npcHandler:addFocus(cid) + return true +end + +local function creatureSayCallback(cid, type, msg) +if not npcHandler:isFocused(cid) then + return false +end +npcHandler.topic[cid] = playerTopic[cid] +local player = Player(cid) +if msgcontains(msg, "mission") and player:getStorageValue(Storage.Kilmaresh.Sixth.Favor) == 11 then + if player:getStorageValue(Storage.Kilmaresh.Sixth.Favor) == 11 then + npcHandler:say({"Some residents are in need of ingredients to finish a ritual. You can help?"}, cid)-- It needs to be revised, it's not the same as the global + npcHandler.topic[cid] = 1 + playerTopic[cid] = 1 + end +elseif msgcontains(msg, "yes") and playerTopic[cid] == 1 then + if player:getStorageValue(Storage.Kilmaresh.Sixth.Favor) == 11 then + npcHandler:say({"Search for the NPCs Yonan, Narsai, Shimun and Tefrit."}, cid)-- It needs to be revised, it's not the same as the global + player:setStorageValue(Storage.Kilmaresh.Set.Ritual, 1) + player:setStorageValue(Storage.Kilmaresh.Set.Yonan, 1) + player:setStorageValue(Storage.Kilmaresh.Set.Narsai, 1) + player:setStorageValue(Storage.Kilmaresh.Set.Shimun, 1) + player:setStorageValue(Storage.Kilmaresh.Set.Tefrit, 1) + player:setStorageValue(Storage.Kilmaresh.Sixth.Favor, 12) + npcHandler.topic[cid] = 2 + playerTopic[cid] = 2 + else + npcHandler:say({"Sorry."}, cid)-- It needs to be revised, it's not the same as the global + end +end +if msgcontains(msg, "mission") and player:getStorageValue(Storage.Kilmaresh.Eighth.Yonan) == 3 and player:getStorageValue(Storage.Kilmaresh.Eighth.Narsai) == 3 and player:getStorageValue(Storage.Kilmaresh.Eighth.Shimun) == 3 and player:getStorageValue(Storage.Kilmaresh.Eighth.Tefrit) == 3 then + if player:getStorageValue(Storage.Kilmaresh.Eighth.Yonan) == 3 and player:getStorageValue(Storage.Kilmaresh.Eighth.Narsai) == 3 and player:getStorageValue(Storage.Kilmaresh.Eighth.Shimun) == 3 and player:getStorageValue(Storage.Kilmaresh.Eighth.Tefrit) == 3 then + npcHandler:say({"Did you help some residents with ingredients?"}, cid)-- It needs to be revised, it's not the same as the global + npcHandler.topic[cid] = 3 + playerTopic[cid] = 3 + end +elseif msgcontains(msg, "yes") and playerTopic[cid] == 3 and player:getStorageValue(Storage.Kilmaresh.Eighth.Yonan) == 3 and player:getStorageValue(Storage.Kilmaresh.Eighth.Narsai) == 3 and player:getStorageValue(Storage.Kilmaresh.Eighth.Shimun) == 3 and player:getStorageValue(Storage.Kilmaresh.Eighth.Tefrit) == 3 then + if player:getStorageValue(Storage.Kilmaresh.Eighth.Yonan) == 3 and player:getStorageValue(Storage.Kilmaresh.Eighth.Narsai) == 3 and player:getStorageValue(Storage.Kilmaresh.Eighth.Shimun) == 3 and player:getStorageValue(Storage.Kilmaresh.Eighth.Tefrit) == 3 then + npcHandler:say({"Thanks. I need you to go to 4 places indicated by Goddess Bastesh."}, cid)-- It needs to be revised, it's not the same as the global + player:setStorageValue(Storage.Kilmaresh.Nine.Owl, 1) + npcHandler.topic[cid] = 4 + playerTopic[cid] = 4 + else + npcHandler:say({"Sorry."}, cid)-- It needs to be revised, it's not the same as the global + end +end +if msgcontains(msg, "mission") and player:getStorageValue(Storage.Kilmaresh.Eleven.Basin) == 1 then + if player:getStorageValue(Storage.Kilmaresh.Eleven.Basin) == 1 then + npcHandler:say({"Did you check all the points and bring the Symbol of Sun and Sea?"}, cid)-- It needs to be revised, it's not the same as the global + npcHandler.topic[cid] = 5 + playerTopic[cid] = 5 + end +elseif msgcontains(msg, "yes") and playerTopic[cid] == 5 and player:getStorageValue(Storage.Kilmaresh.Eleven.Basin) == 1 then + if player:getStorageValue(Storage.Kilmaresh.Eleven.Basin) == 1 and player:getItemById(36266, 1) then + player:addItem(36407, 1) + npcHandler:say({"Thanks. Here is your reward."}, cid)-- It needs to be revised, it's not the same as the global + player:setStorageValue(Storage.Kilmaresh.Twelve.Boss, 1) + player:setStorageValue(Storage.Kilmaresh.Eleven.Basin, 2) + npcHandler.topic[cid] = 6 + playerTopic[cid] = 6 + else + npcHandler:say({"Sorry."}, cid)-- It needs to be revised, it's not the same as the global + end +end +return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/kalvin.lua b/data/npc/scripts/kalvin.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/kalvin.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/karith.lua b/data/npc/scripts/karith.lua new file mode 100644 index 00000000000..cf0a884b11c --- /dev/null +++ b/data/npc/scripts/karith.lua @@ -0,0 +1,307 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local voices = { {text = 'This weather is killing me. If I only had enough money to retire.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) == -1 then + npcHandler:setMessage(MESSAGE_GREET, 'Hello! Tell me what\'s on your mind. Time is money.') + player:setStorageValue(Storage.SearoutesAroundYalahar.TownsCounter, 0) + else + npcHandler:setMessage(MESSAGE_GREET, 'Hello! Tell me what\'s on your mind. Time is money.') + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + +local player = Player(cid) + if msgcontains(msg, "passage") or msgcontains(msg, "sail") then + if player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) < 5 then + npcHandler:say({ + "I see no reason to establish ship routes to other cities. There is nothing that would be worth the effort. ...", + "But since you won\'t stop bugging me, let\'s make a deal: If you can prove that at least five of your so-called \'cities\' are not worthless, I might reconsider my position. ...", + "Bring me something SPECIAL! The local bar tenders usually know what\'s interesting about their city.", + }, cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) >= 5 then + npcHandler:say({ + "For the sake of profit, we established ship routes to {Ab\'Dendriel}, {Darashia}, {Venore}, {Ankrahmun}, {Port Hope}, {Thais}, {Liberty Bay} and {Carlin}.", + }, cid) + npcHandler.topic[cid] = 0 + else return false + end + elseif msgcontains(msg, "Ab\'Dendriel") then + if player:getStorageValue(Storage.SearoutesAroundYalahar.AbDendriel) ~= 1 and player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) < 5 then + npcHandler:say({ + "I\'ve never been there. I doubt the elves there came up with something noteworthy. Or did you find something interesting there?", + }, cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.SearoutesAroundYalahar.AbDendriel) == 1 or player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) >= 5 then + npcHandler:say({ + "Do you want a passage to Ab\'Dendriel for 160 gold?", ---missing line + }, cid) + npcHandler.topic[cid] = 11 + else return false + end + elseif msgcontains(msg, "Darashia") then + if player:getStorageValue(Storage.SearoutesAroundYalahar.Darashia) ~= 1 and player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) < 5 then + npcHandler:say({ + "From all what I have heard, it is an unremarkable pile of huts in the desert. Or did you find something interesting there?", + }, cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(Storage.SearoutesAroundYalahar.Darashia) == 1 or player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) >= 5 then + npcHandler:say({ + "Of course it is merely superstition that the darashian sand wasp honey brings back youth and vitality, but as long people pay a decent price, I couldn't care less. Do you want a passage to Darashia for 210 gold?", + }, cid) + npcHandler.topic[cid] = 12 + else return false + end + elseif msgcontains(msg, "Venore") then + if player:getStorageValue(Storage.SearoutesAroundYalahar.Venore) ~= 1 and player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) < 5 then + npcHandler:say({ + "Another port full of smelly humans, fittingly located in a swamp. Or did you find something interesting there?", + }, cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.SearoutesAroundYalahar.Venore) == 1 or player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) >= 5 then + npcHandler:say({"The swamp spice will turn out very lucrative considering that it helps to make even the most disgusting dish taste good. Do you want a passage to Venore for 185 gold?",}, cid) + npcHandler.topic[cid] = 13 + else return false + end + elseif msgcontains(msg, "Ankrahmun") then + if player:getStorageValue(Storage.SearoutesAroundYalahar.Ankrahmun) ~= 1 and player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) < 5 then + npcHandler:say({ + "A city full of mad death worshippers, no thanks. Or did you find something interesting there?", + }, cid) + npcHandler.topic[cid] = 4 + elseif player:getStorageValue(Storage.SearoutesAroundYalahar.Ankrahmun) == 1 or player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) >= 5 then + npcHandler:say({ + "The Yalahari seem to be obsessed with conserving their dead, so I guess the embalming fluid will be a great success in Yalahar. Do you want a passage to Ankrahmun for 230 gold?", + }, cid) + npcHandler.topic[cid] = 14 + else return false + end + elseif msgcontains(msg, "Port Hope") then + if player:getStorageValue(Storage.SearoutesAroundYalahar.PortHope) ~= 1 and player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) < 5 then + npcHandler:say({ + "Another pointless human settlement. Or did you find something interesting there?", + }, cid) + npcHandler.topic[cid] = 5 + elseif player:getStorageValue(Storage.SearoutesAroundYalahar.PortHope) == 1 or player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) >= 5 then + npcHandler:say({ + "Ivory is highly prized by the artisans of the Yalahari. Do you want a passage to Port Hope for 260 gold?", + }, cid) + npcHandler.topic[cid] = 15 + else return false + end + elseif msgcontains(msg, "Thais") then + if player:getStorageValue(Storage.SearoutesAroundYalahar.Thais) ~= 1 and player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) < 5 then + npcHandler:say({ + "Thais must be a hell hole if only half of the stories we hear about it are true. Or did you find something interesting there?", + }, cid) + npcHandler.topic[cid] = 6 + elseif player:getStorageValue(Storage.SearoutesAroundYalahar.Thais) == 1 or player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) >= 5 then + npcHandler:say({ + "Astonishing enough the royal satin seems to suit the exquisite taste of the Yalahari. Do you want a passage to Thais for 200 gold?", + }, cid) + npcHandler.topic[cid] = 16 + else return false + end + elseif msgcontains(msg, "Liberty Bay") then + if player:getStorageValue(Storage.SearoutesAroundYalahar.LibertyBay) ~= 1 and player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) < 5 then + npcHandler:say({ + "Which sane captain would sail his ship to a pirate town? Or did you find something interesting there?", + }, cid) + npcHandler.topic[cid] = 7 + elseif player:getStorageValue(Storage.SearoutesAroundYalahar.LibertyBay) == 1 or player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) >= 5 then + npcHandler:say({ + "Do you want a passage to Liberty Bay for 275 gold?", ---missing line + }, cid) + npcHandler.topic[cid] = 17 + else return false + end + elseif msgcontains(msg, "Carlin") then + if player:getStorageValue(Storage.SearoutesAroundYalahar.Carlin) ~= 1 and player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) < 5 then + npcHandler:say({ + "An unremarkable town compared to the wonders of Yalahar. Or did you find something interesting there?", + }, cid) + npcHandler.topic[cid] = 8 + elseif player:getStorageValue(Storage.SearoutesAroundYalahar.Carlin) == 1 or player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) >= 5 then + npcHandler:say({ + "The evergreen flower pots are an amusing item that might find some customers here. Do you want a passage to Carlin for 185 gold?", + }, cid) + npcHandler.topic[cid] = 18 + else return false + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 and player:removeItem(9674,1) then + npcHandler:say("What's that? Bug milk? Hm, perhaps I can find some customers for that! ", cid) + player:setStorageValue(Storage.SearoutesAroundYalahar.AbDendriel, 1) + player:setStorageValue(Storage.SearoutesAroundYalahar.TownsCounter, player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) + 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 and player:removeItem(9676,1) then + npcHandler:say("Sand wasp honey? Hm, interesting at least!", cid) + player:setStorageValue(Storage.SearoutesAroundYalahar.Darashia, 1) + player:setStorageValue(Storage.SearoutesAroundYalahar.TownsCounter, player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) + 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 and player:removeItem(9675,1) then + npcHandler:say("Some special spice might be of value indeed.", cid) + player:setStorageValue(Storage.SearoutesAroundYalahar.Venore, 1) + player:setStorageValue(Storage.SearoutesAroundYalahar.TownsCounter, player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) + 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 4 and player:removeItem(9677,1) then + npcHandler:say("I can hardly imagine that someone is interested in embalming fluid, but I\'ll give it a try.", cid) + player:setStorageValue(Storage.SearoutesAroundYalahar.Ankrahmun, 1) + player:setStorageValue(Storage.SearoutesAroundYalahar.TownsCounter, player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) + 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 5 and player:removeItem(3956,1) then + npcHandler:say("Of course! Ivory! Its value is quite obvious.", cid) + player:setStorageValue(Storage.SearoutesAroundYalahar.PortHope, 1) + player:setStorageValue(Storage.SearoutesAroundYalahar.TownsCounter, player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) + 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 6 and player:removeItem(9678,1) then + npcHandler:say("This royal satin is indeed of acceptable quality.", cid) + player:setStorageValue(Storage.SearoutesAroundYalahar.Thais, 1) + player:setStorageValue(Storage.SearoutesAroundYalahar.TownsCounter, player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) + 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 7 and player:removeItem(5553,1,27) then + npcHandler:say("I doubt that the esteemed Yalahari will indulge into something profane as rum. But who knows, I'll give it a try.", cid) + player:setStorageValue(Storage.SearoutesAroundYalahar.LibertyBay, 1) + player:setStorageValue(Storage.SearoutesAroundYalahar.TownsCounter, player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) + 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 8 and player:removeItem(11428,1) then + npcHandler:say("I doubt that these flowers will stay fresh and healthy forever. But if they do, they could be indeed valuable.", cid) + player:setStorageValue(Storage.SearoutesAroundYalahar.Carlin, 1) + player:setStorageValue(Storage.SearoutesAroundYalahar.TownsCounter, player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) + 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 11 then + if player:removeMoneyNpc(160) then + npcHandler:say("Set the sails!", cid) + doTeleportThing(cid, Position(32734, 31668, 6)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don\'t have enough money.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 12 then + if player:removeMoneyNpc(210) then + npcHandler:say("Set the sails!", cid) + doTeleportThing(cid, Position(33289, 32480, 6)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don\'t have enough money.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 13 then + if player:removeMoneyNpc(185) then + npcHandler:say("Set the sails!", cid) + doTeleportThing(cid, Position(32954, 32022, 6)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don\'t have enough money.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 14 then + if player:removeMoneyNpc(230) then + npcHandler:say("Set the sails!", cid) + doTeleportThing(cid, Position(33092, 32883, 6)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don\'t have enough money.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 15 then + if player:removeMoneyNpc(260) then + npcHandler:say("Set the sails!", cid) + doTeleportThing(cid, Position(32527, 32784, 6)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don\'t have enough money.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 16 then + if player:removeMoneyNpc(200) then + npcHandler:say("Set the sails!", cid) + doTeleportThing(cid, Position(32310, 32210, 6)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don\'t have enough money.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 17 then + if player:removeMoneyNpc(275) then + npcHandler:say("Set the sails!", cid) + doTeleportThing(cid, Position(32285, 32892, 6)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don\'t have enough money.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 18 then + if player:removeMoneyNpc(185) then + npcHandler:say("Set the sails!", cid) + doTeleportThing(cid, Position(32387, 31820, 6)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don\'t have enough money.", cid) + npcHandler.topic[cid] = 0 + end + else + npcHandler:say("Don\'t waste my time.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "no") then + npcHandler:say({"Then no.",}, cid) + npcHandler.topic[cid] = 0 + end +return true +end + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, destination = {Position(32811, 31267, 6), Position(32811, 31270, 6), Position(32811, 31273, 6)}}) + +-- Basic +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m Karith. I don\'t belong to a caste any longer, and only serve the Yalahari.'}) +keywordHandler:addKeyword({'yalahar'}, StdModule.say, {npcHandler = npcHandler, text = 'The city was a marvel to behold. It is certain that it have been the many foreigners that ruined it.'}) + +-- Greeting message +keywordHandler:addGreetKeyword({"ashari"}, {npcHandler = npcHandler, text = "Hello! Tell me what\'s on your mind. Time is money."}) +--Farewell message +keywordHandler:addFarewellKeyword({"asgha thrazi"}, {npcHandler = npcHandler, text = "Goodbye, |PLAYERNAME|."}) + +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.") + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/karl.lua b/data/npc/scripts/karl.lua new file mode 100644 index 00000000000..00a1bb18dbc --- /dev/null +++ b/data/npc/scripts/karl.lua @@ -0,0 +1,64 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, 'barrel') then + if player:getStorageValue(Storage.SecretService.AVINMission03) == 2 then + npcHandler:say('Do you bring me a barrel of beer??', cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, 'whisper beer') then + if player:getStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven) == 11 then + npcHandler:say('Do you want to buy a bottle of our finest whisper beer for 80 gold?', cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + if player:removeItem(7706, 1) then + player:setStorageValue(Storage.SecretService.AVINMission03, 3) + npcHandler:say('Three cheers for the noble |PLAYERNAME|.', cid) + else + npcHandler:say("You don't have any barrel of beer!", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + if player:getStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven) == 11 then + if player:removeMoneyNpc(80) then + npcHandler:say("Here. Don't take it into the city though.", cid) + player:setStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven, 12) + player:addItem(6106, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have enough money.", cid) + end + end + end + end + return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, "Please come back, but don't tell others.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Please come back, but don't tell others.") +npcHandler:setMessage(MESSAGE_GREET, 'Pshhhht! Not that loud ... but welcome.') +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/kasmir.lua b/data/npc/scripts/kasmir.lua new file mode 100644 index 00000000000..f4b7ea0d38b --- /dev/null +++ b/data/npc/scripts/kasmir.lua @@ -0,0 +1,108 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Twist of Fate +local blessKeyword = keywordHandler:addKeyword({'twist of fate'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'This is a special blessing I can bestow upon you once you have obtained at least one of the other blessings and which functions a bit differently. ...', + 'It only works when you\'re killed by other adventurers, which means that at least half of the damage leading to your death was caused by others, not by monsters or the environment. ...', + 'The {twist of fate} will not reduce the death penalty like the other blessings, but instead prevent you from losing your other blessings as well as the amulet of loss, should you wear one. It costs the same as the other blessings. ...', + 'Would you like to receive that protection for a sacrifice of |PVPBLESSCOST| gold, child?' + }}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the protection of the twist of fate, pilgrim.', cost = '|PVPBLESSCOST|', bless = 1}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Adventurer Stone +keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Keep your adventurer\'s stone well.'}, function(player) return player:getItemById(18559, true) end) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for free?'}, function(player) return player:getStorageValue(Storage.AdventurersGuild.FreeStone.Kasmir) ~= 1 end) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, nil, function(player) player:addItem(18559, 1) player:setStorageValue(Storage.AdventurersGuild.FreeStone.Kasmir, 1) end) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for 30 gold?'}) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, + function(player) return player:getMoney() + player:getBankBalance() >= 30 end, + function(player) if player:removeMoneyNpc(30) then player:addItem(18559, 1) end end + ) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, you don\'t have enough money.', reset = true}) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +-- Wooden Stake +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'I think you have forgotten to bring your stake, pilgrim.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 7 and player:getItemCount(5941) == 0 end) + +local stakeKeyword = keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes, I was informed what to do. Are you prepared to receive my line of the prayer?'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 7 end) + stakeKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'So receive my prayer: \'Let there be honour and humility\'. Now, bring your stake to Rahkem in Ankrahmun for the next line of the prayer. I will inform him what to do.', reset = true}, nil, + function(player) player:setStorageValue(Storage.FriendsandTraders.TheBlessedStake, 8) player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) end + ) + stakeKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'I will wait for you.', reset = true}) + +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You should visit Rahkem in Ankrahmun now, pilgrim.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 8 end) +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You already received my line of the prayer.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) > 8 end) +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'A blessed stake? That is a strange request. Maybe Quentin knows more, he is one of the oldest monks after all.'}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.'}, function(player) return player:hasBlessing(2) end) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin will provide you with the embrace of Tibia.'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, young |PLAYERNAME|! If you are heavily wounded or poisoned, I can {heal} you for free.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Remember: If you are heavily wounded or poisoned, I can heal you for free.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'May the gods bless you, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/kawill.lua b/data/npc/scripts/kawill.lua new file mode 100644 index 00000000000..e6cd711f685 --- /dev/null +++ b/data/npc/scripts/kawill.lua @@ -0,0 +1,57 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Kawill Blessing +local blessKeyword = keywordHandler:addKeyword({'spark of the phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The Spark of the Phoenix is given by me and by the great pyromancer in the nearby fire temple. Do you wish to receive my part of the Spark of the Phoenix?'}, function(player) return player:getStorageValue(Storage.KawillBlessing) ~= 1 end) + blessKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'So receive the blessing of the life-giving earth, pilgrim.', reset = true}, nil, function(player) player:setStorageValue(Storage.KawillBlessing, 1) player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) end) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Ok. If you don\'t want it...', reset = true}) + keywordHandler:addAliasKeyword({'spark'}) + keywordHandler:addAliasKeyword({'phoenix'}) + +-- Basic +keywordHandler:addKeyword({'god'}, StdModule.say, {npcHandler = npcHandler, text = 'The gods are treacherous and vain. They want to use us like they did in the past. Only the elements can be trusted, because all they want is for nature to run its set course.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the great geomancer of dwarvenkind.'}) +keywordHandler:addKeyword({'geomancer'}, StdModule.say, {npcHandler = npcHandler, text = 'We investigate the will of the earth. It is our duty to make sure things to work in their natural way.'}) +keywordHandler:addKeyword({'life'}, StdModule.say, {npcHandler = npcHandler, text = 'Life is born by earth and fed by earth.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'I am Kawill Marbleeye, Son of Earth, from the Molten Rock.'}) +keywordHandler:addKeyword({'quest'}, StdModule.say, {npcHandler = npcHandler, text = 'There\'s nothing I need, better ask others.'}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = 'Nice world in general. It\'s a shame there is so much water ruining the general impression.'}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = 'Time is not of importance.'}) +keywordHandler:addKeyword({'monsters'}, StdModule.say, {npcHandler = npcHandler, text = 'May the earth swallow them all!'}) +keywordHandler:addKeyword({'excalibug'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, a weapon to be feared by man, beast and god alike, jawoll. He who wields it will be both blessed and cursed at the same time.'}) +keywordHandler:addKeyword({'ferumbras'}, StdModule.say, {npcHandler = npcHandler, text = 'The day will come when he finally bites the dust.'}) +keywordHandler:addKeyword({'kazordoon'}, StdModule.say, {npcHandler = npcHandler, text = 'By using the powers of fire and earth we forced the river that once wound its way through the big old one in other directions, and created our home.'}) +keywordHandler:addKeyword({'bezil'}, StdModule.say, {npcHandler = npcHandler, text = 'Bezil and Nezil have pawn and equpiment shop with an amazing stock.'}) +keywordHandler:addKeyword({'nezil'}, StdModule.say, {npcHandler = npcHandler, text = 'Bezil and Nezil have pawn and equpiment shop with an amazing stock.'}) +keywordHandler:addKeyword({'duria'}, StdModule.say, {npcHandler = npcHandler, text = 'The first knight of dwarvenkind is a fine woman.'}) +keywordHandler:addKeyword({'etzel'}, StdModule.say, {npcHandler = npcHandler, text = 'I fear the sorcerers focus on the destructive forces of fire. They forget about the protection earth could provide.'}) +keywordHandler:addKeyword({'jimbin'}, StdModule.say, {npcHandler = npcHandler, text = 'He is a jolly fellow and one of the oldest dwarves alive.'}) +keywordHandler:addKeyword({'kroox'}, StdModule.say, {npcHandler = npcHandler, text = 'He is a fine smith and his armour may save your neck one day.'}) +keywordHandler:addKeyword({'maryza'}, StdModule.say, {npcHandler = npcHandler, text = 'She is a fine cook, jawoll.'}) +keywordHandler:addKeyword({'uzgod'}, StdModule.say, {npcHandler = npcHandler, text = 'Uzgod is a blacksmith and understands the ways of his element well.'}) +keywordHandler:addKeyword({'kruzak'}, StdModule.say, {npcHandler = npcHandler, text = 'The emperor has rarely visited the temple district in the last years. He should care more about spirituality then about politics. Jawoll.'}) +keywordHandler:addKeyword({'emperor'}, StdModule.say, {npcHandler = npcHandler, text = 'The emperor has rarely visited the temple district in the last years. He should care more about spirituality then about politics. Jawoll.'}) +keywordHandler:addKeyword({'durin'}, StdModule.say, {npcHandler = npcHandler, text = 'The celestial paladin, the protector of our race. The only divine being we care for and the only one who still cares for dwarfs.'}) +keywordHandler:addKeyword({'fire'}, StdModule.say, {npcHandler = npcHandler, text = 'Where earth is giving, fire is taking. That is the way of the elements.'}) +keywordHandler:addKeyword({'earth'}, StdModule.say, {npcHandler = npcHandler, text = 'The lifegiving earth protects us, feeds us and takes us home after death.'}) +keywordHandler:addKeyword({'the big old one'}, StdModule.say, {npcHandler = npcHandler, text = 'The mountain we live in is called the big old one. It\'s the mountain of mountains, and it isand like a friend and protector to our race.'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome |PLAYERNAME|! May earth protect you!') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Earth under your feet, |PLAYERNAME|!') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Earth under your feet, pilgrim. What brings you here?') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/kaya.lua b/data/npc/scripts/kaya.lua new file mode 100644 index 00000000000..3d19a87ca12 --- /dev/null +++ b/data/npc/scripts/kaya.lua @@ -0,0 +1,649 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +local count = {} +local transfer = {} + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Don\'t forget to deposit your money here in the Tibian Bank before you head out for adventure.'} } +if VoiceModule then + npcHandler:addModule(VoiceModule:new(voices)) +end +--------------------------------guild bank----------------------------------------------- +local receiptFormat = 'Date: %s\nType: %s\nGold Amount: %d\nReceipt Owner: %s\nRecipient: %s\n\n%s' +local function getReceipt(info) + local receipt = Game.createItem(info.success and 24301 or 24302) + receipt:setAttribute(ITEM_ATTRIBUTE_TEXT, receiptFormat:format(os.date('%d. %b %Y - %H:%M:%S'), info.type, info.amount, info.owner, info.recipient, info.message)) + + return receipt +end + +local function getGuildIdByName(name, func) + db.asyncStoreQuery('SELECT `id` FROM `guilds` WHERE `name` = ' .. db.escapeString(name), + function(resultId) + if resultId then + func(result.getNumber(resultId, 'id')) + result.free(resultId) + else + func(nil) + end + end + ) +end + +local function getGuildBalance(id) + local guild = Guild(id) + if guild then + return guild:getBankBalance() + else + local balance + local resultId = db.storeQuery('SELECT `balance` FROM `guilds` WHERE `id` = ' .. id) + if resultId then + balance = result.getNumber(resultId, 'balance') + result.free(resultId) + end + + return balance + end +end + +local function setGuildBalance(id, balance) + local guild = Guild(id) + if guild then + guild:setBankBalance(balance) + else + db.query('UPDATE `guilds` SET `balance` = ' .. balance .. ' WHERE `id` = ' .. id) + end +end + +local function transferFactory(playerName, amount, fromGuildId, info) + return function(toGuildId) + if not toGuildId then + local player = Player(playerName) + if player then + info.success = false + info.message = 'We are sorry to inform you that we could not fulfil your request, because we could not find the recipient guild.' + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + end + else + local fromBalance = getGuildBalance(fromGuildId) + if fromBalance < amount then + info.success = false + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your guild account.' + else + info.success = true + info.message = 'We are happy to inform you that your transfer request was successfully carried out.' + setGuildBalance(fromGuildId, fromBalance - amount) + setGuildBalance(toGuildId, getGuildBalance(toGuildId) + amount) + end + + local player = Player(playerName) + if player then + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + end + end + end +end +--------------------------------guild bank----------------------------------------------- + +local function greetCallback(cid) + count[cid], transfer[cid] = nil, nil + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) +---------------------------- help ------------------------ + if msgcontains(msg, 'bank account') then + npcHandler:say({ + 'Every Tibian has one. The big advantage is that you can access your money in every branch of the Tibian Bank! ...', + 'Would you like to know more about the {basic} functions of your bank account, the {advanced} functions, or are you already bored, perhaps?' + }, cid) + npcHandler.topic[cid] = 0 + return true +---------------------------- balance --------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild balance') then + npcHandler.topic[cid] = 0 + if not player:getGuild() then + npcHandler:say('You are not a member of a guild.', cid) + return false + end + npcHandler:say('Your guild account balance is ' .. player:getGuild():getBankBalance() .. ' gold.', cid) + return true +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'balance') then + npcHandler.topic[cid] = 0 + if player:getBankBalance() >= 100000000 then + npcHandler:say('I think you must be one of the richest inhabitants in the world! Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + elseif player:getBankBalance() >= 10000000 then + npcHandler:say('You have made ten millions and it still grows! Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + elseif player:getBankBalance() >= 1000000 then + npcHandler:say('Wow, you have reached the magic number of a million gp!!! Your account balance is ' .. player:getBankBalance() .. ' gold!', cid) + return true + elseif player:getBankBalance() >= 100000 then + npcHandler:say('You certainly have made a pretty penny. Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + else + npcHandler:say('Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + end +---------------------------- deposit --------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild deposit') then + if not player:getGuild() then + npcHandler:say('You are not a member of a guild.', cid) + npcHandler.topic[cid] = 0 + return false + end + -- count[cid] = player:getMoney() + -- if count[cid] < 1 then + -- npcHandler:say('You do not have enough gold.', cid) + -- npcHandler.topic[cid] = 0 + -- return false + --end + if string.match(msg, '%d+') then + count[cid] = getMoneyCount(msg) + if count[cid] < 1 then + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return false + end + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold to your {guild account}?', cid) + npcHandler.topic[cid] = 23 + return true + else + npcHandler:say('Please tell me how much gold it is you would like to deposit.', cid) + npcHandler.topic[cid] = 22 + return true + end + elseif npcHandler.topic[cid] == 22 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold to your {guild account}?', cid) + npcHandler.topic[cid] = 23 + return true + else + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return true + end + elseif npcHandler.topic[cid] == 23 then + if msgcontains(msg, 'yes') then + npcHandler:say('Alright, we have placed an order to deposit the amount of ' .. count[cid] .. ' gold to your guild account. Please check your inbox for confirmation.', cid) + local guild = player:getGuild() + local info = { + type = 'Guild Deposit', + amount = count[cid], + owner = player:getName() .. ' of ' .. guild:getName(), + recipient = guild:getName() + } + local playerBalance = player:getBankBalance() + if playerBalance < tonumber(count[cid]) then + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your bank account.' + info.success = false + else + info.message = 'We are happy to inform you that your transfer request was successfully carried out.' + info.success = true + guild:setBankBalance(guild:getBankBalance() + tonumber(count[cid])) + player:setBankBalance(playerBalance - tonumber(count[cid])) + end + + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish. Is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 + return true +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'deposit') then + count[cid] = player:getMoney() + if count[cid] < 1 then + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return false + end + if msgcontains(msg, 'all') then + count[cid] = player:getMoney() + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid) + npcHandler.topic[cid] = 2 + return true + else + if string.match(msg,'%d+') then + count[cid] = getMoneyCount(msg) + if count[cid] < 1 then + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return false + end + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid) + npcHandler.topic[cid] = 2 + return true + else + npcHandler:say('Please tell me how much gold it is you would like to deposit.', cid) + npcHandler.topic[cid] = 1 + return true + end + end + if not isValidMoney(count[cid]) then + npcHandler:say('Sorry, but you can\'t deposit that much.', cid) + npcHandler.topic[cid] = 0 + return false + end + elseif npcHandler.topic[cid] == 1 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid) + npcHandler.topic[cid] = 2 + return true + else + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return true + end + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, 'yes') then + if player:depositMoney(count[cid]) then + npcHandler:say('Alright, we have added the amount of ' .. count[cid] .. ' gold to your {balance}. You can {withdraw} your money anytime you want to.', cid) + else + npcHandler:say('You do not have enough gold.', cid) + end + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish. Is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 + return true +---------------------------- withdraw -------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild withdraw') then + if not player:getGuild() then + npcHandler:say('I am sorry but it seems you are currently not in any guild.', cid) + npcHandler.topic[cid] = 0 + return false + elseif player:getGuildLevel() < 2 then + npcHandler:say('Only guild leaders or vice leaders can withdraw money from the guild account.', cid) + npcHandler.topic[cid] = 0 + return false + end + + if string.match(msg,'%d+') then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your guild account?', cid) + npcHandler.topic[cid] = 25 + else + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + end + return true + else + npcHandler:say('Please tell me how much gold you would like to withdraw from your guild account.', cid) + npcHandler.topic[cid] = 24 + return true + end + elseif npcHandler.topic[cid] == 24 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your guild account?', cid) + npcHandler.topic[cid] = 25 + else + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + end + return true + elseif npcHandler.topic[cid] == 25 then + if msgcontains(msg, 'yes') then + local guild = player:getGuild() + local balance = guild:getBankBalance() + npcHandler:say('We placed an order to withdraw ' .. count[cid] .. ' gold from your guild account. Please check your inbox for confirmation.', cid) + local info = { + type = 'Guild Withdraw', + amount = count[cid], + owner = player:getName() .. ' of ' .. guild:getName(), + recipient = player:getName() + } + if balance < tonumber(count[cid]) then + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your guild account.' + info.success = false + else + info.message = 'We are happy to inform you that your transfer request was successfully carried out.' + info.success = true + guild:setBankBalance(balance - tonumber(count[cid])) + local playerBalance = player:getBankBalance() + player:setBankBalance(playerBalance + tonumber(count[cid])) + end + + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish. Is there something else I can do for you?', cid) + npcHandler.topic[cid] = 0 + end + return true +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'withdraw') then + if string.match(msg,'%d+') then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your bank account?', cid) + npcHandler.topic[cid] = 7 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + return true + else + npcHandler:say('Please tell me how much gold you would like to withdraw.', cid) + npcHandler.topic[cid] = 6 + return true + end + elseif npcHandler.topic[cid] == 6 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your bank account?', cid) + npcHandler.topic[cid] = 7 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + return true + elseif npcHandler.topic[cid] == 7 then + if msgcontains(msg, 'yes') then + if player:getFreeCapacity() >= getMoneyWeight(count[cid]) then + if not player:withdrawMoney(count[cid]) then + npcHandler:say('There is not enough gold on your account.', cid) + else + npcHandler:say('Here you are, ' .. count[cid] .. ' gold. Please let me know if there is something else I can do for you.', cid) + end + else + npcHandler:say('Whoah, hold on, you have no room in your inventory to carry all those coins. I don\'t want you to drop it on the floor, maybe come back with a cart!', cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') then + npcHandler:say('The customer is king! Come back anytime you want to if you wish to {withdraw} your money.', cid) + npcHandler.topic[cid] = 0 + end + return true +---------------------------- transfer -------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild transfer') then + if not player:getGuild() then + npcHandler:say('I am sorry but it seems you are currently not in any guild.', cid) + npcHandler.topic[cid] = 0 + return false + elseif player:getGuildLevel() < 2 then + npcHandler:say('Only guild leaders or vice leaders can transfer money from the guild account.', cid) + npcHandler.topic[cid] = 0 + return false + end + + if string.match(msg, '%d+') then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + transfer[cid] = string.match(msg, 'to%s*(.+)$') + if transfer[cid] then + npcHandler:say('So you would like to transfer ' .. count[cid] .. ' gold from your guild account to guild ' .. transfer[cid] .. '?', cid) + npcHandler.topic[cid] = 28 + else + npcHandler:say('Which guild would you like to transfer ' .. count[cid] .. ' gold to?', cid) + npcHandler.topic[cid] = 27 + end + else + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + end + else + npcHandler:say('Please tell me the amount of gold you would like to transfer.', cid) + npcHandler.topic[cid] = 26 + end + return true + elseif npcHandler.topic[cid] == 26 then + count[cid] = getMoneyCount(msg) + if player:getGuild():getBankBalance() < count[cid] then + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + return true + end + if isValidMoney(count[cid]) then + npcHandler:say('Which guild would you like to transfer ' .. count[cid] .. ' gold to?', cid) + npcHandler.topic[cid] = 27 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + return true + elseif npcHandler.topic[cid] == 27 then + transfer[cid] = msg + if player:getGuild():getName() == transfer[cid] then + npcHandler:say('Fill in this field with person who receives your gold!', cid) + npcHandler.topic[cid] = 0 + return true + end + npcHandler:say('So you would like to transfer ' .. count[cid] .. ' gold from your guild account to guild ' .. transfer[cid] .. '?', cid) + npcHandler.topic[cid] = 28 + return true + elseif npcHandler.topic[cid] == 28 then + if msgcontains(msg, 'yes') then + npcHandler:say('We have placed an order to transfer ' .. count[cid] .. ' gold from your guild account to guild ' .. transfer[cid] .. '. Please check your inbox for confirmation.', cid) + local guild = player:getGuild() + local balance = guild:getBankBalance() + local info = { + type = 'Guild to Guild Transfer', + amount = count[cid], + owner = player:getName() .. ' of ' .. guild:getName(), + recipient = transfer[cid] + } + if balance < tonumber(count[cid]) then + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your guild account.' + info.success = false + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + else + getGuildIdByName(transfer[cid], transferFactory(player:getName(), tonumber(count[cid]), guild:getId(), info)) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') then + npcHandler:say('Alright, is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'transfer') then + npcHandler:say('Please tell me the amount of gold you would like to transfer.', cid) + npcHandler.topic[cid] = 11 + elseif npcHandler.topic[cid] == 11 then + count[cid] = getMoneyCount(msg) + if player:getBankBalance() < count[cid] then + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + return true + end + if isValidMoney(count[cid]) then + npcHandler:say('Who would you like transfer ' .. count[cid] .. ' gold to?', cid) + npcHandler.topic[cid] = 12 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 12 then + transfer[cid] = msg + if player:getName() == transfer[cid] then + npcHandler:say('Fill in this field with person who receives your gold!', cid) + npcHandler.topic[cid] = 0 + return true + end + if playerExists(transfer[cid]) then + local arrayDenied = {"accountmanager", "rooksample", "druidsample", "sorcerersample", "knightsample", "paladinsample"} + if isInArray(arrayDenied, string.gsub(transfer[cid]:lower(), " ", "")) then + npcHandler:say('This player does not exist.', cid) + npcHandler.topic[cid] = 0 + return true + end + npcHandler:say('So you would like to transfer ' .. count[cid] .. ' gold to ' .. transfer[cid] .. '?', cid) + npcHandler.topic[cid] = 13 + else + npcHandler:say('This player does not exist.', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 13 then + if msgcontains(msg, 'yes') then + if not player:transferMoneyTo(transfer[cid], count[cid]) then + npcHandler:say('You cannot transfer money to this account.', cid) + else + npcHandler:say('Very well. You have transferred ' .. count[cid] .. ' gold to ' .. transfer[cid] ..'.', cid) + transfer[cid] = nil + end + elseif msgcontains(msg, 'no') then + npcHandler:say('Alright, is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 +---------------------------- money exchange -------------- + elseif msgcontains(msg, 'change gold') then + npcHandler:say('How many platinum coins would you like to get?', cid) + npcHandler.topic[cid] = 14 + elseif npcHandler.topic[cid] == 14 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough gold coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] * 100 .. ' of your gold coins into ' .. count[cid] .. ' platinum coins?', cid) + npcHandler.topic[cid] = 15 + end + elseif npcHandler.topic[cid] == 15 then + if msgcontains(msg, 'yes') then + if player:removeItem(2148, count[cid] * 100) then + player:addItem(2152, count[cid]) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough gold coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'change platinum') then + npcHandler:say('Would you like to change your platinum coins into gold or crystal?', cid) + npcHandler.topic[cid] = 16 + elseif npcHandler.topic[cid] == 16 then + if msgcontains(msg, 'gold') then + npcHandler:say('How many platinum coins would you like to change into gold?', cid) + npcHandler.topic[cid] = 17 + elseif msgcontains(msg, 'crystal') then + npcHandler:say('How many crystal coins would you like to get?', cid) + npcHandler.topic[cid] = 19 + else + npcHandler:say('Well, can I help you with something else?', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 17 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] .. ' of your platinum coins into ' .. count[cid] * 100 .. ' gold coins for you?', cid) + npcHandler.topic[cid] = 18 + end + elseif npcHandler.topic[cid] == 18 then + if msgcontains(msg, 'yes') then + if player:removeItem(2152, count[cid]) then + player:addItem(2148, count[cid] * 100) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 19 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] * 100 .. ' of your platinum coins into ' .. count[cid] .. ' crystal coins for you?', cid) + npcHandler.topic[cid] = 20 + end + elseif npcHandler.topic[cid] == 20 then + if msgcontains(msg, 'yes') then + if player:removeItem(2152, count[cid] * 100) then + player:addItem(2160, count[cid]) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'change crystal') then + npcHandler:say('How many crystal coins would you like to change into platinum?', cid) + npcHandler.topic[cid] = 21 + elseif npcHandler.topic[cid] == 21 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough crystal coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] .. ' of your crystal coins into ' .. count[cid] * 100 .. ' platinum coins for you?', cid) + npcHandler.topic[cid] = 22 + end + elseif npcHandler.topic[cid] == 22 then + if msgcontains(msg, 'yes') then + if player:removeItem(2160, count[cid]) then + player:addItem(2152, count[cid] * 100) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough crystal coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'money'}, StdModule.say, {npcHandler = npcHandler, text = 'We can {change} money for you. You can also access your {bank account}.'}) +keywordHandler:addKeyword({'change'}, StdModule.say, {npcHandler = npcHandler, text = 'There are three different coin types in Tibia: 100 gold coins equal 1 platinum coin, 100 platinum coins equal 1 crystal coin. So if you\'d like to change 100 gold into 1 platinum, simply say \'{change gold}\' and then \'1 platinum\'.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'We can {change} money for you. You can also access your {bank account}.'}) +keywordHandler:addKeyword({'advanced'}, StdModule.say, {npcHandler = npcHandler, text = 'Your bank account will be used automatically when you want to {rent} a house or place an offer on an item on the {market}. Let me know if you want to know about how either one works.'}) +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'You can check the {balance} of your bank account, {deposit} money or {withdraw} it. You can also {transfer} money to other characters, provided that they have a vocation.'}) +keywordHandler:addKeyword({'functions'}, StdModule.say, {npcHandler = npcHandler, text = 'You can check the {balance} of your bank account, {deposit} money or {withdraw} it. You can also {transfer} money to other characters, provided that they have a vocation.'}) +keywordHandler:addKeyword({'basic'}, StdModule.say, {npcHandler = npcHandler, text = 'You can check the {balance} of your bank account, {deposit} money or {withdraw} it. You can also {transfer} money to other characters, provided that they have a vocation.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I work in this bank. I can change money for you and help you with your bank account.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Yes? What may I do for you, |PLAYERNAME|? Bank business, perhaps?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Have a nice day.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Have a nice day.") +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/kazzan.lua b/data/npc/scripts/kazzan.lua new file mode 100644 index 00000000000..04ebc47538c --- /dev/null +++ b/data/npc/scripts/kazzan.lua @@ -0,0 +1,77 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + npcHandler.topic[cid] = 0 + return true +end + + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + -- Pegando a quest + if msgcontains(msg, "mission") and player:getStorageValue(Storage.TibiaTales.ToAppeaseTheMightyQuest) < 1 then + if player:getStorageValue(Storage.DjinnWar.Faction.MaridDoor) < 1 and player:getStorageValue(Storage.DjinnWar.Faction.EfreetDoor) < 1 then + npcHandler:say({ + 'Do you know the location of the djinn fortresses in the mountains south of here?'}, cid) + npcHandler.topic[cid] = 1 + end + elseif npcHandler.topic[cid] == 1 and msgcontains(msg, "yes") then + npcHandler:say({ + 'Alright. The problem is that I want to know at least one of them on my side. You never know. I don\'t mind if it\'s the evil Efreet or the Marid. ...', + 'Your mission will be to visit one kind of the djinns and bring them a peace-offering. Are you interested in that mission?' + }, cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 and msgcontains(msg, "yes") then + npcHandler:say({ + 'Very good. I hope you are able to convince one of the fractions to stand on our side. If you haven\'t done yet, you should first go and look for old Melchior in Ankrahmun. ...', + 'He knows many things about the djinn race and he may have some hints for you.' + }, cid) + if player:getStorageValue(Storage.TibiaTales.DefaultStart) <= 0 then + player:setStorageValue(Storage.TibiaTales.DefaultStart, 1) + end + player:setStorageValue(Storage.TibiaTales.ToAppeaseTheMightyQuest, 1) + -- Entregando + elseif player:getStorageValue(Storage.TibiaTales.ToAppeaseTheMightyQuest) == 3 then + npcHandler:say({ + 'Well, I don\'t blame you for that. I am sure you did your best. Now we can just hope that peace remains. Here, take this small gratification for your effort to help and Daraman may bless you!' + }, cid) + player:setStorageValue(Storage.TibiaTales.ToAppeaseTheMightyQuest, player:getStorageValue(Storage.TibiaTales.ToAppeaseTheMightyQuest) + 1) + player:addItem(2152, 20) +end + + if player:getStorageValue(Storage.WhatAFoolish.Questline) == 35 + and player:getStorageValue(Storage.WhatAFoolish.ScaredKazzan) ~= 1 + and player:getOutfit().lookType == 65 then + player:setStorageValue(Storage.WhatAFoolish.ScaredKazzan, 1) + npcHandler:say('WAAAAAHHH!!!', cid) + return false + end + return true +end + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/kendra.lua b/data/npc/scripts/kendra.lua new file mode 100644 index 00000000000..7bf7e54d160 --- /dev/null +++ b/data/npc/scripts/kendra.lua @@ -0,0 +1,48 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Passages to Thais'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, cost, destination, action, condition) + if condition then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sorry but I don\'t sail there.'}, condition) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = true, cost = cost, discount = 'postman', destination = destination}, nil, action) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('thais', 180, Position(32259, 32262, 7)) + +-- Kick +--keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, destination = {Position(32320, 32219, 6), Position(32321, 32210, 6)}}) + +-- Basic +keywordHandler:addKeyword({'passenger'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to welcome you on board.'}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Thais}'}) +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Thais}'}) +keywordHandler:addKeyword({'go'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Thais}'}) +keywordHandler:addKeyword({'Thais'}, StdModule.say, {npcHandler = npcHandler, text = 'This is Thais. Where do you want to go?'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome on board, |PLAYERNAME|. Where can I {sail} you today?') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye. Recommend us if you were satisfied with our service.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye then.') + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/kendra_thais.lua b/data/npc/scripts/kendra_thais.lua new file mode 100644 index 00000000000..cd162a1d773 --- /dev/null +++ b/data/npc/scripts/kendra_thais.lua @@ -0,0 +1,49 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Passages to Nostalgia'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, cost, destination, action, condition) + if condition then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sorry but I don\'t sail there.'}, condition) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = true, cost = cost, discount = 'postman', destination = destination}, nil, action) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('nostalgia', 180, Position(33494, 31059, 7)) + +-- Kick +--keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, destination = {Position(32320, 32219, 6), Position(32321, 32210, 6)}}) + +-- Basic +keywordHandler:addKeyword({'passenger'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to welcome you on board.'}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Nostalgia}, {Horror Village}'}) +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Nostalgia}, {Horror Village}'}) +keywordHandler:addKeyword({'go'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Nostalgia}, {Horror Village}'}) +keywordHandler:addKeyword({'Nostalgia'}, StdModule.say, {npcHandler = npcHandler, text = 'This is Nostalgia. Where do you want to go?'}) +keywordHandler:addKeyword({'Horror Village'}, StdModule.say, {npcHandler = npcHandler, text = 'This is Horror Village. Where do you want to go?'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome on board, |PLAYERNAME|. Where can I {sail} you today?') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye. Recommend us if you were satisfied with our service.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye then.') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/kepar.lua b/data/npc/scripts/kepar.lua new file mode 100644 index 00000000000..3d19a87ca12 --- /dev/null +++ b/data/npc/scripts/kepar.lua @@ -0,0 +1,649 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +local count = {} +local transfer = {} + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Don\'t forget to deposit your money here in the Tibian Bank before you head out for adventure.'} } +if VoiceModule then + npcHandler:addModule(VoiceModule:new(voices)) +end +--------------------------------guild bank----------------------------------------------- +local receiptFormat = 'Date: %s\nType: %s\nGold Amount: %d\nReceipt Owner: %s\nRecipient: %s\n\n%s' +local function getReceipt(info) + local receipt = Game.createItem(info.success and 24301 or 24302) + receipt:setAttribute(ITEM_ATTRIBUTE_TEXT, receiptFormat:format(os.date('%d. %b %Y - %H:%M:%S'), info.type, info.amount, info.owner, info.recipient, info.message)) + + return receipt +end + +local function getGuildIdByName(name, func) + db.asyncStoreQuery('SELECT `id` FROM `guilds` WHERE `name` = ' .. db.escapeString(name), + function(resultId) + if resultId then + func(result.getNumber(resultId, 'id')) + result.free(resultId) + else + func(nil) + end + end + ) +end + +local function getGuildBalance(id) + local guild = Guild(id) + if guild then + return guild:getBankBalance() + else + local balance + local resultId = db.storeQuery('SELECT `balance` FROM `guilds` WHERE `id` = ' .. id) + if resultId then + balance = result.getNumber(resultId, 'balance') + result.free(resultId) + end + + return balance + end +end + +local function setGuildBalance(id, balance) + local guild = Guild(id) + if guild then + guild:setBankBalance(balance) + else + db.query('UPDATE `guilds` SET `balance` = ' .. balance .. ' WHERE `id` = ' .. id) + end +end + +local function transferFactory(playerName, amount, fromGuildId, info) + return function(toGuildId) + if not toGuildId then + local player = Player(playerName) + if player then + info.success = false + info.message = 'We are sorry to inform you that we could not fulfil your request, because we could not find the recipient guild.' + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + end + else + local fromBalance = getGuildBalance(fromGuildId) + if fromBalance < amount then + info.success = false + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your guild account.' + else + info.success = true + info.message = 'We are happy to inform you that your transfer request was successfully carried out.' + setGuildBalance(fromGuildId, fromBalance - amount) + setGuildBalance(toGuildId, getGuildBalance(toGuildId) + amount) + end + + local player = Player(playerName) + if player then + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + end + end + end +end +--------------------------------guild bank----------------------------------------------- + +local function greetCallback(cid) + count[cid], transfer[cid] = nil, nil + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) +---------------------------- help ------------------------ + if msgcontains(msg, 'bank account') then + npcHandler:say({ + 'Every Tibian has one. The big advantage is that you can access your money in every branch of the Tibian Bank! ...', + 'Would you like to know more about the {basic} functions of your bank account, the {advanced} functions, or are you already bored, perhaps?' + }, cid) + npcHandler.topic[cid] = 0 + return true +---------------------------- balance --------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild balance') then + npcHandler.topic[cid] = 0 + if not player:getGuild() then + npcHandler:say('You are not a member of a guild.', cid) + return false + end + npcHandler:say('Your guild account balance is ' .. player:getGuild():getBankBalance() .. ' gold.', cid) + return true +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'balance') then + npcHandler.topic[cid] = 0 + if player:getBankBalance() >= 100000000 then + npcHandler:say('I think you must be one of the richest inhabitants in the world! Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + elseif player:getBankBalance() >= 10000000 then + npcHandler:say('You have made ten millions and it still grows! Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + elseif player:getBankBalance() >= 1000000 then + npcHandler:say('Wow, you have reached the magic number of a million gp!!! Your account balance is ' .. player:getBankBalance() .. ' gold!', cid) + return true + elseif player:getBankBalance() >= 100000 then + npcHandler:say('You certainly have made a pretty penny. Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + else + npcHandler:say('Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + end +---------------------------- deposit --------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild deposit') then + if not player:getGuild() then + npcHandler:say('You are not a member of a guild.', cid) + npcHandler.topic[cid] = 0 + return false + end + -- count[cid] = player:getMoney() + -- if count[cid] < 1 then + -- npcHandler:say('You do not have enough gold.', cid) + -- npcHandler.topic[cid] = 0 + -- return false + --end + if string.match(msg, '%d+') then + count[cid] = getMoneyCount(msg) + if count[cid] < 1 then + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return false + end + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold to your {guild account}?', cid) + npcHandler.topic[cid] = 23 + return true + else + npcHandler:say('Please tell me how much gold it is you would like to deposit.', cid) + npcHandler.topic[cid] = 22 + return true + end + elseif npcHandler.topic[cid] == 22 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold to your {guild account}?', cid) + npcHandler.topic[cid] = 23 + return true + else + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return true + end + elseif npcHandler.topic[cid] == 23 then + if msgcontains(msg, 'yes') then + npcHandler:say('Alright, we have placed an order to deposit the amount of ' .. count[cid] .. ' gold to your guild account. Please check your inbox for confirmation.', cid) + local guild = player:getGuild() + local info = { + type = 'Guild Deposit', + amount = count[cid], + owner = player:getName() .. ' of ' .. guild:getName(), + recipient = guild:getName() + } + local playerBalance = player:getBankBalance() + if playerBalance < tonumber(count[cid]) then + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your bank account.' + info.success = false + else + info.message = 'We are happy to inform you that your transfer request was successfully carried out.' + info.success = true + guild:setBankBalance(guild:getBankBalance() + tonumber(count[cid])) + player:setBankBalance(playerBalance - tonumber(count[cid])) + end + + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish. Is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 + return true +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'deposit') then + count[cid] = player:getMoney() + if count[cid] < 1 then + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return false + end + if msgcontains(msg, 'all') then + count[cid] = player:getMoney() + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid) + npcHandler.topic[cid] = 2 + return true + else + if string.match(msg,'%d+') then + count[cid] = getMoneyCount(msg) + if count[cid] < 1 then + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return false + end + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid) + npcHandler.topic[cid] = 2 + return true + else + npcHandler:say('Please tell me how much gold it is you would like to deposit.', cid) + npcHandler.topic[cid] = 1 + return true + end + end + if not isValidMoney(count[cid]) then + npcHandler:say('Sorry, but you can\'t deposit that much.', cid) + npcHandler.topic[cid] = 0 + return false + end + elseif npcHandler.topic[cid] == 1 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid) + npcHandler.topic[cid] = 2 + return true + else + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return true + end + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, 'yes') then + if player:depositMoney(count[cid]) then + npcHandler:say('Alright, we have added the amount of ' .. count[cid] .. ' gold to your {balance}. You can {withdraw} your money anytime you want to.', cid) + else + npcHandler:say('You do not have enough gold.', cid) + end + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish. Is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 + return true +---------------------------- withdraw -------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild withdraw') then + if not player:getGuild() then + npcHandler:say('I am sorry but it seems you are currently not in any guild.', cid) + npcHandler.topic[cid] = 0 + return false + elseif player:getGuildLevel() < 2 then + npcHandler:say('Only guild leaders or vice leaders can withdraw money from the guild account.', cid) + npcHandler.topic[cid] = 0 + return false + end + + if string.match(msg,'%d+') then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your guild account?', cid) + npcHandler.topic[cid] = 25 + else + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + end + return true + else + npcHandler:say('Please tell me how much gold you would like to withdraw from your guild account.', cid) + npcHandler.topic[cid] = 24 + return true + end + elseif npcHandler.topic[cid] == 24 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your guild account?', cid) + npcHandler.topic[cid] = 25 + else + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + end + return true + elseif npcHandler.topic[cid] == 25 then + if msgcontains(msg, 'yes') then + local guild = player:getGuild() + local balance = guild:getBankBalance() + npcHandler:say('We placed an order to withdraw ' .. count[cid] .. ' gold from your guild account. Please check your inbox for confirmation.', cid) + local info = { + type = 'Guild Withdraw', + amount = count[cid], + owner = player:getName() .. ' of ' .. guild:getName(), + recipient = player:getName() + } + if balance < tonumber(count[cid]) then + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your guild account.' + info.success = false + else + info.message = 'We are happy to inform you that your transfer request was successfully carried out.' + info.success = true + guild:setBankBalance(balance - tonumber(count[cid])) + local playerBalance = player:getBankBalance() + player:setBankBalance(playerBalance + tonumber(count[cid])) + end + + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish. Is there something else I can do for you?', cid) + npcHandler.topic[cid] = 0 + end + return true +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'withdraw') then + if string.match(msg,'%d+') then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your bank account?', cid) + npcHandler.topic[cid] = 7 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + return true + else + npcHandler:say('Please tell me how much gold you would like to withdraw.', cid) + npcHandler.topic[cid] = 6 + return true + end + elseif npcHandler.topic[cid] == 6 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your bank account?', cid) + npcHandler.topic[cid] = 7 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + return true + elseif npcHandler.topic[cid] == 7 then + if msgcontains(msg, 'yes') then + if player:getFreeCapacity() >= getMoneyWeight(count[cid]) then + if not player:withdrawMoney(count[cid]) then + npcHandler:say('There is not enough gold on your account.', cid) + else + npcHandler:say('Here you are, ' .. count[cid] .. ' gold. Please let me know if there is something else I can do for you.', cid) + end + else + npcHandler:say('Whoah, hold on, you have no room in your inventory to carry all those coins. I don\'t want you to drop it on the floor, maybe come back with a cart!', cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') then + npcHandler:say('The customer is king! Come back anytime you want to if you wish to {withdraw} your money.', cid) + npcHandler.topic[cid] = 0 + end + return true +---------------------------- transfer -------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild transfer') then + if not player:getGuild() then + npcHandler:say('I am sorry but it seems you are currently not in any guild.', cid) + npcHandler.topic[cid] = 0 + return false + elseif player:getGuildLevel() < 2 then + npcHandler:say('Only guild leaders or vice leaders can transfer money from the guild account.', cid) + npcHandler.topic[cid] = 0 + return false + end + + if string.match(msg, '%d+') then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + transfer[cid] = string.match(msg, 'to%s*(.+)$') + if transfer[cid] then + npcHandler:say('So you would like to transfer ' .. count[cid] .. ' gold from your guild account to guild ' .. transfer[cid] .. '?', cid) + npcHandler.topic[cid] = 28 + else + npcHandler:say('Which guild would you like to transfer ' .. count[cid] .. ' gold to?', cid) + npcHandler.topic[cid] = 27 + end + else + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + end + else + npcHandler:say('Please tell me the amount of gold you would like to transfer.', cid) + npcHandler.topic[cid] = 26 + end + return true + elseif npcHandler.topic[cid] == 26 then + count[cid] = getMoneyCount(msg) + if player:getGuild():getBankBalance() < count[cid] then + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + return true + end + if isValidMoney(count[cid]) then + npcHandler:say('Which guild would you like to transfer ' .. count[cid] .. ' gold to?', cid) + npcHandler.topic[cid] = 27 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + return true + elseif npcHandler.topic[cid] == 27 then + transfer[cid] = msg + if player:getGuild():getName() == transfer[cid] then + npcHandler:say('Fill in this field with person who receives your gold!', cid) + npcHandler.topic[cid] = 0 + return true + end + npcHandler:say('So you would like to transfer ' .. count[cid] .. ' gold from your guild account to guild ' .. transfer[cid] .. '?', cid) + npcHandler.topic[cid] = 28 + return true + elseif npcHandler.topic[cid] == 28 then + if msgcontains(msg, 'yes') then + npcHandler:say('We have placed an order to transfer ' .. count[cid] .. ' gold from your guild account to guild ' .. transfer[cid] .. '. Please check your inbox for confirmation.', cid) + local guild = player:getGuild() + local balance = guild:getBankBalance() + local info = { + type = 'Guild to Guild Transfer', + amount = count[cid], + owner = player:getName() .. ' of ' .. guild:getName(), + recipient = transfer[cid] + } + if balance < tonumber(count[cid]) then + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your guild account.' + info.success = false + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + else + getGuildIdByName(transfer[cid], transferFactory(player:getName(), tonumber(count[cid]), guild:getId(), info)) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') then + npcHandler:say('Alright, is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'transfer') then + npcHandler:say('Please tell me the amount of gold you would like to transfer.', cid) + npcHandler.topic[cid] = 11 + elseif npcHandler.topic[cid] == 11 then + count[cid] = getMoneyCount(msg) + if player:getBankBalance() < count[cid] then + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + return true + end + if isValidMoney(count[cid]) then + npcHandler:say('Who would you like transfer ' .. count[cid] .. ' gold to?', cid) + npcHandler.topic[cid] = 12 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 12 then + transfer[cid] = msg + if player:getName() == transfer[cid] then + npcHandler:say('Fill in this field with person who receives your gold!', cid) + npcHandler.topic[cid] = 0 + return true + end + if playerExists(transfer[cid]) then + local arrayDenied = {"accountmanager", "rooksample", "druidsample", "sorcerersample", "knightsample", "paladinsample"} + if isInArray(arrayDenied, string.gsub(transfer[cid]:lower(), " ", "")) then + npcHandler:say('This player does not exist.', cid) + npcHandler.topic[cid] = 0 + return true + end + npcHandler:say('So you would like to transfer ' .. count[cid] .. ' gold to ' .. transfer[cid] .. '?', cid) + npcHandler.topic[cid] = 13 + else + npcHandler:say('This player does not exist.', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 13 then + if msgcontains(msg, 'yes') then + if not player:transferMoneyTo(transfer[cid], count[cid]) then + npcHandler:say('You cannot transfer money to this account.', cid) + else + npcHandler:say('Very well. You have transferred ' .. count[cid] .. ' gold to ' .. transfer[cid] ..'.', cid) + transfer[cid] = nil + end + elseif msgcontains(msg, 'no') then + npcHandler:say('Alright, is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 +---------------------------- money exchange -------------- + elseif msgcontains(msg, 'change gold') then + npcHandler:say('How many platinum coins would you like to get?', cid) + npcHandler.topic[cid] = 14 + elseif npcHandler.topic[cid] == 14 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough gold coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] * 100 .. ' of your gold coins into ' .. count[cid] .. ' platinum coins?', cid) + npcHandler.topic[cid] = 15 + end + elseif npcHandler.topic[cid] == 15 then + if msgcontains(msg, 'yes') then + if player:removeItem(2148, count[cid] * 100) then + player:addItem(2152, count[cid]) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough gold coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'change platinum') then + npcHandler:say('Would you like to change your platinum coins into gold or crystal?', cid) + npcHandler.topic[cid] = 16 + elseif npcHandler.topic[cid] == 16 then + if msgcontains(msg, 'gold') then + npcHandler:say('How many platinum coins would you like to change into gold?', cid) + npcHandler.topic[cid] = 17 + elseif msgcontains(msg, 'crystal') then + npcHandler:say('How many crystal coins would you like to get?', cid) + npcHandler.topic[cid] = 19 + else + npcHandler:say('Well, can I help you with something else?', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 17 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] .. ' of your platinum coins into ' .. count[cid] * 100 .. ' gold coins for you?', cid) + npcHandler.topic[cid] = 18 + end + elseif npcHandler.topic[cid] == 18 then + if msgcontains(msg, 'yes') then + if player:removeItem(2152, count[cid]) then + player:addItem(2148, count[cid] * 100) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 19 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] * 100 .. ' of your platinum coins into ' .. count[cid] .. ' crystal coins for you?', cid) + npcHandler.topic[cid] = 20 + end + elseif npcHandler.topic[cid] == 20 then + if msgcontains(msg, 'yes') then + if player:removeItem(2152, count[cid] * 100) then + player:addItem(2160, count[cid]) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'change crystal') then + npcHandler:say('How many crystal coins would you like to change into platinum?', cid) + npcHandler.topic[cid] = 21 + elseif npcHandler.topic[cid] == 21 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough crystal coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] .. ' of your crystal coins into ' .. count[cid] * 100 .. ' platinum coins for you?', cid) + npcHandler.topic[cid] = 22 + end + elseif npcHandler.topic[cid] == 22 then + if msgcontains(msg, 'yes') then + if player:removeItem(2160, count[cid]) then + player:addItem(2152, count[cid] * 100) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough crystal coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'money'}, StdModule.say, {npcHandler = npcHandler, text = 'We can {change} money for you. You can also access your {bank account}.'}) +keywordHandler:addKeyword({'change'}, StdModule.say, {npcHandler = npcHandler, text = 'There are three different coin types in Tibia: 100 gold coins equal 1 platinum coin, 100 platinum coins equal 1 crystal coin. So if you\'d like to change 100 gold into 1 platinum, simply say \'{change gold}\' and then \'1 platinum\'.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'We can {change} money for you. You can also access your {bank account}.'}) +keywordHandler:addKeyword({'advanced'}, StdModule.say, {npcHandler = npcHandler, text = 'Your bank account will be used automatically when you want to {rent} a house or place an offer on an item on the {market}. Let me know if you want to know about how either one works.'}) +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'You can check the {balance} of your bank account, {deposit} money or {withdraw} it. You can also {transfer} money to other characters, provided that they have a vocation.'}) +keywordHandler:addKeyword({'functions'}, StdModule.say, {npcHandler = npcHandler, text = 'You can check the {balance} of your bank account, {deposit} money or {withdraw} it. You can also {transfer} money to other characters, provided that they have a vocation.'}) +keywordHandler:addKeyword({'basic'}, StdModule.say, {npcHandler = npcHandler, text = 'You can check the {balance} of your bank account, {deposit} money or {withdraw} it. You can also {transfer} money to other characters, provided that they have a vocation.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I work in this bank. I can change money for you and help you with your bank account.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Yes? What may I do for you, |PLAYERNAME|? Bank business, perhaps?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Have a nice day.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Have a nice day.") +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/kevin.lua b/data/npc/scripts/kevin.lua new file mode 100644 index 00000000000..4a930b69eb4 --- /dev/null +++ b/data/npc/scripts/kevin.lua @@ -0,0 +1,268 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function getPlayerBones(cid) + local player = Player(cid) + return player:getItemCount(2230) + player:getItemCount(2231) +end + +local function doPlayerRemoveBones(cid) + local player = Player(cid) + return player:removeItem(2230, player:getItemCount(2230)) and player:removeItem(2231, player:getItemCount(2231)) +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.Postman.Mission01) < 1 then + npcHandler:say("You are not a member of our guild yet! We have high standards for our members. To rise in our guild is a difficult but rewarding task. Are you interested in joining?", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.Postman.Mission01) == 5 then + npcHandler:say("So you have finally made it! I did not think that you would have it in you ... However: are you ready for another assignment?", cid) + npcHandler.topic[cid] = 8 + elseif player:getStorageValue(Storage.Postman.Mission02) == 2 then + npcHandler:say("Excellent, you got it fixed! This will teach this mailbox a lesson indeed! Are you interested in another assignment?", cid) + player:setStorageValue(Storage.Postman.Mission02, 3) + npcHandler.topic[cid] = 9 + elseif player:getStorageValue(Storage.Postman.Mission03) == 2 then + npcHandler:say("You truly got him? Quite impressive. You are a very promising candidate! I think I have another mission for you. Are you interested?", cid) + npcHandler.topic[cid] = 11 + elseif player:getStorageValue(Storage.Postman.Mission04) == 1 then + npcHandler:say("Do you bring all bones for our officers' safety fund at once?", cid) + npcHandler.topic[cid] = 13 + elseif player:getStorageValue(Storage.Postman.Mission05) == 3 then + npcHandler:say("Splendid, I knew we could trust you. I would like to ask for your help in another matter. Are you interested?", cid) + npcHandler.topic[cid] = 16 + elseif player:getStorageValue(Storage.Postman.Mission07) == 7 then + npcHandler:say("Once more you have impressed me! Are you willing to do another job?", cid) + npcHandler.topic[cid] = 21 + elseif player:getStorageValue(Storage.Postman.Mission06) >= 1 and player:getStorageValue(Storage.Postman.Mission06) < 10 then + npcHandler:say("First you need to complete your current mission.", cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.Postman.Mission06) == 12 then + npcHandler:say("Excellent! Another job well done! Would you accept another mission?", cid) + player:setStorageValue(Storage.Postman.Mission06, 13) + npcHandler.topic[cid] = 28 + elseif player:getStorageValue(Storage.Postman.Mission06) == 10 then + npcHandler:say("Fine, fine. I think that should do it. Tell Hugo that we order those uniforms. The completed dress pattern will soon arrive in Venore. Report to me when you have talked to him.", cid) + player:setStorageValue(Storage.Postman.Mission06, 11) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.Postman.Mission08) == 2 then + npcHandler:say("So Waldo is dead? This is grave news indeed. Did you recover his posthorn?", cid) + npcHandler.topic[cid] = 23 + elseif player:getStorageValue(Storage.Postman.Mission09) == 3 then + npcHandler:say("You did it? I hope you did not catch a flu in the cold! Anyway, there's another mission for you. Are you interested?", cid) + npcHandler.topic[cid] = 26 + elseif player:getStorageValue(Storage.Postman.Mission10) == 2 then + npcHandler:say("You have delivered that letter? You are a true postofficer. All over the land bards shallpraise your name. There are no missions for you left right now.", cid) + player:setStorageValue(Storage.Postman.Mission10, 3) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.Postman.Mission10) == 3 and player:getStorageValue(Storage.Postman.Rank) == 5 then + npcHandler:say("There are no missions for you left right now. You already have the title of Archpostman.", cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.Postman.Mission10) == 3 and player:getStorageValue(Storage.Postman.Rank) == 4 then + npcHandler:say("There are no missions for you left right now. But you are worthy indeed. Do you want to advance in our guild?", cid) + npcHandler.topic[cid] = 27 + elseif player:getStorageValue(Storage.Postman.Mission08) == 3 and player:getStorageValue(Storage.Postman.Rank) == 3 then + npcHandler:say("So are you ready for another mission?", cid) + npcHandler.topic[cid] = 28 + elseif player:getStorageValue(Storage.Postman.Mission08) == 3 and player:getStorageValue(Storage.Postman.Rank) == 4 then + npcHandler:say("So are you ready for another mission?", cid) + npcHandler.topic[cid] = 25 + elseif player:getStorageValue(Storage.Postman.Rank) == 4 or player:getStorageValue(Storage.Postman.Rank) == 3 and player:getStorageValue(Storage.Postman.Mission09) == 0 then + npcHandler:say("So are you ready for another mission?", cid) + npcHandler.topic[cid] = 25 + elseif player:getStorageValue(Storage.Postman.Mission06) == 13 and player:getStorageValue(Storage.Postman.Rank) == 3 then + npcHandler:say("Excellent! Another job well done! Would you accept another mission?", cid) + npcHandler.topic[cid] = 19 + elseif player:getStorageValue(Storage.Postman.Mission06) == 13 and player:getStorageValue(Storage.Postman.Rank) == 2 then + npcHandler:say("Excellent! Another job well done! Would you accept another mission?", cid) + npcHandler.topic[cid] = 28 + elseif player:getStorageValue(Storage.Postman.Mission04) == 2 and player:getStorageValue(Storage.Postman.Rank) == 2 then + npcHandler:say("You have made it! We have enough bones for the fund! You remind me of myself when I was young! Interested in another mission?", cid) + npcHandler.topic[cid] = 15 + elseif player:getStorageValue(Storage.Postman.Mission04) == 2 and player:getStorageValue(Storage.Postman.Rank) == 1 then + npcHandler:say("You have made it! We have enough bones for the fund! You remind me of myself when I was young! Interested in another mission?", cid) + npcHandler.topic[cid] = 28 + elseif player:getStorageValue(Storage.Postman.Mission03) == 3 and player:getStorageValue(Storage.Postman.Mission04) == 0 then + npcHandler:say("You truly got him? Quite impressive. You are a very promising candidate! I think I have another mission for you. Are you interested?", cid) + npcHandler.topic[cid] = 11 + elseif player:getStorageValue(Storage.Postman.Rank) == 1 and player:getStorageValue(Storage.Postman.Mission03) == 3 then + npcHandler:say("So are you ready for another mission?", cid) + npcHandler.topic[cid] = 11 + elseif player:getStorageValue(Storage.Postman.Mission02) == 3 and player:getStorageValue(Storage.Postman.Rank) == 1 then + npcHandler:say("So are you ready for another mission?", cid) + npcHandler.topic[cid] = 10 + end + elseif msgcontains(msg, "dress pattern") then + if player:getStorageValue(Storage.Postman.Mission06) == 2 then + npcHandler:say("Oh yes, where did we get that from ...? Let's see, first ask the great technomancer in Kazordoon for the technical details. Return here afterwards.", cid) + player:setStorageValue(Storage.Postman.Mission06, 3) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.Postman.Mission06) == 4 then + npcHandler:say("The mail with Talphion's instructions just arived. I remember we asked Queen Eloise of Carlin for the perfect colours. Go there, ask her about the UNIFORMS and report back here.", cid) + player:setStorageValue(Storage.Postman.Mission06, 5) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.Postman.Mission06) == 6 then + npcHandler:say("The queen has sent me the samples we needed. The next part is tricky. We need theuniforms to emanate some odor that dogs hate.The dog with the best 'taste' in that field is Noodles,the dog of King Tibianus. Do you understand so far?", cid) + npcHandler.topic[cid] = 18 + elseif player:getStorageValue(Storage.Postman.Mission06) == 10 then + npcHandler:say("Fine, fine. I think that should do it. Tell Hugo that we order those uniforms. The completed dress pattern will soon arrive in Venore. Report to me when you have talked to him.", cid) + player:setStorageValue(Storage.Postman.Mission06, 11) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "advancement") then + if player:getStorageValue(Storage.Postman.Mission04) == 2 and player:getStorageValue(Storage.Postman.Rank) == 1 then + npcHandler:say("You are worthy indeed. Do you want to advance in our guild?", cid) + npcHandler.topic[cid] = 14 + elseif player:getStorageValue(Storage.Postman.Mission06) == 13 and player:getStorageValue(Storage.Postman.Rank) == 2 then + npcHandler:say("You are worthy indeed. Do you want to advance in our guild?", cid) + npcHandler.topic[cid] = 20 + elseif player:getStorageValue(Storage.Postman.Mission08) == 3 and player:getStorageValue(Storage.Postman.Rank) == 3 then + npcHandler:say("You are worthy indeed. Do you want to advance in our guild?", cid) + npcHandler.topic[cid] = 24 + elseif player:getStorageValue(Storage.Postman.Mission10) == 3 and player:getStorageValue(Storage.Postman.Rank) == 4 then + npcHandler:say("You are worthy indeed. Do you want to advance in our guild?", cid) + npcHandler.topic[cid] = 27 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Hm, I might consider your proposal, but first you will have to prove your worth by doing some tasks for us. Are you willing to do that?", cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say("Excellent! Your first task will be quite simple. But you should better write my instructions down anyways. You can read and write?", cid) + npcHandler.topic[cid] = 3 + elseif npcHandler.topic[cid] == 3 then + npcHandler:say("So listen, you will check certain tours our members have to take to see if there is some trouble. First travel with Captain Bluebear's ship from Thais to Carlin, understood?", cid) + npcHandler.topic[cid] = 4 + elseif npcHandler.topic[cid] == 4 then + npcHandler:say("Excellent! Once you have done that you will travel with Uzon to Edron. You will find him in the Femor Hills. Understood?", cid) + npcHandler.topic[cid] = 5 + elseif npcHandler.topic[cid] == 5 then + npcHandler:say("Fine, fine! Next, travel with Captain Seahorse to the city of Venore. Understood?", cid) + npcHandler.topic[cid] = 6 + elseif npcHandler.topic[cid] == 6 then + npcHandler:say("Good! Finally, find the technomancer Brodrosch and travel with him to the Isle of Cormaya. After this passage report back to me here. Understood?", cid) + npcHandler.topic[cid] = 7 + elseif npcHandler.topic[cid] == 7 then + npcHandler:say("Ok, remember: the Tibian mail service puts trust in you! Don't fail and report back soon. Just tell me about your {mission}.", cid) + player:setStorageValue(Storage.Postman.Mission01, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 8 then + npcHandler:say("I am glad to hear that. One of our mailboxes was reported to be jammed. It is located on the so called 'mountain' on theisle Folda. Get a crowbar and fix the mailbox. Report about your mission when you have done so.", cid) + player:setStorageValue(Storage.Postman.Mission01, 6) + player:setStorageValue(Storage.Postman.Mission02, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 9 then + npcHandler:say("For your noble deeds I grant you the title Assistant Postofficer. All Postofficers will charge you less money from now on. After every second mission ask me for an ADVANCEMENT. Your next task will be a bit more challenging. Do you feel ready for it?", cid) + player:setStorageValue(Storage.Postman.Rank, 1) + npcHandler.topic[cid] = 10 + elseif npcHandler.topic[cid] == 10 then + npcHandler:say("I need you to deliver a bill to the stage magician David Brassacres. He's hiding from his creditors somewhere in Venore. It's likely you will have to trick him somehow to reveal his identity. Report back when you delivered this bill.", cid) + player:setStorageValue(Storage.Postman.Mission03, 1) + player:addItem(2329, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 11 then + npcHandler:say("Ok, listen: we have some serious trouble with agressive dogs lately. We have accumulated some bones as a sort of pacifier but we need more. Collect 20 bones like the one in my room to the left and report here.", cid) + player:setStorageValue(Storage.Postman.Mission03, 3) + player:setStorageValue(Storage.Postman.Mission04, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 13 then + if getPlayerBones(cid) >= 20 then + doPlayerRemoveBones(cid) + npcHandler:say("You have collected all the 20 bones needed. Excellent! Now let's talk about further missions if you are interested.", cid) + player:setStorageValue(Storage.Postman.Mission04, 2) + npcHandler.topic[cid] = 0 + else + npcHandler.topic[cid] = 0 + npcHandler:say("You don't have it...", cid) + end + elseif npcHandler.topic[cid] == 14 then + npcHandler:say("I grant you the title of postman. You are now a full member of our guild. Here have your own officers hat and wear it with pride.", cid) + player:setStorageValue(Storage.Postman.Rank, 2) + player:addItem(2665, 1) + npcHandler.topic[cid] = 15 + elseif npcHandler.topic[cid] == 15 then + npcHandler:say("Since I am convinced I can trust you, this time you must deliver a valuable present to Dermot on Fibula. Do NOT open it!!! You will find the present behind the door here on the lower right side of this room.", cid) + player:setStorageValue(Storage.Postman.Mission05, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 16 then + npcHandler:say("Ok. We need a new set of uniforms, and only the best will do for us. Please travel to Venore and negotiate with Hugo Chief acontract for new uniforms.", cid) + player:setStorageValue(Storage.Postman.Mission05, 4) + player:setStorageValue(Storage.Postman.Mission06, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 18 then + npcHandler:say("Good. Go there and find out what taste he dislikes most: mouldy cheese, a piece of fur or abananaskin. Tell him to SNIFF, then the object. Show him the object and ask 'Do you like that?'.DONT let the guards know what you are doing.", cid) + player:setStorageValue(Storage.Postman.Mission06, 7) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 19 then + npcHandler:say("Good, so listen. Hugo Chief informed me that he needs the measurements of our postofficers. Go and bring me the measurements of Ben, Lokur, Dove, Liane, Chrystal and Olrik.", cid) + player:setStorageValue(Storage.Postman.Mission07, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 20 then + npcHandler:say("From now on it shall be known that you are a grand postman. You are now a privilegedmember until the end of days. Most captains around the world have an agreement with our guild to transport our privileged members, like you, for less gold.", cid) + player:setStorageValue(Storage.Postman.Rank, 3) + npcHandler.topic[cid] = 19 + elseif npcHandler.topic[cid] == 21 then + npcHandler:say("Ok but your next assignment might be dangerous. Our Courier Waldo has been missing for a while. I must assume he is dead. Can you follow me so far?", cid) + npcHandler.topic[cid] = 22 + elseif npcHandler.topic[cid] == 22 then + npcHandler:say("Find out about his whereabouts and retrieve him or at least his posthorn. He was looking for a new underground passage that is rumoured to be found underneath the troll-infested Mountain east of Thais.", cid) + player:setStorageValue(Storage.Postman.Mission07, 8) + player:setStorageValue(Storage.Postman.Mission08, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 23 then + if player:removeItem(2332, 1) then + npcHandler:say("Thank you. We will honour this. Your next mission will be a very special one. Good thing you are a special person as well. Are you ready?", cid) + player:setStorageValue(Storage.Postman.Mission08, 3) + player:setStorageValue(Storage.Postman.Mission09, 0) + npcHandler.topic[cid] = 28 + end + elseif npcHandler.topic[cid] == 24 then + npcHandler:say("From now on you are a grand postman for special operations. You are an honoured member of our guild and earned the privilege of your own post horn. Here, take it.", cid) + player:setStorageValue(Storage.Postman.Rank, 4) + player:addItem(2078, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 25 then + npcHandler:say("So listen well. Behind the lower left door you will find a bag. The letters in the bag are for none other than Santa Claus! Deliver them to his house on the isle of Vega, {use} thebag on his mailbox and report back here.", cid) + player:setStorageValue(Storage.Postman.Mission09, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 26 then + npcHandler:say("Excellent. Here is a letter for you to deliver. Well, to be honest, no one else volunteered. It's a letter from the mother of Markwin, the king of Mintwallin. Deliver that letter to him, but note that you will not be welcome there.", cid) + player:setStorageValue(Storage.Postman.Mission09, 4) + player:setStorageValue(Storage.Postman.Mission10, 1) + player:addItem(2333, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 27 then + npcHandler:say("I grant you the title of Archpostman. You are a legend in our guild. As privilege of your newly aquired status you are allowed to make use of certain mailboxes in dangerous areas. Just look out for them and you'll see.", cid) + player:setStorageValue(Storage.Postman.Rank, 5) + player:setStorageValue(Storage.Postman.Door, 1) + player:addAchievement('Archpostman') + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 28 then + npcHandler:say("Your eagerness is a virtue, young one, but first let's talk about advancement", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/khanna.lua b/data/npc/scripts/khanna.lua new file mode 100644 index 00000000000..527e84a4e49 --- /dev/null +++ b/data/npc/scripts/khanna.lua @@ -0,0 +1,57 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local items = { + [VOCATION.CLIENT_ID.SORCERER] = 2190, + [VOCATION.CLIENT_ID.DRUID] = 2182 +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'first rod') or msgcontains(msg, 'first wand') then + if player:isMage() then + local itemId = items[player:getVocation():getClientId()] + if player:getStorageValue(Storage.firstMageWeapon) == -1 then + npcHandler:say('So you ask me for a {' .. ItemType(itemId):getName() .. '} to begin your adventure?', cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say('What? I have already gave you one {' .. ItemType(itemId):getName() .. '}!', cid) + end + else + npcHandler:say('Sorry, you aren\'t a druid either a sorcerer.', cid) + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + player:addItem(itemId, 1) + npcHandler:say('Here you are young adept, take care yourself.', cid) + player:setStorageValue(Storage.firstMageWeapon, 1) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] == 1 then + npcHandler:say('Ok then.', cid) + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/king_tibianus.lua b/data/npc/scripts/king_tibianus.lua new file mode 100644 index 00000000000..42208f13e2b --- /dev/null +++ b/data/npc/scripts/king_tibianus.lua @@ -0,0 +1,235 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, "farmine") then + if player:getStorageValue(Storage.TheNewFrontier.Questline) == 15 then + npcHandler:say("King Tibianus: Ah, I vaguely remember that our little allies were eager to build some base. So speak up, what do you want?", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "Flatter") then + if npcHandler.topic[cid] == 1 then + if player:getStorageValue(Storage.TheNewFrontier.BribeKing) < 1 then + npcHandler:say("The idea of a promising market and new resources suits us quite well. I think it is reasonable to send some assistance.", cid) + player:setStorageValue(Storage.TheNewFrontier.BribeKing, 1) + player:setStorageValue(Storage.TheNewFrontier.Mission05, player:getStorageValue(Storage.TheNewFrontier.Mission05) + 1) --Questlog, The New Frontier Quest "Mission 05: Getting Things Busy" + end + end + end + + if(msgcontains(msg, "outfit")) or (msgcontains(msg, "addon")) then + selfSay("In exchange for a truly generous donation, I will offer a special outfit. Do you want to make a donation?", cid) + npcHandler.topic[cid] = 1 + elseif(msgcontains(msg, "yes")) then + -- vamos tratar todas condições para YES aqui + if npcHandler.topic[cid] == 1 then + -- para o primeiro Yes, o npc deve explicar como obter o outfit + selfSay("Excellent! Now, let me explain. If you donate 1.000.000.000 gold pieces, you will be entitled to wear a unique outfit. ...", cid) + selfSay("You will be entitled to wear the {armor} for 500.000.000 gold pieces, {helmet} for an additional 250.000.000 and the {boots} for another 250.000.000 gold pieces. ...", cid) + selfSay("What will it be?", cid) + npcHandler.topic[cid] = 2 + -- O NPC só vai oferecer os addons se o player já tiver escolhido. + elseif npcHandler.topic[cid] == 2 then + -- caso o player repita o yes, resetamos o tópico para começar de novo? + selfSay("In that case, return to me once you made up your mind.", cid) + npcHandler.topic[cid] = 0 + -- Inicio do outfit + elseif npcHandler.topic[cid] == 3 then -- ARMOR/OUTFIT + if player:getStorageValue(Storage.OutfitQuest.GoldenOutfit) < 1 then + if player:getMoney() + player:getBankBalance() >= 500000000 then + local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX) + if inbox and inbox:getEmptySlots() > 0 then + local decoKit = inbox:addItem(26054, 1) + local decoItemName = ItemType(36345):getName() + decoKit:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, "Unwrap it in your own house to create a " .. decoItemName .. ".") + decoKit:setCustomAttribute("unWrapId", 36345) + selfSay("Take this armor as a token of great gratitude. Let us forever remember this day, my friend!", cid) + player:removeMoneyNpc(500000000) + player:addOutfit(1211) + player:addOutfit(1210) + player:getPosition():sendMagicEffect(171) + player:setStorageValue(Storage.OutfitQuest.GoldenOutfit, 1) + else + selfSay("Please make sure you have free slots in your store inbox.", cid) + end + else + selfSay("You do not have enough money to donate that amount.", cid) + end + else + selfSay("You alread have that addon.", cid) + end + npcHandler.topic[cid] = 2 + -- Fim do outfit + -- Inicio do helmet + elseif npcHandler.topic[cid] == 4 then + if player:getStorageValue(Storage.OutfitQuest.GoldenOutfit) == 1 then + if player:getStorageValue(Storage.OutfitQuest.GoldenOutfit) < 2 then + if player:getMoney() + player:getBankBalance() >= 250000000 then + selfSay("Take this helmet as a token of great gratitude. Let us forever remember this day, my friend. ", cid) + player:removeMoneyNpc(250000000) + player:addOutfitAddon(1210, 2) + player:addOutfitAddon(1211, 2) + player:getPosition():sendMagicEffect(171) + player:setStorageValue(Storage.OutfitQuest.GoldenOutfit, 2) + npcHandler.topic[cid] = 2 + else + selfSay("You do not have enough money to donate that amount.", cid) + npcHandler.topic[cid] = 2 + end + else + selfSay("You alread have that outfit.", cid) + npcHandler.topic[cid] = 2 + end + else + selfSay("You need to donate {armor} outfit first.", cid) + npcHandler.topic[cid] = 2 + end + npcHandler.topic[cid] = 2 + -- Fim do helmet + -- Inicio da boots + elseif npcHandler.topic[cid] == 5 then + if player:getStorageValue(Storage.OutfitQuest.GoldenOutfit) == 2 then + if player:getStorageValue(Storage.OutfitQuest.GoldenOutfit) < 3 then + if player:getMoney() + player:getBankBalance() >= 250000000 then + selfSay("Take this boots as a token of great gratitude. Let us forever remember this day, my friend. ", cid) + player:removeMoneyNpc(250000000) + player:addOutfitAddon(1210, 1) + player:addOutfitAddon(1211, 1) + player:getPosition():sendMagicEffect(171) + player:setStorageValue(Storage.OutfitQuest.GoldenOutfit, 3) + npcHandler.topic[cid] = 2 + else + selfSay("You do not have enough money to donate that amount.", cid) + npcHandler.topic[cid] = 2 + end + else + selfSay("You alread have that outfit.", cid) + npcHandler.topic[cid] = 2 + end + else + selfSay("You need to donate {helmet} addon first.", cid) + npcHandler.topic[cid] = 2 + end + -- Fim da boots + npcHandler.topic[cid] = 2 + end + --inicio das opções armor/helmet/boots + -- caso o player não diga YES, dirá alguma das seguintes palavras: + elseif(msgcontains(msg, "armor")) and npcHandler.topic[cid] == 2 then + selfSay("So you wold like to donate 500.000.000 gold pieces which in return will entitle you to wear a unique armor?", cid) + npcHandler.topic[cid] = 3 -- alterando o tópico para que no próximo YES ele faça o outfit + elseif(msgcontains(msg, "helmet")) and npcHandler.topic[cid] == 2 then + selfSay("So you would like to donate 250.000.000 gold pieces which in return will entitle you to wear unique helmet?", cid) + npcHandler.topic[cid] = 4 -- alterando o tópico para que no próximo YES ele faça o helmet + elseif(msgcontains(msg, "boots")) and npcHandler.topic[cid] == 2 then + selfSay("So you would like to donate 250.000.000 gold pieces which in return will entitle you to wear a unique boots?", cid) + npcHandler.topic[cid] = 5 -- alterando o tópico para que no próximo YES ele faça a boots + end + -- fim das opções armor/helmet/boots +end +-- Promotion +local node1 = keywordHandler:addKeyword({'promot'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'I can promote you for 20000 gold coins. Do you want me to promote you?'}) + node1:addChildKeyword({'yes'}, StdModule.promotePlayer, {npcHandler = npcHandler, cost = 20000, level = 20, text = 'Congratulations! You are now promoted.'}) + node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Alright then, come back when you are ready.', reset = true}) +-- Basic +keywordHandler:addKeyword({'eremo'}, StdModule.say, {npcHandler = npcHandler, text = 'It is said that he lives on a small island near Edron. Maybe the people there know more about him.'}) +keywordHandler:addKeyword({'otbr'}, StdModule.say, {npcHandler = npcHandler, text = 'Awesome! Please pay a visit to www.otserv.com.br!'}) +keywordHandler:addKeyword({'baah'}, StdModule.say, {npcHandler = npcHandler, text = 'Baah is awesome dude that rewrote my outfit script.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am your sovereign, King Tibianus III, and it\'s my duty to uphold {justice} and provide guidance for my subjects.'}) +keywordHandler:addKeyword({'justice'}, StdModule.say, {npcHandler = npcHandler, text = 'I try my best to be just and fair to our citizens. The army and the {TBI} are a great help in fulfilling this duty.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'Preposterous! You must know the name of your own King!'}) +keywordHandler:addKeyword({'news'}, StdModule.say, {npcHandler = npcHandler, text = 'The latest news is usually brought to our magnificent town by brave adventurers. They recount tales of their journeys at Frodo\'s tavern.'}) +keywordHandler:addKeyword({'how', 'are', 'you'}, StdModule.say, {npcHandler = npcHandler, text = 'Thank you, I\'m fine.'}) +keywordHandler:addKeyword({'castle'}, StdModule.say, {npcHandler = npcHandler, text = 'Rain Castle is my home.'}) +keywordHandler:addKeyword({'sell'}, StdModule.say, {npcHandler = npcHandler, text = 'Sell? Sell what? My kingdom isn\'t for sale!'}) +keywordHandler:addKeyword({'god'}, StdModule.say, {npcHandler = npcHandler, text = 'Honour the Gods and above all pay your {taxes}.'}) +keywordHandler:addKeyword({'zathroth'}, StdModule.say, {npcHandler = npcHandler, text = 'Please ask a priest about the gods.'}) +keywordHandler:addKeyword({'citizen'}, StdModule.say, {npcHandler = npcHandler, text = 'The citizens of Tibia are my subjects. Ask the old monk Quentin if you want to learn more about them.'}) +keywordHandler:addKeyword({'sam'}, StdModule.say, {npcHandler = npcHandler, text = 'He is a skilled blacksmith and a loyal subject.'}) +keywordHandler:addKeyword({'frodo'}, StdModule.say, {npcHandler = npcHandler, text = 'He is the owner of Frodo\'s Hut and a faithful tax-payer.'}) +keywordHandler:addKeyword({'gorn'}, StdModule.say, {npcHandler = npcHandler, text = 'He was once one of Tibia\'s greatest fighters. Now he sells equipment.'}) +keywordHandler:addKeyword({'benjamin'}, StdModule.say, {npcHandler = npcHandler, text = 'He was once my greatest general. Now he is very old and senile so we assigned him to work for the Royal Tibia Mail.'}) +keywordHandler:addKeyword({'noodles'}, StdModule.say, {npcHandler = npcHandler, text = 'The royal poodle Noodles is my greatest {treasure}!'}) +keywordHandler:addKeyword({'ferumbras'}, StdModule.say, {npcHandler = npcHandler, text = 'He is a follower of the evil God Zathroth and responsible for many attacks on us. Kill him on sight!'}) +keywordHandler:addKeyword({'bozo'}, StdModule.say, {npcHandler = npcHandler, text = 'He is my royal jester and cheers me up now and then.'}) +keywordHandler:addKeyword({'treasure'}, StdModule.say, {npcHandler = npcHandler, text = 'The royal poodle Noodles is my greatest treasure!'}) +keywordHandler:addKeyword({'monster'}, StdModule.say, {npcHandler = npcHandler, text = 'Go and hunt them! For king and country!'}) +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'Visit Quentin the monk for help.'}) +keywordHandler:addKeyword({'sewer'}, StdModule.say, {npcHandler = npcHandler, text = 'What a disgusting topic!'}) +keywordHandler:addKeyword({'dungeon'}, StdModule.say, {npcHandler = npcHandler, text = 'Dungeons are no places for kings.'}) +keywordHandler:addKeyword({'equipment'}, StdModule.say, {npcHandler = npcHandler, text = 'Feel free to buy it in our town\'s fine shops.'}) +keywordHandler:addKeyword({'food'}, StdModule.say, {npcHandler = npcHandler, text = 'Ask the royal cook for some food.'}) +keywordHandler:addKeyword({'tax collector'}, StdModule.say, {npcHandler = npcHandler, text = 'That tax collector is the bane of my life. He is so lazy. I bet you haven\'t payed any taxes at all.'}) +keywordHandler:addKeyword({'king'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the king, so watch what you say!'}) +keywordHandler:addKeyword({'army'}, StdModule.say, {npcHandler = npcHandler, text = 'Ask the soldiers about that.'}) +keywordHandler:addKeyword({'shop'}, StdModule.say, {npcHandler = npcHandler, text = 'Visit the shops of our merchants and craftsmen.'}) +keywordHandler:addKeyword({'guild'}, StdModule.say, {npcHandler = npcHandler, text = 'The four major guilds are the knights, the paladins, the druids, and the sorcerers.'}) +keywordHandler:addKeyword({'minotaur'}, StdModule.say, {npcHandler = npcHandler, text = 'Vile monsters, but I must admit they are strong and sometimes even cunning ... in their own bestial way.'}) +keywordHandler:addKeyword({'good'}, StdModule.say, {npcHandler = npcHandler, text = 'The forces of good are hard pressed in these dark times.'}) +keywordHandler:addKeyword({'evil'}, StdModule.say, {npcHandler = npcHandler, text = 'We need all strength we can muster to smite evil!'}) +keywordHandler:addKeyword({'order'}, StdModule.say, {npcHandler = npcHandler, text = 'We need order to survive!'}) +keywordHandler:addKeyword({'chaos'}, StdModule.say, {npcHandler = npcHandler, text = 'Chaos arises from selfishness.'}) +keywordHandler:addKeyword({'excalibug'}, StdModule.say, {npcHandler = npcHandler, text = 'It\'s the sword of the Kings. If you return this weapon to me I will {reward} you beyond your wildest dreams.'}) +keywordHandler:addKeyword({'reward'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, if you want a reward, go on a quest to bring me Excalibug!'}) +keywordHandler:addKeyword({'chester'}, StdModule.say, {npcHandler = npcHandler, text = 'A very competent person. A little nervous but very competent.'}) +keywordHandler:addKeyword({'tbi'}, StdModule.say, {npcHandler = npcHandler, text = 'This organisation is an essential tool for holding our enemies in check. Its headquarter is located in the bastion in the northwall.'}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = 'Soon the whole land will be ruled by me once again!'}) +keywordHandler:addAliasKeyword({'land'}) +keywordHandler:addKeyword({'harkath'}, StdModule.say, {npcHandler = npcHandler, text = 'Harkath Bloodblade is the general of our glorious {army}.'}) +keywordHandler:addAliasKeyword({'bloodblade'}) +keywordHandler:addAliasKeyword({'general'}) +keywordHandler:addKeyword({'quest'}, StdModule.say, {npcHandler = npcHandler, text = 'I will call for heroes as soon as the need arises again and then reward them appropriately.'}) +keywordHandler:addAliasKeyword({'mission'}) +keywordHandler:addKeyword({'gold'}, StdModule.say, {npcHandler = npcHandler, text = 'To pay your taxes, visit the royal tax collector.'}) +keywordHandler:addAliasKeyword({'money'}) +keywordHandler:addAliasKeyword({'tax'}) +keywordHandler:addAliasKeyword({'collector'}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = 'It\'s a time for heroes!'}) +keywordHandler:addAliasKeyword({'hero'}) +keywordHandler:addAliasKeyword({'adventurer'}) +keywordHandler:addKeyword({'enemy'}, StdModule.say, {npcHandler = npcHandler, text = 'Our enemies are numerous. The evil minotaurs, Ferumbras, and the renegade city of Carlin to the north are just some of them.'}) +keywordHandler:addAliasKeyword({'enemies'}) +keywordHandler:addKeyword({'carlin'}, StdModule.say, {npcHandler = npcHandler, text = 'They dare to reject my reign over the whole continent!'}) +keywordHandler:addKeyword({'thais'}, StdModule.say, {npcHandler = npcHandler, text = 'Our beloved city has some fine shops, guildhouses and a modern sewerage system.'}) +keywordHandler:addAliasKeyword({'city'}) +keywordHandler:addKeyword({'merchant'}, StdModule.say, {npcHandler = npcHandler, text = 'Ask around about them.'}) +keywordHandler:addAliasKeyword({'craftsmen'}) +keywordHandler:addKeyword({'paladin'}, StdModule.say, {npcHandler = npcHandler, text = 'The paladins are great protectors for Thais.'}) +keywordHandler:addAliasKeyword({'elane'}) +keywordHandler:addKeyword({'knight'}, StdModule.say, {npcHandler = npcHandler, text = 'The brave knights are necessary for human survival in Thais.'}) +keywordHandler:addAliasKeyword({'gregor'}) +keywordHandler:addKeyword({'sorcerer'}, StdModule.say, {npcHandler = npcHandler, text = 'The magic of the sorcerers is a powerful tool to smite our enemies.'}) +keywordHandler:addAliasKeyword({'muriel'}) +keywordHandler:addKeyword({'druid'}, StdModule.say, {npcHandler = npcHandler, text = 'We need the druidic healing powers to fight evil.'}) +keywordHandler:addAliasKeyword({'marvik'}) + +-- Greeting message +keywordHandler:addGreetKeyword({"hail king"}, {npcHandler = npcHandler, text = "I greet thee, my loyal subject |PLAYERNAME|."}) +keywordHandler:addGreetKeyword({"salutations king"}, {npcHandler = npcHandler, text = "I greet thee, my loyal subject |PLAYERNAME|."}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'How rude!') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/kjesse.lua b/data/npc/scripts/kjesse.lua new file mode 100644 index 00000000000..6dfc7686f5e --- /dev/null +++ b/data/npc/scripts/kjesse.lua @@ -0,0 +1,95 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Twist of Fate +local blessKeyword = keywordHandler:addKeyword({'twist of fate'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'This is a special blessing I can bestow upon you once you have obtained at least one of the other blessings and which functions a bit differently. ...', + 'It only works when you\'re killed by other adventurers, which means that at least half of the damage leading to your death was caused by others, not by monsters or the environment. ...', + 'The {twist of fate} will not reduce the death penalty like the other blessings, but instead prevent you from losing your other blessings as well as the amulet of loss, should you wear one. It costs the same as the other blessings. ...', + 'Would you like to receive that protection for a sacrifice of |PVPBLESSCOST| gold, child?' + }}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the protection of the twist of fate, pilgrim.', cost = '|PVPBLESSCOST|', bless = 1}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Adventurer Stone +keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Keep your adventurer\'s stone well.'}, function(player) return player:getItemById(18559, true) end) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for free?'}, function(player) return player:getStorageValue(Storage.AdventurersGuild.FreeStone.Kjesse) ~= 1 end) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, nil, function(player) player:addItem(18559, 1) player:setStorageValue(Storage.AdventurersGuild.FreeStone.Kjesse, 1) end) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for 30 gold?'}) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, + function(player) return player:getMoney() + player:getBankBalance() >= 30 end, + function(player) if player:removeMoneyNpc(30) then player:addItem(18559, 1) end end + ) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, you don\'t have enough money.', reset = true}) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.'}, function(player) return player:hasBlessing(2) end) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin will provide you with the embrace of Tibia.'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, young |PLAYERNAME|! If you are heavily wounded or poisoned, I can {heal} you for free.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Remember: If you are heavily wounded or poisoned, I can heal you for free.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'May the gods bless you, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/klaus.lua b/data/npc/scripts/klaus.lua new file mode 100644 index 00000000000..f6a424e0c10 --- /dev/null +++ b/data/npc/scripts/klaus.lua @@ -0,0 +1,54 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'mission') then + if player:getStorageValue(Storage.TheShatteredIsles.RaysMission4) == 1 then + npcHandler:say( + 'Hmm, you look like a seasoned seadog. Kill Captain Ray Striker, \ + bring me his lucky pillow as a proof and you are our hero!', + cid) + player:setStorageValue(Storage.TheShatteredIsles.RaysMission4, 2) + elseif player:getStorageValue(Storage.TheShatteredIsles.RaysMission4) == 3 then + npcHandler:say("Do you have Striker's pillow?", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, 'yes') then + if player:getStorageValue(Storage.TheShatteredIsles.RaysMission4) == 3 then + if npcHandler.topic[cid] == 1 then + if player:removeItem(11427, 1) then + npcHandler:say('You DID it!!! Incredible! Boys, lets have a PAAAAAARTY!!!!', cid) + player:setStorageValue(Storage.TheShatteredIsles.RaysMission4, 4) + npcHandler.topic[cid] = 0 + else + npcHandler:say('Come back when you have his lucky pillow.', cid) + npcHandler.topic[cid] = 0 + end + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/klesar.lua b/data/npc/scripts/klesar.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/klesar.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/klom_stonecutter.lua b/data/npc/scripts/klom_stonecutter.lua new file mode 100644 index 00000000000..c516e9b51b1 --- /dev/null +++ b/data/npc/scripts/klom_stonecutter.lua @@ -0,0 +1,242 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local playerTopic = {} +local voices = { {text = 'abc'} } +local quantidade = {} + +local function greetCallback(cid) + local player = Player(cid) + if player then + npcHandler:setMessage(MESSAGE_GREET, {"Greetings. A warning straight ahead: I don't like loiterin'. If you're not here to {help} us, you're here to waste my time. Which I consider loiterin'. Now, try and prove your {worth} to our alliance. ... ", + "I have sealed some of the areas far too dangerous for anyone to enter. If you can prove you're capable, you'll get an opportunity to help destroy the weird machines, pumping lava into the caves leading to the most dangerous enemies."}) + playerTopic[cid] = 1 + end + npcHandler:addFocus(cid) + return true +end + +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, the biggest problem we need to address are the ever charging {subterraneans} around here. And on top of that, there\'s the threat of the Lost, who quite made themselves at {home} in these parts.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'Maintainin\' this whole operation, the dwarven involvement \'course. Don\'t know about them gnomes but if I ain\'t gettin\' those dwarves in line, there\'ll be chaos down here. I also oversee the {defences} and {counterattacks}.'}) +keywordHandler:addKeyword({'defences'}, StdModule.say, {npcHandler = npcHandler, text = {'The attacks of the enemy forces are fierce but we hold our ground. ... ', + 'I\'d love to face one of their generals in combat but as their masters they cowardly hide far behind enemy lines and I have other duties to fulfil. ... ', + 'I envy you for the chance to thrust into the heart of the enemy, locking weapons with their jaws... or whatever... and see the fear in their eyes when they recognise they were bested.'}}) +keywordHandler:addKeyword({'counterattacks'}, StdModule.say, {npcHandler = npcHandler, text = {'I welcome a fine battle as any dwarf worth his beard should do. As long as it\'s a battle against something I can hit with my trusty axe. ...', + 'But here the true {enemy} eludes us. We fight wave after wave of their lackeys and if the gnomes are right the true enemy is up to something far more sinister. '}}) +keywordHandler:addKeyword({'enemy'}, StdModule.say, {npcHandler = npcHandler, text = {'I have no idea what kind of creeps are behind all this. Even the gnomes don\'t and they have handled that stuff way more often. ...', + 'But even if we knew nothing more about them, the fact alone that they employ the help of those mockeries of all things dwarfish, marks them as an enemy of the dwarves and it\'s our obligation to annihilate them.'}}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'Klom Stonecutter\'s the name. '}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + npcHandler.topic[cid] = playerTopic[cid] + local player = Player(cid) + npc = Npc(cid) + + local tempo = 20*60*60 + + -- missão subterraneans + if msgcontains(msg, "subterraneans") and npcHandler.topic[cid] == 1 then + if player:getStorageValue(Storage.DangerousDepths.Dwarves.Subterranean) == 2 and player:getStorageValue(Storage.DangerousDepths.Dwarves.TimeTaskSubterranean) > 0 then + npcHandler:say({"I don't need your help for now. Come back later."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + if player:getStorageValue(Storage.DangerousDepths.Dwarves.Subterranean) == 2 and player:getStorageValue(Storage.DangerousDepths.Dwarves.TimeTaskSubterranean) <= 0 then + npcHandler:say({"Vermin. Everywhere. We get a lot of strange four-legged crawlers and worms down here lately. It's getting out of hand and... well, I need a real killer for this. ", + "Prepared to get rid of some seriously foul creepers for us?"}, cid) + playerTopic[cid] = 2 + npcHandler.topic[cid] = 2 + end + if player:getStorageValue(Storage.DangerousDepths.Dwarves.Subterranean) < 1 then -- Não possuía a missão, agora possui! + npcHandler:say({"Vermin. Everywhere. We get a lot of strange four-legged crawlers and worms down here lately. It's getting out of hand and... well, I need a real killer for this. ", + "Prepared to get rid of some seriously foul creepers for us?"}, cid) + playerTopic[cid] = 2 + npcHandler.topic[cid] = 2 + elseif (player:getStorageValue(Storage.DangerousDepths.Dwarves.Subterranean) == 1) and (player:getStorageValue(Storage.DangerousDepths.Dwarves.Organisms) < 50) then -- Está na missão porém não terminou a task! + npcHandler:say({"Come back when you have finished your job."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + elseif (player:getStorageValue(Storage.DangerousDepths.Dwarves.Subterranean) == 1) and (player:getStorageValue(Storage.DangerousDepths.Dwarves.Organisms) >= 50) then + npcHandler:say({"I'l say I'm blown away but a Klom Stonecutter is not that easily impressed. Still, your got your hands dirt for us and I appreciate that."}, cid) + -- Entregando surprise jar + 1 ponto de missão! + player:setStorageValue(Storage.DangerousDepths.Dwarves.TimeTaskSubterranean, os.time() + tempo) + player:addItem(32014, 1) + player:setStorageValue(Storage.DangerousDepths.Dwarves.Status, player:getStorageValue(Storage.DangerousDepths.Dwarves.Status) + 1) + player:setStorageValue(Storage.DangerousDepths.Dwarves.Subterranean, 2) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + elseif npcHandler.topic[cid] == 2 and msgcontains(msg, "yes") then + npcHandler:say({"Alright, good. Those things are strolling about and I ain't gonna have that. If it moves more than two legs, destroy it. If it moves legs and tentacles, destroy it again."}, cid) + if player:getStorageValue(Storage.DangerousDepths.Questline) < 1 then + player:setStorageValue(Storage.DangerousDepths.Questline, 1) + end + player:setStorageValue(Storage.DangerousDepths.Dwarves.Subterranean, 1) + player:setStorageValue(Storage.DangerousDepths.Dwarves.Organisms, 0) -- Garantindo que a task não inicie com -1 + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + + -- missão home + if msgcontains(msg, "home") and npcHandler.topic[cid] == 1 then + if player:getStorageValue(Storage.DangerousDepths.Dwarves.Home) == 2 and player:getStorageValue(Storage.DangerousDepths.Dwarves.TimeTaskHome) > 0 then + npcHandler:say({"I don't need your help for now. Come back later."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + if player:getStorageValue(Storage.DangerousDepths.Dwarves.Home) == 2 and player:getStorageValue(Storage.DangerousDepths.Dwarves.TimeTaskHome) <= 0 then + npcHandler:say({"We need to find a way to drive off the exiles from these caves. Countless makeshift homes are popping up at every corner. Destroy them and get the Lost out of hiding to eliminate them. ... ", + "If you can capture a few of them, you'll receive a bonus. Just bring 'em to the border of our outpost and we will take care of the rest. ... ", + "Are you ready for that? "}, cid) + playerTopic[cid] = 22 + npcHandler.topic[cid] = 22 + end + if player:getStorageValue(Storage.DangerousDepths.Dwarves.Home) < 1 then -- Não possuía a missão, agora possui! + npcHandler:say({"We need to find a way to drive off the exiles from these caves. Countless makeshift homes are popping up at every corner. Destroy them and get the Lost out of hiding to eliminate them. ... ", + "If you can capture a few of them, you'll receive a bonus. Just bring 'em to the border of our outpost and we will take care of the rest. ... ", + "Are you ready for that? "}, cid) + playerTopic[cid] = 22 + npcHandler.topic[cid] = 22 + elseif (player:getStorageValue(Storage.DangerousDepths.Dwarves.Home) == 1) and (player:getStorageValue(Storage.DangerousDepths.Dwarves.LostExiles) < 20 and player:getStorageValue(Storage.DangerousDepths.Dwarves.Prisoners) < 3) then -- Está na missão porém não terminou nenhuma das tasks! + npcHandler:say({"Come back when you have finished your job."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + elseif (player:getStorageValue(Storage.DangerousDepths.Dwarves.Home) == 1) and (player:getStorageValue(Storage.DangerousDepths.Dwarves.LostExiles) >= 20 and player:getStorageValue(Storage.DangerousDepths.Dwarves.Prisoners) < 3) then + npcHandler:say({"So you did it. Well, that won't be the last of 'em but this sure helps our situation down here. Return to me later if you want to help me again!"}, cid) -- Caso não tenha feito o task bônus + -- Entregando surprise jar + 1 ponto de missão! + player:setStorageValue(Storage.DangerousDepths.Dwarves.TimeTaskHome, os.time() + tempo) + player:setStorageValue(Storage.DangerousDepths.Dwarves.Home, 2) + player:addItem(32014, 1) + player:setStorageValue(Storage.DangerousDepths.Dwarves.Status, player:getStorageValue(Storage.DangerousDepths.Dwarves.Status) + 1) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + elseif (player:getStorageValue(Storage.DangerousDepths.Dwarves.Home) == 1) and (player:getStorageValue(Storage.DangerousDepths.Dwarves.LostExiles) >= 20 and player:getStorageValue(Storage.DangerousDepths.Dwarves.Prisoners) >= 3) then + npcHandler:say({"So you did it. And you even made prisoners, the bonus is yours! Well, that won't be the last of 'em but this sure helps our situation down here. Return to me later if you want to help me again!"}, cid) -- Se tiver feito ambas + -- Entregando 2 surprise jars + 2 pontos de missão! + player:setStorageValue(Storage.DangerousDepths.Dwarves.TimeTaskHome, os.time() + tempo) + player:setStorageValue(Storage.DangerousDepths.Dwarves.Home, 2) + player:addItem(32014, 2) -- +1 item pela task bônus! + player:setStorageValue(Storage.DangerousDepths.Dwarves.Status, player:getStorageValue(Storage.DangerousDepths.Dwarves.Status) + 2) -- +1 ponto pela task bônus! + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + elseif npcHandler.topic[cid] == 22 and msgcontains(msg, "yes") then + npcHandler:say({"Very well, now try to find some of their makeshift homes and tear'em down. There's bound to be some stragglers you can 'persuade' to surrender, eliminate any resistance. Get back here when you're done."}, cid) + if player:getStorageValue(Storage.DangerousDepths.Questline) < 1 then + player:setStorageValue(Storage.DangerousDepths.Questline, 1) + end + player:setStorageValue(Storage.DangerousDepths.Dwarves.Home, 1) + player:setStorageValue(Storage.DangerousDepths.Dwarves.LostExiles, 0) -- Garantindo que a task não inicie com -1 + player:setStorageValue(Storage.DangerousDepths.Dwarves.Prisoners, 0) -- Garantindo que a task não inicie com -1 + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + + local plural = "" + if msgcontains(msg, "suspicious devices") or msgcontains(msg, "suspicious device") then + npcHandler:say({"If you bring me any suspicious devices on creatures you slay down here, I'll make it worth your while by telling the others of your generosity. How many do you want to offer? "}, cid) + playerTopic[cid] = 55 + npcHandler.topic[cid] = 55 + elseif npcHandler.topic[cid] == 55 then + quantidade[cid] = tonumber(msg) + if quantidade[cid] then + if quantidade[cid] > 1 then + plural = plural .. "s" + end + npcHandler:say({"You want to offer " .. quantidade[cid] .. " suspicious device" ..plural.. ". Which leader shall have it, (Gnomus) of the {gnomes}, (Klom Stonecutter) of the {dwarves} or the {scouts} (Lardoc Bashsmite)?"}, cid) + playerTopic[cid] = 56 + npcHandler.topic[cid] = 56 + else + npcHandler:say({"Don't waste my time."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "gnomes") and npcHandler.topic[cid] == 56 then + if player:getItemCount(30888) >= quantidade[cid] then + npcHandler:say({"Done."}, cid) + if quantidade[cid] > 1 then + plural = plural .. "s" + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You earned ".. quantidade[cid] .." point"..plural.." on the gnomes mission.") + player:removeItem(30888, quantidade[cid]) + player:setStorageValue(Storage.DangerousDepths.Gnomes.Status, player:getStorageValue(Storage.DangerousDepths.Gnomes.Status) + quantidade[cid]) + else + npcHandler:say({"You don't have enough suspicious devices."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "dwarves") and npcHandler.topic[cid] == 56 then + if player:getItemCount(30888) >= quantidade[cid] then + npcHandler:say({"Done."}, cid) + if quantidade[cid] > 1 then + plural = plural .. "s" + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You earned ".. quantidade[cid] .." point"..plural.." on the dwarves mission.") + player:removeItem(30888, quantidade[cid]) + player:setStorageValue(Storage.DangerousDepths.Dwarves.Status, player:getStorageValue(Storage.DangerousDepths.Dwarves.Status) + quantidade[cid]) + else + npcHandler:say({"You don't have enough suspicious devices."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "scouts") and npcHandler.topic[cid] == 56 then + if player:getItemCount(30888) >= quantidade[cid] then + npcHandler:say({"Done."}, cid) + if quantidade[cid] > 1 then + plural = plural .. "s" + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You earned ".. quantidade[cid] .." point"..plural.." on the scouts mission.") + player:removeItem(30888, quantidade[cid]) + player:setStorageValue(Storage.DangerousDepths.Scouts.Status, player:getStorageValue(Storage.DangerousDepths.Scouts.Status) + quantidade[cid]) + else + npcHandler:say({"You don't have enough suspicious devices."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + end + + + + -- Início checagem de pontos de tasks!! + if msgcontains(msg, "status") then + npcHandler:say({"So you want to know what we all think about your deeds? What leader\'s opinion are you interested in, the {gnomes} (Gnomus), the {dwarves} (Klom Stonecutter) or the {scouts} (Lardoc Bashsmite)?"}, cid) + playerTopic[cid] = 5 + npcHandler.topic[cid] = 5 + elseif msgcontains(msg, "gnomes") and npcHandler.topic[cid] == 5 then + npcHandler:say({'The gnomes are still in need of your help, member of Bigfoot\'s Brigade. Prove your worth by answering their calls! (' .. math.max(player:getStorageValue(Storage.DangerousDepths.Gnomes.Status), 0) .. '/10)'}, cid) + elseif msgcontains(msg, "dwarves") and npcHandler.topic[cid] == 5 then + npcHandler:say({'The dwarves are still in need of your help, member of Bigfoot\'s Brigade. Prove your worth by answering their calls! (' .. math.max(player:getStorageValue(Storage.DangerousDepths.Dwarves.Status), 0) .. '/10)'}, cid) + elseif msgcontains(msg, "scouts") and npcHandler.topic[cid] == 5 then + npcHandler:say({'The scouts are still in need of your help, member of Bigfoot\'s Brigade. Prove your worth by answering their calls! (' .. math.max(player:getStorageValue(Storage.DangerousDepths.Scouts.Status), 0) .. '/10)'}, cid) + end + return true +end + + + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/knight_hykrion.lua b/data/npc/scripts/knight_hykrion.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/knight_hykrion.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/kratos.lua b/data/npc/scripts/kratos.lua new file mode 100644 index 00000000000..024095475f3 --- /dev/null +++ b/data/npc/scripts/kratos.lua @@ -0,0 +1,79 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- ID, Count, Price +local eventShopItems = { + ["stamina refill low"] = {1000, 1, 10}, + ["stamina refill medium"] = {1000, 1, 20}, + ["stamina refill high"] = {1000, 1, 30}, + ["blood herb"] = {2798, 10, 3} +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + msg = string.lower(msg) + if (msg == "ofertas") then + local answerOffers = "" + for i, v in pairs(eventShopItems) do + answerOffers = answerOffers.. " {" ..i.."} (" ..v[2].. "x) - " ..v[3].." event token(s) |" + end + npcHandler:say("Eu troco os itens: " ..answerOffers, cid) + elseif (msg == "event shop") then + npcHandler:say("Entre no nosso site, clique em {Events} => {Events Shop}.", cid) + end + + if (eventShopItems[msg]) then + npcHandler.topic[cid] = 0 + local itemId, itemCount, itemPrice = eventShopItems[msg][1], eventShopItems[msg][2], eventShopItems[msg][3] + if (player:getItemCount(26143) > 0) then + npcHandler:say("Deseja comprar o item {" ..msg.. "} por " ..itemPrice.. "x?", cid) + npcHandler.topic[cid] = msg + else + npcHandler:say("Voc� n�o tem " ..itemPrice.. " {Event Token(s)}!", cid) + return true + end + end + + if (eventShopItems[npcHandler.topic[cid]]) then + local itemId, itemCount, itemPrice = eventShopItems[npcHandler.topic[cid]][1], eventShopItems[npcHandler.topic[cid]][2], eventShopItems[npcHandler.topic[cid]][3] + if (msg == "no" or + msg == "n�o") then + npcHandler:say("Ent�o qual item deseja comprar?", cid) + npcHandler.topic[cid] = 0 + elseif (msg == "yes" or + msg == "sim") then + if (player:getItemCount(26143) > 0) then + npcHandler:say("Voc� comprou o Item {" ..npcHandler.topic[cid].."} " ..itemCount.. "x por " ..itemPrice.. " {Event Token(s)}!", cid) + player:removeItem(26143, itemPrice) + player:addItem(itemId, itemCount) + end + end + end +end + +local voices = { {text = 'Troco itens por Event Tokens, venha ver minhas ofertas!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, 'Ol�, |PLAYERNAME|! Caso n�o me conhe�a, v� no site e clique em {Event Shop}. Deseja trocar seus Event Tokens? fale {ofertas}.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Foi �timo negociar com voc�, |PLAYERNAME|.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Foi �timo negociar com voc�, |PLAYERNAME|.') +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/kromrek.lua b/data/npc/scripts/kromrek.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/kromrek.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/kroox.lua b/data/npc/scripts/kroox.lua new file mode 100644 index 00000000000..3af9f943ab4 --- /dev/null +++ b/data/npc/scripts/kroox.lua @@ -0,0 +1,46 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "sam sent me") or msgcontains(msg, "sam send me") then + if player:getStorageValue(Storage.SamsOldBackpack) == 1 then + npcHandler:say({ + "Oh, so its you, he wrote me about? Sadly I have no dwarven armor in stock. But I give you the permission to retrive one from the mines. ...", + "The problem is, some giant spiders made the tunnels where the storage is their new home. Good luck." + }, cid) + player:setStorageValue(Storage.SamsOldBackpack, 2) + player:setStorageValue(Storage.SamsOldBackpackDoor, 1) + end + elseif msgcontains(msg, "measurements") then + if player:getStorageValue(Storage.Postman.Mission07) >= 1 and player:getStorageValue(Storage.Postman.MeasurementsKroox) ~= 1 then + npcHandler:say("Hm, well I guess its ok to tell you ... ", cid) + player:setStorageValue(Storage.Postman.Mission07, player:getStorageValue(Storage.Postman.Mission07) + 1) + player:setStorageValue(Storage.Postman.MeasurementsKroox, 1) + else + npcHandler:say("...", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/kulag_the_guard.lua b/data/npc/scripts/kulag_the_guard.lua new file mode 100644 index 00000000000..f623d3f65a4 --- /dev/null +++ b/data/npc/scripts/kulag_the_guard.lua @@ -0,0 +1,47 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "trouble") and player:getStorageValue(Storage.TheInquisition.KulagGuard) < 1 and player:getStorageValue(Storage.TheInquisition.Mission01) ~= -1 then + npcHandler:say("You adventurers become more and more of a pest.", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "authorities") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("They should throw you all into jail instead of giving you all those quests and rewards an honest watchman can only dream about.", cid) + if player:getStorageValue(Storage.TheInquisition.KulagGuard) < 1 then + player:setStorageValue(Storage.TheInquisition.KulagGuard, 1) + player:setStorageValue(Storage.TheInquisition.Mission01, player:getStorageValue(Storage.TheInquisition.Mission01) + 1) -- The Inquisition Questlog- "Mission 1: Interrogation" + player:getPosition():sendMagicEffect(CONST_ME_HOLYAREA) + end + npcHandler.topic[cid] = 0 + end + end + return true +end + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "It's my duty to protect the city."}) + +npcHandler:setMessage(MESSAGE_GREET, "LONG LIVE THE KING!") +npcHandler:setMessage(MESSAGE_FAREWELL, "LONG LIVE THE KING!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "LONG LIVE THE KING!") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lailene.lua b/data/npc/scripts/lailene.lua new file mode 100644 index 00000000000..11d20e10c89 --- /dev/null +++ b/data/npc/scripts/lailene.lua @@ -0,0 +1,24 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'brotherhood of bones'}, StdModule.say, {npcHandler = npcHandler, text = "... what?! Uh - no, no. Of course I wouldn't have anything to do with... them."}) + +npcHandler:setMessage(MESSAGE_GREET, "What do you want in my magical robe store? I doubt I have anything that's of interest to you.") +npcHandler:setMessage(MESSAGE_FAREWELL, "See ya, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "See ya, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Here.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lardoc_bashsmite.lua b/data/npc/scripts/lardoc_bashsmite.lua new file mode 100644 index 00000000000..b357d0d72a6 --- /dev/null +++ b/data/npc/scripts/lardoc_bashsmite.lua @@ -0,0 +1,248 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local playerTopic = {} +local quantidade = {} + +local function greetCallback(cid) + local player = Player(cid) + if player then + npcHandler:setMessage(MESSAGE_GREET, {"Since you are obviously not one of my relatives who pays me a long overdue visit, we should get {work} right away. We'll see if you can prove your {worth} to our alliance."}) + playerTopic[cid] = 1 + end + npcHandler:addFocus(cid) + return true +end + +keywordHandler:addKeyword({'work'}, StdModule.say, {npcHandler = npcHandler, text = 'Here\'s the situation: a tide of hazardous bugs, the gnomes named them {diremaws}, threatens our base. Then there is some kind of {growth} which seems connected to them somehow. We need to get rid of both.'}) +keywordHandler:addKeyword({'worth'}, StdModule.say, {npcHandler = npcHandler, text = {'You\'re already known amongst the gnomes, member of the Bigfoot Brigade. I will make sure that the alliance learns of your deeds but you\'ll still need to help the dwarves and gnomes of this outpost to show your worth. ...', + 'We also found suspicious devices carried by all kinds of creatures down here. Down here, they are of extreme worth to us since they could contain the key to what\'s happening all around us. ... ', + 'If you can aquire any, return them to me and I make sure to tell the others of your generosity. Return to me afterwards to check on your current {status}.'}}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = {'Leading the charge! It\'s a war down here. I maintain the outer defences and supplies which are organised back in Kazordoon and also by the gnomes. ...', + 'I have sealed some of the areas far too dangerous for anyone to enter. If you can prove you\'re capable, you\'ll get an oportunity to help destroying the weird machines, pumping lava into the caves leading to the most dangerous enemies.', + 'But even if we knew nothing more about them, the fact alone that they employ the help of those mockeries of all things dwarfish, marks them as an enemy of the dwarves and it\'s our obligation to annihilate them.'}}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'Bashsmite. That\'s all you need to know.'}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + npcHandler.topic[cid] = playerTopic[cid] + local player = Player(cid) + npc = Npc(cid) + + local tempo = 20*60*60 + + -- missão diremaws + if msgcontains(msg, "diremaws") and npcHandler.topic[cid] == 1 then + if player:getStorageValue(Storage.DangerousDepths.Scouts.Diremaw ) == 2 and player:getStorageValue(Storage.DangerousDepths.Scouts.TimeTaskDiremaws) > 0 then -- Ainda não se passaram as 20h + npcHandler:say({"I don't need your help for now. Come back later."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + if player:getStorageValue(Storage.DangerousDepths.Scouts.Diremaw) == 2 and player:getStorageValue(Storage.DangerousDepths.Scouts.TimeTaskDiremaws) <= 0 then -- Vai fazer a missão após 20h + npcHandler:say({"The gnomes say that these creatures seem to thrive on mushroom sponges. But not only that, apparently they also lay eggs in their own cadavers to breed even faster. ...", + "Yes, disgusting. I guess it provides everything their offspring needs... well, we probably shouldn't go into that much further. Instead we should focus on preventing that from happening. ... ", + "If I understood that correctly, the gnomes 'grew' a device to completely neutralise diremaw corpses. Acting as a very effective counter measure. ... ", + "A lot of corpses are lying around wherever these creatures are being hunted. Now all we need are, you guessed it, volunteers to clean up as many of those remains as possible ... ", + "Are you willing to help? "}, cid) + playerTopic[cid] = 2 + npcHandler.topic[cid] = 2 + end + if player:getStorageValue(Storage.DangerousDepths.Scouts.Diremaw) < 1 then -- Não possuía a missão, agora possui! + npcHandler:say({"The gnomes say that these creatures seem to thrive on mushroom sponges. But not only that, apparently they also lay eggs in their own cadavers to breed even faster. ...", + "Yes, disgusting. I guess it provides everything their offspring needs... well, we probably shouldn't go into that much further. Instead we should focus on preventing that from happening. ... ", + "If I understood that correctly, the gnomes 'grew' a device to completely neutralise diremaw corpses. Acting as a very effective counter measure. ... ", + "A lot of corpses are lying around wherever these creatures are being hunted. Now all we need are, you guessed it, volunteers to clean up as many of those remains as possible ... ", + "Are you willing to help? "}, cid) + playerTopic[cid] = 2 + npcHandler.topic[cid] = 2 + elseif (player:getStorageValue(Storage.DangerousDepths.Scouts.Diremaw) == 1) and (player:getStorageValue(Storage.DangerousDepths.Scouts.DiremawsCount) < 20) then -- Está na missão porém não terminou a task! + npcHandler:say({"Come back when you have finished your job."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.DangerousDepths.Scouts.Diremaw) == 1 and player:getStorageValue(Storage.DangerousDepths.Scouts.DiremawsCount) >= 20 then -- Não possuía a missão, agora possui! + npcHandler:say({"You got rid of a lot of corpses, very good. Now we have a realistic chance of pushing them back! Return to me later for more work if you want."}, cid) + player:setStorageValue(Storage.DangerousDepths.Dwarves.TimeTaskDiremaws, os.time() + tempo) + player:addItem(32014, 1) + player:setStorageValue(Storage.DangerousDepths.Scouts.Status, player:getStorageValue(Storage.DangerousDepths.Scouts.Status) + 1) + player:setStorageValue(Storage.DangerousDepths.Scouts.Diremaw, 2) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + elseif npcHandler.topic[cid] == 2 and msgcontains(msg, "yes") then + npcHandler:say({"Noted. Get one of the gnomish devices from the container next to me and 'use' it on any diremaw corpses to effectively neutralise them. At least the gnomes told me this will work - good luck!"}, cid) + if player:getStorageValue(Storage.DangerousDepths.Questline) < 1 then + player:setStorageValue(Storage.DangerousDepths.Questline, 1) + end + player:setStorageValue(Storage.DangerousDepths.Scouts.Diremaw, 1) + player:setStorageValue(Storage.DangerousDepths.Scouts.GnomishChest, 1) -- Permissão para usar o baú + player:setStorageValue(Storage.DangerousDepths.Scouts.DiremawsCount, 0) -- Garantindo que a task não inicie com -1 + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + + -- missão growth + if msgcontains(msg, "growth") and npcHandler.topic[cid] == 1 then + if player:getStorageValue(Storage.DangerousDepths.Scouts.Growth ) == 2 and player:getStorageValue(Storage.DangerousDepths.Scouts.TimeTaskGrowth) > 0 then -- Ainda não se passaram as 20h + npcHandler:say({"I don't need your help for now. Come back later."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + if player:getStorageValue(Storage.DangerousDepths.Scouts.Growth) == 2 and player:getStorageValue(Storage.DangerousDepths.Scouts.TimeTaskGrowth) <= 0 then -- Vai fazer a missão após 20h + npcHandler:say({"I can't explain that stuff, even the gnomes don't know what grows in those caves. All we know is that this stuff brought about all the diremaws we are now facing. ...", + "This vermin is somehow attracted to this sponge, my guess is they use it as a nourishment, too. We need to get rid of the stuff regularly to reduce their numbers to a manageable level. ...", + "We hauled our explosives down there - and I mean ALL our explosives. Dangerous? Indeed, so we positioned someone down there to actually watch this depot. ...", + "We built an iron fence around it and added a mechanism to quickly get barrel if need be. Then an... accident happened to our guard down there and ...", + "Well, to make a long story short, the barrels are unguarded right now and the diremaws are now too numerous and we are in desperate need of volunteers. ... ", + "We need someone to take those barrels to the source of the ever growing sponge and burn it down. All of it. There should be at least five locations. Are you up for that? "}, cid) + playerTopic[cid] = 22 + npcHandler.topic[cid] = 22 + end + if player:getStorageValue(Storage.DangerousDepths.Scouts.Growth) < 1 then -- Não possuía a missão, agora possui! + npcHandler:say({"I can't explain that stuff, even the gnomes don't know what grows in those caves. All we know is that this stuff brought about all the diremaws we are now facing. ...", + "This vermin is somehow attracted to this sponge, my guess is they use it as a nourishment, too. We need to get rid of the stuff regularly to reduce their numbers to a manageable level. ...", + "We hauled our explosives down there - and I mean ALL our explosives. Dangerous? Indeed, so we positioned someone down there to actually watch this depot. ...", + "We built an iron fence around it and added a mechanism to quickly get barrel if need be. Then an... accident happened to our guard down there and ...", + "Well, to make a long story short, the barrels are unguarded right now and the diremaws are now too numerous and we are in desperate need of volunteers. ... ", + "We need someone to take those barrels to the source of the ever growing sponge and burn it down. All of it. There should be at least five locations. Are you up for that? "}, cid) + playerTopic[cid] = 22 + npcHandler.topic[cid] = 22 + end + if player:getStorageValue(Storage.DangerousDepths.Scouts.Growth) == 1 and player:getStorageValue(Storage.DangerousDepths.Scouts.BarrelCount) >= 3 then -- Não possuía a missão, agora possui! + npcHandler:say({"You did a great job out there, the stuff will continue to grow, however. Return to me later for more work."}, cid) + player:setStorageValue(Storage.DangerousDepths.Dwarves.TimeTaskGrowth, os.time() + tempo) + if player:getStorageValue(Storage.DangerousDepths.Scouts.BarrelCount) >= 5 then + player:addItem(32014, 2) + player:setStorageValue(Storage.DangerousDepths.Scouts.Status, player:getStorageValue(Storage.DangerousDepths.Scouts.Status) + 2) + else + player:addItem(32014, 1) + player:setStorageValue(Storage.DangerousDepths.Scouts.Status, player:getStorageValue(Storage.DangerousDepths.Scouts.Status) + 1) + end + player:setStorageValue(Storage.DangerousDepths.Scouts.Growth, 2) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + elseif npcHandler.topic[cid] == 22 and msgcontains(msg, "yes") then + npcHandler:say({"Noted. Now, get down there and rain some fire on them."}, cid) + if player:getStorageValue(Storage.DangerousDepths.Questline) < 1 then + player:setStorageValue(Storage.DangerousDepths.Questline, 1) + end + player:setStorageValue(Storage.DangerousDepths.Scouts.Growth, 1) + player:setStorageValue(Storage.DangerousDepths.Scouts.BarrelCount, 0) -- Garantindo que a task não inicie com -1 + player:setStorageValue(Storage.DangerousDepths.Scouts.FirstBarrel, 0) -- Garantindo que a task não inicie com -1 + player:setStorageValue(Storage.DangerousDepths.Scouts.SecondBarrel, 0) -- Garantindo que a task não inicie com -1 + player:setStorageValue(Storage.DangerousDepths.Scouts.ThirdBarrel, 0) -- Garantindo que a task não inicie com -1 + player:setStorageValue(Storage.DangerousDepths.Scouts.FourthBarrel, 0) -- Garantindo que a task não inicie com -1 + player:setStorageValue(Storage.DangerousDepths.Scouts.FifthBarrel, 0) -- Garantindo que a task não inicie com -1 + + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + + + local plural = "" + if msgcontains(msg, "suspicious devices") or msgcontains(msg, "suspicious device") then + npcHandler:say({"If you bring me any suspicious devices on creatures you slay down here, I'll make it worth your while by telling the others of your generosity. How many do you want to offer? "}, cid) + playerTopic[cid] = 55 + npcHandler.topic[cid] = 55 + elseif npcHandler.topic[cid] == 55 then + quantidade[cid] = tonumber(msg) + if quantidade[cid] then + if quantidade[cid] > 1 then + plural = plural .. "s" + end + npcHandler:say({"You want to offer " .. quantidade[cid] .. " suspicious device" ..plural.. ". Which leader shall have it, (Gnomus) of the {gnomes}, (Klom Stonecutter) of the {dwarves} or the {scouts} (Lardoc Bashsmite)?"}, cid) + playerTopic[cid] = 56 + npcHandler.topic[cid] = 56 + else + npcHandler:say({"Don't waste my time."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "gnomes") and npcHandler.topic[cid] == 56 then + if player:getItemCount(30888) >= quantidade[cid] then + npcHandler:say({"Done."}, cid) + if quantidade[cid] > 1 then + plural = plural .. "s" + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You earned ".. quantidade[cid] .." point"..plural.." on the gnomes mission.") + player:removeItem(30888, quantidade[cid]) + player:setStorageValue(Storage.DangerousDepths.Gnomes.Status, player:getStorageValue(Storage.DangerousDepths.Gnomes.Status) + quantidade[cid]) + else + npcHandler:say({"You don't have enough suspicious devices."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "dwarves") and npcHandler.topic[cid] == 56 then + if player:getItemCount(30888) >= quantidade[cid] then + npcHandler:say({"Done."}, cid) + if quantidade[cid] > 1 then + plural = plural .. "s" + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You earned ".. quantidade[cid] .." point"..plural.." on the dwarves mission.") + player:removeItem(30888, quantidade[cid]) + player:setStorageValue(Storage.DangerousDepths.Dwarves.Status, player:getStorageValue(Storage.DangerousDepths.Dwarves.Status) + quantidade[cid]) + else + npcHandler:say({"You don't have enough suspicious devices."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "scouts") and npcHandler.topic[cid] == 56 then + if player:getItemCount(30888) >= quantidade[cid] then + npcHandler:say({"Done."}, cid) + if quantidade[cid] > 1 then + plural = plural .. "s" + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You earned ".. quantidade[cid] .." point"..plural.." on the scouts mission.") + player:removeItem(30888, quantidade[cid]) + player:setStorageValue(Storage.DangerousDepths.Scouts.Status, player:getStorageValue(Storage.DangerousDepths.Scouts.Status) + quantidade[cid]) + else + npcHandler:say({"You don't have enough suspicious devices."}, cid) + playerTopic[cid] = 1 + npcHandler.topic[cid] = 1 + end + end + + + + -- Início checagem de pontos de tasks!! + if msgcontains(msg, "status") then + npcHandler:say({"So you want to know what we all think about your deeds? What leader\'s opinion are you interested in, the {gnomes} (Gnomus), the {dwarves} (Klom Stonecutter) or the {scouts} (Lardoc Bashsmite)?"}, cid) + playerTopic[cid] = 5 + npcHandler.topic[cid] = 5 + elseif msgcontains(msg, "gnomes") and npcHandler.topic[cid] == 5 then + npcHandler:say({'The gnomes are still in need of your help, member of Bigfoot\'s Brigade. Prove your worth by answering their calls! (' .. math.max(player:getStorageValue(Storage.DangerousDepths.Gnomes.Status), 0) .. '/10)'}, cid) + elseif msgcontains(msg, "dwarves") and npcHandler.topic[cid] == 5 then + npcHandler:say({'The dwarves are still in need of your help, member of Bigfoot\'s Brigade. Prove your worth by answering their calls! (' .. math.max(player:getStorageValue(Storage.DangerousDepths.Dwarves.Status), 0) .. '/10)'}, cid) + elseif msgcontains(msg, "scouts") and npcHandler.topic[cid] == 5 then + npcHandler:say({'The scouts are still in need of your help, member of Bigfoot\'s Brigade. Prove your worth by answering their calls! (' .. math.max(player:getStorageValue(Storage.DangerousDepths.Scouts.Status), 0) .. '/10)'}, cid) + end + return true +end + + + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/larek.lua b/data/npc/scripts/larek.lua new file mode 100644 index 00000000000..5eceb891b3f --- /dev/null +++ b/data/npc/scripts/larek.lua @@ -0,0 +1,19 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/larfion_the_shaman.lua b/data/npc/scripts/larfion_the_shaman.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/larfion_the_shaman.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lavirias.lua b/data/npc/scripts/lavirias.lua new file mode 100644 index 00000000000..eac508821e8 --- /dev/null +++ b/data/npc/scripts/lavirias.lua @@ -0,0 +1,25 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +-- Greeting message +keywordHandler:addGreetKeyword({"ashari"}, {npcHandler = npcHandler, text = "Greetings, |PLAYERNAME|."}) +--Farewell message +keywordHandler:addFarewellKeyword({"asgha thrazi"}, {npcHandler = npcHandler, text = "Goodbye, |PLAYERNAME|."}) + +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye!") + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/lazaran.lua b/data/npc/scripts/lazaran.lua new file mode 100644 index 00000000000..817d16ecdfd --- /dev/null +++ b/data/npc/scripts/lazaran.lua @@ -0,0 +1,135 @@ + +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "mission") and player:getStorageValue(Storage.TheNewFrontier.Questline) == 9 then + if npcHandler.topic[cid] == 0 then + npcHandler:say("Me people wanting {peace}. No war with others. No war with {little men}. We few. We weak. Need {help}. We not wanting make {war}. No hurt.", cid) + npcHandler.topic[cid] = 10 + end + elseif msgcontains(msg, "peace") and npcHandler.topic[cid] == 10 and player:getStorageValue(Storage.TheNewFrontier.Questline) == 9 then + npcHandler:say("Me people wanting peace. No war with others. No war with little men.", cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 10) + player:setStorageValue(Storage.TheNewFrontier.Mission03, 2) --Questlog, The New Frontier Quest "Mission 03: Strangers in the Night" + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "help") then + npcHandler:say("You mean you want help us?", cid) + npcHandler.topic[cid] = 11 + elseif msgcontains(msg, "mission") and npcHandler.topic[cid] == 12 and player:getStorageValue(Storage.UnnaturalSelection.Questline) < 1 + and player:getStorageValue(Storage.TheNewFrontier.Mission03) == 3 then + npcHandler:say({ + "Big problem we have! Skull of first leader gone. He ancestor of whole tribe but died long ago in war. We have keep his skull on our sacred place. ...", + "Then one night, green men came with wolves... and one of wolves took skull and ran off chewing on it! We need back - many wisdom and power is in skull. Maybe they took to north fortress. But can be hard getting in. You try get our holy skull back?" + }, cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "mission") and player:getStorageValue(Storage.UnnaturalSelection.Questline) >= 1 then + if player:getStorageValue(Storage.UnnaturalSelection.Questline) == 1 then + npcHandler:say("Oh! You found holy skull? In bone pile you found?! Thank Pandor you brought! Me can have it back?", cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(Storage.UnnaturalSelection.Questline) == 2 then + npcHandler:say({ + "You brought back skull of first leader. Hero of tribe! But we more missions to do. ...", + "Me and Ulala talk about land outside. We wanting to see more of land! Land over big water! But us no can leave tribe. No can cross water. Only way is skull of first leader. ...", + "What holy skull sees, tribe sees. That we believe. Can you bring holy skull over big water and show places?" + }, cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.UnnaturalSelection.Questline) == 3 then + npcHandler:say("You say you was to where sun is hot and burning? And where trees grow as high as mountain? And where Fasuon cries white tears? Me can't wait to see!! Can have holy skull back?", cid) + npcHandler.topic[cid] = 4 + elseif player:getStorageValue(Storage.UnnaturalSelection.Questline) == 4 then + npcHandler:say("We been weak for too long! We prepare for great hunt. But still need many doings! You can help us?", cid) + npcHandler.topic[cid] = 5 + elseif player:getStorageValue(Storage.UnnaturalSelection.Questline) == 13 then + npcHandler:say({ + "You well did! Great hunt is under best signs now. We prepare weapons and paint faces and then go! ...", + "No no, you no need to help us. But can prepare afterparty! Little men sent us stuff some time ago. Was strange water in there. Brown and stinky! But when we tried all tribe became veeeeeeery happy. ...", + "Now brown water is gone and we sad! Can you bring POT of brown water for party after great hunt? Just bring to me and me trade for shiny treasure." + }, cid) + player:setStorageValue(Storage.UnnaturalSelection.Questline, 14) + player:setStorageValue(Storage.UnnaturalSelection.Mission06, 2) --Questlog, Unnatural Selection Quest "Mission 6: Firewater Burn" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.UnnaturalSelection.Questline) == 14 then + npcHandler:say("You bring us big pot of strange water from little men?", cid) + npcHandler.topic[cid] = 6 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("You hero of our tribe if bring back holy skull!", cid) + player:setStorageValue(Storage.UnnaturalSelection.Questline, 1) + player:setStorageValue(Storage.UnnaturalSelection.Mission01, 1) --Questlog, Unnatural Selection Quest "Mission 1: Skulled" + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + if player:removeItem(11076, 1) then + npcHandler:say("Me thank you much! All wisdom safe again now.", cid) + player:setStorageValue(Storage.UnnaturalSelection.Questline, 2) + player:setStorageValue(Storage.UnnaturalSelection.Mission01, 3) --Questlog, Unnatural Selection Quest "Mission 1: Skulled" + npcHandler.topic[cid] = 0 + else + npcHandler:say("You do not have it!", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 3 then + npcHandler:say("Here take holy skull. You bring where you think is good. See as much as possible! See where other people live!", cid) + player:addItem(11076, 1) + player:setStorageValue(Storage.UnnaturalSelection.Questline, 3) + player:setStorageValue(Storage.UnnaturalSelection.Mission02, 1) --Questlog, Unnatural Selection Quest "Mission 2: All Around the World" + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 4 then + if player:getStorageValue(Storage.UnnaturalSelection.Mission02) == 12 and player:getItemCount(11076) >= 1 then + npcHandler:say("We make big ritual soon and learn much about world outside. Me thank you many times for teaching us world. Very wise and adventurous you are!", cid) + player:removeItem(11076, 1) + player:setStorageValue(Storage.UnnaturalSelection.Questline, 4) + player:setStorageValue(Storage.UnnaturalSelection.Mission02, 13) --Questlog, Unnatural Selection Quest "Mission 2: All Around the World" + npcHandler.topic[cid] = 0 + else + npcHandler:say("The skull have not seen all yet!", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 5 then + npcHandler:say("We need to calm and make happy gods. Best go to Ulala. She is priest of us and can tell what needs doing.", cid) + player:setStorageValue(Storage.UnnaturalSelection.Questline, 5) + player:setStorageValue(Storage.UnnaturalSelection.Mission03, 1) --Questlog, Unnatural Selection Quest "Mission 3: Dance Dance Evolution" + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 6 then + if player:removeItem(2562, 1, 3) then + npcHandler:say("We make big ritual soon and learn much about world outside. Me thank you many times for teaching us world. Very wise and adventurous you are!", cid) + player:addItem(11115, 1) + player:setStorageValue(Storage.UnnaturalSelection.Questline, 15) + player:setStorageValue(Storage.UnnaturalSelection.Mission06, 3) --Questlog, Unnatural Selection Quest "Mission 6: Firewater Burn" + npcHandler.topic[cid] = 0 + else + npcHandler:say("You do not have the brown strange water!", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 11 then + npcHandler:say("Me have many small task, but also big {mission}. You say what want.", cid) + npcHandler.topic[cid] = 12 + end + elseif msgcontains(msg, "war") then + npcHandler:say("Many mighty monster rule land. We fight. We lose. We flee to mountain to hide.", cid) + elseif msgcontains(msg, "little men") then + npcHandler:say("We come and see little men. They like us, only very little. They having good weapon and armor, like the greens.", cid) + end + return true +end +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lea.lua b/data/npc/scripts/lea.lua new file mode 100644 index 00000000000..68bbcefb195 --- /dev/null +++ b/data/npc/scripts/lea.lua @@ -0,0 +1,28 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am the archsorcerer of Carlin. I keep the secrets of our order."}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "My name is Lea."}) +--keywordHandler:addKeyword({'spell'}, StdModule.say, {npcHandler = npcHandler, text = "Sorry, I only sell spells to sorcerers."}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = "Time is a force we sorcerers will master one day."}) +keywordHandler:addKeyword({'sorcerer'}, StdModule.say, {npcHandler = npcHandler, text = "Any sorcerer dedicates his whole life to the study of the arcane arts."}) +keywordHandler:addKeyword({'power'}, StdModule.say, {npcHandler = npcHandler, text = "We sorcerers wield arcane powers beyond comprehension of men."}) +keywordHandler:addKeyword({'arcane'}, StdModule.say, {npcHandler = npcHandler, text = "We sorcerers wield arcane powers beyond comprehension of men."}) + +npcHandler:setMessage(MESSAGE_GREET, "Greetings, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Take care on your journeys.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lector.lua b/data/npc/scripts/lector.lua new file mode 100644 index 00000000000..9f141d4cd09 --- /dev/null +++ b/data/npc/scripts/lector.lua @@ -0,0 +1,23 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'meat'}, StdModule.say, {npcHandler = npcHandler, text = "I can offer you ham or meat. If you'd like to check the quality of my wares, ask me for a {trade}."}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome to my humble {meat} shop, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Please come and buy again, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Of course, take a good look at my meat.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lee_delle.lua b/data/npc/scripts/lee_delle.lua new file mode 100644 index 00000000000..ab802914e6f --- /dev/null +++ b/data/npc/scripts/lee_delle.lua @@ -0,0 +1,118 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Ask me if you need help!' }, + { text = 'Buy and sell everything you want here!' }, + { text = 'No need to run from shop to shop, my place is all that\'s needed!' }, + { text = 'Special offers for premium customers!' } +} +npcHandler:addModule(VoiceModule:new(voices)) + +-- Basic keywords +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Lee\'Delle.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m a merchant. If you like to see my offers, just ask me for a {trade}.'}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = 'It\'s about |TIME|.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, it\'s a good idea to leave most of your money in the bank and only take what you need. That way your gold is safe.'}) +keywordHandler:addKeyword({'cookie'}, StdModule.say, {npcHandler = npcHandler, text = 'Oh no! I\'ve got to watch what I eat. {Lily} loves cookies, though.'}) +keywordHandler:addKeyword({'merchant'}, StdModule.say, {npcHandler = npcHandler, text = 'There are many merchants in this village. Just ask them for a {trade} to see their offers. But I can promise you - my offers are the best around!'}) +keywordHandler:addKeyword({'how', 'are', 'you'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m fine. I\'m delighted to welcome you as my customer.'}) +keywordHandler:addKeyword({'information'}, StdModule.say, {npcHandler = npcHandler, text = 'What kind of information do you need? I could tell you about different topics such as {equipment}, {monsters} or {Rookgaard} in general.'}) +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'How can I help you? Would you like to {trade} with me? I can also give you general {hints}. Or just ask me anything you\'d like to know.'}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = 'You should really take some time and travel around the marvellous areas of Tibia. There\'s everything - ice islands, deserts, jungles and mountains!'}) +keywordHandler:addKeyword({'temple'}, StdModule.say, {npcHandler = npcHandler, text = 'The temple is the place to go when you are very low on {health} or poisoned. Ask {Cipfried} for a heal - he usually notices emergencies by himself.'}) +keywordHandler:addKeyword({'health'}, StdModule.say, {npcHandler = npcHandler, text = 'Health potions will heal you for about 75 hit points. It can\'t hurt to carry one with you, just in case.'}) +keywordHandler:addKeyword({'equipment'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, very important equipment would be a {backpack}, a {rope}, a {shovel}, a {weapon}, an {armor} and a {shield}. Maybe also a torch if you\'re heading into a dark {dungeon}.'}) +keywordHandler:addKeyword({'fishing'}, StdModule.say, {npcHandler = npcHandler, text = 'I sell fishing rods and worms in case you want to go fishing. Simply ask me for a {trade}.'}) +keywordHandler:addKeyword({'weapon'}, StdModule.say, {npcHandler = npcHandler, text = 'You could check out which weapons I offer by asking me for a {trade}. Don\'t be shy!'}) +keywordHandler:addKeyword({'food'}, StdModule.say, {npcHandler = npcHandler, text = 'Oh, I\'m sorry, that\'s one of the things I don\'t have for sale. But {Willie} or {Billy} surely have something to eat for you.'}) +keywordHandler:addKeyword({'king'}, StdModule.say, {npcHandler = npcHandler, text = 'The king supports our little village very much!'}) +keywordHandler:addKeyword({'academy'}, StdModule.say, {npcHandler = npcHandler, text = 'In the academy you can get a lot of information from books. You can also try out a few things by yourself.'}) +keywordHandler:addKeyword({'rookgaard'}, StdModule.say, {npcHandler = npcHandler, text = 'Isn\'t it lovely here? You\'ll be surprised once you reach the {mainland} - so much to explore!'}) +keywordHandler:addKeyword({'mainland'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, the mainland also consists of several continents. You can go there once you\'ve reached level 8 and talked to the {oracle}.'}) +keywordHandler:addKeyword({'monster'}, StdModule.say, {npcHandler = npcHandler, text = 'Good monsters to start with are rats. They live in the {sewers} under the village of {Rookgaard}.'}) +keywordHandler:addKeyword({'sell'}, StdModule.say, {npcHandler = npcHandler, text = 'Just ask me for a {trade} to see what I buy from you.'}) +keywordHandler:addKeyword({'dungeon'}, StdModule.say, {npcHandler = npcHandler, text = 'Be careful down there! Make sure you bought enough {torches} and a {rope} or you might get lost.'}) +keywordHandler:addKeyword({'sewer'}, StdModule.say, {npcHandler = npcHandler, text = 'There are many sewer entrances throughout Rookgaard. If you want to know more details about monsters and dungeons, best talk to one of the guards.'}) + +keywordHandler:addKeyword({'offer'}, StdModule.say, {npcHandler = npcHandler, text = 'Just ask me for a {trade} to see my offers. Apart from that, I also sell {footballs}.'}) +keywordHandler:addAliasKeyword({'stuff'}) +keywordHandler:addAliasKeyword({'wares'}) +keywordHandler:addAliasKeyword({'buy'}) + +keywordHandler:addKeyword({'quest'}, StdModule.say, {npcHandler = npcHandler, text = 'I really love flowers. My favourites are {honey flowers}. Sadly, they are very rare on this isle. If you can find one for me, I\'ll give you a little reward.'}) +keywordHandler:addAliasKeyword({'mission'}) + +keywordHandler:addKeyword({'armor'}, StdModule.say, {npcHandler = npcHandler, text = 'You could check out which armors or shields I offer by asking me for a {trade}. Don\'t be shy!'}) +keywordHandler:addAliasKeyword({'shield'}) + +keywordHandler:addKeyword({'backpack'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes, I\'m selling that. Simply ask me for a {trade} to view all my offers.'}) +keywordHandler:addAliasKeyword({'rope'}) +keywordHandler:addAliasKeyword({'shovel'}) +keywordHandler:addAliasKeyword({'torch'}) + +keywordHandler:addKeyword({'money'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, no gold, no deal. Earn gold by fighting {monsters} and picking up the things they carry. Sell it to {merchants} to make profit!'}) +keywordHandler:addAliasKeyword({'gold'}) + +-- Names +keywordHandler:addKeyword({'hint'}, StdModule.rookgaardHints, {npcHandler = npcHandler}) +keywordHandler:addKeyword({'obi'}, StdModule.say, {npcHandler = npcHandler, text = 'He sells {weapons}. However, I can offer you better deals than him!'}) +keywordHandler:addKeyword({'norma'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m glad she stopped selling stuff. There was too much of a competition going on!'}) +keywordHandler:addKeyword({'loui'}, StdModule.say, {npcHandler = npcHandler, text = 'Sometimes, I see him walking outside the village near some hole.'}) +keywordHandler:addKeyword({'santiago'}, StdModule.say, {npcHandler = npcHandler, text = 'He dedicated his life to welcome newcomers to this island.'}) +keywordHandler:addKeyword({'zirella'}, StdModule.say, {npcHandler = npcHandler, text = 'Poor old woman, her son {Tom} never visits her.'}) +keywordHandler:addKeyword({'al', 'dee'}, StdModule.say, {npcHandler = npcHandler, text = 'Al Dee has a general {equipment} store in the north-western part of the village.'}) +keywordHandler:addKeyword({'amber'}, StdModule.say, {npcHandler = npcHandler, text = 'She lives under the {academy}. Always nice to chat with her!'}) +keywordHandler:addKeyword({'billy'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s a local farmer. If you need fresh {food} to regain health, it\'s a good place to go. He\'s only trading with premium adventurers, though.'}) +keywordHandler:addKeyword({'willie'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s a local farmer. If you need fresh {food} to regain your health, it\'s a good place to go. However, many monsters carry also food such as meat. Or you could simply pick {blueberries}.'}) +keywordHandler:addKeyword({'cipfried'}, StdModule.say, {npcHandler = npcHandler, text = 'Visiting Cipfried in the {temple} is a good idea if you are injured or poisoned. He can heal you.'}) +keywordHandler:addKeyword({'dixi'}, StdModule.say, {npcHandler = npcHandler, text = 'She\'s {Obi\'s} granddaughter and deals with {armors} and {shields}, just as I do.'}) +keywordHandler:addKeyword({'hyacinth'}, StdModule.say, {npcHandler = npcHandler, text = 'He mostly stays by himself. He\'s a hermit outside of town - good luck finding him.'}) +keywordHandler:addKeyword({'lily'}, StdModule.say, {npcHandler = npcHandler, text = 'She buys all {blueberries} and {cookies} you can find.'}) +keywordHandler:addKeyword({'oracle'}, StdModule.say, {npcHandler = npcHandler, text = 'You can find the oracle on the top floor of the {academy}, just above {Seymour}. Go there when you are level 8 to reach more areas of {Tibia}.'}) +keywordHandler:addKeyword({'paulie'}, StdModule.say, {npcHandler = npcHandler, text = 'He is the {bank} clerk, just below the academy.'}) +keywordHandler:addKeyword({'seymour'}, StdModule.say, {npcHandler = npcHandler, text = 'Seymour is a teacher running the {academy}. He has a lot of important {information} about Tibia.'}) +keywordHandler:addKeyword({'tom'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s the local tanner. You could try selling fresh corpses or leather to him.'}) +keywordHandler:addKeyword({'dallheim'}, StdModule.say, {npcHandler = npcHandler, text = 'He is a great warrior and our protector.'}) +keywordHandler:addAliasKeyword({'zerbrus'}) + +-- Football +local footballKeyword = keywordHandler:addKeyword({'football'}, StdModule.say, {npcHandler = npcHandler, text = 'Do you want to buy a football for 111 gold?'}) + footballKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you go.', reset = true}, + function(player) return player:getMoney() + player:getBankBalance() >= 111 end, + function(player) + if player:removeMoneyNpc(111) then + player:addItem(2109, 1) + end + end + ) + footballKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'You don\'t have enough money.', reset = true}) + footballKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Oh, but it\'s fun to play!', reset = true}) + +-- Honey Flower +keywordHandler:addKeyword({'honey', 'flower'}, StdModule.say, {npcHandler = npcHandler, text = 'Oh, thank you so much! Please take this piece of armor as reward.'}, + function(player) return player:getItemCount(2103) > 0 end, + function(player) player:removeItem(2103, 1) player:addItem(2468, 1) end +) +keywordHandler:addKeyword({'honey', 'flower'}, StdModule.say, {npcHandler = npcHandler, text = 'Honey flowers are my favourites .'}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Bye, bye.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Bye, bye, |PLAYERNAME|.') +npcHandler:setMessage(MESSAGE_SENDTRADE, 'Sure, take a look, honey.') +npcHandler:setMessage(MESSAGE_GREET, 'Nice to see you, |PLAYERNAME|! Ask me for a {trade} if you like to see my exclusive offers.') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/leeland.lua b/data/npc/scripts/leeland.lua new file mode 100644 index 00000000000..cbae8d852df --- /dev/null +++ b/data/npc/scripts/leeland.lua @@ -0,0 +1,41 @@ + +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + local player = Player(cid) + if not npcHandler:isFocused(cid) then + return false + --The New Frontier + elseif msgcontains(msg, "farmine") then + if player:getStorageValue(Storage.TheNewFrontier.Questline) == 15 then + npcHandler:say("Oh yes, that project the whole dwarven community is so excited about. I guess I already know why you are here, but speak up.", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "impress") or msgcontains(msg, "plea") then + if npcHandler.topic[cid] == 1 then + if player:getStorageValue(Storage.TheNewFrontier.BribeLeeland) < 1 then + npcHandler:say("The idea of a promising market and new resources suits us quite well. I think it is reasonable to send some assistance.", cid) + player:setStorageValue(Storage.TheNewFrontier.BribeLeeland, 1) + player:setStorageValue(Storage.TheNewFrontier.Mission05, player:getStorageValue(Storage.TheNewFrontier.Mission05) + 1) --Questlog, The New Frontier Quest "Mission 05: Getting Things Busy" + end + end + end + return true +end +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/legola.lua b/data/npc/scripts/legola.lua new file mode 100644 index 00000000000..3ad85768b8e --- /dev/null +++ b/data/npc/scripts/legola.lua @@ -0,0 +1,55 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Teaching paladin spells! Just come to me!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Sniper Gloves +keywordHandler:addKeyword({'sniper gloves'}, StdModule.say, {npcHandler = npcHandler, text = 'We are always looking for sniper gloves. They are supposed to raise accuracy. If you find a pair, bring them here. Maybe I can offer you a nice trade.'}, function(player) return player:getItemCount(5875) == 0 end) + +local function addGloveKeyword(text, condition, action) + local gloveKeyword = keywordHandler:addKeyword({'sniper gloves'}, StdModule.say, {npcHandler = npcHandler, text = text[1]}, condition) + gloveKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = text[2], reset = true}, function(player) return player:getItemCount(5875) == 0 end) + gloveKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = text[3], reset = true}, nil, action) + gloveKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = text[2], reset = true}) +end + +-- Free Account +addGloveKeyword({ + 'You found sniper gloves?! Incredible! I would love to grant you the sniper gloves accessory, but I can only do that for premium warriors. However, I would pay you 2000 gold pieces for them. How about it?', + 'Maybe another time.', + 'Alright! Here is your money, thank you very much.' + }, function(player) return not player:isPremium() end, function(player) player:removeItem(5875, 1) player:addMoney(2000) end +) + +-- Premium account with addon +addGloveKeyword({ + 'Did you find sniper gloves AGAIN?! Incredible! I cannot grant you other accessories, but would you like to sell them to me for 2000 gold pieces?', + 'Maybe another time.', + 'Alright! Here is your money, thank you very much.' + }, function(player) return player:getStorageValue(Storage.OutfitQuest.Hunter.AddonGlove) == 1 end, function(player) player:removeItem(5875, 1) player:addMoney(2000) end +) + +-- If you don't have the addon +addGloveKeyword({ + 'You found sniper gloves?! Incredible! Listen, if you give them to me, I will grant you the right to wear the sniper gloves accessory. How about it?', + 'No problem, maybe another time.', + 'Great! I hereby grant you the right to wear the sniper gloves as an accessory. Congratulations!' + }, function(player) return player:getStorageValue(Storage.OutfitQuest.Hunter.AddonGlove) == -1 end, function(player) player:removeItem(5875, 1) player:setStorageValue(Storage.OutfitQuest.Hunter.AddonGlove, 1) player:addOutfitAddon(129, 2) player:addOutfitAddon(137, 1) player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) end +) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lesser_messenger_of_heaven.lua b/data/npc/scripts/lesser_messenger_of_heaven.lua new file mode 100644 index 00000000000..d0c68ddbca1 --- /dev/null +++ b/data/npc/scripts/lesser_messenger_of_heaven.lua @@ -0,0 +1,18 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/liane.lua b/data/npc/scripts/liane.lua new file mode 100644 index 00000000000..8ab94cfc5cf --- /dev/null +++ b/data/npc/scripts/liane.lua @@ -0,0 +1,61 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Welcome to the post office!' }, + { text = 'Hey, send a letter to your friend now and then. Keep in touch, you know.' }, + { text = 'If you need help with letters or parcels, just ask me. I can explain everything.' }, + { text = 'No, no, no, there IS no parcel bug, I\'m telling you!' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "measurements") then + if player:getStorageValue(Storage.Postman.Mission07) >= 1 and player:getStorageValue(Storage.Postman.MeasurementsLiane) ~= 1 then + npcHandler:say("I have more urgent problem to attend then that. Those hawks are hunting my carrier pigeons. Bring me 12 arrows and I'll see if I have the time for this nonsense. Do you have 12 arrows with you? ", cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say("...", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + if player:removeItem(2544, 12) then + npcHandler:say("Great! Now I'll teach them a lesson ... For those measurements ... ", cid) + player:setStorageValue(Storage.Postman.Mission07, player:getStorageValue(Storage.Postman.Mission07) + 1) + player:setStorageValue(Storage.Postman.MeasurementsLiane, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Oh, you don\'t have it.", cid) + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "Hello. How may I help you |PLAYERNAME|? Ask me for a trade if you want to buy something. I can also explain the {mail} system.") +npcHandler:setMessage(MESSAGE_FAREWELL, "It was a pleasure to help you, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "It was a pleasure to help you, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Here. Don't forget that you need to buy a label too if you want to send a parcel. Always write the name of the {receiver} in the first line.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lightfoot.lua b/data/npc/scripts/lightfoot.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/lightfoot.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lily.lua b/data/npc/scripts/lily.lua new file mode 100644 index 00000000000..3559bdcc953 --- /dev/null +++ b/data/npc/scripts/lily.lua @@ -0,0 +1,257 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Are you injured or poisoned? Get your potions here! All natural, no artificial ingredients!' }, + { text = 'Hey you, over there! Let\'s have a little chat, shall we?' }, + { text = 'Oh, just in case you are looking for the marketplace and dungeons, just follow the path to the east.' }, + { text = 'Anyone got some cookies for me?' }, + { text = 'Do you need help? Just ask me about anything you\'d like to know!' }, + { text = 'I\'m buying all of your blueberries for my famous blueberry juice!' } +} +npcHandler:addModule(VoiceModule:new(voices)) + +local function greetCallback(cid) + local player = Player(cid) + -- Continue mission 4 + if player:getStorageValue(Storage.TheRookieGuard.Mission04) == 1 then + npcHandler:setMessage(MESSAGE_GREET, "Oh hey, |PLAYERNAME|! Vascalir must have sent you to help me with a little {mission}, right?") + -- Not finished mission 4 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission04) == 2 then + npcHandler:setMessage(MESSAGE_GREET, "Hello, |PLAYERNAME|! Back so soon? Have you delivered the herbs to Hyacinth?") + else + npcHandler:setMessage(MESSAGE_GREET, "Welcome, |PLAYERNAME|! You look a little stressed today. If you like to view my offers of potions, just ask me for a {trade}. In case you're looking for the marketplace and dungeons, just follow the path to the east!") + end + return true +end + +-- The Rookie Guard Quest - Mission 04: Home-Brewed + +-- Mission 4: Start +local mission4 = keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "That's great to hear! You see, I'm not the only potion brewer on Rookgaard. The hermit Hyacinth has his little alchemy lab outside the village. ...", + "He's old and can't make his way into the village anymore, but needs some of the herbs that grow only around here. Could you please deliver a bag of herbs to Hyacinth?" + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission04) == 1 end +) +keywordHandler:addAliasKeyword({"mission"}) + +-- Mission 4: Decline +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Oh. In that case, maybe you're interested in a {trade} - I sell potions and buy a few other things.", + reset = true +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission04) == 1 end +) + +-- Mission 4: Accept +mission4:addChildKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "Here you go, honey. I really appreciate your help. To find Hyacinth, leave the village to the north and go pretty much straight to the east. ...", + "His little alchemy lab is on top of a mountain. I'll mark the ramp leading up on your map, here. Don't stray from the path! There are dangerous monsters roaming the island." + } +}, +nil, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission04, 2) + player:addItemEx(Game.createItem(13827, 1), true, CONST_SLOT_WHEREEVER) + player:addMapMark({x = 32091, y = 32178, z = 7}, MAPMARK_GREENNORTH, "North Exit") + player:addMapMark({x = 32139, y = 32176, z = 7}, MAPMARK_GREENNORTH, "To Hyacinth") +end +) + +-- Mission 4: Decline +mission4:addChildKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Oh. Well, if you change your mind, let me know.", + reset = true +}) + +-- Mission 4: Confirm Delivered (Without) +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "No, you haven't. If you're looking for the way to Hyacinth, just leave the village to the north and then go east. I've marked it on your map!" +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission04) == 2 end +) + +-- Mission 4: Confirm Not Delivered (Without) +local mission4LostHerbs = keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Is something... wrong? You didn't lose the herbs, did you?" +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission04) == 2 end +) + +-- Mission 4: Confirm Lost Herbs +local mission4AcceptAnotherHerbs = mission4LostHerbs:addChildKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Well, at least you're honest. I can give you another sack, but only if you promise not to lose them this time. Okay?" +}) + +-- Mission 4: Decline Lost Herbs +mission4LostHerbs:addChildKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Phew. That's a relief. Well, don't forget to deliver them to Hyacinth! They have to be fresh to create potions.", + reset = true +}) + +-- Mission 4: Accept Lost Herbs +mission4AcceptAnotherHerbs:addChildKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "Here you go, honey. I really appreciate your help. To find Hyacinth, leave the village to the north and go pretty much straight to the east. ...", + "His little alchemy lab is on top of a mountain. I'll mark the ramp leading up on your map, here. Don't stray from the path! There are dangerous monsters roaming the island." + }, + reset = true +}, +nil, +function(player) + player:addItemEx(Game.createItem(13827, 1), true, CONST_SLOT_WHEREEVER) +end +) + +-- Mission 4: Reject Lost Herbs +mission4AcceptAnotherHerbs:addChildKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Oh. Well, if you change your mind, let me know.", + reset = true +}) + +-- Basic Keywords +keywordHandler:addKeyword({'sell'}, StdModule.say, {npcHandler = npcHandler, text = 'Just ask me for a {trade} to see what I buy from you. If you want to sell {blueberries}, ask me about them separately.'}) +keywordHandler:addKeyword({'stuff'}, StdModule.say, {npcHandler = npcHandler, text = 'Just ask me for a {trade} to see my offers. If you want to sell {blueberries}, ask me about them separately.'}) +keywordHandler:addAliasKeyword({'wares'}) +keywordHandler:addAliasKeyword({'offer'}) +keywordHandler:addAliasKeyword({'buy'}) + +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'How can I help you? If you like to buy something, just ask me for a {trade}. We can also chat about {Tibia}. Or, I could give you general {hints} about the game.'}) +keywordHandler:addAliasKeyword({'information'}) + +keywordHandler:addKeyword({'hint'}, StdModule.rookgaardHints, {npcHandler = npcHandler}) +keywordHandler:addKeyword({'equip'}, StdModule.say, {npcHandler = npcHandler, text = 'You definitely need a good {weapon}, an {armor} and a {shield}. Also, you should never leave for a {dungeon} without {rope}, {shovel} and {torch}.'}) +keywordHandler:addKeyword({'how', 'are', 'you'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m in tune with myself and with nature. Thank you.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m a {druid}, bound to the spirit of nature. My {potions} will help you if you feel bad. I also buy {blueberries} and {cookies}. Just ask me for a {trade}.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Lily, like the flower. It also stands for purity, just like my {potions} are!'}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = 'It\'s about |TIME|. But does it really matter? Don\'t rush yourself and enjoy all these little moments.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'It\'s wise to store most of your gold at the bank below the academy. It\'s safer that way.'}) +keywordHandler:addKeyword({'citizen'}, StdModule.say, {npcHandler = npcHandler, text = 'If you tell me the name of a citizen, I\'ll tell you what I know about him or her.'}) +keywordHandler:addKeyword({'antidote'}, StdModule.say, {npcHandler = npcHandler, text = 'Antidote potions will cure {poisoning}. They also have a lovely {blueberry} taste. You only need them when you get poisoned deep down in a dungeon, else just go to the {temple} for a free heal!'}) +keywordHandler:addKeyword({'poisoning'}, StdModule.say, {npcHandler = npcHandler, text = 'Some creatures like snakes or poison spiders can poison you. That will diminish your health over a certain amount of time, so be careful when dealing with those creatures!'}) +keywordHandler:addKeyword({'druid'}, StdModule.say, {npcHandler = npcHandler, text = 'Being a druid is a wonderful profession. You control the forces of nature and can heal others.'}) +keywordHandler:addKeyword({'shop'}, StdModule.say, {npcHandler = npcHandler, text = 'There are many shops around here which are owned by local {citizens}.'}) +keywordHandler:addKeyword({'temple'}, StdModule.say, {npcHandler = npcHandler, text = 'The temple is just to the right. You can get a healing for free there if you are badly injured or poisoned.'}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = 'Tibia is our beautiful world, created by the gods. Being a {druid}, I\'m a worshipper of {Crunor}.'}) +keywordHandler:addKeyword({'crunor'}, StdModule.say, {npcHandler = npcHandler, text = 'Crunor is the great lord of trees and the creator of all plants. Despite what some people believe, he didn\'t create the {monsters}, though.'}) +keywordHandler:addKeyword({'food'}, StdModule.say, {npcHandler = npcHandler, text = 'Oh, I\'m sorry honey, I don\'t sell food. If you are hungry, visit one of the farmers {Billy} and {Willie}. I buy {blueberries} and {cookies}, though.'}) +keywordHandler:addKeyword({'premium'}, StdModule.say, {npcHandler = npcHandler, text = {'If you purchase premium time for your account, this opens up a lot of possibilities. ...', 'For example, you will be able to travel off the mainland, ride a mount and benefit from offline training as well as having more outfits and magic spells to choose from.'}}) +keywordHandler:addKeyword({'potion'}, StdModule.say, {npcHandler = npcHandler, text = 'I can offer you homemade {antidote} potions and small {health} potions. Ask me for a {trade} if you like to see them.'}) +keywordHandler:addKeyword({'health'}, StdModule.say, {npcHandler = npcHandler, text = 'Health potions will heal you for about 75 hit points. It can\'t hurt to carry one with you, just in case.'}) +keywordHandler:addKeyword({'king'}, StdModule.say, {npcHandler = npcHandler, text = 'I think Tibia would be a better place without authorities who lead others to war. Can\'t we just all live in peace?'}) +keywordHandler:addKeyword({'academy'}, StdModule.say, {npcHandler = npcHandler, text = 'The academy is the big stone building in the town centre. If you\'re ready to leave Rookgaard, go there to see the {oracle}.'}) +keywordHandler:addKeyword({'rookgaard'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, in this village and its surroundings you can {train} your skills until you are level 8. Then you should see the {oracle} and head to the {main} continent.'}) +keywordHandler:addKeyword({'train'}, StdModule.say, {npcHandler = npcHandler, text = 'To train your skills, simply help us {fighting} monsters.'}) +keywordHandler:addKeyword({'fight'}, StdModule.say, {npcHandler = npcHandler, text = ' If you want to fight monsters, you should get better {equipment} from the {merchants}. You should also talk to one of the bridge {guards} to find suitable monsters for you.'}) +keywordHandler:addKeyword({'merchant'}, StdModule.say, {npcHandler = npcHandler, text = 'To view the offers of a merchant, simply talk to him or her and ask for a {trade}. They will gladly show you their offers and also the things they buy from you.'}) +keywordHandler:addKeyword({'main'}, StdModule.say, {npcHandler = npcHandler, text = 'The main continent is huge! The gods of Tibia created everything from great seas, deep jungles and large deserts.'}) +keywordHandler:addKeyword({'monster'}, StdModule.say, {npcHandler = npcHandler, text = 'Sadly, our little village of {Rookgaard} is invaded by monsters. From the {dungeons} they creep to the surface and attack the city. We always need adventurers helping us to {fight} them.'}) +keywordHandler:addKeyword({'weapon'}, StdModule.say, {npcHandler = npcHandler, text = 'If you are looking for weapons, you should visit {Obi}\'s shop east of here. Or, if you have a {premium} account, go to {Lee\'Delle} for better offers.'}) +keywordHandler:addKeyword({'armor'}, StdModule.say, {npcHandler = npcHandler, text = 'Armors? Best buy them at {Dixi}\'s little counter, just upstairs from {Obi}\'s shop. Or, if you have a {premium} account, go to {Lee\'Delle} for better offers.'}) +keywordHandler:addKeyword({'shield'}, StdModule.say, {npcHandler = npcHandler, text = 'Shields? Best buy them at {Dixi}\'s little counter, just upstairs from {Obi}\'s shop. Or, if you have a {premium} account, go to {Lee\'Delle} for better offers.'}) +keywordHandler:addKeyword({'dungeon'}, StdModule.say, {npcHandler = npcHandler, text = 'If you need information about the dungeons here, you should talk to one of the bridge {guards}. They will show you where to go.'}) +keywordHandler:addKeyword({'guard'}, StdModule.say, {npcHandler = npcHandler, text = 'Our bridge guards are {Dallheim} and {Zerbrus}. You can find Dallheim if you follow the path to the right, then turn north at the {temple}.'}) +keywordHandler:addKeyword({'cookie'}, StdModule.say, {npcHandler = npcHandler, text = 'Yum, cookies! If you have some for me, just ask me for a trade.'}) + +keywordHandler:addKeyword({'money'}, StdModule.say, {npcHandler = npcHandler, text = 'Earn gold by fighting {monsters} and picking up what they carry. Sell it to {merchants} to make profit!'}) +keywordHandler:addAliasKeyword({'gold'}) + +keywordHandler:addKeyword({'deposit'}, StdModule.say, {npcHandler = npcHandler, text = 'I will pay you 5 gold for every empty vial and potion flask. Just ask me for a {trade}.'}) +keywordHandler:addAliasKeyword({'flask'}) +keywordHandler:addAliasKeyword({'vial'}) + +keywordHandler:addKeyword({'shovel'}, StdModule.say, {npcHandler = npcHandler, text = 'You best buy such equipment at {Al Dee}\'s store in the North of the village. Or, if you have a {premium} account, go to {Lee\'Delle} for better offers.'}) +keywordHandler:addAliasKeyword({'rope'}) +keywordHandler:addAliasKeyword({'torch'}) + +local cookiKeyword = keywordHandler:addKeyword({'cooki'}, StdModule.say, {npcHandler = npcHandler, text = 'Oh yes, I love cookies! Will you accept 1 gold for it?'}) + cookiKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Fine! Here\'s your gold.', reset = true}, + function(player) return player:getItemCount(2687) > 0 end, + function(player) + player:removeItem(2687, 1) + player:addMoney(1) + end + ) + cookiKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, you do not have one.', reset = true}) + cookiKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Oh, what a pity.', reset = true}) + +local blueberryKeyword = keywordHandler:addKeyword({'blueberry'}, StdModule.say, {npcHandler = npcHandler, text = 'Oh, do you have blueberries for sale? I need them for my {antidote potion}. I give you 1 gold for 5 of them, yes?'}) + blueberryKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Fine! Here\'s your gold.', reset = true}, + function(player) return player:getItemCount(2677) >= 5 end, + function(player) + player:removeItem(2677, 5) + player:addMoney(1) + end + ) + blueberryKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Oh, I\'m sorry. I\'m not buying less than 5 blueberries.', reset = true}) + blueberryKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'As you wish.', reset = true}) +keywordHandler:addAliasKeyword({'blueberries'}) +keywordHandler:addAliasKeyword({'berry'}) + +-- Names +keywordHandler:addKeyword({'obi'}, StdModule.say, {npcHandler = npcHandler, text = 'He sells {weapons}. His shop is east of here.'}) +keywordHandler:addKeyword({'norma'}, StdModule.say, {npcHandler = npcHandler, text = 'I don\'t know what to think about all this new bar. {Rookgaard} needs a little peace!'}) +keywordHandler:addKeyword({'loui'}, StdModule.say, {npcHandler = npcHandler, text = 'He used to help me gather blueberries. Then, one day, he suddenly stopped comming here. They say he went a little out of his mind.'}) +keywordHandler:addKeyword({'santiago'}, StdModule.say, {npcHandler = npcHandler, text = 'We tried everything to fight that cockroach plague in his cellar, but natural anti-bug potions simply won\'t help. I guess those roaches need to be fought with stronger weapons.'}) +keywordHandler:addKeyword({'zirella'}, StdModule.say, {npcHandler = npcHandler, text = 'That poor old woman. I wish I could help her.'}) +keywordHandler:addKeyword({'al', 'dee'}, StdModule.say, {npcHandler = npcHandler, text = 'Best tool shop in town, if you ask me.'}) +keywordHandler:addKeyword({'amber'}, StdModule.say, {npcHandler = npcHandler, text = 'I heard that she\'s recovering below the academy. She has been on an exciting expedition. I haven\'t talked to her yet, though.'}) +keywordHandler:addKeyword({'cipfried'}, StdModule.say, {npcHandler = npcHandler, text = 'Visiting Cipfried in the {temple} is a good idea if you are injured or poisoned. He can heal you.'}) +keywordHandler:addKeyword({'dixi'}, StdModule.say, {npcHandler = npcHandler, text = 'She\'s {Obi}\'s granddaughter and deals with {armors} and {shields}, just upstairs from Obi\'s shop.'}) +keywordHandler:addKeyword({'hyacinth'}, StdModule.say, {npcHandler = npcHandler, text = 'Hyacinth also sells small health potions. He lives outside the village, in a hidden place.'}) +keywordHandler:addKeyword({'lee\'delle'}, StdModule.say, {npcHandler = npcHandler, text = 'If you are a {premium} adventurer, you should check out {Lee\'Delle\'s} shop. She lives in the western part of town, just across the bridge.'}) +keywordHandler:addKeyword({'lily'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes?'}) +keywordHandler:addKeyword({'oracle'}, StdModule.say, {npcHandler = npcHandler, text = 'You can find the oracle on the top floor of the {academy}, just above {Seymour}. Go there when you are level 8 to reach more areas of {Tibia}.'}) +keywordHandler:addKeyword({'paulie'}, StdModule.say, {npcHandler = npcHandler, text = 'He takes care of the {bank}, keeping our money safe.'}) +keywordHandler:addKeyword({'seymour'}, StdModule.say, {npcHandler = npcHandler, text = 'Seymour is a teacher running the {academy}. He has many important {information} about Tibia.'}) +keywordHandler:addKeyword({'tom'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s the local tanner. You could try selling fresh corpses or leather to him.'}) +keywordHandler:addKeyword({'dallheim'}, StdModule.say, {npcHandler = npcHandler, text = 'He is a great warrior. He can also tell you much about {monsters} and {dungeons} on this island.'}) +keywordHandler:addAliasKeyword({'zerbrus'}) + +keywordHandler:addKeyword({'billy'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s a farmer and sells {food}. Food will help you regain health when you are injured. Many {monsters} also carry food with them.'}) +keywordHandler:addAliasKeyword({'willie'}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'May Crunor bless you!') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Take care, |PLAYERNAME|.') +npcHandler:setMessage(MESSAGE_SENDTRADE, 'Of course, just browse through my offers. If you buy a potion, don\'t forget that there\'s a {deposit} of 5 gold on the empty flask.') +npcHandler:setCallback(CALLBACK_GREET, greetCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lisander.lua b/data/npc/scripts/lisander.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/lisander.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/livielle.lua b/data/npc/scripts/livielle.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/livielle.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lizard_tunnel_guard.lua b/data/npc/scripts/lizard_tunnel_guard.lua new file mode 100644 index 00000000000..8c7bfc3e921 --- /dev/null +++ b/data/npc/scripts/lizard_tunnel_guard.lua @@ -0,0 +1,30 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.WrathoftheEmperor.Questline) >= 2 then + player:setStorageValue(Storage.WrathoftheEmperor.GuardcaughtYou, 1) + player:setStorageValue(Storage.WrathoftheEmperor.CrateStatus, 0) + player:teleportTo(Position(33361, 31206, 8)) + player:say("The guards have spotted you. You were forcibly dragged into a small cell. It looks like you need to build another disguise.", TALKTYPE_MONSTER_SAY) + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/llathriel.lua b/data/npc/scripts/llathriel.lua new file mode 100644 index 00000000000..eac508821e8 --- /dev/null +++ b/data/npc/scripts/llathriel.lua @@ -0,0 +1,25 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +-- Greeting message +keywordHandler:addGreetKeyword({"ashari"}, {npcHandler = npcHandler, text = "Greetings, |PLAYERNAME|."}) +--Farewell message +keywordHandler:addFarewellKeyword({"asgha thrazi"}, {npcHandler = npcHandler, text = "Goodbye, |PLAYERNAME|."}) + +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye!") + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/lokur.lua b/data/npc/scripts/lokur.lua new file mode 100644 index 00000000000..764718d1d10 --- /dev/null +++ b/data/npc/scripts/lokur.lua @@ -0,0 +1,679 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +local count = {} +local transfer = {} + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Don\'t forget to deposit your money here in the Tibian Bank before you head out for adventure.'} } +if VoiceModule then + npcHandler:addModule(VoiceModule:new(voices)) +end +--------------------------------guild bank----------------------------------------------- +local receiptFormat = 'Date: %s\nType: %s\nGold Amount: %d\nReceipt Owner: %s\nRecipient: %s\n\n%s' +local function getReceipt(info) + local receipt = Game.createItem(info.success and 24301 or 24302) + receipt:setAttribute(ITEM_ATTRIBUTE_TEXT, receiptFormat:format(os.date('%d. %b %Y - %H:%M:%S'), info.type, info.amount, info.owner, info.recipient, info.message)) + + return receipt +end + +local function getGuildIdByName(name, func) + db.asyncStoreQuery('SELECT `id` FROM `guilds` WHERE `name` = ' .. db.escapeString(name), + function(resultId) + if resultId then + func(result.getNumber(resultId, 'id')) + result.free(resultId) + else + func(nil) + end + end + ) +end + +local function getGuildBalance(id) + local guild = Guild(id) + if guild then + return guild:getBankBalance() + else + local balance + local resultId = db.storeQuery('SELECT `balance` FROM `guilds` WHERE `id` = ' .. id) + if resultId then + balance = result.getNumber(resultId, 'balance') + result.free(resultId) + end + + return balance + end +end + +local function setGuildBalance(id, balance) + local guild = Guild(id) + if guild then + guild:setBankBalance(balance) + else + db.query('UPDATE `guilds` SET `balance` = ' .. balance .. ' WHERE `id` = ' .. id) + end +end + +local function transferFactory(playerName, amount, fromGuildId, info) + return function(toGuildId) + if not toGuildId then + local player = Player(playerName) + if player then + info.success = false + info.message = 'We are sorry to inform you that we could not fulfil your request, because we could not find the recipient guild.' + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + end + else + local fromBalance = getGuildBalance(fromGuildId) + if fromBalance < amount then + info.success = false + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your guild account.' + else + info.success = true + info.message = 'We are happy to inform you that your transfer request was successfully carried out.' + setGuildBalance(fromGuildId, fromBalance - amount) + setGuildBalance(toGuildId, getGuildBalance(toGuildId) + amount) + end + + local player = Player(playerName) + if player then + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + end + end + end +end +--------------------------------guild bank----------------------------------------------- + +local function greetCallback(cid) + count[cid], transfer[cid] = nil, nil + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) +---------------------------- help ------------------------ + if msgcontains(msg, 'bank account') then + npcHandler:say({ + 'Every Tibian has one. The big advantage is that you can access your money in every branch of the Tibian Bank! ...', + 'Would you like to know more about the {basic} functions of your bank account, the {advanced} functions, or are you already bored, perhaps?' + }, cid) + npcHandler.topic[cid] = 0 + return true +---------------------------- balance --------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild balance') then + npcHandler.topic[cid] = 0 + if not player:getGuild() then + npcHandler:say('You are not a member of a guild.', cid) + return false + end + npcHandler:say('Your guild account balance is ' .. player:getGuild():getBankBalance() .. ' gold.', cid) + return true +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'balance') then + npcHandler.topic[cid] = 0 + if player:getBankBalance() >= 100000000 then + npcHandler:say('I think you must be one of the richest inhabitants in the world! Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + elseif player:getBankBalance() >= 10000000 then + npcHandler:say('You have made ten millions and it still grows! Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + elseif player:getBankBalance() >= 1000000 then + npcHandler:say('Wow, you have reached the magic number of a million gp!!! Your account balance is ' .. player:getBankBalance() .. ' gold!', cid) + return true + elseif player:getBankBalance() >= 100000 then + npcHandler:say('You certainly have made a pretty penny. Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + else + npcHandler:say('Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + end +---------------------------- deposit --------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild deposit') then + if not player:getGuild() then + npcHandler:say('You are not a member of a guild.', cid) + npcHandler.topic[cid] = 0 + return false + end + -- count[cid] = player:getMoney() + -- if count[cid] < 1 then + -- npcHandler:say('You do not have enough gold.', cid) + -- npcHandler.topic[cid] = 0 + -- return false + --end + if string.match(msg, '%d+') then + count[cid] = getMoneyCount(msg) + if count[cid] < 1 then + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return false + end + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold to your {guild account}?', cid) + npcHandler.topic[cid] = 23 + return true + else + npcHandler:say('Please tell me how much gold it is you would like to deposit.', cid) + npcHandler.topic[cid] = 22 + return true + end + elseif npcHandler.topic[cid] == 22 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold to your {guild account}?', cid) + npcHandler.topic[cid] = 23 + return true + else + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return true + end + elseif npcHandler.topic[cid] == 23 then + if msgcontains(msg, 'yes') then + npcHandler:say('Alright, we have placed an order to deposit the amount of ' .. count[cid] .. ' gold to your guild account. Please check your inbox for confirmation.', cid) + local guild = player:getGuild() + local info = { + type = 'Guild Deposit', + amount = count[cid], + owner = player:getName() .. ' of ' .. guild:getName(), + recipient = guild:getName() + } + local playerBalance = player:getBankBalance() + if playerBalance < tonumber(count[cid]) then + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your bank account.' + info.success = false + else + info.message = 'We are happy to inform you that your transfer request was successfully carried out.' + info.success = true + guild:setBankBalance(guild:getBankBalance() + tonumber(count[cid])) + player:setBankBalance(playerBalance - tonumber(count[cid])) + end + + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish. Is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 + return true +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'deposit') then + count[cid] = player:getMoney() + if count[cid] < 1 then + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return false + end + if msgcontains(msg, 'all') then + count[cid] = player:getMoney() + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid) + npcHandler.topic[cid] = 2 + return true + else + if string.match(msg,'%d+') then + count[cid] = getMoneyCount(msg) + if count[cid] < 1 then + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return false + end + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid) + npcHandler.topic[cid] = 2 + return true + else + npcHandler:say('Please tell me how much gold it is you would like to deposit.', cid) + npcHandler.topic[cid] = 1 + return true + end + end + if not isValidMoney(count[cid]) then + npcHandler:say('Sorry, but you can\'t deposit that much.', cid) + npcHandler.topic[cid] = 0 + return false + end + elseif npcHandler.topic[cid] == 1 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid) + npcHandler.topic[cid] = 2 + return true + else + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return true + end + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, 'yes') then + if player:depositMoney(count[cid]) then + npcHandler:say('Alright, we have added the amount of ' .. count[cid] .. ' gold to your {balance}. You can {withdraw} your money anytime you want to.', cid) + else + npcHandler:say('You do not have enough gold.', cid) + end + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish. Is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 + return true +---------------------------- withdraw -------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild withdraw') then + if not player:getGuild() then + npcHandler:say('I am sorry but it seems you are currently not in any guild.', cid) + npcHandler.topic[cid] = 0 + return false + elseif player:getGuildLevel() < 2 then + npcHandler:say('Only guild leaders or vice leaders can withdraw money from the guild account.', cid) + npcHandler.topic[cid] = 0 + return false + end + + if string.match(msg,'%d+') then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your guild account?', cid) + npcHandler.topic[cid] = 25 + else + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + end + return true + else + npcHandler:say('Please tell me how much gold you would like to withdraw from your guild account.', cid) + npcHandler.topic[cid] = 24 + return true + end + elseif npcHandler.topic[cid] == 24 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your guild account?', cid) + npcHandler.topic[cid] = 25 + else + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + end + return true + elseif npcHandler.topic[cid] == 25 then + if msgcontains(msg, 'yes') then + local guild = player:getGuild() + local balance = guild:getBankBalance() + npcHandler:say('We placed an order to withdraw ' .. count[cid] .. ' gold from your guild account. Please check your inbox for confirmation.', cid) + local info = { + type = 'Guild Withdraw', + amount = count[cid], + owner = player:getName() .. ' of ' .. guild:getName(), + recipient = player:getName() + } + if balance < tonumber(count[cid]) then + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your guild account.' + info.success = false + else + info.message = 'We are happy to inform you that your transfer request was successfully carried out.' + info.success = true + guild:setBankBalance(balance - tonumber(count[cid])) + local playerBalance = player:getBankBalance() + player:setBankBalance(playerBalance + tonumber(count[cid])) + end + + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish. Is there something else I can do for you?', cid) + npcHandler.topic[cid] = 0 + end + return true +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'withdraw') then + if string.match(msg,'%d+') then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your bank account?', cid) + npcHandler.topic[cid] = 7 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + return true + else + npcHandler:say('Please tell me how much gold you would like to withdraw.', cid) + npcHandler.topic[cid] = 6 + return true + end + elseif npcHandler.topic[cid] == 6 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your bank account?', cid) + npcHandler.topic[cid] = 7 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + return true + elseif npcHandler.topic[cid] == 7 then + if msgcontains(msg, 'yes') then + if player:getFreeCapacity() >= getMoneyWeight(count[cid]) then + if not player:withdrawMoney(count[cid]) then + npcHandler:say('There is not enough gold on your account.', cid) + else + npcHandler:say('Here you are, ' .. count[cid] .. ' gold. Please let me know if there is something else I can do for you.', cid) + end + else + npcHandler:say('Whoah, hold on, you have no room in your inventory to carry all those coins. I don\'t want you to drop it on the floor, maybe come back with a cart!', cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') then + npcHandler:say('The customer is king! Come back anytime you want to if you wish to {withdraw} your money.', cid) + npcHandler.topic[cid] = 0 + end + return true +---------------------------- transfer -------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild transfer') then + if not player:getGuild() then + npcHandler:say('I am sorry but it seems you are currently not in any guild.', cid) + npcHandler.topic[cid] = 0 + return false + elseif player:getGuildLevel() < 2 then + npcHandler:say('Only guild leaders or vice leaders can transfer money from the guild account.', cid) + npcHandler.topic[cid] = 0 + return false + end + + if string.match(msg, '%d+') then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + transfer[cid] = string.match(msg, 'to%s*(.+)$') + if transfer[cid] then + npcHandler:say('So you would like to transfer ' .. count[cid] .. ' gold from your guild account to guild ' .. transfer[cid] .. '?', cid) + npcHandler.topic[cid] = 28 + else + npcHandler:say('Which guild would you like to transfer ' .. count[cid] .. ' gold to?', cid) + npcHandler.topic[cid] = 27 + end + else + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + end + else + npcHandler:say('Please tell me the amount of gold you would like to transfer.', cid) + npcHandler.topic[cid] = 26 + end + return true + elseif npcHandler.topic[cid] == 26 then + count[cid] = getMoneyCount(msg) + if player:getGuild():getBankBalance() < count[cid] then + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + return true + end + if isValidMoney(count[cid]) then + npcHandler:say('Which guild would you like to transfer ' .. count[cid] .. ' gold to?', cid) + npcHandler.topic[cid] = 27 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + return true + elseif npcHandler.topic[cid] == 27 then + transfer[cid] = msg + if player:getGuild():getName() == transfer[cid] then + npcHandler:say('Fill in this field with person who receives your gold!', cid) + npcHandler.topic[cid] = 0 + return true + end + npcHandler:say('So you would like to transfer ' .. count[cid] .. ' gold from your guild account to guild ' .. transfer[cid] .. '?', cid) + npcHandler.topic[cid] = 28 + return true + elseif npcHandler.topic[cid] == 28 then + if msgcontains(msg, 'yes') then + npcHandler:say('We have placed an order to transfer ' .. count[cid] .. ' gold from your guild account to guild ' .. transfer[cid] .. '. Please check your inbox for confirmation.', cid) + local guild = player:getGuild() + local balance = guild:getBankBalance() + local info = { + type = 'Guild to Guild Transfer', + amount = count[cid], + owner = player:getName() .. ' of ' .. guild:getName(), + recipient = transfer[cid] + } + if balance < tonumber(count[cid]) then + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your guild account.' + info.success = false + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + else + getGuildIdByName(transfer[cid], transferFactory(player:getName(), tonumber(count[cid]), guild:getId(), info)) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') then + npcHandler:say('Alright, is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'transfer') then + npcHandler:say('Please tell me the amount of gold you would like to transfer.', cid) + npcHandler.topic[cid] = 11 + elseif npcHandler.topic[cid] == 11 then + count[cid] = getMoneyCount(msg) + if player:getBankBalance() < count[cid] then + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + return true + end + if isValidMoney(count[cid]) then + npcHandler:say('Who would you like transfer ' .. count[cid] .. ' gold to?', cid) + npcHandler.topic[cid] = 12 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 12 then + transfer[cid] = msg + if player:getName() == transfer[cid] then + npcHandler:say('Fill in this field with person who receives your gold!', cid) + npcHandler.topic[cid] = 0 + return true + end + if playerExists(transfer[cid]) then + local arrayDenied = {"accountmanager", "rooksample", "druidsample", "sorcerersample", "knightsample", "paladinsample"} + if isInArray(arrayDenied, string.gsub(transfer[cid]:lower(), " ", "")) then + npcHandler:say('This player does not exist.', cid) + npcHandler.topic[cid] = 0 + return true + end + npcHandler:say('So you would like to transfer ' .. count[cid] .. ' gold to ' .. transfer[cid] .. '?', cid) + npcHandler.topic[cid] = 13 + else + npcHandler:say('This player does not exist.', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 13 then + if msgcontains(msg, 'yes') then + if not player:transferMoneyTo(transfer[cid], count[cid]) then + npcHandler:say('You cannot transfer money to this account.', cid) + else + npcHandler:say('Very well. You have transferred ' .. count[cid] .. ' gold to ' .. transfer[cid] ..'.', cid) + transfer[cid] = nil + end + elseif msgcontains(msg, 'no') then + npcHandler:say('Alright, is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 +---------------------------- money exchange -------------- + elseif msgcontains(msg, 'change gold') then + npcHandler:say('How many platinum coins would you like to get?', cid) + npcHandler.topic[cid] = 14 + elseif npcHandler.topic[cid] == 14 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough gold coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] * 100 .. ' of your gold coins into ' .. count[cid] .. ' platinum coins?', cid) + npcHandler.topic[cid] = 15 + end + elseif npcHandler.topic[cid] == 15 then + if msgcontains(msg, 'yes') then + if player:removeItem(2148, count[cid] * 100) then + player:addItem(2152, count[cid]) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough gold coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'change platinum') then + npcHandler:say('Would you like to change your platinum coins into gold or crystal?', cid) + npcHandler.topic[cid] = 16 + elseif npcHandler.topic[cid] == 16 then + if msgcontains(msg, 'gold') then + npcHandler:say('How many platinum coins would you like to change into gold?', cid) + npcHandler.topic[cid] = 17 + elseif msgcontains(msg, 'crystal') then + npcHandler:say('How many crystal coins would you like to get?', cid) + npcHandler.topic[cid] = 19 + else + npcHandler:say('Well, can I help you with something else?', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 17 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] .. ' of your platinum coins into ' .. count[cid] * 100 .. ' gold coins for you?', cid) + npcHandler.topic[cid] = 18 + end + elseif npcHandler.topic[cid] == 18 then + if msgcontains(msg, 'yes') then + if player:removeItem(2152, count[cid]) then + player:addItem(2148, count[cid] * 100) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 19 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] * 100 .. ' of your platinum coins into ' .. count[cid] .. ' crystal coins for you?', cid) + npcHandler.topic[cid] = 20 + end + elseif npcHandler.topic[cid] == 20 then + if msgcontains(msg, 'yes') then + if player:removeItem(2152, count[cid] * 100) then + player:addItem(2160, count[cid]) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'change crystal') then + npcHandler:say('How many crystal coins would you like to change into platinum?', cid) + npcHandler.topic[cid] = 21 + elseif npcHandler.topic[cid] == 21 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough crystal coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] .. ' of your crystal coins into ' .. count[cid] * 100 .. ' platinum coins for you?', cid) + npcHandler.topic[cid] = 22 + end + elseif npcHandler.topic[cid] == 22 then + if msgcontains(msg, 'yes') then + if player:removeItem(2160, count[cid]) then + player:addItem(2152, count[cid] * 100) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough crystal coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + end + -- WAGON TICKET + if msgcontains(msg, 'ticket') then + if player:getStorageValue(Storage.WagonTicket) < os.time() then + npcHandler:say("Do you want to purchase a weekly ticket for the ore wagons? With it you can travel freely and swiftly through Kazordoon for one week. 250 gold only. Deal?", cid) + npcHandler.topic[cid] = 29 + else + npcHandler:say("Your weekly ticket is still valid. Would be a waste of money to purchase a second one", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 29 then + if player:removeMoneyNpc(250) then + player:setStorageValue(Storage.WagonTicket, os.time() + 7 * 24 * 60 * 60) + npcHandler:say("Here is your stamp. It can't be transferred to another person and will last one week from now. You'll get notified upon using an ore wagon when it isn't valid anymore.", cid) + else + npcHandler:say("You don't have enough money.", cid) + end + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 29 then + if msgcontains(msg, 'no') then + npcHandler:say("No then.", cid) + npcHandler.topic[cid] = 0 + end + -- WAGON TICKET + elseif msgcontains(msg, 'measurements') then + if player:getStorageValue(Storage.Postman.Mission07) >= 1 then + npcHandler:say("Come on, I have no clue what they are. Better ask my armorer Kroox for such nonsense.Go and ask him for good ol' Lokurs measurements, he'll know.", cid) + end + end + return true +end + +keywordHandler:addKeyword({'money'}, StdModule.say, {npcHandler = npcHandler, text = 'We can {change} money for you. You can also access your {bank account}.'}) +keywordHandler:addKeyword({'change'}, StdModule.say, {npcHandler = npcHandler, text = 'There are three different coin types in Tibia: 100 gold coins equal 1 platinum coin, 100 platinum coins equal 1 crystal coin. So if you\'d like to change 100 gold into 1 platinum, simply say \'{change gold}\' and then \'1 platinum\'.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'We can {change} money for you. You can also access your {bank account}.'}) +keywordHandler:addKeyword({'advanced'}, StdModule.say, {npcHandler = npcHandler, text = 'Your bank account will be used automatically when you want to {rent} a house or place an offer on an item on the {market}. Let me know if you want to know about how either one works.'}) +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'You can check the {balance} of your bank account, {deposit} money or {withdraw} it. You can also {transfer} money to other characters, provided that they have a vocation.'}) +keywordHandler:addKeyword({'functions'}, StdModule.say, {npcHandler = npcHandler, text = 'You can check the {balance} of your bank account, {deposit} money or {withdraw} it. You can also {transfer} money to other characters, provided that they have a vocation.'}) +keywordHandler:addKeyword({'basic'}, StdModule.say, {npcHandler = npcHandler, text = 'You can check the {balance} of your bank account, {deposit} money or {withdraw} it. You can also {transfer} money to other characters, provided that they have a vocation.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I work in this bank. I can change money for you and help you with your bank account.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Yes? What may I do for you, |PLAYERNAME|? Bank business, perhaps?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Have a nice day.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Have a nice day.") +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lora.lua b/data/npc/scripts/lora.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/lora.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lorbas.lua b/data/npc/scripts/lorbas.lua new file mode 100644 index 00000000000..04523559c11 --- /dev/null +++ b/data/npc/scripts/lorbas.lua @@ -0,0 +1,59 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, 'cookie') then + if player:getStorageValue(Storage.WhatAFoolish.Questline) == 31 + and player:getStorageValue(Storage.WhatAFoolish.CookieDelivery.Lorbas) ~= 1 then + npcHandler:say('You want me to eat this cookie?', cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + if not player:removeItem(8111, 1) then + npcHandler:say('You have no cookie that I\'d like.', cid) + npcHandler.topic[cid] = 0 + return true + end + + player:setStorageValue(Storage.WhatAFoolish.CookieDelivery.Lorbas, 1) + if player:getCookiesDelivered() == 10 then + player:addAchievement('Allow Cookies?') + end + + Npc():getPosition():sendMagicEffect(CONST_ME_GIFT_WRAPS) + npcHandler:say('Well, you don\'t mind if I play around with this antidote rune a bit ... UHHH, YOU LOU ... uhm that was so ... funny, haha ... ha. Mhm, you better leave now.', cid) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + elseif msgcontains(msg, 'no') then + if npcHandler.topic[cid] == 1 then + npcHandler:say('I see.', cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lorek.lua b/data/npc/scripts/lorek.lua new file mode 100644 index 00000000000..7e1dfa6ebb2 --- /dev/null +++ b/data/npc/scripts/lorek.lua @@ -0,0 +1,39 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Travel +local function addTravelKeyword(keyword, text, cost, destination, condition) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to ' .. (text or keyword:titleCase()) .. ' for |TRAVELCOST|?', cost = cost}, condition and function(player) return player:getPawAndFurRank() >= 3 end or nil) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'Maybe another time.', reset = true}) +end + +addTravelKeyword('west', 'the west end of Port Hope', 7, Position(32558, 32780, 7)) +addTravelKeyword('centre', 'the centre of Port Hope', 7, Position(32628, 32771, 7)) +addTravelKeyword('darama', nil, 30, Position(32987, 32729, 7)) +addTravelKeyword('center', 'the centre of Port Hope', 0, Position(32628, 32771, 7)) +addTravelKeyword('chor', nil, 30, Position(32968, 32799, 7), true) +addTravelKeyword('banuta', nil, 30, Position(32826, 32631, 7), true) +addTravelKeyword('mountain', nil, 30, Position(32987, 32729, 7), true) +addTravelKeyword('mountain pass', nil, 30, Position(32987, 32729, 7), true) + + +-- Basic +keywordHandler:addKeyword({'ferumbras'}, StdModule.say, {npcHandler = npcHandler, text = "I heard he is some scary magician or so."}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'I can travel you to west, centre, darama, chor or banuta.'}) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/loria.lua b/data/npc/scripts/loria.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/loria.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lorietta.lua b/data/npc/scripts/lorietta.lua new file mode 100644 index 00000000000..684d014e5ec --- /dev/null +++ b/data/npc/scripts/lorietta.lua @@ -0,0 +1,95 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Twist of Fate +local blessKeyword = keywordHandler:addKeyword({'twist of fate'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'This is a special blessing I can bestow upon you once you have obtained at least one of the other blessings and which functions a bit differently. ...', + 'It only works when you\'re killed by other adventurers, which means that at least half of the damage leading to your death was caused by others, not by monsters or the environment. ...', + 'The {twist of fate} will not reduce the death penalty like the other blessings, but instead prevent you from losing your other blessings as well as the amulet of loss, should you wear one. It costs the same as the other blessings. ...', + 'Would you like to receive that protection for a sacrifice of |PVPBLESSCOST| gold, child?' + }}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the protection of the twist of fate, pilgrim.', cost = '|PVPBLESSCOST|', bless = 1}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Adventurer Stone +keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Keep your adventurer\'s stone well.'}, function(player) return player:getItemById(18559, true) end) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for free?'}, function(player) return player:getStorageValue(Storage.AdventurersGuild.FreeStone.Lorietta) ~= 1 end) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, nil, function(player) player:addItem(18559, 1) player:setStorageValue(Storage.AdventurersGuild.FreeStone.Lorietta, 1) end) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for 30 gold?'}) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, + function(player) return player:getMoney() + player:getBankBalance() >= 30 end, + function(player) if player:removeMoneyNpc(30) then player:addItem(18559, 1) end end + ) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, you don\'t have enough money.', reset = true}) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.'}, function(player) return player:hasBlessing(2) end) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin will provide you with the embrace of Tibia.'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, young |PLAYERNAME|! If you are heavily wounded or poisoned, I can {heal} you for free.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Remember: If you are heavily wounded or poisoned, I can heal you for free.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'May the gods bless you, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lothar.lua b/data/npc/scripts/lothar.lua new file mode 100644 index 00000000000..33f8ca5362c --- /dev/null +++ b/data/npc/scripts/lothar.lua @@ -0,0 +1,89 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'I enjoy the peace and solitude out here. You\'re welcome to be my guest as long as you behave in a quiet and tolerable manner.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +keywordHandler:addKeyword({'here'}, StdModule.say, {npcHandler = npcHandler, text = "Some call me {animal} whisperer. Others say I'm just crazy. I refer to myself as a simple {stable} keeper."}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "Some call me {animal} whisperer. Others say I'm just crazy. I refer to myself as a simple {stable} keeper."}) +keywordHandler:addKeyword({'animal'}, StdModule.say, {npcHandler = npcHandler, text = "I love all animals, whether small or big. I also believe each one, even the wildest and most ferocious being, can be talked to, understood and {tamed}."}) +keywordHandler:addKeyword({'stable'}, StdModule.say, {npcHandler = npcHandler, text = "It's my dream to shelter many different tamed animals. Maybe one day that dream will come true."}) +keywordHandler:addKeyword({'tamed'}, StdModule.say, {npcHandler = npcHandler, text = "Well, usually you can tame animals with the help of a few simple items. If you've found such an {item}, show it to me and I might be able to help you with instructions on the taming process."}) +keywordHandler:addKeyword({'item'}, StdModule.say, {npcHandler = npcHandler, text = "Well? Which item have you found and require advice for?"}) +keywordHandler:addKeyword({'bag of apple slices'}, StdModule.say, {npcHandler = npcHandler, text = "That's among the favourite foods of donkeys, as far as I know. It's a shame I haven't really seen any donkey around. It could require a magic trick to actually get to meet one."}) +keywordHandler:addKeyword({'bamboo leaves'}, StdModule.say, {npcHandler = npcHandler, text = "Pandas love to eat bamboo leaves, but the Tiquandan pandas are actually not that skilled at climbing, so they have a hard time getting some for themselves. You might be able to tame one with them."}) +keywordHandler:addKeyword({'carrot on a stick'}, StdModule.say, {npcHandler = npcHandler, text = "I heard that terror birds really love carrots. I'd try waving it in front of one of those."}) +keywordHandler:addKeyword({'decorative ribbon'}, StdModule.say, {npcHandler = npcHandler, text = "Ah, what a pretty ribbon. Reminds me of the elusive dragonlings - they're quite elegant and vain. They would probably welcome a decorative element. They're sometimes spotted during volcano eruptions."}) +keywordHandler:addKeyword({'diapason'}, StdModule.say, {npcHandler = npcHandler, text = "What a neat little elvish gadget. Did you know a diapason works with vibrations to create sound? I actually think this could work on a creature made of crystals."}) +keywordHandler:addKeyword({'fist on a stick'}, StdModule.say, {npcHandler = npcHandler, text = "I'm against violence towards any creature. I've heard those barbarians in the desert use it for disobedient dromedaries."}) +keywordHandler:addKeyword({'four-leaf clover'}, StdModule.say, {npcHandler = npcHandler, text = "Oh, what a nice little plant! Did you know it's supposed to bring luck? So is the lady bug. Both of them might actually go well together."}) +keywordHandler:addKeyword({'foxtail'}, StdModule.say, {npcHandler = npcHandler, text = "I've heard that there once was a gang of manta ray riders who liked to adorn their mantas with a foxtail. Don't ask me why, maybe they like how it floats in the wind when running really fast?"}) +keywordHandler:addKeyword({'golem wrench'}, StdModule.say, {npcHandler = npcHandler, text = "What a strange device! This looks like a tool for someone who creates golems and modifies living creatures. You could probably tame a modded creature with it, but I doubt they live in the wild."}) +keywordHandler:addKeyword({'giant shrimp'}, StdModule.say, {npcHandler = npcHandler, text = "Oh, that's one of the favourite foods of a crustacea gigantica. I think you can just distract it with the food and quickly jump on its back."}) +keywordHandler:addKeyword({'glow wine'}, StdModule.say, {npcHandler = npcHandler, text = "Have you ever encountered a magma crawler? They only eat and drink really hot things. You could probably try and make one drink some glow wine - and quickly mount it as long as it's drunk."}) +keywordHandler:addKeyword({'golden can of oil'}, StdModule.say, {npcHandler = npcHandler, text = "Hm. What an interesting find. This is definitely not used for any sort of animal. Maybe a vehicle? I can imagine it could be used for a bike of some sorts."}) +keywordHandler:addKeyword({'harness'}, StdModule.say, {npcHandler = npcHandler, text = "That looks like it might fit a draptor. If you can ever get close enough to one to catch it, I'd simply try putting it on while whispering calming words."}) +keywordHandler:addKeyword({'hunting horn'}, StdModule.say, {npcHandler = npcHandler, text = "The sound of a hunting horn is often intimidating to forest creatures, but I heard that wild boars actually like it."}) +keywordHandler:addKeyword({'iron loadstone'}, StdModule.say, {npcHandler = npcHandler, text = "Ironblights consist mainly of stone and iron. With a strong magnet like that you can basically force it to walk in the direction you're wanting it to."}) +keywordHandler:addKeyword({'leather whip'}, StdModule.say, {npcHandler = npcHandler, text = "Try catching a midnight panther using that one. Don't hit the panther, mind you. Just let the whip crack in the air - I think that will work."}) +keywordHandler:addKeyword({'leech'}, StdModule.say, {npcHandler = npcHandler, text = "As far as I know, leeches can be found in terrestrial, swampy areas. Leeches often help large animals such as water buffaloes to get rid of parasites."}) +keywordHandler:addKeyword({'maxilla maximus'}, StdModule.say, {npcHandler = npcHandler, text = "You should show that giant jaw to a creature looking like the one you got it from. It will respect you when it sees those scary teeth."}) +keywordHandler:addKeyword({'music box'}, StdModule.say, {npcHandler = npcHandler, text = "Where did you get that? What a rare treat. This must have been crafted by someone who truly loves both music and animals. I can't tell you anything else about it."}) +keywordHandler:addKeyword({'nail case'}, StdModule.say, {npcHandler = npcHandler, text = "Oh, a nail case..., I hate paring nails. But I heard gravediggers become trusting when they get the right treatment."}) +keywordHandler:addKeyword({'nightmare horn'}, StdModule.say, {npcHandler = npcHandler, text = "How impressive, a nightmare horn. Have you ever encountered a shock head? Try hypnotizing them with your horn."}) +keywordHandler:addKeyword({'reins'}, StdModule.say, {npcHandler = npcHandler, text = "You could probably ride a black sheep with these. Talk to it gently and carefully put on the reins."}) +keywordHandler:addKeyword({'scorpion sceptre'}, StdModule.say, {npcHandler = npcHandler, text = "Wow, that's a rarity. Have you ever met one of those large sandstone scorpions? They're quite impressive. You need such a sceptre to show to one that you're its new master."}) +keywordHandler:addKeyword({'slingshot'}, StdModule.say, {npcHandler = npcHandler, text = "That might be the only way to tame a bear. It has a sensitive spot right between the ears which will calm it down, but you're not strong enough for simple acupressure. Using the slingshot is likely to help you with that."}) +keywordHandler:addKeyword({'slug drug'}, StdModule.say, {npcHandler = npcHandler, text = "As the name indicates - this can be used to make a slug much faster than it normally is! Once you've tamed it, it will race you wherever you want to go."}) +keywordHandler:addKeyword({'sugar oat'}, StdModule.say, {npcHandler = npcHandler, text = "Create sugar oat by just mixing a bunch of sugar cane with a bunch of wheat. All horses love sugar oat! Sometimes when the horses from the horse station in Thais are on the loose, wild horses mix with the herd. Maybe they can be tamed?"}) +keywordHandler:addKeyword({'sweet smelling bait'}, StdModule.say, {npcHandler = npcHandler, text = "The interesting part about that bait isn't the sweet stuff - it's the flies attracted to the sweet smell. Spiders love to eat flies, especially the Zaoan ones."}) +keywordHandler:addKeyword({'tin key'}, StdModule.say, {npcHandler = npcHandler, text = "Hm! Now that's an interesting one. Where did you get that from? I could imagine it winds something up in a factory, but it's definitely not a normal animal."}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "It's on the door."}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if msgcontains(msg, "control unit") then + npcHandler:say({ + 'That\'s an interesting one, nothing like I have ever seen myself. What you describe is a device of which I heard that it grants literally \'complete\' control over some sort of... artificial thing? ...', + 'Well, if you ever happen to come about a stroke of luck and find such a thing - use it on an appropriate mount, it will probably be mechanical, driven by... something.' + }, cid) + elseif msgcontains(msg, "golden fir cone") then + npcHandler:say({ + 'Did you know that you can also create those by yourself? Trade a gold ingot with the sweaty cyclops in Ab\'Dendriel for a cup of molten gold. If you use that on a fir tree, you have a small chance to get a golden fir cone. ...', + 'Those are needed to impress the white deers that roam around Ab\'Dendriel sometimes, but I\'d wait until you are able to enrage one to make sure it has the necessary strength to carry you.' + }, cid) + elseif msgcontains(msg, "melting horn") then + npcHandler:say({ + 'It is said that ferocious creatures once thrived on lush islands in the far northern sea. They died aeons ago when times of great cold came and formed the icy wastes of Svargrond as we know them today. ...', + 'Travellers from the north have told stories of these creatures, watching them from within the ice in the deepest caves, still vigilant as if frozen in time. \'Ursagrodon\' they called them. ...', + 'With tinder and some kind of fireproof vessel, you could create a device to melt the ice surrounding their remains and see for yourself what this is all about.' + }, cid) + elseif isInArray({"arkarra", "stampor"}, msg) then + npcHandler:say({ + 'The stampor in the back? She\'s my friend, but she came to me out of her own free will. I must admit I\'ve never managed to tame any other stampor. ...', + 'I heard that there\'s some sort of voodoo magic which would allow you to summon a stampor, but I\'m not a voodoo expert, so I wouldn\'t know.' + }, cid) + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "Welcome to my humble hut, |PLAYERNAME|. What brings you {here}?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Take care of yourself.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lou_toose.lua b/data/npc/scripts/lou_toose.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/lou_toose.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/loui.lua b/data/npc/scripts/loui.lua new file mode 100644 index 00000000000..63583fcaf19 --- /dev/null +++ b/data/npc/scripts/loui.lua @@ -0,0 +1,78 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'BEWARE! Beware of that hole!' }, + { text = 'STAY AWAY FROM THAT HOLE!' }, + { text = 'What are you doing here?? Get away from that hole!' } +} +npcHandler:addModule(VoiceModule:new(voices)) + +-- Basic keywords +keywordHandler:addKeyword({'hint'}, StdModule.rookgaardHints, {npcHandler = npcHandler}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Loui.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m a {monk}. I wanted to do something here, but I forgot what it was when I fell in that {hole}.'}) +keywordHandler:addKeyword({'monk'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m a humble servant of the {gods}.'}) +keywordHandler:addKeyword({'god'}, StdModule.say, {npcHandler = npcHandler, text = 'They created Tibia and all lifeforms.'}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = 'I have no idea how long I\'ve been in this {hole}. It seemed like an eternity!'}) +keywordHandler:addKeyword({'hole'}, StdModule.say, {npcHandler = npcHandler, text = 'While looking for something - which I forgot - I found that {hole}. I went down, even though I had no torch. And then I heard {THEM}! There must be dozens!'}) +keywordHandler:addKeyword({'them'}, StdModule.say, {npcHandler = npcHandler, text = 'They were so many, EVERYWHERE! I could barely escape alive. I have no clue what THEY were but one more second down there and I\'d have been dead!'}) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, I\'m out of mana and ingredients, please visit Cipfried in town.'}) +keywordHandler:addKeyword({'rat'}, StdModule.say, {npcHandler = npcHandler, text = 'The good thing is that those horrible rats stay mostly in town. The bad thing is that they do so because of bigger {monsters} that would devour them outside.'}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = 'Everything around us, that is Tibia.'}) +keywordHandler:addKeyword({'academy'}, StdModule.say, {npcHandler = npcHandler, text = 'Most adventurers take their first steps there.'}) +keywordHandler:addKeyword({'king'}, StdModule.say, {npcHandler = npcHandler, text = 'Pah, king! He should do something about this {hole}!'}) +keywordHandler:addKeyword({'rookgaard'}, StdModule.say, {npcHandler = npcHandler, text = 'This is the place where everything starts.'}) +keywordHandler:addKeyword({'blueberr'}, StdModule.say, {npcHandler = npcHandler, text = 'Was it...? Yes, I might have looked for blueberries as I foolishly entered this unholy {hole}.'}) +keywordHandler:addKeyword({'monster'}, StdModule.say, {npcHandler = npcHandler, text = 'There must be an army of them, just down this {hole}.'}) +keywordHandler:addKeyword({'rabbit'}, StdModule.say, {npcHandler = npcHandler, text = 'Then, they must be magic wielding beasts using creature illusion! Good thing you escaped.'}) +keywordHandler:addKeyword({'life'}, StdModule.say, {npcHandler = npcHandler, text = 'The gods blessed Tibia with abundant forms of life.'}) +keywordHandler:addKeyword({'story'}, StdModule.say, {npcHandler = npcHandler, text = 'The good thing is that those horrible rats stay mostly in town. The bad thing is that they do so because of bigger {monsters} that would devour them outside.'}) + +keywordHandler:addKeyword({'quest'}, StdModule.say, {npcHandler = npcHandler, text = 'I have no quests but to stay away from that {hole} and I recommend you to do the same.'}) +keywordHandler:addAliasKeyword({'task'}) + +keywordHandler:addKeyword({'cash'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m penniless and poor as becomes a humble monk like me.'}) +keywordHandler:addAliasKeyword({'gold'}) + +-- Names +keywordHandler:addKeyword({'dixi'}, StdModule.say, {npcHandler = npcHandler, text = 'She owns a shop in town.'}) +keywordHandler:addAliasKeyword({'lily'}) +keywordHandler:addAliasKeyword({'lee\'delle'}) + +keywordHandler:addKeyword({'norma'}, StdModule.say, {npcHandler = npcHandler, text = 'She owns a bar in town.'}) +keywordHandler:addKeyword({'loui'}, StdModule.say, {npcHandler = npcHandler, text = 'Waaaah! Don\'t shock me like that!'}) +keywordHandler:addKeyword({'santiago'}, StdModule.say, {npcHandler = npcHandler, text = 'He has his own monsters, I believe.'}) +keywordHandler:addKeyword({'zirella'}, StdModule.say, {npcHandler = npcHandler, text = 'Harmless old woman.'}) +keywordHandler:addKeyword({'al', 'dee'}, StdModule.say, {npcHandler = npcHandler, text = 'He owns a shop in town.'}) +keywordHandler:addKeyword({'amber'}, StdModule.say, {npcHandler = npcHandler, text = 'Who\'s that? Never heard about her.'}) +keywordHandler:addKeyword({'obi'}, StdModule.say, {npcHandler = npcHandler, text = 'He owns a shop in town.'}) +keywordHandler:addKeyword({'billy'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s a farmer.'}) +keywordHandler:addKeyword({'willie'}, StdModule.say, {npcHandler = npcHandler, text = 'The gods may protect me from his rudeness.'}) +keywordHandler:addKeyword({'hyacinth'}, StdModule.say, {npcHandler = npcHandler, text = 'A hermit on the other side of town.'}) +keywordHandler:addKeyword({'oracle'}, StdModule.say, {npcHandler = npcHandler, text = 'The oracle! Yes! You should get off this island as fast as you can!'}) +keywordHandler:addKeyword({'paulie'}, StdModule.say, {npcHandler = npcHandler, text = 'Young and inexperienced he is.'}) +keywordHandler:addKeyword({'seymour'}, StdModule.say, {npcHandler = npcHandler, text = 'Seymour is the headmaster of the local {academy}.'}) +keywordHandler:addKeyword({'tom'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sure he has never seen monsters like those in this hole before.'}) +keywordHandler:addKeyword({'dallheim'}, StdModule.say, {npcHandler = npcHandler, text = 'I tried to warn him about these monsters but he just laughed at me!! It\'s an outrage!'}) +keywordHandler:addAliasKeyword({'zerbrus'}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'STAY AWAY FROM THAT HOLE!') +npcHandler:setMessage(MESSAGE_FAREWELL, 'May the gods protect you! And stay away from that hole!') +npcHandler:setMessage(MESSAGE_GREET, 'BEWARE! Beware of that {hole}!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lubo.lua b/data/npc/scripts/lubo.lua new file mode 100644 index 00000000000..baf9534abec --- /dev/null +++ b/data/npc/scripts/lubo.lua @@ -0,0 +1,127 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Stop by and rest a while, tired adventurer! Have a look at my wares!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + -- Citizen outfit addon + local addonProgress = player:getStorageValue(Storage.OutfitQuest.Citizen.AddonBackpack) + if msgcontains(msg, 'addon') or msgcontains(msg, 'outfit') + or (addonProgress == 1 and msgcontains(msg, 'leather')) + or ((addonProgress == 1 or addonProgress == 2) and msgcontains(msg, 'backpack')) then + if addonProgress < 1 then + npcHandler:say('Sorry, the backpack I wear is not for sale. It\'s handmade from rare minotaur leather.', cid) + npcHandler.topic[cid] = 1 + elseif addonProgress == 1 then + npcHandler:say('Ah, right, almost forgot about the backpack! Have you brought me 100 pieces of minotaur leather as requested?', cid) + npcHandler.topic[cid] = 3 + elseif addonProgress == 2 then + if player:getStorageValue(Storage.OutfitQuest.Citizen.AddonBackpackTimer) < os.time() then + npcHandler:say('Just in time! Your backpack is finished. Here you go, I hope you like it.', cid) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:setStorageValue(Storage.OutfitQuest.Ref, math.min(0, player:getStorageValue(Storage.OutfitQuest.Ref) - 1)) + player:setStorageValue(Storage.OutfitQuest.Citizen.MissionBackpack, 0) + player:setStorageValue(Storage.OutfitQuest.Citizen.AddonBackpack, 3) + + player:addOutfitAddon(136, 1) + player:addOutfitAddon(128, 1) + else + npcHandler:say('Uh... I didn\'t expect you to return that early. Sorry, but I\'m not finished yet with your backpack. I\'m doing the best I can, promised.', cid) + end + elseif addonProgress == 3 then + npcHandler:say('Sorry, but I can only make one backpack per person, else I\'d have to close my shop and open a leather manufactory.', cid) + end + return true + end + if npcHandler.topic[cid] == 1 then + if msgcontains(msg, 'backpack') or msgcontains(msg, 'minotaur') or msgcontains(msg, 'leather') then + npcHandler:say('Well, if you really like this backpack, I could make one for you, but minotaur leather is hard to come by these days. Are you willing to put some work into this?', cid) + npcHandler.topic[cid] = 2 + end + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, 'yes') then + player:setStorageValue(Storage.OutfitQuest.Ref, math.max(0, player:getStorageValue(Storage.OutfitQuest.Ref)) + 1) + player:setStorageValue(Storage.OutfitQuest.Citizen.AddonBackpack, 1) + player:setStorageValue(Storage.OutfitQuest.Citizen.MissionBackpack, 1) + npcHandler:say('Alright then, if you bring me 100 pieces of fine minotaur leather I will see what I can do for you. You probably have to kill really many minotaurs though... so good luck!', cid) + npcHandler:releaseFocus(cid) + else + npcHandler:say('Sorry, but I don\'t run a welfare office, you know... no pain, no gain.', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + if msgcontains(msg, 'yes') then + if player:getItemCount(5878) < 100 then + npcHandler:say('Sorry, but that\'s not enough leather yet to make one of these backpacks. Would you rather like to buy a normal backpack for 10 gold?', cid) + else + npcHandler:say('Great! Alright, I need a while to finish this backpack for you. Come ask me later, okay?', cid) + + player:removeItem(5878, 100) + + player:setStorageValue(Storage.OutfitQuest.Citizen.MissionBackpack, 2) + player:setStorageValue(Storage.OutfitQuest.Citizen.AddonBackpack, 2) + player:setStorageValue(Storage.OutfitQuest.Citizen.AddonBackpackTimer, os.time() + 2 * 60 * 60) + end + else + npcHandler:say('I know, it\'s quite some work... don\'t lose heart, just keep killing minotaurs and you\'ll eventually get lucky. Would you rather like to buy a normal backpack for 10 gold?', cid) + end + npcHandler.topic[cid] = 0 + end + + -- The paradox tower quest + if msgcontains(msg, "crunor's cottage") then + npcHandler:say("Ah yes, I remember my grandfather talking about that name. This house used to be an inn a long time ago. My family bought it from some of these flower guys.", cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "flower guys") then + npcHandler:say("Oh, I mean druids of course. They sold the cottage to my family after some of them died in an accident or something like that.", cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "accident") then + npcHandler:say("As far as I can remember the story, a pet escaped its stable behind the inn. It got somehow involved with powerful magic at a ritual and was transformed in some way.", cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "stable") then + if player:getStorageValue(Storage.Quest.TheParadoxTower.TheFearedHugo) == 3 then + -- Questlog: The Feared Hugo (Completed) + player:setStorageValue(Storage.Quest.TheParadoxTower.TheFearedHugo, 4) + end + npcHandler:say("My grandpa told me, in the old days there were some behind this cottage. Nothing big though, just small ones, for chicken or rabbits.", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am selling equipment for adventurers. If you need anything, let me know.'}) +keywordHandler:addKeyword({'dog'}, StdModule.say, {npcHandler = npcHandler, text = 'This is Ruffy my dog, please don\'t do him any harm.'}) +keywordHandler:addKeyword({'offer'}, StdModule.say, {npcHandler = npcHandler, text = 'I sell torches, fishing rods, worms, ropes, water hoses, backpacks, apples, and maps.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'I am Lubo, the owner of this shop.'}) +keywordHandler:addKeyword({'maps'}, StdModule.say, {npcHandler = npcHandler, text = 'Oh! I\'m sorry, I sold the last one just five minutes ago.'}) +keywordHandler:addKeyword({'hat'}, StdModule.say, {npcHandler = npcHandler, text = 'My hat? Hanna made this one for me.'}) +keywordHandler:addKeyword({'finger'}, StdModule.say, {npcHandler = npcHandler, text = 'Oh, you sure mean this old story about the mage Dago, who lost two fingers when he conjured a dragon.'}) +keywordHandler:addKeyword({'pet'}, StdModule.say, {npcHandler = npcHandler, text = 'There are some strange stories about a magicians pet names. Ask Hoggle about it.'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome to my adventurer shop, |PLAYERNAME|! What do you need? Ask me for a {trade} to look at my wares.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye, |PLAYERNAME|.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lucius.lua b/data/npc/scripts/lucius.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/lucius.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lugri.lua b/data/npc/scripts/lugri.lua new file mode 100644 index 00000000000..444b0339c75 --- /dev/null +++ b/data/npc/scripts/lugri.lua @@ -0,0 +1,154 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "outfit") or msgcontains(msg, "addon") then + if player:getStorageValue(Storage.OutfitQuest.WizardAddon) < 1 then + npcHandler:say("This skull shows that you are a true follower of Zathroth and the glorious gods of darkness. Are you willing to prove your loyalty?", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "shield") or msgcontains(msg, "medusa shield") then + if player:getStorageValue(Storage.OutfitQuest.WizardAddon) == 1 then + npcHandler:say("Is it your true wish to sacrifice a medusa shield to Zathroth?", cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, "mail") or msgcontains(msg, "dragon scale mail") then + if player:getStorageValue(Storage.OutfitQuest.WizardAddon) == 2 then + npcHandler:say("Is it your true wish to sacrifice a dragon scale mail to Zathroth?", cid) + npcHandler.topic[cid] = 4 + end + elseif msgcontains(msg, "legs") or msgcontains(msg, "crown legs") then + if player:getStorageValue(Storage.OutfitQuest.WizardAddon) == 3 then + npcHandler:say("Is it your true wish to sacrifice crown legs to Zathroth?", cid) + npcHandler.topic[cid] = 5 + end + elseif msgcontains(msg, "ring") or msgcontains(msg, "ring of the sky") then + if player:getStorageValue(Storage.OutfitQuest.WizardAddon) == 4 then + npcHandler:say("Is it your true wish to sacrifice a ring of the sky to Zathroth?", cid) + npcHandler.topic[cid] = 6 + end + + ------------Task Part------------- + elseif msgcontains(msg, "task") then + if player:getStorageValue(Storage.KillingInTheNameOf.LugriNecromancers) <= 0 then + npcHandler:say({ + "What? Who are you to imply I need help from a worm like you? ...", + "I don't need help. But if you desperately wish to do something to earn the favour of Zathroth, feel free. Don't expect any reward though. ...", + "Do you want to help and serve Zathroth out of your own free will, without demanding payment or recognition?" + }, cid) + npcHandler.topic[cid] = 7 + elseif player:getStorageValue(Storage.KillingInTheNameOf.LugriNecromancers) == 1 then + if player:getStorageValue(Storage.KillingInTheNameOf.LugriNecromancerCount) >= 4000 then + npcHandler:say({ + "You've slain a mere {4000 necromancers and priestesses}. Still, you've shown some dedication. Maybe that means you can kill one of those so-called 'leaders' too. ...", + "Deep under Drefia, a necromancer called Necropharus is hiding in the Halls of Sacrifice. I'll place a spell on you with which you will be able to pass his weak protective gate. ...", + "Know that this will be your only chance to enter his room. If you leave it or die, you won't be able to return. We'll see if you really dare enter those halls." + }, cid) + player:setStorageValue(17521, 1) + player:setStorageValue(Storage.KillingInTheNameOf.LugriNecromancers, 2) + else + npcHandler:say("Come back when you have slain {4000 necromancers and priestesses!}", cid) + end + elseif player:getStorageValue(Storage.KillingInTheNameOf.LugriNecromancers) == 2 then + npcHandler:say({ + "So you had the guts to enter that room. Well, it's all fake magic anyway and no real threat. ...", + "What are you looking at me for? Waiting for something? I told you that there was no reward. Despite being allowed to stand before me without being squashed like a bug. Get out of my sight!" + }, cid) + player:setStorageValue(Storage.KillingInTheNameOf.LugriNecromancers, 3) + elseif player:getStorageValue(Storage.KillingInTheNameOf.LugriNecromancers) == 3 then + npcHandler:say("You can't live without serving, can you? Although you are quite annoying, you're still somewhat useful. Continue killing Necromancers and Priestesses for me. 1000 are enough this time. What do you say?", cid) + npcHandler.topic[cid] = 8 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("It will be a hard task which requires many sacrifices. Do you still want to proceed?", cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say("Good decision, |PLAYERNAME|. Your first sacrifice will be a medusa shield. Bring it to me and do give it happily.", cid) + player:setStorageValue(Storage.OutfitQuest.WizardAddon, 1) + player:setStorageValue(Storage.OutfitQuest.DefaultStart, 1) --this for default start of Outfit and Addon Quests + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + if player:removeItem(2536, 1) then + npcHandler:say("Good. I accept your sacrifice. The second sacrifice I require from you is a dragon scale mail. Bring it to me and do give it happily.", cid) + player:setStorageValue(Storage.OutfitQuest.WizardAddon, 2) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have it...", cid) + end + elseif npcHandler.topic[cid] == 4 then + if player:removeItem(2492, 1) then + npcHandler:say("Good. I accept your sacrifice. The third sacrifice I require from you are crown legs. Bring them to me and do give them happily.", cid) + player:setStorageValue(Storage.OutfitQuest.WizardAddon, 3) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have it...", cid) + end + elseif npcHandler.topic[cid] == 5 then + if player:removeItem(2488, 1) then + npcHandler:say("Good. I accept your sacrifice. The last sacrifice I require from you is a ring of the sky. Bring it to me and do give it happily.", cid) + player:setStorageValue(Storage.OutfitQuest.WizardAddon, 4) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have it...", cid) + end + elseif npcHandler.topic[cid] == 6 then + if player:removeItem(2123, 1) then + npcHandler:say("Good. I accept your sacrifice. You have proven that you are a true follower of Zathroth and do not hesitate to sacrifice worldly goods. Thus, I will reward you with this headgear. ", cid) + player:setStorageValue(Storage.OutfitQuest.WizardAddon, 5) + player:addOutfitAddon(145, 2) + player:addOutfitAddon(149, 2) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have it...", cid) + end + elseif npcHandler.topic[cid] == 7 then + npcHandler:say({ + "You do? I mean - wise decision. Let me explain. By now, Tibia has been overrun by numerous followers of different cults and beliefs. The true Necromancers died or left Tibia long ago, shortly after their battle was lost. ...", + "What is left are mainly pseudo-dark pretenders, the old wisdom and power being far beyond their grasp. They think they have the right to tap that dark power, but they don't. ...", + "I want you to eliminate them. As many as you can. All of the upstart necromancer orders, and those priestesses. And as I said, don't expect a reward - this is what has to be done to cleanse Tibia of its false dark prophets." + }, cid) + + -- aqui + player:setStorageValue(JOIN_STOR, 1) + -- aqui + player:setStorageValue(Storage.KillingInTheNameOf.LugriNecromancers, 1) + player:setStorageValue(Storage.KillingInTheNameOf.LugriNecromancerCount, 0) + elseif npcHandler.topic[cid] == 8 then + npcHandler:say("Good. Then go.", cid) + player:setStorageValue(Storage.KillingInTheNameOf.LugriNecromancers, 4) + end + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] > 1 then + npcHandler:say("Then no.", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "What is it that you want, |PLAYERNAME|?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Bye.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lukosch.lua b/data/npc/scripts/lukosch.lua new file mode 100644 index 00000000000..e752a19dda7 --- /dev/null +++ b/data/npc/scripts/lukosch.lua @@ -0,0 +1,56 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + -- WAGON TICKET + if(msgcontains(msg, "ticket")) then + if player:getStorageValue(Storage.WagonTicket) < os.time() then + npcHandler:say("Do you want to purchase a weekly ticket for the ore wagons? With it you can travel freely and swiftly through Kazordoon for one week. 250 gold only. Deal?", cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say("Your weekly ticket is still valid. Would be a waste of money to purchase a second one", cid) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "yes")) then + if(npcHandler.topic[cid] == 1) then + if player:getMoney() + player:getBankBalance() >= 250 then + player:removeMoneyNpc(250) + player:setStorageValue(Storage.WagonTicket, os.time() + 7 * 24 * 60 * 60) + npcHandler:say("Here is your stamp. It can't be transferred to another person and will last one week from now. You'll get notified upon using an ore wagon when it isn't valid anymore.", cid) + else + npcHandler:say("You don't have enough money.", cid) + end + npcHandler.topic[cid] = 0 + end + elseif(npcHandler.topic[cid] == 1) then + if(msgcontains(msg, "no")) then + npcHandler:say("No then.", cid) + npcHandler.topic[cid] = 0 + end + -- WAGON TICKET + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "Welcome, |PLAYERNAME|! Do you feel adventurous? Do you want a weekly {ticket} for the ore wagon system here? You can use it right here to get to the centre of Kazordoon!") +npcHandler:setMessage(MESSAGE_FAREWELL, "Hope to see you again.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/luna.lua b/data/npc/scripts/luna.lua new file mode 100644 index 00000000000..2b990234a14 --- /dev/null +++ b/data/npc/scripts/luna.lua @@ -0,0 +1,27 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Selling herbs, mushrooms and flowers, all picked under the light of the full moon!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +keywordHandler:addKeyword({'offers'}, StdModule.say, {npcHandler = npcHandler, text = "I'm selling various herbs, mushrooms, and flowers. If you'd like to see my offers, ask me for a {trade}."}) + +npcHandler:setMessage(MESSAGE_GREET, "Greetings, traveller. Maybe you'd like to take a look at my {offers}...") +npcHandler:setMessage(MESSAGE_FAREWELL, "Goodbye, traveller.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Goodbye, traveller.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Of course, just browse through my wares.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lunch.lua b/data/npc/scripts/lunch.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/lunch.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lungelen.lua b/data/npc/scripts/lungelen.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/lungelen.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lurik.lua b/data/npc/scripts/lurik.lua new file mode 100644 index 00000000000..7cf0e3932ae --- /dev/null +++ b/data/npc/scripts/lurik.lua @@ -0,0 +1,116 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + local player = Player(cid) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.ExplorerSociety.TheAstralPortals) == 56 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 56 then + npcHandler:say("Ah, you've just come in time. An experienced explorer is just what we need here! Would you like to go on a mission for us?", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.ExplorerSociety.TheIslandofDragons) == 58 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 58 then + if player:removeItem(7314, 1) then + npcHandler:say({ + "A frozen dragon lord? This is just the information we needed! And you even brought a scale from it! Take these 5000 gold pieces as a reward. ...", + "As you did such a great job, I might have another mission for you later." + }, cid) + player:addItem(2152, 50) + player:setStorageValue(Storage.ExplorerSociety.TheIslandofDragons, 59) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 59) + else + npcHandler:say("You're not done yet...", cid) + end + elseif player:getStorageValue(Storage.ExplorerSociety.TheIslandofDragons) == 59 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 59 then + npcHandler:say({ + "Ah, yes, the mission. Let me tell you about something called ice music. ...", + "There is a cave on Hrodmir, north of the southernmost barbarian camp Krimhorn. ...", + "In this cave, there are a waterfall and a lot of stalagmites. ...", + "When the wind blows into this cave and hits the stalagmites, it is supposed to create a sound similar to a soft song. ...", + "Please take this resonance crystal and use it on the stalagmites in the cave to record the sound of the wind." + }, cid) + player:setStorageValue(Storage.ExplorerSociety.TheIceMusic, 60) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 60) + player:addItem(7242, 1) + elseif player:getStorageValue(Storage.ExplorerSociety.TheIceMusic) == 61 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 61 and player:removeItem(7315, 1) then + npcHandler:say({ + "Ah! You did it! I can't wait to hear the sound... but I will do that in a silent moment. ...", + "You helped as much in our research here. As a reward, you may use our astral portal in the upper room from now on. ...", + "For just one orichalcum pearl, you can travel between Liberty Bay and Svargrond. Thank you again!" + }, cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.ExplorerSociety.TheIceMusic, 62) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 62) + player:setStorageValue(Storage.ExplorerSociety.IceMusicDoor, 1) + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 32 then + npcHandler:say({ + "You are the one who became an honorary barbarian! The one who made friends with the grim local musher and helped the shamans of Nibelor! The one they call old bearhugg ... erm ... I mean indeed I might have a mission for someone like you ...", + "We are trying to find out what is happening in the raider camps. Through our connection to the shamans we could get a covered contact in their majorcamp far to the south. We equipped our contact with a memory crystal so he could report all he knew ...", + "We need you to recover this crystal. Travel to the southern camp of the raiders and find our contact man there. Get the memory crystal and bring ithere. The society and the shamans will then decide our next steps. Do you think you can do this?" + }, cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 33 then + npcHandler:say("Have you retrieved the memory crystal?", cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 34 and player:getStorageValue(Storage.TheIceIslands.MemoryCrystal) > os.time() then + npcHandler:say("Give me some more time!", cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 34 and player:getStorageValue(Storage.TheIceIslands.MemoryCrystal) < os.time() then + npcHandler:say({ + "The information was quite useful. What worries me most are not the raiders but those that have driven them from the old mines...", + "We need to investigate the mines. Most entrances collapsed due to the lack of maintenance but there should be some possibilities to get in ...", + "In case you find a door, Ill tell you the old trick of the Carlin mining company to open it . Find some hint or someone who is willing to talk about what is going on there." + }, cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.TheIceIslands.Questline, 35) + player:setStorageValue(Storage.TheIceIslands.Mission09, 1) -- Questlog The Ice Islands Quest, Formorgar Mines 1: The Mission + end + elseif msgcontains(msg, "yes") then + -- ISLAND OF DRAGONS + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "Now we're talking! Maybe you've already heard of the island Okolnir south of Hrodmir. ...", + "Okolnir is the home of a new and fierce dragon race, the so-called frost dragons. However, we have no idea where they originate from. ...", + "Rumours say that dragon lords, that roamed on this isle, were somehow turned into frost dragons when the great frost covered Okolnir. ...", + "Travel to Okolnir and try to find a proof for the existence of dragon lords there in the old times. I think old Buddel might be able to bring you there." + }, cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.ExplorerSociety.TheIslandofDragons, 57) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 57) + -- ISLAND OF DRAGONS + elseif npcHandler.topic[cid] == 2 then + npcHandler:say("Excellent. Just report about your mission when you got the memory crystal.", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 33) + player:setStorageValue(Storage.TheIceIslands.Mission08, 2) -- Questlog The Ice Islands Quest, The Contact + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + if player:removeItem(7281, 1) then + npcHandler:say("Ah, great. Please give me some time to evaluate the information. Then talk to me again about your mission. ", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 34) + player:setStorageValue(Storage.TheIceIslands.Mission08, 4) -- Questlog The Ice Islands Quest, The Contact + player:setStorageValue(Storage.TheIceIslands.MemoryCrystal, os.time() + 5 * 60) + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lynda.lua b/data/npc/scripts/lynda.lua new file mode 100644 index 00000000000..ed65d13c5df --- /dev/null +++ b/data/npc/scripts/lynda.lua @@ -0,0 +1,229 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, "angelina") then + if player:getStorageValue(Storage.OutfitQuest.MageSummoner.AddonWand) == 1 then + npcHandler:say({ + "Angelina had been imprisoned? My, these are horrible news, but I am so glad to hear that she is safe now. ...", + "I will happily carry out her wish and reward you, but I fear I need some important ingredients for my blessing spell first. ...", + "Will you gather them for me?" + }, cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "wand") or msgcontains(msg, "rod") then + if player:getStorageValue(Storage.OutfitQuest.MageSummoner.AddonWand) == 2 then + npcHandler:say("Did you bring a sample of each wand and each rod with you?", cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, "sulphur") then + if player:getStorageValue(Storage.OutfitQuest.MageSummoner.AddonWand) == 3 then + npcHandler:say("Did you obtain 10 ounces of magic sulphur?", cid) + npcHandler.topic[cid] = 4 + end + elseif msgcontains(msg, "soul stone") then + if player:getStorageValue(Storage.OutfitQuest.MageSummoner.AddonWand) == 4 then + npcHandler:say("Were you actually able to retrieve the Necromancer's soul stone?", cid) + npcHandler.topic[cid] = 5 + end + elseif msgcontains(msg, "ankh") then + if player:getStorageValue(Storage.OutfitQuest.MageSummoner.AddonWand) == 5 then + npcHandler:say("Am I sensing enough holy energy from ankhs here?", cid) + npcHandler.topic[cid] = 6 + end + elseif msgcontains(msg, "ritual") then + if player:getStorageValue(Storage.OutfitQuest.MageSummoner.AddonWand) == 6 then + if player:getStorageValue(Storage.OutfitQuest.MageSummoner.AddonWandTimer) < os.time() then + player:setStorageValue(Storage.OutfitQuest.MageSummoner.AddonWand, 7) + player:addOutfitAddon(141, 1) + player:addOutfitAddon(130, 1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + npcHandler:say('I\'m glad to tell you that I have finished the ritual, player. Here is your new wand. I hope you carry it proudly for everyone to see..', cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say('Please let me focus for a while, |PLAYERNAME|.', cid) + end + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "Thank you, I promise that your efforts won't be in vain! Listen closely now: First, I need a sample of five druid rods and five sorcerer wands. ...", + "I need a snakebite rod, a moonlight rod, a necrotic rod, a terra rod and a hailstorm rod. Then, I need a wand of vortex, a wand of dragonbreath ...", + "... a wand of decay, a wand of cosmic energy and a wand of inferno. Please bring them all at once so that their energy will be balanced. ...", + "Secondly, I need 10 ounces of magic sulphur. It can absorb the elemental energy of all the wands and rods and bind it to something else. ...", + "Next, I will need a soul stone. These can be used as a vessel for energy, evil as well as good. They are rarely used nowaday though. ...", + "Lastly, I need a lot of holy energy. I can extract it from ankhs, but only a small amount each time. I will need about 20 ankhs. ...", + "Did you understand everything I told you and will help me with my blessing?" + }, cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say("Alright then. Come back to with a sample of all five wands and five rods, please.", cid) + player:setStorageValue(Storage.OutfitQuest.MageSummoner.AddonWand, 2) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + if player:getItemCount(2181) > 0 and player:getItemCount(2182) > 0 and player:getItemCount(2183) > 0 and player:getItemCount(2185) > 0 and player:getItemCount(2186) > 0 and player:getItemCount(2187) > 0 and player:getItemCount(2188) > 0 and player:getItemCount(2189) > 0 and player:getItemCount(2190) > 0 and player:getItemCount(2191) > 0 then + npcHandler:say("Thank you, that must have been a lot to carry. Now, please bring me 10 ounces of magic sulphur.", cid) + player:removeItem(2181, 1) + player:removeItem(2182, 1) + player:removeItem(2183, 1) + player:removeItem(2185, 1) + player:removeItem(2186, 1) + player:removeItem(2187, 1) + player:removeItem(2188, 1) + player:removeItem(2189, 1) + player:removeItem(2190, 1) + player:removeItem(2191, 1) + player:setStorageValue(Storage.OutfitQuest.MageSummoner.AddonWand, 3) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 4 then + if player:removeItem(5904, 10) then + npcHandler:say("Very good. I will immediately start to prepare the ritual and extract the elemental energy from the wands and rods. Please bring me the Necromancer's soul stone now.", cid) + player:setStorageValue(Storage.OutfitQuest.MageSummoner.AddonWand, 4) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 5 then + if player:removeItem(5809, 1) then + npcHandler:say("You have found a rarity there, |PLAYERNAME|. This will become the tip of your blessed wand. Please bring me 20 ankhs now to complete the ritual.", cid) + player:setStorageValue(Storage.OutfitQuest.MageSummoner.AddonWand, 5) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 6 then + if player:removeItem(2193, 20) then + npcHandler:say("The ingredients for the ritual are complete! I will start to prepare your blessed wand, but I have to medidate first. Please come back later to hear how the ritual went.", cid) + player:setStorageValue(Storage.OutfitQuest.MageSummoner.AddonWand, 6) + player:setStorageValue(Storage.OutfitQuest.MageSummoner.AddonWandTimer, os.time() + 10800) + npcHandler.topic[cid] = 0 + end + end + end +end + +local function confirmWedding(cid, message, keywords, parameters, node) + if(not npcHandler:isFocused(cid)) then + return false + end + + local player = Player(cid) + local playerStatus = getPlayerMarriageStatus(player:getGuid()) + local candidate = getPlayerSpouse(player:getGuid()) + if playerStatus == PROPACCEPT_STATUS then + -- local item3 = Item(doPlayerAddItem(cid,ITEM_Meluna_Ticket,2)) + setPlayerMarriageStatus(player:getGuid(), MARRIED_STATUS) + setPlayerMarriageStatus(candidate, MARRIED_STATUS) + setPlayerSpouse(player:getGuid(), candidate) + setPlayerSpouse(candidate, player:getGuid()) + delayedSay('Dear friends and family, we are gathered here today to witness and celebrate the union of ' .. getPlayerNameById(candidate) .. ' and ' .. player:getName() .. ' in marriage.') + delayedSay('Through their time together, they have come to realize that their personal dreams, hopes, and goals are more attainable and more meaningful through the combined effort and mutual support provided in love, commitment, and family;',5000) + delayedSay('and so they have decided to live together as husband and wife. And now, by the power vested in me by the Gods of Tibia, I hereby pronounce you husband and wife.',15000) + delayedSay('*After a whispered blessing opens an hand towards ' .. player:getName() .. '* Take these two engraved wedding rings and give one of them to your spouse.',22000) + delayedSay('You may now kiss your bride.',28000) + local item1 = Item(doPlayerAddItem(cid,ITEM_ENGRAVED_WEDDING_RING,1)) + local item2 = Item(doPlayerAddItem(cid,ITEM_ENGRAVED_WEDDING_RING,1)) + item1:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, player:getName() .. ' & ' .. getPlayerNameById(candidate) .. ' forever - married on ' .. os.date('%B %d, %Y.')) + item2:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, player:getName() .. ' & ' .. getPlayerNameById(candidate) .. ' forever - married on ' .. os.date('%B %d, %Y.')) + else + npcHandler:say('Your partner didn\'t accept your proposal, yet', cid) + end + return true +end + -- END -- +local function confirmRemoveEngage(cid, message, keywords, parameters, node) + if(not npcHandler:isFocused(cid)) then + return false + end + + local player = Player(cid) + local playerStatus = getPlayerMarriageStatus(player:getGuid()) + local playerSpouse = getPlayerSpouse(player:getGuid()) + if playerStatus == PROPOSED_STATUS then + + npcHandler:say('Are you sure you want to remove your wedding proposal with {' .. getPlayerNameById(playerSpouse) .. '}?', cid) + node:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, moveup = 3, text = 'Ok, let\'s keep it then.'}) + + local function removeEngage(cid, message, keywords, parameters, node) + doPlayerAddItem(cid,ITEM_WEDDING_RING,1) + doPlayerAddItem(cid,10503,1) + setPlayerMarriageStatus(player:getGuid(), 0) + setPlayerSpouse(player:getGuid(), -1) + npcHandler:say(parameters.text, cid) + keywordHandler:moveUp(parameters.moveup) + end + node:addChildKeyword({'yes'}, removeEngage, {moveup = 3, text = 'Ok, your marriage proposal to {' .. getPlayerNameById(playerSpouse) .. '} has been removed. Take your wedding ring back.'}) + else + npcHandler:say('You don\'t have any pending proposal to be removed.', cid) + keywordHandler:moveUp(2) + end + return true +end + +local function confirmDivorce(cid, message, keywords, parameters, node) + if(not npcHandler:isFocused(cid)) then + return false + end + + local player = Player(cid) + local playerStatus = getPlayerMarriageStatus(player:getGuid()) + local playerSpouse = getPlayerSpouse(player:getGuid()) + if playerStatus == MARRIED_STATUS then + npcHandler:say('Are you sure you want to divorce of {' .. getPlayerNameById(playerSpouse) .. '}?', cid) + node:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, moveup = 3, text = 'Great! Marriages should be an eternal commitment.'}) + + local function divorce(cid, message, keywords, parameters, node) + local player = Player(cid) + local spouse = getPlayerSpouse(player:getGuid()) + setPlayerMarriageStatus(player:getGuid(), 0) + setPlayerSpouse(player:getGuid(), -1) + setPlayerMarriageStatus(spouse, 0) + setPlayerSpouse(spouse, -1) + npcHandler:say(parameters.text, cid) + keywordHandler:moveUp(parameters.moveup) + end + node:addChildKeyword({'yes'}, divorce, {moveup = 3, text = 'Ok, you are now divorced of {' .. getPlayerNameById(playerSpouse) .. '}. Think better next time after marrying someone.'}) + else + npcHandler:say('You aren\'t married to get a divorce.', cid) + keywordHandler:moveUp(2) + end + return true +end + +local node1 = keywordHandler:addKeyword({'marry'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Would you like to get married? Make sure you have a wedding ring and the wedding outfit box with you.'}) +node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, moveup = 1, text = 'That\'s fine.'}) +local node2 = node1:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'And who would you like to marry?'}) +node2:addChildKeyword({'[%w]'}, tryEngage, {}) + +local node3 = keywordHandler:addKeyword({'celebration'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Is your soulmate and friends here with you for the celebration?.'}) +node3:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, moveup = 1, text = 'Then go bring them here!.'}) +local node4 = node3:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Good, let\'s {begin} then!.'}) --, confirmWedding, {}) +node4:addChildKeyword({'begin'}, confirmWedding, {}) + +keywordHandler:addKeyword({'remove'}, confirmRemoveEngage, {}) + +keywordHandler:addKeyword({'divorce'}, confirmDivorce, {}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome in the name of the gods, pilgrim |PLAYERNAME|!") +npcHandler:setMessage(MESSAGE_FAREWELL, "Be careful on your journeys.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Be careful on your journeys.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/lyonel.lua b/data/npc/scripts/lyonel.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/lyonel.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/maealil.lua b/data/npc/scripts/maealil.lua new file mode 100644 index 00000000000..d00cd1e2a55 --- /dev/null +++ b/data/npc/scripts/maealil.lua @@ -0,0 +1,113 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +-- Twist of Fate +local blessKeyword = keywordHandler:addKeyword({'twist of fate'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'This is a special blessing I can bestow upon you once you have obtained at least one of the other blessings and which functions a bit differently. ...', + 'It only works when you\'re killed by other adventurers, which means that at least half of the damage leading to your death was caused by others, not by monsters or the environment. ...', + 'The {twist of fate} will not reduce the death penalty like the other blessings, but instead prevent you from losing your other blessings as well as the amulet of loss, should you wear one. It costs the same as the other blessings. ...', + 'Would you like to receive that protection for a sacrifice of |PVPBLESSCOST| gold, child?' + }}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the protection of the twist of fate, pilgrim.', cost = '|PVPBLESSCOST|', bless = 1}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Adventurer Stone +keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Keep your adventurer\'s stone well.'}, function(player) return player:getItemById(18559, true) end) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for free?'}, function(player) return player:getStorageValue(Storage.AdventurersGuild.FreeStone.Maealil) ~= 1 end) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, nil, function(player) player:addItem(18559, 1) player:setStorageValue(Storage.AdventurersGuild.FreeStone.Maealil, 1) end) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for 30 gold?'}) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, + function(player) return player:getMoney() + player:getBankBalance() >= 30 end, + function(player) if player:removeMoneyNpc(30) then player:addItem(18559, 1) end end + ) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, you don\'t have enough money.', reset = true}) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +-- Wooden Stake +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'I think you have forgotten to bring your stake.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 3 and player:getItemCount(5941) == 0 end) + +local stakeKeyword = keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes, I was informed what to do. Are you prepared to receive my line of the prayer?'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 3 end) + stakeKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'So receive my prayer: \'Peace may fill your soul - evil shall be cleansed\'. Now, bring your stake to Yberius in the Venore temple for the next line of the prayer. I will inform him what to do.', reset = true}, nil, + function(player) player:setStorageValue(Storage.FriendsandTraders.TheBlessedStake, 4) player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) end + ) + stakeKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'I will wait for you.', reset = true}) + +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You should visit Yberius in the Venore temple now.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 4 end) +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You already received my line of the prayer.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) > 4 end) +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'A blessed stake? That is a strange request. Maybe Quentin knows more, he is one of the oldest monks after all.'}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.'}, function(player) return player:hasBlessing(2) end) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin will provide you with the embrace of Tibia.'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +-- Greeting message +keywordHandler:addGreetKeyword({"ashari"}, {npcHandler = npcHandler, text = "Welcome, young |PLAYERNAME|! If you are heavily wounded or poisoned, I can {heal} you for free."}) +--Farewell message +keywordHandler:addFarewellKeyword({"asgha thrazi"}, {npcHandler = npcHandler, text = "May the gods bless you, |PLAYERNAME|!"}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, young |PLAYERNAME|! If you are heavily wounded or poisoned, I can {heal} you for free.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Remember: If you are heavily wounded or poisoned, I can heal you for free.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'May the gods bless you, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/maelyrra.lua b/data/npc/scripts/maelyrra.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/maelyrra.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/maeryn.lua b/data/npc/scripts/maeryn.lua new file mode 100644 index 00000000000..ec41f014b1c --- /dev/null +++ b/data/npc/scripts/maeryn.lua @@ -0,0 +1,151 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local vocations = { + ['sorcerer'] = 0, + ['druid'] = 1, + ['paladin'] = 2, + ['knight'] = { + ['club'] = 3, + ['axe'] = 4, + ['sword'] = 5, + } + } +local knightChoice = {} + +local function greetCallback(cid) + knightChoice[cid] = nil + return true +end +local voices = { + { text = "Not enough purple nightshade ... not enough liquid silver. *sigh*" }, + { text = "You think the full moon is a romantic affair? Think again!" }, + { text = "This place isn't safe. You should leave this island." } +} + +npcHandler:addModule(VoiceModule:new(voices)) +function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + if msg == "hi" or msg == "hello" then + npcHandler:say("Greetings, visitor. I wonder what may lead you to this {dangerous} place.", cid) + npcHandler:addFocus(cid) + else + return false + end + end + + local player = Player(cid) + if not player then + return false + end + + if msgcontains(msg, 'tokens') then + elseif isInArray({'dangerous', 'beasts'}, msg:lower()) then + npcHandler:say("So you don't know it yet. This island, Grimvale, is affected by were-sickness. Many {pitiful}, who are stricken with the curse, dwell in the {tunnels} and caverns underneath the village and the nearby hurst.", cid) + elseif msgcontains(msg, 'pitiful') then + npcHandler:say("Yes, pitiful. For they are savage beasts now who regularly come up from below to attack the village. But once they were inhabitants of Grimvale, before they {changed}.", cid) + elseif msgcontains(msg, 'changed') then + npcHandler:say("Through a bite or even a scratch, you may be infected with the were-sickness. If that happens, there is little {hope} - until the next full moon you'll change into a were-creature, depending on the animal that hurt you.", cid) + elseif msgcontains(msg, 'hope') then + npcHandler:say("There is a plant, the purple nightshade. It blossoms exclusively in the light of the full moon and only underground, where the full moon's light is falling through fissures in the surface. Only this plant's blossoms are able to defeat the {were-sickness}.", cid) + elseif isInArray({'were-sickness', 'curse'}, msg:lower()) then + npcHandler:say({"It transforms peaceful villagers into savage beasts. We're not sure how this curse found the way into our small village. But one day it began. At first it befell just a few people. ...", + "In a full moon night they changed into bears and wolves, and tore apart their unsuspecting relatives while they were asleep. ...", + "Those merely wounded, first thought they were lucky. But then we realised they were changing, too. Later, others assumed the forms of badgers and boars also. ...", + "But that does not mean they were any less wild or dangerous than the others."}, cid) + elseif msgcontains(msg, 'tunnels') then + npcHandler:say({"We are not sure what they are doing down there. We're glad if they stay in the caverns and leave us alone. Only at full moon do they come up and threaten the island's surface and village. ...", + "I, however, have a {hunch} as to why they dwell so deep under the earth."}, cid) + elseif msgcontains(msg, 'hunch') then + npcHandler:say({"There are old legends about a subterranean temple that was once built in this area. Supposedly many {artefacts} are still hidden down there. ...", + "I don't have the time to tell you the entire tale, but there is a book downstairs in which you may read the whole story."}, cid) + elseif msgcontains(msg, 'artefacts') then + npcHandler:say("Yes, the story goes that there are ancient artefacts still hidden in the temple ruins, such as helmets in the form of wolven heads, for example. It is said that moonlight crystals are needed to enchant these artefacts.", cid) + elseif msgcontains(msg, 'moon') then + npcHandler:say({"Every month around the 13th, the single Tibian moon will by fully visible to us. That's when the curse hits us hardest. ...", + "The two days around the 13th, the 12th and the 14th, are considered 'Harvest Moon', those are the best to gather {nightshade}. However, only after it has reached its apex on the 13th, the curse strengthens. ...", + "We do not know what happens down there in those tunnels around that time but there is a presence there, we all feel - yet cannot quite fathom. ...", + "At full moon, humans transform into wild beasts: wolves, boars, bears and others. Some call it the {curse} of the Full Moon, others think it is a kind of sickness. .", + "During this time, we try to not leave the house, we shut the windows and hope it will pass. The curse will weaken a bit after that but it returns. Every month."}, cid) + elseif msgcontains(msg, 'nightshade') then + npcHandler:say("Three of these blossoms should suffice to heal some afflicted persons. But if you bring more I'd be grateful, of course.", cid) + elseif msgcontains(msg, 'name') then + npcHandler:say("My name is Maeryn.", cid) + elseif msgcontains(msg, 'maeryn') then + npcHandler:say("Yes, that's me.", cid) + elseif msgcontains(msg, 'time') then + npcHandler:say("It's exactly " .. getFormattedWorldTime() .. ".", cid) + elseif msgcontains(msg, 'job') then + npcHandler:say("I'm the protector of this little village. A bit of a self-proclaimed function, I admit, but someone has to watch over {Grimvale}. It is a {dangerous} place.", cid) + elseif msgcontains(msg, 'grimvale') then + npcHandler:say("The small island you are standing on. For a long time it was a peaceful and placid place. But lately it has become more {dangerous}.", cid) + elseif msgcontains(msg, 'owin') then + npcHandler:say("He's an experienced hunter and knows much about the woods, the animals that dwell there, and about the {werewolves}. He's devoted himself to finding out everything there is to know about the {Curse}.", cid) + elseif msgcontains(msg, 'werewolves') then + npcHandler:say("Yes, my friend, werewolves. They dwell here on {Grimvale}, threatening our life. The were-sickness transforms peaceful villagers into savage beasts. We're not sure how this curse found its way into our small village. But undoubtedly it did.", cid) + elseif msgcontains(msg, 'gladys') then + npcHandler:say("She's an old druid. She's been living here on {Grimvale} since she was a little girl, just like me. She's very interested in were-creature body parts. If you find any, I'm sure she will love to trade with you.", cid) + elseif msgcontains(msg, 'cornell') then + npcHandler:say("He's basically a ferryman nowadays, but I remember when he was our village's leading fisherman. He offers a ferry service between Grimvale and Edron. You must have met him - he sailed you here.", cid) + elseif msgcontains(msg, 'werewolf helmet') then + npcHandler:say("You brought the wolven helmet, as i see. Do you want to change something?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + npcHandler:say("So, which profession would you give preference to when enchanting the helmet: {knight}, {sorcerer}, {druid} or {paladin}?", cid) + npcHandler.topic[cid] = 2 + end + elseif isInArray({'knight', 'sorcerer', 'druid', 'paladin'}, msg:lower()) and npcHandler.topic[cid] == 2 then + local helmet = msg:lower() + if not vocations[helmet] then + return false + end + if msg:lower() == 'knight' then + npcHandler:say("And what would be your preferred weapon? {Club}, {axe} or {sword}", cid) + knightChoice[cid] = helmet + npcHandler.topic[cid] = 3 + end + if npcHandler.topic[cid] == 2 then + --if (Set storage if player can enchant helmet(need Grim Vale quest)) then + player:setStorageValue(Storage.Grimvale.WereHelmetEnchant, vocations[helmet]) + npcHandler:say("So this is your choice. If you want to change it, you will have to come to me again.", cid) + --else + --npcHandler:say("Message when player do not have quest.", cid) + --end + npcHandler.topic[cid] = 0 + end + elseif isInArray({'axe', 'club', 'sword'}, msg:lower()) and npcHandler.topic[cid] == 3 then + local weapontype = msg:lower() + if not vocations[knightChoice[cid]][weapontype] then + return false + else + --if (Set storage if player can enchant helmet(need Grim Vale quest)) then + player:setStorageValue(Storage.Grimvale.WereHelmetEnchant, vocations[knightChoice[cid]][weapontype]) + npcHandler:say("So this is your choice. If you want to change it, you will have to come to me again.", cid) + --else + --npcHandler:say("Message when player do not have quest.", cid) + --end + knightChoice[cid] = nil + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'bye') then + npcHandler:say("Farewell, then.", cid) + npcHandler:releaseFocus(cid) + end +end +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) diff --git a/data/npc/scripts/malor.lua b/data/npc/scripts/malor.lua new file mode 100644 index 00000000000..dab115f97ac --- /dev/null +++ b/data/npc/scripts/malor.lua @@ -0,0 +1,109 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local function releasePlayer(cid) + if not Player(cid) then + return + end + + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + local missionProgress = player:getStorageValue(Storage.DjinnWar.EfreetFaction.Mission03) + if msgcontains(msg, 'mission') then + if player:getStorageValue(Storage.DjinnWar.EfreetFaction.Mission02) == 3 then + if missionProgress < 1 then + npcHandler:say({ + 'I guess this is the first time I entrust a human with a mission. And such an important mission, too. But well, we live in hard times, and I am a bit short of adequate staff. ...', + 'Besides, Baa\'leal told me you have distinguished yourself well in previous missions, so I think you might be the right person for the job. ...', + 'But think carefully, human, for this mission will bring you close to certain death. Are you prepared to embark on this mission?' + }, cid) + npcHandler.topic[cid] = 1 + + elseif missionProgress == 1 then + npcHandler:say('You haven\'t finished your final mission yet. Shall I explain it again to you?', cid) + npcHandler.topic[cid] = 1 + + elseif missionProgress == 2 then + npcHandler:say('Have you found Fa\'hradin\'s lamp and placed it in Malor\'s personal chambers?', cid) + npcHandler.topic[cid] = 2 + else + npcHandler:say('There\'s no mission left for you, friend of the Efreet. However, I have a {task} for you.', cid) + end + else + npcHandler:say({ + 'So you would like to fight for us. Hmm. ...', + 'You show true courage, human, but I will not accept your offer at this point of time.' + }, cid) + end + + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, 'yes') then + npcHandler:say({ + 'Well, listen. We are trying to acquire the ultimate weapon to defeat Gabel: Fa\'hradin\'s lamp! ...', + 'At the moment it is still in the possession of that good old friend of mine, the Orc King, who kindly released me from it. ...', + 'However, for some reason he is not as friendly as he used to be. You better watch out, human, because I don\'t think you will get the lamp without a fight. ...', + 'Once you have found the lamp you must enter Ashta\'daramai again. Sneak into Gabel\'s personal chambers and exchange his sleeping lamp with Fa\'hradin\'s lamp! ...', + 'If you succeed, the war could be over one night later!' + }, cid) + player:setStorageValue(Storage.DjinnWar.EfreetFaction.Mission03, 1) + + elseif msgcontains(msg, 'no') then + npcHandler:say('Your choice.', cid) + npcHandler.topic[cid] = 0 + end + + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, 'yes') then + npcHandler:say({ + 'Well well, human. So you really have made it - you have smuggled the modified lamp into Gabel\'s bedroom! ...', + 'I never thought I would say this to a human, but I must confess I am impressed. ...', + 'Perhaps I have underestimated you and your kind after all. ...', + 'I guess I will take this as a lesson to keep in mind when I meet you on the battlefield. ...', + 'But that\'s in the future. For now, I will confine myself to give you the permission to trade with my people whenever you want to. ...', + 'Farewell, human!' + }, cid) + player:setStorageValue(Storage.DjinnWar.EfreetFaction.Mission03, 3) + player:setStorageValue(Storage.DjinnWar.EfreetFaction.DoorToMaridTerritory, 1) + player:addAchievement('Efreet Ally') + addEvent(releasePlayer, 1000, cid) + + elseif msgcontains(msg, 'no') then + npcHandler:say('Just do it!', cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +-- Greeting +keywordHandler:addGreetKeyword({"djanni'hah"}, {npcHandler = npcHandler, text = "Greetings, human |PLAYERNAME|. My patience with your kind is limited, so speak quickly and choose your words well."}) + +npcHandler:setMessage(MESSAGE_FAREWELL, "Farewell, human. When I have taken my rightful place I shall remember those who served me well. Even if they are only humans.") +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Farewell, human.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/malunga.lua b/data/npc/scripts/malunga.lua new file mode 100644 index 00000000000..fd4a12c3898 --- /dev/null +++ b/data/npc/scripts/malunga.lua @@ -0,0 +1,22 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = ''} } +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "Greetings. I have only little time to {spare}, so the conversation will be short. I teach sorcerer {spells} and buy a few magical {ingredients}.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/marcus.lua b/data/npc/scripts/marcus.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/marcus.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/maria.lua b/data/npc/scripts/maria.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/maria.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/marina.lua b/data/npc/scripts/marina.lua new file mode 100644 index 00000000000..46913d2a604 --- /dev/null +++ b/data/npc/scripts/marina.lua @@ -0,0 +1,96 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "silk") or msgcontains(msg, "yarn") or msgcontains(msg, "silk yarn") or msgcontains(msg, "spool of yarn") then + if player:getStorageValue(Storage.FriendsandTraders.TheMermaidMarina) < 1 then + npcHandler:say("Um. You mean, you really want me to touch that gooey spider silk just because you need yarn? Well... do you think that I'm pretty?", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.FriendsandTraders.TheMermaidMarina) == 2 then + npcHandler:say("Okay... a deal is a deal, would you like me to create a {spool of yarn} from {10 pieces of spider silk}?", cid) + npcHandler.topic[cid] = 5 + end + elseif msgcontains(msg, "honey") or msgcontains(msg, "honeycomb") or msgcontains(msg, "50 honeycombs") then + if player:getStorageValue(Storage.FriendsandTraders.TheMermaidMarina) == 1 then + npcHandler:say("Did you bring me the 50 honeycombs I requested and do you absolutely admire my beauty?", cid) + npcHandler.topic[cid] = 4 + end + elseif msgcontains(msg, "raymond striker") then + if player:getStorageValue(Storage.TheShatteredIsles.APoemForTheMermaid) == 1 then + npcHandler:say(" I think he has a crush on me. Well, silly man, it is only for his own good. This way he can get accustomed to TRUE beauty. And I won't give him up anymore now that he is mine.", cid) + player:setStorageValue(Storage.TheShatteredIsles.APoemForTheMermaid, 2) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "date") then + if player:getStorageValue(Storage.TheShatteredIsles.ADjinnInLove) == 1 then + npcHandler:say("Is that the best you can do? A true Djinn would have done something more poetic.", cid) + player:setStorageValue(Storage.TheShatteredIsles.ADjinnInLove, 2) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheShatteredIsles.ADjinnInLove) == 4 then + npcHandler:say({ + "This lovely, exotic Djinn is a true poet. And he is asking me for a date? Excellent. Now I can finaly dump this human pirate. He was growing to be boring more and more with each day ...", + "As a little reward for your efforts I allow you to ride my sea turtles. Just look around at the shores and you will find them." + }, cid) + player:addAchievement('Matchmaker') + player:setStorageValue(Storage.TheShatteredIsles.ADjinnInLove, 5) + player:setStorageValue(Storage.TheShatteredIsles.AccessToLagunaIsland, 1) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Well, everyone would say that in your position. Do you think that I'm really, absolutely the most stunning being that you have ever seen?", cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say({ + " It's funny how easy it is to get humans to say what you want. Now, proving it will be even more fun! ...", + "You want me to touch something gooey, so you have to touch something gooey for me too. ...", + "I love honey and I haven't eaten it in a while, so bring me 50 honeycombs and worship my beauty a little more, then we will see." + }, cid) + player:setStorageValue(Storage.FriendsandTraders.TheMermaidMarina, 1) + player:setStorageValue(Storage.FriendsandTraders.DefaultStart, 1) + elseif npcHandler.topic[cid] == 4 then + if player:removeItem(5902, 50) then + npcHandler:say("Oh goodie! Thank you! Okay... I guess since my fingers are sticky now anyway, I will help you. From now on, if you bring me {10 pieces of spider silk}, I will create one {spool of yarn}.", cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.FriendsandTraders.TheMermaidMarina, 2) + else + npcHandler:say("You don't have enough honey.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 5 then + if player:removeItem(5879, 10) then + player:addItem(5886, 1) + npcHandler:say("Ew... gooey... there you go.", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have the required items.", cid) + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +keywordHandler:addKeyword({'comb'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, I don\'t have a spare comb. I lost my favourite one when diving around in Calassa.'}) +keywordHandler:addKeyword({'mermaid comb'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, I don\'t have a spare comb. I lost my favourite one when diving around in Calassa.'}) + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/maris.lua b/data/npc/scripts/maris.lua new file mode 100644 index 00000000000..5bd4ecede74 --- /dev/null +++ b/data/npc/scripts/maris.lua @@ -0,0 +1,38 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Travel +local function addTravelKeyword(keyword, cost, destination) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you want go to the ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'Alright then!', reset = true}) +end + +addTravelKeyword('fenrock', 100, Position(32563, 31313, 7)) +addTravelKeyword('mistrock', 100, Position(32640, 31439, 7)) + +-- Basic +keywordHandler:addKeyword({'offer'}, StdModule.say, {npcHandler = npcHandler, text = 'I can take you to {Fenrock} and {Mistrock}!'}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'I can take you to {Fenrock} and {Mistrock}!'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am Maris, Captain of this ship.'}) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = 'I am Maris, Captain of this ship.'}) + +npcHandler:setMessage(MESSAGE_GREET, "I hope you have a good reason to step near my ship, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Yeah, bye or whatever.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Bye.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/maris_fenrock.lua b/data/npc/scripts/maris_fenrock.lua new file mode 100644 index 00000000000..b70dd35493d --- /dev/null +++ b/data/npc/scripts/maris_fenrock.lua @@ -0,0 +1,41 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Travel +local function addTravelKeyword(keyword, text, cost, destination) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you want go to ' .. text .. ' for |TRAVELCOST|?', cost = cost}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'Alright then!', reset = true}) +end + +addTravelKeyword('yalahar', 'back to Yalahar', 100, Position(32649, 31292, 6)) +addTravelKeyword('mistrock', 'to the Mistrock', 50, Position(32640, 31439, 7)) + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, destination = {Position(32561, 31312, 7)}}) + +-- Basic +keywordHandler:addKeyword({'offer'}, StdModule.say, {npcHandler = npcHandler, text = 'I can take you to {Yalahar} or {Mistrock}!'}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'I can take you to {Yalahar} or {Mistrock}!'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am Maris, Captain of this ship.'}) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = 'I am Maris, Captain of this ship.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Oh, you're still alive. Hello, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Yeah, bye or whatever.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Bye.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/maris_mistrock.lua b/data/npc/scripts/maris_mistrock.lua new file mode 100644 index 00000000000..67a36134d4a --- /dev/null +++ b/data/npc/scripts/maris_mistrock.lua @@ -0,0 +1,47 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Travel +local function addTravelKeyword(keyword, text, cost, destination) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you want go to ' .. text .. ' for |TRAVELCOST|?', cost = cost}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'Alright then!', reset = true}) +end + +addTravelKeyword('yalahar', 'back to Yalahar', 100, Position(32649, 31292, 6)) +addTravelKeyword('fenrock', 'to the Fenrock', 100, Position(32563, 31313, 7)) + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, destination = {Position(32634, 31437, 7), Position(32634, 31438, 7)}}) + +-- Basic +keywordHandler:addKeyword({'mistrock'}, StdModule.say, {npcHandler = npcHandler, + text = { + "Do you smell this? It's the smell of fire... the fire of a forge. Many people searched this rock here for a hidden path, but they haven't found anything. ...", + "I'd search on Fenrock if I were you. Even though there's snow on the surface, it's still warm underground. There are often caves under fresh lava streams." + }}, nil, function(player) if player:getStorageValue(Storage.HiddenCityOfBeregar.WayToBeregar) ~= 1 then player:setStorageValue(Storage.HiddenCityOfBeregar.WayToBeregar, 1) end end +) +keywordHandler:addKeyword({'offer'}, StdModule.say, {npcHandler = npcHandler, text = 'I can take you to {Yalahar} or {Fenrock}!'}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'I can take you to {Yalahar} or {Fenrock}!'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am Maris, Captain of this ship.'}) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = 'I am Maris, Captain of this ship.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Oh, you're still alive. Hello, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Yeah, bye or whatever.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Bye.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/maritima.lua b/data/npc/scripts/maritima.lua new file mode 100644 index 00000000000..0146e872a5a --- /dev/null +++ b/data/npc/scripts/maritima.lua @@ -0,0 +1,40 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if(msgcontains(msg, "quara")) then + if(player:getStorageValue(Storage.InServiceofYalahar.Questline) == 41 and player:getStorageValue(Storage.InServiceofYalahar.QuaraInky) < 1 and player:getStorageValue(Storage.InServiceofYalahar.QuaraSplasher) < 1 and player:getStorageValue(Storage.InServiceofYalahar.QuaraSharptooth) < 1) then + npcHandler:say({ + "The quara in this area are a strange race that seeks for inner perfection rather than physical one. ...", + "However, recently the quara got mad because their area is flooded with toxic sewage from the city. If you could inform someone about it, they might stop the sewage and the quara could return to their own business." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 42) + player:setStorageValue(Storage.InServiceofYalahar.Mission07, 3) -- StorageValue for Questlog "Mission 07: A Fishy Mission" + player:setStorageValue(Storage.InServiceofYalahar.QuaraState, 1) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/markwin.lua b/data/npc/scripts/markwin.lua new file mode 100644 index 00000000000..e54205dfe77 --- /dev/null +++ b/data/npc/scripts/markwin.lua @@ -0,0 +1,100 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_TICKS, 30 * 1000) +condition:setParameter(CONDITION_PARAM_MINVALUE, 30) +condition:setParameter(CONDITION_PARAM_TICKINTERVAL, 4000) + +local guards = { "Minotaur Guard", "Minotaur Archer", "Minotaur Mage" } +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.MarkwinGreeting) < 1 then + npcHandler:setMessage(MESSAGE_GREET, "Intruder! Guards, take him down!") + player:setStorageValue(Storage.MarkwinGreeting, 1) + local position + for x = -1, 1 do + for y = -1, 1 do + position = Position(32418 + x, 32147 + y, 15) + Game.createMonster(guards[math.random(3)], position) + position:sendMagicEffect(CONST_ME_TELEPORT) + end + end + return false + elseif player:getStorageValue(Storage.MarkwinGreeting) == 1 then + npcHandler:setMessage(MESSAGE_GREET, "Well ... you defeated my guards! Now everything is over! I guess I will have to answer your questions now.") + player:setStorageValue(Storage.MarkwinGreeting, 2) + elseif player:getStorageValue(Storage.MarkwinGreeting) == 2 then + npcHandler:setMessage(MESSAGE_GREET, "Oh its you again. What du you want, hornless messenger?") + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "letter") then + if player:getStorageValue(Storage.Postman.Mission10) == 1 then + if player:getItemCount(2333) > 0 then + npcHandler:say("A letter from my Moohmy?? Do you have a letter from my Moohmy to me?", cid) + npcHandler.topic[cid] = 1 + end + end + elseif msgcontains(msg, 'cookie') then + if player:getStorageValue(Storage.WhatAFoolish.Questline) == 31 + and player:getStorageValue(Storage.WhatAFoolish.CookieDelivery.Markwin) ~= 1 then + npcHandler:say('You bring me ... a cookie???', cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Uhm, well thank you, hornless being.", cid) + player:setStorageValue(Storage.Postman.Mission10, 2) + player:removeItem(2333, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + if not player:removeItem(8111, 1) then + npcHandler:say('You have no cookie that I\'d like.', cid) + npcHandler.topic[cid] = 0 + return true + end + + player:setStorageValue(Storage.WhatAFoolish.CookieDelivery.Markwin, 1) + if player:getCookiesDelivered() == 10 then + player:addAchievement('Allow Cookies?') + end + + Npc():getPosition():sendMagicEffect(CONST_ME_GIFT_WRAPS) + npcHandler:say('I understand this as a peace-offering, human ... UNGH ... THIS IS AN OUTRAGE! THIS MEANS WAR!!!', cid) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + elseif msgcontains(msg, "bye") then + npcHandler:say("Hm ... good bye.", cid) + player:addCondition(condition) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/marlene.lua b/data/npc/scripts/marlene.lua new file mode 100644 index 00000000000..7bb62cec556 --- /dev/null +++ b/data/npc/scripts/marlene.lua @@ -0,0 +1,62 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "My name is Marlene."}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I'm Bruno's wife. Besides: Have you already heard the latest news about the seamonster, Aneus, or the rumours in this area?"}) +keywordHandler:addKeyword({'bruno'}, StdModule.say, {npcHandler = npcHandler, text = "Bruno is a wonderful husband. But he is seldom at home. *looks a little bit sad*"}) +keywordHandler:addKeyword({'graubart'}, StdModule.say, {npcHandler = npcHandler, text = "Ah, old Graubart. A very nice person. But he is strange. He always is busy when I want to talk to him. *lost in thoughts*"}) +keywordHandler:addKeyword({'thank you'}, StdModule.say, {npcHandler = npcHandler, text = "My pleasure, I always enjoy sharing interesting stories."}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + elseif msgcontains(msg, "seamonster") then + npcHandler:say({ + 'Only some days ago I was at the docks late in the night and was looking for my husband\'s ship when suddenly a known noise appeared near the docks. ...', + 'I know this noise very well because it is the noise of a ship sailing very fast. I searched the horizon in hope to see my husbands ship. ...', + 'But instead of a ship I saw a huge shape far away. It was like a big snake swimming in the sea. ...', + 'I couldn\'t see it clearly because of the fog but I think I saw two lava-red eyes glowing in the nightly fog. ...', + 'I ran into the house and hoped that my husband would arrive safely from fishing. And after one hour he finally arrived. ...', + 'I told him about what I saw but he didn\'t believe me because he never saw anything like that in all the years before. But you believe me right? Go and convince yourself. ...', + 'Just go to the docks at exactly midnight and be very quiet. Look at the horizon and maybe you will hear and see it, too!' + }, cid) + elseif msgcontains(msg, "aneus") then + npcHandler:say({ + 'A very nice person. He has a great story to tell with big fights and much magic. Just ask him for his story. ...', + 'I heard that he came from far, far away. He must have seen soooo many countries, cities, different races. ...', + 'He must have collected so much wisdom. *sigh* I wish I could also travel around the world. ...', + 'I would try to visit as many cities and meet as many beings as possible. Who knows what strange races I will meet? ...', + 'Maybe I can also find a lovely new dress for me. I have been looking for one for months now but never found a good one. Maybe... *keeps on babbling*' + }, cid) + elseif msgcontains(msg, "rumours") then + npcHandler:say({ + 'Well, I heard about evil beings living in a dungeon below us. So once I tried to find them and went down the hole far to the southwest. ...', + 'I\'m pretty curious, you know. *smiles* So I took the coat of invisibility from my husband and went down there. At first I only found some spiders, snakes, and wolves. ...', + 'But after some time I found a ladder to a deeper level of the dungeon but I didn\'t dare to go down there because I heard many voices. ...', + 'The voices were very strange and I ran back to my house because they were very loud and very angry. I hope they will never get the idea to attack the surface beings. ...', + 'I heard they are almighty and have incredible powers! I already packed our stuff for an emergency escape. You never know. Maybe they plan to conquer the whole world. ...', + 'I bet that they look very ugly. Most mighty monsters look very ugly. Hmm, you seem to be very strong. Maybe you can go deeper and explore the area. But be careful, please. ...', + 'I heard that they can kill humans with only one hit! And that they have magic abilities twenty times stronger than the mightiest sorcerer in our world.' + }, cid) + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "Ahhh, welcome |PLAYERNAME|! Say, have you already heard the latest news about the {seamonster}, {Aneus}, or the {rumours} in this area?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye and come again for another small talk! *waves*") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/maro.lua b/data/npc/scripts/maro.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/maro.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/marvik.lua b/data/npc/scripts/marvik.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/marvik.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/marvin.lua b/data/npc/scripts/marvin.lua new file mode 100644 index 00000000000..49b1918aaf0 --- /dev/null +++ b/data/npc/scripts/marvin.lua @@ -0,0 +1,52 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function creatureSayCallback(cid, type, msg) + if(not(npcHandler:isFocused(cid))) then + return false + end + + local player = Player(cid) + if(msgcontains(msg, "funding")) then + if(player:setStorageValue(Storage.DarkTrails.Mission07) == 1) then + selfSay("So far you earned x votes. Each single vote can be spent on a different topic or you're also able to cast all your votes on one voting. ...", cid) + selfSay("Well in the topic b you have the possibility to vote for the funding of the {archives}, import of bug {milk} or street {repairs}.", cid) + npcHandler.topic[cid] = 1 + else selfSay("You cant vote yet.", cid) + end + elseif(msgcontains(msg, "archives")) then + if(npcHandler.topic[cid] == 1) then + npcHandler:say("How many of your x votes do you want to cast?", cid) + npcHandler.topic[cid] = 2 + end + elseif(msgcontains(msg, "1")) then + if(npcHandler.topic[cid] == 2) then + npcHandler:say("Did I get that right: You want to cast 1 of your votes on funding the {archives?}", cid) + npcHandler.topic[cid] = 3 + end + elseif(msgcontains(msg, "yes")) then + if(npcHandler.topic[cid] == 3) then + player:setStorageValue(Storage.DarkTrails.Mission08, 1) + npcHandler:say("Thanks, you successfully cast your vote. Feel free to continue gathering votes by helping the city! Farewell.", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/maryza.lua b/data/npc/scripts/maryza.lua new file mode 100644 index 00000000000..24a68ab588e --- /dev/null +++ b/data/npc/scripts/maryza.lua @@ -0,0 +1,58 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, 'cookbook') then + if player:getStorageValue(Storage.MaryzaCookbook) ~= 1 then + npcHandler:say('The cookbook of the famous dwarven kitchen. You\'re lucky. I have a few copies on sale. Do you like one for 150 gold?', cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say('I\'m sorry but I sell only one copy to each customer. Otherwise they would have been sold out a long time ago.', cid) + end + + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, 'yes') then + if not player:removeMoneyNpc(150) then + npcHandler:say('No gold, no sale, that\'s it.', cid) + return true + end + + npcHandler:say('Here you are. Happy cooking!', cid) + player:setStorageValue(Storage.MaryzaCookbook, 1) + player:addItem(2347, 1) + elseif msgcontains(msg, 'no') then + npcHandler:say('I have but a few copies, anyway.', cid) + end + end + return true +end + +-- Greeting message +keywordHandler:addGreetKeyword({"maryza"}, {npcHandler = npcHandler, text = "Welcome to the Jolly Axeman, |PLAYERNAME|. Have a good time and eat some food!"}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome to the Jolly Axeman, |PLAYERNAME|. Have a good time and eat some food!') +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye!") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/maun.lua b/data/npc/scripts/maun.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/maun.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/mazarius.lua b/data/npc/scripts/mazarius.lua new file mode 100644 index 00000000000..c8f2592c90b --- /dev/null +++ b/data/npc/scripts/mazarius.lua @@ -0,0 +1,116 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "brings") then + npcHandler:say("Ah, you have heard about my search for experienced help. And indeed your reputation for solving certain {problems} has preceded you.", cid) + elseif msgcontains(msg, "problems") then + npcHandler:say(" My problems are, so to say, dire news for the whole world. I don't want to confuse you with overly complicated and lengthy stories, so do you want to hear the {long} version or the {short}?", cid) + elseif msgcontains(msg, "long") then + npcHandler:say("He obviously had taken an interest to the topic of ascension, and I came into possession of some of his early writings. ...You have to know I'm a scholar of some renown. In the course of my latest studies about ascension, I stumbled upon disturbing facts about the person of the all to well known Ferumbras, the fiendish. ...", cid) + npcHandler:say("This, combined with investigation and divination, bit by bit led to the conclusion that all that Ferumbras has done in the past may be part of a cunning plan. ...", cid) + npcHandler:say("Considering his writings and the books he based them upon, it became clear that Ferumbras is planning his ascension to godlike status. ...", cid) + npcHandler:say("All of his attacks and defeats only served one purpose: to become an integral part of the people's knowledge, fears and beliefs. ...", cid) + npcHandler:say("He actually used this as an energy source, and combined it with some sources of power which might not all be of our own world. ...", cid) + npcHandler:say("He uses this energy to increasingly empower himself and will eventually be prepared to take the final step to transform himself into a godlike being. ...", cid) + npcHandler:say("With the knowledge what to look for, I acquired expensive but powerful artefacts to scry the world for the expected power signature - and indeed I made contact. ...", cid) + npcHandler:say("To my horror I had to recognise that Ferumbras had already made significant progress, and his final bid for ascension is imminent! ...", cid) + npcHandler:say("His power levels are already too high for there to be any hope of stopping him with conventional means. ...", cid) + npcHandler:say("But not all is lost yet. During my studies about godhood, I learned that the dark Zathroth himself had created a weapon so powerful that it could actually slay a god. ...", cid) + npcHandler:say("Yet even he deemed this so-called '{godbreaker}' too dangerous, and split it into seven parts. These were at some point entrusted to his powerful minions, known as the Ruthless Seven. ...", cid) + npcHandler:say("Ancient, forbidden texts hinted at a hellish place where the seven built deadly dungeons, and placed some of their most fearsome and terrible minions as guards, before they sealed the place off. ...", cid) + npcHandler:say("I'm confident that I can prepare a matching ritual that will breach their protection and allow someone to enter their realm; but I'm in no way suited to handle the horrors to be encountered there. ...", cid) + npcHandler:say("Therefore I have to ask you, if you are willing to retrieve the parts of the godbreaker, and face the threat of the ascending Ferumbras?", cid) + elseif msgcontains(msg, "short") then + npcHandler:say("My studies indicate that without all doubt Ferumbras the fiendish is in the process of accumulating nearly godlike powers. We have to stop him. ...", cid) + npcHandler:say("Therefore I need you to enter a hellish dimension and acquire the parts of a weapon, the {godbreaker}, powerful enough to stop him once and for all. Are you willing to help me in this dire mission?", cid) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 2 and player:getStorageValue(Storage.FerumbrasAscension.Access) < 1 then + npcHandler:say("Good!, but I need 30 {demonic essences} to exchange with the demonic messenger for a ticket for you to enter the Abodes of Torments.", cid) + elseif msgcontains(msg, "demonic essence") or msgcontains(msg, "essence") then + npcHandler:say("Do you have 30 demonic essences to offer to the demonic messenger?", cid) + npcHandler.topic[cid] = 3 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 3 then + if player:removeItem(6500, 30) then + npcHandler:say("Excellent! This will empower possibilty to create a breach is enough to let you pass into that hellish hiding place. ...", cid) + player:addItem(24838, 1) + player:setStorageValue(Storage.FerumbrasAscension.Access, 1) + else + npcHandler:say("You don\'t have the demonic essences, back here when you get it.", cid) + npcHandler:releaseFocus(cid) + end + elseif msgcontains(msg, "godbreaker") then + npcHandler:say("For a long time, I thought the godbreaker to be some apocryphal myth. But apparently others had learned about the godbreaker in the aeons past and lusted for its power. ...", cid) + npcHandler:say("They had gathered hint after hint - until, ultimately, they were squashed by the Seven or their minions; which only made the leads that hinted at them all the more probable. ...", cid) + npcHandler:say("What Zathroth hoped to accomplish with the creation of such a weapon can only be subject to speculation. Assumedly he already had slain Tibiasula, so the godbreaker might have been even more powerful, more absolute. ...", cid) + npcHandler:say("However, it has to be assumed that in the end the sheer power of his creation scared Zathroth, who had to fear the weapon could one day be used against him. So he disassembled it. ...", cid) + npcHandler:say("He kept the parts hidden and guarded, and if the resources can be trusted and my interpretation is right, moved them again and again, never satisfied with a hiding place. In the end he entrusted the parts to the {Ruthless Seven}. ...", cid) + npcHandler:say("Knowing that they would never, ever allow one of their own to come in possession of all parts. Since then, the parts have been hidden in a {demi-plane} shared by the Seven.", cid) + npcHandler:say("Well, I need 30 {demonic essences} to change for a passage to you can access", cid) + elseif msgcontains(msg, "Ruthless Seven") or msgcontains(msg, "ruthless seven") then + npcHandler:say("Given the internal power plays amongst the Seven, they are the ideal keepers for individual parts of an powerful artefact. Not one of them would allow his compatriots to hold such a power, and neither would trust the other.", cid) + elseif msgcontains(msg, "demi-plane") then + npcHandler:say("It is a place, so to say, not completely of this world. It is separate of, yet strongly connected to, our own world. I would imagine it is quite limited in size and its laws of physics and magic should be roughly the same as ours. ...", cid) + npcHandler:say("Being home to a host of demons for a while, I expect it to be an hostile and dangerous environment.", cid) + elseif msgcontains(msg, "ascension") then + npcHandler:say("Ascension is a fascinating topic that dates back to efforts and philosophies of some of the most ancient, and mostly extinct, races which fought in the godwars. ...", cid) + npcHandler:say("Probably born out of desperation, they extensively researched ways to acquire godhood themselves. ...", cid) + npcHandler:say("Some of them at least even met with moderate success. But the process is complicated at best, and may vary from race to race or even from one individual to another. ...", cid) + npcHandler:say("The theories differ vastly and waxed and waned in popularity over the centuries if not aeons. Even today and in human society there are a number of obscure ascension cults. ...", cid) + npcHandler:say("Some of them claim that humans are most suitable for ascension because they already own a bit of divinity through Banor's godly spark.", cid) + elseif msgcontains(msg, "ferumbras") then + npcHandler:say("Although already powerful in his own right, it is obvious that his ultimate goal seems to be the ascension to godly powers. ...", cid) + npcHandler:say("His whole existence seems to be centred on becoming a name that strikes fear into the heart of men and to become a persistent figure in the minds of humanity. ...", cid) + npcHandler:say("This gives him a hold in reality and a kind of mould to fill with his power and conscience. It's also obvious that this kind of belief of the people alone won't be enough to empower him sufficiently. ...", cid) + npcHandler:say("Therefore he has to tap into other, probably even more sinister power sources. I can't tell what these sources are, but my scrying revealed that he has reached massive amounts of power. He has probably been infusing himself since years. ...", cid) + npcHandler:say("By now he is apparently reaching the end circle of his ascension and could make his final move any day.", cid) + elseif msgcontains(msg, "bozarn") then + npcHandler:say("Ah, a good man and a competent aid.", cid) + elseif msgcontains(msg, "darashia") then + npcHandler:say("I like the quietness and the climate. And admittedly it helped my studies not to be constantly disturbed by petitioners.", cid) + elseif msgcontains(msg, "thais") then + npcHandler:say("Thais has become a melting pot of some source. Yet whatever you melt, if the ingredients are corrupted, the outcome is always flawed.", cid) + elseif msgcontains(msg, "carlin") then + npcHandler:say("Instead of banding together and starting to change something, they and Thais keep wasting resources in hostilities.", cid) + elseif msgcontains(msg, "kazordoon") then + npcHandler:say("The dwarves are leftovers from a time long gone by. They have outlived their usefulness to the gods and seem to have come to terms with that. ...", cid) + npcHandler:say("They are as unchanging as rock and no greatness awaits them any more. They missed their chance, if they ever had any.", cid) + elseif msgcontains(msg, "ab\'dendriel") then + npcHandler:say("The elves are like lost children. Their potential might be great, but they lack focus and dedication to truly improve. If their myths are true, some of the more early elves might have accomplished ascension. ...", cid) + npcHandler:say("Yet even if hints strongly suggest those stories are true, the sheer inaction of those assumedly ascended beings is disturbing. Perhaps what those legendary elves achieved was something completely different.", cid) + elseif msgcontains(msg, "edron") then + npcHandler:say("Edron has become as stagnant as the teachings in its academy. No new idea has been thought there for decades. The whole Edron is an example for what happens when humanity has become fat and lazy.", cid) + elseif msgcontains(msg, "demons") then + npcHandler:say("With all their powers and vast magic knowledge they are still more pawns than anything else. Given their resources, ascension might seem within reach. ...", cid) + npcHandler:say("The absence of any ascendant demon might prove that they are no true beings at all and literally damned to be stuck in their accursed forms.", cid) + elseif msgcontains(msg, "venore") then + npcHandler:say("An almost laughable greed is persistent in that city. At least this makes knowledge and materials conveniently available to those who can match their prizes.", cid) + else + npcHandler:say("What?!", cid) + end + +end +npcHandler:setMessage(MESSAGE_GREET, "Greetings, dear visitor. Please tell me what {brings} you here, to my humble adobe.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Oh well.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/mehkesh.lua b/data/npc/scripts/mehkesh.lua new file mode 100644 index 00000000000..0ee59d8998e --- /dev/null +++ b/data/npc/scripts/mehkesh.lua @@ -0,0 +1,25 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Potions brewed by the leading alchemists of the land!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "Be mourned, |PLAYERNAME|, pilgrim in flesh. If you are looking for potions, seek no further.") +npcHandler:setMessage(MESSAGE_FAREWELL, "May enlightenment be your path, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "May enlightenment be your path, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Sure.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/melchior.lua b/data/npc/scripts/melchior.lua new file mode 100644 index 00000000000..e5e4280534f --- /dev/null +++ b/data/npc/scripts/melchior.lua @@ -0,0 +1,53 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + npcHandler:setMessage(MESSAGE_GREET, Player(cid):getSex() == PLAYERSEX_FEMALE and 'Welcome, |PLAYERNAME|! The lovely sound of your voice shines like a beam of light through my solitary darkness!' or 'Greetings, |PLAYERNAME|. I do not see your face, but I can read a thousand things in your voice!') + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'greeting') then + if player:getStorageValue(Storage.DjinnWar.Faction.Greeting) ~= 0 then + npcHandler:say({ + 'The djinns have an ancient code of honour. This code includes a special concept of hospitality. Anybody who utters the word of greeting must not be attacked even if he is an enemy. Well, at least that is what the code says. ...', + 'I have found out, though, that this does not work at all times. There is no point to say the word of greeting to an enraged djinn. ...', + 'I can tell you the word of greeting if you\'re interested. It is {DJANNI\'HAH}. Remember this word well, stranger. It might save your life one day. ...', + 'And keep in mind that you must choose sides in this conflict. You can only follow the Efreet or the Marid - once you have made your choice there is no way back. I know from experience that djinn do not tolerate double-crossing.' + }, cid) + + if player:getStorageValue(Storage.Factions) ~= 1 then + player:setStorageValue(Storage.Factions, 1) + end + player:setStorageValue(Storage.DjinnWar.Faction.Greeting, 1) + end + end + + return true +end + +npcHandler:setMessage(MESSAGE_FAREWELL, 'Farewell, stranger. May Uman the Wise guide your steps in this treacherous land.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Farewell, stranger. May Uman the Wise guide your steps in this treacherous land.') + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/melfar.lua b/data/npc/scripts/melfar.lua new file mode 100644 index 00000000000..0cf86298d85 --- /dev/null +++ b/data/npc/scripts/melfar.lua @@ -0,0 +1,93 @@ + +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local config = { + {position = Position(32474, 31947, 7), type = 2, description = 'Tree 1'}, + {position = Position(32515, 31927, 7), type = 2, description = 'Tree 2'}, + {position = Position(32458, 31997, 7), type = 2, description = 'Tree 3'} +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if(msgcontains(msg, "mission")) then + if(player:getStorageValue(Storage.TheNewFrontier.Questline) == 4) then + npcHandler:say({ + "Ha! Men and wood you say? Well, I might be able to relocate some of our miners to the base. Acquiring wood is an entirely different matter though. ... ", + "I can't spare any men for woodcutting right now but I have an unusual idea that might help. ... ", + "As you might know, this area is troubled by giant beavers. Once a year, the miners decide to have some fun, so they lure the beavers and jump on them to have some sort of rodeo. ... ", + "However, I happen to have some beaver bait left from the last year's competition. ... ", + "If you place it on trees on some strategic locations, we could let the beavers do the work and later on, I'll send men to get the fallen trees. ... ", + "Does this sound like something you can handle? " + }, cid) + npcHandler.topic[cid] = 1 + elseif(player:getStorageValue(Storage.TheNewFrontier.Questline) == 6) then + npcHandler:say("Yes, I can hear them even from here. It has to be a legion of beavers! I'll send the men to get the wood as soon as their gnawing frenzy has settled! You can report to Ongulf that men and wood will be on their way!", cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 7) + player:setStorageValue(Storage.TheNewFrontier.Mission02, 6) --Questlog, The New Frontier Quest "Mission 02: From Kazordoon With Love" + end + elseif(msgcontains(msg, "yes")) then + if(npcHandler.topic[cid] == 1) then + npcHandler:say({ + "So take this beaver bait. It will work best on dwarf trees. I'll mark the three trees on your map. Here .. here .. and here! So now mark those trees with the beaver bait. ... ", + "If you're unlucky enough to meet one of the giant beavers, try to stay calm. Don't do any hectic moves, don't yell, don't draw any weapon, and if you should carry anything wooden on you, throw it away as far as you can. " + }, cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 5) + player:setStorageValue(Storage.TheNewFrontier.Mission02, 2) --Questlog, The New Frontier Quest "Mission 02: From Kazordoon With Love" + player:addItem(11100, 1) + for i = 1, #config do + player:addMapMark(config[i].position, config[i].type, config[i].description) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + if player:removeMoneyNpc(100) then + player:addItem(11100, 1) + npcHandler:say("Here you go.", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You dont have enough of gold coins.", cid) + npcHandler.topic[cid] = 0 + end + end + elseif msgcontains(msg, "buy flask") or msgcontains(msg, "flask") then + if player:getStorageValue(Storage.TheNewFrontier.Questline) == 5 then + npcHandler:say("You want to buy a Flask with Beaver Bait for 100 gold coins?", cid) + npcHandler.topic[cid] = 2 + else + npcHandler:say("Im out of stock.", cid) + end + end + return true +end + +local shopModule = ShopModule:new() +npcHandler:addModule(shopModule) + +shopModule:addBuyableItem({'Broken Crossbow'}, 12407, 30) +shopModule:addBuyableItem({'Minotaur Horn'}, 12428, 75) +shopModule:addBuyableItem({'Piece of Archer Armor'}, 12439, 20) +shopModule:addBuyableItem({'Piece of Warrior Armor'}, 12438, 50) +shopModule:addBuyableItem({'Purple Robe'}, 12429, 110) + +shopModule:addSellableItem({'Flask with Beaver Bait'}, 11100, 100) + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/melian.lua b/data/npc/scripts/melian.lua new file mode 100644 index 00000000000..c05650a5888 --- /dev/null +++ b/data/npc/scripts/melian.lua @@ -0,0 +1,37 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Travel +local function addTravelKeyword(keyword, text, cost, destination) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a ride to ' .. text .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'You shouldn\'t miss the experience.', reset = true}) +end + +addTravelKeyword('darashia', 'Darashia on Darama', 60, Position(33270, 32441, 6)) +addTravelKeyword('svargrond', 'Svargrond', 60, Position(32253, 31097, 4)) +addTravelKeyword('femor hills', 'the Femor Hills', 60, Position(32536, 31837, 4)) +addTravelKeyword('edron', 'Edron', 60, Position(33193, 31784, 3)) +addTravelKeyword('kazordoon', 'Kazordoon', 70, Position(32588, 31941, 0)) +addTravelKeyword('hills', 'the Femor Hills', 60, Position(32536, 31837, 4)) +addTravelKeyword('issavi', 'Issavi', 100, Position(33957, 31515, 0)) + +npcHandler:setMessage(MESSAGE_GREET, "Ah, the wind brings in another visitor. Feel welcome |PLAYERNAME|. Where do you want me to {fly} you?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Daraman's blessings!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Daraman's blessings!") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/memech.lua b/data/npc/scripts/memech.lua new file mode 100644 index 00000000000..55ac05e91f9 --- /dev/null +++ b/data/npc/scripts/memech.lua @@ -0,0 +1,24 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Selling weapons and armors to protect mortal souls.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "Be mourned, |PLAYERNAME|, pilgrim in flesh. Have a look at my fine {weapons} and {armors}.") +npcHandler:setMessage(MESSAGE_FAREWELL, "May enlightenment be your path, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "May enlightenment be your path.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/menacing_mummy.lua b/data/npc/scripts/menacing_mummy.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/menacing_mummy.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/menesto.lua b/data/npc/scripts/menesto.lua new file mode 100644 index 00000000000..06b1299a681 --- /dev/null +++ b/data/npc/scripts/menesto.lua @@ -0,0 +1,63 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.Tutorial) < 1 then + npcHandler:say( + { + "Finally, reinforcements - oh but no, you came through the crystal portal, like the others! \z + I am ser Menesto, I guard the portal. That beast caught me by surprise, I lost my dagger and had to retreat. ...", + "... ...", + "Hmm. ...", + "You look hungry, you should eat regularly to reagain your strength! \z + See what you can find while hunting. Or buy food in a city shop. \z + Here, have some of my rations, I'll take my dagger. Tell me when you're {ready}." + }, + cid, false, true, 10) + player:addItem(2666, 1) + player:setStorageValue(Storage.Dawnport.Tutorial, 1) + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "ready") then + if player:getStorageValue(Storage.Dawnport.Tutorial) == 1 then + npcHandler:say( + { + "I'll stay here till reinforcements come. Go up the ladder to reach the surface. \z + You'll need a rope for the ropestot that comes after the ladder - here, take my spare equipment. ...", + "And remember: Tibia is a world with many dangers and mysteries, so be careful! Farewell, friend." + }, + cid, false, true, 10) + player:setStorageValue(Storage.Dawnport.Tutorial, 2) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/meraya.lua b/data/npc/scripts/meraya.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/meraya.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/messenger_of_heaven.lua b/data/npc/scripts/messenger_of_heaven.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/messenger_of_heaven.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/messenger_of_santa.lua b/data/npc/scripts/messenger_of_santa.lua new file mode 100644 index 00000000000..e88e935b7eb --- /dev/null +++ b/data/npc/scripts/messenger_of_santa.lua @@ -0,0 +1,20 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/miles_the_guard.lua b/data/npc/scripts/miles_the_guard.lua new file mode 100644 index 00000000000..d9aca92cc28 --- /dev/null +++ b/data/npc/scripts/miles_the_guard.lua @@ -0,0 +1,51 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "trouble") and npcHandler.topic[cid] ~= 3 and player:getStorageValue(Storage.TheInquisition.MilesGuard) < 1 and player:getStorageValue(Storage.TheInquisition.Mission01) ~= -1 then + npcHandler:say("I'm fine. There's no trouble at all.", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "foresight of the authorities") and npcHandler.topic[cid] == 1 then + npcHandler:say("Well, of course. We live in safety and peace.", cid) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, "also for the gods") and npcHandler.topic[cid] == 2 then + npcHandler:say("I think the gods are looking after us and their hands shield us from evil.", cid) + npcHandler.topic[cid] = 3 + elseif msgcontains(msg, "trouble will arise in the near future") and npcHandler.topic[cid] == 3 then + npcHandler:say("I think the gods and the government do their best to keep away harm from the citizens.", cid) + npcHandler.topic[cid] = 0 + if player:getStorageValue(Storage.TheInquisition.MilesGuard) < 1 then + player:setStorageValue(Storage.TheInquisition.MilesGuard, 1) + player:setStorageValue(Storage.TheInquisition.Mission01, player:getStorageValue(Storage.TheInquisition.Mission01) + 1) -- The Inquisition Questlog- "Mission 1: Interrogation" + player:getPosition():sendMagicEffect(CONST_ME_HOLYAREA) + end + end + return true +end + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "It's my duty to protect the city."}) + +npcHandler:setMessage(MESSAGE_GREET, "LONG LIVE THE KING!") +npcHandler:setMessage(MESSAGE_FAREWELL, "LONG LIVE THE KING!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "LONG LIVE THE KING!") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/milos.lua b/data/npc/scripts/milos.lua new file mode 100644 index 00000000000..c9805adad08 --- /dev/null +++ b/data/npc/scripts/milos.lua @@ -0,0 +1,22 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'What a fascinating idea!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "Oh hello. I hardly noticed you. I'm afraid I am a bit distracted at the moment.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/mirabell.lua b/data/npc/scripts/mirabell.lua new file mode 100644 index 00000000000..74f3bad3116 --- /dev/null +++ b/data/npc/scripts/mirabell.lua @@ -0,0 +1,87 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'The Horn of Plenty is always open for tired adventurers.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, 'pies') then + if player:getStorageValue(Storage.WhatAFoolish.PieBuying) == -1 then + npcHandler:say('Oh you\'ve heard about my excellent pies, didn\'t you? I am flattered. Unfortunately I\'m completely out of flour. I need 2 portions of flour for one pie. Just tell me when you have enough flour for your pies.', cid) + return true + end + + npcHandler:say('For 12 pies this is 240 gold. Do you want to buy them?', cid) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, 'flour') then + npcHandler:say('Do you bring me the flour needed for your pies?', cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + if not player:removeItem(2692, 24) then + npcHandler:say('I think you are confusing the dust in your pockets with flour. You certainly do not have enough flour for 12 pies.', cid) + npcHandler.topic[cid] = 0 + return true + end + + player:setStorageValue(Storage.WhatAFoolish.PieBuying, player:getStorageValue(Storage.WhatAFoolish.PieBuying) + 1) + npcHandler:say('Excellent. Now I can start baking the pies. As you helped me, I will make you a good price for them.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + if not player:removeMoneyNpc(240) then + npcHandler:say('You don\'t have enough money, don\'t try to fool me.', cid) + npcHandler.topic[cid] = 0 + return true + end + + player:addItem(7484, 1) + player:setStorageValue(Storage.WhatAFoolish.PieBuying, player:getStorageValue(Storage.WhatAFoolish.PieBuying) - 1) + player:setStorageValue(Storage.WhatAFoolish.PieBoxTimer, os.time() + 1200) -- 20 minutes to deliver + npcHandler:say({ + 'Here they are. Wait! Two things you should know: Firstly, they won\'t last long in the sun so you better get them to their destination as quickly as possible ...', + 'Secondly, since my pies are that delicious it is forbidden to leave the town with them. We can\'t afford to attract more tourists to Edron.' + }, cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'no') then + if npcHandler.topic[cid] == 1 then + npcHandler:say('Without flour I can\'t do anything, sorry.', cid) + elseif npcHandler.topic[cid] == 2 then + npcHandler:say('What are you? Some kind of fool?', cid) + end + npcHandler.topic[cid] = 0 + end + + return true +end + +keywordHandler:addKeyword({'drink'}, StdModule.say, {npcHandler = npcHandler, text = 'I can offer you beer, wine, lemonade and water. If you\'d like to see my offers, ask me for a {trade}.'}) +keywordHandler:addKeyword({'food'}, StdModule.say, {npcHandler = npcHandler, text = 'Are you looking for food? I have bread, cheese, ham, and meat. If you\'d like to see my offers, ask me for a {trade}.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome to the Horn of Plenty, |PLAYERNAME|. Sit down, have a {drink} or some {food}!") +npcHandler:setMessage(MESSAGE_FAREWELL, "Come back soon, traveller.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Come back soon, traveller.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Of course, take a look at my tasty offers.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/miraia.lua b/data/npc/scripts/miraia.lua new file mode 100644 index 00000000000..581de04c532 --- /dev/null +++ b/data/npc/scripts/miraia.lua @@ -0,0 +1,157 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local message = {} + +local config = { + ['ape fur'] = { + itemId = 5883, + count = 100, + storageValue = 1, + text = { + 'Have you really managed to fulfil the task and brought me 100 pieces of ape fur?', + 'Only ape fur is good enough to touch the feet of our Caliph.', + 'Ahhh, this softness! I\'m impressed, |PLAYERNAME|. You\'re on the best way to earn that turban. Now, please retrieve 100 fish fins.' + } + }, + ['fish fins'] = { + itemId = 5895, + count = 100, + storageValue = 2, + text = { + 'Were you able to discover the undersea race and retrieved 100 fish fins?', + 'I really wonder what the explorer society is up to. Actually I have no idea how they managed to dive unterwater.', + 'I never thought you\'d make it, |PLAYERNAME|. Now we only need two enchanted chicken wings to start our waterwalking test!' + } + }, + ['enchanted chicken wings'] = { + itemId = 5891, + count = 2, + storageValue = 3, + text = { + 'Were you able to get hold of two enchanted chicken wings?', + 'Enchanted chicken wings are actually used to make boots of haste, so they could be magically extracted again. Djinns are said to be good at that.', + 'Great, thank you very much. Just bring me 100 pieces of blue cloth now and I will happily show you how to make a turban.' + } + }, + ['blue cloth'] = { + itemId = 5912, + count = 100, + storageValue = 4, + text = { + 'Ah, have you brought the 100 pieces of blue cloth?', + 'It\'s a great material for turbans.', + 'Ah! Congratulations - I hope this veil will turn out as beautiful as you are. Here, I\'ll do it for you.' + } + } +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, 'outfit') then + npcHandler:say(player:getSex() == PLAYERSEX_FEMALE and 'Hehe, would you like to wear a pretty veil like I do? Well... I could help you, but you would have to complete a task first.' or 'My veil? No, I will definitely not lift it for you! If you are looking for an addon, go talk to Razan.', cid) + elseif msgcontains(msg, 'task') then + if player:getSex() == PLAYERSEX_MALE then + npcHandler:say('Uh... I don\'t think that I have work for you right now. If you need a job, go talk to Razan.', cid) + return true + end + if player:getStorageValue(Storage.OutfitQuest.secondOrientalAddon) < 1 then + npcHandler:say('You mean, you would like to prove that you deserve to wear such a veil?', cid) + npcHandler.topic[cid] = 1 + end + elseif config[msg] and npcHandler.topic[cid] == 0 then + if player:getStorageValue(Storage.OutfitQuest.secondOrientalAddon) == config[msg].storageValue then + npcHandler:say(config[msg].text[1], cid) + npcHandler.topic[cid] = 3 + message[cid] = msg + else + npcHandler:say(config[msg].text[2], cid) + end + elseif msgcontains(msg, 'scarab cheese') then + if player:getStorageValue(Storage.TravellingTrader.Mission03) == 1 then + npcHandler:say('Let me cover my nose before I get this for you... Would you REALLY like to buy scarab cheese for 100 gold?', cid) + elseif player:getStorageValue(Storage.TravellingTrader.Mission03) == 2 then + npcHandler:say('Oh the last cheese molded? Would you like to buy another one for 100 gold?', cid) + end + npcHandler.topic[cid] = 4 + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + 'Alright, then listen to the following requirements. We are currently in dire need of ape fur since the Caliph has requested a new bathroom carpet. ...', + 'Thus, please bring me 100 pieces of ape fur. Secondly, it came to our ears that the explorer society has discovered a new undersea race of fishmen. ...', + 'Their fins are said to allow humans to walk on water! Please bring us 100 of these fish fin. ...', + 'Third, if the plan of walking on water should fail, we need enchanted chicken wings to prevent the testers from drowning. Please bring me two. ...', + 'Last but not least, just drop by with 100 pieces of blue cloth and I will happily show you how to make a turban. ...', + 'Did you understand everything I told you and are willing to handle this task?' + }, cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + if player:getStorageValue(Storage.OutfitQuest.DefaultStart) ~= 1 then + player:setStorageValue(Storage.OutfitQuest.DefaultStart, 1) + end + player:setStorageValue(Storage.OutfitQuest.secondOrientalAddon, 1) + npcHandler:say('Excellent! Come back to me once you have collected 100 pieces of ape fur.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + local targetMessage = config[message[cid]] + if not player:removeItem(targetMessage.itemId, targetMessage.count) then + npcHandler:say('That is a shameless lie.', cid) + npcHandler.topic[cid] = 0 + return true + end + player:setStorageValue(Storage.OutfitQuest.secondOrientalAddon, player:getStorageValue(Storage.OutfitQuest.secondOrientalAddon) + 1) + if player:getStorageValue(Storage.OutfitQuest.secondOrientalAddon) == 5 then + player:addOutfitAddon(146, 2) + player:addOutfitAddon(150, 2) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + end + npcHandler:say(targetMessage.text[3], cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 4 then + if player:getMoney() + player:getBankBalance() >= 100 then + player:setStorageValue(Storage.TravellingTrader.Mission03, 2) + player:addItem(8112, 1) + player:removeMoneyNpc(100) + npcHandler:say('Here it is.', cid) + else + npcHandler:say('You don\'t have enough money.', cid) + end + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] ~= 0 then + npcHandler:say('What a pity.', cid) + npcHandler.topic[cid] = 0 + end + return true +end + +local function onReleaseFocus(cid) + message[cid] = nil +end + +keywordHandler:addKeyword({'drink'}, StdModule.say, {npcHandler = npcHandler, text = 'I can offer you lemonade, camel milk, and water. If you\'d like to see my offers, ask me for a {trade}.'}) +keywordHandler:addKeyword({'food'}, StdModule.say, {npcHandler = npcHandler, text = 'Are you looking for food? I have bread, cheese, ham, and meat. If you\'d like to see my offers, ask me for a {trade}.'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Daraman\'s blessings, |PLAYERNAME|. Welcome to the Enlightened Oasis. Sit down, have a {drink} or some {food}!') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Daraman\'s blessings. Come back soon.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/moe.lua b/data/npc/scripts/moe.lua new file mode 100644 index 00000000000..7fca17cf61c --- /dev/null +++ b/data/npc/scripts/moe.lua @@ -0,0 +1,86 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local voices = { + {text = "The menu of the day sounds delicious!"}, + {text = "The last visit to the theatre was quite rewarding."}, + {text = "Such a beautiful and wealthy city - with so many opportunities ..."} +} + +keywordHandler:addKeyword( + {"help"}, StdModule.say, { npcHandler = npcHandler, + text = "I guess I could do this, yes. But I have to impose a condition. If you bring me ten sphinx {feathers} I will steal this ring for you."}, + function (player) return player:getStorageValue(Storage.Kilmaresh.Fourth.Moe) == 1 end, + function (player) player:setStorageValue(Storage.Kilmaresh.Fourth.Moe, 2) end +) + +keywordHandler:addKeyword( + {"feathers"}, StdModule.say, { npcHandler = npcHandler, + text = "Thank you! They look so pretty, I'm very pleased. Agreed, now I will steal the ring from the Ambassador of Rathleton. Just be patient, I have to wait for a good moment."}, + function (player) return player:getStorageValue(Storage.Kilmaresh.Fourth.Moe) == 2 and player:getItemById(36272, 10) end, + function (player) + player:removeItem(36272, 10) + player:setStorageValue(Storage.Kilmaresh.Fourth.Moe, 3) + player:setStorageValue(Storage.Kilmaresh.Fourth.MoeTimer, os.time() + 60 * 60 ) -- one hour + end +) + +keywordHandler:addKeyword( + {"feathers"}, StdModule.say, { npcHandler = npcHandler, + text = "If you bring me ten sphinx {feathers} I will steal this ring for you."}, + function (player) return player:getStorageValue(Storage.Kilmaresh.Fourth.Moe) == 2 and not player:getItemById(36272, 10) end +) + +keywordHandler:addKeyword( + {"ring"}, StdModule.say, { npcHandler = npcHandler, + text = "You're arriving at the right time. I have the ring you asked for. It was not too difficult. I just had to wait until the Ambassador left his residence and then I climbed in through the window. Here it is."}, + function (player) + return player:getStorageValue(Storage.Kilmaresh.Fourth.Moe) == 3 and + player:getStorageValue(Storage.Kilmaresh.Fourth.MoeTimer) - os.time() <= 0 + end, + function (player) + player:addItem(36141, 1) + player:setStorageValue(Storage.Kilmaresh.Fourth.Moe, 4) + end +) + +keywordHandler:addKeyword( + {"ring"}, StdModule.say, { npcHandler = npcHandler, + text = "I will steal it, promised. I\'m just waiting for a good moment."}, + function (player) + return player:getStorageValue(Storage.Kilmaresh.Fourth.Moe) == 3 and + player:getStorageValue(Storage.Kilmaresh.Fourth.MoeTimer) - os.time() > 0 + end +) + + +keywordHandler:addKeyword( + {"lyre"}, StdModule.say, { npcHandler = npcHandler, + text = "I'm upset to accuse myself, the lyre is hidden in a tomb west of Kilmaresh."}, + function (player) return player:getStorageValue(Storage.Kilmaresh.Thirteen.Lyre) == 1 end, + function (player) player:setStorageValue(Storage.Kilmaresh.Thirteen.Lyre, 2) end +) + +npcHandler:setMessage(MESSAGE_GREET, "Greetings, traveller. It seems, you're a {guest} here, just like me.") +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(VoiceModule:new(voices)) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/morax.lua b/data/npc/scripts/morax.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/morax.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/mordecai.lua b/data/npc/scripts/mordecai.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/mordecai.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/morgan.lua b/data/npc/scripts/morgan.lua new file mode 100644 index 00000000000..df4ef77fe30 --- /dev/null +++ b/data/npc/scripts/morgan.lua @@ -0,0 +1,139 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'firebird') then + if player:getStorageValue(Storage.OutfitQuest.PirateSabreAddon) == 4 then + player:setStorageValue(Storage.OutfitQuest.PirateSabreAddon, 5) + player:addOutfitAddon(151, 1) + player:addOutfitAddon(155, 1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + npcHandler:say( + 'Ahh. So Duncan sent you, eh? You must have done something really impressive. \ + Okay, take this fine sabre from me, mate.', + cid) + end + elseif msgcontains(msg, 'mission') then + if player:getStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven) == 3 then + npcHandler:say( + { + 'Hm, if you are that eager to work I have an idea how you could help me out. \ + A distant relative of mine, the old sage Eremo lives on the isle Cormaya, near Edron. ...', + "He has not heard from me since ages. He might assume that I am dead. \ + Since I don't want him to get into trouble for receiving a letter from a \ + pirate I ask you to deliver it personally. ...", + "Of course it's a long journey but you asked for it. \ + You will have to prove us your worth. Are you up to that?" + }, + cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven) == 5 then + npcHandler:say('Thank you for delivering my letter to Eremo. I have no more missions for you.', cid) + player:setStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven, 6) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "warrior's sword") then + if player:hasOutfit(player:getSex() == PLAYERSEX_FEMALE and 142 or 134, 2) then + npcHandler:say('You already have this outfit!', cid) + return true + end + + if player:getStorageValue(Storage.OutfitQuest.WarriorSwordAddon) < 1 then + player:setStorageValue(Storage.OutfitQuest.WarriorSwordAddon, 1) + npcHandler:say('Great! Simply bring me 100 iron ore and one royal steel and I will happily {forge} it for you.', cid) + elseif player:getStorageValue(Storage.OutfitQuest.WarriorSwordAddon) == 1 and npcHandler.topic[cid] == 1 then + if player:getItemCount(5887) > 0 and player:getItemCount(5880) > 99 then + player:removeItem(5887, 1) + player:removeItem(5880, 100) + player:addOutfitAddon(134, 2) + player:addOutfitAddon(142, 2) + player:setStorageValue(Storage.OutfitQuest.WarriorSwordAddon, 2) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:addAchievementProgress('Wild Warrior', 2) + npcHandler:say('Alright! As a matter of fact, I have one in store. Here you go!', cid) + else + npcHandler:say('You do not have all the required items.', cid) + end + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "knight's sword") then + if player:hasOutfit(player:getSex() == PLAYERSEX_FEMALE and 139 or 131, 1) then + npcHandler:say('You already have this outfit!', cid) + return true + end + + if player:getStorageValue(Storage.OutfitQuest.Knight.AddonSword) < 1 then + player:setStorageValue(Storage.OutfitQuest.Knight.AddonSword, 1) + npcHandler:say('Great! Simply bring me 100 Iron Ore and one Crude Iron and I will happily {forge} it for you.', cid) + elseif player:getStorageValue(Storage.OutfitQuest.Knight.AddonSword) == 1 and npcHandler.topic[cid] == 1 then + if player:getItemCount(5892) > 0 and player:getItemCount(5880) > 99 then + player:removeItem(5892, 1) + player:removeItem(5880, 100) + player:addOutfitAddon(131, 1) + player:addOutfitAddon(139, 1) + player:setStorageValue(Storage.OutfitQuest.Knight.AddonSword, 2) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + npcHandler:say('Alright! As a matter of fact, I have one in store. Here you go!', cid) + else + npcHandler:say('You do not have all the required items.', cid) + end + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'forge') then + npcHandler:say("What would you like me to forge for you? A {knight's sword} or a {warrior's sword}?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 2 then + if player:getStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven) == 3 then + npcHandler:say('Alright, we will see. Here, take this letter and deliver it safely to old Eremo on Cormaya.', cid) + player:addItem(8188, 1) + player:setStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven, 4) + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +keywordHandler:addKeyword( + {'addon'}, + StdModule.say, + { + npcHandler = npcHandler, + text = 'I can forge the finest {weapons} for knights and warriors. \ + They may wear them proudly and visible to everyone.' + } +) +keywordHandler:addKeyword( + {'weapons'}, + StdModule.say, + { + npcHandler = npcHandler, + text = "Would you rather be interested in a {knight's sword} or in a {warrior's sword}?" + } +) + +npcHandler:setMessage(MESSAGE_GREET, 'Hello there.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/morpel.lua b/data/npc/scripts/morpel.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/morpel.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/mortimer.lua b/data/npc/scripts/mortimer.lua new file mode 100644 index 00000000000..e8704733f81 --- /dev/null +++ b/data/npc/scripts/mortimer.lua @@ -0,0 +1,686 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + -- JOINING + if msgcontains(msg, "join") then + if player:getStorageValue(Storage.ExplorerSociety.JoiningTheExplorers) < 1 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) < 1 then + npcHandler:say("Do you want to join the explorer society?", cid) + npcHandler.topic[cid] = 1 + end + --The New Frontier + elseif msgcontains(msg, "farmine") then + if player:getStorageValue(Storage.TheNewFrontier.Questline) <= 15 + and player:getStorageValue(Storage.TheNewFrontier.BribeExplorerSociety) < 1 then + npcHandler:say("Oh yes, an interesting topic. We had vivid discussions about this discovery. But what is it that you want?", cid) + npcHandler.topic[cid] = 30 + end + elseif msgcontains(msg, "bluff") then + if npcHandler.topic[cid] == 30 then + if player:getStorageValue(Storage.TheNewFrontier.BribeExplorerSociety) < 1 then + npcHandler:say({ + "Those stories are just amazing! Men with faces on their stomach instead of heads you say? And hens that lay golden eggs? Whereas, most amazing is this fountain of youth you've mentioned! ...", + "I'll immediately send some of our most dedicated explorers to check those things out!" + }, cid) + player:setStorageValue(Storage.TheNewFrontier.BribeExplorerSociety, 1) + --Questlog, The New Frontier Quest "Mission 05: Getting Things Busy" + player:setStorageValue(Storage.TheNewFrontier.Mission05, player:getStorageValue(Storage.TheNewFrontier.Mission05) + 1) + end + end + + -- MISSION CHECK + elseif msgcontains(msg, "mission") then + if player:getStorageValue(Storage.ExplorerSociety.JoiningTheExplorers) > 3 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) > 3 + and player:getStorageValue(Storage.ExplorerSociety.ThePlantCollection) < 26 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) < 26 + or player:getStorageValue(Storage.ExplorerSociety.TheIceDelivery) == 7 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 7 + or player:getStorageValue(Storage.ExplorerSociety.TheButterflyHunt) == 16 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 16 + or player:getStorageValue(Storage.ExplorerSociety.JoiningTheExplorers) == 4 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 4 then + npcHandler:say("The missions available for your rank are the {butterfly hunt}, {plant collection} and {ice delivery}.", cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.ExplorerSociety.ThePlantCollection) > 25 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) > 35 + and player:getStorageValue(Storage.ExplorerSociety.TheOrcPowder) < 35 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) < 35 + or player:getStorageValue(Storage.ExplorerSociety.ThePlantCollection) == 26 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 26 + or player:getStorageValue(Storage.ExplorerSociety.TheLizardUrn) == 29 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 29 + or player:getStorageValue(Storage.ExplorerSociety.TheBonelordSecret) == 32 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 32 then + npcHandler:say("The missions available for your rank are {lizard urn}, {bonelord secrets} and {orc powder}.", cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.ExplorerSociety.TheOrcPowder) > 34 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) > 34 + and player:getStorageValue(Storage.ExplorerSociety.TheRuneWritings) < 44 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) < 44 + or player:getStorageValue(Storage.ExplorerSociety.TheOrcPowder) == 35 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 35 + or player:getStorageValue(Storage.ExplorerSociety.TheElvenPoetry) == 38 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 38 + or player:getStorageValue(Storage.ExplorerSociety.TheMemoryStone) == 41 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 41 then + npcHandler:say("The missions available for your rank are {elven poetry}, {memory stone} and {rune writings}.", cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.ExplorerSociety.TheRuneWritings) == 44 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 44 then + npcHandler:say("The explorer society needs a great deal of help in the research of astral travel. Are you willing to help?", cid) + npcHandler.topic[cid] = 27 + elseif player:getStorageValue(Storage.ExplorerSociety.TheEctoplasm) == 46 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 46 then + npcHandler:say("Do you have some collected ectoplasm with you?", cid) + npcHandler.topic[cid] = 29 + elseif player:getStorageValue(Storage.ExplorerSociety.TheEctoplasm) == 47 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 47 then + npcHandler:say({ + "The research on ectoplasm makes good progress. Now we need some spectral article. Our scientists think a spectral dress would be a perfect object for their studies ...", + "The bad news is that the only source to got such a dress is the queen of the banshees. Do you dare to seek her out?" + }, cid) + npcHandler.topic[cid] = 30 + elseif player:getStorageValue(Storage.ExplorerSociety.TheSpectralDress) == 49 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 48 then + npcHandler:say("Did you bring the dress?", cid) + npcHandler.topic[cid] = 31 + -- SPECTRAL STONE + elseif player:getStorageValue(Storage.ExplorerSociety.TheSpectralDress) == 50 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 50 then + npcHandler:say({ + "With the objects you've provided our researchers will make steady progress. Still we are missing some test results from fellow explorers ...", + "Please travel to our base in Port Hope and ask them to mail us their latest research reports. Then return here and ask about new missions." + }, cid) + player:setStorageValue(Storage.ExplorerSociety.TheSpectralStone, 51) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 51) + player:setStorageValue(Storage.ExplorerSociety.SpectralStone, 2) + elseif player:getStorageValue(Storage.ExplorerSociety.TheSpectralStone) == 51 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 51 + and player:getStorageValue(Storage.ExplorerSociety.SpectralStone) == 1 then + npcHandler:say("Oh, yes! Tell our fellow explorer that the papers are in the mail already.", cid) + player:setStorageValue(Storage.ExplorerSociety.TheSpectralStone, 52) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 52) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.ExplorerSociety.TheSpectralStone) == 52 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 52 + and player:getStorageValue(Storage.ExplorerSociety.SpectralStone) == 2 then + npcHandler:say("The reports from Port Hope have already arrived here and our progress is astonishing. We think it is possible to create an astral bridge between our bases. Are you interested to assist us with this?", cid) + npcHandler.topic[cid] = 32 + -- SPECTRAL STONE + -- ASTRAL PORTALS + elseif player:getStorageValue(Storage.ExplorerSociety.TheSpectralStone) == 55 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 55 then + npcHandler:say({ + "Both carvings are now charged and harmonised. In theory you should be able to travel in zero time from one base to the other ...", + "However, you will need to have an orichalcum pearl in your possession to use it as power source. It will be destroyed during the process. I will give you 6 of such pearls and you can buy new ones in our bases ...", + "In addition, you need to be a premium explorer to use the astral travel. ...", + "And remember: it's a small teleport for you, but a big teleport for all Tibians! Here is a small present for your efforts!" + }, cid) + player:setStorageValue(Storage.ExplorerSociety.TheAstralPortals, 56) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 56) + player:addItem(5022, 6) -- orichalcum pearl + player:addItem(10522, 1) -- crown backpack + -- ASTRAL PORTALS + end + -- MISSION CHECK + + -- PICKAXE MISSION + elseif msgcontains(msg, "pickaxe") then + if player:getStorageValue(Storage.ExplorerSociety.JoiningTheExplorers) < 4 + or player:getStorageValue(Storage.ExplorerSociety.JoiningTheExplorers) > 1 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) < 1 + or player:getStorageValue(Storage.ExplorerSociety.QuestLine) > 1 then + npcHandler:say("Did you get the requested pickaxe from Uzgod in Kazordoon?", cid) + npcHandler.topic[cid] = 3 + end + -- PICKAXE MISSION + + -- ICE DELIVERY + elseif msgcontains(msg, "ice delivery") then + if player:getStorageValue(Storage.ExplorerSociety.JoiningTheExplorers) == 4 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 4 then + npcHandler:say({ + "Our finest minds came up with the theory that deep beneath the ice island of Folda ice can be found that is ancient. To prove this theory we would need a sample of the aforesaid ice ...", + "Of course the ice melts away quickly so you would need to hurry to bring it here ...", + "Would you like to accept this mission?" + }, cid) + npcHandler.topic[cid] = 4 + elseif player:getStorageValue(Storage.ExplorerSociety.TheIceDelivery) == 6 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 6 then + npcHandler:say("Did you get the ice we are looking for?", cid) + npcHandler.topic[cid] = 5 + end + -- ICE DELIVERY + + -- BUTTERFLY HUNT + elseif msgcontains(msg, "butterfly hunt") then + if player:getStorageValue(Storage.ExplorerSociety.TheIceDelivery) == 7 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 7 then + npcHandler:say("The mission asks you to collect some species of butterflies, are you interested?", cid) + npcHandler.topic[cid] = 7 + elseif player:getStorageValue(Storage.ExplorerSociety.TheButterflyHunt) == 9 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 9 then + npcHandler:say("Did you acquire the purple butterfly we are looking for?", cid) + npcHandler.topic[cid] = 8 + elseif player:getStorageValue(Storage.ExplorerSociety.TheButterflyHunt) == 10 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 10 then + npcHandler:say({ + "This preparation kit will allow you to collect a blue butterfly you have killed ...", + "Just use it on the fresh corpse of a blue butterfly, return the prepared butterfly to me and give me a report of your butterfly hunt." + }, cid) + npcHandler.topic[cid] = 0 + player:addItem(4865, 1) + player:setStorageValue(Storage.ExplorerSociety.TheButterflyHunt, 11) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 11) + elseif player:getStorageValue(Storage.ExplorerSociety.TheButterflyHunt) == 12 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 12 then + npcHandler:say("Did you acquire the blue butterfly we are looking for?", cid) + npcHandler.topic[cid] = 9 + elseif player:getStorageValue(Storage.ExplorerSociety.TheButterflyHunt) == 13 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 13 then + npcHandler:say({ + "This preparation kit will allow you to collect a red butterfly you have killed ...", + "Just use it on the fresh corpse of a red butterfly, return the prepared butterfly to me and give me a report of your butterfly hunt." + }, cid) + npcHandler.topic[cid] = 0 + player:addItem(4865, 1) + player:setStorageValue(Storage.ExplorerSociety.TheButterflyHunt, 14) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 14) + elseif player:getStorageValue(Storage.ExplorerSociety.TheButterflyHunt) == 15 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 15 then + npcHandler:say("Did you acquire the red butterfly we are looking for?", cid) + npcHandler.topic[cid] = 10 + end + -- BUTTERFLY HUNT + -- PLANT COLLECTION + elseif msgcontains(msg, "plant collection") then + if player:getStorageValue(Storage.ExplorerSociety.TheButterflyHunt) == 16 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 16 then + npcHandler:say("In this mission we require you to get us some plant samples from Tiquandan plants. Would you like to fulfil this mission?", cid) + npcHandler.topic[cid] = 11 + elseif player:getStorageValue(Storage.ExplorerSociety.ThePlantCollection) == 18 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 18 then + npcHandler:say("Did you acquire the sample of the jungle bells plant we are looking for?", cid) + npcHandler.topic[cid] = 12 + elseif player:getStorageValue(Storage.ExplorerSociety.ThePlantCollection) == 19 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 19 then + npcHandler:say("Use this botanist's container on a witches cauldron to collect a sample for us. Bring it here and report about your plant collection.", cid) + npcHandler.topic[cid] = 0 + player:addItem(4869, 1) + player:setStorageValue(Storage.ExplorerSociety.ThePlantCollection, 20) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 20) + elseif player:getStorageValue(Storage.ExplorerSociety.ThePlantCollection) == 21 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 21 then + npcHandler:say("Did you acquire the sample of the witches cauldron we are looking for?", cid) + npcHandler.topic[cid] = 13 + elseif player:getStorageValue(Storage.ExplorerSociety.ThePlantCollection) == 22 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 22 then + npcHandler:say("Use this botanist\'s container on a giant jungle rose to obtain a sample for us. Bring it here and report about your plant collection.", cid) + npcHandler.topic[cid] = 0 + player:addItem(4869, 1) + player:setStorageValue(Storage.ExplorerSociety.ThePlantCollection, 23) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 23) + elseif player:getStorageValue(Storage.ExplorerSociety.ThePlantCollection) == 24 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 24 then + npcHandler:say("Did you acquire the sample of the giant jungle rose we are looking for?", cid) + npcHandler.topic[cid] = 14 + end + -- PLANT COLLECTION + + -- LIZARD URN + elseif msgcontains(msg, "lizard urn") then + if player:getStorageValue(Storage.ExplorerSociety.ThePlantCollection) == 26 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 26 then + npcHandler:say("The explorer society would like to acquire an ancient urn which is some sort of relic to the lizard people of Tiquanda. Would you like to accept this mission?", cid) + npcHandler.topic[cid] = 15 + elseif player:getStorageValue(Storage.ExplorerSociety.TheLizardUrn) == 28 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 27 then + npcHandler:say("Did you manage to get the ancient urn?", cid) + npcHandler.topic[cid] = 16 + end + -- LIZARD URN + + -- BONELORDS + elseif msgcontains(msg, "bonelord secrets") then + if player:getStorageValue(Storage.ExplorerSociety.TheLizardUrn) == 29 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 29 then + npcHandler:say({ + "We want to learn more about the ancient race of bonelords. We believe the black pyramid north east of Darashia was originally built by them ...", + "We ask you to explore the ruins of the black pyramid and look for any signs that prove our theory. You might probably find some document with the numeric bonelord language ...", + "That would be sufficient proof. Would you like to accept this mission?" + }, cid) + npcHandler.topic[cid] = 17 + elseif player:getStorageValue(Storage.ExplorerSociety.TheBonelordSecret) == 31 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 30 then + npcHandler:say("Have you found any proof that the pyramid was built by bonelords?", cid) + npcHandler.topic[cid] = 18 + end + -- BONELORDS + + -- ORC POWDER + elseif msgcontains(msg, "orc powder") then + if player:getStorageValue(Storage.ExplorerSociety.TheBonelordSecret) == 32 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 32 then + npcHandler:say({ + "It is commonly known that orcs of Uldereks Rock use some sort of powder to increase the fierceness of their war wolves and berserkers ...", + "What we do not know are the ingredients of this powder and its effect on humans ...", + "So we would like you to get a sample of the aforesaid powder. Do you want to accept this mission?" + }, cid) + npcHandler.topic[cid] = 19 + elseif player:getStorageValue(Storage.ExplorerSociety.TheOrcPowder) == 34 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 33 then + npcHandler:say("Did you acquire some of the orcish powder?", cid) + npcHandler.topic[cid] = 20 + end + -- ORC POWDER + + -- ELVEN POETRY + elseif msgcontains(msg, "elven poetry") then + if player:getStorageValue(Storage.ExplorerSociety.TheOrcPowder) == 35 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 35 then + npcHandler:say({ + "Some high ranking members would like to study elven poetry. They want the rare book 'Songs of the Forest' ...", + "For sure someone in Ab'Dendriel will own a copy. So you would just have to ask around there. Are you willing to accept this mission?" + }, cid) + npcHandler.topic[cid] = 21 + elseif player:getStorageValue(Storage.ExplorerSociety.TheElvenPoetry) == 37 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 36 then + npcHandler:say("Did you acquire a copy of 'Songs of the Forest' for us?", cid) + npcHandler.topic[cid] = 22 + end + -- ELVEN POETRY + + -- MEMORY STONE + elseif msgcontains(msg, "memory stone") then + if player:getStorageValue(Storage.ExplorerSociety.TheElvenPoetry) == 38 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 38 then + npcHandler:say({ + "We acquired some knowledge about special magic stones. Some lost civilisations used it to store knowledge and lore, just like we use books ...", + "The wisdom in such stones must be immense, but so are the dangers faced by every person who tries to obtain one...", + "As far as we know the ruins found in the north-west of Edron were once inhabited by beings who used such stones. Do you have the heart to go there and to get us such a stone?" + }, cid) + npcHandler.topic[cid] = 23 + elseif player:getStorageValue(Storage.ExplorerSociety.TheMemoryStone) == 40 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 39 then + npcHandler:say("Were you able to acquire a memory stone for our society?", cid) + npcHandler.topic[cid] = 24 + end + -- MEMORY STONE + + -- RUNE WRITINGS + elseif msgcontains(msg, "rune writings") then + if player:getStorageValue(Storage.ExplorerSociety.TheMemoryStone) == 41 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 41 then + npcHandler:say({ + "We would like to study some ancient runes that were used by the lizard race. We suspect some relation of the lizards to the founders of Ankrahmun ...", + "Somewhere under the ape infested city of Banuta, one can find dungeons that were once inhabited by lizards...", + "Look there for an atypical structure that would rather fit to Ankrahmun and its Ankrahmun Tombs. Copy the runes you will find on this structure...", + "Are you up to that challenge?" + }, cid) + npcHandler.topic[cid] = 25 + elseif player:getStorageValue(Storage.ExplorerSociety.TheRuneWritings) == 43 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 43 then + npcHandler:say("Did you create a copy of the ancient runes as requested?", cid) + npcHandler.topic[cid] = 26 + end + -- RUNE WRITINGS + + -- ANSWER YES + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "Fine, though it takes more then a mere lip service to join our ranks. To prove your dedication to the cause you will have to acquire an item for us ...", + "The mission should be simple to fulfil. For our excavations we have ordered a sturdy pickaxe in Kazordoon. You would have to seek out this trader Uzgod and get the pickaxe for us ...", + "Simple enough? Are you interested in this task?" + }, cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say("We will see if you can handle this simple task. Get the pickaxe from Uzgod in Kazordoon and bring it to one of our bases. Report there about the pickaxe.", cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.ExplorerSociety.JoiningTheExplorers, 1) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 1) + elseif npcHandler.topic[cid] == 3 then + if player:removeItem(4874, 1) then + player:setStorageValue(Storage.ExplorerSociety.JoiningTheExplorers, 4) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 4) + npcHandler:say({ + "Excellent, you brought just the tool we need! Of course it was only a simple task. However ...", + "I officially welcome you to the explorer society. From now on you can ask for missions to improve your rank." + }, cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 4 then + player:setStorageValue(Storage.ExplorerSociety.TheIceDelivery, 5) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 5) + npcHandler:say({ + "So listen please: Take this ice pick and use it on a block of ice in the caves beneath Folda. Get some ice and bring it here as fast as you can ...", + "Should the ice melt away, report on your ice delivery mission anyway. I will then tell you if the time is right to start another mission." + }, cid) + npcHandler.topic[cid] = 0 + player:addItem(4856, 1) + elseif npcHandler.topic[cid] == 5 then + if player:removeItem(4848, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheIceDelivery, 7) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 7) + npcHandler:say("Just in time. Sadly not much ice is left over but it will do. Thank you again.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 6 then + player:setStorageValue(Storage.ExplorerSociety.TheIceDelivery, 5) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 5) + npcHandler:say("*Sigh* I think the time is right to grant you another chance to get that ice. Hurry up this time.", cid) + npcHandler.topic[cid] = 0 + + -- BUTTERFLY HUNT + elseif npcHandler.topic[cid] == 7 then + player:setStorageValue(Storage.ExplorerSociety.TheButterflyHunt, 8) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 8) + npcHandler:say({ + "This preparation kit will allow you to collect a purple butterfly you have killed ...", + "Just use it on the fresh corpse of a purple butterfly, return the prepared butterfly to me and give me a report of your butterfly hunt." + }, cid) + npcHandler.topic[cid] = 0 + player:addItem(4865, 1) + elseif npcHandler.topic[cid] == 8 then + if player:removeItem(4866, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheButterflyHunt, 10) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 10) + npcHandler:say("A little bit battered but it will do. Thank you! If you think you are ready, ask for another butterfly hunt.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 9 then + if player:removeItem(4867, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheButterflyHunt, 13) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 13) + npcHandler:say("A little bit battered but it will do. Thank you! If you think you are ready, ask for another butterfly hunt.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 10 then + if player:removeItem(4868, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheButterflyHunt, 16) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 16) + npcHandler:say("That is an extraordinary species you have brought. Thank you! That was the last butterfly we needed.", cid) + npcHandler.topic[cid] = 0 + end + -- BUTTERFLY HUNT + + -- PLANT COLLECTION + elseif npcHandler.topic[cid] == 11 then + player:setStorageValue(Storage.ExplorerSociety.ThePlantCollection, 17) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 17) + npcHandler:say("Fine! Here take this botanist's container. Use it on a jungle bells plant to collect a sample for us. Report about your plant collection when you have been successful.", cid) + npcHandler.topic[cid] = 0 + player:addItem(4869, 1) + elseif npcHandler.topic[cid] == 12 then + if player:removeItem(4870, 1) then + player:setStorageValue(Storage.ExplorerSociety.ThePlantCollection, 19) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 19) + npcHandler:say("I see. It seems you've got some quite useful sample by sheer luck. Thank you! Just tell me when you are ready to continue with the plant collection.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 13 then + if player:removeItem(4871, 1) then + player:setStorageValue(Storage.ExplorerSociety.ThePlantCollection, 22) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 22) + npcHandler:say("Ah, finally. I started to wonder what took you so long. But thank you! Another fine sample, indeed. Just tell me when you are ready to continue with the plant collection.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 14 then + if player:removeItem(4872, 1) then + player:setStorageValue(Storage.ExplorerSociety.ThePlantCollection, 26) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 26) + npcHandler:say("What a lovely sample! With that you have finished your plant collection missions.", cid) + npcHandler.topic[cid] = 0 + end + -- PLANT COLLECTION + + -- LIZARD URN + elseif npcHandler.topic[cid] == 15 then + player:setStorageValue(Storage.ExplorerSociety.TheLizardUrn, 27) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 27) + player:setStorageValue(Storage.ExplorerSociety.ChorurnDoor, 1) + npcHandler:say({ + "You have indeed the spirit of an adventurer! In the south-east of Tiquanda is a small settlement of the lizard people ...", + "Beneath the newly constructed temple there, the lizards hide the said urn. Our attempts to acquire this item were without success ...", + "Perhaps you are more successful." + }, cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 16 then + if player:removeItem(4858, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheLizardUrn, 29) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 29) + npcHandler:say("Yes, that is the prized relic we have been looking for so long. You did a great job, thank you.", cid) + npcHandler.topic[cid] = 0 + end + -- LIZARD URN + + -- BONELORDS + elseif npcHandler.topic[cid] == 17 then + player:setStorageValue(Storage.ExplorerSociety.TheBonelordSecret, 30) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 30) + player:setStorageValue(Storage.ExplorerSociety.BonelordsDoor, 1) + npcHandler:say({ + "Excellent! So travel to the city of Darashia and then head north-east for the pyramid ...", + "If any documents are left, you probably find them in the catacombs beneath. Good luck!" + }, cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 18 then + if player:removeItem(4857, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheBonelordSecret, 32) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 32) + npcHandler:say("You did it! Excellent! The scientific world will be shaken by this discovery!", cid) + npcHandler.topic[cid] = 0 + end + -- BONELORDS + + -- ORC POWDER + elseif npcHandler.topic[cid] == 19 then + player:setStorageValue(Storage.ExplorerSociety.TheOrcPowder, 33) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 33) + player:setStorageValue(Storage.ExplorerSociety.OrcDoor, 1) + npcHandler:say({ + "You are a brave soul. As far as we can tell, the orcs maintain some sort of training facility in some hill in the north-east of their city ...", + "There you should find lots of their war wolves and hopefully also some of the orcish powder. Good luck!" + }, cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 20 then + if player:removeItem(15389, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheOrcPowder, 35) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 35) + npcHandler:say("You really got it? Amazing! Thank you for your efforts.", cid) + npcHandler.topic[cid] = 0 + end + -- ORC POWDER + + -- ELVEN POETRY + elseif npcHandler.topic[cid] == 21 then + player:setStorageValue(Storage.ExplorerSociety.TheElvenPoetry, 36) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 36) + player:setStorageValue(Storage.ExplorerSociety.ElvenDoor, 1) + npcHandler:say("Excellent. This mission is easy but nonetheless vital. Travel to Ab'Dendriel and get the book.", cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 22 then + if player:removeItem(4855, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheElvenPoetry, 38) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 38) + npcHandler:say("Let me have a look! Yes, that's what we wanted. A copy of 'Songs of the Forest'. I won't ask any questions about those bloodstains.", cid) + npcHandler.topic[cid] = 0 + end + -- ELVEN POETRY + + -- MEMORY STONE + elseif npcHandler.topic[cid] == 23 then + player:setStorageValue(Storage.ExplorerSociety.TheMemoryStone, 39) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 39) + player:setStorageValue(Storage.ExplorerSociety.MemoryStoneDoor, 1) + npcHandler:say("In the ruins of north-western Edron you should be able to find a memory stone. Good luck.", cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 24 then + if player:removeItem(4852, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheMemoryStone, 41) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 41) + npcHandler:say("A flawless memory stone! Incredible! It will take years even to figure out how it works but what an opportunity for science, thank you!", cid) + npcHandler.topic[cid] = 0 + end + -- MEMORY STONE + + -- RUNE WRITINGS + elseif npcHandler.topic[cid] == 25 then + player:setStorageValue(Storage.ExplorerSociety.TheRuneWritings, 42) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 42) + npcHandler:say("Excellent! Here, take this tracing paper and use it on the object you will find there to create a copy of the ancient runes.", cid) + npcHandler.topic[cid] = 0 + player:addItem(4853, 1) + elseif npcHandler.topic[cid] == 26 then + if player:removeItem(4854, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheRuneWritings, 44) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 44) + npcHandler:say("It's a bit wrinkled but it will do. Thanks again.", cid) + npcHandler.topic[cid] = 0 + end + -- RUNE WRITINGS + + -- ECTOPLASM + elseif npcHandler.topic[cid] == 27 then + npcHandler:say({ + "Fine. The society is looking for new means to travel. Some of our most brilliant minds have some theories about astral travel that they want to research further ...", + "Therefore we need you to collect some ectoplasm from the corpse of a ghost. We will supply you with a collector that you can use on the body of a slain ghost ...", + "Do you think you are ready for that mission?" + }, cid) + npcHandler.topic[cid] = 28 + elseif npcHandler.topic[cid] == 28 then + npcHandler:say("Good! Take this container and use it on a ghost that was recently slain. Return with the collected ectoplasm and hand me that container ...", cid) + npcHandler:say("Don't lose the container. They are expensive!", cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.ExplorerSociety.TheEctoplasm, 45) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 45) + player:addItem(4863, 1) + elseif npcHandler.topic[cid] == 29 then + if player:removeItem(8182, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheEctoplasm, 47) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 47) + npcHandler:say("Phew, I had no idea that ectoplasm would smell that ... oh, it's you, well, sorry. Thank you for the ectoplasm.", cid) + npcHandler.topic[cid] = 0 + end + -- ECTOPLASM + + -- SPECTRAL DRESS + elseif npcHandler.topic[cid] == 30 then + npcHandler:say({ + "That is quite courageous. We know, it's much we are asking for. The queen of the banshees lives in the so called Ghostlands, south west of Carlin. It is rumoured that her lair is located in the deepest dungeons beneath that cursed place ...", + "Any violence will probably be futile, you will have to negotiate with her. Try to get a spectral dress from her. Good luck." + }, cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.ExplorerSociety.TheSpectralDress, 48) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 48) + elseif npcHandler.topic[cid] == 31 then + if player:removeItem(4847, 1) then + player:setStorageValue(Storage.ExplorerSociety.TheSpectralDress, 50) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 50) + npcHandler:say("Good! Ask me for another mission.", cid) + npcHandler.topic[cid] = 0 + end + -- SPECTRAL DRESS + + -- SPECTRAL STONE + elseif npcHandler.topic[cid] == 32 then + npcHandler:say({ + "Good, just take this spectral essence and use it on the strange carving in this building as well as on the corresponding tile in our base at Northport ...", + "As soon as you have charged the portal tiles that way, report about the spectral portals." + }, cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.ExplorerSociety.TheSpectralStone, 53) + player:setStorageValue(Storage.ExplorerSociety.SpectralStoneDoor, 1) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 53) + player:addItem(4851, 1) -- spectral stone + -- SPECTRAL STONE + + -- SKULL OF RATHA / GIANT SMITHHAMMER + elseif npcHandler.topic[cid] == 33 then + if player:removeItem(2320, 1) then + npcHandler:say("Poor Ratha. Thank you for returning this skull to the society. We will see to a honourable burial of Ratha.", cid) + player:setStorageValue(Storage.ExplorerSociety.SkullOfRatha, 1) + player:addItem(2152, 2) + player:addItem(2148, 50) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Come back when you find any information.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 34 then + if player:removeItem(2321, 1) then + npcHandler:say("Marvellous! You brought a giant smith hammer for the explorer society!", cid) + player:setStorageValue(Storage.ExplorerSociety.GiantSmithHammer, 1) + player:addItem(2152, 2) + player:addItem(2148, 50) + npcHandler.topic[cid] = 0 + else + npcHandler:say("No you don\'t.", cid) + npcHandler.topic[cid] = 0 + end + -- SKULL OF RATHA / GIANT SMITHHAMMER + end + -- ANSWER YES + + -- ANSWER NO + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] == 5 then + npcHandler:say("Did it melt away?", cid) + npcHandler.topic[cid] = 6 + elseif npcHandler.topic[cid] == 33 then + npcHandler:say("Come back when you find any information.", cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 34 then + npcHandler:say("Come back when you find one.", cid) + npcHandler.topic[cid] = 0 + end + -- ANSWER NO + + -- SKULL OF RATHA / GIANT SMITHHAMMER + elseif msgcontains(msg, "skull of ratha") + and player:getStorageValue(Storage.ExplorerSociety.SkullOfRatha) < 1 then + npcHandler:say({ + "Ratha was a great explorer and even greater ladies' man. Sadly he never returned from a visit to the amazons. Probably he is dead ...", + "The society offers a substantial reward for the retrieval of Ratha or his remains. Do you have any news about Ratha?" + }, cid) + npcHandler.topic[cid] = 33 + elseif msgcontains(msg, "giant smithhammer") + and player:getStorageValue(Storage.ExplorerSociety.GiantSmithHammer) < 1 then + npcHandler:say("The explorer society is looking for a genuine giant smith hammer for our collection. It is rumoured the cyclopses of the Plains of Havoc might be using one. Did you by chance obtain such a hammer?", cid) + npcHandler.topic[cid] = 34 + -- SKULL OF RATHA / GIANT SMITHHAMMER + end + return true +end + +local function onTradeRequest(cid) + if Player(cid):getStorageValue(Storage.ExplorerSociety.TheAstralPortals) ~= 56 then + return false + end + + return true +end + +npcHandler:setCallback(CALLBACK_ONTRADEREQUEST, onTradeRequest) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/mortis.lua b/data/npc/scripts/mortis.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/mortis.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/morun.lua b/data/npc/scripts/morun.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/morun.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/mother_of_jack.lua b/data/npc/scripts/mother_of_jack.lua new file mode 100644 index 00000000000..c47fcfd00fe --- /dev/null +++ b/data/npc/scripts/mother_of_jack.lua @@ -0,0 +1,76 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "jack") then + if (player:getStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine) == 5) then + if (player:getStorageValue(Storage.TibiaTales.JackFutureQuest.Mother) < 1) then + npcHandler:say( + "What about him? He's downstairs as he always has been. He never went away from home \z + any further than into the forest nearby. He rarely ever took a walk to Edron, did he?", + cid + ) + npcHandler.topic[cid] = 1 + end + end + elseif msgcontains(msg, "no") then + if (npcHandler.topic[cid] == 2) then + npcHandler:say( + "Thought so. Of course he wouldn't do anything wrong. And he went where? Edron. Hm. I can \z + see nothing wrong with that. But... he wasn't there often, was he?", + cid + ) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, "yes") then + if (npcHandler.topic[cid] == 1) then + npcHandler:say("What...? But he wasn't up to something, was he?", cid) + npcHandler.topic[cid] = 2 + elseif (npcHandler.topic[cid] == 3) then + npcHandler:say( + { + "Oh my... he did what? Why was he there? Edron Academy? ...", + "I see... this cannot be. Spectrofuss? Who? Jack! When? How? But why did he do that? Jack!! \z + JACK!! When I find him he owes me an EXPLANATION. Thanks for telling \z + me what he is actually doing in his FREE TIME. ...", + "JAAAAACK!" + }, + cid + ) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.TibiaTales.JackFutureQuest.Mother, 1) + end + end + return true +end + +local voices = { + {text = "JAAAAACK? EVERYTHING ALRIGHT DOWN THERE?"}, + {text = "Oh dear, I can't find anything in here!"}, + {text = "There is still some dust on the drawer over there. What where you thinking, Jane?"}, + {text = "Jane!"} +} + +npcHandler:addModule(VoiceModule:new(voices)) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "I demand an explanation of you entering our house without any invitation.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/mr_brandon.lua b/data/npc/scripts/mr_brandon.lua new file mode 100644 index 00000000000..0bfeb7552d4 --- /dev/null +++ b/data/npc/scripts/mr_brandon.lua @@ -0,0 +1,24 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = ' Maybe I should rearrange some warm currents to get rid of this horrible fog.' }, + { text = 'All these treasures I cannot reach... what a pity.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/mr_morris.lua b/data/npc/scripts/mr_morris.lua new file mode 100644 index 00000000000..e7fccb6cc44 --- /dev/null +++ b/data/npc/scripts/mr_morris.lua @@ -0,0 +1,377 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + {text = "I have a quest that needs doing. Interested?"}, + {text = "Hmmm. Interesting. If only someone could help investigate this."}, + {text = "There's a task for an intrepid adventurer open! Any volunteers?"}, + {text = "Hey, you. Yes, you. I could use your help."}, + {text = " The Adventurers' Guild really should have equipped me with more man power. \z + Who's to keep all those monsters in check?" }, + {text = "So much to investigate, so little time..."}, + {text = "Buying all sorts of creature products!"}, + {text = "You're looking thoughtful. Maybe I can help you?"} +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "amulet") then + if player:getStorageValue(Storage.Quest.Dawnport.TheLostAmulet) < 1 then + npcHandler:say( + { + "One of our ...less fortunate members lost an ancient amulet somewhere on the island, \z + along with his life. If you could retrieve the amulet at least, there's a little reward. \z + Would you go on that errand?" + }, + cid, false, true, 10) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.Quest.Dawnport.TheLostAmulet) == 2 and player:getItemCount(23750) == 1 then + npcHandler:say( + { + "Ah, you found the amulet! Ah. Really? Poor Dormovo. \z + Always a bit hasty. Forgot his rope, or food, or potions - \z + it was to be expected he would meet an early end. Oh, well. ..." + }, + cid, false, true, 0) + player:removeItem(23750, 1) + player:addItem(2148, 50) + player:setStorageValue(Storage.Quest.Dawnport.TheLostAmulet, 3) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "log book") then + if player:getStorageValue(Storage.Quest.Dawnport.TornLogBook) < 1 then + npcHandler:say("The first log book from the first foray group has been stolen by trolls. \z + One wonders what for, as they can hardly read! Anyway, we need it back. \z + Would you go looking for it?", cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(Storage.Quest.Dawnport.TornLogBook) == 1 + and player:getStorageValue(Storage.Quest.Dawnport.TheStolenLogBook) == 1 + and player:getItemCount(23749) == 1 then + npcHandler:say("Ah, yes, that's it! Torn and gnawed, but, ah well, the information is still retrievable. \z + Thank you. Here's your reward.", cid) + player:removeItem(23749, 1) + player:addItem(2148, 50) + player:setStorageValue(Storage.Quest.Dawnport.TheStolenLogBook, 2) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "herbs") then + if player:getStorageValue(Storage.Quest.Dawnport.TheRareHerb) < 1 then + npcHandler:say("One of our ...less fortunate members lost an ancient amulet somewhere on the island, \z + along with his life. If you could retrieve the amulet at least, there's a little reward. \z + Would you go on that errand?", cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.Quest.Dawnport.TheRareHerb) == 2 then + npcHandler:say("Ah, wonderful. Freshly cut and full of potent... whatever it is it does. \z + Thanks. Here's your reward.", cid) + player:addItem(2148, 50) + player:setStorageValue(Storage.Quest.Dawnport.TheRareHerb, 3) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "key") then + if player:getStorageValue(Storage.Quest.Dawnport.TheDormKey) < 1 then + npcHandler:say("his is an undercover thing - the key to the dormitory has disappeared. \z + No one wants to own up who has lost it, at least not to me. Maybe they'll talk to you. \z + I'll reward you if you find it. You in?", cid) + npcHandler.topic[cid] = 4 + elseif player:getStorageValue(Storage.Quest.Dawnport.TheDormKey) == 4 then + npcHandler:say("Ah, you're here to report about the key - any progress?", cid) + npcHandler.topic[cid] = 5 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Wonderful. I don't believe you will find Dormovo alive, though. \z + He would not have stayed abroad that long without refilling his inkpot for his research notes. \z + But at least the amulet should be retrieved.", cid) + player:setStorageValue(Storage.Quest.Dawnport.TheLostAmulet, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say("Good. The logbook or whatever is left of it is very valuable to my research. \z + If you return its contents to me, I will reward you accordingly.", cid) + player:setStorageValue(Storage.Quest.Dawnport.TheStolenLogBook, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + npcHandler:say( + { + "Splendid. Those Dawnfire buds are just the thing against nasty troll bites, you know? \z + But they're quite rare.", + "Look for a bush with yellow glowing flower buds. It grows only on a special, \z + light grey-brown sand, and is usually surrounded by fireflies. \z + Use the herb to pluck off the fresh flower buds, and return to me." + }, + cid, false, true, 10) + player:setStorageValue(Storage.Quest.Dawnport.TheRareHerb, 1) + player:setStorageValue(Storage.Quest.Dawnport.HerbFlower, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 4 then + npcHandler:say("Good. Just chat with the guys. Someone is bound to remember *something* about that key.", cid) + player:setStorageValue(Storage.Quest.Dawnport.TheDormKey, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 5 then + npcHandler:say("The key to the dormitory! Finally! You're a real sleuth. Here's your reward.", cid) + player:removeItem(23763, 1) + player:addItem(2148, 50) + player:setStorageValue(Storage.Quest.Dawnport.TheDormKey, 5) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 6 then + npcHandler:say("Good. Killing 20 will teach them a lesson, without provoking desperate retaliation. \z + Still, take care!", cid) + player:setStorageValue(Storage.Quest.Dawnport.MorriskTroll, 1) + player:setStorageValue(Storage.Quest.Dawnport.MorrisTrollCount, 0) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 7 then + npcHandler:say("Good. Killing 20 will teach them a lesson, without provoking desperate retaliation. \z + Still, take care!", cid) + player:setStorageValue(Storage.Quest.Dawnport.MorrisGoblin, 1) + player:setStorageValue(Storage.Quest.Dawnport.MorrisGoblinCount, 0) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 8 then + npcHandler:say("Good. Killing 20 will teach them a lesson, without provoking desperate retaliation. \z + Still, take care!", cid) + player:setStorageValue(Storage.Quest.Dawnport.MorrisMinos, 1) + player:setStorageValue(Storage.Quest.Dawnport.MorrisMinosCount, 0) + npcHandler.topic[cid] = 0 + end + --End mission + --Start Task + elseif msgcontains(msg, "trolls") then + if player:getStorageValue(Storage.Quest.Dawnport.MorriskTroll) < 1 then + npcHandler:say( + { + "Mountain trolls are worse than magpies, stealing everything that's not nailed down. \z + Lately, they have raided our ship and made off with most of the Captain's rum stock!", + "I will reward you if you kill 20 mountain trolls. Would you do that?" + }, + cid, false, true, 10) + npcHandler.topic[cid] = 6 + elseif player:getStorageValue(Storage.Quest.Dawnport.MorriskTroll) == 1 then + if player:getStorageValue(Storage.Quest.Dawnport.MorrisTrollCount) >= 20 then + npcHandler:say("Ah, very good job. That should put a crimp in their activities. Here's your reward.", cid) + player:setStorageValue(17524, 1) + player:setStorageValue(Storage.Quest.Dawnport.MorriskTroll, 2) + player:addItem(2148, 50) + else + npcHandler:say("Come back when you have slain {20 mountain trolls!}", cid) + end + end + elseif msgcontains(msg, "globin") then + if player:getStorageValue(Storage.Quest.Dawnport.MorrisGoblin) < 1 then + npcHandler:say( + { + "Footmen of the muglex clan are worse than magpies, stealing everything that's not nailed down. \z + Lately, they have raided our ship and made off with most of the Captain's rum stock!", + "I will reward you if you kill 20 muglex clan footmen. Would you do that?" + }, + cid, false, true, 10) + npcHandler.topic[cid] = 7 + elseif player:getStorageValue(Storage.Quest.Dawnport.MorrisGoblin) == 1 then + if player:getStorageValue(Storage.Quest.Dawnport.MorrisGoblinCount) >= 20 then + npcHandler:say("Ah, very good job. That should put a crimp in their activities. Here's your reward.", cid) + player:setStorageValue(17525, 1) + player:setStorageValue(Storage.Quest.Dawnport.MorrisGoblin, 2) + player:addItem(2148, 50) + else + npcHandler:say("Come back when you have slain {20 muglex clan footman!}", cid) + end + end + elseif msgcontains(msg, "minotaur") then + if player:getStorageValue(Storage.Quest.Dawnport.MorrisMinos) < 1 then + npcHandler:say( + { + "Minotaur bruisers are worse than magpies, stealing everything that's not nailed down. \z + Lately, they have raided our ship and made off with most of the Captain's rum stock!", + "I will reward you if you kill 20 minotaur bruisers. Would you do that?" + }, + cid, false, true, 10) + npcHandler.topic[cid] = 8 + elseif player:getStorageValue(Storage.Quest.Dawnport.MorrisMinos) == 1 then + if player:getStorageValue(Storage.Quest.Dawnport.MorrisMinosCount) >= 20 then + npcHandler:say("Ah, very good job. That should put a crimp in their activities. Here's your reward.", cid) + player:setStorageValue(17526, 1) + player:setStorageValue(Storage.Quest.Dawnport.MorrisMinos, 2) + player:addItem(2148, 50) + else + npcHandler:say("Come back when you have slain {20 minotaur bruisers!}", cid) + end + elseif player:getStorageValue(Storage.Quest.Dawnport.MorrisMinos) == 2 then + npcHandler:say("You already done this task.", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +keywordHandler:addKeyword({"quest"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Hm. Well, you look like you want to take a look at the unknown yourself. \z + I might have a job for you. Choose what you would like to do - {fetch} some things, or {kill} some monsters." + } +) +keywordHandler:addKeyword({"mission"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Hm. Well, you look like you want to take a look at the unknown yourself. \z + I might have a job for you. Choose what you would like to do - {fetch} some things, or {kill} some monsters." + } +) +keywordHandler:addKeyword({"fetch"}, StdModule.say, + { + npcHandler = npcHandler, + text = "There's three things that need to be found. You can look for an {amulet}, \z + a {log book} or pick some rare {herbs}. Take your pick." + } +) +keywordHandler:addKeyword({"kill"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Well, those monsters have grown very uppity lately. There's a choice of three - mountain {trolls}, \z + muglex clan {goblins} or, if you are up to it or together with some friends, \z + there's a need to weed out some risky {minotaur} bruisers. Choose your target." + } +) +keywordHandler:addKeyword({"name"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Mr Morris will do." + } +) +keywordHandler:addKeyword({"job"}, StdModule.say, + { + npcHandler = npcHandler, + text = "There's always someone who needs to be at the front, to take the first step into the unknown. \z + My whole life has been full of such steps." + } +) +keywordHandler:addKeyword({"dawnport"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Ah, that old story of how it was named? I spread it around. \z + Can't remember really what its origins are. Interesting archeological findings here, though." + } +) +keywordHandler:addKeyword({"secrets of dawnport"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Ah yes. Well, the magic that led us here seems to be most potent at a certain time, close before sunrise. \z + Perhaps like a giant pulse, or beacon. Maybe the gods set it here, or a mad sorcerer, \z + we don't know for sure yet... The portal deep down in the caves, resonating with magical energy where you came \z + through, can maybe bring something else into this world as well. \z + So it must be carefully guarded while we investigate the island for more clues... \z + There are some very interesting archeological findings here on the island throughout. \z + Seems the island has drawn some cults here, but why they are gone now, no one knows." + } +) +keywordHandler:addKeyword({"archeological"}, StdModule.say, + { + npcHandler = npcHandler, + text = "It seems that throughout its history, this island was inhabited by very different species. \z + I like to study their remains." + } +) +keywordHandler:addKeyword({"rookgaard"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Yeah. Long time I haven't been to that place. How's old Vascalir? Still hanging around in the academy? \z + And Kraknaknork? Hah, I remember our brawl after that last card game. Fun times." + } +) +keywordHandler:addKeyword({"coltrayne"}, StdModule.say, + { + npcHandler = npcHandler, + text = "What about him? Is he in one of his dark moods again? That's his normal mood, I mean. \z + Just buy your armor, weaponry and ammunition there and don't worry." + } +) +keywordHandler:addKeyword({"garamond"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Tired of the academy, maybe, but not of teaching. If you need druid or sorcerer spells, go to him." + } +) +keywordHandler:addKeyword({"hamish"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Ah, good old Hamish. A real wizard with potions. \z + Will supply you with very useful magic equipment for hunting." + } +) +keywordHandler:addKeyword({"mr morris"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Exactly. Has a nice ring to it." + } +) +keywordHandler:addKeyword({"oressa"}, StdModule.say, + { + npcHandler = npcHandler, + text = "She's a good listener if you should still hesitate as to the choice of your definite vocation." + } +) +keywordHandler:addKeyword({"plunderpurse"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Well, for him it's always been just a question of ''Your gold or your life'' - gold it is nowadays. \z + You can stash your loose change at ol' Abram, but make sure to withdraw it once you leave Dawnport!" + } +) +keywordHandler:addKeyword({"inigo"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Ran across Inigo a few times on some remote islands, years and years ago. \z + Talked him into coming along here, and he seems to enjoy helping newcomers find their way. \z + Passing his knowledge on to the next generation." + } +) +keywordHandler:addKeyword({"richard"}, StdModule.say, + { + npcHandler = npcHandler, + text = "We found him here half-dead and fixed him up, now he fixes us dinner and roof beams. \z + Definitely someone you should check out for food, a rope and a shovel." + } +) +keywordHandler:addKeyword({"ser tybald"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Been together through many a desperate situation. A romantic underneath it all. \z + Found the time to specialise on spells for paladins and knights somewhere along the way." + } +) +keywordHandler:addKeyword({"wentworth"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Be careful that he doesn't bore you to death with accountants of, well, your bank account history." + } +) +keywordHandler:addKeyword({"woblin"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Ah, the goblin who sneaks around here now and then? Lives in a cave to the west, somewhere." + } +) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome, young adventurer. \z +If you seek to help me with some things, I might have a little {quest} or {mission} for you.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/mr_west.lua b/data/npc/scripts/mr_west.lua new file mode 100644 index 00000000000..e4733d4fe40 --- /dev/null +++ b/data/npc/scripts/mr_west.lua @@ -0,0 +1,56 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + local player = Player(cid) + if(player:getStorageValue(Storage.InServiceofYalahar.MrWestDoor) == 1) then + npcHandler:setMessage(MESSAGE_GREET, "Wh .. What? How did you get here? Where are all the guards? You .. you could have killed me but yet you chose to talk? What a relief! ... So what brings you here my friend, if I might call you like that? ") + elseif(player:getStorageValue(Storage.InServiceofYalahar.MrWestDoor) == 2) then + npcHandler:setMessage(MESSAGE_GREET, "Murderer! But .. I give in, you won! ... Dictate me your conditions but please, I beg you, spare my life. What do you want?") + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if(msgcontains(msg, "mission")) then + if(player:getStorageValue(Storage.InServiceofYalahar.Questline) == 24) then + if(player:getStorageValue(Storage.InServiceofYalahar.MrWestDoor) == 1) then + npcHandler:say("Indeed, I can see the benefits of a mutual agreement. I will later read the details and send a letter to your superior. ", cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 25) + player:setStorageValue(Storage.InServiceofYalahar.Mission04, 3) -- StorageValue for Questlog "Mission 04: Good to be Kingpin" + player:setStorageValue(Storage.InServiceofYalahar.MrWestStatus, 1) + npcHandler.topic[cid] = 0 + elseif(player:getStorageValue(Storage.InServiceofYalahar.MrWestDoor) == 2) then + npcHandler:say("Yes, for the sake of my life I'll accept those terms. I know when I have lost. Tell your master I will comply with his orders. ", cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 25) + player:setStorageValue(Storage.InServiceofYalahar.Mission04, 4) -- StorageValue for Questlog "Mission 04: Good to be Kingpin" + player:setStorageValue(Storage.InServiceofYalahar.MrWestStatus, 2) + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/mugluf.lua b/data/npc/scripts/mugluf.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/mugluf.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/mugruu.lua b/data/npc/scripts/mugruu.lua new file mode 100644 index 00000000000..e88e935b7eb --- /dev/null +++ b/data/npc/scripts/mugruu.lua @@ -0,0 +1,20 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/muhad.lua b/data/npc/scripts/muhad.lua new file mode 100644 index 00000000000..678db2866b7 --- /dev/null +++ b/data/npc/scripts/muhad.lua @@ -0,0 +1,63 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'here'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the leader of the true sons of {Daraman}.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the leader of the true sons of {Daraman}.'}) +keywordHandler:addKeyword({'daraman'}, StdModule.say, {npcHandler = npcHandler, text = 'This is our home - the land of the desert.'}) +keywordHandler:addKeyword({'ankrahmun'}, StdModule.say, {npcHandler = npcHandler, text = 'We will fight that city until we get back what belongs to us.'}) +keywordHandler:addKeyword({'darashia'}, StdModule.say, {npcHandler = npcHandler, text = 'We avoid these places you call cities.'}) +keywordHandler:addKeyword({'city'}, StdModule.say, {npcHandler = npcHandler, text = 'I would go crazy living in a cage like that.'}) +keywordHandler:addKeyword({'offer'}, StdModule.say, {npcHandler = npcHandler, text = 'We have nothing that would be of value for you.'}) +keywordHandler:addKeyword({'undead'}, StdModule.say, {npcHandler = npcHandler, text = 'That is the curse for not following the rules of the desert. No son of the desert has ever come back from the dead.'}) +keywordHandler:addKeyword({'daraman'}, StdModule.say, {npcHandler = npcHandler, text = 'We have nothing that would be of value for you.'}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + local AritosTask = player:getStorageValue(Storage.TibiaTales.AritosTask) + + -- AritosTask + if msgcontains(msg, "arito") then + if player:getStorageValue(Storage.TibiaTales.AritosTask) == 1 then + npcHandler:say({ + 'I don\'t know how something like this ever could be possible. He met a girl from {Ankrahmun} and she must have twisted his head. Arito started to tell stories about the Pharaoh and about Ankrahmun. ...', + 'In the wink of an eye he left us and was never seen again. I think he feared revenge for leaving us - which partially is not without reason. Why are you asking me about him? Did he send you to me?' + }, cid) + npcHandler.topic[cid] = 1 + + end + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, "yes") then + npcHandler:say({ + 'Ahh, I know that some of my people fear that Arito tells the old secrets of our race and want to see him dead but I don\'t bear him a grudge. I will have to have a serious word with my people. ...', + 'Tell him that he can consider himself as acquitted. He is not the reason for our attacks towards {Ankrahmun}.' + }, cid) + player:setStorageValue(Storage.TibiaTales.AritosTask, 2) + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Be greeted, foreigner under the sun of Darama. What brings you {here}?") +npcHandler:setMessage(MESSAGE_FAREWELL, "May Daraman be with you on your travels.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "May Daraman be with you on your travels.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/muriel.lua b/data/npc/scripts/muriel.lua new file mode 100644 index 00000000000..56356b9172f --- /dev/null +++ b/data/npc/scripts/muriel.lua @@ -0,0 +1,94 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function releasePlayer(cid) + if not Player(cid) then + return + end + + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, 'mission') then + if player:getLevel() < 35 then + npcHandler:say('Indeed there is something to be done, but I need someone more experienced. Come back later if you want to.', cid) + addEvent(releasePlayer, 1000, cid) + return true + end + + if player:getStorageValue(Storage.TibiaTales.IntoTheBonePit) == -1 then + npcHandler:say({ + 'Indeed, there is something you can do for me. You must know I am researching for a new spell against the undead. ...', + 'To achieve that I need a desecrated bone. There is a cursed bone pit somewhere in the dungeons north of Thais where the dead never rest. ...', + 'Find that pit, dig for a well-preserved human skeleton and conserve a sample in a special container which you receive from me. Are you going to help me?' + }, cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.TibiaTales.IntoTheBonePit) == 1 then + npcHandler:say({ + 'The rotworms dug deep into the soil north of Thais. Rumours say that you can access a place of endless moaning from there. ...', + 'No one knows how old that common grave is but the people who died there are cursed and never come to rest. A bone from that pit would be perfect for my studies.' + }, cid) + addEvent(releasePlayer, 1000, cid) + elseif player:getStorageValue(Storage.TibiaTales.IntoTheBonePit) == 2 then + player:setStorageValue(Storage.TibiaTales.IntoTheBonePit, 3) + if player:removeItem(4864, 1) then + player:addItem(6300, 1) + npcHandler:say('Excellent! Now I can try to put my theoretical thoughts into practice and find a cure for the symptoms of undead. Here, take this for your efforts.', cid) + else + npcHandler:say({ + 'I am so glad you are still alive. Benjamin found the container with the bone sample inside. Fortunately, I inscribe everything with my name, so he knew it was mine. ...', + 'I thought you have been haunted and killed by the undead. I\'m glad that this is not the case. Thank you for your help.' + }, cid) + end + addEvent(releasePlayer, 1000, cid) + else + npcHandler:say('I am very glad you helped me, but I am very busy at the moment.', cid) + addEvent(releasePlayer, 1000, cid) + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + player:addItem(4863, 1) + player:setStorageValue(Storage.TibiaTales.IntoTheBonePit, 1) + npcHandler:say({ + 'Great! Here is the container for the bone. Once, I used it to collect ectoplasma of ghosts, but it will work here as well. ...', + 'If you lose it, you can buy a new one from the explorer\'s society in North Port or Port Hope. Ask me about the mission when you come back.' + }, cid) + addEvent(releasePlayer, 1000, cid) + end + elseif msgcontains(msg, 'no') then + if npcHandler.topic[cid] == 1 then + npcHandler:say('Ohh, then I need to find another adventurer who wants to earn a great reward. Bye!', cid) + addEvent(releasePlayer, 1000, cid) + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, 'Greetings, |PLAYERNAME|! Looking for wisdom and power, eh?') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Farewell.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Farewell.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/myra.lua b/data/npc/scripts/myra.lua new file mode 100644 index 00000000000..20987a137d3 --- /dev/null +++ b/data/npc/scripts/myra.lua @@ -0,0 +1,105 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Start +local tiaraKeyword = keywordHandler:addKeyword({'tiara'}, StdModule.say, {npcHandler = npcHandler, text = 'Well... maybe, if you help me a little, I could convince the academy of Edron that you are a valuable help here and deserve an award too. How about it?'}, function(player) return player:getStorageValue(Storage.OutfitQuest.MageSummoner.AddonHatCloak) == -1 end) + local yesKeyword = tiaraKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'Okay, great! You see, I need a few magical ingredients which I\'ve run out of. First of all, please bring me 70 bat wings. ...', + 'Then, I urgently need a lot of red cloth. I think 20 pieces should suffice. ...', + 'Oh, and also, I could use a whole load of ape fur. Please bring me 40 pieces. ...', + 'After that, um, let me think... I\'d like to have some holy orchids. Or no, many holy orchids, to be safe. Like 35. ...', + 'Then, 10 spools of spider silk yarn, 60 lizard scales and 40 red dragon scales. ...', + 'I know I\'m forgetting something.. wait... ah yes, 15 ounces of magic sulphur and 30 ounces of vampire dust. ...', + 'That\'s it already! Easy task, isn\'t it? I\'m sure you could get all of that within a short time. ...', + 'Did you understand everything I told you and are willing to handle this task?' + }} + ) + + yesKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Fine! Let\'s start with the 70 bat wings. I really feel uncomfortable out there in the jungle.', reset = true}, nil, function(player) player:setStorageValue(Storage.OutfitQuest.MageSummoner.AddonHatCloak, 1) player:setStorageValue(Storage.OutfitQuest.MageSummoner.MissionHatCloak, 1) player:setStorageValue(Storage.OutfitQuest.Ref, math.max(0, player:getStorageValue(Storage.OutfitQuest.Ref)) + 1) end) + yesKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'Would you like me to repeat the task requirements then?', moveup = 2}) + +tiaraKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'That\'s a pity.', reset = true}) +keywordHandler:addAliasKeyword({'award'}) + +-- When asking for your award before completing your tasks +keywordHandler:addKeyword({'tiara'}, StdModule.say, {npcHandler = npcHandler, text = 'Before I can nominate you for an award, please complete your task'}, function(player) return player:getStorageValue(Storage.OutfitQuest.MageSummoner.AddonHatCloak) > 0 and player:getStorageValue(Storage.OutfitQuest.MageSummoner.AddonHatCloak) < 10 end) +keywordHandler:addAliasKeyword({'award'}) + +-- What happens when you say task +local function addTaskKeyword(value, text) + keywordHandler:addKeyword({'task'}, StdModule.say, {npcHandler = npcHandler, text = text}, function(player) return player:getStorageValue(Storage.OutfitQuest.MageSummoner.AddonHatCloak) == value end) + if value == 10 then + keywordHandler:addAliasKeyword({'tiara'}) + keywordHandler:addAliasKeyword({'award'}) + end +end + +addTaskKeyword(1, 'Your current task is to bring me 70 bat wings, |PLAYERNAME|.') +addTaskKeyword(2, 'Your current task is to bring me 20 pieces of red cloth, |PLAYERNAME|.') +addTaskKeyword(3, 'Your current task is to bring me 40 pieces of ape fur, |PLAYERNAME|.') +addTaskKeyword(4, 'Your current task is to bring me 35 holy orchids, |PLAYERNAME|.') +addTaskKeyword(5, 'Your current task is to bring me 10 spools of spider silk yarn, |PLAYERNAME|.') +addTaskKeyword(6, 'Your current task is to bring me 60 lizard scales, |PLAYERNAME|.') +addTaskKeyword(7, 'Your current task is to bring me 40 red dragon scales, |PLAYERNAME|.') +addTaskKeyword(8, 'Your current task is to bring me 15 ounces of magic sulphur, |PLAYERNAME|.') +addTaskKeyword(9, 'Your current task is to bring me 30 ounces of vampire dust, |PLAYERNAME|.') +addTaskKeyword(10, 'Go to the academy in Edron and tell Zoltan that I sent you, |PLAYERNAME|.') +addTaskKeyword(11, 'I don\'t have any tasks for you right now, |PLAYERNAME|. You were of great help.') + +-- Hand over items +local function addItemKeyword(keyword, text, value, itemId, count, last) + local itemKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = text[1]}, function(player) return player:getStorageValue(Storage.OutfitQuest.MageSummoner.AddonHatCloak) == value end) + itemKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'No, no. That\'s not enough, I fear.', reset = true}, function(player) return player:getItemCount(itemId) < count end) + local rewardKeyword = itemKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = text[2]}, nil, + function(player) + player:removeItem(itemId, count) + player:setStorageValue(Storage.OutfitQuest.MageSummoner.AddonHatCloak, player:getStorageValue(Storage.OutfitQuest.MageSummoner.AddonHatCloak) + 1) + player:setStorageValue(Storage.OutfitQuest.MageSummoner.MissionHatCloak, player:getStorageValue(Storage.OutfitQuest.MageSummoner.MissionHatCloak) + 1) + if not last then + npcHandler:resetNpc(player.uid) + end + end + ) + + if last then + rewardKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'I thought so. Go to the academy of Edron and tell Zoltan that I sent you. I will send a nomination to him. You were really a great help. Thanks again!', reset = true}) + rewardKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'Really? Well, if you should change your mind, go to the academy of Edron and tell Zoltan that I sent you. I will send a nomination to him.', reset = true}) + end + + itemKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'That\'s a pity.', reset = true}) + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = text[3]}) +end + +addItemKeyword('bat wing', {'Oh, did you bring the 70 bat wings for me?', 'Thank you! I really needed them for my anti-wrinkle lotion. Now, please bring me 20 pieces of {red cloth}.', 'I love to say \'creatures of the night\'. Got a dramatic as well as romantic ring to it.'}, 1, 5894, 70) +addItemKeyword('red cloth', {'Have you found 20 pieces of red cloth?', 'Great! This should be enough for my new dress. Don\'t forget to bring me 40 pieces of {ape fur} next!', 'Nice material for a cape, isn\'t it?'}, 2, 5911, 20) +addItemKeyword('ape fur', {'Were you able to retrieve 40 pieces of ape fur?', 'Nice job, player. You see, I\'m testing a new depilation cream. I guess if it works on ape fur it\'s good quality. Next, please bring me 35 {holy orchids}.', 'This feels really smooth.'}, 3, 5883, 40) +addItemKeyword('holy orchid', {'Did you convince the elves to give you 35 holy orchids?', 'Thank god! The scent of holy orchids is simply the only possible solution against the horrible stench from the tavern latrine. Now, please bring me 10 rolls of {spider silk yarn}!', 'I heard that some elves cultivate these flowers.'}, 4, 5922, 35) +addItemKeyword('spider silk', {'Oh, did you bring 10 spools of spider silk yarn for me?', 'I appreciate it. My pet doggie manages to bite through all sorts of leashes, which is why he is always gone. I\'m sure this strong yarn will keep him. Now, go for the 60 {lizard scales}!', 'Only very large spiders produce silk which is strong enough to be yarned. I heard that mermaids can turn spider silk into yarn.'}, 5, 5886, 10) +addItemKeyword('lizard scale', {'Have you found 60 lizard scales?', 'Good job. They will look almost like sequins on my new dress. Please go for the 40 {red dragon scales} now.', 'Lizard scales are great for all sorts of magical potions.'}, 6, 5881, 60) +addItemKeyword('red dragon scale', {'Were you able to get all 40 red dragon scales?', 'Thanks! They make a pretty decoration, don\'t you think? Please bring me 15 ounces of {magic sulphur} now!', 'Red dragon scales are hard to come by, but much harder than the green ones.'}, 7, 5882, 40) +addItemKeyword('magic sulphur', {'Have you collected 15 ounces of magic sulphur?', 'Ah, that\'s enough magic sulphur for my new peeling. You should try it once, your skin gets incredibly smooth. Now, the only thing I need is {vampire dust}. 30 ounces will suffice.', 'Magic sulphur can be extracted from magical weapons. I heard that Djinns are good at magical extractions.'}, 8, 5904, 15) +addItemKeyword('vampire dust', {'Have you gathered 30 ounces of vampire dust?', 'Ah, great. Now I can finally finish the potion which the academy of Edron asked me to. I guess, now you want your reward, don\'t you?', 'The Tibian vampires are quite restistant. I needs a special blessed stake to turn their corpse into dust, and it doesn\'t work all the time. Maybe a priest can help you.'}, 9, 5905, 30, true) + +-- Basic +keywordHandler:addKeyword({'outfit'}, StdModule.say, {npcHandler = npcHandler, text = 'This Tiara is an award by the academy of Edron in recognition of my service here.'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Greetings, |PLAYERNAME|. If you are looking for sorcerer {spells} don\'t hesitate to ask.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Farewell, |PLAYERNAME|.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Farewell.') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/mysterious_ornate_chest.lua b/data/npc/scripts/mysterious_ornate_chest.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/mysterious_ornate_chest.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/nah_bob.lua b/data/npc/scripts/nah_bob.lua new file mode 100644 index 00000000000..e6c2f9bc933 --- /dev/null +++ b/data/npc/scripts/nah_bob.lua @@ -0,0 +1,75 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, 'cookie') then + if player:getStorageValue(Storage.WhatAFoolish.Questline) == 31 + and player:getStorageValue(Storage.WhatAFoolish.CookieDelivery.Djinn) ~= 1 then + npcHandler:say('You brought cookies! How nice of you! Can I have one?', cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + if not player:removeItem(8111, 1) then + npcHandler:say('You have no cookie that I\'d like.', cid) + npcHandler.topic[cid] = 0 + return true + end + + player:setStorageValue(Storage.WhatAFoolish.CookieDelivery.Djinn, 1) + if player:getCookiesDelivered() == 10 then + player:addAchievement('Allow Cookies?') + end + + Npc():getPosition():sendMagicEffect(CONST_ME_GIFT_WRAPS) + npcHandler:say('You see, good deeds like this will ... YOU ... YOU SPAWN OF EVIL! I WILL MAKE SURE THE MASTER LEARNS ABOUT THIS!', cid) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + elseif msgcontains(msg, 'no') then + if npcHandler.topic[cid] == 1 then + npcHandler:say('I see.', cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +local function onTradeRequest(cid) + local player = Player(cid) + if player:getStorageValue(Storage.DjinnWar.MaridFaction.Mission03) ~= 3 then + npcHandler:say('I\'m sorry, human. But you need Gabel\'s permission to trade with me.', cid) + return false + end + + return true +end + +npcHandler:setMessage(MESSAGE_GREET, " Another {customer}! I've only just sat down! What is it, |PLAYERNAME|?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Bye now, Neutrala |PLAYERNAME|. Visit old Bob again one day!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Bye then.") +npcHandler:setMessage(MESSAGE_SENDTRADE, 'At your service, just browse through my wares.') + +npcHandler:setCallback(CALLBACK_ONTRADEREQUEST, onTradeRequest) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/narsai.lua b/data/npc/scripts/narsai.lua new file mode 100644 index 00000000000..7755832b7b9 --- /dev/null +++ b/data/npc/scripts/narsai.lua @@ -0,0 +1,87 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local playerTopic = {} +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.Kilmaresh.First.Access) < 1 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + playerTopic[cid] = 1 + elseif (player:getStorageValue(Storage.Kilmaresh.First.JamesfrancisTask) >= 0 and player:getStorageValue(Storage.Kilmaresh.First.JamesfrancisTask) <= 50) + and player:getStorageValue(Storage.Kilmaresh.First.Mission) < 3 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + playerTopic[cid] = 15 + elseif player:getStorageValue(Storage.Kilmaresh.First.Mission) == 4 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + player:setStorageValue(Storage.Kilmaresh.First.Mission, 5) + playerTopic[cid] = 20 + end + npcHandler:addFocus(cid) + return true +end + +local function creatureSayCallback(cid, type, msg) +if not npcHandler:isFocused(cid) then + return false +end +npcHandler.topic[cid] = playerTopic[cid] +local player = Player(cid) +if msgcontains(msg, "mission") and player:getStorageValue(Storage.Kilmaresh.Eighth.Narsai) == 1 then + if player:getStorageValue(Storage.Kilmaresh.Eighth.Narsai) == 1 then + npcHandler:say({"Could you help me do a ritual?"}, cid)-- It needs to be revised, it's not the same as the global + npcHandler.topic[cid] = 1 + playerTopic[cid] = 1 + end +elseif msgcontains(msg, "yes") and playerTopic[cid] == 1 and player:getStorageValue(Storage.Kilmaresh.Eighth.Narsai) == 1 then + if player:getStorageValue(Storage.Kilmaresh.Eighth.Narsai) == 1 then + player:addItem(36549, 1) + npcHandler:say({"Here is the list of ingredients that are missing to complete the ritual. "}, cid)-- It needs to be revised, it's not the same as the global + player:setStorageValue(Storage.Kilmaresh.Eighth.Narsai, 2) + npcHandler.topic[cid] = 2 + playerTopic[cid] = 2 + else + npcHandler:say({"Sorry."}, cid)-- It needs to be revised, it's not the same as the global + end +end +if msgcontains(msg, "mission") and player:getStorageValue(Storage.Kilmaresh.Eighth.Narsai) == 2 then + if player:getStorageValue(Storage.Kilmaresh.Eighth.Narsai) == 2 then + npcHandler:say({"Did you bring all the materials I informed you about?"}, cid)-- It needs to be revised, it's not the same as the global + npcHandler.topic[cid] = 3 + playerTopic[cid] = 3 + end +elseif msgcontains(msg, "yes") and playerTopic[cid] == 3 and player:getStorageValue(Storage.Kilmaresh.Eighth.Narsai) == 2 then + if player:getStorageValue(Storage.Kilmaresh.Eighth.Narsai) == 2 and player:getItemById(36170, 10) and player:getItemById(11196, 2) and player:getItemById(36167, 5) then + player:removeItem(36170, 10) + player:removeItem(11196, 2) + player:removeItem(36167, 5) + npcHandler:say({"Thank you this stage of the ritual is complete."}, cid)-- It needs to be revised, it's not the same as the global + player:setStorageValue(Storage.Kilmaresh.Eighth.Narsai, 3) + npcHandler.topic[cid] = 4 + playerTopic[cid] = 4 + else + npcHandler:say({"Sorry."}, cid)-- It needs to be revised, it's not the same as the global + end +end +return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/navigator.lua b/data/npc/scripts/navigator.lua new file mode 100644 index 00000000000..bca1e6e51e2 --- /dev/null +++ b/data/npc/scripts/navigator.lua @@ -0,0 +1,92 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function creatureSayCallback(cid, type, msg) + if(not npcHandler:isFocused(cid)) then + return false + end + + local player = Player(cid) + + if(msgcontains(msg, "flou")) then + if(getPlayerStorageValue(cid, Storage.Navigator) < 1) then + npcHandler:say("Lhnjei gouthn naumpi! I know why you are here. I can {explain} everything.", cid) + npcHandler.topic[cid] = 1 + end + elseif(msgcontains(msg, "explain")) then + if(npcHandler.topic[cid] == 1) then + npcHandler:say("By entering this place, you have earned the right to learn what this is all about. This is a long story. Are you sure you want to hear this, {yes}?", cid) + npcHandler.topic[cid] = 2 + end + elseif(msgcontains(msg, "helmet")) then + if(npcHandler.topic[cid] == 7) then + selfSay("NAAAAARGH. If you promise to leave me alone and NOT TO TELL MY SECRET to anyone - you can have one. ...", cid) + selfSay("NO! Not the one I'm wearing. I am BOUND to this device. This suit has granted me a longer life. However, once you have spent a certain time with this - there is no turning back if you know what I mean. ...", cid) + selfSay("The armor will merge with your very body. Holding you captive, holding your life in its hands like a ransom. ...", cid) + npcHandler:say("Using Deepling craft and various components from down here, I created several spare helmets - just in case this one gets damaged. If you return that small golden anchor to me, you can have one. Will you?", cid) + npcHandler.topic[cid] = 8 + end + elseif(msgcontains(msg, "no")) then + if(npcHandler.topic[cid] == 3) then + selfSay("When none of my men returned, I forced myself to make a decision. Either dying on this dead ship or plunging into the liquid black beneath. ...", cid) + selfSay("In my desperation my thoughts fell onto a strange armor - a gift from a trader we dealt with just before the storm. Strange ornaments and fish-like elements decorated this armor. We thought it would fit just perfectly into the captain's cabin. ...", cid) + selfSay("He said something like a 'blessed breath' and 'to subdue the drift'. We thought he wanted to sell us worthless decoration and make it look interesting. If I had only listened to what he said. ...", cid) + selfSay("I figured that this thing would have something to do with diving or at least protect me from the icy water. I put it on, grabbed a shimmer glower from our storage to light my path and jumped in. ...", cid) + npcHandler:say("Do you want me to go on?", cid) + npcHandler.topic[cid] = 4 + end + elseif(msgcontains(msg, "yes")) then + if(npcHandler.topic[cid] == 2) then + selfSay("I was once captain of a ship, the Skyflare. We were traders for King Tibianus and on our way home when we got into a storm. We fought hard to escape the cold grip of the sea. ...", cid) + selfSay("I myself did what I could to navigate the Skyflare out of this mess. They depended on me. Me, the navigator. And I succeeded. ...", cid) + selfSay("However, when the sea calmed down and the rain was finally gone, we recognised that our ship wouldn't move. It wasn't my fault. ...", cid) + selfSay("There was a strong gale and we could already see this island on the horizon. There were seagulls all around the Skyflare to lead us to dry land. But the ship did not move a single inch. It was NOT my fault. ...", cid) + selfSay("We dived under the bow and saw that it was stuck right on the tip of a sharp rock. The world below us was treacherous, we could see large underwater mountains and a labyrinthine system of caves and holes. ...", cid) + selfSay("Some of my men panicked and hijacked the dinghies to reach the island, others tried to swim. I remained on the ship. It was not my FAULT. It was not. ...", cid) + npcHandler:say("Do you have enough, can I stop?", cid) + npcHandler.topic[cid] = 3 + elseif(npcHandler.topic[cid] == 4) then + selfSay("Hmpf. The armor was working. After some time I was surrounded by darkness and could only see as far as my shimmer glower would me allow to. But I didn't feel the cold - I could even breathe through that helmet. ...", cid) + selfSay("I dived into the deep black. Across rugged mountains, vast fields of kelp, swarms of strange fish. ...", cid) + selfSay("And then I laid my eyes on a creature I have never seen before. I now know that they call themselves Njey. You would call them the 'Creatures of the Deep' or 'Deeplings'. ...", cid) + npcHandler:say("I am now convinced that when they first saw me descending in that suit with the light of the shimmer glower encompassing me, they took me for their God King Qjell. And that's when it all started to make sense. Don't you agree?", cid) + npcHandler.topic[cid] = 5 + elseif(npcHandler.topic[cid] == 5) then + selfSay("Of course you do. And they did, too. They obeyed me. They adored me. They followed me. ...", cid) + selfSay("I learnt everything about their culture, their life, their goals and their problems. I found out about vile insect-like creatures inhabiting the surface of the island. And their waiting for the return of Qjell. ...", cid) + selfSay("I practically rewrote their history. I WAS THE SECOND COMING. I WAS QJELL. I, THE NAVIGATOR. ...", cid) + npcHandler:say("And I navigated them out of their miserable lives. Away from their petty interests. I led them to a greater purpose - to form chaos out of order, to bring back the storm to the seas and to make THINGS MOVE. Do you want to hear the rest as well?", cid) + npcHandler.topic[cid] = 6 + elseif(npcHandler.topic[cid] == 6) then + selfSay("I control EVERYTHING from this room, navigating the fate of this land for more than a century now. Can you see all these funnels? My voice travels through them and throughout everything down here! ...", cid) + selfSay("The stones on the beach? The trader up there? That was ME ALL THE TIME! I lured YOU into creating all this chaos up there and down here! ...", cid) + npcHandler:say("You thought you could choose sides? Think again! I nearly led you into the destruction of two species! ME, THE NAVIGATOR! I CONTROL YOU, I OWN YOU! QJELL AFAR GOU JEY!", cid) + npcHandler.topic[cid] = 7 + elseif(npcHandler.topic[cid] == 8) then + npcHandler:say("Then take this one. And remember: DO NOT TELL ANYONE ABOUT ME OR ANYTHING YOU HAVE HEARD HERE TODAY.", cid) + player:addOutfitAddon(464, 2) + player:addOutfitAddon(463, 2) + setPlayerStorageValue(cid, Storage.Navigator, 4) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/neill.lua b/data/npc/scripts/neill.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/neill.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/nelliem.lua b/data/npc/scripts/nelliem.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/nelliem.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/nelly.lua b/data/npc/scripts/nelly.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/nelly.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/nemal.lua b/data/npc/scripts/nemal.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/nemal.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/nezil.lua b/data/npc/scripts/nezil.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/nezil.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/nibble.lua b/data/npc/scripts/nibble.lua new file mode 100644 index 00000000000..e88e935b7eb --- /dev/null +++ b/data/npc/scripts/nibble.lua @@ -0,0 +1,20 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/nicholas.lua b/data/npc/scripts/nicholas.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/nicholas.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/nielson.lua b/data/npc/scripts/nielson.lua new file mode 100644 index 00000000000..2d0f1973f9b --- /dev/null +++ b/data/npc/scripts/nielson.lua @@ -0,0 +1,80 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + {text = 'Passages to Senja, Folda and Vega.'} +} + +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, cost, destination) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, + { + npcHandler = npcHandler, + text = "Do you want a round-trip passage to " .. keyword:titleCase() .. " for |TRAVELCOST|?", + cost = cost, + discount = "postman" + } + ) + travelKeyword:addChildKeyword({"yes"}, StdModule.travel, + { + npcHandler = npcHandler, + text = "Have a nice trip!", + premium = false, + cost = cost, + discount = "postman", + destination = destination + } + ) + travelKeyword:addChildKeyword({"no"}, StdModule.say, + { + npcHandler = npcHandler, + text = "You shouldn't miss the experience.", + reset = true + } + ) +end + +addTravelKeyword("vega", 20, {x = 32020, y = 31692, z = 7}) +addTravelKeyword("senja", 20, {x = 32128, y = 31664, z = 7}) +addTravelKeyword("folda", 20, {x = 32046, y = 31578, z = 7}) + +-- Basic +keywordHandler:addKeyword({"passage"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Where do you want to go today? We serve the routes to {Folda}, {Senja} and {Vega} and back to Tibia." + } +) +keywordHandler:addKeyword({"job"}, StdModule.say, + { + npcHandler = npcHandler, + text = "We are ferrymen. We transport goods and passengers to the Ice Islands." + } +) +keywordHandler:addKeyword({"captain"}, StdModule.say, + { + npcHandler = npcHandler, + text = "We are ferrymen. We transport goods and passengers to the Ice Islands." + } +) + +npcHandler:setMessage(MESSAGE_GREET, "Ahoi, young man |PLAYERNAME| and welcome to the Nordic Tibia Ferries. If you need a {passage}, let me know.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye. You are welcome.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/nienna.lua b/data/npc/scripts/nienna.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/nienna.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/nilsor.lua b/data/npc/scripts/nilsor.lua new file mode 100644 index 00000000000..6e6dbde27d4 --- /dev/null +++ b/data/npc/scripts/nilsor.lua @@ -0,0 +1,193 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "svargrond") or msgcontains(msg, "passage") then + npcHandler:say("Do you want to go back to Svargrond?", cid) + npcHandler.topic[cid] = 10 + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 10 then + player:teleportTo(Position(32306, 31082, 7)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + end + end + + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.TheIceIslands.Questline) == 20 then + npcHandler:say({ + "I am in dire need of help. A plague has befallen my dogs. I even called a druid of Carlin for help but all he could do was to recommend some strong medicine ...", + "The thing is the ingredients of the medicine are extremely rare and some only exist in far away and distant lands. If you could help me collecting the ingredients, I would be eternally grateful ...", + "Are you willing to help me?" + }, cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 28 then + npcHandler:say({ + "Thank you. Now I have all necessary ingredients. As a reward I grant you the use of our dog sled, which is located to the east of here. ...", + "The dogs can be a bit moody, but if you always carry some ham with you there shouldnt be any problems. Oh, and Hjaern might have a mission for you. So maybe you go and talk to him." + }, cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 29) + player:setStorageValue(Storage.TheIceIslands.Mission07, 1) -- Questlog The Ice Islands Quest, The Secret of Helheim + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) > 20 and player:getStorageValue(Storage.TheIceIslands.Questline) < 28 then + npcHandler:say("What for ingredient do you have?", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("I have now no mission for you.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "waterskin") then + npcHandler:say("Do you want to buy a waterskin for 25 gold?", cid) + npcHandler.topic[cid] = 2 + + elseif msgcontains(msg, "cactus") then + if player:getStorageValue(Storage.TheIceIslands.Questline) == 21 then + npcHandler:say("You will find this kind of cactus at places that are called deserts. Only an ordinary kitchen knife will be precise enough to produce the ingredient weneed. Do you have a part of that cactus with you?", cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, "water") then + if player:getStorageValue(Storage.TheIceIslands.Questline) == 22 then + npcHandler:say({ + "You will need a specially prepared waterskin to collect the water. You can buy one from me ...", + "Use it on a geyser that is NOT active. The water of active geysers is far too hot. You can find inactive geysers on Okolnir. Do you have some geyser water with you?" + }, cid) + npcHandler.topic[cid] = 4 + end + elseif msgcontains(msg, "sulphur") then + if player:getStorageValue(Storage.TheIceIslands.Questline) == 23 then + npcHandler:say("I need fine sulphur of an inactive lava hole. No other sulphur will do. Use an ordinary kitchen spoon on an inactive lava hole. Do you have fine sulphur with you?", cid) + npcHandler.topic[cid] = 5 + end + elseif msgcontains(msg, "herb") then + if player:getStorageValue(Storage.TheIceIslands.Questline) == 24 then + npcHandler:say("The frostbite herb is a local plant but its quite rare. You can find it on mountain peaks. You will need to cut it with a fine kitchen knife. Do you have a frostbite herb with you?", cid) + npcHandler.topic[cid] = 6 + end + elseif msgcontains(msg, "blossom") then + if player:getStorageValue(Storage.TheIceIslands.Questline) == 25 then + npcHandler:say("The purple kiss is a plant that grows in a place called jungle. You will have to use a kitchen knife to harvest its blossom. Do you have a blossom of a purple kiss with you?", cid) + npcHandler.topic[cid] = 7 + end + elseif msgcontains(msg, "hydra tongue") then + if player:getStorageValue(Storage.TheIceIslands.Questline) == 26 then + npcHandler:say("The hydra tongue is a common pest plant in warmer regions. You might find one in a shop. Do you have a hydra tongue with you?", cid) + npcHandler.topic[cid] = 8 + end + elseif msgcontains(msg, "spores") then + if player:getStorageValue(Storage.TheIceIslands.Questline) == 27 then + npcHandler:say("The giant glimmercap mushroom exists in caves and other preferably warm and humid places. Use an ordinary kitchen spoon on a mushroom to collectits spores. Do you have the glimmercap spores?", cid) + npcHandler.topic[cid] = 9 + end + + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "A thousand thanks in advance. I need no less than 7 ingredients for the cure. You can ask me about each specifically ...", + "I need a part of the sun adorer cactus, a vial of geyser water, sulphur of a lava hole, a frostbite herb, a blossom of a purple kiss, a hydra tongue and spores of a giant glimmercap mushroom ...", + "Turn them in individually by talking about them to me. As soon as I obtained them all, talk to me about the medicine. First time bring a Part of the Sun Adorer {Cactus}." + }, cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 21) + player:setStorageValue(Storage.TheIceIslands.Mission06, 1) -- Questlog The Ice Islands Quest, Nibelor 5: Cure the Dogs + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + if player:getMoney() + player:getBankBalance() >= 25 then + player:removeMoneyNpc(25) + npcHandler:say("Here you are. A waterskin!", cid) + player:addItem(7286, 1) + else + npcHandler:say("You don't have enough money.", cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 3 then + if player:removeItem(7245, 1) then + npcHandler:say("Thank you for this ingredient. Now bring me Geyser {Water} in a Waterskin. ", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 22) + player:setStorageValue(Storage.TheIceIslands.Mission06, 2) -- Questlog The Ice Islands Quest, Nibelor 5: Cure the Dogs + else + npcHandler:say("Come back when you have the ingredient.", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 4 then + if player:removeItem(7246, 1) then + npcHandler:say("Thank you for this ingredient. Now bring me Fine {Sulphur}.", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 23) + player:setStorageValue(Storage.TheIceIslands.Mission06, 3) -- Questlog The Ice Islands Quest, Nibelor 5: Cure the Dogs + else + npcHandler:say("Come back when you have the ingredient.", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 5 then + if player:removeItem(7247, 1) then + npcHandler:say("Thank you for this ingredient. Now bring me the Frostbite {Herb}", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 24) + player:setStorageValue(Storage.TheIceIslands.Mission06, 4) -- Questlog The Ice Islands Quest, Nibelor 5: Cure the Dogs + else + npcHandler:say("Come back when you have the ingredient.", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 6 then + if player:removeItem(7248, 1) then + npcHandler:say("Thank you for this ingredient Now bring me Purple Kiss {Blossom}.", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 25) + player:setStorageValue(Storage.TheIceIslands.Mission06, 5) -- Questlog The Ice Islands Quest, Nibelor 5: Cure the Dogs + else + npcHandler:say("Come back when you have the ingredient.", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 7 then + if player:removeItem(7249, 1) then + npcHandler:say("Thank you for this ingredient. Now bring me the {Hydra Tongue}", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 26) + player:setStorageValue(Storage.TheIceIslands.Mission06, 6) -- Questlog The Ice Islands Quest, Nibelor 5: Cure the Dogs + else + npcHandler:say("Come back when you have the ingredient. ", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 8 then + if player:removeItem(7250, 1) then + npcHandler:say("Thank you for this ingredient. Now bring me {Spores} of a Giant Glimmercap Mushroom.", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 27) + player:setStorageValue(Storage.TheIceIslands.Mission06, 7) -- Questlog The Ice Islands Quest, Nibelor 5: Cure the Dogs + else + npcHandler:say("Come back when you have the ingredient.", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 9 then + if player:removeItem(7251, 1) then + npcHandler:say("Thank you for this ingredient. Now you finish your {mission}", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 28) + player:setStorageValue(Storage.TheIceIslands.Mission06, 8) -- Questlog The Ice Islands Quest, Nibelor 5: Cure the Dogs + else + npcHandler:say("Come back when you have the ingredient.", cid) + end + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] >= 2 then + npcHandler:say("Then come back when you have the ingredient.", cid) + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/nina.lua b/data/npc/scripts/nina.lua new file mode 100644 index 00000000000..d64b03e0ea8 --- /dev/null +++ b/data/npc/scripts/nina.lua @@ -0,0 +1,30 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'chosen'}, StdModule.say, {npcHandler = npcHandler, text = "The lizards here are the chosen ones of their kind. We believe them to be the strongest warriors in these lands.So I lead my people here to learn their ways. We are mere assassins but they are using foreign techniques and seem to be far more efficient"}) +keywordHandler:addAliasKeyword({'lizard'}) +keywordHandler:addKeyword({'fire dragon dojo'}, StdModule.say, {npcHandler = npcHandler, text = "We of the Grey Shadow clan are studying the ways of the Chosen. Our training is hard, encounters with the lizards often deadly. Every one of us fights on his own. Each one more deadly than the other. Under my lead we wil rise renewed, as the Shadow Nina."}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "I am Nina, leader of the Grey Shadow clan. Me and my followers, the Shadow Nina, are exploring the largely uncharted parts of the continent Zao."}) +keywordHandler:addAliasKeyword({'shadow nina'}) +keywordHandler:addAliasKeyword({'nina'}) +keywordHandler:addAliasKeyword({'grey shadow clan'}) + +npcHandler:setMessage(MESSAGE_GREET, "Beware, if you go any further you will have to fight a large group of Chosen. This place is called the Fire Dragon Dojo. Tread carefully since these are lizard training grounds.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Goodbye. Human. Being!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Goodbye. Human. Being!") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ninev.lua b/data/npc/scripts/ninev.lua new file mode 100644 index 00000000000..c7ae04a91a6 --- /dev/null +++ b/data/npc/scripts/ninev.lua @@ -0,0 +1,118 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Wooden Stake Quest +local stakeKeyword = keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'A blessed stake to defeat evil spirits? I do know an old prayer which is said to grant sacred power and to be able to bind this power to someone, or something. ...', + 'However, this prayer needs the combined energy of ten priests. Each of them has to say one line of the prayer. ...', + 'I could start with the prayer, but since the next priest has to be in a different location, you probably will have to travel a lot. ...', + 'Is this stake really important enough to you so that you are willing to take this burden?', + }}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == -1 end + ) + stakeKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Alright, I guess you need a stake first. Maybe Gamon can help you, the leg of a chair or something could just do. Try asking him for a stake, and if you have one, bring it back to me.', reset = true, ungreet = true}, nil, function(player) player:setStorageValue(Storage.FriendsandTraders.DefaultStart, 1) player:setStorageValue(Storage.FriendsandTraders.TheBlessedStake, 1) end) + +-- First prayer +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'I guess you couldn\'t convince Gamon to give you a stake, eh?'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 1 and player:getItemCount(5941) == 0 end) + +local stakeKeyword = keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes, I was informed what to do. Are you prepared to receive my line of the prayer?'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 1 end) + stakeKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'So receive my prayer: \'Light shall be near - and darkness afar\'. Now, bring your stake to Tibra in the Carlin church for the next line of the prayer. I will inform her what to do.', reset = true}, nil, + function(player) player:setStorageValue(Storage.FriendsandTraders.TheBlessedStake, 2) player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) end + ) + stakeKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'I will wait for you.', reset = true}) + +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You should visit Tibra in the Carlin church now.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 2 end) +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You already received my line of the prayer.'}) + +-- Twist of Fate +local blessKeyword = keywordHandler:addKeyword({'twist of fate'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'This is a special blessing I can bestow upon you once you have obtained at least one of the other blessings and which functions a bit differently. ...', + 'It only works when you\'re killed by other adventurers, which means that at least half of the damage leading to your death was caused by others, not by monsters or the environment. ...', + 'The {twist of fate} will not reduce the death penalty like the other blessings, but instead prevent you from losing your other blessings as well as the amulet of loss, should you wear one. It costs the same as the other blessings. ...', + 'Would you like to receive that protection for a sacrifice of |PVPBLESSCOST| gold, child?' + }}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the protection of the twist of fate, pilgrim.', cost = '|PVPBLESSCOST|', bless = 1}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Adventurer Stone +keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Keep your adventurer\'s stone well.'}, function(player) return player:getItemById(18559, true) end) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for free?'}, function(player) return player:getStorageValue(Storage.AdventurersGuild.FreeStone.Quentin) ~= 1 end) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, nil, function(player) player:addItem(18559, 1) player:setStorageValue(Storage.AdventurersGuild.FreeStone.Quentin, 1) end) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for 30 gold?'}) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, + function(player) return player:getMoney() + player:getBankBalance() >= 30 end, + function(player) if player:removeMoneyNpc(30) then player:addItem(18559, 1) end end + ) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, you don\'t have enough money.', reset = true}) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.'}, function(player) return player:hasBlessing(2) end) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin will provide you with the embrace of Tibia.'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, young |PLAYERNAME|! If you are heavily wounded or poisoned, I can {heal} you for free or you want the {adventurer stone}?') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Remember: If you are heavily wounded or poisoned, I can heal you for free.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'May the gods bless you, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ninos.lua b/data/npc/scripts/ninos.lua new file mode 100644 index 00000000000..8b69459c0ff --- /dev/null +++ b/data/npc/scripts/ninos.lua @@ -0,0 +1,49 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Welcome to the post office!' }, + { text = 'If you need help with letters or parcels, just ask me. I can explain everything.' }, + { text = 'Hey, send a letter to your friend now and then. Keep in touch, you know.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if msgcontains(msg, "measurements") then + local player = Player(cid) + if player:getStorageValue(Storage.Postman.Mission07) >= 1 and player:getStorageValue(Storage.Postman.MeasurementsBenjamin) ~= 1 then + npcHandler:say("Oh they don't change that much since in the old days as... ", cid) + player:setStorageValue(Storage.Postman.Mission07, player:getStorageValue(Storage.Postman.Mission07) + 1) + player:setStorageValue(Storage.Postman.MeasurementsBenjamin, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("...", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Hello. How may I help you |PLAYERNAME|? Ask me for a {trade} if you want to buy something. I can also explain the {mail} system.") +npcHandler:setMessage(MESSAGE_FAREWELL, "It was a pleasure to help you, |PLAYERNAME|.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/nokmir.lua b/data/npc/scripts/nokmir.lua new file mode 100644 index 00000000000..1225ae5d4a1 --- /dev/null +++ b/data/npc/scripts/nokmir.lua @@ -0,0 +1,67 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.HiddenCityOfBeregar.JusticeForAll) < 1 then + npcHandler:say("I don't see how you could help me. I'm in deep, deep trouble. I'm accused of having stolen a {ring} from Rerun, but I haven't.", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.HiddenCityOfBeregar.JusticeForAll) == 5 then + player:setStorageValue(Storage.HiddenCityOfBeregar.JusticeForAll, 6) + player:setStorageValue(Storage.HiddenCityOfBeregar.DoorNorthMine, 1) + npcHandler:say("WHAT?! I can't believe it. You saved my life... well, at least one week of it 'cause that would have been the time I had to spend in jail. If you want to, you can pass the door now and take a look at the northern mines. Have fun!", cid) + end + elseif msgcontains(msg, "ring") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "He said he still had it after work. On that evening, {Grombur}, {Rerun} and me opened a cask of beer in one of the mine tunnels. We had a fun evening there. ...", + "On the next day, the guards brought me to emperor {Rehal}, and Rerun was there, too. He said I had stolen his ring. I'd never steal, you have to believe me." + }, cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, "grombur") then + if npcHandler.topic[cid] == 2 then + npcHandler:say("Maybe Grombur knows more than me. The thing is he won't talk to me, and he will surely not accuse his best friend as a liar. What a dilemma!", cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, "rerun") then + if npcHandler.topic[cid] == 3 then + npcHandler:say("He's a miner in the southern wing. Maybe he has lost the ring there... but even if I find the ring, no one will believe me. Someone should talk to Grombur. He's Rerun's best friend.", cid) + npcHandler.topic[cid] = 4 + end + elseif msgcontains(msg, "rehal") then + if npcHandler.topic[cid] == 4 then + player:setStorageValue(Storage.HiddenCityOfBeregar.DefaultStart, 1) + player:setStorageValue(Storage.HiddenCityOfBeregar.JusticeForAll, 1) + npcHandler:say("He's a good emperor but I doubt he is wise enough to see the truth behind that false accusation against me. If just someone would find out the truth about that whole mess.", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, "See you my friend.") +npcHandler:setMessage(MESSAGE_FAREWELL, "See you my friend.") +npcHandler:setMessage(MESSAGE_GREET, "You are....kind of tall! Hello.") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/nomad.lua b/data/npc/scripts/nomad.lua new file mode 100644 index 00000000000..1b4e1539a64 --- /dev/null +++ b/data/npc/scripts/nomad.lua @@ -0,0 +1,72 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Heart of the Mountain +local blessKeyword = keywordHandler:addKeyword({'heart'}, StdModule.say, {npcHandler = npcHandler, text = 'Would you like to receive that protection for a sacrifice of |BLESSCOST| gold, child?'}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the Heart of the Mountain, pilgrim.', cost = '|BLESSCOST|', bless = 8}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, noble |PLAYERNAME|') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good Bye, noble |PLAYERNAME|') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good Bye, noble |PLAYERNAME|') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/noodles.lua b/data/npc/scripts/noodles.lua new file mode 100644 index 00000000000..9466be13b05 --- /dev/null +++ b/data/npc/scripts/noodles.lua @@ -0,0 +1,77 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Grrrrrrr.' }, + { text = '' }, + { text = '' }, + { text = 'Woof! Woof!' }, + { text = 'Wooof!' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "banana skin") then + if player:getStorageValue(Storage.Postman.Mission06) == 7 then + if player:getItemCount(2219) > 0 then + npcHandler:say("", cid) + npcHandler.topic[cid] = 1 + end + end + elseif msgcontains(msg, "dirty fur") then + if player:getStorageValue(Storage.Postman.Mission06) == 8 then + if player:getItemCount(2220) > 0 then + npcHandler:say("", cid) + npcHandler.topic[cid] = 2 + end + end + elseif msgcontains(msg, "mouldy cheese") then + if player:getStorageValue(Storage.Postman.Mission06) == 9 then + if player:getItemCount(2235) > 0 then + npcHandler:say("", cid) + npcHandler.topic[cid] = 3 + end + end + elseif msgcontains(msg, "like") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Woof!", cid) + player:setStorageValue(Storage.Postman.Mission06, 8) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say("Woof!", cid) + player:setStorageValue(Storage.Postman.Mission06, 9) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + npcHandler:say("Meeep! Grrrrr! ", cid) + player:setStorageValue(Storage.Postman.Mission06, 10) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, " Woof! ") +npcHandler:setMessage(MESSAGE_FAREWELL, "Woof! ") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Woof! ") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/noozer.lua b/data/npc/scripts/noozer.lua new file mode 100644 index 00000000000..ec6b5eff9b2 --- /dev/null +++ b/data/npc/scripts/noozer.lua @@ -0,0 +1,71 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local playerTopic = {} +local function greetCallback(cid) +local player = Player(cid) + + npcHandler:setMessage(MESSAGE_GREET, "Hm? Oh! Oh, yes a... visitor! Intruder? Benefactor...? Wha- what are you? If you want to {pass} through this {cave}, I may have to disappoint you. Or maybe not. It... depends. So, just passing through?.") + playerTopic[cid] = 1 + npcHandler:addFocus(cid) + +return true +end + + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + npcHandler.topic[cid] = playerTopic[cid] + local player = Player(cid) + + -- Começou a quest + if msgcontains(msg, "pass") and npcHandler.topic[cid] == 1 then + npcHandler:say({"Yes, yes. Or wait - why do you want to.. ah what does it matter. So you want to get through these {caves}, fine. But be warned! ...", + "...wait a second, I lost it. What was I going to say again? Ah yes - DANGEROUS! These. Caves. Are. Dangerous. No way you get out alive. Ever. Again. ...", + "Also you should not disturb those... people down there. Yeah. They... hm, wait, they - who are they again? Hey! Who are you? Are you talking to me?! Ah, ah... oh yes, I remember. ...", + "Wait - I am the guardian here, yes! The keeper of... something... or another, yes, I... guard this place. With my life. Don't I? Of course! ...", + "Is, er... this the moment where I should try to... stop you? Yes? No? Ah, you know what - you go down there, those guys are angry as dung anyway. Try your luck, return to me when you're done. If you still can. Or not."}, cid) + if player:getStorageValue(Storage.CultsOfTibia.Questline) < 1 then + player:setStorageValue(Storage.CultsOfTibia.Questline, 1) + end + if player:getStorageValue(Storage.CultsOfTibia.Misguided.Mission) < 2 then + player:setStorageValue(Storage.CultsOfTibia.Misguided.Mission, 2) + player:setStorageValue(Storage.CultsOfTibia.Misguided.AccessDoor, 1) + end + elseif msgcontains(msg, "cave") and npcHandler.topic[cid] == 1 then + npcHandler:say({"I was stationed in this cave to... guard something. Right now I am not even sure what that was."}, cid) + elseif msgcontains(msg, "job") and npcHandler.topic[cid] == 1 then + npcHandler:say({"Then don't waste my time. I'm doing some important... business... here. Actually... where am I? If I find out, I will be even more angry than I am now. Out of my sight."}, cid) + elseif msgcontains(msg, "mission") and npcHandler.topic[cid] == 1 then + npcHandler:say({"I was on a mission, too - I guess. It was all quite blurry back then. Maybe I'll leave this place after I recovered completely. I have to find out what happened to me."}, cid) + end +return true +end + + + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/nor.lua b/data/npc/scripts/nor.lua new file mode 100644 index 00000000000..b7ee658e028 --- /dev/null +++ b/data/npc/scripts/nor.lua @@ -0,0 +1,36 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "crystal") then + if player:getStorageValue(Storage.TheIceIslands.Mission08) == 2 then + npcHandler:say("Here, take the memory crystal and leave immediately.", cid) + npcHandler.topic[cid] = 0 + player:addItem(7281, 1) + player:setStorageValue(Storage.TheIceIslands.Mission08, 3) -- Questlog The Ice Islands Quest, The Contact + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/norbert.lua b/data/npc/scripts/norbert.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/norbert.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/norf.lua b/data/npc/scripts/norf.lua new file mode 100644 index 00000000000..5895285d5c5 --- /dev/null +++ b/data/npc/scripts/norf.lua @@ -0,0 +1,69 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Spiritual Shielding +local blessKeyword = keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'Here in the whiteflower temple you may receive the blessing of spiritual shielding. But we must ask of you to sacrifice |BLESSCOST| gold. Are you still interested?'}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the shielding of your spirit, pilgrim.', cost = '|BLESSCOST|', bless = 5}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) +keywordHandler:addAliasKeyword({'shield'}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.'}, function(player) return player:hasBlessing(2) end) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin will provide you with the embrace of Tibia.'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, pilgrim. How may I {help} you? Are you in need of {healing}?') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/norma.lua b/data/npc/scripts/norma.lua new file mode 100644 index 00000000000..7382c407e7a --- /dev/null +++ b/data/npc/scripts/norma.lua @@ -0,0 +1,162 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Great drinks and snacks at fair prices!' }, + { text = 'You know you want a party after all that tiring hunting!' }, + { text = ' ... are a girl\'s best friieeend...' }, + { text = 'Sing and dance at my bar! Yeah!' }, + { text = 'Best place in town! Come to my bar!' } +} +npcHandler:addModule(VoiceModule:new(voices)) + +--[[ +addon +Pretty, isn't it? I made it myself, but I could teach you how to do that if you like. What do you say? +hat +13:44 Norma: Pretty, isn't it? I made it myself, but I could teach you how to do that if you like. What do you say? +yes +13:44 Norma: Okay, here we go, listen closely! I need a few things... a basic hat of course, maybe a legion helmet would do. Then about 100 chicken feathers... and 50 honeycombs as glue. That's it, come back to me once you gathered it!! +]] + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "addon") or msgcontains(msg, "outfit") or msgcontains(msg, "hat") then + local addonProgress = player:getStorageValue(Storage.OutfitQuest.Citizen.AddonHat) + if addonProgress < 1 then + npcHandler:say("Pretty, isn't it? My friend Amber taught me how to make it, but I could help you with one if you like. What do you say?", cid) + npcHandler.topic[cid] = 1 + elseif addonProgress == 1 then + npcHandler:say("Oh, you're back already? Did you bring a legion helmet, 100 chicken feathers and 50 honeycombs?", cid) + npcHandler.topic[cid] = 2 + elseif addonProgress == 2 then + npcHandler:say('Pretty hat, isn\'t it?', cid) + end + return true + end + + if npcHandler.topic[cid] == 1 then + if msgcontains(msg, 'yes') then + player:setStorageValue(Storage.OutfitQuest.Ref, math.max(0, player:getStorageValue(Storage.OutfitQuest.Ref)) + 1) + player:setStorageValue(Storage.OutfitQuest.Citizen.AddonHat, 1) + player:setStorageValue(Storage.OutfitQuest.Citizen.MissionHat, 1) + npcHandler:say('Okay, here we go, listen closely! I need a few things... a basic hat of course, maybe a legion helmet would do. Then about 100 chicken feathers... and 50 honeycombs as glue. That\'s it, come back to me once you gathered it!', cid) + else + npcHandler:say('Aw, I guess you don\'t like feather hats. No big deal.', cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, 'yes') then + if player:getItemCount(2480) < 1 then + npcHandler:say('Sorry, but I can\'t see a legion helmet.', cid) + elseif player:getItemCount(5890) < 100 then + npcHandler:say('Sorry, but you don\'t enough chicken feathers.', cid) + elseif player:getItemCount(5902) < 50 then + npcHandler:say('Sorry, but you don\'t have enough honeycombs.', cid) + else + npcHandler:say('Great job! That must have taken a lot of work. Okay, you put it like this... then glue like this... here!', cid) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + + player:removeItem(2480, 1) + player:removeItem(5902, 50) + player:removeItem(5890, 100) + + player:addOutfitAddon(136, 2) + player:addOutfitAddon(128, 2) + + player:setStorageValue(Storage.OutfitQuest.Ref, math.min(0, player:getStorageValue(Storage.OutfitQuest.Ref) - 1)) + player:setStorageValue(Storage.OutfitQuest.Citizen.MissionHat, 0) + player:setStorageValue(Storage.OutfitQuest.Citizen.AddonHat, 2) + end + else + npcHandler:say('Maybe another time.', cid) + end + npcHandler.topic[cid] = 0 + end + + return true +end + +-- Basic keywords +keywordHandler:addKeyword({'hint'}, StdModule.rookgaardHints, {npcHandler = npcHandler}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, my name is {Norma}.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I used to be a merchant, but being a barkeeper is so much more fun. It\'s been my dream since I was a little girl.'}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = 'It\'s about |TIME|. Time just flies, doesn\'t it?'}) +keywordHandler:addKeyword({'merchant'}, StdModule.say, {npcHandler = npcHandler, text = 'To view the offers of a merchant, simply talk to him or her and ask for a {trade}. They will gladly show you their offers and also the things they buy from you.'}) +keywordHandler:addKeyword({'how', 'are', 'you'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'ve never been better! I love my new {job}!'}) +keywordHandler:addKeyword({'weapon'}, StdModule.say, {npcHandler = npcHandler, text = 'No sorry, I\'m out of that business. Please ask {Obi} or {Lee\'Delle} if you need a weapon.'}) +keywordHandler:addKeyword({'equipment'}, StdModule.say, {npcHandler = npcHandler, text = 'As an adventurer, you should always have at least a {backpack}, a {rope}, a {shovel}, a {weapon}, an {armor} and a {shield}.'}) +keywordHandler:addKeyword({'monster'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, the monsters are far away. Let\'s party now!'}) +keywordHandler:addKeyword({'dungeon'}, StdModule.say, {npcHandler = npcHandler, text = 'If you really want to talk about dungeons, visit Dallheim on the bridge near my bar.'}) +keywordHandler:addKeyword({'sewer'}, StdModule.say, {npcHandler = npcHandler, text = 'Ewww, I don\'t even want to think about the smell from the sewers right now!'}) +keywordHandler:addKeyword({'king'}, StdModule.say, {npcHandler = npcHandler, text = 'Oooh, I wouldn\'t dare gossiping about the king. He might have his spies here somewhere, you know.'}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = 'This is the world we live in, oh-oh-oh, and these are the hands we\'re given, oh-oh... oh, I\'m sorry, I got carried away!'}) +keywordHandler:addKeyword({'premium'}, StdModule.say, {npcHandler = npcHandler, text = 'As a premium adventurer you have many advantages, you should check them out!'}) +keywordHandler:addKeyword({'drink'}, StdModule.say, {npcHandler = npcHandler, text = 'I serve the best drinks in town! What\'s it gonna be, lemonade? Wine? Milk? Beer? Just ask me for a {trade}!'}) +keywordHandler:addKeyword({'temple'}, StdModule.say, {npcHandler = npcHandler, text = 'The temple is a good place to visit if you\'re in urgent need for healing.'}) + +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, the only help I could give you are some general {hints}. And a delicious {drink} along with it.'}) +keywordHandler:addAliasKeyword({'information'}) + +keywordHandler:addKeyword({'backpack'}, StdModule.say, {npcHandler = npcHandler, text = 'No sorry, I\'m out of that business. Please ask {Al Dee} or {Lee\'Delle} if you need equipment.'}) +keywordHandler:addAliasKeyword({'rope'}) +keywordHandler:addAliasKeyword({'shovel'}) +keywordHandler:addAliasKeyword({'fishing'}) + +keywordHandler:addKeyword({'armor'}, StdModule.say, {npcHandler = npcHandler, text = 'No sorry, I\'m out of that business. Please ask {Dixi} or {Lee\'Delle} if you need equipment.'}) +keywordHandler:addAliasKeyword({'shield'}) + +keywordHandler:addKeyword({'offer'}, StdModule.say, {npcHandler = npcHandler, text = 'Oh, would you like something to eat or drink? Ask me for a {trade} to see my offers!'}) +keywordHandler:addAliasKeyword({'sell'}) +keywordHandler:addAliasKeyword({'buy'}) +keywordHandler:addAliasKeyword({'wares'}) +keywordHandler:addAliasKeyword({'stuff'}) + +-- Names +keywordHandler:addKeyword({'mary'}, StdModule.say, {npcHandler = npcHandler, text = ''}) +keywordHandler:addKeyword({'al', 'dee'}, StdModule.say, {npcHandler = npcHandler, text = 'Al Dee treats his customers friendly, but he\'s badmouthing them once he had a few beers.'}) +keywordHandler:addKeyword({'amber'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m curious about her adventures. She really should come here more often!'}) +keywordHandler:addKeyword({'billy'}, StdModule.say, {npcHandler = npcHandler, text = 'He got lucky when Willie and him played a game of dice about who gets to farm on which side of the river. Ever since, Willie holds a grudge against him.'}) +keywordHandler:addKeyword({'willie'}, StdModule.say, {npcHandler = npcHandler, text = 'Hehe, that guy doesn\'t pretend to be anyone that he isn\'t. He is what he is - rude, but honest.'}) +keywordHandler:addKeyword({'tom'}, StdModule.say, {npcHandler = npcHandler, text = 'Oh shush! It\'s kinda disgusting when he walks in here with animal blood on his hands!'}) +keywordHandler:addKeyword({'seymour'}, StdModule.say, {npcHandler = npcHandler, text = 'What Seymour doesn\'t teach you is how much fun you can have here!'}) +keywordHandler:addKeyword({'zirella'}, StdModule.say, {npcHandler = npcHandler, text = 'I invited her to my bar, but she refused. Oh well, it was worth a try!'}) +keywordHandler:addKeyword({'santiago'}, StdModule.say, {npcHandler = npcHandler, text = 'I think that poor guy never gets a break from work. At least he never comes here.'}) +keywordHandler:addKeyword({'paulie'}, StdModule.say, {npcHandler = npcHandler, text = 'That guy seriously needs some partying and a girlfriend.'}) +keywordHandler:addKeyword({'oracle'}, StdModule.say, {npcHandler = npcHandler, text = 'The oracle is on the top floor of the academy. You should go there once you are level 8 to leave this island.'}) +keywordHandler:addKeyword({'obi'}, StdModule.say, {npcHandler = npcHandler, text = 'I think it\'s rather strange that he lives here with his granddaughter. No one\'s ever seen the parents of {Dixi}.'}) +keywordHandler:addKeyword({'norma'}, StdModule.say, {npcHandler = npcHandler, text = 'I hate that name, it sounds so boring. Almost like \'normal\'. I think I should change my name to something more exciting. Like... Marylin! Oh, what a glamorous sound!'}) +keywordHandler:addKeyword({'dixi'}, StdModule.say, {npcHandler = npcHandler, text = 'She told me that she dreams of leaving this island to go on a big adventure.'}) +keywordHandler:addKeyword({'loui'}, StdModule.say, {npcHandler = npcHandler, text = 'They tell me strange stories about him and some monsters in a hole. Weird!'}) +keywordHandler:addKeyword({'lee\'delle'}, StdModule.say, {npcHandler = npcHandler, text = 'That girl thinks that she is soooo special and \'high society\'. We used to be friends, but well, things change.'}) +keywordHandler:addKeyword({'hyacinth'}, StdModule.say, {npcHandler = npcHandler, text = 'That\'s probably someone I\'ll never see in my bar.'}) +keywordHandler:addKeyword({'cipfried'}, StdModule.say, {npcHandler = npcHandler, text = ' That monk with his holier-than-thou attitude hasn\'t anything against a good mug of wine now and then.'}) +keywordHandler:addKeyword({'dallheim'}, StdModule.say, {npcHandler = npcHandler, text = 'If you listen to him, you could get the impression my little bar is the devil himself. He says he has more work now keeping drunken adventurers in than monsters out of the city. Such an exaggeration!'}) +keywordHandler:addAliasKeyword({'zerbrus'}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Hey, where are you going? We\'ve just started!') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Come back soon!') +npcHandler:setMessage(MESSAGE_SENDTRADE, 'Take all the time you need to decide what you want!') +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, welcome! Have a seat! If you like a drink or something to eat, just ask me for a {trade}!') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/norman_the_foreman.lua b/data/npc/scripts/norman_the_foreman.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/norman_the_foreman.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/normod.lua b/data/npc/scripts/normod.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/normod.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/norris.lua b/data/npc/scripts/norris.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/norris.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/nurik.lua b/data/npc/scripts/nurik.lua new file mode 100644 index 00000000000..1c0ed2a134b --- /dev/null +++ b/data/npc/scripts/nurik.lua @@ -0,0 +1,69 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.ThievesGuild.Mission04) ~= 6 or player:getOutfit().lookType ~= 66 then + npcHandler:say('Excuse me, but I\'m waiting for someone important!', cid) + return false + end + + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, 'dwarven bridge') then + npcHandler:say('Wait a minute! Do I get that right? You\'re the owner of the dwarven bridge and you are willing to sell it to me??', cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + 'That\'s just incredible! I\'ve dreamed about acquiring the dwarven bridge since I was a child! Now my dream will finally become true. ...', + 'And you are sure you want to sell it? I mean really, really sure?' + }, cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say('How splendid! Do you have the necessary documents with you?', cid) + npcHandler.topic[cid] = 3 + elseif npcHandler.topic[cid] == 3 then + npcHandler:say('Oh my, oh my. I\'m so excited! So let\'s seal this deal as fast as possible so I can visit my very own dwarven bridge. Are you ready for the transaction?', cid) + npcHandler.topic[cid] = 4 + elseif npcHandler.topic[cid] == 4 then + local player = Player(cid) + if player:removeItem(8694, 1) then + player:addItem(8699, 1) + player:setStorageValue(Storage.ThievesGuild.Mission04, 7) + npcHandler:say({ + 'Excellent! Here is the painting you requested. It\'s quite precious to my father, but imagine his joy when I tell him about my clever deal! ...', + 'Now leave me alone please. I have to prepare for my departure. Now my family will not call me a squandering fool anymore!' + }, cid) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, 'It\'s .. It\'s YOU! At last!! So what\'s this special proposal you would like to make, my friend?') +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/nydala.lua b/data/npc/scripts/nydala.lua new file mode 100644 index 00000000000..358d64db402 --- /dev/null +++ b/data/npc/scripts/nydala.lua @@ -0,0 +1,24 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'furniture'}, StdModule.say, {npcHandler = npcHandler, text = "Well, as you can see, I sell furniture. Ask me for a {trade} if you're interested to see my wares."}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "My name is Nydala. I run this store."}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = "It is |TIME|. Do you need a clock for your house?"}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome to Carlin Furniture Store, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Have a look. Most furniture comes in handy kits. Just use them in your house to assemble the furniture. Do you want to see only a certain {type} of furniture?") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/nymph_challenging.lua b/data/npc/scripts/nymph_challenging.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/nymph_challenging.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/oberon's_bile.lua b/data/npc/scripts/oberon's_bile.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/oberon's_bile.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/oberon's_hate.lua b/data/npc/scripts/oberon's_hate.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/oberon's_hate.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/oberon's_ire.lua b/data/npc/scripts/oberon's_ire.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/oberon's_ire.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/oberon's_spite.lua b/data/npc/scripts/oberon's_spite.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/oberon's_spite.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/obi.lua b/data/npc/scripts/obi.lua new file mode 100644 index 00000000000..638f97220e3 --- /dev/null +++ b/data/npc/scripts/obi.lua @@ -0,0 +1,98 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Only quality steel and wood used for my weapons!' }, + { text = 'Buy your weapons here!' }, + { text = 'Selling and buying all sorts of weapons, come and have a look!' }, + { text = 'Give those monsters a good whipping with my weapons!' } +} +npcHandler:addModule(VoiceModule:new(voices)) + +-- Basic keywords +keywordHandler:addKeyword({'hint'}, StdModule.rookgaardHints, {npcHandler = npcHandler}) +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, how can I help you? Do you need some general {hints}? Or, if you\'re interested in a {trade}, just ask.'}) +keywordHandler:addKeyword({'information'}, StdModule.say, {npcHandler = npcHandler, text = 'What kind of information do you need? I could tell you about different topics such as {equipment}, {monsters} or {Rookgaard} in general.'}) +keywordHandler:addKeyword({'torch'}, StdModule.say, {npcHandler = npcHandler, text = '{Al Dee} sells torches.'}) +keywordHandler:addKeyword({'dungeon'}, StdModule.say, {npcHandler = npcHandler, text = 'Be careful down there! Make sure you bought enough {torches} and a {rope} or you might get lost.'}) +keywordHandler:addKeyword({'king'}, StdModule.say, {npcHandler = npcHandler, text = 'The king encouraged salesmen to travel here, but only I dared to take the risk, and a risk it was!'}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = 'It\'s about |TIME|. Yes, |TIME|. I\'m so sorry, I have no watches for sale.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Obi, just Obi, the honest merchant. If you like to {trade}, just ask.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m a merchant and the local {weapon} smith. If you like to see my quality wares or sell weapons to me, ask me for a {trade}.'}) +keywordHandler:addKeyword({'equipment'}, StdModule.say, {npcHandler = npcHandler, text = 'As an adventurer you should always have at least a {backpack}, a {rope}, a {shovel}, a {weapon}, an {armor} and a {shield}.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'If I were you, I\'d invest my money in quality steel rather than putting it in a so-called safe bank account!'}) +keywordHandler:addKeyword({'mainland'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, the mainland also consists of several continents. You can go there once you are level 8 and have talked to the {oracle}.'}) +keywordHandler:addKeyword({'rookgaard'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, Rookgaard. Home sweet home, that\'s what it became for me, but I will always miss {Thais} and {Sam}.'}) +keywordHandler:addKeyword({'thais'}, StdModule.say, {npcHandler = npcHandler, text = 'Oh, Thais, I\'ll be back. One day, I\'ll be back.'}) +keywordHandler:addKeyword({'sam'}, StdModule.say, {npcHandler = npcHandler, text = 'My good old cousin Sam. Oh, how I miss him.'}) +keywordHandler:addKeyword({'academy'}, StdModule.say, {npcHandler = npcHandler, text = 'I think good practice is better than reading a boring book. Of course, you will need proper {equipment} to be able to get practice!'}) +keywordHandler:addKeyword({'food'}, StdModule.say, {npcHandler = npcHandler, text = ' told them to let me sell food, but no! Sorry, you have to ask {Willie} or {Billy} on the farms west of here.'}) +keywordHandler:addKeyword({'monster'}, StdModule.say, {npcHandler = npcHandler, text = 'Good monsters to start with are rats. They live in the {sewers} under the village of {Rookgaard}.'}) +keywordHandler:addKeyword({'sewer'}, StdModule.say, {npcHandler = npcHandler, text = 'There are many sewer entrances throughout Rookgaard. One is right outside this shop and to the left. For more details about monsters and dungeons, best talk to one of the {guards}.'}) +keywordHandler:addKeyword({'guard'}, StdModule.say, {npcHandler = npcHandler, text = 'The bridge guard {Dallheim} is north of here, just follow the street, you can\'t miss it.'}) +keywordHandler:addKeyword({'merchant'}, StdModule.say, {npcHandler = npcHandler, text = 'Sadly, not many merchants are as honest as I am.'}) +keywordHandler:addKeyword({'potion'}, StdModule.say, {npcHandler = npcHandler, text = 'I wish I could help you with that, but no, I was told to stick to weapons. Go see {Lily}.'}) +keywordHandler:addKeyword({'blueberr'}, StdModule.say, {npcHandler = npcHandler, text = 'There are many blueberry bushes in and around this village. Nature\'s for free.'}) +keywordHandler:addKeyword({'how', 'are', 'you'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m fine. It\'s a little hot near the crucible, but I enjoy the sound of forging {weapons}.'}) +keywordHandler:addKeyword({'sell'}, StdModule.say, {npcHandler = npcHandler, text = 'Just ask me for a {trade} to see which things I buy from you.'}) + +keywordHandler:addKeyword({'armor'}, StdModule.say, {npcHandler = npcHandler, text = 'Oh, just upstairs. My granddaughter {Dixi} is in charge of selling armors and shields.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addAliasKeyword({'helmet'}) + +keywordHandler:addKeyword({'weapon'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes, I\'m selling weapons. Just ask me for a {trade} to see my offers and the things I buy from you.'}) + +keywordHandler:addKeyword({'gold'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, no gold, no deal. Earn gold by fighting {monsters} and picking up the things they carry. Sell it to {merchants} to make profit!'}) +keywordHandler:addAliasKeyword({'money'}) + +keywordHandler:addKeyword({'rope'}, StdModule.say, {npcHandler = npcHandler, text = 'I wish I could help you with that, but no, I was told to stick to weapons. Go see {Al Dee} or {Lee\'Delle}.'}) +keywordHandler:addAliasKeyword({'shovel'}) +keywordHandler:addAliasKeyword({'backpack'}) +keywordHandler:addAliasKeyword({'fishing'}) + +keywordHandler:addKeyword({'buy'}, StdModule.say, {npcHandler = npcHandler, text = 'I sell {weapons} of all kinds. Just ask me for a {trade} if you like to see my offers.'}) +keywordHandler:addAliasKeyword({'stuff'}) +keywordHandler:addAliasKeyword({'wares'}) +keywordHandler:addAliasKeyword({'offer'}) + +-- Names +keywordHandler:addKeyword({'norma'}, StdModule.say, {npcHandler = npcHandler, text = 'I don\'t know how anyone could give up the flourishing business she led. She should have listened to me and find someone who continues that business for her.'}) +keywordHandler:addKeyword({'loui'}, StdModule.say, {npcHandler = npcHandler, text = 'I told him there was no danger, but he wouldn\'t listen to me, no one listens to me.'}) +keywordHandler:addKeyword({'santiago'}, StdModule.say, {npcHandler = npcHandler, text = 'I suggested him opening a tourist guide company with me, Obi\'s and Santiago\'s, but he didn\'t approve. I really don\'t understand why.'}) +keywordHandler:addKeyword({'zirella'}, StdModule.say, {npcHandler = npcHandler, text = 'An old woman shouldn\'t be treated like that, no way, that\'s bad.'}) +keywordHandler:addKeyword({'al', 'dee'}, StdModule.say, {npcHandler = npcHandler, text = 'Oh, this guy is so greedy, so greedy. Ripping off poor adventurers like you!'}) +keywordHandler:addKeyword({'amber'}, StdModule.say, {npcHandler = npcHandler, text = 'She is beautiful, very, very beautiful. I hope I can impress her somehow.'}) +keywordHandler:addKeyword({'billy'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s just like his cousin {Willie}.'}) +keywordHandler:addKeyword({'willie'}, StdModule.say, {npcHandler = npcHandler, text = 'This guy doesn\'t understand that he should entrust me with the food business, too. He really should do. Then he had time for his farm.'}) +keywordHandler:addKeyword({'cipfried'}, StdModule.say, {npcHandler = npcHandler, text = 'He shouldn\'t heal people for free, no he shouldn\'t. That would be a great source of income for the village that could be invested in enhancing the smithy.'}) +keywordHandler:addKeyword({'dixi'}, StdModule.say, {npcHandler = npcHandler, text = 'Oh, what an endearing little girl, and she\'s working so hard to help me, even without receiving payment. Such a sweet little girl!'}) +keywordHandler:addKeyword({'hyacinth'}, StdModule.say, {npcHandler = npcHandler, text = 'I don\'t like him, actually I dislike him deeply. He is so greedy that he doesn\'t want to share his profit he gains from health potions.'}) +keywordHandler:addKeyword({'lee\'delle'}, StdModule.say, {npcHandler = npcHandler, text = 'She ruins the market with her offers! This is bad for us honest merchants, really bad.'}) +keywordHandler:addKeyword({'lily'}, StdModule.say, {npcHandler = npcHandler, text = 'I knew it! I knew she would try to get the monopoly on potions in this village! But no one has listened to me!'}) +keywordHandler:addKeyword({'oracle'}, StdModule.say, {npcHandler = npcHandler, text = 'The oracle, ah, such a weird being! It will lead you off this island once you are level 8, yes it will, mark my words.'}) +keywordHandler:addKeyword({'paulie'}, StdModule.say, {npcHandler = npcHandler, text = 'I told everyone he will cause trouble. He talks people into giving him their money and putting it on the {bank}! They rather should leave it here with us honest merchants!'}) +keywordHandler:addKeyword({'seymour'}, StdModule.say, {npcHandler = npcHandler, text = 'He is the head of the local academy. I encouraged him to sponsor you, but no one listens to Obi, no one listens to me, as usual.'}) +keywordHandler:addKeyword({'tom'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, he just buys what no one else wants. Stuff that\'s long dead. I can live with that, yes, I can live with that.'}) +keywordHandler:addKeyword({'dallheim'}, StdModule.say, {npcHandler = npcHandler, text = 'What a hero, what a hero.'}) +keywordHandler:addAliasKeyword({'zerbrus'}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Um yeah, good day.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Farewell, I hope you were satisfied with our service.') +npcHandler:setMessage(MESSAGE_SENDTRADE, 'Of course, just browse through my wares.') +npcHandler:setMessage(MESSAGE_GREET, 'Hello, hello, |PLAYERNAME|! Please come in, look, and buy! If you like to see my offers, ask me for a {trade}!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/oblivion.lua b/data/npc/scripts/oblivion.lua new file mode 100644 index 00000000000..6bb1fc40321 --- /dev/null +++ b/data/npc/scripts/oblivion.lua @@ -0,0 +1,70 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Hm.' }, + { text = 'Yes. I listen, master.' }, + { text = 'I understand.' }, + { text = 'Not yet, my brothers. Wait.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if(msgcontains(msg, 'scroll') or msgcontains(msg, 'mission')) and player:getStorageValue(Storage.GravediggerOfDrefia.Mission44) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission45) < 1 then + npcHandler:say("Lost. Hidden. The keys are shadow names. Find them, they will talk to me and reveal what is hidden. Will you go on that quest?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, 'yes') and npcHandler.topic[cid] == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission44) == 1 then + npcHandler:say({ + "Then into the vampire crypts, deep down, you must go. ...", + "There... three graves where the shadows swirl, unseen. The first one: name the colour of the silent gong. Then ...", + "The second: the name that is silent now in the halls of Darkstone ...", + "The third: the lost beauty of Dunesea. It must be remembered, the shadows command it. Go now." + }, cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission45, 1) + npcHandler.topic[cid] = 0 + elseif(msgcontains(msg, 'scroll') or msgcontains(msg, 'mission')) and player:getStorageValue(Storage.GravediggerOfDrefia.Mission48) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission49) < 1 then + npcHandler:say("Yes. Have you gone there and found what you sought?", cid) + npcHandler.topic[cid] = 2 + elseif(msgcontains(msg, 'yes')) and npcHandler.topic[cid] == 2 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission48) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission49) < 1 then + npcHandler:say("Tell me. Begin with the colour.", cid) + npcHandler.topic[cid] = 3 + elseif(msgcontains(msg, 'bronze')) and npcHandler.topic[cid] == 3 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission48) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission49) < 1 then + npcHandler:say("Yes. The shadows say this is true. The beauty of House Dunesea, name it.", cid) + npcHandler.topic[cid] = 4 + elseif(msgcontains(msg, 'floating')) and npcHandler.topic[cid] == 4 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission48) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission49) < 1 then + npcHandler:say("The floating gardens. Too beautiful to lie asleep in the memory of men. Yes. The name that is no more in Darkstone?", cid) + npcHandler.topic[cid] = 5 + elseif(msgcontains(msg, 'Takesha Antishu')) and npcHandler.topic[cid] == 5 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission48) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission49) < 1 then + npcHandler:say({ + "Ah, the Lady of Darkstone. You have done well to remember her name. ...", + "Now, the shadows say the thing you seek lies next to Akab, the Quarrelsome. ...", + "No coal is burned in his honour. Find his resting place and dig near it. Now go." + }, cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission49, 1) + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "Be greeted.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ocelus.lua b/data/npc/scripts/ocelus.lua new file mode 100644 index 00000000000..9dee2b8812f --- /dev/null +++ b/data/npc/scripts/ocelus.lua @@ -0,0 +1,74 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "eleonore") then + if player:getStorageValue(Storage.TheShatteredIsles.APoemForTheMermaid) == 2 and player:getStorageValue(Storage.TheShatteredIsles.ADjinnInLove) < 1 then + npcHandler:say("I heard the birds sing about her beauty. But how could a human rival the enchanting beauty of a {mermaid}?", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "mermaid") or msgcontains(msg, "marina") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "Oh yes, I noticed that lovely mermaid. From afar of course. I would not dare to step into the eyes of such a lovely creature. ...", + "... I guess I am quite shy. Oh my, if I were not blue, I would turn red now. If there would be someone to arrange a {date} with her." + }, cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(Storage.TheShatteredIsles.ADjinnInLove) == 2 then + npcHandler:say("Oh my. Its not easy to impress a mermaid I guess. Please get me a {love poem}. I think elves are the greatest poets so their city seems like a good place to look for one.", cid) + player:setStorageValue(Storage.TheShatteredIsles.ADjinnInLove, 3) + end + elseif msgcontains(msg, "date") then + if npcHandler.topic[cid] == 2 then + npcHandler:say("Will you ask the mermaid Marina if she would date me?", cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 3 then + npcHandler:say("Thank you. How ironic, a human granting a djinn a wish.", cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.TheShatteredIsles.ADjinnInLove, 1) + elseif npcHandler.topic[cid] == 4 then + if player:removeItem(8189, 1) then + npcHandler:say("Excellent. Here, with this little spell I enable you to recite the poem like a true elven poet. Now go and ask her for a date again.", cid) + player:setStorageValue(Storage.TheShatteredIsles.ADjinnInLove, 4) + player:setStorageValue(Storage.TheShatteredIsles.APoemForTheMermaid, 3) + npcHandler.topic[cid] = 0 + else + npcHandler.topic[cid] = 0 + npcHandler:say("You don't have it...", cid) + end + end + elseif msgcontains(msg, "love poem") then + if player:getStorageValue(Storage.TheShatteredIsles.ADjinnInLove) == 3 then + npcHandler:say("Did you get a love poem from Ab'Dendriel?", cid) + npcHandler.topic[cid] = 4 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Greetings, dear visitor |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Oh well.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/odemara.lua b/data/npc/scripts/odemara.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/odemara.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/oiriz.lua b/data/npc/scripts/oiriz.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/oiriz.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/old_adall.lua b/data/npc/scripts/old_adall.lua new file mode 100644 index 00000000000..a77558b16fa --- /dev/null +++ b/data/npc/scripts/old_adall.lua @@ -0,0 +1,31 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Travel +local function addTravelKeyword(keyword, cost, destination) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to the ' .. keyword .. ' end for |TRAVELCOST|?', cost = cost}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'Maybe another time.', reset = true}) +end + +addTravelKeyword('east', 7, Position(32679, 32777, 7)) +addTravelKeyword('west', 7, Position(32558, 32780, 7)) + +-- Basic +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'I can bring you either to the east end of Port Hope or to the west end of the town, where would you like to go?'}) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/old_rock_boy.lua b/data/npc/scripts/old_rock_boy.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/old_rock_boy.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/oldrak.lua b/data/npc/scripts/oldrak.lua new file mode 100644 index 00000000000..27db3076704 --- /dev/null +++ b/data/npc/scripts/oldrak.lua @@ -0,0 +1,142 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local shopModule = ShopModule:new() +npcHandler:addModule(shopModule) +shopModule:addBuyableItem({"holy Tible"}, 1970, 1000, 1) + +keywordHandler:addKeyword({"job"}, StdModule.say, {npcHandler = npcHandler, text = "I guard this humble temple as a monument for the order of the {nightmare knights}."}) +keywordHandler:addAliasKeyword({"visitors"}) + +keywordHandler:addKeyword({"name"}, StdModule.say, {npcHandler = npcHandler, text = "My name is Oldrak."}) +keywordHandler:addKeyword({"monster"}, StdModule.say, {npcHandler = npcHandler, text = "These plains are not safe for ordinary travellers. It will take heroes to survive here."}) +keywordHandler:addKeyword({"help"}, StdModule.say, {npcHandler = npcHandler, text = "I can't help you, sorry!"}) +keywordHandler:addKeyword({"goshnar"}, StdModule.say, {npcHandler = npcHandler, text = "The greatest necromant who ever cursed our land with the steps of his feet. He was defeated by the nightmare knights."}) +keywordHandler:addKeyword({"nightmare"}, StdModule.say, {npcHandler = npcHandler, text = "This ancient order was created by a circle of wise humans who were called 'The {Dreamers}'. The order became {extinct} a long time ago."}) +keywordHandler:addKeyword({"extinct"}, StdModule.say, {npcHandler = npcHandler, text = "Many perished in their battles against evil, some went mad, not able to stand their nightmares any longer. Others were seduced by the darkness."}) +keywordHandler:addKeyword({"dreamers"}, StdModule.say, {npcHandler = npcHandler, text = "They learned the ancient art of {dreamwalking} from some elves they befriended."}) +keywordHandler:addKeyword({"dreamwalking"}, StdModule.say, {npcHandler = npcHandler, text = "While the dreamwalkers of the elves experienenced the brightest dreams of pleasure, the humans strangely had dreams of {dark omen}."}) +keywordHandler:addKeyword({"omen"}, StdModule.say, {npcHandler = npcHandler, text = "They dreamed of doom, destruction, talked to dead, tormented souls, and gained unwanted insight into the {schemes of darkness}."}) +keywordHandler:addKeyword({"schemes of darkness"}, StdModule.say, {npcHandler = npcHandler, text = "They figured out how to interpret their dark dreams and so could foresee the plans of the dark gods and their minions."}) +keywordHandler:addKeyword({"plan"}, StdModule.say, {npcHandler = npcHandler, text = "Using this knowledge they formed an order to thwart these plans, and because they battled their nightmares as brave as knights, they named their order accordingly."}) +keywordHandler:addKeyword({"necromant"}, StdModule.say, {npcHandler = npcHandler, text = "It is rumoured to open the entrance to the pits of inferno, also called the nightmare pits. Even if I knew about this secret I wouldn't tell you."}) +keywordHandler:addKeyword({"havok"}, StdModule.say, {npcHandler = npcHandler, text = "Before the battles raged across them, they were called the fair plains."}) +keywordHandler:addKeyword({"tibia"}, StdModule.say, {npcHandler = npcHandler, text = "That's where we are. The world of Tibia."}) +keywordHandler:addKeyword({"god"}, StdModule.say, {npcHandler = npcHandler, text = "They created Tibia and all life on it ... and unlife, too."}) +keywordHandler:addKeyword({"unlife"}, StdModule.say, {npcHandler = npcHandler, text = "Beware the foul undead!"}) +keywordHandler:addKeyword({"undead"}, StdModule.say, {npcHandler = npcHandler, text = "Beware the foul undead!"}) +keywordHandler:addKeyword({"excalibug"}, StdModule.say, {npcHandler = npcHandler, text = "A weapon of myth and legend. It was lost in ancient times ... perhaps lost forever."}) +keywordHandler:addKeyword({"yenny the gentle"}, StdModule.say, {npcHandler = npcHandler, text = "Yenny, known as the Gentle, was one of most powerfull magicwielders in ancient times and known throughout the world for her mercy and kindness."}) +keywordHandler:addKeyword({"offer"}, StdModule.say, {npcHandler = npcHandler, text = "I can offer you the holy tible for a small fee."}) +keywordHandler:addKeyword({"trade"}, StdModule.say, {npcHandler = npcHandler, text = "I can offer you the holy tible for a small fee."}) +keywordHandler:addKeyword({"sell"}, StdModule.say, {npcHandler = npcHandler, text = "I can offer you the holy tible for a small fee."}) +keywordHandler:addKeyword({"buy"}, StdModule.say, {npcHandler = npcHandler, text = "I can offer you the holy tible for a small fee."}) +keywordHandler:addKeyword({"have"}, StdModule.say, {npcHandler = npcHandler, text = "I can offer you the holy tible for a small fee."}) +keywordHandler:addKeyword({"time"}, StdModule.say, {npcHandler = npcHandler, text = "Now, it is |TIME|."}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + -- Demon oak quest + if msgcontains(msg, "mission") or msgcontains(msg, "demon oak") then + if player:getStorageValue(Storage.DemonOak.Done) < 1 then + npcHandler:say("How do you know? Did you go into the infested area?", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.DemonOak.Progress) == 2 and player:getStorageValue(Storage.DemonOak.Done) < 1 then + npcHandler:say("You better don't return here until you've defeated the Demon Oak.", cid) + elseif player:getStorageValue(Storage.DemonOak.Done) == 1 then + npcHandler:say({ + "You chopped down the demon oak?!? Unbelievable!! Let's hope it doesn't come back. As long as evil is still existent in the soil of the plains, it won't be over. Still, the demons suffered a setback, that's for sure. ...", + "For your brave action, I tell you a secret which has been kept for many many years. There is an old house south of the location where you found the demon oak. There should be a grave with the name 'Yesim Adeit' somewhere close by. ...", + "It belongs to a Daramian nobleman named 'Teme Saiyid'. I knew him well and he told me -almost augured- that someone will come who is worthy to obtain his treasure. I'm sure this 'someone' is you. Good luck in finding it!" + }, cid) + player:setStorageValue(Storage.DemonOak.Done, 2) + end + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 1 then + player:setStorageValue(Storage.DemonOak.Progress, 1) + if player:getStorageValue(Storage.DemonOak.Progress) == 1 then + npcHandler:say("A demon oak?!? May the gods be on our side. You'll need a {hallowed axe} to harm that tree. Bring me a simple {axe} and I'll prepare it for you.",cid) + player:setStorageValue(Storage.DemonOak.Progress, 2) + npcHandler.topic[cid] = 0 + else + npcHandler:say("I don't believe a word of it! How rude to lie to a monk!",cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "axe") then + if player:getStorageValue(Storage.DemonOak.Progress) == 2 then + npcHandler:say("Ahh, you've got an axe. Very good. I can make a hallowed axe out of it. It will cost you... er... a donation of 1,000 gold. Alright?",cid) + npcHandler.topic[cid] = 2 + else + npcHandler:say("You have to first talk about {demon oak} or the {mission} before we continue.",cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 2 then + if player:getStorageValue(Storage.DemonOak.Progress) == 2 then + if player:getMoney() + player:getBankBalance() >= 1000 then + if player:removeItem(2386, 1) and player:removeMoneyNpc(1000) then + npcHandler:say("Let's see........here we go. The blessing on this axe will be absorbed by all the demonic energy around here. I presume it will not last very long, so better hurry. Actually, I can refresh the blessing as often as you like.",cid) + player:addItem(8293, 1) + Npc():getPosition():sendMagicEffect(CONST_ME_YELLOWENERGY) + npcHandler.topic[cid] = 0 + else + npcHandler:say("There is no axe with you.",cid) + npcHandler.topic[cid] = 0 + end + else + npcHandler:say("There is not enough of money with you.",cid) + npcHandler.topic[cid] = 0 + end + end + elseif msgcontains(msg, "no") and npcHandler.topic[cid] == 1 then + npcHandler:say("What a pity! Let me know when you managed to get in there. Maybe I can help you when we know what we are dealing with.",cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") and npcHandler.topic[cid] == 2 then + npcHandler:say("No then.",cid) + npcHandler.topic[cid] = 0 + end + + -- The paradox tower quest + if msgcontains(msg, "hugo") then + npcHandler:say("Ah, the curse of the Plains of Havoc, the hidden beast, the unbeatable foe. I've been living here for years and I'm sure this is only a myth.", cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "myth") then + if player:getStorageValue(Storage.Quest.TheParadoxTower.TheFearedHugo) < 1 then + -- Questlog: The Paradox Tower + player:setStorageValue(Storage.Quest.TheParadoxTower.QuestLine, 1) + -- Questlog: The Feared Hugo (Zoltan) + player:setStorageValue(Storage.Quest.TheParadoxTower.TheFearedHugo, 1) + end + npcHandler:say("There are many tales about the fearsome Hugo. It's said it's an abnormality, accidentally created by Yenny the Gentle. It's half demon, half something else and people say it's still alive after all these years.", cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "yenny the gentle") then + npcHandler:say("Yenny, known as the Gentle, was one of the most powerful wielders of magic in ancient times. She was known throughout the world for her mercy and kindness.", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Welcome |PLAYERNAME|! Only rarely I can welcome {visitors} these days.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Take care, it's dangerous out there.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good Bye, |PLAYERNAME|") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/oliver.lua b/data/npc/scripts/oliver.lua new file mode 100644 index 00000000000..429a66178b0 --- /dev/null +++ b/data/npc/scripts/oliver.lua @@ -0,0 +1,53 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if(msgcontains(msg, "report")) then + if(player:getStorageValue(Storage.InServiceofYalahar.Questline) == 8 or player:getStorageValue(Storage.InServiceofYalahar.Questline) == 12) then + npcHandler:say("Nobody knows the trouble I've seen .. . ", cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, player:getStorageValue(Storage.InServiceofYalahar.Questline) + 1) + player:setStorageValue(Storage.InServiceofYalahar.Mission02, player:getStorageValue(Storage.InServiceofYalahar.Mission02) + 1) -- StorageValue for Questlog "Mission 02: Watching the Watchmen" + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "pass")) then + npcHandler:say("You can {pass} either to the {Factory Quarter} or {Sunken Quarter}. Which one will it be?", cid) + npcHandler.topic[cid] = 1 + elseif(msgcontains(msg, "factory")) then + if(npcHandler.topic[cid] == 1) then + local destination = Position(32895, 31231, 7) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "sunken")) then + if(npcHandler.topic[cid] == 1) then + local destination = Position(32895, 31226, 7) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/olrik.lua b/data/npc/scripts/olrik.lua new file mode 100644 index 00000000000..c47da506ad5 --- /dev/null +++ b/data/npc/scripts/olrik.lua @@ -0,0 +1,52 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "measurements") then + if player:getStorageValue(Storage.Postman.Mission07) >= 1 and player:getStorageValue(Storage.Postman.MeasurementsOlrik) ~= 1 then + npcHandler:say("My measurements? Listen, lets make that a bit more exciting ... No, no, not what you think! I mean let's gamble. I will roll a dice. If I roll a 6 you win and I'll tell you what you need to know, else I win and get 5 gold. Deal? ", cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say("...", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "yes") then + if player:getMoney() + player:getBankBalance() >= 5 then + player:removeMoneyNpc(5) + local number = math.random(6) + if number ~= 6 then + npcHandler:say("Ok, here we go ... " .. number .. "! You lose! Try again.", cid) + else + npcHandler:say("Ok, here we go ... " .. number .. "! You have won! How lucky you are! So listen ... ", cid) + player:setStorageValue(Storage.Postman.Mission07, player:getStorageValue(Storage.Postman.Mission07) + 1) + player:setStorageValue(Storage.Postman.MeasurementsOlrik, 1) + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "Hello. How may I help you |PLAYERNAME|? Ask me for a {trade} if you want to buy something. I can also explain the {mail} system.") +npcHandler:setMessage(MESSAGE_FAREWELL, "It was a pleasure to help you, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Here. Don't forget that you need to buy a label too if you want to send a parcel. Always write the name of the {receiver} in the first line.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/omrabas.lua b/data/npc/scripts/omrabas.lua new file mode 100644 index 00000000000..eed0de5e17d --- /dev/null +++ b/data/npc/scripts/omrabas.lua @@ -0,0 +1,519 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Typical. Easy come, easy go.' }, + { text = 'He will PAY for this... They will ALL pay!' }, + { text = '' }, + { text = 'If I ever lay hands on him again...' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.GravediggerOfDrefia.QuestStart) < 1 then + npcHandler:say("Hmm. You could be of assistance, I presume. I need several body parts. I will reward you adequately. Interested?", cid) + player:setStorageValue(Storage.GravediggerOfDrefia.QuestStart, 1) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission01) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission02) < 1 then + npcHandler:say("Ah hello, young friend! Did you bring me two ghoul snacks as requested?", cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission02) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission03) < 1 then + npcHandler:say("Ah, young friend, I found a solution! Find me two {demonic skeletal hands}. That should do it. Now run along! Ask me for {mission} when you're done.", cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission03, 1) + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission03) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission04) < 1 then + npcHandler:say("Ah hello again! You look as if you could, er, lend me a hand or two? Yes?", cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission04) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission05) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission05, 1) + npcHandler:say({ + "I need my heart back. I know where they have hidden it. Too afraid to destroy my beating heart, hah! ...", + "It is in a dusty amphora in a sealed mass grave in the downmost cellar of my ancient home. The ruins lie to the north at the beach. ...", + "Crash the amphoras to find my heart, and bring it to me." + }, cid) + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission06) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission07) < 1 then + npcHandler:say({ + "Yes? You have it? You what? Not in the amphoras? You picked it off someone else?!? ...", + "Well, the important thing is that you have it. Let's see if it's still in good shape. {Give} it to me." + }, cid) + npcHandler.topic[cid] = 4 + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission07) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission08) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission08, 1) + npcHandler:say({ + "I will need brains - don't laugh! Ahem. I will need a stimulated brain, to be precise. ...", + "Use two half-eaten brains with the Brain Heater Machine in the Necromancer halls and bring me the fused, stimulated brain. Now go!" + }, cid) + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission09) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission10) < 1 then + npcHandler:say("Yes, yes, hello. Tell me if you lost something. If not, do you have that stimulated brain with you?", cid) + npcHandler.topic[cid] = 5 + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission10) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission11) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission11, 1) + player:addItem(21402,1) + npcHandler:say({ + "Now that you have shown you've got the brains, I need you to show initiative. ...", + "I will need something that can be adequately used as intestines. Something alive. Stuff it into this storage flask and return it to me!" + }, cid) + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission12) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission13) < 1 then + npcHandler:say("Hello, hello. Let's come to the point - did you find me some intestines?", cid) + npcHandler.topic[cid] = 6 + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission13) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission14) < 1 then + npcHandler:say({ + "Good. As you may have gathered, the body parts you brought need to be assembled to form a whole body. ...", + "This will happen through a necromantic ritual that we - or rather, you - now have to prepare. ...", + "In a first step, it will involve retrieving specific artefacts of dark magic and hallowing the altars of the dark powers with them. ...", + "After that, you will have to speak an ancient incantation to animate the body and fuse my soul within. ...", + "But first things first. Are you ready to {undertake} the hallowing of the five altars?" + }, cid) + npcHandler.topic[cid] = 7 + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission15) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission16) < 1 then + npcHandler:say("Ah hello! Well done there, I felt the old powers settling down. Now, {ready} to hallow the next altar?", cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission16, 1) + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission16) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission17) < 1 then + npcHandler:say({ + "I expected no less. Next is the Bonemarrow Altar, where the Dark Lord feasts upon the hallowed bones of...err. ...", + "Ahem. Just take a yellowed bone or big bone, and hallow it - you don't know how? ...", + "Huh. To HALLOW a yellowed bone, use it with one of the hallowed bonepiles in the Gardens Of Night. There are always bones around there - or were, in my days. ...", + "Then, place the hallowed bone on the firebasin of the Bonemarrow Altar so the Dark Lord can consume it and grants us his power. Return to me after that." + }, cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission17, 1) + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission17) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission18) < 1 then + npcHandler:say({ + "Are you still here? Come on, let's not laze about, go to the Gardens of Night - where? ...", + "East of the Necromancer Halls, you can't miss it, just look for a lot of dark and white sand, dried trees, and priestesses! ...", + "Or got a {problem} with finding bones? Hah!" + }, cid) + npcHandler.topic[cid] = 8 + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission20) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission21) < 1 then + npcHandler:say({ + "Ah, welcome, welcome! I felt that one! The Dark Lord is pleased with the gift you brought, so now we can proceed with everything as planned. ...", + "If it had gone wrong though, he would have had your guts for gart... er... well, here you are, so - ready to get some {blood} flowing?" + }, cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission21, 1) + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission21) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission22) < 1 then + npcHandler:say({ + "Yes, I said blood. Important ingredient in necromantic rituals, usually. ...", + "You need to spill some vials of blood tincture for this task. Probably means killing blood priests to get those vials. Ready to do this?" + }, cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission22, 1) + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission25) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission26) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission26, 1) + npcHandler:say({ + "Ah, it is invigorating to fell the dark flows, rushing through Drefia, once again! Capital. This has earned you a reward. ...", + "Now, the next mission awaits, {yes}?" + }, cid) + npcHandler.topic[cid] = 9 + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission29) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission30) < 1 then + npcHandler:say({ + "Ah, finally. Exceptional! Don't you feel the earth awakening to our call? No? Oh. ...", + "Anyway, you succeeded in hallowing the Fireglass Altar! Only one altar remains to be hallowed! Shall we {proceed}?" + }, cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission30, 1) + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission33) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission34) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission34, 1) + npcHandler:say({ + "Yes! YES! I have felt that! The altars are alive again! Well done! ...", + "We are close now. Only one important thing remains: the incantation itself. We need the {scroll} for that." + }, cid) + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission42) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission43) < 1 then + npcHandler:say('Yes? Do you have the {scroll} piece? ', cid) + npcHandler.topic[cid] = 11 + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission43) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission44) < 1 then + npcHandler:say({ + "Hah, developed a taste for it, have you? I believe the next scroll piece was hidden somewhere, my old friend being of a somewhat distrustful nature. ...", + "The scent may not be lost, though - ask a shadow pupil if he can help - but be careful. ...", + "Those shadow pupils are - strange. Try to find one who will answer and not kill you!" + }, cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission44, 1) + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission50) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission51) < 1 then + npcHandler:say("Ah, hello! I take it you have the next scroll piece for me, {yes}?", cid) + npcHandler.topic[cid] = 12 + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission51) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission52) < 1 then + npcHandler:say({ + "Good! As you can imagine, I had a scroll piece, too. I hid it in my old quarters, northwest of the library. ...", + "The door is magically sealed. Use this copper key with it to get inside. ...", + "Beneath one of the chests is a secret stash, under a loose stone tile. The scroll piece should be inside. Off you go." + }, cid) + player:addItem(21489, 1) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission52, 1) + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission57) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission58) < 1 then + npcHandler:say("Hello - what? You have the {scroll} piece, you say?", cid) + npcHandler.topic[cid] = 13 + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission58) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission59) < 1 then + player:addItem(21464, 1) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission59, 1) + npcHandler:say({ + "Hahah, eager for it, I like that! ...", + "One piece stayed in the hands of a beautiful priestess. ...", + "As they never throw anything away that looks like an incantation - you get my drift. Find out where they still keep it! ...", + "Oh, one more thing! They only talk to you when you look like a fellow summoner. It's dangerous to go without a cape. Use this." + }, cid) + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission64) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission65) < 1 then + npcHandler:say("Hello, young apprentice. Do you have that {scroll} piece from the priestess?", cid) + player:addItem(21464, 1) + npcHandler.topic[cid] = 14 + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission65) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission66) < 1 then + npcHandler:say({ + "That's the spirit! Speaking of which, you will have to look for a White Shade ...", + "That's a ghost, in case you don't know. Goes by name of... Zarifan, if I recall correctly. ...", + "His grave is somewhere to the south, somewhere deeper. And he only reacts to magic words. ...", + "Err... it's embarrassing... the magic words are ...", + "'Friendship lives forever.' Silly, really. Untrue, as well. ...", + "Anyway, say those three words - don't make me repeat them - and the old softie will tell you where the scroll is. Pathetic." + }, cid) + player:addItem(21464, 1) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission66, 1) + --elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission68) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission69) < 1 then + --npcHandler:say("Welcome, welcome! Finally! The last scroll piece.... you do have it, haven't you?", cid) + --npcHandler.topic[cid] = 15 + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission70) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission71) < 1 then + npcHandler:say("Don't keep me waiting. The last scroll piece - were you able to {restore} it?", cid) + npcHandler.topic[cid] = 16 + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission73) == 1 then--and player:getStorageValue(Storage.GravediggerOfDrefia.Mission74) < 1 then + npcHandler:say({ + "It failed! IT FAILED! WHY? What have you done! This must be your fault! ...", + "You... did... that was a recipe for chicken soup! No wonder the scroll failed! Now... all is lost ...", + " I never want to see you again! You and your dirty gravedigger hands! Take this, you ungrateful, useless, imbecile... human! ...", + "Now... get out! And never, ever, dare come back! You ruined EVERYTHING!" + }, cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission73, 2) + player:addItem(21452, 1) + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.QuestStart) == 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission01, 1) + npcHandler:say({ + "Very sensible of you. I will pay you handsomely for your help. ...", + "All you have to do is fetch diverse fresh body parts and then prepare the resurrection ritual. Nothing out of the ordinary. ...", + "First, I need two arms. Ghouls usually carry some as a snack. Two ghoul snacks should not be hard to get! Return when you have them." + }, cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission01) == 1 then + if player:removeItem(12423, 2) then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission02, 1) + npcHandler:say("Splendid! What? They're half gnawed! There are no hands! Hrmmm. Let me think of a solution. Ask me for a new {mission}.", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have two ghoul snacks.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 3 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission03) == 1 then + if player:removeItem(10564, 2) then + npcHandler:say("Yes. Those will be adequate. Talk to me again if you want to continue with your next {mission}.", cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission04, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have two demonic skeletal hands.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 4 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission06) == 1 then + if player:removeItem(21394, 1) then + npcHandler:say("Ah... Very good. Just say the word when you are ready for the next {mission}.", cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission07, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have my heart.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 5 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission09) == 1 then + if player:removeItem(21395, 1) then + npcHandler:say("Ah... Very good. Just say the word when you are ready for the next {mission}.", cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission10, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have the brain.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 6 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission12) == 1 then + if player:removeItem(21403, 1) then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission13, 1) + npcHandler:say({ + "Ah... interesting. A snake? Not bad, not bad at all. ...", + "Right. Now, we need to waken the old powers through ritual. Let me know when you are ready for this {mission}." + }, cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have my intestine.", cid) + npcHandler.topic[cid] = 0 + end + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission22) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission23) < 1 then + npcHandler:say({ + "Ah, I knew you were a sturdy fellow! Necromancer material if ever I saw one! ...", + "Well then, the next task is to anoint the Bloodgong Altar. This will animate the dark flows we need for the ritual. ...", + "You need to spill a vial of blood tincture on each of the four sacrifical stones of the altar in order to anoint them. ...", + "Then, toll the Bloodgong north of the sacrificial stones to set the dark flows going. Return to me after that." + }, cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission23, 1) + elseif npcHandler.topic[cid] == 9 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission26) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission27) < 1 then + npcHandler:say({ + "Excellent. To bind the earthly powers, we, I mean you, must worship at the Fireglass Altar. ...", + "This means scattering sacred ashes from the Ember Chamber on the sacrificial stones of the Fireglass Altar. ...", + "To gather the sacred ashes, you have to use magic chalk with the Shadow Fire in the Ember Chamber. ...", + "Gather the resulting ashes from the Shadow Hearth, and scatter them on the Fireglass Altar's sacrificial stones. Then return here." + }, cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission27, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 10 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission34) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission35) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission35, 1) + npcHandler:say({ + "Superb! You won't regret this. I will reward you beyond your wildest dreams! ...", + "I know that one of my former friends joined the blood priests later on. He made it quite high before he was ritually killed. ...", + "Go find a blood priest you can talk to. Ask him, but subtly. And never tell anyone what the scroll does!" + }, cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 11 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission42) == 1 then + if player:removeItem(21250, 1) then + npcHandler:say("This is it! This is it! Well done, well done! And now, on to the {next} scroll piece, {yes}?", cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission43, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have my scroll.", cid) + npcHandler.topic[cid] = 0 + end + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission43) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission44) < 1 then + npcHandler:say({ + "Hah, developed a taste for it, have you? I believe the next scroll piece was hidden somewhere, my old friend being of a somewhat distrustful nature. ...", + "The scent may not be lost, though - ask a shadow pupil if he can help - but be careful. ...", + "Those shadow pupils are - strange. Try to find one who will answer and not kill you!" + }, cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission44, 1) + elseif npcHandler.topic[cid] == 12 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission50) == 1 then + if player:removeItem(21250, 1) then + npcHandler:say("Indeed it is! The second scroll piece! Splendid! Here you go - for your trouble. And now, on to the {next} scroll piece, {yes}? ", cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission51, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have my scroll.", cid) + npcHandler.topic[cid] = 0 + end + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission51) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission52) < 1 then + npcHandler:say({ + "Good! As you can imagine, I had a scroll piece, too. I hid it in my old quarters, northwest of the library. ...", + "The door is magically sealed. Use this copper key with it to get inside. ...", + "Beneath one of the chests is a secret stash, under a loose stone tile. The scroll piece should be inside. Off you go." + }, cid) + player:addItem(21489, 1) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission52, 1) + elseif npcHandler.topic[cid] == 13 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission57) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission58) < 1 then + if player:removeItem(21250, 1) then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission58, 1) + npcHandler:say({ + "Oh, praise the Dark Lord! It is my scroll piece! Give it here! You can have this instead. ...", + "Ahh, that feels GOOD. Now, only two pieces left to hunt down! On to the {next} scroll piece, yes?" + }, cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have my scroll.", cid) + npcHandler.topic[cid] = 0 + end + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission58) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission59) < 1 then + player:addItem(21464, 1) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission59, 1) + npcHandler:say({ + "Hahah, eager for it, I like that! ...", "One piece stayed in the hands of a beautiful priestess. ...", + "As they never throw anything away that looks like an incantation - you get my drift. Find out where they still keep it! ...", + "Oh, one more thing! They only talk to you when you look like a fellow summoner. It's dangerous to go without a cape. Use this." + }, cid) + elseif npcHandler.topic[cid] == 15 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission68) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission69) < 1 then + + if player:removeItem(21250, 1) then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission69, 1) + npcHandler:say({ + "Ahhh, capital, capital. Good girl for keeping it for me. I'll take back my cape now, thank you. ...", + "Now - the final part of the scroll! Ready to go retrieve it?" + }, cid) + else + npcHandler:say("You don't have my scroll.", cid) + npcHandler.topic[cid] = 0 + end + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission70) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission71) < 1 then + npcHandler:say({ + "That's the spirit! Speaking of which, you will have to look for a White Shade ...", + "That's a ghost, in case you don't know. Goes by name of... Zarifan, if I recall correctly. ...", + "His grave is somewhere to the south, somewhere deeper. And he only reacts to magic words. ...", + "Err... it's embarrassing... the magic words are ...", + "'Friendship lives forever.' Silly, really. Untrue, as well. ...", + "Anyway, say those three words - don't make me repeat them - and the old softie will tell you where the scroll is. Pathetic." + }, cid) + player:addItem(21464, 1) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission71, 1) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission69, 1) + elseif npcHandler.topic[cid] == 15 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission69) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission72) < 1 then + if player:removeItem(21250, 1) then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission72, 1) + npcHandler:say({ + "I am so excited! Finally, we - wait. What is this? That... is not the complete scroll piece. ...", + "I don't care what you say! This is a disaster! We need a complete scr - wait. I have an idea. ...", + "There must be a copy or something in my old library. something to use with the scroll, to find the missing words. ...", + "There must be. Go look there. Next to the fiveserrated room, a small library. Go go go!" + }, cid) + else + npcHandler:say("You don't have my scroll.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 17 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission73) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission74) < 1 then + npcHandler:say({ + "Then let's go. Take my skull and the incantation scroll to the working station in the fiveserrated room ...", + "Where the lava flows and the southern legs of the room meet. Place the Skull on the sacrificial stone and use the scroll ...", + "AND I shall be made whole, and YOU shall be RICH!" + }, cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission74, 1) + player:addItem(21251, 1) + player:addItem(21476, 1) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'demonic skeletal hands') or msgcontains(msg, 'demonic skeletal hand') then + npcHandler:say("What? Hack some off from a demon skeleton, of course! Now get moving.", cid) + elseif msgcontains(msg, 'give') and npcHandler.topic[cid] == 4 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission06) == 1 then + if player:removeItem(21394, 1) then + npcHandler:say("Ah... Very good. Just say the word when you are ready for the next {mission}.", cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission07, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have my heart.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'undertake') and player:getStorageValue(Storage.GravediggerOfDrefia.Mission13) == 1 and npcHandler.topic[cid] == 7 then + npcHandler:say({ + "Good! Let's not waste time. The first altar you must hallow is the Dragonsoul Altar, at the eastern side of the room. ...", + "To hallow it, dig out three dragon tears and place them on the altar to appease the dark powers. ...", + "What? Oh, you'll find some dragon tears near dragon skulls... where? ...", + "In the Dragonbone Cemetery, OBVIOUSLY! Must I explain EVERYTHING to you? Now go!" + }, cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission14, 1) + player:addItem(21401,3) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'ready') and player:getStorageValue(Storage.GravediggerOfDrefia.Mission16) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission17) < 1 then + npcHandler:say({ + "I expected no less. Next is the Bonemarrow Altar, where the Dark Lord feasts upon the hallowed bones of...err. ...", + "Ahem. Just take a yellowed bone or big bone, and hallow it - you don't know how? ...", + "Huh. To HALLOW a yellowed bone, use it with one of the hallowed bonepiles in the Gardens Of Night. There are always bones around there - or were, in my days. ...", + "Then, place the hallowed bone on the firebasin of the Bonemarrow Altar so the Dark Lord can consume it and grants us his power. Return to me after that." + }, cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission17, 1) + elseif msgcontains(msg, 'problem') and player:getStorageValue(Storage.GravediggerOfDrefia.Mission17) == 1 and npcHandler.topic[cid] == 8 then + npcHandler:say("What? No bones around you say? Hrmmm. Wait. Check the skull heap here - that's right - hah! There! Now get to work!", cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission18, 1) + player:addItem(21407, 3) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'blood') and player:getStorageValue(Storage.GravediggerOfDrefia.Mission21) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission22) < 1 then + npcHandler:say({ + "Yes, I said blood. Important ingredient in necromantic rituals, usually. ...", + "You need to spill some vials of blood tincture for this task. Probably means killing blood priests to get those vials. Ready to do this?" + }, cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission22, 1) + elseif msgcontains(msg, 'proceed') and player:getStorageValue(Storage.GravediggerOfDrefia.Mission30) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission31) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission31, 1) + player:addItem(21448, 1) + player:addItem(21482, 1) + npcHandler:say({ + " The final altar that remains to be hallowed... the Shadowthrone. ...", + "Only a candle made of human tallow placed before each shadow statue in the right order, will awaken it. ...", + "I say, are you sick? Human tallow candles are a perfectly good tool - don't look at me like that! Be professional about this, will you? ...", + "I have some candles hidden deep down in the lich caves, east of here. Here's the key that opens the trapdoor to the cache. ...", + "And take this parchment. Identify the right candles with it, take three with you and place one in front of the three shadowthrone statues, starting counterclockwise. Now go!" + }, cid) + elseif msgcontains(msg, 'scroll') then + if player:getStorageValue(Storage.GravediggerOfDrefia.Mission34) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission35) < 1 then + npcHandler:say({ + "Well, it is a rather long story. The short version: I had friends - no need to snigger. ...", + "We were five highly brilliant dark summoners. We joined our forces to find the scroll of Youth and Life Eternal. ...", + "But when we finally found it after years of toiling and danger, we quarreled over who could have it. The scroll tore. ...", + "We each retained one piece of the scroll. Well, that was a long time ago. ...", + "But I think I have a clue where we can find the first piece of the scroll. Would you go looking?" + }, cid) + npcHandler.topic[cid] = 10 + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission42) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission43) < 1 then + npcHandler:say("Yes? Do you have the {scroll} piece?", cid) + npcHandler.topic[cid] = 11 + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission50) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission51) < 1 then + npcHandler:say("Ah, hello! I take it you have the next {scroll} piece for me, {yes}?", cid) + npcHandler.topic[cid] = 12 + elseif npcHandler.topic[cid] == 13 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission57) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission58) < 1 then + if player:removeItem(21250, 1) then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission58, 1) + npcHandler:say({ + "Oh, praise the Dark Lord! It is my scroll piece! Give it here! You can have this instead. ...", + "Ahh, that feels GOOD. Now, only two pieces left to hunt down! On to the {next} scroll piece, yes?" + }, cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have my scroll.", cid) + npcHandler.topic[cid] = 0 + end + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission64) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission65) < 1 then + npcHandler:say("Hello, young apprentice. Do you have that {scroll} piece from the priestess?", cid) + player:addItem(21464, 1) + + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission68) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission69) < 1 then + npcHandler:say("Welcome, welcome! Finally! The last {scroll} piece.... you do have it, haven't you?", cid) + npcHandler.topic[cid] = 15 + end + elseif msgcontains(msg, 'next') then + if player:getStorageValue(Storage.GravediggerOfDrefia.Mission43) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission44) < 1 then + npcHandler:say({ + "Hah, developed a taste for it, have you? I believe the next scroll piece was hidden somewhere, my old friend being of a somewhat distrustful nature. ...", + "The scent may not be lost, though - ask a shadow pupil if he can help - but be careful. ...", + "Those shadow pupils are - strange. Try to find one who will answer and not kill you!" + }, cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission44, 1) + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission51) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission52) < 1 then + npcHandler:say({ + "Good! As you can imagine, I had a scroll piece, too. I hid it in my old quarters, northwest of the library. ...", + "The door is magically sealed. Use this copper key with it to get inside. ...", + "Beneath one of the chests is a secret stash, under a loose stone tile. The scroll piece should be inside. Off you go." + }, cid) + player:addItem(21489, 1) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission52, 1) + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission58) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission59) < 1 then + player:addItem(21464, 1) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission59, 1) + npcHandler:say({ + "Hahah, eager for it, I like that! ...", + "One piece stayed in the hands of a beautiful priestess. ...", + "As they never throw anything away that looks like an incantation - you get my drift. Find out where they still keep it! ...", + "Oh, one more thing! They only talk to you when you look like a fellow summoner. It's dangerous to go without a cape. Use this." + }, cid) + end + elseif msgcontains(msg, 'restore') and player:getStorageValue(Storage.GravediggerOfDrefia.Mission69) <= 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission73) < 1 then --and npcHandler.topic[cid] == 15 then + if player:removeItem(21474, 1) then + npcHandler:say({ + "I knew it! I knew I had made a copy! Oh, I am so clever! ...", + "Now, watch this. THERE. THE COMPLETE INCANTATION SCROLL. ...", + "You have done well. Only one thing remains, and you shall be rich beyond your dreams. Ready for the really final task?" + }, cid) + --player:setStorageValue(Storage.GravediggerOfDrefia.Mission72, 1) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission73, 1) + npcHandler.topic[cid] = 17 + + + else + npcHandler:say("You don't have my scroll.", cid) + npcHandler.topic[cid] = 0 + end + else npcHandler:say("Chzzzz. wtf??@! leave.", cid) + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "At last, a visitor! Welcome to my... humble abode.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/omur.lua b/data/npc/scripts/omur.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/omur.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/one_eyed_joe.lua b/data/npc/scripts/one_eyed_joe.lua new file mode 100644 index 00000000000..f84e8e8678c --- /dev/null +++ b/data/npc/scripts/one_eyed_joe.lua @@ -0,0 +1,107 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end +local voices = { + { text = 'Did you hear that, too?' } +} +npcHandler:addModule(VoiceModule:new(voices)) +function creatureSayCallback(cid, type, msg) +local player = Player(cid) + if not npcHandler:isFocused(cid) then + if msg == "hi" or msg == "hello" then + if (player:getStorageValue(Storage.TibiaTales.TheCursedCrystal.Oneeyedjoe) == 3) then + if (player:getStorageValue(Storage.TibiaTales.TheCursedCrystal.Questline) == 3)then + player:setStorageValue(Storage.TibiaTales.TheCursedCrystal.Questline, 4) + end + player:addAchievement("Wail of the Banshee") + player:setStorageValue(Storage.TibiaTales.TheCursedCrystal.Oneeyedjoe, 4) + doPlayerAddItem(cid,18413,1) + doPlayerAddItem(cid,18414,1) + doPlayerAddItem(cid,18415,1) + math.randomseed(os.time()) + chanceToPirate = math.random(1,4) + if chanceToPirate == 1 then + doPlayerAddItem(cid,5926,1) + elseif chanceToPirate == 2 then + doPlayerAddItem(cid,6098,1) + elseif chanceToPirate == 3 then + doPlayerAddItem(cid,6097,1) + elseif chanceToPirate == 4 then + doPlayerAddItem(cid,6126,1) + end + npcHandler:say("Well done! Take this reward for your efforts. But know this: The cursed crystal seems to regenerate over time. It could be necessary to come back and repeat whatever you have done down there.", cid) + elseif (player:getStorageValue(Storage.TibiaTales.TheCursedCrystal.Oneeyedjoe) >= 0) and (player:getStorageValue(Storage.TibiaTales.TheCursedCrystal.Oneeyedjoe) < 3) then + npcHandler:say("Ah, the brave adventurer who sought to destroy the evil crystal down there. Have you been succesful?", cid) + else + npcHandler:say("Hello there. I'm sorry, I hardly noticed you. I'm a bit nervous. The spooky {sounds} down there, you know.", cid) + end + npcHandler:addFocus(cid) + else + return false + end + end + if msgcontains(msg, "mission") and (player:getStorageValue(Storage.TibiaTales.TheCursedCrystal.Oneeyedjoe) < 0) and npcHandler.topic[cid] < 1 then + npcHandler.topic[cid] = 1 + npcHandler:say({ +"As for myself I haven't been down there. But I heard some disturbing rumours. In these caves are wonderful crystal formations. Some more poetically inclined fellows call them the crystal gardens. ...", +"At first glance it seems to be a beautiful - and precious - surrounding. But in truth, deep down in these caverns exists an old evil. Want to hear more?" + }, cid) + elseif msgcontains(msg, "yes") and (player:getStorageValue(Storage.TibiaTales.TheCursedCrystal.Oneeyedjoe) > 0) and (player:getStorageValue(Storage.TibiaTales.TheCursedCrystal.Oneeyedjoe) < 3) then + npcHandler:say({"Hmm. No, i don't think so. I still feel this strange prickling in my toes."}, cid) + elseif msgcontains(msg, "no") and (player:getStorageValue(Storage.TibiaTales.TheCursedCrystal.Oneeyedjoe) > 0) and (player:getStorageValue(Storage.TibiaTales.TheCursedCrystal.Oneeyedjoe) < 3) then + npcHandler:say({"Too bad."}, cid) + elseif msgcontains(msg, "protect ears") then + npcHandler:say({"Protect your ears? Hmm ... Wasn't there some fabulous seafarer who used wax or something to plug his ears? There was a story about horrible bird-women or something ...? No, sounds like hogwash, doesn't it."}, cid) + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 1 then + npcHandler.topic[cid] = 2 + npcHandler:say({ +"The evil I mentioned is a strange crystal, imbued with some kind of unholy energy. It is very hard to destroy, no weapon is able to shatter the thing. Maybe a jarring, very loud sound could destroy it. ...", +"I heard of creatures, that are able to utter ear-splitting sounds. Don't remember the name, though. Would you go down there and try to destroy the crystal?" + }, cid) + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 2 then + npcHandler.topic[cid] = 3 + player:setStorageValue(Storage.TibiaTales.DefaultStart, 1) + if (player:getStorageValue(Storage.TibiaTales.TheCursedCrystal.Questline) < 0)then + player:setStorageValue(Storage.TibiaTales.TheCursedCrystal.Questline, 0) + end + player:setStorageValue(Storage.TibiaTales.TheCursedCrystal.Oneeyedjoe, 0) + npcHandler:say({"Great! Good luck and be careful down there!"}, cid) + elseif msgcontains(msg, "crystals") then + npcHandler:say({ +"In my humble opinion a pirate should win a fortune by boarding ships not by crawling through caves and tunnels. But who am I to bring into question the captain's decision. All I know is that they sell the crystals at a high price. ...", +"A certain amount of the crystals is ground to crystal dust with a special kind of mill. Don't ask me why. Some kind of magical component perhaps that they sell to mages and sorcerers." + }, cid) + elseif msgcontains(msg, "cursed") and (player:getStorageValue(Storage.TibiaTales.TheCursedCrystal.Oneeyedjoe) < 0) and npcHandler.topic[cid] < 1 then + npcHandler.topic[cid] = 1 + npcHandler:say({ +"As for myself I haven't been down there. But I heard some disturbing rumours. In these caves are wonderful crystal formations. Some more poetically inclined fellows call them the crystal gardens. ...", +"At first glance it seems to be a beautiful - and precious - surrounding. But in truth, deep down in these caverns exists an old evil. Want to hear more?" + }, cid) + elseif msgcontains(msg, "sounds") then + npcHandler:say({ +"These caves are incredibly beautiful, {crystals} in vibrant colours grow there like exotic flowers. There are more than a few captains who send down their men in order to quarry the precious crystals. ...", +"But there are few volunteers. Often the crystal gatherers disappear and are never seen again. Other poor fellows then meet their former shipmates in the form of ghosts or skeletons. It's a {cursed} area, something evil is down there!" + }, cid) + elseif msgcontains(msg, "job") then + npcHandler:say({"I'm a pirate. Normally I'm sailing the seas, boarding other ships and gathering treasures. But at the moment my captain graciously assigned me to watch this {cursed} entrance."}, cid) + elseif msgcontains(msg, "name") then + npcHandler:say({"I'm One-Eyed Joe. From Josephina, got that? And I regard this eye patch as a personal feature of beauty!"}, cid) + elseif msgcontains(msg, "bye") then + npcHandler:say("Good bye adventurer. It was nice to talk with you.", cid) + npcHandler:releaseFocus(cid) + end + return +end +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) diff --git a/data/npc/scripts/ongulf.lua b/data/npc/scripts/ongulf.lua new file mode 100644 index 00000000000..d434b28b1fe --- /dev/null +++ b/data/npc/scripts/ongulf.lua @@ -0,0 +1,207 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Great, another supply ship is due. How is a dwarf supposed to work under these conditions?' }, + { text = 'Ah, there\'s nothing like the sound of hammers in the morning.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "project") and player:getStorageValue(Storage.TheNewFrontier.Questline) < 1 then + if npcHandler.topic[cid] == 0 then + npcHandler:say({ + "Well, it's a long story but you really should listen to understand what is going on here. You can also hear a short version of the story, but then don't blame me if you mess something up due to your undwarfish impatience. ...", + "So what would you like to hear, the {long} story or the {short} version?" + }, cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "long") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "After centuries the resources beneath and around the Big Old One became alarmingly short. Some decades ago, the imperial mining guild financed a project to search and establish new mines far away from Kazordoon. ...", + "After several tries with mixed success, the project of the technomancers proved the most successful. Their steamships studied and mapped the great underwater rivers deep beneath the earth. ...", + "With the help of certain apparatuses, they tracked deposits of ore and compiled ship routes to reach them. These mining bases had some obvious advantages and disadvantages. ...", + "The suitable spots had no connection to the surface. On the one hand, this meant that the new mines were safe from most kinds of beasts. On the other hand, it meant that all food and material had to be brought there by ship. ...", + "Special, heavy ships were built to carry ore and supplies back and forth. The only limitation for such bases had been the range of the steamships. ...", + "Recently, the technomancers with the help of the temples of fire and earth made some crucial discoveries that allowed the ships to extend their cruising range almost limitlessly. ...", + "The survey ships of the technomancers were once again sent out to find new, promising resources. ...", + "Sadly some of the ships never returned and others only found minor deposits of ore, not worth the effort. But one of the ships made some groundbreaking discovery - a cave that had a connection to the surface. ...", + "As far as the explorers could tell, the area had been unknown to dwarfhood and mankind so far. ...", + "What was more, the said cave system had an abundance of rare ores. The imperial mining guild agreed to fund a new project and to name it 'project far far away'. ...", + "Don't look at me, I'm not the one who came up with that name! Those technomancers are such an imaginative bunch. But where have we been? Oh, yes, the new project! ...", + "Well, some ships were sent to establish a first base. ...", + "It became painfully obvious that the number of workers needed there could not easily be supplied by the ships alone. Also such a base would require an amount of money, expertise and manpower that the guild could not provide. ...", + "We would need help and additional resources. That's were you come into play. If you are interested, let's talk about possible missions." + }, cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, "short") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + " Well, we have found this place here full of promising resources and plan to create a new mining outpost. Of course this takes a lot of effort and organisation. ...", + "For some of the tasks at hand we need help, even from outsiders like you. So if you are interested in some missions, let me know.", + "Listen, I can handle the organisation down here and my boys will handle the construction of the base fine enough. Actually, all you do down here is to stand in the workers' way. ...", + "But there might be something for you to do outside the base. We need to learn more about the land up there. Take the lift and do some exploring. Find a passage leading out of the mountains. ...", + "Do not explore any further though. You never know whom you might be messing with." + }, cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 1) + player:setStorageValue(Storage.TheNewFrontier.Mission01, 1) --Questlog, The New Frontier Quest "Mission 01: New Land" + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "mission") then + if player:getStorageValue(Storage.TheNewFrontier.Questline) < 1 and npcHandler.topic[cid] == 2 then + npcHandler:say({ + "Listen, I can handle the organisation down here and my boys will handle the construction of the base fine enough. Actually, all you do down here is to stand in the workers' way. ...", + "But there might be something for you to do outside the base. We need to learn more about the land up there. Take the lift and do some exploring. Find a passage leading out of the mountains. ...", + "Do not explore any further though. You never know whom you might be messing with." + }, cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 1) + player:setStorageValue(Storage.TheNewFrontier.Mission01, 1) --Questlog, The New Frontier Quest "Mission 01: New Land" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheNewFrontier.Questline) == 2 then + npcHandler:say("Excellent. Although we have no idea what awaits us in this foreign land, it is always good to know something more about our surroundings.", cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 3) + player:setStorageValue(Storage.TheNewFrontier.Mission01, 3) --Questlog, The New Frontier Quest "Mission 01: New Land" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheNewFrontier.Questline) == 3 then + npcHandler:say({ + "Things are running fine so far. Actually so fine that we are short of supplies and men. I'd send a letter home but I guess sending you to get some assistance gives the whole affair a bit more urgency. ...", + "So please travel back to Kazordoon. In the western mines outside of The Big Old One, you'll find Melfar of the imperial mining guild. Ask him to send some more miners and wood. When you return, I might have some more interesting missions for you." + }, cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 4) + player:setStorageValue(Storage.TheNewFrontier.Mission02, 1) --Questlog, The New Frontier Quest "Mission 02: From Kazordoon With Love" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheNewFrontier.Questline) == 7 then + npcHandler:say("That's good news for sure. It will give our operation a new impulse. However, only if there is not some unexpected trouble ahead. Well, we'll talk about that when we discuss your next {mission}.", cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 8) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheNewFrontier.Questline) == 8 then + npcHandler:say({ + "Our guards reported some nightly visitors. They chased them through the mountains but lost them when the fugitives climbed up some vines. ...", + "It could easily be some trap and I'm somewhat reluctant to send you there, but we can't allow some invisible aggressor to spy on us and maybe to prepare an attack. ...", + "Find these vines in this mountain, climb up there and find out who is spying on us! If they mean harm, get rid of them if possible. ...", + "If they are too powerful, just retreat and we will have to re-evaluate the situation. If they are harmless, all the better." + }, cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 9) + player:setStorageValue(Storage.TheNewFrontier.Mission03, 1) --Questlog, The New Frontier Quest "Mission 03: Strangers in the Night" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheNewFrontier.Questline) == 10 then + npcHandler:say({ + "Primitive humans you say? These are most startling news, that's for sure. Well, I guess I'll send some victuals we can spare as a sign of our good will. ...", + "However, our miners encountered another problem in the meantime. I'm afraid this will be your next {mission}" + }, cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 11) + player:setStorageValue(Storage.TheNewFrontier.Mission03, 3) --Questlog, The New Frontier Quest "Mission 03: Strangers in the Night" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheNewFrontier.Questline) == 11 then + npcHandler:say({ + "It seems things went from bad to worse! First we had some problems with the mine shafts we were building, and now that we found some precious veins in one of the new mines, and it happens to be the holiday resort of some hostile stone creatures! ...", + "Nothing we dwarfs couldn't handle alone, but I rather thought this could be something interesting for an adventurer like you. ...", + "So I reserved you the privilege to slay the leader! Use the mining lift to reach mine A07. The more stone creatures you kill, the better. Your mission, however, is to slay their leader, most likely some special stone beast." + }, cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 12) + player:setStorageValue(Storage.TheNewFrontier.Mission04, 1) --Questlog, The New Frontier Quest "Mission 04: The Mine Is Mine" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheNewFrontier.Questline) == 13 then + npcHandler:say("Shortly after you killed that creature, the others crumbled to dust and stone. I hope this incident does not foreshadow similar problems in our mines. However, for now I have other things to take care of and you have other {missions} to accomplish. ", cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 14) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheNewFrontier.Questline) == 14 then + npcHandler:say({ + "Things are getting more and more complicated. You need to convince our friends that some intervention for their part is needed. ...", + "We've come a long way with our own resources, but now our resources are short and we need the others to step in. I want you to negotiate some more support from our partners. ... ", + "You'll need all your diplomacy and influence. If you blow the negotiations, look for a guy called Black Bert in Thais. ...", + "He has access to all kind of odd items, and he might have just the right bribe to convince someone to continue negotiations. ...", + "It will not be as easy as it might sound. So watch your words and your manners and keep in mind whom you are talking to. ...", + "Different strategies might be necessary for different people. You may try to FLATTER, THREATEN, IMPRESS, BLUFF, PLEA or to REASON with them. You probably need some luck as well. ... ", + "And now listen: We need more workers for the mines. The technomancers told us that a guy named Telas, who lives in Edron, copied the worker golem technology from Yalahar. Convince him to send us some of these golems. ... ", + "Further, we have more ore and end products than we can use right now. So we need someone to buy all the surplus. Convince Leeland Slim in Venore that the local traders step in as resellers. ... ", + "Another issue at hand is our lack of drilling worms. That should not be a big problem though. Just talk to the worm tamer in Kazordoon. If he does not get mad about you, there should be no problem to get his support. ... ", + "Also, now that our monetary resources are used up and not much cash is coming in, we need additional help to finance this venture. Thais has promised money in advance, but we haven't seen any of this support, yet. ... ", + "Convince the Thaian king to send us the promised money right now. ...", + "Another problem we need to solve is the exploration of our surroundings. We need to know friends and enemies, and find out about the plants and beasts in the vicinity and learn what is edible and what is dangerous. ... ", + "This is all stuff the Explorer Society is interested in. It should be easy to convince their representative in Port Hope. ...", + "At last, with the growing numbers of adventurers here, not only the security of the base is growing but also the demand for certain supplies. I'd like the Edron academy to open up a shop in the base. We need to keep you adventurers happy, don't we? ... ", + "Well, I hope you understand the importance of this mission and got what it takes to fulfil it. So hurry up and get us the needed support." + }, cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 15) + player:setStorageValue(Storage.TheNewFrontier.Mission05, 1) --Questlog, The New Frontier Quest "Mission 05: Getting Things Busy" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheNewFrontier.Questline) == 15 then + if player:getStorageValue(Storage.TheNewFrontier.BribeKing) == 1 and player:getStorageValue(Storage.TheNewFrontier.BribeLeeland) == 1 and player:getStorageValue(Storage.TheNewFrontier.BribeExplorerSociety) == 1 and player:getStorageValue(Storage.TheNewFrontier.BribeWydrin) == 1 and player:getStorageValue(Storage.TheNewFrontier.BribeTelas) == 1 and player:getStorageValue(Storage.TheNewFrontier.BribeHumgolf) == 1 then + npcHandler:say("You did an excellent job! With all this help Farmine will grow and prosper. While we put all available resources into building this base, I have another urgent {mission} for you.", cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 16) + npcHandler.topic[cid] = 0 + end + elseif player:getStorageValue(Storage.TheNewFrontier.Questline) == 16 then + npcHandler:say({ + "Our new friends, those primitive humans sent us a warning. According to them, the 'green men' of the plains plan an attack on the mountains. ...", + "Considering their expected number, there is no chance for us to beat them off. We might be able to hold our ground for a while, but without access to the surface and under constant attacks, we might have to abandon the base. ...", + "Now, I'm aware that you cannot stop an entire army by yourself, but desperate situations call for desperate measures. I ask you to find the leaders of the orcs and - well do something. ...", + "Scare them, bribe them, give them another target or whatever. As futile as it may sound: Try to talk to their leaders in some way and make them stop their attack plans. This is our only hope." + }, cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 17) + player:setStorageValue(Storage.TheNewFrontier.Mission06, 1) --Questlog, The New Frontier Quest "Mission 06: Days Of Doom" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheNewFrontier.Questline) == 20 then + npcHandler:say({ + "Oh my. What a mess you have gotten yourself into. Well, at least you made it out alive. Whatever the value of a minotaur's promise might be, I guess that is the best we can get. ...", + "Of course all those revelations lead to new problems and a new mission for you." + }, cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 21) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheNewFrontier.Questline) == 21 then + npcHandler:say({ + "Ooook. Now that we managed to keep those orcs and minotaurs at bay at least for a while, we learn that the real meanies over here are some lizardmen. Just great, isn't it?. ...", + "So you might already guess your next mission: Find a way to hold those lizards off. Find them, contact them, talk to them, scare them, bribe them, whatever. Just keep that snakes away if anyhow possible. ...", + "If the orcs are right, they are somewhere in or behind those mountains in the north. I doubt you can reason with them in any way, but you'll have to try for the sake of Farmine." + }, cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 22) + player:setStorageValue(Storage.TheNewFrontier.Mission07, 1) --Questlog, The New Frontier Quest "Mission 07: Messengers Of Peace" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheNewFrontier.Questline) == 27 then + npcHandler:say({ + "Oh, my! That sounds like a real mess. For now this dragon empire seems otherwise engaged, but we will be on guard thanks to you my friend. We will continue to fortify the base. ...", + "This leaves not much to do for you down here. I recommend you continue to explore this strange new land. ...", + "I'm pretty sure there are several opportunities at hand for an adventurer like you. ...", + "Perhaps you can help the primitives you encountered. Who knows, maybe even those minotaurs give you a chance to fortify this fragile peace between us. ...", + "Even some of the people here in the base might offer you some tasks sooner or later. If you prefer, you can also do some exploring, hunting and good ol' plundering on your own of course. ...", + "This new land is yours to be taken, so to say. Go out and make your fortune! With Farmine you have always a safe haven to return to. ...", + "Oh and one last thing: We convinced a carpet pilot to join us here. You'll find him on top of our lift in the mountains. I think he can offer you fast access to some cities back home." + }, cid) + player:addExperience(8000, true) + player:addOutfit(335) + player:addOutfit(336) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:setStorageValue(Storage.TheNewFrontier.Questline, 28) + player:setStorageValue(Storage.TheNewFrontier.Mission10, 1) --Questlog, The New Frontier Quest "Mission 10: New Horizons" + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Hello, |PLAYERNAME|. You've come at a good time for our {project}.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/orc_berserker_npc.lua b/data/npc/scripts/orc_berserker_npc.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/orc_berserker_npc.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/oressa.lua b/data/npc/scripts/oressa.lua new file mode 100644 index 00000000000..25ccb7a754f --- /dev/null +++ b/data/npc/scripts/oressa.lua @@ -0,0 +1,390 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + {text = "You can't take it all with you - sell your Dawnport things before \z + you receive the gear of your definite vocation!"}, + {text = "Leave all Dawnport things behind you and choose your destiny!"}, + {text = "Come to me if you need healing!"}, + {text = "Choose your vocation and explore the mainland!"}, + {text = "Talk to me to choose your definite vocation! Become a knight, paladin, druid or sorcerer!"}, + {text = "World needs brave adventurers like you. Choose your vocation and sail to the mainland!"}, + {text = "Poisoned? Bleeding? Wounded? I can help!"} +} + +npcHandler:addModule(VoiceModule:new(voices)) + +-- Basic keywords +keywordHandler:addKeyword({"name"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I am Oressa Fourwinds, the {healer}. " + } +) +keywordHandler:addKeyword({"healer"}, StdModule.say, + { + npcHandler = npcHandler, + text = "If you are hurt my child, I will {heal} your wounds." + } +) +keywordHandler:addKeyword({"job"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I can {heal} you if you are hurt. I can also help you choose your {vocation}. " + } +) +keywordHandler:addKeyword({"doors"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Behind each of those doors, the equipment and skills of one vocation lies - \z + sorcerer, paladin, knight or druid. ...", + "When you have reached level 8, you can choose your definite vocation. You have to talk to me to receive it, \z + and then you may open one of the doors, take up your vocation's gear, and leave the island. But be aware: ...", + "Once you have chosen your vocation and stepped through a door, you cannot go back or choose a different vocation. \z + So choose well!" + } +) +keywordHandler:addKeyword({"inigo"}, StdModule.say, + { + npcHandler = npcHandler, + text = "He has seen much, and likes to help the younger ones. If you have questions about what to do, \z + or whom to ask for anything, go to Inigo." + } +) +keywordHandler:addKeyword({"richard"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Found a new way of living and took to it like a fish to water." + } +) +keywordHandler:addKeyword({"coltrayne"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Ah. Some wounds never heal. Shipwrecked in body and mind. Nowhere to go, so he doesn't leave." + } +) +keywordHandler:addKeyword({"morris"}, StdModule.say, + { + npcHandler = npcHandler, + text = "He broods over problems he won't share. But maybe you can help him with a little quest or two." + } +) +keywordHandler:addKeyword({"hamish"}, StdModule.say, + { + npcHandler = npcHandler, + text = "He lives only for his experiments and potions" + } +) +keywordHandler:addKeyword({"dawnport"}, StdModule.say, + { + npcHandler = npcHandler, + text = { + "This is a strange place. Many beings are called to it. I dreamed of it long before I came here. ...", + "Something spoke to me, telling me I had to be its voice; a voice of the Oracle here for the sake of \z + the adventurers that would come to defend {World} against evil and need to {choose} their destiny." + } + } +) +keywordHandler:addKeyword({"rookgaard"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I have heard of it, yes." + } +) + +--From topic of vocation to topic of the "yes" msg (choosing vocation) +local topicTable = { + [5] = VOCATION.ID.KNIGHT, + [6] = VOCATION.ID.PALADIN, + [7] = VOCATION.ID.DRUID, + [8] = VOCATION.ID.SORCERER +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + local health = player:getHealth() + + local vocationDefaultMessages = { + "A vocation is your profession and destiny, determining your skills and way of fighting. \z + There are four vocations in Tibia: {knight}, {sorcerer}, {paladin} or {druid}. \z + Each one has its unique special abilities. ... ", + "When you leave the outpost through one of the four gates upstairs, you will be equipped with \z + training gear of a specific vocation in order to defend yourself against the monsters outside. ... ", + "You can try them out as often as you wish to. When you have gained enough experience to reach level 8, \z + you are ready to choose the definite vocation that is to become your destiny. ... ", + "Think carefully, as you can't change your vocation later on! You will have to choose your vocation in order \z + to leave Dawnport for the main continent through one of these {doors} behind me. ... ", + "Talk to me again when you are ready to choose your vocation, and I will set you on your way. " + } + + -- Heal and help dialog + if msgcontains(msg, "healing") and npcHandler.topic[cid] == 0 then + if player:getLevel() < 8 then + if health < 40 or player:getCondition(CONDITION_POISON) then + if health < 40 then + player:addHealth(40 - health) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + end + if player:getCondition(CONDITION_POISON) then + player:removeCondition(CONDITION_POISON) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + end + npcHandler:say("You are hurt, my child. I will heal your wounds.", cid) + npcHandler.topic[cid] = 0 + else + return npcHandler:say("You do not need any healing right now.", cid) + end + end + elseif msgcontains(msg, "help") and npcHandler.topic[cid] == 0 then + if player:getCondition(CONDITION_POISON) == nil or health > 40 then + return npcHandler:say("You do not need any healing right now.", cid) + end + if health < 40 or player:getCondition(CONDITION_POISON) then + if health < 40 then + player:addHealth(40 - health) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + end + if player:getCondition(CONDITION_POISON) then + player:removeCondition(CONDITION_POISON) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + end + npcHandler:say("You are hurt, my child. I will heal your wounds.", cid) + npcHandler.topic[cid] = 0 + end + -- Vocation dialog + elseif npcHandler.topic[cid] == 0 and msgcontains(msg, "vocation") then + npcHandler:say(vocationDefaultMessages, cid, false, true, 10) + npcHandler.topic[cid] = 0 + -- Choosing dialog start + elseif msgcontains(msg, "choosing") or msgcontains(msg, "choose") and npcHandler.topic[cid] == 0 then + if player:getLevel() >= 8 then + npcHandler:say("I'll help you decide. \z + Tell me: Do you like to keep your {distance}, or do you like {close} combat?", cid) + npcHandler.topic[cid] = 2 + else + npcHandler:say(vocationDefaultMessages, cid, false, true, 10) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "distance") and npcHandler.topic[cid] == 2 then + npcHandler:say("Tell me: Do you prefer to fight with {bow} and {spear}, or do you want to cast {magic}?", cid) + npcHandler.topic[cid] = 3 + -- knight + elseif msgcontains(msg, "close") and npcHandler.topic[cid] == 2 then + npcHandler:say( + { + "Then you should choose the {vocation} of a knight and become a valiant fighter with sword and shield. ...", + "Knights are the toughest of all vocations. They can take more damage and carry more items than the other \z + vocations, but they will deal less damage than paladins, druids or sorcerers. ...", + "Knights can wield one- or two-handed swords, axes and clubs, and they can cast a few spells to draw a \z + monster's attention to them. ...", + "So tell me: DO YOU WISH TO BECOME A VALIANT KNIGHT? Answer with a proud {YES} if that is your choice!" + }, + cid, false, true, 10) + npcHandler.topic[cid] = 5 + -- Paladin + elseif msgcontains(msg, "bow") or msgcontains(msg, "spear") and npcHandler.topic[cid] == 3 then + npcHandler:say( + { + "Then you should join the ranks of the paladins, noble hunters and rangers of the wild, who rely on the \z + swiftness of movement and ranged attacks. ...", + "Paladins are jacks of all trades. They are tougher than the magically gifted and can carry more items \z + than druids or sorcerers, but they can take not as much damage as a knight can. ...", + "Paladins deal more damage than knights but less than druids or sorcerers, and have the longest range \z + in their distance attacks. ...", + "They can also use holy magic to slay the unholy and undead in particular. ...", + "DO YOU WISH TO BECOME A DARING PALADIN? Answer with a proud {YES} if that is your choice!" + }, + cid, false, true, 10) + npcHandler.topic[cid] = 6 + -- Mage + elseif msgcontains(msg, "magic") and npcHandler.topic[cid] == 3 then + npcHandler:say("Tell me: Do you prefer to {heal} and cast the power of nature and ice, or do you want to rain \z + fire and {death} on your foes?", cid) + npcHandler.topic[cid] = 4 + -- Druid + elseif msgcontains(msg, "heal") and npcHandler.topic[cid] == 4 then + npcHandler:say( + { + "Then you should learn the ways of the druids, healers and powerful masters of natural magic. ...", + "Druids can heal their friends and allies, but they can also cast powerful ice and earth magic \z + to kill their enemies. They can do a little energy, fire or death damage as well. ...", + "Druids cannot take much damage or carry many items, but they deal \z + much more damage than paladins or knights. ...", + "So tell me: DO YOU WISH TO BECOME A SAGACIOUS DRUID? Answer with a proud {YES} if that is your choice!" + }, + cid, false, true, 10) + npcHandler.topic[cid] = 7 + -- Sorcerer + elseif msgcontains(msg, "death") and npcHandler.topic[cid] == 4 then + npcHandler:say( + { + "Then you should become a sorcerer, a mighty wielder of deathly energies and arcane fire. ...", + "Sorcerers are powerful casters of magic. They use fire, energy and death magic to lay low their enemies. \z + They can do a little ice or earth damage as well. ...", + "Sorcerers cannot take much damage or carry many items, \z + but they deal much more damage than paladins or knights. ...", + "So tell me: DO YOU WISH TO BECOME A POWERFUL SORCERER? Answer with a proud {YES} if that is your choice!" + }, + cid, false, true, 10) + npcHandler.topic[cid] = 8 + -- Choosing dialog start + elseif msgcontains(msg, "decided") and npcHandler.topic[cid] == 0 then + npcHandler:say("So tell me, which {vocation} do you want to choose: {knight}, {sorcerer}, {paladin} or {druid}?", cid) + -- Say vocations name + elseif msgcontains(msg, "sorcerer") and npcHandler.topic[cid] == 0 then + local message = { + "Sorcerers are powerful casters of death, energy and fire magic. \z + They can do a little ice or earth damage as well. ...", + "Sorcerers cannot take much damage or carry many items, but they deal more damage than paladins or knights, \z + and can target several enemies. ...", + "If you wish to be a caster of fire and energy, hurling death magic at your foes, \z + you should consider choosing the sorcerer vocation." + } + + if player:getLevel() >= 8 then + table.insert(message, "So tell me: DO YOU WISH TO BECOME A POWERFUL SORCERER?".. + " Answer with a proud {YES} if that is your choice!") + npcHandler.topic[cid] = 8 + else + npcHandler.topic[cid] = 0 + end + + npcHandler:say(message, cid, false, true, 10) + elseif msgcontains(msg, "druid") and npcHandler.topic[cid] == 0 then + local message = { + "Druids are healers and powerful masters of ice and earth magic. \z + They can also do a little energy, fire or death damage as well. ... ", + "Druids cannot take much damage or carry many items, but they deal more damage than paladins or knights, \z + and can target several enemies. ... ", + "If you wish to be a healer and wielder of powerful natural magic, \z + you should consider choosing the druid vocation." + } + + if player:getLevel() >= 8 then + table.insert(message, "So tell me: DO YOU WISH TO BECOME A SAGACIOUS DRUID?".. + " Answer with a proud {YES} if that is your choice!") + npcHandler.topic[cid] = 7 + else + npcHandler.topic[cid] = 0 + end + + npcHandler:say(message, cid, false, true, 10) + elseif msgcontains(msg, "paladin") and npcHandler.topic[cid] == 0 then + local message = { + "Paladins are sturdy distance fighters. They are tougher than druids or sorcerers and can carry more items, \z + but they are less tough than a knight. ... ", + "Paladins have the longest attack range, and can deal the most damage on a single target. ... ", + "They can also use holy magic to slay the unholy and undead in particular. ... ", + "If you like to keep a distance to your enemy, shooting while you outdistance him, \z + you should consider choosing the paladin vocation." + } + + if player:getLevel() >= 8 then + table.insert(message, "So tell me: DO YOU WISH TO BECOME A DARING PALADIN?".. + " Answer with a proud {YES} if that is your choice!") + npcHandler.topic[cid] = 6 + else + npcHandler.topic[cid] = 0 + end + + npcHandler:say(message, cid, false, true, 10) + elseif msgcontains(msg, "knight") and npcHandler.topic[cid] == 0 then + local message = { + "Knights are stalwart melee fighters, the toughest of all vocations. They can take more damage and carry \z + more items than the other vocations, but they will deal less damage than paladins, druids or sorcerers. ... ", + "Knights can wield one- or two-handed swords, axes and clubs, and they can cast a few spells to draw a \z + monster's attention to them. ... ", + "If you want to be a tough melee fighter who can resist much longer than anyone else, \z + you should consider choosing the knight vocation." + } + + if player:getLevel() >= 8 then + table.insert(message, "DO YOU WISH TO BECOME A VALIANT KNIGHT? Answer with a proud {YES} if that is your choice!") + npcHandler.topic[cid] = 5 + else + npcHandler.topic[cid] = 0 + end + + npcHandler:say(message, cid, false, true, 10) + elseif ((npcHandler.topic[cid] >= 5) and (npcHandler.topic[cid] <= 8)) then + if msgcontains(msg, "yes") then + for index, value in pairs(topicTable) do + if npcHandler.topic[cid] == index then + if player:getStorageValue(Storage.Dawnport.DoorVocation) == -1 then + -- Change to new vocation, convert magic level and skills and set proper stats + player:changeVocation(value) + player:setStorageValue(Storage.Dawnport.DoorVocation, value) + else + npcHandler.topic[cid] = 0 + return true + end + end + end + -- Remove Mainland smuggling items + removeMainlandSmugglingItems(player) + npcHandler:say( + { + "SO BE IT. CAST OFF YOUR TRAINING GEAR AND RISE, NOBLE ".. player:getVocation():getName():upper() .. "! ...", + "Go through the second door from the right. Open the chest and take the equipment inside \z + before you leave to the north. ...", + "Take the ship to reach the Mainland. Farewell, friend and good luck in all you undertake!" + }, + cid, false, true, 10) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") then + local vocationMessage = { + [5] = "{paladin}, {sorcerer} or {druid}", + [6] = "{knight}, {sorcerer} or {druid}", + [7] = "{knight}, {paladin} or {sorcerer}", + [8] = "{knight}, {paladin} or {druid}" + } + npcHandler:say( + { + "As you wish. If you wish to learn something about the ".. + vocationMessage[npcHandler.topic[cid]].. + " vocation, tell me.", + }, + cid, false, true, 10) + npcHandler.topic[cid] = 0 + end + end + return true +end + +local function greetCallback(cid) + local player = Player(cid) + if player:getLevel() >= 8 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome, young adventurer. Tell me if you need help in \z + {choosing} your {vocation}, or if you have {decided} on the {vocation} you want to choose.") + else + npcHandler:setMessage(MESSAGE_GREET, "Welcome to the temple of Dawnport, child. \z + If you need {healing}, I can help you. Ask me about a {vocation} if you need counsel.") + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) + +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye, child.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ormuhn.lua b/data/npc/scripts/ormuhn.lua new file mode 100644 index 00000000000..7e4e3350d78 --- /dev/null +++ b/data/npc/scripts/ormuhn.lua @@ -0,0 +1,233 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addSpellKeyword({'find', 'person'}, + { + npcHandler = npcHandler, + spellName = 'Find Person', + price = 80, + level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'great', 'light'}, + { + npcHandler = npcHandler, + spellName = 'Great Light', + price = 500, + level = 13, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'light'}, + { + npcHandler = npcHandler, + spellName = 'Light', + price = 0, + level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'magic', 'rope'}, + { + npcHandler = npcHandler, + spellName = 'Magic Rope', + price = 200, + level = 9, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'cure', 'poison'}, + { + npcHandler = npcHandler, + spellName = 'Cure Poison', + price = 150, + level = 10, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'intense', 'wound', 'cleansing'}, + { + npcHandler = npcHandler, + spellName = 'Intense Wound Cleansing', + price = 6000, + level = 80, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'wound', 'cleansing'}, + { + npcHandler = npcHandler, + spellName = 'Wound Cleansing', + price = 0, + level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'levitate'}, + { + npcHandler = npcHandler, + spellName = 'Levitate', + price = 500, + level = 12, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'haste'}, + { + npcHandler = npcHandler, + spellName = 'Haste', + price = 600, + level = 14, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'brutal', 'strike'}, + { + npcHandler = npcHandler, + spellName = 'Brutal Strike', + price = 1000, + level = 16, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'charge'}, + { + npcHandler = npcHandler, + spellName = 'Charge', + price = 1300, + level = 25, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'whirlwind', 'throw'}, + { + npcHandler = npcHandler, + spellName = 'Whirlwind Throw', + price = 1500, + level = 28, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'groundshaker'}, + { + npcHandler = npcHandler, + spellName = 'Groundshaker', + price = 1500, + level = 33, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'fierce', 'berserk'}, + { + npcHandler = npcHandler, + spellName = 'Fierce Berserk', + price = 7500, + level = 90, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'berserk'}, + { + npcHandler = npcHandler, + spellName = 'Berserk', + price = 2500, + level = 35, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'inflict', 'wound'}, + { + npcHandler = npcHandler, + spellName = 'Inflict Wound', + price = 2500, + level = 40, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'cure', 'bleeding'}, + { + npcHandler = npcHandler, + spellName = 'Cure Bleeding', + price = 2500, + level = 45, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'intense', 'recovery'}, + { + npcHandler = npcHandler, + spellName = 'Intense Recovery', + price = 10000, + level = 100, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'recovery'}, + { + npcHandler = npcHandler, + spellName = 'Recovery', + price = 4000, + level = 50, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'front', 'sweep'}, + { + npcHandler = npcHandler, + spellName = 'Front Sweep', + price = 4000, + level = 70, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'annihilation'}, + { + npcHandler = npcHandler, + spellName = 'Annihilation', + price = 20000, + level = 110, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) + +keywordHandler:addKeyword({'healing', 'spells'}, StdModule.say, + { + npcHandler = npcHandler, + text = "In this category I have '{Bruise Bane}', '{Cure Bleeding}', '{Wound Cleansing}', '{Cure Poison}', '{Intense Wound Cleansing}', '{Recovery}' and '{Intense Recovery}'." + } +) +keywordHandler:addKeyword({'attack', 'spells'}, StdModule.say, + { + npcHandler = npcHandler, + text = {"In this category I have '{Whirlwind Throw}', '{Groundshaker}', '{Berserk}' and '{Fierce Berserk}' as well as ...", "'{Brutal Strike}', '{Front Sweep}', '{Inflict Wound}' and '{Annihilation}'"} + } +) +keywordHandler:addKeyword({'support', 'spells'}, StdModule.say, + { + npcHandler = npcHandler, + text = "In this category I have '{Light}', '{Find Person}', '{Magic Rope}', '{Levitate}', '{Haste}', '{Charge}' and '{Great Light}'." + } +) +keywordHandler:addKeyword({'spells'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'I can teach you {healing spells}, {attack spells} and {support spells}. What kind of spell do you wish to learn? You can also tell me for which level you would like to learn a spell, if you prefer that.' + } +) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/orockle.lua b/data/npc/scripts/orockle.lua new file mode 100644 index 00000000000..ac84cd53ea9 --- /dev/null +++ b/data/npc/scripts/orockle.lua @@ -0,0 +1,42 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + +--[[ + if msgcontains(msg, "fight") then + npcHandler:say("You can help in the fight against the hive. There are several missions available to destabilise the hive. Just ask for them if you want to learn more. After completing many missions you might be worthy to get a reward.", cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "mission") then + npcHandler:say("You could try to blind the hive, you might disrupt its digestion, you could gather acid or you can disable the swarm pores. ...", cid) + npcHandler.topic[cid] = 2 + + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 2 then + npcHandler:say("So be it. Now you are a member of the inquisition. You might ask me for a mission to raise in my esteem.", cid) + npcHandler.topic[cid] = 0 + end + end +--]] + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ortheus.lua b/data/npc/scripts/ortheus.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/ortheus.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/oswald.lua b/data/npc/scripts/oswald.lua new file mode 100644 index 00000000000..a8781f7a5a1 --- /dev/null +++ b/data/npc/scripts/oswald.lua @@ -0,0 +1,91 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'gods'}, StdModule.say, {npcHandler = npcHandler, text = "I think the gods are too busy to care about us mortals, hmm... that makes me feel godlike, too."}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am honored to be the assistant of the great, the illustrious, the magnificent {Durin}!"}) +keywordHandler:addKeyword({'important'}, StdModule.say, {npcHandler = npcHandler, text = "I am honored to be the assistant of the great, the illustrious, the magnificent {Durin}!"}) +keywordHandler:addKeyword({'assistant'}, StdModule.say, {npcHandler = npcHandler, text = "I have a job of great responsibility, mostly I keep annoying persons away from my boss."}) +keywordHandler:addKeyword({'annoying'}, StdModule.say, {npcHandler = npcHandler, text = "You better don't ask, you wouldn't like the answer."}) +keywordHandler:addKeyword({'king'}, StdModule.say, {npcHandler = npcHandler, text = "Ah, yes, yes, hail to King {Tibianus}! Long live the king and so on..."}) +keywordHandler:addKeyword({'magic'}, StdModule.say, {npcHandler = npcHandler, text = "I overheard a conversation of officials, that magic will be forbidden soon."}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "My name is Oswald, but let's proceed, I am a very busy man."}) +keywordHandler:addKeyword({'sell'}, StdModule.say, {npcHandler = npcHandler, text = "Hey, I am not a shopkeeper, I am an important man!"}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = "It is nearly tea time, so please hurry!"}) +keywordHandler:addKeyword({'weapon'}, StdModule.say, {npcHandler = npcHandler, text = "It's rumoured that Sam does not forge all weapons himself, but buys them from his cousin, who is married to a cyclops."}) +keywordHandler:addKeyword({'dungeon'}, StdModule.say, {npcHandler = npcHandler, text = " If you want to see dungeons just don't pay your taxes."}) +keywordHandler:addKeyword({'excalibug'}, StdModule.say, {npcHandler = npcHandler, text = "It's beyond all doubt that certain sinister elements in our city have certain knowledge about this myth."}) +keywordHandler:addKeyword({'necromants nectar'}, StdModule.say, {npcHandler = npcHandler, text = "You are not the first one to ask about that. Am I the only one that preferes wine to such disgusting stuff?"}) +keywordHandler:addKeyword({'benjamin'}, StdModule.say, {npcHandler = npcHandler, text = "What do you expect from ex-soldiers? He is nuts! Hacked on the head far too often."}) +keywordHandler:addKeyword({'bozo'}, StdModule.say, {npcHandler = npcHandler, text = "Isn't he the artist formerly known as the prince?"}) +keywordHandler:addKeyword({'Chester Kahs'}, StdModule.say, {npcHandler = npcHandler, text = "I never found any rumour concerning him, isn't that odd?"}) +keywordHandler:addKeyword({'elane'}, StdModule.say, {npcHandler = npcHandler, text = "They say she killed over a dozen husbands already."}) +keywordHandler:addKeyword({'gamel'}, StdModule.say, {npcHandler = npcHandler, text = "This man lives in the darkness like a rat and is also as handsome as one of them. He surely is up to no good and often consorts with sinister strangers."}) +keywordHandler:addKeyword({'sinister strangers'}, StdModule.say, {npcHandler = npcHandler, text = "Just last week a one eyed man, who had a room at Frodo's, met him in the middle of the night."}) +keywordHandler:addKeyword({'gorn'}, StdModule.say, {npcHandler = npcHandler, text = "He sells his scrolls far too expensive."}) +keywordHandler:addKeyword({'gregor'}, StdModule.say, {npcHandler = npcHandler, text = "I was told he lost a body part or two in duels... if you know what I mean."}) +keywordHandler:addKeyword({'muriel'}, StdModule.say, {npcHandler = npcHandler, text = "He is rumoured to summon kinky demons to... well you know."}) +keywordHandler:addKeyword({'rumours'}, StdModule.say, {npcHandler = npcHandler, text = "You know a rumour? TELL ME! TELL ME! TELL ME!"}) +keywordHandler:addKeyword({'anything'}, StdModule.say, {npcHandler = npcHandler, text = "Fascinating! Absolutely fascinating!"}) +keywordHandler:addKeyword({'quentin'}, StdModule.say, {npcHandler = npcHandler, text = "I heard he was a ladies' man in younger days. In our days he is rumoured to wear women clothes now and then."}) +keywordHandler:addKeyword({'sam'}, StdModule.say, {npcHandler = npcHandler, text = "A simple shopkeeper with minor intelligence."}) +keywordHandler:addKeyword({'goshnar'}, StdModule.say, {npcHandler = npcHandler, text = "They say he isn't truly dead. He was... or is a necromant after all."}) +keywordHandler:addKeyword({'lugri'}, StdModule.say, {npcHandler = npcHandler, text = " Some say he is Ferumbras in disguise."}) +keywordHandler:addKeyword({'partos'}, StdModule.say, {npcHandler = npcHandler, text = "What a shame. He claimed to be the king of thiefs and was caught stealing some fruit."}) +keywordHandler:addKeyword({'durin'}, StdModule.say, {npcHandler = npcHandler, text = "Just between you and me, he can be quite a tyrant."}) +keywordHandler:addKeyword({'monsters'}, StdModule.say, {npcHandler = npcHandler, text = "AHHHH!!! WHERE??? WHERE???"}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, 'invitation') then + if player:getStorageValue(Storage.ThievesGuild.Mission03) == 1 then + npcHandler:say('What? So why in the world should I give you an invitation? It\'s not as if you were someone important, are you?', cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + npcHandler:say('Well, rich and generous people are always welcome in the palace.If you donate 1000 gold to a fund I oversee, I\'ll give you an invitation, ok?', cid) + npcHandler.topic[cid] = 3 + elseif npcHandler.topic[cid] == 3 then + if player:removeMoneyNpc(1000) then + player:addItem(8761, 1) + player:setStorageValue(Storage.ThievesGuild.Mission03, 2) + npcHandler:say('Excellent! Here is your invitation!', cid) + else + npcHandler:say('You don\'t have enough money.', cid) + end + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'gold') then + if npcHandler.topic[cid] == 1 then + npcHandler:say('Not that I am bribeable but I doubt that you own 1000 gold pieces. Or do you?', cid) + npcHandler.topic[cid] = 2 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Oh, hello |PLAYERNAME|. What is it?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Finally!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye, and don't come back too soon.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ottokar.lua b/data/npc/scripts/ottokar.lua new file mode 100644 index 00000000000..a2f723b0f1c --- /dev/null +++ b/data/npc/scripts/ottokar.lua @@ -0,0 +1,45 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, 'belongings of deceasead') or msgcontains(msg, 'medicine') then + if player:getItemCount(13506) > 0 then + npcHandler:say('Did you bring me the medicine pouch?', cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say('I need a {medicine pouch}, to give you the {belongings of deceased}. Come back when you have them.', cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'yes') and npcHandler.topic[cid] == 1 then + if player:removeItem(13506, 1) then + player:addItem(13670, 1) + player:addAchievementProgress('Doctor! Doctor!', 100) + npcHandler:say('Here you are', cid) + else + npcHandler:say('You do not have the required items.', cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/padreia.lua b/data/npc/scripts/padreia.lua new file mode 100644 index 00000000000..d931b5a681e --- /dev/null +++ b/data/npc/scripts/padreia.lua @@ -0,0 +1,104 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + -- Tibia tales quest + if msgcontains(msg, "cough syrup") then + npcHandler:say("Do you want to buy a bottle of cough syrup for 50 gold?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, 'mission') then + if player:getStorageValue(Storage.TibiaTales.TheExterminator) == -1 then + npcHandler:say({ + 'Oh |PLAYERNAME|, thank god you came to me. Last night, I had a vision about an upcoming plague here in Carlin. ...', + 'It will originate from slimes that will swarm out of the sewers and infect every citizen with a deadly disease. Are you willing to help me save Carlin?' + }, cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(Storage.TibiaTales.TheExterminator) == 1 then + npcHandler:say('You MUST find that slime pool immediately or life here in Carlin will not be the same anymore.', cid) + elseif player:getStorageValue(Storage.TibiaTales.TheExterminator) == 2 then + local itemId = {2150, 2149, 2147, 2146} + for i = 1, #itemId do + player:addItem(itemId[i], 1) + end + player:setStorageValue(Storage.TibiaTales.TheExterminator, 3) + npcHandler:say('You did it! Even if only few of the Carliners will ever know about that, you saved all of their lives. Here, take this as a reward. Farewell!', cid) + else + npcHandler:say('Maybe the guards have something to do for you or know someone who could need some help.', cid) + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + if not player:removeMoneyNpc(50) then + npcHandler:say("You don't have enough money.", cid) + return true + end + + npcHandler:say("Thank you. Here it is.", cid) + player:addItem(4839, 1) + elseif npcHandler.topic[cid] == 2 then + player:addItem(8205, 1) + player:setStorageValue(Storage.TibiaTales.TheExterminator, 1) + npcHandler:say({ + 'I knew I could count on you. Take this highly intensified vermin poison. In my vision, I saw some kind of \'pool\' where these slimes came from. ...', + 'Pour the poison in the water to stop the demise of Carlin. Tell me about your mission after you fulfilled your task.' + }, cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Then no.", cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say('Then the downfall of Carlin is inescapable. Please think about it. You know where to find me.', cid) + npcHandler.topic[cid] = 0 + end + end + + -- The paradox tower quest + if msgcontains(msg, "crunor's caress") then + npcHandler:say("Don't ask. They were only an unimportant footnote of history.", cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "footnote") then + if player:getStorageValue(Storage.Quest.TheParadoxTower.TheFearedHugo) == 2 then + -- Questlog: The Feared Hugo (Lubo) + player:setStorageValue(Storage.Quest.TheParadoxTower.TheFearedHugo, 3) + end + npcHandler:say("They thought they had to bring Crunor to the people, if the people had not found Crunor on their own. To achieve this, they founded the inn called Crunor's Cottage, south of Mt. Sternum.", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am the grand druid of Carlin. I am responsible for the guild, the fields, and our citizens' health."}) +keywordHandler:addKeyword({'magic'}, StdModule.say, {npcHandler = npcHandler, text = "Every druid is able to learn the numerous spells of our craft."}) +--keywordHandler:addKeyword({'spell'}, StdModule.say, {npcHandler = npcHandler, text = "Sorry, I don't teach spells for your vocation."}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "I am Padreia, grand druid of our fine city."}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = "Time is just a crystal pillar - the centre of creation and life."}) +keywordHandler:addKeyword({'druids'}, StdModule.say, {npcHandler = npcHandler, text = "We are druids, preservers of life. Our magic is about defence, healing, and nature."}) +keywordHandler:addKeyword({'sorcerers'}, StdModule.say, {npcHandler = npcHandler, text = "Sorcerers are destructive. Their power lies in destruction and pain."}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome to our humble guild, wanderer. May I be of any assistance to you?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Farewell.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Farewell.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/paladin_narai.lua b/data/npc/scripts/paladin_narai.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/paladin_narai.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/palimuth.lua b/data/npc/scripts/palimuth.lua new file mode 100644 index 00000000000..948bcbc74fa --- /dev/null +++ b/data/npc/scripts/palimuth.lua @@ -0,0 +1,280 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if player:getStorageValue(Storage.InServiceofYalahar.Questline) < 1 then + player:setStorageValue(Storage.InServiceofYalahar.Questline, 3) + end + + if msgcontains(msg, "job") and not player:getStorageValue(Storage.InServiceofYalahar.Questline) == 54 then + npcHandler:say("I'm an Augur of the city of Yalahar. My special duty consists of coordinating the efforts to keep the city and its services running.", cid) + elseif msgcontains(msg, "job") then + if player:getStorageValue(Storage.InServiceofYalahar.Questline) == 54 then + npcHandler:say("Did you bring me the vampiric crest?", cid) + npcHandler.topic[cid] = 6 + end + elseif msgcontains(msg, "mission") then + if player:getStorageValue(Storage.InServiceofYalahar.Questline) == 3 then + npcHandler:say({ + "You probably heard that we have numerous problems in different quarters of our city. Our forces are limited, so we really could need some help from outsiders. ...", + "Would you like to assist us in re-establishing order in our city?" + }, cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 4 then + player:setStorageValue(Storage.InServiceofYalahar.Mission01, 1) -- StorageValue for Questlog "Mission 01: Something Rotten" + player:setStorageValue(Storage.InServiceofYalahar.Questline, 5) + npcHandler:say({ + "I hope your first mission will not scare you off. Even though, we cut off our sewer system from other parts of the city to prevent the worst, it still has deteriorated in the last decades. ...", + "Certain parts of the controls are rusty and the drains are stuffed with garbage. Get yourself a crowbar, loosen the controls and clean the pipes from the garbage. ...", + "We were able to locate the 4 worst spots in the sewers. I will mark them for you on your map so you have no trouble finding them. Report to me when you have finished your {mission}. ..." + }, cid) + player:addMapMark(Position(32823, 31161, 8), 4, "Sewer Problem 1") + player:addMapMark(Position(32795, 31152, 8), 4, "Sewer Problem 2") + player:addMapMark(Position(32842, 31250, 8), 4, "Sewer Problem 3") + player:addMapMark(Position(32796, 31192, 8), 4, "Sewer Problem 4") + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 5 then + npcHandler:say("So are you done with your work?", cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 6 then + npcHandler:say({ + "We are still present at each quarter's city wall, even though we can do little to stop the chaos from spreading. Still, our garrisons are necessary to maintain some sort of order in the city. ...", + "My superiors ask for a first hand report about the current situation in the single city quarters. I need someone to travel to our garrisons to get the reports from the guards. Are you willing to do that?" + }, cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) >= 7 and player:getStorageValue(Storage.InServiceofYalahar.Questline) <= 14 then + npcHandler:say("Did you get all the reports my superiors asked for? ", cid) + npcHandler.topic[cid] = 4 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 15 then + npcHandler:say({ + "I did my best to impress my superiors with your accomplishments and it seems that it worked quite well. They want you for their own missions now. ...", + "Missions that are more important than the ones you've fulfilled for me. However, before you leave, there are still some things I need to tell you. ...", + "Listen, I can't explain you everything in detail right now and here. You never know who might be eavesdropping. ...", + "I left some notes in the small room there. Get them and read them. Talk to me again when you've read the notes." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Mission03, 1) -- StorageValue for Questlog "Mission 03: Death to the Deathbringer" + player:setStorageValue(Storage.InServiceofYalahar.Questline, 16) + player:setStorageValue(Storage.InServiceofYalahar.NotesPalimuth, 0) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.NotesPalimuth) == 1 and player:getStorageValue(Storage.InServiceofYalahar.Questline) == 16 then + npcHandler:say({ + "Now you know as much as we do about the things happening in Yalahar. It's up to you what you do with this information. ...", + "Now leave and talk to my superior Azerus in the city centre to get your next mission. I urge you, though, to talk to me whenever he sends you on a new mission. ...", + "I think it is important that you hear my opinion about them. Now hurry. I suppose Azerus is already waiting." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Mission03, 2) -- StorageValue for Questlog "Mission 03: Death to the Deathbringer" + player:setStorageValue(Storage.InServiceofYalahar.Questline, 17) + player:setStorageValue(Storage.InServiceofYalahar.DoorToAzerus, 1) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 20 then + npcHandler:say({ + "This quarter has been sealed off years ago. To send someone there poses a high risk to spread the plague. I assume these research notes you've mentioned must be very important. ...", + "After all those years it is more than strange that someone shows interest in these notes now. Considering what has happened to the alchemists, it is rather unlikely that they contain harmless information. ...", + "I fear these notes will be used to turn the plague into some kind of weapon. Someone with this plague at his disposal could subdue the whole city by blackmailing. ...", + "I beg you to destroy these notes. Just put them into some burning oven to get rid of them and report that you did not find the notes." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 21) + player:setStorageValue(Storage.InServiceofYalahar.DoorToBog, 1) + player:setStorageValue(Storage.InServiceofYalahar.Mission03, 5) -- StorageValue for Questlog "Mission 03: Death to the Deathbringer" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 23 then + npcHandler:say({ + "Mr. West is a little paranoid. That's the reason for his immense private army of bodyguards. He could surely be helpful, especially as he rules over the former trade quarter. ...", + "If you were able to reach him without killing his henchmen, you could probably convince him that you mean no harm to him. ...", + "That would certainly cement our relationship without any needless bloodshed. Perhaps you could use the way through the sewers to avoid his men. ...", + "Mr. West is not a bad man. We should be able to work out some plans to reconstruct the city's safety as soon as he overcomes his paranoia towards us." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 24) + player:setStorageValue(Storage.InServiceofYalahar.Mission04, 2) -- StorageValue for Questlog "Mission 04: Good to be Kingpin" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 25 and player:getStorageValue(Storage.InServiceofYalahar.MrWestStatus) == 1 then + npcHandler:say({ + "You did quite well in gaining a new friend who will work together with us. ...", + "I'm sure he'll still try to gain some profit but that's still better than his former one-man rule during which he dictated his own laws." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.GoodSide, player:getStorageValue(Storage.InServiceofYalahar.GoodSide) >= 0 and player:getStorageValue(Storage.InServiceofYalahar.GoodSide) + 1 or 0) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 26) + player:setStorageValue(Storage.InServiceofYalahar.Mission04, 5) -- StorageValue for Questlog "Mission 04: Good to be Kingpin" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 28 then + npcHandler:say({ + "Warbeasts? Is this true? People are already starving. ...", + "How can we afford to feed an army of hungry beasts? They will not only strengthen the power of the Yalahari over the citizens, they also mean starvation and deathfor the poor. ...", + "Instead of breeding warbeasts, this druid should breed cattle to feed our people. Please I beg you, convince him to do that!" + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 29) + player:setStorageValue(Storage.InServiceofYalahar.TamerinStatus, 0) + player:setStorageValue(Storage.InServiceofYalahar.Mission05, 2) -- StorageValue for Questlog "Mission 05: Food or Fight" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 32 and player:getStorageValue(Storage.InServiceofYalahar.TamerinStatus) == 1 then + npcHandler:say("These are great news indeed. The people of Yalahar will be grateful. The Yalahari probably not, so take care of yourself. ", cid) + player:setStorageValue(Storage.InServiceofYalahar.GoodSide, player:getStorageValue(Storage.InServiceofYalahar.GoodSide) >= 0 and player:getStorageValue(Storage.InServiceofYalahar.GoodSide) + 1 or 0) -- Side Storage + player:setStorageValue(Storage.InServiceofYalahar.Questline, 33) + player:setStorageValue(Storage.InServiceofYalahar.Mission05, 8) -- StorageValue for Questlog "Mission 05: Food or Fight" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 35 then + npcHandler:say({ + "What a sick idea to misuse tortured souls to power some device! Though, this charm might be useful to free these poor souls. ...", + "Please capture the souls as you have been instructed and then bring the charm to me. I will see to it that the souls are freed to go to the afterlife in peace." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 36) + player:setStorageValue(Storage.InServiceofYalahar.Mission06, 2) -- StorageValue for Questlog "Mission 06: Frightening Fuel" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 37 then + if player:removeItem(9742, 1) then + npcHandler:say({ + "I thank you also in the name of these poor lost souls. I will send the charm to a priest who is able to release them. ...", + "Tell the Yalahari that the charm was destroyed by the energy it contained." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 38) + player:setStorageValue(Storage.InServiceofYalahar.Mission06, 4) -- StorageValue for Questlog "Mission 06: Frightening Fuel" + player:setStorageValue(Storage.InServiceofYalahar.QuaraState, 1) + player:setStorageValue(Storage.InServiceofYalahar.GoodSide, player:getStorageValue(Storage.InServiceofYalahar.GoodSide) >= 0 and player:getStorageValue(Storage.InServiceofYalahar.GoodSide) + 1 or 0) -- Side Storage + npcHandler.topic[cid] = 0 + end + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 40 then + npcHandler:say({ + "The quara are indeed a threat. Yet, they are numerous and reproduce quickly. Slaying some of them will only enrage them even more. ...", + "The quara have been there for many generations. They have never threatened anyone who stayed out of their watery realm. ...", + "It would be much more useful to find out what the quara are so upset about. Better avoid slaying their leaders as this will only further the animosities." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 41) + player:setStorageValue(Storage.InServiceofYalahar.DoorToQuara, 1) + player:setStorageValue(Storage.InServiceofYalahar.Mission07, 2) -- StorageValue for Questlog "Mission 07: A Fishy Mission" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 42 and player:getStorageValue(Storage.InServiceofYalahar.QuaraState) == 1 then + npcHandler:say("Oh no! So that's the reason for the quara attacks! I will do my best to close these sewage pipes. We will have to use other drains. ", cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 43) + player:setStorageValue(Storage.InServiceofYalahar.Mission07, 5) -- StorageValue for Questlog "Mission 07: A Fishy Mission" + player:setStorageValue(Storage.InServiceofYalahar.GoodSide, player:getStorageValue(Storage.InServiceofYalahar.GoodSide) >= 0 and player:getStorageValue(Storage.InServiceofYalahar.GoodSide) + 1 or 0) -- Side Storage + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 44 then + npcHandler:say({ + "The constant unrest in the city is to a great extent caused by the lack of food. Weapons will only serve to suppress the poor. ...", + "The factory you were sent to was once used for the production of food. Somewhere in the factory you might find an old pattern crystal for the production of food. ...", + "If you use it on the controls instead of the weapon pattern, you will ensure that our people are supplied with the desperately needed food. ..." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 45) + player:setStorageValue(Storage.InServiceofYalahar.DoorToMatrix, 1) + player:setStorageValue(Storage.InServiceofYalahar.Mission08, 2) -- StorageValue for Questlog "Mission 08: Dangerous Machinations" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 48 then + npcHandler:say({ + "Listen, I know you have worked for Azerus and his friends, but it is not too late to change your mind! I beg you to rethink your loyalties. ...", + "The fate of the whole city might depend on your decision! Think about your options carefully." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 49) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 49 or player:getStorageValue(Storage.InServiceofYalahar.Questline) == 48 then + npcHandler:say("So do you want to side with me? ", cid) + npcHandler.topic[cid] = 5 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 50 and player:getStorageValue(Storage.InServiceofYalahar.SideDecision) == 1 then + npcHandler:say({ + "I cannot tell you how we acquired this information, but we have heard that a circle of Yalahari is planning some kind of ritual. ...", + "They plan to create a portal for some powerful demons and to unleash them in the city to 'purge' it once and for all. ...", + "I doubt those poor fools will be able to control such entities. I can't figure out how they came up with such an insane idea, but they have to be stopped. ...", + "The entrance to their inner sanctum has been opened for you. Please hurry and stop them before it's too late. Be prepared for a HARD battle! Better gather some friends to assist you." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 51) + player:setStorageValue(Storage.InServiceofYalahar.DoorToLastFight, 1) + player:setStorageValue(Storage.InServiceofYalahar.Mission10, 2) -- StorageValue for Questlog "Mission 10: The Final Battle" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 52 then + npcHandler:say({ + "So the Yalahari that opposed us are dead or fled from the city. This should bring us more stability and perhaps a true chance to rebuild the city. ...", + "Still, I wonder from where they gained some of the Yalahari secrets. Did they find some source of knowledge? ...", + "And if so, is this source still around so that we can use it for the benefit of our city? What really troubles me is that none of those false Yalahari had the personality of agreat leader. ...", + "Quite the opposite, they were opportunistic and not exactly bold. Perhaps they were led by some greater power which stayed behind the scenes. ...", + "I'm afraid we have not seen the last chapter of Yalahar's drama. But anyhow, I wish to thank you for putting your life at stake for our cause. ...", + "I allow you to enter the Yalaharian treasure room. I'm sure that you can put what you find inside to better use than them. Choose one chest, but think before takingone! ...", + "Also, take this Yalaharian outfit. Depending on which side you chose previously, you can also acquire one specific addon. Thank you again for your help." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 53) + player:setStorageValue(Storage.InServiceofYalahar.DoorToReward, 1) + player:setStorageValue(Storage.InServiceofYalahar.Mission10, 4) -- StorageValue for Questlog "Mission 10: The Final Battle" + player:addOutfit(324, 0) + player:addOutfit(325, 0) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + player:setStorageValue(Storage.InServiceofYalahar.Questline, 4) + npcHandler:say({ + "I'm pleased to hear that. Rarely we meet outsiders that care about our problems. Most people come here looking for wealth and luxury. ...", + "However, I have to tell you that our ranking system is quite rigid. So, I'm not allowed to entrust you with important missions as long as you haven't proven yourself as reliable. ...", + "If you are willing to work for the city of Yalahar, you can ask me for a {mission} any time, be it night or day." + }, cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + if player:getStorageValue(Storage.InServiceofYalahar.SewerPipe01) == 1 and player:getStorageValue(Storage.InServiceofYalahar.SewerPipe02) == 1 and player:getStorageValue(Storage.InServiceofYalahar.SewerPipe03) == 1 and player:getStorageValue(Storage.InServiceofYalahar.SewerPipe04) == 1 then + player:setStorageValue(Storage.InServiceofYalahar.Questline, 6) + player:setStorageValue(Storage.InServiceofYalahar.Mission01, 6) -- StorageValue for Questlog "Mission 01: Something Rotten" + npcHandler:say("Thank you very much. You have no idea how hard it was to find someone volunteering for that job. If you feel ready for further {missions}, just tell me.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 3 then + player:setStorageValue(Storage.InServiceofYalahar.Mission02, 1) -- StorageValue for Questlog "Mission 02: Watching the Watchmen" + player:setStorageValue(Storage.InServiceofYalahar.Questline, 7) + npcHandler:say({ + "You'll find our seven guards at the gates of each quarter. Just ask them for their report and they will tell you all you need to know.", + "I must warn you, the quarters are in a horrible state. I strongly advise you to stay on the main roads whenever possible while you get those reports. ..." + }, cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 4 then + if player:getStorageValue(Storage.InServiceofYalahar.Questline) == 14 then + player:setStorageValue(Storage.InServiceofYalahar.Mission02, 8) -- StorageValue for Questlog "Mission 02: Watching the Watchmen" + player:setStorageValue(Storage.InServiceofYalahar.Questline, 15) + npcHandler:say("Excellent! My superiors will be pleased to get these reports. I will for sure emphasise your efforts in this mission. Please come back soon to see if there are any more {missions} available for you. ", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Come back when you do.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 5 then + player:setStorageValue(Storage.InServiceofYalahar.Questline, 50) + player:setStorageValue(Storage.InServiceofYalahar.Mission09, 2) -- StorageValue for Questlog "Mission 09: Decision" + player:setStorageValue(Storage.InServiceofYalahar.Mission10, 1) -- StorageValue for Questlog "Mission 10: The Final Battle" + player:setStorageValue(Storage.InServiceofYalahar.SideDecision, 1) + npcHandler:say("I knew that you were smart enough to make the right decision! Your next mission will be a special one! ", cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 6 then + if player:getItemCount(9956) > 0 and player:getStorageValue(Storage.InServiceofYalahar.Questline) == 54 then + player:setStorageValue(Storage.InServiceofYalahar.Questline, 55) + npcHandler:say("Great! Here, take this yalaharian addon in a return.", cid) + player:addOutfitAddon(325, player:getStorageValue(Storage.InServiceofYalahar.SideDecision) == 1 and 1 or 2) + player:addOutfitAddon(324, player:getStorageValue(Storage.InServiceofYalahar.SideDecision) == 1 and 1 or 2) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Come back when you do.", cid) + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Greetings.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye, |PLAYERNAME|.") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/palomino.lua b/data/npc/scripts/palomino.lua new file mode 100644 index 00000000000..5af4fbe4c1e --- /dev/null +++ b/data/npc/scripts/palomino.lua @@ -0,0 +1,75 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, 'transport') then + npcHandler:say('We can bring you to Venore with one of our coaches for 125 gold. Are you interested?', cid) + npcHandler.topic[cid] = 1 + elseif isInArray({'rent', 'horses'}, msg) then + npcHandler:say('Do you want to rent a horse for one day at a price of 500 gold?', cid) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, 'yes') then + local player = Player(cid) + if npcHandler.topic[cid] == 1 then + if player:isPzLocked() then + npcHandler:say('First get rid of those blood stains!', cid) + return true + end + + if not player:removeMoneyNpc(125) then + npcHandler:say('You don\'t have enough money.', cid) + return true + end + + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + local destination = Position(32850, 32124, 7) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + npcHandler:say('Have a nice trip!', cid) + elseif npcHandler.topic[cid] == 2 then + if player:getStorageValue(Storage.RentedHorseTimer) >= os.time() then + npcHandler:say('You already have a horse.', cid) + return true + end + + if not player:removeMoneyNpc(500) then + npcHandler:say('You do not have enough money to rent a horse!', cid) + return true + end + + local mountId = {22, 25, 26} + player:addMount(mountId[math.random(#mountId)]) + player:setStorageValue(Storage.RentedHorseTimer, os.time() + 86400) + player:addAchievement('Natural Born Cowboy') + npcHandler:say('I\'ll give you one of our experienced ones. Take care! Look out for low hanging branches.', cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] > 0 then + npcHandler:say('Then not.', cid) + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, 'Salutations, |PLAYERNAME| I guess you are here for the {horses}.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/paolo.lua b/data/npc/scripts/paolo.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/paolo.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/parlan.lua b/data/npc/scripts/parlan.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/parlan.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/partos.lua b/data/npc/scripts/partos.lua new file mode 100644 index 00000000000..abad346c3a8 --- /dev/null +++ b/data/npc/scripts/partos.lua @@ -0,0 +1,54 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'supplies') then + if player:getStorageValue(Storage.DjinnWar.EfreetFaction.Mission01) == 1 then + npcHandler:say({ + 'What!? I bet, Baa\'leal sent you! ...', + 'I won\'t tell you anything! Shove off!' + }, cid) + player:setStorageValue(Storage.DjinnWar.EfreetFaction.Mission01, 2) + else + npcHandler:say('I won\'t talk about that.', cid) + end + + elseif msgcontains(msg, 'ankrahmun') then + npcHandler:say({ + 'Yes, I\'ve lived in Ankrahmun for quite some time. Ahh, good old times! ...', + 'Unfortunately I had to relocate. ...', + 'Business reasons - you know.' + }, cid) + end + return true +end + +keywordHandler:addKeyword({'prison'}, StdModule.say, {npcHandler = npcHandler, text = 'You mean that\'s a JAIL? They told me it\'s the finest hotel in town! THAT explains the lousy roomservice!'}) +keywordHandler:addKeyword({'jail'}, StdModule.say, {npcHandler = npcHandler, text = 'You mean that\'s a JAIL? They told me it\'s the finest hotel in town! THAT explains the lousy roomservice!'}) +keywordHandler:addKeyword({'cell'}, StdModule.say, {npcHandler = npcHandler, text = 'You mean that\'s a JAIL? They told me it\'s the finest hotel in town! THAT explains the lousy roomservice!'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome to my little kingdom, |PLAYERNAME|.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye, visit me again. I will be here, promised.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye, visit me again. I will be here, promised.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/pat_the_worker.lua b/data/npc/scripts/pat_the_worker.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/pat_the_worker.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/paulie.lua b/data/npc/scripts/paulie.lua new file mode 100644 index 00000000000..9733978b33c --- /dev/null +++ b/data/npc/scripts/paulie.lua @@ -0,0 +1,472 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end + +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end + +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end + +function onThink() + npcHandler:onThink() +end + +local voices = { + {text = "Deposit your money here in the safety of the Tibian Bank!"}, + {text = "Any questions about the functions of your bank account? Feel free to ask me for help!"} +} + +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.TheRookieGuard.Mission08) == 1 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome |PLAYERNAME|! Special newcomer offer, today only! {Deposit} some money - or {deposit ALL} of your money! - and get 50 gold for free!") + else + npcHandler:setMessage(MESSAGE_GREET, "Welcome |PLAYERNAME|! Here, you can {deposit} or {withdraw} your money from your bank account and {change} gold. I can also explain the {functions} of your bank account to you.") + end + return true +end + +-- Bank functions + +-- Balance +keywordHandler:addKeyword({"balance"}, +function(cid, message, keywords, parameters, node) + local npcHandler = parameters.npcHandler + if npcHandler == nil then + error("StdModule.travel called without any npcHandler instance.") + end + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if player:getBankBalance() >= 100000000 then + npcHandler:say("I think you must be one of the richest inhabitants in the world! Your account balance is " .. player:getBankBalance() .. " gold.", cid) + elseif player:getBankBalance() >= 10000000 then + npcHandler:say("You have made ten millions and it still grows! Your account balance is " .. player:getBankBalance() .. " gold.", cid) + elseif player:getBankBalance() >= 1000000 then + npcHandler:say("Wow, you have reached the magic number of a million gp!!! Your account balance is " .. player:getBankBalance() .. " gold!", cid) + elseif player:getBankBalance() >= 100000 then + npcHandler:say("You certainly have made a pretty penny. Your account balance is " .. player:getBankBalance() .. " gold.", cid) + else + npcHandler:say("Your account balance is " .. player:getBankBalance() .. " gold.", cid) + end + return true +end, +{npcHandler = npcHandler} +) + +-- Deposit +local function depositHandler(cid, message, keywords, parameters, node) + local npcHandler = parameters.npcHandler + if npcHandler == nil then + error("StdModule.travel called without any npcHandler instance.") + end + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if string.find(message, "%d+") then + npcHandler.topic[cid] = tonumber(string.match(message, "%d+")) + else + npcHandler.topic[cid] = player:getMoney() + end + if npcHandler.topic[cid] <= 0 then + npcHandler:say("You are joking, aren't you?", cid) + return false + elseif player:getMoney() < npcHandler.topic[cid] then + npcHandler:say("You don't have enough gold.", cid) + return false + elseif player:getBankBalance() + npcHandler.topic[cid] <= 1000 then + npcHandler:say("Want to deposit " .. npcHandler.topic[cid] .. " gold?", cid) + return true + else + if player:getBankBalance() < 1000 then + npcHandler.topic[cid] = 1000 - player:getBankBalance() + npcHandler:say("Uh oh! I fear all that gold would exceed the limit of your Rookgaard bank account which are 1000 gold pieces. I can deposit " .. npcHandler.topic[cid] .. " gold though. Would you like that?", cid) + return true + else + npcHandler:say("Uh oh! I fear all that gold would exceed the limit of your Rookgaard bank account which are 1000 gold pieces.", cid) + return false + end + end +end + +local depositAll = keywordHandler:addKeyword({"deposit all"}, depositHandler, {npcHandler = npcHandler}) +local deposit = keywordHandler:addKeyword({"deposit"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Please tell me how much gold you would like to deposit." +}) + +local depositAmount = deposit:addChildKeyword({"%d+"}, depositHandler, {npcHandler = npcHandler}) + +local depositConfirm = KeywordNode:new({"yes"}, +function(cid, message, keywords, parameters, node) + local npcHandler = parameters.npcHandler + if npcHandler == nil then + error("StdModule.travel called without any npcHandler instance.") + end + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + local depositBonus = player:getStorageValue(Storage.TheRookieGuard.Mission08) == 1 and 50 or false + if depositBonus and player:depositMoney(npcHandler.topic[cid]) then + player:setStorageValue(Storage.TheRookieGuard.Mission08, 2) + player:addMoney(depositBonus) + player:depositMoney(depositBonus) + npcHandler:say("Alright, we have added the amount of " .. (npcHandler.topic[cid] + depositBonus) .. " gold to your {balance} - that is the money you deposited plus a bonus of " .. depositBonus .. " gold. Thank you! You can {withdraw} your money anytime.", cid) + elseif player:depositMoney(npcHandler.topic[cid]) then + npcHandler:say("Alright, we have added the amount of " .. npcHandler.topic[cid] .. " gold to your balance. You can withdraw your money anytime.", cid) + else + npcHandler:say("You don't have enough gold.", cid) + end + npcHandler:resetNpc(cid) + return true +end, +{npcHandler = npcHandler} +) + +local depositDecline = KeywordNode:new({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "As you wish. Is there something else I can do for you?", + reset = true +}) + +depositAmount:addChildKeywordNode(depositConfirm) +depositAll:addChildKeywordNode(depositConfirm) + +depositAmount:addChildKeywordNode(depositDecline) +depositAll:addChildKeywordNode(depositDecline) + +-- Withdraw +local withdraw = keywordHandler:addKeyword({"withdraw"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Please tell me how much gold you would like to withdraw." +}) + +local withdrawAmount = withdraw:addChildKeyword({"%d+"}, +function(cid, message, keywords, parameters, node) + local npcHandler = parameters.npcHandler + if npcHandler == nil then + error("StdModule.travel called without any npcHandler instance.") + end + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + npcHandler.topic[cid] = tonumber(string.match(message, "%d+")) + if npcHandler.topic[cid] <= 0 then + npcHandler:say("Sure, you want nothing - you get nothing!", cid) + return false + elseif player:getBankBalance() >= npcHandler.topic[cid] then + npcHandler:say("Are you sure you wish to withdraw " .. npcHandler.topic[cid] .. " gold from your bank account?", cid) + return true + else + npcHandler:say("There is not enough gold on your account.", cid) + return false + end +end, +{npcHandler = npcHandler} +) + +withdrawAmount:addChildKeyword({"yes"}, +function(cid, message, keywords, parameters, node) + local npcHandler = parameters.npcHandler + if npcHandler == nil then + error("StdModule.travel called without any npcHandler instance.") + end + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if player:getFreeCapacity() >= getMoneyWeight(npcHandler.topic[cid]) then + if player:withdrawMoney(npcHandler.topic[cid]) then + npcHandler:say("Here you are, " .. npcHandler.topic[cid] .. " gold. Please let me know if there is something else I can do for you.", cid) + else + npcHandler:say("There is not enough gold on your account.", cid) + end + else + npcHandler:say("Whoah, hold on, this is too heavy for you. I don't want you to drop it on the floor, maybe come back with a cart!", cid) + end + npcHandler:resetNpc(cid) + return true +end, +{npcHandler = npcHandler} +) + +withdrawAmount:addChildKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "The customer is king! Come back whenever you want if you wish to withdraw your money.", + reset = true +}) + +-- Change gold +local changeGold = keywordHandler:addKeyword({"change gold"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "How many platinum coins would you like to get?" +}) + +local changeDecline = KeywordNode:new({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Well, can I help you with something else?", + reset = true +}) + +local changeGoldAmount = changeGold:addChildKeyword({"%d+"}, +function(cid, message, keywords, parameters, node) + local npcHandler = parameters.npcHandler + if npcHandler == nil then + error("StdModule.travel called without any npcHandler instance.") + end + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + npcHandler.topic[cid] = tonumber(string.match(message, "%d+")) + if npcHandler.topic[cid] == 0 then + npcHandler:say("Hmm, can I help you with something else?", cid) + return false + else + npcHandler:say("So you want me to change " .. (npcHandler.topic[cid] * 100) .. " of your gold coins into " .. npcHandler.topic[cid] .. " platinum coins?", cid) + return true + end +end, +{npcHandler = npcHandler} +) + +changeGoldAmount:addChildKeyword({"yes"}, +function(cid, message, keywords, parameters, node) + local npcHandler = parameters.npcHandler + if npcHandler == nil then + error("StdModule.travel called without any npcHandler instance.") + end + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if player:removeItem(2148, npcHandler.topic[cid] * 100) then + player:addItem(2152, npcHandler.topic[cid]) + npcHandler:say("Here you are.", cid) + else + npcHandler:say("Sorry, you don't have enough gold coins.", cid) + end + npcHandler:resetNpc(cid) + return true +end, +{npcHandler = npcHandler} +) + +changeGoldAmount:addChildKeywordNode(changeDecline) + +-- Change platinum +local changePlatinum = keywordHandler:addKeyword({"change platinum"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Would you like to change your platinum coins into gold or crystal coins?" +}) + +local changePlatinumToGold = changePlatinum:addChildKeyword({"gold"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "How many platinum coins would you like to change into gold coins?" +}) + +local changePlatinumToGoldAmount = changePlatinumToGold:addChildKeyword({"%d+"}, +function(cid, message, keywords, parameters, node) + local npcHandler = parameters.npcHandler + if npcHandler == nil then + error("StdModule.travel called without any npcHandler instance.") + end + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + npcHandler.topic[cid] = tonumber(string.match(message, "%d+")) + if npcHandler.topic[cid] <= 0 then + npcHandler:say("Well, can I help you with something else?", cid) + return false + else + npcHandler:say("So you want me to change " .. npcHandler.topic[cid] .. " of your platinum coins into " .. (npcHandler.topic[cid] * 100) .. " gold coins for you?", cid) + return true + end +end, +{npcHandler = npcHandler} +) + +changePlatinumToGoldAmount:addChildKeyword({"yes"}, +function(cid, message, keywords, parameters, node) + local npcHandler = parameters.npcHandler + if npcHandler == nil then + error("StdModule.travel called without any npcHandler instance.") + end + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if player:getItemCount(2152) >= npcHandler.topic[cid] then + if player:getFreeCapacity() >= (ItemType(2148):getWeight() * (npcHandler.topic[cid] * 100)) then + player:removeItem(2152, npcHandler.topic[cid]) + player:addItem(2148, npcHandler.topic[cid] * 100) + npcHandler:say("Here you are.", cid) + else + npcHandler:say("Whoah, hold on, this is too heavy for you. I don't want you to drop it on the floor, maybe come back with a cart!", cid) + end + else + npcHandler:say("Sorry, you don't have enough platinum coins.", cid) + end + npcHandler:resetNpc(cid) + return true +end, +{npcHandler = npcHandler} +) + +changePlatinumToGoldAmount:addChildKeywordNode(changeDecline) + +local changePlatinumToCrystal = changePlatinum:addChildKeyword({"crystal"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "How many crystal coins would you like to get?" +}) + +local changePlatinumToCrystalAmount = changePlatinumToCrystal:addChildKeyword({"%d+"}, +function(cid, message, keywords, parameters, node) + local npcHandler = parameters.npcHandler + if npcHandler == nil then + error("StdModule.travel called without any npcHandler instance.") + end + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + npcHandler.topic[cid] = tonumber(string.match(message, "%d+")) + if npcHandler.topic[cid] <= 0 then + npcHandler:say("Well, can I help you with something else?", cid) + return false + else + npcHandler:say("So you want me to change " .. (npcHandler.topic[cid] * 100) .. " of your platinum coins into " .. npcHandler.topic[cid] .. " crystal coins for you?", cid) + return true + end +end, +{npcHandler = npcHandler} +) + +changePlatinumToCrystalAmount:addChildKeyword({"yes"}, +function(cid, message, keywords, parameters, node) + local npcHandler = parameters.npcHandler + if npcHandler == nil then + error("StdModule.travel called without any npcHandler instance.") + end + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if player:removeItem(2152, npcHandler.topic[cid] * 100) then + player:addItem(2160, npcHandler.topic[cid]) + npcHandler:say("Here you are.", cid) + else + npcHandler:say("Sorry, you don't have enough platinum coins.", cid) + end + npcHandler:resetNpc(cid) + return true +end, +{npcHandler = npcHandler} +) + +changePlatinumToCrystalAmount:addChildKeywordNode(changeDecline) + +-- Change crystal +local changeCrystal = keywordHandler:addKeyword({"change crystal"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "How many crystal coins would you like to change into platinum coins?" +}) + +local changeCrystalAmount = changeCrystal:addChildKeyword({"%d+"}, +function(cid, message, keywords, parameters, node) + local npcHandler = parameters.npcHandler + if npcHandler == nil then + error("StdModule.travel called without any npcHandler instance.") + end + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + npcHandler.topic[cid] = tonumber(string.match(message, "%d+")) + if npcHandler.topic[cid] == 0 then + npcHandler:say("Hmm, can I help you with something else?", cid) + return false + else + npcHandler:say("So you want me to change " .. npcHandler.topic[cid] .. " of your crystal coins into " .. (npcHandler.topic[cid] * 100) .. " platinum coins?", cid) + return true + end +end, +{npcHandler = npcHandler} +) + +changeCrystalAmount:addChildKeyword({"yes"}, +function(cid, message, keywords, parameters, node) + local npcHandler = parameters.npcHandler + if npcHandler == nil then + error("StdModule.travel called without any npcHandler instance.") + end + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + + if player:getItemCount(2160) >= npcHandler.topic[cid] then + if player:getFreeCapacity() >= (ItemType(2152):getWeight() * (npcHandler.topic[cid] * 100)) then + player:removeItem(2160, npcHandler.topic[cid]) + player:addItem(2152, npcHandler.topic[cid] * 100) + npcHandler:say("Here you are.", cid) + else + npcHandler:say("Whoah, hold on, this is too heavy for you. I don't want you to drop it on the floor, maybe come back with a cart!", cid) + end + else + npcHandler:say("Sorry, you don't have enough crystal coins.", cid) + end + npcHandler:resetNpc(cid) + return true +end, +{npcHandler = npcHandler} +) + +changeCrystalAmount:addChildKeywordNode(changeDecline) + +keywordHandler:addKeyword({"name"}, StdModule.say, {npcHandler = npcHandler, text = "I'm Paulie."}) +keywordHandler:addKeyword({"job"}, StdModule.say, {npcHandler = npcHandler, text = "I'm still a bank clerk-in-training. They say I can work on the {mainland} of Tibia once I have proven myself!"}) +keywordHandler:addKeyword({"mainland"}, StdModule.say, {npcHandler = npcHandler, text = "I'm looking forward to work on the mainland. The great Tibian cities are so much more interesting than this little village of {Rookgaard}."}) +keywordHandler:addKeyword({"rookgaard"}, StdModule.say, {npcHandler = npcHandler, text = "What a godforsaken place! Well, at least there are no criminals robbing the bank which would be - me. "}) +keywordHandler:addKeyword({"trade"}, StdModule.say, {npcHandler = npcHandler, text = "Sorry, I don't trade. Ask the shop owners for a trade instead. I can only help you with your bank account."}) +keywordHandler:addAliasKeyword({"offer"}) +keywordHandler:addAliasKeyword({"buy"}) +keywordHandler:addAliasKeyword({"sell"}) +keywordHandler:addKeyword({"help"}, StdModule.say, {npcHandler = npcHandler, text = "Every Tibian has a bank account. You can {deposit} your gold in one bank and {withdraw} it from the same or any other Tibian bank. Ask me for your {balance} to learn how much money you've already saved. There are also {advanced} functions."}) +keywordHandler:addKeyword({"quest"}, StdModule.say, {npcHandler = npcHandler, text = "Well, the greatest quest in life must be to amass tons of gold coins! Good luck with that!"}) +keywordHandler:addKeyword({"king"}, StdModule.say, {npcHandler = npcHandler, text = "HAIL TO THE KING!"}) + +keywordHandler:addKeyword({"bank account"}, StdModule.say, {npcHandler = npcHandler, text = "You can {deposit} and {withdraw} money from your {bank account} here. I can also {change} money for you."}) +keywordHandler:addAliasKeyword({"money"}) +keywordHandler:addKeyword({"change"}, StdModule.say, {npcHandler = npcHandler, text = "There are three different coin types in Tibia: 100 gold coins equal 1 platinum coin, 100 platinum coins equal 1 crystal coin. For example, if you like to change 100 gold coins into 1 platinum coin, simply say '{change gold}' and then '1 platinum'."}) +keywordHandler:addKeyword({"advanced"}, StdModule.say, {npcHandler = npcHandler, text = {"Once you are on the Tibian mainland, you can access new functions of your bank account, such as transferring money to other players safely, accessing your guild account or taking part in house auctions. ...", "Just ask any of my colleagues on the Mainland and they'll be happy to tell you all about the advanced functions of your bank account."}}) +keywordHandler:addKeyword({"transfer"}, StdModule.say, {npcHandler = npcHandler, text = "I'm afraid this service is not available to you until you reach mainland."}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye, and remember: entrusting us with your gold is the safest way of storing it!") +npcHandler:setCallback(CALLBACK_GREET, greetCallback) + +npcHandler:addModule(VoiceModule:new(voices)) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/peaceful_pooka.lua b/data/npc/scripts/peaceful_pooka.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/peaceful_pooka.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/peggy.lua b/data/npc/scripts/peggy.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/peggy.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/pemaret.lua b/data/npc/scripts/pemaret.lua new file mode 100644 index 00000000000..42905aa5609 --- /dev/null +++ b/data/npc/scripts/pemaret.lua @@ -0,0 +1,69 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "marlin") then + if player:getItemCount(7963) > 0 then + npcHandler:say("WOW! You have a marlin!! I could make a nice decoration for your wall from it. May I have it?", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 1 then + if player:removeItem(7963, 1) then + npcHandler:say("Yeah! Now let's see... There you go, I hope you like it!", cid) + player:addItem(7964, 1) + else + npcHandler:say("You don't have the fish.", cid) + end + npcHandler.topic[cid] = 0 + end + if msgcontains(msg, "no") and npcHandler.topic[cid] == 1 then + npcHandler:say("Then no.", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +-- Travel +local function addTravelKeyword(keyword, text, cost, destination) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'Maybe later.', reset = true}) +end + +addTravelKeyword('edron', 'Do you want to get to Edron for |TRAVELCOST|?', 20, Position(33176, 31764, 6)) +addTravelKeyword('eremo', 'Oh, you know the good old sage Eremo. I can bring you to his little island. Do you want me to do that?', 0, Position(33314, 31883, 7)) + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, destination = {Position(33293, 31957, 6), Position(33294, 31955, 6), Position(33294, 31958, 6)}}) + +-- Basic +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m a fisherman and I take along people to Edron. You can also buy some fresh fish.'}) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m a fisherman and I take along people to Edron. You can also buy some fresh fish.'}) +keywordHandler:addKeyword({'fish'}, StdModule.say, {npcHandler = npcHandler, text = 'My fish is of the finest quality you could find. Ask me for a trade to check for yourself.'}) +keywordHandler:addKeyword({'cormaya'}, StdModule.say, {npcHandler = npcHandler, text = 'It\'s a lovely and peaceful isle. Did you already visit the nice sandy beach?'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Pemaret, the fisherman.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Greetings, young man. Looking for a passage or some fish, |PLAYERNAME|?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/penny.lua b/data/npc/scripts/penny.lua new file mode 100644 index 00000000000..021d3d12d9e --- /dev/null +++ b/data/npc/scripts/penny.lua @@ -0,0 +1,35 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + npcHandler:setMessage(MESSAGE_GREET, "Welcome home, " .. Player(cid):getSex() == PLAYERSEX_FEMALE and "Lady" or "Sir" .. " |PLAYERNAME|.") + return true +end + +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "I am miss Penny, your secretary."}) +keywordHandler:addKeyword({'penny'}, StdModule.say, {npcHandler = npcHandler, text = "Yep, Penny's my name. You seem to be as smart as you're talkative."}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I'm a secretary. I'm organising all those papers and your mail."}) +keywordHandler:addKeyword({'criminal'}, StdModule.say, {npcHandler = npcHandler, text = " It's an evil world, isn't it?"}) +keywordHandler:addKeyword({'record'}, StdModule.say, {npcHandler = npcHandler, text = " It's an evil world, isn't it?"}) +keywordHandler:addKeyword({'paper'}, StdModule.say, {npcHandler = npcHandler, text = " It's an evil world, isn't it?"}) +keywordHandler:addKeyword({'mail'}, StdModule.say, {npcHandler = npcHandler, text = "You can get a letter from me."}) +keywordHandler:addKeyword({'?'}, StdModule.say, {npcHandler = npcHandler, text = "Don't stare at me."}) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setMessage(MESSAGE_FAREWELL, "Farewell, and may Justice be with you!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Wait... will you take me a diamond when you're back?") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/perac.lua b/data/npc/scripts/perac.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/perac.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/percy_silverhand.lua b/data/npc/scripts/percy_silverhand.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/percy_silverhand.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/percybald.lua b/data/npc/scripts/percybald.lua new file mode 100644 index 00000000000..51e89026578 --- /dev/null +++ b/data/npc/scripts/percybald.lua @@ -0,0 +1,104 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, 'disguise') then + if player:getStorageValue(Storage.ThievesGuild.TheatreScript) < 0 then + npcHandler:say({ + 'Hmpf. Why should I waste my time to help some amateur? I\'m afraid I can only offer my assistance to actors that are as great as I am. ...', + 'Though, your futile attempt to prove your worthiness could be amusing. Grab a copy of a script from the prop room at the theatre cellar. Then talk to me again about your test!' + }, cid) + player:setStorageValue(Storage.ThievesGuild.TheatreScript, 0) + end + elseif msgcontains(msg, 'test') then + if player:getStorageValue(Storage.ThievesGuild.Mission04) == 5 then + npcHandler:say('I hope you learnt your role! I\'ll tell you a line from the script and you\'ll have to answer with the corresponding line! Ready?', cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + npcHandler:say('How dare you? Are you mad? I hold the princess hostage and you drop your weapons. You\'re all lost!', cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 3 then + npcHandler:say('Too late puny knight. You can\'t stop my master plan anymore!', cid) + npcHandler.topic[cid] = 4 + elseif npcHandler.topic[cid] == 5 then + npcHandler:say('What\'s this? Behind the doctor?', cid) + npcHandler.topic[cid] = 6 + elseif npcHandler.topic[cid] == 7 then + npcHandler:say('Grrr!', cid) + npcHandler.topic[cid] = 8 + elseif npcHandler.topic[cid] == 9 then + npcHandler:say('You\'re such a monster!', cid) + npcHandler.topic[cid] = 10 + elseif npcHandler.topic[cid] == 11 then + npcHandler:say('Ah well, I think you passed the test! Here is your disguise kit! Now get lost, fate awaits me!', cid) + player:setStorageValue(Storage.ThievesGuild.Mission04, 6) + player:addItem(8693, 1) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, 'I don\'t think so, dear doctor!') then + npcHandler:say('Ok, ok. You\'ve got this one right! Ready for the next one?', cid) + npcHandler.topic[cid] = 3 + else + npcHandler:say('No no no! That is not correct!', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 4 then + if msgcontains(msg, 'Watch out! It\'s a trap!') then + npcHandler:say('Ok, ok. You\'ve got this one right! Ready for the next one?', cid) + npcHandler.topic[cid] = 5 + else + npcHandler:say('No no no! That is not correct!', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 6 then + if msgcontains(msg, 'Look! It\'s Lucky, the wonder dog!') then + npcHandler:say('Ok, ok. You\'ve got this one right! Ready for the next one?', cid) + npcHandler.topic[cid] = 7 + else + npcHandler:say('No no no! That is not correct!', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 8 then + if msgcontains(msg, 'Ahhhhhh!') then + npcHandler:say('Ok, ok. You\'ve got this one right! Ready for the next one?', cid) + npcHandler.topic[cid] = 9 + else + npcHandler:say('No no no! That is not correct!', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 10 then + if msgcontains(msg, 'Hahaha! Now drop your weapons or else...') then + npcHandler:say('Ok, ok. You\'ve got this one right! Ready for the next one?', cid) + npcHandler.topic[cid] = 11 + else + npcHandler:say('No no no! That is not correct!', cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Be greeted |PLAYERNAME|!") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/peremin.lua b/data/npc/scripts/peremin.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/peremin.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/perod.lua b/data/npc/scripts/perod.lua new file mode 100644 index 00000000000..bbccbcd8520 --- /dev/null +++ b/data/npc/scripts/perod.lua @@ -0,0 +1,47 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Stop by before embarking on your great adventure! Distance weapons and general equipment on sale today!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if msgcontains(msg, "football") then + npcHandler:say("Do you want to buy a football for 111 gold?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + local player = Player(cid) + if player:getMoney() + player:getBankBalance() >= 111 then + npcHandler:say("Here it is.", cid) + player:addItem(2109, 1) + player:removeMoneyNpc(111) + else + npcHandler:say("You don't have enough money.", cid) + end + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye, |PLAYERNAME|.") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/peter.lua b/data/npc/scripts/peter.lua new file mode 100644 index 00000000000..767c24b5e66 --- /dev/null +++ b/data/npc/scripts/peter.lua @@ -0,0 +1,53 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if(msgcontains(msg, "report")) then + if(player:getStorageValue(Storage.InServiceofYalahar.Questline) == 7 or player:getStorageValue(Storage.InServiceofYalahar.Questline) == 13) then + npcHandler:say("A report? What do they think is happening here? . ", cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, player:getStorageValue(Storage.InServiceofYalahar.Questline) + 1) + player:setStorageValue(Storage.InServiceofYalahar.Mission02, player:getStorageValue(Storage.InServiceofYalahar.Mission02) + 1) -- StorageValue for Questlog "Mission 02: Watching the Watchmen" + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "pass")) then + npcHandler:say("You can {pass} either to the {Factory Quarter} or {Trade Quarter}. Which one will it be?", cid) + npcHandler.topic[cid] = 1 + elseif(msgcontains(msg, "factory")) then + if(npcHandler.topic[cid] == 1) then + local destination = Position(32859, 31302, 7) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "trade")) then + if(npcHandler.topic[cid] == 1) then + local destination = Position(32854, 31302, 7) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/petros.lua b/data/npc/scripts/petros.lua new file mode 100644 index 00000000000..16b07ce5866 --- /dev/null +++ b/data/npc/scripts/petros.lua @@ -0,0 +1,53 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Travel +local function addTravelKeyword(keyword, cost, destination, condition) + if condition then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sorry but I don\'t sail there.'}, condition) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('venore', 180, Position(32954, 32022, 6)) +addTravelKeyword('port hope', 50, Position(32527, 32784, 6)) +addTravelKeyword('liberty bay', 140, Position(32285, 32892, 6)) +addTravelKeyword('ankrahmun', 150, Position(33092, 32883, 6)) +addTravelKeyword('yalahar', 210, Position(32816, 31272, 6), function(player) return player:getStorageValue(Storage.SearoutesAroundYalahar.Darashia) ~= 1 and player:getStorageValue(Storage.SearoutesAroundYalahar.TownsCounter) < 5 end) +addTravelKeyword('gray island', 160, Position(33196, 31984, 7)) +addTravelKeyword('krailos', 200, Position(33493, 31712, 6)) +addTravelKeyword('travora', 1000, Position(32055, 32368, 6)) +addTravelKeyword('issavi', 130, Position(33902, 31462, 6)) + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, destination = {Position(33288, 32474, 6), Position(33291, 32474, 6), Position(33293, 32471, 6)}}) + +-- Basic +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = "My boat is ready to bring you to {Venore}, {Port Hope}, {Liberty Bay}, {Yalahar}, {Gray Island}, {Ankrahmun}, {Krailos} or {Issavi}. Or to {Travora} - a place between the worlds."}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = "Where do you want to go - {Krailos}, {Venore}, {Port Hope}, {Liberty Bay}, {Ankrahmun}, {Yalahar} or {Gray Island}?"}) +keywordHandler:addKeyword({'darashia'}, StdModule.say, {npcHandler = npcHandler, text = "That's where we are."}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'It\'s Petros.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome on board, |PLAYERNAME|. Where can I {sail} you today?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Bye") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/phillip.lua b/data/npc/scripts/phillip.lua new file mode 100644 index 00000000000..05987a6c697 --- /dev/null +++ b/data/npc/scripts/phillip.lua @@ -0,0 +1,47 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'how', 'are', 'you'}, StdModule.say, {npcHandler = npcHandler, text = "I am fine, thank you very much."}) +keywordHandler:addKeyword({'sell'}, StdModule.say, {npcHandler = npcHandler, text = "My business is knowlegde and it is for free."}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am honored to be teacher in this school."}) +keywordHandler:addKeyword({'teacher'}, StdModule.say, {npcHandler = npcHandler, text = "I run this school, there are other travelling teachers who we call Loremasters."}) +keywordHandler:addKeyword({'loremaster'}, StdModule.say, {npcHandler = npcHandler, text = "If you are lucky you'll meet one in your journeys."}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "My name is Phillip."}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = "It is |TIME|."}) +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = "I will provide you with all knowledge I have."}) +keywordHandler:addKeyword({'monster'}, StdModule.say, {npcHandler = npcHandler, text = "Monsters come in different shape and power. It's said there is a zoo in the dwarfs' town."}) +keywordHandler:addKeyword({'dungeon'}, StdModule.say, {npcHandler = npcHandler, text = "Dungeons are places of danger and puzzles. In some of them a bright mind will serve you more then a blade."}) +keywordHandler:addKeyword({'sewer'}, StdModule.say, {npcHandler = npcHandler, text = "An interesting place you should consider to visit."}) +keywordHandler:addKeyword({'thank you'}, StdModule.say, {npcHandler = npcHandler, text = "You don't have to thank me, it's only my duty."}) +keywordHandler:addKeyword({'god'}, StdModule.say, {npcHandler = npcHandler, text = "To learn about gods, visit the temples and talk to the priests."}) +keywordHandler:addKeyword({'king'}, StdModule.say, {npcHandler = npcHandler, text = "The southern king is called Tibianus. He and our queen Eloise are in a constant struggle."}) +keywordHandler:addKeyword({'queen'}, StdModule.say, {npcHandler = npcHandler, text = "The southern king is called Tibianus. He and our queen Eloise are in a constant struggle."}) +keywordHandler:addKeyword({'rumour'}, StdModule.say, {npcHandler = npcHandler, text = "I don't like rumours."}) +keywordHandler:addKeyword({'gossip'}, StdModule.say, {npcHandler = npcHandler, text = "I don't like rumours."}) +keywordHandler:addKeyword({'news'}, StdModule.say, {npcHandler = npcHandler, text = "I don't like rumours."}) +keywordHandler:addKeyword({'weapon'}, StdModule.say, {npcHandler = npcHandler, text = "To learn about weapons read appropriate books or talk to the smiths."}) +keywordHandler:addKeyword({'magic'}, StdModule.say, {npcHandler = npcHandler, text = "To learn about magic talk to the guild leaders."}) +keywordHandler:addKeyword({'rebellion'}, StdModule.say, {npcHandler = npcHandler, text = "Rebellion? What for? We are contend with our situation."}) +keywordHandler:addKeyword({'in tod we trust'}, StdModule.say, {npcHandler = npcHandler, text = "Tod will come and save us all. He will bring freedom and beer to the men of Carlin."}) +keywordHandler:addKeyword({'lugri'}, StdModule.say, {npcHandler = npcHandler, text = "This servant of evil is protected by the dark gods and can't be harmed."}) +keywordHandler:addKeyword({'ferumbras'}, StdModule.say, {npcHandler = npcHandler, text = "He is a follower of evil. His powers were boosted by a sinister force and he is beyond human restrictions now."}) +keywordHandler:addKeyword({'excalibug'}, StdModule.say, {npcHandler = npcHandler, text = "This weapon is said to be very powerful and unique. It was hidden in ancient times and now is thought to be lost."}) + +npcHandler:setMessage(MESSAGE_GREET, "Hello, mighty adventurer |PLAYERNAME|. Can I teach you something you don't know?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Go and be careful. Remember what you have learned!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Did the bell ring?") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/pig_npc.lua b/data/npc/scripts/pig_npc.lua new file mode 100644 index 00000000000..6cdee856258 --- /dev/null +++ b/data/npc/scripts/pig_npc.lua @@ -0,0 +1,39 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:setMessage(MESSAGE_GREET, "Oink.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Bye.") + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if (msgcontains(msg, "kiss")) then + npcHandler:say("Do you want to try to release me with a kiss?", cid) + npcHandler.topic[cid] = 1 + elseif (msgcontains(msg, "yes")) then + if (npcHandler.topic[cid] == 1) then + npcHandler:say("Mhm Uhhh. Not bad, not bad at all! But you can still improve your skill a LOT.", cid) + npcHandler.topic[cid] = 0 + end + end +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/pino.lua b/data/npc/scripts/pino.lua new file mode 100644 index 00000000000..e5841297686 --- /dev/null +++ b/data/npc/scripts/pino.lua @@ -0,0 +1,45 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Feel the wind in your hair during one of my carpet rides!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, text, cost, destination) + if keyword == 'farmine' then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Never heard about a place like this.'}, function(player) return player:getStorageValue(Storage.TheNewFrontier.Mission10) ~= 1 end) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a ride to ' .. text .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, text = 'Hold on!', cost = cost, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'You shouldn\'t miss the experience.', reset = true}) +end + +addTravelKeyword('farmine', 'Farmine', 60, Position(32983, 31539, 1)) +addTravelKeyword('darashia', 'Darashia on Darama', 60, Position(33270, 32441, 6)) +addTravelKeyword('kazordoon', 'Kazordoon', 80, Position(32588, 31941, 0)) +addTravelKeyword('femor hills', 'the Femor Hills', 60, Position(32536, 31837, 4)) +addTravelKeyword('svargrond', 'Svargrond', 40, Position(32253, 31097, 4)) +addTravelKeyword('edron', 'Edron', 60, Position(33193, 31784, 3)) +addTravelKeyword('hills', 'the Femor Hills', 60, Position(32536, 31837, 4)) +addTravelKeyword('issavi', 'Issavi', 100, Position(33957, 31515, 0)) + +npcHandler:setMessage(MESSAGE_GREET, "Greetings, traveller |PLAYERNAME|. Where do you want me to {fly} you?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye!") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/plunderpurse.lua b/data/npc/scripts/plunderpurse.lua new file mode 100644 index 00000000000..70a79f4018a --- /dev/null +++ b/data/npc/scripts/plunderpurse.lua @@ -0,0 +1,460 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + {text = "Waste not, want not!"}, + {text = "Don't burden yourself with too much cash - store it here!"}, + {text = "Don't take the money and run - deposit it and walk instead!"} +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local count = {} +local function greetCallback(cid) + count[cid] = nil + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + --Help + if msgcontains(msg, "bank account") then + npcHandler:say( + { + "Every Adventurer has one. \z + The big advantage is that you can access your money in every branch of the World Bank! ...", + "Would you like to know more about the {basic} functions of your bank account, the {advanced} functions, \z + or are you already bored, perhaps?" + }, + cid, false, true, 10) + npcHandler.topic[cid] = 0 + return true + --Balance + elseif msgcontains(msg, "balance") then + npcHandler.topic[cid] = 0 + if player:getBankBalance() >= 100000000 then + npcHandler:say("I think you must be one of the richest inhabitants in the world! \z + Your account balance is " .. player:getBankBalance() .. " gold.", cid) + return true + elseif player:getBankBalance() >= 10000000 then + npcHandler:say("You have made ten millions and it still grows! Your account balance is \z + " .. player:getBankBalance() .. " gold.", cid) + return true + elseif player:getBankBalance() >= 1000000 then + npcHandler:say("Wow, you have reached the magic number of a million gp!!! \z + Your account balance is " .. player:getBankBalance() .. " gold!", cid) + return true + elseif player:getBankBalance() >= 100000 then + npcHandler:say("You certainly have made a pretty penny. Your account balance is \z + " .. player:getBankBalance() .. " gold.", cid) + return true + else + npcHandler:say("Your account balance is " .. player:getBankBalance() .. " gold.", cid) + return true + end + --Deposit + elseif msgcontains(msg, "deposit") then + count[cid] = player:getMoney() + if count[cid] < 1 then + npcHandler:say("You do not have enough gold.", cid) + npcHandler.topic[cid] = 0 + return false + elseif not isValidMoney(count[cid]) then + npcHandler:say("Sorry, but you can't deposit that much.", cid) + npcHandler.topic[cid] = 0 + return false + end + if msgcontains(msg, "all") then + count[cid] = player:getMoney() + npcHandler:say("Would you really like to deposit " .. count[cid] .. " gold?", cid) + npcHandler.topic[cid] = 2 + return true + else + if string.match(msg,"%d+") then + count[cid] = getMoneyCount(msg) + if count[cid] < 1 then + npcHandler:say("You do not have enough gold.", cid) + npcHandler.topic[cid] = 0 + return false + end + npcHandler:say("Would you really like to deposit " .. count[cid] .. " gold?", cid) + npcHandler.topic[cid] = 2 + return true + else + npcHandler:say("Please tell me how much gold it is you would like to deposit.", cid) + npcHandler.topic[cid] = 1 + return true + end + end + elseif npcHandler.topic[cid] == 1 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say("Would you really like to deposit " .. count[cid] .. " gold?", cid) + npcHandler.topic[cid] = 2 + return true + else + npcHandler:say("You do not have enough gold.", cid) + npcHandler.topic[cid] = 0 + return true + end + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, "yes") then + if count[cid] > 1500 or player:getBankBalance() >= 1500 then + npcHandler:say("Sorry, but you can't deposit that much.", cid) + npcHandler.topic[cid] = 0 + return false + end + if player:depositMoney(count[cid]) then + npcHandler:say("Alright, we have added the amount of " .. count[cid] .. " gold to your {balance}. \z + You can {withdraw} your money anytime you want to.", cid) + else + npcHandler:say("You do not have enough gold.", cid) + end + elseif msgcontains(msg, "no") then + npcHandler:say("As you wish. Is there something else I can do for you?", cid) + end + npcHandler.topic[cid] = 0 + return true + --Withdraw + elseif msgcontains(msg, "withdraw") then + if string.match(msg,"%d+") then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say("Are you sure you wish to withdraw " .. count[cid] .. " gold from your bank account?", cid) + npcHandler.topic[cid] = 7 + else + npcHandler:say("There is not enough gold on your account.", cid) + npcHandler.topic[cid] = 0 + end + return true + else + npcHandler:say("Please tell me how much gold you would like to withdraw.", cid) + npcHandler.topic[cid] = 6 + return true + end + elseif npcHandler.topic[cid] == 6 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say("Are you sure you wish to withdraw " .. count[cid] .. " gold from your bank account?", cid) + npcHandler.topic[cid] = 7 + else + npcHandler:say("There is not enough gold on your account.", cid) + npcHandler.topic[cid] = 0 + end + return true + elseif npcHandler.topic[cid] == 7 then + if msgcontains(msg, "yes") then + if player:getFreeCapacity() >= getMoneyWeight(count[cid]) then + if not player:withdrawMoney(count[cid]) then + npcHandler:say("There is not enough gold on your account.", cid) + else + npcHandler:say("Here you are, " .. count[cid] .. " gold. \z + Please let me know if there is something else I can do for you.", cid) + end + else + npcHandler:say("Whoah, hold on, you have no room in your inventory to carry all those coins. \z + I don't want you to drop it on the floor, maybe come back with a cart!", cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") then + npcHandler:say("The customer is king! Come back anytime you want to if you wish to {withdraw} your money.", cid) + npcHandler.topic[cid] = 0 + end + return true + --Money exchange + elseif msgcontains(msg, "change gold") then + npcHandler:say("How many platinum coins would you like to get?", cid) + npcHandler.topic[cid] = 14 + elseif npcHandler.topic[cid] == 14 then + if getMoneyCount(msg) < 1 then + npcHandler:say("Sorry, you do not have enough gold coins.", cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say("So you would like me to change " .. count[cid] * 100 .. " of your gold \z + coins into " .. count[cid] .. " platinum coins?", cid) + npcHandler.topic[cid] = 15 + end + elseif npcHandler.topic[cid] == 15 then + if msgcontains(msg, "yes") then + if player:removeItem(2148, count[cid] * 100) then + player:addItem(2152, count[cid]) + npcHandler:say("Here you are.", cid) + else + npcHandler:say("Sorry, you do not have enough gold coins.", cid) + end + else + npcHandler:say("Well, can I help you with something else?", cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "change platinum") then + npcHandler:say("Would you like to change your platinum coins into gold or crystal?", cid) + npcHandler.topic[cid] = 16 + elseif npcHandler.topic[cid] == 16 then + if msgcontains(msg, "gold") then + npcHandler:say("How many platinum coins would you like to change into gold?", cid) + npcHandler.topic[cid] = 17 + elseif msgcontains(msg, "crystal") then + npcHandler:say("How many crystal coins would you like to get?", cid) + npcHandler.topic[cid] = 19 + else + npcHandler:say("Well, can I help you with something else?", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 17 then + if getMoneyCount(msg) < 1 then + npcHandler:say("Sorry, you do not have enough platinum coins.", cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say("So you would like me to change " .. count[cid] .. " of your platinum \z + coins into " .. count[cid] * 100 .. " gold coins for you?", cid) + npcHandler.topic[cid] = 18 + end + elseif npcHandler.topic[cid] == 18 then + if msgcontains(msg, "yes") then + if player:removeItem(2152, count[cid]) then + player:addItem(2148, count[cid] * 100) + npcHandler:say("Here you are.", cid) + else + npcHandler:say("Sorry, you do not have enough platinum coins.", cid) + end + else + npcHandler:say("Well, can I help you with something else?", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 19 then + if getMoneyCount(msg) < 1 then + npcHandler:say("Sorry, you do not have enough platinum coins.", cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say("So you would like me to change " .. count[cid] * 100 .. " of your platinum coins \z + into " .. count[cid] .. " crystal coins for you?", cid) + npcHandler.topic[cid] = 20 + end + elseif npcHandler.topic[cid] == 20 then + if msgcontains(msg, "yes") then + if player:removeItem(2152, count[cid] * 100) then + player:addItem(2160, count[cid]) + npcHandler:say("Here you are.", cid) + else + npcHandler:say("Sorry, you do not have enough platinum coins.", cid) + end + else + npcHandler:say("Well, can I help you with something else?", cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "change crystal") then + npcHandler:say("How many crystal coins would you like to change into platinum?", cid) + npcHandler.topic[cid] = 21 + elseif npcHandler.topic[cid] == 21 then + if getMoneyCount(msg) < 1 then + npcHandler:say("Sorry, you do not have enough crystal coins.", cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say("So you would like me to change " .. count[cid] .. " of your crystal coins \z + into " .. count[cid] * 100 .. " platinum coins for you?", cid) + npcHandler.topic[cid] = 22 + end + elseif npcHandler.topic[cid] == 22 then + if msgcontains(msg, "yes") then + if player:removeItem(2160, count[cid]) then + player:addItem(2152, count[cid] * 100) + npcHandler:say("Here you are.", cid) + else + npcHandler:say("Sorry, you do not have enough crystal coins.", cid) + end + else + npcHandler:say("Well, can I help you with something else?", cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({"dawnport"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Yeah, well, some romantic at work there. \z + Island was reached at dawn, new heroes and adventurers forthcoming, stuff like that." + } +) +keywordHandler:addKeyword({"change"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Ah, wonderful stuff! That and a bottle o' rum, o'course! Harrharr. \z + You have some gold you want to deposit or withdraw, just tell me." + } +) +keywordHandler:addKeyword({"bank"}, StdModule.say, + { + npcHandler = npcHandler, + text = "You can deposit and withdraw money from your bank account here." + } +) +keywordHandler:addKeyword({"advanced"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Once you are on the Tibian mainland, you can access new functions of your bank account, \z + such as changing money, transferring money to other players safely or taking part in house auctions." + } +) +keywordHandler:addKeyword({"name"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Abram Plunderpurse, at your service. " + } +) +keywordHandler:addKeyword({"functions"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Here on Dawnport, I run the bank. I keep any gold you deposit safe, \z + so you can't lose it when you're out fighting or dying, heh. \z + Ask me for your balance to learn how much money you've already saved" + } +) +keywordHandler:addKeyword({"rookgaard"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Arrr. Not a very profitable place." + } +) +keywordHandler:addKeyword({"job"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Arr! I'm a pira... er, I mean ... clerk. Banking clerk. \z + That's what I am. You need somethin'? Bank business, p'raps?" + } +) +keywordHandler:addKeyword({"mainland"}, StdModule.say, + { + npcHandler = npcHandler, + text = { + "Aye, Tibia is a vast world, my friend, with plenty of adventures, harbours, and loot! \z + The Mainland is open to everyone; but there are many beautiful islands and more cities to explore, \z + if you have premium rights and can use a ship.", + "Once you have reached level 8 here on this isle, you can choose your definite vocation and leave for the Mainland." + } + } +) +keywordHandler:addKeyword({"vocation"}, StdModule.say, + { + npcHandler = npcHandler, + text = "There's a choice of four: knight, sorcerer, paladin or druid." + } +) +keywordHandler:addKeyword({"transfer"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I'm afraid this service is not available to you until you reach the World mainland." + } +) +keywordHandler:addKeyword({"inigo"}, StdModule.say, + { + npcHandler = npcHandler, + text = "He's an ol' trapper and knows his away around in Tibia, aye. \z + Ask him how a thing works and he'll be sure to have an answer. ..." + } +) +keywordHandler:addKeyword({"coltrayne"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Gloomy sort. Keeps glaring at me for some reason. Or maybe for no reason, harr. \z + Formidable blacksmith, anyway. Sharpest sword blade I've seen in a long time." + } +) +keywordHandler:addKeyword({"garamond"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Fetching white beard, I hope I grow one in due time, would impress the younger folk no end! \z + Knowing some sorcerer and druid spells like he does wouldn't come amiss, either. \z + Go to him if you need mage spells." + } +) +keywordHandler:addKeyword({"hamish"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Could've used his talent to brew up some more explosive runes back in the sea fight against... \z + ah well, you wouldn't know the name anyway. Gotta admit, his potions are good stuff." + } +) +keywordHandler:addKeyword({"richard"}, StdModule.say, + { + npcHandler = npcHandler, + text = " Well, maybe I did come across his ship some time. In bad weather. \z + And couldn't do a thing for those poor souls. And anyway, he swam ashore here. \z + So it all worked out in the end, see." + } +) +keywordHandler:addKeyword({"mr morris"}, StdModule.say, + { + npcHandler = npcHandler, + text = "That's Mr Morris to you, friend. \z + Go get yourself a useful thing to do and ask him about a quest, will you." + } +) +keywordHandler:addKeyword({"oressa"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Harrr, what a dame! Would like to buy her a pint one day. \z + Unless she kills me with one of her icy looks first. Anyway, decent healer. \z + Can help ya with choosing a vocation." + } +) +keywordHandler:addKeyword({"plunderpurse"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Aye, what about my name? You don't like it? Well, you don't have to wear it! \z + And I am quite happy with that!" + } +) +keywordHandler:addKeyword({"quest"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Not my line of trade, friend! Mr Morris next door will tell you what needs doin' around here." + } +) +keywordHandler:addKeyword({"ser tybald"}, StdModule.say, + { + npcHandler = npcHandler, + text = " I could swear he looks like that old pal I met back on... \z + ah well, much salt water passed my ship since then. \z + If ye need a spell or two for a knight or paladin, he's the spell teacher to go to." + } +) +keywordHandler:addKeyword({"wentworth"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Arrr. We go wayyyy back, Keeran an' me. Best you ask him, I'm no good at details." + } +) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome, young adventurer! Harr! {Deposit} your gold or {withdraw} \z + your money from your bank account. I can also explain the functions of your {bank} account to ya.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Have a nice day.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Have a nice day.") + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/polly.lua b/data/npc/scripts/polly.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/polly.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/pompan.lua b/data/npc/scripts/pompan.lua new file mode 100644 index 00000000000..8c87392bd15 --- /dev/null +++ b/data/npc/scripts/pompan.lua @@ -0,0 +1,164 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function getTable(player) + local itemsList = { + {name='backpack', id=1988, buy=20}, + {name='bag', id=1987, buy=5}, + {name='basket', id=1989, buy=6}, + {name='blue quiver', id=40683, buy=400}, + {name='bucket', id=2005, buy=4}, + {name='candlestick', id=2047, buy=2}, + {name='closed trap', id=2578, buy=280, sell=75}, + {name='crowbar', id=2416, buy=260, sell=50}, + {name='expedition backpack', id=11241, buy=100}, + {name='expedition bag', id=11242, buy=50}, + {name='fishing rod', id=2580, buy=150, sell=40}, + {name='lamp', id=2044, buy=8}, + {name='pick', id=2553, buy=50, sell=15}, + {name='quiver', id=40397, buy=400}, + {name='red quiver', id=40684, buy=400}, + {name='rope', id=2120, buy=50, sell=15}, + {name='scythe', id=2550, buy=50, sell=10}, + {name='shovel', id=2554, buy=50, sell=8}, + {name='torch', id=2050, buy=2}, + {name='watch', id=2036, buy=20, sell=6}, + {name='worm', id=3976, buy=1}, + {name='inkwell', id=2600, sell=8}, + {name='mirror', id=2560, sell=10}, + {name='sickle', id=2405, sell=3} + } + + local tomes = { + -- 1 tome + { + {name='arrow', id=2544, buy=3}, + {name='bolt', id=2543, buy=4}, + {name='bow', id=2456, buy=400, sell=100}, + {name='crossbow', id=2455, buy=500, sell=120}, + {name='crystalline arrow', id=18304, buy=20}, + {name='diamond arrow', id=40736, buy=100}, + {name='dragon tapestry', id=11264, buy=80}, + {name='drill bolt', id=18436, buy=12}, + {name='earth arrow', id=7850, buy=5}, + {name='envenomed arrow', id=18437, buy=12}, + {name='flaming arrow', id=7840, buy=5}, + {name='flash arrow', id=7838, buy=5}, + {name='onyx arrow', id=7365, buy=7}, + {name='piercing bolt', id=7363, buy=5}, + {name='power bolt', id=2547, buy=7}, + {name='prismatic bolt', id=18435, buy=20}, + {name='royal spear', id=7378, buy=15}, + {name='shiver arrow', id=7839, buy=5}, + {name='sniper arrow', id=7364, buy=5}, + {name='spear', id=2389, buy=9, sell=3}, + {name='spectral bolt', id=40737, buy=70}, + {name='tarsal arrow', id=15648, buy=6}, + {name='throwing star', id=2399, buy=42}, + {name='vortex bolt', id=15649, buy=6}, + {name='corrupted flag', id=11326, sell=700}, + {name='high guard flag', id=11332, sell=550}, + {name='legionnaire flags', id=11334, sell=500}, + {name='zaogun flag', id=11330, sell=600} + }, + -- 2 tomes + { + {name='minotaur backpack', id=11244, buy=200} + }, + -- 5 tomes + { + {name='dragon backpack', id=11243, buy=200} + } + } + + if player:getStorageValue(Storage.TheNewFrontier.TomeofKnowledge) >= 1 then + -- 1 tome + for i = 1, #tomes[1] do + itemsList[#itemsList] = tomes[1][i] + end + end + if player:getStorageValue(Storage.TheNewFrontier.TomeofKnowledge) >= 2 then + -- 2 tomes + for i = 1, #tomes[2] do + itemsList[#itemsList] = tomes[2][i] + end + end + if player:getStorageValue(Storage.TheNewFrontier.TomeofKnowledge) >= 5 then + -- 5 tomes + for i = 1, #tomes[3] do + itemsList[#itemsList] = tomes[3][i] + end + end + + return itemsList +end + +local function setNewTradeTable(table) + local items, item = {} + for i = 1, #table do + item = table[i] + items[item.id] = {itemId = item.id, buyPrice = item.buy, sellPrice = item.sell, subType = 0, realName = item.name} + end + return items +end + +local function onBuy(cid, item, subType, amount, ignoreCap, inBackpacks) + local player = Player(cid) + local items = setNewTradeTable(getTable(player)) + if not ignoreCap and player:getFreeCapacity() < ItemType(items[item].itemId):getWeight(amount) then + return player:sendTextMessage(MESSAGE_FAILURE, 'You don\'t have enough cap.') + end + if not player:removeMoneyNpc(items[item].buyPrice * amount) then + selfSay("You don't have enough money.", cid) + else + player:addItem(items[item].itemId, amount) + return player:sendTextMessage(MESSAGE_TRADE, 'Bought '..amount..'x '..items[item].realName..' for '..items[item].buyPrice * amount..' gold coins.') + end + return true +end + +local function onSell(cid, item, subType, amount, ignoreCap, inBackpacks) + local player = Player(cid) + local items = setNewTradeTable(getTable(player)) + if items[item].sellPrice and player:removeItem(items[item].itemId, amount) then + player:addMoney(items[item].sellPrice * amount) + return player:sendTextMessage(MESSAGE_TRADE, 'Sold '..amount..'x '..items[item].realName..' for '..items[item].sellPrice * amount..' gold coins.') + else + selfSay("You don't have item to sell.", cid) + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, 'trade') then + local player = Player(cid) + local items = setNewTradeTable(getTable(player)) + openShopWindow(cid, getTable(player), onBuy, onSell) + npcHandler:say('Keep in mind you won\'t find better offers here. Just browse through my wares.', cid) + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, 'Hello.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'It was a pleasure to help you, |PLAYERNAME|.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/prezil.lua b/data/npc/scripts/prezil.lua new file mode 100644 index 00000000000..98d74790c50 --- /dev/null +++ b/data/npc/scripts/prezil.lua @@ -0,0 +1,95 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Twist of Fate +local blessKeyword = keywordHandler:addKeyword({'twist of fate'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'This is a special blessing I can bestow upon you once you have obtained at least one of the other blessings and which functions a bit differently. ...', + 'It only works when you\'re killed by other adventurers, which means that at least half of the damage leading to your death was caused by others, not by monsters or the environment. ...', + 'The {twist of fate} will not reduce the death penalty like the other blessings, but instead prevent you from losing your other blessings as well as the amulet of loss, should you wear one. It costs the same as the other blessings. ...', + 'Would you like to receive that protection for a sacrifice of |PVPBLESSCOST| gold, child?' + }}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the protection of the twist of fate, pilgrim.', cost = '|PVPBLESSCOST|', bless = 1}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Adventurer Stone +keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Keep your adventurer\'s stone well.'}, function(player) return player:getItemById(18559, true) end) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for free?'}, function(player) return player:getStorageValue(Storage.AdventurersGuild.FreeStone.Alia) ~= 1 end) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, nil, function(player) player:addItem(18559, 1) player:setStorageValue(Storage.AdventurersGuild.FreeStone.Alia, 1) end) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for 30 gold?'}) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, + function(player) return player:getMoney() + player:getBankBalance() >= 30 end, + function(player) if player:removeMoneyNpc(30) then player:addItem(18559, 1) end end + ) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, you don\'t have enough money.', reset = true}) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.'}, function(player) return player:hasBlessing(2) end) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin will provide you with the embrace of Tibia.'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, young |PLAYERNAME|! If you are heavily wounded or poisoned, I can {heal} you for free.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Remember: If you are heavily wounded or poisoned, I can heal you for free.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'May the gods bless you, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/prisoner.lua b/data/npc/scripts/prisoner.lua new file mode 100644 index 00000000000..610009e6682 --- /dev/null +++ b/data/npc/scripts/prisoner.lua @@ -0,0 +1,29 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = "Ahhhh!" }, + { text = "Have mercy!" }, + { text = "I admit! I admit!" }, + { text = "I repent!" }, + { text = "Noooooo!" }, + { text = "Please! I beg you to stop!" }, + { text = "Take it away! Please!" } +} + +npcHandler:addModule(VoiceModule:new(voices)) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/puffels.lua b/data/npc/scripts/puffels.lua new file mode 100644 index 00000000000..2d47a7c6ba0 --- /dev/null +++ b/data/npc/scripts/puffels.lua @@ -0,0 +1,242 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addSpellKeyword({"find", "person"}, + { + npcHandler = npcHandler, + spellName = "Find Person", + price = 80, + level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"great", "light"}, + { + npcHandle = npcHandler, + spellName = "Great Light", + price = 500, + level = 13, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"light"}, + { + npcHandle = npcHandler, + spellName = "Light", + price = 0, + level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"magic", "rope"}, + { + npcHandle = npcHandler, + spellName = "Magic Rope", + price = 200, + level = 9, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"cure", "poison"}, + { + npcHandle = npcHandler, + spellName = "Cure Poison", + price = 150, + level = 10, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"intense", "wound", "cleansing"}, + { + npcHandle = npcHandler, + spellName = "Intense Wound Cleansing", + price = 6000, + level = 80, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"wound", "cleansing"}, + { + npcHandle = npcHandler, + spellName = "Wound Cleansing", + price = 0, + level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"levitate"}, + { + npcHandle = npcHandler, + spellName = "Levitate", + price = 500, + level = 12, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"haste"}, + { + npcHandle = npcHandler, + spellName = "Haste", + price = 600, + level = 14, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"brutal", "strike"}, + { + npcHandle = npcHandler, + spellName = "Brutal Strike", + price = 1000, + level = 16, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"charge"}, + { + npcHandle = npcHandler, + spellName = "Charge", + price = 1300, + level = 25, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"whirlwind", "throw"}, + { + npcHandle = npcHandler, + spellName = "Whirlwind Throw", + price = 1500, + level = 28, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"groundshaker"}, + { + npcHandle = npcHandler, + spellName = "Groundshaker", + price = 1500, + level = 33, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"fierce", "berserk"}, + { + npcHandle = npcHandler, + spellName = "Fierce Berserk", + price = 7500, + level = 90, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"berserk"}, + { + npcHandle = npcHandler, + spellName = "Berserk", + price = 2500, + level = 35, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"inflict", "wound"}, + { + npcHandle = npcHandler, + spellName = "Inflict Wound", + price = 2500, + level = 40, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"cure", "bleeding"}, + { + npcHandle = npcHandler, + spellName = "Cure Bleeding", + price = 2500, + level = 45, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"intense", "recovery"}, + { + npcHandle = npcHandler, + spellName = "Intense Recovery", + price = 10000, + level = 100, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"recovery"}, + { + npcHandle = npcHandler, + spellName = "Recovery", + price = 4000, + level = 50, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"front", "sweep"}, + { + npcHandle = npcHandler, + spellName = "Front Sweep", + price = 4000, + level = 70, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"annihilation"}, + { + npcHandle = npcHandler, + spellName = "Annihilation", + price = 20000, + level = 110, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) + +keywordHandler:addKeyword({"healing", "spells"}, StdModule.say, + { + npcHandle = npcHandler, + text = "In this category I have '{Bruise Bane}', '{Cure Bleeding}', '{Wound Cleansing}', \z + '{Cure Poison}'', '{Intense Wound Cleansing}'', '{Recovery}'' and '{Intense Recovery}''." + } +) +keywordHandler:addKeyword({"attack", "spells"}, StdModule.say, + { + npcHandle = npcHandler, + text = {"In this category I have '{Whirlwind Throw}', '{Groundshaker}', '{Berserk}' and \z + '{Fierce Berserk}' as well as ...', ''{Brutal Strike}', '{Front Sweep}', '{Inflict Wound}' and '{Annihilation}'"} + } +) +keywordHandler:addKeyword({"support", "spells"}, StdModule.say, + { + npcHandle = npcHandler, + text = "In this category I have '{Light}', '{Find Person}', '{Magic Rope}', '{Levitate}', \z + '{Haste}', '{Charge}' and '{Great Light}'." + } +) +keywordHandler:addKeyword({"spells"}, StdModule.say, + { + npcHandle = npcHandler, + text = "I can teach you {healing spells}, {attack spells} and {support spells}. \z + What kind of spell do you wish to learn? \z + You can also tell me for which level you would like to learn a spell, if you prefer that." + } +) + +npcHandler:setMessage(MESSAGE_GREET, "Yeah, another fool {disturbing} me, what a joy.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Whatever.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Whatever.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/pugwah.lua b/data/npc/scripts/pugwah.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/pugwah.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/pukosch.lua b/data/npc/scripts/pukosch.lua new file mode 100644 index 00000000000..e752a19dda7 --- /dev/null +++ b/data/npc/scripts/pukosch.lua @@ -0,0 +1,56 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + -- WAGON TICKET + if(msgcontains(msg, "ticket")) then + if player:getStorageValue(Storage.WagonTicket) < os.time() then + npcHandler:say("Do you want to purchase a weekly ticket for the ore wagons? With it you can travel freely and swiftly through Kazordoon for one week. 250 gold only. Deal?", cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say("Your weekly ticket is still valid. Would be a waste of money to purchase a second one", cid) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "yes")) then + if(npcHandler.topic[cid] == 1) then + if player:getMoney() + player:getBankBalance() >= 250 then + player:removeMoneyNpc(250) + player:setStorageValue(Storage.WagonTicket, os.time() + 7 * 24 * 60 * 60) + npcHandler:say("Here is your stamp. It can't be transferred to another person and will last one week from now. You'll get notified upon using an ore wagon when it isn't valid anymore.", cid) + else + npcHandler:say("You don't have enough money.", cid) + end + npcHandler.topic[cid] = 0 + end + elseif(npcHandler.topic[cid] == 1) then + if(msgcontains(msg, "no")) then + npcHandler:say("No then.", cid) + npcHandler.topic[cid] = 0 + end + -- WAGON TICKET + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "Welcome, |PLAYERNAME|! Do you feel adventurous? Do you want a weekly {ticket} for the ore wagon system here? You can use it right here to get to the centre of Kazordoon!") +npcHandler:setMessage(MESSAGE_FAREWELL, "Hope to see you again.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/pydar.lua b/data/npc/scripts/pydar.lua new file mode 100644 index 00000000000..127d5c957c4 --- /dev/null +++ b/data/npc/scripts/pydar.lua @@ -0,0 +1,63 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Spark of the Phoenix +local blessKeyword = keywordHandler:addKeyword({'spark of the phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The Spark of the Phoenix is given by me and by the great geomancer of the local earth temple. Do you wish to receive my part of the Spark of the Phoenix for |BLESSCOST| gold?'}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the spark of the phoenix, pilgrim.', cost = '|BLESSCOST|', bless = 3}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Maybe another time.', reset = true}) + keywordHandler:addAliasKeyword({'spark'}) + keywordHandler:addAliasKeyword({'phoenix'}) + +-- Basic +keywordHandler:addKeyword({'gods'}, StdModule.say, {npcHandler = npcHandler, text = 'The ways of the gods are imprehensible to mortals. On the other hand, the elements are raw forces and can be understood and tamed.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the head pyromancer of Kazordoon.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Pydar Firefist, Son of Fire, from the Savage Axes.'}) +keywordHandler:addKeyword({'quest'}, StdModule.say, {npcHandler = npcHandler, text = 'Ask around. There\'s a lot to do, jawoll.'}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = 'That is our world.'}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = 'It\'s the fourth age of the yellow flame.'}) +keywordHandler:addKeyword({'monsters'}, StdModule.say, {npcHandler = npcHandler, text = 'May the great flame devour them all!'}) +keywordHandler:addKeyword({'life'}, StdModule.say, {npcHandler = npcHandler, text = 'Life feeds on fire and ultimately fire will feed on life.'}) +keywordHandler:addKeyword({'excalibug'}, StdModule.say, {npcHandler = npcHandler, text = 'A weapon too powerful to be wielded by mortals. It has to be returned to the fire which gave birth to it.'}) +keywordHandler:addKeyword({'ferumbras'}, StdModule.say, {npcHandler = npcHandler, text = 'If he ever dares enter Kazordoon I will gladly dump him into the lava. Tthe sacred flame shall bring justice upon him.'}) +keywordHandler:addKeyword({'kazordoon'}, StdModule.say, {npcHandler = npcHandler, text = 'Our city was founded in ancient times. Abandoned by the gods we once fought for, we created a secure haven for our people.'}) +keywordHandler:addKeyword({'the big old one'}, StdModule.say, {npcHandler = npcHandler, text = 'This mountain is said to be the oldest in the world. It is the place where fire and earth meet and separate at the same time.'}) +keywordHandler:addKeyword({'bezil'}, StdModule.say, {npcHandler = npcHandler, text = 'Bezil and Nezil are buying and selling equipment of all kinds.'}) +keywordHandler:addKeyword({'nezil'}, StdModule.say, {npcHandler = npcHandler, text = 'Bezil and Nezil are buying and selling equipment of all kinds.'}) +keywordHandler:addKeyword({'duria'}, StdModule.say, {npcHandler = npcHandler, text = 'She is the first knight of Kazordoon. She is responsible for teaching our young warriors how to handle an axe.'}) +keywordHandler:addKeyword({'etzel'}, StdModule.say, {npcHandler = npcHandler, text = 'Etzel is a true master of the elements. He is a role-model for our youngsters, jawoll.'}) +keywordHandler:addKeyword({'jimbin'}, StdModule.say, {npcHandler = npcHandler, text = 'He and his wife are running the Jolly Axeman tavern.'}) +keywordHandler:addKeyword({'kroox'}, StdModule.say, {npcHandler = npcHandler, text = 'He is a smith. If you are looking for exquisite weapons and armour just talk to him.'}) +keywordHandler:addKeyword({'maryza'}, StdModule.say, {npcHandler = npcHandler, text = 'She and her husband are running the Jolly Axeman tavern.'}) +keywordHandler:addKeyword({'uzgod'}, StdModule.say, {npcHandler = npcHandler, text = 'Uzgod is a weaponsmith just like those in the old legends.'}) +keywordHandler:addKeyword({'durin'}, StdModule.say, {npcHandler = npcHandler, text = 'Though we are through with the so-called gods, Durin, the first dwarf to aquire divine powers of his own, is considered a protector of our race.'}) +keywordHandler:addKeyword({'fire'}, StdModule.say, {npcHandler = npcHandler, text = 'Unlike the gods, the elements don\'t use mortals as toys, A skilled mind can understand and even control them to some extent.'}) +keywordHandler:addKeyword({'keeper'}, StdModule.say, {npcHandler = npcHandler, text = 'The ways of the gods are imprehensible to mortals. On the other hand, the elements are raw forces and can be understood and tamed.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can receive the Spiritual Shielding in the Whiteflower Temple south of Thais.'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'Ask for the Fire of the Suns in the Suntower near Ab\'Dendriel.'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin can provide you with the Embrace of Tibia.'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, function(player) return player:getCondition(CONDITION_FIRE) ~= nil end) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes.'}) +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m the head pyromancer of Kazordoon. I guess you are here for healing or looking for a blessing.'}) +keywordHandler:addKeyword({'blessing'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five different blessings available in five sacred places. These blessings are: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}.'}) +keywordHandler:addKeyword({'pyromancer'}, StdModule.say, {npcHandler = npcHandler, text = 'We are the keepers and shepherds of the elemental force of {fire}.'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Be greeted |PLAYERNAME|! I can smell the scent of a phoenix on you!') +npcHandler:setMessage(MESSAGE_FAREWELL, 'May the fire in your heart never die, |PLAYERNAME|!') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'May the fire in your heart never die.') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/pyro_peter.lua b/data/npc/scripts/pyro_peter.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/pyro_peter.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/pyromental.lua b/data/npc/scripts/pyromental.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/pyromental.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/pythius_the_rotten.lua b/data/npc/scripts/pythius_the_rotten.lua new file mode 100644 index 00000000000..a876877f839 --- /dev/null +++ b/data/npc/scripts/pythius_the_rotten.lua @@ -0,0 +1,47 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local treasureKeyword = keywordHandler:addKeyword({"treasure"}, StdModule.say, {npcHandler = npcHandler, text = "LIKE MY TREASURE? WANNA PICK SOMETHING OUT OF IT?"}) + treasureKeyword:addChildKeyword({"yes"}, StdModule.say, {npcHandler = npcHandler, text = "ALRIGHT. BUT FIRST OF ALL I WANT YOU TO BRING ME SOMETHING IN EXCHANGE. SURPRISE ME....AND IF I LIKE IT, YOU MAY GET WHAT YOU DESERVE.", reset = true}) + treasureKeyword:addChildKeyword({"no"}, StdModule.say, {npcHandler = npcHandler, text = "HAVE YOU SEEN THESE LEGENDARY ITEMS BACK THERE? WHO COULD REFUSE THE CHANCE OF OBTAINING ONE?!? SO WHAT IS YOUR ANSWER?"}) + +local offerKeyword = keywordHandler:addKeyword({"offer"}, StdModule.say, {npcHandler = npcHandler, text = "I GRANT YOU ACCESS TO THE DUNGEON IN THE NORTH. YOU'LL FIND SOME OF MY LIVING BROTHERS THERE....BUT.....EVERY TIME YOU WANT TO ENTER YOU HAVE TO GIVE ME SOMETHING PRECIOUS. ALRIGHT?"}, function(player) return player:getLevel() > 99 end) + local mugKeyword = offerKeyword:addChildKeyword({"yes"}, StdModule.say, {npcHandler = npcHandler, text = "AS YOU WISH. WHAT DO YOU HAVE TO OFFER?"}) + mugKeyword:addChildKeyword({"golden mug"}, StdModule.say, {npcHandler = npcHandler, text = "I LIKE THAT AND GRANT YOU ACCESS TO THE DUNGEON IN THE NORTH FOR THE NEXT FEW MINUTES. COME BACK ANYTIME AND BRING ME MORE TREASURES.", reset = true}, + function(player) return player:getItemCount(2033) > 0 end, + function(player) + player:removeItem(2033, 1) + player:setStorageValue(Storage.HiddenCityOfBeregar.PythiusTheRotten, os.time() + 180) + end + ) + mugKeyword:addChildKeyword({"golden mug"}, StdModule.say, {npcHandler = npcHandler, text = "THIS IS NOT WORTH BEING PART OF MY TREASURE! BRING ME SOMETHING ELSE.", reset = true}) + mugKeyword:addChildKeyword({""}, StdModule.say, {npcHandler = npcHandler, text = "THIS IS NOT WORTH BEING PART OF MY TREASURE! BRING ME SOMETHING ELSE", reset = true}) + offerKeyword:addChildKeyword({""}, StdModule.say, {npcHandler = npcHandler, text = "TELL ME IF YOU CHANGE YOUR MIND. MY TREASURE THIRSTS FOR GOLD.", reset = true}) +keywordHandler:addKeyword({"offer"}, StdModule.say, {npcHandler = npcHandler, text = "YOU LITTLE MAGGOT. COME BACK TO ME WHEN YOU CAN HANDLE A FIGHT AGAINST MY KIND."}) + +-- Basic keywords +keywordHandler:addKeyword({"awaited"}, StdModule.say, {npcHandler = npcHandler, text = "I HAVE A MISSION FOR YOU BUT YOU NEED TO DIE FIRST AND RETURN AS AN {UNDEAD} CREATURE. COME BACK TO ME WHEN YOU ACHIEVED THIS GOAL."}) +keywordHandler:addKeyword({"exchange"}, StdModule.say, {npcHandler = npcHandler, text = "EVERYTHING YOU CARRY WITH YOU CAN ALSO BE FOUND IN MY {TREASURE}. BRING ME SOMETHING I DON'T OWN!!!"}) +keywordHandler:addKeyword({"mission"}, StdModule.say, {npcHandler = npcHandler, text = "I HAVE A MISSION FOR YOU BUT YOU NEED TO DIE FIRST AND RETURN AS AN {UNDEAD} CREATURE. COME BACK TO ME WHEN YOU ACHIEVED THIS GOAL."}) +keywordHandler:addKeyword({"undead"}, StdModule.say, {npcHandler = npcHandler, text = "BOON AND BANE. I HAVE CHOSEN THIS LIFE VOLUNTARILLY AND I NEVER REGRET IT. MY {TREASURE} IS GROWING BIGGER EACH DAY."}) + +npcHandler:setMessage(MESSAGE_GREET, "I {AWAITED} YOU!") +npcHandler:setMessage(MESSAGE_FAREWELL, "COME BACK ANYTIME AND BRING ME TREASURES.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "COME BACK ANYTIME AND BRING ME TREASURES.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/quandons_ghost.lua b/data/npc/scripts/quandons_ghost.lua new file mode 100644 index 00000000000..fb0974d988b --- /dev/null +++ b/data/npc/scripts/quandons_ghost.lua @@ -0,0 +1,28 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) + +function creatureSayCallback(cid, type, msg) + if(not(npcHandler:isFocused(cid))) then + return false + end + + local player = Player(cid) +end + +-- Missing script for complete the mission 15 of dark trails diff --git a/data/npc/scripts/queen_eloise.lua b/data/npc/scripts/queen_eloise.lua new file mode 100644 index 00000000000..3c3b60b966d --- /dev/null +++ b/data/npc/scripts/queen_eloise.lua @@ -0,0 +1,217 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if(msgcontains(msg, "outfit")) or (msgcontains(msg, "addon")) then + selfSay("In exchange for a truly generous donation, I will offer a special outfit. Do you want to make a donation?", cid) + npcHandler.topic[cid] = 1 + elseif(msgcontains(msg, "yes")) then + -- vamos tratar todas condições para YES aqui + if npcHandler.topic[cid] == 1 then + -- para o primeiro Yes, o npc deve explicar como obter o outfit + selfSay("Excellent! Now, let me explain. If you donate 1.000.000.000 gold pieces, you will be entitled to wear a unique outfit. ...", cid) + selfSay("You will be entitled to wear the {armor} for 500.000.000 gold pieces, {helmet} for an additional 250.000.000 and the {boots} for another 250.000.000 gold pieces. ...", cid) + selfSay("What will it be?", cid) + npcHandler.topic[cid] = 2 + -- O NPC só vai oferecer os addons se o player já tiver escolhido. + elseif npcHandler.topic[cid] == 2 then + -- caso o player repita o yes, resetamos o tópico para começar de novo? + selfSay("In that case, return to me once you made up your mind.", cid) + npcHandler.topic[cid] = 0 + -- Inicio do outfit + elseif npcHandler.topic[cid] == 3 then -- ARMOR/OUTFIT + if player:getStorageValue(Storage.OutfitQuest.GoldenOutfit) < 1 then + if player:getMoney() + player:getBankBalance() >= 500000000 then + local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX) + if inbox and inbox:getEmptySlots() > 0 then + local decoKit = inbox:addItem(26054, 1) + local decoItemName = ItemType(36345):getName() + decoKit:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, "You bought this item in the Store.\nUnwrap it in your own house to create a " .. decoItemName .. ".") + decoKit:setActionId(36345) + selfSay("Take this armor as a token of great gratitude. Let us forever remember this day, my friend!", cid) + player:removeMoneyNpc(500000000) + player:addOutfit(1211) + player:addOutfit(1210) + player:getPosition():sendMagicEffect(171) + player:setStorageValue(Storage.OutfitQuest.GoldenOutfit, 1) + else + selfSay("Please make sure you have free slots in your store inbox.", cid) + end + else + selfSay("You do not have enough money to donate that amount.", cid) + end + else + selfSay("You alread have that addon.", cid) + end + npcHandler.topic[cid] = 2 + -- Fim do outfit + -- Inicio do helmet + elseif npcHandler.topic[cid] == 4 then + if player:getStorageValue(Storage.OutfitQuest.GoldenOutfit) == 1 then + if player:getStorageValue(Storage.OutfitQuest.GoldenOutfit) < 2 then + if player:getMoney() + player:getBankBalance() >= 250000000 then + selfSay("Take this helmet as a token of great gratitude. Let us forever remember this day, my friend. ", cid) + player:removeMoneyNpc(250000000) + player:addOutfitAddon(1210, 1) + player:addOutfitAddon(1211, 1) + player:getPosition():sendMagicEffect(171) + player:setStorageValue(Storage.OutfitQuest.GoldenOutfit, 2) + npcHandler.topic[cid] = 2 + else + selfSay("You do not have enough money to donate that amount.", cid) + npcHandler.topic[cid] = 2 + end + else + selfSay("You alread have that outfit.", cid) + npcHandler.topic[cid] = 2 + end + else + selfSay("You need to donate {armor} outfit first.", cid) + npcHandler.topic[cid] = 2 + end + npcHandler.topic[cid] = 2 + -- Fim do helmet + -- Inicio da boots + elseif npcHandler.topic[cid] == 5 then + if player:getStorageValue(Storage.OutfitQuest.GoldenOutfit) == 2 then + if player:getStorageValue(Storage.OutfitQuest.GoldenOutfit) < 3 then + if player:getMoney() + player:getBankBalance() >= 250000000 then + selfSay("Take this boots as a token of great gratitude. Let us forever remember this day, my friend. ", cid) + player:removeMoneyNpc(250000000) + player:addOutfitAddon(1210, 2) + player:addOutfitAddon(1211, 2) + player:getPosition():sendMagicEffect(171) + player:setStorageValue(Storage.OutfitQuest.GoldenOutfit, 3) + npcHandler.topic[cid] = 2 + else + selfSay("You do not have enough money to donate that amount.", cid) + npcHandler.topic[cid] = 2 + end + else + selfSay("You alread have that outfit.", cid) + npcHandler.topic[cid] = 2 + end + else + selfSay("You need to donate {helmet} addon first.", cid) + npcHandler.topic[cid] = 2 + end + -- Fim da boots + npcHandler.topic[cid] = 2 + end + --inicio das opções armor/helmet/boots + -- caso o player não diga YES, dirá alguma das seguintes palavras: + elseif(msgcontains(msg, "armor")) and npcHandler.topic[cid] == 2 then + selfSay("So you wold like to donate 500.000.000 gold pieces which in return will entitle you to wear a unique armor?", cid) + npcHandler.topic[cid] = 3 -- alterando o tópico para que no próximo YES ele faça o outfit + elseif(msgcontains(msg, "helmet")) and npcHandler.topic[cid] == 2 then + selfSay("So you would like to donate 250.000.000 gold pieces which in return will entitle you to wear unique helmet?", cid) + npcHandler.topic[cid] = 4 -- alterando o tópico para que no próximo YES ele faça o helmet + elseif(msgcontains(msg, "boots")) and npcHandler.topic[cid] == 2 then + selfSay("So you would like to donate 250.000.000 gold pieces which in return will entitle you to wear a unique boots?", cid) + npcHandler.topic[cid] = 5 -- alterando o tópico para que no próximo YES ele faça a boots + end + -- fim das opções armor/helmet/boots +end + +-- Promotion +local node1 = keywordHandler:addKeyword({'promot'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'I can promote you for 20000 gold coins. Do you want me to promote you?'}) + node1:addChildKeyword({'yes'}, StdModule.promotePlayer, {npcHandler = npcHandler, cost = 20000, level = 20, text = 'Congratulations! You are now promoted.'}) + node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Alright then, come back when you are ready.', reset = true}) +-- Postman +keywordHandler:addKeyword({'uniforms'}, StdModule.say, {npcHandler = npcHandler, text = 'I remember about those uniforms, they had a camouflage inlay so they could be worn the inside out too. I will send some color samples via mail to Mr. Postner.'}, + function(player) return player:getStorageValue(Storage.Postman.Mission06) == 5 end, + function(player) player:setStorageValue(Storage.Postman.Mission06, 6) end +) + +-- Greeting +keywordHandler:addGreetKeyword({'hail queen'}, {npcHandler = npcHandler, text = 'I greet thee, my loyal {subject}.'}) +keywordHandler:addGreetKeyword({'salutations queen'}, {npcHandler = npcHandler, text = 'I greet thee, my loyal {subject}.'}) + +keywordHandler:addKeyword({'uniforms'}, StdModule.say, {npcHandler = npcHandler, text = 'The uniforms of our guards and soldiers are of unparraleled quality of course.'}) + +-- Basic +keywordHandler:addKeyword({'subject'}, StdModule.say, {npcHandler = npcHandler, text = 'I am {Queen} Eloise. It is my duty to reign over this marvellous {city} and the {lands} of the north.'}) +keywordHandler:addAliasKeyword({'job'}) +keywordHandler:addKeyword({'justice'}, StdModule.say, {npcHandler = npcHandler, text = 'We women try to bring justice and wisdom to all, even to males.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'I am Queen Eloise. For you it\'s \'My Queen\' or \'Your Majesty\', of course.'}) +keywordHandler:addKeyword({'news'}, StdModule.say, {npcHandler = npcHandler, text = 'I don\'t care about gossip like a simpleminded male would do.'}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = 'Soon the whole land will be ruled by women at last!'}) +keywordHandler:addAliasKeyword({'land'}) +keywordHandler:addKeyword({'how', 'are', 'you'}, StdModule.say, {npcHandler = npcHandler, text = 'Thank you, I\'m fine.'}) +keywordHandler:addKeyword({'castle'}, StdModule.say, {npcHandler = npcHandler, text = 'It\'s my humble domain.'}) +keywordHandler:addKeyword({'sell'}, StdModule.say, {npcHandler = npcHandler, text = 'Sell? Your question shows that you are a typical member of your gender!'}) +keywordHandler:addKeyword({'god'}, StdModule.say, {npcHandler = npcHandler, text = 'We honor the gods of good in our fair city, especially Crunor, of course.'}) +keywordHandler:addKeyword({'citizen'}, StdModule.say, {npcHandler = npcHandler, text = 'All citizens of Carlin are my subjects. I see them more as my childs, though, epecially the male population.'}) +keywordHandler:addKeyword({'thais'}, StdModule.say, {npcHandler = npcHandler, text = 'This beast scared my cat away on my last diplomatic mission in this filthy town.'}) +keywordHandler:addKeyword({'ferumbras'}, StdModule.say, {npcHandler = npcHandler, text = 'He is the scourge of the whole continent!'}) +keywordHandler:addKeyword({'treasure'}, StdModule.say, {npcHandler = npcHandler, text = 'The royal treasure is hidden beyond the grasps of any thieves by magical means.'}) +keywordHandler:addKeyword({'monster'}, StdModule.say, {npcHandler = npcHandler, text = 'Go and hunt them! For queen and country!'}) +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'Visit the church or the townguards for help.'}) +keywordHandler:addKeyword({'quest'}, StdModule.say, {npcHandler = npcHandler, text = 'I will call for heroes as soon as the need arises again.'}) +keywordHandler:addAliasKeyword({'mission'}) +keywordHandler:addKeyword({'gold'}, StdModule.say, {npcHandler = npcHandler, text = 'Our city is rich and prospering.'}) +keywordHandler:addAliasKeyword({'money'}) +keywordHandler:addAliasKeyword({'tax'}) +keywordHandler:addKeyword({'sewer'}, StdModule.say, {npcHandler = npcHandler, text = 'I don\'t want to talk about \'sewers\'.'}) +keywordHandler:addKeyword({'dungeon'}, StdModule.say, {npcHandler = npcHandler, text = 'Dungeons are places where males crawl around and look for trouble.'}) +keywordHandler:addKeyword({'equipment'}, StdModule.say, {npcHandler = npcHandler, text = 'Feel free to visit our town\'s magnificent shops.'}) +keywordHandler:addAliasKeyword({'food'}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = 'Don\'t worry about time in the presence of your Queen.'}) +keywordHandler:addKeyword({'hero'}, StdModule.say, {npcHandler = npcHandler, text = 'We need the assistance of heroes now and then. Even males prove useful now and then.'}) +keywordHandler:addAliasKeyword({'adventure'}) +keywordHandler:addKeyword({'collector'}, StdModule.say, {npcHandler = npcHandler, text = 'The taxes in Carlin are not high, more a symbol than a sacrifice.'}) +keywordHandler:addKeyword({'queen'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the Queen, the only rightful ruler on the continent!'}) +keywordHandler:addKeyword({'army'}, StdModule.say, {npcHandler = npcHandler, text = 'Ask one of the soldiers about that.'}) +keywordHandler:addKeyword({'enemy'}, StdModule.say, {npcHandler = npcHandler, text = 'Our enemies are numerous. We have to fight vile monsters and have to watch this silly king in the south carefully.'}) +keywordHandler:addAliasKeyword({'enemies'}) +keywordHandler:addKeyword({'thais'}, StdModule.say, {npcHandler = npcHandler, text = 'They dare to reject my reign over them!'}) +keywordHandler:addAliasKeyword({'south'}) +keywordHandler:addKeyword({'carlin'}, StdModule.say, {npcHandler = npcHandler, text = 'Isn\'t our city marvellous? Have you noticed the lovely gardens on the roofs?'}) +keywordHandler:addAliasKeyword({'city'}) +keywordHandler:addKeyword({'shop'}, StdModule.say, {npcHandler = npcHandler, text = 'My subjects maintain many fine shops. Go and have a look at their wares.'}) +keywordHandler:addKeyword({'merchant'}, StdModule.say, {npcHandler = npcHandler, text = 'Ask around about them.'}) +keywordHandler:addAliasKeyword({'craftsmen'}) +keywordHandler:addKeyword({'guild'}, StdModule.say, {npcHandler = npcHandler, text = 'The four major guilds are the Knights, the Paladins, the Druids, and the Sorcerers.'}) +keywordHandler:addKeyword({'minotaur'}, StdModule.say, {npcHandler = npcHandler, text = 'They haven\'t troubled our city lately. I guess, they fear the wrath of our druids.'}) +keywordHandler:addKeyword({'paladin'}, StdModule.say, {npcHandler = npcHandler, text = 'The paladins are great hunters.'}) +keywordHandler:addAliasKeyword({'legola'}) +keywordHandler:addKeyword({'elane'}, StdModule.say, {npcHandler = npcHandler, text = 'It\'s a shame that the High Paladin does not reside in Carlin.'}) +keywordHandler:addKeyword({'knight'}, StdModule.say, {npcHandler = npcHandler, text = 'The knights of Carlin are the bravest.'}) +keywordHandler:addAliasKeyword({'trisha'}) +keywordHandler:addKeyword({'sorc'}, StdModule.say, {npcHandler = npcHandler, text = 'The sorcerers have a small isle for their guild. So if they blow something up it does not burn the whole city to ruins.'}) +keywordHandler:addAliasKeyword({'lea'}) +keywordHandler:addKeyword({'druid'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids of Carlin are our protectors and advisors. Their powers provide us with wealth and food.'}) +keywordHandler:addAliasKeyword({'padreia'}) +keywordHandler:addKeyword({'good'}, StdModule.say, {npcHandler = npcHandler, text = 'Carlin is a center of the forces of good, of course.'}) +keywordHandler:addKeyword({'evil'}, StdModule.say, {npcHandler = npcHandler, text = 'The forces of evil have a firm grip on this puny city to the south.'}) +keywordHandler:addKeyword({'order'}, StdModule.say, {npcHandler = npcHandler, text = 'The order, Crunor gives the world, is essential for survival.'}) +keywordHandler:addKeyword({'chaos'}, StdModule.say, {npcHandler = npcHandler, text = 'Chaos is common in the southern regions, where they allow a man to reign over a realm.'}) +keywordHandler:addKeyword({'excalibug'}, StdModule.say, {npcHandler = npcHandler, text = 'A mans tale ... that means \'nonsense\', of course.'}) +keywordHandler:addKeyword({'reward'}, StdModule.say, {npcHandler = npcHandler, text = 'If you want a reward, go and bring me something this silly King Tibianus wants dearly!'}) +keywordHandler:addKeyword({'tbi'}, StdModule.say, {npcHandler = npcHandler, text = 'A dusgusting organisation, which could be only created by men.'}) +keywordHandler:addKeyword({'eremo'}, StdModule.say, {npcHandler = npcHandler, text = 'It is said that he lives on a small island near Edron. Maybe the people there know more about him.'}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Farewell, |PLAYERNAME|!') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/quentin.lua b/data/npc/scripts/quentin.lua new file mode 100644 index 00000000000..c7ae04a91a6 --- /dev/null +++ b/data/npc/scripts/quentin.lua @@ -0,0 +1,118 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Wooden Stake Quest +local stakeKeyword = keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'A blessed stake to defeat evil spirits? I do know an old prayer which is said to grant sacred power and to be able to bind this power to someone, or something. ...', + 'However, this prayer needs the combined energy of ten priests. Each of them has to say one line of the prayer. ...', + 'I could start with the prayer, but since the next priest has to be in a different location, you probably will have to travel a lot. ...', + 'Is this stake really important enough to you so that you are willing to take this burden?', + }}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == -1 end + ) + stakeKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Alright, I guess you need a stake first. Maybe Gamon can help you, the leg of a chair or something could just do. Try asking him for a stake, and if you have one, bring it back to me.', reset = true, ungreet = true}, nil, function(player) player:setStorageValue(Storage.FriendsandTraders.DefaultStart, 1) player:setStorageValue(Storage.FriendsandTraders.TheBlessedStake, 1) end) + +-- First prayer +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'I guess you couldn\'t convince Gamon to give you a stake, eh?'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 1 and player:getItemCount(5941) == 0 end) + +local stakeKeyword = keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes, I was informed what to do. Are you prepared to receive my line of the prayer?'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 1 end) + stakeKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'So receive my prayer: \'Light shall be near - and darkness afar\'. Now, bring your stake to Tibra in the Carlin church for the next line of the prayer. I will inform her what to do.', reset = true}, nil, + function(player) player:setStorageValue(Storage.FriendsandTraders.TheBlessedStake, 2) player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) end + ) + stakeKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'I will wait for you.', reset = true}) + +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You should visit Tibra in the Carlin church now.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 2 end) +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You already received my line of the prayer.'}) + +-- Twist of Fate +local blessKeyword = keywordHandler:addKeyword({'twist of fate'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'This is a special blessing I can bestow upon you once you have obtained at least one of the other blessings and which functions a bit differently. ...', + 'It only works when you\'re killed by other adventurers, which means that at least half of the damage leading to your death was caused by others, not by monsters or the environment. ...', + 'The {twist of fate} will not reduce the death penalty like the other blessings, but instead prevent you from losing your other blessings as well as the amulet of loss, should you wear one. It costs the same as the other blessings. ...', + 'Would you like to receive that protection for a sacrifice of |PVPBLESSCOST| gold, child?' + }}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the protection of the twist of fate, pilgrim.', cost = '|PVPBLESSCOST|', bless = 1}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Adventurer Stone +keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Keep your adventurer\'s stone well.'}, function(player) return player:getItemById(18559, true) end) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for free?'}, function(player) return player:getStorageValue(Storage.AdventurersGuild.FreeStone.Quentin) ~= 1 end) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, nil, function(player) player:addItem(18559, 1) player:setStorageValue(Storage.AdventurersGuild.FreeStone.Quentin, 1) end) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for 30 gold?'}) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, + function(player) return player:getMoney() + player:getBankBalance() >= 30 end, + function(player) if player:removeMoneyNpc(30) then player:addItem(18559, 1) end end + ) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, you don\'t have enough money.', reset = true}) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.'}, function(player) return player:hasBlessing(2) end) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin will provide you with the embrace of Tibia.'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, young |PLAYERNAME|! If you are heavily wounded or poisoned, I can {heal} you for free or you want the {adventurer stone}?') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Remember: If you are heavily wounded or poisoned, I can heal you for free.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'May the gods bless you, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/quero.lua b/data/npc/scripts/quero.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/quero.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/rabaz.lua b/data/npc/scripts/rabaz.lua new file mode 100644 index 00000000000..42c5236d052 --- /dev/null +++ b/data/npc/scripts/rabaz.lua @@ -0,0 +1,71 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.TibiaTales.AnInterestInBotany) < 1 then + npcHandler.topic[cid] = 1 + npcHandler:say({ + "Why yes, there is indeed some minor issue I could need your help with. I was always a friend of nature and it was not recently I discovered the joys of plants, growths, of all the flora around us. ...", + "Botany my friend. The study of plants is of great importance for our future. Many of the potions we often depend on are made of plants you know. Plants can help us tending our wounds, cure us from illness or injury. ...", + "I am currently writing an excessive compilation of all the knowledge I have gathered during my time here in Farmine and soon hope to publish it as 'Rabaz' Unabridged Almanach Of Botany'. ...", + "However, to actually complete my botanical epitome concerning Zao, I would need someone to enter these dangerous lands. Someone able to get closer to the specimens than I can. ...", + "And this is where you come in. There are two extremely rare species I need samples from. Typically not easy to come by but it should not be necessary to venture too far into Zao to find them. ...", + "Explore the anterior outskirts of Zao, use my almanach and find the two specimens with missing samples on their pages. The almanach can be found in a chest in my storage, next to my shop. It's the door over there. ...", + "If you lose it I will have to write a new one and put it in there again - which will undoubtedly take me a while. So keep an eye on it on your travels. ...", + "Once you find what I need, best use a knife to carefully cut and gather a leaf or a scrap of their integument and press it directly under their appropriate entry into my botanical almanach. ...", + "Simply return to me after you have done that and we will discuss your reward. What do you say, are you in?" + }, cid) + elseif player:getStorageValue(Storage.TibiaTales.AnInterestInBotany) == 3 then + npcHandler.topic[cid] = 2 + npcHandler:say("Well fantastic work, you gathered both samples! Now I can continue my work on the almanach, thank you very much for your help indeed. Can I take a look at my book please?", cid) + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + player:setStorageValue(Storage.TibiaTales.DefaultStart, 1) + player:setStorageValue(Storage.TibiaTales.AnInterestInBotany, 1) + player:setStorageValue(Storage.TibiaTales.AnInterestInBotanyChestDoor, 0) + npcHandler:say("Yes? Yes! That's the enthusiasm I need! Remember to bring a sharp knife to gather the samples, plants - even mutated deformed plants - are very sensitive you know. Off you go and be careful out there, Zao is no place for the feint hearted mind you.", cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + if player:removeItem(12655, 1) then + player:addItem(12656, 1) + player:addItem(2152, 10) + player:addExperience(3000, true) + player:setStorageValue(Storage.TibiaTales.AnInterestInBotany, 4) + npcHandler:say({ + "Ah, thank you. Now look at that texture and fine colour, simply marvellous. ...", + "I hope the sun in the steppe did not exhaust you too much? Shellshock. A dangerous foe in the world of field science and exploration. ...", + "Here, I always wore this comfortable hat when travelling, take it. It may be of use for you on further reconnaissances in Zao. Again you have my thanks, friend." + }, cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Oh, you don't have my book.", cid) + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/rachel.lua b/data/npc/scripts/rachel.lua new file mode 100644 index 00000000000..a3499571d7b --- /dev/null +++ b/data/npc/scripts/rachel.lua @@ -0,0 +1,70 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({"magic"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Okay, then just browse through all of my wares." + } +) + +local items = { + [VOCATION.CLIENT_ID.SORCERER] = 2190, + [VOCATION.CLIENT_ID.DRUID] = 2182 +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "first rod") or msgcontains(msg, "first wand") then + if player:isMage() then + local itemId = items[player:getVocation():getClientId()] + if player:getStorageValue(Storage.firstMageWeapon) == -1 then + npcHandler:say("So you ask me for a {" .. ItemType(itemId):getName() .. "} to begin your adventure?", cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say("What? I have already gave you one {" .. ItemType(itemId):getName() .. "}!", cid) + end + else + npcHandler:say("Sorry, you aren't a druid either a sorcerer.", cid) + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + player:addItem(itemId, 1) + npcHandler:say("Here you are young adept, take care yourself.", cid) + player:setStorageValue(Storage.firstMageWeapon, 1) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") and npcHandler.topic[cid] == 1 then + npcHandler:say("Ok then.", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome |PLAYERNAME|! Whats your need?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Of course, just browse through my wares. \z + Or do you want to look only at {potions}, {wands} or {runes}?") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/rafzan.lua b/data/npc/scripts/rafzan.lua new file mode 100644 index 00000000000..eee6bed9e45 --- /dev/null +++ b/data/npc/scripts/rafzan.lua @@ -0,0 +1,33 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'task'}, StdModule.say, {npcHandler = npcHandler, text = 'Are you here to get a task or to report you finished task?'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'Me humble name is Rafzan. Good old goblin name meaning honest, generous and nice person, I swear!'}) +keywordHandler:addKeyword({'goblin'}, StdModule.say, {npcHandler = npcHandler, text = 'Most goblins so afraid of everything, that they fight everything. Me different. Me just want trade.'}) +keywordHandler:addKeyword({'human'}, StdModule.say, {npcHandler = npcHandler, text = 'You humans are so big, strong, clever and beautiful. Me really feel little and green beside you. Must be sooo fun to be human. You surely always make profit!'}) +keywordHandler:addKeyword({'profit'}, StdModule.say, {npcHandler = npcHandler, text = 'To be honest to me human friend, me only heard about it, never seen one. I imagine it\'s something cute and cuddly.'}) +keywordHandler:addKeyword({'swamp'}, StdModule.say, {npcHandler = npcHandler, text = 'Swamp is horrible. Slowly eating away at health of poor little goblin. No profit here at all. Me will die poor and desperate, probably eaten by giant mosquitoes.'}) +keywordHandler:addKeyword({'dwarf'}, StdModule.say, {npcHandler = npcHandler, text = 'Beardmen are nasty. Always want to kill little goblin. No trade at all. Not good, not good.'}) +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'So much to do, so little help. Me poor goblin desperately needs help. Me have a few tasks me need to be done. I can offer you all money I made if you only help me a little with stuff which is easy to strong smart human but impossible for poor, little me.'}) +keywordHandler:addKeyword({'thais'}, StdModule.say, {npcHandler = npcHandler, text = 'Me heard Thais is big city with king! Must be strong and clever, to become chief of all humans. Me cannot imagine how many people you have to beat up to become king of all humans. Surely he makes lot of profit in his pretty city.'}) +keywordHandler:addKeyword({'elves'}, StdModule.say, {npcHandler = npcHandler, text = 'They are mean and cruel. Humble goblin rarely trades with them. They would rather kill poor me if not too greedy for stuff only me can get them. Still, they rob me of it for a few spare coins and there is noooo profit for poor goblin.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'Me job merchant is. Me trade with all kinds of things. Me not good trader though, so you get everything incredibly cheap! You might think me mad, but please don\'t rip off poor goblin too much. Me has four or five wives and dozens of kids to feed!'}) +keywordHandler:addKeyword({'venore'}, StdModule.say, {npcHandler = npcHandler, text = 'Humans so clever. Much, much smarter than poor, stupid goblin. They have big rich town. Goblin lives here poor and hungry. Me so impressed by you strong and smart humans. So much to learn from you. Poor goblin only sees pretty city from afar. Poor goblin too afraid to go there.'}) +keywordHandler:addKeyword({'gold'}, StdModule.say, {npcHandler = npcHandler, text = 'Me have seen a gold coin once or twice. So bright and shiny it hurt me poor eyes. You surely are incredibly rich human who has even three or four coins at once! Perhaps you want to exchange them for some things me offer? Just don\'t rob me too much, me little stupid goblin, have no idea what stuff is worth... you look honest, you surely pay fair price like I ask and tell if it\'s too cheap.'}) +keywordHandler:addKeyword({'ratmen'}, StdModule.say, {npcHandler = npcHandler, text = 'Furry guys are strange fellows. Always collecting things and stuff. Not easy to make them share, oh there is noooo profit for little, poor me to be made. They build underground dens that can stretch quite far. Rumour has it the corym have strange tunnels that connect their different networks all over the world.'}) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/rahkem.lua b/data/npc/scripts/rahkem.lua new file mode 100644 index 00000000000..708ccdf9088 --- /dev/null +++ b/data/npc/scripts/rahkem.lua @@ -0,0 +1,107 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Please, not so loud, not so loud. Some of us are trying to rest in peace here.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Twist of Fate +local blessKeyword = keywordHandler:addKeyword({'twist of fate'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'This is a special blessing I can bestow upon you once you have obtained at least one of the other blessings and which functions a bit differently. ...', + 'It only works when you\'re killed by other adventurers, which means that at least half of the damage leading to your death was caused by others, not by monsters or the environment. ...', + 'The {twist of fate} will not reduce the death penalty like the other blessings, but instead prevent you from losing your other blessings as well as the amulet of loss, should you wear one. It costs the same as the other blessings. ...', + 'Would you like to receive that protection for a sacrifice of |PVPBLESSCOST| gold, child?' + }}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the protection of the twist of fate, pilgrim.', cost = '|PVPBLESSCOST|', bless = 6}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Adventurer Stone +keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Keep your adventurer\'s stone well.'}, function(player) return player:getItemById(18559, true) end) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for free?'}, function(player) return player:getStorageValue(Storage.AdventurersGuild.FreeStone.Rahkem) ~= 1 end) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, nil, function(player) player:addItem(18559, 1) player:setStorageValue(Storage.AdventurersGuild.FreeStone.Rahkem, 1) end) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for 30 gold?'}) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, + function(player) return player:getMoney() + player:getBankBalance() >= 30 end, + function(player) if player:removeMoneyNpc(30) then player:addItem(18559, 1) end end + ) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, you don\'t have enough money.', reset = true}) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Wooden Stake +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'I think you have forgotten to bring your stake, pilgrim.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 8 and player:getItemCount(5941) == 0 end) + +local stakeKeyword = keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes, I was informed what to do. Are you prepared to receive my line of the prayer?'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 8 end) + stakeKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'So receive my prayer: \'Let there be power and compassion\'. Now, bring your stake to Brewster in Port Hope for the next line of the prayer. I will inform him what to do.', reset = true}, nil, + function(player) player:setStorageValue(Storage.FriendsandTraders.TheBlessedStake, 9) player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) end + ) + stakeKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'I will wait for you.', reset = true}) + +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You should visit Brewster in Port Hope now.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 9 end) +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You already received my line of the prayer.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) > 9 end) +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'A blessed stake? That is a strange request. Maybe Quentin knows more, he is one of the oldest monks after all.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.'}, function(player) return player:hasBlessing(2) end) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin will provide you with the embrace of Tibia.'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ramina.lua b/data/npc/scripts/ramina.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/ramina.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/rapanaio.lua b/data/npc/scripts/rapanaio.lua new file mode 100644 index 00000000000..530a43dbbb0 --- /dev/null +++ b/data/npc/scripts/rapanaio.lua @@ -0,0 +1,21 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'mission'}, StdModule.say, {npcHandler = npcHandler, text = 'Now that we have arrived you should waste no time and fight your way to the lair of evil and destroy its master before its too late!'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'Me humble name is Rapanaio. Good old goblin name meaning honest, generous and nice person, I swear!'}) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/rapanaioboat.lua b/data/npc/scripts/rapanaioboat.lua new file mode 100644 index 00000000000..89e22199b2a --- /dev/null +++ b/data/npc/scripts/rapanaioboat.lua @@ -0,0 +1,39 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Passage to {Evil Isle}.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, cost, destination, action) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, discount = 'postman', destination = destination}, nil, action) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('evil isle', 0, Position(32668, 31457, 6)) + + +-- Basic +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Rapanaio from the Royal Tibia Line.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this sailing-ship.'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome on board, |PLAYERNAME|. I can travel you to {evil isle}.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye. Recommend us if you were satisfied with our service.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye then.') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/rapanaioisleofevil.lua b/data/npc/scripts/rapanaioisleofevil.lua new file mode 100644 index 00000000000..6e8345b5d78 --- /dev/null +++ b/data/npc/scripts/rapanaioisleofevil.lua @@ -0,0 +1,39 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Passage to {Kazordoon}.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, cost, destination, action) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, discount = 'postman', destination = destination}, nil, action) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('kazordoon', 0, Position(32699, 31993, 14)) + + +-- Basic +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Rapanaio from the Royal Tibia Line.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this sailing-ship.'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome on board, |PLAYERNAME|. I can travel you to {kazordoon}.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye. Recommend us if you were satisfied with our service.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye then.') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/rashid.lua b/data/npc/scripts/rashid.lua new file mode 100644 index 00000000000..7bde340df44 --- /dev/null +++ b/data/npc/scripts/rashid.lua @@ -0,0 +1,237 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if(not npcHandler:isFocused(cid)) then + return false + end + local player = Player(cid) + if(msgcontains(msg, "mission")) then + if(os.date("%A") == "Monday") then + if(player:getStorageValue(Storage.TravellingTrader.Mission01) < 1) then + npcHandler:say("Well, you could attempt the mission to become a recognised trader, but it requires a lot of travelling. Are you willing to try?", cid) + npcHandler.topic[cid] = 1 + elseif(player:getStorageValue(Storage.TravellingTrader.Mission01) == 1) then + npcHandler:say("Have you managed to obtain a rare deer trophy for my customer?", cid) + npcHandler.topic[cid] = 3 + end + elseif(os.date("%A") == "Tuesday") then + if(player:getStorageValue(Storage.TravellingTrader.Mission01) == 2 and player:getStorageValue(Storage.TravellingTrader.Mission02) < 1 ) then + npcHandler:say("So, my friend, are you willing to proceed to the next mission to become a recognised trader?", cid) + npcHandler.topic[cid] = 4 + elseif(player:getStorageValue(Storage.TravellingTrader.Mission02) == 4) then + npcHandler:say("Did you bring me the package?", cid) + npcHandler.topic[cid] = 6 + end + elseif(os.date("%A") == "Wednesday") then + if(player:getStorageValue(Storage.TravellingTrader.Mission02) == 5 and player:getStorageValue(Storage.TravellingTrader.Mission03) < 1 ) then + npcHandler:say("So, my friend, are you willing to proceed to the next mission to become a recognised trader?", cid) + npcHandler.topic[cid] = 7 + elseif(player:getStorageValue(Storage.TravellingTrader.Mission03) == 2) then + npcHandler:say("Have you brought the cheese?", cid) + npcHandler.topic[cid] = 9 + end + elseif(os.date("%A") == "Thursday") then + if(player:getStorageValue(Storage.TravellingTrader.Mission03) == 3 and player:getStorageValue(Storage.TravellingTrader.Mission04) < 1) then + npcHandler:say("So, my friend, are you willing to proceed to the next mission to become a recognised trader?", cid) + npcHandler.topic[cid] = 10 + elseif(player:getStorageValue(Storage.TravellingTrader.Mission04) == 2) then + npcHandler:say("Have you brought the vase?", cid) + npcHandler.topic[cid] = 12 + end + elseif(os.date("%A") == "Friday") then + if(player:getStorageValue(Storage.TravellingTrader.Mission04) == 3 and player:getStorageValue(Storage.TravellingTrader.Mission05) < 1) then + npcHandler:say("So, my friend, are you willing to proceed to the next mission to become a recognised trader?", cid) + npcHandler.topic[cid] = 13 + elseif(player:getStorageValue(Storage.TravellingTrader.Mission05) == 2) then + npcHandler:say("Have you brought a cheap but good crimson sword?", cid) + npcHandler.topic[cid] = 15 + end + elseif(os.date("%A") == "Saturday") then + if(player:getStorageValue(Storage.TravellingTrader.Mission05) == 3 and player:getStorageValue(Storage.TravellingTrader.Mission06) < 1) then + npcHandler:say("So, my friend, are you willing to proceed to the next mission to become a recognised trader?", cid) + npcHandler.topic[cid] = 16 + elseif(player:getStorageValue(Storage.TravellingTrader.Mission06) == 1) then + npcHandler:say("Have you brought me a gold fish??", cid) + npcHandler.topic[cid] = 18 + end + elseif(os.date("%A") == "Sunday") then + if(player:getStorageValue(Storage.TravellingTrader.Mission06) == 2 and player:getStorageValue(Storage.TravellingTrader.Mission07) ~= 1) then + npcHandler:say("Ah, right. I hereby declare you - one of my recognised traders! Feel free to offer me your wares!", cid) + player:setStorageValue(Storage.TravellingTrader.Mission07, 1) + player:addAchievement('Recognised Trader') + npcHandler.topic[cid] = 0 + end + end + elseif(msgcontains(msg, "yes")) then + if(npcHandler.topic[cid] == 1) then + npcHandler:say({ + "Very good! I need talented people who are able to handle my wares with care, find good offers and the like, so I'm going to test you. ...", + "First, I'd like to see if you can dig up rare wares. Something like a ... mastermind shield! ...", + "Haha, just kidding, fooled you there, didn't I? Always control your nerves, that's quite important during bargaining. ...", + "Okay, all I want from you is one of these rare deer trophies. I have a customer here in Svargrond who ordered one, so I'd like you to deliver it tome while I'm in Svargrond. ...", + "Everything clear and understood?" + }, cid) + + npcHandler.topic[cid] = 2 + elseif(npcHandler.topic[cid] == 2) then + npcHandler:say("Fine. Then get a hold of that deer trophy and bring it to me while I'm in Svargrond. Just ask me about your mission.", cid) + player:setStorageValue(Storage.TravellingTrader.Mission01, 1) + npcHandler.topic[cid] = 0 + elseif(npcHandler.topic[cid] == 3) then + if player:removeItem(7397, 1) then + npcHandler:say("Well done! I'll take that from you. Come see me another day, I'll be busy for a while now. ", cid) + player:setStorageValue(Storage.TravellingTrader.Mission01, 2) + npcHandler.topic[cid] = 0 + end + elseif(npcHandler.topic[cid] == 4) then + npcHandler:say({ + "Alright, that's good to hear. From you as my trader and deliveryman, I expect more than finding rare items. ...", + "You also need to be able to transport heavy wares, weaklings won't get far here. I have ordered a special package from Edron. ...", + "Pick it up from Willard and bring it back to me while I'm in Liberty Bay. Everything clear and understood?" + }, cid) + npcHandler.topic[cid] = 5 + elseif(npcHandler.topic[cid] == 5) then + npcHandler:say("Fine. Then off you go, just ask Willard about the 'package for Rashid'.", cid) + player:setStorageValue(Storage.TravellingTrader.Mission02, 1) + npcHandler.topic[cid] = 0 + elseif(npcHandler.topic[cid] == 6) then + if player:removeItem(7503, 1) then + npcHandler:say("Great. Just place it over there - yes, thanks, that's it. Come see me another day, I'll be busy for a while now. ", cid) + player:setStorageValue(Storage.TravellingTrader.Mission02, 5) + npcHandler.topic[cid] = 0 + end + elseif(npcHandler.topic[cid] == 7) then + npcHandler:say({ + "Well, that's good to hear. From you as my trader and deliveryman, I expect more than carrying heavy packages. ...", + "You also need to be fast and deliver wares in time. I have ordered a very special cheese wheel made from Darashian milk. ...", + "Unfortunately, the high temperature in the desert makes it rot really fast, so it must not stay in the sun for too long. ...", + "I'm also afraid that you might not be able to use ships because of the smell of the cheese. ...", + "Please get the cheese from Miraia and bring it to me while I'm in Port Hope. Everything clear and understood?" + }, cid) + npcHandler.topic[cid] = 8 + elseif(npcHandler.topic[cid] == 8) then + npcHandler:say("Okay, then please find Miraia in Darashia and ask her about the {'scarab cheese'}.", cid) + player:setStorageValue(Storage.TravellingTrader.Mission03, 1) + npcHandler.topic[cid] = 0 + elseif(npcHandler.topic[cid] == 9) then + if player:removeItem(8112, 1) then + npcHandler:say("Mmmhh, the lovely odeur of scarab cheese! I really can't understand why most people can't stand it. Thanks, well done! ", cid) + player:setStorageValue(Storage.TravellingTrader.Mission03, 3) + npcHandler.topic[cid] = 0 + end + elseif(npcHandler.topic[cid] == 10) then + npcHandler:say({ + "Well, that's good to hear. From you as my trader and deliveryman, I expect more than bringing stinky cheese. ...", + "I wonder if you are able to deliver goods so fragile they almost break when looked at. ...", + "I have ordered a special elven vase from Briasol in Ab'Dendriel. Get it from him and don't even touch it, just bring it to me while I'm in Ankrahmun. Everything clear and understood?" + }, cid) + npcHandler.topic[cid] = 11 + elseif(npcHandler.topic[cid] == 11) then + npcHandler:say("Okay, then please find {Briasol} in {Ab'Dendriel} and ask for a {'fine vase'}.", cid) + player:setStorageValue(Storage.TravellingTrader.Mission04, 1) + player:addMoney(1000) + npcHandler.topic[cid] = 0 + elseif(npcHandler.topic[cid] == 12) then + if player:removeItem(7582, 1) then + npcHandler:say("I'm surprised that you managed to bring this vase without a single crack. That was what I needed to know, thank you. ", cid) + player:setStorageValue(Storage.TravellingTrader.Mission04, 3) + npcHandler.topic[cid] = 0 + end + elseif(npcHandler.topic[cid] == 13) then + npcHandler:say({ + "Fine! There's one more skill that I need to test and which is cruicial for a successful trader. ...", + "Of course you must be able to haggle, else you won't survive long in this business. To make things as hard as possible for you, I have the perfect trade partner for you. ...", + "Dwarves are said to be the most stubborn of all traders. Travel to {Kazordoon} and try to get the smith {Uzgod} to sell a {crimson sword} to you. ...", + "Of course, it has to be cheap. Don't come back with anything more expensive than 400 gold. ...", + "And the quality must not suffer, of course! Everything clear and understood?", + "Dwarves are said to be the most stubborn of all traders. Travel to Kazordoon and try to get the smith Uzgod to sell a crimson sword to you. ..." + }, cid) + npcHandler.topic[cid] = 14 + elseif(npcHandler.topic[cid] == 14) then + npcHandler:say("Okay, I'm curious how you will do with {Uzgod}. Good luck!", cid) + player:setStorageValue(Storage.TravellingTrader.Mission05, 1) + npcHandler.topic[cid] = 0 + elseif(npcHandler.topic[cid] == 15) then + if player:removeItem(7385, 1) then + npcHandler:say("Ha! You are clever indeed, well done! I'll take this from you. Come see me tomorrow, I think we two might get into business after all.", cid) + player:setStorageValue(Storage.TravellingTrader.Mission05, 3) + npcHandler.topic[cid] = 0 + end + elseif(npcHandler.topic[cid] == 16) then + npcHandler:say({ + "My friend, it seems you have already learnt a lot about the art of trading. I think you are more than worthy to become a recognised trader. ...", + "There is just one little favour that I would ask from you... something personal, actually, forgive my boldness. ...", + "I have always dreamed to have a small pet, one that I could take with me and which wouldn't cause problems. ...", + "Could you - just maybe - bring me a small goldfish in a bowl? I know that you would be able to get one, wouldn't you?" + }, cid) + npcHandler.topic[cid] = 17 + elseif(npcHandler.topic[cid] == 17) then + npcHandler:say("Thanks so much! I'll be waiting eagerly for your return then.", cid) + player:setStorageValue(Storage.TravellingTrader.Mission06, 1) + npcHandler.topic[cid] = 0 + elseif(npcHandler.topic[cid] == 18) then + if player:removeItem(5929, 1) then + npcHandler:say("Thank you!! Ah, this makes my day! I'll take the rest of the day off to get to know this little guy. Come see me tomorrow, if you like.", cid) + player:setStorageValue(Storage.TravellingTrader.Mission06, 2) + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +keywordHandler:addKeyword({"job"}, StdModule.say, {npcHandler = npcHandler, text = "I am a travelling trader. I don't buy everything, though. And not from everyone, for that matter."}) +keywordHandler:addKeyword({"name"}, StdModule.say, {npcHandler = npcHandler, text = "I am Rashid, son of the desert."}) +keywordHandler:addKeyword({"offers"}, StdModule.say, {npcHandler = npcHandler, text = "Of course, old friend. You can also browse only armor, legs, shields, helmets, boots, weapons, enchanted weapons, jewelry or miscellaneous stuff."}) +keywordHandler:addKeyword({"ab'dendriel"}, StdModule.say, {npcHandler = npcHandler, text = "Elves... I don't really trust them. All this talk about nature and flowers and treehugging... I'm sure there's some wicked scheme behind all this."}) +keywordHandler:addKeyword({"desert"}, StdModule.say, {npcHandler = npcHandler, text = "My beloved hometown! Ah, the sweet scent of the desert sands, the perfect shape of the pyramids... stunningly beautiful."}) +keywordHandler:addKeyword({"carlin"}, StdModule.say, {npcHandler = npcHandler, text = "I have to go to Carlin once in a while, since the queen wishes to see my exclusive wares in regular intervals."}) +keywordHandler:addKeyword({"cormaya"}, StdModule.say, {npcHandler = npcHandler, text = "Cormaya? Not a good place to make business, it's way too far and small."}) +keywordHandler:addKeyword({"darashia"}, StdModule.say, {npcHandler = npcHandler, text = "It's not the real thing, but almost as good. The merchants there claim ridiculous prices, which is fine for my own business."}) +keywordHandler:addKeyword({"edron"}, StdModule.say, {npcHandler = npcHandler, text = "Ah yes, Edron! Such a lovely and quiet island! I usually make some nice business there."}) +keywordHandler:addKeyword({"fibula"}, StdModule.say, {npcHandler = npcHandler, text = "Too few customers there, it's not worth the trip."}) +keywordHandler:addKeyword({"greenshore"}, StdModule.say, {npcHandler = npcHandler, text = "Um... I don't think so."}) +keywordHandler:addKeyword({"kazordoon"}, StdModule.say, {npcHandler = npcHandler, text = "I don't like being underground much. I also tend to get lost in these labyrinthine dwarven tunnels, so I rather avoid them."}) +keywordHandler:addKeyword({"liberty bay"}, StdModule.say, {npcHandler = npcHandler, text = "When you avoid the slums, it's a really pretty city. Almost as pretty as the governor's daughter."}) +keywordHandler:addKeyword({"northport"}, StdModule.say, {npcHandler = npcHandler, text = "Um... I don't think so."}) +keywordHandler:addKeyword({"port hope"}, StdModule.say, {npcHandler = npcHandler, text = "I like the settlement itself, but I don't set my foot into the jungle. Have you seen the size of these centipedes??"}) +keywordHandler:addKeyword({"senja"}, StdModule.say, {npcHandler = npcHandler, text = "Um... I don't think so."}) +keywordHandler:addKeyword({"svargrond"}, StdModule.say, {npcHandler = npcHandler, text = "I wish it was a little bit warmer there, but with a good mug of barbarian mead in your tummy everything gets a lot cosier."}) +keywordHandler:addKeyword({"thais"}, StdModule.say, {npcHandler = npcHandler, text = "I feel uncomfortable and rather unsafe in Thais, so I don't really travel there."}) +keywordHandler:addKeyword({"vega"}, StdModule.say, {npcHandler = npcHandler, text = "Um... I don't think so."}) +keywordHandler:addKeyword({"venore"}, StdModule.say, {npcHandler = npcHandler, text = "Although it's the flourishing trade centre of Tibia, I don't like going there. Too much competition for my taste."}) +keywordHandler:addKeyword({"time"}, StdModule.say, {npcHandler = npcHandler, text = "It's almost time to journey on."}) +keywordHandler:addKeyword({"king"}, StdModule.say, {npcHandler = npcHandler, text = "Kings, queens, emperors and kaliphs... everyone claims to be different and unique, but actually it's the same thing everywhere."}) + +npcHandler:setMessage(MESSAGE_GREET, "Ah, a customer! Be greeted, |PLAYERNAME|!") +npcHandler:setMessage(MESSAGE_FAREWELL, "Farewell, |PLAYERNAME|, may the winds guide your way.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Come back soon!") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Take all the time you need to decide what you want!") + +local function onTradeRequest(cid) + if Player(cid):getStorageValue(Storage.TravellingTrader.Mission07) ~= 1 then + npcHandler:say('Sorry, but you do not belong to my exclusive customers. I have to make sure that I can trust in the quality of your wares.', cid) + return false + end + + return true +end + +npcHandler:setCallback(CALLBACK_ONTRADEREQUEST, onTradeRequest) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/rata_mari.lua b/data/npc/scripts/rata_mari.lua new file mode 100644 index 00000000000..86f84145841 --- /dev/null +++ b/data/npc/scripts/rata_mari.lua @@ -0,0 +1,79 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local function greetCallback(cid) + if Player(cid):getStorageValue(Storage.DjinnWar.MaridFaction.Mission02) == -1 then + return false + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'spy report') then + local reportProgress = player:getStorageValue(Storage.DjinnWar.MaridFaction.RataMari) + if reportProgress < 1 then + npcHandler:say({ + 'You have come for the report? Great! I have been working hard on it during the last months. And nobody came to pick it up. I thought everybody had forgotten about me! ...', + 'Do you have any idea how difficult it is to hold a pen when you have claws instead of hands? ...', + 'But - you know - now I have worked so hard on this report I somehow don\'t want to part with it. At least not without some decent payment. ...', + 'All right - listen - I know Fa\'hradin would not approve of this, but I can\'t help it. I need some cheese! I need it now! ...', + 'And I will not give the report to you until you get me some! Meep!' + }, cid) + player:setStorageValue(Storage.DjinnWar.MaridFaction.RataMari, 1) + + elseif reportProgress == 1 then + npcHandler:say('Ok, have you brought me the cheese, I\'ve asked for?', cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say('I already gave you the report. I\'m not going to write another one!', cid) + end + + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, 'yes') then + if not player:removeItem(2696, 1) then + npcHandler:say('No cheese - no report.', cid) + return true + end + player:setStorageValue(Storage.DjinnWar.MaridFaction.RataMari, 2) + player:addItem(2345, 1) + npcHandler:say('Meep! Meep! Great! Here is the spyreport for you!', cid) + else + npcHandler:say('No cheese - no report.', cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'rat'}, StdModule.say, {npcHandler = npcHandler, text = 'Your power of observation is stunning. Yes, I\'m a rat.'}) + +-- Greeting message +keywordHandler:addGreetKeyword({"piedpiper"}, {npcHandler = npcHandler, text = "Meep? I mean - hello! Sorry, |PLAYERNAME|... Being a {rat} has kind of grown on me."}) + +npcHandler:setMessage(MESSAGE_GREET, "Meep? I mean - hello! Sorry, |PLAYERNAME|... Being a {rat} has kind of grown on me.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Meep!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Meep!") + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/ray.lua b/data/npc/scripts/ray.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/ray.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/raymond_striker.lua b/data/npc/scripts/raymond_striker.lua new file mode 100644 index 00000000000..b6bf2ae574b --- /dev/null +++ b/data/npc/scripts/raymond_striker.lua @@ -0,0 +1,124 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "eleonore") then + if player:getStorageValue(Storage.TheShatteredIsles.APoemForTheMermaid) < 1 then + npcHandler:say("Eleonore ... Yes, I remember her... vaguely. She is a pretty girl ... but still only a girl and now I am in love with a beautiful and passionate woman. A true {mermaid} even.", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "mission") then + if player:getStorageValue(Storage.TheShatteredIsles.APoemForTheMermaid) < 1 then + npcHandler:say("Don't ask about silly missions. All I can think about is this lovely {mermaid}.", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.TheShatteredIsles.APoemForTheMermaid) == 3 and player:getStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven) < 1 then + npcHandler:say("Ask around in the settlement where you can help out. If you have proven your worth I might have some missions for you.", cid) + player:setStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven, 1) + elseif player:getStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven) == 14 and player:getStorageValue(Storage.TheShatteredIsles.RaysMission1) < 1 then + npcHandler:say({ + 'Indeed, I could use some help. The evil pirates of Nargor have convinced an alchemist from Edron to supply them with a substance called Fafnar\'s Fire ...', + 'It can burn even on water and is a threat to us all. I need you to travel to Edron and pretend to the alchemist Sandra that you are the one whom the other pirates sent to get the fire ...', + 'When she asks for a payment, tell her \'Your continued existence is payment enough\'. That should enrage any member of the Edron academy enough to refuse any further deals with the pirates.', + }, cid) + player:setStorageValue(Storage.TheShatteredIsles.RaysMission1, 1) + elseif player:getStorageValue(Storage.TheShatteredIsles.RaysMission1) == 2 then + npcHandler:say("I think that means 'mission accomplished'. Hehe. I guess that will put an end to their efforts to buy any alchemical substance from Edron.", cid) + player:setStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven, 15) + player:setStorageValue(Storage.TheShatteredIsles.RaysMission1, 3) + elseif player:getStorageValue(Storage.TheShatteredIsles.RaysMission1) == 3 and player:getStorageValue(Storage.TheShatteredIsles.RaysMission2) < 1 then + npcHandler:say({ + 'The mission on which I will send you is vital to our cause. It is a sabotage mission. Nargor is guarded by several heavy catapults. ...', + 'I need you to sabotage the most dangerous of those catapults which can be found right in their harbour, aiming at ships passing by the entrance. ...', + 'Get a fire bug - you can buy them in Liberty Bay - and set this catapult on fire. ...', + 'Make sure to use the bug on the left part of the catapult where its lever is. That is where it\'s most vulnerable. ...', + 'If you see a short explosion, you will know that it worked. I will tell Sebastian to bring you to Nargor, but beware. ...', + 'Of course, he can\'t drop you off directly in the pirate\'s base. However, we have discovered a secret way into the Howling Grotto. ...', + 'Try to make your way through the caves of Nargor to reach their harbour. This is where you will find the catapult in question.' + }, cid) + player:setStorageValue(Storage.TheShatteredIsles.AccessToNargor, 1) + player:setStorageValue(Storage.TheShatteredIsles.RaysMission2, 1) + elseif player:getStorageValue(Storage.TheShatteredIsles.RaysMission2) == 2 and player:getStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven) == 16 then + npcHandler:say("You did it! Excellent!", cid) + player:setStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven, 18) + player:setStorageValue(Storage.TheShatteredIsles.RaysMission2, 3) + elseif player:getStorageValue(Storage.TheShatteredIsles.RaysMission2) == 3 and player:getStorageValue(Storage.TheShatteredIsles.RaysMission3) < 1 then + npcHandler:say({ + 'If you manage to accomplish this vital mission you will prove yourself to be a worthy member of our community. Imight even grant you your own ship and pirate clothing! ...', + 'So listen to the first step of my plan. I want you to infiltrate their base. Try to enter their tavern, which meansthat you have to get past the guard. ...', + 'You will probably have to deceive him somehow, so that he thinks you are one of them. ...', + 'In the tavern, the pirates feel safe and plan their next strikes. Study ALL of their maps and plans lying around ...', + 'Afterwards, return here and report to me about your mission.' + }, cid) + player:setStorageValue(Storage.TheShatteredIsles.RaysMission3, 1) + elseif player:getStorageValue(Storage.TheShatteredIsles.RaysMission3) == 1 and player:getStorageValue(Storage.TheShatteredIsles.TavernMap1) == 1 and player:getStorageValue(Storage.TheShatteredIsles.TavernMap2) == 1 and player:getStorageValue(Storage.TheShatteredIsles.TavernMap3) == 1 then + npcHandler:say({ + 'Well done, my friend. That will help us a lot. Of course there are other things to be done though. ...', + 'I learned that Klaus, the owner of the tavern, wants me dead. He is offering any of those pirates a mission to kill me....', + 'If we could convince him that you fulfilled that mission, the pirates will have the party of their lives. This would beour chance for a sneak attack to damage their boats and steal their plunder! ...', + 'Obtain this mission from him and learn what he needs as a proof. Then return to me and report to me about yourmission so we can formulate an appropriate plan.' + }, cid) + player:setStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven, 20) + player:setStorageValue(Storage.TheShatteredIsles.RaysMission3, 3) + player:setStorageValue(Storage.TheShatteredIsles.RaysMission4, 1) + elseif player:getStorageValue(Storage.TheShatteredIsles.RaysMission4) == 2 then + npcHandler:say("My pillow?? They know me all too well... I've owned it since my childhood. However. Here, take it and convincehim that I am dead.", cid) + player:addItem(11427, 1) + player:setStorageValue(Storage.TheShatteredIsles.RaysMission4, 3) + elseif player:getStorageValue(Storage.TheShatteredIsles.RaysMission4) == 4 then + npcHandler:say({ + 'Incredible! You did what no other did even dare to think about! You are indeed a true hero to our cause ...', + 'Sadly I have no ship that lacks a captain, else you would of course be our first choice. I am still true to my word asbest as I am able. ...', + 'So take this as your very own ship. Oh, and remind me about the pirate outfit sometime.' + }, cid) + player:addItem(2113, 1) + player:setStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven, 21) + player:setStorageValue(Storage.TheShatteredIsles.RaysMission4, 5) + end + elseif msgcontains(msg, "mermaid") then + if player:getStorageValue(Storage.TheShatteredIsles.APoemForTheMermaid) < 1 then + if npcHandler.topic[cid] == 1 then + npcHandler:say("The mermaid is the most beautiful creature I have ever met. She is so wonderful. It was some kind of magic as we first met. A look in her eyes and I suddenly knew there would be never again another woman in my life but her.", cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.TheShatteredIsles.APoemForTheMermaid, 1) + end + elseif player:getStorageValue(Storage.TheShatteredIsles.APoemForTheMermaid) == 1 and player:getStorageValue(Storage.TheShatteredIsles.ReputationInSabrehaven) < 1 then + npcHandler:say("I am deeply ashamed that I lacked the willpower to resist her spell. Thank you for your help in that matter. Now my head is once more free to think about our {mission}.", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "pirate outfit") then + if player:getStorageValue(Storage.TheShatteredIsles.AccessToLagunaIsland) == 1 and player:getStorageValue(Storage.OutfitQuest.PirateBaseOutfit) < 1 and player:getStorageValue(Storage.TheShatteredIsles.RaysMission4) == 5 then + npcHandler:say("Ah, right! The pirate outfit! Here you go, now you are truly one of us.", cid) + player:addOutfit(151) + player:addOutfit(155) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + player:setStorageValue(Storage.OutfitQuest.PirateBaseOutfit, 1) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Be greeted. Is there anything I can {do for you}?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Oh well.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/razan.lua b/data/npc/scripts/razan.lua new file mode 100644 index 00000000000..2e8721b69b0 --- /dev/null +++ b/data/npc/scripts/razan.lua @@ -0,0 +1,142 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local message = {} + +local config = { + ['ape fur'] = { + itemId = 5883, + count = 100, + storageValue = 1, + text = { + 'Have you really managed to fulfil the task and brought me 100 pieces of ape fur?', + 'Only ape fur is good enough to touch the feet of our Caliph.', + 'Ahhh, this softness! I\'m impressed, |PLAYERNAME|. You\'re on the best way to earn that turban. Now, please retrieve 100 fish fins.' + } + }, + ['fish fins'] = { + itemId = 5895, + count = 100, + storageValue = 2, + text = { + 'Were you able to discover the undersea race and retrieved 100 fish fins?', + 'I really wonder what the explorer society is up to. Actually I have no idea how they managed to dive unterwater.', + 'I never thought you\'d make it, |PLAYERNAME|. Now we only need two enchanted chicken wings to start our waterwalking test!' + } + }, + ['enchanted chicken wings'] = { + itemId = 5891, + count = 2, + storageValue = 3, + text = { + 'Were you able to get hold of two enchanted chicken wings?', + 'Enchanted chicken wings are actually used to make boots of haste, so they could be magically extracted again. Djinns are said to be good at that.', + 'Great, thank you very much. Just bring me 100 pieces of blue cloth now and I will happily show you how to make a turban.' + } + }, + ['blue cloth'] = { + itemId = 5912, + count = 100, + storageValue = 4, + text = { + 'Ah, have you brought the 100 pieces of blue cloth?', + 'It\'s a great material for turbans.', + 'Ah! Congratulations - even if you are not a true weaponmaster, you surely deserve to wear this turban. Here, I\'ll tie it for you.' + } + } +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, 'outfit') then + npcHandler:say(player:getSex() == PLAYERSEX_FEMALE and 'My turban? I know something better for a pretty girl like you. Why don\'t you go talk to Miraia?' or 'My turban? Eh no, you can\'t have it. Only oriental weaponmasters may wear it after having completed a difficult task.', cid) + elseif msgcontains(msg, 'task') then + if player:getSex() == PLAYERSEX_FEMALE then + npcHandler:say('I really don\'t want to make girls work for me. If you are looking for a job, ask Miraia.', cid) + return true + end + + if player:getStorageValue(Storage.OutfitQuest.secondOrientalAddon) < 1 then + npcHandler:say('You mean, you would like to prove that you deserve to wear such a turban?', cid) + npcHandler.topic[cid] = 1 + end + elseif config[msg] and npcHandler.topic[cid] == 0 then + if player:getStorageValue(Storage.OutfitQuest.secondOrientalAddon) == config[msg].storageValue then + npcHandler:say(config[msg].text[1], cid) + npcHandler.topic[cid] = 3 + message[cid] = msg + else + npcHandler:say(config[msg].text[2], cid) + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + 'Alright, then listen to the following requirements. We are currently in dire need of ape fur since the Caliph has requested a new bathroom carpet. ...', + 'Thus, please bring me 100 pieces of ape fur. Secondly, it came to our ears that the explorer society has discovered a new undersea race of fishmen. ...', + 'Their fins are said to allow humans to walk on water! Please bring us 100 of these fish fin. ...', + 'Third, if the plan of walking on water should fail, we need enchanted chicken wings to prevent the testers from drowning. Please bring me two. ...', + 'Last but not least, just drop by with 100 pieces of blue cloth and I will happily show you how to make a turban. ...', + 'Did you understand everything I told you and are willing to handle this task?' + }, cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + if player:getStorageValue(Storage.OutfitQuest.DefaultStart) ~= 1 then + player:setStorageValue(Storage.OutfitQuest.DefaultStart, 1) + end + player:setStorageValue(Storage.OutfitQuest.secondOrientalAddon, 1) + npcHandler:say('Excellent! Come back to me once you have collected 100 pieces of ape fur.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + local targetMessage = config[message[cid]] + if not player:removeItem(targetMessage.itemId, targetMessage.count) then + npcHandler:say('That is a shameless lie.', cid) + npcHandler.topic[cid] = 0 + return true + end + + player:setStorageValue(Storage.OutfitQuest.secondOrientalAddon, player:getStorageValue(Storage.OutfitQuest.secondOrientalAddon) + 1) + if player:getStorageValue(Storage.OutfitQuest.secondOrientalAddon) == 5 then + player:addOutfitAddon(146, 2) + player:addOutfitAddon(150, 2) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + end + npcHandler:say(targetMessage.text[3], cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] ~= 0 then + npcHandler:say('What a pity.', cid) + npcHandler.topic[cid] = 0 + end + + return true +end + +local function onReleaseFocus(cid) + message[cid] = nil +end + +npcHandler:setMessage(MESSAGE_GREET, 'Greetings |PLAYERNAME|. What leads you to me?') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Daraman\'s blessings.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/rebel.lua b/data/npc/scripts/rebel.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/rebel.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/red_lilly.lua b/data/npc/scripts/red_lilly.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/red_lilly.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/redward.lua b/data/npc/scripts/redward.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/redward.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/reed.lua b/data/npc/scripts/reed.lua new file mode 100644 index 00000000000..46b3da7ace0 --- /dev/null +++ b/data/npc/scripts/reed.lua @@ -0,0 +1,53 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if(msgcontains(msg, "report")) then + if(player:getStorageValue(Storage.InServiceofYalahar.Questline) == 10 or player:getStorageValue(Storage.InServiceofYalahar.Questline) == 11) then + npcHandler:say("You have NO idea what we have to endure each day .. . ", cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, player:getStorageValue(Storage.InServiceofYalahar.Questline) + 1) + player:setStorageValue(Storage.InServiceofYalahar.Mission02, player:getStorageValue(Storage.InServiceofYalahar.Mission02) + 1) -- StorageValue for Questlog "Mission 02: Watching the Watchmen" + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "pass")) then + npcHandler:say("You can {pass} either to the {Cemetery Quarter} or {Magician Quarter}. Which one will it be?", cid) + npcHandler.topic[cid] = 1 + elseif(msgcontains(msg, "cemetery")) then + if(npcHandler.topic[cid] == 1) then + local destination = Position(32799, 31103, 7) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "magician")) then + if(npcHandler.topic[cid] == 1) then + local destination = Position(32804, 31103, 7) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/rehon.lua b/data/npc/scripts/rehon.lua new file mode 100644 index 00000000000..169f2dec9c8 --- /dev/null +++ b/data/npc/scripts/rehon.lua @@ -0,0 +1,38 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, "mission") then + local player = Player(cid) + if player:getStorageValue(Storage.HiddenCityOfBeregar.RoyalRescue) == 4 and player:removeItem(14350, 1) then + player:setStorageValue(Storage.HiddenCityOfBeregar.RoyalRescue, 5) + npcHandler:say("By the Gods! You have the key to the cell! Thank you sooo much, mate. And now leave. I'll wait here until the air is clean and then I'm out of here.", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, "See you my friend.") +npcHandler:setMessage(MESSAGE_FAREWELL, "See you my friend.") +npcHandler:setMessage(MESSAGE_GREET, "Hello, my friend.") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/repenter.lua b/data/npc/scripts/repenter.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/repenter.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/richard.lua b/data/npc/scripts/richard.lua new file mode 100644 index 00000000000..eda8ca7525d --- /dev/null +++ b/data/npc/scripts/richard.lua @@ -0,0 +1,173 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + {text = "Don't forget to always have a rope with you! Buy one here, only the best quality!"}, + {text = "Don't complain to ME when you fell down a hole without a rope to get you out! You can buy one here now!"}, + {text = "Everything an adventurer needs!"}, + {text = "A rope is the adventurer's best friend!"}, + {text = "Fresh meat! Durable provisions! Ropes and shovels!"}, + {text = "Feeling like a bit of treasure-seeking? \z + Buy a shovel or a pick and investigate likely-looking stone piles and cracks!"} +} + +npcHandler:addModule(VoiceModule:new(voices)) + +-- NPC shop +local shopModule = ShopModule:new() +npcHandler:addModule(shopModule) +-- Buyable +-- Name, id, price, count/charges +shopModule:addBuyableItem({"backpack"}, 1988, 10, 1) +shopModule:addBuyableItem({"bag"}, 1987, 4, 1) +shopModule:addBuyableItem({"bread"}, 2689, 3, 1) +shopModule:addBuyableItem({"carrot"}, 2684, 1, 1) +shopModule:addBuyableItem({"cheese"}, 2696, 5, 1) +shopModule:addBuyableItem({"cherry"}, 2679, 1, 1) +shopModule:addBuyableItem({"egg"}, 2695, 1, 1) +shopModule:addBuyableItem({"fishing rod"}, 2580, 150, 1) +shopModule:addBuyableItem({"ham"}, 2671, 8, 1) +shopModule:addBuyableItem({"machete"}, 2420, 6, 1) +shopModule:addBuyableItem({"meat"}, 2666, 5, 1) +shopModule:addBuyableItem({"pick"}, 2553, 15, 1) +shopModule:addBuyableItem({"rope"}, 2120, 50, 1) +shopModule:addBuyableItem({"salmon"}, 2668, 2, 1) +shopModule:addBuyableItem({"scroll"}, 1949, 5, 1) +shopModule:addBuyableItem({"shovel"}, 2554, 10, 1) +shopModule:addBuyableItem({"torch"}, 2050, 2, 1) +shopModule:addBuyableItem({"worm"}, 3976, 1, 1) +-- Sellable +shopModule:addSellableItem({"cheese"}, 2696, 2, 1) +shopModule:addSellableItem({"fishing rod"}, 2580, 30, 1) +shopModule:addSellableItem({"meat"}, 2666, 2, 1) +shopModule:addSellableItem({"rope"}, 2120, 8, 1) +shopModule:addSellableItem({"shovel"}, 2554, 2, 1) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "job") then + npcHandler:say( + { + "I was a carpenter, back on Main. Wanted my own little shop. Didn't sit with the old man. \z + So I shipped to somewhere else. Terrible storm.", + "Woke up on this island. Had to eat squirrels before the adventurers found me and took me in. End of story." + }, + cid, false, true, 10) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "rope") then + npcHandler:say( + { + "Only the best quality, I assure you. A rope in need is a friend indeed! Imagine you stumble into a rat \z + hole without a rope - heh, your bones will be gnawed clean before someone finds ya!", + "Now, about that rope - ask me for equipment to see my wares. " + }, + cid, false, true, 10) + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'name'}, StdModule.say, + { + npcHandler = npcHandler, + text = "Richard. Just Richard. Lost my surname with my past in that storm. " + } +) +keywordHandler:addKeyword({'dawnport'}, StdModule.say, + { + npcHandler = npcHandler, + text = "This lovely island here. Once I didn't have to live off squirrels, it became quite enjoyable. \z + Nasty things though live underground, so take care where you tread and ALWAYS have a rope with you!" + } +) +keywordHandler:addKeyword({'rookgaard'}, StdModule.say, + { + npcHandler = npcHandler, + text = " Never been, mate. Heard it's kinda cute, though." + } +) +keywordHandler:addKeyword({'coltrayne'}, StdModule.say, + { + npcHandler = npcHandler, + text = "You know, I really don't want to poke into someone else's private life. \z + Suffice it to say that everyone has chapters of his life he doesn't want to mention. \z + Judging by Coltrayne's looks, we're looking at a trilogy here." + } +) +keywordHandler:addKeyword({'inigo'}, StdModule.say, + { + npcHandler = npcHandler, + text = "Old Inigo was the one who found me, actually, and brought me to the outpost. \z + I was half starved by then. He taught me how to make better traps and how to fish... I owe much to Inigo." + } +) +keywordHandler:addKeyword({'garamond'}, StdModule.say, + { + npcHandler = npcHandler, + text = "Can you believe how old he is? He won't say it, \z + but I wouldn't be surprised if he had been around for loooooong time." + } +) +keywordHandler:addKeyword({'squirrel'}, StdModule.say, + { + npcHandler = npcHandler, + text = "Don't talk to ME about squirrels! Had to live off them the first days, \z + when they were the only thing to go into my self-made acorn traps. Nasty." + } +) +keywordHandler:addKeyword({'mr morris'}, StdModule.say, + { + npcHandler = npcHandler, + text = "Don't know what to make of him. Great researcher in all Dawnport matters, though. \z + Always has a quest or two where he needs help, if you're looking for adventuring work." + } +) +keywordHandler:addKeyword({'oressa'}, StdModule.say, + { + npcHandler = npcHandler, + text = "Quiet little lady, her. Knows her way around the isle, looking for herbs and stuff \z + but mostly spends her time in the temple, helping younglings like you choose a vocation." + } +) +keywordHandler:addKeyword({'plunderpurse'}, StdModule.say, + { + npcHandler = npcHandler, + text = "You know, on the day that ol' pirate decides to make off with all that gold in the bank, \z + I'm gonna come with him. Should be much more fun landing on a strange island with some gold \z + to spend on booze and babes! " + } +) +keywordHandler:addKeyword({'hamish'}, StdModule.say, + { + npcHandler = npcHandler, + text = "Tries to act tough, but he's quite a witty and decent bloke who wouldn't hurt a fly. \z + We enjoy a good laugh together in the evenings." + } +) + +npcHandler:setMessage(MESSAGE_GREET, "Hello there, mate. Here for a {trade}? My stock's just been refilled.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Of course, just browse through my wares. \z + You can also have a look at food or {equipment} only.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Have fun!") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/riddler.lua b/data/npc/scripts/riddler.lua new file mode 100644 index 00000000000..b7c4d680213 --- /dev/null +++ b/data/npc/scripts/riddler.lua @@ -0,0 +1,125 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + local storage = Storage.Quest.TheParadoxTower + if msgcontains(msg, "test") then + npcHandler:say("Death awaits those who fail the test of the three seals! Do you really want me to test you?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 1 then + npcHandler:say("FOOL! Now you're doomed! But well ... \z + So be it! Let's start out with the Seal of Knowledge and the first question: \z + What name did the necromant king choose for himself?", cid) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, "goshnar") and npcHandler.topic[cid] == 2 then + npcHandler:say("HOHO! You have learned your lesson well. \z + Question number two then: Who or what is the feared Hugo?", cid) + npcHandler.topic[cid] = 3 + elseif msgcontains(msg, "demonbunny") and npcHandler.topic[cid] == 3 then + if player:getStorageValue(storage.TheFearedHugo) == 4 then + npcHandler:say("HOHO! Right again. All right. The final question of the first seal: Who was the first warrior to follow the path of the Mooh'Tah?", cid) + npcHandler.topic[cid] = 4 + else + npcHandler:say("Hmmm, so you think cheating will get you through that test? Then your final question of the first seal is: What is the meaning of life?", cid) + npcHandler.topic[cid] = 5 + end + elseif msgcontains(msg, "tha'kull") and npcHandler.topic[cid] == 4 then + npcHandler:say("HOHO! Lucky you. You have passed the first seal! So ... would you like to continue with the Seal of the Mind?", cid) + npcHandler.topic[cid] = 6 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 6 then + npcHandler:say("As you wish, foolish one! Here is my first question: It's lighter then a feather but no living creature can hold it for ten minutes?", cid) + npcHandler.topic[cid] = 7 + elseif msgcontains(msg, "breath") and npcHandler.topic[cid] == 7 then + npcHandler:say("That was an easy one. Let's try the second: If you name it, you break it.", cid) + npcHandler.topic[cid] = 8 + elseif msgcontains(msg, "silence") and npcHandler.topic[cid] == 8 then + npcHandler:say("Hm. I bet you think you're smart. All right. \z + How about this: What does everybody want to become but nobody to be?", cid) + npcHandler.topic[cid] = 9 + elseif msgcontains(msg, "old") and npcHandler.topic[cid] == 9 then + npcHandler:say("ARGH! You did it again! Well all right. Do you wish to break the Seal of Madness?", cid) + npcHandler.topic[cid] = 10 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 10 then + npcHandler:say("GOOD! So I will get you at last. Answer this: What is your favourite colour?", cid) + npcHandler.topic[cid] = 11 + elseif msgcontains(msg, "green") and npcHandler.topic[cid] == 11 then + if player:getStorageValue(storage.FavoriteColour) < 1 then + player:setStorageValue(storage.FavoriteColour, 1) + end + npcHandler:say("UHM UH OH ... How could you guess that? Are you mad??? All right. \z + Penultimate question: What is the opposite?", cid) + npcHandler.topic[cid] = 12 + elseif msgcontains(msg, "none") and npcHandler.topic[cid] == 12 then + npcHandler:say("NO! NO! NO! That can't be true. You're not only mad, you are a complete idiot! \z + Ah well. Here is the last question: What is 1 plus 1?", cid) + npcHandler.topic[cid] = 13 + elseif msgcontains(msg, "1") then + if npcHandler.topic[cid] == 13 then + if player:getStorageValue(storage.Mathemagics) >= 1 then + -- Complete mission mathemagics + if player:getStorageValue(storage.Mathemagics) == 1 then + player:setStorageValue(storage.Mathemagics, 2) + end + -- Complete mission favorite colour + if player:getStorageValue(storage.FavoriteColour) == 1 then + player:setStorageValue(storage.FavoriteColour, 2) + end + + player:teleportTo({x = 32478, y = 31905, z = 1}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + npcHandler:say("DAMN YOUUUUUUUUUUUUUUUUUUUUUU!", cid) + else + npcHandler:say("WRONG!", cid) + player:teleportTo({x = 32725, y = 31589, z = 12}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + elseif npcHandler.topic[cid] == 5 then + npcHandler:say("WRONG! Next time get your own answers. To hell with thee, cheater Sischfried!", cid) + player:teleportTo({x = 32725, y = 31589, z = 12}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + npcHandler:say("WRONG!", cid) + player:teleportTo({x = 32725, y = 31589, z = 12}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +keywordHandler:addKeyword({"paradox"}, StdModule.say, {npcHandler = npcHandler, text = "This tower, of course, silly one. It holds my {master'}s {treasure}."}) +keywordHandler:addAliasKeyword({"tower"}) + +keywordHandler:addKeyword({"master"}, StdModule.say, {npcHandler = npcHandler, text = "His name is none of your business"}) +keywordHandler:addKeyword({"treasure"}, StdModule.say, {npcHandler = npcHandler, text = "I am guarding the treasures of the tower. Only those who pass the {test} of the three sigils may pass."}) +keywordHandler:addKeyword({"name"}, StdModule.say, {npcHandler = npcHandler, text = "I am known as the riddler. That is all you need to know."}) +keywordHandler:addKeyword({"job"}, StdModule.say, {npcHandler = npcHandler, text = "I am the guardian of the paradox tower."}) +keywordHandler:addKeyword({"key"}, StdModule.say, {npcHandler = npcHandler, text = "The key of this tower! You will never find it! A malicious plant spirit is guarding it!."}) +keywordHandler:addAliasKeyword({"door"}) + +npcHandler:setMessage(MESSAGE_GREET, "|PLAYERNAME| HEHEHEHE! Another fool visits the {tower}! Excellent!") +npcHandler:setMessage(MESSAGE_FAREWELL, "HEHEHE! I knew you don't have the stomach.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "COWARD! CHICKEN! HEHEHEHE!") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/robert.lua b/data/npc/scripts/robert.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/robert.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/robin.lua b/data/npc/scripts/robin.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/robin.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/robson.lua b/data/npc/scripts/robson.lua new file mode 100644 index 00000000000..8ac4fa597eb --- /dev/null +++ b/data/npc/scripts/robson.lua @@ -0,0 +1,73 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = '' }, + { text = 'Just great. Getting stranded on a remote underground isle was not that bad but now I\'m becoming a tourist attraction!' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, 'parcel') then + npcHandler:say('Do you want to buy a parcel for 15 gold?', cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, 'label') then + npcHandler:say('Do you want to buy a label for 1 gold?', cid) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, 'yes') then + local player = Player(cid) + if npcHandler.topic[cid] == 1 then + if not player:removeMoneyNpc(15) then + npcHandler:say('Sorry, that\'s only dust in your purse.', cid) + npcHandler.topic[cid] = 0 + return true + end + + player:addItem(2595, 1) + npcHandler:say('Fine.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + if not player:removeMoneyNpc(1) then + npcHandler:say('Sorry, that\'s only dust in your purse.', cid) + npcHandler.topic[cid] = 0 + return true + end + + player:addItem(2599, 1) + npcHandler:say('Fine.', cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'no') then + if isInArray({1, 2}, npcHandler.topic[cid]) then + npcHandler:say('I knew I would be stuck with that stuff.', cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Hrmpf, I'd say welcome if I felt like lying.") +npcHandler:setMessage(MESSAGE_FAREWELL, "See you next time!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "No patience at all!") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/rock_in_a_hard_place.lua b/data/npc/scripts/rock_in_a_hard_place.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/rock_in_a_hard_place.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/rock_steady.lua b/data/npc/scripts/rock_steady.lua new file mode 100644 index 00000000000..15a5481abcd --- /dev/null +++ b/data/npc/scripts/rock_steady.lua @@ -0,0 +1,72 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, "addon") or msgcontains(msg, "help") then + if player:getStorageValue(72326) < 1 then + selfSay("If you want anything, you should talk to Old Rock Boy over there. I do {collect} stuff, though. So just ask if you're interested in helping me.", cid) + player:setStorageValue(72326, 1) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "collect") then + if player:getStorageValue(72326) == 1 then + selfSay("I collect everything that reflects light in strange ways. However, I am bored by my collection. And there wasn't anything new to add for years. ...", cid) + selfSay("I like pearls for example - but I have already enough. I also like shells - but I can't even count how many I already own. ...", cid) + npcHandler:say("If you find anything of REAL VALUE - bring it to me. I will reward you well. You don't already have something for me by chance?", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(72326) == 2 then + selfSay("Have you got anything for me today?", cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(72326) == 3 then + selfSay("Have you got anything for me today?", cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(72326) == 4 and player:removeItem(15434, 1) then + selfSay("Have you got anything... what? You want what? A reward? HAHAHAHAAAA!! ...", cid) + selfSay("No I'm just teasing you. I'm really happy about my collection now. ...", cid) + npcHandler:say("Well, I found some kind of weapon a long time ago. I believe it may be especially helpful underwater as it is from the deep folk. In any case it is of more use for you than it would be for me.", cid) + player:addOutfitAddon(464, 1) + player:addOutfitAddon(463, 1) + player:setStorageValue(72326, 5) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + selfSay("Great! Let me see. Amazing! I will take this, thank you!", cid) + player:setStorageValue(72326, 2) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 and player:removeItem(15435, 1) then + selfSay("Great! Let me see. Amazing! I will take this, thank you!", cid) + player:setStorageValue(72326, 3) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 and player:removeItem(15436, 1) then + selfSay("Great! Let me see. Amazing! I will take this, thank you!", cid) + player:setStorageValue(72326, 4) + npcHandler.topic[cid] = 0 + else selfSay("You dont have the required items!", cid) + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/rock_with_a_soft_spot.lua b/data/npc/scripts/rock_with_a_soft_spot.lua new file mode 100644 index 00000000000..f54338ab39d --- /dev/null +++ b/data/npc/scripts/rock_with_a_soft_spot.lua @@ -0,0 +1,95 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Twist of Fate +local blessKeyword = keywordHandler:addKeyword({'twist of fate'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'This is a special blessing I can bestow upon you once you have obtained at least one of the other blessings and which functions a bit differently. ...', + 'It only works when you\'re killed by other adventurers, which means that at least half of the damage leading to your death was caused by others, not by monsters or the environment. ...', + 'The {twist of fate} will not reduce the death penalty like the other blessings, but instead prevent you from losing your other blessings as well as the amulet of loss, should you wear one. It costs the same as the other blessings. ...', + 'Would you like to receive that protection for a sacrifice of |PVPBLESSCOST| gold, child?' + }}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the protection of the twist of fate, pilgrim.', cost = '|PVPBLESSCOST|', bless = 6}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Adventurer Stone +keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Keep your adventurer\'s stone well.'}, function(player) return player:getItemById(18559, true) end) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for free?'}, function(player) return player:getStorageValue(Storage.AdventurersGuild.FreeStone.RockWithASoftSpot) ~= 1 end) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, nil, function(player) player:addItem(18559, 1) player:setStorageValue(Storage.AdventurersGuild.FreeStone.RockWithASoftSpot, 1) end) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for 30 gold?'}) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, + function(player) return player:getMoney() + player:getBankBalance() >= 30 end, + function(player) if player:removeMoneyNpc(30) then player:addItem(18559, 1) end end + ) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, you don\'t have enough money.', reset = true}) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.'}, function(player) return player:hasBlessing(2) end) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin will provide you with the embrace of Tibia.'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, this is the {Gray Beach temple}, |PLAYERNAME|. Whether you are wounded, poisoned - or wait, don\'t tell me - yes, this is probably a case of being more emotionally hurt, I will do my best to {heal} you.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Only the best for you.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Goodbye then, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/roderick.lua b/data/npc/scripts/roderick.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/roderick.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/rodney.lua b/data/npc/scripts/rodney.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/rodney.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/roger_the_worker.lua b/data/npc/scripts/roger_the_worker.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/roger_the_worker.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/romella.lua b/data/npc/scripts/romella.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/romella.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/romir.lua b/data/npc/scripts/romir.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/romir.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/rose.lua b/data/npc/scripts/rose.lua new file mode 100644 index 00000000000..2a885713a30 --- /dev/null +++ b/data/npc/scripts/rose.lua @@ -0,0 +1,48 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if(not npcHandler:isFocused(cid)) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "Hydra Tongue") then + npcHandler:say("Do you want to buy a Hydra Tongue for 100 gold?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + if player:getMoney() + player:getBankBalance() >= 100 then + player:removeMoneyNpc(100) + npcHandler:say("Here you are. A Hydra Tongue!", cid) + player:addItem(7250, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have enough money.", cid) + end + end + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Then not.", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/rosemarie.lua b/data/npc/scripts/rosemarie.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/rosemarie.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ross.lua b/data/npc/scripts/ross.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/ross.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/roswitha.lua b/data/npc/scripts/roswitha.lua new file mode 100644 index 00000000000..d7d8ac62b16 --- /dev/null +++ b/data/npc/scripts/roswitha.lua @@ -0,0 +1,37 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function creatureSayCallback(cid, type, msg) + if(not(npcHandler:isFocused(cid))) then + return false + end + + local player = Player(cid) + if(msgcontains(msg, "Harsin")) then + if(player:getStorageValue(Storage.DarkTrails.Mission13) == 1) then + npcHandler:say("I'm sorry, but Harsin no longer lives here. He ordered a local named Quandon to transport all his stuff somewhere. I don't know where he moved, but Quandon should be able to help you with this information.", cid) + player:setStorageValue(Storage.DarkTrails.Mission14, 1) + player:setStorageValue(Storage.DarkTrails.DoorQuandon, 1) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/rotem_valos.lua b/data/npc/scripts/rotem_valos.lua new file mode 100644 index 00000000000..de40643d444 --- /dev/null +++ b/data/npc/scripts/rotem_valos.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = ' The world has grown complicated since my youth.'} } +npcHandler:addModule(VoiceModule:new(voices)) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/rottin_wood.lua b/data/npc/scripts/rottin_wood.lua new file mode 100644 index 00000000000..c7d572bf7e7 --- /dev/null +++ b/data/npc/scripts/rottin_wood.lua @@ -0,0 +1,141 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function creatureSayCallback(cid, type, msg) + if(not npcHandler:isFocused(cid)) then + return false + end + + + if(msgcontains(msg, "mission") or msgcontains(msg, "task")) then + if(getPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Mission03) < 1) and getPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Time) <= os.time() then + npcHandler:say("Oh, you want some work? You can help us, alright. Did you know that the people of the city think those rabbit feet are actually lucky charms?", cid) + npcHandler.topic[cid] = 1 + elseif(getPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Mission03) == 1) then + npcHandler:say("Good to see you back. Now, did you bring us the lucky charms?", cid) + npcHandler.topic[cid] = 3 + + + elseif getPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Time) > os.time() then + npcHandler:say("You need wait some hours to take other mission again or you are still on a mission.", cid) + + ------------------------ FINISH MISSION 01 ------------------------ + elseif(getPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Mission03) == 2) then + selfSay("Of course, of course, there is indeed something you can help us with. Remember that we also have some tasks for you. So, are you ready for another quest to help the men of the forest?", cid) + selfSay("There is a problem with one of our deer stands. Right. Well, there are two problems, our deer stands - and some of the walls of the buildings in the camp are broken. ...", cid) + selfSay("You know, the guys built all of that themselves. Sure, at first it didn't quite work out as we planned and in the end we had to tear down half the forest - but - it was worth it. ...", cid) + selfSay("Still, most of the camp is kind of... broken now. And someone with a good hammer and a steady hand needs to fix that. Or I am afraid we will have to freeze... during the cold evenings... well you know, hard times. ...", cid) + npcHandler:say("So what do you say, in for this one?", cid) + npcHandler.topic[cid] = 4 + elseif(getPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Mission03) == 3) and getPlayerStorageValue(cid, Storage.RottinWoodAndMaried.RottinStart) > 4 then + npcHandler:say("Ah there you are. So, did you repair all the broken structures?", cid) + npcHandler.topic[cid] = 5 + ------------------------ FINISH MISSION 02 ------------------------ + elseif(getPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Mission03) == 4) then + selfSay("Oh my good friend, good to see you! Today you will help us with a very important task. Very important indeed. ...", cid) + selfSay("You know, a large group of merchants is travelling from Thais to Venore and they are crossing the forest to shorten their way - can you believe it? ...", cid) + npcHandler:say("They will enter the forest near our camp which is where you come in - uhm I mean you do want to help us with this, right?", cid) + npcHandler.topic[cid] = 6 + elseif(getPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Mission03) == 5) and getPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Corpse) == 4 then + npcHandler:say("You did it!! And I assume you took only what you needed? Heh. No, I know it. Because my men took the rest. Thanks for helping us, you did a very good job. In fact I have a little 'extra' for you here, thanks again.", cid) + ------------------ RESET STORAGE -------------------- + setPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Mission03, - 1) -- reset storage + setPlayerStorageValue(cid, Storage.RottinWoodAndMaried.RottinStart, - 1) -- reset storage + setPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Trap, - 1) -- reset storage + setPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Corpse, - 1) -- reset storage + ----------------------------------------------------- + setPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Time, os.time() + 20 * 60 * 60) -- set time to start mission again + setPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Questline, 2) -- quest log + ------------------- ITEM RANDOM -------------------- + items = { + [0] = {id = 2152, count = 3, chance = 100}, + [1] = {id = 2169, count = 1, chance = 80}, + [2] = {id = 13247, count = 1, chance = 25}, + } + for i = 0, #items do + if (items[i].chance > math.random(1, 100)) then + doPlayerAddItem(cid, items[i].id, items[i].count) + ---------------------------------------------------- + npcHandler.topic[cid] = 0 + end + end + end + ------------------------ FINISH MISSION 03 ------------------------ + elseif(msgcontains(msg, "yes")) then + if(npcHandler.topic[cid] == 1) then + npcHandler:say("Good, because that is exactly what you will help us with - getting more 'lucky charms'. If we won't get our hands on new charms in time, we will surely have to starve... during the autumn. That would be a hard time for all of us. So... you in?", cid) + npcHandler.topic[cid] = 2 + elseif(npcHandler.topic[cid] == 2) then + selfSay("Fine, now hurry into the woods and find some rabbits. Find them and kill them that is. Use a sharp, thin knife to get the rabbit foot and be careful not to destroy it - no one would buy it in a bad condition after all. ...", cid) + selfSay("Once you gathered some rabbit feet, put one of our - handcrafted by the guys - ribbons on each of them. That will make two lucky charms per rabbit. ...", cid) + selfSay("We will need at least seven. And seven is a lucky number, don't you think? Heh. ...", cid) + npcHandler:say("If you need some more ribbons just come back to me and ask.", cid) + setPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Mission03, 1) + setPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Questline, 1) -- quest log + doPlayerAddItem(cid, 13158, 7) + npcHandler.topic[cid] = 0 + elseif(npcHandler.topic[cid] == 3) and getPlayerItemCount(cid, 13160) >= 7 then + npcHandler:say("Good hunt. That will be enough to help us uhm... get through the winter yes. Now if you want to help us getting even more lucky charms, you can always ask.", cid) + doPlayerRemoveItem(cid, 13160, 7) + setPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Mission03, 2) + setPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Questline, 4) -- quest log + npcHandler.topic[cid] = 0 + + elseif(npcHandler.topic[cid] == 3) and getPlayerItemCount(cid, 13160) <= 6 then + npcHandler:say("You do not have sufficient rabbit's foot.", cid) + + ------------------------ FINISH MISSION 01 ------------------------ + elseif(npcHandler.topic[cid] == 4) then + npcHandler:say("Good, good. Do you remember the old saying? If it ain't broken, it was not made by us. Now, off you go!", cid) + setPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Mission03, 3) + setPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Questline, 3) -- quest log + npcHandler.topic[cid] = 0 + elseif(npcHandler.topic[cid] == 5) then + selfSay("Mmmmh, I have to say - good workmanship. No doubt. Yes, the person who made that tool you used to fix all this was a pure professional. Something I can't say about your work, though. ...", cid) + npcHandler:say("The walls look as if they will come off in a matter of hours. Oh well, you can always come back and repair this mess, ask me for a task if you want to. Yeah, yeah and here's your reward for today.", cid) + setPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Mission03, 4) + setPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Questline, 6) -- quest log + doPlayerAddItem(cid, 2152, 5) + npcHandler.topic[cid] = 0 + ------------------------ FINISH MISSION 02 ------------------------ + elseif(npcHandler.topic[cid] == 6) then + selfSay("Right, now before the merchants enter the woods, you will install several traps - nothing too dangerous, just nets and ropes. ...", cid) + selfSay("When they enter said area which is located close to our hidden camp, they will be trapped and you can... lighten their heavy burden of valuable goods. ...", cid) + selfSay("There is but a tiny little catch - we cannot help you laying these traps. You know, some of the guys became sick recently, we talk about several broken legs here, one almost lost his arm ...", cid) + npcHandler:say("So... it's entirely up to you, will you do this or not?", cid) + npcHandler.topic[cid] = 7 + elseif(npcHandler.topic[cid] == 7) then + selfSay("Alright very good. Now the only thing you need to do is taking these traps and moving out to the area I have marked on your map where you need to place them. ...", cid) + selfSay("Once you did that go to the large high seat near the camp and watch for the travelling merchants. ...", cid) + selfSay("Once all of them are trapped in the nets, you can go down and gather anything of value you can find. But only take what we... you really need - around 100 gold should be enough for any man to take. ...", cid) + selfSay("We have manners after all, haven't we. ...", cid) + selfSay("My men will take their share of course and... help you relieve the merchants of any valuables. ...", cid) + selfSay("You're done if you get at least... let's say 5 of these fools. Return to me and you will be rewarded. ...", cid) + npcHandler:say("Off you go and - good hunt, heh.", cid) + doPlayerAddItem(cid, 13173, 5) + setPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Mission03, 5) + setPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Questline, 5) -- quest log + npcHandler.topic[cid] = 0 + ------------------------ FINISH MISSION 03 ------------------------ + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/roughington.lua b/data/npc/scripts/roughington.lua new file mode 100644 index 00000000000..e88e935b7eb --- /dev/null +++ b/data/npc/scripts/roughington.lua @@ -0,0 +1,20 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/rowenna.lua b/data/npc/scripts/rowenna.lua new file mode 100644 index 00000000000..64c5cef31c0 --- /dev/null +++ b/data/npc/scripts/rowenna.lua @@ -0,0 +1,25 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Selling and buying fine weapons!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome to the finest weaponshop in the land, |PLAYERNAME|! Tell me if you're looking for a good {trade}.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye. Come back soon.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye. Come back soon.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Of course, just browse through my wares.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/rudolph.lua b/data/npc/scripts/rudolph.lua new file mode 100644 index 00000000000..8be853e1daf --- /dev/null +++ b/data/npc/scripts/rudolph.lua @@ -0,0 +1,23 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:setMessage(MESSAGE_GREET, "Oh, a customer. Hello |PLAYERNAME|. If you'd like to see my wonderful self-tailored clothes, ask me for a {trade}.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Oh, good bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Oh, good bye.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Of course, just browse through my wares.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/runtel_blackspark.lua b/data/npc/scripts/runtel_blackspark.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/runtel_blackspark.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ruprecht.lua b/data/npc/scripts/ruprecht.lua new file mode 100644 index 00000000000..2b14abd6c92 --- /dev/null +++ b/data/npc/scripts/ruprecht.lua @@ -0,0 +1,124 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local storeTable = {} +local itemsTable = { + ["gingerbreadman"] = {itemId = 6501, count = 1}, + ["christmas cookie tray"] = {itemId = 22644, count = 1}, + ["gingerbread recipe"] = {itemId = 6523, count = 10}, + ["jewel case"] = {itemId = 8261, count = 25}, + ["santa hat"] = {itemId = 6531, count = 50}, + ["santa backpack"] = {itemId = 11263, count = 75}, + ["snow flake tapestry"] = {itemId = 22649, count = 75}, + ["santa doll"] = {itemId = 6512, count = 100}, + ["snowman doll"] = {itemId = 11256, count = 150}, + ["snow globe"] = {itemId = 22645, count = 150}, + ["frazzlemaw santa"] = {itemId = 22642, count = 250}, + ["leaf golem santa"] = {itemId = 22643, count = 250}, + ["santa music box"] = {itemId = 22647, count = 250}, + ["santa teddy"] = {itemId = 11255, count = 500}, + ["maxxen santa"] = {itemId = 24321, count = 250}, + ["present bag"] = {itemId = 6497, count = 1}, + ["ferumbras' teddy santa"] = {itemId = 25535, count = 250}, + ["nightmare beast santa"] = {itemId = 34585, count = 250}, + ["orclops santa"] = {itemId = 27062, count = 250}, + ["raccoon santa"] = {itemId = 40527, count = 250}, + ["santa fox"] = {itemId = 30826, count = 250}, + ["santa leech"] = {itemId = 37581, count = 250} +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + + if (msgcontains(msg, "offers")) then + local text = "I have these offers: " + for i, v in pairs(itemsTable) do + text = text.. "{" ..i.. "}, " + end + npcHandler:say(text, cid) + end + + if npcHandler.topic[cid] == 0 then + local table = itemsTable[msg] + if table then + if (table.itemId ~= 6497) then + npcHandler:say("So you want to exchange "..msg..", for ".. table.count .." christmas tokens?", cid) + storeTable[cid] = msg + npcHandler.topic[cid] = 1 + else + npcHandler:say("So you want to exchange ".. msg .." to "..table.count.." christmas token(s)?", cid) + storeTable[cid] = 6527 + npcHandler.topic[cid] = 1 + end + end + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, "yes") then + if (tonumber(storeTable[cid]) == 6527) then + if (player:removeItem(6497, 1)) then + npcHandler:say("Thank you, here is your 1 christmas token.", cid) + player:addItem(6527, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have a present bag.", cid) + npcHandler.topic[cid] = 0 + end + return false + end + if player:removeItem(6527, itemsTable[storeTable[cid]].count) then + npcHandler:say("Thank you, here is your "..storeTable[cid]..".", cid) + player:addItem(itemsTable[storeTable[cid]].itemId, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have enough of tokens.", cid) + npcHandler.topic[cid] = 0 + end + end + elseif npcHandler.topic[cid] > 0 then + if msgcontains(msg, "no") then + npcHandler:say("Come back when you are ready to trade some tokens!", cid) + end + end + if msgcontains(msg, "santa claus") then + npcHandler:say({ + "Well, he does not really like it if someone tells his story ... but I do! A long, long time ago Santa was nothing but a greedy little dwarf. A real miser, I tell ya ...", + "He was greedy even by dwarven standards. He would never share anything or give away the cheapest thing in his possession ...", + "One day a woman came to his house and asked him for a cup of water ...", + "Of course he refused. He even mocked her for being so naive. But what he did not know was that this woman was some kind of mighty faery or perhaps a goddess in disguise ...", + "Be it as it may, the woman cursed old Santa, forcing him to share his fortune with everyone he met ...", + "Santa was horrified. Of course, he could not bear the thought of sharing anything at all. So he went into hiding ...", + "He hid in the most remote places in the world, but time and again someone found him out, and the curse made him share his wealth ...", + "And know something? Old Santa actually came to like it! He saw the joy his presents brought, and this opened his old stony heart ...", + "And he learned that this way his fortune gave him more joy and pleasure than it ever did when he locked it away. ...", + "Over the years he turned it into a game. He hid somewhere to reward those who found him ...", + "But once every year, on a very special day which happens to be his curse's anniversary, he goes out and brings presents to the people, and especially to the children ...", + "Well, that is his story ... Nah, that's not a tear in my eye. It's just the wind, you know." + }, cid) + end + return true +end + +local function onReleaseFocus(cid) + storeTable[cid] = nil +end + +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/saideh.lua b/data/npc/scripts/saideh.lua new file mode 100644 index 00000000000..c7413c98094 --- /dev/null +++ b/data/npc/scripts/saideh.lua @@ -0,0 +1,59 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local playerTopic = {} +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.Kilmaresh.First.Access) < 1 then + npcHandler:setMessage(MESSAGE_GREET, "Hello, my name is Saideh. Once this was the entry to the crypt of our heroes. One of the graves belongs to our beloved hero Dayyan. Nowadays it is not a good idea to visit this place.") + playerTopic[cid] = 1 + end + npcHandler:addFocus(cid) + return true +end + +local function creatureSayCallback(cid, type, msg) +if not npcHandler:isFocused(cid) then + return false +end +npcHandler.topic[cid] = playerTopic[cid] +local player = Player(cid) +if msgcontains(msg, "mission") and player:getStorageValue(Storage.Kilmaresh.Fourteen.Remains) == 1 then + if player:getStorageValue(Storage.Kilmaresh.Fourteen.Remains) == 1 then + npcHandler:say({" I would like you to visit the grave of our beloved hero Dayyan. His remains have to be reburied, because a horde of ogres controls this place. Do you want to start this holy mission?"}, cid) + npcHandler.topic[cid] = 1 + playerTopic[cid] = 1 + end +elseif msgcontains(msg, "yes") and playerTopic[cid] == 1 and player:getStorageValue(Storage.Kilmaresh.Fourteen.Remains) == 1 then + if player:getStorageValue(Storage.Kilmaresh.Fourteen.Remains) == 1 then + npcHandler:say({"Well, I appreciate that. Good luck!"}, cid) + player:setStorageValue(Storage.Kilmaresh.Fourteen.Remains, 2) + npcHandler.topic[cid] = 2 + playerTopic[cid] = 2 + else + npcHandler:say({"Sorry."}, cid) + end +end +return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/salbra.lua b/data/npc/scripts/salbra.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/salbra.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/sam.lua b/data/npc/scripts/sam.lua new file mode 100644 index 00000000000..a3ffb6cfb2e --- /dev/null +++ b/data/npc/scripts/sam.lua @@ -0,0 +1,127 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Hello there, adventurer! Need a deal in weapons or armor? I\'m your man!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'adorn') + or msgcontains(msg, 'outfit') + or msgcontains(msg, 'addon') then + local addonProgress = player:getStorageValue(Storage.OutfitQuest.Knight.AddonHelmet) + if addonProgress == 5 then + player:setStorageValue(Storage.OutfitQuest.Knight.MissionHelmet, 6) + player:setStorageValue(Storage.OutfitQuest.Knight.AddonHelmet, 6) + player:setStorageValue(Storage.OutfitQuest.Knight.AddonHelmetTimer, os.time() + 7200) + npcHandler:say('Oh, Gregor sent you? I see. It will be my pleasure to adorn your helmet. Please give me some time to finish it.', cid) + elseif addonProgress == 6 then + if player:getStorageValue(Storage.OutfitQuest.Knight.AddonHelmetTimer) < os.time() then + player:setStorageValue(Storage.OutfitQuest.Knight.MissionHelmet, 0) + player:setStorageValue(Storage.OutfitQuest.Knight.AddonHelmet, 7) + player:setStorageValue(Storage.OutfitQuest.Ref, math.min(0, player:getStorageValue(Storage.OutfitQuest.Ref) - 1)) + player:addOutfitAddon(131, 2) + player:addOutfitAddon(139, 2) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + npcHandler:say('Just in time, |PLAYERNAME|. Your helmet is finished, I hope you like it.', cid) + else + npcHandler:say('Please have some patience, |PLAYERNAME|. Forging is hard work!', cid) + end + elseif addonProgress == 7 then + npcHandler:say('I think it\'s one of my masterpieces.', cid) + else + npcHandler:say('Sorry, but without the permission of Gregor I cannot help you with this matter.', cid) + end + + elseif msgcontains(msg, "old backpack") or msgcontains(msg, "backpack") then + if player:getStorageValue(Storage.SamsOldBackpack) < 1 then + npcHandler:say("What? Are you telling me you found my old adventurer's backpack that I lost years ago??", cid) + npcHandler.topic[cid] = 1 + end + + elseif msgcontains(msg, '2000 steel shields') then + if player:getStorageValue(Storage.WhatAFoolish.Questline) ~= 29 + or player:getStorageValue(Storage.WhatAFoolish.Contract) == 2 then + npcHandler:say('My offers are weapons, armors, helmets, legs, and shields. If you\'d like to see my offers, ask me for a {trade}.', cid) + return true + end + + npcHandler:say('What? You want to buy 2000 steel shields??', cid) + npcHandler.topic[cid] = 2 + + elseif msgcontains(msg, 'contract') then + if player:getStorageValue(Storage.WhatAFoolish.Contract) == 0 then + npcHandler:say('Have you signed the contract?', cid) + npcHandler.topic[cid] = 4 + end + + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + if player:removeItem(3960, 1) then + npcHandler:say({ + "Thank you very much! This brings back good old memories! Please, as a reward, travel to Kazordoon and ask my old friend Kroox to provide you a special dwarven armor. ...", + "I will mail him about you immediately. Just tell him, his old buddy Sam is sending you." + }, cid) + player:setStorageValue(Storage.SamsOldBackpack, 1) + player:addAchievement('Backpack Tourist') + else + npcHandler:say("You don't have it...", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say('I can\'t believe it. Finally I will be rich! I could move to Edron and enjoy my retirement! But ... wait a minute! I will not start working without a contract! Are you willing to sign one?', cid) + npcHandler.topic[cid] = 3 + elseif npcHandler.topic[cid] == 3 then + player:addItem(7492, 1) + player:setStorageValue(Storage.WhatAFoolish.Contract, 1) + npcHandler:say('Fine! Here is the contract. Please sign it. Talk to me about it again when you\'re done.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 4 then + if not player:removeItem(7491, 1) then + npcHandler:say('You don\'t have a signed contract.', cid) + npcHandler.topic[cid] = 0 + return true + end + + player:setStorageValue(Storage.WhatAFoolish.Contract, 2) + npcHandler:say('Excellent! I will start working right away! Now that I am going to be rich, I will take the opportunity to tell some people what I REALLY think about them!', cid) + npcHandler.topic[cid] = 0 + end + + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Then no.", cid) + elseif isInArray({2, 3, 4}, npcHandler.topic[cid]) then + npcHandler:say("This deal sounded too good to be true anyway.", cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am the blacksmith. If you need weapons or armor - just ask me."}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome to my shop, adventurer |PLAYERNAME|! I {trade} with weapons and armor.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye and come again, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye and come again.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/samir.lua b/data/npc/scripts/samir.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/samir.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/sandomo.lua b/data/npc/scripts/sandomo.lua new file mode 100644 index 00000000000..12c6f637187 --- /dev/null +++ b/data/npc/scripts/sandomo.lua @@ -0,0 +1,142 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function Player.getInquisitionGold(self) + local v = { + math.max(0, self:getStorageValue(ROSHAMUUL_MORTAR_THROWN))*100, + math.max(0, self:getStorageValue(ROSHAMUUL_KILLED_FRAZZLEMAWS)), + math.max(0, self:getStorageValue(ROSHAMUUL_KILLED_SILENCERS)) + } + return v[1] + v[2] + v[3] +end + +local function creatureSayCallback(cid, type, msg) + local player = Player(cid) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, "mission") then + npcHandler:say({ + "First, you will help us rebuilding this wretched {bridge} we cannot cross. We need mortar and there are several types of monsters who try to keep us away from it. ...", + "Then there is this enormous wall in the distance. Once we crossed the bridge, we will have to breach this monument. As I see it, you are working for the Inquisition now, I will hear no objection. You may even earn our gratitude." + }, cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "bridge") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "Our brother Mortis is constantly working on keeping the bridge intact. We tried some simple wood planks first but it didn't work out that... well. ...", + "What we need is enough {mortar} to actually build a durable traverse. And we will need even more mortar to maintain it as it constantly gets attacked by vile critters." + }, cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, "mortar") then + if npcHandler.topic[cid] == 2 then + npcHandler:say({ + "We scouted some caves beneath the island which hold plenty of chalk to mix some good mortar. The entrances are not very far from here in fact. ...", + "However, the entrances are somewhat... twisted. The entrance we had mapped to a certain cave one day, would lead to a completely different cave on the next. ...", + "And even when emerging from one of the caves you never know where you are since its exits are just as deceptive. ...", + "Once you gathered some chalk, you should also find gravel on the island. If you have a pick and a bucket, you should be able to collect enough fine gravel to mix some mortar. ...", + "Do not forget to bring some buckets, if you are in short supply, brother Maun will hand some out to you - for a fee of course." + }, cid) + npcHandler.topic[cid] = nil + end + end + + if msgcontains(msg, "gratitude") then + npcHandler.topic[cid] = 3 + npcHandler:say("Oh, so you want a reward, hm? Well... let's see. What did you do for us - helping Mortis with his {repairs} and defended him?", cid) + elseif msgcontains(msg, "repairs") then + if npcHandler.topic[cid] == 3 then + if player:getInquisitionGold() > 0 then + npcHandler.topic[cid] = 4 + npcHandler:say({ + "Alright, so you mixed and delivered ".. math.max(0, player:getStorageValue(ROSHAMUUL_MORTAR_THROWN)) .." mortar and ...", + "You killed ".. math.max(0, player:getStorageValue(ROSHAMUUL_KILLED_FRAZZLEMAWS)) .." frazzlemaws and ...", + "You also hunted ".. math.max(0, player:getStorageValue(ROSHAMUUL_KILLED_SILENCERS)) .." silencers. That would equal ".. player:getInquisitionGold() .." of inquisition gold - BUT we are currently short of this valuable metal so... do you want me to add this amount to my {books} for now or {trade} it for something else.", + }, cid) + else + npcHandler.topic[cid] = nil + npcHandler:say("Come back after you have done at least one of the tasks I talked you about.", cid) + end + end + elseif npcHandler.topic[cid] == 4 then + local v = math.max(0, player:getStorageValue(ROSHAMUUL_GOLD_RECORD)) + if msgcontains(msg, "book") or msgcontains(msg, "books") then + npcHandler.topic[cid] = 5 + npcHandler:say({ + "Of course, let's see. Hm, your recent endeavours would earn you ".. player:getInquisitionGold() .." of righteous inquisition gold. You have earned ".. v .." of gold in total. ...", + "Do you want me to add this amount to my books? This will reset your current records, too, however - so?", + }, cid) + end + elseif npcHandler.topic[cid] == 5 then + if msgcontains(msg, "yes") then + npcHandler:say({ + "Good. Registered as... ".. player:getName() .."... with... about ".. player:getInquisitionGold() .." of righteously earned inquisition gold added. There. Thanks for your help! ..", + "Good. Ask me any time in case you want to know your current {record}. If you have time, Remember you can also {trade} your earnings into some of these... probably far more valuable, ahem... cluster... things, yes.", + }, cid) + player:setStorageValue(ROSHAMUUL_GOLD_RECORD, player:getInquisitionGold()) + player:setStorageValue(ROSHAMUUL_MORTAR_THROWN, 0) + player:setStorageValue(ROSHAMUUL_KILLED_FRAZZLEMAWS, 0) + player:setStorageValue(ROSHAMUUL_KILLED_SILENCERS, 0) + npcHandler.topic[cid] = nil + end + elseif msgcontains(msg, "record") then + local v = player:getStorageValue(ROSHAMUUL_GOLD_RECORD) + if v > 0 then + npcHandler:say("You have ".. v .." inquisition gold registered in my book.", cid) + else + npcHandler:say("I do not see inquisition gold registered in my book from you.", cid) + end + elseif msgcontains(msg, "trade") then + local v = player:getStorageValue(ROSHAMUUL_GOLD_RECORD) + if v >= 100 then + npcHandler.topic[cid] = 6 + npcHandler:say("Ah yes, you currently have ".. v .." of righteously earned inquisition gold in my book. 100 inquisition gold equals one cluster. How many clusters do you want in exchange?", cid) + else + npcHandler.topic[cid] = nil + npcHandler:say("You do not seem to have enough inquisition gold yet to trade for clusters, as it's registered in my book.", cid) + end + elseif npcHandler.topic[cid] == 6 then + local v = tonumber(msg) + if (v == nil) or (v < 1) or (math.floor(v) ~= v) then + return npcHandler:say("You should tell me a real number.", cid) + end + + local max = math.floor(player:getStorageValue(ROSHAMUUL_GOLD_RECORD)/100) + if v > max then + return npcHandler:say("You do not have enough inquisition gold for that, so far you can ask for up to ".. max .." clusters.", cid) + end + + player:addItem(22396, v) + npcHandler.topic[cid] = nil + player:setStorageValue(ROSHAMUUL_GOLD_RECORD, player:getStorageValue(ROSHAMUUL_GOLD_RECORD) - (v*100)) + npcHandler:say("There you are. Now I register ".. player:getStorageValue(ROSHAMUUL_GOLD_RECORD) .." inquisition gold of yours in my book.", cid) + end + + if msgcontains(msg, "bucket") or msgcontains(msg, "supplies") then + npcHandler:say("Head to brother Maun if you are in need of basic supplies. He will help you - for a small fee.", cid) + elseif msgcontains(msg, "maun") then + npcHandler:say("Brother Maun is a valuable member of the Inquisition. He will help you out with supplies. Provided you can actually compensate of course.", cid) + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Hm. Greetings.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Praise the gods, I bid you farewell.") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/sandra.lua b/data/npc/scripts/sandra.lua new file mode 100644 index 00000000000..d6b7a898e34 --- /dev/null +++ b/data/npc/scripts/sandra.lua @@ -0,0 +1,147 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + {text = "Great spirit potions as well as health and mana potions in different sizes!"}, + {text = "If you need alchemical fluids like slime and blood, get them here."} +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if isInArray({"vial", "ticket", "bonus", "deposit"}, msg) then + if player:getStorageValue(Storage.OutfitQuest.MageSummoner.AddonBelt) < 1 then + npcHandler:say( + "You have " .. + player:getStorageValue(38412) .. + " credits. We have a special offer right now for depositing vials. Are you interested in hearing it?", + cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.OutfitQuest.MageSummoner.AddonBelt) >= 1 then + npcHandler:say("Would you like to get a lottery ticket instead of the deposit for your vials?", cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, "prize") then + npcHandler:say("Are you here to claim a prize?", cid) + npcHandler.topic[cid] = 4 + elseif msgcontains(msg, "fafnar fire") then + if player:getStorageValue(Storage.TheShatteredIsles.RaysMission1) == 1 then + npcHandler:say("Pssht, not that loud. So they have sent you to get... the stuff?", cid) + npcHandler.topic[cid] = 5 + end + elseif msgcontains(msg, "your continued existence is payment enough") then + if npcHandler.topic[cid] == 6 then + if player:getStorageValue(Storage.TheShatteredIsles.RaysMission1) == 1 then + npcHandler:say( + "What?? How dare you?! I am a sorcerer of the most reknown academy on the face of this world. \ + Do you think some lousy pirates could scare me? Get lost! Now! \ + I will have no further dealings with the likes of you!", + cid) + player:setStorageValue(Storage.TheShatteredIsles.RaysMission1, 2) + npcHandler.topic[cid] = 0 + end + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say( + { + "The Edron academy has introduced a bonus system. Each time you deposit 100 vials without \ + claiming the money for it, you will receive a lottery ticket. ...", + "Some of these lottery tickets will grant you a special potion belt accessory, \ + if you bring the ticket to me. ...", + "If you join the bonus system now, I will ask you each time you are bringing back 100 or \ + more vials to me whether you claim your deposit or rather want a lottery ticket. ...", + "Of course, you can leave or join the bonus system at any time by just asking me for the 'bonus'. ...", + "Would you like to join the bonus system now?" + }, + cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say( + "Great! I've signed you up for our bonus system. From now on, \ + you will have the chance to win the potion belt addon!", + cid) + player:setStorageValue(Storage.OutfitQuest.MageSummoner.AddonBelt, 1) + player:setStorageValue(Storage.OutfitQuest.DefaultStart, 1) --this for default start of Outfit and Addon Quests + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + if player:getStorageValue(38412) >= 100 + or player:removeItem(7634, 100) + or player:removeItem(7635, 100) + or player:removeItem(7636, 100) then + npcHandler:say( + "Alright, thank you very much! Here is your lottery ticket, good luck. \ + Would you like to deposit more vials that way?", + cid) + player:setStorageValue(38412, player:getStorageValue(38412) - 100) + player:addItem(5957, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say( + "Sorry, but you don't have 100 empty flasks or vials of the SAME kind and thus don't qualify for the lottery. \ + Would you like to deposit the vials you have as usual and receive 5 gold per vial?", + cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 4 then + if player:getStorageValue(Storage.OutfitQuest.MageSummoner.AddonBelt) == 1 and player:removeItem(5958, 1) then + npcHandler:say("Congratulations! Here, from now on you can wear our lovely potion belt as accessory.", cid) + player:setStorageValue(Storage.OutfitQuest.MageSummoner.AddonBelt, 2) + player:addOutfitAddon(138, 1) + player:addOutfitAddon(133, 1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + else + npcHandler:say("Sorry, but you don't have your lottery ticket with you.", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 5 then + if player:getStorageValue(Storage.TheShatteredIsles.RaysMission1) == 1 then + npcHandler:say( + "Finally. You have no idea how difficult it is to keep something secret here. \ + And you brought me all the crystal coins I demanded?", + cid) + npcHandler.topic[cid] = 6 + end + end + return true + end +end + +keywordHandler:addKeyword( + {"shop"}, + StdModule.say, + { + npcHandler = npcHandler, + text = "I sell potions and fluids. If you'd like to see my offers, ask me for a {trade}." + } +) + +npcHandler:setMessage(MESSAGE_GREET, "Hello |PLAYERNAME|, welcome to the fluid and potion {shop} of Edron.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye, |PLAYERNAME|, please come back soon.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye, |PLAYERNAME|, please come back soon.") +npcHandler:setMessage( + MESSAGE_SENDTRADE, + "Of course, just browse through my wares. By the way, if you'd like to join our bonus \ + system for depositing flasks and vial, you have to tell me about that {deposit}." +) + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/sane_mage.lua b/data/npc/scripts/sane_mage.lua new file mode 100644 index 00000000000..9aa00b339b8 --- /dev/null +++ b/data/npc/scripts/sane_mage.lua @@ -0,0 +1,60 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Hm? What is the meaning of all this?' }, + { text = 'What have I become? What is slime if it\'s not for everyone?' }, + { text = 'Slime! Everywhere! SLIME TIME! Or... not?' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "I AM THE... I mean... I am - what is a mage, if he is not {mad}? If he isn't... raging? I am... I am just sane. A sane mage."}) +keywordHandler:addKeyword({'mad'}, StdModule.say, {npcHandler = npcHandler, text = "I am not mad... I- YES, that's the whole problem, isn't it? What's going on, what's happening to me? I don't even know anymore."}) +keywordHandler:addKeyword({'vacation'}, StdModule.say, {npcHandler = npcHandler, text = "Yes, well... I'm taking a break. It will take some time. I don't know how long I just... I want to get away from all this for some time, that's it."}) +keywordHandler:addKeyword({'mission'}, StdModule.say, {npcHandler = npcHandler, text = "Slime is my mission. Is there anything more important? There isn't. To me. Right now at least."}) +keywordHandler:addKeyword({'quest'}, StdModule.say, {npcHandler = npcHandler, text = "Slime is my mission. Is there anything more important? There isn't. To me. Right now at least."}) +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = "You want to help me? HELP me? You? Who... who are you anyway? Ah nevermind."}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if msgcontains(msg, "job") then + npcHandler:say({ + 'Well I conduct experiments. Viscosity, consistency and overall elegance of {SLIME}. Fungus, I am currently working on a formula for the perfect {slime fungus}.', + 'Not... right now, though. I am currently... on {vacation}. {Vacation}, yes. All my experiments went wrong. WRONG. Everything. I tried everything but still.', + 'It\'s always the same, the {fungus} grows, I am EXCITED and... well... WHAAAAAM! It just EXPLODES! It spreads, covers everything.', + 'At least I have my trusty {servants} helping me to clean up. They do ALL the work. Removing ALL the slime. At least they\'re working as intended. I designed them, you know.', + 'However, sometimes people come and just... DESTROY them! Destroy my work!! Why? Do those people help me removing the slime instead? NO! Not at all.', + 'All they do is ruining my experiments, my perfect testing conditions. It makes me just FURIOUS! And boy do I get FURIOUS, I tell you.' + }, cid) + elseif isInArray({"slime", "fungus"}, msg) then + npcHandler:say({ + 'My experiments, my work - not at the moment, however. I\'m on vacation. Trying to get away from it... it\'s all not right. Why... why am I doing this anyway.', + 'NO! I should not talk like that, I just... I shouldn\'t. That\'s not even ME. I... I used to be MAD. A MAD SCIENTIST! THE BEST! THE... the... WORST! A SUPERLATIVE! Ah, nevermind.' + }, cid) + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "...er... hello? Yes...? Well, if... if you have any questions - I am not even here.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Yes... then, goodbye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Yes... then, goodbye.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/santa_claus.lua b/data/npc/scripts/santa_claus.lua new file mode 100644 index 00000000000..92ad5ee852f --- /dev/null +++ b/data/npc/scripts/santa_claus.lua @@ -0,0 +1,113 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) +local talkState = {} + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local normalItems = { + {7439, 7440, 7443}, + {2688, 6508}, + {2688, 6509}, + {2688, 6507}, + {2688, 2114}, + {2688, 2111}, + {2167, 2213, 2214}, + {11227}, + {2156}, + {2153} +} + +local semiRareItems = { + {2173}, + {9954}, + {9971}, + {5080} +} + +local rareItems = { + {2110}, + {5919}, + {6567}, + {11255}, + {11256}, + {6566}, + {2112}, +} + +local veryRareItems = { + {2659}, + {3954}, + {2644}, + {10521}, + {5804} +} + +local function getReward() + local rewardTable = {} + local random = math.random(100) + if (random <= 90) then + rewardTable = normalItems + elseif (random <= 70) then + rewardTable = semiRareItems + elseif (random <= 30) then + rewardTable = rareItems + elseif (random <= 10) then + rewardTable = veryRareItems + end + + local rewardItem = rewardTable[math.random(#rewardTable)] + return rewardItem +end + +function creatureSayCallback(cid, type, msg) + if(not npcHandler:isFocused(cid)) then + return false + end + local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid + + if msgcontains(msg, 'present') then + local player = Player(cid) + if (player:getStorageValue(840293) == 1) then + npcHandler:say("You can't get other present.", cid) + return false + end + + -- if (player:getLevel() < 150) then + -- npcHandler:say("You need level 150 to get a present.", cid) + -- return false + -- end + + local reward = getReward() + local cont = Container(Player(cid):addItem(6511):getUniqueId()) + local count = 1 + + for i = 1, #reward do + if (reward[i] == 2111 or + reward[i] == 2688) then + count = 10 + end + + cont:addItem(reward[i], count) + end + + player:setStorageValue(840293, 1) + npcHandler:say("Merry Christmas!", cid) + end + + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/santiago.lua b/data/npc/scripts/santiago.lua new file mode 100644 index 00000000000..cc16e7d65e2 --- /dev/null +++ b/data/npc/scripts/santiago.lua @@ -0,0 +1,213 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Evil little beasts... I hope someone helps me fight them.' }, + { text = 'Nasty creepy crawlies!' }, + { text = 'Hey! You over there, could you help me with a little quest? Just say \'hi\' or \'hello\' to talk to me!' }, + { text = 'Don\'t be shy, can\'t hurt to greet me with \'hello\' or \'hi\'!' } +} +npcHandler:addModule(VoiceModule:new(voices)) + +local storeTalkCid = {} +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage) < 1 then + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage, 1) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoQuestLog, 1) + npcHandler:setMessage(MESSAGE_GREET, "Hello |PLAYERNAME|, nice to see you on Rookgaard! I saw you walking by and wondered if you could help me. Could you? Please, say {yes}!") + storeTalkCid[cid] = 0 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage) == 1 then + npcHandler:setMessage(MESSAGE_GREET, "Oh, |PLAYERNAME|, it's you again! It's probably impolite to disturb a busy adventurer like you, but I really need help. Please, say {yes}!") + storeTalkCid[cid] = 0 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage) == 2 then + npcHandler:say("Oh, what's wrong? As I said, simply go to my house south of here and go upstairs. Then come back and we'll continue our chat.", cid) + Position(32033, 32277, 6):sendMagicEffect(CONST_ME_TUTORIALARROW) + return false + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage) == 3 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back, |PLAYERNAME|! Ahh, you found my chest. Let me take a look at you. You put on that coat, {yes}?") + storeTalkCid[cid] = 2 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage) == 4 then + npcHandler:setMessage(MESSAGE_GREET, "Hey, I want to give you a weapon for free! You should not refuse that, in fact you should say '{yes}'!") + storeTalkCid[cid] = 2 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage) == 5 then + npcHandler:say("I've forgotten to tell you something. Of course I need proof that you killed cockroaches. Please bring me at least 3 of their legs. Good luck!", cid) + return false + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage) == 6 then + if player:removeItem(8710, 3) then + npcHandler:setMessage(MESSAGE_GREET, "Good job! For that, I'll grant you 100 experience points! Oh - what was that? I think you advanced a level, {right}?") + player:addExperience(100, true) + player:getPosition():sendMagicEffect(CONST_ME_GIFT_WRAPS) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoQuestLog, 5) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage, 7) + storeTalkCid[cid] = 4 + else + npcHandler:say("I've forgotten to tell you something. Of course I need proof that you killed cockroaches. Please bring me at least 3 of their legs. Good luck!", cid) + return false + end + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage) == 7 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back! Where were we... ? Ah, right, I asked you if you saw your 'level up'! You did, {right}?") + storeTalkCid[cid] = 4 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage) == 8 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back! Where were we... ? Ah, right, I asked you if those nasty cockroaches {hurt} you! Did they?") + storeTalkCid[cid] = 5 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage) == 9 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back! Where were we... ? Ah, right, I asked you if I should demonstrate some damage on you. Let's do it, {okay}?") + storeTalkCid[cid] = 6 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage) == 10 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back! Where were we... ? Ah, right, I was about to show you how you regain health, right?") + storeTalkCid[cid] = 7 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage) == 11 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back! Where were we... ? Ah, right, I gave you a fish to eat?") + storeTalkCid[cid] = 8 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage) == 12 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back! Where were we... ? Ah, right, I asked you if you saw Zirella! Did you?") + storeTalkCid[cid] = 9 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage) == 13 then + npcHandler:setMessage(MESSAGE_GREET, "Hello again, |PLAYERNAME|! It's great to see you. If you like, we can chat a little. Just use the highlighted {keywords} again to choose a {topic}.") + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if isInArray({"yes", "right", "ok"}, msg) then + if storeTalkCid[cid] == 0 then + npcHandler:say("Great, please go to my house, just a few steps south of here. Upstairs in my room, you'll find a chest. You can keep what you find inside of it! Come back after you got it and greet me to talk to me again. {Yes}?", cid) + Position(32033, 32277, 6):sendMagicEffect(CONST_ME_TUTORIALARROW) + storeTalkCid[cid] = 1 + elseif storeTalkCid[cid] == 1 then + npcHandler:say("Alright! Do you see the button called 'Quest Log'? There you can check the status of quests, like this one. {Bye} for now!", cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage, 2) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoQuestLog, 2) + player:sendTutorial(3) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + elseif storeTalkCid[cid] == 2 then + if player:getItemCount(2651) > 0 then + local coatSlot = player:getSlotItem(CONST_SLOT_ARMOR) + if coatSlot then + npcHandler:say("Ah, no need to say anything, I can see it suits you perfectly. Now we're getting to the fun part, let's get you armed! Are you ready for some {action}?", cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage, 4) + storeTalkCid[cid] = 3 + else + npcHandler:say("Oh, you don't wear it properly yet. You need to drag and drop it from your bag to your armor slot. Here, let me show you again. Is it a little {clearer} now?", cid) + player:sendTutorial(5) + storeTalkCid[cid] = 2 + end + else + player:addItem(2651, 1) + npcHandler:say("Oh no, did you lose my coat? Well, lucky you, I have a spare one here. Don't lose it again! Now we're getting to the fun part, let's get you armed! Are you ready for some {action}?", cid) + storeTalkCid[cid] = 3 + end + elseif storeTalkCid[cid] == 3 then + npcHandler:say("I knew I could count on you. Here, take this good and sturdy weapon in your hand. Then go back to my house and down the ladder. Good luck, and {bye} for now!", cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoQuestLog, 4) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage, 5) + Position(32036, 32277, 6):sendMagicEffect(CONST_ME_TUTORIALARROW) + player:addItem(2382, 1) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + elseif storeTalkCid[cid] == 4 then + npcHandler:say("That's just great! Now you have more health points, can carry more stuff and walk faster. Talking about health, did you get {hurt} by those cockroaches?", cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage, 8) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoQuestLog, 6) + storeTalkCid[cid] = 5 + elseif storeTalkCid[cid] == 5 then + npcHandler:say("Really? You look fine to me, must have been just a scratch. Well, there are much more dangerous monsters than cockroaches out there. Take a look at your status bar. You have 155 Health right now. I'll show you something, {yes}?", cid) + player:sendTutorial(19) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage, 9) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoQuestLog, 7) + storeTalkCid[cid] = 6 + elseif storeTalkCid[cid] == 6 then + npcHandler:say("This is an important lesson from me - an experienced veteran fighter. Take this! Look at your status bar again. As you can see, you've lost health. Now I'll tell you how to heal that, {yes}?", cid) + player:getPosition():sendMagicEffect(CONST_ME_MORTAREA) + Npc():getPosition():sendMagicEffect(CONST_ME_MORTAREA) + player:addHealth(-20, COMBAT_PHYSICALDAMAGE) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage, 10) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoQuestLog, 8) + player:sendTutorial(19) + storeTalkCid[cid] = 7 + elseif storeTalkCid[cid] == 7 then + npcHandler:say({ + "Here, take this fish which I've caught myself. Find it in your inventory, then 'Use' it to eat it. This will slowly refill your health. ...", + "By the way: If your hitpoints are below 150, you will regenerate back to 150 hitpoints after few seconds as long as you are not hungry, outside a protection zone and do not have a battle sign. {Easy}, yes?" + }, cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoQuestLog, 9) + player:addItem(2667, 1) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage, 11) + storeTalkCid[cid] = 8 + elseif storeTalkCid[cid] == 8 then + npcHandler:say("I knew you'd get it right away. You can loot food from many creatures, such as deer and rabbits. You can find them in the forest nearby. By the way... have you seen {Zirella}?", cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage, 12) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoQuestLog, 10) + storeTalkCid[cid] = 9 + elseif storeTalkCid[cid] == 9 then + npcHandler:say("Really?? She was looking for someone to help her. Maybe you could go and see her. She lives just to the east and down the mountain. So, thank you again and {bye} for now!", cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage, 13) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoQuestLog, 11) + player:addMapMark(Position(32045, 32270, 6), MAPMARK_GREENSOUTH, "To Zirella") + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + elseif msgcontains(msg, "hurt") then + if storeTalkCid[cid] == 6 then + npcHandler:say("This is an important lesson from me - an experienced veteran fighter. Take this! Look at your status bar again. As you can see, you've lost health. Now I'll tell you how to heal that, {yes}?", cid) + player:getPosition():sendMagicEffect(CONST_ME_MORTAREA) + Npc():getPosition():sendMagicEffect(CONST_ME_MORTAREA) + player:addHealth(-20, COMBAT_PHYSICALDAMAGE) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage, 8) + player:sendTutorial(19) + storeTalkCid[cid] = 7 + end + elseif msgcontains(msg, "action") then + if storeTalkCid[cid] == 3 then + npcHandler:say("I knew I could count on you. Here, take this good and sturdy weapon in your hand. Then go back to my house and down the ladder. Good luck, and {bye} for now!", cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoQuestLog, 4) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage, 5) + Position(32036, 32277, 6):sendMagicEffect(CONST_ME_TUTORIALARROW) + player:addItem(2382, 1) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + elseif msgcontains(msg, "easy") then + if storeTalkCid[cid] == 8 then + npcHandler:say("I knew you'd get it right away. You can loot food from many creatures, such as deer and rabbits. You can find them in the forest nearby. By the way... have you seen {Zirella}?", cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage, 11) + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoQuestLog, 10) + storeTalkCid[cid] = 9 + end + end + return true +end + +local function onReleaseFocus(cid) + storeTalkCid[cid] = nil +end + +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setMessage(MESSAGE_FAREWELL, "Take care, |PLAYERNAME|!.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye traveller, and enjoy your stay on Rookgaard.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/sarina.lua b/data/npc/scripts/sarina.lua new file mode 100644 index 00000000000..3b717ee03d0 --- /dev/null +++ b/data/npc/scripts/sarina.lua @@ -0,0 +1,49 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'General equipment and all sorts of goods. Visit my store!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if msgcontains(msg, "football") then + npcHandler:say("Do you want to buy a football for 111 gold?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + local player = Player(cid) + if player:getMoney() + player:getBankBalance() >= 111 then + npcHandler:say("Here it is.", cid) + player:addItem(2109, 1) + player:removeMoneyNpc(111) + else + npcHandler:say("You don't have enough money.", cid) + end + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Oh, please come in, |PLAYERNAME|. What can I do for you? If you need adventure equipment, ask me for a {trade}.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Of course, just browse through my wares. {Footballs} have to be purchased separately.") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/satsu.lua b/data/npc/scripts/satsu.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/satsu.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/scott.lua b/data/npc/scripts/scott.lua new file mode 100644 index 00000000000..3fc5a7f2eb9 --- /dev/null +++ b/data/npc/scripts/scott.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Hey there, adventurer! Need a little rest in my inn? Have some food!'} } +npcHandler:addModule(VoiceModule:new(voices)) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/scott_the_scout.lua b/data/npc/scripts/scott_the_scout.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/scott_the_scout.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/scrutinon.lua b/data/npc/scripts/scrutinon.lua new file mode 100644 index 00000000000..d99b082ea4b --- /dev/null +++ b/data/npc/scripts/scrutinon.lua @@ -0,0 +1,48 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + +-- Travel +local function addTravelKeyword(keyword, destination) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you want to sail ' .. keyword:titleCase() .. '?'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('ab\'dendriel', Position(32734, 31668, 6)) +addTravelKeyword('edron', Position(33175, 31764, 6)) +addTravelKeyword('venore', Position(32954, 32022, 6)) +addTravelKeyword('darashia', Position(33289, 32480, 6)) + +-- Basic +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, + text = { + "My name is Scrutinon. However, there are not many people calling my name nowadays. Not many captains even dare to land on this island. It is too close to {Quirefang}. ...", + "Most of them do not know this island by that name. Some call it Demon Horn, others the Dragon's Tooth or the Gray Beach as none of them ever came closer than a fair distance. ...", + "There are drifts and storms surrounding that place that are far too dangerous to navigate through even for the most versed captains. They often sail not closer than to this island here and drop off whoever dares to explore near this dreaded coast." + }} +) +keywordHandler:addKeyword({'quirefang'}, StdModule.say, {npcHandler = npcHandler, + text = { + "This island is cleft. Go there only prepared or you will meet your end. The surface of this forgotten rock is a barren wasteland full of hostile creatures. ...", + "Its visage is covered with holes and tunnels in which its leggy inhabitants are hiding. Its bowels filled with the strangest creatures, waiting to feast on whatever dares to disturb their hive. ...", + "And you will find no shelter in Quirefang's black depths, where the creatures of the deep are fulfilling a dark prophecy. ...", + "It is impossible to reach it by ship or boat. However, there was one before you. A {visitor} who found a way to enter the island." + }} +) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/scutty.lua b/data/npc/scripts/scutty.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/scutty.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/sebastian.lua b/data/npc/scripts/sebastian.lua new file mode 100644 index 00000000000..f21164afe49 --- /dev/null +++ b/data/npc/scripts/sebastian.lua @@ -0,0 +1,96 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function creatureSayCallback(cid, type, msg) + if(not npcHandler:isFocused(cid)) then + return false + end + + local player = Player(cid) + if(msgcontains(msg, "nargor")) then + if player:getStorageValue(Storage.TheShatteredIsles.AccessToNargor) == 1 then + npcHandler:say("Do you want to sail Nargor for 50 gold coins?", cid) + npcHandler.topic[cid] = 1 + end + elseif(msgcontains(msg, "yes")) then + if(npcHandler.topic[cid] == 1) then + if player:getStorageValue(Storage.TheShatteredIsles.AccessToNargor) == 1 then + if player:removeMoneyNpc(50) then + npcHandler:say("Set the sails!", cid) + player:teleportTo(Position(32024, 32813, 7)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + end + end + end + end + return true +end + +-- Travel +local function addTravelKeyword(keyword, cost, destination) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, + { + npcHandler = npcHandler, + text = 'Do you want to sail ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', + cost = cost, discount = 'postman' + } + ) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, + { + npcHandler = npcHandler, + premium = false, + cost = cost, + discount = 'postman', + destination = destination + } + ) + travelKeyword:addChildKeyword({'no'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'We would like to serve you some time.', + reset = true + } + ) +end + +addTravelKeyword('liberty bay', 50, Position(32316, 32702, 7)) + +-- Basic +keywordHandler:addKeyword({'passage'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'Where do you want to go? To {Liberty bay} or to {Nargor}?' + } + ) +keywordHandler:addKeyword({'job'}, StdModule.say, + {npcHandler = npcHandler, + text = 'I am the captain of this ship.' + } +) +keywordHandler:addKeyword({'captain'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'I am the captain of this ship.' + } +) + +npcHandler:setMessage(MESSAGE_GREET, "Greetings, daring adventurer. If you need a {passage}, let me know.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Oh well.") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/sebastian_nargor.lua b/data/npc/scripts/sebastian_nargor.lua new file mode 100644 index 00000000000..bc868170b8b --- /dev/null +++ b/data/npc/scripts/sebastian_nargor.lua @@ -0,0 +1,36 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Travel +local function addTravelKeyword(keyword, cost, destination) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you want to sail ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('liberty bay', 100, Position(32316, 32702, 7)) +addTravelKeyword('meriana', 50, Position(32346, 32625, 7)) + +-- Basic +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Liberty bay} or to {Meriana}?'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Greetings, daring adventurer. If you need a {passage}, let me know.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Oh well.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ser_tybald.lua b/data/npc/scripts/ser_tybald.lua new file mode 100644 index 00000000000..7c9f0d3ea84 --- /dev/null +++ b/data/npc/scripts/ser_tybald.lua @@ -0,0 +1,342 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- spells for knight and paladin +keywordHandler:addSpellKeyword({"findperson"}, + { + npcHandler = npcHandler, + spellName = "Find Person", + price = 80, + level = 8, + vocation = { + VOCATION.CLIENT_ID.PALADIN, + VOCATION.CLIENT_ID.KNIGHT + } + } +) +keywordHandler:addSpellKeyword({"light"}, + { + npcHandler = npcHandler, + spellName = "Light", + price = 0, + level = 8, + vocation = { + VOCATION.CLIENT_ID.PALADIN, + VOCATION.CLIENT_ID.KNIGHT + } + } +) +keywordHandler:addSpellKeyword({"magicrope"}, + { + npcHandler = npcHandler, + spellName = "Magic Rope", + price = 200, + level = 9, + vocation = { + VOCATION.CLIENT_ID.PALADIN, + VOCATION.CLIENT_ID.KNIGHT + } + } +) +keywordHandler:addSpellKeyword({"curepoison"}, + { + npcHandler = npcHandler, + spellName = "Cure Poison", + price = 150, + level = 10, + vocation = { + VOCATION.CLIENT_ID.PALADIN, + VOCATION.CLIENT_ID.KNIGHT + } + } +) +keywordHandler:addSpellKeyword({"levitate"}, + { + npcHandler = npcHandler, + spellName = "Levitate", + price = 500, + level = 12, + vocation = { + VOCATION.CLIENT_ID.PALADIN, + VOCATION.CLIENT_ID.KNIGHT + } + } +) +keywordHandler:addSpellKeyword({"haste"}, + { + npcHandler = npcHandler, + spellName = "Haste", + price = 600, + level = 14, + vocation = { + VOCATION.CLIENT_ID.PALADIN, + VOCATION.CLIENT_ID.KNIGHT + } + } +) +keywordHandler:addSpellKeyword({"greatlight"}, + { + npcHandler = npcHandler, + spellName = "Great Light", + price = 500, + level = 13, + vocation = { + VOCATION.CLIENT_ID.PALADIN, + VOCATION.CLIENT_ID.KNIGHT + } + } +) +--spells for paladin +keywordHandler:addSpellKeyword({"conjurebolt"}, + { + npcHandler = npcHandler, + spellName = "Conjure Bolt", + price = 750, + level = 17, + vocation = VOCATION.CLIENT_ID.PALADIN + } +) +keywordHandler:addSpellKeyword({"conjurepoisonedarrow"}, + { + npcHandler = npcHandler, + spellName = "Conjure Poisoned Arrow", + price = 700, + level = 16, + vocation = VOCATION.CLIENT_ID.PALADIN + } +) +keywordHandler:addSpellKeyword({"conjurearrow"}, + { + npcHandler = npcHandler, + spellName = "Conjure Arrow", + price = 450, + level = 13,vocation = VOCATION.CLIENT_ID.PALADIN + } +) +keywordHandler:addSpellKeyword({"lighthealing"}, + { + npcHandler = npcHandler, + spellName = "Light Healing", + price = 0, + level = 8, + vocation = VOCATION.CLIENT_ID.PALADIN + } +) +-- spells for knight +keywordHandler:addSpellKeyword({"brutalstrike"}, + { + npcHandler = npcHandler, + spellName = "Brutal Strike", + price = 1000, + level = 16, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"woundcleansing"}, + { + npcHandler = npcHandler, + spellName = "Wound Cleansing", + price = 0, + level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) + +keywordHandler:addKeyword({"healing spells"}, StdModule.say, + { + npcHandler = npcHandler, + text = "In this category I have '{Lighthealing}', '{Healfriend}', and '{Curepoison}'." + } +) +keywordHandler:addKeyword({"support spells"}, StdModule.say, + { + npcHandler = npcHandler, + text = "In this category I have '{Findperson}', '{Magicrope}', '{Levitate}', '{Light}', \z + '{Greatlight}', '{Haste}', '{Poisonfield}', '{Firefield}', '{Lightmagicmissile}' and '{Energyfield}'." + } +) +keywordHandler:addKeyword({"attack spells"}, StdModule.say, + { + npcHandler = npcHandler, + text = "In this category I have '{Deathstrike}', '{Firewave}', '{Apprenticesstrike}', \z + '{Energystrike}', '{Terrastrike}', '{Flamestrike}', '{Icestrike}', '{Physicalstrike}', '{Icewave}'." + } +) +keywordHandler:addKeyword({"spells"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I can teach you {healing spells}, {support spells} and {attack spells}. \z + What kind of spell do you wish to learn?" + } +) + +keywordHandler:addKeyword({"name"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I am Garamond Starstream." + } +) +keywordHandler:addKeyword({"job"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Did you not listen? I am the teacher of druid and sorcerer spells for level 8 to 18. \z + I teach young adventurers spells they can use once they have the proper vocation - druid or sorcerer." + } +) +keywordHandler:addKeyword({"rookgaard"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I have an old friend there. Haven't heard from him in a while." + } +) +keywordHandler:addKeyword({"dawnport"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Oh, it's not too bad here, believe me. At least I always get young and enthusiast disciples! \z + Though I must confess I miss the vastness of the Tibian plains. " + } +) +keywordHandler:addKeyword({"inigo"}, StdModule.say, + { + npcHandler = npcHandler, + text = "A kind old hunter. He loves to see young life around, taking on the ways and lays of the land. \z + If you have any question, ask Inigo for help." + } +) +keywordHandler:addKeyword({"coltrayne"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Roughened and toughened by life's tragedies. A good man, but somber." + } +) +keywordHandler:addKeyword({"garamond"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Yes, child. If you wish to learn a spell, tell me." + } +) +keywordHandler:addKeyword({"hamish"}, StdModule.say, + { + npcHandler = npcHandler, + text = "A very headstrong young man, though I appreciate his devotion to the craft of potion-making. \z + No respect for senior authority or age at all! Except maybe for a little soft spot for Mr Morris." + } +) +keywordHandler:addKeyword({"mr morris"}, StdModule.say, + { + npcHandler = npcHandler, + text = "A strange young man. He seems driven, to my mind. By what force, I do not know. \z + I take it the world needs adventurers such as him." + } +) +keywordHandler:addKeyword({"plunderpurse"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Redeeming one's soul by becoming a clerk? Not very likely. Once a pirate, always a pirate. \z + But he's a charming old rogue." + } +) +keywordHandler:addKeyword({"richard"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Not a half bad cook, truly. Must have been that squirrel diet, \z + it seems to have lead him to discover a new cuisine - everything to forget the bad taste of squirrels, he said." + } +) +keywordHandler:addKeyword({"ser tybald"}, StdModule.say, + { + npcHandler = npcHandler, + text = "He is proficient in the martial arts. A very skilled teacher of spells for knights and paladins. \z + If that is your vocation, you should talk to Ser Tybald." + } +) +keywordHandler:addKeyword({"wentworth"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Ah, yes. Travelled with Plunderpurse a lot as I recall. Captain Plunderpurse, then. \z + Got his head full of numbers and statistics, that boy." + } +) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "magic") then + npcHandler:say( + { + "Spells are very useful in combat - not only for mages, though of course we particularly \z + rely on them for much of our damage output. ...", + "There's a broad variety of what spells can do, as you will see as you progress further. \z + The next spells you can buy with level 8 and on. ...", + "Some attack spells can be directed at a single target while others affect an area, having an \z + effect either over time or instantaneous. Even other spells protect you, or can be used to create runes. ...", + "Each vocation has its own individual spells that none of the other vocations can use. \z + You can only learn spells at a spell trainer of your vocation. ...", + "The spells here on Dawnport are for trying out only, and you will forget them once \z + you choose your definite vocation and leave for the Mainland. ...", + "There, you can go to a spell teacher in a city to permanently learn a spell." + }, + cid) + elseif msgcontains(msg, "mainland") then + npcHandler:say( + { + "The Mainland offers many more adventures, dangers and quests than this small isle, \z + and also has spell teachers where you can permanently learn a spell for your vocation. ...", + "Once you reach level 8 you may choose your definite vocation and leave for Main. \z + Go to a city and seek out the spell trainer of your vocation to learn a spell. \z + And make sure you have enough gold! ...", + "The art of spell teaching is complex and dangerous, and we will only impart our \z + valuable knowledge of a spell to a novice if they can pay the price." + }, + cid) + elseif msgcontains(msg, "tibian") then + npcHandler:say( + { + "Ah, the beauty of our world! It is vast and extraordinarily diverse. Strange islands, \z + beautiful cities and fierce monsters that roam the wildernesses. \z + Mysteries, adventures, danger around every corner. ...", + "Once you have reached level 8, you are ready to choose a vocation and go to the Tibian Mainland." + }, + cid) + elseif msgcontains(msg, "vocation") then + npcHandler:say( + { + "Your choice of vocation will determine your life in Tibia, and the skills and fighting techniques you may use. ...", + "There are four vocation: knight, druid, paladin and sorcerer. \z + If you want to know more about them, talk to Oressa in the temple. ...", + "I myself teach try-out spells for both the magical classes, \z + whereas Tybald in the next room specialises in knight and paladin spells." + }, + cid) + elseif msgcontains(msg, "oressa") then + npcHandler:say( + { + "A very intelligent girl. Prefers to listen to wild animals' noises instead of humans', \z + which is quite understandable when you think about it. ...", + "However, she's also a very apt healer and can give you advice on your choice of vocation." + }, + cid) + end +end + +npcHandler:setMessage(MESSAGE_GREET, "Welcome, child. Have you come to learn about {magic}? \z + Then you are in the right place. I can teach you many useful {spells}.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/serafin.lua b/data/npc/scripts/serafin.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/serafin.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/servant_sentry.lua b/data/npc/scripts/servant_sentry.lua new file mode 100644 index 00000000000..9a24541336c --- /dev/null +++ b/data/npc/scripts/servant_sentry.lua @@ -0,0 +1,63 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Heed. Your. Will. We. Will.' }, + { text = 'Intruder. Intrude. Must. Explain.' }, + { text = 'Ssssttttoooopppp.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +keywordHandler:addKeyword({'master'}, StdModule.say, {npcHandler = npcHandler, text = "Our. Master. Is. Gone. You. Can. Not. Visit. Him! We. Stand. {Sentry}!"}) +keywordHandler:addKeyword({'sentry'}, StdModule.say, {npcHandler = npcHandler, text = "{Master}. Conducted. Experiments. Great. Problems. You. Must. Go!"}) +keywordHandler:addKeyword({'slime'}, StdModule.say, {npcHandler = npcHandler, text = "{Slime}. Dangerous. We. Have. It. Under. Control. ... We. Will. Stand. {Sentry}."}, function(player) return player:getStorageValue(Storage.TheirMastersVoice.SlimeGobblerReceived) == 1 end) + +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.TheirMastersVoice.SlimeGobblerReceived) < 1 then + npcHandler:say("The. {Slime}. Has. Entered. Our. {Master}. Has. Left! We. Must. {Help}.", cid) + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "help") then + npcHandler:say("Defeat. {Slime}. We. Will. Why. Did. You. Kill. Us? Do. You. Want. To. Rectify. And. Help?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + player:setStorageValue(Storage.TheirMastersVoice.SlimeGobblerReceived, 1) + player:addItem(13601, 1) + npcHandler:say("Then. Take. This. Gobbler. Always. Hungry. Eats. Slime. Fungus. Go.", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "The. Slime. Has. Entered. Our. Master. Has. Left! We. Must. Help.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Goodbye. Human. Being!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Goodbye. Human. Being!") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/seymour.lua b/data/npc/scripts/seymour.lua new file mode 100644 index 00000000000..1c757bdc243 --- /dev/null +++ b/data/npc/scripts/seymour.lua @@ -0,0 +1,190 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +npcHandler.rats = {} +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Newcomers - visit me! I\'ll answer your questions!' }, + { text = 'Get some training in the academy!' }, + { text = 'Feeling lost? Ask me for help!' }, + { text = 'Gain some knowledge in the academy!' } +} +npcHandler:addModule(VoiceModule:new(voices)) + +-- Greeting and Farewell +local hiKeyword = keywordHandler:addGreetKeyword({'hi'}, {npcHandler = npcHandler, text = 'Hello, |PLAYERNAME|. Welcome to the Academy of Rookgaard. May I sign you up as a {student}?'}) + hiKeyword:addChildKeyword({'student'}, StdModule.say, {npcHandler = npcHandler, text = 'Brilliant! We need fine adventurers like you! If you are ready to learn, just ask me for a lesson. You can always ask for the differently coloured words - such as this one - to continue the lesson.', reset = true}) + hiKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Brilliant! We need fine adventurers like you! If you are ready to learn, just ask me for a lesson. You can always ask for the differently coloured words - such as this one - to continue the lesson.', reset = true}) + hiKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Only nonsense on your mind, eh?', reset = true}) +keywordHandler:addAliasKeyword({'hello'}) + +keywordHandler:addFarewellKeyword({'bye'}, {npcHandler = npcHandler, text = 'Good bye, |PLAYERNAME|! And remember: No running up and down in the academy!'}) +keywordHandler:addAliasKeyword({'farewell'}) + +-- Rats +local ratsKeyword = keywordHandler:addKeyword({'%d+', 'dead', 'rat'}, StdModule.say, {npcHandler = npcHandler}, + function(player, data) npcHandler.rats[player.uid] = data[1] return data[1] and data[1] > 0 and data[1] < 0xFFFFFFFF end, + function(player) + npcHandler:say(string.format('Have you brought %d dead rats to me to pick up your reward?', npcHandler.rats[player.uid]), player.uid) + end) + ratsKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Thank you! Here is your reward.', reset = true}, + function(player) return player:getItemCount(2813) >= npcHandler.rats[player.uid] end, + function(player) player:removeItem(2813, npcHandler.rats[player.uid]) player:addMoney(2 * npcHandler.rats[player.uid]) end + ) + ratsKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'HEY! You don\'t have so many!', reset = true}) + ratsKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Go and find some rats to kill!', reset = true}) + +local ratKeyword = keywordHandler:addKeyword({'dead', 'rat'}, StdModule.say, {npcHandler = npcHandler, text = 'Have you brought a dead rat to me to pick up your reward?'}) + ratKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Thank you! Here is your reward.', reset = true}, + function(player) return player:getItemCount(2813) > 0 end, + function(player) player:removeItem(2813, 1) player:addMoney(2) end + ) + ratKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'HEY! You don\'t have one! Stop playing tricks on me or I\'ll give you some extra work!', reset = true}) + ratKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Go and find some rats to kill!', reset = true}) + +-- Quest +local boxKeyword = keywordHandler:addKeyword({'box'}, StdModule.say, {npcHandler = npcHandler, text = 'Do you have a suitable present box for me?'}) + boxKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'THANK YOU! Here is a helmet that will serve you well.', reset = true}, + function(player) return player:getItemCount(1990) > 0 end, + function(player) player:removeItem(1990, 1) player:addItem(2480, 1) end + ) + boxKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'HEY! You don\'t have one! Stop playing tricks on me or I\'ll give you some extra work!', reset = true}) + +keywordHandler:addKeyword({'mission'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, I would like to send our king a little present but I do not have a suitable box. If you find a nice box, please bring it to me.'}, + function(player) return player:getLevel() >= 4 end) +keywordHandler:addAliasKeyword({'quest'}) +keywordHandler:addKeyword({'mission'}, StdModule.say, {npcHandler = npcHandler, text = 'You are pretty inexperienced. I think killing rats is a suitable challenge for you. For each fresh {dead rat} I will give you two shiny coins of gold.'}) +keywordHandler:addAliasKeyword({'quest'}) + +keywordHandler:addKeyword({'fuck'}, StdModule.say, {npcHandler = npcHandler, text = 'For this remark I will wash your mouth with soap, young lady!'}, + function(player) return player:getSex() == PLAYERSEX_FEMALE end, + function(player) player:getPosition():sendMagicEffect(CONST_ME_YELLOW_RINGS) end) +keywordHandler:addKeyword({'fuck'}, StdModule.say, {npcHandler = npcHandler, text = 'For this remark I will wash your mouth with soap, young man!'}, nil, + function(player) player:getPosition():sendMagicEffect(CONST_ME_YELLOW_RINGS) end) + +-- Basic keywords +keywordHandler:addKeyword({'hint'}, StdModule.rookgaardHints, {npcHandler = npcHandler}) +keywordHandler:addKeyword({'island', 'of', 'destiny'}, StdModule.say, {npcHandler = npcHandler, text = 'This is an island with {vocation} teachers. You can learn all about the different vocations there once you are level 8.'}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = 'It\'s |TIME|, so you are late. Hurry!'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Seymour, but for you I am \'Sir\' Seymour.'}) +keywordHandler:addKeyword({'sir'}, StdModule.say, {npcHandler = npcHandler, text = 'At least you know how to address a man of my importance.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m the master of this fine {academy}, giving {lessons} to my students.'}) +keywordHandler:addKeyword({'lesson'}, StdModule.say, {npcHandler = npcHandler, text = 'Oh, which lesson did you want to attend again? Was it {Rookgaard}, {fighting}, {equipment}, {citizens}, the {academy} or the {oracle}?'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'In a bank you can deposit your earned gold coins safely. Just go downstairs to {Paulie} and ask him to {deposit} your money.'}) +keywordHandler:addKeyword({'deposit'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes, depositing your money will keep it safe, so it is a good idea to store it in the bank. Of course, you can always withdraw it again.'}) +keywordHandler:addKeyword({'how', 'are', 'you'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, the {king} doesn\'t send troops anymore, the {academy} is dreadfully low on money, and the end of the world is pretty nigh. Apart from that I\'m reasonably fine, I suppose.'}) +keywordHandler:addKeyword({'citizen'}, StdModule.say, {npcHandler = npcHandler, text = 'Most of the citizens here are {merchants}. You can give me the name of any non-player character and I will tell you something about him or her.'}) +keywordHandler:addKeyword({'merchant'}, StdModule.say, {npcHandler = npcHandler, text = 'Merchants buy and sell goods. Just ask them for a {trade} to see what they offer or buy from you.'}) +keywordHandler:addKeyword({'troll'}, StdModule.say, {npcHandler = npcHandler, text = 'Trolls are quite nasty monsters which you shouldn\'t face before level 3 or 4 depending on your {equipment}. Ask the bridge {guards} for their locations!'}) +keywordHandler:addKeyword({'guard'}, StdModule.say, {npcHandler = npcHandler, text = 'The guards {Dallheim} and {Zerbrus} protect our village from {monsters} trying to enter. They also mark useful {dungeon} locations on your map.'}) +keywordHandler:addKeyword({'vocation'}, StdModule.say, {npcHandler = npcHandler, text = 'There are four vocations: {knights}, {paladins}, {sorcerers} and {druids}. You can choose your vocation once you are level 8 and have talked to the {oracle}.'}) +keywordHandler:addKeyword({'sorcerer'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorcerers are talented elemental magicians. You will learn all about them once you are level 8 and reached the Island of {Destiny}.'}) +keywordHandler:addKeyword({'knight'}, StdModule.say, {npcHandler = npcHandler, text = 'Knights are strong melee fighters. You will learn all about them once you are level 8 and reached the Island of {Destiny}.'}) +keywordHandler:addKeyword({'druid'}, StdModule.say, {npcHandler = npcHandler, text = 'Druids are nature magic users and great healers. You will learn all about them once you are level 8 and reached the Island of {Destiny}.'}) +keywordHandler:addKeyword({'paladin'}, StdModule.say, {npcHandler = npcHandler, text = 'Paladins are swift distance fighters. You will learn all about them once you are level 8 and reached the Island of {Destiny}.'}) +keywordHandler:addKeyword({'shop'}, StdModule.say, {npcHandler = npcHandler, text = 'We have a {weapon} and an {armor} shop south of the academy. {Equipment} such as {ropes} are sold to the north-west. {Potions} can be bought to the south. And then there are the {farms}.'}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = 'The world of Tibia is very large with tons of places to explore. Vast deserts, Caribbean islands, deep jungles, green meadows and jagged mountains await you!'}) +keywordHandler:addKeyword({'temple'}, StdModule.say, {npcHandler = npcHandler, text = 'The temple is the place to go when you are very low on {health} or poisoned. Ask {Cipfried} for a heal - he usually notices emergencies by himself.'}) +keywordHandler:addKeyword({'health'}, StdModule.say, {npcHandler = npcHandler, text = 'Your current health is shown by the red bar on the right side. {Death} awaits you if it goes down to zero.'}) +keywordHandler:addKeyword({'death'}, StdModule.say, {npcHandler = npcHandler, text = 'Dying in Tibia is painful, so try to avoid it. You will lose part of your {experience} points and also equipment. Make sure your {health} always stays up!'}) +keywordHandler:addKeyword({'experience'}, StdModule.say, {npcHandler = npcHandler, text = 'You gain experience when fighting {monsters}. You can take a look at your skill window to check your progress.'}) +keywordHandler:addKeyword({'monster'}, StdModule.say, {npcHandler = npcHandler, text = 'Good monsters to start hunting are {rats}. They live in the {sewers} below the village.'}) +keywordHandler:addKeyword({'sewer'}, StdModule.say, {npcHandler = npcHandler, text = 'One entrance to the sewers is south of this {academy}. Look for a sewer grate, then use it to climb down.'}) +keywordHandler:addKeyword({'academy'}, StdModule.say, {npcHandler = npcHandler, text = 'The academy is the building you are standing in. We have a {library}, a {bank} and the room of the {oracle}.'}) +keywordHandler:addKeyword({'library'}, StdModule.say, {npcHandler = npcHandler, text = 'There are many books in the bookcases around you, unless some naughty kids stole them again. Read them for more and detailed information.'}) +keywordHandler:addKeyword({'equip'}, StdModule.say, {npcHandler = npcHandler, text = 'Don\'t go hunting without proper equipment. You need at least a suitable {weapon}, {armor}, {shield}, {rope} and {shovel}. A {torch} is also good as well as {legs}, a {helmet} and {shoes}.'}) +keywordHandler:addKeyword({'money'}, StdModule.say, {npcHandler = npcHandler, text = 'Make money by killing {monsters} and picking up their {loot}. You can sell many of the things they carry.'}) +keywordHandler:addKeyword({'loot'}, StdModule.say, {npcHandler = npcHandler, text = 'Once a monster is dead, you can select \'Open\' on the {corpse} to check what\'s inside. Sometimes they carry {money} or other items which you can sell to {merchants}.'}) +keywordHandler:addKeyword({'corpse'}, StdModule.say, {npcHandler = npcHandler, text = 'You can even sell some corpses! For example, you can sell fresh dead rats to {Tom} the tanner or me. He also buys other dead creatures, just ask him for a {trade}.'}) +keywordHandler:addKeyword({'rope'}, StdModule.say, {npcHandler = npcHandler, text = 'You definitely need a rope to progress in dungeons, else you might end up stuck. Buy one from {Al Dee} or {Lee\'Delle}.'}) +keywordHandler:addKeyword({'shovel'}, StdModule.say, {npcHandler = npcHandler, text = 'A shovel is needed to dig some {dungeon} entrances open. \'Use\' it on a loose stone pile to make a hole large enough to enter.'}) +keywordHandler:addKeyword({'dungeon'}, StdModule.say, {npcHandler = npcHandler, text = 'You should not descend into dungeons without proper {equipment}. Once you are all prepared, ask the bridge {guards} for suitable {monsters}.'}) +keywordHandler:addKeyword({'torch'}, StdModule.say, {npcHandler = npcHandler, text = 'A torch will provide you with light in dark {dungeons}. \'Use\' it to light it. You can buy them from {Al Dee} or {Lee\'Delle}.'}) +keywordHandler:addKeyword({'student'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, I could give you valuable {lessons} or some general {hints} about the game, or a small {quest} if you\'re interested.'}) +keywordHandler:addKeyword({'armor'}, StdModule.say, {npcHandler = npcHandler, text = 'The starter armor, a coat, does not protect you well. First of all, earn some money and try to get a sturdy leather armor from {Dixi}\'s or {Lee\'Delle}\'s shop. Simply ask for a {trade}.'}) +keywordHandler:addKeyword({'weapon'}, StdModule.say, {npcHandler = npcHandler, text = 'The starter weapon, a club, won\'t get you far. You should earn some {money} and buy a better weapon such as a sabre from {Obi}\'s or {Lee\'Delle}\'s shop. Simply ask for a {trade}.'}) +keywordHandler:addKeyword({'helmet'}, StdModule.say, {npcHandler = npcHandler, text = 'A sturdy leather helmet is a good choice for a beginner. You can either buy it from {Dixi} and {Lee\'Delle}, or, once you are strong enough, {loot} them from {trolls}.'}) +keywordHandler:addKeyword({'shield'}, StdModule.say, {npcHandler = npcHandler, text = 'I fear you have to buy your first shield by yourself. A wooden shield from {Dixi} or {Lee\'Delle} is a good choice.'}) +keywordHandler:addKeyword({'shoe'}, StdModule.say, {npcHandler = npcHandler, text = 'Leather boots are basic shoes which will protect you well. You can either buy them from {Dixi} and {Lee\'Delle}, or, once you are strong enough, {loot} them from {trolls}.'}) +keywordHandler:addKeyword({'leg'}, StdModule.say, {npcHandler = npcHandler, text = 'Leather legs might be a good basic protection. You can buy them from {Dixi} or {Lee\'Delle}. Or, once you are strong enough, hunt {trolls}. They sometimes carry them in their {loot}.'}) +keywordHandler:addKeyword({'food'}, StdModule.say, {npcHandler = npcHandler, text = 'Many monsters, such as rabbits or deer, are excellent food providers. You can also buy food from {Willie} or {Billy}, the farmers.'}) +keywordHandler:addKeyword({'premium'}, StdModule.say, {npcHandler = npcHandler, text = 'Paying for your Tibia account will turn it into a premium account. This means access to more areas and functions of the game as well as other neat features.'}) +keywordHandler:addKeyword({'king'}, StdModule.say, {npcHandler = npcHandler, text = 'Hail to King Tibianus! Long live our king! Not that he cares for an old veteran who is stuck on this godforsaken island...'}) +keywordHandler:addKeyword({'potion'}, StdModule.say, {npcHandler = npcHandler, text = 'Use a small health potion in case of emergencies to fill up around 75 health points. You can buy them at {Lily}\'s shop. She also has {antidote} potions.'}) +keywordHandler:addKeyword({'antidote'}, StdModule.say, {npcHandler = npcHandler, text = 'Some monsters poison you. To heal poison, use an antidote potion on yourself. Buy them at {Lily}\'s store.'}) +keywordHandler:addKeyword({'rookgaard'}, StdModule.say, {npcHandler = npcHandler, text = 'Rookgaard is the name of this {village} as well as of the whole {island}. It belongs to the kingdom of {Thais}, in our world which is called {Tibia}.'}) +keywordHandler:addKeyword({'island'}, StdModule.say, {npcHandler = npcHandler, text = 'The island is separated into a {premium} side and a non-premium side. On both sides you will find {dungeons}, but the premium side tends to be a little less crowded with other players.'}) +keywordHandler:addKeyword({'thais'}, StdModule.say, {npcHandler = npcHandler, text = 'The city of Thais is reigned by King Tibianus. Of course, there are many other cities but you will learn about them later.'}) +keywordHandler:addKeyword({'village'}, StdModule.say, {npcHandler = npcHandler, text = 'The most important places in this village are the {temple}, the different {shops}, the {academy} and the {bridges}.'}) +keywordHandler:addKeyword({'bridge'}, StdModule.say, {npcHandler = npcHandler, text = 'There is a bridge to the north and one to the west which lead outside the village. You should only leave once you are well {equipped} and at least level 2.'}) +keywordHandler:addKeyword({'main'}, StdModule.say, {npcHandler = npcHandler, text = 'You can leave for mainland once you are level 8. To do so talk to the {oracle}.'}) +keywordHandler:addKeyword({'fighting'}, StdModule.say, {npcHandler = npcHandler, text = 'You have to fight {monsters} to train your {skills} and {level}. If you lose {health}, eat {food} to regain it or use a {potion}.'}) +keywordHandler:addKeyword({'skill'}, StdModule.say, {npcHandler = npcHandler, text = 'The more you fight with a weapon, the better will be your skill handling this weapon. Don\'t worry about that right now though, this will become important once you have a {vocation}.'}) +keywordHandler:addKeyword({'level'}, StdModule.say, {npcHandler = npcHandler, text = 'Once you gained enough experience for a level, you will advance. This means - among other things - more {health} points, a faster walking speed and more strength to carry things.'}) +keywordHandler:addKeyword({'farm'}, StdModule.say, {npcHandler = npcHandler, text = 'The farms are west of here. You can buy and sell {food} there which you need to regain {health}.'}) +keywordHandler:addKeyword({'rat'}, StdModule.say, {npcHandler = npcHandler, text = 'To attack a rat, simply click on it in your battle list. Make sure that you have proper {equipment}, though! Also, I give you 2 gold coins for each {dead rat}.'}) +keywordHandler:addKeyword({'trade'}, StdModule.say, {npcHandler = npcHandler, text = 'I personally don\'t have anything to trade, but you can ask {merchants} for a trade. That will open a window where you can see their offers and the things they buy from you.'}) + +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, I could give you valuable {lessons} or some general {hints} about the game, or a small {quest} if you\'re interested.'}) +keywordHandler:addAliasKeyword({'information'}) + +local destinyKeyword = keywordHandler:addKeyword({'destiny'}, StdModule.say, {npcHandler = npcHandler, text = 'Shall I try and take a guess at your destiny?'}, function(player) return player:getStorageValue(Storage.RookgaardDestiny) == -1 end) +destinyKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, reset = true}, nil, + function(player) + local destiny = math.random(1, 4) + if destiny == 1 then + npcHandler:say('Hmmm, let me look at you. You got that intelligent sparkle in your eyes and you\'d love to handle great power - that must be a future sorcerer!', player.uid) + elseif destiny == 2 then + npcHandler:say('Hmmm, let me look at you. You have an aura of great wisdom and may have healing hands as well as a sense for the powers of nature - I think you\'re a natural born druid!', player.uid) + elseif destiny == 3 then + npcHandler:say('Hmmm, let me look at you. !', player.uid) + elseif destiny == 4 then + npcHandler:say('Hmmm, let me look at you. Strong and sturdy, with a determined look in your eyes - no doubt the knight profession would be suited for you!', player.uid) + end + player:setStorageValue(Storage.RookgaardDestiny, destiny) + end +) + +keywordHandler:addKeyword({'destiny'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, like I told you before, I really think you got that spirit of a sorcerer in you. But of course it\'s completely up to you!'}, function(player) return player:getStorageValue(Storage.RookgaardDestiny) == 1 end) +keywordHandler:addKeyword({'destiny'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, like I told you before, I really think you got that spirit of a druid in you. But of course it\'s completely up to you!'}, function(player) return player:getStorageValue(Storage.RookgaardDestiny) == 2 end) +keywordHandler:addKeyword({'destiny'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, like I told you before, I really think you got that spirit of a paladin in you. But of course it\'s completely up to you!'}, function(player) return player:getStorageValue(Storage.RookgaardDestiny) == 3 end) +keywordHandler:addKeyword({'destiny'}, StdModule.say, {npcHandler = npcHandler, text = 'Well, like I told you before, I really think you got that spirit of a knight in you. But of course it\'s completely up to you!'}, function(player) return player:getStorageValue(Storage.RookgaardDestiny) == 4 end) + +-- Names +keywordHandler:addKeyword({'obi'}, StdModule.say, {npcHandler = npcHandler, text = 'Obi sells and buys {weapons}. You can find his shop south of the academy.'}) +keywordHandler:addKeyword({'norma'}, StdModule.say, {npcHandler = npcHandler, text = 'Norma has recently opened a bar here meaning she sells drinks and snacks. Nothing of importance to you, young student.'}) +keywordHandler:addKeyword({'loui'}, StdModule.say, {npcHandler = npcHandler, text = 'Oh, let\'s not talk about Loui.'}) +keywordHandler:addKeyword({'santiago'}, StdModule.say, {npcHandler = npcHandler, text = 'A fine and helpful man. Without him, many new adventurers would be quite clueless.'}) +keywordHandler:addKeyword({'zirella'}, StdModule.say, {npcHandler = npcHandler, text = 'This is Tom the tanner\'s mother. Other than that, I don\'t think she is of importance.'}) +keywordHandler:addKeyword({'al', 'dee'}, StdModule.say, {npcHandler = npcHandler, text = 'Al Dee has a general {equipment} store in the north-western part of the village. He sells useful stuff such as {ropes}.'}) +keywordHandler:addKeyword({'amber'}, StdModule.say, {npcHandler = npcHandler, text = 'A traveller from the {main} continent. I wonder what brought her here. No one comes here of his own free will.'}) +keywordHandler:addKeyword({'billy'}, StdModule.say, {npcHandler = npcHandler, text = 'Billy is {Willie}\'s cousin, but he has his farm on the {premium} side of the village.'}) +keywordHandler:addKeyword({'willie'}, StdModule.say, {npcHandler = npcHandler, text = 'Willie is a fine farmer, although he is short-tempered. He sells and buys {food}.'}) +keywordHandler:addKeyword({'cipfried'}, StdModule.say, {npcHandler = npcHandler, text = 'A humble monk living in the {temple} south of here. He can heal you if you are wounded or poisoned.'}) +keywordHandler:addKeyword({'dixi'}, StdModule.say, {npcHandler = npcHandler, text = 'Dixi sells and buys {armors}, {shields}, {helmets} and {legs}. You can find her shop south of the academy, just go up the stairs in {Obi}\'s shop.'}) +keywordHandler:addKeyword({'hyacinth'}, StdModule.say, {npcHandler = npcHandler, text = 'A mysterious druid who lives somewhere in the wilderness. He sells small health {potions} just like {Lily}.'}) +keywordHandler:addKeyword({'lee\'delle'}, StdModule.say, {npcHandler = npcHandler, text = 'Lee\'Delle\'s shop is in the western part of town, on the {premium} side. She sells everything cheaper.'}) +keywordHandler:addKeyword({'lily'}, StdModule.say, {npcHandler = npcHandler, text = 'In the southern part of town, Lily sells {potions} which might come in handy once you are deep in a dungeon and need {health}.'}) +keywordHandler:addKeyword({'oracle'}, StdModule.say, {npcHandler = npcHandler, text = 'The oracle is a mysterious being just upstairs. It will bring you to the {Island of Destiny} to choose your {vocation} once you are level 8.'}) +keywordHandler:addKeyword({'paulie'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes, Paulie is very important. He is the local {bank} clerk.'}) +keywordHandler:addKeyword({'seymour'}, StdModule.say, {npcHandler = npcHandler, text = 'Sir Seymour, yes, that\'s me.'}) +keywordHandler:addKeyword({'tom'}, StdModule.say, {npcHandler = npcHandler, text = 'Tom the tanner buys fresh {corpses}, minotaur leather and paws. Always good to make some {money} if you can carry the corpses there fast enough.'}) +keywordHandler:addKeyword({'dallheim'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s the guard on the north {bridge} and a great fighter. He can show you {monster} locations. Just ask him about monsters!'}) +keywordHandler:addKeyword({'zerbrus'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s the guard on the west {bridge} and a great fighter. He can show you {monster} locations. Just ask him about monsters!'}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye! And remember: No running up and down in the academy!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/shadowpunch.lua b/data/npc/scripts/shadowpunch.lua new file mode 100644 index 00000000000..e88e935b7eb --- /dev/null +++ b/data/npc/scripts/shadowpunch.lua @@ -0,0 +1,20 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/shalmar.lua b/data/npc/scripts/shalmar.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/shalmar.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/shanar.lua b/data/npc/scripts/shanar.lua new file mode 100644 index 00000000000..cd19577aa3a --- /dev/null +++ b/data/npc/scripts/shanar.lua @@ -0,0 +1,32 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local voices = { + { text = 'Fine elven armor and weapons. Have a look.' }, + { text = 'Looking for protective spells for druids? I can teach you.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +-- Greeting message +keywordHandler:addGreetKeyword({"ashari"}, {npcHandler = npcHandler, text = "Greetings, |PLAYERNAME|."}) +--Farewell message +keywordHandler:addFarewellKeyword({"asgha thrazi"}, {npcHandler = npcHandler, text = "Goodbye, |PLAYERNAME|."}) + +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye!") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/shanoya.lua b/data/npc/scripts/shanoya.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/shanoya.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/sharon.lua b/data/npc/scripts/sharon.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/sharon.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/shauna.lua b/data/npc/scripts/shauna.lua new file mode 100644 index 00000000000..1fcac4642ca --- /dev/null +++ b/data/npc/scripts/shauna.lua @@ -0,0 +1,92 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + -- Mission 1 - The Supply Thief + if msgcontains(msg, "job") then + if Player(cid):getStorageValue(Storage.DjinnWar.EfreetFaction.Mission01) == 2 then + npcHandler:say("What do you think? I am the sheriff of Carlin.", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "water pipe") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "Oh, there's a waterpipe in one of my cells? ...", + "I guess my last {prisoner} forgot it there." + }, cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, "prisoner") then + if npcHandler.topic[cid] == 2 then + npcHandler:say({ + "My last prisoner? Hmm. ...", "I think he was some guy from Darama. Can't remember his name. ...", + "He was here just for one night, because he got drunk and annoyed our citizens. ...", + "Obviously he wasn't pleased with this place, because he headed for Thais the next day. ...", + "Something tells me that he won't stay out of trouble for too long." + }, cid) + Player(cid):setStorageValue(Storage.DjinnWar.EfreetFaction.Mission01, 3) + npcHandler.topic[cid] = 0 + end + end + -- Mission 1 - The Supply Thief + return true +end + +keywordHandler:addKeyword({'news'}, StdModule.say, {npcHandler = npcHandler, text = "No news are good news."}) +keywordHandler:addKeyword({'queen'}, StdModule.say, {npcHandler = npcHandler, text = "HAIL TO QUEEN ELOISE!"}) +keywordHandler:addKeyword({'leader'}, StdModule.say, {npcHandler = npcHandler, text = "HAIL TO QUEEN ELOISE!"}) +keywordHandler:addKeyword({'how', 'are', 'you'}, StdModule.say, {npcHandler = npcHandler, text = "Just fine."}) +keywordHandler:addKeyword({'sell'}, StdModule.say, {npcHandler = npcHandler, text = "Would you like to buy the general key to the town?"}) +keywordHandler:addKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = "Yeah, I bet you'd like to do that! HO, HO, HO!"}) +keywordHandler:addKeyword({'army'}, StdModule.say, {npcHandler = npcHandler, text = "If they make trouble, I'll put them behind bars like all others."}) +keywordHandler:addKeyword({'guard'}, StdModule.say, {npcHandler = npcHandler, text = "If they make trouble, I'll put them behind bars like all others."}) +keywordHandler:addKeyword({'general'}, StdModule.say, {npcHandler = npcHandler, text = "The Bonecrusher family is ideally suited for military jobs."}) +keywordHandler:addKeyword({'bonecrusher'}, StdModule.say, {npcHandler = npcHandler, text = "The Bonecrusher family is ideally suited for military jobs."}) +keywordHandler:addKeyword({'enemies'}, StdModule.say, {npcHandler = npcHandler, text = "If you have a crime to report and clues, then do it, but don't waste my time."}) +keywordHandler:addKeyword({'enemy'}, StdModule.say, {npcHandler = npcHandler, text = "If you have a crime to report and clues, then do it, but don't waste my time."}) +keywordHandler:addKeyword({'criminal'}, StdModule.say, {npcHandler = npcHandler, text = "If you have a crime to report and clues, then do it, but don't waste my time."}) +keywordHandler:addKeyword({'murderer'}, StdModule.say, {npcHandler = npcHandler, text = "If you have a crime to report and clues, then do it, but don't waste my time."}) +keywordHandler:addKeyword({'castle'}, StdModule.say, {npcHandler = npcHandler, text = "The castle is one of the safest places in Carlin."}) +keywordHandler:addKeyword({'subject'}, StdModule.say, {npcHandler = npcHandler, text = "Our people are fine and peaceful."}) +keywordHandler:addKeyword({'tbi'}, StdModule.say, {npcHandler = npcHandler, text = "I bet they spy on us... not my business, however."}) +keywordHandler:addKeyword({'todd'}, StdModule.say, {npcHandler = npcHandler, text = "I scared this bigmouth so much that he left the town by night. HO, HO, HO!"}) +keywordHandler:addKeyword({'city'}, StdModule.say, {npcHandler = npcHandler, text = "The city is is a peaceful place, and it's up to me to keep it this way."}) +keywordHandler:addKeyword({'hain'}, StdModule.say, {npcHandler = npcHandler, text = "He is the guy responsible to keep the sewers working. Someone has to do such kind of jobs. I can't handle all the garbage of the city myself."}) +keywordHandler:addKeyword({'rowenna'}, StdModule.say, {npcHandler = npcHandler, text = "Rowenna is one of our local smiths. When you look for weapons, look for Rowenna."}) +keywordHandler:addKeyword({'weapon'}, StdModule.say, {npcHandler = npcHandler, text = "Rowenna is one of our local smiths. When you look for weapons, look for Rowenna."}) +keywordHandler:addKeyword({'cornelia'}, StdModule.say, {npcHandler = npcHandler, text = "Cornelia is one of our local smiths. When you look for armor, look for Cornelia."}) +keywordHandler:addKeyword({'armor'}, StdModule.say, {npcHandler = npcHandler, text = "Cornelia is one of our local smiths. When you look for armor, look for Cornelia."}) +keywordHandler:addKeyword({'legola'}, StdModule.say, {npcHandler = npcHandler, text = "She has the sharpest eye in the region, I'd say."}) +keywordHandler:addKeyword({'padreia'}, StdModule.say, {npcHandler = npcHandler, text = "Her peacefulness is sometimes near stupidity."}) +keywordHandler:addKeyword({'god'}, StdModule.say, {npcHandler = npcHandler, text = "I worship Banor of course."}) +keywordHandler:addKeyword({'banor'}, StdModule.say, {npcHandler = npcHandler, text = "For me, he's the god of justice."}) +keywordHandler:addKeyword({'zathroth'}, StdModule.say, {npcHandler = npcHandler, text = "His cult is forbidden in our town."}) +keywordHandler:addKeyword({'brog'}, StdModule.say, {npcHandler = npcHandler, text = "Wouldn't wonder if some males worship him secretly. HO, HO, HO!"}) +keywordHandler:addKeyword({'monster'}, StdModule.say, {npcHandler = npcHandler, text = "I deal more with the human mosters, you know? HO, HO, HO!"}) +keywordHandler:addKeyword({'excalibug'}, StdModule.say, {npcHandler = npcHandler, text = "Would certainly make a good butterknife. HO, HO, HO!"}) +keywordHandler:addKeyword({'rebellion'}, StdModule.say, {npcHandler = npcHandler, text = "The only thing that rebels here now and then is the stomach of a male after trying to make illegal alcohol. HO, HO, HO!"}) +keywordHandler:addKeyword({'alcohol'}, StdModule.say, {npcHandler = npcHandler, text = "For obvious reasons it's forbidden in our city."}) + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "Howdy, |PLAYERNAME|!") +npcHandler:setMessage(MESSAGE_FAREWELL, "LONG LIVE THE QUEEN!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "LONG LIVE THE QUEEN!") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/sherry_mcronald.lua b/data/npc/scripts/sherry_mcronald.lua new file mode 100644 index 00000000000..506a77a40ad --- /dev/null +++ b/data/npc/scripts/sherry_mcronald.lua @@ -0,0 +1,25 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Isn\'t this a beautiful day? Perfect for farming.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "Hello |PLAYERNAME|! Welcome to our humble farm.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Grace our home with another visit soon, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "What a strange person.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/shiantis.lua b/data/npc/scripts/shiantis.lua new file mode 100644 index 00000000000..069e27773cf --- /dev/null +++ b/data/npc/scripts/shiantis.lua @@ -0,0 +1,49 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Containers, decoration and general goods, all here!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if msgcontains(msg, "football") then + npcHandler:say("Do you want to buy a football for 111 gold?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + local player = Player(cid) + if player:getMoney() + player:getBankBalance() >= 111 then + npcHandler:say("Here it is.", cid) + player:addItem(2109, 1) + player:removeMoneyNpc(111) + else + npcHandler:say("You don't have enough money.", cid) + end + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Oh, please come in, |PLAYERNAME|. What can I do for you? If you need adventure equipment, ask me for a {trade}.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Of course, just browse through my wares.") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/shimun.lua b/data/npc/scripts/shimun.lua new file mode 100644 index 00000000000..638f0749938 --- /dev/null +++ b/data/npc/scripts/shimun.lua @@ -0,0 +1,87 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local playerTopic = {} +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.Kilmaresh.First.Access) < 1 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + playerTopic[cid] = 1 + elseif (player:getStorageValue(Storage.Kilmaresh.First.JamesfrancisTask) >= 0 and player:getStorageValue(Storage.Kilmaresh.First.JamesfrancisTask) <= 50) + and player:getStorageValue(Storage.Kilmaresh.First.Mission) < 3 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + playerTopic[cid] = 15 + elseif player:getStorageValue(Storage.Kilmaresh.First.Mission) == 4 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + player:setStorageValue(Storage.Kilmaresh.First.Mission, 5) + playerTopic[cid] = 20 + end + npcHandler:addFocus(cid) + return true +end + +local function creatureSayCallback(cid, type, msg) +if not npcHandler:isFocused(cid) then + return false +end +npcHandler.topic[cid] = playerTopic[cid] +local player = Player(cid) +if msgcontains(msg, "mission") and player:getStorageValue(Storage.Kilmaresh.Eighth.Shimun) == 1 then + if player:getStorageValue(Storage.Kilmaresh.Eighth.Shimun) == 1 then + npcHandler:say({"Could you help me do a ritual?"}, cid)-- It needs to be revised, it's not the same as the global + npcHandler.topic[cid] = 1 + playerTopic[cid] = 1 + end +elseif msgcontains(msg, "yes") and playerTopic[cid] == 1 and player:getStorageValue(Storage.Kilmaresh.Eighth.Shimun) == 1 then + if player:getStorageValue(Storage.Kilmaresh.Eighth.Shimun) == 1 then + player:addItem(36550, 1) + npcHandler:say({"Here is the list with the missing ingredients to complete the ritual."}, cid)-- It needs to be revised, it's not the same as the global + player:setStorageValue(Storage.Kilmaresh.Eighth.Shimun, 2) + npcHandler.topic[cid] = 2 + playerTopic[cid] = 2 + else + npcHandler:say({"Sorry."}, cid)-- It needs to be revised, it's not the same as the global + end +end +if msgcontains(msg, "mission") and player:getStorageValue(Storage.Kilmaresh.Eighth.Shimun) == 2 then + if player:getStorageValue(Storage.Kilmaresh.Eighth.Shimun) == 2 then + npcHandler:say({"Did you bring all the materials I informed you about? "}, cid)-- It needs to be revised, it's not the same as the global + npcHandler.topic[cid] = 3 + playerTopic[cid] = 3 + end +elseif msgcontains(msg, "yes") and playerTopic[cid] == 3 and player:getStorageValue(Storage.Kilmaresh.Eighth.Shimun) == 2 then + if player:getStorageValue(Storage.Kilmaresh.Eighth.Shimun) == 2 and player:getItemById(36175, 1) and player:getItemById(36171, 12) and player:getItemById(2006, 5) then + player:removeItem(36175, 1) + player:removeItem(36171, 12) + player:removeItem(2006, 5) + npcHandler:say({"Thank you this stage of the ritual is complete."}, cid)-- It needs to be revised, it's not the same as the global + player:setStorageValue(Storage.Kilmaresh.Eighth.Shimun, 3) + npcHandler.topic[cid] = 4 + playerTopic[cid] = 4 + else + npcHandler:say({"Sorry."}, cid)-- It needs to be revised, it's not the same as the global + end +end +return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/shiriel.lua b/data/npc/scripts/shiriel.lua new file mode 100644 index 00000000000..eac508821e8 --- /dev/null +++ b/data/npc/scripts/shiriel.lua @@ -0,0 +1,25 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +-- Greeting message +keywordHandler:addGreetKeyword({"ashari"}, {npcHandler = npcHandler, text = "Greetings, |PLAYERNAME|."}) +--Farewell message +keywordHandler:addFarewellKeyword({"asgha thrazi"}, {npcHandler = npcHandler, text = "Goodbye, |PLAYERNAME|."}) + +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye!") + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/shirith.lua b/data/npc/scripts/shirith.lua new file mode 100644 index 00000000000..b72ae23e63f --- /dev/null +++ b/data/npc/scripts/shirith.lua @@ -0,0 +1,53 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if msgcontains(msg, "key") then + npcHandler:say("Do you want to buy a key for 50 gold?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + local player = Player(cid) + if player:getMoney() + player:getBankBalance() >= 50 then + npcHandler:say("Here it is.", cid) + local key = player:addItem(2088, 1) + if key then + key:setActionId(3033) + end + player:removeMoneyNpc(50) + else + npcHandler:say("You don't have enough money.", cid) + end + npcHandler.topic[cid] = 0 + end + end + return true +end + +keywordHandler:addGreetKeyword({"ashari"}, {npcHandler = npcHandler, text = "Greetings, |PLAYERNAME|."}) +--Farewell message +keywordHandler:addFarewellKeyword({"asgha thrazi"}, {npcHandler = npcHandler, text = "Good bye!."}) + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "Ashari |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye!") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye!") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/shoddy_beggar.lua b/data/npc/scripts/shoddy_beggar.lua new file mode 100644 index 00000000000..719945af0b0 --- /dev/null +++ b/data/npc/scripts/shoddy_beggar.lua @@ -0,0 +1,137 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = '*mumbles*' }, + { text = 'That astronomer of the academy simply has no idea what he is dealing with...' }, + { text = 'Some secrets should better be left uncovered.' }, + { text = 'Ha, ha... *mumbles* Hmm.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, 'spare') then + npcHandler:say('Hmm, if you can spare a coin... we can talk. What do you say?', cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, 'device') then + if player:getStorageValue(Storage.SeaOfLight.Questline) == 1 then + npcHandler:say('Persistent little nuisance, aren\'t we? Well, I like your spirit so I will tell you a secret. I may not look the part but I was once a {scientist}. The academy seemed to not like my... attitude and never actually invited me.', cid) + end + elseif msgcontains(msg, 'scientist') then + if player:getStorageValue(Storage.SeaOfLight.Questline) == 1 then + npcHandler:say('Indeed, I was one myself a long time ago. I may seem a little... distracted by now, but I was working on many important projects. I even created a device to... well, it will cost you another gold coin if you want me to tell you the whole story. You\'re in?', cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + if not player:removeMoneyNpc(1) then + npcHandler:say(player:getStorageValue(Storage.SeaOfLight.Questline) ~= 1 and 'Is that all you have? That would be less than I have... *mumbles*' or 'Mh, it seems you don\'t have any coins.', cid) + npcHandler.topic[cid] = 0 + return true + end + + npcHandler:say(player:getStorageValue(Storage.SeaOfLight.Questline) ~= 1 and 'Very kind indeed. Maybe you are not such a bad guy after all. Maybe I can even give it back to you one day... you know I was not always like that *mumbles*.' or 'Thank you very much... plans you say? I don\'t know what you are talking about. Plans for a magic... device? And the people call ME crazy.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + if not player:removeMoneyNpc(1) then + npcHandler:say('Well, if that is all you can spare... better keep it.', cid) + npcHandler.topic[cid] = 0 + return true + end + + npcHandler:say('Alright, it seems you are serious about this. I will tell you about my device. Every night I looked up to the stars and wondered what worlds we would be able to find if we could just look where we wanted to. So... hey are you still listening?', cid) + npcHandler.topic[cid] = 3 + elseif npcHandler.topic[cid] == 3 then + npcHandler:say('Good, good. So eventually I found a way and invented a magic device I called the Lightboat. It was a large construction you could sit in and... well, judging by your looks you don\'t believe a word. Do you want to hear the story or not?', cid) + npcHandler.topic[cid] = 4 + elseif npcHandler.topic[cid] == 4 then + npcHandler:say('Fine. For years I gathered all the necessary items to build the device. I travelled, traded and took advantage of some rare opportunities. With luck and patience I eventually got every component I needed. Can you imagine the excitement I experienced?', cid) + npcHandler.topic[cid] = 5 + elseif npcHandler.topic[cid] == 5 then + npcHandler:say('And there I stood before my greatest invention. Door to unknown places, mysterious worlds... yet one of my components was flawed. A small crack in a vital element of my construction quickly led to the failure of the whole project. Still following?', cid) + npcHandler.topic[cid] = 6 + elseif npcHandler.topic[cid] == 6 then + npcHandler:say('The device was ultimately destroyed. I barely escaped the chaos with my life. My laboratory was shattered, as were all the components of the cursed device. With nothing left, I started to lead a new, different life. Do you know what that means?', cid) + npcHandler.topic[cid] = 7 + elseif npcHandler.topic[cid] == 7 then + npcHandler:say('Pah!! You have NO idea, leave me alone now.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 8 then + npcHandler:say('Right... I\'m glad everything was destroyed. I don\'t even know why I kept the remaining copy of the plans all those years... oh, did I say this aloud?', cid) + npcHandler.topic[cid] = 9 + elseif npcHandler.topic[cid] == 9 then + npcHandler:say('Yes, well... I do have one remaining copy of the plans. I will keep them as a... reminder. Such ill-fated devices only cause trouble and despair. Mankind would be better off, without them, right?', cid) + npcHandler.topic[cid] = 10 + elseif npcHandler.topic[cid] == 10 then + npcHandler:say('Ah, you think you are wise but you know nothing, nothing about science, nothing about the opportunities it offers... You will never understand scientists like me.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 11 then + player:addItem(10613, 1) + player:setStorageValue(Storage.SeaOfLight.Questline, 2) + player:setStorageValue(Storage.SeaOfLight.Mission1, 2) + npcHandler:say('Well, to be honest, I envy him a little. He can continue his research in his laboratory. He still has working equipment... I sometimes read his publications. He is an able man, but completely on the wrong track... give these plans to him.', cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'no') then + if npcHandler.topic[cid] == 1 then + npcHandler:say('Mean, heartless... go and leave me be.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say('Well, whatever then...', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + npcHandler:say('Then stop bothering me.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 4 then + npcHandler:say('Your decision.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 5 then + npcHandler:say('Yes and I, I... you mean what? Can\'t imagine? Well, then there is no purpose to continue telling you this story.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 6 then + npcHandler:say('*mumbles*', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 7 then + npcHandler:say('Thought so. It means starting anew, without any home, money or goal in your life. However, it also opens up opportunities... don\'t you agree?', cid) + npcHandler.topic[cid] = 8 + elseif npcHandler.topic[cid] == 8 then + npcHandler:say('No, no, you are right, I should have tried to rebuild it, I should have been more careful, I should... ah, why did I even tell you this.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 9 then + npcHandler:say('Phew... alright, it was nice talking to you.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 10 then + npcHandler:say('Hm, maybe you are right. You could give these plans to someone who might be able to finish this project. Someone who will not make the mistakes I made. Someone... hm, do you know the astronomer Spectulus?', cid) + npcHandler.topic[cid] = 11 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "What do you want? Listen to the old madman? If you have nothing to spare, leave me alone.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Yes, whatever.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Yes, whatever.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/sholley.lua b/data/npc/scripts/sholley.lua new file mode 100644 index 00000000000..5ccae12fd29 --- /dev/null +++ b/data/npc/scripts/sholley.lua @@ -0,0 +1,47 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function creatureSayCallback(cid, type, msg) + if(not(npcHandler:isFocused(cid))) then + return false + end + + local player = Player(cid) + if(msgcontains(msg, "friend")) then + if player:getStorageValue(Storage.DarkTrails.Mission12) == 1 then + npcHandler:say("So you have proven yourself a true friend of our city. It's hard to believe but I think your words only give substance to suspicions my heart had harboured since quite a while. ...", cid) + npcHandler:say("So Harsin is probably not the person he appeared to be. Actually I haven't heard from him for quite a while. He was resident in the local bed and breakfast hotel. You should be able to find him there or at least to learn about his whereabouts.", cid) + player:setStorageValue(Storage.DarkTrails.Mission13, 1) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "quandon")) then + if player:setStorageValue(Storage.DarkTrails.Mission14) == 2 then + npcHandler:say("A transporter dead? This is more then alarming. It seems Harsin is up to something and whatever it is, it's nothing good at all. But not all is lost. A local medium, Barnabas, has truly the gift to speak to the dead. ...", cid) + npcHandler:say("I'll mark his home on your map. He should be able to get the information you need to locate Harsin.", cid) + player:setStorageValue(Storage.DarkTrails.Mission15, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Already clicked the body on the house Roswitha ?", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/shortsighted_dwarf.lua b/data/npc/scripts/shortsighted_dwarf.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/shortsighted_dwarf.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/siestaar.lua b/data/npc/scripts/siestaar.lua new file mode 100644 index 00000000000..e1ab01fce12 --- /dev/null +++ b/data/npc/scripts/siestaar.lua @@ -0,0 +1,649 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +local count = {} +local transfer = {} + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Don\'t forget to deposit your money here in the Tibian Bank before you head out for adventure.'} } +if VoiceModule then + npcHandler:addModule(VoiceModule:new(voices)) +end +--------------------------------guild bank----------------------------------------------- +local receiptFormat = 'Date: %s\nType: %s\nGold Amount: %d\nReceipt Owner: %s\nRecipient: %s\n\n%s' +local function getReceipt(info) + local receipt = Game.createItem(info.success and 24301 or 24302) + receipt:setAttribute(ITEM_ATTRIBUTE_TEXT, receiptFormat:format(os.date('%d. %b %Y - %H:%M:%S'), info.type, info.amount, info.owner, info.recipient, info.message)) + + return receipt +end + +local function getGuildIdByName(name, func) + db.asyncStoreQuery('SELECT `id` FROM `guilds` WHERE `name` = ' .. db.escapeString(name), + function(resultId) + if resultId then + func(result.getNumber(resultId, 'id')) + result.free(resultId) + else + func(nil) + end + end + ) +end + +local function getGuildBalance(id) + local guild = Guild(id) + if guild then + return guild:getBankBalance() + else + local balance + local resultId = db.storeQuery('SELECT `balance` FROM `guilds` WHERE `id` = ' .. id) + if resultId then + balance = result.getNumber(resultId, 'balance') + result.free(resultId) + end + + return balance + end +end + +local function setGuildBalance(id, balance) + local guild = Guild(id) + if guild then + guild:setBankBalance(balance) + else + db.query('UPDATE `guilds` SET `balance` = ' .. balance .. ' WHERE `id` = ' .. id) + end +end + +local function transferFactory(playerName, amount, fromGuildId, info) + return function(toGuildId) + if not toGuildId then + local player = Player(playerName) + if player then + info.success = false + info.message = 'We are sorry to inform you that we could not fulfil your request, because we could not find the recipient guild.' + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + end + else + local fromBalance = getGuildBalance(fromGuildId) + if fromBalance < amount then + info.success = false + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your guild account.' + else + info.success = true + info.message = 'We are happy to inform you that your transfer request was successfully carried out.' + setGuildBalance(fromGuildId, fromBalance - amount) + setGuildBalance(toGuildId, getGuildBalance(toGuildId) + amount) + end + + local player = Player(playerName) + if player then + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + end + end + end +end +--------------------------------guild bank----------------------------------------------- + +local function greetCallback(cid) + count[cid], transfer[cid] = nil, nil + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) +---------------------------- help ------------------------ + if msgcontains(msg, 'bank account') then + npcHandler:say({ + 'Every Tibian has one. The big advantage is that you can access your money in every branch of the Tibian Bank! ...', + 'Would you like to know more about the {basic} functions of your bank account, the {advanced} functions, or are you already bored, perhaps?' + }, cid) + npcHandler.topic[cid] = 0 + return true +---------------------------- balance --------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild balance') then + npcHandler.topic[cid] = 0 + if not player:getGuild() then + npcHandler:say('You are not a member of a guild.', cid) + return false + end + npcHandler:say('Your guild account balance is ' .. player:getGuild():getBankBalance() .. ' gold.', cid) + return true +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'balance') then + npcHandler.topic[cid] = 0 + if player:getBankBalance() >= 100000000 then + npcHandler:say('I think you must be one of the richest inhabitants in the world! Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + elseif player:getBankBalance() >= 10000000 then + npcHandler:say('You have made ten millions and it still grows! Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + elseif player:getBankBalance() >= 1000000 then + npcHandler:say('Wow, you have reached the magic number of a million gp!!! Your account balance is ' .. player:getBankBalance() .. ' gold!', cid) + return true + elseif player:getBankBalance() >= 100000 then + npcHandler:say('You certainly have made a pretty penny. Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + else + npcHandler:say('Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + end +---------------------------- deposit --------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild deposit') then + if not player:getGuild() then + npcHandler:say('You are not a member of a guild.', cid) + npcHandler.topic[cid] = 0 + return false + end + -- count[cid] = player:getMoney() + -- if count[cid] < 1 then + -- npcHandler:say('You do not have enough gold.', cid) + -- npcHandler.topic[cid] = 0 + -- return false + --end + if string.match(msg, '%d+') then + count[cid] = getMoneyCount(msg) + if count[cid] < 1 then + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return false + end + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold to your {guild account}?', cid) + npcHandler.topic[cid] = 23 + return true + else + npcHandler:say('Please tell me how much gold it is you would like to deposit.', cid) + npcHandler.topic[cid] = 22 + return true + end + elseif npcHandler.topic[cid] == 22 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold to your {guild account}?', cid) + npcHandler.topic[cid] = 23 + return true + else + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return true + end + elseif npcHandler.topic[cid] == 23 then + if msgcontains(msg, 'yes') then + npcHandler:say('Alright, we have placed an order to deposit the amount of ' .. count[cid] .. ' gold to your guild account. Please check your inbox for confirmation.', cid) + local guild = player:getGuild() + local info = { + type = 'Guild Deposit', + amount = count[cid], + owner = player:getName() .. ' of ' .. guild:getName(), + recipient = guild:getName() + } + local playerBalance = player:getBankBalance() + if playerBalance < tonumber(count[cid]) then + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your bank account.' + info.success = false + else + info.message = 'We are happy to inform you that your transfer request was successfully carried out.' + info.success = true + guild:setBankBalance(guild:getBankBalance() + tonumber(count[cid])) + player:setBankBalance(playerBalance - tonumber(count[cid])) + end + + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish. Is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 + return true +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'deposit') then + count[cid] = player:getMoney() + if count[cid] < 1 then + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return false + end + if msgcontains(msg, 'all') then + count[cid] = player:getMoney() + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid) + npcHandler.topic[cid] = 2 + return true + else + if string.match(msg,'%d+') then + count[cid] = getMoneyCount(msg) + if count[cid] < 1 then + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return false + end + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid) + npcHandler.topic[cid] = 2 + return true + else + npcHandler:say('Please tell me how much gold it is you would like to deposit.', cid) + npcHandler.topic[cid] = 1 + return true + end + end + if not isValidMoney(count[cid]) then + npcHandler:say('Sorry, but you can\'t deposit that much.', cid) + npcHandler.topic[cid] = 0 + return false + end + elseif npcHandler.topic[cid] == 1 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid) + npcHandler.topic[cid] = 2 + return true + else + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return true + end + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, 'yes') then + if player:depositMoney(count[cid]) then + npcHandler:say('Alright, we have added the amount of ' .. count[cid] .. ' gold to your {balance}. You can {withdraw} your money anytime you want to.', cid) + else + npcHandler:say('You do not have enough gold.', cid) + end + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish. Is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 + return true +---------------------------- withdraw -------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild withdraw') then + if not player:getGuild() then + npcHandler:say('I am sorry but it seems you are currently not in any guild.', cid) + npcHandler.topic[cid] = 0 + return false + elseif player:getGuildLevel() < 2 then + npcHandler:say('Only guild leaders or vice leaders can withdraw money from the guild account.', cid) + npcHandler.topic[cid] = 0 + return false + end + + if string.match(msg,'%d+') then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your guild account?', cid) + npcHandler.topic[cid] = 25 + else + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + end + return true + else + npcHandler:say('Please tell me how much gold you would like to withdraw from your guild account.', cid) + npcHandler.topic[cid] = 24 + return true + end + elseif npcHandler.topic[cid] == 24 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your guild account?', cid) + npcHandler.topic[cid] = 25 + else + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + end + return true + elseif npcHandler.topic[cid] == 25 then + if msgcontains(msg, 'yes') then + local guild = player:getGuild() + local balance = guild:getBankBalance() + npcHandler:say('We placed an order to withdraw ' .. count[cid] .. ' gold from your guild account. Please check your inbox for confirmation.', cid) + local info = { + type = 'Guild Withdraw', + amount = count[cid], + owner = player:getName() .. ' of ' .. guild:getName(), + recipient = player:getName() + } + if balance < tonumber(count[cid]) then + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your guild account.' + info.success = false + else + info.message = 'We are happy to inform you that your transfer request was successfully carried out.' + info.success = true + guild:setBankBalance(balance - tonumber(count[cid])) + local playerBalance = player:getBankBalance() + player:setBankBalance(playerBalance + tonumber(count[cid])) + end + + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish. Is there something else I can do for you?', cid) + npcHandler.topic[cid] = 0 + end + return true +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'withdraw') then + if string.match(msg,'%d+') then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your bank account?', cid) + npcHandler.topic[cid] = 7 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + return true + else + npcHandler:say('Please tell me how much gold you would like to withdraw.', cid) + npcHandler.topic[cid] = 6 + return true + end + elseif npcHandler.topic[cid] == 6 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your bank account?', cid) + npcHandler.topic[cid] = 7 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + return true + elseif npcHandler.topic[cid] == 7 then + if msgcontains(msg, 'yes') then + if player:getFreeCapacity() >= getMoneyWeight(count[cid]) then + if not player:withdrawMoney(count[cid]) then + npcHandler:say('There is not enough gold on your account.', cid) + else + npcHandler:say('Here you are, ' .. count[cid] .. ' gold. Please let me know if there is something else I can do for you.', cid) + end + else + npcHandler:say('Whoah, hold on, you have no room in your inventory to carry all those coins. I don\'t want you to drop it on the floor, maybe come back with a cart!', cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') then + npcHandler:say('The customer is king! Come back anytime you want to if you wish to {withdraw} your money.', cid) + npcHandler.topic[cid] = 0 + end + return true +---------------------------- transfer -------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild transfer') then + if not player:getGuild() then + npcHandler:say('I am sorry but it seems you are currently not in any guild.', cid) + npcHandler.topic[cid] = 0 + return false + elseif player:getGuildLevel() < 2 then + npcHandler:say('Only guild leaders or vice leaders can transfer money from the guild account.', cid) + npcHandler.topic[cid] = 0 + return false + end + + if string.match(msg, '%d+') then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + transfer[cid] = string.match(msg, 'to%s*(.+)$') + if transfer[cid] then + npcHandler:say('So you would like to transfer ' .. count[cid] .. ' gold from your guild account to guild ' .. transfer[cid] .. '?', cid) + npcHandler.topic[cid] = 28 + else + npcHandler:say('Which guild would you like to transfer ' .. count[cid] .. ' gold to?', cid) + npcHandler.topic[cid] = 27 + end + else + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + end + else + npcHandler:say('Please tell me the amount of gold you would like to transfer.', cid) + npcHandler.topic[cid] = 26 + end + return true + elseif npcHandler.topic[cid] == 26 then + count[cid] = getMoneyCount(msg) + if player:getGuild():getBankBalance() < count[cid] then + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + return true + end + if isValidMoney(count[cid]) then + npcHandler:say('Which guild would you like to transfer ' .. count[cid] .. ' gold to?', cid) + npcHandler.topic[cid] = 27 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + return true + elseif npcHandler.topic[cid] == 27 then + transfer[cid] = msg + if player:getGuild():getName() == transfer[cid] then + npcHandler:say('Fill in this field with person who receives your gold!', cid) + npcHandler.topic[cid] = 0 + return true + end + npcHandler:say('So you would like to transfer ' .. count[cid] .. ' gold from your guild account to guild ' .. transfer[cid] .. '?', cid) + npcHandler.topic[cid] = 28 + return true + elseif npcHandler.topic[cid] == 28 then + if msgcontains(msg, 'yes') then + npcHandler:say('We have placed an order to transfer ' .. count[cid] .. ' gold from your guild account to guild ' .. transfer[cid] .. '. Please check your inbox for confirmation.', cid) + local guild = player:getGuild() + local balance = guild:getBankBalance() + local info = { + type = 'Guild to Guild Transfer', + amount = count[cid], + owner = player:getName() .. ' of ' .. guild:getName(), + recipient = transfer[cid] + } + if balance < tonumber(count[cid]) then + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your guild account.' + info.success = false + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + else + getGuildIdByName(transfer[cid], transferFactory(player:getName(), tonumber(count[cid]), guild:getId(), info)) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') then + npcHandler:say('Alright, is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'transfer') then + npcHandler:say('Please tell me the amount of gold you would like to transfer.', cid) + npcHandler.topic[cid] = 11 + elseif npcHandler.topic[cid] == 11 then + count[cid] = getMoneyCount(msg) + if player:getBankBalance() < count[cid] then + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + return true + end + if isValidMoney(count[cid]) then + npcHandler:say('Who would you like transfer ' .. count[cid] .. ' gold to?', cid) + npcHandler.topic[cid] = 12 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 12 then + transfer[cid] = msg + if player:getName() == transfer[cid] then + npcHandler:say('Fill in this field with person who receives your gold!', cid) + npcHandler.topic[cid] = 0 + return true + end + if playerExists(transfer[cid]) then + local arrayDenied = {"accountmanager", "rooksample", "druidsample", "sorcerersample", "knightsample", "paladinsample"} + if isInArray(arrayDenied, string.gsub(transfer[cid]:lower(), " ", "")) then + npcHandler:say('This player does not exist.', cid) + npcHandler.topic[cid] = 0 + return true + end + npcHandler:say('So you would like to transfer ' .. count[cid] .. ' gold to ' .. transfer[cid] .. '?', cid) + npcHandler.topic[cid] = 13 + else + npcHandler:say('This player does not exist.', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 13 then + if msgcontains(msg, 'yes') then + if not player:transferMoneyTo(transfer[cid], count[cid]) then + npcHandler:say('You cannot transfer money to this account.', cid) + else + npcHandler:say('Very well. You have transferred ' .. count[cid] .. ' gold to ' .. transfer[cid] ..'.', cid) + transfer[cid] = nil + end + elseif msgcontains(msg, 'no') then + npcHandler:say('Alright, is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 +---------------------------- money exchange -------------- + elseif msgcontains(msg, 'change gold') then + npcHandler:say('How many platinum coins would you like to get?', cid) + npcHandler.topic[cid] = 14 + elseif npcHandler.topic[cid] == 14 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough gold coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] * 100 .. ' of your gold coins into ' .. count[cid] .. ' platinum coins?', cid) + npcHandler.topic[cid] = 15 + end + elseif npcHandler.topic[cid] == 15 then + if msgcontains(msg, 'yes') then + if player:removeItem(2148, count[cid] * 100) then + player:addItem(2152, count[cid]) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough gold coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'change platinum') then + npcHandler:say('Would you like to change your platinum coins into gold or crystal?', cid) + npcHandler.topic[cid] = 16 + elseif npcHandler.topic[cid] == 16 then + if msgcontains(msg, 'gold') then + npcHandler:say('How many platinum coins would you like to change into gold?', cid) + npcHandler.topic[cid] = 17 + elseif msgcontains(msg, 'crystal') then + npcHandler:say('How many crystal coins would you like to get?', cid) + npcHandler.topic[cid] = 19 + else + npcHandler:say('Well, can I help you with something else?', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 17 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] .. ' of your platinum coins into ' .. count[cid] * 100 .. ' gold coins for you?', cid) + npcHandler.topic[cid] = 18 + end + elseif npcHandler.topic[cid] == 18 then + if msgcontains(msg, 'yes') then + if player:removeItem(2152, count[cid]) then + player:addItem(2148, count[cid] * 100) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 19 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] * 100 .. ' of your platinum coins into ' .. count[cid] .. ' crystal coins for you?', cid) + npcHandler.topic[cid] = 20 + end + elseif npcHandler.topic[cid] == 20 then + if msgcontains(msg, 'yes') then + if player:removeItem(2152, count[cid] * 100) then + player:addItem(2160, count[cid]) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'change crystal') then + npcHandler:say('How many crystal coins would you like to change into platinum?', cid) + npcHandler.topic[cid] = 21 + elseif npcHandler.topic[cid] == 21 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough crystal coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] .. ' of your crystal coins into ' .. count[cid] * 100 .. ' platinum coins for you?', cid) + npcHandler.topic[cid] = 22 + end + elseif npcHandler.topic[cid] == 22 then + if msgcontains(msg, 'yes') then + if player:removeItem(2160, count[cid]) then + player:addItem(2152, count[cid] * 100) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough crystal coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'money'}, StdModule.say, {npcHandler = npcHandler, text = 'We can {change} money for you. You can also access your {bank account}.'}) +keywordHandler:addKeyword({'change'}, StdModule.say, {npcHandler = npcHandler, text = 'There are three different coin types in Tibia: 100 gold coins equal 1 platinum coin, 100 platinum coins equal 1 crystal coin. So if you\'d like to change 100 gold into 1 platinum, simply say \'{change gold}\' and then \'1 platinum\'.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'We can {change} money for you. You can also access your {bank account}.'}) +keywordHandler:addKeyword({'advanced'}, StdModule.say, {npcHandler = npcHandler, text = 'Your bank account will be used automatically when you want to {rent} a house or place an offer on an item on the {market}. Let me know if you want to know about how either one works.'}) +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'You can check the {balance} of your bank account, {deposit} money or {withdraw} it. You can also {transfer} money to other characters, provided that they have a vocation.'}) +keywordHandler:addKeyword({'functions'}, StdModule.say, {npcHandler = npcHandler, text = 'You can check the {balance} of your bank account, {deposit} money or {withdraw} it. You can also {transfer} money to other characters, provided that they have a vocation.'}) +keywordHandler:addKeyword({'basic'}, StdModule.say, {npcHandler = npcHandler, text = 'You can check the {balance} of your bank account, {deposit} money or {withdraw} it. You can also {transfer} money to other characters, provided that they have a vocation.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I work in this bank. I can change money for you and help you with your bank account.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Yes? What may I do for you, |PLAYERNAME|? Bank business, perhaps?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Have a nice day.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Have a nice day.") +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/siflind.lua b/data/npc/scripts/siflind.lua new file mode 100644 index 00000000000..658785b53c2 --- /dev/null +++ b/data/npc/scripts/siflind.lua @@ -0,0 +1,178 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.TheIceIslands.Questline) == 5 then + npcHandler:say("I heard you have already helped our cause. Are you interested in another mission, even when it requires you to travel to a distant land?", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 7 then + npcHandler:say("Well done. The termites caused just the distraction that we needed. Are you ready for the next step of my plan?", cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 9 then + npcHandler:say("You saved the lives of many innocent animals. Thank you very much. If you are looking for another mission, just ask me.", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 10) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 10 then + npcHandler:say("Our warriors need a more potent yet more secure berserker elixir to fight our enemies. To brew it, I need several ingredients. The first things needed are 5 bat wings. Bring them to me and Ill tell you the next ingredients we need.", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 11) + player:setStorageValue(Storage.TheIceIslands.Mission05, 1) -- Questlog The Ice Islands Quest, Nibelor 4: Berserk Brewery + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 11 then + npcHandler:say("Do you have the 5 bat wings I requested?", cid) + npcHandler.topic[cid] = 5 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 12 then + npcHandler:say("The second things needed are 4 bear paws. Bring them to me and Ill tell you the next ingredients we need.", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 13) + player:setStorageValue(Storage.TheIceIslands.Mission05, 2) -- Questlog The Ice Islands Quest, Nibelor 4: Berserk Brewery + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 13 then + npcHandler:say("Do you have the 4 bear paws I requested?", cid) + npcHandler.topic[cid] = 6 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 14 then + npcHandler:say("The next things needed are 3 bonelord eyes. Bring them to me and Ill tell you the next ingredients we need.", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 15) + player:setStorageValue(Storage.TheIceIslands.Mission05, 3) -- Questlog The Ice Islands Quest, Nibelor 4: Berserk Brewery + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 15 then + npcHandler:say("Do you have the 3 bonelord eyes I requested?", cid) + npcHandler.topic[cid] = 7 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 16 then + npcHandler:say("The next things needed are 2 fish fins. Bring them to me and Ill tell you the next ingredients we need.", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 17) + player:setStorageValue(Storage.TheIceIslands.Mission05, 4) -- Questlog The Ice Islands Quest, Nibelor 4: Berserk Brewery + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 17 then + npcHandler:say("Do you have the 2 fish fins I requested?", cid) + npcHandler.topic[cid] = 8 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 18 then + npcHandler:say("The last thing needed is a green dragon scale. Bring them to me and Ill tell you the next ingredients we need.", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 19) + player:setStorageValue(Storage.TheIceIslands.Mission05, 5) -- Questlog The Ice Islands Quest, Nibelor 4: Berserk Brewery + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheIceIslands.Questline) == 19 then + npcHandler:say("Do you have the green dragon scale I requested?", cid) + npcHandler.topic[cid] = 9 + else + npcHandler:say("I have now no mission for you.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "jug") then + npcHandler:say("Do you want to buy a jug for 1000 gold?", cid) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "I am pleased to hear that. On the isle of Tyrsung foreign hunters have set up camp. They are hunting the animals there with no mercy. We will haveto find something that distracts them from hunting ...", + "Take this jug here and travel to the jungle of Tiquanda. There you will find a race of wood eating ants called termites. Use the jug on one of their hills to catch some of them ...", + "Then find someone in Svargrond that brings you to Tyrsung. There, release the termites on the bottom of a mast in the hull of the hunters' ship. If you are done, report to me about your mission." + }, cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 6) + player:setStorageValue(Storage.TheIceIslands.Mission03, 1) -- Questlog The Ice Islands Quest, Nibelor 2: Ecological Terrorism + player:addItem(7243, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + if player:getMoney() + player:getBankBalance() >= 1000 then + player:removeMoneyNpc(1000) + npcHandler:say("Here you are.", cid) + npcHandler.topic[cid] = 0 + player:addItem(7243, 1) + end + elseif npcHandler.topic[cid] == 3 then + npcHandler:say("Good! Now listen. To protect the animals there, we have to harm the profit of the hunters. Therefor, I ask you to ruin their best source of earnings. Are you willing to do that?", cid) + npcHandler.topic[cid] = 4 + elseif npcHandler.topic[cid] == 4 then + npcHandler:say("So let's proceed. Take this vial of paint. Travel to Tyrsung again and ruin as many pelts of baby seals as possible before the paint runs dry or freezes. Then return here to report about your mission. ", cid) + player:addItem(7253, 1) + player:setStorageValue(Storage.TheIceIslands.Questline, 8) + player:setStorageValue(Storage.TheIceIslands.Mission04, 1) -- Questlog The Ice Islands Quest, Nibelor 3: Artful Sabotage + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 5 then -- Wings + if player:removeItem(5894, 5) then + npcHandler:say("Thank you very much.", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 12) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Come back when you do.", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 6 then -- Paws + if player:removeItem(5896, 4) then + npcHandler:say("Thank you very much.", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 14) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Come back when you do.", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 7 then -- Eyes + if player:removeItem(5898, 3) then + npcHandler:say("Thank you very much.", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 16) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Come back when you do.", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 8 then -- Fins + if player:removeItem(5895, 2) then + npcHandler:say("Thank you very much.", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 18) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Come back when you do.", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 9 then -- Scale + if player:removeItem(5920, 1) then + npcHandler:say("Thank you very much. This will help us to defend Svargrond. But I heard young Nilsor is in dire need of help. Please contact him immediately.", cid) + player:setStorageValue(Storage.TheIceIslands.Questline, 20) + player:setStorageValue(Storage.TheIceIslands.Mission05, 6) -- Questlog The Ice Islands Quest, Nibelor 4: Berserk Brewery + npcHandler.topic[cid] = 0 + else + npcHandler:say("Come back when you do.", cid) + end + npcHandler.topic[cid] = 0 + end + end + if msgcontains(msg, "buy animal cure") or msgcontains(msg, "animal cure") then -- animal cure for in service of yalahar + if player:getStorageValue(Storage.InServiceofYalahar.Questline) >= 30 and player:getStorageValue(Storage.InServiceofYalahar.Questline) <= 54 then + npcHandler:say("You want to buy animal cure for 400 gold coins?", cid) + npcHandler.topic[cid] = 13 + else + npcHandler:say("Im out of stock.", cid) + end + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 13 then + if npcHandler.topic[cid] == 13 and player:removeMoneyNpc(400) then + player:addItem(9734, 1) + npcHandler:say("Here you go.", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You dont have enough of gold coins.", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/sigurd.lua b/data/npc/scripts/sigurd.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/sigurd.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/silas.lua b/data/npc/scripts/silas.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/silas.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/simon_the_beggar.lua b/data/npc/scripts/simon_the_beggar.lua new file mode 100644 index 00000000000..0f543a8286b --- /dev/null +++ b/data/npc/scripts/simon_the_beggar.lua @@ -0,0 +1,239 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = "Alms! Alms for the poor!" }, + { text = "Sir, Ma'am, have a gold coin to spare?" }, + { text = "I need help! Please help me!" } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +-- Trade buy window +local shopModule = ShopModule:new() +npcHandler:addModule(shopModule) + +shopModule:addBuyableItem({"shovel"}, 2554, 50, 1) + +-- First beggar addon +local function BeggarFirst(cid, message, keywords, parameters, node) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if player:isPremium() then + if player:getStorageValue(Storage.OutfitQuest.BeggarFirstAddonDoor) == -1 then + if player:getItemCount(5883) >= 100 and player:getMoney() + player:getBankBalance() >= 20000 then + if player:removeItem(5883, 100) and player:removeMoneyNpc(20000) then + npcHandler:say("Ah, right! The beggar beard or beggar dress! Here you go.", cid) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:setStorageValue(Storage.OutfitQuest.BeggarFirstAddonDoor, 1) + player:addOutfitAddon(153, 1) + player:addOutfitAddon(157, 1) + end + else + npcHandler:say("You do not have all the required items.", cid) + end + else + npcHandler:say("It seems you already have this addon, don't you try to mock me son!", cid) + end + end +end + +-- Second beggar addon +local function BeggarSecond(cid, message, keywords, parameters, node) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if player:isPremium() then + if player:getStorageValue(Storage.OutfitQuest.BeggarSecondAddon) == -1 then + if player:getItemCount(6107) >= 1 then + if player:removeItem(6107, 1) then + npcHandler:say("Ah, right! The beggar staff! Here you go.", cid) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:setStorageValue(Storage.OutfitQuest.BeggarSecondAddon, 1) + player:addOutfitAddon(153, 2) + player:addOutfitAddon(157, 2) + end + else + npcHandler:say("You do not have all the required items.", cid) + end + else + npcHandler:say("It seems you already have this addon, don't you try to mock me son!", cid) + end + end +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "cookie") then + if player:getStorageValue(Storage.WhatAFoolish.Questline) == 31 + and player:getStorageValue(Storage.WhatAFoolish.CookieDelivery.SimonTheBeggar) ~= 1 then + npcHandler:say("Have you brought a cookie for the poor?", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "help") then + npcHandler:say("I need gold. Can you spare 100 gold pieces for me?", cid) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + if not player:removeItem(8111, 1) then + npcHandler:say("You have no cookie that I'd like.", cid) + npcHandler.topic[cid] = 0 + return true + end + + player:setStorageValue(Storage.WhatAFoolish.CookieDelivery.SimonTheBeggar, 1) + if player:getCookiesDelivered() == 10 then + player:addAchievement("Allow Cookies?") + end + + Npc():getPosition():sendMagicEffect(CONST_ME_GIFT_WRAPS) + npcHandler:say("Well, it's the least you can do for those who live in dire poverty. \z + A single cookie is a bit less than I'd expected, but better than ... WHA ... WHAT?? \z + MY BEARD! MY PRECIOUS BEARD! IT WILL TAKE AGES TO CLEAR IT OF THIS CONFETTI!", cid) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + elseif npcHandler.topic[cid] == 2 then + if not player:removeMoneyNpc(100) then + npcHandler:say("You haven't got enough money for me.", cid) + npcHandler.topic[cid] = 0 + return true + end + + npcHandler:say("Thank you very much. Can you spare 500 more gold pieces for me? I will give you a nice hint.", cid) + npcHandler.topic[cid] = 3 + elseif npcHandler.topic[cid] == 3 then + if not player:removeMoneyNpc(500) then + npcHandler:say("Sorry, that's not enough.", cid) + npcHandler.topic[cid] = 0 + return true + end + + npcHandler:say("That's great! I have stolen something from Dermot. \z + You can buy it for 200 gold. Do you want to buy it?", cid) + npcHandler.topic[cid] = 4 + elseif npcHandler.topic[cid] == 4 then + if not player:removeMoneyNpc(200) then + npcHandler:say("Pah! I said 200 gold. You don't have that much.", cid) + npcHandler.topic[cid] = 0 + return true + end + + local key = player:addItem(2087, 1) + if key then + key:setActionId(3940) + end + npcHandler:say("Now you own the hot key.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "no") and npcHandler.topic[cid] ~= 0 then + if npcHandler.topic[cid] == 1 then + npcHandler:say("I see.", cid) + elseif npcHandler.topic[cid] == 2 then + npcHandler:say("Hmm, maybe next time.", cid) + elseif npcHandler.topic[cid] == 3 then + npcHandler:say("It was your decision.", cid) + elseif npcHandler.topic[cid] == 4 then + npcHandler:say("Ok. No problem. I'll find another buyer.", cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +-- Node 1 +node1 = keywordHandler:addKeyword({"addon"}, StdModule.say, + { + npcHandler = npcHandler, + text = "For the small fee of 20000 gold pieces I will help you mix this potion. \z + Just bring me 100 pieces of ape fur, which are necessary to create this potion. ... Do we have a deal?" + } +) +node1:addChildKeyword({"yes"}, BeggarSecond, {}) +node1:addChildKeyword({"no"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Alright then. Come back when you got all neccessary items.", + reset = true + } +) + +-- Node 2 +node2 = keywordHandler:addKeyword({"dress"}, StdModule.say, + { + npcHandler = npcHandler, + text = "For the small fee of 20000 gold pieces I will help you mix this potion. \z + Just bring me 100 pieces of ape fur, which are necessary to create this potion. ...Do we have a deal?" + } +) +node2:addChildKeyword({"yes"}, BeggarFirst, {}) +node2:addChildKeyword({"no"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Alright then. Come back when you got all neccessary items.", + reset = true + } +) + +-- Node 3 +node3 = keywordHandler:addKeyword({"staff"}, StdModule.say, + { + npcHandler = npcHandler, + text = "To get beggar staff you need to give me simon the beggar's staff. Do you have it with you?" + } +) +node3:addChildKeyword({"yes"}, BeggarSecond, {}) +node3:addChildKeyword({"no"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Alright then. Come back when you got all neccessary items.", + reset = true + } +) + +-- Node 4 +node4 = keywordHandler:addKeyword({"outfit"}, StdModule.say, + { + npcHandler = npcHandler, + text = "For the small fee of 20000 gold pieces I will help you mix this potion. \z + Just bring me 100 pieces of ape fur, which are necessary to create this potion. ...Do we have a deal?" + } +) +node4:addChildKeyword({"yes"}, BeggarFirst, {}) +node4:addChildKeyword({"no"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Alright then. Come back when you got all neccessary items.", + reset = true + } +) + +npcHandler:setMessage(MESSAGE_GREET, "Hello |PLAYERNAME|. I am a poor man. Please help me.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Have a nice day.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Have a nice day.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/sinatuki.lua b/data/npc/scripts/sinatuki.lua new file mode 100644 index 00000000000..8c2cd63c512 --- /dev/null +++ b/data/npc/scripts/sinatuki.lua @@ -0,0 +1,53 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'Chuqua'}, StdModule.say, {npcHandler = npcHandler, text = "Chuqua jamjam!! Tiyopa Sinatuki?"}) + +local fishsID = {7158,7159} + +function creatureSayCallback(cid, type, msg) + +local player = Player(cid) + + if(not npcHandler:isFocused(cid)) then + return false + end + + if msgcontains(msg, 'Nupi') then + if player:getStorageValue(Storage.BarbarianTest.Questline) >= 3 and player:getStorageValue(Storage.TheIceIslands.Questline) >=5 then + for i=1, #fishsID do + if player:getItemCount(fishsID[i]) >= 100 then + player:removeItem(fishsID[i], 100) + player:addItem(7290, 5) + npcHandler:say("Jinuma, suvituka siq chuqua!! Nguraka, nguraka! ", cid) + break + elseif player:getItemCount(fishsID[i]) >= 99 then + player:removeItem(fishsID[i], 99) + player:addItem(7290, 5) + npcHandler:say("Jinuma, suvituka siq chuqua!! Nguraka, nguraka! ", cid) + break + else + npcHandler:say("Kisavuta! ", cid) + end + end + end + end +return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/sinclair.lua b/data/npc/scripts/sinclair.lua new file mode 100644 index 00000000000..14427fd66b5 --- /dev/null +++ b/data/npc/scripts/sinclair.lua @@ -0,0 +1,135 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Indeed, there has to be some other way.' }, + { text = 'Mmh, interesting.' }, + { text = 'Yes indeed, all of the equipment should be checked and calibrated regularly.' }, + { text = 'No, we have to give this another go.' } +} + +local function releasePlayer(cid) + if not Player(cid) then + return + end + + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + + if msgcontains(msg, 'mission') then + local qStorage = player:getStorageValue(Storage.SpiritHunters.Mission01) + if qStorage == 3 then + npcHandler:say("So, did you find anything worth examining? Did you actually catch a ghost?",cid) + npcHandler.topic[cid] = 3 + elseif qStorage == 2 then + npcHandler:say({"So you have passed Spectulus' acceptance test. Well, I'm sure you will live up to that. ...", + "We are trying to get this business up and running and need any help we can get. Did he tell you about the spirit cage?" + }, cid) + npcHandler.topic[cid] = 1 + elseif qStorage > 2 then + npcHandler:say("You already done this quest.",cid) + npcHandler.topic[cid] = 0 + elseif qStorage < 2 then + npcHandler:say("Talk research with spectulus to take some mission.",cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + npcHandler:say({"Excellent. Now we need to concentrate on testing that thing. The spirit cage has been calibrated based on some tests we made - as well as your recent findings over at the graveyard. ...", + "Using the device on the remains of a ghost right after its defeat should capture it inside this trap. We could then transfer it into our spirit chamber which is in fact a magical barrier. ..", + "At first, however, we need you to find a specimen and bring it here for us to test the capacity of the device. Are you ready for this?" + }, cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say("Good, now all you need to do is find a ghost, defeat it and catch its very essence with the cage. Once you have it, return to me and Spectulus and I will move it into our chamber device. Good luck, return to me as soon as you are prepared.", cid) + player:setStorageValue(Storage.SpiritHunters.Mission01, 3) + player:addItem(12671, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + if player:getStorageValue(Storage.SpiritHunters.CharmUse) == 1 then + npcHandler:say({"Fascinating, let me see. ...", + "Amazing! I will transfer this to our spirit chamber right about - now! ...", + "Alright, the device is holding it. The magical barrier should be able to contain nearly 20 times the current load. That's a complete success! Spectulus, are you seeing this? We did it! ...", + "Well, you did! You really helped us pulling this off. Thank you Lord Stalks! ...", + "I doubt we will have much time to hunt for new specimens ourselves in the near future. If you like, you can continue helping us by finding and capturing more and different ghosts. Just talk to me to receive a new task." + }, cid) + player:setStorageValue(Storage.SpiritHunters.Mission01, 4) + player:addExperience(500, true) + addEvent(releasePlayer, 1000, cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Go and use the machine in a dead ghost!", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 4 then + npcHandler:say({"Magnificent! Alright, we will at least need 5 caught ghosts. We will pay some more if you can catch 5 nightstalkers. Of course you will earn some more if you bring us 5 souleaters. ...", + "I heard they dwell somewhere in that new continent - Zao? Well anyway, if you feel you've got enough, just return with what you've got and we will see. Good luck! ...", + "Keep in mind that the specimens are only of any worth to us if the exact amount of 5 per specimen is reached. ...", + "Furhtermore, to successfully bind Nightstalkers to the cage, you will need to have caught at least 5 Ghosts. To bind Souleaters, you will need at least 5 Ghosts and 5 Nightstalkers. ...", + "The higher the amount of spirit energy in the cage, the higher its effective capacity. Oh and always come back and tell me if you lose your spirit cage." + }, cid) + player:setStorageValue(Storage.SpiritHunters.Mission01, 5) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 5 then + npcHandler:say("Good, of course you will also receive an additional monetary reward for your troubles. Are you fine with that?", cid) + npcHandler.topic[cid] = 6 + elseif npcHandler.topic[cid] == 6 then + local nightstalkers, souleaters, ghost = player:getStorageValue(Storage.SpiritHunters.NightstalkerUse), player:getStorageValue(Storage.SpiritHunters.SouleaterUse), player:getStorageValue(Storage.SpiritHunters.GhostUse) + if nightstalkers >= 4 and souleaters >= 4 and ghost >= 4 then + npcHandler:say("Alright, let us see how many ghosts you caught!", cid) + player:setStorageValue(Storage.SpiritHunters.Mission01, 6) + player:addExperience(8000, true) + player:addItem(2152, 60) + addEvent(releasePlayer, 1000, cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You didnt catch the ghost pieces.", cid) + npcHandler.topic[cid] = 0 + end + end + elseif msgcontains(msg, 'research') then + local qStorage = player:getStorageValue(Storage.SpiritHunters.Mission01) + if qStorage == 4 then + npcHandler:say({"We are still in need of more research concerning environmental as well as psychic ecto-magical influences. Besides more common ghosts we also need some of the harder to come by nightstalkers and - if you're really hardboiled - souleaters. ...", + "We will of course pay for every ghost you catch. You will receive more if you hunt for some of the tougher fellows - but don't overdue it. What do you say?" + }, cid) + npcHandler.topic[cid] = 4 + elseif qStorage == 5 then + npcHandler:say(" Alright you found something! Are you really finished hunting out there?", cid) + npcHandler.topic[cid] = 5 + end + end + + return true +end + +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "Greetings |PLAYERNAME|. I have - very - little time, please make it as short as possible. I may be able to help you if you are here to help us with any of our tasks or missions.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Goodbye and good luck |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Goodbye and good luck |PLAYERNAME|.") + +npcHandler:addModule(FocusModule:new()) + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) diff --git a/data/npc/scripts/sirik.lua b/data/npc/scripts/sirik.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/sirik.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/sister_of_jack.lua b/data/npc/scripts/sister_of_jack.lua new file mode 100644 index 00000000000..76521c1bd56 --- /dev/null +++ b/data/npc/scripts/sister_of_jack.lua @@ -0,0 +1,85 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "jack") then + if (player:getStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine) == 5) then + if + (player:getStorageValue(Storage.TibiaTales.JackFutureQuest.Mother == 1) and + (player:getStorageValue(Storage.TibiaTales.JackFutureQuest.Sister)) < 1) + then + npcHandler:say("Why are you asking, he didn't get himself into something again did he?", cid) + npcHandler.topic[cid] = 1 + end + end + elseif msgcontains(msg, "spectulus") then + if (npcHandler.topic[cid] == 3) then + npcHandler:say( + "Spelltolust?! That sounds awfully nasty! What was he doing there - are you telling \z + me he lived an alternate life and he didn't even tell {mother}?", + cid + ) + npcHandler.topic[cid] = 4 + end + elseif msgcontains(msg, "yes") then + if (npcHandler.topic[cid] == 1) then + npcHandler:say( + { + "I knew it! He likes taking extended walks outside, leaving all the cleaning to me - \z + especially when he is working on this sculpture, this... 'thing' he tries to create. ...", + "What did he do? Since you look like a guy from the city, I bet he went to Edron in \z + secrecy or something like that, didn't he? And you are here because of that?" + }, + cid + ) + npcHandler.topic[cid] = 2 + elseif (npcHandler.topic[cid] == 2) then + npcHandler:say("What?! And what did he do there? Who did he visit there?", cid) + npcHandler.topic[cid] = 3 + elseif (npcHandler.topic[cid] == 4) then + npcHandler:say( + { + "Yesss! So this time he will get it for a change! And he lived there...? He helped whom? \z + Ha! He won't get away this time! What did he do there? I see... interesting! ...", + "Wait till mother hears that! Oh he will be in for a surprise, I can tell you that. Ma!! Maaaaa!!" + }, + cid + ) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.TibiaTales.JackFutureQuest.Sister, 1) + player:setStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine, 6) + end + end + return true +end + +local voices = { + {text = "Where did I put my broom? Mother?"}, + {text = "Mother?! Oh no, now I have to do this all over again"}, + {text = "Mhmhmhmhm."}, + {text = "Lalala..."} +} + +npcHandler:addModule(VoiceModule:new(voices)) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_GREET, "Mh hello there. What can I do for you?") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/skeleton_guard.lua b/data/npc/scripts/skeleton_guard.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/skeleton_guard.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/skip.lua b/data/npc/scripts/skip.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/skip.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/skjaar.lua b/data/npc/scripts/skjaar.lua new file mode 100644 index 00000000000..df9c596a881 --- /dev/null +++ b/data/npc/scripts/skjaar.lua @@ -0,0 +1,61 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, 'key') then + npcHandler:say('I will give the key to the crypt only to the closest followers of my master. Would you like me to test you?', cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, 'yes') and npcHandler.topic[cid] == 1 then + npcHandler:say('Before we start I must ask you for a small donation of 1000 gold coins. Are you willing to pay 1000 gold coins for the test?', cid) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, 'yes') and npcHandler.topic[cid] == 2 then + if player:removeMoneyNpc(1000) then + npcHandler:say('All right then. Here comes the first question. What was the name of Dago\'s favourite pet?', cid) + npcHandler.topic[cid] = 3 + else + npcHandler:say('You don\'t have enough money', cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'redips') and npcHandler.topic[cid] == 3 then + npcHandler:say('Perhaps you knew him after all. Tell me - how many fingers did he have when he died?', cid) + npcHandler.topic[cid] = 4 + elseif msgcontains(msg, '7') and npcHandler.topic[cid] == 4 then + npcHandler:say('Also true. But can you also tell me the colour of the deamons in which master specialized?', cid) + npcHandler.topic[cid] = 5 + elseif msgcontains(msg, 'black') and npcHandler.topic[cid] == 5 then + npcHandler:say('It seems you are worthy after all. Do you want the key to the crypt?', cid) + npcHandler.topic[cid] = 6 + elseif msgcontains(msg, 'yes') and npcHandler.topic[cid] == 6 then + npcHandler:say('Here you are', cid) + local key = player:addItem(2089, 1) + if key then + key:setActionId(3142) + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Another creature who believes thinks physical strength is more important than wisdom! Why are you disturbing me?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Farewell, |PLAYERNAME|!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Run away, unworthy |PLAYERNAME|!") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/smiley.lua b/data/npc/scripts/smiley.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/smiley.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/snake_eye.lua b/data/npc/scripts/snake_eye.lua new file mode 100644 index 00000000000..00d22dfaeaa --- /dev/null +++ b/data/npc/scripts/snake_eye.lua @@ -0,0 +1,39 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, 'package for rashid') then + if player:getStorageValue(Storage.TravellingTrader.Mission02) >= 1 and player:getStorageValue(Storage.TravellingTrader.Mission02) < 3 then + npcHandler:say('So you\'re the delivery boy? Go ahead, but I warn you, it\'s quite heavy. You can take it from the box over there.', cid) + player:setStorageValue(Storage.TravellingTrader.Mission02, 3) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'documents') then + if player:getStorageValue(Storage.ThievesGuild.Mission04) == 1 then + player:setStorageValue(Storage.ThievesGuild.Mission04, 2) + npcHandler:say('Funny thing that everyone thinks we have forgers for fake documents here. But no, we don\'t. The best forger is old Ahmet in Ankrahmun.', cid) + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/soilance.lua b/data/npc/scripts/soilance.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/soilance.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/sorcerer_estrella.lua b/data/npc/scripts/sorcerer_estrella.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/sorcerer_estrella.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/spectulus.lua b/data/npc/scripts/spectulus.lua new file mode 100644 index 00000000000..81ffcb143ef --- /dev/null +++ b/data/npc/scripts/spectulus.lua @@ -0,0 +1,889 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + {text = "Precisely."}, + {text = "So my initial calculations had been correct!"}, + {text = "Looks like I have to find another way then."}, + {text = "Hm, I need to recapitulate my equipment..."} +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local function greetCallback(cid) + local player = Player(cid) + + if player:getStorageValue(Storage.SeaOfLight.Questline) < 10 then + npcHandler:setMessage( + MESSAGE_GREET, + "Hello |PLAYERNAME|! You're late, do you have no concept of time? My mission is of utmost importance. If you are not interested in helping me, you might as well just leave." + ) + npcHandler.topic[cid] = 0 + else + npcHandler:setMessage( + MESSAGE_GREET, + "Ah hello again |PLAYERNAME|! I still have one or two other {missions} for you. There are also some {tasks} someone needs to attend to." + ) + npcHandler.topic[cid] = 0 + end + return true +end + +local function releasePlayer(cid) + if not Player(cid) then + return + end + + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "research") then + local qStorage = player:getStorageValue(Storage.SpiritHunters.Mission01) + local tombsStorage = player:getStorageValue(Storage.SpiritHunters.TombUse) + if qStorage == -1 then + if npcHandler.topic[cid] == 17 then + npcHandler:say( + { + "Alright. Let's go. At first we need to find out more about ghosts in general. ...", + "I still need more information and values to properly calibrate the magical orientation of orange \z + and turquoise sparkle attractors which we will need to actually contain ghost-emissions. ...", + "So are you in?" + }, + cid, + false, + true, + 200 + ) + npcHandler.topic[cid] = 18 + else + npcHandler:say( + { + "I fine-tuned another set of devices. You are the lucky candidate to first lay eyes on some revolutionary \z + new concepts. ...", + "Are you ready to help science once again?" + }, + cid, + false, + true, + 200 + ) + npcHandler.topic[cid] = 12 + end + elseif qStorage == 1 and tombsStorage >= 2 then + npcHandler:say("You are back, how did the measurements go? Did you recognise anything of interest?", cid) + npcHandler.topic[cid] = 19 + elseif qStorage == 2 then + npcHandler:say( + { + "Alright, now that we have enough results, the analysing can start. While I do this, I will need you \z + to test the magically enhanced cage Sinclair developed to contain spirits effectively. ...", + "Take the spirit cage from him and use it on the essence of a common ghost. Its essence will then be \z + sucked into the cage and we can study him right here in the safety of the academy walls." + }, + cid, + false, + true, + 200 + ) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "mission") then + if player:getStorageValue(Storage.SeaOfLight.Questline) == -1 then + npcHandler:say( + "Alright, you look bright enough to fulfil my requests - at least you do not fall asleep while standing there. \z + Ahem... I heard about a certain inventor who created a {magic device} to actually sail the {sea of light}. \z + Will you help me find him?", + cid, + false, + true, + 200 + ) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.SeaOfLight.Questline) == 1 then + npcHandler:say( + "You should find the beggar somewhere in Edron. Stay persistent, \z + I'm sure he knows more than he wants to tell us.", + cid + ) + elseif player:getStorageValue(Storage.SeaOfLight.Questline) == 2 then + if not player:removeItem(10613, 1) then + npcHandler:say( + "o have you talked to the beggar? What did he tell you? Where are the plans...? Wh...? He did? He is? \z + You've already got the plans? Beautiful!! Amazing! Alright it will take some time to recapitulate these plans.", + cid, + false, + true, + 200 + ) + return true + end + + player:addExperience(400, true) + player:setStorageValue(Storage.SeaOfLight.Questline, 3) + player:setStorageValue(Storage.SeaOfLight.Mission1, 3) + player:setStorageValue(Storage.SeaOfLight.StudyTimer, os.time() + 1800) + npcHandler:say( + "So have you talked to the beggar? What did he tell you? Where are the plans...? Wh...? He did? He is? \z + You've already got the plans? Beautiful!! Amazing! Alright it will take some time to recapitulate these plans.", + cid, + false, + true, + 200 + ) + addEvent(releasePlayer, 1000, cid) + elseif player:getStorageValue(Storage.SeaOfLight.Questline) == 3 then + local timeStorage = player:getStorageValue(Storage.SeaOfLight.StudyTimer) + if timeStorage > os.time() then + npcHandler:say( + "It will take some time to work out the initial problem of the device. Come back when I've found the \z + component needed to finish it. Alright, B connects to D and another two nails marked with S go... hmmm.", + cid, + false, + true, + 200 + ) + elseif timeStorage > 0 and timeStorage < os.time() then + npcHandler:say( + "...connects to N942. Alright!! That's it! I just finished a prototype device! And it looks like I \z + figured out the initial failure. A very special crystal is needed for the device to work. Aren't \z + you as curious as me to know what went wrong?", + cid, + false, + true, + 200 + ) + npcHandler.topic[cid] = 2 + end + elseif player:getStorageValue(Storage.SeaOfLight.Questline) == 4 then + npcHandler:say( + "Did you enter the Lost Mines yet? They are west of Edron, close to the sea. You will also need a \z + pick once you get to the crystal deposit.", + cid, + false, + true, + 200 + ) + elseif player:getStorageValue(Storage.SeaOfLight.Questline) == 5 then + if player:getItemCount(10614) == 0 then + npcHandler:say( + "Hm, so did you find a rare crystal? Show me... hey! That's not a rare crystal. What... where did \z + you get that anyway? Please return to me with the right crystal.", + cid, + false, + true, + 200 + ) + return true + end + player:addExperience(500, true) + player:setStorageValue(Storage.SeaOfLight.Questline, 6) + player:setStorageValue(Storage.SeaOfLight.Mission2, 3) + npcHandler:say( + { + "Did you find a rare crystal? Show me... Amazing, absolutely amazing. This crystal alone is worth \z + a small fortune. Ahem, of course I'm glad you brought it to me for further research instead of \z + bringing it to a merchant. ...", + "Please return here if you want to continue helping me with another mission." + }, + cid, + false, + true, + 200 + ) + addEvent(releasePlayer, 1000, cid) + elseif player:getStorageValue(Storage.SeaOfLight.Questline) == 6 then + npcHandler:say( + "Well, the only thing left to do would be to offer the crystal at the well of the collector. There \z + must be a pedestal near the well, where you need to put your donation. Ha, do you think you could do that?", + cid + ) + npcHandler.topic[cid] = 5 + elseif player:getStorageValue(Storage.SeaOfLight.Questline) == 7 then + npcHandler:say( + "Found the well yet? Look on one of the ice isles near Carlin. I'm perfectly sure that the well \z + with the pedestal is located on one of them. And be careful with the carrying device, I only have \z + this one prototype.", + cid, + false, + true, + 200 + ) + elseif player:getStorageValue(Storage.SeaOfLight.Questline) == 8 then + npcHandler:say( + "So have you found the well and entered the lair? I hope you can find the {mirror crystal}\z + in there. It is the only way to finish the {Lightboat}.", + cid + ) + elseif player:getStorageValue(Storage.SeaOfLight.Questline) == 9 then + if player:getItemCount(10616) == 0 then + npcHandler:say( + "Put the mirror crystal into the special carrying device \z + I gave you and bring it directly to me.", + cid + ) + return true + end + npcHandler:say( + "Do you have the mirror crystal? Unbelievable! Alright I will extract the crystal from the device \z + myself, would you please give me the device with the crystal and step back?", + cid + ) + npcHandler.topic[cid] = 7 + elseif + (player:getStorageValue(Storage.SeaOfLight.Questline) == 10) and + (player:getStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine) < 1) + then + npcHandler:say( + "After the debacle with the crystal, I started focussing on other things. There are also some {tasks} \z + that still need to be done. If you can spare the time to continue helping me, it shall not be to your \z + disadvantage. So are you in for another mission?", + cid, + false, + true, + 200 + ) + npcHandler.topic[cid] = 27 + elseif player:getStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine) == 2 then + npcHandler:say("So you found him? Have you talked to {Jack} yet?", cid) + npcHandler.topic[cid] = 30 + elseif player:getStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine) == 4 then + npcHandler:say( + "You're back from {Jack}! Mh, by the looks of your face I doubt our little redecoration \z + project yielded any success. But I had an even better idea while you were gone - ready to give it another try?", + cid + ) + npcHandler.topic[cid] = 32 + elseif player:getStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine) == 6 then + npcHandler:say("So, did you talk to his family? Were you able to convince them?", cid) + npcHandler.topic[cid] = 33 + elseif player:getStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine) == 8 then + npcHandler:say( + "Did you find out what hobby {Jack} has? Did you separate him from this activity? \z + Only if he has a free mind, he can truly get back to his former self! Now all you need to do is talk to him again!", + cid + ) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine) == 9 then + npcHandler:say( + { + "Oh you are back already. Hm... I doubt it worked, did it? It DID? Oh well... good job. Really! \z + Now... the thing is - the actual {Jack} wrote. No, no wait. Calm down first. ...", + "You remember me explaining the fold in time, causing a tiny disturbance in infinity? Well, as I \z + already told you, {Jack} was indeed not transported to the future... but to the past. ...", + "I received some kind of letter this morning that has been stored for me by the Academy for \z + about 70 years now. ...", + "It said it should be opened at a specific day 20 years ago to prevent this whole incident but I \z + wasn't even at the Academy by that time. Someone just found the letter earlier today and brought \z + it to my attention. ...", + "So our {Jack} here was in fact... a completely different person. Now, now... don't get upset, \z + there was no chance for me to warn you earlier! ...", + "And it wasn't all that bad, was it? Heh... I mean... everyone needs a change in life now and then! \z + And he can still come here if he likes to! ...", + "Or wait - erm... better not tell him where exactly I live, I have some kind of presentiment concerning \z + that whole affair... yes, we should just leave everything as it is now, indeed we should. ...", + "Anyway you did a great job and I thank you for... putting your hands into my fire Player... once again." + }, + cid + ) + player:addExperience(6000, true) + player:setStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine, 10) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + player:addExperience(100, true) + player:setStorageValue(Storage.SeaOfLight.Questline, 1) + player:setStorageValue(Storage.SeaOfLight.Mission1, 1) + npcHandler:say( + { + "That's the spirit! As time is of the essence, we should start right now. ...", + "A beggar here in Edron brags about how smart he is and that he knows about a man who lost his \z + sanity because of an experiment, but he won't tell anyone any details. Maybe he knows more." + }, + cid, + false, + true, + 200 + ) + addEvent(releasePlayer, 1000, cid) + elseif npcHandler.topic[cid] == 2 then + npcHandler:say( + "The device needs a special crystal. It's called {mirror crystal}. The inventor somehow damaged it \z + - with fatal results. He had to give up, as no second crystal was left to try. I, however, know of \z + another one... but are you up to the task?", + cid + ) + npcHandler.topic[cid] = 3 + elseif npcHandler.topic[cid] == 3 then + npcHandler:say( + "One remaining mirror crystal is in the hands of a creature called the collector which collects all \z + kinds of crystals. The only way to get access to its lair is to donate a very rare crystal to a secret \z + well. I need you to get one, will you help me?", + cid + ) + npcHandler.topic[cid] = 4 + elseif npcHandler.topic[cid] == 4 then + player:setStorageValue(Storage.SeaOfLight.Questline, 4) + player:setStorageValue(Storage.SeaOfLight.Mission1, 4) + player:setStorageValue(Storage.SeaOfLight.Mission2, 1) + player:addMapMark(Position(33103, 31811, 7), MAPMARK_CROSS, "Lost Mines") + npcHandler:say( + { + "Alright, now listen. West of Edron, near the ocean, you'll find the Lost Mines. Go down there \z + to recover one of its rare crystals. But beware, people say the mine workers who died there years \z + ago in an horrible accident are still digging. ...", + "I will mark the location of the mines on your map. Be careful when entering these muddy depths and \z + don't forget that you will need a pick to gather the crystals." + }, + cid, + false, + true, + 200 + ) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 5 then + npcHandler:say( + "Good, because if you wouldn't do it... listen, this well is on one of the isles near Carlin. \z + There you offer the crystal. Once you get access to its lair, find the collector and... convince it to give \z + you the mirror crystal. Understood?", + cid + ) + npcHandler.topic[cid] = 6 + elseif npcHandler.topic[cid] == 6 then + player:setStorageValue(Storage.SeaOfLight.Questline, 7) + player:setStorageValue(Storage.SeaOfLight.Mission3, 1) + player:addItem(10615, 1) + npcHandler:say( + "To collect the unbelievably rare, practically unique mirror crystal, you will need to use this \z + special carrying device I developed. If you find the crystal, use it to store it and transport it \z + safely to me. There is no second one.", + cid + ) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 7 then + if not player:removeItem(10616, 1) then + npcHandler:say("", cid) + npcHandler.topic[cid] = 0 + return true + end + player:addItem(2145, 10) + player:addItem(2154, 1) + player:addExperience(1000, true) + player:setStorageValue(Storage.SeaOfLight.Mission3, 4) + player:setStorageValue(Storage.SeaOfLight.Questline, 10) + npcHandler:say( + { + "Ah yes, slowly, carefully, careful ...", + "...and how shiny it is, almost there ...", + "...now wh- no, NO, NOOO! It just ...", + "...slipped. And cracked. Don't look at me like that ...", + "...I need some time to get over this. What? Oh, yes you can take the remains if you like. \z + Just get it out of my sight." + }, + cid, + false, + true, + 200 + ) + addEvent(releasePlayer, 1000, cid) + elseif npcHandler.topic[cid] == 12 then + npcHandler:say( + "Of course you are. And here we go. I have to ask some questions first. One: You aint \z + afraid of no ghost, right?", + cid + ) + npcHandler.topic[cid] = 13 + elseif npcHandler.topic[cid] == 13 then + npcHandler:say( + "Good. Two: You know that ghosts exist and/or have found and/or defeated \z + one or more of them?", + cid + ) + npcHandler.topic[cid] = 14 + elseif npcHandler.topic[cid] == 14 then + npcHandler:say( + { + "Alright. Let's see - yes. ...", + "Three: You can explain at least three of the following terms, infestations, \z + collective apparitions, ectoplasmic segregations, ecto-magical field phenomena, \z + neuro-speculative sub-conscious awareness of spirits, ghosts and/or ghasts." + }, + cid, + false, + true, + 200 + ) + npcHandler.topic[cid] = 15 + elseif npcHandler.topic[cid] == 16 then + npcHandler:say( + { + "I recently teamed up with a fellow scientist and friend Sinclair, who is also more \z + of an explorer than me, to combine our discoveries in the field of complex phenomena \z + not that easily to describe just by today's state of magic. ...", + "Of course I am talking about ghosts. I know, I know. Hard to believe in those times \z + of highly advanced magic we live in. Yet there are some things, we fail to explain. ...", + "And that is exactly where we come in! Oh, and you of course. We will not only explain \z + them - we will ''remove'' them. Just tell me whenever you are ready to help us with our research." + }, + cid, + false, + true, + 200 + ) + npcHandler.topic[cid] = 17 + elseif npcHandler.topic[cid] == 18 then + npcHandler:say( + "Good. Take this wand - we call it a spirit meter - and go to the graveyard I have \z + marked on your map and take a few measurements on the graves.", + cid + ) + player:setStorageValue(Storage.SpiritHunters.Mission01, 1) + player:addItem(12670, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 19 then + npcHandler:say( + "Let me see the spirit meter. Hmmm... those are grave news you bring - uhm, you \z + know what I mean. But this is awesome! Now I know for sure that the calibration is \z + only some short bursts of magically enhanced energy away.", + cid + ) + player:addExperience(500, true) + player:addItem(2152, 5) + addEvent(releasePlayer, 1000, cid) + player:setStorageValue(Storage.SpiritHunters.Mission01, 2) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 27 then + npcHandler:say( + { + "Very well, hmmm, but this one might get a bit - unpleasant. What? No no, not for you. Probably only \z + for the person I want you to help me with. You know, I once had an {intern}. His name was {Jack}. ...", + "He was as eager as you to help me - quite a nice person, really. At the time he was still around I was \z + working on a device to transport its user to any specified point in time - be it back or to the future \z + if you know what I mean. ...", + "He was helping me quite a lot, no matter which task I applied to him. And one day we finally did it, our \z + tempus machina was up and running. He was certainly all man of action when he actually stepped into the \z + machine for our first run. ...", + "The device was designed for one person with enough room for some provisions and one or two books for reading \z + if one would land in some drab solitude. You never know, you know? So we fired it up and yes, it actually \z + worked! ...", + "He completely disappeared right before my eyes! Eureka! Well ahem, there was but one tiny little problem. ...", + "As all magical calibration was done from my lab I never thought about adding some sort of control to its \z + interior. In other words {Jack} has travelled in time, without any means to come back. ...", + "Sleepless days of intensive research, however, brought me to the conclusion that he was not actually \z + travelling to the future, but to another {dimension}, {parallel} to ours. There is still a chance to rescue \z + him - and you can help me. What do you say?" + }, + cid, + false, + true, + 200 + ) + npcHandler.topic[cid] = 28 + elseif npcHandler.topic[cid] == 28 then + npcHandler:say( + { + "You know, in some way you remind me of {Jack}. Well, I am glad you are up to this task - we just have \z + to get him back. I owe that to him and I owe it to science. Alright, now let me explain that whole \z + {dimensional} problem. ...", + "The bad news is, using the device at that state was not a good idea. We effectively caused a magical \z + distortion in the fabric of time, space and thus folded infinity - just a little. ...", + "The good news is that {Jack} is still on our world, and not even inconveniently far away. ...", + "Unfortunately in the current state of time, he was never interested in attending Edron Academy, he \z + never looked for a job to finance his studies and of course has never been one of my interns. ...", + "Since he was in the magic sphere during the launch, the time fold only affected his own {dimensional} \z + anchoring. ...", + "The number of parallel {dimensions} is endless and the fold made him slip into one completely different \z + course of time where he never was the person I once knew. ...", + "Now you know it all. Still want to help?" + }, + cid, + false, + true, + 200 + ) + npcHandler.topic[cid] = 29 + elseif npcHandler.topic[cid] == 29 then + npcHandler:say( + { + "Thank you. So here we are - now how to get {Jack} back to our {dimension}? Well, the answer to that \z + is easy. It is simply not possible. All my tests concerning the reversal of the process failed. ...", + "But {Jack} is not yet lost to us - if we can get him back to his former self! You have to tell him \z + about his former life, convince him, change his environment. But at first you will need to talk to him \z + and find out who exactly we are dealing with now. ...", + "I will mark his current location on your map, just ask him about me and see what happens - good luck." + }, + cid, + false, + true, + 200 + ) + player:setStorageValue(Storage.SeaOfLight.Questline, 11) + player:setStorageValue(Storage.TibiaTales.DefaultStart, 1) + player:setStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 30 then + npcHandler:say( + "Yes? And he didn't remember anything? Not even me? That's not good. Then we will have to \z + do everything ourselves. Are you ready to continue?", + cid + ) + npcHandler.topic[cid] = 31 + elseif npcHandler.topic[cid] == 31 then + npcHandler:say( + { + "A trigger is needed to make him recall what happened. First thing should be to change his \z + environment to be more... familiar. As soon as he will have the things he used to have around \z + him, his memories will come back. ...", + "I know that he used to have a very comfy red cushioned chair and an old globe which sat near \z + the middle of the room. He also used a smaller telescope and he had that extremely large amphora \z + in a corner. And... there was one other thing. ...", + "A rocking horse. He just loved it! Find these items, buy them if you need to and place them \z + where {Jack} lives. Ask him about the furniture and don't forget to tell me about his reaction!" + }, + cid, + false, + true, + 200 + ) + player:setStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine, 3) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 32 then + npcHandler:say( + { + "Alright listen. As long as his social environment accepts him as the person he is now, \z + he will never come free from the shackles that bind him to this alternate self. ...", + "Oh, he has a sister you say? And his mother is living with them? ...", + "Hm... that's strange, I don't even recall his family. Never knew he had a mother and a \z + sister. Tell them the truth about him - maybe they will understand and even help him getting \z + this over with. ...", + "But be careful, the {dimensional} shift could mean that they will not even know what you're \z + talking about since they are more closely linked to him than anyone else." + }, + cid, + false, + true, + 200 + ) + player:setStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine, 5) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 33 then + npcHandler:say( + { + "Success!! Now it will be far easier to convince him of his true self! Excellent work. \z + Now the only thing left to do is to separate him from whatever still binds him to that place. \z + Did he develop any habits perhaps? ...", + "A hobby or something! Yes, ask him about his hobbies! Convince him somehow that anything he is \z + doing there does not match his true self - he didn't have any hobbies except a healthy interest in \z + science - you MUST convince him, no matter what! ...", + "Or everything we achieved would be in vain. We can still save Jack! Now go and do what you must do." + }, + cid, + false, + true, + 200 + ) + player:setStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine, 7) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "jack") then + if player:getStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine) == 10 then + npcHandler:say( + { + "Well you know Jack - after all you talked to him in person. He will get over it. \z + As for the real Jack, my former intern... I am glad that nothing serious happened to him. ...", + "According to his letter, he did just fine so many years ago. He somehow managed to make a \z + name of himself when he cast some magic we enhanced through our research - of course no one \z + back then had ever seen such spells. ...", + "Oh and he sends his regards to... how did he put it - 'whoever is currently helping me getting \z + out of whatever mess I am currently in'. I... don't really know how this was meant but I \z + guess this is directed at... you!" + }, + cid + ) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "collective apparitions") then + local qStorage = player:getStorageValue(Storage.SpiritHunters.Mission01) + if qStorage == -1 then + if npcHandler.topic[cid] == 15 then + npcHandler:say( + "Ah well, let's forget about the scientific details - you will do just fine as \z + long as you do exactly what I say. Ready for me to go on with your task?", + cid + ) + npcHandler.topic[cid] = 16 + end + end + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] == 1 then + npcHandler:say( + "Yes, maybe it was the right decision. Astronomical research is \z + nothing for the faint-hearted.", + cid + ) + elseif npcHandler.topic[cid] == 2 then + npcHandler:say( + "Well, the... what? You... mean you're no longer interested? I see, well \z + maybe I overestimated your spirit after all.", + cid + ) + elseif npcHandler.topic[cid] == 3 then + npcHandler:say("Alright, alright. You'll never find out the true secrets of life with such attitude, hm.", cid) + elseif npcHandler.topic[cid] == 4 then + npcHandler:say("Come on, this is our only chance to finish the Lightboat.", cid) + elseif npcHandler.topic[cid] == 5 then + npcHandler:say("Thought so. Well, no reason to be ashamed. I'll have to find help elsewhere now, though.", cid) + elseif npcHandler.topic[cid] == 6 then + npcHandler:say("Come back if you made up your mind.", cid) + elseif npcHandler.topic[cid] == 7 then + npcHandler:say("Hmpf. *mumbles*", cid) + end + npcHandler.topic[cid] = 0 + end + + if msgcontains(msg, "machine") and player:getStorageValue(Storage.LiquidBlackQuest.Visitor) == 3 then + npcHandler:say( + { + "Ah, the machine you found at that island. Well, I built this thing to venture far beneath \z + the very soil we walk on. I suspected something there. Something deep down below. Something evil. \z + Even more so than the dreaded bugs which are crawling my study. ...", + "Drilling hole after hole only to get stuck in another hard, unbreakable sediment again and again, \z + I was about to quit this pointless enterprise. ...", + "However, the very last day I lingered on that island, I finally fell into a large hollow right \z + under the beach. My drill was shattered and the machine was not mobile anymore. ...", + "I am well aware that this may sound laughable now - at this part all of my colleagues burst into \z + laughter anyway - but suddenly there were stairs. Incredibly large stairs that led to the underworld. \z + A world deep under the sea - can you believe this?" + }, + cid, + false, + true, + 200 + ) + npcHandler.topic[cid] = 21 + elseif + msgcontains(msg, "yes") and npcHandler.topic[cid] == 21 and + player:getStorageValue(Storage.LiquidBlackQuest.Visitor) == 3 + then + if player:getStorageValue(Storage.LiquidBlackQuest.Visitor) == 3 then + npcHandler:say( + { + "You do? Well, the end of this story was that I had to leave the place. ...", + "I couldnt explore what lies below the stairs as there was an unpredictable stream. Diving \z + into these waters would have been an uncontrollable risk, even with the means to survive without any air. ...", + "So I used the portable teleporting device I installed into my machine in case of an emergency and went home. \z + I could only take the most important research documents with me and had to leave \z + most of my equipment in the cave. ...", + "Of course I also left my final notes with the coordinates there. And for the life of me I cannot remember where \z + I dug that stupid hole. ...", + "When I arrived at home I immediately started looking for a way to manoeuvre in these chaotic conditions once \z + I rediscovered the lost entrance. I never remembered it, but it seems you found it as you \z + indeed have my original notes. ...", + "Oh and just in case you want to complete what I have started - feel free to do so. Up to it?" + }, + cid, + false, + true, + 200 + ) + npcHandler.topic[cid] = 22 + end + elseif + msgcontains(msg, "yes") and npcHandler.topic[cid] == 22 and + player:getStorageValue(Storage.LiquidBlackQuest.Visitor) == 3 + then + if player:getStorageValue(Storage.LiquidBlackQuest.Visitor) == 3 then + npcHandler:say( + { + "Well, if you really want to delve into this - I could use some help. So you have \z + found my {machine} on that island? And you found the notes with the coordinates? \z + Then you can find the entrance! ...", + "Just look for a large staircase with sprawling steps. There is an unpassable stream \z + there that will prevent you from venturing further on. But fear not, you can indeed \z + travel down there - with these small {enhancements} I created. ...", + "At first, take this gold for the passage by ship and return to the Gray Island from \z + where I started my expedition many years ago. From there you should find a way to reach \z + the Gray Beach of Quirefang as no ordinary ship can land there. ...", + "I will put this under your footgear. Here you go. And this in your nose. There. And \z + there will be no further problems for you down there. Except- ah, well youll find \z + out yourself soon enough, wont you?" + }, + cid, + false, + true, + 200 + ) + npcHandler.topic[cid] = 23 + end + elseif + msgcontains(msg, "yes") and npcHandler.topic[cid] == 23 and + player:getStorageValue(Storage.LiquidBlackQuest.Visitor) == 3 + then + if player:getStorageValue(Storage.LiquidBlackQuest.Visitor) == 3 then + npcHandler:say( + { + "Then off you go! Im sorry that I cannot offer you any further help but Im \z + sure you will find support along your way. And - be careful. The sea can \z + appear pitch black down there." + }, + cid, + false, + true, + 200 + ) + player:setStorageValue(Storage.LiquidBlackQuest.Visitor, 4) + npcHandler.topic[cid] = 24 + end + elseif msgcontains(msg, "task") then + if player:getStorageValue(Storage.SeaOfLight.Mission3) == 4 then + end + end + + if msgcontains(msg, "rumours") then + npcHandler:say( + { + "There are rumours of aggressive fishmen in northern Tiquanda. We have to \z + find out if this is even remotely connected to the Njey. ...", + "What's puzzling me is that they were sighted above ground and then retreated \z + into a temple ruin. If we find that ruin, we could find out if there's a relation. ...", + "Are you willing to help me?" + }, + cid, + false, + true, + 200 + ) + npcHandler.topic[cid] = 25 + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 25 then + if npcHandler.topic[cid] == 25 then + npcHandler:say( + { + "Excellent, excellent. The rumours pointed to the north of Tiquanda, a \z + sunken temple probably half drowned in water. Return to me if you find \z + anything interesting!" + }, + cid, + false, + true, + 200 + ) + player:setStorageValue(Storage.TheSecretLibrary.LiquidDeath, 1) + npcHandler.topic[cid] = 0 + end + end + return true +end + +keywordHandler:addKeyword( + {"jack"}, + StdModule.say, + { + npcHandler = npcHandler, + text = "He was the first one I ever hired as an intern to help me with my studies and research. He \z + did an exceptionally good job and I certainly don't know where I would stand today without him. \z + We have to save him |PLAYERNAME|!" + } +) +keywordHandler:addKeyword( + {"device"}, + StdModule.say, + { + npcHandler = npcHandler, + text = "I heard of a device which would allow man to sail the sea of light. I call it the {Lightboat}, \z + probably the most important invention in our history. And I will not rest until I have found a way to \z + put the plan of its inventor into action." + } +) +keywordHandler:addKeyword( + {"lightboat"}, + StdModule.say, + { + npcHandler = npcHandler, + text = "I heard of a device which would allow man to sail the sea of light. I call it the {Lightboat}, \z + probably the most important invention in our history. And I will not rest until I have found a way to \z + put the plan of its inventor into action." + } +) +keywordHandler:addKeyword( + {"magic device"}, + StdModule.say, + { + npcHandler = npcHandler, + text = "I heard of a device which would allow man to sail the sea of light. I call it the {Lightboat}, \z + probably the most important invention in our history. And I will not rest until I have found a way to \z + put the plan of its inventor into action." + } +) +keywordHandler:addKeyword( + {"sea of light"}, + StdModule.say, + { + npcHandler = npcHandler, + text = "The sea of light is what I call the endless arrangement of shiny stars in the night sky. If we \z + fail to complete the {magic device}, science will probably never uncover its secrets." + } +) +keywordHandler:addKeyword( + {"mirror crystal"}, + StdModule.say, + { + npcHandler = npcHandler, + text = "I found the cause of the initial failure. A rare component, a mirror crystal was used to store \z + magical energy. Miscalculations within the construction damaged this fragile power source. The unleashed \z + energy must have been devastating." + } +) +keywordHandler:addKeyword( + {"lost mines"}, + StdModule.say, + { + npcHandler = npcHandler, + text = "The people of Edron were digging there for minerals and gold. It seemed all that work was of \z + no avail when they finally hit the motherlode. Gems, rare crystals and... water. So much that it flooded \z + the whole system. And not a single soul escaped." + } +) +keywordHandler:addKeyword( + {"collector"}, + StdModule.say, + { + npcHandler = npcHandler, + text = "I heard rumours of a fabled creature whose traces were found on an island near Carlin. It \z + lives solely to collect all kinds of rare gems, crystals and minerals. Offering an item it does not \z + already own, reportedly allows passage into its lair." + } +) + +npcHandler:setMessage( + MESSAGE_GREET, + "Hello |PLAYERNAME|! You're late, do you have no concept of time? \z +My mission is of utmost importance. If you are not interested in helping me, you might as well just leave." +) +npcHandler:setMessage(MESSAGE_FAREWELL, "Yes yes. Goodbye |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Yes yes. Goodbye |PLAYERNAME|.") + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/stan.lua b/data/npc/scripts/stan.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/stan.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/storkus.lua b/data/npc/scripts/storkus.lua new file mode 100644 index 00000000000..94d7c74f17d --- /dev/null +++ b/data/npc/scripts/storkus.lua @@ -0,0 +1,156 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if(msgcontains(msg, "mission")) then + if(player:getStorageValue(Storage.TheInquisition.Questline) == 6) then + if(player:getStorageValue(Storage.TheInquisition.StorkusVampiredust) < 0) then + player:setStorageValue(Storage.TheInquisition.StorkusVampiredust, 0) + end + if(player:getStorageValue(Storage.TheInquisition.StorkusVampiredust) < 20) then + npcHandler:say("So far ye've brought me " .. player:getItemCount(5905) .. " of 20 {vampire dusts}. Do ye' have any more with ye'? ", cid) + npcHandler.topic[cid] = 1 + elseif(player:getStorageValue(Storage.TheInquisition.StorkusVampiredust) == 20) then + npcHandler:say("Fine, you're done! Ye' should talk to me about your {mission} again now.", cid) + npcHandler.topic[cid] = 2 + player:setStorageValue(Storage.TheInquisition.Questline, 7) + player:setStorageValue(Storage.TheInquisition.Mission03, 2) -- The Inquisition Questlog- "Mission 3: Vampire Hunt" + end + elseif(player:getStorageValue(Storage.TheInquisition.Questline) == 7) then + npcHandler:say({ + "While ye' were keeping the lower ranks busy, I could get valuable information about some vampire lords. ...", + "One of them is hiding somewhere beneath the Green Claw Swamp. I expect ye' to find him and kill him. ...", + "But be warned: Without good preparation, ye' might get into trouble. I hope for ye' he will be sleeping in his coffin when ye' arrive. ...", + "Before ye' open his coffin and drag that beast out to destroy it, I advise ye' to place some garlic necklaces on the stone slabs next to his coffin. That will weaken him considerably. ...", + "Bring me his ring as proof for his death. And now hurry and good hunt to ye'." + }, cid) + player:setStorageValue(Storage.TheInquisition.Questline, 8) + player:setStorageValue(Storage.TheInquisition.Mission03, 3) -- The Inquisition Questlog- "Mission 3: Vampire Hunt" + npcHandler.topic[cid] = 0 + elseif(player:getStorageValue(Storage.TheInquisition.Questline) == 8 or player:getStorageValue(Storage.TheInquisition.Questline) == 9) then + if(player:removeItem(8752, 1)) then + npcHandler:say({ + "Ding, dong, the vampire is dead, eh? So I guess ye' can return to Henricus and tell him that ye' finished your job here. I'm quite sure he has some more challenging task up his sleeve. ...", + "One more thing before ye' leave: I already mentioned the master vampires. ...", + "They are quite hard to find. If ye' stumble across one of them and manage to kill him, he will surely drop some token that proves his death. Bring me these tokens. ...", + "If ye' kill enough of them, I might have a little surprise for ye'." + }, cid) + player:setStorageValue(Storage.TheInquisition.Questline, 10) + player:setStorageValue(Storage.TheInquisition.Mission03, 5) -- The Inquisition Questlog- "Mission 3: Vampire Hunt" + else + npcHandler:say("Have ye' killed the vampire lord? Because ye' have no his ring.", cid) + end + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "vampire lord token") and player:getStorageValue(Storage.TheInquisition.Questline) == 10) then + if(player:getStorageValue(Storage.VampireHunter.Rank) < 1) then + npcHandler:say("Would ye' like to give me vampire tokens?", cid) + npcHandler.topic[cid] = 3 + elseif(player:getStorageValue(Storage.VampireHunter.Rank) == 1) then + npcHandler:say("Would ye' like to give me vampire tokens?", cid) + npcHandler.topic[cid] = 4 + elseif(player:getStorageValue(Storage.VampireHunter.Rank) == 2) then + npcHandler:say("Would ye' like to give me vampire tokens?", cid) + npcHandler.topic[cid] = 5 + elseif(player:getStorageValue(Storage.VampireHunter.Rank) == 3) then + npcHandler:say("Would ye' like to give me vampire tokens?", cid) + npcHandler.topic[cid] = 6 + elseif(player:getStorageValue(Storage.VampireHunter.Rank) == 4) then + npcHandler:say("Would ye' like to give me vampire tokens?", cid) + npcHandler.topic[cid] = 7 + elseif(player:getStorageValue(Storage.VampireHunter.Rank) == 5) then + npcHandler:say("Would ye' like to give me vampire tokens?", cid) + npcHandler.topic[cid] = 8 + end + elseif(msgcontains(msg, "yes")) then + if(npcHandler.topic[cid] == 1) then + local count = player:getItemCount(5905) + requiredCount = 20 - player:getStorageValue(Storage.TheInquisition.StorkusVampiredust) + if(count > requiredCount) then + count = requiredCount + end + player:setStorageValue(Storage.TheInquisition.StorkusVampiredust, player:getStorageValue(Storage.TheInquisition.StorkusVampiredust) + count) + player:removeItem(5905, count) + npcHandler:say("Ye've brought me " .. count .. " vampire dusts. " .. (20 - player:getStorageValue(Storage.TheInquisition.StorkusVampiredust)) == 0 and ("Ask me for a {mission} to continue your quest.") or ("Ye' need to bring " .. (20 - player:getStorageValue(Storage.TheInquisition.StorkusVampiredust)) .. " more."), cid) + npcHandler.topic[cid] = 0 + elseif(npcHandler.topic[cid] == 3) then + if player:removeItem(9020, 1) then + npcHandler:say("Ye' brought the token needed to advance to the first vampire hunter rank. I consider that a fluke, but still, congrats! Let me share some of my experience with ye'.", cid) + player:setStorageValue(Storage.VampireHunter.Rank, 1) + player:addExperience(1000, true) + else + npcHandler:say("Ye' don't have enought tokens.", cid) + end + npcHandler.topic[cid] = 0 + elseif(npcHandler.topic[cid] == 4) then + if player:removeItem(9020, 4) then + npcHandler:say("Ye' brought the four tokens needed to advance to the second vampire hunter rank. Pretty lucky ye' are! Let me share some of my experience with ye'.", cid) + player:setStorageValue(Storage.VampireHunter.Rank, 2) + player:addExperience(5 * 1000, true) + else + npcHandler:say("Ye' don't have enought tokens.", cid) + end + npcHandler.topic[cid] = 0 + elseif(npcHandler.topic[cid] == 5) then + if player:removeItem(9020, 5) then + npcHandler:say("Ye' brought the five tokens needed to advance to the third vampire hunter rank. Wow, you're pretty determined! Let me share some of my experience with ye'.", cid) + player:setStorageValue(Storage.VampireHunter.Rank, 3) + player:addExperience(10 * 1000, true) + else + npcHandler:say("Ye' don't have enought tokens.", cid) + end + npcHandler.topic[cid] = 0 + elseif(npcHandler.topic[cid] == 6) then + if player:removeItem(9020, 10) then + npcHandler:say("Ye' brought the ten tokens needed to advance to the fourth vampire hunter rank. You're absolutely painstaking! Let me share some of my experience with ye'.", cid) + player:setStorageValue(Storage.VampireHunter.Rank, 4) + player:addExperience(20 * 1000, true) + else + npcHandler:say("Ye' don't have enought tokens.", cid) + end + npcHandler.topic[cid] = 0 + elseif(npcHandler.topic[cid] == 7) then + if player:removeItem(9020, 30) then + npcHandler:say("Ye' brought the thirty tokens needed to advance to the fifth vampire hunter rank. You're completely obliterative, kid! Let me share some of my experience with ye'.", cid) + player:setStorageValue(Storage.VampireHunter.Rank, 5) + player:addExperience(50 * 1000, true) + else + npcHandler:say("Ye' don't have enought tokens.", cid) + end + npcHandler.topic[cid] = 0 + elseif(npcHandler.topic[cid] == 8) then + if player:removeItem(9020, 50) then + npcHandler:say("Ye' brought the fifty tokens needed to advance to the last vampire hunter rank. Now that's something. You're razing-amazing! Let me share some of my experience and a little something with ye'!", cid) + player:setStorageValue(Storage.VampireHunter.Rank, 6) + player:addItem(9019, 1) + player:addExperience(100 * 1000, true) + else + npcHandler:say("Ye' don't have enought tokens.", cid) + end + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/strange_pipe.lua b/data/npc/scripts/strange_pipe.lua new file mode 100644 index 00000000000..5fb40b14db4 --- /dev/null +++ b/data/npc/scripts/strange_pipe.lua @@ -0,0 +1,74 @@ + +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Don't forget npcHandler = npcHandler in the parameters. It is required for all StdModule functions! +keywordHandler:addKeyword({'importance'}, StdModule.say, {npcHandler = npcHandler, text = 'I can\'t reveal much to you right now as time is of the essence. I can tell you though that the glooth plant and the whole town are in danger and we have to act to stop a {madman} and his schemes.'}) +keywordHandler:addKeyword({'laboratory'}, StdModule.say, {npcHandler = npcHandler, text = 'I defeated him there in the past. It has been abandoned for many {years}, but I suspected him to return from the dead eventually, as he has done so often before.'}) +keywordHandler:addKeyword({'plan'}, StdModule.say, {npcHandler = npcHandler, text = 'The creature is powerful but not very clever. It seems it can be easily {enraged} and then it would likely let slip all caution and would relentlessly attack without regard for its safety.'}) +keywordHandler:addKeyword({'years'}, StdModule.say, {npcHandler = npcHandler, text = 'I used the time to prepare. You\'ll find my talking tubes all the {way} to his lair, and I can provide you with vital information about the things ahead.'}) + +local function greetCallback(cid) + local player = Player(cid) + player:setStorageValue(Storage.HeroRathleton.AccessDoor, 1) + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "madman") then + npcHandler:say({ + "He is an old enemy of the city and I've battled him often in the past. ...", + "Now he has returned for vengeance, he reclaimed an old abandoned underground {laboratory} and he has acquired new powerful {allies}." + }, cid) + end + if msgcontains(msg, 'allies') then + npcHandler:say({ + "His allies are an enigma even to me. It seems they belong to some unknown race that lives deep under the earth. ...", + "They seem to have supplied him with resources and workforce and a powerful {guardian} to prevent anyone from entering the passages to his lair." + }, cid) + end + if msgcontains(msg, 'guardian') then + npcHandler:say({ + "It's a fearsome subterranean beast like nothing I've ever encountered. It is dangerous and almost unbeatable because its main body is hidden beneath the ground ...", + "And it has an endless supply of tentacles. But not all is lost, as I have devised a {plan} to battle the beast." + }, cid) + end + if msgcontains(msg, 'enraged') then + npcHandler:say({ + "While it's buried, it only uses his tentacles to attack. If one is destroyed it will simply use another set of tentacles and its supply seems endless. ...", + "If you manage though to kill all the tentacles it is using within a few heartbeats, it will become confused by its momentary helplessness and will probably attack with its main body. ...", + "That is when you have a chance to destroy it. Pass through its chamber and look for another of my tubes to contact me. Please hurry! End of communication." + }, cid) + end + if msgcontains(msg, 'way') then + npcHandler:say({ + "You will have to leave the plant through the eastern door on the lowest level. I have arranged for it to be 'accidentally' open. ...", + "As in the past, our enemy still uses a series of machines to open the way to the next section of his lair. You have to turn them all on to proceed. ...", + "They will only work for a certain amount of time though, so you will have to hurry or some of the machines will turn inactive again." + }, cid) + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/strange_pipe1.lua b/data/npc/scripts/strange_pipe1.lua new file mode 100644 index 00000000000..77d2afd4e74 --- /dev/null +++ b/data/npc/scripts/strange_pipe1.lua @@ -0,0 +1,74 @@ + +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Don't forget npcHandler = npcHandler in the parameters. It is required for all StdModule functions! +keywordHandler:addKeyword({'importance'}, StdModule.say, {npcHandler = npcHandler, text = 'I can\'t reveal much to you right now as time is of the essence. I can tell you though that the glooth plant and the whole town are in danger and we have to act to stop a {madman} and his schemes.'}) +keywordHandler:addKeyword({'laboratory'}, StdModule.say, {npcHandler = npcHandler, text = 'I defeated him there in the past. It has been abandoned for many {years}, but I suspected him to return from the dead eventually, as he has done so often before.'}) +keywordHandler:addKeyword({'plan'}, StdModule.say, {npcHandler = npcHandler, text = 'The creature is powerful but not very clever. It seems it can be easily {enraged} and then it would likely let slip all caution and would relentlessly attack without regard for its safety.'}) +keywordHandler:addKeyword({'years'}, StdModule.say, {npcHandler = npcHandler, text = 'I used the time to prepare. You\'ll find my talking tubes all the {way} to his lair, and I can provide you with vital information about the things ahead.'}) + +local function greetCallback(cid) + local player = Player(cid) + player:setStorageValue(Storage.HeroRathleton.AccessTeleport1, 1) + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "madman") then + npcHandler:say({ + "He is an old enemy of the city and I've battled him often in the past. ...", + "Now he has returned for vengeance, he reclaimed an old abandoned underground {laboratory} and he has acquired new powerful {allies}." + }, cid) + end + if msgcontains(msg, 'allies') then + npcHandler:say({ + "His allies are an enigma even to me. It seems they belong to some unknown race that lives deep under the earth. ...", + "They seem to have supplied him with resources and workforce and a powerful {guardian} to prevent anyone from entering the passages to his lair." + }, cid) + end + if msgcontains(msg, 'guardian') then + npcHandler:say({ + "It's a fearsome subterranean beast like nothing I've ever encountered. It is dangerous and almost unbeatable because its main body is hidden beneath the ground ...", + "And it has an endless supply of tentacles. But not all is lost, as I have devised a {plan} to battle the beast." + }, cid) + end + if msgcontains(msg, 'enraged') then + npcHandler:say({ + "While it's buried, it only uses his tentacles to attack. If one is destroyed it will simply use another set of tentacles and its supply seems endless. ...", + "If you manage though to kill all the tentacles it is using within a few heartbeats, it will become confused by its momentary helplessness and will probably attack with its main body. ...", + "That is when you have a chance to destroy it. Pass through its chamber and look for another of my tubes to contact me. Please hurry! End of communication." + }, cid) + end + if msgcontains(msg, 'way') then + npcHandler:say({ + "You will have to leave the plant through the eastern door on the lowest level. I have arranged for it to be 'accidentally' open. ...", + "As in the past, our enemy still uses a series of machines to open the way to the next section of his lair. You have to turn them all on to proceed. ...", + "They will only work for a certain amount of time though, so you will have to hurry or some of the machines will turn inactive again." + }, cid) + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/strange_pipe2.lua b/data/npc/scripts/strange_pipe2.lua new file mode 100644 index 00000000000..1e6a3c96f88 --- /dev/null +++ b/data/npc/scripts/strange_pipe2.lua @@ -0,0 +1,74 @@ + +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Don't forget npcHandler = npcHandler in the parameters. It is required for all StdModule functions! +keywordHandler:addKeyword({'importance'}, StdModule.say, {npcHandler = npcHandler, text = 'I can\'t reveal much to you right now as time is of the essence. I can tell you though that the glooth plant and the whole town are in danger and we have to act to stop a {madman} and his schemes.'}) +keywordHandler:addKeyword({'laboratory'}, StdModule.say, {npcHandler = npcHandler, text = 'I defeated him there in the past. It has been abandoned for many {years}, but I suspected him to return from the dead eventually, as he has done so often before.'}) +keywordHandler:addKeyword({'plan'}, StdModule.say, {npcHandler = npcHandler, text = 'The creature is powerful but not very clever. It seems it can be easily {enraged} and then it would likely let slip all caution and would relentlessly attack without regard for its safety.'}) +keywordHandler:addKeyword({'years'}, StdModule.say, {npcHandler = npcHandler, text = 'I used the time to prepare. You\'ll find my talking tubes all the {way} to his lair, and I can provide you with vital information about the things ahead.'}) + +local function greetCallback(cid) + local player = Player(cid) + player:setStorageValue(Storage.HeroRathleton.AccessTeleport2, 1) + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "madman") then + npcHandler:say({ + "He is an old enemy of the city and I've battled him often in the past. ...", + "Now he has returned for vengeance, he reclaimed an old abandoned underground {laboratory} and he has acquired new powerful {allies}." + }, cid) + end + if msgcontains(msg, 'allies') then + npcHandler:say({ + "His allies are an enigma even to me. It seems they belong to some unknown race that lives deep under the earth. ...", + "They seem to have supplied him with resources and workforce and a powerful {guardian} to prevent anyone from entering the passages to his lair." + }, cid) + end + if msgcontains(msg, 'guardian') then + npcHandler:say({ + "It's a fearsome subterranean beast like nothing I've ever encountered. It is dangerous and almost unbeatable because its main body is hidden beneath the ground ...", + "And it has an endless supply of tentacles. But not all is lost, as I have devised a {plan} to battle the beast." + }, cid) + end + if msgcontains(msg, 'enraged') then + npcHandler:say({ + "While it's buried, it only uses his tentacles to attack. If one is destroyed it will simply use another set of tentacles and its supply seems endless. ...", + "If you manage though to kill all the tentacles it is using within a few heartbeats, it will become confused by its momentary helplessness and will probably attack with its main body. ...", + "That is when you have a chance to destroy it. Pass through its chamber and look for another of my tubes to contact me. Please hurry! End of communication." + }, cid) + end + if msgcontains(msg, 'way') then + npcHandler:say({ + "You will have to leave the plant through the eastern door on the lowest level. I have arranged for it to be 'accidentally' open. ...", + "As in the past, our enemy still uses a series of machines to open the way to the next section of his lair. You have to turn them all on to proceed. ...", + "They will only work for a certain amount of time though, so you will have to hurry or some of the machines will turn inactive again." + }, cid) + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/strange_pipe3.lua b/data/npc/scripts/strange_pipe3.lua new file mode 100644 index 00000000000..5f31f7ca09c --- /dev/null +++ b/data/npc/scripts/strange_pipe3.lua @@ -0,0 +1,74 @@ + +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Don't forget npcHandler = npcHandler in the parameters. It is required for all StdModule functions! +keywordHandler:addKeyword({'importance'}, StdModule.say, {npcHandler = npcHandler, text = 'I can\'t reveal much to you right now as time is of the essence. I can tell you though that the glooth plant and the whole town are in danger and we have to act to stop a {madman} and his schemes.'}) +keywordHandler:addKeyword({'laboratory'}, StdModule.say, {npcHandler = npcHandler, text = 'I defeated him there in the past. It has been abandoned for many {years}, but I suspected him to return from the dead eventually, as he has done so often before.'}) +keywordHandler:addKeyword({'plan'}, StdModule.say, {npcHandler = npcHandler, text = 'The creature is powerful but not very clever. It seems it can be easily {enraged} and then it would likely let slip all caution and would relentlessly attack without regard for its safety.'}) +keywordHandler:addKeyword({'years'}, StdModule.say, {npcHandler = npcHandler, text = 'I used the time to prepare. You\'ll find my talking tubes all the {way} to his lair, and I can provide you with vital information about the things ahead.'}) + +local function greetCallback(cid) + local player = Player(cid) + player:setStorageValue(Storage.HeroRathleton.AccessTeleport3, 1) + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "madman") then + npcHandler:say({ + "He is an old enemy of the city and I've battled him often in the past. ...", + "Now he has returned for vengeance, he reclaimed an old abandoned underground {laboratory} and he has acquired new powerful {allies}." + }, cid) + end + if msgcontains(msg, 'allies') then + npcHandler:say({ + "His allies are an enigma even to me. It seems they belong to some unknown race that lives deep under the earth. ...", + "They seem to have supplied him with resources and workforce and a powerful {guardian} to prevent anyone from entering the passages to his lair." + }, cid) + end + if msgcontains(msg, 'guardian') then + npcHandler:say({ + "It's a fearsome subterranean beast like nothing I've ever encountered. It is dangerous and almost unbeatable because its main body is hidden beneath the ground ...", + "And it has an endless supply of tentacles. But not all is lost, as I have devised a {plan} to battle the beast." + }, cid) + end + if msgcontains(msg, 'enraged') then + npcHandler:say({ + "While it's buried, it only uses his tentacles to attack. If one is destroyed it will simply use another set of tentacles and its supply seems endless. ...", + "If you manage though to kill all the tentacles it is using within a few heartbeats, it will become confused by its momentary helplessness and will probably attack with its main body. ...", + "That is when you have a chance to destroy it. Pass through its chamber and look for another of my tubes to contact me. Please hurry! End of communication." + }, cid) + end + if msgcontains(msg, 'way') then + npcHandler:say({ + "You will have to leave the plant through the eastern door on the lowest level. I have arranged for it to be 'accidentally' open. ...", + "As in the past, our enemy still uses a series of machines to open the way to the next section of his lair. You have to turn them all on to proceed. ...", + "They will only work for a certain amount of time though, so you will have to hurry or some of the machines will turn inactive again." + }, cid) + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/stricken_soul.lua b/data/npc/scripts/stricken_soul.lua new file mode 100644 index 00000000000..8f054ea6575 --- /dev/null +++ b/data/npc/scripts/stricken_soul.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "Esperando Script."}) +npcHandler:setMessage(MESSAGE_GREET, "Greetings, |PLAYERNAME|.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/stutch.lua b/data/npc/scripts/stutch.lua new file mode 100644 index 00000000000..b2c9e0881b2 --- /dev/null +++ b/data/npc/scripts/stutch.lua @@ -0,0 +1,52 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +keywordHandler:addKeyword({'hi'}, StdModule.say, {npcHandler = npcHandler, onlyUnfocus = true, text = "MIND YOUR MANNERS COMMONER! To address the king greet with his title!"}) +keywordHandler:addKeyword({'hello'}, StdModule.say, {npcHandler = npcHandler, onlyUnfocus = true, text = "MIND YOUR MANNERS COMMONER! To address the king greet with his title!"}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if isInArray({'fuck', 'idiot', 'asshole', 'ass', 'fag', 'stupid', 'tyrant', 'shit', 'lunatic'}, msg) then + local player = Player(cid) + local conditions = { CONDITION_POISON, CONDITION_FIRE, CONDITION_ENERGY, CONDITION_BLEEDING, CONDITION_PARALYZE, CONDITION_DROWN, CONDITION_FREEZING, CONDITION_DAZZLED, CONDITION_CURSED } + for i = 1, #conditions do + if player:getCondition(conditions[i]) then + player:removeCondition(conditions[i]) + end + end + player:getPosition():sendMagicEffect(CONST_ME_EXPLOSIONAREA) + player:addHealth(1 - player:getHealth()) + npcHandler:say('Take this!', cid) + Npc():getPosition():sendMagicEffect(CONST_ME_YELLOW_RINGS) + end + return true +end + +-- Greeting +keywordHandler:addGreetKeyword({'hail king'}, {npcHandler = npcHandler, text = 'HAIL TO THE KING!'}) +keywordHandler:addGreetKeyword({'salutations king'}, {npcHandler = npcHandler, text = 'HAIL TO THE KING!'}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'LONG LIVE THE KING!') +npcHandler:setMessage(MESSAGE_FAREWELL, 'LONG LIVE THE KING! You may leave now!') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/sven.lua b/data/npc/scripts/sven.lua new file mode 100644 index 00000000000..8781953e143 --- /dev/null +++ b/data/npc/scripts/sven.lua @@ -0,0 +1,103 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "barbarian") then + if player:getStorageValue(Storage.BarbarianTest.Questline) < 1 then + npcHandler:say("A true barbarian is something special among our people. Everyone who wants to become a barbarian will have to pass the barbarian {test}.", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "test") then + npcHandler:say({ + "All of our juveniles have to take the barbarian test to become a true member of our community. Foreigners who manage to master the test are granted the title of an honorary barbarian and the respect of our people ...", + "Are you willing to take the barbarian test?" + }, cid) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, "mead") then + if player:getStorageValue(Storage.BarbarianTest.Questline) == 1 then + npcHandler:say("Do you have some honey with you?", cid) + npcHandler.topic[cid] = 4 + elseif player:getStorageValue(Storage.BarbarianTest.Questline) == 3 then + npcHandler:say({ + "An impressive start. Here, take your own mead horn to fill it at the mead bucket as often as you like ...", + "But there is much left to be done. Your next test will be to hug a bear ...", + "You will find one in a cave north of the town. If you are lucky, it's still sleeping. If not ... well that might hurt ...", + "Unless you feel that you hugged the bear, the test is not passed. Once you are done, talk to me about the bear hugging." + }, cid) + player:setStorageValue(Storage.BarbarianTest.Questline, 4) + player:setStorageValue(Storage.BarbarianTest.Mission02, 1) -- Questlog Barbarian Test Quest Barbarian Test 2: The Bear Hugging + player:addItem(7140, 1) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "hug") then + if player:getStorageValue(Storage.BarbarianTest.Questline) == 5 then + npcHandler:say({ + "Amazing. That was as clever and brave as a barbarian is supposed to be. But a barbarian also has to be strong and fearless. To prove that you will have to knock over a mammoth ...", + "Did your face just turn into the color of fresh snow? However, you will find a lonely mammoth north west of the town in the wilderness. Knock it over to prove to be a true barbarian ...", + "Return to me and talk about the {mammoth} pushing when you are done." + }, cid) + player:setStorageValue(Storage.BarbarianTest.Questline, 6) + player:setStorageValue(Storage.BarbarianTest.Mission02, 3) -- Questlog Barbarian Test Quest Barbarian Test 2: The Bear Hugging + player:setStorageValue(Storage.BarbarianTest.Mission03, 1) -- Questlog Barbarian Test Quest Barbarian Test 3: The Mammoth Pushing + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "mammoth") then + if player:getStorageValue(Storage.BarbarianTest.Questline) == 7 then + npcHandler:say({ + "As you have passed all three tests, I welcome you in our town as an honorary barbarian. You can now become a citizen. Don't forget to talk to the people here. Some of them might need some help ...", + "We usually solve our problems on our own but some of the people might have a mission for you. Old Iskan, on the ice in the northern part of the town had some trouble with his dogs lately." + }, cid) + player:setStorageValue(Storage.BarbarianTest.Questline, 8) + player:setStorageValue(Storage.BarbarianTest.Mission03, 3) -- Questlog Barbarian Test Quest Barbarian Test 3: The Mammoth Pushing + player:addAchievement('Honorary Barbarian') + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 2 then + npcHandler:say({ + "That's the spirit! The barbarian test consists of a few tasks you will have to fulfill. All are rather simple - for a barbarian that is...", + "Your first task is to drink some barbarian mead. But be warned, it's a strong brew that could even knock out a bear. You need to make at least ten sips of mead in a row without passing out to pass the test ...", + "Do you think you can do this?" + }, cid) + npcHandler.topic[cid] = 3 + elseif npcHandler.topic[cid] == 3 then + npcHandler:say({ + "Good, but to make barbarian mead we need some honey which is rare here. I'd hate to waste mead just to learn you're not worth it ...", + "Therefore, you have to get your own honey. You'll probably need more than one try so better get some extra honeycombs. Then talk to me again about barbarian {mead}." + }, cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.BarbarianTest.Questline, 1) + player:setStorageValue(Storage.BarbarianTest.Mission01, 1) -- Questlog Barbarian Test Quest Barbarian Test 1: Barbarian Booze + elseif npcHandler.topic[cid] == 4 then + if player:removeItem(5902, 1) then + npcHandler:say("Good, for this honeycomb I allow you 20 sips from the mead bucket over there. Talk to me again about barbarian mead if you have passed the test.", cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.BarbarianTest.Questline, 2) + player:setStorageValue(Storage.BarbarianTest.Mission01, 2) -- Questlog Barbarian Test Quest Barbarian Test 1: Barbarian Booze + player:setStorageValue(Storage.BarbarianTest.MeadTotalSips, 0) + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/svenson.lua b/data/npc/scripts/svenson.lua new file mode 100644 index 00000000000..11e6497deb6 --- /dev/null +++ b/data/npc/scripts/svenson.lua @@ -0,0 +1,58 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if msgcontains(msg, "heavy ball") then + npcHandler:say("Do you want to buy a heavy ball for 123 gold?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + local player = Player(cid) + if player:getMoney() + player:getBankBalance() >= 123 then + npcHandler:say("Here it is.", cid) + player:addItem(11257, 1) + player:removeMoneyNpc(123) + else + npcHandler:say("You don't have enough money.", cid) + end + npcHandler.topic[cid] = 0 + end + end + return true +end + +-- Travel +local function addTravelKeyword(keyword, text, cost, destination) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you want to sail ' .. text, cost = cost}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('tibia', 'back to Tibia?', 0, Position(32235, 31674, 7)) +addTravelKeyword('senja', 'Senja for |TRAVELCOST|?', 10, Position(32128, 31664, 7)) +addTravelKeyword('vega', 'Vega for |TRAVELCOST|?', 10, Position(32020, 31692, 7)) + +-- Basic +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'Where do you want to go? To {Tibia}, {Senja} or {Vega}?'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) +keywordHandler:addKeyword({'captain'}, StdModule.say, {npcHandler = npcHandler, text = 'I am the captain of this ship.'}) + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/swolt.lua b/data/npc/scripts/swolt.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/swolt.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/sylvester.lua b/data/npc/scripts/sylvester.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/sylvester.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/taegen.lua b/data/npc/scripts/taegen.lua new file mode 100644 index 00000000000..26ed8c2712a --- /dev/null +++ b/data/npc/scripts/taegen.lua @@ -0,0 +1,24 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Id like to take a walk with Aurita.'},{text = 'I miss Aurita golden hair.*sigh*'},{text = 'Pas in boldly tyll thow com to an hall the feyrist undir sky ... *sings*'} } +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "Greatings, mortal beigin.") +npcHandler:setMessage(MESSAGE_SENDTRADE, " Im carving bolts and arrows and i also craft bows anda spears.If you'd like to buy some ammunition, take a look.") +npcHandler:setMessage(MESSAGE_FAREWELL, "May enlightenment be your path, |PLAYERNAME|.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/talesia.lua b/data/npc/scripts/talesia.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/talesia.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/talila.lua b/data/npc/scripts/talila.lua new file mode 100644 index 00000000000..6a9cf0e3ca4 --- /dev/null +++ b/data/npc/scripts/talila.lua @@ -0,0 +1,24 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Are you interested in a trade?'},{text = 'Dont touch the wings, theyre delicate.'},{text = 'Tralllalalla.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "Greatings, mortal beigin.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Yes, i have some potions and runes if you are interested. Or do you want to buy only potions or only runes?oh if you want sell or buy gems, your may also ask me.") +npcHandler:setMessage(MESSAGE_FAREWELL, "May enlightenment be your path, |PLAYERNAME|.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/talphion.lua b/data/npc/scripts/talphion.lua new file mode 100644 index 00000000000..60a5d9967f0 --- /dev/null +++ b/data/npc/scripts/talphion.lua @@ -0,0 +1,48 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "dress pattern") then + if player:getStorageValue(Storage.Postman.Mission06) == 3 then + if npcHandler.topic[cid] < 1 then + npcHandler:say("DRESS FLATTEN? WHO WANTS ME TO FLATTEN A DRESS?", cid) + npcHandler.topic[cid] = 1 + elseif npcHandler.topic[cid] == 1 then + npcHandler:say("A PRESS LANTERN? NEVER HEARD ABOUT IT!", cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say("CHESS? I DONT PLAY CHESS!", cid) + npcHandler.topic[cid] = 3 + elseif npcHandler.topic[cid] == 3 then + npcHandler:say("A PATTERN IN THIS MESS?? HEY DON'T INSULT MY MACHINEHALL!", cid) + npcHandler.topic[cid] = 4 + elseif npcHandler.topic[cid] == 4 then + npcHandler:say("AH YES! I WORKED ON THE DRESS PATTERN FOR THOSE UNIFORMS. STAINLESS TROUSERES, STEAM DRIVEN BOOTS! ANOTHERMARVEL TO BEHOLD! I'LL SENT A COPY TO KEVIN IMEDIATELY!", cid) + player:setStorageValue(Storage.Postman.Mission06, 4) + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tamara.lua b/data/npc/scripts/tamara.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/tamara.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tamed_lion.lua b/data/npc/scripts/tamed_lion.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/tamed_lion.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tamerin.lua b/data/npc/scripts/tamerin.lua new file mode 100644 index 00000000000..8dc56dd0917 --- /dev/null +++ b/data/npc/scripts/tamerin.lua @@ -0,0 +1,92 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.InServiceofYalahar.Questline) == 30 then + npcHandler:setMessage(MESSAGE_GREET, "Have you the {animal cure}?") + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 31 then + npcHandler:setMessage(MESSAGE_GREET, "Have you killed {morik}?") + else + npcHandler:setMessage(MESSAGE_GREET, "Hello, what brings you here?") + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.InServiceofYalahar.Questline) == 29 then + npcHandler:say({ + "Why should I do something for another human being? I have been on my own for all those years. Hmm, but actually there is something I could need some assistance with. ... ", + "If you help me to solve my problems, I will help you with your mission. Do you accept?" + }, cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 32 then + npcHandler:say("You have kept your promise. Now, it's time to fulfil my part of the bargain. What kind of animals shall I raise? {Warbeasts} or {cattle}?", cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, "animal cure") then + if player:getStorageValue(Storage.InServiceofYalahar.Questline) == 30 and player:removeItem(9734, 1) then + player:setStorageValue(Storage.InServiceofYalahar.Questline, 31) + player:setStorageValue(Storage.InServiceofYalahar.MorikSummon, 0) + player:setStorageValue(Storage.InServiceofYalahar.Mission05, 4) -- StorageValue for Questlog "Mission 05: Food or Fight" + npcHandler:say("Thank you very much. As I said, as soon as you have helped me to solve both of my problems, we will talk about your mission. Have you killed {morik}?", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Come back when you have the cure.", cid) + end + elseif msgcontains(msg, "cattle") then + if npcHandler.topic[cid] == 2 then + player:setStorageValue(Storage.InServiceofYalahar.TamerinStatus, 1) + player:setStorageValue(Storage.InServiceofYalahar.Mission05, 6) -- StorageValue for Questlog "Mission 05: Food or Fight" + npcHandler:say("So be it!", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "warbeast") then + if npcHandler.topic[cid] == 2 then + player:setStorageValue(Storage.InServiceofYalahar.TamerinStatus, 2) + player:setStorageValue(Storage.InServiceofYalahar.Mission05, 7) -- StorageValue for Questlog "Mission 05: Food or Fight" + npcHandler:say("So be it!", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "morik") then + if player:getStorageValue(Storage.InServiceofYalahar.Questline) == 31 and player:removeItem(9735, 1) then + player:setStorageValue(Storage.InServiceofYalahar.Questline, 32) + player:setStorageValue(Storage.InServiceofYalahar.Mission05, 5) -- StorageValue for Questlog "Mission 05: Food or Fight" + npcHandler:say("So he finally got what he deserved. As I said, as soon as you have helped me to solve both of my problems, we will talk about your {mission}.", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("Come back when you got rid with Morik.", cid) + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + player:setStorageValue(Storage.InServiceofYalahar.Questline, 30) + player:setStorageValue(Storage.InServiceofYalahar.Mission05, 3) -- StorageValue for Questlog "Mission 05: Food or Fight" + npcHandler:say("I ask you for two things! For one thing, I need an animal cure and for another thing, I ask you to get rid of the gladiator Morik for me.", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tamoril.lua b/data/npc/scripts/tamoril.lua new file mode 100644 index 00000000000..9dd5e689dcf --- /dev/null +++ b/data/npc/scripts/tamoril.lua @@ -0,0 +1,74 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) +local talkState = {} + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + npcHandler:setMessage(MESSAGE_GREET, "Another pesky mortal who believes his gold outweighs his nutrition value.") + return true +end + +function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "first dragon") then + npcHandler:say("The First Dragon? The first of all of us? The Son of Garsharak? I'm surprised you heard about him. It is such a long time that he wandered Tibia. Yet, there are some {rumours}.", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "rumours") and npcHandler.topic[cid] == 1 then + npcHandler.topic[cid] = 2 + npcHandler:say("It is told that the First Dragon had four {descendants}, who became the ancestors of the four kinds of dragons we know in Tibia. They perhaps still have knowledge about the First Dragon's whereabouts - if one could find them.", cid) + elseif msgcontains(msg, "descendants") and npcHandler.topic[cid] == 2 then + npcHandler.topic[cid] = 3 + npcHandler:say("The names of these four are Tazhadur, Kalyassa, Gelidrazah and Zorvorax. Not only were they the ancestors of all dragons after but also the primal representation of the {draconic incitements}. About whom do you want to learn more?", cid) + elseif msgcontains(msg, "draconic incitements") and npcHandler.topic[cid] == 3 then + npcHandler.topic[cid] = 4 + npcHandler:say({ + 'Each kind of dragon has its own incitement, an important aspect that impels them and occupies their mind. For the common dragons this is the lust for power, for the dragon lords the greed for treasures. ...', + 'The frost dragons\' incitement is the thirst for knowledge und for the undead dragons it\'s the desire for life, as they regret their ancestor\'s mistake. ...', + 'These incitements are also a kind of trial that has to be undergone if one wants to {find} the First Dragon\'s four descendants.' + }, cid) + elseif msgcontains(msg, "find") then + npcHandler.topic[cid] = 5 + npcHandler:say("What do you want to do, if you know about these mighty dragons' abodes? Go there and look for a fight?", cid) + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 5 then + npcHandler.topic[cid] = 6 + npcHandler:say({ + ' Fine! I\'ll tell you where to find our ancestors. You now may ask yourself why I should want you to go there and fight them. It\'s quite simple: I am a straight descendant of Kalyassa herself. She was not really a caring mother. ...', + 'No, she called herself an empress and behaved exactly like that. She was domineering, farouche and conceited and this finally culminated in a serious quarrel between us. ...', + 'I sought support by my aunt and my uncles but they were not a bit better than my mother was! So, feel free to go to their lairs and challenge them. I doubt you will succeed but then again that\'s not my problem. ...', + 'So, you want to know about their secret lairs?' + }, cid) + elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 6 then + npcHandler:say({ + 'So listen: The lairs are secluded and you can only reach them by using a magical gem teleporter. You will find a teleporter carved out of a giant emerald in the dragon lairs deep beneath the Darama desert, which will lead you to Tazhadur\'s lair. ...', + 'A ruby teleporter located in the western Dragonblaze Peaks allows you to enter the lair of Kalyassa. A teleporter carved out of sapphire is on the island Okolnir and leads you to Gelidrazah\'s lair. ...', + 'And finally an amethyst teleporter in undead-infested caverns underneath Edron allows you to enter the lair of Zorvorax.' + }, cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.FirstDragon.Questline, 1) + player:setStorageValue(Storage.FirstDragon.DragonCounter, 0) + player:setStorageValue(Storage.FirstDragon.ChestCounter, 0) + player:setStorageValue(Storage.FirstDragon.GelidrazahAccess, 0) + player:setStorageValue(Storage.FirstDragon.SecretsCounter, 0) + end + return true +end +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tanaro.lua b/data/npc/scripts/tanaro.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/tanaro.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tandros.lua b/data/npc/scripts/tandros.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/tandros.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tanyt.lua b/data/npc/scripts/tanyt.lua new file mode 100644 index 00000000000..5c41e1080ff --- /dev/null +++ b/data/npc/scripts/tanyt.lua @@ -0,0 +1,55 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Feel the wind in your hair during one of my carpet rides!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, cost, destination, action, condition) + if condition then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m sorry but I don\'t sail there.'}, condition) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a passage to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, discount = 'postman', destination = destination}, nil, action) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'We would like to serve you some time.', reset = true}) +end + +addTravelKeyword('darashia', 60, Position(33270, 32441, 6)) +addTravelKeyword('svargrond', 40, Position(32253, 31097, 4)) +addTravelKeyword('kazordoon', 80, Position(32588, 31941, 0)) +addTravelKeyword('zao', 60, Position(32983, 31539, 1)) +addTravelKeyword('femor hills', 60, Position(32536, 31837, 4)) +addTravelKeyword('edron', 60, Position(33193, 31784, 3)) + +-- Kick +keywordHandler:addKeyword({'kick'}, StdModule.kick, {npcHandler = npcHandler, destination = {Position(33958, 31512, 1), Position(33959, 31512, 1)}}) + +-- Basic +keywordHandler:addKeyword({'trip'}, StdModule.say, {npcHandler = npcHandler, text = 'I can fly you to {Darashia}, to {Svargrond}, to {Kazordoon}, to {Zao}, to the {Femor Hills} or to {Edron} if you like. Where do you want to go?'}) +keywordHandler:addKeyword({'route'}, StdModule.say, {npcHandler = npcHandler, text = 'I can fly you to {Darashia}, to {Svargrond}, to {Kazordoon}, to {Zao}, to the {Femor Hills} or to {Edron} if you like. Where do you want to go?'}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = 'I can fly you to {Darashia}, to {Svargrond}, to {Kazordoon}, to {Zao}, to the {Femor Hills} or to {Edron} if you like. Where do you want to go?'}) +keywordHandler:addKeyword({'town'}, StdModule.say, {npcHandler = npcHandler, text = 'I can fly you to {Darashia}, to {Svargrond}, to {Kazordoon}, to {Zao}, to the {Femor Hills} or to {Edron} if you like. Where do you want to go?'}) +keywordHandler:addKeyword({'destination'}, StdModule.say, {npcHandler = npcHandler, text = 'I can fly you to {Darashia}, to {Svargrond}, to {Kazordoon}, to {Zao}, to the {Femor Hills} or to {Edron} if you like. Where do you want to go?'}) +keywordHandler:addKeyword({'sail'}, StdModule.say, {npcHandler = npcHandler, text = 'I can fly you to {Darashia}, to {Svargrond}, to {Kazordoon}, to {Zao}, to the {Femor Hills} or to {Edron} if you like. Where do you want to go?'}) +keywordHandler:addKeyword({'go'}, StdModule.say, {npcHandler = npcHandler, text = 'I can fly you to {Darashia}, to {Svargrond}, to {Kazordoon}, to {Zao}, to the {Femor Hills} or to {Edron} if you like. Where do you want to go?'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Ah, the wind brings in another visitor. Welcome, dear guest. Are you looking for a {passage} with my carpet?') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye. Recommend us if you were satisfied with our service.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Good bye then.') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tarak_inner.lua b/data/npc/scripts/tarak_inner.lua new file mode 100644 index 00000000000..11aa82d467e --- /dev/null +++ b/data/npc/scripts/tarak_inner.lua @@ -0,0 +1,52 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if msgcontains(msg, "monument tower") or msgcontains(msg, "passage") or msgcontains(msg, "trip") then + npcHandler:say("Do you want to travel to the {monument tower} for a 50 gold fee?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + local player = Player(cid) + if player:getMoney() + player:getBankBalance() >= 50 then + player:removeMoneyNpc(50) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(Position(32940, 31182, 7), false) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + + elseif player:getBankBalance() >= 50 then + getBankMoney(cid, 50) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(Position(32940, 31182, 7), false) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have enought money.", cid) + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Can I interest you in a trip to the {monument tower}?") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tarak_sunken.lua b/data/npc/scripts/tarak_sunken.lua new file mode 100644 index 00000000000..6343940bead --- /dev/null +++ b/data/npc/scripts/tarak_sunken.lua @@ -0,0 +1,39 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, "passage") then + npcHandler:say("Do you want to go back to {Yalahar}?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + local destination = Position(32916, 31199, 7) + Player(cid):teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Want to go back to Yalahar? Just ask me for a free {passage}.") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tarun.lua b/data/npc/scripts/tarun.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/tarun.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tefrit.lua b/data/npc/scripts/tefrit.lua new file mode 100644 index 00000000000..abddf72f3fa --- /dev/null +++ b/data/npc/scripts/tefrit.lua @@ -0,0 +1,88 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local playerTopic = {} +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.Kilmaresh.First.Access) < 1 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + playerTopic[cid] = 1 + elseif (player:getStorageValue(Storage.Kilmaresh.First.JamesfrancisTask) >= 0 and player:getStorageValue(Storage.Kilmaresh.First.JamesfrancisTask) <= 50) + and player:getStorageValue(Storage.Kilmaresh.First.Mission) < 3 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + playerTopic[cid] = 15 + elseif player:getStorageValue(Storage.Kilmaresh.First.Mission) == 4 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + player:setStorageValue(Storage.Kilmaresh.First.Mission, 5) + playerTopic[cid] = 20 + end + npcHandler:addFocus(cid) +return true +end + +local function creatureSayCallback(cid, type, msg) +if not npcHandler:isFocused(cid) then + return false +end +npcHandler.topic[cid] = playerTopic[cid] +local player = Player(cid) +if msgcontains(msg, "mission") and player:getStorageValue(Storage.Kilmaresh.Eighth.Tefrit) == 1 then + if player:getStorageValue(Storage.Kilmaresh.Eighth.Tefrit) == 1 then + npcHandler:say({"Could you help me do a ritual?"}, cid)-- It needs to be revised, it's not the same as the global + npcHandler.topic[cid] = 1 + playerTopic[cid] = 1 + end +elseif msgcontains(msg, "yes") and playerTopic[cid] == 1 and player:getStorageValue(Storage.Kilmaresh.Eighth.Tefrit) == 1 then + if player:getStorageValue(Storage.Kilmaresh.Eighth.Tefrit) == 1 then + player:addItem(36551, 1) + npcHandler:say({"Here is the list with the missing ingredients to complete the ritual."}, cid)-- It needs to be revised, it's not the same as the global + player:setStorageValue(Storage.Kilmaresh.Eighth.Tefrit, 2) + npcHandler.topic[cid] = 2 + playerTopic[cid] = 2 + else + npcHandler:say({"Sorry."}, cid) + end +end +if msgcontains(msg, "mission") and player:getStorageValue(Storage.Kilmaresh.Eighth.Tefrit) == 2 then + if player:getStorageValue(Storage.Kilmaresh.Eighth.Tefrit) == 2 then + npcHandler:say({"Did you bring all the materials I informed you about?"}, cid)-- It needs to be revised, it's not the same as the global + npcHandler.topic[cid] = 3 + playerTopic[cid] = 3 + end +elseif msgcontains(msg, "yes") and playerTopic[cid] == 3 and player:getStorageValue(Storage.Kilmaresh.Eighth.Tefrit) == 2 then + if player:getStorageValue(Storage.Kilmaresh.Eighth.Tefrit) == 2 and player:getItemById(36164, 20) and player:getItemById(36174, 25) and player:getItemById(36165, 15) then + player:removeItem(11189, 5) + player:removeItem(36164, 20) + player:removeItem(36174, 25) + player:removeItem(36165, 15) + npcHandler:say({"Thank you this stage of the ritual is complete."}, cid)-- It needs to be revised, it's not the same as the global + player:setStorageValue(Storage.Kilmaresh.Eighth.Tefrit, 3) + npcHandler.topic[cid] = 4 + playerTopic[cid] = 4 + else + npcHandler:say({"Sorry."}, cid)-- It needs to be revised, it's not the same as the global + end +end +return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tehlim.lua b/data/npc/scripts/tehlim.lua new file mode 100644 index 00000000000..101678e0045 --- /dev/null +++ b/data/npc/scripts/tehlim.lua @@ -0,0 +1,42 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, "mission") then + if Player(cid):getStorageValue(Storage.HiddenCityOfBeregar.RoyalRescue) < 300 then + npcHandler:say("I warn you, those trolls are WAY more dangerous than the usual kind. Alone, I can't do anything for my brothers. Find a way to the trolls' hideout and rescue my brothers. Are you willing to help me?", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + Player(cid):setStorageValue(Storage.HiddenCityOfBeregar.RoyalRescue, 4) + npcHandler:say(" Great! I hope you find my brothers. Good luck!", cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, "See you my friend.") +npcHandler:setMessage(MESSAGE_FAREWELL, "See you my friend.") +npcHandler:setMessage(MESSAGE_GREET, "Hello. I'm so glad someone has found me. Did you meet THEM?!") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/telas.lua b/data/npc/scripts/telas.lua new file mode 100644 index 00000000000..e86b375bc8d --- /dev/null +++ b/data/npc/scripts/telas.lua @@ -0,0 +1,42 @@ + +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if(msgcontains(msg, "farmine")) then + if(player:getStorageValue(Storage.TheNewFrontier.Questline) == 15) then + npcHandler:say("I have heard only little about this mine. I am a bit absorbed in my studies. But what does this mine have to do with me?", cid) + npcHandler.topic[cid] = 1 + end + elseif(msgcontains(msg, "reason")) then + if(npcHandler.topic[cid] == 1) then + if(player:getStorageValue(Storage.TheNewFrontier.BribeTelas) < 1) then + npcHandler:say("Well it sounds like a good idea to test my golems in some real environment. I think it is acceptable to send some of them to Farmine.", cid) + player:setStorageValue(Storage.TheNewFrontier.BribeTelas, 1) + player:setStorageValue(Storage.TheNewFrontier.Mission05, player:getStorageValue(Storage.TheNewFrontier.Mission05) + 1) --Questlog, The New Frontier Quest "Mission 05: Getting Things Busy" + end + end + end + return true +end +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/telas_golem.lua b/data/npc/scripts/telas_golem.lua new file mode 100644 index 00000000000..77e34f36046 --- /dev/null +++ b/data/npc/scripts/telas_golem.lua @@ -0,0 +1,25 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'What .. happened?'} } +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "Where .. am I?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good .. bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good .. bye.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tereban.lua b/data/npc/scripts/tereban.lua new file mode 100644 index 00000000000..361254adeba --- /dev/null +++ b/data/npc/scripts/tereban.lua @@ -0,0 +1,223 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local config = { + ['strong sinew'] = { + storage = Storage.FathersBurden.Sinew, + messages = { + deliever = 'Do you have the required sinew?', + success = 'Ah, not only did you bring some sinew to me, you also made the world a safer place by killing Heoni.', + failure = 'Sorry, you must be wrong. Perhaps Heoni was out to hunt when you were looking for it. Search in the mountains of Edron. I put my trust in your abilities.', + no = 'Perhaps Heoni was out to hunt when you were looking for it. Search in the mountains of Edron. I put my trust in your abilities.', + done = 'Your bravery earned us this excellent sinew.' + }, + itemId = 12504 + }, + ['exquisite wood'] = { + storage = Storage.FathersBurden.Wood, + messages = { + deliever = 'Could you find the wood we were talking about?', + success = 'Thank you. I feel somewhat embarrassed to put you into such a danger for some birthday present but I am sure you can handle it.', + failure = {'Sorry, you must be wrong. The wood that I need should be in one of the barbarian camps. ...', 'It seems logical to search the most northern camp first, it is closest to the place where the tree was cut. Please hurry, there is still so much to do before the birthday.'}, + no = 'The wood that I need should be in one of the barbarian camps. It seems logical to search the most northern camp first, it is closest to the place where the tree was cut. Please hurry, there is still so much to do before the birthday.', + done = 'The wood you have found is just what we needed.' + }, + itemId = 12503 + }, + ['spectral cloth'] = { + storage = Storage.FathersBurden.Cloth, + messages = { + deliever = 'Could you find the cloth I am looking for?', + success = 'It looks a bit scary but I guess sorcerers might even find that appealing. Thank you very much.', + failure = 'Sorry, you must be wrong. You will find it somewhere in the crypts under the Isle of the Kings. You will probably have to look for hidden caves when you don\'t find it at an obvious place. Perhaps you even need a shovel or a pick.', + no = 'Don\'t forget, you will find it somewhere in the crypts under the Isle of the Kings. You will probably have to look for hidden caves when you don\'t find it at an obvious place. Perhaps you even need a shovel or a pick.', + done = 'Thanks to your efforts we have a suitable piece of spectral cloth.' + }, + itemId = 12502 + }, + ['exquisite silk'] = { + storage = Storage.FathersBurden.Silk, + messages = { + deliever = 'So you\'ve found the silk that I need?', + success = 'Great. I better don\'t think about how big a spider has to be to produce such strands of silk.', + failure = 'Sorry, you must be wrong. Search the spider caves of the continent Zao for the silk. They have to be somewhere in the east of Zao\'s southern part. My sources claim there you will find the silk that we need.', + no = 'Then search the spider caves of the continent Zao for the silk. They have to be somewhere in the east of Zao\'s southern part. My sources claim there you will find the silk that we need.', + done = 'The silk you have brought me is exquisite indeed.' + }, + itemId = 12501 + }, + ['magic crystal'] = { + storage = Storage.FathersBurden.Crystal, + messages = { + deliever = 'Did you find the required crystal?', + success = 'Oh look at the colours and sparkles. This crystal is truly remarkable, thank you.', + failure = {'Sorry, you must be wrong. It is probably not easy to find the crystal that we need in such a huge desert which may contain several tombs, but please don\'t give up. ...', 'According to my sources the tomb we are looking for is east of Ankrahmun. You probably need a shovel to enter it. We still have some time and I am convinced you will find it.'}, + no = {'It is probably not easy to find the crystal that we need in such a huge desert which may contain several tombs, but please don\'t give up. ...', 'According to my sources the tomb we are looking for is east of Ankrahmun. You probably need a shovel to enter it. We still have some time and I am convinced you will find it.'}, + done = 'The crystal you have found is absolutely flawless. You did a great job indeed.' + }, + itemId = 12508 + }, + ['mystic root'] = { + storage = Storage.FathersBurden.Root, + messages = { + deliever = 'Could you find the root which we are looking for?', + success = 'You are admirably determined in fulfilling your task. I will make sure that my sons appreciate what you did for their presents.', + failure = 'Sorry, you must be wrong. The best advice I can give you is to look underground beneath the city for a suitable root.', + no = 'The best advice I can give you is to look underground beneath the city for a suitable root.', + done = 'It is even recognisable for me that the root you gave me is filled with magic.' + }, + itemId = 12507 + }, + ['old iron'] = { + storage = Storage.FathersBurden.Iron, + messages = { + deliever = 'Have you found the iron that we need for the present?', + success = 'I wish there\'d an easier way to get that iron but those dwarfs are so stubborn. However, now we got what we need.', + failure = 'Sorry, you must be wrong. I know it\'s not easy to find this iron but there has to be some in the deposits beneath the old Kazordoon mines. I doubt that it can be found in the newer mines outside of Kazordoon.', + no = 'I know it\'s not easy to find this iron but there has to be some in the deposits beneath the old Kazordoon mines. I doubt it that it can be found in the newer mines outside of Kazordoon.', + done = 'The iron that you\'ve found will make an ideal base for a shield.' + }, + itemId = 12505 + }, + ['flexible dragon scale'] = { + storage = Storage.FathersBurden.Scale, + messages = { + deliever = 'Could you get Glitterscale\'s scales yet?', + success = 'These scales must have belonged to a fearsome beast. I envy you for your bravery.', + failure = 'Sorry, you must be wrong. Oh please, search for Glitterscale. It should not be too hard to find it in those caves north of Thais.', + no = 'Oh please, search for Glitterscale. It should not be too hard to find it in those caves north of Thais.', + done = 'Only someone as daring as you could slay the beast to get the necessary scales.' + }, + itemId = 12506 + }, +} + +local message = {} +local storages = { + Storage.FathersBurden.Sinew, Storage.FathersBurden.Wood, + Storage.FathersBurden.Cloth, Storage.FathersBurden.Silk, + Storage.FathersBurden.Crystal, Storage.FathersBurden.Root, + Storage.FathersBurden.Iron, Storage.FathersBurden.Scale +} + +function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if npcHandler.topic[cid] == 0 then + if msgcontains(msg, 'cloak') then + if (player:getStorageValue(Storage.ThreatenedDreams.TroubledMission01) == 14) then + npcHandler:say({ + "I met this troll when he was hanging around near the town. He carried something I would consider rather uncharacteristic for a troll: a stunningly beautiful cloak entirely made of white feathers. I was curious and asked him if he would sell it. ...", + "He seemed to be more interested in some of my coins and a piece of meat than in this unusual garment. Therefore, we made a trade: He got some meat and coins and I got the cloak. ...", + "I had a clue that it was a magical item but nobody in Edron knew something about it. As I have a very lettered friend in Darashia I took a magical carpet flight to visit him and ask him about the cloak. ...", + "But then something very annoying happened: During the flight the wind blew so strongly that it tattered the cloak. Feather after feather was blown off the carpet but I didn't realise it. ...", + "When I reached Darashia there was no cloak just a handful of feathers. *sighs* I'm not sure whether it makes sense to search for these feathers. There was a small wind gust when we were still above Edron. ...", + "But the actual storm began when we were in the air above the Darama. The feathers are now scattered all over the desert I guess. Rather futile to look out for them but if you really want to try: ...", + "The magic carpet made a beeline from Edron to Darashia. You should search along this line on the ground. Good luck!" + }, cid) + player:setStorageValue(Storage.ThreatenedDreams.TroubledMission01, 15) + player:setStorageValue(Storage.ThreatenedDreams.TatteredSwanFeathers, 0) -- Start Mission 'Tattered Swan Feathers' + + else + npcHandler:say("You are not on that mission.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'mission') then + if player:getStorageValue(Storage.FathersBurden.Status) == 1 then + if player:getStorageValue(Storage.FathersBurden.Progress) ~= 8 then + npcHandler:say('Well, I need the parts of a sorcerer\'s robe, a paladin\'s bow, a knight\'s shield, and a druid\'s rod. If you cannot find one of them, ask me about it and I might provide you with some minor hints.', cid) + return true + end + + player:setStorageValue(Storage.FathersBurden.Status, 2) + player:addItem(12657, 1) + player:addExperience(8000, true) + npcHandler:say({ + 'I\'m so glad I finally have all the parts for the presents. Your reward is my eternal gratitude. Well, that and some gold of course. ...', + 'Take this sachet over there, I wrapped the coins into this old cape I had still lying around here from a barter with a stranger, it is of no use for me anyway. Farewell and thank you once again.' + }, cid) + elseif player:getStorageValue(Storage.FathersBurden.Status) == 2 then + npcHandler:say('Thank you for your help!', cid) + return true + else + npcHandler:say({ + 'I have four sons which are very dear to me. Though they were born on the same day and even in the same hour, they took quite different paths in life. ...', + 'Each of them chose a different vocation, one will become a knight, one a sorcerer, one a druid, and the other a paladin. In a few weeks they will reach adulthood and I am holding a birthday party for them. ...', + 'It should become a day to remember and so I want to give them something special as a present. I searched the land for the finest craftsmen so they could create suitable presents for my sons. ...', + 'But something of fine craftsmanship will just not cut it. So I asked them what they would need to create something special. They all came up with lists of rare and expensive items necessary for the task ahead. ...', + 'I spent a small fortune to buy most of the materials but in the end the key components are that rare that they cannot be simply bought somewhere. ...', + 'As far as I understood it, the places where you can get these items are quite dangerous and so it would take some adventurer to get them. ...', + 'That would be your mission if you are interested. Uhm, so are you interested?' + }, cid) + npcHandler.topic[cid] = 1 + end + elseif config[msg:lower()] then + local targetMessage = config[msg:lower()] + if player:getStorageValue(targetMessage.storage) == 2 then + npcHandler:say(targetMessage.messages.done, cid) + return true + end + + npcHandler:say(targetMessage.messages.deliever, cid) + npcHandler.topic[cid] = 2 + message[cid] = targetMessage + end + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, 'yes') then + npcHandler:say('I am relieved someone as capable as you will handle the task. Well, I need the parts of a sorcerer\'s robe, a paladin\'s bow, a knight\'s shield, and a druid\'s wand.', cid) + player:setStorageValue(Storage.FathersBurden.QuestLog, 1) + player:setStorageValue(Storage.FathersBurden.Progress, 0) + player:setStorageValue(Storage.FathersBurden.Status, 1) + for i = 1, #storages do + player:setStorageValue(storages[i], 1) + end + elseif msgcontains(msg, 'no') then + npcHandler:say('Oh my. I really hope you will change your mind.', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + local targetMessage = message[cid] + if msgcontains(msg, 'yes') then + if not player:removeItem(targetMessage.itemId, 1) then + npcHandler:say(targetMessage.messages.failure, cid) + return true + end + + player:setStorageValue(targetMessage.storage, 2) + player:setStorageValue(Storage.FathersBurden.Progress, player:getStorageValue(Storage.FathersBurden.Progress) + 1) + player:addExperience(2500, true) + npcHandler:say(targetMessage.messages.success, cid) + elseif msgcontains(msg, 'no') then + npcHandler:say(targetMessage.messages.no, cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +local function onReleaseFocus(cid) + message[cid] = nil +end + +npcHandler:setMessage(MESSAGE_GREET, "Greetings, friend. Good you are showing up.") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/terrence.lua b/data/npc/scripts/terrence.lua new file mode 100644 index 00000000000..4a0aac4cc96 --- /dev/null +++ b/data/npc/scripts/terrence.lua @@ -0,0 +1,39 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function creatureSayCallback(cid, type, msg) + if(not(npcHandler:isFocused(cid))) then + return false + end + + local player = Player(cid) + -- Missing script for complete the mission 16 of dark trails + if(msgcontains(msg, "mission")) then + if player:getStorageValue(Storage.DarkTrails.Mission16) == 1 then + npcHandler:say("Ahhhhhhhh! Find and investigate the hideout, the mission 17", cid) + setPlayerStorageValue(cid, Storage.DarkTrails.Mission17, 1) + setPlayerStorageValue(cid, Storage.DarkTrails.DoorHideout, 1) + end + else + npcHandler:say("Ahhhhhhhh! ", cid) + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/testserver_assistant.lua b/data/npc/scripts/testserver_assistant.lua new file mode 100644 index 00000000000..7a16b942855 --- /dev/null +++ b/data/npc/scripts/testserver_assistant.lua @@ -0,0 +1,29 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + local player = Player(cid) + if msgcontains(msg, 'money') then + npcHandler:say('There you have', cid) + player:addMoney(100000) + end +end + +npcHandler:setMessage(MESSAGE_FAREWELL, "Happy hunting, old chap!") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tezila.lua b/data/npc/scripts/tezila.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/tezila.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/thanita.lua b/data/npc/scripts/thanita.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/thanita.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/the_beggar_king.lua b/data/npc/scripts/the_beggar_king.lua new file mode 100644 index 00000000000..e40540abaab --- /dev/null +++ b/data/npc/scripts/the_beggar_king.lua @@ -0,0 +1,70 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.DarkTrails.Mission01) == 2 and player:getStorageValue(Storage.DarkTrails.Mission02) == 1 then + npcHandler:say("So I guess you are the one that the magistrate is sending to look after us, eh? ", cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say("You need some quests then come and talk with me again.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + selfSay("Fine. But the first thing you have to know is that we are not the city's problem. We are just trying to survive. We usually seek shelter in the sewers.", cid) + selfSay("There we are comparatively warm and safe. At least we were. But recently something has changed. There is {something} in the sewers. And it is hunting us.", cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, "something") then + if npcHandler.topic[cid] == 2 then + npcHandler:say("Yeah. No one has seen it and lived to tell the tale. People are missing and sometimes there are {traces} of blood or someone heard a scream, but that's all. We have no idea if the killer is a man or a beast, but there is something out there", cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, "traces") then + if npcHandler.topic[cid] == 3 then + npcHandler:say("Some of the more daring of us tried to follow the tracks that were left, but they always lost the trail close to the {abandoned sewers}, in the east of the sewer system.", cid) + npcHandler.topic[cid] = 4 + end + elseif msgcontains(msg, "abandoned sewers") then + if npcHandler.topic[cid] == 4 then + npcHandler:say({ + "Some parts of the sewers were abandoned when they were beyond repair due to old age and earthquakes. ...", + "That part was never truly well liked. There were rumours that the workers found some ancient structures there and that it was ripe with accidents during the construction. ...", + "The city sealed those parts off, and I have no idea how anything could get in or out without the permission of the magistrate. ... ", + "But since you are investigating on their behalf, you might work out some agreement with them, if you're mad enough to enter the sewers at all. ... ", + "However, you will have to talk to one of the Glooth Brothers who are responsible for the sewer system's maintenance. You'll find them somewhere down there." + }, cid, false, true, 10) + player:setStorageValue(Storage.DarkTrails.Mission02, 2) -- Mission 2 end + player:setStorageValue(Storage.DarkTrails.Mission03, 1) -- Mission 3 start + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Hi! You look like someone on a {mission}.") +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye!') -- Need revision + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/the_blind_prophet.lua b/data/npc/scripts/the_blind_prophet.lua new file mode 100644 index 00000000000..7336d8a5745 --- /dev/null +++ b/data/npc/scripts/the_blind_prophet.lua @@ -0,0 +1,63 @@ + +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Don't forget npcHandler = npcHandler in the parameters. It is required for all StdModule functions! +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'Me put name away name long ago. Now only blind prophet of ape people are.'}) +keywordHandler:addKeyword({'blind prophet'}, StdModule.say, {npcHandler = npcHandler, text = 'Me is who in dreams speak to holy banana. Me divine the will of banana.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'Me {prophet} and {guardian} is.'}) +keywordHandler:addKeyword({'prophet'}, StdModule.say, {npcHandler = npcHandler, text = 'Me is who in dreams speak to holy banana. Me divine the will of banana.'}) +keywordHandler:addKeyword({'guardian'}, StdModule.say, {npcHandler = npcHandler, text = 'Me guard the forbidden land behind the great palisade. If any want to enter, he must ask me for transport.'}) +keywordHandler:addKeyword({'forbidden land'}, StdModule.say, {npcHandler = npcHandler, text = 'Me guard the forbidden land behind the great palisade. If any want to enter, he must ask me for transport.'}) +keywordHandler:addKeyword({'hairycles'}, StdModule.say, {npcHandler = npcHandler, text = 'Good ape he is. Has to work hard to make other apes listen but you helped a lot.'}) +keywordHandler:addKeyword({'bong'}, StdModule.say, {npcHandler = npcHandler, text = ' Our holy ancestor he is. Big as mountain. Lizards say they built palisade to keep him but we not believe ... We think Bong palisade built to have peace from pesky lizards. We respect peace of Bong, keep people away from forbidden land.'}) +keywordHandler:addKeyword({'lizards'}, StdModule.say, {npcHandler = npcHandler, text = ' The lizards evil and vengeful are. Ape people on guard must be.'}) +keywordHandler:addKeyword({'ape'}, StdModule.say, {npcHandler = npcHandler, text = 'Our people a lot to learn have. One day we might live in peace with you hairless apes, who knows.'}) +keywordHandler:addKeyword({'excalibug'}, StdModule.say, {npcHandler = npcHandler, text = 'Me not know. Me seldom have visions of not banana related objects.'}) +keywordHandler:addKeyword({'port hope'}, StdModule.say, {npcHandler = npcHandler, text = 'Hairless apes strange people are. '}) + +local function greetCallback(cid) + npcHandler:setMessage(MESSAGE_GREET, "Be greeted, friend of the apes.") + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "transport") or msgcontains(msg, "passage") then + npcHandler:say("You want me to transport you to forbidden land?", cid) + npcHandler.topic[cid] = 1 + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, 'yes') then + npcHandler:say("Take care!", cid) + local destination = Position(33025, 32580, 6) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + elseif msgcontains(msg, 'no') then + npcHandler:say("Wise decision maybe.", cid) + end + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/the_bone_master.lua b/data/npc/scripts/the_bone_master.lua new file mode 100644 index 00000000000..f7eb4cced1e --- /dev/null +++ b/data/npc/scripts/the_bone_master.lua @@ -0,0 +1,99 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "join") then + if player:getStorageValue(Storage.OutfitQuest.NightmareOutfit) < 1 and player:getStorageValue(Storage.OutfitQuest.BrotherhoodOutfit) < 1 then + npcHandler:say({ + "The Brotherhood of Bones has suffered greatly in the past, but we did survive as we always will ...", + "You have proven resourceful by beating the silly riddles the Nightmare Knights set up to test their candidates ...", + "It's an amusing thought that after passing their test you might choose to join the ranks of their sworn enemies ...", + "For the irony of this I ask you, |PLAYERNAME|: Do you want to join the Brotherhood of Bones?" + }, cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "advancement") then + if player:getStorageValue(Storage.OutfitQuest.BrotherhoodOutfit) == 1 then + npcHandler:say("So you want to advance to a {Hyaena} rank? Did you bring 500 demonic essences with you?", cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.OutfitQuest.BrotherhoodOutfit) == 2 then + npcHandler:say("So you want to advance to a {Death Dealer} rank? Did you bring 1000 demonic essences with you?", cid) + npcHandler.topic[cid] = 4 + elseif player:getStorageValue(Storage.OutfitQuest.BrotherhoodOutfit) == 3 then + npcHandler:say("So you want to advance to a {Dread Lord} rank? Did you bring 1500 demonic essences with you?", cid) + npcHandler.topic[cid] = 5 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "But know that your decision will be irrevocable. You will abandon the opportunity to join any order whose doctrine is incontrast to our own ...", + "Do you still want to join the Brotherhood?" + }, cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say({ + "Welcome to the Brotherhood! From now on you will walk the path of Bones. A life full of promises and power has just beenoffered to you ...", + "Take it, if you are up to that challenge ... or perish in agony if you deserve this fate ...", + "You can always ask me about your current rank and about the privileges the ranks grant to those who hold them." + }, cid) + player:setStorageValue(Storage.OutfitQuest.BrotherhoodOutfit, 1) + player:addAchievement('Bone Brother') + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + if player:removeItem(6500, 500) then + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:setStorageValue(Storage.OutfitQuest.BrotherhoodOutfit, 2) + npcHandler:say("You advanced to {Hyaena} rank! You are now able to use teleports of second floor of Knightwatch Tower.", cid) + else + npcHandler:say("Come back when you gather all essences.", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 4 then + if player:removeItem(6500, 1000) then + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:setStorageValue(Storage.OutfitQuest.BrotherhoodOutfit, 3) + player:addItem(6433, 1) + player:addAchievement('Skull and Bones') + npcHandler:say("You advanced to {Death Dealer} rank!", cid) + else + npcHandler:say("Come back when you gather all essences.", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 5 then + if player:removeItem(6500, 1500) then + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:setStorageValue(Storage.OutfitQuest.BrotherhoodOutfit, 4) + player:setStorageValue(Storage.OutfitQuest.BrotherhoodDoor, 1) + player:setStorageValue(Storage.KnightwatchTowerDoor, 1) + player:addAchievement('Dread Lord') + npcHandler:say("You advanced to {Dread Lord} rank! You are now able to use teleports of fourth floor of Knightwatch Tower and to create addon scrolls.", cid) + else + npcHandler:say("Come back when you gather all essences.", cid) + end + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/the_crone.lua b/data/npc/scripts/the_crone.lua new file mode 100644 index 00000000000..489d527bb95 --- /dev/null +++ b/data/npc/scripts/the_crone.lua @@ -0,0 +1,22 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Let me mourn in peace.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "Be greeted, |PLAYERNAME|... mortal.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/the_destiny_seer.lua b/data/npc/scripts/the_destiny_seer.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/the_destiny_seer.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/the_dream_master.lua b/data/npc/scripts/the_dream_master.lua new file mode 100644 index 00000000000..537258b4658 --- /dev/null +++ b/data/npc/scripts/the_dream_master.lua @@ -0,0 +1,97 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "join") then + if player:getStorageValue(Storage.OutfitQuest.BrotherhoodOutfit) < 1 and player:getStorageValue(Storage.OutfitQuest.NightmareOutfit) < 1 then + npcHandler:say({ + "The Nightmare Knights are almost extinct now, and as far as I know I am the only teacher that is left. But you might beright and its time to accept new disciples ...", + "After all you have passed the Dream Challenge to reach this place, which used to be the process of initiation in the past...", + "So I ask you: do you wish to become a member of the ancient order of the Nightmare Knights, |PLAYERNAME|?" + }, cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "advancement") then + if player:getStorageValue(Storage.OutfitQuest.NightmareOutfit) == 1 then + npcHandler:say("So you want to advance to a {Initiate} rank? Did you bring 500 demonic essences with you?", cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.OutfitQuest.NightmareOutfit) == 2 then + npcHandler:say("So you want to advance to a {Dreamer} rank? Did you bring 1000 demonic essences with you?", cid) + npcHandler.topic[cid] = 4 + elseif player:getStorageValue(Storage.OutfitQuest.NightmareOutfit) == 3 then + npcHandler:say("So you want to advance to a {Lord Protector} rank? Did you bring 1500 demonic essences with you?", cid) + npcHandler.topic[cid] = 5 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Please know that your decision is irrevocable. You will abandon the opportunity to join any order whose doctrine is incontrast to our own ...", cid) + npcHandler:say("Do you still want to join our order?", cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say({ + "So I welcome you as the latest member of the order of the Nightmare Knights. You entered this place as a stranger, butyou will leave this place as a friend ...", + "You can always ask me about your current rank and about the privileges the ranks grant to those who hold them." + }, cid) + player:setStorageValue(Storage.OutfitQuest.NightmareOutfit, 1) + player:addAchievement('Nightmare Knight') + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + if player:removeItem(6500, 500) then + player:addItem(7845, 1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:setStorageValue(Storage.OutfitQuest.NightmareOutfit, 2) + npcHandler:say("You advanced to {Initiate} rank! You are now able to use teleports of second floor of Knightwatch Tower.", cid) + else + npcHandler:say("Come back when you gather all essences.", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 4 then + if player:removeItem(6500, 1000) then + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:setStorageValue(Storage.OutfitQuest.NightmareOutfit, 3) + player:addItem(7846, 1) + player:addItem(6391, 1) + player:addAchievement('Nightmare Walker') + npcHandler:say("You advanced to {Dreamer} rank!", cid) + else + npcHandler:say("Come back when you gather all essences.", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 5 then + if player:removeItem(6500, 1500) then + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:setStorageValue(Storage.OutfitQuest.NightmareOutfit, 4) + player:setStorageValue(Storage.OutfitQuest.NightmareDoor, 1) + player:setStorageValue(Storage.KnightwatchTowerDoor, 1) + player:addAchievement('Lord Protector') + npcHandler:say("You advanced to {Lord Protector} rank! You are now able to use teleports of fourth floor of Knightwatch Tower and to create addon scrolls.", cid) + else + npcHandler:say("Come back when you gather all essences.", cid) + end + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/the_empress.lua b/data/npc/scripts/the_empress.lua new file mode 100644 index 00000000000..719ba4bbca2 --- /dev/null +++ b/data/npc/scripts/the_empress.lua @@ -0,0 +1,62 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.Kilmaresh.Fifth.Memories) == 4 then + player:addItem(36249, 1) + npcHandler:setMessage(MESSAGE_GREET, { + "I see. There is enough and adequate evidence that the Ambassador of Rathleton is indeed an arch traitor. So, Eshaya was right. Well done, mortal being. You have proven your loyalty and bravery, therefore allow me to ask you one more favour. ...", + "The Cult of Fafnar is a serious problem for Issavi. The cultists are roaming the sewers and catacombs beneath the city now and again but this time they are really up to something. ...", + "As a member of the Sapphire Blade found out, they are planning to cause a major earthquake, that could severely damage or even destroy Issavi. You may wonder how. ...", + "Well, they want to activate five Fafnar statues which they have already enchanted. They are hidden in the catacombs underneath the city. Please go down and search for the statues. ...", + "Then use this sceptre to bless them in the name of Suon and Bastesh. This will destroy the disastrous enchantment and Issavi will be safe again." + }) + player:setStorageValue(Storage.Kilmaresh.Sixth.Favor, 1) + player:setStorageValue(Storage.Kilmaresh.Sixth.FourMasks, 0) + player:setStorageValue(Storage.Kilmaresh.Sixth.BlessedStatues, 0) + player:setStorageValue(Storage.Kilmaresh.Fifth.Memories, 6) + else + npcHandler:setMessage(MESSAGE_GREET, "Greetings.") + end + npcHandler:addFocus(cid) + return true +end + +local masksDialogue = keywordHandler:addKeyword( + {"mission"}, StdModule.say, { npcHandler = npcHandler, + text = "Did you take all the masks and enchant all the statues?"}, + function (player) return player:getStorageValue(Storage.Kilmaresh.Sixth.Favor) == 10 end +) + + masksDialogue:addChildKeyword( + {"yes"}, StdModule.say, { npcHandler = npcHandler, + text = "Thank you."}, + nil, + function (player) + player:addItem(36408, 1) -- Sun Medal + player:setStorageValue(Storage.Kilmaresh.Sixth.Favor, 11) + end + ) + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/the_first_dragon.lua b/data/npc/scripts/the_first_dragon.lua new file mode 100644 index 00000000000..b5393222af9 --- /dev/null +++ b/data/npc/scripts/the_first_dragon.lua @@ -0,0 +1,136 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +function creatureSayCallback(cid, type, msg) + if(not npcHandler:isFocused(cid)) then + return false + end + local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid + local player = Player(cid) + + if msgcontains(msg, 'reward') and npcHandler.topic[cid] == 0 and player:getStorageValue(34013) < 1 then + npcHandler:say({ + "Have a look at the chests over there. Feel free to take the things you find within. You know, gold, gems and the like. There's also a garment I'm storing here for a while. As it doesn't fit me I have no need for it. ...", + "But it might be a nice outfit for a little human. You also can take the porcelain mask and the feathers. There's a wizard named Muriel in Thais who reportedly embellishes outfits with stuff like this." + }, cid) + player:addOutfit(929, 1) + player:addOutfit(931, 1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:setStorageValue(34013, 1) + npcHandler.topic[cid] = 0 + + elseif msgcontains(msg, 'fight') and npcHandler.topic[cid] == 0 then + npcHandler:say({ + "Even in {retirement} I sometimes succumb to the temptation of sweet battle. Fighting was so different back in the old {times}. You can read about it in my {memoirs}. There should be a copy lying here somewhere." + }, cid) + npcHandler.topic[cid] = 0 + + elseif msgcontains(msg, 'retirement') and npcHandler.topic[cid] == 0 then + npcHandler:say({ + "When you are young, you are much more tolerant towards the burden of life. At a certain age even a {dragon} will start to think about if things will go on forever. ...", + "Eventually there comes a time when you decide all the {hassle} isn't worth it anymore and you decide to concentrate on the {finer} things life has to offer." + }, cid) + npcHandler.topic[cid] = 0 + + elseif msgcontains(msg, 'memoirs') and npcHandler.topic[cid] == 0 then + npcHandler:say({ + "I dictated my memoirs to a human servant. I like the idea to share my thoughts and memories with humanity with the help of a {book}. ...", + "You are my greatest fans after all. ...", + "If it becomes popular, I might consider an orcish translation or even one in bonelord language. ...", + "By the way, it's a funny story how I learnt the bonelord language. However, I saved it for a possible part two of my memoirs." + }, cid) + npcHandler.topic[cid] = 0 + + elseif msgcontains(msg, 'hassle') and npcHandler.topic[cid] == 0 then + npcHandler:say({ + "I really enjoy a good fight now and then. ...", + "A real pain, however, is the constant annoyance caused by tedious fights against adventurers with more healing pots than brain." + }, cid) + npcHandler.topic[cid] = 0 + + elseif msgcontains(msg, 'worthy') and npcHandler.topic[cid] == 0 then + npcHandler:say({ + "To be honest, the first dragon hunters weren't {worthy}. ...", + "They used {weaknesses} to their advantage. It took some time before a dragon could be killed in a fair fight." + }, cid) + npcHandler.topic[cid] = 0 + + elseif msgcontains(msg, 'weaknesses') and npcHandler.topic[cid] == 0 then + npcHandler:say({ + "The first awoken dragons were quite disoriented when leaving the {mists} and re-entering reality. ...", + "This led to certain vulnerabilities. However, the dragons overcame such shortcomings quickly and soon took their rightful place in the food chain, so to say." + }, cid) + npcHandler.topic[cid] = 0 + + elseif msgcontains(msg, 'mists') and npcHandler.topic[cid] == 0 then + npcHandler:say({ + "There was a time before the gods cast the mists of healing over the world. At that time the dragons ruled and burnt the {world}. ...", + "In hindsight I'm not too proud of this. This was some kind of juvenile bullying." + }, cid) + npcHandler.topic[cid] = 0 + + elseif msgcontains(msg, 'world') and npcHandler.topic[cid] == 0 then + npcHandler:say({ + "The world has changed so much; I'm beginning to feel really old. People have changed, the face of the world has changed, even the laws of nature are no longer the same. ...", + "I think it is the greatest advantage of you {humans} to be more flexible and adaptable." + }, cid) + npcHandler.topic[cid] = 0 + + elseif msgcontains(msg, 'books') and npcHandler.topic[cid] == 0 then + npcHandler:say({ + "Your books are an amazing thing. Draconic glyphs are so different. ...", + "They are not only more complicated but also more specific. A single word which always keeps the same meaning is astonishingly effective in its primitive way. ...", + "It helps you to conserve thoughts, stories and history and to share them with others - a {concept} I really appreciate. ...", + "Books are a wonderful {invention}. If you are ever tired of your heroic exploits, take the time to read one." + }, cid) + npcHandler.topic[cid] = 0 + + elseif msgcontains(msg, 'invention') and npcHandler.topic[cid] == 0 then + npcHandler:say({ + "Being powerful creatures themselves, dragons had no need for inventions. ...", + "However, now that times have changed and the pressure increases, even my kin might slowly start to change in order to {adapt}." + }, cid) + npcHandler.topic[cid] = 0 + + elseif msgcontains(msg, 'adapt') and npcHandler.topic[cid] == 0 then + npcHandler:say({ + "Well, surely some of my kin might whine and complain as they always do. ...", + "You have no idea how backwards thinking some dragons can be. A few are even still idealising the times before the {mists}." + }, cid) + npcHandler.topic[cid] = 0 + + elseif msgcontains(msg, 'finer') and npcHandler.topic[cid] == 0 then + npcHandler:say({ + "The definition of finer things is different for a dragon than for a human. ...", + "A young dragon appreciates diving into a lava pool, while an old dragon just can't stand to get rid of the {lava} afterwards and prefers bathing in boiling water." + }, cid) + npcHandler.topic[cid] = 0 + + end + +return TRUE +end + +keywordHandler:addKeyword({'times'}, StdModule.say, {npcHandler = npcHandler, text = "Times have changed . In the past dragons were feared and respected. Only the {demons} rivalled our notoriety."}) +keywordHandler:addKeyword({'demons'}, StdModule.say, {npcHandler = npcHandler, text = "Those upstarts! I wonder why would anyone care about them. They lack our style. For them it is all about brute force and showing-off."}) +keywordHandler:addKeyword({'style'}, StdModule.say, {npcHandler = npcHandler, text = "Breathing fire is an art! Instead of setting everything on fire, you exhale a cone of fire to give a worthy opponent a chance to avoid it."}) +keywordHandler:addKeyword({'humans'}, StdModule.say, {npcHandler = npcHandler, text = "Your lives are so short and meaningless and yet you are here! And as a race you even have your own history and remember things with the help of {books}, which amazes me."}) +keywordHandler:addKeyword({'concept'}, StdModule.say, {npcHandler = npcHandler, text = "I like the idea of books so much that I acquired a human servant to record my memoirs. You find a copy somewhere in my lair."}) +keywordHandler:addKeyword({'lava'}, StdModule.say, {npcHandler = npcHandler, text = "Lava is only fun as long as it doesn't harden - then it turns into an annoyance."}) + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/the_gate_keeper.lua b/data/npc/scripts/the_gate_keeper.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/the_gate_keeper.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/the_librarian.lua b/data/npc/scripts/the_librarian.lua new file mode 100644 index 00000000000..2d609c0bd36 --- /dev/null +++ b/data/npc/scripts/the_librarian.lua @@ -0,0 +1,45 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local voices = { + {text = "I really have to find this scroll. Where did I put it?"}, + {text = "Too much dust here. I should tidy up on occasion."}, + {text = "Someone opened the Grimoire of Flames without permission. Egregious!"} +} + +keywordHandler:addKeyword( + {"ring"}, StdModule.say, { npcHandler = npcHandler, + text = { + "To extract memories from the ring, you have to enter a trance-like state with the help of a hallucinogen. Like this you can see all memories that are stored in the ring. Ask {Faloriel} for a respective potion. ...", + "Drink it while wearing the ring in the Temple of {Bastesh} and say: \'Sa Katesa Tarsani na\'. If the legends are true you will be able to take memories with you in the form of memory shards." + }}, + function (player) return player:getStorageValue(Storage.Kilmaresh.Fourth.Moe) == 4 end, + function (player) + player:setStorageValue(Storage.Kilmaresh.Fifth.Memories, 1) + player:setStorageValue(Storage.Kilmaresh.Fifth.MemoriesShards, 0) + player:setStorageValue(Storage.Kilmaresh.Fourth.Moe, 5) + end +) + +npcHandler:setMessage(MESSAGE_GREET, 'Greetings, dear guest. If you are interested in paperware such as books or scrolls, ask me for a trade.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(VoiceModule:new(voices)) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/the_oracle.lua b/data/npc/scripts/the_oracle.lua new file mode 100644 index 00000000000..386fac2e079 --- /dev/null +++ b/data/npc/scripts/the_oracle.lua @@ -0,0 +1,132 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local vocation = {} +local town = {} +local config = { + towns = { + ["venore"] = TOWNS_LIST.VENORE, + ["thais"] = TOWNS_LIST.THAIS, + ["carlin"] = TOWNS_LIST.CARLIN + }, + vocations = { + ["sorcerer"] = { + text = "A SORCERER! ARE YOU SURE? THIS DECISION IS IRREVERSIBLE!", + vocationId = VOCATION.ID.SORCERER + }, + ["druid"] = { + text = "A DRUID! ARE YOU SURE? THIS DECISION IS IRREVERSIBLE!", + vocationId = VOCATION.ID.DRUID + }, + ["paladin"] = { + text = "A PALADIN! ARE YOU SURE? THIS DECISION IS IRREVERSIBLE!", + vocationId = VOCATION.ID.PALADIN + }, + ["knight"] = { + text = "A KNIGHT! ARE YOU SURE? THIS DECISION IS IRREVERSIBLE!", + vocationId = VOCATION.ID.KNIGHT + } + } +} + +local function greetCallback(cid) + local player = Player(cid) + local level = player:getLevel() + if level < 8 then + npcHandler:say("CHILD! COME BACK WHEN YOU HAVE GROWN UP!", cid) + npcHandler:resetNpc(cid) + return false + elseif level > 10 then + npcHandler:say(player:getName() ..", I CAN'T LET YOU LEAVE - YOU ARE TOO STRONG ALREADY! \z + YOU CAN ONLY LEAVE WITH LEVEL 9 OR LOWER.", cid) + npcHandler:resetNpc(cid) + return false + elseif player:getVocation():getId() > VOCATION.ID.NONE then + npcHandler:say("YOU ALREADY HAVE A VOCATION!", cid) + npcHandler:resetNpc(cid) + return false + else + npcHandler:setMessage(MESSAGE_GREET, player:getName() ..", ARE YOU PREPARED TO FACE YOUR DESTINY?") + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if npcHandler.topic[cid] == 0 then + if msgcontains(msg, "yes") then + npcHandler:say("IN WHICH TOWN DO YOU WANT TO LIVE: {CARLIN}, {THAIS}, OR {VENORE}?", cid) + npcHandler.topic[cid] = 1 + end + elseif npcHandler.topic[cid] == 1 then + local cityTable = config.towns[msg:lower()] + if cityTable then + town[cid] = cityTable + npcHandler:say("IN ".. string.upper(msg) .."! AND WHAT PROFESSION HAVE YOU CHOSEN: \z + {KNIGHT}, {PALADIN}, {SORCERER}, OR {DRUID}?", cid) + npcHandler.topic[cid] = 2 + else + npcHandler:say("IN WHICH TOWN DO YOU WANT TO LIVE: {CARLIN}, {THAIS}, OR {VENORE}?", cid) + end + elseif npcHandler.topic[cid] == 2 then + local vocationTable = config.vocations[msg:lower()] + if vocationTable then + npcHandler:say(vocationTable.text, cid) + npcHandler.topic[cid] = 3 + vocation[cid] = vocationTable.vocationId + else + npcHandler:say("{KNIGHT}, {PALADIN}, {SORCERER}, OR {DRUID}?", cid) + end + elseif npcHandler.topic[cid] == 3 then + if msgcontains(msg, "yes") then + npcHandler:say("SO BE IT!", cid) + player:setVocation(Vocation(vocation[cid])) + player:setTown(Town(town[cid])) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(Town(town[cid]):getTemplePosition()) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + npcHandler:say("THEN WHAT? {KNIGHT}, {PALADIN}, {SORCERER}, OR {DRUID}?", cid) + npcHandler.topic[cid] = 2 + end + end + return true +end + +local function onAddFocus(cid) + town[cid] = 0 + vocation[cid] = 0 +end + +local function onReleaseFocus(cid) + town[cid] = nil + vocation[cid] = nil +end + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:setMessage(MESSAGE_FAREWELL, "COME BACK WHEN YOU ARE PREPARED TO FACE YOUR DESTINY!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "COME BACK WHEN YOU ARE PREPARED TO FACE YOUR DESTINY!") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/the_orc_king.lua b/data/npc/scripts/the_orc_king.lua new file mode 100644 index 00000000000..c6e0abfc56d --- /dev/null +++ b/data/npc/scripts/the_orc_king.lua @@ -0,0 +1,126 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local creatures = { 'Slime', 'Slime', 'Slime', 'Orc Warlord', 'Orc Warlord', 'Orc Leader', 'Orc Leader', 'Orc Leader' } +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.OrcKingGreeting) ~= 1 then + player:setStorageValue(Storage.OrcKingGreeting, 1) + for i = 1, #creatures do + Game.createMonster(creatures[i], Npc():getPosition()) + end + npcHandler:say('Arrrrgh! A dirty paleskin! To me my children! Kill them my guards!', TALKTYPE_SAY) + return false + else + npcHandler:setMessage(MESSAGE_GREET, 'Harrrrk! You think you are strong now? You shall never escape my wrath! I am immortal!') + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + local efreet, marid = player:getStorageValue(Storage.DjinnWar.EfreetFaction.Mission03), player:getStorageValue(Storage.DjinnWar.MaridFaction.Mission03) + -- Mission 3 - Orc Fortress + if msgcontains(msg, 'lamp') then + if efreet == 1 or marid == 1 then + if player:getStorageValue(Storage.DjinnWar.ReceivedLamp) ~= 1 then + npcHandler:say({ + 'I can sense your evil intentions to imprison a djinn! You are longing for the lamp, which I still possess. ...', + 'Who do you want to trap in this cursed lamp?' + }, cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say('For eons he was trapped in an enchanted lamp by some ancient race. Now he\'s free to roam the world again. Although he cheated me I appreciate what he and his brethren will do to this world, now it\'s the time of the Djinn again!', cid) + end + end + + elseif msgcontains(msg, 'cookie') then + if player:getStorageValue(Storage.WhatAFoolish.Questline) == 31 and player:getStorageValue(Storage.WhatAFoolish.CookieDelivery.OrcKing) ~= 1 then + npcHandler:say('You bring me a stinking cookie???', cid) + npcHandler.topic[cid] = 2 + end + + -- Mission 3 - Orc Fortress + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, 'malor') then + if efreet == 1 then + player:setStorageValue(Storage.DjinnWar.EfreetFaction.DoorToLamp, 1) + + elseif marid == 1 then + player:setStorageValue(Storage.DjinnWar.MaridFaction.DoorToLamp, 1) + end + + player:setStorageValue(Storage.DjinnWar.ReceivedLamp, 1) + player:addItem(2344, 1) + npcHandler:say('I was waiting for this day! Take the lamp and let Malor feel my wrath!', cid) + else + npcHandler:say('I don\'t know your enemy, paleskin! Begone!', cid) + end + npcHandler.topic[cid] = 0 + + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, 'yes') then + if not player:removeItem(8111, 1) then + npcHandler:say('You have no cookie that I\'d like.', cid) + npcHandler.topic[cid] = 0 + return true + end + + player:setStorageValue(Storage.WhatAFoolish.CookieDelivery.OrcKing, 1) + if player:getCookiesDelivered() == 10 then + player:addAchievement('Allow Cookies?') + end + + Npc():getPosition():sendMagicEffect(CONST_ME_GIFT_WRAPS) + npcHandler:say('Well, I hope it stinks a lot. I like stinking cookies best ... BY MY THOUSAND SONS! YOU ARE SO DEAD HUMAN! DEAD!', cid) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + + elseif msgcontains(msg, 'no') then + npcHandler:say('I see.', cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +keywordHandler:addKeyword({'immortal'}, StdModule.say, {npcHandler = npcHandler, text = 'I am Charkahn the Slayer! The immortal father of the {orcs} and master of this {hive}.'}) +keywordHandler:addKeyword({'orcs'}, StdModule.say, {npcHandler = npcHandler, text = 'The orcs are the bearers of Blogs rage. This makes us the ultimate fighters and the most powerful of all races.'}) +keywordHandler:addKeyword({'divine'}, StdModule.say, {npcHandler = npcHandler, text = 'The orcs are the bearers of Blogs rage. This makes us the ultimate fighters and the most powerful of all races.'}) +keywordHandler:addKeyword({'hive'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense the presence and the feelings of my underlings and {minions}. I embrace the rage of the horde.'}) +keywordHandler:addKeyword({'minions'}, StdModule.say, {npcHandler = npcHandler, text = 'The orcish horde of this hive is under my control. I sense their emotions and their needs and provide them with the leadership they need to focus their hate and rage'}) +keywordHandler:addKeyword({'hate'}, StdModule.say, {npcHandler = npcHandler, text = 'Hate and rage are the true blessings of Blog, since they are powerful weapons. They give the hive strength. I provide them with direction and focus.'}) +keywordHandler:addKeyword({'blog'}, StdModule.say, {npcHandler = npcHandler, text = 'The Raging One blessed us with his burning hate. We are truly his children and therefore {divine}.'}) +keywordHandler:addKeyword({'direction'}, StdModule.say, {npcHandler = npcHandler, text = 'To conquer, to destroy and to dominate. Orcs are born to rule the {world}.'}) +keywordHandler:addKeyword({'world'}, StdModule.say, {npcHandler = npcHandler, text = 'One day I will rule the world, even when turned into a {slime}.'}) +keywordHandler:addKeyword({'slime'}, StdModule.say, {npcHandler = npcHandler, text = 'Pah! Don\'t mock me, mortal! This shape is a curse which the evil {djinn} bestowed upon me!'}) +keywordHandler:addKeyword({'djinn'}, StdModule.say, {npcHandler = npcHandler, text = 'This cursed djinn king! I set him free from an enchanted {lamp}, and he {cheated} me!'}) +keywordHandler:addKeyword({'cheated'}, StdModule.say, {npcHandler = npcHandler, text = 'Because I freed him he granted me three wishes. He was true to his word in the first two {wishes}.'}) +keywordHandler:addKeyword({'wishes'}, StdModule.say, {npcHandler = npcHandler, text = 'He built this fortress over Uldrek\'s grave within a single night. Also, he granted me my second wish and gave me immortality. Test it and try to kill me if you want. Har Har!'}) +keywordHandler:addKeyword({'third'}, StdModule.say, {npcHandler = npcHandler, text = 'I wished to father more healthy and fertile children as any orc has ever done. But the djinn cheated me and made me a slime! Then he laughed at me and left for his abandoned fortress in the {Deathwish} Mountains.'}) +keywordHandler:addKeyword({'deathwish'}, StdModule.say, {npcHandler = npcHandler, text = 'His ancient fortress on Darama was deserted as the evil Djinn fled this world after his imprisonment. Now the time has come for the evil Djinns to return to their master although this will certainly awaken the {good Djinn} too.'}) +keywordHandler:addKeyword({'good djinn'}, StdModule.say, {npcHandler = npcHandler, text = 'I will not share anything more about that topic with you {paleskins}.'}) +keywordHandler:addKeyword({'paleskins'}, StdModule.say, {npcHandler = npcHandler, text = 'You are as ugly as maggots, although not quite as as tasty.'}) +keywordHandler:addKeyword({'malor'}, StdModule.say, {npcHandler = npcHandler, text = 'This cursed djinn king! I set him free from an enchanted lamp, and he cheated me!'}, function(player) return player:getStorageValue(Storage.DjinnWar.ReceivedLamp) == 1 end) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/the_queen_of_the_banshees.lua b/data/npc/scripts/the_queen_of_the_banshees.lua new file mode 100644 index 00000000000..e5b983f4977 --- /dev/null +++ b/data/npc/scripts/the_queen_of_the_banshees.lua @@ -0,0 +1,227 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Uhhhhhh....'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + local player = Player(cid) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, "seventh seal") then + npcHandler:say("If you have passed the first six seals and entered the blue fires that lead to \z + the chamber of the seal you might receive my {kiss} ... It will open the last seal. \z + Do you think you are ready?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "kiss") and npcHandler.topic[cid] == 7 then + if player:getStorageValue(Storage.Quest.TheQueenOfTheBanshees.LastSeal) < 1 then + npcHandler:say("Are you prepared to receive my kiss, even though this will mean that your \z + death as well as a part of your soul will forever belong to me, my dear?", cid) + npcHandler.topic[cid] = 8 + else + npcHandler:say("You have already received my kiss. You should know better then to ask for it.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "spectral dress") then + if player:getStorageValue(Storage.ExplorerSociety.TheSpectralDress) == 48 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 48 and player:getStorageValue(Storage.ExplorerSociety.BansheeDoor) < 1 then + npcHandler:say("Your wish for a spectral dress is silly. \z + Although I will grant you the permission to take one. \z + My maidens left one in a box in a room, directly south of here.", cid) + player:setStorageValue(Storage.ExplorerSociety.BansheeDoor, 1) + end + elseif msgcontains(msg, "addon") then + if player:getStorageValue(Storage.OutfitQuest.WizardAddon) == 5 then + npcHandler:say("Say... I have been longing for something for an eternity now... \z + if you help me retrieve it, I will reward you. Do you consent to this arrangement?", cid) + npcHandler.topic[cid] = 9 + end + elseif msgcontains(msg, "orchid") or msgcontains(msg, "holy orchid") then + if player:getStorageValue(Storage.OutfitQuest.WizardAddon) == 6 then + npcHandler:say("Have you really brought me 50 holy orchids?", cid) + npcHandler.topic[cid] = 11 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + if player:getStorageValue(Storage.Quest.TheQueenOfTheBanshees.FourthSeal) == 1 then + npcHandler:say("The Queen of the Banshee: Yessss, I can sense you have passed the seal of sacrifice. \z + Have you passed any other seal yet?", cid) + npcHandler.topic[cid] = 2 + else + npcHandler:say("You have not passed the seal of sacrifice yet. Return to me when you are better prepared.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 2 then + if player:getStorageValue(Storage.Quest.TheQueenOfTheBanshees.FirstSeal) == 1 then + npcHandler:say("The Queen of the Banshee: I sense you have passed the hidden seal as well. \z + Have you passed any other seal yet?", cid) + npcHandler.topic[cid] = 3 + else + npcHandler:say("You have not found the hidden seal yet. Return when you are better prepared.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 3 then + if player:getStorageValue(Storage.Quest.TheQueenOfTheBanshees.SecondSeal) == 1 then + npcHandler:say("The Queen of the Banshee: Oh yes, you have braved the plague seal. \z + Have you passed any other seal yet?", cid) + npcHandler.topic[cid] = 4 + else + npcHandler:say("You have not faced the plagueseal yet. Return to me when you are better prepared.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 4 then + if player:getStorageValue(Storage.Quest.TheQueenOfTheBanshees.ThirdSeal) == 1 then + npcHandler:say("The Queen of the Banshee: Ah, I can sense the power of the seal of \z + demonrage burning in your heart. Have you passed any other seal yet?", cid) + npcHandler.topic[cid] = 5 + else + npcHandler:say("You are not filled with the fury of the imprisoned demon. Return when you are better prepared.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 5 then + if player:getStorageValue(Storage.Quest.TheQueenOfTheBanshees.FifthSeal) == 1 then + npcHandler:say("The Queen of the Banshee: So, you have managed to pass the seal of the true path. \z + Have you passed any other seal yet?", cid) + npcHandler.topic[cid] = 6 + else + npcHandler:say("You have not found your true path yet. Return when you are better prepared.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 6 then + if player:getStorageValue(Storage.Quest.TheQueenOfTheBanshees.SixthSeal) == 1 then + npcHandler:say("The Queen of the Banshee: I see! You have mastered the seal of logic. \z + You have made the sacrifice, you have seen the unseen, you possess fortitude, \z + you have filled yourself with power and found your path. You may ask me for my {kiss} now.", cid) + npcHandler.topic[cid] = 7 + else + npcHandler:say("You have not found your true path yet. Return to meh when you are better prepared.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 8 then + if not player:isPzLocked() then + npcHandler:say("So be it! Hmmmmmm...", cid) + npcHandler.topic[cid] = 0 + player:teleportTo({x = 32202, y = 31812, z = 8}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.LastSeal, 1) + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.LastSealDoor, 1) + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.BansheeDoor, 1) + else + npcHandler:say("You have spilled too much blood recently and the dead are hungry for your soul. \z + Perhaps return when you regained you inner balance.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 9 then + npcHandler:say({ + "Listen... there are no blooming flowers down here and the only smell present is that of death and decay. ...", + "I wish that I could breathe the lovely smell of beautiful flowers just one more time, \z + especially those which elves cultivate. ...", + "Could you please bring me 50 holy orchids?" + }, cid) + npcHandler.topic[cid] = 10 + elseif npcHandler.topic[cid] == 10 then + npcHandler:say("Thank you. I will wait for your return.", cid) + player:setStorageValue(Storage.OutfitQuest.WizardAddon, 6) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 11 then + if player:removeItem(5922, 50) then + npcHandler:say("Thank you! You have no idea what that means to me. As promised,here is your reward... as a follower of Zathroth, I hope that you will like this accessory.", cid) + player:setStorageValue(Storage.OutfitQuest.WizardAddon, 7) + player:addOutfitAddon(145, 1) + player:addOutfitAddon(149, 1) + player:addAchievement('Warlock') + npcHandler.topic[cid] = 0 + else + npcHandler:say("You need 50 holy orchid.", cid) + npcHandler.topic[cid] = 0 + end + end + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] >= 1 and npcHandler.topic[cid] <= 7 then + npcHandler:say("Then try to be better prepared next time we meet.", cid) + elseif npcHandler.topic[cid] == 8 then + npcHandler:say("Perhaps it is the better choice for you, my dear.", cid) + end + end + return true +end + +keywordHandler:addKeyword({'stay'}, StdModule.say, + { + npcHandler = npcHandler, + text = "It's my curse to be the eternal {guardian} of this ancient {place}." + } +) +keywordHandler:addKeyword({'guardian'}, StdModule.say, + { + npcHandler = npcHandler, + text = "I'm the {guardian} of the {SEVENTH} and final seal. The seal to open the last door before ... \z + but perhaps it's better to see it with your own eyes." + } +) +keywordHandler:addKeyword({'place'}, StdModule.say, + { + npcHandler = npcHandler, + text = "It served as a temple, a source of power and ... \z + as a sender for an ancient {race} which lived a long time ago and has long been forgotten." + } +) +keywordHandler:addKeyword({'race'}, StdModule.say, + { + npcHandler = npcHandler, + text = "The race that built this edifice came to this place from the stars. \z + They ran from an enemy even more horrible than themselves. \z + But they carried the {seed} of their own destruction in them." + } +) +keywordHandler:addKeyword({'seed'}, StdModule.say, + { + npcHandler = npcHandler, + text = "This ancient race was annihilated by its own doings, that's all I know. \z + Aeons have passed since then, but the sheer presence of this {complex} is still defiling and desecrating this area." + } +) +keywordHandler:addKeyword({'complex'}, StdModule.say, + { + npcHandler = npcHandler, + text = "Its constructors were too strange for you or even me to understand. \z + We don't know what this ... thing they built was supposed to be good for. \z + I feel a constant twisting and binding of souls, though, that is probably only a side-effect." + } +) +keywordHandler:addKeyword({'ghostlands'}, StdModule.say, + { + npcHandler = npcHandler, + text = "The place you know as the Ghostlands had a different name once ... \z + and many names after. Too many to remember them all." + } +) +keywordHandler:addKeyword({'banshee'}, StdModule.say, + { + npcHandler = npcHandler, + text = "They are my maidens. They give me comfort in my eternal watch over the last seal." + } +) + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:setMessage(MESSAGE_GREET, "Be greeted, dear visitor. Come and {stay} ... a while.") +npcHandler:setMessage(MESSAGE_FAREWELL, "We will meet again, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Yes, flee from death. But know it shall be always one step behind you.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/theodore_loveless.lua b/data/npc/scripts/theodore_loveless.lua new file mode 100644 index 00000000000..438e89b9487 --- /dev/null +++ b/data/npc/scripts/theodore_loveless.lua @@ -0,0 +1,49 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + if msgcontains(msg, 'cigar') then + npcHandler:say('Oh my. Have you gotten an exquisite cigar for me, my young friend?', cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, 'yes') and npcHandler.topic[cid] == 1 then + local player = Player(cid) + if not player:removeItem(7499, 1) then + npcHandler.topic[cid] = 0 + return true + end + + player:setStorageValue(Storage.WhatAFoolish.Cigar, 1) + Npc():getPosition():sendMagicEffect(CONST_ME_EXPLOSIONHIT) + npcHandler:say({ + 'Ah what a fine blend. I really ...', + 'OUCH! What have you done you fool? How dare you???' + }, cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] == 1 then + npcHandler:say('Oh, then there must be a misunderstanding.', cid) + npcHandler.topic[cid] = 0 + end + + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/thomas.lua b/data/npc/scripts/thomas.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/thomas.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/thorgrin.lua b/data/npc/scripts/thorgrin.lua new file mode 100644 index 00000000000..6c3b471270a --- /dev/null +++ b/data/npc/scripts/thorgrin.lua @@ -0,0 +1,36 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Ask me for a passage...'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, cost, destination) + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Do you seek a ride to ' .. keyword:titleCase() .. ' for |TRAVELCOST|?', cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, cost = cost, discount = 'postman', destination = destination}) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'Then not.', reset = true}) +end + +addTravelKeyword('kazordoon', 210, Position(32659, 31957, 15)) +addTravelKeyword('cormaya', 110, Position(33310, 31988, 15)) + +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = "Do you want me take you to {Cormaya} or {Kazordoon}?"}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome, |PLAYERNAME|! May earth protect you on the rocky grounds. If you need a {passage} back, I can help you.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye then.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/thorwulf.lua b/data/npc/scripts/thorwulf.lua new file mode 100644 index 00000000000..6a0f132228f --- /dev/null +++ b/data/npc/scripts/thorwulf.lua @@ -0,0 +1,221 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addSpellKeyword({'find', 'person'}, + { + npcHandler = npcHandler, + spellName = 'Find Person', + price = 80, level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'great', 'light'}, + { + npcHandler = npcHandler, + spellName = 'Great Light', + price = 500, level = 13, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'light'}, + { + npcHandler = npcHandler, + spellName = 'Light', + price = 0, level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'magic', 'rope'}, + { + npcHandler = npcHandler, + spellName = 'Magic Rope', + price = 200, level = 9, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'cure', 'poison'}, + { + npcHandler = npcHandler, + spellName = 'Cure Poison', + price = 150, level = 10, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'intense', 'wound', 'cleansing'}, + { + npcHandler = npcHandler, + spellName = 'Intense Wound Cleansing', + price = 6000, level = 80, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'wound', 'cleansing'}, + { + npcHandler = npcHandler, + spellName = 'Wound Cleansing', + price = 0, level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'levitate'}, + { + npcHandler = npcHandler, + spellName = 'Levitate', + price = 500, level = 12, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'haste'}, + { + npcHandler = npcHandler, + spellName = 'Haste', + price = 600, level = 14, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'brutal', 'strike'}, + { + npcHandler = npcHandler, + spellName = 'Brutal Strike', + price = 1000, level = 16, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'charge'}, + { + npcHandler = npcHandler, + spellName = 'Charge', + price = 1300, level = 25, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'whirlwind', 'throw'}, + { + npcHandler = npcHandler, + spellName = 'Whirlwind Throw', + price = 1500, level = 28, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'groundshaker'}, + { + npcHandler = npcHandler, + spellName = 'Groundshaker', + price = 1500, level = 33, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'fierce', 'berserk'}, + { + npcHandler = npcHandler, + spellName = 'Fierce Berserk', + price = 7500, level = 90, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'berserk'}, + { + npcHandler = npcHandler, + spellName = 'Berserk', + price = 2500, level = 35, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'inflict', 'wound'}, + { + npcHandler = npcHandler, + spellName = 'Inflict Wound', + price = 2500, level = 40, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'cure', 'bleeding'}, + { + npcHandler = npcHandler, + spellName = 'Cure Bleeding', + price = 2500, level = 45, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'intense', 'recovery'}, + { + npcHandler = npcHandler, + spellName = 'Intense Recovery', + price = 10000, level = 100, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'recovery'}, + { + npcHandler = npcHandler, + spellName = 'Recovery', + price = 4000, level = 50, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'front', 'sweep'}, + { + npcHandler = npcHandler, + spellName = 'Front Sweep', + price = 4000, level = 70, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'annihilation'}, + { + npcHandler = npcHandler, + spellName = 'Annihilation', + price = 20000, level = 110, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) + +keywordHandler:addKeyword({'healing', 'spells'}, StdModule.say, + { + npcHandler = npcHandler, + text = "In this category I have '{Bruise Bane}', '{Cure Bleeding}', '{Wound Cleansing}', \z + '{Cure Poison}', '{Intense Wound Cleansing}', '{Recovery}' and '{Intense Recovery}'." + } +) +keywordHandler:addKeyword({'attack', 'spells'}, StdModule.say, + { + npcHandler = npcHandler, + text = {"In this category I have '{Whirlwind Throw}', '{Groundshaker}', '{Berserk}' and '{Fierce Berserk}' \z + as well as ...", "'{Brutal Strike}', '{Front Sweep}', '{Inflict Wound}' and '{Annihilation}'"} + } +) +keywordHandler:addKeyword({'support', 'spells'}, StdModule.say, + { + npcHandler = npcHandler, + text = "In this category I have '{Light}', '{Find Person}', '{Magic Rope}', '{Levitate}', '{Haste}', \z + '{Charge}' and '{Great Light}'." + } +) +keywordHandler:addKeyword({'spells'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'I can teach you {healing spells}, {attack spells} and {support spells}. \z + What kind of spell do you wish to learn? \z + You can also tell me for which level you would like to learn a spell, if you prefer that.' + } +) + +npcHandler:setMessage(MESSAGE_GREET, 'Hi |PLAYERNAME|.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Bye |PLAYERNAME|.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Bye.') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tibra.lua b/data/npc/scripts/tibra.lua new file mode 100644 index 00000000000..f21cc5b6492 --- /dev/null +++ b/data/npc/scripts/tibra.lua @@ -0,0 +1,96 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Wooden Stake +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'I think you have forgotten to bring your stake, my child.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 2 and player:getItemCount(5941) == 0 end) + +local stakeKeyword = keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes, I was informed what to do. Are you prepared to receive my line of the prayer?'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 2 end) + stakeKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'So receive my prayer: \'Hope may fill your heart - doubt shall be banned\'. Now, bring your stake to Maealil in the elven settlement for the next line of the prayer. I will inform him what to do.', reset = true}, nil, + function(player) player:setStorageValue(Storage.FriendsandTraders.TheBlessedStake, 3) player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) end + ) + stakeKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'I will wait for you.', reset = true}) + +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You should visit Maealil in the elven settlement now, my child.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 3 end) +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You already received my line of the prayer, dear child.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) > 3 end) +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'A blessed stake? That is a strange request, my child. Maybe Quentin knows more, he is one of the oldest monks after all.'}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I am a priest of the great pantheon.'}) +keywordHandler:addKeyword({'life'}, StdModule.say, {npcHandler = npcHandler, text = 'The teachings of Crunor tell us to honor life and not to harm it.'}) +keywordHandler:addKeyword({'mission'}, StdModule.say, {npcHandler = npcHandler, text = 'It is my mission to bring the teachings of the gods to everyone.'}) +keywordHandler:addKeyword({'quest'}, StdModule.say, {npcHandler = npcHandler, text = 'It is my mission to bring the teachings of the gods to everyone.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Tibra. Your soul tells me that you are |PLAYERNAME|.'}) +keywordHandler:addKeyword({'queen'}, StdModule.say, {npcHandler = npcHandler, text = 'Queen Eloise is wise to listen to the proposals of the druidic followers of Crunor.'}) +keywordHandler:addKeyword({'sell'}, StdModule.say, {npcHandler = npcHandler, text = 'The grace of the gods must be earned, it cannot be bought!'}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = 'The world of Tibia is the creation of the gods.'}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = 'Now, it is |TIME|.'}) +keywordHandler:addKeyword({'crypt'}, StdModule.say, {npcHandler = npcHandler, text = 'There\'s something strange in its neighbourhood. But whom we gonna call for help if not the gods?'}) +keywordHandler:addKeyword({'monsters'}, StdModule.say, {npcHandler = npcHandler, text = 'Remind: Not everything you call monster is evil to the core!'}) +keywordHandler:addKeyword({'excalibug'}, StdModule.say, {npcHandler = npcHandler, text = 'The mythical blade was hidden in ancient times. Its said that powerful wards protect it.'}) +keywordHandler:addKeyword({'ferumbras'}, StdModule.say, {npcHandler = npcHandler, text = 'The fallen one should be mourned, not feared.'}) +keywordHandler:addKeyword({'lugri'}, StdModule.say, {npcHandler = npcHandler, text = 'Only a man can fall as low as he did. His soul rotted away already.'}) +keywordHandler:addKeyword({'gods'}, StdModule.say, {npcHandler = npcHandler, text = 'The gods of good guard us and guide us, the gods of evil want to destroy us and steal our souls!'}) +keywordHandler:addKeyword({'gods of good'}, StdModule.say, {npcHandler = npcHandler, text = 'The gods we call the good ones are Fardos, Uman, the Elements, Suon, Crunor, Nornur, Bastesh, Kirok, Toth, and Banor.'}) +keywordHandler:addKeyword({'fardos'}, StdModule.say, {npcHandler = npcHandler, text = 'Fardos is the creator. The great obsever. He is our caretaker.'}) +keywordHandler:addKeyword({'uman'}, StdModule.say, {npcHandler = npcHandler, text = 'Uman is the positive aspect of magic. He brings us the secrets of the arcane arts.'}) +keywordHandler:addKeyword({'air'}, StdModule.say, {npcHandler = npcHandler, text = 'Air is one of the primal elemental forces, sometimes worshipped by tribal shamans.'}) +keywordHandler:addKeyword({'fire'}, StdModule.say, {npcHandler = npcHandler, text = 'Fire is one of the primal elemental forces, sometimes worshipped by tribal shamans.'}) +keywordHandler:addKeyword({'sula'}, StdModule.say, {npcHandler = npcHandler, text = 'Sula is the essence of the elemental power of water.'}) +keywordHandler:addKeyword({'suon'}, StdModule.say, {npcHandler = npcHandler, text = 'Suon is the lifebringing sun. He observes the creation with love.'}) +keywordHandler:addKeyword({'crunor'}, StdModule.say, {npcHandler = npcHandler, text = 'Crunor, the great tree, is the father of all plantlife. He is a prominent god for many druids.'}) +keywordHandler:addKeyword({'nornur'}, StdModule.say, {npcHandler = npcHandler, text = 'Nornur is the mysterious god of fate. Who knows if he is its creator or just a chronist?'}) +keywordHandler:addKeyword({'bastesh'}, StdModule.say, {npcHandler = npcHandler, text = 'Bastesh, the deep one, is the goddess of the sea and its creatures.'}) +keywordHandler:addKeyword({'kirok'}, StdModule.say, {npcHandler = npcHandler, text = 'Kirok, the mad one, is the god of scientists and jesters.'}) +keywordHandler:addKeyword({'toth'}, StdModule.say, {npcHandler = npcHandler, text = 'Toth, Lord of Death, is the keeper of the souls, the guardian of the afterlife.'}) +keywordHandler:addKeyword({'banor'}, StdModule.say, {npcHandler = npcHandler, text = 'Banor, the heavenly warrior, is the patron of all fighters against evil. He is the gift of the gods to inspire humanity.'}) +keywordHandler:addKeyword({'evil'}, StdModule.say, {npcHandler = npcHandler, text = 'The gods we call the evil ones are Zathroth, Fafnar, Brog, Urgith, and the Archdemons!'}) +keywordHandler:addKeyword({'zathroth'}, StdModule.say, {npcHandler = npcHandler, text = 'Zathroth is the destructive aspect of magic. He is the deciver and the thief of souls.'}) +keywordHandler:addKeyword({'fafnar'}, StdModule.say, {npcHandler = npcHandler, text = 'Fafnar is the scorching sun. She observes the creation with hate and jealousy.'}) +keywordHandler:addKeyword({'brog'}, StdModule.say, {npcHandler = npcHandler, text = 'Brog, the raging one, is the great destroyer. The berserk of darkness.'}) +keywordHandler:addKeyword({'urgith'}, StdModule.say, {npcHandler = npcHandler, text = 'The bonemaster Urgith is the lord of the undead and keeper of the damned souls.'}) +keywordHandler:addKeyword({'archdemons'}, StdModule.say, {npcHandler = npcHandler, text = 'The demons are followers of Zathroth. The cruelest are known as the ruthless seven.'}) +keywordHandler:addKeyword({'ruthless seven'}, StdModule.say, {npcHandler = npcHandler, text = 'I don\'t want to talk about that subject!'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome in the name of the gods, pilgrim |PLAYERNAME|!') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Good bye, |PLAYERNAME|. May the gods be with you to guard and guide you, my child!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tigo.lua b/data/npc/scripts/tigo.lua new file mode 100644 index 00000000000..93d80893407 --- /dev/null +++ b/data/npc/scripts/tigo.lua @@ -0,0 +1,78 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local playerTopic = {} +local function greetCallback(cid) + + local player = Player(cid) + + if player:getStorageValue(Storage.CultsOfTibia.Barkless.Mission) < 2 then + npcHandler:setMessage(MESSAGE_GREET, "There, there initiate. You will now become one of us, as so many before you. One of the {Barkless}. Walk with us and you will walk tall my friend.") + playerTopic[cid] = 1 + end + npcHandler:addFocus(cid) + return true +end + + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + npcHandler.topic[cid] = playerTopic[cid] + local player = Player(cid) + + -- Começou a quest + if msgcontains(msg, "barkless") and npcHandler.topic[cid] == 1 then + npcHandler:say({"You are now one of us. Learn to endure this world's suffering in every facet and take delight in the soothing eternity that waits for the {purest} of us on the other side."}, cid) + npcHandler.topic[cid] = 2 + playerTopic[cid] = 2 + if player:getStorageValue(Storage.CultsOfTibia.Questline) < 1 then + player:setStorageValue(Storage.CultsOfTibia.Questline, 1) + end + if player:getStorageValue(Storage.CultsOfTibia.Barkless.Mission) < 1 then + player:setStorageValue(Storage.CultsOfTibia.Barkless.Mission, 1) + player:setStorageValue(Storage.CultsOfTibia.Barkless.TrialAccessDoor, 1) + end + elseif msgcontains(msg, "purest") and npcHandler.topic[cid] == 2 then + npcHandler:say({"Purification is but one of the difficult steps on your way to the other side. The {trial} of tar, sulphur and ice."}, cid) + npcHandler.topic[cid] = 2 + playerTopic[cid] = 2 + elseif msgcontains(msg, "trial") and npcHandler.topic[cid] == 3 then + npcHandler:say({"The trial consists of three steps. The trial of tar, where you will suffer unbearable heat and embrace the stigma of misfortune. ...", + "The trial of sulphur, where you will bathe in burning sulphur and embrace the stigma of vanity. Then, there is the trial of purification. The truest of us will be purified to face judgement from the {Penitent}.", + "To purge your soul, your body will have to be near absolute zero, the point where life becomes impossible. ...", + "Something about you is different. I know that you will find a way to return even if you should die during the purification. And if you do... Leiden will become aware of you and retreat. ...", + "If he does, follow him into his own chambers. Barkless are neither allowed to go near the throne room, aside from being judged, nor can we actually enter it.", + "He should be easy to defeat with his back to the wall, find him - and delvier us from whatever became of the Penitent."}, cid) + npcHandler.topic[cid] = 0 + playerTopic[cid] = 0 + end + return true +end + + + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tim_the_guard.lua b/data/npc/scripts/tim_the_guard.lua new file mode 100644 index 00000000000..7877eefecc5 --- /dev/null +++ b/data/npc/scripts/tim_the_guard.lua @@ -0,0 +1,57 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "trouble") and player:getStorageValue(Storage.TheInquisition.TimGuard) < 1 and player:getStorageValue(Storage.TheInquisition.Mission01) ~= -1 then + npcHandler:say("Ah, well. Just this morning my new toothbrush fell into the toilet.", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "authorities") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("What do you mean? Of course they will immediately send someone with extra long and thin arms to retrieve it! ", cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, "avoided") then + if npcHandler.topic[cid] == 2 then + npcHandler:say("Your humour might let end you up beaten in some dark alley, you know? No, I don't think someone could have prevented that accident! ", cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, "gods would allow") then + if npcHandler.topic[cid] == 3 then + npcHandler:say("It's not a drama!! I think there is just no god who's responsible for toothbrush safety, that's all ... ", cid) + npcHandler.topic[cid] = 0 + if player:getStorageValue(Storage.TheInquisition.TimGuard) < 1 then + player:setStorageValue(Storage.TheInquisition.TimGuard, 1) + player:setStorageValue(Storage.TheInquisition.Mission01, player:getStorageValue(Storage.TheInquisition.Mission01) + 1) -- The Inquisition Questlog- "Mission 1: Interrogation" + player:getPosition():sendMagicEffect(CONST_ME_HOLYAREA) + end + end + end + return true +end + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "It's my duty to protect the city."}) + +npcHandler:setMessage(MESSAGE_GREET, "LONG LIVE THE KING!") +npcHandler:setMessage(MESSAGE_FAREWELL, "LONG LIVE THE KING!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "LONG LIVE THE KING!") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/timothy.lua b/data/npc/scripts/timothy.lua new file mode 100644 index 00000000000..a769425b6c6 --- /dev/null +++ b/data/npc/scripts/timothy.lua @@ -0,0 +1,45 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if(not npcHandler:isFocused(cid)) then + return false + end + local player = Player(cid) + if(msgcontains(msg, "research notes")) then + if player:getStorageValue(Storage.TheWayToYalahar.QuestLine) == 1 then + npcHandler:say({ + "Oh, you are the contact person of the academy? Here are the notes that contain everything I have found out so far. ...", + "This city is absolutely fascinating, I tell you! If there hadn't been all this trouble and chaos in the past, this city would certainly be the greatest centre of knowledge in the world. ...", + "Oh, by the way, speaking about all the trouble here reminds me of Palimuth, a friend of mine. He is a native who was quite helpful in gathering all these information. ...", + "I'd like to pay him back for his kindness by sending him some experienced helper that assists him in his effort to restore some order in this city. Maybe you are interested in this job?" + }, cid) + npcHandler.topic[cid] = 1 + end + elseif(msgcontains(msg, "yes")) then + if(npcHandler.topic[cid] == 1) then + player:setStorageValue(Storage.TheWayToYalahar.QuestLine, 2) + npcHandler:say("Excellent! You will find Palimuth near the entrance of the city centre. Just ask him if you can assist him in a few missions.", cid) + player:addItem(10090, 1) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/timur.lua b/data/npc/scripts/timur.lua new file mode 100644 index 00000000000..cc2d6f60626 --- /dev/null +++ b/data/npc/scripts/timur.lua @@ -0,0 +1,28 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Equipment and general goods!' }, + { text = 'Selling ammunition and buying bows and crossbows!' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome to my little shop, adventurer! First read my blackboards.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Bye, bye.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Bye, bye.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tired_tree.lua b/data/npc/scripts/tired_tree.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/tired_tree.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/todd.lua b/data/npc/scripts/todd.lua new file mode 100644 index 00000000000..ac4c878417b --- /dev/null +++ b/data/npc/scripts/todd.lua @@ -0,0 +1,49 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if msgcontains(msg, "interesting") then + npcHandler:say({ + "I'd really like to rebuild my reputation someday and maybe find a nice girl. If you come across scrolls of heroic deeds or addresses of lovely maidens... let me know! ...", + "Oh no, it doesn't matter what name is on the scrolls. I'm, uhm... flexible! And money - yes, I can pay. My, erm... uncle died recently and left me a pretty sum. Yes." + }, cid) + end +end + +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am... a traveler. Just leave me alone if you have nothing {interesting} to talk about."}) +keywordHandler:addKeyword({'want'}, StdModule.say, {npcHandler = npcHandler, text = "I am... a traveler. Just leave me alone if you have nothing {interesting} to talk about."}) +keywordHandler:addKeyword({'head'}, StdModule.say, {npcHandler = npcHandler, text = "Uhhh ohhhh one of the beers yesterday must have been bad."}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "My Name? I am To... ahm... hum... My name is {Hugo}."}) +keywordHandler:addKeyword({'hugo'}, StdModule.say, {npcHandler = npcHandler, text = "Yes, that's my name of course."}) +keywordHandler:addKeyword({'todd'}, StdModule.say, {npcHandler = npcHandler, text = "Uh .. I... I met a Todd on the road. He told me he was traveling to Venore, look there for your Todd."}) +keywordHandler:addKeyword({'thais'}, StdModule.say, {npcHandler = npcHandler, text = "I love that city."}) +keywordHandler:addKeyword({'carlin'}, StdModule.say, {npcHandler = npcHandler, text = "I never was there. Now leave me alone."}) +keywordHandler:addKeyword({'resistance'}, StdModule.say, {npcHandler = npcHandler, text = "Resistance is futile... uhm... I wonder where I picked that saying up. Oh my head..."}) +keywordHandler:addKeyword({'money'}, StdModule.say, {npcHandler = npcHandler, text = "I don't know anything about money, missing or not."}) +keywordHandler:addKeyword({'eclesius'}, StdModule.say, {npcHandler = npcHandler, text = "He often comes here. But his constant confusion gives me a worse headache than Frodo's beer. I rather avoid him."}) +keywordHandler:addKeyword({'karl'}, StdModule.say, {npcHandler = npcHandler, text = "Uhm, never heard about him... and you can't prove otherwise."}) +keywordHandler:addKeyword({'william'}, StdModule.say, {npcHandler = npcHandler, text = "Thats a common name, perhaps I met a William, not sure about that."}) + +npcHandler:setMessage(MESSAGE_GREET, "Uhm oh hello |PLAYERNAME|... not so loud please... my {head}... What ... do you {want}?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Yes, goodbye |PLAYERNAME|, just leave me alone.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Silence at last.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tokel.lua b/data/npc/scripts/tokel.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/tokel.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tom.lua b/data/npc/scripts/tom.lua new file mode 100644 index 00000000000..4efa22817db --- /dev/null +++ b/data/npc/scripts/tom.lua @@ -0,0 +1,229 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Buying fresh corpses of rats, rabbits and wolves.' }, + { text = 'Oh yeah, I\'m also interested in wolf paws and bear paws.' }, + { text = 'Also buying minotaur leather.' } +} +npcHandler:addModule(VoiceModule:new(voices)) + +local function greetCallback(cid) + local player = Player(cid) + -- Starting mission 6 + if player:getStorageValue(Storage.TheRookieGuard.Mission06) == 1 then + npcHandler:setMessage(MESSAGE_GREET, "Hey there, |PLAYERNAME|. Did Vascalir send you to me for a {mission}?") + -- Not finished mission 6 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission06) > 1 and player:getStorageValue(Storage.TheRookieGuard.Mission06) < 6 then + npcHandler:setMessage(MESSAGE_GREET, "Now, now - we can't work with that. Go back to that wolf den and fulfil your mission! Unless there is anything else I can help you with.") + -- Finishing mission 6 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission06) == 6 then + npcHandler:setMessage(MESSAGE_GREET, "Hey there, |PLAYERNAME|. You look... exhausted. Did you run a lot? And more importantly, were you able to find some war wolf leather?") + else + npcHandler:setMessage(MESSAGE_GREET, "Hey there, |PLAYERNAME|. I'm Tom the tanner. If you have fresh {corpses}, leather, paws or other animal body parts, {trade} with me.") + end + return true +end + +local function farewellCallback(cid) + local player = Player(cid) + if player:getSex() == PLAYERSEX_FEMALE then + npcHandler:setMessage(MESSAGE_FAREWELL, "Good hunting, child.") + else + npcHandler:setMessage(MESSAGE_FAREWELL, "Good hunting, son.") + end + return true +end + +-- The Rookie Guard Quest - Mission 06: Run Like a Wolf + +-- Mission 6: Start +local mission6 = keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "I can help you get boots, but I can't give them to you for free. Besides, you'd want good boots, not that stuff made from rat leather. The best leather you'd find on Rook is wolf leather. ...", + "War wolf leather, to be precise. Problem is - war wolves are rare, and you can't hope to fight and defeat them. So your only chance is to find an already dead war wolf, take his skin, and escape really fast. ...", + "What an interesting coincidence that I've seen a poacher sneak into the wolf den just a few hours ago. I'm not exactly a fan of poachers - they kill too many of our wolves. ...", + "Sooo... what I'm suggesting is: follow his traces into the wolf den, and if you get lucky, you'll be able to take one of his illegally obtained war wolf skins. ...", + "That's why I wouldn't call it 'stealing', what an ugly word... anyway, if you bring the skin back to me, I'll make some great war wolf boots from them. What do you say?" + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission06) == 1 end +) +keywordHandler:addAliasKeyword({"mission"}) + +-- Mission 6: Decline start +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Alright. Can I help you with something else then?" +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission06) == 1 end +) + +-- Mission 6: Accept +mission6:addChildKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "That's what I thought. I marked the wolf den on your map. To go there, exit the village to the north and walk north-east. Good luck finding that poacher and figuring out a plan to take those skins! Hehe.", + ungreet = true +}, +nil, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission06, 2) + player:addMapMark({x = 32138, y = 32132, z = 7}, MAPMARK_GREENSOUTH, "War Wolf Den") +end +) + +-- Mission 6: Decline +mission6:addChildKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Well, then walk Rookgaard barefoot. It's up to you!", + reset = true +}) + +-- Mission 6: Finish - Confirm (Give skin) +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "Hmm... unfortunately the skin is damaged too badly. Whoever skinned this wolf wasn't very skilled at it. Hmm. ...", + "Ah, no need to fret. Tell you what kid, I'm gonna give you some normal leather boots instead. They should keep your feet warm as well. Here you go. ...", + "By the way... that running you did to get out of the cave will be your normal walking speed when you are several levels higher. With each level you gain, you'll also become a little faster. ...", + "There are also other items, spells and equipment that increase your speed. ...", + "You can also tame creatures to ride on that will also increase your speed. So don't worry if you're out of breath now - you won't always be that slow. Now off with you and back to Vascalir, I have work to do." + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission06) == 6 and player:getItemCount(13879) >= 1 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission06, 7) + player:removeItem(13879, 1) + player:addItemEx(Game.createItem(2643, 1), true, CONST_SLOT_WHEREEVER) +end +) + +-- Mission 6: Finish - Decline (Give skin) +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Are you sure? I think I see some war wolf leather on you. You should reply with {yes}." +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission06) == 6 and player:getItemCount(13879) >= 1 end +) + +-- Basic keywords +keywordHandler:addKeyword({'hint'}, StdModule.rookgaardHints, {npcHandler = npcHandler}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'My name is Tom the tanner.'}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m the local {tanner}. I buy fresh animal {corpses}, tan them, and convert them into fine leather clothes which I then sell to {merchants}.'}) +keywordHandler:addKeyword({'merchant'}, StdModule.say, {npcHandler = npcHandler, text = '{Dixi} and {Lee\'Delle} sell my leather clothes in their shops.'}) +keywordHandler:addKeyword({'tanner'}, StdModule.say, {npcHandler = npcHandler, text = 'That\'s my job. It can be dirty at times but it provides enough income for my living.'}) +keywordHandler:addKeyword({'information'}, StdModule.say, {npcHandler = npcHandler, text = 'Do I look like a tourist information centre? Go ask someone else.'}) +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'Help? I will give you a few gold coins if you have some fresh dead {animals} for me. Note the word {fresh}.'}) +keywordHandler:addKeyword({'fresh'}, StdModule.say, {npcHandler = npcHandler, text = 'Fresh means: shortly after their death.'}) +keywordHandler:addKeyword({'how', 'are', 'you'}, StdModule.say, {npcHandler = npcHandler, text = 'Much to do these days.'}) +keywordHandler:addKeyword({'monster'}, StdModule.say, {npcHandler = npcHandler, text = 'Good monsters to start with are rats. They live in the {sewers} under the village of {Rookgaard}.'}) +keywordHandler:addKeyword({'dungeon'}, StdModule.say, {npcHandler = npcHandler, text = 'Dungeons can be dangerous without proper {equipment}.'}) +keywordHandler:addKeyword({'equipment'}, StdModule.say, {npcHandler = npcHandler, text = 'You need at least a {backpack}, a {rope}, a {shovel}, a {weapon}, an {armor} and a {shield}.'}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, I haven\'t been outside for a while, so I don\'t know.'}) + +keywordHandler:addKeyword({'troll'}, StdModule.say, {npcHandler = npcHandler, text = 'Troll leather stinks. Can\'t use it.'}) +keywordHandler:addKeyword({'orc'}, StdModule.say, {npcHandler = npcHandler, text = 'I don\'t buy orcs. Their skin is too scratchy.'}) +keywordHandler:addKeyword({'human'}, StdModule.say, {npcHandler = npcHandler, text = 'Are you crazy?!', ungreet = true}) + +keywordHandler:addKeyword({'backpack'}, StdModule.say, {npcHandler = npcHandler, text = 'Nope, sorry, don\'t sell that. Go see {Al Dee} or {Lee\'Delle}.'}) +keywordHandler:addAliasKeyword({'rope'}) + +keywordHandler:addKeyword({'armor'}, StdModule.say, {npcHandler = npcHandler, text = 'Nope, sorry, don\'t sell that. Ask {Dixi} or {Lee\'Delle}.'}) +keywordHandler:addAliasKeyword({'shield'}) + +keywordHandler:addKeyword({'weapon'}, StdModule.say, {npcHandler = npcHandler, text = 'Nope, sorry, don\'t sell that. Ask {Obi} or {Lee\'Delle}.'}) + +keywordHandler:addKeyword({'corpse'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m buying fresh {corpses} of rats, rabbits and wolves. I don\'t buy half-decayed ones. If you have any for sale, {trade} with me.'}) +keywordHandler:addAliasKeyword({'wares'}) +keywordHandler:addAliasKeyword({'animal'}) +keywordHandler:addAliasKeyword({'sell'}) +keywordHandler:addAliasKeyword({'buy'}) +keywordHandler:addAliasKeyword({'offer'}) + +-- Names +keywordHandler:addKeyword({'al', 'dee'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s an apple polisher.'}) +keywordHandler:addKeyword({'amber'}, StdModule.say, {npcHandler = npcHandler, text = 'Now that\'s an interesting woman.'}) +keywordHandler:addKeyword({'billy'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s a better cook than his cousin {Willie}, actually.'}) +keywordHandler:addKeyword({'willie'}, StdModule.say, {npcHandler = npcHandler, text = 'I kinda like him. At least he says what he thinks.'}) +keywordHandler:addKeyword({'tom'}, StdModule.say, {npcHandler = npcHandler, text = 'Yep.'}) +keywordHandler:addKeyword({'seymour'}, StdModule.say, {npcHandler = npcHandler, text = 'He sticks his nose too much in books.'}) +keywordHandler:addKeyword({'zirella'}, StdModule.say, {npcHandler = npcHandler, text = 'My mother?? Did you meet my mother??'}) +keywordHandler:addKeyword({'santiago'}, StdModule.say, {npcHandler = npcHandler, text = 'I don\'t have a problem with him.'}) +keywordHandler:addKeyword({'paulie'}, StdModule.say, {npcHandler = npcHandler, text = 'Typical pencil pusher.'}) +keywordHandler:addKeyword({'oracle'}, StdModule.say, {npcHandler = npcHandler, text = 'It\'s in the academy, just above Seymour. Go there once you are level 8 to leave this place.'}) +keywordHandler:addKeyword({'obi'}, StdModule.say, {npcHandler = npcHandler, text = 'He is such a hypocrite.'}) +keywordHandler:addKeyword({'norma'}, StdModule.say, {npcHandler = npcHandler, text = 'I like her beer.'}) +keywordHandler:addKeyword({'dixi'}, StdModule.say, {npcHandler = npcHandler, text = 'She buys my fine leather clothes.'}) +keywordHandler:addKeyword({'loui'}, StdModule.say, {npcHandler = npcHandler, text = 'I wonder what spectacular monsters he has found.'}) +keywordHandler:addKeyword({'lee\'delle'}, StdModule.say, {npcHandler = npcHandler, text = 'Her nose is a little high in the air, I think. She never shakes my hand.'}) +keywordHandler:addKeyword({'hyacinth'}, StdModule.say, {npcHandler = npcHandler, text = 'I wonder if he\'s angry because his potion monopoly fell.'}) +keywordHandler:addKeyword({'cipfried'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m not what you\'d call a \'believer\'.'}) +keywordHandler:addKeyword({'dallheim'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s okay.'}) +keywordHandler:addAliasKeyword({'zerbrus'}) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "cough syrup") then + npcHandler:say("I had some cough syrup a while ago. It was stolen in an ape raid. I fear if you want more cough syrup you will have to buy it in the druids guild in carlin.", cid) + elseif msgcontains(msg, "addon") then + if player:getStorageValue(Storage.OutfitQuest.DruidBodyAddon) < 1 then + npcHandler:say("Would you like to wear bear paws like I do? No problem, just bring me 50 bear paws and 50 wolf paws and I'll fit them on.", cid) + player:setStorageValue(Storage.OutfitQuest.DruidBodyAddon, 1) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "paws") or msgcontains(msg, "bear paws") then + if player:getStorageValue(Storage.OutfitQuest.DruidBodyAddon) == 1 then + npcHandler:say("Have you brought 50 bear paws and 50 wolf paws?", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + if player:getItemCount(5896) >= 50 and player:getItemCount(5897) >= 50 then + npcHandler:say("Excellent! Like promised, here are your bear paws. ", cid) + player:removeItem(5896, 50) + player:removeItem(5897, 50) + player:setStorageValue(Storage.OutfitQuest.DruidBodyAddon, 2) + player:addOutfitAddon(148, 1) + player:addOutfitAddon(144, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You don't have all items.", cid) + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_FAREWELL, farewellCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setMessage(MESSAGE_WALKAWAY, 'D\'oh?') +npcHandler:setMessage(MESSAGE_SENDTRADE, 'Sure, check what I buy.') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tomruk_the_ruddy.lua b/data/npc/scripts/tomruk_the_ruddy.lua new file mode 100644 index 00000000000..f2d65c4a917 --- /dev/null +++ b/data/npc/scripts/tomruk_the_ruddy.lua @@ -0,0 +1,94 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Interesting reaction. Bloodcurdling. Must inspect further.' }, + { text = 'This is really sanguine!' }, + { text = 'Hmm... the conductors are too dry to transmit energy.' }, + { text = 'Ah, fresh blood. My favourite.' } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if(msgcontains(msg, 'scroll') or msgcontains(msg, 'mission')) and player:getStorageValue(Storage.GravediggerOfDrefia.Mission35) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission36) < 1 then + npcHandler:say({ + "So someone sent you after a scroll, eh? A stroll for a scroll! Sounds like an old-fashioned necromancer thing. ...", + "Well, this piece here is a rather fascinating thing - see those strange blood stains? - ...", + "My predecessors have had it for quite a while without finding out more - I was hoping to investigate, but there's always so much to do! ...", + "Ah, so you want it, too? Well, do me a favour: fetch two samples and assist in my experiment, in exchange for the scroll piece. Yes?" + }, cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, 'yes') and npcHandler.topic[cid] == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission35) == 1 then + npcHandler:say({ + "Sanguine! I need two different blood samples - The first one from the necromancer's pure blood chamber. ... ", + "I was barred from the premises. For my research! Shameful! I'm a martyr to the cause - oh, the second sample you said? ...", + "The second sample you must retrieve from the sacrificial chamber in the ancient vampire crypts, first floor, far west. ...", + "Take these two sterilised vials, one for each blood basin. Oh, I wish I could go myself! Come back when you have filled both vials." + }, cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission36, 1) + player:addItem(21417, 2) + npcHandler.topic[cid] = 0 + elseif(msgcontains(msg, 'scroll') or msgcontains(msg, 'mission') or msgcontains(msg, 'blood')) and player:getStorageValue(Storage.GravediggerOfDrefia.Mission37) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission38) < 1 then + npcHandler:say("Hello hello! Did you bring those blood samples?", cid) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, 'yes') and npcHandler.topic[cid] == 2 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission37) == 1 then + if player:getItemCount(21419) >= 1 and player:getItemCount(21418) >= 1 then + npcHandler:say({ + "Now, let me see... yes... yes... very good. Let me add THIS ..... swill it... there. Sanguine! ...", + "We're not finished yet. Take this tainted blood vial ...", + "Dab some drops from it on to the four blood pagodas in the inner circle here. Then pull the lightning lever over there." + }, cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission38, 1) + player:removeItem(21418, 1) + player:removeItem(21419, 1) + player:addItem(21449, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say("You haven't got any blood.", cid) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, 'scroll') or msgcontains(msg, 'mission')) and player:getStorageValue(Storage.GravediggerOfDrefia.Mission40) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission41) < 1 then + npcHandler:say("Hello hello! Did Hello hello! Well now, painted all those blood pagodas properly?", cid) + npcHandler.topic[cid] = 3 + elseif msgcontains(msg, 'yes') and npcHandler.topic[cid] == 3 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission40) == 1 then + npcHandler:say({ + "Sanguine! Did you see those sparks! We definitely had some energy transfer! Well done! Now, for your reward. ...", + "Err... I would awfully like to know more about the scroll ...", + "Would you settle for a heartfelt handshake instead - oh, you wouldn't? Well, er, okay ...", + "Give me a minute or two to retrieve it. Ask me for the {scroll} or the {mission}" + }, cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission41, 1) + npcHandler.topic[cid] = 0 + elseif(msgcontains(msg, 'scroll') or msgcontains(msg, 'mission')) and player:getStorageValue(Storage.GravediggerOfDrefia.Mission41) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission42) < 1 then + npcHandler:say("Hello hell- oh, you've come for the scroll, haven't you?", cid) + npcHandler.topic[cid] = 4 + elseif msgcontains(msg, 'yes') and npcHandler.topic[cid] == 4 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission41) == 1 then + npcHandler:say("My heart bleeds to part from it. Here. Extend your hand - I'll just retrieve some blood from in exchange - HOLD STILL.", cid) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission42, 1) + player:addItem(21250, 1) + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tony.lua b/data/npc/scripts/tony.lua new file mode 100644 index 00000000000..d8d1889db14 --- /dev/null +++ b/data/npc/scripts/tony.lua @@ -0,0 +1,51 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "report") then + if player:getStorageValue(Storage.InServiceofYalahar.Questline) == 7 or player:getStorageValue(Storage.InServiceofYalahar.Questline) == 13 then + npcHandler:say("Uhm, report, eh? . ", cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, math.max(1, player:getStorageValue(Storage.InServiceofYalahar.Questline) +1)) + player:setStorageValue(Storage.InServiceofYalahar.Mission02, math.max(1, player:getStorageValue(Storage.InServiceofYalahar.Mission02) +1)) -- StorageValue for Questlog "Mission 02: Watching the Watchmen" + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "pass") then + npcHandler:say("You can {pass} either to the {Arena Quarter} or {Foreigner Quarter}. Which one will it be?", cid) + npcHandler.topic[cid] = 1 + elseif(msgcontains(msg, "arena")) then + if npcHandler.topic[cid] == 1 then + player:teleportTo(Position(32695, 31254, 7)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + end + elseif(msgcontains(msg, "foreigner")) then + if npcHandler.topic[cid] == 1 then + player:teleportTo(Position(32695, 31259, 7)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tooth_fairy.lua b/data/npc/scripts/tooth_fairy.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/tooth_fairy.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/toothless_tim.lua b/data/npc/scripts/toothless_tim.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/toothless_tim.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/topsy.lua b/data/npc/scripts/topsy.lua new file mode 100644 index 00000000000..fb9c1944d94 --- /dev/null +++ b/data/npc/scripts/topsy.lua @@ -0,0 +1,65 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = "Runes, wands, rods, health and mana potions! Have a look!"} } +npcHandler:addModule(VoiceModule:new(voices)) + +local items = { + [VOCATION.CLIENT_ID.SORCERER] = 2190, + [VOCATION.CLIENT_ID.DRUID] = 2182 +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "first rod") or msgcontains(msg, "first wand") then + if player:isMage() then + local itemId = items[player:getVocation():getClientId()] + if player:getStorageValue(Storage.firstMageWeapon) == -1 then + npcHandler:say("So you ask me for a {" .. ItemType(itemId):getName() .. "} to begin your adventure?", cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say("What? I have already gave you one {" .. ItemType(itemId):getName() .. "}!", cid) + end + else + npcHandler:say("Sorry, you aren't a druid either a sorcerer.", cid) + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + player:addItem(itemId, 1) + npcHandler:say("Here you are young adept, take care yourself.", cid) + player:setStorageValue(Storage.firstMageWeapon, 1) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") and npcHandler.topic[cid] == 1 then + npcHandler:say("Ok then.", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:setMessage(MESSAGE_GREET, "Hello, dear |PLAYERNAME|. How can I help you? \z + If you need magical equipment such as runes or wands, just ask me for a trade. ") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye, |PLAYERNAME|. Do come again!") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye, |PLAYERNAME|. Do come again!") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/torence.lua b/data/npc/scripts/torence.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/torence.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tothdral.lua b/data/npc/scripts/tothdral.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/tothdral.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/towncryer.lua b/data/npc/scripts/towncryer.lua new file mode 100644 index 00000000000..f14f37a0f94 --- /dev/null +++ b/data/npc/scripts/towncryer.lua @@ -0,0 +1,45 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = "Hear me! Hear me! The mage Wyrdin in the Edron academy is looking for brave adventurers to undertake a task!" }, + { text = "Hear me! Hear me! The postmaster\'s guild has open spots for aspiring postmen! Contact Kevin Postner at the post office in the plains south of Kazordoon!" }, + { text = "Hear me! Hear me! The inquisition is looking for daring people to fight evil! Apply at the inquisition headquarters next to the Thaian jail!" } +} + +local worldChanges = { + { + storage = GlobalStorage.FuryGates, + text = "Hear ye! Hear ye! A fiery gate has opened, threatening a city! Guard the people frightened, their death would be a pity!" + }, + { + storage = GlobalStorage.Yasir, + text = "Hear ye! Hear ye! What a lucky and beautiful day! Visit Carlin, Ankrahmun, or Liberty Bay. Yasir, the oriental trader might be there. Gather your creature products, for this chance is rare." + }, + { + storage = GlobalStorage.NightmareIsle, + text = "Hear me! Hear me! A river is flooding, south of the outlaw base. Explore a new isle, an unknown place. Don\'t be afraid, but ready your blade." + } +} + +for i = 1, #worldChanges do + if getGlobalStorageValue(worldChanges[i].storage) > 0 then + table.insert(voices, {text = worldChanges[i].text}) + end +end + +npcHandler:addModule(VoiceModule:new(voices)) diff --git a/data/npc/scripts/trimegis.lua b/data/npc/scripts/trimegis.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/trimegis.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/trisha.lua b/data/npc/scripts/trisha.lua new file mode 100644 index 00000000000..ba18d9db99f --- /dev/null +++ b/data/npc/scripts/trisha.lua @@ -0,0 +1,221 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local config = { + ["hardened bones"] = { + value = 1, + message = { + wrongValue = "Well, I'll give you a little hint. They can sometimes be extracted from creatures \z + that consist only of - you guessed it, bones. You need an obsidian knife though.", + deliever = "How are you faring with your mission? Have you collected all 100 hardened bones?", + success = "I'm surprised. That's pretty good for a man. Now, bring us the 100 turtle shells." + }, + itemId = 5925, + count = 100 + }, + ["turtle shells"] = { + value = 2, + message = { + wrongValue = "Turtles can be found on some idyllic islands which have recently been discovered.", + deliever = "Did you get us 100 turtle shells so we can make new shields?", + success = "Well done - for a man. These shells are enough to build many strong new shields. \z + Thank you! Now - show me fighting spirit." + }, + itemId = 5899, + count = 100 + }, + ["fighting spirit"] = { + value = 3, + message = { + wrongValue = "You should have enough fighting spirit if you are a true hero. \z + Sorry, but you have to figure this one out by yourself. Unless someone grants you a wish.", + deliever = "So, can you show me your fighting spirit?", + success = "Correct - pretty smart for a man. But the hardest task is yet to come: \z + the claw from a lord among the dragon lords." + }, + itemId = 5884 + }, + ["dragon claw"] = { + value = 4, + message = { + wrongValue = "You cannot get this special red claw from any common dragon in Tibia. \z + It requires a special one, a lord among the lords.", + deliever = "Have you actually managed to obtain the dragon claw I asked for?", + success = "You did it! I have seldom seen a man as courageous as you. \z + I really have to say that you deserve to wear a spike. Go ask Cornelia to adorn your armour." + }, + itemId = 5919 + } +} + +local message = {} + +local function greetCallback(cid) + npcHandler:setMessage(MESSAGE_GREET, "Salutations, |PLAYERNAME|. What can I do for you?") + message[cid] = nil + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player, storage = Player(cid), Storage.OutfitQuest.WarriorShoulderAddon + if npcHandler.topic[cid] == 0 then + if isInArray({"outfit", "addon"}, msg) then + npcHandler:say("Are you talking about my spiky shoulder pad? You can't buy one of these. \z + They have to be {earned}.", cid) + elseif msgcontains(msg, "earn") then + if player:getStorageValue(storage) < 1 then + npcHandler:say("I'm not sure if you are enough of a hero to earn them. \z + You could try, though. What do you think?", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(storage) >= 1 and player:getStorageValue(storage) < 5 then + npcHandler:say("Before I can nominate you for an award, please complete your task.", cid) + elseif player:getStorageValue(storage) == 5 then + npcHandler:say("You did it! I have seldom seen a man as courageous as you. \z + I really have to say that you deserve to wear a spike. Go ask Cornelia to adorn your armour.", cid) + end + elseif config[msg:lower()] then + local targetMessage = config[msg:lower()] + if player:getStorageValue(storage) ~= targetMessage.value then + npcHandler:say(targetMessage.message.wrongValue, cid) + return true + end + + npcHandler:say(targetMessage.message.deliever, cid) + npcHandler.topic[cid] = 3 + message[cid] = targetMessage + end + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, "yes") then + npcHandler:say({ + "Okay, who knows, maybe you have a chance. A really small one though. Listen up: ...", + "First, you have to prove your guts by bringing me 100 hardened bones. ...", + "Next, if you actually managed to collect that many, please complete a small task for \z + our guild and bring us 100 turtle shells. ...", + "It is said that excellent shields can be created from these. ...", + "Alright, um, afterwards show me that you have fighting spirit. Any true hero needs plenty of that. ...", + "The last task is the hardest. You will need to bring me a claw from a mighty dragon king. ...", + "Did you understand everything I told you and are willing to handle this task?" + }, cid, false, true, 100) + npcHandler.topic[cid] = 2 + elseif msgcontains(msg, "no") then + npcHandler:say("I thought so. Train hard and maybe some day you will be ready to face this mission.", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, "yes") then + player:setStorageValue(storage, 1) + -- This for default start of outfit and addon quests + player:setStorageValue(Storage.OutfitQuest.DefaultStart, 1) + npcHandler:say("Excellent! Don't forget: Your first task is to bring me 100 hardened bones. Good luck!", cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") then + npcHandler:say("Would you like me to repeat the task requirements then?", cid) + npcHandler.topic[cid] = 1 + end + elseif npcHandler.topic[cid] == 3 then + if msgcontains(msg, "yes") then + local targetMessage = message[cid] + if not player:removeItem(targetMessage.itemId, targetMessage.count or 1) then + npcHandler:say("Why do men always lie?", cid) + return true + end + + player:setStorageValue(storage, player:getStorageValue(storage) + 1) + npcHandler:say(targetMessage.message.success, cid) + elseif msgcontains(msg, "no") then + npcHandler:say("Don't give up just yet.", cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addSpellKeyword({"find", "person"}, + { + npcHandler = npcHandler, + spellName = "Find Person", + price = 80, + level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"light"}, + { + npcHandler = npcHandler, + spellName = "Light", + price = 0, + level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"cure", "poison"}, + { + npcHandler = npcHandler, + spellName = "Cure Poison", + price = 150, + level = 10, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"wound", "cleansing"}, + { + npcHandler = npcHandler, + spellName = "Wound Cleansing", + price = 0, + level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({"great", "light"}, + { + npcHandler = npcHandler, + spellName = "Great Light", + price = 500, + level = 13, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addKeyword({"healing", "spells"}, StdModule.say, + { + npcHandler = npcHandler, + text = "In this category I have '{Wound Cleansing}'' and '{Cure Poison}''." + } +) +keywordHandler:addKeyword({"support", "spells"}, StdModule.say, + { + npcHandler = npcHandler, + text = "In this category I have '{Light}', '{Find Person}' and '{Great Light}'." + } +) +keywordHandler:addKeyword({"spells"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I can teach you {healing spells} and {support spells}. What kind of spell do you wish to learn? You can also tell me for which level you would like to learn a spell, if you prefer that." + } +) + +npcHandler:setMessage(MESSAGE_WALKAWAY, "Be careful on your journeys.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Don't hurt yourself with that weapon, little one.") + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tristan.lua b/data/npc/scripts/tristan.lua new file mode 100644 index 00000000000..8ee96d53bbf --- /dev/null +++ b/data/npc/scripts/tristan.lua @@ -0,0 +1,234 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addSpellKeyword({'find', 'person'}, + { + npcHandler = npcHandler, + spellName = 'Find Person', + price = 80, + level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'great', 'light'}, + { + npcHandler = npcHandler, + spellName = 'Great Light', + price = 500, + level = 13, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'light'}, + { + npcHandler = npcHandler, + spellName = 'Light', + price = 0, + level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'magic', 'rope'}, + { + npcHandler = npcHandler, + spellName = 'Magic Rope', + price = 200, + level = 9, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'cure', 'poison'}, + { + npcHandler = npcHandler, + spellName = 'Cure Poison', + price = 150, + level = 10, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'intense', 'wound', 'cleansing'}, + { + npcHandler = npcHandler, + spellName = 'Intense Wound Cleansing', + price = 6000, + level = 80, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'wound', 'cleansing'}, + { + npcHandler = npcHandler, + spellName = 'Wound Cleansing', + price = 0, + level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'levitate'}, + { + npcHandler = npcHandler, + spellName = 'Levitate', + price = 500, + level = 12, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'haste'}, + { + npcHandler = npcHandler, + spellName = 'Haste', + price = 600, + level = 14, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'brutal', 'strike'}, + { + npcHandler = npcHandler, + spellName = 'Brutal Strike', + price = 1000, + level = 16, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'charge'}, + { + npcHandler = npcHandler, + spellName = 'Charge', + price = 1300, + level = 25, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'whirlwind', 'throw'}, + { + npcHandler = npcHandler, + spellName = 'Whirlwind Throw', + price = 1500, + level = 28, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'groundshaker'}, + { + npcHandler = npcHandler, + spellName = 'Groundshaker', + price = 1500, + level = 33, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'fierce', 'berserk'}, + { + npcHandler = npcHandler, + spellName = 'Fierce Berserk', + price = 7500, + level = 90, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'berserk'}, + { + npcHandler = npcHandler, + spellName = 'Berserk', + price = 2500, + level = 35, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'inflict', 'wound'}, + { + npcHandler = npcHandler, + spellName = 'Inflict Wound', + price = 2500, + level = 40, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'cure', 'bleeding'}, + { + npcHandler = npcHandler, + spellName = 'Cure Bleeding', + price = 2500, + level = 45, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'intense', 'recovery'}, + { + npcHandler = npcHandler, + spellName = 'Intense Recovery', + price = 10000, + level = 100, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'recovery'}, + { + npcHandler = npcHandler, + spellName = 'Recovery', + price = 4000, + level = 50, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'front', 'sweep'}, + { + npcHandler = npcHandler, + spellName = 'Front Sweep', + price = 4000, + level = 70, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'annihilation'}, + { + npcHandler = npcHandler, + spellName = 'Annihilation', + price = 20000, + level = 110, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) + +keywordHandler:addKeyword({'healing', 'spells'}, StdModule.say, + { + npcHandler = npcHandler, + text = "In this category I have '{Bruise Bane}', '{Cure Bleeding}', '{Wound Cleansing}', '{Cure Poison}', '{Intense Wound Cleansing}', '{Recovery}' and '{Intense Recovery}'." + } +) +keywordHandler:addKeyword({'attack', 'spells'}, StdModule.say, + { + npcHandler = npcHandler, + text = {"In this category I have '{Whirlwind Throw}', '{Groundshaker}', '{Berserk}' and '{Fierce Berserk}' as well as ...", "'{Brutal Strike}', '{Front Sweep}', '{Inflict Wound}' and '{Annihilation}'"} + } +) +keywordHandler:addKeyword({'support', 'spells'}, StdModule.say, + { + npcHandler = npcHandler, + text = "In this category I have '{Light}', '{Find Person}', '{Magic Rope}', '{Levitate}', '{Haste}', '{Charge}' and '{Great Light}'." + } +) +keywordHandler:addKeyword({'spells'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'I can teach you {healing spells}, {attack spells} and {support spells}. What kind of spell do you wish to learn? You can also tell me for which level you would like to learn a spell, if you prefer that.' + } +) + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tulf.lua b/data/npc/scripts/tulf.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/tulf.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/turvy.lua b/data/npc/scripts/turvy.lua new file mode 100644 index 00000000000..4391ff7d3ae --- /dev/null +++ b/data/npc/scripts/turvy.lua @@ -0,0 +1,27 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Courageous adventurers, come buy your weapons and armors here!'} } +npcHandler:addModule(VoiceModule:new(voices)) + + +npcHandler:setMessage(MESSAGE_GREET, "Hello, dear |PLAYERNAME|. Can I be of any assistance? Just tell me if you'd like to {trade} weapons or armor.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye, |PLAYERNAME|. Do come again!.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye, |PLAYERNAME|. Do come again!.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Of course, just browse through my offers.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tylius.lua b/data/npc/scripts/tylius.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/tylius.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/tyrias.lua b/data/npc/scripts/tyrias.lua new file mode 100644 index 00000000000..2f6293b6bac --- /dev/null +++ b/data/npc/scripts/tyrias.lua @@ -0,0 +1,109 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Twist of Fate +local blessKeyword = keywordHandler:addKeyword({'twist of fate'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'This is a special blessing I can bestow upon you once you have obtained at least one of the other blessings and which functions a bit differently. ...', + 'It only works when you\'re killed by other adventurers, which means that at least half of the damage leading to your death was caused by others, not by monsters or the environment. ...', + 'The {twist of fate} will not reduce the death penalty like the other blessings, but instead prevent you from losing your other blessings as well as the amulet of loss, should you wear one. It costs the same as the other blessings. ...', + 'Would you like to receive that protection for a sacrifice of |PVPBLESSCOST| gold, child?' + }}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the protection of the twist of fate, pilgrim.', cost = '|PVPBLESSCOST|', bless = 6}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Adventurer Stone +keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Keep your adventurer\'s stone well.'}, function(player) return player:getItemById(18559, true) end) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for free?'}, function(player) return player:getStorageValue(Storage.AdventurersGuild.FreeStone.Tyrias) ~= 1 end) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, nil, function(player) player:addItem(18559, 1) player:setStorageValue(Storage.AdventurersGuild.FreeStone.Tyrias, 1) end) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for 30 gold?'}) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, + function(player) return player:getMoney() + player:getBankBalance() >= 30 end, + function(player) if player:removeMoneyNpc(30) then player:addItem(18559, 1) end end + ) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, you don\'t have enough money.', reset = true}) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +-- Wooden Stake +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You don\'t even have that strange stake with you.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 10 and player:getItemCount(5941) == 0 end) + +local stakeKeyword = keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'Brewster sent me a strange message about some strange hocus-pocus. I think it\'s nonsense, but since you have come that far, I\'ll play along. Are you ready?'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 10 end) + stakeKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'So receive my prayer: \'Your mind shall be a vessel for joy, light and wisdom\' - uh, wow, something happened. Well, I guess that\'s it, but next time if you need some mumbo jumbo rather go to Chondur.', reset = true}, + function(player) return player:getItemCount(5941) > 0 end, + function(player) player:setStorageValue(Storage.FriendsandTraders.TheBlessedStake, 11) player:removeItem(5941, 1) player:addItem(5942, 1) end + ) + stakeKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'You don\'t even have that strange stake with you.', reset = true}) + stakeKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem, I have other things to do.', reset = true}) + +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'A blessed stake? I don\'t believe in things like that. If anyone does, it\'s probably old Quentin.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) < 10 end) +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'I won\'t do that rubbish again. Go pester Chondur with your hocus-pocus.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 11 end) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.'}, function(player) return player:hasBlessing(2) end) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin will provide you with the embrace of Tibia.'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, young |PLAYERNAME|! If you are heavily wounded or poisoned, I can {heal} you for free.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Remember: If you are heavily wounded or poisoned, I can heal you for free.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'May the gods bless you, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ubaid.lua b/data/npc/scripts/ubaid.lua new file mode 100644 index 00000000000..0548ff7c5eb --- /dev/null +++ b/data/npc/scripts/ubaid.lua @@ -0,0 +1,134 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local function greetCallback(cid, message) + local player = Player(cid) + if not msgcontains(message, "djanni'hah") and player:getStorageValue(Storage.DjinnWar.Faction.EfreetDoor) ~= 1 then + npcHandler:say('Shove off, little one! Humans are not welcome here, |PLAYERNAME|!', cid) + return false + end + + if player:getStorageValue(Storage.DjinnWar.Faction.Greeting) == -1 then + npcHandler:say({ + 'Hahahaha! ...', + '|PLAYERNAME|, that almost sounded like the word of greeting. Humans - cute they are!' + }, cid) + return false + end + + if player:getStorageValue(Storage.DjinnWar.Faction.EfreetDoor) ~= 1 then + npcHandler:setMessage(MESSAGE_GREET, 'What? You know the word, |PLAYERNAME|? All right then - I won\'t kill you. At least, not now. What brings you {here}?') + else + npcHandler:setMessage(MESSAGE_GREET, 'Still alive, |PLAYERNAME|? What brings you {here}?') + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + -- To Appease the Mighty Quest + if msgcontains(msg, "mission") and player:getStorageValue(Storage.TibiaTales.ToAppeaseTheMightyQuest) == 2 then + npcHandler:say({ + 'You have the smell of the Marid on you. Tell me who sent you?'}, cid) + npcHandler.topic[cid] = 9 + elseif msgcontains(msg, "kazzan") and npcHandler.topic[cid] == 9 then + npcHandler:say({ + 'And he is sending a worm like you to us!?! The mighty Efreet!! Tell him that we won\'t be part in his \'great\' plans and now LEAVE!! ...', + '...or do you want to join us and fight those stinking Marid who claim themselves to be noble and righteous?!? Just let me know.'}, cid) + player:setStorageValue(Storage.TibiaTales.ToAppeaseTheMightyQuest, player:getStorageValue(Storage.TibiaTales.ToAppeaseTheMightyQuest) + 1) + end + + if msgcontains(msg, 'passage') then + if player:getStorageValue(Storage.DjinnWar.Faction.EfreetDoor) ~= 1 then + npcHandler:say({ + 'Only the mighty Efreet, the true djinn of Tibia, may enter Mal\'ouquah! ...', + 'All Marid and little worms like yourself should leave now or something bad may happen. Am I right?' + }, cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say('You already pledged loyalty to king Malor!', cid) + end + + elseif msgcontains(msg, 'here') then + npcHandler:say({ + 'Only the mighty Efreet, the true djinn of Tibia, may enter Mal\'ouquah! ...', + 'All Marid and little worms like yourself should leave now or something bad may happen. Am I right?' + }, cid) + npcHandler.topic[cid] = 1 + + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, 'yes') then + npcHandler:say('Of course. Then don\'t waste my time and shove off.', cid) + npcHandler.topic[cid] = 0 + + elseif msgcontains(msg, 'no') then + if player:getStorageValue(Storage.DjinnWar.Faction.MaridDoor) == 1 then + npcHandler:say('Who do you think you are? A Marid? Shove off you worm!', cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say({ + 'Of cour... Huh!? No!? I can\'t believe it! ...', + 'You... you got some nerves... Hmm. ...', + 'Maybe we have some use for someone like you. Would you be interested in working for us. Helping to fight the Marid?' + }, cid) + npcHandler.topic[cid] = 2 + end + end + + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, 'yes') then + npcHandler:say('So you pledge loyalty to king Malor and you are willing to never ever set foot on Marid\'s territory, unless you want to kill them? Yes?', cid) + npcHandler.topic[cid] = 3 + + elseif msgcontains(msg, 'no') then + npcHandler:say('Of course. Then don\'t waste my time and shove off.', cid) + npcHandler.topic[cid] = 0 + end + + elseif npcHandler.topic[cid] == 3 then + if msgcontains(msg, 'yes') then + npcHandler:say({ + 'Well then - welcome to Mal\'ouquah. ...', + 'Go now to general Baa\'leal and don\'t forget to greet him correctly! ...', + 'And don\'t touch anything!' + }, cid) + player:setStorageValue(Storage.DjinnWar.Faction.EfreetDoor, 1) + player:setStorageValue(Storage.DjinnWar.Faction.Greeting, 0) + + elseif msgcontains(msg, 'no') then + npcHandler:say('Of course. Then don\'t waste my time and shove off.', cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +-- Greeting +keywordHandler:addGreetKeyword({"djanni'hah"}, {npcHandler = npcHandler, text = "Shove off, little one! Humans are not welcome here, |PLAYERNAME|"}) + +npcHandler:setMessage(MESSAGE_FAREWELL, 'Farewell human!') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Farewell human!') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/ukea.lua b/data/npc/scripts/ukea.lua new file mode 100644 index 00000000000..eac508821e8 --- /dev/null +++ b/data/npc/scripts/ukea.lua @@ -0,0 +1,25 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +-- Greeting message +keywordHandler:addGreetKeyword({"ashari"}, {npcHandler = npcHandler, text = "Greetings, |PLAYERNAME|."}) +--Farewell message +keywordHandler:addFarewellKeyword({"asgha thrazi"}, {npcHandler = npcHandler, text = "Goodbye, |PLAYERNAME|."}) + +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye!") + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/ula.lua b/data/npc/scripts/ula.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/ula.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ulala.lua b/data/npc/scripts/ulala.lua new file mode 100644 index 00000000000..65a39838db5 --- /dev/null +++ b/data/npc/scripts/ulala.lua @@ -0,0 +1,99 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.UnnaturalSelection.Questline) == 5 then + npcHandler:say({ + "The great hunt! About to begin, but gods are not in favour of us yet. We need all help we get. We please Krunus with special nature dance. ...", + "You seen Krunus altar south in camp, on mountain top? This is where dance is. If you do right steps Krunus will give you sign. If wrong, he not pleased. ...", + "Do Krunus dance for us! Step and dance and turn around! You will know when you do good. Make {Krunus} happy and support our great hunt!" + }, cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.UnnaturalSelection.Questline) == 6 then + npcHandler:say("Come back if you finished the dance.", cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.UnnaturalSelection.Questline) == 7 then + npcHandler:say({ + "You born dancer! Krunus is pleased and support the great hunt. But he easy to please! Pandor much harder. We weak, so he sad about us. ...", + "Maybe we can please with sacrifice of body parts of our enemies. But you need help us get it! We much too weak. ...", + "If you bring us 5 teeth of green men, 5 skin of horned ones and 5 skin of snakemen that already be good. Please help tribe make Pandor happy!" + }, cid) + player:setStorageValue(Storage.UnnaturalSelection.Questline, 8) + player:setStorageValue(Storage.UnnaturalSelection.Mission04, 1) --Questlog, Unnatural Selection Quest "Mission 4: Bits and Pieces" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.UnnaturalSelection.Questline) == 8 then + npcHandler:say("Please help tribe make Pandor happy! Did you bring us what I asked?", cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(Storage.UnnaturalSelection.Questline) == 9 then + npcHandler:say({ + "We need make sure Fasuon is on our side. There is laaaaaaaarge crystal on top of mountain. Don't know where come from, was there before us. Problem is - way is infested with creatures! ...", + "Creatures from the other side of mountain. Bony! Scary! We too weak to go through there, can just run and hope to survive.. but you do better! ...", + "Please find great crystal of Fasuon and pray there for his support!" + }, cid) + player:setStorageValue(Storage.UnnaturalSelection.Questline, 10) + player:setStorageValue(Storage.UnnaturalSelection.Mission05, 1) --Questlog, Unnatural Selection Quest "Mission 5: Ray of Light" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.UnnaturalSelection.Questline) == 10 then + npcHandler:say("Please find great crystal of Fasuon and pray there for his support!", cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.UnnaturalSelection.Questline) == 11 then + npcHandler:say("You prayed to Fasuon! Me saw ray of lights on mountain top! Beautiful it was. Me thank you for your help. Great hunt almost can't go wrong now!", cid) + player:setStorageValue(Storage.UnnaturalSelection.Questline, 12) + player:setStorageValue(Storage.UnnaturalSelection.Mission05, 3) --Questlog, Unnatural Selection Quest "Mission 5: Ray of Light" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.UnnaturalSelection.Questline) == 12 then + npcHandler:say({ + "Uzroth very easy to anger. You been great help so far but me think that need to pray to Uzroth meself. Only me understand what he wants at time and he is veeeeeery moody. Cannot risk to make angry! ...", + "So me will do when you gone. But me thank you very much. Go speak Lazaran and tell the gods are pleased now." + }, cid) + player:setStorageValue(Storage.UnnaturalSelection.Questline, 13) + player:setStorageValue(Storage.UnnaturalSelection.Mission06, 1) --Questlog, Unnatural Selection Quest "Mission 6: Firewater Burn" + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "krunus") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Krunus is God for plants and birth. He hidden in all that grows.", cid) + player:setStorageValue(Storage.UnnaturalSelection.Questline, 6) + player:setStorageValue(Storage.UnnaturalSelection.Mission03, 2) --Questlog, Unnatural Selection Quest "Mission 3: Dance Dance Evolution" + player:setStorageValue(Storage.UnnaturalSelection.DanceStatus, 1) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 2 then + if player:getItemCount(11113) >= 5 and player:getItemCount(5878) >= 5 and player:getItemCount(5876) >= 5 then + player:removeItem(11113, 5) + player:removeItem(5878, 5) + player:removeItem(5876, 5) + npcHandler:say("Me thank you! Me will bring sacrifice for Pandor. He surely be pleased with our work. Well your work, but me won't tell him. Teehee.", cid) + player:setStorageValue(Storage.UnnaturalSelection.Questline, 9) + player:setStorageValue(Storage.UnnaturalSelection.Mission04, 2) --Questlog, Unnatural Selection Quest "Mission 4: Bits and Pieces" + npcHandler.topic[cid] = 0 + else + npcHandler:say("You do not have these things!", cid) + npcHandler.topic[cid] = 0 + end + end + end + return true +end +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ulrik.lua b/data/npc/scripts/ulrik.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/ulrik.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/umar.lua b/data/npc/scripts/umar.lua new file mode 100644 index 00000000000..e6a21a53fe5 --- /dev/null +++ b/data/npc/scripts/umar.lua @@ -0,0 +1,117 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local function greetCallback(cid, message) + local player = Player(cid) + if not msgcontains(message, 'djanni\'hah') and player:getStorageValue(Storage.DjinnWar.Faction.MaridDoor) ~= 1 then + npcHandler:say('Whoa! A human! This is no place for you, |PLAYERNAME|. Go and play somewhere else.', cid) + return false + end + + if player:getStorageValue(Storage.DjinnWar.Faction.Greeting) == -1 then + npcHandler:say({ + 'Hahahaha! ...', + '|PLAYERNAME|, that almost sounded like the word of greeting. Humans - cute they are!' + }, cid) + return false + end + + if player:getStorageValue(Storage.DjinnWar.Faction.MaridDoor) ~= 1 then + npcHandler:setMessage(MESSAGE_GREET, { + 'Whoa? You know the word! Amazing, |PLAYERNAME|! ...', + 'I should go and tell Fa\'hradin. ...', + 'Well. Why are you here anyway, |PLAYERNAME|?' + }) + else + npcHandler:setMessage(MESSAGE_GREET, '|PLAYERNAME|! How\'s it going these days? What brings you {here}?') + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + -- To Appease the Mighty Quest + if msgcontains(msg, "mission") and player:getStorageValue(Storage.TibiaTales.ToAppeaseTheMightyQuest) == 1 then + npcHandler:say({ + 'I should go and tell Fa\'hradin. ...', + 'I am impressed you know our address of welcome! I honour that. So tell me who sent you on a mission to our fortress?'}, cid) + npcHandler.topic[cid] = 9 + elseif msgcontains(msg, "kazzan") and npcHandler.topic[cid] == 9 then + npcHandler:say({ + 'How dare you lie to me?!? The caliph should choose his envoys more carefully. We will not accept his peace-offering ...', + '...but we are always looking for support in our fight against the evil Efreets. Tell me if you would like to join our fight.'}, cid) + player:setStorageValue(Storage.TibiaTales.ToAppeaseTheMightyQuest, player:getStorageValue(Storage.TibiaTales.ToAppeaseTheMightyQuest) + 1) + end + + if msgcontains(msg, 'passage') then + if player:getStorageValue(Storage.DjinnWar.Faction.MaridDoor) ~= 1 then + npcHandler:say({ + 'If you want to enter our fortress you have to become one of us and fight the Efreet. ...', + 'So, are you willing to do so?' + }, cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say('You already have the permission to enter Ashta\'daramai.', cid) + end + + elseif npcHandler.topic[cid] == 1 then + if msgcontains(msg, 'yes') then + if player:getStorageValue(Storage.DjinnWar.Faction.EfreetDoor) ~= 1 then + npcHandler:say('Are you sure? You pledge loyalty to king Gabel, who is... you know. And you are willing to never ever set foot on Efreets\' territory, unless you want to kill them? Yes?', cid) + npcHandler.topic[cid] = 2 + else + npcHandler:say('I don\'t believe you! You better go now.', cid) + npcHandler.topic[cid] = 0 + end + + elseif msgcontains(msg, 'no') then + npcHandler:say('This isn\'t your war anyway, human.', cid) + npcHandler.topic[cid] = 0 + end + + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, 'yes') then + npcHandler:say({ + 'Oh. Ok. Welcome then. You may pass. ...', + 'And don\'t forget to kill some Efreets, now and then.' + }, cid) + player:setStorageValue(Storage.DjinnWar.Faction.MaridDoor, 1) + player:setStorageValue(Storage.DjinnWar.Faction.Greeting, 0) + + elseif msgcontains(msg, 'no') then + npcHandler:say('This isn\'t your war anyway, human.', cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +-- Greeting +keywordHandler:addGreetKeyword({"djanni'hah"}, {npcHandler = npcHandler, text = "Whoa! A human! This is no place for you, |PLAYERNAME|. Go and play somewhere else"}) + +npcHandler:setMessage(MESSAGE_FAREWELL, 'Aaaa -tention!') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Aaaa -tention!') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) + +npcHandler:addModule(FocusModule:new()) \ No newline at end of file diff --git a/data/npc/scripts/uncle.lua b/data/npc/scripts/uncle.lua new file mode 100644 index 00000000000..abc9372c991 --- /dev/null +++ b/data/npc/scripts/uncle.lua @@ -0,0 +1,187 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +local fire = Condition(CONDITION_FIRE) +fire:setParameter(CONDITION_PARAM_DELAYED, true) +fire:setParameter(CONDITION_PARAM_FORCEUPDATE, true) +fire:addDamage(25, 9000, -10) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + player:setStorageValue(Storage.SecretService.Quest, 1) + npcHandler:say('Then welcome to the family.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 2 then + player:setStorageValue(Storage.SecretService.AVINMission01, 4) + player:setStorageValue(Storage.SecretService.Quest, 3) + npcHandler:say('I hope you did not make this little pest too nervous. He isn\'t serving us too well by hiding under some stone or something like that. However, nicely done for your first job.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + if player:removeItem(7705, 1) then + player:setStorageValue(Storage.SecretService.AVINMission02, 2) + player:setStorageValue(Storage.SecretService.Quest, 5) + npcHandler:say('Ah, yes. This will be a most interesting lecture.', cid) + else + npcHandler:say('Please bring me the file AH-X17L89.', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 4 then + player:setStorageValue(Storage.SecretService.AVINMission03, 4) + player:setStorageValue(Storage.SecretService.Quest, 7) + npcHandler:say('Does it not warm up your heart if you can bring a little joy to the people while doing your job? Well, don\'t get carried away, most part of your job is not warming up hearts but tearing them out.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 5 then + player:setStorageValue(Storage.SecretService.AVINMission04, 3) + player:setStorageValue(Storage.SecretService.Quest, 9) + npcHandler:say('Good work getting rid of that nuisance.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 6 then + if player:removeItem(7708, 1) then + player:setStorageValue(Storage.SecretService.AVINMission05, 2) + player:setStorageValue(Storage.SecretService.Quest, 11) + npcHandler:say('Fine, fine. This will serve us quite well. Ah, don\'t give me that look... you are not that stupid, are you?', cid) + else + npcHandler:say('Come back when you\'ve found the ring.', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 7 then + player:setStorageValue(Storage.SecretService.AVINMission06, 3) + player:setStorageValue(Storage.SecretService.Quest, 13) + npcHandler:say('Even if the present has not improved our relations, the weapons will enable the barbarians to put more pressure on Svargrond and Carlin. So in any case we profited from the present.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 8 then + if player:removeItem(7699, 1) then + player:setStorageValue(Storage.SecretService.Mission07, 2) + player:setStorageValue(Storage.SecretService.Quest, 15) + player:addItem(7962, 1) + npcHandler:say({ + 'You have proven yourself as very efficient. The future may hold great things for you in store ...', + 'Take this token of gratitude. I hope you can use well what you will find inside!' + }, cid) + else + npcHandler:say('Please bring me proof of the mad technomancers defeat!', cid) + end + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish.', cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'join') then + if player:getStorageValue(Storage.SecretService.Quest) < 1 then + npcHandler:say({ + 'Well, well, well! As you might know, we are entrusted by the Venorean tradesmen to ensure the safety of their ventures ...', + 'This task often puts our representatives in rather dangerous and challenging situations. On the other hand, you can expect a generous compensation for your efforts on our behalf...', + 'Just keep in mind though that we expect quick action and that we are rather intolerant to needless questions and moral doubts ...', + 'If you join our ranks, you cannot join the service of another city! So do I understand you correctly, you want to join our small business?' + }, cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, 'mission') then + if player:getStorageValue(Storage.SecretService.Quest) == 1 and player:getStorageValue(Storage.SecretService.TBIMission01) < 1 and player:getStorageValue(Storage.SecretService.CGBMission01) < 1 then + player:setStorageValue(Storage.SecretService.Quest, 2) + player:setStorageValue(Storage.SecretService.AVINMission01, 1) + player:addItem(14326, 1) + npcHandler:say('Let\'s start with a rather simple job. There is a contact in Thais with that we need to get in touch again. Deliver this note to Gamel in Thais. Get an answer from him. If he is a bit reluctant, be \'persuasive\'.', cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.SecretService.AVINMission01) == 3 then + npcHandler:say('Do you have news to make old Uncle happy?', cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(Storage.SecretService.AVINMission01) == 4 and player:getStorageValue(Storage.SecretService.Quest) == 3 then + player:setStorageValue(Storage.SecretService.Quest, 4) + player:setStorageValue(Storage.SecretService.AVINMission02, 1) + npcHandler:say({ + 'Our Thaian allies are sometimes a bit forgetful. For this reason we are not always informed timely about certain activities. We won\'t insult our great king by pointing out this flaw ...', + 'Still, we are in dire need of these information so we are forced to take action on our own. Travel to the Thaian castle and \'find\' the documents we need. They have the file name AH-X17L89. ...', + 'Now go to Thaian castle and get the File.' + }, cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.SecretService.AVINMission02) == 1 then + npcHandler:say('Do you have news to make old Uncle happy?', cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.SecretService.AVINMission02) == 2 and player:getStorageValue(Storage.SecretService.Quest) == 5 then + player:setStorageValue(Storage.SecretService.Quest, 6) + player:setStorageValue(Storage.SecretService.AVINMission03, 1) + player:addItem(7706, 1) + npcHandler:say({ + 'The oppression of Carlin\'s men by their lunatic women is unbearable to some of our authorities. We see it as our honourable duty to support the male resistance in Carlin ...', + 'The poor guys have some speakeasy in the sewers. Bring them this barrel of beer with our kind regards to strengthen their resistance.' + }, cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.SecretService.AVINMission03) == 3 then + npcHandler:say('Do you have news to make old Uncle happy?', cid) + npcHandler.topic[cid] = 4 + elseif player:getStorageValue(Storage.SecretService.AVINMission03) == 4 and player:getStorageValue(Storage.SecretService.Quest) == 7 then + player:setStorageValue(Storage.SecretService.Quest, 8) + player:setStorageValue(Storage.SecretService.AVINMission04, 1) + npcHandler:say({ + 'As you know, our lovely city is a bastion of civilisation surrounded by numerous hazards. The nearby Plains of Havoc and the hostile elven town Shadowthorn are only a few of the obstacles we have to overcome on an almost daily basis ...', + 'Against all odds, we managed to gain some modest profit by exploiting these circumstances in one way or the other. Recently though, one of our neighbours went too far...', + 'In some ruin in the midst of the Green Claw Swamp, a dark knight had fancied himself as the lord of the swamp for quite a while ...', + 'For some years, we had some sort of gentleman\'s agreement. In exchange for some supplies and luxuries, the deranged knight used his ominous influence over the local bonelord species to supply us with ... certain goods ...', + 'However, lately the black knight has proven himself to be no gentleman at all. In a fit of unprovoked rage, he slew our emissary and almost all of his henchmen ...', + 'Even though we can live with this loss, it becomes obvious that the knight\'s madness gets worse which makes him unbearable as a neighbour. Find him in his hideout in the Green Claw Swamp and get rid of him.' + }, cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.SecretService.AVINMission04) == 2 then + npcHandler:say('Do you have news to make old Uncle happy?', cid) + npcHandler.topic[cid] = 5 + elseif player:getStorageValue(Storage.SecretService.AVINMission04) == 3 and player:getStorageValue(Storage.SecretService.Quest) == 9 then + player:setStorageValue(Storage.SecretService.Quest, 10) + player:setStorageValue(Storage.SecretService.AVINMission05, 1) + npcHandler:say('I need you to locate a lost ring on the Isle of the Kings for me, get back to me once you have it.', cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.SecretService.AVINMission05) == 1 then + npcHandler:say('Do you have news to make old Uncle happy?', cid) + npcHandler.topic[cid] = 6 + elseif player:getStorageValue(Storage.SecretService.AVINMission05) == 2 and player:getStorageValue(Storage.SecretService.Quest) == 11 then + player:setStorageValue(Storage.SecretService.Quest, 12) + player:setStorageValue(Storage.SecretService.AVINMission06, 1) + player:addItem(7707, 1) + npcHandler:say({ + 'We try to establish new trade agreements with various potential customers. Sometimes we have to offer some presents in advance to ensure that trade is prospering and flourishing. It will be your task to deliver one of those little presents ...', + 'The northern barbarians are extremely hostile to us. The ones living in Svargrond are poisoned by the lies of agitators from Carlin. The barbarians that are also known as raiders are another story though ...', + 'Of course they are extremely wild and hostile but we believe that we will sooner or later profit from it when we are able to improve our relations. Please deliver this chest of weapons to the barbarians as a sign of our good will ...', + 'Unfortunately, most of them will attack you on sight. It will probably take some time until you find somebody that is willing to talk to you and to accept the weapons.' + }, cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.SecretService.AVINMission06) == 2 then + npcHandler:say('Do you have news to make old Uncle happy?', cid) + npcHandler.topic[cid] = 7 + elseif player:getStorageValue(Storage.SecretService.AVINMission06) == 3 and player:getStorageValue(Storage.SecretService.Quest) == 13 then + player:setStorageValue(Storage.SecretService.Quest, 14) + player:setStorageValue(Storage.SecretService.Mission07, 1) + npcHandler:say({ + 'Some dwarven criminal called Blowbeard dares to blackmail our city. He threatens to destroy the whole city and demands an insane amount of gold ...', + 'Of course we are not willing to give him a single gold coin. It will be your job to get rid of this problem. Go and kill this infamous dwarf ...', + 'His laboratory is near the technomancer hall. Bring me his beard as proof of his demise.' + }, cid) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.SecretService.AVINMission06) == 3 and player:getStorageValue(Storage.SecretService.Mission07) == 1 then + npcHandler:say('Do you have news to make old Uncle happy?', cid) + npcHandler.topic[cid] = 8 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/undercover.lua b/data/npc/scripts/undercover.lua new file mode 100644 index 00000000000..5532e4285e4 --- /dev/null +++ b/data/npc/scripts/undercover.lua @@ -0,0 +1,37 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +if not UNDERCOVER_CONTACTED then + UNDERCOVER_CONTACTED = {} +end + +function onCreatureAppear(cid) npcHandler:onCreatureAppear(cid) end +function onCreatureDisappear(cid) npcHandler:onCreatureDisappear(cid) end +function onCreatureSay(cid, type, msg) npcHandler:onCreatureSay(cid, type, msg) end +function onThink() npcHandler:onThink() end + +function greetCallback(cid) + local player = Player(cid) + local status = player:getStorageValue(SPIKE_LOWER_UNDERCOVER_MAIN) + + if isInArray({-1, 3}, status) then + return false + end + + if not UNDERCOVER_CONTACTED[player:getGuid()] then + UNDERCOVER_CONTACTED[player:getGuid()] = {} + end + + if isInArray(UNDERCOVER_CONTACTED[player:getGuid()], Creature(getNpcCid()):getId()) then + return false + end + + player:setStorageValue(SPIKE_LOWER_UNDERCOVER_MAIN, status + 1) + table.insert(UNDERCOVER_CONTACTED[player:getGuid()], Creature(getNpcCid()):getId()) + npcHandler:releaseFocus(cid) + return npcHandler:say("Pssst! Keep it down! ", cid) +end + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/urkalio.lua b/data/npc/scripts/urkalio.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/urkalio.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ursula.lua b/data/npc/scripts/ursula.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/ursula.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/uso.lua b/data/npc/scripts/uso.lua new file mode 100644 index 00000000000..7e4e3350d78 --- /dev/null +++ b/data/npc/scripts/uso.lua @@ -0,0 +1,233 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addSpellKeyword({'find', 'person'}, + { + npcHandler = npcHandler, + spellName = 'Find Person', + price = 80, + level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'great', 'light'}, + { + npcHandler = npcHandler, + spellName = 'Great Light', + price = 500, + level = 13, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'light'}, + { + npcHandler = npcHandler, + spellName = 'Light', + price = 0, + level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'magic', 'rope'}, + { + npcHandler = npcHandler, + spellName = 'Magic Rope', + price = 200, + level = 9, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'cure', 'poison'}, + { + npcHandler = npcHandler, + spellName = 'Cure Poison', + price = 150, + level = 10, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'intense', 'wound', 'cleansing'}, + { + npcHandler = npcHandler, + spellName = 'Intense Wound Cleansing', + price = 6000, + level = 80, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'wound', 'cleansing'}, + { + npcHandler = npcHandler, + spellName = 'Wound Cleansing', + price = 0, + level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'levitate'}, + { + npcHandler = npcHandler, + spellName = 'Levitate', + price = 500, + level = 12, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'haste'}, + { + npcHandler = npcHandler, + spellName = 'Haste', + price = 600, + level = 14, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'brutal', 'strike'}, + { + npcHandler = npcHandler, + spellName = 'Brutal Strike', + price = 1000, + level = 16, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'charge'}, + { + npcHandler = npcHandler, + spellName = 'Charge', + price = 1300, + level = 25, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'whirlwind', 'throw'}, + { + npcHandler = npcHandler, + spellName = 'Whirlwind Throw', + price = 1500, + level = 28, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'groundshaker'}, + { + npcHandler = npcHandler, + spellName = 'Groundshaker', + price = 1500, + level = 33, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'fierce', 'berserk'}, + { + npcHandler = npcHandler, + spellName = 'Fierce Berserk', + price = 7500, + level = 90, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'berserk'}, + { + npcHandler = npcHandler, + spellName = 'Berserk', + price = 2500, + level = 35, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'inflict', 'wound'}, + { + npcHandler = npcHandler, + spellName = 'Inflict Wound', + price = 2500, + level = 40, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'cure', 'bleeding'}, + { + npcHandler = npcHandler, + spellName = 'Cure Bleeding', + price = 2500, + level = 45, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'intense', 'recovery'}, + { + npcHandler = npcHandler, + spellName = 'Intense Recovery', + price = 10000, + level = 100, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'recovery'}, + { + npcHandler = npcHandler, + spellName = 'Recovery', + price = 4000, + level = 50, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'front', 'sweep'}, + { + npcHandler = npcHandler, + spellName = 'Front Sweep', + price = 4000, + level = 70, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'annihilation'}, + { + npcHandler = npcHandler, + spellName = 'Annihilation', + price = 20000, + level = 110, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) + +keywordHandler:addKeyword({'healing', 'spells'}, StdModule.say, + { + npcHandler = npcHandler, + text = "In this category I have '{Bruise Bane}', '{Cure Bleeding}', '{Wound Cleansing}', '{Cure Poison}', '{Intense Wound Cleansing}', '{Recovery}' and '{Intense Recovery}'." + } +) +keywordHandler:addKeyword({'attack', 'spells'}, StdModule.say, + { + npcHandler = npcHandler, + text = {"In this category I have '{Whirlwind Throw}', '{Groundshaker}', '{Berserk}' and '{Fierce Berserk}' as well as ...", "'{Brutal Strike}', '{Front Sweep}', '{Inflict Wound}' and '{Annihilation}'"} + } +) +keywordHandler:addKeyword({'support', 'spells'}, StdModule.say, + { + npcHandler = npcHandler, + text = "In this category I have '{Light}', '{Find Person}', '{Magic Rope}', '{Levitate}', '{Haste}', '{Charge}' and '{Great Light}'." + } +) +keywordHandler:addKeyword({'spells'}, StdModule.say, + { + npcHandler = npcHandler, + text = 'I can teach you {healing spells}, {attack spells} and {support spells}. What kind of spell do you wish to learn? You can also tell me for which level you would like to learn a spell, if you prefer that.' + } +) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ustan.lua b/data/npc/scripts/ustan.lua new file mode 100644 index 00000000000..2315f40f8ae --- /dev/null +++ b/data/npc/scripts/ustan.lua @@ -0,0 +1,55 @@ + +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "cough syrup") then + npcHandler:say("I had some cough syrup a while ago. It was stolen in an ape raid. I fear if you want more cough syrup you will have to buy it in the druids guild in carlin.", cid) + elseif msgcontains(msg, "addon") then + if player:getStorageValue(Storage.OutfitQuest.DruidBodyAddon) < 1 then + npcHandler:say("Would you like to wear bear paws like I do? No problem, just bring me 50 bear paws and 50 wolf paws and I'll fit them on.", cid) + player:setStorageValue(Storage.OutfitQuest.DruidBodyAddon, 1) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "paws") or msgcontains(msg, "bear paws") then + if player:getStorageValue(Storage.OutfitQuest.DruidBodyAddon) == 1 then + npcHandler:say("Have you brought 50 bear paws and 50 wolf paws?", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + if player:getItemCount(5896) >= 50 and player:getItemCount(5897) >= 50 then + npcHandler:say("Excellent! Like promised, here are your bear paws. ", cid) + player:removeItem(5896, 50) + player:removeItem(5897, 50) + player:setStorageValue(Storage.OutfitQuest.DruidBodyAddon, 2) + player:addOutfitAddon(148, 1) + player:addOutfitAddon(144, 1) + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/uzgod.lua b/data/npc/scripts/uzgod.lua new file mode 100644 index 00000000000..46dfb583197 --- /dev/null +++ b/data/npc/scripts/uzgod.lua @@ -0,0 +1,109 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if(not npcHandler:isFocused(cid)) then + return false + end + local player = Player(cid) + if(msgcontains(msg, "piece of draconian steel")) then + npcHandler:say("You bringing me draconian steel and obsidian lance in exchange for obsidian knife?", cid) + npcHandler.topic[cid] = 15 + elseif(msgcontains(msg, "yes") and npcHandler.topic[cid] == 15) then + if player:getItemCount(5889) >= 1 and player:getItemCount(2425) >= 1 then + if player:removeItem(5889, 1) and player:removeItem(2425, 1) then + npcHandler:say("Here you have it.", cid) + player:addItem(5908, 1) + npcHandler.topic[cid] = 0 + end + else + npcHandler:say("You don\'t have these items.", cid) + npcHandler.topic[cid] = 0 + end + end + + if(msgcontains(msg, "pickaxe")) then + if player:getStorageValue(Storage.ExplorerSociety.JoiningTheExplorers) == 1 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 1 then + npcHandler:say("True dwarven pickaxes having to be maded by true weaponsmith! You wanting to get pickaxe for explorer society?", cid) + npcHandler.topic[cid] = 1 + end + elseif(msgcontains(msg, "crimson sword")) then + if player:getStorageValue(Storage.TravellingTrader.Mission05) == 1 then + npcHandler:say("Me don't sell crimson sword.", cid) + npcHandler.topic[cid] = 5 + end + elseif(msgcontains(msg, "forge")) then + if(npcHandler.topic[cid] == 5) then + npcHandler:say("You telling me to forge one?! Especially for you? You making fun of me?", cid) + npcHandler.topic[cid] = 6 + end + elseif(msgcontains(msg, "brooch")) then + if player:getStorageValue(Storage.ExplorerSociety.JoiningTheExplorers) == 2 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 2 then + npcHandler:say("You got me brooch?", cid) + npcHandler.topic[cid] = 3 + end + elseif(msgcontains(msg, "yes")) then + if(npcHandler.topic[cid] == 1) then + npcHandler:say("Me order book quite full is. But telling you what: You getting me something me lost and Uzgod seeing that your pickaxe comes first. Jawoll! You interested?", cid) + npcHandler.topic[cid] = 2 + elseif(npcHandler.topic[cid] == 2) then + npcHandler:say("Good good. You listening: Me was stolen valuable heirloom. Brooch from my family. Good thing is criminal was caught. Bad thing is, criminal now in dwarven prison of dwacatra is and must have taken brooch with him ...", cid) + npcHandler:say("To get into dwacatra you having to get several keys. Each key opening way to other key until you get key to dwarven prison ...", cid) + npcHandler:say("Last key should be in the generals quarter near armory. Only General might have key to enter there too. But me not knowing how to enter Generals private room at barracks. You looking on your own ...", cid) + npcHandler:say("When got key, then you going down to dwarven prison and getting me that brooch. Tell me that you got brooch when having it.", cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.ExplorerSociety.JoiningTheExplorers, 2) + player:setStorageValue(Storage.ExplorerSociety.DwacatraDoor, 1) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 2) + elseif(npcHandler.topic[cid] == 3) then + if player:removeItem(4845, 1) then ----- + npcHandler:say("Thanking you for brooch. Me guessing you now want your pickaxe?", cid) + npcHandler.topic[cid] = 4 + end + elseif(npcHandler.topic[cid] == 4) then + npcHandler:say("Here you have it.", cid) + player:addItem(4874, 1) ----- + player:setStorageValue(Storage.ExplorerSociety.JoiningTheExplorers, 3) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 3) + npcHandler.topic[cid] = 0 + elseif(npcHandler.topic[cid] == 9) then + if player:getMoney() + player:getBankBalance() >= 250 and player:getItemCount(5880) >= 3 then + if player:removeMoneyNpc(250) and player:removeItem(5880, 3) then + npcHandler:say("Ah, that's how me like me customers. Ok, me do this... ... another fine swing of the hammer here and there... ... here you have it!", cid) + player:addItem(7385, 1) + player:setStorageValue(Storage.TravellingTrader.Mission05, 2) + npcHandler.topic[cid] = 0 + end + end + end + elseif(msgcontains(msg, "no")) then + if(npcHandler.topic[cid] == 6) then + npcHandler:say("Well. Thinking about it, me a smith, so why not. 1000 gold for your personal crimson sword. Ok?", cid) + npcHandler.topic[cid] = 7 + elseif(npcHandler.topic[cid] == 7) then + npcHandler:say("Too expensive?! You think me work is cheap? Well, if you want cheap, I can make cheap. Hrmpf. I make cheap sword for 300 gold. Ok?", cid) + npcHandler.topic[cid] = 8 + elseif(npcHandler.topic[cid] == 8) then + npcHandler:say("Cheap but good quality? Impossible. Unless... you bring material. Three iron ores, 250 gold. Okay?", cid) + npcHandler.topic[cid] = 9 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/uzon.lua b/data/npc/scripts/uzon.lua new file mode 100644 index 00000000000..21261e34d0f --- /dev/null +++ b/data/npc/scripts/uzon.lua @@ -0,0 +1,66 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Feel the wind in your hair during one of my carpet rides!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Travel +local function addTravelKeyword(keyword, text, cost, destination, condition, action) + if condition then + keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = 'Never heard about a place like this.'}, condition) + end + + local travelKeyword = keywordHandler:addKeyword({keyword}, StdModule.say, {npcHandler = npcHandler, text = text, cost = cost, discount = 'postman'}) + travelKeyword:addChildKeyword({'yes'}, StdModule.travel, {npcHandler = npcHandler, premium = false, text = 'Hold on!', cost = cost, discount = 'postman', destination = destination}, nil, action) + travelKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'You shouldn\'t miss the experience.', reset = true}) +end + +addTravelKeyword('eclipse', 'Oh no, so the time has come? Do you really want me to fly you to this unholy place?', 110, Position(32659, 31915, 0), function(player) return player:getStorageValue(Storage.TheInquisition.Questline) ~= 4 and player:getStorageValue(Storage.TheInquisition.Questline) ~= 5 end) +addTravelKeyword('farmine', 'Do you seek a ride to Farmine for |TRAVELCOST|?', 60, Position(32983, 31539, 1), function(player) return player:getStorageValue(Storage.TheNewFrontier.Mission10) ~= 1 end) +addTravelKeyword('edron', 'Do you seek a ride to Edron for |TRAVELCOST|?', 60, Position(33193, 31783, 3), nil, function(player) if player:getStorageValue(Storage.Postman.Mission01) == 2 then player:setStorageValue(Storage.Postman.Mission01, 3) end end) +addTravelKeyword('darashia', 'Do you seek a ride to Darashia on Darama for |TRAVELCOST|?', 60, Position(33270, 32441, 6)) +addTravelKeyword('svargrond', 'Do you seek a ride to Svargrond for |TRAVELCOST|?', 60, Position(32253, 31097, 4)) +addTravelKeyword('kazordoon', 'Do you seek a ride to Kazordoon for |TRAVELCOST|?', 60, Position(32588, 31942, 0)) +addTravelKeyword('issavi', 'Do you seek a ride to Issavi for |TRAVELCOST|?', 100, Position(33957, 31515, 0)) + +-- Basic +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = "I am known as Uzon Ibn Kalith."}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am a licensed Darashian carpet pilot. I can bring you to {Darashia}, {Kazordoon}, {Svargrond} or {Edron}."}) +keywordHandler:addKeyword({'caliph'}, StdModule.say, {npcHandler = npcHandler, text = "The caliph welcomes travellers to his land."}) +keywordHandler:addKeyword({'kazzan'}, StdModule.say, {npcHandler = npcHandler, text = "The caliph welcomes travellers to his land."}) +keywordHandler:addKeyword({'daraman'}, StdModule.say, {npcHandler = npcHandler, text = "Oh, there is so much to tell about Daraman. You better travel to Darama to learn about his teachings."}) +keywordHandler:addKeyword({'ferumbras'}, StdModule.say, {npcHandler = npcHandler, text = "I would never transport this one."}) +keywordHandler:addKeyword({'drefia'}, StdModule.say, {npcHandler = npcHandler, text = "So you heard about haunted Drefia? Many adventures travel there to test their skills against the undead: vampires, mummies, and ghosts."}) +keywordHandler:addKeyword({'excalibug'}, StdModule.say, {npcHandler = npcHandler, text = "Some people claim it is hidden somewhere under the endless sands of the devourer desert in Darama."}) +keywordHandler:addKeyword({'thais'}, StdModule.say, {npcHandler = npcHandler, text = "Thais is noisy and overcrowded. That's why I like Darashia more."}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = "I have seen almost every place on the continent."}) +keywordHandler:addKeyword({'continent'}, StdModule.say, {npcHandler = npcHandler, text = "I could retell the tales of my travels for hours. Sadly another flight is scheduled soon."}) +keywordHandler:addKeyword({'carlin'}, StdModule.say, {npcHandler = npcHandler, text = "Just another Thais but with women to lead them."}) +keywordHandler:addKeyword({'flying'}, StdModule.say, {npcHandler = npcHandler, text = "You can buy flying carpets only in Darashia."}) +keywordHandler:addKeyword({'fly'}, StdModule.say, {npcHandler = npcHandler, text = "I transport travellers to the continent of Darama for a small fee. So many want to see the wonders of the desert and learn the secrets of Darama."}) +keywordHandler:addKeyword({'new'}, StdModule.say, {npcHandler = npcHandler, text = "I heard too many news to recall them all."}) +keywordHandler:addKeyword({'rumors'}, StdModule.say, {npcHandler = npcHandler, text = "I heard too many news to recall them all."}) +keywordHandler:addKeyword({'passage'}, StdModule.say, {npcHandler = npcHandler, text = "I can fly you to {Darashia} on Darama, {Kazordoon}, {Svargrond} or {Edron} if you like. Where do you want to go?"}) +keywordHandler:addKeyword({'transport'}, StdModule.say, {npcHandler = npcHandler, text = "I can fly you to {Darashia} on Darama, {Kazordoon}, {Svargrond} or {Edron} if you like. Where do you want to go?"}) +keywordHandler:addKeyword({'ride'}, StdModule.say, {npcHandler = npcHandler, text = "I can fly you to {Darashia} on Darama, {Kazordoon}, {Svargrond} or {Edron} if you like. Where do you want to go?"}) +keywordHandler:addKeyword({'trip'}, StdModule.say, {npcHandler = npcHandler, text = "I can fly you to {Darashia} on Darama, {Kazordoon}, {Svargrond} or {Edron} if you like. Where do you want to go?"}) + +npcHandler:setMessage(MESSAGE_GREET, "Daraman's blessings, traveller |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Daraman's blessings") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Daraman's blessings") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/vad_inchi.lua b/data/npc/scripts/vad_inchi.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/vad_inchi.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/valentina.lua b/data/npc/scripts/valentina.lua new file mode 100644 index 00000000000..9635ea70f06 --- /dev/null +++ b/data/npc/scripts/valentina.lua @@ -0,0 +1,28 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Love is beautiful, we are loved.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +-- Basic +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = "I am known as the saleswoman of love, as a cupid."}) + +npcHandler:setMessage(MESSAGE_GREET, "Welcome to Valentine's Store. Let's {trade} something?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Please come back from time to time.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Please come back from time to time.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/valindara.lua b/data/npc/scripts/valindara.lua new file mode 100644 index 00000000000..d5b8fed36c0 --- /dev/null +++ b/data/npc/scripts/valindara.lua @@ -0,0 +1,24 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Im eager for a bath in the lake.'},{text = 'Im interested in shiny precious things, if you have some.'},{text = 'No, you cant have this cloak.'} } +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setMessage(MESSAGE_GREET, "Greatings, mortal beigin.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Yes, i have some potions and runes if you are interested. Or do you want to buy only potions or only runes?oh if you want sell or buy gems, your may also ask me.") +npcHandler:setMessage(MESSAGE_FAREWELL, "May enlightenment be your path, |PLAYERNAME|.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/vascalir.lua b/data/npc/scripts/vascalir.lua new file mode 100644 index 00000000000..8beb6e1487d --- /dev/null +++ b/data/npc/scripts/vascalir.lua @@ -0,0 +1,972 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end + +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end + +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end + +function onThink() + npcHandler:onThink() +end + +local voices = { + {text = 'Talk to me if you want to help protecting the village.'}, + {text = 'Rookgaard needs your help more than ever.'} +} +npcHandler:addModule(VoiceModule:new(voices)) + +local function greetCallback(cid) + local player = Player(cid) + -- Reject to start missions + if player:getStorageValue(Storage.TheRookieGuard.Questline) == -1 and player:getLevel() > 5 then + npcHandler:say("Welcome, adventurer |PLAYERNAME|. Thank you for offering your help - but you are already too experienced to start this quest. Just go on hunting monsters, you'll be better off that way.", cid) + return false + -- Warn if started missions and reached level 8 + elseif player:getStorageValue(Storage.TheRookieGuard.Questline) == 1 and player:getLevel() == 8 and player:getStorageValue(Storage.TheRookieGuard.Level8Warning) == -1 then + npcHandler:setMessage(MESSAGE_GREET, { + "|PLAYERNAME| - a small word of advice before we continue this mission. You are level 8 now, while it is possible to reach higher levels while still on Rookgaard, you should consider leaving Rookgaard at about level 9. ...", + "You can still go on with this mission, but you won't be able to finish the quest once you've reached level 9. So only kill the monsters you absolutely have to kill - if you want to finish this quest! ...", + "If you don't care about that, you can also simply leave Rookgaard now and learn a vocation by talking to the oracle above the academy. It's up to you. Or - I could simply clean up your questlog, if you prefer. ...", + "What would you like to do? {Continue} the mission or {delete} the unfinished questline from your questlog?" + }) + -- Completed all missions + elseif player:getStorageValue(Storage.TheRookieGuard.Questline) == 2 then + npcHandler:say("|PLAYERNAME|, the only thing left for you to do here is to talk to the oracle above the academy and leave for the Isle of Destiny. Thanks again for your great work and good luck on your journeys!", cid) + return false + -- Not started mission 2 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission02) == -1 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome, adventurer |PLAYERNAME|. These are dire times for Rookgaard... have you come to help in our {mission}?") + -- Not finished mission 2 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission02) >= 1 and player:getStorageValue(Storage.TheRookieGuard.Mission02) <= 3 then + npcHandler:setMessage(MESSAGE_GREET, "Greetings, |PLAYERNAME|. Your task is still not done - do you remember everything you need to do?") + -- Finishing mission 2 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission02) == 4 then + npcHandler:setMessage(MESSAGE_GREET, "Greetings, |PLAYERNAME|. I've heard a loud rumbling from the roof - I hope the stones didn't fall on your toes. Have you loaded at least two catapults?") + -- Finished mission 2 but not started mission 3 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission02) == 5 and player:getStorageValue(Storage.TheRookieGuard.Mission03) == -1 then + npcHandler:setMessage(MESSAGE_GREET, "Greetings, |PLAYERNAME|. Actually I have some more equipment I could give to you, but first I want to see how you fight. You have fought before, haven't you?") + -- Not finished or finishing mission 3 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission03) == 1 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back, |PLAYERNAME|. Are you done with the 5 rats I asked you to kill?") + -- Started but not finished mission 4 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission04) >= 1 and player:getStorageValue(Storage.TheRookieGuard.Mission04) <= 4 then + npcHandler:say("Greetings, |PLAYERNAME|. Right now I don't need your help. I heard that Lily south-west of here requires assistance though.", cid) + return false + -- Finishing mission 4 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission04) == 5 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back, |PLAYERNAME|. Glad to see you made it back in one piece. I hope you're not too exhausted, because I could use your {help} again.") + -- Finished mission 4 but not started mission 5 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission04) == 6 and player:getStorageValue(Storage.TheRookieGuard.Mission05) == -1 then + npcHandler:setMessage(MESSAGE_GREET, "Oh, hello |PLAYERNAME|! Have you made up your mind about sneaking into the tarantula's lair and retrieving a sample of her web? Are you up for it?") + -- Started but not finished mission 5 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission05) >= 1 and player:getStorageValue(Storage.TheRookieGuard.Mission05) <= 2 then + npcHandler:setMessage(MESSAGE_GREET, "Do you need the instruction for the tarantula's lair again?") + -- Finishing mission 5 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission05) == 3 then + npcHandler:setMessage(MESSAGE_GREET, "Oh, well done! Let me take that spider web sample from you - careful, careful... it's sturdy, yet fragile. Thank you! I should be able to make a great paralyse trap with this one. Here, I have something sturdy for you as well - want it?") + player:setStorageValue(Storage.TheRookieGuard.Mission05, 5) + player:addExperience(50, true) + -- Finishing mission 5 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission05) == 5 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back, |PLAYERNAME|! How about that studded armor - would you like to have it now?") + -- Started but not finished mission 6 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission06) >= 1 and player:getStorageValue(Storage.TheRookieGuard.Mission06) <= 6 then + npcHandler:say("Greetings, |PLAYERNAME|. Right now I don't need your help. You should pay a visit to Tom the Tanner. His hut is south-west of the academy!", cid) + return false + -- Finished mission 6 but not started mission 7 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission06) == 7 and player:getStorageValue(Storage.TheRookieGuard.Mission07) == -1 then + npcHandler:setMessage(MESSAGE_GREET, "|PLAYERNAME|! Thank the gods you are back! While you were gone, something horrible happened. Do you smell the fire?") + -- Started but not finished mission 7 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission07) == 1 and player:getStorageValue(Storage.TheRookieGuard.LibraryChest) == -1 then + npcHandler:say("You can find the vault if you go down the stairs in the northern part of the academy. The book should be in a large blue chest somewhere down there - I hope it's not burnt yet.", cid) + return false + -- Finishing mission 7 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission07) == 1 and player:getStorageValue(Storage.TheRookieGuard.LibraryChest) == 1 then + npcHandler:setMessage(MESSAGE_GREET, "Oh my, what happened to your hair? Your face is all black, too - it must have been a hell of flames down there. That's so brave of you. Did you get the book?") + -- Finished mission 7 but not started mission 8 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission07) == 2 and player:getStorageValue(Storage.TheRookieGuard.Mission08) == -1 then + npcHandler:setMessage(MESSAGE_GREET, "Are you prepared for your next mission, |PLAYERNAME|?") + -- Started but not finished mission 8 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission08) == 1 then + npcHandler:say("I think it's a good idea to go see Paulie before you leave the village again. Just go downstairs and to the right to find the bank.", cid) + return false + -- Finished mission 8 but not started mission 9 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission08) == 2 and player:getStorageValue(Storage.TheRookieGuard.Mission09) == -1 then + npcHandler:setMessage(MESSAGE_GREET, "Now that you know how to store your money, it's time to go after the trolls. I'm even going to give you some more equipment as reward. Do you feel ready for that mission?") + -- Started but not finished mission 9 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission09) >= 1 and player:getStorageValue(Storage.TheRookieGuard.Mission09) <= 7 then + npcHandler:say("|PLAYERNAME|, you need to discover the troll tunnel and find a way to make it collapse. Maybe you're able to use some of the trolls' tools. Make sure they can't enter the village via that tunnel anymore!", cid) + return false + -- Finishing mission 9 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission09) == 8 then + npcHandler:setMessage(MESSAGE_GREET, "|PLAYERNAME|, welcome back! That was great work you did there. Let me give you something for your efforts - you deserve it. Here, want a helmet?") + player:setStorageValue(Storage.TheRookieGuard.Mission09, 9) + player:addExperience(50, true) + -- Finish mission 9 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission09) == 9 then + npcHandler:setMessage(MESSAGE_GREET, "Greetings, |PLAYERNAME|. Do you have enough space for the brass helmet now?") + -- Finished mission 9 but not started mission 10 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission09) == 10 and player:getStorageValue(Storage.TheRookieGuard.Mission10) == -1 then + npcHandler:setMessage(MESSAGE_GREET, "Greetings, |PLAYERNAME|. Are you ready for your next mission?") + -- Started but not finished mission 10 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission10) == 1 and player:getStorageValue(Storage.TheRookieGuard.Sarcophagus) == -1 then + npcHandler:setMessage(MESSAGE_GREET, "Greetings, |PLAYERNAME|. I see you haven't explored the whole crypt yet - do you need explanations again?") + -- Finishing mission 10 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission10) == 1 and player:getStorageValue(Storage.TheRookieGuard.Sarcophagus) == 1 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back, |PLAYERNAME|! Did you find a nice, fleshy bone in the crypt?") + -- Finish mission 10 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission10) == 2 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back, |PLAYERNAME|! Do you have enough space for that sword now?") + -- Finished mission 10 but not started mission 11 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission10) == 3 and player:getStorageValue(Storage.TheRookieGuard.Mission11) == -1 then + npcHandler:setMessage(MESSAGE_GREET, "Greetings, |PLAYERNAME|! I'm in a really good mood, I must say. We're almost able to infiltrate Kraknaknork's hideout. I have one last little favour to ask and then my plan is complete. Are you ready?") + -- Started but not finished mission 11 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission11) == 1 or player:getStorageValue(Storage.TheRookieGuard.Mission11) == 2 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back, |PLAYERNAME|! But - back so soon? Please find the wasps' lair in the north-western region of Rookgaard and use the flask I gave you on its dead body. Or did you lose the flask?") + -- Finishing mission 11 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission11) == 3 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back, |PLAYERNAME|! Were you able to bring back some wasp poison?") + -- Finish mission 11 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission11) == 4 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back, |PLAYERNAME|! Do you have enough space for that brass shield now?") + -- Finished mission 11 but not started mission 12 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission11) == 5 and player:getStorageValue(Storage.TheRookieGuard.Mission12) == -1 then + npcHandler:setMessage(MESSAGE_GREET, "|PLAYERNAME|, the time of our triumph has come. Are you ready to vanquish Kraknaknork once and for all?") + -- Started but not finished mission 12 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission12) >= 1 and player:getStorageValue(Storage.TheRookieGuard.Mission12) <= 13 then + npcHandler:say("|PLAYERNAME|, the air smells like victory. Head into the orc fortress and vanquish Kraknaknork once and for all. Don't forget to take the items from below the academy!", cid) + return false + -- Finish mission 12 + elseif player:getStorageValue(Storage.TheRookieGuard.Mission12) == 14 then + npcHandler:setMessage(MESSAGE_GREET, "|PLAYERNAME|! You're back! And you're covered in orc blood... that can only mean... were you able to kill Kraknaknork?") + end + return true +end + +-- Mission 2: Start +local mission2 = keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "Have you ever heard of Kraknaknork? He's a powerful orc shaman who has recently risen from the orc tribe and started to terrorise Rookgaard. Maybe we can kill several birds with one stone. Listen: ...", + "What would you say about you defeat Kraknaknork, save Rookgaard and earn some experience and better equipment on the way? Sounds good?" + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission02) == -1 end +) +keywordHandler:addAliasKeyword({"mission"}) + +-- Mission 2: Decline +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Well, if you change your mind you know where to find me. Remember that if you help Rookgaard, Rookgaard might be able to help you.", + ungreet = true +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission02) == -1 end +) + +local mission02Reject = KeywordNode:new({"no"}, StdModule.say, {npcHandler = npcHandler, text = 'OK, dude!'}) + +-- Mission 2: Accept +local mission2Accept = mission2:addChildKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "Great. We best start by reinforcing our defences. There are four large catapults positioned on roofs high over the village. If you want to fight, you have to build up some muscles. ...", + "Go into the barn just a few steps to the north-west of here and down the ladder into the cellar. You'll find a huge stone pile down there. Use it to pick up one of the big stones. ...", + "Carry one stone to at least two of the four catapults located on Norma's roof to the north, this academy and Obi's roof to the south. ...", + "Use the stone on the catapult to load it. You can load each catapult only once, so try spotting two different catapults. Have you understood all of that?" + } +}, +nil, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Questline, 1) + player:setStorageValue(Storage.TheRookieGuard.Mission02, 1) + player:setStorageValue(Storage.TheRookieGuard.Catapults, 0) + player:addMapMark({x = 32082, y = 32182, z = 7}, MAPMARK_FLAG, "Barn") + player:addMapMark({x = 32097, y = 32181, z = 7}, MAPMARK_BAG, "Norma's Bar") + player:addMapMark({x = 32105, y = 32203, z = 7}, MAPMARK_BAG, "Obi's Shop") +end +) + +mission2Accept:addChildKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Awesome! Off to work with you. I've marked the barn on your map.", + ungreet = true +}) + +mission2Accept:addChildKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "Let me explain again then. We best start by reinforcing our defences. There are four large catapults positioned on roofs high over the village. If you want to fight, you have to build up some muscles. ...", + "Go into the barn just a few steps to the north-west of here and down the ladder into the cellar. You'll find a huge stone pile down there. Use it to pick up one of the big stones. ...", + "Carry one stone to at least two of the four catapults located on Norma's roof to the north, this academy and Obi's roof to the south. ...", + "Use the stone on the catapult to load it. You can load each catapult only once, so try spotting two different catapults. Have you understood all of that?" + }, + moveup = 1 +}) + +-- Mission 2: Finish - Confirm +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "Well done! The villagers are much safer now that the catapults are ready to fire. You also look like you've built some muscles. ...", + "Great - so the piece of equipment I just gave you will not go to waste. Take this studded shield and put it to good use! ...", + "Actually I have some more equipment I could give to you, but first I want to see how you fight. You have fought before, haven't you?" + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission02) == 4 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission02, 5) + player:addItemEx(Game.createItem(2526, 1), true, CONST_SLOT_WHEREEVER) +end +) + +-- Mission 2: Finish - Decline +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Oh, but you have... you should say {yes}!" +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission02) == 4 end +) + +-- Mission 3: Start +local mission3 = keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "Ah, that came with confidence. Suited monsters to do some basic fighting would be rats - they actually fight back, but they don't hit that hard. Just make sure you wear your new studded shield and a sword. ...", + "You can find rats in the sewers. In case you might think so, this task is not a lame excuse to help us with some rat infestation, we got the rat population quite under control. ...", + "So, back to the topic - please kill 5 rats and then come back to me. Shouldn't be too hard, should it? Just pay attention they don't trap you in a narrow passage and take on one at a time. ...", + "If you run low on health, go on full defence - click the little shield icon - and leave the dungeon. Nothing corwardish about running, because dying hurts. Are you ready to go?" + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission02) == 5 and player:getStorageValue(Storage.TheRookieGuard.Mission03) == -1 end +) + +-- Mission 3: Decline +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "No worries, let's refresh your memory. To fight a monster, click on it in the battle list and you'll automatically attack it. It's as easy as that! If you want to practice, just hunt a few harmless rabbits south of here. Remember it now?" +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission02) == 5 and player:getStorageValue(Storage.TheRookieGuard.Mission03) == -1 end +) + +-- Mission 3: Accept +mission3:addChildKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "Nice. I've marked two rat dungeons on your map. Kill 5 rats and return to me. Smart adventurers try to face one creature at a time - use the environment to your advantage. ...", + "If you should happen to forget how many you have killed in the meantime, simply check your questlog. ...", + "Once you reach level 8, you should leave this island. While it is possible to reach higher levels, this quest is meant to be played up to level 8. ...", + "No need to be scared, just saying you don't need to plan large hunting sessions while helping me with this mission or kill more rats than I've asked you to. So, good hunting!" + } +}, +nil, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission03, 1) + player:setStorageValue(Storage.TheRookieGuard.RatKills, 0) + player:addMapMark({x = 32097, y = 32205, z = 7}, MAPMARK_GREENSOUTH, "Rat Dungeon") + player:addMapMark({x = 32041, y = 32228, z = 7}, MAPMARK_GREENSOUTH, "Rat Dungeon") +end +) + +-- Mission 3: Decline +mission3:addChildKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "I'll explain it again then. Suited monsters to do some basic fighting would be rats - they actually fight back, but they don't hit that hard. Just make sure you wear your new studded shield and a sword. ...", + "You can find rats in the sewers. In case you might think so, this task is not a lame excuse to help us with some rat infestation, we got the rat population quite under control. ...", + "So, back to the topic - please kill 5 rats and then come back to me. Shouldn't be too hard, should it? Just pay attention they don't trap you in a narrow passage and take on one at a time. ...", + "If you run low on health, go on full defence - click the little shield icon - and leave the dungeon. Nothing corwardish about running, because dying hurts. Are you ready to go?" + }, + moveup = 1 +}) + +-- Mission 3: Complain not finished +keywordHandler:addKeyword({"yes"}, nil, +{}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission03) == 1 and player:getStorageValue(Storage.TheRookieGuard.RatKills) < 5 end, +function(player) + local ratKills = player:getStorageValue(Storage.TheRookieGuard.RatKills) + npcHandler:say("You still need to kill " .. (5 - ratKills) .. " more rats. Come back once you've killed enough for some experience and equipment!", player.uid) +end +) +keywordHandler:addAliasKeyword({"no"}) + +-- Mission 3: Finish - Confirm +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "Good job. Here's your promised reward - a sabre. You can replace your wooden sword with it, if you still have it - the sabre does more damage. ...", + "If you look at a piece of equipment, you can check its stats. By the way, if you use sword weapons such as sabres or swords, you are training your 'sword fighting skill'. ...", + "This is quite important if you plan on becoming a melee fighter - the better your sword fighting skill, the higher the damage you do will be. ...", + "There are also club and axe type weapons - they train different skills, so maybe you should choose one type of weapon you always want to use. It doesn't make that much difference, but swords often have a good balance between offence and defence. ...", + "Anyway, I think you're well enough equipped now to leave the village of Rookgaard for another small task. Find Lily south-west of here, she will tell you what she needs done." + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission03) == 1 and player:getStorageValue(Storage.TheRookieGuard.RatKills) == 5 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission03, 2) + player:setStorageValue(Storage.TheRookieGuard.Mission04, 1) + player:addExperience(30, true) + player:addItemEx(Game.createItem(2385, 1), true, CONST_SLOT_WHEREEVER) +end +) + +-- Mission 3: Finish - Decline +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Actually I think you have killed enough. You should reply with {yes}!" +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission03) == 1 and player:getStorageValue(Storage.TheRookieGuard.RatKills) == 5 end +) + +-- Mission 4: Finish - Confirm +keywordHandler:addKeyword({"help"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "That's the spirit Rookgaard needs. Listen, while you were gone I thought about a way to weaken and fight Kraknaknork - that orc shaman who terrorises Rookgaard. ...", + "Even if we could make our way into his stronghold past all his minions, we cannot hope to defeat him as long as he is powerful enough to summon demons and access other dimensions. ...", + "While studying the fauna of Rookgaard I came across an interesting specimen that might help us in our battle. Deep in the underground tunnels, there is a spider queen - a tarantula, who is bigger and deadlier than all the other spiders here. ...", + "Her web is enormous - and causes a strong paralysis. If you could get a small sample of her web, I might be able to craft a trap that we can use to paralyse the orcs so you can get past their defences. ...", + "Do you dare sneak into the tarantula's lair and retrieve a sample of her web?" + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission04) == 5 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission04, 6) +end +) + +-- Mission 4: Finish - Wrong Confirm +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "What do you mean? If you're ready to {help} me again, just say so." +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission04) == 5 end +) +keywordHandler:addAliasKeyword({"no"}) + +-- Mission 5: Accept - Explain again +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "That's very courageous. I'll mark the spider lair on your map. If you leave the village to the north again like before, but walk north-west and cross the bridge, you will find it. ...", + "Listen, I have some more important information regarding your task. It will likely be dark in the cave, so maybe you'll want to buy a torch or two from Al Dee's shop to the left of the barn. ...", + "The spider queen is far too strong for you to fight and if she catches you, you might end up in her stomach. The good news is that she is almost blind and relies on her sense of smelling to find her prey. ...", + "Deep in her lair you'll find some blue greasy stones. If you use them, you'll rub some of the smelly grease on your body. From that moment on you'll be invisible to her, but only for a short time. ...", + "If you run into her lair, you should have enough time to retrieve a sample of her web before she catches you. Just USE one of her intact cobwebs in her lair. Good luck!" + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission04) == 6 and player:getStorageValue(Storage.TheRookieGuard.Mission05) == -1 or (player:getStorageValue(Storage.TheRookieGuard.Mission05) >= 1 and player:getStorageValue(Storage.TheRookieGuard.Mission05) <= 2) end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission05, 1) + player:addMapMark({x = 32051, y = 32110, z = 7}, MAPMARK_GREENSOUTH, "Spider Lair") +end +) + +-- Mission 5: Decline - Explain again +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Well, if you change your mind, let me know.", + ungreet = true +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission04) == 6 and player:getStorageValue(Storage.TheRookieGuard.Mission05) == -1 or (player:getStorageValue(Storage.TheRookieGuard.Mission05) >= 1 and player:getStorageValue(Storage.TheRookieGuard.Mission05) <= 2) end +) + +-- Mission 5: Finish - Accept Reward (Studded armor) +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Here, this studded armor will protect you much better. Fits you perfectly! Now - let's work on your footwear. Tom the Tanner can create great boots out of quality leather. You should pay him a visit!", + ungreet = true +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission05) == 5 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission05, 6) + player:setStorageValue(Storage.TheRookieGuard.Mission06, 1) + player:addItemEx(Game.createItem(2484, 1), true, CONST_SLOT_WHEREEVER) +end +) + +-- Mission 5: Finish - Reject Reward (Studded armor) +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Seriously, don't reject that offer. I'm going to give you a studded armor. No one refuses free stuff! If you don't like it, you can sell it - I don't need it anymore. I promise it's not too used or smelly. Want it?" +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission05) == 5 end +) + +-- Mission 7: Start +local mission7 = keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "Time is of the essence now. The library vault is on fire! It's where Rookgaard's oldest and most important books are stored. ...", + "The trolls from the northern ruins somehow found their way into the vault by digging a tunnel from the other side and set everything on fire. ...", + "You HAVE to go down there and look for our copy of the book of orc language - while I'm thinking of a reason why I can't go myself. ...", + "Just kidding, I need to find out just how the trolls got in there before they wreak more havoc. I think there's something bigger behind all this. ...", + "The vault is likely set on fire - be careful down there, and don't run into open fire, it can and will hurt you. There should be a rune in the vault that can at least weaken fire, just in case. ...", + "Are you ready to go?" + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission06) == 7 and player:getStorageValue(Storage.TheRookieGuard.Mission07) == -1 end +) +--keywordHandler:addAliasKeyword({"no"}) + +-- Mission 7: Accept +mission7:addChildKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "You can find the vault if you go down the stairs in the northern part of the academy. The book should be in a large blue chest somewhere down there - I hope it's not burnt yet. ...", + "Make sure you're healthy - if you are wounded, ask Cipfried in the temple for a healing first. Good luck!" + } +}, +nil, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission07, 1) + player:setStorageValue(Storage.TheRookieGuard.LibraryDoor, 1) +end +) + +-- Mission 7: Decline +mission7:addChildKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Then do whatever you have to do first, but please hurry!", + ungreet = true +}) + +-- Mission 7: Finish - Confirm/Decline (Without having the book) +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "What happened, you say? The book was already burnt to ashes? That's too bad... well, you deserve a reward for your courage anyway. Thanks for at least trying. ...", + "I was trying to figure out a way to get into the orc fortress by maybe using their language... but that won't work now I fear. ...", + "We do have to stop the trolls though before taking care of the orcs. I found their tunnel in the northern ruins. Are you prepared for your next mission?" + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission07) == 1 and player:getStorageValue(Storage.TheRookieGuard.LibraryChest) == 1 and player:getItemCount(13831) <= 0 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission07, 2) + player:setStorageValue(Storage.TheRookieGuard.LibraryDoor, -1) + player:addExperience(100, true) +end +) +keywordHandler:addAliasKeyword({"no"}) + +-- Mission 7: Finish - Confirm (Having the book) +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "Great job down there! You do deserve a reward for your courage. Here is a platinum coin for you, worth 100 gold coins. Let me take a look at the book... ...", + "Argh... the pages are barely readable anymore. I was trying to figure out a way to get into the orc fortress by maybe using their language... but that won't work now I fear. ...", + "We do have to stop the trolls though before taking care of the orcs. I found their tunnel in the northern ruins. Are you prepared for your next mission?" + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission07) == 1 and player:getStorageValue(Storage.TheRookieGuard.LibraryChest) == 1 and player:getItemCount(13831) >= 1 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission07, 2) + player:setStorageValue(Storage.TheRookieGuard.LibraryDoor, -1) + player:removeItem(13831, 1) + player:addExperience(100, true) + player:addItemEx(Game.createItem(2152, 1), true, CONST_SLOT_WHEREEVER) +end +) + +-- Mission 7: Finish - Decline (Having the book) +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "Oh, but you have it! Great job down there! You do deserve a reward for your courage. Here is a platinum coin for you, worth 100 gold coins. Let me take a look at the book... ...", + "Argh... the pages are barely readable anymore. I was trying to figure out a way to get into the orc fortress by maybe using their language... but that won't work now I fear. ...", + "We do have to stop the trolls though before taking care of the orcs. I found their tunnel in the northern ruins. Are you prepared for your next mission?" + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission07) == 1 and player:getStorageValue(Storage.TheRookieGuard.LibraryChest) == 1 and player:getItemCount(13831) >= 1 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission07, 2) + player:setStorageValue(Storage.TheRookieGuard.LibraryDoor, -1) + player:removeItem(13831, 1) + player:addExperience(100, true) + player:addItemEx(Game.createItem(2152, 1), true, CONST_SLOT_WHEREEVER) +end +) + +-- Mission 8: Accept +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "First things first. I think by now you should have gathered some money, and it's better to play things safely instead of rushing into the trolls' lair. You might have seen the Bank of Rookgaard downstairs. ...", + "Each Tibian inhabitant has a bank account where you can store your money safely - so in case you die, you won't lose it. ...", + "You don't have to worry about item loss here on Rookgaard, but as soon as you grow stronger and learn a vocation, it can happen to you that you lose some of your items when dying. ...", + "It's probably safer to get used to depositing all of your money on your bank account before you leave for a hunt. ...", + "Go downstairs and talk to Paulie. I'm sure he can explain to you everything you need to know, and he might also give you a small bonus for your account." + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission07) == 2 and player:getStorageValue(Storage.TheRookieGuard.Mission08) == -1 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission08, 1) +end +) + +-- Mission 8: Decline +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Take a small break then and return to me when you have recovered... and cleaned your face.", + ungreet = true +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission07) == 2 and player:getStorageValue(Storage.TheRookieGuard.Mission08) == -1 end +) + +-- Mission 9: Accept +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "Very well. What I know is the following: somewhere in the northern ruins, the trolls have found a way to dig a tunnel that leads to the library vault. That's how they were able to set fire to it. ...", + "You need to discover that tunnel and find a way to make it collapse. Maybe you're able to use some of the trolls' tools. Make sure that they can't enter the village via that tunnel anymore! ...", + "And please don't hurt yourself in the process. You'll probably have to fight them, so bring food and maybe a potion. If you need to buy something, don't forget that you can withdraw money from your bank account. Good luck!" + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission08) == 2 and player:getStorageValue(Storage.TheRookieGuard.Mission09) == -1 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission09, 1) + player:setStorageValue(Storage.TheRookieGuard.TrollChests, 0) + player:setStorageValue(Storage.TheRookieGuard.TunnelPillars, 0) + player:addMapMark({x = 32094, y = 32137, z = 7}, MAPMARK_GREENSOUTH, "Troll Caves") +end +) + +-- Mission 9: Decline +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Alright, then just let me know when you're ready. Don't take too much time though.", + ungreet = true +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission08) == 2 and player:getStorageValue(Storage.TheRookieGuard.Mission09) == -1 end +) + +-- Mission 9: Finish - Accept Reward (Brass helmet) +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "This brass helmet will make sure you don't hurt your head. I probably should have given that to you BEFORE you made a rocky tunnel collapse! Take your well-deserved break. Once you're ready for the next mission, talk to me again.", + ungreet = true +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission09) == 9 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission09, 10) + player:addItemEx(Game.createItem(2460, 1), true, CONST_SLOT_WHEREEVER) +end +) + +-- Mission 9: Finish - Reject Reward (Brass helmet) +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Seriously, don't reject that offer. I'm going to give you a brass helmet. No one refuses free stuff! If you don't like it, you can sell it - I don't need it anymore. I promise there are no fleas in it. Want it?" +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission09) == 9 end +) + +-- Mission 10: Accept +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "Now that we got rid of the troll threat, it's about time we get back to the imminent danger coming from the orc side of Rookgaard. The spider web you retrieved was only the first step - I've thought of something else. ...", + "To infiltrate the orc fortress, we're going to make use of a technique I've learnt on the battlefield - distraction! I'll explain the plan to you when everything's ready, but for now I have a small favour to ask. ...", + "Please go to the graveyard east of the village, enter the crypt and retrieve a bone. Now I know this is a little morbid, but it would be best if it still had some meat on it. ...", + "The graveyard hasn't been used by the villagers for a long time. It's cursed - skeletons are roaming around, so be careful. Take this garlic necklace just in case. ...", + "Undead monsters tend to drain your life - because their own life force is gone. If you wear it, you'll be protected from it. Search around in the coffins in the crypt, one of them should hold a nice fleshy bone. See you soon!" + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission09) == 10 and player:getStorageValue(Storage.TheRookieGuard.Mission10) == -1 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission10, 1) + player:setStorageValue(Storage.TheRookieGuard.UnholyCryptDoor, 1) + player:setStorageValue(Storage.TheRookieGuard.UnholyCryptChests, 0) + player:addItemEx(Game.createItem(2199, 1), true, CONST_SLOT_WHEREEVER) + player:addMapMark({x = 32131, y = 32201, z = 7}, MAPMARK_GREENSOUTH, "Unholy Crypt") +end +) + +-- Mission 10: Decline +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Let me know when you're ready. This should be fun.", + ungreet = true +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission09) == 10 and player:getStorageValue(Storage.TheRookieGuard.Mission10) == -1 end +) + +-- Mission 10: Confirm (Explain again) +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "Please go to the graveyard east of the village, enter the crypt and retrieve a bone. Now I know this is a little morbid, but it would be best if it still had some meat on it. ...", + "The graveyard hasn't been used by the villagers for a long time. It's cursed - skeletons are roaming around, so be careful. ...", + "Undead monsters tend to drain your life - because their own life force is gone. If you wear the garlic necklace I gave you, you'll be protected from it. Search around in the coffins in the crypt, one of them should hold a nice fleshy bone. See you soon!" + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission10) == 1 and player:getStorageValue(Storage.TheRookieGuard.Sarcophagus) == -1 end +) + +-- Mission 10: Decline (Explain again) +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Okay, then good hunting.", + ungreet = true +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission10) == 1 and player:getStorageValue(Storage.TheRookieGuard.Sarcophagus) == -1 end +) + +-- Mission 10: Finish - Confirm/Decline (Having the fleshy bone) +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Well done, this bone is exactly what I needed! Great. I have to do some preparations, but as reward for your great work, I have a shiny new weapon for you. Here, would you like to have this sword?" +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission10) == 1 and player:getStorageValue(Storage.TheRookieGuard.Sarcophagus) == 1 and player:getItemCount(13830) >= 1 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission10, 2) + player:addExperience(150, true) + player:removeItem(13830, 1) +end +) +keywordHandler:addAliasKeyword({"no"}) + +-- Mission 10: Finish - Confirm/Decline (Without having the fleshy bone) +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Ah... well, if you lost that bone on the way, that's too bad. I just hope you didn't get hungry and nibbled on it. I wouldn't eat cursed flesh if I were you. Anyway, you can still have this old sword as reward, do you want it?" +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission10) == 1 and player:getStorageValue(Storage.TheRookieGuard.Sarcophagus) == 1 and player:getItemCount(13830) == 0 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission10, 2) + player:addExperience(80, true) +end +) +keywordHandler:addAliasKeyword({"no"}) + +-- Mission 10: Finish - Accept Reward (Sword) +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "This sword has helped me in many fierce battles. I hope you can put it to good use. Once you're ready for the next mission, talk to me again.", + ungreet = true +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission10) == 2 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission10, 3) + player:addItemEx(Game.createItem(2376, 1), true, CONST_SLOT_WHEREEVER) +end +) + +-- Mission 10: Finish - Reject Reward (Sword) +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Seriously, don't reject that offer. Just take that sword, it's free. If you don't like it, you can sell it - I don't need it anymore. I promise there are no blood stains on it. Want it?" +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission10) == 2 end +) + +-- Mission 11: Start +local mission11 = keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "I'm happy to hear that! We already have the paralyse trap and the fleshy bone, and now we need one final ingredient to weaken Kraknaknork so that you stand a chance against him. ...", + "Wasp poison! There are many toxic creatures - like snakes or poison spiders - but none is as deadly as the wasp. At least none on Rookgaard. If we could poison Kraknaknork with it, I think he won't be able to make use of his spells for quite a while. ...", + "The only problem is - to get it, you need to get close to a wasp, kill it and extract some poison from its dead body. Wasps are located on the north-western side of Rookgaard, which is quite dangerous. ...", + "However, I can give you something for protection - a silver amulet. As long as you wear it, poison can't harm you as much as it usually would do. I'll also give you the flask which you have to use on a fresh, dead wasp. Are you prepared for that mission?" + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission10) == 3 and player:getStorageValue(Storage.TheRookieGuard.Mission11) == -1 end +) + +-- Mission 11: Decline Start +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Well, then just let me know when you're ready.", + ungreet = true +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission10) == 3 and player:getStorageValue(Storage.TheRookieGuard.Mission11) == -1 end +) + +-- Mission 11: Accept +mission11:addChildKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Alright. Here is the empty flask to use on a dead wasp. I also marked the wasps' nest on your map. Be careful and don't forget to wear your silver amulet for poison protection!", + ungreet = true +}, +nil, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission11, 1) + player:addItemEx(Game.createItem(2170, 1), true, CONST_SLOT_WHEREEVER) + player:addItemEx(Game.createItem(13924, 1), true, CONST_SLOT_WHEREEVER) + player:addMapMark({x = 32000, y = 32139, z = 7}, MAPMARK_GREENSOUTH, "Wasps' Nest") +end +) + +-- Mission 11: Decline +mission11:addChildKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Should I explain it again?", + reset = true +}) + +-- Mission 11: Confirm - Lost Flask (Having it) +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Oh, but there you have it in your inventory! Yeah, your backpack is a bit of a mess. I understand you overlooked it. Dig deeper!", + ungreet = true +}, +function(player) return (player:getStorageValue(Storage.TheRookieGuard.Mission11) == 1 or player:getStorageValue(Storage.TheRookieGuard.Mission11) == 2) and player:getItemCount(13924) > 0 end +) + +-- Mission 11: Confirm - Lost Flask (Without having it) +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "No problem. Here's a new one. I can only give you one per hour though, so try not to lose it again this time.", + ungreet = true +}, +function(player) return (player:getStorageValue(Storage.TheRookieGuard.Mission11) == 1 or player:getStorageValue(Storage.TheRookieGuard.Mission11) == 2) and player:getItemCount(13924) == 0 end, +function(player) + player:addItemEx(Game.createItem(13924, 1), true, CONST_SLOT_WHEREEVER) +end +) + +-- Mission 11: Decline - Lost Flask +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Great, then please find the wasps' nest, kill one and use the empty flask on its dead body.", + ungreet = true +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission11) == 1 or player:getStorageValue(Storage.TheRookieGuard.Mission11) == 2 end +) + +-- Mission 11: Finish - Confirm Give (Wasp poison flask, having it) +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "|PLAYERNAME|, I must say I'm impressed. Not everyone would dare go into that region of Rookgaard and face creatures as strong as wasps. Wait, let me give something to you... ...", + "Here, with a drop of the wasp poison this potion turned into an effective antidote. Should you get poisoned again and are losing a lot of health, use the antidote potion to cure yourself. ...", + "There is also a rune and a spell to remove poison available once you leave this island and arrive on the mainland. It's always good to protect yourself! ...", + "And I have a good shield for you, too. Here, can you carry it?" + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission11) == 3 and player:getItemCount(13923) > 0 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission11, 4) + player:removeItem(13923, 1) + player:addItemEx(Game.createItem(8474, 1), true, CONST_SLOT_WHEREEVER) + player:addExperience(150, true) +end +) + +-- Mission 11: Finish - Decline Give (Wasp poison flask) +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Well, please come back with the poison soon. We won't have much time until Kraknaknork's next attack.", + ungreet = true +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission11) == 3 end +) + +-- Mission 11: Finish - Confirm Give (Wasp poison flask, without having it) +local mission11Reset = keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Oh, but you don't carry any - did you lose the flask? I can give you a new empty one, but that will also reset your mission, meaning you have to extract new poison. Would you like that?" +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission11) == 3 and player:getItemCount(13923) == 0 end +) + +-- Mission 11: Confirm - Reset Mission +mission11Reset:addChildKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Alright. Here is the empty flask to use on a dead wasp. Don't lose it this time!", + ungreet = true +}, +nil, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission11, 1) + player:addItemEx(Game.createItem(13924, 1), true, CONST_SLOT_WHEREEVER) +end +) + +-- Mission 11: Decline - Reset Mission +mission11Reset:addChildKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Great, then please find the wasps' nest, kill one and use the empty flask on its dead body.", + ungreet = true +} +) + +-- Mission 11: Finish - Accept Reward (Brass shield) +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "This brass shield is actually brand-new. It's never been used! I hope it will serve you well. Take a small break, regenerate your health, and then talk to me again for your final mission!", + ungreet = true +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission11) == 4 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission11, 5) + player:addItemEx(Game.createItem(2511, 1), true, CONST_SLOT_WHEREEVER) +end +) + +-- Mission 11: Finish - Reject Reward (Brass shield) +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Seriously, don't reject that offer. Just take that shield, it's free. If you don't like it, you can sell it - I don't need it anymore. I promise it's really brand-new. Want it?" +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission11) == 4 end +) + +-- Mission 12: Accept +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "The air smells like victory today. I've kept the items you brought from your journeys safe - the time has come to use them. ...", + "Enter the small treasure room under the academy - just down the stairs and to the right, near Paulie - and open the large blue chest to retrieve them. You'll find a rolling pin, the fleshy bone, the wasp poison and a tarantula trap. ...", + "Now let me explain the plan in detail. Go to the orc fortress - you've already been nearby when hunting for the wasp poison, it's the same way, but I'll mark it on your map just in case. ...", + "There you will have to find a way to sneak past the guards, they are much too strong for you. The rolling pin might come in handy during that part. Afterwards, the fleshy bone will help to create a distraction to get into the fortress. ...", + "Once you're inside the fortress, find the orc kitchen and pour the wasp poison into Kraknaknork's soup! The tarantula trap will come in handy if you meet a guard who might seem simply too fast for you. You can use it on him to slow him down. ...", + "|PLAYERNAME|, take the items and go claim your victory. I know you will do us proud. Good luck!" + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission11) == 5 and player:getStorageValue(Storage.TheRookieGuard.Mission12) == -1 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission12, 1) + player:setStorageValue(Storage.TheRookieGuard.AcademyDoor, 1) + player:setStorageValue(Storage.TheRookieGuard.OrcFortressChests, 0) + player:setStorageValue(Storage.TheRookieGuard.KraknaknorkChests, 0) + player:addMapMark({x = 31976, y = 32156, z = 7}, MAPMARK_SKULL, "Orc Fortress") +end +) + +-- Mission 12: Decline +keywordHandler:addKeyword({"no"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Rest for a bit, but don't take too much time to come back.", + ungreet = true +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission11) == 5 and player:getStorageValue(Storage.TheRookieGuard.Mission12) == -1 end +) + +-- Mission 12: Finish - Confirm/Decline +keywordHandler:addKeyword({"yes"}, StdModule.say, +{ + npcHandler = npcHandler, + text = { + "You DID kill him indeed! Incredible! This little village can finally live in peace again - and you've grown so strong, too. I'm proud of you, Synanceia Horrida. My work here is done, and yours too. Thank you for all you've done for us. ...", + "Now all that is left for you to do here is to talk to the oracle above the academy and travel to the Isle of Destiny. There, you will determine your future - which I'm sure is a bright one. ...", + "What will become of you? A mighty sorcerer? A fierce knight? A skilled paladin? Or a powerful druid? Only you can decide. ...", + "Rookgaard will miss you, but the whole world of Tibia is open to you now. Take care, |PLAYERNAME|. It's good to know you." + } +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Mission12) == 14 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Mission12, 15) + player:setStorageValue(Storage.TheRookieGuard.Questline, 2) + player:setStorageValue(Storage.TheRookieGuard.AcademyDoor, -1) +end +) +keywordHandler:addAliasKeyword({"no"}) + +-- Missions: Confirm - Continue (Level 8) +keywordHandler:addKeyword({"continue"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Alright. Talk to me again to continue with your mission, but heed my words!", + ungreet = true +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Questline) == 1 and player:getLevel() == 8 and player:getStorageValue(Storage.TheRookieGuard.Level8Warning) == -1 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Level8Warning, 1) +end +) + +-- Missions: Confirm - Delete (Level 8) +keywordHandler:addKeyword({"delete"}, StdModule.say, +{ + npcHandler = npcHandler, + text = "Alright.", + ungreet = true +}, +function(player) return player:getStorageValue(Storage.TheRookieGuard.Questline) == 1 and player:getLevel() == 8 and player:getStorageValue(Storage.TheRookieGuard.Level8Warning) == -1 end, +function(player) + player:setStorageValue(Storage.TheRookieGuard.Questline, -1) + player:setStorageValue(Storage.TheRookieGuard.Mission01, -1) + player:setStorageValue(Storage.TheRookieGuard.Mission02, -1) + player:setStorageValue(Storage.TheRookieGuard.Mission03, -1) + player:setStorageValue(Storage.TheRookieGuard.Mission04, -1) + player:setStorageValue(Storage.TheRookieGuard.Mission05, -1) + player:setStorageValue(Storage.TheRookieGuard.Mission06, -1) + player:setStorageValue(Storage.TheRookieGuard.Mission07, -1) + player:setStorageValue(Storage.TheRookieGuard.Mission08, -1) + player:setStorageValue(Storage.TheRookieGuard.Mission09, -1) + player:setStorageValue(Storage.TheRookieGuard.Mission10, -1) + player:setStorageValue(Storage.TheRookieGuard.Mission11, -1) + player:setStorageValue(Storage.TheRookieGuard.Mission12, -1) +end +) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setMessage(MESSAGE_FAREWELL, "Farewell.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Farewell.") +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/velvet.lua b/data/npc/scripts/velvet.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/velvet.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/vera.lua b/data/npc/scripts/vera.lua new file mode 100644 index 00000000000..1943c5ae462 --- /dev/null +++ b/data/npc/scripts/vera.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Have you moved to a new home? I\'m the specialist for equipping it.'} } +npcHandler:addModule(VoiceModule:new(voices)) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/vescu.lua b/data/npc/scripts/vescu.lua new file mode 100644 index 00000000000..fc1e082f032 --- /dev/null +++ b/data/npc/scripts/vescu.lua @@ -0,0 +1,137 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local message = {} + +local config = { + ['30 bonelord eyes'] = {storageValue = 1, text = {'Have you really managed to bring me 30 bonelord eyes? ', 'Do bonelord eyes continue blinking when they are seperated from the bonelord? That is a scary thought.', 'Aw-awsome! Squishy! Now, please bring me 10 {red dragon scales}.'}, itemId = 5898, count = 30}, + ['bonelord eyes'] = {storageValue = 1, text = {'Have you really managed to bring me 30 bonelord eyes? ', 'Do bonelord eyes continue blinking when they are seperated from the bonelord? That is a scary thought.', 'Aw-awsome! Squishy! Now, please bring me 10 {red dragon scales}.'}, itemId = 5898, count = 30}, + ['bonelord eye'] = {storageValue = 1, text = {'Have you really managed to bring me 30 bonelord eyes? ', 'Do bonelord eyes continue blinking when they are seperated from the bonelord? That is a scary thought.', 'Aw-awsome! Squishy! Now, please bring me 10 {red dragon scales}.'}, itemId = 5898, count = 30}, + ['10 red dragon scales'] = {storageValue = 2, text = {'D-did you get all of the 10 red dragon scales? ', 'Have you ever wondered if a red dragon means \'stop\' whereas a green dragon means \'go\'?', 'G-good work, ... wha-what\'s your name again? Anyway... come back with 30 {lizard scales}.'}, itemId = 5882, count = 10}, + ['red dragon scales'] = {storageValue = 2, text = {'D-did you get all of the 10 red dragon scales? ', 'Have you ever wondered if a red dragon means \'stop\' whereas a green dragon means \'go\'?', 'G-good work, ... wha-what\'s your name again? Anyway... come back with 30 {lizard scales}.'}, itemId = 5882, count = 10}, + ['red dragon scale'] = {storageValue = 2, text = {'D-did you get all of the 10 red dragon scales? ', 'Have you ever wondered if a red dragon means \'stop\' whereas a green dragon means \'go\'?', 'G-good work, ... wha-what\'s your name again? Anyway... come back with 30 {lizard scales}.'}, itemId = 5882, count = 10}, + ['30 lizard scales'] = {storageValue = 3, text = {'Ah, are those - - the 30 lizard scales?', 'I once had a girlfriend c-called L-lizzie. She had s-scales too.', 'This potion will become p-pretty scaly. I\'m not sure yet if I want to d-drink that. I think the 20 {fish fins} which come next won\'t really improve it. '}, itemId = 5881, count = 30}, + ['lizard scales'] = {storageValue = 3, text = {'Ah, are those - - the 30 lizard scales?', 'I once had a girlfriend c-called L-lizzie. She had s-scales too.', 'This potion will become p-pretty scaly. I\'m not sure yet if I want to d-drink that. I think the 20 {fish fins} which come next won\'t really improve it. '}, itemId = 5881, count = 30}, + ['lizard scale'] = {storageValue = 3, text = {'Ah, are those - - the 30 lizard scales?', 'I once had a girlfriend c-called L-lizzie. She had s-scales too.', 'This potion will become p-pretty scaly. I\'m not sure yet if I want to d-drink that. I think the 20 {fish fins} which come next won\'t really improve it. '}, itemId = 5881, count = 30}, + ['20 fish fins'] = {storageValue = 4, text = {'Eww, is that disgusting smell coming from the 20 fish fins? ', 'Not normal fish fins of course. We need Quara fish fins. If you haven\'t h-heard about them, ask the - - plorer society.', 'Alrrrrrrright! Thanks for the f-fish. Get me the 20 ounces of {vampire dust} now. I\'ll have another b-beer.'}, itemId = 5895, count = 20}, + ['fish fins'] = {storageValue = 4, text = {'Eww, is that disgusting smell coming from the 20 fish fins? ', 'Not normal fish fins of course. We need Quara fish fins. If you haven\'t h-heard about them, ask the - - plorer society.', 'Alrrrrrrright! Thanks for the f-fish. Get me the 20 ounces of {vampire dust} now. I\'ll have another b-beer.'}, itemId = 5895, count = 20}, + ['fish fin'] = {storageValue = 4, text = {'Eww, is that disgusting smell coming from the 20 fish fins? ', 'Not normal fish fins of course. We need Quara fish fins. If you haven\'t h-heard about them, ask the - - plorer society.', 'Alrrrrrrright! Thanks for the f-fish. Get me the 20 ounces of {vampire dust} now. I\'ll have another b-beer.'}, itemId = 5895, count = 20}, + ['20 vampire dust'] = {storageValue = 5, text = {'Have you collected 20 ounces of vampire d-dust? ', 'Don\'t you think vampires have something - - romantic about them? I think you need a b-blessed steak though to turn them into d-dust.', 'Tha-thank you. Trolls are good for something a-after all. Bring me the 10 ounces of {demon dust} now. '}, itemId = 5905, count = 20}, + ['vampire dust'] = {storageValue = 5, text = {'Have you collected 20 ounces of vampire d-dust? ', 'Don\'t you think vampires have something - - romantic about them? I think you need a b-blessed steak though to turn them into d-dust.', 'Tha-thank you. Trolls are good for something a-after all. Bring me the 10 ounces of {demon dust} now. '}, itemId = 5905, count = 20}, + ['10 demon dust'] = {storageValue = 6, text = {'Have you slain enough d-demons to gather 10 ounces of demon dust? ', 'I like d-demons. They are just as pretty as flamingos. But you need a blessed stake or something to get demon dust. ', 'G-great. You\'re a reeeal k-killer like me, eh? I think I\'ll g-give you something fun when the potion is complete. But first, b-bring me {warrior\'s sweat}.'}, itemId = 5906, count = 10}, + ['demon dust'] = {storageValue = 6, text = {'Have you slain enough d-demons to gather 10 ounces of demon dust? ', 'I like d-demons. They are just as pretty as flamingos. But you need a blessed stake or something to get demon dust. ', 'G-great. You\'re a reeeal k-killer like me, eh? I think I\'ll g-give you something fun when the potion is complete. But first, b-bring me {warrior\'s sweat}.'}, itemId = 5906, count = 10}, + ['warrior\'s sweat'] = {storageValue = 7, text = {'This s-smells even worse than the fish fins. Is that warrior\'s sweat?', 'If you can\'t sweat enough yourself, go ask a Djinn. They do - magical - tractions. Err, extractions.', 'Yahaha! Here we g-go. I\'ll just take a small sip - . Okay, this is disgusting, but it seems to work. I\'ll teach you something fun, remind me to tell you a {secret} sometime.'}, itemId = 5885}, +} + +local function greetCallback(cid) + if Player(cid):getCondition(CONDITION_DRUNK) then + npcHandler:setMessage(MESSAGE_GREET, 'Hey t-there, you look like someone who enjoys a good {booze}.') + else + npcHandler:say('Oh, two t-trolls. Hellooo, wittle twolls. ', cid) + return false + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, 'potion') then + if player:getStorageValue(Storage.OutfitQuest.AssassinBaseOutfit) < 1 then + npcHandler:say('It\'s so hard to know the exact time when to stop drinking. C-could you help me to brew such a potion?', cid) + npcHandler.topic[cid] = 1 + end + elseif config[msg] and npcHandler.topic[cid] == 0 then + if player:getStorageValue(Storage.OutfitQuest.AssassinBaseOutfit) == config[msg].storageValue then + npcHandler:say(config[msg].text[1], cid) + npcHandler.topic[cid] = 3 + message[cid] = msg + else + npcHandler:say(config[msg].text[2], cid) + end + elseif msgcontains(msg, 'secret') then + if player:getStorageValue(Storage.OutfitQuest.AssassinBaseOutfit) == 8 then + npcHandler:say('Right. Since you helped me to b-brew that potion and thus ensured the high quality of my work , I\'ll give you my old assassin costume. It lacks the head part, but it\'s almost like new. Don\'t pretend to be me though, \'kay? ', cid) + player:addOutfit(156) + player:addOutfit(152) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + player:setStorageValue(Storage.OutfitQuest.AssassinBaseOutfit, 9) + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + 'You\'re a true buddy. I promise I will t-try to avoid killing you even if someone asks me to. ...', + 'Listen, I have this old formula from my grandma. It says... 30 {bonelord eyes}... 10 {red dragon scales}. ...', + 'Then 30 {lizard scales}... 20 {fish fins} - ew, this sounds disgusting, I wonder if this is really a potion or rather a cleaning agent. ...', + 'Add 20 ounces of {vampire dust}, 10 ounces of {demon dust} and mix well with one flask of {warrior\'s sweat}. ...', + 'Okayyy, this is a lot... we\'ll take this step by step. Will you help me gathering 30 {bonelord eyes}?' + }, cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + if player:getStorageValue(Storage.OutfitQuest.DefaultStart) ~= 1 then + player:setStorageValue(Storage.OutfitQuest.DefaultStart, 1) + end + player:setStorageValue(Storage.OutfitQuest.AssassinBaseOutfit, 1) + npcHandler:say('G-good. Go get them, I\'ll have a beer in the meantime.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + local targetMessage = config[message[cid]] + local count = targetMessage.count or 1 + if not player:removeItem(targetMessage.itemId, count) then + npcHandler:say('Next time you lie to me I\'ll k-kill you. Don\'t think I can\'t aim well just because I\'m d-drunk.', cid) + npcHandler.topic[cid] = 0 + return true + end + + player:setStorageValue(Storage.OutfitQuest.AssassinBaseOutfit, player:getStorageValue(Storage.OutfitQuest.AssassinBaseOutfit) + 1) + npcHandler:say(targetMessage.text[3], cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'no') then + if npcHandler.topic[cid] ~= 3 then + npcHandler:say('Then not .', cid) + elseif npcHandler.topic[cid] == 3 then + npcHandler:say('H-hurry up! I have to start working soon.', cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +local function onReleaseFocus(cid) + message[cid] = nil +end + +keywordHandler:addKeyword({'addon'}, StdModule.say, {npcHandler = npcHandler, text = 'I can give you a scar as an addon. Nyahahah.'}) +keywordHandler:addKeyword({'booze'}, StdModule.say, {npcHandler = npcHandler, text = 'Did I say booze? I meant, {flamingo}. Pink birds are kinda cool, don\'t you think? Especially on a painting.'}) +keywordHandler:addKeyword({'flamingo'}, StdModule.say, {npcHandler = npcHandler, text = 'You have to enjoy the word. Like, {flayyyminnngoooo}. Say it with me. '}) +keywordHandler:addKeyword({'flayyyminnngoooo'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes, you got it! Hahaha, we understand each other. Good {job}. '}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m a killer! Yeshindeed! A masterful assassin. I prefer that too \'Peekay\'. '}) +keywordHandler:addKeyword({'outfit'}, StdModule.say, {npcHandler = npcHandler, text = 'O-outfit? You already have a t-troll outfit. That\'s good enough for you. '}) +keywordHandler:addKeyword({'sober'}, StdModule.say, {npcHandler = npcHandler, text = 'I wish there was like a {potion} which makes you sober in an instant. Dwarven rings wear off so fast. '}) + +npcHandler:setMessage(MESSAGE_FAREWELL, 'T-time for another b-beer. ') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Oh, two t-trolls. Hellooo, wittle twolls. ') + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/victor.lua b/data/npc/scripts/victor.lua new file mode 100644 index 00000000000..e88e935b7eb --- /dev/null +++ b/data/npc/scripts/victor.lua @@ -0,0 +1,20 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/vigintius.lua b/data/npc/scripts/vigintius.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/vigintius.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/vincent.lua b/data/npc/scripts/vincent.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/vincent.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/virgil.lua b/data/npc/scripts/virgil.lua new file mode 100644 index 00000000000..c2b06b7aa5b --- /dev/null +++ b/data/npc/scripts/virgil.lua @@ -0,0 +1,649 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +local count = {} +local transfer = {} + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Don\'t forget to deposit your money here in the Tibian Bank before you head out for adventure.'} } +if VoiceModule then + npcHandler:addModule(VoiceModule:new(voices)) +end +--------------------------------guild bank----------------------------------------------- +local receiptFormat = 'Date: %s\nType: %s\nGold Amount: %d\nReceipt Owner: %s\nRecipient: %s\n\n%s' +local function getReceipt(info) + local receipt = Game.createItem(info.success and 24301 or 24302) + receipt:setAttribute(ITEM_ATTRIBUTE_TEXT, receiptFormat:format(os.date('%d. %b %Y - %H:%M:%S'), info.type, info.amount, info.owner, info.recipient, info.message)) + + return receipt +end + +local function getGuildIdByName(name, func) + db.asyncStoreQuery('SELECT `id` FROM `guilds` WHERE `name` = ' .. db.escapeString(name), + function(resultId) + if resultId then + func(result.getNumber(resultId, 'id')) + result.free(resultId) + else + func(nil) + end + end + ) +end + +local function getGuildBalance(id) + local guild = Guild(id) + if guild then + return guild:getBankBalance() + else + local balance + local resultId = db.storeQuery('SELECT `balance` FROM `guilds` WHERE `id` = ' .. id) + if resultId then + balance = result.getNumber(resultId, 'balance') + result.free(resultId) + end + + return balance + end +end + +local function setGuildBalance(id, balance) + local guild = Guild(id) + if guild then + guild:setBankBalance(balance) + else + db.query('UPDATE `guilds` SET `balance` = ' .. balance .. ' WHERE `id` = ' .. id) + end +end + +local function transferFactory(playerName, amount, fromGuildId, info) + return function(toGuildId) + if not toGuildId then + local player = Player(playerName) + if player then + info.success = false + info.message = 'We are sorry to inform you that we could not fulfil your request, because we could not find the recipient guild.' + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + end + else + local fromBalance = getGuildBalance(fromGuildId) + if fromBalance < amount then + info.success = false + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your guild account.' + else + info.success = true + info.message = 'We are happy to inform you that your transfer request was successfully carried out.' + setGuildBalance(fromGuildId, fromBalance - amount) + setGuildBalance(toGuildId, getGuildBalance(toGuildId) + amount) + end + + local player = Player(playerName) + if player then + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + end + end + end +end +--------------------------------guild bank----------------------------------------------- + +local function greetCallback(cid) + count[cid], transfer[cid] = nil, nil + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) +---------------------------- help ------------------------ + if msgcontains(msg, 'bank account') then + npcHandler:say({ + 'Every Tibian has one. The big advantage is that you can access your money in every branch of the Tibian Bank! ...', + 'Would you like to know more about the {basic} functions of your bank account, the {advanced} functions, or are you already bored, perhaps?' + }, cid) + npcHandler.topic[cid] = 0 + return true +---------------------------- balance --------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild balance') then + npcHandler.topic[cid] = 0 + if not player:getGuild() then + npcHandler:say('You are not a member of a guild.', cid) + return false + end + npcHandler:say('Your guild account balance is ' .. player:getGuild():getBankBalance() .. ' gold.', cid) + return true +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'balance') then + npcHandler.topic[cid] = 0 + if player:getBankBalance() >= 100000000 then + npcHandler:say('I think you must be one of the richest inhabitants in the world! Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + elseif player:getBankBalance() >= 10000000 then + npcHandler:say('You have made ten millions and it still grows! Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + elseif player:getBankBalance() >= 1000000 then + npcHandler:say('Wow, you have reached the magic number of a million gp!!! Your account balance is ' .. player:getBankBalance() .. ' gold!', cid) + return true + elseif player:getBankBalance() >= 100000 then + npcHandler:say('You certainly have made a pretty penny. Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + else + npcHandler:say('Your account balance is ' .. player:getBankBalance() .. ' gold.', cid) + return true + end +---------------------------- deposit --------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild deposit') then + if not player:getGuild() then + npcHandler:say('You are not a member of a guild.', cid) + npcHandler.topic[cid] = 0 + return false + end + -- count[cid] = player:getMoney() + -- if count[cid] < 1 then + -- npcHandler:say('You do not have enough gold.', cid) + -- npcHandler.topic[cid] = 0 + -- return false + --end + if string.match(msg, '%d+') then + count[cid] = getMoneyCount(msg) + if count[cid] < 1 then + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return false + end + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold to your {guild account}?', cid) + npcHandler.topic[cid] = 23 + return true + else + npcHandler:say('Please tell me how much gold it is you would like to deposit.', cid) + npcHandler.topic[cid] = 22 + return true + end + elseif npcHandler.topic[cid] == 22 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold to your {guild account}?', cid) + npcHandler.topic[cid] = 23 + return true + else + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return true + end + elseif npcHandler.topic[cid] == 23 then + if msgcontains(msg, 'yes') then + npcHandler:say('Alright, we have placed an order to deposit the amount of ' .. count[cid] .. ' gold to your guild account. Please check your inbox for confirmation.', cid) + local guild = player:getGuild() + local info = { + type = 'Guild Deposit', + amount = count[cid], + owner = player:getName() .. ' of ' .. guild:getName(), + recipient = guild:getName() + } + local playerBalance = player:getBankBalance() + if playerBalance < tonumber(count[cid]) then + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your bank account.' + info.success = false + else + info.message = 'We are happy to inform you that your transfer request was successfully carried out.' + info.success = true + guild:setBankBalance(guild:getBankBalance() + tonumber(count[cid])) + player:setBankBalance(playerBalance - tonumber(count[cid])) + end + + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish. Is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 + return true +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'deposit') then + count[cid] = player:getMoney() + if count[cid] < 1 then + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return false + end + if msgcontains(msg, 'all') then + count[cid] = player:getMoney() + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid) + npcHandler.topic[cid] = 2 + return true + else + if string.match(msg,'%d+') then + count[cid] = getMoneyCount(msg) + if count[cid] < 1 then + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return false + end + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid) + npcHandler.topic[cid] = 2 + return true + else + npcHandler:say('Please tell me how much gold it is you would like to deposit.', cid) + npcHandler.topic[cid] = 1 + return true + end + end + if not isValidMoney(count[cid]) then + npcHandler:say('Sorry, but you can\'t deposit that much.', cid) + npcHandler.topic[cid] = 0 + return false + end + elseif npcHandler.topic[cid] == 1 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Would you really like to deposit ' .. count[cid] .. ' gold?', cid) + npcHandler.topic[cid] = 2 + return true + else + npcHandler:say('You do not have enough gold.', cid) + npcHandler.topic[cid] = 0 + return true + end + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, 'yes') then + if player:depositMoney(count[cid]) then + npcHandler:say('Alright, we have added the amount of ' .. count[cid] .. ' gold to your {balance}. You can {withdraw} your money anytime you want to.', cid) + else + npcHandler:say('You do not have enough gold.', cid) + end + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish. Is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 + return true +---------------------------- withdraw -------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild withdraw') then + if not player:getGuild() then + npcHandler:say('I am sorry but it seems you are currently not in any guild.', cid) + npcHandler.topic[cid] = 0 + return false + elseif player:getGuildLevel() < 2 then + npcHandler:say('Only guild leaders or vice leaders can withdraw money from the guild account.', cid) + npcHandler.topic[cid] = 0 + return false + end + + if string.match(msg,'%d+') then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your guild account?', cid) + npcHandler.topic[cid] = 25 + else + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + end + return true + else + npcHandler:say('Please tell me how much gold you would like to withdraw from your guild account.', cid) + npcHandler.topic[cid] = 24 + return true + end + elseif npcHandler.topic[cid] == 24 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your guild account?', cid) + npcHandler.topic[cid] = 25 + else + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + end + return true + elseif npcHandler.topic[cid] == 25 then + if msgcontains(msg, 'yes') then + local guild = player:getGuild() + local balance = guild:getBankBalance() + npcHandler:say('We placed an order to withdraw ' .. count[cid] .. ' gold from your guild account. Please check your inbox for confirmation.', cid) + local info = { + type = 'Guild Withdraw', + amount = count[cid], + owner = player:getName() .. ' of ' .. guild:getName(), + recipient = player:getName() + } + if balance < tonumber(count[cid]) then + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your guild account.' + info.success = false + else + info.message = 'We are happy to inform you that your transfer request was successfully carried out.' + info.success = true + guild:setBankBalance(balance - tonumber(count[cid])) + local playerBalance = player:getBankBalance() + player:setBankBalance(playerBalance + tonumber(count[cid])) + end + + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') then + npcHandler:say('As you wish. Is there something else I can do for you?', cid) + npcHandler.topic[cid] = 0 + end + return true +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'withdraw') then + if string.match(msg,'%d+') then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your bank account?', cid) + npcHandler.topic[cid] = 7 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + return true + else + npcHandler:say('Please tell me how much gold you would like to withdraw.', cid) + npcHandler.topic[cid] = 6 + return true + end + elseif npcHandler.topic[cid] == 6 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say('Are you sure you wish to withdraw ' .. count[cid] .. ' gold from your bank account?', cid) + npcHandler.topic[cid] = 7 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + return true + elseif npcHandler.topic[cid] == 7 then + if msgcontains(msg, 'yes') then + if player:getFreeCapacity() >= getMoneyWeight(count[cid]) then + if not player:withdrawMoney(count[cid]) then + npcHandler:say('There is not enough gold on your account.', cid) + else + npcHandler:say('Here you are, ' .. count[cid] .. ' gold. Please let me know if there is something else I can do for you.', cid) + end + else + npcHandler:say('Whoah, hold on, you have no room in your inventory to carry all those coins. I don\'t want you to drop it on the floor, maybe come back with a cart!', cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') then + npcHandler:say('The customer is king! Come back anytime you want to if you wish to {withdraw} your money.', cid) + npcHandler.topic[cid] = 0 + end + return true +---------------------------- transfer -------------------- +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'guild transfer') then + if not player:getGuild() then + npcHandler:say('I am sorry but it seems you are currently not in any guild.', cid) + npcHandler.topic[cid] = 0 + return false + elseif player:getGuildLevel() < 2 then + npcHandler:say('Only guild leaders or vice leaders can transfer money from the guild account.', cid) + npcHandler.topic[cid] = 0 + return false + end + + if string.match(msg, '%d+') then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + transfer[cid] = string.match(msg, 'to%s*(.+)$') + if transfer[cid] then + npcHandler:say('So you would like to transfer ' .. count[cid] .. ' gold from your guild account to guild ' .. transfer[cid] .. '?', cid) + npcHandler.topic[cid] = 28 + else + npcHandler:say('Which guild would you like to transfer ' .. count[cid] .. ' gold to?', cid) + npcHandler.topic[cid] = 27 + end + else + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + end + else + npcHandler:say('Please tell me the amount of gold you would like to transfer.', cid) + npcHandler.topic[cid] = 26 + end + return true + elseif npcHandler.topic[cid] == 26 then + count[cid] = getMoneyCount(msg) + if player:getGuild():getBankBalance() < count[cid] then + npcHandler:say('There is not enough gold on your guild account.', cid) + npcHandler.topic[cid] = 0 + return true + end + if isValidMoney(count[cid]) then + npcHandler:say('Which guild would you like to transfer ' .. count[cid] .. ' gold to?', cid) + npcHandler.topic[cid] = 27 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + return true + elseif npcHandler.topic[cid] == 27 then + transfer[cid] = msg + if player:getGuild():getName() == transfer[cid] then + npcHandler:say('Fill in this field with person who receives your gold!', cid) + npcHandler.topic[cid] = 0 + return true + end + npcHandler:say('So you would like to transfer ' .. count[cid] .. ' gold from your guild account to guild ' .. transfer[cid] .. '?', cid) + npcHandler.topic[cid] = 28 + return true + elseif npcHandler.topic[cid] == 28 then + if msgcontains(msg, 'yes') then + npcHandler:say('We have placed an order to transfer ' .. count[cid] .. ' gold from your guild account to guild ' .. transfer[cid] .. '. Please check your inbox for confirmation.', cid) + local guild = player:getGuild() + local balance = guild:getBankBalance() + local info = { + type = 'Guild to Guild Transfer', + amount = count[cid], + owner = player:getName() .. ' of ' .. guild:getName(), + recipient = transfer[cid] + } + if balance < tonumber(count[cid]) then + info.message = 'We are sorry to inform you that we could not fulfill your request, due to a lack of the required sum on your guild account.' + info.success = false + local inbox = player:getInbox() + local receipt = getReceipt(info) + inbox:addItemEx(receipt, INDEX_WHEREEVER, FLAG_NOLIMIT) + else + getGuildIdByName(transfer[cid], transferFactory(player:getName(), tonumber(count[cid]), guild:getId(), info)) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') then + npcHandler:say('Alright, is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 +--------------------------------guild bank----------------------------------------------- + elseif msgcontains(msg, 'transfer') then + npcHandler:say('Please tell me the amount of gold you would like to transfer.', cid) + npcHandler.topic[cid] = 11 + elseif npcHandler.topic[cid] == 11 then + count[cid] = getMoneyCount(msg) + if player:getBankBalance() < count[cid] then + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + return true + end + if isValidMoney(count[cid]) then + npcHandler:say('Who would you like transfer ' .. count[cid] .. ' gold to?', cid) + npcHandler.topic[cid] = 12 + else + npcHandler:say('There is not enough gold on your account.', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 12 then + transfer[cid] = msg + if player:getName() == transfer[cid] then + npcHandler:say('Fill in this field with person who receives your gold!', cid) + npcHandler.topic[cid] = 0 + return true + end + if playerExists(transfer[cid]) then + local arrayDenied = {"accountmanager", "rooksample", "druidsample", "sorcerersample", "knightsample", "paladinsample"} + if isInArray(arrayDenied, string.gsub(transfer[cid]:lower(), " ", "")) then + npcHandler:say('This player does not exist.', cid) + npcHandler.topic[cid] = 0 + return true + end + npcHandler:say('So you would like to transfer ' .. count[cid] .. ' gold to ' .. transfer[cid] .. '?', cid) + npcHandler.topic[cid] = 13 + else + npcHandler:say('This player does not exist.', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 13 then + if msgcontains(msg, 'yes') then + if not player:transferMoneyTo(transfer[cid], count[cid]) then + npcHandler:say('You cannot transfer money to this account.', cid) + else + npcHandler:say('Very well. You have transferred ' .. count[cid] .. ' gold to ' .. transfer[cid] ..'.', cid) + transfer[cid] = nil + end + elseif msgcontains(msg, 'no') then + npcHandler:say('Alright, is there something else I can do for you?', cid) + end + npcHandler.topic[cid] = 0 +---------------------------- money exchange -------------- + elseif msgcontains(msg, 'change gold') then + npcHandler:say('How many platinum coins would you like to get?', cid) + npcHandler.topic[cid] = 14 + elseif npcHandler.topic[cid] == 14 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough gold coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] * 100 .. ' of your gold coins into ' .. count[cid] .. ' platinum coins?', cid) + npcHandler.topic[cid] = 15 + end + elseif npcHandler.topic[cid] == 15 then + if msgcontains(msg, 'yes') then + if player:removeItem(2148, count[cid] * 100) then + player:addItem(2152, count[cid]) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough gold coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'change platinum') then + npcHandler:say('Would you like to change your platinum coins into gold or crystal?', cid) + npcHandler.topic[cid] = 16 + elseif npcHandler.topic[cid] == 16 then + if msgcontains(msg, 'gold') then + npcHandler:say('How many platinum coins would you like to change into gold?', cid) + npcHandler.topic[cid] = 17 + elseif msgcontains(msg, 'crystal') then + npcHandler:say('How many crystal coins would you like to get?', cid) + npcHandler.topic[cid] = 19 + else + npcHandler:say('Well, can I help you with something else?', cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 17 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] .. ' of your platinum coins into ' .. count[cid] * 100 .. ' gold coins for you?', cid) + npcHandler.topic[cid] = 18 + end + elseif npcHandler.topic[cid] == 18 then + if msgcontains(msg, 'yes') then + if player:removeItem(2152, count[cid]) then + player:addItem(2148, count[cid] * 100) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 19 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] * 100 .. ' of your platinum coins into ' .. count[cid] .. ' crystal coins for you?', cid) + npcHandler.topic[cid] = 20 + end + elseif npcHandler.topic[cid] == 20 then + if msgcontains(msg, 'yes') then + if player:removeItem(2152, count[cid] * 100) then + player:addItem(2160, count[cid]) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough platinum coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'change crystal') then + npcHandler:say('How many crystal coins would you like to change into platinum?', cid) + npcHandler.topic[cid] = 21 + elseif npcHandler.topic[cid] == 21 then + if getMoneyCount(msg) < 1 then + npcHandler:say('Sorry, you do not have enough crystal coins.', cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say('So you would like me to change ' .. count[cid] .. ' of your crystal coins into ' .. count[cid] * 100 .. ' platinum coins for you?', cid) + npcHandler.topic[cid] = 22 + end + elseif npcHandler.topic[cid] == 22 then + if msgcontains(msg, 'yes') then + if player:removeItem(2160, count[cid]) then + player:addItem(2152, count[cid] * 100) + npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry, you do not have enough crystal coins.', cid) + end + else + npcHandler:say('Well, can I help you with something else?', cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({'money'}, StdModule.say, {npcHandler = npcHandler, text = 'We can {change} money for you. You can also access your {bank account}.'}) +keywordHandler:addKeyword({'change'}, StdModule.say, {npcHandler = npcHandler, text = 'There are three different coin types in Tibia: 100 gold coins equal 1 platinum coin, 100 platinum coins equal 1 crystal coin. So if you\'d like to change 100 gold into 1 platinum, simply say \'{change gold}\' and then \'1 platinum\'.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'We can {change} money for you. You can also access your {bank account}.'}) +keywordHandler:addKeyword({'advanced'}, StdModule.say, {npcHandler = npcHandler, text = 'Your bank account will be used automatically when you want to {rent} a house or place an offer on an item on the {market}. Let me know if you want to know about how either one works.'}) +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'You can check the {balance} of your bank account, {deposit} money or {withdraw} it. You can also {transfer} money to other characters, provided that they have a vocation.'}) +keywordHandler:addKeyword({'functions'}, StdModule.say, {npcHandler = npcHandler, text = 'You can check the {balance} of your bank account, {deposit} money or {withdraw} it. You can also {transfer} money to other characters, provided that they have a vocation.'}) +keywordHandler:addKeyword({'basic'}, StdModule.say, {npcHandler = npcHandler, text = 'You can check the {balance} of your bank account, {deposit} money or {withdraw} it. You can also {transfer} money to other characters, provided that they have a vocation.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I work in this bank. I can change money for you and help you with your bank account.'}) + +npcHandler:setMessage(MESSAGE_GREET, "Yes? What may I do for you, |PLAYERNAME|? Bank business, perhaps?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Have a nice day.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Have a nice day.") +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/vladruc.lua b/data/npc/scripts/vladruc.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/vladruc.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/vulturenose.lua b/data/npc/scripts/vulturenose.lua new file mode 100644 index 00000000000..1180d8dd959 --- /dev/null +++ b/data/npc/scripts/vulturenose.lua @@ -0,0 +1,46 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'enter') then + if player:getStorageValue(Storage.TheShatteredIsles.RaysMission3) == 1 + and player:getStorageValue(Storage.TheShatteredIsles.YavernDoor) < 0 then + local headItem = player:getSlotItem(CONST_SLOT_HEAD) + local armorItem = player:getSlotItem(CONST_SLOT_ARMOR) + local legsItem = player:getSlotItem(CONST_SLOT_LEGS) + local feetItem = player:getSlotItem(CONST_SLOT_FEET) + if headItem and headItem.itemid == 6096 and armorItem and armorItem.itemid == 6095 + and legsItem and legsItem.itemid == 5918 and feetItem and feetItem.itemid == 5462 then + npcHandler:say('Hey, I rarely see a dashing pirate like you! Get in, matey!', cid) + player:setStorageValue(Storage.TheShatteredIsles.YavernDoor, 1) + else + npcHandler:say("YOU WILL NOT PASS! Erm ... \ + I mean you don't look like a true pirate to me. You won't get in.", cid) + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/vuzrog.lua b/data/npc/scripts/vuzrog.lua new file mode 100644 index 00000000000..e88e935b7eb --- /dev/null +++ b/data/npc/scripts/vuzrog.lua @@ -0,0 +1,20 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/wally.lua b/data/npc/scripts/wally.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/wally.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/walter_the_guard.lua b/data/npc/scripts/walter_the_guard.lua new file mode 100644 index 00000000000..520707f1205 --- /dev/null +++ b/data/npc/scripts/walter_the_guard.lua @@ -0,0 +1,52 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if(msgcontains(msg, "trouble") and player:getStorageValue(Storage.TheInquisition.WalterGuard) < 1 and player:getStorageValue(Storage.TheInquisition.Mission01) ~= -1) then + npcHandler:say("I think there is a pickpocket in town.", cid) + npcHandler.topic[cid] = 1 + elseif(msgcontains(msg, "authorities")) then + if(npcHandler.topic[cid] == 1) then + npcHandler:say("Well, sooner or later we will get hold of that delinquent. That's for sure.", cid) + npcHandler.topic[cid] = 2 + end + elseif(msgcontains(msg, "avoided")) then + if(npcHandler.topic[cid] == 2) then + npcHandler:say("You can't tell by a person's appearance who is a pickpocket and who isn't. You simply can't close the city gates for everyone.", cid) + npcHandler.topic[cid] = 3 + end + elseif(msgcontains(msg, "gods would allow")) then + if(npcHandler.topic[cid] == 3) then + npcHandler:say("If the gods had created the world a paradise, no one had to steal at all.", cid) + npcHandler.topic[cid] = 0 + if(player:getStorageValue(Storage.TheInquisition.WalterGuard) < 1) then + player:setStorageValue(Storage.TheInquisition.WalterGuard, 1) + player:setStorageValue(Storage.TheInquisition.Mission01, player:getStorageValue(Storage.TheInquisition.Mission01) + 1) -- The Inquisition Questlog- "Mission 1: Interrogation" + player:getPosition():sendMagicEffect(CONST_ME_HOLYAREA) + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/warbert.lua b/data/npc/scripts/warbert.lua new file mode 100644 index 00000000000..e160dd39add --- /dev/null +++ b/data/npc/scripts/warbert.lua @@ -0,0 +1,38 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(10, 1000, -10) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if isInArray({"fuck", "idiot", "asshole", "ass", "fag", "stupid", "tyrant", "shit", "lunatic"}, msg) then + npcHandler:say("Take this!", cid) + local player = Player(cid) + player:getPosition():sendMagicEffect(CONST_ME_EXPLOSIONAREA) + player:addCondition(condition) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/weaponmaster.lua b/data/npc/scripts/weaponmaster.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/weaponmaster.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/wentworth.lua b/data/npc/scripts/wentworth.lua new file mode 100644 index 00000000000..4a16e59d101 --- /dev/null +++ b/data/npc/scripts/wentworth.lua @@ -0,0 +1,371 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + {text = "Waste not, want not!"}, + {text = "Don't burden yourself with too much cash - store it here!"}, + {text = "Don't take the money and run - deposit it and walk instead!"} +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local count = {} +local function greetCallback(cid) + count[cid] = nil + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + --Help + if msgcontains(msg, "bank account") then + npcHandler:say( + { + "Every Adventurer has one. \z + The big advantage is that you can access your money in every branch of the World Bank! ...", + "Would you like to know more about the {basic} functions of your bank account, the {advanced} functions, \z + or are you already bored, perhaps?" + }, + cid, false, true, 10) + npcHandler.topic[cid] = 0 + return true + --Balance + elseif msgcontains(msg, "balance") then + npcHandler.topic[cid] = 0 + if player:getBankBalance() >= 100000000 then + npcHandler:say("I think you must be one of the richest inhabitants in the world! \z + Your account balance is " .. player:getBankBalance() .. " gold.", cid) + return true + elseif player:getBankBalance() >= 10000000 then + npcHandler:say("You have made ten millions and it still grows! Your account balance is \z + " .. player:getBankBalance() .. " gold.", cid) + return true + elseif player:getBankBalance() >= 1000000 then + npcHandler:say("Wow, you have reached the magic number of a million gp!!! \z + Your account balance is " .. player:getBankBalance() .. " gold!", cid) + return true + elseif player:getBankBalance() >= 100000 then + npcHandler:say("You certainly have made a pretty penny. Your account balance is \z + " .. player:getBankBalance() .. " gold.", cid) + return true + else + npcHandler:say("Your account balance is " .. player:getBankBalance() .. " gold.", cid) + return true + end + --Deposit + elseif msgcontains(msg, "deposit") then + count[cid] = player:getMoney() + if count[cid] < 1 then + npcHandler:say("You do not have enough gold.", cid) + npcHandler.topic[cid] = 0 + return false + elseif not isValidMoney(count[cid]) then + npcHandler:say("Sorry, but you can't deposit that much.", cid) + npcHandler.topic[cid] = 0 + return false + end + if msgcontains(msg, "all") then + count[cid] = player:getMoney() + npcHandler:say("Would you really like to deposit " .. count[cid] .. " gold?", cid) + npcHandler.topic[cid] = 2 + return true + else + if string.match(msg,"%d+") then + count[cid] = getMoneyCount(msg) + if count[cid] < 1 then + npcHandler:say("You do not have enough gold.", cid) + npcHandler.topic[cid] = 0 + return false + end + npcHandler:say("Would you really like to deposit " .. count[cid] .. " gold?", cid) + npcHandler.topic[cid] = 2 + return true + else + npcHandler:say("Please tell me how much gold it is you would like to deposit.", cid) + npcHandler.topic[cid] = 1 + return true + end + end + elseif npcHandler.topic[cid] == 1 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say("Would you really like to deposit " .. count[cid] .. " gold?", cid) + npcHandler.topic[cid] = 2 + return true + else + npcHandler:say("You do not have enough gold.", cid) + npcHandler.topic[cid] = 0 + return true + end + elseif npcHandler.topic[cid] == 2 then + if msgcontains(msg, "yes") then + if player:getLevel() == 8 then + if count[cid] > 1000 or player:getBankBalance() >= 1000 then + npcHandler:say("Sorry, but you can't deposit that much.", cid) + npcHandler.topic[cid] = 0 + return false + end + elseif player:getLevel() > 9 then + if count[cid] > 2000 or player:getBankBalance() >= 2000 then + npcHandler:say("Sorry, but you can't deposit that much.", cid) + npcHandler.topic[cid] = 0 + return false + end + end + if player:depositMoney(count[cid]) then + npcHandler:say("Alright, we have added the amount of " .. count[cid] .. " gold to your {balance}. \z + You can {withdraw} your money anytime you want to.", cid) + else + npcHandler:say("You do not have enough gold.", cid) + end + elseif msgcontains(msg, "no") then + npcHandler:say("As you wish. Is there something else I can do for you?", cid) + end + npcHandler.topic[cid] = 0 + return true + --Withdraw + elseif msgcontains(msg, "withdraw") then + if string.match(msg,"%d+") then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say("Are you sure you wish to withdraw " .. count[cid] .. " gold from your bank account?", cid) + npcHandler.topic[cid] = 7 + else + npcHandler:say("There is not enough gold on your account.", cid) + npcHandler.topic[cid] = 0 + end + return true + else + npcHandler:say("Please tell me how much gold you would like to withdraw.", cid) + npcHandler.topic[cid] = 6 + return true + end + elseif npcHandler.topic[cid] == 6 then + count[cid] = getMoneyCount(msg) + if isValidMoney(count[cid]) then + npcHandler:say("Are you sure you wish to withdraw " .. count[cid] .. " gold from your bank account?", cid) + npcHandler.topic[cid] = 7 + else + npcHandler:say("There is not enough gold on your account.", cid) + npcHandler.topic[cid] = 0 + end + return true + elseif npcHandler.topic[cid] == 7 then + if msgcontains(msg, "yes") then + if player:getFreeCapacity() >= getMoneyWeight(count[cid]) then + if not player:withdrawMoney(count[cid]) then + npcHandler:say("There is not enough gold on your account.", cid) + else + npcHandler:say("Here you are, " .. count[cid] .. " gold. \z + Please let me know if there is something else I can do for you.", cid) + end + else + npcHandler:say("Whoah, hold on, you have no room in your inventory to carry all those coins. \z + I don't want you to drop it on the floor, maybe come back with a cart!", cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "no") then + npcHandler:say("The customer is king! Come back anytime you want to if you wish to {withdraw} your money.", cid) + npcHandler.topic[cid] = 0 + end + return true + --Money exchange + elseif msgcontains(msg, "change gold") then + npcHandler:say("How many platinum coins would you like to get?", cid) + npcHandler.topic[cid] = 14 + elseif npcHandler.topic[cid] == 14 then + if getMoneyCount(msg) < 1 then + npcHandler:say("Sorry, you do not have enough gold coins.", cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say("So you would like me to change " .. count[cid] * 100 .. " of your gold \z + coins into " .. count[cid] .. " platinum coins?", cid) + npcHandler.topic[cid] = 15 + end + elseif npcHandler.topic[cid] == 15 then + if msgcontains(msg, "yes") then + if player:removeItem(2148, count[cid] * 100) then + player:addItem(2152, count[cid]) + npcHandler:say("Here you are.", cid) + else + npcHandler:say("Sorry, you do not have enough gold coins.", cid) + end + else + npcHandler:say("Well, can I help you with something else?", cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "change platinum") then + npcHandler:say("Would you like to change your platinum coins into gold or crystal?", cid) + npcHandler.topic[cid] = 16 + elseif npcHandler.topic[cid] == 16 then + if msgcontains(msg, "gold") then + npcHandler:say("How many platinum coins would you like to change into gold?", cid) + npcHandler.topic[cid] = 17 + elseif msgcontains(msg, "crystal") then + npcHandler:say("How many crystal coins would you like to get?", cid) + npcHandler.topic[cid] = 19 + else + npcHandler:say("Well, can I help you with something else?", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 17 then + if getMoneyCount(msg) < 1 then + npcHandler:say("Sorry, you do not have enough platinum coins.", cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say("So you would like me to change " .. count[cid] .. " of your platinum \z + coins into " .. count[cid] * 100 .. " gold coins for you?", cid) + npcHandler.topic[cid] = 18 + end + elseif npcHandler.topic[cid] == 18 then + if msgcontains(msg, "yes") then + if player:removeItem(2152, count[cid]) then + player:addItem(2148, count[cid] * 100) + npcHandler:say("Here you are.", cid) + else + npcHandler:say("Sorry, you do not have enough platinum coins.", cid) + end + else + npcHandler:say("Well, can I help you with something else?", cid) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 19 then + if getMoneyCount(msg) < 1 then + npcHandler:say("Sorry, you do not have enough platinum coins.", cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say("So you would like me to change " .. count[cid] * 100 .. " of your platinum coins \z + into " .. count[cid] .. " crystal coins for you?", cid) + npcHandler.topic[cid] = 20 + end + elseif npcHandler.topic[cid] == 20 then + if msgcontains(msg, "yes") then + if player:removeItem(2152, count[cid] * 100) then + player:addItem(2160, count[cid]) + npcHandler:say("Here you are.", cid) + else + npcHandler:say("Sorry, you do not have enough platinum coins.", cid) + end + else + npcHandler:say("Well, can I help you with something else?", cid) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "change crystal") then + npcHandler:say("How many crystal coins would you like to change into platinum?", cid) + npcHandler.topic[cid] = 21 + elseif npcHandler.topic[cid] == 21 then + if getMoneyCount(msg) < 1 then + npcHandler:say("Sorry, you do not have enough crystal coins.", cid) + npcHandler.topic[cid] = 0 + else + count[cid] = getMoneyCount(msg) + npcHandler:say("So you would like me to change " .. count[cid] .. " of your crystal coins \z + into " .. count[cid] * 100 .. " platinum coins for you?", cid) + npcHandler.topic[cid] = 22 + end + elseif npcHandler.topic[cid] == 22 then + if msgcontains(msg, "yes") then + if player:removeItem(2160, count[cid]) then + player:addItem(2152, count[cid] * 100) + npcHandler:say("Here you are.", cid) + else + npcHandler:say("Sorry, you do not have enough crystal coins.", cid) + end + else + npcHandler:say("Well, can I help you with something else?", cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + +keywordHandler:addKeyword({"money"}, StdModule.say, + { + npcHandler = npcHandler, + text = "We can {change} money for you. You can also access your {bank account}." + } +) +keywordHandler:addKeyword({"change"}, StdModule.say, + { + npcHandler = npcHandler, + text = "There are three different coin types in Tibia: 100 gold coins equal 1 platinum coin, \z + 100 platinum coins equal 1 crystal coin. \z + So if you'd like to change 100 gold into 1 platinum, simply say '{change gold}' and then '1 platinum'." + } +) +keywordHandler:addKeyword({"bank"}, StdModule.say, + { + npcHandler = npcHandler, + text = "We can {change} money for you. You can also access your {bank account}." + } +) +keywordHandler:addKeyword({"advanced"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Your bank account will be used automatically when you want to {rent} a house or place an offer \z + on an item on the {market}. Let me know if you want to know about how either one works." + } +) +keywordHandler:addKeyword({"help"}, StdModule.say, + { + npcHandler = npcHandler, + text = "You can check the {balance} of your bank account, {deposit} money or {withdraw} it. \z + You can also {transfer} money to other characters, provided that they have a vocation." + } +) +keywordHandler:addKeyword({"functions"}, StdModule.say, + { + npcHandler = npcHandler, + text = "You can check the {balance} of your bank account, {deposit} money or {withdraw} it. \z + You can also {transfer} money to other characters, provided that they have a vocation." + } +) +keywordHandler:addKeyword({"basic"}, StdModule.say, + { + npcHandler = npcHandler, + text = "You can check the {balance} of your bank account, {deposit} money or {withdraw} it. \z + You can also {transfer} money to other characters, provided that they have a vocation." + } +) +keywordHandler:addKeyword({"job"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I work in this bank. I can change money for you and help you with your bank account." + } +) +keywordHandler:addKeyword({"transfer"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I'm afraid this service is not available to you until you reach the World mainland." + } +) + +npcHandler:setMessage(MESSAGE_GREET, "Yes? What may I do for you, |PLAYERNAME|? Bank business, perhaps?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Have a nice day.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Have a nice day.") + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/willard.lua b/data/npc/scripts/willard.lua new file mode 100644 index 00000000000..a64542f3eac --- /dev/null +++ b/data/npc/scripts/willard.lua @@ -0,0 +1,51 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Selling weapons, ammunition and armor. Special offers only available here, have a look!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "package for rashid") then + if player:getStorageValue(Storage.TravellingTrader.Mission02) >= 1 and player:getStorageValue(Storage.TravellingTrader.Mission02) < 3 then + npcHandler:say({ + "Oooh, damn, I completely forgot about that. I was supposed to pick it up from the Outlaw Camp. ...", + "I can't leave my shop here right now, please go and talk to Snake Eye about that package... I promise he won't make any trouble. ...", + "Don't tell Rashid! I really don't want him to know that I forgot his order. Okay?" + }, cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Thank you, I appreciate it. Don't forget to mention the package to Snake.", cid) + player:setStorageValue(Storage.TravellingTrader.Mission02, player:getStorageValue(Storage.TravellingTrader.Mission02) + 1) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Greetings and Banor be with you, |PLAYERNAME|! May I interest you in a {trade} for weapons, ammunition or armor?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Farewell, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Farewell, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Of course, just browse through my wares. If you're only interested in {distance} equipment, let me know.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/willem.lua b/data/npc/scripts/willem.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/willem.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/william.lua b/data/npc/scripts/william.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/william.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/willie.lua b/data/npc/scripts/willie.lua new file mode 100644 index 00000000000..8456830fdc1 --- /dev/null +++ b/data/npc/scripts/willie.lua @@ -0,0 +1,342 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = "Ah, what the heck.Make sure you know what you want before you bug me." }, + { text = "Buying and selling food!" }, + { text = "Make sure you know what you want before you bug me." }, + { text = "You, over there! Stop sniffing around my farm! Either trade with me or leave!" } +} +npcHandler:addModule(VoiceModule:new(voices)) + +-- NPC shop +local shopModule = ShopModule:new() +npcHandler:addModule(shopModule) +-- Buyable +-- Name, id, price, count/charges +shopModule:addBuyableItem({"bread"}, 2689, 3, 1) +shopModule:addBuyableItem({"cheese"}, 2696, 5, 1) +shopModule:addBuyableItem({"ham"}, 2671, 8, 1) +shopModule:addBuyableItem({"meat"}, 2666, 5, 1) +-- Sellable +shopModule:addSellableItem({"bread"}, 2689, 1, 1) +shopModule:addSellableItem({"cheese"}, 2696, 2, 1) +shopModule:addSellableItem({"ham"}, 2671, 4, 1) +shopModule:addSellableItem({"meat"}, 2666, 2, 1) +shopModule:addSellableItem({"cherry"}, 2679, 1, 1) +shopModule:addSellableItem({"egg"}, 2695, 1, 1) +shopModule:addSellableItem({"salmon"}, 2668, 2, 1) + +-- Basic keywords +keywordHandler:addKeyword({"offer"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Haven't they taught you anything at school? Ask for a {trade} if you want to trade." + } +) +keywordHandler:addAliasKeyword({"sell"}) +keywordHandler:addAliasKeyword({"buy"}) +keywordHandler:addAliasKeyword({"food"}) + +keywordHandler:addKeyword({"information"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Help yourself. Or ask the other {citizens}, I don't have time for that." + } +) +keywordHandler:addAliasKeyword({"help"}) +keywordHandler:addAliasKeyword({"hint"}) + +keywordHandler:addKeyword({"how", "are", "you"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Fine enough." + } +) +keywordHandler:addKeyword({"name"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Willie." + } +) +keywordHandler:addKeyword({"job"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I'm a farmer and a cook." + } +) +keywordHandler:addKeyword({"cook"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I try out old and new {recipes}. You can sell all {food} to me." + } +) +keywordHandler:addKeyword({"recipe"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I'd love to try a banana pie but I lack the {bananas}. If you get me one, I'll reward you." + } +) +keywordHandler:addKeyword({"citizen"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Which one?" + } +) +keywordHandler:addKeyword({"rookgaard"}, StdModule.say, + { + npcHandler = npcHandler, + text = "This island would be wonderful if there weren't a constant flood of newcomers." + } +) +keywordHandler:addKeyword({"tibia"}, StdModule.say, + { + npcHandler = npcHandler, + text = "If I were you, I'd stay here." + } +) +keywordHandler:addKeyword({"spell"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I know how to spell." + } +) +keywordHandler:addKeyword({"magic"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I'm a magician in the kitchen." + } +) +keywordHandler:addKeyword({"weapon"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I'm not in the weapon business, so stop disturbing me." + } +) +keywordHandler:addKeyword({"king"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I'm glad that we don't see many officials here." + } +) +keywordHandler:addKeyword({"god"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I'm a farmer, not a preacher." + } +) +keywordHandler:addKeyword({"sewer"}, StdModule.say, + { + npcHandler = npcHandler, + text = "What about them? Do you live there?" + } +) +keywordHandler:addKeyword({"dungeon"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I've got no time for your dungeon nonsense." + } +) +keywordHandler:addKeyword({"rat"}, StdModule.say, + { + npcHandler = npcHandler, + text = "My cousin {Billy} cooks rat stew. Yuck! Can you imagine that?" + } +) +keywordHandler:addKeyword({"monster"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Are you afraid of monsters? I bet even the sight of a {rat} would let your knees tremble. Hahaha." + } +) +keywordHandler:addKeyword({"time"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Do I look like a clock?" + } +) +keywordHandler:addKeyword({"god"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I'm a farmer, not a preacher." + } +) + +-- Names +keywordHandler:addKeyword({"al", "dee"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Can't stand him." + } +) +keywordHandler:addKeyword({"amber"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Quite a babe." + } +) +keywordHandler:addKeyword({"billy"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Don't ever mention his name again! He can't even {cook}!" + } +) +keywordHandler:addKeyword({"cipfried"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Our little monkey." + } +) +keywordHandler:addKeyword({"dallheim"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Uhm, fine guy I think." + } +) +keywordHandler:addKeyword({"dixi"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Boring little girl." + } +) +keywordHandler:addKeyword({"hyacinth"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Overrated." + } +) +keywordHandler:addKeyword({"lee'delle"}, StdModule.say, + { + npcHandler = npcHandler, + text = "She thinks she owns this island with her underpriced offers." + } +) +keywordHandler:addKeyword({"lily"}, StdModule.say, + { + npcHandler = npcHandler, + text = "I don't like hippie girls." + } +) +keywordHandler:addKeyword({"loui"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Leave me alone with that guy." + } +) +keywordHandler:addKeyword({"norma"}, StdModule.say, + { + npcHandler = npcHandler, + text = "About time we got a bar here." + } +) +keywordHandler:addKeyword({"obi"}, StdModule.say, + { + npcHandler = npcHandler, + text = "This old guy has only money on his mind." + } +) +keywordHandler:addKeyword({"oracle"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Hopefully it gets you off this island soon so you can stop bugging me." + } +) +keywordHandler:addKeyword({"paulie"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Uptight and correct in any situation." + } +) +keywordHandler:addKeyword({"santiago"}, StdModule.say, + { + npcHandler = npcHandler, + text = "If he wants to sacrifice all his free time for beginners, fine with me. Then they don't disturb me." + } +) +keywordHandler:addKeyword({"seymour"}, StdModule.say, + { + npcHandler = npcHandler, + text = "This joke of a man thinks he is sooo important." + } +) +keywordHandler:addKeyword({"tom"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Decent guy." + } +) +keywordHandler:addKeyword({"willie"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Yeah, so?" + } +) +keywordHandler:addKeyword({"zerbrus"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Overrated." + } +) +keywordHandler:addKeyword({"zirella"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Too old to be interesting for me." + } +) + +-- Studded Shield Quest +local bananaKeyword = keywordHandler:addKeyword({"banana"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Have you found a banana for me?" + } +) +bananaKeyword:addChildKeyword({"yes"}, StdModule.say, + { + npcHandler = npcHandler, + text = "A banana! Great. Here, take this shield, I don't need it anyway.", + reset = true + }, + function(player) + return player:getItemCount(2676) > 0 + end, + function(player) + player:removeItem(2676, 1) + player:addItem(2526, 1) + end +) +bananaKeyword:addChildKeyword({"yes"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Are you trying to mess with me?!", + reset = true + } +) +bananaKeyword:addChildKeyword({""}, StdModule.say, + { + npcHandler = npcHandler, + text = "Too bad.", + reset = true + } +) + +npcHandler:setMessage(MESSAGE_WALKAWAY, "Yeah go away!") +npcHandler:setMessage(MESSAGE_FAREWELL, "Yeah, bye |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Ya take a good look.") +npcHandler:setMessage(MESSAGE_GREET, "Hiho |PLAYERNAME|. I hope you're here to {trade}.") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/willow.lua b/data/npc/scripts/willow.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/willow.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/woblin.lua b/data/npc/scripts/woblin.lua new file mode 100644 index 00000000000..c9d0e9d446c --- /dev/null +++ b/data/npc/scripts/woblin.lua @@ -0,0 +1,83 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "key") then + if player:getStorageValue(Storage.Quest.Dawnport.TheDormKey) == 1 then + npcHandler:say("Me not give key! Key my precious now! \z + By old goblin law all that one has in his pockets for two days is family heirloom! \z + Me no part with my precious ... hm unless you provide Woblin with some {reward}!", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "reward") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Me good angler but one fish eludes me since many many weeks. I call fish ''Old Nasty''. \z + You might catch him in this cave, in that pond there. Bring me Old Nasty and I'll give you key!", cid) + player:setStorageValue(Storage.Quest.Dawnport.TheDormKey, 2) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "old nasty") then + if player:getStorageValue(Storage.Quest.Dawnport.TheDormKey) == 3 and player:getItemCount(23773) >= 1 then + npcHandler:say("You bring me Old Nasty?", cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 2 then + npcHandler:say("Wonderful. I don't believe you will find Dormovo alive, though. \z + He would not have stayed abroad that long without refilling his inkpot for his research notes. \z + But at least the amulet should be retrieved.", cid) + player:removeItem(23773, 1) + key = player:addItem(23763, 1) + key:setActionId(103) + player:setStorageValue(Storage.Quest.Dawnport.TheDormKey, 4) + npcHandler.topic[cid] = 0 + end + end + return true +end + + +keywordHandler:addKeyword({"goblins"}, StdModule.say, + { + npcHandler = npcHandler, + text = "No part of clan. Me prefer company of precious. Or mirror image. Always nice to see pretty me!" + } +) +keywordHandler:addKeyword({"quest"}, StdModule.say, + { + npcHandler = npcHandler, + text = "What you on quest for? Go leave Woblin alone with {precious}" + } +) +keywordHandler:addKeyword({"precious"}, StdModule.say, + { + npcHandler = npcHandler, + text = "Me not give {key}! Key my precious now! By old goblin law all that one has in his pockets for two days \z + is family heirloom! Me no part with my precious ... hm unless you provide Woblin with some {reward}!" + } +) + +npcHandler:setMessage(MESSAGE_GREET, "Hi there human!") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/wyat.lua b/data/npc/scripts/wyat.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/wyat.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/wyda.lua b/data/npc/scripts/wyda.lua new file mode 100644 index 00000000000..c092df102f5 --- /dev/null +++ b/data/npc/scripts/wyda.lua @@ -0,0 +1,99 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(60, 2000, -10) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, 'cookie') then + if player:getStorageValue(Storage.WhatAFoolish.Questline) == 31 + and player:getStorageValue(Storage.WhatAFoolish.CookieDelivery.Wyda) ~= 1 then + npcHandler:say('You brought me a cookie?', cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, 'mission') or msgcontains(msg, 'quest') then + npcHandler:say({ + "A quest? Well, if you\'re so keen on doing me a favour... Why don\'t you try to find a {blood herb}?", + "To be honest, I\'m drowning in blood herbs by now." + }, cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'bloodherb') or msgcontains(msg, 'blood herb') then + if player:getStorageValue(Storage.BloodHerbQuest) == 1 then + npcHandler:say('Arrr... here we go again.... do you have a #$*§# blood herb for me?', cid) + npcHandler.topic[cid] = 2 + else + npcHandler:say({ + "The blood herb is very rare. This plant would be very useful for me, but I don't know any accessible places to find it.", + "To be honest, I'm drowning in blood herbs by now. But if it helps you, well yes.. I guess I could use another blood herb..." + }, cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + if not player:removeItem(8111, 1) then + npcHandler:say('You have no cookie that I\'d like.', cid) + npcHandler.topic[cid] = 0 + return true + end + + player:setStorageValue(Storage.WhatAFoolish.CookieDelivery.Wyda, 1) + player:addCondition(condition) + if player:getCookiesDelivered() == 10 then + player:addAchievement('Allow Cookies?') + end + + Npc():getPosition():sendMagicEffect(CONST_ME_GIFT_WRAPS) + npcHandler:say('Well, it\'s a welcome change from all that gingerbread ... AHHH HOW DARE YOU??? FEEL MY WRATH!', cid) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + elseif npcHandler.topic[cid] == 2 then + if player:removeItem(2798, 1) then + player:setStorageValue(Storage.BloodHerbQuest, 2) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + local TornTeddyRand = math.random(1, 100) + if TornTeddyRand <= 70 then + player:addItem(2324, 1) -- witchesbroom + npcHandler:say('Thank you -SOOO- much! No, I really mean it! Really! Here, let me give you a reward...', cid) + npcHandler.topic[cid] = 0 + else + player:addItem(13774, 1) -- torn teddy + npcHandler:say('Thank you -SOOO- much! No, I really mean it! Really! Ah, you know what, you can have this old thing...', cid) + npcHandler.topic[cid] = 0 + end + else + npcHandler:say('No, you don\'t have any...', cid) + npcHandler.topic[cid] = 0 + end + end + elseif msgcontains(msg, 'no') then + if npcHandler.topic[cid] == 1 or npcHandler.topic[cid] == 2 then + npcHandler:say('I see.', cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/wyrdin.lua b/data/npc/scripts/wyrdin.lua new file mode 100644 index 00000000000..aa145f84212 --- /dev/null +++ b/data/npc/scripts/wyrdin.lua @@ -0,0 +1,78 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = " So where was I again?" }, + { text = " Typical - you can never find a hero when you need one!" }, + { text = " Could the bonelord language be the invention of some madman?" }, + { text = " The curse algorithm of triplex shadowing has to be two times higher than an overcharged nanoquorx on the peripheral..." } +} + +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.TheWayToYalahar.QuestLine) < 1 and player:getStorageValue(Storage.ExplorerSociety.JoiningTheExplorers) >= 4 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) >= 4 then + npcHandler:say({ + "There is indeed something that needs our attention. In the far north, a new city named Yalahar was discovered. It seems to be incredibly huge. ...", + "According to travelers, it's a city of glory and wonders. We need to learn as much as we can about this city and its inhabitants. ...", + "Gladly the explorer's society already sent a representative there. Still, we need someone to bring us the information he was able to gather until now. ...", + "Please look for the explorer's society's captain Maximilian in Liberty Bay. Ask him for a passage to Yalahar. There visit Timothy of the explorer's society and get his research notes. ...", + "It might be a good idea to explore the city a bit on your own before you deliver the notes here, but please make sure you don't lose them." + }, cid) + player:setStorageValue(Storage.TheWayToYalahar.QuestLine, 1) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.TheWayToYalahar.QuestLine) == 2 then + npcHandler:say("Did you bring the papers I asked you for?", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + if player:removeItem(10090, 1) then + player:setStorageValue(Storage.TheWayToYalahar.QuestLine, 3) + npcHandler:say("Oh marvellous, please excuse me. I need to read this text immediately. Here, take this small reward of 500 gold pieces for your efforts.", cid) + player:addMoney(500) + npcHandler.topic[cid] = 0 + end + end + --The New Frontier + elseif msgcontains(msg, "farmine") then + if player:getStorageValue(Storage.TheNewFrontier.Questline) == 15 then + npcHandler:say("I've heard some odd rumours about this new dwarven outpost. But tell me, what has the Edron academy to do with Farmine?", cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, "plea") then + if npcHandler.topic[cid] == 2 then + if player:getStorageValue(Storage.TheNewFrontier.BribeWydrin) < 1 then + npcHandler:say("Hm, you are right, we are at the forefront of knowledge and innovation. Our dwarven friends could learn much from one of our representatives.", cid) + player:setStorageValue(Storage.TheNewFrontier.BribeWydrin, 1) + player:setStorageValue(Storage.TheNewFrontier.Mission05, player:getStorageValue(Storage.TheNewFrontier.Mission05) + 1) --Questlog, The New Frontier Quest "Mission 05: Getting Things Busy" + end + end + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Hello, what brings you here?") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/xed.lua b/data/npc/scripts/xed.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/xed.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/xelvar.lua b/data/npc/scripts/xelvar.lua new file mode 100644 index 00000000000..1884b314c74 --- /dev/null +++ b/data/npc/scripts/xelvar.lua @@ -0,0 +1,95 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if not player then + return false + end + + if msgcontains(msg, "adventures") or msgcontains(msg, "join") then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) < 1 then + npcHandler:say({ + "I am glad to hear that. In the spirit of our own foreign legion we suggested the gnomes might hire heroes like you to build some kind of troop. They gave me that strange crystal to allow people passage to their realm. ...", + "I hereby grant you permission to use the basic gnomish teleporters. I also give you four gnomish teleport crystals. One will be used up each time you use the teleporter. ...", + "You can stock up your supply by buying more from me. Just ask me for a {trade}. Gnomette in the teleport chamber of the gnome outpost will sell them too. ...", + "The teleporter here will transport you to one of the bigger gnomish outposts. ...", + "There you will meet Gnomerik, the recruitment officer of the Gnomes. If you are lost, Gnomette in the teleport chamber might be able to help you with directions. ...", + "Good luck to you and don't embarrass your race down there! Keep in mind that you are a representative of the big people." + }, cid) + + player:setStorageValue(Storage.BigfootBurden.QuestLine, 1) + player:addItem(18457, 4) + + --npcHandler:say("Right now I am sort of {recruiting} people.", cid) + npcHandler.topic[cid] = 1 + else npcHandler:say("You already talked with me.", cid) + end + elseif msgcontains(msg, "recruiting") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Ok, so listen. Your help is needed. That is if you're the hero type. Our ... {partners} need some help in urgent matters.", cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, "partners") then + if npcHandler.topic[cid] == 2 then + npcHandler:say("I guess the time of secrecy is over now. Well, we have an old alliance with another underground dwelling race, the {gnomes}.", cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, "gnomes") then + if npcHandler.topic[cid] == 3 then + npcHandler:say({ + "The gnomes preferred to keep our alliance and their whole {existence} a secret. They are a bit distrustful of others. ...", + "They are quite self-sufficient and the fact that they are actually accepting some help is more than alarming. The gnomes are in real trouble and I am kind of an ambassador to find some people willing to {help}." + }, cid) + npcHandler.topic[cid] = 4 + end + elseif msgcontains(msg, "help") then + if npcHandler.topic[cid] == 4 then + npcHandler:say({ + "The gnomes are locked in a war with an enemy that thins out their resources but foremost their manpower. We have suggested that people like you could be just the specialists they are looking for. ...", + "If you are interested to {join} the gnomish cause I can arrange a meeting with their recruiter." + }, cid) + npcHandler.topic[cid] = 5 + end + elseif msgcontains(msg, "join") then + if npcHandler.topic[cid] == 5 then + npcHandler:say({ + "I am glad to hear that. In the spirit of our own foreign legion we suggested the gnomes might hire heroes like you to build some kind of troop. They gave me that strange crystal to allow people passage to their realm. ...", + "I hereby grant you permission to use the basic gnomish teleporters. I also give you four gnomish teleport crystals. One will be used up each time you use the teleporter. ...", + "You can stock up your supply by buying more from me. Just ask me for a {trade}. Gnomette in the teleport chamber of the gnome outpost will sell them too. ...", + "The teleporter here will transport you to one of the bigger gnomish outposts. ...", + "There you will meet Gnomerik, the recruitment officer of the Gnomes. If you are lost, Gnomette in the teleport chamber might be able to help you with directions. ...", + "Good luck to you and don't embarrass your race down there! Keep in mind that you are a representative of the big people." + }, cid) + + player:setStorageValue(Storage.BigfootBurden.QuestLine, 1) + player:addItem(18457, 4) + npcHandler.topic[cid] = 0 + end + + end + + + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/xodet.lua b/data/npc/scripts/xodet.lua new file mode 100644 index 00000000000..527e84a4e49 --- /dev/null +++ b/data/npc/scripts/xodet.lua @@ -0,0 +1,57 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local items = { + [VOCATION.CLIENT_ID.SORCERER] = 2190, + [VOCATION.CLIENT_ID.DRUID] = 2182 +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'first rod') or msgcontains(msg, 'first wand') then + if player:isMage() then + local itemId = items[player:getVocation():getClientId()] + if player:getStorageValue(Storage.firstMageWeapon) == -1 then + npcHandler:say('So you ask me for a {' .. ItemType(itemId):getName() .. '} to begin your adventure?', cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say('What? I have already gave you one {' .. ItemType(itemId):getName() .. '}!', cid) + end + else + npcHandler:say('Sorry, you aren\'t a druid either a sorcerer.', cid) + end + elseif msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 1 then + player:addItem(itemId, 1) + npcHandler:say('Here you are young adept, take care yourself.', cid) + player:setStorageValue(Storage.firstMageWeapon, 1) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') and npcHandler.topic[cid] == 1 then + npcHandler:say('Ok then.', cid) + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/xorlosh.lua b/data/npc/scripts/xorlosh.lua new file mode 100644 index 00000000000..ac1a17b8367 --- /dev/null +++ b/data/npc/scripts/xorlosh.lua @@ -0,0 +1,55 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.HiddenCityOfBeregar.GoingDown) < 1 then + npcHandler:say("Hmmmm, you could indeed help me. See this mechanism? Some son of a rotworm put WAY too much stuff on this elevator and now it's broken. I need 3 gear wheels to fix it. You think you could get them for me?", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.HiddenCityOfBeregar.GoingDown) == 1 and player:removeItem(9690, 3) then + player:setStorageValue(Storage.HiddenCityOfBeregar.GoingDown, 2) + npcHandler:say("HOLY MOTHER OF ALL ROTWORMS! You did it and they are of even better quality than the old ones. You should be the first one to try the elevator, just jump on it. See you my friend.", cid) + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + player:setStorageValue(Storage.HiddenCityOfBeregar.GoingDown, 1) + player:setStorageValue(Storage.HiddenCityOfBeregar.DefaultStart, 1) + npcHandler:say("That would be great! Maybe a blacksmith can forge you some. Come back when you got them and ask me about your mission.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "tunnel") then + if player:getStorageValue(Storage.HiddenCityOfBeregar.RoyalRescue) == 1 then + npcHandler:say({ + "There should be a book in our library about tunnelling. I don't have that much time to talk to you about that. ...", + "The book about tunnelling is in the library which is located in the north eastern wing of Beregar city." + }, cid) + end + end + return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, "See you my friend.") +npcHandler:setMessage(MESSAGE_FAREWELL, "See you my friend.") +npcHandler:setMessage(MESSAGE_GREET, "Who are you? Are you a genius in mechanics? You don't look like one.") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/yalahari.lua b/data/npc/scripts/yalahari.lua new file mode 100644 index 00000000000..8b9c22dfe60 --- /dev/null +++ b/data/npc/scripts/yalahari.lua @@ -0,0 +1,245 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.InServiceofYalahar.Questline) == 17 then + npcHandler:say({ + "With all the coming and going of strangers here, it would be quite tedious to explain everything again and again. So we have written a manifesto. ...", + "Grab a copy from the room behind me. Let's talk about your further career in our ranks once you've read it." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 18) + player:setStorageValue(Storage.InServiceofYalahar.Mission03, 3) -- StorageValue for Questlog "Mission 03: Death to the Deathbringer" + player:setStorageValue(Storage.InServiceofYalahar.NotesAzerus, 0) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.NotesAzerus) == 1 and player:getStorageValue(Storage.InServiceofYalahar.Questline) == 18 then + npcHandler:say({ + "I'm mildly impressed by your previous deeds in our service. So I'm willing to grant you some more important {missions}. ...", + "If you please us, a life of luxury as an important person in our city is ensured. If you fail, you will be replaced by someone more capable than you. ...", + "So if you are up for a challenge, ask me for a {mission}." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 19) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 19 then + npcHandler:say({ + "The former alchemist quarter was struck by even more disasters than the rest of the city. Fires, explosions, poisonous fumes - all sorts of catastrophes. ...", + "The worst plague, however, are unknown diseases that have spread in this quarter and eradicated any human population. We must stop it before other quarters areafflicted. We already identified certain carriers responsible for spreading the plague. ...", + "It will be your task to eliminate them. This spell will protect you from becoming infected yourself. Enter the alchemist quarter and kill the three plague carriers, and atbest anything else you might find there. ...", + "Even more important, retrieve the last research notes that the local alchemists made before the plague killed them. They might be the key for a cure or something else. ...", + "At least we have to make sure that these scientists did not die in vain, and honour their researches. So please bring us these research notes. ...", + "Also, I will inform the guards that you are allowed to pass the centre gate to the alchemist quarter. Just use the gate mechanism to pass." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 20) + player:setStorageValue(Storage.InServiceofYalahar.Mission03, 4) -- StorageValue for Questlog "Mission 03: Death to the Deathbringer" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 21 and player:getStorageValue(Storage.InServiceofYalahar.AlchemistFormula) == 1 then + npcHandler:say("So you have killed the plague carriers. Have you also retrieved the research papers? ", cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 22 then + npcHandler:say({ + "We surely cannot allow some underworld kingpin to rule a significant part of the city. Although, I have to admit that his firm grip on the former trade quarter might be useful....", + "I expect you to fight your way through his minions and to show him that we are determined and powerful enough to retake the quarter, if necessary by force. Talk to himafter killing some of his henchmen. ...", + "I'm sure he'll understand that he will succumb to a greater power. That's how his little empire has worked after all. ...", + "Also, I will inform the guards that you are allowed to pass the centre gate to the trade quarter now. Just use the gate mechanism to pass." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 23) + player:setStorageValue(Storage.InServiceofYalahar.Mission04, 1) -- StorageValue for Questlog "Mission 04: Good to be Kingpin" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 26 then + npcHandler:say({ + "So he has been too uncooperative for you? Well, you weren't the first we have sent and you won't be the last. ...", + "However, if you cannot even serve us as a bully, we might have to rethink if you are the right person for us. That was a bad job and we don't tolerate many of them." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 27) + player:setStorageValue(Storage.InServiceofYalahar.Mission04, 6) -- StorageValue for Questlog "Mission 04: Good to be Kingpin" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 25 and player:getStorageValue(Storage.InServiceofYalahar.MrWestStatus) == 2 then + npcHandler:say({ + "I hope you gave this criminal a real scare! I'm sure he'll remember what he has to expect if he arouses our anger again. ...", + "You have proven yourself as quite valuable with this mission! That was just the first step on your rise through the ranks of our helpers. ...", + "Just ask me for more missions and we will see what you are capable of!" + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.BadSide, player:getStorageValue(Storage.InServiceofYalahar.BadSide) >= 0 and player:getStorageValue(Storage.InServiceofYalahar.BadSide) + 1 or 0) -- Side Storage + player:setStorageValue(Storage.InServiceofYalahar.Questline, 27) + player:setStorageValue(Storage.InServiceofYalahar.Mission04, 6) -- StorageValue for Questlog "Mission 04: Good to be Kingpin" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 27 then + npcHandler:say({ + "As you probably noticed, once our city had a park and a zoo around a grand arena. It was a favourite pastime of our citizens to visit this quarter in their spare time. ...", + "Nowadays, the quarter is lost. The animals are on the loose, and an attempt to revitalise the city with new arena games resulted in a revolt of the foreign gladiators. ...", + "Now all kinds of beasts roam the park, and gladiators challenge them and visitors to test their skills. One of the residents is an ancient druid that rather cares foranimals than for people. ...", + "It is said that he is able to use magic to breed animals with changed abilities and appearances. Such skills are of course quite useful for us. ...", + "We lack the manpower to retake all quarters, or just to defend ourselves adequately. If he bred us some guards and warbeasts, we could strengthen our positionconsiderably. ...", + "Travel to the arena quarter and gain his assistance for us. I will inform the guards that you are allowed to pass the centre gate to the arena quarter now. Just use thegate mechanism to pass." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 28) + player:setStorageValue(Storage.InServiceofYalahar.Mission05, 1) -- StorageValue for Questlog "Mission 05: Food or Fight" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 33 then + npcHandler:say({ + "This druid dares to affront us? We will look into this when we have enough time. But there are other things that needs to be settled. ...", + "Although, we probably should not do so after your last failure, we are willing to grant you another mission." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 34) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 32 and player:getStorageValue(Storage.InServiceofYalahar.TamerinStatus) == 2 then + npcHandler:say({ + "So have you won us a new ally? Excellent. I knew you would not dare to ruin this mission. Soon we might be able to strengthen our defences and even relocate some of our guards. ...", + "Perhaps some day soon, you lead your own unit of men. However, there are more missions that need to be accomplished. Let's talk about them." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.BadSide, player:getStorageValue(Storage.InServiceofYalahar.BadSide) >= 0 and player:getStorageValue(Storage.InServiceofYalahar.BadSide) + 1 or 0) -- Side Storage + player:setStorageValue(Storage.InServiceofYalahar.Questline, 34) + player:setStorageValue(Storage.InServiceofYalahar.Mission05, 8) -- StorageValue for Questlog "Mission 05: Food or Fight" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 34 then + npcHandler:say({ + "The old cemetery of the city has been abandoned decades ago when the activity of the various undead there became unbearable. The reason for their appearance was never found out or researched. ...", + "However, those undead could be useful, at least some of them. Particular ghosts consist of a substance that is very similar to the energy source that powered some of our devices. ...", + "Since we lack most of the original sources, some substitute might come in handy. Take this ghost charm and place it on the strange carving in the cemetery. ...", + "Use it to attract ghosts and slay them. Then use the residues of the ghosts on the charm to capture the essence. ...", + "Once it is filled, ghosts will not be attracted any longer. Then return the charm to me. I will inform the guards that you are allowed to pass the centre gate to the cemetery quarter now. Just use the gate mechanism to pass." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 35) + player:setStorageValue(Storage.InServiceofYalahar.Mission06, 1) -- StorageValue for Questlog "Mission 06: Frightening Fuel" + player:addItem(9737, 1) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 38 then + npcHandler:say({ + "Destroyed you say? That's impossible! I'm not sure if I can trust you in this matter? One might assume, you fled from the ghosts in terror and left the charm there. ...", + "You will have to work twice as hard on your next missions to restore the trust you have lost." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 39) + player:setStorageValue(Storage.InServiceofYalahar.Mission06, 5) -- StorageValue for Questlog "Mission 06: Frightening Fuel" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 37 then + if player:removeItem(9742, 1) then + npcHandler:say({ + "Ah, what an unexpected sight. I can almost feel the energy of the charm. It will help to recover some of the past wealth. ...", + "You did quite an impressive job. I'm considering to introduce you to my ma.. to my direct superior one day. But there are still other missions to fulfil." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 39) + player:setStorageValue(Storage.InServiceofYalahar.Mission06, 5) -- StorageValue for Questlog "Mission 06: Frightening Fuel" + player:setStorageValue(Storage.InServiceofYalahar.QuaraState, 2) + player:setStorageValue(Storage.InServiceofYalahar.BadSide, player:getStorageValue(Storage.InServiceofYalahar.BadSide) >= 0 and player:getStorageValue(Storage.InServiceofYalahar.BadSide) + 1 or 0) -- Side Storage + npcHandler.topic[cid] = 0 + end + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 39 then + npcHandler:say({ + "Recently, our fishermen have been attacked by a maritime race called the quara. They live in the sunken quarter and are a significant threat to our people. I ask you to enter the sunken quarter and slay all their leaders. ...", + "We believe that there are three leaders in this area. Your task is simple enough, so you better don't fail! ...", + "I will inform the guards that you are allowed to pass the centre gate to the sunken quarter now. Just use the gate mechanism to pass." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 40) + player:setStorageValue(Storage.InServiceofYalahar.Mission07, 1) -- StorageValue for Questlog "Mission 07: A Fishy Mission" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 41 and player:getStorageValue(Storage.InServiceofYalahar.QuaraInky) == 1 and player:getStorageValue(Storage.InServiceofYalahar.QuaraSharptooth) == 1 and player:getStorageValue(Storage.InServiceofYalahar.QuaraSplasher) == 1 and player:getStorageValue(Storage.InServiceofYalahar.QuaraState) == 2 then + npcHandler:say("This will teach these fishmen who is the ruler of that area. You have earned yourself a special privilege. But we will talk about that when we speak about your next mission. ", cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 43) + player:setStorageValue(Storage.InServiceofYalahar.Mission07, 5) -- StorageValue for Questlog "Mission 07: A Fishy Mission" + player:setStorageValue(Storage.InServiceofYalahar.BadSide, player:getStorageValue(Storage.InServiceofYalahar.BadSide) >= 0 and player:getStorageValue(Storage.InServiceofYalahar.BadSide) + 1 or 0) -- Side Storage + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 43 then + npcHandler:say({ + "In the past, we had many magical factories providing the citizens with everything they needed. Now that most of these factories are shut down, we have trouble getting enough supplies. ...", + "We need you to enter one of the lesser damaged factories. Go to the factory district and look for a pattern crystal used for weapon production. Use it on the factory controller. ...", + "It will ensure that the factory will provide us with a suitable amount of weapons which we dearly need to reclaim and secure the most dangerous parts of the city. ...", + "I will inform the guards that you are allowed to pass the centre gate to the factory quarter now. Just use the gate mechanism to pass." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 44) + player:setStorageValue(Storage.InServiceofYalahar.Mission08, 1) -- StorageValue for Questlog "Mission 08: Dangerous Machinations" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 46 then + if player:getStorageValue(Storage.InServiceofYalahar.MatrixState) == 1 then + npcHandler:say("Your failure is an outrage! I think we have to talk about the missions you have accomplished so far. ", cid) + player:setStorageValue(Storage.InServiceofYalahar.GoodSide, player:getStorageValue(Storage.InServiceofYalahar.GoodSide) >= 0 and player:getStorageValue(Storage.InServiceofYalahar.GoodSide) + 1 or 0) -- Side Storage + elseif player:getStorageValue(Storage.InServiceofYalahar.MatrixState) == 2 then + npcHandler:say("Now we will have power we truly deserve!...", cid) + player:setStorageValue(Storage.InServiceofYalahar.BadSide, player:getStorageValue(Storage.InServiceofYalahar.BadSide) >= 0 and player:getStorageValue(Storage.InServiceofYalahar.BadSide) + 1 or 0) -- Side Storage + end + player:setStorageValue(Storage.InServiceofYalahar.Questline, 47) + player:setStorageValue(Storage.InServiceofYalahar.Mission08, 4) -- StorageValue for Questlog "Mission 08: Dangerous Machinations" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 47 then + npcHandler:say({ + "I'm impressed by your support for our cause. Still, I'm aware that this scheming Palimuth tried to influence you. Think about who are your real friends and who can assist you in your career. ...", + "Come back if you have decided to which side you want to belong." + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 48) + player:setStorageValue(Storage.InServiceofYalahar.Mission09, 1) -- StorageValue for Questlog "Mission 09: Decision" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 49 or player:getStorageValue(Storage.InServiceofYalahar.Questline) == 48 then + npcHandler:say("So do you want to side with me |PLAYERNAME|? ", cid) + npcHandler.topic[cid] = 2 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 50 and player:getStorageValue(Storage.InServiceofYalahar.SideDecision) == 2 then + npcHandler:say({ + "For your noble deeds, we would like to invite you to a special celebration ceremony. ...", + "Only the most prominent Yalahari are allowed to join the festivities. I assume you can imagine what honour it is that you'vebeen invited to join us. Meet us in the inner city's centre. ...", + "As our most trusted ally, you may pass all doors to reach the festivity hall. There you will receive your reward for the achievements you have gained so far. ...", + "I'm convinced your reward will be beyond your wildest dreams. And that is just the beginning!" + }, cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 51) + player:setStorageValue(Storage.InServiceofYalahar.DoorToLastFight, 1) + player:setStorageValue(Storage.InServiceofYalahar.Mission10, 2) -- StorageValue for Questlog "Mission 10: The Final Battle" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.InServiceofYalahar.Questline) == 52 and player:getStorageValue(Storage.InServiceofYalahar.SideDecision) == 2 then + npcHandler:say("Great work, take this outfit and you are able to open the door to the reward room.", cid) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 53) + player:setStorageValue(Storage.InServiceofYalahar.DoorToReward, 1) + player:setStorageValue(Storage.InServiceofYalahar.Mission10, 4) -- StorageValue for Questlog "Mission 10: The Final Battle" + player:addOutfit(324, 0) + player:addOutfit(325, 0) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + if player:removeItem(9733, 1) then + player:setStorageValue(Storage.InServiceofYalahar.BadSide, 1) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 22) + player:setStorageValue(Storage.InServiceofYalahar.Mission03, 6) -- StorageValue for Questlog "Mission 03: Death to the Deathbringer" + npcHandler:say("Impressive indeed! Someone with your skills will quickly raise in our ranks of helpers. You have great potential, and if you are upfor further missions, just ask for them. ", cid) + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 2 then + player:setStorageValue(Storage.InServiceofYalahar.Questline, 50) + player:setStorageValue(Storage.InServiceofYalahar.SideDecision, 2) + player:setStorageValue(Storage.InServiceofYalahar.Mission09, 2) -- StorageValue for Questlog "Mission 09: Decision" + npcHandler:say("I knew that you were smart enough to make the right decision! Your next mission will be a special one! ", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] == 1 then + player:setStorageValue(Storage.InServiceofYalahar.GoodSide, 1) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 22) + player:setStorageValue(Storage.InServiceofYalahar.Mission03, 6) -- StorageValue for Questlog "Mission 03: Death to the Deathbringer" + npcHandler:say({ + "Hm, no sign of any notes you say? That's odd - odd and a bit suspicious. I doubt you have tried hard enough. ...", + "There are only a few chances to impress us. For those who please us great rewards are in store. If you fail though, you might lose more than you can imagine." + }, cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/yaman.lua b/data/npc/scripts/yaman.lua new file mode 100644 index 00000000000..3f581798267 --- /dev/null +++ b/data/npc/scripts/yaman.lua @@ -0,0 +1,106 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if isInArray({"enchanted chicken wing", "boots of haste", "Enchanted Chicken Wing", "Boots of Haste"}, msg) then + npcHandler:say('Do you want to trade Boots of haste for Enchanted Chicken Wing?', cid) + npcHandler.topic[cid] = 1 + elseif isInArray({"warrior sweat", "warrior helmet", "Warrior Sweat", "Warrior Helmet"}, msg) then + npcHandler:say('Do you want to trade 4 Warrior Helmet for Warrior Sweat?', cid) + npcHandler.topic[cid] = 2 + elseif isInArray({"fighting spirit", "royal helmet", "Fighting Spirit", "Royal Helmet"}, msg) then + npcHandler:say('Do you want to trade 2 Royal Helmet for Fighting Spirit', cid) + npcHandler.topic[cid] = 3 + elseif isInArray({"magic sulphur", "fire sword", "Magic Sulphur", "Fire Sword"}, msg) then + npcHandler:say('Do you want to trade 3 Fire Sword for Magic Sulphur', cid) + npcHandler.topic[cid] = 4 + elseif isInArray({"job", "items", "Items", "Job"}, msg) then + npcHandler:say('I trade Enchanted Chicken Wing for Boots of Haste, Warrior Sweat for 4 Warrior Helmets, Fighting Spirit for 2 Royal Helmet Magic Sulphur for 3 Fire Swords', cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'cookie') then + if player:getStorageValue(Storage.WhatAFoolish.Questline) == 31 + and player:getStorageValue(Storage.WhatAFoolish.CookieDelivery.Djinn) ~= 1 then + npcHandler:say('You brought cookies! How nice of you! Can I have one?', cid) + npcHandler.topic[cid] = 5 + end + elseif msgcontains(msg,'yes') then + if npcHandler.topic[cid] >= 1 and npcHandler.topic[cid] <= 4 then + local trade = { + { NeedItem = 2195, Ncount = 1, GiveItem = 5891, Gcount = 1}, -- Enchanted Chicken Wing + { NeedItem = 2475, Ncount = 4, GiveItem = 5885, Gcount = 1}, -- Flask of Warrior's Sweat + { NeedItem = 2498, Ncount = 2, GiveItem = 5884, Gcount = 1}, -- Spirit Container + { NeedItem = 2392, Ncount = 3, GiveItem = 5904, Gcount = 1} -- Magic Sulphur + } + if player:getItemCount(trade[npcHandler.topic[cid]].NeedItem) >= trade[npcHandler.topic[cid]].Ncount then + player:removeItem(trade[npcHandler.topic[cid]].NeedItem, trade[npcHandler.topic[cid]].Ncount) + player:addItem(trade[npcHandler.topic[cid]].GiveItem, trade[npcHandler.topic[cid]].Gcount) + return npcHandler:say('Here you are.', cid) + else + npcHandler:say('Sorry but you don\'t have the item.', cid) + end + elseif npcHandler.topic[cid] == 5 then + if not player:removeItem(8111, 1) then + npcHandler:say('You have no cookie that I\'d like.', cid) + npcHandler.topic[cid] = 0 + return true + end + + player:setStorageValue(Storage.WhatAFoolish.CookieDelivery.Djinn, 1) + if player:getCookiesDelivered() == 10 then + player:addAchievement('Allow Cookies?') + end + + Npc():getPosition():sendMagicEffect(CONST_ME_GIFT_WRAPS) + npcHandler:say('You see, good deeds like this will ... YOU ... YOU SPAWN OF EVIL! I WILL MAKE SURE THE MASTER LEARNS ABOUT THIS!', cid) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + elseif msgcontains(msg,'no') then + if npcHandler.topic[cid] >= 1 and npcHandler.topic[cid] <= 4 then + npcHandler:say('Ok then.', cid) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 5 then + npcHandler:say('I see.', cid) + npcHandler.topic[cid] = 0 + end + end + return true +end + +local function onTradeRequest(cid) + local player = Player(cid) + if player:getStorageValue(Storage.DjinnWar.EfreetFaction.Mission03) ~= 3 then + npcHandler:say('I\'m sorry, but you don\'t have Malor\'s permission to trade with me.', cid) + return false + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, "Be greeted, human |PLAYERNAME|. How can a humble djinn be of service?") +npcHandler:setMessage(MESSAGE_FAREWELL, "Farewell, human.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Farewell, human.") +npcHandler:setMessage(MESSAGE_SENDTRADE, 'At your service, just browse through my wares.') + +npcHandler:setCallback(CALLBACK_ONTRADEREQUEST, onTradeRequest) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/yana.lua b/data/npc/scripts/yana.lua new file mode 100644 index 00000000000..7cde9d527b0 --- /dev/null +++ b/data/npc/scripts/yana.lua @@ -0,0 +1,234 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +local shop = { + {id=30686, buy=50, sell=0, name='axe of desctruction'}, + {id=30684, buy=50, sell=0, name='blade of desctruction'}, + {id=30690, buy=50, sell=0, name='bow of desctruction'}, + {id=30687, buy=50, sell=0, name='chopper of desctruction'}, + {id=30691, buy=50, sell=0, name='crossbow of desctruction'}, + {id=30689, buy=50, sell=0, name='hammer of desctruction'}, + {id=30688, buy=50, sell=0, name='mace of desctruction'}, + {id=30693, buy=50, sell=0, name='rod of desctruction'}, + {id=30685, buy=50, sell=0, name='slayer of desctruction'}, + {id=30692, buy=50, sell=0, name='wand of desctruction'}, +} + +local function setNewTradeTable(table) + local items, item = {} + for i = 1, #table do + item = table[i] + items[item.id] = {id = item.id, buy = item.buy, sell = item.sell, subType = 0, name = item.name} + end + return items +end + +local function onBuy(cid, item, subType, amount, ignoreCap, inBackpacks) + local player = Player(cid) + local itemsTable = setNewTradeTable(shop) + if not ignoreCap and player:getFreeCapacity() < ItemType(itemsTable[item].id):getWeight(amount) then + return player:sendTextMessage(MESSAGE_FAILURE, "You don't have enough cap.") + end + if itemsTable[item].buy then + if player:removeItem(Npc():getCurrency(), amount * itemsTable[item].buy) then + if amount > 1 then + currencyName = ItemType(Npc():getCurrency()):getPluralName():lower() + else + currencyName = ItemType(Npc():getCurrency()):getName():lower() + end + player:addItem(itemsTable[item].id, amount) + return player:sendTextMessage(MESSAGE_TRADE, + "Bought "..amount.."x "..itemsTable[item].name.." for "..itemsTable[item].buy * amount.." "..currencyName..".") + else + return player:sendTextMessage(MESSAGE_TRADE, "You don't have enough "..currencyName..".") + end + end + + return true +end + +local function onSell(cid, item, subType, amount, ignoreCap, inBackpacks) + return true +end + +local products = { + ['strike'] = { + ['basic'] = { + text = "The basic bundle for the strike imbuement consists of 20 protective charms. Would you like to buy it for 2 ".. ItemType(Npc():getCurrency()):getPluralName():lower() .."?", + itens = { + [1] = {id = 12400, amount = 20} + }, + value = 2 + }, + ['intricate'] = { + text = "The intricate bundle for the strike imbuement consists of 20 protective charms and 25 sabreteeth. Would you like to buy it for 4 ".. ItemType(Npc():getCurrency()):getPluralName():lower() .."?", + itens = { + [1] = {id = 12400, amount = 20}, + [2] = {id = 11228, amount = 25} + }, + value = 4 + }, + ['powerful'] = { + text = "The powerful bundle for the strike imbuement consists of 20 protective charms, 25 sabreteeth and 5 vexclaw talons. Would you like to buy it for 6 ".. ItemType(Npc():getCurrency()):getPluralName():lower() .."?", + itens = { + [1] = {id = 12400, amount = 20}, + [2] = {id = 11228, amount = 25}, + [3] = {id = 25384, amount = 5} + }, + value = 6 + } + }, + ['vampirism'] = { + ['basic'] = { + text = "The basic bundle for the vampirism imbuement consists of 25 vampire teeth. Would you like to buy it for 2 ".. ItemType(Npc():getCurrency()):getPluralName():lower() .."?", + itens = { + [1] = {id = 10602, amount = 25} + }, + value = 2 + }, + ['intricate'] = { + text = "The intricate bundle for the strike imbuement consists of 20 protective charms and 25 sabreteeth. Would you like to buy it for 4 ".. ItemType(Npc():getCurrency()):getPluralName():lower() .."?", + itens = { + [1] = {id = 10602, amount = 25}, + [2] = {id = 10550, amount = 15} + }, + value = 4 + }, + ['powerful'] = { + text = "The powerful bundle for the vampirism imbuement consists of 25 vampire teeth, 15 bloody pincers and 5 pieces of dead brain. Would you like to it for 6 ".. ItemType(Npc():getCurrency()):getPluralName():lower() .."?", + itens = { + [1] = {id = 10602, amount = 25}, + [2] = {id = 10550, amount = 15}, + [3] = {id = 10580, amount = 5} + }, + value = 6 + } + }, + ['void'] = { + ['basic'] = { + text = "The basic bundle for the void imbuement consists of 25 rope belts. Would you like to buy it for 2 ".. ItemType(Npc():getCurrency()):getPluralName():lower() .."?", + itens = { + [1] = {id = 12448, amount = 25} + }, + value = 2, + }, + ['intricate'] = { + text = "The intricate bundle for the void imbuement consists of 25 rope belts and 25 silencer claws. Would you like to buy it for 4 ".. ItemType(Npc():getCurrency()):getPluralName():lower() .."?.", + itens = { + [1] = {id = 12448, amount = 25}, + [2] = {id = 22534, amount = 25} + }, + value = 4, + }, + ['powerful'] = { + text = "The powerful bundle for the void imbuement consists of 25 rope belts, 25 silencer claws and 5 grimeleech wings. Would you like to buy it for 6 ".. ItemType(Npc():getCurrency()):getPluralName():lower() .."?", + itens = { + [1] = {id = 12448, amount = 25}, + [2] = {id = 22534, amount = 25}, + [3] = {id = 25386, amount = 5} + }, + value = 6, + } + }, +} + +local answerType = {} +local answerLevel = {} + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function greetCallback(cid) + npcHandler.topic[cid] = 0 + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + if msgcontains(msg, "information") then + npcHandler:say({"{Tokens} are small objects made of metal or other materials. You can use them to buy superior equipment from token traders like me.", + "There are several ways to obtain the tokens I'm interested in - killing certain bosses, for example. In exchange for a certain amount of tokens, I can offer you some first-class items."}, cid) + elseif msgcontains(msg, "worth") then + -- to do: check if Heart of Destruction was killed + -- after kill msg: 'You disrupted the Heart of Destruction, defeated the World Devourer and bought our world some time. You have proven your worth.' + npcHandler:say({"Disrupt the Heart of Destruction, fell the World Devourer to prove your worth and you will be granted the power to imbue 'Powerful Strike', 'Powerful Void' and --'Powerful Vampirism'."}, cid) + elseif msgcontains(msg, "tokens") then + openShopWindow(cid, shop, onBuy, onSell) + npcHandler:say("If you have any gold tokens with you, let's have a look! These are my offers.", cid) + elseif msgcontains(msg, "trade") then + npcHandler:say({"I have creature products for the imbuements {strike}, {vampirism} and {void}. Make your choice, please!"}, cid) + npcHandler.topic[cid] = 1 + elseif npcHandler.topic[cid] == 1 then + local imbueType = products[msg:lower()] + if imbueType then + npcHandler:say({"You have chosen "..msg..". {Basic}, {intricate} or {powerful}?"}, cid) + answerType[cid] = msg + npcHandler.topic[cid] = 2 + end + elseif npcHandler.topic[cid] == 2 then + local imbueLevel = products[answerType[cid]][msg:lower()] + if imbueLevel then + answerLevel[cid] = msg:lower() + local neededCap = 0 + for i = 1, #products[answerType[cid]][answerLevel[cid]].itens do + neededCap = neededCap + ItemType(products[answerType[cid]][answerLevel[cid]].itens[i].id):getWeight() * products[answerType[cid]][answerLevel[cid]].itens[i].amount + end + npcHandler:say({imbueLevel.text.."...", + "Make sure that you have ".. #products[answerType[cid]][answerLevel[cid]].itens .." free slot and that you can carry ".. string.format("%.2f",neededCap/100) .." oz in addition to that."}, cid) + npcHandler.topic[cid] = 3 + end + elseif npcHandler.topic[cid] == 3 then + if msgcontains(msg, "yes") then + local neededCap = 0 + for i = 1, #products[answerType[cid]][answerLevel[cid]].itens do + neededCap = neededCap + ItemType(products[answerType[cid]][answerLevel[cid]].itens[i].id):getWeight() * products[answerType[cid]][answerLevel[cid]].itens[i].amount + end + if player:getFreeCapacity() > neededCap then + if player:getItemCount(Npc():getCurrency()) >= products[answerType[cid]][answerLevel[cid]].value then + for i = 1, #products[answerType[cid]][answerLevel[cid]].itens do + player:addItem(products[answerType[cid]][answerLevel[cid]].itens[i].id, products[answerType[cid]][answerLevel[cid]].itens[i].amount) + end + player:removeItem(Npc():getCurrency(), products[answerType[cid]][answerLevel[cid]].value) + npcHandler:say("There it is.", cid) + npcHandler.topic[cid] = 0 + else + npcHandler:say("I'm sorry but it seems you don't have enough ".. ItemType(Npc():getCurrency()):getPluralName():lower() .." yet. Bring me "..products[answerType[cid]][answerLevel[cid]].value.." of them and we'll make a trade.", cid) + end + else + npcHandler:say("You don\'t have enough capacity. You must have "..neededCap.." oz.", cid) + end + elseif msgcontains(msg, "no") then + npcHandler:say("Your decision. Come back if you have changed your mind.",cid) + end + npcHandler.topic[cid] = 0 + end + return true +end + + + +local voices = { {text = 'Trading tokens! First-class equipment available!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/yanni.lua b/data/npc/scripts/yanni.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/yanni.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/yasir.lua b/data/npc/scripts/yasir.lua new file mode 100644 index 00000000000..9622751d034 --- /dev/null +++ b/data/npc/scripts/yasir.lua @@ -0,0 +1,35 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if(not npcHandler:isFocused(cid)) then + return false + end + + if msg:lower() == "name" then + return npcHandler:say("Me Yasir.", cid) + elseif msg:lower() == "job" then + return npcHandler:say("Tje hari ku ne finjala. {Ariki}?", cid) + elseif msg:lower() == "passage" then + return npcHandler:say("Soso yana. ", cid) + end + return true +end + +npcHandler:setMessage(MESSAGE_FAREWELL, "Si, jema ze harun. ") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/yawno.lua b/data/npc/scripts/yawno.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/yawno.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/yberius.lua b/data/npc/scripts/yberius.lua new file mode 100644 index 00000000000..02c8b071eed --- /dev/null +++ b/data/npc/scripts/yberius.lua @@ -0,0 +1,108 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Twist of Fate +local blessKeyword = keywordHandler:addKeyword({'twist of fate'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'This is a special blessing I can bestow upon you once you have obtained at least one of the other blessings and which functions a bit differently. ...', + 'It only works when you\'re killed by other adventurers, which means that at least half of the damage leading to your death was caused by others, not by monsters or the environment. ...', + 'The {twist of fate} will not reduce the death penalty like the other blessings, but instead prevent you from losing your other blessings as well as the amulet of loss, should you wear one. It costs the same as the other blessings. ...', + 'Would you like to receive that protection for a sacrifice of |PVPBLESSCOST| gold, child?' + }}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the protection of the twist of fate, pilgrim.', cost = '|PVPBLESSCOST|', bless = 1}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Adventurer Stone +keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Keep your adventurer\'s stone well.'}, function(player) return player:getItemById(18559, true) end) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for free?'}, function(player) return player:getStorageValue(Storage.AdventurersGuild.FreeStone.Yberius) ~= 1 end) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, nil, function(player) player:addItem(18559, 1) player:setStorageValue(Storage.AdventurersGuild.FreeStone.Yberius, 1) end) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for 30 gold?'}) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, + function(player) return player:getMoney() + player:getBankBalance() >= 30 end, + function(player) if player:removeMoneyNpc(30) then player:addItem(18559, 1) end end + ) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, you don\'t have enough money.', reset = true}) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +-- Wooden Stake +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'I think you have forgotten to bring your stake.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 4 and player:getItemCount(5941) == 0 end) + +local stakeKeyword = keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes, I was informed what to do. Are you prepared to receive my line of the prayer?'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 4 end) + stakeKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'So receive my prayer: \'Protection will be granted - from dangers at hand\'. Now, bring your stake to Isimov in the dwarven settlement for the next line of the prayer. I will inform him what to do.', reset = true}, nil, + function(player) player:setStorageValue(Storage.FriendsandTraders.TheBlessedStake, 5) player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) end + ) + stakeKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'I will wait for you.', reset = true}) + +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You should visit Isimov in the dwarven settlement now.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) == 5 end) +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'You already received my line of the prayer.'}, function(player) return player:getStorageValue(Storage.FriendsandTraders.TheBlessedStake) > 5 end) +keywordHandler:addKeyword({'stake'}, StdModule.say, {npcHandler = npcHandler, text = 'A blessed stake? That is a strange request. Maybe Quentin knows more, he is one of the oldest monks after all.'}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.'}, function(player) return player:hasBlessing(2) end) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin will provide you with the embrace of Tibia.'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, young |PLAYERNAME|! If you are heavily wounded or poisoned, I can {heal} you for free.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Remember: If you are heavily wounded or poisoned, I can heal you for free.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'May the gods bless you, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/yoem.lua b/data/npc/scripts/yoem.lua new file mode 100644 index 00000000000..525ed120f01 --- /dev/null +++ b/data/npc/scripts/yoem.lua @@ -0,0 +1,26 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Beds, chairs, tables, statues and everything you could imagine for decorating your home!'} } +npcHandler:addModule(VoiceModule:new(voices)) + +keywordHandler:addKeyword({'furniture'}, StdModule.say, {npcHandler = npcHandler, text = "I have {beds}, {chairs}, {containers}, {decoration}, {flowers}, {instruments}, {pillows}, {pottery}, {statues}, {tapestries} and {tables}. Which of those would you like to see?"}) + +npcHandler:setMessage(MESSAGE_GREET, "Hello |PLAYERNAME|! Do you need some equipment for your house?") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Have a look. Most furniture comes in handy kits. Just use them in your house to assemble the furniture. Do you want to see only a certain {type} of furniture?") + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/yonan.lua b/data/npc/scripts/yonan.lua new file mode 100644 index 00000000000..416f592c29c --- /dev/null +++ b/data/npc/scripts/yonan.lua @@ -0,0 +1,88 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) +npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) +npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) +npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() +npcHandler:onThink() +end + +local playerTopic = {} +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.Kilmaresh.First.Access) < 1 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + playerTopic[cid] = 1 + elseif (player:getStorageValue(Storage.Kilmaresh.First.JamesfrancisTask) >= 0 and player:getStorageValue(Storage.Kilmaresh.First.JamesfrancisTask) <= 50) + and player:getStorageValue(Storage.Kilmaresh.First.Mission) < 3 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + playerTopic[cid] = 15 + elseif player:getStorageValue(Storage.Kilmaresh.First.Mission) == 4 then + npcHandler:setMessage(MESSAGE_GREET, "How could I help you?") -- It needs to be revised, it's not the same as the global + player:setStorageValue(Storage.Kilmaresh.First.Mission, 5) + playerTopic[cid] = 20 + end + npcHandler:addFocus(cid) + return true +end + +local function creatureSayCallback(cid, type, msg) +if not npcHandler:isFocused(cid) then + return false +end +npcHandler.topic[cid] = playerTopic[cid] +local player = Player(cid) +if msgcontains(msg, "mission") and player:getStorageValue(Storage.Kilmaresh.Eighth.Yonan) == 1 then + if player:getStorageValue(Storage.Kilmaresh.Eighth.Yonan) == 1 then + npcHandler:say({"Could you help me do a ritual?"}, cid)-- It needs to be revised, it's not the same as the global + npcHandler.topic[cid] = 1 + playerTopic[cid] = 1 + end +elseif msgcontains(msg, "yes") and playerTopic[cid] == 1 and player:getStorageValue(Storage.Kilmaresh.Eighth.Yonan) == 1 then + if player:getStorageValue(Storage.Kilmaresh.Eighth.Yonan) == 1 then + player:addItem(36552, 1) -- Yonans List + player:addItem(36448, 1) -- Pick Enchanted + npcHandler:say({"Here is the list with the missing ingredients to complete the ritual."}, cid)-- It needs to be revised, it's not the same as the global + player:setStorageValue(Storage.Kilmaresh.Eighth.Yonan, 2) + npcHandler.topic[cid] = 2 + playerTopic[cid] = 2 + else + npcHandler:say({"Sorry."}, cid) + end +end +if msgcontains(msg, "mission") and player:getStorageValue(Storage.Kilmaresh.Eighth.Yonan) == 2 then + if player:getStorageValue(Storage.Kilmaresh.Eighth.Yonan) == 2 then + npcHandler:say({"Did you bring all the materials I informed you about? "}, cid)-- It needs to be revised, it's not the same as the global + npcHandler.topic[cid] = 3 + playerTopic[cid] = 3 + end +elseif msgcontains(msg, "yes") and playerTopic[cid] == 3 and player:getStorageValue(Storage.Kilmaresh.Eighth.Yonan) == 2 then + if player:getStorageValue(Storage.Kilmaresh.Eighth.Yonan) == 2 and player:getItemById(10568, 3) and player:getItemById(36160, 12) and player:getItemById(36168, 10) then + player:removeItem(10568, 3) + player:removeItem(36160, 12) + player:removeItem(36168, 10) + npcHandler:say({"Thank you this stage of the ritual is complete."}, cid)-- It needs to be revised, it's not the same as the global + player:setStorageValue(Storage.Kilmaresh.Eighth.Yonan, 3) + npcHandler.topic[cid] = 4 + playerTopic[cid] = 4 + else + npcHandler:say({"Sorry."}, cid)-- It needs to be revised, it's not the same as the global + end +end +return true +end + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Well, bye then.') +npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus) +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/yulas.lua b/data/npc/scripts/yulas.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/yulas.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/zaidal.lua b/data/npc/scripts/zaidal.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/zaidal.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/zalamon.lua b/data/npc/scripts/zalamon.lua new file mode 100644 index 00000000000..5c377e6ebec --- /dev/null +++ b/data/npc/scripts/zalamon.lua @@ -0,0 +1,386 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local marks = { + ChildrenOfTheRevolution = { + {position = Position(33235, 31177, 7), type = 4, description = 'entrance of the camp'}, + {position = Position(33257, 31172, 7), type = 3, description = 'building 1 which you have to spy'}, + {position = Position(33227, 31163, 7), type = 3, description = 'building 2 which you have to spy'}, + {position = Position(33230, 31156, 7), type = 3, description = 'building 3 which you have to spy'} + }, + WrathOfTheEmperor = { + {position = Position(33356, 31180, 7), description = 'tunnel to hideout'}, + {position = Position(33173, 31076, 7), description = 'the rebel hideout'} + }, +} + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "mission") then + -- CHILDREN OF REVOLUTION QUEST + if player:getStorageValue(Storage.ChildrenoftheRevolution.Questline) < 1 then + npcHandler:say({ + "Zzo you are offering your help to a lizzard? Hmm, unuzzual. I don't know if I can fully truzzt you yet. ...", + "You'll have to work to earn my truzzt. Are you zzure you want to offer me your help?" + }, cid) + npcHandler.topic[cid] = 1 + elseif player:getStorageValue(Storage.ChildrenoftheRevolution.Questline) == 2 then + npcHandler:say("What newzz do you bring? Did you find any cluezz about zzeir whereaboutzz? ", cid) + npcHandler.topic[cid] = 3 + elseif player:getStorageValue(Storage.ChildrenoftheRevolution.Questline) == 3 then + npcHandler:say({ + "Zzurely you have zzeen zze black pondzz and puddlezz all over zze mountain pazz, palezzkin. It izz zze corruption zzat pervadezz zze landzz. It would be wizze not to drink or tazzte from zzem. ... ", + "It zzoakzz zze land, itzz people and even zze air itzzelf. But zzere are zztill zzpotzz not tainted by zze darknezz. ... ", + "A temple, norzzwezzt of zze barricaded outpozzt wizztood zze evil influenzze. However, I lozzt contact to itzz inhabitantzz when zze lizzardzz tightened zzeir grip. ... ", + "No one made it zzrough zze mountainzz for quite zzome time now - exzzept you. Maybe you can find out what happened zzere? " + }, cid) + npcHandler.topic[cid] = 5 + elseif player:getStorageValue(Storage.ChildrenoftheRevolution.Questline) == 5 then + npcHandler:say({ + "Zzo you found zze temple... lozzt you zzay. It wazz our lazzt remaining bazztion of hope for help from wizzin zze plainzz. ... ", + "Zzat meanzz zze plainzz are now in zze handzz of zze emperor and hizz army. I'm afraid zzat even zze great gate izz zzealed and zze landzz beyond it tainted azz well. ... ", + "Dark timezz, and I fear we know nozzing about our enemy yet. " + }, cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.ChildrenoftheRevolution.Questline, 6) + player:setStorageValue(Storage.ChildrenoftheRevolution.Mission01, 3) --Questlog, Children of the Revolution "Mission 1: Corruption" + elseif player:getStorageValue(Storage.ChildrenoftheRevolution.Questline) == 6 then + npcHandler:say({ + "Large partzz of zze empire are tainted. I zzee now zzat zzere izz almozzt nozzing left of our onzze zzo zztrong zzivilizzation. But I zztill don't know which danger our enemy really pozzezz. ... ", + "Zzere uzzed to be a remote and quiet zzettlement in zze middle of zze valley. If it hazz not been dezztroyed by zze corruption, I'm zzure zze army of zze emperor will have confizzcated it to gazzer rezzourzzezz. ... ", + "If you can get inzzide zze village, find out anyzzing you can about zzeir zzituation. Zze clever hawk hidezz itzz clawzz. ... ", + "I'm mozzt interezzted in zzeir weaponzz, food and zze zztrengzz of zzeir forzzezz. ... ", + "Are you prepared for zzizz mizzion? " + }, cid) + npcHandler.topic[cid] = 6 + elseif player:getStorageValue(Storage.ChildrenoftheRevolution.Questline) == 7 then + if player:getStorageValue(Storage.ChildrenoftheRevolution.SpyBuilding01) == 1 and player:getStorageValue(Storage.ChildrenoftheRevolution.SpyBuilding02) == 1 and player:getStorageValue(Storage.ChildrenoftheRevolution.SpyBuilding03) == 1 then + npcHandler:say({ + "Zzizz izz mozzt unfortunate. Zzo many warriorzz? Large amountzz of food? And how many weaponzz did you zzay? I zzee, hmm. ... ", + "Direct confrontation izz futile. We'll have to find ozzer wayzz to approach zze emperor and hizz army. " + }, cid) + player:setStorageValue(Storage.ChildrenoftheRevolution.Questline, 8) + player:setStorageValue(Storage.ChildrenoftheRevolution.Mission02, 5) --Questlog, Children of the Revolution "Mission 2: Imperial Zzecret Weaponzz" + npcHandler.topic[cid] = 0 + end + elseif player:getStorageValue(Storage.ChildrenoftheRevolution.Questline) == 8 then + npcHandler:say({ + "Your lazzt excurzzion revealed a terrifying truzz. Zze enemy'zz forzzezz are overwhelming, zzeir zztrengzz probably unrivaled. We cannot attack an army of zzizz zzize unlezz - unlezz we zzin out zzeir rankzz a little. ... ", + "A zzingle individual can be azz zztrong azz an army if he zztrikezz zze army azz a whole. ... ", + "Are you ready for your nexzzt tazzk? " + }, cid) + npcHandler.topic[cid] = 7 + elseif player:getStorageValue(Storage.ChildrenoftheRevolution.Questline) == 11 then + npcHandler:say({ + "You accomplished an important tazzk in breaking zze defenzze of zze emperor. Not everyzzing might be lozzt yet. ... ", + "I've got anozzer mizzion for you which will be even more dangerouzz zzan zze lazzt one. Return to me when you're ready. " + }, cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.ChildrenoftheRevolution.Questline, 12) + player:setStorageValue(Storage.ChildrenoftheRevolution.Mission03, 3) --Questlog, Children of the Revolution "Mission 3: Zee Killing Fieldzz" + elseif player:getStorageValue(Storage.ChildrenoftheRevolution.Questline) == 12 then + npcHandler:say({ + "Wizz zze enemy'zz forzzezz weakened like zzizz, we will be able to zzneak pazzt zze defenzze and furzzer inzzpect zze norzz. You should travel to zze mountain range furzzer eazzt of zze village. ... ", + "Zze old route to zze gate hazz been taken by darknezz. You'll have to find ozzer wayzz. Are you up to zzizz, palezzkin? " + }, cid) + npcHandler.topic[cid] = 10 + elseif player:getStorageValue(Storage.ChildrenoftheRevolution.Questline) == 17 then + npcHandler:say({ + "You have zzolved zze riddle? Imprezzive, palezzkin. Zze humming you hear in zze chamber mozzt zzertainly comezz from a magic portal zzomewhere in zze temple. ...", + "Have you zzearched zze ozzer chamberzz for any magical devizzezz or portalzz?" + }, cid) + npcHandler.topic[cid] = 12 + elseif player:getStorageValue(Storage.ChildrenoftheRevolution.Questline) == 18 then + npcHandler:say({ + "If I'm correct, zze portal in zze chamber beyond zze mechanizzm will lead you to zze great gate. It izz perfectly pozzible, however, zzat you will not be tranzzported directly into zze area. ...", + "You will razzer be brought to a plazze clozze by your goal. Where exzzactly, I cannot zzay. ...", + "Take all your courage and walk zze pazz zzrough zze portal. At leazzt TRY it - after all, I didn't make you my pupil for nozzing, Kohei. Are you prepared?" + }, cid) + npcHandler.topic[cid] = 13 + elseif player:getStorageValue(Storage.ChildrenoftheRevolution.Questline) == 20 then + npcHandler:say({ + "Too clozze, far too clozze. I felt a huge impact not long after you left. Zze war machinery of zze emperor muzzt finally have been zztarted. ...", + "I focuzzed and could only hope zzat I would reach you before everyzzing wazz too late. If I hadn't been able to tranzzport you here, our cauzze would have been lozzt. ...", + "I'm afraid we cannot continue zzizz fight here today. Zze rezzizztanzze izz zztill fragile. I'm afraid, zzere izz zztill much left to do. We'll have to prepare for war. ...", + "You've helped uzz a great deal during zzezze dark hourzz, I've got zzomezzing for you my friend. Pleazze, take zzizz zzerpent crezzt azz a zzign of my deep rezzpect. ...", + "Rezzt for now, you will need it - you have earned it." + }, cid) + player:setStorageValue(Storage.ChildrenoftheRevolution.Questline, 21) + player:setStorageValue(Storage.ChildrenoftheRevolution.Mission05, 3) --Questlog, Children of the Revolution "Mission 5: Phantom Army" + player:addItem(11116, 1) + player:addExperience(10000, true) + npcHandler.topic[cid] = 0 + -- CHILDREN OF REVOLUTION QUEST + + -- WRATH OF THE EMPEROR QUEST + elseif player:getStorageValue(Storage.ChildrenoftheRevolution.Questline) == 21 and player:getStorageValue(Storage.WrathoftheEmperor.Questline) < 1 then + npcHandler:say({ + "Zze attackzz have weakened our enemy zzignificantly. Yet, your quezzt continuezz. Bezzidezz zzome tazzkzz you could take, zze zzreat of zze emperor izz zztill hanging over our headzz like a rain cloud. ... ", + "Zzo, are you indeed willing to continue zze fight for our cauzze? " + }, cid) + npcHandler.topic[cid] = 14 + elseif player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 1 then + npcHandler:say("Ah you have returned. I azzume you already found zzome itemzz to build a proper dizzguizze? ", cid) + npcHandler.topic[cid] = 16 + elseif player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 6 then + npcHandler:say({ + "You ezztablished zze connection to zze hideout, good. But zzizz izz no time to rezzt. Your new tazzk will be quite different. ... ", + "Zze gardenzz are plagued by a creature. Zze former keeper of zzizz garden became an abomination of madnezz zzat needzz to be zztopped. ... ", + "He hidezz deep underground and it will be dangerouzz to challenge him in hizz lair but I am willing to rizzk it. ... ", + "Find him, dezztroy him, bring me hizz - I uhm, mean it izz utterly nezzezzary for you to deliver me a proof of hizz deazz. ... ", + "Now go - what are you waiting for, zzoftzzkin? Ready to finish what needzz to be finished? " + }, cid) + npcHandler.topic[cid] = 19 + elseif player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 8 then + npcHandler:say("Zzo... you finished him. Show me hizz head, will you? ", cid) + npcHandler.topic[cid] = 20 + elseif player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 9 then + npcHandler:say({ + "At zze dawn of time, zze children of zze Great Zznake were numerouzz. Zzey daringly colonizzed many partzz of zze world. But all bravery did not help againzzt zze sheer number of enemiezz zzey encountered. ... ", + "And while zze entitiezz zze unbelieverzz call godzz battled for power out of vanity, zze fazze of zze world changed violently. ... ", + "Many zzentrezz of our magnifizzent zzivilizzation were dezztroyed and only two realmzz zzat we know of remained intact but lozzt contact to each ozzer. ... ", + "In vizzionzz, zze Great Zznake revealed to Zalamon zze exzzizztenzze of ozzer lizzard people in a vazzt jungle in a far away land. ...", + "Zzough zze lizardzz of zze land failed zze Great Zznake and lozzt itzz favour, zzey are zztill in pozzezzion of ancient reliczz of immenzze power, onzze imbued by zze Great Zznake himzzelf. ... ", + "I had vizzionzz of an - item. Yezz. It may be uzzeful for uzz - I mean you, ezzpecially you. ... ", + "We need a zzeptre of power zzat can be found in zze underground of an ancient temple. It hazz been overrun by zzavage apezz and you will have to fight zzem and zze ancient guardianzz of zze temple azz well. Get uzz zzat zzeptre wherever it might be. ... ", + "It wazz revealed zzat it hazz been zzplit into 3 partzz for reazzonzz zzat are of no importanzze anymore. Zzizz powerful devizze could help uzz in our battle againzzt zze emperor. ... ", + "A shaft, a cuzzp, and an emerald form a zzeptre of zzuch power zzat zze partzz were hidden and are now guarded by vile creaturezz. ... ", + "Find it. Retrieve it. And bring it back to me. " + }, cid) + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 10) + player:setStorageValue(Storage.WrathoftheEmperor.Mission04, 1) --Questlog, Wrath of the Emperor "Mission 04: Sacrament of the Snake" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 11 then + npcHandler:say("You - azzembled zze zzeptre? Hand it out, give it to me, will you? ", cid) + npcHandler.topic[cid] = 21 + elseif player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 12 then + npcHandler:say({ + "Now we need to get clozzer to zze emperor himzzelf. A hive of beezz would defend zzeir queen wizz zzeir lives in cazze an enemy gained entranzze. Zzizz makezz a formidable defenzze line, nearly inviolable. ... ", + "But a zztranger directly in zze midzzt of zze hive will be acczzepted - after all it izz not pozzible to overcome zzuch a formidable defenzze which izz nearly inviolable, or izz it? Ha. ... ", + "Now zzat you overcame zzeir linezz of defenzze at zze great gate, you only need to find a way to enter zzeir home. ... ", + "Head zztraight to zze entranzze of zze zzity. If you can convinzze zze guardzz to let you enter zze zzity, you should be able to reach our contact zzere wizz eazze. ... ", + "We have alzzo forged zome paperzz for you and zzent zzem to zze zzity. Your victory in zze arena iz well known in our land. Wizz zze help of zzezze paperzz you will pretend zzat zzome of zze higher officialzz want to talk to you about your battle. ... ", + "Zzizz way you will be able to enter zze zzity of zze dragon emperor and meet our contact zzere in zze imperial offizze. He will give you zze next inzztructionzz. " + }, cid) + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 13) + player:setStorageValue(Storage.WrathoftheEmperor.Mission05, 1) --Questlog, Wrath of the Emperor "Mission 05: New in Town" + npcHandler.topic[cid] = 0 + -- WRATH OF THE EMPEROR QUEST + end + + -- WRATH OF THE EMPEROR QUEST + elseif msgcontains(msg, "crate") then + if npcHandler.topic[cid] == 17 then + npcHandler:say("Ah I zzee. You are ready for your mizzion and waiting for me to create and mark zze crate? ", cid) + npcHandler.topic[cid] = 18 + end + -- WRATH OF THE EMPEROR QUEST + + -- CHILDREN OF REVOLUTION QUEST + elseif msgcontains(msg, "symbols") then + if player:getStorageValue(Storage.ChildrenoftheRevolution.StrangeSymbols) == 1 then + npcHandler:say({ + "Mh, zze zzymbolzz of zze chamber you dezzcribe are very common in our culture, palezzkin. You should have come accrozz zzem in many a plazze already. ...", + "Zze zzymbolzz zzeem to be arranged in zzome way you zzay? Were zzere any notizzeable devizzezz? Zzwitchezz or leverzz? " + }, cid) + npcHandler.topic[cid] = 11 + end + -- CHILDREN OF REVOLUTION QUEST + elseif msgcontains(msg, "poison") or msgcontains(msg, "poizzon") then + if player:getStorageValue(Storage.ChildrenoftheRevolution.Questline) == 9 then + npcHandler:say("Zze emperor of zze dragonzz hazz tranzzformed himzzelf into an undead creature to lazzt for all eternity, to cheat deazz. Hizz corruption flowzz to zzozze he bound, and from zzem to zzozze zzey bound, and from zzem into zze land.", cid) + npcHandler.topic[cid] = 0 + end + -- CHILDREN OF REVOLUTION QUEST + elseif msgcontains(msg, "yes") then + -- CHILDREN OF REVOLUTION QUEST + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "Zzen indeed, I have a tazzk for you. Lizzten carefully and you might even learn zzomezzing. A wizze being hearzz one zzing and underzztandzz ten. ...", + "Zze mountainzz to zze norzz are overrun by corrupted lizzardzz. ...", + "Beyond zzem, you'll find a lush valley, zze Muggy Plainzz. Find out about zzeir planzz, zzeir tacticzz. Zze lizzardzz' art of war izz characterizzed by dizzguizze and zzecrezzy. ...", + "A traveller told me about a barricaded zzettlement zzey ezztablished. It'zz a weak and in all zzeir arroganzze, poorly guarded outpozzt beyond zze mountainzz. ...", + "If you can find any documentzz about zzeir zztrategiezz, zze rezzizztanzze will be very grateful. ...", + "Are you interezzted, palezzkin?" + }, cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 2 then + npcHandler:say("Be warned. Zze mountain pazzezz have been dezzerted for zzeveral weekzz now. No one made it acrozz and I fear you won't meet a zzingle friendly zzoul up zzere.", cid) + player:setStorageValue(Storage.ChildrenoftheRevolution.Questline, 1) + player:setStorageValue(Storage.ChildrenoftheRevolution.Mission00, 1) --Questlog, Children of the Revolution "Prove Your Worzz!" + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 3 then + npcHandler:say("Exzztraordinary. We are mozzt fortunate to have zzezze documentzz in our handzz now. Zzizz would zzertainly help me to build an effective rezzizztanzze. Will you give zzem to me? ", cid) + npcHandler.topic[cid] = 4 + elseif npcHandler.topic[cid] == 4 then + if player:removeItem(11101, 1) then + npcHandler:say({ + "Aaah, zzezze look zzertainly interezzting. Zzezze manuzzcriptzz show uzz zzeveral locationzz of zze enemy troopzz. ... ", + "I'm imprezzed, zzoftzzkin. Maybe you can be of zzome more help. " + }, cid) + player:setStorageValue(Storage.ChildrenoftheRevolution.Questline, 3) + player:setStorageValue(Storage.ChildrenoftheRevolution.Mission00, 2) --Questlog, Children of the Revolution "Prove Your Worzz!" + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 5 then + npcHandler:say("I've marked itzz location on your map. Go and find out what happened zzere. In zze pazzt it wazz known azz zze Temple of Equilibrium. ", cid) + player:setStorageValue(Storage.ChildrenoftheRevolution.Questline, 4) + player:setStorageValue(Storage.ChildrenoftheRevolution.Mission01, 1) --Questlog, Children of the Revolution "Mission 1: Corruption" + player:addMapMark(Position(33177, 31193, 7), 5, "Temple of Equilibrium") + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 6 then + npcHandler:say({ + "I'll mark zze entranzze to Chaochai on your map. ... ", + "Conzzentrate on one location at a time. Zze one who chazzezz after two harezz, won't catch even one. " + }, cid) + player:setStorageValue(Storage.ChildrenoftheRevolution.Questline, 7) + player:setStorageValue(Storage.ChildrenoftheRevolution.Mission02, 1) --Questlog, Children of the Revolution "Mission 2: Imperial Zzecret Weaponzz" + for i = 1, #marks.ChildrenOfTheRevolution do + local mark = marks.ChildrenOfTheRevolution[i] + player:addMapMark(mark.position, mark.type, mark.description) + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 7 then + npcHandler:say({ + "Not far to zze eazzt of zze village, you'll find rizze fieldzz. Zzey uzze zzem to rezztore zzeir food suppliezz. ... ", + "In zze zztorage accrozz zzizz room, you'll find a zzpecial poizzon which will zzignificantly weaken zzem if uzzed on zze water and zzoil zze rizze growzz in. ... ", + "Are you fully prepared for zzizz?" + }, cid) + npcHandler.topic[cid] = 8 + elseif npcHandler.topic[cid] == 8 then + npcHandler:say({ + "Good. Zze fieldzz should be not far from Xiachai in zze eazzt. Go to zze top terrazze and mix zze poizzon wizz zze water. ... ", + "{Poizzon} izz often uzzed by cowardzz, yet it grantzz great power to zze opprezzed. " + }, cid) + player:setStorageValue(Storage.ChildrenoftheRevolution.Questline, 9) + player:setStorageValue(Storage.ChildrenoftheRevolution.Mission03, 1) --Questlog, Children of the Revolution "Mission 3: Zee Killing Fieldzz" + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 10 then + npcHandler:say({ + "Perhapzz you can find a way to enter zze norzz of zze valley and find a pazzage to zze great gate itzzelf. Zzearch any templezz or zzettlementzz you come accrozz for hidden pazzagezz. ... ", + "I wish for a zzafe return wizz good newzz. " + }, cid) + player:setStorageValue(Storage.ChildrenoftheRevolution.Questline, 13) + if player:getStorageValue(Storage.ChildrenoftheRevolution.Mission04) <= 1 then + player:setStorageValue(Storage.ChildrenoftheRevolution.Mission04, 1) --Questlog, Children of the Revolution "Mission 4: Zze Way of Zztonezz" + end + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 11 then + npcHandler:say({ + "Interezzting. It'zz a riddle, zzoftzzkin. Zzuch gamezz are very popular in our culture. I believe zze leverzz will alter zze arrangement. ... ", + "Not too far from zze lever, zzere muzzt be a hint of zzome zzort. An image of how zze zzymbolzz muzzt be arranged. Zzurely zze mechanizzm will trigger a zzecret pazzage, maybe a moving wall or a portal. ... ", + "Zzizz should be our pazz to zze great gate. Head to zze zztorage onzze again. Zzere should be zzome extra greazzy oil which should work wizz zzuch a large mechanizzm. Zze leverzz should zzen be movable again. " + }, cid) + player:setStorageValue(Storage.ChildrenoftheRevolution.StrangeSymbols, 2) + player:setStorageValue(Storage.ChildrenoftheRevolution.Mission04, 3) --Questlog, Children of the Revolution "Mission 4: Zze Way of Zztonezz" + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 12 then + npcHandler:say({ + "Zzen zzizz izz zze way which will lead you to zze great gate. ...", + "By zze way, before I forget it - zzinzze you are zzkilled in zzolving riddlezz, maybe you can make uzze of zzizz old tome I've found? It containzz ancient knowledge and truly izz a tezztament of our culture, treat it wizz care. ...", + "I may alzzo have anozzer mizzion for you if you are interezzted." + }, cid) + player:addItem(11134, 1) + player:setStorageValue(Storage.ChildrenoftheRevolution.Questline, 18) + player:setStorageValue(Storage.ChildrenoftheRevolution.Mission04, 6) --Questlog, Children of the Revolution "Mission 4: Zze Way of Zztonezz" + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 13 then + npcHandler:say("You did well on your quezzt zzo far. I hope you will reach zze great gate in time. If we are lucky, it will zztill be open. ... Zalamon: If not, it will already be overrun by enemy zzoldierzz. Direct confrontation will be inevitable in zzat cazze, palezzkin. Now clear your mind and approach zze portal.", cid) + player:setStorageValue(Storage.ChildrenoftheRevolution.Questline, 19) + player:setStorageValue(Storage.ChildrenoftheRevolution.Mission05, 1) --Questlog, Children of the Revolution "Mission 5: Phantom Army" + npcHandler.topic[cid] = 0 + -- CHILDREN OF REVOLUTION QUEST + + -- WRATH OF THE EMPEROR QUEST + elseif npcHandler.topic[cid] == 14 then + npcHandler:say({ + "You continue to imprezz, zzoftzzkin. ... ", + "A contact of zze rezzizztanzze izz located furzzer in zze norzz of Zao. ... ", + "Zze emperor will drag hizz forzzezz to zze great gate now to bolzzter hizz defenzze. Zzinzze we attacked zze gate directly, he will not expect uzz taking a completely different route to reach zze norzzern territoriezz. ... ", + "I azzume you are already geared up and ready to conquer zze norzz? " + }, cid) + npcHandler.topic[cid] = 15 + elseif npcHandler.topic[cid] == 15 then + npcHandler:say({ + "Your determination izz highly appreciated. To zzneak pazzt zze eyezz of zze enemy, you will have to uzze a diverzzion. Zzere are zzeveral old tunnelzz beneazz zze zzoil of Zzao. ... ", + "One of zzem izz uzzed azz a maintenanzze connection by enemy lizardzz. To enter it, you will have to uzze a dizzguizze. Zzomezzing like a crate perhapzz. ... ", + "Mh, if you can find zzome nailzz - 3 should be enough - and 1 piezze of wood, I should be able to create an appropriate cazzing. Return to me if you found zze itemzz and we will talk about zze next zztep. " + }, cid) + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 1) + player:setStorageValue(Storage.WrathoftheEmperor.Mission01, 1) --Questlog, Wrath of the Emperor "Mission 01: Catering the Lions Den" + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 16 then + npcHandler:say({ + "Very good, I am confident zzizz will zzuffizze. Now I can build and mark a {crate} large enough for you to fit in - while zztill being able to breazze of courzze - and I will mark it in our tongue zzo it will look lezz zzuzzpizziouzz. ... ", + "Wizz zzeir eyezz towardzz zze gate, your chanzzezz to zzlip zzrough have never been better. I will keep zze zzpare materialzz here wizz me, we can alwayzz build a new one if you need to. " + }, cid) + npcHandler.topic[cid] = 17 + elseif npcHandler.topic[cid] == 18 then + if player:getItemCount(8309) >= 3 and player:getItemCount(5901) >= 1 then + player:removeItem(5901, 1) + player:removeItem(8309, 3) + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 2) + player:setStorageValue(Storage.WrathoftheEmperor.Mission01, 2) --Questlog, Wrath of the Emperor "Mission 01: Catering the Lions Den" + player:addItem(12284, 1) + npcHandler:say({ + "Alright. Let uzz create a crate. Hm. Let me zzee. ... ", + "Good. Zzat will do. ... ", + "Zze maintenanzze tunnelzz are in zze eazzt of zze plainzz, near ze coazt. Here, I will mark zzem on your map. ... ", + "Uzze zze dizzguizze wizzely, try to hide in zze dark and avoid being zzeen at all cozzt. ... ", + "Onzze you have reached zze norzz, you can find zze rezzizztanzze hideout at zze ozzer zzpot I marked on your map. Now hurry. " + }, cid) + for i = 1, #marks.WrathOfTheEmperor do + local mark = marks.WrathOfTheEmperor[i] + player:addMapMark(mark.position, 19, mark.description) + end + npcHandler.topic[cid] = 0 + end + elseif npcHandler.topic[cid] == 19 then + npcHandler:say({ + "Fine. I guezz poizzoning zzome of hizz plantzz will be enough to lure him out of hizz conzzealment. Zzizz plant poizzon here should allow you to do zzome zzignificant damage, take it. ... ", + "You can find him eazzt of zze corrupted gardenzz. Zzere uzzed to be a zzmall domizzile zzere but it hazz probably been conzzumed by zze corruption zzo beware. And now - go. " + }, cid) + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 7) + player:setStorageValue(Storage.WrathoftheEmperor.Mission03, 1) --Questlog, Wrath of the Emperor "Mission 03: The Keeper" + player:addItem(12320, 1) + npcHandler.topic[cid] = 0 + elseif npcHandler.topic[cid] == 20 then + if player:removeItem(12323, 1) then + npcHandler:say("Zzizz izz not hizz head but clearly belonged to zze keeper. I - I am imprezzed. You can go now. Leave me alone for a zzecond. ", cid) + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 9) + player:setStorageValue(Storage.WrathoftheEmperor.Mission03, 3) --Questlog, Wrath of the Emperor "Mission 03: The Keeper" + npcHandler.topic[cid] = 0 + end + + elseif npcHandler.topic[cid] == 21 then + if player:removeItem(12327, 1) then + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 12) + player:setStorageValue(Storage.WrathoftheEmperor.Mission04, 3) --Questlog, Wrath of the Emperor "Mission 04: Sacrament of the Snake" + npcHandler:say("Finally. At lazzt. Zze zzeptre izz - ourzz. Ourzz of courzze. A weapon we should uzze wizzely for our cauzze. I need a zzecond or two. Do you leave me already? ", cid) + npcHandler.topic[cid] = 0 + end + -- WRATH OF THE EMPEROR QUEST + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/zarak.lua b/data/npc/scripts/zarak.lua new file mode 100644 index 00000000000..c18a46f71ad --- /dev/null +++ b/data/npc/scripts/zarak.lua @@ -0,0 +1,238 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +keywordHandler:addSpellKeyword({'find', 'person'}, + { + npcHandler = npcHandler, + spellName = 'Find Person', + price = 80, + level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'great', 'light'}, + { + npcHandler = npcHandler, + spellName = 'Great Light', + price = 500, + level = 13, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'light'}, + { + npcHandler = npcHandler, + spellName = 'Light', + price = 0, + level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'magic', 'rope'}, + { + npcHandler = npcHandler, + spellName = 'Magic Rope', + price = 200, + level = 9, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'cure', 'poison'}, + { + npcHandler = npcHandler, + spellName = 'Cure Poison', + price = 150, + level = 10, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'intense', 'wound', 'cleansing'}, + { + npcHandler = npcHandler, + spellName = 'Intense Wound Cleansing', + price = 6000, + level = 80, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'wound', 'cleansing'}, + { + npcHandler = npcHandler, + spellName = 'Wound Cleansing', + price = 0, + level = 8, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'levitate'}, + { + npcHandler = npcHandler, + spellName = 'Levitate', + price = 500, + level = 12, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'haste'}, + { + npcHandler = npcHandler, + spellName = 'Haste', + price = 600, + level = 14, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'brutal', 'strike'}, + { + npcHandler = npcHandler, + spellName = 'Brutal Strike', + price = 1000, + level = 16, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'charge'}, + { + npcHandler = npcHandler, + spellName = 'Charge', + price = 1300, + level = 25, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'whirlwind', 'throw'}, + { + npcHandler = npcHandler, + spellName = 'Whirlwind Throw', + price = 1500, + level = 28, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'groundshaker'}, + { + npcHandler = npcHandler, + spellName = 'Groundshaker', + price = 1500, + level = 33, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'fierce', 'berserk'}, + { + npcHandler = npcHandler, + spellName = 'Fierce Berserk', + price = 7500, + level = 90, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'berserk'}, + { + npcHandler = npcHandler, + spellName = 'Berserk', + price = 2500, + level = 35, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'inflict', 'wound'}, + { + npcHandler = npcHandler, + spellName = 'Inflict Wound', + price = 2500, + level = 40, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'cure', 'bleeding'}, + { + npcHandler = npcHandler, + spellName = 'Cure Bleeding', + price = 2500, + level = 45, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'intense', 'recovery'}, + { + npcHandler = npcHandler, + spellName = 'Intense Recovery', + price = 10000, + level = 100, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'recovery'}, + { + npcHandler = npcHandler, + spellName = 'Recovery', + price = 4000, + level = 50, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'front', 'sweep'}, + { + npcHandler = npcHandler, + spellName = 'Front Sweep', + price = 4000, + level = 70, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) +keywordHandler:addSpellKeyword({'annihilation'}, + { + npcHandler = npcHandler, + spellName = 'Annihilation', + price = 20000, + level = 110, + vocation = VOCATION.CLIENT_ID.KNIGHT + } +) + +keywordHandler:addKeyword({'healing', 'spells'}, StdModule.say, + { + npcHandler = npcHandler, + text = "In this category I have '{Bruise Bane}', '{Cure Bleeding}', '{Wound Cleansing}', \z + '{Cure Poison}', '{Intense Wound Cleansing}', '{Recovery}' and '{Intense Recovery}'." + } +) +keywordHandler:addKeyword({'attack', 'spells'}, StdModule.say, + { + npcHandler = npcHandler, + text = {"In this category I have '{Whirlwind Throw}', '{Groundshaker}', '{Berserk}' and '{Fierce Berserk}' \z + as well as ...", "'{Brutal Strike}', '{Front Sweep}', '{Inflict Wound}' and '{Annihilation}'"} + } +) +keywordHandler:addKeyword({'support', 'spells'}, StdModule.say, + { + npcHandler = npcHandler, + text = "In this category I have '{Light}', '{Find Person}', '{Magic Rope}', '{Levitate}', '{Haste}', \z + '{Charge}' and '{Great Light}'." + } +) +keywordHandler:addKeyword({'spells'}, StdModule.say, + { + npcHandler = npcHandler, + text = "I can teach you {healing spells}, {attack spells} and {support spells}. \z + What kind of spell do you wish to learn? \z + You can also tell me for which level you would like to learn a spell, if you prefer that." + } +) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/zarifan.lua b/data/npc/scripts/zarifan.lua new file mode 100644 index 00000000000..298454bbf14 --- /dev/null +++ b/data/npc/scripts/zarifan.lua @@ -0,0 +1,46 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = ' lost... word...' }, + { text = ' ohhhh.... memories...' }, + { text = 'The secrets... too many... sleep...' }, + { text = 'Loneliness...' } +} + +local function creatureSayCallback(cid, type, msg) +if not npcHandler:isFocused(cid) then + return false + end + +local player = Player(cid) + if msgcontains(msg, "magic") and player:getStorageValue(12902) < 1 then + npcHandler:say("...Tell me...the first... magic word.", cid) + player:setStorageValue(12902, 1) + else npcHandler:say("...continue with your mission...", cid) + end + + end +keywordHandler:addKeyword({'mission'}, StdModule.say, {npcHandler = npcHandler, text = '..what about {magic}..'}) +keywordHandler:addKeyword({'friendship'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes... YES... friendship... now... second word?'}) +keywordHandler:addKeyword({'lives'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes... YES... friendship... lives... now third word?'}) +keywordHandler:addKeyword({'forever'}, StdModule.say, {npcHandler = npcHandler, text = 'Yes... YES... friendship... lives... FOREVER ... And say hello... to... my old friend... Omrabas. '}) + + +npcHandler:addModule(VoiceModule:new(voices)) +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/zebron.lua b/data/npc/scripts/zebron.lua new file mode 100644 index 00000000000..3e8db8df196 --- /dev/null +++ b/data/npc/scripts/zebron.lua @@ -0,0 +1,99 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Hey mate, up for a game of dice?'} } +npcHandler:addModule(VoiceModule:new(voices)) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, 'yes') then + if npcHandler.topic[cid] == 0 then + npcHandler:say('Hmmm, would you like to play for {money} or for a chance to win your own {dice}?', cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 4 then + if not player:removeMoneyNpc(100) then + npcHandler:say('I am sorry, but you don\'t have so much money.', cid) + npcHandler.topic[cid] = 0 + return false + end + + Npc():getPosition():sendMagicEffect(CONST_ME_CRAPS) + local realRoll = math.random(30) + local roll = math.random(5) + if realRoll < 30 then + npcHandler:say('Ok, here we go ... '.. roll ..'! You have lost. Bad luck. One more game?', cid) + else + npcHandler:say('Ok, here we go ... 6! You have won a dice, congratulations. One more game?', cid) + player:addItem(5792, 1) + end + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'game') then + if npcHandler.topic[cid] == 1 then + npcHandler:say('So you care for a civilized game of dice?', cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'money') then + if npcHandler.topic[cid] == 2 then + npcHandler:say('I thought so. Okay, I will roll a dice. If it shows 6, you will get five times your bet. How much do you want to bet?', cid) + npcHandler.topic[cid] = 3 + end + elseif msgcontains(msg, 'dice') then + if npcHandler.topic[cid] == 2 then + npcHandler:say('Hehe, good choice. Okay, the price for this game is 100 gold pieces. I will roll a dice. If I roll a 6, you can have my dice. Agreed?', cid) + npcHandler.topic[cid] = 4 + end + elseif tonumber(msg) then + local amount = tonumber(msg) + if amount < 1 or amount > 99 then + npcHandler:say('I am sorry, but I accept only bets between 1 and 99 gold. I don\'t want to ruin you after all. How much do you want to bet?', cid) + npcHandler.topic[cid] = 3 + return false + end + + if not player:removeMoneyNpc(amount) then + npcHandler:say('I am sorry, but you don\'t have so much money.', cid) + npcHandler.topic[cid] = 0 + return false + end + + Npc():getPosition():sendMagicEffect(CONST_ME_CRAPS) + local roll = math.random(6) + if roll < 6 then + npcHandler:say('Ok, here we go ... '.. roll ..'! You have lost. Bad luck. One more game?', cid) + else + npcHandler:say('Ok, here we go ... 6! You have won '.. amount * 5 ..', congratulations. One more game?', cid) + player:addMoney(amount * 5) + end + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, 'no') then + npcHandler:say('Oh come on, don\'t be a child.', cid) + npcHandler.topic[cid] = 1 + end + return true +end + +npcHandler:setMessage(MESSAGE_GREET, 'Greetings, high roller. So you care for a game, |PLAYERNAME|?') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Hey, you can\'t leave. Luck is smiling on you. I can feel it!') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Hey, you can\'t leave, |PLAYERNAME|. Luck is smiling on you. I can feel it!') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/zedrulon_the_fallen.lua b/data/npc/scripts/zedrulon_the_fallen.lua new file mode 100644 index 00000000000..98d74790c50 --- /dev/null +++ b/data/npc/scripts/zedrulon_the_fallen.lua @@ -0,0 +1,95 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +-- Twist of Fate +local blessKeyword = keywordHandler:addKeyword({'twist of fate'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'This is a special blessing I can bestow upon you once you have obtained at least one of the other blessings and which functions a bit differently. ...', + 'It only works when you\'re killed by other adventurers, which means that at least half of the damage leading to your death was caused by others, not by monsters or the environment. ...', + 'The {twist of fate} will not reduce the death penalty like the other blessings, but instead prevent you from losing your other blessings as well as the amulet of loss, should you wear one. It costs the same as the other blessings. ...', + 'Would you like to receive that protection for a sacrifice of |PVPBLESSCOST| gold, child?' + }}) + blessKeyword:addChildKeyword({'yes'}, StdModule.bless, {npcHandler = npcHandler, text = 'So receive the protection of the twist of fate, pilgrim.', cost = '|PVPBLESSCOST|', bless = 1}) + blessKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'Fine. You are free to decline my offer.', reset = true}) + +-- Adventurer Stone +keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Keep your adventurer\'s stone well.'}, function(player) return player:getItemById(18559, true) end) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for free?'}, function(player) return player:getStorageValue(Storage.AdventurersGuild.FreeStone.Alia) ~= 1 end) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, nil, function(player) player:addItem(18559, 1) player:setStorageValue(Storage.AdventurersGuild.FreeStone.Alia, 1) end) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +local stoneKeyword = keywordHandler:addKeyword({'adventurer stone'}, StdModule.say, {npcHandler = npcHandler, text = 'Ah, you want to replace your adventurer\'s stone for 30 gold?'}) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Here you are. Take care.', reset = true}, + function(player) return player:getMoney() + player:getBankBalance() >= 30 end, + function(player) if player:removeMoneyNpc(30) then player:addItem(18559, 1) end end + ) + stoneKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, you don\'t have enough money.', reset = true}) + stoneKeyword:addChildKeyword({''}, StdModule.say, {npcHandler = npcHandler, text = 'No problem.', reset = true}) + +-- Healing +local function addHealKeyword(text, condition, effect) + keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getCondition(condition) ~= nil end, + function(player) + player:removeCondition(condition) + player:getPosition():sendMagicEffect(effect) + end + ) +end + +addHealKeyword('You are burning. Let me quench those flames.', CONDITION_FIRE, CONST_ME_MAGIC_GREEN) +addHealKeyword('You are poisoned. Let me soothe your pain.', CONDITION_POISON, CONST_ME_MAGIC_RED) +addHealKeyword('You are electrified, my child. Let me help you to stop trembling.', CONDITION_ENERGY, CONST_ME_MAGIC_GREEN) + +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are hurt, my child. I will heal your wounds.'}, + function(player) return player:getHealth() < 40 end, + function(player) + local health = player:getHealth() + if health < 40 then player:addHealth(40 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking that bad. Sorry, I can\'t help you. But if you are looking for additional protection you should go on the {pilgrimage} of ashes or get the protection of the {twist of fate} here.'}) + +-- Basic +keywordHandler:addKeyword({'pilgrimage'}, StdModule.say, {npcHandler = npcHandler, text = 'Whenever you receive a lethal wound, your vital force is damaged and there is a chance that you lose some of your equipment. With every single of the five {blessings} you have, this damage and chance of loss will be reduced.'}) +keywordHandler:addKeyword({'blessings'}, StdModule.say, {npcHandler = npcHandler, text = 'There are five blessings available in five sacred places: the {spiritual} shielding, the spark of the {phoenix}, the {embrace} of Tibia, the fire of the {suns} and the wisdom of {solitude}. Additionally, you can receive the {twist of fate} here.'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'I see you received the spiritual shielding in the whiteflower temple south of Thais.'}, function(player) return player:hasBlessing(1) end) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the druids north of Carlin have provided you with the Embrace of Tibia.'}, function(player) return player:hasBlessing(2) end) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'I can see you received the blessing of the two suns in the suntower near Ab\'Dendriel.'}, function(player) return player:hasBlessing(3) end) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense that the spark of the phoenix already was given to you by the dwarven priests of earth and fire in Kazordoon.'}, function(player) return player:hasBlessing(4) end) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'I can sense you already talked to the hermit Eremo on the isle of Cormaya and received this blessing.'}, function(player) return player:hasBlessing(5) end) +keywordHandler:addAliasKeyword({'wisdom'}) +keywordHandler:addKeyword({'spiritual'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of spiritual shielding in the whiteflower temple south of Thais.'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addKeyword({'embrace'}, StdModule.say, {npcHandler = npcHandler, text = 'The druids north of Carlin will provide you with the embrace of Tibia.'}) +keywordHandler:addKeyword({'suns'}, StdModule.say, {npcHandler = npcHandler, text = 'You can ask for the blessing of the two suns in the suntower near Ab\'Dendriel.'}) +keywordHandler:addAliasKeyword({'fire'}) +keywordHandler:addKeyword({'phoenix'}, StdModule.say, {npcHandler = npcHandler, text = 'The spark of the phoenix is given by the dwarven priests of earth and fire in Kazordoon.'}) +keywordHandler:addAliasKeyword({'spark'}) +keywordHandler:addKeyword({'solitude'}, StdModule.say, {npcHandler = npcHandler, text = 'Talk to the hermit Eremo on the isle of Cormaya about this blessing.'}) +keywordHandler:addAliasKeyword({'wisdom'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome, young |PLAYERNAME|! If you are heavily wounded or poisoned, I can {heal} you for free.') +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Remember: If you are heavily wounded or poisoned, I can heal you for free.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'May the gods bless you, |PLAYERNAME|!') + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/zerbrus.lua b/data/npc/scripts/zerbrus.lua new file mode 100644 index 00000000000..e1ccaa60a53 --- /dev/null +++ b/data/npc/scripts/zerbrus.lua @@ -0,0 +1,179 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'Are you injured or poisoned? I can help you.' }, + { text = 'For Rookgaard! For Tibia!' }, + { text = 'No monster shall go past me.' }, + { text = 'The premium side of Rookgaard lies beyond.' }, + { text = 'Want to know what monsters are good for you at your level? Just ask me!' } +} +npcHandler:addModule(VoiceModule:new(voices)) + +-- Greeting and Farewell +keywordHandler:addGreetKeyword({'hi'}, {npcHandler = npcHandler, text = 'Greetings, |PLAYERNAME|! You\'re looking really bad. Let me heal your wounds.'}, + function(player) return player:getHealth() < 65 or player:getCondition(CONDITION_POISON) ~= nil end, + function(player) + local health = player:getHealth() + if health < 65 then player:addHealth(65 - health) end + player:removeCondition(CONDITION_POISON) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + end +) +keywordHandler:addAliasKeyword({'hello'}) + +keywordHandler:addGreetKeyword({'hi'}, {npcHandler = npcHandler, text = ' At your service, |PLAYERNAME|, protecting the {village} from {monsters}.'}, function(player) return player:getSex() == PLAYERSEX_FEMALE end) +keywordHandler:addAliasKeyword({'hello'}) + +keywordHandler:addFarewellKeyword({'bye'}, {npcHandler = npcHandler, text = 'Bye, |PLAYERNAME|.'}) +keywordHandler:addAliasKeyword({'farewell'}) + +local function addMonsterKeyword(level, text, marks) + keywordHandler:addKeyword({'monster'}, StdModule.say, {npcHandler = npcHandler, text = text}, + function(player) return player:getLevel() >= level end, + function(player) + if marks then + for i = 1, #marks do + player:addMapMark(marks[i].position, marks[i].type, marks[i].description) + end + end + end + ) +end + +-- Monster +keywordHandler:addKeyword({'monster'}, StdModule.say, {npcHandler = npcHandler, text = 'Hmm, |PLAYERNAME|. I really don\'t know if you should go into the wilderness without a shield. You should earn some money by hunting rats under the village first until you can afford at least a wooden shield.'}, function(player) return not player:hasRookgaardShield() end) + +addMonsterKeyword(10, 'It looks like you have mastered the drill.') +addMonsterKeyword(8, 'Wow, |PLAYERNAME|! You have grown so much. I think there is nothing more I could teach you. Talk to the {oracle} to travel to other places which will pose more of a challenge for you. ') +addMonsterKeyword(7, 'Impressive, |PLAYERNAME|. You are almost strong enough to leave this island. Maybe you can take on minotaurs or rotworms now. There are no rotworms on this side of the island, ask Dallheim for their location.') +addMonsterKeyword(6, 'Nice job out there,|PLAYERNAME|. If you are looking for a challenge, descend into the troll cave as deep as you can. Or explore the northern side of this island. Talk to {Dallheim} for directions.') +addMonsterKeyword(5, 'Nice job out there, |PLAYERNAME|. Are you looking for other monsters than {trolls} or {wolves}? Maybe you\'d like to check out {skeletons}. I\'ll mark them for you so you can find them easily.', + {{position = Position(31977, 32228, 7), type = MAPMARK_GREENSOUTH, description = 'Skeleton Cave'}} +) +addMonsterKeyword(4, 'You\'re halfway to leaving this island, well done. {Spiders} or {wolves} are always good to fight, but if you want to move on, why don\'t you check out trolls? I\'ll mark you the troll cave on this side.', + {{position = Position(32002, 32212, 7), type = MAPMARK_GREENSOUTH, description = 'Troll Cave'}} +) +addMonsterKeyword(3, 'Good progress, |PLAYERNAME|. You can still stay with {spiders} or {snakes}, but maybe you\'d like to try fighting a {wolf}? I\'ll mark some of their hills on your map.', + {{position = Position(32002, 32225, 7), type = MAPMARK_GREENNORTH, description = 'Wolf Hill'}, {position = Position(31989, 32198, 7), type = MAPMARK_GREENNORTH, description = 'Wolf Hill'}} +) +addMonsterKeyword(2, 'You\'ve already grown some, |PLAYERNAME|. You can either stay with {rats} or leave town to hunt {spiders} or {snakes}. I\'ll mark some spawns on your map.', + {{position = Position(32001, 32238, 7), type = MAPMARK_GREENSOUTH, description = 'Snake Pit'}, {position = Position(32046, 32188, 7), type = MAPMARK_GREENSOUTH, description = 'Spider Cave'}} +) +addMonsterKeyword(1, 'You are just beginning your journey, dear |PLAYERNAME|. You can start by helping me fight {rats} in the sewers. I\'ll mark an entrance on your map.', + {{position = Position(32097, 32205, 7), type = MAPMARK_GREENSOUTH, description = 'Sewer Entrance'}} +) + +-- Basic keywords +keywordHandler:addKeyword({'hint'}, StdModule.rookgaardHints, {npcHandler = npcHandler}) +keywordHandler:addKeyword({'name'}, StdModule.say, {npcHandler = npcHandler, text = 'Zerbrus, at your service.'}) +keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m the guard of this bridge. I defend Rookgaard against the beasts of the {wilderness} and the {dungeons}, and even of the stinking {sewers}.'}) +keywordHandler:addKeyword({'time'}, StdModule.say, {npcHandler = npcHandler, text = 'My duty is eternal. Time is of no importance.'}) +keywordHandler:addKeyword({'bank'}, StdModule.say, {npcHandler = npcHandler, text = 'Before you fight monsters, deposit your money there. If you die, you won\'t lose it if it\'s save in the bank.'}) +keywordHandler:addKeyword({'how', 'are', 'you'}, StdModule.say, {npcHandler = npcHandler, text = 'Fine.'}) +keywordHandler:addKeyword({'help'}, StdModule.say, {npcHandler = npcHandler, text = 'I have to stay here, sorry. But I can {heal} you if you are wounded. I have also valuable information about {monsters}.'}) +keywordHandler:addKeyword({'information'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m an expert concerning the wildlife and {monsters} on this island.'}) +keywordHandler:addKeyword({'citizen'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m not a gossiper, but if you want to know something about a certain Rookgaardian, ask.'}) +keywordHandler:addKeyword({'rat'}, StdModule.say, {npcHandler = npcHandler, text = 'They\'re not that dangerous, but don\'t let yourself get cornered by many of them. They still can hurt.'}) +keywordHandler:addKeyword({'spider'}, StdModule.say, {npcHandler = npcHandler, text = 'There are two types of spiders on this island: normal spiders and poison spiders. As their name says, the latter ones can poison you which will cause a constant loss of your health. Beware of them!'}) +keywordHandler:addKeyword({'troll'}, StdModule.say, {npcHandler = npcHandler, text = 'Once you have upgraded your starter {equipment} a little - maybe leather stuff - and got a better weapon as well as a shield, you should be able to kill trolls.'}) +keywordHandler:addKeyword({'wolf'}, StdModule.say, {npcHandler = npcHandler, text = 'You need a stronger weapon than the starter club to kill wolves. Maybe a {sabre} or a short {sword} will do.'}) +keywordHandler:addAliasKeyword({'wolves'}) +keywordHandler:addKeyword({'orc'}, StdModule.say, {npcHandler = npcHandler, text = 'The orcs have a hideout under the troll cave, just descend deep. Still, be very careful!'}) +keywordHandler:addKeyword({'minotaur'}, StdModule.say, {npcHandler = npcHandler, text = 'Minotaurs are very strong. You will need a group of people or at least level 6 and good equipment to be able to kill them.'}) +keywordHandler:addKeyword({'bug'}, StdModule.say, {npcHandler = npcHandler, text = 'They are a little tougher than they look like, but they\'re still good beginner monsters.'}) +keywordHandler:addKeyword({'skeleton'}, StdModule.say, {npcHandler = npcHandler, text = 'The skeletons on this island are usually fairly hidden. They are often found near graves and always underground. Beware of their evil life drain.'}) +keywordHandler:addKeyword({'bear'}, StdModule.say, {npcHandler = npcHandler, text = 'There is a bear cave close to this bridge. Be careful, though, they hit hard!'}) +keywordHandler:addKeyword({'wasp'}, StdModule.say, {npcHandler = npcHandler, text = 'Wasp hives exist only behind the north bridge, so ask {Dallheim} for information. I\'m glad there are no wasps here. They always make me jump.'}) +keywordHandler:addKeyword({'snake'}, StdModule.say, {npcHandler = npcHandler, text = 'Snakes can poison you, too, but their poison is usually not as dangerous as that of poison spiders. Just be careful and kill them fast.'}) +keywordHandler:addKeyword({'premium'}, StdModule.say, {npcHandler = npcHandler, text = 'Premium warriors pay. They gain many advantages this way.'}) +keywordHandler:addKeyword({'king'}, StdModule.say, {npcHandler = npcHandler, text = 'HAIL TO THE KING!'}) +keywordHandler:addKeyword({'academy'}, StdModule.say, {npcHandler = npcHandler, text = 'It\'s north of the temple.'}) +keywordHandler:addKeyword({'temple'}, StdModule.say, {npcHandler = npcHandler, text = 'A place of protection. Nothing can harm you there.'}) +keywordHandler:addKeyword({'dungeon'}, StdModule.say, {npcHandler = npcHandler, text = 'I can mark you some dungeons on your map if you ask me about {monsters} suited for your level.'}) +keywordHandler:addKeyword({'sewer'}, StdModule.say, {npcHandler = npcHandler, text = 'The sewers are crowded with {rats}. They make fine targets for young heroes.'}) +keywordHandler:addKeyword({'wilderness'}, StdModule.say, {npcHandler = npcHandler, text = 'There are {wolves}, {bears}, {snakes}, {deer}, and {spiders} in the wilderness past this bridge.'}) +keywordHandler:addKeyword({'god'}, StdModule.say, {npcHandler = npcHandler, text = 'I\'m a follower of {Banor}.'}) +keywordHandler:addKeyword({'banor'}, StdModule.say, {npcHandler = npcHandler, text = 'The heavenly warrior! Read {books} to learn about him.'}) +keywordHandler:addKeyword({'magic'}, StdModule.say, {npcHandler = npcHandler, text = 'You will learn about magic soon enough.'}) +keywordHandler:addKeyword({'tibia'}, StdModule.say, {npcHandler = npcHandler, text = 'In the world of Tibia, many challenges await the brave adventurer.'}) +keywordHandler:addKeyword({'book'}, StdModule.say, {npcHandler = npcHandler, text = 'There are many books in the {academy}. Theory can be just as important as practice.'}) + +keywordHandler:addKeyword({'rookgaard'}, StdModule.say, {npcHandler = npcHandler, text = 'It\'s my duty to protect this village and its {citizens}.'}) +keywordHandler:addAliasKeyword({'protect'}) + +keywordHandler:addKeyword({'monster'}, StdModule.say, {npcHandler = npcHandler, text = 'It looks like you have mastered the drill.'}) + +keywordHandler:addKeyword({'trade'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry, I don\'t trade. Ask the shop owners for a trade instead.'}) +keywordHandler:addAliasKeyword({'offer'}) +keywordHandler:addAliasKeyword({'stuff'}) +keywordHandler:addAliasKeyword({'wares'}) +keywordHandler:addAliasKeyword({'sell'}) +keywordHandler:addAliasKeyword({'buy'}) +keywordHandler:addAliasKeyword({'sword'}) +keywordHandler:addAliasKeyword({'sabre'}) +keywordHandler:addAliasKeyword({'equip'}) +keywordHandler:addAliasKeyword({'weapon'}) +keywordHandler:addAliasKeyword({'armor'}) +keywordHandler:addAliasKeyword({'shield'}) +keywordHandler:addAliasKeyword({'food'}) +keywordHandler:addAliasKeyword({'potion'}) + +-- Names +keywordHandler:addKeyword({'norma'}, StdModule.say, {npcHandler = npcHandler, text = 'I don\'t approve of her opening a bar. Those drunken adventurers stumbling over the bridge at nighttime are not especially helpful in improving the situation.'}) +keywordHandler:addKeyword({'loui'}, StdModule.say, {npcHandler = npcHandler, text = 'Such a chicken-hearted person.'}) +keywordHandler:addKeyword({'obi'}, StdModule.say, {npcHandler = npcHandler, text = 'He sells {weapons}. His shop is south west of town, close to the {temple}.'}) +keywordHandler:addKeyword({'santiago'}, StdModule.say, {npcHandler = npcHandler, text = 'He dedicated his life to welcoming newcomers to this island.'}) +keywordHandler:addKeyword({'zirella'}, StdModule.say, {npcHandler = npcHandler, text = 'She has her own problems.'}) +keywordHandler:addKeyword({'al', 'dee'}, StdModule.say, {npcHandler = npcHandler, text = 'There\'s something about this guy I don\'t like.'}) +keywordHandler:addKeyword({'amber'}, StdModule.say, {npcHandler = npcHandler, text = 'She\'s very attractive. Too bad my duty leaves me no time to date her.'}) +keywordHandler:addKeyword({'cipfried'}, StdModule.say, {npcHandler = npcHandler, text = 'He guards the temple and can heal you if you are badly injured or poisoned, just like me.'}) +keywordHandler:addKeyword({'dixi'}, StdModule.say, {npcHandler = npcHandler, text = 'She\'s {Obi\'s} granddaughter and deals with {armors} and {shields}. Her shop is south west of town, close to the temple.'}) +keywordHandler:addKeyword({'hyacinth'}, StdModule.say, {npcHandler = npcHandler, text = 'One of these reclusive druids.'}) +keywordHandler:addKeyword({'lee\'delle'}, StdModule.say, {npcHandler = npcHandler, text = 'Her shop is just north of the bridge. She really has good offers.'}) +keywordHandler:addKeyword({'lily'}, StdModule.say, {npcHandler = npcHandler, text = 'Gentle girl, but a little to esoteric for my taste. However, her {potions} might come in handy.'}) +keywordHandler:addKeyword({'oracle'}, StdModule.say, {npcHandler = npcHandler, text = 'You can find the oracle on the top floor of the {academy}, just above {Seymour}. Go there when you are level 8.'}) +keywordHandler:addKeyword({'paulie'}, StdModule.say, {npcHandler = npcHandler, text = 'The local {bank} clerk.'}) +keywordHandler:addKeyword({'seymour'}, StdModule.say, {npcHandler = npcHandler, text = 'His job of teaching young heroes is important for the survival of all of us.'}) +keywordHandler:addKeyword({'tom'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s the local tanner. You could try selling fresh corpses or leather to him.'}) +keywordHandler:addKeyword({'dallheim'}, StdModule.say, {npcHandler = npcHandler, text = 'He does a fine job, protecting the north bridge. He\'s been on duty longer than me and knows the north side of Rookgaard well.'}) +keywordHandler:addKeyword({'zerbrus'}, StdModule.say, {npcHandler = npcHandler, text = 'At your service.'}) +keywordHandler:addKeyword({'billy'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s a farmer. A little more friendly than his cousin {Willie}, he also buys and sells {food}.'}) +keywordHandler:addKeyword({'willie'}, StdModule.say, {npcHandler = npcHandler, text = 'He\'s quite rude. Also, he buys and sells {food}.'}) + +-- Healing +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are poisoned. I will help you.'}, + function(player) return player:getCondition(CONDITION_POISON) ~= nil end, + function(player) + local health = player:getHealth() + if health < 65 then player:addHealth(65 - health) end + player:removeCondition(CONDITION_POISON) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You are looking really bad. Let me heal your wounds.'}, + function(player) return player:getHealth() < 65 end, + function(player) + local health = player:getHealth() + if health < 65 then player:addHealth(65 - health) end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + end +) +keywordHandler:addKeyword({'heal'}, StdModule.say, {npcHandler = npcHandler, text = 'You aren\'t looking really bad. Eat some food to regain strength.'}) + +npcHandler:setMessage(MESSAGE_WALKAWAY, 'Hm.') +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/zeronex.lua b/data/npc/scripts/zeronex.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/zeronex.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/zethra.lua b/data/npc/scripts/zethra.lua new file mode 100644 index 00000000000..b52215cfce1 --- /dev/null +++ b/data/npc/scripts/zethra.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { {text = 'Come over here if you have to resupply!'} } +npcHandler:addModule(VoiceModule:new(voices)) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/zirella.lua b/data/npc/scripts/zirella.lua new file mode 100644 index 00000000000..ed46f8a67fc --- /dev/null +++ b/data/npc/scripts/zirella.lua @@ -0,0 +1,143 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local voices = { + { text = 'I wish someone could spare a minute and help me...' }, + { text = 'This is too hard for an old woman like me.' }, + { text = 'Hello, young adventurer, you look strong enough to help me!' } +} +npcHandler:addModule(VoiceModule:new(voices)) + +local storeTalkCid = {} +local function greetCallback(cid) + local player = Player(cid) + if player:getStorageValue(Storage.RookgaardTutorialIsland.ZirellaNpcGreetStorage) < 1 then + npcHandler:setMessage(MESSAGE_GREET, "Oh, heaven must have sent you! Could you please help me with a {quest}?") + storeTalkCid[cid] = 0 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.ZirellaNpcGreetStorage) == 1 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back, darling... so about that firewood, could you please {help} me?") + storeTalkCid[cid] = 2 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.ZirellaNpcGreetStorage) == 2 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back, darling... so about the {dead trees}, let me explain that a little more, {yes}?") + storeTalkCid[cid] = 3 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.ZirellaNpcGreetStorage) == 3 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back, darling... so about the {branches}, let me explain that a little more, {yes}?") + storeTalkCid[cid] = 4 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.ZirellaNpcGreetStorage) == 4 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back, darling... so about the {pushing}, let me explain that a little more, {yes}?") + storeTalkCid[cid] = 5 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.ZirellaNpcGreetStorage) == 5 then + npcHandler:setMessage(MESSAGE_GREET, "Welcome back, darling... so about the {cart}, let me explain that a little more, {yes}?") + storeTalkCid[cid] = 6 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.ZirellaNpcGreetStorage) == 6 then + npcHandler:setMessage(MESSAGE_GREET, "Oh, sweetheart, is there a problem with the quest? Should I {explain} it again?") + storeTalkCid[cid] = 7 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.ZirellaNpcGreetStorage) == 7 then + npcHandler:setMessage(MESSAGE_GREET, "Right, thank you sweetheart! This will be enough to heat my oven. Oh, and you are probably waiting for your reward, {yes}?") + storeTalkCid[cid] = 8 + elseif player:getStorageValue(Storage.RookgaardTutorialIsland.ZirellaNpcGreetStorage) == 8 then + npcHandler:setMessage(MESSAGE_GREET, "Oh, welcome back, dear Isleth Eagonst! Are you here for a little chat? Just use the highlighted {keywords} again to choose a {topic}.") + end + return true +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if isInArray({"yes", "quest", "ok"}, msg) then + if storeTalkCid[cid] == 0 then + npcHandler:say("By the way, 'quest' is a keyword that many NPCs react to, especially those which have tasks for you. So darling, about that {quest}... are you listening?", cid) + storeTalkCid[cid] = 1 + elseif storeTalkCid[cid] == 1 then + npcHandler:say("Thank you so much for your kindness. I'm an old woman and I desperately need firewood for my oven. Could you please help me?", cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.ZirellaQuestLog, 1) + player:setStorageValue(Storage.RookgaardTutorialIsland.ZirellaNpcGreetStorage, 1) + storeTalkCid[cid] = 2 + elseif storeTalkCid[cid] == 2 then + npcHandler:say("You're such a treasure. In the forest south of here, there are {dead trees} without any leaves. The first thing you have to do is search for one, {okay}?", cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.ZirellaQuestLog, 2) + player:setStorageValue(Storage.RookgaardTutorialIsland.ZirellaNpcGreetStorage, 2) + storeTalkCid[cid] = 3 + elseif storeTalkCid[cid] == 3 then + npcHandler:say("Splendid, once you've found one, 'Use' it to break a branch from it. Did you understand that so far?", cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.ZirellaQuestLog, 3) + player:setStorageValue(Storage.RookgaardTutorialIsland.ZirellaNpcGreetStorage, 3) + storeTalkCid[cid] = 4 + elseif storeTalkCid[cid] == 4 then + npcHandler:say("Good... so after you broke a branch, please push it here and select 'use with'. That will turn your mouse cursor into crosshairs. Then left-click on my cart. {Alright}?", cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.ZirellaQuestLog, 4) + player:setStorageValue(Storage.RookgaardTutorialIsland.ZirellaNpcGreetStorage, 4) + storeTalkCid[cid] = 5 + elseif storeTalkCid[cid] == 5 then + npcHandler:say("To push the branch, drag and drop it on the grass by holding the left mousebutton and moving the cursor to where you want to throw the branch. Just push it near my cart before you 'Use' it, {alright}?", cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.ZirellaQuestLog, 5) + player:setStorageValue(Storage.RookgaardTutorialIsland.ZirellaNpcGreetStorage, 5) + storeTalkCid[cid] = 6 + elseif storeTalkCid[cid] == 6 then + npcHandler:say({ + "Thank you darling! My cart is right beside me. It's a little complicated: I need some firewood, but it's very difficult for my slightly advanced age. ...", + "Please go into the the forest southeast of here. You will find fine old rotten brown trees. Please RIGHT-CLICK in the lower right corner of that tree and choose 'USE'. That way, a branch should appear on the map. ...", + "Don't put it in your inventory like before, but instead DRAG it over the map by LEFT-CLICKING the loose branch, HOLDING the LEFT MOUSE BUTTON and moving it over the map. ...", + "When you are close to my cart, USE the branch WITH the cart: RIGHT-CLICK the branch on the floor and select 'USE WITH', Then LEFT-CLICK on the cart. Don't worry, you will see what I mean on the way. Thanks and {bye} for now!" + }, cid) + player:setStorageValue(Storage.RookgaardTutorialIsland.ZirellaQuestLog, 6) + player:setStorageValue(Storage.RookgaardTutorialIsland.ZirellaNpcGreetStorage, 6) + Position(32064, 32273, 7):sendMagicEffect(CONST_ME_TUTORIALARROW) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + elseif storeTalkCid[cid] == 7 then + npcHandler:say({ + "Well, you know that old women like me like to talk a lot. If you see three dots at the end of a sentence, I have still something to say and you should not interrupt, like now ...", + "Patience is a virtue, young adventurer! So, the quest was to go into the forest south of here and to find a dead tree. Wait, let me continue! ...", + "'Use' a tree to break a dry branch from it. Afterwards, drag and drop the branch back to my cart and select 'Use with', then left-click on my cart. Thanks again for offering your help!" + }, cid) + storeTalkCid[cid] = nil + elseif storeTalkCid[cid] == 8 then + npcHandler:say("Oh, you deserve it. You really have earned some experience! Also, you may enter my little house now and take what's in that chest beside my bed. Good {bye} for now!", cid) + player:addExperience(50, true) + Position(32058, 32266, 6):sendMagicEffect(CONST_ME_TUTORIALARROW) + player:getPosition():sendMagicEffect(CONST_ME_GIFT_WRAPS) + player:setStorageValue(Storage.RookgaardTutorialIsland.ZirellaQuestLog, 8) + player:setStorageValue(Storage.RookgaardTutorialIsland.ZirellaNpcGreetStorage, 8) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + elseif msgcontains(msg, "no") then + if storeTalkCid[cid] == 7 then + npcHandler:say("Well then, I hope you find nice and dry branches for me! Good {bye}!", cid) + npcHandler:releaseFocus(cid) + npcHandler:resetNpc(cid) + end + end + return true +end + +local function onReleaseFocus(cid) + storeTalkCid[cid] = nil +end + +npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus) + +npcHandler:setCallback(CALLBACK_GREET, greetCallback) +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye |PLAYERNAME|, may Uman bless you!.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye traveller, take care.") + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/zirkon.lua b/data/npc/scripts/zirkon.lua new file mode 100644 index 00000000000..aad3e61ab80 --- /dev/null +++ b/data/npc/scripts/zirkon.lua @@ -0,0 +1,18 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/zizzle.lua b/data/npc/scripts/zizzle.lua new file mode 100644 index 00000000000..b8e04b5b4cc --- /dev/null +++ b/data/npc/scripts/zizzle.lua @@ -0,0 +1,84 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if(msgcontains(msg, "mission")) then + if player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 25 then + npcHandler:say("You made it! Az zoon az you are prepared, I will brief you for your nexzt mizzion. ", cid) + player:setStorageValue(Storage.WrathoftheEmperor.Mission08, 2) --Questlog, Wrath of the Emperor "Mission 08: Uninvited Guests" + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 26) + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 26 then + npcHandler:say({ + "Ze dragon emperor controlz ze whole empire wiz hiz willpower. But even he iz not powerful enough to uze ziz control continuouzly wizout zome form of aid. ... ", + "Wiz ze ancient zeptre zat you acquired for uz earlier, I can charge ozer zeptrez wiz azpectz of power of ze Great Znake. If you manage to touch one of ze tranzmitter cryztalz wiz ze zeptre, itz godly power will realign ze cryztal. ...", + "Not only will ze cryztal ztop zending ze orderz of ze emperor into ze mindz of my opprezzed people, it will alzo zend a mezzage of freedom and zelf-rezpect inztead. ...", + "Dizabling ze cryztalz will probably alert ze emperor. It will likely be too late for him to intervene in perzon but a creature of hiz power might have ozer wayz to intervene. ...", + "But zere iz more. To reach ze emperor, you will need accezz to hiz inner realmz. Ze zecret to enter iz guarded by a dragon. ...", + "But ziz iz not ze catch - ze catch iz, zat ze key iz buried in hiz vazt mind. Ze emperor haz bound ze dragon to himzelf, forzing him into an eternal zlumber. ...", + "A zignificant part of ze emperor'z power iz uzed to reztrain ze dragon. Ze only way to free him will be to enter hiz dreamz. Are you prepared for ziz?" + }, cid) + npcHandler.topic[cid] = 1 + + elseif player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 29 then + if player:getStorageValue(Storage.WrathoftheEmperor.Questline) < 30 then + npcHandler:say({ + "You freed ze dragon! And you pozzezz ze key to enter ze inner realmz of ze emperor, well done. ...", + "Now you are ready to reach ze inner zanctum of ze emperor. Zalamon'z revelationz showed him zat zere are four cryztalz channelling ze will of ze emperor into ze land. ...", + "Wiz ze relic you gained from Zalamon we were able to create powerful replicaz of ze zeptre. Take ziz wiz you. ...", + "You will have to realign ze cryztalz one after ze ozer. Ztart wiz ze one in ze norz-wezt and work your way clockwize zrough ze room. ...", + "Uzing ze zeptre will forze a part of ze emperor'z willpower out of ze cryztal. You will have to kill zoze manifeztationz. ...", + "Zen uze your zeptre on ze remainz to deztroy ze emperor'z influenze over ze cryztal. ...", + "I recommend not to go alone becauze it will be very dangerouz - but ALL of you will have to uze zeir zeptre replicaz on ze emperor'z remainz to prozeed! ...", + "You will need it. Now go to the north of Sleeping Dragon room, {dont need talk} with he! Good luck." + }, cid) + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 30) + player:setStorageValue(Storage.WrathoftheEmperor.Mission10, 2) --Questlog, Wrath of the Emperor "Mission 10: A Message of Freedom" + player:setStorageValue(Storage.WrathoftheEmperor.BossStatus, 1) + player:addItem(12318, 1) + npcHandler.topic[cid] = 0 + else + npcHandler:say({"Now go to the north of Sleeping Dragon room, {dont need talk} with he!"}, cid) + end + + end + + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "Didn't exzpect anyzing lezz from you. Alright, zankz to your effortz to build an effective reziztanze, our comradez zalvaged ziz potion and ze formula you need to utter to breach hiz zubconzciouznezz. ...", + "Drink it and when you are cloze to ze dragon zpeak: Z...z.. well, juzt take ze sheet wiz ze word and read it yourzelf. A lot of rebelz have died to retrieve ziz information, uze it wizely. ...", + "Now go and try to find a way to reach ze emperor and to free ze land from it'z opprezzor. Onze you have found a way, return to me and I will explain what to do wiz ze cryztalz. May ze Great Znake guide you!" + }, cid) + player:setStorageValue(Storage.WrathoftheEmperor.Mission09, 1) --Questlog, Wrath of the Emperor "Mission 08: Uninvited Guests" + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 27) + player:addItem(12328, 1) + player:addItem(12382, 1) + end + npcHandler.topic[cid] = 0 + end + + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/zlak.lua b/data/npc/scripts/zlak.lua new file mode 100644 index 00000000000..88d27e21460 --- /dev/null +++ b/data/npc/scripts/zlak.lua @@ -0,0 +1,67 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + local player = Player(cid) + if msgcontains(msg, "mission") then + if player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 22 then + npcHandler:say({ + "Ze rumour mill iz quite fazt. Ezpecially when zomeone unuzual az you enterz ze zity. Zoon zey will learn zat you have no reazon to be here and our raze will be buzted. ...", + "Zo we have to ztrike fazt and quickly. You will have to eliminate zome high ranking key officialz. I zink killing four of zem should be enough. ...", + "Ziz will dizrupt ze order in ze zity zignificantly zinze zo much dependz on bureaucracy and ze chain of command. Only chaoz and dizorganization will enable me to help you with ze next ztep in ze plan." + }, cid) + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 23) + player:setStorageValue(Storage.WrathoftheEmperor.Mission05, 3) --Questlog, Wrath of the Emperor "Mission 05: New in Town" + player:setStorageValue(Storage.WrathoftheEmperor.Mission06, 0) --Questlog, Wrath of the Emperor "Mission 06: The Office Job" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 23 and player:getStorageValue(Storage.WrathoftheEmperor.Mission06) == 4 then + npcHandler:say({ + "Chaoz and panic are already zpreading. Your barbaric brutality iz frightening effectively. I could acquire a key zat we need to get you into ze palaze itzelf. But zere are ztill too many guardz and elite zquadz even for you to fight. ...", + "I need you to enter ze zity and zlay at leazt zix noblez. Ze otherz will feel zreatened and call guardz to zemzelvez, and ze dragon kingz will accuze each ozer to be rezponzible for zlaying zeir pet noblez. ...", + "Zat should enable uz to give you at leazt a chanze to attack ze palaze." + }, cid) + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 24) + player:setStorageValue(Storage.WrathoftheEmperor.Mission07, 0) --Questlog, Wrath of the Emperor "Mission 07: A Noble Cause" + npcHandler.topic[cid] = 0 + elseif player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 24 and player:getStorageValue(Storage.WrathoftheEmperor.Mission07) == 6 then + if npcHandler.topic[cid] ~= 1 then + npcHandler:say({ + "Word of your deedz iz already zpreading like a wildfire. Zalamon'z plan to unleash zome murderouz beaztz in ze zity workz almozt too well. You are already becoming zome kind of legend with which motherz frighten zeir unruly hatchlingz. ...", + "Your next {mizzion} will be a ztrike into ze heart of ze empire." + }, cid) + npcHandler.topic[cid] = 1 + else + npcHandler:say({ + "Your eagernezz for killing and bloodshed iz frightening, but your next mizzion will zuit your tazte. Wiz ze zity in chaoz and defenzez diverted, ze ztage iz zet for our final ztrike. ...", + "A large number of rebelz have arrived undercover in ze zity. Zey will attack ze palaze and zome loyal palaze guardz will let zem in. ...", + "Meanwhile, you will take ze old ezcape tunnel zat leadz from ze abandoned bazement in ze norz of ze miniztry to a lift zat endz zomewhere in ze palaze. ...", + "When everyzing workz according to ze plan, you will meet Zalamon zomewhere in the underground part of ze palaze." + }, cid) + player:setStorageValue(Storage.WrathoftheEmperor.Mission08, 1) --Questlog, Wrath of the Emperor "Mission 08: Uninvited Guests" + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 25) + npcHandler.topic[cid] = 0 + end + end + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/zoltan.lua b/data/npc/scripts/zoltan.lua new file mode 100644 index 00000000000..4d1c6995db1 --- /dev/null +++ b/data/npc/scripts/zoltan.lua @@ -0,0 +1,80 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + + -- The paradox tower quest + if msgcontains(msg, "yenny the gentle") then + npcHandler:say("Ah, Yenny the Gentle was one of the founders of the druid order called Crunor's Caress, that has been originated in her hometown Carlin.", cid) + npcHandler.topic[cid] = 0 + elseif msgcontains(msg, "crunors caress") then + if player:getStorageValue(Storage.Quest.TheParadoxTower.TheFearedHugo) == 1 then + -- Questlog: The Feared Hugo (Padreia) + player:setStorageValue(Storage.Quest.TheParadoxTower.TheFearedHugo, 2) + end + npcHandler:say("A quite undruidic order of druids they were, as far as we know. I have no more enlightening knowledge about them though.", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +-- Female Summoner and Male Mage Hat Addon (needs to be rewritten) +local hatKeyword = keywordHandler:addKeyword({'proof'}, StdModule.say, {npcHandler = npcHandler, text = '... I cannot believe my eyes. You retrieved this hat from Ferumbras\' remains? That is incredible. If you give it to me, I will grant you the right to wear this hat as addon. What do you say?'}, + function(player) return not player:hasOutfit(player:getSex() == PLAYERSEX_FEMALE and 141 or 130, 2) end + ) + hatKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'Sorry you don\'t have the Ferumbras\' hat.'}, function(player) return player:getItemCount(5903) == 0 end) + hatKeyword:addChildKeyword({'yes'}, StdModule.say, {npcHandler = npcHandler, text = 'I bow to you, player, and hereby grant you the right to wear Ferumbras\' hat as accessory. Congratulations!'}, nil, + function(player) + player:removeItem(5903, 1) + player:addOutfitAddon(141, 2) + player:addOutfitAddon(130, 2) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + end + ) + -- hatKeyword:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = ''}) + +keywordHandler:addKeyword({'myra'}, StdModule.say, {npcHandler = npcHandler, + text = { + 'Bah, I know. I received some sort of \'nomination\' from our outpost in Port Hope. ...', + 'Usually it takes a little more than that for an award though. However, I honour Myra\'s word. ...', + 'I hereby grant you the right to wear a special sign of honour, acknowledged by the academy of Edron. Since you are a man, I guess you don\'t want girlish stuff. There you go.' + }}, + function(player) return player:getStorageValue(Storage.OutfitQuest.MageSummoner.AddonHatCloak) == 10 end, + function(player) + player:addOutfitAddon(138, 2) + player:addOutfitAddon(133, 2) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:setStorageValue(Storage.OutfitQuest.MageSummoner.AddonHatCloak, 11) + player:setStorageValue(Storage.OutfitQuest.MageSummoner.MissionHatCloak, 0) + player:setStorageValue(Storage.OutfitQuest.Ref, math.min(0, player:getStorageValue(Storage.OutfitQuest.Ref) - 1)) + end +) + +keywordHandler:addKeyword({'myra'}, StdModule.say, {npcHandler = npcHandler, text = 'Stop bothering me. I am a far too busy man to be constantly giving out awards.'}, function(player) return player:getStorageValue(Storage.OutfitQuest.MageSummoner.AddonHatCloak) == 11 end) +keywordHandler:addKeyword({'myra'}, StdModule.say, {npcHandler = npcHandler, text = 'What the hell are you talking about?'}) + +npcHandler:setMessage(MESSAGE_GREET, 'Welcome |PLAYERNAME|, student of the arcane arts. I teach the fiercest {spells} available.') +npcHandler:setMessage(MESSAGE_FAREWELL, 'Use your knowledge wisely, |PLAYERNAME|.') + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/zora.lua b/data/npc/scripts/zora.lua new file mode 100644 index 00000000000..1588ba4866f --- /dev/null +++ b/data/npc/scripts/zora.lua @@ -0,0 +1,48 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + if msgcontains(msg, "football") then + npcHandler:say("Do you want to buy a football for 111 gold?", cid) + npcHandler.topic[cid] = 1 + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + local player = Player(cid) + if player:getMoney() + player:getBankBalance() >= 111 then + npcHandler:say("Here it is.", cid) + player:addItem(2109, 1) + player:removeMoneyNpc(111) + else + npcHandler:say("You don't have enough money.", cid) + end + npcHandler.topic[cid] = 0 + end + end + return true +end + +keywordHandler:addKeyword({'equipment'}, StdModule.say, {npcHandler = npcHandler, text = "I sell equipment for your adventure! Just ask me for a {trade} to see my wares."}) + +npcHandler:setMessage(MESSAGE_GREET, "Oh, please come in, |PLAYERNAME|. What can I do for you? If you need adventure equipment, ask me for a {trade}.") +npcHandler:setMessage(MESSAGE_FAREWELL, "Good bye, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_WALKAWAY, "Good bye, |PLAYERNAME|.") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Of course, just browse through my wares. {Footballs} have to be purchased separately.") +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/ztiss.lua b/data/npc/scripts/ztiss.lua new file mode 100644 index 00000000000..bc7096b07b6 --- /dev/null +++ b/data/npc/scripts/ztiss.lua @@ -0,0 +1,60 @@ + +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "offer") then + if player:getStorageValue(Storage.TheNewFrontier.Questline) == 23 then + npcHandler:say("You are ztill a captive and your life is forfeit. Zere might be a way for you to ezcape if you agree to {work} for my mazter.", cid) + npcHandler.topic[cid] = 1 + end + elseif msgcontains(msg, "work") then + if npcHandler.topic[cid] == 1 then + npcHandler:say({ + "Zere iz a great tournament of ztrengz each decade. It determinez ze granted privilegez for zertain individualz of power for ze comming decade. ...", + "My mazter wantz to zurprize hiz opponentz by an unexpected move. He will uze warriorz from ze outzide, zomeone zat no one can azzezz. ...", + "One of ziz warriorz could be you. Or you could ztay here and rot in ze dungeon. Are you interezted in ziz deal?" + }, cid) + npcHandler.topic[cid] = 2 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 2 then + npcHandler:say({ + "You are zmart for a zoftzkin, but before you begin to feel too zmart, you should know zat we will zeal our deal wiz you drinking a ztrong poizon zat will inevitably kill you if you want to trick me and not attend ze tournament. ...", + "Zo are you ready to drink ziz poizon here?" + }, cid) + npcHandler.topic[cid] = 3 + elseif npcHandler.topic[cid] == 3 then + npcHandler:say({ + "Excellent! Now you may leave ziz area zrough ze teleporter to ze norz. It will bring you to a hidden boat. Ziz boat will take you to ze tournament izle. ...", + "Zere you'll learn anyzing you need to know about ze great tournament." + }, cid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 24) + player:setStorageValue(Storage.TheNewFrontier.Mission07, 3) --Questlog, The New Frontier Quest "Mission 07: Messengers Of Peace" + player:setStorageValue(Storage.TheNewFrontier.Mission08, 1) --Questlog, The New Frontier Quest "Mission 08: An Offer You Can't Refuse" + npcHandler.topic[cid] = 0 + end + end + return true +end +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/zuma_magehide.lua b/data/npc/scripts/zuma_magehide.lua new file mode 100644 index 00000000000..61457cb34ff --- /dev/null +++ b/data/npc/scripts/zuma_magehide.lua @@ -0,0 +1,20 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + + + +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/zumtah.lua b/data/npc/scripts/zumtah.lua new file mode 100644 index 00000000000..06c190df59c --- /dev/null +++ b/data/npc/scripts/zumtah.lua @@ -0,0 +1,94 @@ +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local condition = Condition(CONDITION_OUTFIT) +condition:setOutfit({lookType = 352}) +condition:setTicks(-1) + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + end + + local player = Player(cid) + if msgcontains(msg, "exit") then + if player:getStorageValue(Storage.WrathoftheEmperor.ZumtahStatus) ~= 1 then + if npcHandler.topic[cid] < 1 then + npcHandler:say("Oh of course, may I show you around a bit before? You want to go straight to the exit? Would you please follow me. Oh right, I am terribly sorry but THERE IS NONE. Will you finally give it up please?", cid) + npcHandler.topic[cid] = 1 + elseif npcHandler.topic[cid] == 3 then + npcHandler.topic[cid] = 4 + elseif npcHandler.topic[cid] == 6 then + npcHandler.topic[cid] = 7 + elseif npcHandler.topic[cid] == 10 then + npcHandler:say("Oh, you mean - if I have ever been out of here in those 278 years? Well, I - I can't remember. No, I can't remember. Sorry.", cid) + npcHandler.topic[cid] = 11 + elseif npcHandler.topic[cid] == 11 then + npcHandler:say("No, I really can't remember. I enjoyed my stay here so much that I forgot how it looks outside of this hole. Outside. The air, the sky, the light. Oh well... well.", cid) + npcHandler.topic[cid] = 12 + elseif npcHandler.topic[cid] == 12 then + npcHandler:say("Oh yes, yes. I... I never really thought about how you creatures feel in here I guess. I... just watched all these beings die here. ...", cid) + npcHandler.topic[cid] = 13 + elseif npcHandler.topic[cid] == 13 then + npcHandler:say("Oh, excuse me of course, you... wanted to go. Like all... the others. I am sorry, so sorry. You... you can leave. Yes. You can go. You are free. I shall stay here and help every poor soul which ever gets thrown in here from this day onward. ...", cid) + npcHandler.topic[cid] = 14 + elseif npcHandler.topic[cid] == 14 then + npcHandler:say({ + "Alright, as I said you are free now. There will not be an outside for the next three centuries, but you - go. ...", + "Oh and I recovered the strange crate you where hiding in, it will wait for you at the exit since you can't carry it as... a beetle, muhaha. Yes, you shall now crawl through the passage as a beetle. There you go." + }, cid) + npcHandler.topic[cid] = 0 + player:setStorageValue(Storage.WrathoftheEmperor.ZumtahStatus, 1) + player:setStorageValue(Storage.WrathoftheEmperor.PrisonReleaseStatus, 1) + player:addCondition(condition) + end + else + npcHandler:say("It's you, why did they throw you in here again? Anyway, I will just transform you once more. I also recovered your crate which will wait for you at the exit. There, feel free to go.", cid) + player:setStorageValue(Storage.WrathoftheEmperor.PrisonReleaseStatus, 1) + player:addCondition(condition) + end + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("You are starting to get on my nerves. Is this the only topic you know?", cid) + npcHandler.topic[cid] = 2 + elseif npcHandler.topic[cid] == 4 then + npcHandler.topic[cid] = 5 + elseif npcHandler.topic[cid] == 7 then + npcHandler.topic[cid] = 8 + end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 2 then + npcHandler:say("Pesky, persistent human.", cid) + npcHandler.topic[cid] = 3 + elseif npcHandler.topic[cid] == 5 then + npcHandler.topic[cid] = 6 + elseif npcHandler.topic[cid] == 8 then + npcHandler:say("Muhahaha. Then I will give you a test. How many years do you think have I been here? {89}, {164} or {278}?", cid) + npcHandler.topic[cid] = 9 + end + elseif msgcontains(msg, "278") and npcHandler.topic[cid] == 9 then + npcHandler:say("Correct human, and that is not nearly how high you would need to count to tell all the lost souls I've seen dying here. I AM PERPETUAL. Muahahaha.", cid) + npcHandler.topic[cid] = 10 + elseif (msgcontains(msg, "164") or msgcontains(msg, "89")) and npcHandler.topic[cid] == 9 then + npcHandler:say("Wrong answer human! Muahahaha.", cid) + npcHandler.topic[cid] = 0 + end + return true +end + +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/zurak.lua b/data/npc/scripts/zurak.lua new file mode 100644 index 00000000000..be71d92ef3f --- /dev/null +++ b/data/npc/scripts/zurak.lua @@ -0,0 +1,50 @@ + +local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + elseif msgcontains(msg, "trip") or msgcontains(msg, "passage") then + --if Player(cid):getStorageValue(Storage.TheNewFrontier.Questline) >= 24 then + npcHandler:say("You want trip to Izzle of Zztrife?", cid) + npcHandler.topic[cid] = 1 + --else + --npcHandler:say("You need The New Frontier Quest to travel.", cid) + --end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("It'zz your doom you travel to.", cid) + local player, destination = Player(cid), Position(33102, 31056, 7) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Zzoftzzkinzz zzo full of fear.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'hurry') or msgcontains(msg, 'job') then + npcHandler:say('Me zzimple ferryman. I arrange {trip} to Izzle of Zztrife.', cid) + npcHandler.topic[cid] = 0 + end + return true +end +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scripts/zurakarena.lua b/data/npc/scripts/zurakarena.lua new file mode 100644 index 00000000000..d1cc270f1ee --- /dev/null +++ b/data/npc/scripts/zurakarena.lua @@ -0,0 +1,47 @@ + local keywordHandler = KeywordHandler:new() +local npcHandler = NpcHandler:new(keywordHandler) +NpcSystem.parseParameters(npcHandler) + +function onCreatureAppear(cid) + npcHandler:onCreatureAppear(cid) +end +function onCreatureDisappear(cid) + npcHandler:onCreatureDisappear(cid) +end +function onCreatureSay(cid, type, msg) + npcHandler:onCreatureSay(cid, type, msg) +end +function onThink() + npcHandler:onThink() +end + +local function creatureSayCallback(cid, type, msg) + if not npcHandler:isFocused(cid) then + return false + elseif isInArray({"trip", "passage", "back"}, msg) then + --if Player(cid):getStorageValue(Storage.TheNewFrontier.Questline) >= 24 then + npcHandler:say("You want to go back?", cid) + npcHandler.topic[cid] = 1 + --end + elseif msgcontains(msg, "yes") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("It'zz your doom you travel to.", cid) + local player, destination = Player(cid), Position(33158, 31228, 7) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, "no") then + if npcHandler.topic[cid] == 1 then + npcHandler:say("Zzoftzzkinzz zzo full of fear.", cid) + npcHandler.topic[cid] = 0 + end + elseif msgcontains(msg, 'hurry') or msgcontains(msg, 'job') then + npcHandler:say('Me zzimple ferryman. I arrange {trip} to Zao.', cid) + npcHandler.topic[cid] = 0 + end + return true +end +npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) +npcHandler:addModule(FocusModule:new()) diff --git a/data/npc/scrutinon.xml b/data/npc/scrutinon.xml new file mode 100644 index 00000000000..d0799e440de --- /dev/null +++ b/data/npc/scrutinon.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/data/npc/scutty.xml b/data/npc/scutty.xml new file mode 100644 index 00000000000..1191460c045 --- /dev/null +++ b/data/npc/scutty.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/sebastian.xml b/data/npc/sebastian.xml new file mode 100644 index 00000000000..e262a9e6661 --- /dev/null +++ b/data/npc/sebastian.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/sebastian_nargor.xml b/data/npc/sebastian_nargor.xml new file mode 100644 index 00000000000..4bbbb98c910 --- /dev/null +++ b/data/npc/sebastian_nargor.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ser_tybald.xml b/data/npc/ser_tybald.xml new file mode 100644 index 00000000000..ad420800962 --- /dev/null +++ b/data/npc/ser_tybald.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/serafin.xml b/data/npc/serafin.xml new file mode 100644 index 00000000000..010ac41a5ab --- /dev/null +++ b/data/npc/serafin.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + diff --git a/data/npc/servant_sentry.xml b/data/npc/servant_sentry.xml new file mode 100644 index 00000000000..dfbc7335c8a --- /dev/null +++ b/data/npc/servant_sentry.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/seymour.xml b/data/npc/seymour.xml new file mode 100644 index 00000000000..43bdbccd9ab --- /dev/null +++ b/data/npc/seymour.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/shadowpunch.xml b/data/npc/shadowpunch.xml new file mode 100644 index 00000000000..45a82aa6157 --- /dev/null +++ b/data/npc/shadowpunch.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/shalmar.xml b/data/npc/shalmar.xml new file mode 100644 index 00000000000..331c56d2002 --- /dev/null +++ b/data/npc/shalmar.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/shanar.xml b/data/npc/shanar.xml new file mode 100644 index 00000000000..e7a3c2b6000 --- /dev/null +++ b/data/npc/shanar.xml @@ -0,0 +1,86 @@ + + + + + + + + + + diff --git a/data/npc/shanoya.xml b/data/npc/shanoya.xml new file mode 100644 index 00000000000..6b528243a35 --- /dev/null +++ b/data/npc/shanoya.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/sharon.xml b/data/npc/sharon.xml new file mode 100644 index 00000000000..da0ab1ce7bf --- /dev/null +++ b/data/npc/sharon.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/shauna.xml b/data/npc/shauna.xml new file mode 100644 index 00000000000..268c110234a --- /dev/null +++ b/data/npc/shauna.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/sherry_mcronald.xml b/data/npc/sherry_mcronald.xml new file mode 100644 index 00000000000..e5ee1d68da2 --- /dev/null +++ b/data/npc/sherry_mcronald.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/data/npc/shiantis.xml b/data/npc/shiantis.xml new file mode 100644 index 00000000000..80716b1a9b0 --- /dev/null +++ b/data/npc/shiantis.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + diff --git a/data/npc/shimun.xml b/data/npc/shimun.xml new file mode 100644 index 00000000000..7dff8c3c3fc --- /dev/null +++ b/data/npc/shimun.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/shiriel.xml b/data/npc/shiriel.xml new file mode 100644 index 00000000000..607f1ac3d0d --- /dev/null +++ b/data/npc/shiriel.xml @@ -0,0 +1,59 @@ + + + + + + + + + + diff --git a/data/npc/shirith.xml b/data/npc/shirith.xml new file mode 100644 index 00000000000..abe84aa59f1 --- /dev/null +++ b/data/npc/shirith.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/shoddy_beggar.xml b/data/npc/shoddy_beggar.xml new file mode 100644 index 00000000000..c74d8c88ecc --- /dev/null +++ b/data/npc/shoddy_beggar.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/sholley.xml b/data/npc/sholley.xml new file mode 100644 index 00000000000..19200b8a9b5 --- /dev/null +++ b/data/npc/sholley.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/shortsighted_dwarf.xml b/data/npc/shortsighted_dwarf.xml new file mode 100644 index 00000000000..267b513f044 --- /dev/null +++ b/data/npc/shortsighted_dwarf.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/siestaar.xml b/data/npc/siestaar.xml new file mode 100644 index 00000000000..6378b96694a --- /dev/null +++ b/data/npc/siestaar.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/siflind.xml b/data/npc/siflind.xml new file mode 100644 index 00000000000..8aa7b87b24e --- /dev/null +++ b/data/npc/siflind.xml @@ -0,0 +1,70 @@ + + + + + + + + + + diff --git a/data/npc/sigurd.xml b/data/npc/sigurd.xml new file mode 100644 index 00000000000..bceef6ca567 --- /dev/null +++ b/data/npc/sigurd.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + diff --git a/data/npc/silas.xml b/data/npc/silas.xml new file mode 100644 index 00000000000..23b8a90bdba --- /dev/null +++ b/data/npc/silas.xml @@ -0,0 +1,37 @@ + + + + + + + + + + diff --git a/data/npc/simon_the_beggar.xml b/data/npc/simon_the_beggar.xml new file mode 100644 index 00000000000..97737973d09 --- /dev/null +++ b/data/npc/simon_the_beggar.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/sinatuki.xml b/data/npc/sinatuki.xml new file mode 100644 index 00000000000..54aa9fcbf16 --- /dev/null +++ b/data/npc/sinatuki.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/sinclair.xml b/data/npc/sinclair.xml new file mode 100644 index 00000000000..a0f7da4f05c --- /dev/null +++ b/data/npc/sinclair.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/sirik.xml b/data/npc/sirik.xml new file mode 100644 index 00000000000..3128bc127af --- /dev/null +++ b/data/npc/sirik.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/sister_of_jack.xml b/data/npc/sister_of_jack.xml new file mode 100644 index 00000000000..768e7700313 --- /dev/null +++ b/data/npc/sister_of_jack.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/skeleton_guard.xml b/data/npc/skeleton_guard.xml new file mode 100644 index 00000000000..6299ab9b132 --- /dev/null +++ b/data/npc/skeleton_guard.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/skip.xml b/data/npc/skip.xml new file mode 100644 index 00000000000..09f6aea2e0f --- /dev/null +++ b/data/npc/skip.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/skjaar.xml b/data/npc/skjaar.xml new file mode 100644 index 00000000000..e91c7d64a52 --- /dev/null +++ b/data/npc/skjaar.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/smiley.xml b/data/npc/smiley.xml new file mode 100644 index 00000000000..41fcb24c95a --- /dev/null +++ b/data/npc/smiley.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/data/npc/snake_eye.xml b/data/npc/snake_eye.xml new file mode 100644 index 00000000000..82e7fbb3aec --- /dev/null +++ b/data/npc/snake_eye.xml @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/data/npc/soilance.xml b/data/npc/soilance.xml new file mode 100644 index 00000000000..250538baaea --- /dev/null +++ b/data/npc/soilance.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + diff --git a/data/npc/sorcerer_estrella.xml b/data/npc/sorcerer_estrella.xml new file mode 100644 index 00000000000..4f5a8b0f1ea --- /dev/null +++ b/data/npc/sorcerer_estrella.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/spectulus.xml b/data/npc/spectulus.xml new file mode 100644 index 00000000000..0939be2c4f4 --- /dev/null +++ b/data/npc/spectulus.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/stan.xml b/data/npc/stan.xml new file mode 100644 index 00000000000..d2dbd56c39e --- /dev/null +++ b/data/npc/stan.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + diff --git a/data/npc/storkus.xml b/data/npc/storkus.xml new file mode 100644 index 00000000000..6926df84db4 --- /dev/null +++ b/data/npc/storkus.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/strange_pipe.xml b/data/npc/strange_pipe.xml new file mode 100644 index 00000000000..a273b606083 --- /dev/null +++ b/data/npc/strange_pipe.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/strange_pipe1.xml b/data/npc/strange_pipe1.xml new file mode 100644 index 00000000000..14953acd5c3 --- /dev/null +++ b/data/npc/strange_pipe1.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/strange_pipe2.xml b/data/npc/strange_pipe2.xml new file mode 100644 index 00000000000..61bf84fe69a --- /dev/null +++ b/data/npc/strange_pipe2.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/strange_pipe3.xml b/data/npc/strange_pipe3.xml new file mode 100644 index 00000000000..792671125d9 --- /dev/null +++ b/data/npc/strange_pipe3.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/stricken_soul.xml b/data/npc/stricken_soul.xml new file mode 100644 index 00000000000..a8ef812d465 --- /dev/null +++ b/data/npc/stricken_soul.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/stutch.xml b/data/npc/stutch.xml new file mode 100644 index 00000000000..e2b778a30be --- /dev/null +++ b/data/npc/stutch.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/suzy.xml b/data/npc/suzy.xml new file mode 100644 index 00000000000..d1beaae0d63 --- /dev/null +++ b/data/npc/suzy.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/sven.xml b/data/npc/sven.xml new file mode 100644 index 00000000000..8fcb52c698e --- /dev/null +++ b/data/npc/sven.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/svenson.xml b/data/npc/svenson.xml new file mode 100644 index 00000000000..64b248d5ea4 --- /dev/null +++ b/data/npc/svenson.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/swolt.xml b/data/npc/swolt.xml new file mode 100644 index 00000000000..bbbcfdf2b0b --- /dev/null +++ b/data/npc/swolt.xml @@ -0,0 +1,20 @@ + + + + + + + + + + diff --git a/data/npc/sylvester.xml b/data/npc/sylvester.xml new file mode 100644 index 00000000000..b02485d2a08 --- /dev/null +++ b/data/npc/sylvester.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/data/npc/taegen.xml b/data/npc/taegen.xml new file mode 100644 index 00000000000..e4c53ce6e5c --- /dev/null +++ b/data/npc/taegen.xml @@ -0,0 +1,39 @@ + + + + + + + + + + diff --git a/data/npc/talesia.xml b/data/npc/talesia.xml new file mode 100644 index 00000000000..130f7cfb1af --- /dev/null +++ b/data/npc/talesia.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/data/npc/talila.xml b/data/npc/talila.xml new file mode 100644 index 00000000000..f4c267a188b --- /dev/null +++ b/data/npc/talila.xml @@ -0,0 +1,151 @@ + + + + + + + + + + diff --git a/data/npc/talphion.xml b/data/npc/talphion.xml new file mode 100644 index 00000000000..43ac4148abc --- /dev/null +++ b/data/npc/talphion.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/data/npc/tamara.xml b/data/npc/tamara.xml new file mode 100644 index 00000000000..f8e8770e496 --- /dev/null +++ b/data/npc/tamara.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/tamed_lion.xml b/data/npc/tamed_lion.xml new file mode 100644 index 00000000000..7c73bcd0004 --- /dev/null +++ b/data/npc/tamed_lion.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/tamerin.xml b/data/npc/tamerin.xml new file mode 100644 index 00000000000..d646dbc7d29 --- /dev/null +++ b/data/npc/tamerin.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/tamoril.xml b/data/npc/tamoril.xml new file mode 100644 index 00000000000..e72064c51f4 --- /dev/null +++ b/data/npc/tamoril.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + diff --git a/data/npc/tanaro.xml b/data/npc/tanaro.xml new file mode 100644 index 00000000000..cacc9eec4e6 --- /dev/null +++ b/data/npc/tanaro.xml @@ -0,0 +1,23 @@ + + + + + + + + + diff --git a/data/npc/tandros.xml b/data/npc/tandros.xml new file mode 100644 index 00000000000..665eb44801e --- /dev/null +++ b/data/npc/tandros.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/data/npc/tanyt.xml b/data/npc/tanyt.xml new file mode 100644 index 00000000000..6b0388f1a08 --- /dev/null +++ b/data/npc/tanyt.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/tarak_inner.xml b/data/npc/tarak_inner.xml new file mode 100644 index 00000000000..345f2a86953 --- /dev/null +++ b/data/npc/tarak_inner.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/tarak_sunken.xml b/data/npc/tarak_sunken.xml new file mode 100644 index 00000000000..50bf2812d93 --- /dev/null +++ b/data/npc/tarak_sunken.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/tarun.xml b/data/npc/tarun.xml new file mode 100644 index 00000000000..62f8dc965fc --- /dev/null +++ b/data/npc/tarun.xml @@ -0,0 +1,34 @@ + + + + + + + + + + diff --git a/data/npc/tefrit.xml b/data/npc/tefrit.xml new file mode 100644 index 00000000000..636953f84f0 --- /dev/null +++ b/data/npc/tefrit.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/tehlim.xml b/data/npc/tehlim.xml new file mode 100644 index 00000000000..d089dd68ec8 --- /dev/null +++ b/data/npc/tehlim.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/telas.xml b/data/npc/telas.xml new file mode 100644 index 00000000000..25764ff4138 --- /dev/null +++ b/data/npc/telas.xml @@ -0,0 +1,34 @@ + + + + + + + + + diff --git a/data/npc/telas_golem.xml b/data/npc/telas_golem.xml new file mode 100644 index 00000000000..9ba24147c22 --- /dev/null +++ b/data/npc/telas_golem.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/tereban.xml b/data/npc/tereban.xml new file mode 100644 index 00000000000..e31cd9988ba --- /dev/null +++ b/data/npc/tereban.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/terrence.xml b/data/npc/terrence.xml new file mode 100644 index 00000000000..1989accff28 --- /dev/null +++ b/data/npc/terrence.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/tesha.xml b/data/npc/tesha.xml new file mode 100644 index 00000000000..2a920b897b7 --- /dev/null +++ b/data/npc/tesha.xml @@ -0,0 +1,80 @@ + + + + + + + + + + diff --git a/data/npc/testserver_assistant.xml b/data/npc/testserver_assistant.xml new file mode 100644 index 00000000000..497cf226f72 --- /dev/null +++ b/data/npc/testserver_assistant.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/tezila.xml b/data/npc/tezila.xml new file mode 100644 index 00000000000..c25a1aa4186 --- /dev/null +++ b/data/npc/tezila.xml @@ -0,0 +1,73 @@ + + + + + + + + + + diff --git a/data/npc/thanita.xml b/data/npc/thanita.xml new file mode 100644 index 00000000000..8ce858ef3d5 --- /dev/null +++ b/data/npc/thanita.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/the_beggar_king.xml b/data/npc/the_beggar_king.xml new file mode 100644 index 00000000000..a114c5b8cc4 --- /dev/null +++ b/data/npc/the_beggar_king.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/the_blind_prophet.xml b/data/npc/the_blind_prophet.xml new file mode 100644 index 00000000000..5ec06e27359 --- /dev/null +++ b/data/npc/the_blind_prophet.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/the_bone_master.xml b/data/npc/the_bone_master.xml new file mode 100644 index 00000000000..f34d80ab44c --- /dev/null +++ b/data/npc/the_bone_master.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/the_crone.xml b/data/npc/the_crone.xml new file mode 100644 index 00000000000..c961ea91d9d --- /dev/null +++ b/data/npc/the_crone.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/the_destiny_seer.xml b/data/npc/the_destiny_seer.xml new file mode 100644 index 00000000000..4f765791b33 --- /dev/null +++ b/data/npc/the_destiny_seer.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/the_dream_master.xml b/data/npc/the_dream_master.xml new file mode 100644 index 00000000000..6f97deccf70 --- /dev/null +++ b/data/npc/the_dream_master.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/the_empress.xml b/data/npc/the_empress.xml new file mode 100644 index 00000000000..09c2f484a46 --- /dev/null +++ b/data/npc/the_empress.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/the_first_dragon.xml b/data/npc/the_first_dragon.xml new file mode 100644 index 00000000000..5de2cbbadb8 --- /dev/null +++ b/data/npc/the_first_dragon.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/the_gate_keeper.xml b/data/npc/the_gate_keeper.xml new file mode 100644 index 00000000000..37475a94186 --- /dev/null +++ b/data/npc/the_gate_keeper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/the_librarian.xml b/data/npc/the_librarian.xml new file mode 100644 index 00000000000..2151e0e948f --- /dev/null +++ b/data/npc/the_librarian.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/data/npc/the_oracle.xml b/data/npc/the_oracle.xml new file mode 100644 index 00000000000..bfeba542b47 --- /dev/null +++ b/data/npc/the_oracle.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/the_orc_king.xml b/data/npc/the_orc_king.xml new file mode 100644 index 00000000000..0fc5a940bfc --- /dev/null +++ b/data/npc/the_orc_king.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/the_queen_of_the_banshees.xml b/data/npc/the_queen_of_the_banshees.xml new file mode 100644 index 00000000000..02d9915b0c5 --- /dev/null +++ b/data/npc/the_queen_of_the_banshees.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/theodore_loveless.xml b/data/npc/theodore_loveless.xml new file mode 100644 index 00000000000..c61d6de7992 --- /dev/null +++ b/data/npc/theodore_loveless.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/thomas.xml b/data/npc/thomas.xml new file mode 100644 index 00000000000..c957b74886e --- /dev/null +++ b/data/npc/thomas.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + diff --git a/data/npc/thorgrin.xml b/data/npc/thorgrin.xml new file mode 100644 index 00000000000..8e66b852c76 --- /dev/null +++ b/data/npc/thorgrin.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/thorwulf.xml b/data/npc/thorwulf.xml new file mode 100644 index 00000000000..702970cb567 --- /dev/null +++ b/data/npc/thorwulf.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/tibra.xml b/data/npc/tibra.xml new file mode 100644 index 00000000000..5b2367020db --- /dev/null +++ b/data/npc/tibra.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/tigo.xml b/data/npc/tigo.xml new file mode 100644 index 00000000000..feb9f3e2a5b --- /dev/null +++ b/data/npc/tigo.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/tim_the_guard.xml b/data/npc/tim_the_guard.xml new file mode 100644 index 00000000000..bc293eebc73 --- /dev/null +++ b/data/npc/tim_the_guard.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/timothy.xml b/data/npc/timothy.xml new file mode 100644 index 00000000000..bbb849e9658 --- /dev/null +++ b/data/npc/timothy.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/timur.xml b/data/npc/timur.xml new file mode 100644 index 00000000000..502480af869 --- /dev/null +++ b/data/npc/timur.xml @@ -0,0 +1,50 @@ + + + + + + + + + + diff --git a/data/npc/tired_tree.xml b/data/npc/tired_tree.xml new file mode 100644 index 00000000000..548dd07cf50 --- /dev/null +++ b/data/npc/tired_tree.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/todd.xml b/data/npc/todd.xml new file mode 100644 index 00000000000..fe6fc82d7ab --- /dev/null +++ b/data/npc/todd.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/data/npc/tokel.xml b/data/npc/tokel.xml new file mode 100644 index 00000000000..905791e6130 --- /dev/null +++ b/data/npc/tokel.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + diff --git a/data/npc/tom.xml b/data/npc/tom.xml new file mode 100644 index 00000000000..47be66fbbf8 --- /dev/null +++ b/data/npc/tom.xml @@ -0,0 +1,26 @@ + + + + + + + + + diff --git a/data/npc/tomruk_the_ruddy.xml b/data/npc/tomruk_the_ruddy.xml new file mode 100644 index 00000000000..ce943dd7936 --- /dev/null +++ b/data/npc/tomruk_the_ruddy.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/tony.xml b/data/npc/tony.xml new file mode 100644 index 00000000000..40cb04a8729 --- /dev/null +++ b/data/npc/tony.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/tooth_fairy.xml b/data/npc/tooth_fairy.xml new file mode 100644 index 00000000000..40d7f340566 --- /dev/null +++ b/data/npc/tooth_fairy.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/toothless_tim.xml b/data/npc/toothless_tim.xml new file mode 100644 index 00000000000..96ee75590cb --- /dev/null +++ b/data/npc/toothless_tim.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/topsy.xml b/data/npc/topsy.xml new file mode 100644 index 00000000000..98b0d6cc213 --- /dev/null +++ b/data/npc/topsy.xml @@ -0,0 +1,59 @@ + + + + + + + + + + diff --git a/data/npc/torence.xml b/data/npc/torence.xml new file mode 100644 index 00000000000..ec0492e6533 --- /dev/null +++ b/data/npc/torence.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/tothdral.xml b/data/npc/tothdral.xml new file mode 100644 index 00000000000..0f718f46398 --- /dev/null +++ b/data/npc/tothdral.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + diff --git a/data/npc/towncryer.xml b/data/npc/towncryer.xml new file mode 100644 index 00000000000..e1b9da667f5 --- /dev/null +++ b/data/npc/towncryer.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/trimegis.xml b/data/npc/trimegis.xml new file mode 100644 index 00000000000..e8c964b92e1 --- /dev/null +++ b/data/npc/trimegis.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/trisha.xml b/data/npc/trisha.xml new file mode 100644 index 00000000000..2dfec23202d --- /dev/null +++ b/data/npc/trisha.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/tristan.xml b/data/npc/tristan.xml new file mode 100644 index 00000000000..fbeb6357c43 --- /dev/null +++ b/data/npc/tristan.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/tulf.xml b/data/npc/tulf.xml new file mode 100644 index 00000000000..ff91c01c51e --- /dev/null +++ b/data/npc/tulf.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/turvy.xml b/data/npc/turvy.xml new file mode 100644 index 00000000000..986e0d16241 --- /dev/null +++ b/data/npc/turvy.xml @@ -0,0 +1,136 @@ + + + + + + + + + + diff --git a/data/npc/tylius.xml b/data/npc/tylius.xml new file mode 100644 index 00000000000..fec94bafa7a --- /dev/null +++ b/data/npc/tylius.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/tyrias.xml b/data/npc/tyrias.xml new file mode 100644 index 00000000000..18ed4a575b3 --- /dev/null +++ b/data/npc/tyrias.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ubaid.xml b/data/npc/ubaid.xml new file mode 100644 index 00000000000..3f41f75243e --- /dev/null +++ b/data/npc/ubaid.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ukea.xml b/data/npc/ukea.xml new file mode 100644 index 00000000000..d9cd44b3f7e --- /dev/null +++ b/data/npc/ukea.xml @@ -0,0 +1,94 @@ + + + + + + + + + diff --git a/data/npc/ula.xml b/data/npc/ula.xml new file mode 100644 index 00000000000..8cf1e02a48d --- /dev/null +++ b/data/npc/ula.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ulala.xml b/data/npc/ulala.xml new file mode 100644 index 00000000000..3e4f7d5d93b --- /dev/null +++ b/data/npc/ulala.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/ulrik.xml b/data/npc/ulrik.xml new file mode 100644 index 00000000000..212ab990024 --- /dev/null +++ b/data/npc/ulrik.xml @@ -0,0 +1,125 @@ + + + + + + + + + + diff --git a/data/npc/umar.xml b/data/npc/umar.xml new file mode 100644 index 00000000000..3260e7afbcc --- /dev/null +++ b/data/npc/umar.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/uncle.xml b/data/npc/uncle.xml new file mode 100644 index 00000000000..8910b9c8559 --- /dev/null +++ b/data/npc/uncle.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/undal.xml b/data/npc/undal.xml new file mode 100644 index 00000000000..459c93779f4 --- /dev/null +++ b/data/npc/undal.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/urkalio.xml b/data/npc/urkalio.xml new file mode 100644 index 00000000000..053b4225e6e --- /dev/null +++ b/data/npc/urkalio.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + diff --git a/data/npc/ursula.xml b/data/npc/ursula.xml new file mode 100644 index 00000000000..87d129a2230 --- /dev/null +++ b/data/npc/ursula.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/uso.xml b/data/npc/uso.xml new file mode 100644 index 00000000000..31ac4f8108e --- /dev/null +++ b/data/npc/uso.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/ustan.xml b/data/npc/ustan.xml new file mode 100644 index 00000000000..a42ab41b744 --- /dev/null +++ b/data/npc/ustan.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + diff --git a/data/npc/uzgod.xml b/data/npc/uzgod.xml new file mode 100644 index 00000000000..95551220151 --- /dev/null +++ b/data/npc/uzgod.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + diff --git a/data/npc/uzon.xml b/data/npc/uzon.xml new file mode 100644 index 00000000000..830bbe6091f --- /dev/null +++ b/data/npc/uzon.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/vad_inchi.xml b/data/npc/vad_inchi.xml new file mode 100644 index 00000000000..157473d6e04 --- /dev/null +++ b/data/npc/vad_inchi.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/valentina.xml b/data/npc/valentina.xml new file mode 100644 index 00000000000..a0cbcebe48a --- /dev/null +++ b/data/npc/valentina.xml @@ -0,0 +1,17 @@ + + + + + + + + + diff --git a/data/npc/valindara.xml b/data/npc/valindara.xml new file mode 100644 index 00000000000..d1591f0cdcc --- /dev/null +++ b/data/npc/valindara.xml @@ -0,0 +1,151 @@ + + + + + + + + + + diff --git a/data/npc/vanys.xml b/data/npc/vanys.xml new file mode 100644 index 00000000000..6b072a34f35 --- /dev/null +++ b/data/npc/vanys.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/vascalir.xml b/data/npc/vascalir.xml new file mode 100644 index 00000000000..3260fe3b5cb --- /dev/null +++ b/data/npc/vascalir.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/velvet.xml b/data/npc/velvet.xml new file mode 100644 index 00000000000..088bfab9a72 --- /dev/null +++ b/data/npc/velvet.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + diff --git a/data/npc/vera.xml b/data/npc/vera.xml new file mode 100644 index 00000000000..859838da37b --- /dev/null +++ b/data/npc/vera.xml @@ -0,0 +1,94 @@ + + + + + + + + + diff --git a/data/npc/vescu.xml b/data/npc/vescu.xml new file mode 100644 index 00000000000..c76df03fdf6 --- /dev/null +++ b/data/npc/vescu.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/victor.xml b/data/npc/victor.xml new file mode 100644 index 00000000000..40d0c08bc55 --- /dev/null +++ b/data/npc/victor.xml @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/data/npc/vigintius.xml b/data/npc/vigintius.xml new file mode 100644 index 00000000000..40e9450ee9e --- /dev/null +++ b/data/npc/vigintius.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/vincent.xml b/data/npc/vincent.xml new file mode 100644 index 00000000000..25a56a4732f --- /dev/null +++ b/data/npc/vincent.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + diff --git a/data/npc/virgil.xml b/data/npc/virgil.xml new file mode 100644 index 00000000000..51f335483a4 --- /dev/null +++ b/data/npc/virgil.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/vladruc.xml b/data/npc/vladruc.xml new file mode 100644 index 00000000000..147bf187d9e --- /dev/null +++ b/data/npc/vladruc.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/vulturenose.xml b/data/npc/vulturenose.xml new file mode 100644 index 00000000000..b05e5d911dc --- /dev/null +++ b/data/npc/vulturenose.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/vuzrog.xml b/data/npc/vuzrog.xml new file mode 100644 index 00000000000..c6dd493fd26 --- /dev/null +++ b/data/npc/vuzrog.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/wally.xml b/data/npc/wally.xml new file mode 100644 index 00000000000..268f5c805f7 --- /dev/null +++ b/data/npc/wally.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + diff --git a/data/npc/walter_the_guard.xml b/data/npc/walter_the_guard.xml new file mode 100644 index 00000000000..4e841f0a710 --- /dev/null +++ b/data/npc/walter_the_guard.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/data/npc/warbert.xml b/data/npc/warbert.xml new file mode 100644 index 00000000000..e7afbbb6cdf --- /dev/null +++ b/data/npc/warbert.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/data/npc/weaponmaster.xml b/data/npc/weaponmaster.xml new file mode 100644 index 00000000000..cc8b276439f --- /dev/null +++ b/data/npc/weaponmaster.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/wentworth.xml b/data/npc/wentworth.xml new file mode 100644 index 00000000000..927168a73fa --- /dev/null +++ b/data/npc/wentworth.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/wesley.xml b/data/npc/wesley.xml new file mode 100644 index 00000000000..f2424e9cd13 --- /dev/null +++ b/data/npc/wesley.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/willard.xml b/data/npc/willard.xml new file mode 100644 index 00000000000..563affa1918 --- /dev/null +++ b/data/npc/willard.xml @@ -0,0 +1,168 @@ + + + + + + + + + + diff --git a/data/npc/willem.xml b/data/npc/willem.xml new file mode 100644 index 00000000000..3e2af6ad33d --- /dev/null +++ b/data/npc/willem.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/william.xml b/data/npc/william.xml new file mode 100644 index 00000000000..d9b6e1a9daf --- /dev/null +++ b/data/npc/william.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/willie.xml b/data/npc/willie.xml new file mode 100644 index 00000000000..5de663e7883 --- /dev/null +++ b/data/npc/willie.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/willow.xml b/data/npc/willow.xml new file mode 100644 index 00000000000..402dd7a0698 --- /dev/null +++ b/data/npc/willow.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/woblin.xml b/data/npc/woblin.xml new file mode 100644 index 00000000000..e68092b4d92 --- /dev/null +++ b/data/npc/woblin.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/wyat.xml b/data/npc/wyat.xml new file mode 100644 index 00000000000..4f95e35037c --- /dev/null +++ b/data/npc/wyat.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/data/npc/wyda.xml b/data/npc/wyda.xml new file mode 100644 index 00000000000..e58e05df292 --- /dev/null +++ b/data/npc/wyda.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/wyrdin.xml b/data/npc/wyrdin.xml new file mode 100644 index 00000000000..237e47a956a --- /dev/null +++ b/data/npc/wyrdin.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/xed.xml b/data/npc/xed.xml new file mode 100644 index 00000000000..b2176af5715 --- /dev/null +++ b/data/npc/xed.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data/npc/xelvar.xml b/data/npc/xelvar.xml new file mode 100644 index 00000000000..8529dcae73f --- /dev/null +++ b/data/npc/xelvar.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/npc/xodet.xml b/data/npc/xodet.xml new file mode 100644 index 00000000000..cf1cab378a5 --- /dev/null +++ b/data/npc/xodet.xml @@ -0,0 +1,59 @@ + + + + + + + + + + diff --git a/data/npc/xorlosh.xml b/data/npc/xorlosh.xml new file mode 100644 index 00000000000..385410525e2 --- /dev/null +++ b/data/npc/xorlosh.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/yalahari_npc.xml b/data/npc/yalahari_npc.xml new file mode 100644 index 00000000000..a0087d82d75 --- /dev/null +++ b/data/npc/yalahari_npc.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/data/npc/yaman.xml b/data/npc/yaman.xml new file mode 100644 index 00000000000..0828d7c3210 --- /dev/null +++ b/data/npc/yaman.xml @@ -0,0 +1,42 @@ + + + + + + + + + + diff --git a/data/npc/yana.xml b/data/npc/yana.xml new file mode 100644 index 00000000000..8f3580cf90f --- /dev/null +++ b/data/npc/yana.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/yanni.xml b/data/npc/yanni.xml new file mode 100644 index 00000000000..751a0ea2216 --- /dev/null +++ b/data/npc/yanni.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + diff --git a/data/npc/yasir.xml b/data/npc/yasir.xml new file mode 100644 index 00000000000..3713d652251 --- /dev/null +++ b/data/npc/yasir.xml @@ -0,0 +1,573 @@ + + + + + + + + + + diff --git a/data/npc/yawno.xml b/data/npc/yawno.xml new file mode 100644 index 00000000000..29c3f5d1666 --- /dev/null +++ b/data/npc/yawno.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/npc/yberius.xml b/data/npc/yberius.xml new file mode 100644 index 00000000000..391a641912e --- /dev/null +++ b/data/npc/yberius.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/yoem.xml b/data/npc/yoem.xml new file mode 100644 index 00000000000..663cdfb2eb3 --- /dev/null +++ b/data/npc/yoem.xml @@ -0,0 +1,94 @@ + + + + + + + + + diff --git a/data/npc/yonan.xml b/data/npc/yonan.xml new file mode 100644 index 00000000000..2d9602a01e1 --- /dev/null +++ b/data/npc/yonan.xml @@ -0,0 +1,73 @@ + + + + + + + + + + diff --git a/data/npc/yulas.xml b/data/npc/yulas.xml new file mode 100644 index 00000000000..9978eacaa74 --- /dev/null +++ b/data/npc/yulas.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + diff --git a/data/npc/zaidal.xml b/data/npc/zaidal.xml new file mode 100644 index 00000000000..9d858ba0d40 --- /dev/null +++ b/data/npc/zaidal.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + diff --git a/data/npc/zalamon.xml b/data/npc/zalamon.xml new file mode 100644 index 00000000000..9d806be3781 --- /dev/null +++ b/data/npc/zalamon.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/zarak.xml b/data/npc/zarak.xml new file mode 100644 index 00000000000..ce09ff18332 --- /dev/null +++ b/data/npc/zarak.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/zarifan.xml b/data/npc/zarifan.xml new file mode 100644 index 00000000000..b1c35b79231 --- /dev/null +++ b/data/npc/zarifan.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/zebron.xml b/data/npc/zebron.xml new file mode 100644 index 00000000000..56b90fa4e52 --- /dev/null +++ b/data/npc/zebron.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/zedrulon_the_fallen.xml b/data/npc/zedrulon_the_fallen.xml new file mode 100644 index 00000000000..0b5ab76f49e --- /dev/null +++ b/data/npc/zedrulon_the_fallen.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/zerbrus.xml b/data/npc/zerbrus.xml new file mode 100644 index 00000000000..d1817c171f7 --- /dev/null +++ b/data/npc/zerbrus.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/zeronex.xml b/data/npc/zeronex.xml new file mode 100644 index 00000000000..61fda556626 --- /dev/null +++ b/data/npc/zeronex.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/zethra.xml b/data/npc/zethra.xml new file mode 100644 index 00000000000..942720d8941 --- /dev/null +++ b/data/npc/zethra.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/zirella.xml b/data/npc/zirella.xml new file mode 100644 index 00000000000..18cdd9725cd --- /dev/null +++ b/data/npc/zirella.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/zirkon.xml b/data/npc/zirkon.xml new file mode 100644 index 00000000000..85259273c5d --- /dev/null +++ b/data/npc/zirkon.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/zizzle.xml b/data/npc/zizzle.xml new file mode 100644 index 00000000000..7daa8d06efc --- /dev/null +++ b/data/npc/zizzle.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/zlak.xml b/data/npc/zlak.xml new file mode 100644 index 00000000000..622bc2a5af7 --- /dev/null +++ b/data/npc/zlak.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/znozel.xml b/data/npc/znozel.xml new file mode 100644 index 00000000000..3171b868ea0 --- /dev/null +++ b/data/npc/znozel.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/zoltan.xml b/data/npc/zoltan.xml new file mode 100644 index 00000000000..0f1787d6cee --- /dev/null +++ b/data/npc/zoltan.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/npc/zora.xml b/data/npc/zora.xml new file mode 100644 index 00000000000..ccef4b2f37d --- /dev/null +++ b/data/npc/zora.xml @@ -0,0 +1,52 @@ + + + + + + + + + + diff --git a/data/npc/ztiss.xml b/data/npc/ztiss.xml new file mode 100644 index 00000000000..3d7f8b1ff0e --- /dev/null +++ b/data/npc/ztiss.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/zuma_magehide.xml b/data/npc/zuma_magehide.xml new file mode 100644 index 00000000000..316c9455080 --- /dev/null +++ b/data/npc/zuma_magehide.xml @@ -0,0 +1,28 @@ + + + + + + + + + diff --git a/data/npc/zumtah.xml b/data/npc/zumtah.xml new file mode 100644 index 00000000000..03e072c9382 --- /dev/null +++ b/data/npc/zumtah.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/zurak.xml b/data/npc/zurak.xml new file mode 100644 index 00000000000..f1e8640ab6c --- /dev/null +++ b/data/npc/zurak.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npc/zurakarena.xml b/data/npc/zurakarena.xml new file mode 100644 index 00000000000..d588dc445d7 --- /dev/null +++ b/data/npc/zurakarena.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/npclua/a_bearded_woman.lua b/data/npclua/a_bearded_woman.lua new file mode 100644 index 00000000000..ad4802f5257 --- /dev/null +++ b/data/npclua/a_bearded_woman.lua @@ -0,0 +1,127 @@ +local npcType = Game.createNpcType("A Bearded Woman") +local npcConfig = {} + +npcConfig.description = "A Bearded Woman" + +npcConfig.health = 100 +npcConfig.maxHealth = npcConfig.health +npcConfig.walkInterval = 2000 +npcConfig.walkRadius = 2 + +npcConfig.outfit = { + lookType = 140, + lookHead = 60, + lookBody = 22, + lookLegs = 24, + lookFeet = 32, + lookAddons = 1 +} + +npcConfig.voices = { + interval = 2000, + chance = 20, + { text = 'I am a MAN! Get me out you drunken fools!' }, + { text = 'GET ME OUT OF HERE!' }, + { text = 'Get me out! It was all part of the plan, you fools!' }, + { text = 'If I ever get out of here, I\'ll kill you all! All of you!' }, + { text = 'I am NOT Princess Lumelia, you fools!' }, + { text = 'Get a locksmith and free me or you will regret it, you foolish pirates!' }, + { text = 'I am not a princess, I am an actor!' } +} + +npcConfig.flags = { + hostile = false, + floorchange = false +} + +npcType.onThink = function(npc, interval) +end + +npcType.onAppear = function(npc, creature) +end + +npcType.onDisappear = function(npc, creature) +end + +npcType.onMove = function(npc, creature, fromPosition, toPosition) +end + +local interactions = { + NpcInteraction:createGreetInteraction("GET ME OUT OF HERE! NOW!"), + NpcInteraction:createReplyInteraction({"job"}, "I am a great and famous actor! Not a princess, at all. I was only PRETENDING to be a princess. But try explaining that to those stupid pirates."), + NpcInteraction:createReplyInteraction({"actor", "stage"}, "Stage acting was a waste of my immense talent. Not only am I a born leader, my talent is more profitable when it is used for conning people."), + NpcInteraction:createReplyInteraction({"kid"}, "He was always a fool with a heart too soft to become a feared pirate"), + NpcInteraction:createReplyInteraction({"princess"}, "Me playing a princess was just part of a cunning plan we had"), + NpcInteraction:createReplyInteraction({"cell"}, "If you find some way to release me I might even let you live as reward! So you'd better do your best or I'll kill you!"), + NpcInteraction:createReplyInteraction({"name"}, "How dare you? I left to rot in this dirty cell and you have nothing better to do than chit chat?"), + NpcInteraction:createReplyInteraction({"rot"}, "YOU .. YOU .. You are as good as dead! I will get you! Do you hear me? I will have your head! On a platter!"), + NpcInteraction:createReplyInteraction( + {"pirate"}, + { + "In a just world, I would be captain of a grand ship, ...", + "Those pirates out there would now be my minions, and we would brave the seas and become the terror of the coastal towns! ...", + "If only our plan had worked!" + }), + NpcInteraction:createReplyInteraction( + {"ship"}, + { + "Captain Kid sold his ship to buy pointless things like those insanely expensive locks for the cell doors. ...", + "He said the canoes would do for a while. ...", + "I got the impression he was not overly sad to part with the ship because he was known to suffer a lot from seasickness." + }), + NpcInteraction:createReplyInteraction( + {"captain"}, + { + "I'd have been a much better captain then Kid was. I played several captains on stage and I was good! ...", + "Where Kid longed for the appreciation of his men, I would rule by fear and with an iron fist!" + }), + NpcInteraction:createReplyInteraction( + {"plan"}, + { + "It was all captain Kid's idea. You see, he hated his name and planned to become known by the name captain Kidnap. ...", + "All he needed was someone famous to kidnap. ...", + "Given his men's dismal lack of talent and intelligence that would have been quite a feat. ...", + "We knew each other from a few scams we did together in the past, so he contacted me. ...", + "I was to impersonate the famous Princess Lumelia. You know, the one everyone was looking for. ...", + "That would show his men and the other pirates what a great kidnapper he was. ...", + "He promised me that I would become his second in command and lead a wonderful life of plundering, robbing and pillaging. ...", + "So I agreed to impersonate the Princess for a while and it worked fine at first. ...", + "He returned with me dressed as the Princess from a raid on his own and was instantaneously the hero of the day for his men. ...", + "Things went bad when they decided to have a victory party. ...", + "As far as I could make out from the mumblings of the pirates, Kid lost the key to my cell while relieving himself in the underground river. ...", + "The fool decided to dive after it .. never to be seen again. ...", + "When I found out about Kid's demise I tried to convince the pirates it was a hoax, but they just won't believe me!" + }), + NpcInteraction:createReplyInteraction( + {"kidnap"}, + { + "Ah kidnapping is so much fun. That is, if you're not on the receiving end. ...", + "It's easy money and you have a chance to frighten and torture someone who can't fight back!" + }), + NpcInteraction:createReplyInteraction( + {"scams"}, + { + "The more stupid the people are, the easier it is to con them. ...", + "And the poorer they are the less means they have to get revenge. Har Har! ...", + "So I make sure I ruin those I scam. Then they have other things to worry about than getting revenge on me." + }), + NpcInteraction:createReplyInteraction( + {"key"}, + { + "The key was lost in the underground river and has probably washed into the seven seas by now! ...", + "If that stupid Kid hadn't been so obsessed with kidnapping he'd not have sold his ship to buy the most expensive and complicated locks for his cells!" + }), + NpcInteraction:createReplyInteraction( + {"plundering"}, + { + "As long as we stick to undefended coastal towns we can make an easy fortune. Har Har! ...", + "As soon as I get out of here I'll finally become a pirate captain on my own. I don't need Captain Kid!" + }), + NpcInteraction:createFarewellInteraction(), +} + +npcType.onSay = function(npc, creature, type, message) + return npc:processOnSay(message, creature, interactions) +end + +npcType:register(npcConfig) diff --git a/data/npclua/a_beautiful_girl.lua b/data/npclua/a_beautiful_girl.lua new file mode 100644 index 00000000000..39aec11e4f8 --- /dev/null +++ b/data/npclua/a_beautiful_girl.lua @@ -0,0 +1,46 @@ +local npcType = Game.createNpcType("A Beautiful Girl") +local npcConfig = {} + +npcConfig.description = "A Beautiful Girl" + +npcConfig.health = 100 +npcConfig.maxHealth = npcConfig.health +npcConfig.walkInterval = 2000 +npcConfig.walkRadius = 2 + +npcConfig.outfit = { + lookType = 140, + lookHead = 77, + lookBody = 81, + lookLegs = 79, + lookFeet = 95, + lookAddons = 0 +} + +npcConfig.flags = { + hostile = false, + floorchange = false +} + +npcType.onThink = function(npc, interval) +end + +npcType.onAppear = function(npc, creature) +end + +npcType.onDisappear = function(npc, creature) +end + +npcType.onMove = function(npc, creature, fromPosition, toPosition) +end + +local interactions = { + NpcInteraction:createGreetInteraction("So you have come, %s. I hoped you would not..."), + NpcInteraction:createFarewellInteraction(), +} + +npcType.onSay = function(npc, creature, type, message) + return npc:processOnSay(message, creature, interactions) +end + +npcType:register(npcConfig) diff --git a/data/npclua/a_beggar.lua b/data/npclua/a_beggar.lua new file mode 100644 index 00000000000..ec310aa381d --- /dev/null +++ b/data/npclua/a_beggar.lua @@ -0,0 +1,82 @@ +local npcType = Game.createNpcType("A Beggar") +local npcConfig = {} + +npcConfig.description = "A Beggar" + +npcConfig.health = 100 +npcConfig.maxHealth = npcConfig.health +npcConfig.walkInterval = 2000 +npcConfig.walkRadius = 2 + +npcConfig.outfit = { + lookType = 153, + lookHead = 39, + lookBody = 39, + lookLegs = 39, + lookFeet = 76, + lookAddons = 0 +} + +npcConfig.flags = { + hostile = false, + floorchange = false +} + +npcType.onThink = function(npc, interval) +end + +npcType.onAppear = function(npc, creature) +end + +npcType.onDisappear = function(npc, creature) +end + +npcType.onMove = function(npc, creature, fromPosition, toPosition) +end + +local interactions = { + NpcInteraction:createGreetInteraction("Hi %s! What is it, what d'ye {want}?") + :addInitValidationProcessor( + PlayerProcessingConfigs:new() + :addStorage(Storage.DarkTrails.Mission01, 1) + ), + NpcInteraction:createGreetInteraction() + :addInitValidationProcessor( + PlayerProcessingConfigs:new() + :addStorage(Storage.DarkTrails.Mission01, 2) + ), + NpcInteraction:new( + {"want"}, + { + reply = "The guys from the magistrate sent you here, didn't they?", + confirmation = { + "Thought so. You'll have to talk to the king though. The beggar king that is. The king does not grant an audience to just everyone. You know how those kings are, don't you? ... ", + "However, to get an audience with the king, you'll have to help his subjects a bit. ... ", + "His subjects that would be us, the poor, you know? ... ", + "So why don't you show your dedication to the poor? Go and help Chavis at the poor house. He's collecting food for people like us. ... ", + "If you brought enough of the stuff you'll see that the king will grant you entrance in his {palace}." + }, + }, + {current = 1, previous = 0} + ):addSubInteraction( + NpcInteraction:createReplyInteraction( + {"yes"}, + nil, + {current = 0, previous = 1} + ):addCompletionUpdateProcessor( + PlayerProcessingConfigs:new() + :addStorage(Storage.DarkTrails.Mission01, 2) + :addStorage(Storage.DarkTrails.Mission02, 1) + ) + ):addInitValidationProcessor( + PlayerProcessingConfigs:new() + :addStorage(Storage.DarkTrails.Mission01, 1) + ), + NpcInteraction:createFarewellInteraction(), +} + +npcType.onSay = function(npc, creature, type, message) + return npc:processOnSay(message, creature, interactions) +end + +npcType:register(npcConfig) diff --git a/data/npclua/a_sweaty_cyclops.lua b/data/npclua/a_sweaty_cyclops.lua new file mode 100644 index 00000000000..a5742c3c312 --- /dev/null +++ b/data/npclua/a_sweaty_cyclops.lua @@ -0,0 +1,241 @@ +local npcType = Game.createNpcType("A Sweaty Cyclops") +local npcConfig = {} + +npcConfig.description = "A Sweaty Cyclops" + +npcConfig.health = 100 +npcConfig.maxHealth = npcConfig.health +npcConfig.walkInterval = 2000 +npcConfig.walkRadius = 0 + +npcConfig.outfit = { lookType = 22 } + +npcConfig.voices = { + interval = 2000, + chance = 20, + { text = 'Hum hum, huhum' }, + { text = 'Silly lil\' human' }, +} + +npcConfig.flags = { + floorchange = false +} + +local craftConfigs = { + ["uth'kean"] = { item = 2487, metal = 5887, message = "Very noble. Shiny. Me like. But breaks so fast. Me can make from shiny armour. Lil' one want to trade?" }, + ["uth'lokr"] = { item = 2516, metal = 5889, message = "Firy steel it is. Need green ones' breath to melt. Or red even better. Me can make from shield. Lil' one want to trade?" }, + ["uth'prta"] = { item = 2393, metal = 5892, message = "Good iron is. Me friends use it much for fight. Me can make from weapon. Lil' one want to trade?" }, + ["za'ralator"] = { item = 2462, metal = 5888, message = "Hellsteel is. Cursed and evil. Dangerous to work with. Me can make from evil helmet. Lil' one want to trade?" }, + ["soul orb"] = { item = 5944, metal = 6529, message = "Uh. Me can make some nasty lil' bolt from soul orbs. Lil' one want to trade all?" }, +} + +local getCraftInteractions = function (craftConfigs) + local craftInteractions = {} + local topic = 4 + + for index, craftConfig in pairs(craftConfigs) do + craftInteractions[#craftInteractions + 1] = NpcInteraction:createReplyInteraction( + {index}, craftConfig.message, {current = 1, previous = 0} + ):addInitValidationProcessor( + PlayerProcessingConfigs:new():addStorage(Storage.FriendsandTraders.TheSweatyCyclops, 0, ConfigsTypes.CONFIG_LTE) + ) + + if index ~= "soul orb" then + craftInteractions[#craftInteractions + 1] = NpcInteraction:createConfirmationInteraction( + {index}, + { + reply = craftConfig.message, + confirmation = "Cling clang!", + }, + topic + ):addInitValidationProcessor( + PlayerProcessingConfigs:new() + :addStorage(Storage.FriendsandTraders.TheSweatyCyclops, 2) + ):addCompletionValidationProcessor( + PlayerProcessingConfigs:new():addItem(craftConfig.item, 1) + ):addCompletionUpdateProcessor( + PlayerProcessingConfigs:new():addItem(craftConfig.item, -1):addItem(craftConfig.metal, 1) + ) + + topic = topic + 1 + end + end + + return craftInteractions +end + +local interactions = { + NpcInteraction:createGreetInteraction("Hum Humm! Welcume lil' %s"), + NpcInteraction:createReplyInteraction({'job'}, "I am smith."), + NpcInteraction:createReplyInteraction({'smith'}, "Working steel is my profession."), + NpcInteraction:createReplyInteraction({'steel'}, "Manny kinds of. Like {Mesh Kaha Rogh'}, {Za'Kalortith}, {Uth'Byth}, {Uth'Morc}, {Uth'Amon}, {Uth'Maer}, {Uth'Doon}, and {Zatragil}."), + NpcInteraction:createReplyInteraction({'zatragil'}, "Most ancients use dream silver for different stuff. Now ancients most gone. Most not know about."), + NpcInteraction:createReplyInteraction({'uth\'doon'}, "It's high steel called. Only lil' lil' ones know how make."), + NpcInteraction:createReplyInteraction({'za\'kalortith'}, "It's evil. Demon iron is. No good cyclops goes where you can find and need evil flame to melt."), + NpcInteraction:createReplyInteraction({'mesh kaha rogh'}, "Steel that is singing when forged. No one knows where find today."), + NpcInteraction:createReplyInteraction({'uth\'byth'}, "Not good to make stuff off. Bad steel it is. But eating magic, so useful is."), + NpcInteraction:createReplyInteraction({'uth\'maer'}, "Brightsteel is. Much art made with it. Sorcerers too lazy and afraid to enchant much."), + NpcInteraction:createReplyInteraction({'uth\'amon'}, "Heartiron from heart of big old mountain, found very deep. Lil' lil ones fiercely defend. Not wanting to have it used for stuff but holy stuff."), + NpcInteraction:createReplyInteraction({'ab\'dendriel'}, "Me parents live here before town was. Me not care about lil' ones."), + NpcInteraction:createReplyInteraction({'lil\' lil\''}, "Lil' lil' ones are so fun. We often chat."), + NpcInteraction:createReplyInteraction({'tibia'}, "One day I'll go and look."), + NpcInteraction:createReplyInteraction({'teshial'}, "Is one of elven family or such thing. Me not understand lil' ones and their business."), + NpcInteraction:createReplyInteraction({'cenath'}, "Is one of elven family or such thing. Me not understand lil' ones and their business."), + NpcInteraction:createReplyInteraction({'name'}, "I called Bencthyclthrtrprr by me people. Lil' ones me call Big Ben."), + NpcInteraction:createReplyInteraction({'god'}, "You shut up. Me not want to hear."), + NpcInteraction:createReplyInteraction({'fire sword'}, "Do lil' one want to trade a fire sword?"), + NpcInteraction:createReplyInteraction({'dragon shield'}, "Do lil' one want to trade a dragon shield?"), + NpcInteraction:createReplyInteraction({'sword of valor'}, "Do lil' one want to trade a sword of valor?"), + NpcInteraction:createReplyInteraction({'warlord sword'}, "Do lil' one want to trade a warlord sword?"), + NpcInteraction:createReplyInteraction({'minotaurs'}, "They were friend with me parents. Long before elves here, they often made visit. No longer come here."), + NpcInteraction:createReplyInteraction({'elves'}, "Me not fight them, they not fight me."), + NpcInteraction:createReplyInteraction({'excalibug'}, "Me wish I could make weapon like it."), + NpcInteraction:createReplyInteraction({'cyclops'}, "Me people not live here much. Most are far away."), + NpcInteraction:createFarewellInteraction("Good bye lil' one"), + NpcInteraction:createReplyInteraction( + {'yes'}, + "Wait. Me work no cheap is. Do favour for me first, yes?", + {current = 2, previous = 1} + ), + NpcInteraction:createReplyInteraction( + {'yes'}, + "Me need gift for woman. We dance, so me want to give her bast skirt. But she big is. So I need many to make big one. Bring three okay? Me wait.", + {current = 0, previous = 2} + ):addInitUpdateProcessor( + PlayerProcessingConfigs:new() + :addStorage(Storage.FriendsandTraders.DefaultStart, 1) + :addStorage(Storage.FriendsandTraders.TheSweatyCyclops, 1) + ), + NpcInteraction:createConfirmationInteraction( + {"bast skirt", "uth'kean", "uth'prta", "uth'lokr", "za'ralator", "soul orb"}, + { + reply = "Lil' one bring three bast skirts?", + confirmation = "Good good! Woman happy will be. Now me happy too and help you.", + cannotExecute = "Lil' one does not have three bast skirts.", + }, + 3 + ):addInitValidationProcessor( + PlayerProcessingConfigs:new() + :addStorage(Storage.FriendsandTraders.TheSweatyCyclops, 1) + ):addCompletionValidationProcessor( + PlayerProcessingConfigs:new():addItem(3983, 3) + ):addCompletionUpdateProcessor( + PlayerProcessingConfigs:new():addItem(3983, -3) + :addStorage(Storage.FriendsandTraders.TheSweatyCyclops, 2) + ), + NpcInteraction:createConfirmationInteraction( + {"soul orb"}, + { + reply = craftConfigs["soul orb"].message, + confirmation = "Cling clang!", + cannotExecute = "Lil' one does not have soul orbs!", + }, + 8 + ):addInitValidationProcessor( + PlayerProcessingConfigs:new() + :addStorage(Storage.FriendsandTraders.TheSweatyCyclops, 2) + ):addCompletionValidationProcessor( + PlayerProcessingConfigs:new():addItem(5944, 1, ConfigsTypes.CONFIG_GTE) + ):addCompletionUpdateProcessor( + PlayerProcessingConfigs:new():addCallback( + function (player) + local total = player:getItemCount(5944) + for i = 1, total do + player:addItem(6529, 3 * math.random(1,2)) + player:removeItem(5944, 1) + end + end + ) + ), + NpcInteraction:createConfirmationInteraction( + {"melt"}, + { + reply = "Me can do unbroken but Big Ben want gold 5000 and Big Ben need a lil' time to make it unbroken. Yes or no??", + confirmation = "whoooosh There!", + cannotExecute = "There is no gold ingot with you.", + }, + 9 + ):addCompletionValidationProcessor( + PlayerProcessingConfigs:new():addItem(9971, 1) + ):addCompletionUpdateProcessor( + PlayerProcessingConfigs:new():addItem(9971, -1):addItem(13941, 1) + ), + NpcInteraction:createConfirmationInteraction( + {"amulet"}, + { + reply = "Can melt gold ingot for lil' one. You want?", + confirmation = "Well, well, I do that! Big Ben makes lil' amulet unbroken with big hammer in big hands! No worry! Come back after sun hits the horizon 24 times and ask me for amulet.", + }, + 10 + ):addInitValidationProcessor( + PlayerProcessingConfigs:new() + :addStorage(Storage.SweetyCyclops.AmuletStatus, 0, ConfigsTypes.CONFIG_LTE) + ):addCompletionValidationProcessor( + PlayerProcessingConfigs:new() + :addItem(8262, 1) + :addItem(8263, 1) + :addItem(8264, 1) + :addItem(8265, 1) + :addAmount(5000) + ):addCompletionUpdateProcessor( + PlayerProcessingConfigs:new() + :addItem(8262, -1) + :addItem(8263, -1) + :addItem(8264, -1) + :addItem(8265, -1) + :removeAmount(5000) + :addStorage(Storage.SweetyCyclops.AmuletStatus, 1) + :addStorage(Storage.SweetyCyclops.AmuletTimer, os.time() + 24 * 60 * 60) + ), + NpcInteraction:createReplyInteraction( + {"amulet"}, + "Ahh, lil' one wants amulet. Here! Have it! Mighty, mighty amulet lil' one has. Don't know what but mighty, mighty it is!!!" + ):addInitValidationProcessor( + PlayerProcessingConfigs:new() + :addStorage(Storage.SweetyCyclops.AmuletStatus, 1) + :addStorage(Storage.SweetyCyclops.AmuletTimer, os.time(), ConfigsTypes.CONFIG_LTE) + ):addCompletionUpdateProcessor( + PlayerProcessingConfigs:new() + :addStorage(Storage.SweetyCyclops.AmuletStatus, 2) + :addItem(8266, 1) + ), + NpcInteraction:createConfirmationInteraction( + {"gear wheel"}, + { + reply = "Uh. Me can make some gear wheel from iron ores. Lil' one want to trade?", + confirmation = "Cling clang!", + cannotExecute = "Lil' one does not have any iron ores.", + }, + 11 + ):addInitValidationProcessor( + PlayerProcessingConfigs:new() + :addStorage(Storage.HiddenCityOfBeregar.GoingDown, 1, ConfigsTypes.CONFIG_GTE) + :addStorage(Storage.HiddenCityOfBeregar.GearWheel, 2, ConfigsTypes.CONFIG_LTE) + ):addCompletionValidationProcessor( + PlayerProcessingConfigs:new():addItem(5880, 1) + ):addCompletionUpdateProcessor( + PlayerProcessingConfigs:new() + -- Needs to do in way that we can increase storage + :addStorage(Storage.HiddenCityOfBeregar.GearWheel, 3) + :addItem(5880, -1) + :addItem(9690, 1) + ), +} + +npcType.onThink = function(npc, interval) +end + +npcType.onAppear = function(npc, creature) +end + +npcType.onDisappear = function(npc, creature) +end + +npcType.onMove = function(npc, creature, fromPosition, toPosition) +end + +npcType.onSay = function(npc, creature, type, message) + return npc:processOnSay(message, creature, table.concat(interactions, getCraftInteractions(craftConfigs))) +end + +npcType:register(npcConfig) diff --git a/data/npclua/black_bert.lua b/data/npclua/black_bert.lua new file mode 100644 index 00000000000..bd993ea6d79 --- /dev/null +++ b/data/npclua/black_bert.lua @@ -0,0 +1,153 @@ +local npcType = Game.createNpcType("Black Bert") +local npcConfig = {} + +npcConfig.description = "Black Bert" + +npcConfig.health = 100 +npcConfig.maxHealth = npcConfig.health +npcConfig.walkInterval = 2000 +npcConfig.walkRadius = 2 + +npcConfig.outfit = { + lookType = 151, + lookHead = 0, + lookBody = 38, + lookLegs = 19, + lookFeet = 76, + lookAddons = 0 +} + +npcConfig.flags = { + floorchange = false +} + +npcConfig.shop = { + {clientId = 123, buy = 16000, sell = 16000, count = 1}, + {clientId = 130, buy = 100, count = 1}, + {clientId = 135, buy = 5000, count = 1}, + {clientId = 138, buy = 600, count = 1}, + {clientId = 141, buy = 2000, count = 1}, + {clientId = 142, buy = 6000, count = 1}, + {clientId = 349, buy = 15000, count = 1}, + {clientId = 396, buy = 5000, count = 1}, + {clientId = 406, buy = 15000, count = 1}, + {clientId = 3216, buy = 8000, count = 1}, + {clientId = 3217, buy = 8000, count = 1}, + {clientId = 3232, buy = 3000, count = 1}, + {clientId = 3233, buy = 16000, count = 1}, + {clientId = 3234, buy = 150, count = 1}, + {clientId = 4827, buy = 18000, count = 1}, + {clientId = 4832, buy = 24000, count = 1}, + {clientId = 4834, buy = 1000, count = 1}, + {clientId = 4835, buy = 8000, count = 1}, + {clientId = 4836, buy = 15000, count = 1}, + {clientId = 4841, buy = 3000, count = 1}, + {clientId = 4843, buy = 500, count = 1}, + {clientId = 4846, buy = 4000, count = 1}, + {clientId = 4847, buy = 6000, count = 1}, + {clientId = 5940, buy = 10000, count = 1}, + {clientId = 6124, buy = 40000, count = 1}, + {clientId = 7281, buy = 500, count = 1}, + {clientId = 7924, buy = 10000, count = 1}, + {clientId = 7936, buy = 7000, count = 1}, + {clientId = 8453, buy = 50000, count = 1}, + {clientId = 8746, buy = 50000, count = 1}, + {clientId = 8818, buy = 8000, count = 1}, + {clientId = 8822, buy = 20000, count = 1}, + {clientId = 9107, buy = 600, count = 1}, + {clientId = 9188, buy = 5000, count = 1}, + {clientId = 9191, buy = 5000, count = 1}, + {clientId = 9236, buy = 10000, count = 1}, + {clientId = 9237, buy = 12500, count = 1}, + {clientId = 9238, buy = 17000, count = 1}, + {clientId = 9239, buy = 12500, count = 1}, + {clientId = 9240, buy = 13000, count = 1}, + {clientId = 9241, buy = 10000, count = 1}, + {clientId = 9247, buy = 13500, count = 1}, + {clientId = 9248, buy = 12500, count = 1}, + {clientId = 9249, buy = 13000, count = 1}, + {clientId = 9251, buy = 8000, count = 1}, + {clientId = 9252, buy = 13000, count = 1}, + {clientId = 9255, buy = 25000, count = 1}, + {clientId = 9308, buy = 5250, count = 1}, + {clientId = 9390, buy = 8500, count = 1}, + {clientId = 9391, buy = 10000, count = 1}, + {clientId = 9537, buy = 350, count = 1}, + {clientId = 9696, buy = 1000, count = 1}, + {clientId = 9698, buy = 1000, count = 1}, + {clientId = 9699, buy = 1000, count = 1}, + {clientId = 10009, buy = 700, count = 1}, + {clientId = 10011, buy = 650, count = 1}, + {clientId = 10025, buy = 600, count = 1}, + {clientId = 10028, buy = 666, count = 1}, + {clientId = 10183, buy = 1000, count = 1}, + {clientId = 10187, buy = 1000, count = 1}, + {clientId = 10189, buy = 1000, count = 1}, + {clientId = 11329, buy = 1000, count = 1}, + {clientId = 11339, buy = 550, count = 1}, + {clientId = 11341, buy = 1000, count = 1}, + {clientId = 11544, buy = 600, count = 1}, + {clientId = 11545, buy = 4000, count = 1}, + {clientId = 11546, buy = 4000, count = 1}, + {clientId = 11547, buy = 4000, count = 1}, + {clientId = 11548, buy = 4000, count = 1}, + {clientId = 11549, buy = 4000, count = 1}, + {clientId = 11550, buy = 4000, count = 1}, + {clientId = 11551, buy = 4000, count = 1}, + {clientId = 11552, buy = 4000, count = 1}, + {clientId = 13974, buy = 5000, count = 1}, + {clientId = 31414, buy = 50000, count = 1}, + {clientId = 31447, buy = 5000, count = 1} +} + +npcType.onThink = function(npc, interval) +end + +npcType.onAppear = function(npc, creature) +end + +npcType.onDisappear = function(npc, creature) +end + +npcType.onMove = function(npc, creature, fromPosition, toPosition) +end + +npcType.onPlayerBuyItem = function(npc, player, itemId, subType, amount, inBackpacks, name, totalCost) + npc:doSellItem(player, itemId, amount, subType, true, inBackpacks, 1988) + npc:talk(player, string.format("You've bought %i %s for %i", amount, name, totalCost)) +end + +npcType.onPlayerSellItem = function(npc, player, amount, name, totalCost, clientId) + npc:talk(player, string.format("You've sold %i %s for %i", amount, name, totalCost)) +end + +npcType.onPlayerCheckItem = function(npc, player, itemId) +end + +local interactions = { + NpcInteraction:createGreetInteraction("Hi there, %s! You look like you are eager to {trade}!"), + NpcInteraction:new( + {"trade"}, + { + cannotExecute = "I don't know you and I don't have any dealings with people whom I don't trust." + } + ):addCompletionValidationProcessor( + PlayerProcessingConfigs:new() + :addStorage(Storage.ThievesGuild.Mission08, 3) + ) + :addCompletionUpdateProcessor( + PlayerProcessingConfigs:new() + :addCallback(function (player, npc) npc:openShopWindow(player, 0) end) + ), + NpcInteraction:createFarewellInteraction() + :addCompletionUpdateProcessor( + PlayerProcessingConfigs:new() + :addCallback(function (player, npc) npc:closeShopWindow(player, 0) end) + ), +} + +npcType.onSay = function(npc, creature, type, message) + return npc:processOnSay(message, creature, interactions) +end + +npcType:register(npcConfig) \ No newline at end of file diff --git a/data/npclua/captain_bluebear.lua b/data/npclua/captain_bluebear.lua new file mode 100644 index 00000000000..a01bdaca9f5 --- /dev/null +++ b/data/npclua/captain_bluebear.lua @@ -0,0 +1,123 @@ +local npcType = Game.createNpcType("Captain Bluebear") +local npcConfig = {} + +npcConfig.description = "Captain Bluebear" + +npcConfig.health = 100 +npcConfig.maxHealth = npcConfig.health +npcConfig.walkInterval = 2000 +npcConfig.walkRadius = 0 + +npcConfig.outfit = { + lookType = 129, + lookHead = 19, + lookBody = 69, + lookLegs = 125, + lookFeet = 50, + lookAddons = 0 +} + +npcConfig.voices = { + interval = 2000, + chance = 20, + { text = 'Passages to Carlin, Ab\'Dendriel, Edron, Venore, Port Hope, Liberty Bay, Yalahar, Roshamuul, Krailos, Oramond and Svargrond.' } +} + +npcConfig.flags = { + floorchange = false +} + +local travelMessages = { + reply = "Do you seek a passage to %s for %s?", + confirmation = "Set the sails!", + cancellation = "We would like to serve you some time.", + cannotExecute = "I'm sorry but I don't sail there." +} + +local replyInteractions = { + NpcInteraction:createGreetInteraction("Welcome on board %s, Where can I {sail} you today?"), + NpcInteraction:createReplyInteraction({"name"}, "My name is Captain Bluebear from the Royal Tibia Line."), + NpcInteraction:createReplyInteraction({"job", "captain"}, "I am the captain of this sailing-ship."), + NpcInteraction:createReplyInteraction({"ship", "line", "company", "tibia"}, "The Royal Tibia Line connects all seaside towns of Tibia."), + NpcInteraction:createReplyInteraction({"good"}, "We can transport everything you want."), + NpcInteraction:createReplyInteraction({"passenger"}, ""), + NpcInteraction:createReplyInteraction({"trip", "route", "passage", "town", "destination", "sail", "go"}, "Where do you want to go? To {Carlin}, {Ab\'Dendriel}, {Venore}, {Port Hope}, {Liberty Bay}, {Svargrond}, {Yalahar}, {Roshamuul}, {Oramond} or {Edron}?"), + NpcInteraction:createReplyInteraction({"ice", "senja", "folda", "vega"}, "I\'m sorry, but we don\'t serve the routes to the Ice Islands."), + NpcInteraction:createReplyInteraction({"darashia", "darama"}, "I\'m not sailing there. This route is afflicted by a ghostship! However I\'ve heard that Captain Fearless from Venore sails there."), + NpcInteraction:createReplyInteraction({"ghost"}, "Many people who sailed to Darashia never returned because they were attacked by a ghostship! I\'ll never sail there!"), + NpcInteraction:createReplyInteraction({"thais"}, "This is Thais. Where do you want to go?"), + NpcInteraction:createFarewellInteraction("Good bye %s. Recommend us if you were satisfied with our service."), +} + +local destinations = { + -- TODO: Create TravelConfig class + { town = "carlin", baseCost = 110, position = Position(32387, 31820, 6), discounts = 'postman', + completionUpdaters = { + PlayerProcessingConfigs:new() + :addCallback( + function(player) + --[[ + we can simplify this by adding "validations" attribute + to the player processing that will make the processor only execute + if they run successfully. This is useful since we use this kind of + conditional updates everywhere. + + e.g. + completionUpdaters = { + PlayerProcessingConfigs:new():addValidation( + PlayerProcessingConfigs:new():addStorage(Storage.Postman.Mission01, 1) + ):addStorage(Storage.Postman.Mission01, 2) + } + ]]-- + if player:getStorageValue(Storage.Postman.Mission01) == 1 then + player:setStorageValue(Storage.Postman.Mission01, 2) + end + end + ) + }}, + { town = "ab'dendriel", baseCost = 130, position = Position(32734, 31668, 6), discounts = 'postman' }, + { town = "edron", baseCost = 160, position = Position(33175, 31764, 6), discounts = 'postman' }, + { town = "venore", baseCost = 170, position = Position(32954, 32022, 6), discounts = 'postman' }, + { town = "port hope", baseCost = 160, position = Position(32527, 32784, 6), discounts = 'postman' }, + { town = "roshamuul", baseCost = 210, position = Position(33494, 32567, 7), discounts = 'postman' }, + { town = "svargrond", baseCost = 180, position = Position(32341, 31108, 6), discounts = 'postman' }, + { town = "liberty bay", baseCost = 180, position = Position(32285, 32892, 6), discounts = 'postman' }, + { town = "oramond", baseCost = 150, position = Position(33479, 31985, 7), discounts = 'postman' }, + { town = "krailos", baseCost = 230, position = Position(33492, 31712, 6), discounts = 'postman' }, + { town = "yalahar", baseCost = 200, position = Position(32816, 31272, 6), discounts = 'postman', + completionValidations = { + PlayerProcessingConfigs:new() + :addStorage(Storage.SearoutesAroundYalahar.Thais, 1, ConfigsTypes.CONFIG_NEQ) + :addStorage(Storage.SearoutesAroundYalahar.TownsCounter, 4, ConfigsTypes.CONFIG_LTE) + } + }, +} + +local getTravelInteractions = function (player, destinations, baseMessages) + local travelInteractions = {} + + for index, travelConfigs in pairs(destinations) do + travelInteractions[#travelInteractions + 1] = NpcInteraction:createTravelInteraction(player, travelConfigs, baseMessages, index) + end + + return travelInteractions +end + +npcType.onThink = function(npc, interval) +end + +npcType.onAppear = function(npc, creature) +end + +npcType.onDisappear = function(npc, creature) +end + +npcType.onMove = function(npc, creature, fromPosition, toPosition) +end + +npcType.onSay = function(npc, creature, type, message) + local npcInteractions = table.concat(replyInteractions, getTravelInteractions(creature, destinations, travelMessages)) + return npc:processOnSay(message, creature, npcInteractions) +end + +npcType:register(npcConfig) diff --git a/data/npclua/garamond.lua b/data/npclua/garamond.lua new file mode 100644 index 00000000000..6f97f1f0884 --- /dev/null +++ b/data/npclua/garamond.lua @@ -0,0 +1,40 @@ +local npcType = Game.createNpcType("Garamond") +local npcConfig = {} + +npcConfig.description = "Garamond" + +npcConfig.health = 100 +npcConfig.maxHealth = npcConfig.health +npcConfig.walkInterval = 2000 +npcConfig.walkRadius = 2 + +npcConfig.outfit = { + lookType = 432, + lookHead = 0, + lookBody = 113, + lookLegs = 109, + lookFeet = 107, + lookAddons = 2 +} + +npcConfig.flags = { + floorchange = false +} + +npcType.onThink = function(npc, interval) +end + +npcType.onAppear = function(npc, creature) + Spdlog.info("onAppear") +end + +npcType.onDisappear = function(npc, creature) +end + +npcType.onMove = function(npc, creature, fromPosition, toPosition) +end + +npcType.onSay = function(npc, creature, type, message) +end + +npcType:register(npcConfig) diff --git a/data/npclua/zurak_arena.lua b/data/npclua/zurak_arena.lua new file mode 100644 index 00000000000..d01a1d15ead --- /dev/null +++ b/data/npclua/zurak_arena.lua @@ -0,0 +1,52 @@ +local npcType = Game.createNpcType("Zurak") +local npcConfig = {} + +npcConfig.description = "Zurak (Arena)" + +npcConfig.health = 100 +npcConfig.maxHealth = npcConfig.health +npcConfig.walkInterval = 0 +npcConfig.walkRadius = 0 + +npcConfig.outfit = { + lookType = 114 +} + +npcConfig.flags = { + floorchange = false +} + +npcType.onThink = function(npc, interval) +end + +npcType.onAppear = function(npc, creature) +end + +npcType.onDisappear = function(npc, creature) +end + +npcType.onMove = function(npc, creature, fromPosition, toPosition) +end + +local interactions = { + NpcInteraction:createGreetInteraction(), + NpcInteraction:createConfirmationInteraction( + {"trip", "passage", "back"}, + { + reply = "You want to go back?", + confirmation = "It'zz your doom you travel to.", + cancellation = "Zzoftzzkinzz zzo full of fear." + }, + 1 + ):addCompletionUpdateProcessor( + PlayerProcessingConfigs:new():addPosition(Position(33158, 31228, 7)) + ), + NpcInteraction:createReplyInteraction({"job", "hurry"}, "Me zzimple ferryman. I arrange {trip} to Zao."), + NpcInteraction:createFarewellInteraction(), +} + +npcType.onSay = function(npc, creature, type, message) + return npc:processOnSay(message, creature, interactions) +end + +npcType:register(npcConfig) diff --git a/data/raids/abdendriel/badger.xml b/data/raids/abdendriel/badger.xml new file mode 100644 index 00000000000..00b252b204c --- /dev/null +++ b/data/raids/abdendriel/badger.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/raids/abdendriel/dragons.xml b/data/raids/abdendriel/dragons.xml new file mode 100644 index 00000000000..f991a71d52f --- /dev/null +++ b/data/raids/abdendriel/dragons.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/raids/abdendriel/warwolf.xml b/data/raids/abdendriel/warwolf.xml new file mode 100644 index 00000000000..5f243c0b6eb --- /dev/null +++ b/data/raids/abdendriel/warwolf.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/raids/abdendriel/wasp_bear.xml b/data/raids/abdendriel/wasp_bear.xml new file mode 100644 index 00000000000..6b1b61dfb35 --- /dev/null +++ b/data/raids/abdendriel/wasp_bear.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/raids/ankrahmun/bone_beast.xml b/data/raids/ankrahmun/bone_beast.xml new file mode 100644 index 00000000000..e9a8947fa85 --- /dev/null +++ b/data/raids/ankrahmun/bone_beast.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/raids/ankrahmun/cobra.xml b/data/raids/ankrahmun/cobra.xml new file mode 100644 index 00000000000..521ac6132fd --- /dev/null +++ b/data/raids/ankrahmun/cobra.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/raids/ankrahmun/gargoyle.xml b/data/raids/ankrahmun/gargoyle.xml new file mode 100644 index 00000000000..0eb910b461c --- /dev/null +++ b/data/raids/ankrahmun/gargoyle.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/raids/ankrahmun/nomad.xml b/data/raids/ankrahmun/nomad.xml new file mode 100644 index 00000000000..3eba5d47956 --- /dev/null +++ b/data/raids/ankrahmun/nomad.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/data/raids/ankrahmun/scarab.xml b/data/raids/ankrahmun/scarab.xml new file mode 100644 index 00000000000..866cc923538 --- /dev/null +++ b/data/raids/ankrahmun/scarab.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/raids/ankrahmun/terramite.xml b/data/raids/ankrahmun/terramite.xml new file mode 100644 index 00000000000..c509481f816 --- /dev/null +++ b/data/raids/ankrahmun/terramite.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/raids/carlin/orc.xml b/data/raids/carlin/orc.xml new file mode 100644 index 00000000000..255b2accd49 --- /dev/null +++ b/data/raids/carlin/orc.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/data/raids/carlin/yeti.xml b/data/raids/carlin/yeti.xml new file mode 100644 index 00000000000..a1071d025c0 --- /dev/null +++ b/data/raids/carlin/yeti.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/data/raids/chayenne/chayenne.xml b/data/raids/chayenne/chayenne.xml new file mode 100644 index 00000000000..fdc42ec4540 --- /dev/null +++ b/data/raids/chayenne/chayenne.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/raids/darashia/arachir_the_ancient_one.xml b/data/raids/darashia/arachir_the_ancient_one.xml new file mode 100644 index 00000000000..74683ff1c7e --- /dev/null +++ b/data/raids/darashia/arachir_the_ancient_one.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/raids/darashia/lions.xml b/data/raids/darashia/lions.xml new file mode 100644 index 00000000000..2272ded24c4 --- /dev/null +++ b/data/raids/darashia/lions.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/data/raids/darashia/minotaurs.xml b/data/raids/darashia/minotaurs.xml new file mode 100644 index 00000000000..5a7859d1f8c --- /dev/null +++ b/data/raids/darashia/minotaurs.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/data/raids/darashia/necropharus.xml b/data/raids/darashia/necropharus.xml new file mode 100644 index 00000000000..28bd10050e4 --- /dev/null +++ b/data/raids/darashia/necropharus.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/raids/darashia/pirates.xml b/data/raids/darashia/pirates.xml new file mode 100644 index 00000000000..617becfd654 --- /dev/null +++ b/data/raids/darashia/pirates.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/data/raids/darashia/priestesses.xml b/data/raids/darashia/priestesses.xml new file mode 100644 index 00000000000..60ff80e7c53 --- /dev/null +++ b/data/raids/darashia/priestesses.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/raids/darashia/the_pale_count.xml b/data/raids/darashia/the_pale_count.xml new file mode 100644 index 00000000000..b7ba36a4bb4 --- /dev/null +++ b/data/raids/darashia/the_pale_count.xml @@ -0,0 +1,4 @@ + + + + diff --git a/data/raids/darashia/tyrn.xml b/data/raids/darashia/tyrn.xml new file mode 100644 index 00000000000..6d647afe102 --- /dev/null +++ b/data/raids/darashia/tyrn.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/data/raids/darashia/undead_darashia.xml b/data/raids/darashia/undead_darashia.xml new file mode 100644 index 00000000000..0b516353ed2 --- /dev/null +++ b/data/raids/darashia/undead_darashia.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/data/raids/darashia/white_pale.xml b/data/raids/darashia/white_pale.xml new file mode 100644 index 00000000000..e5e33ee8f05 --- /dev/null +++ b/data/raids/darashia/white_pale.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/raids/edron/feroxa.xml b/data/raids/edron/feroxa.xml new file mode 100644 index 00000000000..2451287064a --- /dev/null +++ b/data/raids/edron/feroxa.xml @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/data/raids/edron/goblins.xml b/data/raids/edron/goblins.xml new file mode 100644 index 00000000000..8089cf924c8 --- /dev/null +++ b/data/raids/edron/goblins.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/data/raids/edron/mad_mage.xml b/data/raids/edron/mad_mage.xml new file mode 100644 index 00000000000..fc50f263b77 --- /dev/null +++ b/data/raids/edron/mad_mage.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/raids/edron/orc.xml b/data/raids/edron/orc.xml new file mode 100644 index 00000000000..06cadf99f83 --- /dev/null +++ b/data/raids/edron/orc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + diff --git a/data/raids/edron/orshabaal.xml b/data/raids/edron/orshabaal.xml new file mode 100644 index 00000000000..484529c7da3 --- /dev/null +++ b/data/raids/edron/orshabaal.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/data/raids/edron/sir_valorcrest.xml b/data/raids/edron/sir_valorcrest.xml new file mode 100644 index 00000000000..c001abb283c --- /dev/null +++ b/data/raids/edron/sir_valorcrest.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/data/raids/edron/warlock.xml b/data/raids/edron/warlock.xml new file mode 100644 index 00000000000..94fc343804a --- /dev/null +++ b/data/raids/edron/warlock.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + diff --git a/data/raids/edron/weakened_shlorg.xml b/data/raids/edron/weakened_shlorg.xml new file mode 100644 index 00000000000..673f0080b2f --- /dev/null +++ b/data/raids/edron/weakened_shlorg.xml @@ -0,0 +1,4 @@ + + + + diff --git a/data/raids/farmine/beetles.xml b/data/raids/farmine/beetles.xml new file mode 100644 index 00000000000..7647f638421 --- /dev/null +++ b/data/raids/farmine/beetles.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/raids/farmine/draptor.xml b/data/raids/farmine/draptor.xml new file mode 100644 index 00000000000..c72397bbb59 --- /dev/null +++ b/data/raids/farmine/draptor.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/raids/farmine/gnarlhounds.xml b/data/raids/farmine/gnarlhounds.xml new file mode 100644 index 00000000000..dec413321b6 --- /dev/null +++ b/data/raids/farmine/gnarlhounds.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/data/raids/farmine/zevelon_duskbringer.xml b/data/raids/farmine/zevelon_duskbringer.xml new file mode 100644 index 00000000000..2dfd4ad385c --- /dev/null +++ b/data/raids/farmine/zevelon_duskbringer.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/data/raids/farmine/zulazza_the_corruptor.xml b/data/raids/farmine/zulazza_the_corruptor.xml new file mode 100644 index 00000000000..77b8ab8dbfe --- /dev/null +++ b/data/raids/farmine/zulazza_the_corruptor.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + diff --git a/data/raids/fury_gate/furyosa.xml b/data/raids/fury_gate/furyosa.xml new file mode 100644 index 00000000000..7e4f76178a9 --- /dev/null +++ b/data/raids/fury_gate/furyosa.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/raids/kazordoon/goblins.xml b/data/raids/kazordoon/goblins.xml new file mode 100644 index 00000000000..41f1af6cba1 --- /dev/null +++ b/data/raids/kazordoon/goblins.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/data/raids/kazordoon/horned.xml b/data/raids/kazordoon/horned.xml new file mode 100644 index 00000000000..84121d85af9 --- /dev/null +++ b/data/raids/kazordoon/horned.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/raids/liberty_bay/crustacea_gigantica_1.xml b/data/raids/liberty_bay/crustacea_gigantica_1.xml new file mode 100644 index 00000000000..bd6e1b5d3d7 --- /dev/null +++ b/data/raids/liberty_bay/crustacea_gigantica_1.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/raids/liberty_bay/crustacea_gigantica_2.xml b/data/raids/liberty_bay/crustacea_gigantica_2.xml new file mode 100644 index 00000000000..02190fbc396 --- /dev/null +++ b/data/raids/liberty_bay/crustacea_gigantica_2.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/raids/liberty_bay/crustacea_gigantica_3.xml b/data/raids/liberty_bay/crustacea_gigantica_3.xml new file mode 100644 index 00000000000..4a3fa212a45 --- /dev/null +++ b/data/raids/liberty_bay/crustacea_gigantica_3.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/raids/liberty_bay/diblis_the_fair.xml b/data/raids/liberty_bay/diblis_the_fair.xml new file mode 100644 index 00000000000..4aa53b73934 --- /dev/null +++ b/data/raids/liberty_bay/diblis_the_fair.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/data/raids/liberty_bay/ferumbras.xml b/data/raids/liberty_bay/ferumbras.xml new file mode 100644 index 00000000000..308d6c35e06 --- /dev/null +++ b/data/raids/liberty_bay/ferumbras.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/data/raids/liberty_bay/morgaroth.xml b/data/raids/liberty_bay/morgaroth.xml new file mode 100644 index 00000000000..fa132046e47 --- /dev/null +++ b/data/raids/liberty_bay/morgaroth.xml @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/data/raids/liberty_bay/quaras.xml b/data/raids/liberty_bay/quaras.xml new file mode 100644 index 00000000000..fe896359f6c --- /dev/null +++ b/data/raids/liberty_bay/quaras.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/data/raids/liberty_bay/tigers.xml b/data/raids/liberty_bay/tigers.xml new file mode 100644 index 00000000000..fb06e95a3b7 --- /dev/null +++ b/data/raids/liberty_bay/tigers.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/raids/liberty_bay/tortoises.xml b/data/raids/liberty_bay/tortoises.xml new file mode 100644 index 00000000000..440b5b6a003 --- /dev/null +++ b/data/raids/liberty_bay/tortoises.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/raids/liberty_bay/undead_cavebear.xml b/data/raids/liberty_bay/undead_cavebear.xml new file mode 100644 index 00000000000..5643c7605f2 --- /dev/null +++ b/data/raids/liberty_bay/undead_cavebear.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/raids/oramond/crustacea_gigantica_4.xml b/data/raids/oramond/crustacea_gigantica_4.xml new file mode 100644 index 00000000000..0054e58ab8d --- /dev/null +++ b/data/raids/oramond/crustacea_gigantica_4.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/raids/oramond/crustacea_gigantica_5.xml b/data/raids/oramond/crustacea_gigantica_5.xml new file mode 100644 index 00000000000..53bda7cb4df --- /dev/null +++ b/data/raids/oramond/crustacea_gigantica_5.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/raids/port_hope/kongras.xml b/data/raids/port_hope/kongras.xml new file mode 100644 index 00000000000..11f3cc8113c --- /dev/null +++ b/data/raids/port_hope/kongras.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/data/raids/port_hope/lizards.xml b/data/raids/port_hope/lizards.xml new file mode 100644 index 00000000000..11f3cc8113c --- /dev/null +++ b/data/raids/port_hope/lizards.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/data/raids/port_hope/midnight_panther_1.xml b/data/raids/port_hope/midnight_panther_1.xml new file mode 100644 index 00000000000..7000c7581d2 --- /dev/null +++ b/data/raids/port_hope/midnight_panther_1.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/raids/port_hope/midnight_panther_2.xml b/data/raids/port_hope/midnight_panther_2.xml new file mode 100644 index 00000000000..2b5a89e393e --- /dev/null +++ b/data/raids/port_hope/midnight_panther_2.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/raids/port_hope/midnight_panther_3.xml b/data/raids/port_hope/midnight_panther_3.xml new file mode 100644 index 00000000000..2b5a89e393e --- /dev/null +++ b/data/raids/port_hope/midnight_panther_3.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/raids/port_hope/serpent_spawn.xml b/data/raids/port_hope/serpent_spawn.xml new file mode 100644 index 00000000000..3fe562d678d --- /dev/null +++ b/data/raids/port_hope/serpent_spawn.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/data/raids/port_hope/terrorbirds.xml b/data/raids/port_hope/terrorbirds.xml new file mode 100644 index 00000000000..040dcfe48f1 --- /dev/null +++ b/data/raids/port_hope/terrorbirds.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/raids/port_hope/the_welter.xml b/data/raids/port_hope/the_welter.xml new file mode 100644 index 00000000000..708f28a0fd7 --- /dev/null +++ b/data/raids/port_hope/the_welter.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/raids/raids.xml b/data/raids/raids.xml new file mode 100644 index 00000000000..82af716354d --- /dev/null +++ b/data/raids/raids.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/raids/rookgaard/munster.xml b/data/raids/rookgaard/munster.xml new file mode 100644 index 00000000000..cc7f2a61f69 --- /dev/null +++ b/data/raids/rookgaard/munster.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/raids/rookgaard/rats.xml b/data/raids/rookgaard/rats.xml new file mode 100644 index 00000000000..07ee7f84e51 --- /dev/null +++ b/data/raids/rookgaard/rats.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/raids/rookgaard/rottie1.xml b/data/raids/rookgaard/rottie1.xml new file mode 100644 index 00000000000..07ee7f84e51 --- /dev/null +++ b/data/raids/rookgaard/rottie1.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/raids/rookgaard/rottie2.xml b/data/raids/rookgaard/rottie2.xml new file mode 100644 index 00000000000..3bbc485ef8d --- /dev/null +++ b/data/raids/rookgaard/rottie2.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/data/raids/rookgaard/sheng.xml b/data/raids/rookgaard/sheng.xml new file mode 100644 index 00000000000..6426b900376 --- /dev/null +++ b/data/raids/rookgaard/sheng.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/raids/rookgaard/teleskor.xml b/data/raids/rookgaard/teleskor.xml new file mode 100644 index 00000000000..0f356310dd1 --- /dev/null +++ b/data/raids/rookgaard/teleskor.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/raids/roshamuul/gaz_haragoth.xml b/data/raids/roshamuul/gaz_haragoth.xml new file mode 100644 index 00000000000..3b771fa0fca --- /dev/null +++ b/data/raids/roshamuul/gaz_haragoth.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/data/raids/roshamuul/mawhawk.xml b/data/raids/roshamuul/mawhawk.xml new file mode 100644 index 00000000000..db48081d57a --- /dev/null +++ b/data/raids/roshamuul/mawhawk.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/raids/roshamuul/omrafir.xml b/data/raids/roshamuul/omrafir.xml new file mode 100644 index 00000000000..214d5fc44a4 --- /dev/null +++ b/data/raids/roshamuul/omrafir.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/data/raids/svargrond/barba_bittermor.xml b/data/raids/svargrond/barba_bittermor.xml new file mode 100644 index 00000000000..9d3af1d419d --- /dev/null +++ b/data/raids/svargrond/barba_bittermor.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + diff --git a/data/raids/svargrond/barba_svar.xml b/data/raids/svargrond/barba_svar.xml new file mode 100644 index 00000000000..826fd02c189 --- /dev/null +++ b/data/raids/svargrond/barba_svar.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/raids/svargrond/barbarian.xml b/data/raids/svargrond/barbarian.xml new file mode 100644 index 00000000000..594feff70d1 --- /dev/null +++ b/data/raids/svargrond/barbarian.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/data/raids/svargrond/ghazbaran.xml b/data/raids/svargrond/ghazbaran.xml new file mode 100644 index 00000000000..f12b715bfa9 --- /dev/null +++ b/data/raids/svargrond/ghazbaran.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/raids/svargrond/hirintror.xml b/data/raids/svargrond/hirintror.xml new file mode 100644 index 00000000000..1fcf1e735d5 --- /dev/null +++ b/data/raids/svargrond/hirintror.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/raids/svargrond/ice_golems.xml b/data/raids/svargrond/ice_golems.xml new file mode 100644 index 00000000000..302bf4f8e84 --- /dev/null +++ b/data/raids/svargrond/ice_golems.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/raids/svargrond/ocyakao.xml b/data/raids/svargrond/ocyakao.xml new file mode 100644 index 00000000000..46bdafa2142 --- /dev/null +++ b/data/raids/svargrond/ocyakao.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/raids/svargrond/zushuka.xml b/data/raids/svargrond/zushuka.xml new file mode 100644 index 00000000000..5d4e76dffdf --- /dev/null +++ b/data/raids/svargrond/zushuka.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/data/raids/thais/cyclops.xml b/data/raids/thais/cyclops.xml new file mode 100644 index 00000000000..e0afaf055c3 --- /dev/null +++ b/data/raids/thais/cyclops.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/data/raids/thais/orcs.xml b/data/raids/thais/orcs.xml new file mode 100644 index 00000000000..398632712e4 --- /dev/null +++ b/data/raids/thais/orcs.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/raids/thais/rats.xml b/data/raids/thais/rats.xml new file mode 100644 index 00000000000..d7acd070dd8 --- /dev/null +++ b/data/raids/thais/rats.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/data/raids/thais/wild_horses.xml b/data/raids/thais/wild_horses.xml new file mode 100644 index 00000000000..02af606988d --- /dev/null +++ b/data/raids/thais/wild_horses.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/data/raids/venore/dharalion.xml b/data/raids/venore/dharalion.xml new file mode 100644 index 00000000000..7caf8fad6c4 --- /dev/null +++ b/data/raids/venore/dharalion.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/data/raids/venore/elves.xml b/data/raids/venore/elves.xml new file mode 100644 index 00000000000..8445fd3f264 --- /dev/null +++ b/data/raids/venore/elves.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/data/raids/venore/fernfang.xml b/data/raids/venore/fernfang.xml new file mode 100644 index 00000000000..8099c9459c4 --- /dev/null +++ b/data/raids/venore/fernfang.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/raids/venore/feverish_citizen.xml b/data/raids/venore/feverish_citizen.xml new file mode 100644 index 00000000000..8e01355fcdb --- /dev/null +++ b/data/raids/venore/feverish_citizen.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/data/raids/venore/hunter.xml b/data/raids/venore/hunter.xml new file mode 100644 index 00000000000..def572be0d8 --- /dev/null +++ b/data/raids/venore/hunter.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/raids/venore/orc_backpack.xml b/data/raids/venore/orc_backpack.xml new file mode 100644 index 00000000000..76acbc9ef25 --- /dev/null +++ b/data/raids/venore/orc_backpack.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/raids/venore/the_old_widow.xml b/data/raids/venore/the_old_widow.xml new file mode 100644 index 00000000000..3d7632cc7d0 --- /dev/null +++ b/data/raids/venore/the_old_widow.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + diff --git a/data/raids/venore/undead.xml b/data/raids/venore/undead.xml new file mode 100644 index 00000000000..2a65bfac6c4 --- /dev/null +++ b/data/raids/venore/undead.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + diff --git a/data/raids/venore/water_buffalo.xml b/data/raids/venore/water_buffalo.xml new file mode 100644 index 00000000000..c4e125f0a65 --- /dev/null +++ b/data/raids/venore/water_buffalo.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/reports/bugs/.gitignore b/data/reports/bugs/.gitignore new file mode 100644 index 00000000000..eb67fe0afb7 --- /dev/null +++ b/data/reports/bugs/.gitignore @@ -0,0 +1,3 @@ +# Ignore user generated reports +* +!.gitignore diff --git a/data/reports/players/.gitignore b/data/reports/players/.gitignore new file mode 100644 index 00000000000..eb67fe0afb7 --- /dev/null +++ b/data/reports/players/.gitignore @@ -0,0 +1,3 @@ +# Ignore user generated reports +* +!.gitignore diff --git a/data/scripts/actions/addons/addons.lua b/data/scripts/actions/addons/addons.lua new file mode 100644 index 00000000000..e9ccb57fe41 --- /dev/null +++ b/data/scripts/actions/addons/addons.lua @@ -0,0 +1,56 @@ +local config = { + -- soil guardian + [18517] = {female = 514, male = 516, effect = CONST_ME_GREEN_RINGS}, + [18518] = {female = 514, male = 516, addon = 1, effect = CONST_ME_GREEN_RINGS, achievement = 'Funghitastic'}, + [18519] = {female = 514, male = 516, addon = 2, effect = CONST_ME_GREEN_RINGS, achievement = 'Funghitastic'}, + -- crystal warlord + [18520] = {female = 513, male = 512, effect = CONST_ME_GIANTICE}, + [18521] = {female = 513, male = 512, addon = 1, effect = CONST_ME_GIANTICE, achievement = 'Crystal Clear'}, + [18522] = {female = 513, male = 512, addon = 2, effect = CONST_ME_GIANTICE, achievement = 'Crystal Clear'}, + -- makeshift warrior + [30890] = {female = 1043, male = 1042}, + [30892] = {female = 1043, male = 1042, addon = 1, achievement = 'Cobbled and Patched'}, + [30891] = {female = 1043, male = 1042, addon = 2, achievement = 'Cobbled and Patched'} +} + +local addons = Action() + +function addons.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local useItem = config[item.itemid] + if not useItem then + return true + end + + local looktype = player:getSex() == PLAYERSEX_FEMALE and useItem.female or useItem.male + + if useItem.addon then + if not player:isPremium() + or not player:hasOutfit(looktype) + or player:hasOutfit(looktype, useItem.addon) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You own no premium account, lack the base outfit or already own this outfit part.') + return true + end + + player:addOutfitAddon(useItem.female, useItem.addon) + player:addOutfitAddon(useItem.male, useItem.addon) + player:getPosition():sendMagicEffect(CONST_ME_GIFT_WRAPS) + if player:hasOutfit(looktype, 3) then + player:addAchievement(useItem.achievement) + end + item:remove() + else + if not player:isPremium() or player:hasOutfit(looktype) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You own no premium account or already own this outfit part.') + return true + end + + player:addOutfit(useItem.female) + player:addOutfit(useItem.male) + player:getPosition():sendMagicEffect(CONST_ME_GIFT_WRAPS) + item:remove() + end + return true +end + +addons:id(18517, 18518, 18519, 18520, 18521, 18522, 30890, 30891, 30892) +addons:register() diff --git a/data/scripts/actions/addons/afflicted_outfit.lua b/data/scripts/actions/addons/afflicted_outfit.lua new file mode 100644 index 00000000000..56235dad9a0 --- /dev/null +++ b/data/scripts/actions/addons/afflicted_outfit.lua @@ -0,0 +1,65 @@ +local afflictedOutfit = Action() + +function afflictedOutfit.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local hasOutfit = player:getStorageValue(Storage.OutfitQuest.Afflicted.Outfit) == 1 + -- Plgue Mask + if item.itemid == 13925 then + if not hasOutfit then + return false + end + + if player:getStorageValue(Storage.OutfitQuest.Afflicted.AddonPlagueMask) == 1 then + return false + end + + player:addOutfitAddon(430, 2) + player:addOutfitAddon(431, 2) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:setStorageValue(Storage.OutfitQuest.Afflicted.AddonPlagueMask, 1) + player:say('You gained a plague mask for your outfit.', TALKTYPE_MONSTER_SAY, false, player) + item:remove() + + -- Plague Bell + elseif item.itemid == 13926 then + if not hasOutfit then + return false + end + + if player:getStorageValue(Storage.OutfitQuest.Afflicted.AddonPlagueBell) == 1 then + return false + end + + player:addOutfitAddon(430, 1) + player:addOutfitAddon(431, 1) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:setStorageValue(Storage.OutfitQuest.Afflicted.AddonPlagueBell, 1) + player:say('You gained a plague bell for your outfit.', TALKTYPE_MONSTER_SAY, false, player) + item:remove() + + -- Outfit + else + if hasOutfit then + return false + end + + for id = 13540, 13545 do + if player:getItemCount(id) < 1 then + return false + end + end + + for id = 13540, 13545 do + player:removeItem(id, 1) + end + + player:addOutfit(430) + player:addOutfit(431) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:setStorageValue(Storage.OutfitQuest.Afflicted.Outfit, 1) + player:say('You have restored an outfit.', TALKTYPE_MONSTER_SAY, false, player) + end + return true +end + +afflictedOutfit:id(13540, 13541, 13542, 13543, 13544, 13545, 13925, 13926) +afflictedOutfit:register() diff --git a/data/scripts/actions/adventurers_guild/adventurers_stone.lua b/data/scripts/actions/adventurers_guild/adventurers_stone.lua new file mode 100644 index 00000000000..0d5223fd69e --- /dev/null +++ b/data/scripts/actions/adventurers_guild/adventurers_stone.lua @@ -0,0 +1,51 @@ +local setting = { + {fromPos = Position(32718, 31628, 7), toPos = Position(32736, 31639, 7), townId = TOWNS_LIST.AB_DENDRIEL}, + {fromPos = Position(32356, 31775, 7), toPos = Position(32364, 31787, 7), townId = TOWNS_LIST.CARLIN}, + {fromPos = Position(32642, 31921, 11), toPos = Position(32656, 31929, 11), townId = TOWNS_LIST.KAZORDOON}, + {fromPos = Position(32364, 32231, 7), toPos = Position(32374, 32243, 7), townId = TOWNS_LIST.THAIS}, + {fromPos = Position(32953, 32072, 7), toPos = Position(32963, 32081, 7), townId = TOWNS_LIST.VENORE}, + {fromPos = Position(33188, 32844, 8), toPos = Position(33201, 32857, 8), townId = TOWNS_LIST.ANKRAHMUN}, + {fromPos = Position(33208, 31803, 8), toPos = Position(33225, 31819, 8), townId = TOWNS_LIST.EDRON}, + {fromPos = Position(33018, 31514, 11), toPos = Position(33032, 31531, 11), townId = TOWNS_LIST.FARMINE}, + {fromPos = Position(33210, 32450, 1), toPos = Position(33217, 32457, 1), townId = TOWNS_LIST.DARASHIA}, + {fromPos = Position(32313, 32818, 7), toPos = Position(32322, 32830, 7), townId = TOWNS_LIST.LIBERTY_BAY}, + {fromPos = Position(32590, 32740, 7), toPos = Position(32600, 32750, 7), townId = TOWNS_LIST.PORT_HOPE}, + {fromPos = Position(32207, 31127, 7), toPos = Position(32218, 31138, 7), townId = TOWNS_LIST.SVARGROND}, + {fromPos = Position(32785, 31274, 7), toPos = Position(32789, 31279, 7), townId = TOWNS_LIST.YALAHAR}, + {fromPos = Position(33442, 31312, 9), toPos = Position(33454, 31326, 9), townId = TOWNS_LIST.GRAY_BEACH}, + {fromPos = Position(33586, 31895, 6), toPos = Position(33603, 31903, 6), townId = TOWNS_LIST.RATHLETON}, + {fromPos = Position(33510, 32360, 6), toPos = Position(33516, 32366, 6), townId = TOWNS_LIST.ROSHAMUUL}, + {fromPos = Position(33916, 31474, 5), toPos = Position(33927, 31484, 5), townId = TOWNS_LIST.ISSAVI} +} + +local adventurersStone = Action() + +function adventurersStone.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + local playerPos, isInTemple, temple, townId = player:getPosition(), false + for i = 1, #setting do + temple = setting[i] + if isInRange(playerPos, temple.fromPos, temple.toPos) then + if Tile(playerPos):hasFlag(TILESTATE_PROTECTIONZONE) then + isInTemple, townId = true, temple.townId + break + end + end + end + + if not isInTemple then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Try to move more to the center of a temple to use the spiritual energy for a teleport.') + return true + end + + player:setStorageValue(Storage.AdventurersGuild.Stone, townId) + playerPos:sendMagicEffect(CONST_ME_TELEPORT) + + local destination = Position(32210, 32300, 6) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +adventurersStone:id(18559) +adventurersStone:register() diff --git a/data/scripts/actions/adventurers_guild/magic_door.lua b/data/scripts/actions/adventurers_guild/magic_door.lua new file mode 100644 index 00000000000..732a65c2b20 --- /dev/null +++ b/data/scripts/actions/adventurers_guild/magic_door.lua @@ -0,0 +1,25 @@ +local magicDoor = Action() + +function magicDoor.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local playerPos, destination = player:getPosition() + if item.itemid == 19598 then + player:setStorageValue(Storage.AdventurersGuild.MagicDoor, 1) + destination = Position(32292, 32293, 7) + else + if player:getStorageValue(Storage.AdventurersGuild.MagicDoor) == 1 then + player:setStorageValue(Storage.AdventurersGuild.MagicDoor, -1) + destination = Position(32199, 32309, 7) + elseif playerPos.x == 32293 then + destination = Position(32297, 32293, 7) + else + destination = Position(32292, 32293, 7) + end + end + player:teleportTo(destination) + playerPos:sendMagicEffect(CONST_ME_TELEPORT) + destination:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +magicDoor:id(19598, 19599) +magicDoor:register() diff --git a/data/scripts/actions/arena_pvp/arena_10x10.lua b/data/scripts/actions/arena_pvp/arena_10x10.lua new file mode 100644 index 00000000000..cd181d2e313 --- /dev/null +++ b/data/scripts/actions/arena_pvp/arena_10x10.lua @@ -0,0 +1,48 @@ +local setting = { + centerRoom = {x = 32255, y = 32178, z = 9}, + range = 10 +} + +local playerPositions = { + {fromPos = {x = 32242, y = 32175, z = 8}, toPos = {x = 32246, y = 32175, z = 9}}, + {fromPos = {x = 32242, y = 32176, z = 8}, toPos = {x = 32246, y = 32177, z = 9}}, + {fromPos = {x = 32242, y = 32177, z = 8}, toPos = {x = 32246, y = 32179, z = 9}}, + {fromPos = {x = 32242, y = 32178, z = 8}, toPos = {x = 32246, y = 32181, z = 9}}, + {fromPos = {x = 32242, y = 32180, z = 8}, toPos = {x = 32264, y = 32174, z = 9}}, + {fromPos = {x = 32242, y = 32181, z = 8}, toPos = {x = 32264, y = 32176, z = 9}}, + {fromPos = {x = 32242, y = 32182, z = 8}, toPos = {x = 32264, y = 32178, z = 9}}, + {fromPos = {x = 32242, y = 32183, z = 8}, toPos = {x = 32264, y = 32180, z = 9}}, + {fromPos = {x = 32242, y = 32184, z = 8}, toPos = {x = 32264, y = 32182, z = 9}}, + {fromPos = {x = 32241, y = 32179, z = 8}, toPos = {x = 32246, y = 32183, z = 9}}, -- Player 1 pos +} + +local arena10x10 = Action() + +function arena10x10.onUse(player, item, fromPosition, target, toPosition, monster, isHotkey) + if toPosition == Position(32240, 32179, 8) then + if roomIsOccupied(setting.centerRoom, setting.range, setting.range) then + player:say("Please wait for the fighters come out of the arena.", TALKTYPE_ORANGE_1) + return true + end + for i = 1, #playerPositions do + local creature = Tile(playerPositions[i].fromPos):getTopCreature() + if creature and creature:getPlayer() then + creature:teleportTo(playerPositions[i].toPos) + creature:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + elseif not creature then + player:say("You need 10 players for enter in the arena.", TALKTYPE_ORANGE_1) + return true + else + player:say("You need 10 players for enter in the arena.", TALKTYPE_ORANGE_1) + return true + end + end + else + return false + end + return true +end + +arena10x10:id(24181) +arena10x10:register() + diff --git a/data/scripts/actions/arena_pvp/arena_2x2.lua b/data/scripts/actions/arena_pvp/arena_2x2.lua new file mode 100644 index 00000000000..84f28da741a --- /dev/null +++ b/data/scripts/actions/arena_pvp/arena_2x2.lua @@ -0,0 +1,43 @@ +local setting = { + centerRoom = {x = 32255, y = 32178, z = 9}, + range = 10 +} + +local playerPositions = { + {fromPos = {x = 32269, y = 32180, z = 8}, toPos = {x = 32247, y = 32178, z = 9}}, -- Player 2 + {fromPos = {x = 32270, y = 32180, z = 8}, toPos = {x = 32264, y = 32178, z = 9}} -- Player 1 +} + +local positions = { +} + +local arena2x2 = Action() + +function arena2x2.onUse(player, item, fromPosition, target, toPosition, monster, isHotkey) + if toPosition == Position(32271, 32180, 8) then + if roomIsOccupied(setting.centerRoom, setting.range, setting.range) then + player:say("Please wait for the fighters come out of the arena.", TALKTYPE_ORANGE_1) + return true + end + for i = 1, #playerPositions do + local creature = Tile(playerPositions[i].fromPos):getTopCreature() + if creature and creature:getPlayer() then + creature:teleportTo(playerPositions[i].toPos) + creature:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + elseif not creature then + player:say("You need 2 players for enter in the arena.", TALKTYPE_ORANGE_1) + return true + else + player:say("You need 2 players for enter in the arena.", TALKTYPE_ORANGE_1) + return true + end + end + else + return false + end + return true +end + +arena2x2:id(24173) +arena2x2:register() + diff --git a/data/scripts/actions/dawnport/lever.lua b/data/scripts/actions/dawnport/lever.lua new file mode 100644 index 00000000000..d14c32555db --- /dev/null +++ b/data/scripts/actions/dawnport/lever.lua @@ -0,0 +1,71 @@ +local positions = { + {x = 32106, y = 31903, z = 7}, + {x = 32106, y = 31904, z = 7}, + {x = 32105, y = 31903, z = 7}, + {x = 32105, y = 31904, z = 7} +} + +local lever = Action() + +function lever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.Dawnport.Lever) < 1 then + player:setStorageValue(Storage.Dawnport.Lever, 1) + end + + if item.itemid == 10044 and player:getStorageValue(Storage.Dawnport.Lever) == 1 then + for i = 1, #positions do + local tile = Tile(positions[i]) + local createBridge = tile:getItemById(4665) + if createBridge then + createBridge:transform(5769) + end + end + player:say("", TALKTYPE_MONSTER_SAY, false, player, {x = 32107, y = 31904, z = 7}) + player:setStorageValue(Storage.Dawnport.Lever, 2) + item:transform(23661) + addEvent(function() + item:transform(10044) + end, 8 * 1000) + elseif item.itemid == 10044 and player:getStorageValue(Storage.Dawnport.Lever) == 2 then + for i = 1, #positions do + local tile = Tile(positions[i]) + if tile then + local creature = tile:getTopCreature() + if creature then + toPosition.x = toPosition.x + 1 + local query = Tile(toPosition):queryAdd(creature, bit.bor(FLAG_IGNOREBLOCKCREATURE, FLAG_PATHFINDING)) + if query ~= RETURNVALUE_NOERROR then + toPosition.x = toPosition.x - 1 + toPosition.y = toPosition.y + 1 + query = Tile(toPosition):queryAdd(creature, bit.bor(FLAG_IGNOREBLOCKCREATURE, FLAG_PATHFINDING)) + end + if query ~= RETURNVALUE_NOERROR then + toPosition.y = toPosition.y - 2 + query = Tile(toPosition):queryAdd(creature, bit.bor(FLAG_IGNOREBLOCKCREATURE, FLAG_PATHFINDING)) + end + if query ~= RETURNVALUE_NOERROR then + toPosition.x = toPosition.x - 1 + toPosition.y = toPosition.y + 1 + query = Tile(toPosition):queryAdd(creature, bit.bor(FLAG_IGNOREBLOCKCREATURE, FLAG_PATHFINDING)) + end + creature:teleportTo(toPosition, true) + end + + local removeBridge = tile:getItemById(5769) + if removeBridge then + removeBridge:transform(4665) + end + end + end + player:say("", TALKTYPE_MONSTER_SAY, false, player, {x = 32107, y = 31904, z = 7}) + player:setStorageValue(Storage.Dawnport.Lever, 1) + item:transform(23661) + addEvent(function() + item:transform(10044) + end, 8 * 1000) + end + return true +end + +lever:aid(30001) +lever:register() diff --git a/data/scripts/actions/dawnport/vocation_door.lua b/data/scripts/actions/dawnport/vocation_door.lua new file mode 100644 index 00000000000..97471f29180 --- /dev/null +++ b/data/scripts/actions/dawnport/vocation_door.lua @@ -0,0 +1,48 @@ +local vocationDoors = { + -- Sorcerer + [22001] = { + vocation = VOCATION.ID.SORCERER, + destination = {x = 32054, y = 31883, z = 6} + }, + -- Druid + [22002] = { + vocation = VOCATION.ID.DRUID, + destination = {x = 32073, y = 31883, z = 6} + }, + -- Paladin + [22003] = { + vocation = VOCATION.ID.PALADIN, + destination = {x = 32059, y = 31883, z = 6} + }, + -- Knight + [22004] = { + vocation = VOCATION.ID.KNIGHT, + destination = {x = 32068, y = 31883, z = 6} + }, +} + +local vocationDoor = Action() + +function vocationDoor.onUse(player, item, target, position, fromPosition) + local door = vocationDoors[item.uid] + --Check Oressa storage before choose vocation + if player:getStorageValue(Storage.Dawnport.DoorVocation) == door.vocation then + -- Remove Mainland smuggling items + removeMainlandSmugglingItems(player) + player:teleportTo(door.destination) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage( + MESSAGE_EVENT_ADVANCE, + "Open the chest and take your gear, young " .. player:getVocation():getName():lower() .. "!" + ) + elseif player:getStorageValue(Storage.Dawnport.DoorVocation) ~= door.vocation then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The door seems to be sealed against unwanted intruders.") + end + return true +end + +for index, value in pairs(vocationDoors) do + vocationDoor:uid(index) +end + +vocationDoor:register() diff --git a/data/scripts/actions/door/custom_door.lua b/data/scripts/actions/door/custom_door.lua new file mode 100644 index 00000000000..7a2f129eb04 --- /dev/null +++ b/data/scripts/actions/door/custom_door.lua @@ -0,0 +1,37 @@ +local doorIds = {} +for index, value in ipairs(CustomDoorTable) do + if not table.contains(doorIds, value.openDoor) then + table.insert(doorIds, value.openDoor) + end + + if not table.contains(doorIds, value.closedDoor) then + table.insert(doorIds, value.closedDoor) + end +end + +local customDoor = Action() +function customDoor.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if Creature.checkCreatureInsideDoor(player, toPosition) then + return true + end + + for index, value in ipairs(CustomDoorTable) do + if value.closedDoor == item.itemid then + item:transform(value.openDoor) + return true + end + end + for index, value in ipairs(CustomDoorTable) do + if value.openDoor == item.itemid then + item:transform(value.closedDoor) + return true + end + end + return true +end + +for index, value in ipairs(doorIds) do + customDoor:id(value) +end + +customDoor:register() diff --git a/data/scripts/actions/door/key_door.lua b/data/scripts/actions/door/key_door.lua new file mode 100644 index 00000000000..cd69e0fcd5a --- /dev/null +++ b/data/scripts/actions/door/key_door.lua @@ -0,0 +1,78 @@ +local doorId = {} +local keyLockedDoor = {} +local keyUnlockedDoor = {} +for index, value in ipairs(KeyDoorTable) do + if not table.contains(doorId, value.closedDoor) then + table.insert(doorId, value.closedDoor) + end + if not table.contains(doorId, value.lockedDoor) then + table.insert(doorId, value.lockedDoor) + end + if not table.contains(doorId, value.openDoor) then + table.insert(doorId, value.openDoor) + end + if not table.contains(keyLockedDoor, value.lockedDoor) then + table.insert(keyLockedDoor, value.lockedDoor) + end + if not table.contains(keyUnlockedDoor, value.closedDoor) then + table.insert(keyUnlockedDoor, value.closedDoor) + end +end + +for index, value in pairs(keysID) do + if not table.contains(doorId, value) then + table.insert(doorId, value) + end +end + +local keyDoor = Action() +function keyDoor.onUse(player, item, fromPosition, target, toPosition, isHotkey) + -- It is locked msg + if table.contains(keyLockedDoor, item.itemid) or (table.contains(keyUnlockedDoor, item.itemid) and table.contains({1001, 101}, item.actionid)) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "It is locked.") + return true + end + + -- onUse unlocked key door + for index, value in ipairs(KeyDoorTable) do + if value.closedDoor == item.itemid then + item:transform(value.openDoor) + return true + end + end + for index, value in ipairs(KeyDoorTable) do + if value.openDoor == item.itemid then + if Creature.checkCreatureInsideDoor(player, toPosition) then + return false + end + item:transform(value.closedDoor) + return true + end + end + + -- Key use on door (locked key door) + if target.actionid > 0 then + for index, value in ipairs(KeyDoorTable) do + if item.actionid ~= target.actionid and value.lockedDoor == target.itemid then + player:sendCancelMessage("The key does not match.") + return true + end + if item.actionid == target.actionid then + if value.lockedDoor == target.itemid then + target:transform(value.openDoor) + return true + elseif table.contains({value.openDoor, value.closedDoor}, target.itemid) then + target:transform(value.lockedDoor) + return true + end + end + end + end + return false +end + +for key, value in pairs(doorId) do + keyDoor:id(value) +end + +keyDoor:register() diff --git a/data/scripts/actions/door/level_door.lua b/data/scripts/actions/door/level_door.lua new file mode 100644 index 00000000000..8f8ca3ad1bc --- /dev/null +++ b/data/scripts/actions/door/level_door.lua @@ -0,0 +1,37 @@ +local doorIds = {} +for index, value in ipairs(LevelDoorTable) do + if not table.contains(doorIds, value.openDoor) then + table.insert(doorIds, value.openDoor) + end + + if not table.contains(doorIds, value.closedDoor) then + table.insert(doorIds, value.closedDoor) + end +end + +local levelDoor = Action() +function levelDoor.onUse(player, item, fromPosition, target, toPosition, isHotkey) + for index, value in ipairs(LevelDoorTable) do + if value.closedDoor == item.itemid then + if item.actionid > 0 and player:getLevel() >= item.actionid - 1000 then + item:transform(value.openDoor) + player:teleportTo(toPosition, true) + return true + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Only the worthy may pass.") + return true + end + end + end + + if Creature.checkCreatureInsideDoor(player, toPosition) then + return true + end + return true +end + +for index, value in ipairs(doorIds) do + levelDoor:id(value) +end + +levelDoor:register() diff --git a/data/scripts/actions/door/quest_door.lua b/data/scripts/actions/door/quest_door.lua new file mode 100644 index 00000000000..438a23a5591 --- /dev/null +++ b/data/scripts/actions/door/quest_door.lua @@ -0,0 +1,37 @@ +local doorIds = {} +for index, value in ipairs(QuestDoorTable) do + if not table.contains(doorIds, value.openDoor) then + table.insert(doorIds, value.openDoor) + end + + if not table.contains(doorIds, value.closedDoor) then + table.insert(doorIds, value.closedDoor) + end +end + +local questDoor = Action() +function questDoor.onUse(player, item, fromPosition, target, toPosition, isHotkey) + for index, value in ipairs(QuestDoorTable) do + if value.closedDoor == item.itemid then + if item.actionid > 0 and player:getStorageValue(item.actionid) ~= -1 then + item:transform(value.openDoor) + player:teleportTo(toPosition, true) + return true + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The door seems to be sealed against unwanted intruders.") + return true + end + end + end + + if Creature.checkCreatureInsideDoor(player, toPosition) then + return true + end + return true +end + +for index, value in ipairs(doorIds) do + questDoor:id(value) +end + +questDoor:register() diff --git a/data/scripts/actions/falcons/falcon_shield.lua b/data/scripts/actions/falcons/falcon_shield.lua new file mode 100644 index 00000000000..fab70d8f236 --- /dev/null +++ b/data/scripts/actions/falcons/falcon_shield.lua @@ -0,0 +1,27 @@ +local falconShield = Action() + +function falconShield.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if not target or type(target) ~= 'userdata' or not target:isItem() then + return false + end + + if player:getItemCount(32521) < 1 or player:getItemCount(32518) < 1 then + return false + end + + if target:getId() ~= 8671 or target:getPosition() ~= Position(33363, 31342, 7) then + return false + end + + local mould = Position(33361, 31341, 7) + toPosition:sendMagicEffect(CONST_ME_POFF) + toPosition:sendMagicEffect(CONST_ME_HITAREA) + mould:sendMagicEffect(CONST_ME_SMOKE) + player:removeItem(32518, 1) + player:addItem(32422, 1) + item:remove(1) + return true +end + +falconShield:id(32421) +falconShield:register() diff --git a/data/scripts/actions/farmine/boat.lua b/data/scripts/actions/farmine/boat.lua new file mode 100644 index 00000000000..3f2b1dd6655 --- /dev/null +++ b/data/scripts/actions/farmine/boat.lua @@ -0,0 +1,22 @@ +local config = { + [57601] = Position(33326, 31351, 7), + [57602] = Position(33382, 31292, 7), + [57603] = Position(33374, 31310, 7), + [64007] = Position(33346, 31349, 7), +} + +local boat = Action() + +function boat.onUse(player, item, fromPosition, itemEx, toPosition) + for actionId, destination in pairs(config) do + if item.actionid == actionId then + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_POFF) + fromPosition:sendMagicEffect(CONST_ME_POFF) + return true + end + end +end + +boat:aid(57601, 57602, 57603, 64007) +boat:register() diff --git a/data/scripts/actions/farmine/elevator_lever.lua b/data/scripts/actions/farmine/elevator_lever.lua new file mode 100644 index 00000000000..0656d5fc408 --- /dev/null +++ b/data/scripts/actions/farmine/elevator_lever.lua @@ -0,0 +1,41 @@ +local t = { + [9118] = {{x=32991, y=31539, z=1}, {x=32991, y=31539, z=4}, effect = true}, --last, to flying carpet + [9119] = {{x=32991, y=31539, z=4}, {x=32991, y=31539, z=1}, effect = true}, --to flying carpet + [9120] = {{x=32993, y=31547, z=4}, {x=33061, y=31527, z=14}, effect = true}, -- elevator to Farmine + [9121] = {{x=33061, y=31527, z=10}, {x=32993, y=31547, z=4}, effect = true}, -- Farmine Stage 3 + [9122] = {{x=33061, y=31527, z=12}, {x=32993, y=31547, z=4}, effect = true}, -- Farmine Stage 2 + [9123] = {{x=33061, y=31527, z=14}, {x=32993, y=31547, z=4}, effect = true} -- Farmine Stage 1 +} + +local elevatorLever = Action() + +function elevatorLever.onUse(cid, item, fromPosition, itemEx, toPosition) + local k = t[item.actionid] + local thing = getTopCreature(k[1]).uid + if(item.actionid == 9120 and item.itemid == 1945) then -- elevator to Farmine + if(isPlayer(thing)) then + if cid:getStorageValue(Storage.TheNewFrontier.Mission05) == 7 then -- if Farmine is on Stage 3 + k[2].z = 10 + elseif cid:getStorageValue(Storage.TheNewFrontier.Mission03) >= 2 then -- if Farmine is on Stage 2 + k[2].z = 12 + elseif cid:getStorageValue(Storage.TheNewFrontier.Mission03) < 2 then -- if Farmine is on Stage 1 + k[2].z = 14 + end + doTeleportThing(thing, k[2], false) + if(k.effect) then + doSendMagicEffect(k[2], CONST_ME_TELEPORT) + end + end + elseif(k and item.itemid == 1945) then + if(isPlayer(thing)) then + doTeleportThing(thing, k[2], false) + if(k.effect) then + doSendMagicEffect(k[2], CONST_ME_TELEPORT) + end + end + end + return doTransformItem(item.uid, item.itemid == 1945 and 1946 or 1945) +end + +elevatorLever:aid(9118, 9119, 9120, 9121, 9122, 9123) +elevatorLever:register() diff --git a/data/scripts/actions/farmine/oberon_lever.lua b/data/scripts/actions/farmine/oberon_lever.lua new file mode 100644 index 00000000000..fb5647a4d87 --- /dev/null +++ b/data/scripts/actions/farmine/oberon_lever.lua @@ -0,0 +1,59 @@ +local setting = { + centerRoom = {x = 33364, y = 31318, z = 9}, + storage = Storage.TheSecretLibrary.TheOrderOfTheFalcon.OberonTimer, + Pillar1pos = {x = 33361, y = 31316, z = 9}, + bossPosition = {x = 33364, y = 31317, z = 9}, + kickPosition = {x = 33300, y = 31289, z = 9}, + playerTeleport = {x = 33364, y = 31322, z = 9} +} + +local oberonLever = Action() + +-- Start Script +function oberonLever.onUse(creature, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 1945 and item.actionid == 57605 then + local clearOberonRoom = Game.getSpectators(Position(setting.centerRoom), false, false, 10, 10, 10, 10) + for index, spectatorcheckface in ipairs(clearOberonRoom) do + if spectatorcheckface:isPlayer() then + creature:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Someone is fighting against the boss! You need wait awhile.") + return false + end + end + for index, removeOberon in ipairs(clearOberonRoom) do + if (removeOberon:isMonster()) then + removeOberon:remove() + end + end + Game.createMonster("Grand Master Oberon", setting.bossPosition, false, true) + Game.createMonster("Oberon's Bile", Position({x = setting.Pillar1pos.x, y = setting.Pillar1pos.y, z = setting.Pillar1pos.z}), false, true) + Game.createMonster("Oberon's Hate", Position({x = setting.Pillar1pos.x + 6, y = setting.Pillar1pos.y, z = setting.Pillar1pos.z}), false, true) + Game.createMonster("Oberon's Spite", Position({x = setting.Pillar1pos.x, y = setting.Pillar1pos.y + 4, z = setting.Pillar1pos.z}), false, true) + Game.createMonster("Oberon's Ire", Position({x = setting.Pillar1pos.x + 6, y = setting.Pillar1pos.y + 4, z = setting.Pillar1pos.z}), false, true) + local players = {} + for i = 0, 4 do + local player1 = Tile({x = (Position(item:getPosition()).x - 2) + i, y = Position(item:getPosition()).y + 1, z = Position(item:getPosition()).z}):getTopCreature() + players[#players+1] = player1 + end + for i, player in ipairs(players) do + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:teleportTo(Position(setting.playerTeleport), false) + doSendMagicEffect(player:getPosition(), CONST_ME_TELEPORT) + setPlayerStorageValue(player,setting.storage, os.time() + 20 * 60 * 60) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have 20 minute(s) to defeat the boss.') + addEvent(function() + local spectatorsOberon = Game.getSpectators(Position(setting.centerRoom), false, false, 10, 10, 10, 10) + for u = 1, #spectatorsOberon, 1 do + if spectatorsOberon[u]:isPlayer() and (spectatorsOberon[u]:getName() == player:getName()) then + player:teleportTo(Position(setting.kickPosition)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Time is over.') + end + end + end, 20 * 60 * 1000) + end + end + return true +end + +oberonLever:aid(57605) +oberonLever:register() diff --git a/data/scripts/actions/farmine/temple_of_equilibrium_vines.lua b/data/scripts/actions/farmine/temple_of_equilibrium_vines.lua new file mode 100644 index 00000000000..626485ff590 --- /dev/null +++ b/data/scripts/actions/farmine/temple_of_equilibrium_vines.lua @@ -0,0 +1,19 @@ +local templeOfEquilibriumVines = Action() + +function templeOfEquilibriumVines.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.actionid == 12141 then + local destination = Position(33187, 31206, 7) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_POFF) + fromPosition:sendMagicEffect(CONST_ME_POFF) + player:say("The slippery vines barely hold your weight and you rather slide than climb down.", TALKTYPE_MONSTER_SAY) + else + player:say("The vines are too slippery down here to climb them.", TALKTYPE_MONSTER_SAY) + fromPosition:sendMagicEffect(CONST_ME_SMALLPLANTS) + end + return true +end + + +templeOfEquilibriumVines:aid(12141, 12142) +templeOfEquilibriumVines:register() diff --git a/data/scripts/actions/kazordoon/elevator_lever.lua b/data/scripts/actions/kazordoon/elevator_lever.lua new file mode 100644 index 00000000000..c6a537645da --- /dev/null +++ b/data/scripts/actions/kazordoon/elevator_lever.lua @@ -0,0 +1,33 @@ +local config = { + [50011] = Position(32636, 31881, 2), + [50012] = Position(32636, 31881, 7) +} + +local elevatorLever = Action() + +function elevatorLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local targetPosition = config[item.actionid] + if not targetPosition then + return true + end + + item:transform(item.itemid == 1945 and 1946 or 1945) + + toPosition.x = toPosition.x - 1 + local creature = Tile(toPosition):getTopCreature() + if not creature or not creature:isPlayer() then + return true + end + + if item.itemid ~= 1945 then + return true + end + + creature:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + creature:teleportTo(targetPosition) + targetPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +elevatorLever:aid(50011, 50012) +elevatorLever:register() diff --git a/data/scripts/actions/kazordoon/ore_wagons.lua b/data/scripts/actions/kazordoon/ore_wagons.lua new file mode 100644 index 00000000000..6b790b71870 --- /dev/null +++ b/data/scripts/actions/kazordoon/ore_wagons.lua @@ -0,0 +1,74 @@ +local config = { +-- outside wagons -- + [50136] = Position(32618, 31899, 9), + [50137] = Position(32620, 31899, 9), + [50138] = Position(32614, 31899, 9), + [50139] = Position(32616, 31899, 9), +-- kaz main gate wagons -- + [50140] = Position(32673, 31975, 15), -- Steamboat + [50141] = Position(32625, 31921, 11), -- Temple + [50142] = Position(32605, 31902, 9), -- Shops + [50143] = Position(32654, 31902, 8), -- Depot +-- kaz temple wagons -- + [50144] = Position(32575, 31974, 9), -- Main gate + [50145] = Position(32674, 31975, 15), -- Steamboat + [50146] = Position(32605, 31907, 9), -- Shops + [50147] = Position(32655, 31902, 8), -- Depot +-- kaz steamboat wagons -- + [50148] = Position(32575, 31977, 9), -- Main gate + [50149] = Position(32626, 31921, 11), -- Temple + [50150] = Position(32605, 31908, 9), -- Shops + [50151] = Position(32660, 31902, 8), -- Depot +-- kaz depot wagons -- + [50152] = Position(32575, 31968, 9), -- Main gate + [50153] = Position(32631, 31921, 11), -- Temple + [50154] = Position(32605, 31903, 9), -- Shops + [50155] = Position(32679, 31975, 15), -- Steamboat +-- kaz shop wagons -- + [50156] = Position(32678, 31975, 15), -- Steamboat + [50157] = Position(32630, 31921, 11), -- Temple + [50158] = Position(32659, 31902, 8), -- Depot + [50159] = Position(32575, 31971, 9), -- Main gate +-- inside to outside wagons -- + [50230] = Position(32600, 31875, 7), -- Kazordoon Surface North + [50231] = Position(32577, 31929, 0), -- Colossus Top + [50232] = Position(32619, 31944, 7), -- Kazordoon Surface South + [50233] = Position(32553, 31930, 7), -- Kazordoon Surface West +-- Lost Cavern + [50245] = Position(32526, 31840, 9), -- To: Entrance Area + [50246] = Position(32559, 31852, 7), -- To: Entrance Door + [50247] = Position(32499, 31827, 9), -- To: Crystal Storage + [50248] = Position(32517, 31806, 9), -- To: Crystal Mining + [50249] = Position(32515, 31827, 9), -- To: Entrance Area + [50250] = Position(32489, 31812, 9), -- To: Crystal Cultivation + [50251] = Position(32495, 31833, 9), -- To: Crystal Storage + [50252] = Position(32511, 31806, 9), -- To: Crystal Mining + [50253] = Position(32498, 31807, 9), -- To: Crystal Cultivation + [50254] = Position(32516, 31829, 9) -- To: Entrance Area +} + +local oreWagons = Action() + +function oreWagons.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local targetPosition = config[item.actionid] + if not targetPosition then + return true + end + + if item.actionid < 50245 and player:getStorageValue(Storage.WagonTicket) < os.time() then + player:say("Purchase a weekly ticket from Gewen, Lokur in the post office, The Lukosch brothers or from Brodrosch on the steamboat.", TALKTYPE_MONSTER_SAY) + return true + end + + player:addAchievementProgress('Rollercoaster', 100) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(targetPosition) + targetPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +for index, value in pairs(config) do + oreWagons:aid(index) +end + +oreWagons:register() diff --git a/data/scripts/actions/kazordoon/stone.lua b/data/scripts/actions/kazordoon/stone.lua new file mode 100644 index 00000000000..82abf2676ca --- /dev/null +++ b/data/scripts/actions/kazordoon/stone.lua @@ -0,0 +1,30 @@ +local config = { + {position = Position(32604, 31904, 3), itemId = 1300}, + {position = Position(32605, 31904, 3), itemId = 1301}, + {position = Position(32604, 31905, 3), itemId = 1302}, + {position = Position(32605, 31905, 3), itemId = 1303} +} + +local stone = Action() + +function stone.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 1945 then + local stoneItem + for i = 1, #config do + stoneItem = Tile(config[i].position):getItemById(config[i].itemId) + if stoneItem then + stoneItem:remove() + end + end + else + for i = 1, #config do + Game.createItem(config[i].itemId, 1, config[i].position) + end + end + + item:transform(item.itemid == 1945 and 1946 or 1945) + return true +end + +stone:aid(50237) +stone:register() diff --git a/data/scripts/actions/kazordoon/trap_door.lua b/data/scripts/actions/kazordoon/trap_door.lua new file mode 100644 index 00000000000..6302586f33f --- /dev/null +++ b/data/scripts/actions/kazordoon/trap_door.lua @@ -0,0 +1,26 @@ +local exitPosition = Position(32605, 31902, 4) + +local trapDoor = Action() + +function trapDoor.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local ground = Tile(exitPosition):getGround() + if ground and isInArray({369, 413}, ground.itemid) then + ground:transform(ground.itemid == 369 and 413 or 369) + + if ground.itemid == 369 then + local items = ground:getTile():getItems() + if items then + exitPosition.z = exitPosition.z + 1 + for i = 1, #items do + items[i]:moveTo(exitPosition) + end + end + end + end + + item:transform(item.itemid == 1945 and 1946 or 1945) + return true +end + +trapDoor:aid(50238) +trapDoor:register() diff --git a/data/scripts/actions/mounts/mounts.lua b/data/scripts/actions/mounts/mounts.lua new file mode 100644 index 00000000000..1b0c148a28f --- /dev/null +++ b/data/scripts/actions/mounts/mounts.lua @@ -0,0 +1,178 @@ +local ACTION_RUN, ACTION_BREAK, ACTION_NONE, ACTION_ALL = 1, 2, 3, 4 +local TYPE_MONSTER, TYPE_NPC, TYPE_ITEM, TYPE_ACTION, TYPE_UNIQUE = 1, 2, 3, 4, 5 + +local config = { + [5907] = {NAME = 'Bear', ID = 3, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 20, FAIL_MSG = { {1, 'The bear ran away.'}, {2, 'Oh no! The slingshot broke.'}, {3, 'The bear is trying to hit you with its claws.'} }, SUCCESS_MSG = 'You have tamed the war bear.', ACHIEV = "Bearbaiting"}, + [13295] = {NAME = 'Black Sheep', ID = 4, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 25, FAIL_MSG = { {1, 'The black sheep ran away.'}, {2, 'Oh no! The reins were torn.'}, {3, 'The black sheep is trying to run away.'} }, SUCCESS_MSG = 'You have tamed the sheep.', ACHIEV = "Little Ball of Wool"}, + [13247] = {NAME = 'Boar', ID = 10, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 40, FAIL_MSG = { {1, 'The boar has run away'}, {3, 'The boar attacks you.'} }, SUCCESS_MSG = 'You have tamed the boar.', ACHIEV = "Pig-Headed"}, + [13305] = {NAME = 'Crustacea Gigantica', ID = 7, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 40, FAIL_MSG = { {1, 'The crustacea has run away.'}, {2, 'The crustacea ate the shrimp.'} }, SUCCESS_MSG = 'You have tamed the crustacea.', ACHIEV = "Fried Shrimp"}, + [13536] = {NAME = 'Crystal Wolf', ID = 16, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 40, FAIL_MSG = { {1, 'The wolf has run away.'} }, SUCCESS_MSG = 'You have tamed the wolf.', ACHIEV = "The Right Tone"}, + [13537] = {NAME = 'Donkey', ID = 13, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 40, FAIL_MSG = { {1, 'The donkey transformation suddenly wears off.'}, {2, 'Heeee-haaa-haaa-haaw!'}, {3, 'You did not manage to feed the donkey enough apple slices.'} }, SUCCESS_MSG = 'Heeee-haaaaw!', ACHIEV = "Loyal Lad"}, + [18449] = {NAME = 'Dragonling', ID = 31, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 30, FAIL_MSG = { {1, "The dragonling got scared and ran away."}, {2, "The dragonling is trying to nibble."} }, SUCCESS_MSG = "You tamed a dragonling.", ACHIEV = "Dragon Mimicry"}, + [13294] = {NAME = 'Draptor', ID = 6, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 40, FAIL_MSG = { {1, 'The draptor has run away.'}, {3, 'The draptor has fled.'} }, SUCCESS_MSG = 'You have tamed the draptor.', ACHIEV = "Scales and Tail"}, + [13535] = {NAME = 'Dromedary', ID = 20, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 40, FAIL_MSG = { {1, 'Dromedary has run away.'} }, SUCCESS_MSG = 'You have tamed the dromedary.', ACHIEV = "Fata Morgana"}, + [13539] = {NAME = 'Enraged White Deer', ID = 18, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 40, FAIL_MSG = { {2, 'The cone broke.'}, {3, 'The deer has fled in fear.'} }, SUCCESS_MSG = 'You have tamed the white deer.', ACHIEV = "Friend of Elves"}, + [32491] = {NAME = 'Flying Book', ID = 126, BREAK = false, TYPE = TYPE_MONSTER, CHANCE = 20, FAIL_MSG = { {1, 'Flying Book has run away.'} }, SUCCESS_MSG = 'You have converted your library ticket and receive permission to ride a flying book.', ACHIEV = "Bibliomaniac"}, + [21452] = {NAME = 'Gravedigger', ID = 39, BREAK = false, TYPE = TYPE_MONSTER, CHANCE = 40, FAIL_MSG = { {1, "The gravedigger got scared and ran away."}, {3, "The gravedigger is trying to nibble."} }, SUCCESS_MSG = "You tamed the hellgrip.", ACHIEV = "Blacknailed"}, + [36411] = {NAME = 'Gryphon', ID = 144, BREAK = false, TYPE = TYPE_MONSTER, CHANCE = 30, FAIL_MSG = { {1, 'Gryphon has run away.'} }, SUCCESS_MSG = 'You have tamed the gryphon.', ACHIEV = "Gryphon Rider"}, + [34809] = {NAME = 'Hibernal Moth', ID = 131, BREAK = false, TYPE = TYPE_MONSTER, CHANCE = 20, FAIL_MSG = { {2, 'The hibernal moth is not interested in your lantern and flies away.'}, {4, 'The hibernal moth is not interested in your lantern and flies away.'} }, SUCCESS_MSG = 'You have tamed a hibernal moth.', ACHIEV = "Moth Whisperer"}, + [13292] = {NAME = 'inoperative tin lizzard', ID = 8, BREAK = true, TYPE = TYPE_ITEM, CHANCE = 40, FAIL_MSG = { {2, 'The key broke inside.'} }, SUCCESS_MSG = 'You wind up the tin lizzard.', ACHIEV = "Knock on Wood"}, + [13938] = {NAME = 'inoperative uniwheel', ID = 15, BREAK = true, TYPE = TYPE_ITEM, CHANCE = 40, FAIL_MSG = { {3, 'The oil have no effect.'}, {2, 'Splosh!'} }, SUCCESS_MSG = 'The strange wheel seems to vibrate and slowly starts turning continuously.', ACHIEV = "Stuntman"}, + [18447] = {NAME = 'Ironblight', ID = 29, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 30, FAIL_MSG = { {1, 'The ironblight managed to run away.'}, {2, 'Oh no! The magnet lost its power!'}, {3, 'The ironblight is fighting against the magnetic force.'} }, SUCCESS_MSG = 'You tamed the ironblight.', ACHIEV = "Magnetised"}, + [34808] = {NAME = 'Lacewing Moth', ID = 130, BREAK = false, TYPE = TYPE_MONSTER, CHANCE = 20, FAIL_MSG = { {2, 'The lacewing moth is not interested in your lantern and flies away.'}, {4, 'The lacewing moth is not interested in your lantern and flies away.'} }, SUCCESS_MSG = 'You have tamed a lancewing moth.', ACHIEV = "Lacewing Catcher"}, + [15546] = {NAME = 'Ladybug', ID = 27, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 30, FAIL_MSG = { {1, 'The ladybug got scared and ran away.'}, {3, 'The ladybug is trying to nibble.'} }, SUCCESS_MSG = 'You tame a lady bug.', ACHIEV = "Lovely Dots"}, + [18448] = {NAME = 'Magma Crawler', ID = 30, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 30, FAIL_MSG = { {1, 'The magma crawler refused to drink wine and vanishes into thin air.'}, {2, 'Argh! The magma crawler pushed you and you spilled the glow wine!'}, {3, 'The magma crawler is smelling the glow wine suspiciously.'} }, SUCCESS_MSG = 'The magma crawler will accompany you as a friend from now on.', ACHIEV = "Way to Hell"}, + [15545] = {NAME = 'Manta Ray', ID = 28, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 30, FAIL_MSG = { {1, 'The manta ray fled.'}, {3, 'The manta ray is trying to escape.'} }, SUCCESS_MSG = 'You have tamed the manta ray.', ACHIEV = "Beneath the Sea"}, + [13293] = {NAME = 'Midnight Panther', ID = 5, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 20, FAIL_MSG = { {1, 'The panther has escaped.'}, {2, 'The whip broke.'} },SUCCESS_MSG = 'You have tamed the panther.', ACHIEV = "Starless Night"}, + [18516] = {NAME = 'Modified Gnarlhound', ID = 32, BREAK = false, TYPE = TYPE_MONSTER, CHANCE = 100, FAIL_MSG = { }, SUCCESS_MSG = 'You now own a modified gnarlhound.', ACHIEV = "Mind the Dog!"}, + [30840] = {NAME = 'Mole', ID = 119, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 30, FAIL_MSG = { {2, 'The Mole is a bit capricious. Maybe I should leave it alone.'}, {4, 'The Mole is a bit capricious. Maybe I should leave it alone.'} }, SUCCESS_MSG = 'You tamed the mole.', ACHIEV = "Up the Molehill"}, + [23810] = {NAME = 'Noble Lion', ID = 40, BREAK = false, TYPE = TYPE_MONSTER, CHANCE = 30, FAIL_MSG = { {2, 'The lion got scared and ran away.'}, {4, 'The lion is trying to nibble.'} }, SUCCESS_MSG = 'You tamed the lion.', ACHIEV = "Lion King"}, + [13538] = {NAME = 'Panda', ID = 19, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 40, FAIL_MSG = { {4, 'Panda the leaves and ran away.'} }, SUCCESS_MSG = 'You have tamed the panda.', ACHIEV = "Chequered Teddy"}, + [13498] = {NAME = 'Sandstone Scorpion', ID = 21, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 40, FAIL_MSG = { {1, 'The scorpion has vanished.'}, {2, 'Scorpion broken the sceptre.'} }, SUCCESS_MSG = 'You have tamed the scorpion.', ACHIEV = "Golden Sands"}, + [22608] = {NAME = 'Shock Head', ID = 42, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 30, FAIL_MSG = { {1, 'The shock head ran away.'}, {3, 'The shock head is growling at you.'} }, SUCCESS_MSG = 'You tamed the shock head.', ACHIEV = "Personal Nightmare"}, + [27628] = {NAME = 'Stone Rhino', ID = 106, BREAK = false, TYPE = TYPE_MONSTER, CHANCE = 30, FAIL_MSG = { {1, 'The stone rhino ran away.'}, {3, 'The stone rhino is growling at you.'} }, SUCCESS_MSG = 'You tamed the stone rhino.', ACHIEV = "Rhino Rider"}, + [13508] = {NAME = 'Slug', ID = 14, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 40, FAIL_MSG = { {1, 'The slug has run away.'}, {3, 'The drug had no effect.'} }, SUCCESS_MSG = 'You have tamed the slug.', ACHIEV = "Slugging Around"}, + [13298] = {NAME = 'Terror Bird', ID = 2, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 15, FAIL_MSG = { {1, 'The bird ran away.'}, {3, 'The terror bird is pecking you.'} }, SUCCESS_MSG = 'You have tamed the bird.', ACHIEV = "Pecking Order"}, + [13291] = {NAME = 'Undead Cavebear', ID = 12, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 40, FAIL_MSG = { {1, 'The undead bear has run away.'} }, SUCCESS_MSG = 'You have tamed the skeleton.', ACHIEV = "Out of the Stone Age"}, + [13307] = {NAME = 'Wailing Widow', ID = 1, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 40, FAIL_MSG = { {1, 'The widow has run away.'}, {2, 'The widow has eaten the sweet bait.'} }, SUCCESS_MSG = 'You have tamed the widow.', ACHIEV = "Spin-Off"}, + [23557] = {NAME = 'Walker', ID = 43, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 30, FAIL_MSG = { {2, 'This walker is incompatible with your control unit.'}, {4, 'This walker is incompatible with your control unit.'} }, SUCCESS_MSG = 'You tamed the walker.', ACHIEV = "Gear Up"}, + [20138] = {NAME = 'Water Buffalo', ID = 35, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 30, FAIL_MSG = { {1, 'The water buffalo got scared and ran away.'}, {3, 'The water buffalo is trying to nibble.'} }, SUCCESS_MSG = 'You tamed a water buffalo.', ACHIEV = "Swamp Beast"}, + [13939] = {NAME = 'Wild Horse', ID = 17, BREAK = true, TYPE = TYPE_MONSTER, CHANCE = 15, FAIL_MSG = { {1, 'The horse runs away.'}, {2, 'The horse ate the oats.'} }, SUCCESS_MSG = 'You have tamed the horse.', ACHIEV = "Lucky Horseshoe"} + + +} + +local function doFailAction(cid, mount, pos, item, itemEx, loseItem) + local action, effect = mount.FAIL_MSG[math.random(#mount.FAIL_MSG)], CONST_ME_POFF + if(action[1] == ACTION_RUN) then + Creature(itemEx.uid):remove() + elseif(action[1] == ACTION_BREAK) then + effect = CONST_ME_BLOCKHIT + if loseItem then + Item(item.uid):remove(1) + end + elseif(action[1] == ACTION_ALL) then + Creature(itemEx.uid):remove() + if loseItem then + Item(item.uid):remove(1) + end + end + + pos:sendMagicEffect(effect) + Player(cid):say(action[2], TALKTYPE_MONSTER_SAY) + return action +end + +local mounts = Action() + +function mounts.onUse(cid, item, fromPosition, itemEx, toPosition) + local player = Player(cid) + local targetMonster = Monster(itemEx.uid) + local targetNpc = Npc(itemEx.uid) + local targetItem = Item(itemEx.uid) + local mount = config[item.itemid] + if mount == nil or player:hasMount(mount.ID) then + return false + end + + local rand = math.random(100) + --Monster Mount + if targetMonster ~= nil and mount.TYPE == TYPE_MONSTER then + if Creature(itemEx.uid):getMaster() then + player:say('You can\'t tame a summon!', TALKTYPE_MONSTER_SAY) + return true + end + + if mount.NAME == targetMonster:getName() then + if rand > mount.CHANCE then + doFailAction(cid, mount, toPosition, item, itemEx, mount.BREAK) + return true + end + if mount.ACHIEV then + player:addAchievement(mount.ACHIEV) + end + player:addAchievement("Natural Born Cowboy") + player:addMount(mount.ID) + player:say(mount.SUCCESS_MSG, TALKTYPE_MONSTER_SAY) + targetMonster:remove() + toPosition:sendMagicEffect(CONST_ME_MAGIC_GREEN) + Item(item.uid):remove(1) + return true + end + --NPC Mount + elseif targetNpc ~= nil and mount.TYPE == TYPE_NPC then + if mount.NAME == targetNpc:getName() then + if rand > mount.CHANCE then + doFailAction(cid, mount, toPosition, item, itemEx, mount.BREAK) + return true + end + if mount.ACHIEV then + player:addAchievement(mount.ACHIEV) + end + player:addAchievement("Natural Born Cowboy") + player:addMount(mount.ID) + player:say(mount.SUCCESS_MSG, TALKTYPE_MONSTER_SAY) + toPosition:sendMagicEffect(CONST_ME_MAGIC_GREEN) + Item(item.uid):remove(1) + return true + end + --Item Mount + elseif targetItem ~= nil and mount.TYPE == TYPE_ITEM then + if mount.NAME == targetItem:getName() then + if rand > mount.CHANCE then + doFailAction(cid, mount, toPosition, item, itemEx, mount.BREAK) + return true + end + if mount.ACHIEV then + player:addAchievement(mount.ACHIEV) + end + player:addAchievement("Natural Born Cowboy") + player:addMount(mount.ID) + player:say(mount.SUCCESS_MSG, TALKTYPE_MONSTER_SAY) + toPosition:sendMagicEffect(CONST_ME_MAGIC_GREEN) + Item(item.uid):remove(1) + return true + end + --Action Mount + elseif itemEx.actionid > 0 and mount.TYPE == TYPE_ACTION then + if(mount.NAME == itemEx.actionid) then + if rand > mount.CHANCE then + doFailAction(cid, mount, toPosition, item, itemEx, mount.BREAK) + return true + end + if mount.ACHIEV then + player:addAchievement(mount.ACHIEV) + end + player:addAchievement("Natural Born Cowboy") + player:addMount(mount.ID) + player:say(mount.SUCCESS_MSG, TALKTYPE_MONSTER_SAY) + toPosition:sendMagicEffect(CONST_ME_MAGIC_GREEN) + Item(item.uid):remove(1) + return true + end + --Unique Mount + elseif itemEx.uid <= 65535 and mount.TYPE == TYPE_UNIQUE then + if mount.NAME == itemEx.uid then + if rand > mount.CHANCE then + doFailAction(cid, mount, toPosition, item, itemEx, mount.BREAK) + return true + end + if mount.ACHIEV then + player:addAchievement(mount.ACHIEV) + end + player:addAchievement("Natural Born Cowboy") + player:addMount(mount.ID) + player:say(mount.SUCCESS_MSG, TALKTYPE_MONSTER_SAY) + toPosition:sendMagicEffect(CONST_ME_MAGIC_GREEN) + Item(item.uid):remove(1) + return true + end + end + return false +end + +for index, value in pairs(config) do + mounts:id(index) +end + +mounts:register() diff --git a/data/scripts/actions/mounts/music_box.lua b/data/scripts/actions/mounts/music_box.lua new file mode 100644 index 00000000000..86932f39b53 --- /dev/null +++ b/data/scripts/actions/mounts/music_box.lua @@ -0,0 +1,46 @@ +local config = { + ['dragonling'] = {mountId = 31, tameMessage = 'The wild dragonling will accompany you as a friend from now on.', sound = 'FI?', ACHIEV = "Dragon Mimicry"}, + ['draptor'] = {mountId = 6, tameMessage = 'You have tamed the wild draptor.', sound = 'Screeeeeeeeech', ACHIEV = "Scales and Tail"}, + ['enraged white deer'] = {mountId = 18, tameMessage = 'You have tamed the deer.', sound = 'bell', ACHIEV = "Friend of Elves"}, + ['ironblight'] = {mountId = 29, tameMessage = 'You tamed the ironblight.', sound = 'Plinngggg', ACHIEV = "Magnetised"}, + ['magma crawler'] = {mountId = 30, tameMessage = 'The magma crawler will accompany you as a friend from now on.', sound = 'ZzzZzzZzzzZz', ACHIEV = "Way to Hell"}, + ['midnight panther'] = {mountId = 5, tameMessage = 'You have tamed the wild panther.', sound = 'Purrrrrrr', ACHIEV = "Starless Night"}, + ['wailing widow'] = {mountId = 1, mountName = 'widow queen', tameMessage = 'You have tamed the wailing widow.', sound = 'Sssssssss', ACHIEV = "Spin-Off"}, + ['wild horse'] = {mountId = 17, mountName = 'war horse', tameMessage = 'The horse eats the sugar oat and accepts you as its new master.', sound = '*snort*', ACHIEV = "Lucky Horseshoe"}, + ['panda'] = {mountId = 19, tameMessage = 'You have tamed the panda.', sound = 'Rrrrr...', ACHIEV = "Chequered Teddy"} +} + +local musicBox = Action() + +function musicBox.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + if not target:isCreature() + or not target:isMonster() + or target:getMaster() then + return false + end + + local targetName = target:getName():lower() + local monsterConfig = config[targetName] + if not monsterConfig then + return true + end + + if player:hasMount(monsterConfig.mountId) then + player:say('You already tamed a ' .. (monsterConfig.mountName or targetName) .. '.', TALKTYPE_MONSTER_SAY) + return true + end + + player:addAchievement('Natural Born Cowboy') + player:addAchievement(monsterConfig.ACHIEV) + player:addMount(monsterConfig.mountId) + player:say(monsterConfig.tameMessage, TALKTYPE_MONSTER_SAY) + toPosition:sendMagicEffect(CONST_ME_SOUND_RED) + target:say(monsterConfig.sound, TALKTYPE_MONSTER_SAY) + target:remove() + item:remove() + return true +end + +musicBox:id(18511) +musicBox:register() diff --git a/data/scripts/actions/object/imbuement_shrine.lua b/data/scripts/actions/object/imbuement_shrine.lua new file mode 100644 index 00000000000..65aee70a037 --- /dev/null +++ b/data/scripts/actions/object/imbuement_shrine.lua @@ -0,0 +1,13 @@ +local imbuement = Action() + +function imbuement.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.ForgottenKnowledge.Tomes) ~= 1 then + return player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You did not collect enough knowledge from the ancient Shapers. Visit the Shaper temple in Thais for help.") + end + + player:sendImbuementPanel(target, true) + return true +end + +imbuement:id(27728, 27729, 27843, 27850, 27851) +imbuement:register() diff --git a/data/scripts/actions/object/market.lua b/data/scripts/actions/object/market.lua new file mode 100644 index 00000000000..64e55416d98 --- /dev/null +++ b/data/scripts/actions/object/market.lua @@ -0,0 +1,9 @@ +local market = Action() + +function market.onUse(player, item, fromPosition, target, toPosition, isHotkey) + player:openMarket() + return true +end + +market:id(14405) +market:register() diff --git a/data/scripts/actions/object/moonlight_crystals.lua b/data/scripts/actions/object/moonlight_crystals.lua new file mode 100644 index 00000000000..3e2c0d42f33 --- /dev/null +++ b/data/scripts/actions/object/moonlight_crystals.lua @@ -0,0 +1,33 @@ +local moonlightCrystals = Action() + +function moonlightCrystals.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid == 24716 then + target:transform(24717) + item:remove(1) + return true + elseif target.itemid == 24718 then + if (player:getStorageValue(Storage.Grimvale.WereHelmetEnchant) == 0) or (player:getStorageValue(Storage.Grimvale.WereHelmetEnchant) == 1) then + target:transform(24783) -- Magic level helmet + item:remove(1) + elseif player:getStorageValue(Storage.Grimvale.WereHelmetEnchant) == 2 then + target:transform(24788) -- Paladin helmet + item:remove(1) + elseif player:getStorageValue(Storage.Grimvale.WereHelmetEnchant) == 3 then + target:transform(24784) -- Knight club + item:remove(1) + elseif player:getStorageValue(Storage.Grimvale.WereHelmetEnchant) == 4 then + target:transform(24786) -- Knight axe + item:remove(1) + elseif player:getStorageValue(Storage.Grimvale.WereHelmetEnchant) == 5 then + target:transform(24785) -- Knight sword + item:remove(1) + else + return false + end + return true + end + return false +end + +moonlightCrystals:id(24739) +moonlightCrystals:register() diff --git a/data/scripts/actions/object/stash.lua b/data/scripts/actions/object/stash.lua new file mode 100644 index 00000000000..dcef07e74a1 --- /dev/null +++ b/data/scripts/actions/object/stash.lua @@ -0,0 +1,9 @@ +local stash = Action() + +function stash.onUse(player, item, fromPosition, target, toPosition, isHotkey) + player:openStash() + return true +end + +stash:id(32450) +stash:register() diff --git a/data/scripts/actions/oramond/elevator.lua b/data/scripts/actions/oramond/elevator.lua new file mode 100644 index 00000000000..80766f15859 --- /dev/null +++ b/data/scripts/actions/oramond/elevator.lua @@ -0,0 +1,46 @@ +local firstFloor = Position(33638, 31903, 6) +local secondFloor = Position(33638, 31903, 5) +local elevatorPusherItemId = 23424 +local elevatorStructureItemId = 23428 +local elevatorBaseItemId = 23432 + +local elevator = Action() + +function elevator.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getPosition() ~= firstFloor and player:getPosition() ~= secondFloor then + return true + end + + local firstTile = Tile(firstFloor) + local secondTile = Tile(secondFloor) + local fromTile = nil + local toTile = nil + + if firstTile:getItemById(elevatorBaseItemId, -1) then + fromTile = firstTile + toTile = secondTile + else + fromTile = secondTile + toTile = firstTile + end + + local elevatorStructureItem = fromTile:getItemById(elevatorStructureItemId, -1) + local elevatorBaseItem = fromTile:getItemById(elevatorBaseItemId, -1) + + elevatorBaseItem:moveTo(toTile) + player:teleportTo(toTile:getPosition()) + elevatorStructureItem:moveTo(toTile) + + local elevatorPusherItem = toTile:getItemById(elevatorPusherItemId, -1) + if not elevatorPusherItem then + elevatorPusherItem = fromTile:getItemById(elevatorPusherItemId, -1) + elevatorPusherItem:moveTo(toTile) + else + elevatorPusherItem:moveTo(fromTile) + end + + return true +end + +elevator:id(23422, 23429) +elevator:register() diff --git a/data/scripts/actions/oramond/sewer_grate.lua b/data/scripts/actions/oramond/sewer_grate.lua new file mode 100644 index 00000000000..99a296d3a0f --- /dev/null +++ b/data/scripts/actions/oramond/sewer_grate.lua @@ -0,0 +1,15 @@ +local upFloorIds = {23669} + +local sewerGrate = Action() + +function sewerGrate.onUse(cid, item, fromPosition, itemEx, toPosition) + if isInArray(upFloorIds, item.itemid) == TRUE then + fromPosition.x = fromPosition.x + 1 + fromPosition.z = fromPosition.z + 2 + end + doTeleportThing(cid, fromPosition, FALSE) + return TRUE +end + +sewerGrate:id(23669) +sewerGrate:register() diff --git a/data/scripts/actions/oramond/sewer_grate_teleport.lua b/data/scripts/actions/oramond/sewer_grate_teleport.lua new file mode 100644 index 00000000000..92a6fabd6e1 --- /dev/null +++ b/data/scripts/actions/oramond/sewer_grate_teleport.lua @@ -0,0 +1,15 @@ +local upFloorIds = {23668} + +local sewerGrateTeleport = Action() + +function sewerGrateTeleport.onUse(cid, item, fromPosition, itemEx, toPosition) + if isInArray(upFloorIds, item.itemid) == TRUE then + fromPosition.x = fromPosition.x + 1 + fromPosition.z = fromPosition.z - 2 + end + doTeleportThing(cid, fromPosition, FALSE) + return TRUE +end + +sewerGrateTeleport:id(23668) +sewerGrateTeleport:register() diff --git a/data/scripts/actions/oramond/teleport_north.lua b/data/scripts/actions/oramond/teleport_north.lua new file mode 100644 index 00000000000..8fb65accb38 --- /dev/null +++ b/data/scripts/actions/oramond/teleport_north.lua @@ -0,0 +1,10 @@ +local teleportNorth = Action() + +function teleportNorth.onUse(cid, item, fromPosition, itemEx, toPosition) + fromPosition.z = fromPosition.z - 1 + doTeleportThing(cid, fromPosition, FALSE) + return TRUE +end + +teleportNorth:id(22949) +teleportNorth:register() diff --git a/data/scripts/actions/oramond/teleport_west.lua b/data/scripts/actions/oramond/teleport_west.lua new file mode 100644 index 00000000000..a2c434a7e9f --- /dev/null +++ b/data/scripts/actions/oramond/teleport_west.lua @@ -0,0 +1,10 @@ +local teleportWest = Action() + +function teleportWest.onUse(cid, item, fromPosition, itemEx, toPosition) + fromPosition.z = fromPosition.z - 1 + doTeleportThing(cid, fromPosition, FALSE) + return TRUE +end + +teleportWest:id(22944) +teleportWest:register() diff --git a/data/scripts/actions/other/bag_you_desire.lua b/data/scripts/actions/other/bag_you_desire.lua new file mode 100644 index 00000000000..5623f2c2448 --- /dev/null +++ b/data/scripts/actions/other/bag_you_desire.lua @@ -0,0 +1,36 @@ +local rewards = { + { id = 38917, name = "Soulcutter" }, + { id = 38918, name = "Soulshredder" }, + { id = 38919, name = "Soulbiter" }, + { id = 38920, name = "Souleater" }, + { id = 38921, name = "Soulcrusher" }, + { id = 38922, name = "Soulmaimer" }, + { id = 38923, name = "Soulbleeder" }, + { id = 38924, name = "Soulpiercer" }, + { id = 38925, name = "Soultainter" }, + { id = 38926, name = "Soulhexer" }, + { id = 38927, name = "Soulshanks" }, + { id = 38928, name = "Soulstrider" }, + { id = 38929, name = "Soulshell" }, + { id = 38930, name = "Soulmantel" }, + { id = 38931, name = "Soulshroud" }, + { id = 38932, name = "Pair of Soulwalkers" }, + { id = 38933, name = "Pair of Soulstalkers" }, + { id = 38934, name = "Soulbastion" } +} + +local bagyouDesire = Action() + +function bagyouDesire.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local randId = math.random(1, #rewards) + local rewardItem = rewards[randId] + + player:addItem(rewardItem.id, 1) + item:remove(1) + + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You received a ' .. rewardItem.name .. '.') + return true +end + +bagyouDesire:id(38944) +bagyouDesire:register() \ No newline at end of file diff --git a/data/scripts/actions/other/baking.lua b/data/scripts/actions/other/baking.lua new file mode 100644 index 00000000000..8a6ba4d5f66 --- /dev/null +++ b/data/scripts/actions/other/baking.lua @@ -0,0 +1,42 @@ +local liquidContainers = {1775, 2005, 2006, 2007, 2008, 2009, 2011, 2012, 2013, 2014, 2015, 2023, 2031, 2032, 2033} +local millstones = {1381, 1382, 1383, 1384} +local dough = {6277, 8846} +local oven = {1786, 1788, 1790, 1792 } + +local baking = Action() + +function baking.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 2692 and isInArray(liquidContainers, target.itemid) then + if target.type == 1 then + item:transform(item.itemid, item.type - 1) + player:addItem(2693, 1) + target:transform(target.itemid, 0) + elseif target.type == 6 then + item:transform(item.itemid, item.type - 1) + player:addItem(6277, 1) + target:transform(target.itemid, 0) + end + elseif isInArray(dough, item.itemid) then + if target.itemid == 1786 then + item:transform(item.itemid + 1) + elseif target.itemid == 6574 then + item:transform(8846) + target:remove() + end + elseif isInArray(oven, target.itemid) then + item:transform(item.itemid, item.type - 1) + player:addItem(2689, 1) + elseif item.itemid == 5467 and target.itemid == 2694 then + item:transform(13939) + target:remove() + elseif isInArray(millstones, target.itemid) then + item:transform(item.itemid, item.type - 1) + player:addItem(2692, 1) + else + return false + end + return true +end + +baking:id(2692, 2693, 2694, 6277, 8846) +baking:register() diff --git a/data/scripts/actions/other/bath_tub.lua b/data/scripts/actions/other/bath_tub.lua new file mode 100644 index 00000000000..fc9d51b60e2 --- /dev/null +++ b/data/scripts/actions/other/bath_tub.lua @@ -0,0 +1,12 @@ +local bathtubDrain = Action() +function bathtubDrain.onUse(player, item, fromPosition, itemEx, toPosition) + local tile = Tile(fromPosition) + if tile:getTopCreature() then + return false + end + + item:transform(BATHTUB_EMPTY) +end + +bathtubDrain:id(BATHTUB_FILLED) +bathtubDrain:register() \ No newline at end of file diff --git a/data/scripts/actions/other/bed_modification_kits.lua b/data/scripts/actions/other/bed_modification_kits.lua new file mode 100644 index 00000000000..a01d4b5b4a1 --- /dev/null +++ b/data/scripts/actions/other/bed_modification_kits.lua @@ -0,0 +1,54 @@ +local beds = { + [7904] = {{7811, 7812}, {7813, 7814}}, -- green kit + [7905] = {{7819, 7820}, {7821, 7822}}, -- yellow kit + [7906] = {{7815, 7816}, {7817, 7818}}, -- red kit + [7907] = {{1754, 1755}, {1760, 1761}}, -- removal kit + [20252] = {{20197, 20198}, {20199, 20200}} -- canopy kit +} + +local function internalBedTransform(item, target, toPosition, itemArray) + target:transform(itemArray[1]) + target:getPosition():sendMagicEffect(CONST_ME_POFF) + + toPosition:getTile():getItemByType(ITEM_TYPE_BED):transform(itemArray[2]) + toPosition:sendMagicEffect(CONST_ME_POFF) + + item:remove() +end + +local bedModificationKits = Action() + +function bedModificationKits.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local newBed = beds[item.itemid] + if not newBed then + return false + end + + local tile = toPosition:getTile() + if not tile or not tile:getHouse() then + return false + end + + if target.itemid == newBed[1][1] or target.itemid == newBed[2][1] then + player:sendTextMessage(MESSAGE_FAILURE, "You already have this bed modification.") + return true + end + + for kit, bed in pairs(beds) do + if bed[1][1] == target.itemid or isInArray({1758, 5502, 18027}, target.itemid) then + toPosition:sendMagicEffect(CONST_ME_POFF) + toPosition.y = toPosition.y + 1 + internalBedTransform(item, target, toPosition, newBed[1]) + break + elseif bed[2][1] == target.itemid or isInArray({1756, 5500, 18029}, target.itemid) then + toPosition:sendMagicEffect(CONST_ME_POFF) + toPosition.x = toPosition.x + 1 + internalBedTransform(item, target, toPosition, newBed[2]) + break + end + end + return true +end + +bedModificationKits:id(7904, 7905, 7906, 7907, 20252) +bedModificationKits:register() diff --git a/data/scripts/actions/other/blessing_charms.lua b/data/scripts/actions/other/blessing_charms.lua new file mode 100644 index 00000000000..e475007cc38 --- /dev/null +++ b/data/scripts/actions/other/blessing_charms.lua @@ -0,0 +1,10 @@ +dofile('data/modules/scripts/blessings/blessings.lua') + +local blessingCharms = Action() + +function blessingCharms.onUse(player, item, fromPosition, target, toPosition, isHotkey) + return Blessings.useCharm(player, item) +end + +blessingCharms:id(11258, 11259, 11260, 11261, 11262, 28036, 28037) +blessingCharms:register() diff --git a/data/scripts/actions/other/blueberry_bush.lua b/data/scripts/actions/other/blueberry_bush.lua new file mode 100644 index 00000000000..bd5c872058d --- /dev/null +++ b/data/scripts/actions/other/blueberry_bush.lua @@ -0,0 +1,12 @@ +local blueberryBush = Action() + +function blueberryBush.onUse(player, item, fromPosition, target, toPosition, isHotkey) + item:transform(2786) + item:decay() + Game.createItem(2677, 3, fromPosition) + player:addAchievementProgress('Bluebarian', 500) + return true +end + +blueberryBush:id(2785) +blueberryBush:register() diff --git a/data/scripts/actions/other/carpets.lua b/data/scripts/actions/other/carpets.lua new file mode 100644 index 00000000000..2b5b3b5a435 --- /dev/null +++ b/data/scripts/actions/other/carpets.lua @@ -0,0 +1,92 @@ +local carpetItems = { + [25393] = 25392, --rift carpet + [25392] = 25393, --rift carpet + [26193] = 26192, --void carpet + [26192] = 26193, --void carpet + [26087] = 26109, --yalahahari carpet + [26109] = 26087, --yalahahari carpet + [26088] = 26110, --white fur carpet + [26110] = 26088, --white fur carpet + [26089] = 26111, --bamboo mat carpet + [26111] = 26089, --bamboo matr carpet + [26371] = 26363, --crimson carpet + [26363] = 26371, --crimson carpet + [26366] = 26372, --azure carpet + [26372] = 26366, --azure carpet + [26367] = 26373, --emerald carpet + [26373] = 26367, --emerald carpet + [26368] = 26374, --light parquet carpet + [26374] = 26368, --light parquet carpet + [26369] = 26375, --dark parquet carpet + [26375] = 26369, --dark parquet carpet + [26370] = 26376, --mable floor + [26376] = 26370, --marble floor + [27084] = 27092, --flowery carpet + [27092] = 27084, --flowery carpet + [27085] = 27093, --Colourful Carpet + [27093] = 27085, --Colourful Carpet + [27086] = 27094, --striped carpet + [27094] = 27086, --striped carpet + [27087] = 27095, --fur carpet + [27095] = 27087, --fur carpet + [27088] = 27096, --diamond carpet + [27096] = 27088, --diamond carpet + [27089] = 27097, --patterned carpet + [27097] = 27089, --patterned carpet + [27090] = 27098, --night sky carpet + [27098] = 27090, --night sky carpet + [27091] = 27099, --star carpet + [27099] = 27091, --star carpet + [29350] = 29351, --verdant carpet + [29351] = 29350, --verdant carpet + [29352] = 29353, --shaggy carpet + [29353] = 29352, --shaggy carpet + [29355] = 29354, --mystic carpet + [29354] = 29355, --mystic carpet + [29356] = 29357, --stone tile + [29357] = 29356, --stone tile + [29359] = 29358, --wooden plank + [29358] = 29359, --wooden plank + [29386] = 29387, --wheat carpet + [29387] = 29386, --wheat carpet + [29388] = 29389, --crested carpet + [29389] = 29388, --crested carpet + [29390] = 29391, --decorated carpet + [29391] = 29390, --decorated carpet + [36301] = 36303, --tournament carpet + [36303] = 36301, --tournament carpet + [36302] = 36304, --sublime tournament carpet + [36304] = 36302, --sublime tournament carpet + [40776] = 40777, --grandiose carpet + [40777] = 40776, --grandiose carpet +} + +local carpets = Action() + +function carpets.onUse(player, item, fp, target, toPosition, isHotkey) + local carpet = carpetItems[item.itemid] + if not carpet then + return false + end + + local fromPosition = item:getPosition() + local tile = Tile(fromPosition) + if not fromPosition:getTile():getHouse() then + player:sendTextMessage(MESSAGE_FAILURE, "You may use this only inside a house.") + elseif tile:getItemCountById(item.itemid) == 1 then + for k,v in pairs(carpetItems) do + if tile:getItemCountById(k) > 0 and k ~= item.itemid then + player:sendCancelMessage(Game.getReturnMessage(RETURNVALUE_NOTPOSSIBLE)) + return true + end + end + item:transform(carpet) + end + return true +end + +for index, value in pairs(carpetItems) do + carpets:id(index) +end + +carpets:register() diff --git a/data/scripts/actions/other/cask_kegs.lua b/data/scripts/actions/other/cask_kegs.lua new file mode 100644 index 00000000000..4a4a7f2f4bd --- /dev/null +++ b/data/scripts/actions/other/cask_kegs.lua @@ -0,0 +1,63 @@ +local targetIdList = { + --health potions casks + [28555] = {itemId = 7636, transform = 7618}, [28579] = {itemId = 7636, transform = 7618}, -- Health Potion -- + [28556] = {itemId = 7634, transform = 7588}, [28580] = {itemId = 7634, transform = 7588}, -- Strong Health -- + [28557] = {itemId = 7635, transform = 7591}, [28581] = {itemId = 7635, transform = 7591}, -- Great Health -- + [28558] = {itemId = 7635, transform = 8473}, [28582] = {itemId = 7635, transform = 8473}, -- Ultimate Health -- + [28559] = {itemId = 7635, transform = 26031}, [28583] = {itemId = 7635, transform = 26031}, -- Supreme Health -- + --mana potions casks + [28565] = {itemId = 7636, transform = 7620}, [28584] = {itemId = 7636, transform = 7620}, -- Mana Potion -- + [28566] = {itemId = 7634, transform = 7589}, [28585] = {itemId = 7634, transform = 7589}, -- Strong Mana -- + [28567] = {itemId = 7635, transform = 7590}, [28586] = {itemId = 7635, transform = 7590}, -- Great Mana -- + [28568] = {itemId = 7635, transform = 26029}, [28587] = {itemId = 7635, transform = 26029}, -- Ultimate Mana -- + --spirit potions caks + [28575] = {itemId = 7635, transform = 8472}, [28589] = {itemId = 7635, transform = 8472}, -- Great Spirit -- + [28576] = {itemId = 7635, transform = 26030}, [28590] = {itemId = 7635, transform = 26030}, --Ultimate Spirit -- + } + +local flasks = Action() + +function flasks.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target:getId() >= 28535 and target:getId() <= 28590 then + local house = player:getTile():getHouse() + if house and house:canEditAccessList(SUBOWNER_LIST, player) and house:canEditAccessList(doorId, player) or target:getId() >= 28579 then + elseif target:getId() >= 28535 and target:getId() < 28579 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Sorry, casks only can be useds inside house.') + return false + else + return false + end + + if target then + local charges = target:getCharges() + local itemCount = item:getCount() + if itemCount > charges then + itemCount = charges + end + + local targetId = targetIdList[target:getId()] + if targetId then + if item:getId() == targetId.itemId then + if not(itemCount == item:getCount()) then + local potMath = item:getCount() - itemCount + if not(item:getParent():isContainer() and item:getParent():addItem(item:getId(), potMath)) then + player:addItem(item:getId(), potMath, true) + end + end + item:transform(targetId.transform, itemCount) + charges = charges - itemCount + target:transform(target:getId(), charges) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format('Remaining %s charges.', charges)) + + if charges == 0 then + target:remove() + end + end + end + end + return true +end +end + +flasks:id(7634, 7635, 7636) +flasks:register() diff --git a/data/scripts/actions/other/catch_fish.lua b/data/scripts/actions/other/catch_fish.lua new file mode 100644 index 00000000000..775efcc5b5a --- /dev/null +++ b/data/scripts/actions/other/catch_fish.lua @@ -0,0 +1,19 @@ +local catchFish = Action() + +function catchFish.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid ~= 5554 then + return false + end + + if math.random(10) ~= 1 then + player:say("The golden fish escaped.", TALKTYPE_MONSTER_SAY) + return true + end + player:say("You catch a golden fish in the bowl.", TALKTYPE_MONSTER_SAY) + item:transform(5929) + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + return true +end + +catchFish:id(5928) +catchFish:register() diff --git a/data/scripts/actions/other/check_bless.lua b/data/scripts/actions/other/check_bless.lua new file mode 100644 index 00000000000..b307394f77f --- /dev/null +++ b/data/scripts/actions/other/check_bless.lua @@ -0,0 +1,10 @@ +dofile('data/modules/scripts/blessings/blessings.lua') + +local checkBless = Action() + +function checkBless.onUse(player, item, fromPosition, target, toPosition, isHotkey) + return Blessings.checkBless(player) +end + +checkBless:id(6561, 12424) +checkBless:register() diff --git a/data/scripts/actions/other/clay_lump.lua b/data/scripts/actions/other/clay_lump.lua new file mode 100644 index 00000000000..9cf88b5a3f2 --- /dev/null +++ b/data/scripts/actions/other/clay_lump.lua @@ -0,0 +1,43 @@ +local config = { + {chance = {0.0, 1.1}, transformId = 11342, description = 'This little figurine of Brog, the raging Titan, was skillfully made by |PLAYERNAME|.', achievement = true}, + {chance = {1.1, 10.52}, transformId = 11341, description = 'It was made by |PLAYERNAME| and is clearly a little figurine of.. hm, one does not recognise that yet.'}, + {chance = {10.52, 35.38}, transformId = 11340, description = 'It was made by |PLAYERNAME|, whose potter skills could use some serious improvement.'}, + {chance = {35.38, 100.0}, remove = true, sound = 'Aw man. That did not work out too well.'} +} + +local clayLump = Action() + +function clayLump.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local random, tmpItem = math.random(0, 10000) * 0.01 + for i = 1, #config do + tmpItem = config[i] + if random >= tmpItem.chance[1] and random < tmpItem.chance[2] then + item:getPosition():sendMagicEffect(CONST_ME_POFF) + + if tmpItem.remove then + item:remove() + else + item:transform(tmpItem.transformId) + end + + if tmpItem.sound then + player:say(tmpItem.sound, TALKTYPE_MONSTER_SAY, false, player) + end + + if tmpItem.description then + item:setDescription(tmpItem.description:gsub('|PLAYERNAME|', player:getName())) + end + + if tmpItem.achievement then + player:addAchievement('Clay Fighter') + player:addAchievementProgress('Clay to Fame', 5) + end + + break + end + end + return true +end + +clayLump:id(11339) +clayLump:register() diff --git a/data/scripts/actions/other/cobra_flask.lua b/data/scripts/actions/other/cobra_flask.lua new file mode 100644 index 00000000000..a41a4a6fcb8 --- /dev/null +++ b/data/scripts/actions/other/cobra_flask.lua @@ -0,0 +1,19 @@ +local cobraFlask = Action() + +function cobraFlask.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if (item.itemid == 36132) and (target.itemid == 3007) then + item:transform(36131) + target:transform(3008) + target:decay() + return + elseif (item.itemid == 36131) and ((target.itemid == 36119) or (target.itemid == 36120) or (target.itemid == 36121) or (target.itemid == 36122)) then + doSendMagicEffect(target:getPosition(), CONST_ME_GREENSMOKE) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You carefully pour just a tiny, little, finely dosed... and there goes the whole content of the bottle. Stand back!") + item:transform(36132) + setGlobalStorageValue(GlobalStorage.CobraBastionFlask, os.time() + 1800) -- 30 minutes + end + return +end + +cobraFlask:id(36131, 36132) +cobraFlask:register() diff --git a/data/scripts/actions/other/construction_kits.lua b/data/scripts/actions/other/construction_kits.lua new file mode 100644 index 00000000000..e564f4a9bd5 --- /dev/null +++ b/data/scripts/actions/other/construction_kits.lua @@ -0,0 +1,140 @@ +local constructionKits = { + [3901] = 1666, + [3902] = 1670, + [3903] = 1652, + [3904] = 1674, + [3905] = 1658, + [3906] = 3813, + [3907] = 3817, + [3908] = 1619, + [3909] = 12799, + [3910] = 2105, + [3911] = 1614, + [3912] = 3806, + [3913] = 3807, + [3914] = 3809, + [3915] = 1716, + [3916] = 1724, + [3917] = 1732, + [3918] = 1775, + [3919] = 1774, + [3920] = 1750, + [3921] = 3832, + [3922] = 2095, + [3923] = 2098, + [3924] = 2064, + [3925] = 2582, + [3926] = 2117, + [3927] = 1728, + [3928] = 1442, + [3929] = 1446, + [3930] = 1447, + [3931] = 2034, + [3932] = 2604, + [3933] = 2080, + [3934] = 2084, + [3935] = 3821, + [3936] = 3811, + [3937] = 2101, + [3938] = 3812, + [5086] = 5046, + [5087] = 5055, + [5088] = 5056, + [6114] = 6111, + [6115] = 6109, + [6372] = 6356, + [6373] = 6371, + [8692] = 8688, + [9974] = 9975, + [11126] = 11127, + [11133] = 11129, + [11124] = 11125, + [11205] = 11203, + [14328] = 1616, + [14329] = 1615, + [16075] = 16020, + [16099] = 16098, + [20254] = 20295, + [20255] = 20297, + [20257] = 20299 +} + +local jackToTheFuture_Kits = { + [3901] = { + itemId = 1666, + kitMessage = "The red cushioned chair looks quite comfy in that corner.", + jackSay = "Jack: Yeah uhm... impressive chair. Now would you please remove it? Thanks.", + storage = Storage.TibiaTales.JackFutureQuest.Furniture01 + }, + [3923] = { + itemId = 2098, + kitMessage = "A globe like this should be in every household.", + jackSay = "Jack: What the... what do I need a 'globe' for? Take this away.", + storage = Storage.TibiaTales.JackFutureQuest.Furniture02 + }, + [3925] = { + itemId = 2582, + kitMessage = "The telescope just looks like it was the one thing missing from this room.", + jackSay = "Jack: Nice, a... what is this actually?", + storage = Storage.TibiaTales.JackFutureQuest.Furniture03 + }, + [3926] = { + itemId = 2117, + kitMessage = "What a cute horse - and just the right thing to place into this cute room.", + jackSay = "Jack: A rocking horse? What's wrong with you.", + storage = Storage.TibiaTales.JackFutureQuest.Furniture04 + }, + [3931] = { + itemId = 2034, + kitMessage = "There seems to be no better place for this amphora than right here.", + jackSay = "Jack: Trying to get rid of your junk in my house? Do I look like I need such a... 'vase'?", + storage = Storage.TibiaTales.JackFutureQuest.Furniture05 + } +} + +local jackToTheFuture_House = { + beginPos = Position(33273, 31754, 7), + finalPos = Position(33278, 31759, 7) +} + +local constructionKit = Action() + +function constructionKit.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getPosition():isInRange(jackToTheFuture_House.beginPos, jackToTheFuture_House.finalPos) then + if player:getStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine) == 3 then + local setting = jackToTheFuture_Kits[item.itemid] + if setting then + if player:getStorageValue(setting.storage) < 1 then + item:remove() + Game.createItem(setting.itemId, 1, player:getPosition()) + player:say(setting.jackSay, TALKTYPE_MONSTER_SAY) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, setting.kitMessage) + player:setStorageValue(setting.storage, 1) + return true + end + end + end + end + + local kit = constructionKits[item.itemid] + if not kit then + return false + end + + if fromPosition.x == CONTAINER_POSITION then + player:sendTextMessage(MESSAGE_FAILURE, "Put the construction kit on the floor first.") + elseif not fromPosition:getTile():getHouse() then + player:sendTextMessage(MESSAGE_FAILURE, "You may construct this only inside a house.") + else + item:transform(kit) + fromPosition:sendMagicEffect(CONST_ME_POFF) + player:addAchievementProgress("Interior Decorator", 1000) + end + return true +end + +for index, value in pairs(constructionKits) do + constructionKit:id(index) +end + +constructionKit:register() diff --git a/data/scripts/actions/other/costume_bags.lua b/data/scripts/actions/other/costume_bags.lua new file mode 100644 index 00000000000..6cc57932ce0 --- /dev/null +++ b/data/scripts/actions/other/costume_bags.lua @@ -0,0 +1,24 @@ +local config = { + [7737] = {'orc warrior', 'pirate cutthroat', 'dworc voodoomaster', 'dwarf guard', 'minotaur mage', 'ogre shaman', 'ogre brute', 'rat'}, -- common + [7739] = {'serpent spawn', 'demon', 'juggernaut', 'behemoth', 'ashmunrah', 'vexclaw', 'grimeleech', 'hellflayer', 'black sheep'}, -- uncommon + [9076] = {'quara hydromancer', 'diabolic imp', 'banshee', 'frost giant', 'lich', 'vexclaw', 'grimeleech', 'hellflayer', 'ogre shaman', 'ogre brute', 'pig'}, -- deluxe + [27617] = {'old beholder', 'old bug', 'old wolf', 'old giant spider'} -- old +} + +local costumeBags = Action() + +function costumeBags.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local monsterNames = config[item.itemid] + if not monsterNames then + return true + end + player:sendTextMessage(MESSAGE_STATUS, 'You will stay 5 minutes transformed in a monster!') + doSetMonsterOutfit(player, monsterNames[math.random(#monsterNames)], 300 * 1000) + player:addAchievementProgress('Masquerader', 100) + item:getPosition():sendMagicEffect(36) + item:remove() + return true +end + +costumeBags:id(7737, 7739, 9076, 27617) +costumeBags:register() diff --git a/data/scripts/actions/other/create_sugar_oat.lua b/data/scripts/actions/other/create_sugar_oat.lua new file mode 100644 index 00000000000..436d8685c4a --- /dev/null +++ b/data/scripts/actions/other/create_sugar_oat.lua @@ -0,0 +1,20 @@ +local createSugarOat = Action() + +function createSugarOat.onUse(cid, item, fromPosition, itemEx, toPosition, isHotkey) + local player = Player(cid) + if itemEx.itemid == 2694 then + if toPosition.x ~= CONTAINER_POSITION then + Game.createItem(13939, 1, toPosition) + else + player:addItem(13939, 1) + toPosition = player:getPosition() + end + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + Item(item.uid):remove(1) + Item(itemEx.uid):remove(1) + end + return true +end + +createSugarOat:id(5467) +createSugarOat:register() diff --git a/data/scripts/actions/other/cup_cakes.lua b/data/scripts/actions/other/cup_cakes.lua new file mode 100644 index 00000000000..1c143ac4520 --- /dev/null +++ b/data/scripts/actions/other/cup_cakes.lua @@ -0,0 +1,51 @@ +local data = { +[31719] = { + Type = "mana", + ExhaustStor = Storage.BlueberryCupcake, + timestamp = 10 + }, +[31720] = { + Type = "health", + ExhaustStor = Storage.StrawberryCupcake, + timestamp = 10 + }, +[31721] = { + Type = "skill", + ExhaustStor = Storage.LemonCupcake, + timestamp = 10 + } +} + +local lemon = Condition(CONDITION_ATTRIBUTES) +lemon:setParameter(CONDITION_PARAM_TICKS, 60 * 60 * 1000) +lemon:setParameter(CONDITION_PARAM_SKILL_DISTANCE, 10) + +local cupCakes = Action() + +function cupCakes.onUse(player, item, fromPos, itemEx, toPos) +local foundItem = data[item.itemid] + if not(foundItem) then + return + end + if (player:getStorageValue(foundItem.ExhaustStor)) < os.time() then + if foundItem.Type == "mana" then + player:addMana(player:getMaxMana()) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your mana has been refilled.") + elseif foundItem.Type == "health" then + player:addHealth(player:getMaxHealth()) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your health has been refilled.") + elseif foundItem.Type == "skill" then + player:addCondition(lemon) + player:sendTextMessage(MESSAGE_FAILURE, "You feel more focused.") + end + player:say("Mmmm.",TALKTYPE_ORANGE_1) + item:remove(1) + player:setStorageValue(foundItem.ExhaustStor, os.time() + (foundItem.timestamp * 60)) + else + player:sendTextMessage(MESSAGE_FAILURE, "You need to wait before using it again.") + end + return true +end + +cupCakes:id(31719, 31720, 31721) +cupCakes:register() diff --git a/data/scripts/actions/other/cup_of_molten_gold.lua b/data/scripts/actions/other/cup_of_molten_gold.lua new file mode 100644 index 00000000000..ba8e4b89744 --- /dev/null +++ b/data/scripts/actions/other/cup_of_molten_gold.lua @@ -0,0 +1,24 @@ +local items = { + [0] = {id = 2152, count = 3, chance = 100}, + [1] = {id = 2013, count = 1, chance = 80}, + [2] = {id = 13539, count = 1, chance = 25}, +} + +local cupOfMoltenGold = Action() + +function cupOfMoltenGold.onUse(cid, item, fromPosition, itemEx, toPosition) + + if itemEx.itemid == 2700 or itemEx.itemid == 21428 then + doRemoveItem(item.uid, 1) + for i = 0, #items do + if (items[i].chance > math.random(1, 100)) then + doPlayerAddItem(cid, items[i].id, items[i].count) + doSendMagicEffect(toPosition, CONST_ME_EXPLOSIONAREA) + end + end + end + return true +end + +cupOfMoltenGold:id(13941) +cupOfMoltenGold:register() diff --git a/data/scripts/actions/other/daily_reward_shrine.lua b/data/scripts/actions/other/daily_reward_shrine.lua new file mode 100644 index 00000000000..31f8b725beb --- /dev/null +++ b/data/scripts/actions/other/daily_reward_shrine.lua @@ -0,0 +1,9 @@ +local dailyRewardShrine = Action() + +function dailyRewardShrine.onUse(player, item, fromPosition, itemEx, toPosition) + DailyReward.loadDailyReward(player,0) + return true +end + +dailyRewardShrine:id(29021, 29022, 29023, 29024, 29089, 29090) +dailyRewardShrine:register() diff --git a/data/scripts/actions/other/destroy.lua b/data/scripts/actions/other/destroy.lua new file mode 100644 index 00000000000..c1f4d549d4d --- /dev/null +++ b/data/scripts/actions/other/destroy.lua @@ -0,0 +1,44 @@ +local scimitarPos = {x = 33205, y = 32537, z = 6} + +local function removeScimitar(position) + local scimitarItem = Tile(position):getItemById(5858) + if scimitarItem then + scimitarItem:remove() + end +end + +local destroy = Action() + +function destroy.onUse(player, item, fromPosition, target, toPosition, isHotkey) + -- Tibia tales quest, Aritos task + local itemPosition = {x = 33205, y = 32537, z = 6} + if (toPosition == itemPosition) then + local itemTile = Tile(itemPosition) + local getItem = itemTile:getItemById(22679) + if getItem then + if player:getStorageValue(Storage.TibiaTales.AritosTask) >= 0 then + item:remove() + Game.createItem(5858, 1, scimitarPos) + addEvent(removeScimitar, 1 * 60 * 1000, scimitarPos) + return true + end + end + end + return onDestroyItem(player, item, fromPosition, target, toPosition, isHotkey) +end + +for id = 2376, 2404 do + destroy:id(id) +end +for id = 2408, 2415 do + destroy:id(id) +end +for id = 2417, 2419 do + destroy:id(id) +end +for id = 2421, 2453 do + destroy:id(id) +end +destroy:id(2406) + +destroy:register() diff --git a/data/scripts/actions/other/dice.lua b/data/scripts/actions/other/dice.lua new file mode 100644 index 00000000000..bd0c6c8f31a --- /dev/null +++ b/data/scripts/actions/other/dice.lua @@ -0,0 +1,18 @@ +local dice = Action() + +function dice.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local dicePosition = item:getPosition() + local value = math.random(6) + local isInGhostMode = player:isInGhostMode() + + dicePosition:sendMagicEffect(CONST_ME_CRAPS, isInGhostMode and player) + local spectators = Game.getSpectators(dicePosition, false, true, 3, 3) + for i = 1, #spectators do + player:say(player:getName() .. " rolled a " .. value .. ".", TALKTYPE_MONSTER_SAY, isInGhostMode, spectators[i], dicePosition) + end + item:transform(5791 + value) + return true +end + +dice:id(5792, 5793, 5794, 5795, 5796, 5797) +dice:register() diff --git a/data/scripts/actions/other/dolls.lua b/data/scripts/actions/other/dolls.lua new file mode 100644 index 00000000000..84727716c7a --- /dev/null +++ b/data/scripts/actions/other/dolls.lua @@ -0,0 +1,100 @@ +local dolls = { + [5080] = {"Hug me."}, + [5669] = { + "It's not winning that matters, but winning in style.", + "Today's your lucky day. Probably.", + "Do not meddle in the affairs of dragons, for you are crunchy and taste good with ketchup.", + "That is one stupid question.", + "You'll need more rum for that.", + "Do or do not. There is no try.", + "You should do something you always wanted to.", + "If you walk under a ladder and it falls down on you it probably means bad luck.", + "Never say 'oops'. Always say 'Ah, interesting!'", + "Five steps east, fourteen steps south, two steps north and seventeen steps west!" + }, + [6566] = { + "Fchhhhhh!", + "Zchhhhhh!", + "Grooaaaaar*cough*", + "Aaa... CHOO!", + "You... will.... burn!!" + }, + [6388] = {"Merry Christmas |PLAYERNAME|."}, + [6512] = { + "Ho ho ho", + "Jingle bells, jingle bells...", + "Have you been naughty?", + "Have you been nice?", + "Merry Christmas!", + "Can you stop squeezing me now... I'm starting to feel a little sick." + }, + [8974] = {"ARE YOU PREPARED TO FACE YOUR DESTINY?"}, + [8977] = { + "Weirdo, you're a weirdo! Actually all of you are!", + "Pie for breakfast, pie for lunch and pie for dinner!", + "All hail the control panel!", + "I own, Tibiacity owns, perfect match!", + "Hug me! Feed me! Hail me!" + }, + [8981] = { + "It's news to me.", + "News, updated as infrequently as possible!", + "Extra! Extra! Read all about it!", + "Fresh off the press!" + }, + [8982] = { + "Hail TibiaNordic!", + "So cold..", + "Run, mammoth!" + }, + [23806] = { + "I can hear their whisperings... Revenge!", + "You shall feel pain and terror, |PLAYERNAME|", + "I do not need a sword to slaughter you", + "My sword is broken, but my spirit is not dead", + "I can say 469 and more...", + "My dark magic lies on tibialatina.wikia.com" + }, + [24331] = {"Hail Tibia Brasileiros! (União&Força)"} +} + +local doll = Action() + +function doll.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local sounds = dolls[item.itemid] + if not sounds then + return false + end + + if fromPosition.x == CONTAINER_POSITION then + fromPosition = player:getPosition() + end + + local random = math.random(#sounds) + local sound = sounds[random] + if item.itemid == 6566 then + if random == 3 then + fromPosition:sendMagicEffect(CONST_ME_POFF) + elseif random == 4 then + fromPosition:sendMagicEffect(CONST_ME_FIREAREA) + elseif random == 5 then + doTargetCombatHealth(0, player, COMBAT_PHYSICALDAMAGE, -1, -1, CONST_ME_EXPLOSIONHIT) + end + elseif item.itemid == 5669 then + fromPosition:sendMagicEffect(CONST_ME_MAGIC_RED) + item:transform(item.itemid + 1) + item:decay() + elseif item.itemid == 6388 then + fromPosition:sendMagicEffect(CONST_ME_SOUND_YELLOW) + end + + sound = sound:gsub('|PLAYERNAME|', player:getName()) + player:say(sound, TALKTYPE_MONSTER_SAY, false, 0, fromPosition) + return true +end + +for index, value in pairs(dolls) do + doll:id(index) +end + +doll:register() diff --git a/data/scripts/actions/other/door_shive1.lua b/data/scripts/actions/other/door_shive1.lua new file mode 100644 index 00000000000..57202650547 --- /dev/null +++ b/data/scripts/actions/other/door_shive1.lua @@ -0,0 +1,16 @@ +local doorShive1 = Action() + +function doorShive1.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local position = player:getPosition() + if position.y == toPosition.y then + return false + end + + toPosition.y = position.y > toPosition.y and toPosition.y - 1 or toPosition.y + 1 + player:teleportTo(toPosition) + toPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +doorShive1:id(14755, 14756, 14757, 14758, 14759, 14760) +doorShive1:register() diff --git a/data/scripts/actions/other/door_shive2.lua b/data/scripts/actions/other/door_shive2.lua new file mode 100644 index 00000000000..3f73bf6440b --- /dev/null +++ b/data/scripts/actions/other/door_shive2.lua @@ -0,0 +1,16 @@ +local doorShive2 = Action() + +function doorShive2.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local position = player:getPosition() + if position.x == toPosition.x then + return false + end + + toPosition.x = position.x > toPosition.x and toPosition.x - 1 or toPosition.x + 1 + player:teleportTo(toPosition) + toPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +doorShive2:id(14767, 14768, 14769, 14770, 14771) +doorShive2:register() diff --git a/data/scripts/actions/other/down_floor.lua b/data/scripts/actions/other/down_floor.lua new file mode 100644 index 00000000000..2d969800e74 --- /dev/null +++ b/data/scripts/actions/other/down_floor.lua @@ -0,0 +1,11 @@ +local downFloor = Action() + +function downFloor.onUse(player, item, fromPosition, itemEx, toPosition) + fromPosition.x = fromPosition.x + 1 + fromPosition.z = fromPosition.z + 1 + player:teleportTo(fromPosition, false) + return true +end + +downFloor:aid(102) +downFloor:register() diff --git a/data/scripts/actions/other/dryad_garden.lua b/data/scripts/actions/other/dryad_garden.lua new file mode 100644 index 00000000000..a8cc73b4a05 --- /dev/null +++ b/data/scripts/actions/other/dryad_garden.lua @@ -0,0 +1,28 @@ +local dryadPos = { + -- unique id, destination + -- entrance + [33331] = Position(33202 , 32012, 11), + + -- exit + [33332] = Position(33264 , 32012, 7) + +} + +local dryadAction = Action() + +function dryadAction.onUse(player, item, target, position, fromPosition) + local destination = dryadPos[item.uid] + if not destination then + return true + end + + player:teleportTo(destination) + player:getPosition():sendMagicEffect(CONST_ME_WATERSPLASH) + return true +end + +for i, x in pairs(dryadPos) do + dryadAction:uid(i) +end + +dryadAction:register() diff --git a/data/scripts/actions/other/enchanting.lua b/data/scripts/actions/other/enchanting.lua new file mode 100644 index 00000000000..02d892217bb --- /dev/null +++ b/data/scripts/actions/other/enchanting.lua @@ -0,0 +1,143 @@ +local config = { + manaCost = 300, + soulCost = 2, +} + +local spheres = { + [7759] = {VOCATION.CLIENT_ID.PALADIN}, + [7760] = {VOCATION.CLIENT_ID.SORCERER}, + [7761] = {VOCATION.CLIENT_ID.DRUID}, + [7762] = {VOCATION.CLIENT_ID.KNIGHT} +} + +local enchantableGems = {2147, 2146, 2149, 2150} +local enchantableItems = {2383, 7383, 7384, 7406, 7402, 2429, 2430, 7389, 7380, 2454, 2423, 2445, 7415, 7392, 2391, 2544, 8905} + +local enchantingAltars = { + {7504, 7505, 7506, 7507}, + {7508, 7509, 7510, 7511}, + {7516, 7517, 7518, 7519}, + {7512, 7513, 7514, 7515} +} + +local enchantedGems = {7760, 7759, 7761, 7762} +local enchantedItems = { + [2383] = {7744, 7763, 7854, 7869}, + [7383] = {7745, 7764, 7855, 7870}, + [7384] = {7746, 7765, 7856, 7871}, + [7406] = {7747, 7766, 7857, 7872}, + [7402] = {7748, 7767, 7858, 7873}, + [2429] = {7749, 7768, 7859, 7874}, + [2430] = {7750, 7769, 7860, 7875}, + [7389] = {7751, 7770, 7861, 7876}, + [7380] = {7752, 7771, 7862, 7877}, + [2454] = {7753, 7772, 7863, 7878}, + [2423] = {7754, 7773, 7864, 7879}, + [2445] = {7755, 7774, 7865, 7880}, + [7415] = {7756, 7775, 7866, 7881}, + [7392] = {7757, 7776, 7867, 7882}, + [2391] = {7758, 7777, 7868, 7883}, + [2544] = {7840, 7839, 7850, 7838}, + [8905] = {8906, 8907, 8909, 8908} +} + +local enchanting = Action() + +function enchanting.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + if table.contains({33268, 33269}, toPosition.x) + and toPosition.y == 31830 and toPosition.z == 10 + and player:getStorageValue(Storage.ElementalSphere.QuestLine) > 0 then + if not table.contains(spheres[item.itemid], player:getVocation():getClientId()) then + return false + elseif table.contains({7915, 7916}, target.itemid) then + player:say('Turn off the machine first.', TALKTYPE_MONSTER_SAY) + return true + else + player:setStorageValue(Storage.ElementalSphere.MachineGemCount, math.max(1, player:getStorageValue(Storage.ElementalSphere.MachineGemCount) + 1)) + toPosition:sendMagicEffect(CONST_ME_PURPLEENERGY) + item:transform(item.itemid, item.type - 1) + return true + end + end + + if item.itemid == 2147 and target.itemid == 2342 then + target:transform(2343) + target:decay() + item:remove(1) + toPosition:sendMagicEffect(CONST_ME_MAGIC_RED) + return true + end + + if item.itemid == 7760 and isInArray({9934, 10022}, target.itemid) then + target:transform(9933) + item:remove(1) + toPosition:sendMagicEffect(CONST_ME_MAGIC_RED) + return true + end + + if isInArray(enchantableGems, item.itemid) then + local subtype = item.type + if subtype == 0 then + subtype = 1 + end + + local mana = config.manaCost * subtype + if player:getMana() < mana then + player:say('Not enough mana, separate one gem in your backpack and try again.', TALKTYPE_MONSTER_SAY) + return false + end + + local soul = config.soulCost * subtype + if player:getSoul() < soul then + player:sendCancelMessage(RETURNVALUE_NOTENOUGHSOUL) + return false + end + + local targetId = table.find(enchantableGems, item.itemid) + if not targetId or not isInArray(enchantingAltars[targetId], target.itemid) then + return false + end + + player:addMana(-mana) + player:addSoul(-soul) + item:transform(enchantedGems[targetId]) + player:addManaSpent(items.valuables.mana) + player:getPosition():sendMagicEffect(CONST_ME_HOLYDAMAGE) + return true + end + + if item.itemid == 7761 and isInArray({9949, 9954}, target.itemid) then + target:transform(target.itemid - 1) + target:decay() + item:remove(1) + toPosition:sendMagicEffect(CONST_ME_MAGIC_GREEN) + return true + end + + if isInArray(enchantedGems, item.itemid) then + if not isInArray(enchantableItems, target.itemid) then + fromPosition:sendMagicEffect(CONST_ME_POFF) + return false + end + + local targetId = table.find(enchantedGems, item.itemid) + if not targetId then + return false + end + + local subtype = target.type + if not isInArray({2544, 8905}, target.itemid) then + subtype = 1000 + end + + target:transform(enchantedItems[target.itemid][targetId], subtype) + target:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + item:remove(1) + return true + end + return false +end + +enchanting:id(7759, 7760, 7761, 7762) +enchanting:register() diff --git a/data/scripts/actions/other/exercise_training.lua b/data/scripts/actions/other/exercise_training.lua new file mode 100644 index 00000000000..1282e521a08 --- /dev/null +++ b/data/scripts/actions/other/exercise_training.lua @@ -0,0 +1,178 @@ +local skills = { + [32384] = {id=SKILL_SWORD,voc=4}, -- KNIGHT + [32385] = {id=SKILL_AXE,voc=4}, -- KNIGHT + [32386] = {id=SKILL_CLUB,voc=4}, -- KNIGHT + [32387] = {id=SKILL_DISTANCE,voc=3,range=CONST_ANI_SIMPLEARROW}, -- PALADIN + [32388] = {id=SKILL_MAGLEVEL,voc=2,range=CONST_ANI_SMALLICE}, -- DRUID + [32389] = {id=SKILL_MAGLEVEL,voc=1,range=CONST_ANI_FIRE}, -- SORCERER + [32124] = {id=SKILL_SWORD,voc=4}, -- KNIGHT + [32125] = {id=SKILL_AXE,voc=4}, -- KNIGHT + [32126] = {id=SKILL_CLUB,voc=4}, -- KNIGHT + [32127] = {id=SKILL_DISTANCE,voc=3,range=CONST_ANI_SIMPLEARROW}, -- PALADIN + [32128] = {id=SKILL_MAGLEVEL,voc=2,range=CONST_ANI_SMALLICE}, -- DRUID + [32129] = {id=SKILL_MAGLEVEL,voc=1,range=CONST_ANI_FIRE}, -- SORCERER + [40114] = {id=SKILL_SWORD,voc=4}, -- KNIGHT + [40115] = {id=SKILL_AXE,voc=4}, -- KNIGHT + [40116] = {id=SKILL_CLUB,voc=4}, -- KNIGHT + [40117] = {id=SKILL_DISTANCE,voc=3,range=CONST_ANI_SIMPLEARROW}, -- PALADIN + [40118] = {id=SKILL_MAGLEVEL,voc=2,range=CONST_ANI_SMALLICE}, -- DRUID + [40119] = {id=SKILL_MAGLEVEL,voc=1,range=CONST_ANI_FIRE}, -- SORCERER + [40120] = {id=SKILL_SWORD,voc=4}, -- KNIGHT + [40121] = {id=SKILL_AXE,voc=4}, -- KNIGHT + [40122] = {id=SKILL_CLUB,voc=4}, -- KNIGHT + [40123] = {id=SKILL_DISTANCE,voc=3,range=CONST_ANI_SIMPLEARROW}, -- PALADIN + [40124] = {id=SKILL_MAGLEVEL,voc=2,range=CONST_ANI_SMALLICE}, -- DRUID + [40125] = {id=SKILL_MAGLEVEL,voc=1,range=CONST_ANI_FIRE} -- SORCERER +} + +local houseDummies = {32143, 32144, 32145, 32146, 32147, 32148} +local freeDummies = {32142, 32149} +local skillRateDefault = configManager.getNumber(configKeys.RATE_SKILL) +local magicRateDefault = configManager.getNumber(configKeys.RATE_MAGIC) + +local function removeExerciseWeapon(player, exercise) + exercise:remove(1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your training weapon vanished.") + stopEvent(training) + player:setStorageValue(Storage.isTraining,0) + player:setTraining(false) +end + +local function startTraining(playerId, startPosition, itemid, tilePosition, bonusDummy, dummyId) + local player = Player(playerId) + if player ~= nil then + if Tile(tilePosition):getItemById(dummyId) then + local playerPosition = player:getPosition() + if startPosition:getDistance(playerPosition) == 0 and getTilePzInfo(playerPosition) then + if player:getItemCount(itemid) >= 1 then + local exercise = player:getItemById(itemid,true) + if exercise:isItem() then + if exercise:hasAttribute(ITEM_ATTRIBUTE_CHARGES) then + local charges_n = exercise:getAttribute(ITEM_ATTRIBUTE_CHARGES) + if charges_n >= 1 then + exercise:setAttribute(ITEM_ATTRIBUTE_CHARGES,(charges_n-1)) + + local voc = player:getVocation() + + if skills[itemid].id == SKILL_MAGLEVEL then + local magicRate = getRateFromTable(magicLevelStages, player:getMagicLevel(), magicRateDefault) + if not bonusDummy then + player:addManaSpent(math.ceil(500*magicRate)) + else + player:addManaSpent(math.ceil(500*magicRate)*1.1) -- 10% + end + else + local skillRate = getRateFromTable(skillsStages, player:getEffectiveSkillLevel(skills[itemid].id), skillRateDefault) + if not bonusDummy then + player:addSkillTries(skills[itemid].id, 7*skillRate) + else + player:addSkillTries(skills[itemid].id, (7*skillRate)*1.1) -- 10% + end + end + tilePosition:sendMagicEffect(CONST_ME_HITAREA) + if skills[itemid].range then + playerPosition:sendDistanceEffect(tilePosition, skills[itemid].range) + end + if exercise:getAttribute(ITEM_ATTRIBUTE_CHARGES) == 0 then + removeExerciseWeapon(player, exercise) + else + local training = addEvent(startTraining, voc:getAttackSpeed(), playerId,startPosition,itemid,tilePosition,bonusDummy,dummyId) + player:setStorageValue(Storage.isTraining,1) + player:setTraining(true) + end + else + removeExerciseWeapon(player, exercise) + end + end + end + end + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your training has stopped.") + stopEvent(training) + player:setStorageValue(Storage.isTraining,0) + player:setTraining(false) + end + else + stopEvent(training) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your training has stopped.") + player:setStorageValue(Storage.isTraining, 0) + player:setTraining(false) + end + else + stopEvent(training) + if player then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your training has stopped.") + player:setStorageValue(Storage.isTraining,0) + player:setTraining(false) + end + end + return true +end + +local exerciseTraining = Action() + +function exerciseTraining.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local startPos = player:getPosition() + if player:getStorageValue(Storage.isTraining) == 1 then + player:sendTextMessage(MESSAGE_FAILURE, "You are already training.") + return false + end + if target:isItem() then + if isInArray(houseDummies,target:getId()) then + if not skills[item.itemid].range and (startPos:getDistance(target:getPosition()) > 1) then + player:sendTextMessage(MESSAGE_FAILURE, "Get closer to the dummy.") + stopEvent(training) + return true + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You started training.") + startTraining(player:getId(),startPos,item.itemid,target:getPosition(), true, target:getId()) + elseif isInArray(freeDummies, target:getId()) then + if not skills[item.itemid].range and (startPos:getDistance(target:getPosition()) > 1) then + player:sendTextMessage(MESSAGE_FAILURE, "Get closer to the dummy.") + stopEvent(training) + return true + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You started training.") + startTraining(player:getId(),startPos,item.itemid,target:getPosition(), false, target:getId()) + end + end + return true +end + +for id = 32124, 32126 do + exerciseTraining:id(id) +end + +for id = 32127, 32129 do + exerciseTraining:id(id) + exerciseTraining:allowFarUse(true) +end + +for id = 32384, 32386 do + exerciseTraining:id(id) +end + +for id = 32387, 32389 do + exerciseTraining:id(id) + exerciseTraining:allowFarUse(true) +end + +for id = 40114, 40116 do + exerciseTraining:id(id) +end + +for id = 40117, 40119 do + exerciseTraining:id(id) + exerciseTraining:allowFarUse(true) +end + +for id = 40120, 40122 do + exerciseTraining:id(id) +end + +for id = 40123, 40125 do + exerciseTraining:id(id) + exerciseTraining:allowFarUse(true) +end + +exerciseTraining:register() diff --git a/data/scripts/actions/other/fireworks_rocket.lua b/data/scripts/actions/other/fireworks_rocket.lua new file mode 100644 index 00000000000..6045fce8f55 --- /dev/null +++ b/data/scripts/actions/other/fireworks_rocket.lua @@ -0,0 +1,19 @@ +local fireworksRocket = Action() + +function fireworksRocket.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if fromPosition.x ~= CONTAINER_POSITION then + fromPosition:sendMagicEffect(math.random(CONST_ME_FIREWORK_YELLOW, CONST_ME_FIREWORK_BLUE)) + else + local position = player:getPosition() + position:sendMagicEffect(CONST_ME_HITBYFIRE) + position:sendMagicEffect(CONST_ME_EXPLOSIONAREA) + player:say("Ouch! Rather place it on the ground next time.", TALKTYPE_MONSTER_SAY) + player:addHealth(-10, COMBAT_PHYSICALDAMAGE) + end + player:addAchievementProgress('Fireworks in the Sky', 250) + item:remove() + return true +end + +fireworksRocket:id(6576) +fireworksRocket:register() diff --git a/data/scripts/actions/other/fish_tank.lua b/data/scripts/actions/other/fish_tank.lua new file mode 100644 index 00000000000..7774f77321d --- /dev/null +++ b/data/scripts/actions/other/fish_tank.lua @@ -0,0 +1,9 @@ +local fishTank = Action() + +function fishTank.onUse(cid, item, fromPosition, itemEx, toPosition) + item:getPosition():sendMagicEffect(175) + return true +end + +fishTank:id(26347) +fishTank:register() diff --git a/data/scripts/actions/other/fishing.lua b/data/scripts/actions/other/fishing.lua new file mode 100644 index 00000000000..8c192fe25b1 --- /dev/null +++ b/data/scripts/actions/other/fishing.lua @@ -0,0 +1,117 @@ +local waterIds = {493, 4608, 4609, 4610, 4611, 13550, 13552, 4612, 4613, 4614, 4615, 4616, 4617, 4618, 4619, 4620, 4621, 4622, 4623, 4624, 4625, 7236, 10499, 15401, 15402, 13549, 23785} +local lootTrash = {2234, 2238, 2376, 2509, 2667} +local lootCommon = {2152, 2167, 2168, 2669, 7588, 7589} +local lootRare = {2143, 2146, 2149, 7158, 7159} +local lootVeryRare = {7632, 7633, 10220} +local lootVeryRare1 = {7632, 13546} +local lootRare1 = {2143, 13546} +local lootCommon1 = {2152, 7589, 13546} + +local useWorms = true + +local fishing = Action() + +function fishing.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if not isInArray(waterIds, target.itemid) then + return false + end + + local targetId = target.itemid + if targetId == 10499 then + local owner = target:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) + if owner ~= 0 and owner ~= player.uid then + player:sendTextMessage(MESSAGE_FAILURE, "You are not the owner.") + return true + end + + toPosition:sendMagicEffect(CONST_ME_WATERSPLASH) + target:remove() + + local rareChance = math.random(100) + if rareChance == 1 then + player:addItem(lootVeryRare[math.random(#lootVeryRare)], 1) + elseif rareChance <= 3 then + player:addItem(lootRare[math.random(#lootRare)], 1) + elseif rareChance <= 10 then + player:addItem(lootCommon[math.random(#lootCommon)], 1) + else + player:addItem(lootTrash[math.random(#lootTrash)], 1) + end + return true + end + + if targetId == 13549 then + toPosition:sendMagicEffect(CONST_ME_WATERSPLASH) + local rareChance = math.random(100) + if rareChance == 1 then + player:addItem(lootVeryRare1[math.random(#lootVeryRare1)], 1) + elseif rareChance <= 3 then + player:addItem(lootRare1[math.random(#lootRare1)], 1) + elseif rareChance <= 10 then + player:addItem(lootCommon1[math.random(#lootCommon1)], 1) + else + player:addItem(lootTrash[math.random(#lootTrash)], 1) + end + return true + end + + if targetId ~= 7236 then + toPosition:sendMagicEffect(CONST_ME_LOSEENERGY) + end + + if targetId == 493 or targetId == 15402 then + return true + end + + if useWorms and player:removeItem("worm", 1) and targetId == 23785 then + if player:getStorageValue(Storage.Quest.Dawnport.TheDormKey) == 2 then + if math.random(100) >= 97 then + player:addItem(23773, 1) + player:setStorageValue(Storage.Quest.Dawnport.TheDormKey, 3) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "With a giant splash, you heave an enormous fish out of the water.") + return true + end + elseif math.random(100) <= math.min(math.max(10 + (player:getEffectiveSkillLevel(SKILL_FISHING) - 10) * 0.597, 10), 50) then + player:addItem(2667, 1) + end + end + + player:addSkillTries(SKILL_FISHING, 1) + if math.random(100) <= math.min(math.max(10 + (player:getEffectiveSkillLevel(SKILL_FISHING) - 10) * 0.597, 10), 50) then + if useWorms and not player:removeItem("worm", 1) then + return true + end + + if targetId == 15401 then + target:transform(targetId + 1) + target:decay() + + if math.random(100) >= 97 then + player:addItem(15405, 1) + return true + end + elseif targetId == 7236 then + target:transform(targetId + 1) + target:decay() + + local rareChance = math.random(100) + if rareChance == 1 then + player:addItem(7158, 1) + return true + elseif rareChance <= 4 then + player:addItem(2669, 1) + return true + elseif rareChance <= 10 then + player:addItem(7159, 1) + return true + end + end + player:addItem(2667, 1) + end + return true +end + +fishing:id(2580) +fishing:allowFarUse(true) +fishing:register() + diff --git a/data/scripts/actions/other/fluids.lua b/data/scripts/actions/other/fluids.lua new file mode 100644 index 00000000000..32287fc89e0 --- /dev/null +++ b/data/scripts/actions/other/fluids.lua @@ -0,0 +1,190 @@ +local drunk = Condition(CONDITION_DRUNK) +drunk:setParameter(CONDITION_PARAM_TICKS, 60000) + +local poison = Condition(CONDITION_POISON) +poison:setParameter(CONDITION_PARAM_DELAYED, true) +poison:setParameter(CONDITION_PARAM_MINVALUE, -50) +poison:setParameter(CONDITION_PARAM_MAXVALUE, -120) +poison:setParameter(CONDITION_PARAM_STARTVALUE, -5) +poison:setParameter(CONDITION_PARAM_TICKINTERVAL, 4000) +poison:setParameter(CONDITION_PARAM_FORCEUPDATE, true) + +local fluidMessage = { + [3] = 'Aah...', + [4] = 'Urgh!', + [5] = 'Mmmh.', + [7] = 'Aaaah...', + [10] = 'Aaaah...', + [11] = 'Urgh!', + [13] = 'Urgh!', + [15] = 'Aah...', + [19] = 'Urgh!', + [43] = 'Aaaah...' +} + +local function graveStoneTeleport(cid, fromPosition, toPosition) + local player = Player(cid) + if not player then + return true + end + + player:teleportTo(toPosition) + player:say('Muahahahaha..', TALKTYPE_MONSTER_SAY, false, player) + fromPosition:sendMagicEffect(CONST_ME_DRAWBLOOD) + toPosition:sendMagicEffect(CONST_ME_MORTAREA) +end + +-- Special poison condition used on dawnport residents +-- Doesnt allow poison yourself when health is <= 10 or your health go low than 10 due poison +function dawnportPoisonCondition(player) + local health = player:getHealth(); + local minHealth = 10 + -- Default poison values (not possible read condition parameters) + local startValue = 5 + local minPoisonDamage = 50 + local maxPoisonDamage = 120 + + -- Special poison + if health > minHealth and health < (minHealth + maxPoisonDamage) then + local maxValue = health - minHealth + local minValue = minPoisonDamage + local value = startValue + local minRoundsDamage = (startValue * (startValue + 1) / 2) + + if maxValue < minPoisonDamage then + minValue = maxValue + end + + if maxValue < minRoundsDamage then + value = math.floor( math.sqrt(maxValue) ) + end + + local poisonMod = Condition(CONDITION_POISON) + poisonMod:setParameter(CONDITION_PARAM_DELAYED, true) + poisonMod:setParameter(CONDITION_PARAM_MINVALUE, -minValue) + poisonMod:setParameter(CONDITION_PARAM_MAXVALUE, -maxValue) + poisonMod:setParameter(CONDITION_PARAM_STARTVALUE, -value) + poisonMod:setParameter(CONDITION_PARAM_TICKINTERVAL, 4000) + poisonMod:setParameter(CONDITION_PARAM_FORCEUPDATE, true) + + player:addCondition(poisonMod) + -- Common poison + elseif health >= (minHealth + maxPoisonDamage) then + player:addCondition(poison) + end + -- Otherwise no poison +end + +local fluid = Action() + +function fluid.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local targetType = ItemType(target.itemid) + if targetType:isFluidContainer() then + if target.type == 0 and item.type ~= 0 then + target:transform(target.itemid, item.type) + item:transform(item.itemid, 0) + return true + elseif target.type ~= 0 and item.type == 0 then + target:transform(target.itemid, 0) + item:transform(item.itemid, target.type) + return true + end + end + if target.itemid == 29312 then + if item.type == 0 then + player:sendTextMessage(MESSAGE_FAILURE, 'It is empty.') + + elseif item.type == 1 then + toPosition:sendMagicEffect(CONST_ME_WATER_SPLASH) + target:transform(target.itemid + 1) + item:transform(item.itemid, 0) + else + player:sendTextMessage(MESSAGE_FAILURE, 'You need water.') + end + return true + end + + if target.itemid == 1 then + if item.type == 0 then + player:sendTextMessage(MESSAGE_FAILURE, 'It is empty.') + + elseif target.uid == player.uid then + if isInArray({3, 15, 43}, item.type) then + player:addCondition(drunk) + + elseif item.type == 4 then + local town = player:getTown() + if town and town:getId() == TOWNS_LIST.DAWNPORT then + dawnportPoisonCondition(player) + else + player:addCondition(poison) + end + elseif item.type == 7 then + player:addMana(math.random(50, 150)) + fromPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + elseif item.type == 10 then + player:addHealth(60) + fromPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + end + + player:say(fluidMessage[item.type] or 'Gulp.', TALKTYPE_MONSTER_SAY) + item:transform(item.itemid, 0) + else + local pool = Game.createItem(2016, item.type, toPosition) + if pool then + pool:decay() + if item.type == 1 then + checkWallArito(pool, toPosition) + end + end + item:transform(item.itemid, 0) + end + + else + + local fluidSource = targetType:getFluidSource() + if fluidSource ~= 0 then + item:transform(item.itemid, fluidSource) + + elseif item.type == 0 then + player:sendTextMessage(MESSAGE_FAILURE, 'It is empty.') + + else + if item.type == 2 and target.actionid == 2023 then + toPosition.y = toPosition.y + 1 + local creatures, destination = Tile(toPosition):getCreatures(), Position(32791, 32332, 10) + if #creatures == 0 then + graveStoneTeleport(player.uid, fromPosition, destination) + else + local creature + for i = 1, #creatures do + creature = creatures[i] + if creature and creature:isPlayer() then + graveStoneTeleport(creature.uid, toPosition, destination) + end + end + end + + else + if toPosition.x == CONTAINER_POSITION then + toPosition = player:getPosition() + end + + local pool = Game.createItem(2016, item.type, toPosition) + if pool then + pool:decay() + if item.type == 1 then + checkWallArito(pool, toPosition) + end + end + end + item:transform(item.itemid, 0) + end + end + + return true +end + +fluid:id(1775, 2005, 2006, 2007, 2008, 2009, 2011, 2012, 2013, 2014, 2015, 2023, 2031, 2032, 2033, 2034, 2562, 2574, 2575, 2576, 2577) +fluid:register() + diff --git a/data/scripts/actions/other/food.lua b/data/scripts/actions/other/food.lua new file mode 100644 index 00000000000..4350b1bcbc8 --- /dev/null +++ b/data/scripts/actions/other/food.lua @@ -0,0 +1,146 @@ +local foods = { + [2695] = {6, 'Gulp.'}, -- egg + [2362] = {5, 'Crunch.'}, -- carrot + [2666] = {15, 'Munch.'}, -- meat + [23516] = {15, 'Burp.'}, -- Bottle of Glooth Wine + [23515] = {15, 'Slurp.'}, -- Bowl of Glooth Soup + [23514] = {10, 'Munch.'}, -- Bowl of Glooth Soup + [2667] = {12, 'Munch.'}, -- fish + [2668] = {10, 'Mmmm.'}, -- salmon + [26191] = {30, 'Mmmm.'}, -- energy bar + [26201] = {30, 'Mmmm.'}, -- energy drink + [2669] = {17, 'Munch.'}, -- northern pike + [2670] = {4, 'Gulp.'}, -- shrimp + [2671] = {30, 'Chomp.'}, -- ham + [2672] = {60, 'Chomp.'}, -- dragon ham + [2673] = {5, 'Yum.'}, -- pear + [2674] = {6, 'Yum.'}, -- red apple + [2675] = {13, 'Yum.'}, -- orange + [2676] = {8, 'Yum.'}, -- banana + [2677] = {1, 'Yum.'}, -- blueberry + [2678] = {18, 'Slurp.'}, -- coconut + [2679] = {1, 'Yum.'}, -- cherry + [2680] = {2, 'Yum.'}, -- strawberry + [2681] = {9, 'Yum.'}, -- grapes + [7966] = {9, 'Hum.'}, -- cream cake + [2682] = {20, 'Yum.'}, -- melon + [2683] = {17, 'Munch.'}, -- pumpkin + [2684] = {5, 'Crunch.'}, -- carrot + [2685] = {6, 'Munch.'}, -- tomato + [2686] = {9, 'Crunch.'}, -- corncob + [2687] = {2, 'Crunch.'}, -- cookie + [2688] = {2, 'Munch.'}, -- candy cane + [2689] = {10, 'Crunch.'}, -- bread + [2690] = {3, 'Crunch.'}, -- roll + [2691] = {8, 'Crunch.'}, -- brown bread + [2696] = {9, 'Smack.'}, -- cheese + [2787] = {9, 'Munch.'}, -- white mushroom + [2788] = {4, 'Munch.'}, -- red mushroom + [2789] = {22, 'Munch.'}, -- brown mushroom + [2790] = {30, 'Munch.'}, -- orange mushroom + [2791] = {9, 'Munch.'}, -- wood mushroom + [2792] = {6, 'Munch.'}, -- dark mushroom + [2793] = {12, 'Munch.'}, -- some mushrooms + [2794] = {3, 'Munch.'}, -- some mushrooms + [2795] = {36, 'Munch.'}, -- fire mushroom + [2796] = {5, 'Munch.'}, -- green mushroom + [5097] = {4, 'Yum.'}, -- mango + [22644] = {4, 'Mmmm.'}, -- Christmas Cookie Tray + [6125] = {8, 'Gulp.'}, -- tortoise egg + [6278] = {10, 'Mmmm.'}, -- cake + [6279] = {15, 'Mmmm.'}, -- decorated cake + [6393] = {12, 'Mmmm.'}, -- valentine's cake + [6394] = {15, 'Mmmm.'}, -- cream cake + [6501] = {20, 'Mmmm.'}, -- gingerbread man + [6541] = {6, 'Gulp.'}, -- coloured egg (yellow) + [6542] = {6, 'Gulp.'}, -- coloured egg (red) + [6543] = {6, 'Gulp.'}, -- coloured egg (blue) + [6544] = {6, 'Gulp.'}, -- coloured egg (green) + [6545] = {6, 'Gulp.'}, -- coloured egg (purple) + [6569] = {1, 'Mmmm.'}, -- candy + [6574] = {5, 'Mmmm.'}, -- bar of chocolate + [7158] = {15, 'Munch.'}, -- rainbow trout + [7159] = {13, 'Munch.'}, -- green perch + [7372] = {2, 'Yum.'}, -- ice cream cone (crispy chocolate chips) + [7373] = {2, 'Yum.'}, -- ice cream cone (velvet vanilla) + [7374] = {2, 'Yum.'}, -- ice cream cone (sweet strawberry) + [7375] = {2, 'Yum.'}, -- ice cream cone (chilly cherry) + [7376] = {2, 'Yum.'}, -- ice cream cone (mellow melon) + [7377] = {2, 'Yum.'}, -- ice cream cone (blue-barian) + [7909] = {4, 'Crunch.'}, -- walnut + [7910] = {4, 'Crunch.'}, -- peanut + [7963] = {60, 'Munch.'}, -- marlin + [8112] = {9, 'Urgh.'}, -- scarab cheese + [8838] = {10, 'Gulp.'}, -- potato + [8839] = {5, 'Yum.'}, -- plum + [8840] = {1, 'Yum.'}, -- raspberry + [8841] = {1, 'Urgh.'}, -- lemon + [8842] = {7, 'Munch.'}, -- cucumber + [8843] = {5, 'Crunch.'}, -- onion + [8844] = {1, 'Gulp.'}, -- jalapeño pepper + [8845] = {5, 'Munch.'}, -- beetroot + [8847] = {11, 'Yum.'}, -- chocolate cake + [9005] = {7, 'Slurp.'}, -- yummy gummy worm + [9114] = {5, 'Crunch.'}, -- bulb of garlic + [10454] = {0, 'Your head begins to feel better.'}, -- headache pill + [11246] = {15, 'Yum.'}, -- rice ball + [11370] = {3, 'Urgh.'}, -- terramite eggs + [11429] = {10, 'Mmmm.'}, -- crocodile steak + [12415] = {20, 'Yum.'}, -- pineapple + [12416] = {10, 'Munch.'}, -- aubergine + [12417] = {8, 'Crunch.'}, -- broccoli + [12418] = {9, 'Crunch.'}, -- cauliflower + [12637] = {55, 'Gulp.'}, -- ectoplasmic sushi + [12638] = {18, 'Yum.'}, -- dragonfruit + [12639] = {2, 'Munch.'}, -- peas + [13297] = {20, 'Crunch.'}, -- haunch of boar + [15405] = {55, 'Munch.'}, -- sandfish + [15487] = {14, 'Urgh.'}, -- larvae + [15488] = {15, 'Munch.'}, -- deepling filet + [16014] = {60, 'Mmmm.'}, -- anniversary cake + [18306] = {0, 'Phew!'}, -- stale mushroom beer + [18397] = {33, 'Munch.'}, -- mushroom pie + [19737] = {10, 'Urgh.'}, -- insectoid eggs + [20100] = {15, 'Smack.'}, -- soft cheese + [20101] = {12, 'Smack.'}, -- rat cheese + [23517] = {25, 'Chomp.'}, -- glooth steak + [24843] = {25, 'Chomp.'}, -- Roasted Meat + [24841] = {8, 'Yum.'}, -- pickle pear + [27050] = {20, 'Urgh.'}, -- bug meat + [27051] = {10, 'Gulp.'}, -- cave turnip + [27064] = {60, 'Mmmm.'}, -- birthday cake + [27616] = {10, 'Slurp.'}, -- bottle of tibian wine + [28997] = {15, 'Mmmmm!'}, -- fresh fruit + [35057] = {40, 'Mmmmm!'}, -- meringue cake + [35060] = {15, 'Slurp.'} -- winterberry liquor +} + +local food = Action() + +function food.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local food = foods[item.itemid] + if not food then + return false + end + + --player:removeCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) + + local condition = player:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) + if condition and math.floor(condition:getTicks() / 1000 + (food[1] * 12)) >= 1200 then + player:sendTextMessage(MESSAGE_FAILURE, 'You are full.') + return true + end + + player:feed(food[1] * 12) + player:say(food[2], TALKTYPE_MONSTER_SAY) + item:remove(1) + player:updateSupplyTracker(item) + + return true +end + +for index, value in pairs(foods) do + food:id(index) +end + +food:register() diff --git a/data/scripts/actions/other/gems.lua b/data/scripts/actions/other/gems.lua new file mode 100644 index 00000000000..f739c2b59de --- /dev/null +++ b/data/scripts/actions/other/gems.lua @@ -0,0 +1,184 @@ +local lionsRockSanctuaryPos = Position(33073, 32300, 9) +local lionsRockSanctuaryRockId = 3608 +local lionsRockSanctuaryFountainId = 6390 + +local shrine = { + -- ice shrine + [2146] = { + targetAction = 15001, + -- shrinePosition = {x = 32194, y = 31418, z = 2}, -- read-only + destination = {x = 33430, y = 32278, z = 7}, + effect = CONST_ME_ICEATTACK + }, + -- fire shrine + [2147] = { + targetAction = 15002, + -- shrinePosition = {x = 32910, y = 32338, z = 15}, -- read-only + destination = {x = 33586, y = 32263, z = 7}, + effect = CONST_ME_MAGIC_RED + }, + -- earth shrine + [2149] = { + targetAction = 15003, + -- shrinePosition = {x = 32973, y = 32225, z = 7}, -- read-only + destination = {x = 33539, y = 32209, z = 7}, + effect = CONST_ME_SMALLPLANTS + }, + [2150] = { + targetAction = 15004, + -- shrinePosition = {x = 33060, y = 32713, z = 5}, -- read-only + destination = {x = 33527, y = 32301, z = 4}, + effect = CONST_ME_ENERGYHIT + } +} + +local lionsRock = { + [25006] = { + itemId = 23813, + itemPos = {x = 33069, y = 32298, z = 9}, + storage = Storage.LionsRock.Questline, + value = 9, + item = 2147, + fieldId = 1492, + message = "You place the ruby on the small socket. A red flame begins to burn.", + effect = CONST_ME_MAGIC_RED + }, + [25007] = { + itemId = 23813, + itemPos = {x = 33069, y = 32302, z = 9}, + storage = Storage.LionsRock.Questline, + value = 9, + item = 2146, + fieldId = 24618, + message = "You place the sapphire on the small socket. A blue flame begins to burn.", + effect = CONST_ME_MAGIC_BLUE + }, + [25008] = { + itemId = 23811, + itemPos = {x = 33077, y = 32302, z = 9}, + storage = Storage.LionsRock.Questline, + value = 9, + item = 2150, + fieldId = 7465, + message = "You place the amethyst on the small socket. A violet flame begins to burn.", + effect = CONST_ME_PURPLESMOKE + }, + [25009] = { + itemId = 23808, + itemPos = {x = 33077, y = 32298, z = 9}, + storage = Storage.LionsRock.Questline, + value = 9, + item = 9970, + fieldId = 1500, + message = "You place the topaz on the small socket. A yellow flame begins to burn.", + effect = CONST_ME_BLOCKHIT + } +} + +local gems = Action() + +function gems.onUse(player, item, fromPosition, target, toPosition, isHotkey) + -- Small emerald for Kilmaresh quest + -- see data\scripts\quests\kilmaresh\1-fafnars-wrath\7-four-masks.lua + if item.itemid == 2149 and target.uid == 40032 + and player:getStorageValue(Storage.Kilmaresh.Sixth.Favor) >= 1 + and not testFlag(player:getStorageValue(Storage.Kilmaresh.Sixth.FourMasks), 4) then + player:addItem(36206, 1) -- Ivory mask + item:remove(1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You hear a *click*. You can now lift the floor tile and discover a secret compartment. A mask made of ivory lies in it.") + player:setStorageValue(Storage.Kilmaresh.Sixth.Favor, player:getStorageValue(Storage.Kilmaresh.Sixth.Favor) + 1) + player:setStorageValue(Storage.Kilmaresh.Sixth.FourMasks, setFlag(player:getStorageValue(Storage.Kilmaresh.Sixth.FourMasks), 4)) + return true + -- Enchanted helmet of the ancients + elseif player:getItemCount(2147) >= 1 and target.itemid == 2342 then + target:transform(2343) + target:decay() + item:remove(1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + toPosition:sendMagicEffect(CONST_ME_MAGIC_RED) + return true + end + + -- Gems teleport to feyrist + for index, value in pairs(shrine) do + if target.actionid == value.targetAction then + if (player:getStorageValue(Storage.ThreatenedDreams.TroubledMission01) == 17) then + if item.itemid == index then + player:teleportTo(value.destination) + player:getPosition():sendMagicEffect(value.effect) + item:remove(1) + return true + else + player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + return true + end + else + player:say("When the time comes, 'small amethysts' will be accepted at this shrine.") + return true + end + end + end + + -- Use gems in the tile of lions rock quest + local setting = lionsRock[target.uid] + if not setting then + return false + end + + -- Reset lion's fields + local function lionsRockFieldReset() + local gemSpot = Tile(setting.itemPos):getItemById(setting.fieldId) + if gemSpot then + Game.setStorageValue(GlobalStorage.LionsRockFields, Game.getStorageValue(GlobalStorage.LionsRockFields) - 1) + gemSpot:remove() + return true + end + end + + -- Check if all lion's fields are set + local function checkLionsRockFields(storage) + if Game.getStorageValue(GlobalStorage.LionsRockFields) == 3 then + local stone = Tile(lionsRockSanctuaryPos):getItemById(lionsRockSanctuaryRockId) + if stone then + stone:transform(lionsRockSanctuaryFountainId) + lionsRockSanctuaryPos:sendMagicEffect(CONST_ME_THUNDER) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Something happens at the center of the room ...') + player:setStorageValue(storage, 10) + return true + end + end + end + + -- Delay to create lion's field + local function lionsRockCreateField(itemPos, fieldId, storage) + local gemSpot = Tile(itemPos):getItemById(fieldId) + if not gemSpot then + Game.createItem(fieldId, 1, itemPos) + Game.setStorageValue(GlobalStorage.LionsRockFields, Game.getStorageValue(GlobalStorage.LionsRockFields) + 1) + checkLionsRockFields(storage) + return true + end + end + + if player:getStorageValue(setting.storage) >= setting.value then + if setting.item == item.itemid then + local gemSpot = Tile(setting.itemPos):getItemById(setting.fieldId) + if not gemSpot then + toPosition:sendMagicEffect(setting.effect) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, setting.message) + item:remove(1) + addEvent(lionsRockCreateField, 2 * 1000, setting.itemPos, setting.fieldId, setting.storage) + addEvent(lionsRockFieldReset, 60 * 1000) + return true + end + end + end + return false +end + +for index, value in pairs(shrine) do + gems:id(index) +end + +gems:id(9970) +gems:register() diff --git a/data/scripts/actions/other/glooth_bag.lua b/data/scripts/actions/other/glooth_bag.lua new file mode 100644 index 00000000000..504433074d7 --- /dev/null +++ b/data/scripts/actions/other/glooth_bag.lua @@ -0,0 +1,49 @@ +-- + +local items = { + glooth_spears = 23529, + glooth_amulet = 23554, + glooth_club = 23549, + glooth_axe = 23551, + glooth_blade = 23550, + glooth_backpack = 23666, + glooth_sandwiches = 23514, + glooth_soup = 23515, + glooth_steaks = 23517, + control_unit = 23557, +} + +local gloothBag = Action() + +function gloothBag.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local rand = math.random(1, 100) + + if rand <= 15 then + player:addItem(items.glooth_spears, 2) + elseif rand >= 16 and rand <= 23 then + player:addItem(items.glooth_amulet, 1) + elseif rand >= 24 and rand <= 32 then + player:addItem(items.glooth_club, 1) + elseif rand >= 33 and rand <= 50 then + player:addItem(items.glooth_axe, 1) + elseif rand >= 51 and rand <= 64 then + player:addItem(items.glooth_blade, 1) + elseif rand >= 65 and rand <= 75 then + player:addItem(items.glooth_backpack, 1) + elseif rand >= 76 and rand <= 86 then + player:addItem(items.glooth_sandwiches, 10) + elseif rand >= 87 and rand <= 96 then + player:addItem(items.glooth_soup, 10) + elseif rand >= 97 and rand <= 99 then + player:addItem(items.control_unit, 1) + elseif rand == 100 then + player:addItem(items.glooth_steaks, 10) + end + + item:remove(1) + + return true +end + +gloothBag:id(23574) +gloothBag:register() diff --git a/data/scripts/actions/other/gold_converter.lua b/data/scripts/actions/other/gold_converter.lua new file mode 100644 index 00000000000..4884dee792a --- /dev/null +++ b/data/scripts/actions/other/gold_converter.lua @@ -0,0 +1,37 @@ +local config = { + [ITEM_GOLD_COIN] = {changeTo = ITEM_PLATINUM_COIN}, + [ITEM_PLATINUM_COIN] = {changeBack = ITEM_GOLD_COIN, changeTo = ITEM_CRYSTAL_COIN}, + [ITEM_CRYSTAL_COIN] = {changeBack = ITEM_PLATINUM_COIN} +} + +local goldConverter = Action() + +function goldConverter.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local coin = config[target.itemid] + + if not coin then + return false + end + + local charges = item:getCharges() + if coin.changeTo and target.type == 100 then + target:remove() + player:addItem(coin.changeTo, 1) + item:transform(item:getId(), charges -1) + elseif coin.changeBack then + target:transform(target.itemid, target.type - 1) + player:addItem(coin.changeBack, 100) + item:transform(item:getId(), charges -1) + else + return false + end + + if charges == 0 then + item:remove() + end + + return true +end + +goldConverter:id(26378, 29020) +goldConverter:register() diff --git a/data/scripts/actions/other/golden_outfit_display.lua b/data/scripts/actions/other/golden_outfit_display.lua new file mode 100644 index 00000000000..965d50a772b --- /dev/null +++ b/data/scripts/actions/other/golden_outfit_display.lua @@ -0,0 +1,63 @@ +local goldenOutfitDisplay = Action() + +function goldenOutfitDisplay.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + if player:getStorageValue(Storage.OutfitQuest.GoldenOutfit) == 3 then + if (item:getId() == 36344) then --direita + item:transform(36336) + item:getPosition():sendMagicEffect(171) + elseif (item:getId() == 36336) then + item:transform(36340) + item:getPosition():sendMagicEffect(171) + elseif (item:getId() == 36340) then + item:transform(36348) + item:getPosition():sendMagicEffect(171) + elseif (item:getId() == 36348) then + item:transform(36344) + item:getPosition():sendMagicEffect(171) + elseif (item:getId() == 36345) then --baixo + item:transform(36337) + item:getPosition():sendMagicEffect(171) + elseif (item:getId() == 36337) then + item:transform(36341) + item:getPosition():sendMagicEffect(171) + elseif (item:getId() == 36341) then + item:transform(36349) + item:getPosition():sendMagicEffect(171) + elseif (item:getId() == 36349) then + item:transform(36345) + item:getPosition():sendMagicEffect(171) + elseif (item:getId() == 36346) then --esquerda + item:transform(36338) + item:getPosition():sendMagicEffect(171) + elseif (item:getId() == 36338) then + item:transform(36342) + item:getPosition():sendMagicEffect(171) + elseif (item:getId() == 36342) then + item:transform(36350) + item:getPosition():sendMagicEffect(171) + elseif (item:getId() == 36350) then + item:transform(36346) + item:getPosition():sendMagicEffect(171) + elseif (item:getId() == 36347) then --cima + item:transform(36339) + item:getPosition():sendMagicEffect(171) + elseif (item:getId() == 36339) then + item:transform(36343) + item:getPosition():sendMagicEffect(171) + elseif (item:getId() == 36343) then + item:transform(36351) + item:getPosition():sendMagicEffect(171) + elseif (item:getId() == 36351) then + item:transform(36347) + item:getPosition():sendMagicEffect(171) + end + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need Full Golden Outfit to use it.") + item:getPosition():sendMagicEffect(CONST_ME_POFF) + end + return true +end + +goldenOutfitDisplay:id(36336, 36337, 36338, 36339, 36340, 36341, 36342, 36343, 36344, 36345, 36346, 36347, 36348, 36349, 36350, 36351) +goldenOutfitDisplay:register() diff --git a/data/scripts/actions/other/golden_outfit_memorial.lua b/data/scripts/actions/other/golden_outfit_memorial.lua new file mode 100644 index 00000000000..ed8eee97f8c --- /dev/null +++ b/data/scripts/actions/other/golden_outfit_memorial.lua @@ -0,0 +1,26 @@ +local storage = Storage.OutfitQuest.GoldenOutfit + +local goldenOutfitMemorial = Action() + +function goldenOutfitMemorial.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local resultId = db.storeQuery("SELECT `player_id` FROM `player_storage` WHERE `key` = " .. storage .. " AND `value` >= 3;") + if resultId ~= false then + local message = "The following characters have spent a fortune on a Golden Outfit:\n\nFull Outfit for 1,000,000,000 gold:\n\n" + repeat + local resultId2 = db.storeQuery("SELECT `name` FROM `players` WHERE `id` = " .. result.getDataInt(resultId, "player_id") .. ";") + if resultId2 ~= false then + local playerName = result.getString(resultId2, "name") + message = ""..message.."- ".. playerName .."\n" + result.free(resultId2) + end + until not result.next(resultId) + result.free(resultId) + player:showTextDialog(item.itemid, message) + else + player:showTextDialog(item.itemid, "The Golden Outfit has not been acquired by anyone yet.") + end + return true +end + +goldenOutfitMemorial:id(36353, 36354, 36355, 36356, 36357, 36358) +goldenOutfitMemorial:register() diff --git a/data/scripts/actions/other/hireling_food.lua b/data/scripts/actions/other/hireling_food.lua new file mode 100644 index 00000000000..d1e5f6335c6 --- /dev/null +++ b/data/scripts/actions/other/hireling_food.lua @@ -0,0 +1,87 @@ +local config = { + storage = 19042, --use empty storage + exhaust = 600 --Exhaust is in seconds 600 equals 10min +} + +local chilliConCarniphila = Condition(CONDITION_HASTE) +chilliConCarniphila:setParameter(CONDITION_PARAM_TICKS, 60 * 60 * 1000) +chilliConCarniphila:setParameter(CONDITION_PARAM_SPEED, 80) + +local svargrondSalmonFilet = Condition(CONDITION_ATTRIBUTES) +svargrondSalmonFilet:setParameter(CONDITION_PARAM_TICKS, 60 * 60 * 1000) +svargrondSalmonFilet:setParameter(CONDITION_PARAM_SKILL_FISHING, 30) + +local tropicalMarinatedTiger = Condition(CONDITION_ATTRIBUTES) +tropicalMarinatedTiger:setParameter(CONDITION_PARAM_TICKS, 60 * 60 * 1000) +tropicalMarinatedTiger:setParameter(CONDITION_PARAM_STAT_MAGICPOINTS, 3) + +local delicatessenSalad = Condition(CONDITION_ATTRIBUTES) +delicatessenSalad:setParameter(CONDITION_PARAM_TICKS, 60 * 60 * 1000) +delicatessenSalad:setParameter(CONDITION_PARAM_SKILL_MELEE, 3) + +local roastedWyvernWings = Condition(CONDITION_ATTRIBUTES) +roastedWyvernWings:setParameter(CONDITION_PARAM_TICKS, 60 * 60 * 1000) +roastedWyvernWings:setParameter(CONDITION_PARAM_SKILL_SHIELD, 7) + +local carrotPie = Condition(CONDITION_ATTRIBUTES) +carrotPie:setParameter(CONDITION_PARAM_TICKS, 60 * 60 * 1000) +carrotPie:setParameter(CONDITION_PARAM_SKILL_DISTANCE, 7) + +local hirelingFood = Action() + +function hirelingFood.onUse(player, item, frompos, item2, topos) + local cid = player:getId() + if (player:getStorageValue(config.storage) <= os.time()) then + if (item.itemid == 35172) then + player:say("Chomp.",TALKTYPE_MONSTER_SAY) + Creature(cid):addCondition(roastedWyvernWings) + item:remove(1) + player:setStorageValue(config.storage, os.time() + config.exhaust) + elseif (item.itemid == 35173) then + player:say("Yummm.",TALKTYPE_MONSTER_SAY) + Creature(cid):addCondition(carrotPie) + item:remove(1) + player:setStorageValue(config.storage, os.time() + config.exhaust) + elseif (item.itemid == 35174) then + player:say("Munch.",TALKTYPE_MONSTER_SAY) + Creature(cid):addCondition(tropicalMarinatedTiger) + item:remove(1) + player:setStorageValue(config.storage, os.time() + config.exhaust) + elseif (item.itemid == 35175) then + player:say("Munch.",TALKTYPE_MONSTER_SAY) + Creature(cid):addCondition(delicatessenSalad) + item:remove(1) + player:setStorageValue(config.storage, os.time() + config.exhaust) + elseif (item.itemid == 35176) then + player:say("Yummm.",TALKTYPE_MONSTER_SAY) + Creature(cid):addCondition(chilliConCarniphila) + item:remove(1) + player:setStorageValue(config.storage, os.time() + config.exhaust) + elseif (item.itemid == 35177) then + player:say("Mmmmm.",TALKTYPE_MONSTER_SAY) + Creature(cid):addCondition(svargrondSalmonFilet) + item:remove(1) + player:setStorageValue(config.storage, os.time() + config.exhaust) + elseif (item.itemid == 35178) then + Creature(cid):addHealth(getCreatureMaxHealth(cid) * 0.3) + player:say("Munch.",TALKTYPE_MONSTER_SAY) + item:remove(1) + player:setStorageValue(config.storage, os.time() + config.exhaust) + elseif (item.itemid == 35179) then + Creature(cid):addMana(Creature(cid):getMaxMana() * 0.3) + player:say("Chomp.",TALKTYPE_MONSTER_SAY) + item:remove(1) + player:setStorageValue(config.storage, os.time() + config.exhaust) + elseif (item.itemid == 35180) then + player:say("Blurg.",TALKTYPE_MONSTER_SAY) + item:remove(1) + player:setStorageValue(config.storage, os.time() + config.exhaust) + end + else + player:sendCancelMessage("You're still too full to eat any gourmet dishes for a while.") + end + return true +end + +hirelingFood:id(35172, 35173, 35174, 35175, 35176, 35177, 35178, 35179, 35180) +hirelingFood:register() diff --git a/data/scripts/actions/other/hirelinglamp.lua b/data/scripts/actions/other/hirelinglamp.lua new file mode 100644 index 00000000000..179d858625d --- /dev/null +++ b/data/scripts/actions/other/hirelinglamp.lua @@ -0,0 +1,35 @@ +local hirelingLamp = Action() + +function hirelingLamp.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local spawnPosition = player:getPosition() + local hireling_id = item:getSpecialAttribute(HIRELING_ATTRIBUTE) + local house = spawnPosition and spawnPosition:getTile() and spawnPosition:getTile():getHouse() or nil + if not house then + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:sendTextMessage(MESSAGE_FAILURE, "You may use this only inside a house.") + return false + elseif house:getDoorIdByPosition(spawnPosition) then + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:sendTextMessage(MESSAGE_FAILURE, "You cannot spawn a hireling on the door") + return false + elseif getHirelingByPosition(spawnPosition) then + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:sendTextMessage(MESSAGE_FAILURE, "You cannot spawn another hireling here.") + return false + elseif house:getOwnerGuid() ~= player:getGuid() then + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:sendTextMessage(MESSAGE_FAILURE, "You cannot spawn a hireling on another's person house.") + return false + end + + local hireling = getHirelingById(hireling_id) + + hireling:setPosition(spawnPosition) + item:remove(1) + hireling:spawn() + spawnPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +hirelingLamp:id(34070) +hirelingLamp:register() diff --git a/data/scripts/actions/other/jean_pierre_food.lua b/data/scripts/actions/other/jean_pierre_food.lua new file mode 100644 index 00000000000..1ee9c72ff4a --- /dev/null +++ b/data/scripts/actions/other/jean_pierre_food.lua @@ -0,0 +1,217 @@ +local conditions = { + CONDITION_POISON, CONDITION_FIRE, CONDITION_ENERGY, + CONDITION_PARALYZE, CONDITION_DRUNK, CONDITION_DROWN, + CONDITION_FREEZING, CONDITION_DAZZLED, CONDITION_CURSED, + CONDITION_BLEEDING +} +local condition_shield = createConditionObject(CONDITION_ATTRIBUTES) +setConditionParam(condition_shield, CONDITION_PARAM_SUBID, 3) +setConditionParam(condition_shield, CONDITION_PARAM_BUFF_SPELL, 1) +setConditionParam(condition_shield, CONDITION_PARAM_TICKS, 60 * 60 * 1000) +setConditionParam(condition_shield, CONDITION_PARAM_SKILL_SHIELD, 10) +setConditionParam(condition_shield, CONDITION_PARAM_FORCEUPDATE, true) +local condition_ml = createConditionObject(CONDITION_ATTRIBUTES) +setConditionParam(condition_ml, CONDITION_PARAM_SUBID, 4) +setConditionParam(condition_ml, CONDITION_PARAM_BUFF_SPELL, 1) +setConditionParam(condition_ml, CONDITION_PARAM_TICKS, 60 * 60 * 1000) +setConditionParam(condition_ml, CONDITION_PARAM_STAT_MAGICPOINTS, 5) +setConditionParam(condition_ml, CONDITION_PARAM_FORCEUPDATE, true) +local condition_melee = createConditionObject(CONDITION_ATTRIBUTES) +setConditionParam(condition_melee, CONDITION_PARAM_SUBID, 5) +setConditionParam(condition_melee, CONDITION_PARAM_BUFF_SPELL, 1) +setConditionParam(condition_melee, CONDITION_PARAM_TICKS, 60 * 60 * 1000) +setConditionParam(condition_melee, CONDITION_PARAM_SKILL_MELEE, 10) +setConditionParam(condition_melee, CONDITION_PARAM_FORCEUPDATE, true) +local condition_dist = createConditionObject(CONDITION_ATTRIBUTES) +setConditionParam(condition_dist, CONDITION_PARAM_SUBID, 6) +setConditionParam(condition_dist, CONDITION_PARAM_BUFF_SPELL, 1) +setConditionParam(condition_dist, CONDITION_PARAM_TICKS, 60 * 60 * 1000) +setConditionParam(condition_dist, CONDITION_PARAM_SKILL_DISTANCE, 10) +setConditionParam(condition_dist, CONDITION_PARAM_FORCEUPDATE, true) +local condition_f = createConditionObject(CONDITION_ATTRIBUTES) +setConditionParam(condition_f, CONDITION_PARAM_SUBID, 6) +setConditionParam(condition_f, CONDITION_PARAM_BUFF_SPELL, 1) +setConditionParam(condition_f, CONDITION_PARAM_TICKS, 60 * 60 * 1000) +setConditionParam(condition_f, CONDITION_PARAM_SKILL_FISHING, 50) +setConditionParam(condition_f, CONDITION_PARAM_FORCEUPDATE, true) +local condition_speed = createConditionObject(CONDITION_HASTE) +setConditionParam(condition_speed, CONDITION_PARAM_TICKS, 60 * 60 * 1000) +setConditionParam(condition_speed, CONDITION_PARAM_SPEED, 600) +local combat_i = createCombatObject() +setCombatParam(combat_i, COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) +setCombatParam(combat_i, COMBAT_PARAM_AGGRESSIVE, 0) +local condition_i = createConditionObject(CONDITION_INVISIBLE) +setConditionParam(condition_i, CONDITION_PARAM_TICKS, 600000) +addCombatCondition(combat_i, condition_i) +local iid = {[9992] = 0, [9993] = 1, [9994] = 2, [9995] = 3, [9996] = 4, [9997] = 5, [9998] = 6, [9999] = 7, [10000] = 8, [10001] = 9, [12540] = 10, [12542] = 11, [12543] = 12, [12544] = 13} + +local jeanPierreFood = Action() + +function jeanPierreFood.onUse(player, item, frompos, item2, topos) + local cid = player:getId() + if player:getStorageValue(17110 + iid[item.itemid]) > os.time() then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need to wait before using it again.") + return true + end + player:setStorageValue(17110 + iid[item.itemid],os.time() + (15 * 60)) + + if item.itemid == 9992 then + item:remove(1) + Creature(cid):addHealth(getCreatureMaxHealth(cid) - getCreatureHealth(cid)) + player:say("Gulp.", TALKTYPE_MONSTER_SAY) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your health has been refilled.") + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + return true + elseif item.itemid == 9993 then + item:remove(1) + for i = 1, #conditions do + doRemoveCondition(cid, conditions[i]) + end + player:say("Chomp.", TALKTYPE_MONSTER_SAY) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You feel better body condition.") + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + return true + elseif item.itemid == 9994 then + item:remove(1) + Creature(cid):addCondition(condition_shield) + player:say("Chomp.", TALKTYPE_MONSTER_SAY) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You feel less vulnerable.") + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + return true + elseif item.itemid == 9995 then + item:remove(1) + Creature(cid):addCondition(condition_ml) + player:say("Chomp.", TALKTYPE_MONSTER_SAY) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You feel smarter.") + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + return true + elseif item.itemid == 9996 then + item:remove(1) + player:say("Slurp.", TALKTYPE_MONSTER_SAY) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You don't really know what this did to you, but suddenly you feel very happy.") + player:getPosition():sendMagicEffect(CONST_ME_HEARTS) + return true + elseif item.itemid == 9997 then + item:remove(1) + Creature(cid):addCondition(condition_melee) + player:say("Yum.", TALKTYPE_MONSTER_SAY) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You feel stronger.") + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + return true + elseif item.itemid == 9998 then + item:remove(1) + Creature(cid):addCondition(condition_speed) + player:say("Munch.", TALKTYPE_MONSTER_SAY) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your speed has been increased.") + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + return true + elseif item.itemid == 9999 then + item:remove(1) + Creature(cid):addMana(Creature(cid):getMaxMana() - Creature(cid):getMana()) + player:say("Chomp.", TALKTYPE_MONSTER_SAY) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your mana has been refilled.") + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + return true + elseif item.itemid == 10000 then + item:remove(1) + Creature(cid):addCondition(condition_dist) + player:say("Mmmm.", TALKTYPE_MONSTER_SAY) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You feel more focused.") + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + return true + elseif item.itemid == 10001 then + item:remove(1) + Creature(cid):addCondition(condition_f) + player:say("Smack.", TALKTYPE_MONSTER_SAY) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You felt fishing inspiration.") + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + return true + elseif item.itemid == 12540 then + item:remove(1) + player:setStorageValue(17100,os.time() + 86400) + player:say("Yum.", TALKTYPE_MONSTER_SAY) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Underwater walking speed increased.") + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + return true + elseif item.itemid == 12542 then + if math.random(1,5) == 5 then + item:remove(1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You take the last gulp from the large bowl. No leftovers!") + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You take a gulp from the large bowl, but there's still some blackjack in it.") + end + Creature(cid):addHealth(getCreatureMaxHealth(cid) - getCreatureHealth(cid)) + player:say("Gulp.", TALKTYPE_MONSTER_SAY) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + return true + elseif item.itemid == 12543 then + item:remove(1) + local c = {condition_shield,condition_ml,condition_melee,condition_dist,condition_speed} + local r = math.random(1,4) + if r == 1 then + Creature(cid):addCondition(c[math.random(1, #c)]) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You feel stronger, but you have no idea what was increased.") + elseif r == 2 then + doSetCreatureLight(cid, 15, 154, 60*60*1000) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You feel enlightened.") + elseif r == 3 then + Creature(cid):addCondition(condition_i) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You became invisible.") + elseif r == 4 then + Creature(cid):addHealth(getCreatureMaxHealth(cid) - getCreatureHealth(cid)) + Creature(cid):addMana(Creature(cid):getMaxMana() - Creature(cid):getMana()) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your vitality has been restored.") + end + player:say("Smack.", TALKTYPE_MONSTER_SAY) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + return true + elseif item.itemid == 12544 then + local ring = getPlayerSlotItem(cid, CONST_SLOT_RING) + local r_t = { + [2211] = 2208, + [2212] = 2209, + [6301] = 6300, + [2215] = 2213, + [2204] = 2167, + [2205] = 2168, + [2164] = 2164, + [2203] = 2166, + [18528] = 18408, + [2216] = 2214, + [13826] = 13825, + [2202] = 2165, + [2210] = 2207, + [2206] = 2169} + if(ring.itemid == 0) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "No ring equipped.") + player:getPosition():sendMagicEffect(CONST_ME_POFF) + return true + end + + if r_t[ring.itemid] ~= nil then + item:remove(1) + if ring.itemid == r_t[ring.itemid] then + r_m_am = 20 + else + r_m_am = 1 + end + + for i = 1, 10 do + doPlayerAddItem(cid, r_t[ring.itemid], r_m_am) + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your ring has been multiplied.") + player:say("Slurp!", TALKTYPE_MONSTER_SAY) + return true + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "This ring cannot be multiplied.") + player:getPosition():sendMagicEffect(CONST_ME_POFF) + return true + end + end +end + +for index, value in pairs(iid) do + jeanPierreFood:id(index) +end + +jeanPierreFood:register() diff --git a/data/scripts/actions/other/lottery_ticket.lua b/data/scripts/actions/other/lottery_ticket.lua new file mode 100644 index 00000000000..d758d066328 --- /dev/null +++ b/data/scripts/actions/other/lottery_ticket.lua @@ -0,0 +1,15 @@ +local lotteryTicket= Action() + +function lotteryTicket.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if math.random(98) == 1 then + player:getPosition():sendMagicEffect(CONST_ME_SOUND_YELLOW) + item:transform(5958) + else + item:getPosition():sendMagicEffect(CONST_ME_POFF) + item:remove(1) + end + return true +end + +lotteryTicket:id(5957) +lotteryTicket:register() diff --git a/data/scripts/actions/other/magic_gold_converter.lua b/data/scripts/actions/other/magic_gold_converter.lua new file mode 100644 index 00000000000..bafba710dad --- /dev/null +++ b/data/scripts/actions/other/magic_gold_converter.lua @@ -0,0 +1,81 @@ +local data = { + converterIds = { + [32109] = 33299, + [33299] = 32109, + }, + coins = { + [ITEM_GOLD_COIN] = ITEM_PLATINUM_COIN, + [ITEM_PLATINUM_COIN] = ITEM_CRYSTAL_COIN + } +} + +local function finditem(self, cylinder, conv) + if cylinder == 0 then + cylinder = self:getSlotItem(CONST_SLOT_BACKPACK) + finditem(self, self:getSlotItem(CONST_SLOT_STORE_INBOX), conv) + end + + if cylinder and cylinder:isContainer() then + for i = 0, cylinder:getSize() - 1 do + local item = cylinder:getItem(i) + if item:isContainer() then + if finditem(self, Container(item.uid), conv) then + -- Breaks the recursion from going into the next items in this cylinder + return true + end + else + for fromid, toid in pairs(data.coins) do + if item:getId() == fromid and item:getCount() == 100 then + item:remove() + if not(cylinder:addItem(toid, 1)) then + player:addItem(toid, 1) + end + + conv:setAttribute(ITEM_ATTRIBUTE_CHARGES, conv:getAttribute(ITEM_ATTRIBUTE_CHARGES) - 1) + + return true + end + end + end + end + -- End of items in this cylinder, returning to parent cylinder or finishing iteration + return false + end +end + +local function start_converter(pid, itemid) + local player = Player(pid) + if player ~= nil then + + local item = player:getItemById(itemid,true) + if player:getItemCount(itemid) >= 1 then + if item:hasAttribute(ITEM_ATTRIBUTE_CHARGES) then + local charges_n = item:getAttribute(ITEM_ATTRIBUTE_CHARGES) + if charges_n >= 1 then + if player:getItemCount(ITEM_GOLD_COIN) >= 100 or player:getItemCount(ITEM_PLATINUM_COIN) >= 100 then + finditem(player, 0, item) + end + local converting = addEvent(start_converter, 300, pid, itemid) + else + item:remove(1) + stopEvent(converting) + end + end + else + stopEvent(converting) + end + end + return true +end + +local magicGoldConverter = Action() + +function magicGoldConverter.onUse(player, item, fromPosition, target, toPosition, isHotkey) + item:transform(data.converterIds[item.itemid]) + item:decay() + start_converter(player:getId(), 33299) + return true +end + +magicGoldConverter:id(32109, 33299) +magicGoldConverter:register() diff --git a/data/scripts/actions/other/magic_tree.lua b/data/scripts/actions/other/magic_tree.lua new file mode 100644 index 00000000000..83922ec4bbb --- /dev/null +++ b/data/scripts/actions/other/magic_tree.lua @@ -0,0 +1,45 @@ +local itemInfos = { + [29425] = {29429, 29425}, -- first index is the id of the item and the second the storage number for exhaustion purposes + [29429] = {29425, 29425}, + [29423] = {29427, 29423}, + [29427] = {29423, 29423}, + [29428] = {29424, 29428}, + [29424] = {29428, 29428}, + [29430] = {29426, 29426}, + [29426] = {29430, 29426} +} + +local storageValues = {} +local exhaustDelaySeconds = 1 + +local magicTree = Action() + +function magicTree.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if(fromPosition.x == CONTAINER_POSITION) then + return false + end + + local house = player:getTile():getHouse() + if not house then + return false + end + + local itemInfo = itemInfos[item:getId()] + if not itemInfo then + return false + end + + if player:getStorageValue(itemInfo[2]) >= os.time() then + return false + end + + item:transform(itemInfo[1]) + player:setStorageValue(itemInfo[2], os.time() + exhaustDelaySeconds) + return true +end + +for index, value in pairs(itemInfos) do + magicTree:id(index) +end + +magicTree:register() diff --git a/data/scripts/actions/other/mechanical_fishing.lua b/data/scripts/actions/other/mechanical_fishing.lua new file mode 100644 index 00000000000..22279bc7d60 --- /dev/null +++ b/data/scripts/actions/other/mechanical_fishing.lua @@ -0,0 +1,85 @@ +local waterIds = {493, 4608, 4609, 4610, 4611, 4612, 4613, 4614, 4615, 4616, 4617, 4618, 4619, 4620, 4621, 4622, 4623, 4624, 4625, 7236, 10499, 15401, 15402} +local lootTrash = {2234, 2238, 2376, 2509, 2667} +local lootCommon = {2152, 2167, 2168, 2669, 7588, 7589} +local lootRare = {2143, 2146, 2149, 7158, 7159} +local lootVeryRare = {7632, 7633, 10220} +local useWorms = true + +local mechanicalFishing = Action() + +function mechanicalFishing.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if not isInArray(waterIds, target.itemid) then + return false + end + + local targetId = target.itemid + if targetId == 10499 then + local owner = target:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) + if owner ~= 0 and owner ~= player.uid then + player:sendTextMessage(MESSAGE_FAILURE, "You are not the owner.") + return true + end + + toPosition:sendMagicEffect(CONST_ME_WATERSPLASH) + target:remove() + + local rareChance = math.random(100) + if rareChance == 1 then + player:addItem(lootVeryRare[math.random(#lootVeryRare)], 1) + elseif rareChance <= 3 then + player:addItem(lootRare[math.random(#lootRare)], 1) + elseif rareChance <= 10 then + player:addItem(lootCommon[math.random(#lootCommon)], 1) + else + player:addItem(lootTrash[math.random(#lootTrash)], 1) + end + return true + end + + if targetId ~= 7236 then + toPosition:sendMagicEffect(CONST_ME_LOSEENERGY) + end + + if targetId == 493 or targetId == 15402 then + return true + end + + player:addSkillTries(SKILL_FISHING, 1) + if math.random(100) <= math.min(math.max(10 + (player:getEffectiveSkillLevel(SKILL_FISHING) - 10) * 0.597, 10), 50) then + if useWorms and not player:removeItem("nail", 1) then + return true + end + + if targetId == 15401 then + target:transform(targetId + 1) + target:decay() + + if math.random(100) >= 97 then + player:addItem(15405, 1) + return true + end + elseif targetId == 7236 then + target:transform(targetId + 1) + target:decay() + + local rareChance = math.random(100) + if rareChance == 1 then + player:addItem(7158, 1) + return true + elseif rareChance <= 4 then + player:addItem(2669, 1) + return true + elseif rareChance <= 10 then + player:addItem(7159, 1) + return true + end + end + player:addItem("mechanical fish", 1) + end + return true +end + +mechanicalFishing:id(10223) +mechanicalFishing:allowFarUse(true) +mechanicalFishing:register() + diff --git a/data/scripts/actions/other/muck_remover.lua b/data/scripts/actions/other/muck_remover.lua new file mode 100644 index 00000000000..fdff643085c --- /dev/null +++ b/data/scripts/actions/other/muck_remover.lua @@ -0,0 +1,41 @@ +local config = { + {from = 1, to = 1644, itemId = 18394}, + {from = 1645, to = 3189, itemId = 2158}, + {from = 3190, to = 4725, itemId = 18391}, + {from = 4726, to = 6225, itemId = 18414, count = 5}, + {from = 6226, to = 7672, itemId = 18418, count = 10}, + {from = 7673, to = 9083, itemId = 18413, count = 10}, + {from = 9084, to = 9577, itemId = 2445}, + {from = 9578, to = 9873, itemId = 8878}, + {from = 9874, to = 9999, itemId = 18450} +} + +local muckRemover = Action() + +function muckRemover.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid ~= 18396 then + return false + end + + local chance, randomItem = math.random(9999) + for i = 1, #config do + randomItem = config[i] + if chance >= randomItem.from and chance <= randomItem.to then + if toPosition.x == CONTAINER_POSITION then + target:getParent():addItem(randomItem.itemId, randomItem.count or 1, INDEX_WHEREEVER, FLAG_NOLIMIT) + else + Game.createItem(randomItem.itemId, randomItem.count or 1, toPosition) + end + + target:getPosition():sendMagicEffect(CONST_ME_GREEN_RINGS) + target:remove(1) + + item:remove(1) + break + end + end + return true +end + +muckRemover:id(18395) +muckRemover:register() diff --git a/data/scripts/actions/other/music.lua b/data/scripts/actions/other/music.lua new file mode 100644 index 00000000000..bf446b60322 --- /dev/null +++ b/data/scripts/actions/other/music.lua @@ -0,0 +1,62 @@ +local MusicEffect = { + [2070] = CONST_ME_SOUND_GREEN, --Wooden Flute + [2071] = CONST_ME_SOUND_GREEN, --Lyre + [2072] = CONST_ME_SOUND_GREEN, --Lute + [2073] = CONST_ME_SOUND_GREEN, --Drum + [2074] = CONST_ME_SOUND_BLUE, --Panpipes + [2075] = CONST_ME_SOUND_GREEN, --Simple Fanfare + [2076] = CONST_ME_SOUND_GREEN, --Fanfare + [2077] = CONST_ME_SOUND_GREEN, --Royal Fanfare + [2078] = CONST_ME_SOUND_GREEN, --Post Horn + [2079] = CONST_ME_SOUND_RED, --War Horn + [2080] = CONST_ME_SOUND_BLUE, --Piano + [2081] = CONST_ME_SOUND_BLUE, --Piano + [2082] = CONST_ME_SOUND_BLUE, --Piano + [2083] = CONST_ME_SOUND_BLUE, --Piano + [2084] = CONST_ME_SOUND_BLUE, --Harp + [2085] = CONST_ME_SOUND_BLUE, --Harp + [2332] = CONST_ME_SOUND_GREEN, --Waldo's Post Horn + [2364] = CONST_ME_SOUND_GREEN, --Post Horn + -- non movable instruments + [2367] = CONST_ME_SOUND_GREEN, --Drum + [2368] = CONST_ME_SOUND_GREEN, --Simple Fanfare + [3957] = CONST_ME_SOUND_YELLOW, --Cornucopia + [2370] = CONST_ME_SOUND_GREEN, --Lute + [2371] = CONST_ME_SOUND_BLUE, --Horn of Sundering + [2372] = CONST_ME_SOUND_GREEN, --Lyre + [2373] = CONST_ME_SOUND_BLUE, --Panpipes + [2070] = CONST_ME_SOUND_GREEN, --Wooden Flute + -- + [3951] = CONST_ME_SOUND_BLUE, --Bongo Drum + [3952] = CONST_ME_SOUND_GREEN, --Didgeridoo + [3953] = CONST_ME_SOUND_RED, --War Drum + [5786] = CONST_ME_SOUND_GREEN, --Wooden Whistle + [13759] = CONST_ME_SOUND_BLUE, --Small Whistle +} + +local music = Action() + +function music.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 2071 then + if isInRange(player:getPosition(), Position(32695, 31717, 2), Position(32699, 31719, 2)) then + local lyreProgress = player:getStorageValue(Storage.Diapason.Lyre) + if lyreProgress < 7 + and player:getStorageValue(Storage.Diapason.Edala) ~= 1 + and player:getStorageValue(Storage.Diapason.LyreTimer) < os.time() then + player:setStorageValue(Storage.Diapason.Lyre, math.max(0, lyreProgress) + 1) + player:setStorageValue(Storage.Diapason.Edala, 1) + player:setStorageValue(Storage.Diapason.LyreTimer, os.time() + 86400) + end + end + end + + player:addAchievementProgress('Rockstar', 10000) + item:getPosition():sendMagicEffect(MusicEffect[item.itemid]) + return true +end + +for index, value in pairs(MusicEffect) do + music:id(index) +end + +music:register() diff --git a/data/scripts/actions/other/offline_training.lua b/data/scripts/actions/other/offline_training.lua new file mode 100644 index 00000000000..4f2faa31f68 --- /dev/null +++ b/data/scripts/actions/other/offline_training.lua @@ -0,0 +1,30 @@ +local statues = { + [18488] = SKILL_SWORD, + [18489] = SKILL_AXE, + [18490] = SKILL_CLUB, + [18491] = SKILL_DISTANCE, + [18492] = SKILL_MAGLEVEL +} + +local offlineTraining = Action() + +function offlineTraining.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local skill = statues[item:getId()] + if not player:isPremium() then + player:sendTextMessage(MESSAGE_FAILURE, Game.getReturnMessage(RETURNVALUE_YOUNEEDPREMIUMACCOUNT)) + return true + end + + if player:isPzLocked() then + return false + end + player:setOfflineTrainingSkill(skill) + player:remove() + return true +end + +for index, value in pairs(statues) do + offlineTraining:id(index) +end + +offlineTraining:register() diff --git a/data/scripts/actions/other/offline_training_book.lua b/data/scripts/actions/other/offline_training_book.lua new file mode 100644 index 00000000000..d47ac501532 --- /dev/null +++ b/data/scripts/actions/other/offline_training_book.lua @@ -0,0 +1,11 @@ +local text = "Information on Offline Training:\n 1. You need to have a Premium account in order to train here.\n 2. Choose a skill you'd like to train. Shielding is ALWAYS included.\n 3. If you're not sure which statue trains what, read the inscriptions.\n 4. Use a statue to be logged out of the game and train the skills associated with that statue.\n 5. When you log back into the game, your skills will have improved depending on how long you trained.\n 6. You have to be logged out of the game for at least 10 minutes in order for the training to take effect.\n 7. After 12 hours of constant offline training, your skills will not improve any further. Similar to stamina, your training bar will regenerate if you are not training offline." + +local offlineTrainingBook = Action() + +function offlineTrainingBook.onUse(player, item, fromPosition, target, toPosition, isHotkey) + player:showTextDialog(item.itemid, text) + return true +end + +offlineTrainingBook:id(12397) +offlineTrainingBook:register() diff --git a/data/scripts/actions/other/ore_wagon.lua b/data/scripts/actions/other/ore_wagon.lua new file mode 100644 index 00000000000..f7e5c14bfe5 --- /dev/null +++ b/data/scripts/actions/other/ore_wagon.lua @@ -0,0 +1,31 @@ +local config = { + [1042] = {destination = Position(32527, 31842, 9)}, + [1043] = {destination = Position(32559, 31852, 7)}, + [1044] = {destination = Position(32498, 31828, 9)}, + [1045] = {destination = Position(32517, 31806, 9)}, + [1046] = {destination = Position(32517, 31830, 9)}, + [1047] = {destination = Position(32490, 31810, 9)}, + [1048] = {destination = Position(32494, 31831, 9)}, + [1049] = {destination = Position(32514, 31805, 9)}, + [1050] = {destination = Position(32497, 31805, 9)}, + [1051] = {destination = Position(32518, 31827, 9)} +} + +local oreWagon = Action() + +function oreWagon.onUse(player, item, position, fromPosition) + local teleport = config[item.uid] + if not teleport then + return true + end + + player:teleportTo(teleport.destination) + teleport.destination:sendMagicEffect(10) + return true +end + +for index, value in pairs(config) do + oreWagon:uid(index) +end + +oreWagon:register() diff --git a/data/scripts/actions/other/others/quest_system1.lua b/data/scripts/actions/other/others/quest_system1.lua new file mode 100644 index 00000000000..5aae489da6c --- /dev/null +++ b/data/scripts/actions/other/others/quest_system1.lua @@ -0,0 +1,136 @@ +local specialQuests = { + [2016] = Storage.DreamersChallenge.Reward, + [10544] = Storage.PitsOfInferno.WeaponReward, + [12513] = Storage.ThievesGuild.Reward, + [12374] = Storage.WrathoftheEmperor.mainReward, + [26300] = Storage.SvargrondArena.RewardGreenhorn, + [27300] = Storage.SvargrondArena.RewardScrapper, + [28300] = Storage.SvargrondArena.RewardWarlord +} + +local questsExperience = { + [2217] = 1 -- dummy values +} + +local questLog = { + [9130] = Storage.HiddenCityOfBeregar.DefaultStart +} + +local tutorialIds = { + [50080] = 5, + [50082] = 6, + [50084] = 10, + [50086] = 11 +} + +local hotaQuest = {50950, 50951, 50952, 50953, 50954, 50955} + +local questSystem1 = Action() + +function questSystem1.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local storage = specialQuests[item.actionid] + if not storage then + storage = item.uid + if storage > 65535 then + return false + end + end + + if storage == 26300 or storage == 27300 or storage == 28300 then + player:setStorageValue(Storage.SvargrondArena.PitDoor, -1) + end + + if player:getStorageValue(storage) > 0 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The ' .. ItemType(item.itemid):getName() .. ' is empty.') + return true + end + + local items, reward = {} + local size = item:isContainer() and item:getSize() or 0 + if size == 0 then + reward = item:clone() + else + local container = Container(item.uid) + for i = 0, container:getSize() - 1 do + items[#items + 1] = container:getItem(i):clone() + end + end + + size = #items + if size == 1 then + reward = items[1]:clone() + end + + local result = '' + if reward then + local ret = ItemType(reward.itemid) + if ret:isRune() then + result = ret:getArticle() .. ' ' .. ret:getName() .. ' (' .. reward.type .. ' charges)' + elseif ret:isStackable() and reward:getCount() > 1 then + result = reward:getCount() .. ' ' .. ret:getPluralName() + elseif ret:getArticle() ~= '' then + result = ret:getArticle() .. ' ' .. ret:getName() + else + result = ret:getName() + end + else + if size > 20 then + reward = Game.createItem(item.itemid, 1) + elseif size > 8 then + reward = Game.createItem(1988, 1) + else + reward = Game.createItem(1987, 1) + end + + for i = 1, size do + local tmp = items[i] + if reward:addItemEx(tmp) ~= RETURNVALUE_NOERROR then + Spdlog.warn("[questSystem1.onUse] - Could not add quest reward to container") + end + end + local ret = ItemType(reward.itemid) + result = ret:getArticle() .. ' ' .. ret:getName() + end + + if player:addItemEx(reward) ~= RETURNVALUE_NOERROR then + local weight = reward:getWeight() + if player:getFreeCapacity() < weight then + player:sendCancelMessage(string.format('You have found %s weighing %.2f oz. You have no capacity.', result, (weight / 100))) + else + player:sendCancelMessage('You have found ' .. result .. ', but you have no room to take it.') + end + return true + end + + if questsExperience[storage] then + player:addExperience(questsExperience[storage], true) + end + + if questLog[storage] then + player:setStorageValue(questLog[storage], 1) + end + + if tutorialIds[storage] then + player:sendTutorial(tutorialIds[storage]) + if item.uid == 50080 then + player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage, 3) + end + end + + if isInArray(hotaQuest, item.uid) then + if player:getStorageValue(Storage.TheAncientTombs.DefaultStart) ~= 1 then + player:setStorageValue(Storage.TheAncientTombs.DefaultStart, 1) + end + end + + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have found ' .. result .. '.') + player:setStorageValue(storage, 1) + return true +end + +for index, value in pairs(specialQuests) do + questSystem1:aid(index) +end + +questSystem1:aid(2000) +questSystem1:register() diff --git a/data/scripts/actions/other/others/quest_system2.lua b/data/scripts/actions/other/others/quest_system2.lua new file mode 100644 index 00000000000..348a0259ddc --- /dev/null +++ b/data/scripts/actions/other/others/quest_system2.lua @@ -0,0 +1,402 @@ +local config = { + [2285] = { + items = { + {itemId = 2356} + }, + storage = Storage.DjinnWar.EfreetFaction.Mission03, + formerValue = 1, + newValue = 2, + needItem = {itemId = 2344}, + effect = CONST_ME_MAGIC_BLUE + }, + [2286] = { + items = { + {itemId = 2318} + }, + storage = Storage.QuestChests.FamilyBrooch + }, + [3002] = { + items = { + {itemId = 2147, count = 6} + }, + storage = Storage.QuestChests.SixRubiesQuest + }, + [3018] = { + items = { + {itemId = 2332} + }, + storage = Storage.Postman.Mission08, + formerValue = 1, + newValue = 2 + }, + [3020] = { + items = { + {itemId = 7503} + }, + storage = Storage.TravellingTrader.Mission02, + formerValue = 3, + newValue = 4 + }, + [3024] = { + items = { + {itemId = 2356} + }, + storage = Storage.DjinnWar.MaridFaction.Mission03, + formerValue = 1, + newValue = 2, + needItem = {itemId = 2344}, + effect = CONST_ME_MAGIC_RED + }, + [3062] = { + items = { + {itemId = 8262} + }, + storage = Storage.QuestChests.KosheiAmulet1 + }, + [3064] = { + items = { + {itemId = 8264} + }, + storage = Storage.QuestChests.KosheiAmulet2 + }, + [3084] = { + items = { + {itemId = 9744} + }, + storage = Storage.InServiceofYalahar.MatrixReward + }, + [3085] = { + items = { + {itemId = 9743} + }, + storage = Storage.InServiceofYalahar.MatrixReward + }, + [3112] = { + items = { + {itemId = 1954, text = ' Tylaf, apprentice of Hjaern'} + }, + storage = Storage.TheIceIslands.Questline, + formerValue = 35, + newValue = 36, + missionStorage = { key = Storage.TheIceIslands.Mission09, value = 2 } + }, + [3116] = { + items = { + {itemId = 2330} + }, + storage = Storage.Postman.Mission09, + formerValue = 1, + newValue = 2 + }, + [3120] = { + items = { + {itemId = 2331} + }, + storage = Storage.Postman.Mission05, + formerValue = 1, + newValue = 2 + }, + [3162] = { + items = { + {itemId = 11101} + }, + storage = Storage.ChildrenoftheRevolution.Questline, + formerValue = 1, + newValue = 2, + say = 'A batch of documents has been stashed in the shelf. These might be of interest to Zalamon.', + effect = CONST_ME_POFF + }, + [3311] = { + items = { + {itemId = 2089, actionId = 3301} + }, + storage = Storage.QuestChests.OutlawCampKey1 + }, + [3312] = { + items = { + {itemId = 2088, actionId = 3302} + }, + storage = Storage.QuestChests.OutlawCampKey2 + }, + [3313] = { + items = { + {itemId = 2089, actionId = 3303} + }, + storage = Storage.QuestChests.OutlawCampKey3 + }, + [4010] = { + items = { + {itemId = 4843} + }, + storage = Storage.TheApeCity.HolyApeHair + }, + [5556] = { + items = { + {itemId = 2463} + }, + storage = Storage.GhostShipQuest + }, + [9136] = { + items = { + {itemId = 2091, actionId = 3980} + }, + storage = Storage.QuestChests.DeeperFibulaKey + }, + [9185] = { + items = { + {itemId = 2134}, {itemId = 2147, count = 2}, {itemId = 2145, count = 3} + }, + storage = Storage.QuestChests.SilverBrooch + }, + [9226] = { + items = { + {itemId = 2503} + }, + storage = Storage.SamsOldBackpack, + formerValue = 2, + newValue = 3 + }, + [9255] = { + items = { + {itemId = 4850} + }, + storage = Storage.HydraEggQuest + }, + [9256] = { + items = { + {itemId = 4840, decay = true} + }, + storage = Storage.TheApeCity.WitchesCapSpot, + time = true + }, + [9259] = { + items = { + {itemId = 11076} + }, + storage = Storage.UnnaturalSelection.Mission01, + formerValue = 1, + newValue = 2, + say = 'You dig out a skull from the pile of bones. That must be the skull Lazaran talked about.' + }, + [9266] = { + items = { + {itemId = 8766} + }, + storage = Storage.ThievesGuild.Mission06, + formerValue = 2, + newValue = 3, + say = 'To buy some time you replace the fish with a piece of carrot.' + }, + [9277] = { + items = { + {itemId = 7736} + }, + storage = Storage.SecretService.RottenTree + }, + [50032] = { + items = { + {itemId = 2798} + }, + storage = Storage.BloodHerbQuest + }, + [50112] = { + items = { + {itemId = 2789, count = 10} + }, + storage = Storage.HiddenCityOfBeregar.BrownMushrooms + }, + [50125] = { + items = { + {itemId = 14348} + }, + storage = Storage.HiddenCityOfBeregar.JusticeForAll, + formerValue = 3, + newValue = 4 + }, + [65201] = { + items = { + {itemId = 2087, actionId = 3980} + }, + storage = 857440 + }, + [65202] = { + items = { + {itemId = 2088, actionId = 3610} + }, + storage = 857441 + }, + [65204] = { + items = { + {itemId = 2381, count = 1} + }, + storage = 857442 + }, + [65205] = { + items = { + {itemId = 2462, count = 1} + }, + storage = 857443 + }, + [65206] = { + items = { + {itemId = 2146, count = 4} + }, + storage = 857444 + }, + [65207] = { + items = { + {itemId = 2642, count = 1} + }, + storage = 857445 + }, + [65208] = { + items = { + {itemId = 2483, count = 1} + }, + storage = 857446 + }, + [65209] = { + items = { + {itemId = 2170, count = 1} + }, + storage = 857447 + }, + [65210] = { + items = { + {itemId = 2260, count = 3} + }, + storage = 857448 + }, + [65211] = { + items = { + {itemId = 2145, count = 1} + }, + storage = 857449 + }, + [65212] = { + items = { + {itemId = 2088, actionId = 3667} + }, + storage = 857450 + }, + -- 65203 reservado +} + +local questSystem2 = Action() + +function questSystem2.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local useItem = config[item.uid] + if not useItem then + return true + end + + if (useItem.time and player:getStorageValue(useItem.storage) > os.time()) + or player:getStorageValue(useItem.storage) ~= (useItem.formerValue or -1) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The ' .. ItemType(item.itemid):getName() .. ' is empty.') + return true + end + + if useItem.needItem then + if player:getItemCount(useItem.needItem.itemId) < (useItem.needItem.count or 1) then + return false + end + end + + local items, reward = useItem.items + local size = #items + if size == 1 then + reward = Game.createItem(items[1].itemId, items[1].count or 1) + end + + local result = '' + if reward then + local ret = ItemType(reward.itemid) + if ret:isRune() then + result = ret:getArticle() .. ' ' .. ret:getName() .. ' (' .. reward.type .. ' charges)' + elseif reward:getCount() > 1 then + result = reward:getCount() .. ' ' .. ret:getPluralName() + elseif ret:getArticle() ~= '' then + result = ret:getArticle() .. ' ' .. ret:getName() + else + result = ret:getName() + end + + if items[1].actionId then + reward:setActionId(items[1].actionId) + end + + if items[1].text then + reward:setText(items[1].text) + end + + if items[1].decay then + reward:decay() + end + + else + if size > 8 then + reward = Game.createItem(1988, 1) + else + reward = Game.createItem(1987, 1) + end + + for i = 1, size do + local tmp = Game.createItem(items[i].itemId, items[i].count or 1) + if reward:addItemEx(tmp) ~= RETURNVALUE_NOERROR then + Spdlog.warn("[questSystem2.onUse] - Could not add quest reward to container") + else + if items[i].actionId then + tmp:setActionId(items[i].actionId) + end + + if items[i].text then + tmp:setText(items[i].text) + end + + if items[i].decay then + tmp:decay() + end + + end + end + local ret = ItemType(reward.itemid) + result = ret:getArticle() .. ' ' .. ret:getName() + end + + if player:addItemEx(reward) ~= RETURNVALUE_NOERROR then + local weight = reward:getWeight() + if player:getFreeCapacity() < weight then + player:sendCancelMessage('You have found ' .. result .. '. Weighing ' .. string.format('%.2f', (weight / 100)) .. ' oz, it is too heavy.') + else + player:sendCancelMessage('You have found ' .. result .. ', but you have no room to take it.') + end + return true + end + + if useItem.say then + player:say(useItem.say, TALKTYPE_MONSTER_SAY) + end + + if useItem.needItem then + player:removeItem(useItem.needItem.itemId, useItem.needItem.count or 1) + end + + if useItem.effect then + toPosition:sendMagicEffect(useItem.effect) + end + + if useItem.missionStorage then + player:setStorageValue(useItem.missionStorage.key, useItem.missionStorage.value) + end + + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have found ' .. result .. '.') + if useItem.time then + player:setStorageValue(useItem.storage, os.time() + 86400) + else + player:setStorageValue(useItem.storage, useItem.newValue or 1) + end + return true +end + +questSystem2:aid(2001) +questSystem2:register() diff --git a/data/scripts/actions/other/party_hat.lua b/data/scripts/actions/other/party_hat.lua new file mode 100644 index 00000000000..63509d15064 --- /dev/null +++ b/data/scripts/actions/other/party_hat.lua @@ -0,0 +1,14 @@ +local partyHat = Action() + +function partyHat.onUse(player, item, fromPosition, target, toPosition, isHotkey) +local slot = player:getSlotItem(CONST_SLOT_HEAD) + if slot and item.uid == slot.uid then + player:addAchievementProgress('Party Animal', 200) + player:getPosition():sendMagicEffect(CONST_ME_GIFT_WRAPS) + return true + end + return false +end + +partyHat:id(6578) +partyHat:register() diff --git a/data/scripts/actions/other/party_trumpet.lua b/data/scripts/actions/other/party_trumpet.lua new file mode 100644 index 00000000000..bb9152043f9 --- /dev/null +++ b/data/scripts/actions/other/party_trumpet.lua @@ -0,0 +1,12 @@ +local partyTrumpet = Action() + +function partyTrumpet.onUse(player, item, fromPosition, target, toPosition, isHotkey) + item:transform(13578) + item:decay() + player:say("TOOOOOOT!", TALKTYPE_MONSTER_SAY) + fromPosition:sendMagicEffect(CONST_ME_SOUND_BLUE) + return true +end + +partyTrumpet:id(6572) +partyTrumpet:register() diff --git a/data/scripts/actions/other/piggy_bank.lua b/data/scripts/actions/other/piggy_bank.lua new file mode 100644 index 00000000000..e028dee39ba --- /dev/null +++ b/data/scripts/actions/other/piggy_bank.lua @@ -0,0 +1,18 @@ +local piggyBank = Action() + +function piggyBank.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if math.random(6) == 1 then + fromPosition:sendMagicEffect(CONST_ME_POFF) + item:transform(2115) + + player:addItem(ITEM_GOLD_COIN, 1) + player:addAchievementProgress('Allowance Collector', 50) + else + fromPosition:sendMagicEffect(CONST_ME_SOUND_YELLOW) + player:addItem(ITEM_PLATINUM_COIN, 1) + end + return true +end + +piggyBank:id(2114) +piggyBank:register() diff --git a/data/scripts/actions/other/potions.lua b/data/scripts/actions/other/potions.lua new file mode 100644 index 00000000000..a58cc583ad1 --- /dev/null +++ b/data/scripts/actions/other/potions.lua @@ -0,0 +1,308 @@ +local berserk = Condition(CONDITION_ATTRIBUTES) +berserk:setParameter(CONDITION_PARAM_TICKS, 10 * 60 * 1000) +berserk:setParameter(CONDITION_PARAM_SKILL_MELEE, 5) +berserk:setParameter(CONDITION_PARAM_SKILL_SHIELD, -10) +berserk:setParameter(CONDITION_PARAM_BUFF_SPELL, true) + +local mastermind = Condition(CONDITION_ATTRIBUTES) +mastermind:setParameter(CONDITION_PARAM_TICKS, 10 * 60 * 1000) +mastermind:setParameter(CONDITION_PARAM_STAT_MAGICPOINTS, 3) +mastermind:setParameter(CONDITION_PARAM_BUFF_SPELL, true) + +local bullseye = Condition(CONDITION_ATTRIBUTES) +bullseye:setParameter(CONDITION_PARAM_TICKS, 10 * 60 * 1000) +bullseye:setParameter(CONDITION_PARAM_SKILL_DISTANCE, 5) +bullseye:setParameter(CONDITION_PARAM_SKILL_SHIELD, -10) +bullseye:setParameter(CONDITION_PARAM_BUFF_SPELL, true) + +local antidote = Combat() +antidote:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING) +antidote:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +antidote:setParameter(COMBAT_PARAM_DISPEL, CONDITION_POISON) +antidote:setParameter(COMBAT_PARAM_AGGRESSIVE, false) +antidote:setParameter(COMBAT_PARAM_TARGETCASTERORTOPMOST, true) + +local exhaust = Condition(CONDITION_EXHAUST_HEAL) +exhaust:setParameter(CONDITION_PARAM_TICKS, (configManager.getNumber(configKeys.EX_ACTIONS_DELAY_INTERVAL) - 1000)) +-- 1000 - 100 due to exact condition timing. -100 doesn't hurt us, and players don't have reminding ~50ms exhaustion. + +local function magicshield(player) +local condition = Condition(CONDITION_MANASHIELD) +condition:setParameter(CONDITION_PARAM_TICKS, 60000) +condition:setParameter(CONDITION_PARAM_MANASHIELD, math.min(player:getMaxMana(), 300 + 7.6 * player:getLevel() + 7 * player:getMagicLevel())) +player:addCondition(condition) +end + +local potions = { + [6558] = { + transform = { + id = {7588, 7589} + }, + effect = CONST_ME_DRAWBLOOD + }, + [7439] = { + vocations = { + VOCATION.CLIENT_ID.KNIGHT + }, + condition = berserk, + effect = CONST_ME_MAGIC_RED, + description = "Only knights may drink this potion.", + text = "You feel stronger." + }, + [7440] = { + vocations = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID + }, + condition = mastermind, + effect = CONST_ME_MAGIC_BLUE, + description = "Only sorcerers and druids may drink this potion.", + text = "You feel smarter." + }, + [7443] = { + vocations = { + VOCATION.CLIENT_ID.PALADIN + }, + condition = bullseye, + effect = CONST_ME_MAGIC_GREEN, + description = "Only paladins may drink this potion.", + text = "You feel more accurate." + }, + [40398] = { + vocations = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID + }, + level = 14, + func = magicshield, + effect = CONST_ME_ENERGYAREA, + description = "Only sorcerers and druids of level 14 or above may drink this potion.", + }, + [7588] = { + health = { + 250, + 350 + }, + vocations = { + VOCATION.CLIENT_ID.PALADIN, + VOCATION.CLIENT_ID.KNIGHT + }, + level = 50, + flask = 7634, + description = "Only knights and paladins of level 50 or above may drink this fluid." + }, + [7589] = { + mana = { + 115, + 185 + }, + level = 50, + flask = 7634, + description = "Only players of level 50 or above may drink this fluid." + }, + [7590] = { + mana = { + 150, + 250 + }, + vocations = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID, + VOCATION.CLIENT_ID.PALADIN + }, + level = 80, + flask = 7635, + description = "Only sorcerers, druids and paladins of level 80 or above may drink this fluid." + }, + [7591] = { + health = { + 425, + 575 + }, + vocations = { + VOCATION.CLIENT_ID.KNIGHT + }, + level = 80, + flask = 7635, + description = "Only knights of level 80 or above may drink this fluid." + }, + [7618] = { + health = { + 125, + 175 + }, + flask = 7636 + }, + [7620] = { + mana = { + 75, + 125 + }, + flask = 7636 + }, + [8472] = { + health = { + 250, + 350 + }, + mana = { + 100, + 200 + }, + vocations = { + VOCATION.CLIENT_ID.PALADIN + }, + level = 80, + flask = 7635, + description = "Only paladins of level 80 or above may drink this fluid." + }, + [8473] = { + health = {650, 850}, + vocations = { + VOCATION.CLIENT_ID.KNIGHT + }, + level = 130, + flask = 7635, + description = "Only knights of level 130 or above may drink this fluid." + }, + [8474] = { + combat = antidote, + flask = 7636 + }, + [8704] = { + health = { + 60, + 90 + }, + flask = 7636 + }, + [26029] = { + mana = { + 425, + 575 + }, + vocations = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID + }, + level = 130, + flask = 7635, + description = "Only druids and sorcerers of level 130 or above may drink this fluid." + }, + [26030] = { + health = { + 420, + 580 + }, + mana = { + 250, + 350 + }, + vocations = { + VOCATION.CLIENT_ID.PALADIN + }, + level = 130, + flask = 7635, + description = "Only paladins of level 130 or above may drink this fluid." + }, + [26031] = { + health = { + 875, + 1125 + }, + vocations = { + VOCATION.CLIENT_ID.KNIGHT + }, + level = 200, + flask = 7635, + description = "Only knights of level 200 or above may drink this fluid." + } +} + +local flaskPotion = Action() + +function flaskPotion.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if type(target) == "userdata" and not target:isPlayer() then + return false + end + + -- Delay potion + if not playerDelayPotion[player:getId()] then + playerDelayPotion[player:getId()] = 0 + end + if playerDelayPotion[player:getId()] > os.mtime() then + player:sendTextMessage(MESSAGE_FAILURE, Game.getReturnMessage(RETURNVALUE_YOUAREEXHAUSTED)) + return true + end + + local potion = potions[item:getId()] + if potion.level and player:getLevel() < potion.level or potion.vocations and not table.contains(potion.vocations, player:getVocation():getClientId()) and not (player:getGroup():getId() >= 2) then + player:say(potion.description, MESSAGE_POTION) + return true + end + + if player:getCondition(CONDITION_EXHAUST_HEAL) then + player:sendTextMessage(MESSAGE_FAILURE, Game.getReturnMessage(RETURNVALUE_YOUAREEXHAUSTED)) + return true + end + + if potion.health or potion.mana or potion.combat then + if potion.health then + doTargetCombatHealth(0, target, COMBAT_HEALING, potion.health[1], potion.health[2], CONST_ME_MAGIC_BLUE) + end + + if potion.mana then + doTargetCombatMana(0, target, potion.mana[1], potion.mana[2], CONST_ME_MAGIC_BLUE) + end + + if potion.combat then + potion.combat:execute(target, Variant(target:getId())) + end + + player:addAchievementProgress('Potion Addict', 100000) + target:say("Aaaah...", MESSAGE_POTION) + player:addItem(potion.flask, 1) + player:addCondition(exhaust) + player:setStorageValue(38412, player:getStorageValue(38412)+1) + end + + -- Delay potion + playerDelayPotion[player:getId()] = os.mtime() + 500 + + if potion.func then + potion.func(player) + if potion.text then + player:say(potion.text, MESSAGE_POTION) + end + player:getPosition():sendMagicEffect(potion.effect) + end + + if potion.condition then + player:addCondition(potion.condition) + player:say(potion.text, MESSAGE_POTION) + player:getPosition():sendMagicEffect(potion.effect) + end + + if potion.transform then + if item:getCount() >= 1 then + item:remove(1) + player:addItem(potion.transform.id[math.random(#potion.transform.id)], 1) + item:getPosition():sendMagicEffect(potion.effect) + return true + end + end + + if not configManager.getBoolean(configKeys.REMOVE_POTION_CHARGES) then + return true + end + + player:updateSupplyTracker(item) + item:remove(1) + return true +end + +for index, value in pairs(potions) do + flaskPotion:id(index) +end + +flaskPotion:register() diff --git a/data/scripts/actions/other/rafzane_elevator.lua b/data/scripts/actions/other/rafzane_elevator.lua new file mode 100644 index 00000000000..3eece262fa2 --- /dev/null +++ b/data/scripts/actions/other/rafzane_elevator.lua @@ -0,0 +1,95 @@ +local elevatorPosition = { + Position(33051, 32099, 6), + Position(33051, 32099, 7) +} + +local config = { + [1] = { + fromPosition = elevatorPosition[1], + toPosition = elevatorPosition[2], + itemIds = { 20218, 20219 }, + transform = { + position = { elevatorPosition[1], elevatorPosition[2] }, + itemId = { 20219, 20219 }, + transformId = { 20222, 20223 } + }, + sound = 'Srrrt!', + soundPosition = Position(33052, 32099, 6), + relocatePosition = Position(33051, 32098, 6) + }, + [2] = { + fromPosition = elevatorPosition[2], + toPosition = elevatorPosition[1], + itemIds = { 20218, 20223 }, + transform = { + position = { elevatorPosition[1], elevatorPosition[1] }, + itemId = { 20222, 20223 }, + transformId = { 20219, 20219 }, + }, + sound = 'Zrrrt!', + soundPosition = Position(33052, 32099, 7), + relocatePosition = Position(33051, 32100, 7) + } +} + +local winch = { + [20220] = { config[2], config[1] }, + [20224] = { config[1], config[2] } +} + +local relocate = true + +local function moveElevator(config, player) + for i = 1, #config.itemIds do + local item = Tile(config.fromPosition):getItemById(config.itemIds[i]) + if item then + item:moveTo(config.toPosition) + end + end + + for i = 1, #config.transform.position do + local item = Tile(config.transform.position[i]):getItemById(config.transform.itemId[i]) + if item then + item:transform(config.transform.transformId[i]) + end + end + + if player then + player:say(config.sound, TALKTYPE_MONSTER_YELL, false, player, config.soundPosition) + end +end + +local rafzaneElevator = Action() + +function rafzaneElevator.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local useItem = winch[item.itemid] + if not useItem then + return true + end + + toPosition.x = toPosition.x - 1 + local tile = Tile(toPosition) + if not tile:getItemById(20218) then + local option = useItem[1] + if relocate then + Tile(option.fromPosition):relocateTo(option.relocatePosition) + end + + moveElevator(option, player) + return true + end + + local creature = tile:getTopCreature() + if not creature or creature.uid ~= player.uid then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Step inside the elevator to use it.') + return true + end + + local option = useItem[2] + moveElevator(option, player) + player:teleportTo(option.toPosition) + return true +end + +rafzaneElevator:id(20220, 20224) +rafzaneElevator:register() diff --git a/data/scripts/actions/other/roasted_meat.lua b/data/scripts/actions/other/roasted_meat.lua new file mode 100644 index 00000000000..1971d1e4e78 --- /dev/null +++ b/data/scripts/actions/other/roasted_meat.lua @@ -0,0 +1,12 @@ +local roastedMeat = Action() + +function roastedMeat.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid == 1423 then -- campfire + item:transform(24843) -- roasted meat + toPosition:sendMagicEffect(CONST_ME_HITBYFIRE) + end + return true +end + +roastedMeat:id(24842) +roastedMeat:register() \ No newline at end of file diff --git a/data/scripts/actions/other/string_of_mending.lua b/data/scripts/actions/other/string_of_mending.lua new file mode 100644 index 00000000000..4cd58c326c9 --- /dev/null +++ b/data/scripts/actions/other/string_of_mending.lua @@ -0,0 +1,48 @@ +------------ +-- Alternative to no-magic style. +-- Description here +---- + +---- string of mending id "22542"----- +local ITEMS = { + [13877] = { -----Broken Ring Id "13877" Ring of ending "22516" + {"ring of ending", 50.50} ----- 1.97 es la probabilidad de crear el item + } +} + +local stringOfMending = Action() + +---- onUse [opt] +-- @param cid Player ID +-- @param item Item ID +-- @param fromPosition Current Position +-- @param[opt] itemEx Item change +-- @param[opt] toPosition Nem position +function stringOfMending.onUse(cid, item, fromPosition, itemEx, toPosition) + local cadena = ITEMS[itemEx.itemid] + if cadena == nil then + return false + end + + local iEx = Item(itemEx.uid) + local random, chance = math.random() * 100, 0 + + for i = 1, #cadena do + chance = chance + cadena[i][2] + if random <= chance then + iEx:transform(cadena[i][1]) + iEx:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + Item(item.uid):remove(1) + return true + end + end + + iEx:getPosition():sendMagicEffect(CONST_ME_BLOCKHIT) + Item(item.uid):remove(1) + iEx:remove() + doCreatureSay(cid, "50% chance, the item was broken.", TALKTYPE_ORANGE_1) + return true +end + +stringOfMending:id(22542) +stringOfMending:register() diff --git a/data/scripts/actions/other/surprise_bag.lua b/data/scripts/actions/other/surprise_bag.lua new file mode 100644 index 00000000000..1bae36b1120 --- /dev/null +++ b/data/scripts/actions/other/surprise_bag.lua @@ -0,0 +1,41 @@ +local config = { + [6570] = { -- bluePresent + {2687, 10}, {6394, 3}, 6280, 6574, 6578, 6575, 6577, 6569, 6576, 6572, 2114, 15439, 16014 + }, + [6571] = { -- redPresent + 6574, 2195, 6394, 6576, 6578, 2114, 15439, 2153, 5944, 2492, 2520, 2156, 5080, 2112, 2498, 2173, 5791 + }, + [9108] = { -- surpriseBag + {2148, 10}, 7487, 2114, 8072, 7735, 8110, 6574, 6394, 7377, 2667, 9693 + }, + [16094] = { -- surpriseBag + {10559, 15},{2670, 15}, 5917, 2385, 11219, 2238, 5928, 5926, 5927, 6095, 5918, 6097, 6098, 5462, 5091 + }, + [16102] = { -- surpriseBag + {6569, 10}, {6541, 10}, {6542, 10}, {6543, 10}, {6544, 10}, {6545, 10}, 6574, 4850, 6570, 6571, 11400 + } +} + +local surpriseBag = Action() + +function surpriseBag.onUse(cid, item, fromPosition, itemEx, toPosition) + local present = config[item.itemid] + if not present then + return false + end + + local count = 1 + local gift = present[math.random(1, #present)] + if type(gift) == "table" then + count = gift[2] + gift = gift[1] + end + + Player(cid):addItem(gift, count) + Item(item.uid):remove(1) + fromPosition:sendMagicEffect(CONST_ME_GIFT_WRAPS) + return true +end + +surpriseBag:id(6570, 6571, 9108, 16094, 16102) +surpriseBag:register() diff --git a/data/scripts/actions/other/surprise_box.lua b/data/scripts/actions/other/surprise_box.lua new file mode 100644 index 00000000000..1173dd01178 --- /dev/null +++ b/data/scripts/actions/other/surprise_box.lua @@ -0,0 +1,31 @@ +local prize = { + [1] = {chance = 1, id = 2358, amount = 1 }, + [2] = {chance = 2, id = 11144, amount = 1 }, + [3] = {chance = 3, id = 12544, amount = 1 }, + [4] = {chance = 4, id = 2640, amount = 1 }, + [5] = {chance = 5, id = 2520, amount = 1 }, + [6] = {chance = 10, id = ITEM_CRYSTAL_COIN, amount = 17 }, + [7] = {chance = 20, id = ITEM_GOLD_COIN, amount = 1 }, + [8] = {chance = 30, id = ITEM_CRYSTAL_COIN, amount = 1 }, + [9] = {chance = 40, id = ITEM_GOLD_COIN, amount = 50 }, + [10] = {chance = 50, id = ITEM_PLATINUM_COIN, amount = 15 }, + [11] = {chance = 90, id = ITEM_GOLD_COIN, amount = 80}, +} + +local surpriseBox = Action() + +function surpriseBox.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + for i = 1,#prize do local number = math.random() * 100 + if prize[i].chance>100-number then + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:addItem(prize[i].id, prize[i].amount) + item:remove() + break + end + end + return true +end + +surpriseBox:id(26333) +surpriseBox:register() diff --git a/data/scripts/actions/other/sweet_heart.lua b/data/scripts/actions/other/sweet_heart.lua new file mode 100644 index 00000000000..b94610de10b --- /dev/null +++ b/data/scripts/actions/other/sweet_heart.lua @@ -0,0 +1,20 @@ +local sweetHeart = Action() + +function sweetHeart.onUse(cid, item, fromPosition, itemEx, toPosition) + local player = Player(cid) + if (not player) then + return false + end + + if (player:getSlotItem(CONST_SLOT_RING)) then + if (player:getSlotItem(CONST_SLOT_RING):getId() == item:getId()) then + player:getPosition():sendMagicEffect(CONST_ME_HEARTS) + end + else + return false + end + return true +end + +sweetHeart:id(24324) +sweetHeart:register() diff --git a/data/scripts/actions/other/teleport.lua b/data/scripts/actions/other/teleport.lua new file mode 100644 index 00000000000..896cb3dc51b --- /dev/null +++ b/data/scripts/actions/other/teleport.lua @@ -0,0 +1,16 @@ +local upFloorIds = {1386, 3678, 5543, 22845, 22846, 33397, 35005, 36097, 35964, 35965, 39078} + +local teleport = Action() + +function teleport.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if isInArray(upFloorIds, item.itemid) then + fromPosition:moveUpstairs() + else + fromPosition.z = fromPosition.z + 1 + end + player:teleportTo(fromPosition, false) + return true +end + +teleport:id(430, 1386, 3678, 5543, 22845, 22846, 33397, 35005, 35964, 35965, 36097, 39078) +teleport:register() diff --git a/data/scripts/actions/other/teleport_draw_well.lua b/data/scripts/actions/other/teleport_draw_well.lua new file mode 100644 index 00000000000..953d5395825 --- /dev/null +++ b/data/scripts/actions/other/teleport_draw_well.lua @@ -0,0 +1,14 @@ +local teleportDrawWell = Action() + +function teleportDrawWell.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item:getActionId() ~= 1000 then + return false + end + + fromPosition.z = fromPosition.z + 1 + player:teleportTo(fromPosition) + return true +end + +teleportDrawWell:id(1369) +teleportDrawWell:register() diff --git a/data/scripts/actions/other/teleport_item.lua b/data/scripts/actions/other/teleport_item.lua new file mode 100644 index 00000000000..7e6a92bb5a9 --- /dev/null +++ b/data/scripts/actions/other/teleport_item.lua @@ -0,0 +1,19 @@ +-- Script for items that teleport when giving use +-- Add a new item in the action_unique table at the correct range + +local teleportItem = Action() + +function teleportItem.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local setting = TeleportItemUnique[item.uid] + if setting then + player:teleportTo(setting.destination) + player:getPosition():sendMagicEffect(setting.effect) + end + return true +end + +for uniqueRange = 15001, 20000 do + teleportItem:uid(uniqueRange) +end + +teleportItem:register() diff --git a/data/scripts/actions/other/temple_scroll.lua b/data/scripts/actions/other/temple_scroll.lua new file mode 100644 index 00000000000..a7c04725af3 --- /dev/null +++ b/data/scripts/actions/other/temple_scroll.lua @@ -0,0 +1,16 @@ +local templeScroll = Action() + +function templeScroll.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if not player:isPzLocked() and not player:getCondition(CONDITION_INFIGHT, CONDITIONID_DEFAULT) then + player:teleportTo(getTownTemplePosition(player:getTown():getId())) + item:remove() + Position(fromPosition):sendMagicEffect(CONST_ME_TELEPORT) + else + player:sendCancelMessage("You can't use this when you're in a fight.") + Position(fromPosition):sendMagicEffect(CONST_ME_POFF) + end + return true +end + +templeScroll:id(29019) +templeScroll:register() diff --git a/data/scripts/actions/other/thais_exhibition.lua b/data/scripts/actions/other/thais_exhibition.lua new file mode 100644 index 00000000000..187df4ffafb --- /dev/null +++ b/data/scripts/actions/other/thais_exhibition.lua @@ -0,0 +1,364 @@ +local exhibits = { + [50030] = { + sounds = { + {text = 'Hail |PLAYERNAME|, my friend!'}, + {text = 'Friends forever!'}, + {text = 'Look, how our friendship shines!'}, + {text = 'Hail Tibiafriends!'} + }, + itemid = 10719, + dir = DIRECTION_NORTH + }, + [50031] = { + sounds = { + {text = 'Why so serious?'}, + {text = 'These are not the puppets you are looking for...'}, + {text = 'May the roleplay be with you.'}, + {text = 'An age of roleplay, and all will know, that three hundred puppets gave their last breath to defend it!'}, + {text = 'They stoles it! Sneaky little puppetses!'}, + {text = 'There was a dream that was roleplay. You could only whisper it. Anything more than a whisper and it would vanish.'} + }, + itemid = 10107, + dir = DIRECTION_WEST + }, + [50032] = { + sounds = { + {text = 'Hauopa!'}, + {text = 'Yala Boom', exhibitEffect = CONST_ME_SOUND_RED}, + {text = 'Hail Portal Tibia!'} + }, + itemid = 10063, + transformid = 10064, + dir = DIRECTION_NORTH + }, + [50033] = { + sounds = { + {text = 'Hail TibiaNordic!'}, + {text = 'So cold...'}, + {text = 'Run, mammoth!'} + }, + itemid = 8982, + dir = DIRECTION_WEST + }, + [50034] = { + sounds = { + {text = 'Hail Tibia Library!'}, + {text = 'Shhhhhh, please be quiet!'}, + {text = 'Books are great!! Aren\'t they?'} + }, + itemid = 20624, + dir = DIRECTION_NORTH + }, + [50035] = { + sounds = { + {text = 'It\'s news to me.'}, + {text = 'News, updated as infrequently as possible!'}, + {text = 'Extra! Extra! Read all about it!'}, + {text = 'Fresh off the press!'} + }, + itemid = 8981, + dir = DIRECTION_NORTH + }, + [50036] = { + sounds = { + {text = 'I own, Tibiacity owns, perfect match!'}, + {text = 'Weirdo, you\'re a weirdo! Actually all of you are!'}, + {text = 'All hail the control panel!'}, + {text = 'Pie for breakfast, pie for lunch and pie for dinner!'}, + {text = 'Hug me! Feed me! Hail me!'} + }, + itemid = 8977, + dir = DIRECTION_WEST + }, + [50037] = { + sounds = { + {text = 'Oh, when I get my claws on you...'}, + {text = 'Let\'s hunt, |PLAYERNAME|!'}, + {text = 'Hail TibiaBR.com! Flap! Flap!'} + }, + itemid = 8976, + transformid = 9003, + dir = DIRECTION_NORTH + }, + [50038] = { + sounds = { + {text = 'I WILL PROTECT YOUR KNOWLEDGEZZZ.'}, + {text = 'FCHHH - FEEEEED ME AT TIBIAVENEZUELA.COM'}, + {text = 'I SENSE WISDOM...HUMILITY...AND...PERSEVERANCE!!!'}, + {text = 'MAY MY ETERNAL FLAME BE YOUR SHIELD AND PATH OF SUCCESS, |PLAYERNAME|!'} + }, + itemid = 11394, + dir = DIRECTION_NORTH + }, + [50039] = { + sounds = { + {text = 'Mwahaha!'}, + {text = 'NO ONE WILL STOP ME THIS TIME!'}, + {text = 'THE POWER IS IN TIBIOPEDIA!'}, + {text = 'THE POWER IS MINE!'} + }, + itemid = 11754, + dir = DIRECTION_NORTH + }, + [50040] = { + sounds = { + {text = 'Could a dead, frozen heart beat again? It felt like mine was about to.'}, + {text = 'The world was born from Tibiasula\'s love.'}, + {text = 'Look after TibiaTR\'s frozen heart. I\'ve left it with you.'}, + {text = 'Hail TibiaTR.net!'} + }, + itemid = 13028, + transformid = 13029, + transformDuration = 13000, + dir = DIRECTION_NORTH + }, + [50041] = { + sounds = { + {text = 'For zze emperor!'}, + {text = 'Hail TibiaJourney.com!'}, + {text = 'Hail |PLAYERNAME|!'} + }, + itemid = 13030, + dir = DIRECTION_NORTH + }, + [50042] = { + itemids = { + { + itemid = 13032, + transformid = 13033 + }, + { + itemid = 13033, + transformid = 13032 + } + }, + dir = DIRECTION_NORTH + }, + [50043] = { + sounds = { + {text = 'My powers are limitless!'}, + {text = 'Hail Tibia Bariloche!'} + }, + itemid = 16107, + dir = DIRECTION_NORTH + }, + [50044] = { + sounds = { + {text = 'Do not trade me!'}, + {text = 'Hail |PLAYERNAME|!'}, + {text = 'Hail Tibia-Market!'} + }, + itemid = 18526, + dir = DIRECTION_NORTH + }, + [50045] = { + sounds = { + {text = 'Uploading to TibiaEvents.... processing...'}, + {text = 'Say "Rat CHeese!"'}, + {text = 'I got the perfect shot!'}, + {text = 'Hold still...got it!'}, + {text = 'Look at this one! Wasn\'t this your first battle with a dragon?'}, + {text = 'This picture reminds me of the latest event.'} + }, + itemid = 21731, + transformid = 21732, + transformDuration = 7000, + dir = DIRECTION_WEST + }, + [50046] = { + itemid = 18550, + transformid = 18551, + dir = DIRECTION_NORTH + }, + [50047] = { + sounds = { + {text = 'I will petrify thisss moment! Sstonesss are forever!!!'}, + {text = 'Where isss my body?!? I\'ll kill you!!!'} + }, + itemid = 16105, + dir = DIRECTION_NORTH + }, + [50048] = { + sounds = { + {exhibitEffect = CONST_ME_LOSEENERGY} + }, + itemid = 16103, + transformid = 16104, + dir = DIRECTION_NORTH + }, + [50049] = { + sounds = { + {text = 'Now you will see, |PLAYERNAME|!'}, + {text = 'More eyes for many numbers!'}, + {text = '469!? So easy...'}, + {text = 'Numbers for Exhiti...'} + }, + itemid = 13948, + transformid = 13949, + dir = DIRECTION_WEST + }, + [50050] = { + itemids = { + { + sounds = { + {text = 'Now Tibia bffff... has sound.'}, + {text = 'Hail bffff... RadioTibia!'}, + {text = 'Hello bffff... |PLAYERNAME|.'} + }, + itemid = 13950, + transformid = 13951 + }, + { + itemid = 13951, + transformid = 13950 + } + }, + dir = DIRECTION_NORTH + }, + [50051] = { + sounds = { + {text = 'MY BRAIN... TOO MUCH... KNOWLEDGE! AAAAH!', playerEffect = CONST_ME_STUN}, + {text = 'Excalibug is lying at the heart of every true fighter.'}, + {text = 'Fire is fascinating. But whether it is going to light your path or burning you till death, you can never tell.'} + }, + itemid = 13946, + dir = DIRECTION_NORTH + }, + [50052] = { + sounds = { + {text = 'Mhausheausheu! What a FAIL! Mwahaha!'}, + {text = 'Hail |PLAYERNAME|! You are wearing old socks!'}, + {text = 'ou are so unpopular even your own shadow refuses to follow you.'}, + {text = 'Have fun with FunTibia.com!'} + }, + itemid = 13559, + dir = DIRECTION_NORTH + }, + [50053] = { + sounds = { + {text = 'Come closer, I will show some Tibian mysteries to you!'}, + {text = 'Feel the eternity of Tibiafans.se!'}, + {text = '|PLAYERNAME|, you are worthy to feel the power of Tibiafans.se! HAIL TIBIAFANS!'} + }, + itemid = 12667, + dir = DIRECTION_WEST + }, + [50054] = { + sounds = { + {text = 'Hail |PLAYERNAME|!'}, + {text = 'Hail TibiaSpy.com!'}, + {text = 'Wrrrzzzgggrrzzzz...'}, + {text = 'Yummy...'} + }, + itemid = 11756, + dir = DIRECTION_NORTH + }, + [50055] = { + sounds = { + {text = 'According to tibia-wiki.net, Jalapeño Peppers are as hot and famous as the place they come from - Ankrahmun.'}, + {text = 'According to tibia-wiki.net, a Bulb of Garlic is a great spice AND protection against vampires.'}, + {text = 'According to tibia-wiki.net, star and sling herbs taste like cinnamon and vanilla.'} + }, + itemid = 11773, + dir = DIRECTION_NORTH + }, + [50056] = { + sounds = { + {text = 'Click! You don\'t seem experienced enough to open this properly.'}, + {text = 'Click! The box won\'t open for you.'}, + {text = 'Click! This item is too precious for a newbie. You are unable to open it.'} + }, + itemid = 11401, + transformid = 11402, + transformDuration = 7000, + dir = DIRECTION_NORTH + }, +} + +local function resetExhibit(exhibitPosition, actionid) + local settings = exhibits[actionid] + if not settings.transformid then + return + end + + local exhibitItem = Tile(exhibitPosition):getItemById(settings.transformid) + if exhibitItem then + exhibitItem:transform(settings.itemid) + end +end + +local function resetLever(leverPos) + local leverItem = Tile(leverPos):getItemById(1946) + if leverItem then + leverItem:transform(1945) + end +end + +local thaisExhibition = Action() + +function thaisExhibition.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 1946 then + return false + end + + local settings = exhibits[item.actionid] + if not settings then + return false + end + + local exhibitPosition = fromPosition + exhibitPosition:getNextPosition(settings.dir) + + local exhibitTile = Tile(exhibitPosition) + local exhibitItem, isToggle = nil, false + if settings.itemid then + exhibitItem = exhibitTile:getItemById(settings.itemid) + elseif settings.itemids then + for i = 1, #settings.itemids do + local tmpItem = exhibitTile:getItemById(settings.itemids[i].itemid) + if tmpItem then + exhibitItem = tmpItem + isToggle = true + settings = settings.itemids[i] + break + end + end + end + + if not exhibitItem then + return false + end + + if settings.sounds and #settings.sounds > 0 then + local sound = settings.sounds[math.random(#settings.sounds)] + if sound.text then + player:say(sound.text:gsub('|PLAYERNAME|', player:getName()), TALKTYPE_MONSTER_SAY, false, nil, exhibitPosition) + end + + if sound.exhibitEffect then + exhibitPosition:sendMagicEffect(sound.exhibitEffect) + end + + if sound.playerEffect then + player:getPosition():sendMagicEffect(sound.playerEffect) + end + end + + if settings.transformid then + exhibitItem:transform(settings.transformid) + end + + item:transform(1946) + addEvent(resetLever, 6000 or 6000, toPosition) + + if not isToggle then + addEvent(resetExhibit, 6000 or 6000, exhibitPosition, item.actionid) + end + return true +end + +for index, value in pairs(exhibits) do + thaisExhibition:aid(index) +end + +thaisExhibition:register() diff --git a/data/scripts/actions/other/transform_to.lua b/data/scripts/actions/other/transform_to.lua new file mode 100644 index 00000000000..d51e149ff5a --- /dev/null +++ b/data/scripts/actions/other/transform_to.lua @@ -0,0 +1,125 @@ +local voices = { + [26364] = "Au au!", + [26099] = "Grooaarr!" +} + +local transformItems = { + [1479] = 1480, [1480] = 1479, + [1634] = 1635, [1635] = 1634, + [1636] = 1637, [1637] = 1636, + [1638] = 1639, [1639] = 1638, + [1640] = 1641, [1641] = 1640, + [1786] = 1787, [1787] = 1786, + [1788] = 1789, [1789] = 1788, + [1790] = 1791, [1791] = 1790, + [1792] = 1793, [1793] = 1792, + [1873] = 1874, [1874] = 1873, + [1875] = 1876, [1876] = 1875, + [1945] = 1946, [1946] = 1945, + [2037] = 2038, [2038] = 2037, + [2039] = 2040, [2040] = 2039, + [2041] = 2042, [2042] = 2041, + [2044] = 2045, [2045] = 2044, + [2047] = 2048, [2048] = 2047, + [2050] = 2051, [2051] = 2050, + [2052] = 2053, [2053] = 2052, + [2054] = 2055, [2055] = 2054, + [2058] = 2059, [2059] = 2058, + [2060] = 2061, [2061] = 2060, + [2064] = 2065, [2065] = 2064, + [2066] = 2067, [2067] = 2066, + [2068] = 2069, [2069] = 2068, + [2096] = 2097, [2097] = 2096, + [2162] = 2163, [2163] = 2162, + [2578] = 2579, + [3697] = 3698, [3698] = 3697, + [3699] = 3700, [3700] = 3699, + [3947] = 3948, [3948] = 3947, + [5812] = 5813, [5813] = 5812, + [6489] = 6490, [6490] = 6489, + [7058] = 7059, [7059] = 7058, + [8684] = 8685, [8685] = 8684, + [8686] = 8687, [8687] = 8686, + [8688] = 8689, [8689] = 8688, + [8690] = 8691, [8691] = 8690, + [9575] = 9576, [9576] = 9575, + [9577] = 9578, [9578] = 9577, + [9579] = 9580, [9580] = 9579, + [9581] = 9582, [9582] = 9581, + [9747] = 9748, [9748] = 9747, + [9749] = 9750, [9750] = 9749, + [19691] = 19692, [19692] = 19691, + [22869] = 22868, [22868] = 22869, + [22871] = 22870, [22870] = 22871, + [22872] = 22873, [22873] = 22872, + [22874] = 22875, [22875] = 22874, + [26094] = 26096, [26096] = 26094, [26095] = 26097, [26097] = 26095, --protectress lamp + [26090] = 26092, [26092] = 26090, [26091] = 26093, [26093] = 26091, --predador lamp + [26098] = 26099, [26099] = 26098, --baby dragon + [26100] = 26101, [26101] = 26100, --hamster wheel + [26107] = 26108, [26108] = 26107, --cat in a basket + [26141] = 26142, [26142] = 26141, --barrel + [26364] = 26365, [26365] = 26364, --dog house + [26365] = 26353, [26353] = 26364, --dog house + [22614] = 22615, [22615] = 22614, --beacon + [25420] = 25421, [25421] = 25420, --ferumbras staff + [24809] = 24810, [24810] = 24809, --skull + [27100] = 27101, [27101] = 27100, --parrot + [27102] = 27104, [27103] = 27102, --skull lamp + [27888] = 27886, [27887] = 27888, --vengothic lamp + [29314] = 29315, --spider terrarium + [29317] = 29319, [29319] = 29317, --hrodmiran weapons rack + [29320] = 29318, [29318] = 29320, --hrodmiran weapons rack side + [29407] = 29405, [29408] = 29406, --snake terrarium + [29409] = 29411, [29410] = 29412, --demon pet + [32023] = 32070, --light of change empty to red + [32070] = 33174, --light of change red to green + [32036] = 32037, [32037] = 32036, --pile of alchemistic books + [32258] = 32259, [32259] = 32258, --anglerfish lamp + [32390] = 32391, [32391] = 32390, --baby rotworm + [32394] = 32395, [32395] = 32394, --fennec + [32759] = 32761, [32761] = 32759, --bonelord statue + [32760] = 32762, [32762] = 32760, --bonelord statue + [32769] = 32771, [32771] = 32769, --scholar bust + [32770] = 32772, [32772] = 32770, --scholar bust + [32773] = 32775, [32775] = 32773, --scholar bust + [32774] = 32776, [32776] = 32774, --scholar bust + [33174] = 32026, --light of change green to blue + [32026] = 32023, --light of change blue to empty + [33491] = 33492, [33492] = 33491, --fluorescent fungi + [33493] = 33494, [33494] = 33493, --luminescent fungi + [33495] = 33496, [33496] = 33495, --glowing sulphur fungi + [33497] = 33498, [33498] = 33497, --gloomy poisonous fungi + [35031] = 35032, [35032] = 35031, --festive tree + [35042] = 35043, [35043] = 35042, --festive pyramid + [36031] = 36032, [36032] = 36031, --crystal lamp + [36048] = 36050, [36050] = 36048, --idol lamp + [36049] = 36051, [36051] = 36049, --idol lamp side + [36516] = 36517, [36517] = 36516, --hedgehog + [36518] = 36519, [36519] = 36518, --exalted sarcophagus + [36530] = 36531, [36531] = 36530, --curly hortensis lamp + [36532] = 36533, [36533] = 36532, --little big flower lamp + [36539] = 36538, [36538] = 36539, --baby unicorn + [36509] = 36510, --omniscient owl +} + +local transformTo = Action() + +function transformTo.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if (voices[item:getId()]) then + local spectators = Game.getSpectators(fromPosition, false, true, 3, 3) + for i = 1, #spectators do + player:say(voices[item:getId()], TALKTYPE_MONSTER_SAY, false, spectators[i], fromPosition) + end + end + + item:transform(transformItems[item.itemid]) + item:decay() + return true +end + +for index, value in pairs(transformItems) do + transformTo:id(index) +end + +transformTo:register() diff --git a/data/scripts/actions/other/trap.lua b/data/scripts/actions/other/trap.lua new file mode 100644 index 00000000000..844238944ec --- /dev/null +++ b/data/scripts/actions/other/trap.lua @@ -0,0 +1,10 @@ +local trap = Action() + +function trap.onUse(player, item, fromPosition, target, toPosition, isHotkey) + item:transform(item.itemid - 1) + fromPosition:sendMagicEffect(CONST_ME_POFF) + return true +end + +trap:id(2579) +trap:register() diff --git a/data/scripts/actions/other/unrealized_dream.lua b/data/scripts/actions/other/unrealized_dream.lua new file mode 100644 index 00000000000..0871ffedbdd --- /dev/null +++ b/data/scripts/actions/other/unrealized_dream.lua @@ -0,0 +1,124 @@ +local unrealizedDream = Action() + +function unrealizedDream.onUse(cid, item, frompos, item2, topos) + +presente = math.random(1,22) +pos = getPlayerPosition(cid) + +--surpriese bag-- +if presente == 1 then +doSendMagicEffect(pos,26) +doPlayerAddItem(cid,13537,1) -- Bag of Apple Slices +doRemoveItem(item.uid,1) + +elseif presente == 2 then +doSendMagicEffect(pos,26) +doPlayerAddItem(cid,22609,1) -- Dream Warden Claw +doRemoveItem(item.uid,1) + +elseif presente == 3 then +doSendMagicEffect(pos,26) +doPlayerAddItem(cid,2355,1) -- Stuffed Bunny +doRemoveItem(item.uid,1) + +elseif presente == 4 then +doSendMagicEffect(pos,26) +doPlayerAddItem(cid,5929,1) -- Goldfish Bowl +doRemoveItem(item.uid,1) + +elseif presente == 5 then +doSendMagicEffect(pos,26) +doPlayerAddItem(cid,5792,1) -- Dice +doRemoveItem(item.uid,1) + +elseif presente == 6 then +doSendMagicEffect(pos,26) +doPlayerAddItem(cid,2666,1) -- Meat +doRemoveItem(item.uid,1) + +elseif presente == 7 then +doSendMagicEffect(pos,26) +doPlayerAddItem(cid,2121,1) -- Wedding Ring +doRemoveItem(item.uid,1) + +elseif presente == 8 then +doSendMagicEffect(pos,26) +doPlayerAddItem(cid,2560,1) -- Mirror +doRemoveItem(item.uid,1) + +elseif presente == 9 then +doSendMagicEffect(pos,26) +doPlayerAddItem(cid,7459,1) -- Pair of Earmuffs +doRemoveItem(item.uid,1) + +elseif presente == 10 then +doSendMagicEffect(pos,26) +doPlayerAddItem(cid,2111,1) -- Snowball +doRemoveItem(item.uid,1) + +elseif presente == 11 then +doSendMagicEffect(pos,26) +doPlayerAddItem(cid,2223,1) -- Rubbish +doRemoveItem(item.uid,1) + +elseif presente == 12 then +doSendMagicEffect(pos,26) +doPlayerAddItem(cid,2114,1) -- Piggy Bank +doRemoveItem(item.uid,1) + +elseif presente == 13 then +doSendMagicEffect(pos,26) +doPlayerAddItem(cid,2657,1) -- Simple Dress +doRemoveItem(item.uid,1) + +elseif presente == 14 then +doSendMagicEffect(pos,26) +doPlayerAddItem(cid,1990,1) -- Present +doRemoveItem(item.uid,1) + +elseif presente == 15 then +doSendMagicEffect(pos,26) +doPlayerAddItem(cid,2745,1) -- Blue Rose +doRemoveItem(item.uid,1) + +elseif presente == 16 then +doSendMagicEffect(pos,26) +doPlayerAddItem(cid,2072,1) -- Lute +doRemoveItem(item.uid,1) + +elseif presente == 17 then +doSendMagicEffect(pos,26) +doPlayerAddItem(cid,22606,1) -- Bronze Prison Key +doRemoveItem(item.uid,1) + +elseif presente == 18 then +doSendMagicEffect(pos,26) +doPlayerAddItem(cid,22604,1) -- Silver Prison Key +doRemoveItem(item.uid,1) + +elseif presente == 19 then +doSendMagicEffect(pos,26) +doPlayerAddItem(cid,22607,1) -- Golden Prison Key +doRemoveItem(item.uid,1) + +elseif presente == 20 then +doSendMagicEffect(pos,26) +doPlayerAddItem(cid,22396,1) -- Cluster of Solace +doRemoveItem(item.uid,1) + +elseif presente == 21 then +doSendMagicEffect(pos,26) +doPlayerAddItem(cid,7735,1) -- Spellwand +doRemoveItem(item.uid,1) + +elseif presente == 22 then +doSendMagicEffect(pos,26) +doPlayerAddItem(cid,22605,1) -- Copper Prision Key +doRemoveItem(item.uid,1) +end + +return 1 +end + +unrealizedDream:id(22598) +unrealizedDream:register() diff --git a/data/scripts/actions/other/ursagrodon.lua b/data/scripts/actions/other/ursagrodon.lua new file mode 100644 index 00000000000..07244b60ba4 --- /dev/null +++ b/data/scripts/actions/other/ursagrodon.lua @@ -0,0 +1,57 @@ +local config = { + item1 = 22729, + item2 = 22730, + item3 = 22731, + item4 = 22732, + porcentagem = 30, +} + +local function revertIce(toPosition) + local tile = toPosition:getTile() + if tile then + local thing = tile:getItemById(config.item4) + if thing then + thing:transform(config.item1) + end + end +end + +local ursagrodon = Action() + +function ursagrodon.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local rand = math.random(1, 100) + + if target.itemid == config.item1 or target.itemid == config.item2 or target.itemid == config.item3 then + + if player:getStorageValue(config.item4) > 0 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You already have the obedience of ursagrodon.') + return true + end + + if rand <= config.porcentagem then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The ice cracked and the frozen creature with it - be more careful next time!') + item:remove(1) + target:transform(config.item4) + addEvent(revertIce, 600000, toPosition) + else + if target.itemid == config.item1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You managed to melt about half of the ice blook. Quickly now, it\'s ice cold here and the ice block could freeze over again.') + target:transform(config.item2) + elseif target.itemid == config.item2 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You managed to melt almost the whole block, only the feet of the creature are still stuck in the ice. Finish the job!') + target:transform(config.item3) + elseif target.itemid == config.item3 then + target:transform(config.item4) + item:remove(1) + player:addMount(38) + player:setStorageValue(config.item4, 1) + addEvent(revertIce, 600 * 1000, toPosition) + return player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The freed ursagrodon look at you with glowing, obedient eyes.') + end + end + end + return true +end + +ursagrodon:id(22726) +ursagrodon:register() diff --git a/data/scripts/actions/other/voodoo_doll.lua b/data/scripts/actions/other/voodoo_doll.lua new file mode 100644 index 00000000000..1132ede1b2e --- /dev/null +++ b/data/scripts/actions/other/voodoo_doll.lua @@ -0,0 +1,21 @@ +local voodooDoll = Action() + +function voodooDoll.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid ~= 1 or target.type ~= THING_TYPE_PLAYER then + return false + end + + local text = "" + if math.random(100) <= 5 then + text = "You concentrate on your victim and hit the needle in the doll." + player:addAchievement("Dark Voodoo Priest") + toPosition:sendMagicEffect(CONST_ME_DRAWBLOOD, player) + else + text = "You concentrate on your victim, hit the needle in the doll.......but nothing happens." + end + player:say(text, TALKTYPE_MONSTER_SAY, false, player) + return true +end + +voodooDoll:id(3955) +voodooDoll:register() diff --git a/data/scripts/actions/other/watch.lua b/data/scripts/actions/other/watch.lua new file mode 100644 index 00000000000..c16f9531ab7 --- /dev/null +++ b/data/scripts/actions/other/watch.lua @@ -0,0 +1,9 @@ +local watch = Action() + +function watch.onUse(player, item, fromPosition, target, toPosition, isHotkey) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The time is " .. getFormattedWorldTime() .. ".") + return true +end + +watch:id(1728, 1729, 1730, 1731, 2036, 3900) +watch:register() diff --git a/data/scripts/actions/other/windows.lua b/data/scripts/actions/other/windows.lua new file mode 100644 index 00000000000..e1163e12d30 --- /dev/null +++ b/data/scripts/actions/other/windows.lua @@ -0,0 +1,55 @@ + +local windowId = {} +for index, value in ipairs(windowTable) do + if not table.contains(windowId, value.openWindow) then + table.insert(windowId, value.openWindow) + end + + if not table.contains(windowId, value.closedWindow) then + table.insert(windowId, value.closedWindow) + end +end + +local windows = Action() + +function windows.onUse(player, item, fromPosition, target, toPosition, isHotkey) + for index, value in ipairs(windowTable) do + if value.closedWindow == item.itemid then + item:transform(value.openWindow) + return true + end + end + + local tile = fromPosition:getTile() + local house = tile and tile:getHouse() + if not house then + fromPosition.y = fromPosition.y - 1 + tile = fromPosition:getTile() + house = tile and tile:getHouse() + if not house then + fromPosition.y = fromPosition.y + 1 + fromPosition.x = fromPosition.x - 1 + tile = fromPosition:getTile() + house = tile and tile:getHouse() + end + end + + if house then + if player:getPosition():getTile():getHouse() ~= house and player:getAccountType() < ACCOUNT_TYPE_GAMEMASTER then + return false + end + end + + for index, value in ipairs(windowTable) do + if value.openWindow == item.itemid then + item:transform(value.closedWindow) + end + end + return true +end + +for index, value in ipairs(windowId) do + windows:id(value) +end + +windows:register() diff --git a/data/scripts/actions/quests/adventurers_guild/treasure.lua b/data/scripts/actions/quests/adventurers_guild/treasure.lua new file mode 100644 index 00000000000..e4955316a50 --- /dev/null +++ b/data/scripts/actions/quests/adventurers_guild/treasure.lua @@ -0,0 +1,49 @@ +local items = { + { description = 'a platinum coins', items = {{ id = ITEM_PLATINUM_COIN, count = 5 }}}, + { description = 'some gems', items = { + { id = 2146, count = 1 }, + { id = 2149, count = 1 }, + { id = 2147, count = 1 } + }}, + { description = 'a life ring', items = {{ id = 2205, count = 1 }} }, + { description = 'a red gem', items = {{ id = 2156, count = 1 }} }, + { description = 'a mana potion', items = {{ id = 7589, count = 10 }} }, + { description = 'a health potion', items = {{ id = 7588, count = 8 }} } +} + +local adventurersTreasure = Action() +function adventurersTreasure.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.AdventurersGuild.GreatDragonHunt.DragonCounter) >= 50 then + local treasure = items[math.random(#items)] + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "It is impossible to take along all of the treasures here. Buy you pick out " .. treasure.description) + for _, item in ipairs(treasure.items) do + player:addItem(item.id, item.count) + end + + -- reset dragon counter + player:setStorageValue(Storage.AdventurersGuild.GreatDragonHunt.DragonCounter, 0) + + -- hoard of the dragon achievement + local achievement = getAchievementInfoByName('Hoard of the Dragon') + if not achievement or player:hasAchievement(achievement.id) then + return true + end + + local times = player:getStorageValue(achievement.actionStorage) + if times < 10 then + player:setStorageValue(achievement.actionStorage, times + 1) + end + + if times + 1 == 10 then + player:addAchievement(achievement.id) + end + + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You try to pick a treasure, but you hear further dragons approaching. You should kill some more before picking out something.") + end + + return true +end + +adventurersTreasure:aid(50808) +adventurersTreasure:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/adventurers_guild/warrior_skeleton.lua b/data/scripts/actions/quests/adventurers_guild/warrior_skeleton.lua new file mode 100644 index 00000000000..ff47e0561a2 --- /dev/null +++ b/data/scripts/actions/quests/adventurers_guild/warrior_skeleton.lua @@ -0,0 +1,16 @@ +local adventurersWarriorSkeleton = Action() +function adventurersWarriorSkeleton.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.AdventurersGuild.GreatDragonHunt.WarriorSkeleton) < 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have discovered a deceased warrior's skeleton. It seems he tried to hunt the dragons around here - and failed.") + player:addItem(5882, 1) -- red dragon scale + player:setStorageValue(Storage.AdventurersGuild.GreatDragonHunt.WarriorSkeleton, 1) + player:setStorageValue(Storage.AdventurersGuild.GreatDragonHunt.DragonCounter, 0) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The dead explorer is empty.") + end + + return true +end + +adventurersWarriorSkeleton:aid(50806) +adventurersWarriorSkeleton:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/barbarian_test/horn.lua b/data/scripts/actions/quests/barbarian_test/horn.lua new file mode 100644 index 00000000000..9afca96bcfa --- /dev/null +++ b/data/scripts/actions/quests/barbarian_test/horn.lua @@ -0,0 +1,50 @@ +local function sendSleepEffect(position) + position:sendMagicEffect(CONST_ME_SLEEP) +end + +local barbarianHorn = Action() +function barbarianHorn.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.uid == 3110 and item.itemid == 7140 then + player:say('You fill your horn with ale.', TALKTYPE_MONSTER_SAY) + item:transform(7141) + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + elseif target.itemid == 7174 and item.itemid == 7141 then + player:say('The bear is now unconcious.', TALKTYPE_MONSTER_SAY) + item:transform(7140) + target:transform(7175) + toPosition:sendMagicEffect(CONST_ME_STUN) + elseif item.itemid == 7175 then + if player:getStorageValue(Storage.BarbarianTest.Questline) == 4 then + player:say('You hug the unconcious bear.', TALKTYPE_MONSTER_SAY) + player:setStorageValue(Storage.BarbarianTest.Questline, 5) + player:setStorageValue(Storage.BarbarianTest.Mission02, 2) -- Questlog Barbarian Test Quest Barbarian Test 2: The Bear Hugging + player:addAchievement('Bearhugger') + item:transform(7174) + toPosition:sendMagicEffect(CONST_ME_SLEEP) + else + player:say('You don\'t feel like hugging an unconcious bear.', TALKTYPE_MONSTER_SAY) + end + elseif item.itemid == 7174 then + player:say('Grr.', TALKTYPE_MONSTER_SAY) + player:say('The bear is not amused by the disturbance.', TALKTYPE_MONSTER_SAY) + doAreaCombatHealth(player, COMBAT_PHYSICALDAMAGE, player:getPosition(), 0, -10, -30, CONST_ME_POFF) + elseif item.itemid == 7176 then + if player:getStorageValue(Storage.BarbarianTest.Questline) == 6 then + if player:getCondition(CONDITION_DRUNK) then + player:say('You hustle the mammoth. What a fun. *hicks*.', TALKTYPE_MONSTER_SAY) + player:setStorageValue(Storage.BarbarianTest.Questline, 7) + player:setStorageValue(Storage.BarbarianTest.Mission03, 2) -- Questlog Barbarian Test Quest Barbarian Test 3: The Mammoth Pushing + item:transform(7177) + item:decay() + addEvent(sendSleepEffect, 60 * 1000, toPosition) + toPosition:sendMagicEffect(CONST_ME_SLEEP) + else + player:say('You are not drunk enought to hustle a mammoth.', TALKTYPE_MONSTER_SAY) + end + end + end + return true +end + +barbarianHorn:id(7140,7141,7174,7175,7176) +barbarianHorn:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/barbarian_test/mead.lua b/data/scripts/actions/quests/barbarian_test/mead.lua new file mode 100644 index 00000000000..40458de7018 --- /dev/null +++ b/data/scripts/actions/quests/barbarian_test/mead.lua @@ -0,0 +1,29 @@ +local barbarianMead = Action() +function barbarianMead.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.BarbarianTest.Questline) == 2 and player:getStorageValue(Storage.BarbarianTest.MeadTotalSips) <= 20 then + if math.random(5) > 1 then + player:say('The world seems to spin but you manage to stay on your feet.', TALKTYPE_MONSTER_SAY) + player:setStorageValue(Storage.BarbarianTest.MeadSuccessSips, player:getStorageValue(Storage.BarbarianTest.MeadSuccessSips) + 1) + if player:getStorageValue(Storage.BarbarianTest.MeadSuccessSips) == 9 then -- 9 sips here cause local player at start + player:say('10 sips in a row. Yeah!', TALKTYPE_MONSTER_SAY) + player:setStorageValue(Storage.BarbarianTest.Questline, 3) + player:setStorageValue(Storage.BarbarianTest.Mission01, 3) -- Questlog Barbarian Test Quest Barbarian Test 1: Barbarian Booze + return true + end + else + player:say('The mead was too strong. You passed out for a moment.', TALKTYPE_MONSTER_SAY) + player:setStorageValue(Storage.BarbarianTest.MeadSuccessSips, 0) + end + player:setStorageValue(Storage.BarbarianTest.MeadTotalSips, player:getStorageValue(Storage.BarbarianTest.MeadTotalSips) + 1) + elseif player:getStorageValue(Storage.BarbarianTest.MeadTotalSips) > 20 then + player:say('Ask Sven for another round.', TALKTYPE_MONSTER_SAY) + player:setStorageValue(Storage.BarbarianTest.Questline, 1) + player:setStorageValue(Storage.BarbarianTest.Mission01, 1) -- Questlog Barbarian Test Quest Barbarian Test 1: Barbarian Booze + elseif player:getStorageValue(Storage.BarbarianTest.Questline) >= 3 then + player:say('You already passed the test, no need to torture yourself anymore.', TALKTYPE_MONSTER_SAY) + end + return true +end + +barbarianMead:uid(3110) +barbarianMead:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/bigfoot_burden/beer.lua b/data/scripts/actions/quests/bigfoot_burden/beer.lua new file mode 100644 index 00000000000..2849c3e8c04 --- /dev/null +++ b/data/scripts/actions/quests/bigfoot_burden/beer.lua @@ -0,0 +1,14 @@ +local bigfootBeer = Action() +function bigfootBeer.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.BigfootBurden.NeedsBeer) == 1 then + player:setStorageValue(Storage.BigfootBurden.NeedsBeer, 0) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Your mind feels refreshed!') + end + + player:say("Gulp!", TALKTYPE_MONSTER_SAY) + item:remove(1) + return true +end + +bigfootBeer:id(18305) +bigfootBeer:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/bigfoot_burden/crystal.lua b/data/scripts/actions/quests/bigfoot_burden/crystal.lua new file mode 100644 index 00000000000..bc0ad075251 --- /dev/null +++ b/data/scripts/actions/quests/bigfoot_burden/crystal.lua @@ -0,0 +1,28 @@ +local function returnCrystal(position, id) + local tile = Tile(position):getItemById(18311) + if tile then + tile:transform(id) + end +end + +local bigfootCrystal = Action() +function bigfootCrystal.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local repairedCount = player:getStorageValue(Storage.BigfootBurden.RepairedCrystalCount) + if repairedCount == 5 or player:getStorageValue(Storage.BigfootBurden.MissionCrystalKeeper) ~= 1 then + return false + end + + if target.itemid == 18307 or target.itemid == 18228 then + player:setStorageValue(Storage.BigfootBurden.RepairedCrystalCount, repairedCount + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have repaired a damaged crystal!') + addEvent(returnCrystal, math.random(50, 140) * 1000, toPosition, target.itemid) + target:transform(18311) + toPosition:sendMagicEffect(CONST_ME_ENERGYAREA) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'This is no damaged crystal!') + end + return true +end + +bigfootCrystal:id(18219) +bigfootCrystal:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/bigfoot_burden/extractor.lua b/data/scripts/actions/quests/bigfoot_burden/extractor.lua new file mode 100644 index 00000000000..d2cc84282e4 --- /dev/null +++ b/data/scripts/actions/quests/bigfoot_burden/extractor.lua @@ -0,0 +1,26 @@ +local bigfootExtractor = Action() +function bigfootExtractor.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local extractedCount = player:getStorageValue(Storage.BigfootBurden.ExtractedCount) + if extractedCount == 7 + or player:getStorageValue(Storage.BigfootBurden.MissionRaidersOfTheLostSpark) ~= 1 then + return false + end + + if target.itemid == 18487 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "This body is not ready yet.") + return true + end + + if target.itemid ~= 18484 then + return false + end + + player:setStorageValue(Storage.BigfootBurden.ExtractedCount, math.max(0, extractedCount) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You gathered a spark.') + target:transform(18485) + toPosition:sendMagicEffect(CONST_ME_ENERGYHIT) + return true +end + +bigfootExtractor:id(18213) +bigfootExtractor:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/bigfoot_burden/matchmaker.lua b/data/scripts/actions/quests/bigfoot_burden/matchmaker.lua new file mode 100644 index 00000000000..970ba2120af --- /dev/null +++ b/data/scripts/actions/quests/bigfoot_burden/matchmaker.lua @@ -0,0 +1,24 @@ +local bigfootMatch = Action() +function bigfootMatch.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid < 18320 and target.itemid > 18326 then + return false + end + + if player:getStorageValue(Storage.BigfootBurden.MatchmakerStatus) == 1 or player:getStorageValue(Storage.BigfootBurden.MissionMatchmaker) ~= 1 then + return false + end + + if player:getStorageValue(Storage.BigfootBurden.MatchmakerIdNeeded) ~= target.itemid then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'This is not the crystal you\'re looking for!') + return true + end + + player:setStorageValue(Storage.BigfootBurden.MatchmakerStatus, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Congratulations! The crystals seem to have fallen in love and your mission is done!') + toPosition:sendMagicEffect(CONST_ME_HEARTS) + item:remove() + return true +end + +bigfootMatch:id(18312) +bigfootMatch:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/bigfoot_burden/mouthpiece.lua b/data/scripts/actions/quests/bigfoot_burden/mouthpiece.lua new file mode 100644 index 00000000000..7a8eb4b19a9 --- /dev/null +++ b/data/scripts/actions/quests/bigfoot_burden/mouthpiece.lua @@ -0,0 +1,13 @@ +local bigfootPiece = Action() +function bigfootPiece.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.BigfootBurden.Mouthpiece) ~= os.time() then + player:addItem(22391, 1) + player:setStorageValue(Storage.BigfootBurden.Mouthpiece, os.time() + 20 * 60 * 60) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "It is empty.") + end + return true +end + +bigfootPiece:uid(9307) +bigfootPiece:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/bigfoot_burden/mushroom.lua b/data/scripts/actions/quests/bigfoot_burden/mushroom.lua new file mode 100644 index 00000000000..11c3eecc31b --- /dev/null +++ b/data/scripts/actions/quests/bigfoot_burden/mushroom.lua @@ -0,0 +1,25 @@ +local function revertAid(position) + local mushroom = Tile(position):getItemById(18220) + if mushroom then + mushroom:removeAttribute(ITEM_ATTRIBUTE_ACTIONID) + end +end + +local bigfootMushroom = Action() +function bigfootMushroom.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item:hasAttribute(ITEM_ATTRIBUTE_ACTIONID) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have to wait to extract spores from this mushroom.") + return true + end + + local spore = Game.createItem(math.random(18221, 18224), 1, toPosition) + if spore then + spore:decay() + item:setActionId(100) + addEvent(revertAid, math.random(2,4) * 60 * 1000, toPosition) + end + return true +end + +bigfootMushroom:id(18220) +bigfootMushroom:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/bigfoot_burden/music.lua b/data/scripts/actions/quests/bigfoot_burden/music.lua new file mode 100644 index 00000000000..c27a197b784 --- /dev/null +++ b/data/scripts/actions/quests/bigfoot_burden/music.lua @@ -0,0 +1,34 @@ +local cToneStorages = { + Storage.BigfootBurden.MelodyTone1, + Storage.BigfootBurden.MelodyTone2, + Storage.BigfootBurden.MelodyTone3, + Storage.BigfootBurden.MelodyTone4, + Storage.BigfootBurden.MelodyTone5, + Storage.BigfootBurden.MelodyTone6, + Storage.BigfootBurden.MelodyTone7 +} + +local bigfootMusic = Action() +function bigfootMusic.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.BigfootBurden.QuestLine) == 21 then + local value = player:getStorageValue(Storage.BigfootBurden.MelodyStatus) + if player:getStorageValue(cToneStorages[value]) == item.uid then + player:setStorageValue(Storage.BigfootBurden.MelodyStatus, value + 1) + if value + 1 == 8 then + toPosition:sendMagicEffect(CONST_ME_HEARTS) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "That was the correct note! Now you know your soul melody!") + player:setStorageValue(Storage.BigfootBurden.QuestLine, 22) + else + toPosition:sendMagicEffect(CONST_ME_SOUND_GREEN) + player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_YELLOW) + end + else + player:setStorageValue(Storage.BigfootBurden.MelodyStatus, 1) + toPosition:sendMagicEffect(CONST_ME_SOUND_RED) + end + end + return true +end + +bigfootMusic:uid(3124,3125,3126,3127) +bigfootMusic:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/bigfoot_burden/package.lua b/data/scripts/actions/quests/bigfoot_burden/package.lua new file mode 100644 index 00000000000..a13a402083e --- /dev/null +++ b/data/scripts/actions/quests/bigfoot_burden/package.lua @@ -0,0 +1,8 @@ +local bigfootPackage = Action() +function bigfootPackage.onUse(player, item, fromPosition, target, toPosition, isHotkey) + item:transform(item.itemid - 1) + return true +end + +bigfootPackage:id(18313) +bigfootPackage:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/bigfoot_burden/pig.lua b/data/scripts/actions/quests/bigfoot_burden/pig.lua new file mode 100644 index 00000000000..3f564352044 --- /dev/null +++ b/data/scripts/actions/quests/bigfoot_burden/pig.lua @@ -0,0 +1,25 @@ +local bigfootPig = Action() +function bigfootPig.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid ~= 18341 then + return false + end + + local mushroomCount = player:getStorageValue(Storage.BigfootBurden.MushroomCount) + if player:getStorageValue(Storage.BigfootBurden.MissionMushroomDigger) ~= 1 then + return false + end + + if mushroomCount == 3 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The little pig is stuffed and you better return it home.") + return true + end + + player:setStorageValue(Storage.BigfootBurden.MushroomCount, mushroomCount + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The little pig happily eats the truffles.') + target:transform(18218) + toPosition:sendMagicEffect(CONST_ME_GROUNDSHAKER) + return true +end + +bigfootPig:id(18339) +bigfootPig:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/bigfoot_burden/repair.lua b/data/scripts/actions/quests/bigfoot_burden/repair.lua new file mode 100644 index 00000000000..7687df706ca --- /dev/null +++ b/data/scripts/actions/quests/bigfoot_burden/repair.lua @@ -0,0 +1,29 @@ +local bigfootRepair = Action() +function bigfootRepair.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if not target:isMonster() then + return false + end + + if target:getName():lower() ~= 'damaged crystal golem' then + return false + end + + if player:getStorageValue(Storage.BigfootBurden.MissionTinkersBell) ~= 1 then + return false + end + + if player:getStorageValue(Storage.BigfootBurden.GolemCount) >= 4 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have returned enough golems for now. Give the gnomes some time for their repairs. Report back now.") + return true + end + + player:setStorageValue(Storage.BigfootBurden.GolemCount, player:getStorageValue(Storage.BigfootBurden.GolemCount) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The golem has been returned to the gnomish workshop.') + target:remove() + player:getPosition():sendMagicEffect(CONST_ME_ENERGYHIT) + + return true +end + +bigfootRepair:id(18343) +bigfootRepair:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/bigfoot_burden/rewards.lua b/data/scripts/actions/quests/bigfoot_burden/rewards.lua new file mode 100644 index 00000000000..6e8a8d8590c --- /dev/null +++ b/data/scripts/actions/quests/bigfoot_burden/rewards.lua @@ -0,0 +1,97 @@ +local rewards = { + [3148] = { + storage = Storage.BigfootBurden.Warzone1Reward, + bossName = 'Deathstrike', + items = { + {rand = true, itemId = {18396, 18501, 18502, 18503}}, + {itemId = 18402, count = 750}, + {itemId = 18396}, + {itemId = 2160, count = 3}, + {itemId = 18415, count = 7}, + {itemId = 18423, count = 2} + }, + achievement = {'Final Strike', 'Death on Strike'} + }, + [3149] = { + storage = Storage.BigfootBurden.Warzone2Reward, + bossName = 'Gnomevil', + items = { + {rand = true, itemId = {18505, 18506, 18507}}, + {itemId = 18407, count = 750}, + {itemId = 18396}, + {itemId = 2160, count = 4}, + {itemId = 18413, count = 10}, + {itemId = 18423, count = 2} + }, + miniatureHouse = true, + achievement = {'Gnomebane\'s Bane', 'Fall of the Fallen'} + }, + [3150] = { + storage = Storage.BigfootBurden.Warzone3Reward, + bossName = 'Abyssador', + items = { + {rand = true, itemId = {18497, 18498, 18499}}, + {itemId = 18408}, + {itemId = 18396}, + {itemId = 2160, count = 5}, + {itemId = 18414, count = 12}, + {itemId = 18423, count = 2} + }, + achievement = {'Death from Below', 'Diplomatic Immunity'} + } +} + +local bigfootRewards = Action() +function bigfootRewards.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.uid == 3147 then + if player:getStorageValue(Storage.BigfootBurden.WarzoneStatus) == 4 then + player:setStorageValue(Storage.BigfootBurden.WarzoneStatus, 5) + player:addItem(2137, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have found some golden fruits.') + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The chest is empty.') + end + elseif item.uid > 3147 and item.uid < 3151 then + local reward = rewards[item.uid] + if not reward then + return false + end + + if player:getStorageValue(reward.storage) ~= 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, reward.bossName .. ' defends his belongings and will not let you open his chest.') + return true + end + + local backpack = player:getSlotItem(CONST_SLOT_BACKPACK) + if backpack and backpack:getEmptySlots(false) < 5 + or player:getFreeCapacity() < 100 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Please make sure that you have at least 5 free inventory slots and that you can carry on additional 100 oz.') + return true + end + + for i = 1, #reward.items do + local items = reward.items[i] + if items.rand then + if math.random(10) == 1 then + player:addItem(items.itemId[math.random(#items.itemId)], 1) + end + else + player:addItem(items.itemId, items.count or 1) + end + end + + if reward.miniatureHouse then + if math.random(25) == 1 then + player:addItem(16619, 1) + end + end + + player:setStorageValue(reward.storage, 0) + player:addAchievement(reward.achievement[1]) + player:addAchievementProgress(reward.achievement[2], 50) + end + return true +end + +bigfootRewards:uid(3147,3148,3149,3150) +bigfootRewards:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/bigfoot_burden/shooting.lua b/data/scripts/actions/quests/bigfoot_burden/shooting.lua new file mode 100644 index 00000000000..d7392c79b91 --- /dev/null +++ b/data/scripts/actions/quests/bigfoot_burden/shooting.lua @@ -0,0 +1,34 @@ +local bigfootShooting = Action() +function bigfootShooting.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local playerPos = player:getPosition() + if player:getStorageValue(Storage.BigfootBurden.Shooting) < 5 then + local pos = Position(playerPos.x, playerPos.y - 5, 10) + local tile = Tile(pos) + if tile:getItemById(18226) then + player:setStorageValue(Storage.BigfootBurden.Shooting, player:getStorageValue(Storage.BigfootBurden.Shooting) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Hit!") + tile:getItemById(18226):remove() + pos:sendMagicEffect(CONST_ME_FIREATTACK) + for i = 2, 4 do + Position(playerPos.x, playerPos.y - i, 10):sendMagicEffect(CONST_ME_TELEPORT) + end + if player:getStorageValue(Storage.BigfootBurden.Shooting) >= 5 then + player:setStorageValue(Storage.BigfootBurden.QuestLine, 14) + end + elseif tile:getItemById(18227) then + player:setStorageValue(Storage.BigfootBurden.Shooting, 0) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You've hit the wrong target and have to start all over!") + tile:getItemById(18227):remove() + pos:sendMagicEffect(CONST_ME_FIREATTACK) + for i = 2, 4 do + Position(playerPos.x, playerPos.y - i, 10):sendMagicEffect(CONST_ME_TELEPORT) + end + end + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have hit enough targets. Report back!") + end + return true +end + +bigfootShooting:id(18225) +bigfootShooting:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/bigfoot_burden/spores.lua b/data/scripts/actions/quests/bigfoot_burden/spores.lua new file mode 100644 index 00000000000..359a1c069c0 --- /dev/null +++ b/data/scripts/actions/quests/bigfoot_burden/spores.lua @@ -0,0 +1,36 @@ +local config = { + [18328] = 18221, + [18329] = 18222, + [18330] = 18223, + [18331] = 18224 +} + +local bigfootSpores = Action() +function bigfootSpores.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local spores = config[item.itemid] + if not spores then + return false + end + + local sporeCount = player:getStorageValue(Storage.BigfootBurden.SporeCount) + if sporeCount == 4 or player:getStorageValue(Storage.BigfootBurden.MissionSporeGathering) ~= 1 then + return false + end + + if target.itemid ~= spores then + player:setStorageValue(Storage.BigfootBurden.SporeCount, 0) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have gathered the wrong spores. You ruined your collection.') + item:transform(18328) + toPosition:sendMagicEffect(CONST_ME_POFF) + return true + end + + player:setStorageValue(Storage.BigfootBurden.SporeCount, sporeCount + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have gathered the correct spores.') + item:transform(item.itemid + 1) + toPosition:sendMagicEffect(CONST_ME_GREEN_RINGS) + return true +end + +bigfootSpores:id(18328,18329,18330,18331) +bigfootSpores:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/bigfoot_burden/stone.lua b/data/scripts/actions/quests/bigfoot_burden/stone.lua new file mode 100644 index 00000000000..f6bc32078de --- /dev/null +++ b/data/scripts/actions/quests/bigfoot_burden/stone.lua @@ -0,0 +1,22 @@ +local bigfootStone = Action() +function bigfootStone.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.BigfootBurden.GrindstoneStatus) == 1 or player:getStorageValue(Storage.BigfootBurden.MissionGrindstoneHunt) ~= 1 then + return false + end + + toPosition:sendMagicEffect(CONST_ME_HITBYFIRE) + item:transform(18335) + + if math.random(15) <= 12 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You had no luck this time.') + return true + end + + player:setStorageValue(Storage.BigfootBurden.GrindstoneStatus, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Your skill allowed you to grab a whetstone before the stone sinks into lava.') + player:addItem(18337, 1) + return true +end + +bigfootStone:id(18336) +bigfootStone:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/bigfoot_burden/warzone1_crystal.lua b/data/scripts/actions/quests/bigfoot_burden/warzone1_crystal.lua new file mode 100644 index 00000000000..b8ccf0aaf7c --- /dev/null +++ b/data/scripts/actions/quests/bigfoot_burden/warzone1_crystal.lua @@ -0,0 +1,59 @@ +local posdotp = Position(33104, 31908, 10) + +local creatures = { + "humongous fungus", + "hideous fungus" +} + +local function removeTp() + local t = Tile(posdotp):getItemById(1387) + if t then + t:remove() + Game.createItem(17999,1,posdotp)-- Stone pos + posdotp:sendMagicEffect(CONST_ME_POFF) + end +end + +local function magicEffectWz(pos, cons) + pos:sendMagicEffect(cons) +end + +local function createTp() + local cristal = Tile(posdotp):getItemById(17999) + if cristal then + cristal:remove() + local tp = Game.createItem(1387, 1, posdotp) + if tp then + tp:setActionId(45700) + end + end + return true +end + +local bigfootWarzoneCrystal = Action() +function bigfootWarzoneCrystal.onUse(player, item, fromPosition, itemEx, toPosition, isHotkey) + local config = warzoneConfig.findByName("Deathstrike") + if Game.getStorageValue(96974) < 1 then + Game.setStorageValue(96974, 1) + for i = 1, 10 do + for k = 1, 6 do + pos = Position(math.random(33094, 33101), math.random(31900, 31916), 10) + addEvent(Game.createMonster, i * 20 * 1000, creatures[math.random(1,2)], pos) + addEvent(magicEffectWz, i * 20 * 1000, pos, CONST_ME_TELEPORT) + end + end + + player:say("The crystals are charging!", TALKTYPE_MONSTER_SAY, false, player, toPosition) + addEvent(createTp, 200000) -- 3.33 min + addEvent(removeTp, 260000) -- 4.33 min + addEvent(warzoneConfig.spawnBoss, 280000, config.boss, config.bossResp) -- 5 min + addEvent(warzoneConfig.resetRoom, 30 * 60 * 1000, config, "You were teleported out by the gnomish emergency device.", true) + addEvent(Game.setStorageValue, 30 * 60 * 1000, 96974, 0) + else + doPlayerSendCancel(player, "Wait 30 minutes to start again.") + end + return true +end + +bigfootWarzoneCrystal:uid(3143) +bigfootWarzoneCrystal:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/chayenne_realm/lever.lua b/data/scripts/actions/quests/chayenne_realm/lever.lua new file mode 100644 index 00000000000..91b4c3ef947 --- /dev/null +++ b/data/scripts/actions/quests/chayenne_realm/lever.lua @@ -0,0 +1,22 @@ +local chayenneLever = Action() +function chayenneLever.onUse(cid, item, fromPosition, itemEx, toPosition) + if item.itemid == 1945 then + if getGlobalStorageValue(71543) <= os.time() then + if getPlayerItemCount(cid, 16015) >= 1 then + doTransformItem(getTileItemById({x = 33080, y = 32582, z = 3},1945).uid,1946) + doRemoveItem(getTileItemById({x = 33075, y = 32591, z = 3}, 1498).uid, 1) + setGlobalStorageValue(71543, os.time()+5*60) + addEvent(Game.createItem, 60*1000, 1498, {x = 33075, y = 32591, z = 3}) + else + doPlayerSendTextMessage(cid, 19, "You do not have the Chayenne's magical key.") + end + else + doPlayerSendTextMessage(cid, 19, "You need to wait few minutes to use again.") + end + elseif item.itemid == 1946 then + doTransformItem(getTileItemById({x = 33080, y = 32582, z = 3},1946).uid,1945) + end +end + +chayenneLever:aid(55021) +chayenneLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/chayenne_realm/reward.lua b/data/scripts/actions/quests/chayenne_realm/reward.lua new file mode 100644 index 00000000000..d8d3ac264fc --- /dev/null +++ b/data/scripts/actions/quests/chayenne_realm/reward.lua @@ -0,0 +1,22 @@ +local chayenneReward = Action() +function chayenneReward.onUse(player, item, fromPosition, itemEx, toPosition) + if player:getStorageValue(Storage.ChayenneReward) < 1 then + local backpack = player:addItem(5949, 1) + backpack:addItem(18511, 1) + backpack:addItem(2745, 1) + backpack:addItem(9948, 1) + backpack:addItem(2144, 1) + backpack:addItem(5882, 1) + backpack:addItem(5791, 1) + backpack:addItem(2114, 1) + backpack:addItem(6570, 1) + player:setStorageValue(Storage.ChayenneReward, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a beach backpack.") + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You already got your reward.") + end + return true +end + +chayenneReward:aid(55023) +chayenneReward:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/children_of_the_revolution/mission3_chest.lua b/data/scripts/actions/quests/children_of_the_revolution/mission3_chest.lua new file mode 100644 index 00000000000..a7ea91e8d7a --- /dev/null +++ b/data/scripts/actions/quests/children_of_the_revolution/mission3_chest.lua @@ -0,0 +1,18 @@ +local childrenMission3 = Action() +function childrenMission3.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.ChildrenoftheRevolution.Questline) == 9 then + player:setStorageValue(Storage.ChildrenoftheRevolution.Questline, 10) + player:addItem(10760, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a flask of poison.") + elseif player:getStorageValue(Storage.ChildrenoftheRevolution.StrangeSymbols) == 2 then + player:setStorageValue(Storage.ChildrenoftheRevolution.StrangeSymbols, 3) + player:addItem(11106, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a flask of extra greasy oil.") + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The chest is empty.") + end + return true +end + +childrenMission3:uid(3164) +childrenMission3:register() diff --git a/data/scripts/actions/quests/children_of_the_revolution/mission3_poison_water.lua b/data/scripts/actions/quests/children_of_the_revolution/mission3_poison_water.lua new file mode 100644 index 00000000000..ae18e9e230a --- /dev/null +++ b/data/scripts/actions/quests/children_of_the_revolution/mission3_poison_water.lua @@ -0,0 +1,17 @@ +local childrenPoison = Action() +function childrenPoison.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid ~= 8012 then + return false + end + + if player:getStorageValue(Storage.ChildrenoftheRevolution.Questline) == 10 then + player:setStorageValue(Storage.ChildrenoftheRevolution.Questline, 11) + player:setStorageValue(Storage.ChildrenoftheRevolution.Mission03, 2) --Questlog, Children of the Revolution "Mission 3: Zee Killing Fieldzz" + item:remove() + player:say("The rice has been poisoned. This will weaken the Emperor's army significantly. Return and tell Zalamon about your success.", TALKTYPE_MONSTER_SAY) + end + return true +end + +childrenPoison:id(10760) +childrenPoison:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/children_of_the_revolution/mission4_grease_oil.lua b/data/scripts/actions/quests/children_of_the_revolution/mission4_grease_oil.lua new file mode 100644 index 00000000000..58979b73b77 --- /dev/null +++ b/data/scripts/actions/quests/children_of_the_revolution/mission4_grease_oil.lua @@ -0,0 +1,17 @@ +local childrenGrease = Action() +function childrenGrease.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid ~= 8013 then + return false + end + + if player:getStorageValue(Storage.ChildrenoftheRevolution.Questline) == 13 then + player:setStorageValue(Storage.ChildrenoftheRevolution.Questline, 14) + player:setStorageValue(Storage.ChildrenoftheRevolution.Mission04, 4) --Questlog, Children of the Revolution "Mission 4: Zze Way of Zztonezz" + item:remove() + player:say("Due to being extra greasy, the leavers can now be moved.", TALKTYPE_MONSTER_SAY) + end + return true +end + +childrenGrease:id(11106) +childrenGrease:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/children_of_the_revolution/zalamon_door.lua b/data/scripts/actions/quests/children_of_the_revolution/zalamon_door.lua new file mode 100644 index 00000000000..72210edb828 --- /dev/null +++ b/data/scripts/actions/quests/children_of_the_revolution/zalamon_door.lua @@ -0,0 +1,15 @@ +local childrenZalamon = Action() +function childrenZalamon.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TheNewFrontier.Mission08) >= 2 and player:getStorageValue(Storage.WrathoftheEmperor.Mission11) < 2 then + if item.itemid == 10791 then + player:teleportTo(toPosition, true) + item:transform(item.itemid + 1) + end + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The door seems to be sealed against unwanted intruders.") + end + return true +end + +childrenZalamon:uid(3170) +childrenZalamon:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/cults_of_tibia/analyser.lua b/data/scripts/actions/quests/cults_of_tibia/analyser.lua new file mode 100644 index 00000000000..d675686f435 --- /dev/null +++ b/data/scripts/actions/quests/cults_of_tibia/analyser.lua @@ -0,0 +1,28 @@ +local cultsOfTibiaAnalyser = Action() +function cultsOfTibiaAnalyser.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local sqm = Position(33485, 32276, 10) + + if not player then + return true + end + + if not target:isItem() then + return false + end + + if target:isCreature() then + return false + end + + if player:getStorageValue(Storage.CultsOfTibia.Life.Mission) == 4 then + if target:getPosition() == sqm or target:getPosition() == Position(sqm.x, sqm.y + 1, sqm.z) + or target:getPosition() == Position(sqm.x, sqm.y + 2, sqm.z) then + player:setStorageValue(Storage.CultsOfTibia.Life.Mission, 5) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Well done! The water is analyzed.") + end + end + return true +end + +cultsOfTibiaAnalyser:id(28666) +cultsOfTibiaAnalyser:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/cults_of_tibia/bosses_levers.lua b/data/scripts/actions/quests/cults_of_tibia/bosses_levers.lua new file mode 100644 index 00000000000..3001030d8b2 --- /dev/null +++ b/data/scripts/actions/quests/cults_of_tibia/bosses_levers.lua @@ -0,0 +1,538 @@ +local transformid = { + [9825] = 9826, + [9826] = 9825 +} + +local geyser = { + [1] = Position(33132, 31917, 15), + [2] = Position(33135, 31919, 15), + [3] = Position(33135, 31923, 15), + [4] = Position(33128, 31922, 15), + [5] = Position(33128, 31918, 15), + [6] = Position(33124, 31920, 15), + [7] = Position(33124, 31925, 15), + [8] = Position(33131, 31927, 15), + [9] = Position(33135, 31926, 15), + [10] = Position(33128, 31929, 15), + [11] = Position(33133, 31930, 15), + [12] = Position(33127, 31933, 15) +} + +local function spawnStolenSoul(t_time) + if t_time == 0 then + local a1 = Position(33034, 31916, 15) + local a2 = Position(33048, 31927, 15) + if not isPlayerInArea(a1, a2) then + return true + end + local newArea = Position(math.random(a1.x, a2.x), math.random(a1.y, a2.y), math.random(a1.z, a2.z) ) + Game.createMonster(math.random(1, 2) == 1 and 'Stolen Soul' or 'Soul Reaper', newArea) + t_time = 31 + end + addEvent(spawnStolenSoul, 1000, t_time - 1) +end + +local function spawnDarkSoul(area, t_time) + if t_time == 0 then + local esperandoPlayer = false + local p1 = Position(33023, 31904, 14) + local p2 = Position(33037, 31915, 14) + local sA1 = Position(33028, 31908, 14) + local sA2 = Position(33036, 31914, 14) + if area == 2 then + p1 = Position(33039, 31902, 14) + p2 = Position(33052, 31916, 14) + sA1 = Position(33042, 31908, 14) + sA2 = Position(33051, 31914, 14) + end + if not isPlayerInArea(p1, p2) then + local a1 = Position(33034, 31916, 15) + local a2 = Position(33048, 31927, 15) + if not isPlayerInArea(a1, a2) then + return true + end + esperandoPlayer = true + else + local monster = {} + for _x= sA1.x, sA2.x, 1 do + for _y= sA1.y, sA2.y, 1 do + local tileMonster = Tile(Position(_x, _y, sA1.z)):getTopCreature() + if tileMonster and tileMonster:isMonster() and tileMonster:getName() == 'Dark Soul' then + monster[#monster + 1] = tileMonster + end + end + end + if #monster >= 4 then + for _, pid in pairs(monster)do + pid:remove() + end + end + -- spawn + local newPos = Position(math.random(sA1.x, sA2.x), math.random(sA1.y, sA2.y), math.random(sA1.z, sA2.z) ) + Game.createMonster('Dark Soul', newPos) + end + addEvent(spawnDarkSoul, 1000, area, (esperandoPlayer and 1 or 30)) + else + addEvent(spawnDarkSoul, 1000, area, t_time - 1) + end +end + +local function transformMonster(itid, action, monster, frompos, topos, _temp) +-- minotaur idol + if action == 1 then + local tempo = _temp + for _x = frompos.x, topos.x, 1 do + local tile = Tile(Position(_x, frompos.y, frompos.z)) + if(_x % 2 == 0) then + tempo = tempo + 1 + if tile then + if tile:getItemCountById(itid) < 1 then + Game.createItem(itid, 1, Position(_x, frompos.y, frompos.z)) + end + addEvent(transformMonster, tempo * 15000, itid, 2, monster, Position(_x, frompos.y, frompos.z), {}, _temp + 1) + end + end + end + elseif action == 2 then + local tile = Tile(frompos) + if tile:getItemCountById(itid) > 0 then + tile:getItemById(itid):remove() + end + Game.createMonster(monster, frompos) + elseif action == 3 then + local pos = Position(33158, 31912, 15) + local pos2 = Position(33169, 31919, 15) + Game.createMonster(monster, {x = math.random(pos.x, pos2.x), y = math.random(pos.y, pos2.y), z = pos2.z}) + if _temp < itid then + _temp = _temp + 1 + addEvent(transformMonster, 15000, itid, 3, "Sphere Of Wrath", {}, {}, _temp) + end + end +end + +local function ativarGeyser(player) + local frompos = Position(33119, 31913, 15) -- Checagem + local topos = Position(33142, 31936, 15) -- Checagem + if(isPlayerInArea(frompos, topos)) then + addEvent(function() + local rand = math.random(1,12) + local geyserPos = Position(geyser[rand]) + local checar1 = Tile(Position(geyserPos)):getItemById(28868) + if checar1 then + addEvent(function() + local player1 = Game.getPlayers()[1] + Game.createItem(28869, 1, geyserPos) + player1:say("SPLASH!", TALKTYPE_MONSTER_SAY, false, false, geyserPos) + addEvent(function() + local checar2 = Tile(Position(geyserPos)):getItemById(28869) + if checar2 then + checar2:remove() + end + end, 9 * 1000) + end, 5 * 1000) + elseif checar2 then + return false + end + addEvent(function() + ativarGeyser() end, 1 * 1000) + end, 8 * 1000) + end + return true +end + +local cultsOfTibiaLevers = Action() +function cultsOfTibiaLevers.onUse(player, item, fromPosition, itemEx, toPosition) + local players = {} + local ittable = {} + local blockmonsters = {"Leiden", "Wine Cask", "Liquor Spirit", "Ravennous Hunger"} + local convertTable = {} + item:transform(transformid[item:getId()]) + + if item:getActionId() == 5501 and item:getId() == 9826 then -- Leiden + if player:getPosition() == Position(33138, 31953, 15) then + local teleport = 0 + for i = 31953, 31957, 1 do + local newpos = Position(33138, i, 15) + local nplayer = Tile(newpos):getTopCreature() + if nplayer and nplayer:isPlayer() then + teleport = teleport + 1 + end + end + + local frompos = Position(33151, 31942, 15) -- Checagem + local topos = Position(33176, 31966, 15) -- Checagem + + if(isPlayerInArea(frompos, topos)) then + player:sendCancelMessage('The room is full.') + return true + end + + for _x= frompos.x, topos.x, 1 do + for _y= frompos.y, topos.y, 1 do + for _z= frompos.z, topos.z, 1 do + local tile = Tile(Position(_x, _y, _z)) + if tile and tile:getTopCreature() and tile:getTopCreature():isMonster() then + tile:getTopCreature():remove() + end + end + end + end + + for i = 31953, 31957, 1 do + local newpos = Position(33138, i, 15) + local nplayer = Tile(newpos):getTopCreature() + if nplayer and nplayer:isPlayer() then + nplayer:setStorageValue(Storage.CultsOfTibia.Barkless.BossTimer, os.time() + 20 * 60 * 60) + nplayer:teleportTo(Position(33161, 31959, 15),true) + convertTable[#convertTable + 1] = nplayer:getId() + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + Game.createMonster("Wine Cask", Position(33162, 31945, 15)) + Game.createMonster("Leiden", Position(33162, 31950, 15)) + kickerPlayerRoomAfferMin(convertTable, frompos, topos, Position(33121, 31951, 15), "You were kicked for exceeding the time limit within the boss room.", '', 60, true, ittable, blockmonsters) + end + end + if item:getActionId() == 5502 and item:getId() == 9826 then -- Leiden + if player:getPosition() == Position(33162, 31893, 15) then + local teleport = 0 + for i = 31893, 31897, 1 do + local newpos = Position(33162, i, 15) + local nplayer = Tile(newpos):getTopCreature() + if nplayer and nplayer:isPlayer() then + teleport = teleport + 1 + end + end + + local frompos = Position(33152, 31908, 15) -- Checagem + local topos = Position(33175, 31923, 15) -- Checagem + + if(isPlayerInArea(frompos, topos)) then + player:sendCancelMessage('The room is full.') + return true + end + + for _x= frompos.x, topos.x, 1 do + for _y= frompos.y, topos.y, 1 do + for _z= frompos.z, topos.z, 1 do + local tile = Tile(Position(_x, _y, _z)) + if tile and tile:getTopCreature() and tile:getTopCreature():isMonster() then + tile:getTopCreature():remove() + end + end + end + end + + for i = 31893, 31897, 1 do + local newpos = Position(33162, i, 15) + local nplayer = Tile(newpos):getTopCreature() + if nplayer and nplayer:isPlayer() then + nplayer:setStorageValue(Storage.CultsOfTibia.Minotaurs.BossTimer, os.time() + 20 * 60 * 60) + nplayer:teleportTo(Position(33169, 31915, 15),true) + convertTable[#convertTable + 1] = nplayer:getId() + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + transformMonster(28661, 1, "minotaur idol", Position(33157, 31910, 15), Position(33168, 31910, 15), 0) + transformMonster(28661, 1, "minotaur idol", Position(33158, 31921, 15), Position(33168, 31921, 15), 6) + addEvent(transformMonster, 13*15000, 3, 3, "Sphere Of Wrath", {}, {}, 0) + Game.createMonster("The False God", Position(33159, 31914, 15)) + -- funçao + kickerPlayerRoomAfferMin(convertTable, frompos, topos, Position(33181, 31894, 15), "You were kicked for exceeding the time limit within the boss room.", '', 60, true, ittable, blockmonsters) + end + end + + if item:getActionId() == 5500 then -- Essence of Malice + if player:getPosition() == Position(33095, 31943, 15) and item:getId() == 9826 then + local teleport = 0 + for i = 31943, 31947, 1 do + local newpos = Position(33095, i, 15) + local nplayer = Tile(newpos):getTopCreature() + if nplayer and nplayer:isPlayer() then + teleport = teleport + 1 + end + end + + local frompos = Position(33084, 31907, 15) -- Checagem + local topos = Position(33114, 31933, 15) -- Checagem + + if(isPlayerInArea(frompos, topos)) then + player:sendCancelMessage('It looks like there is someone inside.') + return true + end + + for _x= frompos.x, topos.x, 1 do + for _y= frompos.y, topos.y, 1 do + for _z= frompos.z, topos.z, 1 do + local tile = Tile(Position(_x, _y, _z)) + if tile and tile:getTopCreature() and tile:getTopCreature():isMonster() then + tile:getTopCreature():remove() + end + end + end + end + + for i = 31943, 31947, 1 do + local newpos = Position(33095, i, 15) + local nplayer = Tile(newpos):getTopCreature() + if nplayer and nplayer:isPlayer() then + nplayer:setStorageValue(Storage.CultsOfTibia.Humans.BossTimer, os.time() + 20 * 60 * 60) + nplayer:teleportTo(Position(33098, 31921, 15),true) + convertTable[#convertTable + 1] = nplayer:getId() + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + kickerPlayerRoomAfferMin(convertTable, frompos, topos, Position(33091, 31963, 15), "You were kicked for exceeding the time limit within the boss room.", '', 60, true, ittable, blockmonsters) + Game.createMonster("Pillar of Summoning", Position(33093, 31919, 15)) + Game.createMonster("Pillar of Death", Position(33098, 31915, 15)) + Game.createMonster("Pillar of Protection", Position(33103, 31919, 15)) + Game.createMonster("Pillar of Healing", Position(33101, 31925, 15)) + Game.createMonster("Pillar of Draining", Position(33095, 31925, 15)) + Game.createMonster("Dorokoll The Mystic STOP", Position(33095, 31924, 15)):registerEvent("pilaresHealth") + Game.createMonster("Eshtaba The Conjurer STOP", Position(33094, 31919, 15)):registerEvent("pilaresHealth") + Game.createMonster("Eliz The Unyielding STOP", Position(33102, 31919, 15)):registerEvent("pilaresHealth") + Game.createMonster("Mezlon The Defiler STOP", Position(33101, 31924, 15)):registerEvent("pilaresHealth") + Game.createMonster("Malkhar Deathbringer STOP", Position(33098, 31916, 15)):registerEvent("pilaresHealth") + end + end + + if item:getActionId() == 5503 then -- The Sinister Hermit + if player:getPosition() == Position(33127, 31892, 15) and item:getId() == 9826 then + local teleport = 0 + for i = 31892, 31896, 1 do + local newpos = Position(33127, i, 15) + local nplayer = Tile(newpos):getTopCreature() + if nplayer and nplayer:isPlayer() then + teleport = teleport + 1 + end + end + + local frompos = Position(33119, 31913, 15) -- Checagem + local topos = Position(33142, 31936, 15) -- Checagem + + if(isPlayerInArea(frompos, topos)) then + player:sendCancelMessage('It looks like there is someone inside.') + return true + end + + for _x= frompos.x, topos.x, 1 do + for _y= frompos.y, topos.y, 1 do + for _z= frompos.z, topos.z, 1 do + local tile = Tile(Position(_x, _y, _z)) + if tile and tile:getTopCreature() and tile:getTopCreature():isMonster() then + tile:getTopCreature():remove() + end + end + end + end + + for i = 31892, 31896, 1 do + local newpos = Position(33127, i, 15) + local nplayer = Tile(newpos):getTopCreature() + if nplayer and nplayer:isPlayer() then + nplayer:setStorageValue(Storage.CultsOfTibia.Misguided.BossTimer, os.time() + 20 * 60 * 60) + nplayer:teleportTo(Position(33130, 31919, 15),true) + convertTable[#convertTable + 1] = nplayer:getId() + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + kickerPlayerRoomAfferMin(convertTable, frompos, topos, Position(33109, 31887, 15), "You were kicked for exceeding the time limit within the boss room.", '', 60, true, ittable, blockmonsters) + Game.createMonster("The Sinister Hermit Dirty", Position(33131, 31925, 15)) + ativarGeyser() + end +end + + if item:getActionId() == 5504 then -- Boss do orc + if player:getPosition() == Position(33164, 31859, 15) and item:getId() == 9826 then + local teleport = 0 + for y = 31859, 31863, 1 do + local newpos = Position(33164, y, 15) + local nplayer = Tile(newpos):getTopCreature() + if nplayer and nplayer:isPlayer() then + teleport = teleport + 1 + end + end + + local frompos = Position(33123, 31846, 15) -- Checagem + local topos = Position(33149, 31871, 15) -- Checagem + + if(isPlayerInArea(frompos, topos)) then + player:sendCancelMessage('It looks like there is someone inside.') + return true + end + + for _x= frompos.x, topos.x, 1 do + for _y= frompos.y, topos.y, 1 do + for _z= frompos.z, topos.z, 1 do + local tile = Tile(Position(_x, _y, _z)) + if tile and tile:getTopCreature() and tile:getTopCreature():isMonster() then + tile:getTopCreature():remove() + end + end + end + end + + for y = 31859, 31863, 1 do + local newpos = Position(33164, y, 15) + local nplayer = Tile(newpos):getTopCreature() + if nplayer and nplayer:isPlayer() then + nplayer:setStorageValue(Storage.CultsOfTibia.Orcs.BossTimer, os.time() + 20 * 60 * 60) + nplayer:teleportTo(Position(33137, 31867, 15),true) + convertTable[#convertTable + 1] = nplayer:getId() + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + local function criarRaio1(fromPos, toPos, id, dir) + if dir == 1 then + for _x = fromPos.x, toPos.x, 1 do + local tile = Tile(Position(_x, fromPos.y, fromPos.z)) + if tile and tile:getItemCountById(id) == 0 then + Game.createItem(id, 1, Position(_x, fromPos.y, fromPos.z)) + end + end + elseif dir == 2 then + for _y = fromPos.y, toPos.y, 1 do + local tile = Tile(Position(fromPos.x, _y, fromPos.z)) + if tile and tile:getItemCountById(id) == 0 then + Game.createItem(id, 1, Position(fromPos.x, _y, fromPos.z)) + end + end + end + end + local itensToMonster = {--8633 + Position(33133, 31856, 15), + Position(33140, 31856, 15), + Position(33140, 31863, 15), + Position(33133, 31863, 15) + } + -- criando os itens + for _, position in pairs(itensToMonster) do + local tile = Tile(position) + if tile and tile:getItemCountById(8633) < 1 then + Game.createItem(8633, 1, position) + end + end + -- criando os raios + criarRaio1(Position(33134, 31856, 15), Position(33139, 31856, 15), 29087, 1) + criarRaio1(Position(33134, 31863, 15), Position(33139, 31863, 15), 29087, 1) + criarRaio1(Position(33140, 31857, 15), Position(33140, 31862, 15), 29087, 2) + criarRaio1(Position(33133, 31857, 15), Position(33133, 31862, 15), 29087, 2) + + -- criando os securys + Game.createMonster("Security Golem", Position(33131, 31855, 15)) + Game.createMonster("Security Golem", Position(33142, 31855, 15)) + Game.createMonster("Security Golem", Position(33141, 31863, 15)) + Game.createMonster("Security Golem", Position(33132, 31863, 15)) + + Game.createMonster("Containment Machine", Position(33133, 31864, 15)):registerEvent("machineDeath") + Game.createMonster("The Armored Voidborn", Position(33135, 31859, 15)):registerEvent("machineDeath") + kickerPlayerRoomAfferMin(convertTable, frompos, topos, Position(33179, 31840, 15), "You were kicked for exceeding the time limit within the boss room.", '', 60, true, ittable, blockmonsters) + end + end + if item:getActionId() == 5505 then -- Boss da areia + if player:getPosition() == Position(33507, 32228, 10) and item:getId() == 9826 then + local teleport = 0 + for _y = 32228, 32232, 1 do + local newpos = Position(33507, _y, 10) + local nplayer = Tile(newpos):getTopCreature() + if nplayer and nplayer:isPlayer() then + teleport = teleport + 1 + end + end + + local frompos = Position(33087, 31848, 15) -- Checagem + local topos = Position(33109, 31871, 15) -- Checagem + + if(isPlayerInArea(frompos, topos)) then + player:sendCancelMessage('It looks like there is someone inside.') + return true + end + + for _x= frompos.x, topos.x, 1 do + for _y= frompos.y, topos.y, 1 do + for _z= frompos.z, topos.z, 1 do + local tile = Tile(Position(_x, _y, _z)) + if tile and tile:getTopCreature() and tile:getTopCreature():isMonster() then + tile:getTopCreature():remove() + end + if tile then + local tileItems = tile:getItems() + if type(tileItems) == "table" and #tileItems > 0 then + for _, it in pairs(tileItems) do + if ItemType(it:getId()):isCorpse() then + it:remove() + end + end + end + end + end + end + end + + for _y = 32228, 32232, 1 do + local newpos = Position(33507,_y, 10) + local nplayer = Tile(newpos):getTopCreature() + if nplayer and nplayer:isPlayer() then + nplayer:setStorageValue(Storage.CultsOfTibia.Life.BossTimer, os.time() + 20 * 60 * 60) + nplayer:teleportTo(Position(33099, 31864, 15),true) + convertTable[#convertTable + 1] = nplayer:getId() + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + + Game.createMonster("the sandking fake", Position(33099, 31858, 15)):registerEvent("sandkingThink") + Game.setStorageValue("sandking", 1) + kickerPlayerRoomAfferMin(convertTable, frompos, topos, Position(33459, 32269, 10), "You were kicked for exceeding the time limit within the boss room.", '', 60, true, ittable, blockmonsters) + end + end + + -- final boss + if item:getActionId() == 5506 then + if player:getPosition() == Position(33074, 31884, 15) and item:getId() == 9826 then + local convertTable = {} + convertTable[#convertTable + 1] = player:getId() + + local frompos = Position(33023, 31904, 14) -- Checagem + local topos = Position(33052, 31932, 15) -- Checagem + + if(isPlayerInArea(frompos, topos)) then + player:sendCancelMessage('It looks like there is someone inside.') + return true + end + + local pt1 = Position(33073, 31885, 15) + local pt2 = Position(33075, 31887, 15) + for _x = pt1.x, pt2.x, 1 do + for _y = pt1.y, pt2.y, 1 do + for _z = pt1.z, pt2.z, 1 do + local nplayer = Tile(Position(_x, _y, _z)):getTopCreature() + if nplayer and nplayer:isPlayer() then + convertTable[#convertTable + 1] = nplayer:getId() + end + end + end + end + for _, pid in pairs(convertTable) do + local nplayer = Player(pid) + if nplayer then + nplayer:setStorageValue(Storage.CultsOfTibia.FinalBoss.BossTimer, os.time() + 20 * 60 * 60) + nplayer:teleportTo(Position(33039, 31925, 15),true) + nplayer:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + + Game.createMonster('The Remorseless Corruptor', Position(33039, 31922, 15)) + Game.createMonster('Zarcorix Of Yalahar', Position(33039, 31921, 15)):registerEvent("yalahariHealth") + Game.createMonster('Stolen Soul', Position(33039, 31920, 15)) + Game.createMonster('Soul Reaper', Position(33039, 31919, 15)) + spawnDarkSoul(1, 30) + spawnDarkSoul(2, 30) + spawnStolenSoul(30) + kickerPlayerRoomAfferMin(convertTable, frompos, topos, Position(33072, 31867, 15), "You were kicked for exceeding the time limit within the boss room.", '', 60, true, ittable, blockmonsters) + end + end + return true +end + +cultsOfTibiaLevers:aid(5500,5501,5502,5503,5504,5505,5506) +cultsOfTibiaLevers:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/cults_of_tibia/counter_agent.lua b/data/scripts/actions/quests/cults_of_tibia/counter_agent.lua new file mode 100644 index 00000000000..100ca833296 --- /dev/null +++ b/data/scripts/actions/quests/cults_of_tibia/counter_agent.lua @@ -0,0 +1,46 @@ +local config = { + [1] = Position(33488, 32234, 10), + [2] = Position(33488, 32235, 10), + [3] = Position(33482, 32229, 10), + [4] = Position(33483, 32228, 10), + [5] = Position(33481, 32235, 10), + [6] = Position(33482, 32234, 10), + [7] = Position(33492, 32234, 10), + [8] = Position(33491, 32227, 10), + [9] = Position(33492, 32226, 10) + +} + +local cultsOfTibiaCounter = Action() +function cultsOfTibiaCounter.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local sqm = Position(33485, 32276, 10) + local destino = Position(33487, 32230, 10) + + if not player then + return true + end + + if not target:isItem() then + return false + end + + if target:isCreature() then + return false + end + + if player:getStorageValue(Storage.CultsOfTibia.Life.Mission) == 6 then + if target:getPosition() == sqm or target:getPosition() == Position(sqm.x, sqm.y + 1, sqm.z) or target:getPosition() == Position(sqm.x, sqm.y + 2, sqm.z) then + player:teleportTo(destino) + player:setStorageValue(Storage.CultsOfTibia.Life.Mission, 7) + for i, position in pairs(config) do + position:sendMagicEffect(CONST_ME_POFF) + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "A sandstorm has destroyed almost all pillars. The effect of the counteragent worked different than expected.") + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The sandstorm has not only destroyed the oasis, but also revealed some paving tiles and a lever.") + end + end + return true +end + +cultsOfTibiaCounter:id(28665) +cultsOfTibiaCounter:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/cults_of_tibia/crate.lua b/data/scripts/actions/quests/cults_of_tibia/crate.lua new file mode 100644 index 00000000000..0a826bcd845 --- /dev/null +++ b/data/scripts/actions/quests/cults_of_tibia/crate.lua @@ -0,0 +1,20 @@ +local cultsOfTibiaCrate = Action() +function cultsOfTibiaCrate.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local posCrate = Position(33300, 32277, 12) + -- Document + if item:getPosition() == posCrate then + if player:getStorageValue(Storage.CultsOfTibia.MotA.Mission) == 7 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Perfect! You took a wonderful loupe from this crate.") + player:addItem(28667, 1) + player:setStorageValue(Storage.CultsOfTibia.MotA.Mission, 8) + elseif player:getStorageValue(Storage.CultsOfTibia.MotA.Mission) > 7 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You already took the magnifier.") + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "This crate belongs to Angelo. You should talk to him before taking something out.") + end + end + return true +end + +cultsOfTibiaCrate:aid(5523) +cultsOfTibiaCrate:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/cults_of_tibia/cult_symbol.lua b/data/scripts/actions/quests/cults_of_tibia/cult_symbol.lua new file mode 100644 index 00000000000..c6ea99ed534 --- /dev/null +++ b/data/scripts/actions/quests/cults_of_tibia/cult_symbol.lua @@ -0,0 +1,54 @@ +local config = { + [Position(32731, 31531, 9)] = {base = 0}, + [Position(32739, 31489, 9)] = {base = 1}, + [Position(32739, 31507, 9)] = {base = 2}, + [Position(32761, 31518, 9)] = {base = 3}, + [Position(32720, 31545, 8)] = {base = 4}, + [Position(32745, 31423, 8)] = {base = 5}, + [Position(32742, 31410, 8)] = {base = 6}, + [Position(32685, 31430, 8)] = {base = 7}, + [Position(32746, 31462, 8)] = {base = 8}, + [Position(32683, 31537, 9)] = {base = 9}, + [Position(32740, 31494, 9)] = {base = 10}, + [Position(32741, 31494, 9)] = {base = 11}, + [Position(32745, 31523, 9)] = {base = 12}, + +} + +local cultsOfTibiaCult = Action() +function cultsOfTibiaCult.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local stg = math.max(player:getStorageValue(Storage.CultsOfTibia.Barkless.Objects), 0) + if stg >= 10 then + if player:getStorageValue(Storage.CultsOfTibia.Barkless.Mission) >= 4 then + -- continue + else + player:setStorageValue(Storage.CultsOfTibia.Barkless.Mission, 4) + end + return false + end + local mancha = false + for pos, pid in pairs(config) do + if item:getPosition():compare(pos) then + mancha = pid + break; + end + end + local stgTemp = math.max(player:getStorageValue(Storage.CultsOfTibia.Barkless.Temp), 0) + local manchaMeta = NewBit(stgTemp) + local base = bit.lshift(1, mancha.base) + if manchaMeta:hasFlag(base) then + return false + end + manchaMeta:updateFlag(base) + player:setStorageValue(Storage.CultsOfTibia.Barkless.Temp, manchaMeta:getNumber()) + player:setStorageValue(Storage.CultsOfTibia.Barkless.Objects, stg + 1) + if (player:getStorageValue(Storage.CultsOfTibia.Barkless.Objects) >= 10) then + player:setStorageValue(Storage.CultsOfTibia.Barkless.Mission, 4) + end + local msg = (player:getStorageValue(Storage.CultsOfTibia.Barkless.Objects) < 10 and "Your body reacts to this strange green substance as you reach out to touch it. You feel an urge for more of this energy." or "You gathered an impressive amount of power from simply touching the strange green symbols of the Barkless. But how...?") + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, msg) + return true +end + +cultsOfTibiaCult:aid(5535) +cultsOfTibiaCult:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/cults_of_tibia/document.lua b/data/scripts/actions/quests/cults_of_tibia/document.lua new file mode 100644 index 00000000000..2ab9dcf9a6f --- /dev/null +++ b/data/scripts/actions/quests/cults_of_tibia/document.lua @@ -0,0 +1,19 @@ +local cultsOfTibiaDocument = Action() +function cultsOfTibiaDocument.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local posDocument = Position(33279, 32169, 8) + -- Document + if item:getPosition() == posDocument then + if player:getStorageValue(Storage.CultsOfTibia.MotA.Mission) == 2 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Dear curator, this recently opened museum is a really nice place to be.") + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "But wait! What about the empty space in front of you? What a pity!") + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "It seems that somebody has removed one of the beautiful pictures. But come on! You have the money and we need it.") + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "So for a small expense allowance you'll get it back. Just talk to Iwar in Kazordoon for further information. ") + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Ask him: Has the cat got your tongue?") + player:setStorageValue(Storage.CultsOfTibia.MotA.Mission, 3) + end + end + return true +end + +cultsOfTibiaDocument:aid(5522) +cultsOfTibiaDocument:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/cults_of_tibia/last_object.lua b/data/scripts/actions/quests/cults_of_tibia/last_object.lua new file mode 100644 index 00000000000..d5909dbebf4 --- /dev/null +++ b/data/scripts/actions/quests/cults_of_tibia/last_object.lua @@ -0,0 +1,33 @@ +local config = { + [1] = Position(32731, 31531, 9), + [2] = Position(32739, 31489, 9), + [3] = Position(32739, 31507, 9), + [4] = Position(32761, 31518, 9), + [5] = Position(32720, 31545, 8), + [6] = Position(32745, 31423, 8), + [7] = Position(32742, 31410, 8), + [8] = Position(32685, 31430, 8), + [9] = Position(32746, 31462, 8), + [10] = Position(32683, 31537, 9), + [11] = Position(32740, 31494, 9), -- Bancada Cult Object + [12] = Position(32741, 31494, 9) -- Bancada Cult Object + +} + +local cultsOfTibiaLastObject = Action() +function cultsOfTibiaLastObject.onUse(player, item) + if player:getStorageValue(Storage.CultsOfTibia.Barkless.Mission) == 4 then + for i, position in pairs(config) do + position:sendMagicEffect(CONST_ME_YELLOWENERGY) + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The strange symbol in the wall in the back glows violently.") + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The cult object just lies there quietly. The dangerous area around it has been all but dissolved.") + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "As you reach out to touch the cult object, a surge of energy burst from the skull. You banished its power.") + player:setStorageValue(Storage.CultsOfTibia.Barkless.Mission, 5) + player:setStorageValue(Storage.CultsOfTibia.Barkless.BossAccessDoor, 1) + end + return true +end + +cultsOfTibiaLastObject:aid(5536) +cultsOfTibiaLastObject:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/cults_of_tibia/lever_mota.lua b/data/scripts/actions/quests/cults_of_tibia/lever_mota.lua new file mode 100644 index 00000000000..c234abd258b --- /dev/null +++ b/data/scripts/actions/quests/cults_of_tibia/lever_mota.lua @@ -0,0 +1,61 @@ +local transformid = { + [10029] = 10030, + [10030] = 10029 +} + +local cultsOfTibiaLeverMota = Action() +function cultsOfTibiaLeverMota.onUse(player, item, fromPosition, itemEx, toPosition) + local posPedra = Position() + local posPedra2 = Position() + local posPedra3 = Position() + local pedraid = 18008 + if player:getStorageValue(Storage.CultsOfTibia.MotA.Mission) ~= 12 then + player:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + for i = 33300, 33305, 1 do + local newpos = Position(i, 32144, 10) + if(Tile(newpos):getItemCountById(pedraid) == 1)then + posPedra = newpos + end + newpos = Position(i, 32146, 10) + if(Tile(newpos):getItemCountById(pedraid) == 1)then + posPedra2 = newpos + end + newpos = Position(i, 32148, 10) + if(Tile(newpos):getItemCountById(pedraid) == 1)then + posPedra3 = newpos + end + end + local pedra1 = math.random(0,5) + local pedra2 = math.random(0,5) + local pedra3 = math.random(0,5) + -- pedra 1 + local itpedra1 = Tile(posPedra):getItemById(pedraid) + local newpos = {x = 33300 + pedra1, y = itpedra1:getPosition().y, z = itpedra1:getPosition().z} + itpedra1:moveTo(newpos) + Position(newpos):sendMagicEffect(CONST_ME_POFF) + + -- pedra 2 + local itpedra2 = Tile(posPedra2):getItemById(pedraid) + local newpos = {x = 33300 + pedra2, y = itpedra2:getPosition().y, z = itpedra2:getPosition().z} + itpedra2:moveTo(newpos) + Position(newpos):sendMagicEffect(CONST_ME_POFF) + + -- pedra 3 + local itpedra3 = Tile(posPedra3):getItemById(pedraid) + local newpos = {x = 33300 + pedra3, y = itpedra3:getPosition().y, z = itpedra3:getPosition().z} + itpedra3:moveTo(newpos) + Position(newpos):sendMagicEffect(CONST_ME_POFF) + + player:setStorageValue(Storage.CultsOfTibia.MotA.Stone1, Stone1) + player:setStorageValue(Storage.CultsOfTibia.MotA.Stone2, Stone2) + player:setStorageValue(Storage.CultsOfTibia.MotA.Stone3, Stone3) + player:setStorageValue(Storage.CultsOfTibia.MotA.AccessDoorGareth, -1) + player:setStorageValue(Storage.CultsOfTibia.MotA.Mission, player:getStorageValue(Storage.CultsOfTibia.MotA.Mission) + 1) + item:transform(transformid[item:getId()]) + return true +end + +cultsOfTibiaLeverMota:aid(5520) +cultsOfTibiaLeverMota:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/cults_of_tibia/magnifier.lua b/data/scripts/actions/quests/cults_of_tibia/magnifier.lua new file mode 100644 index 00000000000..124a7ffb98c --- /dev/null +++ b/data/scripts/actions/quests/cults_of_tibia/magnifier.lua @@ -0,0 +1,31 @@ +local cultsOfTibiaMagnifier = Action() +function cultsOfTibiaMagnifier.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local sqm = Position(33296, 32140, 8) + local tile = Tile(Position(target:getPosition())) + + if not player then + return true + end + + if not target:isItem() then + return false + end + + if target:isCreature() then + return false + end + + if (isInArray({1835, 1814, 1809, 1825, 1831}, target:getId())) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Nothing special. This picture looks genuine.") + target:getPosition():sendMagicEffect(CONST_ME_POFF) + elseif target:getPosition() == sqm and target:getId() == 1826 and player:getStorageValue(Storage.CultsOfTibia.MotA.Mission) == 8 then + target:getPosition():sendMagicEffect(CONST_ME_POFF) + player:setStorageValue(Storage.CultsOfTibia.MotA.Mission, 9) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "This is it. It looks like it was painted by a child!") + end + + return true +end + +cultsOfTibiaMagnifier:id(28667) +cultsOfTibiaMagnifier:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/cults_of_tibia/misguided.lua b/data/scripts/actions/quests/cults_of_tibia/misguided.lua new file mode 100644 index 00000000000..5bdcbdb2676 --- /dev/null +++ b/data/scripts/actions/quests/cults_of_tibia/misguided.lua @@ -0,0 +1,69 @@ +local function cleanMMap(frompos, topos) + for _x= frompos.x, topos.x, 1 do + for _y= frompos.y, topos.y, 1 do + for _z= frompos.z, topos.z, 1 do + local newpos = Position(_x, _y, _z) + local tile = Tile(newpos) + if tile and tile:getItemCount() > 0 then + for _, it in pairs(tile:getItems()) do + if it then + local itemType = ItemType(it:getId()) + if itemType and not itemType:isCorpse() and not itemType:isContainer() and itemType:getWeaponType() <= WEAPON_NONE then + it:remove() + end + end + end + end + end + end + end +end + +local function changeMap(mapName) + local map = (type(Game.getStorageValue("cultsMap")) == "string" and Game.getStorageValue("cultsMap") or 'ouro') + if map:lower() == mapName:lower() then + return true + end + local frompos = Position(32523, 32323, 10) + local topos = Position( 32573, 32477, 10) + cleanMMap(frompos, topos) + cleanMMap(Position(32512, 32364, 10), Position(32526, 32474, 10)) + if mapName:lower() == "ouro" then + Game.setStorageValue("cultsMap", "ouro") + Game.loadMap('data/world/worldchanges/ouro.otbm') + else + Game.setStorageValue("cultsMap", "folhas") + Game.loadMap('data/world/worldchanges/folhas.otbm') + addEvent(changeMap, 15000, "ouro") + end +end + +local cultsOfTibiaMisguided = Action() +function cultsOfTibiaMisguided.onUse(player, item, position, target, targetPosition) + local monster = Monster(target) + if not monster then + return false + end + local map = (type(Game.getStorageValue("cultsMap")) == "string" and Game.getStorageValue("cultsMap") or 'ouro') + if monster:getName():lower() == "misguided bully" or monster:getName():lower() == "misguided thief" then + player:setStorageValue(Storage.CultsOfTibia.Misguided.Monsters, 0) + item:remove(1) + local pos = monster:getPosition() + Game.createItem(28659, 1, pos) + monster:remove() + local newMonster = Game.createMonster("Misguided Shadow", pos) + if newMonster then + newMonster:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You paralyse the bully and the amulet reveals the true face of the creature behind the possession of this misguided creature.") + local it = player:addItem(28657, 1) + if map == "ouro" then + changeMap("folhas") + end + it:decay() + end + return true +end + +cultsOfTibiaMisguided:id(28658) +cultsOfTibiaMisguided:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/cults_of_tibia/torch.lua b/data/scripts/actions/quests/cults_of_tibia/torch.lua new file mode 100644 index 00000000000..11f8327f522 --- /dev/null +++ b/data/scripts/actions/quests/cults_of_tibia/torch.lua @@ -0,0 +1,26 @@ +local config = { + {position = Position(32396, 31806, 8), itemId = 1050} +} + +local cultsOfTibiaTouch = Action() +function cultsOfTibiaTouch.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local wallItem + if Game.getStorageValue(12345) >= os.time() then + player:getPosition():sendMagicEffect(CONST_ME_POFF) + else + for i = 1, #config do + wallItem = Tile(config[i].position):getItemById(config[i].itemId) + if wallItem then + Position(32396, 31806, 8):sendMagicEffect(CONST_ME_POFF) + wallItem:remove() + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You hear a loud grinding sound not very far from you. something very heavy seems to have moved.") + Game.setStorageValue(12345, os.time() + 306) + addEvent(Game.createItem, 300000, 1050, 1, Position(32396, 31806, 8)) + end + end + end + return true +end + +cultsOfTibiaTouch:aid(5524) +cultsOfTibiaTouch:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/dangerous_depth/crude_lava_pump.lua b/data/scripts/actions/quests/dangerous_depth/crude_lava_pump.lua new file mode 100644 index 00000000000..bfa72f67c62 --- /dev/null +++ b/data/scripts/actions/quests/dangerous_depth/crude_lava_pump.lua @@ -0,0 +1,71 @@ +local transformid = { + [30735] = 30737, +} + +local dangerousDepthPump = Action() +function dangerousDepthPump.onUse(player, item) + if not player then + return true + end + + local positionItem = item:getPosition() + + if item:getActionId() == 57300 then -- Warzone VI + local spectators = Game.getSpectators(positionItem, false, true, 5, 5, 5, 5) + for _, spectator in pairs(spectators) do + if spectator:isPlayer() then + local playerSpectator = spectator + if playerSpectator:getStorageValue(Storage.DangerousDepths.Access.LavaPumpWarzoneVI) < 1 then + playerSpectator:setStorageValue(Storage.DangerousDepths.Access.LavaPumpWarzoneVI, 1) + end + end + end + player:say("With the pump destroyed, the lava stream has been stopped. Zone VI is acessible now!", TALKTYPE_MONSTER_SAY, false, false, positionItem) + item:transform(transformid[item:getId()]) + addEvent(function() + if item then + item:transform(30735) + end + end, 10 * 60 * 1000) -- 10 minutos para o item voltar ao normal. + end + if item:getActionId() == 57302 then -- Warzone V + local spectators = Game.getSpectators(positionItem, false, true, 5, 5, 5, 5) + for _, spectator in pairs(spectators) do + if spectator:isPlayer() then + local playerSpectator = spectator + if playerSpectator:getStorageValue(Storage.DangerousDepths.Access.LavaPumpWarzoneV) < 1 then + playerSpectator:setStorageValue(Storage.DangerousDepths.Access.LavaPumpWarzoneV, 1) + end + end + end + player:say("With the pump destroyed, the lava stream has been stopped. Zone V is acessible now!", TALKTYPE_MONSTER_SAY, false, false, positionItem) + item:transform(transformid[item:getId()]) + addEvent(function() + if item then + item:transform(30735) + end + end, 10 * 60 * 1000) -- 10 minutos para o item voltar ao normal. + end + if item:getActionId() == 57301 then -- Warzone IV + local spectators = Game.getSpectators(positionItem, false, true, 5, 5, 5, 5) + for _, spectator in pairs(spectators) do + if spectator:isPlayer() then + local playerSpectator = spectator + if playerSpectator:getStorageValue(Storage.DangerousDepths.Access.LavaPumpWarzoneIV) < 1 then + playerSpectator:setStorageValue(Storage.DangerousDepths.Access.LavaPumpWarzoneIV, 1) + end + end + end + player:say("With the pump destroyed, the lava stream has been stopped. Zone IV is acessible now!", TALKTYPE_MONSTER_SAY, false, false, positionItem) + item:transform(transformid[item:getId()]) + addEvent(function() + if item then + item:transform(30735) + end + end, 10 * 60 * 1000) -- 10 minutos para o item voltar ao normal. + end + return true +end + +dangerousDepthPump:aid(57300,57301,57302) +dangerousDepthPump:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/dangerous_depth/crude_lava_pump_achievements.lua b/data/scripts/actions/quests/dangerous_depth/crude_lava_pump_achievements.lua new file mode 100644 index 00000000000..aed1c2bea6e --- /dev/null +++ b/data/scripts/actions/quests/dangerous_depth/crude_lava_pump_achievements.lua @@ -0,0 +1,66 @@ +local transformid = { + [30735] = 30737, +} + +local function explosion(item) + local centerPosition = item:getPosition() + for x = centerPosition.x - 1, centerPosition.x + 1 do + for y = centerPosition.y - 1, centerPosition.y + 1 do + for z = centerPosition.z, centerPosition.z do + if Tile(Position(x, y, z)) then + if Tile(Position(x, y, z)) then + local sqm = Position(x, y, z) + sqm:sendMagicEffect(CONST_ME_FIREAREA) + end + end + end + end + end +end + +local dangerousDepthAchievements = Action() +function dangerousDepthAchievements.onUse(player, item) + if not player then + return true + end + + explosion(item) + + local positionItem = item:getPosition() + local WarzoneIV = Position(33673, 32304, 15) + local WarzoneV = Position(33679, 32310, 15) + local WarzoneVI = Position(33685, 32304, 15) + + if positionItem == WarzoneIV then -- Warzone VI + if player:getStorageValue(Storage.DangerousDepths.Bosses.TheBaronFromBelowAchiev) < 1 then + player:addAchievement('Buried the Baron') + player:setStorageValue(Storage.DangerousDepths.Bosses.TheBaronFromBelowAchiev, 1) + end + end + + if positionItem == WarzoneV then -- Warzone V + if player:getStorageValue(Storage.DangerousDepths.Bosses.TheCountOfTheCoreAchiev) < 1 then + player:addAchievement('His Days are Counted') + player:setStorageValue(Storage.DangerousDepths.Bosses.TheCountOfTheCoreAchiev, 1) + end + end + + if positionItem == WarzoneVI then -- Warzone IV + if player:getStorageValue(Storage.DangerousDepths.Bosses.TheDukeOfTheDepthsAchiev) < 1 then + player:addAchievement('Duked It Out') + player:setStorageValue(Storage.DangerousDepths.Bosses.TheDukeOfTheDepthsAchiev, 1) + end + end + + if player:getStorageValue(Storage.DangerousDepths.Bosses.LastAchievement) < 1 then + if player:getStorageValue(Storage.DangerousDepths.Bosses.TheDukeOfTheDepthsAchiev) == 1 and player:getStorageValue(Storage.DangerousDepths.Bosses.TheBaronFromBelowAchiev) == 1 + and player:getStorageValue(Storage.DangerousDepths.Bosses.TheCountOfTheCoreAchiev) == 1 then + player:addAchievement('Death in the Depths') + player:setStorageValue(Storage.DangerousDepths.Bosses.LastAchievement, 1) + end + end + return true +end + +dangerousDepthAchievements:aid(57303) +dangerousDepthAchievements:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/dangerous_depth/gnome_chart.lua b/data/scripts/actions/quests/dangerous_depth/gnome_chart.lua new file mode 100644 index 00000000000..2c48e595b5e --- /dev/null +++ b/data/scripts/actions/quests/dangerous_depth/gnome_chart.lua @@ -0,0 +1,70 @@ +local config = { + OldGate = {fromPosition = Position(33978, 32177, 14), toPosition = Position(33982, 32177, 14)}, + LostRuin = {fromPosition = Position(33946, 32161, 14), toPosition = Position(33951, 32163, 14)}, + TheGaze = {fromPosition = Position(33962, 32139, 14), toPosition = Position(33976, 32148, 14)}, + Outpost = {fromPosition = Position(33865, 32008, 14), toPosition = Position(33875, 32021, 14)}, + Bastion = {fromPosition = Position(33923, 31983, 14), toPosition = Position(33942, 31998, 14)}, + BrokenTower = {fromPosition = Position(33859, 32358, 14), toPosition = Position(33867, 32363, 14)}, +} + +local dangerousDepthChart = Action() +function dangerousDepthChart.onUse(player, item, isHotkey) + if not player then + return true + end + + if player:getStorageValue(Storage.DangerousDepths.Gnomes.Charting) == 1 then + if player:getPosition():isInRange(config.OldGate.fromPosition, config.OldGate.toPosition) then + if player:getStorageValue(Storage.DangerousDepths.Gnomes.OldGate) < 1 then + player:setStorageValue(Storage.DangerousDepths.Gnomes.OldGate, 1) + player:setStorageValue(Storage.DangerousDepths.Gnomes.ChartingCount, player:getStorageValue(Storage.DangerousDepths.Gnomes.ChartingCount) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You charted the location and dimensions of a strange structure, an ancient gate.") + player:getPosition():sendMagicEffect(CONST_ME_HITAREA) + end + end + if player:getPosition():isInRange(config.LostRuin.fromPosition, config.LostRuin.toPosition) then + if player:getStorageValue(Storage.DangerousDepths.Gnomes.LostRuin) < 1 then + player:setStorageValue(Storage.DangerousDepths.Gnomes.LostRuin, 1) + player:setStorageValue(Storage.DangerousDepths.Gnomes.ChartingCount, player:getStorageValue(Storage.DangerousDepths.Gnomes.ChartingCount) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You charted the location and dimensions of a strange structure, a small ruin.") + player:getPosition():sendMagicEffect(CONST_ME_HITAREA) + end + end + if player:getPosition():isInRange(config.TheGaze.fromPosition, config.TheGaze.toPosition) then + if player:getStorageValue(Storage.DangerousDepths.Gnomes.TheGaze) < 1 then + player:setStorageValue(Storage.DangerousDepths.Gnomes.TheGaze, 1) + player:setStorageValue(Storage.DangerousDepths.Gnomes.ChartingCount, player:getStorageValue(Storage.DangerousDepths.Gnomes.ChartingCount) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You charted the location and dimensions of a strange structure, resembling a stone face.") + player:getPosition():sendMagicEffect(CONST_ME_HITAREA) + end + end + if player:getPosition():isInRange(config.Outpost.fromPosition, config.Outpost.toPosition) then + if player:getStorageValue(Storage.DangerousDepths.Gnomes.Outpost) < 1 then + player:setStorageValue(Storage.DangerousDepths.Gnomes.Outpost, 1) + player:setStorageValue(Storage.DangerousDepths.Gnomes.ChartingCount, player:getStorageValue(Storage.DangerousDepths.Gnomes.ChartingCount) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You charted the location and dimensions of a strange structure, an outpost.") + player:getPosition():sendMagicEffect(CONST_ME_HITAREA) + end + end + if player:getPosition():isInRange(config.Bastion.fromPosition, config.Bastion.toPosition) then + if player:getStorageValue(Storage.DangerousDepths.Gnomes.Bastion) < 1 then + player:setStorageValue(Storage.DangerousDepths.Gnomes.Bastion, 1) + player:setStorageValue(Storage.DangerousDepths.Gnomes.ChartingCount, player:getStorageValue(Storage.DangerousDepths.Gnomes.ChartingCount) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You charted the location and dimensions of a strange structure, a bastion.") + player:getPosition():sendMagicEffect(CONST_ME_HITAREA) + end + end + if player:getPosition():isInRange(config.BrokenTower.fromPosition, config.BrokenTower.toPosition) then + if player:getStorageValue(Storage.DangerousDepths.Gnomes.BrokenTower) < 1 then + player:setStorageValue(Storage.DangerousDepths.Gnomes.BrokenTower, 1) + player:setStorageValue(Storage.DangerousDepths.Gnomes.ChartingCount, player:getStorageValue(Storage.DangerousDepths.Gnomes.ChartingCount) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You charted the location and dimensions of a strange structure, a broken tower.") + player:getPosition():sendMagicEffect(CONST_ME_HITAREA) + end + end + end + return true +end + +dangerousDepthChart:id(31931) +dangerousDepthChart:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/dangerous_depth/gnome_items.lua b/data/scripts/actions/quests/dangerous_depth/gnome_items.lua new file mode 100644 index 00000000000..8b0196156ea --- /dev/null +++ b/data/scripts/actions/quests/dangerous_depth/gnome_items.lua @@ -0,0 +1,24 @@ +local dangerousDepthItems = Action() +function dangerousDepthItems.onUse(player, item) + if item:getUniqueId() == 57235 then + if player:getStorageValue(Storage.DangerousDepths.Gnomes.GnomeChartPaper) == 1 then -- Permissão para usar o baú == 1 then + player:addItem(31931, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a gnome charts.") + player:setStorageValue(Storage.DangerousDepths.Gnomes.GnomeChartPaper, 2) + elseif player:getStorageValue(Storage.DangerousDepths.Gnomes.GnomeChartPaper) == 2 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You can not use this item again.") + end + elseif item:getUniqueId() == 57236 then + if player:getStorageValue(Storage.DangerousDepths.Gnomes.GnomeChartChest) == 1 then -- Permissão para usar o baú == 1 then + player:addItem(31930, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a gnome trignometre.") + player:setStorageValue(Storage.DangerousDepths.Gnomes.GnomeChartChest, 2) + elseif player:getStorageValue(Storage.DangerousDepths.Gnomes.GnomeChartChest) == 2 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "It is empty.") + end + end + return true +end + +dangerousDepthItems:uid(57235,57236) +dangerousDepthItems:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/dangerous_depth/gnome_trignometre.lua b/data/scripts/actions/quests/dangerous_depth/gnome_trignometre.lua new file mode 100644 index 00000000000..41d41add405 --- /dev/null +++ b/data/scripts/actions/quests/dangerous_depth/gnome_trignometre.lua @@ -0,0 +1,60 @@ +local config = { + locationA = {fromPosition = Position(33921, 32141, 14), toPosition = Position(33926, 32146, 14)}, + locationB = {fromPosition = Position(33965, 32139, 14), toPosition = Position(33975, 32149, 14)}, + locationC = {fromPosition = Position(33911, 32176, 14), toPosition = Position(33914, 32180, 14)}, + locationD = {fromPosition = Position(33947, 32206, 14), toPosition = Position(33952, 32209, 14)}, + locationE = {fromPosition = Position(33877, 32173, 14), toPosition = Position(33881, 32179, 14)}, +} + +local dangerousDepthTrignometre = Action() +function dangerousDepthTrignometre.onUse(player, item, isHotkey) + if not player then + return true + end + if player:getStorageValue(Storage.DangerousDepths.Gnomes.Measurements) == 1 then + if player:getPosition():isInRange(config.locationA.fromPosition, config.locationA.toPosition) then + if player:getStorageValue(Storage.DangerousDepths.Gnomes.LocationA) < 1 then + player:setStorageValue(Storage.DangerousDepths.Gnomes.LocationA, 1) + player:setStorageValue(Storage.DangerousDepths.Gnomes.LocationCount, player:getStorageValue(Storage.DangerousDepths.Gnomes.LocationCount) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You probed the location successfully.") + player:getPosition():sendMagicEffect(CONST_ME_HITAREA) + end + end + if player:getPosition():isInRange(config.locationB.fromPosition, config.locationB.toPosition) then + if player:getStorageValue(Storage.DangerousDepths.Gnomes.LocationB) < 1 then + player:setStorageValue(Storage.DangerousDepths.Gnomes.LocationB, 1) + player:setStorageValue(Storage.DangerousDepths.Gnomes.LocationCount, player:getStorageValue(Storage.DangerousDepths.Gnomes.LocationCount) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You probed the location successfully.") + player:getPosition():sendMagicEffect(CONST_ME_HITAREA) + end + end + if player:getPosition():isInRange(config.locationC.fromPosition, config.locationC.toPosition) then + if player:getStorageValue(Storage.DangerousDepths.Gnomes.LocationC) < 1 then + player:setStorageValue(Storage.DangerousDepths.Gnomes.LocationC, 1) + player:setStorageValue(Storage.DangerousDepths.Gnomes.LocationCount, player:getStorageValue(Storage.DangerousDepths.Gnomes.LocationCount) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You probed the location successfully.") + player:getPosition():sendMagicEffect(CONST_ME_HITAREA) + end + end + if player:getPosition():isInRange(config.locationD.fromPosition, config.locationD.toPosition) then + if player:getStorageValue(Storage.DangerousDepths.Gnomes.LocationD) < 1 then + player:setStorageValue(Storage.DangerousDepths.Gnomes.LocationD, 1) + player:setStorageValue(Storage.DangerousDepths.Gnomes.LocationCount, player:getStorageValue(Storage.DangerousDepths.Gnomes.LocationCount) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You probed the location successfully.") + player:getPosition():sendMagicEffect(CONST_ME_HITAREA) + end + end + if player:getPosition():isInRange(config.locationE.fromPosition, config.locationE.toPosition) then + if player:getStorageValue(Storage.DangerousDepths.Gnomes.LocationE) < 1 then + player:setStorageValue(Storage.DangerousDepths.Gnomes.LocationE, 1) + player:setStorageValue(Storage.DangerousDepths.Gnomes.LocationCount, player:getStorageValue(Storage.DangerousDepths.Gnomes.LocationCount) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You probed the location successfully.") + player:getPosition():sendMagicEffect(CONST_ME_HITAREA) + end + end + end + return true +end + +dangerousDepthTrignometre:id(31930) +dangerousDepthTrignometre:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/dangerous_depth/gnomish_chest.lua b/data/scripts/actions/quests/dangerous_depth/gnomish_chest.lua new file mode 100644 index 00000000000..d3c1cc62eff --- /dev/null +++ b/data/scripts/actions/quests/dangerous_depth/gnomish_chest.lua @@ -0,0 +1,14 @@ +local dangerousDepthChest = Action() +function dangerousDepthChest.onUse(player, item) + if player:getStorageValue(Storage.DangerousDepths.Scouts.GnomishChest) == 1 then + player:addItem(30733, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found gnomish pesticides.") + player:setStorageValue(Storage.DangerousDepths.Scouts.GnomishChest, 2) + elseif player:getStorageValue(Storage.DangerousDepths.Scouts.GnomishChest) == 2 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "It is empty.") + end + return true +end + +dangerousDepthChest:uid(57234) +dangerousDepthChest:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/dangerous_depth/gnomish_pesticide.lua b/data/scripts/actions/quests/dangerous_depth/gnomish_pesticide.lua new file mode 100644 index 00000000000..c113eaf4b1d --- /dev/null +++ b/data/scripts/actions/quests/dangerous_depth/gnomish_pesticide.lua @@ -0,0 +1,42 @@ +local dangerousDepthPesticide = Action() +function dangerousDepthPesticide.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if not player then + return true + end + + if not target:isItem() then + return false + end + + if target:isCreature() then + return false + end + + local r = math.random(1, 100) + local corpseId = 30729 + local posTarget = target:getPosition() + + if target:getId() == corpseId then + if player:getStorageValue(Storage.DangerousDepths.Scouts.Diremaw) == 1 and player:getStorageValue(Storage.DangerousDepths.Scouts.DiremawsCount) < 20 then + if r <= 50 then + posTarget:sendMagicEffect(CONST_ME_POISONAREA) + local diremaw = Game.createMonster("Diremaw", target:getPosition()) + player:setStorageValue(Storage.DangerousDepths.Scouts.DiremawsCount, player:getStorageValue(Storage.DangerousDepths.Scouts.DiremawsCount) +1) + target:transform(30730) + + else + posTarget:sendMagicEffect(CONST_ME_POISONAREA) + player:setStorageValue(Storage.DangerousDepths.Scouts.DiremawsCount, player:getStorageValue(Storage.DangerousDepths.Scouts.DiremawsCount) +1) + target:transform(30730) + end + end + elseif (isInArray({30730, 30731, 30732}, target:getId())) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Only half-decayed diremaw corpses can be neutralised with these pesticides.") + return true + end + + return true +end + +dangerousDepthPesticide:id(30733) +dangerousDepthPesticide:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/dangerous_depth/lever_barrel.lua b/data/scripts/actions/quests/dangerous_depth/lever_barrel.lua new file mode 100644 index 00000000000..43ddb3ee03d --- /dev/null +++ b/data/scripts/actions/quests/dangerous_depth/lever_barrel.lua @@ -0,0 +1,152 @@ +local transformid = { + [28594] = 1946, + [1946] = 28594 +} + +local config = { + first = { + [1] = {fromPosition = Position(33877, 32060, 14), toPosition = Position(33888, 32068, 14), stgRoom = Storage.DangerousDepths.Scouts.FirstBarrel}, + }, + second = { + [1] = {fromPosition = Position(33906, 32026, 14), toPosition = Position(33916, 32037, 14), stgRoom = Storage.DangerousDepths.Scouts.SecondBarrel}, + }, + third = { + [1] = {fromPosition = Position(33865, 32009, 14), toPosition = Position(33874, 32020, 14), stgRoom = Storage.DangerousDepths.Scouts.ThirdBarrel}, + }, + fourth = { + [1] = {fromPosition = Position(33837, 31984, 14), toPosition = Position(33852, 31991, 14), stgRoom = Storage.DangerousDepths.Scouts.FourthBarrel}, + }, + fifth = { + [1] = {fromPosition = Position(33923, 31982, 14), toPosition = Position(33942, 31998, 14), stgRoom = Storage.DangerousDepths.Scouts.FifthBarrel}, + }, +} + +local function checarPos(item) + for _, info1 in pairs(config.first) do + local fromPos, toPos, stgRoom = info1.fromPosition, info1.toPosition, info1.stgRoom + if item:getPosition():isInRange(fromPos, toPos) then + local stgBarril = item:getSpecialAttribute(Storage.DangerousDepths.Scouts.Barrel) or -1 + local player = Player(stgBarril) + if player then + if player:getStorageValue(stgRoom) < 1 then + player:setStorageValue(Storage.DangerousDepths.Scouts.BarrelCount, player:getStorageValue(Storage.DangerousDepths.Scouts.BarrelCount) + 1) + player:setStorageValue(stgRoom, 1) + end + end + end + end + for _, info2 in pairs(config.second) do + local fromPos, toPos, stgRoom = info2.fromPosition, info2.toPosition, info2.stgRoom + if item:getPosition():isInRange(fromPos, toPos) then + local stgBarril = item:getSpecialAttribute(Storage.DangerousDepths.Scouts.Barrel) or -1 + local player = Player(stgBarril) + if player then + if player:getStorageValue(stgRoom) < 1 then + player:setStorageValue(Storage.DangerousDepths.Scouts.BarrelCount, player:getStorageValue(Storage.DangerousDepths.Scouts.BarrelCount) + 1) + player:setStorageValue(stgRoom, 1) + end + end + end + end + for _, info3 in pairs(config.third) do + local fromPos, toPos, stgRoom = info3.fromPosition, info3.toPosition, info3.stgRoom + if item:getPosition():isInRange(fromPos, toPos) then + local stgBarril = item:getSpecialAttribute(Storage.DangerousDepths.Scouts.Barrel) or -1 + local player = Player(stgBarril) + if player then + if player:getStorageValue(stgRoom) < 1 then + player:setStorageValue(Storage.DangerousDepths.Scouts.BarrelCount, player:getStorageValue(Storage.DangerousDepths.Scouts.BarrelCount) + 1) + player:setStorageValue(stgRoom, 1) + end + end + end + end + for _, info4 in pairs(config.fourth) do + local fromPos, toPos, stgRoom = info4.fromPosition, info4.toPosition, info4.stgRoom + if item:getPosition():isInRange(fromPos, toPos) then + local stgBarril = item:getSpecialAttribute(Storage.DangerousDepths.Scouts.Barrel) or -1 + local player = Player(stgBarril) + if player then + if player:getStorageValue(stgRoom) < 1 then + player:setStorageValue(Storage.DangerousDepths.Scouts.BarrelCount, player:getStorageValue(Storage.DangerousDepths.Scouts.BarrelCount) + 1) + player:setStorageValue(stgRoom, 1) + end + end + end + end + for _, info5 in pairs(config.fifth) do + local fromPos, toPos, stgRoom = info5.fromPosition, info5.toPosition, info5.stgRoom + if item:getPosition():isInRange(fromPos, toPos) then + local stgBarril = item:getSpecialAttribute(Storage.DangerousDepths.Scouts.Barrel) or -1 + local player = Player(stgBarril) + if player then + if player:getStorageValue(stgRoom) < 1 then + player:setStorageValue(Storage.DangerousDepths.Scouts.BarrelCount, player:getStorageValue(Storage.DangerousDepths.Scouts.BarrelCount) + 1) + player:setStorageValue(stgRoom, 1) + end + end + end + end +end + +local function explode(item) + local position = item:getPosition() + local fromPosition = Position(position.x - 6, position.y - 6, position.z) + local toPosition = Position(position.x + 6, position.y + 6, position.z) + local c = Game.getPlayers()[1] + + addEvent(function() + for x = fromPosition.x, toPosition.x do + for y = fromPosition.y, toPosition.y do + for z = fromPosition.z, toPosition.z do + if Tile(Position(x, y, z)) then + if Tile(Position(x, y, z)) then + local posEffect = Tile(Position(x, y, z)):getPosition() + local creature = Tile(Position(x, y, z)):getTopCreature() + posEffect:sendMagicEffect(CONST_ME_FIREAREA) + end + end + end + end + end + checarPos(item) + c:say("KABOOM!!", TALKTYPE_MONSTER_SAY, false, false, position) + if item then + item:remove() + end + end, 2 * 1000) + item:transform(32401) + c:say("Tsssss...!", TALKTYPE_MONSTER_SAY, false, false, position) +end + +local dangerousDepthLever = Action() +function dangerousDepthLever.onUse(player, item) + if not player then + return true + end + + local posBarril = Position(33838, 32077, 14) + local stgCount = player:getStorageValue(Storage.DangerousDepths.Scouts.BarrelCount) + local BarrelTimer = player:getStorageValue(Storage.DangerousDepths.Scouts.BarrelTimer) + + if item:getId() == 28594 then + if player:getStorageValue(Storage.DangerousDepths.Scouts.Growth) == 1 and stgCount < 5 and BarrelTimer <= 0 then + local barril = Game.createItem(31992, 1, posBarril) + local stgBarril = barril:getSpecialAttribute(Storage.DangerousDepths.Scouts.Barrel) or -1 + barril:setSpecialAttribute(Storage.DangerousDepths.Scouts.Barrel, player:getId()) + addEvent(function() + if barril then + explode(barril) + end + player:setStorageValue(Storage.DangerousDepths.Scouts.BarrelTimer, 0) + end, 2 * 60 * 1000) + player:setStorageValue(Storage.DangerousDepths.Scouts.BarrelTimer, os.time() + 2*60) -- Só para barrar. + --O tempo é setado em 0 ao barril explodir. + end + end + item:transform(transformid[item:getId()]) + return true +end + +dangerousDepthLever:aid(57234) +dangerousDepthLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/dangerous_depth/using_crystals.lua b/data/scripts/actions/quests/dangerous_depth/using_crystals.lua new file mode 100644 index 00000000000..1464744e466 --- /dev/null +++ b/data/scripts/actions/quests/dangerous_depth/using_crystals.lua @@ -0,0 +1,538 @@ +local beastPositions = { + [1] = Position(33677, 32333, 15), + [2] = Position(33677, 32337, 15), + [3] = Position(33685, 32333, 15), + [4] = Position(33685, 32337, 15), +} + +local machinePositions ={ + [1] = { + [1] = Position(33672, 32331, 15), + [2] = Position(33673, 32331, 15), + [3] = Position(33674, 32331, 15), + [4] = Position(33675, 32331, 15), + }, + [2] = { + [1] = Position(33676, 32339, 15), + [2] = Position(33677, 32339, 15), + [3] = Position(33678, 32339, 15), + [4] = Position(33679, 32339, 15), + }, + [3] = { + [1] = Position(33680, 32330, 15), + [2] = Position(33681, 32330, 15), + [3] = Position(33682, 32330, 15), + [4] = Position(33683, 32330, 15), + }, + [4] = { + [1] = Position(33684, 32339, 15), + [2] = Position(33685, 32339, 15), + [3] = Position(33686, 32339, 15), + [4] = Position(33687, 32339, 15), + }, + [5] = { + [1] = Position(33688, 32332, 15), + [2] = Position(33689, 32332, 15), + [3] = Position(33690, 32332, 15), + [4] = Position(33691, 32332, 15), + }, +} + +local fieryHearts = { + [1] = Position(33712, 32299, 15), + [2] = Position(33715, 32301, 15), + [3] = Position(33714, 32305, 15), + [4] = Position(33710, 32305, 15), + [5] = Position(33709, 32301, 15), +} + +local aggressiveLavasIV = { + [1] = Position(33648, 32295, 15), + [2] = Position(33648, 32313, 15), +} + +local aggressiveLavasVI = { + [1] = Position(33712, 32296, 15), + [2] = Position(33712, 32310, 15), +} + +local function lavaHoles(i) + local lavaHolesArray = { + [1] = Position(33652, 32307, 15), + [2] = Position(33644, 32307, 15), + [3] = Position(33644, 32299, 15), + [4] = Position(33652, 32299, 15), + } + local boss = false + local positionCenter = Position(33648, 32302, 15) + local spectator = Game.getSpectators(positionCenter, false, false, 20, 20, 20, 20) + for _, creature in pairs(spectator) do + if creature:isMonster() then + if creature:getName():lower() == "the baron from below" or creature:getName():lower() == "the hungry baron from below" then + boss = true + end + end + end + if boss == true then + local position = lavaHolesArray[i] + local desativado = Tile(position):getItemById(388) + if desativado then + desativado:transform(389) + addEvent(function() + local ativado = Tile(position):getItemById(389) + if ativado then + local c = Game.getPlayers()[1] + c:say("BOOOOM!", TALKTYPE_MONSTER_SAY, false, false, position) + for x = position.x - 4, position.x + 4 do + for y = position.y - 4, position.y + 4 do + for z = position.z, position.z do + if Tile(Position(x, y, z)) then + if Tile(Position(x, y, z)) then + local sqm = Position(x, y, z) + local creature = Tile(Position(x, y, z)):getTopCreature() + local mwCheck = Tile(Position(x, y, z)):getItemById(1497) + local wildCheck = Tile(Position(x, y, z)):getItemById(1499) + if not (mwCheck or wildCheck) then + if creature then + if creature:isPlayer() then + creature:addHealth(-(math.random(0, 1500))) + end + end + sqm:sendMagicEffect(CONST_ME_HITBYFIRE) + end + end + end + end + end + end + ativado:transform(388) + end + end, 3*1000) + i = i + 1 + if i > 4 then + i = 1 + end + end + end + if boss == true then + addEvent(lavaHoles, 15*1000, i) + end +end + +local function sumonarLavasIV(i) + local boss = false + local positionCenter = Position(33648, 32302, 15) + local spectator = Game.getSpectators(positionCenter, false, false, 20, 20, 20, 20) + for _, creature in pairs(spectator) do + if creature:isMonster() then + if creature:getName():lower() == "the baron from below" or creature:getName():lower() == "the hungry baron from below" then + boss = true + end + end + end + if boss == true then + if i >= 1 then + for j, position in pairs(aggressiveLavasIV) do + position:sendMagicEffect(CONST_ME_TELEPORT) + end + i = i - 1 + addEvent(sumonarLavasIV, 2*1000, i) + elseif i == 0 then + for j, position in pairs(aggressiveLavasIV) do + local lava = Game.createMonster("Aggressive Lava", position) + end + addEvent(sumonarLavasIV, 15*1000, 5) + end + end +end + +local function sumonarLavasVI(i) + local boss = false + local positionCenter = Position(33712, 32303, 15) + local spectator = Game.getSpectators(positionCenter, false, false, 20, 20, 20, 20) + for _, creature in pairs(spectator) do + if creature:isMonster() then + if creature:getName():lower() == "the duke of the depths" or creature:getName():lower() == "the duke of the depths immortal" then + boss = true + end + end + end + if boss == true then + if i >= 1 then + for j, position in pairs(aggressiveLavasVI) do + position:sendMagicEffect(CONST_ME_TELEPORT) + end + i = i - 1 + addEvent(sumonarLavasVI, 2*1000, i) + elseif i == 0 then + for j, position in pairs(aggressiveLavasVI) do + local lava = Game.createMonster("Aggressive Lava", position) + end + addEvent(sumonarLavasVI, 15*1000, 5) + end + end +end + +local function sumonarFieryHearts() + local boss = false + local bossId + local contagemHearts = 0 + local positionCenter = Position(33712, 32303, 15) + local spectator = Game.getSpectators(positionCenter, false, false, 20, 20, 20, 20) + for _, creature in pairs(spectator) do + if creature:isMonster() then + if creature:getName():lower() == "the duke of the depths" then + boss = true + bossId = Creature(creature:getId()) + end + end + end + for _, heart in pairs(spectator) do + if heart:isMonster() then + if heart:getName():lower() == "fiery heart" then + contagemHearts = contagemHearts + 1 + end + end + end + if boss == true and contagemHearts == 0 then + for _, position in pairs(fieryHearts) do + Game.createMonster("Fiery Heart", position):registerEvent("fieryHearts") + end + local oldBossHealth = bossId:getHealth() + local oldBossPosition = bossId:getPosition() + bossId:remove() + local newBoss = Game.createMonster("the duke of the depths immortal", oldBossPosition, false, true) + if newBoss then + newBoss:registerEvent("fieryHearts") + newBoss:registerEvent("healFireDamage") + newBoss:addHealth(-(newBoss:getHealth() - oldBossHealth)) + end + end + if boss == true then + addEvent(sumonarFieryHearts, 40*1000) + end +end + +local function startMachines() +local random = math.random(1, 5) +local positionCenter = Position(33681, 32335, 15) +local spectator = Game.getSpectators(positionCenter, false, false, 20, 20, 20, 20) +local checagem = false + for _, monster in pairs(spectator) do + if monster:isMonster() then + if monster:getName():lower() == "the count of the core" then + checagem = true + addEvent(function() + for _, position in pairs(machinePositions[random]) do + local machineOff = Tile(position):getItemById(31724) + if machineOff then + machineOff:remove() + local machineOn = Game.createItem(31723, 1, position) + addEvent(function() + local a = machineOn:getPosition().y + 10 + local a_ = machineOn:getPosition().y - 10 + if random%2 ~= 0 then + for x = machineOn:getPosition().x, machineOn:getPosition().x do + for y = machineOn:getPosition().y + 1, a do + for z = machineOn:getPosition().z, machineOn:getPosition().z do + if Tile(Position(x, y, z)) then + if Tile(Position(x, y, z)) then + local sqm = Position(x, y, z) + local creature = Tile(Position(x, y, z)):getTopCreature() + local mwCheck = Tile(Position(x, y, z)):getItemById(1497) + local wildCheck = Tile(Position(x, y, z)):getItemById(1499) + if not (mwCheck or wildCheck) then + if creature then + if creature:isMonster() then + if creature:getName():lower() == "the count of the core" then + creature:addHealth(math.random(3000, 5000)) + end + elseif creature:isPlayer() then + creature:addHealth(-(math.random(0, 1500))) + end + end + sqm:sendMagicEffect(CONST_ME_HITBYFIRE) + else + a = machineOn:getPosition().y + end + end + end + end + end + end + else + for x = machineOn:getPosition().x, machineOn:getPosition().x do + for y = a_, machineOn:getPosition().y - 1 do + for z = machineOn:getPosition().z, machineOn:getPosition().z do + if Tile(Position(x, y, z)) then + if Tile(Position(x, y, z)) then + local sqm = Position(x, y, z) + local creature = Tile(Position(x, y, z)):getTopCreature() + local mwCheck = Tile(Position(x, y, z)):getItemById(1497) + local wildCheck = Tile(Position(x, y, z)):getItemById(1499) + if not (mwCheck or wildCheck) then + if creature then + if creature:isMonster() then + if creature:getName():lower() == "the count of the core" then + creature:addHealth(math.random(3000, 5000)) + end + elseif creature:isPlayer() then + creature:addHealth(-(math.random(0, 1500))) + end + end + sqm:sendMagicEffect(CONST_ME_HITBYFIRE) + else + a_ = machineOn:getPosition().y + end + end + end + end + end + end + end + addEvent(function() + if machineOn then + machineOn:transform(31724) + end + end, 1*1000) + end, 2*1000) + end + end + end, 6*1000) + end + end + end + if checagem == true then + addEvent(startMachines, 6*1000) + end +end + +local function summonBeasts(i) + local position = Position(randomarea) + if i >= 1 then + for j, position in pairs(beastPositions) do + position:sendMagicEffect(CONST_ME_TELEPORT) + end + i = i - 1 + addEvent(summonBeasts, 2*1000, i) + elseif i == 0 then + for j, position in pairs(beastPositions) do + local beast = Game.createMonster("Ember Beast", position) + end + end +end + +local function checarSala(qnt) + local temBoss = false + local hpBoss + local position = Position(33681, 32334, 15) + local spectators = Game.getSpectators(position, false, false, 20, 20, 20, 20) + for _, checagem in pairs(spectators) do + if checagem:isMonster() then + if checagem:getName():lower() == "the count of the core" then + temBoss = true + hpBoss = (checagem:getHealth()/checagem:getMaxHealth())*100 + end + end + end + local contagemBeast = 0 + for _, checagem2 in pairs(spectators) do + if checagem2:isMonster() then + if checagem2:getName():lower() == "ember beast" then + contagemBeast = contagemBeast + 1 + end + end + end + if temBoss == true then + if contagemBeast > 0 then + for _, spectator in pairs(spectators) do + if spectator:isMonster() then + if spectator:getName():lower() == "ember beast" then + if hpBoss < 70 then + qnt = qnt - 1 + spectator:remove() + for _, boss in pairs(spectators) do + if boss:isMonster() then + if boss:getName():lower() == "the count of the core" then + boss:say("The count absorbs he power of the beast and becomes stronger.", TALKTYPE_ORANGE_2) + boss:addHealth(math.random(0, 15000)) + end + end + end + break + end + end + end + end + if temBoss == true then + addEvent(checarSala, 60*1000, qnt) + end + end + end +end + +local function startWarzoneIV() + addEvent(function() + local monstro = Game.createMonster("The Baron From Below", Position(33648, 32303, 15)) + if monstro then + monstro:registerEvent("theBaronFromBelow") + end + addEvent(sumonarLavasIV, 15*1000, 5) + addEvent(lavaHoles, 15*1000, 1) + end, 10*1000) +end + +local function startWarzoneV() + addEvent(function() + local monstro = Game.createMonster("The Count Of The Core", Position(33681, 32334, 15)) + if monstro then + monstro:registerEvent("healFireDamage") + monstro:registerEvent("emberBeasts") + end + summonBeasts(5) + addEvent(startMachines, 10*1000) + addEvent(checarSala, 30*1000, 4) + end, 5*1000) +end + +local function startWarzoneVI() + addEvent(function() + local monstro = Game.createMonster("The Duke Of The Depths", Position(33712, 32303, 15)) + if monstro then + monstro:registerEvent("healFireDamage") + end + addEvent(sumonarFieryHearts, 30*1000) + addEvent(sumonarLavasVI, 15*1000, 5) + end, 10*1000) +end + +local dangerousDepthCrystals = Action() +function dangerousDepthCrystals.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if not player then + return true + end + + if not target:isItem() then + return false + end + + if target:isCreature() then + return false + end + + local WarzoneVI = Position(33274, 32316, 15) + local WarzoneIV = Position(33459, 32267, 15) + local WarzoneV = Position(33323, 32109, 15) + local geodeId = 30745 + local targetPosition = target:getPosition() + + if targetPosition == WarzoneIV and target:getId() == geodeId then -- Warzone 4 BOSS!!! + if Game.getStorageValue(GlobalStorage.DangerousDepths.Geodes.WarzoneIV) < 30 then + targetPosition:sendMagicEffect(CONST_ME_HITAREA) + item:remove(1) + if Game.getStorageValue(GlobalStorage.DangerousDepths.Geodes.WarzoneIV) < 0 then + Game.setStorageValue(GlobalStorage.DangerousDepths.Geodes.WarzoneIV, 0) + end + Game.setStorageValue(GlobalStorage.DangerousDepths.Geodes.WarzoneIV, Game.getStorageValue(GlobalStorage.DangerousDepths.Geodes.WarzoneIV) + 1) + if Game.getStorageValue(GlobalStorage.DangerousDepths.Geodes.WarzoneIV) == 30 then + local spectators = Game.getSpectators(targetPosition, false, true, 3, 3, 3, 3) + for _, spectator in pairs(spectators) do + if spectator:isPlayer() then + spectator:sendTextMessage(MESSAGE_EVENT_ADVANCE, "This crystal geode is shaking from a battle nearby.") + end + end + local stalagmites = Tile(Position(33460, 32267, 15)):getItemById(386) + if stalagmites then + stalagmites:remove() + local teleport = Game.createItem(1387, 1, Position(33460, 32267, 15)) + teleport:setActionId(57243) + addEvent(function() + if teleport then + teleport:remove(1) + Game.createItem(386, 1, Position(33460, 32267, 15)) + end + end, 8*1000) + addEvent(clearForgotten, 30*60*1000, Position(33638, 32291, 15), Position(33675, 32313, 15), Position(33462, 32267, 15), GlobalStorage.DangerousDepths.Geodes.WarzoneIV) + startWarzoneIV() + end + end + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The crystal geode can't carry any more crystals.") + end + end + + if targetPosition == WarzoneV and target:getId() == geodeId then -- Warzone 5 BOSS!!! + if Game.getStorageValue(GlobalStorage.DangerousDepths.Geodes.WarzoneV) < 30 then + targetPosition:sendMagicEffect(CONST_ME_HITAREA) + item:remove(1) + if Game.getStorageValue(GlobalStorage.DangerousDepths.Geodes.WarzoneV) < 0 then + Game.setStorageValue(GlobalStorage.DangerousDepths.Geodes.WarzoneV, 0) + end + Game.setStorageValue(GlobalStorage.DangerousDepths.Geodes.WarzoneV, Game.getStorageValue(GlobalStorage.DangerousDepths.Geodes.WarzoneV) + 1) + if Game.getStorageValue(GlobalStorage.DangerousDepths.Geodes.WarzoneV) == 30 then + local spectators = Game.getSpectators(targetPosition, false, true, 3, 3, 3, 3) + for _, spectator in pairs(spectators) do + if spectator:isPlayer() then + spectator:sendTextMessage(MESSAGE_EVENT_ADVANCE, "This crystal geode is shaking from a battle nearby.") + end + end + local stalagmites = Tile(Position(33324, 32109, 15)):getItemById(386) + if stalagmites then + stalagmites:remove() + local teleport = Game.createItem(1387, 1, Position(33324, 32109, 15)) + teleport:setActionId(57243) + addEvent(function() + if teleport then + teleport:remove(1) + Game.createItem(386, 1, Position(33324, 32109, 15)) + end + end, 8*1000) + addEvent(clearForgotten, 30*60*1000, Position(33668, 32310, 15), Position(33695, 32343, 15), Position(33323, 32111, 15), GlobalStorage.DangerousDepths.Geodes.WarzoneV) + startWarzoneV() + end + end + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The crystal geode can't carry any more crystals.") + end + end + + if targetPosition == WarzoneVI and target:getId() == geodeId then -- Warzone 6 BOSS!!! + if Game.getStorageValue(GlobalStorage.DangerousDepths.Geodes.WarzoneVI) < 30 then + targetPosition:sendMagicEffect(CONST_ME_HITAREA) + item:remove(1) + if Game.getStorageValue(GlobalStorage.DangerousDepths.Geodes.WarzoneVI) < 0 then + Game.setStorageValue(GlobalStorage.DangerousDepths.Geodes.WarzoneVI, 0) + end + Game.setStorageValue(GlobalStorage.DangerousDepths.Geodes.WarzoneVI, Game.getStorageValue(GlobalStorage.DangerousDepths.Geodes.WarzoneVI) + 1) + if Game.getStorageValue(GlobalStorage.DangerousDepths.Geodes.WarzoneVI) == 30 then + local spectators = Game.getSpectators(targetPosition, false, true, 3, 3, 3, 3) + for _, spectator in pairs(spectators) do + if spectator:isPlayer() then + spectator:sendTextMessage(MESSAGE_EVENT_ADVANCE, "This crystal geode is shaking from a battle nearby.") + end + end + local stalagmites = Tile(Position(33275, 32316, 15)):getItemById(386) + if stalagmites then + stalagmites:remove() + local teleport = Game.createItem(1387, 1, Position(33275, 32316, 15)) + teleport:setActionId(57243) + addEvent(function() + if teleport then + teleport:remove(1) + Game.createItem(386, 1, Position(33275, 32316, 15)) + end + end, 8*1000) + addEvent(clearForgotten, 30*60*1000, Position(33684, 32293, 15), Position(33724, 32314, 15), Position(33275, 32318, 15), GlobalStorage.DangerousDepths.Geodes.WarzoneVI) + startWarzoneVI() + end + end + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The crystal geode can't carry any more crystals.") + end + end + + return true +end + +dangerousDepthCrystals:id(31993) +dangerousDepthCrystals:register() diff --git a/data/scripts/actions/quests/dangerous_depth/warzone_crystals.lua b/data/scripts/actions/quests/dangerous_depth/warzone_crystals.lua new file mode 100644 index 00000000000..494ad8f2400 --- /dev/null +++ b/data/scripts/actions/quests/dangerous_depth/warzone_crystals.lua @@ -0,0 +1,74 @@ +local crystalDuration = 5 * 60 -- 5 minutes + +local crystals = { + -- Warzone IV + [57350] = Storage.DangerousDepths.Crystals.WarzoneVI.MediumCrystal1, + [57351] = Storage.DangerousDepths.Crystals.WarzoneVI.BigCrystal1, + [57352] = Storage.DangerousDepths.Crystals.WarzoneVI.BigCrystal2, + [57353] = Storage.DangerousDepths.Crystals.WarzoneVI.MediumCrystal2, + [57354] = Storage.DangerousDepths.Crystals.WarzoneVI.SmallCrystal1, + [57355] = Storage.DangerousDepths.Crystals.WarzoneVI.SmallCrystal2, + + -- Warzone V + [57356] = Storage.DangerousDepths.Crystals.WarzoneV.BigCrystal1, + [57357] = Storage.DangerousDepths.Crystals.WarzoneIV.MediumCrystal1, + [57358] = Storage.DangerousDepths.Crystals.WarzoneV.BigCrystal2, + [57359] = Storage.DangerousDepths.Crystals.WarzoneIV.MediumCrystal2, + [57360] = Storage.DangerousDepths.Crystals.WarzoneV.SmallCrystal1, + [57361] = Storage.DangerousDepths.Crystals.WarzoneV.SmallCrystal2, + + -- Warzone IV + [57362] = Storage.DangerousDepths.Crystals.WarzoneIV.BigCrystal1, + [57363] = Storage.DangerousDepths.Crystals.WarzoneIV.MediumCrystal1, + [57364] = Storage.DangerousDepths.Crystals.WarzoneIV.BigCrystal2, + [57365] = Storage.DangerousDepths.Crystals.WarzoneIV.MediumCrystal2, + [57366] = Storage.DangerousDepths.Crystals.WarzoneIV.SmallCrystal1, + [57367] = Storage.DangerousDepths.Crystals.WarzoneIV.SmallCrystal2, +} + +local crystalsChance = { + [30738] = 1, -- Large Crystal + [30740] = 5, -- Medium Crystal + [17017] = 5, -- Medium Crystal + [32405] = 7, -- Small Crystal +} + +local function createCrystal(crystalId, player) + local crystalChance = crystalsChance[crystalId] + if not crystalChance then + return false + end + + local chance = math.random(10) + local itemId = chance <= crystalChance and 18554 or 31993 + + local item = Game.createItem(itemId, 1) + local ret = player:addItemEx(item) + if ret ~= RETURNVALUE_NOERROR then + player:sendCancelMessage(Game.getReturnMessage(ret)) + return false + end + + return true +end + +local dangerousDepthWarzoneCrystals = Action() +function dangerousDepthWarzoneCrystals.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local crystalTimer = crystals[item:getActionId()] + if not crystalTimer or crystalTimer > os.time() then + return true + end + + local itemId = item:getId() + local crystal = createCrystal(itemId, player) + if crystal then + player:setStorageValue(crystalTimer, os.time() + crystalDuration) + end + + return true +end + +for value = 57350, 57367 do + dangerousDepthWarzoneCrystals:aid(value) +end +dangerousDepthWarzoneCrystals:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/dangerous_depth/wooden_trash.lua b/data/scripts/actions/quests/dangerous_depth/wooden_trash.lua new file mode 100644 index 00000000000..ca81247ebe2 --- /dev/null +++ b/data/scripts/actions/quests/dangerous_depth/wooden_trash.lua @@ -0,0 +1,32 @@ +local dangerousDepthWooden = Action() +function dangerousDepthWooden.onUse(creature, item) + if not creature or not creature:isPlayer() then + return true + end + local r = math.random(1, 100) + local stgValueP = creature:getStorageValue(Storage.DangerousDepths.Dwarves.Prisoners) + + if creature:getStorageValue(Storage.DangerousDepths.Dwarves.Home) == 1 and stgValueP < 3 then + if r <= 25 then + creature:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You started an escort, get your prisoner to the dwarf outpost!") + local prisoner = Game.createMonster("Captured Dwarf", item:getPosition()) + item:getPosition():sendMagicEffect(CONST_ME_POFF) + item:remove() + addEvent(function(pid) + local prisoner = Monster(pid) + if prisoner then + prisoner:getPosition():sendMagicEffect(CONST_ME_POFF) + prisoner:remove() + end + end, 5 * 60 * 1000, creatureid) + else + creature:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You find nothing of interest beneath the rubble.") + item:getPosition():sendMagicEffect(CONST_ME_POFF) + item:remove() + end + end + return true +end + +dangerousDepthWooden:aid(57233) +dangerousDepthWooden:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/dark_trails/corpse.lua b/data/scripts/actions/quests/dark_trails/corpse.lua new file mode 100644 index 00000000000..9b09c1103c1 --- /dev/null +++ b/data/scripts/actions/quests/dark_trails/corpse.lua @@ -0,0 +1,14 @@ +local darkCorpse = Action() + +function darkCorpse.onUse(player) + if player:getStorageValue(Storage.DarkTrails.Mission14) == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Quandon has been murdered! You should report to Sholley about it!.') + player:setStorageValue(Storage.DarkTrails.Mission14, 2) + elseif player:getStorageValue(Storage.DarkTrails.Mission14) == 2 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'This is empty!') + end + return true +end + +darkCorpse:uid(20001) +darkCorpse:register() diff --git a/data/scripts/actions/quests/dark_trails/lever_death_priest_shargon.lua b/data/scripts/actions/quests/dark_trails/lever_death_priest_shargon.lua new file mode 100644 index 00000000000..e4121320087 --- /dev/null +++ b/data/scripts/actions/quests/dark_trails/lever_death_priest_shargon.lua @@ -0,0 +1,71 @@ +local setting = { + centerRoom = {x = 33487, y = 32111, z = 9}, + range = 10, + playerPositions = { + {x = 33583, y = 31844, z = 10}, + {x = 33584, y = 31844, z = 10}, + {x = 33585, y = 31844, z = 10}, + {x = 33586, y = 31844, z = 10}, + {x = 33587, y = 31844, z = 10} + }, + newPositions = { + {x = 33486, y = 32120, z = 9}, + {x = 33486, y = 32120, z = 9}, + {x = 33486, y = 32120, z = 9}, + {x = 33486, y = 32120, z = 9}, + {x = 33486, y = 32120, z = 9} + }, + minionPositions = { + {x = 33482, y = 32105, z = 9}, + {x = 33484, y = 32105, z = 9}, + {x = 33484, y = 32107, z = 9}, + {x = 33481, y = 32109, z = 9}, + {x = 33482, y = 32111, z = 9}, + {x = 33488, y = 32106, z = 9}, + {x = 33490, y = 32106, z = 9}, + {x = 33492, y = 32109, z = 9}, + {x = 33492, y = 32112, z = 9}, + {x = 33490, y = 32112, z = 9} + } +} + +local leverDeathPriestShargon = Action() +function leverDeathPriestShargon.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 1945 then + if roomIsOccupied(setting.centerRoom, setting.range, setting.range) then + player:say("Someone is fighting against the boss! You need wait awhile.", TALKTYPE_MONSTER_SAY) + return true + end + + local storePlayers, playerTile = {} + for i = 1, #setting.playerPositions do + local creature = Tile(playerPositions[i]):getTopCreature() + if not creature or not creature:isPlayer() then + player:sendMessageCancel("You need 5 of players to fight with Death Priest Shargon.") + return true + end + storePlayers[#storePlayers + 1] = playerTile + end + + for i = 1, #config.minionPositions do + Game.createMonster("greater death minion", config.minionPositions[i]) + + end + Game.createMonster("death priest shargon", {x = 33487, y = 32108, z = 9}) + + local players + for i = 1, #storePlayers do + players = storePlayers[i] + config.playerPositions[i]:sendMagicEffect(CONST_ME_POFF) + players:teleportTo(config.newPositions[i]) + config.newPositions[i]:sendMagicEffect(CONST_ME_ENERGYAREA) + end + item:transform(1946) + elseif item.itemid == 1946 then + item:transform(1945) + end + return true +end + +leverDeathPriestShargon:uid(30002) +leverDeathPriestShargon:register() diff --git a/data/scripts/actions/quests/dark_trails/lever_the_ravager.lua b/data/scripts/actions/quests/dark_trails/lever_the_ravager.lua new file mode 100644 index 00000000000..a2306f56b54 --- /dev/null +++ b/data/scripts/actions/quests/dark_trails/lever_the_ravager.lua @@ -0,0 +1,63 @@ +local setting = { + centerRoom = {x = 33487, y = 32079, z = 8}, + range = 10, + playerPositions = { + Position(33417, 32102, 10), + Position(33418, 32102, 10), + Position(33419, 32102, 10), + Position(33420, 32102, 10) + }, + newPositions = { + Position(33487, 32088, 8), + Position(33487, 32088, 8), + Position(33487, 32088, 8), + Position(33487, 32088, 8) + }, + canopicJarPositions = { + Position(33486, 32081, 8), + Position(33488, 32081, 8), + Position(33486, 32083, 8), + Position(33488, 32083, 8) + } +} + +local leverTheRavager = Action() +function leverTheRavager.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 1945 then + if roomIsOccupied(setting.centerRoom, setting.range, setting.range) then + player:say("Someone is fighting against the boss! You need wait awhile.", TALKTYPE_MONSTER_SAY) + return true + end + + local storePlayers, playerTile = {} + for i = 1, #setting.playerPositions do + local creature = Tile(playerPositions[i]):getTopCreature() + if not creature or not creature:isPlayer() then + player:sendMessageCancel("You need 4 of players to fight with The Ravager.") + return true + end + storePlayers[#storePlayers + 1] = playerTile + end + + for i = 1, #setting.canopicJarPositions do + Game.createMonster("greater canopic jar", setting.canopicJarPositions[i]) + + end + Game.createMonster("the ravager", {x = 33487, y = 32108, z = 9}) + + local players + for i = 1, #storePlayers do + players = storePlayers[i] + setting.playerPositions[i]:sendMagicEffect(CONST_ME_POFF) + players:teleportTo(setting.newPositions[i]) + setting.newPositions[i]:sendMagicEffect(CONST_ME_ENERGYAREA) + end + item:transform(1946) + elseif item.itemid == 1946 then + item:transform(1945) + end + return true +end + +leverTheRavager:uid(30001) +leverTheRavager:register() diff --git a/data/scripts/actions/quests/dawnport/legion_helmet.lua b/data/scripts/actions/quests/dawnport/legion_helmet.lua new file mode 100644 index 00000000000..e8e60f58af7 --- /dev/null +++ b/data/scripts/actions/quests/dawnport/legion_helmet.lua @@ -0,0 +1,38 @@ +local sacrificialPosition = { + Position(32111, 31933, 8), + Position(32112, 31933, 8) +} + +local effectPosition = { + Position(32110, 31933, 8), + Position(32113, 31933, 8) +} + +local sacredSnake = Action() + +function sacredSnake.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 23838 then + for i = 1, #sacrificialPosition do + local tile = Tile(sacrificialPosition[i]) + if toPosition == sacrificialPosition[i] then + if player:getStorageValue(Storage.Quest.SanctuaryOfTheLizardGod.LizardGodTeleport) < 1 then + player:removeItem(23838, 1) + player:setStorageValue(Storage.Quest.SanctuaryOfTheLizardGod.LizardGodTeleport, 1) + player:say("The lizard god accepts your offer! You may enter the santuary!", TALKTYPE_MONSTER_SAY, false, player, toPosition) + toPosition:sendMagicEffect(CONST_ME_MORTAREA) + item:remove(1) + for i = 1, #effectPosition do + effectPosition[i]:sendMagicEffect(CONST_ME_FIREAREA) + end + else + player:say("You have already discovered this teleport.", TALKTYPE_MONSTER_SAY, false, player, toPosition) + end + return true + end + end + end + return true +end + +sacredSnake:id(23838) +sacredSnake:register() diff --git a/data/scripts/actions/quests/dawnport/the_rare_herb.lua b/data/scripts/actions/quests/dawnport/the_rare_herb.lua new file mode 100644 index 00000000000..8737b7f3ef7 --- /dev/null +++ b/data/scripts/actions/quests/dawnport/the_rare_herb.lua @@ -0,0 +1,17 @@ +local theRareHerb = Action() + +function theRareHerb.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local setting = ItemUnique[item.uid] + if setting then + if player:getStorageValue(Storage.Quest.Dawnport.TheRareHerb) == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You harvested some of the herb's flower buds. Bring them Morris for a reward.") + player:setStorageValue(Storage.Quest.Dawnport.TheRareHerb, 2) + else + return false + end + end + return true +end + +theRareHerb:uid(40027) +theRareHerb:register() diff --git a/data/scripts/actions/quests/dawnport/vocation_reward.lua b/data/scripts/actions/quests/dawnport/vocation_reward.lua new file mode 100644 index 00000000000..ee7f0012501 --- /dev/null +++ b/data/scripts/actions/quests/dawnport/vocation_reward.lua @@ -0,0 +1,130 @@ +local adventurersGuildText = [[ +Brave adventurer, + +the Adventurers' Guild bids you welcome as a new hero of the land. + +Take this adventurer's stone and use it in any city temple to instantly travel to our guild hall. If you should ever lose your adventurer's stone, you can replace it by talking to a priest in the temple. +I hope you will be visiting us soon. + +Kind regards, +Rotem, Head of the Adventurers' Guild +]] + +local reward = { + container = 1988, + commonItems = { + {id = 18559, amount = 1}, -- Adventurer's stone + -- Parchment + {id = 1953, amount = 1, text = adventurersGuildText} + }, + vocationItems = { + -- Sorcerer + [14025] = { + {id = 8820, amount = 1}, -- Mage hat + {id = 8819, amount = 1}, -- Magician's robe + {id = 2649, amount = 1}, -- Leather legs + {id = 2643, amount = 1}, -- Leather boots + {id = 2190, amount = 1}, -- Wand of vortex + {id = 2175, amount = 1} -- Spellbook + }, + -- Druid + [14026] = { + {id = 8820, amount = 1}, -- Mage hat + {id = 8819, amount = 1}, -- Magician's robe + {id = 2649, amount = 1}, -- Leather legs + {id = 2643, amount = 1}, -- Leather boots + {id = 2182, amount = 1}, -- Snakebite rod + {id = 2175, amount = 1} -- Spellbook + }, + -- Paladin + [14027] = { + {id = 2461, amount = 1}, -- Leader helmet + {id = 2660, amount = 1}, -- Ranger's cloak + {id = 8923, amount = 1}, -- Ranger legs + {id = 2643, amount = 1}, -- Leather boots + {id = 2456, amount = 1}, -- Bow + {id = 2389, amount = 1}, -- Spear + {id = 40397, amount = 1}, -- Quiver + {id = 2544, amount = 100} -- Arrows + }, + -- Knight + [14028] = { + {id = 2481, amount = 1}, -- Soldier helmet + {id = 2465, amount = 1}, -- Brass armor + {id = 2478, amount = 1}, -- Brass legs + {id = 2643, amount = 1}, -- Leather boots + {id = 8602, amount = 1}, -- Jagged sword + {id = 2509, amount = 1} -- Steel shield + } + } +} + +local vocationReward = Action() + +function vocationReward.onUse(player, item, fromPosition, itemEx, toPosition) + local vocationItems = reward.vocationItems[item.uid] + -- Check there is items for item.uid + if not vocationItems then + return true + end + -- Check quest storage + if player:getStorageValue(Storage.Quest.Dawnport.VocationReward) == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The " .. item:getName() .. " is empty.") + return true + end + -- Calculate reward weight + local rewardsWeight = ItemType(reward.container):getWeight() + for i = 1, #vocationItems do + rewardsWeight = rewardsWeight + (ItemType(vocationItems[i].id):getWeight() * vocationItems[i].amount) + end + for i = 1, #reward.commonItems do + rewardsWeight = rewardsWeight + (ItemType(reward.commonItems[i].id):getWeight() * reward.commonItems[i].amount) + end + -- Check if enough weight capacity + if player:getFreeCapacity() < rewardsWeight then + player:sendTextMessage( + MESSAGE_EVENT_ADVANCE, + "You have found a " .. getItemName(reward.container) .. + ". Weighing " .. (rewardsWeight / 100) .. " oz it is too heavy." + ) + return true + end + -- Check if enough free slots + if player:getFreeBackpackSlots() < 1 then + player:sendTextMessage( + MESSAGE_EVENT_ADVANCE, + "You have found a " .. getItemName(reward.container) .. ". There is no room." + ) + return true + end + -- Create reward container + local container = Game.createItem(reward.container) + -- Iterate in inverse order due on addItem/addItemEx by default its added at first index + -- Add common items + for i = #reward.commonItems, 1, -1 do + if reward.commonItems[i].text then + -- Create item to customize + local document = Game.createItem(reward.commonItems[i].id) + document:setAttribute(ITEM_ATTRIBUTE_TEXT, reward.commonItems[i].text) + container:addItemEx(document) + else + container:addItem(reward.commonItems[i].id, reward.commonItems[i].amount) + end + end + -- Add vocation items + for i = #vocationItems, 1, -1 do + container:addItem(vocationItems[i].id, vocationItems[i].amount) + end + -- Ensure reward was added properly to player + if player:addItemEx(container, false, CONST_SLOT_WHEREEVER) == RETURNVALUE_NOERROR then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a " .. container:getName() .. ".") + player:setStorageValue(Storage.Quest.Dawnport.VocationReward, 1) + end + return true +end + +for index, value in pairs(reward.vocationItems) do + vocationReward:uid(index) +end + +vocationReward:register() diff --git a/data/scripts/actions/quests/deepling_worldchange/boxramp.lua b/data/scripts/actions/quests/deepling_worldchange/boxramp.lua new file mode 100644 index 00000000000..eb2f1854787 --- /dev/null +++ b/data/scripts/actions/quests/deepling_worldchange/boxramp.lua @@ -0,0 +1,14 @@ +local boxRamp = Action() + +function boxRamp.onUse(player, item, frompos, item2, topos) + if player:getStorageValue(Storage.DeeplingsWorldChange.Crystal) == 12 then + player:removeItem(15568, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Clonk.") + player:setStorageValue(Storage.DeeplingsWorldChange.Crystal, 13) + return true + end + return false +end + +boxRamp:uid(1106) +boxRamp:register() diff --git a/data/scripts/actions/quests/deepling_worldchange/coral.lua b/data/scripts/actions/quests/deepling_worldchange/coral.lua new file mode 100644 index 00000000000..931ba2d3d3a --- /dev/null +++ b/data/scripts/actions/quests/deepling_worldchange/coral.lua @@ -0,0 +1,21 @@ +local crystaldeepling = Action() +function crystaldeepling.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local posMonster = player:getPosition() + if player:getStorageValue(Storage.DeeplingsWorldChange.Crystal) == 9 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"Suddenly a guard jumps at you from behind!") + Game.createMonster("Deepling Worker", posMonster) + player:setStorageValue(Storage.DeeplingsWorldChange.Crystal, 10) + elseif player:getStorageValue(Storage.DeeplingsWorldChange.Crystal) == 10 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"Fail.") + player:setStorageValue(Storage.DeeplingsWorldChange.Crystal, 11) + elseif player:getStorageValue(Storage.DeeplingsWorldChange.Crystal) == 11 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"Yeah.") + player:addItem(15568, 1) + player:setStorageValue(Storage.DeeplingsWorldChange.Crystal, 12) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"Sorry.") + end + return true +end +crystaldeepling:aid(28572) +crystaldeepling:register() diff --git a/data/scripts/actions/quests/deepling_worldchange/crystal.lua b/data/scripts/actions/quests/deepling_worldchange/crystal.lua new file mode 100644 index 00000000000..b4129242b46 --- /dev/null +++ b/data/scripts/actions/quests/deepling_worldchange/crystal.lua @@ -0,0 +1,21 @@ +local crystaldeepling = Action() +function crystaldeepling.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local posMonster = player:getPosition() + if player:getStorageValue(Storage.DeeplingsWorldChange.Crystal) == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"Suddenly a guard jumps at you from behind!") + Game.createMonster("Deepling Guard", posMonster) + player:setStorageValue(Storage.DeeplingsWorldChange.Crystal, 2) + elseif player:getStorageValue(Storage.DeeplingsWorldChange.Crystal) == 2 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You gathered nothing more than some small chips of red gem.") + player:setStorageValue(Storage.DeeplingsWorldChange.Crystal, 3) + elseif player:getStorageValue(Storage.DeeplingsWorldChange.Crystal) == 3 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"With considerable effort you manage to knock a largely unscathed rough gem out of the rocks.") + player:addItem(15565, 1) + player:setStorageValue(Storage.DeeplingsWorldChange.Crystal, 4) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"Sorry.") + end + return true +end +crystaldeepling:aid(28570) +crystaldeepling:register() diff --git a/data/scripts/actions/quests/deepling_worldchange/crystalvortex.lua b/data/scripts/actions/quests/deepling_worldchange/crystalvortex.lua new file mode 100644 index 00000000000..389cbc89a6a --- /dev/null +++ b/data/scripts/actions/quests/deepling_worldchange/crystalvortex.lua @@ -0,0 +1,13 @@ +local crystalvortex = Action() +function crystalvortex.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.DeeplingsWorldChange.Crystal) == 4 then + if table.contains({15560}, target.itemid) then + player:removeItem(15565, 1) + player:addItem(15431, 1) + player:setStorageValue(Storage.DeeplingsWorldChange.Crystal, 5) + end + end + return true +end +crystalvortex:id(15565) +crystalvortex:register() diff --git a/data/scripts/actions/quests/deepling_worldchange/golden_anchor.lua b/data/scripts/actions/quests/deepling_worldchange/golden_anchor.lua new file mode 100644 index 00000000000..53793f8f2a8 --- /dev/null +++ b/data/scripts/actions/quests/deepling_worldchange/golden_anchor.lua @@ -0,0 +1,21 @@ + +local anchorIds = {15358, 15359} +local navigatorNpc = Position(33640, 31379, 9) +local goldenAnchorTeleport = Action() + +function goldenAnchorTeleport.onUse(creature, item, fromPosition, target, toPosition, isHotkey) + if not creature:isPlayer() then + return + end + + if target and table.contains(anchorIds, target.itemid) then + creature:teleportTo(navigatorNpc) + navigatorNpc:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + return true +end + +goldenAnchorTeleport:id(15432) +goldenAnchorTeleport:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/deepling_worldchange/questfirst.lua b/data/scripts/actions/quests/deepling_worldchange/questfirst.lua new file mode 100644 index 00000000000..3378bd94d5e --- /dev/null +++ b/data/scripts/actions/quests/deepling_worldchange/questfirst.lua @@ -0,0 +1,14 @@ +local questFirst = Action() + +function questFirst.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.DeeplingsWorldChange.Crystal) == 7 then + player:addItem(2152, 10) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a reward.") + player:setStorageValue(Storage.DeeplingsWorldChange.Crystal, 8) + return true + end + return false +end + +questFirst:uid(1105) +questFirst:register() diff --git a/data/scripts/actions/quests/deepling_worldchange/statue.lua b/data/scripts/actions/quests/deepling_worldchange/statue.lua new file mode 100644 index 00000000000..adb8bfc28c6 --- /dev/null +++ b/data/scripts/actions/quests/deepling_worldchange/statue.lua @@ -0,0 +1,13 @@ +local statuegod = Action() +function statuegod.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.DeeplingsWorldChange.Crystal) == 6 then + if table.contains({15254}, target.itemid) then + player:removeItem(15431, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You carefully insert the blood red gem but it would take a hundred hearts to replace the original.") + player:setStorageValue(Storage.DeeplingsWorldChange.Crystal, 6) + end + end + return true +end +statuegod:id(15431) +statuegod:register() diff --git a/data/scripts/actions/quests/demon_oak/demon_oak.lua b/data/scripts/actions/quests/demon_oak/demon_oak.lua new file mode 100644 index 00000000000..57dde05032b --- /dev/null +++ b/data/scripts/actions/quests/demon_oak/demon_oak.lua @@ -0,0 +1,132 @@ +local config = { + demonOakIds = {8288, 8289, 8290, 8291}, + sounds = { + 'MY ROOTS ARE SHARP AS A SCYTHE! FEEL IT?!?', + 'CURSE YOU!', + 'RISE, MINIONS, RISE FROM THE DEAD!!!!', + 'AHHHH! YOUR BLOOD MAKES ME STRONG!', + 'GET THE BONES, HELLHOUND! GET THEM!!', + 'GET THERE WHERE I CAN REACH YOU!!!', + 'ETERNAL PAIN AWAITS YOU! NICE REWARD, HUH?!?!', + 'YOU ARE GOING TO PAY FOR EACH HIT WITH DECADES OF TORTURE!!', + 'ARGG! TORTURE IT!! KILL IT SLOWLY MY MINION!!' + }, + bonebeastChance = 90, + bonebeastCount = 4, + waves = 10, + questArea = { + fromPosition = {x = 32706, y = 32345, z = 7}, + toPosition = {x = 32725, y = 32357, z = 7} + }, + summonPositions = { + {x = 32714, y = 32348, z = 7}, + {x = 32712, y = 32349, z = 7}, + {x = 32711, y = 32351, z = 7}, + {x = 32713, y = 32354, z = 7}, + {x = 32716, y = 32354, z = 7}, + {x = 32719, y = 32354, z = 7}, + {x = 32721, y = 32351, z = 7}, + {x = 32719, y = 32348, z = 7} + }, + summons = { + [8288] = { + [5] = {'Spectre', 'Blightwalker', 'Braindeath', 'Demon'}, + [10] = {'Betrayed Wraith', 'Betrayed Wraith'} + }, + [8289] = { + [5] = {'Plaguesmith', 'Plaguesmith', 'Blightwalker'}, + [10] = {'Dark Torturer', 'Blightwalker'} + }, + [8290] = { + [5] = {'Banshee', 'Plaguesmith', 'Hellhound'}, + [10] = {'Grim Reaper'} + }, + [8291] = { + [5] = {'Plaguesmith', 'Hellhound', 'Hellhound'}, + [10] = {'Undead Dragon', 'Hand of Cursed Fate'} + } + }, + storages = { + [8288] = Storage.DemonOak.AxeBlowsBird, + [8289] = Storage.DemonOak.AxeBlowsLeft, + [8290] = Storage.DemonOak.AxeBlowsRight, + [8291] = Storage.DemonOak.AxeBlowsFace + } +} + +local function getRandomSummonPosition() + return config.summonPositions[math.random(#config.summonPositions)] +end + +local demonOak = Action() +function demonOak.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if not isInArray(config.demonOakIds, target.itemid) then + return true + end + + local totalProgress = 0 + for k,v in pairs(config.storages) do + totalProgress = totalProgress + math.max(0, player:getStorageValue(v)) + end + + local spectators, hasMonsters = Game.getSpectators(DEMON_OAK_POSITION, false, false, 9, 9, 6, 6), false + for i = 1, #spectators do + if spectators[i]:isMonster() then + hasMonsters = true + break + end + end + + local isDefeated = totalProgress == (#config.demonOakIds * (config.waves + 1)) + if (config.killAllBeforeCut or isDefeated) + and hasMonsters then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You need to kill all monsters first.') + return true + end + + if isDefeated then + player:teleportTo(DEMON_OAK_KICK_POSITION) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Tell Oldrak about your great victory against the demon oak.') + player:setStorageValue(Storage.DemonOak.Done, 1) + player:setStorageValue(Storage.DemonOak.Progress, 3) + return true + end + + local cStorage = config.storages[target.itemid] + local progress = math.max(player:getStorageValue(cStorage), 1) + if progress >= config.waves + 1 then + toPosition:sendMagicEffect(CONST_ME_POFF) + return true + end + + local isLastCut = totalProgress == (#config.demonOakIds * (config.waves + 1) - 1) + local summons = config.summons[target.itemid] + if summons and summons[progress] then + -- Summon a single demon on the last hit + if isLastCut then + Game.createMonster('Demon', getRandomSummonPosition(), false, true) + + -- Summon normal monsters otherwise + else + for i = 1, #summons[progress] do + Game.createMonster(summons[progress][i], getRandomSummonPosition(), false, true) + end + end + + -- if it is not the 5th or 10th there is only a chance to summon bonebeasts + elseif math.random(100) >= config.bonebeastChance then + for i = 1, config.bonebeastCount do + Game.createMonster('Bonebeast', getRandomSummonPosition(), false, true) + end + end + + player:say(isLastCut and 'HOW IS THAT POSSIBLE?!? MY MASTER WILL CRUSH YOU!! AHRRGGG!' or config.sounds[math.random(#config.sounds)], TALKTYPE_MONSTER_YELL, false, player, DEMON_OAK_POSITION) + toPosition:sendMagicEffect(CONST_ME_DRAWBLOOD) + player:setStorageValue(cStorage, progress + 1) + player:say('-krrrrak-', TALKTYPE_MONSTER_YELL, false, player, toPosition) + doTargetCombatHealth(0, player, COMBAT_EARTHDAMAGE, -170, -210, CONST_ME_BIGPLANTS) + return true +end + +demonOak:id(8293) +demonOak:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/demon_oak/demon_oak_chest.lua b/data/scripts/actions/quests/demon_oak/demon_oak_chest.lua new file mode 100644 index 00000000000..30aac0e0652 --- /dev/null +++ b/data/scripts/actions/quests/demon_oak/demon_oak_chest.lua @@ -0,0 +1,30 @@ +local chests = { + [1002] = {itemid = 2495, count = 1}, + [1003] = {itemid = 8905, count = 1}, + [1004] = {itemid = 16111, count = 1}, + [1005] = {itemid = 16112, count = 1} +} + +local demonOakChest = Action() +function demonOakChest.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if chests[item.uid] then + if player:getStorageValue(Storage.DemonOak.Done) ~= 2 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'It\'s empty.') + return true + end + + local chest = chests[item.uid] + local itemType = ItemType(chest.itemid) + if itemType then + local article = itemType:getArticle() + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have found ' .. (#article > 0 and article .. ' ' or '') .. itemType:getName() .. '.') + end + + player:addItem(chest.itemid, chest.count) + player:setStorageValue(Storage.DemonOak.Done, 3) + end + return true +end + +demonOakChest:uid(1002, 1003, 1004, 1005) +demonOakChest:register() diff --git a/data/scripts/actions/quests/demon_oak/demon_oak_gravestone.lua b/data/scripts/actions/quests/demon_oak/demon_oak_gravestone.lua new file mode 100644 index 00000000000..2a3bb33fd0c --- /dev/null +++ b/data/scripts/actions/quests/demon_oak/demon_oak_gravestone.lua @@ -0,0 +1,11 @@ +local demonOakGrave = Action() +function demonOakGrave.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.DemonOak.Done) == 2 then + player:teleportTo(DEMON_OAK_REWARDROOM_POSITION) + DEMON_OAK_REWARDROOM_POSITION:sendMagicEffect(CONST_ME_TELEPORT) + return true + end +end + +demonOakGrave:uid(1001) +demonOakGrave:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/devil_helmet/lever.lua b/data/scripts/actions/quests/devil_helmet/lever.lua new file mode 100644 index 00000000000..c1f08dcb5db --- /dev/null +++ b/data/scripts/actions/quests/devil_helmet/lever.lua @@ -0,0 +1,19 @@ +local removePositions = { + fromPos = 32593, + toPos = 32601 +} + +local closeId = 1025 +local devilHelmetLever = Action() +function devilHelmetLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + item:remove(1) + Game.createItem(closeId, 1, Position(32592, 32105, 14)) + Game.createItem(closeId, 1, Position(32592, 32106, 14)) + for i = removePositions.fromPos, removePositions.toPos do + Tile(i, 32104, 14):getItemById(1026):remove() + end + return true +end + +devilHelmetLever:aid(20594) +devilHelmetLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/dreamer_challenge/documents.lua b/data/scripts/actions/quests/dreamer_challenge/documents.lua new file mode 100644 index 00000000000..7c4896f3523 --- /dev/null +++ b/data/scripts/actions/quests/dreamer_challenge/documents.lua @@ -0,0 +1,67 @@ +local config = { + [7844] = { + [1] = {female = 269, male = 268, msg = 'nightmare'}, + [2] = {female = 279, male = 278, msg = 'brotherhood'} + }, + [7845] = { + [1] = {female = 269, male = 268, addon = 1, msg = 'first nightmare'}, + [2] = {female = 279, male = 278, addon = 1, msg = 'first brotherhood'}, + storageValue = 2 + }, + [7846] = { + [1] = {female = 269, male = 268, addon = 2, msg = 'second nightmare'}, + [2] = {female = 279, male = 278, addon = 2, msg = 'second brotherhood'}, + storageValue = 3 + } +} + +local dreamerDocuments = Action() +function dreamerDocuments.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local useItem = config[item.itemid] + if not useItem then + return true + end + + local choice = useItem[1] + if player:getStorageValue(Storage.OutfitQuest.BrotherhoodOutfit) > player:getStorageValue(Storage.OutfitQuest.NightmareOutfit) then + choice = useItem[2] + end + + if choice.addon then + if player:hasOutfit(player:getSex() == PLAYERSEX_FEMALE and choice.female or choice.male) then + if not player:hasOutfit(player:getSex() == PLAYERSEX_FEMALE and choice.female or choice.male, choice.addon) then + if player:getStorageValue(Storage.OutfitQuest.NightmareOutfit) >= useItem.storageValue or player:getStorageValue(Storage.OutfitQuest.BrotherhoodOutfit) >= useItem.storageValue then + player:addOutfitAddon(choice.female, choice.addon) + player:addOutfitAddon(choice.male, choice.addon) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have received the ' .. choice.msg .. ' addon!') + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + item:remove(1) + else + return false + end + else + player:sendCancelMessage('You have already obtained this addon!') + end + else + return false + end + else + if not player:hasOutfit(player:getSex() == PLAYERSEX_FEMALE and choice.female or choice.male) then + if player:getStorageValue(Storage.OutfitQuest.NightmareOutfit) >= 1 or player:getStorageValue(Storage.OutfitQuest.BrotherhoodOutfit) >= 1 then + player:addOutfit(choice.female) + player:addOutfit(choice.male) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have received the ' .. choice.msg .. ' outfit!') + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + item:remove(1) + else + return false + end + else + player:sendCancelMessage('You have already obtained this outfit!') + end + end + return true +end + +dreamerDocuments:id(7844,7845,7846) +dreamerDocuments:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/dreamer_challenge/lever_brotherhood.lua b/data/scripts/actions/quests/dreamer_challenge/lever_brotherhood.lua new file mode 100644 index 00000000000..c4612c6ade4 --- /dev/null +++ b/data/scripts/actions/quests/dreamer_challenge/lever_brotherhood.lua @@ -0,0 +1,77 @@ +local config = { + [1] = {uid = 3045, position = Position(32784, 32222, 14), itemId = 7844, storageOutfit = 2}, + [2] = {uid = 3046, position = Position(32785, 32230, 14), itemId = 7846, storageOutfit = 3}, + [3] = {uid = 3047, position = Position(32781, 32226, 14), itemId = 7845, storageOutfit = 4} +} + +local function revertLever(position) + local leverItem = Tile(position):getItemById(1946) + if leverItem then + leverItem:transform(1945) + end +end + +local dreamerBrotherhoodLever = Action() +function dreamerBrotherhoodLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid ~= 1945 then + return true + end + if item.uid == config[1].uid then + local diamondItem = Tile(config[1].position):getItemById(2145) + if player:getStorageValue(Storage.OutfitQuest.BrotherhoodOutfit) >= config[1].storageOutfit then + if diamondItem and player:getStorageValue(Storage.DreamersChallenge.LeverBrotherhood1) < 1 then + diamondItem:remove(1) + player:setStorageValue(Storage.DreamersChallenge.LeverBrotherhood1, 1) + config[1].position:sendMagicEffect(CONST_ME_TELEPORT) + Game.createItem(config[1].itemId, 1, config[1].position) + item:transform(1946) + addEvent(revertLever, 4 * 1000, toPosition) + elseif not diamondItem and player:getStorageValue(Storage.DreamersChallenge.LeverBrotherhood1) < 1 then + player:sendCancelMessage('You need to offer a small diamond.') + else + player:sendCancelMessage('You have already used this lever!') + end + else + player:sendCancelMessage('You still don\'t have permission.') + end + elseif item.uid == config[2].uid then + if player:getStorageValue(Storage.OutfitQuest.BrotherhoodOutfit) >= config[2].storageOutfit then + local diamondItem = Tile(config[2].position):getItemById(2145) + if diamondItem and player:getStorageValue(Storage.DreamersChallenge.LeverBrotherhood2) < 1 then + diamondItem:remove(1) + player:setStorageValue(Storage.DreamersChallenge.LeverBrotherhood2, 1) + config[2].position:sendMagicEffect(CONST_ME_TELEPORT) + Game.createItem(config[2].itemId, 1, config[2].position) + item:transform(1946) + addEvent(revertLever, 4 * 1000, toPosition) + elseif not diamondItem and player:getStorageValue(Storage.DreamersChallenge.LeverBrotherhood2) < 1 then + player:sendCancelMessage('You need to offer a small diamond.') + else + player:sendCancelMessage('You have already used this lever!') + end + else + player:sendCancelMessage('You still don\'t have permission.') + end + elseif item.uid == config[3].uid then + if player:getStorageValue(Storage.OutfitQuest.BrotherhoodOutfit) >= config[3].storageOutfit then + local diamondItem = Tile(config[3].position):getItemById(2145) + if diamondItem and player:getStorageValue(Storage.DreamersChallenge.LeverBrotherhood3) < 1 then + diamondItem:remove(1) + player:setStorageValue(Storage.DreamersChallenge.LeverBrotherhood3, 1) + config[3].position:sendMagicEffect(CONST_ME_TELEPORT) + Game.createItem(config[3].itemId, 1, config[3].position) + item:transform(1946) + addEvent(revertLever, 4 * 1000, toPosition) + elseif not diamondItem and player:getStorageValue(Storage.DreamersChallenge.LeverBrotherhood3) < 1 then + player:sendCancelMessage('You need to offer a small diamond.') + else + player:sendCancelMessage('You have already used this lever!') + end + else + player:sendCancelMessage('You still don\'t have permission.') + end + end +end + +dreamerBrotherhoodLever:uid(3045,3046,3047) +dreamerBrotherhoodLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/dreamer_challenge/lever_nightmare.lua b/data/scripts/actions/quests/dreamer_challenge/lever_nightmare.lua new file mode 100644 index 00000000000..68e878b3d50 --- /dev/null +++ b/data/scripts/actions/quests/dreamer_challenge/lever_nightmare.lua @@ -0,0 +1,77 @@ +local config = { + [1] = {uid = 3041, position = Position(32836, 32221, 14), itemId = 7844, storageOutfit = 2}, + [2] = {uid = 3042, position = Position(32837, 32229, 14), itemId = 7846, storageOutfit = 3}, + [3] = {uid = 3043, position = Position(32833, 32225, 14), itemId = 7845, storageOutfit = 4} +} + +local function revertLever(position) + local leverItem = Tile(position):getItemById(1946) + if leverItem then + leverItem:transform(1945) + end +end + +local dreamerNightmareLever = Action() +function dreamerNightmareLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid ~= 1945 then + return true + end + if item.uid == config[1].uid then + local diamondItem = Tile(config[1].position):getItemById(2145) + if player:getStorageValue(Storage.OutfitQuest.BrotherhoodOutfit) >= config[1].storageOutfit then + if diamondItem and player:getStorageValue(Storage.DreamersChallenge.LeverNightmare1) < 1 then + diamondItem:remove(1) + player:setStorageValue(Storage.DreamersChallenge.LeverNightmare1, 1) + config[1].position:sendMagicEffect(CONST_ME_TELEPORT) + Game.createItem(config[1].itemId, 1, config[1].position) + item:transform(1946) + addEvent(revertLever, 4 * 1000, toPosition) + elseif not diamondItem and player:getStorageValue(Storage.DreamersChallenge.LeverNightmare1) < 1 then + player:sendCancelMessage('You need to offer a small diamond.') + else + player:sendCancelMessage('You have already used this lever!') + end + else + player:sendCancelMessage('You still don\'t have permission.') + end + elseif item.uid == config[2].uid then + if player:getStorageValue(Storage.OutfitQuest.BrotherhoodOutfit) >= config[2].storageOutfit then + local diamondItem = Tile(config[2].position):getItemById(2145) + if diamondItem and player:getStorageValue(Storage.DreamersChallenge.LeverNightmare1) < 1 then + diamondItem:remove(1) + player:setStorageValue(Storage.DreamersChallenge.LeverNightmare1, 1) + config[2].position:sendMagicEffect(CONST_ME_TELEPORT) + Game.createItem(config[2].itemId, 1, config[2].position) + item:transform(1946) + addEvent(revertLever, 4 * 1000, toPosition) + elseif not diamondItem and player:getStorageValue(Storage.DreamersChallenge.LeverNightmare1) < 1 then + player:sendCancelMessage('You need to offer a small diamond.') + else + player:sendCancelMessage('You have already used this lever!') + end + else + player:sendCancelMessage('You still don\'t have permission.') + end + elseif item.uid == config[3].uid then + if player:getStorageValue(Storage.OutfitQuest.BrotherhoodOutfit) >= config[3].storageOutfit then + local diamondItem = Tile(config[3].position):getItemById(2145) + if diamondItem and player:getStorageValue(Storage.DreamersChallenge.LeverNightmare3) < 1 then + diamondItem:remove(1) + player:setStorageValue(Storage.DreamersChallenge.LeverNightmare3, 1) + config[3].position:sendMagicEffect(CONST_ME_TELEPORT) + Game.createItem(config[3].itemId, 1, config[3].position) + item:transform(1946) + addEvent(revertLever, 4 * 1000, toPosition) + elseif not diamondItem and player:getStorageValue(Storage.DreamersChallenge.LeverNightmare3) < 1 then + player:sendCancelMessage('You need to offer a small diamond.') + else + player:sendCancelMessage('You have already used this lever!') + end + else + player:sendCancelMessage('You still don\'t have permission.') + end + end +end + +dreamerNightmareLever:uid(3041,3042,3043) +dreamerNightmareLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/dreamer_challenge/stone_teleport.lua b/data/scripts/actions/quests/dreamer_challenge/stone_teleport.lua new file mode 100644 index 00000000000..b0afa58afa0 --- /dev/null +++ b/data/scripts/actions/quests/dreamer_challenge/stone_teleport.lua @@ -0,0 +1,77 @@ +local config = { + [1945] = { + sacrifices = { + {position = Position(32878, 32270, 14), itemId = 2016}, + {position = Position(32881, 32267, 14), itemId = 2168}, + {position = Position(32881, 32273, 14), itemId = 6300}, + {position = Position(32884, 32270, 14), itemId = 1500} -- or itemID = 1487 for PVP servers + }, + wells = { + {position = Position(32874, 32263, 14), wellId = 3729, transformId = 3733}, + {position = Position(32875, 32263, 14), wellId = 3730, transformId = 3734}, + {position = Position(32874, 32264, 14), wellId = 3731, transformId = 3735}, + {position = Position(32875, 32264, 14), wellId = 3732, transformId = 3736} + } + }, + [1946] = { + wells = { + {position = Position(32874, 32263, 14), wellId = 3733, transformId = 3729}, + {position = Position(32875, 32263, 14), wellId = 3734, transformId = 3730}, + {position = Position(32874, 32264, 14), wellId = 3735, transformId = 3731}, + {position = Position(32875, 32264, 14), wellId = 3736, transformId = 3732} + } + } +} + +local dreamerStone = Action() +function dreamerStone.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local lever = config[item.itemid] + if not lever then + return true + end + + item:transform(item.itemid == 1945 and 1946 or 1945) + + local wellItem + for i = 1, #lever.wells do + wellItem = Tile(lever.wells[i].position):getItemById(lever.wells[i].wellId) + if wellItem then + wellItem:transform(lever.wells[i].transformId) + end + end + + if lever.sacrifices then + local sacrificeItems, sacrificeItem = true + for i = 1, #lever.sacrifices do + sacrificeItem = Tile(lever.sacrifices[i].position):getItemById(lever.sacrifices[i].itemId) + if not sacrificeItem then + sacrificeItems = false + break + elseif sacrificeItem then + sacrificeItem:remove() + end + end + + if not sacrificeItems then + return true + end + + local stonePosition = Position(32881, 32270, 14) + local stoneItem = Tile(stonePosition):getItemById(1355) + if stoneItem then + stoneItem:remove() + end + + local teleportExists = Tile(stonePosition):getItemById(1387) + if not teleportExists then + local newItem = Game.createItem(1387, 1, stonePosition) + if newItem then + newItem:setActionId(9031) + end + end + end + return true +end + +dreamerStone:uid(2004) +dreamerStone:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/dreamer_challenge/tic_tac.lua b/data/scripts/actions/quests/dreamer_challenge/tic_tac.lua new file mode 100644 index 00000000000..7668ad83a67 --- /dev/null +++ b/data/scripts/actions/quests/dreamer_challenge/tic_tac.lua @@ -0,0 +1,23 @@ +local dreamerTicTac = Action() +function dreamerTicTac.onUse(player, item, fromPosition, target, toPosition, isHotkey) + item:transform(item.itemid == 1945 and 1946 or 1945) + + if item.itemid ~= 1945 then + return true + end + + local position = {x = 32838, y = 32264, z = 14} + if player:getStorageValue(Storage.DreamersChallenge.TicTac) < 1 then + player:setStorageValue(Storage.DreamersChallenge.TicTac, 1) + Game.createItem(2638, 8, position) + Game.createItem(2639, 12, {x = 32839, y = 32263, z = 14}) + position:sendMagicEffect(CONST_ME_MAGIC_BLUE) + return true + else + player:say("You have used and can not use more.", TALKTYPE_ORANGE_1) + end + return true +end + +dreamerTicTac:uid(2272) +dreamerTicTac:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/dreamer_challenge/tic_tac_teleport.lua b/data/scripts/actions/quests/dreamer_challenge/tic_tac_teleport.lua new file mode 100644 index 00000000000..51ea6070ab6 --- /dev/null +++ b/data/scripts/actions/quests/dreamer_challenge/tic_tac_teleport.lua @@ -0,0 +1,68 @@ +local config = { + {position = Position(32845, 32264, 14), itemId = 2639}, + {position = Position(32843, 32266, 14), itemId = 2639}, + {position = Position(32843, 32268, 14), itemId = 2639}, + {position = Position(32845, 32268, 14), itemId = 2639}, + {position = Position(32844, 32267, 14), itemId = 2639}, + {position = Position(32840, 32269, 14), itemId = 2639}, + {position = Position(32841, 32269, 14), itemId = 2638}, + {position = Position(32840, 32268, 14), itemId = 2638}, + {position = Position(32842, 32267, 14), itemId = 2638} +} + +local dreamerTicTacTeleport = Action() +function dreamerTicTacTeleport.onUse(player, item, fromPosition, target, toPosition, isHotkey) + item:transform(item.itemid == 1945 and 1946 or 1945) + + iterateArea( + function(position) + local pillar = Tile(position):getItemById(1515) + if pillar then + pillar:remove() + else + Game.createItem(1515, 1, position) + end + end, + Position(32835, 32285, 14), + Position(32838, 32285, 14) + ) + + local tokens, ticTacToeItem = true + for i = 1, #config do + ticTacToeItem = Tile(config[i].position):getItemById(config[i].itemId) + if not ticTacToeItem then + tokens = false + break + end + end + + if not tokens then + return true + end + + local position = Position(32836, 32288, 14) + if item.itemid == 1945 then + local crack = Tile(position):getItemById(6299) + if crack then + crack:remove() + + local teleport = Game.createItem(1387, 1, position) + if teleport then + teleport:setActionId(9032) + end + end + + else + + local teleport = Tile(position):getItemById(1387) + if teleport then + teleport:remove() + Game.createItem(6299, 1, position) + end + end + + return true +end + +dreamerTicTacTeleport:aid(8033) +dreamerTicTacTeleport:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/dreamer_challenge/walls.lua b/data/scripts/actions/quests/dreamer_challenge/walls.lua new file mode 100644 index 00000000000..2f5890f5873 --- /dev/null +++ b/data/scripts/actions/quests/dreamer_challenge/walls.lua @@ -0,0 +1,65 @@ +local config = { + [2246] = { + [1] = {pos = Position(32763, 32292, 14), id = 1026}, + [2] = {pos = Position(32762, 32292, 14), id = 1026}, + [3] = {pos = Position(32761, 32292, 14), id = 1026} + }, + [2247] = { + [1] = {pos = Position(32760, 32289, 14), id = 1025}, + [2] = {pos = Position(32760, 32290, 14), id = 1025}, + [3] = {pos = Position(32760, 32291, 14), id = 1025}, + [4] = {pos = Position(32760, 32292, 14), id = 1030} + }, + [2248] = { + [1] = {pos = Position(32764, 32292, 14), id = 1029}, + [2] = {pos = Position(32764, 32291, 14), id = 1025}, + [3] = {pos = Position(32764, 32290, 14), id = 1025}, + [4] = {pos = Position(32764, 32289, 14), id = 1025} + }, + [2249] = { + [1] = {pos = Position(32760, 32288, 14), id = 1027}, + [2] = {pos = Position(32761, 32288, 14), id = 1026}, + [3] = {pos = Position(32762, 32288, 14), id = 1026}, + [4] = {pos = Position(32763, 32288, 14), id = 1026}, + [5] = {pos = Position(32764, 32288, 14), id = 1028} + } +} + +local function revertLever(position) + local leverItem = Tile(position):getItemById(1946) + if leverItem then + leverItem:transform(1945) + end +end + +local dreamerWalls = Action() +function dreamerWalls.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local walls = config[item.uid] + if not walls then + return true + end + + if item.itemid ~= 1945 then + return false + end + + item:transform(1946) + addEvent(revertLever, 8 * 1000, toPosition) + + local wallItem + for i = 1, #walls do + wallItem = Tile(walls[i].pos):getItemById(walls[i].id) + if wallItem then + wallItem:remove() + addEvent(Game.createItem, 7 * 1000, walls[i].id, 1 , walls[i].pos) + end + end + + return true +end + +for index, value in pairs(config) do + dreamerWalls:uid(index) +end + +dreamerWalls:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/druid_outfit/waterskin.lua b/data/scripts/actions/quests/druid_outfit/waterskin.lua new file mode 100644 index 00000000000..d526c161267 --- /dev/null +++ b/data/scripts/actions/quests/druid_outfit/waterskin.lua @@ -0,0 +1,13 @@ +local druidWaterSkin = Action() +function druidWaterSkin.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid ~= 5663 then + return false + end + + toPosition:sendMagicEffect(CONST_ME_LOSEENERGY) + item:transform(5939) + return true +end + +druidWaterSkin:id(5938) +druidWaterSkin:register() diff --git a/data/scripts/actions/quests/dwarven_legs/ladder.lua b/data/scripts/actions/quests/dwarven_legs/ladder.lua new file mode 100644 index 00000000000..0d3910cf43c --- /dev/null +++ b/data/scripts/actions/quests/dwarven_legs/ladder.lua @@ -0,0 +1,15 @@ +local dwarvenLadder = Action() +function dwarvenLadder.onUse(player, item, fromPosition, itemEx, toPosition) + if player:getStorageValue(Storage.DwarvenLegs) < 1 then + player:teleportTo({x = 32681, y = 31507, z = 10}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + else + player:say("Zzz Dont working.", TALKTYPE_ORANGE_1) + return true + end + return false +end + +dwarvenLadder:aid(42139) +dwarvenLadder:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/dwarven_legs/ore_wagon.lua b/data/scripts/actions/quests/dwarven_legs/ore_wagon.lua new file mode 100644 index 00000000000..e1a682371a5 --- /dev/null +++ b/data/scripts/actions/quests/dwarven_legs/ore_wagon.lua @@ -0,0 +1,26 @@ +local dwarvenOreWagon = Action() +function dwarvenOreWagon.onUse(player, item, fromPosition, itemEx, toPosition) + if item.actionid == 50109 then + if player:getStorageValue(Storage.DwarvenLegs) < 1 then + player:teleportTo({x = 32624, y = 31514, z = 9}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + else + player:say("Zzz Dont working.", TALKTYPE_ORANGE_1) + return true + end + elseif item.actionid == 50110 then + if player:getStorageValue(Storage.HiddenCityOfBeregar.RoyalRescue) == 4 then + player:teleportTo({x = 32725, y = 31487, z = 15}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + else + player:say("You need talk with Tehlim first.", TALKTYPE_ORANGE_1) + return true + end + end + return false +end + +dwarvenOreWagon:aid(50109, 50110) +dwarvenOreWagon:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/elemental_spheres/lever.lua b/data/scripts/actions/quests/elemental_spheres/lever.lua new file mode 100644 index 00000000000..af2dddc15d4 --- /dev/null +++ b/data/scripts/actions/quests/elemental_spheres/lever.lua @@ -0,0 +1,73 @@ +local config = { + { + position = Position(33268, 31833, 10), + itemid = 8304, + toPosition = Position(33268, 31833, 12), + vocationId = VOCATION.CLIENT_ID.SORCERER + }, + { + position = Position(33268, 31838, 10), + itemid = 8305, + toPosition = Position(33267, 31838, 12), + vocationId = VOCATION.CLIENT_ID.DRUID + }, + { + position = Position(33266, 31835, 10), + itemid = 8306, + toPosition = Position(33265, 31835, 12), + vocationId = VOCATION.CLIENT_ID.KNIGHT + }, + { + position = Position(33270, 31835, 10), + itemid = 8300, + toPosition = Position(33270, 31835, 12), + vocationId = VOCATION.CLIENT_ID.PALADIN + } +} + +local elementalSpheresLever = Action() +function elementalSpheresLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid ~= 1945 then + item:transform(1945) + return true + end + + if player:getPosition() ~= Position(33270, 31835, 10) then + return false + end + + local spectators = Game.getSpectators(Position(33268, 31836, 12), false, true, 30, 30, 30, 30) + if #spectators > 0 or Game.getStorageValue(GlobalStorage.ElementalSphere.BossRoom) > 0 then + player:say('Wait for the current team to exit.', TALKTYPE_MONSTER_SAY, false, 0, Position(33268, 31835, 10)) + return true + end + + local players = {} + for i = 1, #config do + local creature = Tile(config[i].position):getTopCreature() + if not creature or not creature:isPlayer() then + player:say('You need one player of each vocation having completed the Elemental Spheres quest and also carrying the elemental rare item.', TALKTYPE_MONSTER_SAY, false, 0, Position(33268, 31835, 10)) + return true + end + + local vocationId = creature:getVocation():getClientId() + if vocationId ~= config[i].vocationId or creature:getItemCount(config[i].itemid) < 1 or creature:getStorageValue(Storage.ElementalSphere.QuestLine) < 1 then + player:say('You need one player of each vocation having completed the Elemental Spheres quest and also carrying the elemental rare item.', TALKTYPE_MONSTER_SAY, false, 0, Position(33268, 31835, 10)) + return true + end + + players[#players + 1] = creature + end + + for i = 1, #players do + players[i]:teleportTo(config[i].toPosition) + config[i].position:sendMagicEffect(CONST_ME_TELEPORT) + config[i].toPosition:sendMagicEffect(CONST_ME_TELEPORT) + end + + item:transform(item.itemid + 1) + return true +end + +elementalSpheresLever:uid(1010) +elementalSpheresLever:register() diff --git a/data/scripts/actions/quests/elemental_spheres/lord_of_elements_lever.lua b/data/scripts/actions/quests/elemental_spheres/lord_of_elements_lever.lua new file mode 100644 index 00000000000..4c11852ee05 --- /dev/null +++ b/data/scripts/actions/quests/elemental_spheres/lord_of_elements_lever.lua @@ -0,0 +1,172 @@ +local config = { + exitPosition = Position(33265, 31838, 10), + area = { + from = Position(33238, 31806, 12), + to = Position(33297, 31865, 12) + }, + positions = { + Position(33272, 31840, 12), + Position(33263, 31840, 12), + Position(33263, 31831, 12), + Position(33272, 31831, 12) + }, + leverPositions = { + Position(33273, 31831, 12), + Position(33273, 31840, 12), + Position(33262, 31840, 12), + Position(33262, 31831, 12) + }, + walls = { + {from = Position(33275, 31834, 12), to = Position(33275, 31838, 12), wallId = 5072, soundPosition = Position(33275, 31836, 12)}, + {from = Position(33266, 31843, 12), to = Position(33270, 31843, 12), wallId = 5071, soundPosition = Position(33268, 31843, 12)}, + {from = Position(33260, 31834, 12), to = Position(33260, 31838, 12), wallId = 5072, soundPosition = Position(33260, 31836, 12)}, + {from = Position(33266, 31828, 12), to = Position(33270, 31828, 12), wallId = 5071, soundPosition = Position(33268, 31828, 12)} + }, + roomArea = { + from = Position(33261, 31829, 12), + to = Position(33274, 31842, 12) + }, + machineStorages = {GlobalStorage.ElementalSphere.Machine1, GlobalStorage.ElementalSphere.Machine2, GlobalStorage.ElementalSphere.Machine3, GlobalStorage.ElementalSphere.Machine4}, + centerPosition = Position(33267, 31836, 12), + effectPositions = { + Position(33261, 31829, 12), Position(33262, 31830, 12), Position(33263, 31831, 12), + Position(33264, 31832, 12), Position(33265, 31833, 12), Position(33266, 31834, 12), + Position(33267, 31835, 12), Position(33268, 31836, 12), Position(33269, 31837, 12), + Position(33270, 31838, 12), Position(33271, 31839, 12), Position(33272, 31840, 12), + Position(33273, 31841, 12), Position(33274, 31842, 12), Position(33274, 31829, 12), + Position(33273, 31830, 12), Position(33272, 31831, 12), Position(33271, 31832, 12), + Position(33270, 31833, 12), Position(33269, 31834, 12), Position(33268, 31835, 12), + Position(33267, 31836, 12), Position(33266, 31837, 12), Position(33265, 31838, 12), + Position(33264, 31839, 12), Position(33263, 31840, 12), Position(33262, 31841, 12), + Position(33261, 31842, 12) + } +} + + +local function resetRoom(players) + for i = 1, #players do + local player = Player(players[i]) + if player and isInRange(player:getPosition(), config.area.from, config.area.to) then + player:teleportTo(config.exitPosition) + config.exitPosition:sendMagicEffect(CONST_ME_TELEPORT) + end + end + + for i = 1, #config.walls do + local wall = config.walls[i] + for x = wall.from.x, wall.to.x do + for y = wall.from.y, wall.to.y do + local wallItem = Tile(Position(x, y, wall.from.z)):getItemById(wall.wallId) + if wallItem then + wallItem:remove() + end + end + end + end + + local creature = Creature('lord of the elements') + if creature then + creature:remove() + end + + for i = 1, #config.leverPositions do + local leverItem = Tile(config.leverPositions[i]):getItemById(1946) + if leverItem then + leverItem:transform(1945) + end + end + + Game.setStorageValue(GlobalStorage.ElementalSphere.BossRoom, -1) + for i = 1, #config.machineStorages do + Game.setStorageValue(config.machineStorages[i], -1) + end + return true +end + +local function warnPlayers(players) + local player + for i = 1, #players do + player = Player(players[i]) + if player and isInRange(player:getPosition(), config.roomArea.from, config.roomArea.to) then + break + end + player = nil + end + + if not player then + return + end + + player:say('You have 5 minutes from now on until you get teleported out.', TALKTYPE_MONSTER_YELL, false, 0, Position(33266, 31835, 13)) +end + +local function areMachinesCharged() + for i = 1, #config.machineStorages do + if Game.getStorageValue(config.machineStorages[i]) <= 0 then + return false + end + end + return true +end + +local elementalSpheresLordLever = Action() +function elementalSpheresLordLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid ~= 1945 then + return true + end + + for i = 1, #config.machineStorages do + Game.setStorageValue(config.machineStorages[i], 1) + end + + if not areMachinesCharged() then + return false + end + + local index = table.find(config.positions, player:getPosition()) + if not index then + return false + end + + item:transform(1946) + local leverCount = 0 + for i = 1, #config.leverPositions do + if Tile(config.leverPositions[i]):getItemById(1946) then + leverCount = leverCount + 1 + end + end + + local walls = config.walls[index] + for x = walls.from.x, walls.to.x do + for y = walls.from.y, walls.to.y do + Game.createItem(walls.wallId, 1, Position(x, y, walls.from.z)) + end + end + player:say('ZOOOOOOOOM', TALKTYPE_MONSTER_SAY, false, 0, walls.soundPosition) + + if leverCount ~= #config.leverPositions then + return true + end + + local players = {} + for i = 1, #config.positions do + local creature = Tile(config.positions[i]):getTopCreature() + if creature then + players[#players + 1] = creature.uid + end + end + + Game.setStorageValue(GlobalStorage.ElementalSphere.BossRoom, 1) + Game.createMonster('Lord of the Elements', config.centerPosition) + player:say('You have 10 minutes from now on until you get teleported out.', TALKTYPE_MONSTER_YELL, false, 0, config.centerPosition) + addEvent(warnPlayers, 5 * 60 * 1000, players) + addEvent(resetRoom, 10 * 60 * 1000, players) + + for i = 1, #config.effectPositions do + config.effectPositions[i]:sendMagicEffect(CONST_ME_ENERGYHIT) + end + return true +end + +elementalSpheresLordLever:uid(1011, 1012, 1013, 1014) +elementalSpheresLordLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/elemental_spheres/machine1.lua b/data/scripts/actions/quests/elemental_spheres/machine1.lua new file mode 100644 index 00000000000..b4859050582 --- /dev/null +++ b/data/scripts/actions/quests/elemental_spheres/machine1.lua @@ -0,0 +1,46 @@ +local config = { + [VOCATION.CLIENT_ID.SORCERER] = {x = 33183, y = 32197, z = 13}, + [VOCATION.CLIENT_ID.DRUID] = {x = 33331, y = 32076, z = 13}, + [VOCATION.CLIENT_ID.PALADIN] = {x = 33265, y = 32202, z = 13}, + [VOCATION.CLIENT_ID.KNIGHT] = {x = 33087, y = 32096, z = 13} +} + +local elementalSpheresMachine1 = Action() +function elementalSpheresMachine1.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local destination = config[player:getVocation():getClientId()] + if table.contains({7911, 7912}, item.itemid) then + local gemCount = player:getStorageValue(Storage.ElementalSphere.MachineGemCount) + if table.contains({33268, 33269}, toPosition.x) + and toPosition.y == 31830 + and toPosition.z == 10 + and gemCount >= 20 then + player:teleportTo(destination, false) + player:setStorageValue(Storage.ElementalSphere.MachineGemCount, gemCount - 20) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + toPosition.x = toPosition.x + (item.itemid == 7911 and 1 or -1) + local tile = toPosition:getTile() + if tile then + local thing = tile:getItemById(item.itemid == 7911 and 7912 or 7911) + if thing then + thing:transform(thing.itemid + 4) + end + end + item:transform(item.itemid + 4) + else + toPosition.x = toPosition.x + (item.itemid == 7915 and 1 or -1) + local tile = toPosition:getTile() + if tile then + local thing = tile:getItemById(item.itemid == 7915 and 7916 or 7915) + if thing then + thing:transform(thing.itemid - 4) + end + end + item:transform(item.itemid - 4) + end + return true +end + +elementalSpheresMachine1:id(7911, 7912, 7915, 7916) +elementalSpheresMachine1:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/elemental_spheres/machine2.lua b/data/scripts/actions/quests/elemental_spheres/machine2.lua new file mode 100644 index 00000000000..b4185f87b13 --- /dev/null +++ b/data/scripts/actions/quests/elemental_spheres/machine2.lua @@ -0,0 +1,28 @@ +local elementalSpheresMachine2 = Action() +function elementalSpheresMachine2.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if not isInRange(toPosition, Position(33238, 31806, 12), Position(33297, 31865, 12)) then + return false + end + + if isInArray({7913, 7914}, item.itemid) then + toPosition.y = toPosition.y + (item.itemid == 7913 and 1 or -1) + local machineItem = Tile(toPosition):getItemById(item.itemid == 7913 and 7914 or 7913) + if machineItem then + machineItem:transform(machineItem.itemid + 4) + end + item:transform(item.itemid + 4) + player:say('ON', TALKTYPE_MONSTER_SAY, false, player, toPosition) + else + toPosition.y = toPosition.y + (item.itemid == 7917 and 1 or -1) + local machineItem = Tile(toPosition):getItemById(item.itemid == 7917 and 7918 or 7917) + if machineItem then + machineItem:transform(machineItem.itemid - 4) + end + item:transform(item.itemid - 4) + player:say('OFF', TALKTYPE_MONSTER_SAY, false, player, toPosition) + end + return true +end + +elementalSpheresMachine2:id(7913,7914,7917,7918) +elementalSpheresMachine2:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/elemental_spheres/soils1.lua b/data/scripts/actions/quests/elemental_spheres/soils1.lua new file mode 100644 index 00000000000..0cb7e924071 --- /dev/null +++ b/data/scripts/actions/quests/elemental_spheres/soils1.lua @@ -0,0 +1,38 @@ +local config = { + [8298] = {targetId = 8572, transformId = 8576, effect = CONST_ME_BIGPLANTS}, + [8299] = {targetId = 8573, transformId = 8575}, + [8302] = {targetId = 8571, transformId = 8574, effect = CONST_ME_ICEATTACK}, + [8303] = {targetId = 8567, createId = 1495} +} + +local elementalSpheresSouls1 = Action() +function elementalSpheresSouls1.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local soil = config[item.itemid] + if not soil then + return true + end + + if soil.targetId ~= target.itemid then + return true + end + + if soil.transformId then + target:transform(soil.transformId) + target:decay() + elseif soil.createId then + local newItem = Game.createItem(soil.createId, 1, toPosition) + if newItem then + newItem:decay() + end + end + + if soil.effect then + toPosition:sendMagicEffect(soil.effect) + end + + item:transform(item.itemid, item.type - 1) + return true +end + +elementalSpheresSouls1:id(8298,8299,8302,8303) +elementalSpheresSouls1:register() diff --git a/data/scripts/actions/quests/elemental_spheres/soils2.lua b/data/scripts/actions/quests/elemental_spheres/soils2.lua new file mode 100644 index 00000000000..ff1e1307843 --- /dev/null +++ b/data/scripts/actions/quests/elemental_spheres/soils2.lua @@ -0,0 +1,41 @@ +local spheres = { + [8300] = VOCATION.CLIENT_ID.PALADIN, + [8304] = VOCATION.CLIENT_ID.SORCERER, + [8305] = VOCATION.CLIENT_ID.DRUID, + [8306] = VOCATION.CLIENT_ID.KNIGHT +} + +local globalTable = { + [VOCATION.CLIENT_ID.SORCERER] = 10005, + [VOCATION.CLIENT_ID.DRUID] = 10006, + [VOCATION.CLIENT_ID.PALADIN] = 10007, + [VOCATION.CLIENT_ID.KNIGHT] = 10008 +} + +local elementalSpheresSoils2 = Action() +function elementalSpheresSoils2.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if not table.contains({7917, 7918, 7913, 7914}, target.itemid) then + return false + end + + if not isInRange(toPosition, {x=33238, y=31806, z=12}, {x=33297, y=31865, z=12}) then + return false + end + + if not table.contains(spheres[item.itemid], player:getVocation():getClientId()) then + return false + end + + if table.contains({7917, 7918}, target.itemid) then + player:say('Turn off the machine first.', TALKTYPE_MONSTER_SAY) + return true + end + + toPosition:sendMagicEffect(CONST_ME_PURPLEENERGY) + Game.setStorageValue(globalTable[player:getVocation():getBase():getId()], 1) + item:remove(1) + return true +end + +elementalSpheresSoils2:id(8300,8304,8305,8306) +elementalSpheresSoils2:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/explorer_society/botanist.lua b/data/scripts/actions/quests/explorer_society/botanist.lua new file mode 100644 index 00000000000..0ac800544d4 --- /dev/null +++ b/data/scripts/actions/quests/explorer_society/botanist.lua @@ -0,0 +1,33 @@ +local explorerSocietyBotanist = Action() +function explorerSocietyBotanist.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid == 4138 and player:getStorageValue(Storage.ExplorerSociety.ThePlantCollection) == 17 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 17 then + player:setStorageValue(Storage.ExplorerSociety.ThePlantCollection, 18) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 18) + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + item:transform(4870) + elseif target.itemid == 4149 and player:getStorageValue(Storage.ExplorerSociety.ThePlantCollection) == 20 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 20 then + player:setStorageValue(Storage.ExplorerSociety.ThePlantCollection, 21) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 21) + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + item:transform(4871) + elseif target.itemid == 4142 and player:getStorageValue(Storage.ExplorerSociety.ThePlantCollection) == 23 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 23 then + player:setStorageValue(Storage.ExplorerSociety.ThePlantCollection, 24) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 24) + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + item:transform(4872) + elseif target.itemid == 5659 and target.uid == 3152 then + if player:getStorageValue(53051) < 1 then + toPosition:sendMagicEffect(CONST_ME_MAGIC_RED) + item:transform(5937) + player:setStorageValue(53051, 1) + player:say("You successfully took a sample of the rare griffinclaw flower.", TALKTYPE_ORANGE_1) + else + toPosition:sendMagicEffect(CONST_ME_POFF) + player:say("You already took a sample of the rare griffinclaw flower.", TALKTYPE_ORANGE_1) + end + end + return true +end + +explorerSocietyBotanist:id(4869) +explorerSocietyBotanist:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/explorer_society/butterfly.lua b/data/scripts/actions/quests/explorer_society/butterfly.lua new file mode 100644 index 00000000000..40ffbb6a556 --- /dev/null +++ b/data/scripts/actions/quests/explorer_society/butterfly.lua @@ -0,0 +1,26 @@ +local explorerSocietyButterfly = Action() +function explorerSocietyButterfly.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid == 4993 and player:getStorageValue(Storage.ExplorerSociety.TheButterflyHunt) == 8 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 8 then + player:setStorageValue(Storage.ExplorerSociety.TheButterflyHunt, 9) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 9) + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + item:transform(4866) + target:remove() + elseif target.itemid == 4994 and player:getStorageValue(Storage.ExplorerSociety.TheButterflyHunt) == 11 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 11 then + player:setStorageValue(Storage.ExplorerSociety.TheButterflyHunt, 12) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 12) + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + item:transform(4867) + target:remove() + elseif target.itemid == 4992 and player:getStorageValue(Storage.ExplorerSociety.TheButterflyHunt) == 14 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 14 then + player:setStorageValue(Storage.ExplorerSociety.TheButterflyHunt, 15) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 15) + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + item:transform(4868) + target:remove() + end + return true +end + +explorerSocietyButterfly:id(4865) +explorerSocietyButterfly:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/explorer_society/dragon.lua b/data/scripts/actions/quests/explorer_society/dragon.lua new file mode 100644 index 00000000000..15251fa4d8b --- /dev/null +++ b/data/scripts/actions/quests/explorer_society/dragon.lua @@ -0,0 +1,13 @@ +local explorerSocietyDragon = Action() +function explorerSocietyDragon.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.ExplorerSociety.TheIslandofDragons) == 57 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 57 then + player:setStorageValue(Storage.ExplorerSociety.TheIslandofDragons, 58) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 58) + player:addItem(7314, 1) + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + end + return true +end + +explorerSocietyDragon:uid(40042) +explorerSocietyDragon:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/explorer_society/findings.lua b/data/scripts/actions/quests/explorer_society/findings.lua new file mode 100644 index 00000000000..46e8846b46d --- /dev/null +++ b/data/scripts/actions/quests/explorer_society/findings.lua @@ -0,0 +1,88 @@ +local UniqueTable = { + -- Chests uniques + [14029] = { + -- Uzgod's Family Brooch + rewardItemId = 4845, + storageMission = Storage.ExplorerSociety.TheBonelordSecret, + storageMissionValue = 31, + storageQuestlineValue = 30 + }, + [14030] = { + -- Wrinkled parchment + rewardItemId = 4857, + storageMission = Storage.ExplorerSociety.TheBonelordSecret, + storageMissionValue = 31, + storageQuestlineValue = 30 + }, + [14031] = { + -- Strange powder + rewardItemId = 15389, + storageMission = Storage.ExplorerSociety.TheOrcPowder, + storageMissionValue = 34, + storageQuestlineValue = 33 + }, + [14032] = { + -- Elven poetry book + rewardItemId = 4855, + storageMission = Storage.ExplorerSociety.TheElvenPoetry, + storageMissionValue = 37, + storageQuestlineValue = 36 + }, + [14033] = { + -- Memory stone + rewardItemId = 4852, + storageMission = Storage.ExplorerSociety.TheMemoryStone, + storageMissionValue = 40, + storageQuestlineValue = 39 + }, + [14034] = { + -- Spectral dress + rewardItemId = 4847, + storageMission = Storage.ExplorerSociety.TheSpectralDress, + storageMissionValue = 49, + storageQuestlineValue = 48 + }, + [14035] = { + -- Damage logbook + rewardItemId = 6124, + storageMission = Storage.ExplorerSociety.CalassaQuest, + storageMissionValue = 2, + storageQuestlineValue = 0 + }, + -- Others uniques + [40041] = { + -- Funeral urn + rewardItemId = 4858, + storageMission = Storage.ExplorerSociety.TheLizardUrn, + storageMissionValue = 28, + storageQuestlineValue = 27 + }, +} + +local explorerSocietyFindings = Action() +function explorerSocietyFindings.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local uniqueItem = UniqueTable[item.uid] + if not uniqueItem then + return true + end + if player:getStorageValue(item.uid) >= 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The ' .. getItemName(uniqueItem.itemId) .. ' is empty.') + return true + end + if player:getStorageValue(uniqueItem.storageMission) ~= uniqueItem.storageMissionValue then + player:addItem(uniqueItem.rewardItemId, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a " .. getItemName(uniqueItem.rewardItemId) .. ".") + player:setStorageValue(item.uid, 1) + player:setStorageValue(uniqueItem.storageMission, uniqueItem.storageMissionValue) + if(uniqueItem.storageQuestlineValue > 0) then + player:setStorageValue(Storage.ExplorerSociety.QuestLine, uniqueItem.storageQuestlineValue) + end + return true + end +end + +for index, value in pairs(UniqueTable) do + explorerSocietyFindings:uid(index) +end + +explorerSocietyFindings:register() diff --git a/data/scripts/actions/quests/explorer_society/icicle.lua b/data/scripts/actions/quests/explorer_society/icicle.lua new file mode 100644 index 00000000000..f3f8d8ed4b2 --- /dev/null +++ b/data/scripts/actions/quests/explorer_society/icicle.lua @@ -0,0 +1,13 @@ +local explorerSocietyIcicle = Action() +function explorerSocietyIcicle.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid == 4995 and player:getStorageValue(Storage.ExplorerSociety.TheIceDelivery) == 5 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 5 then + player:setStorageValue(Storage.ExplorerSociety.TheIceDelivery, 6) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 6) + player:addItem(4848, 1) + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + end + return true +end + +explorerSocietyIcicle:id(4856) +explorerSocietyIcicle:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/explorer_society/resonance.lua b/data/scripts/actions/quests/explorer_society/resonance.lua new file mode 100644 index 00000000000..18462b46947 --- /dev/null +++ b/data/scripts/actions/quests/explorer_society/resonance.lua @@ -0,0 +1,15 @@ +local explorerSocietyResonance = Action() +function explorerSocietyResonance.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.uid == 40043 then + if player:getStorageValue(Storage.ExplorerSociety.TheIceMusic) == 60 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 60 then + player:setStorageValue(Storage.ExplorerSociety.TheIceMusic, 61) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 61) + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + item:transform(7315) + end + end + return true +end + +explorerSocietyResonance:id(7242) +explorerSocietyResonance:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/explorer_society/stone.lua b/data/scripts/actions/quests/explorer_society/stone.lua new file mode 100644 index 00000000000..d04ef0f28ea --- /dev/null +++ b/data/scripts/actions/quests/explorer_society/stone.lua @@ -0,0 +1,26 @@ +local explorerSocietyStone = Action() +function explorerSocietyStone.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.uid == 25018 and player:getStorageValue(Storage.ExplorerSociety.TheSpectralStone) == 53 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 53 and player:getStorageValue(Storage.ExplorerSociety.SpectralStone) == 1 then -- mission taken from Angus + player:setStorageValue(Storage.ExplorerSociety.TheSpectralStone, 54) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 54) + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + elseif target.uid == 25019 and player:getStorageValue(Storage.ExplorerSociety.TheSpectralStone) == 54 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 54 and player:getStorageValue(Storage.ExplorerSociety.SpectralStone) == 1 then -- mission taken from Angus + player:setStorageValue(Storage.ExplorerSociety.TheSpectralStone, 55) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 55) + player:removeItem(4851, 1) + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + elseif target.uid == 25019 and player:getStorageValue(Storage.ExplorerSociety.TheSpectralStone) == 53 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 53 and player:getStorageValue(Storage.ExplorerSociety.SpectralStone) == 2 then -- mission taken from Mortimer + player:setStorageValue(Storage.ExplorerSociety.TheSpectralStone, 54) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 54) + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + elseif target.uid == 25018 and player:getStorageValue(Storage.ExplorerSociety.TheSpectralStone) == 54 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 54 and player:getStorageValue(Storage.ExplorerSociety.SpectralStone) == 2 then -- mission taken from Mortimer + player:setStorageValue(Storage.ExplorerSociety.TheSpectralStone, 55) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 55) + player:removeItem(4851, 1) + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + end + return true +end + +explorerSocietyStone:id(4851) +explorerSocietyStone:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/explorer_society/tracing_paper.lua b/data/scripts/actions/quests/explorer_society/tracing_paper.lua new file mode 100644 index 00000000000..7a65b2a7bd4 --- /dev/null +++ b/data/scripts/actions/quests/explorer_society/tracing_paper.lua @@ -0,0 +1,13 @@ +local explorerSocietyPaper = Action() +function explorerSocietyPaper.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid == 1560 and target.uid == 3010 and player:getStorageValue(Storage.ExplorerSociety.TheRuneWritings) == 42 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 42 then + player:setStorageValue(Storage.ExplorerSociety.TheRuneWritings, 43) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 43) + item:transform(4854) + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + end + return true +end + +explorerSocietyPaper:id(4853) +explorerSocietyPaper:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/fathers_burden/corpse.lua b/data/scripts/actions/quests/fathers_burden/corpse.lua new file mode 100644 index 00000000000..d0d4aaaabfa --- /dev/null +++ b/data/scripts/actions/quests/fathers_burden/corpse.lua @@ -0,0 +1,24 @@ +local config = { + [12545] = {itemId = 12506, storage = Storage.FathersBurden.Corpse.Scale, text = 'Glitterscale\'s scale.'}, + [12546] = {itemId = 12504, storage = Storage.FathersBurden.Corpse.Sinew, text = 'Heoni\'s sinew'} +} + +local fatherCorpse = Action() +function fatherCorpse.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local corpse = config[item.itemid] + if not corpse then + return true + end + + if player:getStorageValue(corpse.storage) == 1 then + return false + end + + player:addItem(corpse.itemId, 1) + player:setStorageValue(corpse.storage, 1) + player:say('You acquired ' .. corpse.text, TALKTYPE_MONSTER_SAY) + return true +end + +fatherCorpse:id(12545, 12546) +fatherCorpse:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/bone_flute.lua b/data/scripts/actions/quests/ferumbras_ascendant/bone_flute.lua new file mode 100644 index 00000000000..e4e3946fc00 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/bone_flute.lua @@ -0,0 +1,31 @@ +local ferumbrasAscendantBoneFlute = Action() +function ferumbrasAscendantBoneFlute.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target:isItem() then + return false + end + if player:getStorageValue(Storage.FerumbrasAscension.BoneFlute) >= 1 then + return false + end + if not isInRange(target:getPosition(), Position(33477, 32775, 11), Position(33493, 32781, 11)) then + return false + end + if target:getName():lower() == 'snake' or target:getName():lower() == 'lion' or target:getName():lower() == 'bear' or target:getName():lower() == 'seagull' or target:getName():lower() == 'pig' then + local rand = math.random(100) + if rand <= 5 then + player:say('Finally this one reveal your spirit animal.', TALKTYPE_MONSTER_SAY) + player:setStorageValue(Storage.FerumbrasAscension.BoneFlute, 1) + item:remove() + return true + elseif rand > 5 and rand <= 50 then + player:say('This one has shaken its head. This probably means it\'s not your spirit animal.', TALKTYPE_MONSTER_SAY) + return true + elseif rand > 50 then + player:say('This one\'s still unwilling reveal whether it\'s your spirit animal.', TALKTYPE_MONSTER_SAY) + return true + end + end + return true +end + +ferumbrasAscendantBoneFlute:id(24910) +ferumbrasAscendantBoneFlute:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/bone_flute_wall.lua b/data/scripts/actions/quests/ferumbras_ascendant/bone_flute_wall.lua new file mode 100644 index 00000000000..3d7e619bf2c --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/bone_flute_wall.lua @@ -0,0 +1,15 @@ +local ferumbrasAscendantBoneWall = Action() +function ferumbrasAscendantBoneWall.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.FerumbrasAscension.BoneFluteWall) < 1 then + player:addItem(24910) + player:setStorageValue(Storage.FerumbrasAscension.BoneFluteWall, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have found a bone flute.') + toPosition:sendMagicEffect(CONST_ME_THUNDER) + else + return false + end + return true +end + +ferumbrasAscendantBoneWall:aid(54386) +ferumbrasAscendantBoneWall:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/boots_of_homecoming.lua b/data/scripts/actions/quests/ferumbras_ascendant/boots_of_homecoming.lua new file mode 100644 index 00000000000..255e59f181a --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/boots_of_homecoming.lua @@ -0,0 +1,28 @@ +local ferumbrasAscendantHomeComing = Action() +function ferumbrasAscendantHomeComing.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + local boots = player:getSlotItem(CONST_SLOT_FEET) + if boots ~= item or boots ~= item then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You need to equip the boot to try use it.') + return true + end + if item.itemid == 25429 then + if Tile(player:getPosition()):hasFlag(TILESTATE_PROTECTIONZONE) then + item:transform(25430) + item:decay() + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:teleportTo(Position(32121, 32708, 7)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Magical sparks whirl around the boots and suddenly you are somewhere else.') + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'If you want to wear this boots you need to stay in a protection zone.') + return true + end + elseif item.itemid == 25430 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You are tired of the last use of the boots, you must wait for one hour to use it again.') + end + return true +end + +ferumbrasAscendantHomeComing:id(25429,25430) +ferumbrasAscendantHomeComing:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/color_levers.lua b/data/scripts/actions/quests/ferumbras_ascendant/color_levers.lua new file mode 100644 index 00000000000..e6f7c428b23 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/color_levers.lua @@ -0,0 +1,44 @@ +local ferumbrasAscendantColorLevers = Action() +function ferumbrasAscendantColorLevers.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.FerumbrasAscension.FirstDoor) >= 1 then + item:transform(item.itemid == 10044 and 10045 or 10044) + return true + end + if item.actionid == 54381 then + if player:getStorageValue(Storage.FerumbrasAscension.ColorLever) < 1 then + local rand = math.random(4) + player:setStorageValue(Storage.FerumbrasAscension.ColorLever, rand) + player:getPosition():sendMagicEffect(166 + rand) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You choose the colour of decay.') + end + elseif item.actionid == 54382 then + if player:getStorageValue(Storage.FerumbrasAscension.ColorLever) == 1 then + player:setStorageValue(Storage.FerumbrasAscension.FirstDoor, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You select the correct colour.') + toPosition:sendMagicEffect(CONST_ME_POFF) + end + elseif item.actionid == 54383 then + if player:getStorageValue(Storage.FerumbrasAscension.ColorLever) == 3 then + player:setStorageValue(Storage.FerumbrasAscension.FirstDoor, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You select the correct colour.') + toPosition:sendMagicEffect(CONST_ME_POFF) + end + elseif item.actionid == 54384 then + if player:getStorageValue(Storage.FerumbrasAscension.ColorLever) == 4 then + player:setStorageValue(Storage.FerumbrasAscension.FirstDoor, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You select the correct colour.') + toPosition:sendMagicEffect(CONST_ME_POFF) + end + elseif item.actionid == 54385 then + if player:getStorageValue(Storage.FerumbrasAscension.ColorLever) == 2 then + player:setStorageValue(Storage.FerumbrasAscension.FirstDoor, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You select the correct colour.') + toPosition:sendMagicEffect(CONST_ME_POFF) + end + end + item:transform(item.itemid == 10044 and 10045 or 10044) + return true +end + +ferumbrasAscendantColorLevers:aid(54381,54382,54383,54384,54385) +ferumbrasAscendantColorLevers:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/ferumbras_amulet.lua b/data/scripts/actions/quests/ferumbras_ascendant/ferumbras_amulet.lua new file mode 100644 index 00000000000..b048e352440 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/ferumbras_amulet.lua @@ -0,0 +1,28 @@ +local ferumbrasAscendantAmulet = Action() +function ferumbrasAscendantAmulet.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + local amulet = player:getSlotItem(CONST_SLOT_NECKLACE) + if amulet ~= item or amulet ~= item then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You need to equip the amulet to try use it.') + return true + end + if item.itemid == 25423 then + if math.random(2) == 1 then + player:addHealth(1000, true, true) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Magical sparks whirl around the amulet as you use it and you was healed.') + else + player:addMana(1000, true, true) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Magical sparks whirl around the amulet as you use it and you was restored.') + end + item:transform(25424) + item:decay() + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + return true + elseif item.itemid == 25424 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You are tired of the last use of the amulet, you must wait for the recharge.') + end + return true +end + +ferumbrasAscendantAmulet:id(25423,25424) +ferumbrasAscendantAmulet:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/ferumbras_lever.lua b/data/scripts/actions/quests/ferumbras_ascendant/ferumbras_lever.lua new file mode 100644 index 00000000000..8737bd5bc36 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/ferumbras_lever.lua @@ -0,0 +1,110 @@ +local config = { + bossName = "Ascending Ferumbras", + summonName = "Rift Invader", + bossPos = Position(33392, 31473, 14), + centerRoom = Position(33392, 31473, 14), -- Center Room + exitPosition = Position(33266, 31479, 14), -- Exit Position + newPos = Position(33392, 31479, 14), -- Player Position on room + playerPositions = { + Position(33269, 31477, 14), + Position(33269, 31478, 14), + Position(33269, 31479, 14), + Position(33269, 31480, 14), + Position(33269, 31481, 14), + Position(33270, 31477, 14), + Position(33270, 31478, 14), + Position(33270, 31479, 14), + Position(33270, 31480, 14), + Position(33270, 31481, 14), + Position(33271, 31477, 14), + Position(33271, 31478, 14), + Position(33271, 31479, 14), + Position(33271, 31480, 14), + Position(33271, 31481, 14) + }, + range = 20, + time = 30, -- time in minutes to remove the player +} +local function clearFerumbrasRoom() + local spectators = Game.getSpectators(config.bossPos, false, false, 20, 20, 20, 20) + for i = 1, #spectators do + local spectator = spectators[i] + if spectator:isPlayer() then + spectator:teleportTo(config.exitPosition) + spectator:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + spectator:say('Time out! You were teleported out by strange forces.', TALKTYPE_MONSTER_SAY) + elseif spectator:isMonster() then + spectator:remove() + end + end +end + +local ferumbrasAscendantLever = Action() +function ferumbrasAscendantLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 9825 then + if player:getPosition() ~= Position(33270, 31477, 14) then + return true + end + + for x = 33269, 33271 do + for y = 31477, 31481 do + local playerTile = Tile(Position(x, y, 14)):getTopCreature() + if playerTile and playerTile:isPlayer() then + if playerTile:getStorageValue(Storage.FerumbrasAscension.FerumbrasTimer) > os.time() then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You or a member in your team have to wait 5 days to face Ferumbras again!") + item:transform(9826) + return true + end + end + end + end + + local specs, spec = Game.getSpectators(config.centerRoom, false, false, 15, 15, 15, 15) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "There's someone fighting with Ferumbras.") + return true + end + end + + local spectators = Game.getSpectators(config.bossPos, false, false, 15, 15, 15, 15) + for i = 1, #spectators do + local spectator = spectators[i] + if spectator:isMonster() then + spectator:remove() + end + end + + for x = 33269, 33271 do + for y = 31477, 31481 do + local playerTile = Tile(Position(x, y, 14)):getTopCreature() + if playerTile and playerTile:isPlayer() then + playerTile:getPosition():sendMagicEffect(CONST_ME_POFF) + playerTile:teleportTo(config.newPos) + playerTile:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + playerTile:setStorageValue(Storage.FerumbrasAscension.FerumbrasTimer, os.time() + 280 * 60 * 3600) -- 14 days + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have 30 minutes to kill and loot this boss. Otherwise you will lose that chance and will be kicked out.") + addEvent(clearFerumbrasRoom, 60 * config.time * 1000, player:getId(), config.centerRoom, config.range, config.range, config.exitPosition) + + for b = 1,10 do + local xrand = math.random(-10, 10) + local yrand = math.random(-10, 10) + local position = Position(33392 + xrand, 31473 + yrand, 14) + if Game.createMonster("rift invader", position) then + end + end + + Game.createMonster(config.bossName, config.bossPos, true, true) + item:transform(9826) + end + end + end + elseif item.itemid == 9826 then + item:transform(9825) + return true + end +end + +ferumbrasAscendantLever:uid(1021) +ferumbrasAscendantLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/ferumbras_mana_keg.lua b/data/scripts/actions/quests/ferumbras_ascendant/ferumbras_mana_keg.lua new file mode 100644 index 00000000000..8c672b35014 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/ferumbras_mana_keg.lua @@ -0,0 +1,18 @@ +local ferumbrasAscendantManaKeg = Action() +function ferumbrasAscendantManaKeg.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + if item.itemid == 25425 then + player:addItem('ultimate mana potion', 10) + item:transform(25426) + item:decay() + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Magical sparks whirl around the keg as you open the spigot and you fill ten empty vials with mana fluid.') + return true + elseif item.itemid == 25426 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You are tired of the last use of the mana keg, rest your arms for a moment.') + end + return true +end + +ferumbrasAscendantManaKeg:id(25425,25426) +ferumbrasAscendantManaKeg:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/flower_puzzle_lever.lua b/data/scripts/actions/quests/ferumbras_ascendant/flower_puzzle_lever.lua new file mode 100644 index 00000000000..7611e08217d --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/flower_puzzle_lever.lua @@ -0,0 +1,68 @@ +local flowerPositions = { + [1] = {itemid = 2762, position = Position(33455, 32707, 14)}, + [2] = {itemid = 2762, position = Position(33460, 32707, 14)}, + [3] = {itemid = 2764, position = Position(33455, 32708, 14)}, + [4] = {itemid = 2763, position = Position(33457, 32707, 14)}, + [5] = {itemid = 2764, position = Position(33457, 32708, 14)}, + [6] = {itemid = 2763, position = Position(33456, 32708, 14)}, + [7] = {itemid = 2762, position = Position(33458, 32709, 14)}, + [8] = {itemid = 2763, position = Position(33459, 32708, 14)}, + [9] = {itemid = 2764, position = Position(33460, 32709, 14)} +} + +local gates = { + {position = Position(33476, 32698, 14), itemid = 19160, transform = 19157}, + {position = Position(33478, 32698, 14), itemid = 19160, transform = 19156}, + {position = Position(33475, 32698, 14), itemid = 19157, transform = 19160}, + {position = Position(33479, 32698, 14), itemid = 19156, transform = 19160} +} + +local function revertItem(position, itemId, transformId) + local item = Tile(position):getItemById(itemId) + if item then + item:transform(transformId) + end +end + +local ferumbrasAscendantFlowerPuzzle = Action() +function ferumbrasAscendantFlowerPuzzle.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 10029 then + for a = 1, #flowerPositions do + local flower = flowerPositions[a] + if not Tile(flower.position):getItemById(flower.itemid) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The order of the flowers in the garden are wrong.') + return true + end + end + if Game.getStorageValue(Storage.FerumbrasAscension.FlowerPuzzleTimer) >= 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The portal still activated.') + else + Game.setStorageValue(Storage.FerumbrasAscension.FlowerPuzzleTimer, 1) + addEvent(Game.setStorageValue, 30 * 1000, Storage.FerumbrasAscension.FlowerPuzzleTimer, 0) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'A portal forms as two beams of a strange construction dividing this room move towards each other.') + for x = 33475, 33479 do + local pos = Position(x, 32698, 14) + pos:sendMagicEffect(CONST_ME_POFF) + end + for k = 1, #gates do + local gate = gates[k] + local gatee = Tile(gate.position):getItemById(gate.itemid) + if gatee then + gatee:transform(gate.transform) + end + addEvent(revertItem, 30 * 1000, gate.position, gate.itemid, gate.transform) + end + local wall = Tile(Position(33477, 32698, 14)):getItemById(6116) + if not wall then + Game.createItem(6116, 1, Position(33477, 32698, 14)) + end + end + item:transform(10030) + elseif item.itemid == 10030 then + item:transform(10029) + end + return true +end + +ferumbrasAscendantFlowerPuzzle:aid(34300) +ferumbrasAscendantFlowerPuzzle:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/grave_flower.lua b/data/scripts/actions/quests/ferumbras_ascendant/grave_flower.lua new file mode 100644 index 00000000000..05313db0a30 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/grave_flower.lua @@ -0,0 +1,17 @@ +local function revertItem(position, itemId, transformId) + local item = Tile(position):getItemById(itemId) + if item then + item:transform(transformId) + end +end + +local ferumbrasAscendantGraveFlower = Action() +function ferumbrasAscendantGraveFlower.onUse(player, item, fromPosition, target, toPosition, isHotkey) + item:transform(25530) + player:addItem(2747, 1) + addEvent(revertItem, 2 * 60 * 1000, toPosition, 25530, 25529) + return true +end + +ferumbrasAscendantGraveFlower:id(25529) +ferumbrasAscendantGraveFlower:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/habitat_corrupted.lua b/data/scripts/actions/quests/ferumbras_ascendant/habitat_corrupted.lua new file mode 100644 index 00000000000..a5add4865cb --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/habitat_corrupted.lua @@ -0,0 +1,405 @@ +local corrupted = { + {itemid = 11752, position = Position(33614,32724, 12)}, + {itemid = 11752, position = Position(33620,32713, 12)}, + {itemid = 11752, position = Position(33619,32727, 12)}, + {itemid = 11752, position = Position(33615,32715, 12)}, + {itemid = 11752, position = Position(33622,32712, 12)}, + {itemid = 11752, position = Position(33620,32726, 12)}, + {itemid = 11751, position = Position(33613,32715, 12)}, + {itemid = 11751, position = Position(33618,32712, 12)}, + {itemid = 11751, position = Position(33613,32725, 12)}, + {itemid = 11751, position = Position(33624,32718, 12)}, + {itemid = 11751, position = Position(33612,32714, 12)}, + {itemid = 11751, position = Position(33612,32724, 12)}, + {itemid = 11751, position = Position(33619,32713, 12)}, + {itemid = 11750, position = Position(33615,32723, 12)}, + {itemid = 11750, position = Position(33612,32718, 12)}, + {itemid = 11750, position = Position(33613,32720, 12)}, + {itemid = 11750, position = Position(33614,32721, 12)}, + {itemid = 11750, position = Position(33621,32725, 12)}, + {itemid = 11750, position = Position(33615,32714, 12)}, + {itemid = 11750, position = Position(33614,32713, 12)}, + {itemid = 11749, position = Position(33624,32717, 12)}, + {itemid = 11749, position = Position(33625,32716, 12)}, + {itemid = 11749, position = Position(33618,32726, 12)}, + {itemid = 11749, position = Position(33616,32727, 12)}, + {itemid = 11749, position = Position(33619,32725, 12)}, + {itemid = 11748, position = Position(33614,32723, 12)}, + {itemid = 11748, position = Position(33613,32724, 12)}, + {itemid = 11748, position = Position(33619,32726, 12)}, + {itemid = 11748, position = Position(33620,32725, 12)}, + {itemid = 11748, position = Position(33620,32712, 12)}, + {itemid = 11747, position = Position(33613,32714, 12)}, + {itemid = 11747, position = Position(33619,32712, 12)}, + {itemid = 11747, position = Position(33613,32724, 12)}, + {itemid = 11747, position = Position(33612,32713, 12)}, + {itemid = 11747, position = Position(33612,32723, 12)}, + {itemid = 11746, position = Position(33614,32714, 12)}, + {itemid = 11746, position = Position(33614,32723, 12)}, + {itemid = 11746, position = Position(33612,32720, 12)}, + {itemid = 11746, position = Position(33613,32721, 12)}, + {itemid = 11746, position = Position(33613,32713, 12)}, + {itemid = 11745, position = Position(33618,32727, 12)}, + {itemid = 11745, position = Position(33619,32726, 12)}, + {itemid = 11745, position = Position(33625,32717, 12)}, + {itemid = 11743, position = Position(33621,32725, 12)}, + {itemid = 11743, position = Position(33621,32712, 12)}, + {itemid = 11743, position = Position(33615,32723, 12)}, + {itemid = 11743, position = Position(33611,32713, 12)}, + {itemid = 11743, position = Position(33611,32723, 12)}, + {itemid = 11743, position = Position(33614,32715, 12)}, + {itemid = 11742, position = Position(33614,32722, 12)}, + {itemid = 11742, position = Position(33613,32725, 12)}, + {itemid = 11742, position = Position(33612,32719, 12)}, + {itemid = 11742, position = Position(33613,32712, 12)}, + {itemid = 11741, position = Position(33620,32725, 12)}, + {itemid = 11741, position = Position(33617,32727, 12)}, + {itemid = 11741, position = Position(33611,32718, 12)}, + {itemid = 11739, position = Position(33625,32720, 12)}, + {itemid = 11735, position = Position(33625,32718, 12)}, + {itemid = 11732, position = Position(33625,32719, 12)}, + {itemid = 11696, position = Position(33619,32724, 12)}, + {itemid = 11693, position = Position(33613,32722, 12)}, + {itemid = 11692, position = Position(33619,32721, 12)}, + {itemid = 11691, position = Position(33623,32720, 12)}, + {itemid = 11666, position = Position(33620,32723, 12)}, + {itemid = 11664, position = Position(33615,32719, 12)}, + {itemid = 11649, position = Position(33622,32720, 12)}, + {itemid = 11649, position = Position(33618,32716, 12)}, + {itemid = 11648, position = Position(33617,32717, 12)}, + {itemid = 11647, position = Position(33621,32721, 12)}, + {itemid = 11646, position = Position(33621,32712, 12)}, + {itemid = 11646, position = Position(33625,32718, 12)}, + {itemid = 11645, position = Position(33618,32726, 12)}, + {itemid = 11645, position = Position(33624,32717, 12)}, + {itemid = 11644, position = Position(33620,32712, 12)}, + {itemid = 11644, position = Position(33614,32713, 12)}, + {itemid = 11643, position = Position(33613,32724, 12)}, + {itemid = 11642, position = Position(33613,32714, 12)}, + {itemid = 11641, position = Position(33614,32724, 12)}, + {itemid = 11641, position = Position(33619,32726, 12)}, + {itemid = 11638, position = Position(33614,32715, 12)}, + {itemid = 11560, position = Position(33616,32722, 12)}, + {itemid = 11559, position = Position(33620,32721, 12)}, + {itemid = 11559, position = Position(33621,32720, 12)}, + {itemid = 11559, position = Position(33618,32722, 12)}, + {itemid = 11558, position = Position(33621,32717, 12)}, + {itemid = 11557, position = Position(33616,32719, 12)}, + {itemid = 11557, position = Position(33617,32718, 12)}, + {itemid = 11557, position = Position(33618,32717, 12)}, + {itemid = 11555, position = Position(33617,32719, 12)}, + {itemid = 11555, position = Position(33618,32718, 12)}, + {itemid = 11554, position = Position(33620,32720, 12)}, + {itemid = 11554, position = Position(33618,32721, 12)}, + {itemid = 11552, position = Position(33621,32719, 12)}, + {itemid = 11552, position = Position(33621,32718, 12)}, + {itemid = 11551, position = Position(33617,32722, 12)}, + {itemid = 11551, position = Position(33619,32721, 12)}, + {itemid = 11550, position = Position(33616,32721, 12)}, + {itemid = 11550, position = Position(33616,32720, 12)}, + {itemid = 11549, position = Position(33620,32717, 12)}, + {itemid = 11549, position = Position(33619,32717, 12)}, + {itemid = 11548, position = Position(33619, 32718, 12)}, + {itemid = 11548, position = Position(33620, 32718, 12)}, + {itemid = 11548, position = Position(33618, 32719, 12)}, + {itemid = 11548, position = Position(33619, 32719, 12)}, + {itemid = 11548, position = Position(33620, 32719, 12)}, + {itemid = 11548, position = Position(33617, 32720, 12)}, + {itemid = 11548, position = Position(33618, 32720, 12)}, + {itemid = 11548, position = Position(33619, 32720, 12)}, + {itemid = 11548, position = Position(33617, 32721, 12)}, + {itemid = 11504, position = Position(33619,32722, 12)}, + {itemid = 11504, position = Position(33621,32715, 12)}, + {itemid = 11504, position = Position(33619,32721, 12)}, + {itemid = 11504, position = Position(33620,32723, 12)}, + {itemid = 11504, position = Position(33621,32716, 12)}, + {itemid = 11504, position = Position(33621,32714, 12)}, + {itemid = 11504, position = Position(33619,32716, 12)}, + {itemid = 11504, position = Position(33619,32717, 12)}, + {itemid = 11504, position = Position(33619,32723, 12)}, + {itemid = 11504, position = Position(33619,32724, 12)}, + {itemid = 11504, position = Position(33620,32724, 12)}, + {itemid = 11504, position = Position(33620,32721, 12)}, + {itemid = 11504, position = Position(33620,32727, 12)}, + {itemid = 11504, position = Position(33620,32722, 12)}, + {itemid = 11504, position = Position(33621,32713, 12)}, + {itemid = 11504, position = Position(33620,32720, 12)}, + {itemid = 11504, position = Position(33620,32716, 12)}, + {itemid = 11504, position = Position(33620,32717, 12)}, + {itemid = 11504, position = Position(33620,32714, 12)}, + {itemid = 11504, position = Position(33621,32717, 12)}, + {itemid = 11504, position = Position(33620,32715, 12)}, + {itemid = 11504, position = Position(33625,32727, 12)}, + {itemid = 11504, position = Position(33621,32719, 12)}, + {itemid = 11504, position = Position(33624,32715, 12)}, + {itemid = 11504, position = Position(33624,32714, 12)}, + {itemid = 11504, position = Position(33624,32713, 12)}, + {itemid = 11504, position = Position(33624,32716, 12)}, + {itemid = 11504, position = Position(33624,32720, 12)}, + {itemid = 11504, position = Position(33624,32719, 12)}, + {itemid = 11504, position = Position(33624,32721, 12)}, + {itemid = 11504, position = Position(33624,32712, 12)}, + {itemid = 11504, position = Position(33623,32726, 12)}, + {itemid = 11504, position = Position(33623,32722, 12)}, + {itemid = 11504, position = Position(33623,32727, 12)}, + {itemid = 11504, position = Position(33623,32723, 12)}, + {itemid = 11504, position = Position(33623,32725, 12)}, + {itemid = 11504, position = Position(33623,32724, 12)}, + {itemid = 11504, position = Position(33623,32721, 12)}, + {itemid = 11504, position = Position(33624,32722, 12)}, + {itemid = 11504, position = Position(33624,32724, 12)}, + {itemid = 11504, position = Position(33625,32722, 12)}, + {itemid = 11504, position = Position(33625,32721, 12)}, + {itemid = 11504, position = Position(33625,32723, 12)}, + {itemid = 11504, position = Position(33625,32725, 12)}, + {itemid = 11504, position = Position(33625,32724, 12)}, + {itemid = 11504, position = Position(33624,32723, 12)}, + {itemid = 11504, position = Position(33625,32715, 12)}, + {itemid = 11504, position = Position(33625,32713, 12)}, + {itemid = 11504, position = Position(33624,32725, 12)}, + {itemid = 11504, position = Position(33625,32714, 12)}, + {itemid = 11504, position = Position(33624,32726, 12)}, + {itemid = 11504, position = Position(33625,32712, 12)}, + {itemid = 11504, position = Position(33624,32727, 12)}, + {itemid = 11504, position = Position(33621,32718, 12)}, + {itemid = 11504, position = Position(33623,32720, 12)}, + {itemid = 11504, position = Position(33623,32718, 12)}, + {itemid = 11504, position = Position(33622,32715, 12)}, + {itemid = 11504, position = Position(33622,32714, 12)}, + {itemid = 11504, position = Position(33622,32713, 12)}, + {itemid = 11504, position = Position(33622,32716, 12)}, + {itemid = 11504, position = Position(33622,32718, 12)}, + {itemid = 11504, position = Position(33622,32717, 12)}, + {itemid = 11504, position = Position(33619,32715, 12)}, + {itemid = 11504, position = Position(33621,32727, 12)}, + {itemid = 11504, position = Position(33621,32724, 12)}, + {itemid = 11504, position = Position(33621,32720, 12)}, + {itemid = 11504, position = Position(33621,32726, 12)}, + {itemid = 11504, position = Position(33621,32721, 12)}, + {itemid = 11504, position = Position(33621,32723, 12)}, + {itemid = 11504, position = Position(33621,32722, 12)}, + {itemid = 11504, position = Position(33623,32719, 12)}, + {itemid = 11504, position = Position(33622,32719, 12)}, + {itemid = 11504, position = Position(33622,32721, 12)}, + {itemid = 11504, position = Position(33623,32714, 12)}, + {itemid = 11504, position = Position(33623,32713, 12)}, + {itemid = 11504, position = Position(33623,32715, 12)}, + {itemid = 11504, position = Position(33623,32717, 12)}, + {itemid = 11504, position = Position(33623,32716, 12)}, + {itemid = 11504, position = Position(33622,32720, 12)}, + {itemid = 11504, position = Position(33623,32712, 12)}, + {itemid = 11504, position = Position(33622,32726, 12)}, + {itemid = 11504, position = Position(33622,32722, 12)}, + {itemid = 11504, position = Position(33622,32727, 12)}, + {itemid = 11504, position = Position(33622,32723, 12)}, + {itemid = 11504, position = Position(33622,32725, 12)}, + {itemid = 11504, position = Position(33622,32724, 12)}, + {itemid = 11504, position = Position(33619,32714, 12)}, + {itemid = 11504, position = Position(33618,32716, 12)}, + {itemid = 11504, position = Position(33614,32727, 12)}, + {itemid = 11504, position = Position(33615,32719, 12)}, + {itemid = 11504, position = Position(33615,32720, 12)}, + {itemid = 11504, position = Position(33615,32721, 12)}, + {itemid = 11504, position = Position(33615,32722, 12)}, + {itemid = 11504, position = Position(33615,32718, 12)}, + {itemid = 11504, position = Position(33615,32716, 12)}, + {itemid = 11504, position = Position(33615,32717, 12)}, + {itemid = 11504, position = Position(33611,32725, 12)}, + {itemid = 11504, position = Position(33611,32724, 12)}, + {itemid = 11504, position = Position(33615,32713, 12)}, + {itemid = 11504, position = Position(33615,32724, 12)}, + {itemid = 11504, position = Position(33615,32726, 12)}, + {itemid = 11504, position = Position(33616,32715, 12)}, + {itemid = 11504, position = Position(33616,32716, 12)}, + {itemid = 11504, position = Position(33616,32717, 12)}, + {itemid = 11504, position = Position(33615,32725, 12)}, + {itemid = 11504, position = Position(33616,32714, 12)}, + {itemid = 11504, position = Position(33612,32727, 12)}, + {itemid = 11504, position = Position(33616,32713, 12)}, + {itemid = 11504, position = Position(33615,32727, 12)}, + {itemid = 11504, position = Position(33616,32718, 12)}, + {itemid = 11504, position = Position(33615,32712, 12)}, + {itemid = 11504, position = Position(33614,32726, 12)}, + {itemid = 11504, position = Position(33613,32719, 12)}, + {itemid = 11504, position = Position(33613,32726, 12)}, + {itemid = 11504, position = Position(33613,32727, 12)}, + {itemid = 11504, position = Position(33614,32712, 12)}, + {itemid = 11504, position = Position(33613,32718, 12)}, + {itemid = 11504, position = Position(33613,32716, 12)}, + {itemid = 11504, position = Position(33613,32717, 12)}, + {itemid = 11504, position = Position(33612,32725, 12)}, + {itemid = 11504, position = Position(33611,32726, 12)}, + {itemid = 11504, position = Position(33612,32717, 12)}, + {itemid = 11504, position = Position(33612,32715, 12)}, + {itemid = 11504, position = Position(33614,32720, 12)}, + {itemid = 11504, position = Position(33611,32727, 12)}, + {itemid = 11504, position = Position(33614,32725, 12)}, + {itemid = 11504, position = Position(33612,32716, 12)}, + {itemid = 11504, position = Position(33614,32719, 12)}, + {itemid = 11504, position = Position(33614,32717, 12)}, + {itemid = 11504, position = Position(33614,32718, 12)}, + {itemid = 11504, position = Position(33614,32716, 12)}, + {itemid = 11504, position = Position(33616,32719, 12)}, + {itemid = 11504, position = Position(33616,32712, 12)}, + {itemid = 11504, position = Position(33616,32720, 12)}, + {itemid = 11504, position = Position(33611,32716, 12)}, + {itemid = 11504, position = Position(33618,32713, 12)}, + {itemid = 11504, position = Position(33618,32714, 12)}, + {itemid = 11504, position = Position(33618,32715, 12)}, + {itemid = 11504, position = Position(33611,32717, 12)}, + {itemid = 11504, position = Position(33617,32725, 12)}, + {itemid = 11504, position = Position(33617,32726, 12)}, + {itemid = 11504, position = Position(33617,32724, 12)}, + {itemid = 11504, position = Position(33617,32723, 12)}, + {itemid = 11504, position = Position(33611,32715, 12)}, + {itemid = 11504, position = Position(33618,32717, 12)}, + {itemid = 11504, position = Position(33618,32724, 12)}, + {itemid = 11504, position = Position(33618,32725, 12)}, + {itemid = 11504, position = Position(33611,32714, 12)}, + {itemid = 11504, position = Position(33625,32726, 12)}, + {itemid = 11504, position = Position(33618,32723, 12)}, + {itemid = 11504, position = Position(33618,32721, 12)}, + {itemid = 11504, position = Position(33618,32722, 12)}, + {itemid = 11504, position = Position(33618,32718, 12)}, + {itemid = 11504, position = Position(33617,32722, 12)}, + {itemid = 11504, position = Position(33612,32726, 12)}, + {itemid = 11504, position = Position(33616,32726, 12)}, + {itemid = 11504, position = Position(33616,32723, 12)}, + {itemid = 11504, position = Position(33617,32714, 12)}, + {itemid = 11504, position = Position(33617,32715, 12)}, + {itemid = 11504, position = Position(33617,32713, 12)}, + {itemid = 11504, position = Position(33616,32725, 12)}, + {itemid = 11504, position = Position(33617,32712, 12)}, + {itemid = 11504, position = Position(33616,32724, 12)}, + {itemid = 11504, position = Position(33616,32722, 12)}, + {itemid = 11504, position = Position(33617,32716, 12)}, + {itemid = 11504, position = Position(33617,32718, 12)}, + {itemid = 11504, position = Position(33616,32721, 12)}, + {itemid = 11504, position = Position(33617,32719, 12)}, + {itemid = 11504, position = Position(33617,32717, 12)}, + {itemid = 414, position = Position(33612,32721, 12)}, + {itemid = 414, position = Position(33611,32713, 12)}, + {itemid = 414, position = Position(33624,32718, 12)}, + {itemid = 414, position = Position(33624,32717, 12)}, + {itemid = 414, position = Position(33611,32721, 12)}, + {itemid = 414, position = Position(33612,32723, 12)}, + {itemid = 414, position = Position(33612,32724, 12)}, + {itemid = 414, position = Position(33612,32720, 12)}, + {itemid = 414, position = Position(33612,32722, 12)}, + {itemid = 414, position = Position(33612,32719, 12)}, + {itemid = 414, position = Position(33625,32716, 12)}, + {itemid = 414, position = Position(33611,32720, 12)}, + {itemid = 414, position = Position(33611,32718, 12)}, + {itemid = 414, position = Position(33625,32717, 12)}, + {itemid = 414, position = Position(33625,32719, 12)}, + {itemid = 414, position = Position(33611,32719, 12)}, + {itemid = 414, position = Position(33612,32718, 12)}, + {itemid = 414, position = Position(33612,32712, 12)}, + {itemid = 414, position = Position(33612,32714, 12)}, + {itemid = 414, position = Position(33611,32723, 12)}, + {itemid = 414, position = Position(33612,32713, 12)}, + {itemid = 414, position = Position(33625,32718, 12)}, + {itemid = 414, position = Position(33611,32722, 12)}, + {itemid = 414, position = Position(33625,32720, 12)}, + {itemid = 414, position = Position(33619,32712, 12)}, + {itemid = 414, position = Position(33613,32713, 12)}, + {itemid = 414, position = Position(33620,32725, 12)}, + {itemid = 414, position = Position(33616,32727, 12)}, + {itemid = 414, position = Position(33620,32713, 12)}, + {itemid = 414, position = Position(33620,32726, 12)}, + {itemid = 414, position = Position(33615,32723, 12)}, + {itemid = 414, position = Position(33621,32712, 12)}, + {itemid = 414, position = Position(33621,32725, 12)}, + {itemid = 414, position = Position(33615,32715, 12)}, + {itemid = 414, position = Position(33620,32712, 12)}, + {itemid = 414, position = Position(33619,32727, 12)}, + {itemid = 414, position = Position(33618,32726, 12)}, + {itemid = 414, position = Position(33618,32727, 12)}, + {itemid = 414, position = Position(33617,32727, 12)}, + {itemid = 414, position = Position(33619,32725, 12)}, + {itemid = 414, position = Position(33618,32712, 12)}, + {itemid = 414, position = Position(33619,32726, 12)}, + {itemid = 414, position = Position(33613,32712, 12)}, + {itemid = 414, position = Position(33615,32714, 12)}, + {itemid = 414, position = Position(33619,32713, 12)}, + {itemid = 414, position = Position(33613,32722, 12)}, + {itemid = 414, position = Position(33613,32723, 12)}, + {itemid = 414, position = Position(33613,32724, 12)}, + {itemid = 414, position = Position(33613,32721, 12)}, + {itemid = 414, position = Position(33613,32715, 12)}, + {itemid = 414, position = Position(33613,32720, 12)}, + {itemid = 414, position = Position(33613,32714, 12)}, + {itemid = 414, position = Position(33622,32712, 12)}, + {itemid = 414, position = Position(33613,32725, 12)}, + {itemid = 414, position = Position(33614,32714, 12)}, + {itemid = 414, position = Position(33614,32723, 12)}, + {itemid = 414, position = Position(33614,32724, 12)}, + {itemid = 414, position = Position(33614,32713, 12)}, + {itemid = 414, position = Position(33614,32722, 12)}, + {itemid = 414, position = Position(33614,32715, 12)}, + {itemid = 414, position = Position(33614,32721, 12)}, + {itemid = 414, position = Position(33611,32712, 12)} +} +local function transformArea() + for x = 33611, 33625 do + for y = 32712, 32727 do + local position = Position(x, y, 12) + local tile = Tile(position) + if not tile then + return + end + local ground = tile:getGround() + if not ground then + return + end + local grounds = ground:getId() + local items = tile:getItems() + if items then + for i = 1, #items do + local item = items[i] + if item then + item:remove() + end + end + end + ground:remove() + end + end + for i = 1, #corrupted do + local item = corrupted[i] + local ground = Tile(item.position):getGround() + local transformid = item.itemid + local tp = Game.createItem(item.itemid, 1, item.position) + end + return true +end + +local ferumbrasAscendantHabitatCorrupted = Action() +function ferumbrasAscendantHabitatCorrupted.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 10044 then + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Corrupted) >= 1 then + player:say('The lever are stucke, need some time to it can be moveable again.', TALKTYPE_MONSTER_SAY) + return true + end + Game.createMonster('lovely yielothax', Position(33619, 32722, 12), true, true) + addEvent(transformArea, 2 * 1000) + item:transform(10045) + local basin = Tile(Position(33628, 32721, 12)):getItemById(12070) + if basin then + basin:getPosition():sendMagicEffect(CONST_ME_ENERGYAREA) + basin:transform(24852) + end + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Corrupted, 1) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats, Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The room transforms into a completely different landscape.') + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats) >= 8 then + addEvent(functionRevert, 1 * 60 * 60 * 1000) + end + elseif item.itemid == 10045 then + item:transform(10044) + end + return true +end + +ferumbrasAscendantHabitatCorrupted:aid(34311) +ferumbrasAscendantHabitatCorrupted:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/habitat_desert.lua b/data/scripts/actions/quests/ferumbras_ascendant/habitat_desert.lua new file mode 100644 index 00000000000..d0a3fbb7100 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/habitat_desert.lua @@ -0,0 +1,385 @@ +local desert = { + {itemid = 13505, position = Position(33642,32683, 12)}, + {itemid = 13505, position = Position(33643,32682, 12)}, + {itemid = 9059, position = Position(33641,32680, 12)}, + {itemid = 9059, position = Position(33641,32683, 12)}, + {itemid = 9059, position = Position(33641,32681, 12)}, + {itemid = 9059, position = Position(33641,32682, 12)}, + {itemid = 9059, position = Position(33641,32679, 12)}, + {itemid = 9059, position = Position(33641,32677, 12)}, + {itemid = 9059, position = Position(33640,32690, 12)}, + {itemid = 9059, position = Position(33641,32678, 12)}, + {itemid = 9059, position = Position(33640,32691, 12)}, + {itemid = 9059, position = Position(33641,32676, 12)}, + {itemid = 9059, position = Position(33640,32689, 12)}, + {itemid = 9059, position = Position(33641,32684, 12)}, + {itemid = 9059, position = Position(33641,32686, 12)}, + {itemid = 9059, position = Position(33642,32678, 12)}, + {itemid = 9059, position = Position(33642,32677, 12)}, + {itemid = 9059, position = Position(33642,32679, 12)}, + {itemid = 9059, position = Position(33642,32680, 12)}, + {itemid = 9059, position = Position(33641,32685, 12)}, + {itemid = 9059, position = Position(33642,32676, 12)}, + {itemid = 9059, position = Position(33641,32690, 12)}, + {itemid = 9059, position = Position(33641,32691, 12)}, + {itemid = 9059, position = Position(33641,32687, 12)}, + {itemid = 9059, position = Position(33641,32688, 12)}, + {itemid = 9059, position = Position(33641,32689, 12)}, + {itemid = 9059, position = Position(33640,32688, 12)}, + {itemid = 9059, position = Position(33640,32686, 12)}, + {itemid = 9059, position = Position(33639,32685, 12)}, + {itemid = 9059, position = Position(33639,32684, 12)}, + {itemid = 9059, position = Position(33639,32686, 12)}, + {itemid = 9059, position = Position(33639,32687, 12)}, + {itemid = 9059, position = Position(33639,32688, 12)}, + {itemid = 9059, position = Position(33639,32683, 12)}, + {itemid = 9059, position = Position(33639,32681, 12)}, + {itemid = 9059, position = Position(33639,32682, 12)}, + {itemid = 9059, position = Position(33639,32679, 12)}, + {itemid = 9059, position = Position(33639,32680, 12)}, + {itemid = 9059, position = Position(33640,32687, 12)}, + {itemid = 9059, position = Position(33639,32689, 12)}, + {itemid = 9059, position = Position(33640,32676, 12)}, + {itemid = 9059, position = Position(33640,32683, 12)}, + {itemid = 9059, position = Position(33640,32682, 12)}, + {itemid = 9059, position = Position(33640,32684, 12)}, + {itemid = 9059, position = Position(33640,32685, 12)}, + {itemid = 9059, position = Position(33639,32690, 12)}, + {itemid = 9059, position = Position(33640,32681, 12)}, + {itemid = 9059, position = Position(33640,32679, 12)}, + {itemid = 9059, position = Position(33640,32680, 12)}, + {itemid = 9059, position = Position(33646,32688, 12)}, + {itemid = 9059, position = Position(33646,32687, 12)}, + {itemid = 9059, position = Position(33642,32681, 12)}, + {itemid = 9059, position = Position(33642,32682, 12)}, + {itemid = 9059, position = Position(33642,32684, 12)}, + {itemid = 9059, position = Position(33644,32687, 12)}, + {itemid = 9059, position = Position(33644,32686, 12)}, + {itemid = 9059, position = Position(33644,32688, 12)}, + {itemid = 9059, position = Position(33644,32689, 12)}, + {itemid = 9059, position = Position(33644,32690, 12)}, + {itemid = 9059, position = Position(33644,32685, 12)}, + {itemid = 9059, position = Position(33644,32683, 12)}, + {itemid = 9059, position = Position(33644,32684, 12)}, + {itemid = 9059, position = Position(33646,32679, 12)}, + {itemid = 9059, position = Position(33644,32682, 12)}, + {itemid = 9059, position = Position(33646,32680, 12)}, + {itemid = 9059, position = Position(33644,32691, 12)}, + {itemid = 9059, position = Position(33645,32680, 12)}, + {itemid = 9059, position = Position(33645,32689, 12)}, + {itemid = 9059, position = Position(33645,32688, 12)}, + {itemid = 9059, position = Position(33645,32690, 12)}, + {itemid = 9059, position = Position(33645,32691, 12)}, + {itemid = 9059, position = Position(33645,32676, 12)}, + {itemid = 9059, position = Position(33645,32687, 12)}, + {itemid = 9059, position = Position(33645,32685, 12)}, + {itemid = 9059, position = Position(33645,32686, 12)}, + {itemid = 9059, position = Position(33645,32681, 12)}, + {itemid = 9059, position = Position(33645,32684, 12)}, + {itemid = 9059, position = Position(33639,32676, 12)}, + {itemid = 9059, position = Position(33646,32681, 12)}, + {itemid = 9059, position = Position(33644,32676, 12)}, + {itemid = 9059, position = Position(33642,32691, 12)}, + {itemid = 9059, position = Position(33642,32690, 12)}, + {itemid = 9059, position = Position(33643,32676, 12)}, + {itemid = 9059, position = Position(33643,32677, 12)}, + {itemid = 9059, position = Position(33643,32678, 12)}, + {itemid = 9059, position = Position(33642,32689, 12)}, + {itemid = 9059, position = Position(33642,32687, 12)}, + {itemid = 9059, position = Position(33642,32688, 12)}, + {itemid = 9059, position = Position(33642,32685, 12)}, + {itemid = 9059, position = Position(33642,32686, 12)}, + {itemid = 9059, position = Position(33644,32677, 12)}, + {itemid = 9059, position = Position(33643,32679, 12)}, + {itemid = 9059, position = Position(33643,32683, 12)}, + {itemid = 9059, position = Position(33643,32689, 12)}, + {itemid = 9059, position = Position(33643,32690, 12)}, + {itemid = 9059, position = Position(33643,32691, 12)}, + {itemid = 9059, position = Position(33646,32684, 12)}, + {itemid = 9059, position = Position(33643,32688, 12)}, + {itemid = 9059, position = Position(33643,32686, 12)}, + {itemid = 9059, position = Position(33643,32687, 12)}, + {itemid = 9059, position = Position(33643,32684, 12)}, + {itemid = 9059, position = Position(33643,32685, 12)}, + {itemid = 9059, position = Position(33638,32690, 12)}, + {itemid = 9059, position = Position(33639,32691, 12)}, + {itemid = 9059, position = Position(33637,32676, 12)}, + {itemid = 9059, position = Position(33637,32687, 12)}, + {itemid = 9059, position = Position(33637,32686, 12)}, + {itemid = 9059, position = Position(33636,32683, 12)}, + {itemid = 9059, position = Position(33637,32685, 12)}, + {itemid = 9059, position = Position(33637,32688, 12)}, + {itemid = 9059, position = Position(33647,32680, 12)}, + {itemid = 9059, position = Position(33648,32679, 12)}, + {itemid = 9059, position = Position(33648,32681, 12)}, + {itemid = 9059, position = Position(33646,32691, 12)}, + {itemid = 9059, position = Position(33638,32689, 12)}, + {itemid = 9059, position = Position(33637,32684, 12)}, + {itemid = 9059, position = Position(33637,32682, 12)}, + {itemid = 9059, position = Position(33647,32682, 12)}, + {itemid = 9059, position = Position(33647,32679, 12)}, + {itemid = 9059, position = Position(33647,32681, 12)}, + {itemid = 9059, position = Position(33637,32683, 12)}, + {itemid = 9059, position = Position(33635,32686, 12)}, + {itemid = 9059, position = Position(33635,32684, 12)}, + {itemid = 9059, position = Position(33635,32685, 12)}, + {itemid = 9059, position = Position(33647,32688, 12)}, + {itemid = 9059, position = Position(33638,32676, 12)}, + {itemid = 9059, position = Position(33648,32680, 12)}, + {itemid = 9059, position = Position(33638,32677, 12)}, + {itemid = 9059, position = Position(33638,32686, 12)}, + {itemid = 9059, position = Position(33638,32685, 12)}, + {itemid = 9059, position = Position(33636,32685, 12)}, + {itemid = 9059, position = Position(33636,32686, 12)}, + {itemid = 9059, position = Position(33638,32687, 12)}, + {itemid = 9059, position = Position(33648,32688, 12)}, + {itemid = 9059, position = Position(33636,32684, 12)}, + {itemid = 9059, position = Position(33638,32688, 12)}, + {itemid = 9059, position = Position(33638,32683, 12)}, + {itemid = 9059, position = Position(33638,32684, 12)}, + {itemid = 9059, position = Position(33638,32680, 12)}, + {itemid = 9059, position = Position(33638,32682, 12)}, + {itemid = 9059, position = Position(33638,32681, 12)}, + {itemid = 9059, position = Position(33638,32679, 12)}, + {itemid = 9059, position = Position(33638,32678, 12)}, + {itemid = 8346, position = Position(33646,32679, 12)}, + {itemid = 8346, position = Position(33644,32681, 12)}, + {itemid = 8346, position = Position(33637,32681, 12)}, + {itemid = 8346, position = Position(33645,32680, 12)}, + {itemid = 8346, position = Position(33636,32682, 12)}, + {itemid = 8346, position = Position(33635,32683, 12)}, + {itemid = 8345, position = Position(33646,32690, 12)}, + {itemid = 8345, position = Position(33643,32681, 12)}, + {itemid = 8345, position = Position(33646,32686, 12)}, + {itemid = 8345, position = Position(33647,32678, 12)}, + {itemid = 8345, position = Position(33647,32687, 12)}, + {itemid = 8344, position = Position(33636,32676, 12)}, + {itemid = 8344, position = Position(33636,32687, 12)}, + {itemid = 8344, position = Position(33638,32691, 12)}, + {itemid = 8344, position = Position(33637,32689, 12)}, + {itemid = 8344, position = Position(33637,32677, 12)}, + {itemid = 8343, position = Position(33645,32677, 12)}, + {itemid = 8343, position = Position(33646,32689, 12)}, + {itemid = 8343, position = Position(33643,32680, 12)}, + {itemid = 8343, position = Position(33648,32682, 12)}, + {itemid = 8343, position = Position(33644,32678, 12)}, + {itemid = 8343, position = Position(33646,32685, 12)}, + {itemid = 8343, position = Position(33647,32683, 12)}, + {itemid = 8342, position = Position(33634,32683, 12)}, + {itemid = 8342, position = Position(33646,32677, 12)}, + {itemid = 8342, position = Position(33635,32682, 12)}, + {itemid = 8342, position = Position(33645,32679, 12)}, + {itemid = 8342, position = Position(33644,32680, 12)}, + {itemid = 8342, position = Position(33636,32681, 12)}, + {itemid = 8341, position = Position(33647,32690, 12)}, + {itemid = 8341, position = Position(33648,32687, 12)}, + {itemid = 8341, position = Position(33647,32686, 12)}, + {itemid = 8341, position = Position(33647,32677, 12)}, + {itemid = 8340, position = Position(33636,32677, 12)}, + {itemid = 8340, position = Position(33636,32689, 12)}, + {itemid = 8340, position = Position(33637,32691, 12)}, + {itemid = 8340, position = Position(33635,32676, 12)}, + {itemid = 8340, position = Position(33634,32687, 12)}, + {itemid = 8339, position = Position(33648,32683, 12)}, + {itemid = 8339, position = Position(33648,32689, 12)}, + {itemid = 8339, position = Position(33644,32680, 12)}, + {itemid = 8339, position = Position(33647,32685, 12)}, + {itemid = 8339, position = Position(33645,32678, 12)}, + {itemid = 8339, position = Position(33646,32677, 12)}, + {itemid = 8338, position = Position(33646,32678, 12)}, + {itemid = 8338, position = Position(33637,32678, 12)}, + {itemid = 8338, position = Position(33634,32686, 12)}, + {itemid = 8338, position = Position(33637,32679, 12)}, + {itemid = 8338, position = Position(33634,32684, 12)}, + {itemid = 8338, position = Position(33636,32688, 12)}, + {itemid = 8338, position = Position(33637,32690, 12)}, + {itemid = 8338, position = Position(33634,32685, 12)}, + {itemid = 8338, position = Position(33637,32680, 12)}, + {itemid = 8337, position = Position(33647,32684, 12)}, + {itemid = 8337, position = Position(33646,32676, 12)}, + {itemid = 8337, position = Position(33647,32691, 12)}, + {itemid = 8337, position = Position(33648,32688, 12)}, + {itemid = 8337, position = Position(33644,32679, 12)}, + {itemid = 8336, position = Position(33648,32678, 12)}, + {itemid = 8335, position = Position(33647,32689, 12)}, + {itemid = 8335, position = Position(33635,32687, 12)}, + {itemid = 6219, position = Position(33642,32685, 12)}, + {itemid = 6219, position = Position(33642,32684, 12)}, + {itemid = 6219, position = Position(33639,32682, 12)}, + {itemid = 6219, position = Position(33639,32683, 12)}, + {itemid = 6219, position = Position(33643,32684, 12)}, + {itemid = 6218, position = Position(33641,32683, 12)}, + {itemid = 6218, position = Position(33640,32686, 12)}, + {itemid = 6218, position = Position(33643,32685, 12)}, + {itemid = 6218, position = Position(33640,32681, 12)}, + {itemid = 6218, position = Position(33642,32689, 12)}, + {itemid = 3622, position = Position(33640,32690, 12)}, + {itemid = 3621, position = Position(33638,32684, 12)}, + {itemid = 3613, position = Position(33642,32680, 12)}, + {itemid = 2736, position = Position(33640,32687, 12)}, + {itemid = 2728, position = Position(33639,32683, 12)}, + {itemid = 2726, position = Position(33642,32686, 12)}, + {itemid = 2725, position = Position(33640,32680, 12)}, + {itemid = 2725, position = Position(33643,32683, 12)}, + {itemid = 414, position = Position(33647,32686, 12)}, + {itemid = 414, position = Position(33647,32687, 12)}, + {itemid = 414, position = Position(33648,32685, 12)}, + {itemid = 414, position = Position(33646,32686, 12)}, + {itemid = 414, position = Position(33648,32686, 12)}, + {itemid = 414, position = Position(33648,32678, 12)}, + {itemid = 414, position = Position(33648,32687, 12)}, + {itemid = 414, position = Position(33648,32689, 12)}, + {itemid = 414, position = Position(33647,32685, 12)}, + {itemid = 414, position = Position(33647,32684, 12)}, + {itemid = 414, position = Position(33647,32683, 12)}, + {itemid = 414, position = Position(33646,32689, 12)}, + {itemid = 414, position = Position(33646,32677, 12)}, + {itemid = 414, position = Position(33646,32685, 12)}, + {itemid = 414, position = Position(33647,32678, 12)}, + {itemid = 414, position = Position(33648,32676, 12)}, + {itemid = 414, position = Position(33647,32691, 12)}, + {itemid = 414, position = Position(33648,32682, 12)}, + {itemid = 414, position = Position(33648,32677, 12)}, + {itemid = 414, position = Position(33646,32690, 12)}, + {itemid = 414, position = Position(33647,32676, 12)}, + {itemid = 414, position = Position(33648,32683, 12)}, + {itemid = 414, position = Position(33648,32684, 12)}, + {itemid = 414, position = Position(33647,32689, 12)}, + {itemid = 414, position = Position(33647,32690, 12)}, + {itemid = 414, position = Position(33646,32678, 12)}, + {itemid = 414, position = Position(33647,32677, 12)}, + {itemid = 414, position = Position(33646,32676, 12)}, + {itemid = 414, position = Position(33634,32676, 12)}, + {itemid = 414, position = Position(33648,32691, 12)}, + {itemid = 414, position = Position(33635,32681, 12)}, + {itemid = 414, position = Position(33635,32682, 12)}, + {itemid = 414, position = Position(33635,32683, 12)}, + {itemid = 414, position = Position(33635,32680, 12)}, + {itemid = 414, position = Position(33635,32678, 12)}, + {itemid = 414, position = Position(33635,32679, 12)}, + {itemid = 414, position = Position(33635,32677, 12)}, + {itemid = 414, position = Position(33635,32687, 12)}, + {itemid = 414, position = Position(33635,32689, 12)}, + {itemid = 414, position = Position(33636,32677, 12)}, + {itemid = 414, position = Position(33636,32678, 12)}, + {itemid = 414, position = Position(33635,32688, 12)}, + {itemid = 414, position = Position(33636,32676, 12)}, + {itemid = 414, position = Position(33635,32690, 12)}, + {itemid = 414, position = Position(33635,32691, 12)}, + {itemid = 414, position = Position(33636,32679, 12)}, + {itemid = 414, position = Position(33635,32676, 12)}, + {itemid = 414, position = Position(33634,32690, 12)}, + {itemid = 414, position = Position(33634,32680, 12)}, + {itemid = 414, position = Position(33634,32681, 12)}, + {itemid = 414, position = Position(33634,32682, 12)}, + {itemid = 414, position = Position(33634,32679, 12)}, + {itemid = 414, position = Position(33634,32677, 12)}, + {itemid = 414, position = Position(33634,32678, 12)}, + {itemid = 414, position = Position(33634,32691, 12)}, + {itemid = 414, position = Position(33634,32683, 12)}, + {itemid = 414, position = Position(33634,32685, 12)}, + {itemid = 414, position = Position(33634,32689, 12)}, + {itemid = 414, position = Position(33634,32684, 12)}, + {itemid = 414, position = Position(33634,32688, 12)}, + {itemid = 414, position = Position(33634,32686, 12)}, + {itemid = 414, position = Position(33634,32687, 12)}, + {itemid = 414, position = Position(33636,32680, 12)}, + {itemid = 414, position = Position(33636,32681, 12)}, + {itemid = 414, position = Position(33636,32682, 12)}, + {itemid = 414, position = Position(33645,32677, 12)}, + {itemid = 414, position = Position(33644,32681, 12)}, + {itemid = 414, position = Position(33645,32678, 12)}, + {itemid = 414, position = Position(33645,32679, 12)}, + {itemid = 414, position = Position(33638,32691, 12)}, + {itemid = 414, position = Position(33648,32690, 12)}, + {itemid = 414, position = Position(33643,32680, 12)}, + {itemid = 414, position = Position(33644,32680, 12)}, + {itemid = 414, position = Position(33642,32683, 12)}, + {itemid = 414, position = Position(33643,32682, 12)}, + {itemid = 414, position = Position(33643,32681, 12)}, + {itemid = 414, position = Position(33644,32679, 12)}, + {itemid = 414, position = Position(33637,32691, 12)}, + {itemid = 414, position = Position(33637,32689, 12)}, + {itemid = 414, position = Position(33636,32689, 12)}, + {itemid = 414, position = Position(33636,32690, 12)}, + {itemid = 414, position = Position(33636,32688, 12)}, + {itemid = 414, position = Position(33636,32687, 12)}, + {itemid = 414, position = Position(33637,32690, 12)}, + {itemid = 414, position = Position(33636,32691, 12)}, + {itemid = 414, position = Position(33637,32678, 12)}, + {itemid = 414, position = Position(33637,32681, 12)}, + {itemid = 414, position = Position(33637,32677, 12)}, + {itemid = 414, position = Position(33637,32680, 12)}, + {itemid = 414, position = Position(33637,32679, 12)}, + {itemid = 414, position = Position(33644,32678, 12)}, + {itemid = 231, position = Position(33640,32677, 12)}, + {itemid = 231, position = Position(33646,32683, 12)}, + {itemid = 231, position = Position(33639,32677, 12)}, + {itemid = 231, position = Position(33646,32682, 12)}, + {itemid = 231, position = Position(33639,32678, 12)}, + {itemid = 231, position = Position(33640,32678, 12)}, + {itemid = 231, position = Position(33645,32683, 12)}, + {itemid = 231, position = Position(33645,32682, 12)} +} + +local function transformArea() + for x = 33634, 33648 do + for y = 32676, 32691 do + local position = Position(x, y, 12) + local tile = Tile(position) + if not tile then + return + end + local ground = tile:getGround() + if not ground then + return + end + local grounds = ground:getId() + local items = tile:getItems() + for i = 1, #items do + local item = items[i] + if item then + item:remove() + end + end + ground:remove() + end + end + for i = 1, #desert do + local item = desert[i] + local ground = Tile(item.position):getGround() + local transformid = item.itemid + local tp = Game.createItem(item.itemid, 1, item.position) + end + return true +end + +local ferumbrasAscendantHabitatDesert = Action() +function ferumbrasAscendantHabitatDesert.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 10044 then + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Desert) >= 1 then + player:say('The lever are stucke, need some time to it can be moveable again.', TALKTYPE_MONSTER_SAY) + return true + end + Game.createMonster('lovely rotworm', Position(33641, 32684, 12), true, true) + addEvent(transformArea, 2 * 1000) + item:transform(10045) + local basin = Tile(Position(33631, 32685, 12)):getItemById(12070) + if basin then + basin:getPosition():sendMagicEffect(CONST_ME_ENERGYAREA) + basin:transform(24852) + end + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Desert, 1) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats, Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The room transforms into a completely different landscape.') + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats) >= 8 then + addEvent(functionRevert, 1 * 60 * 60 * 1000) + end + elseif item.itemid == 10045 then + item:transform(10044) + end + return true +end + +ferumbrasAscendantHabitatDesert:aid(34308) +ferumbrasAscendantHabitatDesert:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/habitat_dimension.lua b/data/scripts/actions/quests/ferumbras_ascendant/habitat_dimension.lua new file mode 100644 index 00000000000..700f3618c55 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/habitat_dimension.lua @@ -0,0 +1,421 @@ +local dimension = { + {itemid = 13643, position = Position(33639,32718, 12)}, + {itemid = 13643, position = Position(33638,32715, 12)}, + {itemid = 13643, position = Position(33645,32715, 12)}, + {itemid = 13643, position = Position(33644,32727, 12)}, + {itemid = 13643, position = Position(33637,32725, 12)}, + {itemid = 13643, position = Position(33639,32713, 12)}, + {itemid = 13643, position = Position(33638,32727, 12)}, + {itemid = 13643, position = Position(33647,32726, 12)}, + {itemid = 13643, position = Position(33641,32714, 12)}, + {itemid = 13643, position = Position(33643,32720, 12)}, + {itemid = 13643, position = Position(33644,32722, 12)}, + {itemid = 13643, position = Position(33636,32717, 12)}, + {itemid = 13643, position = Position(33636,32718, 12)}, + {itemid = 13643, position = Position(33636,32724, 12)}, + {itemid = 13643, position = Position(33646,32726, 12)}, + {itemid = 13642, position = Position(33637,32719, 12)}, + {itemid = 13642, position = Position(33638,32721, 12)}, + {itemid = 13642, position = Position(33639,32716, 12)}, + {itemid = 13642, position = Position(33636,32726, 12)}, + {itemid = 13642, position = Position(33637,32720, 12)}, + {itemid = 13642, position = Position(33644,32721, 12)}, + {itemid = 13642, position = Position(33645,32724, 12)}, + {itemid = 13642, position = Position(33645,32716, 12)}, + {itemid = 13642, position = Position(33640,32712, 12)}, + {itemid = 13641, position = Position(33646,32723, 12)}, + {itemid = 13641, position = Position(33646,32722, 12)}, + {itemid = 13641, position = Position(33648,32727, 12)}, + {itemid = 13641, position = Position(33647,32716, 12)}, + {itemid = 13641, position = Position(33644,32719, 12)}, + {itemid = 13641, position = Position(33644,32715, 12)}, + {itemid = 13641, position = Position(33642,32713, 12)}, + {itemid = 13641, position = Position(33637,32726, 12)}, + {itemid = 13641, position = Position(33641,32718, 12)}, + {itemid = 13641, position = Position(33645,32720, 12)}, + {itemid = 13641, position = Position(33640,32716, 12)}, + {itemid = 13641, position = Position(33639,32726, 12)}, + {itemid = 13641, position = Position(33635,32723, 12)}, + {itemid = 13641, position = Position(33638,32722, 12)}, + {itemid = 13641, position = Position(33648,32715, 12)}, + {itemid = 13641, position = Position(33648,32713, 12)}, + {itemid = 13641, position = Position(33635,32719, 12)}, + {itemid = 13641, position = Position(33648,32712, 12)}, + {itemid = 13641, position = Position(33634,32722, 12)}, + {itemid = 13640, position = Position(33643,32725, 12)}, + {itemid = 13640, position = Position(33639,32724, 12)}, + {itemid = 13640, position = Position(33639,32712, 12)}, + {itemid = 13640, position = Position(33645,32723, 12)}, + {itemid = 13640, position = Position(33644,32724, 12)}, + {itemid = 13640, position = Position(33641,32725, 12)}, + {itemid = 13639, position = Position(33640,32722, 12)}, + {itemid = 13639, position = Position(33640,32719, 12)}, + {itemid = 13639, position = Position(33645,32722, 12)}, + {itemid = 13639, position = Position(33636,32725, 12)}, + {itemid = 13639, position = Position(33643,32715, 12)}, + {itemid = 13639, position = Position(33638,32723, 12)}, + {itemid = 13639, position = Position(33637,32718, 12)}, + {itemid = 13639, position = Position(33646,32727, 12)}, + {itemid = 13639, position = Position(33634,32723, 12)}, + {itemid = 13639, position = Position(33638,32725, 12)}, + {itemid = 13639, position = Position(33648,32714, 12)}, + {itemid = 13639, position = Position(33640,32726, 12)}, + {itemid = 13639, position = Position(33641,32713, 12)}, + {itemid = 13639, position = Position(33641,32712, 12)}, + {itemid = 13639, position = Position(33641,32722, 12)}, + {itemid = 13639, position = Position(33637,32724, 12)}, + {itemid = 13639, position = Position(33642,32726, 12)}, + {itemid = 13639, position = Position(33643,32721, 12)}, + {itemid = 13639, position = Position(33637,32723, 12)}, + {itemid = 13639, position = Position(33643,32717, 12)}, + {itemid = 13638, position = Position(33648,32725, 12)}, + {itemid = 13638, position = Position(33645,32725, 12)}, + {itemid = 13638, position = Position(33635,32724, 12)}, + {itemid = 13638, position = Position(33642,32727, 12)}, + {itemid = 13638, position = Position(33642,32725, 12)}, + {itemid = 13638, position = Position(33638,32716, 12)}, + {itemid = 13638, position = Position(33647,32715, 12)}, + {itemid = 13638, position = Position(33642,32722, 12)}, + {itemid = 13638, position = Position(33635,32718, 12)}, + {itemid = 13638, position = Position(33644,32718, 12)}, + {itemid = 13638, position = Position(33640,32718, 12)}, + {itemid = 13638, position = Position(33637,32717, 12)}, + {itemid = 13637, position = Position(33638,32719, 12)}, + {itemid = 13637, position = Position(33638,32717, 12)}, + {itemid = 13637, position = Position(33638,32720, 12)}, + {itemid = 13637, position = Position(33640,32717, 12)}, + {itemid = 13637, position = Position(33645,32727, 12)}, + {itemid = 13637, position = Position(33641,32721, 12)}, + {itemid = 13637, position = Position(33644,32716, 12)}, + {itemid = 13637, position = Position(33641,32727, 12)}, + {itemid = 13637, position = Position(33639,32714, 12)}, + {itemid = 13637, position = Position(33645,32714, 12)}, + {itemid = 13637, position = Position(33645,32721, 12)}, + {itemid = 13637, position = Position(33648,32716, 12)}, + {itemid = 13637, position = Position(33639,32719, 12)}, + {itemid = 13637, position = Position(33639,32721, 12)}, + {itemid = 13637, position = Position(33646,32715, 12)}, + {itemid = 13637, position = Position(33639,32720, 12)}, + {itemid = 13637, position = Position(33647,32725, 12)}, + {itemid = 13636, position = Position(33639,32727, 12)}, + {itemid = 13636, position = Position(33636,32727, 12)}, + {itemid = 13636, position = Position(33647,32714, 12)}, + {itemid = 13636, position = Position(33644,32717, 12)}, + {itemid = 13636, position = Position(33640,32713, 12)}, + {itemid = 13636, position = Position(33640,32714, 12)}, + {itemid = 13636, position = Position(33639,32725, 12)}, + {itemid = 13636, position = Position(33639,32722, 12)}, + {itemid = 13636, position = Position(33640,32725, 12)}, + {itemid = 13636, position = Position(33639,32723, 12)}, + {itemid = 13636, position = Position(33635,32727, 12)}, + {itemid = 13636, position = Position(33647,32724, 12)}, + {itemid = 13636, position = Position(33641,32726, 12)}, + {itemid = 13636, position = Position(33646,32724, 12)}, + {itemid = 13636, position = Position(33647,32713, 12)}, + {itemid = 13636, position = Position(33636,32719, 12)}, + {itemid = 13636, position = Position(33644,32725, 12)}, + {itemid = 13636, position = Position(33644,32726, 12)}, + {itemid = 13636, position = Position(33636,32720, 12)}, + {itemid = 13636, position = Position(33640,32715, 12)}, + {itemid = 13636, position = Position(33644,32723, 12)}, + {itemid = 13636, position = Position(33648,32717, 12)}, + {itemid = 13636, position = Position(33644,32720, 12)}, + {itemid = 13636, position = Position(33648,32726, 12)}, + {itemid = 13636, position = Position(33645,32717, 12)}, + {itemid = 13636, position = Position(33646,32725, 12)}, + {itemid = 13636, position = Position(33645,32726, 12)}, + {itemid = 13636, position = Position(33646,32716, 12)}, + {itemid = 13636, position = Position(33646,32721, 12)}, + {itemid = 13636, position = Position(33638,32724, 12)}, + {itemid = 13636, position = Position(33647,32727, 12)}, + {itemid = 13636, position = Position(33638,32726, 12)}, + {itemid = 13636, position = Position(33646,32714, 12)}, + {itemid = 13636, position = Position(33643,32716, 12)}, + {itemid = 13636, position = Position(33638,32718, 12)}, + {itemid = 13636, position = Position(33635,32725, 12)}, + {itemid = 13636, position = Position(33637,32727, 12)}, + {itemid = 13636, position = Position(33638,32714, 12)}, + {itemid = 13636, position = Position(33643,32723, 12)}, + {itemid = 13636, position = Position(33643,32722, 12)}, + {itemid = 13636, position = Position(33640,32727, 12)}, + {itemid = 13636, position = Position(33639,32715, 12)}, + {itemid = 13636, position = Position(33634,32724, 12)}, + {itemid = 13636, position = Position(33642,32714, 12)}, + {itemid = 13636, position = Position(33642,32715, 12)}, + {itemid = 13636, position = Position(33639,32717, 12)}, + {itemid = 13636, position = Position(33642,32721, 12)}, + {itemid = 13636, position = Position(33643,32727, 12)}, + {itemid = 13636, position = Position(33643,32726, 12)}, + {itemid = 13631, position = Position(33634,32726, 12)}, + {itemid = 13631, position = Position(33634,32720, 12)}, + {itemid = 13631, position = Position(33637,32712, 12)}, + {itemid = 13631, position = Position(33635,32721, 12)}, + {itemid = 13631, position = Position(33642,32724, 12)}, + {itemid = 13631, position = Position(33647,32718, 12)}, + {itemid = 13630, position = Position(33646,32718, 12)}, + {itemid = 13630, position = Position(33648,32722, 12)}, + {itemid = 13629, position = Position(33643,32712, 12)}, + {itemid = 13629, position = Position(33648,32723, 12)}, + {itemid = 13629, position = Position(33648,32721, 12)}, + {itemid = 13629, position = Position(33634,32716, 12)}, + {itemid = 13629, position = Position(33647,32720, 12)}, + {itemid = 13629, position = Position(33641,32724, 12)}, + {itemid = 13629, position = Position(33635,32721, 12)}, + {itemid = 13629, position = Position(33636,32722, 12)}, + {itemid = 13629, position = Position(33646,32719, 12)}, + {itemid = 13628, position = Position(33646,32712, 12)}, + {itemid = 13628, position = Position(33636,32722, 12)}, + {itemid = 13628, position = Position(33634,32726, 12)}, + {itemid = 13628, position = Position(33642,32724, 12)}, + {itemid = 13628, position = Position(33644,32713, 12)}, + {itemid = 13628, position = Position(33635,32716, 12)}, + {itemid = 13628, position = Position(33637,32713, 12)}, + {itemid = 13627, position = Position(33635,32720, 12)}, + {itemid = 13627, position = Position(33637,32721, 12)}, + {itemid = 13627, position = Position(33634,32725, 12)}, + {itemid = 13627, position = Position(33643,32724, 12)}, + {itemid = 13627, position = Position(33647,32717, 12)}, + {itemid = 13627, position = Position(33638,32712, 12)}, + {itemid = 13627, position = Position(33642,32723, 12)}, + {itemid = 13627, position = Position(33635,32726, 12)}, + {itemid = 13627, position = Position(33634,32718, 12)}, + {itemid = 13626, position = Position(33640,32723, 12)}, + {itemid = 13626, position = Position(33647,32722, 12)}, + {itemid = 13626, position = Position(33645,32718, 12)}, + {itemid = 13626, position = Position(33646,32717, 12)}, + {itemid = 13625, position = Position(33642,32712, 12)}, + {itemid = 13625, position = Position(33648,32724, 12)}, + {itemid = 13625, position = Position(33646,32720, 12)}, + {itemid = 13625, position = Position(33647,32723, 12)}, + {itemid = 13625, position = Position(33640,32724, 12)}, + {itemid = 13625, position = Position(33634,32717, 12)}, + {itemid = 13625, position = Position(33643,32714, 12)}, + {itemid = 13625, position = Position(33647,32721, 12)}, + {itemid = 13625, position = Position(33636,32723, 12)}, + {itemid = 13625, position = Position(33645,32719, 12)}, + {itemid = 13625, position = Position(33635,32722, 12)}, + {itemid = 13624, position = Position(33637,32716, 12)}, + {itemid = 13624, position = Position(33638,32713, 12)}, + {itemid = 13624, position = Position(33634,32727, 12)}, + {itemid = 13624, position = Position(33637,32722, 12)}, + {itemid = 13624, position = Position(33644,32714, 12)}, + {itemid = 13624, position = Position(33647,32712, 12)}, + {itemid = 13624, position = Position(33646,32713, 12)}, + {itemid = 13624, position = Position(33635,32717, 12)}, + {itemid = 13623, position = Position(33643,32713, 12)}, + {itemid = 13622, position = Position(33636,32723, 12)}, + {itemid = 13622, position = Position(33637,32714, 12)}, + {itemid = 13622, position = Position(33637,32715, 12)}, + {itemid = 13622, position = Position(33634,32719, 12)}, + {itemid = 13621, position = Position(33648,32718, 12)}, + {itemid = 13621, position = Position(33641,32723, 12)}, + {itemid = 13621, position = Position(33636,32721, 12)}, + {itemid = 13620, position = Position(33636,32716, 12)}, + {itemid = 13620, position = Position(33645,32713, 12)}, + {itemid = 13620, position = Position(33643,32724, 12)}, + {itemid = 13620, position = Position(33642,32724, 12)}, + {itemid = 13620, position = Position(33634,32721, 12)}, + {itemid = 13620, position = Position(33641,32724, 12)}, + {itemid = 13620, position = Position(33635,32726, 12)}, + {itemid = 13619, position = Position(33641,32717, 12)}, + {itemid = 13619, position = Position(33641,32715, 12)}, + {itemid = 13619, position = Position(33642,32717, 12)}, + {itemid = 13619, position = Position(33641,32716, 12)}, + {itemid = 13619, position = Position(33642,32716, 12)}, + {itemid = 13618, position = Position(33639,32716, 12)}, + {itemid = 13618, position = Position(33639,32712, 12)}, + {itemid = 13617, position = Position(33643,32717, 12)}, + {itemid = 13617, position = Position(33644,32716, 12)}, + {itemid = 13616, position = Position(33644,32715, 12)}, + {itemid = 13616, position = Position(33642,32713, 12)}, + {itemid = 13615, position = Position(33639,32715, 12)}, + {itemid = 13615, position = Position(33640,32714, 12)}, + {itemid = 13614, position = Position(33642,32715, 12)}, + {itemid = 13614, position = Position(33641,32712, 12)}, + {itemid = 13613, position = Position(33640,32715, 12)}, + {itemid = 13613, position = Position(33641,32714, 12)}, + {itemid = 13612, position = Position(33643,32716, 12)}, + {itemid = 13611, position = Position(33640,32712, 12)}, + {itemid = 13611, position = Position(33640,32716, 12)}, + {itemid = 13611, position = Position(33641,32713, 12)}, + {itemid = 13610, position = Position(33642,32714, 12)}, + {itemid = 13607, position = Position(33643,32715, 12)}, + {itemid = 13479, position = Position(33641,32717, 12)}, + {itemid = 13479, position = Position(33646,32720, 12)}, + {itemid = 13477, position = Position(33642,32724, 12)}, + {itemid = 13476, position = Position(33636,32722, 12)}, + {itemid = 11560, position = Position(33639,32722, 12)}, + {itemid = 11559, position = Position(33641,32722, 12)}, + {itemid = 11559, position = Position(33644,32720, 12)}, + {itemid = 11559, position = Position(33643,32721, 12)}, + {itemid = 11558, position = Position(33644,32717, 12)}, + {itemid = 11557, position = Position(33639,32719, 12)}, + {itemid = 11557, position = Position(33640,32718, 12)}, + {itemid = 11557, position = Position(33641,32717, 12)}, + {itemid = 11555, position = Position(33640,32719, 12)}, + {itemid = 11555, position = Position(33641,32718, 12)}, + {itemid = 11554, position = Position(33643,32720, 12)}, + {itemid = 11554, position = Position(33641,32721, 12)}, + {itemid = 11552, position = Position(33644,32719, 12)}, + {itemid = 11552, position = Position(33644,32718, 12)}, + {itemid = 11551, position = Position(33642,32721, 12)}, + {itemid = 11551, position = Position(33640,32722, 12)}, + {itemid = 11550, position = Position(33639,32720, 12)}, + {itemid = 11550, position = Position(33639,32721, 12)}, + {itemid = 11549, position = Position(33643,32717, 12)}, + {itemid = 11549, position = Position(33642,32717, 12)}, + {itemid = 11548, position = Position(33642, 32718, 12)}, + {itemid = 11548, position = Position(33643, 32718, 12)}, + {itemid = 11548, position = Position(33641, 32719, 12)}, + {itemid = 11548, position = Position(33642, 32719, 12)}, + {itemid = 11548, position = Position(33643, 32719, 12)}, + {itemid = 11548, position = Position(33640, 32720, 12)}, + {itemid = 11548, position = Position(33641, 32720, 12)}, + {itemid = 11548, position = Position(33642, 32720, 12)}, + {itemid = 11548, position = Position(33640, 32721, 12)}, + {itemid = 414, position = Position(33635,32716, 12)}, + {itemid = 414, position = Position(33635,32720, 12)}, + {itemid = 414, position = Position(33647,32720, 12)}, + {itemid = 414, position = Position(33635,32721, 12)}, + {itemid = 414, position = Position(33635,32726, 12)}, + {itemid = 414, position = Position(33647,32721, 12)}, + {itemid = 414, position = Position(33635,32713, 12)}, + {itemid = 414, position = Position(33636,32712, 12)}, + {itemid = 414, position = Position(33647,32723, 12)}, + {itemid = 414, position = Position(33647,32719, 12)}, + {itemid = 414, position = Position(33635,32717, 12)}, + {itemid = 414, position = Position(33647,32718, 12)}, + {itemid = 414, position = Position(33635,32715, 12)}, + {itemid = 414, position = Position(33647,32717, 12)}, + {itemid = 414, position = Position(33635,32714, 12)}, + {itemid = 414, position = Position(33635,32722, 12)}, + {itemid = 414, position = Position(33647,32722, 12)}, + {itemid = 414, position = Position(33635,32712, 12)}, + {itemid = 414, position = Position(33634,32720, 12)}, + {itemid = 414, position = Position(33634,32726, 12)}, + {itemid = 414, position = Position(33634,32715, 12)}, + {itemid = 414, position = Position(33648,32722, 12)}, + {itemid = 414, position = Position(33634,32716, 12)}, + {itemid = 414, position = Position(33648,32721, 12)}, + {itemid = 414, position = Position(33648,32723, 12)}, + {itemid = 414, position = Position(33648,32724, 12)}, + {itemid = 414, position = Position(33634,32714, 12)}, + {itemid = 414, position = Position(33634,32713, 12)}, + {itemid = 414, position = Position(33634,32727, 12)}, + {itemid = 414, position = Position(33634,32717, 12)}, + {itemid = 414, position = Position(33648,32719, 12)}, + {itemid = 414, position = Position(33634,32721, 12)}, + {itemid = 414, position = Position(33634,32725, 12)}, + {itemid = 414, position = Position(33648,32720, 12)}, + {itemid = 414, position = Position(33636,32713, 12)}, + {itemid = 414, position = Position(33634,32718, 12)}, + {itemid = 414, position = Position(33634,32719, 12)}, + {itemid = 414, position = Position(33648,32718, 12)}, + {itemid = 414, position = Position(33636,32714, 12)}, + {itemid = 414, position = Position(33646,32713, 12)}, + {itemid = 414, position = Position(33647,32712, 12)}, + {itemid = 414, position = Position(33641,32723, 12)}, + {itemid = 414, position = Position(33641,32724, 12)}, + {itemid = 414, position = Position(33642,32712, 12)}, + {itemid = 414, position = Position(33645,32712, 12)}, + {itemid = 414, position = Position(33645,32713, 12)}, + {itemid = 414, position = Position(33640,32724, 12)}, + {itemid = 414, position = Position(33640,32723, 12)}, + {itemid = 414, position = Position(33645,32718, 12)}, + {itemid = 414, position = Position(33644,32714, 12)}, + {itemid = 414, position = Position(33644,32712, 12)}, + {itemid = 414, position = Position(33643,32713, 12)}, + {itemid = 414, position = Position(33643,32714, 12)}, + {itemid = 414, position = Position(33644,32713, 12)}, + {itemid = 414, position = Position(33643,32712, 12)}, + {itemid = 414, position = Position(33642,32723, 12)}, + {itemid = 414, position = Position(33642,32724, 12)}, + {itemid = 414, position = Position(33643,32724, 12)}, + {itemid = 414, position = Position(33636,32715, 12)}, + {itemid = 414, position = Position(33645,32719, 12)}, + {itemid = 414, position = Position(33638,32713, 12)}, + {itemid = 414, position = Position(33637,32712, 12)}, + {itemid = 414, position = Position(33637,32713, 12)}, + {itemid = 414, position = Position(33637,32714, 12)}, + {itemid = 414, position = Position(33636,32723, 12)}, + {itemid = 414, position = Position(33636,32721, 12)}, + {itemid = 414, position = Position(33636,32722, 12)}, + {itemid = 414, position = Position(33636,32716, 12)}, + {itemid = 414, position = Position(33646,32712, 12)}, + {itemid = 414, position = Position(33646,32720, 12)}, + {itemid = 414, position = Position(33646,32719, 12)}, + {itemid = 414, position = Position(33637,32722, 12)}, + {itemid = 414, position = Position(33638,32712, 12)}, + {itemid = 414, position = Position(33637,32715, 12)}, + {itemid = 414, position = Position(33646,32717, 12)}, + {itemid = 414, position = Position(33646,32718, 12)}, + {itemid = 414, position = Position(33637,32721, 12)}, + {itemid = 414, position = Position(33637,32716, 12)}, + {itemid = 414, position = Position(33634,32712, 12)}, + {itemid = 13608, position = Position(33640,32718, 12)}, + {itemid = 13608, position = Position(33640,32717, 12)} +} + +local function transformArea() + for x = 33634, 33648 do + for y = 32712, 32727 do + local position = Position(x, y, 12) + local tile = Tile(position) + if not tile then + return + end + local ground = tile:getGround() + if not ground then + return + end + local grounds = ground:getId() + local items = tile:getItems() + if items then + for i = 1, #items do + local item = items[i] + if item then + item:remove() + end + end + end + ground:remove() + end + end + for i = 1, #dimension do + local item = dimension[i] + local ground = Tile(item.position):getGround() + local transformid = item.itemid + local tp = Game.createItem(item.itemid, 1, item.position) + end + return true +end + +local ferumbrasAscendantHabitatDimension = Action() +function ferumbrasAscendantHabitatDimension.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 10044 then + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Dimension) >= 1 then + player:say('The lever are stucke, need some time to it can be moveable again.', TALKTYPE_MONSTER_SAY) + return true + end + Game.createMonster('lovely souleater', Position(33642, 32722, 12), true, true) + addEvent(transformArea, 2 * 1000) + item:transform(10045) + local basin = Tile(Position(33631, 32721, 12)):getItemById(12070) + if basin then + basin:getPosition():sendMagicEffect(CONST_ME_ENERGYAREA) + basin:transform(24852) + end + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Dimension, 1) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats, Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The room transforms into a completely different landscape.') + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats) >= 8 then + addEvent(functionRevert, 1 * 60 * 60 * 1000) + end + elseif item.itemid == 10045 then + item:transform(10044) + end + return true +end + +ferumbrasAscendantHabitatDimension:aid(34312) +ferumbrasAscendantHabitatDimension:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/habitat_grass.lua b/data/scripts/actions/quests/ferumbras_ascendant/habitat_grass.lua new file mode 100644 index 00000000000..629e0d0fb67 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/habitat_grass.lua @@ -0,0 +1,453 @@ +local grass = { + {itemid = 17684, position = Position(33639,32664, 12)}, + {itemid = 9057, position = Position(33643,32658, 12)}, + {itemid = 9054, position = Position(33640,32658, 12)}, + {itemid = 9053, position = Position(33645,32670, 12)}, + {itemid = 9052, position = Position(33645,32672, 12)}, + {itemid = 9050, position = Position(33648,32669, 12)}, + {itemid = 9049, position = Position(33638,32673, 12)}, + {itemid = 9048, position = Position(33643,32668, 12)}, + {itemid = 9048, position = Position(33643,32671, 12)}, + {itemid = 9047, position = Position(33639,32666, 12)}, + {itemid = 9047, position = Position(33643,32665, 12)}, + {itemid = 9047, position = Position(33641,32669, 12)}, + {itemid = 9047, position = Position(33640,32661, 12)}, + {itemid = 9046, position = Position(33642,32667, 12)}, + {itemid = 9046, position = Position(33645,32673, 12)}, + {itemid = 9045, position = Position(33639,32667, 12)}, + {itemid = 9045, position = Position(33644,32670, 12)}, + {itemid = 9045, position = Position(33637,32665, 12)}, + {itemid = 9043, position = Position(33640,32664, 12)}, + {itemid = 9043, position = Position(33640,32666, 12)}, + {itemid = 9043, position = Position(33640,32665, 12)}, + {itemid = 9043, position = Position(33640,32669, 12)}, + {itemid = 9043, position = Position(33640,32668, 12)}, + {itemid = 9043, position = Position(33641,32663, 12)}, + {itemid = 9043, position = Position(33641,32662, 12)}, + {itemid = 9043, position = Position(33641,32664, 12)}, + {itemid = 9043, position = Position(33641,32665, 12)}, + {itemid = 9043, position = Position(33640,32667, 12)}, + {itemid = 9043, position = Position(33641,32661, 12)}, + {itemid = 9043, position = Position(33641,32659, 12)}, + {itemid = 9043, position = Position(33641,32660, 12)}, + {itemid = 9043, position = Position(33640,32670, 12)}, + {itemid = 9043, position = Position(33641,32658, 12)}, + {itemid = 9043, position = Position(33640,32660, 12)}, + {itemid = 9043, position = Position(33639,32670, 12)}, + {itemid = 9043, position = Position(33639,32673, 12)}, + {itemid = 9043, position = Position(33638,32668, 12)}, + {itemid = 9043, position = Position(33638,32669, 12)}, + {itemid = 9043, position = Position(33638,32670, 12)}, + {itemid = 9043, position = Position(33638,32671, 12)}, + {itemid = 9043, position = Position(33638,32667, 12)}, + {itemid = 9043, position = Position(33638,32665, 12)}, + {itemid = 9043, position = Position(33638,32666, 12)}, + {itemid = 9043, position = Position(33646,32673, 12)}, + {itemid = 9043, position = Position(33640,32659, 12)}, + {itemid = 9043, position = Position(33638,32672, 12)}, + {itemid = 9043, position = Position(33639,32660, 12)}, + {itemid = 9043, position = Position(33639,32669, 12)}, + {itemid = 9043, position = Position(33641,32666, 12)}, + {itemid = 9043, position = Position(33639,32671, 12)}, + {itemid = 9043, position = Position(33639,32659, 12)}, + {itemid = 9043, position = Position(33639,32668, 12)}, + {itemid = 9043, position = Position(33639,32662, 12)}, + {itemid = 9043, position = Position(33639,32665, 12)}, + {itemid = 9043, position = Position(33639,32661, 12)}, + {itemid = 9043, position = Position(33641,32667, 12)}, + {itemid = 9043, position = Position(33642,32658, 12)}, + {itemid = 9043, position = Position(33641,32670, 12)}, + {itemid = 9043, position = Position(33644,32665, 12)}, + {itemid = 9043, position = Position(33644,32667, 12)}, + {itemid = 9043, position = Position(33646,32664, 12)}, + {itemid = 9043, position = Position(33644,32669, 12)}, + {itemid = 9043, position = Position(33644,32664, 12)}, + {itemid = 9043, position = Position(33644,32661, 12)}, + {itemid = 9043, position = Position(33644,32663, 12)}, + {itemid = 9043, position = Position(33644,32659, 12)}, + {itemid = 9043, position = Position(33644,32660, 12)}, + {itemid = 9043, position = Position(33644,32658, 12)}, + {itemid = 9043, position = Position(33644,32671, 12)}, + {itemid = 9043, position = Position(33645,32658, 12)}, + {itemid = 9043, position = Position(33646,32660, 12)}, + {itemid = 9043, position = Position(33646,32659, 12)}, + {itemid = 9043, position = Position(33645,32669, 12)}, + {itemid = 9043, position = Position(33646,32663, 12)}, + {itemid = 9043, position = Position(33645,32665, 12)}, + {itemid = 9043, position = Position(33645,32660, 12)}, + {itemid = 9043, position = Position(33645,32664, 12)}, + {itemid = 9043, position = Position(33645,32659, 12)}, + {itemid = 9043, position = Position(33641,32668, 12)}, + {itemid = 9043, position = Position(33643,32670, 12)}, + {itemid = 9043, position = Position(33643,32667, 12)}, + {itemid = 9043, position = Position(33642,32662, 12)}, + {itemid = 9043, position = Position(33642,32663, 12)}, + {itemid = 9043, position = Position(33642,32664, 12)}, + {itemid = 9043, position = Position(33642,32665, 12)}, + {itemid = 9043, position = Position(33642,32661, 12)}, + {itemid = 9043, position = Position(33642,32659, 12)}, + {itemid = 9043, position = Position(33642,32660, 12)}, + {itemid = 9043, position = Position(33646,32669, 12)}, + {itemid = 9043, position = Position(33638,32662, 12)}, + {itemid = 9043, position = Position(33643,32669, 12)}, + {itemid = 9043, position = Position(33642,32666, 12)}, + {itemid = 9043, position = Position(33642,32669, 12)}, + {itemid = 9043, position = Position(33643,32662, 12)}, + {itemid = 9043, position = Position(33643,32663, 12)}, + {itemid = 9043, position = Position(33643,32664, 12)}, + {itemid = 9043, position = Position(33642,32668, 12)}, + {itemid = 9043, position = Position(33643,32661, 12)}, + {itemid = 9043, position = Position(33643,32659, 12)}, + {itemid = 9043, position = Position(33643,32660, 12)}, + {itemid = 9043, position = Position(33646,32668, 12)}, + {itemid = 9043, position = Position(33638,32661, 12)}, + {itemid = 9043, position = Position(33640,32662, 12)}, + {itemid = 9043, position = Position(33648,32662, 12)}, + {itemid = 9043, position = Position(33637,32660, 12)}, + {itemid = 9043, position = Position(33635,32664, 12)}, + {itemid = 9043, position = Position(33635,32665, 12)}, + {itemid = 9043, position = Position(33647,32662, 12)}, + {itemid = 9043, position = Position(33647,32660, 12)}, + {itemid = 9043, position = Position(33647,32663, 12)}, + {itemid = 9043, position = Position(33648,32670, 12)}, + {itemid = 9043, position = Position(33647,32661, 12)}, + {itemid = 9043, position = Position(33637,32668, 12)}, + {itemid = 9043, position = Position(33648,32668, 12)}, + {itemid = 9043, position = Position(33637,32662, 12)}, + {itemid = 9043, position = Position(33637,32667, 12)}, + {itemid = 9043, position = Position(33637,32663, 12)}, + {itemid = 9043, position = Position(33637,32664, 12)}, + {itemid = 9043, position = Position(33637,32670, 12)}, + {itemid = 9043, position = Position(33637,32666, 12)}, + {itemid = 9043, position = Position(33636,32666, 12)}, + {itemid = 9043, position = Position(33637,32671, 12)}, + {itemid = 9043, position = Position(33648,32661, 12)}, + {itemid = 9043, position = Position(33636,32665, 12)}, + {itemid = 9043, position = Position(33636,32664, 12)}, + {itemid = 9043, position = Position(33647,32668, 12)}, + {itemid = 9043, position = Position(33636,32663, 12)}, + {itemid = 9043, position = Position(33638,32660, 12)}, + {itemid = 9043, position = Position(33647,32669, 12)}, + {itemid = 9043, position = Position(33636,32671, 12)}, + {itemid = 9043, position = Position(33637,32672, 12)}, + {itemid = 9043, position = Position(33647,32667, 12)}, + {itemid = 9043, position = Position(33647,32670, 12)}, + {itemid = 7710, position = Position(33646,32670, 12)}, + {itemid = 7710, position = Position(33645,32663, 12)}, + {itemid = 7710, position = Position(33642,32670, 12)}, + {itemid = 7710, position = Position(33636,32668, 12)}, + {itemid = 7710, position = Position(33634,32665, 12)}, + {itemid = 7710, position = Position(33636,32660, 12)}, + {itemid = 7710, position = Position(33634,32664, 12)}, + {itemid = 7710, position = Position(33642,32671, 12)}, + {itemid = 7710, position = Position(33635,32671, 12)}, + {itemid = 7709, position = Position(33647,32666, 12)}, + {itemid = 7709, position = Position(33644,32668, 12)}, + {itemid = 7709, position = Position(33644,32666, 12)}, + {itemid = 7709, position = Position(33637,32659, 12)}, + {itemid = 7664, position = Position(33638,32659, 12)}, + {itemid = 7664, position = Position(33637,32661, 12)}, + {itemid = 7664, position = Position(33646,32662, 12)}, + {itemid = 7664, position = Position(33640,32663, 12)}, + {itemid = 7664, position = Position(33635,32663, 12)}, + {itemid = 7664, position = Position(33639,32658, 12)}, + {itemid = 7664, position = Position(33637,32669, 12)}, + {itemid = 7664, position = Position(33636,32670, 12)}, + {itemid = 7664, position = Position(33644,32673, 12)}, + {itemid = 7664, position = Position(33636,32662, 12)}, + {itemid = 7664, position = Position(33639,32664, 12)}, + {itemid = 7664, position = Position(33646,32667, 12)}, + {itemid = 7664, position = Position(33645,32668, 12)}, + {itemid = 7663, position = Position(33648,32660, 12)}, + {itemid = 7663, position = Position(33640,32673, 12)}, + {itemid = 7663, position = Position(33648,32667, 12)}, + {itemid = 7663, position = Position(33647,32659, 12)}, + {itemid = 7663, position = Position(33646,32672, 12)}, + {itemid = 7663, position = Position(33645,32663, 12)}, + {itemid = 7663, position = Position(33645,32671, 12)}, + {itemid = 7663, position = Position(33647,32673, 12)}, + {itemid = 7663, position = Position(33644,32662, 12)}, + {itemid = 7663, position = Position(33638,32664, 12)}, + {itemid = 7663, position = Position(33639,32672, 12)}, + {itemid = 7663, position = Position(33646,32658, 12)}, + {itemid = 7663, position = Position(33643,32666, 12)}, + {itemid = 7662, position = Position(33636,32667, 12)}, + {itemid = 7662, position = Position(33644,32672, 12)}, + {itemid = 7662, position = Position(33646,32661, 12)}, + {itemid = 7662, position = Position(33635,32666, 12)}, + {itemid = 7662, position = Position(33637,32673, 12)}, + {itemid = 7662, position = Position(33636,32672, 12)}, + {itemid = 7661, position = Position(33648,32663, 12)}, + {itemid = 7661, position = Position(33646,32670, 12)}, + {itemid = 7661, position = Position(33638,32663, 12)}, + {itemid = 7661, position = Position(33640,32671, 12)}, + {itemid = 7661, position = Position(33642,32670, 12)}, + {itemid = 7661, position = Position(33645,32661, 12)}, + {itemid = 7661, position = Position(33644,32668, 12)}, + {itemid = 7661, position = Position(33647,32664, 12)}, + {itemid = 7661, position = Position(33646,32665, 12)}, + {itemid = 7660, position = Position(33645,32667, 12)}, + {itemid = 7660, position = Position(33636,32661, 12)}, + {itemid = 7660, position = Position(33634,32663, 12)}, + {itemid = 7660, position = Position(33645,32662, 12)}, + {itemid = 7660, position = Position(33639,32663, 12)}, + {itemid = 7660, position = Position(33636,32669, 12)}, + {itemid = 7660, position = Position(33643,32673, 12)}, + {itemid = 7660, position = Position(33635,32662, 12)}, + {itemid = 7660, position = Position(33635,32670, 12)}, + {itemid = 7660, position = Position(33638,32658, 12)}, + {itemid = 7660, position = Position(33646,32666, 12)}, + {itemid = 7660, position = Position(33636,32659, 12)}, + {itemid = 7659, position = Position(33647,32672, 12)}, + {itemid = 7659, position = Position(33648,32666, 12)}, + {itemid = 7659, position = Position(33648,32659, 12)}, + {itemid = 7659, position = Position(33646,32671, 12)}, + {itemid = 7659, position = Position(33640,32672, 12)}, + {itemid = 7659, position = Position(33641,32673, 12)}, + {itemid = 7659, position = Position(33645,32666, 12)}, + {itemid = 7659, position = Position(33645,32662, 12)}, + {itemid = 7659, position = Position(33647,32658, 12)}, + {itemid = 7659, position = Position(33648,32673, 12)}, + {itemid = 7658, position = Position(33635,32672, 12)}, + {itemid = 7658, position = Position(33642,32672, 12)}, + {itemid = 7658, position = Position(33636,32673, 12)}, + {itemid = 7658, position = Position(33636,32661, 12)}, + {itemid = 7658, position = Position(33634,32666, 12)}, + {itemid = 7658, position = Position(33635,32667, 12)}, + {itemid = 7658, position = Position(33636,32669, 12)}, + {itemid = 7658, position = Position(33646,32671, 12)}, + {itemid = 7657, position = Position(33642,32671, 12)}, + {itemid = 7657, position = Position(33648,32664, 12)}, + {itemid = 7657, position = Position(33645,32668, 12)}, + {itemid = 7657, position = Position(33645,32662, 12)}, + {itemid = 7657, position = Position(33647,32665, 12)}, + {itemid = 7657, position = Position(33646,32666, 12)}, + {itemid = 7657, position = Position(33646,32671, 12)}, + {itemid = 7657, position = Position(33640,32672, 12)}, + {itemid = 7656, position = Position(33645,32667, 12)}, + {itemid = 7653, position = Position(33644,32662, 12)}, + {itemid = 7653, position = Position(33645,32671, 12)}, + {itemid = 7653, position = Position(33648,32671, 12)}, + {itemid = 7653, position = Position(33643,32666, 12)}, + {itemid = 7653, position = Position(33643,32672, 12)}, + {itemid = 7653, position = Position(33644,32666, 12)}, + {itemid = 7653, position = Position(33645,32666, 12)}, + {itemid = 7653, position = Position(33641,32671, 12)}, + {itemid = 7653, position = Position(33639,32672, 12)}, + {itemid = 7653, position = Position(33639,32663, 12)}, + {itemid = 7653, position = Position(33637,32669, 12)}, + {itemid = 7653, position = Position(33647,32671, 12)}, + {itemid = 7653, position = Position(33640,32663, 12)}, + {itemid = 7653, position = Position(33637,32661, 12)}, + {itemid = 6217, position = Position(33644,32664, 12)}, + {itemid = 6217, position = Position(33639,32665, 12)}, + {itemid = 6217, position = Position(33639,32667, 12)}, + {itemid = 6217, position = Position(33638,32660, 12)}, + {itemid = 6217, position = Position(33639,32673, 12)}, + {itemid = 6217, position = Position(33643,32664, 12)}, + {itemid = 6217, position = Position(33647,32668, 12)}, + {itemid = 6217, position = Position(33640,32670, 12)}, + {itemid = 6217, position = Position(33645,32673, 12)}, + {itemid = 6217, position = Position(33644,32660, 12)}, + {itemid = 6217, position = Position(33636,32665, 12)}, + {itemid = 6217, position = Position(33646,32669, 12)}, + {itemid = 6217, position = Position(33637,32672, 12)}, + {itemid = 6217, position = Position(33638,32665, 12)}, + {itemid = 6217, position = Position(33642,32671, 12)}, + {itemid = 6217, position = Position(33642,32664, 12)}, + {itemid = 6217, position = Position(33646,32672, 12)}, + {itemid = 6217, position = Position(33638,32672, 12)}, + {itemid = 6217, position = Position(33642,32662, 12)}, + {itemid = 6217, position = Position(33639,32662, 12)}, + {itemid = 4181, position = Position(33639,32666, 12)}, + {itemid = 4180, position = Position(33640,32667, 12)}, + {itemid = 4179, position = Position(33641,32668, 12)}, + {itemid = 3623, position = Position(33644,32666, 12)}, + {itemid = 3622, position = Position(33639,32666, 12)}, + {itemid = 3614, position = Position(33640,32668, 12)}, + {itemid = 3614, position = Position(33642,32661, 12)}, + {itemid = 3613, position = Position(33642,32666, 12)}, + {itemid = 3613, position = Position(33638,32671, 12)}, + {itemid = 3612, position = Position(33648,32668, 12)}, + {itemid = 3612, position = Position(33641,32659, 12)}, + {itemid = 3611, position = Position(33641,32660, 12)}, + {itemid = 2785, position = Position(33637,32670, 12)}, + {itemid = 2768, position = Position(33641,32663, 12)}, + {itemid = 2768, position = Position(33644,32668, 12)}, + {itemid = 2700, position = Position(33640,32664, 12)}, + {itemid = 2700, position = Position(33644,32670, 12)}, + {itemid = 2700, position = Position(33642,32665, 12)}, + {itemid = 2700, position = Position(33641,32666, 12)}, + {itemid = 2700, position = Position(33642,32668, 12)}, + {itemid = 2700, position = Position(33640,32669, 12)}, + {itemid = 414, position = Position(33646,32667, 12)}, + {itemid = 414, position = Position(33646,32666, 12)}, + {itemid = 414, position = Position(33646,32672, 12)}, + {itemid = 414, position = Position(33648,32659, 12)}, + {itemid = 414, position = Position(33646,32658, 12)}, + {itemid = 414, position = Position(33647,32672, 12)}, + {itemid = 414, position = Position(33647,32659, 12)}, + {itemid = 414, position = Position(33648,32672, 12)}, + {itemid = 414, position = Position(33648,32671, 12)}, + {itemid = 414, position = Position(33647,32658, 12)}, + {itemid = 414, position = Position(33647,32673, 12)}, + {itemid = 414, position = Position(33647,32671, 12)}, + {itemid = 414, position = Position(33647,32664, 12)}, + {itemid = 414, position = Position(33648,32660, 12)}, + {itemid = 414, position = Position(33646,32670, 12)}, + {itemid = 414, position = Position(33647,32665, 12)}, + {itemid = 414, position = Position(33648,32665, 12)}, + {itemid = 414, position = Position(33648,32667, 12)}, + {itemid = 414, position = Position(33648,32666, 12)}, + {itemid = 414, position = Position(33646,32662, 12)}, + {itemid = 414, position = Position(33646,32671, 12)}, + {itemid = 414, position = Position(33648,32664, 12)}, + {itemid = 414, position = Position(33646,32665, 12)}, + {itemid = 414, position = Position(33646,32661, 12)}, + {itemid = 414, position = Position(33648,32663, 12)}, + {itemid = 414, position = Position(33647,32666, 12)}, + {itemid = 414, position = Position(33648,32658, 12)}, + {itemid = 414, position = Position(33634,32658, 12)}, + {itemid = 414, position = Position(33645,32668, 12)}, + {itemid = 414, position = Position(33635,32669, 12)}, + {itemid = 414, position = Position(33635,32670, 12)}, + {itemid = 414, position = Position(33635,32671, 12)}, + {itemid = 414, position = Position(33635,32672, 12)}, + {itemid = 414, position = Position(33635,32668, 12)}, + {itemid = 414, position = Position(33635,32666, 12)}, + {itemid = 414, position = Position(33635,32667, 12)}, + {itemid = 414, position = Position(33635,32663, 12)}, + {itemid = 414, position = Position(33635,32662, 12)}, + {itemid = 414, position = Position(33635,32673, 12)}, + {itemid = 414, position = Position(33636,32659, 12)}, + {itemid = 414, position = Position(33636,32668, 12)}, + {itemid = 414, position = Position(33636,32669, 12)}, + {itemid = 414, position = Position(33636,32658, 12)}, + {itemid = 414, position = Position(33636,32667, 12)}, + {itemid = 414, position = Position(33636,32661, 12)}, + {itemid = 414, position = Position(33636,32662, 12)}, + {itemid = 414, position = Position(33636,32660, 12)}, + {itemid = 414, position = Position(33636,32670, 12)}, + {itemid = 414, position = Position(33635,32661, 12)}, + {itemid = 414, position = Position(33635,32659, 12)}, + {itemid = 414, position = Position(33634,32663, 12)}, + {itemid = 414, position = Position(33634,32664, 12)}, + {itemid = 414, position = Position(33634,32665, 12)}, + {itemid = 414, position = Position(33634,32662, 12)}, + {itemid = 414, position = Position(33634,32660, 12)}, + {itemid = 414, position = Position(33634,32661, 12)}, + {itemid = 414, position = Position(33634,32659, 12)}, + {itemid = 414, position = Position(33635,32660, 12)}, + {itemid = 414, position = Position(33634,32666, 12)}, + {itemid = 414, position = Position(33634,32668, 12)}, + {itemid = 414, position = Position(33634,32673, 12)}, + {itemid = 414, position = Position(33635,32658, 12)}, + {itemid = 414, position = Position(33634,32667, 12)}, + {itemid = 414, position = Position(33634,32672, 12)}, + {itemid = 414, position = Position(33634,32670, 12)}, + {itemid = 414, position = Position(33634,32671, 12)}, + {itemid = 414, position = Position(33634,32669, 12)}, + {itemid = 414, position = Position(33645,32671, 12)}, + {itemid = 414, position = Position(33636,32672, 12)}, + {itemid = 414, position = Position(33637,32658, 12)}, + {itemid = 414, position = Position(33643,32672, 12)}, + {itemid = 414, position = Position(33643,32673, 12)}, + {itemid = 414, position = Position(33644,32662, 12)}, + {itemid = 414, position = Position(33643,32666, 12)}, + {itemid = 414, position = Position(33642,32672, 12)}, + {itemid = 414, position = Position(33642,32673, 12)}, + {itemid = 414, position = Position(33642,32671, 12)}, + {itemid = 414, position = Position(33642,32670, 12)}, + {itemid = 414, position = Position(33644,32666, 12)}, + {itemid = 414, position = Position(33644,32672, 12)}, + {itemid = 414, position = Position(33645,32666, 12)}, + {itemid = 414, position = Position(33645,32667, 12)}, + {itemid = 414, position = Position(33644,32668, 12)}, + {itemid = 414, position = Position(33645,32663, 12)}, + {itemid = 414, position = Position(33645,32661, 12)}, + {itemid = 414, position = Position(33645,32662, 12)}, + {itemid = 414, position = Position(33644,32673, 12)}, + {itemid = 414, position = Position(33636,32673, 12)}, + {itemid = 414, position = Position(33641,32673, 12)}, + {itemid = 414, position = Position(33641,32671, 12)}, + {itemid = 414, position = Position(33638,32658, 12)}, + {itemid = 414, position = Position(33638,32659, 12)}, + {itemid = 414, position = Position(33638,32663, 12)}, + {itemid = 414, position = Position(33637,32673, 12)}, + {itemid = 414, position = Position(33637,32661, 12)}, + {itemid = 414, position = Position(33637,32669, 12)}, + {itemid = 414, position = Position(33637,32659, 12)}, + {itemid = 414, position = Position(33641,32672, 12)}, + {itemid = 414, position = Position(33638,32664, 12)}, + {itemid = 414, position = Position(33639,32663, 12)}, + {itemid = 414, position = Position(33640,32672, 12)}, + {itemid = 414, position = Position(33640,32673, 12)}, + {itemid = 414, position = Position(33639,32658, 12)}, + {itemid = 414, position = Position(33640,32671, 12)}, + {itemid = 414, position = Position(33639,32672, 12)}, + {itemid = 414, position = Position(33640,32663, 12)}, + {itemid = 414, position = Position(33639,32664, 12)}, + {itemid = 414, position = Position(33648,32673, 12)} +} + +local function transformArea() + for x = 33634, 33648 do + for y = 32658, 32673 do + local position = Position(x, y, 12) + local tile = Tile(position) + if not tile then + return + end + local ground = tile:getGround() + if not ground then + return + end + local grounds = ground:getId() + local items = tile:getItems() + for i = 1, #items do + local item = items[i] + if item then + item:remove() + end + end + ground:remove() + end + end + for i = 1, #grass do + local item = grass[i] + local ground = Tile(item.position):getGround() + local transformid = item.itemid + local tp = Game.createItem(item.itemid, 1, item.position) + end + return true +end + +local ferumbrasAscendantHabitatGlass = Action() +function ferumbrasAscendantHabitatGlass.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 10044 then + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Grass) >= 1 then + player:say('The lever are stucke, need some time to it can be moveable again.', TALKTYPE_MONSTER_SAY) + return true + end + Game.createMonster('lovely frazzlemaw', Position(33642, 32666, 12), true, true) + addEvent(transformArea, 2 * 1000) + item:transform(10045) + local basin = Tile(Position(33631, 32667, 12)):getItemById(12070) + if basin then + basin:getPosition():sendMagicEffect(CONST_ME_ENERGYAREA) + basin:transform(24852) + end + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Grass, 1) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats, Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The room transforms into a completely different landscape.') + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats) >= 8 then + addEvent(functionRevert, 1 * 60 * 60 * 1000) + end + elseif item.itemid == 10045 then + item:transform(10044) + end + return true +end + +ferumbrasAscendantHabitatGlass:aid(34306) +ferumbrasAscendantHabitatGlass:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/habitat_ice.lua b/data/scripts/actions/quests/ferumbras_ascendant/habitat_ice.lua new file mode 100644 index 00000000000..71dec78b589 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/habitat_ice.lua @@ -0,0 +1,468 @@ +local ice = { + {itemid = 7156, position = Position(33641,32702, 12)}, + {itemid = 7156, position = Position(33642,32706, 12)}, + {itemid = 7155, position = Position(33642,32702, 12)}, + {itemid = 7154, position = Position(33641,32701, 12)}, + {itemid = 7153, position = Position(33642,32707, 12)}, + {itemid = 7153, position = Position(33641,32703, 12)}, + {itemid = 7153, position = Position(33640,32702, 12)}, + {itemid = 7153, position = Position(33641,32706, 12)}, + {itemid = 7152, position = Position(33643,32703, 12)}, + {itemid = 7152, position = Position(33643,32707, 12)}, + {itemid = 7151, position = Position(33642,32700, 12)}, + {itemid = 7151, position = Position(33643,32702, 12)}, + {itemid = 7151, position = Position(33643,32705, 12)}, + {itemid = 7150, position = Position(33640,32701, 12)}, + {itemid = 7150, position = Position(33641,32705, 12)}, + {itemid = 7150, position = Position(33641,32700, 12)}, + {itemid = 7149, position = Position(33643,32706, 12)}, + {itemid = 7149, position = Position(33642,32701, 12)}, + {itemid = 7147, position = Position(33642,32703, 12)}, + {itemid = 7146, position = Position(33642,32705, 12)}, + {itemid = 7023, position = Position(33641,32696, 12)}, + {itemid = 7022, position = Position(33643,32708, 12)}, + {itemid = 7022, position = Position(33646,32698, 12)}, + {itemid = 7020, position = Position(33638,32695, 12)}, + {itemid = 6718, position = Position(33646,32696, 12)}, + {itemid = 6718, position = Position(33639,32695, 12)}, + {itemid = 6718, position = Position(33635,32701, 12)}, + {itemid = 6718, position = Position(33635,32696, 12)}, + {itemid = 6718, position = Position(33648,32701, 12)}, + {itemid = 6718, position = Position(33647,32707, 12)}, + {itemid = 6718, position = Position(33642,32707, 12)}, + {itemid = 6718, position = Position(33638,32707, 12)}, + {itemid = 6718, position = Position(33640,32708, 12)}, + {itemid = 6718, position = Position(33638,32704, 12)}, + {itemid = 6717, position = Position(33641,32708, 12)}, + {itemid = 6717, position = Position(33644,32696, 12)}, + {itemid = 6717, position = Position(33645,32709, 12)}, + {itemid = 6717, position = Position(33637,32707, 12)}, + {itemid = 6717, position = Position(33637,32704, 12)}, + {itemid = 6717, position = Position(33640,32694, 12)}, + {itemid = 6717, position = Position(33636,32702, 12)}, + {itemid = 6717, position = Position(33648,32704, 12)}, + {itemid = 6717, position = Position(33643,32700, 12)}, + {itemid = 6717, position = Position(33638,32699, 12)}, + {itemid = 6716, position = Position(33640,32705, 12)}, + {itemid = 6716, position = Position(33636,32701, 12)}, + {itemid = 6716, position = Position(33646,32709, 12)}, + {itemid = 6685, position = Position(33639,32703, 12)}, + {itemid = 6685, position = Position(33643,32704, 12)}, + {itemid = 6685, position = Position(33642,32702, 12)}, + {itemid = 6684, position = Position(33641,32705, 12)}, + {itemid = 6683, position = Position(33641,32704, 12)}, + {itemid = 6683, position = Position(33641,32702, 12)}, + {itemid = 6683, position = Position(33640,32703, 12)}, + {itemid = 6683, position = Position(33641,32703, 12)}, + {itemid = 6683, position = Position(33640,32704, 12)}, + {itemid = 6683, position = Position(33643,32703, 12)}, + {itemid = 6611, position = Position(33644,32703, 12)}, + {itemid = 6610, position = Position(33640,32701, 12)}, + {itemid = 6609, position = Position(33638,32703, 12)}, + {itemid = 6608, position = Position(33640,32705, 12)}, + {itemid = 6607, position = Position(33637,32702, 12)}, + {itemid = 6601, position = Position(33638,32703, 12)}, + {itemid = 6601, position = Position(33638,32702, 12)}, + {itemid = 6598, position = Position(33639,32704, 12)}, + {itemid = 6598, position = Position(33636,32702, 12)}, + {itemid = 6598, position = Position(33638,32705, 12)}, + {itemid = 6597, position = Position(33639,32705, 12)}, + {itemid = 6594, position = Position(33638,32704, 12)}, + {itemid = 6594, position = Position(33639,32702, 12)}, + {itemid = 6594, position = Position(33639,32701, 12)}, + {itemid = 6593, position = Position(33641,32700, 12)}, + {itemid = 6593, position = Position(33641,32698, 12)}, + {itemid = 6593, position = Position(33644,32704, 12)}, + {itemid = 6592, position = Position(33643,32697, 12)}, + {itemid = 6592, position = Position(33645,32697, 12)}, + {itemid = 6592, position = Position(33638,32694, 12)}, + {itemid = 6592, position = Position(33642,32706, 12)}, + {itemid = 6591, position = Position(33635,32698, 12)}, + {itemid = 6591, position = Position(33637,32695, 12)}, + {itemid = 6591, position = Position(33642,32708, 12)}, + {itemid = 6590, position = Position(33635,32709, 12)}, + {itemid = 6590, position = Position(33647,32694, 12)}, + {itemid = 6590, position = Position(33647,32708, 12)}, + {itemid = 6590, position = Position(33636,32694, 12)}, + {itemid = 6589, position = Position(33637,32703, 12)}, + {itemid = 6589, position = Position(33636,32708, 12)}, + {itemid = 6588, position = Position(33642,32701, 12)}, + {itemid = 6588, position = Position(33641,32697, 12)}, + {itemid = 6588, position = Position(33643,32709, 12)}, + {itemid = 6588, position = Position(33640,32696, 12)}, + {itemid = 6587, position = Position(33639,32707, 12)}, + {itemid = 6587, position = Position(33636,32706, 12)}, + {itemid = 6587, position = Position(33635,32707, 12)}, + {itemid = 6587, position = Position(33646,32709, 12)}, + {itemid = 6586, position = Position(33641,32706, 12)}, + {itemid = 6586, position = Position(33634,32697, 12)}, + {itemid = 6586, position = Position(33645,32704, 12)}, + {itemid = 6586, position = Position(33643,32702, 12)}, + {itemid = 6586, position = Position(33645,32696, 12)}, + {itemid = 6586, position = Position(33640,32707, 12)}, + {itemid = 6585, position = Position(33642,32699, 12)}, + {itemid = 6585, position = Position(33637,32704, 12)}, + {itemid = 6584, position = Position(33634,32698, 12)}, + {itemid = 6584, position = Position(33644,32698, 12)}, + {itemid = 6584, position = Position(33639,32708, 12)}, + {itemid = 6583, position = Position(33634,32706, 12)}, + {itemid = 6583, position = Position(33636,32709, 12)}, + {itemid = 6583, position = Position(33648,32708, 12)}, + {itemid = 6583, position = Position(33634,32708, 12)}, + {itemid = 6583, position = Position(33640,32694, 12)}, + {itemid = 6582, position = Position(33638,32696, 12)}, + {itemid = 6582, position = Position(33634,32705, 12)}, + {itemid = 6582, position = Position(33645,32706, 12)}, + {itemid = 6582, position = Position(33640,32706, 12)}, + {itemid = 6581, position = Position(33641,32707, 12)}, + {itemid = 6581, position = Position(33643,32699, 12)}, + {itemid = 6581, position = Position(33647,32705, 12)}, + {itemid = 6581, position = Position(33644,32707, 12)}, + {itemid = 6580, position = Position(33634,32709, 12)}, + {itemid = 6580, position = Position(33642,32705, 12)}, + {itemid = 4748, position = Position(33638,32708, 12)}, + {itemid = 4748, position = Position(33645,32694, 12)}, + {itemid = 4748, position = Position(33644,32695, 12)}, + {itemid = 4748, position = Position(33635,32703, 12)}, + {itemid = 4748, position = Position(33646,32707, 12)}, + {itemid = 4748, position = Position(33647,32702, 12)}, + {itemid = 4748, position = Position(33639,32700, 12)}, + {itemid = 4748, position = Position(33643,32704, 12)}, + {itemid = 4748, position = Position(33634,32704, 12)}, + {itemid = 4747, position = Position(33644,32701, 12)}, + {itemid = 4747, position = Position(33645,32707, 12)}, + {itemid = 4747, position = Position(33636,32699, 12)}, + {itemid = 4747, position = Position(33638,32700, 12)}, + {itemid = 4747, position = Position(33639,32703, 12)}, + {itemid = 4747, position = Position(33640,32704, 12)}, + {itemid = 4747, position = Position(33647,32704, 12)}, + {itemid = 4747, position = Position(33641,32705, 12)}, + {itemid = 4747, position = Position(33647,32698, 12)}, + {itemid = 4747, position = Position(33634,32696, 12)}, + {itemid = 4747, position = Position(33635,32697, 12)}, + {itemid = 4747, position = Position(33636,32707, 12)}, + {itemid = 4747, position = Position(33645,32702, 12)}, + {itemid = 4747, position = Position(33637,32708, 12)}, + {itemid = 4747, position = Position(33642,32696, 12)}, + {itemid = 4746, position = Position(33640,32698, 12)}, + {itemid = 4746, position = Position(33642,32702, 12)}, + {itemid = 4746, position = Position(33638,32706, 12)}, + {itemid = 4746, position = Position(33638,32697, 12)}, + {itemid = 4746, position = Position(33643,32703, 12)}, + {itemid = 4746, position = Position(33635,32702, 12)}, + {itemid = 4746, position = Position(33635,32694, 12)}, + {itemid = 4746, position = Position(33647,32699, 12)}, + {itemid = 4746, position = Position(33636,32695, 12)}, + {itemid = 4746, position = Position(33637,32696, 12)}, + {itemid = 4746, position = Position(33637,32705, 12)}, + {itemid = 4746, position = Position(33634,32700, 12)}, + {itemid = 4745, position = Position(33643,32694, 12)}, + {itemid = 4745, position = Position(33642,32695, 12)}, + {itemid = 4745, position = Position(33644,32700, 12)}, + {itemid = 4745, position = Position(33648,32696, 12)}, + {itemid = 4745, position = Position(33647,32697, 12)}, + {itemid = 4745, position = Position(33648,32699, 12)}, + {itemid = 4745, position = Position(33646,32706, 12)}, + {itemid = 4745, position = Position(33648,32705, 12)}, + {itemid = 4745, position = Position(33647,32703, 12)}, + {itemid = 4745, position = Position(33641,32702, 12)}, + {itemid = 4745, position = Position(33645,32699, 12)}, + {itemid = 4744, position = Position(33647,32701, 12)}, + {itemid = 4744, position = Position(33634,32703, 12)}, + {itemid = 4744, position = Position(33641,32704, 12)}, + {itemid = 4744, position = Position(33639,32698, 12)}, + {itemid = 4744, position = Position(33642,32695, 12)}, + {itemid = 4744, position = Position(33646,32706, 12)}, + {itemid = 4744, position = Position(33644,32694, 12)}, + {itemid = 4743, position = Position(33641,32704, 12)}, + {itemid = 4743, position = Position(33638,32699, 12)}, + {itemid = 4743, position = Position(33645,32701, 12)}, + {itemid = 4743, position = Position(33634,32695, 12)}, + {itemid = 4743, position = Position(33636,32697, 12)}, + {itemid = 4743, position = Position(33637,32707, 12)}, + {itemid = 4743, position = Position(33635,32696, 12)}, + {itemid = 4743, position = Position(33640,32703, 12)}, + {itemid = 4743, position = Position(33648,32701, 12)}, + {itemid = 4742, position = Position(33647,32700, 12)}, + {itemid = 4742, position = Position(33642,32703, 12)}, + {itemid = 4742, position = Position(33634,32694, 12)}, + {itemid = 4742, position = Position(33638,32698, 12)}, + {itemid = 4742, position = Position(33637,32697, 12)}, + {itemid = 4742, position = Position(33637,32706, 12)}, + {itemid = 4742, position = Position(33634,32702, 12)}, + {itemid = 4742, position = Position(33635,32695, 12)}, + {itemid = 4742, position = Position(33636,32696, 12)}, + {itemid = 4741, position = Position(33646,32707, 12)}, + {itemid = 4741, position = Position(33644,32694, 12)}, + {itemid = 4741, position = Position(33645,32700, 12)}, + {itemid = 4741, position = Position(33647,32699, 12)}, + {itemid = 4741, position = Position(33648,32697, 12)}, + {itemid = 4741, position = Position(33643,32695, 12)}, + {itemid = 4741, position = Position(33648,32700, 12)}, + {itemid = 4741, position = Position(33637,32707, 12)}, + {itemid = 4741, position = Position(33641,32703, 12)}, + {itemid = 4741, position = Position(33648,32706, 12)}, + {itemid = 4741, position = Position(33648,32703, 12)}, + {itemid = 4740, position = Position(33648,32702, 12)}, + {itemid = 4740, position = Position(33636,32698, 12)}, + {itemid = 4740, position = Position(33637,32705, 12)}, + {itemid = 4740, position = Position(33637,32706, 12)}, + {itemid = 4739, position = Position(33648,32704, 12)}, + {itemid = 4739, position = Position(33642,32704, 12)}, + {itemid = 4739, position = Position(33646,32702, 12)}, + {itemid = 4739, position = Position(33648,32706, 12)}, + {itemid = 4739, position = Position(33647,32706, 12)}, + {itemid = 4739, position = Position(33637,32699, 12)}, + {itemid = 4739, position = Position(33648,32698, 12)}, + {itemid = 4739, position = Position(33643,32695, 12)}, + {itemid = 4739, position = Position(33640,32698, 12)}, + {itemid = 4738, position = Position(33641,32705, 12)}, + {itemid = 4738, position = Position(33638,32707, 12)}, + {itemid = 4738, position = Position(33639,32699, 12)}, + {itemid = 4738, position = Position(33642,32696, 12)}, + {itemid = 4738, position = Position(33634,32701, 12)}, + {itemid = 4737, position = Position(33646,32699, 12)}, + {itemid = 4737, position = Position(33636,32707, 12)}, + {itemid = 4737, position = Position(33645,32707, 12)}, + {itemid = 4737, position = Position(33647,32706, 12)}, + {itemid = 4737, position = Position(33639,32698, 12)}, + {itemid = 4737, position = Position(33639,32703, 12)}, + {itemid = 4737, position = Position(33640,32703, 12)}, + {itemid = 2698, position = Position(33644,32697, 12)}, + {itemid = 2698, position = Position(33647,32709, 12)}, + {itemid = 2698, position = Position(33645,32708, 12)}, + {itemid = 2698, position = Position(33644,32709, 12)}, + {itemid = 2698, position = Position(33646,32705, 12)}, + {itemid = 2697, position = Position(33642,32699, 12)}, + {itemid = 671, position = Position(33642,32703, 12)}, + {itemid = 671, position = Position(33642,32704, 12)}, + {itemid = 670, position = Position(33645,32703, 12)}, + {itemid = 670, position = Position(33644,32703, 12)}, + {itemid = 670, position = Position(33645,32695, 12)}, + {itemid = 670, position = Position(33645,32705, 12)}, + {itemid = 670, position = Position(33644,32708, 12)}, + {itemid = 670, position = Position(33636,32705, 12)}, + {itemid = 670, position = Position(33636,32701, 12)}, + {itemid = 670, position = Position(33644,32705, 12)}, + {itemid = 670, position = Position(33641,32699, 12)}, + {itemid = 670, position = Position(33636,32700, 12)}, + {itemid = 670, position = Position(33636,32704, 12)}, + {itemid = 670, position = Position(33636,32703, 12)}, + {itemid = 670, position = Position(33644,32706, 12)}, + {itemid = 670, position = Position(33644,32709, 12)}, + {itemid = 670, position = Position(33645,32698, 12)}, + {itemid = 670, position = Position(33646,32704, 12)}, + {itemid = 670, position = Position(33635,32708, 12)}, + {itemid = 670, position = Position(33647,32696, 12)}, + {itemid = 670, position = Position(33634,32707, 12)}, + {itemid = 670, position = Position(33647,32695, 12)}, + {itemid = 670, position = Position(33635,32700, 12)}, + {itemid = 670, position = Position(33635,32699, 12)}, + {itemid = 670, position = Position(33635,32701, 12)}, + {itemid = 670, position = Position(33647,32707, 12)}, + {itemid = 670, position = Position(33648,32694, 12)}, + {itemid = 670, position = Position(33648,32707, 12)}, + {itemid = 670, position = Position(33647,32709, 12)}, + {itemid = 670, position = Position(33634,32699, 12)}, + {itemid = 670, position = Position(33648,32695, 12)}, + {itemid = 670, position = Position(33645,32708, 12)}, + {itemid = 670, position = Position(33646,32708, 12)}, + {itemid = 670, position = Position(33646,32705, 12)}, + {itemid = 670, position = Position(33646,32695, 12)}, + {itemid = 670, position = Position(33635,32706, 12)}, + {itemid = 670, position = Position(33646,32694, 12)}, + {itemid = 670, position = Position(33645,32709, 12)}, + {itemid = 670, position = Position(33635,32704, 12)}, + {itemid = 670, position = Position(33646,32696, 12)}, + {itemid = 670, position = Position(33635,32705, 12)}, + {itemid = 670, position = Position(33644,32702, 12)}, + {itemid = 670, position = Position(33646,32697, 12)}, + {itemid = 670, position = Position(33646,32703, 12)}, + {itemid = 670, position = Position(33646,32698, 12)}, + {itemid = 670, position = Position(33641,32696, 12)}, + {itemid = 670, position = Position(33648,32709, 12)}, + {itemid = 670, position = Position(33639,32695, 12)}, + {itemid = 670, position = Position(33642,32707, 12)}, + {itemid = 670, position = Position(33642,32709, 12)}, + {itemid = 670, position = Position(33640,32697, 12)}, + {itemid = 670, position = Position(33640,32695, 12)}, + {itemid = 670, position = Position(33639,32709, 12)}, + {itemid = 670, position = Position(33640,32699, 12)}, + {itemid = 670, position = Position(33643,32698, 12)}, + {itemid = 670, position = Position(33643,32701, 12)}, + {itemid = 670, position = Position(33643,32696, 12)}, + {itemid = 670, position = Position(33643,32700, 12)}, + {itemid = 670, position = Position(33637,32709, 12)}, + {itemid = 670, position = Position(33640,32700, 12)}, + {itemid = 670, position = Position(33639,32706, 12)}, + {itemid = 670, position = Position(33638,32701, 12)}, + {itemid = 670, position = Position(33642,32700, 12)}, + {itemid = 670, position = Position(33639,32697, 12)}, + {itemid = 670, position = Position(33642,32698, 12)}, + {itemid = 670, position = Position(33642,32697, 12)}, + {itemid = 670, position = Position(33641,32708, 12)}, + {itemid = 670, position = Position(33639,32696, 12)}, + {itemid = 670, position = Position(33638,32709, 12)}, + {itemid = 670, position = Position(33639,32694, 12)}, + {itemid = 670, position = Position(33641,32709, 12)}, + {itemid = 670, position = Position(33642,32694, 12)}, + {itemid = 670, position = Position(33640,32701, 12)}, + {itemid = 670, position = Position(33638,32695, 12)}, + {itemid = 670, position = Position(33643,32705, 12)}, + {itemid = 670, position = Position(33644,32697, 12)}, + {itemid = 670, position = Position(33637,32694, 12)}, + {itemid = 670, position = Position(33643,32708, 12)}, + {itemid = 670, position = Position(33644,32699, 12)}, + {itemid = 670, position = Position(33641,32701, 12)}, + {itemid = 670, position = Position(33644,32696, 12)}, + {itemid = 670, position = Position(33640,32709, 12)}, + {itemid = 670, position = Position(33637,32700, 12)}, + {itemid = 670, position = Position(33643,32706, 12)}, + {itemid = 670, position = Position(33643,32707, 12)}, + {itemid = 670, position = Position(33640,32708, 12)}, + {itemid = 670, position = Position(33637,32701, 12)}, + {itemid = 670, position = Position(33640,32702, 12)}, + {itemid = 670, position = Position(33641,32694, 12)}, + {itemid = 670, position = Position(33641,32695, 12)}, + {itemid = 414, position = Position(33634,32702, 12)}, + {itemid = 414, position = Position(33648,32706, 12)}, + {itemid = 414, position = Position(33639,32699, 12)}, + {itemid = 414, position = Position(33647,32704, 12)}, + {itemid = 414, position = Position(33648,32700, 12)}, + {itemid = 414, position = Position(33647,32703, 12)}, + {itemid = 414, position = Position(33647,32701, 12)}, + {itemid = 414, position = Position(33635,32694, 12)}, + {itemid = 414, position = Position(33634,32703, 12)}, + {itemid = 414, position = Position(33642,32695, 12)}, + {itemid = 414, position = Position(33634,32704, 12)}, + {itemid = 414, position = Position(33647,32702, 12)}, + {itemid = 414, position = Position(33639,32700, 12)}, + {itemid = 414, position = Position(33634,32694, 12)}, + {itemid = 414, position = Position(33648,32705, 12)}, + {itemid = 414, position = Position(33634,32700, 12)}, + {itemid = 414, position = Position(33648,32698, 12)}, + {itemid = 414, position = Position(33647,32700, 12)}, + {itemid = 414, position = Position(33648,32699, 12)}, + {itemid = 414, position = Position(33648,32701, 12)}, + {itemid = 414, position = Position(33648,32702, 12)}, + {itemid = 414, position = Position(33647,32706, 12)}, + {itemid = 414, position = Position(33648,32703, 12)}, + {itemid = 414, position = Position(33648,32697, 12)}, + {itemid = 414, position = Position(33634,32701, 12)}, + {itemid = 414, position = Position(33634,32696, 12)}, + {itemid = 414, position = Position(33634,32695, 12)}, + {itemid = 414, position = Position(33648,32704, 12)}, + {itemid = 414, position = Position(33640,32698, 12)}, + {itemid = 414, position = Position(33648,32696, 12)}, + {itemid = 414, position = Position(33642,32696, 12)}, + {itemid = 414, position = Position(33636,32707, 12)}, + {itemid = 414, position = Position(33635,32695, 12)}, + {itemid = 414, position = Position(33645,32702, 12)}, + {itemid = 414, position = Position(33636,32697, 12)}, + {itemid = 414, position = Position(33645,32701, 12)}, + {itemid = 414, position = Position(33637,32705, 12)}, + {itemid = 414, position = Position(33637,32706, 12)}, + {itemid = 414, position = Position(33637,32707, 12)}, + {itemid = 414, position = Position(33636,32696, 12)}, + {itemid = 414, position = Position(33645,32707, 12)}, + {itemid = 414, position = Position(33636,32695, 12)}, + {itemid = 414, position = Position(33637,32708, 12)}, + {itemid = 414, position = Position(33645,32700, 12)}, + {itemid = 414, position = Position(33636,32698, 12)}, + {itemid = 414, position = Position(33644,32695, 12)}, + {itemid = 414, position = Position(33637,32696, 12)}, + {itemid = 414, position = Position(33644,32701, 12)}, + {itemid = 414, position = Position(33645,32699, 12)}, + {itemid = 414, position = Position(33644,32694, 12)}, + {itemid = 414, position = Position(33637,32698, 12)}, + {itemid = 414, position = Position(33637,32697, 12)}, + {itemid = 414, position = Position(33636,32699, 12)}, + {itemid = 414, position = Position(33637,32699, 12)}, + {itemid = 414, position = Position(33647,32699, 12)}, + {itemid = 414, position = Position(33643,32695, 12)}, + {itemid = 414, position = Position(33638,32697, 12)}, + {itemid = 414, position = Position(33644,32700, 12)}, + {itemid = 414, position = Position(33646,32707, 12)}, + {itemid = 414, position = Position(33635,32702, 12)}, + {itemid = 414, position = Position(33646,32706, 12)}, + {itemid = 414, position = Position(33639,32698, 12)}, + {itemid = 414, position = Position(33647,32697, 12)}, + {itemid = 414, position = Position(33635,32697, 12)}, + {itemid = 414, position = Position(33647,32698, 12)}, + {itemid = 414, position = Position(33635,32696, 12)}, + {itemid = 414, position = Position(33643,32694, 12)}, + {itemid = 414, position = Position(33635,32703, 12)}, + {itemid = 414, position = Position(33638,32707, 12)}, + {itemid = 414, position = Position(33646,32699, 12)}, + {itemid = 414, position = Position(33638,32699, 12)}, + {itemid = 414, position = Position(33638,32698, 12)}, + {itemid = 414, position = Position(33638,32708, 12)}, + {itemid = 414, position = Position(33646,32700, 12)}, + {itemid = 414, position = Position(33638,32700, 12)}, + {itemid = 414, position = Position(33646,32701, 12)}, + {itemid = 414, position = Position(33638,32706, 12)}, + {itemid = 414, position = Position(33646,32702, 12)}, + {itemid = 414, position = Position(33645,32694, 12)} +} + +local function transformArea() + for x = 33634, 33648 do + for y = 32694, 32709 do + local position = Position(x, y, 12) + local tile = Tile(position) + if not tile then + return + end + local ground = tile:getGround() + if not ground then + return + end + local grounds = ground:getId() + local items = tile:getItems() + for i = 1, #items do + local item = items[i] + if item then + item:remove() + end + end + ground:remove() + end + end + for i = 1, #ice do + local item = ice[i] + local ground = Tile(item.position):getGround() + local transformid = item.itemid + local tp = Game.createItem(item.itemid, 1, item.position) + end + return true +end + +local ferumbrasAscendantHabitatIce = Action() +function ferumbrasAscendantHabitatIce.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 10044 then + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Ice) >= 1 then + player:say('The lever are stucke, need some time to it can be moveable again.', TALKTYPE_MONSTER_SAY) + return true + end + Game.createMonster('lovely snake', Position(33642, 32702, 12), true, true) + addEvent(transformArea, 2 * 1000) + item:transform(10045) + local basin = Tile(Position(33631, 32703, 12)):getItemById(12070) + if basin then + basin:getPosition():sendMagicEffect(CONST_ME_ENERGYAREA) + basin:transform(24852) + end + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Ice, 1) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats, Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The room transforms into a completely different landscape.') + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats) >= 8 then + addEvent(functionRevert, 1 * 60 * 60 * 1000) + end + elseif item.itemid == 10045 then + item:transform(10044) + end + return true +end + +ferumbrasAscendantHabitatIce:aid(34310) +ferumbrasAscendantHabitatIce:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/habitat_lever.lua b/data/scripts/actions/quests/ferumbras_ascendant/habitat_lever.lua new file mode 100644 index 00000000000..6676eb420b1 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/habitat_lever.lua @@ -0,0 +1,17 @@ +local ferumbrasAscendantHabitatLever = Action() +function ferumbrasAscendantHabitatLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.FerumbrasAscension.HabitatsAccess) >= 1 then + return false + end + + if item.itemid == 10044 then + player:setStorageValue(Storage.FerumbrasAscension.HabitatsAccess, 1) + item:transform(10045) + elseif item.itemid == 10045 then + item:transform(10044) + end + return true +end + +ferumbrasAscendantHabitatLever:aid(34324) +ferumbrasAscendantHabitatLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/habitat_mushroom.lua b/data/scripts/actions/quests/ferumbras_ascendant/habitat_mushroom.lua new file mode 100644 index 00000000000..d581747ab66 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/habitat_mushroom.lua @@ -0,0 +1,421 @@ +local mushroom = { + {itemid = 11792, position = Position(33615,32678, 12)}, + {itemid = 11792, position = Position(33615,32686, 12)}, + {itemid = 11792, position = Position(33622,32688, 12)}, + {itemid = 11792, position = Position(33614,32677, 12)}, + {itemid = 11792, position = Position(33613,32676, 12)}, + {itemid = 11792, position = Position(33620,32680, 12)}, + {itemid = 11792, position = Position(33624,32689, 12)}, + {itemid = 11792, position = Position(33621,32683, 12)}, + {itemid = 11792, position = Position(33613,32681, 12)}, + {itemid = 11792, position = Position(33623,32676, 12)}, + {itemid = 11791, position = Position(33612,32686, 12)}, + {itemid = 11791, position = Position(33613,32691, 12)}, + {itemid = 11791, position = Position(33616,32678, 12)}, + {itemid = 11791, position = Position(33620,32684, 12)}, + {itemid = 11791, position = Position(33617,32685, 12)}, + {itemid = 11791, position = Position(33616,32686, 12)}, + {itemid = 11791, position = Position(33622,32682, 12)}, + {itemid = 11791, position = Position(33611,32681, 12)}, + {itemid = 11790, position = Position(33614,32690, 12)}, + {itemid = 11790, position = Position(33614,32684, 12)}, + {itemid = 11790, position = Position(33621,32679, 12)}, + {itemid = 11790, position = Position(33612,32679, 12)}, + {itemid = 11790, position = Position(33617,32677, 12)}, + {itemid = 11790, position = Position(33611,32682, 12)}, + {itemid = 11790, position = Position(33612,32683, 12)}, + {itemid = 11790, position = Position(33613,32688, 12)}, + {itemid = 11790, position = Position(33611,32687, 12)}, + {itemid = 11790, position = Position(33622,32681, 12)}, + {itemid = 11790, position = Position(33613,32680, 12)}, + {itemid = 11789, position = Position(33620,32679, 12)}, + {itemid = 11789, position = Position(33620,32687, 12)}, + {itemid = 11789, position = Position(33617,32684, 12)}, + {itemid = 11789, position = Position(33623,32686, 12)}, + {itemid = 11789, position = Position(33621,32686, 12)}, + {itemid = 11789, position = Position(33624,32691, 12)}, + {itemid = 11789, position = Position(33625,32682, 12)}, + {itemid = 11789, position = Position(33624,32685, 12)}, + {itemid = 11788, position = Position(33615,32677, 12)}, + {itemid = 11788, position = Position(33622,32687, 12)}, + {itemid = 11788, position = Position(33624,32688, 12)}, + {itemid = 11788, position = Position(33613,32680, 12)}, + {itemid = 11788, position = Position(33614,32676, 12)}, + {itemid = 11788, position = Position(33621,32680, 12)}, + {itemid = 11788, position = Position(33625,32689, 12)}, + {itemid = 11788, position = Position(33615,32685, 12)}, + {itemid = 11787, position = Position(33616,32685, 12)}, + {itemid = 11787, position = Position(33611,32680, 12)}, + {itemid = 11787, position = Position(33613,32690, 12)}, + {itemid = 11787, position = Position(33616,32677, 12)}, + {itemid = 11787, position = Position(33612,32685, 12)}, + {itemid = 11787, position = Position(33621,32682, 12)}, + {itemid = 11786, position = Position(33612,32680, 12)}, + {itemid = 11786, position = Position(33611,32683, 12)}, + {itemid = 11786, position = Position(33621,32682, 12)}, + {itemid = 11786, position = Position(33612,32684, 12)}, + {itemid = 11786, position = Position(33613,32690, 12)}, + {itemid = 11786, position = Position(33621,32687, 12)}, + {itemid = 11786, position = Position(33621,32681, 12)}, + {itemid = 11786, position = Position(33616,32677, 12)}, + {itemid = 11786, position = Position(33614,32685, 12)}, + {itemid = 11786, position = Position(33611,32688, 12)}, + {itemid = 11785, position = Position(33625,32685, 12)}, + {itemid = 11785, position = Position(33623,32687, 12)}, + {itemid = 11785, position = Position(33621,32687, 12)}, + {itemid = 11785, position = Position(33625,32691, 12)}, + {itemid = 11785, position = Position(33624,32686, 12)}, + {itemid = 11785, position = Position(33617,32685, 12)}, + {itemid = 11778, position = Position(33613,32689, 12)}, + {itemid = 11778, position = Position(33621,32683, 12)}, + {itemid = 11778, position = Position(33617,32684, 12)}, + {itemid = 11778, position = Position(33621,32680, 12)}, + {itemid = 11778, position = Position(33613,32681, 12)}, + {itemid = 11778, position = Position(33621,32686, 12)}, + {itemid = 11778, position = Position(33616,32676, 12)}, + {itemid = 11777, position = Position(33614,32690, 12)}, + {itemid = 11777, position = Position(33614,32685, 12)}, + {itemid = 11777, position = Position(33621,32687, 12)}, + {itemid = 11777, position = Position(33617,32677, 12)}, + {itemid = 11777, position = Position(33623,32688, 12)}, + {itemid = 11777, position = Position(33613,32685, 12)}, + {itemid = 11777, position = Position(33625,32676, 12)}, + {itemid = 11777, position = Position(33624,32691, 12)}, + {itemid = 11777, position = Position(33620,32687, 12)}, + {itemid = 11777, position = Position(33625,32691, 12)}, + {itemid = 11777, position = Position(33612,32680, 12)}, + {itemid = 11777, position = Position(33611,32686, 12)}, + {itemid = 11777, position = Position(33624,32676, 12)}, + {itemid = 11776, position = Position(33625,32683, 12)}, + {itemid = 11776, position = Position(33621,32681, 12)}, + {itemid = 11776, position = Position(33620,32684, 12)}, + {itemid = 11776, position = Position(33625,32690, 12)}, + {itemid = 11776, position = Position(33625,32684, 12)}, + {itemid = 11776, position = Position(33621,32682, 12)}, + {itemid = 11775, position = Position(33613,32684, 12)}, + {itemid = 11775, position = Position(33611,32679, 12)}, + {itemid = 11775, position = Position(33620,32684, 12)}, + {itemid = 11775, position = Position(33612,32688, 12)}, + {itemid = 11775, position = Position(33622,32687, 12)}, + {itemid = 11775, position = Position(33615,32685, 12)}, + {itemid = 11775, position = Position(33616,32685, 12)}, + {itemid = 11561, position = Position(33620,32688, 12)}, + {itemid = 11561, position = Position(33611,32676, 12)}, + {itemid = 11561, position = Position(33619,32690, 12)}, + {itemid = 11561, position = Position(33620,32685, 12)}, + {itemid = 11561, position = Position(33619,32679, 12)}, + {itemid = 11561, position = Position(33619,32678, 12)}, + {itemid = 11561, position = Position(33619,32680, 12)}, + {itemid = 11561, position = Position(33619,32682, 12)}, + {itemid = 11561, position = Position(33619,32681, 12)}, + {itemid = 11561, position = Position(33619,32683, 12)}, + {itemid = 11561, position = Position(33619,32677, 12)}, + {itemid = 11561, position = Position(33618,32691, 12)}, + {itemid = 11561, position = Position(33618,32687, 12)}, + {itemid = 11561, position = Position(33619,32676, 12)}, + {itemid = 11561, position = Position(33618,32688, 12)}, + {itemid = 11561, position = Position(33618,32690, 12)}, + {itemid = 11561, position = Position(33618,32689, 12)}, + {itemid = 11561, position = Position(33620,32686, 12)}, + {itemid = 11561, position = Position(33619,32684, 12)}, + {itemid = 11561, position = Position(33619,32686, 12)}, + {itemid = 11561, position = Position(33620,32678, 12)}, + {itemid = 11561, position = Position(33620,32677, 12)}, + {itemid = 11561, position = Position(33620,32681, 12)}, + {itemid = 11561, position = Position(33620,32683, 12)}, + {itemid = 11561, position = Position(33620,32682, 12)}, + {itemid = 11561, position = Position(33619,32685, 12)}, + {itemid = 11561, position = Position(33620,32676, 12)}, + {itemid = 11561, position = Position(33620,32689, 12)}, + {itemid = 11561, position = Position(33619,32687, 12)}, + {itemid = 11561, position = Position(33619,32691, 12)}, + {itemid = 11561, position = Position(33619,32688, 12)}, + {itemid = 11561, position = Position(33619,32689, 12)}, + {itemid = 11561, position = Position(33620,32690, 12)}, + {itemid = 11561, position = Position(33622,32680, 12)}, + {itemid = 11561, position = Position(33621,32676, 12)}, + {itemid = 11561, position = Position(33623,32691, 12)}, + {itemid = 11561, position = Position(33623,32690, 12)}, + {itemid = 11561, position = Position(33624,32677, 12)}, + {itemid = 11561, position = Position(33624,32678, 12)}, + {itemid = 11561, position = Position(33624,32679, 12)}, + {itemid = 11561, position = Position(33623,32689, 12)}, + {itemid = 11561, position = Position(33623,32684, 12)}, + {itemid = 11561, position = Position(33623,32685, 12)}, + {itemid = 11561, position = Position(33623,32682, 12)}, + {itemid = 11561, position = Position(33623,32683, 12)}, + {itemid = 11561, position = Position(33623,32681, 12)}, + {itemid = 11561, position = Position(33624,32680, 12)}, + {itemid = 11561, position = Position(33624,32682, 12)}, + {itemid = 11561, position = Position(33625,32679, 12)}, + {itemid = 11561, position = Position(33625,32680, 12)}, + {itemid = 11561, position = Position(33625,32681, 12)}, + {itemid = 11561, position = Position(33624,32681, 12)}, + {itemid = 11561, position = Position(33625,32678, 12)}, + {itemid = 11561, position = Position(33624,32690, 12)}, + {itemid = 11561, position = Position(33625,32677, 12)}, + {itemid = 11561, position = Position(33624,32683, 12)}, + {itemid = 11561, position = Position(33624,32684, 12)}, + {itemid = 11561, position = Position(33620,32691, 12)}, + {itemid = 11561, position = Position(33623,32680, 12)}, + {itemid = 11561, position = Position(33623,32678, 12)}, + {itemid = 11561, position = Position(33621,32690, 12)}, + {itemid = 11561, position = Position(33621,32689, 12)}, + {itemid = 11561, position = Position(33621,32691, 12)}, + {itemid = 11561, position = Position(33622,32676, 12)}, + {itemid = 11561, position = Position(33622,32677, 12)}, + {itemid = 11561, position = Position(33621,32688, 12)}, + {itemid = 11561, position = Position(33621,32684, 12)}, + {itemid = 11561, position = Position(33621,32685, 12)}, + {itemid = 11561, position = Position(33621,32677, 12)}, + {itemid = 11561, position = Position(33621,32678, 12)}, + {itemid = 11561, position = Position(33623,32679, 12)}, + {itemid = 11561, position = Position(33622,32678, 12)}, + {itemid = 11561, position = Position(33618,32686, 12)}, + {itemid = 11561, position = Position(33622,32690, 12)}, + {itemid = 11561, position = Position(33622,32691, 12)}, + {itemid = 11561, position = Position(33623,32677, 12)}, + {itemid = 11561, position = Position(33622,32679, 12)}, + {itemid = 11561, position = Position(33622,32689, 12)}, + {itemid = 11561, position = Position(33622,32685, 12)}, + {itemid = 11561, position = Position(33622,32686, 12)}, + {itemid = 11561, position = Position(33622,32683, 12)}, + {itemid = 11561, position = Position(33622,32684, 12)}, + {itemid = 11561, position = Position(33618,32685, 12)}, + {itemid = 11561, position = Position(33618,32682, 12)}, + {itemid = 11561, position = Position(33614,32687, 12)}, + {itemid = 11561, position = Position(33616,32683, 12)}, + {itemid = 11561, position = Position(33614,32680, 12)}, + {itemid = 11561, position = Position(33616,32684, 12)}, + {itemid = 11561, position = Position(33614,32681, 12)}, + {itemid = 11561, position = Position(33616,32681, 12)}, + {itemid = 11561, position = Position(33616,32682, 12)}, + {itemid = 11561, position = Position(33616,32680, 12)}, + {itemid = 11561, position = Position(33614,32679, 12)}, + {itemid = 11561, position = Position(33613,32687, 12)}, + {itemid = 11561, position = Position(33616,32689, 12)}, + {itemid = 11561, position = Position(33616,32690, 12)}, + {itemid = 11561, position = Position(33614,32678, 12)}, + {itemid = 11561, position = Position(33616,32688, 12)}, + {itemid = 11561, position = Position(33616,32687, 12)}, + {itemid = 11561, position = Position(33613,32686, 12)}, + {itemid = 11561, position = Position(33615,32683, 12)}, + {itemid = 11561, position = Position(33616,32679, 12)}, + {itemid = 11561, position = Position(33614,32683, 12)}, + {itemid = 11561, position = Position(33615,32679, 12)}, + {itemid = 11561, position = Position(33614,32691, 12)}, + {itemid = 11561, position = Position(33615,32687, 12)}, + {itemid = 11561, position = Position(33615,32680, 12)}, + {itemid = 11561, position = Position(33615,32681, 12)}, + {itemid = 11561, position = Position(33615,32684, 12)}, + {itemid = 11561, position = Position(33614,32682, 12)}, + {itemid = 11561, position = Position(33615,32688, 12)}, + {itemid = 11561, position = Position(33615,32689, 12)}, + {itemid = 11561, position = Position(33618,32684, 12)}, + {itemid = 11561, position = Position(33614,32686, 12)}, + {itemid = 11561, position = Position(33614,32689, 12)}, + {itemid = 11561, position = Position(33615,32691, 12)}, + {itemid = 11561, position = Position(33615,32690, 12)}, + {itemid = 11561, position = Position(33614,32688, 12)}, + {itemid = 11561, position = Position(33613,32683, 12)}, + {itemid = 11561, position = Position(33616,32691, 12)}, + {itemid = 11561, position = Position(33613,32682, 12)}, + {itemid = 11561, position = Position(33617,32689, 12)}, + {itemid = 11561, position = Position(33617,32690, 12)}, + {itemid = 11561, position = Position(33617,32691, 12)}, + {itemid = 11561, position = Position(33617,32688, 12)}, + {itemid = 11561, position = Position(33617,32676, 12)}, + {itemid = 11561, position = Position(33617,32687, 12)}, + {itemid = 11561, position = Position(33612,32676, 12)}, + {itemid = 11561, position = Position(33618,32676, 12)}, + {itemid = 11561, position = Position(33618,32678, 12)}, + {itemid = 11561, position = Position(33611,32677, 12)}, + {itemid = 11561, position = Position(33618,32683, 12)}, + {itemid = 11561, position = Position(33618,32677, 12)}, + {itemid = 11561, position = Position(33618,32681, 12)}, + {itemid = 11561, position = Position(33618,32679, 12)}, + {itemid = 11561, position = Position(33618,32680, 12)}, + {itemid = 11561, position = Position(33612,32677, 12)}, + {itemid = 11561, position = Position(33611,32678, 12)}, + {itemid = 11561, position = Position(33612,32678, 12)}, + {itemid = 11561, position = Position(33617,32679, 12)}, + {itemid = 11561, position = Position(33617,32686, 12)}, + {itemid = 11561, position = Position(33617,32680, 12)}, + {itemid = 11561, position = Position(33613,32678, 12)}, + {itemid = 11561, position = Position(33613,32679, 12)}, + {itemid = 11561, position = Position(33617,32678, 12)}, + {itemid = 11561, position = Position(33617,32681, 12)}, + {itemid = 11561, position = Position(33613,32677, 12)}, + {itemid = 11561, position = Position(33615,32682, 12)}, + {itemid = 11561, position = Position(33617,32682, 12)}, + {itemid = 11561, position = Position(33612,32682, 12)}, + {itemid = 11561, position = Position(33612,32681, 12)}, + {itemid = 11561, position = Position(33617,32683, 12)}, + {itemid = 11561, position = Position(33612,32687, 12)}, + {itemid = 4183, position = Position(33618,32684, 12)}, + {itemid = 4182, position = Position(33615,32684, 12)}, + {itemid = 4182, position = Position(33615,32681, 12)}, + {itemid = 4182, position = Position(33617,32683, 12)}, + {itemid = 4181, position = Position(33618,32687, 12)}, + {itemid = 4180, position = Position(33619,32687, 12)}, + {itemid = 4180, position = Position(33619,32689, 12)}, + {itemid = 4180, position = Position(33622,32684, 12)}, + {itemid = 4174, position = Position(33616,32683, 12)}, + {itemid = 4173, position = Position(33620,32683, 12)}, + {itemid = 4172, position = Position(33617,32680, 12)}, + {itemid = 4171, position = Position(33620,32686, 12)}, + {itemid = 4170, position = Position(33618,32682, 12)}, + {itemid = 4170, position = Position(33619,32685, 12)}, + {itemid = 4170, position = Position(33621,32685, 12)}, + {itemid = 4169, position = Position(33619,32686, 12)}, + {itemid = 4168, position = Position(33617,32687, 12)}, + {itemid = 414, position = Position(33621,32686, 12)}, + {itemid = 414, position = Position(33624,32687, 12)}, + {itemid = 414, position = Position(33624,32688, 12)}, + {itemid = 414, position = Position(33624,32689, 12)}, + {itemid = 414, position = Position(33624,32686, 12)}, + {itemid = 414, position = Position(33624,32685, 12)}, + {itemid = 414, position = Position(33611,32691, 12)}, + {itemid = 414, position = Position(33612,32684, 12)}, + {itemid = 414, position = Position(33612,32685, 12)}, + {itemid = 414, position = Position(33612,32686, 12)}, + {itemid = 414, position = Position(33612,32679, 12)}, + {itemid = 414, position = Position(33612,32683, 12)}, + {itemid = 414, position = Position(33617,32685, 12)}, + {itemid = 414, position = Position(33617,32684, 12)}, + {itemid = 414, position = Position(33612,32680, 12)}, + {itemid = 414, position = Position(33611,32690, 12)}, + {itemid = 414, position = Position(33611,32689, 12)}, + {itemid = 414, position = Position(33612,32688, 12)}, + {itemid = 414, position = Position(33625,32686, 12)}, + {itemid = 414, position = Position(33625,32685, 12)}, + {itemid = 414, position = Position(33611,32680, 12)}, + {itemid = 414, position = Position(33625,32684, 12)}, + {itemid = 414, position = Position(33625,32687, 12)}, + {itemid = 414, position = Position(33611,32679, 12)}, + {itemid = 414, position = Position(33625,32688, 12)}, + {itemid = 414, position = Position(33625,32690, 12)}, + {itemid = 414, position = Position(33625,32689, 12)}, + {itemid = 414, position = Position(33624,32691, 12)}, + {itemid = 414, position = Position(33611,32681, 12)}, + {itemid = 414, position = Position(33611,32682, 12)}, + {itemid = 414, position = Position(33611,32687, 12)}, + {itemid = 414, position = Position(33611,32688, 12)}, + {itemid = 414, position = Position(33625,32676, 12)}, + {itemid = 414, position = Position(33625,32683, 12)}, + {itemid = 414, position = Position(33611,32686, 12)}, + {itemid = 414, position = Position(33611,32684, 12)}, + {itemid = 414, position = Position(33611,32685, 12)}, + {itemid = 414, position = Position(33625,32682, 12)}, + {itemid = 414, position = Position(33611,32683, 12)}, + {itemid = 414, position = Position(33624,32676, 12)}, + {itemid = 414, position = Position(33612,32691, 12)}, + {itemid = 414, position = Position(33612,32690, 12)}, + {itemid = 414, position = Position(33622,32681, 12)}, + {itemid = 414, position = Position(33614,32685, 12)}, + {itemid = 414, position = Position(33621,32679, 12)}, + {itemid = 414, position = Position(33616,32676, 12)}, + {itemid = 414, position = Position(33614,32684, 12)}, + {itemid = 414, position = Position(33616,32677, 12)}, + {itemid = 414, position = Position(33622,32682, 12)}, + {itemid = 414, position = Position(33620,32687, 12)}, + {itemid = 414, position = Position(33616,32678, 12)}, + {itemid = 414, position = Position(33616,32685, 12)}, + {itemid = 414, position = Position(33621,32680, 12)}, + {itemid = 414, position = Position(33614,32690, 12)}, + {itemid = 414, position = Position(33621,32682, 12)}, + {itemid = 414, position = Position(33615,32685, 12)}, + {itemid = 414, position = Position(33621,32683, 12)}, + {itemid = 414, position = Position(33621,32681, 12)}, + {itemid = 414, position = Position(33621,32687, 12)}, + {itemid = 414, position = Position(33615,32677, 12)}, + {itemid = 414, position = Position(33615,32678, 12)}, + {itemid = 414, position = Position(33615,32686, 12)}, + {itemid = 414, position = Position(33615,32676, 12)}, + {itemid = 414, position = Position(33612,32689, 12)}, + {itemid = 414, position = Position(33616,32686, 12)}, + {itemid = 414, position = Position(33614,32677, 12)}, + {itemid = 414, position = Position(33620,32680, 12)}, + {itemid = 414, position = Position(33613,32680, 12)}, + {itemid = 414, position = Position(33613,32681, 12)}, + {itemid = 414, position = Position(33617,32677, 12)}, + {itemid = 414, position = Position(33623,32686, 12)}, + {itemid = 414, position = Position(33623,32687, 12)}, + {itemid = 414, position = Position(33620,32679, 12)}, + {itemid = 414, position = Position(33613,32676, 12)}, + {itemid = 414, position = Position(33623,32688, 12)}, + {itemid = 414, position = Position(33622,32687, 12)}, + {itemid = 414, position = Position(33613,32684, 12)}, + {itemid = 414, position = Position(33620,32684, 12)}, + {itemid = 414, position = Position(33613,32691, 12)}, + {itemid = 414, position = Position(33614,32676, 12)}, + {itemid = 414, position = Position(33622,32688, 12)}, + {itemid = 414, position = Position(33613,32685, 12)}, + {itemid = 414, position = Position(33613,32690, 12)}, + {itemid = 414, position = Position(33623,32676, 12)}, + {itemid = 414, position = Position(33613,32689, 12)}, + {itemid = 414, position = Position(33613,32688, 12)}, + {itemid = 414, position = Position(33625,32691, 12)} +} + +local function transformArea() + for x = 33611, 33625 do + for y = 32676, 32691 do + local position = Position(x, y, 12) + local tile = Tile(position) + if not tile then + return + end + local ground = tile:getGround() + if not ground then + return + end + local grounds = ground:getId() + local items = tile:getItems() + for i = 1, #items do + local item = items[i] + if item then + item:remove() + end + end + ground:remove() + end + end + for i = 1, #mushroom do + local item = mushroom[i] + local ground = Tile(item.position):getGround() + local transformid = item.itemid + local tp = Game.createItem(item.itemid, 1, item.position) + end + return true +end + +local ferumbrasAscendantHabitatMushroom = Action() +function ferumbrasAscendantHabitatMushroom.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 10044 then + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Mushroom) >= 1 then + player:say('The lever are stucke, need some time to it can be moveable again.', TALKTYPE_MONSTER_SAY) + return true + end + Game.createMonster('lovely scorpion', Position(33617, 32684, 12), true, true) + addEvent(transformArea, 2 * 1000) + item:transform(10045) + local basin = Tile(Position(33628, 32685, 12)):getItemById(12070) + if basin then + basin:getPosition():sendMagicEffect(CONST_ME_ENERGYAREA) + basin:transform(24852) + end + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Mushroom, 1) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats, Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The room transforms into a completely different landscape.') + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats) >= 8 then + addEvent(functionRevert, 1 * 60 * 60 * 1000) + end + elseif item.itemid == 10045 then + item:transform(10044) + end + return true +end + +ferumbrasAscendantHabitatMushroom:aid(34307) +ferumbrasAscendantHabitatMushroom:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/habitat_roshamuul.lua b/data/scripts/actions/quests/ferumbras_ascendant/habitat_roshamuul.lua new file mode 100644 index 00000000000..b5f4bca3469 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/habitat_roshamuul.lua @@ -0,0 +1,494 @@ +local roshamuul = { + {itemid = 22256, position = Position(33620,32672, 12)}, + {itemid = 22109, position = Position(33620,32666, 12)}, + {itemid = 22109, position = Position(33618,32671, 12)}, + {itemid = 22108, position = Position(33618,32668, 12)}, + {itemid = 22107, position = Position(33617,32670, 12)}, + {itemid = 22092, position = Position(33614,32670, 12)}, + {itemid = 22073, position = Position(33618,32663, 12)}, + {itemid = 22071, position = Position(33618,32666, 12)}, + {itemid = 22050, position = Position(33621,32670, 12)}, + {itemid = 22050, position = Position(33617,32664, 12)}, + {itemid = 22026, position = Position(33617,32669, 12)}, + {itemid = 22024, position = Position(33621,32668, 12)}, + {itemid = 22010, position = Position(33619,32668, 12)}, + {itemid = 22010, position = Position(33619,32665, 12)}, + {itemid = 21903, position = Position(33613,32671, 12)}, + {itemid = 21901, position = Position(33613,32669, 12)}, + {itemid = 21901, position = Position(33613,32667, 12)}, + {itemid = 21900, position = Position(33612,32669, 12)}, + {itemid = 21900, position = Position(33612,32670, 12)}, + {itemid = 21900, position = Position(33613,32668, 12)}, + {itemid = 21899, position = Position(33614,32669, 12)}, + {itemid = 21899, position = Position(33614,32670, 12)}, + {itemid = 21898, position = Position(33614,32671, 12)}, + {itemid = 21898, position = Position(33613,32670, 12)}, + {itemid = 21898, position = Position(33615,32665, 12)}, + {itemid = 21895, position = Position(33616,32670, 12)}, + {itemid = 21895, position = Position(33615,32664, 12)}, + {itemid = 21895, position = Position(33615,32670, 12)}, + {itemid = 21895, position = Position(33616,32671, 12)}, + {itemid = 21894, position = Position(33614,32665, 12)}, + {itemid = 21894, position = Position(33613,32666, 12)}, + {itemid = 21893, position = Position(33615,32671, 12)}, + {itemid = 21892, position = Position(33614,32672, 12)}, + {itemid = 21630, position = Position(33613,32670, 12)}, + {itemid = 21624, position = Position(33617,32659, 12)}, + {itemid = 21624, position = Position(33623,32666, 12)}, + {itemid = 21624, position = Position(33616,32658, 12)}, + {itemid = 21624, position = Position(33614,32672, 12)}, + {itemid = 21624, position = Position(33625,32669, 12)}, + {itemid = 21624, position = Position(33612,32670, 12)}, + {itemid = 21624, position = Position(33613,32671, 12)}, + {itemid = 21624, position = Position(33621,32662, 12)}, + {itemid = 21624, position = Position(33624,32668, 12)}, + {itemid = 21623, position = Position(33611,32671, 12)}, + {itemid = 21623, position = Position(33612,32665, 12)}, + {itemid = 21623, position = Position(33613,32662, 12)}, + {itemid = 21623, position = Position(33616,32671, 12)}, + {itemid = 21623, position = Position(33618,32659, 12)}, + {itemid = 21623, position = Position(33622,32661, 12)}, + {itemid = 21623, position = Position(33611,32667, 12)}, + {itemid = 21623, position = Position(33615,32661, 12)}, + {itemid = 21623, position = Position(33615,32665, 12)}, + {itemid = 21623, position = Position(33612,32663, 12)}, + {itemid = 21623, position = Position(33620,32658, 12)}, + {itemid = 21622, position = Position(33625,32670, 12)}, + {itemid = 21622, position = Position(33612,32669, 12)}, + {itemid = 21622, position = Position(33623,32664, 12)}, + {itemid = 21622, position = Position(33625,32667, 12)}, + {itemid = 21622, position = Position(33624,32671, 12)}, + {itemid = 21622, position = Position(33620,32661, 12)}, + {itemid = 21622, position = Position(33622,32665, 12)}, + {itemid = 21622, position = Position(33622,32673, 12)}, + {itemid = 21622, position = Position(33623,32672, 12)}, + {itemid = 21622, position = Position(33621,32660, 12)}, + {itemid = 21622, position = Position(33614,32665, 12)}, + {itemid = 21621, position = Position(33613,32659, 12)}, + {itemid = 21621, position = Position(33622,32659, 12)}, + {itemid = 21621, position = Position(33615,32660, 12)}, + {itemid = 21621, position = Position(33612,32664, 12)}, + {itemid = 21621, position = Position(33615,32664, 12)}, + {itemid = 21621, position = Position(33612,32658, 12)}, + {itemid = 21621, position = Position(33613,32666, 12)}, + {itemid = 21621, position = Position(33611,32668, 12)}, + {itemid = 21621, position = Position(33616,32670, 12)}, + {itemid = 21621, position = Position(33623,32660, 12)}, + {itemid = 21621, position = Position(33614,32669, 12)}, + {itemid = 21621, position = Position(33624,32662, 12)}, + {itemid = 21620, position = Position(33622,32660, 12)}, + {itemid = 21620, position = Position(33614,32670, 12)}, + {itemid = 21620, position = Position(33613,32669, 12)}, + {itemid = 21620, position = Position(33611,32658, 12)}, + {itemid = 21620, position = Position(33624,32663, 12)}, + {itemid = 21620, position = Position(33612,32659, 12)}, + {itemid = 21620, position = Position(33611,32664, 12)}, + {itemid = 21620, position = Position(33613,32660, 12)}, + {itemid = 21619, position = Position(33621,32661, 12)}, + {itemid = 21619, position = Position(33613,32669, 12)}, + {itemid = 21619, position = Position(33624,32664, 12)}, + {itemid = 21619, position = Position(33623,32665, 12)}, + {itemid = 21619, position = Position(33625,32671, 12)}, + {itemid = 21619, position = Position(33625,32668, 12)}, + {itemid = 21619, position = Position(33624,32672, 12)}, + {itemid = 21619, position = Position(33615,32665, 12)}, + {itemid = 21619, position = Position(33623,32673, 12)}, + {itemid = 21619, position = Position(33622,32660, 12)}, + {itemid = 21618, position = Position(33614,32671, 12)}, + {itemid = 21618, position = Position(33623,32665, 12)}, + {itemid = 21618, position = Position(33621,32661, 12)}, + {itemid = 21618, position = Position(33617,32658, 12)}, + {itemid = 21617, position = Position(33621,32661, 12)}, + {itemid = 21617, position = Position(33622,32660, 12)}, + {itemid = 21617, position = Position(33618,32658, 12)}, + {itemid = 21617, position = Position(33614,32671, 12)}, + {itemid = 21617, position = Position(33611,32663, 12)}, + {itemid = 21617, position = Position(33613,32661, 12)}, + {itemid = 21617, position = Position(33611,32665, 12)}, + {itemid = 21617, position = Position(33615,32671, 12)}, + {itemid = 21616, position = Position(33613,32668, 12)}, + {itemid = 21616, position = Position(33613,32667, 12)}, + {itemid = 21616, position = Position(33611,32670, 12)}, + {itemid = 21616, position = Position(33611,32666, 12)}, + {itemid = 21616, position = Position(33614,32672, 12)}, + {itemid = 21616, position = Position(33611,32669, 12)}, + {itemid = 21616, position = Position(33621,32662, 12)}, + {itemid = 21615, position = Position(33615,32664, 12)}, + {itemid = 21615, position = Position(33613,32668, 12)}, + {itemid = 21615, position = Position(33622,32659, 12)}, + {itemid = 21615, position = Position(33613,32666, 12)}, + {itemid = 21615, position = Position(33624,32662, 12)}, + {itemid = 21615, position = Position(33624,32663, 12)}, + {itemid = 21615, position = Position(33613,32667, 12)}, + {itemid = 21614, position = Position(33619,32658, 12)}, + {itemid = 21614, position = Position(33615,32671, 12)}, + {itemid = 21614, position = Position(33625,32666, 12)}, + {itemid = 21614, position = Position(33623,32660, 12)}, + {itemid = 21614, position = Position(33622,32665, 12)}, + {itemid = 21614, position = Position(33624,32666, 12)}, + {itemid = 21614, position = Position(33620,32661, 12)}, + {itemid = 21614, position = Position(33614,32661, 12)}, + {itemid = 21614, position = Position(33614,32665, 12)}, + {itemid = 21613, position = Position(33625,32663, 12)}, + {itemid = 21613, position = Position(33615,32670, 12)}, + {itemid = 21613, position = Position(33624,32668, 12)}, + {itemid = 21613, position = Position(33614,32660, 12)}, + {itemid = 21612, position = Position(33618,32666, 12)}, + {itemid = 21612, position = Position(33621,32663, 12)}, + {itemid = 21612, position = Position(33618,32660, 12)}, + {itemid = 21612, position = Position(33622,32671, 12)}, + {itemid = 21612, position = Position(33622,32670, 12)}, + {itemid = 21612, position = Position(33619,32660, 12)}, + {itemid = 21612, position = Position(33619,32661, 12)}, + {itemid = 21612, position = Position(33617,32665, 12)}, + {itemid = 21612, position = Position(33618,32668, 12)}, + {itemid = 21612, position = Position(33621,32673, 12)}, + {itemid = 21612, position = Position(33620,32665, 12)}, + {itemid = 21612, position = Position(33618,32661, 12)}, + {itemid = 21612, position = Position(33621,32659, 12)}, + {itemid = 21612, position = Position(33621,32664, 12)}, + {itemid = 21612, position = Position(33622,32663, 12)}, + {itemid = 21612, position = Position(33620,32663, 12)}, + {itemid = 21612, position = Position(33616,32660, 12)}, + {itemid = 21612, position = Position(33614,32667, 12)}, + {itemid = 21612, position = Position(33623,32663, 12)}, + {itemid = 21612, position = Position(33623,32667, 12)}, + {itemid = 21612, position = Position(33624,32661, 12)}, + {itemid = 21612, position = Position(33615,32663, 12)}, + {itemid = 21612, position = Position(33614,32664, 12)}, + {itemid = 21612, position = Position(33615,32673, 12)}, + {itemid = 21612, position = Position(33612,32673, 12)}, + {itemid = 21612, position = Position(33615,32658, 12)}, + {itemid = 21612, position = Position(33616,32662, 12)}, + {itemid = 21611, position = Position(33617,32660, 12)}, + {itemid = 21611, position = Position(33621,32668, 12)}, + {itemid = 21611, position = Position(33621,32670, 12)}, + {itemid = 21611, position = Position(33617,32663, 12)}, + {itemid = 21611, position = Position(33620,32673, 12)}, + {itemid = 21611, position = Position(33619,32662, 12)}, + {itemid = 21611, position = Position(33621,32665, 12)}, + {itemid = 21611, position = Position(33616,32669, 12)}, + {itemid = 21611, position = Position(33614,32663, 12)}, + {itemid = 21611, position = Position(33625,32659, 12)}, + {itemid = 21611, position = Position(33618,32663, 12)}, + {itemid = 21611, position = Position(33614,32659, 12)}, + {itemid = 21611, position = Position(33623,32669, 12)}, + {itemid = 21611, position = Position(33613,32673, 12)}, + {itemid = 21611, position = Position(33612,32667, 12)}, + {itemid = 21610, position = Position(33622,32666, 12)}, + {itemid = 21610, position = Position(33619,32665, 12)}, + {itemid = 21610, position = Position(33619,32663, 12)}, + {itemid = 21610, position = Position(33617,32667, 12)}, + {itemid = 21609, position = Position(33616,32664, 12)}, + {itemid = 21609, position = Position(33615,32672, 12)}, + {itemid = 21609, position = Position(33623,32659, 12)}, + {itemid = 21609, position = Position(33616,32661, 12)}, + {itemid = 21609, position = Position(33621,32667, 12)}, + {itemid = 21609, position = Position(33614,32662, 12)}, + {itemid = 21609, position = Position(33617,32673, 12)}, + {itemid = 21609, position = Position(33616,32663, 12)}, + {itemid = 21609, position = Position(33619,32659, 12)}, + {itemid = 21609, position = Position(33625,32658, 12)}, + {itemid = 21609, position = Position(33624,32667, 12)}, + {itemid = 21609, position = Position(33623,32670, 12)}, + {itemid = 21609, position = Position(33622,32664, 12)}, + {itemid = 21609, position = Position(33617,32666, 12)}, + {itemid = 21609, position = Position(33614,32666, 12)}, + {itemid = 21609, position = Position(33612,32672, 12)}, + {itemid = 21609, position = Position(33615,32668, 12)}, + {itemid = 21609, position = Position(33620,32659, 12)}, + {itemid = 21608, position = Position(33623,32661, 12)}, + {itemid = 21608, position = Position(33620,32666, 12)}, + {itemid = 21608, position = Position(33618,32673, 12)}, + {itemid = 21608, position = Position(33625,32661, 12)}, + {itemid = 21608, position = Position(33624,32670, 12)}, + {itemid = 21608, position = Position(33620,32667, 12)}, + {itemid = 21608, position = Position(33616,32665, 12)}, + {itemid = 21608, position = Position(33613,32665, 12)}, + {itemid = 21608, position = Position(33616,32672, 12)}, + {itemid = 21608, position = Position(33617,32671, 12)}, + {itemid = 21608, position = Position(33616,32659, 12)}, + {itemid = 21608, position = Position(33622,32672, 12)}, + {itemid = 21608, position = Position(33621,32666, 12)}, + {itemid = 21608, position = Position(33619,32673, 12)}, + {itemid = 21608, position = Position(33616,32673, 12)}, + {itemid = 21608, position = Position(33617,32664, 12)}, + {itemid = 21608, position = Position(33613,32664, 12)}, + {itemid = 21608, position = Position(33623,32668, 12)}, + {itemid = 21608, position = Position(33623,32658, 12)}, + {itemid = 21607, position = Position(33620,32660, 12)}, + {itemid = 21607, position = Position(33613,32672, 12)}, + {itemid = 21607, position = Position(33624,32659, 12)}, + {itemid = 21607, position = Position(33624,32669, 12)}, + {itemid = 21607, position = Position(33622,32658, 12)}, + {itemid = 21607, position = Position(33612,32671, 12)}, + {itemid = 21607, position = Position(33621,32658, 12)}, + {itemid = 21607, position = Position(33617,32672, 12)}, + {itemid = 21607, position = Position(33617,32662, 12)}, + {itemid = 21607, position = Position(33622,32668, 12)}, + {itemid = 21607, position = Position(33615,32666, 12)}, + {itemid = 21607, position = Position(33617,32661, 12)}, + {itemid = 21607, position = Position(33622,32667, 12)}, + {itemid = 21607, position = Position(33618,32665, 12)}, + {itemid = 21606, position = Position(33615,32667, 12)}, + {itemid = 21606, position = Position(33620,32662, 12)}, + {itemid = 21606, position = Position(33616,32668, 12)}, + {itemid = 21606, position = Position(33621,32671, 12)}, + {itemid = 21606, position = Position(33613,32658, 12)}, + {itemid = 21606, position = Position(33616,32667, 12)}, + {itemid = 21606, position = Position(33620,32664, 12)}, + {itemid = 21606, position = Position(33612,32666, 12)}, + {itemid = 21606, position = Position(33611,32672, 12)}, + {itemid = 21606, position = Position(33625,32662, 12)}, + {itemid = 21606, position = Position(33625,32660, 12)}, + {itemid = 21606, position = Position(33621,32672, 12)}, + {itemid = 21606, position = Position(33616,32666, 12)}, + {itemid = 21606, position = Position(33614,32668, 12)}, + {itemid = 21606, position = Position(33617,32669, 12)}, + {itemid = 21606, position = Position(33618,32672, 12)}, + {itemid = 21606, position = Position(33622,32662, 12)}, + {itemid = 21606, position = Position(33623,32671, 12)}, + {itemid = 21606, position = Position(33622,32669, 12)}, + {itemid = 21605, position = Position(33612,32668, 12)}, + {itemid = 21605, position = Position(33624,32658, 12)}, + {itemid = 21605, position = Position(33615,32662, 12)}, + {itemid = 21605, position = Position(33618,32662, 12)}, + {itemid = 21605, position = Position(33614,32658, 12)}, + {itemid = 21605, position = Position(33614,32673, 12)}, + {itemid = 21605, position = Position(33623,32662, 12)}, + {itemid = 21605, position = Position(33617,32668, 12)}, + {itemid = 21605, position = Position(33618,32664, 12)}, + {itemid = 21605, position = Position(33611,32673, 12)}, + {itemid = 21605, position = Position(33615,32659, 12)}, + {itemid = 21605, position = Position(33615,32669, 12)}, + {itemid = 21605, position = Position(33624,32660, 12)}, + {itemid = 21605, position = Position(33613,32663, 12)}, + {itemid = 21605, position = Position(33619,32664, 12)}, + {itemid = 17684, position = Position(33617,32672, 12)}, + {itemid = 17684, position = Position(33616,32671, 12)}, + {itemid = 17684, position = Position(33617,32665, 12)}, + {itemid = 17684, position = Position(33616,32664, 12)}, + {itemid = 17684, position = Position(33617,32668, 12)}, + {itemid = 17683, position = Position(33620,32664, 12)}, + {itemid = 17683, position = Position(33623,32669, 12)}, + {itemid = 17683, position = Position(33622,32670, 12)}, + {itemid = 17683, position = Position(33618,32665, 12)}, + {itemid = 17682, position = Position(33619,32662, 12)}, + {itemid = 17682, position = Position(33621,32667, 12)}, + {itemid = 17682, position = Position(33623,32667, 12)}, + {itemid = 17682, position = Position(33619,32664, 12)}, + {itemid = 17682, position = Position(33620,32665, 12)}, + {itemid = 17682, position = Position(33620,32663, 12)}, + {itemid = 17681, position = Position(33622,32667, 12)}, + {itemid = 17681, position = Position(33617,32668, 12)}, + {itemid = 17681, position = Position(33617,32666, 12)}, + {itemid = 17681, position = Position(33618,32662, 12)}, + {itemid = 17681, position = Position(33616,32669, 12)}, + {itemid = 17681, position = Position(33618,32664, 12)}, + {itemid = 17680, position = Position(33617,32664, 12)}, + {itemid = 17680, position = Position(33620,32673, 12)}, + {itemid = 17680, position = Position(33617,32671, 12)}, + {itemid = 17680, position = Position(33618,32672, 12)}, + {itemid = 17679, position = Position(33621,32670, 12)}, + {itemid = 17679, position = Position(33622,32669, 12)}, + {itemid = 17679, position = Position(33618,32664, 12)}, + {itemid = 17679, position = Position(33619,32673, 12)}, + {itemid = 17678, position = Position(33619,32665, 12)}, + {itemid = 17678, position = Position(33621,32668, 12)}, + {itemid = 17678, position = Position(33620,32667, 12)}, + {itemid = 17678, position = Position(33621,32673, 12)}, + {itemid = 17678, position = Position(33619,32663, 12)}, + {itemid = 17677, position = Position(33618,32668, 12)}, + {itemid = 17677, position = Position(33618,32673, 12)}, + {itemid = 17677, position = Position(33618,32666, 12)}, + {itemid = 17677, position = Position(33618,32663, 12)}, + {itemid = 17677, position = Position(33617,32669, 12)}, + {itemid = 17677, position = Position(33622,32668, 12)}, + {itemid = 17676, position = Position(33620,32666, 12)}, + {itemid = 17676, position = Position(33621,32672, 12)}, + {itemid = 17676, position = Position(33623,32668, 12)}, + {itemid = 17676, position = Position(33621,32671, 12)}, + {itemid = 17676, position = Position(33618,32664, 12)}, + {itemid = 17675, position = Position(33617,32667, 12)}, + {itemid = 17675, position = Position(33616,32670, 12)}, + {itemid = 17675, position = Position(33618,32665, 12)}, + {itemid = 17674, position = Position(33619,32664, 12)}, + {itemid = 17674, position = Position(33618,32668, 12)}, + {itemid = 17673, position = Position(33617,32663, 12)}, + {itemid = 17672, position = Position(33619,32668, 12)}, + {itemid = 17672, position = Position(33619,32671, 12)}, + {itemid = 17672, position = Position(33621,32669, 12)}, + {itemid = 17672, position = Position(33617,32670, 12)}, + {itemid = 17672, position = Position(33619,32669, 12)}, + {itemid = 17671, position = Position(33620,32670, 12)}, + {itemid = 17671, position = Position(33618,32671, 12)}, + {itemid = 17670, position = Position(33619,32672, 12)}, + {itemid = 17669, position = Position(33619,32666, 12)}, + {itemid = 17669, position = Position(33620,32668, 12)}, + {itemid = 17669, position = Position(33619,32667, 12)}, + {itemid = 17668, position = Position(33619,32670, 12)}, + {itemid = 17668, position = Position(33620,32669, 12)}, + {itemid = 17668, position = Position(33618,32670, 12)}, + {itemid = 17667, position = Position(33618,32669, 12)}, + {itemid = 17666, position = Position(33620,32671, 12)}, + {itemid = 17665, position = Position(33618,32667, 12)}, + {itemid = 17665, position = Position(33620,32672, 12)}, + {itemid = 10738, position = Position(33614,32665, 12)}, + {itemid = 10738, position = Position(33615,32664, 12)}, + {itemid = 10738, position = Position(33615,32670, 12)}, + {itemid = 10738, position = Position(33616,32671, 12)}, + {itemid = 10738, position = Position(33613,32669, 12)}, + {itemid = 10738, position = Position(33612,32671, 12)}, + {itemid = 3623, position = Position(33621,32666, 12)}, + {itemid = 3623, position = Position(33615,32659, 12)}, + {itemid = 3623, position = Position(33615,32665, 12)}, + {itemid = 3622, position = Position(33613,32665, 12)}, + {itemid = 3622, position = Position(33615,32667, 12)}, + {itemid = 3622, position = Position(33622,32662, 12)}, + {itemid = 3621, position = Position(33617,32660, 12)}, + {itemid = 3621, position = Position(33623,32670, 12)}, + {itemid = 3621, position = Position(33620,32670, 12)}, + {itemid = 3621, position = Position(33624,32659, 12)}, + {itemid = 3614, position = Position(33620,32664, 12)}, + {itemid = 3613, position = Position(33619,32660, 12)}, + {itemid = 3613, position = Position(33617,32672, 12)}, + {itemid = 3613, position = Position(33616,32662, 12)}, + {itemid = 3612, position = Position(33619,32661, 12)}, + {itemid = 3612, position = Position(33613,32666, 12)}, + {itemid = 3612, position = Position(33615,32666, 12)}, + {itemid = 3610, position = Position(33617,32667, 12)}, + {itemid = 414, position = Position(33624,32671, 12)}, + {itemid = 414, position = Position(33612,32660, 12)}, + {itemid = 414, position = Position(33611,32670, 12)}, + {itemid = 414, position = Position(33624,32666, 12)}, + {itemid = 414, position = Position(33624,32672, 12)}, + {itemid = 414, position = Position(33611,32660, 12)}, + {itemid = 414, position = Position(33611,32671, 12)}, + {itemid = 414, position = Position(33612,32662, 12)}, + {itemid = 414, position = Position(33612,32659, 12)}, + {itemid = 414, position = Position(33624,32668, 12)}, + {itemid = 414, position = Position(33612,32661, 12)}, + {itemid = 414, position = Position(33612,32658, 12)}, + {itemid = 414, position = Position(33625,32668, 12)}, + {itemid = 414, position = Position(33611,32661, 12)}, + {itemid = 414, position = Position(33611,32662, 12)}, + {itemid = 414, position = Position(33625,32671, 12)}, + {itemid = 414, position = Position(33611,32669, 12)}, + {itemid = 414, position = Position(33625,32663, 12)}, + {itemid = 414, position = Position(33611,32664, 12)}, + {itemid = 414, position = Position(33611,32665, 12)}, + {itemid = 414, position = Position(33611,32658, 12)}, + {itemid = 414, position = Position(33625,32670, 12)}, + {itemid = 414, position = Position(33625,32664, 12)}, + {itemid = 414, position = Position(33611,32659, 12)}, + {itemid = 414, position = Position(33624,32673, 12)}, + {itemid = 414, position = Position(33611,32663, 12)}, + {itemid = 414, position = Position(33612,32663, 12)}, + {itemid = 414, position = Position(33625,32666, 12)}, + {itemid = 414, position = Position(33625,32665, 12)}, + {itemid = 414, position = Position(33611,32666, 12)}, + {itemid = 414, position = Position(33611,32668, 12)}, + {itemid = 414, position = Position(33625,32669, 12)}, + {itemid = 414, position = Position(33611,32667, 12)}, + {itemid = 414, position = Position(33625,32667, 12)}, + {itemid = 414, position = Position(33624,32665, 12)}, + {itemid = 414, position = Position(33623,32664, 12)}, + {itemid = 414, position = Position(33612,32664, 12)}, + {itemid = 414, position = Position(33625,32672, 12)}, + {itemid = 414, position = Position(33622,32665, 12)}, + {itemid = 414, position = Position(33622,32661, 12)}, + {itemid = 414, position = Position(33618,32659, 12)}, + {itemid = 414, position = Position(33622,32673, 12)}, + {itemid = 414, position = Position(33618,32658, 12)}, + {itemid = 414, position = Position(33617,32659, 12)}, + {itemid = 414, position = Position(33617,32658, 12)}, + {itemid = 414, position = Position(33622,32660, 12)}, + {itemid = 414, position = Position(33622,32659, 12)}, + {itemid = 414, position = Position(33621,32661, 12)}, + {itemid = 414, position = Position(33621,32660, 12)}, + {itemid = 414, position = Position(33619,32658, 12)}, + {itemid = 414, position = Position(33621,32662, 12)}, + {itemid = 414, position = Position(33620,32658, 12)}, + {itemid = 414, position = Position(33620,32661, 12)}, + {itemid = 414, position = Position(33624,32664, 12)}, + {itemid = 414, position = Position(33623,32660, 12)}, + {itemid = 414, position = Position(33623,32665, 12)}, + {itemid = 414, position = Position(33613,32659, 12)}, + {itemid = 414, position = Position(33613,32660, 12)}, + {itemid = 414, position = Position(33613,32661, 12)}, + {itemid = 414, position = Position(33624,32662, 12)}, + {itemid = 414, position = Position(33624,32663, 12)}, + {itemid = 414, position = Position(33612,32665, 12)}, + {itemid = 414, position = Position(33616,32658, 12)}, + {itemid = 414, position = Position(33613,32662, 12)}, + {itemid = 414, position = Position(33623,32672, 12)}, + {itemid = 414, position = Position(33615,32661, 12)}, + {itemid = 414, position = Position(33623,32666, 12)}, + {itemid = 414, position = Position(33623,32673, 12)}, + {itemid = 414, position = Position(33615,32660, 12)}, + {itemid = 414, position = Position(33614,32660, 12)}, + {itemid = 414, position = Position(33614,32661, 12)}, + {itemid = 414, position = Position(33625,32673, 12)} +} + +local function transformArea() + for x = 33611, 33625 do + for y = 32658, 32673 do + local position = Position(x, y, 12) + local tile = Tile(position) + if not tile then + return + end + local ground = tile:getGround() + if not ground then + return + end + local grounds = ground:getId() + local items = tile:getItems() + for i = 1, #items do + local item = items[i] + if item then + item:remove() + end + end + ground:remove() + end + end + for i = 1, #roshamuul do + local item = roshamuul[i] + local ground = Tile(item.position):getGround() + local transformid = item.itemid + local tp = Game.createItem(item.itemid, 1, item.position) + end + return true +end + +local ferumbrasAscendantHabitatRoshamuul = Action() +function ferumbrasAscendantHabitatRoshamuul.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 10044 then + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Roshamuul) >= 1 then + player:say('The lever are stucke, need some time to it can be moveable again.', TALKTYPE_MONSTER_SAY) + return true + end + Game.createMonster('lovely deer', Position(33619, 32666, 12), true, true) + addEvent(transformArea, 2 * 1000) + item:transform(10045) + local basin = Tile(Position(33628, 32667, 12)):getItemById(12070) + if basin then + basin:getPosition():sendMagicEffect(CONST_ME_ENERGYAREA) + basin:transform(24852) + end + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Roshamuul, 1) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats, Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The room transforms into a completely different landscape.') + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats) >= 8 then + addEvent(functionRevert, 1 * 60 * 60 * 1000) + end + elseif item.itemid == 10045 then + item:transform(10044) + end + return true +end + +ferumbrasAscendantHabitatRoshamuul:aid(34305) +ferumbrasAscendantHabitatRoshamuul:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/habitat_venom.lua b/data/scripts/actions/quests/ferumbras_ascendant/habitat_venom.lua new file mode 100644 index 00000000000..bf6eff7717e --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/habitat_venom.lua @@ -0,0 +1,476 @@ +local venom = { + {itemid = 3299, position = Position(33611,32694, 12)}, + {itemid = 414, position = Position(33611,32694, 12)}, + {itemid = 3307, position = Position(33611,32695, 12)}, + {itemid = 414, position = Position(33611,32695, 12)}, + {itemid = 3263, position = Position(33611,32696, 12)}, + {itemid = 3263, position = Position(33611,32697, 12)}, + {itemid = 3263, position = Position(33611,32698, 12)}, + {itemid = 3263, position = Position(33611,32699, 12)}, + {itemid = 3305, position = Position(33611,32700, 12)}, + {itemid = 414, position = Position(33611,32700, 12)}, + {itemid = 6219, position = Position(33611,32701, 12)}, + {itemid = 414, position = Position(33611,32701, 12)}, + {itemid = 414, position = Position(33611,32702, 12)}, + {itemid = 414, position = Position(33611,32703, 12)}, + {itemid = 6217, position = Position(33611,32704, 12)}, + {itemid = 6219, position = Position(33611,32704, 12)}, + {itemid = 3298, position = Position(33611,32704, 12)}, + {itemid = 414, position = Position(33611,32704, 12)}, + {itemid = 3300, position = Position(33611,32705, 12)}, + {itemid = 414, position = Position(33611,32705, 12)}, + {itemid = 414, position = Position(33611,32706, 12)}, + {itemid = 3298, position = Position(33611,32707, 12)}, + {itemid = 414, position = Position(33611,32707, 12)}, + {itemid = 3306, position = Position(33611,32708, 12)}, + {itemid = 414, position = Position(33611,32708, 12)}, + {itemid = 3263, position = Position(33611,32709, 12)}, + {itemid = 6217, position = Position(33612,32694, 12)}, + {itemid = 414, position = Position(33612,32694, 12)}, + {itemid = 3299, position = Position(33612,32695, 12)}, + {itemid = 414, position = Position(33612,32695, 12)}, + {itemid = 3307, position = Position(33612,32696, 12)}, + {itemid = 414, position = Position(33612,32696, 12)}, + {itemid = 3263, position = Position(33612,32697, 12)}, + {itemid = 3263, position = Position(33612,32698, 12)}, + {itemid = 3263, position = Position(33612,32699, 12)}, + {itemid = 3308, position = Position(33612,32700, 12)}, + {itemid = 414, position = Position(33612,32700, 12)}, + {itemid = 6217, position = Position(33612,32701, 12)}, + {itemid = 3300, position = Position(33612,32701, 12)}, + {itemid = 414, position = Position(33612,32701, 12)}, + {itemid = 6217, position = Position(33612,32702, 12)}, + {itemid = 414, position = Position(33612,32702, 12)}, + {itemid = 3298, position = Position(33612,32703, 12)}, + {itemid = 414, position = Position(33612,32703, 12)}, + {itemid = 3306, position = Position(33612,32704, 12)}, + {itemid = 414, position = Position(33612,32704, 12)}, + {itemid = 3308, position = Position(33612,32705, 12)}, + {itemid = 414, position = Position(33612,32705, 12)}, + {itemid = 6217, position = Position(33612,32706, 12)}, + {itemid = 3300, position = Position(33612,32706, 12)}, + {itemid = 414, position = Position(33612,32706, 12)}, + {itemid = 6219, position = Position(33612,32707, 12)}, + {itemid = 3304, position = Position(33612,32707, 12)}, + {itemid = 414, position = Position(33612,32707, 12)}, + {itemid = 3263, position = Position(33612,32708, 12)}, + {itemid = 3263, position = Position(33612,32709, 12)}, + {itemid = 6217, position = Position(33613,32694, 12)}, + {itemid = 3302, position = Position(33613,32694, 12)}, + {itemid = 414, position = Position(33613,32694, 12)}, + {itemid = 3300, position = Position(33613,32695, 12)}, + {itemid = 414, position = Position(33613,32695, 12)}, + {itemid = 6217, position = Position(33613,32696, 12)}, + {itemid = 3299, position = Position(33613,32696, 12)}, + {itemid = 414, position = Position(33613,32696, 12)}, + {itemid = 3307, position = Position(33613,32697, 12)}, + {itemid = 414, position = Position(33613,32697, 12)}, + {itemid = 3263, position = Position(33613,32698, 12)}, + {itemid = 3263, position = Position(33613,32699, 12)}, + {itemid = 3263, position = Position(33613,32700, 12)}, + {itemid = 3308, position = Position(33613,32701, 12)}, + {itemid = 414, position = Position(33613,32701, 12)}, + {itemid = 6217, position = Position(33613,32702, 12)}, + {itemid = 3298, position = Position(33613,32702, 12)}, + {itemid = 3300, position = Position(33613,32702, 12)}, + {itemid = 414, position = Position(33613,32702, 12)}, + {itemid = 3306, position = Position(33613,32703, 12)}, + {itemid = 414, position = Position(33613,32703, 12)}, + {itemid = 3263, position = Position(33613,32704, 12)}, + {itemid = 3263, position = Position(33613,32705, 12)}, + {itemid = 3305, position = Position(33613,32706, 12)}, + {itemid = 3298, position = Position(33613,32706, 12)}, + {itemid = 414, position = Position(33613,32706, 12)}, + {itemid = 3306, position = Position(33613,32707, 12)}, + {itemid = 414, position = Position(33613,32707, 12)}, + {itemid = 3263, position = Position(33613,32708, 12)}, + {itemid = 3263, position = Position(33613,32709, 12)}, + {itemid = 3263, position = Position(33614,32694, 12)}, + {itemid = 414, position = Position(33614,32695, 12)}, + {itemid = 3300, position = Position(33614,32696, 12)}, + {itemid = 3298, position = Position(33614,32696, 12)}, + {itemid = 414, position = Position(33614,32696, 12)}, + {itemid = 3306, position = Position(33614,32697, 12)}, + {itemid = 414, position = Position(33614,32697, 12)}, + {itemid = 3263, position = Position(33614,32698, 12)}, + {itemid = 3263, position = Position(33614,32699, 12)}, + {itemid = 3263, position = Position(33614,32700, 12)}, + {itemid = 3263, position = Position(33614,32701, 12)}, + {itemid = 3304, position = Position(33614,32702, 12)}, + {itemid = 3302, position = Position(33614,32702, 12)}, + {itemid = 3305, position = Position(33614,32702, 12)}, + {itemid = 414, position = Position(33614,32702, 12)}, + {itemid = 3263, position = Position(33614,32703, 12)}, + {itemid = 3263, position = Position(33614,32704, 12)}, + {itemid = 3263, position = Position(33614,32705, 12)}, + {itemid = 3304, position = Position(33614,32706, 12)}, + {itemid = 3302, position = Position(33614,32706, 12)}, + {itemid = 3305, position = Position(33614,32706, 12)}, + {itemid = 414, position = Position(33614,32706, 12)}, + {itemid = 3263, position = Position(33614,32707, 12)}, + {itemid = 3263, position = Position(33614,32708, 12)}, + {itemid = 3263, position = Position(33614,32709, 12)}, + {itemid = 3263, position = Position(33615,32694, 12)}, + {itemid = 4134, position = Position(33615,32695, 12)}, + {itemid = 3263, position = Position(33615,32695, 12)}, + {itemid = 3305, position = Position(33615,32696, 12)}, + {itemid = 3299, position = Position(33615,32696, 12)}, + {itemid = 414, position = Position(33615,32696, 12)}, + {itemid = 6217, position = Position(33615,32697, 12)}, + {itemid = 3303, position = Position(33615,32697, 12)}, + {itemid = 414, position = Position(33615,32697, 12)}, + {itemid = 3307, position = Position(33615,32698, 12)}, + {itemid = 414, position = Position(33615,32698, 12)}, + {itemid = 3263, position = Position(33615,32699, 12)}, + {itemid = 3263, position = Position(33615,32700, 12)}, + {itemid = 3263, position = Position(33615,32701, 12)}, + {itemid = 10738, position = Position(33615,32702, 12)}, + {itemid = 3305, position = Position(33615,32702, 12)}, + {itemid = 3299, position = Position(33615,32702, 12)}, + {itemid = 8328, position = Position(33615,32702, 12)}, + {itemid = 3303, position = Position(33615,32703, 12)}, + {itemid = 8348, position = Position(33615,32703, 12)}, + {itemid = 10740, position = Position(33615,32704, 12)}, + {itemid = 3307, position = Position(33615,32704, 12)}, + {itemid = 8332, position = Position(33615,32704, 12)}, + {itemid = 3263, position = Position(33615,32705, 12)}, + {itemid = 3263, position = Position(33615,32706, 12)}, + {itemid = 3263, position = Position(33615,32707, 12)}, + {itemid = 3263, position = Position(33615,32708, 12)}, + {itemid = 3263, position = Position(33615,32709, 12)}, + {itemid = 3263, position = Position(33616,32694, 12)}, + {itemid = 3263, position = Position(33616,32695, 12)}, + {itemid = 3308, position = Position(33616,32696, 12)}, + {itemid = 414, position = Position(33616,32696, 12)}, + {itemid = 3300, position = Position(33616,32697, 12)}, + {itemid = 414, position = Position(33616,32697, 12)}, + {itemid = 6219, position = Position(33616,32698, 12)}, + {itemid = 3304, position = Position(33616,32698, 12)}, + {itemid = 414, position = Position(33616,32698, 12)}, + {itemid = 3263, position = Position(33616,32699, 12)}, + {itemid = 3263, position = Position(33616,32700, 12)}, + {itemid = 6217, position = Position(33616,32701, 12)}, + {itemid = 10738, position = Position(33616,32701, 12)}, + {itemid = 3309, position = Position(33616,32701, 12)}, + {itemid = 8329, position = Position(33616,32701, 12)}, + {itemid = 3301, position = Position(33616,32702, 12)}, + {itemid = 8348, position = Position(33616,32702, 12)}, + {itemid = 10739, position = Position(33616,32703, 12)}, + {itemid = 8333, position = Position(33616,32703, 12)}, + {itemid = 10738, position = Position(33616,32704, 12)}, + {itemid = 3299, position = Position(33616,32704, 12)}, + {itemid = 8333, position = Position(33616,32704, 12)}, + {itemid = 3307, position = Position(33616,32705, 12)}, + {itemid = 8329, position = Position(33616,32705, 12)}, + {itemid = 10740, position = Position(33616,32706, 12)}, + {itemid = 3263, position = Position(33616,32706, 12)}, + {itemid = 3263, position = Position(33616,32707, 12)}, + {itemid = 3263, position = Position(33616,32708, 12)}, + {itemid = 3309, position = Position(33616,32709, 12)}, + {itemid = 414, position = Position(33616,32709, 12)}, + {itemid = 3263, position = Position(33617,32694, 12)}, + {itemid = 3263, position = Position(33617,32695, 12)}, + {itemid = 3263, position = Position(33617,32696, 12)}, + {itemid = 3308, position = Position(33617,32697, 12)}, + {itemid = 414, position = Position(33617,32697, 12)}, + {itemid = 3300, position = Position(33617,32698, 12)}, + {itemid = 3299, position = Position(33617,32698, 12)}, + {itemid = 3298, position = Position(33617,32698, 12)}, + {itemid = 414, position = Position(33617,32698, 12)}, + {itemid = 3302, position = Position(33617,32699, 12)}, + {itemid = 3304, position = Position(33617,32699, 12)}, + {itemid = 3303, position = Position(33617,32699, 12)}, + {itemid = 414, position = Position(33617,32699, 12)}, + {itemid = 3263, position = Position(33617,32700, 12)}, + {itemid = 10739, position = Position(33617,32701, 12)}, + {itemid = 3308, position = Position(33617,32701, 12)}, + {itemid = 8334, position = Position(33617,32701, 12)}, + {itemid = 10738, position = Position(33617,32702, 12)}, + {itemid = 10739, position = Position(33617,32702, 12)}, + {itemid = 3300, position = Position(33617,32702, 12)}, + {itemid = 8348, position = Position(33617,32702, 12)}, + {itemid = 8330, position = Position(33617,32703, 12)}, + {itemid = 10739, position = Position(33617,32704, 12)}, + {itemid = 8326, position = Position(33617,32704, 12)}, + {itemid = 10740, position = Position(33617,32705, 12)}, + {itemid = 3299, position = Position(33617,32705, 12)}, + {itemid = 3298, position = Position(33617,32705, 12)}, + {itemid = 8328, position = Position(33617,32705, 12)}, + {itemid = 3302, position = Position(33617,32706, 12)}, + {itemid = 3304, position = Position(33617,32706, 12)}, + {itemid = 3303, position = Position(33617,32706, 12)}, + {itemid = 8329, position = Position(33617,32706, 12)}, + {itemid = 3263, position = Position(33617,32707, 12)}, + {itemid = 3309, position = Position(33617,32708, 12)}, + {itemid = 414, position = Position(33617,32708, 12)}, + {itemid = 6217, position = Position(33617,32709, 12)}, + {itemid = 3301, position = Position(33617,32709, 12)}, + {itemid = 414, position = Position(33617,32709, 12)}, + {itemid = 3263, position = Position(33618,32694, 12)}, + {itemid = 3263, position = Position(33618,32695, 12)}, + {itemid = 4024, position = Position(33618,32696, 12)}, + {itemid = 3263, position = Position(33618,32696, 12)}, + {itemid = 3263, position = Position(33618,32697, 12)}, + {itemid = 3304, position = Position(33618,32698, 12)}, + {itemid = 3302, position = Position(33618,32698, 12)}, + {itemid = 3305, position = Position(33618,32698, 12)}, + {itemid = 414, position = Position(33618,32698, 12)}, + {itemid = 3263, position = Position(33618,32699, 12)}, + {itemid = 3263, position = Position(33618,32700, 12)}, + {itemid = 10740, position = Position(33618,32701, 12)}, + {itemid = 3263, position = Position(33618,32701, 12)}, + {itemid = 3308, position = Position(33618,32702, 12)}, + {itemid = 8326, position = Position(33618,32702, 12)}, + {itemid = 10740, position = Position(33618,32703, 12)}, + {itemid = 3300, position = Position(33618,32703, 12)}, + {itemid = 8347, position = Position(33618,32703, 12)}, + {itemid = 3298, position = Position(33618,32704, 12)}, + {itemid = 8328, position = Position(33618,32704, 12)}, + {itemid = 10739, position = Position(33618,32705, 12)}, + {itemid = 3306, position = Position(33618,32705, 12)}, + {itemid = 8332, position = Position(33618,32705, 12)}, + {itemid = 3263, position = Position(33618,32706, 12)}, + {itemid = 3263, position = Position(33618,32707, 12)}, + {itemid = 3308, position = Position(33618,32708, 12)}, + {itemid = 414, position = Position(33618,32708, 12)}, + {itemid = 6219, position = Position(33618,32709, 12)}, + {itemid = 3300, position = Position(33618,32709, 12)}, + {itemid = 414, position = Position(33618,32709, 12)}, + {itemid = 3263, position = Position(33619,32694, 12)}, + {itemid = 3263, position = Position(33619,32695, 12)}, + {itemid = 3263, position = Position(33619,32696, 12)}, + {itemid = 3263, position = Position(33619,32697, 12)}, + {itemid = 3263, position = Position(33619,32698, 12)}, + {itemid = 4019, position = Position(33619,32699, 12)}, + {itemid = 3263, position = Position(33619,32699, 12)}, + {itemid = 3263, position = Position(33619,32700, 12)}, + {itemid = 3263, position = Position(33619,32701, 12)}, + {itemid = 3263, position = Position(33619,32702, 12)}, + {itemid = 3308, position = Position(33619,32703, 12)}, + {itemid = 8332, position = Position(33619,32703, 12)}, + {itemid = 10740, position = Position(33619,32704, 12)}, + {itemid = 3306, position = Position(33619,32704, 12)}, + {itemid = 8347, position = Position(33619,32704, 12)}, + {itemid = 3263, position = Position(33619,32705, 12)}, + {itemid = 3263, position = Position(33619,32706, 12)}, + {itemid = 3263, position = Position(33619,32707, 12)}, + {itemid = 3263, position = Position(33619,32708, 12)}, + {itemid = 3305, position = Position(33619,32709, 12)}, + {itemid = 414, position = Position(33619,32709, 12)}, + {itemid = 3263, position = Position(33620,32694, 12)}, + {itemid = 3263, position = Position(33620,32695, 12)}, + {itemid = 3263, position = Position(33620,32696, 12)}, + {itemid = 3263, position = Position(33620,32697, 12)}, + {itemid = 3263, position = Position(33620,32698, 12)}, + {itemid = 3263, position = Position(33620,32699, 12)}, + {itemid = 3263, position = Position(33620,32700, 12)}, + {itemid = 3263, position = Position(33620,32701, 12)}, + {itemid = 3304, position = Position(33620,32702, 12)}, + {itemid = 3303, position = Position(33620,32702, 12)}, + {itemid = 3305, position = Position(33620,32702, 12)}, + {itemid = 414, position = Position(33620,32702, 12)}, + {itemid = 3263, position = Position(33620,32703, 12)}, + {itemid = 3263, position = Position(33620,32704, 12)}, + {itemid = 3263, position = Position(33620,32705, 12)}, + {itemid = 3263, position = Position(33620,32706, 12)}, + {itemid = 3263, position = Position(33620,32707, 12)}, + {itemid = 5391, position = Position(33620,32708, 12)}, + {itemid = 3263, position = Position(33620,32708, 12)}, + {itemid = 414, position = Position(33620,32709, 12)}, + {itemid = 3263, position = Position(33621,32694, 12)}, + {itemid = 3263, position = Position(33621,32695, 12)}, + {itemid = 3263, position = Position(33621,32696, 12)}, + {itemid = 4008, position = Position(33621,32697, 12)}, + {itemid = 3263, position = Position(33621,32697, 12)}, + {itemid = 3263, position = Position(33621,32698, 12)}, + {itemid = 3263, position = Position(33621,32699, 12)}, + {itemid = 3263, position = Position(33621,32700, 12)}, + {itemid = 3309, position = Position(33621,32701, 12)}, + {itemid = 414, position = Position(33621,32701, 12)}, + {itemid = 6219, position = Position(33621,32702, 12)}, + {itemid = 3301, position = Position(33621,32702, 12)}, + {itemid = 3304, position = Position(33621,32702, 12)}, + {itemid = 414, position = Position(33621,32702, 12)}, + {itemid = 3263, position = Position(33621,32703, 12)}, + {itemid = 3263, position = Position(33621,32704, 12)}, + {itemid = 3263, position = Position(33621,32705, 12)}, + {itemid = 3263, position = Position(33621,32706, 12)}, + {itemid = 3263, position = Position(33621,32707, 12)}, + {itemid = 3263, position = Position(33621,32708, 12)}, + {itemid = 5157, position = Position(33621,32709, 12)}, + {itemid = 3263, position = Position(33621,32709, 12)}, + {itemid = 3263, position = Position(33622,32694, 12)}, + {itemid = 3263, position = Position(33622,32695, 12)}, + {itemid = 3263, position = Position(33622,32696, 12)}, + {itemid = 3263, position = Position(33622,32697, 12)}, + {itemid = 3263, position = Position(33622,32698, 12)}, + {itemid = 3263, position = Position(33622,32699, 12)}, + {itemid = 3309, position = Position(33622,32700, 12)}, + {itemid = 414, position = Position(33622,32700, 12)}, + {itemid = 3301, position = Position(33622,32701, 12)}, + {itemid = 414, position = Position(33622,32701, 12)}, + {itemid = 3299, position = Position(33622,32702, 12)}, + {itemid = 3298, position = Position(33622,32702, 12)}, + {itemid = 414, position = Position(33622,32702, 12)}, + {itemid = 3302, position = Position(33622,32703, 12)}, + {itemid = 3304, position = Position(33622,32703, 12)}, + {itemid = 3303, position = Position(33622,32703, 12)}, + {itemid = 414, position = Position(33622,32703, 12)}, + {itemid = 3263, position = Position(33622,32704, 12)}, + {itemid = 3263, position = Position(33622,32705, 12)}, + {itemid = 3304, position = Position(33622,32706, 12)}, + {itemid = 3303, position = Position(33622,32706, 12)}, + {itemid = 3305, position = Position(33622,32706, 12)}, + {itemid = 414, position = Position(33622,32706, 12)}, + {itemid = 3263, position = Position(33622,32707, 12)}, + {itemid = 4020, position = Position(33622,32708, 12)}, + {itemid = 3263, position = Position(33622,32708, 12)}, + {itemid = 3263, position = Position(33622,32709, 12)}, + {itemid = 3263, position = Position(33623,32694, 12)}, + {itemid = 3263, position = Position(33623,32695, 12)}, + {itemid = 3263, position = Position(33623,32696, 12)}, + {itemid = 3263, position = Position(33623,32697, 12)}, + {itemid = 4135, position = Position(33623,32698, 12)}, + {itemid = 3263, position = Position(33623,32698, 12)}, + {itemid = 3263, position = Position(33623,32699, 12)}, + {itemid = 6219, position = Position(33623,32700, 12)}, + {itemid = 3308, position = Position(33623,32700, 12)}, + {itemid = 414, position = Position(33623,32700, 12)}, + {itemid = 6219, position = Position(33623,32701, 12)}, + {itemid = 3300, position = Position(33623,32701, 12)}, + {itemid = 414, position = Position(33623,32701, 12)}, + {itemid = 6218, position = Position(33623,32702, 12)}, + {itemid = 3304, position = Position(33623,32702, 12)}, + {itemid = 414, position = Position(33623,32702, 12)}, + {itemid = 3263, position = Position(33623,32703, 12)}, + {itemid = 3263, position = Position(33623,32704, 12)}, + {itemid = 3302, position = Position(33623,32705, 12)}, + {itemid = 3305, position = Position(33623,32705, 12)}, + {itemid = 3303, position = Position(33623,32705, 12)}, + {itemid = 4024, position = Position(33623,32705, 12)}, + {itemid = 414, position = Position(33623,32705, 12)}, + {itemid = 3302, position = Position(33623,32706, 12)}, + {itemid = 3301, position = Position(33623,32706, 12)}, + {itemid = 3299, position = Position(33623,32706, 12)}, + {itemid = 414, position = Position(33623,32706, 12)}, + {itemid = 3300, position = Position(33623,32707, 12)}, + {itemid = 3303, position = Position(33623,32707, 12)}, + {itemid = 3304, position = Position(33623,32707, 12)}, + {itemid = 414, position = Position(33623,32707, 12)}, + {itemid = 3263, position = Position(33623,32708, 12)}, + {itemid = 3263, position = Position(33623,32709, 12)}, + {itemid = 3307, position = Position(33624,32694, 12)}, + {itemid = 414, position = Position(33624,32694, 12)}, + {itemid = 3263, position = Position(33624,32695, 12)}, + {itemid = 3263, position = Position(33624,32696, 12)}, + {itemid = 3263, position = Position(33624,32697, 12)}, + {itemid = 3263, position = Position(33624,32698, 12)}, + {itemid = 3263, position = Position(33624,32699, 12)}, + {itemid = 3263, position = Position(33624,32700, 12)}, + {itemid = 3308, position = Position(33624,32701, 12)}, + {itemid = 414, position = Position(33624,32701, 12)}, + {itemid = 6217, position = Position(33624,32702, 12)}, + {itemid = 3304, position = Position(33624,32702, 12)}, + {itemid = 3300, position = Position(33624,32702, 12)}, + {itemid = 414, position = Position(33624,32702, 12)}, + {itemid = 3263, position = Position(33624,32703, 12)}, + {itemid = 3263, position = Position(33624,32704, 12)}, + {itemid = 3263, position = Position(33624,32705, 12)}, + {itemid = 3263, position = Position(33624,32706, 12)}, + {itemid = 3299, position = Position(33624,32707, 12)}, + {itemid = 3305, position = Position(33624,32707, 12)}, + {itemid = 3302, position = Position(33624,32707, 12)}, + {itemid = 414, position = Position(33624,32707, 12)}, + {itemid = 3300, position = Position(33624,32708, 12)}, + {itemid = 3303, position = Position(33624,32708, 12)}, + {itemid = 3304, position = Position(33624,32708, 12)}, + {itemid = 414, position = Position(33624,32708, 12)}, + {itemid = 4021, position = Position(33624,32709, 12)}, + {itemid = 3263, position = Position(33624,32709, 12)}, + {itemid = 3299, position = Position(33625,32694, 12)}, + {itemid = 414, position = Position(33625,32694, 12)}, + {itemid = 3307, position = Position(33625,32695, 12)}, + {itemid = 414, position = Position(33625,32695, 12)}, + {itemid = 3263, position = Position(33625,32696, 12)}, + {itemid = 3263, position = Position(33625,32697, 12)}, + {itemid = 3263, position = Position(33625,32698, 12)}, + {itemid = 3263, position = Position(33625,32699, 12)}, + {itemid = 3309, position = Position(33625,32700, 12)}, + {itemid = 414, position = Position(33625,32700, 12)}, + {itemid = 3303, position = Position(33625,32701, 12)}, + {itemid = 414, position = Position(33625,32701, 12)}, + {itemid = 3303, position = Position(33625,32702, 12)}, + {itemid = 414, position = Position(33625,32702, 12)}, + {itemid = 3307, position = Position(33625,32703, 12)}, + {itemid = 414, position = Position(33625,32703, 12)}, + {itemid = 3263, position = Position(33625,32704, 12)}, + {itemid = 3263, position = Position(33625,32705, 12)}, + {itemid = 3263, position = Position(33625,32706, 12)}, + {itemid = 3263, position = Position(33625,32707, 12)}, + {itemid = 3305, position = Position(33625,32708, 12)}, + {itemid = 3299, position = Position(33625,32708, 12)}, + {itemid = 414, position = Position(33625,32708, 12)}, + {itemid = 3303, position = Position(33625,32709, 12)}, + {itemid = 414, position = Position(33625,32709, 12)} +} +local function transformArea() + for x = 33611, 33625 do + for y = 32694, 32709 do + local position = Position(x, y, 12) + local tile = Tile(position) + if not tile then + return + end + local ground = tile:getGround() + if not ground then + return + end + local grounds = ground:getId() + local items = tile:getItems() + for i = 1, #items do + local item = items[i] + if item then + item:remove() + end + end + ground:remove() + end + end + for i = 1, #venom do + local item = venom[i] + local ground = Tile(item.position):getGround() + local transformid = item.itemid + local tp = Game.createItem(item.itemid, 1, item.position) + end + return true +end + +local ferumbrasAscendantHabitatVenom = Action() +function ferumbrasAscendantHabitatVenom.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 10044 then + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Venom) >= 1 then + player:say('The lever are stucke, need some time to it can be moveable again.', TALKTYPE_MONSTER_SAY) + return true + end + Game.createMonster('lovely polar bear', Position(33617, 32702, 12), true, true) + addEvent(transformArea, 2 * 1000) + item:transform(10045) + local basin = Tile(Position(33628, 32703, 12)):getItemById(12070) + if basin then + basin:getPosition():sendMagicEffect(CONST_ME_ENERGYAREA) + basin:transform(24852) + end + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Venom, 1) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats, Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The room transforms into a completely different landscape.') + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats) >= 8 then + addEvent(functionRevert, 1 * 60 * 60 * 1000) + end + elseif item.itemid == 10045 then + item:transform(10044) + end + return true +end + +ferumbrasAscendantHabitatVenom:aid(34309) +ferumbrasAscendantHabitatVenom:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/lever_first.lua b/data/scripts/actions/quests/ferumbras_ascendant/lever_first.lua new file mode 100644 index 00000000000..9bc76d4c72c --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/lever_first.lua @@ -0,0 +1,32 @@ +local ferumbrasAscendantLeverFirst = Action() +function ferumbrasAscendantLeverFirst.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Active) < 1 then + return false + end + if item.itemid == 10029 then + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Done) >= 1 then + local spectators = Game.getSpectators(item:getPosition(), false, false, 9, 9, 6, 6) + for i = 1, #spectators do + if spectators[i]:isPlayer() then + local spec = spectators[i] + spec:teleportTo(Position(33646, 32654, 14)) + spec:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + spec:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Something clicked at same time a booming sound almost deafens you.") + end + end + revertStorages() + return true + end + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Done) < 1 then + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Done, 2) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Something clicked.") + end + item:transform(10030) + elseif item.itemid == 10030 then + item:transform(10029) + end + return true +end + +ferumbrasAscendantLeverFirst:aid(53821) +ferumbrasAscendantLeverFirst:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/lever_four.lua b/data/scripts/actions/quests/ferumbras_ascendant/lever_four.lua new file mode 100644 index 00000000000..4b59ba67bcd --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/lever_four.lua @@ -0,0 +1,30 @@ +local ferumbrasAscendantLevelFour = Action() +function ferumbrasAscendantLevelFour.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Active) < 1 then + return false + end + if item.itemid == 10029 then + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Done) < 4 then + local spectators = Game.getSpectators(item:getPosition(), false, false, 9, 9, 6, 6) + for i = 1, #spectators do + if spectators[i]:isPlayer() then + local spec = spectators[i] + spec:teleportTo(Position(33646, 32654, 14)) + spec:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + revertStorages() + return true + end + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Done) >= 4 then + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Done, 4) + end + item:transform(10030) + elseif item.itemid == 10030 then + item:transform(10029) + end + return true +end + +ferumbrasAscendantLevelFour:aid(53824) +ferumbrasAscendantLevelFour:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/lever_second.lua b/data/scripts/actions/quests/ferumbras_ascendant/lever_second.lua new file mode 100644 index 00000000000..29d74d9f6f6 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/lever_second.lua @@ -0,0 +1,32 @@ +local ferumbrasAscendantLeverSecond = Action() +function ferumbrasAscendantLeverSecond.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Active) < 1 then + return false + end + if item.itemid == 10029 then + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Done) < 2 then + local spectators = Game.getSpectators(item:getPosition(), false, false, 9, 9, 6, 6) + for i = 1, #spectators do + if spectators[i]:isPlayer() then + local spec = spectators[i] + spec:teleportTo(Position(33646, 32654, 14)) + spec:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + spec:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Something clicked at same time a booming sound almost deafens you.") + end + end + revertStorages() + return true + end + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Done) >= 2 then + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Done, 3) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Something clicked.") + end + item:transform(10030) + elseif item.itemid == 10030 then + item:transform(10029) + end + return true +end + +ferumbrasAscendantLeverSecond:aid(53822) +ferumbrasAscendantLeverSecond:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/lever_third.lua b/data/scripts/actions/quests/ferumbras_ascendant/lever_third.lua new file mode 100644 index 00000000000..4df2ee4d449 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/lever_third.lua @@ -0,0 +1,40 @@ +local ferumbrasAscendantLeverThird = Action() +function ferumbrasAscendantLeverThird.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Active) < 1 then + return false + end + if item.itemid == 10029 then + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Done) < 3 then + local spectators = Game.getSpectators(item:getPosition(), false, false, 9, 9, 6, 6) + for i = 1, #spectators do + if spectators[i]:isPlayer() then + local spec = spectators[i] + spec:teleportTo(Position(33646, 32654, 14)) + spec:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + spec:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Something clicked at same time a booming sound almost deafens you.") + end + end + revertStorages() + return true + end + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Four) == 4 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "A booming sound almost deafens you. From somewhere deep within you hear a whisper: 'Blood...'") + end + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Four) == 5 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "A booming sound almost deafens you. From somewhere deep within you hear a whisper: 'Grass...'") + end + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Four) == 6 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "A booming sound almost deafens you. From somewhere deep within you hear a whisper: 'Ice...'") + end + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Done) >= 3 then + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Done, 4) + end + item:transform(10030) + elseif item.itemid == 10030 then + item:transform(10029) + end + return true +end + +ferumbrasAscendantLeverThird:aid(53823) +ferumbrasAscendantLeverThird:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/mazoran_lever.lua b/data/scripts/actions/quests/ferumbras_ascendant/mazoran_lever.lua new file mode 100644 index 00000000000..02b38484ea0 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/mazoran_lever.lua @@ -0,0 +1,50 @@ +local config = { + centerRoom = Position(33584, 32689, 14), + BossPosition = Position(33584, 32689, 14), + playerPositions = { + Position(33593, 32644, 14), + Position(33593, 32645, 14), + Position(33593, 32646, 14), + Position(33593, 32647, 14), + Position(33593, 32648, 14) + }, + newPosition = Position(33585, 32693, 14) +} + +local ferumbrasAscendantMazoranLever = Action() +function ferumbrasAscendantMazoranLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 9825 then + if player:getPosition() ~= Position(33593, 32644, 14) then + item:transform(9826) + return true + end + end + if item.itemid == 9825 then + local specs, spec = Game.getSpectators(config.centerRoom, false, false, 15, 15, 15, 15) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Someone is fighting with Mazoran.") + return true + end + end + Game.createMonster("Mazoran", config.BossPosition, true, true) + for y = 32644, 32648 do + local playerTile = Tile(Position(33593, y, 14)):getTopCreature() + if playerTile and playerTile:isPlayer() then + playerTile:getPosition():sendMagicEffect(CONST_ME_POFF) + playerTile:teleportTo(config.newPosition) + playerTile:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.MazoranTimer, 1) + addEvent(clearForgotten, 30 * 60 * 1000, Position(33572, 32679, 14), Position(33599, 32701, 14), Position(33319, 32318, 13), GlobalStorage.FerumbrasAscendant.MazoranTimer) + item:transform(9826) + elseif item.itemid == 9826 then + item:transform(9825) + end + return true +end + +ferumbrasAscendantMazoranLever:uid(1025) +ferumbrasAscendantMazoranLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/mysterious_scroll.lua b/data/scripts/actions/quests/ferumbras_ascendant/mysterious_scroll.lua new file mode 100644 index 00000000000..66d8f84e98a --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/mysterious_scroll.lua @@ -0,0 +1,15 @@ +local ferumbrasAscendantMysterious = Action() +function ferumbrasAscendantMysterious.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.FerumbrasAscension.RiftRunner) >= 1 or player:getStorageValue(24850) < 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'No matter how often you try, you cannot decipher anything.') + return true + else + player:addMount(87) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You decipher something! You get a rift runner to accompany you on your journey.') + player:setStorageValue(Storage.FerumbrasAscension.RiftRunner, 1) + end + return true +end + +ferumbrasAscendantMysterious:id(34784) +ferumbrasAscendantMysterious:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/plagirath_lever.lua b/data/scripts/actions/quests/ferumbras_ascendant/plagirath_lever.lua new file mode 100644 index 00000000000..fed5a0ce8fd --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/plagirath_lever.lua @@ -0,0 +1,50 @@ +local config = { + centerRoom = Position(33172, 31501, 13), + BossPosition = Position(33172, 31501, 13), + playerPositions = { + Position(33229, 31500, 13), + Position(33229, 31501, 13), + Position(33229, 31502, 13), + Position(33229, 31503, 13), + Position(33229, 31504, 13) + }, + newPosition = Position(33173, 31504, 13) +} + +local ferumbrasAscendantPlagirathLever = Action() +function ferumbrasAscendantPlagirathLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 9825 then + if player:getPosition() ~= Position(33229, 31500, 13) then + item:transform(9826) + return true + end + end + if item.itemid == 9825 then + local specs, spec = Game.getSpectators(config.centerRoom, false, false, 15, 15, 15, 15) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Someone is fighting with Plagirath.") + return true + end + end + Game.createMonster("Plagirath", config.BossPosition, true, true) + for y = 31500, 31504 do + local playerTile = Tile(Position(33229, y, 13)):getTopCreature() + if playerTile and playerTile:isPlayer() then + playerTile:getPosition():sendMagicEffect(CONST_ME_POFF) + playerTile:teleportTo(config.newPosition) + playerTile:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.PlagirathTimer, 1) + addEvent(clearForgotten, 30 * 60 * 1000, Position(33159, 31491, 13), Position(33185, 31513, 13), Position(33319, 32318, 13), GlobalStorage.FerumbrasAscendant.PlagirathTimer) + item:transform(9826) + elseif item.itemid == 9826 then + item:transform(9825) + end + return true +end + +ferumbrasAscendantPlagirathLever:uid(1022) +ferumbrasAscendantPlagirathLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/purified_soul.lua b/data/scripts/actions/quests/ferumbras_ascendant/purified_soul.lua new file mode 100644 index 00000000000..a6f272f7baf --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/purified_soul.lua @@ -0,0 +1,16 @@ +local ferumbrasAscendantPurifiedSoul = Action() +function ferumbrasAscendantPurifiedSoul.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local devourer = target:getName():lower() == 'sin devourer' and target:isMonster() + if not devourer then + return false + end + + target:getPosition():sendMagicEffect(CONST_ME_HOLYAREA) + target:say('The Sin Devourer has been driven out!', TALKTYPE_MONSTER_SAY) + target:remove() + item:remove() + return true +end + +ferumbrasAscendantPurifiedSoul:id(25354) +ferumbrasAscendantPurifiedSoul:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/ragiaz_lever.lua b/data/scripts/actions/quests/ferumbras_ascendant/ragiaz_lever.lua new file mode 100644 index 00000000000..76564d2adaf --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/ragiaz_lever.lua @@ -0,0 +1,52 @@ +local config = { + centerRoom = Position(33481, 32334, 13), + BossPosition = Position(33481, 32334, 13), + newPosition = Position(33482, 32339, 13), + deathDragons = { + Position(33476, 32331, 13), + Position(33476, 32340, 13), + Position(33487, 32340, 13), + Position(33488, 32331, 13) + } +} + +local ferumbrasAscendantRagiaz = Action() +function ferumbrasAscendantRagiaz.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 9825 then + if player:getPosition() ~= Position(33456, 32356, 13) then + item:transform(9826) + return true + end + end + if item.itemid == 9825 then + local specs, spec = Game.getSpectators(config.centerRoom, false, false, 15, 15, 15, 15) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Someone is fighting with Ragiaz.") + return true + end + end + Game.createMonster("Ragiaz", config.BossPosition, true, true) + for d = 1, #config.deathDragons do + Game.createMonster('Death Dragon', config.deathDragons[d], true, true) + end + for x = 33456, 33460 do + local playerTile = Tile(Position(x, 32356, 13)):getTopCreature() + if playerTile and playerTile:isPlayer() then + playerTile:getPosition():sendMagicEffect(CONST_ME_POFF) + playerTile:teleportTo(config.newPosition) + playerTile:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.RagiazTimer, 1) + addEvent(clearForgotten, 30 * 60 * 1000, Position(33472, 32323, 13), Position(33493, 32347, 13), Position(33319, 32318, 13), GlobalStorage.FerumbrasAscendant.RagiazTimer) + item:transform(9826) + elseif item.itemid == 9826 then + item:transform(9825) + end + return true +end + +ferumbrasAscendantRagiaz:uid(1023) +ferumbrasAscendantRagiaz:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/rat_lever.lua b/data/scripts/actions/quests/ferumbras_ascendant/rat_lever.lua new file mode 100644 index 00000000000..9b699fbdcc9 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/rat_lever.lua @@ -0,0 +1,49 @@ +local config = { + centerRoom = Position(33215, 31456, 12), + BossPosition = Position(33220, 31460, 12), + playerPositions = { + Position(33197, 31475, 11), + Position(33198, 31475, 11), + Position(33199, 31475, 11), + Position(33200, 31475, 11), + Position(33201, 31475, 11) + }, + newPosition = Position(33215, 31470, 12) +} + +local ferumbrasAscendantRatLever = Action() +function ferumbrasAscendantRatLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 9825 then + if player:getPosition() ~= Position(33201, 31475, 11) then + item:transform(9826) + return true + end + end + if item.itemid == 9825 then + local specs, spec = Game.getSpectators(config.centerRoom, false, false, 30, 30, 30, 30) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Someone is fighting with The Lord of The Lice.") + return true + end + end + Game.createMonster("the lord of the lice", config.BossPosition, true, true) + for x = 33197, 33201 do + local playerTile = Tile(Position(x, 31475, 11)):getTopCreature() + if playerTile and playerTile:isPlayer() then + playerTile:getPosition():sendMagicEffect(CONST_ME_POFF) + playerTile:teleportTo(config.newPosition) + playerTile:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + addEvent(clearForgotten, 30 * 60 * 1000, Position(33187, 31429, 12), Position(33242, 31487, 12), Position(33319, 32318, 13)) + item:transform(9826) + elseif item.itemid == 9826 then + item:transform(9825) + end + return true +end + +ferumbrasAscendantRatLever:uid(1030) +ferumbrasAscendantRatLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/razzagorn_lever.lua b/data/scripts/actions/quests/ferumbras_ascendant/razzagorn_lever.lua new file mode 100644 index 00000000000..d7dadc47afa --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/razzagorn_lever.lua @@ -0,0 +1,42 @@ +local config = { + centerRoom = Position(33422, 32467, 14), + BossPosition = Position(33422, 32467, 14), + newPosition = Position(33419, 32467, 14) +} + +local ferumbrasAscendantRazzagornLever = Action() +function ferumbrasAscendantRazzagornLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 9825 then + if player:getPosition() ~= Position(33386, 32455, 14) then + item:transform(9826) + return true + end + end + if item.itemid == 9825 then + local specs, spec = Game.getSpectators(config.centerRoom, false, false, 15, 15, 15, 15) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Someone is fighting with Razzagorn.") + return true + end + end + Game.createMonster("Razzagorn", config.BossPosition, true, true) + for x = 33386, 33390 do + local playerTile = Tile(Position(x, 32455, 14)):getTopCreature() + if playerTile and playerTile:isPlayer() then + playerTile:getPosition():sendMagicEffect(CONST_ME_POFF) + playerTile:teleportTo(config.newPosition) + playerTile:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + addEvent(clearForgotten, 30 * 60 * 1000, Position(33408, 32454, 14), Position(33440, 32480, 14), Position(33319, 32318, 13)) + item:transform(9826) + elseif item.itemid == 9826 then + item:transform(9825) + end + return true +end + +ferumbrasAscendantRazzagornLever:uid(1024) +ferumbrasAscendantRazzagornLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/reward.lua b/data/scripts/actions/quests/ferumbras_ascendant/reward.lua new file mode 100644 index 00000000000..d988d0ad5c5 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/reward.lua @@ -0,0 +1,42 @@ +local items = { + {itemid = 25387, count = 1}, + {itemid = 25387, count = 1}, + {itemid = 25387, count = 1}, + {itemid = 25387, count = 1}, + {itemid = 25393, count = 4}, + {itemid = 25431, count = 1}, + {itemid = 2160, count = 10}, + {itemid = 25172, count = 5} +} + +local ferumbrasAscendantReward = Action() +function ferumbrasAscendantReward.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid ~= 12664 then + return false + end + if player:getStorageValue(Storage.FerumbrasAscension.Reward) >= 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The treasure chest is empty.') + return true + end + player:addAchievement('Hat Hunter') + player:addOutfitAddon(852, 3) + player:addOutfitAddon(846, 3) + local bag = Game.createItem(1987) + for i = 1, #items do + bag:addItem(items[i].itemid, items[i].count) + end + if player:addItemEx(bag) ~= RETURNVALUE_NOERROR then + local weight = bag:getWeight() + if player:getFreeCapacity() < weight then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format('You have found %s weighing %.2f oz. You have no capacity.', bag:getName(), (weight / 100))) + else + player:sendCancelMessage('You have found a bag, but you have no room to take it.') + end + return true + end + player:setStorageValue(Storage.FerumbrasAscension.Reward, 1) + return true +end + +ferumbrasAscendantReward:uid(1035) +ferumbrasAscendantReward:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/sacrifice.lua b/data/scripts/actions/quests/ferumbras_ascendant/sacrifice.lua new file mode 100644 index 00000000000..42d2e70c5da --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/sacrifice.lua @@ -0,0 +1,61 @@ +local fount = { + [1] = {transformid = 24822, pos = Position(33421, 32383, 12), revert = 3729}, + [2] = {transformid = 24823, pos = Position(33422, 32383, 12), revert = 3730}, + [3] = {transformid = 24824, pos = Position(33421, 32384, 12), revert = 3731}, + [4] = {transformid = 24825, pos = Position(33422, 32384, 12), revert = 3732} +} + +local ferumbrasAscendantSacrifice = Action() +function ferumbrasAscendantSacrifice.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if not target.actionid == 53805 or Tile(Position(33415, 32379, 12)):getItemById(24817) or player:getStorageValue(Storage.FerumbrasAscension.Fount) >= 4 then + return false + end + if item.itemid == 24814 then + if player:getStorageValue(Storage.FerumbrasAscension.Bone) >= 1 then + player:say('You already put the bones on the blood well.', TALKTYPE_MONSTER_SAY) + return true + end + player:setStorageValue(Storage.FerumbrasAscension.Bone, 1) + elseif item.itemid == 24826 then + if player:getStorageValue(Storage.FerumbrasAscension.Ring2) >= 1 then + player:say('You already put the signet ring on the blood well.', TALKTYPE_MONSTER_SAY) + return true + end + player:setStorageValue(Storage.FerumbrasAscension.Ring2, 1) + elseif item.itemid == 10602 then + if player:getStorageValue(Storage.FerumbrasAscension.Vampire) >= 1 then + player:say('You already put the vampire teeth on the blood well.', TALKTYPE_MONSTER_SAY) + return true + end + player:setStorageValue(Storage.FerumbrasAscension.Vampire, 1) + elseif item.itemid == 2747 then + if player:getStorageValue(Storage.FerumbrasAscension.Flower) >= 1 then + player:say('You already put the grave flower on the blood well.', TALKTYPE_MONSTER_SAY) + return true + end + player:setStorageValue(Storage.FerumbrasAscension.Flower, 1) + end + if player:getStorageValue(Storage.FerumbrasAscension.Fount) == 3 then + for i = 1, #fount do + local fount = fount[i] + local founts = Tile(fount.pos):getItemById(fount.revert) + founts:transform(fount.transformid) + founts:setActionId(100) + end + local statue = Tile(Position(33415, 32379, 12)):getItemById(24819) + if statue then + statue:transform(24817) + end + end + if player:getStorageValue(Storage.FerumbrasAscension.Fount) < 0 then + player:setStorageValue(Storage.FerumbrasAscension.Fount, 0) + end + player:setStorageValue(Storage.FerumbrasAscension.Fount, player:getStorageValue(Storage.FerumbrasAscension.Fount) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You put the ' ..item:getName().. ' into the dried well.') + toPosition:sendMagicEffect(CONST_ME_DRAWBLOOD) + item:remove(1) + return true +end + +ferumbrasAscendantSacrifice:id(2747,10602,24814,24826) +ferumbrasAscendantSacrifice:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/scroll_of_ascension.lua b/data/scripts/actions/quests/ferumbras_ascendant/scroll_of_ascension.lua new file mode 100644 index 00000000000..59191114949 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/scroll_of_ascension.lua @@ -0,0 +1,18 @@ +local ferumbrasAscendantScroll = Action() +function ferumbrasAscendantScroll.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local outfit = {lookType = 35} + if item.itemid == 25427 then + doSetCreatureOutfit(player, outfit, 30 * 1000) + item:transform(25428) + item:decay() + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Magical sparks whirl around the scroll as you read and then your appearance is changing.') + return true + elseif item.itemid == 25428 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You are tired of the last scroll reading, rest your eyes for a moment.') + end + return true +end + +ferumbrasAscendantScroll:id(25427,25428) +ferumbrasAscendantScroll:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/shulgrax_lever.lua b/data/scripts/actions/quests/ferumbras_ascendant/shulgrax_lever.lua new file mode 100644 index 00000000000..3409adf3f4e --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/shulgrax_lever.lua @@ -0,0 +1,50 @@ +local config = { + centerRoom = Position(33485, 32786, 13), + BossPosition = Position(33485, 32786, 13), + playerPositions = { + Position(33434, 32785, 13), + Position(33434, 32786, 13), + Position(33434, 32787, 13), + Position(33434, 32788, 13), + Position(33434, 32789, 13) + }, + newPosition = Position(33485, 32790, 13) +} + +local ferumbrasAscendantShulgraxLever = Action() +function ferumbrasAscendantShulgraxLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 9825 then + if player:getPosition() ~= Position(33434, 32785, 13) then + item:transform(9826) + return true + end + end + if item.itemid == 9825 then + local specs, spec = Game.getSpectators(config.centerRoom, false, false, 15, 15, 15, 15) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Someone is fighting with Shulgrax.") + return true + end + end + Game.createMonster("Shulgrax", config.BossPosition, true, true) + for y = 32785, 32789 do + local playerTile = Tile(Position(33434, y, 13)):getTopCreature() + if playerTile and playerTile:isPlayer() then + playerTile:getPosition():sendMagicEffect(CONST_ME_POFF) + playerTile:teleportTo(config.newPosition) + playerTile:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.ShulgraxTimer, 1) + addEvent(clearForgotten, 30 * 60 * 1000, Position(33473, 32776, 13), Position(33496, 32798, 13), Position(33319, 32318, 13), GlobalStorage.FerumbrasAscendant.ShulgraxTimer) + item:transform(9826) + elseif item.itemid == 9826 then + item:transform(9825) + end + return true +end + +ferumbrasAscendantShulgraxLever:uid(1028) +ferumbrasAscendantShulgraxLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/statue.lua b/data/scripts/actions/quests/ferumbras_ascendant/statue.lua new file mode 100644 index 00000000000..46cbcf28afa --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/statue.lua @@ -0,0 +1,26 @@ +local fount = { + [1] = {transformid = 24822, pos = Position(33421, 32383, 12), revert = 3729}, + [2] = {transformid = 24823, pos = Position(33422, 32383, 12), revert = 3730}, + [3] = {transformid = 24824, pos = Position(33421, 32384, 12), revert = 3731}, + [4] = {transformid = 24825, pos = Position(33422, 32384, 12), revert = 3732} +} + +local ferumbrasAscendantStatue = Action() +function ferumbrasAscendantStatue.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if Tile(Position(33415, 32379, 12)):getItemById(24819) or player:getStorageValue(Storage.FerumbrasAscension.Fount) < 4 or player:getStorageValue(Storage.FerumbrasAscension.Statue) >= 1 then + return false + end + for i = 1, #fount do + local fount = fount[i] + local founts = Tile(fount.pos):getItemById(fount.transformid) + founts:transform(fount.revert) + founts:setActionId(53805) + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You douse the sacred statue\'s flame. The room darkens.') + player:setStorageValue(Storage.FerumbrasAscension.Statue, 1) + item:transform(24819) + return true +end + +ferumbrasAscendantStatue:id(24817) +ferumbrasAscendantStatue:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/tarbaz_lever.lua b/data/scripts/actions/quests/ferumbras_ascendant/tarbaz_lever.lua new file mode 100644 index 00000000000..7a440da44bc --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/tarbaz_lever.lua @@ -0,0 +1,42 @@ +local config = { + centerRoom = Position(33459, 32844, 11), + BossPosition = Position(33459, 32844, 11), + newPosition = Position(33459, 32848, 11) +} + +local ferumbrasAscendantTarbazLever = Action() +function ferumbrasAscendantTarbazLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 9825 then + if player:getPosition() ~= Position(33418, 32849, 11) then + item:transform(9826) + return true + end + end + if item.itemid == 9825 then + local specs, spec = Game.getSpectators(config.centerRoom, false, false, 15, 15, 15, 15) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Someone is fighting with Tarbaz.") + return true + end + end + Game.createMonster("Tarbaz", config.BossPosition, true, true) + for y = 32849, 32853 do + local playerTile = Tile(Position(33418, y, 11)):getTopCreature() + if playerTile and playerTile:isPlayer() then + playerTile:getPosition():sendMagicEffect(CONST_ME_POFF) + playerTile:teleportTo(config.newPosition) + playerTile:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + addEvent(clearForgotten, 30 * 60 * 1000, Position(33446, 32833, 11), Position(33515, 32875, 12), Position(33319, 32318, 13)) + item:transform(9826) + elseif item.itemid == 9826 then + item:transform(9825) + end + return true +end + +ferumbrasAscendantTarbazLever:uid(1027) +ferumbrasAscendantTarbazLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/tarbaz_notes.lua b/data/scripts/actions/quests/ferumbras_ascendant/tarbaz_notes.lua new file mode 100644 index 00000000000..54656b5e3f0 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/tarbaz_notes.lua @@ -0,0 +1,21 @@ +local ferumbrasAscendantTarbazNotes = Action() +function ferumbrasAscendantTarbazNotes.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.actionid == 54388 then + if player:getStorageValue(Storage.FerumbrasAscension.BasinCounter) ~= 8 then + return false + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Suddenly, you see the big picture. It all makes sense now. And then you despair.') + player:setStorageValue(Storage.FerumbrasAscension.TarbazNotes, 1) + elseif item.actionid == 54389 then + if player:getStorageValue(Storage.FerumbrasAscension.BasinCounter) ~= 8 and player:getStorageValue(Storage.FerumbrasAscension.TarbazNotes) < 1 then + return false + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Suddenly, you see the latter A. It all makes sense now. And then you now the secret.') + player:setStorageValue(Storage.FerumbrasAscension.TarbazNotes, 2) + end + toPosition:sendMagicEffect(CONST_ME_THUNDER) + return true +end + +ferumbrasAscendantTarbazNotes:aid(54388,54389) +ferumbrasAscendantTarbazNotes:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/teleportation_rod.lua b/data/scripts/actions/quests/ferumbras_ascendant/teleportation_rod.lua new file mode 100644 index 00000000000..032ce5bb0a1 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/teleportation_rod.lua @@ -0,0 +1,31 @@ +local config = { + [24830] = {storageKey = Storage.FerumbrasAscension.Razzagorn}, + [24831] = {storageKey = Storage.FerumbrasAscension.Ragiaz}, + [24832] = {storageKey = Storage.FerumbrasAscension.Zamulosh}, + [24833] = {storageKey = Storage.FerumbrasAscension.Mazoran}, + [24834] = {storageKey = Storage.FerumbrasAscension.Tarbaz}, + [24835] = {storageKey = Storage.FerumbrasAscension.Shulgrax}, + [24836] = {storageKey = Storage.FerumbrasAscension.Plagirath} +} + +local ferumbrasAscendantTeleportation = Action() +function ferumbrasAscendantTeleportation.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local targetItem = config[target.itemid] + if not targetItem then + return false + end + if player:getStorageValue(targetItem.storageKey) == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You already teleported this part of the Godbreaker to Mazarius.') + return true + end + player:setStorageValue(targetItem.storageKey, 1) + local pos = player:getPosition() + pos.z = pos.z - 1 + player:teleportTo(pos) + player:getPosition():sendMagicEffect(CONST_ME_THUNDER) + toPosition:sendMagicEffect(CONST_ME_MORTAREA) + return true +end + +ferumbrasAscendantTeleportation:id(24838) +ferumbrasAscendantTeleportation:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/the_shatterer_lever.lua b/data/scripts/actions/quests/ferumbras_ascendant/the_shatterer_lever.lua new file mode 100644 index 00000000000..6a191f51228 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/the_shatterer_lever.lua @@ -0,0 +1,50 @@ +local config = { + centerRoom = Position(33406, 32418, 14), + BossPosition = Position(33406, 32418, 14), + playerPositions = { + Position(33403, 32465, 13), + Position(33404, 32465, 13), + Position(33405, 32465, 13), + Position(33406, 32465, 13), + Position(33407, 32465, 13) + }, + newPosition = Position(33398, 32414, 14) +} + +local ferumbrasAscendantTheShattererLever = Action() +function ferumbrasAscendantTheShattererLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 9825 then + if player:getPosition() ~= Position(33403, 32465, 13) then + item:transform(9826) + return true + end + end + if item.itemid == 9825 then + local specs, spec = Game.getSpectators(config.centerRoom, false, false, 30, 30, 30, 30) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Someone is fighting with The Shatterer.") + return true + end + end + Game.createMonster("The Shatterer", config.BossPosition, true, true) + for x = 33403, 33407 do + local playerTile = Tile(Position(x, 32465, 13)):getTopCreature() + if playerTile and playerTile:isPlayer() then + playerTile:getPosition():sendMagicEffect(CONST_ME_POFF) + playerTile:teleportTo(config.newPosition) + playerTile:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + Game.setStorageValue(Storage.FerumbrasAscension.TheShattererTimer, 1) + addEvent(clearForgotten, 30 * 60 * 1000, Position(33377, 32390, 14), Position(33446, 32447, 14), Position(33319, 32318, 13), Storage.FerumbrasAscension.TheShattererTimer) + item:transform(9826) + elseif item.itemid == 9826 then + item:transform(9825) + end + return true +end + +ferumbrasAscendantTheShattererLever:uid(1029) +ferumbrasAscendantTheShattererLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/the_shatterer_levers.lua b/data/scripts/actions/quests/ferumbras_ascendant/the_shatterer_levers.lua new file mode 100644 index 00000000000..933fe988148 --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/the_shatterer_levers.lua @@ -0,0 +1,129 @@ +local chains = { + West = { + [1] = {itemid = 23656, position = Position(33401, 32419, 14)}, + [2] = {itemid = 23655, position = Position(33402, 32419, 14)}, + [3] = {itemid = 23655, position = Position(33403, 32419, 14)}, + [4] = {itemid = 23657, position = Position(33404, 32419, 14)}, + [5] = {itemid = 23656, position = Position(33405, 32419, 14)}, + [6] = {itemid = 23657, position = Position(33406, 32419, 14)}, + [7] = {itemid = 1495, position = Position(33403, 32418, 14)}, + [8] = {itemid = 1495, position = Position(33404, 32418, 14)} + }, + North = { + [1] = {itemid = 23659, position = Position(33407, 32414, 14)}, + [2] = {itemid = 23658, position = Position(33407, 32415, 14)}, + [3] = {itemid = 23660, position = Position(33407, 32416, 14)}, + [4] = {itemid = 23659, position = Position(33407, 32417, 14)}, + [5] = {itemid = 23660, position = Position(33407, 32418, 14)}, + [6] = {itemid = 1495, position = Position(33406, 32415, 14)}, + [7] = {itemid = 1495, position = Position(33406, 32416, 14)} + }, + East = { + [1] = {itemid = 23656, position = Position(33408, 32419, 14)}, + [2] = {itemid = 23657, position = Position(33409, 32419, 14)}, + [3] = {itemid = 23656, position = Position(33410, 32419, 14)}, + [4] = {itemid = 23655, position = Position(33411, 32419, 14)}, + [5] = {itemid = 23657, position = Position(33412, 32419, 14)}, + [6] = {itemid = 1495, position = Position(33408, 32418, 14)}, + [7] = {itemid = 1495, position = Position(33409, 32418, 14)} + }, + South = { + [1] = {itemid = 23659, position = Position(33407, 32420, 14)}, + [2] = {itemid = 23660, position = Position(33407, 32421, 14)}, + [3] = {itemid = 23659, position = Position(33407, 32422, 14)}, + [4] = {itemid = 23658, position = Position(33407, 32423, 14)}, + [5] = {itemid = 23660, position = Position(33407, 32424, 14)}, + [6] = {itemid = 1495, position = Position(33406, 32420, 14)}, + [7] = {itemid = 1495, position = Position(33406, 32421, 14)} + } +} + +local ferumbrasAscendantTheShattererLevers = Action() +function ferumbrasAscendantTheShattererLevers.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.FerumbrasAscension.TheShatterer) >= 1 then + player:sendCancelMessage('You cannot use this lever again.') + return true + end + if item.itemid == 9825 then + item:transform(9826) + if item:getPosition() == Position(33385, 32410, 14) then + for i = 1, #chains.West do + local chain = chains.West[i] + local bla = Tile(chain.position):getItemById(chain.itemid) + if bla then + bla:remove() + Game.createMonster("Fury", { x=player:getPosition().x+math.random(-3, 3), y=player:getPosition().y+math.random(-3, 3), z=player:getPosition().z }) + end + end + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.TheShattererLever, Game.getStorageValue(GlobalStorage.FerumbrasAscendant.TheShattererLever) + 1) + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.TheShattererLever) >= 4 then + local boss = Tile(Position(33406, 32418, 14)):getTopCreature() + if boss:getName():lower() == 'the shatterer' then + boss:teleportTo(Position(33400, 32415, 14)) + boss:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + end + elseif item:getPosition() == Position(33403, 32391, 14) then + for i = 1, #chains.North do + local chain = chains.North[i] + local bla = Tile(chain.position):getItemById(chain.itemid) + if bla then + bla:remove() + Game.createMonster("Destroyer", { x=player:getPosition().x+math.random(-3, 3), y=player:getPosition().y+math.random(-3, 3), z=player:getPosition().z }) + end + end + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.TheShattererLever, Game.getStorageValue(GlobalStorage.FerumbrasAscendant.TheShattererLever) + 1) + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.TheShattererLever) >= 4 then + local boss = Tile(Position(33406, 32418, 14)):getTopCreature() + if boss:getName():lower() == 'the shatterer' then + boss:teleportTo(Position(33400, 32415, 14)) + boss:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + end + elseif item:getPosition() == Position(33430, 32418, 14) then + for i = 1, #chains.East do + local chain = chains.East[i] + local bla = Tile(chain.position):getItemById(chain.itemid) + if bla then + bla:remove() + end + end + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.TheShattererLever, Game.getStorageValue(GlobalStorage.FerumbrasAscendant.TheShattererLever) + 1) + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.TheShattererLever) >= 4 then + local boss = Tile(Position(33406, 32418, 14)):getTopCreature() + if boss:getName():lower() == 'the shatterer' then + boss:teleportTo(Position(33400, 32415, 14)) + boss:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + end + elseif item:getPosition() == Position(33410, 32441, 14) then + for i = 1, #chains.South do + local chain = chains.South[i] + local bla = Tile(chain.position):getItemById(chain.itemid) + if bla then + bla:remove() + end + end + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.TheShattererLever, Game.getStorageValue(GlobalStorage.FerumbrasAscendant.TheShattererLever) + 1) + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.TheShattererLever) >= 4 then + local boss = Tile(Position(33406, 32418, 14)):getTopCreature() + if boss:getName():lower() == 'the shatterer' then + boss:teleportTo(Position(33400, 32415, 14)) + boss:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + end + end + player:say('CLICK', TALKTYPE_MONSTER_SAY, false, nil, toPosition) + elseif item.itemid == 9826 then + player:sendCancelMessage('Sorry, not possible.') + return true + end + return true +end + +ferumbrasAscendantTheShattererLevers:uid(1031,1032,1033,1034) +ferumbrasAscendantTheShattererLevers:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ferumbras_ascendant/zamulosh_lever.lua b/data/scripts/actions/quests/ferumbras_ascendant/zamulosh_lever.lua new file mode 100644 index 00000000000..ade66aff62e --- /dev/null +++ b/data/scripts/actions/quests/ferumbras_ascendant/zamulosh_lever.lua @@ -0,0 +1,54 @@ +local config = { + centerRoom = Position(33643, 32756, 11), + BossPosition = Position(33643, 32756, 11), + newPosition = Position(33644, 32760, 11), + zamuloshSummons = { + Position(33642, 32756, 11), + Position(33642, 32756, 11), + Position(33642, 32756, 11), + Position(33644, 32756, 11), + Position(33644, 32756, 11), + Position(33644, 32756, 11) + } +} + +local ferumbrasAscendantZamulosh = Action() +function ferumbrasAscendantZamulosh.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 9825 then + if player:getPosition() ~= Position(33680, 32741, 11) then + item:transform(9826) + return true + end + end + if item.itemid == 9825 then + local specs, spec = Game.getSpectators(config.centerRoom, false, false, 15, 15, 15, 15) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Someone is fighting with Zamulosh.") + return true + end + end + Game.createMonster("Zamulosh", config.BossPosition, true, true) + for d = 1, #config.zamuloshSummons do + Game.createMonster('Zamulosh3', config.zamuloshSummons[d], true, true) + end + for y = 32741, 32745 do + local playerTile = Tile(Position(33680, y, 11)):getTopCreature() + if playerTile and playerTile:isPlayer() then + playerTile:getPosition():sendMagicEffect(CONST_ME_POFF) + playerTile:teleportTo(config.newPosition) + playerTile:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.ZamuloshTimer, 1) + addEvent(clearForgotten, 30 * 60 * 1000, Position(33634, 32749, 11), Position(33654, 32765, 11), Position(33319, 32318, 13), GlobalStorage.FerumbrasAscendant.ZamuloshTimer) + item:transform(9826) + elseif item.itemid == 9826 then + item:transform(9825) + end + return true +end + +ferumbrasAscendantZamulosh:uid(1026) +ferumbrasAscendantZamulosh:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/first_dragon/lair_entrance.lua b/data/scripts/actions/quests/first_dragon/lair_entrance.lua new file mode 100644 index 00000000000..c795de708b1 --- /dev/null +++ b/data/scripts/actions/quests/first_dragon/lair_entrance.lua @@ -0,0 +1,22 @@ +local lairEntrance = Action() + +function lairEntrance.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.FirstDragon.AccessCave) <= 3 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are not worthy to enter in The First Dragon's Lair yet.") + return true + end + + if item:getPosition() == Position(33047, 32712, 3) then + player:teleportTo({x = 31994, y = 32391, z = 9}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + elseif item:getPosition() == Position(31994, 32390, 9) then + player:teleportTo({x = 33047, y = 32713, z = 3}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + return false +end + +lairEntrance:id(27828) +lairEntrance:register() diff --git a/data/scripts/actions/quests/first_dragon/lever.lua b/data/scripts/actions/quests/first_dragon/lever.lua new file mode 100644 index 00000000000..d6e52bd2990 --- /dev/null +++ b/data/scripts/actions/quests/first_dragon/lever.lua @@ -0,0 +1,131 @@ +local lever = Action() + +local setting = { + centerRoom = {x = 33616, y = 31022, z = 14}, + range = 10 +} + +local monsterPosition = { + {position = Position(33574, 31013, 14)}, + {position = Position(33592, 31013, 14)}, + {position = Position(33583, 31022, 14)}, + {position = Position(33574, 31031, 14)}, + {position = Position(33592, 31031, 14)} +} + +local playerPositions = { + Position(33582,30993,14), + Position(33583,30993,14), + Position(33584,30993,14), + Position(33582,30994,14), + Position(33583,30994,14), + Position(33584,30994,14), + Position(33582,30995,14), + Position(33583,30995,14), + Position(33584,30995,14), + Position(33582,30996,14), + Position(33583,30996,14), + Position(33584,30996,14), + Position(33582,30997,14), + Position(33583,30997,14), + Position(33584,30997,14) +} + +local config = { + toPosition1 = Position(33574, 31017, 14), + roomTile1 = { + {fromPosition = Position(33582, 30993, 14)}, + {fromPosition = Position(33583, 30993, 14)}, + {fromPosition = Position(33584, 30993, 14)}, + }, + toPosition2 = Position(33592, 31017, 14), + roomTile2 = { + {fromPosition = Position(33582, 30994, 14)}, + {fromPosition = Position(33583, 30994, 14)}, + {fromPosition = Position(33584, 30994, 14)}, + }, + toPosition3 = Position(33592, 31035, 14), + roomTile3 = { + {fromPosition = Position(33582, 30995, 14)}, + {fromPosition = Position(33583, 30995, 14)}, + {fromPosition = Position(33584, 30995, 14)}, + }, + toPosition4 = Position(33574, 31035, 14), + roomTile4 = { + {fromPosition = Position(33582, 30996, 14)}, + {fromPosition = Position(33583, 30996, 14)}, + {fromPosition = Position(33584, 30996, 14)}, + }, + toPosition5 = Position(33583, 31026, 14), + roomTile5 = { + {fromPosition = Position(33582, 30997, 14)}, + {fromPosition = Position(33583, 30997, 14)}, + {fromPosition = Position(33584, 30997, 14)}, + }, +} + +function lever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 9825 then + for i = 1, #playerPositions do + local creature = Tile(playerPositions[i]):getTopCreature() + if not creature then + item:transform(9826) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need 5 players to fight with this boss.") + return true + end + end + end + if item.itemid == 9825 then + if roomIsOccupied(setting.centerRoom, setting.range, setting.range) then + player:say("Someone is fighting against the boss! You need wait awhile.", TALKTYPE_MONSTER_SAY) + return true + end + + for d = 1, 5 do + Game.createMonster("unbeatable dragon", position(math.random(33610, 33622), math.random(31016, 31030), 14), true, true) + end + for b = 1, #monsterPosition do + Game.createMonster("fallen challenger", monsterPosition[b].position, true, true) + end + for i = 1, #playerPositions do + local creature = Tile(playerPositions[i]):getTopCreature() + if creature then + for i = 1, #config.roomTile1 do + local toRoom1 = Tile(config.roomTile1[i].fromPosition):getTopCreature() + if toRoom1 then + toRoom1:teleportTo(config.toPosition1) + end + local toRoom2 = Tile(config.roomTile2[i].fromPosition):getTopCreature() + if toRoom2 then + toRoom2:teleportTo(config.toPosition2) + end + local toRoom3 = Tile(config.roomTile3[i].fromPosition):getTopCreature() + if toRoom3 then + toRoom3:teleportTo(config.toPosition3) + end + local toRoom4 = Tile(config.roomTile4[i].fromPosition):getTopCreature() + if toRoom4 then + toRoom4:teleportTo(config.toPosition4) + end + local toRoom5 = Tile(config.roomTile5[i].fromPosition):getTopCreature() + if toRoom5 then + toRoom5:teleportTo(config.toPosition5) + end + end + creature:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + creature:setStorageValue(Storage.FirstDragon.FirstDragonTimer, os.time() + 20 * 3600) + creature:setStorageValue(Storage.FirstDragon.SomewhatBeatable, 0) + end + end + -- One hour for clean the room + addEvent(clearRoom, 60 * 60 * 1000, Position(33583, 31022, 14), 50, 50, fromPosition) + Game.createMonster("spirit of fertility", Position(33625, 31021, 14), true, true) + item:transform(9826) + elseif item.itemid == 9826 then + item:transform(9825) + end + return true +end + +lever:uid(30003) +lever:register() diff --git a/data/scripts/actions/quests/first_dragon/rewards.lua b/data/scripts/actions/quests/first_dragon/rewards.lua new file mode 100644 index 00000000000..8c01d1f1d48 --- /dev/null +++ b/data/scripts/actions/quests/first_dragon/rewards.lua @@ -0,0 +1,69 @@ +local bpItems = { + {name = 'ancient coin', count = 1}, + {name = 'draken sulphur', count = 1}, + {name = 'seacrest hair', count = 2}, + {name = 'mystical hourglass', count = 2}, + {name = 'gold token', count = 3}, + {name = 'blue gem', count = 1}, + {name = 'yellow gem', count = 1}, + {name = 'red gem', count = 1}, + {name = 'demon horn', count = 2}, + {name = 'slime heart', count = 2}, + {name = 'energy vein', count = 2}, + {name = 'petrified scream', count = 2}, + {name = 'brimstone shell', count = 2}, + {name = 'deepling wart', count = 2}, + {name = 'wyrm scale', count = 2}, + {name = 'hellspawn tail', count = 2} +} + +local chests = { + [14021] = { + name = "porcelain mask", + count = 1 + }, + [14022] = { + name = "backpack", + count = 1 + }, + [14023] = { + name = "colourful feathers", + count = 3 + } +} + +local finalReward = Action() +function finalReward.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local setting = chests[item.uid] + if not setting then + return true + end + if item.uid == 14021 and player:getStorageValue(Storage.FirstDragon.RewardFeather) < os.time() then + player:addItem(setting.name, setting.count, true) + player:setStorageValue(Storage.FirstDragon.RewardFeather, os.time() + 24 * 3600) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You found ' ..setting.count.. ' ' ..setting.name..'.') + elseif item.uid == 14022 and player:getStorageValue(Storage.FirstDragon.RewardBackpack) < os.time() then + local bp = Game.createItem('Backpack', 1) + if bp then + for i = 1, #bpItems do + bp:addItem(bpItems[i].name, count) + end + bp:moveTo(player) + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You found a backpack.') + player:setStorageValue(Storage.FirstDragon.RewardBackpack, os.time() + 60 * 60 * 365 * 24) + elseif item.uid == 14023 and player:getStorageValue(Storage.FirstDragon.RewardMask) < os.time() then + player:addItem(setting.name, setting.count, true) + player:setStorageValue(Storage.FirstDragon.RewardMask, os.time() + 60 * 60 * 5 * 24) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You found ' ..setting.count.. ' ' ..setting.name..'.') + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The ' ..getItemName(setting.itemId).. ' is empty.') + end + return true +end + +for uniqueRange = 14021, 14023 do + finalReward:uid(uniqueRange) +end + +finalReward:register() diff --git a/data/scripts/actions/quests/first_dragon/sacrifice_items.lua b/data/scripts/actions/quests/first_dragon/sacrifice_items.lua new file mode 100644 index 00000000000..a679a5fce33 --- /dev/null +++ b/data/scripts/actions/quests/first_dragon/sacrifice_items.lua @@ -0,0 +1,47 @@ +local sacrificeItems = Action() + +local config = { + [27607] = {storage = Storage.FirstDragon.Scale}, + [27608] = {storage = Storage.FirstDragon.Tooth}, + [27609] = {storage = Storage.FirstDragon.Horn}, + [27610] = {storage = Storage.FirstDragon.Bones} +} + +function sacrificeItems.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local setting = config[item.itemid] + if not setting then + return true + end + + if player:getStorageValue(setting.storage) >= 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You already sacrificed this item to pass.") + return true + end + + if player:getStorageValue(Storage.FirstDragon.AccessCave) >= 4 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You\'re plunging " ..item:getName().. " into the lava. You are now worthy to enter The First Dragon's Lair. Touch the lava pool again.") + return true + end + + if player:getStorageValue(Storage.FirstDragon.AccessCave) < 0 then + player:setStorageValue(Storage.FirstDragon.AccessCave, 0) + end + local targetPosition = Position(33047, 32712, 3) + if (toPosition == targetPosition) then + local targetId = Tile(targetPosition):getItemById(27828) + if targetId then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You're plunging " ..item:getName().. " into the lava.") + player:setStorageValue(Storage.FirstDragon.AccessCave, player:getStorageValue(Storage.FirstDragon.AccessCave) + 1) + player:setStorageValue(setting.storage, 1) + item:remove(1) + return true + end + end + return false +end + +for value = 27607, 27610 do + sacrificeItems:id(value) +end + +sacrificeItems:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/first_dragon/treasure_chest.lua b/data/scripts/actions/quests/first_dragon/treasure_chest.lua new file mode 100644 index 00000000000..bb863ceed92 --- /dev/null +++ b/data/scripts/actions/quests/first_dragon/treasure_chest.lua @@ -0,0 +1,112 @@ +local UniqueTable = { + [14001] = { + name = "giant shimmering pearl", + count = 1 + }, + [14002] = { + name = "gold nugget", + count = 2 + }, + [14003] = { + name = "blue crystal shard", + count = 1 + }, + [14004] = { + name = "violet crystal shard", + count = 1 + }, + [14005] = { + name = "green crystal splinter", + count = 2 + }, + [14006] = { + name = "red gem", + count = 1 + }, + [14007] = { + name = "onyx chip", + count = 3 + }, + [14008] = { + name = "platinum coin", + count = 3 + }, + [14009] = { + name = "red crystal fragment", + count = 2 + }, + [14010] = { + name = "yellow gem", + count = 1 + }, + [14011] = { + name = "talon", + count = 3 + }, + [14012] = { + name = "white pearl", + count = 2 + }, + [14013] = { + name = "gold ingot", + count = 1 + }, + [14014] = { + name = "opal", + count = 3 + }, + [14015] = { + name = "small diamond", + count = 2 + }, + [14016] = { + name = "green crystal shard", + count = 1 + }, + [14017] = { + name = "black pearl", + count = 3 + }, + [14018] = { + name = "emerald bangle", + count = 1 + }, + [14019] = { + name = "green gem", + count = 1 + }, + [14020] = { + name = "giant shimmering pearl", + count = 1 + } +} + +local treasureChest = Action() +function treasureChest.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local setting = UniqueTable[item.uid] + if not setting then + return true + end + if player:getStorageValue(item.uid) >= 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The ' .. getItemName(setting.itemId) .. ' is empty.') + return true + end + if player:getStorageValue(Storage.FirstDragon.ChestCounter) >= 19 then + player:addAchievement('Treasure Hunter') + player:addItem(setting.name, setting.count, true) + player:setStorageValue(item.uid, 1) + player:setStorageValue(Storage.FirstDragon.ChestCounter, player:getStorageValue(Storage.FirstDragon.ChestCounter) + 1) + return true + end + player:addItem(setting.name, setting.count, true) + player:setStorageValue(item.uid, 1) + player:setStorageValue(Storage.FirstDragon.ChestCounter, player:getStorageValue(Storage.FirstDragon.ChestCounter) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You found ' ..setting.count.. ' ' ..setting.name..'.') + return true +end + +for index, value in pairs(UniqueTable) do + treasureChest:uid(index) +end + +treasureChest:register() diff --git a/data/scripts/actions/quests/forgotten_knowledge/bird_cage.lua b/data/scripts/actions/quests/forgotten_knowledge/bird_cage.lua new file mode 100644 index 00000000000..421cba97df7 --- /dev/null +++ b/data/scripts/actions/quests/forgotten_knowledge/bird_cage.lua @@ -0,0 +1,28 @@ +local forgottenKnowledgeBird = Action() +function forgottenKnowledgeBird.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 26480 then + if target:getName():lower() ~= 'cave parrot' then + return false + end + target:getPosition():sendMagicEffect(CONST_ME_POFF) + target:remove() + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The cave parrot may be tough but he somehow couldn\'t resist this particular birdcage. Or maybe it was you...') + item:transform(26481) + return true + elseif item.itemid == 26481 then + if player:getPosition() ~= Position(32737, 32117, 10) then + return false + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You open the cage and let the cave parrot roam free!') + item:transform(26480) + if player:getStorageValue(Storage.ForgottenKnowledge.BirdCounter) < 0 then + player:setStorageValue(Storage.ForgottenKnowledge.BirdCounter, 0) + end + player:setStorageValue(Storage.ForgottenKnowledge.BirdCounter, player:getStorageValue(Storage.ForgottenKnowledge.BirdCounter) + 1) + end + player:getPosition():sendMagicEffect(CONST_ME_HEARTS) + return true +end + +forgottenKnowledgeBird:id(26480,26481) +forgottenKnowledgeBird:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/forgotten_knowledge/dragonking_lever.lua b/data/scripts/actions/quests/forgotten_knowledge/dragonking_lever.lua new file mode 100644 index 00000000000..7d17d70b9e6 --- /dev/null +++ b/data/scripts/actions/quests/forgotten_knowledge/dragonking_lever.lua @@ -0,0 +1,61 @@ +local config = { + bossPosition = Position(33357, 31182, 10), + newPosition = Position(33359, 31186, 10), + soulPosition = Position(33359, 31182, 12) +} + +local monsters = { + {position = Position(33352, 31187, 10)}, + {position = Position(33363, 31187, 10)}, + {position = Position(33353, 31176, 10)}, + {position = Position(33363, 31176, 10)} +} + +local forgottenKnowledgeDragonking = Action() +function forgottenKnowledgeDragonking.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 9825 then + if player:getPosition() ~= Position(33391, 31178, 10) then + item:transform(9826) + return true + end + end + if item.itemid == 9825 then + for v = 10, 12 do + local specs, spec = Game.getSpectators(Position(33357, 31182, v), false, false, 15, 15, 15, 15) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Someone is fighting with Dragonking Zyrtarch.") + return true + end + end + end + for d = 1, #monsters do + Game.createMonster('soulcatcher', monsters[d].position, true, true) + end + Game.createMonster("dragonking zyrtarch", config.bossPosition, true, true) + Game.createMonster("soul of dragonking zyrtarch", config.soulPosition, true, true) + for y = 31178, 31182 do + local playerTile = Tile(Position(33391, y, 10)):getTopCreature() + if playerTile and playerTile:isPlayer() then + if playerTile:getStorageValue(Storage.ForgottenKnowledge.DragonkingTimer) < os.time() then + playerTile:getPosition():sendMagicEffect(CONST_ME_POFF) + playerTile:teleportTo(config.newPosition) + playerTile:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + playerTile:setStorageValue(Storage.ForgottenKnowledge.DragonkingTimer, os.time() + 20 * 3600) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need to wait a while, recently someone challenge Frozen Horror.") + return true + end + end + end + addEvent(clearForgotten, 30 * 60 * 1000, Position(33348, 31172, 10), Position(33368, 31190, 12), Position(33407, 31172, 10)) + item:transform(9826) + elseif item.itemid == 9826 then + item:transform(9825) + end + return true +end + +forgottenKnowledgeDragonking:aid(24880) +forgottenKnowledgeDragonking:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/forgotten_knowledge/fount.lua b/data/scripts/actions/quests/forgotten_knowledge/fount.lua new file mode 100644 index 00000000000..403f276b649 --- /dev/null +++ b/data/scripts/actions/quests/forgotten_knowledge/fount.lua @@ -0,0 +1,13 @@ +local forgottenKnowledgeFount = Action() +function forgottenKnowledgeFount.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.ForgottenKnowledge.Phial) >= 1 then + return false + end + player:addItem(26478) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'A phial of fresh pond water. It looks crystal clear and sparkles a little.') + player:setStorageValue(Storage.ForgottenKnowledge.Phial, 1) + return true +end + +forgottenKnowledgeFount:id(27803,27804,27805,27806) +forgottenKnowledgeFount:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/forgotten_knowledge/girl_picture.lua b/data/scripts/actions/quests/forgotten_knowledge/girl_picture.lua new file mode 100644 index 00000000000..1f32184bd52 --- /dev/null +++ b/data/scripts/actions/quests/forgotten_knowledge/girl_picture.lua @@ -0,0 +1,13 @@ +local forgottenKnowledgeGirl = Action() +function forgottenKnowledgeGirl.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.ForgottenKnowledge.GirlPicture) >= 1 then + return false + end + player:setStorageValue(Storage.ForgottenKnowledge.GirlPicture, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Seems that an old silver key appears in the drower.') + item:remove() + return true +end + +forgottenKnowledgeGirl:id(26400) +forgottenKnowledgeGirl:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/forgotten_knowledge/horror_lever.lua b/data/scripts/actions/quests/forgotten_knowledge/horror_lever.lua new file mode 100644 index 00000000000..12a2a9ceea0 --- /dev/null +++ b/data/scripts/actions/quests/forgotten_knowledge/horror_lever.lua @@ -0,0 +1,58 @@ +local config = { + centerRoom = Position(32269, 31091, 14), + bossPosition = Position(32269, 31091, 14), + newPosition = Position(32271, 31097, 14) +} + +local monsters = { + {monster = 'icicle', pos = Position(32266, 31084, 14)}, + {monster = 'icicle', pos = Position(32272, 31084, 14)}, + {monster = 'dragon egg', pos = Position(32269, 31084, 14)}, + {monster = 'melting frozen horror', pos = Position(32267, 31071, 14)} +} + +local forgottenKnowledgeHorror = Action() +function forgottenKnowledgeHorror.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 9825 then + if player:getPosition() ~= Position(32302, 31088, 14) then + item:transform(9826) + return true + end + end + if item.itemid == 9825 then + local specs, spec = Game.getSpectators(config.centerRoom, false, false, 15, 15, 15, 15) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Someone is fighting with Frozen Horror.") + return true + end + end + for n = 1, #monsters do + Game.createMonster(monsters[n].monster, monsters[n].pos, true, true) + end + Game.createMonster("solid frozen horror", config.bossPosition, true, true) + for y = 31088, 31092 do + local playerTile = Tile(Position(32302, y, 14)):getTopCreature() + if playerTile and playerTile:isPlayer() then + if playerTile:getStorageValue(Storage.ForgottenKnowledge.HorrorTimer) < os.time() then + playerTile:getPosition():sendMagicEffect(CONST_ME_POFF) + playerTile:teleportTo(config.newPosition) + playerTile:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + playerTile:setStorageValue(Storage.ForgottenKnowledge.HorrorTimer, os.time() + 20 * 3600) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need to wait a while, recently someone challenge Frozen Horror.") + return true + end + end + end + addEvent(clearForgotten, 30 * 60 * 1000, Position(32264, 31070, 14), Position(32284, 31104, 14), Position(32319, 31091, 14)) + item:transform(9826) + elseif item.itemid == 9826 then + item:transform(9825) + end + return true +end + +forgottenKnowledgeHorror:aid(24882) +forgottenKnowledgeHorror:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/forgotten_knowledge/lantern.lua b/data/scripts/actions/quests/forgotten_knowledge/lantern.lua new file mode 100644 index 00000000000..7c9f5c7f47d --- /dev/null +++ b/data/scripts/actions/quests/forgotten_knowledge/lantern.lua @@ -0,0 +1,33 @@ +local config = { + [26402] = {transformId = 26406}, + [26406] = {transformId = 26402} +} + +local forgottenKnowledgeLantern = Action() +function forgottenKnowledgeLantern.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local lantern = config[item.itemid] + if not lantern then + return true + end + + if not player:getStorageValue(26402) == 1 then + return false + end + if item:getId() == 26402 then + player:getPosition():sendMagicEffect(CONST_ME_ENERGYAREA) + local msg = 'As you start polishing the lantern it begins to glow in an otherworldly light.' + if player:getPosition():getDistance(Position(32891, 31619, 10)) < 2 then + if not player:getItemById(26401, true) then + msg = 'In the light of the ghostsilver lantern you discover an otherwise invisible door. But you lack the key to open it.' + else + msg = 'In the light of the ghostsilver lantern you discover an otherwise invisible door. As you have the fitting key you can pass.' + end + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, msg) + end + item:transform(lantern.transformId) + return true +end + +forgottenKnowledgeLantern:id(26402,26406) +forgottenKnowledgeLantern:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/forgotten_knowledge/last_lore_lever.lua b/data/scripts/actions/quests/forgotten_knowledge/last_lore_lever.lua new file mode 100644 index 00000000000..d65cc558cea --- /dev/null +++ b/data/scripts/actions/quests/forgotten_knowledge/last_lore_lever.lua @@ -0,0 +1,60 @@ +local config = { + {newPosition = Position(31985, 32851, 14)}, + {pos = Position(31986, 32840, 14), monster = 'a shielded astral glyph'}, + {pos = Position(31975, 32856, 15), monster = 'bound astral power'}, + {pos = Position(31987, 32839, 14), monster = 'the astral source'}, + {pos = Position(31986, 32823, 15), monster = 'the distorted astral source'}, + {pos = Position(31989, 32823, 15), monster = 'an astral glyph'} +} + +local forgottenKnowledgeLastLore = Action() +function forgottenKnowledgeLastLore.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 9825 then + if player:getPosition() ~= Position(32019, 32844, 14) then + item:transform(9826) + return true + end + end + if item.itemid == 9825 then + for xx = 14, 15 do + local spectators = Game.getSpectators(Position(31986, 32846, xx), false, false, 21, 21, 21, 21) + for i = 1, #spectators do + spec = spectators[i] + if spec:isPlayer() then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Someone is fighting with The Last Lore Keeper.") + return true + end + end + end + for x = 32018, 32020 do + for y = 32844, 32848 do + local playerTile = Tile(Position(x, y, 14)):getTopCreature() + if playerTile and playerTile:isPlayer() then + if playerTile:getStorageValue(Storage.ForgottenKnowledge.LastLoreTimer) < os.time() then + playerTile:getPosition():sendMagicEffect(CONST_ME_POFF) + playerTile:teleportTo(config[1].newPosition) + playerTile:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + playerTile:setStorageValue(Storage.ForgottenKnowledge.LastLoreTimer, os.time() + 60 * 60 * 14 * 24) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need to wait a while, recently someone challenge The Last Lore Keeper.") + return true + end + end + end + end + for b = 2, #config do + Game.createMonster(config[b].monster, config[b].pos, true, true) + end + Game.setStorageValue(GlobalStorage.ForgottenKnowledge.AstralPowerCounter, 1) + Game.setStorageValue(GlobalStorage.ForgottenKnowledge.AstralGlyph, 0) + player:say('The Astral Glyph begins to draw upon bound astral power to expel you from the room!', TALKTYPE_MONSTER_SAY) + addEvent(clearForgotten, 30 * 60 * 1000, Position(31968, 32821, 14), Position(32004, 32865, 15), Position(32035, 32859, 14)) + item:transform(9826) + elseif item.itemid == 9826 then + item:transform(9825) + end + return true +end + +forgottenKnowledgeLastLore:aid(24884) +forgottenKnowledgeLastLore:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/forgotten_knowledge/lloyd_lever.lua b/data/scripts/actions/quests/forgotten_knowledge/lloyd_lever.lua new file mode 100644 index 00000000000..81e5358dc04 --- /dev/null +++ b/data/scripts/actions/quests/forgotten_knowledge/lloyd_lever.lua @@ -0,0 +1,72 @@ +local config = { + centerRoom = Position(32799, 32832, 14), + bossPosition = Position(32799, 32827, 14), + newPosition = Position(32800, 32831, 14) +} + +local monsters = { + {cosmic = 'cosmic energy prism a', pos = Position(32801, 32827, 14)}, + {cosmic = 'cosmic energy prism b', pos = Position(32798, 32827, 14)}, + {cosmic = 'cosmic energy prism c', pos = Position(32803, 32826, 14)}, + {cosmic = 'cosmic energy prism d', pos = Position(32796, 32826, 14)} +} + +local function clearForgottenLloyd() + local spectators = Game.getSpectators(config.centerRoom, false, false, 15, 15, 15, 15) + for i = 1, #spectators do + local spectator = spectators[i] + if spectator:isPlayer() then + spectator:teleportTo(Position(32815, 32873, 13)) + spectator:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + spectator:say('Time out! You were teleported out by strange forces.', TALKTYPE_MONSTER_SAY) + elseif spectator:isMonster() then + spectator:remove() + end + end +end + +local forgottenKnowledgeLever = Action() +function forgottenKnowledgeLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 9825 then + if player:getPosition() ~= Position(32759, 32868, 14) then + item:transform(9826) + return true + end + end + if item.itemid == 9825 then + local specs, spec = Game.getSpectators(config.centerRoom, false, false, 15, 15, 15, 15) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Someone is fighting with Lloyd.") + return true + end + end + for n = 1, #monsters do + Game.createMonster(monsters[n].cosmic, monsters[n].pos, true, true) + end + Game.createMonster("lloyd", config.bossPosition, true, true) + for y = 32868, 32872 do + local playerTile = Tile(Position(32759, y, 14)):getTopCreature() + if playerTile and playerTile:isPlayer() then + if playerTile:getStorageValue(Storage.ForgottenKnowledge.LloydTimer) < os.time() then + playerTile:getPosition():sendMagicEffect(CONST_ME_POFF) + playerTile:teleportTo(config.newPosition) + playerTile:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + playerTile:setStorageValue(Storage.ForgottenKnowledge.LloydTimer, os.time() + 20 * 3600) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need to wait a while, recently someone challenge Lloyd.") + return true + end + end + end + addEvent(clearForgottenLloyd, 30 * 60 * 1000) + item:transform(9826) + elseif item.itemid == 9826 then + item:transform(9825) + end + return true +end + +forgottenKnowledgeLever:aid(24881) +forgottenKnowledgeLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/forgotten_knowledge/lost_time.lua b/data/scripts/actions/quests/forgotten_knowledge/lost_time.lua new file mode 100644 index 00000000000..a2d49dea93c --- /dev/null +++ b/data/scripts/actions/quests/forgotten_knowledge/lost_time.lua @@ -0,0 +1,14 @@ +local forgottenKnowledgeLostTime = Action() +function forgottenKnowledgeLostTime.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target:getName():lower() ~= 'time waster' then + return false + end + target:getPosition():sendMagicEffect(CONST_ME_POFF) + target:remove() + item:remove() + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The time waster hungrily consumes the time and vanishes.') + return true +end + +forgottenKnowledgeLostTime:id(26397) +forgottenKnowledgeLostTime:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/forgotten_knowledge/old_desk.lua b/data/scripts/actions/quests/forgotten_knowledge/old_desk.lua new file mode 100644 index 00000000000..46c0d24ba73 --- /dev/null +++ b/data/scripts/actions/quests/forgotten_knowledge/old_desk.lua @@ -0,0 +1,24 @@ +local forgottenKnowledgeOldDesk = Action() +function forgottenKnowledgeOldDesk.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.ForgottenKnowledge.SilverKey) >= 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You already get an old silver key.') + return true + end + if player:getStorageValue(Storage.ForgottenKnowledge.GirlPicture) >= 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You find an old silver key inside of the drower.') + player:addItem(26401, true, true) + player:setStorageValue(Storage.ForgottenKnowledge.SilverKey, 1) + return true + end + if player:getStorageValue(Storage.ForgottenKnowledge.OldDesk) >= 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You already get an old note.') + return true + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'As you open the drower a ghostly apparition shortly appears hovering over the desk. You find an old note inside of the drower.') + player:addItem(26399, true, true) + player:setStorageValue(Storage.ForgottenKnowledge.OldDesk, 1) + return true +end + +forgottenKnowledgeOldDesk:aid(24875) +forgottenKnowledgeOldDesk:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/forgotten_knowledge/plant.lua b/data/scripts/actions/quests/forgotten_knowledge/plant.lua new file mode 100644 index 00000000000..93ab0e04186 --- /dev/null +++ b/data/scripts/actions/quests/forgotten_knowledge/plant.lua @@ -0,0 +1,509 @@ +local config = { + fromPosition = Position(32731, 32108, 11), + toPosition = Position(32745, 32121, 11) +} + +local items = { + {itemid = 17727, position = Position(32732, 32113, 11)}, + {itemid = 9043, position = Position(32732,32113, 11)}, + {itemid = 17720, position = Position(32732, 32114, 11)}, + {itemid = 9043, position = Position(32732,32114, 11)}, + {itemid = 17898, position = Position(32732, 32115, 11)}, + {itemid = 9043, position = Position(32732,32115, 11)}, + {itemid = 17727, position = Position(32733, 32111, 11)}, + {itemid = 9043, position = Position(32733,32111, 11)}, + {itemid = 17720, position = Position(32733, 32112, 11)}, + {itemid = 9043, position = Position(32733,32112, 11)}, + {itemid = 17724, position = Position(32733, 32113, 11)}, + {itemid = 9043, position = Position(32733,32113, 11)}, + {itemid = 8313, position = Position(32733, 32114, 11)}, + {itemid = 9043, position = Position(32733,32114, 11)}, + {itemid = 17725, position = Position(32733, 32115, 11)}, + {itemid = 9043, position = Position(32733,32115, 11)}, + {itemid = 17898, position = Position(32733, 32116, 11)}, + {itemid = 9043, position = Position(32733,32116, 11)}, + {itemid = 17727, position = Position(32734, 32110, 11)}, + {itemid = 9043, position = Position(32734,32110, 11)}, + {itemid = 17724, position = Position(32734, 32111, 11)}, + {itemid = 9043, position = Position(32734,32111, 11)}, + {itemid = 3611, position = Position(32734, 32112, 11)}, + {itemid = 3611, position = Position(32734, 32112, 11)}, + {itemid = 6217, position = Position(32734, 32112, 11)}, + {itemid = 9043, position = Position(32734,32112, 11)}, + {itemid = 2712, position = Position(32734, 32113, 11)}, + {itemid = 9043, position = Position(32734,32113, 11)}, + {itemid = 9043, position = Position(32734,32114, 11)}, + {itemid = 6217, position = Position(32734, 32115, 11)}, + {itemid = 9043, position = Position(32734,32115, 11)}, + {itemid = 17725, position = Position(32734, 32116, 11)}, + {itemid = 9043, position = Position(32734,32116, 11)}, + {itemid = 17720, position = Position(32734, 32117, 11)}, + {itemid = 9043, position = Position(32734,32117, 11)}, + {itemid = 6217, position = Position(32734, 32118, 11)}, + {itemid = 17898, position = Position(32734, 32118, 11)}, + {itemid = 9043, position = Position(32734,32118, 11)}, + {itemid = 17843, position = Position(32735, 32110, 11)}, + {itemid = 9043, position = Position(32735,32110, 11)}, + {itemid = 9043, position = Position(32735,32111, 11)}, + {itemid = 6217, position = Position(32735, 32112, 11)}, + {itemid = 2702, position = Position(32735, 32112, 11)}, + {itemid = 9043, position = Position(32735,32112, 11)}, + {itemid = 6217, position = Position(32735, 32113, 11)}, + {itemid = 17701, position = Position(32735, 32113, 11)}, + {itemid = 9043, position = Position(32735,32113, 11)}, + {itemid = 6217, position = Position(32735, 32114, 11)}, + {itemid = 17685, position = Position(32735, 32114, 11)}, + {itemid = 9043, position = Position(32735,32114, 11)}, + {itemid = 2705, position = Position(32735, 32115, 11)}, + {itemid = 9043, position = Position(32735,32115, 11)}, + {itemid = 6217, position = Position(32735, 32116, 11)}, + {itemid = 9043, position = Position(32735,32116, 11)}, + {itemid = 2707, position = Position(32735, 32117, 11)}, + {itemid = 9043, position = Position(32735,32117, 11)}, + {itemid = 17725, position = Position(32735, 32118, 11)}, + {itemid = 9043, position = Position(32735,32118, 11)}, + {itemid = 6217, position = Position(32735, 32119, 11)}, + {itemid = 17898, position = Position(32735, 32119, 11)}, + {itemid = 9043, position = Position(32735,32119, 11)}, + {itemid = 17727, position = Position(32736, 32109, 11)}, + {itemid = 9043, position = Position(32736,32108, 11)}, + {itemid = 17724, position = Position(32736, 32110, 11)}, + {itemid = 9043, position = Position(32736,32110, 11)}, + {itemid = 6217, position = Position(32736, 32111, 11)}, + {itemid = 9043, position = Position(32736,32111, 11)}, + {itemid = 6217, position = Position(32736, 32112, 11)}, + {itemid = 17701, position = Position(32736, 32112, 11)}, + {itemid = 9043, position = Position(32736,32112, 11)}, + {itemid = 17933, position = Position(32736, 32113, 11)}, + {itemid = 9043, position = Position(32736,32113, 11)}, + {itemid = 6217, position = Position(32736, 32115, 11)}, + {itemid = 17842, position = Position(32736, 32115, 11)}, + {itemid = 9043, position = Position(32736,32115, 11)}, + {itemid = 6217, position = Position(32736, 32116, 11)}, + {itemid = 17685, position = Position(32736, 32116, 11)}, + {itemid = 9043, position = Position(32736,32116, 11)}, + {itemid = 6217, position = Position(32736, 32117, 11)}, + {itemid = 17685, position = Position(32736, 32117, 11)}, + {itemid = 9043, position = Position(32736,32117, 11)}, + {itemid = 6217, position = Position(32736, 32118, 11)}, + {itemid = 17685, position = Position(32736, 32118, 11)}, + {itemid = 9043, position = Position(32736,32118, 11)}, + {itemid = 6217, position = Position(32736, 32119, 11)}, + {itemid = 17933, position = Position(32736, 32119, 11)}, + {itemid = 9043, position = Position(32736,32119, 11)}, + {itemid = 17842, position = Position(32737, 32109, 11)}, + {itemid = 9043, position = Position(32737,32108, 11)}, + {itemid = 17726, position = Position(32737, 32110, 11)}, + {itemid = 9043, position = Position(32737,32110, 11)}, + {itemid = 6217, position = Position(32737, 32111, 11)}, + {itemid = 9043, position = Position(32737,32111, 11)}, + {itemid = 6217, position = Position(32737, 32112, 11)}, + {itemid = 17694, position = Position(32737, 32112, 11)}, + {itemid = 9043, position = Position(32737,32112, 11)}, + {itemid = 17694, position = Position(32737, 32119, 11)}, + {itemid = 17894, position = Position(32737,32119, 11)}, + {itemid = 17843, position = Position(32738, 32110, 11)}, + {itemid = 9043, position = Position(32738,32110, 11)}, + {itemid = 2711, position = Position(32738, 32111, 11)}, + {itemid = 9043, position = Position(32738,32111, 11)}, + {itemid = 17725, position = Position(32738, 32112, 11)}, + {itemid = 9043, position = Position(32738,32112, 11)}, + {itemid = 17898, position = Position(32738, 32113, 11)}, + {itemid = 9043, position = Position(32738,32113, 11)}, + {itemid = 6150, position = Position(32738, 32115, 11)}, + {itemid = 9043, position = Position(32738,32115, 11)}, + {itemid = 17720, position = Position(32738, 32116, 11)}, + {itemid = 9043, position = Position(32738,32116, 11)}, + {itemid = 17720, position = Position(32738, 32117, 11)}, + {itemid = 9043, position = Position(32738,32117, 11)}, + {itemid = 17720, position = Position(32738, 32118, 11)}, + {itemid = 9043, position = Position(32738,32118, 11)}, + {itemid = 6217, position = Position(32738, 32119, 11)}, + {itemid = 17898, position = Position(32738, 32119, 11)}, + {itemid = 9043, position = Position(32738,32119, 11)}, + {itemid = 17842, position = Position(32739, 32110, 11)}, + {itemid = 9043, position = Position(32739,32110, 11)}, + {itemid = 17726, position = Position(32739, 32111, 11)}, + {itemid = 9043, position = Position(32739,32111, 11)}, + {itemid = 6217, position = Position(32739, 32112, 11)}, + {itemid = 9043, position = Position(32739,32112, 11)}, + {itemid = 17725, position = Position(32739, 32113, 11)}, + {itemid = 9043, position = Position(32739,32113, 11)}, + {itemid = 17720, position = Position(32739, 32114, 11)}, + {itemid = 9043, position = Position(32739,32114, 11)}, + {itemid = 6180, position = Position(32739, 32115, 11)}, + {itemid = 17724, position = Position(32739, 32115, 11)}, + {itemid = 9043, position = Position(32739,32115, 11)}, + {itemid = 6181, position = Position(32739, 32116, 11)}, + {itemid = 6217, position = Position(32739, 32116, 11)}, + {itemid = 9043, position = Position(32739,32116, 11)}, + {itemid = 6217, position = Position(32739, 32117, 11)}, + {itemid = 9043, position = Position(32739,32117, 11)}, + {itemid = 2708, position = Position(32739, 32118, 11)}, + {itemid = 9043, position = Position(32739,32118, 11)}, + {itemid = 6217, position = Position(32739, 32119, 11)}, + {itemid = 17694, position = Position(32739, 32119, 11)}, + {itemid = 9043, position = Position(32739,32119, 11)}, + {itemid = 17842, position = Position(32740, 32111, 11)}, + {itemid = 9043, position = Position(32740,32111, 11)}, + {itemid = 17726, position = Position(32740, 32112, 11)}, + {itemid = 9043, position = Position(32740,32112, 11)}, + {itemid = 6217, position = Position(32740, 32113, 11)}, + {itemid = 9043, position = Position(32740,32113, 11)}, + {itemid = 2703, position = Position(32740, 32114, 11)}, + {itemid = 9043, position = Position(32740,32114, 11)}, + {itemid = 6217, position = Position(32740, 32115, 11)}, + {itemid = 9043, position = Position(32740,32115, 11)}, + {itemid = 6217, position = Position(32740, 32116, 11)}, + {itemid = 9043, position = Position(32740,32116, 11)}, + {itemid = 9043, position = Position(32740,32117, 11)}, + {itemid = 6217, position = Position(32740, 32118, 11)}, + {itemid = 17701, position = Position(32740, 32118, 11)}, + {itemid = 9043, position = Position(32740,32118, 11)}, + {itemid = 6217, position = Position(32740, 32119, 11)}, + {itemid = 17933, position = Position(32740, 32119, 11)}, + {itemid = 9043, position = Position(32740,32119, 11)}, + {itemid = 17842, position = Position(32741, 32112, 11)}, + {itemid = 9043, position = Position(32741,32112, 11)}, + {itemid = 17726, position = Position(32741, 32113, 11)}, + {itemid = 9043, position = Position(32741,32113, 11)}, + {itemid = 6217, position = Position(32741, 32114, 11)}, + {itemid = 9043, position = Position(32741,32114, 11)}, + {itemid = 6217, position = Position(32741, 32115, 11)}, + {itemid = 9043, position = Position(32741,32115, 11)}, + {itemid = 9043, position = Position(32741,32116, 11)}, + {itemid = 6217, position = Position(32741, 32117, 11)}, + {itemid = 17701, position = Position(32741, 32117, 11)}, + {itemid = 9043, position = Position(32741,32117, 11)}, + {itemid = 6217, position = Position(32741, 32118, 11)}, + {itemid = 17933, position = Position(32741, 32118, 11)}, + {itemid = 9043, position = Position(32741,32118, 11)}, + {itemid = 6217, position = Position(32742, 32113, 11)}, + {itemid = 17842, position = Position(32742, 32113, 11)}, + {itemid = 9043, position = Position(32742,32113, 11)}, + {itemid = 6217, position = Position(32742, 32114, 11)}, + {itemid = 17685, position = Position(32742, 32114, 11)}, + {itemid = 9043, position = Position(32742,32114, 11)}, + {itemid = 17726, position = Position(32742, 32115, 11)}, + {itemid = 9043, position = Position(32742,32115, 11)}, + {itemid = 6217, position = Position(32742, 32116, 11)}, + {itemid = 17701, position = Position(32742, 32116, 11)}, + {itemid = 9043, position = Position(32742,32116, 11)}, + {itemid = 6217, position = Position(32742, 32117, 11)}, + {itemid = 17933, position = Position(32742, 32117, 11)}, + {itemid = 9043, position = Position(32742,32117, 11)}, + {itemid = 17842, position = Position(32743, 32115, 11)}, + {itemid = 9043, position = Position(32743,32115, 11)}, + {itemid = 6217, position = Position(32743, 32116, 11)}, + {itemid = 17933, position = Position(32743, 32116, 11)}, + {itemid = 9043, position = Position(32743,32116, 11)} +} + +local dry = { + {itemid = 17727, position = Position(32732, 32113, 11)}, + {itemid = 11561, position = Position(32732,32113, 11)}, + {itemid = 17720, position = Position(32732, 32114, 11)}, + {itemid = 11561, position = Position(32732,32114, 11)}, + {itemid = 17898, position = Position(32732, 32115, 11)}, + {itemid = 11561, position = Position(32732,32115, 11)}, + {itemid = 17727, position = Position(32733, 32111, 11)}, + {itemid = 11561, position = Position(32733,32111, 11)}, + {itemid = 17720, position = Position(32733, 32112, 11)}, + {itemid = 11561, position = Position(32733,32112, 11)}, + {itemid = 17724, position = Position(32733, 32113, 11)}, + {itemid = 11561, position = Position(32733,32113, 11)}, + {itemid = 3622, position = Position(32733, 32114, 11)}, + {itemid = 8314, position = Position(32733, 32114, 11)}, + {itemid = 11561, position = Position(32733,32114, 11)}, + {itemid = 17725, position = Position(32733, 32115, 11)}, + {itemid = 11561, position = Position(32733,32115, 11)}, + {itemid = 17898, position = Position(32733, 32116, 11)}, + {itemid = 11561, position = Position(32733,32116, 11)}, + {itemid = 17727, position = Position(32734, 32110, 11)}, + {itemid = 11561, position = Position(32734,32110, 11)}, + {itemid = 17724, position = Position(32734, 32111, 11)}, + {itemid = 11561, position = Position(32734,32111, 11)}, + {itemid = 3611, position = Position(32734, 32112, 11)}, + {itemid = 3611, position = Position(32734, 32112, 11)}, + {itemid = 11561, position = Position(32734,32112, 11)}, + {itemid = 11561, position = Position(32734,32113, 11)}, + {itemid = 6190, position = Position(32734, 32114, 11)}, + {itemid = 11561, position = Position(32734,32114, 11)}, + {itemid = 3612, position = Position(32734, 32115, 11)}, + {itemid = 11561, position = Position(32734,32115, 11)}, + {itemid = 17725, position = Position(32734, 32116, 11)}, + {itemid = 11561, position = Position(32734,32116, 11)}, + {itemid = 17720, position = Position(32734, 32117, 11)}, + {itemid = 11561, position = Position(32734,32117, 11)}, + {itemid = 17898, position = Position(32734, 32118, 11)}, + {itemid = 11561, position = Position(32734,32118, 11)}, + {itemid = 17843, position = Position(32735, 32110, 11)}, + {itemid = 11561, position = Position(32735,32110, 11)}, + {itemid = 6431, position = Position(32735, 32111, 11)}, + {itemid = 11561, position = Position(32735,32111, 11)}, + {itemid = 11561, position = Position(32735,32112, 11)}, + {itemid = 17701, position = Position(32735, 32113, 11)}, + {itemid = 11561, position = Position(32735,32113, 11)}, + {itemid = 17685, position = Position(32735, 32114, 11)}, + {itemid = 11561, position = Position(32735,32114, 11)}, + {itemid = 6432, position = Position(32735, 32115, 11)}, + {itemid = 11561, position = Position(32735,32115, 11)}, + {itemid = 11561, position = Position(32735,32116, 11)}, + {itemid = 6431, position = Position(32735, 32117, 11)}, + {itemid = 11561, position = Position(32735,32117, 11)}, + {itemid = 17725, position = Position(32735, 32118, 11)}, + {itemid = 11561, position = Position(32735,32118, 11)}, + {itemid = 17898, position = Position(32735, 32119, 11)}, + {itemid = 11561, position = Position(32735,32119, 11)}, + {itemid = 17727, position = Position(32736, 32109, 11)}, + {itemid = 11561, position = Position(32736,32108, 11)}, + {itemid = 17724, position = Position(32736, 32110, 11)}, + {itemid = 11561, position = Position(32736,32110, 11)}, + {itemid = 11561, position = Position(32736,32111, 11)}, + {itemid = 17701, position = Position(32736, 32112, 11)}, + {itemid = 11561, position = Position(32736,32112, 11)}, + {itemid = 17933, position = Position(32736, 32113, 11)}, + {itemid = 11561, position = Position(32736,32113, 11)}, + {itemid = 17842, position = Position(32736, 32115, 11)}, + {itemid = 11561, position = Position(32736,32115, 11)}, + {itemid = 17685, position = Position(32736, 32116, 11)}, + {itemid = 11561, position = Position(32736,32116, 11)}, + {itemid = 17685, position = Position(32736, 32117, 11)}, + {itemid = 11561, position = Position(32736,32117, 11)}, + {itemid = 17685, position = Position(32736, 32118, 11)}, + {itemid = 11561, position = Position(32736,32118, 11)}, + {itemid = 17933, position = Position(32736, 32119, 11)}, + {itemid = 11561, position = Position(32736,32119, 11)}, + {itemid = 17842, position = Position(32737, 32109, 11)}, + {itemid = 11561, position = Position(32737,32108, 11)}, + {itemid = 17726, position = Position(32737, 32110, 11)}, + {itemid = 11561, position = Position(32737,32110, 11)}, + {itemid = 6191, position = Position(32737, 32111, 11)}, + {itemid = 11561, position = Position(32737,32111, 11)}, + {itemid = 17694, position = Position(32737, 32112, 11)}, + {itemid = 11561, position = Position(32737,32112, 11)}, + {itemid = 17694, position = Position(32737, 32119, 11)}, + {itemid = 17894, position = Position(32737,32119, 11)}, + {itemid = 17843, position = Position(32738, 32110, 11)}, + {itemid = 11561, position = Position(32738,32110, 11)}, + {itemid = 11561, position = Position(32738,32111, 11)}, + {itemid = 17725, position = Position(32738, 32112, 11)}, + {itemid = 11561, position = Position(32738,32112, 11)}, + {itemid = 17898, position = Position(32738, 32113, 11)}, + {itemid = 11561, position = Position(32738,32113, 11)}, + {itemid = 6150, position = Position(32738, 32115, 11)}, + {itemid = 11561, position = Position(32738,32115, 11)}, + {itemid = 17720, position = Position(32738, 32116, 11)}, + {itemid = 11561, position = Position(32738,32116, 11)}, + {itemid = 17720, position = Position(32738, 32117, 11)}, + {itemid = 11561, position = Position(32738,32117, 11)}, + {itemid = 17720, position = Position(32738, 32118, 11)}, + {itemid = 11561, position = Position(32738,32118, 11)}, + {itemid = 17898, position = Position(32738, 32119, 11)}, + {itemid = 11561, position = Position(32738,32119, 11)}, + {itemid = 17842, position = Position(32739, 32110, 11)}, + {itemid = 11561, position = Position(32739,32110, 11)}, + {itemid = 17726, position = Position(32739, 32111, 11)}, + {itemid = 11561, position = Position(32739,32111, 11)}, + {itemid = 11561, position = Position(32739,32112, 11)}, + {itemid = 17725, position = Position(32739, 32113, 11)}, + {itemid = 11561, position = Position(32739,32113, 11)}, + {itemid = 17720, position = Position(32739, 32114, 11)}, + {itemid = 11561, position = Position(32739,32114, 11)}, + {itemid = 6180, position = Position(32739, 32115, 11)}, + {itemid = 17724, position = Position(32739, 32115, 11)}, + {itemid = 11561, position = Position(32739,32115, 11)}, + {itemid = 6181, position = Position(32739, 32116, 11)}, + {itemid = 11561, position = Position(32739,32116, 11)}, + {itemid = 11561, position = Position(32739,32117, 11)}, + {itemid = 11561, position = Position(32739,32118, 11)}, + {itemid = 17694, position = Position(32739, 32119, 11)}, + {itemid = 11561, position = Position(32739,32119, 11)}, + {itemid = 17842, position = Position(32740, 32111, 11)}, + {itemid = 11561, position = Position(32740,32111, 11)}, + {itemid = 17726, position = Position(32740, 32112, 11)}, + {itemid = 11561, position = Position(32740,32112, 11)}, + {itemid = 3622, position = Position(32740, 32113, 11)}, + {itemid = 3622, position = Position(32740, 32113, 11)}, + {itemid = 6431, position = Position(32740, 32113, 11)}, + {itemid = 11561, position = Position(32740,32113, 11)}, + {itemid = 11561, position = Position(32740,32114, 11)}, + {itemid = 11561, position = Position(32740,32115, 11)}, + {itemid = 3611, position = Position(32740, 32116, 11)}, + {itemid = 11561, position = Position(32740,32116, 11)}, + {itemid = 6432, position = Position(32740, 32117, 11)}, + {itemid = 11561, position = Position(32740,32117, 11)}, + {itemid = 17701, position = Position(32740, 32118, 11)}, + {itemid = 11561, position = Position(32740,32118, 11)}, + {itemid = 17933, position = Position(32740, 32119, 11)}, + {itemid = 11561, position = Position(32740,32119, 11)}, + {itemid = 17842, position = Position(32741, 32112, 11)}, + {itemid = 11561, position = Position(32741,32112, 11)}, + {itemid = 17726, position = Position(32741, 32113, 11)}, + {itemid = 11561, position = Position(32741,32113, 11)}, + {itemid = 11561, position = Position(32741,32114, 11)}, + {itemid = 6432, position = Position(32741, 32115, 11)}, + {itemid = 11561, position = Position(32741,32115, 11)}, + {itemid = 11561, position = Position(32741,32116, 11)}, + {itemid = 17701, position = Position(32741, 32117, 11)}, + {itemid = 11561, position = Position(32741,32117, 11)}, + {itemid = 17933, position = Position(32741, 32118, 11)}, + {itemid = 11561, position = Position(32741,32118, 11)}, + {itemid = 17842, position = Position(32742, 32113, 11)}, + {itemid = 11561, position = Position(32742,32113, 11)}, + {itemid = 17685, position = Position(32742, 32114, 11)}, + {itemid = 11561, position = Position(32742,32114, 11)}, + {itemid = 17726, position = Position(32742, 32115, 11)}, + {itemid = 11561, position = Position(32742,32115, 11)}, + {itemid = 17701, position = Position(32742, 32116, 11)}, + {itemid = 11561, position = Position(32742,32116, 11)}, + {itemid = 17933, position = Position(32742, 32117, 11)}, + {itemid = 11561, position = Position(32742,32117, 11)}, + {itemid = 17842, position = Position(32743, 32115, 11)}, + {itemid = 11561, position = Position(32743,32115, 11)}, + {itemid = 17933, position = Position(32743, 32116, 11)}, + {itemid = 11561, position = Position(32743,32116, 11)} +} + +local function revertItem(position, itemId, transformId) + local item = Tile(position):getItemById(itemId) + if item then + item:transform(transformId) + end +end + +local function revertTree() + iterateArea( + function(position) + local tile = Tile(position) + if tile then + local items = tile:getItems() + if items then + for i = 1, #items do + items[i]:remove() + end + end + + local ground = tile:getGround() + if ground then + ground:remove() + end + end + end, + config.fromPosition, + config.toPosition + ) + local tree = Tile(Position(32737, 32114, 10)):getItemById(2703) + local teleport = Tile(Position(32736, 32117, 10)):getItemById(1397) + local jade = Tile(Position(32736, 32117, 10)):getItemById(12064) + if teleport then + teleport:getPosition():sendMagicEffect(CONST_ME_POFF) + teleport:remove() + end + if jade then + jade:remove() + end + if tree then + tree:getPosition():sendMagicEffect(CONST_ME_POFF) + tree:transform(6190) + end + Game.setStorageValue(GlobalStorage.ForgottenKnowledge.ActiveTree, 0) + for v = 1, #dry do + Game.createItem(dry[v].itemid, 1, dry[v].position) + local pos = Position(dry[v].position) + pos:sendMagicEffect(CONST_ME_POFF) + end +end + +local forgottenKnowledgePlant = Action() +function forgottenKnowledgePlant.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 26479 then + if target.itemid ~= 26482 then + return false + end + target:transform(26484) + target:getPosition():sendMagicEffect(CONST_ME_SMALLPLANTS) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You planted some seeds into the soil.') + addEvent(revertItem, 10 * 60 * 1000, target:getPosition(), 26484, 26482) + item:remove(1) + return true + elseif item.itemid == 26478 then + if target.itemid == 26484 then + target:transform(26483) + target:getPosition():sendMagicEffect(CONST_ME_SMALLPLANTS) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The birch grows as you pour the sparkling water from the phial over it.') + addEvent(revertItem, 10 * 60 * 1000, target:getPosition(), 26483, 26482) + if player:getStorageValue(Storage.ForgottenKnowledge.PlantCounter) < 0 then + player:setStorageValue(Storage.ForgottenKnowledge.PlantCounter, 0) + end + player:setStorageValue(Storage.ForgottenKnowledge.PlantCounter, player:getStorageValue(Storage.ForgottenKnowledge.PlantCounter) + 1) + elseif target.itemid == 6181 and target:getPosition() == Position(32737, 32116, 10) then + if Game.getStorageValue(GlobalStorage.ForgottenKnowledge.ActiveTree) >= 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You cannot use the phial while the trees still have life and colour.') + return true + end + if player:getStorageValue(Storage.ForgottenKnowledge.PlantCounter) < 5 or player:getStorageValue(Storage.ForgottenKnowledge.BirdCounter) < 3 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Seems that you don\'t make grow enough trees or not free the parrots.') + return true + end + iterateArea( + function(position) + local tile = Tile(position) + if tile then + local items = tile:getItems() + if items then + for i = 1, #items do + items[i]:remove() + end + end + + local ground = tile:getGround() + if ground then + ground:remove() + end + end + end, + config.fromPosition, + config.toPosition + ) + for k = 1, #items do + Game.createItem(items[k].itemid, 1, items[k].position) + local pos = Position(items[k].position) + pos:sendMagicEffect(CONST_ME_THUNDER) + end + local tree = Tile(Position(32737, 32114, 10)):getItemById(6190) + if tree then + tree:getPosition():sendMagicEffect(CONST_ME_THUNDER) + tree:transform(2703) + end + local contingences = Tile(Position(32736, 32117, 10)):getItems() + if contingences then + for h = 1, #contingences do + local contingence = contingences[h] + if contingence then + contingence:moveTo(Position(32737, 32117, 10)) + end + end + end + Game.setStorageValue(GlobalStorage.ForgottenKnowledge.ActiveTree, 1) + addEvent(revertTree, 1 * 60 * 1000) + Game.createItem(12064, 1, Position(32736, 32117, 10)) + local teleport = Game.createItem(1397, 1, Position(32736, 32117, 10)) + local creature = Tile(Position(32736, 32117, 10)):getTopCreature() + if creature then + creature:teleportTo(Position(32737, 32117, 10)) + end + if teleport then + teleport:setActionId(27830) + teleport:getPosition():sendMagicEffect(CONST_ME_THUNDER) + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Suddenly the area brightens and everything around you starts to bloom and thrive with life and colour.') + else + return false + end + end + return true +end + +forgottenKnowledgePlant:id(26478,26479) +forgottenKnowledgePlant:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/forgotten_knowledge/secret_wall.lua b/data/scripts/actions/quests/forgotten_knowledge/secret_wall.lua new file mode 100644 index 00000000000..094475ccfa7 --- /dev/null +++ b/data/scripts/actions/quests/forgotten_knowledge/secret_wall.lua @@ -0,0 +1,19 @@ +local forgottenKnowledgeSecret = Action() +function forgottenKnowledgeSecret.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.actionid == 24877 then + player:teleportTo(Position(32891, 31620, 10)) + return true + end + if not player:getItemById(26406, true) then + return false + end + if player:getStorageValue(Storage.ForgottenKnowledge.SilverKey) < 1 or not player:getItemById(26401, true) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You don\'t have the fitting key.') + return true + end + player:teleportTo(Position(32924, 31637, 14)) + return true +end + +forgottenKnowledgeSecret:aid(24876,24877) +forgottenKnowledgeSecret:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/forgotten_knowledge/servants_mechanism.lua b/data/scripts/actions/quests/forgotten_knowledge/servants_mechanism.lua new file mode 100644 index 00000000000..9a092b86f88 --- /dev/null +++ b/data/scripts/actions/quests/forgotten_knowledge/servants_mechanism.lua @@ -0,0 +1,64 @@ +local config = { + [26663] = {storage = GlobalStorage.ForgottenKnowledge.MechanismDiamond, counter = GlobalStorage.ForgottenKnowledge.DiamondServant, msg = "5 diamond entities are consuming too much raw energy for the cosmic chamber to awaken, it will be put to rest again in 10 minutes."}, + [26664] = {storage = GlobalStorage.ForgottenKnowledge.MechanismGolden, counter = GlobalStorage.ForgottenKnowledge.GoldenServant, msg = "5 golden entities are consuming too much raw energy for the cosmic chamber to awaken, it will be put to rest again in 10 minutes."} +} + +local function clearGolems() + local specs, spec = Game.getSpectators(Position(32815, 32874, 13), false, false, 63, 63, 63, 63) + for i = 1, #specs do + spec = specs[i] + if Game.getStorageValue(GlobalStorage.ForgottenKnowledge.MechanismDiamond) < 1 then + if spec:isMonster() and spec:getName():lower() == 'diamond servant replica' then + spec:getPosition():sendMagicEffect(CONST_ME_POFF) + spec:remove() + end + end + if Game.getStorageValue(GlobalStorage.ForgottenKnowledge.MechanismGolden) < 1 then + if spec:isMonster() and spec:getName():lower() == 'golden servant replica' then + spec:getPosition():sendMagicEffect(CONST_ME_POFF) + spec:remove() + end + end + if spec:isMonster() and spec:getName():lower() == 'iron servant replica' then + if math.random(100) <= 40 then + spec:getPosition():sendMagicEffect(CONST_ME_POFF) + spec:remove() + end + end + end +end + +local function turnOff(storage, counter) + Game.setStorageValue(storage, 0) + Game.setStorageValue(counter, 0) + clearGolems() + local teleport = Tile(Position(32815, 32870, 13)):getItemById(11796) + if teleport then + teleport:getPosition():sendMagicEffect(CONST_ME_POFF) + teleport:remove() + end +end + +local forgottenKnowledgeMechanism = Action() +function forgottenKnowledgeMechanism.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local lever = config[item.actionid] + if item.itemid == 10044 then + if Game.getStorageValue(lever.storage) >= 1 then + player:say('seems that the mechanism still active.', TALKTYPE_MONSTER_SAY, false, nil, toPosition) + return true + end + clearGolems() + Game.setStorageValue(lever.storage, 1) + Game.setStorageValue(lever.counter, 0) + addEvent(turnOff, 10 * 60 * 1000, lever.storage, lever.counter) + item:transform(10045) + player:say('*click*', TALKTYPE_MONSTER_SAY, false, nil, toPosition) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, lever.msg) + elseif item.itemid == 10045 then + item:transform(10044) + end + return true +end + +forgottenKnowledgeMechanism:aid(26663,26664) +forgottenKnowledgeMechanism:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/forgotten_knowledge/tenebris_lever.lua b/data/scripts/actions/quests/forgotten_knowledge/tenebris_lever.lua new file mode 100644 index 00000000000..89c8e5699d6 --- /dev/null +++ b/data/scripts/actions/quests/forgotten_knowledge/tenebris_lever.lua @@ -0,0 +1,65 @@ +local config = { + centerRoom = Position(32912, 31599, 14), + bossPosition = Position(32912, 31599, 14), + newPosition = Position(32911, 31603, 14) +} + +local function clearTenebris() + local spectators = Game.getSpectators(config.centerRoom, false, false, 15, 15, 15, 15) + for i = 1, #spectators do + local spectator = spectators[i] + if spectator:isPlayer() then + spectator:teleportTo(Position(32902, 31629, 14)) + spectator:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + spectator:say('Time out! You were teleported out by strange forces.', TALKTYPE_MONSTER_SAY) + elseif spectator:isMonster() then + spectator:remove() + end + end +end + +local forgottenKnowledgeTenebris = Action() +function forgottenKnowledgeTenebris.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 9825 then + if player:getPosition() ~= Position(32902, 31623, 14) then + return true + end + end + if item.itemid == 9825 then + local specs, spec = Game.getSpectators(config.centerRoom, false, false, 15, 15, 15, 15) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Someone is fighting with Lloyd.") + return true + end + end + for d = 1, 6 do + Game.createMonster('shadow tentacle', Position(math.random(32909, 32914), math.random(31596, 31601), 14), true, true) + end + Game.createMonster("lady tenebris", config.bossPosition, true, true) + for y = 31623, 31627 do + local playerTile = Tile(Position(32902, y, 14)):getTopCreature() + if playerTile and playerTile:isPlayer() then + if playerTile:getStorageValue(Storage.ForgottenKnowledge.LadyTenebrisTimer) < os.time() then + playerTile:getPosition():sendMagicEffect(CONST_ME_POFF) + playerTile:teleportTo(config.newPosition) + playerTile:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + playerTile:setStorageValue(Storage.ForgottenKnowledge.LadyTenebrisTimer, os.time() + 20 * 3600) + playerTile:say('You have 20 minutes to kill and loot this boss. Otherwise you will lose that chance and will be kicked out.', TALKTYPE_MONSTER_SAY) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need to wait a while, recently someone challenge Lady Tenebris.") + return true + end + end + end + addEvent(clearTenebris, 20 * 60 * 1000, Position(32902, 31589, 14), Position(32922, 31589, 14), Position(32924, 31610, 14)) + item:transform(9826) + elseif item.itemid == 9826 then + item:transform(9825) + end + return true +end + +forgottenKnowledgeTenebris:aid(24878) +forgottenKnowledgeTenebris:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/forgotten_knowledge/thorn_knight_lever.lua b/data/scripts/actions/quests/forgotten_knowledge/thorn_knight_lever.lua new file mode 100644 index 00000000000..c402d213d2e --- /dev/null +++ b/data/scripts/actions/quests/forgotten_knowledge/thorn_knight_lever.lua @@ -0,0 +1,51 @@ +local config = { + centerRoom = Position(32624, 32880, 14), + bossPosition = Position(32624, 32880, 14), + newPosition = Position(32624, 32886, 14) +} + +local forgottenKnowledgeThorn = Action() +function forgottenKnowledgeThorn.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 9825 then + if player:getPosition() ~= Position(32657, 32877, 14) then + item:transform(9826) + return true + end + end + if item.itemid == 9825 then + local specs, spec = Game.getSpectators(config.centerRoom, false, false, 15, 15, 15, 15) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Someone is fighting with Thorn Knight.") + return true + end + end + for d = 1, 6 do + Game.createMonster('possessed tree', Position(math.random(32619, 32629), math.random(32877, 32884), 14), true, true) + end + Game.createMonster("mounted thorn knight", config.bossPosition, true, true) + for y = 32877, 32881 do + local playerTile = Tile(Position(32657, y, 14)):getTopCreature() + if playerTile and playerTile:isPlayer() then + if playerTile:getStorageValue(Storage.ForgottenKnowledge.ThornKnightTimer) < os.time() then + playerTile:getPosition():sendMagicEffect(CONST_ME_POFF) + playerTile:teleportTo(config.newPosition) + playerTile:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + playerTile:setStorageValue(Storage.ForgottenKnowledge.ThornKnightTimer, os.time() + 20 * 3600) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need to wait a while, recently someone challenge Thorn Knight.") + return true + end + end + end + addEvent(clearForgotten, 30 * 60 * 1000, Position(32613, 32869, 14), Position(32636, 32892, 14), Position(32678, 32888, 14)) + item:transform(9826) + elseif item.itemid == 9826 then + item:transform(9825) + end + return true +end + +forgottenKnowledgeThorn:aid(24879) +forgottenKnowledgeThorn:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/forgotten_knowledge/time_guardian_lever.lua b/data/scripts/actions/quests/forgotten_knowledge/time_guardian_lever.lua new file mode 100644 index 00000000000..e354544edfa --- /dev/null +++ b/data/scripts/actions/quests/forgotten_knowledge/time_guardian_lever.lua @@ -0,0 +1,55 @@ +local config = { + centerRoom = Position(32977, 31662, 14), + newPosition = Position(32977, 31667, 14) +} + +local bosses = { + {bossPosition = Position(32977, 31662, 14), bossName = 'The Time Guardian'}, + {bossPosition = Position(32975, 31664, 13), bossName = 'The Freezing Time Guardian'}, + {bossPosition = Position(32980, 31664, 13), bossName = 'The Blazing Time Guardian'} +} + +local forgottenKnowledgeGuardianLever = Action() +function forgottenKnowledgeGuardianLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 9825 then + if player:getPosition() ~= Position(33010, 31660, 14) then + item:transform(9826) + return true + end + end + if item.itemid == 9825 then + local specs, spec = Game.getSpectators(config.centerRoom, false, false, 15, 15, 15, 15) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Someone is fighting with The Time Guardian.") + return true + end + end + for q = 1,#bosses do + Game.createMonster(bosses[q].bossName, bosses[q].bossPosition, true, true) + end + for y = 31660, 31664 do + local playerTile = Tile(Position(33010, y, 14)):getTopCreature() + if playerTile and playerTile:isPlayer() then + if playerTile:getStorageValue(Storage.ForgottenKnowledge.TimeGuardianTimer) < os.time() then + playerTile:getPosition():sendMagicEffect(CONST_ME_POFF) + playerTile:teleportTo(config.newPosition) + playerTile:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + playerTile:setStorageValue(Storage.ForgottenKnowledge.TimeGuardianTimer, os.time() + 20 * 3600) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need to wait a while, recently someone challenge The Time Guardian.") + return true + end + end + end + addEvent(clearForgotten, 30 * 60 * 1000, Position(32967, 31654, 13), Position(32989, 31677, 14), Position(32870, 32724, 14)) + item:transform(9826) + elseif item.itemid == 9826 then + item:transform(9825) + end + return true +end + +forgottenKnowledgeGuardianLever:aid(24883) +forgottenKnowledgeGuardianLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/forgotten_knowledge/time_machine.lua b/data/scripts/actions/quests/forgotten_knowledge/time_machine.lua new file mode 100644 index 00000000000..4154af7b845 --- /dev/null +++ b/data/scripts/actions/quests/forgotten_knowledge/time_machine.lua @@ -0,0 +1,26 @@ +local forgottenKnowledgeMachine = Action() +function forgottenKnowledgeMachine.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getPosition() == Position(32870, 32723, 15) then + player:teleportTo(Position(32870, 32724, 14)) + player:getPosition():sendMagicEffect(CONST_ME_ENERGYHIT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The mechanism takes you back in time.') + return true + end + + if player:getPosition() == Position(32870, 32723, 14) then + if player:getStorageValue(Storage.ForgottenKnowledge.TimeGuardianTimer) < os.time() then + player:teleportTo(Position(32870, 32724, 15)) + player:getPosition():sendMagicEffect(CONST_ME_ENERGYHIT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The mechanism takes you back in time.') + return true + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have to wait a while before travel in time!") + return true + end + else + return false + end +end + +forgottenKnowledgeMachine:id(27764) +forgottenKnowledgeMachine:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/grave_danger/cobra_bastion/scarlett.lua b/data/scripts/actions/quests/grave_danger/cobra_bastion/scarlett.lua new file mode 100644 index 00000000000..55a97fff23c --- /dev/null +++ b/data/scripts/actions/quests/grave_danger/cobra_bastion/scarlett.lua @@ -0,0 +1,129 @@ +local info = { + bossName = "Scarlett Etzel", + middle = Position(33395, 32662, 6), + fromPos = Position(33385, 32638, 6), + toPos = Position(33406, 32660, 6), + exitPos = Position(33395, 32670, 6), + timer = Storage.GraveDanger.CobraBastion.ScarlettTimer, + armorId = 36317, + armorPos = Position(33398, 32640, 6), +} + +local entry = { + metalWallId = 36284, + roomEntryPos = Position(33395, 32666, 6), + roomExitPos = Position(33395, 32668, 6) +} + +local transformTo = { + [36309] = 36310, + [36310] = 36311, + [36311] = 36312, + [36312] = 36309 +} + +local function createArmor(id, amount, pos) + local armor = Game.createItem(id, amount, pos) + if armor then armor:setActionId(40003) end +end + +local graveScarlettUid = Action() +function graveScarlettUid.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local playersTable = {} + if item:getUniqueId() == 40028 then + if player:doCheckBossRoom(info.bossName, info.fromPos, info.toPos) then + for x = info.middle.x - 1, info.middle.x + 1 do + for y = info.middle.y - 1, info.middle.y + 1 do + local sqm = Tile(Position(x, y, 6)) + if sqm and sqm:getGround():getId() == 20293 then + local player_ = sqm:getTopCreature() + if player_ and player_:isPlayer() then + if player_:getStorageValue(info.timer) > os.time() then + player_:getPosition():sendMagicEffect(CONST_ME_POFF) + player_:sendCancelMessage('You are still exhausted from your last battle.') + return true + end + table.insert(playersTable, player_:getId()) + end + end + end + end + for _, p in pairs(playersTable) do + local nPlayer = Player(p) + if nPlayer then + nPlayer:teleportTo(Position(33395, 32656, 6)) + nPlayer:setStorageValue(info.timer, os.time() + 20*60*60) + end + end + local scarlett = Game.createMonster("Scarlett Etzel", Position(33396, 32640, 6)) + if scarlett then + scarlett:registerEvent('scarlettThink') + scarlett:registerEvent('scarlettHealth') + scarlett:setStorageValue(Storage.GraveDanger.CobraBastion.Questline, 1) + end + SCARLETT_MAY_TRANSFORM = 0 + addEvent(kickPlayersAfterTime, 30*60*1000, playersTable, info.fromPos, info.toPos, info.exitPos) + end + end + return true +end + +graveScarlettUid:uid(40028) +graveScarlettUid:register() + + +local mirror = { + fromPos = Position(33389, 32641, 6), + toPos = Position(33403, 32655, 6), + mirrors = {36309, 36310, 36311, 36312} +} + +local function backMirror() + for x = mirror.fromPos.x, mirror.toPos.x do + for y = mirror.fromPos.y, mirror.toPos.y do + local sqm = Tile(Position(x, y, 6)) + if sqm then + for _, id in pairs(mirror.mirrors) do + local item = sqm:getItemById(id) + if item then + item:transform(mirror.mirrors[math.random(#mirror.mirrors)]) + item:getPosition():sendMagicEffect(CONST_ME_POFF) + end + end + end + end + end +end + +local graveScarlettAid = Action(); +function graveScarlettAid.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.actionid == 40003 then + if isInArray(transformTo, item.itemid) then + local pilar = transformTo[item.itemid] + if pilar then + item:transform(pilar) + item:getPosition():sendMagicEffect(CONST_ME_POFF) + end + elseif item.itemid == info.armorId then + item:getPosition():sendMagicEffect(CONST_ME_THUNDER) + item:remove(1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You hold the old chestplate of Galthein in front of you. It does not fit and far too old to withstand any attack.") + addEvent(createArmor, 20*1000, info.armorId, 1, info.armorPos) + addEvent(backMirror, 10*1000) + SCARLETT_MAY_TRANSFORM = 1 + addEvent(function() + SCARLETT_MAY_TRANSFORM = 0 + end, 1 * 1000) + elseif item.itemid == entry.metalWallId then + if player:getPosition().y == entry.roomExitPos.y then + player:teleportTo(entry.roomEntryPos) + else + player:teleportTo(entry.roomExitPos) + end + end + end + return true +end + +graveScarlettAid:aid(40003) +graveScarlettAid:register() diff --git a/data/scripts/actions/quests/gravedigger/amforas.lua b/data/scripts/actions/quests/gravedigger/amforas.lua new file mode 100644 index 00000000000..f3be0ce8baa --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/amforas.lua @@ -0,0 +1,21 @@ +local gravediggerAmforas = Action() +function gravediggerAmforas.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.GravediggerOfDrefia.Mission05) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission06) ~= 1 then + local chances = math.random(30) + if chances == 13 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission06,1) + player:say("You've got an amazing heart!", TALKTYPE_MONSTER_SAY) + player:getPosition():sendMagicEffect(CONST_ME_HEARTS) + player:addItem(21394,1) + else + player:say("Keep it trying!", TALKTYPE_MONSTER_SAY) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + end + else + player:say("You've already got your heart", TALKTYPE_MONSTER_SAY) + end + return true +end + +gravediggerAmforas:aid(4630) +gravediggerAmforas:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/gravedigger/ashes.lua b/data/scripts/actions/quests/gravedigger/ashes.lua new file mode 100644 index 00000000000..5473a421a97 --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/ashes.lua @@ -0,0 +1,16 @@ +local gravediggerAshes = Action() +function gravediggerAshes.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid ~= 4638 then + return false + end + + if player:getStorageValue(Storage.GravediggerOfDrefia.Mission28) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission29) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission29, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The ashes swirl with a life of their own, mixing with the sparks of the altar.') + item:remove(1) + end + return true +end + +gravediggerAshes:id(21446) +gravediggerAshes:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/gravedigger/blood.lua b/data/scripts/actions/quests/gravedigger/blood.lua new file mode 100644 index 00000000000..f4560ad0423 --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/blood.lua @@ -0,0 +1,24 @@ +local config = { + [4644] = {storageKey = {Storage.GravediggerOfDrefia.Mission36, Storage.GravediggerOfDrefia.Mission36a}, message = 'The blood in the vial is of a deep, ruby red.', itemId = 21418}, + [4645] = {storageKey = {Storage.GravediggerOfDrefia.Mission36a, Storage.GravediggerOfDrefia.Mission37}, message = 'The blood in the vial is of a strange colour, as if tainted.', itemId = 21419} +} + +local gravediggerBlood = Action() +function gravediggerBlood.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local targetItem = config[target.actionid] + if not targetItem then + return true + end + + local cStorages = targetItem.storageKey + if player:getStorageValue(cStorages[1]) == 1 and player:getStorageValue(cStorages[2]) < 1 then + player:setStorageValue(cStorages[2], 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, targetItem.message) + player:addItem(targetItem.itemId, 1) + item:remove(1) + end + return true +end + +gravediggerBlood:id(21417) +gravediggerBlood:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/gravedigger/bones.lua b/data/scripts/actions/quests/gravedigger/bones.lua new file mode 100644 index 00000000000..80f8c39d334 --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/bones.lua @@ -0,0 +1,16 @@ +local gravediggerBones = Action() +function gravediggerBones.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid ~= 4633 then + return false + end + + if player:getStorageValue(Storage.GravediggerOfDrefia.Mission17) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission19) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission19, 1) + player:addItem(21406, 1) + item:remove() + end + return true +end + +gravediggerBones:id(21407) +gravediggerBones:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/gravedigger/bookcase.lua b/data/scripts/actions/quests/gravedigger/bookcase.lua new file mode 100644 index 00000000000..73ead7c64b8 --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/bookcase.lua @@ -0,0 +1,15 @@ +local gravediggerBook = Action() +function gravediggerBook.onUse(item, fromPosition, itemEx, toPosition) + if player:getStorageValue(Storage.GravediggerOfDrefia.Bookcase) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Bookcase, 1) + player:addItem(21474,1) + player:say("You have found a crumpled paper.", TALKTYPE_ORANGE_1) + else + player:say("You've picked up here.", TALKTYPE_ORANGE_1) + return true + end + return true +end + +gravediggerBook:aid(4669) +gravediggerBook:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/gravedigger/brain.lua b/data/scripts/actions/quests/gravedigger/brain.lua new file mode 100644 index 00000000000..45032b02ccb --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/brain.lua @@ -0,0 +1,22 @@ +local gravediggerBrain = Action() +function gravediggerBrain.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local rightbrain = Tile(Position(33025, 32332, 10)) + local leftbrain = Tile(Position(33020, 32332, 10)) + if player:getStorageValue(Storage.GravediggerOfDrefia.Mission08) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission09) < 1 then + if leftbrain:getItemById(10576) and rightbrain:getItemById(10576) then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission09, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, ' ') + leftbrain:getItemById(10576):remove() + rightbrain:getItemById(10576):remove() + Game.createItem(21395, 1, Position(33022, 32332, 10)) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'No brains') + end + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have already got your brain') + end + return true +end + +gravediggerBrain:aid(4631) +gravediggerBrain:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/gravedigger/caixa.lua b/data/scripts/actions/quests/gravedigger/caixa.lua new file mode 100644 index 00000000000..cbe3f8c15e9 --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/caixa.lua @@ -0,0 +1,12 @@ +local gravediggerCaixa = Action() +function gravediggerCaixa.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.GravediggerOfDrefia.Mission67) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission68) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission68, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have found an incantation fragment.') + player:addItem(21250, 1) + end + return true +end + +gravediggerCaixa:uid(4663) +gravediggerCaixa:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/gravedigger/candles.lua b/data/scripts/actions/quests/gravedigger/candles.lua new file mode 100644 index 00000000000..72b9b5bc82e --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/candles.lua @@ -0,0 +1,17 @@ +local gravediggerCandles = Action() +function gravediggerCandles.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid ~= 4640 then + return false + end + + if player:getStorageValue(Storage.GravediggerOfDrefia.Mission31) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission32) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission32, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Reading the parchment, you identify three human tallow candles and pocket them.') + player:addItem(21248, 3) + item:remove(1) + end + return true +end + +gravediggerCandles:id(21448) +gravediggerCandles:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/gravedigger/cape.lua b/data/scripts/actions/quests/gravedigger/cape.lua new file mode 100644 index 00000000000..0da17ef78bd --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/cape.lua @@ -0,0 +1,13 @@ +local gravediggerCape = Action() +function gravediggerCape.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.GravediggerOfDrefia.Mission59) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission60) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission60, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You now look like a Necromancer.') + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:removeItem(21464, 1) + end + return true +end + +gravediggerCape:id(21464) +gravediggerCape:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/gravedigger/chalk.lua b/data/scripts/actions/quests/gravedigger/chalk.lua new file mode 100644 index 00000000000..c01ae8f3289 --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/chalk.lua @@ -0,0 +1,17 @@ +local gravediggerChalk = Action() +function gravediggerChalk.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid ~= 4637 then + return false + end + + if player:getStorageValue(Storage.GravediggerOfDrefia.Mission27) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission28) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission28, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The flame wavers as it engulfs the chalk. Strange ashes appear beside it.') + Game.createItem(21446, 1, Position(32983, 32376, 11)) + item:remove(1) + end + return true +end + +gravediggerChalk:id(21247) +gravediggerChalk:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/gravedigger/flask.lua b/data/scripts/actions/quests/gravedigger/flask.lua new file mode 100644 index 00000000000..e747a53912b --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/flask.lua @@ -0,0 +1,17 @@ +local gravediggerFlask = Action() +function gravediggerFlask.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid ~= 2817 then + return false + end + + if player:getStorageValue(Storage.GravediggerOfDrefia.Mission11) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission12) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission12, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Done! Report back to Omrabas.') + player:addItem(21403, 1) + item:remove() + end + return true +end + +gravediggerFlask:id(21402) +gravediggerFlask:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/gravedigger/hallowed.lua b/data/scripts/actions/quests/gravedigger/hallowed.lua new file mode 100644 index 00000000000..5926ac8b613 --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/hallowed.lua @@ -0,0 +1,16 @@ +local gravediggerHallowed = Action() +function gravediggerHallowed.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid ~= 4634 then + return false + end + + if player:getStorageValue(Storage.GravediggerOfDrefia.Mission19) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission20) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission20, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The flames roar and eat the bone hungrily. The Dark Lord is satisfied with your gift') + item:remove() + end + return true +end + +gravediggerHallowed:id(21406) +gravediggerHallowed:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/gravedigger/inscriptions.lua b/data/scripts/actions/quests/gravedigger/inscriptions.lua new file mode 100644 index 00000000000..04dc9f09601 --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/inscriptions.lua @@ -0,0 +1,20 @@ +local gravediggerInscriptions = Action() +function gravediggerInscriptions.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.GravediggerOfDrefia.Mission45) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission46) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission46, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The words seem to breathe, stangely. One word stays in your mind: bronze') + player:getPosition():sendMagicEffect(CONST_ME_ENERGYHIT) + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission46) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission47) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission47, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The words seem to glow slightly. A name fixes in your mind: Takesha Antishu') + player:getPosition():sendMagicEffect(CONST_ME_ENERGYHIT) + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission47) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission48) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission48, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The words seem to flutter. One word stays in your mind: floating') + player:getPosition():sendMagicEffect(CONST_ME_ENERGYHIT) + end + return true +end + +gravediggerInscriptions:aid(4651,4652,4653) +gravediggerInscriptions:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/gravedigger/key1.lua b/data/scripts/actions/quests/gravedigger/key1.lua new file mode 100644 index 00000000000..dde0e876d14 --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/key1.lua @@ -0,0 +1,16 @@ +local gravediggerKey1 = Action() +function gravediggerKey1.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid ~= 4639 then + return false + end + + if player:getStorageValue(Storage.GravediggerOfDrefia.Mission31) == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, ' ') + item:remove(1) + Tile(Position(33071, 32442, 11)):getItemById(9624):transform(9625) + end + return true +end + +gravediggerKey1:id(21482) +gravediggerKey1:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/gravedigger/key2.lua b/data/scripts/actions/quests/gravedigger/key2.lua new file mode 100644 index 00000000000..b1275d9fc23 --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/key2.lua @@ -0,0 +1,22 @@ +local gravediggerKey2 = Action() +function gravediggerKey2.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid ~= 4661 then + return false + end + + if player:getStorageValue(Storage.GravediggerOfDrefia.Mission52) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission53) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission53, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "An invisible hand pulls you inside.") + player:teleportTo(Position({x = 33011, y = 32392, z = 10})) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + elseif player:getStorageValue(Storage.GravediggerOfDrefia.Mission53) == 1 then --and player:getStorageValue(Storage.GravediggerOfDrefia.Mission55) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission55, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Get out of my room!") + player:teleportTo(Position({x = 33008, y = 32392, z = 10})) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + end + return true +end + +gravediggerKey2:id(21489) +gravediggerKey2:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/gravedigger/monks.lua b/data/scripts/actions/quests/gravedigger/monks.lua new file mode 100644 index 00000000000..0ef96e3d0c2 --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/monks.lua @@ -0,0 +1,24 @@ +local config = { + [4641] = {storageKey = {Storage.GravediggerOfDrefia.Mission32, Storage.GravediggerOfDrefia.Mission32a}, message = 'Shadows rise and engulf the candle. The statue flickers in an unearthly light.'}, + [4642] = {storageKey = {Storage.GravediggerOfDrefia.Mission32a, Storage.GravediggerOfDrefia.Mission32b}, message = 'The shadows of the statue swallow the candle hungrily.'}, + [4643] = {storageKey = {Storage.GravediggerOfDrefia.Mission32b, Storage.GravediggerOfDrefia.Mission33}, message = 'A shade emerges and snatches the candle from your hands.'} +} + +local gravediggerMonks = Action() +function gravediggerMonks.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local targetItem = config[target.actionid] + if not targetItem then + return true + end + + local cStorages = targetItem.storageKey + if player:getStorageValue(cStorages[1]) == 1 and player:getStorageValue(cStorages[2]) < 1 then + player:setStorageValue(cStorages[2], 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, targetItem.message) + item:remove(1) + end + return true +end + +gravediggerMonks:id(21248) +gravediggerMonks:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/gravedigger/palanca.lua b/data/scripts/actions/quests/gravedigger/palanca.lua new file mode 100644 index 00000000000..9d9dd8f7d61 --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/palanca.lua @@ -0,0 +1,12 @@ +local gravediggerPalanca = Action() +function gravediggerPalanca.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.GravediggerOfDrefia.Mission39) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission40) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission40, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, ' ') + player:getPosition():sendMagicEffect(CONST_ME_ENERGYHIT) + end + return true +end + +gravediggerPalanca:aid(4650) +gravediggerPalanca:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/gravedigger/pyramids1.lua b/data/scripts/actions/quests/gravedigger/pyramids1.lua new file mode 100644 index 00000000000..0e925c13078 --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/pyramids1.lua @@ -0,0 +1,24 @@ +local config = { + [4646] = {Storage.GravediggerOfDrefia.Mission38, Storage.GravediggerOfDrefia.Mission38a}, + [4647] = {Storage.GravediggerOfDrefia.Mission38a, Storage.GravediggerOfDrefia.Mission38b}, + [4648] = {Storage.GravediggerOfDrefia.Mission38b, Storage.GravediggerOfDrefia.Mission38c}, + [4649] = {Storage.GravediggerOfDrefia.Mission38c, Storage.GravediggerOfDrefia.Mission39} +} + +local gravediggerPyramids1 = Action() +function gravediggerPyramids1.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local cStorages = config[target.actionid] + if not cStorages then + return true + end + + if player:getStorageValue(cStorages[1]) == 1 and player:getStorageValue(cStorages[2]) < 1 then + player:setStorageValue(cStorages[2], 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, ' ') + player:getPosition():sendMagicEffect(CONST_ME_ENERGYHIT) + end + return true +end + +gravediggerPyramids1:id(21449) +gravediggerPyramids1:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/gravedigger/pyramids2.lua b/data/scripts/actions/quests/gravedigger/pyramids2.lua new file mode 100644 index 00000000000..009f1b3faee --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/pyramids2.lua @@ -0,0 +1,27 @@ +local config = { + [4663] = {Storage.GravediggerOfDrefia.Mission38, Storage.GravediggerOfDrefia.Mission62}, + [4664] = {Storage.GravediggerOfDrefia.Mission38a, Storage.GravediggerOfDrefia.Mission63}, + [4665] = {Storage.GravediggerOfDrefia.Mission38b, Storage.GravediggerOfDrefia.Mission64}, + [4666] = {Storage.GravediggerOfDrefia.Mission38c, Storage.GravediggerOfDrefia.Mission65}, + [4667] = {Storage.GravediggerOfDrefia.Mission38c, Storage.GravediggerOfDrefia.Mission66} +} + +local gravediggerPyramids2 = Action() +function gravediggerPyramids2.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local cStorages = config[target.actionid] + if not cStorages then + return true + end + + if player:getStorageValue(cStorages[1]) == 1 and player:getStorageValue(cStorages[2]) < 1 then + player:setStorageValue(cStorages[2], 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, ' ') + player:getPosition():sendMagicEffect(CONST_ME_ENERGYHIT) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Mission already completed here!') + end + return true +end + +gravediggerPyramids2:id(21249) +gravediggerPyramids2:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/gravedigger/sacrifice.lua b/data/scripts/actions/quests/gravedigger/sacrifice.lua new file mode 100644 index 00000000000..60b5edd29b4 --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/sacrifice.lua @@ -0,0 +1,35 @@ +local gravediggerSacrifice = Action() +function gravediggerSacrifice.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.GravediggerOfDrefia.Mission74) == 1 then --and player:getStorageValue(Storage.GravediggerOfDrefia.Mission73) < 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission74) < 1 then + local skullItem = Tile(Position(33015, 32418, 11)):getItemById(21476) + if skullItem then + skullItem:remove() + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The scroll burns to dust. The magic stutters. Omrabas\' soul flees to his old hideaway.') + player:removeItem(21251, 1) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission74, 1) + Game.createMonster("Chicken", Position(33015, 32418, 11)) + end + else player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Teste') + end + return true +end + +gravediggerSacrifice:id(21251) +gravediggerSacrifice:register() + +-- SE DER RUIM AI EM CIMA, COLOCAR ESSE: + +--function onUse(player, item, fromPosition, target, toPosition, isHotkey) + --if player:getStorageValue(Storage.GravediggerOfDrefia.Mission73) == 1 then --and player:getStorageValue(Storage.GravediggerOfDrefia.Mission73) < 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission74) < 1 then + --local skullItem = Tile(Position(33015, 32418, 11)):getItemById(21476) + --if skullItem then + -- skullItem:remove() + -- player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The scroll burns to dust. The magic stutters. Omrabas\' soul flees to his old hideaway.') + -- player:removeItem(21251, 1) + --player:setStorageValue(Storage.GravediggerOfDrefia.Mission73, 1) + -- Game.createMonster("Chicken", Position(33015, 32418, 11)) + --end + --else player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Teste') + --end + --return true +--end diff --git a/data/scripts/actions/quests/gravedigger/scroll.lua b/data/scripts/actions/quests/gravedigger/scroll.lua new file mode 100644 index 00000000000..fc84b62b1c1 --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/scroll.lua @@ -0,0 +1,13 @@ +local gravediggerScroll = Action() +function gravediggerScroll.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.GravediggerOfDrefia.Mission53) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission54) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission54, 1) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission55, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Somebody left a card. It says: Looking for the scroll? Come find me. Take the stairs next to the students. Dorm.') + player:getPosition():sendMagicEffect(CONST_ME_POFF) + end + return true +end + +gravediggerScroll:aid(4662) +gravediggerScroll:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/gravedigger/statue.lua b/data/scripts/actions/quests/gravedigger/statue.lua new file mode 100644 index 00000000000..3e25e2aa46a --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/statue.lua @@ -0,0 +1,17 @@ +local gravediggerStatue = Action() +function gravediggerStatue.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid ~= 21429 then + return false + end + + if player:getStorageValue(Storage.GravediggerOfDrefia.Mission20) >= 1 + and player:getStorageValue(Storage.GravediggerOfDrefia.Mission25) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission25,1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, ' A slow throbbing, like blood pulsing, runs through the floor.') + player:getPosition():sendMagicEffect(CONST_ME_SOUND_GREEN) + end + return true +end + +gravediggerStatue:aid(4636) +gravediggerStatue:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/gravedigger/tears.lua b/data/scripts/actions/quests/gravedigger/tears.lua new file mode 100644 index 00000000000..0b45e19ba27 --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/tears.lua @@ -0,0 +1,16 @@ +local gravediggerTears = Action() +function gravediggerTears.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid ~= 4632 then + return false + end + + if player:getStorageValue(Storage.GravediggerOfDrefia.Mission14) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission15) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission15, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The dragon tears glow and disappear. The old powers are appeased.') + item:remove(3) + end + return true +end + +gravediggerTears:id(21401) +gravediggerTears:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/gravedigger/tincture.lua b/data/scripts/actions/quests/gravedigger/tincture.lua new file mode 100644 index 00000000000..138aee9a97e --- /dev/null +++ b/data/scripts/actions/quests/gravedigger/tincture.lua @@ -0,0 +1,16 @@ +local gravediggerTincture = Action() +function gravediggerTincture.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid ~= 4635 then + return false + end + + if player:getStorageValue(Storage.GravediggerOfDrefia.Mission23) == 1 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission24) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission24,1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You crash the vial and spill the blood tincture. This altar is anointed.') + item:remove() + end + return true +end + +gravediggerTincture:id(21245) +gravediggerTincture:register() diff --git a/data/scripts/actions/quests/green_djinn/tear.lua b/data/scripts/actions/quests/green_djinn/tear.lua new file mode 100644 index 00000000000..f7819aa99e7 --- /dev/null +++ b/data/scripts/actions/quests/green_djinn/tear.lua @@ -0,0 +1,14 @@ +local greenTear = Action() +function greenTear.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.DjinnWar.EfreetFaction.Mission02) ~= 1 then + return true + end + + Game.createItem(2346, 1, fromPosition) + player:setStorageValue(Storage.DjinnWar.EfreetFaction.Mission02, 2) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a tear of daraman.") + return true +end + +greenTear:aid(5390) +greenTear:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/grimvale/closed_silvered_trap.lua b/data/scripts/actions/quests/grimvale/closed_silvered_trap.lua new file mode 100644 index 00000000000..d2b6a5a3663 --- /dev/null +++ b/data/scripts/actions/quests/grimvale/closed_silvered_trap.lua @@ -0,0 +1,19 @@ +local grimValeClosed = Action() +function grimValeClosed.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if toPosition.x == CONTAINER_POSITION then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Use it on the ground to set the trap.') + return true + end + if player:getPosition():getDistance(Position(33390, 31540, 11)) >= 30 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You may use it in the Feroxa\'s room.') + return true + end + item:transform(24715) + item:decay() + toPosition:sendMagicEffect(CONST_ME_POFF) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The silvered trap has been set and cannot be removed from its current position.') + return true +end + +grimValeClosed:id(24730) +grimValeClosed:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/grimvale/silver_liquid.lua b/data/scripts/actions/quests/grimvale/silver_liquid.lua new file mode 100644 index 00000000000..51794877ea2 --- /dev/null +++ b/data/scripts/actions/quests/grimvale/silver_liquid.lua @@ -0,0 +1,15 @@ +local grimValeSilver = Action() +function grimValeSilver.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid == 2578 or target.itemid == 2579 then + target:transform(24730) + item:remove() + player:getPosition():sendMagicEffect(CONST_ME_POFF) + toPosition:sendMagicEffect(CONST_ME_POFF) + else + return false + end + return true +end + +grimValeSilver:id(24714) +grimValeSilver:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/heart_of_destruction/anomaly_lever.lua b/data/scripts/actions/quests/heart_of_destruction/anomaly_lever.lua new file mode 100644 index 00000000000..15d72e25b71 --- /dev/null +++ b/data/scripts/actions/quests/heart_of_destruction/anomaly_lever.lua @@ -0,0 +1,124 @@ +-- FUNCTIONS +local function doCheckArea() + local upConer = {x = 32258, y = 31237, z = 14} -- upLeftCorner + local downConer = {x = 32284, y = 31262, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k = upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + return true + end + end + end + end + end + end + end + return false +end + +local function clearArea() + local upConer = {x = 32258, y = 31237, z = 14} -- upLeftCorner + local downConer = {x = 32284, y = 31262, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k= upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + c:teleportTo({x = 32104, y = 31329, z = 12}) + elseif isMonster(c) then + c:remove() + end + end + end + end + end + end + end +end +-- FUNCTIONS END + +local heartDestructionAnomaly = Action() +function heartDestructionAnomaly.onUse(player, item, fromPosition, itemEx, toPosition) + + local config = { + playerPositions = { + Position(32245, 31245, 14), + Position(32245, 31246, 14), + Position(32245, 31247, 14), + Position(32245, 31248, 14), + Position(32245, 31249, 14) + }, + + newPos = {x = 32271, y = 31257, z = 14}, + } + + local pushPos = {x = 32245, y = 31245, z = 14} + + if item.actionid == 14325 then + if item.itemid == 9825 then + if player:getPosition().x == pushPos.x and player:getPosition().y == pushPos.y and player:getPosition().z == pushPos.z then + + local storePlayers, playerTile = {} + for i = 1, #config.playerPositions do + playerTile = Tile(config.playerPositions[i]):getTopCreature() + if isPlayer(playerTile) then + storePlayers[#storePlayers + 1] = playerTile + end + end + + if doCheckArea() == false then + clearArea() + + local players + + for i = 1, #storePlayers do + players = storePlayers[i] + config.playerPositions[i]:sendMagicEffect(CONST_ME_POFF) + players:teleportTo(config.newPos) + players:setStorageValue(14321, os.time() + 20*60*60) + end + Position(config.newPos):sendMagicEffect(11) + + areaAnomaly1 = addEvent(clearArea, 15 * 60000) + + Game.setStorageValue(14322, 0) -- Anomaly Stages + + Game.createMonster("Spark of Destruction", {x = 32267, y = 31253, z = 14}, false, true) + Game.createMonster("Spark of Destruction", {x = 32274, y = 31255, z = 14}, false, true) + Game.createMonster("Spark of Destruction", {x = 32274, y = 31249, z = 14}, false, true) + Game.createMonster("Spark of Destruction", {x = 32267, y = 31249, z = 14}, false, true) + Game.createMonster("Anomaly", {x = 32271, y = 31249, z = 14}, false, true) + + local vortex = Tile({x = 32261, y = 31250, z = 14}):getItemById(26138) + if vortex then + vortex:transform(26139) + vortex:setActionId(14324) + end + else + player:sendTextMessage(19, "Someone is in the area.") + end + else + return true + end + end + item:transform(item.itemid == 9825 and 9826 or 9825) + end + return true +end + +heartDestructionAnomaly:aid(14325) +heartDestructionAnomaly:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/heart_of_destruction/charges_lever.lua b/data/scripts/actions/quests/heart_of_destruction/charges_lever.lua new file mode 100644 index 00000000000..51bec0e4606 --- /dev/null +++ b/data/scripts/actions/quests/heart_of_destruction/charges_lever.lua @@ -0,0 +1,261 @@ +local team = {} + +-- FUNCTIONS + +local function shuffleTable(t, count, ri, rj) + ri = ri or 1 + rj = rj or #t + for x = 1, count or 1 do + for i = rj, ri + 1, -1 do + local j = math.random(ri, rj) + t[i], t[j] = t[j], t[i] + end + end +end + +local function doCheckArea() + --Room 1 + local upConer = {x = 32133, y = 31341, z = 14} -- upLeftCorner + local downConer = {x = 32174, y = 31375, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k = upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + return true + end + end + end + end + end + end + end + + --Room 2 + local upConer2 = {x = 32140, y = 31340, z = 15} -- upLeftCorner + local downConer2 = {x = 32174, y = 31375, z = 15} -- downRightCorner + + for f=upConer2.x, downConer2.x do + for g=upConer2.y, downConer2.y do + for h= upConer2.z, downConer2.z do + local room = {x=f, y=g, z=h} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + return true + end + end + end + end + end + end + end + + if spawningCharge == true then + return true + end + + return false +end + +local function clearArea() + --Room 1 + local upConer = {x = 32133, y = 31341, z = 14} -- upLeftCorner + local downConer = {x = 32174, y = 31375, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k= upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + c:teleportTo({x = 32092, y = 31330, z = 12}) + elseif isMonster(c) then + c:remove() + end + end + end + end + end + end + end + + --Room 2 + local upConer2 = {x = 32140, y = 31340, z = 15} -- upLeftCorner + local downConer2 = {x = 32174, y = 31375, z = 15} -- downRightCorner + + for f=upConer2.x, downConer2.x do + for g=upConer2.y, downConer2.y do + for h=upConer2.z, downConer2.z do + local room = {x=f, y=g, z=h} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + c:teleportTo({x = 32092, y = 31330, z = 12}) + elseif isMonster(c) then + c:remove() + end + end + end + end + end + end + end + team = {} + stopEvent(areaHeart1) + stopEvent(areaHeart2) + stopEvent(areaHeart3) +end + +function teleportToCrackler() + shuffleTable(team, 2, ri, rj) -- Embaralha a tabela para dar um random teleport + + --Room 1 + local upConer = {x = 32142, y = 31341, z = 14} -- upLeftCorner + local downConer = {x = 32176, y = 31375, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k= upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if c == team[1] or c == team[2] then + c:teleportTo({x = c:getPosition().x, y = c:getPosition().y, z = c:getPosition().z + 1}) + c:say("A shift in polarity switches creatures with coresponding polarity into another phase of existence!", TALKTYPE_MONSTER_YELL, isInGhostMode, pid, {x = 32158, y = 31355, z = 14}) + end + end + end + end + end + end + end + areaHeart3 = addEvent(teleportToCharger, 10000) +end + +function teleportToCharger() + --Room 1 + local upConer = {x = 32142, y = 31341, z = 15} -- upLeftCorner + local downConer = {x = 32176, y = 31375, z = 15} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k= upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + c:teleportTo({x = c:getPosition().x, y = c:getPosition().y, z = c:getPosition().z - 1}) + end + end + end + end + end + end + end + areaHeart2 = addEvent(teleportToCrackler, 25000) +end +-- FUNCTIONS END + +local heartDestructionCharges = Action() +function heartDestructionCharges.onUse(player, item, fromPosition, itemEx, toPosition) + + local config = { + playerPositions = { + Position(32091, 31327, 12), + Position(32092, 31327, 12), + Position(32093, 31327, 12), + Position(32094, 31327, 12), + Position(32095, 31327, 12) + }, + + newPos = {x = 32135, y = 31363, z = 14}, + } + + local pushPos = {x = 32091, y = 31327, z = 12} + + if item.actionid == 14320 then + if item.itemid == 9825 then + if player:getPosition().x == pushPos.x and player:getPosition().y == pushPos.y and player:getPosition().z == pushPos.z then + + local storePlayers, playerTile = {} + for i = 1, #config.playerPositions do + playerTile = Tile(config.playerPositions[i]):getTopCreature() + if isPlayer(playerTile) then + storePlayers[#storePlayers + 1] = playerTile + end + end + + if doCheckArea() == false then + clearArea() + + local players + + for i = 1, #storePlayers do + players = storePlayers[i] + table.insert(team, players) -- Insert players on table to get a random teleport + config.playerPositions[i]:sendMagicEffect(CONST_ME_POFF) + players:teleportTo(config.newPos) + Position(config.newPos):sendMagicEffect(11) + end + + areaHeart1 = addEvent(clearArea, 15 * 60000) + areaHeart2 = addEvent(teleportToCrackler, 25000) + + Game.setStorageValue(14321, 0) -- Overcharge Count + + spawningCharge = false + + Game.createMonster("Charger", {x = 32151, y = 31356, z = 14}, false, true) + Game.createMonster("Charger", {x = 32154, y = 31353, z = 14}, false, true) + Game.createMonster("Charger", {x = 32153, y = 31361, z = 14}, false, true) + Game.createMonster("Charger", {x = 32158, y = 31362, z = 14}, false, true) + Game.createMonster("Charger", {x = 32161, y = 31360, z = 14}, false, true) + Game.createMonster("Charger", {x = 32156, y = 31357, z = 14}, false, true) + Game.createMonster("Charger", {x = 32159, y = 31354, z = 14}, false, true) + Game.createMonster("Charger", {x = 32163, y = 31356, z = 14}, false, true) + Game.createMonster("Charger", {x = 32162, y = 31352, z = 14}, false, true) + Game.createMonster("Charger", {x = 32158, y = 31350, z = 14}, false, true) + + Game.createMonster("Overcharge", {x = 32152, y = 31355, z = 15}, false, true) + Game.createMonster("Overcharge", {x = 32154, y = 31360, z = 15}, false, true) + Game.createMonster("Overcharge", {x = 32160, y = 31360, z = 15}, false, true) + Game.createMonster("Overcharge", {x = 32162, y = 31356, z = 15}, false, true) + Game.createMonster("Overcharge", {x = 32158, y = 31352, z = 15}, false, true) + else + player:sendTextMessage(19, "Someone is in the area.") + end + else + return true + end + end + item:transform(item.itemid == 9825 and 9826 or 9825) + end + + return true +end + +heartDestructionCharges:aid(14320) +heartDestructionCharges:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/heart_of_destruction/cracklers_lever.lua b/data/scripts/actions/quests/heart_of_destruction/cracklers_lever.lua new file mode 100644 index 00000000000..e3477c48bff --- /dev/null +++ b/data/scripts/actions/quests/heart_of_destruction/cracklers_lever.lua @@ -0,0 +1,202 @@ +local function doCheckArea() + local upConer = {x = 32192, y = 31311, z = 14} -- upLeftCorner + local downConer = {x = 32225, y = 31343, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k = upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + return true + end + end + end + end + end + end + end + return false +end + +local function clearArea() + local upConer = {x = 32192, y = 31311, z = 14} -- upLeftCorner + local downConer = {x = 32225, y = 31343, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k= upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + c:teleportTo({x = 32078, y = 31320, z = 13}) + elseif isMonster(c) then + c:remove() + end + end + end + end + end + end + end + stopEvent(areaCrackler1) + stopEvent(areaCrackler2) +end + +local function createVortex() + local positions1 = { + {x = 32197, y = 31322, z = 14}, + {x = 32202, y = 31328, z = 14}, + {x = 32208, y = 31324, z = 14}, + {x = 32210, y = 31334, z = 14}, + } + + local positions2 = { + {x = 32202, y = 31325, z = 14}, + {x = 32201, y = 31334, z = 14}, + {x = 32215, y = 31332, z = 14}, + {x = 32208, y = 31320, z = 14}, + } + + local positions3 = { + {x = 32199, y = 31329, z = 14}, + {x = 32207, y = 31335, z = 14}, + {x = 32208, y = 31327, z = 14}, + {x = 32213, y = 31322, z = 14}, + } + + local positions4 = { + {x = 32203, y = 31319, z = 14}, + {x = 32205, y = 31325, z = 14}, + {x = 32212, y = 31330, z = 14}, + {x = 32219, y = 31328, z = 14}, + } + local tempo = 10 + if vortexPositions == 0 then + for i = 1, #positions1 do + local items = Tile(Position(positions1[i])):getGround() + items:transform(26127) + addEvent(function() + items:transform(25707) + end, tempo*1000) + end + vortexPositions = 1 + elseif vortexPositions == 1 then + for i = 1, #positions2 do + local items = Tile(Position(positions2[i])):getGround() + items:transform(26127) + addEvent(function() + items:transform(25707) + end, tempo*1000) + end + vortexPositions = 2 + elseif vortexPositions == 2 then + for i = 1, #positions3 do + local items = Tile(Position(positions3[i])):getGround() + items:transform(26127) + addEvent(function() + items:transform(25707) + end, tempo*1000) + end + vortexPositions = 3 + elseif vortexPositions == 3 then + for i = 1, #positions4 do + local items = Tile(Position(positions4[i])):getGround() + items:transform(26127) + addEvent(function() + items:transform(25707) + end, tempo*1000) + end + vortexPositions = 0 + end + + cracklerTransform = false + areaCrackler2 = addEvent(createVortex, tempo*1000) +end +-- FUNCTIONS END + +local heartDestructionCracklers = Action() +function heartDestructionCracklers.onUse(player, item, fromPosition, itemEx, toPosition) + + local config = { + playerPositions = { + Position(32079, 31313, 13), + Position(32079, 31314, 13), + Position(32079, 31315, 13), + Position(32079, 31316, 13), + Position(32079, 31317, 13) + }, + + newPos = {x = 32219, y = 31325, z = 14}, + } + + local pushPos = {x = 32079, y = 31313, z = 13} + + if item.actionid == 14326 then + if item.itemid == 9825 then + if player:getPosition().x == pushPos.x and player:getPosition().y == pushPos.y and player:getPosition().z == pushPos.z then + + local storePlayers, playerTile = {} + for i = 1, #config.playerPositions do + playerTile = Tile(config.playerPositions[i]):getTopCreature() + if isPlayer(playerTile) then + storePlayers[#storePlayers + 1] = playerTile + end + end + + if #storePlayers < 4 then + player:sendTextMessage(19, "You need at least 4 players to this mission.") + return true + end + + if doCheckArea() == false then + clearArea() + + local players + + for i = 1, #storePlayers do + players = storePlayers[i] + config.playerPositions[i]:sendMagicEffect(CONST_ME_POFF) + players:teleportTo(config.newPos) + end + Position(config.newPos):sendMagicEffect(11) + + areaCrackler1 = addEvent(clearArea, 15 * 60000) + + Game.createMonster("Crackler", {x = 32200, y = 31322, z = 14}, false, true) + Game.createMonster("Crackler", {x = 32202, y = 31327, z = 14}, false, true) + Game.createMonster("Crackler", {x = 32199, y = 31330, z = 14}, false, true) + Game.createMonster("Crackler", {x = 32201, y = 31334, z = 14}, false, true) + Game.createMonster("Crackler", {x = 32207, y = 31335, z = 14}, false, true) + Game.createMonster("Crackler", {x = 32211, y = 31334, z = 14}, false, true) + Game.createMonster("Crackler", {x = 32215, y = 31332, z = 14}, false, true) + Game.createMonster("Crackler", {x = 32208, y = 31327, z = 14}, false, true) + Game.createMonster("Crackler", {x = 32207, y = 31323, z = 14}, false, true) + Game.createMonster("Crackler", {x = 32213, y = 31323, z = 14}, false, true) + + Game.setStorageValue(14323, 0) -- Depolarized Cracklers Count + vortexPositions = 0 + createVortex() + else + player:sendTextMessage(19, "Someone is in the area.") + end + else + return true + end + end + item:transform(item.itemid == 9825 and 9826 or 9825) + end + + return true +end + +heartDestructionCracklers:aid(14326) +heartDestructionCracklers:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/heart_of_destruction/devourer_access.lua b/data/scripts/actions/quests/heart_of_destruction/devourer_access.lua new file mode 100644 index 00000000000..d7db3ca3154 --- /dev/null +++ b/data/scripts/actions/quests/heart_of_destruction/devourer_access.lua @@ -0,0 +1,16 @@ +local heartDestructionDevourer = Action() +function heartDestructionDevourer.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + if player:getStorageValue(14333) > os.time() then + player:setStorageValue(14333, -1) + player:sendTextMessage(19, "You access to World Devourer was released!") + item:transform(26343) + else + player:sendTextMessage(19, "You access to World Devourer is already released!") + end + + return true +end + +heartDestructionDevourer:id(26342) +heartDestructionDevourer:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/heart_of_destruction/eradicator_lever.lua b/data/scripts/actions/quests/heart_of_destruction/eradicator_lever.lua new file mode 100644 index 00000000000..72ff8a49941 --- /dev/null +++ b/data/scripts/actions/quests/heart_of_destruction/eradicator_lever.lua @@ -0,0 +1,127 @@ +-- FUNCTIONS +local function doCheckArea() + local upConer = {x = 32297, y = 31272, z = 14} -- upLeftCorner + local downConer = {x = 32321, y = 31296, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k = upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + return true + end + end + end + end + end + end + end + return false +end + +local function clearArea() + local upConer = {x = 32297, y = 31272, z = 14} -- upLeftCorner + local downConer = {x = 32321, y = 31296, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k= upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + c:teleportTo({x = 32218, y = 31375, z = 11}) + elseif isMonster(c) then + c:remove() + end + end + end + end + end + end + end + stopEvent(areaEradicator1) + stopEvent(areaEradicator2) +end +-- FUNCTIONS END + +local heartDestructionEradicator = Action() +function heartDestructionEradicator.onUse(player, item, fromPosition, itemEx, toPosition) + + local config = { + playerPositions = { + Position(32334, 31284, 14), + Position(32334, 31285, 14), + Position(32334, 31286, 14), + Position(32334, 31287, 14), + Position(32334, 31288, 14) + }, + + newPos = {x = 32309, y = 31290, z = 14}, + } + + local pushPos = {x = 32334, y = 31284, z = 14} + + if item.actionid == 14330 then + if item.itemid == 9825 then + if player:getPosition().x == pushPos.x and player:getPosition().y == pushPos.y and player:getPosition().z == pushPos.z then + + local storePlayers, playerTile = {} + for i = 1, #config.playerPositions do + playerTile = Tile(config.playerPositions[i]):getTopCreature() + if isPlayer(playerTile) then + storePlayers[#storePlayers + 1] = playerTile + end + end + + if doCheckArea() == false then + clearArea() + + local players + + for i = 1, #storePlayers do + players = storePlayers[i] + config.playerPositions[i]:sendMagicEffect(CONST_ME_POFF) + players:teleportTo(config.newPos) + players:setStorageValue(14329, os.time() + 20*60*60) + end + Position(config.newPos):sendMagicEffect(11) + + eradicatorReleaseT = false -- Liberar Spell + eradicatorWeak = 0 -- Eradicator Form + areaEradicator1 = addEvent(clearArea, 15 * 60000) + areaEradicator2 = addEvent(function() eradicatorReleaseT = true end, 74000) + + Game.createMonster("Spark of Destruction", {x = 32304, y = 31282, z = 14}, false, true) + Game.createMonster("Spark of Destruction", {x = 32305, y = 31287, z = 14}, false, true) + Game.createMonster("Spark of Destruction", {x = 32312, y = 31287, z = 14}, false, true) + Game.createMonster("Spark of Destruction", {x = 32314, y = 31282, z = 14}, false, true) + Game.createMonster("Eradicator", {x = 32309, y = 31283, z = 14}, false, true) + + local vortex = Tile({x = 32318, y = 31284, z = 14}):getItemById(26138) + if vortex then + vortex:transform(26139) + vortex:setActionId(14348) + end + else + player:sendTextMessage(19, "Someone is in the area.") + end + else + return true + end + end + item:transform(item.itemid == 9825 and 9826 or 9825) + end + return true +end + +heartDestructionEradicator:aid(14330) +heartDestructionEradicator:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/heart_of_destruction/final_lever.lua b/data/scripts/actions/quests/heart_of_destruction/final_lever.lua new file mode 100644 index 00000000000..0c776047b9c --- /dev/null +++ b/data/scripts/actions/quests/heart_of_destruction/final_lever.lua @@ -0,0 +1,473 @@ +--[[ +Storages: +The Hunger = 14334 +The Destruction = 14335 +The Rage = 14336 +]]-- +-- FUNCTIONS +function sparkDevourerSpawn() + local positions = { + {x = 32268, y = 31341, z = 14}, + {x = 32275, y = 31342, z = 14}, + {x = 32269, y = 31352, z = 14}, + {x = 32277, y = 31351, z = 14} + } + + if sparkSpawnCount > 0 then + for i = 1, sparkSpawnCount do + Game.createMonster("Spark of Destruction2", positions[i], false, true) + end + sparkSpawnCount = 0 + end + areaDevourer6 = addEvent(sparkDevourerSpawn, 10000) +end + +local function doCheckArea() + local upConer = {x = 32260, y = 31336, z = 14} -- upLeftCorner + local downConer = {x = 32283, y = 31360, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k = upConer.z, downConer.z do + local tile = Tile(i, j, k) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + return true + end + end + end + end + end + end + end + + for _, online in ipairs(Game.getPlayers()) do + if online:isPlayer() then + if online:getStorageValue(14334) >= 1 or online:getStorageValue(14335) >= 1 or online:getStorageValue(14336) >= 1 then + return true + end + end + end + + return false +end + +local function changeArea() + local function organizeHunger() + local upConer = {x = 32233, y = 31360, z = 14} -- upLeftCorner + local downConer = {x = 32256, y = 31384, z = 14} -- downRightCorner + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k = upConer.z, downConer.z do + local tile = Tile(i, j, k) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + if theHungerKilled == false then + for _, c in pairs(creatures) do + if isMonster(c) then + c:teleportTo({x = 32244, y = 31369, z = 14}) + end + end + else + devourerBossesKilled = devourerBossesKilled - 1 + Game.createMonster("The Hunger", {x = 32244, y = 31372, z = 14}, false, true) + theHungerKilled = false + end + end + end + end + end + end + end + + local function organizeDestruction() + local upConer = {x = 32260, y = 31304, z = 14} -- upLeftCorner + local downConer = {x = 32283, y = 31328, z = 14} -- downRightCorner + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k = upConer.z, downConer.z do + local tile = Tile(i, j, k) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + if theDestructionKilled == false then + for _, c in pairs(creatures) do + if isMonster(c) then + c:teleportTo({x = 32271, y = 31313, z = 14}) + end + end + else + devourerBossesKilled = devourerBossesKilled - 1 + Game.createMonster("The Destruction", {x = 32271, y = 31316, z = 14}, false, true) + theDestructionKilled = false + end + end + end + end + end + end + end + + local function organizeRage() + local upConer = {x = 32288, y = 31360, z = 14} -- upLeftCorner + local downConer = {x = 32311, y = 31384, z = 14} -- downRightCorner + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k = upConer.z, downConer.z do + local tile = Tile(i, j, k) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + if theRageKilled == false then + for _, c in pairs(creatures) do + if isMonster(c) then + c:teleportTo({x = 32299, y = 31369, z = 14}) + end + end + else + devourerBossesKilled = devourerBossesKilled - 1 + Game.createMonster("The Rage", {x = 32299, y = 31372, z = 14}, false, true) + theRageKilled = false + end + end + end + end + end + end + end + + if devourerBossesKilled < 3 then + for _, online in ipairs(Game.getPlayers()) do + if online:isPlayer() then + -- Teleport players from The Hunger to The Rage + if online:getStorageValue(14334) >= 1 then + online:setStorageValue(14334, -1) + online:setStorageValue(14336, 1) + online:teleportTo({x = 32299, y = 31372, z = 14}) + online:say("A polarity shift moves you into another part of the heart of destruction.", TALKTYPE_MONSTER_SAY) + Position({x = 32299, y = 31372, z = 14}):sendMagicEffect(11) + -- Teleport players from The Destruction to The Hunger + elseif online:getStorageValue(14335) >= 1 then + online:setStorageValue(14335, -1) + online:setStorageValue(14334, 1) + online:teleportTo({x = 32244, y = 31372, z = 14}) + online:say("A polarity shift moves you into another part of the heart of destruction.", TALKTYPE_MONSTER_SAY) + Position({x = 32244, y = 31372, z = 14}):sendMagicEffect(11) + -- Teleport players from The Rage to The Destruction + elseif online:getStorageValue(14336) >= 1 then + online:setStorageValue(14336, -1) + online:setStorageValue(14335, 1) + online:teleportTo({x = 32271, y = 31316, z = 14}) + online:say("A polarity shift moves you into another part of the heart of destruction.", TALKTYPE_MONSTER_SAY) + Position({x = 32271, y = 31316, z = 14}):sendMagicEffect(11) + end + end + end + organizeHunger() + organizeDestruction() + organizeRage() + areaDevourer4 = addEvent(changeArea, 30000) + else + stopEvent(areaDevourer1) + stopEvent(areaDevourer2) + stopEvent(areaDevourer3) + stopEvent(areaDevourer4) + for _, online in ipairs(Game.getPlayers()) do + if online:isPlayer() then + if online:getStorageValue(14334) >= 1 then + online:setStorageValue(14334, -1) + online:unregisterEvent("DevourerStorage") + online:teleportTo({x = 32271, y = 31357, z = 14}) + Position({x = 32271, y = 31357, z = 14}):sendMagicEffect(11) + elseif online:getStorageValue(14335) >= 1 then + online:setStorageValue(14335, -1) + online:unregisterEvent("DevourerStorage") + online:teleportTo({x = 32272, y = 31357, z = 14}) + Position({x = 32272, y = 31357, z = 14}):sendMagicEffect(11) + elseif online:getStorageValue(14336) >= 1 then + online:setStorageValue(14336, -1) + online:unregisterEvent("DevourerStorage") + online:teleportTo({x = 32273, y = 31357, z = 14}) + Position({x = 32273, y = 31357, z = 14}):sendMagicEffect(11) + end + end + end + local spectators = Game.getSpectators(Position(32271, 31348, 14), false, true, 10, 10, 10, 10) + if #spectators > 0 then + for i = 1, #spectators do + spectators[i]:say("With the Rage, Hunger and Destruction gone, you're sucked into the heart of destruction!! THE WORLD DEVOURER AWAITS YOU!", TALKTYPE_MONSTER_YELL, false, spectators[i], Position(32271, 31348, 14)) + end + end + + Game.createMonster("World Devourer", {x = 32271, y = 31347, z = 14}, false, true) + Game.createMonster("Spark of Destruction2", {x = 32268, y = 31341, z = 14}, false, true) + Game.createMonster("Spark of Destruction2", {x = 32275, y = 31342, z = 14}, false, true) + Game.createMonster("Spark of Destruction2", {x = 32269, y = 31352, z = 14}, false, true) + Game.createMonster("Spark of Destruction2", {x = 32277, y = 31351, z = 14}, false, true) + sparkSpawnCount = 0 + devourerSummon = 0 + areaDevourer5 = addEvent(clearDevourer, 30 * 60000) + areaDevourer6 = addEvent(sparkDevourerSpawn, 10000) + end +end + +local function clearHunger() + local upConer = {x = 32233, y = 31360, z = 14} -- upLeftCorner + local downConer = {x = 32256, y = 31384, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k = upConer.z, downConer.z do + local tile = Tile(i, j, k) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + c:teleportTo({x = 32208, y = 31372, z = 14}) + elseif isMonster(c) and c:getName() ~= "Spark of Destruction" then + c:remove() + end + end + end + end + end + end + end + stopEvent(areaDevourer1) +end + +local function clearDestruction() + local upConer = {x = 32260, y = 31304, z = 14} -- upLeftCorner + local downConer = {x = 32283, y = 31328, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k = upConer.z, downConer.z do + local tile = Tile(i, j, k) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + c:teleportTo({x = 32208, y = 31372, z = 14}) + elseif isMonster(c) and c:getName() ~= "Spark of Destruction" then + c:remove() + end + end + end + end + end + end + end + stopEvent(areaDevourer2) +end + +local function clearRage() + local upConer = {x = 32288, y = 31360, z = 14} -- upLeftCorner + local downConer = {x = 32311, y = 31384, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k = upConer.z, downConer.z do + local tile = Tile(i, j, k) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + c:teleportTo({x = 32208, y = 31372, z = 14}) + elseif isMonster(c) and c:getName() ~= "Spark of Destruction" then + c:remove() + end + end + end + end + end + end + end + stopEvent(areaDevourer3) +end + +function clearDevourer() + local upConer = {x = 32260, y = 31336, z = 14} -- upLeftCorner + local downConer = {x = 32283, y = 31360, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k = upConer.z, downConer.z do + local tile = Tile(i, j, k) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + c:teleportTo({x = 32208, y = 31372, z = 14}) + elseif isMonster(c) then + c:remove() + end + end + end + end + end + end + end + stopEvent(areaDevourer4) + stopEvent(areaDevourer5) + stopEvent(areaDevourer6) +end +-- FUNCTIONS END + +local heartDestructionFinal = Action() +function heartDestructionFinal.onUse(player, item, fromPosition, itemEx, toPosition) + + local config = { + hungerPositions = { + Position(32271, 31374, 14), + Position(32271, 31375, 14), + Position(32271, 31376, 14), + Position(32271, 31377, 14), + Position(32271, 31378, 14) + }, + + destructionPositions = { + Position(32272, 31374, 14), + Position(32272, 31375, 14), + Position(32272, 31376, 14), + Position(32272, 31377, 14), + Position(32272, 31378, 14) + }, + + ragePositions = { + Position(32273, 31374, 14), + Position(32273, 31375, 14), + Position(32273, 31376, 14), + Position(32273, 31377, 14), + Position(32273, 31378, 14) + }, + + hungerNewPos = {x = 32244, y = 31381, z = 14}, + destructionNewPos = {x = 32271, y = 31325, z = 14}, + rageNewPos = {x = 32299, y = 31381, z = 14}, + } + + local pushPos = {x = 32272, y = 31374, z = 14} + + if item.actionid == 14332 then + if item.itemid == 9825 then + if player:getPosition().x == pushPos.x and player:getPosition().y == pushPos.y and player:getPosition().z == pushPos.z then + + local storeHunger, hungerTile = {} + local storeDestruction, destructionTile = {} + local storeRage, rageTile = {} + + for i = 1, #config.hungerPositions do + hungerTile = Tile(config.hungerPositions[i]):getTopCreature() + if isPlayer(hungerTile) then + storeHunger[#storeHunger + 1] = hungerTile + end + end + + for i = 1, #config.destructionPositions do + destructionTile = Tile(config.destructionPositions[i]):getTopCreature() + if isPlayer(destructionTile) then + storeDestruction[#storeDestruction + 1] = destructionTile + end + end + + for i = 1, #config.ragePositions do + rageTile = Tile(config.ragePositions[i]):getTopCreature() + if isPlayer(rageTile) then + storeRage[#storeRage + 1] = rageTile + end + end + + if #storeHunger < 1 or #storeDestruction < 1 or #storeRage < 1 then + player:sendTextMessage(19, "You need at least 3 players, each in a column.") + return true + end + + if doCheckArea() == false then + clearHunger() + clearDestruction() + clearRage() + clearDevourer() + + local teamHunger + local teamDestruction + local teamRage + + for i = 1, #storeHunger do + teamHunger = storeHunger[i] + config.hungerPositions[i]:sendMagicEffect(CONST_ME_POFF) + teamHunger:teleportTo(config.hungerNewPos) + teamHunger:setStorageValue(14333, os.time() + 7*24*60*60) + teamHunger:setStorageValue(14334, 1) --storage Hunger + teamHunger:registerEvent("DevourerStorage") + end + + for i = 1, #storeDestruction do + teamDestruction = storeDestruction[i] + config.destructionPositions[i]:sendMagicEffect(CONST_ME_POFF) + teamDestruction:teleportTo(config.destructionNewPos) + teamDestruction:setStorageValue(14333, os.time() + 7*24*60*60) + teamDestruction:setStorageValue(14335, 1) --storage Destruction + teamDestruction:registerEvent("DevourerStorage") + end + + for i = 1, #storeRage do + teamRage = storeRage[i] + config.ragePositions[i]:sendMagicEffect(CONST_ME_POFF) + teamRage:teleportTo(config.rageNewPos) + teamRage:setStorageValue(14333, os.time() + 7*24*60*60) + teamRage:setStorageValue(14336, 1) --storage Rage + teamRage:registerEvent("DevourerStorage") + end + + Position(config.hungerNewPos):sendMagicEffect(11) + Position(config.destructionNewPos):sendMagicEffect(11) + Position(config.rageNewPos):sendMagicEffect(11) + + areaDevourer1 = addEvent(clearHunger, 30 * 60000) + areaDevourer2 = addEvent(clearDestruction, 30 * 60000) + areaDevourer3 = addEvent(clearRage, 30 * 60000) + areaDevourer4 = addEvent(changeArea, 30000) --mudar + + --Variables + devourerBossesKilled = 0 + theHungerKilled = false + theDestructionKilled = false + theRageKilled = false + + hungerSummon = 0 + rageSummon = 0 + destructionSummon = 0 + devourerSummon = 0 + + Game.createMonster("The Hunger", {x = 32244, y = 31372, z = 14}, false, true) + Game.createMonster("The Destruction", {x = 32271, y = 31316, z = 14}, false, true) + Game.createMonster("The Rage", {x = 32299, y = 31372, z = 14}, false, true) + + local vortex = Tile({x = 32281, y = 31348, z = 14}):getItemById(26138) + if vortex then + vortex:transform(26139) + vortex:setActionId(14352) + end + else + player:sendTextMessage(19, "Someone is in the area.") + end + else + return true + end + end + item:transform(item.itemid == 9825 and 9826 or 9825) + end + return true +end + +heartDestructionFinal:aid(14332) +heartDestructionFinal:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/heart_of_destruction/outburst_lever.lua b/data/scripts/actions/quests/heart_of_destruction/outburst_lever.lua new file mode 100644 index 00000000000..5616482a2fc --- /dev/null +++ b/data/scripts/actions/quests/heart_of_destruction/outburst_lever.lua @@ -0,0 +1,126 @@ +-- FUNCTIONS +local function doCheckArea() + local upConer = {x = 32223, y = 31273, z = 14} -- upLeftCorner + local downConer = {x = 32246, y = 31297, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k = upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + return true + end + end + end + end + end + end + end + return false +end + +local function clearArea() + local upConer = {x = 32223, y = 31273, z = 14} -- upLeftCorner + local downConer = {x = 32246, y = 31297, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k= upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + c:teleportTo({x = 32208, y = 31372, z = 14}) + elseif isMonster(c) then + c:remove() + end + end + end + end + end + end + end + stopEvent(areaOutburst1) +end +-- FUNCTIONS END + +local heartDestructionOutburst = Action() +function heartDestructionOutburst.onUse(player, item, fromPosition, itemEx, toPosition) + + local config = { + playerPositions = { + Position(32207, 31284, 14), + Position(32207, 31285, 14), + Position(32207, 31286, 14), + Position(32207, 31287, 14), + Position(32207, 31288, 14) + }, + + newPos = {x = 32234, y = 31292, z = 14}, + } + + local pushPos = {x = 32207, y = 31284, z = 14} + + if item.actionid == 14331 then + if item.itemid == 9825 then + if player:getPosition().x == pushPos.x and player:getPosition().y == pushPos.y and player:getPosition().z == pushPos.z then + + local storePlayers, playerTile = {} + for i = 1, #config.playerPositions do + playerTile = Tile(config.playerPositions[i]):getTopCreature() + if isPlayer(playerTile) then + storePlayers[#storePlayers + 1] = playerTile + end + end + + if doCheckArea() == false then + clearArea() + + local players + + for i = 1, #storePlayers do + players = storePlayers[i] + config.playerPositions[i]:sendMagicEffect(CONST_ME_POFF) + players:teleportTo(config.newPos) + players:setStorageValue(14331, os.time() + 20*60*60) + end + Position(config.newPos):sendMagicEffect(11) + + areaOutburst1 = addEvent(clearArea, 15 * 60000) + + Game.createMonster("Spark of Destruction", {x = 32229, y = 31282, z = 14}, false, true) + Game.createMonster("Spark of Destruction", {x = 32230, y = 31287, z = 14}, false, true) + Game.createMonster("Spark of Destruction", {x = 32237, y = 31287, z = 14}, false, true) + Game.createMonster("Spark of Destruction", {x = 32238, y = 31282, z = 14}, false, true) + Game.createMonster("Outburst", {x = 32234, y = 31284, z = 14}, false, true) + + outburstStage = 0 + outburstHealth = 290000 + + local vortex = Tile({x = 32225, y = 31285, z = 14}):getItemById(26138) + if vortex then + vortex:transform(26139) + vortex:setActionId(14350) + end + else + player:sendTextMessage(19, "Someone is in the area.") + end + else + return true + end + end + item:transform(item.itemid == 9825 and 9826 or 9825) + end + return true +end + +heartDestructionOutburst:aid(14331) +heartDestructionOutburst:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/heart_of_destruction/quake_lever.lua b/data/scripts/actions/quests/heart_of_destruction/quake_lever.lua new file mode 100644 index 00000000000..6694540a36a --- /dev/null +++ b/data/scripts/actions/quests/heart_of_destruction/quake_lever.lua @@ -0,0 +1,129 @@ +-- FUNCTIONS +local function doCheckArea() + local upConer = {x = 32197, y = 31236, z = 14} -- upLeftCorner + local downConer = {x = 32220, y = 31260, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k = upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + return true + end + end + end + end + end + end + end + return false +end + +local function clearArea() + local upConer = {x = 32197, y = 31236, z = 14} -- upLeftCorner + local downConer = {x = 32220, y = 31260, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k= upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + c:teleportTo({x = 32230, y = 31358, z = 11}) + elseif isMonster(c) then + c:remove() + end + end + end + end + end + end + end + stopEvent(areaQuake1) +end +-- FUNCTIONS END + +local heartDestructionQuake = Action() +function heartDestructionQuake.onUse(player, item, fromPosition, itemEx, toPosition) + + local config = { + playerPositions = { + Position(32182, 31244, 14), + Position(32182, 31245, 14), + Position(32182, 31246, 14), + Position(32182, 31247, 14), + Position(32182, 31248, 14) + }, + + newPos = {x = 32208, y = 31256, z = 14}, + } + + local pushPos = {x = 32182, y = 31244, z = 14} + + if item.actionid == 14329 then + if item.itemid == 9825 then + if player:getPosition().x == pushPos.x and player:getPosition().y == pushPos.y and player:getPosition().z == pushPos.z then + + local storePlayers, playerTile = {} + for i = 1, #config.playerPositions do + playerTile = Tile(config.playerPositions[i]):getTopCreature() + if isPlayer(playerTile) then + storePlayers[#storePlayers + 1] = playerTile + end + end + + if doCheckArea() == false then + clearArea() + + local players + + for i = 1, #storePlayers do + players = storePlayers[i] + config.playerPositions[i]:sendMagicEffect(CONST_ME_POFF) + players:teleportTo(config.newPos) + players:setStorageValue(14325, os.time() + 20*60*60) + end + Position(config.newPos):sendMagicEffect(11) + + areaQuake1 = addEvent(clearArea, 15 * 60000) + + Game.createMonster("Spark of Destruction", {x = 32203, y = 31246, z = 14}, false, true) + Game.createMonster("Spark of Destruction", {x = 32205, y = 31251, z = 14}, false, true) + Game.createMonster("Spark of Destruction", {x = 32210, y = 31251, z = 14}, false, true) + Game.createMonster("Spark of Destruction", {x = 32212, y = 31246, z = 14}, false, true) + Game.createMonster("Foreshock", {x = 32208, y = 31248, z = 14}, false, true) + + foreshockHealth = 105000 + aftershockHealth = 105000 + realityQuakeStage = 0 + foreshockStage = 0 + aftershockStage = 0 + + local vortex = Tile({x = 32199, y = 31248, z = 14}):getItemById(26138) + if vortex then + vortex:transform(26139) + vortex:setActionId(14345) + end + else + player:sendTextMessage(19, "Someone is in the area.") + end + else + return true + end + end + item:transform(item.itemid == 9825 and 9826 or 9825) + end + return true +end + +heartDestructionQuake:aid(14329) +heartDestructionQuake:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/heart_of_destruction/reward.lua b/data/scripts/actions/quests/heart_of_destruction/reward.lua new file mode 100644 index 00000000000..db429ad7601 --- /dev/null +++ b/data/scripts/actions/quests/heart_of_destruction/reward.lua @@ -0,0 +1,25 @@ +local heartDestructionReward = Action() +function heartDestructionReward.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + if item.uid == 1038 then + if player:getStorageValue(14337) < 1 then + local container = player:addItem(26181) + container:addItem(26168, 1) + container:addItem(26194, 1) + container:addItem(26192, 1) + container:addItem(26165, 1) + container:addItem(2160, 20) + container:addItem(25377, 5) + player:setStorageValue(14337, 1) + player:addAchievement("Ender of the End") + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found an energetic backpack.") + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The chest is empty.") + end + end + + return true +end + +heartDestructionReward:uid(1038) +heartDestructionReward:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/heart_of_destruction/rupture_lever.lua b/data/scripts/actions/quests/heart_of_destruction/rupture_lever.lua new file mode 100644 index 00000000000..1bb26846a98 --- /dev/null +++ b/data/scripts/actions/quests/heart_of_destruction/rupture_lever.lua @@ -0,0 +1,125 @@ +-- FUNCTIONS +local function doCheckArea() + local upConer = {x = 32324, y = 31239, z = 14} -- upLeftCorner + local downConer = {x = 32347, y = 31263, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k = upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + return true + end + end + end + end + end + end + end + return false +end + +local function clearArea() + local upConer = {x = 32324, y = 31239, z = 14} -- upLeftCorner + local downConer = {x = 32347, y = 31263, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k= upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + c:teleportTo({x = 32088, y = 31321, z = 13}) + elseif isMonster(c) then + c:remove() + end + end + end + end + end + end + end +end +-- FUNCTIONS END + +local heartDestructionRupture = Action() +function heartDestructionRupture.onUse(player, item, fromPosition, itemEx, toPosition) + + local config = { + playerPositions = { + Position(32309, 31248, 14), + Position(32309, 31249, 14), + Position(32309, 31250, 14), + Position(32309, 31251, 14), + Position(32309, 31252, 14) + }, + + newPos = {x = 32335, y = 31257, z = 14}, + } + + local pushPos = {x = 32309, y = 31248, z = 14} + + if item.actionid == 14327 then + if item.itemid == 9825 then + if player:getPosition().x == pushPos.x and player:getPosition().y == pushPos.y and player:getPosition().z == pushPos.z then + + local storePlayers, playerTile = {} + for i = 1, #config.playerPositions do + playerTile = Tile(config.playerPositions[i]):getTopCreature() + if isPlayer(playerTile) then + storePlayers[#storePlayers + 1] = playerTile + end + end + + if doCheckArea() == false then + clearArea() + + local players + + for i = 1, #storePlayers do + players = storePlayers[i] + config.playerPositions[i]:sendMagicEffect(CONST_ME_POFF) + players:teleportTo(config.newPos) + players:setStorageValue(14323, os.time() + 20*60*60) + end + Position(config.newPos):sendMagicEffect(11) + + areaRupture1 = addEvent(clearArea, 15 * 60000) + + ruptureResonanceStage = 0 + resonanceActive = false + + Game.createMonster("Spark of Destruction", {x = 32331, y = 31254, z = 14}, false, true) + Game.createMonster("Spark of Destruction", {x = 32338, y = 31254, z = 14}, false, true) + Game.createMonster("Spark of Destruction", {x = 32330, y = 31250, z = 14}, false, true) + Game.createMonster("Spark of Destruction", {x = 32338, y = 31250, z = 14}, false, true) + Game.createMonster("Rupture", {x = 32332, y = 31250, z = 14}, false, true) + + local vortex = Tile({x = 32326, y = 31250, z = 14}):getItemById(26138) + if vortex then + vortex:transform(26139) + vortex:setActionId(14343) + end + else + player:sendTextMessage(19, "Someone is in the area.") + end + else + return true + end + end + item:transform(item.itemid == 9825 and 9826 or 9825) + end + return true +end + +heartDestructionRupture:aid(14327) +heartDestructionRupture:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/heart_of_destruction/sparkion_eggs.lua b/data/scripts/actions/quests/heart_of_destruction/sparkion_eggs.lua new file mode 100644 index 00000000000..98d66306cb9 --- /dev/null +++ b/data/scripts/actions/quests/heart_of_destruction/sparkion_eggs.lua @@ -0,0 +1,26 @@ +local heartDestructionEggs = Action() +function heartDestructionEggs.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local config = { + [26194] = {mountId = 94, message = "You receive the permission to ride a sparkion"}, + [26340] = {mountId = 98, message = "You receive the permission to ride a neon sparkid"}, + [26341] = {mountId = 99, message = "You receive the permission to ride a vortexion"}, + } + + local mount = config[item.itemid] + + if not mount then + return true + end + + if not player:hasMount(mount.mountId) then + player:addMount(mount.mountId) + player:say(mount.message, TALKTYPE_MONSTER_SAY) + item:remove(1) + else + player:sendTextMessage(19, "You already have this mount") + end + return true +end + +heartDestructionEggs:id(26194,26340,26341) +heartDestructionEggs:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/heart_of_destruction/sparks_lever.lua b/data/scripts/actions/quests/heart_of_destruction/sparks_lever.lua new file mode 100644 index 00000000000..71aa83d06a0 --- /dev/null +++ b/data/scripts/actions/quests/heart_of_destruction/sparks_lever.lua @@ -0,0 +1,197 @@ +local function shuffleTable(t, count, ri, rj) + ri = ri or 1 + rj = rj or #t + for x = 1, count or 1 do + for i = rj, ri + 1, -1 do + local j = math.random(ri, rj) + t[i], t[j] = t[j], t[i] + end + end +end + +local function doCheckArea() + local upConer = {x = 32126, y = 31296, z = 14} -- upLeftCorner + local downConer = {x = 32162, y = 31322, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k = upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + return true + end + end + end + end + end + end + end + return false +end + +local function clearArea() + local upConer = {x = 32126, y = 31296, z = 14} -- upLeftCorner + local downConer = {x = 32162, y = 31322, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k= upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + c:teleportTo({x = 32225, y = 31347, z = 11}) + elseif isMonster(c) then + c:remove() + end + end + end + end + end + end + end + stopEvent(areaSparks1) + stopEvent(areaSparks2) + stopEvent(areaSparks3) + stopEvent(areaSparks4) +end + +function createSparks() + + local positions = { + {x = 32132, y = 31306, z = 14}, + {x = 32133, y = 31309, z = 14}, + {x = 32132, y = 31312, z = 14}, + {x = 32136, y = 31302, z = 14}, + {x = 32136, y = 31307, z = 14}, + {x = 32137, y = 31311, z = 14}, + {x = 32138, y = 31314, z = 14}, + {x = 32139, y = 31304, z = 14}, + {x = 32141, y = 31307, z = 14}, + {x = 32141, y = 31310, z = 14}, + {x = 32141, y = 31315, z = 14}, + {x = 32145, y = 31317, z = 14}, + {x = 32144, y = 31313, z = 14}, + {x = 32145, y = 31309, z = 14}, + {x = 32145, y = 31302, z = 14}, + {x = 32149, y = 31304, z = 14}, + {x = 32152, y = 31302, z = 14}, + {x = 32154, y = 31305, z = 14}, + {x = 32148, y = 31315, z = 14}, + {x = 32150, y = 31312, z = 14}, + {x = 32153, y = 31315, z = 14}, + {x = 32157, y = 31313, z = 14}, + {x = 32154, y = 31310, z = 14}, + {x = 32157, y = 31308, z = 14}, + {x = 32157, y = 31302, z = 14}, + } + + if unstableSparksCount < 11 then + shuffleTable(positions, 2, ri, rj) + + for i = 1, 15 do + Game.createMonster("Unstable Spark", positions[i], false, true) + end + + areaSparks3 = addEvent(renewSparks, 7000) + end +end + +function renewSparks() + local upConer = {x = 32126, y = 31296, z = 14} -- upLeftCorner + local downConer = {x = 32162, y = 31322, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k= upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + local cPos = c:getPosition() + if isMonster(c) and c:getName() == "Unstable Spark" then + cPos:sendMagicEffect(3) + c:remove() + end + end + end + end + end + end + end + areaSparks4 = addEvent(createSparks, 1000) +end + +-- FUNCTIONS END +local heartDestructionSparks = Action() +function heartDestructionSparks.onUse(player, item, fromPosition, itemEx, toPosition) + + local config = { + playerPositions = { + Position(32227, 31343, 11), + Position(32227, 31344, 11), + Position(32227, 31345, 11), + Position(32227, 31346, 11), + Position(32227, 31347, 11) + }, + + newPos = {x = 32151, y = 31301, z = 14}, + } + + local pushPos = {x = 32227, y = 31343, z = 11} + + if item.actionid == 14328 then + if item.itemid == 9825 then + if player:getPosition().x == pushPos.x and player:getPosition().y == pushPos.y and player:getPosition().z == pushPos.z then + + local storePlayers, playerTile = {} + for i = 1, #config.playerPositions do + playerTile = Tile(config.playerPositions[i]):getTopCreature() + if isPlayer(playerTile) then + storePlayers[#storePlayers + 1] = playerTile + end + end + + if doCheckArea() == false then + clearArea() + + local players + + for i = 1, #storePlayers do + players = storePlayers[i] + config.playerPositions[i]:sendMagicEffect(CONST_ME_POFF) + players:teleportTo(config.newPos) + end + Position(config.newPos):sendMagicEffect(11) + + areaSparks1 = addEvent(clearArea, 15 * 60000) + areaSparks2 = addEvent(createSparks, 10000) + + unstableSparksCount = 0 + --Game.createMonster("Crackler", {x = 32200, y = 31322, z = 14}, false, true) + player:say("The room slowly beginns to crackle. An erruption seems imanent!", TALKTYPE_MONSTER_YELL, isInGhostMode, pid, {x = 32143, y = 31308, z = 14}) + else + player:sendTextMessage(19, "Someone is in the area.") + end + else + return true + end + end + item:transform(item.itemid == 9825 and 9826 or 9825) + end + + return true +end + +heartDestructionSparks:aid(14328) +heartDestructionSparks:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/hero_of_rathleton/machines_deep_terror.lua b/data/scripts/actions/quests/hero_of_rathleton/machines_deep_terror.lua new file mode 100644 index 00000000000..a7070b978c9 --- /dev/null +++ b/data/scripts/actions/quests/hero_of_rathleton/machines_deep_terror.lua @@ -0,0 +1,32 @@ +local function revertMachine(position, itemId, transformId) + local item = Tile(position):getItemById(itemId) + if item then + item:transform(transformId) + end + Game.setStorageValue(GlobalStorage.HeroRathleton.FirstMachines, Game.getStorageValue(GlobalStorage.HeroRathleton.FirstMachines) - 1) +end + +local heroRathletonDeep = Action() +function heroRathletonDeep.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid ~= 24112 then + return false + end + + if Game.getStorageValue(GlobalStorage.HeroRathleton.DeepTerrorRunning) >= 1 then + player:say('Impossible to turn on this machine for now!', TALKTYPE_MONSTER_SAY, false, nil, toPosition) + return true + end + + if Game.getStorageValue(GlobalStorage.HeroRathleton.FirstMachines) == 7 then + player:say('All machines are working, now is possible to use the teleport at east.', TALKTYPE_MONSTER_SAY) + end + + item:transform(24113) + addEvent(revertMachine, 10 * 60 * 1000, toPosition, 24113, 24112) + Game.setStorageValue(GlobalStorage.HeroRathleton.FirstMachines, Game.getStorageValue(GlobalStorage.HeroRathleton.FirstMachines) + 1) + player:say('~Zzzz~\n The machine is working!', TALKTYPE_MONSTER_SAY, false, nil, toPosition) + return true +end + +heroRathletonDeep:aid(24861) +heroRathletonDeep:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/hero_of_rathleton/machines_glooth_horror.lua b/data/scripts/actions/quests/hero_of_rathleton/machines_glooth_horror.lua new file mode 100644 index 00000000000..4318ab3f1ea --- /dev/null +++ b/data/scripts/actions/quests/hero_of_rathleton/machines_glooth_horror.lua @@ -0,0 +1,32 @@ +local function revertMachine(position, itemId, transformId) + local item = Tile(position):getItemById(itemId) + if item then + item:transform(transformId) + end + Game.setStorageValue(GlobalStorage.HeroRathleton.SecondMachines, Game.getStorageValue(GlobalStorage.HeroRathleton.SecondMachines) - 1) +end + +local heroRathletonGlooth = Action() +function heroRathletonGlooth.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid ~= 24112 then + return false + end + + if Game.getStorageValue(GlobalStorage.HeroRathleton.DeepTerrorRunning) >= 1 then + player:say('Impossible to turn on this machine for now!', TALKTYPE_MONSTER_SAY, false, nil, toPosition) + return true + end + + if Game.getStorageValue(GlobalStorage.HeroRathleton.SecondMachines) == 7 then + player:say('All machines are working, now is possible to use the teleport at west.', TALKTYPE_MONSTER_SAY) + end + + item:transform(24113) + addEvent(revertMachine, 10 * 60 * 1000, toPosition, 24113, 24112) + Game.setStorageValue(GlobalStorage.HeroRathleton.SecondMachines, Game.getStorageValue(GlobalStorage.HeroRathleton.SecondMachines) + 1) + player:say('~Zzzz~\n The machine is working!', TALKTYPE_MONSTER_SAY, false, nil, toPosition) + return true +end + +heroRathletonGlooth:aid(24863) +heroRathletonGlooth:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/hero_of_rathleton/machines_lava.lua b/data/scripts/actions/quests/hero_of_rathleton/machines_lava.lua new file mode 100644 index 00000000000..7b4a3e6beb7 --- /dev/null +++ b/data/scripts/actions/quests/hero_of_rathleton/machines_lava.lua @@ -0,0 +1,32 @@ +local function revertMachine(position, itemId, transformId) + local item = Tile(position):getItemById(itemId) + if item then + item:transform(transformId) + end + Game.setStorageValue(GlobalStorage.HeroRathleton.FourthMachines, Game.getStorageValue(GlobalStorage.HeroRathleton.FourthMachines) - 1) +end + +local heroRathletonLava = Action() +function heroRathletonLava.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid ~= 24112 then + return false + end + + if Game.getStorageValue(GlobalStorage.HeroRathleton.LavaRunning) >= 1 then + player:say('Impossible to turn on this machine for now!', TALKTYPE_MONSTER_SAY, false, nil, toPosition) + return true + end + + if Game.getStorageValue(GlobalStorage.HeroRathleton.FourthMachines) == 7 then + player:say('All machines are working, now is possible to use the teleport at west.', TALKTYPE_MONSTER_SAY) + end + + item:transform(24113) + addEvent(revertMachine, 10 * 60 * 1000, toPosition, 24113, 24112) + Game.setStorageValue(GlobalStorage.HeroRathleton.FourthMachines, Game.getStorageValue(GlobalStorage.HeroRathleton.FourthMachines) + 1) + player:say('~Zzzz~\n The machine is working!', TALKTYPE_MONSTER_SAY, false, nil, toPosition) + return true +end + +heroRathletonLava:aid(24865) +heroRathletonLava:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/hero_of_rathleton/machines_professor_maxxen.lua b/data/scripts/actions/quests/hero_of_rathleton/machines_professor_maxxen.lua new file mode 100644 index 00000000000..0741d3a69a4 --- /dev/null +++ b/data/scripts/actions/quests/hero_of_rathleton/machines_professor_maxxen.lua @@ -0,0 +1,32 @@ +local function revertMachine(position, itemId, transformId) + local item = Tile(position):getItemById(itemId) + if item then + item:transform(transformId) + end + Game.setStorageValue(GlobalStorage.HeroRathleton.ThirdMachines, Game.getStorageValue(GlobalStorage.HeroRathleton.ThirdMachines) - 1) +end + +local heroRathletonProfessor = Action() +function heroRathletonProfessor.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid ~= 24112 then + return false + end + + if Game.getStorageValue(GlobalStorage.HeroRathleton.MaxxenRunning) >= 1 then + player:say('Impossible to turn on this machine for now!', TALKTYPE_MONSTER_SAY, false, nil, toPosition) + return true + end + + if Game.getStorageValue(GlobalStorage.HeroRathleton.ThirdMachines) == 7 then + player:say('All machines are working, now is possible to use the teleport at east.', TALKTYPE_MONSTER_SAY) + end + + item:transform(24113) + addEvent(revertMachine, 10 * 60 * 1000, toPosition, 24113, 24112) + Game.setStorageValue(GlobalStorage.HeroRathleton.ThirdMachines, Game.getStorageValue(GlobalStorage.HeroRathleton.ThirdMachines) + 1) + player:say('~Zzzz~\n The machine is working!', TALKTYPE_MONSTER_SAY, false, nil, toPosition) + return true +end + +heroRathletonProfessor:aid(9299) +heroRathletonProfessor:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/hero_of_rathleton/raging_corpse.lua b/data/scripts/actions/quests/hero_of_rathleton/raging_corpse.lua new file mode 100644 index 00000000000..171a971f29d --- /dev/null +++ b/data/scripts/actions/quests/hero_of_rathleton/raging_corpse.lua @@ -0,0 +1,14 @@ +local heroRathletonCorpse = Action() +function heroRathletonCorpse.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid ~= 8641 then + return false + end + Game.setStorageValue(GlobalStorage.HeroRathleton.LavaCounter, Game.getStorageValue(GlobalStorage.HeroRathleton.LavaCounter) + 1) + item:remove() + target:getPosition():sendMagicEffect(CONST_ME_FIREAREA) + return true +end + +heroRathletonCorpse:id(24184) +heroRathletonCorpse:allowFarUse(true) +heroRathletonCorpse:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/hero_of_rathleton/reward.lua b/data/scripts/actions/quests/hero_of_rathleton/reward.lua new file mode 100644 index 00000000000..558c8c948d3 --- /dev/null +++ b/data/scripts/actions/quests/hero_of_rathleton/reward.lua @@ -0,0 +1,19 @@ +local heroRathletonReward = Action() +function heroRathletonReward.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(24850) < 1 then + player:addItem(23574, 5) + player:addItem(2152, 4) + player:addItem(24266) + player:addItem(9971) + player:addItem(7909) + player:addAchievement('The Professors Nut') + player:setStorageValue(24850, 1) -- storage da recompensa + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You opened the Maxxen\'s chest.') + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The chest is empty.') + end + return true +end + +heroRathletonReward:uid(24850) +heroRathletonReward:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/hot_cuisine/cookbook1.lua b/data/scripts/actions/quests/hot_cuisine/cookbook1.lua new file mode 100644 index 00000000000..544d8748749 --- /dev/null +++ b/data/scripts/actions/quests/hot_cuisine/cookbook1.lua @@ -0,0 +1,25 @@ +local config = { + [1] = "Rotworm Stew\n- 2 Pieces of meat\n- 2 Vials of beer\n- 20 Potatoes\n- 1 Onion\n- 1 Garlic\n- 5 Ounces of flour\n\n", + [2] = "Hydra Tongue Salad\n- 2 Hydra tongues\n- 2 Tomatoes\n- 1 Cucumber\n- 2 Eggs\n- 1 Troll green\n- 1 Vial of wine\n\n", + [3] = "Roasted Dragon Wings\n- 1 Fresh dead bat\n- 3 Jalape�o peppers\n- 5 Brown breads\n- 2 Eggs\n- 1 Powder herb\n- 5 Red mushrooms\n\n", + [4] = "Tropical Fried Terrorbird\n- 1 Fresh dead chicken\n- 2 Lemons\n- 2 Oranges\n- 2 Mangos\n- 2 Vials of coconut milk\n- 1 Stone herb\n\n", + [5] = "Banana Chocolate Shake\n- 1 Bar of chocolate\n- 1 Cream cake\n- 2 Bananas\n- 2 Vials of milk\n- 1 Sling herb\n- 1 Star herb\n\n", + [6] = "Veggie Casserole\n- 2 Carrots\n- 2 Tomatoes\n- 2 Corncobs\n- 2 Cucumbers\n- 1 Onion\n- 1 Garlic\n- 1 Cheese\n- 20 White mushrooms\n- 5 Brown mushrooms\n\n", + [7] = "Filled Jalape�o Peppers\n- 10 Jalape�o peppers\n- 2 Cheese\n- 1 Troll green\n- 1 Shadow herb\n- 1 Vial of mead\n- 2 Eggs\n\n", + [8] = "Blessed Steak\n- 1 Piece of ham\n- 5 Plums\n- 1 Onions\n- 2 Beetroot\n- 1 Pumpkin\n- 2 Jalape�o peppers\n\n", + [9] = "Northern Fishburger\n- 1 Northern pike\n- 1 Rainbow trout\n- 1 Green perch\n- 5 Shrimps\n- 2 Rolls- 1 Fern\n\n", + [10] = "Carrot Cake\n- 5 Carrots\n- 1 Vial of milk\n- 1 Lemon\n- 10 Ounces of flour\n- 2 Eggs\n- 10 Cookies\n- 2 Peanuts" +} + +local hotCuisineCook1 = Action() +function hotCuisineCook1.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local text = {} + for i = 1, 10 do + text[#text + 1] = config[i] + end + player:showTextDialog(item.itemid, table.concat(text)) + return true +end + +hotCuisineCook1:id(10006) +hotCuisineCook1:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/hot_cuisine/cookbook2.lua b/data/scripts/actions/quests/hot_cuisine/cookbook2.lua new file mode 100644 index 00000000000..c908905a6bf --- /dev/null +++ b/data/scripts/actions/quests/hot_cuisine/cookbook2.lua @@ -0,0 +1,19 @@ +local config = { + [1] = "Coconut Shrimp Bake\n- 5 vials of milk\n- 5 brown mushrooms\n- 5 red mushrooms\n- 10 rice balls\n- 10 shrimps\n\n", + [2] = "Pot of Blackjack\n- 5 sandcrawler shells\n- 2 vials of water\n- 20 carrots\n- 10 potatoes\n- 3 jalapeno peppers\n\n", + [3] = "Demonic Candy Ball\n- 3 candies\n- 3 candy canes\n- 2 bar of chocolate\n- 15 gingerbreadmen\n- 1 concentrated demonic blood\n\n", + [4] = "Sweet Mangonaise Elixir\n- 100 eggs\n- 50 mangoes\n- 10 honeycombs\n- 1 bottle of bug milk\n- 1 blessed wooden stake\n\n" +} + +local hotCuisineCook2 = Action() +function hotCuisineCook2.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local text = {} + for i = 1, 4 do + text[#text + 1] = config[i] + end + player:showTextDialog(item.itemid, table.concat(text)) + return true +end + +hotCuisineCook2:id(12497) +hotCuisineCook2:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/hunter_outfit/all_hymn_piano_teleport.lua b/data/scripts/actions/quests/hunter_outfit/all_hymn_piano_teleport.lua new file mode 100644 index 00000000000..63ea5b1603e --- /dev/null +++ b/data/scripts/actions/quests/hunter_outfit/all_hymn_piano_teleport.lua @@ -0,0 +1,17 @@ +local portpos = Position({x = 32402, y = 32794, z = 9}) + +local hunterAll = Action() +function hunterAll.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.OutfitQuest.HunterMusicSheet01) == 1 and player:getStorageValue(Storage.OutfitQuest.HunterMusicSheet02) == 1 and player:getStorageValue(Storage.OutfitQuest.HunterMusicSheet03) == 1 and player:getStorageValue(Storage.OutfitQuest.HunterMusicSheet04) == 1 then + player:teleportTo(portpos, false) + portpos:sendMagicEffect(CONST_ME_TELEPORT) + toPosition:sendMagicEffect(CONST_ME_SOUND_YELLOW) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have not learned all the verses of the hymn") + toPosition:sendMagicEffect(CONST_ME_POFF) + end + return true +end + +hunterAll:aid(33216) +hunterAll:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/hunter_outfit/music_sheet.lua b/data/scripts/actions/quests/hunter_outfit/music_sheet.lua new file mode 100644 index 00000000000..6266423440e --- /dev/null +++ b/data/scripts/actions/quests/hunter_outfit/music_sheet.lua @@ -0,0 +1,28 @@ +local config = { + [6087] = {storage = Storage.OutfitQuest.HunterMusicSheet01, text = 'first'}, + [6088] = {storage = Storage.OutfitQuest.HunterMusicSheet02, text = 'second'}, + [6089] = {storage = Storage.OutfitQuest.HunterMusicSheet03, text = 'third'}, + [6090] = {storage = Storage.OutfitQuest.HunterMusicSheet04, text = 'fourth'} +} + +local hunterMusic = Action() +function hunterMusic.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local useItem = config[item.itemid] + if not useItem then + return true + end + + local cStorage = useItem.storage + if player:getStorageValue(cStorage) ~= 1 then + player:setStorageValue(cStorage, 1) + player:sendTextMessage(MESSAGE_GAME_HIGHLIGHT, 'You have learned the ' .. useItem.text .. ' part of a hymn.') + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + item:remove(1) + else + player:sendTextMessage(MESSAGE_GAME_HIGHLIGHT, 'You already know the ' .. useItem.text .. ' verse of the hymn.') + end + return true +end + +hunterMusic:id(6087, 6088, 6089, 6090) +hunterMusic:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ice_islands/anthill.lua b/data/scripts/actions/quests/ice_islands/anthill.lua new file mode 100644 index 00000000000..dad7e53564c --- /dev/null +++ b/data/scripts/actions/quests/ice_islands/anthill.lua @@ -0,0 +1,24 @@ +local iceAntHill = Action() +function iceAntHill.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local mast = {x = 32360, y = 31365, z = 7} + if target.itemid == 3323 and item.itemid == 7243 then + if player:getStorageValue(Storage.TheIceIslands.Questline) == 6 then + toPosition:sendMagicEffect(CONST_ME_GROUNDSHAKER) + player:setStorageValue(Storage.TheIceIslands.Mission03, 2) -- Questlog The Ice Islands Quest, Nibelor 2: Ecological Terrorism + player:say("You fill the jug with ants.", TALKTYPE_MONSTER_SAY) + item:transform(7244) + end + elseif target.itemid == 4942 and item.itemid == 7244 and toPosition.x == mast.x and toPosition.y == mast.y and toPosition.z == mast.z then + if player:getStorageValue(Storage.TheIceIslands.Questline) == 6 then + toPosition:sendMagicEffect(CONST_ME_GROUNDSHAKER) + player:setStorageValue(Storage.TheIceIslands.Questline, 7) + player:setStorageValue(Storage.TheIceIslands.Mission03, 3) -- Questlog The Ice Islands Quest, Nibelor 2: Ecological Terrorism + player:say("You released ants on the hill.", TALKTYPE_MONSTER_SAY) + item:transform(7243) + end + end + return true +end + +iceAntHill:id(7243,7244) +iceAntHill:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ice_islands/charm.lua b/data/scripts/actions/quests/ice_islands/charm.lua new file mode 100644 index 00000000000..aa1d05dbbe6 --- /dev/null +++ b/data/scripts/actions/quests/ice_islands/charm.lua @@ -0,0 +1,49 @@ +local iceCharm = Action() +function iceCharm.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid ~= 1354 then + return false + end + + if player:getStorageValue(Storage.TheIceIslands.Questline) ~= 39 then + return true + end + + local obelisk1 = {x = 32138, y = 31113, z = 14} + local obelisk2 = {x = 32119, y = 30992, z = 14} + local obelisk3 = {x = 32180, y = 31069, z = 14} + local obelisk4 = {x = 32210, y = 31027, z = 14} + + if toPosition.x == obelisk1.x and toPosition.y == obelisk1.y and toPosition.z == obelisk1.z then + if player:getStorageValue(Storage.TheIceIslands.Obelisk01) < 5 then + player:setStorageValue(Storage.TheIceIslands.Obelisk01, 5) + player:setStorageValue(Storage.TheIceIslands.Mission12, player:getStorageValue(Storage.TheIceIslands.Mission12) + 1) -- Questlog The Ice Islands Quest, Formorgar Mines 4: Retaliation + toPosition:sendMagicEffect(CONST_ME_FIREWORK_BLUE) + player:say("You mark an obelisk with the frost charm.", TALKTYPE_MONSTER_SAY) + end + elseif toPosition.x == obelisk2.x and toPosition.y == obelisk2.y and toPosition.z == obelisk2.z then + if player:getStorageValue(Storage.TheIceIslands.Obelisk02) < 5 then + player:setStorageValue(Storage.TheIceIslands.Obelisk02, 5) + player:setStorageValue(Storage.TheIceIslands.Mission12, player:getStorageValue(Storage.TheIceIslands.Mission12) + 1) -- Questlog The Ice Islands Quest, Formorgar Mines 4: Retaliation + toPosition:sendMagicEffect(CONST_ME_FIREWORK_BLUE) + player:say("You mark an obelisk with the frost charm.", TALKTYPE_MONSTER_SAY) + end + elseif toPosition.x == obelisk3.x and toPosition.y == obelisk3.y and toPosition.z == obelisk3.z then + if player:getStorageValue(Storage.TheIceIslands.Obelisk03) < 5 then + player:setStorageValue(Storage.TheIceIslands.Obelisk03, 5) + player:setStorageValue(Storage.TheIceIslands.Mission12, player:getStorageValue(Storage.TheIceIslands.Mission12) + 1) -- Questlog The Ice Islands Quest, Formorgar Mines 4: Retaliation + toPosition:sendMagicEffect(CONST_ME_FIREWORK_BLUE) + player:say("You mark an obelisk with the frost charm.", TALKTYPE_MONSTER_SAY) + end + elseif toPosition.x == obelisk4.x and toPosition.y == obelisk4.y and toPosition.z == obelisk4.z then + if player:getStorageValue(Storage.TheIceIslands.Obelisk04) < 5 then + player:setStorageValue(Storage.TheIceIslands.Obelisk04, 5) + player:setStorageValue(Storage.TheIceIslands.Mission12, player:getStorageValue(Storage.TheIceIslands.Mission12) + 1) -- Questlog The Ice Islands Quest, Formorgar Mines 4: Retaliation + toPosition:sendMagicEffect(CONST_ME_FIREWORK_BLUE) + player:say("You mark an obelisk with the frost charm.", TALKTYPE_MONSTER_SAY) + end + end + return true +end + +iceCharm:id(7289) +iceCharm:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ice_islands/cure.lua b/data/scripts/actions/quests/ice_islands/cure.lua new file mode 100644 index 00000000000..ff78974f34d --- /dev/null +++ b/data/scripts/actions/quests/ice_islands/cure.lua @@ -0,0 +1,16 @@ +local iceCure = Action() +function iceCure.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid ~= 7106 then + return false + end + + if player:getStorageValue(Storage.TheIceIslands.Questline) >= 21 then + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:say('You take some hot water from the geyser.', TALKTYPE_MONSTER_SAY) + item:transform(7246) + end + return true +end + +iceCure:id(7286) +iceCure:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ice_islands/paint.lua b/data/scripts/actions/quests/ice_islands/paint.lua new file mode 100644 index 00000000000..3306ec99cb3 --- /dev/null +++ b/data/scripts/actions/quests/ice_islands/paint.lua @@ -0,0 +1,30 @@ +local function transformBack(position, itemId, transformId) + local item = Tile(position):getItemById(itemId) + if item then + item:transform(transformId) + position:sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +end + +local icePaint = Action() +function icePaint.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid ~= 7178 then + return false + end + + if player:getStorageValue(Storage.TheIceIslands.Questline) == 8 then + toPosition:sendMagicEffect(CONST_ME_MAGIC_GREEN) + player:setStorageValue(Storage.TheIceIslands.PaintSeal, player:getStorageValue(Storage.TheIceIslands.PaintSeal) + 1) + if player:getStorageValue(Storage.TheIceIslands.PaintSeal) == 2 then + player:setStorageValue(Storage.TheIceIslands.Questline, 9) + player:setStorageValue(Storage.TheIceIslands.Mission04, 2) -- Questlog The Ice Islands Quest, Nibelor 3: Artful Sabotage + end + player:say('You painted a baby seal.', TALKTYPE_MONSTER_SAY) + target:transform(7252) + addEvent(transformBack, 30 * 1000, toPosition, 7252, 7178) + end + return true +end + +icePaint:id(7253) +icePaint:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/ice_islands/yakchal.lua b/data/scripts/actions/quests/ice_islands/yakchal.lua new file mode 100644 index 00000000000..b423639ed5d --- /dev/null +++ b/data/scripts/actions/quests/ice_islands/yakchal.lua @@ -0,0 +1,45 @@ +local creatureName = { + [1] = 'ice golem', + [2] = 'ice witch', + [3] = 'crystal spider', + [4] = 'frost dragon' +} + +local function summonMonster(name, position) + Game.createMonster(name, position) + position:sendMagicEffect(CONST_ME_TELEPORT) +end + +local iceYakchal = Action() +function iceYakchal.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local sarcophagus = Position(32205, 31002, 14) + if toPosition.x == sarcophagus.x and toPosition.y == sarcophagus.y and toPosition.z == sarcophagus.z and target.itemid == 7362 and item.itemid == 2361 then + if Game.getStorageValue(GlobalStorage.Yakchal) < os.time() then + Game.setStorageValue(GlobalStorage.Yakchal, os.time() + 24 * 60 * 60) + if math.random(2) == 2 then + player:say("You have awoken the icewitch Yakchal from her slumber! She seems not amused...", TALKTYPE_MONSTER_SAY) + else + player:say("The frozen starlight shattered, but you have awoken the icewitch Yakchal from her slumber! She seems not amused...", TALKTYPE_MONSTER_SAY) + item:remove(1) + end + Game.createMonster("Yakchal", toPosition) + toPosition:sendMagicEffect(CONST_ME_TELEPORT) + local creature, pos + for i = 1, 4 do + creature = creatureName[i] + for k = 1, 70 do + pos = Position(math.random(32193, 32215), math.random(30985, 31014), 14) + if math.random(i + 1) == 1 then + addEvent(summonMonster, (i - 1) * 10 * 1000, creature, pos) + end + end + end + else + player:say("Yakchal has already been awakened today. You should try again tomorrow.", TALKTYPE_MONSTER_SAY) + end + end + return true +end + +iceYakchal:id(2361) +iceYakchal:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/in_service_of_yalahar/charm.lua b/data/scripts/actions/quests/in_service_of_yalahar/charm.lua new file mode 100644 index 00000000000..e3aed47a364 --- /dev/null +++ b/data/scripts/actions/quests/in_service_of_yalahar/charm.lua @@ -0,0 +1,21 @@ +local inServiceYalaharCharm = Action() +function inServiceYalaharCharm.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid == 100 and target.itemid == 471 then + if player:getStorageValue(Storage.InServiceofYalahar.Questline) == 36 then + player:removeItem(9737, 1) + Game.createItem(9738, 1, toPosition) + toPosition:sendMagicEffect(CONST_ME_CARNIPHILA) + local monster + for i = 1, 2 do + monster = Game.createMonster('Tormented Ghost', player:getPosition()) + if monster then + monster:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + end + end + return true +end + +inServiceYalaharCharm:id(9737) +inServiceYalaharCharm:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/in_service_of_yalahar/formula.lua b/data/scripts/actions/quests/in_service_of_yalahar/formula.lua new file mode 100644 index 00000000000..50bcdfba048 --- /dev/null +++ b/data/scripts/actions/quests/in_service_of_yalahar/formula.lua @@ -0,0 +1,14 @@ +local inServiceYalaharFormula = Action() +function inServiceYalaharFormula.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if not isInArray({1786, 1787, 1788, 1789, 1790, 1791, 1792, 1793, 9911}, target.itemid) then + return false + end + + item:remove(1) + toPosition:sendMagicEffect(CONST_ME_MAGIC_GREEN) + player:say("You burned the alchemist formula.", TALKTYPE_MONSTER_SAY) + return true +end + +inServiceYalaharFormula:id(9733) +inServiceYalaharFormula:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/in_service_of_yalahar/ghost.lua b/data/scripts/actions/quests/in_service_of_yalahar/ghost.lua new file mode 100644 index 00000000000..141d691dfe2 --- /dev/null +++ b/data/scripts/actions/quests/in_service_of_yalahar/ghost.lua @@ -0,0 +1,37 @@ +local config = { + [9738] = 9739, + [9739] = 9740, + [9740] = 9773, + [9773] = 9742 +} + +local inServiceYalaharGhost = Action() +function inServiceYalaharGhost.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local transformId = config[target.itemid] + if not transformId then + return true + end + + for i = 1, 2 do + Game.createMonster('Tormented Ghost', fromPosition) + end + + local charmItem = Tile(Position(32776, 31062, 7)):getItemById(target.itemid) + if charmItem then + charmItem:transform(transformId) + end + + toPosition:sendMagicEffect(CONST_ME_ENERGYHIT) + item:remove() + player:say('The ghost charm is charging.', TALKTYPE_MONSTER_SAY) + + if target.itemid == 9773 then + player:setStorageValue(Storage.InServiceofYalahar.Questline, 37) + player:setStorageValue(Storage.InServiceofYalahar.Mission06, 3) -- StorageValue for Questlog "Mission 06: Frightening Fuel" + player:removeItem(9737, 1) + end + return true +end + +inServiceYalaharGhost:id(9741) +inServiceYalaharGhost:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/in_service_of_yalahar/last_fight.lua b/data/scripts/actions/quests/in_service_of_yalahar/last_fight.lua new file mode 100644 index 00000000000..a1d8de54634 --- /dev/null +++ b/data/scripts/actions/quests/in_service_of_yalahar/last_fight.lua @@ -0,0 +1,95 @@ +local waves = { + Position(32779, 31166, 10), + Position(32787, 31166, 10), + Position(32782, 31162, 10), + Position(32784, 31162, 10), + Position(32782, 31170, 10), + Position(32784, 31170, 10) +} + +local creatureNames = { + [1] = 'rift worm', + [2] = 'rift scythe', + [3] = 'rift brood', + [4] = 'war golem' +} + +local effectPositions = { + Position(32779, 31161, 10), + Position(32787, 31171, 10) +} + +local function doClearAreaAzerus() + if Game.getStorageValue(GlobalStorage.InServiceOfYalahar.LastFight) == 1 then + local spectators, spectator = Game.getSpectators(Position(32783, 31166, 10), false, false, 10, 10, 10, 10) + for i = 1, #spectators do + spectator = spectators[i] + if spectator:isMonster() then + spectator:getPosition():sendMagicEffect(CONST_ME_POFF) + spectator:remove() + end + end + Game.setStorageValue(GlobalStorage.InServiceOfYalahar.LastFight, 0) + end + return true +end + +local function doChangeAzerus() + local spectators, spectator = Game.getSpectators(Position(32783, 31166, 10), false, false, 10, 10, 10, 10) + for i = 1, #spectators do + spectator = spectators[i] + if spectator:isMonster() and spectator:getName():lower() == "azerus" then + spectator:say("No! I am losing my energy!", TALKTYPE_MONSTER_SAY) + Game.createMonster("Azerus", spectator:getPosition(), false, true) + spectator:remove() + return true + end + end + return false +end + +local function summonMonster(name, position) +Game.createMonster(name, position, false, true) + --Game.createMonster(name, position) + position:sendMagicEffect(CONST_ME_TELEPORT) +end + +local inServiceYalaharLastFight = Action() +function inServiceYalaharLastFight.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if Game.getStorageValue(GlobalStorage.InServiceOfYalahar.LastFight) == 1 then + player:say('You have to wait some time before this globe charges.', TALKTYPE_MONSTER_SAY) + return true + end + + local amountOfPlayers = 1 + local spectators = Game.getSpectators(Position(32783, 31166, 10), false, true, 10, 10, 10, 10) + if #spectators < amountOfPlayers then + for i = 1, #spectators do + spectators[i]:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need atleast " .. amountOfPlayers .. " players inside the quest room.") + end + return true + end + + Game.setStorageValue(GlobalStorage.InServiceOfYalahar.LastFight, 1) + addEvent(Game.createMonster, 18 * 1000, "Azerus2", Position(32783, 31167, 10), false, true) + --addEvent(Game.createMonster, 18 * 1000, "Azerus2", Position(32783, 31167, 10)) + + local azeruswavemonster + for i = 1, #creatureNames do + azeruswavemonster = creatureNames[i] + for k = 1, #waves do + addEvent(summonMonster, (i - 1) * 60 * 1000, azeruswavemonster, waves[k]) + end + end + + for i = 1, #effectPositions do + effectPositions[i]:sendMagicEffect(CONST_ME_HOLYAREA) + end + + addEvent(doChangeAzerus, 3 * 60 * 1000) + addEvent(doClearAreaAzerus, 5 * 60 * 1000) + return true +end + +inServiceYalaharLastFight:uid(3086) +inServiceYalaharLastFight:register() diff --git a/data/scripts/actions/quests/in_service_of_yalahar/matrix.lua b/data/scripts/actions/quests/in_service_of_yalahar/matrix.lua new file mode 100644 index 00000000000..3e45fd704ee --- /dev/null +++ b/data/scripts/actions/quests/in_service_of_yalahar/matrix.lua @@ -0,0 +1,17 @@ +local inServiceYalaharMatrix = Action() +function inServiceYalaharMatrix.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if isInArray({7915, 7916}, target.itemid) and target.actionid == 100 then + if isInArray({9743, 9744}, item.itemid) and player:getStorageValue(Storage.InServiceofYalahar.MatrixState) < 1 then + player:setStorageValue(Storage.InServiceofYalahar.MatrixState, 1) + item:remove(1) + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:say("The machine was activated.", TALKTYPE_MONSTER_SAY) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 46) + player:setStorageValue(Storage.InServiceofYalahar.Mission08, 3) -- StorageValue for Questlog "Mission 08: Dangerous Machinations" + end + end + return true +end + +inServiceYalaharMatrix:id(9743,9744) +inServiceYalaharMatrix:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/in_service_of_yalahar/mechanism.lua b/data/scripts/actions/quests/in_service_of_yalahar/mechanism.lua new file mode 100644 index 00000000000..11600c66b26 --- /dev/null +++ b/data/scripts/actions/quests/in_service_of_yalahar/mechanism.lua @@ -0,0 +1,43 @@ +local mechanisms = { + [3091] = {pos = {x = 32744, y = 31161, z = 5}, value = 21}, -- Alchemist + [3092] = {pos = {x = 32744, y = 31164, z = 5}, value = 21}, + [3093] = {pos = {x = 32833, y = 31269, z = 5}, value = 24}, -- Trade + [3094] = {pos = {x = 32833, y = 31266, z = 5}, value = 24}, + [3095] = {pos = {x = 32729, y = 31200, z = 5}, value = 29}, -- Arena + [3096] = {pos = {x = 32734, y = 31200, z = 5}, value = 29}, + [3097] = {pos = {x = 32776, y = 31141, z = 5}, value = 35}, -- Cemetery + [3098] = {pos = {x = 32776, y = 31145, z = 5}, value = 35}, + [3099] = {pos = {x = 32874, y = 31202, z = 5}, value = 41}, -- Sunken + [3100] = {pos = {x = 32869, y = 31202, z = 5}, value = 41}, + [3101] = {pos = {x = 32856, y = 31251, z = 5}, value = 45}, -- Factory + [3102] = {pos = {x = 32854, y = 31248, z = 5}, value = 45} +} + +local mechanisms2 = { + [1018] = {pos = {x = 32773, y = 31116, z = 7}}, + [1019] = {pos = {x = 32780, y = 31115, z = 7}} +} + +local inServiceYalaharMechanism = Action() +function inServiceYalaharMechanism.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if(mechanisms[item.uid]) then + if(player:getStorageValue(Storage.InServiceofYalahar.Questline) >= mechanisms[item.uid].value) then + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(mechanisms[item.uid].pos) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The gate mechanism won't move. You probably have to find a way around until you figure out how to operate the gate.") + end + elseif(mechanisms2[item.uid]) then + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(mechanisms2[item.uid].pos) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +inServiceYalaharMechanism:uid(1018,1019) +for value = 3091, 3102 do + inServiceYalaharMechanism:uid(value) +end +inServiceYalaharMechanism:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/in_service_of_yalahar/morik_summon.lua b/data/scripts/actions/quests/in_service_of_yalahar/morik_summon.lua new file mode 100644 index 00000000000..fa09bc46403 --- /dev/null +++ b/data/scripts/actions/quests/in_service_of_yalahar/morik_summon.lua @@ -0,0 +1,15 @@ +local inServiceYalaharMorik = Action() +function inServiceYalaharMorik.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.uid == 1015 then + if player:getStorageValue(Storage.InServiceofYalahar.Questline) == 31 + and player:getStorageValue(Storage.InServiceofYalahar.MorikSummon) < 1 then + local ret = Game.createMonster("Morik the Gladiator", fromPosition) + ret:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:setStorageValue(Storage.InServiceofYalahar.MorikSummon, 1) + end + end + return true +end + +inServiceYalaharMorik:uid(1015) +inServiceYalaharMorik:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/in_service_of_yalahar/mr_west_door.lua b/data/scripts/actions/quests/in_service_of_yalahar/mr_west_door.lua new file mode 100644 index 00000000000..ceb16f02f32 --- /dev/null +++ b/data/scripts/actions/quests/in_service_of_yalahar/mr_west_door.lua @@ -0,0 +1,24 @@ +local inServiceYalaharWest = Action() +function inServiceYalaharWest.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if(item.uid == 3081) then + if(player:getStorageValue(Storage.InServiceofYalahar.Questline) >= 24) then + if(item.itemid == 5288) then + player:teleportTo(toPosition, true) + item:transform(5289) + player:setStorageValue(Storage.InServiceofYalahar.MrWestDoor, 1) + end + end + elseif(item.uid == 3082) then + if(player:getStorageValue(Storage.InServiceofYalahar.Questline) >= 24) then + if(item.itemid == 6261) then + player:teleportTo(toPosition, true) + item:transform(6262) + player:setStorageValue(Storage.InServiceofYalahar.MrWestDoor, 2) + end + end + end + return true +end + +inServiceYalaharWest:uid(3081,3082) +inServiceYalaharWest:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/in_service_of_yalahar/reward.lua b/data/scripts/actions/quests/in_service_of_yalahar/reward.lua new file mode 100644 index 00000000000..b44ecdd8f97 --- /dev/null +++ b/data/scripts/actions/quests/in_service_of_yalahar/reward.lua @@ -0,0 +1,49 @@ +local inServiceYalaharReward = Action() +function inServiceYalaharReward.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if(item.uid == 3088) then + if(player:getStorageValue(Storage.InServiceofYalahar.Questline) == 53) then + player:setStorageValue(Storage.InServiceofYalahar.Questline, 54) + player:setStorageValue(Storage.InServiceofYalahar.Mission10, 5) -- StorageValue for Questlog "Mission 10: The Final Battle" + player:addItem(9776, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a yalahari armor.") + player:addOutfitAddon(324, 2) + player:addOutfitAddon(324, 1) + player:addOutfitAddon(325, 1) + player:addOutfitAddon(325, 2) + + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The chest is empty.") + end + elseif(item.uid == 3089) then + if(player:getStorageValue(Storage.InServiceofYalahar.Questline) == 53) then + player:setStorageValue(Storage.InServiceofYalahar.Questline, 54) + player:setStorageValue(Storage.InServiceofYalahar.Mission10, 5) -- StorageValue for Questlog "Mission 10: The Final Battle" + player:addItem(9778, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a yalahari mask.") + player:addOutfitAddon(324, 2) + player:addOutfitAddon(324, 1) + player:addOutfitAddon(325, 1) + player:addOutfitAddon(325, 2) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The chest is empty.") + end + elseif(item.uid == 3090) then + if(player:getStorageValue(Storage.InServiceofYalahar.Questline) == 53) then + player:setStorageValue(Storage.InServiceofYalahar.Questline, 54) + player:setStorageValue(Storage.InServiceofYalahar.Mission10, 5) -- StorageValue for Questlog "Mission 10: The Final Battle" + player:addItem(9777, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a yalahari leg piece.") + player:addOutfitAddon(324, 2) + player:addOutfitAddon(324, 1) + player:addOutfitAddon(325, 1) + player:addOutfitAddon(325, 2) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The chest is empty.") + end + end + + return true +end + +inServiceYalaharReward:uid(3088,3089,3090) +inServiceYalaharReward:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/in_service_of_yalahar/yalahar_machine_war_golems.lua b/data/scripts/actions/quests/in_service_of_yalahar/yalahar_machine_war_golems.lua new file mode 100644 index 00000000000..82be833bd64 --- /dev/null +++ b/data/scripts/actions/quests/in_service_of_yalahar/yalahar_machine_war_golems.lua @@ -0,0 +1,54 @@ +local config = { + [23700] = { + storage = GlobalStorage.InServiceOfYalahar.WarGolemsMachine1, + machines = { + {x = 32882, y = 31323, z = 10}, + {x = 32882, y = 31320, z = 10}, + {x = 32882, y = 31318, z = 10}, + {x = 32882, y = 31316, z = 10} + } + }, + [23701] = { + storage = GlobalStorage.InServiceOfYalahar.WarGolemsMachine2, + machines = { + {x = 32869, y = 31322, z = 10}, + {x = 32869, y = 31320, z = 10}, + {x = 32869, y = 31318, z = 10}, + {x = 32869, y = 31316, z = 10} + } + } +} + +local function disableMachine(storage) + Game.setStorageValue(storage, -1) +end + +local inServiceYalaharWarGolem = Action() +function inServiceYalaharWarGolem.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local machineGroup = config[item.actionid] + if not machineGroup then + return true + end + + if Game.getStorageValue(machineGroup.storage) == 1 then + return true + end + + if player:getItemCount(9690) < 4 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You don\'t have enough gear wheels to activate the machine.') + return true + end + + Game.setStorageValue(machineGroup.storage, 1) + addEvent(disableMachine, 60 * 60 * 1000, machineGroup.storage) + player:removeItem(9690, 4) + for i = 1, #machineGroup.machines do + player:say('*CLICK*', TALKTYPE_MONSTER_YELL, false, player, machineGroup.machines[i]) + end + + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You insert all 4 gear wheels, them adjusting the teleporter to transport you to the deeper floor') + return true +end + +inServiceYalaharWarGolem:aid(23700,23701) +inServiceYalaharWarGolem:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/inquisition/brother_lever.lua b/data/scripts/actions/quests/inquisition/brother_lever.lua new file mode 100644 index 00000000000..20387022167 --- /dev/null +++ b/data/scripts/actions/quests/inquisition/brother_lever.lua @@ -0,0 +1,95 @@ +local config = { + [1006] = { + wallPositions = { + Position(33226, 31721, 11), + Position(33227, 31721, 11), + Position(33228, 31721, 11), + Position(33229, 31721, 11), + Position(33230, 31721, 11), + Position(33231, 31721, 11), + Position(33232, 31721, 11), + Position(33233, 31721, 11), + Position(33234, 31721, 11), + Position(33235, 31721, 11), + Position(33236, 31721, 11), + Position(33237, 31721, 11), + Position(33238, 31721, 11) + }, + wallDown = 1524, + wallUp = 1050 + }, + [1007] = { + wallPositions = { + Position(33223, 31724, 11), + Position(33223, 31725, 11), + Position(33223, 31726, 11), + Position(33223, 31727, 11), + Position(33223, 31728, 11), + Position(33223, 31729, 11), + Position(33223, 31730, 11), + Position(33223, 31731, 11), + Position(33223, 31732, 11) + }, + wallDown = 1526, + wallUp = 1049 + }, + [1008] = { + wallPositions = { + Position(33226, 31735, 11), + Position(33227, 31735, 11), + Position(33228, 31735, 11), + Position(33229, 31735, 11), + Position(33230, 31735, 11), + Position(33231, 31735, 11), + Position(33232, 31735, 11), + Position(33233, 31735, 11), + Position(33234, 31735, 11), + Position(33235, 31735, 11), + Position(33236, 31735, 11), + Position(33237, 31735, 11), + Position(33238, 31735, 11) + }, + wallDown = 1524, + wallUp = 1050 + }, + [1009] = { + wallPositions = { + Position(33241, 31724, 11), + Position(33241, 31725, 11), + Position(33241, 31726, 11), + Position(33241, 31727, 11), + Position(33241, 31728, 11), + Position(33241, 31729, 11), + Position(33241, 31730, 11), + Position(33241, 31731, 11), + Position(33241, 31732, 11) + }, + wallDown = 1526, + wallUp = 1049 + } +} + +local inquisitionBrother = Action() +function inquisitionBrother.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local targetLever = config[item.uid] + if not targetLever then + return true + end + + local tile, thing + for i = 1, #targetLever.wallPositions do + tile = Tile(targetLever.wallPositions[i]) + if tile then + thing = tile:getItemById(item.itemid == 1945 and targetLever.wallDown or targetLever.wallUp) + if thing then + thing:transform(item.itemid == 1945 and targetLever.wallUp or targetLever.wallDown) + end + end + end + + item:transform(item.itemid == 1945 and 1946 or 1945) + return true +end + +inquisitionBrother:uid(1006,1007,1008,1009) +inquisitionBrother:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/inquisition/rewards.lua b/data/scripts/actions/quests/inquisition/rewards.lua new file mode 100644 index 00000000000..300d01bbee4 --- /dev/null +++ b/data/scripts/actions/quests/inquisition/rewards.lua @@ -0,0 +1,35 @@ +local rewards = { + [1300] = 8890, + [1301] = 8918, + [1302] = 8881, + [1303] = 8888, + [1304] = 8851, + [1305] = 8924, + [1306] = 8928, + [1307] = 8930, + [1308] = 8854 +} + +local inquisitionRewards = Action() +function inquisitionRewards.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TheInquisition.Reward) < 1 then + player:setStorageValue(Storage.TheInquisition.Reward, 1) + player:setStorageValue(Storage.TheInquisition.Questline, 25) + player:setStorageValue(Storage.TheInquisition.Mission07, 5) -- The Inquisition Questlog- "Mission 7: The Shadow Nexus" + player:addItem(rewards[item.uid], 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found " .. ItemType(rewards[item.uid]):getName() .. ".") + player:addAchievement('Master of the Nexus') + player:addOutfitAddon(288, 2) + player:addOutfitAddon(288, 1) + player:addOutfitAddon(289, 1) + player:addOutfitAddon(289, 2) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The chest is empty.") + end + return true +end + +for value = 1300, 1308 do + inquisitionRewards:uid(value) +end +inquisitionRewards:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/inquisition/ungreez_door.lua b/data/scripts/actions/quests/inquisition/ungreez_door.lua new file mode 100644 index 00000000000..3f97f7dac51 --- /dev/null +++ b/data/scripts/actions/quests/inquisition/ungreez_door.lua @@ -0,0 +1,25 @@ +local inquisitionUngreez = Action() +function inquisitionUngreez.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TheInquisition.Questline) == 18 then + if item.actionid == 1004 then + if item.itemid == 5114 then + player:teleportTo(toPosition, true) + item:transform(item.itemid + 1) + elseif item.itemid == 5115 then + if Creature.checkCreatureInsideDoor(player, toPosition) then + return true + end + if item.itemid == 5115 then + item:transform(item.itemid - 1) + return true + end + end + end + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The door seems to be sealed against unwanted intruders.") + end + return true +end + +inquisitionUngreez:aid(1004) +inquisitionUngreez:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/inquisition/vampire_hunt.lua b/data/scripts/actions/quests/inquisition/vampire_hunt.lua new file mode 100644 index 00000000000..e10f0023454 --- /dev/null +++ b/data/scripts/actions/quests/inquisition/vampire_hunt.lua @@ -0,0 +1,31 @@ +local altars = { + Position(32777, 31982, 9), + Position(32779, 31977, 9), + Position(32781, 31982, 9) +} + +local inquisitionVampire = Action() +function inquisitionVampire.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TheInquisition.Questline) == 8 then + player:setStorageValue(Storage.TheInquisition.Questline, 9) + player:setStorageValue(Storage.TheInquisition.Mission03, 4) -- The Inquisition Questlog- "Mission 3: Vampire Hunt" + local k = {} + for i = 1, #altars do + local tmp = Tile(altars[i]):getItemById(2199) + if not tmp then + Game.createMonster("The Count", toPosition) + return true + else + k[#k + 1] = tmp + end + end + for i = 1, #k do + k[i]:remove() + end + Game.createMonster("The Weakened Count", toPosition) + return true + end +end + +inquisitionVampire:aid(2002) +inquisitionVampire:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/kilmaresh/augerfun.lua b/data/scripts/actions/quests/kilmaresh/augerfun.lua new file mode 100644 index 00000000000..696deb22f74 --- /dev/null +++ b/data/scripts/actions/quests/kilmaresh/augerfun.lua @@ -0,0 +1,18 @@ +local augerfun = Action() + +function augerfun.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + if player:getStorageValue(Storage.Kilmaresh.Eighth.Narsai) == 2 then + if table.contains({36212}, target.itemid) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are gathering some catus milk.") + player:addItem(36170, 1) + end + else + player:sendTextMessage(MESSAGE_FAILURE, "Sorry, not possible.") + end + + return true +end + +augerfun:id(36169) +augerfun:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/kilmaresh/basin.lua b/data/scripts/actions/quests/kilmaresh/basin.lua new file mode 100644 index 00000000000..953eebe3e6d --- /dev/null +++ b/data/scripts/actions/quests/kilmaresh/basin.lua @@ -0,0 +1,15 @@ +local basin = Action() + +function basin.onUse(player, item, frompos, item2, topos) + if player:getStorageValue(Storage.Kilmaresh.Tem.Bleeds) == 1 then + player:addItem(36266, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You find a golden symbol at the bottom of the blood-filled basin.") + player:setStorageValue(Storage.Kilmaresh.Eleven.Basin, 1) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Sorry") + end + return true +end + +basin:uid(57527) +basin:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/kilmaresh/books.lua b/data/scripts/actions/quests/kilmaresh/books.lua new file mode 100644 index 00000000000..cdf1369fdfd --- /dev/null +++ b/data/scripts/actions/quests/kilmaresh/books.lua @@ -0,0 +1,14 @@ +local books = Action() + +function books.onUse(player, item, frompos, item2, topos) + if player:getStorageValue(Storage.Kilmaresh.Second.Investigating) == 4 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You find nothing in the Ambassador's house. If he's in fact a traitor he got rid of any evidence that could incriminate him.") + player:setStorageValue(Storage.Kilmaresh.Second.Investigating, 5) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Empty.") + end + return true +end + +books:uid(57504) +books:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/kilmaresh/cagekey.lua b/data/scripts/actions/quests/kilmaresh/cagekey.lua new file mode 100644 index 00000000000..de9a9bffc13 --- /dev/null +++ b/data/scripts/actions/quests/kilmaresh/cagekey.lua @@ -0,0 +1,17 @@ +local cagekey = Action() + +function cagekey.onUse(player, item, frompos, item2, topos) + + if player:getStorageValue(Storage.Kilmaresh.Fourteen.Remains) == 2 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You have found a wooden cage key.") + player:addItem(36214, 1) -- Wooden Cage Key + player:setStorageValue(Storage.Kilmaresh.Fourteen.Remains, 3) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Empty.") + end + + return true +end + +cagekey:uid(57530) +cagekey:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/kilmaresh/coruja.lua b/data/scripts/actions/quests/kilmaresh/coruja.lua new file mode 100644 index 00000000000..3b4b79a11c9 --- /dev/null +++ b/data/scripts/actions/quests/kilmaresh/coruja.lua @@ -0,0 +1,14 @@ +local coruja = Action() + +function coruja.onUse(player, item, frompos, item2, topos) + if player:getStorageValue(Storage.Kilmaresh.Nine.Owl) == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You discover an owl resting in a tree. Thats special, because you have never seen an owl in all of Kilmaresh.") + player:setStorageValue(Storage.Kilmaresh.Nine.Owl, 2) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Sorry") + end + return true +end + +coruja:uid(57525) +coruja:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/kilmaresh/glasshoneyfun.lua b/data/scripts/actions/quests/kilmaresh/glasshoneyfun.lua new file mode 100644 index 00000000000..af98734a0c3 --- /dev/null +++ b/data/scripts/actions/quests/kilmaresh/glasshoneyfun.lua @@ -0,0 +1,19 @@ +local glasshoneyfun = Action() + +function glasshoneyfun.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + if player:getStorageValue(Storage.Kilmaresh.Eighth.Narsai) == 2 then + if table.contains({36211}, target.itemid) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are gently squishing some of the honey palm blossoms and golden honey is depping into the jug.") + player:removeItem(36166, 1) + player:addItem(36167, 1) + end + else + player:sendTextMessage(MESSAGE_FAILURE, "Sorry, not possible.") + end + + return true +end + +glasshoneyfun:id(36166) +glasshoneyfun:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/kilmaresh/lyre.lua b/data/scripts/actions/quests/kilmaresh/lyre.lua new file mode 100644 index 00000000000..6f120a3d05c --- /dev/null +++ b/data/scripts/actions/quests/kilmaresh/lyre.lua @@ -0,0 +1,17 @@ +local lyre = Action() + +function lyre.onUse(player, item, frompos, item2, topos) + + if player:getStorageValue(Storage.Kilmaresh.Thirteen.Lyre) == 2 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You have found Lyre.") + player:addItem(36282, 1) + player:setStorageValue(Storage.Kilmaresh.Thirteen.Lyre, 3) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The bag can not be opened.") + end + + return true +end + +lyre:uid(57529) +lyre:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/kilmaresh/peeler.lua b/data/scripts/actions/quests/kilmaresh/peeler.lua new file mode 100644 index 00000000000..d42c21490c3 --- /dev/null +++ b/data/scripts/actions/quests/kilmaresh/peeler.lua @@ -0,0 +1,18 @@ +local peeler = Action() + +function peeler.onUse(player, item, frompos, item2, topos) + + if player:getStorageValue(Storage.Kilmaresh.Set.Ritual) == 2 then + player:addItem(36163, 1) + player:setStorageValue(Storage.Kilmaresh.Set.Ritual, 3) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You have found a bark peeler.") + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Empty.") + end + + + return true +end + +peeler:uid(57518) +peeler:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/kilmaresh/peelerfun.lua b/data/scripts/actions/quests/kilmaresh/peelerfun.lua new file mode 100644 index 00000000000..b7bd88b5349 --- /dev/null +++ b/data/scripts/actions/quests/kilmaresh/peelerfun.lua @@ -0,0 +1,18 @@ +local peelerfun = Action() + +function peelerfun.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + if player:getStorageValue(Storage.Kilmaresh.Eighth.Tefrit) == 2 then + if table.contains({36211}, target.itemid) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are peeling a piece of tark off the again tree.") + player:addItem(36164, 1) + end + else + player:sendTextMessage(MESSAGE_FAILURE, "Sorry, not possible.") + end + + return true +end + +peelerfun:id(36163) +peelerfun:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/kilmaresh/pickenchanted.lua b/data/scripts/actions/quests/kilmaresh/pickenchanted.lua new file mode 100644 index 00000000000..30c6b46a9b6 --- /dev/null +++ b/data/scripts/actions/quests/kilmaresh/pickenchanted.lua @@ -0,0 +1,18 @@ +local pickenchanted = Action() + +function pickenchanted.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + if player:getStorageValue(Storage.Kilmaresh.Eighth.Yonan) == 2 then + if table.contains({35273}, target.itemid) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are quarrying some tagralt.") + player:addItem(36168, 1) + end + else + player:sendTextMessage(MESSAGE_FAILURE, "Sorry, not possible.") + end + + return true +end + +pickenchanted:id(36448) +pickenchanted:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/kilmaresh/sangra.lua b/data/scripts/actions/quests/kilmaresh/sangra.lua new file mode 100644 index 00000000000..2f284830bed --- /dev/null +++ b/data/scripts/actions/quests/kilmaresh/sangra.lua @@ -0,0 +1,14 @@ +local sangra = Action() + +function sangra.onUse(player, item, frompos, item2, topos) + if player:getStorageValue(Storage.Kilmaresh.Nine.Owl) == 2 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"The arrow is still sticking in the tree. Fresh blood keeps trickling from the spot where the arrow hit the trunk.") + player:setStorageValue(Storage.Kilmaresh.Tem.Bleeds, 1) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Sorry") + end + return true +end + +sangra:uid(57526) +sangra:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/kilmaresh/scissors.lua b/data/scripts/actions/quests/kilmaresh/scissors.lua new file mode 100644 index 00000000000..81ad1c3f258 --- /dev/null +++ b/data/scripts/actions/quests/kilmaresh/scissors.lua @@ -0,0 +1,18 @@ +local scissors = Action() + +function scissors.onUse(player, item, frompos, item2, topos) + + if player:getStorageValue(Storage.Kilmaresh.Set.Ritual) == 1 then + player:addItem(36162, 1) + player:setStorageValue(Storage.Kilmaresh.Set.Ritual, 2) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You have found a ritual scissors.") + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Empty.") + end + + + return true +end + +scissors:uid(uniqueid) +scissors:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/kilmaresh/scissorsfun.lua b/data/scripts/actions/quests/kilmaresh/scissorsfun.lua new file mode 100644 index 00000000000..8c220b6e903 --- /dev/null +++ b/data/scripts/actions/quests/kilmaresh/scissorsfun.lua @@ -0,0 +1,288 @@ +local config = { + [35261] = { + itemId = 35261, + msg = "You are cutting some veldt flowers.", + storage = Storage.Kilmaresh.Eighth.Yonan, + getValue = 2, + addValue = 36160 + }, -- Veldt Flower + [35257] = { + itemId = 35257, + msg = "You are cutting some snake maw.", + storage = Storage.Kilmaresh.Eighth.Shimun, + getValue = 2, + addValue = 36171 + }, -- Sanke Maw + [35262] = { + itemId = 35262, + msg = "You are cutting some desert rose blossoms.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36165 + }, -- Rose Blossoms + [13886] = { + itemId = 13886, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13887] = { + itemId = 13887, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13888] = { + itemId = 13888, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13889] = { + itemId = 13889, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13890] = { + itemId = 13890, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13891] = { + itemId = 13891, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13892] = { + itemId = 13892, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13893] = { + itemId = 13893, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13894] = { + itemId = 13894, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13895] = { + itemId = 13895, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13896] = { + itemId = 13896, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13897] = { + itemId = 13897, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13898] = { + itemId = 13898, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13899] = { + itemId = 13899, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13900] = { + itemId = 13900, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13901] = { + itemId = 13901, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13902] = { + itemId = 13902, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13903] = { + itemId = 13903, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13904] = { + itemId = 13904, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13905] = { + itemId = 13905, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13906] = { + itemId = 13906, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13907] = { + itemId = 13907, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13908] = { + itemId = 13908, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13909] = { + itemId = 13909, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13910] = { + itemId = 13910, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13911] = { + itemId = 13911, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13912] = { + itemId = 13912, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13913] = { + itemId = 13913, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13914] = { + itemId = 13914, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13915] = { + itemId = 13915, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13916] = { + itemId = 13916, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13917] = { + itemId = 13917, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13918] = { + itemId = 13918, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13919] = { + itemId = 13919, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds + [13920] = { + itemId = 13920, + msg = "You are gathering some spiderweb cloud shreds. But you become entangled.", + storage = Storage.Kilmaresh.Eighth.Tefrit, + getValue = 2, + addValue = 36174 + }, -- Spider Cloud Shreds +} + +local scissorsfun = Action() +function scissorsfun.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local key = config[target.itemid] + if key then + if player:getStorageValue(key.storage) == key.getValue then + if table.contains({key.itemId + }, target.itemid) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, key.msg) + player:addItem(key.addValue, 1) + end + else + player:sendTextMessage(MESSAGE_FAILURE, "Sorry, not possible.") + end + end + return true +end + +scissorsfun:id(36162) +scissorsfun:register() diff --git a/data/scripts/actions/quests/kilmaresh/tortoise.lua b/data/scripts/actions/quests/kilmaresh/tortoise.lua new file mode 100644 index 00000000000..c1caee74a6c --- /dev/null +++ b/data/scripts/actions/quests/kilmaresh/tortoise.lua @@ -0,0 +1,17 @@ +local tortoise = Action() + +function tortoise.onUse(player, item, frompos, item2, topos) + + if player:getStorageValue(Storage.Kilmaresh.Thirteen.Presente) == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"Tortoise.") + player:addItem(36280, 1) + player:setStorageValue(Storage.Kilmaresh.Thirteen.Presente, 2) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The tortoise nest empty.") + end + + return true +end + +tortoise:uid(57528) +tortoise:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/kilmaresh/tumulo.lua b/data/scripts/actions/quests/kilmaresh/tumulo.lua new file mode 100644 index 00000000000..93e423d88b9 --- /dev/null +++ b/data/scripts/actions/quests/kilmaresh/tumulo.lua @@ -0,0 +1,17 @@ +local tumulo = Action() + +function tumulo.onUse(player, item, frompos, item2, topos) + + if player:getStorageValue(Storage.Kilmaresh.Thirteen.Presente) == 1 then + + -- player:setStorageValue(Storage.Kilmaresh.Treze.Presente, 2) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"The grave is empty. Nothing than gaping void.") + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Empty.") + end + + return true +end + +tumulo:uid(57543) +tumulo:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/kilmaresh/tumuloerro.lua b/data/scripts/actions/quests/kilmaresh/tumuloerro.lua new file mode 100644 index 00000000000..4374eee88a6 --- /dev/null +++ b/data/scripts/actions/quests/kilmaresh/tumuloerro.lua @@ -0,0 +1,17 @@ +local tumuloerro = Action() + +function tumuloerro.onUse(player, item, frompos, item2, topos) + + if player:getStorageValue(Storage.Kilmaresh.Thirteen.Presente) == 1 then + + -- player:setStorageValue(Storage.Kilmaresh.Treze.Presente, 2) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"The grave is empty. Nothing than gaping void.") + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Empty.") + end + + return true +end + +tumuloerro:uid(57544) +tumuloerro:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/koshei_amulet/bag.lua b/data/scripts/actions/quests/koshei_amulet/bag.lua new file mode 100644 index 00000000000..a14ab6cba45 --- /dev/null +++ b/data/scripts/actions/quests/koshei_amulet/bag.lua @@ -0,0 +1,32 @@ +local documentContent = [[ +PAGE 2 +Lord Koshei the Curious +-_-_-_-_-_-_-_-_-_-_-_- +Date of birth: unknown +Age: unknown +Hometown: unknown +Date of death: unknown +There are not many things known about this man. He appeared out of nowhere and lived here for nearly ten years. Even though he was communicative, he never told anything about his profession or what he did for a living. First he lived in Darashia 2, Flat 11 for about two years. During that time he was roaming around, travelling the lands of Darama and often visiting the Bath of Dreams and the minotaur pyramid in the North. +Then it was discovered that he had built a tower south of the mountains. It is unexplained how he managed to do that because no one has been seen to help him. Anyway, the remains of his tower are still there. ...]] + +local kosheiBag = Action() +function kosheiBag.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if (player:getStorageValue(483293) == -1) then + local bag = player:addItem(1987, 1) + if (bag) then + local document = bag:addItem(1968, 1) + if (document) then + document:setAttribute(ITEM_ATTRIBUTE_NAME, "Famous Inhabitants of Darashia, Page 2") + document:setAttribute(ITEM_ATTRIBUTE_TEXT, documentContent) + end + end + player:setStorageValue(483293) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You found a bag.") + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The bookcase is empty.") + end + return true +end + +kosheiBag:aid(40532) +kosheiBag:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/koshei_amulet/boss.lua b/data/scripts/actions/quests/koshei_amulet/boss.lua new file mode 100644 index 00000000000..91893d5f7b6 --- /dev/null +++ b/data/scripts/actions/quests/koshei_amulet/boss.lua @@ -0,0 +1,17 @@ +local kosheiBoss = Action() +function kosheiBoss.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid ~= 8272 then + return false + end + + if player:getStorageValue(Storage.SweetyCyclops.AmuletStatus) == 2 and player:getStorageValue(Storage.KosheiTheDeathless.RewardDoor) ~= 1 then + player:removeItem(8266, 1) + player:setStorageValue(Storage.KosheiTheDeathless.RewardDoor, 1) + toPosition:sendMagicEffect(CONST_ME_MAGIC_RED) + player:say("At last.. I have it back, my precious amulet. I am glad you didn't use it! I allow you to ...ahh... enter door ...ahh", TALKTYPE_MONSTER_SAY, false, player, toPosition) + end + return true +end + +kosheiBoss:id(8266) +kosheiBoss:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/koshei_amulet/switch.lua b/data/scripts/actions/quests/koshei_amulet/switch.lua new file mode 100644 index 00000000000..170c9573c5e --- /dev/null +++ b/data/scripts/actions/quests/koshei_amulet/switch.lua @@ -0,0 +1,45 @@ +local config = { + {position = Position(33281, 32442, 8), itemId = 3698}, + {position = Position(33286, 32444, 8), itemId = 3698}, + {position = Position(33276, 32444, 8), itemId = 3697}, + {position = Position(33278, 32450, 8), itemId = 3697}, + {position = Position(33284, 32450, 8), itemId = 3697} +} + +local coffinPosition = Position(33273, 32458, 8) + +local function revertCoffin() + local coffinItem = Tile(coffinPosition):getItemById(7525) + if coffinItem then + coffinItem:transform(7520) + end +end + +local kosheiSwitch = Action() +function kosheiSwitch.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local statuesInOrder, statueItem = true + for i = 1, #config do + local statue = config[i] + statueItem = Tile(statue.position):getItemById(statue.itemId) + if not statueItem then + statuesInOrder = false + break + end + end + + if not statuesInOrder or Tile(coffinPosition):getItemById(7525) then + player:say('Nothing happens', TALKTYPE_MONSTER_SAY, false, player, toPosition) + return true + end + + local coffinItem = Tile(coffinPosition):getItemById(7520) + if coffinItem then + coffinItem:transform(7525) + addEvent(revertCoffin, 2 * 60 * 1000) + player:say('CLICK', TALKTYPE_MONSTER_SAY, false, player, coffinPosition) + end + return true +end + +kosheiSwitch:uid(3070) +kosheiSwitch:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/lions_rock/lions_rock.lua b/data/scripts/actions/quests/lions_rock/lions_rock.lua new file mode 100644 index 00000000000..2abfe7bbaa2 --- /dev/null +++ b/data/scripts/actions/quests/lions_rock/lions_rock.lua @@ -0,0 +1,235 @@ +local lionsRockSanctuaryRockId = 3608 + +local rewards = { + 'emerald bangle', + 'giant shimmering pearl', + 'gold ingot', + 'green gem', + 'red gem', + "lion's heart", + 'yellow gem' +} + +local UniqueTable = { + [40004] = { + storage = Storage.LionsRock.LionsStrength, + itemPosition = {x = 33137, y = 32291, z = 8}, + pagodaPosition = { x = 33134, y = 32289, z = 8}, + item = 10551, + storage = Storage.LionsRock.Questline, + value = 1, + newValue = 2, + message = "You have sacrificed a cobra tongue at an ancient statue. The light in the small \z + pyramid nearby begins to shine.", + effect = CONST_ME_BLOCKHIT, + }, + [40005] = { + storage = Storage.LionsRock.LionsBeauty, + itemPosition = {x = 33138, y = 32369, z = 8}, + pagodaPosition = { x = 33136, y = 32369, z = 8}, + item = 23760, + storage = Storage.LionsRock.Questline, + value = 2, + newValue = 3, + message = "You burnt a lion's mane flower. The light in the small pyramid nearby begins to shine.", + effect = CONST_ME_REDSMOKE + }, + [40006] = { + storage = Storage.LionsRock.LionsTears, + itemPosition = {x = 33154, y = 32279, z = 8}, + pagodaPosition = { x = 33156, y = 32279, z = 8}, + item = 23835, + storage = Storage.LionsRock.Questline, + value = 3, + newValue = 4, + message = "You have purified a sacret pedestal with holy water. You have now passed the last test\z + to enter thge inner sanctum.", + effect = CONST_ME_LOSEENERGY + } +} + +-- Lions rock skeleton +local lionsRockSkeleton = Action() + +function lionsRockSkeleton.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local setting = CorpseUnique[item.uid] + if not setting then + return true + end + + if player:getStorageValue(Storage.LionsRock.Questline) < 0 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have discovered a skeleton. It seems to hold an old parchment.') + player:addItem(23784, 1):setAttribute( + ITEM_ATTRIBUTE_TEXT, + "\"Still it is hard to believe that I finally found the mystical rock formations near Darashia, \z + known as Lion's Rock. According to ancient records there is a temple for an unknown, probably long \z + forgotten deity, built in the tunnels deep below the rock centuries ago. This holy site was once guarded \z + by mystical lions and they may still be down there. But yet I haven't succeeded in entering the inner \z + sanctum. The entrance to the lower temple areas is protected by an old and powerful enchantment. I \z + studied the inscriptions on the temple walls and thus learned that the key to the inner sanctum is the \z + passing of three tests. The first test is the Lion's Strength. In order to honour the site's mystical \z + cats of prey one has to hunt and slay a cobra. The cobra's tongue must be laid down at a stone statue as \z + a sacrifice. The second test is the Lion's Beauty. One has to burn the petals of a lion's mane flower on \z + a coal basin. In the sand at the rock's foot I saw some dried lion's mane petals. Maybe these flowers \z + grow somewhere upwards. The third test is called the Lion's Tears. It seems one has to purify an \z + ornamented stone pedestal with ...\" At this point the records end because the parchment is destroyed. \z + It seems that is was torn by a big paw ..." + ) + player:setStorageValue(Storage.LionsRock.Questline, 1) + player:setStorageValue(Storage.TibiaTales.DefaultStart, 1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end + return true +end + +lionsRockSkeleton:uid(20002) +lionsRockSkeleton:register() + +-- Lions rock sacrifices +local lionsRockSacrificesTest = Action() + +function lionsRockSacrificesTest.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local setting = UniqueTable[target.uid] + if not setting then + return true + end + + local function reset() + local pagodaLit = Tile(setting.itemPosition):getItemById(3710) + if pagodaLit then + pagodaLit:transform(3709) + end + end + + if item.itemid == setting.item then + if player:getStorageValue(setting.storage) == setting.value then + local pagoda = Tile(setting.pagodaPosition):getItemById(3709) + if pagoda then + pagoda:transform(3710) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, setting.message) + player:setStorageValue(setting.storage, setting.newValue) + player:removeItem(setting.item, 1) + toPosition:sendMagicEffect(setting.effect) + addEvent(reset, 15 * 1000) + end + end + end + return true +end + +lionsRockSacrificesTest:id(10551) +lionsRockSacrificesTest:id(23760) +lionsRockSacrificesTest:id(23835) +lionsRockSacrificesTest:register() + +-- Get lions mane +local lionsGetLionsMane = Action() + +function lionsGetLionsMane.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 23759 then + if player:getStorageValue(Storage.LionsRock.Questline) > 0 then + if player:getStorageValue(Storage.LionsRock.GetLionsMane) < 0 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You picked a beautiful lion's mane flower.") + player:addItem(23760, 1) + player:setStorageValue(Storage.LionsRock.GetLionsMane, 1) + end + end + end + return true +end + +lionsGetLionsMane:id(23759) +lionsGetLionsMane:register() + +-- Get holy water +local lionsGetHolyWater = Action() + +function lionsGetHolyWater.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local setting = ItemUnique[item.uid] + if not setting then + return true + end + + if player:getStorageValue(Storage.LionsRock.Questline) > 0 then + if player:getStorageValue(Storage.LionsRock.GetHolyWater) < 0 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You took some holy water from the sacred well.') + player:addItem(23835, 1) + player:setStorageValue(Storage.LionsRock.GetHolyWater, 1) + end + end + return true +end + +lionsGetHolyWater:uid(40007) +lionsGetHolyWater:register() + +-- Rock translation scroll +local lionsRockTranslationScroll = Action() + +function lionsRockTranslationScroll.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local amphoraPos = Position(33119, 32247, 9) + local amphoraID = 24314 + local amphoraBrokenID = 24315 + + local function reset() + local brokenAmphora = Tile(amphoraPos):getItemById(amphoraBrokenID) + if brokenAmphora then + brokenAmphora:transform(amphoraID) + end + end + + if player:getStorageValue(Storage.LionsRock.Questline) == 4 then + local amphora = Tile(amphoraPos):getItemById(amphoraID) + if amphora then + amphora:transform(amphoraBrokenID) + player:sendTextMessage( + MESSAGE_EVENT_ADVANCE, + 'As you pass incautiously, the ancient amphora crumbles to shards and dust. \z + Amidst the debris you discover an old scroll.' + ) + player:setStorageValue(Storage.LionsRock.Questline, 5) + player:addItem(23836, 1) + toPosition:sendMagicEffect(CONST_ME_GROUNDSHAKER) + addEvent(reset, 15 * 1000) + end + end + return true +end + +lionsRockTranslationScroll:uid(40008) +lionsRockTranslationScroll:register() + +-- Lions rock fountain +local lionsRockFountain = Action() + +function lionsRockFountain.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.LionsRock.Time) < os.time() then + local reward = '' + if (player:hasMount(40)) then + repeat + reward = math.random(1, #rewards) + until (rewards[reward] ~= "lion's heart") + else + reward = math.random(1, #rewards) + end + + if (player:getStorageValue(Storage.LionsRock.Questline) == 10) then + player:setStorageValue(Storage.LionsRock.Questline, 11) + end + + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + "Something sparkles in the fountain's water. You draw out a " .. rewards[reward] .. '.') + player:sendMagicEffect(CONST_ME_HOLYAREA) + player:addAchievement("Lion's Den Explorer") + item:transform(lionsRockSanctuaryRockId) + player:addItem(rewards[reward], 1) + player:setStorageValue(Storage.LionsRock.Time, os.time() + 24 * 60 * 60) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + 'At the moment there is neither a treasure nor anything else in the fountain. Perhaps you might return later.') + end + return true +end + +lionsRockFountain:id(6390) +lionsRockFountain:register() diff --git a/data/scripts/actions/quests/liquid_black/chairteleport.lua b/data/scripts/actions/quests/liquid_black/chairteleport.lua new file mode 100644 index 00000000000..59829135b01 --- /dev/null +++ b/data/scripts/actions/quests/liquid_black/chairteleport.lua @@ -0,0 +1,19 @@ +local teleportplayer = {x = 33269, y = 31832, z = 1} + +local chairteleport = Action() + +function chairteleport.onUse(player, item, frompos, item2, topos) + + if player:getStorageValue(Storage.LiquidBlackQuest.Visitor) == 2 then + player:teleportTo(teleportplayer) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"Teleport.") + player:setStorageValue(Storage.LiquidBlackQuest.Visitor, 3) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Empty.") + end + + return true +end + +chairteleport:uid(57744) +chairteleport:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/liquid_black/notescoordinates.lua b/data/scripts/actions/quests/liquid_black/notescoordinates.lua new file mode 100644 index 00000000000..2887304073c --- /dev/null +++ b/data/scripts/actions/quests/liquid_black/notescoordinates.lua @@ -0,0 +1,17 @@ +local notescoordinates = Action() + +function notescoordinates.onUse(player, item, frompos, item2, topos) + + if player:getStorageValue(Storage.LiquidBlackQuest.Visitor) == -1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You have found notes and coordinates.") + player:addItem(15576, 1) + player:setStorageValue(Storage.LiquidBlackQuest.Visitor, 2) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Empty.") + end + + return true +end + +notescoordinates:uid(57743) +notescoordinates:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/lower_roshamuul/bone.lua b/data/scripts/actions/quests/lower_roshamuul/bone.lua new file mode 100644 index 00000000000..941e7504606 --- /dev/null +++ b/data/scripts/actions/quests/lower_roshamuul/bone.lua @@ -0,0 +1,29 @@ +local function revertBone(position, itemId, transformId) + local item = Tile(position):getItemById(itemId) + if item then + item:transform(transformId) + end +end + +local lowerRoshamuulBone = Action() +function lowerRoshamuulBone.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local rand = math.random(1, 100) + if item.itemid == 22513 then + if rand <= 20 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Amidst the pile of various bones you find large, hollow part, similar to a pipe.') + player:addItem(22389, 1) + item:transform(11253, 22513) + addEvent(revertBone, 120000, toPosition, 11253, 22513) + toPosition:sendMagicEffect(3) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You ransack the pile but fail to find any useful parts.') + item:transform(11253, 22513) + addEvent(revertBone, 120000, toPosition, 11253, 22513) + toPosition:sendMagicEffect(3) + doSummonCreature("Guzzlemaw", toPosition) + end + end +end + +lowerRoshamuulBone:id(22513) +lowerRoshamuulBone:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/lower_roshamuul/chalk.lua b/data/scripts/actions/quests/lower_roshamuul/chalk.lua new file mode 100644 index 00000000000..4910631c9ff --- /dev/null +++ b/data/scripts/actions/quests/lower_roshamuul/chalk.lua @@ -0,0 +1,27 @@ +local data = {} + +local lowerRoshamuulChalk = Action() +function lowerRoshamuulChalk.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local bucket = player:getItemById(2005, true, 0) + if bucket == nil then + return fromPosition:sendMagicEffect(3) + end + + if not data[player:getId()] then + data[player:getId()] = 0 + end + + data[player:getId()] = data[player:getId()] + 1 + if data[player:getId()] > 10 then + bucket:transform(22388) + data[player:getId()] = 0 + end + + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You fill some of the fine chalk into a bucket.") + item:transform(22470) + item:decay() + return true +end + +lowerRoshamuulChalk:id(22459) +lowerRoshamuulChalk:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/lower_roshamuul/gravel.lua b/data/scripts/actions/quests/lower_roshamuul/gravel.lua new file mode 100644 index 00000000000..2d4579cb05b --- /dev/null +++ b/data/scripts/actions/quests/lower_roshamuul/gravel.lua @@ -0,0 +1,27 @@ +local data = {} + +local lowerRoshamuulGravel = Action() +function lowerRoshamuulGravel.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local bucket = player:getItemById(2005, true, 0) + if bucket == nil then + return fromPosition:sendMagicEffect(3) + end + + if not data[player:getId()] then + data[player:getId()] = 0 + end + + data[player:getId()] = data[player:getId()] + 1 + if data[player:getId()] > 10 then + bucket:transform(22387) + data[player:getId()] = 0 + end + + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You gather some fine gravel.") + item:transform(22468) + item:decay() + return true +end + +lowerRoshamuulGravel:id(22467) +lowerRoshamuulGravel:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/lower_roshamuul/mixture.lua b/data/scripts/actions/quests/lower_roshamuul/mixture.lua new file mode 100644 index 00000000000..d429132f03c --- /dev/null +++ b/data/scripts/actions/quests/lower_roshamuul/mixture.lua @@ -0,0 +1,20 @@ +local buckets = { + [22387] = 22388, + [22388] = 22387 +} + +local lowerRoshamuulMixtune = Action() +function lowerRoshamuulMixtune.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if (target == nil) or not target:isItem() then + return false + end + + if target:getId() == buckets[item:getId()] then + item:transform(2005, 0) + target:transform(22503) + end + return true +end + +lowerRoshamuulMixtune:id(22387,22388) +lowerRoshamuulMixtune:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/lower_roshamuul/mortar.lua b/data/scripts/actions/quests/lower_roshamuul/mortar.lua new file mode 100644 index 00000000000..ffaed9789ae --- /dev/null +++ b/data/scripts/actions/quests/lower_roshamuul/mortar.lua @@ -0,0 +1,15 @@ +local lowerRoshamuulMortar = Action() +function lowerRoshamuulMortar.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if (target == nil) or not target:isItem() then + return false + end + + if (target:getId() == 2005) and (target:getFluidType() == 1) then + item:transform(2005, 0) + target:transform(22504) + end + return true +end + +lowerRoshamuulMortar:id(22503) +lowerRoshamuulMortar:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/lower_roshamuul/resonance_chamber.lua b/data/scripts/actions/quests/lower_roshamuul/resonance_chamber.lua new file mode 100644 index 00000000000..1e02412a6b0 --- /dev/null +++ b/data/scripts/actions/quests/lower_roshamuul/resonance_chamber.lua @@ -0,0 +1,106 @@ +local config = { + item = 22535, + storage = 34380, + position = { + Position(33637, 32516, 5), -- Top Left + Position(33664, 32537, 5), -- botton Right + Position(33650, 32527, 5) -- Center + }, + raid = { + [1] = {"silencer", math.random(8,15) }, + [2] = {"silencer", math.random(11,18) }, + [3] = {"silencer", math.random(8,15) }, + [4] = {"sight of surrender", math.random(3,8) } + }, + globalEventTime = 30 * 60 * 1000, -- [30min] waiting time to get started again + timeBetweenraid = 1 * 60 * 1000, -- [1min] Waiting time between each raid + cleanraid = true -- Clean zone after globalEventTime +} + +local function raids(monster) + local randX,randY,randZ = 0,0,0 + randX = math.random(config.position[1].x, config.position[2].x) + randY = math.random(config.position[1].y, config.position[2].y) + randZ = math.random(config.position[1].z, config.position[2].z) + + local pos = Position(randX, randY, randZ) + local tile = Tile(pos) + if not tile then return false end + + if tile:isWalkable(true, false, false, false, true) then + Game.createMonster(monster, Position(randX, randY, randZ)) + else + raids(monster) + end +end + +local function cleanRaid() + local mostersraid= Game.getSpectators(config.position[3], false, false, 13, 13, 11, 11) + for i = 1, #mostersraid do + if mostersraid[i]:isMonster() then + mostersraid[i]:remove() + end + end +end + +local lowerRoshamuulChamber = Action() +function lowerRoshamuulChamber.onUse(cid, item, fromPosition, itemEx, toPosition) + local player = Player(cid) + local max,time,monster = 0,0,"" + + if item.itemid ~= config.item then + return true + end + local spectators,hasPlayer,hasMonsters = Game.getSpectators(config.position[3], false, false, 13, 13, 11, 11),false,false + for i = 1, #spectators do + if spectators[i]:isPlayer() then + if spectators[i]:getName() == player:getName() then + hasPlayer = true + end + elseif spectators[i]:isMonster() then + hasMonsters = true + end + end + if not hasPlayer then + player:sendCancelMessage('Use on Silencer Plateau is located in the south-eastern part of Roshamuul') + return true + end + if hasMonsters then + player:sendCancelMessage('You need kill all monsters') + return true + end + + if Game.getStorageValue(config.storage) <= 0 then + if math.random(0,10000) < 7000 then + player:say("PRRRR...*crackle*", TALKTYPE_MONSTER_SAY) + item:remove(1) + return true + else + player:say("PRRRROOOOOAAAAAHHHH!!!", TALKTYPE_MONSTER_SAY) + end + + local raid = config.raid + for y, x in pairs(raid) do + local i = 1 + while i <= #x do + time = time + config.timeBetweenraid + for j = 1, x[i+1] do + Game.setStorageValue(config.storage,x[i+1]) + addEvent(raids,time,x[i]) + end + i = i + 2 + end + end + + addEvent(Game.setStorageValue, config.globalEventTime, config.storage, 0) + if config.cleanraid then + addEvent(cleanRaid, config.globalEventTime) + end + item:remove(1) + else + player:sendCancelMessage('You need to wait') + end +end + +lowerRoshamuulChamber:id(22535) +lowerRoshamuulChamber:register() diff --git a/data/scripts/actions/quests/lower_roshamuul/trough.lua b/data/scripts/actions/quests/lower_roshamuul/trough.lua new file mode 100644 index 00000000000..b9c2fa80fc5 --- /dev/null +++ b/data/scripts/actions/quests/lower_roshamuul/trough.lua @@ -0,0 +1,16 @@ +local lowerRoshamuulTrough = Action() +function lowerRoshamuulTrough.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if (target == nil) or not target:isItem() then + return false + end + + if target:getId() == 22550 then + item:transform(2005, 0) + toPosition:sendMagicEffect(10) + player:setStorageValue(ROSHAMUUL_MORTAR_THROWN, math.max(0, player:getStorageValue(ROSHAMUUL_MORTAR_THROWN)) + 1) + end + return true +end + +lowerRoshamuulTrough:id(22504) +lowerRoshamuulTrough:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/mysterious_ornate/mysterious_metal_egg.lua b/data/scripts/actions/quests/mysterious_ornate/mysterious_metal_egg.lua new file mode 100644 index 00000000000..1be521ae6c6 --- /dev/null +++ b/data/scripts/actions/quests/mysterious_ornate/mysterious_metal_egg.lua @@ -0,0 +1,8 @@ +local mysterious = Action() +function mysterious.onUse(cid, item, fromPosition, itemEx, toPosition) + local p = {x = 33672, y = 31884, z = 5} -- where to tp to 33672, 31884, 5 + doCreatureSay(cid, "This metal egg seems to be locked by a strange mechanism. The time for it to reveal its contents has not yet come.", TALKTYPE_ORANGE_1) +end + +mysterious:id(21382, 25395) +mysterious:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/oramond/chavis_tasks/to_take_roots.lua b/data/scripts/actions/quests/oramond/chavis_tasks/to_take_roots.lua new file mode 100644 index 00000000000..6464550cbaa --- /dev/null +++ b/data/scripts/actions/quests/oramond/chavis_tasks/to_take_roots.lua @@ -0,0 +1,62 @@ +local function revertRoot(position, itemId, transformId) + local item = Tile(position):getItemById(itemId) + if item then + item:transform(transformId) + end +end + +local toTakeRoots = Action() +function toTakeRoots.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local rand = math.random(1, 100) + if item.itemid == 23475 then + if rand <= 50 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You successfully harvest some juicy roots.') + player:addItem(23662, 1) + item:transform(item.itemid + 2) + addEvent(revertRoot, 120000, toPosition, 23477, 23475) + toPosition:sendMagicEffect(CONST_ME_GREEN_RINGS) + if player:getStorageValue(Storage.Oramond.QuestLine) <= 0 then + player:setStorageValue(Storage.Oramond.QuestLine, 1) + end + if player:getStorageValue(Storage.Oramond.MissionToTakeRoots) <= 0 then + player:setStorageValue(Storage.Oramond.MissionToTakeRoots, 1) + end + player:setStorageValue(Storage.Oramond.HarvestedRootCount, + player:getStorageValue(Storage.Oramond.HarvestedRootCount) > 0 + and player:getStorageValue(Storage.Oramond.HarvestedRootCount) + 1 or 1) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Your harvesting attempt destroyed more of the juicy roots than you could salvage.') + item:transform(item.itemid + 2) + addEvent(revertRoot, 120000, toPosition, 23477, 23475) + toPosition:sendMagicEffect(CONST_ME_GREEN_RINGS) + end + elseif item.itemid == 23476 then + if rand <= 50 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You successfully harvest some juicy roots.') + player:addItem(23662, 1) + item:transform(item.itemid + 2) + addEvent(revertRoot, 120000, toPosition, 23478, 23476) + toPosition:sendMagicEffect(CONST_ME_GREEN_RINGS) + if player:getStorageValue(Storage.Oramond.QuestLine) <= 0 then + player:setStorageValue(Storage.Oramond.QuestLine, 1) + end + if player:getStorageValue(Storage.Oramond.MissionToTakeRoots) <= 0 then + player:setStorageValue(Storage.Oramond.MissionToTakeRoots, 1) + end + player:setStorageValue(Storage.Oramond.HarvestedRootCount, + player:getStorageValue(Storage.Oramond.HarvestedRootCount) > 0 + and player:getStorageValue(Storage.Oramond.HarvestedRootCount) + 1 or 1) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Your harvesting attempt destroyed more of the juicy roots than you could salvage.') + item:transform(item.itemid + 2) + addEvent(revertRoot, 120000, toPosition, 23478, 23476) + toPosition:sendMagicEffect(CONST_ME_GREEN_RINGS) + end + elseif item.itemid == 23477 or item.itemid == 23478 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'This root has already been harvested, nothing to gain here.') + end + return true +end + +toTakeRoots:id(23475,23476,23477,23478) +toTakeRoots:register() diff --git a/data/scripts/actions/quests/oramond/glooth_fairy_lever.lua b/data/scripts/actions/quests/oramond/glooth_fairy_lever.lua new file mode 100644 index 00000000000..e9507ad8517 --- /dev/null +++ b/data/scripts/actions/quests/oramond/glooth_fairy_lever.lua @@ -0,0 +1,68 @@ +local function removeBosst(fromArea1, fromArea2, bossName) + for x = fromArea1.x, fromArea2.x do + for y = fromArea1.y, fromArea2.y do + for z = fromArea1.z, fromArea2.z do + if(getTopCreature({x = x, y = y, z = z, stackpos = 255}).uid > 0) then + if(isMonster(getTopCreature({x = x, y = y, z = z, stackpos = 255}).uid)) then + if(string.lower(getCreatureName(getTopCreature({x = x, y = y, z = z, stackpos = 255}).uid)) == bossName) then + doRemoveCreature(getTopCreature({x = x, y = y, z = z, stackpos = 255}).uid) + end + end + end + end + end + end + return true +end + +local function teleportAllPlayersFromAreat(fromArea1, fromArea2, toPos) + for x = fromArea1.x, fromArea2.x do + for y = fromArea1.y, fromArea2.y do + for z = fromArea1.z, fromArea2.z do + if(getTopCreature({x = x, y = y, z = z, stackpos = 255}).uid > 0) then + if(isPlayer(getTopCreature({x = x, y = y, z = z, stackpos = 255}).uid)) then + doTeleportThing(getTopCreature({x = x, y = y, z = z, stackpos = 255}).uid, toPos) + doSendMagicEffect(toPos, CONST_ME_TELEPORT) + end + end + end + end + end + return true +end + +local function PrepareEnter() + removeBosst({x=33679,y=31919,z=9}, {x=33701,y=31941,z=9}, "glooth fairy") + teleportAllPlayersFromAreat({x=33659,y=31935,z=9},{x=33668,y=31939,z=9},{x=33684,y=31935,z=9}) + Game.createMonster("Glooth Fairy", {x=33688,y=31937,z=9}) +end + +local oramondGloothLever = Action() +function oramondGloothLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 9827 then + if getGlobalStorageValue(18081) >= os.time() then + doPlayerSendTextMessage(player, 19, "You need to wait 15 minutes to use again.") + return true + end + + local specs, spec = Game.getSpectators({x=33688,y=31932,z=9}, false, false, 13, 13, 13, 13) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "A team is already inside the quest room.") + return true + end + spec:remove() + end + setGlobalStorageValue(18081, os.time()+15*60) + player:say("Everyone in this place will be teleported into Glooth Fairy\'s hideout in one minute. No way back!!!", TALKTYPE_MONSTER_SAY) + addEvent(PrepareEnter,60*1000) + + end + + item:transform(item.itemid == 9827 and 9828 or 9827) + return true +end + +oramondGloothLever:uid(1020) +oramondGloothLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/oramond/the_glooth_brothers_tasks/the_ancient_sewers.lua b/data/scripts/actions/quests/oramond/the_glooth_brothers_tasks/the_ancient_sewers.lua new file mode 100644 index 00000000000..ce6e28ef4af --- /dev/null +++ b/data/scripts/actions/quests/oramond/the_glooth_brothers_tasks/the_ancient_sewers.lua @@ -0,0 +1,81 @@ +local function revertItem(toPosition, getItemId, itemTransform) + local tile = toPosition:getTile() + if tile then + local thing = tile:getItemById(getItemId) + if thing then + thing:transform(itemTransform) + end + end +end + +local config = { + [23410] = {itemGerator = 24161, itemTransform = 23410}, -- Gerator 1 + [23411] = {itemGerator = 24161, itemTransform = 23411} -- Gerator 2 +} + +local theAncientSewers = Action() + +function theAncientSewers.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local gerator = config[item.itemid] + if gerator then + local chance = math.random(1, 100) + if((chance >= 1) and (chance < 50)) then + player:say(" There This piece fixed.", TALKTYPE_ORANGE_1) + elseif((chance >= 50) and (chance < 100)) then + player:say(" This should do it.", TALKTYPE_ORANGE_1) + end + + item:transform(gerator.itemGerator) + addEvent(revertItem, 2 * 60 * 1000, toPosition, gerator.itemGerator, gerator.itemTransform) + toPosition:sendMagicEffect(CONST_ME_BLOCKHIT) + if player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) <= 0 then + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer,1) + player:setStorageValue(Storage.Oramond.MissionToTakeRoots1) + elseif player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) == 1 then + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer,2) + elseif player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) == 2 then + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer,3) + elseif player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) == 3 then + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer,4) + elseif player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) == 4 then + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer,5) + elseif player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) == 5 then + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer,6) + elseif player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) == 6 then + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer,7) + elseif player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) == 7 then + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer,8) + elseif player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) == 8 then + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer,9) + elseif player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) == 9 then + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer,10) + elseif player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) == 10 then + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer,11) + elseif player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) == 11 then + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer,12) + elseif player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) == 12 then + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer,13) + elseif player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) == 13 then + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer,14) + elseif player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) == 14 then + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer,15) + elseif player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) == 15 then + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer,16) + elseif player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) == 16 then + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer,17) + elseif player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) == 17 then + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer,18) + elseif player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) == 18 then + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer,19) + elseif player:getStorageValue(Storage.Oramond.MissionAbandonedSewer) == 19 then + if player:getStorageValue(Storage.DarkTrails.Mission03) < 1 then + player:setStorageValue(Storage.DarkTrails.Mission03,1) + end + player:setStorageValue(Storage.Oramond.MissionAbandonedSewer, 20) + end + end + return true +end + +theAncientSewers:id(23410, 23411) +theAncientSewers:register() diff --git a/data/scripts/actions/quests/others/black_knight_quest.lua b/data/scripts/actions/quests/others/black_knight_quest.lua new file mode 100644 index 00000000000..33310ab8698 --- /dev/null +++ b/data/scripts/actions/quests/others/black_knight_quest.lua @@ -0,0 +1,15 @@ +local othersBlackKnight = Action() +function othersBlackKnight.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.QuestChests.BlackKnightTreeKey) ~= 1 then + local newItem = Game.createItem(2088, 1) + newItem:setActionId(5010) + player:addItemEx(newItem) + player:setStorageValue(Storage.QuestChests.BlackKnightTreeKey, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a silver key.") + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The ' .. ItemType(item.itemid):getName() .. ' is empty.') + end +end + +othersBlackKnight:aid(5558) +othersBlackKnight:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/others/calassa_comb_door.lua b/data/scripts/actions/quests/others/calassa_comb_door.lua new file mode 100644 index 00000000000..dee2719f027 --- /dev/null +++ b/data/scripts/actions/quests/others/calassa_comb_door.lua @@ -0,0 +1,18 @@ +local othersCalassa = Action() +function othersCalassa.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid ~= 5745 then + return false + end + + if player:getStorageValue(Storage.OutfitQuest.firstOrientalAddon) ~= 1 or player:hasOutfit(player:getSex() == PLAYERSEX_FEMALE and 150 or 146, 1) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The door seems to be sealed against unwanted intruders.') + return true + end + + item:transform(item.itemid + 1) + player:teleportTo(toPosition, true) + return true +end + +othersCalassa:aid(50161) +othersCalassa:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/others/deeper_banuta_shortcut.lua b/data/scripts/actions/quests/others/deeper_banuta_shortcut.lua new file mode 100644 index 00000000000..f43da945a04 --- /dev/null +++ b/data/scripts/actions/quests/others/deeper_banuta_shortcut.lua @@ -0,0 +1,18 @@ +local othersDeeper = Action() +function othersDeeper.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid ~= 62378 then + return false + end + + if player:getStorageValue(Storage.BanutaSecretTunnel.DeeperBanutaShortcut) ~= 1 then + player:removeItem(10523, 1) + player:setStorageValue(Storage.BanutaSecretTunnel.DeeperBanutaShortcut, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You discovered a secret tunnel.") + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have already discovered this secret.") + end + return true +end + +othersDeeper:id(10523) +othersDeeper:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/others/desert_dungeon_lever_quest.lua b/data/scripts/actions/quests/others/desert_dungeon_lever_quest.lua new file mode 100644 index 00000000000..facf7276fba --- /dev/null +++ b/data/scripts/actions/quests/others/desert_dungeon_lever_quest.lua @@ -0,0 +1,82 @@ +local config = { + { + fromPosition = Position(32677, 32089, 8), + toPosition = Position(32671, 32071, 8), + sacrificePosition = Position(32679, 32089, 8), + sacrificeId = 2175, + vocationId = VOCATION.CLIENT_ID.SORCERER + }, + { + fromPosition = Position(32669, 32089, 8), + toPosition = Position(32673, 32071, 8), + sacrificePosition = Position(32667, 32089, 8), + sacrificeId = 2674, + vocationId = VOCATION.CLIENT_ID.DRUID + }, + { + fromPosition = Position(32673, 32085, 8), + toPosition = Position(32670, 32071, 8), + sacrificePosition = Position(32673, 32083, 8), + sacrificeId = 2455, + vocationId = VOCATION.CLIENT_ID.PALADIN + }, + { + fromPosition = Position(32673, 32093, 8), + toPosition = Position(32672, 32071, 8), + sacrificePosition = Position(32673, 32094, 8), + sacrificeId = 2376, + vocationId = VOCATION.CLIENT_ID.KNIGHT + } +} + +local othersDesert = Action() +function othersDesert.onUse(player, item, fromPosition, target, toPosition, isHotkey) + item:transform(item.itemid == 1945 and 1946 or 1945) + + if item.itemid ~= 1945 then + return true + end + + local position = player:getPosition() + + local players = {} + for i = 1, #config do + local creature = Tile(config[i].fromPosition):getTopCreature() + if not creature or not creature:isPlayer() then + player:sendCancelMessage('You need one player of each vocation for this quest.') + position:sendMagicEffect(CONST_ME_POFF) + return true + end + + local vocationId = creature:getVocation():getClientId() + if vocationId ~= config[i].vocationId then + player:sendCancelMessage('You need one player of each vocation for this quest.') + position:sendMagicEffect(CONST_ME_POFF) + return true + end + + local sacrificeItem = Tile(config[i].sacrificePosition):getItemById(config[i].sacrificeId) + if not sacrificeItem then + player:sendCancelMessage(creature:getName() .. ' is missing ' .. (creature:getSex() == PLAYERSEX_FEMALE and 'her' or 'his') .. ' sacrifice on the altar.') + position:sendMagicEffect(CONST_ME_POFF) + return true + end + + players[#players + 1] = creature + end + + for i = 1, #players do + local sacrificeItem = Tile(config[i].sacrificePosition):getItemById(config[i].sacrificeId) + if sacrificeItem then + sacrificeItem:remove() + end + + players[i]:getPosition():sendMagicEffect(CONST_ME_POFF) + players[i]:teleportTo(config[i].toPosition) + config[i].toPosition:sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +othersDesert:uid(1912) +othersDesert:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/others/ectoplasm_container.lua b/data/scripts/actions/quests/others/ectoplasm_container.lua new file mode 100644 index 00000000000..7448bed54b4 --- /dev/null +++ b/data/scripts/actions/quests/others/ectoplasm_container.lua @@ -0,0 +1,25 @@ +local othersEctoplasm = Action() +function othersEctoplasm.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid == 4206 then + if player:getStorageValue(Storage.TibiaTales.IntoTheBonePit) ~= 1 then + return false + end + + player:setStorageValue(Storage.TibiaTales.IntoTheBonePit, 2) + item:transform(4864) + target:remove() + toPosition:sendMagicEffect(CONST_ME_POFF) + elseif target.itemid == 3108 then + if player:getStorageValue(Storage.ExplorerSociety.TheEctoplasm) == 45 and player:getStorageValue(Storage.ExplorerSociety.QuestLine) == 45 then + player:setStorageValue(Storage.ExplorerSociety.TheEctoplasm, 46) + player:setStorageValue(Storage.ExplorerSociety.QuestLine, 46) + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + item:transform(8182) + target:remove() + end + end + return true +end + +othersEctoplasm:id(4863) +othersEctoplasm:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/others/fire_bug.lua b/data/scripts/actions/quests/others/fire_bug.lua new file mode 100644 index 00000000000..8fefcf56873 --- /dev/null +++ b/data/scripts/actions/quests/others/fire_bug.lua @@ -0,0 +1,71 @@ +local function revert(position, itemId, transformId) + local item = Tile(position):getItemById(itemId) + if item then + item:transform(transformId) + end +end + +local function revertAshes() + local item = Tile(Position(32849, 32233, 9)):getItemById(1387) + if item then + item:transform(2249) + local itemUid = Tile(Position(32849, 32233, 9)):getItemById(2249) + if itemUid then + itemUid:setAttribute(ITEM_ATTRIBUTE_UNIQUEID, 2243) + end + end +end + +local positions = { + Position(32848, 32230, 9), + Position(32849, 32230, 9), + Position(32847, 32231, 9), + Position(32848, 32231, 9), + Position(32849, 32231, 9), + Position(32850, 32231, 9), + Position(32848, 32232, 9), + Position(32849, 32232, 9) +} + +local othersFireBug = Action() +function othersFireBug.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid == 54387 and target.itemid == 25531 then + if player:getStorageValue(Storage.FerumbrasAscension.BasinCounter) >= 8 or player:getStorageValue(Storage.FerumbrasAscension.BoneFlute) < 1 then + return false + end + if player:getStorageValue(Storage.FerumbrasAscension.BasinCounter) < 0 then + player:setStorageValue(Storage.FerumbrasAscension.BasinCounter, 0) + end + if player:getStorageValue(Storage.FerumbrasAscension.BasinCounter) == 7 then + player:say('You ascended the last basin.', TALKTYPE_MONSTER_SAY) + item:remove() + player:setStorageValue(Storage.FerumbrasAscension.MonsterDoor, 1) + end + target:transform(25532) + player:setStorageValue(Storage.FerumbrasAscension.BasinCounter, player:getStorageValue(Storage.FerumbrasAscension.BasinCounter) + 1) + toPosition:sendMagicEffect(CONST_ME_FIREAREA) + addEvent(revert, 2 * 60 * 1000, toPosition, 25532, 25531) + return true + elseif target.uid == 2243 then + local tile = Tile(Position(32849, 32233, 9)) + local item = tile:getItemById(2249) + local createTeleport = Game.createItem(1387, 1, Position(32849, 32233, 9)) + for k, v in pairs(positions) do + v:sendMagicEffect(CONST_ME_YELLOW_RINGS) + end + item:remove() + addEvent(revertAshes, 5 * 60 * 1000) -- 5 minutes + createTeleport:setDestination(Position(32857, 32234, 11)) + return true + elseif target.uid == 2273 then + if player:getStorageValue(Storage.TheShatteredIsles.RaysMission2) == 1 then + player:setStorageValue(Storage.TheShatteredIsles.RaysMission2, 2) + toPosition:sendMagicEffect(CONST_ME_FIREAREA) + return true + end + end + return false +end + +othersFireBug:id(5468) +othersFireBug:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/others/gooey_mass.lua b/data/scripts/actions/quests/others/gooey_mass.lua new file mode 100644 index 00000000000..b3960b04b04 --- /dev/null +++ b/data/scripts/actions/quests/others/gooey_mass.lua @@ -0,0 +1,98 @@ +local UniqueTable = { + [40011] = { + storage = Storage.InsectoidCell.Reward1, + reward = 15572 + }, + [40012] = { + storage = Storage.InsectoidCell.Reward2, + reward = 15572 + }, + [40013] = { + storage = Storage.InsectoidCell.Reward3, + reward = 15572 + }, + [40014] = { + storage = Storage.InsectoidCell.Reward4, + reward = 15572 + }, + [40015] = { + storage = Storage.InsectoidCell.Reward5, + reward = 15572 + }, + [40016] = { + storage = Storage.InsectoidCell.Reward6, + reward = 15572 + }, + [40017] = { + storage = Storage.InsectoidCell.Reward7, + reward = 15572 + }, + [40018] = { + storage = Storage.InsectoidCell.Reward8, + reward = 15572 + }, + [40019] = { + storage = Storage.InsectoidCell.Reward9, + reward = 15572 + }, + [40020] = { + storage = Storage.InsectoidCell.Reward10, + reward = 15572 + }, + [40021] = { + storage = Storage.InsectoidCell.Reward11, + reward = 15572 + }, + [40022] = { + storage = Storage.InsectoidCell.Reward12, + reward = 15572 + }, + [40023] = { + storage = Storage.InsectoidCell.Reward13, + reward = 15572 + }, + [40024] = { + storage = Storage.InsectoidCell.Reward14, + reward = 15572 + }, + [40025] = { + storage = Storage.InsectoidCell.Reward15, + reward = 15572 + }, + [40026] = { + storage = Storage.InsectoidCell.Reward16, + reward = 15572 + } +} + +local gooeyMass = Action() + +function gooeyMass.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local setting = UniqueTable[item.uid] + if setting then + if player:getStorageValue(setting.storage) < os.time() then + local backpack = player:getSlotItem(CONST_SLOT_BACKPACK) + if backpack and backpack:getEmptySlots(true) >= 1 then + if (player:getFreeCapacity() / 100) > getItemWeight(setting.reward) then + player:addItem(setting.reward) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a " .. getItemName(setting.reward) .. ".") + player:setStorageValue(setting.storage, os.time() + 7 * 24 * 60 * 60) -- 7 days + return true + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a " .. getItemName(setting.reward) .. ". Weighing " .. getItemWeight(setting.reward) .. " oz it is too heavy.") + end + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a " .. getItemName(setting.reward) .. ", but you have no room to take it") + end + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The ".. getItemName(setting.itemId) .. " is empty.") + end + end + return true +end + +for index, value in pairs(UniqueTable) do + gooeyMass:uid(index) +end + +gooeyMass:register() diff --git a/data/scripts/actions/quests/others/hellgate_lever.lua b/data/scripts/actions/quests/others/hellgate_lever.lua new file mode 100644 index 00000000000..8e0748562d4 --- /dev/null +++ b/data/scripts/actions/quests/others/hellgate_lever.lua @@ -0,0 +1,34 @@ +local config = { + bridgePositions = { + Position(32627, 31699, 10), + Position(32628, 31699, 10), + Position(32629, 31699, 10) + }, + removeCreaturePosition = Position(32630, 31699, 10), + bridgeID = 5770, + waterID = 493 +} + +local othersHellGate = Action() +function othersHellGate.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local tile, thing, creature + for i = 1, #config.bridgePositions do + tile = Tile(config.bridgePositions[i]) + if tile then + thing, creature = tile:getItemById(item.itemid == 1945 and config.waterID or config.bridgeID), tile:getTopCreature() + if thing then + thing:transform(item.itemid == 1945 and config.bridgeID or config.waterID) + end + + if creature then + creature:teleportTo(config.removeCreaturePosition) + end + end + end + + item:transform(item.itemid == 1945 and 1946 or 1945) + return true +end + +othersHellGate:aid(50027) +othersHellGate:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/others/holy_water.lua b/data/scripts/actions/quests/others/holy_water.lua new file mode 100644 index 00000000000..e20d504e702 --- /dev/null +++ b/data/scripts/actions/quests/others/holy_water.lua @@ -0,0 +1,142 @@ +local doorPosition = Position(32260, 32791, 7) +local shadowNexusPosition = Position(33115, 31702, 12) +local effectPositions = { + Position(33113, 31702, 12), + Position(33116, 31702, 12) +} + +local function revertItem(position, itemId, transformId) + local item = Tile(position):getItemById(itemId) + if item then + item:transform(transformId) + end +end + +local function nexusMessage(player, message) + local spectators = Game.getSpectators(shadowNexusPosition, false, true, 3, 3) + for i = 1, #spectators do + player:say(message, TALKTYPE_MONSTER_YELL, false, spectators[i], shadowNexusPosition) + end +end + +local storages = { + [4008] = Storage.TibiaTales.RestInHallowedGround.Graves.Grave1, + [4009] = Storage.TibiaTales.RestInHallowedGround.Graves.Grave2, + [4010] = Storage.TibiaTales.RestInHallowedGround.Graves.Grave3, + [4011] = Storage.TibiaTales.RestInHallowedGround.Graves.Grave4, + [4012] = Storage.TibiaTales.RestInHallowedGround.Graves.Grave5, + [4013] = Storage.TibiaTales.RestInHallowedGround.Graves.Grave6, + [4014] = Storage.TibiaTales.RestInHallowedGround.Graves.Grave7, + [4015] = Storage.TibiaTales.RestInHallowedGround.Graves.Grave8, + [4016] = Storage.TibiaTales.RestInHallowedGround.Graves.Grave9, + [4017] = Storage.TibiaTales.RestInHallowedGround.Graves.Grave10, + [4018] = Storage.TibiaTales.RestInHallowedGround.Graves.Grave11, + [4019] = Storage.TibiaTales.RestInHallowedGround.Graves.Grave12, + [4020] = Storage.TibiaTales.RestInHallowedGround.Graves.Grave13, + [4021] = Storage.TibiaTales.RestInHallowedGround.Graves.Grave14, + [4022] = Storage.TibiaTales.RestInHallowedGround.Graves.Grave15, + [4023] = Storage.TibiaTales.RestInHallowedGround.Graves.Grave16 +} + +local config = { + antler_talisman = 24664, + sacred_antler_talisman = 24665 +} + +local othersHolyWater = Action() +function othersHolyWater.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + if target.itemid == config.antler_talisman then + item:transform(config.sacred_antler_talisman) + item:remove(1) + target:remove(1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You besprinkle the antler talisman with holy water. It glittlers faintly") + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + return true + end + + -- Eclipse + if target.actionid == 2000 then + item:remove(1) + toPosition:sendMagicEffect(CONST_ME_FIREAREA) + -- The Inquisition Questlog- 'Mission 2: Eclipse' + player:setStorageValue(Storage.TheInquisition.Mission02, 2) + player:setStorageValue(Storage.TheInquisition.Questline, 5) + return true + + -- Haunted Ruin + elseif target.actionid == 2003 then + if player:getStorageValue(Storage.TheInquisition.Questline) ~= 12 then + return true + end + + Game.createMonster('Pirate Ghost', toPosition) + item:remove(1) + + -- The Inquisition Questlog- 'Mission 4: The Haunted Ruin' + player:setStorageValue(Storage.TheInquisition.Questline, 13) + player:setStorageValue(Storage.TheInquisition.Mission04, 2) + + local doorItem = Tile(doorPosition):getItemById(8697) + if doorItem then + doorItem:transform(8696) + end + addEvent(revertItem, 10 * 1000, doorPosition, 8696, 8697) + return true + end + + if target.actionid == 4007 and target.actionid == 4024 then + local graveStorage = storages[target.actionid] + if player:getStorageValue(graveStorage) == 1 + or player:getStorageValue(Storage.TibiaTales.RestInHallowedGround.Questline) ~= 3 then + return false + end + + player:setStorageValue(graveStorage, 1) + + local cStorage = player:getStorageValue(Storage.TibiaTales.RestInHallowedGround.HolyWater) + if cStorage < 14 then + player:setStorageValue(Storage.TibiaTales.RestInHallowedGround.HolyWater, math.max(0, cStorage) + 1) + elseif cStorage == 14 then + player:setStorageValue(Storage.TibiaTales.RestInHallowedGround.HolyWater, -1) + player:setStorageValue(Storage.TibiaTales.RestInHallowedGround.Questline, 4) + item:transform(2006, 0) + end + + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + end + + -- Shadow Nexus + if isInArray({8753, 8755, 8757}, target.itemid) then + if target.itemid == 8757 then + Game.setStorageValue(GlobalStorage.Inquisition, math.random(4,5)) + end + target:transform(target.itemid + 1) + target:setAttribute(ITEM_ATTRIBUTE_DURATION, 20000) + target:decay() + nexusMessage(player, player:getName() .. ' damaged the shadow nexus! You can\'t damage it while it\'s burning.') + toPosition:sendMagicEffect(CONST_ME_ENERGYHIT) + elseif target.itemid == 8759 then + if Game.getStorageValue(GlobalStorage.Inquisition) > 0 then + Game.setStorageValue(GlobalStorage.Inquisition, (Game.getStorageValue(GlobalStorage.Inquisition)-1)) + if player:getStorageValue(Storage.TheInquisition.Questline) < 22 then + -- The Inquisition Questlog- 'Mission 7: The Shadow Nexus' + player:setStorageValue(Storage.TheInquisition.Mission07, 2) + player:setStorageValue(Storage.TheInquisition.Questline, 22) + end + for i = 1, #effectPositions do + effectPositions[i]:sendMagicEffect(CONST_ME_HOLYAREA) + end + nexusMessage(player, player:getName() .. ' destroyed the shadow nexus! In 10 seconds it will return to its original state.') + item:remove(1) + toPosition:sendMagicEffect(CONST_ME_HOLYAREA) + else + target:transform(8753) + end + end + + return true +end + +othersHolyWater:id(7494) +othersHolyWater:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/others/life_ring_lever.lua b/data/scripts/actions/quests/others/life_ring_lever.lua new file mode 100644 index 00000000000..f5818c1ce39 --- /dev/null +++ b/data/scripts/actions/quests/others/life_ring_lever.lua @@ -0,0 +1,37 @@ +local config = { + bridgePositions = { + Position(32410, 32232, 10), + Position(32411, 32232, 10), + Position(32412, 32232, 10), + Position(32410, 32231, 10), + Position(32411, 32231, 10), + Position(32412, 32231, 10) + }, + removeCreaturePosition = Position(32409, 32231, 10), + bridgeID = 5770, + waterID = 4615 +} + +local othersLifeRing = Action() +function othersLifeRing.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local tile, thing, creature + for i = 1, #config.bridgePositions do + tile = Tile(config.bridgePositions[i]) + if tile then + thing, creature = tile:getItemById(item.itemid == 1945 and config.waterID or config.bridgeID), tile:getTopCreature() + if thing then + thing:transform(item.itemid == 1945 and config.bridgeID or config.waterID) + end + + if creature then + creature:teleportTo(config.removeCreaturePosition) + end + end + end + + item:transform(item.itemid == 1945 and 1946 or 1945) + return true +end + +othersLifeRing:aid(50129) +othersLifeRing:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/others/orc_edron_lever.lua b/data/scripts/actions/quests/others/orc_edron_lever.lua new file mode 100644 index 00000000000..322515e61d7 --- /dev/null +++ b/data/scripts/actions/quests/others/orc_edron_lever.lua @@ -0,0 +1,19 @@ +local othersOrcEdron = Action() +function othersOrcEdron.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local tile = Tile(Position(33171, 31897, 8)) + if item.itemid == 1945 then + local stoneItem = tile:getItemById(1285) + if stoneItem then + stoneItem:remove() + item:transform(1946) + end + else + tile:relocateTo(Position(33171, 31898, 8), true) + Game.createItem(1285, 1, Position(33171, 31897, 8)) + item:transform(1945) + end + return true +end + +othersOrcEdron:uid(1017) +othersOrcEdron:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/others/plate_armor_quest.lua b/data/scripts/actions/quests/others/plate_armor_quest.lua new file mode 100644 index 00000000000..5ffdb2436c0 --- /dev/null +++ b/data/scripts/actions/quests/others/plate_armor_quest.lua @@ -0,0 +1,13 @@ +local othersPlateArmor = Action() +function othersPlateArmor.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.GhostShipQuest) == 1 then + return false + end + + player:setStorageValue(Storage.GhostShipQuest, 1) + player:addItem(2463, 1) + return true +end + +othersPlateArmor:aid(5556) +othersPlateArmor:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/others/serpentine_tower_lever.lua b/data/scripts/actions/quests/others/serpentine_tower_lever.lua new file mode 100644 index 00000000000..c60e10c29b1 --- /dev/null +++ b/data/scripts/actions/quests/others/serpentine_tower_lever.lua @@ -0,0 +1,34 @@ +local walls = { + {position = Position(33148, 32867, 9), relocatePosition = Position(33148, 32869, 9)}, + {position = Position(33148, 32868, 9), relocatePosition = Position(33148, 32869, 9)}, + {position = Position(33149, 32867, 9), relocatePosition = Position(33149, 32869, 9)}, + {position = Position(33149, 32868, 9), relocatePosition = Position(33149, 32869, 9)} +} + +local othersSerpentineLever = Action() +function othersSerpentineLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 1945 then + local wallItem + for i = 1, #walls do + wallItem = Tile(walls[i].position):getItemById(1498) + if wallItem then + wallItem:remove() + end + end + + item:transform(1946) + else + local wall + for i = 1, #walls do + wall = walls[i] + Tile(wall.position):relocateTo(wall.relocatePosition) + Game.createItem(1498, 1, wall.position) + end + + item:transform(1945) + end + return true +end + +othersSerpentineLever:aid(5633) +othersSerpentineLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/others/serpentine_tower_torch.lua b/data/scripts/actions/quests/others/serpentine_tower_torch.lua new file mode 100644 index 00000000000..7e94add10d1 --- /dev/null +++ b/data/scripts/actions/quests/others/serpentine_tower_torch.lua @@ -0,0 +1,14 @@ +local othersSerpentineTorch = Action() +function othersSerpentineTorch.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local wallItem = Tile(33151, 32866, 8):getItemById(1100) + if wallItem then + wallItem:remove() + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + else + player:getPosition():sendMagicEffect(CONST_ME_POFF) + end + return true +end + +othersSerpentineTorch:aid(5632) +othersSerpentineTorch:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/others/steal_from_thieves.lua b/data/scripts/actions/quests/others/steal_from_thieves.lua new file mode 100644 index 00000000000..7502045181c --- /dev/null +++ b/data/scripts/actions/quests/others/steal_from_thieves.lua @@ -0,0 +1,23 @@ +local chests = { + [19910] = {itemid = 7587}, +} + +local othersSteal = Action() +function othersSteal.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if chests[item.uid] then + if player:getStorageValue(Storage.QuestChests.StealFromThieves) > 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'It\'s empty.') + return true + end + + local chest = chests[item.uid] + player:addItem(chest.itemid, 1) + player:setStorageValue(Storage.QuestChests.StealFromThieves, 2) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You found a bag.') + end + + return true +end + +othersSteal:aid(19910) +othersSteal:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/others/triangle_tower_lever.lua b/data/scripts/actions/quests/others/triangle_tower_lever.lua new file mode 100644 index 00000000000..47b41383f0c --- /dev/null +++ b/data/scripts/actions/quests/others/triangle_tower_lever.lua @@ -0,0 +1,19 @@ +local othersTriangle = Action() +function othersTriangle.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local tile = Tile(Position({x = 32566, y = 32119, z = 7})) + if item.itemid == 1945 then + if tile:getItemById(1025) then + tile:getItemById(1025):remove() + item:transform(1946) + else + Game.createItem(1025, 1, {x = 32566, y = 32119, z = 7}) + end + else + Game.createItem(1025, 1, {x = 32566, y = 32119, z = 7}) + item:transform(1945) + end + return true +end + +othersTriangle:uid(50023) +othersTriangle:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/pits_of_inferno/bazir_maze_lever.lua b/data/scripts/actions/quests/pits_of_inferno/bazir_maze_lever.lua new file mode 100644 index 00000000000..d9fcea1fc52 --- /dev/null +++ b/data/scripts/actions/quests/pits_of_inferno/bazir_maze_lever.lua @@ -0,0 +1,17 @@ +local pitsOfInfernoMazeLever = Action() +function pitsOfInfernoMazeLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local portal = Tile(Position(32816, 32345, 13)):getItemById(1387) + if not portal then + local item = Game.createItem(1387, 1, Position(32816, 32345, 13)) + if item:isTeleport() then + item:setDestination(Position(32767, 32366, 15)) + end + else + portal:remove() + end + item:transform(item.itemid == 1945 and 1946 or 1945) + return true +end + +pitsOfInfernoMazeLever:uid(50105) +pitsOfInfernoMazeLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/pits_of_inferno/bazir_mirror.lua b/data/scripts/actions/quests/pits_of_inferno/bazir_mirror.lua new file mode 100644 index 00000000000..4d3286fb5c7 --- /dev/null +++ b/data/scripts/actions/quests/pits_of_inferno/bazir_mirror.lua @@ -0,0 +1,34 @@ +local config = { + [39511] = { + fromPosition = Position(32739, 32392, 14), + toPosition = Position(32739, 32391, 14) + }, + [39512] = { + teleportPlayer = true, + fromPosition = Position(32739, 32391, 14), + toPosition = Position(32739, 32392, 14) + } +} + +local pitsOfInfernoBlackMirror = Action() +function pitsOfInfernoBlackMirror.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local useItem = config[item.actionid] + if not useItem then + return true + end + + if useItem.teleportPlayer then + player:teleportTo(Position(32712, 32392, 13)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say('Beauty has to be rewarded! Muahahaha!', TALKTYPE_MONSTER_SAY) + end + + local tapestry = Tile(useItem.fromPosition):getItemById(6434) + if tapestry then + tapestry:moveTo(useItem.toPosition) + end + return true +end + +pitsOfInfernoBlackMirror:aid(39511,39512) +pitsOfInfernoBlackMirror:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/pits_of_inferno/bazir_wrong_levers.lua b/data/scripts/actions/quests/pits_of_inferno/bazir_wrong_levers.lua new file mode 100644 index 00000000000..68a5f380018 --- /dev/null +++ b/data/scripts/actions/quests/pits_of_inferno/bazir_wrong_levers.lua @@ -0,0 +1,14 @@ +local pitsOfInfernoWrongLevers = Action() +function pitsOfInfernoWrongLevers.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 1945 then + player:teleportTo(Position(32806, 32328, 15)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + item:transform(1946) + end + return true +end + +for value = 50095, 50104 do + pitsOfInfernoWrongLevers:uid(value) +end +pitsOfInfernoWrongLevers:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/pits_of_inferno/fire_throne_lever.lua b/data/scripts/actions/quests/pits_of_inferno/fire_throne_lever.lua new file mode 100644 index 00000000000..7ed53266bee --- /dev/null +++ b/data/scripts/actions/quests/pits_of_inferno/fire_throne_lever.lua @@ -0,0 +1,24 @@ +local lava = { + Position(32912, 32209, 15), + Position(32913, 32209, 15), + Position(32912, 32210, 15), + Position(32913, 32210, 15) +} + +local pitsOfInfernoFirstThroneLever = Action() +function pitsOfInfernoFirstThroneLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local lavaTile + for i = 1, #lava do + lavaTile = Tile(lava[i]):getGround() + if lavaTile and isInArray({407, 598}, lavaTile.itemid) then + lavaTile:transform(lavaTile.itemid == 598 and 407 or 598) + lava[i]:sendMagicEffect(CONST_ME_SMOKE) + end + end + + item:transform(item.itemid == 1945 and 1946 or 1945) + return true +end + +pitsOfInfernoFirstThroneLever:uid(50106) +pitsOfInfernoFirstThroneLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/pits_of_inferno/fountain.lua b/data/scripts/actions/quests/pits_of_inferno/fountain.lua new file mode 100644 index 00000000000..a8e2c798683 --- /dev/null +++ b/data/scripts/actions/quests/pits_of_inferno/fountain.lua @@ -0,0 +1,16 @@ +local pitsOfInfernoFountain = Action() +function pitsOfInfernoFountain.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.FountainOfLife) == 1 then + return false + end + + player:addHealth(player:getMaxHealth()) + player:addMana(player:getMaxMana()) + player:addAchievement('Fountain of Life') + player:setStorageValue(Storage.FountainOfLife, 1) + player:say('You feel very refreshed and relaxed.', TALKTYPE_MONSTER_SAY) + return true +end + +pitsOfInfernoFountain:aid(8815) +pitsOfInfernoFountain:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/pits_of_inferno/goshnar.lua b/data/scripts/actions/quests/pits_of_inferno/goshnar.lua new file mode 100644 index 00000000000..b896cea6362 --- /dev/null +++ b/data/scripts/actions/quests/pits_of_inferno/goshnar.lua @@ -0,0 +1,18 @@ +local pitsOfInfernoGoshnar = Action() +function pitsOfInfernoGoshnar.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid ~= 2023 then + return false + end + + if not Tile(toPosition):getItemById(2016, 2) then + return true + end + + toPosition.z = toPosition.z + 1 + player:teleportTo(toPosition) + toPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +pitsOfInfernoGoshnar:aid(2022) +pitsOfInfernoGoshnar:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/pits_of_inferno/ladder_levers.lua b/data/scripts/actions/quests/pits_of_inferno/ladder_levers.lua new file mode 100644 index 00000000000..d2b3d1d2a9a --- /dev/null +++ b/data/scripts/actions/quests/pits_of_inferno/ladder_levers.lua @@ -0,0 +1,34 @@ +local pos = { Position(32861, 32305, 11), Position(32860, 32313, 11) } + +local pitsOfInfernoLadderLevers = Action() +function pitsOfInfernoLadderLevers.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid ~= 1945 then + return false + end + + item:transform(1946) + + if item.uid == 3301 then + local lava = Tile(pos[1]):getItemById(598) + if lava then + lava:transform(1284) + end + + local dirtId, dirtItem = { 4808, 4810 } + for i = 1, #dirtId do + dirtItem = Tile(pos[1]):getItemById(dirtId[i]) + if dirtItem then + dirtItem:remove() + end + end + elseif item.uid == 3302 then + local item = Tile(pos[2]):getItemById(387) + if item then + item:remove() + end + end + return true +end + +pitsOfInfernoLadderLevers:uid(3301,3302) +pitsOfInfernoLadderLevers:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/pits_of_inferno/levers.lua b/data/scripts/actions/quests/pits_of_inferno/levers.lua new file mode 100644 index 00000000000..064d0a9cee2 --- /dev/null +++ b/data/scripts/actions/quests/pits_of_inferno/levers.lua @@ -0,0 +1,71 @@ +local text = { + [1] = 'first', [2] = 'second', [3] = 'third', [4] = 'fourth', [5] = 'fifth', + [6] = 'sixth', [7] = 'seventh', [8] = 'eighth', [9] = 'ninth', [10] = 'tenth', + [11] = 'eleventh', [12] = 'twelfth', [13] = 'thirteenth', [14] = 'fourteenth', [15] = 'fifteenth' +} + +local stonePositions = { + Position(32851, 32333, 12), + Position(32852, 32333, 12) +} + +local function createStones() + for i = 1, #stonePositions do + local stone = Tile(stonePositions[i]):getItemById(1304) + if not stone then + Game.createItem(1304, 1, stonePositions[i]) + end + end + + Game.setStorageValue(GlobalStorage.PitsOfInfernoLevers, 0) +end + +local function revertLever(position) + local leverItem = Tile(position):getItemById(1946) + if leverItem then + leverItem:transform(1945) + end +end + +local pitsOfInfernoLevers = Action() +function pitsOfInfernoLevers.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid ~= 1945 then + return false + end + + local leverCount = math.max(0, Game.getStorageValue(GlobalStorage.PitsOfInfernoLevers)) + if item.uid > 2049 and item.uid < 2065 then + local number = item.uid - 2049 + if leverCount + 1 ~= number then + return false + end + + Game.setStorageValue(GlobalStorage.PitsOfInfernoLevers, number) + player:say('You flipped the ' .. text[number] .. ' lever. Hurry up and find the next one!', TALKTYPE_MONSTER_SAY, false, player, toPosition) + elseif item.uid == 2065 then + if leverCount ~= 15 then + player:say('The final lever won\'t budge... yet.', TALKTYPE_MONSTER_SAY) + return true + end + + local stone + for i = 1, #stonePositions do + stone = Tile(stonePositions[i]):getItemById(1304) + if stone then + stone:remove() + stonePositions[i]:sendMagicEffect(CONST_ME_EXPLOSIONAREA) + end + end + + addEvent(createStones, 15 * 60 * 1000) + end + + item:transform(1946) + addEvent(revertLever, 15 * 60 * 1000, toPosition) + return true +end + +for value = 2050, 2065 do + pitsOfInfernoLevers:uid(value) +end +pitsOfInfernoLevers:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/pits_of_inferno/maze_stone.lua b/data/scripts/actions/quests/pits_of_inferno/maze_stone.lua new file mode 100644 index 00000000000..f7e40eac8e4 --- /dev/null +++ b/data/scripts/actions/quests/pits_of_inferno/maze_stone.lua @@ -0,0 +1,20 @@ +local pitsOfInfernoMazeStone = Action() +function pitsOfInfernoMazeStone.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 1946 then + return false + end + + toPosition.x = toPosition.x - 1 + toPosition.y = toPosition.y + 1 + + local stone = Tile(toPosition):getItemById(1304) + if stone then + stone:remove() + end + + item:transform(1946) + return true +end + +pitsOfInfernoMazeStone:aid(50160) +pitsOfInfernoMazeStone:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/pits_of_inferno/oil.lua b/data/scripts/actions/quests/pits_of_inferno/oil.lua new file mode 100644 index 00000000000..b7be3664dac --- /dev/null +++ b/data/scripts/actions/quests/pits_of_inferno/oil.lua @@ -0,0 +1,37 @@ +local bridgePosition = Position(32801, 32336, 11) + +local function revertBridge() + Tile(bridgePosition):getItemById(5770):transform(493) +end + +local function revertLever(position) + local leverItem = Tile(position):getItemById(1946) + if leverItem then + leverItem:transform(1945) + end +end + +local pitsOfInfernoOil = Action() +function pitsOfInfernoOil.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid ~= 1945 then + return false + end + + if not Tile(Position(32800, 32339, 11)):getItemById(2016, 11) then + player:say('The lever is creaking and rusty.', TALKTYPE_MONSTER_SAY) + return true + end + + local water = Tile(bridgePosition):getItemById(493) + if water then + water:transform(5770) + addEvent(revertBridge, 10 * 60 * 1000) + end + + item:transform(1946) + addEvent(revertLever, 10 * 60 * 1000, toPosition) + return true +end + +pitsOfInfernoOil:uid(1037) +pitsOfInfernoOil:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/pits_of_inferno/stone_lever.lua b/data/scripts/actions/quests/pits_of_inferno/stone_lever.lua new file mode 100644 index 00000000000..964461e15e5 --- /dev/null +++ b/data/scripts/actions/quests/pits_of_inferno/stone_lever.lua @@ -0,0 +1,16 @@ +local pitsOfInfernoStoneLever = Action() +function pitsOfInfernoStoneLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 1945 then + local stonePosition = Position(32849, 32282, 10) + local stoneItem = Tile(stonePosition):getItemById(1304) + if stoneItem then + stoneItem:remove() + stonePosition:sendMagicEffect(CONST_ME_EXPLOSIONAREA) + item:transform(1946) + end + end + return true +end + +pitsOfInfernoStoneLever:uid(3300) +pitsOfInfernoStoneLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/pits_of_inferno/trap_lever.lua b/data/scripts/actions/quests/pits_of_inferno/trap_lever.lua new file mode 100644 index 00000000000..053992ced34 --- /dev/null +++ b/data/scripts/actions/quests/pits_of_inferno/trap_lever.lua @@ -0,0 +1,18 @@ +local pitsOfInfernoTrapLever = Action() +function pitsOfInfernoTrapLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + item:transform(item.itemid == 1945 and 1946 or 1945) + + if item.itemid ~= 1945 then + return true + end + + local stoneItem = Tile(Position(32826, 32274, 11)):getItemById(1285) + if stoneItem then + stoneItem:remove() + end + return true +end + +pitsOfInfernoTrapLever:uid(3304) +pitsOfInfernoTrapLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/pits_of_inferno/walls.lua b/data/scripts/actions/quests/pits_of_inferno/walls.lua new file mode 100644 index 00000000000..422d3d24261 --- /dev/null +++ b/data/scripts/actions/quests/pits_of_inferno/walls.lua @@ -0,0 +1,32 @@ +local pos = { + [2025] = {x = 32831, y = 32333, z = 11}, + [2026] = {x = 32833, y = 32333, z = 11}, + [2027] = {x = 32835, y = 32333, z = 11}, + [2028] = {x = 32837, y = 32333, z = 11} +} + +local function doRemoveFirewalls(fwPos) + local tile = Position(fwPos):getTile() + if tile then + local thing = tile:getItemById(6289) + if thing then + thing:remove() + end + end +end + +local pitsOfInfernoWalls = Action() +function pitsOfInfernoWalls.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if(item.itemid == 1945) then + doRemoveFirewalls(pos[item.uid]) + Position(pos[item.uid]):sendMagicEffect(CONST_ME_FIREAREA) + else + Game.createItem(6289, 1, pos[item.uid]) + Position(pos[item.uid]):sendMagicEffect(CONST_ME_FIREAREA) + end + item:transform(item.itemid == 1945 and 1946 or 1945) + return true +end + +pitsOfInfernoWalls:uid(2025,2026,2027,2028) +pitsOfInfernoWalls:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/postman/package.lua b/data/scripts/actions/quests/postman/package.lua new file mode 100644 index 00000000000..a3029e7ba82 --- /dev/null +++ b/data/scripts/actions/quests/postman/package.lua @@ -0,0 +1,14 @@ +local postmanPackage = Action() +function postmanPackage.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid == 101 and target.itemid == 2334 then + if player:getStorageValue(Storage.Postman.Mission09) == 2 then + player:setStorageValue(Storage.Postman.Mission09, 3) + toPosition:sendMagicEffect(CONST_ME_MAGIC_GREEN) + item:transform(1993) + end + end + return true +end + +postmanPackage:id(2330) +postmanPackage:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/postman/present.lua b/data/scripts/actions/quests/postman/present.lua new file mode 100644 index 00000000000..1623d5774e2 --- /dev/null +++ b/data/scripts/actions/quests/postman/present.lua @@ -0,0 +1,10 @@ +local postmanPresent = Action() +function postmanPresent.onUse(player, item, fromPosition, target, toPosition, isHotkey) + item:remove(1) + toPosition:sendMagicEffect(CONST_ME_POFF) + player:say("You open the present.", TALKTYPE_MONSTER_SAY) + return true +end + +postmanPresent:id(2331) +postmanPresent:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/postman/waldos_posthorn.lua b/data/scripts/actions/quests/postman/waldos_posthorn.lua new file mode 100644 index 00000000000..bb37cd38e4c --- /dev/null +++ b/data/scripts/actions/quests/postman/waldos_posthorn.lua @@ -0,0 +1,14 @@ +local postmanWaldos = Action() +function postmanWaldos.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.Postman.Mission08) == 1 then + player:setStorageValue(Storage.Postman.Mission08, 2) + player:addItem(2332, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You found Waldo's posthorn.") + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The dead human is empty.') + end + return true +end + +postmanWaldos:uid(3118) +postmanWaldos:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/rottin_wood_and_married_men/broken_wall.lua b/data/scripts/actions/quests/rottin_wood_and_married_men/broken_wall.lua new file mode 100644 index 00000000000..c35c91447b8 --- /dev/null +++ b/data/scripts/actions/quests/rottin_wood_and_married_men/broken_wall.lua @@ -0,0 +1,17 @@ +local rottinWoodBroken = Action() +function rottinWoodBroken.onUse(player, item, fromPosition, itemEx, toPosition, isHotkey) + local position = {x = 32655, y = 32205, z = 7} --32655, 32205, 7 + if player:getStorageValue(Storage.RottinWoodAndMaried.RottinStart) < 6 then + player:setStorageValue(Storage.RottinWoodAndMaried.RottinStart, 6) + player:teleportTo(position) + position:sendMagicEffect(CONST_ME_TELEPORT) + player:say("There we go.", TALKTYPE_ORANGE_1) + else + player:say( "You already done this mission, go and talk with Rottin Wood to others missions.", TALKTYPE_ORANGE_1) + return true + end + return true +end + +rottinWoodBroken:aid(42501,42502,42503,42504,42505) +rottinWoodBroken:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/rottin_wood_and_married_men/corpse.lua b/data/scripts/actions/quests/rottin_wood_and_married_men/corpse.lua new file mode 100644 index 00000000000..73e843895e1 --- /dev/null +++ b/data/scripts/actions/quests/rottin_wood_and_married_men/corpse.lua @@ -0,0 +1,15 @@ +local rottinWoodCorpse = Action() +function rottinWoodCorpse.onUse(cid, item, fromPosition, itemEx, toPosition, isHotkey) + if(item.itemid == 13176) then + if(getPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Mission03) == 5) and getPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Corpse) < 4 then + doCreatureSay(cid, "You take no more gold than you actually need and release the merchant who makes away the very second you remove the ropes.", TALKTYPE_ORANGE_1) + doPlayerAddItem(cid, 2148, 100) + doRemoveItem(item.uid, 1) + setPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Corpse, getPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Corpse) + 1) + end + end + return true +end + +rottinWoodCorpse:id(13176) +rottinWoodCorpse:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/rottin_wood_and_married_men/trap.lua b/data/scripts/actions/quests/rottin_wood_and_married_men/trap.lua new file mode 100644 index 00000000000..42c6b4d6fa6 --- /dev/null +++ b/data/scripts/actions/quests/rottin_wood_and_married_men/trap.lua @@ -0,0 +1,72 @@ +function removeMonster() + doRemoveItem(getTileItemById({x = 32662, y = 32190, z = 7}, 2768).uid,1) + doSendMagicEffect({x = 32662, y = 32190, z = 7}, 45) + TOP_LEFT_CORNER = {x = 32651, y = 32178, z = 7, stackpos=253} + BOTTOM_RIGHT_CORNER = {x = 32668, y = 32190, z = 7, stackpos=253} + for Py = TOP_LEFT_CORNER.y, BOTTOM_RIGHT_CORNER.y do + for Px = TOP_LEFT_CORNER.x, BOTTOM_RIGHT_CORNER.x do + creature = getThingfromPos({x=Px, y=Py, z=7, stackpos=253}) + if isMonster(creature.uid) then + if getCreatureName(creature.uid) == "Travelling Merchant" then + --doRemoveCreature(creature.uid) + doSendMagicEffect({x=Px, y=Py, z=7}, 45) + --setPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Trap, -1) + end + end + end + end + return TRUE +end + + +function removeTrap() + TOP_LEFT_CORNER = {x = 32651, y = 32178, z = 7, stackpos=253} + BOTTOM_RIGHT_CORNER = {x = 32668, y = 32190, z = 7, stackpos=253} + for Py = TOP_LEFT_CORNER.y, BOTTOM_RIGHT_CORNER.y do + for Px = TOP_LEFT_CORNER.x, BOTTOM_RIGHT_CORNER.x do + local trap = getTileItemById({x=Px, y=Py, z=7}, 13174) + if trap then + setPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Trap, -1) + doRemoveItem(trap.uid, 1) + end + end + end + return TRUE +end + + +local rottinWoodtrap = Action() +function rottinWoodtrap.onUse(cid, item, fromPosition, itemEx, toPosition, isHotkey) + if(item.itemid == 13173) then + if(itemEx.itemid == 11436) then + if(getPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Mission03) == 5) and getPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Trap) < 3 then + doCreatureSay(cid, "You place the trap carefully on the ground. Between twigs and leaves it is almost invisible.", TALKTYPE_ORANGE_1) + doRemoveItem(item.uid, 1) + Game.createItem(13174, 1, toPosition) + setPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Trap, getPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Trap) + 1) + else + if(getPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Trap) == 3) then + doCreatureSay(cid, "It looks like the merchants are about to arrive, better hide somewhere where you can see whats going on in the area.", TALKTYPE_ORANGE_1) + doRemoveItem(item.uid, 1) + Game.createItem(13174, 1, toPosition) + doTeleportThing(cid, {x = 32660, y = 32193, z = 7}) + doSendMagicEffect(getCreaturePosition(cid), 45) + Game.createItem(2768, 1, {x = 32662, y = 32190, z = 7}) -- small fir tree + ----------------------- SUMMON MERCHANT ----------------------------- + doSummonCreature("Travelling Merchant", {x = 32656, y = 32182, z = 7}) + doSummonCreature("Travelling Merchant", {x = 32660, y = 32181, z = 7}) + doSummonCreature("Travelling Merchant", {x = 32661, y = 32184, z = 7}) + doSummonCreature("Travelling Merchant", {x = 32662, y = 32181, z = 7}) + doSummonCreature("Travelling Merchant", {x = 32657, y = 32185, z = 7}) + ---------------------------------------------------------------------- + addEvent(removeMonster, 5*60*1000) + addEvent(removeTrap, 5*60*1000) + end + end + end + end + return true +end + +rottinWoodtrap:id(13173) +rottinWoodtrap:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/sea_of_light/sea_of_light.lua b/data/scripts/actions/quests/sea_of_light/sea_of_light.lua new file mode 100644 index 00000000000..9611289f40e --- /dev/null +++ b/data/scripts/actions/quests/sea_of_light/sea_of_light.lua @@ -0,0 +1,42 @@ +-- Rare crystal +local rareCrystal = Action() + +function rareCrystal.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.SeaOfLight.Questline) ~= 7 then + return false + end + + if toPosition == Position(32011, 31709, 7) then + player:setStorageValue(Storage.SeaOfLight.Questline, player:getStorageValue(Storage.SeaOfLight.Questline) + 1) + player:setStorageValue(Storage.SeaOfLight.Mission3, player:getStorageValue(Storage.SeaOfLight.Mission3) + 1) + player:teleportTo({x = 32017, y = 31730, z = 8}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + item:remove() + return true + end + return false +end + +rareCrystal:id(10614) +rareCrystal:register() + +-- Collector corpse +local collectorCorpse = Action() + +function collectorCorpse.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid ~= 10612 then + return false + end + + if player:getStorageValue(Storage.SeaOfLight.Questline) ~= 8 then + return false + end + + player:say("You carefully put the mirror crystal into the astronomers's device.", TALKTYPE_MONSTER_SAY) + player:setStorageValue(Storage.SeaOfLight.Questline, 9) + player:setStorageValue(Storage.SeaOfLight.Mission3, 3) + item:transform(10616) +end + +collectorCorpse:id(10615) +collectorCorpse:register() diff --git a/data/scripts/actions/quests/secret_library/brokul_lever.lua b/data/scripts/actions/quests/secret_library/brokul_lever.lua new file mode 100644 index 00000000000..02c92c69a09 --- /dev/null +++ b/data/scripts/actions/quests/secret_library/brokul_lever.lua @@ -0,0 +1,102 @@ +bossConfig = { + [34000] = { -- ActionID + requiredLevel = 150, + minPlayersRequired = 1, + + boss = "Brokul", + bossGlobalStorage = 35000, + playerStorage = 36000, + teleportPosition = Position(33483, 31445, 15), + centerRoomPosition = Position(33483, 31439, 15), + northRange = 15, eastRange = 15, southRange = 15, westRange = 15, + exit = Position(33522, 31468, 15), + bossPosition = Position(33483, 31434, 15), + time = 15, + + playerPositions = { + [1] = Position(33520, 31465, 15), + [2] = Position(33521, 31465, 15), + [3] = Position(33522, 31465, 15), + [4] = Position(33523, 31465, 15), + [5] = Position(33524, 31465, 15) + } + } +} + +local function resetBoss(bossConfig, bossId) + local monster = Monster(bossId) + if monster then + monster:remove() + end + local spectators = Game.getSpectators(bossConfig.centerRoomPosition, false, true, bossConfig.westRange, bossConfig.eastRange, bossConfig.northRange, bossConfig.southRange) + for i = 1, #spectators do + spectators[i]:teleportTo(bossConfig.exit) + end +end + +local secretBrokul = Action() +function secretBrokul.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + if item.itemid == 1946 then + local bossConfig = bossConfig[item:getActionId()] + if not bossConfig then + return false + end + + if (getGlobalStorageValue(bossConfig.bossGlobalStorage) > 0) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "There is already a team inside. Please wait.") + return true + end + + local errorMsg + local rPlayers = {} + for index, ipos in pairs(bossConfig.playerPositions) do + local playerTile = Tile(ipos):getTopCreature() + if playerTile then + if playerTile:isPlayer() then + if playerTile:getLevel() >= bossConfig.requiredLevel then + if playerTile:getStorageValue(bossConfig.playerStorage) <= os.time() then + table.insert(rPlayers, playerTile:getId()) + else + errorMsg = 'One or more players have already entered in the last 20 hours.' + end + else + errorMsg = 'All the players need to be level '.. bossConfig.requiredLevel ..' or higher.' + end + end + end + end + + if (#rPlayers >= bossConfig.minPlayersRequired) then + for _, pid in pairs(rPlayers) do + local rplayer = Player(pid) + if rplayer:isPlayer() then + rplayer:sendTextMessage(MESSAGE_EVENT_ADVANCE, ('You have %o minutes before you get kicked out.'):format(bossConfig.time)) + bossConfig.playerPositions[_]:sendMagicEffect(CONST_ME_POFF) + rplayer:teleportTo(bossConfig.teleportPosition) + rplayer:setStorageValue(bossConfig.playerStorage, os.time() + (20 * 60 * 60)) + bossConfig.teleportPosition:sendMagicEffect(CONST_ME_ENERGYAREA) + rplayer:setDirection(DIRECTION_NORTH) + end + end + setGlobalStorageValue(bossConfig.bossGlobalStorage, 1) + addEvent(setGlobalStorageValue, bossConfig.time * 60 * 1000, bossConfig.bossGlobalStorage, 0) + local monster = Game.createMonster(bossConfig.boss, bossConfig.bossPosition) + addEvent(resetBoss, bossConfig.time * 60 * 1000, bossConfig, monster and monster.uid or 0) + else + if not errorMsg then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, ("You need %u players."):format(bossConfig.minPlayersRequired)) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, errorMsg) + end + return true + end + + end + item:transform(item.itemid == 1946 and 1945 or 1946) + + return true +end + +secretBrokul:aid(34000) +secretBrokul:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/secret_service/amazon_disguise_kit.lua b/data/scripts/actions/quests/secret_service/amazon_disguise_kit.lua new file mode 100644 index 00000000000..d8cfa4b076b --- /dev/null +++ b/data/scripts/actions/quests/secret_service/amazon_disguise_kit.lua @@ -0,0 +1,14 @@ +local condition = Condition(CONDITION_OUTFIT) +condition:setTicks(20 * 1000) -- should be approximately 20 seconds +condition:setOutfit({lookType = 137, lookHead = 113, lookBody = 120, lookLegs = 114, lookFeet = 132}) -- amazon looktype + +local secretServiceKit = Action() +function secretServiceKit.onUse(player, item, fromPosition, target, toPosition, isHotkey) + player:addCondition(condition) + player:say('You disguise yourself as a beautiful amazon!', TALKTYPE_MONSTER_SAY) + item:remove() + return true +end + +secretServiceKit:id(7700) +secretServiceKit:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/secret_service/lever.lua b/data/scripts/actions/quests/secret_service/lever.lua new file mode 100644 index 00000000000..7a283f4a74a --- /dev/null +++ b/data/scripts/actions/quests/secret_service/lever.lua @@ -0,0 +1,36 @@ +local monsters = { + {monster = 'dwarf henchman', monsterPos = Position(32570, 31858, 14)}, + {monster = 'dwarf henchman', monsterPos = Position(32573, 31861, 14)}, + {monster = 'dwarf henchman', monsterPos = Position(32562, 31860, 14)}, + {monster = 'dwarf henchman', monsterPos = Position(32564, 31856, 14)}, + {monster = 'dwarf henchman', monsterPos = Position(32580, 31860, 14)}, + {monster = 'dwarf henchman', monsterPos = Position(32574, 31850, 14)}, + {monster = 'dwarf henchman', monsterPos = Position(32574, 31870, 14)}, + {monster = 'dwarf henchman', monsterPos = Position(32576, 31856, 14)}, + {monster = 'dwarf henchman', monsterPos = Position(32562, 31858, 14)}, + {monster = 'dwarf henchman', monsterPos = Position(32584, 31868, 14)}, + {monster = 'stone golem', monsterPos = Position(32570, 31861, 14)}, + {monster = 'stone golem', monsterPos = Position(32579, 31868, 14)}, + {monster = 'stone golem', monsterPos = Position(32569, 31852, 14)}, + {monster = 'stone golem', monsterPos = Position(32584, 31866, 14)}, + {monster = 'stone golem', monsterPos = Position(32572, 31851, 14)}, + {monster = 'mechanical fighter', monsterPos = Position(32573, 31858, 14)}, + {monster = 'mechanical fighter', monsterPos = Position(32570, 31868, 14)}, + {monster = 'mechanical fighter', monsterPos = Position(32579, 31852, 14)}, + {monster = 'mad technomancer', monsterPos = Position(32571, 31859, 14)} +} + +local secretServiceLever = Action() +function secretServiceLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 1945 then + for i = 1, #monsters do + Game.createMonster(monsters[i].monster, monsters[i].monsterPos) + end + end + + item:transform(item.itemid == 1945 and 1946 or 1945) + return true +end + +secretServiceLever:aid(12574) +secretServiceLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/secret_service/ring.lua b/data/scripts/actions/quests/secret_service/ring.lua new file mode 100644 index 00000000000..db464070fc8 --- /dev/null +++ b/data/scripts/actions/quests/secret_service/ring.lua @@ -0,0 +1,16 @@ +local secretServiceRing = Action() +function secretServiceRing.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid ~= 12563 then + return false + end + + if player:getStorageValue(Storage.SecretService.TBIMission05) == 1 then + player:setStorageValue(Storage.SecretService.TBIMission05, 2) + item:remove() + player:say('You have placed the false evidence!', TALKTYPE_MONSTER_SAY) + end + return true +end + +secretServiceRing:id(7697) +secretServiceRing:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/secret_service/rust_bugs.lua b/data/scripts/actions/quests/secret_service/rust_bugs.lua new file mode 100644 index 00000000000..a0d01d52c02 --- /dev/null +++ b/data/scripts/actions/quests/secret_service/rust_bugs.lua @@ -0,0 +1,17 @@ +local secretServiceBugs = Action() +function secretServiceBugs.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.uid ~= 12579 then + return false + end + + if player:getStorageValue(Storage.SecretService.CGBMission03) == 1 then + player:setStorageValue(Storage.SecretService.CGBMission03, 2) + item:remove() + Game.createItem(8016, 1, Position(32909, 32112, 7)) + player:say('The bugs are at work!', TALKTYPE_MONSTER_SAY) + end + return true +end + +secretServiceBugs:id(7698) +secretServiceBugs:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/secret_service/tools.lua b/data/scripts/actions/quests/secret_service/tools.lua new file mode 100644 index 00000000000..7a6416ff7ef --- /dev/null +++ b/data/scripts/actions/quests/secret_service/tools.lua @@ -0,0 +1,22 @@ +local config = { + [7960] = 10515, -- TBI + [7961] = 10513, -- CGB + [7962] = 10511 -- AVIN +} + +local secretServiceTools = Action() +function secretServiceTools.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local useItem = config[item.itemid] + if not useItem then + return true + end + + player:addItem(useItem) + player:say('You\'ve found a useful little tool for secret agents in the parcel.', TALKTYPE_MONSTER_SAY) + + item:remove() + return true +end + +secretServiceTools:id(7960,7961,7962) +secretServiceTools:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/spike_tasks/fertilizer.lua b/data/scripts/actions/quests/spike_tasks/fertilizer.lua new file mode 100644 index 00000000000..0d56d13c05d --- /dev/null +++ b/data/scripts/actions/quests/spike_tasks/fertilizer.lua @@ -0,0 +1,36 @@ +if not FERTILIZED_MUSHROOMS then + FERTILIZED_MUSHROOMS = {} +end + +local spikeTasksFertilizer = Action() +function spikeTasksFertilizer.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if isInArray({-1, 4}, player:getStorageValue(SPIKE_MIDDLE_MUSHROOM_MAIN)) then + return false + end + + if (target == nil) or not target:isItem() or (target:getId() ~= 21565) then + return false + end + + if not FERTILIZED_MUSHROOMS[player:getGuid()] then + FERTILIZED_MUSHROOMS[player:getGuid()] = {} + end + + local mushPos = Position(toPosition.x, toPosition.y, toPosition.z) + if isInArray(FERTILIZED_MUSHROOMS[player:getGuid()], mushPos) then + return player:sendCancelMessage("You have already fertilised this mushroom.") + end + + table.insert(FERTILIZED_MUSHROOMS[player:getGuid()], mushPos) + local sum = player:getStorageValue(SPIKE_MIDDLE_MUSHROOM_MAIN) + 1 + player:setStorageValue(SPIKE_MIDDLE_MUSHROOM_MAIN, sum) + + if sum == 4 then + item:remove() + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Report the task to Gnombold.") + end + return toPosition:sendMagicEffect(46) +end + +spikeTasksFertilizer:id(21564) +spikeTasksFertilizer:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/spike_tasks/ghost_detector.lua b/data/scripts/actions/quests/spike_tasks/ghost_detector.lua new file mode 100644 index 00000000000..9ad4228e9a3 --- /dev/null +++ b/data/scripts/actions/quests/spike_tasks/ghost_detector.lua @@ -0,0 +1,99 @@ +if not GHOST_DETECTOR_MAP then + GHOST_DETECTOR_MAP = {} +end + +ghost_detector_area = { + from = Position(32008, 32522, 8), + to = Position(32365, 32759, 10) +} + +local function getSearchString(fromPos, toPos) + local distance = 0 + local direction = 0 + local level = 0 + + local dx = fromPos.x - toPos.x + local dy = fromPos.y - toPos.y + local dz = fromPos.z - toPos.z + + level = (dz > 0) and 0 or (dz < 0) and 1 or 2 + + if math.abs(dx) < 5 and math.abs(dy) < 5 then + distance = 0 + else + local tmp = dx * dx + dy * dy + distance = (tmp < 10000) and 1 or (tmp < 75625) and 2 or 3 + end + + local tang = (dx ~= 0) and dy / dx or 10 + if math.abs(tang) < 0.4142 then + direction = (dx > 0) and 3 or 2 + elseif math.abs(tang) < 2.4142 then + direction = (tang > 0) and ((dy > 0) and 5 or 6) or ((dx > 0) and 7 or 4) + else + direction = (dy > 0) and 0 or 1 + end + + local text = { + [0] = { + [0] = "above you", + [1] = "below you", + [2] = "next to you" + }, + [1] = { + [0] = "on a higher level to the ", + [1] = "on a lower level to the ", + [2] = "to the " + }, + [2] = "far to the ", + [3] = "very far to the " + } + + local dirs = { + [0] = "north", + [1] = "south", + [2] = "east", + [3] = "west", + [4] = "north-east", + [5] = "north-west", + [6] = "south-east", + [7] = "south-west" + } + + return ((type(text[distance]) == "table") and text[distance][level] or text[distance]) .. ((distance ~= 0) and dirs[direction] or '') +end + +local spikeTasksGhost = Action() +function spikeTasksGhost.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local stat = player:getStorageValue(SPIKE_UPPER_TRACK_MAIN) + + if isInArray({-1, 3}, stat) then + return player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + end + + local current = GHOST_DETECTOR_MAP[player:getGuid()] + if not current then + local random = Position.getFreeSand() + GHOST_DETECTOR_MAP[player:getGuid()] = random + current = random + end + + if player:getPosition():compare(current) then + if stat == 2 then + item:remove() + GHOST_DETECTOR_MAP[player:getGuid()] = nil + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Report the task to Gnomilly.") + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You found a malignant presence, the glowing detector signals that it does not need any further data.") + else + GHOST_DETECTOR_MAP[player:getGuid()] = getFreeSand() + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You found a malignant presence, the glowing detector signals another presence nearby.') + end + player:setStorageValue(SPIKE_UPPER_TRACK_MAIN, stat+1) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The detector points ' .. getSearchString(player:getPosition(), current) .. '.') + end + return true +end + +spikeTasksGhost:id(21555) +spikeTasksGhost:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/spike_tasks/lode_stone.lua b/data/scripts/actions/quests/spike_tasks/lode_stone.lua new file mode 100644 index 00000000000..b70c7ff961d --- /dev/null +++ b/data/scripts/actions/quests/spike_tasks/lode_stone.lua @@ -0,0 +1,38 @@ +local transformTo = { + [21557] = 21566, + [21566] = 21568, +} + +local area = { --area where to teleport + Position(32152, 32502, 11), Position(32365, 32725, 12) +} + +local spikeTasksStone = Action() +function spikeTasksStone.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(SPIKE_MIDDLE_CHARGE_MAIN) ~= 0 then + return false + end + + if (target == nil) or not target:isItem() or (target:getId() ~= 21567) then + return false + end + + target:transform(21713) + target:decay() + if item:getId() == 21568 then + player:setStorageValue(SPIKE_MIDDLE_CHARGE_MAIN, 1) + player:getPosition():sendMagicEffect(12) + player:say('Your tinkering caused some kind of magnetic storm that caused you to get disorientated.', TALKTYPE_MONSTER_SAY) + item:remove() + else + item:transform(transformTo[item:getId()]) + if math.random(100) > 60 then + player:teleportTo(Position.getFreePosition(area[1], area[2])) + player:getPosition():sendMagicEffect(11) + end + end + return toPosition:sendMagicEffect(12) +end + +spikeTasksStone:id(21557,21566,21568) +spikeTasksStone:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/spike_tasks/nests.lua b/data/scripts/actions/quests/spike_tasks/nests.lua new file mode 100644 index 00000000000..919e5488a43 --- /dev/null +++ b/data/scripts/actions/quests/spike_tasks/nests.lua @@ -0,0 +1,32 @@ +local summon = {"Spider", "Larva", "Scarab", "Tarantula"} + +local spikeTasksNests = Action() +function spikeTasksNests.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if isInArray({-1, 8}, player:getStorageValue(SPIKE_MIDDLE_NEST_MAIN)) then + return false + end + + if player:getOutfit().lookType ~= 307 then + return false + end + + local sum = player:getStorageValue(SPIKE_MIDDLE_NEST_MAIN) + 1 + player:setStorageValue(SPIKE_MIDDLE_NEST_MAIN, sum) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have destroyed a monster nest.") + + if sum == 8 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Report the task to Gnombold.") + end + + if math.random(100) > 60 then + Game.createMonster(summon[math.random(#summon)], player:getPosition()) + end + + item:transform(21560) + item:decay() + toPosition:sendMagicEffect(17) + return true +end + +spikeTasksNests:id(21559) +spikeTasksNests:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/spike_tasks/spirit_shovel.lua b/data/scripts/actions/quests/spike_tasks/spirit_shovel.lua new file mode 100644 index 00000000000..2e31802e9a4 --- /dev/null +++ b/data/scripts/actions/quests/spike_tasks/spirit_shovel.lua @@ -0,0 +1,43 @@ +local chance = { + {90, "You unearthed a spirit\'s anger!!!", "Enraged Soul"}, + {80, "Your crude digging has angered some ancient ghost.", "Ghost"}, + {70, "You unearthed some not-so-death creature.", "Demon Skeleton"}, + {50, "You unearthed some not-so-death creature.", "Zombie"}, + {1, "You've found nothing special."} +} + +local spikeTasksShovel = Action() +function spikeTasksShovel.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if isInArray({-1, 4}, player:getStorageValue(SPIKE_UPPER_MOUND_MAIN)) then + return player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + end + + if (target == nil) or not target:isItem() or (target:getId() ~= 21561) then + return player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + end + + target:transform(21562) + target:decay() + local luck = math.random(100) + for i, result in ipairs(chance) do + if luck >= result[1] then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, result[2]) + if result[3] then + Game.createMonster(result[3], toPosition) + end + if i == 1 then + local sum = player:getStorageValue(SPIKE_UPPER_MOUND_MAIN) + 1 + player:setStorageValue(SPIKE_UPPER_MOUND_MAIN, sum) + if sum == 4 then + item:remove() + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Report the task to Gnomilly.") + end + end + break + end + end + return toPosition:sendMagicEffect(35) +end + +spikeTasksShovel:id(21553) +spikeTasksShovel:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/spike_tasks/thermometer.lua b/data/scripts/actions/quests/spike_tasks/thermometer.lua new file mode 100644 index 00000000000..cc718f9d469 --- /dev/null +++ b/data/scripts/actions/quests/spike_tasks/thermometer.lua @@ -0,0 +1,37 @@ +hot_lava_pools = { --all range areas of the 9 lava pools + {Position(32263, 32481, 13), Position(32274, 32490, 13)}, + {Position(32163, 32558, 13), Position(32173, 32567, 13)}, + {Position(32201, 32667, 13), Position(32211, 32672, 13)}, + {Position(32135, 32606, 14), Position(32143, 32614, 14)}, + {Position(32330, 32519, 14), Position(32339, 32521, 14)}, + {Position(32260, 32697, 14), Position(32272, 32705, 14)}, + {Position(32176, 32493, 15), Position(32186, 32502, 15)}, + {Position(32341, 32577, 15), Position(32347, 32586, 15)}, + {Position(32220, 32643, 15), Position(32223, 32652, 15)}, +} + +if not SPIKE_LOWER_HOTTEST_POOL then + SPIKE_LOWER_HOTTEST_POOL = math.random(#hot_lava_pools) +end + +local spikeTasksThermometer = Action() +function spikeTasksThermometer.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local status = player:getStorageValue(SPIKE_LOWER_LAVA_MAIN) + + if isInArray({-1, 1}, status) then + return player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + end + + if player:getPosition():isInRange(hot_lava_pools[SPIKE_LOWER_HOTTEST_POOL][1], hot_lava_pools[SPIKE_LOWER_HOTTEST_POOL][2]) then + item:remove() + player:getPosition():sendMagicEffect(16) + player:setStorageValue(SPIKE_LOWER_LAVA_MAIN, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Whew! That was that hot, it melted the thermometer! At least you've found the hot spot!") + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'This is not the hot spot!') + end + return true +end + +spikeTasksThermometer:id(21556) +spikeTasksThermometer:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/spike_tasks/tuning_fork.lua b/data/scripts/actions/quests/spike_tasks/tuning_fork.lua new file mode 100644 index 00000000000..e1d37e02c03 --- /dev/null +++ b/data/scripts/actions/quests/spike_tasks/tuning_fork.lua @@ -0,0 +1,26 @@ +local spikeTasksFork = Action() +function spikeTasksFork.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if isInArray({-1, 7}, player:getStorageValue(SPIKE_UPPER_PACIFIER_MAIN)) then + return player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + end + + if (target == nil) or not target:isItem() or (target:getId() ~= 21558) then + return player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + end + + local sum = player:getStorageValue(SPIKE_UPPER_PACIFIER_MAIN) + 1 + player:setStorageValue(SPIKE_UPPER_PACIFIER_MAIN, sum) + + if sum == 7 then + item:remove() + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Report the task to Gnomilly.") + end + + target:transform(21563) + target:decay() + toPosition:sendMagicEffect(24) + return true +end + +spikeTasksFork:id(21554) +spikeTasksFork:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/spirit_hunters/magical_device.lua b/data/scripts/actions/quests/spirit_hunters/magical_device.lua new file mode 100644 index 00000000000..0378ffb02f5 --- /dev/null +++ b/data/scripts/actions/quests/spirit_hunters/magical_device.lua @@ -0,0 +1,43 @@ + local spiritMagical = Action() + function spiritMagical.onUse(cid, item, fromPosition, itemEx, toPosition) + local player = Player(cid) + if item:getId() == 12670 then + if itemEx.itemid == 8059 then + if player:getStorageValue(Storage.SpiritHunters.Mission01 == 1) then + qStorage = player:getStorageValue(Storage.SpiritHunters.TombUse) + if qStorage < 3 then + position = player:getPosition() + player:say('An incredibly slimy substance oozes out of every crack in the old gravestone. It seems to attack you.', TALKTYPE_MONSTER_SAY) + player:setStorageValue(Storage.SpiritHunters.TombUse, qStorage+1) + Game.createMonster('Squidgy Slime', Position(position.x+1, position.y, position.z), false, false) + elseif qStorage == 4 then + player:say('You have used items in gravestone.', TALKTYPE_MONSTER_SAY) + end + end + end + elseif item:getId() == 12671 then + if itemEx.itemid == 5993 then -- ghost + player:say("As you open the device a bright light pours out of its interior and drags all remaining energy of the ghost into it.", TALKTYPE_MONSTER_SAY) + if player:getStorageValue(Storage.SpiritHunters.CharmUse) < 1 then + player:setStorageValue(Storage.SpiritHunters.CharmUse, 1) + else + player:setStorageValue(Storage.SpiritHunters.GhostUse, player:getStorageValue(Storage.SpiritHunters.GhostUse) + 1) + end + itemEx:transform(itemEx:getType():getDecayId()) + toPosition:sendMagicEffect(CONST_ME_MAGIC_GREEN) + elseif itemEx.itemid == 12631 or itemEx.itemid == 12632 then -- souleater + player:say("As you open the device a bright light pours out of its interior and drags all remaining energy of the souleater into it.", TALKTYPE_MONSTER_SAY) + player:setStorageValue(Storage.SpiritHunters.SouleaterUse, player:getStorageValue(Storage.SpiritHunters.SouleaterUse) + 1) + itemEx:transform(itemEx:getType():getDecayId()) + toPosition:sendMagicEffect(CONST_ME_MAGIC_GREEN) + elseif itemEx.itemid == 9915 or itemEx.itemid == 9916 then --nightstalker + player:say("As you open the device a bright light pours out of its interior and drags all remaining energy of the nightstalker into it.", TALKTYPE_MONSTER_SAY) + player:setStorageValue(Storage.SpiritHunters.NightstalkerUse, player:getStorageValue(Storage.SpiritHunters.NightstalkerUse) + 1) + itemEx:transform(itemEx:getType():getDecayId()) + toPosition:sendMagicEffect(CONST_ME_MAGIC_GREEN) + end + end + end + + spiritMagical:id(12670,12671) + spiritMagical:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_ancient_tombs/active_teleport_switches.lua b/data/scripts/actions/quests/the_ancient_tombs/active_teleport_switches.lua new file mode 100644 index 00000000000..15bf5c8fc9d --- /dev/null +++ b/data/scripts/actions/quests/the_ancient_tombs/active_teleport_switches.lua @@ -0,0 +1,34 @@ +local config = { + [12121] = GlobalStorage.TheAncientTombs.ThalasSwitchesGlobalStorage, + [12122] = GlobalStorage.TheAncientTombs.DiprathSwitchesGlobalStorage, + [12123] = GlobalStorage.TheAncientTombs.AshmunrahSwitchesGlobalStorage +} + +local function resetScript(position, storage) + local item = Tile(position):getItemById(1946) + if item then + item:transform(1945) + end + + Game.setStorageValue(storage, Game.getStorageValue(storage) - 1) +end + +local theAncientActiveTeleport = Action() +function theAncientActiveTeleport.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local storage = config[item.actionid] + if not storage then + return true + end + + if item.itemid ~= 1945 then + return false + end + + Game.setStorageValue(storage, Game.getStorageValue(storage) + 1) + item:transform(1946) + addEvent(resetScript, 20 * 60 * 1000, toPosition, storage) + return true +end + +theAncientActiveTeleport:aid(12121,12122,12123) +theAncientActiveTeleport:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_ancient_tombs/lever.lua b/data/scripts/actions/quests/the_ancient_tombs/lever.lua new file mode 100644 index 00000000000..1ba6679b72f --- /dev/null +++ b/data/scripts/actions/quests/the_ancient_tombs/lever.lua @@ -0,0 +1,64 @@ +local config = { + bridgePositions = { + {position = Position(33119, 32794, 14), groundId = 598}, + {position = Position(33119, 32795, 14), groundId = 598}, + {position = Position(33120, 32794, 14), groundId = 598}, + {position = Position(33120, 32795, 14), groundId = 598}, + {position = Position(33121, 32794, 14), groundId = 598}, + {position = Position(33121, 32795, 14), groundId = 598} + + }, + leverPositions = { + Position(33115, 32797, 14), + Position(33118, 32790, 14), + Position(33122, 32790, 14) + }, + relocatePosition = Position(33120, 2791, 14), + relocateMonsterPosition = Position(33120, 32799, 14), + bridgeId = 5770 +} + +local theAncientLever = Action() +function theAncientLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local leverLeft, lever = item.itemid == 1945 + for i = 1, #config.leverPositions do + lever = Tile(config.leverPositions[i]):getItemById(leverLeft and 1945 or 1946) + if lever then + lever:transform(leverLeft and 1946 or 1945) + end + end + + local tile, tmpItem, bridge + if leverLeft then + for i = 1, #config.bridgePositions do + bridge = config.bridgePositions[i] + tile = Tile(bridge.position) + + tmpItem = tile:getGround() + if tmpItem then + tmpItem:transform(config.bridgeId) + end + + if bridge.itemId then + tmpItem = tile:getItemById(bridge.itemId) + if tmpItem then + tmpItem:remove() + end + end + end + else + for i = 1, #config.bridgePositions do + bridge = config.bridgePositions[i] + tile = Tile(bridge.position) + + tile:relocateTo(config.relocatePosition, true, config.relocateMonsterPosition) + tile:getGround():transform(bridge.groundId) + Game.createItem(bridge.itemId, 1, bridge.position) + end + + end + return true +end + +theAncientLever:aid(12120) +theAncientLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_ancient_tombs/oasis_lever_door.lua b/data/scripts/actions/quests/the_ancient_tombs/oasis_lever_door.lua new file mode 100644 index 00000000000..f68016f024b --- /dev/null +++ b/data/scripts/actions/quests/the_ancient_tombs/oasis_lever_door.lua @@ -0,0 +1,49 @@ +local doorPosition = Position(33122, 32765, 14) + +local function revertCarrotAndLever(position, carrotPosition) + local leverItem = Tile(position):getItemById(1946) + if leverItem then + leverItem:transform(1945) + end + + local carrotItem = Tile(carrotPosition):getItemById(2684) + if carrotItem then + carrotItem:remove() + end +end + +local theAncientOasisLever = Action() +function theAncientOasisLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 1243 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You first must find the Carrot under one of the three hats to get the access!') + return true + end + + if item.itemid ~= 1945 then + return true + end + + if math.random(3) == 1 then + local hatPosition = Position(toPosition.x - 1, toPosition.y, toPosition.z) + hatPosition:sendMagicEffect(CONST_ME_MAGIC_GREEN) + doorPosition:sendMagicEffect(CONST_ME_MAGIC_GREEN) + Game.createItem(2684, 1, hatPosition) + + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You found the carrot! The door is open!') + item:transform(1946) + addEvent(revertCarrotAndLever, 4 * 1000, toPosition, hatPosition) + + local doorItem = Tile(doorPosition):getItemById(1243) + if doorItem then + doorItem:transform(1244) + end + return true + end + + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You guessed wrong! Take this! Carrot changed now the Hat!') + doAreaCombatHealth(player, COMBAT_PHYSICALDAMAGE, player:getPosition(), 0, -200, -200, CONST_ME_POFF) + return true +end + +theAncientOasisLever:aid(12107) +theAncientOasisLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_ancient_tombs/ruins_instruments.lua b/data/scripts/actions/quests/the_ancient_tombs/ruins_instruments.lua new file mode 100644 index 00000000000..ee67f22b6e1 --- /dev/null +++ b/data/scripts/actions/quests/the_ancient_tombs/ruins_instruments.lua @@ -0,0 +1,32 @@ +local config = { + [2367] = 1, + [2373] = 2, + [2370] = 3, + [2372] = 4, + [2369] = 5 +} + +local storage = Storage.TheAncientTombs.VashresamunInstruments + +local theAncientRuinsInstru = Action() +function theAncientRuinsInstru.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local targetTable = config[item.itemid] + if not targetTable then + player:setStorageValue(storage, 0) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You played them wrong, now you must begin with first again!') + doTargetCombatHealth(0, player, COMBAT_PHYSICALDAMAGE, -20, -20, CONST_ME_GROUNDSHAKER) + return true + end + + if player:getStorageValue(storage) == targetTable and targetTable < 4 then + player:setStorageValue(storage, math.max(1, player:getPlayerStorageValue(storage)) + 1) + fromPosition:sendMagicEffect(CONST_ME_SOUND_BLUE) + else + player:setStorageValue(Storage.TheAncientTombs.VashresamunsDoor, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You played them in correct order and got the access through door!') + end + return true +end + +theAncientRuinsInstru:aid(12105) +theAncientRuinsInstru:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_ape_city/mission9_catacombs_lever.lua b/data/scripts/actions/quests/the_ape_city/mission9_catacombs_lever.lua new file mode 100644 index 00000000000..cc7a69bae7f --- /dev/null +++ b/data/scripts/actions/quests/the_ape_city/mission9_catacombs_lever.lua @@ -0,0 +1,90 @@ +local config = { + leverTime = 15 * 60, + leverPositions = { + Position(32891, 32590, 11), + Position(32843, 32649, 11), + Position(32808, 32613, 11), + Position(32775, 32583, 11), + Position(32756, 32494, 11), + Position(32799, 32556, 11) + }, + + gateLevers = { + {position = Position(32862, 32555, 11), duration = 15 * 60, ignoreLevers = true}, + {position = Position(32862, 32557, 11), duration = 60, ignoreLevers = true} + }, + + walls = { + {position = Position(32864, 32556, 11), itemId = 3474} + } +} + +local function revertLever(position) + local leverItem = Tile(position):getItemById(1946) + if leverItem then + leverItem:transform(1945) + end +end + +local function revertWalls(leverPosition) + revertLever(leverPosition) + + for i = 1, #config.walls do + Game.createItem(config.walls[i].itemId, 1, config.walls[i].position) + end +end + +local theApeMiss9 = Action() +function theApeMiss9.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid ~= 1945 then + player:sendTextMessage(MESSAGE_FAILURE, 'It doesn\'t move.') + return true + end + + if isInArray(config.leverPositions, toPosition) then + item:transform(1946) + addEvent(revertLever, config.leverTime * 1000, toPosition) + return true + end + + local gateLever + for i = 1, #config.gateLevers do + if toPosition == config.gateLevers[i].position then + gateLever = config.gateLevers[i] + break + end + end + + if not gateLever then + return true + end + + if not gateLever.ignoreLevers then + for i = 1, #config.leverPositions do + -- if lever not pushed, do not continue + local leverItem = Tile(config.leverPositions[i]):getItemById(1946) + if not leverItem then + return false + end + end + end + + -- open gate when all levers used + for i = 1, #config.walls do + local wallItem = Tile(config.walls[i].position):getItemById(config.walls[i].itemId) + if not wallItem then + player:say('The lever won\'t budge', TALKTYPE_MONSTER_SAY, false, nil, toPosition) + return true + end + + wallItem:remove() + config.walls[i].position:sendMagicEffect(CONST_ME_MAGIC_RED) + end + + addEvent(revertWalls, gateLever.duration * 1000, toPosition) + item:transform(1946) + return true +end + +theApeMiss9:uid(1040, 1041) +theApeMiss9:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_ape_city/mission9_catacombs_snake_destroyer.lua b/data/scripts/actions/quests/the_ape_city/mission9_catacombs_snake_destroyer.lua new file mode 100644 index 00000000000..aa6559f1cfc --- /dev/null +++ b/data/scripts/actions/quests/the_ape_city/mission9_catacombs_snake_destroyer.lua @@ -0,0 +1,21 @@ +local theApeMiss9 = Action() +function theApeMiss9.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid ~= 4861 then + return false + end + + if player:getStorageValue(Storage.TheApeCity.Questline) ~= 17 + or player:getStorageValue(Storage.TheApeCity.SnakeDestroyer) == 1 then + return false + end + + player:setStorageValue(Storage.TheApeCity.SnakeDestroyer, 1) + item:remove() + target:transform(4862) + target:decay() + toPosition:sendMagicEffect(CONST_ME_FIREAREA) + return true +end + +theApeMiss9:id(4846) +theApeMiss9:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_cursed_crystal/MedusaOil.lua b/data/scripts/actions/quests/the_cursed_crystal/MedusaOil.lua new file mode 100644 index 00000000000..b6854ff2562 --- /dev/null +++ b/data/scripts/actions/quests/the_cursed_crystal/MedusaOil.lua @@ -0,0 +1,77 @@ +local ItemsCursed = { + [12422] = {usedID = 23873, finalID = 23874}, -- Flask with oil and blood + [23873] = {usedID = 12422, finalID = 23874}, -- Flask with oil and blood + [23874] = {usedID = 23876, finalID = 23875}, -- Medusa's oilment + [23876] = {usedID = 23874, finalID = 23875} -- Medusa's oilment +} + +local theCursedMedusa = Action() +function theCursedMedusa.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if (item.itemid == 23875) and (item2.itemid == 11337) then + if(player:getStorageValue(Storage.TibiaTales.TheCursedCrystal.Oneeyedjoe) == 2)then + if not(((Player(player):getPosition().x - TCC_PILLARPETRIFIED.x) < 5) and ((Player(player):getPosition().x - TCC_PILLARPETRIFIED.x) > -5) and + ((Player(player):getPosition().y - TCC_PILLARPETRIFIED.y) < 5) and ((Player(player):getPosition().y - TCC_PILLARPETRIFIED.y) > -5) and (Player(player):getPosition().z == TCC_PILLARPETRIFIED.z)) then + return + end + player:setStorageValue(Storage.TibiaTales.TheCursedCrystal.Oneeyedjoe, 3) + item:remove(1) + item2:remove(1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You unpetrify a banshee's scream near the evil crystal, your ears protected by wax. Thus the baleful artefact is destroyed.") + local stone = Tile(TCC_PILLARPETRIFIED):getItemById(11753) + doSendMagicEffect(stone:getPosition(), CONST_ME_POFF) + stone:transform(11826) + addEvent(function() + stone:transform(11753) + end,5000) + end + return + elseif(item.itemid == 10025)then + if not(Tile(topos)) or not(Tile(topos):getTopCreature()) or not(Tile(topos):getTopCreature():isPlayer()) then + return + end + if (Player(player) == Player(Tile(topos):getTopCreature())) and (player:getStorageValue(Storage.TibiaTales.TheCursedCrystal.Oneeyedjoe) < 2) then + if not(((Player(player):getPosition().x - TCC_PILLARPETRIFIED.x) < 5) and ((Player(player):getPosition().x - TCC_PILLARPETRIFIED.x) > -5) and + ((Player(player):getPosition().y - TCC_PILLARPETRIFIED.y) < 5) and ((Player(player):getPosition().y - TCC_PILLARPETRIFIED.y) > -5) and (Player(player):getPosition().z == TCC_PILLARPETRIFIED.z)) then + return + end + player:setStorageValue(Storage.TibiaTales.TheCursedCrystal.Oneeyedjoe, 2) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You use the molten wax to plug your ears.") + doSendMagicEffect(player:getPosition(), CONST_ME_YELLOWSMOKE) + item:remove(1) + end + return + end + for index, value in pairs(ItemsCursed) do + if item2.itemid == index and item.itemid == value.usedID then + if(value.finalID == 23874)then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You mixed the first ingredients to create a special ointment. But it isn't complete yet.") + elseif(value.finalID == 23875)then + if(player:getStorageValue(Storage.TibiaTales.TheCursedCrystal.Questline) < 2)then + player:setStorageValue(Storage.TibiaTales.TheCursedCrystal.Questline, 2) + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You mixed the proper ingredients to create a special ointment. With this salve you may unpetrify a petrified object.") + end + local topParent = item2:getTopParent() + if topParent.isItem and (not topParent:isItem() or topParent.itemid ~= 460) then + local parent = item2:getParent() + if not parent:isTile() and (parent:addItem(value.finalID, 1) or topParent:addItem(value.finalID, 1)) then + item2:remove(1) + item:remove(1) + Game.createItem(value.finalID, 1, item2:getPosition()) + return true + else + Game.createItem(value.finalID, 1, item2:getPosition()) + end + else + Game.createItem(value.finalID, 1, item2:getPosition()) + end + item2:remove(1) + item:remove(1) + return + end + end + player:sendTextMessage(MESSAGE_FAILURE, "Sorry, not possible.") +end + +theCursedMedusa:id(10025,12422,23873,23874,23876) +theCursedMedusa:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_cursed_crystal/Misc.lua b/data/scripts/actions/quests/the_cursed_crystal/Misc.lua new file mode 100644 index 00000000000..af11aca2f15 --- /dev/null +++ b/data/scripts/actions/quests/the_cursed_crystal/Misc.lua @@ -0,0 +1,61 @@ +local theCursedMiscItem = Action() +function theCursedMiscItem.onUse(cid, item, frompos, item2, topos) + local user1 = Player(cid) + if (item.itemid == 5902) then + if ((item2.itemid == 1786) or (item2.itemid == 1788) or (item2.itemid == 1790) or (item2.itemid == 1792)) then + item:remove(1) + doPlayerAddItem(cid,10025,1) + end + return + elseif (item.itemid == 23923) then + if (((user1:getPosition().x - TCC_VORTEX_POSITION.x) < 4) and ((user1:getPosition().x - TCC_VORTEX_POSITION.x) > -4)) and + (((user1:getPosition().y - TCC_VORTEX_POSITION.y) < 4) and ((user1:getPosition().y - TCC_VORTEX_POSITION.y) > -4)) then + Game.createItem(8632, 1, TCC_VORTEX_POSITION) + Tile(TCC_VORTEX_POSITION):getItemById(8632):setActionId(35001) + doSendMagicEffect(user1:getPosition(), CONST_ME_SOUND_WHITE) + user1:sendTextMessage(MESSAGE_EVENT_ADVANCE, "As you use the small bell an unearthly sound rings out sweetly. At the same moment, the lake's waters begin to whirl.") + addEvent(function() + Tile(TCC_VORTEX_POSITION):getItemById(8632):remove() + end, 10000) + end + end +end + +theCursedMiscItem:id(5902,23923,23941) +theCursedMiscItem:register() + +local theCursedMiscAction = Action() +function theCursedMiscAction.onUse(cid, item, frompos, item2, topos) + if (item.actionid == 40001) and (item:getPosition() == TCC_SKELETON_PAPER_POS) then -- 40028 + if (user1:getStorageValue(Storage.TibiaTales.TheCursedCrystal.Oneeyedjoe) < 1) then + user1:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a sheet of paper.") + local paperCursedCrystal = doPlayerAddItem(cid, 1954, 1) + Item(paperCursedCrystal):setAttribute(ITEM_ATTRIBUTE_TEXT, "I did it! I reached the crystal gardens! What beauty and splendor I have seen down there. Even more: I discovered a small subterranean lake - but Harry was there before me. And he did something strange: He ringed a small, transparent looking bell and immediatly a big whirl appeared in the water. I suppose this is the mysterious way deeper into the caves we sought after for so long. But Harry, the coward, didn't dare to dive into the water. Instead he left the caverns and heeded back to the surface. I have to go after him tomorrow. I must have this bell!") + else + user1:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The pile of bones empty.") + end + return + elseif (item.actionid == 40001) and (item:getPosition() == TCC_SKELETON_BELL_POS) then -- 40029 + if (user1:getStorageValue(Storage.TibiaTales.TheCursedCrystal.Oneeyedjoe) < 1) then + user1:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a small crystal bell.") + doPlayerAddItem(cid, 23923, 1) + user1:setStorageValue(Storage.TibiaTales.TheCursedCrystal.Oneeyedjoe, 1) + else + user1:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The pile of bones empty.") + end + return + elseif (item.actionid == 40002) and (item.itemid == 23941) then + if (user1:getStorageValue(Storage.TibiaTales.TheCursedCrystal.Oneeyedjoe) > 0) then + if (user1:getStorageValue(Storage.TibiaTales.TheCursedCrystal.MedusaOil) < os.time()) then + user1:setStorageValue(Storage.TibiaTales.TheCursedCrystal.MedusaOil, os.time() + 72000) + doPlayerAddItem(cid, 23873, 1) + doSendMagicEffect(item:getPosition(), CONST_ME_MAGIC_RED) + user1:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You take some blood out of the hollow crystal. Hopefully that it is actually a medusa's blood.") + end + return + end + end +end + +theCursedMiscAction:id(40001, 40002) +theCursedMiscAction:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_cursed_crystal/Ointment.lua b/data/scripts/actions/quests/the_cursed_crystal/Ointment.lua new file mode 100644 index 00000000000..2f128fb8ecc --- /dev/null +++ b/data/scripts/actions/quests/the_cursed_crystal/Ointment.lua @@ -0,0 +1,31 @@ +local theCursedOintment = Action() +function theCursedOintment.onUse(player, item, frompos, item2, topos) + -- The Cursed Crystal quest: + if (item.itemid == 23875) and (item2.itemid == 11337) then + if(player:getStorageValue(Storage.TibiaTales.TheCursedCrystal.Oneeyedjoe) == 2)then + if not(((Player(player):getPosition().x - TCC_PILLARPETRIFIED.x) < 5) and ((Player(player):getPosition().x - TCC_PILLARPETRIFIED.x) > -5) and + ((Player(player):getPosition().y - TCC_PILLARPETRIFIED.y) < 5) and ((Player(player):getPosition().y - TCC_PILLARPETRIFIED.y) > -5) and (Player(player):getPosition().z == TCC_PILLARPETRIFIED.z)) then + return + end + if (player:getStorageValue(Storage.TibiaTales.TheCursedCrystal.Questline) < 3)then + player:setStorageValue(Storage.TibiaTales.TheCursedCrystal.Questline, 3) + end + player:setStorageValue(Storage.TibiaTales.TheCursedCrystal.Oneeyedjoe, 3) + item:remove(1) + item2:remove(1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You unpetrify a banshee's scream near the evil crystal, your ears protected by wax. Thus the baleful artefact is destroyed.") + local stone = Tile(TCC_PILLARPETRIFIED):getItemById(11753) + doSendMagicEffect(stone:getPosition(), CONST_ME_POFF) + stone:transform(11826) + addEvent(function() + stone:transform(11753) + end,5000) + end + return + -- The dream courts quest: not ready + -- elseif + end +end + +theCursedOintment:id(23875) +theCursedOintment:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_hidden_city_of_beregar/bargate_lever.lua b/data/scripts/actions/quests/the_hidden_city_of_beregar/bargate_lever.lua new file mode 100644 index 00000000000..59956ad180b --- /dev/null +++ b/data/scripts/actions/quests/the_hidden_city_of_beregar/bargate_lever.lua @@ -0,0 +1,49 @@ +-- NEED REVIEW +local config = { + gatePositions = { + Position(32569, 31421, 9), + Position(32569, 31422, 9) + }, + leverPositions = { + Position(32568, 31421, 9), + Position(32570, 31421, 9) + }, + removeCreaturePosition = Position(32568, 31422, 9), + wallID = 3519, + wallID2 = 3524, + tileID = 3154 +} + +local theHiddenBeregar = Action() +function theHiddenBeregar.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local tile, thing, thing2 , creature, lever, leverstatus + leverstatus = item.itemid + for i = 1, #config.leverPositions do + lever = Tile(config.leverPositions[i]):getItemById(leverstatus == 1945 and 1945 or 1946) + lever:transform(item.itemid == 1945 and 1946 or 1945) + end + for i = 1, #config.gatePositions do + tile = Tile(config.gatePositions[i]) + if tile then + creature = tile:getTopCreature() + if leverstatus == 1945 then + thing = tile:getItemById(config.wallID) + thing2 = tile:getItemById(config.wallID2) + if thing and thing2 then + thing:remove() + thing2:remove() + end + else + Game.createItem(config.wallID, 1, config.gatePositions[i]) + Game.createItem(config.wallID2, 1, config.gatePositions[i]) + end + if creature then + creature:teleportTo(config.removeCreaturePosition) + end + end + end + return true +end + +--theHiddenBeregar:id() +--theHiddenBeregar:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_hidden_city_of_beregar/coal_exit_wagons.lua b/data/scripts/actions/quests/the_hidden_city_of_beregar/coal_exit_wagons.lua new file mode 100644 index 00000000000..47f6610ff96 --- /dev/null +++ b/data/scripts/actions/quests/the_hidden_city_of_beregar/coal_exit_wagons.lua @@ -0,0 +1,22 @@ +local config = { + [50122] = Position(32704, 31507, 12), -- small tunnel with golems + [50123] = Position(32661, 31495, 13), -- mushroom quest + [50124] = Position(32687, 31470, 13), -- wagon maze + [50125] = Position(32690, 31495, 11) -- room with lava that I couldn't find, setting destination to the same as mushroom quest +} + +local theHiddenCoalExit = Action() +function theHiddenCoalExit.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local targetPosition = config[item.actionid] + if not targetPosition then + return true + end + + player:teleportTo(targetPosition) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + item:remove() + return true +end + +theHiddenCoalExit:aid(50122,50123,50124,50125) +theHiddenCoalExit:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_hidden_city_of_beregar/coal_levers.lua b/data/scripts/actions/quests/the_hidden_city_of_beregar/coal_levers.lua new file mode 100644 index 00000000000..21c1124c78a --- /dev/null +++ b/data/scripts/actions/quests/the_hidden_city_of_beregar/coal_levers.lua @@ -0,0 +1,30 @@ +local config = { + [50108] = {actionId = 50122, wagonPos = Position(32696, 31495, 11)}, + [50109] = {actionId = 50123, wagonPos = Position(32694, 31495, 11)}, + [50110] = {actionId = 50124, wagonPos = Position(32692, 31495, 11)}, + [50111] = {actionId = 50125, wagonPos = Position(32690, 31495, 11)} +} + +local theHiddenCoalLevers = Action() +function theHiddenCoalLevers.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local useItem = config[item.uid] + if not useItem then + return true + end + + local crucible = Tile(Position(32699, 31494, 11)):getItemById(8641) + if crucible.actionid == 50121 then + local wagon = Game.createItem(7132, 1, useItem.wagonPos) + if wagon then + wagon:setActionId(useItem.actionId) + end + + crucible:transform(8642) + end + + item:transform(item.itemid == 10044 and 10045 or 10044) + return true +end + +theHiddenCoalLevers:uid(50108,50109,50110,50111) +theHiddenCoalLevers:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_hidden_city_of_beregar/coal_wagon.lua b/data/scripts/actions/quests/the_hidden_city_of_beregar/coal_wagon.lua new file mode 100644 index 00000000000..8b730ca3921 --- /dev/null +++ b/data/scripts/actions/quests/the_hidden_city_of_beregar/coal_wagon.lua @@ -0,0 +1,15 @@ +local theHiddenCoalWagon = Action() +function theHiddenCoalWagon.onUse(player, item, fromPosition, itemEx, toPosition) + if player:getStorageValue(Storage.DwarvenLegs) < 1 then + player:teleportTo({x = 32693, y = 31460, z = 13}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + else + player:say("Zzz Dont working.", TALKTYPE_ORANGE_1) + return true + end + return false +end + +theHiddenCoalWagon:aid(50117) +theHiddenCoalWagon:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_hidden_city_of_beregar/deeper_mine_wagon.lua b/data/scripts/actions/quests/the_hidden_city_of_beregar/deeper_mine_wagon.lua new file mode 100644 index 00000000000..22f1e0f4815 --- /dev/null +++ b/data/scripts/actions/quests/the_hidden_city_of_beregar/deeper_mine_wagon.lua @@ -0,0 +1,26 @@ +local config = { + [1] = Position(32566, 31505, 9), + [2] = Position(32611, 31513, 9) +} + +local theHiddenDeeper = Action() +function theHiddenDeeper.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.HiddenCityOfBeregar.RoyalRescue) >= 3 then + player:teleportTo(Position(32611, 31513, 9), true) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + local targetPosition = config[player:getStorageValue(Storage.HiddenCityOfBeregar.RoyalRescue)] + if not targetPosition then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You don't have permission to use this yet.") + return true + end + + player:teleportTo(targetPosition, true) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +theHiddenDeeper:aid(50128) +theHiddenDeeper:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_hidden_city_of_beregar/gap_wagon.lua b/data/scripts/actions/quests/the_hidden_city_of_beregar/gap_wagon.lua new file mode 100644 index 00000000000..55f41fd4f5f --- /dev/null +++ b/data/scripts/actions/quests/the_hidden_city_of_beregar/gap_wagon.lua @@ -0,0 +1,32 @@ +local theHiddenGapWagon = Action() +function theHiddenGapWagon.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local tile = Tile(Position(32571, 31508, 9)) + if not tile:getItemById(7122) then + player:teleportTo(Position(32580, 31487, 9)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say("You need to build a bridge to pass the gap.", TALKTYPE_MONSTER_SAY) + return true + end + + if player:getStorageValue(Storage.HiddenCityOfBeregar.RoyalRescue) ~= 1 then + return false + end + + player:setStorageValue(Storage.HiddenCityOfBeregar.RoyalRescue, 2) + player:teleportTo(Position(32578, 31507, 9)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say("You safely passed the gap but your bridge collapsed behind you.", TALKTYPE_MONSTER_SAY) + + local items = tile:getItems() + for i = 1, tile:getItemCount() do + local tmpItem = items[i] + if isInArray({7122, 5770}, tmpItem:getId()) then + tmpItem:remove() + end + end + + return true +end + +theHiddenGapWagon:aid(50112) +theHiddenGapWagon:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_hidden_city_of_beregar/ore_wagon.lua b/data/scripts/actions/quests/the_hidden_city_of_beregar/ore_wagon.lua new file mode 100644 index 00000000000..f93f67cb9e3 --- /dev/null +++ b/data/scripts/actions/quests/the_hidden_city_of_beregar/ore_wagon.lua @@ -0,0 +1,35 @@ +local config = { + [50098] = Position(32687, 31470, 13), + [50099] = Position(32600, 31504, 13), + [50100] = Position(32604, 31338, 11), + [50101] = Position(32611, 31513, 9), + [50102] = Position(32652, 31507, 10), + [50103] = Position(32692, 31501, 11), + [50104] = Position(32687, 31470, 13), + [50105] = Position(32687, 31470, 13), + [50106] = Position(32687, 31470, 13), + [50107] = Position(32580, 31487, 9), + [50108] = Position(32687, 31470, 13) +} + +local theHiddenOreWagon = Action() +function theHiddenOreWagon.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local targetPosition = config[item.actionid] + if not targetPosition then + return true + end + + + if player:getStorageValue(Storage.HiddenCityOfBeregar.OreWagon) == 1 then + player:teleportTo(targetPosition) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + elseif player:getStorageValue(Storage.HiddenCityOfBeregar.OreWagon) < 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You don't know how to use this yet.") + end + return true +end + +for value = 50098, 50108 do + theHiddenOreWagon:aid(value) +end +theHiddenOreWagon:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_hidden_city_of_beregar/tunnel_wagon.lua b/data/scripts/actions/quests/the_hidden_city_of_beregar/tunnel_wagon.lua new file mode 100644 index 00000000000..75292f441fa --- /dev/null +++ b/data/scripts/actions/quests/the_hidden_city_of_beregar/tunnel_wagon.lua @@ -0,0 +1,35 @@ +local theHiddenTunnel = Action() +function theHiddenTunnel.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local rubblePosition = Position(32619, 31514, 9) + if Tile(rubblePosition):getItemById(5709) then + player:teleportTo(Position(32580, 31487, 9)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say("You need to build a bridge to pass the gap.", TALKTYPE_MONSTER_SAY) + return true + end + + if player:getStorageValue(Storage.HiddenCityOfBeregar.RoyalRescue) ~= 2 then + return false + end + + player:setStorageValue(Storage.HiddenCityOfBeregar.RoyalRescue, 3) + player:teleportTo(Position(32625, 31514, 9)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say("You safely passed the tunnel.", TALKTYPE_MONSTER_SAY) + Game.createItem(5709, 1, rubblePosition) + + local wallItem = Tile(Position(32617, 31513, 9)):getItemById(1027) + if wallItem then + wallItem:remove() + end + + local archwayItem = Tile(Position(32617, 31514, 9)):getItemById(1205) + if archwayItem then + archwayItem:remove() + end + + return true +end + +theHiddenTunnel:aid(50115) +theHiddenTunnel:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_hidden_city_of_beregar/wagon_maze_exit.lua b/data/scripts/actions/quests/the_hidden_city_of_beregar/wagon_maze_exit.lua new file mode 100644 index 00000000000..6f1b59f2f5f --- /dev/null +++ b/data/scripts/actions/quests/the_hidden_city_of_beregar/wagon_maze_exit.lua @@ -0,0 +1,23 @@ +local theHiddenWagonExit = Action() +function theHiddenWagonExit.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local destinations = { + {teleportPos = Position(32692, 31501, 11), railCheck = Tile(Position(32688, 31469, 13)):getItemById(7124) and Tile(Position(32690, 31465, 13)):getItemById(7122)}, --Coal Room + {teleportPos = Position(32549, 31407, 11), railCheck = Tile(Position(32688, 31469, 13)):getItemById(7124) and Tile(Position(32690, 31465, 13)):getItemById(7125) and Tile(Position(32684, 31464, 13)):getItemById(7123)}, --Infested Tavern + {teleportPos = Position(32579, 31487, 9), railCheck = Tile(Position(32688, 31469, 13)):getItemById(7124) and Tile(Position(32690, 31465, 13)):getItemById(7125) and Tile(Position(32684, 31464, 13)):getItemById(7122) and Tile(Position(32682, 31455, 13)):getItemById(7124)}, --Beregar + {teleportPos = Position(32701, 31448, 15), railCheck = Tile(Position(32688, 31469, 13)):getItemById(7124) and Tile(Position(32690, 31465, 13)):getItemById(7125) and Tile(Position(32684, 31464, 13)):getItemById(7122) and Tile(Position(32682, 31455, 13)):getItemById(7121) and Tile(Position(32687, 31452, 13)):getItemById(7125) and Tile(Position(32692, 31453, 13)):getItemById(7126)}, --NPC Tehlim + {teleportPos = Position(32721, 31487, 15), railCheck = Tile(Position(32688, 31469, 13)):getItemById(7121) and Tile(Position(32692, 31459, 13)):getItemById(7123) and Tile(Position(32696, 31453, 13)):getItemById(7123)}, --Troll tribe's hideout + {teleportPos = Position(32600, 31504, 13), railCheck = Tile(Position(32688, 31469, 13)):getItemById(7123) and Tile(Position(32695, 31464, 13)):getItemById(7123)} --City's Entrance + } + + for i = 1, #config do + local table = config[i] + if table.railCheck then + player:teleportTo(table.teleportPos) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + return true +end + +theHiddenWagonExit:uid(50124) +theHiddenWagonExit:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_hidden_city_of_beregar/wagon_maze_levers.lua b/data/scripts/actions/quests/the_hidden_city_of_beregar/wagon_maze_levers.lua new file mode 100644 index 00000000000..4de4907205b --- /dev/null +++ b/data/scripts/actions/quests/the_hidden_city_of_beregar/wagon_maze_levers.lua @@ -0,0 +1,36 @@ +local levers = { + {uniqueId = 50113, railPos = Position(32696, 31453, 13)}, + {uniqueId = 50114, railPos = Position(32692, 31453, 13)}, + {uniqueId = 50115, railPos = Position(32687, 31452, 13)}, + {uniqueId = 50116, railPos = Position(32682, 31455, 13)}, + {uniqueId = 50117, railPos = Position(32688, 31456, 13)}, + {uniqueId = 50118, railPos = Position(32692, 31459, 13)}, + {uniqueId = 50119, railPos = Position(32696, 31461, 13)}, + {uniqueId = 50120, railPos = Position(32695, 31464, 13)}, + {uniqueId = 50121, railPos = Position(32690, 31465, 13)}, + {uniqueId = 50122, railPos = Position(32684, 31464, 13)}, + {uniqueId = 50123, railPos = Position(32688, 31469, 13)} +} + +local theHiddenWagonLevers = Action() +function theHiddenWagonLevers.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + for i = 1, #config do + local table = config[i] + if item.uid == table.uniqueId then + local tile = Tile(railPos) + if tile:getItemById(7130) then + tile:getItemById(7130):transform(7121) + else + tile:getItemById():transform(item.itemid + 1) + end + end + end + item:transform(item.itemid == 10044 and 10045 or 10044) + return true +end + +for value = 50113, 50123 do + theHiddenWagonLevers:uid(value) +end +theHiddenWagonLevers:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_lost_brother/asura_mirror.lua b/data/scripts/actions/quests/the_lost_brother/asura_mirror.lua new file mode 100644 index 00000000000..e80cd16b332 --- /dev/null +++ b/data/scripts/actions/quests/the_lost_brother/asura_mirror.lua @@ -0,0 +1,9 @@ +local theLostAsura = Action() +function theLostAsura.onUse(player, item, fromPosition, itemEx, toPosition) + player:teleportTo({x = 32966, y = 31460, z = 1}) -- Where to tp to 33672, 31884, 5 + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +theLostAsura:aid(12441) +theLostAsura:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_new_frontier/arena.lua b/data/scripts/actions/quests/the_new_frontier/arena.lua new file mode 100644 index 00000000000..f65340ab578 --- /dev/null +++ b/data/scripts/actions/quests/the_new_frontier/arena.lua @@ -0,0 +1,85 @@ +local config = { + bosses = { + {'Baron Brute', 'The Axeorcist'}, + {'Menace', 'Fatality'}, + {'Incineron', 'Coldheart'}, + {'Dreadwing', 'Doomhowl'}, + {'Haunter', 'The Dreadorian'}, + {'Rocko', 'Tremorak'}, + {'Tirecz'} + }, + + teleportPositions = { + Position(33059, 31032, 3), + Position(33057, 31034, 3) + }, + + positions = { + -- other bosses + Position(33065, 31035, 3), + Position(33068, 31034, 3), + + -- first 2 bosses + Position(33065, 31033, 3), + Position(33066, 31037, 3) + } +} + +local function summonBoss(name, position) + Game.createMonster(name, position) + position:sendMagicEffect(CONST_ME_TELEPORT) +end + +local function clearArena() + local spectators = Game.getSpectators(Position(33063, 31034, 3), false, false, 10, 10, 10, 10) + local exitPosition = Position(33049, 31017, 2) + for i = 1, #spectators do + local spectator = spectators[i] + if spectator:isPlayer() then + spectator:teleportTo(exitPosition) + exitPosition:sendMagicEffect(CONST_ME_TELEPORT) + else + spectator:remove() + end + end +end + +local theNewFrontierArena = Action() +function theNewFrontierArena.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local player1 = Tile(Position({x = 33080, y = 31014, z = 2})):getTopCreature() + if not(player1 and player1:isPlayer()) then + return true + end + + local player2 = Tile(Position({x = 33081, y = 31014, z = 2})):getTopCreature() + if not(player2 and player2:isPlayer()) then + return true + end + + if player1:getStorageValue(Storage.TheNewFrontier.Questline) ~= 25 then + player1:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You already finished this battle.') + return true + end + + if Game.getStorageValue(Storage.TheNewFrontier.Mission09) == 1 then + player1:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The arena is already in use.') + return true + end + + Game.setStorageValue(Storage.TheNewFrontier.Mission09, 1) + addEvent(clearArena, 30 * 60 * 1000) + player1:teleportTo(config.teleportPositions[1]) + player1:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player2:teleportTo(config.teleportPositions[2]) + player2:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + + for i = 1, #config.bosses do + for j = 1, #config.bosses[i] do + addEvent(summonBoss, (i - 1) * 90 * 1000, config.bosses[i][j], config.positions[j + (i == 1 and 2 or 0)]) + end + end + return true +end + +theNewFrontierArena:uid(3157) +theNewFrontierArena:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_new_frontier/beaver.lua b/data/scripts/actions/quests/the_new_frontier/beaver.lua new file mode 100644 index 00000000000..f6e7d93b5d2 --- /dev/null +++ b/data/scripts/actions/quests/the_new_frontier/beaver.lua @@ -0,0 +1,47 @@ +local theNewFrontierBeaver = Action() +function theNewFrontierBeaver.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid == 8002 then + if player:getStorageValue(Storage.TheNewFrontier.Questline) == 5 and player:getStorageValue(Storage.TheNewFrontier.Beaver1) < 1 then + Game.createMonster("thieving squirrel", toPosition) + toPosition:sendMagicEffect(CONST_ME_TELEPORT) + player:setStorageValue(Storage.TheNewFrontier.Beaver1, 1) + player:setStorageValue(Storage.TheNewFrontier.Mission02, player:getStorageValue(Storage.TheNewFrontier.Mission02) + 1) --Questlog, The New Frontier Quest "Mission 02: From Kazordoon With Love" + Game.createMonster("thieving squirrel", toPosition) + player:say("You've marked the tree, but its former inhabitant has stolen your bait! Get it before it runs away!", TALKTYPE_MONSTER_SAY) + item:remove() + end + elseif target.actionid == 8003 then + if player:getStorageValue(Storage.TheNewFrontier.Questline) == 5 and player:getStorageValue(Storage.TheNewFrontier.Beaver2) < 1 then + for i = 1, 5 do + pos = toPosition + Game.createMonster("wolf", pos) + toPosition:sendMagicEffect(CONST_ME_TELEPORT) + end + Game.createMonster("war wolf", toPosition) + toPosition:sendMagicEffect(CONST_ME_TELEPORT) + player:setStorageValue(Storage.TheNewFrontier.Beaver2, 1) + player:setStorageValue(Storage.TheNewFrontier.Mission02, player:getStorageValue(Storage.TheNewFrontier.Mission02) + 1) --Questlog, The New Frontier Quest "Mission 02: From Kazordoon With Love" + player:say("You have marked the tree but it seems someone marked it already! He is not happy with your actions and he brought friends!", TALKTYPE_MONSTER_SAY) + end + elseif target.actionid == 8004 then + if player:getStorageValue(Storage.TheNewFrontier.Questline) == 5 and player:getStorageValue(Storage.TheNewFrontier.Beaver3) < 1 then + for i = 1, 3 do + pos = toPosition + Game.createMonster("enraged squirrel", pos) + toPosition:sendMagicEffect(CONST_ME_TELEPORT) + end + player:setStorageValue(Storage.TheNewFrontier.Beaver3, 1) + player:setStorageValue(Storage.TheNewFrontier.Mission02, player:getStorageValue(Storage.TheNewFrontier.Mission02) + 1) --Questlog, The New Frontier Quest "Mission 02: From Kazordoon With Love" + player:say("You have marked the tree, but you also angered the aquirrel family who lived on it!", TALKTYPE_MONSTER_SAY) + end + end + if player:getStorageValue(Storage.TheNewFrontier.Beaver1) == 1 + and player:getStorageValue(Storage.TheNewFrontier.Beaver2) == 1 + and player:getStorageValue(Storage.TheNewFrontier.Beaver3) == 1 then + player:setStorageValue(Storage.TheNewFrontier.Questline, 6) + end + return true +end + +theNewFrontierBeaver:id(11100) +theNewFrontierBeaver:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_new_frontier/lever.lua b/data/scripts/actions/quests/the_new_frontier/lever.lua new file mode 100644 index 00000000000..2ddc894a6cd --- /dev/null +++ b/data/scripts/actions/quests/the_new_frontier/lever.lua @@ -0,0 +1,42 @@ +local config = { + [8005] = Position(33055, 31527, 14), + [8006] = Position(33065, 31489, 15) +} + +local theNewFrontierLever = Action() +function theNewFrontierLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local targetPosition = config[item.actionid] + if not targetPosition then + return true + end + + item:transform(item.itemid == 1945 and 1946 or 1945) + + toPosition.x = item.actionid == 8005 and toPosition.x + 1 or toPosition.x - 1 + local creature = Tile(toPosition):getTopCreature() + if not creature or not creature:isPlayer() then + return true + end + + if item.itemid ~= 1945 then + return true + end + + if item.actionid == 8005 then + if creature:getStorageValue(Storage.TheNewFrontier.Mission05) == 7 then + targetPosition.z = 10 + elseif creature:getStorageValue(Storage.TheNewFrontier.Mission03) == 3 then + targetPosition.z = 12 + elseif creature:getStorageValue(Storage.TheNewFrontier.Mission03) < 2 then + targetPosition.z = 14 + end + end + + creature:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + creature:teleportTo(targetPosition) + targetPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +theNewFrontierLever:aid(8005,8006) +theNewFrontierLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_new_frontier/outfit.lua b/data/scripts/actions/quests/the_new_frontier/outfit.lua new file mode 100644 index 00000000000..15b91d974d3 --- /dev/null +++ b/data/scripts/actions/quests/the_new_frontier/outfit.lua @@ -0,0 +1,14 @@ +local theNewFrontierOutfit = Action() +function theNewFrontierOutfit.onUse(player, item) + if player:getStorageValue(Storage.TheNewFrontier.Questline) == 26 then + player:addOutfit(335, 0) + player:addOutfit(336, 0) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have gained your new outfit and may leave the reward room now!") + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You already taken the outfit, ask about mission for Chrak.") + end + return true +end + +theNewFrontierOutfit:aid(45440) +theNewFrontierOutfit:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_new_frontier/retreat.lua b/data/scripts/actions/quests/the_new_frontier/retreat.lua new file mode 100644 index 00000000000..7b1ffa49a86 --- /dev/null +++ b/data/scripts/actions/quests/the_new_frontier/retreat.lua @@ -0,0 +1,11 @@ +local theNewFrontierRetreat = Action() +function theNewFrontierRetreat.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local destination = Position(33170, 31247, 11) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_POFF) + player:setStorageValue(Storage.TheNewFrontier.Questline, 23) + return true +end + +theNewFrontierRetreat:uid(3156) +theNewFrontierRetreat:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_new_frontier/vine.lua b/data/scripts/actions/quests/the_new_frontier/vine.lua new file mode 100644 index 00000000000..2e1d56d78f8 --- /dev/null +++ b/data/scripts/actions/quests/the_new_frontier/vine.lua @@ -0,0 +1,19 @@ +local config = { + [3153] = Position(33022, 31536, 6), + [3154] = Position(33020, 31536, 4) +} + +local theNewFrontierVine = Action() +function theNewFrontierVine.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local targetPosition = config[item.uid] + if not targetPosition then + return true + end + + player:teleportTo(targetPosition) + targetPosition:sendMagicEffect(CONST_ME_POFF) + return true +end + +theNewFrontierVine:uid(3153,3154) +theNewFrontierVine:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_outlaw_camp/oven.lua b/data/scripts/actions/quests/the_outlaw_camp/oven.lua new file mode 100644 index 00000000000..93851562bd1 --- /dev/null +++ b/data/scripts/actions/quests/the_outlaw_camp/oven.lua @@ -0,0 +1,24 @@ +local config = { + [1945] = {position = {Position(32623, 32188, 9), Position(32623, 32189, 9)}}, + [1946] = {position = {Position(32623, 32189, 9), Position(32623, 32188, 9)}} +} + +local theOutlawOven = Action() +function theOutlawOven.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local useItem = config[item.itemid] + if not useItem then + return true + end + + + local oven = Tile(useItem.position[1]):getTopTopItem() + if oven and isInArray({1786, 1787}, oven.itemid) then + oven:moveTo(useItem.position[2]) + end + + item:transform(item.itemid == 1945 and 1946 or 1945) + return true +end + +theOutlawOven:uid(3400) +theOutlawOven:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_outlaw_camp/power_burn.lua b/data/scripts/actions/quests/the_outlaw_camp/power_burn.lua new file mode 100644 index 00000000000..7fcb9c36512 --- /dev/null +++ b/data/scripts/actions/quests/the_outlaw_camp/power_burn.lua @@ -0,0 +1,21 @@ +local theOutlawPower = Action() +function theOutlawPower.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + local power1 = Tile(Position({x = 32613, y = 32220, z = 10})) + local barrel = Tile(Position({x = 32614, y = 32209, z = 10})) + local wall = Tile(Position({x = 32614, y = 32205, z = 10})) + local stone = Tile(Position({x = 32614, y = 32206, z = 10})) + local burn = Position({x = 32615, y = 32221, z = 10}) + + if item.itemid == 1945 and power1:getItemById(2166) and wall:getItemById(1025) and stone:getItemById(1304) and barrel:getItemById(1774) then + power1:getItemById(2166):transform(1487) + wall:getItemById(1025):remove() + stone:getItemById(1304):transform(1025) + Game.createItem(1487, 1, burn) + end + item:transform(item.itemid == 1945 and 1946 or 1945) + return true +end + +theOutlawPower:id(3402) +theOutlawPower:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_outlaw_camp/power_switch.lua b/data/scripts/actions/quests/the_outlaw_camp/power_switch.lua new file mode 100644 index 00000000000..5cde0624e3b --- /dev/null +++ b/data/scripts/actions/quests/the_outlaw_camp/power_switch.lua @@ -0,0 +1,20 @@ + +local theOutlawPowerSwitch = Action() +function theOutlawPowerSwitch.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + local wall = Tile(Position({x=32604, y=32216, z=9})) + local power2pos = Position({x = 32613, y = 32220, z = 10}) + local power1pos = Position({x = 32594, y = 32214, z = 9}) + local power1 = power1pos:getTile() + + if item.itemid == 1945 and power1:getItemById(2166) and wall:getItemById(1026) then + power1:getItemById(2166):moveTo(power2pos) + wall:getItemById(1026):remove() + power1pos:sendMagicEffect(CONST_ME_TELEPORT) + end + item:transform(item.itemid == 1945 and 1946 or 1945) + return true +end + +theOutlawPowerSwitch:uid(3401) +theOutlawPowerSwitch:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_secret_library/asura_mirror.lua b/data/scripts/actions/quests/the_secret_library/asura_mirror.lua new file mode 100644 index 00000000000..445be7dac92 --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/asura_mirror.lua @@ -0,0 +1,20 @@ +local goPos = {x = 32813, y = 32754, z = 9} + +local asuraMirror = Action() +function asuraMirror.onUse(creature, item, position, fromPosition, pos, target, toPosition) + local player = creature:getPlayer() + if not player then + return + end + + if player:getLevel() >= 250 then + position:sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(goPos) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:sendCancelMessage('You do not have enough level.') + end +end + +asuraMirror:aid(64019) +asuraMirror:register() diff --git a/data/scripts/actions/quests/the_secret_library/basinfire.lua b/data/scripts/actions/quests/the_secret_library/basinfire.lua new file mode 100644 index 00000000000..0a300e229e4 --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/basinfire.lua @@ -0,0 +1,18 @@ +local basinFire = Action() + +function basinFire.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TheSecretLibrary.Mota) == 8 then + if target.itemid == 1485 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a reward.") + player:setStorageValue(Storage.TheSecretLibrary.Mota, 9) + player:removeItem(32408, 1) + player:addItem(32623, 1) + player:setStorageValue(Storage.TheSecretLibrary.BasinDoor, 1) + end + return true + end + return false +end + +basinFire:id(1089) +basinFire:register() diff --git a/data/scripts/actions/quests/the_secret_library/blacktp.lua b/data/scripts/actions/quests/the_secret_library/blacktp.lua new file mode 100644 index 00000000000..e6d511fb8be --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/blacktp.lua @@ -0,0 +1,14 @@ +local backTp = Action() + +function backTp.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TheSecretLibrary.BlackTel) == -1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You have found a skull.") + player:addItem(33272, 1) + player:setStorageValue(Storage.TheSecretLibrary.BlackTel, 1) + return true + end + return false +end + +backTp:uid(1098) +backTp:register() diff --git a/data/scripts/actions/quests/the_secret_library/bluetp.lua b/data/scripts/actions/quests/the_secret_library/bluetp.lua new file mode 100644 index 00000000000..b578e7bbb60 --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/bluetp.lua @@ -0,0 +1,14 @@ +local greenTp = Action() + +function greenTp.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TheSecretLibrary.BlueTel) == -1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You have found a piece of ebony.") + player:addItem(33274, 1) + player:setStorageValue(Storage.TheSecretLibrary.BlueTel, 1) + return true + end + return false +end + +greenTp:uid(1097) +greenTp:register() diff --git a/data/scripts/actions/quests/the_secret_library/boattp.lua b/data/scripts/actions/quests/the_secret_library/boattp.lua new file mode 100644 index 00000000000..7a65d92d4e2 --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/boattp.lua @@ -0,0 +1,17 @@ +local boatTp = Action() + +function boatTp.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TheSecretLibrary.HighDry) == 4 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"The raft was not that solid in the end, its parts are floating in the ocean now. But at least you reached dry land.") + player:removeItem(32407, 1) + player:teleportTo(Position(32187, 32474, 7)) + player:setStorageValue(Storage.TheSecretLibrary.HighDry, 5) + player:setStorageValue(Storage.TheSecretLibrary.PinkTel, 3) + player:setStorageValue(Storage.TheSecretLibrary.Mota, 13) + return true + end + return false +end + +boatTp:uid(1104) +boatTp:register() diff --git a/data/scripts/actions/quests/the_secret_library/bone.lua b/data/scripts/actions/quests/the_secret_library/bone.lua new file mode 100644 index 00000000000..2a5244d449b --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/bone.lua @@ -0,0 +1,13 @@ +local bone = Action() + +function bone.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TheSecretLibrary.Mota) == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a reward.") + player:setStorageValue(Storage.TheSecretLibrary.Mota, 2) + return true + end + return false +end + +bone:uid(1083) +bone:register() diff --git a/data/scripts/actions/quests/the_secret_library/bonedoor.lua b/data/scripts/actions/quests/the_secret_library/bonedoor.lua new file mode 100644 index 00000000000..596841b27a4 --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/bonedoor.lua @@ -0,0 +1,17 @@ +local boneDoor = Action() + +function boneDoor.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TheSecretLibrary.Mota) == 9 then + if target.itemid == 11832 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a reward.") + player:setStorageValue(Storage.TheSecretLibrary.Mota, 10) + player:removeItem(32648, 1) + player:setStorageValue(Storage.TheSecretLibrary.SkullDoor, 1) + end + return true + end + return false +end + +boneDoor:id(1090) +boneDoor:register() diff --git a/data/scripts/actions/quests/the_secret_library/book.lua b/data/scripts/actions/quests/the_secret_library/book.lua new file mode 100644 index 00000000000..91b1400694a --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/book.lua @@ -0,0 +1,14 @@ +local bookdeepling = Action() + +function bookdeepling.onUse(player, item, frompos, item2, topos) + if player:getStorageValue(Storage.TheSecretLibrary.LiquidDeath) == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"The descriptions in this book look like plans detailing the launch of a large-scale assault.") + player:setStorageValue(Storage.TheSecretLibrary.LiquidDeath, 2) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "oh sorry") + end + return true +end + +bookdeepling:uid(1073) +bookdeepling:register() diff --git a/data/scripts/actions/quests/the_secret_library/corpse.lua b/data/scripts/actions/quests/the_secret_library/corpse.lua new file mode 100644 index 00000000000..5f2a91df10c --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/corpse.lua @@ -0,0 +1,14 @@ +local corpse = Action() + +function corpse.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TheSecretLibrary.TheLament) == 5 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You have found a scribbled notes.") + player:addItem(33292, 1) + player:setStorageValue(Storage.TheSecretLibrary.TheLament, 6) + return true + end + return false +end + +corpse:uid(1095) +corpse:register() diff --git a/data/scripts/actions/quests/the_secret_library/energybasin.lua b/data/scripts/actions/quests/the_secret_library/energybasin.lua new file mode 100644 index 00000000000..ef8fa43b25d --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/energybasin.lua @@ -0,0 +1,51 @@ +local config = { + -- yellow + [1085] = { + itemId = 32642, + msg = "Success", + storage = Storage.TheSecretLibrary.Mota, + getValue = 4, + setValue = 5, + basin = 2605 + }, + -- green + [1086] = { + itemId = 32641, + msg = "Success", + storage = Storage.TheSecretLibrary.Mota, + getValue = 5, + setValue = 6, + basin = 2605 + }, + -- red + [1087] = + {itemId = 32643, + msg = "Success", + storage = Storage.TheSecretLibrary.Mota, + getValue = 6, + setValue = 7, + basin = 2605 + } +} + +local energyBasin = Action() + +function energyBasin.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local setting = config[item.uid] + if setting then + if player:getStorageValue(setting.storage) == setting.getValue then + player:removeItem(setting.itemId, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, setting.msg) + player:setStorageValue(setting.storage, setting.setValue) + else + player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + end + end + return true +end + +for index, value in pairs(config) do + energyBasin:uid(index) +end + +energyBasin:register() diff --git a/data/scripts/actions/quests/the_secret_library/enterlibrary.lua b/data/scripts/actions/quests/the_secret_library/enterlibrary.lua new file mode 100644 index 00000000000..0eb988e9aa3 --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/enterlibrary.lua @@ -0,0 +1,16 @@ +local blacktp = Action() + +function blacktp.onUse(player, item, frompos, item2, topos) + + if player:getStorageValue(Storage.TheSecretLibrary.HighDry) == 5 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"Welcome to the Secret Library.") + player:teleportTo(Position(32516, 32537, 12)) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "sorry") + end + + return true +end + +blacktp:uid(26705) +blacktp:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_secret_library/eyekey.lua b/data/scripts/actions/quests/the_secret_library/eyekey.lua new file mode 100644 index 00000000000..cbffe3a334e --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/eyekey.lua @@ -0,0 +1,14 @@ +local eyeKey = Action() + +function eyeKey.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TheSecretLibrary.TheLament) == 4 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You have found a eye key.") + player:addItem(33265, 1) + player:setStorageValue(Storage.TheSecretLibrary.TheLament, 5) + return true + end + return false +end + +eyeKey:uid(1094) +eyeKey:register() diff --git a/data/scripts/actions/quests/the_secret_library/fish.lua b/data/scripts/actions/quests/the_secret_library/fish.lua new file mode 100644 index 00000000000..bd22741c85e --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/fish.lua @@ -0,0 +1,14 @@ +local fish = Action() + +function fish.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TheSecretLibrary.HighDry) == 2 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You have found a hawser.") + player:addItem(32407, 1) + player:setStorageValue(Storage.TheSecretLibrary.HighDry, 3) + return true + end + return false +end + +fish:uid(1102) +fish:register() diff --git a/data/scripts/actions/quests/the_secret_library/greentp.lua b/data/scripts/actions/quests/the_secret_library/greentp.lua new file mode 100644 index 00000000000..ad4698b4026 --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/greentp.lua @@ -0,0 +1,14 @@ +local greenTp = Action() + +function greenTp.onUse(player, item, frompos, item2, topos) + if player:getStorageValue(Storage.TheSecretLibrary.GreenTel) == -1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You see silver chimes dangling on the dragon statue in this room.") + player:addItem(33277, 1) + player:setStorageValue(Storage.TheSecretLibrary.GreenTel, 1) + return true + end + return false +end + +greenTp:uid(1096) +greenTp:register() diff --git a/data/scripts/actions/quests/the_secret_library/leverdoor.lua b/data/scripts/actions/quests/the_secret_library/leverdoor.lua new file mode 100644 index 00000000000..f8cc5d8af77 --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/leverdoor.lua @@ -0,0 +1,14 @@ +local leverDoor = Action() + +function leverDoor.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TheSecretLibrary.Mota) == 3 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a reward.") + player:setStorageValue(Storage.TheSecretLibrary.Mota, 4) + player:setStorageValue(Storage.TheSecretLibrary.MotaDoor, 1) + return true + end + return false +end + +leverDoor:uid(1084) +leverDoor:register() diff --git a/data/scripts/actions/quests/the_secret_library/leverruby.lua b/data/scripts/actions/quests/the_secret_library/leverruby.lua new file mode 100644 index 00000000000..c9365895118 --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/leverruby.lua @@ -0,0 +1,14 @@ +local leverRuby = Action() + +function leverRuby.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TheSecretLibrary.Mota) == 7 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a reward.") + player:addItem(32409, 1) + player:setStorageValue(Storage.TheSecretLibrary.Mota, 8) + return true + end + return false +end + +leverRuby:uid(1088) +leverRuby:register() diff --git a/data/scripts/actions/quests/the_secret_library/lotuskey.lua b/data/scripts/actions/quests/the_secret_library/lotuskey.lua new file mode 100644 index 00000000000..c4634370815 --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/lotuskey.lua @@ -0,0 +1,14 @@ +local lotusKey = Action() + +function lotusKey.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TheSecretLibrary.TheLament) == 3 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You have found a lotus key.") + player:addItem(33264, 1) + player:setStorageValue(Storage.TheSecretLibrary.TheLament, 4) + return true + end + return false +end + +lotusKey:uid(1093) +lotusKey:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_secret_library/peacock.lua b/data/scripts/actions/quests/the_secret_library/peacock.lua new file mode 100644 index 00000000000..c5e52aae923 --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/peacock.lua @@ -0,0 +1,14 @@ +local peacock = Action() + +function peacock.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TheSecretLibrary.Peacock) == -1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You have found the Peacock Ballad.") + player:addItem(32410, 1) + player:setStorageValue(Storage.TheSecretLibrary.Peacock, 1) + return true + end + return false +end + +peacock:uid(1099) +peacock:register() diff --git a/data/scripts/actions/quests/the_secret_library/pinktp.lua b/data/scripts/actions/quests/the_secret_library/pinktp.lua new file mode 100644 index 00000000000..a97bba5a284 --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/pinktp.lua @@ -0,0 +1,14 @@ +local blacktp = Action() + +function blacktp.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TheSecretLibrary.PinkTel) == -1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You discovered an old writing desk that contains an ancient map.") + player:addItem(27615, 1) + player:setStorageValue(Storage.TheSecretLibrary.PinkTel, 1) + return true + end + return false +end + +blacktp:uid(1100) +blacktp:register() diff --git a/data/scripts/actions/quests/the_secret_library/sealedbook.lua b/data/scripts/actions/quests/the_secret_library/sealedbook.lua new file mode 100644 index 00000000000..848feefb284 --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/sealedbook.lua @@ -0,0 +1,14 @@ +local sealedBook = Action() + +function sealedBook.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TheSecretLibrary.PinkTel) == 2 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You have found a scribbled notes.") + player:addItem(33391, 1) + player:setStorageValue(Storage.TheSecretLibrary.HighDry, 1) + return true + end + return false +end + +sealedBook:uid(1101) +sealedBook:register() diff --git a/data/scripts/actions/quests/the_secret_library/skullground.lua b/data/scripts/actions/quests/the_secret_library/skullground.lua new file mode 100644 index 00000000000..cb05d63c102 --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/skullground.lua @@ -0,0 +1,15 @@ +local skeleton = Action() + +function skeleton.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TheSecretLibrary.TheLament) == 2 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You have found an old letter.") + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You have discovered a skeleton. It seems to hold an old letter and its skull is missing.") + player:addItem(33294, 1) + player:setStorageValue(Storage.TheSecretLibrary.TheLament, 3) + return true + end + return false +end + +skeleton:uid(1092) +skeleton:register() diff --git a/data/scripts/actions/quests/the_secret_library/statuedeeplings.lua b/data/scripts/actions/quests/the_secret_library/statuedeeplings.lua new file mode 100644 index 00000000000..d7a9232a2e2 --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/statuedeeplings.lua @@ -0,0 +1,35 @@ +local config = { + [1074] = {itemId = 17240, msg = "The Njey will appreciate your help.", storage = Storage.TheSecretLibrary.LiquidDeath, getValue = 2, setValue = 3}, + [1075] = {itemId = 17240, msg = "The Njey will appreciate your help.", storage = Storage.TheSecretLibrary.LiquidDeath, getValue = 3, setValue = 4}, + [1076] = {itemId = 17240, msg = "The Njey will appreciate your help.", storage = Storage.TheSecretLibrary.LiquidDeath, getValue = 4, setValue = 5}, + [1077] = {itemId = 17240, msg = "The Njey will appreciate your help.", storage = Storage.TheSecretLibrary.LiquidDeath, getValue = 5, setValue = 6}, + [1078] = {itemId = 17240, msg = "The Njey will appreciate your help.", storage = Storage.TheSecretLibrary.LiquidDeath, getValue = 6, setValue = 7}, + [1079] = {itemId = 17240, msg = "The Njey will appreciate your help.", storage = Storage.TheSecretLibrary.LiquidDeath, getValue = 7, setValue = 8}, + [1080] = {itemId = 17240, msg = "The Njey will appreciate your help.", storage = Storage.TheSecretLibrary.LiquidDeath, getValue = 8, setValue = 9}, + [1081] = {itemId = 17240, msg = "The Njey will appreciate your help.", storage = Storage.TheSecretLibrary.LiquidDeath, getValue = 9, setValue = 10}, + [1082] = {itemId = 17240, msg = "The Njey will appreciate your help.", storage = Storage.TheSecretLibrary.LiquidDeath, getValue = 10, setValue = 11}, +} + +local statuedeeplings = Action() + +function statuedeeplings.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + local key = config[item.uid] + if key then + if player:getStorageValue(key.storage) == key.getValue then + if table.contains({key.itemId}, item.itemid) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, key.msg) + player:setStorageValue(key.storage, key.setValue) + end + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"Empty.") + end + end + return true +end + +for index, value in pairs(config) do + statuedeeplings:uid(index) +end + +statuedeeplings:register() diff --git a/data/scripts/actions/quests/the_secret_library/strandhair.lua b/data/scripts/actions/quests/the_secret_library/strandhair.lua new file mode 100644 index 00000000000..048d6c36248 --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/strandhair.lua @@ -0,0 +1,14 @@ +local strandHair = Action() + +function strandHair.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TheSecretLibrary.TheLament) == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You have found a strand of hair.") + player:addItem(33273, 1) + player:setStorageValue(Storage.TheSecretLibrary.TheLament, 2) + return true + end + return false +end + +strandHair:uid(1091) +strandHair:register() diff --git a/data/scripts/actions/quests/the_secret_library/telescop.lua b/data/scripts/actions/quests/the_secret_library/telescop.lua new file mode 100644 index 00000000000..5cce05313d5 --- /dev/null +++ b/data/scripts/actions/quests/the_secret_library/telescop.lua @@ -0,0 +1,13 @@ +local telescop = Action() + +function telescop.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TheSecretLibrary.HighDry) == 3 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"By using the telescope you observate the stellar constellations. This should help you to navigate your way back to mainland.") + player:setStorageValue(Storage.TheSecretLibrary.HighDry, 4) + return true + end + return false +end + +telescop:uid(1103) +telescop:register() diff --git a/data/scripts/actions/quests/the_shattered_isles/nargor_maps.lua b/data/scripts/actions/quests/the_shattered_isles/nargor_maps.lua new file mode 100644 index 00000000000..ea6e9060fa5 --- /dev/null +++ b/data/scripts/actions/quests/the_shattered_isles/nargor_maps.lua @@ -0,0 +1,40 @@ +local UniqueTable = { + [40001] = { + storage = Storage.TheShatteredIsles.TavernMap1, + message = "You have sucessfully read plan A." + }, + [40002] = { + storage = Storage.TheShatteredIsles.TavernMap2, + message = "You have sucessfully read plan B." + }, + [40003] = { + storage = Storage.TheShatteredIsles.TavernMap3, + message = "You have sucessfully read plan C." + } +} + +local nargorMaps = Action() + +function nargorMaps.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local setting = UniqueTable[item.uid] + if not setting then + return true + end + + if player:getStorageValue(Storage.TheShatteredIsles.RaysMission3) ~= 1 then + return false + end + + if player:getStorageValue(setting.storage) < 0 then + player:setStorageValue(setting.storage, 1) + player:say(setting.message, TALKTYPE_MONSTER_SAY) + return true + end + return false +end + +for index, value in pairs(UniqueTable) do + nargorMaps:uid(index) +end + +nargorMaps:register() diff --git a/data/scripts/actions/quests/the_shattered_isles/tortoise_egg_nargor.lua b/data/scripts/actions/quests/the_shattered_isles/tortoise_egg_nargor.lua new file mode 100644 index 00000000000..51f266d5da1 --- /dev/null +++ b/data/scripts/actions/quests/the_shattered_isles/tortoise_egg_nargor.lua @@ -0,0 +1,28 @@ +local UniqueTable = { + [14024] = { + itemId = 6125, + name = "tortoise egg from Nargor", + count = 1 + } +} + +local tortoiseEggNargor = Action() + +function tortoiseEggNargor.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local setting = UniqueTable[item.uid] + if not setting then + return true + end + + if player:getStorageValue(Storage.TheShatteredIsles.TortoiseEggNargorTime) < os.time() then + player:addItem(setting.name, setting.count, true) + player:setStorageValue(Storage.TheShatteredIsles.TortoiseEggNargorTime, os.time() + 24 * 3600) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You found " ..setting.count.. " " ..setting.name..".") + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The " ..getItemName(setting.itemId).. " is empty.") + end + return true +end + +tortoiseEggNargor:uid(14024) +tortoiseEggNargor:register() diff --git a/data/scripts/actions/quests/the_tainted_soul/star_herb.lua b/data/scripts/actions/quests/the_tainted_soul/star_herb.lua new file mode 100644 index 00000000000..d1f2b81eb47 --- /dev/null +++ b/data/scripts/actions/quests/the_tainted_soul/star_herb.lua @@ -0,0 +1,20 @@ +local config = { + antlers = 11214, + antler_talisman = 24664 +} + +local starHerb = Action() +function starHerb.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + if target.itemid == config.antlers then + item:transform(config.antler_talisman) + item:remove(1) + target:remove(1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You entwine the antler with fresh star herb") + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end + return true +end + +starHerb:id(2800) +starHerb:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_thieves_guild/climbing_vine.lua b/data/scripts/actions/quests/the_thieves_guild/climbing_vine.lua new file mode 100644 index 00000000000..99eba79b7d2 --- /dev/null +++ b/data/scripts/actions/quests/the_thieves_guild/climbing_vine.lua @@ -0,0 +1,23 @@ +local config = { + [12501] = Position(32336, 31813, 6), -- to the room + [12502] = Position(32337, 31815, 7) -- outside the room +} + +local theThievesVine = Action() +function theThievesVine.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local targetPosition = config[item.actionid] + if not targetPosition then + return true + end + if player:isPzLocked() then + player:sendTextMessage(MESSAGE_FAILURE, "You can not enter a protection zone after attacking another player.") + player:getPosition():sendMagicEffect(CONST_ME_POFF) + return true + end + player:teleportTo(targetPosition) + + return true +end + +theThievesVine:aid(12501,12502) +theThievesVine:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_thieves_guild/dwarf_disguise_kit.lua b/data/scripts/actions/quests/the_thieves_guild/dwarf_disguise_kit.lua new file mode 100644 index 00000000000..9914c5ed4c9 --- /dev/null +++ b/data/scripts/actions/quests/the_thieves_guild/dwarf_disguise_kit.lua @@ -0,0 +1,13 @@ +local condition = Condition(CONDITION_OUTFIT) +condition:setTicks(5 * 60 * 1000) -- should be 5 minutes +condition:setOutfit({lookType = 66}) -- dwarf geomancer looktype + +local theThievesKit = Action() +function theThievesKit.onUse(player, item, fromPosition, target, toPosition, isHotkey) + player:addCondition(condition) + item:remove() + return true +end + +theThievesKit:id(8693) +theThievesKit:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_thieves_guild/fish_napping_door.lua b/data/scripts/actions/quests/the_thieves_guild/fish_napping_door.lua new file mode 100644 index 00000000000..44359b40c60 --- /dev/null +++ b/data/scripts/actions/quests/the_thieves_guild/fish_napping_door.lua @@ -0,0 +1,12 @@ +local theThievesDoor = Action() +function theThievesDoor.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + if player:getStorageValue(Storage.ThievesGuild.Mission06) == 3 then + player:say('You slip through the door', TALKTYPE_MONSTER_SAY) + player:teleportTo(Position(32359, 32786, 6)) + end + return true +end + +theThievesDoor:aid(51394) +theThievesDoor:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_thieves_guild/fish_napping_key.lua b/data/scripts/actions/quests/the_thieves_guild/fish_napping_key.lua new file mode 100644 index 00000000000..4d159f02662 --- /dev/null +++ b/data/scripts/actions/quests/the_thieves_guild/fish_napping_key.lua @@ -0,0 +1,17 @@ +-- Theodore Loveless' key + +local theThievesKey = Action() +function theThievesKey.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.ThievesGuild.Mission06) == 2 then + if target.actionid == 51394 and item.itemid == 8762 then + player:removeItem(8762, 1) + player:say('In your haste you break the key while slipping in.', TALKTYPE_MONSTER_SAY) + player:teleportTo(Position(32359, 32788, 6)) + return true + end + end + return false +end + +theThievesKey:id(8762) +theThievesKey:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_thieves_guild/note.lua b/data/scripts/actions/quests/the_thieves_guild/note.lua new file mode 100644 index 00000000000..54d8a2b891b --- /dev/null +++ b/data/scripts/actions/quests/the_thieves_guild/note.lua @@ -0,0 +1,26 @@ +local notePos = Position(32598, 32381, 10) + +local function removeNote(position) + local noteItem = Tile(position):getItemById(8700) + if noteItem then + noteItem:remove() + end +end + +local theThievesNote = Action() +function theThievesNote.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid ~= 12509 then + return false + end + + if player:getStorageValue(Storage.ThievesGuild.Mission08) == 1 then + player:removeItem(8701, 1) + Game.createItem(8700, 1, notePos) + player:setStorageValue(Storage.ThievesGuild.Mission08, 2) + addEvent(removeNote, 5 * 60 * 1000, notePos) + end + return true +end + +theThievesNote:id(8701) +theThievesNote:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/the_travelling_trader/outlaw_camp_door.lua b/data/scripts/actions/quests/the_travelling_trader/outlaw_camp_door.lua new file mode 100644 index 00000000000..ffdb71c6ad8 --- /dev/null +++ b/data/scripts/actions/quests/the_travelling_trader/outlaw_camp_door.lua @@ -0,0 +1,15 @@ +local outlawCamp = Action() +function outlawCamp.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.TravellingTrader.Mission02) == 3 then + if item.itemid == 1223 then + player:teleportTo(toPosition, true) + item:transform(item.itemid + 1) + end + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The door seems to be sealed against unwanted intruders.") + end + return true +end + +outlawCamp:aid(1108) +outlawCamp:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/their_master_voice/slime_gobbler.lua b/data/scripts/actions/quests/their_master_voice/slime_gobbler.lua new file mode 100644 index 00000000000..2e3a6f784c1 --- /dev/null +++ b/data/scripts/actions/quests/their_master_voice/slime_gobbler.lua @@ -0,0 +1,7 @@ +local slimeGobbler = Action() +function slimeGobbler.onUse(player, item, fromPosition, target, toPosition, isHotkey) + return Gobbler_onUse(player, item, fromPosition, target, toPosition, isHotkey) +end + +slimeGobbler:id(13601) +slimeGobbler:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/threatened_dreams/fur_of_a_wolf_whelp.lua b/data/scripts/actions/quests/threatened_dreams/fur_of_a_wolf_whelp.lua new file mode 100644 index 00000000000..05626e0ad35 --- /dev/null +++ b/data/scripts/actions/quests/threatened_dreams/fur_of_a_wolf_whelp.lua @@ -0,0 +1,19 @@ +local furWolf = Action() +function furWolf.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if (player:getStorageValue(Storage.ThreatenedDreams.TroubledMission01) == 9) then + if (target.itemid == 28598)then + target:decay() + item:remove(1) + toPosition:sendMagicEffect(CONST_ME_BLOCKHIT) + player:setStorageValue(Storage.ThreatenedDreams.TroubledMission01, 10) + return true + end + else + player:sendCancelMessage("You are not on that mission.") + end + + return true +end + +furWolf:id(28599) +furWolf:register() diff --git a/data/scripts/actions/quests/threatened_dreams/lever.lua b/data/scripts/actions/quests/threatened_dreams/lever.lua new file mode 100644 index 00000000000..2bdc941bb12 --- /dev/null +++ b/data/scripts/actions/quests/threatened_dreams/lever.lua @@ -0,0 +1,56 @@ +local setting = { + timeToFightAgain = 20, -- In hour + clearRoomTime = 60, -- In hour + centerRoom = {x = 33617, y = 32562, z = 13}, + range = 10, + exitPosition = {x = 33618, y = 32520, z = 15}, + storage = Storage.ThreatenedDreams.FacelessBaneTime, + bossName = "faceless bane", + bossPosition = {x = 33528, y = 32333, z = 12} +} + +local playerPositions = { + {fromPos = {x = 33638, y = 32562, z = 13}, toPos = {x = 33615, y = 32567, z = 13}}, + {fromPos = {x = 33639, y = 32362, z = 13}, toPos = {x = 33616, y = 32567, z = 13}}, + {fromPos = {x = 33640, y = 32362, z = 13}, toPos = {x = 33617, y = 32567, z = 13}}, + {fromPos = {x = 33641, y = 32362, z = 13}, toPos = {x = 33618, y = 32567, z = 13}}, + {fromPos = {x = 33642, y = 32362, z = 13}, toPos = {x = 33619, y = 32567, z = 13}} +} + +local threatenedLever = Action() +function threatenedLever.onUse(player, item, fromPosition, target, toPosition, monster, isHotkey) + if item.itemid == 9825 then + if player:getPosition() ~= Position(33638, 32562, 13) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need 5 players to fight with this boss.") + item:transform(9826) + return true + end + + if roomIsOccupied(setting.centerRoom, setting.range, setting.range) then + player:say("Someone is fighting against the boss! You need wait awhile.", TALKTYPE_MONSTER_SAY) + return true + end + + for i = 1, #playerPositions do + local creature = Tile(playerPositions[i].fromPos):getTopCreature() + if creature then + if creature:getStorageValue(setting.storage) >= os.time() then + creature:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have faced this boss in the last " .. setting.timeToFightAgain .. " hours.") + return true + end + if creature:getStorageValue(setting.storage) < os.time() then + creature:setStorageValue(setting.storage, os.time() + setting.timeToFightAgain * 60 * 60) + creature:teleportTo(playerPositions[i].toPos) + creature:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + end + -- One hour for clean the room + addEvent(clearRoom, setting.clearRoomTime * 60 * 1000, setting.centerRoom, setting.range, setting.range, setting.exitPosition) + Game.createMonster(setting.bossName, setting.bossPosition) + end + return true +end + +threatenedLever:uid(1039) +threatenedLever:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/threatened_dreams/notes_of_a_poacher.lua b/data/scripts/actions/quests/threatened_dreams/notes_of_a_poacher.lua new file mode 100644 index 00000000000..c25a76eb89b --- /dev/null +++ b/data/scripts/actions/quests/threatened_dreams/notes_of_a_poacher.lua @@ -0,0 +1,14 @@ +local notesPoacher = Action() +function notesPoacher.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if (player:getStorageValue(Storage.ThreatenedDreams.TroubledMission01) == 7) then + player:addItem(28603, 1) + player:setStorageValue(Storage.ThreatenedDreams.TroubledMission01, 8) + else + player:sendCancelMessage("You are not on that mission.") + end + + return true +end + +notesPoacher:aid(28600) +notesPoacher:register() diff --git a/data/scripts/actions/quests/threatened_dreams/poacher_chest.lua b/data/scripts/actions/quests/threatened_dreams/poacher_chest.lua new file mode 100644 index 00000000000..7ed9bfa630a --- /dev/null +++ b/data/scripts/actions/quests/threatened_dreams/poacher_chest.lua @@ -0,0 +1,32 @@ +local chests = { + [34123] = {itemid = 28596, count = 1} +} + +local poacherChest = Action() +function poacherChest.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if (player:getStorageValue(Storage.ThreatenedDreams.TroubledMission01) == 1) then + if chests[item.uid] then + if player:getStorageValue(34123) == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'It\'s empty.') + return true + end + + local chest = chests[item.uid] + local itemType = ItemType(chest.itemid) + if itemType then + local article = itemType:getArticle() + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have found ' .. (#article > 0 and article .. ' ' or '') .. itemType:getName() .. '.') + end + + player:addItem(chest.itemid, chest.count) + player:setStorageValue(34123, 1) + player:setStorageValue(Storage.ThreatenedDreams.TroubledMission01, 2) + end + else + player:sendCancelMessage("You are not on this mission.") + end + return true +end + +poacherChest:uid(34123) +poacherChest:register() diff --git a/data/scripts/actions/quests/threatened_dreams/poacher_use.lua b/data/scripts/actions/quests/threatened_dreams/poacher_use.lua new file mode 100644 index 00000000000..d10e46f056e --- /dev/null +++ b/data/scripts/actions/quests/threatened_dreams/poacher_use.lua @@ -0,0 +1,18 @@ +local poacherUse = Action() +function poacherUse.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if (player:getStorageValue(Storage.ThreatenedDreams.TroubledMission01) == 3) then + if (target.itemid == 13805 or target.itemid == 13806)then + target:decay() + item:remove(1) + player:say("You are placing the book on the table, hopefully the poachers will discover it soon.", TALKTYPE_ORANGE_1) + toPosition:sendMagicEffect(CONST_ME_BLOCKHIT) + player:setStorageValue(Storage.ThreatenedDreams.TroubledMission01, 4) + return true + end + else + player:sendCancelMessage("You are not on that mission.") + end +end + +poacherUse:id(28596) +poacherUse:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/tibia_tales/exterminator_flask.lua b/data/scripts/actions/quests/tibia_tales/exterminator_flask.lua new file mode 100644 index 00000000000..fbe9419ec9f --- /dev/null +++ b/data/scripts/actions/quests/tibia_tales/exterminator_flask.lua @@ -0,0 +1,18 @@ +local exterminatorFlask = Action() +function exterminatorFlask.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid ~= 4207 then + return false + end + + if player:getStorageValue(Storage.TibiaTales.TheExterminator) ~= 1 then + return false + end + + player:setStorageValue(Storage.TibiaTales.TheExterminator, 2) + item:transform(2006, 0) + toPosition:sendMagicEffect(CONST_ME_GREEN_RINGS) + return true +end + +exterminatorFlask:id(8205) +exterminatorFlask:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/tibia_tales/ultimate_booze_beer_bottle.lua b/data/scripts/actions/quests/tibia_tales/ultimate_booze_beer_bottle.lua new file mode 100644 index 00000000000..ea72dca9338 --- /dev/null +++ b/data/scripts/actions/quests/tibia_tales/ultimate_booze_beer_bottle.lua @@ -0,0 +1,18 @@ +local ultimateBoozer = Action() +function ultimateBoozer.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid ~= 8176 then + return false + end + + if player:getStorageValue(Storage.TibiaTales.ultimateBoozeQuest) == 1 then + player:setStorageValue(Storage.TibiaTales.ultimateBoozeQuest, 2) + end + player:removeItem(7496, 1) + player:addItem(7495, 1) + player:say("GULP, GULP, GULP", TALKTYPE_MONSTER_SAY, false, 0, toPosition) + toPosition:sendMagicEffect(CONST_ME_SOUND_YELLOW) + return true +end + +ultimateBoozer:id(7496) +ultimateBoozer:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/tinder_box/reward.lua b/data/scripts/actions/quests/tinder_box/reward.lua new file mode 100644 index 00000000000..c18e458d789 --- /dev/null +++ b/data/scripts/actions/quests/tinder_box/reward.lua @@ -0,0 +1,13 @@ +local tinderReward = Action() +function tinderReward.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + if player:getStorageValue(12450) >= os.time() then + return player:sendCancelMessage("The pile of bones is empty.") + end + player:addItem(22728, 1) + player:setStorageValue(12450, os.time() + 20 * 3600) + return player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a tinder box.") +end + +tinderReward:uid(3263) +tinderReward:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/tinder_box/tinder_box.lua b/data/scripts/actions/quests/tinder_box/tinder_box.lua new file mode 100644 index 00000000000..edaf160048d --- /dev/null +++ b/data/scripts/actions/quests/tinder_box/tinder_box.lua @@ -0,0 +1,19 @@ +local config = { + item = 22728, + target = 22727, + reward = 22726, +} +local tinderBox = Action() +function tinderBox.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + if item.itemid == config.item and target.itemid == config.target then + item:remove(1) + target:remove(1) + player:addItem(config.reward, 1) + end + + return true +end + +tinderBox:id(22728) +tinderBox:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/unnatural_selection/mission5_ray_of_light.lua b/data/scripts/actions/quests/unnatural_selection/mission5_ray_of_light.lua new file mode 100644 index 00000000000..b088b125190 --- /dev/null +++ b/data/scripts/actions/quests/unnatural_selection/mission5_ray_of_light.lua @@ -0,0 +1,13 @@ +local unnatural = Action() +function unnatural.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.UnnaturalSelection.Mission05) == 1 then + player:setStorageValue(Storage.UnnaturalSelection.Questline, 11) + player:setStorageValue(Storage.UnnaturalSelection.Mission05, 2) --Questlog, Unnatural Selection Quest "Mission 5: Ray of Light" + player:say("A ray of sunlight comes down from the heaven and hits the crystal. Wow. That probably means Fasuon is supporting.", TALKTYPE_MONSTER_SAY) + toPosition:sendMagicEffect(CONST_ME_HOLYAREA) + end + return true +end + +unnatural:uid(1052) +unnatural:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/what_a_foolish/cat_basket.lua b/data/scripts/actions/quests/what_a_foolish/cat_basket.lua new file mode 100644 index 00000000000..35c996921ea --- /dev/null +++ b/data/scripts/actions/quests/what_a_foolish/cat_basket.lua @@ -0,0 +1,41 @@ +local effectPositions = { + Position(32312, 31745, 9), + Position(32313, 31745, 9), + Position(32314, 31746, 9), + Position(32315, 31746, 9), + Position(32316, 31746, 9), + Position(32317, 31745, 9) +} + +local function removeKitty(monsterId) + local monster = Monster(monsterId) + if monster then + monster:remove() + end +end + +local whatFoolishCat = Action() +function whatFoolishCat.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.WhatAFoolish.Questline) ~= 19 + or player:getStorageValue(Storage.WhatAFoolish.CatBasket) == 1 then + return false + end + + player:setStorageValue(Storage.WhatAFoolish.CatBasket, 1) + player:say('The queen\'s cat is not amused!', TALKTYPE_MONSTER_SAY) + player:getPosition():sendMagicEffect(CONST_ME_DRAWBLOOD) + player:say('Fchhhhh', TALKTYPE_MONSTER_SAY, false, player, effectPositions[1]) + + for i = 1, #effectPositions do + effectPositions[i]:sendMagicEffect(CONST_ME_POFF) + end + + Game.createItem(7487, 1, toPosition) + toPosition:sendMagicEffect(CONST_ME_POFF) + local monster = Game.createMonster('Kitty', Position(toPosition.x, toPosition.y + 1, toPosition.z)) + addEvent(removeKitty, 10000, monster.uid) + return true +end + +whatFoolishCat:id(7486) +whatFoolishCat:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/what_a_foolish/contract.lua b/data/scripts/actions/quests/what_a_foolish/contract.lua new file mode 100644 index 00000000000..c3954161113 --- /dev/null +++ b/data/scripts/actions/quests/what_a_foolish/contract.lua @@ -0,0 +1,19 @@ +local whatFoolishContract = Action() +function whatFoolishContract.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid ~= 7492 then + return false + end + + if player:getStorageValue(Storage.WhatAFoolish.Contract) ~= 1 then + return false + end + + player:say('You sign the contract', TALKTYPE_MONSTER_SAY) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + item:remove() + target:transform(7491) + return true +end + +whatFoolishContract:id(7490) +whatFoolishContract:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/what_a_foolish/crate.lua b/data/scripts/actions/quests/what_a_foolish/crate.lua new file mode 100644 index 00000000000..43cf9b6dbd9 --- /dev/null +++ b/data/scripts/actions/quests/what_a_foolish/crate.lua @@ -0,0 +1,19 @@ +local whatFoolishCrate = Action() +function whatFoolishCrate.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid ~= 7481 then + return false + end + + if player:getStorageValue(Storage.WhatAFoolish.Questline) ~= 8 then + return false + end + + player:getPosition():sendMagicEffect(CONST_ME_SOUND_GREEN) + player:say('Your innocent whistle will fool them all...', TALKTYPE_MONSTER_SAY) + toPosition:sendMagicEffect(CONST_ME_BLOCKHIT) + item:transform(item.itemid + 1) + return true +end + +whatFoolishCrate:id(7482) +whatFoolishCrate:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/what_a_foolish/cushion.lua b/data/scripts/actions/quests/what_a_foolish/cushion.lua new file mode 100644 index 00000000000..c3290359700 --- /dev/null +++ b/data/scripts/actions/quests/what_a_foolish/cushion.lua @@ -0,0 +1,21 @@ +local whatFoolishCushion = Action() +function whatFoolishCushion.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid ~= 4202 then + return false + end + + if player:getStorageValue(Storage.WhatAFoolish.Questline) ~= 17 + or player:getStorageValue(Storage.WhatAFoolish.WhoopeeCushion) == 1 then + return false + end + + player:setStorageValue(Storage.WhatAFoolish.WhoopeeCushion, 1) + player:say('*chuckles maniacally*', TALKTYPE_MONSTER_SAY) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:say('Woooosh!', TALKTYPE_MONSTER_SAY, false, player, toPosition) + item:remove() + return true +end + +whatFoolishCushion:id(7485) +whatFoolishCushion:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/what_a_foolish/disguise.lua b/data/scripts/actions/quests/what_a_foolish/disguise.lua new file mode 100644 index 00000000000..54ade35c63c --- /dev/null +++ b/data/scripts/actions/quests/what_a_foolish/disguise.lua @@ -0,0 +1,13 @@ +local condition = Condition(CONDITION_OUTFIT) +condition:setTicks(10000) +condition:setOutfit({lookType = 65}) + +local whatFoolishDisguise = Action() +function whatFoolishDisguise.onUse(player, item, fromPosition, target, toPosition, isHotkey) + player:addCondition(condition) + player:say('You are now disguised as a mummy for 10 seconds. Hurry up and scare the caliph!', TALKTYPE_MONSTER_SAY) + return true +end + +whatFoolishDisguise:id(7502) +whatFoolishDisguise:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/what_a_foolish/flask.lua b/data/scripts/actions/quests/what_a_foolish/flask.lua new file mode 100644 index 00000000000..5d5d8e1c4be --- /dev/null +++ b/data/scripts/actions/quests/what_a_foolish/flask.lua @@ -0,0 +1,29 @@ +local config = { + [8062] = {text = 'This mission stinks ... and now you do as well!', condition = true, transformId = 7477}, + [6065] = {text = 'You carefully gather the quara ink', transformId = 7489}, + [20514] = {text = 'You carefully gather the stalker blood.', transformId = 7488} +} + +local poisonField = Condition(CONDITION_OUTFIT) +poisonField:setTicks(8000) +poisonField:setOutfit({lookTypeEx = 1496}) + +local whatFoolishFlask = Action() +function whatFoolishFlask.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local targetItem = config[target.itemid] + if not targetItem then + return false + end + + if targetItem.condition then + player:addCondition(poisonField) + end + + player:say(targetItem.text, TALKTYPE_MONSTER_SAY) + player:getPosition():sendMagicEffect(CONST_ME_HITBYPOISON) + item:transform(targetItem.transformId) + return true +end + +whatFoolishFlask:id(7478) +whatFoolishFlask:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/what_a_foolish/watch.lua b/data/scripts/actions/quests/what_a_foolish/watch.lua new file mode 100644 index 00000000000..faa39fa6794 --- /dev/null +++ b/data/scripts/actions/quests/what_a_foolish/watch.lua @@ -0,0 +1,29 @@ +local targetDestination = { + Position(32659, 31853, 13), + Position(32646, 31903, 3) +} + +local whatFoolishWatch = Action() +function whatFoolishWatch.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.WhatAFoolish.Questline) ~= 11 then + return false + end + + local playerPos = player:getPosition() + if not isInArray(targetDestination, playerPos) then + return false + end + + local destination = playerPos == targetDestination[2] and targetDestination[1] or targetDestination[2] + if destination.z == 6 then + item:remove() + end + + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + player:say('You are travelling in time', TALKTYPE_MONSTER_SAY) + return true +end + +whatFoolishWatch:id(8187) +whatFoolishWatch:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/what_a_foolish/worn_cloth.lua b/data/scripts/actions/quests/what_a_foolish/worn_cloth.lua new file mode 100644 index 00000000000..94778ae75db --- /dev/null +++ b/data/scripts/actions/quests/what_a_foolish/worn_cloth.lua @@ -0,0 +1,20 @@ +local whatFoolishWorn = Action() +function whatFoolishWorn.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid ~= 4204 then + return false + end + + if player:getStorageValue(Storage.WhatAFoolish.Questline) ~= 34 + or player:getStorageValue(Storage.WhatAFoolish.OldWornCloth) == 1 then + return false + end + + player:setStorageValue(Storage.WhatAFoolish.OldWornCloth, 1) + player:say('Amazing! That was quite fast!', TALKTYPE_MONSTER_SAY) + toPosition:sendMagicEffect(CONST_ME_BLOCKHIT) + item:transform(7501) + return true +end + +whatFoolishWorn:id(7500) +whatFoolishWorn:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/wrath_of_the_emperor/mission01_crate.lua b/data/scripts/actions/quests/wrath_of_the_emperor/mission01_crate.lua new file mode 100644 index 00000000000..0a54d95d023 --- /dev/null +++ b/data/scripts/actions/quests/wrath_of_the_emperor/mission01_crate.lua @@ -0,0 +1,16 @@ +local condition = Condition(CONDITION_OUTFIT) +condition:setOutfit({lookTypeEx = 12496}) +condition:setTicks(-1) + +local wrathEmperorMiss1Crate = Action() +function wrathEmperorMiss1Crate.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.WrathoftheEmperor.CrateStatus) ~= 1 and player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 2 then + player:addCondition(condition) + player:setStorageValue(Storage.WrathoftheEmperor.CrateStatus, 1) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + end + return true +end + +wrathEmperorMiss1Crate:id(12284) +wrathEmperorMiss1Crate:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/wrath_of_the_emperor/mission01_lights.lua b/data/scripts/actions/quests/wrath_of_the_emperor/mission01_lights.lua new file mode 100644 index 00000000000..7e52d709878 --- /dev/null +++ b/data/scripts/actions/quests/wrath_of_the_emperor/mission01_lights.lua @@ -0,0 +1,58 @@ +local function transformLamp(position, itemId, transformId) + local lampItem = Tile(position):getItemById(itemId) + if lampItem then + lampItem:transform(transformId) + end +end + +local wrathEmperorMiss1Light = Action() +function wrathEmperorMiss1Light.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if(item.uid == 3171) then + if Game.getStorageValue(GlobalStorage.WrathOfTheEmperor.Light01) ~= 1 then + Game.setStorageValue(GlobalStorage.WrathOfTheEmperor.Light01, 1) + addEvent(Game.setStorageValue, 20 * 1000, GlobalStorage.WrathOfTheEmperor.Light01, 0) + local pos = { + Position(33369, 31075, 8), + Position(33372, 31075, 8) + } + for i = 1, #pos do + transformLamp(pos[i], 11447, 11446) + addEvent(transformLamp, 20 * 1000, pos[i], 11446, 11447) + end + end + elseif(item.uid == 3172) then + if Game.getStorageValue(GlobalStorage.WrathOfTheEmperor.Light02) ~= 1 then + Game.setStorageValue(GlobalStorage.WrathOfTheEmperor.Light02, 1) + addEvent(Game.setStorageValue, 20 * 1000, GlobalStorage.WrathOfTheEmperor.Light02, 0) + local pos = Position(33360, 31079, 8) + transformLamp(pos, 11449, 11463) + addEvent(transformLamp, 20 * 1000, pos, 11463, 11449) + end + elseif(item.uid == 3173) then + if Game.getStorageValue(GlobalStorage.WrathOfTheEmperor.Light03) ~= 1 then + Game.setStorageValue(GlobalStorage.WrathOfTheEmperor.Light03, 1) + addEvent(Game.setStorageValue, 20 * 1000, GlobalStorage.WrathOfTheEmperor.Light03, 0) + local pos = Position(33346, 31074, 8) + transformLamp(pos, 11449, 11463) + addEvent(transformLamp, 20 * 1000, pos, 11463, 11449) + end + elseif(item.uid == 3174) then + if Game.getStorageValue(GlobalStorage.WrathOfTheEmperor.Light04) ~= 1 then + Game.setStorageValue(GlobalStorage.WrathOfTheEmperor.Light04, 1) + addEvent(Game.setStorageValue, 20 * 1000, GlobalStorage.WrathOfTheEmperor.Light04, 0) + local wallItem, pos + for i = 1, 4 do + pos = Position(33355, 31067 + i, 9) + wallItem = Tile(pos):getItemById(9264) + if wallItem then + wallItem:remove() + addEvent(Game.createItem, 20 * 1000, 9264, 1, pos) + end + end + end + end + return true +end + +wrathEmperorMiss1Light:uid(3171,3172,3173,3174) +wrathEmperorMiss1Light:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/wrath_of_the_emperor/mission02_firstcontact_repair_teleport.lua b/data/scripts/actions/quests/wrath_of_the_emperor/mission02_firstcontact_repair_teleport.lua new file mode 100644 index 00000000000..fafe553e5a0 --- /dev/null +++ b/data/scripts/actions/quests/wrath_of_the_emperor/mission02_firstcontact_repair_teleport.lua @@ -0,0 +1,58 @@ +local waterpos = { + Position({x = 33282, y = 31036, z = 10}), + Position({x = 33282, y = 31037, z = 10}), + Position({x = 33283, y = 31037, z = 10}), + Position({x = 33283, y = 31036, z = 10}), + Position({x = 33283, y = 31038, z = 10}), + Position({x = 33283, y = 31035, z = 10}) +} + +local function revertWater(position) + local waterTile = Tile(position):getItemById(11030) + if waterTile then + waterTile:transform(11450) + end +end + +local wrathEmperorMiss2FirstContact = Action() +function wrathEmperorMiss2FirstContact.onUse(player, item, fromPosition, target, toPosition, isHotkey) + -- clay with the sacred earth + if (item.itemid == 12285 and target.itemid == 12297) or (item.itemid == 12297 and target.itemid == 12285) then + player:say("You carefully mix the clay with the sacred earth.", TALKTYPE_MONSTER_SAY) + item:remove() + target:remove() + player:addItem(12300, 1) + -- sacred clay + elseif item.itemid == 12300 and target.itemid == 12287 then + player:say("You carefully coat the inside of the wooden bowl with the sacred clay.", TALKTYPE_MONSTER_SAY) + target:remove() + item:transform(12303) + -- sacred bowl of purification + elseif item.itemid == 12303 and target.itemid == 11450 then + player:say("Filling the corrupted water into the sacred bowl completly purifies the fluid.", TALKTYPE_MONSTER_SAY) + item:transform(12289) + -- bowl with sacred water + elseif item.itemid == 12289 and target.itemid == 12301 then + item:transform(12290) + toPosition:sendMagicEffect(CONST_ME_POFF) + -- sacred coal + elseif item.itemid == 12290 and target.actionid == 8025 then + player:say("As you give the coal into the pool the corrupted fluid begins to dissolve, leaving purified, refreshing water.", TALKTYPE_MONSTER_SAY) + item:remove() + if player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 4 then + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 5) + player:setStorageValue(Storage.WrathoftheEmperor.Mission02, 2) --Questlog, Wrath of the Emperor "Mission 02: First Contact" + end + for i = 1, 4 do + waterpos[i]:sendMagicEffect(CONST_ME_GREEN_RINGS) + end + for i = 1, 6 do + Tile(waterpos[i]):getItemById(11450):transform(11030) + addEvent(revertWater, 60 * 1000, waterpos[i]) + end + end + return true +end + +wrathEmperorMiss2FirstContact:id(12285,12289,12290,12297,12300,12303) +wrathEmperorMiss2FirstContact:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/wrath_of_the_emperor/mission03_the_keeper.lua b/data/scripts/actions/quests/wrath_of_the_emperor/mission03_the_keeper.lua new file mode 100644 index 00000000000..4a2cbb703df --- /dev/null +++ b/data/scripts/actions/quests/wrath_of_the_emperor/mission03_the_keeper.lua @@ -0,0 +1,29 @@ +local function revertKeeperstorage() + Game.setStorageValue(Storage.WrathoftheEmperor.Mission03, 0) +end + +local wrathEmperorMiss3Keeper = Action() +function wrathEmperorMiss3Keeper.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 12320 and target.actionid == 8026 then + if Game.getStorageValue(Storage.WrathoftheEmperor.Mission03) < 5 then + Game.setStorageValue(Storage.WrathoftheEmperor.Mission03, math.max(0, Game.getStorageValue(Storage.WrathoftheEmperor.Mission03)) + 1) + player:say("The plant twines and twiggles even more than before, it almost looks as it would scream great pain.", TALKTYPE_MONSTER_SAY) + elseif Game.getStorageValue(Storage.WrathoftheEmperor.Mission03) == 5 then + Game.setStorageValue(Storage.WrathoftheEmperor.Mission03, 6) + toPosition:sendMagicEffect(CONST_ME_YELLOW_RINGS) + Game.createMonster('the keeper', {x = 33171, y = 31058, z = 11}) + Position({x = 33171, y = 31058, z = 11}):sendMagicEffect(CONST_ME_TELEPORT) + addEvent(revertKeeperstorage, 60 * 1000) + end + elseif item.itemid == 12316 then + if player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 7 then + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 8) + player:setStorageValue(Storage.WrathoftheEmperor.Mission03, 2) --Questlog, Wrath of the Emperor "Mission 03: The Keeper" + player:addItem(12323, 1) + end + end + return true +end + +wrathEmperorMiss3Keeper:id(12316,12320) +wrathEmperorMiss3Keeper:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/wrath_of_the_emperor/mission04_sacrament_of_the_snake_sceptre.lua b/data/scripts/actions/quests/wrath_of_the_emperor/mission04_sacrament_of_the_snake_sceptre.lua new file mode 100644 index 00000000000..5d5b29b75e2 --- /dev/null +++ b/data/scripts/actions/quests/wrath_of_the_emperor/mission04_sacrament_of_the_snake_sceptre.lua @@ -0,0 +1,17 @@ +local wrathEmperorMiss4Sacrament = Action() +function wrathEmperorMiss4Sacrament.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getItemCount(12324) >= 1 and player:getItemCount(12325) >= 1 and player:getItemCount(12326) >= 1 and player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 10 then + player:removeItem(12324, 1) + player:removeItem(12325, 1) + player:removeItem(12326, 1) + player:addItem(12327, 1) + player:getPosition():sendMagicEffect(CONST_ME_HOLYAREA) + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 11) + player:setStorageValue(Storage.WrathoftheEmperor.Mission04, 2) --Questlog, Wrath of the Emperor "Mission 04: Sacrament of the Snake" + end + item:transform(item.itemid == 1945 and 1946 or 1945) + return true +end + +wrathEmperorMiss4Sacrament:uid(1053) +wrathEmperorMiss4Sacrament:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/wrath_of_the_emperor/mission08_uninvited_guests_lever.lua b/data/scripts/actions/quests/wrath_of_the_emperor/mission08_uninvited_guests_lever.lua new file mode 100644 index 00000000000..73bcb577b60 --- /dev/null +++ b/data/scripts/actions/quests/wrath_of_the_emperor/mission08_uninvited_guests_lever.lua @@ -0,0 +1,32 @@ +local config = { + [3184] = Position(33082, 31110, 2), + [3185] = Position(33078, 31080, 13) +} + +local wrathEmperorMiss8Uninvited = Action() +function wrathEmperorMiss8Uninvited.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local targetPosition = config[item.uid] + if not targetPosition then + return true + end + + item:transform(item.itemid == 1945 and 1946 or 1945) + + toPosition.y = toPosition.y + 1 + local creature = Tile(toPosition):getTopCreature() + if not creature or not creature:isPlayer() then + return true + end + + if item.itemid ~= 1945 then + return true + end + + creature:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + creature:teleportTo(targetPosition) + targetPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +wrathEmperorMiss8Uninvited:uid(3184,3185) +wrathEmperorMiss8Uninvited:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/wrath_of_the_emperor/mission09_the_sleeping_dragon_mixture.lua b/data/scripts/actions/quests/wrath_of_the_emperor/mission09_the_sleeping_dragon_mixture.lua new file mode 100644 index 00000000000..40e3f5fb498 --- /dev/null +++ b/data/scripts/actions/quests/wrath_of_the_emperor/mission09_the_sleeping_dragon_mixture.lua @@ -0,0 +1,15 @@ +local wrathEmperorMiss9Sleeping = Action() +function wrathEmperorMiss9Sleeping.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.WrathoftheEmperor.InterdimensionalPotion) == 1 then + return true + end + + player:setStorageValue(Storage.WrathoftheEmperor.InterdimensionalPotion, 1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + + item:remove() + return true +end + +wrathEmperorMiss9Sleeping:id(12328) +wrathEmperorMiss9Sleeping:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/wrath_of_the_emperor/mission10_a_message_of_freedom_sceptre.lua b/data/scripts/actions/quests/wrath_of_the_emperor/mission10_a_message_of_freedom_sceptre.lua new file mode 100644 index 00000000000..aa09223ffb3 --- /dev/null +++ b/data/scripts/actions/quests/wrath_of_the_emperor/mission10_a_message_of_freedom_sceptre.lua @@ -0,0 +1,60 @@ +local boss = { + [3193] = "fury of the emperor", + [3194] = "wrath of the emperor", + [3195] = "scorn of the emperor", + [3196] = "spite of the emperor", +} + +local wrathEmperorMiss10Message = Action() +function wrathEmperorMiss10Message.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if boss[target.uid] and target.itemid == 12383 then + target:transform(11753) + Game.createMonster(boss[target.uid], {x = toPosition.x + 4, y = toPosition.y, z = toPosition.z}) + Game.setStorageValue(target.uid - 4, 1) + elseif target.itemid == 12317 then + if toPosition.x > 33034 and toPosition.x < 33071 and + toPosition.y > 31079 and toPosition.y < 31102 then + if player:getStorageValue(Storage.WrathoftheEmperor.BossStatus) == 1 then + player:setStorageValue(Storage.WrathoftheEmperor.BossStatus, 2) + player:setStorageValue(Storage.WrathoftheEmperor.Mission10, 3) --Questlog, Wrath of the Emperor "Mission 10: A Message of Freedom" + player:say("The sceptre is almost torn from your hand as you banish the presence of the emperor.", TALKTYPE_MONSTER_SAY) + end + elseif toPosition.x > 33080 and toPosition.x < 33111 and + toPosition.y > 31079 and toPosition.y < 31100 then + if player:getStorageValue(Storage.WrathoftheEmperor.BossStatus) == 2 then + player:setStorageValue(Storage.WrathoftheEmperor.BossStatus, 3) + player:setStorageValue(Storage.WrathoftheEmperor.Mission10, 4) --Questlog, Wrath of the Emperor "Mission 10: A Message of Freedom" + player:say("The sceptre is almost torn from your hand as you banish the presence of the emperor.", TALKTYPE_MONSTER_SAY) + end + elseif toPosition.x > 33078 and toPosition.x < 33112 and + toPosition.y > 31106 and toPosition.y < 31127 then + if player:getStorageValue(Storage.WrathoftheEmperor.BossStatus) == 3 then + player:setStorageValue(Storage.WrathoftheEmperor.BossStatus, 4) + player:setStorageValue(Storage.WrathoftheEmperor.Mission10, 5) --Questlog, Wrath of the Emperor "Mission 10: A Message of Freedom" + player:say("The sceptre is almost torn from your hand as you banish the presence of the emperor.", TALKTYPE_MONSTER_SAY) + end + elseif toPosition.x > 33035 and toPosition.x < 33069 and + toPosition.y > 31107 and toPosition.y < 31127 then + if player:getStorageValue(Storage.WrathoftheEmperor.BossStatus) == 4 then + player:setStorageValue(Storage.WrathoftheEmperor.BossStatus, 5) + player:setStorageValue(Storage.WrathoftheEmperor.Mission10, 6) --Questlog, Wrath of the Emperor "Mission 10: A Message of Freedom" + player:say("The sceptre is almost torn from your hand as you banish the presence of the emperor.", TALKTYPE_MONSTER_SAY) + local destination = Position(33072, 31151, 15) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + end + end + elseif target.itemid == 12385 then + if player:getStorageValue(Storage.WrathoftheEmperor.Questline) == 31 then + player:setStorageValue(Storage.WrathoftheEmperor.Questline, 32) + player:setStorageValue(Storage.WrathoftheEmperor.Mission11, 2) --Questlog, Wrath of the Emperor "Mission 11: Payback Time" + end + player:say("NOOOoooooooo...!", TALKTYPE_MONSTER_SAY, false, player, toPosition) + player:say("This should have dealt the deathblow to the snake things' ambitions.", TALKTYPE_MONSTER_SAY) + end + return true +end + +wrathEmperorMiss10Message:id(12318) +wrathEmperorMiss10Message:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/wrath_of_the_emperor/mission11_payback_time_lever.lua b/data/scripts/actions/quests/wrath_of_the_emperor/mission11_payback_time_lever.lua new file mode 100644 index 00000000000..fe25a5dfe93 --- /dev/null +++ b/data/scripts/actions/quests/wrath_of_the_emperor/mission11_payback_time_lever.lua @@ -0,0 +1,54 @@ +local config = { + firstboss = "snake god essence", + bossPosition = Position(33365, 31407, 10), + + trap = "plaguethrower", + trapPositions = { + Position(33355, 31403, 10), + Position(33364, 31403, 10), + Position(33355, 31410, 10), + Position(33364, 31410, 10) + }, + startAreaPosition = Position(33357, 31404, 9), + arenaPosition = Position(33359, 31406, 10) +} + +local wrathEmperorMiss11Payback = Action() +function wrathEmperorMiss11Payback.onUse(player, item, fromPosition, target, toPosition, isHotkey) + + if Game.getStorageValue(Storage.WrathoftheEmperor.Mission11) == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The arena is already in use.') + return true + end + + Game.setStorageValue(Storage.WrathoftheEmperor.Mission11, 1) + addEvent(Game.setStorageValue, 10 * 60000, Storage.WrathoftheEmperor.Mission11, 0) + + local monsters = Game.getSpectators(config.arenaPosition, false, false, 10, 10, 10, 10) + local spectator + for i = 1, #monsters do + spectator = monsters[i] + if spectator:isMonster() then + spectator:remove() + end + end + + local spectators = Game.getSpectators(config.startAreaPosition, false, true, 0, 5, 0, 5) + for i = 1, #spectators do + spectator = spectators[i] + spectator:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + spectator:teleportTo(config.arenaPosition) + config.arenaPosition:sendMagicEffect(CONST_ME_TELEPORT) + end + + for i = 1, #config.trapPositions do + Game.createMonster(config.trap, config.trapPositions[i]) + end + + Game.createMonster(config.firstboss, config.bossPosition) + item:transform(item.itemid == 1945 and 1946 or 1945) + return true +end + +wrathEmperorMiss11Payback:uid(3198) +wrathEmperorMiss11Payback:register() \ No newline at end of file diff --git a/data/scripts/actions/quests/wrath_of_the_emperor/mission12_just_rewards.lua b/data/scripts/actions/quests/wrath_of_the_emperor/mission12_just_rewards.lua new file mode 100644 index 00000000000..75a11d66265 --- /dev/null +++ b/data/scripts/actions/quests/wrath_of_the_emperor/mission12_just_rewards.lua @@ -0,0 +1,21 @@ +local wrathEmperorMiss12Just = Action() +function wrathEmperorMiss12Just.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.WrathoftheEmperor.Mission12) == 0 then + player:addOutfit(366, 0) + player:addOutfit(367, 0) + player:addOutfit(366, 1) + player:addOutfit(367, 1) + player:addOutfit(366, 2) + player:addOutfit(367, 2) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found some clothes in wardrobe") + player:setStorageValue(Storage.WrathoftheEmperor.Mission12, 1) --Questlog, Wrath of the Emperor "Mission 12: Just Rewards" + player:setStorageValue(1150, 1) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The wardrobe is empty.") + player:setStorageValue(1150, 1) + end + return true +end + +wrathEmperorMiss12Just:uid(3200) +wrathEmperorMiss12Just:register() \ No newline at end of file diff --git a/data/scripts/actions/rookgaard/banana_quest.lua b/data/scripts/actions/rookgaard/banana_quest.lua new file mode 100644 index 00000000000..8fd658d64de --- /dev/null +++ b/data/scripts/actions/rookgaard/banana_quest.lua @@ -0,0 +1,15 @@ +local bananaQuest = Action() + +function bananaQuest.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.QuestChests.BananaPalm) == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The banana palm is empty.') + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have found a banana.') + player:addItem(2676, 1) + player:setStorageValue(Storage.QuestChests.BananaPalm, 1) + end + return true +end + +bananaQuest:aid(5641) +bananaQuest:register() diff --git a/data/scripts/actions/rookgaard/bearroom_quest_lever.lua b/data/scripts/actions/rookgaard/bearroom_quest_lever.lua new file mode 100644 index 00000000000..1bd588cf423 --- /dev/null +++ b/data/scripts/actions/rookgaard/bearroom_quest_lever.lua @@ -0,0 +1,22 @@ +local stonePosition = Position(32145, 32101, 11) +local relocatePosition = Position(32145, 32102, 11) + +local bearRoomQuestLever = Action() + +function bearRoomQuestLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 1945 then + local stoneItem = Tile(stonePosition):getItemById(1304) + if stoneItem then + stoneItem:remove() + item:transform(1946) + end + else + Tile(stonePosition):relocateTo(relocatePosition) + Game.createItem(1304, 1, stonePosition) + item:transform(1945) + end + return true +end + +bearRoomQuestLever:uid(1056) +bearRoomQuestLever:register() diff --git a/data/scripts/actions/rookgaard/chest.lua b/data/scripts/actions/rookgaard/chest.lua new file mode 100644 index 00000000000..79960b8dcce --- /dev/null +++ b/data/scripts/actions/rookgaard/chest.lua @@ -0,0 +1,16 @@ +local chest = Action() + +function chest.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if (player:getStorageValue(405492) == 1) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The chest is empty.") + return true + end + + player:addItem(13829, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You found a wooden sword.") + player:setStorageValue(405492, 1) + return true +end + +chest:aid(30492) +chest:register() diff --git a/data/scripts/actions/rookgaard/doublet_quest.lua b/data/scripts/actions/rookgaard/doublet_quest.lua new file mode 100644 index 00000000000..0437d30182d --- /dev/null +++ b/data/scripts/actions/rookgaard/doublet_quest.lua @@ -0,0 +1,15 @@ +local doubletQuest = Action() + +function doubletQuest.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.QuestChests.DoubletQuest) == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The loose board is empty.') + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have found a doublet.') + player:addItem(2485, 1) + player:setStorageValue(Storage.QuestChests.DoubletQuest, 1) + end + return true +end + +doubletQuest:aid(5639) +doubletQuest:register() diff --git a/data/scripts/actions/rookgaard/honey_flower_quest.lua b/data/scripts/actions/rookgaard/honey_flower_quest.lua new file mode 100644 index 00000000000..0cb7671e9f7 --- /dev/null +++ b/data/scripts/actions/rookgaard/honey_flower_quest.lua @@ -0,0 +1,15 @@ +local honeyFlowerQuest = Action() + +function honeyFlowerQuest.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.QuestChests.HoneyFlower) == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'The honeyflower patch is empty.') + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have found a honey flower.') + player:addItem(2103, 1) + player:setStorageValue(Storage.QuestChests.HoneyFlower, 1) + end + return true +end + +honeyFlowerQuest:aid(5640) +honeyFlowerQuest:register() diff --git a/data/scripts/actions/rookgaard/katana_quest_door.lua b/data/scripts/actions/rookgaard/katana_quest_door.lua new file mode 100644 index 00000000000..f620a1733e8 --- /dev/null +++ b/data/scripts/actions/rookgaard/katana_quest_door.lua @@ -0,0 +1,8 @@ +local katanaQuestDoor = Action() + +function katanaQuestDoor.onUse(player, item, fromPosition, target, toPosition, isHotkey) + return false +end + +katanaQuestDoor:uid(1055) +katanaQuestDoor:register() diff --git a/data/scripts/actions/rookgaard/katana_quest_lever.lua b/data/scripts/actions/rookgaard/katana_quest_lever.lua new file mode 100644 index 00000000000..408f5afbb43 --- /dev/null +++ b/data/scripts/actions/rookgaard/katana_quest_lever.lua @@ -0,0 +1,28 @@ +local doorPosition = Position(32177, 32148, 11) +local relocatePosition = Position(32178, 32148, 11) + +local katanaQuestLever = Action() + +function katanaQuestLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 1945 then + local doorItem = Tile(doorPosition):getItemById(5108) + if doorItem then + doorItem:transform(5109) + doorItem:setAttribute(ITEM_ATTRIBUTE_UNIQUEID, 1055) + item:transform(1946) + end + else + local tile = Tile(doorPosition) + local doorItem = tile:getItemById(5109) + if doorItem then + tile:relocateTo(relocatePosition, true) + doorItem:transform(5108) + doorItem:setAttribute(ITEM_ATTRIBUTE_UNIQUEID, 1055) + item:transform(1945) + end + end + return true +end + +katanaQuestLever:uid(1054) +katanaQuestLever:register() diff --git a/data/scripts/actions/rookgaard/sewer_lever.lua b/data/scripts/actions/rookgaard/sewer_lever.lua new file mode 100644 index 00000000000..82561b94b64 --- /dev/null +++ b/data/scripts/actions/rookgaard/sewer_lever.lua @@ -0,0 +1,88 @@ +local config = { + bridgePositions = { + {position = Position(32099, 32205, 8), groundId = 9022, itemId = 4645}, + {position = Position(32100, 32205, 8), groundId = 4616}, + {position = Position(32101, 32205, 8), groundId = 9022, itemId = 4647} + }, + leverPositions = { + Position(32098, 32204, 8), + Position(32104, 32204, 8) + }, + relocatePosition = Position(32102, 32205, 8), + relocateMonsterPosition = Position(32103, 32205, 8), + bridgeId = 5770 +} + +function moveToPosition(self, toPosition, pushMove, monsterPosition) + if self:getPosition() == toPosition then + return false + end + + if not Tile(toPosition) then + return false + end + + for i = self:getThingCount() - 1, 0, -1 do + local thing = self:getThing(i) + if thing then + if thing:isItem() then + if thing:getId() ~= config.bridgeId then + thing:moveTo(toPosition) + end + elseif thing:isCreature() then + if monsterPosition and thing:isMonster() then + thing:teleportTo(monsterPosition, pushMove) + else + thing:teleportTo(toPosition, pushMove) + end + end + end + end + return true +end + +local sewerLever = Action() + +function sewerLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local leverLeft, lever = item.itemid == 1945 + for i = 1, #config.leverPositions do + lever = Tile(config.leverPositions[i]):getItemById(leverLeft and 1945 or 1946) + if lever then + lever:transform(leverLeft and 1946 or 1945) + end + end + + local tile, tmpItem, bridge + if leverLeft then + for i = 1, #config.bridgePositions do + bridge = config.bridgePositions[i] + tile = Tile(bridge.position) + + tmpItem = tile:getGround() + if tmpItem then + tmpItem:transform(config.bridgeId) + end + + if bridge.itemId then + tmpItem = tile:getItemById(bridge.itemId) + if tmpItem then + tmpItem:remove() + end + end + end + else + for i = 1, #config.bridgePositions do + bridge = config.bridgePositions[i] + tile = Tile(bridge.position) + + moveToPosition(tile, config.relocatePosition, true, config.relocateMonsterPosition) + tile:getGround():transform(bridge.groundId) + Game.createItem(bridge.itemId, 1, bridge.position) + end + + end + return true +end + +sewerLever:aid(50239) +sewerLever:register() diff --git a/data/scripts/actions/roshamuul/prison/golden.lua b/data/scripts/actions/roshamuul/prison/golden.lua new file mode 100644 index 00000000000..6825cd74d5d --- /dev/null +++ b/data/scripts/actions/roshamuul/prison/golden.lua @@ -0,0 +1,67 @@ +local setting = { + timeToFightAgain = 20, + clearRoomTime = 60, -- In hour + centerRoom = {x = 33528, y = 32334, z = 12}, + range = 10, + storage = Storage.PrinceDrazzakTime, + clearRoomStorage = GlobalStorage.PrinceDrazzakEventTime, + bossName = "prince drazzak", + bossPosition = {x = 33528, y = 32333, z = 12} +} + +local playerPositions = { + {fromPos = {x = 33607, y = 32362, z = 11}, toPos = {x = 33526, y = 32341, z = 12}}, + {fromPos = {x = 33608, y = 32362, z = 11}, toPos = {x = 33527, y = 32341, z = 12}}, + {fromPos = {x = 33609, y = 32362, z = 11}, toPos = {x = 33528, y = 32341, z = 12}}, + {fromPos = {x = 33610, y = 32362, z = 11}, toPos = {x = 33529, y = 32341, z = 12}}, + {fromPos = {x = 33611, y = 32362, z = 11}, toPos = {x = 33530, y = 32341, z = 12}} +} + +local golden = Action() + +function golden.onUse(player, item, fromPosition, target, toPosition, monster, isHotkey) + if toPosition == Position(33606, 32362, 11) then + for i = 1, #playerPositions do + local creature = Tile(playerPositions[i].fromPos):getTopCreature() + if not creature then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need 5 players to fight with this boss.") + return true + end + end + end + + if toPosition == Position(33606, 32362, 11) then + if roomIsOccupied(setting.centerRoom, setting.range, setting.range) + or Game.getStorageValue(setting.clearRoomStorage) == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Someone is fighting against the boss! You need wait awhile.") + return true + end + + for i = 1, #playerPositions do + local creature = Tile(playerPositions[i].fromPos):getTopCreature() + if creature and creature:isPlayer() then + if creature:getStorageValue(setting.storage) >= os.time() then + creature:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have faced this boss in the last " .. setting.timeToFightAgain .. " hours.") + return true + end + if creature:getStorageValue(setting.storage) < os.time() then + creature:setStorageValue(setting.storage, os.time() + setting.timeToFightAgain * 60 * 60) + creature:teleportTo(playerPositions[i].toPos) + creature:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + else + return false + end + end + item:remove() + -- One hour for clean the room and other time goto again + addEvent(clearRoom, setting.clearRoomTime * 60 * 1000, setting.centerRoom, + setting.range, setting.range, setting.clearRoomStorage) + Game.createMonster(setting.bossName, setting.bossPosition) + Game.setStorageValue(setting.clearRoomStorage, 1) + end + return true +end + +golden:id(22607) +golden:register() diff --git a/data/scripts/actions/roshamuul/prison/keys.lua b/data/scripts/actions/roshamuul/prison/keys.lua new file mode 100644 index 00000000000..0eb05f88e16 --- /dev/null +++ b/data/scripts/actions/roshamuul/prison/keys.lua @@ -0,0 +1,106 @@ +-------------THIS SCRIPT WAS MADED BY VANKK AT 15TH DECEMBER 2016 AT 4 P.M (GMT - 3) ------------- + +local config = { + [22606] = { + targetId = 22636, -- Target ID. + bossName = 'Zavarash', -- boss name + keyPlayerPosition = Position(33608, 32394, 11), -- Where the player should be. + newPosition = Position(33567, 32422, 12), -- Position to teleport + bossPosition = Position(33565, 32418, 12), -- Boss Position + centerPosition = Position(33567, 32422, 12), -- Center Room + exitPosition = Position(33611, 32377, 11), -- Exit Position + rangeX = 20, -- Range in X + rangeY = 20, -- Range in Y + time = 15, -- time in minutes to remove the player + }, + [22605] = { + targetId = 22634, -- Target ID. + bossName = 'Horadron', -- boss name + keyPlayerPosition = Position(33603, 32394, 11), -- Where the player should be. + newPosition = Position(33607, 32421, 12), -- Position to teleport + bossPosition = Position(33606, 32417, 12), -- Boss Position + centerPosition = Position(33607, 32421, 12), -- Center Room + exitPosition = Position(33611, 32377, 11), -- Exit Position + rangeX = 20, + rangeY = 20, + time = 15, -- time in minutes to remove the player + }, + [22604] = { + targetId = 22638, -- Target ID. + bossName = 'Terofar', -- boss name + keyPlayerPosition = Position(33614, 32394, 11), -- Where the player should be. + newPosition = Position(33526, 32421, 12), -- Position to teleport + bossPosition = Position(33524, 32418, 12), -- Boss Position + centerPosition = Position(33526, 32421, 12), -- Center Room + exitPosition = Position(33611, 32377, 11), -- Exit Position + rangeX = 20, + rangeY = 20, + time = 15, -- time in minutes to remove the player + } +} + +local function roomIsOccupied(centerPosition, rangeX, rangeY) + local spectators = Game.getSpectators(centerPosition, false, false, rangeX, rangeX, rangeY, rangeY) + if #spectators ~= 0 then + return true + end + + return false +end + +function clearBossRoom(playerId, centerPosition, rangeX, rangeY, exitPosition) + local spectators, spectator = Game.getSpectators(centerPosition, false, false, rangeX, rangeX, rangeY, rangeY) + for i = 1, #spectators do + spectator = spectators[i] + if spectator:isPlayer() and spectator.uid == playerId then + spectator:teleportTo(exitPosition) + exitPosition:sendMagicEffect(CONST_ME_TELEPORT) + end + + if spectator:isMonster() then + spectator:remove() + end + end +end + +local keys = Action() + +function keys.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local tmpConfig = config[item.itemid] + if not tmpConfig then + return true + end + + if target.itemid ~= tmpConfig.targetId then + return true + end + + local creature = Tile(tmpConfig.keyPlayerPosition):getTopCreature() + if not creature or not creature:isPlayer() then + return true + end + + if roomIsOccupied(tmpConfig.centerPosition, tmpConfig.rangeX, tmpConfig.rangeY) then + player:sendCancelMessage("There is someone in the room.") + return true + end + + local monster = Game.createMonster(tmpConfig.bossName, tmpConfig.bossPosition) + if not monster then + return true + end + + -- Send message + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have entered an ancient demon prison cell!') + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have fifteen minutes to kill and loot this boss, else you will lose that chance.') + + -- Let's roll + addEvent(clearBossRoom, 60 * tmpConfig.time * 1000, player:getId(), tmpConfig.centerPosition, tmpConfig.rangeX, tmpConfig.rangeY, tmpConfig.exitPosition) + item:remove() + player:teleportTo(tmpConfig.newPosition) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +keys:id(22604, 22605, 22606) +keys:register() diff --git a/data/scripts/actions/shrines/feyrist_exit.lua b/data/scripts/actions/shrines/feyrist_exit.lua new file mode 100644 index 00000000000..a99c5e57174 --- /dev/null +++ b/data/scripts/actions/shrines/feyrist_exit.lua @@ -0,0 +1,21 @@ +local backPositions = { + { actionId = 24999, toPos = Position(32972, 32227, 7), effect = CONST_ME_SMALLPLANTS }, + { actionId = 25000, toPos = Position(32192, 31419, 2), effect = CONST_ME_ICEATTACK }, + { actionId = 25001, toPos = Position(33059, 32716, 5), effect = CONST_ME_ENERGYHIT }, + { actionId = 25002, toPos = Position(32911, 32336, 15), effect = CONST_ME_MAGIC_RED } +} + +local feyristExit = Action() + +function feyristExit.onUse(player, item, fromPosition, target, toPosition, isHotkey) + for _, feyrist in pairs(backPositions) do + if item.actionid == feyrist.actionId then + player:teleportTo(feyrist.toPos) + player:getPosition():sendMagicEffect(feyrist.effect) + return true + end + end +end + +feyristExit:aid(24999, 25000, 25001, 25002) +feyristExit:register() diff --git a/data/scripts/actions/spellbook.lua b/data/scripts/actions/spellbook.lua new file mode 100644 index 00000000000..89fb2e02ffd --- /dev/null +++ b/data/scripts/actions/spellbook.lua @@ -0,0 +1,56 @@ +local spellbook = Action() + +function spellbook.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local text = "" + local tlvl = {} + local tml = {} + + for _, spell in ipairs(player:getInstantSpells()) do + if spell.level ~= 0 or spell.mlevel ~= 0 then + if spell.manapercent > 0 then + spell.mana = spell.manapercent .. "%" + end + if spell.level > 0 then + tlvl[#tlvl+1] = spell + elseif spell.mlevel > 0 then + tml[#tml+1] = spell + end + end + end + + table.sort(tlvl, function(a, b) return a.level < b.level end) + local prevLevel = -1 + for i, spell in ipairs(tlvl) do + local line = "" + if prevLevel ~= spell.level then + if i ~= 1 then + line = "\n" + end + line = line .. "Spells for Level " .. spell.level .. "\n" + prevLevel = spell.level + end + text = text .. line .. " " .. spell.words .. " - " .. spell.name .. " : " .. spell.mana .. "\n" + end + text = text.."\n" + table.sort(tml, function(a, b) return a.mlevel < b.mlevel end) + local prevmLevel = -1 + for i, spell in ipairs(tml) do + local line = "" + if prevLevel ~= spell.mlevel then + if i ~= 1 then + line = "\n" + end + line = line .. "Spells for Magic Level " .. spell.mlevel .. "\n" + prevmLevel = spell.mlevel + end + text = text .. line .. " " .. spell.words .. " - " .. spell.name .. " : " .. spell.mana .. "\n" + end + + + player:showTextDialog(item:getId(), text) + return true +end + + +spellbook:id(2175, 6120, 8900, 8901, 8902, 8903, 8904, 8918, 12647, 16112, 18401, 22422, 23771) +spellbook:register() diff --git a/data/scripts/actions/system/quest_reward_common.lua b/data/scripts/actions/system/quest_reward_common.lua new file mode 100644 index 00000000000..685aa78bbf9 --- /dev/null +++ b/data/scripts/actions/system/quest_reward_common.lua @@ -0,0 +1,181 @@ +-- Common chest reward +-- You just need to add a new table in the data/startup/tables/chest.lua file +-- This script will pull everything from there + +local AttributeTable = { + [6013] = { + text = [[ +Hardek * +Bozo * +Sam **** +Oswald +Partos *** +Quentin * +Tark *** +Harsky *** +Stutch * +Ferumbras * +Frodo ** +Noodles ****]] + } +} + +local achievementTable = { + -- [chestUniqueId] = "Achievement name", + -- Annihilator + [6085] = "Annihilator", + [6086] = "Annihilator", + [6087] = "Annihilator", + [6088] = "Annihilator" +} + +local function playerAddItem(params, item) + local player = params.player + if not checkWeightAndBackpackRoom(player, params.weight, params.message) then + return false + end + + if params.key then + local itemType = ItemType(params.itemid) + -- 23763 Is key of Dawnport + -- Needs independent verification because it cannot be set as "key" in items.xml + -- Because it generate bug in the item description + if itemType:isKey() or itemType:getId(23763) then + -- If is key not in container, uses the "isKey = true" variable + keyItem = player:addItem(params.itemid, params.count) + keyItem:setActionId(params.storage) + end + else + addItem = player:addItem(params.itemid, params.count) + -- If the item is writeable, just put its unique and the text in the "AttributeTable" + local attribute = AttributeTable[item.uid] + if attribute then + addItem:setAttribute(ITEM_ATTRIBUTE_TEXT, attribute.text) + end + local achievement = achievementTable[item.uid] + if achievement then + player:addAchievement(achievement) + end + end + + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, params.message .. ".") + player:setStorageValue(params.storage, 1) + return true +end + +local function playerAddContainerItem(params, item) + local player = params.player + + local reward = params.containerReward + if params.action then + local itemType = ItemType(params.itemid) + if itemType:isKey() then + -- If is key inside container, uses the "keyAction" variable + keyItem = reward:addItem(params.itemid, params.count) + keyItem:setActionId(params.action) + end + end + + local achievement = achievementTable[item.uid] + if achievement then + player:addAchievement(achievement) + end + + reward:addItem(params.itemid, params.count) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a " .. getItemName(params.itemBagName) .. ".") + player:setStorageValue(params.storage, 1) + return true +end + +local questReward = Action() + +function questReward.onUse(player, item, fromPosition, itemEx, toPosition) + local setting = ChestUnique[item.uid] + if not setting then + return true + end + + if setting.weight then + local message = "You have found a " .. getItemName(setting.container) .. "." + + local backpack = player:getSlotItem(CONST_SLOT_BACKPACK) + if not backpack or backpack:getEmptySlots(true) < 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, message .. " But you have no room to take it.") + return true + end + if (player:getFreeCapacity() / 100) < setting.weight then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + message .. ". Weighing " .. setting.weight .. " oz, it is too heavy for you to carry.") + return true + end + end + + if player:getStorageValue(setting.storage) >= 0 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The ".. getItemName(setting.itemId) .. " is empty.") + return true + end + + local container = player:addItem(setting.container) + for i = 1, #setting.reward do + local itemid = setting.reward[i][1] + local count = setting.reward[i][2] + local itemDescriptions = getItemDescriptions(itemid) + local itemArticle = itemDescriptions.article + local itemName = itemDescriptions.name + local itemBagName = setting.container + local itemBag = container + + if not setting.container then + local addItemParams = { + player = player, + itemid = itemid, + count = count, + weight = getItemWeight(itemid) * count, + storage = setting.storage, + key = setting.isKey + } + + if count > 1 and ItemType(itemid):isStackable() then + if (itemDescriptions.plural) then + itemName = itemDescriptions.plural + end + addItemParams.message = "You have found " .. count .. " " .. itemName + elseif ItemType(itemid):getCharges() > 0 then + addItemParams.message = "You have found " .. itemArticle .. " " .. itemName + else + addItemParams.message = "You have found " .. itemArticle .. " " .. itemName + end + if not playerAddItem(addItemParams, item) then + return true + end + end + + if setting.container then + local addContainerItemParams = { + player = player, + itemid = itemid, + count = count, + weight = setting.weight, + storage = setting.storage, + action = setting.keyAction, + itemBagName = itemBagName, + containerReward = itemBag + } + + if not playerAddContainerItem(addContainerItemParams, item) then + return true + end + end + end + return true +end + +for uniqueRange = 5000, 9000 do + questReward:uid(uniqueRange) +end + +for uniqueRange = 10000, 12000 do + questReward:uid(uniqueRange) +end + +questReward:register() diff --git a/data/scripts/actions/tools/bricklayer_kit.lua b/data/scripts/actions/tools/bricklayer_kit.lua new file mode 100644 index 00000000000..787dce868b5 --- /dev/null +++ b/data/scripts/actions/tools/bricklayer_kit.lua @@ -0,0 +1,17 @@ +local brickLayerKit = Action() + +function brickLayerKit.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid ~= 50113 then + return false + end + + player:removeItem(5901, 3) + player:removeItem(8309, 3) + Game.createItem(1217, 1, Position(32617, 31513, 9)) + Game.createItem(7143, 1, Position(32617, 31514, 9)) + player:removeItem(8613, 1) + return true +end + +brickLayerKit:id(8613) +brickLayerKit:register() diff --git a/data/scripts/actions/tools/crowbar.lua b/data/scripts/actions/tools/crowbar.lua new file mode 100644 index 00000000000..af27d403566 --- /dev/null +++ b/data/scripts/actions/tools/crowbar.lua @@ -0,0 +1,8 @@ +local crowbar = Action() + +function crowbar.onUse(player, item, fromPosition, target, toPosition, isHotkey) + return onUseCrowbar(player, item, fromPosition, target, toPosition, isHotkey) +end + +crowbar:id(2416) +crowbar:register() diff --git a/data/scripts/actions/tools/grinder.lua b/data/scripts/actions/tools/grinder.lua new file mode 100644 index 00000000000..a22896acb70 --- /dev/null +++ b/data/scripts/actions/tools/grinder.lua @@ -0,0 +1,10 @@ +local grinder = Action() + +function grinder.onUse(player, item, frompos, item2, topos) + if(item2.itemid == 23942)then + return onGrindItem(player, item, frompos, item2, topos) + end +end + +grinder:id(18416) +grinder:register() diff --git a/data/scripts/actions/tools/hammer.lua b/data/scripts/actions/tools/hammer.lua new file mode 100644 index 00000000000..1a27340ae6a --- /dev/null +++ b/data/scripts/actions/tools/hammer.lua @@ -0,0 +1,189 @@ +function remove01() + +local wood1 = Position(32647, 32216, 7) + local wooda = Tile(wood1):getItemById(6475) + if wooda then + wooda:remove() + local woods = Game.createItem(13170, 1, { x=32647, y=32216, z=7}) + woods:setActionId(42501) + end + return true +end + + +function remove02() + +local wood11 = Position(32660, 32213, 7) + local woodaa = Tile(wood11):getItemById(6475) + if woodaa then + woodaa:remove() + local woodss = Game.createItem(13170, 1, { x=32660, y=32213, z=7}) -- 32660, 32213, 7 + woodss:setActionId(42502) + end + return true +end + +function remove03() + +local wood111 = Position(32644, 32183, 6) + local woodaaa = Tile(wood111):getItemById(6474) + if woodaaa then + woodaaa:remove() + local woodsss = Game.createItem(13172, 1, { x=32644, y=32183, z=6}) -- 32660, 32213, 7 + woodsss:setActionId(42503) + end + return true +end + +function remove04() + +local wood1111 = Position(32660, 32201, 7) + local woodaaaa = Tile(wood1111):getItemById(6474) + if woodaaaa then + woodaaaa:remove() + local woodssss = Game.createItem(13171, 1, { x=32660, y=32201, z=7}) -- + woodssss:setActionId(42504) + end + return true +end + +function remove05() + +local wood11111 = Position(32652, 32200, 5) + local woodaaaaa = Tile(wood11111):getItemById(6474) + if woodaaaaa then + woodaaaaa:remove() + local woodsssss = Game.createItem(13172, 1, { x=32652, y=32200, z=5}) -- + woodsssss:setActionId(42505) + end + return true +end + +local hammer = Action() + +function hammer.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if not target or type(target) ~= "userdata" or not target:isItem() then + return false + end + + local targetActionId = target:getActionId() + -- Lay down the wood + if targetActionId == 50109 then + if player:getItemCount(5901) >= 3 and player:getItemCount(8309) >= 3 then + player:removeItem(5901, 3) + player:removeItem(8309, 3) + player:say("KLING KLONG!", TALKTYPE_MONSTER_SAY) + + local bridge = Game.createItem(5770, 1, Position(32571, 31508, 9)) + if bridge then + bridge:setActionId(50110) + end + end + + -- Lay down the rails + elseif targetActionId == 50110 then + if player:getItemCount(10033) >= 1 and player:getItemCount(10034) >= 2 and player:getItemCount(8309) >= 3 then + player:removeItem(10033, 1) + player:removeItem(10034, 2) + player:removeItem(8309, 3) + player:say("KLING KLONG!", TALKTYPE_MONSTER_SAY) + + local rails = Game.createItem(7122, 1, Position(32571, 31508, 9)) + if rails then + rails:setActionId(50111) + end + end + + -- ROTTIMN START + elseif targetActionId == 42501 then + if player:getStorageValue(41600) == 3 and player:getStorageValue(Storage.RottinWoodAndMaried.RottinStart) < 6 then + + local wood1 = Position(32647, 32216, 7) + local wooda = Tile(wood1):getItemById(13170) + if wooda then + wooda:remove() + Game.createItem(6475, 1, { x=32647, y=32216, z=7}) + addEvent(remove01, 2*60*1000) + end + + player:setStorageValue(Storage.RottinWoodAndMaried.RottinStart, player:getStorageValue(Storage.RottinWoodAndMaried.RottinStart) +1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You fixed this broken wall.") + else player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You already fixed many broken walls today.") + end + + -- parte 2 + elseif targetActionId == 42502 then + if player:getStorageValue(41600) == 3 and player:getStorageValue(Storage.RottinWoodAndMaried.RottinStart) < 6 then + + local wood11 = Position(32660, 32213, 7) + local woodaa = Tile(wood11):getItemById(13170) + if woodaa then + woodaa:remove() + Game.createItem(6475, 1, { x=32660, y=32213, z=7}) + addEvent(remove02, 2*60*1000) + end + + player:setStorageValue(Storage.RottinWoodAndMaried.RottinStart, player:getStorageValue(Storage.RottinWoodAndMaried.RottinStart) +1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You fixed this broken wall.") + else player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You already fixed many broken walls today.") + end + + -- parte 3 + elseif targetActionId == 42503 then + if player:getStorageValue(41600) == 3 and player:getStorageValue(Storage.RottinWoodAndMaried.RottinStart) < 6 then + local wood111 = Position(32644, 32183, 6) + local woodaaa = Tile(wood111):getItemById(13172) + if woodaaa then + woodaaa:remove() + Game.createItem(6474, 1, { x=32644, y=32183, z=6}) + addEvent(remove03, 2*60*1000) + end + + player:setStorageValue(Storage.RottinWoodAndMaried.RottinStart, player:getStorageValue(Storage.RottinWoodAndMaried.RottinStart) +1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You fixed this broken wall.") + else player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You already fixed many broken walls today.") + end + + -- parte 4 + elseif targetActionId == 42504 then + if player:getStorageValue(41600) == 3 and player:getStorageValue(Storage.RottinWoodAndMaried.RottinStart) < 6 then + local wood1111 = Position(32660, 32201, 7) + local woodaaaa = Tile(wood1111):getItemById(13171) + if woodaaaa then + woodaaaa:remove() + Game.createItem(6474, 1, { x=32660, y=32201, z=7}) + addEvent(remove04, 2*60*1000) + end + + player:setStorageValue(Storage.RottinWoodAndMaried.RottinStart, player:getStorageValue(Storage.RottinWoodAndMaried.RottinStart) +1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You fixed this broken wall.") + else player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You already fixed many broken walls today.") + end + + -- parte 5 + elseif targetActionId == 42505 then + if player:getStorageValue(41600) == 3 and player:getStorageValue(Storage.RottinWoodAndMaried.RottinStart) < 6 then + local wood11111 = Position(32652, 32200, 5) + local woodaaaaa = Tile(wood11111):getItemById(13172) + if woodaaaaa then + woodaaaaa:remove() + Game.createItem(6474, 1, { x=32652, y=32200, z=5}) + addEvent(remove05, 2*60*1000) + end + + player:setStorageValue(Storage.RottinWoodAndMaried.RottinStart, player:getStorageValue(Storage.RottinWoodAndMaried.RottinStart) +1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You fixed this broken wall.") + else player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You already fixed many broken walls today.") + end + + + -- ROTTIM END + else + return false + end + + return true +end + +hammer:id(2557) +hammer:register() diff --git a/data/scripts/actions/tools/juice_squeezer.lua b/data/scripts/actions/tools/juice_squeezer.lua new file mode 100644 index 00000000000..7850aa3cf94 --- /dev/null +++ b/data/scripts/actions/tools/juice_squeezer.lua @@ -0,0 +1,14 @@ +local fruits = {2673, 2674, 2675, 2676, 2677, 2678, 2679, 2680, 2681, 2682, 2684, 2685, 5097, 8839, 8840, 8841} + +local juiceSqueezer = Action() + +function juiceSqueezer.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if isInArray(fruits, target.itemid) and player:removeItem(2006, 1, 0) then + target:remove(1) + player:addItem(2006, target.itemid == 2678 and 14 or 21) + return true + end +end + +juiceSqueezer:id(5865) +juiceSqueezer:register() diff --git a/data/scripts/actions/tools/kitchen_knife.lua b/data/scripts/actions/tools/kitchen_knife.lua new file mode 100644 index 00000000000..89cb0c38d19 --- /dev/null +++ b/data/scripts/actions/tools/kitchen_knife.lua @@ -0,0 +1,8 @@ +local kitchenKnife = Action() + +function kitchenKnife.onUse(player, item, fromPosition, target, toPosition, isHotkey) + return onUseKitchenKnife(player, item, fromPosition, target, toPosition, isHotkey) +end + +kitchenKnife:id(2566) +kitchenKnife:register() diff --git a/data/scripts/actions/tools/lock_pick.lua b/data/scripts/actions/tools/lock_pick.lua new file mode 100644 index 00000000000..ef074755d7c --- /dev/null +++ b/data/scripts/actions/tools/lock_pick.lua @@ -0,0 +1,22 @@ +local lockPick = Action() + +function lockPick.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.actionid ~= 12503 then + return false + end + + if math.random(100) <= 30 then + if player:getStorageValue(Storage.ThievesGuild.Mission02) == 1 then + player:addItem(8760, 1) + player:setStorageValue(Storage.ThievesGuild.Mission02, 2) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your lock pick open this chest!") + end + else + item:remove(1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your lock pick broke.") + end + return true +end + +lockPick:id(8717) +lockPick:register() diff --git a/data/scripts/actions/tools/machete.lua b/data/scripts/actions/tools/machete.lua new file mode 100644 index 00000000000..3888352441b --- /dev/null +++ b/data/scripts/actions/tools/machete.lua @@ -0,0 +1,8 @@ +local machete = Action() + +function machete.onUse(player, item, fromPosition, target, toPosition, isHotkey) + return onUseMachete(player, item, fromPosition, target, toPosition, isHotkey) +end + +machete:id(2420) +machete:register() diff --git a/data/scripts/actions/tools/noxious_claw.lua b/data/scripts/actions/tools/noxious_claw.lua new file mode 100644 index 00000000000..11ae78048df --- /dev/null +++ b/data/scripts/actions/tools/noxious_claw.lua @@ -0,0 +1,15 @@ +local noxiousClaw = Action() + +function noxiousClaw.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local player, useItem, depleteChance = player, item, 5 + if player:getCondition(CONDITION_POISON) then + player:removeCondition(CONDITION_POISON) + end + useItem:transform(10311) + useItem:decay() + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + return true +end + +noxiousClaw:id(10309) +noxiousClaw:register() diff --git a/data/scripts/actions/tools/pick.lua b/data/scripts/actions/tools/pick.lua new file mode 100644 index 00000000000..cdebff1a9d2 --- /dev/null +++ b/data/scripts/actions/tools/pick.lua @@ -0,0 +1,8 @@ +local pick = Action() + +function pick.onUse(player, item, fromPosition, target, toPosition, isHotkey) + return onUsePick(player, item, fromPosition, target, toPosition, isHotkey) +end + +pick:id(2553) +pick:register() diff --git a/data/scripts/actions/tools/present.lua b/data/scripts/actions/tools/present.lua new file mode 100644 index 00000000000..37bf9b44555 --- /dev/null +++ b/data/scripts/actions/tools/present.lua @@ -0,0 +1,17 @@ +local present = Action() + +function present.onUse(cid, item, fromPosition, itemEx, toPosition) + if(item.itemid == 13158) then + if(itemEx.itemid == 13159) then + if(getPlayerStorageValue(cid, Storage.RottinWoodAndMaried.Mission03) == 1) then + doRemoveItem(item.uid, 1) + doRemoveItem(itemEx.uid, 1) + doPlayerAddItem(cid, 13160, 1) + end + end + end + return true +end + +present:id(13158) +present:register() diff --git a/data/scripts/actions/tools/rake.lua b/data/scripts/actions/tools/rake.lua new file mode 100644 index 00000000000..4ebac8276ff --- /dev/null +++ b/data/scripts/actions/tools/rake.lua @@ -0,0 +1,22 @@ +local rake = Action() + +function rake.onUse(player, item, fromPosition, target, toPosition, isHotkey) + -- Wrath of the Emperor Mission02 + if target.itemid == 12322 then + player:addItem(12285, 1) + player:say("You dig out a handful of ordinary clay.", TALKTYPE_MONSTER_SAY) + -- The Shattered Isles Parrot ring + elseif target.itemid == 6094 then + if player:getStorageValue(Storage.TheShatteredIsles.TheGovernorDaughter) == 1 then + toPosition:sendMagicEffect(CONST_ME_POFF) + Game.createItem(6093, 1, Position(32422, 32770, 1)) + player:say("You have found a ring.", TALKTYPE_MONSTER_SAY) + player:setStorageValue(Storage.TheShatteredIsles.TheGovernorDaughter, 2) + end + end + return true +end + +rake:id(2549) +rake:register() + diff --git a/data/scripts/actions/tools/rope.lua b/data/scripts/actions/tools/rope.lua new file mode 100644 index 00000000000..1153ea7d2da --- /dev/null +++ b/data/scripts/actions/tools/rope.lua @@ -0,0 +1,8 @@ +local rope = Action() + +function rope.onUse(player, item, fromPosition, target, toPosition, isHotkey) + return onUseRope(player, item, fromPosition, target, toPosition, isHotkey) +end + +rope:id(2120, 7731) +rope:register() diff --git a/data/scripts/actions/tools/rust_remover.lua b/data/scripts/actions/tools/rust_remover.lua new file mode 100644 index 00000000000..d85dcd2ec90 --- /dev/null +++ b/data/scripts/actions/tools/rust_remover.lua @@ -0,0 +1,102 @@ +local CHAIN_ARMOR, SCALE_ARMOR, BRASS_ARMOR, PLATE_ARMOR, KNIGHT_ARMOR, PALADIN_ARMOR, CROWN_ARMOR, GOLDEN_ARMOR, DRAGON_SCALE_MAIL, MAGIC_PLATE_ARMOR = 2464, 2483, 2465, 2463, 2476, 8891, 2487, 2466, 2492, 2472 +local STUDDED_LEGS, CHAIN_LEGS, BRASS_LEGS, PLATE_LEGS, KNIGHT_LEGS, CROWN_LEGS, GOLDEN_LEGS = 2468, 2648, 2478, 2647, 2477, 2488, 2470 +local BRASS_HELMET, IRON_HELMET, STEEL_HELMET, CROWN_HELMET, CRUSADER_HELMET, ROYAL_HELMET = 2460, 2459, 2457, 2491, 2497, 2498 + +local config = { + [9808] = { -- common rusty armor + {{1, 30000}}, + {{30001, 60000}, CHAIN_ARMOR}, + {{60001, 90000}, SCALE_ARMOR}, + {{90001, 97000}, BRASS_ARMOR}, + {{97001, 99000}, PLATE_ARMOR}, + {{99001, 100000}, KNIGHT_ARMOR} + }, + + [9820] = { -- semi-rare rusty helmet + {{1, 40000}}, + {{40001, 57500}, BRASS_HELMET}, + {{57501, 70000}, IRON_HELMET}, + {{70001, 81000}, STEEL_HELMET}, + {{81001, 94000}, CROWN_HELMET}, + {{94001, 98500}, CRUSADER_HELMET}, + {{98501, 100000}, ROYAL_HELMET} + }, + + + [9809] = { -- semi-rare rusty armor + {{1, 40000}}, + {{40001, 57500}, CHAIN_ARMOR}, + {{57501, 70000}, SCALE_ARMOR}, + {{70001, 81000}, BRASS_ARMOR}, + {{81001, 90000}, PLATE_ARMOR}, + {{90001, 96500}, KNIGHT_ARMOR}, + {{96501, 99500}, PALADIN_ARMOR}, + {{99501, 100000}, CROWN_ARMOR} + }, + [9810] = { -- rare rusty armor + {{1, 50000}}, + {{50001, 60000}, CHAIN_ARMOR}, + {{60001, 70000}, SCALE_ARMOR}, + {{70001, 80000}, BRASS_ARMOR}, + {{80001, 87500}, PLATE_ARMOR}, + {{87501, 93000}, KNIGHT_ARMOR}, + {{93001, 96000}, PALADIN_ARMOR}, + {{96000, 97000}, CROWN_ARMOR}, + {{96001, 98500}, GOLDEN_ARMOR}, + {{98501, 99500}, DRAGON_SCALE_MAIL}, + {{99501, 100000}, MAGIC_PLATE_ARMOR} + }, + [9811] = { -- common rusty legs + {{1, 30000}}, + {{30001, 60000}, STUDDED_LEGS}, + {{60001, 85000}, CHAIN_LEGS}, + {{85001, 98000}, BRASS_LEGS}, + {{98001, 99500}, PLATE_LEGS}, + {{99501, 100000}, KNIGHT_LEGS} + }, + [9812] = { -- semi-rare rusty legs + {{1, 40000}}, + {{40001, 60000}, STUDDED_LEGS}, + {{60001, 75000}, CHAIN_LEGS}, + {{75001, 87500}, BRASS_LEGS}, + {{87501, 95500}, PLATE_LEGS}, + {{95501, 98250}, KNIGHT_LEGS}, + {{98251, 99250}, CROWN_LEGS}, + {{99251, 100000}, GOLDEN_LEGS} + }, + [9813] = { -- rare rusty legs + {{1, 50000}}, + {{50001, 75000}, BRASS_LEGS}, + {{75001, 90000}, PLATE_LEGS}, + {{90001, 97500}, KNIGHT_LEGS}, + {{97501, 99000}, CROWN_LEGS}, + {{99001, 100000}, GOLDEN_LEGS} + } +} + +local rustRemover = Action() + +function rustRemover.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local targetItem = config[target.itemid] + if not targetItem then + return true + end + + local chance = math.random(100000) + for i = 1, #targetItem do + if chance >= targetItem[i][1][1] and chance <= targetItem[i][1][2] then + if targetItem[i][2] then + target:transform(targetItem[i][2]) + toPosition:sendMagicEffect(CONST_ME_MAGIC_GREEN) + else + player:say((isInArray({9808, 9809, 9810}, target.itemid) and "The item was already damaged so badly that it broke when you tried to clean it." or "The item were already damaged so badly that they broke when you tried to clean them."),TALKTYPE_MONSTER_SAY) + target:remove() + toPosition:sendMagicEffect(CONST_ME_BLOCKHIT) + end + return item:remove(1) + end + end +end + +rustRemover:id(9930) +rustRemover:register() diff --git a/data/scripts/actions/tools/saw.lua b/data/scripts/actions/tools/saw.lua new file mode 100644 index 00000000000..8a10274db54 --- /dev/null +++ b/data/scripts/actions/tools/saw.lua @@ -0,0 +1,14 @@ +local saw = Action() + +function saw.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid ~= 5901 then + return false + end + + target:transform(10033) + toPosition:sendMagicEffect(CONST_ME_POFF) --Not sure if there's any magic effect when you use saw? + return true +end + +saw:id(2558) +saw:register() diff --git a/data/scripts/actions/tools/scythe.lua b/data/scripts/actions/tools/scythe.lua new file mode 100644 index 00000000000..dbb0e675209 --- /dev/null +++ b/data/scripts/actions/tools/scythe.lua @@ -0,0 +1,8 @@ +local scythe = Action() + +function scythe.onUse(player, item, fromPosition, target, toPosition, isHotkey) + return onUseScythe(player, item, fromPosition, target, toPosition, isHotkey) +end + +scythe:id(2550) +scythe:register() diff --git a/data/scripts/actions/tools/shovel.lua b/data/scripts/actions/tools/shovel.lua new file mode 100644 index 00000000000..077165fcaec --- /dev/null +++ b/data/scripts/actions/tools/shovel.lua @@ -0,0 +1,8 @@ +local shovel = Action() + +function shovel.onUse(player, item, itemEx, fromPosition, target, toPosition, isHotkey) + return onUseShovel(player, item, itemEx, fromPosition, target, toPosition, isHotkey) +end + +shovel:id(2554, 5710) +shovel:register() diff --git a/data/scripts/actions/tools/sickle.lua b/data/scripts/actions/tools/sickle.lua new file mode 100644 index 00000000000..c0feb61644c --- /dev/null +++ b/data/scripts/actions/tools/sickle.lua @@ -0,0 +1,13 @@ +local sickle = Action() + +function sickle.onUse(player, item, fromPosition, target, toPosition, isHotkey) +if target.itemid == 5465 then + target:transform(5464) + target:decay() + Game.createItem(5467, 1, toPosition) + return true + end +end + +sickle:id(2405) +sickle:register() diff --git a/data/scripts/actions/tools/skinning.lua b/data/scripts/actions/tools/skinning.lua new file mode 100644 index 00000000000..c4eb83ea01a --- /dev/null +++ b/data/scripts/actions/tools/skinning.lua @@ -0,0 +1,217 @@ +---- if you want protected corpses (10 second protection after monster being killed) to be skinned/dusted, delete '--#' in the appropriate lines; be careful, it may cause abuses ---- +local config = { + [5908] = { + + -- rabbits + [2992] = {value = 25000, newItem = 13159, after = 2993}, + [6017] = {value = 25000, newItem = 13159, after = 2993}, -- after being killed + + -- Minotaurs + [3090] = {value = 25000, newItem = 5878, after = 2831}, -- minotaur + [5969] = {value = 25000, newItem = 5878, after = 2831}, -- minotaur, after being killed + [2871] = {value = 25000, newItem = 5878, after = 2872}, -- minotaur archer + [5982] = {value = 25000, newItem = 5878, after = 2872}, -- minotaur archer, after being killed + [2866] = {value = 25000, newItem = 5878, after = 2867}, -- minotaur mage + [5981] = {value = 25000, newItem = 5878, after = 2867}, -- minotaur mage, after being killed + [2876] = {value = 25000, newItem = 5878, after = 2877}, -- minotaur guard/invader + [5983] = {value = 25000, newItem = 5878, after = 2877}, -- minotaur guard/invader, after being killed + [23463] = {value = 25000, newItem = 5878, after = 23464}, -- mooh'tah warrior + [23462] = {value = 25000, newItem = 5878, after = 23464}, -- mooh'tah warrior, after being killed + [23467] = {value = 25000, newItem = 5878, after = 23468}, -- minotaur hunter + [23466] = {value = 25000, newItem = 5878, after = 23468}, -- minotaur hunter, after being killed + [23471] = {value = 25000, newItem = 5878, after = 23472}, -- worm priestess + [23470] = {value = 25000, newItem = 5878, after = 23472}, -- worm priestess, after being killed + [23371] = {value = 25000, newItem = 5878, after = 23373}, -- minotaur amazon + [23372] = {value = 25000, newItem = 5878, after = 23373}, -- minotaur amazon, after being killed + [23375] = {value = 25000, newItem = 5878, after = 23377}, -- execowtioner + [23376] = {value = 25000, newItem = 5878, after = 23377}, -- execowtioner, after being killed + [23367] = {value = 25000, newItem = 5878, after = 23369}, -- moohtant + [23368] = {value = 25000, newItem = 5878, after = 23369}, -- moohtant, after being killed + + -- Low Class Lizards + [4259] = {value = 25000, newItem = 5876, after = 4260}, -- lizard sentinel + [6040] = {value = 25000, newItem = 5876, after = 4260}, -- lizard sentinel, after being killed + [4262] = {value = 25000, newItem = 5876, after = 4263}, -- lizard snakecharmer + [6041] = {value = 25000, newItem = 5876, after = 4263}, -- lizard snakecharmer, after being killed + [4256] = {value = 25000, newItem = 5876, after = 4257}, -- lizard templar + [4251] = {value = 25000, newItem = 5876, after = 4257}, -- lizard templar, after being killed + + -- High Class Lizards + [11285] = {value = 25000, newItem = 5876, after = 11286}, -- lizard chosen, + [11288] = {value = 25000, newItem = 5876, after = 11286}, -- lizard chosen, after being killed + [11277] = {value = 25000, newItem = 5876, after = 11278}, -- lizard dragon priest + [11280] = {value = 25000, newItem = 5876, after = 11278}, -- lizard dragon priest, after being killed + [11269] = {value = 25000, newItem = 5876, after = 11270}, -- lizard high guard + [11272] = {value = 25000, newItem = 5876, after = 11270}, -- lizard high guard, after being killed + [11281] = {value = 25000, newItem = 5876, after = 11282}, -- lizard zaogun + [11284] = {value = 25000, newItem = 5876, after = 11282}, -- lizard zaogun, after being killed + + -- Dragons + [3104] = {value = 25000, newItem = 5877, after = 3105}, + [2844] = {value = 25000, newItem = 5877, after = 3105}, + [5973] = {value = 25000, newItem = 5877, after = 3105}, -- after being killed + + -- Dragon Lords + [2881] = {value = 25000, newItem = 5948, after = 2882}, + [5984] = {value = 25000, newItem = 5948, after = 2882}, -- after being killed + + -- Behemoths + [2931] = {value = 35000, newItem = 5893, after = 2932}, + [5999] = {value = 35000, newItem = 5893, after = 2932}, -- after being killed + + -- Bone Beasts + [3031] = {value = 25000, newItem = 5925, after = 3032}, + [6030] = {value = 25000, newItem = 5925, after = 3032}, -- after being killed + + -- Clomp - raw meat + [25399] = {value = 25000, newItem = 24842, after = 25400}, + [25398] = {value = 25000, newItem = 24842, after = 25400}, -- after being killed + + -- The Mutated Pumpkin + [8961] = { { value = 5000, newItem = 7487 }, { value = 10000, newItem = 7737 }, { value = 20000, 6492 }, { value = 30000, newItem = 8860 }, { value = 45000, newItem = 2683 }, { value = 60000, newItem = 2096 }, { value = 90000, newItem = 9005, amount = 50 } }, + + -- Marble + [11343] = { { value = 10000, newItem = 11346, desc = "This little figurine of Tibiasula was masterfully sculpted by |PLAYERNAME|." }, {value = 30000, newItem = 11345, desc = "This little figurine made by |PLAYERNAME| has some room for improvement." }, {value = 60000, newItem = 11344, desc = "This shoddy work was made by |PLAYERNAME|." } }, + + -- Ice Cube + [7441] = {value = 25000, newItem = 7442}, + [7442] = {value = 25000, newItem = 7444}, + [7444] = {value = 25000, newItem = 7445}, + [7445] = {value = 25000, newItem = 7446}, + }, + [5942] = { + -- Demon + [2916] = {value = 25000, newItem = 5906, after = 2917}, + [5995] = {value = 25000, newItem = 5906, after = 2917}, -- after being killed + + -- Vampires + [2956] = {value = 25000, newItem = 5905, after = 2957}, -- vampire + [6006] = {value = 25000, newItem = 5905, after = 2957}, -- vampire, after being killed + [9654] = {value = 25000, newItem = 5905, after = 9658}, -- vampire bride + [9660] = {value = 25000, newItem = 5905, after = 9658}, -- vampire bride, after being killed + [8937] = {value = 25000, newItem = 5905, after = 8939}, -- vampire lord, after being killed (the count, diblis, etc) + [8938] = {value = 25000, newItem = 5905, after = 8939}, -- vampire lord (the count, diblis, etc) + [21275] = {value = 25000, newItem= 5905, after = 21276}, -- vampire viscount + [21278] = {value = 25000, newItem= 5905, after = 21276} -- vampire viscount, after being killed + } +} + +local skinning = Action() + +function skinning.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local skin = config[item.itemid][target.itemid] + + if item.itemid == 5908 then + if target.itemid == 38613 then + local chance = math.random(1, 10000) + target:getPosition():sendMagicEffect(CONST_ME_HITAREA) + target:remove(1) + if chance <= 9556 then + player:addItem(38614, 1) + else + player:addItem(38615, 1) + end + return true + -- Wrath of the emperor quest + elseif target.itemid == 12295 then + target:transform(12287) + player:say("You carve a solid bowl of the chunk of wood.", TALKTYPE_MONSTER_SAY) + return true + -- An Interest In Botany Quest + elseif target.itemid == 11691 and player:getItemCount(12655) > 0 and player:getStorageValue(Storage.TibiaTales.AnInterestInBotany) == 1 then + player:say("The plant feels cold but dry and very soft. You streak the plant gently with your knife and put a fragment in the almanach.", TALKTYPE_MONSTER_SAY) + player:setStorageValue(Storage.TibiaTales.AnInterestInBotany, 2) + return true + elseif target.itemid == 11653 and player:getItemCount(12655) > 0 and player:getStorageValue(Storage.TibiaTales.AnInterestInBotany) == 2 then + player:say("You cut a leaf from a branch and put it in the almanach. It smells strangely sweet and awfully bitter at the same time.", TALKTYPE_MONSTER_SAY) + player:setStorageValue(Storage.TibiaTales.AnInterestInBotany, 3) + return true + elseif target.itemid == 9009 and player:getStorageValue(789100) <= 1 then + player:say("You got Neutral matter.", TALKTYPE_MONSTER_SAY) + player:addItem(8310, 1) + player:setStorageValue(789100, 1) + return true + elseif target.itemid == 9010 and player:getStorageValue(789100) <= 1 then + player:say("You got Neutral matter.", TALKTYPE_MONSTER_SAY) + player:addItem(8310, 1) + player:setStorageValue(789100, 2) + return true + end + end + + if not skin then + player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + return true + end + + local charmMType, chanceRange = player:getCharmMonsterType(CHARM_SCAVENGE), 100000 + if charmMType then + local charmCorpse = charmMType:getCorpseId() + if charmCorpse == target.itemid or ItemType(charmCorpse):getDecayId() == target.itemid then + chanceRange = chanceRange * ((100 - GLOBAL_CHARM_SCAVENGE)/100) + end + end + + local random, effect, transform = math.random(1, chanceRange), CONST_ME_MAGIC_GREEN, true + if type(skin[1]) == 'table' then + local added = false + local _skin + for i = 1, #skin do + _skin = skin[i] + if random <= _skin.value then + if target.itemid == 11343 then + target:getPosition():sendMagicEffect(CONST_ME_ICEAREA) + local gobletItem = player:addItem(_skin.newItem, _skin.amount or 1) + if gobletItem then + gobletItem:setDescription(_skin.desc:gsub('|PLAYERNAME|', player:getName())) + end + target:remove() + added = true + else + target:transform(_skin.newItem, _skin.amount or 1) + added = true + end + break + end + end + + if not added and target.itemid == 8961 then + effect = CONST_ME_POFF + transform = false + elseif not added and target.itemid == 11343 then + effect = CONST_ME_POFF + transform = false + target:remove() + end + elseif random <= skin.value then + if isInArray({7441, 7442, 7444, 7445}, target.itemid) then + if skin.newItem == 7446 then + player:addAchievement('Ice Sculptor') + end + target:transform(skin.newItem, 1) + effect = CONST_ME_HITAREA + else + player:addItem(skin.newItem, skin.amount or 1) + end + else + if isInArray({7441, 7442, 7444, 7445}, target.itemid) then + player:say('The attempt of sculpting failed miserably.', TALKTYPE_MONSTER_SAY) + effect = CONST_ME_HITAREA + target:remove() + else + effect = CONST_ME_POFF + end + end + -- SE BUGAR, PEGAR SCRIPT ANTIGO + toPosition:sendMagicEffect(effect) + if transform then + target:transform(skin.after or target:getType():getDecayId() or target.itemid + 1) + else + target:remove() + end + + return true +end + +skinning:id(5908, 5942) +skinning:register() diff --git a/data/scripts/actions/tools/spoon.lua b/data/scripts/actions/tools/spoon.lua new file mode 100644 index 00000000000..31e855e25f8 --- /dev/null +++ b/data/scripts/actions/tools/spoon.lua @@ -0,0 +1,8 @@ +local spoon = Action() + +function spoon.onUse(player, item, fromPosition, target, toPosition, isHotkey) + return onUseSpoon(player, item, fromPosition, target, toPosition, isHotkey) +end + +spoon:id(2565) +spoon:register() diff --git a/data/scripts/actions/tools/toolgear.lua b/data/scripts/actions/tools/toolgear.lua new file mode 100644 index 00000000000..5a3b088d6e4 --- /dev/null +++ b/data/scripts/actions/tools/toolgear.lua @@ -0,0 +1,15 @@ +local toolGear = Action() + +function toolGear.onUse(player, item, fromPosition, target, toPosition, isHotkey) + return onUseRope(player, item, fromPosition, target, toPosition, isHotkey) + or onUseShovel(player, item, fromPosition, target, toPosition, isHotkey) + or onUsePick(player, item, fromPosition, target, toPosition, isHotkey) + or onUseMachete(player, item, fromPosition, target, toPosition, isHotkey) + or onUseCrowbar(player, item, fromPosition, target, toPosition, isHotkey) + or onUseSpoon(player, item, fromPosition, target, toPosition, isHotkey) + or onUseScythe(player, item, fromPosition, target, toPosition, isHotkey) + or onUseKitchenKnife(player, item, fromPosition, target, toPosition, isHotkey) +end + +toolGear:id(10511, 10513, 10515) +toolGear:register() diff --git a/data/scripts/actions/valuables/random_items.lua b/data/scripts/actions/valuables/random_items.lua new file mode 100644 index 00000000000..a73aeb54b74 --- /dev/null +++ b/data/scripts/actions/valuables/random_items.lua @@ -0,0 +1,174 @@ +local config = { + [13670] = { -- belonging of a deceased + chances = { + {from = 1, to = 1442, itemId = 2238}, + {from = 1443, to = 2856, itemId = 2237}, + {from = 2857, to = 4262, itemId = 2115}, + {from = 4263, to = 4819, itemId = 2148, count = 6}, + {from = 4820, to = 5325, itemId = 2787}, + {from = 5326, to = 5813, itemId = 5890}, + {from = 5814, to = 6283, itemId = 3976, count = 4}, + {from = 6284, to = 6751, itemId = 2695}, + {from = 6752, to = 7175, itemId = 5899}, + {from = 7176, to = 7576, itemId = 5894}, + {from = 7577, to = 7949, itemId = 10606}, + {from = 7950, to = 8315, itemId = 2403}, + {from = 8316, to = 8673, itemId = 8859}, + {from = 8674, to = 8972, itemId = 5902}, + {from = 8973, to = 9187}, + {from = 9188, to = 9328, itemId = 2661}, + {from = 9329, to = 9428, itemId = 2199}, + {from = 9429, to = 9515, itemId = 13926}, + {from = 9516, to = 9594, itemId = 2143}, + {from = 9595, to = 9666, itemId = 5879}, + {from = 9667, to = 9732, itemId = 2114}, + {from = 9733, to = 9791, itemId = 13925}, + {from = 9792, to = 9845, itemId = 10563}, + {from = 9846, to = 9891, itemId = 2110}, + {from = 9892, to = 9929, itemId = 5895}, + {from = 9930, to = 9967, itemId = 5880}, + {from = 9968, to = 9998, itemId = 13508}, + {from = 9999, to = 10001, itemId = 2195} + }, + effect = CONST_ME_POFF + }, + [15572] = { -- gooey mass + chances = { + {from = 1, to = 2}, + {from = 3, to = 2167, itemId = 15487, count = 10}, + {from = 2168, to = 4243, itemId = 2152, count = 2}, + {from = 4244, to = 6196, itemId = 2144, count = 2}, + {from = 6197, to = 8149, itemId = 7591, count = 2}, + {from = 8150, to = 9823, itemId = 7590, count = 2}, + {from = 9824, to = 9923, itemId = 9971}, + {from = 9924, to = 9990, itemId = 15546}, + {from = 9991, to = 10001, itemId = 15492} + }, + effect = CONST_ME_HITBYPOISON + }, + [18215] = { -- gnomish supply package + chances = { + {from = 1, to = 1440, itemId = 2787, count = 20}, + {from = 1441, to = 2434, itemId = 18397}, + {from = 2435, to = 3270, itemId = 18437, count = 15}, + {from = 3271, to = 4085, itemId = 18304, count = 15}, + {from = 4086, to = 4836, itemId = 18457}, + {from = 4837, to = 5447, itemId = 7588, count = 2}, + {from = 5448, to = 6047, itemId = 7589, count = 2}, + {from = 6048, to = 6576, itemId = 7618, count = 4}, + {from = 6577, to = 7094, itemId = 7620, count = 4}, + {from = 7095, to = 7559, itemId = 7590}, + {from = 7560, to = 7963, itemId = 7591}, + {from = 7964, to = 8317, itemId = 7443}, + {from = 8318, to = 8628, itemId = 7439}, + {from = 8629, to = 8932, itemId = 2152, count = 5}, + {from = 8933, to = 9232, itemId = 5911}, + {from = 9233, to = 9511, itemId = 7440}, + {from = 9512, to = 9636, itemId = 18455}, + {from = 9637, to = 9747, itemId = 18522}, + {from = 9748, to = 9836, itemId = 18519}, + {from = 9837, to = 9893, itemId = 2160}, + {from = 9894, to = 9929, itemId = 2156}, + {from = 9930, to = 9958, itemId = 18509}, + {from = 9959, to = 9987, itemId = 2154}, + {from = 9988, to = 9994, itemId = 2158}, + {from = 9995, to = 10001, itemId = 2155} + }, + effect = CONST_ME_CRAPS + }, + [25419] = { -- shaggy ogre bag + chances = { + {from = 1, to = 1440, itemId = 24843, count = 5}, + {from = 1441, to = 2434, itemId = 24847}, + {from = 2435, to = 3270, itemId = 24840}, + {from = 3271, to = 4085, itemId = 24850, count = 2}, + {from = 4086, to = 4836, itemId = 24844}, + {from = 4837, to = 5447, itemId = 24849, count = 3}, + {from = 5448, to = 6047, itemId = 3967}, + {from = 6048, to = 6576, itemId = 3970}, + {from = 6577, to = 7094, itemId = 7432}, + {from = 7095, to = 7418, itemId = 24839}, + {from = 7419, to = 7741, itemId = 24828}, + {from = 7742, to = 8064, itemId = 24827}, + {from = 8065, to = 8387, itemId = 3973}, + {from = 8388, to = 8710, itemId = 3983}, + {from = 8711, to = 9033, itemId = 24848}, + {from = 9034, to = 9356, itemId = 7413}, + {from = 9357, to = 9679, itemId = 7452}, + {from = 9680, to = 10001, itemId = 5669} + }, + effect = CONST_ME_CRAPS + }, + [26165] = { -- mysterious remains + chances = { + {from = 1, to = 1440, itemId = 2787, count = 10}, + {from = 1441, to = 2434, itemId = 2114}, + {from = 2435, to = 3270, itemId = 2661}, + {from = 3271, to = 4085, itemId = 5880}, + {from = 4086, to = 4836, itemId = 3956}, + {from = 4837, to = 5447, itemId = 2199}, + {from = 5448, to = 6047, itemId = 5879}, + {from = 6048, to = 6576, itemId = 6570}, + {from = 6577, to = 7094, itemId = 2165}, + {from = 7095, to = 7559, itemId = 5882}, + {from = 7560, to = 7963, itemId = 13537}, + {from = 7964, to = 8317, itemId = 18215}, + {from = 8318, to = 8628, itemId = 2162}, + {from = 8629, to = 8932, itemId = 24850}, + {from = 8933, to = 9232, itemId = 9813}, + {from = 9233, to = 9511, itemId = 2079}, + {from = 9512, to = 9636, itemId = 25419}, + {from = 9637, to = 9747, itemId = 2154}, + {from = 9748, to = 9836, itemId = 2153}, + {from = 9837, to = 9893, itemId = 9971}, + {from = 9894, to = 9929, itemId = 25393}, + {from = 9930, to = 9958, itemId = 26192}, + {from = 9959, to = 10001, itemId = 25387} + }, + effect = CONST_ME_CRAPS + }, + [32014] = { -- surprise jar + chances = { + {from = 0, to = 2500, itemId = 2158}, + {from = 2501, to = 5001, itemId = 2153}, + {from = 5002, to = 6668, itemId = 25377}, + {from = 6668, to = 8335, itemId = 25172}, + {from = 8336, to = 10001, itemId = 30888} + }, + effect = CONST_ME_CRAPS + } +} + +local randomItems = Action() + +function randomItems.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local useId = config[item.itemid] + if not useId then + return false + end + + local chance = math.random(10001) + for i = 1, #useId.chances do + local randomItem = useId.chances[i] + if chance >= randomItem.from and chance <= randomItem.to then + if randomItem.itemId then + local itemId, count = randomItem.itemId, randomItem.count or 1 + player:addItem(itemId, count) + if item.itemid == 13670 then + local itemType = ItemType(itemId) + player:say('You found ' .. (count > 1 and count or (itemType:getArticle() ~= '' and itemType:getArticle() or '')) .. ' ' .. (count > 1 and itemType:getPluralName() or itemType:getName()) .. ' in the bag.', TALKTYPE_MONSTER_SAY) + end + else + player:say('You found nothing useful.', TALKTYPE_MONSTER_SAY) + end + + item:getPosition():sendMagicEffect(useId.effect) + item:remove(1) + break + end + end + return true +end + +randomItems:id(13670, 15572, 18215, 25419, 26165, 32014) +randomItems:register() diff --git a/data/scripts/actions/worldboard.lua b/data/scripts/actions/worldboard.lua new file mode 100644 index 00000000000..456177ebba4 --- /dev/null +++ b/data/scripts/actions/worldboard.lua @@ -0,0 +1,33 @@ +local worldBoard = Action() + +local communicates = { +-- Fury Gates +[1] = { + globalStorage=65000, + communicate = "A fiery fury gate has opened near one of the major cities somewhere in Tibia." +}, +-- Yasir +[2] = { + globalStorage = 65014, + communicate = "Oriental ships sighted! A trader for exotic creature products may currently be visiting Carlin, Ankrahmun or Liberty Bay." +}, +-- Nightmare Isle +[3] = { + globalStorage = 65015, + communicate = "A sandstorm travels through Darama, leading to isles full of deadly creatures inside a nightmare. Avoid the river near Drefia/northernmost coast/Ankhramun tar pits!" +} +} + +function worldBoard.onUse(player, item, fromPosition, target, toPosition, isHotkey) + +for index, value in pairs(communicates) do + if getGlobalStorageValue(value.globalStorage) > 0 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, value.communicate) + end +end + return true +end + + +worldBoard:id(21570) +worldBoard:register() diff --git a/data/scripts/actions/worldchanges/deeplings/bosses_reward.lua b/data/scripts/actions/worldchanges/deeplings/bosses_reward.lua new file mode 100644 index 00000000000..05f27b7d4f3 --- /dev/null +++ b/data/scripts/actions/worldchanges/deeplings/bosses_reward.lua @@ -0,0 +1,69 @@ +local rewards = { + [9302] = { + storage = Storage.DeeplingBosses.Jaul, + bossName = 'Jaul', + items = { + {rand = true, itemId = {15403, 15434}}, + {itemId = 2152, count = 50}, + {itemId = 15621}, + {itemId = 15453} + } + }, + [9303] = { + storage = Storage.DeeplingBosses.Tanjis, + bossName = 'Tanjis', + items = { + {rand = true, itemId = {15435, 2144}}, + {itemId = 15620}, + {itemId = 2152, count = 20}, + {itemId = 15403}, + {itemId = 15453} + } + }, + [9304] = { + storage = Storage.DeeplingBosses.Obujos, + bossName = 'Obujos', + items = { + {rand = true, itemId = {15436, 7632}}, + {itemId = 15619}, + {itemId = 15454}, + {itemId = 2152, count = 30}, + {itemId = 15400} + } + } +} + +local bossesReward = Action() + +function bossesReward.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.uid > 25609 and item.uid < 25613 then + local reward = rewards[item.uid] + if not reward then + return true + end + + if player:getStorageValue(reward.storage) ~= 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, reward.bossName .. ' defends his belongings and will not let you open his chest.') + return true + end + + + for i = 1, #reward.items do + local items = reward.items[i] + if items.rand then + if math.random(10) == 1 then + player:addItem(items.itemId[math.random(#items.itemId)], 1) + end + else + player:addItem(items.itemId, items.count or 1) + end + end + + player:setStorageValue(reward.storage, 0) + end + return true +end + +bossesReward:uid(9302, 9303, 9304) +bossesReward:register() + diff --git a/data/scripts/actions/worldchanges/the_mummys_curse/horestis_jars.lua b/data/scripts/actions/worldchanges/the_mummys_curse/horestis_jars.lua new file mode 100644 index 00000000000..868c55aea26 --- /dev/null +++ b/data/scripts/actions/worldchanges/the_mummys_curse/horestis_jars.lua @@ -0,0 +1,129 @@ +local bossName = "Horestis" +local bossPosition = {x = 32943, y = 32791, z = 12} +local Poswall1 = {x = 32941, y = 32754, z = 12} +local Poswall2 = {x = 32942, y = 32754, z = 12} +local Poswall3 = {x = 32943, y = 32754, z = 12} +local Poswall4 = {x = 32944, y = 32754, z = 12} +local failMessages = {"Waaaaaah", "You are too afraid to destroy this object"} + +function createWall() --creates walls + Game.createItem(3514,1,Poswall1) + Game.createItem(3514,1,Poswall2) + Game.createItem(3514,1,Poswall3) + Game.createItem(3514,1,Poswall4) +end + +local horestisJars = Action() + +function horestisJars.onUse(cid, item, fromPosition, itemEx, toPosition) + + local exaustedSeconds = 1 + local player = Player(cid) + local chances = math.random(10) + + if item.actionid == 50006 then + if(item.itemid == 13500) then + if getPlayerStorageValue(cid, Storage.TheMummysCurse.Time1) <= os.time() then + if chances == 1 then + doTransformItem(item.uid, 13495) + setGlobalStorageValue(GlobalStorage.TheMummysCurse, 1) + else + player:say(failMessages[math.random(#failMessages)], TALKTYPE_ORANGE_1) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + setPlayerStorageValue(cid, Storage.TheMummysCurse.Time1, os.time()+exaustedSeconds*1800) + end + else + doPlayerSendCancel(cid, "You need wait 30 minutes to use again.") + end + end + + elseif item.actionid == 50007 then + if(item.itemid == 13500) then + if(getGlobalStorageValue(GlobalStorage.TheMummysCurse) == 1) then + if getPlayerStorageValue(cid, Storage.TheMummysCurse.Time2) <= os.time() then + if chances == 1 then + doTransformItem(item.uid, 13495) + setGlobalStorageValue(GlobalStorage.TheMummysCurse, 2) + else + player:say(failMessages[math.random(#failMessages)], TALKTYPE_ORANGE_1) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + setPlayerStorageValue(cid, Storage.TheMummysCurse.Time2, os.time()+exaustedSeconds*1800) + end + else + doPlayerSendCancel(cid, "You need wait 30 minutes to use again.") + end + else + doPlayerSendCancel(cid, "You need to break the first jar.") + end + end + + elseif item.actionid == 50008 then + if(item.itemid == 13500) then + if(getGlobalStorageValue(GlobalStorage.TheMummysCurse) == 2) then + if getPlayerStorageValue(cid, Storage.TheMummysCurse.Time3) <= os.time() then + if chances == 1 then + doTransformItem(item.uid, 13495) + setGlobalStorageValue(GlobalStorage.TheMummysCurse, 3) + else + player:say(failMessages[math.random(#failMessages)], TALKTYPE_ORANGE_1) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + setPlayerStorageValue(cid, Storage.TheMummysCurse.Time3, os.time()+exaustedSeconds*1800) + end + else + doPlayerSendCancel(cid, "You need wait 30 minutes to use again.") + end + else + doPlayerSendCancel(cid, "You need to break the second jar.") + end + end + + + elseif item.actionid == 50009 then + if(item.itemid == 13500) then + if(getGlobalStorageValue(GlobalStorage.TheMummysCurse) == 3) then + if getPlayerStorageValue(cid, Storage.TheMummysCurse.Time4) <= os.time() then + if chances == 1 then + doTransformItem(item.uid, 13495) + setGlobalStorageValue(GlobalStorage.TheMummysCurse, 4) + else + player:say(failMessages[math.random(#failMessages)], TALKTYPE_ORANGE_1) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + setPlayerStorageValue(cid, Storage.TheMummysCurse.Time4, os.time()+exaustedSeconds*1800) + end + else + doPlayerSendCancel(cid, "You need wait 30 minutes to use again.") + end + else + doPlayerSendCancel(cid, "You need to break the third jar.") + end + end + + elseif item.actionid == 50010 then + if(item.itemid == 13500) then + if(getGlobalStorageValue(GlobalStorage.TheMummysCurse) == 4) then + doTransformItem(item.uid, 13495) + -- Remover Barreira e Sumonar Boss + doRemoveItem(getTileItemById({x = 32941, y = 32754, z = 12}, 3514).uid, 1) + doRemoveItem(getTileItemById({x = 32942, y = 32754, z = 12}, 3514).uid, 1) + doRemoveItem(getTileItemById({x = 32943, y = 32754, z = 12}, 3514).uid, 1) + doRemoveItem(getTileItemById({x = 32944, y = 32754, z = 12}, 3514).uid, 1) + doCreatureSay(cid, "The horestis tomb was broken, the boss of the tomb will be reborn in 45 seconds. The barrier will be built from here 2 minutes.", TALKTYPE_ORANGE_1) + Game.createMonster(bossName, bossPosition) + addEvent(doSummonCreature, 45*1000, "Horestis", {x = 32942, y = 32765, z = 12}) + + addEvent(createWall, 61000+6*20*1800) + addEvent(Game.createItem, 20 * 60 * 1000, 3514, {x = 32941, y = 32754, z = 12}) + addEvent(Game.createItem, 20 * 60 * 1000, 3514, {x = 32942, y = 32754, z = 12}) + addEvent(Game.createItem, 20 * 60 * 1000, 3514, {x = 32943, y = 32754, z = 12}) + addEvent(Game.createItem, 20 * 60 * 1000, 3514, {x = 32944, y = 32754, z = 12}) + else + doPlayerSendCancel(cid, "You need to break the fourth jar.") + end + end + end + return true +end + +horestisJars:aid(50006, 50007, 50008, 50009, 50010) +horestisJars:register() + diff --git a/data/scripts/creaturescripts/customs/freequests.lua b/data/scripts/creaturescripts/customs/freequests.lua new file mode 100644 index 00000000000..ff6e24244ae --- /dev/null +++ b/data/scripts/creaturescripts/customs/freequests.lua @@ -0,0 +1,350 @@ +local questTable = { +[1] = {storageId = Storage.BigfootBurden.QuestLine, storageValue = 2}, +[2] = {storageId = Storage.BigfootBurden.QuestLine, storageValue = 4}, +[3] = {storageId = Storage.BigfootBurden.QuestLine, storageValue = 7}, +[4] = {storageId = Storage.BigfootBurden.QuestLine, storageValue = 9}, +[5] = {storageId = Storage.BigfootBurden.QuestLine, storageValue = 12}, +[6] = {storageId = Storage.BigfootBurden.Shooting, storageValue = 5}, +[7] = {storageId = Storage.BigfootBurden.QuestLine, storageValue = 16}, +[8] = {storageId = Storage.BigfootBurden.QuestLine, storageValue = 20}, +[9] = {storageId = Storage.BigfootBurden.QuestLine, storageValue = 23}, +[10] = {storageId = Storage.BigfootBurden.QuestLineComplete, storageValue = 2}, +[11] = {storageId = Storage.BigfootBurden.Rank, storageValue = 999999}, +[12] = {storageId = Storage.BigfootBurden.Warzone1Access, storageValue = 2}, +[13] = {storageId = Storage.BigfootBurden.Warzone2Access, storageValue = 2}, +[14] = {storageId = Storage.BigfootBurden.Warzone3Access, storageValue = 2}, +[15] = {storageId = Storage.DangerousDepths.Questline, storageValue = 10}, +[16] = {storageId = Storage.DangerousDepths.Access.LavaPumpWarzoneVI, storageValue = 10}, +[17] = {storageId = Storage.DangerousDepths.Access.LavaPumpWarzoneV, storageValue = 10}, +[18] = {storageId = Storage.DangerousDepths.Access.LavaPumpWarzoneIV, storageValue = 30}, +[19] = {storageId = Storage.DangerousDepths.Dwarves.Status, storageValue = 10}, +[20] = {storageId = Storage.DangerousDepths.Scouts.Status, storageValue = 10}, +[21] = {storageId = Storage.DangerousDepths.Gnomes.Status, storageValue = 10}, +[22] = {storageId = Storage.InServiceofYalahar.Questline, storageValue = 51}, +[23] = {storageId = Storage.InServiceofYalahar.Mission01, storageValue = 6}, +[24] = {storageId = Storage.InServiceofYalahar.Mission02, storageValue = 8}, +[25] = {storageId = Storage.InServiceofYalahar.Mission03, storageValue = 6}, +[26] = {storageId = Storage.InServiceofYalahar.Mission04, storageValue = 6}, +[27] = {storageId = Storage.InServiceofYalahar.Mission05, storageValue = 8}, +[28] = {storageId = Storage.InServiceofYalahar.Mission06, storageValue = 5}, +[29] = {storageId = Storage.InServiceofYalahar.Mission07, storageValue = 5}, +[30] = {storageId = Storage.InServiceofYalahar.Mission08, storageValue = 4}, +[31] = {storageId = Storage.InServiceofYalahar.Mission09, storageValue = 2}, +[32] = {storageId = Storage.InServiceofYalahar.Mission10, storageValue = 1}, +[33] = {storageId = Storage.InServiceofYalahar.SewerPipe01, storageValue = 1}, +[34] = {storageId = Storage.InServiceofYalahar.SewerPipe02, storageValue = 1}, +[35] = {storageId = Storage.InServiceofYalahar.SewerPipe03, storageValue = 1}, +[36] = {storageId = Storage.InServiceofYalahar.SewerPipe04, storageValue = 1}, +[37] = {storageId = Storage.InServiceofYalahar.DiseasedDan, storageValue = 1}, +[38] = {storageId = Storage.InServiceofYalahar.DiseasedBill, storageValue = 1}, +[39] = {storageId = Storage.InServiceofYalahar.DiseasedFred, storageValue = 1}, +[40] = {storageId = Storage.InServiceofYalahar.AlchemistFormula, storageValue = 1}, +[41] = {storageId = Storage.InServiceofYalahar.BadSide, storageValue = 1}, +[42] = {storageId = Storage.InServiceofYalahar.GoodSide , storageValue = 1}, +[43] = {storageId = Storage.InServiceofYalahar.MrWestDoor, storageValue = 1}, +[44] = {storageId = Storage.InServiceofYalahar.MrWestStatus, storageValue = 1}, +[45] = {storageId = Storage.InServiceofYalahar.TamerinStatus, storageValue = 1}, +[46] = {storageId = Storage.InServiceofYalahar.MorikSummon, storageValue = 1}, +[47] = {storageId = Storage.InServiceofYalahar.QuaraState, storageValue = 1}, +[48] = {storageId = Storage.InServiceofYalahar.QuaraSplasher, storageValue = 1}, +[49] = {storageId = Storage.InServiceofYalahar.QuaraSharptooth, storageValue = 1}, +[50] = {storageId = Storage.InServiceofYalahar.QuaraInky, storageValue = 1}, +[51] = {storageId = Storage.InServiceofYalahar.MatrixState, storageValue = 1}, +[52] = {storageId = Storage.InServiceofYalahar.NotesPalimuth, storageValue = 1}, +[53] = {storageId = Storage.InServiceofYalahar.NotesAzerus, storageValue = 1}, +[54] = {storageId = Storage.InServiceofYalahar.DoorToAzerus, storageValue = 1}, +[55] = {storageId = Storage.InServiceofYalahar.DoorToBog, storageValue = 1}, +[56] = {storageId = Storage.InServiceofYalahar.DoorToLastFight, storageValue = 1}, +[57] = {storageId = Storage.InServiceofYalahar.DoorToMatrix, storageValue = 1}, +[58] = {storageId = Storage.InServiceofYalahar.DoorToQuara, storageValue = 1}, +[59] = {storageId = Storage.InServiceofYalahar.SewerPipe01, storageValue = 1}, +[60] = {storageId = Storage.InServiceofYalahar.SewerPipe02, storageValue = 1}, +[61] = {storageId = Storage.InServiceofYalahar.SewerPipe03, storageValue = 1}, +[62] = {storageId = Storage.InServiceofYalahar.SewerPipe04, storageValue = 1}, +[63] = {storageId = Storage.InServiceofYalahar.DiseasedDan, storageValue = 1}, +[64] = {storageId = Storage.InServiceofYalahar.DiseasedBill, storageValue = 1}, +[65] = {storageId = Storage.InServiceofYalahar.DiseasedFred, storageValue = 1}, +[66] = {storageId = Storage.InServiceofYalahar.AlchemistFormula, storageValue = 1}, +[67] = {storageId = Storage.InServiceofYalahar.BadSide, storageValue = 1}, +[68] = {storageId = Storage.InServiceofYalahar.GoodSide, storageValue = 1}, +[69] = {storageId = Storage.InServiceofYalahar.MrWestDoor, storageValue = 1}, +[70] = {storageId = Storage.InServiceofYalahar.MrWestStatus, storageValue = 1}, +[71] = {storageId = Storage.InServiceofYalahar.TamerinStatus, storageValue = 1}, +[72] = {storageId = Storage.InServiceofYalahar.MorikSummon, storageValue = 1}, +[73] = {storageId = Storage.InServiceofYalahar.QuaraState, storageValue = 1}, +[74] = {storageId = Storage.InServiceofYalahar.QuaraSplasher, storageValue = 1}, +[75] = {storageId = Storage.InServiceofYalahar.QuaraSharptooth, storageValue = 1}, +[76] = {storageId = Storage.InServiceofYalahar.QuaraInky, storageValue = 1}, +[77] = {storageId = Storage.CultsOfTibia.Questline, storageValue = 7}, +[78] = {storageId = Storage.CultsOfTibia.Minotaurs.jamesfrancisTask, storageValue = 1}, +[79] = {storageId = Storage.CultsOfTibia.Minotaurs.Mission, storageValue = 1}, +[80] = {storageId = Storage.CultsOfTibia.Minotaurs.bossTimer, storageValue = 1}, +[81] = {storageId = Storage.CultsOfTibia.MotA.Mission, storageValue = 1}, +[82] = {storageId = Storage.CultsOfTibia.MotA.Pedra1, storageValue = 1}, +[83] = {storageId = Storage.CultsOfTibia.MotA.Pedra2, storageValue = 1}, +[84] = {storageId = Storage.CultsOfTibia.MotA.Pedra3, storageValue = 1}, +[85] = {storageId = Storage.CultsOfTibia.MotA.Respostas, storageValue = 1}, +[86] = {storageId = Storage.CultsOfTibia.MotA.Perguntaid, storageValue = 1}, +[87] = {storageId = Storage.CultsOfTibia.Barkless.Mission, storageValue = 1}, +[88] = {storageId = Storage.CultsOfTibia.Barkless.sulphur, storageValue = 1}, +[89] = {storageId = Storage.CultsOfTibia.Barkless.tar, storageValue = 1}, +[90] = {storageId = Storage.CultsOfTibia.Barkless.ice, storageValue = 1}, +[91] = {storageId = Storage.CultsOfTibia.Barkless.Objects, storageValue = 1}, +[92] = {storageId = Storage.CultsOfTibia.Barkless.Temp, storageValue = 1}, +[93] = {storageId = Storage.CultsOfTibia.Barkless.bossTimer, storageValue = 1}, +[94] = {storageId = Storage.CultsOfTibia.Orcs.Mission, storageValue = 1}, +[95] = {storageId = Storage.CultsOfTibia.Orcs.lookType, storageValue = 1}, +[96] = {storageId = Storage.CultsOfTibia.Orcs.bossTimer, storageValue = 1}, +[97] = {storageId = Storage.CultsOfTibia.Life.Mission, storageValue = 1}, +[98] = {storageId = Storage.CultsOfTibia.Life.bossTimer, storageValue = 1}, +[99] = {storageId = Storage.CultsOfTibia.Humans.Mission, storageValue = 1}, +[100] = {storageId = Storage.CultsOfTibia.Humans.Vaporized, storageValue = 1}, +[101] = {storageId = Storage.CultsOfTibia.Humans.Decaying, storageValue = 1}, +[102] = {storageId = Storage.CultsOfTibia.Humans.bossTimer, storageValue = 1}, +[103] = {storageId = Storage.CultsOfTibia.Misguided.Mission, storageValue = 1}, +[104] = {storageId = Storage.CultsOfTibia.Misguided.Monsters, storageValue = 1}, +[105] = {storageId = Storage.CultsOfTibia.Misguided.Exorcisms, storageValue = 1}, +[106] = {storageId = Storage.CultsOfTibia.Misguided.Time, storageValue = 1}, +[107] = {storageId = Storage.CultsOfTibia.Misguided.bossTimer, storageValue = 1}, +[108] = {storageId = Storage.ExplorerSociety.QuestLine, storageValue = 1}, +[109] = {storageId = Storage.ExplorerSociety.QuestLine, storageValue = 4}, +[110] = {storageId = Storage.ExplorerSociety.QuestLine, storageValue = 7}, +[111] = {storageId = Storage.ExplorerSociety.QuestLine, storageValue = 16}, +[112] = {storageId = Storage.ExplorerSociety.QuestLine, storageValue = 26}, +[113] = {storageId = Storage.ExplorerSociety.QuestLine, storageValue = 29}, +[114] = {storageId = Storage.ExplorerSociety.QuestLine, storageValue = 32}, +[115] = {storageId = Storage.ExplorerSociety.QuestLine, storageValue = 35}, +[116] = {storageId = Storage.ExplorerSociety.QuestLine, storageValue = 38}, +[117] = {storageId = Storage.ExplorerSociety.QuestLine, storageValue = 41}, +[118] = {storageId = Storage.ExplorerSociety.QuestLine, storageValue = 43}, +[119] = {storageId = Storage.ExplorerSociety.QuestLine, storageValue = 46}, +[120] = {storageId = Storage.ExplorerSociety.QuestLine, storageValue = 47}, +[121] = {storageId = Storage.ExplorerSociety.QuestLine, storageValue = 50}, +[122] = {storageId = Storage.ExplorerSociety.QuestLine, storageValue = 55}, +[123] = {storageId = Storage.ExplorerSociety.QuestLine, storageValue = 56}, +[124] = {storageId = Storage.ExplorerSociety.QuestLine, storageValue = 58}, +[125] = {storageId = Storage.ExplorerSociety.QuestLine, storageValue = 61}, +[126] = {storageId = Storage.ExplorerSociety.CalassaQuest, storageValue = 2}, +[127] = {storageId = Storage.ForgottenKnowledge.Tomes, storageValue = 1}, +[128] = {storageId = Storage.ForgottenKnowledge.LastLoreKilled, storageValue = 1}, +[129] = {storageId = Storage.ForgottenKnowledge.TimeGuardianKilled, storageValue = 1}, +[130] = {storageId = Storage.ForgottenKnowledge.HorrorKilled, storageValue = 1}, +[131] = {storageId = Storage.ForgottenKnowledge.DragonkingKilled, storageValue = 1}, +[132] = {storageId = Storage.ForgottenKnowledge.ThornKnightKilled, storageValue = 1}, +[133] = {storageId = Storage.ForgottenKnowledge.LloydKilled, storageValue = 1}, +[134] = {storageId = Storage.ForgottenKnowledge.LadyTenebrisKilled, storageValue = 1}, +[135] = {storageId = Storage.ForgottenKnowledge.AccessMachine, storageValue = 1}, +[136] = {storageId = Storage.BarbarianTest.Questline, storageValue = 1}, +[137] = {storageId = Storage.BarbarianTest.Mission01, storageValue = 3}, +[138] = {storageId = Storage.BarbarianTest.Mission02, storageValue = 3}, +[139] = {storageId = Storage.BarbarianTest.Mission03, storageValue = 3}, +[140] = {storageId = Storage.BarbarianTest.Mission03, storageValue = 3}, +[141] = {storageId = Storage.ChildrenoftheRevolution.Questline, storageValue = 21}, +[142] = {storageId = Storage.ChildrenoftheRevolution.Mission00, storageValue = 2}, +[143] = {storageId = Storage.ChildrenoftheRevolution.Mission01, storageValue = 3}, +[144] = {storageId = Storage.ChildrenoftheRevolution.Mission02, storageValue = 5}, +[145] = {storageId = Storage.ChildrenoftheRevolution.Mission03, storageValue = 3}, +[146] = {storageId = Storage.ChildrenoftheRevolution.Mission04, storageValue = 6}, +[147] = {storageId = Storage.ChildrenoftheRevolution.Mission05, storageValue = 3}, +[148] = {storageId = Storage.ChildrenoftheRevolution.SpyBuilding01, storageValue = 1}, +[149] = {storageId = Storage.ChildrenoftheRevolution.SpyBuilding02, storageValue = 1}, +[150] = {storageId = Storage.ChildrenoftheRevolution.SpyBuilding03, storageValue = 1}, +[151] = {storageId = Storage.ChildrenoftheRevolution.StrangeSymbols, storageValue = 1}, +[152] = {storageId = Storage.DjinnWar.Faction.Greeting, storageValue = 2}, +[153] = {storageId = Storage.DjinnWar.Faction.Marid, storageValue = 2}, +[154] = {storageId = Storage.DjinnWar.Faction.Efreet, storageValue = 2}, +[155] = {storageId = Storage.DjinnWar.EfreetFaction.Start, storageValue = 1}, +[156] = {storageId = Storage.DjinnWar.EfreetFaction.Mission01, storageValue = 3}, +[157] = {storageId = Storage.DjinnWar.EfreetFaction.Mission02, storageValue = 3}, +[158] = {storageId = Storage.DjinnWar.EfreetFaction.Mission03, storageValue = 3}, +[159] = {storageId = Storage.DjinnWar.MaridFaction.Start, storageValue = 1}, +[160] = {storageId = Storage.DjinnWar.MaridFaction.Mission01, storageValue = 2}, +[161] = {storageId = Storage.DjinnWar.MaridFaction.Mission02, storageValue = 2}, +[162] = {storageId = Storage.DjinnWar.MaridFaction.RataMari, storageValue = 2}, +[163] = {storageId = Storage.DjinnWar.MaridFaction.Mission03, storageValue = 3}, +[164] = {storageId = Storage.TheWayToYalahar.Questline, storageValue = 1}, +[165] = {storageId = Storage.SearoutesAroundYalahar.TownsCounter, storageValue = 1}, +[166] = {storageId = Storage.SearoutesAroundYalahar.AbDendriel, storageValue = 1}, +[167] = {storageId = Storage.SearoutesAroundYalahar.Darashia, storageValue = 1}, +[168] = {storageId = Storage.SearoutesAroundYalahar.Venore, storageValue = 1}, +[169] = {storageId = Storage.SearoutesAroundYalahar.Ankrahmun, storageValue = 1}, +[170] = {storageId = Storage.SearoutesAroundYalahar.PortHope, storageValue = 1}, +[171] = {storageId = Storage.SearoutesAroundYalahar.Thais, storageValue = 1}, +[172] = {storageId = Storage.SearoutesAroundYalahar.LibertyBay, storageValue = 1}, +[173] = {storageId = Storage.SearoutesAroundYalahar.Carlin, storageValue = 1}, +[174] = {storageId = Storage.HiddenCityOfBeregar.DefaultStart, storageValue = 1}, +[175] = {storageId = Storage.HiddenCityOfBeregar.GoingDown, storageValue = 1}, +[176] = {storageId = Storage.TheIceIslands.Questline, storageValue = 12}, +[177] = {storageId = Storage.TheIceIslands.Mission01, storageValue = 3}, +[178] = {storageId = Storage.TheIceIslands.Mission02, storageValue = 5}, +[179] = {storageId = Storage.TheIceIslands.Mission03, storageValue = 3}, +[180] = {storageId = Storage.TheIceIslands.Mission04, storageValue = 2}, +[181] = {storageId = Storage.TheIceIslands.Mission05, storageValue = 6}, +[182] = {storageId = Storage.TheIceIslands.Mission06, storageValue = 8}, +[183] = {storageId = Storage.TheIceIslands.Mission07, storageValue = 3}, +[184] = {storageId = Storage.TheIceIslands.Mission08, storageValue = 4}, +[185] = {storageId = Storage.TheIceIslands.Mission09, storageValue = 2}, +[186] = {storageId = Storage.TheIceIslands.Mission10, storageValue = 2}, +[187] = {storageId = Storage.TheIceIslands.Mission11, storageValue = 2}, +[188] = {storageId = Storage.TheIceIslands.Mission12, storageValue = 6}, +[189] = {storageId = Storage.TheInquisition.Questline, storageValue = 25}, +[190] = {storageId = Storage.TheInquisition.Mission01, storageValue = 7}, +[191] = {storageId = Storage.TheInquisition.Mission02, storageValue = 3}, +[192] = {storageId = Storage.TheInquisition.Mission03, storageValue = 6}, +[193] = {storageId = Storage.TheInquisition.Mission04, storageValue = 3}, +[194] = {storageId = Storage.TheInquisition.Mission05, storageValue = 3}, +[195] = {storageId = Storage.TheInquisition.Mission06, storageValue = 3}, +[196] = {storageId = Storage.TheInquisition.Mission07, storageValue = 1}, +[197] = {storageId = Storage.TheInquisition.GrofGuard, storageValue = 1}, +[198] = {storageId = Storage.TheInquisition.KulagGuard, storageValue = 1}, +[199] = {storageId = Storage.TheInquisition.TimGuard, storageValue = 1}, +[200] = {storageId = Storage.TheInquisition.WalterGuard, storageValue = 1}, +[201] = {storageId = Storage.TheInquisition.StorkusVampiredust, storageValue = 1}, +[202] = {storageId = Storage.TheNewFrontier.Questline, storageValue = 28}, +[203] = {storageId = Storage.TheNewFrontier.Mission01, storageValue = 3}, +[204] = {storageId = Storage.TheNewFrontier.Mission02, storageValue = 6}, +[205] = {storageId = Storage.TheNewFrontier.Mission03, storageValue = 3}, +[206] = {storageId = Storage.TheNewFrontier.Mission04, storageValue = 2}, +[207] = {storageId = Storage.TheNewFrontier.Mission05, storageValue = 7}, +[208] = {storageId = Storage.TheNewFrontier.Mission06, storageValue = 3}, +[209] = {storageId = Storage.TheNewFrontier.Mission07, storageValue = 3}, +[210] = {storageId = Storage.TheNewFrontier.Mission08, storageValue = 2}, +[211] = {storageId = Storage.TheNewFrontier.Mission09, storageValue = 3}, +[212] = {storageId = Storage.TheNewFrontier.Mission10, storageValue = 1}, +[213] = {storageId = Storage.TheNewFrontier.TomeofKnowledge, storageValue = 12}, +[214] = {storageId = Storage.TheNewFrontier.Beaver1, storageValue = 1}, +[215] = {storageId = Storage.TheNewFrontier.Beaver2, storageValue = 1}, +[216] = {storageId = Storage.TheNewFrontier.Beaver3, storageValue = 1}, +[217] = {storageId = Storage.TheNewFrontier.BribeKing, storageValue = 1}, +[218] = {storageId = Storage.TheNewFrontier.BribeLeeland, storageValue = 1}, +[219] = {storageId = Storage.TheNewFrontier.BribeExplorerSociety, storageValue = 1}, +[220] = {storageId = Storage.TheNewFrontier.BribeWydrin, storageValue = 1}, +[221] = {storageId = Storage.TheNewFrontier.BribeTelas, storageValue = 1}, +[222] = {storageId = 12200, storageValue = 1}, +[213] = {storageId = 12201, storageValue = 3}, +[224] = {storageId = 12202, storageValue = 5}, +[225] = {storageId = 12203, storageValue = 3}, +[226] = {storageId = 12204, storageValue = 2}, +[227] = {storageId = 12205, storageValue = 6}, +[228] = {storageId = 12206, storageValue = 8}, +[229] = {storageId = 12207, storageValue = 3}, +[230] = {storageId = 12208, storageValue = 4}, +[231] = {storageId = 12209, storageValue = 2}, +[232] = {storageId = 12210, storageValue = 2}, +[233] = {storageId = 12211, storageValue = 2}, +[234] = {storageId = 12212, storageValue = 1}, +[235] = {storageId = Storage.TheShatteredIsles.DefaultStart, storageValue = 3}, +[236] = {storageId = Storage.TheShatteredIsles.TheGovernorDaughter, storageValue = 3}, +[237] = {storageId = Storage.TheShatteredIsles.TheErrand, storageValue = 2}, +[238] = {storageId = Storage.TheShatteredIsles.AccessToMeriana, storageValue = 1}, +[239] = {storageId = Storage.TheShatteredIsles.APoemForTheMermaid, storageValue = 3}, +[240] = {storageId = Storage.TheShatteredIsles.ADjinnInLove, storageValue = 5}, +[241] = {storageId = Storage.TheShatteredIsles.AccessToLagunaIsland, storageValue = 1}, +[242] = {storageId = Storage.TheShatteredIsles.AccessToGoroma, storageValue = 1}, +[243] = {storageId = Storage.TheShatteredIsles.Shipwrecked, storageValue = 2}, +[244] = {storageId = Storage.TheShatteredIsles.DragahsSpellbook, storageValue = 1}, +[245] = {storageId = Storage.TheShatteredIsles.TheCounterspell, storageValue = 4}, +[246] = {storageId = Storage.ThievesGuild.Quest, storageValue = 1}, +[247] = {storageId = Storage.ThievesGuild.Mission01, storageValue = 2}, +[248] = {storageId = Storage.ThievesGuild.Mission02, storageValue = 3}, +[249] = {storageId = Storage.ThievesGuild.Mission03, storageValue = 3}, +[250] = {storageId = Storage.ThievesGuild.Mission04, storageValue = 8}, +[251] = {storageId = Storage.ThievesGuild.Mission05, storageValue = 2}, +[252] = {storageId = Storage.ThievesGuild.Mission06, storageValue = 4}, +[253] = {storageId = Storage.ThievesGuild.Mission07, storageValue = 2}, +[254] = {storageId = Storage.ThievesGuild.Mission08, storageValue = 1}, +[255] = {storageId = Storage.TravellingTrader.Mission01, storageValue = 1}, +[256] = {storageId = Storage.TravellingTrader.Mission01, storageValue = 2}, +[257] = {storageId = Storage.TravellingTrader.Mission02, storageValue = 5}, +[258] = {storageId = Storage.TravellingTrader.Mission03, storageValue = 3}, +[259] = {storageId = Storage.TravellingTrader.Mission04, storageValue = 3}, +[260] = {storageId = Storage.TravellingTrader.Mission05, storageValue = 3}, +[261] = {storageId = Storage.TravellingTrader.Mission06, storageValue = 2}, +[262] = {storageId = Storage.TravellingTrader.Mission07, storageValue = 1}, +[263] = {storageId = Storage.SvargrondArena.QuestLogGreenhorn, storageValue = 1}, +[264] = {storageId = Storage.TibiaTales.DefaultStart, storageValue = 1}, +[265] = {storageId = Storage.TibiaTales.ToAppeaseTheMightyQuest, storageValue = 1}, +[266] = {storageId = 12450, storageValue = 6}, +[267] = {storageId = 12451, storageValue = 3}, +[268] = {storageId = 12452, storageValue = 3}, +[269] = {storageId = 12453, storageValue = 2}, +[270] = {storageId = 12454, storageValue = 4}, +[271] = {storageId = 12455, storageValue = 13}, +[272] = {storageId = 12456, storageValue = 8}, +[273] = {storageId = 12457, storageValue = 3}, +[274] = {storageId = 12458, storageValue = 4}, +[275] = {storageId = 12459, storageValue = 3}, +[276] = {storageId = 12460, storageValue = 5}, +[277] = {storageId = 12330, storageValue = 1}, +[278] = {storageId = 12331, storageValue = 3}, +[279] = {storageId = 12332, storageValue = 13}, +[280] = {storageId = 12333, storageValue = 3}, +[281] = {storageId = 12334, storageValue = 2}, +[282] = {storageId = 12335, storageValue = 3}, +[283] = {storageId = 12336, storageValue = 3}, +[284] = {storageId = Storage.FriendsandTraders.DefaultStart, storageValue = 1}, +[285] = {storageId = Storage.FriendsandTraders.TheSweatyCyclops, storageValue = 2}, +[286] = {storageId = Storage.FriendsandTraders.TheMermaidMarina, storageValue = 2}, +[287] = {storageId = Storage.FriendsandTraders.TheBlessedStake, storageValue = 12}, +[288] = {storageId = 100157, storageValue = 1}, +[289] = {storageId = 2500, storageValue = 0}, +[290] = {storageId = 22000, storageValue = 5}, +[291] = {storageId = Storage.WrathoftheEmperor.Questline, storageValue = 1}, +[292] = {storageId = Storage.WrathoftheEmperor.Mission01, storageValue = 3}, +[293] = {storageId = Storage.WrathoftheEmperor.Mission02, storageValue = 3}, +[294] = {storageId = Storage.WrathoftheEmperor.Mission03, storageValue = 3}, +[295] = {storageId = Storage.WrathoftheEmperor.Mission04, storageValue = 3}, +[296] = {storageId = Storage.WrathoftheEmperor.Mission05, storageValue = 3}, +[297] = {storageId = Storage.WrathoftheEmperor.Mission06, storageValue = 4}, +[298] = {storageId = Storage.WrathoftheEmperor.Mission07, storageValue = 6}, +[299] = {storageId = Storage.WrathoftheEmperor.Mission08, storageValue = 2}, +[300] = {storageId = Storage.WrathoftheEmperor.Mission09, storageValue = 2}, +[301] = {storageId = Storage.WrathoftheEmperor.Mission10, storageValue = 6}, +[302] = {storageId = Storage.WrathoftheEmperor.Mission11, storageValue = 1}, +[303] = {storageId = Storage.TheApeCity.Started, storageValue = 1}, +[304] = {storageId = Storage.TheApeCity.Questline, storageValue = 18}, +[305] = {storageId = Storage.Oramond.QuestLine, storageValue = 1}, +[306] = {storageId = Storage.Oramond.MissionToTakeRoots, storageValue = 3000}, +[307] = {storageId = Storage.DangerousDepths.Questline, storageValue = 1}, +[308] = {storageId = Storage.DangerousDepths.Dwarves.Home, storageValue = 2}, +[309] = {storageId = Storage.DangerousDepths.Dwarves.Subterranean, storageValue = 2}, +[310] = {storageId = Storage.DangerousDepths.Gnomes.Measurements, storageValue = 2}, +[311] = {storageId = Storage.DangerousDepths.Gnomes.Ordnance, storageValue = 3}, +[312] = {storageId = Storage.DangerousDepths.Gnomes.Charting, storageValue = 2}, +[313] = {storageId = Storage.DangerousDepths.Scouts.Growth, storageValue = 2}, +[314] = {storageId = Storage.DangerousDepths.Scouts.Diremaw, storageValue = 2}, +[315] = {storageId = Storage.ThreatenedDreams.Start, storageValue = 1}, +[316] = {storageId = Storage.ThreatenedDreams.TroubledMission01, storageValue = 4}, +[317] = {storageId = Storage.AdventurersGuild.GreatDragonHunt.WarriorSkeleton, storageValue = 1}, +[318] = {storageId = Storage.AdventurersGuild.GreatDragonHunt.WarriorSkeleton, storageValue = 2}, +[319] = {storageId = Storage.Quest.Dawnport.Questline, storageValue = 1}, +[320] = {storageId = Storage.Quest.Dawnport.GoMain, storageValue = 1}, +[321] = {storageId = Storage.ForgottenKnowledge.AccessDeath, storageValue = 1}, +[322] = {storageId = Storage.ForgottenKnowledge.AccessViolet, storageValue = 1}, +[323] = {storageId = Storage.ForgottenKnowledge.AccessEarth, storageValue = 1}, +[324] = {storageId = Storage.ForgottenKnowledge.AccessFire, storageValue = 1}, +[325] = {storageId = Storage.ForgottenKnowledge.AccessIce, storageValue = 1}, +[326] = {storageId = Storage.ForgottenKnowledge.AccessGolden, storageValue = 1} +} + +local upperLimit = 1 -- change upperLimit to a higher one after adding a new quest to questTable + +local freeQuests = CreatureEvent("FreeQuests") + +function freeQuests.onLogin(player) + + if configManager.getBoolean(configKeys.FREE_QUESTS) and player:getStorageValue(Storage.FreeQuests) < upperLimit then + for index, value in pairs(questTable) do + if value.storageId and value.storageValue then + if player:getStorageValue(value.storageId) < value.storageValue then + player:setStorageValue(value.storageId, value.storageValue) + end + end + end + + player:setStorageValue(Storage.FreeQuests, upperLimit) + end + return true +end + +freeQuests:register() diff --git a/data/scripts/creaturescripts/monster/gaz_haragoth_heal.lua b/data/scripts/creaturescripts/monster/gaz_haragoth_heal.lua new file mode 100644 index 00000000000..04c76b878d3 --- /dev/null +++ b/data/scripts/creaturescripts/monster/gaz_haragoth_heal.lua @@ -0,0 +1,25 @@ +local condition = Condition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) +condition:setParameter(CONDITION_PARAM_SUBID, 88888) +condition:setParameter(CONDITION_PARAM_TICKS, 7 * 1000) +condition:setParameter(CONDITION_PARAM_HEALTHGAIN, 0.01) +condition:setParameter(CONDITION_PARAM_HEALTHTICKS, 7 * 1000) + +local gazHaragothHeal = CreatureEvent("GazHaragothHeal") +function gazHaragothHeal.onThink(creature) + local hp = (creature:getHealth()/creature:getMaxHealth())*100 + if (hp < 12.5 and not creature:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, 88888)) then + creature:addCondition(condition) + creature:say("Gaz'haragoth begins to draw on the nightmares to HEAL himself!", TALKTYPE_ORANGE_2) + addEvent(function(cid) + local creature = Creature(cid) + if not creature then + return + end + creature:addHealth(300000) + creature:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + creature:say("Gaz'haragoth HEALS himself!", TALKTYPE_ORANGE_2) + return true + end, 7000, creature:getId()) + end +end +gazHaragothHeal:register() diff --git a/data/scripts/creaturescripts/monster/greater_minion.lua b/data/scripts/creaturescripts/monster/greater_minion.lua new file mode 100644 index 00000000000..1f71474bfd7 --- /dev/null +++ b/data/scripts/creaturescripts/monster/greater_minion.lua @@ -0,0 +1,23 @@ +local greaterMinion = CreatureEvent("GreaterMinion") +function greaterMinion.onThink(creature) + addEvent(function(cid) + local creature = Creature(cid) + if not creature then + return + end + local pos = creature:getPosition() + local creatureMaster = creature:getMaster() + pos:sendMagicEffect(CONST_ME_MORTAREA) + local say = creatureMaster:say("The minion gains greater power!", TALKTYPE_ORANGE_2) + if not say then + return + end + creature:remove() + local summon = Game.createMonster("greater death minion", pos, false, true) + if not summon then + return + end + return true + end, 7000, creature:getId()) +end +greaterMinion:register() diff --git a/data/scripts/creaturescripts/monster/hirintror_heal.lua b/data/scripts/creaturescripts/monster/hirintror_heal.lua new file mode 100644 index 00000000000..19e393e9529 --- /dev/null +++ b/data/scripts/creaturescripts/monster/hirintror_heal.lua @@ -0,0 +1,20 @@ +local condition = Condition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) +condition:setParameter(CONDITION_PARAM_SUBID, 88888) +condition:setParameter(CONDITION_PARAM_TICKS, 15 * 60 * 1000) +condition:setParameter(CONDITION_PARAM_HEALTHGAIN, 0.01) +condition:setParameter(CONDITION_PARAM_HEALTHTICKS, 15 * 60 * 1000) + +local hirintrorHeal = CreatureEvent("HirintrorHeal") +function hirintrorHeal.onPrepareDeath(creature, lastHitKiller, mostDamageKiller) + if creature:getName():lower() == "hirintror" then + if not creature:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, 88888) then + creature:addCondition(condition) + creature:addHealth(1000) + return + end + else + return + end + return true +end +hirintrorHeal:register() diff --git a/data/scripts/creaturescripts/monster/lower_roshamuul.lua b/data/scripts/creaturescripts/monster/lower_roshamuul.lua new file mode 100644 index 00000000000..7ce2e4c501f --- /dev/null +++ b/data/scripts/creaturescripts/monster/lower_roshamuul.lua @@ -0,0 +1,14 @@ +local setting = { + ["frazzlemaw"] = roshamuul_killed_frazzlemaws, + ["silencer"] = ROSHAMUUL_KILLED_SILENCERS +} + +local lowerRoshamuul = CreatureEvent("LowerRoshamuul") +function lowerRoshamuul.onKill(creature, target) + local monster = setting[target:getName():lower()] + if monster then + creature:setStorageValue(monster, math.max(0, creature:getStorageValue(monster)) + 1) + end + return true +end +lowerRoshamuul:register() diff --git a/data/scripts/creaturescripts/monster/necromantic_minion.lua b/data/scripts/creaturescripts/monster/necromantic_minion.lua new file mode 100644 index 00000000000..6b7c39e38f1 --- /dev/null +++ b/data/scripts/creaturescripts/monster/necromantic_minion.lua @@ -0,0 +1,18 @@ +local necromanticMinion = CreatureEvent("NecromanticMinion") +function necromanticMinion.onThink(creature) + addEvent(function(cid) + local creature = Creature(cid) + if not creature then + return + end + local pos = creature:getPosition() + pos:sendMagicEffect(CONST_ME_MORTAREA) + creature:remove() + local summon = Game.createMonster("necromantic energy", pos, false, true) + if not summon then + return + end + return true + end, 7000, creature:getId()) +end +necromanticMinion:register() diff --git a/data/scripts/creaturescripts/monster/northern_pike.lua b/data/scripts/creaturescripts/monster/northern_pike.lua new file mode 100644 index 00000000000..2b370dc3717 --- /dev/null +++ b/data/scripts/creaturescripts/monster/northern_pike.lua @@ -0,0 +1,9 @@ +local northernPike = CreatureEvent("NorthernPike") +function northernPike.onDeath(creature, corpse, killer, mostDamage, unjustified, mostDamage_unjustified) + local chance = math.random(1, 100) + if chance < 50 then + Game.createMonster("slippery northern pike", creature:getPosition()) + else + end +end +northernPike:register() diff --git a/data/scripts/creaturescripts/monster/omrafir_explode.lua b/data/scripts/creaturescripts/monster/omrafir_explode.lua new file mode 100644 index 00000000000..01acca114c0 --- /dev/null +++ b/data/scripts/creaturescripts/monster/omrafir_explode.lua @@ -0,0 +1,41 @@ +local condition = Condition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) +condition:setParameter(CONDITION_PARAM_SUBID, 88888) +condition:setParameter(CONDITION_PARAM_TICKS, 5 * 1000) +condition:setParameter(CONDITION_PARAM_HEALTHGAIN, 0.01) +condition:setParameter(CONDITION_PARAM_HEALTHTICKS, 5 * 1000) + +function boom(cid) + local creature = Creature(cid) + if not creature then + return + end + creature:say("OMRAFIR EXPLODES INTO FLAMES!", TALKTYPE_ORANGE_2) + Game.setStorageValue(112416, Game.getStorageValue(112416) + 1) + creature:getPosition():sendMagicEffect(CONST_ME_FIREATTACK) + for i = 1, 9 do + Game.createMonster("Hellfire Fighter", Position(33589 + math.random(-8,8), 32379 + math.random(-9,9), 12), true, true) + creature:remove() + end + return true +end + +local omrafirExplode = CreatureEvent("OmrafirExplode") +function omrafirExplode.onThink(creature) + local hp = (creature:getHealth()/creature:getMaxHealth())*100 + local summons = creature:getSummons() + if hp <= 50 and #summons < 4 and not creature:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, 88888) and + Game.getStorageValue(112416) < 2 then + addEvent(boom, 10, creature:getId()) + addEvent(function(cid) + Game.createMonster("Omrafir", Position(33586, 32379, 12), false, true) + end, 30000, creature:getId()) + elseif hp <= 3 and not creature:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, 88888) then + addEvent(boom, 10, creature:getId()) + addEvent(function(cid) + local summon = Game.createMonster("Omrafir2", Position(33586, 32379, 12), false, true) + summon:say("OMRAFIR REFORMS HIMSELF WITH NEW STRENGTH!", TALKTYPE_ORANGE_2) + end, 30000, creature:getId()) + end + return true +end +omrafirExplode:register() diff --git a/data/scripts/creaturescripts/monster/shared_life.lua b/data/scripts/creaturescripts/monster/shared_life.lua new file mode 100644 index 00000000000..a2a1f23fa5f --- /dev/null +++ b/data/scripts/creaturescripts/monster/shared_life.lua @@ -0,0 +1,30 @@ +local sharedLife = CreatureEvent("SharedLife") +function sharedLife.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin) + if not creature:isMonster() then + return primaryDamage, primaryType, secondaryDamage, secondaryType + end + if not creature:inSharedLife() then + return primaryDamage, primaryType, secondaryDamage, secondaryType + end + local killer = false + -- Monster.onReceivDamageSL(self, damage, tp) + if primaryType == COMBAT_HEALING then + creature:onReceivDamageSL(primaryDamage, "healing", killer) + else + if(creature:getHealth() - primaryDamage <= 0)then + killer = true + end + creature:onReceivDamageSL(primaryDamage, "damage", killer) + end + killer = false + if secondaryType == COMBAT_HEALING then + creature:onReceivDamageSL(secondaryDamage, "healing", killer) + else + if(creature:getHealth() - secondaryDamage <= 0)then + killer = true + end + creature:onReceivDamageSL(secondaryDamage, "damage", killer) + end + return primaryDamage, primaryType, secondaryDamage, secondaryType +end +sharedLife:register() diff --git a/data/scripts/creaturescripts/monster/shargon_growth_check.lua b/data/scripts/creaturescripts/monster/shargon_growth_check.lua new file mode 100644 index 00000000000..6ff88541416 --- /dev/null +++ b/data/scripts/creaturescripts/monster/shargon_growth_check.lua @@ -0,0 +1,16 @@ +local shargonGrowthCheck = CreatureEvent("ShargonGrowthCheck") +function shargonGrowthCheck.onThink(creature) + local tilePos = Tile({x=creature:getPosition().x+math.random(-1, 1), y=creature:getPosition().y+math.random(-1, 1), z=creature:getPosition().z }) + if not tilePos then + return true + end + if tilePos:getItemById(1497) or tilePos:getItemById(1499) then + creature:say("Your tricks are older then my minions! You wont trap me! Amuse yourself with my slaves as long was your traps are in place!", TALKTYPE_ORANGE_2) + for i = 1, 20 do + Game.createMonster("Death Reaper", {x = 176 + math.random(-6,6), y = 386 + math.random(-6,6), z = 7}, false, true) + creature:remove() + end + end + return true +end +shargonGrowthCheck:register() diff --git a/data/scripts/creaturescripts/monster/shlorg_teleport.lua b/data/scripts/creaturescripts/monster/shlorg_teleport.lua new file mode 100644 index 00000000000..91881a08404 --- /dev/null +++ b/data/scripts/creaturescripts/monster/shlorg_teleport.lua @@ -0,0 +1,21 @@ +local position = { + [1] = {pos = {x=33170, y=31730, z=9}}, + [2] = {pos = {x=33175, y=31736, z=9}}, + [3] = {pos = {x=33174, y=31747, z=9}}, + [4] = {pos = {x=33164, y=31744, z=9}} +} + +local shlorgTeleport = CreatureEvent("ShlorgTeleport") +function shlorgTeleport.onThink(creature) + local chance = math.random(1, 100) + if chance < 7 then + if(not creature:isMonster()) then + return true + end + local spawn = position[math.random(4)] + creature:teleportTo(spawn.pos) + creature:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end +end +shlorgTeleport:register() diff --git a/data/scripts/creaturescripts/monster/superior_minion.lua b/data/scripts/creaturescripts/monster/superior_minion.lua new file mode 100644 index 00000000000..52edcfd2fa8 --- /dev/null +++ b/data/scripts/creaturescripts/monster/superior_minion.lua @@ -0,0 +1,18 @@ +local superiorMinion = CreatureEvent("SuperiorMinion") +function superiorMinion.onThink(creature) + addEvent(function(cid) + local creature = Creature(cid) + if not creature then + return + end + local pos = creature:getPosition() + pos:sendMagicEffect(CONST_ME_MORTAREA) + creature:remove() + local summon = Game.createMonster("superior death minion", pos, false, true) + if not summon then + return + end + return true + end, 7000, creature:getId()) +end +superiorMinion:register() diff --git a/data/scripts/creaturescripts/monster/the_pale_count_kill.lua b/data/scripts/creaturescripts/monster/the_pale_count_kill.lua new file mode 100644 index 00000000000..b95ff808a00 --- /dev/null +++ b/data/scripts/creaturescripts/monster/the_pale_count_kill.lua @@ -0,0 +1,11 @@ +local thePaleCountKill = CreatureEvent("ThePaleCountKill") +function thePaleCountKill.onThink(creature) + local hp = (creature:getHealth()/creature:getMaxHealth())*100 + if (hp < 75) then + creature:say("Dare to follow me to my Sanctuary below and you shall DIE!", TALKTYPE_ORANGE_1) + creature:remove() + Game.createMonster("the pale count2", { x=32972, y=32419, z=15 }) + end + return true +end +thePaleCountKill:register() diff --git a/data/scripts/creaturescripts/monster/the_welter_egg.lua b/data/scripts/creaturescripts/monster/the_welter_egg.lua new file mode 100644 index 00000000000..6b1010ebcdb --- /dev/null +++ b/data/scripts/creaturescripts/monster/the_welter_egg.lua @@ -0,0 +1,18 @@ +local theWelterEgg = CreatureEvent("TheWelterEgg") +function theWelterEgg.onThink(creature) + addEvent(function(cid) + local creature = Creature(cid) + if not creature then + return + end + local pos = creature:getPosition() + pos:sendMagicEffect(CONST_ME_POISONAREA) + creature:remove() + local summon = Game.createMonster("spawn of the welter", pos, false, true) + if not summon then + return + end + return true + end, 10000, creature:getId()) +end +theWelterEgg:register() diff --git a/data/scripts/creaturescripts/monster/urmahlullu_change.lua b/data/scripts/creaturescripts/monster/urmahlullu_change.lua new file mode 100644 index 00000000000..a0ef004709d --- /dev/null +++ b/data/scripts/creaturescripts/monster/urmahlullu_change.lua @@ -0,0 +1,95 @@ +local UrmahlulluChanges = CreatureEvent("UrmahlulluChanges") +local WeakenedDeath = CreatureEvent("WeakenedDeath") +local timetochange = 60 --in seconds + +local config = { + {itemId = 36248}, + {itemId = 2016}, +} + +--base urmahlullu have 515000/515000 hp, next form 400000/515000, +-- next form 300000/515000, next form 200000/515000, and last 100000/515000 + +function UrmahlulluChanges.onHealthChange(creature, attacker, primaryDamage, primaryType, + secondaryDamage, secondaryType) + if creature:getName() == 'Urmahlullu the Immaculate' then + if creature:getHealth()<=400000 then + position=creature:getPosition() + creature:remove() + Game.createMonster('Wildness of Urmahlullu', position, true, true) + time=os.time() + -- make change and start counter (~ 1 minute) + end + end + if creature:getName() == 'Wildness of Urmahlullu' then + if creature:getHealth()<=300000 then + if os.time()<=time+timetochange then + position=creature:getPosition() + creature:remove() + Game.createMonster('Urmahlullu the Tamed', position, true, true) + time=os.time() + -- make change to urmahlullu the tamed and start new count (~1 minute) + else + position=creature:getPosition() + creature:remove() + Game.createMonster('Urmahlullu the Immaculate', position, true, true) + -- back to wildness of urmahlullu + end + end + end + if creature:getName() == 'Urmahlullu the Tamed' then + if creature:getHealth()<=200000 then + if os.time()<=time+timetochange then + position=creature:getPosition() + creature:remove() + Game.createMonster('Wisdom of Urmahlullu', position, true, true) + time=os.time() + -- make change to wisdom of urmahlullu and start new count (~1 minute) + else + position=creature:getPosition() + creature:remove() + Game.createMonster('Wildness of Urmahlullu', position, true, true) + time=os.time() + -- back to wildness of urmahlullu + end + end + end + if creature:getName() == 'Wisdom of Urmahlullu' then + if creature:getHealth()<=100000 then + if os.time()<=time+timetochange then + position=creature:getPosition() + creature:remove() + Game.createMonster('Urmahlullu the Weakened', position, true, true) + time=os.time() + -- make change to urmahlullu the weakened and start new count (~1 minute) + else + position=creature:getPosition() + creature:remove() + Game.createMonster('Urmahlullu the Tamed', position, true, true) + time=os.time() + --back to urmahlullu the tamed + end + end + end + return primaryDamage, primaryType, secondaryDamage, secondaryType +end + +function WeakenedDeath.onDeath(creature, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified) + if creature:getName()=='Urmahlullu the Weakened' then + if os.time()>time+timetochange then + position=creature:getPosition() + for _, tab in ipairs(config) do + local item = Tile(position):getItemById(tab.itemId) + if item then + item:remove() + end + end + Game.createMonster('Wisdom of Urmahlullu', position, true, true) + time=os.time() + end + end + return true +end + +UrmahlulluChanges:register() +WeakenedDeath:register() diff --git a/data/scripts/creaturescripts/monster/white_deer.lua b/data/scripts/creaturescripts/monster/white_deer.lua new file mode 100644 index 00000000000..f4e62d9cd67 --- /dev/null +++ b/data/scripts/creaturescripts/monster/white_deer.lua @@ -0,0 +1,27 @@ +local config = { + -- ordered by chance, the last chance being 100 + {chance = 30, monster = 'Enraged White Deer', message = 'The white deer summons all his strength and turns to fight!'}, + {chance = 100, monster = 'Desperate White Deer', message = 'The white deer desperately tries to escape!'} +} + +local whiteDeerDeath = CreatureEvent("WhiteDeerDeath") +function whiteDeerDeath.onDeath(creature, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified) + local targetMonster = creature:getMonster() + if not targetMonster or targetMonster:getMaster() then + return true + end + + local chance = math.random(100) + for i = 1, #config do + if chance <= config[i].chance then + local spawnMonster = Game.createMonster(config[i].monster, targetMonster:getPosition(), true, true) + if spawnMonster then + spawnMonster:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + targetMonster:say(config[i].message, TALKTYPE_MONSTER_SAY) + end + break + end + end + return true +end +whiteDeerDeath:register() diff --git a/data/scripts/creaturescripts/monster/white_deer_scout.lua b/data/scripts/creaturescripts/monster/white_deer_scout.lua new file mode 100644 index 00000000000..ae38878fa9d --- /dev/null +++ b/data/scripts/creaturescripts/monster/white_deer_scout.lua @@ -0,0 +1,20 @@ +local whiteDeerScoutsDeath = CreatureEvent("WhiteDeerScoutsDeath") +function whiteDeerScoutsDeath.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + local targetMonster = creature:getMonster() + if not targetMonster or targetMonster:getMaster() then + return true + end + + local chance = math.random(100) + if chance <= 10 then + for i = 1, 2 do + local spawnMonster = Game.createMonster('Elf Scout', targetMonster:getPosition(), true, true) + if spawnMonster then + spawnMonster:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + + targetMonster:say('The elves came too late to save the deer, however they might avenge it.', TALKTYPE_MONSTER_SAY) + end +end +whiteDeerScoutsDeath:register() diff --git a/data/scripts/creaturescripts/monster/white_pale_heal.lua b/data/scripts/creaturescripts/monster/white_pale_heal.lua new file mode 100644 index 00000000000..25ffaac01ae --- /dev/null +++ b/data/scripts/creaturescripts/monster/white_pale_heal.lua @@ -0,0 +1,20 @@ +local condition = Condition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) +condition:setParameter(CONDITION_PARAM_SUBID, 88888) +condition:setParameter(CONDITION_PARAM_TICKS, 15 * 60 * 1000) +condition:setParameter(CONDITION_PARAM_HEALTHGAIN, 0.01) +condition:setParameter(CONDITION_PARAM_HEALTHTICKS, 15 * 60 * 1000) + +local whitePaleHeal = CreatureEvent("WhitePaleHeal") +function whitePaleHeal.onPrepareDeath(creature, lastHitKiller, mostDamageKiller) + if creature:getName():lower() == "white pale" then + if not creature:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, 88888) then + creature:addCondition(condition) + creature:addHealth(400) + return + end + else + return + end + return true +end +whitePaleHeal:register() diff --git a/data/scripts/creaturescripts/monster/wyda.lua b/data/scripts/creaturescripts/monster/wyda.lua new file mode 100644 index 00000000000..84f143acf97 --- /dev/null +++ b/data/scripts/creaturescripts/monster/wyda.lua @@ -0,0 +1,5 @@ +local wyda = CreatureEvent("Wyda") +function wyda.onDeath(creature, corpse, killer, mostDamage, unjustified, mostDamage_unjustified) + creature:say("It seems this was just an illusion.", TALKTYPE_ORANGE_1) +end +wyda:register() diff --git a/data/scripts/creaturescripts/monster/zavarash_hide.lua b/data/scripts/creaturescripts/monster/zavarash_hide.lua new file mode 100644 index 00000000000..e28302c1c8b --- /dev/null +++ b/data/scripts/creaturescripts/monster/zavarash_hide.lua @@ -0,0 +1,30 @@ +local condition = Condition(CONDITION_INVISIBLE) +condition:setParameter(CONDITION_PARAM_TICKS, 10000) + +local condition2 = Condition(CONDITION_OUTFIT) +condition2:setTicks(-1) +condition2:setOutfit({lookTypeEx = 1548}) + +local zavarashHide = CreatureEvent("ZavarashHide") +function zavarashHide.onThink(creature) + local hp, cpos = (creature:getHealth()/creature:getMaxHealth())*100, creature:getPosition() + + if creature:getName():lower() == "zavarash" and (hp < 100) then + creature:addCondition(condition) + creature:addCondition(condition2) + creature:setHiddenHealth(creature) + end + if creature:getCondition(CONDITION_POISON, CONDITIONID_COMBAT) or + creature:getCondition(CONDITION_FIRE, CONDITIONID_COMBAT) or + creature:getCondition(CONDITION_ENERGY, CONDITIONID_COMBAT) or + creature:getCondition(CONDITION_BLEEDING, CONDITIONID_COMBAT) or + creature:getCondition(CONDITION_DAZZLED, CONDITIONID_COMBAT) then + creature:setOutfit({lookType=12,lookHead=0,lookAddons=0,lookLegs=57,lookBody=15,lookFeet=85}, -1) + creature:removeCondition(CONDITION_INVISIBLE) + creature:removeCondition(CONDITION_OUTFIT) + creature:setHiddenHealth(false) + return + end + return true +end +zavarashHide:register() diff --git a/data/scripts/creaturescripts/others/advance_save.lua b/data/scripts/creaturescripts/others/advance_save.lua new file mode 100644 index 00000000000..4742018ce08 --- /dev/null +++ b/data/scripts/creaturescripts/others/advance_save.lua @@ -0,0 +1,27 @@ +local config = { + heal = true, + save = true, + effect = false +} + +local advanceSave = CreatureEvent("AdvanceSave") +function advanceSave.onAdvance(player, skill, oldLevel, newLevel) + if skill ~= SKILL_LEVEL or newLevel <= oldLevel then + return true + end + + if config.effect then + player:getPosition():sendMagicEffect(math.random(CONST_ME_FIREWORK_YELLOW, CONST_ME_FIREWORK_BLUE)) + player:say('LEVEL UP!', TALKTYPE_MONSTER_SAY) + end + + if config.heal then + player:addHealth(player:getMaxHealth()) + end + + if config.save then + player:save() + end + return true +end +advanceSave:register() \ No newline at end of file diff --git a/data/scripts/creaturescripts/others/adventure_blessing_login.lua b/data/scripts/creaturescripts/others/adventure_blessing_login.lua new file mode 100644 index 00000000000..c2a5ea3ed41 --- /dev/null +++ b/data/scripts/creaturescripts/others/adventure_blessing_login.lua @@ -0,0 +1,9 @@ +dofile('data/modules/scripts/blessings/blessings.lua') + +local adventurerBlessingLogin = CreatureEvent("AdventurerBlessingLogin") +function adventurerBlessingLogin.onLogin(cid) + local player = Player(cid) + return Blessings.doAdventurerBlessing(player) +end + +adventurerBlessingLogin:register() diff --git a/data/scripts/creaturescripts/others/bestiary_kill.lua b/data/scripts/creaturescripts/others/bestiary_kill.lua new file mode 100644 index 00000000000..53a047202dd --- /dev/null +++ b/data/scripts/creaturescripts/others/bestiary_kill.lua @@ -0,0 +1,16 @@ +local bestiaryOnKill = CreatureEvent("BestiaryOnKill") +function bestiaryOnKill.onKill(player, creature, lastHit) + if not player:isPlayer() or not creature:isMonster() or creature:hasBeenSummoned() or creature:isPlayer() then + return true + end + + for cid, damage in pairs(creature:getDamageMap()) do + local participant = Player(cid) + if participant and participant:isPlayer() then + participant:addBestiaryKill(creature:getName()) + end + end + + return true +end +bestiaryOnKill:register() diff --git a/data/scripts/creaturescripts/others/boss_reward_chest.lua b/data/scripts/creaturescripts/others/boss_reward_chest.lua new file mode 100644 index 00000000000..59055c2bcc1 --- /dev/null +++ b/data/scripts/creaturescripts/others/boss_reward_chest.lua @@ -0,0 +1,259 @@ +local function pushSeparated(buffer, sep, ...) + local argv = {...} + local argc = #argv + for k, v in ipairs(argv) do + table.insert(buffer, v) + if k < argc and sep then + table.insert(buffer, sep) + end + end +end + +local function insertItems(buffer, info, parent, items) + local start = info.running + for _, item in ipairs(items) do + if item ~= nil then + if _ ~= 1 or parent > 100 then + table.insert(buffer, ",") + end + info.running = info.running + 1 + table.insert(buffer, "(") + pushSeparated(buffer, ",", info.playerGuid, parent, info.running, item:getId(), item:getSubType(), db.escapeString(serializeAttributes(item))) + table.insert(buffer, ")") + + if item:isContainer() then + local size = item:getSize() + if size > 0 then + local subItems = {} + for i = 1, size do + table.insert(subItems, item:getItem(i - 1)) + end + + insertItems(buffer, info, info.running, subItems) + end + end + end + end + return info.running - start +end + +local function insertRewardItems(playerGuid, timestamp, itemList) + db.asyncStoreQuery('select `pid`, `sid` from `player_rewards` where player_id = ' .. playerGuid .. ' order by `sid` ASC;', + function(query) + local lastReward = 0 + local lastStoreId + if(query) then + repeat + local sid = result.getDataInt(query, 'sid') + local pid = result.getDataInt(query, 'pid') + + if pid < 100 then + lastReward = pid + end + lastStoreId = sid + until not result.next(query) + end + + local buffer = {'INSERT INTO `player_rewards` (`player_id`, `pid`, `sid`, `itemtype`, `count`, `attributes`) VALUES'} + + --reward bag + local info = { + playerGuid = playerGuid, + running = lastStoreId or 100 + } + + local bag = Game.createItem(ITEM_REWARD_CONTAINER) + bag:setAttribute(ITEM_ATTRIBUTE_DATE, timestamp) + if itemList then + for _, p in ipairs(itemList) do + bag:addItem(p[1], p[2]) + end + end + + local total = insertItems(buffer, info, lastReward + 1, {bag}) + table.insert(buffer, ";") + + if total ~= 0 then + db.query(table.concat(buffer)) + end + end + ) +end + +local function getPlayerStats(bossId, playerGuid, autocreate) + local ret = globalBosses[bossId][playerGuid] + if not ret and autocreate then + ret = { + bossId = bossId, + damageIn = 0, -- damage taken from the boss + healing = 0, -- healing (other players) done + } + globalBosses[bossId][playerGuid] = ret + return ret + end + return ret +end + +local function resetAndSetTargetList(creature) + if not creature then + return + end + + local bossId = creature:getId() + local info = globalBosses[bossId] + -- Reset all players' status + for _, player in pairs(info) do + player.active = false + end + -- Set all players in boss' target list as active in the fight + local targets = creature:getTargetList() + for _, target in ipairs(targets) do + if target:isPlayer() then + local stats = getPlayerStats(bossId, target:getGuid(), true) + stats.playerId = target:getId() -- Update player id + stats.active = true + end + end +end + +local bossDeath = CreatureEvent("BossDeath") +function bossDeath.onDeath(creature, corpse, killer, mostDamageKiller, lastHitUnjustified, mostDamageUnjustified) + -- player + if not creature or creature:isPlayer() then + return true + end + + -- Deny summons + if creature:getMaster() then + return true + end + + -- boss + local monsterType = creature:getType() + if monsterType and monsterType:isRewardBoss() then -- Make sure it is a boss + local bossId = creature:getId() + local timestamp = os.time() + + resetAndSetTargetList(creature) + + local totalDamageOut, totalDamageIn, totalHealing = 0.1, 0.1, 0.1 -- avoid dividing by zero + + local scores = {} + local info = globalBosses[bossId] + local damageMap = creature:getDamageMap() + + for guid, stats in pairs(info) do + local player = Player(stats.playerId) + local part = damageMap[stats.playerId] + local damageOut, damageIn, healing = (stats.damageOut or 0) + (part and part.total or 0), stats.damageIn or 0, stats.healing or 0 + + totalDamageOut = totalDamageOut + damageOut + totalDamageIn = totalDamageIn + damageIn + totalHealing = totalHealing + healing + + table.insert(scores, { + player = player, + guid = guid, + damageOut = damageOut, + damageIn = damageIn, + healing = healing, + }) + end + + local participants = 0 + for _, con in ipairs(scores) do + local score = (con.damageOut / totalDamageOut) + (con.damageIn / totalDamageIn) + (con.healing / totalHealing) + con.score = score / 3 -- normalize to 0-1 + if score ~= 0 then + participants = participants + 1 + end + end + table.sort(scores, function(a, b) return a.score > b.score end) + + local expectedScore = 1 / participants + + for _, con in ipairs(scores) do + local reward, stamina -- ignoring stamina for now because I heard you get receive rewards even when it's depleted + if con.player then + reward = con.player:getReward(timestamp, true) + stamina = con.player:getStamina() + else + stamina = con.stamina or 0 + end + + local playerLoot + if --[[stamina > 840 and]] con.score ~= 0 then + local lootFactor = 1 + lootFactor = lootFactor / participants ^ (1 / 3) -- tone down the loot a notch if there are many participants + lootFactor = lootFactor * (1 + lootFactor) ^ (con.score / expectedScore) -- increase the loot multiplicatively by how many times the player surpassed the expected score + playerLoot = monsterType:getBossReward(lootFactor, _ == 1) + + if con.player then + for _, p in ipairs(playerLoot) do + reward:addItem(p[1], p[2]) + end + end + end + + if con.player and con.score ~= 0 then + local lootMessage = ("The following items dropped by %s are available in your reward chest: %s"):format(creature:getName(), reward:getContentDescription()) + + if stamina > 840 then + reward:getContentDescription(lootMessage) + end + con.player:sendTextMessage(MESSAGE_LOOT, lootMessage) + elseif con.score ~= 0 then + insertRewardItems(con.guid, timestamp, playerLoot) + end + end + + globalBosses[bossId] = nil + end + return true +end +bossDeath:register() + +local bossThink = CreatureEvent("BossThink") +function bossThink.onThink(creature, interval) + resetAndSetTargetList(creature) +end +bossThink:register() + +local bossParticipation = CreatureEvent("BossParticipation") +function bossParticipation.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin) + if not next(globalBosses) then + return primaryDamage, primaryType, secondaryDamage, secondaryType + end + + if not creature or not attacker then + return primaryDamage, primaryType, secondaryDamage, secondaryType + end + + local stats = creature:inBossFight() + if not stats then + return primaryDamage, primaryType, secondaryDamage, secondaryType + end + + local creatureId, attackerId = creature:getId(), attacker:getId() + stats.playerId = creatureId -- Update player id + + -- Account for healing of others active in the boss fight + if primaryType == COMBAT_HEALING and attacker:isPlayer() and attackerId ~= creatureId then + local healerStats = getPlayerStats(stats.bossId, attacker:getGuid(), true) + healerStats.active = true + healerStats.playerId = attackerId -- Update player id + healerStats.healing = healerStats.healing + primaryDamage + elseif stats.bossId == attackerId then + -- Account for damage taken from the boss + stats.damageIn = stats.damageIn + primaryDamage + end + return primaryDamage, primaryType, secondaryDamage, secondaryType +end +bossParticipation:register() + +local loginBossPlayer = CreatureEvent("LoginBossPlayer") +function loginBossPlayer.onLogin(player) + player:registerEvent("BossDeath") + return true +end +loginBossPlayer:register() diff --git a/data/scripts/creaturescripts/others/dawnport.lua b/data/scripts/creaturescripts/others/dawnport.lua new file mode 100644 index 00000000000..55a452be440 --- /dev/null +++ b/data/scripts/creaturescripts/others/dawnport.lua @@ -0,0 +1,54 @@ +-- Teleport to the dawnport temple after reaching level 20 (the player has five minutes before being teleported) +local function teleportToDawnportTemple(uid) + local player = Player(uid) + -- If not have the Oressa storage, teleport player to the temple + if player and player:getStorageValue(Storage.Dawnport.DoorVocation) == -1 then + player:teleportTo(player:getTown():getTemplePosition()) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end +end + +local dawnportAdvance = CreatureEvent("DawnportAdvance") + +function dawnportAdvance.onAdvance(player, skill, oldLevel, newLevel) + local town = player:getTown() + -- Check that resides on dawnport + if town and town:getId() == TOWNS_LIST.DAWNPORT then + if skill == SKILL_LEVEL then + -- Notify min level to leave dawnport + if newLevel == 8 then + player:sendTextMessage( + MESSAGE_EVENT_ADVANCE, + "Congratulations! \z + You may now choose your vocation and leave Dawnport. Talk to Oressa in the temple." + ) + -- Notify max level to stay in dawnport + elseif newLevel >= 20 then + player:sendTextMessage( + MESSAGE_EVENT_ADVANCE, + "You have reached the limit level and have to choose your vocation and leave Dawnport." + ) + -- Adds the event that teleports the player to the temple in five minutes after reaching level 20 + addEvent(teleportToDawnportTemple, 5 * 60 * 1000, player:getId()) + end + -- Notify reached a skill limit + elseif skill ~= SKILL_LEVEL and isSkillGrowthLimited(player, skill) then + if skill == SKILL_MAGLEVEL then + player:sendTextMessage( + MESSAGE_EVENT_ADVANCE, + "You cannot train your magic level any further. \z + If you want to improve it further, you must go to the mainland." + ) + else + player:sendTextMessage( + MESSAGE_EVENT_ADVANCE, + "You cannot train your skill level any further. \z + If you want to improve it further, you must go to the mainland." + ) + end + end + end + return true +end + +dawnportAdvance:register() diff --git a/data/scripts/creaturescripts/others/droploot.lua b/data/scripts/creaturescripts/others/droploot.lua new file mode 100644 index 00000000000..3a5d57130a5 --- /dev/null +++ b/data/scripts/creaturescripts/others/droploot.lua @@ -0,0 +1,15 @@ +dofile('data/modules/scripts/blessings/blessings.lua') +local dropLoot = CreatureEvent("DropLoot") +function dropLoot.onDeath(player, corpse, killer, mostDamage, unjustified, mostDamage_unjustified) + local town = player:getTown() + if town and town:getId() == TOWNS_LIST.DAWNPORT and player:getLevel() < 8 then + return true + end + + if player:hasFlag(PlayerFlag_NotGenerateLoot) then + return true + end + Blessings.DebugPrint("onDeath DROPLOOT EVENT DropLoot") + return Blessings.PlayerDeath(player, corpse, killer) +end +dropLoot:register() diff --git a/data/scripts/creaturescripts/others/familiars.lua b/data/scripts/creaturescripts/others/familiars.lua new file mode 100644 index 00000000000..c222cbb8712 --- /dev/null +++ b/data/scripts/creaturescripts/others/familiars.lua @@ -0,0 +1,116 @@ +local familiar = { + [VOCATION.CLIENT_ID.SORCERER] = {id = 994, name = "Sorcerer familiar"}, + [VOCATION.CLIENT_ID.DRUID] = {id = 993, name = "Druid familiar"}, + [VOCATION.CLIENT_ID.PALADIN] = {id = 992, name = "Paladin familiar"}, + [VOCATION.CLIENT_ID.KNIGHT] = {id = 991, name = "Knight familiar"} +} + +local timer = { + [1] = {storage=Storage.PetSummonEvent10, countdown=10, message = "10 seconds"}, + [2] = {storage=Storage.PetSummonEvent60, countdown=60, message = "one minute"} +} + +local function sendMessageFunction(pid, message) + if Player(pid) then + Player(pid):sendTextMessage(MESSAGE_LOOT, "Your summon will disappear in less than " .. message) + end +end + +local function removePet(creatureId, playerId) + local creature = Creature(creatureId) + local player = Player(playerId) + if not creature or not player then + return true + end + creature:remove() + for sendMessage = 1, #timer do + player:setStorageValue(timer[sendMessage].storage, -1) + end +end + +local familiarStorage = Storage.PetSummon + +local familiarLogin = CreatureEvent("FamiliarLogin") + +function familiarLogin.onLogin(player) + local vocation = familiar[player:getVocation():getClientId()] + local familiarName + local petTimeLeft = player:getStorageValue(familiarStorage) - player:getLastLogout() + + if vocation then + if (not isPremium(player) and player:hasFamiliar(vocation.id)) or player:getLevel() < 200 then + player:removeFamiliar(vocation.id) + elseif isPremium(player) and player:getLevel() >= 200 then + if petTimeLeft > 0 then + familiarName = vocation.name + end + if player:getFamiliarLooktype() == 0 then + player:setFamiliarLooktype(vocation.id) + end + if not player:hasFamiliar(vocation.id) then + player:addFamiliar(vocation.id) + end + end + end + + if familiarName then + position = player:getPosition() + local familiarMonster = Game.createMonster(familiarName, position, true, false) + player:addSummon(familiarMonster) + familiarMonster:setOutfit({lookType = player:getFamiliarLooktype()}) + --familiarMonster:reload() + local deltaSpeed = math.max(player:getSpeed() - familiarMonster:getSpeed(), 0) + familiarMonster:changeSpeed(deltaSpeed) + player:setStorageValue(familiarStorage, os.time() + petTimeLeft) + familiarMonster:registerEvent("FamiliarDeath") + position:sendMagicEffect(CONST_ME_MAGIC_BLUE) + addEvent(removePet, petTimeLeft*1000, familiarMonster:getId(), player:getId()) + for sendMessage = 1, #timer do + if player:getStorageValue(timer[sendMessage].storage) == -1 and petTimeLeft >= timer[sendMessage].countdown then + player:setStorageValue(timer[sendMessage].storage, addEvent(sendMessageFunction, (petTimeLeft-timer[sendMessage].countdown)*1000, player:getId(), timer[sendMessage].message)) + end + end + end + return true +end + +familiarLogin:register() + +local advanceFamiliar = CreatureEvent("AdvanceFamiliar") + +function advanceFamiliar.onAdvance(player, skill, oldLevel, newLevel) + local vocation = familiar[player:getVocation():getClientId()] + if newLevel >= 200 and isPremium(player) then + if player:getFamiliarLooktype() == 0 then + player:setFamiliarLooktype(vocation.id) + end + if not player:hasFamiliar(vocation.id) then + player:addFamiliar(vocation.id) + end + end + return true +end + +advanceFamiliar:register() + +local familiarDeath = CreatureEvent("FamiliarDeath") + +function familiarDeath.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, + mostdamageunjustified) + local player = creature:getMaster() + if not player then + return false + end + local vocation = familiar[player:getVocation():getClientId()] + + if table.contains(vocation, creature:getName()) then + player:setStorageValue(familiarStorage, os.time()) + for sendMessage = 1, #timer do + stopEvent(player:getStorageValue(timer[sendMessage].storage)) + player:setStorageValue(timer[sendMessage].storage, -1) + end + end + return true +end + +familiarDeath:register() diff --git a/data/scripts/creaturescripts/others/hireling_logout.lua b/data/scripts/creaturescripts/others/hireling_logout.lua new file mode 100644 index 00000000000..6dfd9ca7c5b --- /dev/null +++ b/data/scripts/creaturescripts/others/hireling_logout.lua @@ -0,0 +1,6 @@ +local hirelingLogoutPlayer = CreatureEvent("HirelingLogoutPlayer") +function hirelingLogoutPlayer.onLogout(player) + player:copyHirelingStorageToCache() + return true +end +hirelingLogoutPlayer:register() diff --git a/data/scripts/creaturescripts/others/login.lua b/data/scripts/creaturescripts/others/login.lua new file mode 100644 index 00000000000..cc92ec714c3 --- /dev/null +++ b/data/scripts/creaturescripts/others/login.lua @@ -0,0 +1,234 @@ +local function onMovementRemoveProtection(cid, oldPos, time) + local player = Player(cid) + if not player then + return true + end + + local playerPos = player:getPosition() + if (playerPos.x ~= oldPos.x or playerPos.y ~= oldPos.y or playerPos.z ~= oldPos.z) or player:getTarget() then + player:setStorageValue(Storage.combatProtectionStorage, 0) + return true + end + + addEvent(onMovementRemoveProtection, 1000, cid, oldPos, time - 1) +end + +local function protectionZoneCheck(playerName) + doRemoveCreature(playerName) + return true +end + +local playerLogin = CreatureEvent("PlayerLogin") + +function playerLogin.onLogin(player) + local items = { + {2120, 1}, + {2148, 3} + } + if player:getLastLoginSaved() == 0 then + player:sendOutfitWindow() + local backpack = player:addItem(1988) + if backpack then + for i = 1, #items do + backpack:addItem(items[i][1], items[i][2]) + end + end + player:addItem(2050, 1, true, 1, CONST_SLOT_AMMO) + db.query('UPDATE `players` SET `istutorial` = 0 where `id`='..player:getGuid()) + else + player:sendTextMessage(MESSAGE_STATUS, "Welcome to " .. SERVER_NAME .. "!") + player:sendTextMessage(MESSAGE_LOGIN, string.format("Your last visit in ".. SERVER_NAME ..": %s.", os.date("%d. %b %Y %X", player:getLastLoginSaved()))) + end + + local playerId = player:getId() + + -- kick other players from account + if configManager.getBoolean(configKeys.ONE_PLAYER_ON_ACCOUNT) then + local resultId = db.storeQuery("SELECT players.name FROM `players` INNER JOIN `players_online` WHERE players_online.player_id=players.id and players_online.player_id!=" .. player:getGuid() .. " and players.account_id=" .. player:getAccountId()) + if resultId ~= false then + repeat + if player:getAccountType() <= ACCOUNT_TYPE_GOD and player:getGroup():getId() < GROUP_TYPE_GOD then + local name = result.getDataString(resultId, "name") + if getCreatureCondition(Player(name), CONDITION_INFIGHT) == false then + Player(name):remove() + else + addEvent(protectionZoneCheck, 2000, player:getName()) + doPlayerPopupFYI(player, "You cant login now.") + end + end + until not result.next(resultId) + result.free(resultId) + end + end + -- End kick other players from account + if isPremium(player) then + player:setStorageValue(Storage.PremiumAccount, 1) + end + -- Premium Ends Teleport to Temple, change addon (citizen) houseless + local defaultTown = "Thais" -- default town where player is teleported if his home town is in premium area + local freeTowns = {"Ab'Dendriel", "Carlin", "Kazordoon", "Thais", "Venore", "Rookgaard", "Dawnport", "Dawnport Tutorial", "Island of Destiny"} -- towns in free account area + + if isPremium(player) == false and isInArray(freeTowns, player:getTown():getName()) == false then + local town = player:getTown() + local sex = player:getSex() + local home = getHouseByPlayerGUID(getPlayerGUID(player)) + town = isInArray(freeTowns, town:getName()) and town or Town(defaultTown) + player:teleportTo(town:getTemplePosition()) + player:setTown(town) + player:sendTextMessage(MESSAGE_FAILURE, "Your premium time has expired.") + player:setStorageValue(Storage.PremiumAccount, 0) + if sex == 1 then + player:setOutfit({lookType = 128, lookFeet = 114, lookLegs = 134, lookHead = 114,lookAddons = 0}) + elseif sex == 0 then + player:setOutfit({lookType = 136, lookFeet = 114, lookLegs = 134, lookHead = 114, lookAddons = 0}) + end + if home ~= nil and not isPremium(player) then + setHouseOwner(home, 0) + player:sendTextMessage(MESSAGE_GAME_HIGHLIGHT, 'You\'ve lost your house because you are not premium anymore.') + player:sendTextMessage(MESSAGE_GAME_HIGHLIGHT, 'Your items from house are send to your inbox.') + end + end + -- End 'Premium Ends Teleport to Temple' + + -- Recruiter system + local resultId = db.storeQuery('SELECT `recruiter` from `accounts` where `id`='..getAccountNumberByPlayerName(getPlayerName(player))) + local recruiterStatus = result.getNumber(resultId, 'recruiter') + local sex = player:getSex() + if recruiterStatus >= 1 then + if sex == 1 then + local outfit = player:hasOutfit(746) + if outfit == false then + player:addOutfit(746) + end + else + local outfit = player:hasOutfit(745) + if outfit == false then + player:addOutfit(745) + end + end + end + if recruiterStatus >= 3 then + if sex == 1 then + local outfit = player:hasOutfit(746,1) + if outfit == false then + player:addOutfitAddon(746,1) + end + else + local outfit = player:hasOutfit(745,1) + if outfit == false then + player:addOutfit(745,1) + end + end + end + if recruiterStatus >= 10 then + if sex == 1 then + local outfit = player:hasOutfit(746,2) + if outfit == false then + player:addOutfitAddon(746,2) + end + else + local outfit = player:hasOutfit(745,2) + if outfit == false then + player:addOutfit(745,2) + end + end + end + -- End recruiter system + + DailyReward.init(playerId) + + player:loadSpecialStorage() + + if player:getGroup():getId() >= GROUP_TYPE_GAMEMASTER then + player:setGhostMode(true) + end + -- Boosted creature + player:sendTextMessage(MESSAGE_BOOSTED_CREATURE, "Today's boosted creature: " .. Game.getBoostedCreature() .. " \ + Boosted creatures yield more experience points, carry more loot than usual and respawn at a faster rate.") + + -- Stamina + nextUseStaminaTime[playerId] = 1 + + -- EXP Stamina + nextUseXpStamina[playerId] = 1 + + -- Prey Small Window + for slot = CONST_PREY_SLOT_FIRST, CONST_PREY_SLOT_THIRD do + player:sendPreyData(slot) + end + + -- New prey + nextPreyTime[playerId] = { + [CONST_PREY_SLOT_FIRST] = 1, + [CONST_PREY_SLOT_SECOND] = 1, + [CONST_PREY_SLOT_THIRD] = 1 + } + + if (player:getAccountType() == ACCOUNT_TYPE_TUTOR) then + local msg = [[:: Tutor Rules + 1 *> 3 Warnings you lose the job. + 2 *> Without parallel conversations with players in Help, if the player starts offending, you simply mute it. + 3 *> Be educated with the players in Help and especially in the Private, try to help as much as possible. + 4 *> Always be on time, if you do not have a justification you will be removed from the staff. + 5 *> Help is only allowed to ask questions related to tibia. + 6 *> It is not allowed to divulge time up or to help in quest. + 7 *> You are not allowed to sell items in the Help. + 8 *> If the player encounters a bug, ask to go to the website to send a ticket and explain in detail. + 9 *> Always keep the Tutors Chat open. (required). + 10 *> You have finished your schedule, you have no tutor online, you communicate with some CM in-game + or ts and stay in the help until someone logs in, if you can. + 11 *> Always keep a good Portuguese in the Help, we want tutors who support, not that they speak a satanic ritual. + 12 *> If you see a tutor doing something that violates the rules, take a print and send it to your superiors. " + - Commands - + Mute Player: /mute nick, 90 (90 seconds) + Unmute Player: /unmute nick. + - Commands -]] + player:popupFYI(msg) + end + + -- Open channels + if table.contains({TOWNS_LIST.DAWNPORT, TOWNS_LIST.DAWNPORT_TUTORIAL}, player:getTown():getId())then + player:openChannel(3) -- World chat + else + player:openChannel(3) -- World chat + player:openChannel(5) -- Advertsing main + end + + -- Rewards + local rewards = #player:getRewardList() + if(rewards > 0) then + player:sendTextMessage(MESSAGE_LOGIN, string.format("You have %d %s in your reward chest.", + rewards, rewards > 1 and "rewards" or "reward")) + end + + -- Update player id + local stats = player:inBossFight() + if stats then + stats.playerId = player:getId() + end + + if player:getStorageValue(Storage.combatProtectionStorage) < 1 then + player:setStorageValue(Storage.combatProtectionStorage, 1) + onMovementRemoveProtection(playerId, player:getPosition(), 10) + end + -- Set Client XP Gain Rate + local baseExp = 100 + if Game.getStorageValue(GlobalStorage.XpDisplayMode) > 0 then + baseExp = getRateFromTable(experienceStages, player:getLevel(), configManager.getNumber(configKeys.RATE_EXP)) + end + + local staminaMinutes = player:getStamina() + local doubleExp = false --Can change to true if you have double exp on the server + local staminaBonus = (staminaMinutes > 2340) and 150 or ((staminaMinutes < 840) and 50 or 100) + if doubleExp then + baseExp = baseExp * 2 + end + player:setStaminaXpBoost(staminaBonus) + player:setBaseXpGain(baseExp) + + if player:getStorageValue(Storage.isTraining) == 1 then --Reset exercise weapon storage + player:setStorageValue(Storage.isTraining,0) + end + return true +end +playerLogin:register() diff --git a/data/scripts/creaturescripts/others/login_events.lua b/data/scripts/creaturescripts/others/login_events.lua new file mode 100644 index 00000000000..9caca90c730 --- /dev/null +++ b/data/scripts/creaturescripts/others/login_events.lua @@ -0,0 +1,108 @@ +local loginEvents = CreatureEvent("LoginEvents") +function loginEvents.onLogin(player) + + local events = { + --Monster + "LowerRoshamuul", + --Others + "AdvanceSave", + "BestiaryOnKill", + "BossParticipation", + "DropLoot", + "PlayerDeath", + "PreyLootBonusKill", + "RookgaardAdvance", + "FamiliarLogin", + "AdvanceFamiliar", + --Quests + --Adventurers Guild Quest + "Thegreatdragonhuntkill", + --Bigfoot Burden Quest + "BossesWarzone", + "ParasiteWarzone", + "VersperothKill", + "WigglerKill", + --Cults Of Tibia Quest + "BossesCults", + "MinotaurTask", + "VortexCarlin", + "LeidenHeal", + "GlowingRubbishAmulet", + "DestroyedPillar", + "HealthPillar", + "YalahariHealth", + --Dangerous Depths Quest + "LostExileKill", + "SnailSlimeKill", + "TheBaronFromBelowKill", + --Dawnport Quest + "MorrisMinotaurKill", + "MorrisGoblinKill", + "MorrisTrollKill", + --Elemental Spheres Quest + "OverlordKill", + --Ferumbras Ascendant Quest + "AscendantBossesKill", + "TheShattererKill", + --Firewalker Boots + "PythiusTheRottenKill", + --Forgotten Knowledge Quest + "BossesForgottenKill", + "AstralPower", + "EnergyPrismDeath", + "ReplicaServant", + --Hero Of Rathleton + "RathletonBossKill", + --Secret Service + "BlackKnightKill", + --Service Of Yalahar + "DiseasedTrio", + "Azerus", + "QuaraLeaders", + --Inquisition + "InquisitionBossKill", + "UngreezKill", + --Killing In The Name Of + "KillingInTheNameOfKill", + "KillingInTheNameOfMinotaurKill", + --Kilmaresh + "BragrumolKill", + "MozradekKill", + "XogixathKill", + "FafnarKill", + --Liquid Black + "DeeplingBosses", + --Raging Mage Worldchange + "EnergizedRagingMageKill", + "RagingMageKill", + "YielothaxKill", + --Spike Tasks + "LowerSpikeKill", + "UpperSpikeKill", + "MiddleSpikeKill", + --Svargrond Arena + "SvargrondArenaKill", + --The First Dragon + "KillDragon", + "SomewhatBeatableDeath", + --The New Frontier + "ShardOfCorruptionKill", + "TireczKill", + --Thieves Guild + "NomadKill", + --Wrath of the Emperor + "LizardMagistratusKill", + "LizardNobleKill", + "KeeperKill", + "BossesKill", + "ZalamonKill", + -- The Rookie Guard + "VascalirRatKills" + } + + for i = 1, #events do + player:registerEvent(events[i]) + end + return true +end +loginEvents:register() diff --git a/data/scripts/creaturescripts/others/logout.lua b/data/scripts/creaturescripts/others/logout.lua new file mode 100644 index 00000000000..892039a0ab7 --- /dev/null +++ b/data/scripts/creaturescripts/others/logout.lua @@ -0,0 +1,25 @@ +local playerLogout = CreatureEvent("PlayerLogout") +function playerLogout.onLogout(player) + local playerId = player:getId() + if nextUseStaminaTime[playerId] ~= nil then + nextUseStaminaTime[playerId] = nil + end + player:saveSpecialStorage() + player:setStorageValue(Storage.ExerciseDummyExhaust, 0) + + local stats = player:inBossFight() + if stats then + local boss = Monster(stats.bossId) + -- Player logged out (or died) in the middle of a boss fight, store his damageOut and stamina + if boss then + local dmgOut = boss:getDamageMap()[playerId] + if dmgOut then + stats.damageOut = (stats.damageOut or 0) + dmgOut.total + end + stats.stamina = player:getStamina() + end + end + player:setStorageValue(17101,0) + return true +end +playerLogout:register() diff --git a/data/scripts/creaturescripts/others/modal_window_helper.lua b/data/scripts/creaturescripts/others/modal_window_helper.lua new file mode 100644 index 00000000000..3655044e9e5 --- /dev/null +++ b/data/scripts/creaturescripts/others/modal_window_helper.lua @@ -0,0 +1,33 @@ +local modalWindowHelper = CreatureEvent("ModalWindowHelper") +function modalWindowHelper.onModalWindow(player, modalWindowId, buttonId, choiceId) + local modalWindow + for _, window in ipairs(modalWindows.windows) do + if window.id == modalWindowId then + modalWindow = window + break + end + end + + if not modalWindow then + return true + end + + local playerId = player:getId() + if not modalWindow.players[playerId] then + return true + end + modalWindow.players[playerId] = nil + + local choice = modalWindow.choices[choiceId] + for _, button in ipairs(modalWindow.buttons) do + if button.id == buttonId then + local callback = button.callback or modalWindow.defaultCallback + if callback then + callback(button, choice) + break + end + end + end + return true +end +modalWindowHelper:register() diff --git a/data/scripts/creaturescripts/others/offline_training.lua b/data/scripts/creaturescripts/others/offline_training.lua new file mode 100644 index 00000000000..1843f811898 --- /dev/null +++ b/data/scripts/creaturescripts/others/offline_training.lua @@ -0,0 +1,77 @@ +local offlineTraining = CreatureEvent("OfflineTraining") +function offlineTraining.onLogin(player) + local lastLogout = player:getLastLogout() + local offlineTime = lastLogout ~= 0 and math.min(os.time() - lastLogout, 86400 * 21) or 0 + local offlineTrainingSkill = player:getOfflineTrainingSkill() + if offlineTrainingSkill == -1 then + player:addOfflineTrainingTime(offlineTime * 1000) + return true + end + + player:setOfflineTrainingSkill(-1) + + if offlineTime < 600 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + "You must be logged out for more than 10 minutes to start offline training.") + return true + end + + local trainingTime = math.max(0, math.min(offlineTime, math.min(43200, player:getOfflineTrainingTime() / 1000))) + player:removeOfflineTrainingTime(trainingTime * 1000) + + local remainder = offlineTime - trainingTime + if remainder > 0 then + player:addOfflineTrainingTime(remainder * 1000) + end + + if trainingTime < 60 then + return true + end + + local text = "During your absence you trained for" + local hours = math.floor(trainingTime / 3600) + if hours > 1 then + text = string.format("%s %d hours", text, hours) + elseif hours == 1 then + text = string.format("%s 1 hour", text) + end + + local minutes = math.floor((trainingTime % 3600) / 60) + if minutes ~= 0 then + if hours ~= 0 then + text = string.format("%s and", text) + end + + if minutes > 1 then + text = string.format("%s %d minutes", text, minutes) + else + text = string.format("%s 1 minute", text) + end + end + text = string.format("%s.", text) + player:sendTextMessage(MESSAGE_OFFLINE_TRAINING, text) + + local vocation = player:getVocation() + local promotion = vocation:getPromotion() + local topVocation = not promotion and vocation or promotion + + local updateSkill = false + if isInArray({SKILL_CLUB, SKILL_SWORD, SKILL_AXE, SKILL_DISTANCE}, offlineTrainingSkill) then + local modifier = topVocation:getAttackSpeed() / 1000 + updateSkill = player:addOfflineTrainingTries( + offlineTrainingSkill, (trainingTime / modifier) / (offlineTrainingSkill == SKILL_DISTANCE and 4 or 2)) + elseif offlineTrainingSkill == SKILL_MAGLEVEL then + local gainTicks = topVocation:getManaGainTicks() * 2 + if gainTicks == 0 then + gainTicks = 1 + end + + updateSkill = player:addOfflineTrainingTries(SKILL_MAGLEVEL, trainingTime * (vocation:getManaGainAmount() / gainTicks)) + end + + if updateSkill then + player:addOfflineTrainingTries(SKILL_SHIELD, trainingTime / 4) + end + return true +end +offlineTraining:register() diff --git a/data/scripts/creaturescripts/others/player_death.lua b/data/scripts/creaturescripts/others/player_death.lua new file mode 100644 index 00000000000..d1bbc95f0d9 --- /dev/null +++ b/data/scripts/creaturescripts/others/player_death.lua @@ -0,0 +1,93 @@ +local deathListEnabled = true + +local playerDeath = CreatureEvent("PlayerDeath") +function playerDeath.onDeath(player, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified) + local playerId = player:getId() + if nextUseStaminaTime[playerId] ~= nil then + nextUseStaminaTime[playerId] = nil + end + + player:sendTextMessage(MESSAGE_BEYOND_LAST, 'You are dead.') + if player:getStorageValue(Storage.SvargrondArena.PitDoor) > 0 then + player:setStorageValue(Storage.SvargrondArena.PitDoor, 0) + end + + if not deathListEnabled then + return + end + + local byPlayer = 0 + local killerName + if killer ~= nil then + if killer:isPlayer() then + byPlayer = 1 + else + local master = killer:getMaster() + if master and master ~= killer and master:isPlayer() then + killer = master + byPlayer = 1 + end + end + killerName = killer:isMonster() and killer:getType():getNameDescription() or killer:getName() + else + killerName = 'field item' + end + + local byPlayerMostDamage = 0 + local mostDamageKillerName + if mostDamageKiller ~= nil then + if mostDamageKiller:isPlayer() then + byPlayerMostDamage = 1 + else + local master = mostDamageKiller:getMaster() + if master and master ~= mostDamageKiller and master:isPlayer() then + mostDamageKiller = master + byPlayerMostDamage = 1 + end + end + mostDamageName = mostDamageKiller:isMonster() and mostDamageKiller:getType():getNameDescription() or mostDamageKiller:getName() + else + mostDamageName = 'field item' + end + + local playerGuid = player:getGuid() + db.query('INSERT INTO `player_deaths` (`player_id`, `time`, `level`, `killed_by`, `is_player`, `mostdamage_by`, `mostdamage_is_player`, `unjustified`, `mostdamage_unjustified`) VALUES (' .. playerGuid .. ', ' .. os.time() .. ', ' .. player:getLevel() .. ', ' .. db.escapeString(killerName) .. ', ' .. byPlayer .. ', ' .. db.escapeString(mostDamageName) .. ', ' .. byPlayerMostDamage .. ', ' .. (unjustified and 1 or 0) .. ', ' .. (mostDamageUnjustified and 1 or 0) .. ')') + local resultId = db.storeQuery('SELECT `player_id` FROM `player_deaths` WHERE `player_id` = ' .. playerGuid) + + local deathRecords = 0 + local tmpResultId = resultId + while tmpResultId ~= false do + tmpResultId = result.next(resultId) + deathRecords = deathRecords + 1 + end + + if resultId ~= false then + result.free(resultId) + end + + if byPlayer == 1 then + local targetGuild = player:getGuild() + targetGuild = targetGuild and targetGuild:getId() or 0 + if targetGuild ~= 0 then + local killerGuild = killer:getGuild() + killerGuild = killerGuild and killerGuild:getId() or 0 + if killerGuild ~= 0 and targetGuild ~= killerGuild and isInWar(playerId, killer.uid) then + local warId = false + resultId = db.storeQuery('SELECT `id` FROM `guild_wars` WHERE `status` = 1 AND \z + ((`guild1` = ' .. killerGuild .. ' AND `guild2` = ' .. targetGuild .. ') OR \z + (`guild1` = ' .. targetGuild .. ' AND `guild2` = ' .. killerGuild .. '))') + if resultId ~= false then + warId = result.getNumber(resultId, 'id') + result.free(resultId) + end + + if warId ~= false then + db.asyncQuery('INSERT INTO `guildwar_kills` (`killer`, `target`, `killerguild`, `targetguild`, `time`, `warid`) \z + VALUES (' .. db.escapeString(killerName) .. ', ' .. db.escapeString(player:getName()) .. ', ' .. killerGuild .. ', \z + ' .. targetGuild .. ', ' .. os.time() .. ', ' .. warId .. ')') + end + end + end + end +end +playerDeath:register() diff --git a/data/scripts/creaturescripts/others/prey_loot.lua b/data/scripts/creaturescripts/others/prey_loot.lua new file mode 100644 index 00000000000..88e52be420b --- /dev/null +++ b/data/scripts/creaturescripts/others/prey_loot.lua @@ -0,0 +1,47 @@ +local BONUS_RATE = 3 + +local preyLootBonusKill = CreatureEvent("PreyLootBonusKill") +function preyLootBonusKill.onKill(player, target, lastHit) + -- Monster verify + if not target:isMonster() or target:getMaster() then + return true + end + for slot = CONST_PREY_SLOT_FIRST, CONST_PREY_SLOT_THIRD do + if (player:getPreyCurrentMonster(slot) == target:getName() and + player:getPreyBonusType(slot) == CONST_BONUS_IMPROVED_LOOT) then + preyTimeLeft(player, slot) -- Slot consumption + local probability = math.random(0, 100) + if (probability < player:getPreyBonusValue(slot)) then + target:registerEvent('BonusPreyLootDeath') + player:sendTextMessage(MESSAGE_ATTENTION, "You get extra loot due your active prey.") + break + end + end + end + return true +end +preyLootBonusKill:register() + +local bonusPreyLootDeath = CreatureEvent("BonusPreyLootDeath") +function bonusPreyLootDeath.onDeath(creature, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified) + if not creature then + return true + end + if not creature:getType():getLoot() then + return true + end + + local tc = 0 + for i, k in pairs(creature:getType():getLoot()) do + tc = tc + k.chance + end + for i = 1, BONUS_RATE - 1 do + for i, k in pairs(creature:getType():getLoot()) do + if math.random() < k.chance/tc then + local item = corpse:addItem(k.itemId,math.random(k.maxCount) or k.subType) + end + end + end + return true +end +bonusPreyLootDeath:register() diff --git a/data/scripts/creaturescripts/others/regenerate_stamina.lua b/data/scripts/creaturescripts/others/regenerate_stamina.lua new file mode 100644 index 00000000000..0962c791bd6 --- /dev/null +++ b/data/scripts/creaturescripts/others/regenerate_stamina.lua @@ -0,0 +1,27 @@ +local regenerateStamina = CreatureEvent("RegenerateStamina") +function regenerateStamina.onLogin(player) + if not configManager.getBoolean(configKeys.STAMINA_SYSTEM) then + return true + end + + local lastLogout = player:getLastLogout() + local offlineTime = lastLogout ~= 0 and math.min(os.time() - lastLogout, 86400 * 21) or 0 + offlineTime = offlineTime - 600 + + if offlineTime < 180 then + return true + end + + local staminaMinutes = player:getStamina() + local maxNormalStaminaRegen = 2340 - math.min(2340, staminaMinutes) + local regainStaminaMinutes = offlineTime / 180 + if regainStaminaMinutes > maxNormalStaminaRegen then + local happyHourStaminaRegen = (offlineTime - (maxNormalStaminaRegen * 180)) / 360 + staminaMinutes = math.min(2520, math.max(2340, staminaMinutes) + happyHourStaminaRegen) + else + staminaMinutes = staminaMinutes + regainStaminaMinutes + end + player:setStamina(staminaMinutes) + return true +end +regenerateStamina:register() diff --git a/data/scripts/creaturescripts/others/rookgaard_advance.lua b/data/scripts/creaturescripts/others/rookgaard_advance.lua new file mode 100644 index 00000000000..e8b9972c985 --- /dev/null +++ b/data/scripts/creaturescripts/others/rookgaard_advance.lua @@ -0,0 +1,10 @@ +local rookgaardAdvance = CreatureEvent("RookgaardAdvance") +function rookgaardAdvance.onAdvance(player, skill, oldLevel, newLevel) + if skill ~= SKILL_LEVEL or newLevel ~= 8 or player:getVocation():getId() ~= 0 then + return true + end + + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Congratulations! You are ready to leave this island and choose a vocation now. Go see the Oracle over the academy in Rookgaard before you advance to level 10!') + return true +end +rookgaardAdvance:register() diff --git a/data/scripts/creaturescripts/quests/adventurers_guild/the_great_dragon_hunt.lua b/data/scripts/creaturescripts/quests/adventurers_guild/the_great_dragon_hunt.lua new file mode 100644 index 00000000000..84826bac7a0 --- /dev/null +++ b/data/scripts/creaturescripts/quests/adventurers_guild/the_great_dragon_hunt.lua @@ -0,0 +1,32 @@ +local areas = { + { from = Position(33061, 32646, 6), to = Position(33081, 32665, 6) }, + { from = Position(33027, 32634, 7), to = Position(33081, 32658, 7) }, + { from = Position(32983, 32616, 7), to = Position(33026, 32631, 7) }, + { from = Position(33007, 32612, 6), to = Position(33020, 32623, 6) }, + { from = Position(32987, 32621, 6), to = Position(33043, 32661, 6) }, + { from = Position(33002, 32614, 5), to = Position(33023, 32642, 5) }, + { from = Position(32993, 32632, 7), to = Position(33042, 32688, 7) } +} + +local adventurersGuildHunt = CreatureEvent("TheGreatDragonHuntKill") +function adventurersGuildHunt.onKill(creature, target) + if not creature or not creature:isPlayer() then + return true + end + + if not target or not target:isMonster() then + return true + end + + if isInArray({ 'dragon lord', 'dragon' }, target:getName():lower()) then + for _, area in ipairs(areas) do + if creature:getPosition():isInRange(area.from, area.to) then + creature:setStorageValue(Storage.AdventurersGuild.GreatDragonHunt.DragonCounter, creature:getStorageValue(Storage.AdventurersGuild.GreatDragonHunt.DragonCounter) + 1) + break + end + end + end + return true +end + +adventurersGuildHunt:register() diff --git a/data/scripts/creaturescripts/quests/bigfoot_burden/boss_room_kick.lua b/data/scripts/creaturescripts/quests/bigfoot_burden/boss_room_kick.lua new file mode 100644 index 00000000000..2c87030e839 --- /dev/null +++ b/data/scripts/creaturescripts/quests/bigfoot_burden/boss_room_kick.lua @@ -0,0 +1,18 @@ +-- This will kick the players in 1 min after the boss is dead AND add the 20 hours delay to go in again +local bossWarzoneDeath = CreatureEvent("BossWarzoneDeath") +function bossWarzoneDeath.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + local info = warzoneConfig.findByName(creature:getName()) + if not info then + return true + end + + local spectators = Game.getSpectators(info.center, false, true, info.minRangeX, info.maxRangeX, info.minRangeY, info.maxRangeY) + for i = 1, #spectators do + spectators[i]:setStorageValue(info.storage, os.time() + info.interval) + spectators[i]:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have one minute to loot the boss and leave the room.") + end + addEvent(warzoneConfig.resetRoom, 60 * 1000, info, "You were teleported out by the gnomish emergency device.", false) + return true +end + +bossWarzoneDeath:register() diff --git a/data/scripts/creaturescripts/quests/bigfoot_burden/bosses_warzone.lua b/data/scripts/creaturescripts/quests/bigfoot_burden/bosses_warzone.lua new file mode 100644 index 00000000000..57614340e7d --- /dev/null +++ b/data/scripts/creaturescripts/quests/bigfoot_burden/bosses_warzone.lua @@ -0,0 +1,35 @@ +local bosses = { + ['deathstrike'] = {status = 2, storage = Storage.BigfootBurden.Warzone1Reward}, + ['gnomevil'] = {status = 3, storage = Storage.BigfootBurden.Warzone2Reward}, + ['abyssador'] = {status = 4, storage = Storage.BigfootBurden.Warzone3Reward}, +} + +-- This will set the status of warzone (killing 1, 2 and 3 wz bosses in order you can open the chest and get "some golden fruits") and the reward chest storages +local bossesWarzone = CreatureEvent("BossesWarzone") +function bossesWarzone.onKill(creature, target) + local targetMonster = target:getMonster() + if not targetMonster then + return true + end + + local bossConfig = bosses[targetMonster:getName():lower()] + if not bossConfig then + return true + end + + for index, value in pairs(targetMonster:getDamageMap()) do + local attackerPlayer = Player(index) + if attackerPlayer then + if (attackerPlayer:getStorageValue(Storage.BigfootBurden.WarzoneStatus) + 1) == bossConfig.status then + attackerPlayer:setStorageValue(Storage.BigfootBurden.WarzoneStatus, bossConfig.status) + if bossConfig.status == 4 then + attackerPlayer:setStorageValue(Storage.BigfootBurden.DoorGoldenFruits, 1) + end + end + attackerPlayer:setStorageValue(bossConfig.storage, 1) + attackerPlayer:setStorageValue(Storage.BigfootBurden.BossKills, attackerPlayer:getStorageValue(Storage.BigfootBurden.BossKills) + 1) + end + end +end + +bossesWarzone:register() diff --git a/data/scripts/creaturescripts/quests/bigfoot_burden/parasite.lua b/data/scripts/creaturescripts/quests/bigfoot_burden/parasite.lua new file mode 100644 index 00000000000..4778b264043 --- /dev/null +++ b/data/scripts/creaturescripts/quests/bigfoot_burden/parasite.lua @@ -0,0 +1,85 @@ +--[[ +Created by gagoosh [gudan garam on otland] +for otx server malucoo +]] + +local positionsWall = { + {x = 33098, y = 31979, z = 11}, + {x = 33098, y = 31978, z = 11}, + {x = 33098, y = 31977, z = 11}, + {x = 33098, y = 31976, z = 11} +} + +local function recreateCrystals(c) + for i = 1, #positionsWall do + local crystal = Tile(positionsWall[i]):getItemById(c.wall) or nil + if not item then + Game.createItem(c.wall, 1, positionsWall[i]) + end + end + + local spectators = Game.getSpectators(Position(33099, 31977, 11), false, false, 1, 1, 1, 2) + for i = 1, #spectators do + if spectators[i]:isPlayer() then + local specPos = spectators[i]:getPosition() + spectators[i]:teleportTo(Position(specPos.x - 2, specPos.y, specPos.z)) + else + spectators[i]:getPosition():sendMagicEffect(CONST_ME_POFF) + spectators[i]:remove() + end + end +end + +local parasiteWarzone = CreatureEvent("ParasiteWarzone") +function parasiteWarzone.onKill(player, target) + local targetMonster = target:getMonster() + if not targetMonster then + return false + end + + local targetName = targetMonster:getName():lower() + if targetName ~= 'parasite' then + return false + end + + local master = targetMonster:getMaster() + if not master or master:isPlayer() then + return false + end + + local pos = targetMonster:getPosition() + if pos.x ~= 33097 or pos.y > 31979 or pos.y < 31976 or pos.z ~= 11 then + return false + end + + local config = warzoneConfig.findByName('Gnomevil') + if config.locked then + targetMonster:say("It seems that someone has already destroyed the walls in the last 30 minutes.", TALKTYPE_MONSTER_SAY) + return false + end + + if config.wall < 18461 and config.wall >= 18459 then + for i = 1, #positionsWall do + local crystal = Tile(positionsWall[i]):getItemById(config.wall) + if crystal then + Tile(positionsWall[i]):getItemById(config.wall):remove() + Game.createItem(config.wall+1, 1, positionsWall[i]) + end + end + config.wall = config.wall + 1 + elseif config.wall == 18461 then + for i = 1, #positionsWall do + local crystal = Tile(positionsWall[i]):getItemById(config.wall) + if crystal then + Tile(positionsWall[i]):getItemById(config.wall):remove() + end + end + config.wall = 18459 + addEvent(recreateCrystals, 1 * 60 * 1000, config) + addEvent(warzoneConfig.spawnBoss, 1 * 60 * 1000, config.boss, config.bossResp) + addEvent(warzoneConfig.resetRoom, 30 * 60 * 1000, config, "You were teleported out by the gnomish emergency device.", true) + end + return true +end + +parasiteWarzone:register() diff --git a/data/scripts/creaturescripts/quests/bigfoot_burden/versperoth_kill.lua b/data/scripts/creaturescripts/quests/bigfoot_burden/versperoth_kill.lua new file mode 100644 index 00000000000..3072942801c --- /dev/null +++ b/data/scripts/creaturescripts/quests/bigfoot_burden/versperoth_kill.lua @@ -0,0 +1,49 @@ +local teleportPosition = Position(33075, 31878, 12) + +local function transformTeleport(open) + local id = (open and 18462 or 1387) + local teleportItem = Tile(teleportPosition):getItemById(id) + if not teleportItem then + return + end + + teleportPosition:sendMagicEffect(CONST_ME_POFF) + if open then + teleportItem:transform(18463) -- can pass and summon versperoth + else + teleportItem:transform(18462) -- cannot summon versperoth + end +end + +local versperothKill = CreatureEvent("VersperothKill") +function versperothKill.onKill(creature, target) + local config = warzoneConfig.findByName("Abyssador") + local targetMonster = target:getMonster() + if not targetMonster then + return true + end + + if targetMonster:getName():lower() ~= 'versperoth' then + return true + end + + Game.setStorageValue(GlobalStorage.BigfootBurden.Versperoth.Battle, 2) + addEvent(Game.setStorageValue, 30 * 60 * 1000, GlobalStorage.BigfootBurden.Versperoth.Battle, 0) + + blood = Tile(teleportPosition):getItemById(2016) + if blood then + blood:remove() + end + local tp = Game.createItem(1387, 1, teleportPosition) + if tp then + tp:setActionId(45702) + end + + addEvent(transformTeleport, 1 * 60 * 1000, false) + addEvent(transformTeleport, 30 * 60 * 1000, true) + addEvent(warzoneConfig.spawnBoss, 1 * 80 * 1000, config.boss, config.bossResp) + addEvent(warzoneConfig.resetRoom, 30 * 60 * 1000, config, "You were teleported out by the gnomish emergency device.", true) + return true +end + +versperothKill:register() diff --git a/data/scripts/creaturescripts/quests/bigfoot_burden/wiggler_kill.lua b/data/scripts/creaturescripts/quests/bigfoot_burden/wiggler_kill.lua new file mode 100644 index 00000000000..1fd7f47033c --- /dev/null +++ b/data/scripts/creaturescripts/quests/bigfoot_burden/wiggler_kill.lua @@ -0,0 +1,20 @@ +local wigglerKill = CreatureEvent("WigglerKill") +function wigglerKill.onKill(creature, target) + local targetMonster = target:getMonster() + if not targetMonster then + return true + end + + if targetMonster:getName():lower() ~= 'wiggler' then + return true + end + + local player = creature:getPlayer() + local value = player:getStorageValue(Storage.BigfootBurden.ExterminatedCount) + if value < 10 and player:getStorageValue(Storage.BigfootBurden.MissionExterminators) == 1 then + player:setStorageValue(Storage.BigfootBurden.ExterminatedCount, value + 1) + end + return true +end + +wigglerKill:register() diff --git a/data/scripts/creaturescripts/quests/cults_of_tibia/bosses_mission_cults.lua b/data/scripts/creaturescripts/quests/cults_of_tibia/bosses_mission_cults.lua new file mode 100644 index 00000000000..4e7eff23522 --- /dev/null +++ b/data/scripts/creaturescripts/quests/cults_of_tibia/bosses_mission_cults.lua @@ -0,0 +1,61 @@ +local bossesCults = CreatureEvent("BossesCults") +function bossesCults.onKill(player, creature) + local bosses = { + ["ravennous hunger"] = {storage = Storage.CultsOfTibia.Barkless.Mission, value = 6}, + ["the souldespoiler"] = {storage = Storage.CultsOfTibia.Misguided.Mission, value = 4}, + ["essence of malice"] = {storage = Storage.CultsOfTibia.Humans.Mission, value = 2}, + ["the unarmored voidborn"] = {storage = Storage.CultsOfTibia.Orcs.Mission, value = 2}, + ["the false god"] = {storage = Storage.CultsOfTibia.Minotaurs.Mission, value = 4}, + ["the sandking"] = {storage = Storage.CultsOfTibia.Life.Mission, value = 8, global = "sandking", g_value = 5}, + ["the corruptor of souls"] = {createNew = 'The Source Of Corruption', pos = Position(33039, 31922, 15), removeMonster = 'zarcorix of yalahar', area1 = Position(33073, 31885, 15), area2 = Position(33075, 31887, 15)}, + ["the source of corruption"] = {storage = Storage.CultsOfTibia.FinalBoss.Mission, value = 2}, + } + + if not player:isPlayer() then + return true + end + + if not creature:isMonster() or creature:getMaster() then + return true + end + + local monsterName = creature:getName():lower() + local boss = bosses[monsterName] + if boss then + if boss.global and Game.getStorageValue(boss.global) < boss.g_value then + return true + end + if boss.createNew then + Game.setStorageValue('CheckTile', -1) + Game.createMonster(boss.createNew, boss.pos) + if removeMonster then + for _x = boss.area1.x, boss.area2.x, 1 do + for _y = boss.area1.y, boss.area2.y, 1 do + for _z = boss.area1.z, boss.area2.z, 1 do + if Tile(Position(_x, _y, _z)) then + local monster = Tile(Position(_x, _y, _z)):getTopCreature() + if monster and monster:isMonster() and monster:getName():lower() == string.lower(boss.removeMonster) then + monster:remove() + end + end + end + end + end + end + return true + end + for playerid, damage in pairs(creature:getDamageMap()) do + -- broadcastMessage(playerid.." damage:"..damage.total) + local p = Player(playerid) + if p then + -- broadcastMessage(p:getName()) + if p:getStorageValue(boss.storage) < boss.value then + p:setStorageValue(boss.storage, boss.value) + end + end + end + end + return true +end + +bossesCults:register() diff --git a/data/scripts/creaturescripts/quests/cults_of_tibia/carlin_vortex_spawn.lua b/data/scripts/creaturescripts/quests/cults_of_tibia/carlin_vortex_spawn.lua new file mode 100644 index 00000000000..0b94f8d786c --- /dev/null +++ b/data/scripts/creaturescripts/quests/cults_of_tibia/carlin_vortex_spawn.lua @@ -0,0 +1,36 @@ +local vortexCarlin = CreatureEvent("VortexCarlin") +function vortexCarlin.onKill(creature, target, item) + if not creature or not creature:isPlayer() then + return true + end + + if not target or not target:isMonster() then + return true + end + + if(table.contains({'cult enforcer', 'cult believer', 'cult scholar'}, target:getName():lower())) then + local corpsePosition = target:getPosition() + local rand = math.random(1,2) + if rand == 1 then + Game.createItem(26140, 1, corpsePosition):setActionId(5580) + addEvent(function() + local teleport1 = Tile(corpsePosition):getItemById(26140) + if teleport1 then + teleport1:remove(1) + end + end, (1*60*1000), 26140, 1, corpsePosition) + end + if rand == 2 then + Game.createItem(26138, 1, corpsePosition):setActionId(5580) + addEvent(function() + local teleport2 = Tile(corpsePosition):getItemById(26138) + if teleport2 then + teleport2:remove(1) + end + end, (1*60*1000), 26138, 1, corpsePosition) + end + end + return true +end + +vortexCarlin:register() diff --git a/data/scripts/creaturescripts/quests/cults_of_tibia/check_tile.lua b/data/scripts/creaturescripts/quests/cults_of_tibia/check_tile.lua new file mode 100644 index 00000000000..2c6acfe289f --- /dev/null +++ b/data/scripts/creaturescripts/quests/cults_of_tibia/check_tile.lua @@ -0,0 +1,14 @@ +local checkTile = CreatureEvent("CheckTile") +function checkTile.onThink(creature, interval) + if creature:getName():lower() == 'the corruptor of souls' then + if Game.getStorageValue('CheckTile') < os.time() then + local pos = creature:getPosition() + Game.setStorageValue('healthSoul', creature:getHealth()) + creature:remove() + Game.createMonster('the remorseless corruptor', pos) + end + end + return true +end + +checkTile:register() diff --git a/data/scripts/creaturescripts/quests/cults_of_tibia/destroyed_pillar.lua b/data/scripts/creaturescripts/quests/cults_of_tibia/destroyed_pillar.lua new file mode 100644 index 00000000000..3f6b1d1c7ab --- /dev/null +++ b/data/scripts/creaturescripts/quests/cults_of_tibia/destroyed_pillar.lua @@ -0,0 +1,76 @@ +local destroyedPillar = CreatureEvent("DestroyedPillar") +function destroyedPillar.onKill(creature, target) + if not creature or not creature:isPlayer() then + return true + end + if not target or not target:isMonster() then + return true + end + + local pillar = { + [1] = "pillar of summoning", + [2] = "pillar of death", + [3] = "pillar of protection", + [4] = "pillar of healing", + [5] = "pillar of draining" + } + + local monsterName = target:getName():lower() + local summoning = "summoning" + local death = "death" + local healing = "healing" + local protection = "protection" + local draining = "draining" + for i = 1, #pillar do + local position = target:getPosition() + local pilar = "" + local newpos = {} + pilar = pillar[i] + if monsterName == pilar:lower() then + if monsterName:find(summoning) then + newpos = {x = position.x + 1, y = position.y, z = position.z} + local boss = Tile(Position(newpos)):getTopCreature() + if boss then + boss:remove() + end + Game.createMonster("Destroyed Pillar", position, true, true) + Game.createMonster("Eshtaba The Conjurer", newpos, true, true):registerEvent("essenceMalice") + elseif monsterName:find(death) then + newpos = {x = position.x, y = position.y + 1, z = position.z} + local boss = Tile(Position(newpos)):getTopCreature() + if boss then + boss:remove() + end + Game.createMonster("Destroyed Pillar", position, true, true) + Game.createMonster("Malkhar Deathbringer", newpos, true, true):registerEvent("essenceMalice") + elseif monsterName:find(healing) then + newpos = {x = position.x, y = position.y -1, z = position.z} + local boss = Tile(Position(newpos)):getTopCreature() + if boss then + boss:remove() + end + Game.createMonster("Destroyed Pillar", position, true, true) + Game.createMonster("Mezlon The Defiler", newpos, true, true):registerEvent("essenceMalice") + elseif monsterName:find(protection) then + newpos = {x = position.x - 1, y = position.y , z = position.z} + local boss = Tile(Position(newpos)):getTopCreature() + if boss then + boss:remove() + end + Game.createMonster("Destroyed Pillar", position, true, true) + Game.createMonster("Eliz The Unyielding", newpos, true, true):registerEvent("essenceMalice") + elseif monsterName:find(draining) then + newpos = {x = position.x, y = position.y - 1, z = position.z} + local boss = Tile(Position(newpos)):getTopCreature() + if boss then + boss:remove() + end + Game.createMonster("Destroyed Pillar", position, true, true) + Game.createMonster("Dorokoll The Mystic", newpos, true, true):registerEvent("essenceMalice") + end + end + end + return true +end + +destroyedPillar:register() diff --git a/data/scripts/creaturescripts/quests/cults_of_tibia/essence_of_malice.lua b/data/scripts/creaturescripts/quests/cults_of_tibia/essence_of_malice.lua new file mode 100644 index 00000000000..e9ac598a126 --- /dev/null +++ b/data/scripts/creaturescripts/quests/cults_of_tibia/essence_of_malice.lua @@ -0,0 +1,32 @@ +local essenceOfMalice = CreatureEvent("EssenceOfMalice") +function essenceOfMalice.onKill(creature, target) + if not creature:isMonster() or creature:getMaster() then + return false + end + + local boss = {"eshtaba the conjurer", "mezlon the defiler", "eliz the unyielding", "malkhar deathbringer", "dorokoll the mystic"} + local newBoss = 0 + local fromPos = Position(33087, 31909, 15) + local toPos = Position(33112, 31932, 15) + for _x = fromPos.x, toPos.x, 1 do + for _y = fromPos.y, toPos.y, 1 do + for _z = fromPos.z, toPos.z, 1 do + local tile = Tile(Position(_x, _y, _z)) + if tile then + local monster = Monster(tile:getTopCreature()) + if monster then + if isInArray(boss, monster:getName():lower()) then + newBoss = newBoss + 1 + end + end + end + end + end + end + if newBoss == 1 then + Game.createMonster("Essence Of Malice", Position(33098, 31920, 15)) + end + return true +end + +essenceOfMalice:register() diff --git a/data/scripts/creaturescripts/quests/cults_of_tibia/evaporate.lua b/data/scripts/creaturescripts/quests/cults_of_tibia/evaporate.lua new file mode 100644 index 00000000000..657826b1d37 --- /dev/null +++ b/data/scripts/creaturescripts/quests/cults_of_tibia/evaporate.lua @@ -0,0 +1,57 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_PURPLESMOKE) + +combat:setArea(createCombatArea({ + {0, 0, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 1}, + {1, 1, 1, 3, 1, 1, 1}, + {1, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 0, 0} +})) + +function spellCallback(param) + local tile = Tile(Position(param.pos)) + if tile then + if tile:getTopCreature() and tile:getTopCreature():isMonster() then + if tile:getTopCreature():getName():lower() == "leiden" then + tile:getTopCreature():registerEvent("spawnBoss") + tile:getTopCreature():addHealth(-math.random(3000, 6000)) + elseif tile:getTopCreature():getName():lower() == "ravennous hunger" then + tile:getTopCreature():addHealth(math.random(3000, 6000)) + end + end + end +end + +function onTargetTile(cid, pos) + local param = {} + param.cid = cid + param.pos = pos + param.count = 0 + spellCallback(param) +end + +setCombatCallback(combat, CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +local evaporate = CreatureEvent("Evaporate") +function evaporate.onThink(creature) + local hp = (creature:getHealth()/creature:getMaxHealth())*100 + if hp < 60.0 then + addEvent(function(cid) + local creature = Creature(cid) + if not creature then + return + end + creature:say("The liquor spirit evaporates!", TALKTYPE_ORANGE_2) + local var = {type = 1, number = creature:getId()} + combat:execute(creature, var) + creature:remove(1) + return true + end, 100, creature:getId()) + end +end + +evaporate:register() diff --git a/data/scripts/creaturescripts/quests/cults_of_tibia/glowing_rubbish_amulet.lua b/data/scripts/creaturescripts/quests/cults_of_tibia/glowing_rubbish_amulet.lua new file mode 100644 index 00000000000..3cb8b45a77f --- /dev/null +++ b/data/scripts/creaturescripts/quests/cults_of_tibia/glowing_rubbish_amulet.lua @@ -0,0 +1,44 @@ +local glowingRubbishAmulet = CreatureEvent("GlowingRubbishAmulet") +function glowingRubbishAmulet.onKill(creature, killed) + local player = Player(creature) + if not player then + return true + end + + local monster = Monster(killed) + if not monster then + return true + end + + local colar = player:getSlotItem(CONST_SLOT_NECKLACE) + if not colar or colar:getId() ~= 28657 then + return true + end + + if player:getStorageValue(Storage.CultsOfTibia.Misguided.Mission) ~= 3 then + return true + end + + local mStg = math.max(player:getStorageValue(Storage.CultsOfTibia.Misguided.Monsters), 0) + local eStg = math.max(player:getStorageValue(Storage.CultsOfTibia.Misguided.Exorcisms), 0) + if monster:getName():lower() == "misguided shadow" then + if eStg < 5 then + player:setStorageValue(Storage.CultsOfTibia.Misguided.Exorcisms, eStg+1) + end + return true + end + + if monster:getName():lower() == "misguided bully" or monster:getName():lower() == "misguided thief" then + player:setStorageValue(Storage.CultsOfTibia.Misguided.Monsters, mStg+1) + if player:getStorageValue(Storage.CultsOfTibia.Misguided.Monsters) >= 10 then + colar:remove() + local it = player:addItem(28658, 1) + if it then + it:decay() + end + end + end + return true +end + +glowingRubbishAmulet:register() diff --git a/data/scripts/creaturescripts/quests/cults_of_tibia/leiden_heal.lua b/data/scripts/creaturescripts/quests/cults_of_tibia/leiden_heal.lua new file mode 100644 index 00000000000..1eaf838ec28 --- /dev/null +++ b/data/scripts/creaturescripts/quests/cults_of_tibia/leiden_heal.lua @@ -0,0 +1,18 @@ +local leidenHeal = CreatureEvent("LeidenHeal") +function leidenHeal.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin) + if creature:getName():lower() == "leiden" then + if attacker and attacker:isPlayer() then + primaryType = COMBAT_HEALING + secondaryType = primaryType + if primaryDamage < 0 then + primaryDamage = primaryDamage * -1 + end + secondaryDamage = primaryDamage + creature:addHealth(primaryDamage < 0 and -primaryDamage or primaryDamage) + return primaryDamage, primaryType, secondaryDamage, secondaryType + end + end + return primaryDamage, primaryType, secondaryDamage, secondaryType +end + +leidenHeal:register() diff --git a/data/scripts/creaturescripts/quests/cults_of_tibia/machine.lua b/data/scripts/creaturescripts/quests/cults_of_tibia/machine.lua new file mode 100644 index 00000000000..95fb23a290f --- /dev/null +++ b/data/scripts/creaturescripts/quests/cults_of_tibia/machine.lua @@ -0,0 +1,107 @@ +local function DestruirRaio1(fromPos, toPos, id, dir) + if dir == 1 then + for _x = fromPos.x, toPos.x, 1 do + local tile = Tile(Position(_x, fromPos.y, fromPos.z)) + if tile and tile:getItemCountById(id) > 0 then + tile:getItemById(id):remove() + end + end + elseif dir == 2 then + for _y = fromPos.y, toPos.y, 1 do + local tile = Tile(Position(fromPos.x, _y, fromPos.z)) + if tile and tile:getItemCountById(id) > 0 then + tile:getItemById(id):remove() + end + end + end +end + +local machineDeath = CreatureEvent("MachineDeath") +function machineDeath.onDeath(creature, attacker) + if not creature:isMonster() then + return true + end + + local name = creature:getName():lower() + local creaturePosition = creature:getPosition() + if name == "containment machine" then + -- destruindo os raios + DestruirRaio1(Position(33134, 31856, 15), Position(33139, 31856, 15), 29087, 1) + DestruirRaio1(Position(33134, 31863, 15), Position(33139, 31863, 15), 29087, 1) + DestruirRaio1(Position(33140, 31857, 15), Position(33140, 31862, 15), 29087, 2) + DestruirRaio1(Position(33133, 31857, 15), Position(33133, 31862, 15), 29087, 2) + local itensToMonster = {--8633 + Position(33133, 31856, 15), + Position(33140, 31856, 15), + Position(33140, 31863, 15), + Position(33133, 31863, 15) + } + for _, position in pairs(itensToMonster) do + local tile = Tile(position) + if tile then + if tile:getItemCountById(8633) > 0 then + tile:getItemById(8633):remove() + end + local crystal = Game.createMonster("Containment Crystal", position) + crystal:registerEvent("machineHealth") + crystal:registerEvent("machineDeath") + end + end + elseif name == "containment crystal" then + Game.createItem(8637,1, creaturePosition) + elseif name == "the armored voidborn" then + Game.createMonster("The Unarmored Voidborn", creaturePosition):registerEvent("bossesMission") + end + + return true +end + +machineDeath:register() + +local machineHealth = CreatureEvent("MachineHealth") +function machineHealth.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin) + local frompos = Position(33123, 31846, 15) -- Checagem + local topos = Position(33149, 31871, 15) -- Checagem + + if creature:getName():lower() == "containment crystal" then + local bossid = 0 + for _x= frompos.x, topos.x, 1 do + for _y= frompos.y, topos.y, 1 do + for _z= frompos.z, topos.z, 1 do + local tile = Tile(Position(_x, _y, _z)) + if tile and tile:getTopCreature() and tile:getTopCreature():isMonster() and tile:getTopCreature():getName():lower() == "the armored voidborn" then + bossid = tile:getTopCreature():getId() + end + end + end + end + local boss = Monster(bossid) + if not boss or primaryType == COMBAT_HEALING or secondaryType == COMBAT_HEALING then + return primaryDamage, primaryType, secondaryDamage, secondaryType + end + local hasdano = false + local maxheal = creature:getMaxHealth() + if creature:getHealth() > (maxheal*60)/100 and creature:getHealth() < (maxheal*65)/100 then + boss:addHealth(-7000) + hasdano = true + end + for _x= frompos.x, topos.x, 1 do + for _y= frompos.y, topos.y, 1 do + for _z= frompos.z, topos.z, 1 do + local tile = Tile(Position(_x, _y, _z)) + if tile and tile:getTopCreature() and tile:getTopCreature():isMonster() and tile:getTopCreature():getName():lower() == "voidshard" then + hasdano = false + end + end + end + end + if hasdano then + Game.createMonster("Voidshard", boss:getPosition() ) + Game.createMonster("Voidshard", boss:getPosition() ) + end + + end + return primaryDamage, primaryType, secondaryDamage, secondaryType +end + +machineHealth:register() diff --git a/data/scripts/creaturescripts/quests/cults_of_tibia/minotaur_task_count.lua b/data/scripts/creaturescripts/quests/cults_of_tibia/minotaur_task_count.lua new file mode 100644 index 00000000000..fadf7111797 --- /dev/null +++ b/data/scripts/creaturescripts/quests/cults_of_tibia/minotaur_task_count.lua @@ -0,0 +1,18 @@ +local minotaurTask = CreatureEvent("MinotaurTask") +function minotaurTask.onKill(creature, target) + if not creature or not creature:isPlayer() then + return true + end + + if not target or not target:isMonster() then + return true + end + + local storage = creature:getStorageValue(Storage.CultsOfTibia.Minotaurs.JamesfrancisTask) + if(isInArray({'minotaur cult follower', 'minotaur cult zealot', 'minotaur cult prophet'}, target:getName():lower()) and storage >= 0 and storage < 50)then + creature:setStorageValue(Storage.CultsOfTibia.Minotaurs.JamesfrancisTask, storage + 1) + end + return true +end + +minotaurTask:register() diff --git a/data/scripts/creaturescripts/quests/cults_of_tibia/pillar_health.lua b/data/scripts/creaturescripts/quests/cults_of_tibia/pillar_health.lua new file mode 100644 index 00000000000..da2d9145d50 --- /dev/null +++ b/data/scripts/creaturescripts/quests/cults_of_tibia/pillar_health.lua @@ -0,0 +1,29 @@ +local defensor = { + ["eshtaba the conjurer"] = Position(33093, 31919, 15), + ["dorokoll the mystic"] = Position(33095, 31925, 15), + ["mezlon the defiler"] = Position(33101, 31925, 15), + ["eliz the unyielding"] = Position( 33103, 31919, 15), + ["malkhar deathbringer"] = Position(33098, 31915, 15), +} + +local healthPillar = CreatureEvent("HealthPillar") +function healthPillar.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin) + if not creature:isMonster() then + return primaryDamage, primaryType, secondaryDamage, secondaryType + end + local monster = defensor[creature:getName():lower()] + local protector = 'pillar of' + if monster then + local pMonster = Tile(Position(monster)):getTopCreature() + if not pMonster then + return primaryDamage, primaryType, secondaryDamage, secondaryType + end + if pMonster:getName():lower():find(protector) then + primaryDamage = 0 + secondaryDamage = 0 + end + end + return primaryDamage, primaryType, secondaryDamage, secondaryType +end + +healthPillar:register() diff --git a/data/scripts/creaturescripts/quests/cults_of_tibia/sandking.lua b/data/scripts/creaturescripts/quests/cults_of_tibia/sandking.lua new file mode 100644 index 00000000000..b82d551131a --- /dev/null +++ b/data/scripts/creaturescripts/quests/cults_of_tibia/sandking.lua @@ -0,0 +1,154 @@ +local function spawnSandBoss(name, frompos, topos) + local spawn = true + for _x= frompos.x, topos.x, 1 do + for _y= frompos.y, topos.y, 1 do + for _z= frompos.z, topos.z, 1 do + local tile = Tile(Position(_x, _y, _z)) + if tile and tile:getTopCreature() and tile:getTopCreature():isMonster() and tile:getTopCreature():getName():lower() == "sand brood" then + spawn = false + break + end + end + end + end + if not spawn then + addEvent(spawnSandBoss, 5000, name, frompos, topos) + return true + end + for _x= frompos.x, topos.x, 1 do + for _y= frompos.y, topos.y, 1 do + for _z= frompos.z, topos.z, 1 do + local tile = Tile(Position(_x, _y, _z)) + if tile and tile:getTopCreature() and tile:getTopCreature():getName():lower() == "sand vortex" then + tile:getTopCreature():remove() + end + end + end + end + + local str = Game.getStorageValue("sandking") + local boss = Game.createMonster("the sandking fake", Position( 33099, 31859, 15)) + if str < 4 then + boss:registerEvent("sandking think") + end + Game.setStorageValue("sandking", str + 1) + boss:say("THE BROOD RETREATS AND THE SANDKING REMERGES TO PROTECT HIS OFFSPRING!",TALKTYPE_MONSTER_SAY) + return true +end +local function spawnSandMonster(name, _time) + if _time == 0 then + addEvent(spawnSandBoss, 5000, "the sandking fake", Position(33087, 31848, 15), Position(33109, 31871, 15)) + return true + end + local randomarea = {x = math.random(33092, 33105), y = math.random(31853, 31865), z = 15} + Game.createMonster(name, randomarea):registerEvent("sandking death") + _time = _time - 1 + addEvent(spawnSandMonster, 5000, name, _time) + return true +end + +local sandkingThink = CreatureEvent("SandkingThink") +function sandkingThink.onThink(creature) + if not creature:isMonster() then + return true + end + if creature:getName():lower() ~= "the sandking" then + return true + end + local maxhealth = creature:getMaxHealth() + local str = Game.getStorageValue("sandking") + if str <= 3 then + if ((maxhealth*0.95) > creature:getHealth() ) then + creature:say("THE SANDKING VANISHES INTO THE SAND AND HIS BROOD EMERGES!",TALKTYPE_MONSTER_SAY) + creature:remove() + local positions = { + Position(33095, 31854, 15), + Position(33102, 31854, 15), + Position(33095, 31864, 15), + Position(33102, 31864, 15), + } + + for _, pos in pairs(positions) do + Game.createMonster("sand vortex",pos):registerEvent("sand health") + end + spawnSandMonster("Sand Brood", 10) + end + elseif str == 4 then + local tm = os.time() + if ((maxhealth*0.50) > creature:getHealth() ) then + creature:say("THE SANDKING VANISHES INTO THE SAND AND HIS BROOD EMERGES!",TALKTYPE_MONSTER_SAY) + creature:remove() + local ps = { + Position(33097, 31857, 15), + Position(33099, 31856, 15), + Position(33102, 31857, 15), + } + local pass = 0 + for _, pos in pairs(ps) do + local monster = Game.createMonster("the sandking fake", pos) + monster:setHealth(monster:getMaxHealth()/2) + if pass == 0 then + monster:registerEvent("sandking death") + pass = 1 + end + monster:beginSharedLife(tm) + monster:registerEvent("shared life") + end + end + end + return true +end +sandkingThink:register() + +local sandkingDeath = CreatureEvent("SandkingDeath") +function sandkingDeath.onDeath(creature, attacker, corpse) + if not creature:isMonster() then + return true + end + if creature:getName():lower() == "sand brood" then + addEvent( + function(position, corpseid) + local tile = Tile(position) + if tile then + local corpoCount = tile:getItemCountById(corpseid) + if corpoCount > 0 then + tile:getItemById(corpseid):setActionId(5595) + end + end + end, 200, creature:getPosition(), MonsterType(creature:getName()):getCorpseId() + ) + return true + end + local stg = Game.getStorageValue("sandking") + if stg == 4 then + local monster = Game.createMonster("the sandking", Position( 33099, 31859, 15)) + monster:setHealth(monster:getMaxHealth()/2) + addEvent(Game.setStorageValue, 2000, "sandking", 5) + end + return true +end +sandkingDeath:register() + + +local sandHealth = CreatureEvent("SandHealth") +function sandHealth.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin) + if not creature:isMonster() then + return primaryDamage, primaryType, secondaryDamage, secondaryType + end + + if creature:getName():lower() == "sand vortex" then + if primaryType == COMBAT_HEALING or secondaryType == COMBAT_HEALING then + return primaryDamage, primaryType, secondaryDamage, secondaryType + end + if attacker and attacker:isPlayer() then + if primaryDamage > 0 then + attacker:addHealth(-primaryDamage) + end + if secondaryDamage > 0 then + attacker:addHealth(-secondaryDamage) + end + end + end + return primaryDamage, primaryType, secondaryDamage, secondaryType +end +sandHealth:register() diff --git a/data/scripts/creaturescripts/quests/cults_of_tibia/spawn_boss.lua b/data/scripts/creaturescripts/quests/cults_of_tibia/spawn_boss.lua new file mode 100644 index 00000000000..76c2b27729b --- /dev/null +++ b/data/scripts/creaturescripts/quests/cults_of_tibia/spawn_boss.lua @@ -0,0 +1,15 @@ +local spawnBoss = CreatureEvent("SpawnBoss") +function spawnBoss.onDeath(creature, target) + if not creature or not creature:isMonster() then + return true + end + + if creature:getName():lower() == "leiden" then + local monster = Game.createMonster("ravennous hunger", creature:getPosition()) + elseif creature:getName():lower() == "the sinister hermit" then + local monster = Game.createMonster("the souldespoiler", creature:getPosition()) + end + return true +end + +spawnBoss:register() diff --git a/data/scripts/creaturescripts/quests/cults_of_tibia/splash.lua b/data/scripts/creaturescripts/quests/cults_of_tibia/splash.lua new file mode 100644 index 00000000000..b1ea1b06049 --- /dev/null +++ b/data/scripts/creaturescripts/quests/cults_of_tibia/splash.lua @@ -0,0 +1,18 @@ +local splash = CreatureEvent("Splash") +function splash.onThink(creature) + local hp = (creature:getHealth()/creature:getMaxHealth())*100 + if hp < 85.0 then + addEvent(function(cid) + local monsterPos = Position(33160, 31945, 15) + if not creature then + return + end + Game.createMonster("liquor spirit", monsterPos) + creature:say("SPLASH!", TALKTYPE_ORANGE_2) + creature:addHealth((creature:getMaxHealth()) - (creature:getHealth())) + return true + end, 100, creature:getId()) + end +end + +splash:register() diff --git a/data/scripts/creaturescripts/quests/cults_of_tibia/zarcorix_reflect_damage.lua b/data/scripts/creaturescripts/quests/cults_of_tibia/zarcorix_reflect_damage.lua new file mode 100644 index 00000000000..d32ed32c563 --- /dev/null +++ b/data/scripts/creaturescripts/quests/cults_of_tibia/zarcorix_reflect_damage.lua @@ -0,0 +1,23 @@ +local yalahariHealth = CreatureEvent("YalahariHealth") +function yalahariHealth.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin) + if not creature:isMonster() then + return primaryDamage, primaryType, secondaryDamage, secondaryType + end + + if creature:getName():lower() == "zarcorix of yalahar" then + if primaryType == COMBAT_HEALING or secondaryType == COMBAT_HEALING then + return primaryDamage, primaryType, secondaryDamage, secondaryType + end + if attacker and attacker:isPlayer() then + if primaryDamage > 0 then + attacker:addHealth(-primaryDamage) + end + if secondaryDamage > 0 then + attacker:addHealth(-secondaryDamage) + end + end + end + return primaryDamage, primaryType, secondaryDamage, secondaryType +end + +yalahariHealth:register() diff --git a/data/scripts/creaturescripts/quests/dangerous_depths/bosses_mission_depths.lua b/data/scripts/creaturescripts/quests/dangerous_depths/bosses_mission_depths.lua new file mode 100644 index 00000000000..ebc9e90a489 --- /dev/null +++ b/data/scripts/creaturescripts/quests/dangerous_depths/bosses_mission_depths.lua @@ -0,0 +1,48 @@ +local function revert(position, toPosition) + local teleport = Tile(position):getItemById(25417) + if teleport then + teleport:transform(1387) + teleport:setDestination(toPosition) + end +end + +local bossesMissionDepth = CreatureEvent("BossesMissionDepth") +function bossesMissionDepth.onKill(creature, creature) + if not creature or not creature:isPlayer() then + return true + end + + if not target or not target:isMonster() then + return true + end + + local bosses = { + ["the count of the core"] = {stg = Storage.DangerousDepths.Bosses.TheCountOfTheCore, value = os.time() + 20*60*60, teleportPosition = Position(33681, 32340, 15), + toPosition = Position(33682, 32315, 15), toPositionBack = Position(33324, 32111, 15)}, + ["the duke of the depths"] = {stg = Storage.DangerousDepths.Bosses.TheDukeOfTheDepths, value = os.time() + 20*60*60, teleportPosition = Position(33719, 32302, 15), + toPosition = Position(33691, 32301, 15), toPositionBack = Position(33275, 32318, 15)}, + ["the baron from below"] = {stg = Storage.DangerousDepths.Bosses.TheBaronFromBelow, value = os.time() + 20*60*60, teleportPosition = Position(33650, 32312, 15), + toPosition = Position(33668, 32301, 15), toPositionBack = Position(33462, 32267, 15)}, + } + + local boss = bosses[creature:getName():lower()] + if boss then + for playerid, damage in pairs(creature:getDamageMap()) do + local player = Player(playerid) + if player then + if player:getStorageValue(boss.stg) < boss.value then + player:setStorageValue(boss.stg, boss.value) + end + end + end + local teleport = Tile(boss.teleportPosition):getItemById(1387) + if teleport then + teleport:transform(25417) + teleport:setDestination(boss.toPosition) + addEvent(revert, 20*60*1000, boss.teleportPosition, boss.toPositionBack) + end + end + return true +end + +bossesMissionDepth:register() diff --git a/data/scripts/creaturescripts/quests/dangerous_depths/fiery_heart.lua b/data/scripts/creaturescripts/quests/dangerous_depths/fiery_heart.lua new file mode 100644 index 00000000000..2405c16918a --- /dev/null +++ b/data/scripts/creaturescripts/quests/dangerous_depths/fiery_heart.lua @@ -0,0 +1,82 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONHIT) + +local area = createCombatArea(AREA_CIRCLE3X3) +combat:setArea(area) + +function spellCallbackTemp(param) + local tile = Tile(Position(param.pos)) + if tile then + if tile:getTopCreature() and tile:getTopCreature():isMonster() then + if tile:getTopCreature():getName():lower() == "the duke of the depths" then + tile:getTopCreature():addHealth(math.random(0, 5000)) + end + elseif tile:getTopCreature() and tile:getTopCreature():isPlayer() then + tile:getTopCreature():addHealth(- math.random(0, 1500)) + end + end +end + +function onTargetTile(cid, pos) + local param = {} + param.cid = cid + param.pos = pos + param.count = 0 + spellCallbackTemp(param) +end + +setCombatCallback(combat, CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +local function suicideHeart(creature) + local monster = Creature(creature) + if monster then + local monsterPos = monster:getPosition() + monster:remove() + local fieryBlood = Game.createMonster("fiery blood", monsterPos, true, true) + if fieryBlood then + local var = {type = 1, number = fieryBlood:getId()} + combat:execute(fieryBlood, var) + end + end +end + +local fieryHeartThink = CreatureEvent("FieryHeartThink") +function fieryHeartThink.onThink(creature) + if not creature:isMonster() then + return true + end + local contadorHearts = 0 + local bossId + if creature:getName():lower() == "the duke of the depths" then + bossId = Creature(creature:getId()) + local spectators = Game.getSpectators(creature:getPosition(), false, false, 20, 20, 20, 20) + for _, spectator in pairs(spectators) do + if spectator:getName():lower() == "fiery heart" then + contadorHearts = contadorHearts + 1 + end + end + if contadorHearts < 1 then + if bossId then + local oldBossHealth = bossId:getHealth() + local oldBossPosition = bossId:getPosition() + bossId:remove() + local newBoss = Game.createMonster("the duke of the depths", oldBossPosition, true, true) + if newBoss then + newBoss:registerEvent("the duke heal fire damage") + newBoss:addHealth(-(newBoss:getHealth() - oldBossHealth)) + end + end + end + end + + if creature:getName():lower() == "fiery heart" then + if creature then + addEvent(suicideHeart, 20*1000, creature:getId()) + end + end + + return true +end + +fieryHeartThink:register() diff --git a/data/scripts/creaturescripts/quests/dangerous_depths/lost_exile_task.lua b/data/scripts/creaturescripts/quests/dangerous_depths/lost_exile_task.lua new file mode 100644 index 00000000000..7f12c6f154d --- /dev/null +++ b/data/scripts/creaturescripts/quests/dangerous_depths/lost_exile_task.lua @@ -0,0 +1,44 @@ +local lostExileKill = CreatureEvent("LostExileKill") +function lostExileKill.onKill(creature, target) + if not creature or not creature:isPlayer() then + return true + end + + if not target or not target:isMonster() then + return true + end + + local fromPos = Position(33768, 32227, 14) + local toPos = Position(33781, 32249, 14) + local monsterName = target:getName():lower() + + local storage = creature:getStorageValue(Storage.DangerousDepths.Dwarves.LostExiles) + local storage2 = creature:getStorageValue(Storage.DangerousDepths.Dwarves.Organisms) + if (isInArray({'lost exile'}, monsterName)) then + if creature:getStorageValue(Storage.DangerousDepths.Dwarves.Home) == 1 then + if target:getPosition():isInRange(fromPos, toPos) then + if storage < 20 then + if storage < 0 then + creature:setStorageValue(Storage.DangerousDepths.Dwarves.LostExiles, 1) + end + creature:setStorageValue(Storage.DangerousDepths.Dwarves.LostExiles, storage + 1) + end + end + end + elseif (isInArray({'deepworm', 'diremaw'}, monsterName)) then + if creature:getStorageValue(Storage.DangerousDepths.Dwarves.Subterranean) == 1 then + if storage2 < 50 then + if storage2 < 0 then + creature:setStorageValue(Storage.DangerousDepths.Dwarves.Organisms, 1) + end + creature:setStorageValue(Storage.DangerousDepths.Dwarves.Organisms, storage2 + 1) + end + end + elseif (isInArray({'makeshift home'}, monsterName)) then + local woodenTrash = Game.createItem(7701, 1, target:getPosition()) + woodenTrash:setActionId(57233) + end + return true +end + +lostExileKill:register() diff --git a/data/scripts/creaturescripts/quests/dangerous_depths/snail_slime_kill.lua b/data/scripts/creaturescripts/quests/dangerous_depths/snail_slime_kill.lua new file mode 100644 index 00000000000..dfc19937d3e --- /dev/null +++ b/data/scripts/creaturescripts/quests/dangerous_depths/snail_slime_kill.lua @@ -0,0 +1,81 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONHIT) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) + +function spellCallbackTemp(param) + local tile = Tile(Position(param.pos)) + if tile then + if tile:getTopCreature() and tile:getTopCreature():isMonster() then + if tile:getTopCreature():getName():lower() == "the count of the core" then + tile:getTopCreature():addHealth(math.random(0, 5000)) + end + end + end +end + +function onTargetTile(cid, pos) + local param = {} + param.cid = cid + param.pos = pos + param.count = 0 + spellCallbackTemp(param) +end + +setCombatCallback(combat, CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +local function summonSlimes(master) + local contador = 0 + local slimeCheck = Game.getSpectators(master:getPosition(), false, false, 20, 20, 20, 20) + for _, slime in pairs(slimeCheck) do + if slime:isMonster() then + if slime:getName():lower() == "snail slime" then + contador = contador + 1 + end + end + end + if contador < 3 then + local summon = Game.createMonster("Snail Slime", master:getPosition(), true) + end +end + +local snailSlimeThink = CreatureEvent("SnailSlimeThink") +function snailSlimeThink.onThink(creature) + if not creature:isMonster() then + return true + end + if creature:getName():lower() == "the count of the core" then + local percHealth = (creature:getHealth()/creature:getMaxHealth())*100 + if percHealth <= 50 then + summonSlimes(creature) + end + end + return true +end + +snailSlimeThink:register() + +local snailSlimeKill = CreatureEvent("SnailSlimeKill") +function snailSlimeKill.onKill(player, creature) + if not player:isPlayer() then + return true + end + if not creature:isMonster() or creature:getMaster() then + return true + end + + local monsterName = creature:getName():lower() + if monsterName == "snail slime" then + if not creature then + return + end + creature:say("!!", TALKTYPE_ORANGE_2) + local var = {type = 1, number = creature:getId()} + combat:execute(creature, var) + end +return true +end + +snailSlimeKill:register() diff --git a/data/scripts/creaturescripts/quests/dangerous_depths/the_baron_from_below.lua b/data/scripts/creaturescripts/quests/dangerous_depths/the_baron_from_below.lua new file mode 100644 index 00000000000..0585e7ed8bf --- /dev/null +++ b/data/scripts/creaturescripts/quests/dangerous_depths/the_baron_from_below.lua @@ -0,0 +1,87 @@ +local function summonHungry(creature) + local monster = Creature(creature) + local organic = false + if monster then + monster:remove() + local hungryBoss = Game.createMonster("the hungry baron from below", Position(33648, 32300, 15), true, true) + local organicMatter = Game.createMonster("organic matter", Position(33647, 32300, 15), true, true) + if hungryBoss then + hungryBoss:registerEvent("the baron from below think") + hungryBoss:addHealth(-(hungryBoss:getHealth() - monster:getHealth())) + hungryBoss:say("Gulp!", TALKTYPE_MONSTER_SAY) + addEvent(function() + if hungryBoss then + hungryBoss:say("Gulp!", TALKTYPE_MONSTER_SAY) + end + end, 2*1000) + addEvent(function() + local spectators = Game.getSpectators(Position(33648, 32303, 15), false, false, 20, 20, 20, 20) + for _, checagem in pairs(spectators) do + if checagem then + if checagem:getName():lower() == "organic matter" then + organic = true + end + end + end + if organic == true then + local organicPosition = organicMatter:getPosition() + organicMatter:remove() + local hungryBossHealth = hungryBoss:getHealth() + local hungryBossPosition = hungryBoss:getPosition() + hungryBoss:remove() + local newBoss = Game.createMonster("the baron from below", hungryBossPosition, true, true) + if newBoss then + newBoss:registerEvent("the baron from below think") + newBoss:addHealth( - (newBoss:getHealth() - hungryBossHealth)) + newBoss:addHealth(math.random(10000, 30000)) + for i = 1, 4 do + Game.createMonster("Aggressive Matter", organicPosition, true, false) + end + end + else + local hungryBossHealth = hungryBoss:getHealth() + local hungryBossPosition = hungryBoss:getPosition() + hungryBoss:remove() + local newBoss = Game.createMonster("the baron from below", hungryBossPosition, true, true) + if newBoss then + newBoss:registerEvent("the baron from below think") + newBoss:addHealth( - (newBoss:getHealth() - hungryBossHealth)) + end + end + end, 10*1000) + end + end +end + +local theBaronFromBelowThink = CreatureEvent("TheBaronFromBelowThink") +function theBaronFromBelowThink.onThink(creature) + if not creature:isMonster() then + return true + end + + if creature:getName():lower() == "the baron from below" then + addEvent(summonHungry, 30*1000, creature:getId()) + end + return true +end + +theBaronFromBelowThink:register() + +local theBaronFromBelowKill = CreatureEvent("TheBaronFromBelowKill") +function theBaronFromBelowKill.onKill(player, creature) + if not player:isPlayer() then + return true + end + + if not creature:isMonster() then + return true + end + + if creature:getName():lower() == "organic matter" then + for i = 1, 4 do + Game.createMonster("aggressive matter", creature:getPosition(), true, false) + end + end +end + +theBaronFromBelowKill:register() diff --git a/data/scripts/creaturescripts/quests/dangerous_depths/the_duke_heal_fire_damage.lua b/data/scripts/creaturescripts/quests/dangerous_depths/the_duke_heal_fire_damage.lua new file mode 100644 index 00000000000..e620a85d6a6 --- /dev/null +++ b/data/scripts/creaturescripts/quests/dangerous_depths/the_duke_heal_fire_damage.lua @@ -0,0 +1,10 @@ +local theDukeHealFireDamage = CreatureEvent("TheDukeHealFireDamage") +function theDukeHealFireDamage.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin) + if primaryType == COMBAT_FIREDAMAGE then + creature:addHealth(primaryDamage) + primaryDamage = 0 + end + return primaryDamage, primaryType, secondaryDamage, secondaryType +end + +theDukeHealFireDamage:register() diff --git a/data/scripts/creaturescripts/quests/dark_trails/kill_death_priest_shargon.lua b/data/scripts/creaturescripts/quests/dark_trails/kill_death_priest_shargon.lua new file mode 100644 index 00000000000..fc858d9d2a9 --- /dev/null +++ b/data/scripts/creaturescripts/quests/dark_trails/kill_death_priest_shargon.lua @@ -0,0 +1,28 @@ +local function removeTeleport(position) + local teleportItem = Tile({x = 33487, y = 32101, z = 9}):getItemById(1387) + if teleportItem then + teleportItem:remove() + position:sendMagicEffect(CONST_ME_POFF) + end +end + +local deathPriestShargon = CreatureEvent("ShargonKill") +function deathPriestShargon.onKill(creature, target) + if target:isPlayer() or target:getMaster() or target:getName():lower() ~= "death priest shargon" then + return true + end + + local position = target:getPosition() + position:sendMagicEffect(CONST_ME_TELEPORT) + local item = Game.createItem(1387, 1, {x = 33487, y = 32101, z = 9}) + if item:isTeleport() then + item:setDestination(Position(33489,32088,9)) + end + if creature:getStorageValue(Storage.DarkTrails.Mission18) < 1 then + creature:setStorageValue(Storage.DarkTrails.Mission18, 1) + end + addEvent(removeTeleport, 5 * 60 * 1000, position) + return true +end + +deathPriestShargon:register() diff --git a/data/scripts/creaturescripts/quests/dark_trails/kill_the_ravager.lua b/data/scripts/creaturescripts/quests/dark_trails/kill_the_ravager.lua new file mode 100644 index 00000000000..fddbb927110 --- /dev/null +++ b/data/scripts/creaturescripts/quests/dark_trails/kill_the_ravager.lua @@ -0,0 +1,28 @@ +local function removeTeleport(position) + local teleportItem = Tile({x = 33496, y = 32070, z = 8}):getItemById(1387) + if teleportItem then + teleportItem:remove() + position:sendMagicEffect(CONST_ME_POFF) + end +end + +local theRavager = CreatureEvent("TheRavager") +function theRavager.onKill(creature, target) + if target:isPlayer() or target:getMaster() or target:getName():lower() ~= "the ravager" then + return true + end + + local position = target:getPosition() + position:sendMagicEffect(CONST_ME_TELEPORT) + local item = Game.createItem(1387, 1, {x = 33496, y = 32070, z = 8}) + if item:isTeleport() then + item:setDestination(Position(33459,32083,8)) + end + if creature:getStorageValue(Storage.DarkTrails.Mission11) < 1 then + creature:setStorageValue(Storage.DarkTrails.Mission11, 1) + end + addEvent(removeTeleport, 5 * 60 * 1000, position) + return true +end + +theRavager:register() diff --git a/data/scripts/creaturescripts/quests/dark_trails/think_the_ravager_heal.lua b/data/scripts/creaturescripts/quests/dark_trails/think_the_ravager_heal.lua new file mode 100644 index 00000000000..7434352e7cb --- /dev/null +++ b/data/scripts/creaturescripts/quests/dark_trails/think_the_ravager_heal.lua @@ -0,0 +1,17 @@ +local theRavagerHeal = CreatureEvent("TheRavagerHeal") + +function theRavagerHeal.onThink(creature) + local health = math.random(7500, 9000) + local hp = (creature:getHealth()/creature:getMaxHealth())*100 + if creature:getName() == "The Ravager" and (hp < 99.99) then + local tile = Tile(creature:getPosition()):getItemById(3172) + if not tile then + return true + end + creature:addHealth(health) + creature:say("The Ravager is healed by the strange floor rune!", TALKTYPE_ORANGE_1) + end + return true +end + +theRavagerHeal:register() diff --git a/data/scripts/creaturescripts/quests/dawnport/goblin_kill.lua b/data/scripts/creaturescripts/quests/dawnport/goblin_kill.lua new file mode 100644 index 00000000000..f3102add229 --- /dev/null +++ b/data/scripts/creaturescripts/quests/dawnport/goblin_kill.lua @@ -0,0 +1,19 @@ +local goblinKill = CreatureEvent("MorrisGoblinKill") + +function onKill(player, target) + if target:isPlayer() or target:getMaster() then + return true + end + + if not target:getName():lower() == "muglex clan footman" then + return true + end + + local killAmount = player:getStorageValue(Storage.Quest.Dawnport.MorrisGoblinCount) + if player:getStorageValue(Storage.Quest.Dawnport.MorrisGoblin) == 1 and killAmount < 20 then + player:setStorageValue(Storage.Quest.Dawnport.MorrisGoblinCount, killAmount + 1) + end + return true +end + +goblinKill:register() diff --git a/data/scripts/creaturescripts/quests/dawnport/minotaur_kill.lua b/data/scripts/creaturescripts/quests/dawnport/minotaur_kill.lua new file mode 100644 index 00000000000..6d049f8d37e --- /dev/null +++ b/data/scripts/creaturescripts/quests/dawnport/minotaur_kill.lua @@ -0,0 +1,19 @@ +local minotaurKill = CreatureEvent("MorrisMinotaurKill") + +function minotaurKill.onKill(player, target) + if target:isPlayer() or target:getMaster() then + return true + end + + if not target:getName():lower() == "minotaur bruiser" then + return true + end + + local killAmount = player:getStorageValue(Storage.Quest.Dawnport.MorrisMinosCount) + if player:getStorageValue(Storage.Quest.Dawnport.MorrisMinos) == 1 and killAmount < 20 then + player:setStorageValue(Storage.Quest.Dawnport.MorrisMinosCount, killAmount + 1) + end + return true +end + +minotaurKill:register() diff --git a/data/scripts/creaturescripts/quests/dawnport/troll_kill.lua b/data/scripts/creaturescripts/quests/dawnport/troll_kill.lua new file mode 100644 index 00000000000..74805a77427 --- /dev/null +++ b/data/scripts/creaturescripts/quests/dawnport/troll_kill.lua @@ -0,0 +1,18 @@ +local trollKill = CreatureEvent("MorrisTrollKill") +function trollKill.onKill(player, target) + if target:isPlayer() or target:getMaster() then + return true + end + + if not target:getName():lower() == "mountain troll" then + return true + end + + local killAmount = player:getStorageValue(Storage.Quest.Dawnport.MorrisTrollCount) + if player:getStorageValue(Storage.Quest.Dawnport.MorriskTroll) == 1 and killAmount < 5000 then + player:setStorageValue(Storage.Quest.Dawnport.MorrisTrollCount, killAmount + 1) + end + return true +end + +trollKill:register() diff --git a/data/scripts/creaturescripts/quests/elemental_spheres/overlord_kill.lua b/data/scripts/creaturescripts/quests/elemental_spheres/overlord_kill.lua new file mode 100644 index 00000000000..0e9afdf1f96 --- /dev/null +++ b/data/scripts/creaturescripts/quests/elemental_spheres/overlord_kill.lua @@ -0,0 +1,33 @@ +local overlords = { + ['energy overlord'] = {storage = Storage.ElementalSphere.BossStorage, globalStorage = GlobalStorage.ElementalSphere.KnightBoss}, + ['fire overlord'] = {storage = Storage.ElementalSphere.BossStorage, globalStorage = GlobalStorage.ElementalSphere.SorcererBoss}, + ['ice overlord'] = {storage = Storage.ElementalSphere.BossStorage, globalStorage = GlobalStorage.ElementalSphere.PaladinBoss}, + ['earth overlord'] = {storage = Storage.ElementalSphere.BossStorage, globalStorage = GlobalStorage.ElementalSphere.DruidBoss}, + ['lord of the elements'] = {} +} + +local elementalSpheresOver = CreatureEvent("OverlordKill") +function elementalSpheresOver.onKill(creature, target) + if not target:isMonster() then + return true + end + + local bossName = target:getName() + local bossConfig = overlords[bossName:lower()] + if not bossConfig then + return true + end + + if bossConfig.globalStorage then + Game.setStorageValue(bossConfig.globalStorage, 0) + end + + if bossConfig.storage and creature:getStorageValue(bossConfig.storage) < 1 then + creature:setStorageValue(bossConfig.storage, 1) + end + + creature:say('You slayed ' .. bossName .. '.', TALKTYPE_MONSTER_SAY) + return true +end + +elementalSpheresOver:register() diff --git a/data/scripts/creaturescripts/quests/ferumbras_ascendant/bone_capsule.lua b/data/scripts/creaturescripts/quests/ferumbras_ascendant/bone_capsule.lua new file mode 100644 index 00000000000..463bd1c1da9 --- /dev/null +++ b/data/scripts/creaturescripts/quests/ferumbras_ascendant/bone_capsule.lua @@ -0,0 +1,21 @@ +local boneCapsule = CreatureEvent("BoneCapsule") +function boneCapsule.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + local targetMonster = creature:getMonster() + local position = targetMonster:getPosition() + position:sendMagicEffect(CONST_ME_POFF) + if not targetMonster or targetMonster:getName():lower() ~= 'bone capsule' then + return true + end + + local monster = Game.createMonster('bone capsule', Position(33485, 32333, 14), true, true) + if not monster then + return true + end + + local ragiaz = Tile(Position(33487, 32333, 14)):getTopCreature() + ragiaz:teleportTo(position) + ragiaz:addHealth(math.random(25000, 35000), true, true) + return true +end + +boneCapsule:register() diff --git a/data/scripts/creaturescripts/quests/ferumbras_ascendant/bosses_kill.lua b/data/scripts/creaturescripts/quests/ferumbras_ascendant/bosses_kill.lua new file mode 100644 index 00000000000..7a1e56948af --- /dev/null +++ b/data/scripts/creaturescripts/quests/ferumbras_ascendant/bosses_kill.lua @@ -0,0 +1,87 @@ +local bosses = { + ['the lord of the lice'] = {teleportPos = Position(33226, 31478, 12), godbreakerPos = Position(33237, 31477, 13)}, + ['tarbaz'] = {teleportPos = Position(33460, 32853, 11), godbreakerPos = Position(33427, 32852, 13), timer = Storage.FerumbrasAscension.TarbazTimer}, + ['ragiaz'] = {teleportPos = Position(33482, 32345, 13), godbreakerPos = Position(33466, 32392, 13), timer = Storage.FerumbrasAscension.RagiazTimer}, + ['plagirath'] = {teleportPos = Position(33174, 31511, 13), godbreakerPos = Position(33204, 31510, 13), timer = Storage.FerumbrasAscension.PlagirathTimer}, + ['razzagorn'] = {teleportPos = Position(33413, 32467, 14), godbreakerPos = Position(33357, 32440, 13), timer = Storage.FerumbrasAscension.RazzagornTimer}, + ['zamulosh'] = {teleportPos = Position(33644, 32764, 11), godbreakerPos = Position(33678, 32758, 13), timer = Storage.FerumbrasAscension.ZamuloshTimer}, + ['mazoran'] = {teleportPos = Position(33585, 32699, 14), godbreakerPos = Position(33614, 32679, 15), timer = Storage.FerumbrasAscension.MazoranTimer}, + ['shulgrax'] = {teleportPos = Position(33486, 32796, 13), godbreakerPos = Position(33459, 32820, 14), timer = Storage.FerumbrasAscension.ShulgraxTimer}, + ['ferumbras mortal shell'] = {teleportPos = Position(33392, 31485, 14), godbreakerPos = Position(33388, 31414, 14), timer = Storage.FerumbrasAscension.FerumbrasTimer} +} + +local crystals = { + [1] = {crystalPosition = Position(33390, 31468, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal1}, + [2] = {crystalPosition = Position(33394, 31468, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal2}, + [3] = {crystalPosition = Position(33397, 31471, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal3}, + [4] = {crystalPosition = Position(33397, 31475, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal4}, + [5] = {crystalPosition = Position(33394, 31478, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal5}, + [6] = {crystalPosition = Position(33390, 31478, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal6}, + [7] = {crystalPosition = Position(33387, 31475, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal7}, + [8] = {crystalPosition = Position(33387, 31471, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal8} +} +local function transformCrystal() + for c = 1, #crystals do + local crystal = crystals[c] + Game.getStorageValue(crystal.globalStorage, 0) + Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Crystals.AllCrystals, 0) + local item = Tile(crystal.crystalPosition):getItemById(17586) + if item then + item:transform(17580) + end + end +end + +local function revertTeleport(position, itemId, transformId, destination) + local item = Tile(position):getItemById(itemId) + if item then + item:transform(transformId) + item:setDestination(destination) + end +end + +local ascendantBossesKill = CreatureEvent("AscendantBossesKill") +function ascendantBossesKill.onKill(creature, target) + local targetMonster = target:getMonster() + if not targetMonster or targetMonster:getMaster() then + return true + end + + local bossConfig = bosses[targetMonster:getName():lower()] + if not bossConfig then + return true + end + + for key, value in pairs(targetMonster:getDamageMap()) do + local attackerPlayer = Player(pid) + if attackerPlayer then + if bossConfig.timer then + attackerPlayer:setStorageValue(bossConfig.timer, os.time() + 20 * 3600) + elseif targetMonster:getName():lower() == 'ferumbras mortal shell' then + if bossConfig.timer then + attackerPlayer:setStorageValue(bossConfig.timer, os.time() + 60 * 60 * 14 * 24) + end + elseif targetMonster:getName():lower() == 'the lord of the lice' then + attackerPlayer:setStorageValue(Storage.FerumbrasAscension.TheLordOfTheLiceAccess, 1) + end + end + end + + local teleport = Tile(bossConfig.teleportPos):getItemById(1387) + if not teleport then + return true + end + + if teleport then + teleport:transform(25417) + targetMonster:getPosition():sendMagicEffect(CONST_ME_THUNDER) + teleport:setDestination(bossConfig.godbreakerPos) + addEvent(revertTeleport, 2 * 60 * 1000, bossConfig.teleportPos, 25417, 1387, teleport:getDestination()) + end + + if targetMonster:getName():lower() == 'ferumbras mortal shell' then + addEvent(transformCrystal, 2 * 60 * 1000) + end + return true +end +ascendantBossesKill:register() diff --git a/data/scripts/creaturescripts/quests/ferumbras_ascendant/death_dragon.lua b/data/scripts/creaturescripts/quests/ferumbras_ascendant/death_dragon.lua new file mode 100644 index 00000000000..e03f803afd9 --- /dev/null +++ b/data/scripts/creaturescripts/quests/ferumbras_ascendant/death_dragon.lua @@ -0,0 +1,24 @@ +local deathDragon = CreatureEvent("DeathDragon") +function deathDragon.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + local targetMonster = creature:getMonster() + if not targetMonster or targetMonster:getName():lower() ~= 'death dragon' then + return true + end + + local monster = addEvent(Game.createMonster, 1 * 1000, 'death dragon', creature:getPosition(), true, true) + if not monster then + return true + end + + local spectators = Game.getSpectators(targetMonster:getPosition(), false, false, 10, 10, 10, 10) + for i = 1, #spectators do + local spectator = spectators[i] + if spectator:isMonster() and spectator:getName():lower() == 'ragiaz' then + spectator:say('Ragiaz power revives his minion!', TALKTYPE_MONSTER_SAY) + return true + end + end + return true +end + +deathDragon:register() diff --git a/data/scripts/creaturescripts/quests/ferumbras_ascendant/disgusting_ooze_death.lua b/data/scripts/creaturescripts/quests/ferumbras_ascendant/disgusting_ooze_death.lua new file mode 100644 index 00000000000..3bc5663b1ec --- /dev/null +++ b/data/scripts/creaturescripts/quests/ferumbras_ascendant/disgusting_ooze_death.lua @@ -0,0 +1,21 @@ +local disgustingOozeDeath = CreatureEvent("DisgustingOozeDeath") +function disgustingOozeDeath.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + local targetMonster = creature:getMonster() + if not targetMonster or targetMonster:getName():lower() ~= 'disgusting ooze' then + return true + end + + if math.random(20) < 3 then + for i = 1, 2 do + local monster = Game.createMonster('disgusting ooze', targetMonster:getPosition(), false, true) + if not monster then + return true + end + monster:setMaster(targetMonster:getMaster()) + end + targetMonster:say('The ooze splits and regenerates.', TALKTYPE_MONSTER_SAY) + end + return true +end + +disgustingOozeDeath:register() diff --git a/data/scripts/creaturescripts/quests/ferumbras_ascendant/ferumbras_mortal_shell_death.lua b/data/scripts/creaturescripts/quests/ferumbras_ascendant/ferumbras_mortal_shell_death.lua new file mode 100644 index 00000000000..be8850315d6 --- /dev/null +++ b/data/scripts/creaturescripts/quests/ferumbras_ascendant/ferumbras_mortal_shell_death.lua @@ -0,0 +1,17 @@ +local ferumbrasMortalShell = CreatureEvent("FerumbrasMortalShell") +function ferumbrasMortalShell.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + local targetMonster = creature:getMonster() + if not targetMonster or targetMonster:getName():lower() ~= 'destabilized ferumbras' then + return true + end + + local monster = Game.createMonster('Ferumbras Mortal Shell', Position(33392, 31473, 14), true, true) + if not monster then + return true + end + monster:say('AAAAAAAAAAAAAAAAAAHHHHHHHHHHHHHH!', TALKTYPE_MONSTER_SAY) + lasthitkiller:say('FINALY YOU FORCED FERUMBRAS BACK INTO A MORTAL FORM - HE IS NOT AMUSED!', TALKTYPE_MONSTER_SAY, nil, nil, Position(33392, 31475, 14)) + return true +end + +ferumbrasMortalShell:register() diff --git a/data/scripts/creaturescripts/quests/ferumbras_ascendant/ferumbras_soul_splinter.lua b/data/scripts/creaturescripts/quests/ferumbras_ascendant/ferumbras_soul_splinter.lua new file mode 100644 index 00000000000..a57cbfd9b49 --- /dev/null +++ b/data/scripts/creaturescripts/quests/ferumbras_ascendant/ferumbras_soul_splinter.lua @@ -0,0 +1,15 @@ +local ferumbrasSoulSplinter = CreatureEvent("FerumbrasSoulSplinter") +function ferumbrasSoulSplinter.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + local targetMonster = creature:getMonster() + if not targetMonster or targetMonster:getName():lower() ~= 'ferumbras soul splinter' then + return true + end + + local monster = Game.createMonster('ferumbras essence', targetMonster:getPosition(), true, true) + if not monster then + return true + end + return true +end + +ferumbrasSoulSplinter:register() diff --git a/data/scripts/creaturescripts/quests/ferumbras_ascendant/rift_invader_death.lua b/data/scripts/creaturescripts/quests/ferumbras_ascendant/rift_invader_death.lua new file mode 100644 index 00000000000..4a2d6fd785b --- /dev/null +++ b/data/scripts/creaturescripts/quests/ferumbras_ascendant/rift_invader_death.lua @@ -0,0 +1,58 @@ +local crystals = { + [1] = {fromPosition = Position(33389, 31467, 14), toPosition = Position(33391, 31469, 14), crystalPosition = Position(33390, 31468, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal1}, + [2] = {fromPosition = Position(33393, 31467, 14), toPosition = Position(33395, 31469, 14), crystalPosition = Position(33394, 31468, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal2}, + [3] = {fromPosition = Position(33396, 31470, 14), toPosition = Position(33398, 31472, 14), crystalPosition = Position(33397, 31471, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal3}, + [4] = {fromPosition = Position(33396, 31474, 14), toPosition = Position(33398, 31476, 14), crystalPosition = Position(33397, 31475, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal4}, + [5] = {fromPosition = Position(33393, 31477, 14), toPosition = Position(33395, 31479, 14), crystalPosition = Position(33394, 31478, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal5}, + [6] = {fromPosition = Position(33389, 31477, 14), toPosition = Position(33391, 31479, 14), crystalPosition = Position(33390, 31478, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal6}, + [7] = {fromPosition = Position(33386, 31474, 14), toPosition = Position(33388, 31476, 14), crystalPosition = Position(33387, 31475, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal7}, + [8] = {fromPosition = Position(33386, 31470, 14), toPosition = Position(33388, 31472, 14), crystalPosition = Position(33387, 31471, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal8} +} + +local riftInvaderDeath = CreatureEvent("RiftInvaderDeath") +function riftInvaderDeath.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + if not targetMonster or targetMonster:getName():lower() ~= 'rift invader' then + return true + end + + local targetMonster = creature:getMonster() + local pos = Position(33392 + math.random(-10, 10), 31473 + math.random(-10, 10), 14) + local name = targetMonster:getName():lower() + Game.createMonster(name, pos) + + for i = 1, #crystals do + local crystal = crystals[i] + if isInRange(targetMonster:getPosition(), crystal.fromPosition, crystal.toPosition) then + if Game.getStorageValue(crystal.globalStorage) > 8 then + local item = Tile(crystal.crystalPosition):getItemById(17580) + if not item then + return true + end + item:transform(17586) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Crystals.AllCrystals, Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Crystals.AllCrystals) + 1) + end + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Crystals.AllCrystals) == 8 then + local creature = Tile(Position(33392, 31473, 14)):getTopCreature() + creature:say('NOOOOOOOOOOO!', TALKTYPE_MONSTER_YELL) + creature:say('FERUMBRAS BURSTS INTO SOUL SPLINTERS!', TALKTYPE_MONSTER_YELL, nil, nil, Position(33392, 31475, 14)) + creature:remove() + for a = 1, #crystals do + local crystalEffect = crystals[i] + crystalEffect.crystalPosition:sendMagicEffect(CONST_ME_FERUMBRAS) + Game.createMonster('Ferumbras Soul Splinter', Position(33392, 31473, 14), false, true) + end + end + Game.setStorageValue(crystal.globalStorage, Game.getStorageValue(crystal.globalStorage) + 1) + lasthitkiller:say("The negative energy of the rift creature is absorbed by the crystal!", TALKTYPE_MONSTER_SAY, nil, nil, crystal.crystalPosition) + lasthitkiller:say("ARGH!", TALKTYPE_MONSTER_SAY, nil, nil, Position(33392, 31473, 14)) + end + end + + local vortex = Game.createItem(22455, 1, creature:getPosition()) + addEvent(function() + vortex:remove(1) + end, 10 * 1000) + return true +end + +riftInvaderDeath:register() diff --git a/data/scripts/creaturescripts/quests/ferumbras_ascendant/the_shatterer_kill.lua b/data/scripts/creaturescripts/quests/ferumbras_ascendant/the_shatterer_kill.lua new file mode 100644 index 00000000000..1f0bd1af5cf --- /dev/null +++ b/data/scripts/creaturescripts/quests/ferumbras_ascendant/the_shatterer_kill.lua @@ -0,0 +1,111 @@ +local function revertTeleport(position, itemId, transformId, destination) + local item = Tile(position):getItemById(itemId) + if item then + item:transform(transformId) + item:setDestination(destination) + end +end + +local chains = { + West = { + [1] = {itemid = 23656, position = Position(33401, 32419, 14)}, + [2] = {itemid = 23655, position = Position(33402, 32419, 14)}, + [3] = {itemid = 23655, position = Position(33403, 32419, 14)}, + [4] = {itemid = 23657, position = Position(33404, 32419, 14)}, + [5] = {itemid = 23656, position = Position(33405, 32419, 14)}, + [6] = {itemid = 23657, position = Position(33406, 32419, 14)}, + [7] = {itemid = 1495, position = Position(33403, 32418, 14)}, + [8] = {itemid = 1495, position = Position(33404, 32418, 14)} + }, + North = { + [1] = {itemid = 23659, position = Position(33407, 32414, 14)}, + [2] = {itemid = 23658, position = Position(33407, 32415, 14)}, + [3] = {itemid = 23660, position = Position(33407, 32416, 14)}, + [4] = {itemid = 23659, position = Position(33407, 32417, 14)}, + [5] = {itemid = 23660, position = Position(33407, 32418, 14)}, + [6] = {itemid = 1495, position = Position(33406, 32415, 14)}, + [7] = {itemid = 1495, position = Position(33406, 32416, 14)} + }, + East = { + [1] = {itemid = 23656, position = Position(33408, 32419, 14)}, + [2] = {itemid = 23657, position = Position(33409, 32419, 14)}, + [3] = {itemid = 23656, position = Position(33410, 32419, 14)}, + [4] = {itemid = 23655, position = Position(33411, 32419, 14)}, + [5] = {itemid = 23657, position = Position(33412, 32419, 14)}, + [6] = {itemid = 1495, position = Position(33408, 32418, 14)}, + [7] = {itemid = 1495, position = Position(33409, 32418, 14)} + }, + South = { + [1] = {itemid = 23659, position = Position(33407, 32420, 14)}, + [2] = {itemid = 23660, position = Position(33407, 32421, 14)}, + [3] = {itemid = 23659, position = Position(33407, 32422, 14)}, + [4] = {itemid = 23658, position = Position(33407, 32423, 14)}, + [5] = {itemid = 23660, position = Position(33407, 32424, 14)}, + [6] = {itemid = 1495, position = Position(33406, 32420, 14)}, + [7] = {itemid = 1495, position = Position(33406, 32421, 14)} + } +} +local levers = { + [1] = {position = Position(33385, 32410, 14)}, + [2] = {position = Position(33403, 32391, 14)}, + [3] = {position = Position(33430, 32418, 14)}, + [4] = {position = Position(33410, 32441, 14)} +} +local function revert() + for i = 1, #chains.West do + local chainWest = chains.West[i] + Game.createItem(chainWest.itemid, 1, chainWest.position) + end + for a = 1, #chains.North do + local chainNorth = chains.North[a] + Game.createItem(chainNorth.itemid, 1, chainNorth.position) + end + for k = 1, #chains.East do + local chainEast = chains.East[k] + Game.createItem(chainEast.itemid, 1, chainEast.position) + end + for b = 1, #chains.South do + local chainSouth = chains.South[b] + Game.createItem(chainSouth.itemid, 1, chainSouth.position) + end + for c = 1, #levers do + local lever = levers[c] + local leverT = Tile(lever.position):getItemById(9826) + if leverT then + leverT:transform(9825) + end + end +end + +local theShattererKill = CreatureEvent("TheShattererKill") +function theShattererKill.onKill(creature, target) + local targetMonster = target:getMonster() + if not targetMonster or targetMonster:getMaster() or targetMonster:getName():lower() ~= 'the shatterer' then + return true + end + for pid, _ in pairs(targetMonster:getDamageMap()) do + local attackerPlayer = Player(pid) + if attackerPlayer then + if targetMonster:getName():lower() == 'the shatterer' then + attackerPlayer:setStorageValue(Storage.FerumbrasAscension.TheShatterer, 1) + end + end + end + local teleport = Tile(Position(33393, 32438, 14)):getItemById(1387) + if not teleport then return true end + local oldPos = teleport:getDestination() + local teleportPos = Position(33393, 32438, 14) + local newPos = Position(33436, 32443, 15) + if teleport then + teleport:transform(25417) + targetMonster:getPosition():sendMagicEffect(CONST_ME_THUNDER) + teleport:setDestination(newPos) + addEvent(revertTeleport, 2 * 60 * 1000, teleportPos, 25417, 1387, oldPos) + revert() + end + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.TheShattererLever, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.TheShattererTimer, 0) + return true +end + +theShattererKill:register() diff --git a/data/scripts/creaturescripts/quests/ferumbras_ascendant/zamulosh_clone.lua b/data/scripts/creaturescripts/quests/ferumbras_ascendant/zamulosh_clone.lua new file mode 100644 index 00000000000..73ba7dc3b37 --- /dev/null +++ b/data/scripts/creaturescripts/quests/ferumbras_ascendant/zamulosh_clone.lua @@ -0,0 +1,25 @@ +function onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + local targetMonster = creature:getMonster() + if not targetMonster or targetMonster:getName():lower() ~= 'zamulosh' and not targetMonster:getMaster() then + return true + end + + local monster = Game.createMonster('Zamulosh3', targetMonster:getPosition(), true, true) + if not monster then + return true + end + return true +end + +local zamuloshClone = CreatureEvent("ZamuloshClone") +function zamuloshClone.onThink(creature) + local spectators = Game.getSpectators(Position(33644, 32757, 11), false, false, 10, 10, 10, 10) + for i = 1, #spectators do + local master = spectators[i] + if master:getMaxHealth() == 300000 and not master:getMaster() then + master:addSummon(creature) + end + end +end + +zamuloshClone:register() diff --git a/data/scripts/creaturescripts/quests/firewalker_boots/pythius_the_rotten_kill.lua b/data/scripts/creaturescripts/quests/firewalker_boots/pythius_the_rotten_kill.lua new file mode 100644 index 00000000000..43543a8cbd7 --- /dev/null +++ b/data/scripts/creaturescripts/quests/firewalker_boots/pythius_the_rotten_kill.lua @@ -0,0 +1,14 @@ +local firewalkerBootsKill = CreatureEvent("PythiusTheRottenKill") +function firewalkerBootsKill.onKill(player, target) + if not target:isMonster() or target:getName():lower() ~= "pythius the rotten" then + return true + end + + target:say("NICE FIGHTING LITTLE WORM, YOUR VICTORY SHALL BE REWARDED!", TALKTYPE_MONSTER_SAY, false, player, Position(32572, 31405, 15)) + + player:teleportTo(Position(32577, 31403, 15)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +firewalkerBootsKill:register() diff --git a/data/scripts/creaturescripts/quests/first_dragon/death_angry_plant.lua b/data/scripts/creaturescripts/quests/first_dragon/death_angry_plant.lua new file mode 100644 index 00000000000..14474b4c002 --- /dev/null +++ b/data/scripts/creaturescripts/quests/first_dragon/death_angry_plant.lua @@ -0,0 +1,10 @@ +local deathAngryPlant = CreatureEvent("Angry Plant Death") + +function deathAngryPlant.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + if corpse then + corpse:setAttribute(ITEM_ATTRIBUTE_UNIQUEID, 1066) + end + return true +end + +deathAngryPlant:register() diff --git a/data/scripts/creaturescripts/quests/first_dragon/death_dragon_essence.lua b/data/scripts/creaturescripts/quests/first_dragon/death_dragon_essence.lua new file mode 100644 index 00000000000..aaa553855ed --- /dev/null +++ b/data/scripts/creaturescripts/quests/first_dragon/death_dragon_essence.lua @@ -0,0 +1,16 @@ +local deathDragonEssence = CreatureEvent("Dragon Essence Death") + +function deathDragonEssence.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + local spectators = Game.getSpectators(Position(33617, 31023, 14), false, false, 14, 14, 14, 14) + for i = 1, #spectators do + local spec = spectators[i] + if spec:getName() == 'Dragon Essence' then + spec:remove() + end + end + Game.createMonster('The First Dragon', Position(33617, 31023, 14), true, true) + creature:say('BEWARE! THE FIRST DRAGON APROACHES!', TALKTYPE_MONSTER_SAY, false, nil, Position(33617, 31023, 14)) + return true +end + +deathDragonEssence:register() diff --git a/data/scripts/creaturescripts/quests/first_dragon/death_fallen.lua b/data/scripts/creaturescripts/quests/first_dragon/death_fallen.lua new file mode 100644 index 00000000000..b349601b942 --- /dev/null +++ b/data/scripts/creaturescripts/quests/first_dragon/death_fallen.lua @@ -0,0 +1,17 @@ +local deathFallen = CreatureEvent("Fallen Death") + +local function removeTp(position, itemid) + local teleport = Tile(position):getItemById(itemid) + if teleport then + teleport:remove() + end +end +function deathFallen.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + if corpse then + corpse:setDestination(Position(33621, 31023, 14)) + addEvent(removeTp, 30 * 1000, corpse:getPosition(), 1397) + end + return true +end + +deathFallen:register() diff --git a/data/scripts/creaturescripts/quests/first_dragon/death_first_dragon.lua b/data/scripts/creaturescripts/quests/first_dragon/death_first_dragon.lua new file mode 100644 index 00000000000..fad8bfb6d19 --- /dev/null +++ b/data/scripts/creaturescripts/quests/first_dragon/death_first_dragon.lua @@ -0,0 +1,34 @@ +local deathFirstDragon = CreatureEvent("First Dragon Death") + +local destinations = { + Position(33616, 31020, 13), + Position(33617, 31020, 13), + Position(33618, 31020, 13), + Position(33616, 31021, 13), + Position(33617, 31021, 13), + Position(33618, 31021, 13), + Position(33616, 31022, 13), + Position(33617, 31022, 13), + Position(33618, 31022, 13), + Position(33616, 31023, 13), + Position(33617, 31023, 13), + Position(33618, 31023, 13), + Position(33616, 31024, 13), + Position(33617, 31024, 13), + Position(33618, 31024, 13) +} + +function deathFirstDragon.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + local spectators = Game.getSpectators(Position(33617, 31023, 14), false, false, 14, 14, 14, 14) + for i = 1, #spectators do + local spec = spectators[i] + if spec:isPlayer() then + spec:teleportTo(Position(33617, 31020, 13)) + spec:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + spec:setStorageValue(Storage.FirstDragon.Feathers, 1) + end + end + return true +end + +deathFirstDragon:register() diff --git a/data/scripts/creaturescripts/quests/first_dragon/death_somewhat_beatable.lua b/data/scripts/creaturescripts/quests/first_dragon/death_somewhat_beatable.lua new file mode 100644 index 00000000000..2f192a3a302 --- /dev/null +++ b/data/scripts/creaturescripts/quests/first_dragon/death_somewhat_beatable.lua @@ -0,0 +1,24 @@ +local deathSomewhatBeatable = CreatureEvent("Somewhat Beatable Death") + +function deathSomewhatBeatable.onDeath(creature, target) + local spectators = Game.getSpectators(Position(33617, 31023, 14), false, false, 14, 14, 14, 14) + for i = 1, #spectators do + local spec = spectators[i] + if spec:isPlayer() then + if creature:getName():lower() == "somewhat beatable" then + if spec:getStorageValue(Storage.FirstDragon.SomewhatBeatable) < 5 then + spec:setStorageValue(Storage.FirstDragon.SomewhatBeatable, spec:getStorageValue(Storage.FirstDragon.SomewhatBeatable) + 1) + end + end + if spec:getStorageValue(Storage.FirstDragon.SomewhatBeatable) == 5 then + for b = 1, 6 do + Game.createMonster('Dragon Essence', Position(math.random(33609, 33624), math.random(31017, 31028), 14), true, true) + end + spec:setStorageValue(Storage.FirstDragon.SomewhatBeatable, 0) + end + end + end + return true +end + +deathSomewhatBeatable:register() diff --git a/data/scripts/creaturescripts/quests/first_dragon/kill_dragon.lua b/data/scripts/creaturescripts/quests/first_dragon/kill_dragon.lua new file mode 100644 index 00000000000..9ad90295190 --- /dev/null +++ b/data/scripts/creaturescripts/quests/first_dragon/kill_dragon.lua @@ -0,0 +1,19 @@ +local killDragon = CreatureEvent("Kill Dragon") + +function killDragon.onKill(player, target) + if target:isPlayer() or target:getMaster() then + return true + end + if target:getName():lower() == "dragon" then + local storage = player:getStorageValue(Storage.FirstDragon.DragonCounter) + if storage >= 0 and storage < 200 then + player:setStorageValue(Storage.FirstDragon.DragonCounter, player:getStorageValue(Storage.FirstDragon.DragonCounter) + 1) + end + end + if player:getStorageValue(Storage.FirstDragon.TazhadurTimer) >= os.time() then + return true + end + return true +end + +killDragon:register() diff --git a/data/scripts/creaturescripts/quests/forgotten_knowledge/astral_glyph_death.lua b/data/scripts/creaturescripts/quests/forgotten_knowledge/astral_glyph_death.lua new file mode 100644 index 00000000000..2a921e70ff2 --- /dev/null +++ b/data/scripts/creaturescripts/quests/forgotten_knowledge/astral_glyph_death.lua @@ -0,0 +1,13 @@ +local astralGlyphDeath = CreatureEvent("AstralGlyphDeath") +function astralGlyphDeath.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + local targetMonster = creature:getMonster() + if not targetMonster then + return true + end + + if targetMonster:getName():lower() == 'an astral glyph' then + Game.createMonster('the last lore keeper', targetMonster:getPosition(), true, true) + end + return true +end +astralGlyphDeath:register() diff --git a/data/scripts/creaturescripts/quests/forgotten_knowledge/astral_source.lua b/data/scripts/creaturescripts/quests/forgotten_knowledge/astral_source.lua new file mode 100644 index 00000000000..8b0cb67eb10 --- /dev/null +++ b/data/scripts/creaturescripts/quests/forgotten_knowledge/astral_source.lua @@ -0,0 +1,30 @@ +local astralSource = CreatureEvent("AstralSource") +function astralSource.onThink(creature) + local hp = (creature:getHealth() / creature:getMaxHealth()) * 100 + local health, difference, glyph, pos = 0, 0, Tile(Position(31989, 32823, 15)):getTopCreature(), creature:getPosition() + if hp < 5.5 and Game.getStorageValue(GlobalStorage.ForgottenKnowledge.AstralGlyph) >= 1 then + sourcePos = creature:getPosition() + creature:say('Your damage distorted the source and prevents the Glyph to draw on its power.', TALKTYPE_MONSTER_SAY) + creature:remove() + local source = Tile(Position(31986, 32823, 15)):getTopCreature() + if source then + source:teleportTo(sourcePos) + end + local spectators = Game.getSpectators(Position(31986, 32847, 14), false, false, 12, 12, 12, 12) + for i = 1, #spectators do + local spec = spectators[i] + if spec:getName():lower() == 'a shielded astral glyph' then + health = spec:getHealth() + difference = glyph:getHealth() - health + local pos = spec:getPosition() + spec:teleportTo(Position(31989, 32823, 15)) + glyph:addHealth( - difference) + glyph:teleportTo(pos) + glyph:say('Without the power of the source the Glyph loses its protection!', TALKTYPE_MONSTER_SAY) + end + end + elseif Game.getStorageValue(GlobalStorage.ForgottenKnowledge.AstralGlyph) < 1 then + creature:addHealth(10000, false) + end +end +astralSource:register() diff --git a/data/scripts/creaturescripts/quests/forgotten_knowledge/bosses_kill.lua b/data/scripts/creaturescripts/quests/forgotten_knowledge/bosses_kill.lua new file mode 100644 index 00000000000..58520ad8dc2 --- /dev/null +++ b/data/scripts/creaturescripts/quests/forgotten_knowledge/bosses_kill.lua @@ -0,0 +1,52 @@ +local bosses = { + -- bosses + ["lady tenebris"] = {storage = Storage.ForgottenKnowledge.LadyTenebrisKilled}, + ["the enraged thorn knight"] = {storage = Storage.ForgottenKnowledge.ThornKnightKilled}, + ["lloyd"] = {storage = Storage.ForgottenKnowledge.LloydKilled}, + ["soul of dragonking zyrtarch"] = {storage = Storage.ForgottenKnowledge.DragonkingKilled}, + ["melting frozen horror"] = {storage = Storage.ForgottenKnowledge.HorrorKilled}, + ["the time guardian"] = {storage = Storage.ForgottenKnowledge.TimeGuardianKilled}, + ["the blazing time guardian"] = {storage = Storage.ForgottenKnowledge.TimeGuardianKilled}, + ["the freezing time guardian"] = {storage = Storage.ForgottenKnowledge.TimeGuardianKilled}, + ["the last lore keeper"] = {storage = Storage.ForgottenKnowledge.LastLoreKilled}, + -- IA interactions + ["an astral glyph"] = {} +} + +local bossesForgottenKill = CreatureEvent("BossesForgottenKill") +function bossesForgottenKill.onKill(creature, target) + local targetMonster = target:getMonster() + if not targetMonster or targetMonster:getMaster() then + return true + end + + local bossConfig = bosses[targetMonster:getName():lower()] + if not bossConfig then + return true + end + + for key, value in pairs(targetMonster:getDamageMap()) do + local attackerPlayer = Player(key) + if attackerPlayer then + if bossConfig.storage then + attackerPlayer:setStorageValue(bossConfig.storage, os.time() + 20 * 3600) + elseif targetMonster:getName():lower() == "the enraged thorn knight" then + attackerPlayer:setStorageValue(Storage.ForgottenKnowledge.PlantCounter, 0) + attackerPlayer:setStorageValue(Storage.ForgottenKnowledge.BirdCounter, 0) + elseif targetMonster:getName():lower() == "melting frozen horror" then + local egg = Tile(Position(32269, 31084, 14)):getTopCreature() + if egg then + local pos = egg:getPosition() + egg:remove() + Game.createMonster("baby dragon", pos, true, true) + end + local horror = Tile(Position(32267, 31071, 14)):getTopCreature() + if horror then + horror:remove() + end + end + end + end + return true +end +bossesForgottenKill:register() diff --git a/data/scripts/creaturescripts/quests/forgotten_knowledge/bound_astral_power.lua b/data/scripts/creaturescripts/quests/forgotten_knowledge/bound_astral_power.lua new file mode 100644 index 00000000000..10af98d01c5 --- /dev/null +++ b/data/scripts/creaturescripts/quests/forgotten_knowledge/bound_astral_power.lua @@ -0,0 +1,41 @@ +local positions = { + [1] = {pos = Position(31975, 32856, 15), nextPos = Position(31975, 32839, 15)}, + [2] = {pos = Position(31975, 32839, 15), nextPos = Position(31995, 32839, 15)}, + [3] = {pos = Position(31995, 32839, 15), nextPos = Position(31995, 32856, 15)}, + [4] = {pos = Position(31995, 32856, 15), nextPos = Position(31975, 32856, 15)} +} + +local astralPower = CreatureEvent("AstralPower") +function astralPower.onKill(creature, target) + local player = creature:getPlayer() + if not player then + return true + end + + local targetMonster = target:getMonster() + if not targetMonster or targetMonster:getMaster() then + return true + end + + local bossConfig = targetMonster:getName():lower() == 'bound astral power' + if not bossConfig then + return true + end + Game.setStorageValue(GlobalStorage.ForgottenKnowledge.AstralPowerCounter, + Game.getStorageValue(GlobalStorage.ForgottenKnowledge.AstralPowerCounter) + 1) + if Game.getStorageValue(GlobalStorage.ForgottenKnowledge.AstralPowerCounter) >= 4 then + Game.setStorageValue(GlobalStorage.ForgottenKnowledge.AstralPowerCounter, 1) + end + + local msg = "The destruction of the power source gained you more time until the glyph is powered up!" + for i = 1, #positions do + if creature:getPosition():getDistance(positions[i].pos) < 7 then + target:say(msg, TALKTYPE_MONSTER_SAY, false, nil, positions[i].pos) + Game.createMonster('bound astral power', positions[i].nextPos, true, true) + Game.setStorageValue(GlobalStorage.ForgottenKnowledge.AstralGlyph, 1) + addEvent(Game.setStorageValue, 1 * 60 * 1000, GlobalStorage.ForgottenKnowledge.AstralGlyph, 0) + end + end + return true +end +astralPower:register() diff --git a/data/scripts/creaturescripts/quests/forgotten_knowledge/corrupted_soul.lua b/data/scripts/creaturescripts/quests/forgotten_knowledge/corrupted_soul.lua new file mode 100644 index 00000000000..a510de8a771 --- /dev/null +++ b/data/scripts/creaturescripts/quests/forgotten_knowledge/corrupted_soul.lua @@ -0,0 +1,29 @@ +local function removeVortex(pos) + local vortex = Tile(pos):getItemById(26394) or Tile(pos):getItemById(26395) or Tile(pos):getItemById(26396) + if vortex then + vortex:remove() + end +end + +local corruptedSoul = CreatureEvent("CorruptedSoul") +function corruptedSoul.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + local targetMonster = creature:getMonster() + if not targetMonster then + return true + end + local pos = targetMonster:getPosition() + local vortex = Tile(pos):getItemById(26394) or Tile(pos):getItemById(26395) or Tile(pos):getItemById(26396) + if not vortex then + Game.createItem(26394, 1, pos) + return true + end + if vortex:getId() == 26394 then + vortex:transform(26395) + elseif vortex:getId() == 26395 then + vortex:transform(26396) + end + addEvent(removeVortex, 30 * 1000, pos) + return true +end + +corruptedSoul:register() diff --git a/data/scripts/creaturescripts/quests/forgotten_knowledge/distorted_source.lua b/data/scripts/creaturescripts/quests/forgotten_knowledge/distorted_source.lua new file mode 100644 index 00000000000..b7b1ac19d65 --- /dev/null +++ b/data/scripts/creaturescripts/quests/forgotten_knowledge/distorted_source.lua @@ -0,0 +1,40 @@ +local distortedSource = CreatureEvent("DistortedSource") +function distortedSource.onThink(creature) + local health, difference, glyph, pos = 0, 0, Tile(Position(31989, 32823, 15)):getTopCreature(), creature:getPosition() + if creature:getHealth() <= 40000 then + creature:addHealth(10000, false) + elseif creature:getHealth() >= 55000 or Game.getStorageValue(GlobalStorage.ForgottenKnowledge.AstralGlyph) < 1 then + local spectators = Game.getSpectators(Position(31986, 32847, 14), false, false, 12, 12, 12, 12) + for i = 1, #spectators do + local spec = spectators[i] + if spec:getName():lower() == 'an astral glyph' then + local pos2 = spec:getPosition() + health = spec:getHealth() + difference = glyph:getHealth() - health + spec:teleportTo(Position(31989, 32823, 15)) + glyph:addHealth( - difference) + glyph:teleportTo(pos2) + glyph:say('Drawing upon the power of the source, the Glyph becomes shielded again!', TALKTYPE_MONSTER_SAY) + return true + end + end + end + + if Game.getStorageValue(GlobalStorage.ForgottenKnowledge.AstralGlyph) >= 1 then + local spectators = Game.getSpectators(Position(31986, 32847, 14), false, false, 12, 12, 12, 12) + for i = 1, #spectators do + local spec2 = spectators[i] + if spec2:getName():lower() == 'a shielded astral glyph' then + local pos3 = spec2:getPosition() + health = spec2:getHealth() + difference = glyph:getHealth() - health + spec2:teleportTo(Position(31989, 32823, 15)) + glyph:addHealth( - difference) + glyph:teleportTo(pos3) + glyph:say('Without the power of the source the Glyph loses its protection!', TALKTYPE_MONSTER_SAY) + return true + end + end + end +end +distortedSource:register() diff --git a/data/scripts/creaturescripts/quests/forgotten_knowledge/dragon_egg.lua b/data/scripts/creaturescripts/quests/forgotten_knowledge/dragon_egg.lua new file mode 100644 index 00000000000..89e1d294b96 --- /dev/null +++ b/data/scripts/creaturescripts/quests/forgotten_knowledge/dragon_egg.lua @@ -0,0 +1,69 @@ +local function revertHorror() + local melting = Tile(Position(32267, 31071, 14)):getTopCreature() + local diference, pos, monster = 0, 0, false + local specs, spec = Game.getSpectators(Position(32269, 31091, 14), false, false, 12, 12, 12, 12) + for i = 1, #specs do + spec = specs[i] + if spec:isMonster() and spec:getName():lower() == 'melting frozen horror' then + health = spec:getHealth() + pos = spec:getPosition() + spec:teleportTo(Position(32267, 31071, 14)) + diference = melting:getHealth() - health + melting:addHealth( - diference) + melting:teleportTo(pos) + monster = true + end + end + if not monster then + if melting then + melting:remove() + end + end +end + +local function changeHorror() + local melting = Tile(Position(32267, 31071, 14)):getTopCreature() + local pos = 0 + local specs, spec = Game.getSpectators(Position(32269, 31091, 14), false, false, 12, 12, 12, 12) + for i = 1, #specs do + spec = specs[i] + if spec:isMonster() and spec:getName():lower() == 'solid frozen horror' then + pos = spec:getPosition() + spec:teleportTo(Position(32267, 31071, 14)) + melting:teleportTo(pos) + end + end + addEvent(revertHorror, 20 * 1000) +end + +local dragonEggPrepareDeath = CreatureEvent("DragonEggPrepareDeath") +function dragonEggPrepareDeath.onPrepareDeath(creature, lastHitKiller, mostDamageKiller) + if not creature:getName():lower() == "dragon egg" and creature:isMonster() then + return true + end + creature:addHealth(1, false) + return true +end +dragonEggPrepareDeath:register() + +local dragonEggHealthChange = CreatureEvent("DragonEggHealthChange") +function dragonEggHealthChange.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin) + if creature:getName():lower() == 'dragon egg' then + if primaryType == COMBAT_HEALING then + doTargetCombatHealth(0, creature, COMBAT_ICEDAMAGE, -primaryDamage, -primaryDamage, CONST_ME_MAGIC_GREEN) + return true + end + if primaryType == COMBAT_FIREDAMAGE then + primaryType = COMBAT_HEALING + creature:addHealth(primaryDamage, true) + if creature:getHealth() == creature:getMaxHealth() then + creature:say('The egg sends out a fiery eruption!\n Weakening the frozen horror significantly!', TALKTYPE_MONSTER_SAY) + doTargetCombatHealth(0, creature, COMBAT_ICEDAMAGE, -creature:getMaxHealth()/2, -creature:getMaxHealth()/2, CONST_ME_MAGIC_GREEN) + changeHorror() + end + return true + end + end + return primaryDamage, primaryType, secondaryDamage, secondaryType +end +dragonEggHealthChange:register() diff --git a/data/scripts/creaturescripts/quests/forgotten_knowledge/energy_prism.lua b/data/scripts/creaturescripts/quests/forgotten_knowledge/energy_prism.lua new file mode 100644 index 00000000000..6413a427f02 --- /dev/null +++ b/data/scripts/creaturescripts/quests/forgotten_knowledge/energy_prism.lua @@ -0,0 +1,12 @@ +local energyPrism = CreatureEvent("EnergyPrism") +function energyPrism.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin) + if not Tile(Position(32799, 32826, 14)):getTopCreature() then + if creature:getHealth() < creature:getMaxHealth() then + creature:say('*zap!*', TALKTYPE_MONSTER_SAY) + creature:getPosition():sendMagicEffect(CONST_ME_ENERGYHIT) + creature:addHealth(10000, false) + end + end + return primaryDamage, primaryType, secondaryDamage, secondaryType +end +energyPrism:register() diff --git a/data/scripts/creaturescripts/quests/forgotten_knowledge/energy_prism_death.lua b/data/scripts/creaturescripts/quests/forgotten_knowledge/energy_prism_death.lua new file mode 100644 index 00000000000..83ed8b1e4bc --- /dev/null +++ b/data/scripts/creaturescripts/quests/forgotten_knowledge/energy_prism_death.lua @@ -0,0 +1,26 @@ +local cosmic = {'cosmic energy prism a', 'cosmic energy prism b', 'cosmic energy prism c', 'cosmic energy prism d'} +local energyPrismDeath = CreatureEvent("EnergyPrismDeath") +function energyPrismDeath.onKill(creature, target) + local player = creature:getPlayer() + if not player then + return true + end + + local targetMonster = target:getMonster() + if not targetMonster or targetMonster:getMaster() then + return true + end + + local bossConfig = cosmic[targetMonster:getName():lower()] + if not bossConfig then + return true + end + stopEvent(revertLloyd) + local lloyd = Tile(Position(32799, 32826, 14)):getTopCreature() + if lloyd then + lloyd:teleportTo(Position(32799, 32828, 14)) + lloyd:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end +energyPrismDeath:register() diff --git a/data/scripts/creaturescripts/quests/forgotten_knowledge/healthchange_forgotten.lua b/data/scripts/creaturescripts/quests/forgotten_knowledge/healthchange_forgotten.lua new file mode 100644 index 00000000000..909e4000d83 --- /dev/null +++ b/data/scripts/creaturescripts/quests/forgotten_knowledge/healthchange_forgotten.lua @@ -0,0 +1,25 @@ +local healthForgotten = CreatureEvent("HealthForgotten") +function healthForgotten.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin) + local name = creature:getName():lower() + if name == "lady tenebris" then + local spectators = Game.getSpectators(creature:getPosition(), false, false, 7, 7, 7, 7) + for i = 1, #spectators do + local spectator = spectators[i] + if spectator:getName():lower() == "shadow tentacle" then + return primaryDamage, primaryType, secondaryDamage, secondaryType + end + end + elseif name == "mounted thorn knight" or name == "the shielded thorn knight" or name == "the enraged thorn knight" then + local spectators = Game.getSpectators(creature:getPosition(), false, false, 7, 7, 7, 7) + for i = 1, #spectators do + local spectator = spectators[i] + if spectator:getName():lower() == "possessed tree" then + return primaryDamage, primaryType, secondaryDamage, secondaryType + end + end + end + primaryDamage = primaryDamage + 100 / 100. * primaryDamage + return primaryDamage, primaryType, secondaryDamage, secondaryType +end + +healthForgotten:register() diff --git a/data/scripts/creaturescripts/quests/forgotten_knowledge/lloyd_preparedeath.lua b/data/scripts/creaturescripts/quests/forgotten_knowledge/lloyd_preparedeath.lua new file mode 100644 index 00000000000..0916c238a06 --- /dev/null +++ b/data/scripts/creaturescripts/quests/forgotten_knowledge/lloyd_preparedeath.lua @@ -0,0 +1,48 @@ +local monsters = { + {cosmic = 'cosmic energy prism a', pos = Position(32801, 32827, 14)}, + {cosmic = 'cosmic energy prism b', pos = Position(32798, 32827, 14)}, + {cosmic = 'cosmic energy prism c', pos = Position(32803, 32826, 14)}, + {cosmic = 'cosmic energy prism d', pos = Position(32796, 32826, 14)} +} + +local function revertLloyd(creature, cosmic) + local monster = Creature(creature) + if monster and monster:getHealth() >= 1 and monster:getPosition() == Position(32799, 32826, 14) then + monster:say('The cosmic energies in the chamber refocus on Lloyd.', TALKTYPE_MONSTER_SAY) + monster:teleportTo(Position(32799, 32828, 14)) + monster:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + + for i = 1, #monsters do + local cosmics = monsters[i] + local cosmic = Tile(Position(cosmics.pos)):getTopCreature() + if cosmic and cosmic:isMonster() and cosmic:getName():lower() == cosmics.cosmic and cosmic:getHealth() >= 1 then + cosmic:setMaxHealth(100000) + cosmic:addHealth(100000) + return true + end + end +end + +local lloydPrepareDeath = CreatureEvent("LloydPrepareDeath") +function lloydPrepareDeath.onPrepareDeath(creature, lastHitKiller, mostDamageKiller) + if not creature:getName():lower() == "lloyd" and creature:isMonster() then + return true + end + + for i = 1, #monsters do + local cosmics = monsters[i] + local cosmic = Tile(Position(cosmics.pos)):getTopCreature() + if cosmic and cosmic:isMonster() and cosmic:getName():lower() == cosmics.cosmic then + creature:teleportTo(Position(32799, 32826, 14)) + creature:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + creature:addHealth(300000, true) + cosmic:setMaxHealth(1000) + creature:say('The cosmic energies in the chamber refocus on Lloyd.', TALKTYPE_MONSTER_SAY) + addEvent(revertLloyd, 10 * 1000, creature:getId(), cosmic:getId()) + return true + end + end + return true +end +lloydPrepareDeath:register() diff --git a/data/scripts/creaturescripts/quests/forgotten_knowledge/possessed_tree.lua b/data/scripts/creaturescripts/quests/forgotten_knowledge/possessed_tree.lua new file mode 100644 index 00000000000..0f52ccb5f40 --- /dev/null +++ b/data/scripts/creaturescripts/quests/forgotten_knowledge/possessed_tree.lua @@ -0,0 +1,16 @@ +local monsters = {"unbound blightwalker", "unbound demon", "unbound demon outcast", "unbound defiler"} +local possessedTree = CreatureEvent("PossessedTree") +function possessedTree.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + local targetMonster = creature:getMonster() + if not targetMonster then + return true + end + targetMonster:getPosition():sendMagicEffect(CONST_ME_SMALLPLANTS) + local monster = Game.createMonster(monsters[math.random(#monsters)], targetMonster:getPosition(), true, true) + if monster then + monster:say("The destruction of the tree unleashes the " ..monster:getName():lower().."!", TALKTYPE_MONSTER_SAY) + end + addEvent(Game.createMonster, 60 * 1000, "possessed tree", targetMonster:getPosition(), true, true) + return true +end +possessedTree:register() diff --git a/data/scripts/creaturescripts/quests/forgotten_knowledge/replica_servants.lua b/data/scripts/creaturescripts/quests/forgotten_knowledge/replica_servants.lua new file mode 100644 index 00000000000..42cb299c8e1 --- /dev/null +++ b/data/scripts/creaturescripts/quests/forgotten_knowledge/replica_servants.lua @@ -0,0 +1,45 @@ +local servants = { + ['golden servant replica'] = { + storage = GlobalStorage.ForgottenKnowledge.GoldenServant, + playerStorage = Storage.ForgottenKnowledge.GoldenServantCounter + }, + ['diamond servant replica'] = { + storage = GlobalStorage.ForgottenKnowledge.DiamondServant, + playerStorage = Storage.ForgottenKnowledge.DiamondServantCounter + } +} +local replicaServant = CreatureEvent("ReplicaServant") +function replicaServant.onKill(creature, target) + local player = creature:getPlayer() + if not player then + return true + end + + local targetMonster = target:getMonster() + if not targetMonster or targetMonster:getMaster() then + return true + end + + local bossConfig = servants[targetMonster:getName():lower()] + if not bossConfig then + return true + end + if bossConfig.storage < 0 then + Game.setStorageValue(bossConfig.storage, 0) + end + Game.setStorageValue(bossConfig.storage, Game.getStorageValue(bossConfig.storage) + 1) + if Game.getStorageValue(GlobalStorage.ForgottenKnowledge.GoldenServant) >= 5 and Game.getStorageValue(GlobalStorage.ForgottenKnowledge.DiamondServant) >= 5 then + if not Tile(Position(32815, 32870, 13)):getItemById(11796) then + local teleport = Game.createItem(11796, 1, Position(32815, 32870, 13)) + if teleport then + teleport:setActionId(26665) + end + end + end + if player:getStorageValue(bossConfig.playerStorage) < 0 then + player:setStorageValue(bossConfig.playerStorage, 0) + end + player:setStorageValue(bossConfig.playerStorage, player:getStorageValue(bossConfig.playerStorage) + 1) + return true +end +replicaServant:register() diff --git a/data/scripts/creaturescripts/quests/forgotten_knowledge/thorn_knight_death.lua b/data/scripts/creaturescripts/quests/forgotten_knowledge/thorn_knight_death.lua new file mode 100644 index 00000000000..1e230911295 --- /dev/null +++ b/data/scripts/creaturescripts/quests/forgotten_knowledge/thorn_knight_death.lua @@ -0,0 +1,30 @@ +local function checkBlood(position) + local tile = Tile(position) + local items = tile:getItems() + for i = 1, #items do + local item = items[i] + if not ItemType(item):isMovable() then + item:remove() + end + end +end +local thornKnightDeath = CreatureEvent("ThornKnightDeath") +function thornKnightDeath.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + local targetMonster = creature:getMonster() + if not targetMonster then + return true + end + if targetMonster:getName():lower() == 'mounted thorn knight' then + targetMonster:say('The thorn knight unmounts!', TALKTYPE_MONSTER_SAY) + Game.createMonster('the shielded thorn knight', targetMonster:getPosition(), true, true) + Game.createMonster('thorn steed', targetMonster:getPosition(), false, true) + addEvent(checkBlood, 1, targetMonster:getPosition()) + return true + elseif targetMonster:getName():lower() == 'the shielded thorn knight' then + Game.createMonster('the enraged thorn knight', targetMonster:getPosition(), true, true) + addEvent(checkBlood, 1, targetMonster:getPosition()) + return true + end + return true +end +thornKnightDeath:register() diff --git a/data/scripts/creaturescripts/quests/forgotten_knowledge/time_guardian_health.lua b/data/scripts/creaturescripts/quests/forgotten_knowledge/time_guardian_health.lua new file mode 100644 index 00000000000..23e83fea1d4 --- /dev/null +++ b/data/scripts/creaturescripts/quests/forgotten_knowledge/time_guardian_health.lua @@ -0,0 +1,9 @@ +local timeGuardianHealth = CreatureEvent("TimeGuardianHealth") +function timeGuardianHealth.onPrepareDeath(creature, lastHitKiller, mostDamageKiller) + if not creature:getName():lower() == "the freezing time guardian" or creature:getName():lower() == "the blazing time guardian" and creature:isMonster() then + return true + end + creature:addHealth(1, false) + return true +end +timeGuardianHealth:register() diff --git a/data/scripts/creaturescripts/quests/grave_danger/cobra_bastion/scarlett.lua b/data/scripts/creaturescripts/quests/grave_danger/cobra_bastion/scarlett.lua new file mode 100644 index 00000000000..4ed2ea0716e --- /dev/null +++ b/data/scripts/creaturescripts/quests/grave_danger/cobra_bastion/scarlett.lua @@ -0,0 +1,116 @@ +local storage = Storage.GraveDanger.CobraBastion.Questline +local rooms = { + [1] = {fromPos = Position(33390, 32642, 6), toPos = Position(33394, 32646, 6)}, + [2] = {fromPos = Position(33390, 32646, 6), toPos = Position(33394, 32650, 6)}, + [3] = {fromPos = Position(33390, 32650, 6), toPos = Position(33394, 32654, 6)}, + [4] = {fromPos = Position(33394, 32642, 6), toPos = Position(33398, 32646, 6)}, + [5] = {fromPos = Position(33394, 32646, 6), toPos = Position(33398, 32650, 6)}, + [6] = {fromPos = Position(33394, 32650, 6), toPos = Position(33398, 32654, 6)}, + [5] = {fromPos = Position(33398, 32642, 6), toPos = Position(33402, 32646, 6)}, + [6] = {fromPos = Position(33398, 32646, 6), toPos = Position(33402, 32650, 6)}, + [7] = {fromPos = Position(33398, 32650, 6), toPos = Position(33402, 32654, 6)} +} + +local function isMirrorsCorrect(fromPosition, toPosition) + local Pillar1 = Tile(fromPosition):getItemById(36309) + local Pillar2 = Tile(Position(fromPosition.x + 4, fromPosition.y, fromPosition.z)):getItemById(36310) + local Pillar3 = Tile(Position(toPosition.x - 4, toPosition.y, toPosition.z)):getItemById(36312) + local Pillar4 = Tile(toPosition):getItemById(36311) + + if Pillar1 and Pillar2 and Pillar3 and Pillar4 then + return true + end + + return false +end + +local eventDoDamage = function(creatureid, attackerid, type) + local creature = Creature(creatureid) + if not creature then + return + end + + local damage = creature:getMaxHealth()/4 + creature:say('AHHHHHHHHHHH!', TALKTYPE_MONSTER_SAY) + doTargetCombatHealth(attackerid, creature, type, -damage, -damage, CONST_ME_POFF, ORIGIN_NONE) + creature:setMoveLocked(false) +end + +local eventRemoveFreeze = function(creatureid, evented) + local creature = Creature(creatureid) + if not creature then + return + end + + if creature:isMoveLocked() then + creature:setMoveLocked(false) + if evented then + SCARLETT_MAY_DIE = 0 + end + end +end + +local function changeScarlett(creatureid) + local creature = Creature(creatureid) + if not creature then + return + end + + creature:say('Galthen... is that you?', TALKTYPE_MONSTER_SAY) + SCARLETT_MAY_DIE = 1 + SCARLETT_MAY_TRANSFORM = 0 + creature:setMoveLocked(true) + addEvent(eventRemoveFreeze, 4*1000, creature:getId(), true) +end + +local scarlettThink = CreatureEvent("scarlettThink") +function scarlettThink.onThink(creature) + if not creature:isMonster() then + return true + end + + if SCARLETT_MAY_TRANSFORM ~= 1 then + return true + end + + local mirrorsCount = 0 + for _, p in pairs(rooms) do + if creature:getPosition():isInRange(p.fromPos, p.toPos) then + if isMirrorsCorrect(p.fromPos, p.toPos) then + addEvent(changeScarlett, 0.5*1000, creature:getId()) + return true + end + end + end + return true +end + +scarlettThink:register() + +local scarlettHealth = CreatureEvent("scarlettHealth") +function scarlettHealth.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin) + if not creature:isMonster() then + return primaryDamage, primaryType, secondaryDamage, secondaryType + end + + if creature:getStorageValue(storage) ~= 1 then + return primaryDamage, primaryType, secondaryDamage, secondaryType + end + + if not creature:isMoveLocked() then + return primaryDamage*0.01, primaryType, secondaryDamage*0.01, secondaryType + end + + local spec = Game.getSpectators(creature:getPosition(), false, false, 4, 4, 4, 4) + for _, c in pairs(spec) do + if c and (c:isPlayer() or c:getMaster()) then + doTargetCombatHealth(creature:getId(), c, COMBAT_EARTHDAMAGE, -7500, -7500, CONST_ME_GROUNDSHAKER) + end + end + + addEvent(eventDoDamage, 200, creature:getId(), attacker:getId(), primaryType) + SCARLETT_MAY_DIE = 0 + return primaryDamage, primaryType, secondaryDamage, secondaryType +end + +scarlettHealth:register() diff --git a/data/scripts/creaturescripts/quests/grimvale/feroxa_transform.lua b/data/scripts/creaturescripts/quests/grimvale/feroxa_transform.lua new file mode 100644 index 00000000000..3cf7101763d --- /dev/null +++ b/data/scripts/creaturescripts/quests/grimvale/feroxa_transform.lua @@ -0,0 +1,37 @@ +local feroxaTransform = CreatureEvent("FeroxaTransform") +function feroxaTransform.onThink(creature) + if creature:getName():lower() ~= 'feroxa' then + return true + end + if creature:getMaxHealth() == 100000 then + if creature:getHealth() <= 50000 then + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + Game.createMonster('feroxa2', creature:getPosition(), true, true) + creature:remove() + end + end + if creature:getMaxHealth() == 50000 then + if creature:getHealth() <= 25000 then + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + local feroxas = { + [1] = {name = 'feroxa3'}, + [2] = {name = 'feroxa4'} + } + Game.createMonster(feroxas[math.random(#feroxas)].name, creature:getPosition(), true, true) + creature:remove() + end + end +end + +feroxaTransform:register() + +local feroxaDeath = CreatureEvent("FeroxaDeath") +function feroxaDeath.onDeath(creature, corpse, deathList) + local pool = Tile(creature:getPosition()):getItemById(2016) + if pool then + pool:remove() + end + Game.createMonster("Feroxa5", creature:getPosition(), true, true) +end + +feroxaDeath:register() diff --git a/data/scripts/creaturescripts/quests/heart_of_destruction/aftershock_transform.lua b/data/scripts/creaturescripts/quests/heart_of_destruction/aftershock_transform.lua new file mode 100644 index 00000000000..ac749fe3087 --- /dev/null +++ b/data/scripts/creaturescripts/quests/heart_of_destruction/aftershock_transform.lua @@ -0,0 +1,40 @@ +local aftershockTransform = CreatureEvent("AftershockTransform") +function aftershockTransform.onThink(creature) + if not creature:isMonster() then + return true + end + + local sparkOfDestructionPositions = { + {x = 32203, y = 31246, z = 14}, + {x = 32205, y = 31251, z = 14}, + {x = 32210, y = 31251, z = 14}, + {x = 32212, y = 31246, z = 14} + } + + local monsterTable = { + [80] = {fromStage = 0, toStage = 1}, + [60] = {fromStage = 1, toStage = 2}, + [40] = {fromStage = 2, toStage = 3}, + [25] = {fromStage = 3, toStage = 4}, + [10] = {fromStage = 4, toStage = 5} + } + + for index, value in pairs(monsterTable) do + local hp = (creature:getHealth() / creature:getMaxHealth()) * 100 + if realityQuakeStage == 0 then + local aftershockHealth = creature:getHealth() + if hp <= index and aftershockStage == value.fromStage then + creature:remove() + for i = 1, #sparkOfDestructionPositions do + Game.createMonster("spark of destruction", #sparkOfDestructionPositions[i], false, true) + end + local monster = Game.createMonster("foreshock", {x = 32208, y = 31248, z = 14}, false, true) + monster:addHealth(-monster:getHealth() + aftershockHealth, COMBAT_PHYSICALDAMAGE) + aftershockStage = value.toStage + end + end + end + return true +end + +aftershockTransform:register() diff --git a/data/scripts/creaturescripts/quests/heart_of_destruction/anomaly_transform.lua b/data/scripts/creaturescripts/quests/heart_of_destruction/anomaly_transform.lua new file mode 100644 index 00000000000..d3a1f22eff0 --- /dev/null +++ b/data/scripts/creaturescripts/quests/heart_of_destruction/anomaly_transform.lua @@ -0,0 +1,44 @@ +local anomalyTransform = CreatureEvent("AnomalyTransform") +function anomalyTransform.onThink(creature) + if not creature or not creature:isMonster() then + return false + end + + local hp = (creature:getHealth() / creature:getMaxHealth()) * 100 + if hp <= 75 and Game.getStorageValue(14322) == 0 then + creature:remove() + Game.createMonster("spark of destruction", {x = 32267, y = 31253, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32274, y = 31255, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32274, y = 31249, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32267, y = 31249, z = 14}, false, true) + Game.createMonster("charged anomaly", {x = 32271, y = 31249, z = 14}, false, true) + Game.setStorageValue(14322, 1) + elseif hp <= 50 and Game.getStorageValue(14322) == 1 then + creature:remove() + Game.createMonster("spark of destruction", {x = 32267, y = 31253, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32274, y = 31255, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32274, y = 31249, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32267, y = 31249, z = 14}, false, true) + Game.createMonster("charged anomaly", {x = 32271, y = 31249, z = 14}, false, true) + Game.setStorageValue(14322, 2) + elseif hp <= 25 and Game.getStorageValue(14322) == 2 then + creature:remove() + Game.createMonster("spark of destruction", {x = 32267, y = 31253, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32274, y = 31255, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32274, y = 31249, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32267, y = 31249, z = 14}, false, true) + Game.createMonster("charged anomaly", {x = 32271, y = 31249, z = 14}, false, true) + Game.setStorageValue(14322, 3) + elseif hp <= 5 and Game.getStorageValue(14322) == 3 then + creature:remove() + Game.createMonster("spark of destruction", {x = 32267, y = 31253, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32274, y = 31255, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32274, y = 31249, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32267, y = 31249, z = 14}, false, true) + Game.createMonster("charged anomaly", {x = 32271, y = 31249, z = 14}, false, true) + Game.setStorageValue(14322, 4) + end + return true +end + +anomalyTransform:register() diff --git a/data/scripts/creaturescripts/quests/heart_of_destruction/charged_anomaly_death.lua b/data/scripts/creaturescripts/quests/heart_of_destruction/charged_anomaly_death.lua new file mode 100644 index 00000000000..82f69e311a6 --- /dev/null +++ b/data/scripts/creaturescripts/quests/heart_of_destruction/charged_anomaly_death.lua @@ -0,0 +1,20 @@ +local monsterTable = { + [1] = 72500, + [2] = 145000, + [3] = 217500, + [4] = 275500 +} + +local chargedAnomalyDeath = CreatureEvent("ChargedAnomalyDeath") + +function chargedAnomalyDeath.onDeath(creature) + for storageValue, health in pairs(monsterTable) do + if Game.getStorageValue(14322) == storageValue then + local monster = Game.createMonster("anomaly", {x = 32271, y = 31249, z = 14}, false, true) + monster:addHealth(-health) + end + end + return true +end + +chargedAnomalyDeath:register() diff --git a/data/scripts/creaturescripts/quests/heart_of_destruction/charged_disruption_transform.lua b/data/scripts/creaturescripts/quests/heart_of_destruction/charged_disruption_transform.lua new file mode 100644 index 00000000000..3ee0c14d344 --- /dev/null +++ b/data/scripts/creaturescripts/quests/heart_of_destruction/charged_disruption_transform.lua @@ -0,0 +1,30 @@ +local explodeExhaust = 18 --in seconds +local minionExhaust = {} + +local function minionExplode(creature) + if not creature:isMonster() then + return true + end + + local cid = creature:getId() + local exhaust = minionExhaust[cid] + + if not exhaust then + minionExhaust[cid] = 1 + return + end + + if exhaust >= explodeExhaust then + Game.createMonster("overcharged disruption", creature:getPosition(), false, true) + creature:remove() + else + minionExhaust[cid] = exhaust + 1 + end +end + +local chargedDisruptionTransform = CreatureEvent("ChargedDisruptionTransform") +function chargedDisruptionTransform.onThink(creature) + minionExplode(creature) +end + +chargedDisruptionTransform:register() diff --git a/data/scripts/creaturescripts/quests/heart_of_destruction/charger_spawn.lua b/data/scripts/creaturescripts/quests/heart_of_destruction/charger_spawn.lua new file mode 100644 index 00000000000..6718aad3712 --- /dev/null +++ b/data/scripts/creaturescripts/quests/heart_of_destruction/charger_spawn.lua @@ -0,0 +1,28 @@ +local function chargerSpawn(pos) + Game.createMonster("charger", pos, false, true) + spawningCharge = false + return true +end + +local chargerSpawn = CreatureEvent("ChargerSpawn") +function chargerSpawn.onDeath(creature) + local positions = { + {x = 32151, y = 31356, z = 14}, + {x = 32154, y = 31353, z = 14}, + {x = 32153, y = 31361, z = 14}, + {x = 32158, y = 31362, z = 14}, + {x = 32161, y = 31360, z = 14}, + {x = 32156, y = 31357, z = 14}, + {x = 32159, y = 31354, z = 14}, + {x = 32163, y = 31356, z = 14}, + {x = 32162, y = 31352, z = 14}, + {x = 32158, y = 31350, z = 14}, + } + + local pos = positions[math.random(1, #positions)] + addEvent(chargerSpawn, 6000, pos) + spawningCharge = true + return true +end + +chargerSpawn:register() diff --git a/data/scripts/creaturescripts/quests/heart_of_destruction/charging_out_death.lua b/data/scripts/creaturescripts/quests/heart_of_destruction/charging_out_death.lua new file mode 100644 index 00000000000..3484a8ce99b --- /dev/null +++ b/data/scripts/creaturescripts/quests/heart_of_destruction/charging_out_death.lua @@ -0,0 +1,9 @@ +local chargingOutDeath = CreatureEvent("ChargingOutDeath") +function chargingOutDeath.onDeath(creature) + if chargingOutKilled == false then + local monster = Game.createMonster("outburst", {x = 32234, y = 31285, z = 14}, false, true) + monster:addHealth(-monster:getHealth() + outburstHealth, COMBAT_PHYSICALDAMAGE) + end + return true +end +chargingOutDeath:register() diff --git a/data/scripts/creaturescripts/quests/heart_of_destruction/crackler_transform.lua b/data/scripts/creaturescripts/quests/heart_of_destruction/crackler_transform.lua new file mode 100644 index 00000000000..67e8f222ec6 --- /dev/null +++ b/data/scripts/creaturescripts/quests/heart_of_destruction/crackler_transform.lua @@ -0,0 +1,16 @@ +local cracklerTransform = CreatureEvent("CracklerTransform") +function cracklerTransform.onThink(creature) + if not creature or not creature:isMonster() then + return true + end + + if cracklerTransform == true then + local monster = Game.createMonster("depolarized crackler", creature:getPosition(), false, true) + monster:addHealth(-monster:getHealth() + creature:getHealth(), COMBAT_PHYSICALDAMAGE) + creature:remove() + end + + return true +end + +cracklerTransform:register() diff --git a/data/scripts/creaturescripts/quests/heart_of_destruction/depolarized_death.lua b/data/scripts/creaturescripts/quests/heart_of_destruction/depolarized_death.lua new file mode 100644 index 00000000000..93b9199c204 --- /dev/null +++ b/data/scripts/creaturescripts/quests/heart_of_destruction/depolarized_death.lua @@ -0,0 +1,38 @@ +local function setStorage() + local upConer = {x = 32192, y = 31311, z = 14} -- upLeftCorner + local downConer = {x = 32225, y = 31343, z = 14} -- downRightCorner + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k= upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + if c:getStorageValue(14322) < 1 then + c:setStorageValue(14322, 1) -- Access to boss Anomaly + end + end + end + end + end + end + end + end +end + +local depolarizedDeath = CreatureEvent("DepolarizedDeath") +function depolarizedDeath.onDeath(creature) + + Game.setStorageValue(14323, Game.getStorageValue(14323) + 1) + if Game.getStorageValue(14323) == 10 then + setStorage() + creature:say("You have reached enough charges to pass further into the destruction!", TALKTYPE_MONSTER_YELL, isInGhostMode, pid, {x = 32209, y = 31326, z = 14}) + Game.setStorageValue(14323, -1) + end + return true +end + +depolarizedDeath:register() diff --git a/data/scripts/creaturescripts/quests/heart_of_destruction/depolarized_transform.lua b/data/scripts/creaturescripts/quests/heart_of_destruction/depolarized_transform.lua new file mode 100644 index 00000000000..818ac791203 --- /dev/null +++ b/data/scripts/creaturescripts/quests/heart_of_destruction/depolarized_transform.lua @@ -0,0 +1,15 @@ +local depolarizedTransform = CreatureEvent("DepolarizedTransform") +function depolarizedTransform.onThink(creature) + if not creature or not creature:isMonster() then + return false + end + + if cracklerTransform == false then + local monster = Game.createMonster("Crackler", creature:getPosition(), false, true) + monster:addHealth(-monster:getHealth() + creature:getHealth(), COMBAT_PHYSICALDAMAGE) + creature:remove() + end + return true +end + +depolarizedTransform:register() diff --git a/data/scripts/creaturescripts/quests/heart_of_destruction/devourer_player_death.lua b/data/scripts/creaturescripts/quests/heart_of_destruction/devourer_player_death.lua new file mode 100644 index 00000000000..543a6ac616e --- /dev/null +++ b/data/scripts/creaturescripts/quests/heart_of_destruction/devourer_player_death.lua @@ -0,0 +1,9 @@ +local devourerStorage = CreatureEvent("DevourerStorage") +function devourerStorage.onDeath(player) + player:setStorageValue(14334, -1) + player:setStorageValue(14335, -1) + player:setStorageValue(14336, -1) + player:unregisterEvent("DevourerStorage") + return true +end +devourerStorage:register() diff --git a/data/scripts/creaturescripts/quests/heart_of_destruction/disruption_transform.lua b/data/scripts/creaturescripts/quests/heart_of_destruction/disruption_transform.lua new file mode 100644 index 00000000000..d3918b98ccb --- /dev/null +++ b/data/scripts/creaturescripts/quests/heart_of_destruction/disruption_transform.lua @@ -0,0 +1,30 @@ +local explodeExhaust = 12 --in seconds +local minionExhaust = {} + +local function minionExplode(monster) + if not monster:isMonster() then + return false + end + + local cid = monster:getId() + local exhaust = minionExhaust[cid] + if not exhaust then + minionExhaust[cid] = 1 + return + end + + if exhaust >= explodeExhaust then + local monsterPos = monster:getPosition() + Game.createMonster("Charged Disruption", monsterPos, false, true) + monster:remove() + else + minionExhaust[cid] = exhaust + 1 + end +end + +local disruptionTransform = CreatureEvent("DisruptionTransform") +function disruptionTransform.onThink(monster) + minionExplode(monster) +end + +disruptionTransform:register() diff --git a/data/scripts/creaturescripts/quests/heart_of_destruction/eradicator_transform.lua b/data/scripts/creaturescripts/quests/heart_of_destruction/eradicator_transform.lua new file mode 100644 index 00000000000..2b24881715d --- /dev/null +++ b/data/scripts/creaturescripts/quests/heart_of_destruction/eradicator_transform.lua @@ -0,0 +1,38 @@ +local eradicatorTransform = CreatureEvent("EradicatorTransform") +function eradicatorTransform.onThink(creature) + if not creature or not creature:isMonster() then + return false + end + + if eradicatorReleaseT == true then + if eradicatorWeak == 0 then + local pos = creature:getPosition() + local health = creature:getHealth() + creature:remove() + + local monster = Game.createMonster("eradicator2", pos, false, true) + monster:addHealth(-monster:getHealth() + health, COMBAT_PHYSICALDAMAGE) + Game.createMonster("spark of destruction", {x = 32304, y = 31282, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32305, y = 31287, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32312, y = 31287, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32314, y = 31282, z = 14}, false, true) + eradicatorWeak = 1 -- Eradicator form + eradicatorReleaseT = false -- Release spell + areaEradicator2 = addEvent(function() eradicatorReleaseT = true end, 9000) + elseif eradicatorWeak == 1 then + local pos = creature:getPosition() + local health = creature:getHealth() + + creature:remove() + + local monster = Game.createMonster("eradicator", pos, false, true) + monster:addHealth(-monster:getHealth() + health, COMBAT_PHYSICALDAMAGE) + eradicatorWeak = 0 + eradicatorReleaseT = false -- Release spell + areaEradicator2 = addEvent(function() eradicatorReleaseT = true end, 74000) + end + end + return true +end + +eradicatorTransform:register() diff --git a/data/scripts/creaturescripts/quests/heart_of_destruction/foreshock_transform.lua b/data/scripts/creaturescripts/quests/heart_of_destruction/foreshock_transform.lua new file mode 100644 index 00000000000..4f10776d44b --- /dev/null +++ b/data/scripts/creaturescripts/quests/heart_of_destruction/foreshock_transform.lua @@ -0,0 +1,40 @@ +local foreshockTransform = CreatureEvent("ForeshockTransform") +function foreshockTransform.onThink(creature) + if not creature:isMonster() then + return true + end + + local sparkOfDestructionPositions = { + {x = 32203, y = 31246, z = 14}, + {x = 32205, y = 31251, z = 14}, + {x = 32210, y = 31251, z = 14}, + {x = 32212, y = 31246, z = 14} + } + + local monsterTable = { + [80] = {fromStage = 0, toStage = 1}, + [60] = {fromStage = 1, toStage = 2}, + [40] = {fromStage = 2, toStage = 3}, + [25] = {fromStage = 3, toStage = 4}, + [10] = {fromStage = 4, toStage = 5} + } + + for index, value in pairs(monsterTable) do + local hp = (creature:getHealth() / creature:getMaxHealth()) * 100 + if realityQuakeStage == 0 then + local foreshockHealth = creature:getHealth() + if hp <= index and aftershockStage == value.fromStage then + creature:remove() + for i = 1, #sparkOfDestructionPositions do + Game.createMonster("spark of destruction", #sparkOfDestructionPositions[i], false, true) + end + local monster = Game.createMonster("aftershock", {x = 32208, y = 31248, z = 14}, false, true) + monster:addHealth(-monster:getHealth() + foreshockHealth, COMBAT_PHYSICALDAMAGE) + foreshockStage = value.toStage + end + end + end + return true +end + +foreshockTransform:register() diff --git a/data/scripts/creaturescripts/quests/heart_of_destruction/heart_boss_death.lua b/data/scripts/creaturescripts/quests/heart_of_destruction/heart_boss_death.lua new file mode 100644 index 00000000000..9c8cfb72750 --- /dev/null +++ b/data/scripts/creaturescripts/quests/heart_of_destruction/heart_boss_death.lua @@ -0,0 +1,137 @@ +function clearDevourer() + local upConer = {x = 32260, y = 31336, z = 14} -- upLeftCorner + local downConer = {x = 32283, y = 31360, z = 14} -- downRightCorner + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k = upConer.z, downConer.z do + local tile = Tile(i, j, k) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, creature in pairs(creatures) do + if creature:isMonster() then -- éMonstro + creature:remove() + end + end + end + end + end + end + end + stopEvent(areaDevourer4) + stopEvent(areaDevourer5) + stopEvent(areaDevourer6) +end + +local function setStorageDevourer() + local upConer = {x = 32260, y = 31336, z = 14} -- upLeftCorner + local downConer = {x = 32283, y = 31360, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k= upConer.z, downConer.z do + local tile = Tile(i, j, k) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, creature in pairs(creatures) do + if creature:isPlayer() then -- éPlayer + creature:setStorageValue(60835, 1) + creature:setStorageValue(60814, 1) + creature:setStorageValue(60828, 1) + end + end + end + end + end + end + end +end + +local function setStorage(fromPos, toPos, storage) + local upConer = fromPos -- upLeftCorner + local downConer = toPos -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k= upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, creature in pairs(creatures) do + if creature:isPlayer() and creature:getStorageValue(storage) < 1 then + creature:setStorageValue(storage, 1) -- Access to boss Anomaly + end + end + end + end + end + end + end +end + +local heartBossDeath = CreatureEvent("HeartBossDeath") +function heartBossDeath.onDeath(creature) + + local bosses = { + ["anomaly"] = { + tile = {x = 32261, y = 31250, z = 14}, + actionId = 14325, + fromPos = {x = 32258, y = 31237, z = 14}, + toPos = {x = 32284, y = 31262, z = 14}, + storage = 14326 + }, + ["rupture"] = { + tile = {x = 32326, y = 31250, z = 14}, + actionId = 14325, + fromPos = {x = 32324, y = 31239, z = 14}, + toPos = {x = 32347, y = 31263, z = 14}, + storage = 14327 + }, + ["realityquake"] = { + tile = {x = 32199, y = 31248, z = 14}, + actionId = 14325, + fromPos = {x = 32197, y = 31236, z = 14}, + toPos = {x = 32220, y = 31260, z = 14}, + storage = 14328 + }, + ["eradicator"] = { + tile = {x = 32318, y = 31284, z = 14}, + actionId = 14325, + fromPos = {x = 32297, y = 31272, z = 14}, + toPos = {x = 32321, y = 31296, z = 14}, + storage = 14330 + }, + ["outburst"] = { + tile = {x = 32225, y = 31285, z = 14}, + actionId = 14325, + fromPos = {x = 32223, y = 31273, z = 14}, + toPos = {x = 32246, y = 31297, z = 14}, + storage = 14332 + }, + } + + local monsterName = creature:getName():lower() + local bossName = bosses[monsterName] + if bossName then + local vortex = Tile(bossName.tile):getItemById(26139) + if vortex then + vortex:transform(26138) + vortex:setActionId(bossName.actionId) + end + setStorage(bossName.fromPos, bossName.toPos, bossName.storage) + elseif monsterName == "world devourer" then + local vortex = Tile({x = 32281, y = 31348, z = 14}):getItemById(26139) + if vortex then + vortex:transform(26138) + vortex:setActionId(14354) + end + setStorageDevourer() + clearDevourer() + end + return true +end + +heartBossDeath:register() diff --git a/data/scripts/creaturescripts/quests/heart_of_destruction/heart_minion_death.lua b/data/scripts/creaturescripts/quests/heart_of_destruction/heart_minion_death.lua new file mode 100644 index 00000000000..6a8782fd431 --- /dev/null +++ b/data/scripts/creaturescripts/quests/heart_of_destruction/heart_minion_death.lua @@ -0,0 +1,28 @@ +local heartMinionDeath = CreatureEvent("HeartMinionDeath") +function heartMinionDeath.onDeath(creature) + if not creature or not creature:isMonster() then -- éMonstro! + return true + end + local monster = creature:getName():lower() + if monster == "frenzy" then + rageSummon = rageSummon - 1 + devourerSummon = devourerSummon - 1 + elseif monster == "damage resonance" then + resonanceActive = false + elseif monster == "disruption" or monster == "charged disruption" or monster == "overcharged disruption" then + destructionSummon = destructionSummon - 1 + devourerSummon = devourerSummon - 1 + elseif monster == "the hunger" then + devourerBossesKilled = devourerBossesKilled + 1 + theHungerKilled = true + elseif monster == "the destruction" then + devourerBossesKilled = devourerBossesKilled + 1 + theDestructionKilled = true + elseif monster == "the rage" then + devourerBossesKilled = devourerBossesKilled + 1 + theRageKilled = true + end + return true +end + +heartMinionDeath:register() diff --git a/data/scripts/creaturescripts/quests/heart_of_destruction/outburst_charge.lua b/data/scripts/creaturescripts/quests/heart_of_destruction/outburst_charge.lua new file mode 100644 index 00000000000..36fcd8f6d72 --- /dev/null +++ b/data/scripts/creaturescripts/quests/heart_of_destruction/outburst_charge.lua @@ -0,0 +1,52 @@ +local outburstCharge = CreatureEvent("OutburstCharge") +function outburstCharge.onThink(creature) + if not creature or not creature:isMonster() then + return false + end + + local hp = (creature:getHealth() / creature:getMaxHealth()) * 100 + if hp <= 80 and outburstStage == 0 then + outburstHealth = creature:getHealth() + creature:remove() + Game.createMonster("spark of destruction", {x = 32229, y = 31282, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32230, y = 31287, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32237, y = 31287, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32238, y = 31282, z = 14}, false, true) + Game.createMonster("charging outburst", {x = 32234, y = 31284, z = 14}, false, true) + outburstStage = 1 + chargingOutKilled = false + elseif hp <= 60 and outburstStage == 1 then + outburstHealth = creature:getHealth() + creature:remove() + Game.createMonster("spark of destruction", {x = 32229, y = 31282, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32230, y = 31287, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32237, y = 31287, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32238, y = 31282, z = 14}, false, true) + Game.createMonster("charging outburst", {x = 32234, y = 31284, z = 14}, false, true) + outburstStage = 2 + chargingOutKilled = false + elseif hp <= 40 and outburstStage == 2 then + outburstHealth = creature:getHealth() + creature:remove() + Game.createMonster("spark of destruction", {x = 32229, y = 31282, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32230, y = 31287, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32237, y = 31287, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32238, y = 31282, z = 14}, false, true) + Game.createMonster("charging outburst", {x = 32234, y = 31284, z = 14}, false, true) + outburstStage = 3 + chargingOutKilled = false + elseif hp <= 20 and outburstStage == 3 then + outburstHealth = creature:getHealth() + creature:remove() + Game.createMonster("spark of destruction", {x = 32229, y = 31282, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32230, y = 31287, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32237, y = 31287, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32238, y = 31282, z = 14}, false, true) + Game.createMonster("charging outburst", {x = 32234, y = 31284, z = 14}, false, true) + outburstStage = 4 + chargingOutKilled = false + end + return true +end + +outburstCharge:register() diff --git a/data/scripts/creaturescripts/quests/heart_of_destruction/overcharge_death.lua b/data/scripts/creaturescripts/quests/heart_of_destruction/overcharge_death.lua new file mode 100644 index 00000000000..9ce78b6239f --- /dev/null +++ b/data/scripts/creaturescripts/quests/heart_of_destruction/overcharge_death.lua @@ -0,0 +1,63 @@ +local function setStorage() + --Room 1 + local upConer = {x = 32133, y = 31341, z = 14} -- upLeftCorner + local downConer = {x = 32174, y = 31375, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k= upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, creature in pairs(creatures) do + if creature:isPlayer() and creature:getStorageValue(14320) < 1 then + creature:setStorageValue(14320, 1) -- Access to boss Anomaly + end + end + end + end + end + end + end + + --Room 2 + local upConer2 = {x = 32140, y = 31340, z = 15} -- upLeftCorner + local downConer2 = {x = 32174, y = 31375, z = 15} -- downRightCorner + + for f=upConer2.x, downConer2.x do + for g=upConer2.y, downConer2.y do + for h=upConer2.z, downConer2.z do + local room = {x=f, y=g, z=h} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, creature in pairs(creatures) do + if creature:isPlayer() and creature:getStorageValue(14320) < 1 then -- hardcoded storges + creature:setStorageValue(14320, 1) -- Access to boss Anomaly + end + end + end + end + end + end + end +end + +local overchargeDeath = CreatureEvent("OverchargeDeath") +function overchargeDeath.onDeath(creature) + + Game.setStorageValue(14321, Game.getStorageValue(14321) + 1) + + if Game.getStorageValue(14321) == 5 then + setStorage() + creature:say("You have reached enough charges to pass further into the destruction!", TALKTYPE_MONSTER_YELL, isInGhostMode, pid, {x = 32162, y = 31356, z = 15}) + Game.setStorageValue(14321, -1) + end + + return true +end + +overchargeDeath:register() diff --git a/data/scripts/creaturescripts/quests/heart_of_destruction/rupture_heal.lua b/data/scripts/creaturescripts/quests/heart_of_destruction/rupture_heal.lua new file mode 100644 index 00000000000..7f6edbfc68c --- /dev/null +++ b/data/scripts/creaturescripts/quests/heart_of_destruction/rupture_heal.lua @@ -0,0 +1,11 @@ +local ruptureHeal = CreatureEvent() +function ruptureHeal.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin) + local healthGain = math.random(5000, 10000) + if attacker and attacker:isPlayer() and resonanceActive == true then + creature:addHealth(healthGain) + creature:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + end + return primaryDamage, primaryType, secondaryDamage, secondaryType +end + +ruptureHeal:register() diff --git a/data/scripts/creaturescripts/quests/heart_of_destruction/rupture_resonance.lua b/data/scripts/creaturescripts/quests/heart_of_destruction/rupture_resonance.lua new file mode 100644 index 00000000000..4d6a55a181e --- /dev/null +++ b/data/scripts/creaturescripts/quests/heart_of_destruction/rupture_resonance.lua @@ -0,0 +1,53 @@ +local ruptureResonance = CreatureEvent("RuptureResonance") +function ruptureResonance.onThink(creature) + if not creature or not creature:isMonster() then + return false + end + + local hp = (creature:getHealth() / creature:getMaxHealth()) * 100 + if hp <= 80 and ruptureResonanceStage == 0 and resonanceActive == false then + Game.createMonster("spark of destruction", {x = 32331, y = 31254, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32338, y = 31254, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32330, y = 31250, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32338, y = 31250, z = 14}, false, true) + Game.createMonster("damage resonance", {x = 32332, y = 31250, z = 14}, false, true) + ruptureResonanceStage = 1 + resonanceActive = true + elseif hp <= 60 and ruptureResonanceStage == 1 and resonanceActive == false then + Game.createMonster("spark of destruction", {x = 32331, y = 31254, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32338, y = 31254, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32330, y = 31250, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32338, y = 31250, z = 14}, false, true) + Game.createMonster("damage resonance", {x = 32332, y = 31250, z = 14}, false, true) + ruptureResonanceStage = 2 + resonanceActive = true + elseif hp <= 40 and ruptureResonanceStage == 2 and resonanceActive == false then + Game.createMonster("spark of destruction", {x = 32331, y = 31254, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32338, y = 31254, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32330, y = 31250, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32338, y = 31250, z = 14}, false, true) + Game.createMonster("damage resonance", {x = 32332, y = 31250, z = 14}, false, true) + ruptureResonanceStage = 3 + resonanceActive = true + elseif hp <= 25 and ruptureResonanceStage == 3 and resonanceActive == false then + Game.createMonster("spark of destruction", {x = 32331, y = 31254, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32338, y = 31254, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32330, y = 31250, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32338, y = 31250, z = 14}, false, true) + Game.createMonster("damage resonance", {x = 32332, y = 31250, z = 14}, false, true) + ruptureResonanceStage = 4 + resonanceActive = true + elseif hp <= 10 and ruptureResonanceStage == 4 and resonanceActive == false then + Game.createMonster("spark of destruction", {x = 32331, y = 31254, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32338, y = 31254, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32330, y = 31250, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32338, y = 31250, z = 14}, false, true) + Game.createMonster("damage resonance", {x = 32332, y = 31250, z = 14}, false, true) + ruptureResonanceStage = -1 + resonanceActive = true + end + + return true +end + +ruptureResonance:register() diff --git a/data/scripts/creaturescripts/quests/heart_of_destruction/shocks_death.lua b/data/scripts/creaturescripts/quests/heart_of_destruction/shocks_death.lua new file mode 100644 index 00000000000..f1257877b74 --- /dev/null +++ b/data/scripts/creaturescripts/quests/heart_of_destruction/shocks_death.lua @@ -0,0 +1,39 @@ +local shocksDeath = CreatureEvent("ShocksDeath") +function shocksDeath.onDeath(creature) + if not creature or not creature:isMonster() then + return true + end + + local name = creature:getName():lower() + if name == "foreshock" and realityQuakeStage == 0 then + if realityQuakeStage == 0 then + local monster = Game.createMonster("aftershock", {x = 32208, y = 31248, z = 14}, false, true) + monster:addHealth(-monster:getHealth() + aftershockHealth, COMBAT_PHYSICALDAMAGE) + Game.createMonster("spark of destruction", {x = 32203, y = 31246, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32205, y = 31251, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32210, y = 31251, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32212, y = 31246, z = 14}, false, true) + end + elseif name == "aftershock" and realityQuakeStage == 0 then + local monster = Game.createMonster("foreshock", {x = 32208, y = 31248, z = 14}, false, true) + monster:addHealth(-monster:getHealth() + aftershockHealth, COMBAT_PHYSICALDAMAGE) + Game.createMonster("spark of destruction", {x = 32203, y = 31246, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32205, y = 31251, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32210, y = 31251, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32212, y = 31246, z = 14}, false, true) + end + realityQuakeStage = realityQuakeStage + 1 + + if realityQuakeStage == 2 then + local pos = creature:getPosition() + local monster = Game.createMonster("realityquake", pos, false, true) + Game.createMonster("spark of destruction", {x = 32203, y = 31246, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32205, y = 31251, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32210, y = 31251, z = 14}, false, true) + Game.createMonster("spark of destruction", {x = 32212, y = 31246, z = 14}, false, true) + end + + return true +end + +shocksDeath:register() diff --git a/data/scripts/creaturescripts/quests/heart_of_destruction/spark_death.lua b/data/scripts/creaturescripts/quests/heart_of_destruction/spark_death.lua new file mode 100644 index 00000000000..9f292f791bc --- /dev/null +++ b/data/scripts/creaturescripts/quests/heart_of_destruction/spark_death.lua @@ -0,0 +1,37 @@ +local function setStorage() + local upConer = {x = 32126, y = 31296, z = 14} -- upLeftCorner + local downConer = {x = 32162, y = 31322, z = 14} -- downRightCorner + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k= upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, creature in pairs(creatures) do + if creature:isPlayer() and creature:getStorageValue(14324) < 1 then -- hardcoded storges + creature:setStorageValue(14324, 1) -- Access to boss realityquake + end + end + end + end + end + end + end +end + +local sparkDeath = CreatureEvent("SparkDeath") +function sparkDeath.onDeath(creature) + if unstableSparksCount < 10 then + unstableSparksCount = unstableSparksCount + 1 + creature:say("The death of the spark charges the room!", TALKTYPE_MONSTER_YELL, isInGhostMode, pid, {x = 32143, y = 31308, z = 14}) + elseif unstableSparksCount == 10 then + setStorage() + creature:say("The room is fully charged up! You are permeated with its power and can venture deeper into the heart of destruction now!", TALKTYPE_MONSTER_YELL, isInGhostMode, pid, {x = 32143, y = 31308, z = 14}) + unstableSparksCount = 11 + end + return true +end + +sparkDeath:register() diff --git a/data/scripts/creaturescripts/quests/heart_of_destruction/spark_devourer_death.lua b/data/scripts/creaturescripts/quests/heart_of_destruction/spark_devourer_death.lua new file mode 100644 index 00000000000..684327553b4 --- /dev/null +++ b/data/scripts/creaturescripts/quests/heart_of_destruction/spark_devourer_death.lua @@ -0,0 +1,7 @@ +local sparkDevourerDeath = CreatureEvent("SparkDevourerDeath") +function sparkDevourerDeath.onDeath(creature) + sparkSpawnCount = sparkSpawnCount + 1 + return true +end + +sparkDevourerDeath:register() diff --git a/data/scripts/creaturescripts/quests/hero_of_rathleton/bosses_kill.lua b/data/scripts/creaturescripts/quests/hero_of_rathleton/bosses_kill.lua new file mode 100644 index 00000000000..2936753cf9b --- /dev/null +++ b/data/scripts/creaturescripts/quests/hero_of_rathleton/bosses_kill.lua @@ -0,0 +1,76 @@ +local bosses = { + ['deep terror'] = { + teleportPos = Position(33749, 31952, 14), + nextpos = Position(33740, 31940, 15), + globaltimer = GlobalStorage.HeroRathleton.DeepRunning}, + ['empowered glooth horror'] = { + teleportPos = Position(33545, 31955, 15), + nextpos = Position(33534, 31955, 15), + globaltimer = GlobalStorage.HeroRathleton.HorrorRunning}, + ['professor maxxen'] = { + teleportPos = Position(33718, 32047, 15), + nextpos = Position(33707, 32107, 15), + globaltimer = GlobalStorage.HeroRathleton.MaxxenRunning} +} + +local function checkHorror() + local spectators = Game.getSpectators(Position(33555, 31956, 15), false, false, 13, 13, 13, 13) + for i = 1, #spectators do + local spectator = spectators[i] + if spectator:isMonster() then + if spectator:getName():lower() == 'empowered glooth horror' and spectator:getHealth() >= 1 then + return true + elseif spectator:getName():lower() == 'strong glooth horror' and spectator:getHealth() >= 1 then + return true + elseif spectator:getName():lower() == 'feeble glooth horror' and spectator:getHealth() >= 1 then + return true + elseif spectator:getName():lower() == 'weakened glooth horror' and spectator:getHealth() >= 1 then + return true + elseif spectator:getName():lower() == 'glooth horror' and spectator:getHealth() >= 1 then + return true + end + end + end + return false +end + +local function revertTeleport(position, itemId, transformId, destination) + local item = Tile(position):getItemById(itemId) + if item then + item:transform(transformId) + item:setDestination(destination) + end +end + +local rathletonBossKill = CreatureEvent("RathletonBossKill") +function rathletonBossKill.onKill(creature, target) + local targetMonster = target:getMonster() + if not targetMonster or targetMonster:getMaster() then + return true + end + local bossConfig = bosses[targetMonster:getName():lower()] + if not bossConfig then + return true + end + if targetMonster:getName():lower() == 'empowered glooth horror' then + if checkHorror() == true then + return true + end + end + + local teleport = Tile(bossConfig.teleportPos):getItemById(1387) + if not teleport then return true end + local teleportPos = bossConfig.teleportPos + local oldPos = teleport:getDestination() + local newPos = bossConfig.nextpos + if teleport then + teleport:transform(25417) + targetMonster:getPosition():sendMagicEffect(CONST_ME_THUNDER) + teleport:setDestination(newPos) + addEvent(revertTeleport, 2 * 60 * 1000, teleportPos, 25417, 1387, oldPos) + Game.setStorageValue(bossConfig.globaltimer, 0) + end + return true +end + +rathletonBossKill:register() diff --git a/data/scripts/creaturescripts/quests/hero_of_rathleton/glooth_horror.lua b/data/scripts/creaturescripts/quests/hero_of_rathleton/glooth_horror.lua new file mode 100644 index 00000000000..2ec80331e29 --- /dev/null +++ b/data/scripts/creaturescripts/quests/hero_of_rathleton/glooth_horror.lua @@ -0,0 +1,30 @@ +local config = { + {name = 'Feeble Glooth Horror', monster = 'Weakened Glooth Horror'}, + {name = 'Weakened Glooth Horror', monster = 'Glooth Horror'}, + {name = 'Glooth Horror', monster = 'Strong Glooth Horror'}, + {name = 'Strong Glooth Horror', monster = 'Empowered Glooth Horror'} +} + +local gloothHorror = CreatureEvent("GloothHorror") +function gloothHorror.onDeath(creature, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified) + local targetMonster = creature:getMonster() + if not targetMonster or targetMonster:getMaster() then + return true + end + + local name = targetMonster:getName() + for i = 1, #config do + if name == config[i].name then + for j = 1, 2 do + local spawnMonster = Game.createMonster(config[i].monster, targetMonster:getPosition(), true, true) + if spawnMonster then + spawnMonster:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + break + end + end + return true +end + +gloothHorror:register() diff --git a/data/scripts/creaturescripts/quests/hero_of_rathleton/tentacle.lua b/data/scripts/creaturescripts/quests/hero_of_rathleton/tentacle.lua new file mode 100644 index 00000000000..69797f798cf --- /dev/null +++ b/data/scripts/creaturescripts/quests/hero_of_rathleton/tentacle.lua @@ -0,0 +1,30 @@ +local function checkTentacle() + local spectators = Game.getSpectators(Position(33740, 31953, 14), false, false, 13, 13, 13, 13) + local position = math.random(33736, 33746), math.random(31948, 31957), 14 + for i = 1, #spectators do + local spec = spectators[i] + if spec:isMonster() and spec:getName():lower() == 'tentacle of the deep terror' and spec:getHealth() >= 1 then + Game.createMonster('tentacle of the deep terror', Position(position), true, true) + return true + else + if Game.getStorageValue(GlobalStorage.HeroRathleton.DeepRunning) == 2 then + return true + end + Game.createMonster('Deep Terror', Position(33741, 31953, 14), true, true) + Game.setStorageValue(GlobalStorage.HeroRathleton.DeepRunning, 2) + return true + end + end +end + +local tentacleDeep = CreatureEvent("TentacleDeep") +function tentacleDeep.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + local targetMonster = creature:getMonster() + if not targetMonster then + return true + end + addEvent(checkTentacle, 5 * 1000) + return true +end + +tentacleDeep:register() diff --git a/data/scripts/creaturescripts/quests/in_service_of_yalahar/azerus_kill.lua b/data/scripts/creaturescripts/quests/in_service_of_yalahar/azerus_kill.lua new file mode 100644 index 00000000000..87bda64b60a --- /dev/null +++ b/data/scripts/creaturescripts/quests/in_service_of_yalahar/azerus_kill.lua @@ -0,0 +1,41 @@ + +local function removeTeleport(position) + local teleportItem = Tile(position):getItemById(1387) + if teleportItem then + teleportItem:remove() + position:sendMagicEffect(CONST_ME_POFF) + end +end + +local azerus = CreatureEvent("Azerus") +function azerus.onKill(creature, target) + local targetMonster = target:getMonster() + if not targetMonster or targetMonster:getName():lower() ~= 'azerus' then + return true + end + + local position = targetMonster:getPosition() + position:sendMagicEffect(CONST_ME_TELEPORT) + local item = Game.createItem(1387, 1, position) + local teleportToPosition = Position(32780, 31168, 14) + if item:isTeleport() then + item:setDestination(teleportToPosition) + end + targetMonster:say("Azerus ran into teleporter! It will disappear in 2 minutes. Enter it!", + TALKTYPE_MONSTER_SAY, 0, 0, position) + --remove portal after 2 min + addEvent(removeTeleport, 2 * 60 * 1000, position) + + --clean arena of monsters + local spectators, spectator = Game.getSpectators(Position(32783, 31166, 10), false, false, 10, 10, 10, 10) + for i = 1, #spectators do + spectator = spectators[i] + if spectator:isMonster() then + spectator:getPosition():sendMagicEffect(CONST_ME_POFF) + spectator:remove() + end + end + return true +end + +azerus:register() diff --git a/data/scripts/creaturescripts/quests/in_service_of_yalahar/diseased_trio_kill.lua b/data/scripts/creaturescripts/quests/in_service_of_yalahar/diseased_trio_kill.lua new file mode 100644 index 00000000000..050a5e41827 --- /dev/null +++ b/data/scripts/creaturescripts/quests/in_service_of_yalahar/diseased_trio_kill.lua @@ -0,0 +1,34 @@ +local diseasedTrio = { + ['diseased bill'] = Storage.InServiceofYalahar.DiseasedBill, + ['diseased dan'] = Storage.InServiceofYalahar.DiseasedDan, + ['diseased fred'] = Storage.InServiceofYalahar.DiseasedFred +} + +local diseasedTrioKill = CreatureEvent("DiseasedTrio") +function diseasedTrioKill.onKill(creature, target) + local targetMonster = target:getMonster() + if not targetMonster then + return true + end + + local bossStorage = diseasedTrio[targetMonster:getName():lower()] + if not bossStorage then + return true + end + + local player = creature:getPlayer() + if player:getStorageValue(bossStorage) < 1 then + player:setStorageValue(bossStorage, 1) + player:say('You slayed ' .. targetMonster:getName() .. '.', TALKTYPE_MONSTER_SAY) + end + + if (player:getStorageValue(Storage.InServiceofYalahar.DiseasedDan) == 1 and + player:getStorageValue(Storage.InServiceofYalahar.DiseasedBill) == 1 and + player:getStorageValue(Storage.InServiceofYalahar.DiseasedFred) == 1 and + player:getStorageValue(Storage.InServiceofYalahar.AlchemistFormula) ~= 1) then + player:setStorageValue(Storage.InServiceofYalahar.AlchemistFormula, 0) + end + return true +end + +diseasedTrioKill:register() diff --git a/data/scripts/creaturescripts/quests/in_service_of_yalahar/quara_leader_kill.lua b/data/scripts/creaturescripts/quests/in_service_of_yalahar/quara_leader_kill.lua new file mode 100644 index 00000000000..669f6c2d452 --- /dev/null +++ b/data/scripts/creaturescripts/quests/in_service_of_yalahar/quara_leader_kill.lua @@ -0,0 +1,31 @@ +local quaraLeaders = { + ['inky'] = Storage.InServiceofYalahar.QuaraInky, + ['sharptooth'] = Storage.InServiceofYalahar.QuaraSharptooth, + ['splasher'] = Storage.InServiceofYalahar.QuaraSplasher +} + +local quaraLeadersKill = CreatureEvent("QuaraLeaders") +function quaraLeadersKill.onKill(creature, target) + local targetMonster = target:getMonster() + if not targetMonster then + return true + end + + local bossStorage = quaraLeaders[targetMonster:getName():lower()] + if not bossStorage then + return true + end + + local player = creature:getPlayer() + if player:getStorageValue(bossStorage) < 1 then + player:setStorageValue(bossStorage, 1) + player:say('You slayed ' .. targetMonster:getName() .. '.', TALKTYPE_MONSTER_SAY) + player:setStorageValue(Storage.InServiceofYalahar.QuaraState, 2) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 41) + -- StorageValue for Questlog 'Mission 07: A Fishy Mission' + player:setStorageValue(Storage.InServiceofYalahar.Mission07, 4) + end + return true +end + +quaraLeadersKill:register() diff --git a/data/scripts/creaturescripts/quests/inquisition/inquisition_boss.lua b/data/scripts/creaturescripts/quests/inquisition/inquisition_boss.lua new file mode 100644 index 00000000000..ac19f2ac40e --- /dev/null +++ b/data/scripts/creaturescripts/quests/inquisition/inquisition_boss.lua @@ -0,0 +1,37 @@ +local bosses = { + ['ushuriel'] = 200, + ['zugurosh'] = 201, + ['madareth'] = 202, + ['latrivan'] = 203, + ['golgordan'] = 203, + ['annihilon'] = 204, + ['hellgorak'] = 205 +} + +local inquisitionBossKill = CreatureEvent("InquisitionBossKill") +function inquisitionBossKill.onKill(player, target) + local targetMonster = target:getMonster() + if not targetMonster then + return true + end + + local targetName = targetMonster:getName():lower() + local bossStorage = bosses[targetName] + if not bossStorage then + return true + end + + local newValue = 2 + if targetName == 'latrivan' or targetName == 'golgordan' then + newValue = math.max(0, Game.getStorageValue(bossStorage)) + 1 + end + Game.setStorageValue(bossStorage, newValue) + + if newValue == 2 then + player:say('You now have 10 minutes to exit this room through the teleporter. It will bring you to the next room.', TALKTYPE_MONSTER_SAY) + addEvent(Game.setStorageValue, 10 * 60 * 1000, bossStorage, 0) + end + return true +end + +inquisitionBossKill:register() diff --git a/data/scripts/creaturescripts/quests/inquisition/inquisition_ungreez.lua b/data/scripts/creaturescripts/quests/inquisition/inquisition_ungreez.lua new file mode 100644 index 00000000000..9f5a2a0a067 --- /dev/null +++ b/data/scripts/creaturescripts/quests/inquisition/inquisition_ungreez.lua @@ -0,0 +1,21 @@ +local ungreezKill = CreatureEvent("UngreezKill") +function ungreezKill.onKill(creature, target) + local targetMonster = target:getMonster() + if not targetMonster then + return true + end + + if targetMonster:getName():lower() ~= 'ungreez' then + return true + end + + local player = creature:getPlayer() + if player:getStorageValue(Storage.TheInquisition.Questline) == 18 then + -- The Inquisition Questlog- 'Mission 6: The Demon Ungreez' + player:setStorageValue(Storage.TheInquisition.Mission06, 2) + player:setStorageValue(Storage.TheInquisition.Questline, 19) + end + return true +end + +ungreezKill:register() diff --git a/data/scripts/creaturescripts/quests/killing_in_the_name_of/kill.lua b/data/scripts/creaturescripts/quests/killing_in_the_name_of/kill.lua new file mode 100644 index 00000000000..3d2dabce651 --- /dev/null +++ b/data/scripts/creaturescripts/quests/killing_in_the_name_of/kill.lua @@ -0,0 +1,45 @@ +local killingInTheNameOfKill = CreatureEvent("KillingInTheNameOfKill") +function killingInTheNameOfKill.onKill(player, target) + if target:isPlayer() or target:getMaster() then + return true + end + + local targetName, startedTasks, taskId = target:getName():lower(), player:getStartedTasks() + for i = 1, #startedTasks do + taskId = startedTasks[i] + if isInArray(tasks[taskId].creatures, targetName) then + local killAmount = player:getStorageValue(KILLSSTORAGE_BASE + taskId) + if killAmount < tasks[taskId].killsRequired then + -- Set max kills to adm + if (player:getAccountType() >= ACCOUNT_TYPE_GOD) then + player:setStorageValue(KILLSSTORAGE_BASE + taskId, tasks[taskId].killsRequired) + return true + end + + player:setStorageValue(KILLSSTORAGE_BASE + taskId, killAmount + 1) + end + end + end + + if(isMonster(target)) then + local killAmount = player:getStorageValue(Storage.KillingInTheNameOf.LugriNecromancerCount) + if(string.lower(getCreatureName(target)) == "necromancer") and killAmount < 4000 and player:getStorageValue(Storage.KillingInTheNameOf.LugriNecromancers) == 1 then + player:setStorageValue(Storage.KillingInTheNameOf.LugriNecromancerCount, killAmount + 1) + + elseif(string.lower(getCreatureName(target)) == "priestess") and killAmount < 4000 and player:getStorageValue(Storage.KillingInTheNameOf.LugriNecromancers) == 1 then + player:setStorageValue(Storage.KillingInTheNameOf.LugriNecromancerCount, killAmount + 1) + + elseif(string.lower(getCreatureName(target)) == "blood priest") and killAmount < 4000 and player:getStorageValue(Storage.KillingInTheNameOf.LugriNecromancers) == 1 then + player:setStorageValue(Storage.KillingInTheNameOf.LugriNecromancerCount, killAmount + 1) + + elseif(string.lower(getCreatureName(target)) == "blood hand") and killAmount < 4000 and player:getStorageValue(Storage.KillingInTheNameOf.LugriNecromancers) == 1 then + player:setStorageValue(Storage.KillingInTheNameOf.LugriNecromancerCount, killAmount + 1) + + elseif(string.lower(getCreatureName(target)) == "shadow pupil") and killAmount < 4000 and player:getStorageValue(Storage.KillingInTheNameOf.LugriNecromancers) == 1 then + player:setStorageValue(Storage.KillingInTheNameOf.LugriNecromancerCount, killAmount + 1) + end + end + return true +end + +killingInTheNameOfKill:register() diff --git a/data/scripts/creaturescripts/quests/killing_in_the_name_of/minotaur_kill.lua b/data/scripts/creaturescripts/quests/killing_in_the_name_of/minotaur_kill.lua new file mode 100644 index 00000000000..3f6f7384b8d --- /dev/null +++ b/data/scripts/creaturescripts/quests/killing_in_the_name_of/minotaur_kill.lua @@ -0,0 +1,35 @@ +local minotaurs = { + "minotaur", + "depowered minotaur", + "execowtioner", + "glooth powered minotaur", + "minotaur archer", + "minotaur bruiser", + "minotaur guard", + "minotaur hunter", + "minotaur mage", + "minotaur poacher", + "mooh'tah warrior", + "moohtant", + "worm priestess", + "minotaur amazon" +} + +local killingInTheNameOfMinotaurKill = CreatureEvent("KillingInTheNameOfMinotaurKill") +function killingInTheNameOfMinotaurKill.onKill(player, target) + if target:isPlayer() or target:getMaster() then + return true + end + + if not isInArray(minotaurs, target:getName():lower()) then + return true + end + + local killAmount = player:getStorageValue(Storage.KillingInTheNameOf.BudrikMinosCount) + if player:getStorageValue(Storage.KillingInTheNameOf.BudrikMinos) == 1 and killAmount < 5000 then + player:setStorageValue(Storage.KillingInTheNameOf.BudrikMinosCount, killAmount + 1) + end + return true +end + +killingInTheNameOfMinotaurKill:register() diff --git a/data/scripts/creaturescripts/quests/kilmaresh/bragrumol.lua b/data/scripts/creaturescripts/quests/kilmaresh/bragrumol.lua new file mode 100644 index 00000000000..9e4b43946ca --- /dev/null +++ b/data/scripts/creaturescripts/quests/kilmaresh/bragrumol.lua @@ -0,0 +1,17 @@ +local bragrumol = CreatureEvent("BragrumolKill") + +function bragrumol.onKill(cid, target, damage, flags, corpse) + if(isMonster(target)) then + if(string.lower(getCreatureName(target)) == "bragrumol") then + for attackerUid, damage in pairs(target:getDamageMap()) do + local player = Player(attackerUid) + if player and player:getStorageValue(Storage.Kilmaresh.Twelve.Bragrumol) == 1 then + player:setStorageValue(Storage.Kilmaresh.Twelve.Bragrumol, 2) + end + end + end + end + return true +end + +bragrumol:register() diff --git a/data/scripts/creaturescripts/quests/kilmaresh/fafnar.lua b/data/scripts/creaturescripts/quests/kilmaresh/fafnar.lua new file mode 100644 index 00000000000..a924cb03905 --- /dev/null +++ b/data/scripts/creaturescripts/quests/kilmaresh/fafnar.lua @@ -0,0 +1,25 @@ +local monster = { + ['burning gladiator'] = Storage.Kilmaresh.Thirteen.Fafnar, + ['priestess of the wild sun'] = Storage.Kilmaresh.Thirteen.Fafnar +} + +local fafnar = CreatureEvent("FafnarKill") + +function fafnar.onKill(creature, target) + local storage = monster[target:getName():lower()] + if target:isPlayer() or target:getMaster() or not storage then + return false + end + + local kills = creature:getStorageValue(storage) + if kills == 300 and creature:getStorageValue(storage) == 1 then + creature:say('You slayed ' .. target:getName() .. '.', TALKTYPE_MONSTER_SAY) + else + kills = kills + 1 + creature:say('You have slayed ' .. target:getName() .. ' '.. kills ..' times!', TALKTYPE_MONSTER_SAY) + creature:setStorageValue(storage, kills) + end + return true +end + +fafnar:register() diff --git a/data/scripts/creaturescripts/quests/kilmaresh/mozradek.lua b/data/scripts/creaturescripts/quests/kilmaresh/mozradek.lua new file mode 100644 index 00000000000..c039bda2492 --- /dev/null +++ b/data/scripts/creaturescripts/quests/kilmaresh/mozradek.lua @@ -0,0 +1,17 @@ +local mozradek = CreatureEvent("MozradekKill") + +function mozradek.onKill(cid, target, damage, flags, corpse) + if(isMonster(target)) then + if(string.lower(getCreatureName(target)) == "mozradek") then + for attackerUid, damage in pairs(target:getDamageMap()) do + local player = Player(attackerUid) + if player and player:getStorageValue(Storage.Kilmaresh.Twelve.Mozradek) == 1 then + player:setStorageValue(Storage.Kilmaresh.Twelve.Mozradek, 2) + end + end + end + end + return true +end + +mozradek:register() diff --git a/data/scripts/creaturescripts/quests/kilmaresh/xogixath.lua b/data/scripts/creaturescripts/quests/kilmaresh/xogixath.lua new file mode 100644 index 00000000000..b02ae3baf79 --- /dev/null +++ b/data/scripts/creaturescripts/quests/kilmaresh/xogixath.lua @@ -0,0 +1,17 @@ +local xogixath = CreatureEvent("XogixathKill") + +function xogixath.onKill(cid, target, damage, flags, corpse) + if(isMonster(target)) then + if(string.lower(getCreatureName(target)) == "xogixath") then + for attackerUid, damage in pairs(target:getDamageMap()) do + local player = Player(attackerUid) + if player and player:getStorageValue(Storage.Kilmaresh.Twelve.Xogixath) == 1 then + player:setStorageValue(Storage.Kilmaresh.Twelve.Xogixath, 2) + end + end + end + end + return true +end + +xogixath:register() diff --git a/data/scripts/creaturescripts/quests/liquid_black/deepling_boss_kill.lua b/data/scripts/creaturescripts/quests/liquid_black/deepling_boss_kill.lua new file mode 100644 index 00000000000..5e71e3958bd --- /dev/null +++ b/data/scripts/creaturescripts/quests/liquid_black/deepling_boss_kill.lua @@ -0,0 +1,30 @@ +local bosses = { + ['jaul'] = {status = 2, storage = Storage.DeeplingBosses.Jaul}, + ['tanjis'] = {status = 3, storage = Storage.DeeplingBosses.Tanjis}, + ['obujos'] = {status = 4, storage = Storage.DeeplingBosses.Obujos}, +} + +local deeplingBosses = CreatureEvent("DeeplingBosses") +function deeplingBosses.onKill(creature, target) + local targetMonster = target:getMonster() + if not targetMonster then + return true + end + + local bossConfig = bosses[targetMonster:getName():lower()] + if not bossConfig then + return true + end + + for pid, _ in pairs(targetMonster:getDamageMap()) do + local attackerPlayer = Player(pid) + if attackerPlayer then + if attackerPlayer:getStorageValue(Storage.DeeplingBosses.DeeplingStatus) < bossConfig.status then + attackerPlayer:setStorageValue(Storage.DeeplingBosses.DeeplingStatus, bossConfig.status) + end + attackerPlayer:setStorageValue(bossConfig.storage, 1) + end + end +end + +deeplingBosses:register() diff --git a/data/scripts/creaturescripts/quests/raging_mage_tower/energized_raging_mage_kill.lua b/data/scripts/creaturescripts/quests/raging_mage_tower/energized_raging_mage_kill.lua new file mode 100644 index 00000000000..95cf707a712 --- /dev/null +++ b/data/scripts/creaturescripts/quests/raging_mage_tower/energized_raging_mage_kill.lua @@ -0,0 +1,24 @@ +local energizedRagingMageKill = CreatureEvent("EnergizedRagingMageKill") +function energizedRagingMageKill.onKill(player, creature, damage, flags) + if not creature or not creature:isMonster() then + return true + end + + if creature:getName():lower() ~= "energized raging mage" then + return true + end + + if getGlobalStorageValue(673003) < 2000 then + return true + end + + local monster = Game.createMonster("Raging Mage", creature:getPosition()) + monster:setReward(true) + + doCreatureSayWithRadius(player, "GNAAAAAHRRRG!! WHAT? WHAT DID YOU DO TO ME!! I... I feel the energies crawling away... from me... DIE!!!", TALKTYPE_ORANGE_1, 35, 71) + setGlobalStorageValue(673003, 0) + + return true +end + +energizedRagingMageKill:register() diff --git a/data/scripts/creaturescripts/quests/raging_mage_tower/raging_mage_1.lua b/data/scripts/creaturescripts/quests/raging_mage_tower/raging_mage_1.lua new file mode 100644 index 00000000000..15525e2d8b0 --- /dev/null +++ b/data/scripts/creaturescripts/quests/raging_mage_tower/raging_mage_1.lua @@ -0,0 +1,39 @@ +local ragingMage1 = CreatureEvent("RagingMage1") +function ragingMage1.onDeath(creature, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified) + local playerDoubleMageKill = 775558 + local yielothaxKillStorage = 673003 + local enoughKills = 775559 + + if killer:getStorageValue(playerDoubleMageKill) < 2 and not + mostDamageKiller:hasAchievement('Mageslayer') and Game.getStorageValue(yielothaxKillStorage) < 2000 then + creature:say("MWAAAHAHAAA!! NO ONE!! NO ONE CAN DEFEAT MEEE!!!", + TALKTYPE_MONSTER_YELL, false, nil, Position(33143, 31527, 2)) + Game.createMonster("energized raging mage", Position(33142, 31529, 2)) + mostDamageKiller:setStorageValue(playerDoubleMageKill, mostDamageKiller:getStorageValue(playerDoubleMageKill) + 1) + mostDamageKiller:addAchievement('Mageslayer') + elseif Game.getStorageValue(yielothaxKillStorage) < 2000 then + creature:say("MWAAAHAHAAA!! NO ONE!! NO ONE CAN DEFEAT MEEE!!!", + TALKTYPE_MONSTER_YELL, false, nil, Position(33143, 31527, 2)) + Game.createMonster("Energized Raging Mage", Position(33142, 31529, 2)) + elseif Game.getStorageValue(yielothaxKillStorage) > 1999 then + Game.createMonster("raging mage", Position(33142, 31529, 2)) + creature:say("GNAAAAAHRRRG!! WHAT? WHAT DID YOU DO TO ME!! I... I feel the energies crawling away... from me... DIE!!!", + TALKTYPE_MONSTER_YELL, false, nil, Position(33143, 31527, 2)) + Game.setStorageValue(yielothaxKillStorage, 0) + Game.setStorageValue(enoughKills, 1) + local t, spectator = Game.getSpectators(creature:getPosition(), false, false, 10, 10, 10, 10) + if #t ~= nil then + for i = 1, #t do + spectator = t[i] + if spectator:isPlayer() and spectator:getStorageValue(673004) < 250 then + spectator:teleportTo(Position(33142, 31529, 3)) + spectator:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + spectator:say("You have not proven worthy in the dimensional struggle against the yielothax." , TALKTYPE_MONSTER_SAY, false, nil, Position(33142, 31529, 3)) + end + end + end + return true + end +end + +ragingMage1:register() diff --git a/data/scripts/creaturescripts/quests/raging_mage_tower/raging_mage_2.lua b/data/scripts/creaturescripts/quests/raging_mage_tower/raging_mage_2.lua new file mode 100644 index 00000000000..4161b682eb5 --- /dev/null +++ b/data/scripts/creaturescripts/quests/raging_mage_tower/raging_mage_2.lua @@ -0,0 +1,26 @@ +local ragingMage2 = CreatureEvent("RagingMage2") +function ragingMage2.onDeath(creature, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified) + local targetMonster = creature:getMonster() + if not targetMonster or targetMonster:getName():lower() ~= 'raging mage' then + return true + end + + broadcastMessage("The remains of the Raging Mage are scattered on the floor of his Tower. \z + The dimensional portal quakes.", MESSAGE_EVENT_ADVANCE) + targetMonster:say("I WILL RETURN!! My death will just be a door to await my homecoming, \z + my physical hull will be... my... argh...", TALKTYPE_MONSTER_SAY, 0, 0, Position(33142, 31529, 2)) + addEvent(function() + local tilePos = Tile(Position(33143, 31527, 2)):getItemById(11796) + if not tilePos then + return true + end + tilePos:remove() + broadcastMessage("With a great bang the dimensional portal in Zao collapsed and \z + with it the connection to the other dimension shattered.", MESSAGE_EVENT_ADVANCE) + end, 5 * 60 * 1000) + mostDamageKiller:setStorageValue(673004, 0) + Game.setStorageValue(775559, 0) + return true +end + +ragingMage2:register() diff --git a/data/scripts/creaturescripts/quests/raging_mage_tower/raging_mage_kill.lua b/data/scripts/creaturescripts/quests/raging_mage_tower/raging_mage_kill.lua new file mode 100644 index 00000000000..d21e5bbf276 --- /dev/null +++ b/data/scripts/creaturescripts/quests/raging_mage_tower/raging_mage_kill.lua @@ -0,0 +1,14 @@ +local ragingMageKill = CreatureEvent("ragingMageKill") +function ragingMageKill.onKill(cid, target, damage, flags, corpse) + if(isMonster(target)) then + if(string.lower(getCreatureName(target)) == "raging mage") then + broadcastMessage("The remains of the Raging Mage are scattered on the floor of his Tower. The dimensional portal quakes.", MESSAGE_EVENT_ADVANCE) + doCreatureSay(target, "I WILL RETURN!! My death will just be a door to await my homecoming, my physical hull will be... my... argh...", TALKTYPE_ORANGE_1) + addEvent(doRemoveItem, 5 * 60 * 1000, getTileItemById({x = 33143, y = 31527, z = 2}, 11796).uid, 1) + addEvent(broadcastMessage, 5 * 60 * 1000, "With a great bang the dimensional portal in Zao collapsed and with it the connection to the other dimension shattered.", MESSAGE_EVENT_ADVANCE) + end + end + return true +end + +ragingMageKill:register() diff --git a/data/scripts/creaturescripts/quests/raging_mage_tower/yielothax_kill.lua b/data/scripts/creaturescripts/quests/raging_mage_tower/yielothax_kill.lua new file mode 100644 index 00000000000..20d8ace18d2 --- /dev/null +++ b/data/scripts/creaturescripts/quests/raging_mage_tower/yielothax_kill.lua @@ -0,0 +1,11 @@ +local yielothaxKill = CreatureEvent("YielothaxKill") +function yielothaxKill.onKill(cid, target, damage, flags) + if(isMonster(target)) then + if(string.lower(getCreatureName(target)) == "yielothax") then + setGlobalStorageValue(673003, getGlobalStorageValue(673003) + 1) + end + end + return true +end + +yielothaxKill:register() diff --git a/data/scripts/creaturescripts/quests/secret_service/black_knight_kill.lua b/data/scripts/creaturescripts/quests/secret_service/black_knight_kill.lua new file mode 100644 index 00000000000..611de73ce09 --- /dev/null +++ b/data/scripts/creaturescripts/quests/secret_service/black_knight_kill.lua @@ -0,0 +1,20 @@ +local blackKnightKill = CreatureEvent("BlackKnightKill") +function blackKnightKill.onKill(creature, target) + local targetMonster = target:getMonster() + if not targetMonster then + return true + end + + if targetMonster:getName():lower() ~= "black knight" then + return true + end + + local player = creature:getPlayer() + if player:getStorageValue(Storage.SecretService.AVINMission04) == 1 then + player:setStorageValue(Storage.SecretService.AVINMission04, 2) + end + + return true +end + +blackKnightKill:register() diff --git a/data/scripts/creaturescripts/quests/spike_tasks/lower_spike_kill.lua b/data/scripts/creaturescripts/quests/spike_tasks/lower_spike_kill.lua new file mode 100644 index 00000000000..d735cdcaf5e --- /dev/null +++ b/data/scripts/creaturescripts/quests/spike_tasks/lower_spike_kill.lua @@ -0,0 +1,23 @@ +local range = { + -- Only the Drillworms killed on this area count + from = Position(32120, 32470, 13), + to = Position(32345, 32710, 15) +} + +local lowerSpikeKill = CreatureEvent("LowerSpikeKill") +function lowerSpikeKill.onKill(creature, target) + if not isInArray({-1, 7}, creature:getStorageValue(SPIKE_LOWER_KILL_MAIN)) then + if creature:getPosition():isInRange(range.from, range.to) then + if target:isMonster() and (target:getMaster() == nil) and (target:getName():lower() == "drillworm") then + local sum = creature:getStorageValue(SPIKE_LOWER_KILL_MAIN) + 1 + creature:setStorageValue(SPIKE_LOWER_KILL_MAIN, sum) + creature:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have slayed " .. sum .. " out of 7 Drillworms.") + if sum == 7 then + creature:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Report the task to Gnomargery.") + end + end + end + end +end + +lowerSpikeKill:register() diff --git a/data/scripts/creaturescripts/quests/spike_tasks/middle_spike_kill.lua b/data/scripts/creaturescripts/quests/spike_tasks/middle_spike_kill.lua new file mode 100644 index 00000000000..dcdc2d6a088 --- /dev/null +++ b/data/scripts/creaturescripts/quests/spike_tasks/middle_spike_kill.lua @@ -0,0 +1,23 @@ +local range = { + -- Only the Crystalcrushers killed on this area count + from = Position(32100, 32470, 11), + to = Position(32380, 32725, 12) +} + +local middleSpikeKill = CreatureEvent("MiddleSpikeKill") +function middleSpikeKill.onKill(creature, target) + if not isInArray({-1, 7}, creature:getStorageValue(SPIKE_MIDDLE_KILL_MAIN)) then + if creature:getPosition():isInRange(range.from, range.to) then + if target:isMonster() and (target:getMaster() == nil) and (target:getName():lower() == "crystalcrusher") then + local sum = creature:getStorageValue(SPIKE_MIDDLE_KILL_MAIN) + 1 + creature:setStorageValue(SPIKE_MIDDLE_KILL_MAIN, sum) + creature:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have slayed " .. sum .. " out of 7 Crystalcrushers.") + if sum == 7 then + creature:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Report the task to Gnombold.") + end + end + end + end +end + +middleSpikeKill:register() diff --git a/data/scripts/creaturescripts/quests/spike_tasks/upper_spike_kill.lua b/data/scripts/creaturescripts/quests/spike_tasks/upper_spike_kill.lua new file mode 100644 index 00000000000..f3f7cae4d5e --- /dev/null +++ b/data/scripts/creaturescripts/quests/spike_tasks/upper_spike_kill.lua @@ -0,0 +1,23 @@ +local range = { + -- Only the Demon Skeletons killed on this area count + from = Position(32008, 32522, 8), + to = Position(32365, 32759, 10) +} + +local upperSpikeKill = CreatureEvent("UpperSpikeKill") +function upperSpikeKill.onKill(creature, target) + if not isInArray({-1, 7}, creature:getStorageValue(SPIKE_UPPER_KILL_MAIN)) then + if creature:getPosition():isInRange(range.from, range.to) then + if target:isMonster() and (target:getMaster() == nil) and (target:getName():lower() == "demon skeleton") then + local sum = creature:getStorageValue(SPIKE_UPPER_KILL_MAIN) + 1 + creature:setStorageValue(SPIKE_UPPER_KILL_MAIN, sum) + creature:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have slayed " .. sum .. " out of 7 Demon Skeletons.") + if sum == 7 then + creature:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Report the task to Gnomilly.") + end + end + end + end +end + +upperSpikeKill:register() diff --git a/data/scripts/creaturescripts/quests/svargrond_arena/arena_kill.lua b/data/scripts/creaturescripts/quests/svargrond_arena/arena_kill.lua new file mode 100644 index 00000000000..0219a8a6369 --- /dev/null +++ b/data/scripts/creaturescripts/quests/svargrond_arena/arena_kill.lua @@ -0,0 +1,43 @@ +local svargrondArenaKill = CreatureEvent("SvargrondArenaKill") +function svargrondArenaKill.onKill(creature, target) + local targetMonster = target:getMonster() + if not targetMonster then + return + end + + local player = creature:getPlayer() + local pit = player:getStorageValue(Storage.SvargrondArena.PitDoor) + if pit < 1 or pit > 10 then + return + end + + local arena = player:getStorageValue(Storage.SvargrondArena.Arena) + if arena < 1 then + return + end + + if not isInArray(ARENA[arena].creatures, targetMonster:getName():lower()) then + return + end + + -- Remove pillar and create teleport + local pillarTile = Tile(PITS[pit].pillar) + if pillarTile then + local pillarItem = pillarTile:getItemById(SvargrondArena.itemPillar) + if pillarItem then + pillarItem:remove() + + local teleportItem = Game.createItem(SvargrondArena.itemTeleport, 1, PITS[pit].tp) + if teleportItem then + teleportItem:setActionId(25200) + end + + SvargrondArena.sendPillarEffect(pit) + end + end + player:setStorageValue(Storage.SvargrondArena.PitDoor, pit + 1) + player:say('Victory! Head through the new teleporter into the next room.', TALKTYPE_MONSTER_SAY) + return true +end + +svargrondArenaKill:register() diff --git a/data/scripts/creaturescripts/quests/the_first_dragon/death_angry_plant.lua b/data/scripts/creaturescripts/quests/the_first_dragon/death_angry_plant.lua new file mode 100644 index 00000000000..98ed269bddb --- /dev/null +++ b/data/scripts/creaturescripts/quests/the_first_dragon/death_angry_plant.lua @@ -0,0 +1,10 @@ +local deathAngryPlant = CreatureEvent("AngryPlantDeath") + +function deathAngryPlant.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + if corpse then + corpse:setAttribute(ITEM_ATTRIBUTE_UNIQUEID, 1066) + end + return true +end + +deathAngryPlant:register() diff --git a/data/scripts/creaturescripts/quests/the_first_dragon/death_dragon_essence.lua b/data/scripts/creaturescripts/quests/the_first_dragon/death_dragon_essence.lua new file mode 100644 index 00000000000..da59201440a --- /dev/null +++ b/data/scripts/creaturescripts/quests/the_first_dragon/death_dragon_essence.lua @@ -0,0 +1,16 @@ +local deathDragonEssence = CreatureEvent("DragonEssenceDeath") + +function deathDragonEssence.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + local spectators = Game.getSpectators(Position(33617, 31023, 14), false, false, 14, 14, 14, 14) + for i = 1, #spectators do + local spec = spectators[i] + if spec:getName() == 'Dragon Essence' then + spec:remove() + end + end + Game.createMonster('The First Dragon', Position(33617, 31023, 14), true, true) + creature:say('BEWARE! THE FIRST DRAGON APROACHES!', TALKTYPE_MONSTER_SAY, false, nil, Position(33617, 31023, 14)) + return true +end + +deathDragonEssence:register() diff --git a/data/scripts/creaturescripts/quests/the_first_dragon/death_fallen.lua b/data/scripts/creaturescripts/quests/the_first_dragon/death_fallen.lua new file mode 100644 index 00000000000..9aeebb67ae3 --- /dev/null +++ b/data/scripts/creaturescripts/quests/the_first_dragon/death_fallen.lua @@ -0,0 +1,17 @@ +local deathFallen = CreatureEvent("FallenDeath") + +local function removeTp(position, itemid) + local teleport = Tile(position):getItemById(itemid) + if teleport then + teleport:remove() + end +end +function deathFallen.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + if corpse then + corpse:setDestination(Position(33621, 31023, 14)) + addEvent(removeTp, 30 * 1000, corpse:getPosition(), 1397) + end + return true +end + +deathFallen:register() diff --git a/data/scripts/creaturescripts/quests/the_first_dragon/death_first_dragon.lua b/data/scripts/creaturescripts/quests/the_first_dragon/death_first_dragon.lua new file mode 100644 index 00000000000..d8dea2a090b --- /dev/null +++ b/data/scripts/creaturescripts/quests/the_first_dragon/death_first_dragon.lua @@ -0,0 +1,34 @@ +local deathFirstDragon = CreatureEvent("FirstDragonDeath") + +local destinations = { + Position(33616, 31020, 13), + Position(33617, 31020, 13), + Position(33618, 31020, 13), + Position(33616, 31021, 13), + Position(33617, 31021, 13), + Position(33618, 31021, 13), + Position(33616, 31022, 13), + Position(33617, 31022, 13), + Position(33618, 31022, 13), + Position(33616, 31023, 13), + Position(33617, 31023, 13), + Position(33618, 31023, 13), + Position(33616, 31024, 13), + Position(33617, 31024, 13), + Position(33618, 31024, 13) +} + +function deathFirstDragon.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + local spectators = Game.getSpectators(Position(33617, 31023, 14), false, false, 14, 14, 14, 14) + for i = 1, #spectators do + local spec = spectators[i] + if spec:isPlayer() then + spec:teleportTo(Position(33617, 31020, 13)) + spec:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + spec:setStorageValue(Storage.FirstDragon.Feathers, 1) + end + end + return true +end + +deathFirstDragon:register() diff --git a/data/scripts/creaturescripts/quests/the_first_dragon/death_somewhat_beatable.lua b/data/scripts/creaturescripts/quests/the_first_dragon/death_somewhat_beatable.lua new file mode 100644 index 00000000000..80e77291281 --- /dev/null +++ b/data/scripts/creaturescripts/quests/the_first_dragon/death_somewhat_beatable.lua @@ -0,0 +1,24 @@ +local deathSomewhatBeatable = CreatureEvent("SomewhatBeatableDeath") + +function deathSomewhatBeatable.onDeath(creature, target) + local spectators = Game.getSpectators(Position(33617, 31023, 14), false, false, 14, 14, 14, 14) + for i = 1, #spectators do + local spec = spectators[i] + if spec:isPlayer() then + if creature:getName():lower() == "somewhat beatable" then + if spec:getStorageValue(Storage.FirstDragon.SomewhatBeatable) < 5 then + spec:setStorageValue(Storage.FirstDragon.SomewhatBeatable, spec:getStorageValue(Storage.FirstDragon.SomewhatBeatable) + 1) + end + end + if spec:getStorageValue(Storage.FirstDragon.SomewhatBeatable) == 5 then + for b = 1, 6 do + Game.createMonster('dragon essence', Position(math.random(33609, 33624), math.random(31017, 31028), 14), true, true) + end + spec:setStorageValue(Storage.FirstDragon.SomewhatBeatable, 0) + end + end + end + return true +end + +deathSomewhatBeatable:register() diff --git a/data/scripts/creaturescripts/quests/the_first_dragon/kill_dragon.lua b/data/scripts/creaturescripts/quests/the_first_dragon/kill_dragon.lua new file mode 100644 index 00000000000..eae77dc5437 --- /dev/null +++ b/data/scripts/creaturescripts/quests/the_first_dragon/kill_dragon.lua @@ -0,0 +1,19 @@ +local killDragon = CreatureEvent("KillDragon") + +function killDragon.onKill(player, target) + if target:isPlayer() or target:getMaster() then + return true + end + if target:getName():lower() == "dragon" then + local storage = player:getStorageValue(Storage.FirstDragon.DragonCounter) + if storage >= 0 and storage < 200 then + player:setStorageValue(Storage.FirstDragon.DragonCounter, player:getStorageValue(Storage.FirstDragon.DragonCounter) + 1) + end + end + if player:getStorageValue(Storage.FirstDragon.TazhadurTimer) >= os.time() then + return true + end + return true +end + +killDragon:register() diff --git a/data/scripts/creaturescripts/quests/the_new_frontier/shard_of_corruption_kill.lua b/data/scripts/creaturescripts/quests/the_new_frontier/shard_of_corruption_kill.lua new file mode 100644 index 00000000000..aaef3833d2d --- /dev/null +++ b/data/scripts/creaturescripts/quests/the_new_frontier/shard_of_corruption_kill.lua @@ -0,0 +1,21 @@ +local shardOfCorruptionKill = CreatureEvent("ShardOfCorruptionKill") +function shardOfCorruptionKill.onKill(creature, target) + local targetMonster = target:getMonster() + if not targetMonster then + return true + end + + if targetMonster:getName():lower() ~= 'shard of corruption' then + return true + end + + local player = creature:getPlayer() + if player:getStorageValue(Storage.TheNewFrontier.Questline) == 12 then + --Questlog, The New Frontier Quest 'Mission 04: The Mine Is Mine' + player:setStorageValue(Storage.TheNewFrontier.Mission04, 2) + player:setStorageValue(Storage.TheNewFrontier.Questline, 13) + end + return true +end + +shardOfCorruptionKill:register() diff --git a/data/scripts/creaturescripts/quests/the_new_frontier/tirecz_kill.lua b/data/scripts/creaturescripts/quests/the_new_frontier/tirecz_kill.lua new file mode 100644 index 00000000000..0ab13bb3156 --- /dev/null +++ b/data/scripts/creaturescripts/quests/the_new_frontier/tirecz_kill.lua @@ -0,0 +1,45 @@ +local exitPosition = {Position(33053, 31022, 7), Position(33049, 31017, 2)} + +local function clearArena() + local spectators, spectator = Game.getSpectators(Position(33063, 31034, 3), false, false, 10, 10, 10, 10) + for i = 1, #spectators do + spectator = spectators[i] + if spectator:isPlayer() then + spectator:teleportTo(exitPosition[2]) + exitPosition[2]:sendMagicEffect(CONST_ME_TELEPORT) + else + spectator:remove() + end + end +end + +local tireczKill = CreatureEvent("TireczKill") +function tireczKill.onKill(creature, target) + local targetMonster = target:getMonster() + if not targetMonster then + return true + end + + if targetMonster:getName():lower() ~= 'tirecz' then + return true + end + + local spectators, spectator = Game.getSpectators(Position({x = 33063, y = 31034, z = 3}), false, true, 10, 10, 10, 10) + for i = 1, #spectators do + spectator = spectators[i] + spectator:teleportTo(exitPosition[1]) + exitPosition[1]:sendMagicEffect(CONST_ME_TELEPORT) + spectator:say('You have won! As new champion take the ancient armor as reward before you leave.', TALKTYPE_MONSTER_SAY) + if spectator:getStorageValue(Storage.TheNewFrontier.Questline) == 25 then + -- Questlog: The New Frontier Quest 'Mission 09: Mortal Combat' + spectator:setStorageValue(Storage.TheNewFrontier.Mission09, 2) + spectator:setStorageValue(Storage.TheNewFrontier.Questline, 26) + end + end + + Game.setStorageValue(Storage.TheNewFrontier.Mission09, -1) + clearArena() + return true +end + +tireczKill:register() diff --git a/data/scripts/creaturescripts/quests/their_masters_voice/mage_death.lua b/data/scripts/creaturescripts/quests/their_masters_voice/mage_death.lua new file mode 100644 index 00000000000..ecae277c368 --- /dev/null +++ b/data/scripts/creaturescripts/quests/their_masters_voice/mage_death.lua @@ -0,0 +1,6 @@ +local mageDeath = CreatureEvent("MageDeath") +function mageDeath.onDeath(creature, corpse, killer, mostDamageKiller, lastHitUnjustified) + return Mage_onDeath(creature, corpse, killer, mostDamageKiller, lastHitUnjustified) +end + +mageDeath:register() diff --git a/data/scripts/creaturescripts/quests/their_masters_voice/servant_death.lua b/data/scripts/creaturescripts/quests/their_masters_voice/servant_death.lua new file mode 100644 index 00000000000..a0b7a1b01ed --- /dev/null +++ b/data/scripts/creaturescripts/quests/their_masters_voice/servant_death.lua @@ -0,0 +1,6 @@ +local servantDeath = CreatureEvent("ServantDeath") +function servantDeath.onDeath(creature, corpse, killer, mostDamageKiller, lastHitUnjustified) + return Servant_onDeath(creature, corpse, killer, mostDamageKiller, lastHitUnjustified) +end + +servantDeath:register() diff --git a/data/scripts/creaturescripts/quests/thieves_guild/nomad_kill.lua b/data/scripts/creaturescripts/quests/thieves_guild/nomad_kill.lua new file mode 100644 index 00000000000..1bf05869998 --- /dev/null +++ b/data/scripts/creaturescripts/quests/thieves_guild/nomad_kill.lua @@ -0,0 +1,20 @@ +local nomadKill = CreatureEvent("NomadKill") +function nomadKill.onKill(creature, target) + local targetMonster = target:getMonster() + if not targetMonster then + return true + end + + if targetMonster:getName():lower() ~= "nomad" then + return true + end + + local player = creature:getPlayer() + if player:getStorageValue(Storage.ThievesGuild.Mission04) == 3 then + player:setStorageValue(Storage.ThievesGuild.Mission04, 4) + end + + return true +end + +nomadKill:register() diff --git a/data/scripts/creaturescripts/quests/wrath_of_the_emperor/bosses_kill.lua b/data/scripts/creaturescripts/quests/wrath_of_the_emperor/bosses_kill.lua new file mode 100644 index 00000000000..72f27661755 --- /dev/null +++ b/data/scripts/creaturescripts/quests/wrath_of_the_emperor/bosses_kill.lua @@ -0,0 +1,39 @@ +local bosses = { + ['fury of the emperor'] = { + position = Position(33048, 31085, 15), + storage = GlobalStorage.WrathOfTheEmperor.Bosses.Fury}, + ['wrath of the emperor'] = { + position = Position(33094, 31087, 15), + storage = GlobalStorage.WrathOfTheEmperor.Bosses.Wrath}, + ['scorn of the emperor'] = { + position = Position(33095, 31110, 15), + storage = GlobalStorage.WrathOfTheEmperor.Bosses.Scorn}, + ['spite of the emperor'] = { + position = Position(33048, 31111, 15), + storage = GlobalStorage.WrathOfTheEmperor.Bosses.Spite}, +} + +local bossesKill = CreatureEvent("BossesKill") +function bossesKill.onKill(creature, target) + local targetMonster = target:getMonster() + if not targetMonster then + return true + end + + local bossConfig = bosses[targetMonster:getName():lower()] + if not bossConfig then + return true + end + + Game.setStorageValue(bossConfig.storage, 0) + local tile = Tile(bossConfig.position) + if tile then + local thing = tile:getItemById(11753) + if thing then + thing:transform(12383) + end + end + return true +end + +bossesKill:register() diff --git a/data/scripts/creaturescripts/quests/wrath_of_the_emperor/keeper_kill.lua b/data/scripts/creaturescripts/quests/wrath_of_the_emperor/keeper_kill.lua new file mode 100644 index 00000000000..d5335d12c84 --- /dev/null +++ b/data/scripts/creaturescripts/quests/wrath_of_the_emperor/keeper_kill.lua @@ -0,0 +1,14 @@ +local keeperKill = CreatureEvent("KeeperKill") +function keeperKill.onKill(creature, target) + local targetMonster = target:getMonster() + if not targetMonster then + return true + end + + if targetMonster:getName():lower() == 'the keeper' then + Game.setStorageValue(Storage.WrathoftheEmperor.Mission03, 0) + end + return true +end + +keeperKill:register() diff --git a/data/scripts/creaturescripts/quests/wrath_of_the_emperor/lizard_magistratus_kill.lua b/data/scripts/creaturescripts/quests/wrath_of_the_emperor/lizard_magistratus_kill.lua new file mode 100644 index 00000000000..f07a771c70a --- /dev/null +++ b/data/scripts/creaturescripts/quests/wrath_of_the_emperor/lizard_magistratus_kill.lua @@ -0,0 +1,21 @@ +local lizardMagistratusKill = CreatureEvent("LizardMagistratusKill") +function lizardMagistratusKill.onKill(creature, target) + local targetMonster = target:getMonster() + if not targetMonster then + return true + end + + if targetMonster:getName():lower() ~= 'lizard magistratus' then + return true + end + + local player = creature:getPlayer() + local storage = player:getStorageValue(Storage.WrathoftheEmperor.Mission06) + if storage >= 0 and storage < 4 then + player:setStorageValue(Storage.WrathoftheEmperor.Mission06, math.max(1, storage) + 1) + end + + return true +end + +lizardMagistratusKill:register() diff --git a/data/scripts/creaturescripts/quests/wrath_of_the_emperor/lizard_noble_kill.lua b/data/scripts/creaturescripts/quests/wrath_of_the_emperor/lizard_noble_kill.lua new file mode 100644 index 00000000000..4272a187322 --- /dev/null +++ b/data/scripts/creaturescripts/quests/wrath_of_the_emperor/lizard_noble_kill.lua @@ -0,0 +1,21 @@ +local lizardNobleKill = CreatureEvent("LizardNobleKill") +function lizardNobleKill.onKill(creature, target) + local targetMonster = target:getMonster() + if not targetMonster then + return true + end + + if targetMonster:getName():lower() ~= 'lizard noble' then + return true + end + + local player = creature:getPlayer() + local storage = player:getStorageValue(Storage.WrathoftheEmperor.Mission07) + if storage >= 0 and storage < 6 then + player:setStorageValue(Storage.WrathoftheEmperor.Mission07, math.max(1, storage) + 1) + end + + return true +end + +lizardNobleKill:register() diff --git a/data/scripts/creaturescripts/quests/wrath_of_the_emperor/zalamon_kill.lua b/data/scripts/creaturescripts/quests/wrath_of_the_emperor/zalamon_kill.lua new file mode 100644 index 00000000000..820ec7b1884 --- /dev/null +++ b/data/scripts/creaturescripts/quests/wrath_of_the_emperor/zalamon_kill.lua @@ -0,0 +1,49 @@ +local bossForms = { + ['snake god essence'] = { + text = 'IT\'S NOT THAT EASY MORTALS! FEEL THE POWER OF THE GOD!', + newForm = 'snake thing' + }, + ['snake thing'] = { + text = 'NOOO! NOW YOU HERETICS WILL FACE MY GODLY WRATH!', + newForm = 'lizard abomination' + }, + ['lizard abomination'] = { + text = 'YOU ... WILL ... PAY WITH ETERNITY ... OF AGONY!', + newForm = 'mutated zalamon' + } +} + +local zalamonKill = CreatureEvent("ZalamonKill") +function zalamonKill.onKill(player, target) + local targetMonster = target:getMonster() + if not targetMonster then + return true + end + + if targetMonster:getName():lower() == 'mutated zalamon' then + Game.setStorageValue(Storage.WrathoftheEmperor.Mission11, -1) + return true + end + + local name = targetMonster:getName():lower() + local bossConfig = bossForms[name] + if not bossConfig then + return true + end + + local found = false + for k, v in ipairs(Game.getSpectators(targetMonster:getPosition())) do + if v:getName():lower() == bossConfig.newForm then + found = true + break + end + end + + if not found then + Game.createMonster(bossConfig.newForm, targetMonster:getPosition(), false, true) + player:say(bossConfig.text, TALKTYPE_MONSTER_SAY) + end + return true +end + +zalamonKill:register() diff --git a/data/scripts/custom/monster_training_machine.lua b/data/scripts/custom/monster_training_machine.lua new file mode 100644 index 00000000000..bb67ef325ff --- /dev/null +++ b/data/scripts/custom/monster_training_machine.lua @@ -0,0 +1,69 @@ +local mType = Game.createMonsterType("Training Machine") +local monster = {} +monster.description = "Training Machine" +monster.experience = 0 +monster.outfit = { + lookType = 1142 +} + +monster.health = 1000000 +monster.maxHealth = monster.health +monster.race = "energy" +monster.corpse = 0 +monster.speed = 0 +monster.maxSummons = 0 + +monster.changeTarget = { + interval = 1*1000, + chance = 0 +} + +monster.flags = { + summonable = false, + attackable = true, + hostile = true, + convinceable = false, + illusionable = false, + canPushItems = true, + canPushCreatures = true, + targetDistance = 1, + staticAttackChance = 100, +} + +monster.summons = { +} + +monster.voices = { + interval = 5000, + chance = 10, + {text = "I hope you are enjoying your sparring Sir or Ma'am!", yell = false}, + {text = "Threat level rising!", yell = false}, + {text = "Engaging in hostile interaction!", yell = false}, + {text = "Rrrtttarrrttarrrtta", yell = false}, + {text = "Please feel free to hit me Sir or Ma'am!", yell = false}, + {text = "klonk klonk klonk", yell = false}, + {text = "Self-diagnosis running.", yell = false}, + {text = "Battle simulation proceeding.", yell = false}, + {text = "Repairs initiated!", yell = false} +} + +monster.loot = { +} + +monster.attacks = { + {name = "melee", attack = 130, interval = 2*1000, minDamage = -1, maxDamage = -2} +} + +monster.defenses = { + defense = 1, + armor = 1, + {name = "combat", type = COMBAT_HEALING, chance = 15, interval = 2*1000, minDamage = 10000, maxDamage = 50000, effect = CONST_ME_MAGIC_BLUE} +} + +monster.elements = { +} + +monster.immunities = { +} + +mType:register(monster) diff --git a/data/scripts/custom/movement_trainer_entrance.lua b/data/scripts/custom/movement_trainer_entrance.lua new file mode 100644 index 00000000000..796496e0e97 --- /dev/null +++ b/data/scripts/custom/movement_trainer_entrance.lua @@ -0,0 +1,76 @@ +local config = { + -- Position of the first position (line 1 column 1) + firstRoomPosition = {x = 1018, y = 1112, z = 7}, + -- X distance between each room (on the same line) + distancePositionX= 12, + -- Y distance between each room (on the same line) + distancePositionY= 12, + -- Number of columns + columns= 7, + -- Number of lines + lines= 54 +} + +local function isBusyable(position) + local player = Tile(position):getTopCreature() + if player then + if player:isPlayer() then + return false + end + end + + local tile = Tile(position) + if not tile then + return false + end + + local ground = tile:getGround() + if not ground or ground:hasProperty(CONST_PROP_BLOCKSOLID) then + return false + end + + local items = tile:getItems() + for i = 1, tile:getItemCount() do + local item = items[i] + local itemType = item:getType() + if itemType:getType() ~= ITEM_TYPE_MAGICFIELD and not itemType:isMovable() and item:hasProperty(CONST_PROP_BLOCKSOLID) then + return false + end + end + return true +end + +local function calculatingRoom(uid, position, column, line) + local player = Player(uid) + if column >= config.columns then + column = 0 + line = line < (config.lines -1) and line + 1 or false + end + + if line then + local room_pos = {x = position.x + (column * config.distancePositionX), y = position.y + (line * config.distancePositionY), z = position.z} + if isBusyable(room_pos) then + player:teleportTo(room_pos) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + calculatingRoom(uid, position, column + 1, line) + end + else + player:sendCancelMessage("Couldn't find any position for you right now.") + end +end + +local trainerEntrance = MoveEvent() +function trainerEntrance.onStepIn(creature, item, position, fromPosition) + if not creature:isPlayer() then + return true + end + + calculatingRoom(creature.uid, config.firstRoomPosition, 0, 0) + Game.createMonster("training machine", creature:getPosition(), true, false) + Game.createMonster("training machine", creature:getPosition(), true, false) + return true +end + +trainerEntrance:position({x = 1116, y = 1092, z = 7}) +trainerEntrance:register() diff --git a/data/scripts/custom/movement_trainer_exit.lua b/data/scripts/custom/movement_trainer_exit.lua new file mode 100644 index 00000000000..210a72309d8 --- /dev/null +++ b/data/scripts/custom/movement_trainer_exit.lua @@ -0,0 +1,30 @@ +local function removeTrainers(position) + local arrayPos = { + {x = position.x - 1, y = position.y + 1, z = position.z}, + {x = position.x + 1 , y = position.y + 1, z = position.z} + } + + for places = 1, #arrayPos do + local trainer = Tile(arrayPos[places]):getTopCreature() + if trainer then + if trainer:isMonster() then + trainer:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + trainer:remove() + end + end + end +end + +local trainerExit = MoveEvent() +function trainerExit.onStepIn(creature, item, position, fromPosition) + if not creature:isPlayer() then + return true + end + + creature:teleportTo(creature:getTown():getTemplePosition()) + creature:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +trainerExit:aid(40015) +trainerExit:register() diff --git a/data/scripts/globalevents/cobra_flask.lua b/data/scripts/globalevents/cobra_flask.lua new file mode 100644 index 00000000000..635eebff11e --- /dev/null +++ b/data/scripts/globalevents/cobra_flask.lua @@ -0,0 +1,14 @@ +local position = Position(33395, 32666, 5) + +local cobraEmptyFlask = GlobalEvent("Cobraflask") + +function cobraEmptyFlask.onThink(interval) +local flask = Tile(position):getItemById(36132) +if not(flask) then + Game.createItem(36132, 1, position) +end + return true +end + +cobraEmptyFlask:interval(1000*60*60*8) -- 8 hours +cobraEmptyFlask:register() diff --git a/data/scripts/globalevents/customs/rain.lua b/data/scripts/globalevents/customs/rain.lua new file mode 100644 index 00000000000..e54063851cf --- /dev/null +++ b/data/scripts/globalevents/customs/rain.lua @@ -0,0 +1,50 @@ +if configManager.getBoolean(configKeys.WEATHER_RAIN) then + local weatherStartup = GlobalEvent("WeatherStartup") + + function weatherStartup.onStartup() + local rain = math.random(100) + if rain > 95 then + Game.setStorageValue('Weather', 1) + else + Game.setStorageValue('Weather', 0) + end + return true + end + + weatherStartup:register() + + local weather = GlobalEvent("Weather") + + function weather.onThink(interval, lastExecution) + local rain = math.random(100) + if rain > 95 then + Game.setStorageValue('Weather', 1) + else + Game.setStorageValue('Weather', 0) + end + return true + end + + weather:interval(200000) -- how often to randomize rain / weather + weather:register() + + local weatherRain = GlobalEvent("WeatherRain") + + function weatherRain.onThink(interval, lastExecution) + if Game.getStorageValue('Weather') == 1 then + local players = Game.getPlayers() + if #players == 0 then + return true + end + local player + for i = 1, #players do + player = players[i] + player:sendWeatherEffect(weatherConfig.groundEffect, weatherConfig.fallEffect, weatherConfig.thunderEffect) + end + end + return true + end + + weatherRain:interval(50) -- less rain = greater value + weatherRain:register() +end diff --git a/data/scripts/globalevents/dawnport_magic_effect.lua b/data/scripts/globalevents/dawnport_magic_effect.lua new file mode 100644 index 00000000000..9c048d44d9e --- /dev/null +++ b/data/scripts/globalevents/dawnport_magic_effect.lua @@ -0,0 +1,21 @@ +local positions = { + {x = 32056, y = 31889, z = 5}, + {x = 32056, y = 31892, z = 5}, + {x = 32063, y = 31900, z = 5}, + {x = 32066, y = 31900, z = 5}, + {x = 32074, y = 31892, z = 5}, + {x = 32074, y = 31889, z = 5}, + {x = 32063, y = 31881, z = 5}, + {x = 32066, y = 31881, z = 5} +} +local dawnportMagicEffect = GlobalEvent("DawnportMagicEffect") + +function dawnportMagicEffect.onThink(interval) + for i = 1, #positions do + Position(positions[i]):sendMagicEffect(CONST_ME_THUNDER) + end + return true +end + +dawnportMagicEffect:interval(5000) +dawnportMagicEffect:register() diff --git a/data/scripts/globalevents/others/check_inbox.lua b/data/scripts/globalevents/others/check_inbox.lua new file mode 100644 index 00000000000..11daad196fa --- /dev/null +++ b/data/scripts/globalevents/others/check_inbox.lua @@ -0,0 +1,17 @@ +local checkInbox = GlobalEvent("checkinbox") +function checkInbox.onThink(interval, lastExecution) + local records = db.storeQuery('SELECT `player_id`, COUNT(`player_id`) FROM `player_inboxitems` GROUP BY `player_id` HAVING COUNT(`player_id`) > 10000') + if records ~= false then + local count = 0 + repeat + local player_id = result.getNumber(records, 'player_id') + db.asyncQuery('DELETE FROM `player_inboxitems` WHERE `player_id` = ' .. player_id) + db.asyncQuery('DELETE FROM `player` WHERE `id` = ' .. player_id) + until not result.next(records) + result.free(records) + end + return true +end + +checkInbox:interval(30000) +checkInbox:register() diff --git a/data/scripts/globalevents/others/check_mount.lua b/data/scripts/globalevents/others/check_mount.lua new file mode 100644 index 00000000000..a450784d962 --- /dev/null +++ b/data/scripts/globalevents/others/check_mount.lua @@ -0,0 +1,34 @@ +local mountIds = {22, 25, 26} + +local rentedMounts = GlobalEvent("rentedmounts") +function rentedMounts.onThink(interval) + local players = Game.getPlayers() + if #players == 0 then + return true + end + + local player, outfit + for i = 1, #players do + player = players[i] + if player:getStorageValue(Storage.RentedHorseTimer) < 1 or player:getStorageValue(Storage.RentedHorseTimer) >= os.time() then + break + end + + outfit = player:getOutfit() + if isInArray(mountIds, outfit.lookMount) then + outfit.lookMount = nil + player:setOutfit(outfit) + end + + for m = 1, #mountIds do + player:removeMount(mountIds[m]) + end + + player:setStorageValue(Storage.RentedHorseTimer, -1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Your contract with your horse expired and it returned back to the horse station.') + end + return true +end + +rentedMounts:interval(15000) +rentedMounts:register() diff --git a/data/scripts/globalevents/others/guild_war.lua b/data/scripts/globalevents/others/guild_war.lua new file mode 100644 index 00000000000..f34828b1fa7 --- /dev/null +++ b/data/scripts/globalevents/others/guild_war.lua @@ -0,0 +1,9 @@ +local guildWar = GlobalEvent("guildwar") +function guildWar.onThink(interval) + local time = os.time() + db.query("UPDATE `guild_wars` SET `status` = 4, `ended` = " .. time .. " WHERE `status` = 1 AND (`started` + 5 * 60 * 60) < " .. time) + return true +end + +guildWar:interval(100000) +guildWar:register() diff --git a/data/scripts/globalevents/others/hireling_save.lua b/data/scripts/globalevents/others/hireling_save.lua new file mode 100644 index 00000000000..98dd7d033c7 --- /dev/null +++ b/data/scripts/globalevents/others/hireling_save.lua @@ -0,0 +1,7 @@ +local hirelingSave = GlobalEvent("hirelingSave") +function hirelingSave.onShutdown() + Spdlog.info("Saving Hirelings") + SaveHirelings() + return true +end +hirelingSave:register() diff --git a/data/scripts/globalevents/others/online_record.lua b/data/scripts/globalevents/others/online_record.lua new file mode 100644 index 00000000000..d8eb60e09eb --- /dev/null +++ b/data/scripts/globalevents/others/online_record.lua @@ -0,0 +1,6 @@ +local playerrecord = GlobalEvent("playerrecord") +function playerrecord.onRecord(current, old) + addEvent(Game.broadcastMessage, 150, 'New record: ' .. current .. ' players online.', MESSAGE_EVENT_ADVANCE) + return true +end +playerrecord:register() diff --git a/data/scripts/globalevents/others/server_save.lua b/data/scripts/globalevents/others/server_save.lua new file mode 100644 index 00000000000..956d1bccea8 --- /dev/null +++ b/data/scripts/globalevents/others/server_save.lua @@ -0,0 +1,48 @@ +local function ServerSave() + if configManager.getBoolean(configKeys.SERVER_SAVE_CLEAN_MAP) then + cleanMap() + end + if configManager.getBoolean(configKeys.SERVER_SAVE_CLOSE) then + Game.setGameState(GAME_STATE_CLOSED) + end + if configManager.getBoolean(configKeys.SERVER_SAVE_SHUTDOWN) then + Game.setGameState(GAME_STATE_SHUTDOWN) + end + -- Updating daily reward next server save. + updateGlobalStorage(DailyReward.storages.lastServerSave, os.time()) + -- Reset gamestore exp boost count. + db.query('UPDATE `player_storage` SET `value` = 0 WHERE `player_storage`.`key` = 51052') +end + +local function ServerSaveWarning(time) + -- minus one minutes + local remaningTime = tonumber(time) - 60000 + if configManager.getBoolean(configKeys.SERVER_SAVE_NOTIFY_MESSAGE) then + local message = "Server is saving game in " .. (remaningTime/60000) .." minute(s). Please logout." + Webhook.send("Server save", message, WEBHOOK_COLOR_WARNING) + Game.broadcastMessage(message, MESSAGE_GAME_HIGHLIGHT) + end + -- if greater than one minute, schedule another warning + -- else the next event will be the server save + if remaningTime > 60000 then + addEvent(ServerSaveWarning, 60000, remaningTime) + else + addEvent(ServerSave, 60000) + end +end + +-- Function that is called by the global events when it reaches the time configured +-- interval is the time between the event start and the the effective save, it will send an notify message every minute +local serversave = GlobalEvent("serversave") +function serversave.onTime(interval) + local remaningTime = configManager.getNumber(configKeys.SERVER_SAVE_NOTIFY_DURATION) * 60000 + if configManager.getBoolean(configKeys.SERVER_SAVE_NOTIFY_MESSAGE) then + local message = "Server is saving game in " .. (remaningTime/60000) .." minute(s). Please logout." + Webhook.send("Server save", message, WEBHOOK_COLOR_WARNING) + Game.broadcastMessage(message, MESSAGE_GAME_HIGHLIGHT) + end + addEvent(ServerSaveWarning, 60000, remaningTime) -- Schedule next event in 1 minute(60000) + return not configManager.getBoolean(configKeys.SERVER_SAVE_SHUTDOWN) +end +serversave:time("05:55:00") +serversave:register() diff --git a/data/scripts/globalevents/others/spawns_npc_by_time.lua b/data/scripts/globalevents/others/spawns_npc_by_time.lua new file mode 100644 index 00000000000..b5759aee675 --- /dev/null +++ b/data/scripts/globalevents/others/spawns_npc_by_time.lua @@ -0,0 +1,73 @@ +-- enum LightState_t +-- LIGHT_STATE_DAY, +-- LIGHT_STATE_NIGHT, +-- LIGHT_STATE_SUNSET, +-- LIGHT_STATE_SUNRISE, +local periods = { + [LIGHT_STATE_NIGHT] = "Night", + [LIGHT_STATE_DAY] = "Day", + [LIGHT_STATE_SUNRISE] = "Sunrise", + [LIGHT_STATE_SUNSET] = "Sunset" +} + +local spawns = { + -- spawnByType day / night + [1] = { -- spawn in night + id = "ghostly_wolf", + name = "Ghostly Wolf", + spawn = LIGHT_STATE_SUNSET, + despawn = LIGHT_STATE_SUNRISE, + position = { x = 33332, y = 32052, z = 7 } + }, + [2] = { -- spawn in night + id = "talila", + name = "Talila", + spawn = LIGHT_STATE_SUNSET, + despawn = LIGHT_STATE_SUNRISE, + position = { x=33504 , y=32222 , z=7 } + }, + [3] = { -- spawn in day + id = "valindara", + name = "Valindara", + spawn = LIGHT_STATE_SUNRISE, + despawn = LIGHT_STATE_SUNSET, + position = { x=33504 , y=32222 , z=7 } + } +} + +local spawnsByTime = GlobalEvent("spawnsByTime") +function spawnsByTime.onPeriodChange(period, light) + local time = getWorldTime() + + if configManager.getBoolean(configKeys.ALL_CONSOLE_LOG) then + Spdlog.info(string.format("Starting %s Current light is %s and it's %s Tibian Time", + periods[period], light, getFormattedWorldTime(time))) + end + for index, value in pairs(spawns) do + if value.spawn == period then + -- Adding + local spawn = Game.createNpc(value.id, value.position) + if spawn then + if configManager.getBoolean(configKeys.ALL_CONSOLE_LOG) then + Spdlog.info("NPC " .. value.name .. " added") + end + spawn:setMasterPos(value.position) + spawn:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + elseif value.despawn == period then + -- Removing + local target = Npc(value.name) + if target then + if configManager.getBoolean(configKeys.ALL_CONSOLE_LOG) then + Spdlog.info("NPC " .. value.name .. " removed") + end + target:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + target:remove() + end + end + end + + return true +end + +spawnsByTime:register() diff --git a/data/scripts/globalevents/others/startup.lua b/data/scripts/globalevents/others/startup.lua new file mode 100644 index 00000000000..2eeb7179697 --- /dev/null +++ b/data/scripts/globalevents/others/startup.lua @@ -0,0 +1,132 @@ +local serverstartup = GlobalEvent("serverstartup") +function serverstartup.onStartup() + Spdlog.info("Loading map attributes") + -- Sign table + loadLuaMapSign(SignTable) + Spdlog.info("Loaded " .. (#SignTable) .. " signs in the map") + -- Book/Document table + loadLuaMapBookDocument(BookDocumentTable) + + -- Action and unique tables + -- Chest table + loadLuaMapAction(ChestAction) + loadLuaMapUnique(ChestUnique) + -- Corpse table + loadLuaMapAction(CorpseAction) + loadLuaMapUnique(CorpseUnique) + -- Doors key table + loadLuaMapAction(KeyDoorAction) + -- Doors level table + loadLuaMapAction(LevelDoorAction) + -- Doors quest table + loadLuaMapAction(QuestDoorAction) + loadLuaMapUnique(QuestDoorUnique) + -- Item table + loadLuaMapAction(ItemAction) + loadLuaMapUnique(ItemUnique) + -- Item daily reward table + loadLuaMapAction(DailyRewardAction) + -- Item unmoveable table + loadLuaMapAction(ItemUnmoveableAction) + -- Lever table + loadLuaMapAction(LeverAction) + loadLuaMapUnique(LeverUnique) + -- Teleport (magic forcefields) table + loadLuaMapAction(TeleportAction) + loadLuaMapUnique(TeleportUnique) + -- Teleport item table + loadLuaMapAction(TeleportItemAction) + loadLuaMapUnique(TeleportItemUnique) + -- Tile table + loadLuaMapAction(TileAction) + loadLuaMapUnique(TileUnique) + -- Tile pick table + loadLuaMapAction(TilePickAction) + + Spdlog.info("Loaded all actions in the map") + Spdlog.info("Loaded all uniques in the map") + + for i = 1, #startupGlobalStorages do + Game.setStorageValue(startupGlobalStorages[i], 0) + end + + local time = os.time() + db.asyncQuery('TRUNCATE TABLE `players_online`') + + -- reset Daily Reward status + db.query('UPDATE `players` SET `isreward` = '..DAILY_REWARD_NOTCOLLECTED) + + -- reset storages and allow purchase of boost in the store + db.query('UPDATE `player_storage` SET `value` = 0 WHERE `player_storage`.`key` = 51052') + + -- reset familiars message storage + db.query('DELETE FROM `player_storage` WHERE `key` = '..Storage.PetSummonEvent10) + db.query('DELETE FROM `player_storage` WHERE `key` = '..Storage.PetSummonEvent60) + + -- delete canceled and rejected guilds + db.asyncQuery('DELETE FROM `guild_wars` WHERE `status` = 2') + db.asyncQuery('DELETE FROM `guild_wars` WHERE `status` = 3') + + -- Delete guilds that are pending for 3 days + db.asyncQuery('DELETE FROM `guild_wars` WHERE `status` = 0 AND (`started` + 72 * 60 * 60) <= ' .. os.time()) + + db.asyncQuery('DELETE FROM `players` WHERE `deletion` != 0 AND `deletion` < ' .. time) + db.asyncQuery('DELETE FROM `ip_bans` WHERE `expires_at` != 0 AND `expires_at` <= ' .. time) + db.asyncQuery('DELETE FROM `market_history` WHERE `inserted` <= \z + ' .. (time - configManager.getNumber(configKeys.MARKET_OFFER_DURATION))) + + -- Move expired bans to ban history + local banResultId = db.storeQuery('SELECT * FROM `account_bans` WHERE `expires_at` != 0 AND `expires_at` <= ' .. time) + if banResultId ~= false then + repeat + local accountId = result.getNumber(banResultId, 'account_id') + db.asyncQuery('INSERT INTO `account_ban_history` (`account_id`, `reason`, `banned_at`, \z + `expired_at`, `banned_by`) VALUES (' .. accountId .. ', \z + ' .. db.escapeString(result.getString(banResultId, 'reason')) .. ', \z + ' .. result.getNumber(banResultId, 'banned_at') .. ', ' .. result.getNumber(banResultId, 'expires_at') .. ', \z + ' .. result.getNumber(banResultId, 'banned_by') .. ')') + db.asyncQuery('DELETE FROM `account_bans` WHERE `account_id` = ' .. accountId) + until not result.next(banResultId) + result.free(banResultId) + end + + -- Ferumbras Ascendant quest + for i = 1, #GlobalStorage.FerumbrasAscendant.Habitats do + local storage = GlobalStorage.FerumbrasAscendant.Habitats[i] + Game.setStorageValue(storage, 0) + end + + -- Check house auctions + local resultId = db.storeQuery('SELECT `id`, `highest_bidder`, `last_bid`, (SELECT `balance` FROM \z + `players` WHERE `players`.`id` = `highest_bidder`) AS `balance` FROM `houses` WHERE `owner` = 0 AND \z + `bid_end` != 0 AND `bid_end` < ' .. time) + if resultId ~= false then + repeat + local house = House(result.getNumber(resultId, 'id')) + if house then + local highestBidder = result.getNumber(resultId, 'highest_bidder') + local balance = result.getNumber(resultId, 'balance') + local lastBid = result.getNumber(resultId, 'last_bid') + if balance >= lastBid then + db.query('UPDATE `players` SET `balance` = ' .. (balance - lastBid) .. ' WHERE `id` = ' .. highestBidder) + house:setOwnerGuid(highestBidder) + end + db.asyncQuery('UPDATE `houses` SET `last_bid` = 0, `bid_end` = 0, `highest_bidder` = 0, \z + `bid` = 0 WHERE `id` = ' .. house:getId()) + end + until not result.next(resultId) + result.free(resultId) + end + + -- Client XP Display Mode + -- 0 = ignore exp rate /stage + -- 1 = include exp rate / stage + Game.setStorageValue(GlobalStorage.XpDisplayMode, 0) + + -- Hireling System + HirelingsInit() + + -- Load otservbr-custom map (data/world/custom/otservbr-custom.otbm) + loadCustomMap() +end +serverstartup:register() diff --git a/data/scripts/globalevents/quests/demon_oak_voices.lua b/data/scripts/globalevents/quests/demon_oak_voices.lua new file mode 100644 index 00000000000..5e4d9ff12e0 --- /dev/null +++ b/data/scripts/globalevents/quests/demon_oak_voices.lua @@ -0,0 +1,32 @@ +local questArea = { + Position(32706, 32345, 7), + Position(32725, 32357, 7) +} + +local sounds = { + 'Release me and you will be rewarded greatefully!', + 'What is this? Demon Legs lying here? Someone might have lost them!', + 'I\'m trapped, come here and free me fast!!', + 'I can bring your beloved back from the dead, just release me!', + 'What a nice shiny golden armor. Come to me and you can have it!', + 'Find a way in here and release me! Pleeeease hurry!', + 'You can have my demon set, if you help me get out of here!' +} + +local demonOakVoices = GlobalEvent("demon oak voices") +function demonOakVoices.onThink(interval, lastExecution) + local spectators, spectator = Game.getSpectators(DEMON_OAK_POSITION, false, true, 0, 15, 0, 15) + local sound = sounds[math.random(#sounds)] + for i = 1, #spectators do + spectator = spectators[i] + if isInRange(spectator:getPosition(), questArea[1], questArea[2]) then + return true + end + spectator:say(sound, TALKTYPE_MONSTER_YELL, false, 0, DEMON_OAK_POSITION) + end + return true +end + + +demonOakVoices:interval(15000) +demonOakVoices:register() diff --git a/data/scripts/globalevents/quests/druid_outfits_blooming_griffinclaw.lua b/data/scripts/globalevents/quests/druid_outfits_blooming_griffinclaw.lua new file mode 100644 index 00000000000..1fe061cf635 --- /dev/null +++ b/data/scripts/globalevents/quests/druid_outfits_blooming_griffinclaw.lua @@ -0,0 +1,33 @@ +local flowerPosition = Position(32024, 32830, 4) + +local function decayFlower() + local item = Tile(flowerPosition):getItemById(5659) + if item then + item:transform(5687) + end +end + +local function bloom() + if math.random(7) ~= 1 then + addEvent(bloom, 60 * 60 * 1000) + return + end + + local item = Tile(flowerPosition):getItemById(5687) + if item then + item:transform(5659) + flowerPosition:sendMagicEffect(CONST_ME_MAGIC_RED) + end + + local bloomHours = math.random(2, 6) + addEvent(decayFlower, bloomHours * 60 * 60 * 1000) + addEvent(bloom, bloomHours * 60 * 60 * 1000) +end + +local druidOutfit = GlobalEvent("blooming griffinclaw") +function druidOutfit.onStartup() + bloom() + return true +end + +druidOutfit:register() diff --git a/data/scripts/globalevents/quests/ferumbras_ascendant_effect_1.lua b/data/scripts/globalevents/quests/ferumbras_ascendant_effect_1.lua new file mode 100644 index 00000000000..26d8defcf0b --- /dev/null +++ b/data/scripts/globalevents/quests/ferumbras_ascendant_effect_1.lua @@ -0,0 +1,31 @@ +local effects = { + {position = Position(33472, 32383, 13), text = '', effect = 73}, + {position = Position(33469, 32382, 13), text = '', effect = 73}, + {position = Position(33359, 32431, 13), text = '', effect = 73}, + {position = Position(33356, 32433, 13), text = '', effect = 73}, + {position = Position(33614, 32671, 15), text = '', effect = 73}, + {position = Position(33619, 32672, 15), text = '', effect = 73}, + {position = Position(33672, 32748, 13), text = '', effect = 73}, + {position = Position(33678, 32751, 13), text = '', effect = 73}, + {position = Position(33205, 31502, 13), text = '', effect = 73}, + {position = Position(33203, 31506, 13), text = '', effect = 73}, + {position = Position(33426, 32844, 13), text = '', effect = 73}, + {position = Position(33427, 32849, 13), text = '', effect = 73}, + {position = Position(33434, 32841, 13), text = '', effect = 73}, + {position = Position(33453, 32811, 14), text = '', effect = 73}, + {position = Position(33461, 32810, 14), text = '', effect = 73} +} + +local ferumbrasEffect1 = GlobalEvent("effect") +function ferumbrasEffect1.onThink(interval) + for i = 1, #effects do + local settings = effects[i] + if settings.effect then + settings.position:sendMagicEffect(settings.effect) + end + end + return true +end + +ferumbrasEffect1:interval(3000) +ferumbrasEffect1:register() diff --git a/data/scripts/globalevents/quests/ferumbras_ascendant_effect_2.lua b/data/scripts/globalevents/quests/ferumbras_ascendant_effect_2.lua new file mode 100644 index 00000000000..be5c7ac05a0 --- /dev/null +++ b/data/scripts/globalevents/quests/ferumbras_ascendant_effect_2.lua @@ -0,0 +1,30 @@ +local effects = { + {position = Position(33463, 32385, 13), text = '', effect = 73}, + {position = Position(33468, 32387, 13), text = '', effect = 73}, + {position = Position(33363, 32435, 13), text = '', effect = 73}, + {position = Position(33354, 32437, 13), text = '', effect = 73}, + {position = Position(33608, 32669, 15), text = '', effect = 73}, + {position = Position(33611, 32676, 15), text = '', effect = 73}, + {position = Position(33675, 32753, 13), text = '', effect = 73}, + {position = Position(33684, 32754, 13), text = '', effect = 73}, + {position = Position(33198, 31506, 13), text = '', effect = 73}, + {position = Position(33211, 31504, 13), text = '', effect = 73}, + {position = Position(33421, 32847, 13), text = '', effect = 73}, + {position = Position(33429, 32845, 13), text = '', effect = 73}, + {position = Position(33458, 32813, 14), text = '', effect = 73}, + {position = Position(33464, 32817, 14), text = '', effect = 73}, +} + +local ferumbrasEffect2 = GlobalEvent("effcts") +function ferumbrasEffect2.onThink(interval) + for i = 1, #effects do + local settings = effects[i] + if settings.effect then + settings.position:sendMagicEffect(settings.effect) + end + end + return true +end + +ferumbrasEffect2:interval(4000) +ferumbrasEffect2:register() diff --git a/data/scripts/globalevents/quests/grimvale_feroxa.lua b/data/scripts/globalevents/quests/grimvale_feroxa.lua new file mode 100644 index 00000000000..52523a85450 --- /dev/null +++ b/data/scripts/globalevents/quests/grimvale_feroxa.lua @@ -0,0 +1,118 @@ +local config = { + position = {fromPosition = Position(33415, 31522, 11), toPosition = Position(33445, 31554, 11)} +} + +local spawnByDay = true +local spawnDay = 13 +local currentDay = os.date("%d") +local waitPosition = Position(33442, 31559, 10) +local oldpos = {} +local function teleport(player, pos) + if player:getName() ~= nil then + player:teleportTo(pos) + end +end + +local function loadMap() + Game.loadMap('data/world/feroxa/final.otbm') +end + +local function removeFeroxa(feroxa) + if not feroxa then + return true + end + feroxa = Game.createMonster('Feroxa', Position(33380, 31537, 11), true, true) + addEvent(removeFeroxa, 5 * 60 * 1000, feroxa:getId()) +end + +local function final() + local specs, spec = Game.getSpectators(Position(33430, 31537, 11), false, false, 18, 18, 18, 18) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + spec:teleportTo(Position(33419, 31539, 10)) + end + end + local teleport = Tile(Position(33430, 31537, 11)):getItemById(1387) + if teleport and teleport:isTeleport() then + teleport:transform(25417) + teleport:setDestination(Position(33419, 31539, 10)) + teleport:setActionId(12450) + end + if spec then + spec:say('You are the contenders. This is your only chance to break the Curse of The Full Moon. Make it count!', TALKTYPE_MONSTER_SAY, false, nil, Position(33419, 31539, 10)) + end + local feroxa = Game.createMonster('Feroxa', Position(33380, 31537, 11), true, true) + addEvent(removeFeroxa, 5 * 60 * 1000, feroxa:getId()) +end + +local function removeItems() + for x = config.position.fromPosition.x, config.position.toPosition.x do + for y = config.position.fromPosition.y, config.position.toPosition.y do + for z = config.position.fromPosition.z, config.position.toPosition.z do + local tile = Tile(Position(x, y, z)) + if not tile then + break + end + local items = tile:getItems() + if items then + for i = 1, #items do + items[i]:remove() + end + end + local ground = tile:getGround() + if ground then + ground:remove() + end + end + end + end +end + +local function spectators() + local specs, spec = Game.getSpectators(Position(33430, 31537, 11), false, false, 18, 18, 18, 18) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + oldpos = spec:getPosition() + end + addEvent(teleport, 1, 60 * 1000, spec, oldpos) + end + if Game.getStorageValue(GlobalStorage.Feroxa.Active) == 2 then + addEvent(removeItems, 15 * 60 * 1000) + addEvent(loadMap, 15 * 60 * 1000) + addEvent(Game.broadcastMessage, 15 * 60 * 1000, 'The full moon is completely exposed: Feroxa awaits!', MESSAGE_EVENT_ADVANCE) + addEvent(final, 30 * 60 * 1000) + Game.setStorageValue(GlobalStorage.Feroxa.Active, 3) + return true + end + Game.setStorageValue(GlobalStorage.Feroxa.Active, 2) + addEvent(spectators, 15 * 60 * 1000) + addEvent(Game.broadcastMessage, 15 * 60 * 1000, 'Half of the current full moon is visible now, there are still a lot of clouds in front of it.', MESSAGE_EVENT_ADVANCE) +end + +local grimVale = GlobalEvent("grimvale") +function grimVale.onThink(interval, lastExecution) + local chance = Game.getStorageValue(GlobalStorage.Feroxa.Chance) + if Game.getStorageValue(GlobalStorage.Feroxa.Active) >= 1 then + return true + end + if spawnByDay then + if Game.getStorageValue(GlobalStorage.Feroxa.Active) < 1 then + if spawnDay == tonumber(currentDay) then + if chance <= 5 then + addEvent(removeItems, 30 * 60 * 1000) + addEvent(Game.loadMap, 30 * 60 * 1000, 'data/world/feroxa/middle.otbm') + addEvent(spectators, 30 * 60 * 1000) + Game.setStorageValue(GlobalStorage.Feroxa.Active, 1) + Game.broadcastMessage('Grimvale drowns in werecreatures as the full moon reaches its apex and ancient evil returns.', MESSAGE_EVENT_ADVANCE) + else + Game.setStorageValue(GlobalStorage.Feroxa.Chance, math.random(1, 10)) + end + end + end + end + return true +end +grimVale:interval(60000) +grimVale:register() diff --git a/data/scripts/globalevents/quests/pits_of_inferno_bosses.lua b/data/scripts/globalevents/quests/pits_of_inferno_bosses.lua new file mode 100644 index 00000000000..da3cbf2151d --- /dev/null +++ b/data/scripts/globalevents/quests/pits_of_inferno_bosses.lua @@ -0,0 +1,25 @@ +local spawns = { + [1] = {position = Position(32876,32270,15), monster = 'Massacre'}, + [2] = {position = Position(32837,32309,15), monster = 'Dracola'}, + [3] = {position = Position(32907,32215,15), monster = 'The Imperor'}, + [4] = {position = Position(32763,32243,15), monster = 'Mr. Punish'}, + [5] = {position = Position(32802,32333,15), monster = 'Countess Sorrow'}, + [6] = {position = Position(32845,32332,15), monster = 'The Plasmother'}, + [7] = {position = Position(32785,32290,15), monster = 'The Handmaiden'} +} + +local pitsOfInfernoBosses = GlobalEvent("PitsOfInfernoBosses") +function pitsOfInfernoBosses.onThink(interval, lastExecution) + local spawn = spawns[math.random(#spawns)] + local monster = Game.createMonster(spawn.monster, spawn.position, true, true) + + if not monster then + Spdlog.error(string.format("[PitsOfInfernoBosses] - Failed to spawn %s", + rand.bossName)) + return true + end + return true +end + +pitsOfInfernoBosses:interval(46800000) +pitsOfInfernoBosses:register() diff --git a/data/scripts/globalevents/quests/secret_library_grand_canon_dominus.lua b/data/scripts/globalevents/quests/secret_library_grand_canon_dominus.lua new file mode 100644 index 00000000000..97eb51c03f3 --- /dev/null +++ b/data/scripts/globalevents/quests/secret_library_grand_canon_dominus.lua @@ -0,0 +1,35 @@ +local config = { + monsterName = 'Grand Canon Dominus', + bossPosition = Position(33384, 31282, 6), + centerPosition = Position(33384, 31282, 6), + rangeX = 50, + rangeY = 50 +} + +local function checkBoss(centerPosition, rangeX, rangeY, bossName) + local spectators, spec = Game.getSpectators(centerPosition, false, false, rangeX, rangeX, rangeY, rangeY) + for i = 1, #spectators do + spec = spectators[i] + if spec:isMonster() then + if spec:getName() == bossName then + return true + end + end + end + return false +end + +local canonDominus = GlobalEvent("canon dominus") +function canonDominus.onThink(interval, lastExecution) + if checkBoss(config.centerPosition, config.rangeX, config.rangeY, config.monsterName) then + return true + end + + local boss = + Game.createMonster(config.monsterName, config.bossPosition, true, true) + boss:setReward(true) + return true +end + +canonDominus:interval(900000) +canonDominus:register() diff --git a/data/scripts/globalevents/quests/secret_library_grand_chaplain_gaunder.lua b/data/scripts/globalevents/quests/secret_library_grand_chaplain_gaunder.lua new file mode 100644 index 00000000000..796b782bcda --- /dev/null +++ b/data/scripts/globalevents/quests/secret_library_grand_chaplain_gaunder.lua @@ -0,0 +1,36 @@ + +local config = { + monsterName = 'Grand Chaplain Gaunder', + bossPosition = Position(33370, 31327, 5), + centerPosition = Position(33370, 31327, 5), + rangeX = 50, + rangeY = 50 +} + +local function checkBoss(centerPosition, rangeX, rangeY, bossName) + local spectators, spec = Game.getSpectators(centerPosition, false, false, rangeX, rangeX, rangeY, rangeY) + for i = 1, #spectators do + spec = spectators[i] + if spec:isMonster() then + if spec:getName() == bossName then + return true + end + end + end + return false +end + +local chaplaingaunder = GlobalEvent("chaplaingaunder") +function chaplaingaunder.onThink(interval, lastExecution) + if checkBoss(config.centerPosition, config.rangeX, config.rangeY, config.monsterName) then + return true + end + + local boss = + Game.createMonster(config.monsterName, config.bossPosition, true, true) + boss:setReward(true) + return true +end + +chaplaingaunder:interval(900000) +chaplaingaunder:register() diff --git a/data/scripts/globalevents/quests/secret_library_grand_commander_soeren.lua b/data/scripts/globalevents/quests/secret_library_grand_commander_soeren.lua new file mode 100644 index 00000000000..d9f29f869f3 --- /dev/null +++ b/data/scripts/globalevents/quests/secret_library_grand_commander_soeren.lua @@ -0,0 +1,35 @@ +local config = { + monsterName = 'Grand Commander Soeren', + bossPosition = Position(33376, 31320, 2), + centerPosition = Position(33376, 31320, 2), + rangeX = 50, + rangeY = 50 +} + +local function checkBoss(centerPosition, rangeX, rangeY, bossName) + local spectators, spec = Game.getSpectators(centerPosition, false, false, rangeX, rangeX, rangeY, rangeY) + for i = 1, #spectators do + spec = spectators[i] + if spec:isMonster() then + if spec:getName() == bossName then + return true + end + end + end + return false +end + +local grandCommander = GlobalEvent("grand commander") +function grandCommander.onThink(interval, lastExecution) + if checkBoss(config.centerPosition, config.rangeX, config.rangeY, config.monsterName) then + return true + end + + local boss = + Game.createMonster(config.monsterName, config.bossPosition, true, true) + boss:setReward(true) + return true +end + +grandCommander:interval(900000) +grandCommander:register() diff --git a/data/scripts/globalevents/quests/secret_library_preceptor_lazare.lua b/data/scripts/globalevents/quests/secret_library_preceptor_lazare.lua new file mode 100644 index 00000000000..be6cf081b91 --- /dev/null +++ b/data/scripts/globalevents/quests/secret_library_preceptor_lazare.lua @@ -0,0 +1,35 @@ +local config = { + monsterName = 'Preceptor Lazare', + bossPosition = Position(33373, 31348, 3), + centerPosition = Position(33373, 31348, 3), + rangeX = 50, + rangeY = 50 +} + +local function checkBoss(centerPosition, rangeX, rangeY, bossName) + local spectators, spec = Game.getSpectators(centerPosition, false, false, rangeX, rangeX, rangeY, rangeY) + for i = 1, #spectators do + spec = spectators[i] + if spec:isMonster() then + if spec:getName() == bossName then + return true + end + end + end + return false +end + +local preceptorLazare = GlobalEvent("preceptor lazare") +function preceptorLazare.onThink(interval, lastExecution) + if checkBoss(config.centerPosition, config.rangeX, config.rangeY, config.monsterName) then + return true + end + + local boss = + Game.createMonster(config.monsterName, config.bossPosition, true, true) + boss:setReward(true) + return true +end + +preceptorLazare:interval(900000) +preceptorLazare:register() diff --git a/data/scripts/globalevents/quests/secret_library_spawn_damage.lua b/data/scripts/globalevents/quests/secret_library_spawn_damage.lua new file mode 100644 index 00000000000..3d9552b1b5a --- /dev/null +++ b/data/scripts/globalevents/quests/secret_library_spawn_damage.lua @@ -0,0 +1,84 @@ +local effects = { + {fromPosition = Position(32526, 32536, 12), toPosition = Position(32526, 32539, 12), effect = CONST_ME_HOLYDAMAGE}, + {fromPosition = Position(32533, 32536, 12), toPosition = Position(32533, 32539, 12), effect = CONST_ME_HOLYDAMAGE}, + {fromPosition = Position(32540, 32536, 12), toPosition = Position(32540, 32539, 12), effect = CONST_ME_HOLYDAMAGE}, + {fromPosition = Position(32544, 32542, 12), toPosition = Position(32546, 32542, 12), effect = CONST_ME_HOLYDAMAGE}, + {fromPosition = Position(32540, 32545, 12), toPosition = Position(32540, 32547, 12), effect = CONST_ME_HOLYDAMAGE}, + {fromPosition = Position(32533, 32545, 12), toPosition = Position(32533, 32547, 12), effect = CONST_ME_HOLYDAMAGE}, + {fromPosition = Position(32526, 32545, 12), toPosition = Position(32526, 32547, 12), effect = CONST_ME_HOLYDAMAGE}, + {fromPosition = Position(32522, 32549, 12), toPosition = Position(32524, 32549, 12), effect = CONST_ME_HOLYDAMAGE}, + {fromPosition = Position(32522, 32554, 12), toPosition = Position(32524, 32554, 12), effect = CONST_ME_HOLYDAMAGE}, + {fromPosition = Position(32522, 32559, 12), toPosition = Position(32524, 32559, 12), effect = CONST_ME_HOLYDAMAGE}, + {fromPosition = Position(32528, 32561, 12), toPosition = Position(32528, 32563, 12), effect = CONST_ME_HOLYDAMAGE}, + {fromPosition = Position(32535, 32561, 12), toPosition = Position(32535, 32563, 12), effect = CONST_ME_HOLYDAMAGE}, + {fromPosition = Position(32542, 32561, 12), toPosition = Position(32542, 32563, 12), effect = CONST_ME_HOLYDAMAGE}, + {fromPosition = Position(33369, 31342, 5), toPosition = Position(33371, 31342, 5), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(33369, 31334, 5), toPosition = Position(33371, 31334, 5), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(33363, 31330, 4), toPosition = Position(33365, 31330, 4), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(33363, 31332, 4), toPosition = Position(33365, 31332, 4), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(33369, 31318, 3), toPosition = Position(33370, 31318, 3), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(33369, 31322, 3), toPosition = Position(33370, 31322, 3), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(33369, 31324, 3), toPosition = Position(33370, 31324, 3), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(33369, 31328, 3), toPosition = Position(33370, 31328, 3), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(33369, 31330, 3), toPosition = Position(33370, 31330, 3), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(33369, 31336, 3), toPosition = Position(33370, 31336, 3), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(33369, 31339, 3), toPosition = Position(33370, 31339, 3), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(33364, 31351, 4), toPosition = Position(33364, 31352, 4), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(33366, 31351, 4), toPosition = Position(33366, 31352, 4), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(31716, 31789, 1), toPosition = Position(31716, 31791, 1), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(31709, 31789, 1), toPosition = Position(31709, 31791, 1), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(31710, 31789, 1), toPosition = Position(31710, 31791, 1), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(31703, 31789, 1), toPosition = Position(31703, 31791, 1), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(31704, 31789, 1), toPosition = Position(31704, 31791, 1), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(31697, 31789, 1), toPosition = Position(31697, 31791, 1), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(31698, 31789, 1), toPosition = Position(31698, 31791, 1), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(31691, 31789, 1), toPosition = Position(31691, 31791, 1), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(31692, 31789, 1), toPosition = Position(31692, 31791, 1), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(32514, 32610, 12), toPosition = Position(32514, 32612, 12), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(32515, 32610, 12), toPosition = Position(32515, 32612, 12), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(32520, 32610, 12), toPosition = Position(32520, 32612, 12), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(32521, 32610, 12), toPosition = Position(32521, 32612, 12), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(32526, 32610, 12), toPosition = Position(32526, 32612, 12), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(32532, 32610, 12), toPosition = Position(32532, 32612, 12), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(32533, 32610, 12), toPosition = Position(32533, 32612, 12), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(32538, 32610, 12), toPosition = Position(32538, 32612, 12), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(32539, 32610, 12), toPosition = Position(32539, 32612, 12), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(32544, 32610, 12), toPosition = Position(32544, 32612, 12), effect = CONST_ME_FIREAREA}, + {fromPosition = Position(32545, 32610, 12), toPosition = Position(32545, 32612, 12), effect = CONST_ME_FIREAREA}, +} + +local spawnDamage = GlobalEvent("spawn damage") +function spawnDamage.onThink(interval) + local jolf + for i = 1, #effects do + local settings = effects[i] + fromPosition = settings.fromPosition + toPosition = settings.toPosition + local spectators = Game.getSpectators(settings.fromPosition, false, true, 7, 7, 5, 5) + if #spectators > 0 then + if settings.effect then + for y = fromPosition.y, toPosition.y do + local newPosition = Position(fromPosition.x, y, fromPosition.z) + newPosition:sendMagicEffect(settings.effect) + + jolf = Tile(newPosition):getTopCreature() + if jolf and jolf:isPlayer() then + doTargetCombatHealth(0, jolf, COMBAT_PHYSICALDAMAGE, -500, -1000, settings.effect) + end + end + for x = fromPosition.x, toPosition.x do + local newPosition2 = Position(x, fromPosition.y, fromPosition.z) + newPosition2:sendMagicEffect(settings.effect) + jolf = Tile(newPosition2):getTopCreature() + if jolf and jolf:isPlayer() then + doTargetCombatHealth(0, jolf, COMBAT_PHYSICALDAMAGE, -10, -500, settings.effect) + end + end + end + end + end + return true +end + +spawnDamage:interval(9000) +spawnDamage:register() diff --git a/data/scripts/globalevents/quests/their_master_voice_mad_mage.lua b/data/scripts/globalevents/quests/their_master_voice_mad_mage.lua new file mode 100644 index 00000000000..aceab6932d1 --- /dev/null +++ b/data/scripts/globalevents/quests/their_master_voice_mad_mage.lua @@ -0,0 +1,25 @@ +local spawns = { + [1] = {position = Position(33339,31914,9), monster = 'Mad Mage'}, + [2] = {position = Position(33358,31914,9), monster = 'Mad Mage'}, + [3] = {position = Position(33348,31899,9), monster = 'Mad Mage'}, + [4] = {position = Position(33369,31873,9), monster = 'Mad Mage'}, + [5] = {position = Position(33360,31852,9), monster = 'Mad Mage'}, + [6] = {position = Position(33328,31860,9), monster = 'Mad Mage'}, + [7] = {position = Position(33335,31873,9), monster = 'Mad Mage'} +} + +local mad = GlobalEvent("MadMage") +function mad.onThink(interval, lastExecution) + local spawn = spawns[math.random(#spawns)] + local monster = Game.createMonster(spawn.monster, spawn.position, true, true) + monster:setReward(true) + + if not monster then + Spdlog.error("[mad.onThink] - Failed to spawn ".. rand.bossName) + return true + end + return true +end + +mad:interval(14400000) +mad:register() diff --git a/data/scripts/globalevents/spawn/gray_island_bosses.lua b/data/scripts/globalevents/spawn/gray_island_bosses.lua new file mode 100644 index 00000000000..73858a4b23a --- /dev/null +++ b/data/scripts/globalevents/spawn/gray_island_bosses.lua @@ -0,0 +1,24 @@ +local config = { + teleportId = 1387, + days = { + ["Saturday"] = {Position(33649, 31261, 11), Position(33647, 31254, 11)}, -- tanjis + ["Friday"] = {Position(33558, 31282, 11), Position(33545, 31263, 11)}, -- jaul + ["Sunday"] = {Position(33438, 31248, 11), Position(33419, 31255, 11)}, -- obujos + } +} + +local gray = GlobalEvent("gray island bosses") +function gray.onStartup() + local day = config.days[os.date("%A")] + if day then + local item = Game.createItem(config.teleportId, 1, day[1]) + if not item:isTeleport() then + item:remove() + return false + end + item:setDestination(day[2]) + end + return true +end + +gray:register() diff --git a/data/scripts/globalevents/spawn/grimvale_respawn.lua b/data/scripts/globalevents/spawn/grimvale_respawn.lua new file mode 100644 index 00000000000..aacb668a569 --- /dev/null +++ b/data/scripts/globalevents/spawn/grimvale_respawn.lua @@ -0,0 +1,57 @@ +local config = { + position = {fromPosition = Position(33330, 31670, 7), toPosition = Position(33350, 31690, 7)} +} +local spawnDay = 13 +local currentDay = os.date("%d") +local monsters = {} + +function Game.createRandom(position) + local tile = Tile(position) + if not tile or Tile(position):getItemById(3139) then + return false + end + + local ground = tile:getGround() + if not ground or ground:hasProperty(CONST_PROP_BLOCKSOLID) or tile:getTopCreature() then + return false + end + local monsterName = monsters[math.random(#monsters)] + local monster = Game.createMonster(monsterName, position) + if monster then + monster:setSpawnPosition() + monster:remove() + end + return true +end + +local grimvaleRespawn = GlobalEvent("grimvale respawn") +function grimvaleRespawn.onStartup() + local contador = 1 + if spawnDay == tonumber(currentDay) then + table.insert(monsters, 'wereboar') + table.insert(monsters, 'werebadger') + for x = config.position.fromPosition.x, config.position.toPosition.x do + for y = config.position.fromPosition.y, config.position.toPosition.y do + if math.random(1000) >= 983 then + if Game.createRandom(Position(x, y, 7)) then + end + end + end + end + else + table.insert(monsters, 'bandit') + table.insert(monsters, 'badger') + table.insert(monsters, 'blue butterfly') + table.insert(monsters, 'yellow butterfly') + for x = config.position.fromPosition.x, config.position.toPosition.x do + for y = config.position.fromPosition.y, config.position.toPosition.y do + if math.random(1000) >= 983 then + if Game.createRandom(Position(x, y, 7)) then + end + end + end + end + end + return true +end +grimvaleRespawn:register() diff --git a/data/scripts/globalevents/spawn/mawhawk.lua b/data/scripts/globalevents/spawn/mawhawk.lua new file mode 100644 index 00000000000..053fc0bdbd9 --- /dev/null +++ b/data/scripts/globalevents/spawn/mawhawk.lua @@ -0,0 +1,35 @@ +local config = { + monsterName = 'Mawhawk', + bossPosition = Position(33703, 32461, 7), + centerPosition = Position(33703, 32461, 7), + rangeX = 50, + rangeY = 50 +} + +local function checkBoss(centerPosition, rangeX, rangeY, bossName) + local spectators, spec = Game.getSpectators(centerPosition, false, false, rangeX, rangeX, rangeY, rangeY) + for i = 1, #spectators do + spec = spectators[i] + if spec:isMonster() then + if spec:getName() == bossName then + return true + end + end + end + return false +end + +local mawhawk = GlobalEvent("mawhawk") +function mawhawk.onThink(interval, lastExecution) + if checkBoss(config.centerPosition, config.rangeX, config.rangeY, config.monsterName) then + return true + end + addEvent(Game.broadcastMessage, 150, 'Beware! Mawhawk!', MESSAGE_EVENT_ADVANCE) + local boss = + Game.createMonster(config.monsterName, config.bossPosition, true, true) + boss:setReward(true) + return true +end + +mawhawk:interval(14399999) +mawhawk:register() diff --git a/data/scripts/globalevents/spawn/raids.lua b/data/scripts/globalevents/spawn/raids.lua new file mode 100644 index 00000000000..9a40592f0ef --- /dev/null +++ b/data/scripts/globalevents/spawn/raids.lua @@ -0,0 +1,71 @@ +local raids = { + -- Weekly + --Segunda-Feira + ['Monday'] = { + ['06:00'] = {raidName = 'RatsThais'}, + }, + + --Terça-Feira + ['Tuesday'] = { + ['16:00'] = {raidName = 'Midnight Panther'} + }, + + --Quarta-Feira + ['Wednesday'] = { + ['12:00'] = {raidName = 'Draptor'} + }, + + --Quinta-Feira + ['Thursday'] = { + ['19:00'] = {raidName = 'Undead Cavebear'} + }, + + --Sexta-feira + ['Friday'] = { + ['06:00'] = {raidName = 'Titanica'} + }, + + --Sábado + ['Saturday'] = { + ['20:00'] = {raidName = 'Draptor'} + }, + + --Domingo + ['Sunday'] = { + ['15:00'] = {raidName = 'Midnight Panther'}, + ['13:00'] = {raidName = 'Orc Backpack'} + }, + + -- By date (Day/Month) + ['31/10'] = { + ['16:00'] = {raidName = 'Halloween Hare'} + } +} + +local spawnRaids = GlobalEvent("spawn raids") +function spawnRaids.onThink(interval, lastExecution, thinkInterval) + local day, date = os.date('%A'), getRealDate() + + local raidDays = {} + if raids[day] then + raidDays[#raidDays + 1] = raids[day] + end + if raids[date] then + raidDays[#raidDays + 1] = raids[date] + end + if #raidDays == 0 then + return true + end + + for i = 1, #raidDays do + local settings = raidDays[i][getRealTime()] + if settings and not settings.alreadyExecuted then + Game.startRaid(settings.raidName) + settings.alreadyExecuted = true + end + end + return true +end + +spawnRaids:interval(60000) +spawnRaids:register() diff --git a/data/scripts/globalevents/spawn/rashid.lua b/data/scripts/globalevents/spawn/rashid.lua new file mode 100644 index 00000000000..733fe3ad0da --- /dev/null +++ b/data/scripts/globalevents/spawn/rashid.lua @@ -0,0 +1,51 @@ +local positionByDay = { + [1] = {position = Position(32328, 31782, 6), city = "Carlin"}, -- Sunday + [2] = {position = Position(32207, 31155, 7), city = "Svarground"}, -- Monday + [3] = {position = Position(32300, 32837, 7), city = "Liberty Bay"}, -- Tuesday + [4] = {position = Position(32577, 32753, 7), city = "Port Hope"}, -- Wednesday + [5] = {position = Position(33066, 32879, 6), city = "Ankrahmun"}, -- Thursday + [6] = {position = Position(33235, 32483, 7), city = "Darashia"}, -- Friday + [7] = {position = Position(33166, 31810, 6), city = "Edron"} -- Saturday +} + +local rashid = GlobalEvent("rashid") +function rashid.onStartup() + + local today = os.date("*t").wday + + local config = positionByDay[today] + if config then + local rashid = Game.createNpc("rashid", config.position) + rashid:setMasterPos(config.position) + rashid:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + Spdlog.info(string.format("Rashid arrived at %s", config.city)) + else + Spdlog.warn(string.format("[rashid.onStartup] - Cannot create Rashid. Day: %s", + os.date("%A"))) + end + + return true + +end +rashid:register() + +local rashidSpawnOnTime = GlobalEvent("rashidSpawnOnTime") +function rashidSpawnOnTime.onTime(interval) + + local today = os.date("*t").wday + + local rashidTarget = Npc("rashid") + + if rashidTarget then + Spdlog.info("Rashid is traveling to " .. os.date("%A") .. "s location.") + rashidTarget:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + rashidTarget:teleportTo(positionByDay[today]) + rashidTarget:setMasterPos(positionByDay[today]) + rashidTarget:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + + return true + +end +rashidSpawnOnTime:time("00:01") +rashidSpawnOnTime:register() diff --git a/data/scripts/globalevents/spawn/thawing_dragon_lord.lua b/data/scripts/globalevents/spawn/thawing_dragon_lord.lua new file mode 100644 index 00000000000..39d00e359cb --- /dev/null +++ b/data/scripts/globalevents/spawn/thawing_dragon_lord.lua @@ -0,0 +1,34 @@ +local config = { + monsterName = 'Thawing Dragon Lord', + bossPosition = Position(33361, 31316, 5), + centerPosition = Position(33361, 31316, 5), + rangeX = 50, + rangeY = 50 +} + +local function checkBoss(centerPosition, rangeX, rangeY, bossName) + local spectators, spec = Game.getSpectators(centerPosition, false, false, rangeX, rangeX, rangeY, rangeY) + for i = 1, #spectators do + spec = spectators[i] + if spec:isMonster() then + if spec:getName() == bossName then + return true + end + end + end + return false +end + +local thawingDragonLord = GlobalEvent("thawing dragon lord") +function thawingDragonLord.onThink(interval, lastExecution) + if checkBoss(config.centerPosition, config.rangeX, config.rangeY, config.monsterName) then + return true + end + + local boss = + Game.createMonster(config.monsterName, config.bossPosition, true, true) + boss:setReward(true) + return true +end +thawingDragonLord:interval(900000) +thawingDragonLord:register() diff --git a/data/scripts/globalevents/update.lua b/data/scripts/globalevents/update.lua new file mode 100644 index 00000000000..19ee9bd00a0 --- /dev/null +++ b/data/scripts/globalevents/update.lua @@ -0,0 +1,26 @@ +local fileToUpdate = "data/update.lua" +dofile(fileToUpdate) + +local update = GlobalEvent("Update") +function update.onStartup() + if updated then + db.query("UPDATE `players` SET `posx` = 0, `posy` = 0, `posz` = 0;") + local readFile = io.open(fileToUpdate,'r') + if readFile then + io.input(readFile) + local str = io.read() + io.close(readFile) + local ae = string.match(str,"updated = true") + if ae then + afterUpdate = 'updated = false' + local updateFile=io.open(fileToUpdate, "w") + io.output(updateFile) + io.write(afterUpdate) + io.close(updateFile) + Spdlog.warn("All players sent to temple. Check if 'data/update.lua' contains 'updated = false'.") + end + end + end + return true +end +update:register() diff --git a/data/scripts/globalevents/worldchanges/fury_gates.lua b/data/scripts/globalevents/worldchanges/fury_gates.lua new file mode 100644 index 00000000000..115e8671d69 --- /dev/null +++ b/data/scripts/globalevents/worldchanges/fury_gates.lua @@ -0,0 +1,178 @@ +local gates = { + -- Ab'dendriel + [1] = { + city = "Ab'dendriel", + mapName = "abdendriel", + exitPosition = Position(32680, 31720, 7) + }, + -- Ankrahmun + [2] = { + city = "Ankrahmun", + mapName = "ankrahmun", + exitPosition = Position(33269, 32841, 7) + }, + -- Carlin + [3] = { + city = "Carlin", + mapName = "carlin", + exitPosition = Position(32263, 31848, 7), + burntItems = { + {position = Position(32266, 31842, 7), itemId = 6218}, + {position = Position(32258, 31843, 7), itemId = 6219}, + {position = Position(32264, 31843, 7), itemId = 4181} + } + }, + -- Darashia + [4] = { + city = "Darashia", + mapName = "darashia", + exitPosition = Position(33304, 32371, 7), + burntItems = { + {position = Position(33300, 32366, 7), itemId = 6218} + } + }, + -- Edron + [5] = { + city = "Edron", + mapName = "edron", + exitPosition = Position(33221, 31923, 7) + }, + -- Kazordoon + [6] = { + city = "Kazordoon", + mapName = "kazordoon", + exitPosition = Position(32575, 31981, 7), + burntItems = { + {position = Position(32571, 31976, 7), itemId = 6219}, + {position = Position(32573, 31977, 7), itemId = 6219}, + {position = Position(32569, 31984, 7), itemId = 6218}, + {position = Position(32572, 31984, 7), itemId = 6218}, + {position = Position(32572, 31985, 7), itemId = 6219} + } + }, + -- Liberty Bay + [7] = { + city = "Liberty Bay", + mapName = "libertybay", + exitPosition = Position(32348, 32693, 7) + }, + -- Port Hope + [8] = { + city = "Port Hope", + mapName = "porthope", + exitPosition = Position(32530, 32712, 7), + burntItems = { + {position = Position(32532, 32719, 7), itemId = 2782} + } + }, + -- Thais + [9] = { + city = "Thais", + mapName = "thais", + exitPosition = Position(32265, 32164, 7), + burntItems = { + {position = Position(32269, 32157, 7), itemId = 6219}, + {position = Position(32274, 32165, 7), itemId = 6219} + } + }, + -- Venore + [10] = { + city = "Venore", + mapName = "venore", + exitPosition = Position(32834, 32082, 7), + burntItems = { + {position = Position(32836, 32079, 7), itemId = 6218}, + {position = Position(32835, 32080, 7), itemId = 2779}, + {position = Position(32837, 32080, 7), itemId = 6219}, + {position = Position(32828, 32081, 7), itemId = 6217}, + {position = Position(32836, 32081, 7), itemId = 2772}, + {position = Position(32837, 32081, 7), itemId = 6218}, + {position = Position(32827, 32082, 7), itemId = 6219}, + {position = Position(32836, 32082, 7), itemId = 6219}, + {position = Position(32834, 32084, 7), itemId = 2779}, + {position = Position(32830, 32086, 7), itemId = 2780}, + {position = Position(32836, 32086, 7), itemId = 2769}, + {position = Position(32836, 32087, 7), itemId = 2772}, + {position = Position(32838, 32087, 7), itemId = 2782}, + {position = Position(32835, 32089, 7), itemId = 6218}, + {position = Position(32836, 32091, 7), itemId = 2775} + } + } +} + + +-- FURY GATES MAP LOAD + +local furygates = GlobalEvent("furygates") + +function furygates.onStartup(interval) + local gateId = math.random(1, 10) + + -- Remove burnt items + if gates[gateId].burntItems then + local item + for i = 1, #gates[gateId].burntItems do + item = Tile(gates[gateId].burntItems[i].position):getItemById(gates[gateId].burntItems[i].itemId) + if item then + item:remove() + end + end + end + + Game.loadMap('data/world/furygates/' .. gates[gateId].mapName .. '.otbm') + + setGlobalStorageValue(GlobalStorage.FuryGates, gateId) + + Spdlog.info(string.format("Fury Gate will be active in %s today", + gates[gateId].city)) + + return true +end + +furygates:register() + + +-- FURY GATE TELEPORTS + +local teleport = MoveEvent() + +function teleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local gateId = Game.getStorageValue(GlobalStorage.FuryGates) + + if not gates[gateId] then + return true + end + + position:sendMagicEffect(CONST_ME_TELEPORT) + + -- Enter gates + if item.actionid == 9710 then + -- Check requirements + if not player:isPremium() or not player:isPromoted() or player:getLevel() < 60 then + player:say("Only Premium promoted players of level 60 or higher are able to enter this portal.", TALKTYPE_MONSTER_SAY, false, player, fromPosition) + player:teleportTo(fromPosition) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + local destination = Position(33290, 31786, 13) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + -- Exit gate + elseif item.actionid == 9715 then + player:teleportTo(gates[gateId].exitPosition) + gates[gateId].exitPosition:sendMagicEffect(CONST_ME_TELEPORT) + end + + return true +end + +teleport:type("stepin") +teleport:aid(9710, 9715) + +teleport:register() diff --git a/data/scripts/globalevents/worldchanges/nightmare_isle.lua b/data/scripts/globalevents/worldchanges/nightmare_isle.lua new file mode 100644 index 00000000000..b7f09372974 --- /dev/null +++ b/data/scripts/globalevents/worldchanges/nightmare_isle.lua @@ -0,0 +1,30 @@ +local config = { + -- ankrahmun - north + [1] = { + mapName = "ankrahmun-north", + displayName = "north of Ankrahmun" + }, + -- darashia - west + [2] = { + mapName = "darashia-west", + displayName = "west of Darashia" + }, + -- darashia - north + [3] = { + mapName = "darashia-north", + displayName = "north of Darashia" + } +} + +local NightmareIsle = GlobalEvent("NightmareIsle") +function NightmareIsle.onStartup(interval) + local select = config[math.random(#config)] + Game.loadMap('data/world/nightmareisle/' .. select.mapName .. '.otbm') + Spdlog.info(string.format("[WorldChanges] Nightmare Isle will be active %s today", + select.displayName)) + + setGlobalStorageValue(GlobalStorage.NightmareIsle, 1) + + return true +end +NightmareIsle:register() diff --git a/data/scripts/globalevents/worldchanges/their_masters_voice.lua b/data/scripts/globalevents/worldchanges/their_masters_voice.lua new file mode 100644 index 00000000000..ce1911bf553 --- /dev/null +++ b/data/scripts/globalevents/worldchanges/their_masters_voice.lua @@ -0,0 +1,30 @@ +local theirmastersvoice = GlobalEvent("theirmastersvoice") +function theirmastersvoice.onStartup() + local eventEnabled = true + local eventChance = 20 + local function fillFungus(fromPosition, toPosition) + for x = fromPosition.x, toPosition.x do + for y = fromPosition.y, toPosition.y do + local position = Position(x, y, 9) + local tile = Tile(position) + if tile then + local item = tile:getItemById(13590) + if item then + local slimeChance = math.random(100) + if slimeChance <= 30 then + item:transform(math.random(13585, 13589)) + position:sendMagicEffect(CONST_ME_YELLOW_RINGS) + end + end + end + end + end + end + + if eventEnabled then + if math.random(100) <= eventChance then + fillFungus({x = 33306, y = 31847}, {x = 33369, y = 31919}) + end + end +end +theirmastersvoice:register() diff --git a/data/scripts/globalevents/worldchanges/yasir.lua b/data/scripts/globalevents/worldchanges/yasir.lua new file mode 100644 index 00000000000..5145fcd7816 --- /dev/null +++ b/data/scripts/globalevents/worldchanges/yasir.lua @@ -0,0 +1,104 @@ +local config = { + -- Ankrahmun + [1] = { + removeItems = { + {position = Position(33096, 32882, 6), itemId = 4978}, + {position = Position(33096, 32883, 6), itemId = 4978}, + {position = Position(33096, 32883, 6), itemId = 4922}, + {position = Position(33096, 32884, 6), itemId = 4922}, + {position = Position(33096, 32885, 6), itemId = 4922} + }, + fromPosition = Position(33099, 32875, 7), + toPosition = Position(33106, 32893, 7), + mapName = 'ankrahmun', + yasirPosition = Position(33102, 32884, 6) + }, + -- Carlin + [2] = { + removeItems = { + {position = Position(32393, 31814, 6), itemId = 10408}, + {position = Position(32393, 31815, 6), itemId = 10408}, + {position = Position(32393, 31816, 6), itemId = 10408} + }, + fromPosition = Position(32397, 31806, 7), + toPosition = Position(32403, 31824, 7), + mapName = 'carlin', + yasirPosition = Position(32400, 31815, 6) + }, + -- Liberty Bay + [3] = { + removeItems = { + {position = Position(32309, 32896, 6), itemId = 3782}, + {position = Position(32309, 32895, 6), itemId = 3782}, + {position = Position(32309, 32894, 6), itemId = 3782}, + {position = Position(32309, 32893, 6), itemId = 3782}, + {position = Position(32309, 32896, 6), itemId = 3760}, + {position = Position(32309, 32895, 6), itemId = 3760}, + {position = Position(32309, 32894, 6), itemId = 3760}, + {position = Position(32309, 32893, 6), itemId = 3760}, + {position = Position(32309, 32892, 6), itemId = 3759} + }, + fromPosition = Position(32311, 32884, 1), + toPosition = Position(32318, 32904, 7), + mapName = 'libertybay', + yasirPosition = Position(32314, 32895, 6) + } +} + +local yasirEnabled = true +local yasirChance = 33 + +local function spawnYasir(position) + local npc = Game.createNpc('yasir', position) + if npc then + npc:setMasterPos(position) + end +end + +local yasir = GlobalEvent("yasir") +function yasir.onStartup() + if yasirEnabled then + if math.random(100) <= yasirChance then + local randTown = config[math.random(#config)] + Spdlog.info(string.format("[WorldChanges] Yasir: %s", randTown.mapName)) + iterateArea( + function(position) + local tile = Tile(position) + if tile then + local items = tile:getItems() + if items then + for i = 1, #items do + items[i]:remove() + end + end + + local ground = tile:getGround() + if ground then + ground:remove() + end + end + end, + randTown.fromPosition, + randTown.toPosition + ) + + if randTown.removeItems then + local item + for i = 1, #randTown.removeItems do + item = Tile(randTown.removeItems[i].position):getItemById(randTown.removeItems[i].itemId) + if item then + item:remove() + end + end + end + + Game.loadMap('data/world/yasir/' .. randTown.mapName .. '.otbm') + addEvent(spawnYasir, 5000, randTown.yasirPosition) + setGlobalStorageValue(GlobalStorage.Yasir, 1) + else + Spdlog.info("Yasir: not this time") + setGlobalStorageValue(GlobalStorage.Yasir, 0) + end + end +end +yasir:register() diff --git a/data/scripts/lib/create_functions.lua b/data/scripts/lib/create_functions.lua new file mode 100644 index 00000000000..845b70375c3 --- /dev/null +++ b/data/scripts/lib/create_functions.lua @@ -0,0 +1,3 @@ +createFunctions(MonsterType) -- creates get/set functions for MonsterType +createFunctions(NpcType) -- creates get/set functions for NpcType +createFunctions(Spell) -- creates get/set functions for Spell diff --git a/data/scripts/lib/defaults_move_event.lua b/data/scripts/lib/defaults_move_event.lua new file mode 100644 index 00000000000..75191a642dc --- /dev/null +++ b/data/scripts/lib/defaults_move_event.lua @@ -0,0 +1,25 @@ +-- default callbacks + +function defaultStepIn(creature, item, position, fromPosition) + return true +end + +function defaultStepOut(creature, item, position, fromPosition) + return true +end + +function defaultAddItem(moveitem, tileitem, pos) + return true +end + +function defaultRemoveItem(moveitem, tileitem, pos) + return true +end + +function defaultEquip(player, item, slot, isCheck) + return true +end + +function defaultDeEquip(player, item, slot, isCheck) + return true +end diff --git a/data/scripts/lib/helper_constructors.lua b/data/scripts/lib/helper_constructors.lua new file mode 100644 index 00000000000..0d2725e202c --- /dev/null +++ b/data/scripts/lib/helper_constructors.lua @@ -0,0 +1,53 @@ +-- HelperConstructors +local classes = {Action, CreatureEvent, Spell, TalkAction, MoveEvent, GlobalEvent, Weapon} + +for _, class in ipairs(classes) do + local MT = getmetatable(class) + local DefaultConstructor = MT.__call + + MT.__call = function(self, def, ...) + -- Backwards compatibility for default obj() constructor + if type(def) ~= "table" then + return DefaultConstructor(self, def, ...) + end + + local obj = nil + if def.init then + obj = DefaultConstructor(self, unpack(def.init)) + else + obj = DefaultConstructor(self) + end + + -- Call each method from definition table with the value as params + local hasCallback = false + + for methodName, value in pairs(def) do + -- Strictly check if a correct callback is passed + if methodName:sub(1, 2) == "on" and type(value) == "function" and rawget(class, methodName) then + hasCallback = true + end + + if methodName ~= "register" then + local method = rawget(self, methodName) + if method then + if type(value) == "table" then + method(obj, unpack(value)) + else + method(obj, value) + end + end + end + end + + -- Only register if callback has already been defined, otherwise defining afterwards will not work + if def.register then + if not hasCallback then + Spdlog.warn("[HelperConstructors] - Event not registered due to there being no callback") + else + obj:register() + end + end + + return obj + end +end diff --git a/data/scripts/lib/register_actions.lua b/data/scripts/lib/register_actions.lua new file mode 100644 index 00000000000..32cf6e44d33 --- /dev/null +++ b/data/scripts/lib/register_actions.lua @@ -0,0 +1,1012 @@ +local holeId = { + 294, 369, 370, 383, 392, 408, 409, 410, 427, 428, 430, 462, 469, 470, 482, 484, 485, 489, 924, 3135, 3136, 7933, 7938, 8170, 8286, 8285, 8284, 8281, 8280, 8279, 8277, 8276, 8567, 8585, 8596, 8595, 8249, 8250, 8251, 8252, 8253, 8254, 8255, 8256, 8592, 8972, 9606, 9625, 13190, 14461, 19519, 21536, 26020 +} + +local Itemsgrinder = { + [7759] = {item_id = 34642, effect = CONST_ME_BLUE_FIREWORKS}, -- Sapphire dust + [18416] = {item_id = 23876, effect = CONST_ME_GREENSMOKE} -- Pinch of crystal dust + } + +local holes = { + 468, 481, 483, 7932, 23712 +} + +local JUNGLE_GRASS = { + 2782, 3985, 19433 +} +local WILD_GROWTH = { + 1499, 11099, 2101, 1775, 1447, 1446, 20670 +} + +local fruits = { + 2673, 2674, 2675, 2676, 2677, 2678, 2679, 2680, 2681, 2682, 2684, 2685, 5097, 8839, 8840, 8841 +} + +local lava = { + Position(32808, 32336, 11), + Position(32809, 32336, 11), + Position(32810, 32336, 11), + Position(32808, 32334, 11), + Position(32807, 32334, 11), + Position(32807, 32335, 11), + Position(32807, 32336, 11), + Position(32807, 32337, 11), + Position(32806, 32337, 11), + Position(32805, 32337, 11), + Position(32805, 32338, 11), + Position(32805, 32339, 11), + Position(32806, 32339, 11), + Position(32806, 32338, 11), + Position(32807, 32338, 11), + Position(32808, 32338, 11), + Position(32808, 32337, 11), + Position(32809, 32337, 11), + Position(32810, 32337, 11), + Position(32811, 32337, 11), + Position(32811, 32338, 11), + Position(32806, 32338, 11), + Position(32810, 32338, 11), + Position(32810, 32339, 11), + Position(32809, 32339, 11), + Position(32809, 32338, 11), + Position(32811, 32336, 11), + Position(32811, 32335, 11), + Position(32810, 32335, 11), + Position(32809, 32335, 11), + Position(32808, 32335, 11), + Position(32809, 32334, 11), + Position(32809, 32333, 11), + Position(32810, 32333, 11), + Position(32811, 32333, 11), + Position(32806, 32338, 11), + Position(32810, 32334, 11), + Position(32811, 32334, 11), + Position(32812, 32334, 11), + Position(32813, 32334, 11), + Position(32814, 32334, 11), + Position(32812, 32333, 11), + Position(32810, 32334, 11), + Position(32812, 32335, 11), + Position(32813, 32335, 11), + Position(32814, 32335, 11), + Position(32814, 32333, 11), + Position(32813, 32333, 11) +} + +local function revertItem(position, itemId, transformId) + local item = Tile(position):getItemById(itemId) + if item then + item:transform(transformId) + end +end + +local function removeRemains(toPosition) + local item = Tile(toPosition):getItemById(2248) + if item then + item:remove() + end +end + +local function revertCask(position) + local caskItem = Tile(position):getItemById(2249) + if caskItem then + caskItem:transform(5539) + position:sendMagicEffect(CONST_ME_MAGIC_GREEN) + end +end + +local cutItems = { + [3794] = 3959, + [3795] = 3959, + [3796] = 3958, + [3797] = 3958, + [3798] = 3958, + [3799] = 3958, + [1614] = 2251, + [1615] = 2251, + [1616] = 2251, + [1619] = 2251, + [1650] = 2253, + [1651] = 2253, + [1652] = 2253, + [1653] = 2253, + [1658] = 2252, + [1659] = 2252, + [1660] = 2252, + [1661] = 2252, + [1666] = 2252, + [1667] = 2252, + [1668] = 2252, + [1669] = 2252, + [1670] = 2252, + [1671] = 2252, + [1672] = 2252, + [1673] = 2252, + [1674] = 2253, + [1676] = 2252, + [1677] = 2253, + [1714] = 2251, + [1715] = 2251, + [1716] = 2251, + [1724] = 2252, + [1725] = 2252, + [1726] = 2252, + [1727] = 2252, + [1728] = 2254, + [1729] = 2254, + [1730] = 2254, + [1731] = 2254, + [1732] = 2254, + [1733] = 2254, + [1735] = 2254, + [1775] = 2250, + [2034] = 2252, + [4996] = 2252, + [2116] = 2254, + [2116] = 2254, + [2117] = 2254, + [2118] = 2254, + [2119] = 2254, + [6123] = 2254, + [2080] = 2254, + [2081] = 2254, + [2082] = 2254, + [2083] = 2254, + [2084] = 2254, + [2085] = 2254, + [2093] = 2250, + [2094] = 2250, + [2095] = 2250, + [2098] = 2250, + [2099] = 2250, + [2101] = 2250, + [2106] = 2250, + [2105] = 2250, + [2562] = 2257, + [2581] = 2258, + [2582] = 2258, + [2582] = 2258, + [2583] = 2258, + [3805] = 6267, + [3806] = 6267, + [3807] = 2252, + [3808] = 2252, + [3809] = 2252, + [3810] = 2252, + [3811] = 2255, + [3812] = 6267, + [3813] = 2252, + [3814] = 2252, + [3815] = 2252, + [3816] = 2252, + [3817] = 2252, + [3818] = 2252, + [3819] = 2252, + [3820] = 2252, + [3821] = 2255, + [3832] = 2255, + [3833] = 2255, + [3834] = 2255, + [3835] = 2255, + [6356] = 2257, + [6357] = 2257, + [6358] = 2257, + [6359] = 2257, + [6360] = 2257, + [6361] = 2257, + [6363] = 2257, + [6368] = 2250, + [6369] = 2250, + [6370] = 2250, + [6371] = 2250, + [1738] = 2250, + [1739] = 2251, + [1740] = 2250, + [1741] = 2255, + [1747] = 2250, + [1748] = 2250, + [1749] = 1750, + [1750] = 2254, + [1751] = 2254, + [1752] = 2254, + [1753] = 2254, + [1770] = 2251, + [1774] = 2250, + [6085] = 2254, + [7481] = 2251, + [7482] = 2251, + [7483] = 2251, + [7484] = 2250, + [7706] = 2251, + [7707] = 2251, + [1738] = 2250, + [1739] = 2251, + [6109] = 2254, + [6110] = 2254, + [6111] = 2254, + [6112] = 2254, + [7538] = 7544, + [7539] = 7545, + [7585] = 7586, + [29087] = 0, + [29088] = 0 +} + +function onDestroyItem(player, item, fromPosition, target, toPosition, isHotkey) + if not target or target == nil or type(target) ~= "userdata" or not target:isItem() then + return false + end + + if target:hasAttribute(ITEM_ATTRIBUTE_UNIQUEID) or target:hasAttribute(ITEM_ATTRIBUTE_ACTIONID) then + return false + end + + if toPosition.x == CONTAINER_POSITION then + player:sendCancelMessage(Game.getReturnMessage(RETURNVALUE_NOTPOSSIBLE)) + return true + end + + local destroyId = cutItems[target.itemid] or ItemType(target.itemid):getDestroyId() + if destroyId == 0 then + if target.itemid ~= 29087 and target.itemid ~= 29088 then + return false + end + end + + local watt = ItemType(item.itemid):getAttack() + if math.random(1, 80) <= (watt and watt > 10 and watt or 10) then + -- Against The Spider Cult (Spider Eggs) + if target.itemid == 7585 then + local eggStorage = player:getStorageValue(Storage.TibiaTales.AgainstTheSpiderCult) + if eggStorage >= 1 and eggStorage < 5 then + player:setStorageValue(Storage.TibiaTales.AgainstTheSpiderCult, math.max(1, eggStorage) + 1) + end + + Game.createMonster("Giant Spider", Position(33181, 31869, 12)) + end + + -- Move items outside the container + if target:isContainer() then + for i = target:getSize() - 1, 0, -1 do + local containerItem = target:getItem(i) + if containerItem then + containerItem:moveTo(toPosition) + end + end + end + + -- Being better than cipsoft + if target:getFluidType() ~= 0 then + local fluid = Game.createItem(2016, target:getFluidType(), toPosition) + if fluid ~= nil then + fluid:decay() + end + end + + target:remove(1) + + local itemDestroy = Game.createItem(destroyId, 1, toPosition) + if itemDestroy ~= nil then + itemDestroy:decay() + end + + -- Energy barrier na threatned dreams quest (feyrist) + if target.itemid == 29087 or target.itemid == 29088 then + addEvent(Game.createItem, math.random(13000, 17000), target.itemid, 1, toPosition) + end + end + + toPosition:sendMagicEffect(CONST_ME_POFF) + return true +end + +function onUseRope(player, item, fromPosition, target, toPosition, isHotkey) + if toPosition.x == CONTAINER_POSITION then + return false + end + + local tile = Tile(toPosition) + if tile:isRopeSpot() then + player:teleportTo(toPosition:moveUpstairs()) + if target.itemid == 8592 then + if player:getStorageValue(Storage.RookgaardTutorialIsland.tutorialHintsStorage) < 22 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + "You have successfully used your rope to climb out of the hole. Congratulations! Now continue to the east.") + end + end + elseif table.contains(holeId, target.itemid) then + toPosition.z = toPosition.z + 1 + tile = Tile(toPosition) + if tile then + local thing = tile:getTopVisibleThing() + if thing:isItem() and thing:getType():isMovable() then + return thing:moveTo(toPosition:moveUpstairs()) + elseif thing:isCreature() and thing:isPlayer() then + return thing:teleportTo(toPosition:moveUpstairs()) + end + end + + player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + else + return false + end + return true +end + +function onUseShovel(player, item, fromPosition, target, toPosition, isHotkey) + --Dawnport quest (Morris amulet task) + local sandPosition = Position(32099, 31933, 7) + if (toPosition == sandPosition) then + local sandTile = Tile(sandPosition) + local amuletId = sandTile:getItemById(22679) + if amuletId then + if player:getStorageValue(Storage.Quest.Dawnport.TheLostAmulet) == 1 then + local rand = math.random(100) + if rand <= 10 then + player:addItem(23750, 1) + player:setStorageValue(Storage.Quest.Dawnport.TheLostAmulet, 2) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found an ancient amulet. Strange engravings cover it. Maybe Morris can make them out.") + elseif rand <= 80 then + player:addItem(23766, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You dig up sand and sea shells.") + elseif rand > 95 then + player:addItem(3976, math.random(1, 10)) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You dig up some worms. But you are confident that you'll find the amulet here, somewhere.") + end + toPosition:sendMagicEffect(CONST_ME_POFF) + else + return false + end + end + return true + end + + if table.contains(holes, target.itemid) then + target:transform(target.itemid + 1) + target:decay() + elseif table.contains({231, 9059}, target.itemid) then + local rand = math.random(100) + if target.actionid == 100 and rand <= 20 then + target:transform(489) + target:decay() + elseif rand == 1 then + Game.createItem(2159, 1, toPosition) + elseif rand > 95 then + Game.createMonster("Scarab", toPosition) + end + toPosition:sendMagicEffect(CONST_ME_POFF) + -- Rookgaard tutorial island + elseif target.itemid == 351 and target.actionid == 8024 then + player:addItem(12297, 1) + player:say("You dig out a handful of earth from this sacred place.", TALKTYPE_MONSTER_SAY) + elseif target.itemid == 8579 and player:getStorageValue(Storage.RookgaardTutorialIsland.tutorialHintsStorage) < 20 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + "You dug a hole! Walk onto it as long as it is open to jump down into the forest cave." + ) + player:setStorageValue(Storage.RookgaardTutorialIsland.tutorialHintsStorage, 19) + Position(32070, 32266, 7):sendMagicEffect(CONST_ME_TUTORIALARROW) + Position(32070, 32266, 7):sendMagicEffect(CONST_ME_TUTORIALSQUARE) + target:transform(469) + addEvent(revertItem, 30 * 1000, toPosition, 469, 8579) + elseif target.actionid == 4654 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission49) == 1 + and player:getStorageValue(Storage.GravediggerOfDrefia.Mission50) < 1 then + -- Gravedigger Quest + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You found a piece of the scroll. You pocket it quickly.") + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:addItem(21250, 1) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission50, 1) + elseif target.actionid == 4668 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission69) == 1 + and player:getStorageValue(Storage.GravediggerOfDrefia.Mission70) < 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "A torn scroll piece emerges. Probably gnawed off by rats.") + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:addItem(21250, 1) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission70, 1) + elseif target.actionid == 50118 then + local wagonItem = Tile(Position(32717, 31492, 11)):getItemById(7131) + if wagonItem then + Game.createItem(8749, 1, wagonItem:getPosition()) + toPosition:sendMagicEffect(CONST_ME_POFF) + end + elseif target.itemid == 8749 then + local coalItem = Tile(Position(32699, 31492, 11)):getItemById(8749) + if coalItem then + coalItem:remove(1) + toPosition:sendMagicEffect(CONST_ME_POFF) + + local crucibleItem = Tile(Position(32699, 31494, 11)):getItemById(8642) + if crucibleItem then + crucibleItem:setActionId(50119) + end + end + elseif table.contains({9632, 20230, 17672, 18586, 18580}, target.itemid) then + if player:getStorageValue(Storage.SwampDiggingTimeout) >= os.time() then + toPosition:sendMagicEffect(CONST_ME_POFF) + return false + end + + local config = { + {from = 1, to = 39, itemId = 2817}, + {from = 40, to = 79, itemId = 2145}, + {from = 80, to = 100, itemId = 20138} + } + + local chance = math.random(100) + for i = 1, #config do + local randItem = config[i] + if chance >= randItem.from and chance <= randItem.to then + player:addItem(randItem.itemId, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You dug up a " .. ItemType(randItem.itemId):getName() .. ".") + player:setStorageValue(Storage.SwampDiggingTimeout, os.time() + 604800) + toPosition:sendMagicEffect(CONST_ME_GREEN_RINGS) + break + end + end + elseif target.itemid == 103 and target.actionid == 4205 then + if player:getStorageValue(Storage.TibiaTales.IntoTheBonePit) ~= 1 then + return false + end + + local remains = Game.createItem(2248, 1, toPosition) + if remains then + remains:setActionId(4206) + end + toPosition:sendMagicEffect(CONST_ME_HITAREA) + addEvent(removeRemains, 60000, toPosition) + elseif target.itemid == 22674 then + if not player:removeItem(5091, 1) then + return false + end + + target:transform(5731) + target:decay() + toPosition:sendMagicEffect(CONST_ME_POFF) + else + return false + end + return true +end + +function onUsePick(player, item, fromPosition, target, toPosition, isHotkey) + local stonePos = Position(32648, 32134, 10) + if (toPosition == stonePos) then + local tile = Tile(stonePos) + local stone = tile:getItemById(1285) + if stone then + stone:remove(1) + toPosition:sendMagicEffect(CONST_ME_POFF) + addEvent(function() + Game.createItem(1285, 1, stonePos) + end, 20000) + return true + end + end + + -- The Rookie Guard Quest - Mission 09: Rock 'n Troll + -- Path: data\scripts\actions\quests\the_rookie_guard\mission09_rock_troll.lua + -- Damage tunnel pillars + if player:getStorageValue(Storage.TheRookieGuard.Mission09) ~= -1 and target.itemid == 3511 then + return onUsePickAtTunnelPillar(player, item, fromPosition, target, toPosition) + end + + --Dawnport some cracks down + local crackPosition = Position(32099, 31930, 7) + if (toPosition == crackPosition) then + local tile = Tile(crackPosition) + local crack = tile:getItemById(6299) + if crack then + player:teleportTo({x = 32099, y = 31930, z = 8}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + end + + if table.contains({354, 355}, target.itemid) and target.actionid == 101 then + target:transform(392) + target:decay() + toPosition:sendMagicEffect(CONST_ME_POFF) + elseif target.itemid == 11227 then + -- shiny stone refining + local chance = math.random(1, 100) + if chance == 1 then + player:addItem(2160, 1) -- 1% chance of getting crystal coin + elseif chance <= 6 then + player:addItem(2148, 1) -- 5% chance of getting gold coin + elseif chance <= 51 then + player:addItem(2152, 1) -- 45% chance of getting platinum coin + else + player:addItem(2145, 1) -- 49% chance of getting small diamond + end + target:getPosition():sendMagicEffect(CONST_ME_BLOCKHIT) + target:remove(1) + elseif target.itemid == 11227 then + target:remove(1) + toPosition:sendMagicEffect(CONST_ME_POFF) + player:addItem(2152, 10) + elseif target.itemid == 7200 then + target:transform(7236) + target:decay() + toPosition:sendMagicEffect(CONST_ME_HITAREA) + elseif target.itemid == 468 then + target:transform(469) + target:decay() + toPosition:sendMagicEffect(CONST_ME_HITAREA) + elseif target.itemid == 6299 and target.actionid > 0 then + target:transform(482) + target:decay() + toPosition:sendMagicEffect(CONST_ME_HITAREA) + elseif target.itemid == 23712 then + target:transform(23713) + target:decay() + toPosition:sendMagicEffect(CONST_ME_HITAREA) + elseif target.itemid == 481 then + target:transform(482) + target:decay() + toPosition:sendMagicEffect(CONST_ME_HITAREA) + elseif target.itemid == 483 then + target:transform(484) + target:decay() + toPosition:sendMagicEffect(CONST_ME_HITAREA) + elseif target.itemid == 7932 then + target:transform(7933) + target:decay() + toPosition:sendMagicEffect(CONST_ME_HITAREA) + elseif target.itemid == 8634 then + -- Sea of light quest + if player:getStorageValue(Storage.SeaOfLight.Questline) ~= 4 then + return false + end + + if toPosition == Position(33031, 31758, 8) then + if math.random(100) <= 30 then + if player:getStorageValue(Storage.SeaOfLight.Questline) == 4 then + player:addItem(10614, 1) + player:setStorageValue(Storage.SeaOfLight.Questline, player:getStorageValue(Storage.SeaOfLight.Questline) + 1) + player:say("*crush*", TALKTYPE_MONSTER_SAY) + end + else + player:getPosition():sendMagicEffect(CONST_ME_POFF) + end + end + elseif target.itemid == 24731 then + -- Grimvale quest + if player:getStorageValue(Storage.Grimvale.SilverVein) < os.time() then + local chance = math.random(1, 10) + if chance >= 5 then + player:sendTextMessage( + MESSAGE_EVENT_ADVANCE, + "Even after a thorough and frustrating \z + search you could not find enough liquified silver in this vein to fill a flask." + ) + elseif chance <= 4 then + player:sendTextMessage( + MESSAGE_EVENT_ADVANCE, + "Carefully you gather some of the liquified \z + silver from this vein in a small flask. You now feel strangely affected to the moon." + ) + player:addItem(24714) + target:transform(4475) + addEvent(revertItem, 10 * 60 * 1000, toPosition, 4475, 24731) + end + player:setStorageValue(Storage.Grimvale.SilverVein, os.time() + 2 * 60) + else + player:sendTextMessage( + MESSAGE_EVENT_ADVANCE,"You are still exhausted from earlier attempts. \z + Getting liquid silver out of the mountain needs concentration and a steady hand.") + end + elseif target.itemid == 3621 and target.actionid == 12026 then + --The Ice Islands Quest, Nibelor 1: Breaking the Ice + local missionProgress = player:getStorageValue(Storage.TheIceIslands.Mission02) + local pickAmount = player:getStorageValue(Storage.TheIceIslands.PickAmount) + if missionProgress < 1 or pickAmount >= 3 or player:getStorageValue(Storage.TheIceIslands.Questline) ~= 3 then + return false + end + + player:setStorageValue(Storage.TheIceIslands.PickAmount, math.max(0, pickAmount) + 1) + -- Questlog The Ice Islands Quest, Nibelor 1: Breaking the Ice + player:setStorageValue(Storage.TheIceIslands.Mission02, missionProgress + 1) + + if pickAmount >= 2 then + player:setStorageValue(Storage.TheIceIslands.Questline, 4) + -- Questlog The Ice Islands Quest, Nibelor 1: Breaking the Ice + player:setStorageValue(Storage.TheIceIslands.Mission02, 4) + end + + local crackItem = Tile(toPosition):getItemById(7185) + if crackItem then + crackItem:transform(7186) + addEvent(revertItem, 60 * 1000, toPosition, 7186, 7185) + end + + local chakoyas = {"chakoya toolshaper", "chakoya tribewarden", "chakoya windcaller"} + Game.createMonster(chakoyas[math.random(#chakoyas)], toPosition) + toPosition:sendMagicEffect(CONST_ME_TELEPORT) + elseif target.itemid == 1304 then + -- The Pits of Inferno Quest + if toPosition == Position(32808, 32334, 11) then + for i = 1, #lava do + Game.createItem(5815, 1, lava[i]) + end + target:transform(2256) + toPosition:sendMagicEffect(CONST_ME_SMOKE) + elseif target.actionid == 50058 then + -- naginata quest + local stoneStorage = Game.getStorageValue(GlobalStorage.NaginataStone) + if stoneStorage ~= 5 then + Game.setStorageValue(GlobalStorage.NaginataStone, math.max(0, stoneStorage) + 1) + elseif stoneStorage == 5 then + target:remove(1) + Game.setStorageValue(GlobalStorage.NaginataStone) + end + toPosition:sendMagicEffect(CONST_ME_POFF) + doTargetCombatHealth(0, player, COMBAT_PHYSICALDAMAGE, -31, -39, CONST_ME_NONE) + end + elseif target.itemid == 9025 and target.actionid == 101 then + -- The Banshee Quest + target:transform(392) + target:decay() + toPosition:sendMagicEffect(CONST_ME_POFF) + elseif target.actionid == 50090 then + -- The Hidden City of Beregar Quest + if player:getStorageValue(Storage.hiddenCityOfBeregar.WayToBeregar) == 1 then + player:teleportTo(Position(32566, 31338, 10)) + end + elseif target.actionid == 50114 then + if Tile(Position(32617, 31513, 9)):getItemById(1027) and Tile(Position(32617, 31514, 9)):getItemById(1205) then + local rubbleItem = Tile(Position(32619, 31514, 9)):getItemById(5709) + if rubbleItem then + rubbleItem:remove(1) + end + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + "You can't remove this pile since it's currently holding up the tunnel.") + end + elseif target.actionid == 50127 then + -- Pythius The Rotten (Firewalker Boots) + if player:getStorageValue(Storage.QuestChests.FirewalkerBoots) == 1 then + return false + end + target:remove(1) + + local stoneItem = Tile(toPosition):getItemById(1304) + if stoneItem then + stoneItem:remove(1) + end + + iterateArea(function(position) + local groundItem = Tile(position):getGround() + if groundItem and groundItem.itemid == 598 then + groundItem:transform(5815) + end + end, Position(32550, 31373, 15), Position(32551, 31379, 15)) + + iterateArea(function(position) + position:sendMagicEffect(CONST_ME_POFF) + end, Position(32551, 31374, 15), Position(32551, 31379, 15) ) + + local portal = Game.createItem(1387, 1, Position(32551, 31376, 15)) + if portal then + portal:setActionId(50126) + end + elseif target.actionid == 50091 then + -- The Asure + player:teleportTo(Position(32960, 32676, 4)) + elseif target.itemid == 12296 then + -- Wrath of the emperor quest + player:addItem(12295, 1) + player:say("The cracked part of the table lets you cut out a large chunk of wood with your pick.", + TALKTYPE_MONSTER_SAY ) + elseif target.itemid == 22671 then + target:transform(392) + target:decay() + elseif target.itemid == 3706 then + -- Jack to the Future Quest + if player:getStorageValue(Storage.TibiaTales.JackFutureQuest.Statue) ~= 1 then + return false + end + + if toPosition == Position(33277, 31754, 7) then + if player:getStorageValue(Storage.TibiaTales.JackFutureQuest.Statue) == 1 then + target:transform(3701) + toPosition:sendMagicEffect(CONST_ME_POFF) + player:addItem(11343, 1) + player:setStorageValue(Storage.TibiaTales.JackFutureQuest.Statue, 2) + player:setStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine, player:getStorageValue(Storage.TibiaTales.JackFutureQuest.QuestLine) + 1) + addEvent(revertItem, 2 * 60 * 1000, {x = 33277, y = 31754, z = 7}, 3701, 3706) + end + end + else + return false + end + if (target ~= nil) and target:isItem() and (target:getId() == 22469) then + --Lower Roshamuul + if math.random(100) > 50 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Crushing the stone produces some fine gravel.") + target:transform(22467) + target:decay() + else + Game.createMonster("Frazzlemaw", toPosition) + player:sendTextMessage( + MESSAGE_EVENT_ADVANCE, + "Crushing the stone yields nothing but slightly finer, yet still unusable rubber." + ) + target:transform(22468) + target:decay() + end + return true + end + return true +end + +function onUseMachete(player, item, fromPosition, target, toPosition, isHotkey) + if table.contains(JUNGLE_GRASS, target.itemid) then + target:transform(target.itemid == 19433 and 19431 or target.itemid - 1) + target:decay() + return true + end + + if table.contains(WILD_GROWTH, target.itemid) then + toPosition:sendMagicEffect(CONST_ME_POFF) + target:remove() + return true + end + + return onDestroyItem(player, item, fromPosition, target, toPosition, isHotkey) +end + +function onUseCrowbar(player, item, fromPosition, target, toPosition, isHotkey) + if not table.contains({2416, 10515}, item.itemid) then + return false + end + + if target.uid == 3071 then + -- In service of yalahar quest + if player:getStorageValue(Storage.InServiceofYalahar.SewerPipe01) < 1 then + doSetMonsterOutfit(player, "skeleton", 3 * 1000) + fromPosition:sendMagicEffect(CONST_ME_ENERGYHIT) + player:setStorageValue(Storage.InServiceofYalahar.SewerPipe01, 1) + -- StorageValue for Questlog "Mission 01: Something Rotten" + player:setStorageValue(Storage.InServiceofYalahar.Mission01, + player:getStorageValue(Storage.InServiceofYalahar.Mission01) + 1) + local position = player:getPosition() + for x = -1, 1 do + for y = -1, 1 do + position = position + Position(x, y, 0) + position:sendMagicEffect(CONST_ME_YELLOWENERGY) + end + end + end + elseif target.uid == 3072 then + if player:getStorageValue(Storage.InServiceofYalahar.SewerPipe02) < 1 then + player:setStorageValue(Storage.InServiceofYalahar.SewerPipe02, 1) + -- StorageValue for Questlog "Mission 01: Something Rotten" + player:setStorageValue(Storage.InServiceofYalahar.Mission01, + player:getStorageValue(Storage.InServiceofYalahar.Mission01) + 1) + local position = player:getPosition() + for x = -1, 1 do + for y = -1, 1 do + if math.random(2) == 2 then + position = position + Position(x, y, 0) + Game.createMonster("rat", position) + position:sendMagicEffect(CONST_ME_TELEPORT) + end + end + end + end + elseif target.uid == 3073 then + if player:getStorageValue(Storage.InServiceofYalahar.SewerPipe03) < 1 then + player:say("You have used the crowbar on a grate.", TALKTYPE_MONSTER_SAY) + player:setStorageValue(Storage.InServiceofYalahar.SewerPipe03, 1) + -- StorageValue for Questlog "Mission 01: Something Rotten" + player:setStorageValue(Storage.InServiceofYalahar.Mission01, + player:getStorageValue(Storage.InServiceofYalahar.Mission01) + 1) + end + elseif target.uid == 3074 then + if player:getStorageValue(Storage.InServiceofYalahar.SewerPipe04) < 1 then + doSetMonsterOutfit(player, "bog raider", 5 * 1000) + player:say("You have used the crowbar on a knot.", TALKTYPE_MONSTER_SAY) + player:setStorageValue(Storage.InServiceofYalahar.SewerPipe04, 1) + -- StorageValue for Questlog "Mission 01: Something Rotten" + player:setStorageValue(Storage.InServiceofYalahar.Mission01, + player:getStorageValue(Storage.InServiceofYalahar.Mission01) + 1) + end + elseif target.actionid == 100 then + if target.itemid == 2593 then + -- Postman quest + if player:getStorageValue(Storage.Postman.Mission02) == 1 then + player:setStorageValue(Storage.Postman.Mission02, 2) + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + end + elseif target.itemid == 5539 then + -- The ape city - mission 7 + local apeCityStorage = player:getStorageValue(Storage.TheApeCity.Casks) + if apeCityStorage < 3 then + player:setStorageValue(Storage.TheApeCity.Casks, math.max(0, apeCityStorage) + 1) + target:transform(2249) + toPosition:sendMagicEffect(CONST_ME_EXPLOSIONAREA) + addEvent(revertCask, 3 * 60 * 1000, toPosition) + end + end + elseif target.actionid == 12566 and player:getStorageValue(Storage.secretService.TBIMission06) == 1 then + -- Secret service quest + local yellPosition = Position(32204, 31157, 8) + -- Amazon lookType + if player:getOutfit().lookType == 137 then + player:setStorageValue(Storage.secretService.TBIMission06, 2) + Game.createMonster("barbarian skullhunter", yellPosition) + player:say("Nooooo! What have you done??", TALKTYPE_MONSTER_SAY, false, 0, yellPosition) + yellPosition.y = yellPosition.y - 1 + Game.createMonster("barbarian skullhunter", yellPosition) + end + else + return false + end + return true +end + +function onUseSpoon(player, item, fromPosition, target, toPosition, isHotkey) + if target.itemid == 388 then + --The ice islands quest + if player:getStorageValue(Storage.TheIceIslands.Questline) >= 21 then + if player:getStorageValue(Storage.TheIceIslands.SulphurLava) < 1 then + -- Fine sulphur + player:addItem(7247, 1) + player:setStorageValue(Storage.TheIceIslands.SulphurLava, 1) + toPosition:sendMagicEffect(CONST_ME_MAGIC_RED) + player:say("You retrive a fine sulphur from a lava hole.", TALKTYPE_MONSTER_SAY) + end + end + elseif target.itemid == 4184 then + --The ice islands quest + if player:getStorageValue(Storage.TheIceIslands.Questline) >= 21 then + if player:getStorageValue(Storage.TheIceIslands.SporesMushroom) < 1 then + player:addItem(7251, 1) + player:setStorageValue(Storage.TheIceIslands.SporesMushroom, 1) + toPosition:sendMagicEffect(CONST_ME_MAGIC_RED) + player:say("You retrive spores from a mushroom.", TALKTYPE_MONSTER_SAY) + end + end + elseif target.itemid == 8573 or target.itemid == 388 then + -- What a foolish quest - mission 8 (sulphur) + if player:getStorageValue(Storage.WhatAFoolishQuest.Questline) ~= 21 + or player:getStorageValue(Storage.WhatAFoolishQuest.InflammableSulphur) == 1 then + return false + end + + player:setStorageValue(Storage.WhatAFoolishQuest.InflammableSulphur, 1) + -- Easily inflammable sulphur + player:addItem(8204, 1) + toPosition:sendMagicEffect(CONST_ME_YELLOW_RINGS) + else + return false + end + return true +end + +function onUseScythe(player, item, fromPosition, target, toPosition, isHotkey) + if not table.contains({2550, 10513}, item.itemid) then + return false + end + + if target.itemid == 5465 then + target:transform(5464) + target:decay() + Game.createItem(5467, 1, toPosition) + elseif target.itemid == 2739 then + target:transform(2737) + target:decay() + Game.createItem(2694, 1, toPosition) + -- The secret library + elseif toPosition == Position(32177, 31925, 7) then + player:teleportTo({x = 32515, y = 32535, z = 12}) + else + return false + end + return onDestroyItem(player, item, fromPosition, target, toPosition, isHotkey) +end + +function onUseKitchenKnife(player, item, fromPosition, target, toPosition, isHotkey) + if not table.contains({2566, 10511, 10515}, item.itemid) then + return false + end + + -- The ice islands quest + if target.itemid == 7261 then + if player:getStorageValue(Storage.TheIceIslands.Questline) >= 21 then + if player:getStorageValue(Storage.TheIceIslands.FrostbiteHerb) < 1 then + player:addItem(7248, 1) + player:setStorageValue(Storage.TheIceIslands.FrostbiteHerb, 1) + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:say("You cut a leaf from a frostbite herb.", TALKTYPE_MONSTER_SAY) + end + end + elseif target.itemid == 2733 then + if player:getStorageValue(Storage.TheIceIslands.Questline) >= 21 then + if player:getStorageValue(Storage.TheIceIslands.FlowerCactus) < 1 then + player:addItem(7245, 1) + player:setStorageValue(Storage.TheIceIslands.FlowerCactus, 1) + target:transform(2723) + addEvent(revertItem, 60 * 1000, toPosition, 2723, 2733) + toPosition:sendMagicEffect(CONST_ME_MAGIC_GREEN) + player:say("You cut a flower from a cactus.", TALKTYPE_MONSTER_SAY) + end + end + elseif target.itemid == 4017 then + if player:getStorageValue(Storage.TheIceIslands.Questline) >= 21 then + if player:getStorageValue(Storage.TheIceIslands.FlowerBush) < 1 then + player:addItem(7249, 1) + player:setStorageValue(Storage.TheIceIslands.FlowerBush, 1) + target:transform(4014) + addEvent(revertItem, 60 * 1000, toPosition, 4014, 4017) + toPosition:sendMagicEffect(CONST_ME_MAGIC_GREEN) + player:say("You cut a flower from a bush.", TALKTYPE_MONSTER_SAY) + end + end + -- What a foolish Quest (Mission 1) + elseif target.actionid == 4200 then + if toPosition.x == 32349 and toPosition.y == 32361 and toPosition.z == 7 then + player:addItem(7476, 1) + player:say( + "The stubborn flower has ruined your knife but at least you got it.", + TALKTYPE_MONSTER_SAY, false, player, toPosition) + item:remove(1) + else + player:say("This flower is too pathetic.", TALKTYPE_MONSTER_SAY, false, player, toPosition) + end + -- What a foolish quest (mission 5) + elseif target.itemid == 7480 then + if player:getStorageValue(Storage.WhatAFoolishQuest.EmperorBeardShave) == 1 then + player:say("God shave the emperor. Some fool already did it.", TALKTYPE_MONSTER_SAY) + return true + end + + player:setStorageValue(Storage.WhatAFoolishQuest.EmperorBeardShave, 1) + player:say("This is probably the most foolish thing you've ever done!", TALKTYPE_MONSTER_SAY) + player:addItem(7479, 1) + Game.createMonster("dwarf guard", Position(32656, 31853, 13)) + -- What a foolish quest (mission 8) + elseif target.itemid == 4008 then + if player:getStorageValue(Storage.WhatAFoolishQuest.Questline) ~= 22 or + player:getStorageValue(Storage.WhatAFoolishQuest.SpecialLeaves) == 1 then + return false + end + + player:setStorageValue(Storage.WhatAFoolishQuest.SpecialLeaves, 1) + player:addItem(8109, 1) + toPosition:sendMagicEffect(CONST_ME_BLOCKHIT) + elseif table.contains(fruits, target.itemid) and player:removeItem(6278, 1) then + target:remove(1) + player:addItem(6279, 1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + else + return false + end + return true +end + +function onGrindItem(player, item, fromPosition, target, toPosition) + if not(target.itemid == 23942) then + return false + end + for index, value in pairs(Itemsgrinder) do + if item.itemid == index then + local topParent = item:getTopParent() + if topParent.isItem and (not topParent:isItem() or topParent.itemid ~= 460) then + local parent = item:getParent() + if not parent:isTile() and (parent:addItem(value.item_id, 1) or topParent:addItem(value.item_id, 1)) then + item:remove(1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You grind a " .. ItemType(index):getName() .. " into fine, " .. ItemType(value.item_id):getName() .. ".") + doSendMagicEffect(target:getPosition(), value.effect) + return true + else + Game.createItem(value.item_id, 1, item:getPosition()) + end + else + Game.createItem(value.item_id, 1, item:getPosition()) + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You grind a " .. ItemType(index):getName() .. " into fine, " .. ItemType(value.item_id):getName() .. ".") + item:remove(1) + doSendMagicEffect(target:getPosition(), value.effect) + return + end + end +end \ No newline at end of file diff --git a/data/scripts/lib/register_bestiary_charm.lua b/data/scripts/lib/register_bestiary_charm.lua new file mode 100644 index 00000000000..5e25f4191d3 --- /dev/null +++ b/data/scripts/lib/register_bestiary_charm.lua @@ -0,0 +1,74 @@ +registerCharmType = {} +setmetatable(registerCharmType, +{ + __call = + function(self, charm, mask) + for _,parse in pairs(self) do + parse(charm, mask) + end + end +}) + +Bestiaryregister = function(charm, mask) + return registerCharmType(charm, mask) +end + +registerCharmType.name = function(charm, mask) + if mask.name then + charm:Name(mask.name) + end +end + +registerCharmType.description = function(charm, mask) + if mask.description then + charm:Description(mask.description) + end +end + +registerCharmType.type = function(charm, mask) + if mask.type then + charm:Type(mask.type) + end +end + +registerCharmType.damageType = function(charm, mask) + if mask.damageType then + charm:DamageType(mask.damageType) + end +end + +registerCharmType.percent = function(charm, mask) + if mask.percent then + charm:Percentage(mask.percent) + end +end + +registerCharmType.chance = function(charm, mask) + if mask.chance then + charm:Chance(mask.chance) + end +end + +registerCharmType.messageCancel = function(charm, mask) + if mask.messageCancel then + charm:CancelMsg(mask.messageCancel) + end +end + +registerCharmType.messageServerLog = function(charm, mask) + if mask.messageServerLog then + charm:LogMsg(mask.messageServerLog) + end +end + +registerCharmType.effect = function(charm, mask) + if mask.effect then + charm:Effect(mask.effect) + end +end + +registerCharmType.points = function(charm, mask) + if mask.points then + charm:Points(mask.points) + end +end \ No newline at end of file diff --git a/data/scripts/lib/register_monster_type.lua b/data/scripts/lib/register_monster_type.lua new file mode 100644 index 00000000000..0da2029a7dd --- /dev/null +++ b/data/scripts/lib/register_monster_type.lua @@ -0,0 +1,557 @@ +registerMonsterType = {} +setmetatable(registerMonsterType, +{ + __call = + function(self, mtype, mask) + for _,parse in pairs(self) do + parse(mtype, mask) + end + end +}) + +MonsterType.register = function(self, mask) + return registerMonsterType(self, mask) +end + +registerMonsterType.name = function(mtype, mask) + if mask.name then + mtype:name(mask.name) + end +end +registerMonsterType.description = function(mtype, mask) + if mask.description then + mtype:nameDescription(mask.description) + end +end +registerMonsterType.experience = function(mtype, mask) + if mask.experience then + mtype:experience(mask.experience) + end +end +registerMonsterType.raceId = function(mtype, mask) + if mask.raceId then + mtype:raceId(mask.raceId) + end +end +registerMonsterType.Bestiary = function(mtype, mask) + if mask.Bestiary then + if mask.Bestiary.race then + mtype:Bestiaryrace(mask.Bestiary.race) + end + if mask.Bestiary.class then + mtype:Bestiaryclass(mask.Bestiary.class) + end + if mask.Bestiary.toKill then + mtype:BestiarytoKill(mask.Bestiary.toKill) + end + if mask.Bestiary.FirstUnlock then + mtype:BestiaryFirstUnlock(mask.Bestiary.FirstUnlock) + end + if mask.Bestiary.SecondUnlock then + mtype:BestiarySecondUnlock(mask.Bestiary.SecondUnlock) + end + if mask.Bestiary.CharmsPoints then + mtype:BestiaryCharmsPoints(mask.Bestiary.CharmsPoints) + end + if mask.Bestiary.Stars then + mtype:BestiaryStars(mask.Bestiary.Stars) + end + if mask.Bestiary.Occurrence then + mtype:BestiaryOccurrence(mask.Bestiary.Occurrence) + end + if mask.Bestiary.Locations then + mtype:BestiaryLocations(mask.Bestiary.Locations) + end + end +end +registerMonsterType.skull = function(mtype, mask) + if mask.skull then + mtype:skull(mask.skull) + end +end +registerMonsterType.outfit = function(mtype, mask) + if mask.outfit then + mtype:outfit(mask.outfit) + end +end +registerMonsterType.maxHealth = function(mtype, mask) + if mask.maxHealth then + mtype:maxHealth(mask.maxHealth) + end +end +registerMonsterType.health = function(mtype, mask) + if mask.health then + mtype:health(mask.health) + end +end +registerMonsterType.maxSummons = function(mtype, mask) + if mask.maxSummons then + mtype:maxSummons(mask.maxSummons) + end +end +registerMonsterType.race = function(mtype, mask) + if mask.race then + mtype:race(mask.race) + end +end +registerMonsterType.manaCost = function(mtype, mask) + if mask.manaCost then + mtype:manaCost(mask.manaCost) + end +end +registerMonsterType.speed = function(mtype, mask) + if mask.speed then + mtype:baseSpeed(mask.speed) + end +end +registerMonsterType.corpse = function(mtype, mask) + if mask.corpse then + mtype:corpseId(mask.corpse) + end +end +registerMonsterType.flags = function(mtype, mask) + if mask.flags then + if mask.flags.attackable ~= nil then + mtype:isAttackable(mask.flags.attackable) + end + if mask.flags.convinceable ~= nil then + mtype:isConvinceable(mask.flags.convinceable) + end + if mask.flags.summonable ~= nil then + mtype:isSummonable(mask.flags.summonable) + end + if mask.flags.illusionable ~= nil then + mtype:isIllusionable(mask.flags.illusionable) + end + if mask.flags.hostile ~= nil then + mtype:isHostile(mask.flags.hostile) + end + if mask.flags.healthHidden ~= nil then + mtype:isHealthHidden(mask.flags.healthHidden) + end + if mask.flags.pushable ~= nil then + mtype:isPushable(mask.flags.pushable) + end + if mask.flags.canPushItems ~= nil then + mtype:canPushItems(mask.flags.canPushItems) + end + if mask.flags.rewardBoss then + mtype:isRewardBoss(mask.flags.rewardBoss) + end + if mask.flags.pet then + mtype:isPet(mask.flags.pet) + end + if mask.flags.respawntype or mask.flags.respawnType then + Spdlog.warn(string.format("[registerMonsterType.flags] - Monster: %s. Deprecated flag 'respawnType', use instead table 'respawnType = { period = RespawnPeriod_t, underground = boolean}'", + mtype:name())) + end + if mask.flags.canPushCreatures ~= nil then + mtype:canPushCreatures(mask.flags.canPushCreatures) + end + if mask.flags.targetDistance then + mtype:targetDistance(math.max(1, mask.flags.targetDistance)) + end + if mask.flags.runHealth then + mtype:runHealth(mask.flags.runHealth) + end + if mask.flags.staticAttackChance then + mtype:staticAttackChance(mask.flags.staticAttackChance) + end + if mask.flags.canWalkOnEnergy ~= nil then + mtype:canWalkOnEnergy(mask.flags.canWalkOnEnergy) + end + if mask.flags.canWalkOnFire ~= nil then + mtype:canWalkOnFire(mask.flags.canWalkOnFire) + end + if mask.flags.canWalkOnPoison ~= nil then + mtype:canWalkOnPoison(mask.flags.canWalkOnPoison) + end + if mask.flags.isBlockable ~= nil then + mtype:isBlockable(mask.flags.isBlockable) + end + end +end +registerMonsterType.light = function(mtype, mask) + if mask.light then + if mask.light.color then + local color = mask.light.color + end + if mask.light.level then + mtype:light(color, mask.light.level) + end + end +end +registerMonsterType.changeTarget = function(mtype, mask) + if mask.changeTarget then + if mask.changeTarget.chance then + mtype:changeTargetChance(mask.changeTarget.chance) + end + if mask.changeTarget.interval then + mtype:changeTargetSpeed(mask.changeTarget.interval) + end + end +end +registerMonsterType.strategiesTarget = function(mtype, mask) + if mask.strategiesTarget then + if mask.strategiesTarget.nearest then + mtype:strategiesTargetNearest(mask.strategiesTarget.nearest) + end + if mask.strategiesTarget.health then + mtype:strategiesTargetHealth(mask.strategiesTarget.health) + end + if mask.strategiesTarget.damage then + mtype:strategiesTargetDamage(mask.strategiesTarget.damage) + end + if mask.strategiesTarget.random then + mtype:strategiesTargetRandom(mask.strategiesTarget.random) + end + end +end +registerMonsterType.respawnType = function(mtype, mask) + if mask.respawnType then + if mask.respawnType.period then + mtype:respawnTypePeriod(mask.respawnType.period) + end + if mask.respawnType.underground then + mtype:respawnTypeIsUnderground(mask.respawnType.underground) + end + end +end +registerMonsterType.voices = function(mtype, mask) + if type(mask.voices) == "table" then + local interval, chance + if mask.voices.interval then + interval = mask.voices.interval + end + if mask.voices.chance then + chance = mask.voices.chance + end + for k, v in pairs(mask.voices) do + if type(v) == "table" then + mtype:addVoice(v.text, interval, chance, v.yell) + end + end + end +end +registerMonsterType.summons = function(mtype, mask) + if type(mask.summons) == "table" then + for k, v in pairs(mask.summons) do + mtype:addSummon(v.name, v.interval, v.chance) + end + end +end +registerMonsterType.events = function(mtype, mask) + if type(mask.events) == "table" then + for k, v in pairs(mask.events) do + mtype:registerEvent(v) + end + end +end +registerMonsterType.loot = function(mtype, mask) + if type(mask.loot) == "table" then + local lootError = false + for _, loot in pairs(mask.loot) do + local parent = Loot() + if loot.name then + if not parent:setIdFromName(loot.name) then + lootError = true + end + else + if not isInteger(loot.id) or loot.id < 1 then + lootError = true + end + parent:setId(loot.id) + end + if loot.subType or loot.charges then + parent:setSubType(loot.subType or loot.charges) + else + local lType = ItemType(loot.name and loot.name or loot.id) + if lType and lType:getCharges() > 1 then + parent:setSubType(lType:getCharges()) + end + end + if loot.chance then + parent:setChance(loot.chance) + end + if loot.minCount then + parent:setMinCount(loot.minCount) + end + if loot.maxCount then + parent:setMaxCount(loot.maxCount) + end + if loot.aid or loot.actionId then + parent:setActionId(loot.aid or loot.actionId) + end + if loot.text or loot.description then + parent:setText(loot.text or loot.description) + end + if loot.name then + parent:setNameItem(loot.name) + end + if loot.article then + parent:setArticle(loot.article) + end + if loot.attack then + parent:setAttack(loot.attack) + end + if loot.defense then + parent:setDefense(loot.defense) + end + if loot.extraDefense or loot.extraDef then + parent:setExtraDefense(loot.extraDefense or loot.extraDef) + end + if loot.armor then + parent:setArmor(loot.armor) + end + if loot.shootRange or loot.range then + parent:setShootRange(loot.shootRange or loot.range) + end + if loot.unique then + parent:setUnique(loot.unique) + end + if loot.child then + for _, children in pairs(loot.child) do + local child = Loot() + if children.name then + if not child:setIdFromName(children.name) then + lootError = true + end + else + if not isInteger(children.id) or children.id < 1 then + lootError = true + end + child:setId(children.id) + end + if children.subType or children.charges then + child:setSubType(children.subType or children.charges) + else + local cType = ItemType(children.name and children.name or children.id) + if cType and cType:getCharges() > 1 then + child:setSubType(cType:getCharges()) + end + end + if children.chance then + child:setChance(children.chance) + end + if children.minCount then + child:setMinCount(children.minCount) + end + if children.maxCount then + child:setMaxCount(children.maxCount) + end + if children.aid or children.actionId then + child:setActionId(children.aid or children.actionId) + end + if children.text or children.description then + child:setText(children.text or children.description) + end + if loot.name then + child:setNameItem(loot.name) + end + if children.article then + child:setArticle(children.article) + end + if children.attack then + child:setAttack(children.attack) + end + if children.defense then + child:setDefense(children.defense) + end + if children.extraDefense or children.extraDef then + child:setExtraDefense(children.extraDefense or children.extraDef) + end + if children.armor then + child:setArmor(children.armor) + end + if children.shootRange or children.range then + child:setShootRange(children.shootRange or children.range) + end + if children.unique then + child:setUnique(children.unique) + end + parent:addChildLoot(child) + end + end + mtype:addLoot(parent) + end + if lootError then + Spdlog.warn("[registerMonsterType.loot] - Monster: ".. mtype:name() .. " loot could not correctly be load") + end + end +end +registerMonsterType.elements = function(mtype, mask) + if type(mask.elements) == "table" then + for _, element in pairs(mask.elements) do + if element.type and element.percent then + mtype:addElement(element.type, element.percent) + end + end + end +end +registerMonsterType.reflects = function(mtype, mask) + if type(mask.reflects) == "table" then + for _, reflect in pairs(mask.reflects) do + if reflect.type and reflect.percent then + mtype:addReflect(reflect.type, reflect.percent) + end + end + end +end +registerMonsterType.heals = function(mtype, mask) + if type(mask.heals) == "table" then + for _, heal in pairs(mask.heals) do + if heal.type and heal.percent then + mtype:addHealing(heal.type, heal.percent) + end + end + end +end +registerMonsterType.immunities = function(mtype, mask) + if type(mask.immunities) == "table" then + for _, immunity in pairs(mask.immunities) do + if immunity.type and immunity.combat then + mtype:combatImmunities(immunity.type) + end + if immunity.type and immunity.condition then + mtype:conditionImmunities(immunity.type) + end + end + end +end +registerMonsterType.attacks = function(mtype, mask) + if type(mask.attacks) == "table" then + for _, attack in pairs(mask.attacks) do + mtype:addAttack(readSpell(attack)) + end + end +end + +registerMonsterType.defenses = function(mtype, mask) + if type(mask.defenses) == "table" then + if mask.defenses.defense then + mtype:defense(mask.defenses.defense) + end + if mask.defenses.armor then + mtype:armor(mask.defenses.armor) + end + for _, defense in pairs(mask.defenses) do + if type(defense) == "table" then + mtype:addDefense(readSpell(defense)) + end + end + end +end + +function readSpell(incomingLua) + local spell = MonsterSpell() + if incomingLua.name then + if incomingLua.name == "melee" then + spell:setType("melee") + if incomingLua.attack and incomingLua.skill then + spell:setAttackValue(incomingLua.attack, incomingLua.skill) + end + if incomingLua.minDamage and incomingLua.maxDamage then + spell:setCombatValue(incomingLua.minDamage, incomingLua.maxDamage) + end + if incomingLua.interval then + spell:setInterval(incomingLua.interval) + end + if incomingLua.effect then + spell:setCombatEffect(incomingLua.effect) + end + else + spell:setType(incomingLua.name) + if incomingLua.type then + if incomingLua.name == "combat" then + spell:setCombatType(incomingLua.type) + elseif incomingLua.name == "condition" then + spell:setConditionType(incomingLua.type) + else + Spdlog.warn("[readSpell] - Monster ".. mtype:name() .. ": Loading spell ".. incomingLua.name .. ". Parameter type applies only for condition and combat.") + end + end + if incomingLua.interval then + spell:setInterval(incomingLua.interval) + end + if incomingLua.chance then + spell:setChance(incomingLua.chance) + end + if incomingLua.range then + spell:setRange(incomingLua.range) + end + if incomingLua.duration then + spell:setConditionDuration(incomingLua.duration) + end + if incomingLua.speedChange then + spell:setConditionSpeedChange(incomingLua.speedChange) + end + if incomingLua.target then + spell:setNeedTarget(incomingLua.target) + end + if incomingLua.length then + spell:setCombatLength(incomingLua.length) + end + if incomingLua.spread then + spell:setCombatSpread(incomingLua.spread) + end + if incomingLua.radius then + spell:setCombatRadius(incomingLua.radius) + end + if incomingLua.outfitMonster then + spell:setOutfitMonster(incomingLua.outfitMonster) + end + if incomingLua.outfitItem then + spell:setOutfitItem(incomingLua.outfitItem) + end + if incomingLua.minDamage and incomingLua.maxDamage then + if incomingLua.name == "combat" or Spell(incomingLua.name) then + spell:setCombatValue(incomingLua.minDamage, incomingLua.maxDamage) + else + local startDamage = 0 + if incomingLua.startDamage then + startDamage = incomingLua.startDamage + end + spell:setConditionDamage(incomingLua.minDamage, incomingLua.maxDamage, startDamage) + end + end + if incomingLua.effect then + spell:setCombatEffect(incomingLua.effect) + end + if incomingLua.shootEffect then + spell:setCombatShootEffect(incomingLua.shootEffect) + end + end + + -- This is for a complex spell, that has combat damage AND some condition + -- For example scorpions, which attack and cause poison on attack + if incomingLua.condition then + if incomingLua.condition.type then + spell:setConditionType(incomingLua.condition.type) + end + if incomingLua.condition.duration then + spell:setConditionDuration(incomingLua.condition.duration) + end + if incomingLua.condition.interval then + spell:setConditionTickInterval(incomingLua.condition.interval) + end + + spell:setConditionDamage(incomingLua.condition.totalDamage, incomingLua.condition.totalDamage, 0) + end + elseif incomingLua.script then + spell:setScriptName("monster/" .. incomingLua.script .. ".lua") + if incomingLua.interval then + spell:setInterval(incomingLua.interval) + end + if incomingLua.chance then + spell:setChance(incomingLua.chance) + end + if incomingLua.minDamage and incomingLua.maxDamage then + spell:setCombatValue(incomingLua.minDamage, incomingLua.maxDamage) + end + if incomingLua.target then + spell:setNeedTarget(incomingLua.target) + end + end + + return spell +end diff --git a/data/scripts/lib/register_movements.lua b/data/scripts/lib/register_movements.lua new file mode 100644 index 00000000000..3e4436cf83e --- /dev/null +++ b/data/scripts/lib/register_movements.lua @@ -0,0 +1,55 @@ +local conditionHaste = Condition(CONDITION_HASTE, 10) +local conditionSkill = Condition(CONDITION_ATTRIBUTES, 10) + +function onEquipWeaponImbuement(player, item) + local weaponType = item:getType() + for i = 1, weaponType:getImbuingSlots() do + local slotEnchant = item:getSpecialAttribute(i) + if (slotEnchant) then + local skillValue = item:getImbuementPercent(slotEnchant) + local typeEnchant = item:getImbuementType(i) or "" + if (typeEnchant == "skillSword") then + conditionSkill:setParameter(CONDITION_PARAM_TICKS, -1) + conditionSkill:setParameter(CONDITION_PARAM_SKILL_SWORD, skillValue) + player:addCondition(conditionSkill) + elseif (typeEnchant == "skillAxe") then + conditionSkill:setParameter(CONDITION_PARAM_TICKS, -1) + conditionSkill:setParameter(CONDITION_PARAM_SKILL_AXE, skillValue) + player:addCondition(conditionSkill) + elseif (typeEnchant == "skillClub") then + conditionSkill:setParameter(CONDITION_PARAM_TICKS, -1) + conditionSkill:setParameter(CONDITION_PARAM_SKILL_CLUB, skillValue) + player:addCondition(conditionSkill) + elseif (typeEnchant == "skillDist") then + conditionSkill:setParameter(CONDITION_PARAM_TICKS, -1) + conditionSkill:setParameter(CONDITION_PARAM_SKILL_DISTANCE, skillValue) + player:addCondition(conditionSkill) + elseif (typeEnchant == "skillShield") then + conditionSkill:setParameter(CONDITION_PARAM_TICKS, -1) + conditionSkill:setParameter(CONDITION_PARAM_SKILL_SHIELD, skillValue) + player:addCondition(conditionSkill) + elseif (typeEnchant == "criticalhit") then + conditionSkill:setParameter(CONDITION_PARAM_TICKS, -1) + conditionSkill:setParameter(CONDITION_PARAM_SKILL_CRITICAL_HIT_CHANCEPERCENT, 10) + conditionSkill:setParameter(CONDITION_PARAM_SKILL_CRITICAL_HIT_DAMAGEPERCENT, skillValue) + player:addCondition(conditionSkill) + elseif (typeEnchant == "hitpointsleech") then + conditionSkill:setParameter(CONDITION_PARAM_TICKS, -1) + conditionSkill:setParameter(CONDITION_PARAM_SKILL_LIFE_LEECH_CHANCEPERCENT, 100) + conditionSkill:setParameter(CONDITION_PARAM_SKILL_LIFE_LEECH_AMOUNTPERCENT, skillValue) + player:addCondition(conditionSkill) + elseif (typeEnchant == "magiclevelpoints") then + conditionSkill:setParameter(CONDITION_PARAM_TICKS, -1) + conditionSkill:setParameter(CONDITION_PARAM_STAT_MAGICPOINTS, skillValue) + player:addCondition(conditionSkill) + end + end + end + return true +end + +function onDeEquipWeaponImbuement(player, item) + player:removeCondition(CONDITION_HASTE, 10) + player:removeCondition(CONDITION_ATTRIBUTES, 10) + return true +end diff --git a/data/scripts/lib/register_npc_type.lua b/data/scripts/lib/register_npc_type.lua new file mode 100644 index 00000000000..9c9860f59a1 --- /dev/null +++ b/data/scripts/lib/register_npc_type.lua @@ -0,0 +1,146 @@ +registerNpcType = {} +setmetatable(registerNpcType, +{ + __call = + function(self, npcType, mask) + for _,parse in pairs(self) do + parse(npcType, mask) + end + end +}) + +NpcType.register = function(self, mask) + return registerNpcType(self, mask) +end + +registerNpcType.name = function(npcType, mask) + if mask.name then + npcType:name(mask.name) + end +end + +registerNpcType.description = function(npcType, mask) + if mask.description then + npcType:nameDescription(mask.description) + end +end + +registerNpcType.speechBubble = function(npcType, mask) + if mask.speechBubble then + npcType:setSpeechBubble(mask.speechBubble) + end +end + +registerNpcType.outfit = function(npcType, mask) + if mask.outfit then + npcType:outfit(mask.outfit) + end +end + +registerNpcType.maxHealth = function(npcType, mask) + if mask.maxHealth then + npcType:maxHealth(mask.maxHealth) + end +end + +registerNpcType.health = function(npcType, mask) + if mask.health then + npcType:health(mask.health) + end +end + +registerNpcType.race = function(npcType, mask) + if mask.race then + npcType:race(mask.race) + end +end + +registerNpcType.walkInterval = function(npcType, mask) + if mask.walkInterval then + npcType:walkInterval(mask.walkInterval) + end +end + +registerNpcType.walkRadius = function(npcType, mask) + if mask.walkRadius then + npcType:walkRadius(mask.walkRadius) + end +end + +registerNpcType.speed = function(npcType, mask) + if mask.speed then + npcType:baseSpeed(mask.speed) + end +end + +registerNpcType.flags = function(npcType, mask) + if mask.flags then + if mask.flags.floorchange ~= nil then + npcType:floorChange(mask.flags.floorchange) + end + if mask.flags.canPushCreatures ~= nil then + npcType:canPushCreatures(mask.flags.canPushCreatures) + end + if mask.flags.canPushItems ~= nil then + npcType:canPushItems(mask.flags.canPushItems) + end + if mask.flags.pushable ~= nil then + npcType:isPushable(mask.flags.pushable) + end + end +end + +registerNpcType.light = function(npcType, mask) + if mask.light then + if mask.light.color then + local color = mask.light.color + end + if mask.light.level then + npcType:light(color, mask.light.level) + end + end +end + +registerNpcType.respawnType = function(npcType, mask) + if mask.respawnType then + if mask.respawnType.period then + npcType:respawnTypePeriod(mask.respawnType.period) + end + if mask.respawnType.underground then + npcType:respawnTypeIsUnderground(mask.respawnType.underground) + end + end +end + +registerNpcType.voices = function(npcType, mask) + if type(mask.voices) == "table" then + local interval, chance + if mask.voices.interval then + interval = mask.voices.interval + end + if mask.voices.chance then + chance = mask.voices.chance + end + for k, v in pairs(mask.voices) do + if type(v) == "table" then + npcType:addVoice(v.text, interval, chance, v.yell) + end + end + end +end + +registerNpcType.events = function(npcType, mask) + if type(mask.events) == "table" then + for k, v in pairs(mask.events) do + npcType:registerEvent(v) + end + end +end + +registerNpcType.shop = function(npcType, mask) + if type(mask.shop) == "table" then + for _, shopItem in pairs(mask.shop) do + npcType:addShopItem(shopItem) + end + end +end diff --git a/data/scripts/modules/bestiary_charms.lua b/data/scripts/modules/bestiary_charms.lua new file mode 100644 index 00000000000..08df9570fa9 --- /dev/null +++ b/data/scripts/modules/bestiary_charms.lua @@ -0,0 +1,313 @@ +-- +-- Wound charm +-- +local charm_1 = Game.createBestiaryCharm(0) +local charm_t1 = {} + +charm_t1.name = "Wound" +charm_t1.description = "Triggers on a creature with a certain chance and deals 5% \z + of its initial hit points as physical damage once." +charm_t1.type = CHARM_OFFENSIVE +charm_t1.damageType = COMBAT_PHYSICALDAMAGE +charm_t1.percent = 10 +charm_t1.chance = 20 +charm_t1.messageCancel = "You wounded the monster." +charm_t1.messageServerLog = "[Wound charm]" +charm_t1.effect = CONST_ME_HITAREA +charm_t1.points = 600 + +Bestiaryregister(charm_1, charm_t1) +-- +-- Enflame charm +-- +local charm_2 = Game.createBestiaryCharm(1) +local charm_t2 = {} + +charm_t2.name = "Enflame" +charm_t2.description = "Triggers on a creature with a certain chance and deals 5% \z + of its initial hit points as fire damage once." +charm_t2.type = CHARM_OFFENSIVE +charm_t2.damageType = COMBAT_FIREDAMAGE +charm_t2.percent = 10 +charm_t2.chance = 20 +charm_t2.messageCancel = "You enflamed the monster." +charm_t2.messageServerLog = "[Enflame charm]" +charm_t2.effect = CONST_ME_HITBYFIRE +charm_t2.points = 1000 + +Bestiaryregister(charm_2, charm_t2) +-- +-- Poison charm +-- +local charm_3 = Game.createBestiaryCharm(2) +local charm_t3 = {} + +charm_t3.name = "Poison" +charm_t3.description = "Triggers on a creature with a certain chance and deals 5% \z + of its initial hit points as earth damage once." +charm_t3.type = CHARM_OFFENSIVE +charm_t3.damageType = COMBAT_EARTHDAMAGE +charm_t3.percent = 10 +charm_t3.chance = 20 +charm_t3.messageCancel = "You poisoned the monster." +charm_t3.messageServerLog = "[Poison charm]" +charm_t3.effect = CONST_ME_GREEN_RINGS +charm_t3.points = 600 + +Bestiaryregister(charm_3, charm_t3) +-- +-- Freeze charm +-- +local charm_4 = Game.createBestiaryCharm(3) +local charm_t4 = {} + +charm_t4.name = "Freeze" +charm_t4.description = "Triggers on a creature with a certain chance and deals 5% \z + of its initial hit points as ice damage once." +charm_t4.type = CHARM_OFFENSIVE +charm_t4.damageType = COMBAT_ICEDAMAGE +charm_t4.percent = 10 +charm_t4.chance = 20 +charm_t4.messageCancel = "You frozen the monster." +charm_t4.messageServerLog = "[Freeze charm]" +charm_t4.effect = CONST_ME_ICEATTACK +charm_t4.points = 800 + +Bestiaryregister(charm_4, charm_t4) +-- +-- Zap charm +-- +local charm_5 = Game.createBestiaryCharm(4) +local charm_t5 = {} + +charm_t5.name = "Zap" +charm_t5.description = "Triggers on a creature with a certain chance and deals 5% \z + of its initial hit points as energy damage once." +charm_t5.type = CHARM_OFFENSIVE +charm_t5.damageType = COMBAT_ENERGYDAMAGE +charm_t5.percent = 10 +charm_t5.chance = 20 +charm_t5.messageCancel = "You eletrocuted the monster." +charm_t5.messageServerLog = "[Zap charm]" +charm_t5.effect = CONST_ME_ENERGYHIT +charm_t5.points = 800 + +Bestiaryregister(charm_5, charm_t5) +-- +-- Curse charm +-- +local charm_6 = Game.createBestiaryCharm(5) +local charm_t6 = {} + +charm_t6.name = "Curse" +charm_t6.description = "Triggers on a creature with a certain chance and deals 5% \z + of its initial hit points as death damage once." +charm_t6.type = CHARM_OFFENSIVE +charm_t6.damageType = COMBAT_DEATHDAMAGE +charm_t6.percent = 10 +charm_t6.chance = 20 +charm_t6.messageCancel = "You curse the monster." +charm_t6.messageServerLog = "[Curse charm]" +charm_t6.effect = CONST_ME_SMALLCLOUDS +charm_t6.points = 900 + +Bestiaryregister(charm_6, charm_t6) + + +-- +-- Cripple charm +-- +local charm7 = Game.createBestiaryCharm(6) +local charm_t7 = {} + +charm_t7.name = "Cripple" +charm_t7.description = "Cripples the creature with a certain chance and paralyzes it for 10 seconds." +charm_t7.type = CHARM_OFFENSIVE +charm_t7.chance = 20 +charm_t7.messageCancel = "You cripple the monster." +charm_t7.points = 500 + +Bestiaryregister(charm7, charm_t7) +-- +-- Parry charm +-- +local charm_8 = Game.createBestiaryCharm(7) +local charm_t8 = {} + +charm_t8.name = "Parry" +charm_t8.description = "Any damage taken is reflected to the aggressor with a certain chance." +charm_t8.type = CHARM_DEFENSIVE +charm_t8.damageType = COMBAT_PHYSICALDAMAGE +charm_t8.chance = 10 +charm_t8.messageCancel = "You parry the attack." +charm_t8.messageServerLog = "[Parry charm]" +charm_t8.effect = CONST_ME_EXPLOSIONAREA +charm_t8.points = 1000 + +Bestiaryregister(charm_8, charm_t8) +-- +-- Dodge charm +-- +local charm_9 = Game.createBestiaryCharm(8) +local charm_t9 = {} + +charm_t9.name = "Dodge" +charm_t9.description = "Dodges an attack with a certain chance without taking any damage at all." +charm_t9.type = CHARM_DEFENSIVE +charm_t9.chance = 20 +charm_t9.messageCancel = "You dodge the attack." +charm_t9.effect = CONST_ME_POFF +charm_t9.points = 600 + +Bestiaryregister(charm_9, charm_t9) +-- +-- Adrenaline burst charm +-- +local charm_10 = Game.createBestiaryCharm(9) +local charm_t10 = {} + +charm_t10.name = "Adrenaline Burst" +charm_t10.description = "Bursts of adrenaline enhance your reflexes with a certain chance \z + after you get hit and let you move faster for 10 seconds." +charm_t10.type = CHARM_DEFENSIVE +charm_t10.chance = 20 +charm_t10.messageCancel = "Your movements where bursted." +charm_t10.points = 500 + +Bestiaryregister(charm_10, charm_t10) +-- +-- Numb charm +-- +local charm_11 = Game.createBestiaryCharm(10) +local charm_t11 = {} + +charm_t11.name = "Numb" +charm_t11.description = "Numbs the creature with a certain chance after its attack and paralyzes the creature for 10 seconds." +charm_t11.type = CHARM_DEFENSIVE +charm_t11.chance = 20 +charm_t11.messageCancel = "You numb the monster." +charm_t11.points = 500 + +Bestiaryregister(charm_11, charm_t11) +-- +-- Cleanse charm +-- +local charm_12 = Game.createBestiaryCharm(11) +local charm_t12 = {} + +charm_t12.name = "Cleanse" +charm_t12.description = "Cleanses you from within with a certain chance after you get hit and \z + removes one random active negative status effect and temporarily makes you immune against it." +charm_t12.type = CHARM_DEFENSIVE +charm_t12.chance = 20 +charm_t12.messageCancel = "You purified the attack." +charm_t12.points = 700 + +Bestiaryregister(charm_12, charm_t12) +-- +-- Bless charm +-- +local charm_13 = Game.createBestiaryCharm(12) +local charm_t13 = {} + +charm_t13.name = "Bless" +charm_t13.description = "Blesses you and reduces skill and xp loss by 10% \z + when killed by the chosen creature." +charm_t13.type = CHARM_PASSIVE +charm_t13.percent = 10 +charm_t13.chance = 100 +charm_t13.points = 800 + +Bestiaryregister(charm_13, charm_t13) + +-- +-- Scavenge charm +-- +local charm_14 = Game.createBestiaryCharm(13) +local charm_t14 = {} + +charm_t14.name = "Scavenge" +charm_t14.description = "Enhances your chances to successfully skin/dust a skinnable/dustable creature." +charm_t14.type = CHARM_PASSIVE +charm_t14.percent = 10 +charm_t14.points = 800 + +GLOBAL_CHARM_SCAVENGE = charm_t14.percent +Bestiaryregister(charm_14, charm_t14) +-- +-- Gut charm +-- +local charm_15 = Game.createBestiaryCharm(14) +local charm_t15 = {} + +charm_t15.name = "Gut" +charm_t15.description = "Gutting the creature yields 20% more creature products." +charm_t15.type = CHARM_PASSIVE +charm_t15.percent = 20 +charm_t15.points = 800 + +GLOBAL_CHARM_GUT = charm_t15.percent +Bestiaryregister(charm_15, charm_t15) +-- +-- Low blow charm +-- +local charm_16 = Game.createBestiaryCharm(15) +local charm_t16 = {} + +charm_t16.name = "Low Blow" +charm_t16.description = "Adds 8% critical hit chance to attacks with critical hit weapons." +charm_t16.type = CHARM_PASSIVE +charm_t16.percent = 8 +charm_t16.chance = 0 +charm_t16.points = 2000 + +Bestiaryregister(charm_16, charm_t16) +-- +-- Divine wrath charm +-- +local charm_17 = Game.createBestiaryCharm(16) +local charm_t17 = {} + +charm_t17.name = "Divine Wrath" +charm_t17.description = "Triggers on a creature with a certain chance and deals 5% \z + of its initial hit points as holy damage once." +charm_t17.type = CHARM_OFFENSIVE +charm_t17.damageType = COMBAT_HOLYDAMAGE +charm_t17.percent = 10 +charm_t17.chance = 20 +charm_t17.messageCancel = "You divine the monster." +charm_t17.messageServerLog = "[Divine charm]" +charm_t17.effect = CONST_ME_HOLYDAMAGE +charm_t17.points = 1500 + +Bestiaryregister(charm_17, charm_t17) +-- +-- Vampiric embrace charm +-- +local charm_18 = Game.createBestiaryCharm(17) +local charm_t18 = {} + +charm_t18.name = "Vampiric Embrace" +charm_t18.description = "Adds 4% Life Leech to attacks if wearing equipment that \z + provides life leech." +charm_t18.type = CHARM_PASSIVE +charm_t18.percent = 4 +charm_t18.chance = 0 +charm_t18.points = 1500 + +Bestiaryregister(charm_18, charm_t18) +-- +-- Void's call charm +-- +local charm_19 = Game.createBestiaryCharm(18) +local charm_t19 = {} + +charm_t19.name = "Void's Call" +charm_t19.description = "Adds 2% Mana Leech to attacks if wearing equipment that \z + provides mana leech." +charm_t19.type = CHARM_PASSIVE +charm_t19.percent = 2 +charm_t19.chance = 0 +charm_t19.points = 1500 + +Bestiaryregister(charm_19, charm_t19) diff --git a/data/scripts/movements/equipment/unscripted_equipments.lua b/data/scripts/movements/equipment/unscripted_equipments.lua new file mode 100644 index 00000000000..1b15bdef68b --- /dev/null +++ b/data/scripts/movements/equipment/unscripted_equipments.lua @@ -0,0 +1,14818 @@ +if not equipmentsTable then + equipmentsTable = { + { + itemid = 40737, + type = "equip", + slot = "ammo" + }, -- spectral bolt (no decay) + { + itemid = 40737, + type = "deequip", + slot = "ammo" + }, -- spectral bolt (no decay) + { + itemid = 40684, + type = "equip", + slot = "right-hand", + vocation = { + {"None", true}, + {"Paladin", true, true}, + {"Royal Paladin"} + } + }, -- red quiver + { + itemid = 40684, + type = "deequip", + slot = "right-hand", + vocation = { + {"None", true}, + {"Paladin", true, true}, + {"Royal Paladin"} + } + }, -- red quiver + { + itemid = 40683, + type = "equip", + slot = "right-hand", + vocation = { + {"None", true}, + {"Paladin", true, true}, + {"Royal Paladin"} + } + }, -- blue quiver + { + itemid = 40683, + type = "deequip", + slot = "right-hand", + vocation = { + {"None", true}, + {"Paladin", true, true}, + {"Royal Paladin"} + } + }, -- blue quiver + { + itemid = 40397, + type = "equip", + slot = "right-hand", + vocation = { + {"None", true}, + {"Paladin", true, true}, + {"Royal Paladin"} + } + }, -- quiver + { + itemid = 40397, + type = "deequip", + slot = "right-hand", + vocation = { + {"None", true}, + {"Paladin", true, true}, + {"Royal Paladin"} + } + }, -- quiver + { + itemid = 40359, + type = "equip", + slot = "right-hand", + level = 150, + vocation = { + {"Paladin", true, true}, + {"Royal Paladin"} + } + }, -- jungle quiver + { + itemid = 40359, + type = "deequip", + slot = "right-hand", + level = 150, + vocation = { + {"Paladin", true, true}, + {"Royal Paladin"} + } + }, -- jungle quiver + { + itemid = 40358, + type = "equip", + slot = "necklace", + level = 180 + }, -- exotic amulet + { + itemid = 40358, + type = "deequip", + slot = "necklace" + }, -- exotic amulet + { + itemid = 40357, + type = "equip", + slot = "hand", + level = 150, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- jungle wand + { + itemid = 40357, + type = "deequip", + slot = "hand", + }, -- jungle wand + { + itemid = 40356, + type = "equip", + slot = "hand", + level = 150, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- jungle rod + { + itemid = 40356, + type = "deequip", + slot = "hand", + }, -- jungle rod + { + itemid = 40355, + type = "equip", + slot = "feet", + level = 150, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- make-do boots + { + itemid = 40355, + type = "deequip", + slot = "feet", + }, -- make-do boots + { + itemid = 40354, + type = "equip", + slot = "feet", + level = 150, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- makeshift boots + { + itemid = 40354, + type = "deequip", + slot = "feet", + }, -- makeshift boots + { + itemid = 40353, + type = "equip", + slot = "hand", + level = 150, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- jungle bow + { + itemid = 40353, + type = "deequip", + slot = "hand", + }, -- jungle bow + { + itemid = 40352, + type = "equip", + slot = "legs", + level = 150, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- bast legs + { + itemid = 40352, + type = "deequip", + slot = "legs", + }, -- bast legs + { + itemid = 40351, + type = "equip", + slot = "legs", + level = 130, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- exotic legs + { + itemid = 40351, + type = "deequip", + slot = "legs", + }, -- exotic legs + { + itemid = 40350, + type = "equip", + slot = "hand", + level = 150, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- throwing axe + { + itemid = 40350, + type = "deequip", + slot = "hand", + }, -- throwing axe + { + itemid = 40349, + type = "equip", + slot = "hand", + level = 150, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- jungle flail + { + itemid = 40349, + type = "deequip", + slot = "hand", + }, -- jungle flail + { + itemid = 39089, + type = "equip", + slot = "hand", + level = 270, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- lion hammer + { + itemid = 39089, + type = "deequip", + slot = "hand" + }, -- lion hammer + { + itemid = 39088, + type = "equip", + slot = "hand", + level = 270, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- lion axe + { + itemid = 39088, + type = "deequip", + slot = "hand" + }, -- lion axe + { + itemid = 38993, + type = "equip", + slot = "necklace", + level = 150 + }, -- lion amulet + { + itemid = 38993, + type = "deequip", + slot = "necklace", + level = 150 + }, -- lion amulet + { + itemid = 38992, + type = "deequip", + slot = "armor", + level = 270 + }, -- lion plate + { + itemid = 38992, + type = "equip", + slot = "armor", + level = 270, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- lion plate + { + itemid = 38991, + type = "deequip", + slot = "head" + }, -- lion spangenhelm + { + itemid = 38991, + type = "equip", + slot = "head", + level = 230, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- lion spangenhelm + { + itemid = 38990, + type = "equip", + slot = "hand", + level = 270, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- lion longsword + { + itemid = 38990, + type = "deequip", + slot = "hand" + }, -- lion longsword + { + itemid = 38988, + type = "deequip", + slot = "shield" + }, -- lion spellbook + { + itemid = 38988, + type = "equip", + slot = "shield", + level = 220, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- lion spellbook + { + itemid = 38987, + type = "equip", + slot = "hand", + level = 220, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- lion wand + { + itemid = 38987, + type = "deequip", + slot = "hand" + }, -- lion wand + { + itemid = 38986, + type = "equip", + slot = "hand", + level = 270, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- lion rod + { + itemid = 38986, + type = "deequip", + slot = "hand" + }, -- lion rod + { + itemid = 38985, + type = "equip", + slot = "hand", + level = 270, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- lion longbow + { + itemid = 38985, + type = "deequip", + slot = "hand" + }, -- lion longbow + { + itemid = 38934, + type = "deequip", + slot = "shield" + }, -- soulbastion shield + { + itemid = 38934, + type = "equip", + slot = "shield", + level = 400, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- soulbastion shield + { + itemid = 38933, + type = "deequip", + slot = "feet" + }, -- pair of soulstalkers + { + itemid = 38933, + type = "equip", + slot = "feet", + level = 400, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- pair of soulstalkers + { + itemid = 38932, + type = "deequip", + slot = "feet" + }, -- pair of soulwalkers + { + itemid = 38932, + type = "equip", + slot = "feet", + level = 400, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- pair of soulwalkers + { + itemid = 38931, + type = "deequip", + slot = "armor" + }, -- soulshroud armor + { + itemid = 38931, + type = "equip", + slot = "armor", + level = 400, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- soulshroud armor + { + itemid = 38930, + type = "deequip", + slot = "armor" + }, -- soulmantel armor + { + itemid = 38930, + type = "equip", + slot = "armor", + level = 400, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- soulmantel armor + { + itemid = 38929, + type = "deequip", + slot = "armor", + level = 400 + }, -- soulshell armor + { + itemid = 38929, + type = "equip", + slot = "armor", + level = 400, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- soulshell armor + { + itemid = 38928, + type = "deequip", + slot = "legs", + level = 400 + }, -- soulstrider legs + { + itemid = 38928, + type = "equip", + slot = "legs", + level = 400, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- soulstrider legs + { + itemid = 38927, + type = "deequip", + slot = "legs", + level = 400 + }, -- soulshanks legs + { + itemid = 38927, + type = "equip", + slot = "legs", + level = 400, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- soulshanks legs + { + itemid = 38926, + type = "deequip", + slot = "hand", + }, -- soulhexer + { + itemid = 38926, + type = "equip", + slot = "hand", + level = 400, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- soulhexer + { + itemid = 38925, + type = "deequip", + slot = "hand", + }, -- soultainter + { + itemid = 38925, + type = "equip", + slot = "hand", + level = 400, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- soultainter + { + itemid = 38924, + type = "deequip", + slot = "hand", + }, -- soulpiercer + { + itemid = 38924, + type = "equip", + slot = "hand", + level = 400, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- soulpiercer + { + itemid = 38923, + type = "deequip", + slot = "hand", + }, -- soulbleeder + { + itemid = 38923, + type = "equip", + slot = "hand", + level = 400, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- soulbleeder + { + itemid = 38922, + type = "deequip", + slot = "hand", + }, -- soulmaimer + { + itemid = 38922, + type = "equip", + slot = "hand", + level = 400, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- soulmaimer + { + itemid = 38921, + type = "deequip", + slot = "hand", + }, -- soulcrusher + { + itemid = 38921, + type = "equip", + slot = "hand", + level = 400, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- soulcrusher + { + itemid = 38920, + type = "deequip", + slot = "hand", + }, -- souleater + { + itemid = 38920, + type = "equip", + slot = "hand", + level = 400, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- souleater + { + itemid = 38919, + type = "deequip", + slot = "hand", + }, -- soulbiter + { + itemid = 38919, + type = "equip", + slot = "hand", + level = 400, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- soulbiter + { + itemid = 38918, + type = "deequip", + slot = "hand", + }, -- soulshredder + { + itemid = 38918, + type = "equip", + slot = "hand", + level = 400, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- soulshredder + { + itemid = 38917, + type = "deequip", + slot = "hand", + }, -- soulcutter + { + itemid = 38917, + type = "equip", + slot = "hand", + level = 400, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- soulcutter + { + itemid = 38915, + type = "deequip", + slot = "ring", + level = 270 + }, -- lion ring + { + itemid = 38915, + type = "equip", + slot = "ring", + level = 270, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- lion ring + { + itemid = 37540, + type = "equip", + slot = "armor" + }, -- pair of old bracers + { + itemid = 37540, + type = "deequip", + slot = "armor" + }, -- pair of old bracers + { + itemid = 37471, + type = "equip", + slot = "ring", + level = 200 + }, -- ring of souls + { + itemid = 37471, + type = "deequip", + slot = "ring", + level = 200 + }, -- ring of souls + { + itemid = 37470, + type = "equip", + slot = "ring", + level = 200 + }, -- ring of souls + { + itemid = 37470, + type = "deequip", + slot = "ring", + level = 200 + }, -- ring of souls + { + itemid = 37465, + type = "equip", + slot = "head" + }, -- spooky hood + { + itemid = 37465, + type = "deequip", + slot = "head" + }, -- spooky hood + { + itemid = 37463, + type = "equip", + slot = "armor", + level = 230, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- ghost chestplate + { + itemid = 37463, + type = "deequip", + slot = "armor", + level = 230 + }, -- ghost chestplate + { + itemid = 37456, + type = "equip", + slot = "ring", + level = 200 + }, -- ring of souls + { + itemid = 37456, + type = "deequip", + slot = "ring", + level = 200 + }, -- ring of souls + { + itemid = 37455, + type = "equip", + slot = "backpack" + }, -- ghost backpack + { + itemid = 37455, + type = "deequip", + slot = "backpack" + }, -- ghost backpack + { + itemid = 37454, + type = "equip", + slot = "feet", + level = 140, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- pair of nightmare boots + { + itemid = 37454, + type = "deequip", + slot = "feet", + level = 140 + }, -- pair of nightmare boots + { + itemid = 37453, + type = "equip", + slot = "legs", + level = 180, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- soulful legs + { + itemid = 37453, + type = "deequip", + slot = "legs", + level = 180 + }, -- soulful legs + { + itemid = 37452, + type = "equip", + slot = "legs", + level = 225, + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- fabulous legs + { + itemid = 37452, + type = "deequip", + slot = "legs", + level = 225 + }, -- fabulous legs + { + itemid = 37451, + type = "equip", + slot = "hand" + }, -- phantasmal axe + { + itemid = 37451, + type = "deequip", + slot = "hand" + }, -- phantasmal axe + { + itemid = 37420, + type = "equip", + slot = "armor" + }, -- burial shroud + { + itemid = 37420, + type = "deequip", + slot = "armor" + }, -- burial shroud + { + itemid = 36928, + type = "equip", + slot = "hand", + }, -- meat hammer + { + itemid = 36928, + type = "deequip", + slot = "hand", + }, -- meat hammer + { + itemid = 36511, + type = "equip", + slot = "necklace", + }, -- note about two souls + { + itemid = 36511, + type = "deequip", + slot = "necklace", + }, -- note about two souls + { + itemid = 36466, + type = "equip", + slot = "necklace", + level = 250, + }, -- the cobra amulet + { + itemid = 36466, + type = "deequip", + slot = "necklace", + level = 250, + }, -- the cobra amulet + { + itemid = 36460, + type = "equip", + slot = "backpack", + }, -- winged backpack + { + itemid = 36460, + type = "deequip", + slot = "backpack", + }, -- winged backpack + { + itemid = 36456, + type = "equip", + slot = "ring", + level = 220, + }, -- blister ring + { + itemid = 36456, + type = "deequip", + slot = "ring", + level = 220, + }, -- blister ring + { + itemid = 36452, + type = "equip", + slot = "feet", + level = 220, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + }, + }, -- winged boots + { + itemid = 36452, + type = "deequip", + slot = "feet", + level = 220, + }, -- winged boots + { + itemid = 36451, + type = "equip", + slot = "ring", + level = 220, + }, -- blister ring + { + itemid = 36451, + type = "deequip", + slot = "ring", + level = 220, + }, -- blister ring + { + itemid = 36449, + type = "equip", + slot = "hand", + }, -- tagralt blade + { + itemid = 36449, + type = "deequip", + slot = "hand", + }, -- tagralt blade + { + itemid = 36418, + type = "equip", + slot = "armor", + level = 220, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + }, + }, -- toga mortis + { + itemid = 36418, + type = "deequip", + slot = "armor", + level = 220, + }, -- toga mortis + { + itemid = 36417, + type = "equip", + slot = "head", + level = 220, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + }, + }, -- galea mortis + { + itemid = 36417, + type = "deequip", + slot = "head", + level = 220 + }, -- galea mortis + { + itemid = 36416, + type = "equip", + slot = "hand", + }, -- bow of cataclysm + { + itemid = 36416, + type = "deequip", + slot = "hand", + }, -- bow of cataclysm + { + itemid = 36415, + type = "equip", + slot = "hand", + }, -- mortal mace + { + itemid = 36415, + type = "deequip", + slot = "hand", + }, -- mortal mace + { + itemid = 36414, + type = "equip", + slot = "armor", + level = 220, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + }, + }, -- embrace of nature + { + itemid = 36414, + type = "deequip", + slot = "armor", + level = 220, + }, -- embrace of nature + { + itemid = 36413, + type = "equip", + slot = "armor", + level = 230, + vocation = { + {"Druid", true}, + {"Elder Druid"} + }, + }, -- bear skin + { + itemid = 36413, + type = "deequip", + slot = "armor", + level = 230, + }, -- bear skin + { + itemid = 36412, + type = "equip", + slot = "head", + level = 230, + vocation = { + {"Knight", true}, + {"Elite Knight"} + }, + }, -- terra helmet + { + itemid = 36412, + type = "deequip", + slot = "head", + level = 230, + }, -- terra helmet + { + itemid = 36392, + type = "equip", + slot = "ring", + level = 220, + }, -- blister ring + { + itemid = 36392, + type = "deequip", + slot = "ring", + level = 220, + }, -- blister ring + { + itemid = 36391, + type = "equip", + slot = "necklace", + level = 220, + }, -- rainbow amulet + { + itemid = 36391, + type = "deequip", + slot = "necklace", + level = 220, + }, -- rainbow amulet + { + itemid = 36273, + type = "equip", + slot = "head", + }, -- sphinx tiara + { + itemid = 36273, + type = "deequip", + slot = "head", + }, -- sphinx tiara + { + itemid = 36268, + type = "equip", + slot = "head", + }, -- gryphon mask + { + itemid = 36268, + type = "deequip", + slot = "head", + }, -- gryphon mask + { + itemid = 36266, + type = "equip", + slot = "ring", + }, -- symbol of sun and sea + { + itemid = 36266, + type = "deequip", + slot = "ring", + }, -- symbol of sun and sea + { + itemid = 36205, + type = "equip", + slot = "head", + }, -- silver mask + { + itemid = 36205, + type = "deequip", + slot = "head", + }, -- silver mask + { + itemid = 36141, + type = "equip", + slot = "ring", + }, -- ring of secret thoughts + { + itemid = 36141, + type = "deequip", + slot = "ring", + }, -- ring of secret thoughts + { + itemid = 36103, + type = "equip", + slot = "necklace", + }, -- jade amulet + { + itemid = 36103, + type = "deequip", + slot = "necklace", + }, -- jade amulet + { + itemid = 36098, + type = "equip", + slot = "ring", + }, -- ring of secret thoughts + { + itemid = 36098, + type = "deequip", + slot = "ring", + }, -- ring of secret thoughts + { + itemid = 35238, + type = "equip", + slot = "necklace", + level = 220, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + }, + }, -- amulet of theurgy + { + itemid = 35238, + type = "deequip", + slot = "necklace", + level = 220, + }, -- amulet of theurgy + { + itemid = 35237, + type = "equip", + slot = "necklace", + level = 220, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + }, + }, -- enchanted theurgic amulet + { + itemid = 35237, + type = "deequip", + slot = "necklace", + level = 220, + }, -- enchanted theurgic amulet + { + itemid = 35236, + type = "equip", + slot = "necklace", + level = 220, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + }, + }, -- amulet of theurgy + { + itemid = 35236, + type = "deequip", + slot = "necklace", + level = 220, + }, -- amulet of theurgy + { + itemid = 35235, + type = "equip", + slot = "hand", + level = 220, + vocation = { + {"Druid", true}, + {"Elder Druid"} + }, + }, -- cobra rod + { + itemid = 35235, + type = "deequip", + slot = "hand", + level = 220, + }, -- cobra rod + { + itemid = 35234, + type = "equip", + slot = "hand", + level = 270, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + }, + }, -- cobra wand + { + itemid = 35234, + type = "deequip", + slot = "hand", + level = 270, + }, -- cobra wand + { + itemid = 35233, + type = "equip", + slot = "hand", + }, -- cobra sword + { + itemid = 35233, + type = "deequip", + slot = "hand", + }, -- cobra sword + { + itemid = 35232, + type = "equip", + slot = "head", + level = 270, + vocation = { + {"Knight", true}, + {"Elite Knight"} + }, + }, -- cobra hood + { + itemid = 35232, + type = "deequip", + slot = "head", + level = 270, + }, -- cobra hood + { + itemid = 35231, + type = "equip", + slot = "hand", + }, -- cobra axe + { + itemid = 35231, + type = "deequip", + slot = "hand", + }, -- cobra axe + { + itemid = 35230, + type = "equip", + slot = "hand", + }, -- cobra club + { + itemid = 35230, + type = "deequip", + slot = "hand", + }, -- cobra club + { + itemid = 35229, + type = "equip", + slot = "feet", + level = 220, + vocation = { + {"Knight", true}, + {"Elite Knight"} + }, + }, -- cobra boots + { + itemid = 35229, + type = "deequip", + slot = "feet", + level = 220, + }, -- cobra boots + { + itemid = 35228, + type = "equip", + slot = "hand", + }, -- cobra crossbow + { + itemid = 35228, + type = "deequip", + slot = "hand", + }, -- cobra crossbow + { + itemid = 35150, + type = "equip", + slot = "necklace", + level = 220 + }, -- rainbow necklace + { + itemid = 35150, + type = "deequip", + slot = "necklace", + level = 220 + }, -- rainbow necklace + { + itemid = 35112, + type = "equip", + slot = "hand" + }, -- ice hatchet + { + itemid = 35112, + type = "deequip", + slot = "hand" + }, -- ice hatchet + { + itemid = 35108, + type = "equip", + slot = "ring" + }, -- frozen claw + { + itemid = 35108, + type = "deequip", + slot = "ring" + }, -- frozen claw + { + itemid = 35105, + type = "equip", + slot = "head" + }, -- the crown of the percht queen + { + itemid = 35105, + type = "deequip", + slot = "head" + }, -- the crown of the percht queen + { + itemid = 35104, + type = "equip", + slot = "head" + }, -- the crown of the percht queen + { + itemid = 35104, + type = "deequip", + slot = "head" + }, -- the crown of the percht queen + { + itemid = 35056, + type = "equip", + slot = "backpack" + }, -- festive backpack + { + itemid = 35056, + type = "deequip", + slot = "backpack" + }, -- festive backpack + { + itemid = 35055, + type = "equip", + slot = "feet" + }, -- yetislippers + { + itemid = 35055, + type = "deequip", + slot = "feet" + }, -- yetislippers + { + itemid = 34983, + type = "equip", + slot = "necklace", + level = 180, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- pendulet + { + itemid = 34983, + type = "deequip", + slot = "necklace", + level = 180 + }, -- pendulet + { + itemid = 34982, + type = "equip", + slot = "necklace", + level = 180, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- enchanted pendulet + { + itemid = 34982, + type = "deequip", + slot = "necklace", + level = 180 + }, -- enchanted pendulet + { + itemid = 34981, + type = "equip", + slot = "necklace", + level = 180, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- sleep shawl + { + itemid = 34981, + type = "deequip", + slot = "necklace", + level = 180 + }, -- sleep shawl + { + itemid = 34980, + type = "equip", + slot = "necklace", + level = 180, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- enchanted sleep shawl + { + itemid = 34980, + type = "deequip", + slot = "necklace", + level = 180 + }, -- enchanted sleep shawl + { + itemid = 34819, + type = "equip", + slot = "shield" + }, -- shield of endless search + { + itemid = 34819, + type = "deequip", + slot = "shield" + }, -- shield of endless search + { + itemid = 34069, + type = "equip", + slot = "shield", + level = 180, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- spirit guide + { + itemid = 34069, + type = "deequip", + slot = "shield", + level = 180 + }, -- spirit guide + { + itemid = 34068, + type = "equip", + slot = "shield", + level = 180, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- ectoplasmic shield + { + itemid = 34068, + type = "deequip", + slot = "shield", + level = 180 + }, -- ectoplasmic shield + { + itemid = 34067, + type = "equip", + slot = "necklace", + level = 180, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- pendulet + { + itemid = 34067, + type = "deequip", + slot = "necklace", + level = 180 + }, -- pendulet + { + itemid = 34066, + type = "equip", + slot = "necklace", + level = 180, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- sleep shawl + { + itemid = 34066, + type = "deequip", + slot = "necklace", + level = 180 + }, -- sleep shawl + { + itemid = 34065, + type = "equip", + slot = "head", + level = 180, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- dark whispers + { + itemid = 34065, + type = "deequip", + slot = "head", + level = 180 + }, -- dark whispers + { + itemid = 34064, + type = "equip", + slot = "shield", + level = 180, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- brain in a jar + { + itemid = 34064, + type = "deequip", + slot = "shield", + level = 180 + }, -- brain in a jar + { + itemid = 34063, + type = "equip", + slot = "hand", + level = 180, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- energized limb + { + itemid = 34063, + type = "deequip", + slot = "hand", + level = 180 + }, -- energized limb + { + itemid = 34062, + type = "equip", + slot = "feet", + level = 180, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- pair of dreamwalkers + { + itemid = 34062, + type = "deequip", + slot = "feet", + level = 180 + }, -- pair of dreamwalkers + { + itemid = 34061, + type = "equip", + slot = "armor", + level = 180, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- dream shroud + { + itemid = 34061, + type = "deequip", + slot = "armor", + level = 180 + }, -- dream shroud + { + itemid = 34060, + type = "equip", + slot = "hand" + }, -- winterblade + { + itemid = 34060, + type = "deequip", + slot = "hand" + }, -- winterblade + { + itemid = 34059, + type = "equip", + slot = "hand" + }, -- summerblade + { + itemid = 34059, + type = "deequip", + slot = "hand" + }, -- summerblade + { + itemid = 34058, + type = "equip", + slot = "shield", + level = 180, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- shoulder plate + { + itemid = 34058, + type = "deequip", + slot = "shield", + level = 180 + }, -- shoulder plate + { + itemid = 34057, + type = "equip", + slot = "hand" + }, -- resizer + { + itemid = 34057, + type = "deequip", + slot = "hand" + }, -- resizer + { + itemid = 34056, + type = "equip", + slot = "armor", + level = 180, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- living armor + { + itemid = 34056, + type = "deequip", + slot = "armor", + level = 180 + }, -- living armor + { + itemid = 34055, + type = "equip", + slot = "hand" + }, -- living vine bow + { + itemid = 34055, + type = "deequip", + slot = "hand" + }, -- living vine bow + { + itemid = 33925, + type = "equip", + slot = "hand" + }, -- golden axe + { + itemid = 33925, + type = "deequip", + slot = "hand" + }, -- golden axe + { + itemid = 33552, + type = "equip", + slot = "shield" + }, -- mathmaster shield (souvenir) + { + itemid = 33552, + type = "deequip", + slot = "shield" + }, -- mathmaster shield (souvenir) + { + itemid = 33318, + type = "equip", + slot = "backpack" + }, -- book backpack + { + itemid = 33318, + type = "deequip", + slot = "backpack" + }, -- book backpack + { + itemid = 33267, + type = "equip", + slot = "hand" + }, -- wand of destruction test + { + itemid = 33267, + type = "deequip", + slot = "hand" + }, -- wand of destruction test + { + itemid = 33266, + type = "equip", + slot = "hand" + }, -- umbral master bow test + { + itemid = 33266, + type = "deequip", + slot = "hand" + }, -- umbral master bow test + { + itemid = 33263, + type = "equip", + slot = "armor" + }, -- ornate testtplate + { + itemid = 33263, + type = "deequip", + slot = "armor" + }, -- ornate testtplate + { + itemid = 33254, + type = "equip", + slot = "hand" + }, -- sorcerer test weapon + { + itemid = 33254, + type = "deequip", + slot = "hand" + }, -- sorcerer test weapon + { + itemid = 33253, + type = "equip", + slot = "hand" + }, -- bow of destruction test + { + itemid = 33253, + type = "deequip", + slot = "hand" + }, -- bow of destruction test + { + itemid = 33252, + type = "equip", + slot = "hand" + }, -- test weapon for knights + { + itemid = 33252, + type = "deequip", + slot = "hand" + }, -- test weapon for knights + { + itemid = 32529, + type = "equip", + slot = "hand" + }, -- sulphurous demonbone + { + itemid = 32529, + type = "deequip", + slot = "hand" + }, -- sulphurous demonbone + { + itemid = 32528, + type = "equip", + slot = "hand" + }, -- unliving demonbone + { + itemid = 32528, + type = "deequip", + slot = "hand" + }, -- unliving demonbone + { + itemid = 32527, + type = "equip", + slot = "hand" + }, -- energized demonbone + { + itemid = 32527, + type = "deequip", + slot = "hand" + }, -- energized demonbone + { + itemid = 32526, + type = "equip", + slot = "hand" + }, -- rotten demonbone + { + itemid = 32526, + type = "deequip", + slot = "hand" + }, -- rotten demonbone + { + itemid = 32523, + type = "equip", + slot = "hand", + level = 230, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- deepling fork + { + itemid = 32523, + type = "deequip", + slot = "hand", + level = 230 + }, -- deepling fork + { + itemid = 32522, + type = "equip", + slot = "hand", + level = 180, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- deepling ceremonial dagger + { + itemid = 32522, + type = "deequip", + slot = "hand", + level = 180 + }, -- deepling ceremonial dagger + { + itemid = 32425, + type = "equip", + slot = "hand" + }, -- falcon mace + { + itemid = 32425, + type = "deequip", + slot = "hand" + }, -- falcon mace + { + itemid = 32424, + type = "equip", + slot = "hand" + }, -- falcon battleaxe + { + itemid = 32424, + type = "deequip", + slot = "hand" + }, -- falcon battleaxe + { + itemid = 32423, + type = "equip", + slot = "hand" + }, -- falcon longsword + { + itemid = 32423, + type = "deequip", + slot = "hand" + }, -- falcon longsword + { + itemid = 32422, + type = "equip", + slot = "shield", + level = 300, + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- falcon escutcheon + { + itemid = 32422, + type = "deequip", + slot = "shield", + level = 300 + }, -- falcon escutcheon + { + itemid = 32421, + type = "equip", + slot = "shield", + level = 300, + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- falcon shield + { + itemid = 32421, + type = "deequip", + slot = "shield", + level = 300 + }, -- falcon shield + { + itemid = 32420, + type = "equip", + slot = "legs", + level = 300, + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- falcon greaves + { + itemid = 32420, + type = "deequip", + slot = "legs", + level = 300 + }, -- falcon greaves + { + itemid = 32419, + type = "equip", + slot = "armor", + level = 300, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- falcon plate + { + itemid = 32419, + type = "deequip", + slot = "armor", + level = 300 + }, -- falcon plate + { + itemid = 32418, + type = "equip", + slot = "hand" + }, -- falcon bow + { + itemid = 32418, + type = "deequip", + slot = "hand" + }, -- falcon bow + { + itemid = 32417, + type = "equip", + slot = "hand", + level = 300, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- falcon wand + { + itemid = 32417, + type = "deequip", + slot = "hand", + level = 300 + }, -- falcon wand + { + itemid = 32416, + type = "equip", + slot = "hand", + level = 300, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- falcon rod + { + itemid = 32416, + type = "deequip", + slot = "hand", + level = 300 + }, -- falcon rod + { + itemid = 32415, + type = "equip", + slot = "head", + level = 300, + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- falcon coif + { + itemid = 32415, + type = "deequip", + slot = "head", + level = 300 + }, -- falcon coif + { + itemid = 32414, + type = "equip", + slot = "head", + level = 300, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- falcon circlet + { + itemid = 32414, + type = "deequip", + slot = "head", + level = 300 + }, -- falcon circlet + { + itemid = 32078, + type = "equip", + slot = "shield" + }, -- silver chimes + { + itemid = 32078, + type = "deequip", + slot = "shield" + }, -- silver chimes + { + itemid = 30888, + type = "equip", + slot = "necklace" + }, -- suspicious device + { + itemid = 30888, + type = "deequip", + slot = "necklace" + }, -- suspicious device + { + itemid = 30886, + type = "equip", + slot = "hand" + }, -- gnome sword + { + itemid = 30886, + type = "deequip", + slot = "hand" + }, -- gnome sword + { + itemid = 30885, + type = "equip", + slot = "shield", + level = 200, + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Royal Paladin"}, + {"Elite Knight"} + } + }, -- gnome shield + { + itemid = 30885, + type = "deequip", + slot = "shield", + level = 200 + }, -- gnome shield + { + itemid = 30884, + type = "equip", + slot = "legs", + level = 200, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- gnome legs + { + itemid = 30884, + type = "deequip", + slot = "legs", + level = 200 + }, -- gnome legs + { + itemid = 30883, + type = "equip", + slot = "armor", + level = 200, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- gnome armor + { + itemid = 30883, + type = "deequip", + slot = "armor", + level = 200 + }, -- gnome armor + { + itemid = 30882, + type = "equip", + slot = "head", + level = 200, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- gnome helmet + { + itemid = 30882, + type = "deequip", + slot = "head", + level = 200 + }, -- gnome helmet + { + itemid = 30800, + type = "equip", + slot = "necklace", + level = 100 + }, -- foxtail amulet + { + itemid = 30800, + type = "deequip", + slot = "necklace", + level = 100 + }, -- foxtail amulet + { + itemid = 30760, + type = "equip", + slot = "hand" + }, -- mallet handle + { + itemid = 30760, + type = "deequip", + slot = "hand" + }, -- mallet handle + { + itemid = 30758, + type = "equip", + slot = "hand" + }, -- strange mallet + { + itemid = 30758, + type = "deequip", + slot = "hand" + }, -- strange mallet + { + itemid = 30757, + type = "equip", + slot = "head" + }, -- blue spectacles + { + itemid = 30757, + type = "deequip", + slot = "head" + }, -- blue spectacles + { + itemid = 30693, + type = "equip", + slot = "hand", + level = 200, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- rod of destruction + { + itemid = 30693, + type = "deequip", + slot = "hand", + level = 200 + }, -- rod of destruction + { + itemid = 30692, + type = "equip", + slot = "hand", + level = 200, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of destruction + { + itemid = 30692, + type = "deequip", + slot = "hand", + level = 200 + }, -- wand of destruction + { + itemid = 30691, + type = "equip", + slot = "hand" + }, -- crossbow of destruction + { + itemid = 30691, + type = "deequip", + slot = "hand" + }, -- crossbow of destruction + { + itemid = 30690, + type = "equip", + slot = "hand" + }, -- bow of destruction + { + itemid = 30690, + type = "deequip", + slot = "hand" + }, -- bow of destruction + { + itemid = 30689, + type = "equip", + slot = "hand" + }, -- hammer of destruction + { + itemid = 30689, + type = "deequip", + slot = "hand" + }, -- hammer of destruction + { + itemid = 30688, + type = "equip", + slot = "hand" + }, -- mace of destruction + { + itemid = 30688, + type = "deequip", + slot = "hand" + }, -- mace of destruction + { + itemid = 30687, + type = "equip", + slot = "hand" + }, -- chopper of destruction + { + itemid = 30687, + type = "deequip", + slot = "hand" + }, -- chopper of destruction + { + itemid = 30686, + type = "equip", + slot = "hand" + }, -- axe of destruction + { + itemid = 30686, + type = "deequip", + slot = "hand" + }, -- axe of destruction + { + itemid = 30685, + type = "equip", + slot = "hand" + }, -- slayer of destruction + { + itemid = 30685, + type = "deequip", + slot = "hand" + }, -- slayer of destruction + { + itemid = 30684, + type = "equip", + slot = "hand" + }, -- blade of destruction + { + itemid = 30684, + type = "deequip", + slot = "hand" + }, -- blade of destruction + { + itemid = 30183, + type = "equip", + slot = "shield" + }, -- Journal Shield + { + itemid = 30183, + type = "deequip", + slot = "shield" + }, -- Journal Shield + { + itemid = 29426, + type = "equip", + slot = "head" + }, -- reflecting crown + { + itemid = 29426, + type = "deequip", + slot = "head" + }, -- reflecting crown + { + itemid = 29425, + type = "equip", + slot = "head" + }, -- incandescent crown + { + itemid = 29425, + type = "deequip", + slot = "head" + }, -- incandescent crown + { + itemid = 29424, + type = "equip", + slot = "head" + }, -- iron crown + { + itemid = 29424, + type = "deequip", + slot = "head" + }, -- iron crown + { + itemid = 29423, + type = "equip", + slot = "head" + }, -- leaf crown + { + itemid = 29423, + type = "deequip", + slot = "head" + }, -- leaf crown + { + itemid = 29297, + type = "equip", + slot = "hand" + }, -- ornate carving hammer + { + itemid = 29297, + type = "deequip", + slot = "hand" + }, -- ornate carving hammer + { + itemid = 29296, + type = "equip", + slot = "hand" + }, -- valuable carving hammer + { + itemid = 29296, + type = "deequip", + slot = "hand" + }, -- valuable carving hammer + { + itemid = 29295, + type = "equip", + slot = "hand" + }, -- plain carving hammer + { + itemid = 29295, + type = "deequip", + slot = "hand" + }, -- plain carving hammer + { + itemid = 29294, + type = "equip", + slot = "hand" + }, -- ornate carving mace + { + itemid = 29294, + type = "deequip", + slot = "hand" + }, -- ornate carving mace + { + itemid = 29293, + type = "equip", + slot = "hand" + }, -- valuable carving mace + { + itemid = 29293, + type = "deequip", + slot = "hand" + }, -- valuable carving mace + { + itemid = 29292, + type = "equip", + slot = "hand" + }, -- plain carving mace + { + itemid = 29292, + type = "deequip", + slot = "hand" + }, -- plain carving mace + { + itemid = 29291, + type = "equip", + slot = "hand" + }, -- ornate carving chopper + { + itemid = 29291, + type = "deequip", + slot = "hand" + }, -- ornate carving chopper + { + itemid = 29290, + type = "equip", + slot = "hand" + }, -- valuable carving chopper + { + itemid = 29290, + type = "deequip", + slot = "hand" + }, -- valuable carving chopper + { + itemid = 29289, + type = "equip", + slot = "hand" + }, -- plain carving chopper + { + itemid = 29289, + type = "deequip", + slot = "hand" + }, -- plain carving chopper + { + itemid = 29288, + type = "equip", + slot = "hand" + }, -- ornate carving axe + { + itemid = 29288, + type = "deequip", + slot = "hand" + }, -- ornate carving axe + { + itemid = 29287, + type = "equip", + slot = "hand" + }, -- valuable carving axe + { + itemid = 29287, + type = "deequip", + slot = "hand" + }, -- valuable carving axe + { + itemid = 29286, + type = "equip", + slot = "hand" + }, -- plain carving axe + { + itemid = 29286, + type = "deequip", + slot = "hand" + }, -- plain carving axe + { + itemid = 29285, + type = "equip", + slot = "hand" + }, -- ornate carving slayer + { + itemid = 29285, + type = "deequip", + slot = "hand" + }, -- ornate carving slayer + { + itemid = 29284, + type = "equip", + slot = "hand" + }, -- valuable carving slayer + { + itemid = 29284, + type = "deequip", + slot = "hand" + }, -- valuable carving slayer + { + itemid = 29283, + type = "equip", + slot = "hand" + }, -- plain carving slayer + { + itemid = 29283, + type = "deequip", + slot = "hand" + }, -- plain carving slayer + { + itemid = 29282, + type = "equip", + slot = "hand" + }, -- ornate carving blade + { + itemid = 29282, + type = "deequip", + slot = "hand" + }, -- ornate carving blade + { + itemid = 29281, + type = "equip", + slot = "hand" + }, -- valuable carving blade + { + itemid = 29281, + type = "deequip", + slot = "hand" + }, -- valuable carving blade + { + itemid = 29280, + type = "equip", + slot = "hand" + }, -- plain carving blade + { + itemid = 29280, + type = "deequip", + slot = "hand" + }, -- plain carving blade + { + itemid = 29267, + type = "equip", + slot = "hand" + }, -- ornate remedy hammer + { + itemid = 29267, + type = "deequip", + slot = "hand" + }, -- ornate remedy hammer + { + itemid = 29266, + type = "equip", + slot = "hand" + }, -- valuable remedy hammer + { + itemid = 29266, + type = "deequip", + slot = "hand" + }, -- valuable remedy hammer + { + itemid = 29265, + type = "equip", + slot = "hand" + }, -- plain remedy hammer + { + itemid = 29265, + type = "deequip", + slot = "hand" + }, -- plain remedy hammer + { + itemid = 29264, + type = "equip", + slot = "hand" + }, -- ornate remedy mace + { + itemid = 29264, + type = "deequip", + slot = "hand" + }, -- ornate remedy mace + { + itemid = 29263, + type = "equip", + slot = "hand" + }, -- valuable remedy mace + { + itemid = 29263, + type = "deequip", + slot = "hand" + }, -- valuable remedy mace + { + itemid = 29262, + type = "equip", + slot = "hand" + }, -- plain remedy mace + { + itemid = 29262, + type = "deequip", + slot = "hand" + }, -- plain remedy mace + { + itemid = 29261, + type = "equip", + slot = "hand" + }, -- ornate remedy chopper + { + itemid = 29261, + type = "deequip", + slot = "hand" + }, -- ornate remedy chopper + { + itemid = 29260, + type = "equip", + slot = "hand" + }, -- valuable remedy chopper + { + itemid = 29260, + type = "deequip", + slot = "hand" + }, -- valuable remedy chopper + { + itemid = 29259, + type = "equip", + slot = "hand" + }, -- plain remedy chopper + { + itemid = 29259, + type = "deequip", + slot = "hand" + }, -- plain remedy chopper + { + itemid = 29258, + type = "equip", + slot = "hand" + }, -- ornate remedy axe + { + itemid = 29258, + type = "deequip", + slot = "hand" + }, -- ornate remedy axe + { + itemid = 29257, + type = "equip", + slot = "hand" + }, -- valuable remedy axe + { + itemid = 29257, + type = "deequip", + slot = "hand" + }, -- valuable remedy axe + { + itemid = 29256, + type = "equip", + slot = "hand" + }, -- plain remedy axe + { + itemid = 29256, + type = "deequip", + slot = "hand" + }, -- plain remedy axe + { + itemid = 29255, + type = "equip", + slot = "hand" + }, -- ornate remedy slayer + { + itemid = 29255, + type = "deequip", + slot = "hand" + }, -- ornate remedy slayer + { + itemid = 29254, + type = "equip", + slot = "hand" + }, -- valuable remedy slayer + { + itemid = 29254, + type = "deequip", + slot = "hand" + }, -- valuable remedy slayer + { + itemid = 29253, + type = "equip", + slot = "hand" + }, -- plain remedy slayer + { + itemid = 29253, + type = "deequip", + slot = "hand" + }, -- plain remedy slayer + { + itemid = 29252, + type = "equip", + slot = "hand" + }, -- ornate remedy blade + { + itemid = 29252, + type = "deequip", + slot = "hand" + }, -- ornate remedy blade + { + itemid = 29251, + type = "equip", + slot = "hand" + }, -- valuable remedy blade + { + itemid = 29251, + type = "deequip", + slot = "hand" + }, -- valuable remedy blade + { + itemid = 29250, + type = "equip", + slot = "hand" + }, -- plain remedy blade + { + itemid = 29250, + type = "deequip", + slot = "hand" + }, -- plain remedy blade + { + itemid = 29236, + type = "equip", + slot = "hand" + }, -- ornate mayhem hammer + { + itemid = 29236, + type = "deequip", + slot = "hand" + }, -- ornate mayhem hammer + { + itemid = 29235, + type = "equip", + slot = "hand" + }, -- valuable mayhem hammer + { + itemid = 29235, + type = "deequip", + slot = "hand" + }, -- valuable mayhem hammer + { + itemid = 29234, + type = "equip", + slot = "hand" + }, -- plain mayhem hammer + { + itemid = 29234, + type = "deequip", + slot = "hand" + }, -- plain mayhem hammer + { + itemid = 29233, + type = "equip", + slot = "hand" + }, -- ornate mayhem mace + { + itemid = 29233, + type = "deequip", + slot = "hand" + }, -- ornate mayhem mace + { + itemid = 29232, + type = "equip", + slot = "hand" + }, -- valuable mayhem mace + { + itemid = 29232, + type = "deequip", + slot = "hand" + }, -- valuable mayhem mace + { + itemid = 29231, + type = "equip", + slot = "hand" + }, -- plain mayhem mace + { + itemid = 29231, + type = "deequip", + slot = "hand" + }, -- plain mayhem mace + { + itemid = 29230, + type = "equip", + slot = "hand" + }, -- ornate mayhem chopper + { + itemid = 29230, + type = "deequip", + slot = "hand" + }, -- ornate mayhem chopper + { + itemid = 29229, + type = "equip", + slot = "hand" + }, -- valuable mayhem chopper + { + itemid = 29229, + type = "deequip", + slot = "hand" + }, -- valuable mayhem chopper + { + itemid = 29228, + type = "equip", + slot = "hand" + }, -- plain mayhem chopper + { + itemid = 29228, + type = "deequip", + slot = "hand" + }, -- plain mayhem chopper + { + itemid = 29227, + type = "equip", + slot = "hand" + }, -- ornate mayhem axe + { + itemid = 29227, + type = "deequip", + slot = "hand" + }, -- ornate mayhem axe + { + itemid = 29226, + type = "equip", + slot = "hand" + }, -- valuable mayhem axe + { + itemid = 29226, + type = "deequip", + slot = "hand" + }, -- valuable mayhem axe + { + itemid = 29225, + type = "equip", + slot = "hand" + }, -- plain mayhem axe + { + itemid = 29225, + type = "deequip", + slot = "hand" + }, -- plain mayhem axe + { + itemid = 29224, + type = "equip", + slot = "hand" + }, -- ornate mayhem slayer + { + itemid = 29224, + type = "deequip", + slot = "hand" + }, -- ornate mayhem slayer + { + itemid = 29223, + type = "equip", + slot = "hand" + }, -- valuable mayhem slayer + { + itemid = 29223, + type = "deequip", + slot = "hand" + }, -- valuable mayhem slayer + { + itemid = 29222, + type = "equip", + slot = "hand" + }, -- plain mayhem slayer + { + itemid = 29222, + type = "deequip", + slot = "hand" + }, -- plain mayhem slayer + { + itemid = 29221, + type = "equip", + slot = "hand" + }, -- ornate mayhem blade + { + itemid = 29221, + type = "deequip", + slot = "hand" + }, -- ornate mayhem blade + { + itemid = 29220, + type = "equip", + slot = "hand" + }, -- valuable mayhem blade + { + itemid = 29220, + type = "deequip", + slot = "hand" + }, -- valuable mayhem blade + { + itemid = 29219, + type = "equip", + slot = "hand" + }, -- plain mayhem blade + { + itemid = 29219, + type = "deequip", + slot = "hand" + }, -- plain mayhem blade + { + itemid = 29218, + type = "equip", + slot = "shield" + }, -- mathmaster shield (souvenir) + { + itemid = 29218, + type = "deequip", + slot = "shield" + }, -- mathmaster shield (souvenir) + { + itemid = 29210, + type = "equip", + slot = "hand" + }, -- energy war hammer replica + { + itemid = 29210, + type = "deequip", + slot = "hand" + }, -- energy war hammer replica + { + itemid = 29209, + type = "equip", + slot = "hand" + }, -- energy orcish maul replica + { + itemid = 29209, + type = "deequip", + slot = "hand" + }, -- energy orcish maul replica + { + itemid = 29208, + type = "equip", + slot = "hand" + }, -- energy basher replica + { + itemid = 29208, + type = "deequip", + slot = "hand" + }, -- energy basher replica + { + itemid = 29207, + type = "equip", + slot = "hand" + }, -- energy crystal mace replica + { + itemid = 29207, + type = "deequip", + slot = "hand" + }, -- energy crystal mace replica + { + itemid = 29206, + type = "equip", + slot = "hand" + }, -- energy clerical mace replica + { + itemid = 29206, + type = "deequip", + slot = "hand" + }, -- energy clerical mace replica + { + itemid = 29205, + type = "equip", + slot = "hand" + }, -- energy war axe replica + { + itemid = 29205, + type = "deequip", + slot = "hand" + }, -- energy war axe replica + { + itemid = 29204, + type = "equip", + slot = "hand" + }, -- energy headchopper replica + { + itemid = 29204, + type = "deequip", + slot = "hand" + }, -- energy headchopper replica + { + itemid = 29203, + type = "equip", + slot = "hand" + }, -- energy heroic axe replica + { + itemid = 29203, + type = "deequip", + slot = "hand" + }, -- energy heroic axe replica + { + itemid = 29202, + type = "equip", + slot = "hand" + }, -- energy knight axe replica + { + itemid = 29202, + type = "deequip", + slot = "hand" + }, -- energy knight axe replica + { + itemid = 29201, + type = "equip", + slot = "hand" + }, -- energy barbarian axe replica + { + itemid = 29201, + type = "deequip", + slot = "hand" + }, -- energy barbarian axe replica + { + itemid = 29200, + type = "equip", + slot = "hand" + }, -- energy dragon slayer replica + { + itemid = 29200, + type = "deequip", + slot = "hand" + }, -- energy dragon slayer replica + { + itemid = 29199, + type = "equip", + slot = "hand" + }, -- energy blacksteel replica + { + itemid = 29199, + type = "deequip", + slot = "hand" + }, -- energy blacksteel replica + { + itemid = 29198, + type = "equip", + slot = "hand" + }, -- energy mystic blade replica + { + itemid = 29198, + type = "deequip", + slot = "hand" + }, -- energy mystic blade replica + { + itemid = 29197, + type = "equip", + slot = "hand" + }, -- energy relic sword replica + { + itemid = 29197, + type = "deequip", + slot = "hand" + }, -- energy relic sword replica + { + itemid = 29196, + type = "equip", + slot = "hand" + }, -- energy spike sword replica + { + itemid = 29196, + type = "deequip", + slot = "hand" + }, -- energy spike sword replica + { + itemid = 29195, + type = "equip", + slot = "hand" + }, -- earth war hammer replica + { + itemid = 29195, + type = "deequip", + slot = "hand" + }, -- earth war hammer replica + { + itemid = 29194, + type = "equip", + slot = "hand" + }, -- earth orcish maul replica + { + itemid = 29194, + type = "deequip", + slot = "hand" + }, -- earth orcish maul replica + { + itemid = 29193, + type = "equip", + slot = "hand" + }, -- earth basher replica + { + itemid = 29193, + type = "deequip", + slot = "hand" + }, -- earth basher replica + { + itemid = 29192, + type = "equip", + slot = "hand" + }, -- earth crystal mace replica + { + itemid = 29192, + type = "deequip", + slot = "hand" + }, -- earth crystal mace replica + { + itemid = 29191, + type = "equip", + slot = "hand" + }, -- earth clerical mace replica + { + itemid = 29191, + type = "deequip", + slot = "hand" + }, -- earth clerical mace replica + { + itemid = 29190, + type = "equip", + slot = "hand" + }, -- earth war axe replica + { + itemid = 29190, + type = "deequip", + slot = "hand" + }, -- earth war axe replica + { + itemid = 29189, + type = "equip", + slot = "hand" + }, -- earth headchopper replica + { + itemid = 29189, + type = "deequip", + slot = "hand" + }, -- earth headchopper replica + { + itemid = 29188, + type = "equip", + slot = "hand" + }, -- earth heroic axe replica + { + itemid = 29188, + type = "deequip", + slot = "hand" + }, -- earth heroic axe replica + { + itemid = 29187, + type = "equip", + slot = "hand" + }, -- earth knight axe replica + { + itemid = 29187, + type = "deequip", + slot = "hand" + }, -- earth knight axe replica + { + itemid = 29186, + type = "equip", + slot = "hand" + }, -- earth barbarian axe replica + { + itemid = 29186, + type = "deequip", + slot = "hand" + }, -- earth barbarian axe replica + { + itemid = 29185, + type = "equip", + slot = "hand" + }, -- earth dragon slayer replica + { + itemid = 29185, + type = "deequip", + slot = "hand" + }, -- earth dragon slayer replica + { + itemid = 29184, + type = "equip", + slot = "hand" + }, -- earth blacksteel replica + { + itemid = 29184, + type = "deequip", + slot = "hand" + }, -- earth blacksteel replica + { + itemid = 29183, + type = "equip", + slot = "hand" + }, -- earth mystic blade replica + { + itemid = 29183, + type = "deequip", + slot = "hand" + }, -- earth mystic blade replica + { + itemid = 29182, + type = "equip", + slot = "hand" + }, -- earth relic sword replica + { + itemid = 29182, + type = "deequip", + slot = "hand" + }, -- earth relic sword replica + { + itemid = 29181, + type = "equip", + slot = "hand" + }, -- earth spike sword replica + { + itemid = 29181, + type = "deequip", + slot = "hand" + }, -- earth spike sword replica + { + itemid = 29180, + type = "equip", + slot = "hand" + }, -- icy war hammer replica + { + itemid = 29180, + type = "deequip", + slot = "hand" + }, -- icy war hammer replica + { + itemid = 29179, + type = "equip", + slot = "hand" + }, -- icy orcish maul replica + { + itemid = 29179, + type = "deequip", + slot = "hand" + }, -- icy orcish maul replica + { + itemid = 29178, + type = "equip", + slot = "hand" + }, -- icy basher replica + { + itemid = 29178, + type = "deequip", + slot = "hand" + }, -- icy basher replica + { + itemid = 29177, + type = "equip", + slot = "hand" + }, -- icy crystal mace replica + { + itemid = 29177, + type = "deequip", + slot = "hand" + }, -- icy crystal mace replica + { + itemid = 29176, + type = "equip", + slot = "hand" + }, -- icy clerical mace replica + { + itemid = 29176, + type = "deequip", + slot = "hand" + }, -- icy clerical mace replica + { + itemid = 29175, + type = "equip", + slot = "hand" + }, -- icy war axe replica + { + itemid = 29175, + type = "deequip", + slot = "hand" + }, -- icy war axe replica + { + itemid = 29174, + type = "equip", + slot = "hand" + }, -- icy headchopper replica + { + itemid = 29174, + type = "deequip", + slot = "hand" + }, -- icy headchopper replica + { + itemid = 29173, + type = "equip", + slot = "hand" + }, -- icy heroic axe replica + { + itemid = 29173, + type = "deequip", + slot = "hand" + }, -- icy heroic axe replica + { + itemid = 29172, + type = "equip", + slot = "hand" + }, -- icy knight axe replica + { + itemid = 29172, + type = "deequip", + slot = "hand" + }, -- icy knight axe replica + { + itemid = 29171, + type = "equip", + slot = "hand" + }, -- icy barbarian axe replica + { + itemid = 29171, + type = "deequip", + slot = "hand" + }, -- icy barbarian axe replica + { + itemid = 29170, + type = "equip", + slot = "hand" + }, -- icy dragon slayer replica + { + itemid = 29170, + type = "deequip", + slot = "hand" + }, -- icy dragon slayer replica + { + itemid = 29169, + type = "equip", + slot = "hand" + }, -- icy blacksteel replica + { + itemid = 29169, + type = "deequip", + slot = "hand" + }, -- icy blacksteel replica + { + itemid = 29168, + type = "equip", + slot = "hand" + }, -- icy mystic blade replica + { + itemid = 29168, + type = "deequip", + slot = "hand" + }, -- icy mystic blade replica + { + itemid = 29167, + type = "equip", + slot = "hand" + }, -- icy relic sword replica + { + itemid = 29167, + type = "deequip", + slot = "hand" + }, -- icy relic sword replica + { + itemid = 29166, + type = "equip", + slot = "hand" + }, -- icy spike sword replica + { + itemid = 29166, + type = "deequip", + slot = "hand" + }, -- icy spike sword replica + { + itemid = 29165, + type = "equip", + slot = "hand" + }, -- fiery war hammer replica + { + itemid = 29165, + type = "deequip", + slot = "hand" + }, -- fiery war hammer replica + { + itemid = 29164, + type = "equip", + slot = "hand" + }, -- fiery orcish maul replica + { + itemid = 29164, + type = "deequip", + slot = "hand" + }, -- fiery orcish maul replica + { + itemid = 29163, + type = "equip", + slot = "hand" + }, -- fiery basher replica + { + itemid = 29163, + type = "deequip", + slot = "hand" + }, -- fiery basher replica + { + itemid = 29162, + type = "equip", + slot = "hand" + }, -- fiery crystal mace replica + { + itemid = 29162, + type = "deequip", + slot = "hand" + }, -- fiery crystal mace replica + { + itemid = 29161, + type = "equip", + slot = "hand" + }, -- fiery clerical mace replica + { + itemid = 29161, + type = "deequip", + slot = "hand" + }, -- fiery clerical mace replica + { + itemid = 29160, + type = "equip", + slot = "hand" + }, -- fiery war axe replica + { + itemid = 29160, + type = "deequip", + slot = "hand" + }, -- fiery war axe replica + { + itemid = 29159, + type = "equip", + slot = "hand" + }, -- fiery headchopper replica + { + itemid = 29159, + type = "deequip", + slot = "hand" + }, -- fiery headchopper replica + { + itemid = 29158, + type = "equip", + slot = "hand" + }, -- fiery heroic axe replica + { + itemid = 29158, + type = "deequip", + slot = "hand" + }, -- fiery heroic axe replica + { + itemid = 29157, + type = "equip", + slot = "hand" + }, -- fiery knight axe replica + { + itemid = 29157, + type = "deequip", + slot = "hand" + }, -- fiery knight axe replica + { + itemid = 29156, + type = "equip", + slot = "hand" + }, -- fiery barbarian axe replica + { + itemid = 29156, + type = "deequip", + slot = "hand" + }, -- fiery barbarian axe replica + { + itemid = 29155, + type = "equip", + slot = "hand" + }, -- fiery dragon slayer replica + { + itemid = 29155, + type = "deequip", + slot = "hand" + }, -- fiery dragon slayer replica + { + itemid = 29154, + type = "equip", + slot = "hand" + }, -- fiery blacksteel replica + { + itemid = 29154, + type = "deequip", + slot = "hand" + }, -- fiery blacksteel replica + { + itemid = 29153, + type = "equip", + slot = "hand" + }, -- fiery mystic blade replica + { + itemid = 29153, + type = "deequip", + slot = "hand" + }, -- fiery mystic blade replica + { + itemid = 29152, + type = "equip", + slot = "hand" + }, -- fiery relic sword replica + { + itemid = 29152, + type = "deequip", + slot = "hand" + }, -- fiery relic sword replica + { + itemid = 29151, + type = "equip", + slot = "hand" + }, -- fiery spike sword replica + { + itemid = 29151, + type = "deequip", + slot = "hand" + }, -- fiery spike sword replica + { + itemid = 29080, + type = "equip", + slot = "backpack" + }, -- blossom bag + { + itemid = 29080, + type = "deequip", + slot = "backpack" + }, -- blossom bag + { + itemid = 29079, + type = "equip", + slot = "armor", + level = 60 + }, -- swan feather cloak + { + itemid = 29079, + type = "deequip", + slot = "armor", + level = 60 + }, -- swan feather cloak + { + itemid = 29060, + type = "equip", + slot = "hand", + level = 41, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of darkness + { + itemid = 29060, + type = "deequip", + slot = "hand", + level = 41 + }, -- wand of darkness + { + itemid = 29059, + type = "equip", + slot = "hand" + }, -- royal star + { + itemid = 29059, + type = "deequip", + slot = "hand" + }, -- royal star + { + itemid = 29058, + type = "equip", + slot = "ammo" + }, -- spectral bolt + { + itemid = 29058, + type = "deequip", + slot = "ammo" + }, -- spectral bolt + { + itemid = 29036, + type = "equip", + slot = "hand" + }, -- leaf star + { + itemid = 29036, + type = "deequip", + slot = "hand" + }, -- leaf star + { + itemid = 29005, + type = "equip", + slot = "hand", + level = 80, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- dream blossom staff + { + itemid = 29005, + type = "deequip", + slot = "hand", + level = 80 + }, -- dream blossom staff + { + itemid = 29004, + type = "equip", + slot = "shield", + level = 80, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- wooden spellbook + { + itemid = 29004, + type = "deequip", + slot = "shield", + level = 80 + }, -- wooden spellbook + { + itemid = 29003, + type = "equip", + slot = "ring", + level = 50 + }, -- butterfly ring + { + itemid = 29003, + type = "deequip", + slot = "ring", + level = 50 + }, -- butterfly ring + --[[ + { + glowing rubbish amulet + itemid = 28658 + begin task + } + { + rubbish amulet + itemid = 28657 + begin task + } + ]] + { + itemid = 27756, + type = "equip", + slot = "head" + }, -- porcelain mask + { + itemid = 27756, + type = "deequip", + slot = "head" + }, -- porcelain mask + { + itemid = 27077, + type = "equip", + slot = "feet" + }, -- filthy bunnyslippers + { + itemid = 27077, + type = "deequip", + slot = "feet" + }, -- filthy bunnyslippers + { + itemid = 27073, + type = "equip", + slot = "head" + }, -- rusty winged helmet + { + itemid = 27073, + type = "deequip", + slot = "head" + }, -- rusty winged helmet + { + itemid = 27072, + type = "equip", + slot = "legs" + }, -- tatty Dragon scale legs + { + itemid = 27072, + type = "deequip", + slot = "legs" + }, -- tatty Dragon scale legs + { + itemid = 27070, + type = "equip", + slot = "legs" + }, -- chocolatey dragon scale legs + { + itemid = 27070, + type = "deequip", + slot = "legs" + }, -- chocolatey dragon scale legs + { + itemid = 27065, + type = "equip", + slot = "head" + }, -- Ferumbras' Candy Hat + { + itemid = 27065, + type = "deequip", + slot = "head" + }, -- Ferumbras' Candy Hat + { + itemid = 27063, + type = "equip", + slot = "backpack" + }, -- birthday backpack + { + itemid = 27063, + type = "deequip", + slot = "backpack" + }, -- birthday backpack + { + itemid = 27061, + type = "equip", + slot = "backpack" + }, -- pillow backpack + { + itemid = 27061, + type = "deequip", + slot = "backpack" + }, -- pillow backpack + { + itemid = 26200, + type = "equip", + slot = "necklace", + level = 150, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- collar of red plasma + { + itemid = 26200, + type = "deequip", + slot = "necklace", + level = 150 + }, -- collar of red plasma + { + itemid = 26199, + type = "equip", + slot = "necklace", + level = 150, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- collar of green plasma + { + itemid = 26199, + type = "deequip", + slot = "necklace", + level = 150 + }, -- collar of green plasma + { + itemid = 26198, + type = "equip", + slot = "necklace", + level = 150, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- collar of blue plasma + { + itemid = 26198, + type = "deequip", + slot = "necklace", + level = 150 + }, -- collar of blue plasma + { + itemid = 26190, + type = "equip", + slot = "ring", + level = 100, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- ring of red plasma + { + itemid = 26190, + type = "deequip", + slot = "ring", + level = 100 + }, -- ring of red plasma + { + itemid = 26189, + type = "equip", + slot = "ring", + level = 100, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- ring of red plasma + { + itemid = 26189, + type = "deequip", + slot = "ring", + level = 100 + }, -- ring of red plasma + { + itemid = 26188, + type = "equip", + slot = "ring", + level = 100, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- ring of green plasma + { + itemid = 26188, + type = "deequip", + slot = "ring", + level = 100 + }, -- ring of green plasma + { + itemid = 26187, + type = "equip", + slot = "ring", + level = 100, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- ring of green plasma + { + itemid = 26187, + type = "deequip", + slot = "ring", + level = 100 + }, -- ring of green plasma + { + itemid = 26186, + type = "equip", + slot = "ring", + level = 100, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- ring of blue plasma + { + itemid = 26186, + type = "deequip", + slot = "ring", + level = 100 + }, -- ring of blue plasma + { + itemid = 26185, + type = "equip", + slot = "ring", + level = 100, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- ring of blue plasma + { + itemid = 26185, + type = "deequip", + slot = "ring", + level = 100 + }, -- ring of blue plasma + { + itemid = 26184, + type = "equip", + slot = "necklace", + level = 150, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- collar of red plasma + { + itemid = 26184, + type = "deequip", + slot = "necklace", + level = 150 + }, -- collar of red plasma + { + itemid = 26183, + type = "equip", + slot = "necklace", + level = 150, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- collar of green plasma + { + itemid = 26183, + type = "deequip", + slot = "necklace", + level = 150 + }, -- collar of green plasma + { + itemid = 26182, + type = "equip", + slot = "necklace", + level = 150, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- collar of blue plasma + { + itemid = 26182, + type = "deequip", + slot = "necklace", + level = 150 + }, -- collar of blue plasma + { + itemid = 26181, + type = "equip", + slot = "backpack" + }, -- energetic backpack + { + itemid = 26181, + type = "deequip", + slot = "backpack" + }, -- energetic backpack + { + itemid = 26133, + type = "equip", + slot = "feet", + level = 150 + }, -- void boots + { + itemid = 26133, + type = "deequip", + slot = "feet", + level = 150 + }, -- void boots + { + itemid = 26132, + type = "equip", + slot = "feet", + level = 150 + }, -- void boots + { + itemid = 26132, + type = "deequip", + slot = "feet", + level = 150 + }, -- void boots + { + itemid = 26131, + type = "equip", + slot = "head", + level = 100, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- tiara of power + { + itemid = 26131, + type = "deequip", + slot = "head", + level = 100 + }, -- tiara of power + { + itemid = 26130, + type = "equip", + slot = "head", + level = 100, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- tiara of power + { + itemid = 26130, + type = "deequip", + slot = "head", + level = 100 + }, -- tiara of power + { + itemid = 25995, + type = "equip", + slot = "hand", + level = 100, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- rod of carving + { + itemid = 25995, + type = "deequip", + slot = "hand", + level = 100 + }, -- rod of carving + { + itemid = 25991, + type = "equip", + slot = "hand", + level = 100, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of carving + { + itemid = 25991, + type = "deequip", + slot = "hand", + level = 100 + }, -- wand of carving + { + itemid = 25987, + type = "equip", + slot = "hand" + }, -- crossbow of carving + { + itemid = 25987, + type = "deequip", + slot = "hand" + }, -- crossbow of carving + { + itemid = 25983, + type = "equip", + slot = "hand" + }, -- bow of carving + { + itemid = 25983, + type = "deequip", + slot = "hand" + }, -- bow of carving + { + itemid = 25979, + type = "equip", + slot = "hand" + }, -- hammer of carving + { + itemid = 25979, + type = "deequip", + slot = "hand" + }, -- hammer of carving + { + itemid = 25975, + type = "equip", + slot = "hand" + }, -- mace of carving + { + itemid = 25975, + type = "deequip", + slot = "hand" + }, -- mace of carving + { + itemid = 25971, + type = "equip", + slot = "hand" + }, -- chopper of carving + { + itemid = 25971, + type = "deequip", + slot = "hand" + }, -- chopper of carving + { + itemid = 25967, + type = "equip", + slot = "hand" + }, -- axe of carving + { + itemid = 25967, + type = "deequip", + slot = "hand" + }, -- axe of carving + { + itemid = 25963, + type = "equip", + slot = "hand" + }, -- slayer of carving + { + itemid = 25963, + type = "deequip", + slot = "hand" + }, -- slayer of carving + { + itemid = 25959, + type = "equip", + slot = "hand" + }, -- blade of carving + { + itemid = 25959, + type = "deequip", + slot = "hand" + }, -- blade of carving + { + itemid = 25955, + type = "equip", + slot = "hand", + level = 100, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- rod of remedy + { + itemid = 25955, + type = "deequip", + slot = "hand", + level = 100 + }, -- rod of remedy + { + itemid = 25951, + type = "equip", + slot = "hand", + level = 100, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of remedy + { + itemid = 25951, + type = "deequip", + slot = "hand", + level = 100 + }, -- wand of remedy + { + itemid = 25947, + type = "equip", + slot = "hand" + }, -- crossbow of remedy + { + itemid = 25947, + type = "deequip", + slot = "hand" + }, -- crossbow of remedy + { + itemid = 25943, + type = "equip", + slot = "hand" + }, -- bow of remedy + { + itemid = 25943, + type = "deequip", + slot = "hand" + }, -- bow of remedy + { + itemid = 25935, + type = "equip", + slot = "hand" + }, -- mace of remedy + { + itemid = 25935, + type = "deequip", + slot = "hand" + }, -- mace of remedy + { + itemid = 25931, + type = "equip", + slot = "hand" + }, -- chopper of remedy + { + itemid = 25931, + type = "deequip", + slot = "hand" + }, -- chopper of remedy + { + itemid = 25927, + type = "equip", + slot = "hand" + }, -- axe of remedy + { + itemid = 25927, + type = "deequip", + slot = "hand" + }, -- axe of remedy + { + itemid = 25923, + type = "equip", + slot = "hand" + }, -- slayer of remedy + { + itemid = 25923, + type = "deequip", + slot = "hand" + }, -- slayer of remedy + { + itemid = 25919, + type = "equip", + slot = "hand" + }, -- blade of remedy + { + itemid = 25919, + type = "deequip", + slot = "hand" + }, -- blade of remedy + { + itemid = 25888, + type = "equip", + slot = "hand", + level = 100, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- rod of mayhem + { + itemid = 25888, + type = "deequip", + slot = "hand", + level = 100 + }, -- rod of mayhem + { + itemid = 25887, + type = "equip", + slot = "hand", + level = 100, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of mayhem + { + itemid = 25887, + type = "deequip", + slot = "hand", + level = 100 + }, -- wand of mayhem + { + itemid = 25886, + type = "equip", + slot = "hand" + }, -- crossbow of mayhem + { + itemid = 25886, + type = "deequip", + slot = "hand" + }, -- crossbow of mayhem + { + itemid = 25885, + type = "equip", + slot = "hand" + }, -- bow of mayhem + { + itemid = 25885, + type = "deequip", + slot = "hand" + }, -- bow of mayhem + { + itemid = 25884, + type = "equip", + slot = "hand" + }, -- hammer of mayhem + { + itemid = 25884, + type = "deequip", + slot = "hand" + }, -- hammer of mayhem + { + itemid = 25883, + type = "equip", + slot = "hand" + }, -- mace of mayhem + { + itemid = 25883, + type = "deequip", + slot = "hand" + }, -- mace of mayhem + { + itemid = 25882, + type = "equip", + slot = "hand" + }, -- chopper of mayhem + { + itemid = 25882, + type = "deequip", + slot = "hand" + }, -- chopper of mayhem + { + itemid = 25881, + type = "equip", + slot = "hand" + }, -- axe of mayhem + { + itemid = 25881, + type = "deequip", + slot = "hand" + }, -- axe of mayhem + { + itemid = 25880, + type = "equip", + slot = "hand" + }, -- slayer of mayhem + { + itemid = 25880, + type = "deequip", + slot = "hand" + }, -- slayer of mayhem + { + itemid = 25879, + type = "equip", + slot = "hand" + }, -- blade of mayhem + { + itemid = 25879, + type = "deequip", + slot = "hand" + }, -- blade of mayhem + { + itemid = 25546, + type = "equip", + slot = "shield" + }, -- shield of destiny + { + itemid = 25546, + type = "deequip", + slot = "shield" + }, -- shield of destiny + { + itemid = 25545, + type = "equip", + slot = "shield" + }, -- shield of destiny + { + itemid = 25545, + type = "deequip", + slot = "shield" + }, -- shield of destiny + { + itemid = 25523, + type = "equip", + slot = "hand" + }, -- rift crossbow + { + itemid = 25523, + type = "deequip", + slot = "hand" + }, -- rift crossbow + { + itemid = 25522, + type = "equip", + slot = "hand" + }, -- rift bow + { + itemid = 25522, + type = "deequip", + slot = "hand" + }, -- rift bow + { + itemid = 25430, + type = "equip", + slot = "feet", + level = 100 + }, -- boots of homecoming + { + itemid = 25430, + type = "deequip", + slot = "feet", + level = 100 + }, -- boots of homecoming + { + itemid = 25429, + type = "equip", + slot = "feet", + level = 100 + }, -- boots of homecoming + { + itemid = 25429, + type = "deequip", + slot = "feet", + level = 100 + }, -- boots of homecoming + { + itemid = 25424, + type = "equip", + slot = "necklace", + level = 100 + }, -- ferumbras' amulet + { + itemid = 25424, + type = "deequip", + slot = "necklace", + level = 100 + }, -- ferumbras' amulet + { + itemid = 25423, + type = "equip", + slot = "necklace", + level = 100 + }, -- ferumbras' amulet + { + itemid = 25423, + type = "deequip", + slot = "necklace", + level = 100 + }, -- ferumbras' amulet + { + itemid = 25422, + type = "equip", + slot = "hand", + level = 100, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- ferumbras' staff (enchanted) + { + itemid = 25422, + type = "deequip", + slot = "hand", + level = 100 + }, -- ferumbras' staff (enchanted) + { + itemid = 25421, + type = "equip", + slot = "hand", + level = 65, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- ferumbras' staff (failed) + { + itemid = 25421, + type = "deequip", + slot = "hand", + level = 65 + }, -- ferumbras' staff (failed) + { + itemid = 25420, + type = "equip", + slot = "hand" + }, -- Ferumbras' staff + { + itemid = 25420, + type = "deequip", + slot = "hand" + }, -- Ferumbras' staff + { + itemid = 25418, + type = "equip", + slot = "hand" + }, -- maimer + { + itemid = 25418, + type = "deequip", + slot = "hand" + }, -- maimer + { + itemid = 25416, + type = "equip", + slot = "hand" + }, -- Impaler of the igniter + { + itemid = 25416, + type = "deequip", + slot = "hand" + }, -- Impaler of the igniter + { + itemid = 25415, + type = "equip", + slot = "hand" + }, -- plague bite + { + itemid = 25415, + type = "deequip", + slot = "hand" + }, -- plague bite + { + itemid = 25414, + type = "equip", + slot = "shield", + level = 200 + }, -- death gaze + { + itemid = 25414, + type = "deequip", + slot = "shield", + level = 200 + }, -- death gaze + { + itemid = 25413, + type = "equip", + slot = "head", + level = 150 + }, -- shroud of despair + { + itemid = 25413, + type = "deequip", + slot = "head", + level = 150 + }, -- shroud of despair + { + itemid = 25412, + type = "equip", + slot = "feet" + }, -- treader of torment + { + itemid = 25412, + type = "deequip", + slot = "feet" + }, -- treader of torment + { + itemid = 25411, + type = "equip", + slot = "shield", + level = 150, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- book of lies + { + itemid = 25411, + type = "deequip", + slot = "shield", + level = 150 + }, -- book of lies + { + itemid = 25410, + type = "equip", + slot = "head" + }, -- visage of the end days + { + itemid = 25410, + type = "deequip", + slot = "head" + }, -- visage of the end days + { + itemid = 25402, + type = "equip", + slot = "necklace" + }, -- ancient amulet + { + itemid = 25402, + type = "deequip", + slot = "necklace" + }, -- ancient amulet + { + itemid = 25383, + type = "equip", + slot = "hand" + }, -- rift lance + { + itemid = 25383, + type = "deequip", + slot = "hand" + }, -- rift lance + { + itemid = 25382, + type = "equip", + slot = "shield" + }, -- rift shield + { + itemid = 25382, + type = "deequip", + slot = "shield" + }, -- rift shield + { + itemid = 25307, + type = "equip", + slot = "shield" + }, -- rattling gourd + { + itemid = 25307, + type = "deequip", + slot = "shield" + }, -- rattling gourd + { + itemid = 25306, + type = "equip", + slot = "shield" + }, -- gourd + { + itemid = 25306, + type = "deequip", + slot = "shield" + }, -- gourd + { + itemid = 25193, + type = "equip", + slot = "armor", + level = 200, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- frostmind raiment + { + itemid = 25193, + type = "deequip", + slot = "armor", + level = 200 + }, -- frostmind raiment + { + itemid = 25192, + type = "equip", + slot = "armor", + level = 200, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- thundermind raiment + { + itemid = 25192, + type = "deequip", + slot = "armor", + level = 200 + }, -- thundermind raiment + { + itemid = 25191, + type = "equip", + slot = "armor", + level = 200, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- earthmind raiment + { + itemid = 25191, + type = "deequip", + slot = "armor", + level = 200 + }, -- earthmind raiment + { + itemid = 25190, + type = "equip", + slot = "armor", + level = 200, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- firemind raiment + { + itemid = 25190, + type = "deequip", + slot = "armor", + level = 200 + }, -- firemind raiment + { + itemid = 25189, + type = "equip", + slot = "armor", + level = 200, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- frostsoul tabard + { + itemid = 25189, + type = "deequip", + slot = "armor", + level = 200 + }, -- frostsoul tabard + { + itemid = 25188, + type = "equip", + slot = "armor", + level = 200, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- thundersoul tabard + { + itemid = 25188, + type = "deequip", + slot = "armor", + level = 200 + }, -- thundersoul tabard + { + itemid = 25187, + type = "equip", + slot = "armor", + level = 200, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- earthsoul tabard + { + itemid = 25187, + type = "deequip", + slot = "armor", + level = 200 + }, -- earthsoul tabard + { + itemid = 25186, + type = "equip", + slot = "armor", + level = 200, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- firesoul tabard + { + itemid = 25186, + type = "deequip", + slot = "armor", + level = 200 + }, -- firesoul tabard + { + itemid = 25185, + type = "equip", + slot = "armor", + level = 200, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- frostheart platemail + { + itemid = 25185, + type = "deequip", + slot = "armor", + level = 200 + }, -- frostheart platemail + { + itemid = 25184, + type = "equip", + slot = "armor", + level = 200, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- frostheart hauberk + { + itemid = 25184, + type = "deequip", + slot = "armor", + level = 200 + }, -- frostheart hauberk + { + itemid = 25183, + type = "equip", + slot = "armor", + level = 200, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- frostheart cuirass + { + itemid = 25183, + type = "deequip", + slot = "armor", + level = 200 + }, -- frostheart cuirass + { + itemid = 25182, + type = "equip", + slot = "armor", + level = 200, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- thunderheart platemail + { + itemid = 25182, + type = "deequip", + slot = "armor", + level = 200 + }, -- thunderheart platemail + { + itemid = 25181, + type = "equip", + slot = "armor", + level = 200, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- thunderheart hauberk + { + itemid = 25181, + type = "deequip", + slot = "armor", + level = 200 + }, -- thunderheart hauberk + { + itemid = 25180, + type = "equip", + slot = "armor", + level = 200, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- thunderheart cuirass + { + itemid = 25180, + type = "deequip", + slot = "armor", + level = 200 + }, -- thunderheart cuirass + { + itemid = 25179, + type = "equip", + slot = "armor", + level = 200, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- earthheart platemail + { + itemid = 25179, + type = "deequip", + slot = "armor", + level = 200 + }, -- earthheart platemail + { + itemid = 25178, + type = "equip", + slot = "armor", + level = 200, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- earthheart hauberk + { + itemid = 25178, + type = "deequip", + slot = "armor", + level = 200 + }, -- earthheart hauberk + { + itemid = 25177, + type = "equip", + slot = "armor", + level = 200, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- earthheart cuirass + { + itemid = 25177, + type = "deequip", + slot = "armor", + level = 200 + }, -- earthheart cuirass + { + itemid = 25176, + type = "equip", + slot = "armor", + level = 200, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- fireheart platemail + { + itemid = 25176, + type = "deequip", + slot = "armor", + level = 200 + }, -- fireheart platemail + { + itemid = 25175, + type = "equip", + slot = "armor", + level = 200, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- fireheart hauberk + { + itemid = 25175, + type = "deequip", + slot = "armor", + level = 200 + }, -- fireheart hauberk + { + itemid = 25174, + type = "equip", + slot = "armor", + level = 200, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- fireheart cuirass + { + itemid = 25174, + type = "deequip", + slot = "armor", + level = 200 + }, -- fireheart cuirass + { + itemid = 24851, + type = "equip", + slot = "necklace", + level = 60 + }, -- onyx pendant + { + itemid = 24851, + type = "deequip", + slot = "necklace", + level = 60 + }, -- onyx pendant + { + itemid = 24848, + type = "equip", + slot = "head" + }, -- shamanic mask + { + itemid = 24848, + type = "deequip", + slot = "head" + }, -- shamanic mask + { + itemid = 24846, + type = "equip", + slot = "shield" + }, -- painted gourd rattle + { + itemid = 24846, + type = "deequip", + slot = "shield" + }, -- painted gourd rattle + { + itemid = 24839, + type = "equip", + slot = "hand", + level = 37, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- ogre sceptra + { + itemid = 24839, + type = "deequip", + slot = "hand", + level = 37 + }, -- ogre sceptra + { + itemid = 24828, + type = "equip", + slot = "hand" + }, -- ogre choppa + { + itemid = 24828, + type = "deequip", + slot = "hand" + }, -- ogre choppa + { + itemid = 24827, + type = "equip", + slot = "hand" + }, -- ogre klubba + { + itemid = 24827, + type = "deequip", + slot = "hand" + }, -- ogre klubba + { + itemid = 24826, + type = "equip", + slot = "ring" + }, -- house silversun's signet ring + { + itemid = 24826, + type = "deequip", + slot = "ring" + }, -- house silversun's signet ring + { + itemid = 24810, + type = "equip", + slot = "head" + }, -- dark wizard's crown + { + itemid = 24810, + type = "deequip", + slot = "head" + }, -- dark wizard's crown + { + itemid = 24809, + type = "equip", + slot = "head" + }, -- dark wizard's crown + { + itemid = 24809, + type = "deequip", + slot = "head" + }, -- dark wizard's crown + { + itemid = 24790, + type = "equip", + slot = "necklace" + }, -- enchanted werewolf amulet + { + itemid = 24790, + type = "deequip", + slot = "necklace" + }, -- enchanted werewolf amulet + { + itemid = 24788, + type = "equip", + slot = "head", + level = 100, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- enchanted werewolf helmet (paladin) + { + itemid = 24788, + type = "deequip", + slot = "head", + level = 100 + }, -- enchanted werewolf helmet (paladin) + { + itemid = 24786, + type = "equip", + slot = "head", + level = 100, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- enchanted werewolf helmet + { + itemid = 24786, + type = "deequip", + slot = "head", + level = 100 + }, -- enchanted werewolf helmet + { + itemid = 24785, + type = "equip", + slot = "head", + level = 100, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- enchanted werewolf helmet + { + itemid = 24785, + type = "deequip", + slot = "head", + level = 100 + }, -- enchanted werewolf helmet + { + itemid = 24784, + type = "equip", + slot = "head", + level = 100, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- enchanted werewolf helmet + { + itemid = 24784, + type = "deequip", + slot = "head", + level = 100 + }, -- enchanted werewolf helmet + { + itemid = 24783, + type = "equip", + slot = "head", + level = 100, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- enchanted werewolf helmet (mage) + { + itemid = 24783, + type = "deequip", + slot = "head", + level = 100 + }, -- enchanted werewolf helmet (mage) + { + itemid = 24772, + type = "equip", + slot = "head", + level = 100, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- enchanted werewolf helmet (paladin) + { + itemid = 24772, + type = "deequip", + slot = "head", + level = 100 + }, -- enchanted werewolf helmet (paladin) + { + itemid = 24771, + type = "equip", + slot = "head", + level = 100, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- enchanted werewolf helmet (knight) + { + itemid = 24771, + type = "deequip", + slot = "head", + level = 100 + }, -- enchanted werewolf helmet (knight) + { + itemid = 24770, + type = "equip", + slot = "head", + level = 100, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- enchanted werewolf helmet (knight) + { + itemid = 24770, + type = "deequip", + slot = "head", + level = 100 + }, -- enchanted werewolf helmet (knight) + { + itemid = 24769, + type = "equip", + slot = "head", + level = 100, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- enchanted werewolf helmet (knight) + { + itemid = 24769, + type = "deequip", + slot = "head", + level = 100 + }, -- enchanted werewolf helmet (knight) + { + itemid = 24743, + type = "equip", + slot = "legs" + }, -- wereboar loincloth + { + itemid = 24743, + type = "deequip", + slot = "legs" + }, -- wereboar loincloth + { + itemid = 24742, + type = "equip", + slot = "feet", + level = 60 + }, -- badger boots + { + itemid = 24742, + type = "deequip", + slot = "feet", + level = 60 + }, -- badger boots + { + itemid = 24741, + type = "equip", + slot = "armor", + level = 50 + }, -- fur armor + { + itemid = 24741, + type = "deequip", + slot = "armor", + level = 50 + }, -- fur armor + { + itemid = 24740, + type = "equip", + slot = "backpack" + }, -- wolf backpack + { + itemid = 24740, + type = "deequip", + slot = "backpack" + }, -- wolf backpack + { + itemid = 24718, + type = "equip", + slot = "head", + level = 100 + }, -- werewolf helmet + { + itemid = 24718, + type = "deequip", + slot = "head", + level = 100 + }, -- werewolf helmet + { + itemid = 24716, + type = "equip", + slot = "necklace" + }, -- werewolf amulet + { + itemid = 24716, + type = "deequip", + slot = "necklace" + }, -- werewolf amulet + { + itemid = 24637, + type = "equip", + slot = "feet", + level = 80, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- oriental shoes + { + itemid = 24637, + type = "deequip", + slot = "feet", + level = 80 + }, -- oriental shoes + { + itemid = 24324, + type = "equip", + slot = "ring" + }, -- sweetheart ring + { + itemid = 24324, + type = "deequip", + slot = "ring" + }, -- sweetheart ring + { + itemid = 24261, + type = "equip", + slot = "head", + level = 80 + }, -- crest of the deep seas + { + itemid = 24261, + type = "deequip", + slot = "head", + level = 80 + }, -- crest of the deep seas + { + itemid = 24114, + type = "equip", + slot = "ring" + }, -- brandon's wedding ring + { + itemid = 24114, + type = "deequip", + slot = "ring" + }, -- brandon's wedding ring + { + itemid = 23839, + type = "equip", + slot = "ammo" + }, -- simple arrow + { + itemid = 23839, + type = "deequip", + slot = "ammo" + }, -- simple arrow + { + itemid = 23816, + type = "equip", + slot = "backpack" + }, -- war backpack + { + itemid = 23816, + type = "deequip", + slot = "backpack" + }, -- war backpack + { + itemid = 23810, + type = "equip", + slot = "necklace" + }, -- the Lion's Heart + { + itemid = 23810, + type = "deequip", + slot = "necklace" + }, -- the Lion's Heart + { + itemid = 23782, + type = "equip", + slot = "backpack" + }, -- shopping bag + { + itemid = 23782, + type = "deequip", + slot = "backpack" + }, -- shopping bag + { + itemid = 23772, + type = "equip", + slot = "shield" + }, -- broken wooden shield + { + itemid = 23772, + type = "deequip", + slot = "shield" + }, -- broken wooden shield + { + itemid = 23771, + type = "equip", + slot = "shield", + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- spellbook of the novice + { + itemid = 23771, + type = "deequip", + slot = "shield" + }, -- spellbook of the novice + { + itemid = 23721, + type = "equip", + slot = "hand", + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- the chiller + { + itemid = 23721, + type = "deequip", + slot = "hand" + }, -- the chiller + { + itemid = 23719, + type = "equip", + slot = "hand", + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- the scorcher + { + itemid = 23719, + type = "deequip", + slot = "hand" + }, -- the scorcher + { + itemid = 23666, + type = "equip", + slot = "backpack" + }, -- glooth backpack + { + itemid = 23666, + type = "deequip", + slot = "backpack" + }, -- glooth backpack + { + itemid = 23663, + type = "equip", + slot = "backpack" + }, -- feedbag + { + itemid = 23663, + type = "deequip", + slot = "backpack" + }, -- feedbag + { + itemid = 23590, + type = "equip", + slot = "hand" + }, -- one hit wonder + { + itemid = 23590, + type = "deequip", + slot = "hand" + }, -- one hit wonder + { + itemid = 23554, + type = "equip", + slot = "necklace", + level = 75, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- glooth amulet + { + itemid = 23554, + type = "deequip", + slot = "necklace", + level = 75 + }, -- glooth amulet + { + itemid = 23551, + type = "equip", + slot = "hand" + }, -- glooth axe + { + itemid = 23551, + type = "deequip", + slot = "hand" + }, -- glooth axe + { + itemid = 23550, + type = "equip", + slot = "hand" + }, -- glooth blade + { + itemid = 23550, + type = "deequip", + slot = "hand" + }, -- glooth blade + { + itemid = 23549, + type = "equip", + slot = "hand" + }, -- glooth club + { + itemid = 23549, + type = "deequip", + slot = "hand" + }, -- glooth club + { + itemid = 23548, + type = "equip", + slot = "hand" + }, -- cowtana + { + itemid = 23548, + type = "deequip", + slot = "hand" + }, -- cowtana + { + itemid = 23547, + type = "equip", + slot = "hand" + }, -- execowtioner axe + { + itemid = 23547, + type = "deequip", + slot = "hand" + }, -- execowtioner axe + { + itemid = 23546, + type = "equip", + slot = "shield" + }, -- mino shield + { + itemid = 23546, + type = "deequip", + slot = "shield" + }, -- mino shield + { + itemid = 23545, + type = "equip", + slot = "hand" + }, -- mino lance + { + itemid = 23545, + type = "deequip", + slot = "hand" + }, -- mino lance + { + itemid = 23544, + type = "equip", + slot = "hand" + }, -- moohtant cudgel + { + itemid = 23544, + type = "deequip", + slot = "hand" + }, -- moohtant cudgel + { + itemid = 23543, + type = "equip", + slot = "hand" + }, -- glooth whip + { + itemid = 23543, + type = "deequip", + slot = "hand" + }, -- glooth whip + { + itemid = 23542, + type = "equip", + slot = "hand" + }, -- metal bat + { + itemid = 23542, + type = "deequip", + slot = "hand" + }, -- metal bat + { + itemid = 23541, + type = "equip", + slot = "necklace", + level = 75 + }, -- gearwheel chain + { + itemid = 23541, + type = "deequip", + slot = "necklace", + level = 75 + }, -- gearwheel chain + { + itemid = 23540, + type = "equip", + slot = "feet", + level = 50, + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- metal spats + { + itemid = 23540, + type = "deequip", + slot = "feet", + level = 50 + }, -- metal spats + { + itemid = 23539, + type = "equip", + slot = "legs", + level = 60 + }, -- alloy legs + { + itemid = 23539, + type = "deequip", + slot = "legs", + level = 60 + }, -- alloy legs + { + itemid = 23538, + type = "equip", + slot = "armor" + }, -- heat core + { + itemid = 23538, + type = "deequip", + slot = "armor" + }, -- heat core + { + itemid = 23537, + type = "equip", + slot = "armor", + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- mooh'tah plate + { + itemid = 23537, + type = "deequip", + slot = "armor" + }, -- mooh'tah plate + { + itemid = 23536, + type = "equip", + slot = "head", + level = 70, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- rubber cap + { + itemid = 23536, + type = "deequip", + slot = "head", + level = 70 + }, -- rubber cap + { + itemid = 23535, + type = "equip", + slot = "armor", + level = 40, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- glooth cape + { + itemid = 23535, + type = "deequip", + slot = "armor", + level = 40 + }, -- glooth cape + { + itemid = 23529, + type = "equip", + slot = "hand" + }, -- glooth spear + { + itemid = 23529, + type = "deequip", + slot = "hand" + }, -- glooth spear + { + itemid = 22696, + type = "equip", + slot = "backpack" + }, -- cake backpack + { + itemid = 22696, + type = "deequip", + slot = "backpack" + }, -- cake backpack + { + itemid = 22543, + type = "equip", + slot = "ring" + }, -- unstable ring of ending + { + itemid = 22543, + type = "deequip", + slot = "ring" + }, -- unstable ring of ending + { + itemid = 22518, + type = "equip", + slot = "head" + }, -- broken visor + { + itemid = 22518, + type = "deequip", + slot = "head" + }, -- broken visor + { + itemid = 22516, + type = "equip", + slot = "ring", + level = 200 + }, -- ring of ending + { + itemid = 22516, + type = "deequip", + slot = "ring", + level = 200 + }, -- ring of ending + { + itemid = 22474, + type = "equip", + slot = "shield" + }, -- eerie song book + { + itemid = 22474, + type = "deequip", + slot = "shield" + }, -- eerie song book + { + itemid = 22424, + type = "equip", + slot = "shield", + level = 250, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- umbral master spellbook + { + itemid = 22424, + type = "deequip", + slot = "shield", + level = 250 + }, -- umbral master spellbook + { + itemid = 22423, + type = "equip", + slot = "shield", + level = 150, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- umbral spellbook + { + itemid = 22423, + type = "deequip", + slot = "shield", + level = 150 + }, -- umbral spellbook + { + itemid = 22422, + type = "equip", + slot = "shield", + level = 75, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- crude umbral spellbook + { + itemid = 22422, + type = "deequip", + slot = "shield", + level = 75 + }, -- crude umbral spellbook + { + itemid = 22421, + type = "equip", + slot = "hand" + }, -- umbral master crossbow + { + itemid = 22421, + type = "deequip", + slot = "hand" + }, -- umbral master crossbow + { + itemid = 22420, + type = "equip", + slot = "hand" + }, -- umbral crossbow + { + itemid = 22420, + type = "deequip", + slot = "hand" + }, -- umbral crossbow + { + itemid = 22419, + type = "equip", + slot = "hand" + }, -- crude umbral crossbow + { + itemid = 22419, + type = "deequip", + slot = "hand" + }, -- crude umbral crossbow + { + itemid = 22418, + type = "equip", + slot = "hand" + }, -- umbral master bow + { + itemid = 22418, + type = "deequip", + slot = "hand" + }, -- umbral master bow + { + itemid = 22417, + type = "equip", + slot = "hand" + }, -- umbral bow + { + itemid = 22417, + type = "deequip", + slot = "hand" + }, -- umbral bow + { + itemid = 22416, + type = "equip", + slot = "hand" + }, -- crude umbral bow + { + itemid = 22416, + type = "deequip", + slot = "hand" + }, -- crude umbral bow + { + itemid = 22415, + type = "equip", + slot = "hand" + }, -- umbral master hammer + { + itemid = 22415, + type = "deequip", + slot = "hand" + }, -- umbral master hammer + { + itemid = 22414, + type = "equip", + slot = "hand" + }, -- umbral hammer + { + itemid = 22414, + type = "deequip", + slot = "hand" + }, -- umbral hammer + { + itemid = 22413, + type = "equip", + slot = "hand" + }, -- crude umbral hammer + { + itemid = 22413, + type = "deequip", + slot = "hand" + }, -- crude umbral hammer + { + itemid = 22412, + type = "equip", + slot = "hand" + }, -- umbral master mace + { + itemid = 22412, + type = "deequip", + slot = "hand" + }, -- umbral master mace + { + itemid = 22411, + type = "equip", + slot = "hand" + }, -- umbral mace + { + itemid = 22411, + type = "deequip", + slot = "hand" + }, -- umbral mace + { + itemid = 22410, + type = "equip", + slot = "hand" + }, -- crude umbral mace + { + itemid = 22410, + type = "deequip", + slot = "hand" + }, -- crude umbral mace + { + itemid = 22409, + type = "equip", + slot = "hand" + }, -- umbral master chopper + { + itemid = 22409, + type = "deequip", + slot = "hand" + }, -- umbral master chopper + { + itemid = 22408, + type = "equip", + slot = "hand" + }, -- umbral chopper + { + itemid = 22408, + type = "deequip", + slot = "hand" + }, -- umbral chopper + { + itemid = 22407, + type = "equip", + slot = "hand" + }, -- guardian halberd + { + itemid = 22407, + type = "deequip", + slot = "hand" + }, -- guardian halberd + { + itemid = 22406, + type = "equip", + slot = "hand" + }, -- umbral master axe + { + itemid = 22406, + type = "deequip", + slot = "hand" + }, -- umbral master axe + { + itemid = 22405, + type = "equip", + slot = "hand" + }, -- umbral axe + { + itemid = 22405, + type = "deequip", + slot = "hand" + }, -- umbral axe + { + itemid = 22404, + type = "equip", + slot = "hand" + }, -- crude umbral axe + { + itemid = 22404, + type = "deequip", + slot = "hand" + }, -- crude umbral axe + { + itemid = 22403, + type = "equip", + slot = "hand" + }, -- umbral master slayer + { + itemid = 22403, + type = "deequip", + slot = "hand" + }, -- umbral master slayer + { + itemid = 22402, + type = "equip", + slot = "hand" + }, -- umbral slayer + { + itemid = 22402, + type = "deequip", + slot = "hand" + }, -- umbral slayer + { + itemid = 22401, + type = "equip", + slot = "hand" + }, -- crude umbral slayer + { + itemid = 22401, + type = "deequip", + slot = "hand" + }, -- crude umbral slayer + { + itemid = 22400, + type = "equip", + slot = "hand" + }, -- umbral masterblade + { + itemid = 22400, + type = "deequip", + slot = "hand" + }, -- umbral masterblade + { + itemid = 22399, + type = "equip", + slot = "hand" + }, -- umbral blade + { + itemid = 22399, + type = "deequip", + slot = "hand" + }, -- umbral blade + { + itemid = 22398, + type = "equip", + slot = "hand" + }, -- crude umbral blade + { + itemid = 22398, + type = "deequip", + slot = "hand" + }, -- crude umbral blade + { + itemid = 22384, + type = "equip", + slot = "shield" + }, -- strange good night songs + { + itemid = 22384, + type = "deequip", + slot = "shield" + }, -- strange good night songs + { + itemid = 21725, + type = "equip", + slot = "armor", + level = 130, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- furious frock + { + itemid = 21725, + type = "deequip", + slot = "armor", + level = 130 + }, -- furious frock + { + itemid = 21708, + type = "equip", + slot = "feet" + }, -- vampire silk slippers + { + itemid = 21708, + type = "deequip", + slot = "feet" + }, -- vampire silk slippers + { + itemid = 21707, + type = "equip", + slot = "shield" + }, -- haunted mirror piece + { + itemid = 21707, + type = "deequip", + slot = "shield" + }, -- haunted mirror piece + { + itemid = 21706, + type = "equip", + slot = "armor" + }, -- goo shell + { + itemid = 21706, + type = "deequip", + slot = "armor" + }, -- goo shell + { + itemid = 21700, + type = "equip", + slot = "legs", + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- icy culottes + { + itemid = 21700, + type = "deequip", + slot = "legs" + }, -- icy culottes + { + itemid = 21697, + type = "equip", + slot = "shield" + }, -- runic ice shield + { + itemid = 21697, + type = "deequip", + slot = "shield" + }, -- runic ice shield + { + itemid = 21696, + type = "equip", + slot = "hand" + }, -- icicle bow + { + itemid = 21696, + type = "deequip", + slot = "hand" + }, -- icicle bow + { + itemid = 21693, + type = "equip", + slot = "ring" + }, -- horn + { + itemid = 21693, + type = "deequip", + slot = "ring" + }, -- horn + { + itemid = 21692, + type = "equip", + slot = "armor" + }, -- albino plate + { + itemid = 21692, + type = "deequip", + slot = "armor" + }, -- albino plate + { + itemid = 21691, + type = "equip", + slot = "necklace", + level = 150 + }, -- shrunken head necklace + { + itemid = 21691, + type = "deequip", + slot = "necklace", + level = 150 + }, -- shrunken head necklace + { + itemid = 21690, + type = "equip", + slot = "hand" + }, -- triple bolt crossbow + { + itemid = 21690, + type = "deequip", + slot = "hand" + }, -- triple bolt crossbow + { + itemid = 21475, + type = "equip", + slot = "backpack" + }, -- pannier backpack + { + itemid = 21475, + type = "deequip", + slot = "backpack" + }, -- pannier backpack + { + itemid = 21469, + type = "equip", + slot = "necklace" + }, -- friendship amulet + { + itemid = 21469, + type = "deequip", + slot = "necklace" + }, -- friendship amulet + { + itemid = 21252, + type = "equip", + slot = "ring" + }, -- vampire's signet ring + { + itemid = 21252, + type = "deequip", + slot = "ring" + }, -- vampire's signet ring + { + itemid = 20139, + type = "equip", + slot = "hand" + }, -- spiky club + { + itemid = 20139, + type = "deequip", + slot = "hand" + }, -- spiky club + { + itemid = 20132, + type = "equip", + slot = "head" + }, -- helmet of the lost + { + itemid = 20132, + type = "deequip", + slot = "head" + }, -- helmet of the lost + { + itemid = 20126, + type = "equip", + slot = "armor" + }, -- leather harness + { + itemid = 20126, + type = "deequip", + slot = "armor" + }, -- leather harness + { + itemid = 20109, + type = "equip", + slot = "armor" + }, -- buckle + { + itemid = 20109, + type = "deequip", + slot = "armor" + }, -- buckle + { + itemid = 20108, + type = "equip", + slot = "hand" + }, -- pair of iron fists + { + itemid = 20108, + type = "deequip", + slot = "hand" + }, -- pair of iron fists + { + itemid = 20104, + type = "equip", + slot = "hand" + }, -- swampling club + { + itemid = 20104, + type = "deequip", + slot = "hand" + }, -- swampling club + { + itemid = 20093, + type = "equip", + slot = "hand" + }, -- life preserver + { + itemid = 20093, + type = "deequip", + slot = "hand" + }, -- life preserver + { + itemid = 20092, + type = "equip", + slot = "hand" + }, -- ratana + { + itemid = 20092, + type = "deequip", + slot = "hand" + }, -- ratana + { + itemid = 20090, + type = "equip", + slot = "shield" + }, -- spike shield + { + itemid = 20090, + type = "deequip", + slot = "shield" + }, -- spike shield + { + itemid = 19391, + type = "equip", + slot = "hand", + level = 1, + vocation = { + {"None", true} + } + }, -- sorc and druid staff + { + itemid = 19391, + type = "deequip", + slot = "hand", + level = 1 + }, -- sorc and druid staff + { + itemid = 19390, + type = "equip", + slot = "hand" + }, -- mean paladin spear + { + itemid = 19390, + type = "deequip", + slot = "hand" + }, -- mean paladin spear + { + itemid = 19389, + type = "equip", + slot = "hand" + }, -- mean knight sword + { + itemid = 19389, + type = "deequip", + slot = "hand" + }, -- mean knight sword + { + itemid = 18528, + type = "equip", + slot = "ring", + level = 120 + }, -- prismatic ring + { + itemid = 18528, + type = "deequip", + slot = "ring", + level = 120 + }, -- prismatic ring + { + itemid = 18465, + type = "equip", + slot = "hand" + }, -- shiny blade + { + itemid = 18465, + type = "deequip", + slot = "hand" + }, -- shiny blade + { + itemid = 18454, + type = "equip", + slot = "hand" + }, -- mycological bow + { + itemid = 18454, + type = "deequip", + slot = "hand" + }, -- mycological bow + { + itemid = 18453, + type = "equip", + slot = "hand" + }, -- crystal crossbow + { + itemid = 18453, + type = "deequip", + slot = "hand" + }, -- crystal crossbow + { + itemid = 18452, + type = "equip", + slot = "hand" + }, -- mycological mace + { + itemid = 18452, + type = "deequip", + slot = "hand" + }, -- mycological mace + { + itemid = 18451, + type = "equip", + slot = "hand" + }, -- crystalline axe + { + itemid = 18451, + type = "deequip", + slot = "hand" + }, -- crystalline axe + { + itemid = 18450, + type = "equip", + slot = "hand" + }, -- crystalline sword + { + itemid = 18450, + type = "deequip", + slot = "hand" + }, -- crystalline sword + { + itemid = 18437, + type = "equip", + slot = "ammo" + }, -- envenomed arrow + { + itemid = 18437, + type = "deequip", + slot = "ammo" + }, -- envenomed arrow + { + itemid = 18436, + type = "equip", + slot = "ammo" + }, -- drill bolt + { + itemid = 18436, + type = "deequip", + slot = "ammo" + }, -- drill bolt + { + itemid = 18435, + type = "equip", + slot = "ammo" + }, -- prismatic bolt + { + itemid = 18435, + type = "deequip", + slot = "ammo" + }, -- prismatic bolt + { + itemid = 18412, + type = "equip", + slot = "hand", + level = 65, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- glacial rod + { + itemid = 18412, + type = "deequip", + slot = "hand", + level = 65 + }, -- glacial rod + { + itemid = 18411, + type = "equip", + slot = "hand", + level = 65, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- muck rod + { + itemid = 18411, + type = "deequip", + slot = "hand", + level = 65 + }, -- muck rod + { + itemid = 18410, + type = "equip", + slot = "shield", + level = 150, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- prismatic shield + { + itemid = 18410, + type = "deequip", + slot = "shield", + level = 150 + }, -- prismatic shield + { + itemid = 18409, + type = "equip", + slot = "hand", + level = 65, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of everblazing + { + itemid = 18409, + type = "deequip", + slot = "hand", + level = 65 + }, -- wand of everblazing + { + itemid = 18408, + type = "equip", + slot = "ring", + level = 120 + }, -- prismatic ring + { + itemid = 18408, + type = "deequip", + slot = "ring", + level = 120 + }, -- prismatic ring + { + itemid = 18407, + type = "equip", + slot = "necklace", + level = 150 + }, -- prismatic necklace + { + itemid = 18407, + type = "deequip", + slot = "necklace", + level = 150 + }, -- prismatic necklace + { + itemid = 18406, + type = "equip", + slot = "feet", + level = 150, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- prismatic boots + { + itemid = 18406, + type = "deequip", + slot = "feet", + level = 150 + }, -- prismatic boots + { + itemid = 18405, + type = "equip", + slot = "legs", + level = 150, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- prismatic legs + { + itemid = 18405, + type = "deequip", + slot = "legs", + level = 150 + }, -- prismatic legs + { + itemid = 18404, + type = "equip", + slot = "armor", + level = 120, + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- prismatic armor + { + itemid = 18404, + type = "deequip", + slot = "armor", + level = 120 + }, -- prismatic armor + { + itemid = 18403, + type = "equip", + slot = "head", + level = 150, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- prismatic helmet + { + itemid = 18403, + type = "deequip", + slot = "head", + level = 150 + }, -- prismatic helmet + { + itemid = 18402, + type = "equip", + slot = "necklace", + level = 150 + }, -- gill necklace + { + itemid = 18402, + type = "deequip", + slot = "necklace", + level = 150 + }, -- gill necklace + { + itemid = 18401, + type = "equip", + slot = "shield", + level = 130, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- spellbook of vigilance + { + itemid = 18401, + type = "deequip", + slot = "shield", + level = 130 + }, -- spellbook of vigilance + { + itemid = 18400, + type = "equip", + slot = "legs", + level = 150, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- gill legs + { + itemid = 18400, + type = "deequip", + slot = "legs", + level = 150 + }, -- gill legs + { + itemid = 18399, + type = "equip", + slot = "armor", + level = 150, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- gill coat + { + itemid = 18399, + type = "deequip", + slot = "armor", + level = 150 + }, -- gill coat + { + itemid = 18398, + type = "equip", + slot = "head", + level = 150, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- gill gugel + { + itemid = 18398, + type = "deequip", + slot = "head", + level = 150 + }, -- gill gugel + { + itemid = 18394, + type = "equip", + slot = "backpack" + }, -- crystal backpack + { + itemid = 18394, + type = "deequip", + slot = "backpack" + }, -- crystal backpack + { + itemid = 18393, + type = "equip", + slot = "backpack" + }, -- mushroom backpack + { + itemid = 18393, + type = "deequip", + slot = "backpack" + }, -- mushroom backpack + { + itemid = 18390, + type = "equip", + slot = "hand", + level = 65, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of defiance + { + itemid = 18390, + type = "deequip", + slot = "hand", + level = 65 + }, -- wand of defiance + { + itemid = 18304, + type = "equip", + slot = "ammo" + }, -- crystalline arrow + { + itemid = 18304, + type = "deequip", + slot = "ammo" + }, -- crystalline arrow + { + itemid = 18303, + type = "equip", + slot = "ammo" + }, -- crystal bolt + { + itemid = 18303, + type = "deequip", + slot = "ammo" + }, -- crystal bolt + { + itemid = 16112, + type = "equip", + slot = "shield", + level = 150, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- spellbook of ancient arcana + { + itemid = 16112, + type = "deequip", + slot = "shield", + level = 150 + }, -- spellbook of ancient arcana + { + itemid = 16111, + type = "equip", + slot = "hand" + }, -- thorn spitter + { + itemid = 16111, + type = "deequip", + slot = "hand" + }, -- thorn spitter + { + itemid = 16104, + type = "equip", + slot = "shield" + }, -- mathmaster shield + { + itemid = 16104, + type = "deequip", + slot = "shield" + }, -- mathmaster shield + { + itemid = 16103, + type = "equip", + slot = "shield" + }, -- mathmaster shield + { + itemid = 16103, + type = "deequip", + slot = "shield" + }, -- mathmaster shield + { + itemid = 16007, + type = "equip", + slot = "backpack" + }, -- anniversary backpack + { + itemid = 16007, + type = "deequip", + slot = "backpack" + }, -- anniversary backpack + { + itemid = 15649, + type = "equip", + slot = "ammo" + }, -- vortex bolt + { + itemid = 15649, + type = "deequip", + slot = "ammo" + }, -- vortex bolt + { + itemid = 15648, + type = "equip", + slot = "ammo" + }, -- tarsal arrow + { + itemid = 15648, + type = "deequip", + slot = "ammo" + }, -- tarsal arrow + { + itemid = 15647, + type = "equip", + slot = "hand" + }, -- deepling squelcher + { + itemid = 15647, + type = "deequip", + slot = "hand" + }, -- deepling squelcher + { + itemid = 15646, + type = "equip", + slot = "backpack" + }, -- buggy backpack + { + itemid = 15646, + type = "deequip", + slot = "backpack" + }, -- buggy backpack + { + itemid = 15645, + type = "equip", + slot = "backpack" + }, -- deepling backpack + { + itemid = 15645, + type = "deequip", + slot = "backpack" + }, -- deepling backpack + { + itemid = 15644, + type = "equip", + slot = "hand" + }, -- ornate crossbow + { + itemid = 15644, + type = "deequip", + slot = "hand" + }, -- ornate crossbow + { + itemid = 15643, + type = "equip", + slot = "hand" + }, -- hive bow + { + itemid = 15643, + type = "deequip", + slot = "hand" + }, -- hive bow + { + itemid = 15492, + type = "equip", + slot = "hand" + }, -- hive scythe + { + itemid = 15492, + type = "deequip", + slot = "hand" + }, -- hive scythe + { + itemid = 15491, + type = "equip", + slot = "shield" + }, -- carapace shield + { + itemid = 15491, + type = "deequip", + slot = "shield" + }, -- carapace shield + { + itemid = 15490, + type = "equip", + slot = "legs", + level = 75 + }, -- grasshopper legs + { + itemid = 15490, + type = "deequip", + slot = "legs", + level = 75 + }, -- grasshopper legs + { + itemid = 15489, + type = "equip", + slot = "armor", + level = 80, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- calopteryx cape + { + itemid = 15489, + type = "deequip", + slot = "armor", + level = 80 + }, -- calopteryx cape + { + itemid = 15454, + type = "equip", + slot = "hand" + }, -- guardian axe + { + itemid = 15454, + type = "deequip", + slot = "hand" + }, -- guardian axe + { + itemid = 15453, + type = "equip", + slot = "shield" + }, -- warrior's shield + { + itemid = 15453, + type = "deequip", + slot = "shield" + }, -- warrior's shield + { + itemid = 15451, + type = "equip", + slot = "hand" + }, -- warrior's axe + { + itemid = 15451, + type = "deequip", + slot = "hand" + }, -- warrior's axe + { + itemid = 15414, + type = "equip", + slot = "hand" + }, -- ornate mace + { + itemid = 15414, + type = "deequip", + slot = "hand" + }, -- ornate mace + { + itemid = 15413, + type = "equip", + slot = "shield", + level = 130, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- ornate shield + { + itemid = 15413, + type = "deequip", + slot = "shield", + level = 130 + }, -- ornate shield + { + itemid = 15412, + type = "equip", + slot = "legs", + level = 185, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- ornate legs + { + itemid = 15412, + type = "deequip", + slot = "legs", + level = 185 + }, -- ornate legs + { + itemid = 15411, + type = "equip", + slot = "shield", + level = 120, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- depth scutum + { + itemid = 15411, + type = "deequip", + slot = "shield", + level = 120 + }, -- depth scutum + { + itemid = 15410, + type = "equip", + slot = "feet", + level = 150, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- depth calcei + { + itemid = 15410, + type = "deequip", + slot = "feet", + level = 150 + }, -- depth calcei + { + itemid = 15409, + type = "equip", + slot = "legs", + level = 130, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- depth ocrea + { + itemid = 15409, + type = "deequip", + slot = "legs", + level = 130 + }, -- depth ocrea + { + itemid = 15408, + type = "equip", + slot = "head", + level = 150 + }, -- depth galea + { + itemid = 15408, + type = "deequip", + slot = "head", + level = 150 + }, -- depth galea + { + itemid = 15407, + type = "equip", + slot = "armor", + level = 150, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- depth lorica + { + itemid = 15407, + type = "deequip", + slot = "armor", + level = 150 + }, -- depth lorica + { + itemid = 15406, + type = "equip", + slot = "armor", + level = 200, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- ornate chestplate + { + itemid = 15406, + type = "deequip", + slot = "armor", + level = 200 + }, -- ornate chestplate + { + itemid = 15404, + type = "equip", + slot = "hand" + }, -- deepling axe + { + itemid = 15404, + type = "deequip", + slot = "hand" + }, -- deepling axe + { + itemid = 15403, + type = "equip", + slot = "necklace", + level = 120 + }, -- necklace of the deep + { + itemid = 15403, + type = "deequip", + slot = "necklace", + level = 120 + }, -- necklace of the deep + { + itemid = 15400, + type = "equip", + slot = "hand" + }, -- deepling staff + { + itemid = 15400, + type = "deequip", + slot = "hand" + }, -- deepling staff + { + itemid = 13947, + type = "equip", + slot = "head" + }, -- the Epic Wisdom + { + itemid = 13947, + type = "deequip", + slot = "head" + }, -- the Epic Wisdom + { + itemid = 13946, + type = "equip", + slot = "head" + }, -- the Epic Wisdom + { + itemid = 13946, + type = "deequip", + slot = "head" + }, -- the Epic Wisdom + { + itemid = 13880, + type = "equip", + slot = "hand", + level = 40, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- shimmer wand + { + itemid = 13880, + type = "deequip", + slot = "hand", + level = 40 + }, -- shimmer wand + { + itemid = 13877, + type = "equip", + slot = "ring" + }, -- broken ring of ending + { + itemid = 13877, + type = "deequip", + slot = "ring" + }, -- broken ring of ending + { + itemid = 13873, + type = "equip", + slot = "hand" + }, -- shimmer bow + { + itemid = 13873, + type = "deequip", + slot = "hand" + }, -- shimmer bow + { + itemid = 13872, + type = "equip", + slot = "hand", + level = 40, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- shimmer rod + { + itemid = 13872, + type = "deequip", + slot = "hand", + level = 40 + }, -- shimmer rod + { + itemid = 13871, + type = "equip", + slot = "hand" + }, -- shimmer sword + { + itemid = 13871, + type = "deequip", + slot = "hand" + }, -- shimmer sword + { + itemid = 13838, + type = "equip", + slot = "hand" + }, -- heavy trident + { + itemid = 13838, + type = "deequip", + slot = "hand" + }, -- heavy trident + { + itemid = 13829, + type = "equip", + slot = "hand" + }, -- wooden sword + { + itemid = 13829, + type = "deequip", + slot = "hand" + }, -- wooden sword + { + itemid = 13826, + type = "equip", + slot = "ring", + vocation = { + {"None", true} + } + }, -- star ring + { + itemid = 13826, + type = "deequip", + slot = "ring", + vocation = { + {"None", true} + } + }, -- star ring + { + itemid = 13825, + type = "equip", + slot = "ring", + vocation = { + {"None", true} + } + }, -- star ring + { + itemid = 13825, + type = "deequip", + slot = "ring", + vocation = { + {"None", true} + } + }, -- star ring + { + itemid = 13760, + type = "equip", + slot = "hand", + level = 37, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of dimensions + { + itemid = 13760, + type = "deequip", + slot = "hand", + level = 37 + }, -- wand of dimensions + { + itemid = 13756, + type = "equip", + slot = "head", + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- mage's cap + { + itemid = 13756, + type = "deequip", + slot = "head" + }, -- mage's cap + { + itemid = 13580, + type = "equip", + slot = "feet" + }, -- fish tail (equipped) + { + itemid = 13580, + type = "deequip", + slot = "feet" + }, -- fish tail (equipped) + { + itemid = 13532, + type = "equip", + slot = "necklace" + }, -- golden hyena pendant + { + itemid = 13532, + type = "deequip", + slot = "necklace" + }, -- golden hyena pendant + { + itemid = 13531, + type = "equip", + slot = "necklace" + }, -- golden scorpion pendant + { + itemid = 13531, + type = "deequip", + slot = "necklace" + }, -- golden scorpion pendant + { + itemid = 12657, + type = "equip", + slot = "armor" + }, -- old cape + { + itemid = 12657, + type = "deequip", + slot = "armor" + }, -- old cape + { + itemid = 12656, + type = "equip", + slot = "head" + }, -- sedge hat + { + itemid = 12656, + type = "deequip", + slot = "head" + }, -- sedge hat + { + itemid = 12654, + type = "equip", + slot = "backpack" + }, -- loot bag + { + itemid = 12654, + type = "deequip", + slot = "backpack" + }, -- loot bag + { + itemid = 12649, + type = "equip", + slot = "hand" + }, -- blade of corruption + { + itemid = 12649, + type = "deequip", + slot = "hand" + }, -- blade of corruption + { + itemid = 12648, + type = "equip", + slot = "hand" + }, -- snake god's sceptre + { + itemid = 12648, + type = "deequip", + slot = "hand" + }, -- snake god's sceptre + { + itemid = 12647, + type = "equip", + slot = "shield", + level = 100, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- snake god's wristguard + { + itemid = 12647, + type = "deequip", + slot = "shield", + level = 100 + }, -- snake god's wristguard + { + itemid = 12646, + type = "equip", + slot = "feet", + level = 80, + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- draken boots + { + itemid = 12646, + type = "deequip", + slot = "feet", + level = 80 + }, -- draken boots + { + itemid = 12645, + type = "equip", + slot = "head", + level = 100, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- elite draken helmet + { + itemid = 12645, + type = "deequip", + slot = "head", + level = 100 + }, -- elite draken helmet + { + itemid = 12644, + type = "equip", + slot = "shield", + level = 80, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- shield of corruption + { + itemid = 12644, + type = "deequip", + slot = "shield", + level = 80 + }, -- shield of corruption + { + itemid = 12643, + type = "equip", + slot = "armor", + level = 100, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- royal scale robe + { + itemid = 12643, + type = "deequip", + slot = "armor", + level = 100 + }, -- royal scale robe + { + itemid = 12642, + type = "equip", + slot = "armor", + level = 100, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- royal draken mail + { + itemid = 12642, + type = "deequip", + slot = "armor", + level = 100 + }, -- royal draken mail + { + itemid = 12630, + type = "equip", + slot = "head", + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- cobra crown + { + itemid = 12630, + type = "deequip", + slot = "head" + }, -- cobra crown + { + itemid = 12613, + type = "equip", + slot = "hand" + }, -- twiceslicer + { + itemid = 12613, + type = "deequip", + slot = "hand" + }, -- twiceslicer + { + itemid = 12607, + type = "equip", + slot = "armor", + level = 100, + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- elite draken mail + { + itemid = 12607, + type = "deequip", + slot = "armor", + level = 100 + }, -- elite draken mail + { + itemid = 12498, + type = "equip", + slot = "feet" + }, -- fish tail (unequipped) + { + itemid = 12498, + type = "deequip", + slot = "feet" + }, -- fish tail (unequipped) + { + itemid = 12424, + type = "equip", + slot = "necklace" + }, -- ornamented brooch + { + itemid = 12424, + type = "deequip", + slot = "necklace" + }, -- ornamented brooch + { + itemid = 11393, + type = "equip", + slot = "necklace" + }, -- lucky clover amulet + { + itemid = 11393, + type = "deequip", + slot = "necklace" + }, -- lucky clover amulet + { + itemid = 11374, + type = "equip", + slot = "necklace" + }, -- beetle necklace + { + itemid = 11374, + type = "deequip", + slot = "necklace" + }, -- beetle necklace + { + itemid = 11368, + type = "equip", + slot = "head", + level = 60, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- jade hat + { + itemid = 11368, + type = "deequip", + slot = "head", + level = 60 + }, -- jade hat + { + itemid = 11356, + type = "equip", + slot = "armor", + level = 60, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- Zaoan robe + { + itemid = 11356, + type = "deequip", + slot = "armor", + level = 60 + }, -- Zaoan robe + { + itemid = 11355, + type = "equip", + slot = "armor", + level = 60, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- spellweaver's robe + { + itemid = 11355, + type = "deequip", + slot = "armor", + level = 60 + }, -- spellweaver's robe + { + itemid = 11329, + type = "equip", + slot = "necklace" + }, -- wailing widow's necklace + { + itemid = 11329, + type = "deequip", + slot = "necklace" + }, -- wailing widow's necklace + { + itemid = 11323, + type = "equip", + slot = "hand" + }, -- Zaoan halberd + { + itemid = 11323, + type = "deequip", + slot = "hand" + }, -- Zaoan halberd + { + itemid = 11309, + type = "equip", + slot = "hand" + }, -- twin hooks + { + itemid = 11309, + type = "deequip", + slot = "hand" + }, -- twin hooks + { + itemid = 11308, + type = "equip", + slot = "hand" + }, -- drachaku + { + itemid = 11308, + type = "deequip", + slot = "hand" + }, -- drachaku + { + itemid = 11307, + type = "equip", + slot = "hand" + }, -- Zaoan sword + { + itemid = 11307, + type = "deequip", + slot = "hand" + }, -- Zaoan sword + { + itemid = 11306, + type = "equip", + slot = "hand" + }, -- sai + { + itemid = 11306, + type = "deequip", + slot = "hand" + }, -- sai + { + itemid = 11305, + type = "equip", + slot = "hand" + }, -- drakinata + { + itemid = 11305, + type = "deequip", + slot = "hand" + }, -- drakinata + { + itemid = 11304, + type = "equip", + slot = "legs" + }, -- Zaoan legs + { + itemid = 11304, + type = "deequip", + slot = "legs" + }, -- Zaoan legs + { + itemid = 11303, + type = "equip", + slot = "feet" + }, -- zaoan shoes + { + itemid = 11303, + type = "deequip", + slot = "feet" + }, -- zaoan shoes + { + itemid = 11302, + type = "equip", + slot = "head", + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- Zaoan helmet + { + itemid = 11302, + type = "deequip", + slot = "head" + }, -- Zaoan helmet + { + itemid = 11301, + type = "equip", + slot = "armor", + level = 50, + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- Zaoan armor + { + itemid = 11301, + type = "deequip", + slot = "armor", + level = 50 + }, -- Zaoan armor + { + itemid = 11263, + type = "equip", + slot = "backpack" + }, -- santa backpack + { + itemid = 11263, + type = "deequip", + slot = "backpack" + }, -- santa backpack + { + itemid = 11244, + type = "equip", + slot = "backpack" + }, -- minotaur backpack + { + itemid = 11244, + type = "deequip", + slot = "backpack" + }, -- minotaur backpack + { + itemid = 11243, + type = "equip", + slot = "backpack" + }, -- dragon backpack + { + itemid = 11243, + type = "deequip", + slot = "backpack" + }, -- dragon backpack + { + itemid = 11242, + type = "equip", + slot = "backpack" + }, -- expedition bag + { + itemid = 11242, + type = "deequip", + slot = "backpack" + }, -- expedition bag + { + itemid = 11241, + type = "equip", + slot = "backpack" + }, -- expedition backpack + { + itemid = 11241, + type = "deequip", + slot = "backpack" + }, -- expedition backpack + { + itemid = 11240, + type = "equip", + slot = "feet", + level = 70, + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- guardian boots + { + itemid = 11240, + type = "deequip", + slot = "feet", + level = 70 + }, -- guardian boots + { + itemid = 11119, + type = "equip", + slot = "backpack" + }, -- heart backpack + { + itemid = 11119, + type = "deequip", + slot = "backpack" + }, -- heart backpack + { + itemid = 11118, + type = "equip", + slot = "feet", + level = 70, + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- dragon scale boots + { + itemid = 11118, + type = "deequip", + slot = "feet", + level = 70 + }, -- dragon scale boots + { + itemid = 11117, + type = "equip", + slot = "feet", + level = 70, + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- crystal boots + { + itemid = 11117, + type = "deequip", + slot = "feet", + level = 70 + }, -- crystal boots + { + itemid = 10570, + type = "equip", + slot = "head", + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- witch hat + { + itemid = 10570, + type = "deequip", + slot = "head" + }, -- witch hat + { + itemid = 10522, + type = "equip", + slot = "backpack" + }, -- crown backpack + { + itemid = 10522, + type = "deequip", + slot = "backpack" + }, -- crown backpack + { + itemid = 10521, + type = "equip", + slot = "backpack" + }, -- moon backpack + { + itemid = 10521, + type = "deequip", + slot = "backpack" + }, -- moon backpack + { + itemid = 10520, + type = "equip", + slot = "backpack" + }, -- orange bag + { + itemid = 10520, + type = "deequip", + slot = "backpack" + }, -- orange bag + { + itemid = 10519, + type = "equip", + slot = "backpack" + }, -- orange backpack + { + itemid = 10519, + type = "deequip", + slot = "backpack" + }, -- orange backpack + { + itemid = 10518, + type = "equip", + slot = "backpack" + }, -- demon backpack + { + itemid = 10518, + type = "deequip", + slot = "backpack" + }, -- demon backpack + { + itemid = 10510, + type = "equip", + slot = "ring" + }, -- broken wedding ring + { + itemid = 10510, + type = "deequip", + slot = "ring" + }, -- broken wedding ring + { + itemid = 10502, + type = "equip", + slot = "ring" + }, -- engraved wedding ring + { + itemid = 10502, + type = "deequip", + slot = "ring" + }, -- engraved wedding ring + { + itemid = 10364, + type = "equip", + slot = "shield" + }, -- the shield Nevermourn + { + itemid = 10364, + type = "deequip", + slot = "shield" + }, -- the shield Nevermourn + { + itemid = 10363, + type = "equip", + slot = "armor" + }, -- the rain coat + { + itemid = 10363, + type = "deequip", + slot = "armor" + }, -- the rain coat + { + itemid = 10318, + type = "equip", + slot = "shield" + }, -- the shield Nevermourn + { + itemid = 10318, + type = "deequip", + slot = "shield" + }, -- the shield Nevermourn + { + itemid = 10317, + type = "equip", + slot = "armor" + }, -- the rain coat + { + itemid = 10317, + type = "deequip", + slot = "armor" + }, -- the rain coat + { + itemid = 10316, + type = "equip", + slot = "head" + }, -- mighty helm of green sparks + { + itemid = 10316, + type = "deequip", + slot = "head" + }, -- mighty helm of green sparks + { + itemid = 10313, + type = "equip", + slot = "hand" + }, -- incredible mumpiz slayer + { + itemid = 10313, + type = "deequip", + slot = "hand" + }, -- incredible mumpiz slayer + { + itemid = 10311, + type = "equip", + slot = "ring", + level = 100 + }, -- claw of 'The Noxious Spawn' + { + itemid = 10311, + type = "deequip", + slot = "ring", + level = 100 + }, -- claw of 'The Noxious Spawn' + { + itemid = 10309, + type = "equip", + slot = "ring", + level = 100 + }, -- claw of 'The Noxious Spawn' + { + itemid = 10309, + type = "deequip", + slot = "ring", + level = 100 + }, -- claw of 'The Noxious Spawn' + { + itemid = 10304, + type = "equip", + slot = "hand" + }, -- poet's fencing quill + { + itemid = 10304, + type = "deequip", + slot = "hand" + }, -- poet's fencing quill + { + itemid = 10303, + type = "equip", + slot = "hand" + }, -- farmer's avenger + { + itemid = 10303, + type = "deequip", + slot = "hand" + }, -- farmer's avenger + { + itemid = 10302, + type = "equip", + slot = "hand" + }, -- club of the fury + { + itemid = 10302, + type = "deequip", + slot = "hand" + }, -- club of the fury + { + itemid = 10301, + type = "equip", + slot = "hand" + }, -- scythe of the reaper + { + itemid = 10301, + type = "deequip", + slot = "hand" + }, -- scythe of the reaper + { + itemid = 10300, + type = "equip", + slot = "legs" + }, -- trousers of the ancients + { + itemid = 10300, + type = "deequip", + slot = "legs" + }, -- trousers of the ancients + { + itemid = 10299, + type = "equip", + slot = "head" + }, -- helmet of nature + { + itemid = 10299, + type = "deequip", + slot = "head" + }, -- helmet of nature + { + itemid = 10298, + type = "equip", + slot = "head" + }, -- helmet of ultimate terror + { + itemid = 10298, + type = "deequip", + slot = "head" + }, -- helmet of ultimate terror + { + itemid = 10297, + type = "equip", + slot = "shield" + }, -- shield of care + { + itemid = 10297, + type = "deequip", + slot = "shield" + }, -- shield of care + { + itemid = 10296, + type = "equip", + slot = "armor" + }, -- heavy metal t-shirt + { + itemid = 10296, + type = "deequip", + slot = "armor" + }, -- heavy metal t-shirt + { + itemid = 10295, + type = "equip", + slot = "hand" + }, -- musician's bow + { + itemid = 10295, + type = "deequip", + slot = "hand" + }, -- musician's bow + { + itemid = 10294, + type = "equip", + slot = "shield" + }, -- shield of the white knight + { + itemid = 10294, + type = "deequip", + slot = "shield" + }, -- shield of the white knight + { + itemid = 10293, + type = "equip", + slot = "hand" + }, -- stale bread of ancientness + { + itemid = 10293, + type = "deequip", + slot = "hand" + }, -- stale bread of ancientness + { + itemid = 10292, + type = "equip", + slot = "hand" + }, -- pointed rabbitslayer + { + itemid = 10292, + type = "deequip", + slot = "hand" + }, -- pointed rabbitslayer + { + itemid = 10291, + type = "equip", + slot = "head" + }, -- odd hat + { + itemid = 10291, + type = "deequip", + slot = "head" + }, -- odd hat + { + itemid = 10290, + type = "equip", + slot = "hand" + }, -- glutton's mace + { + itemid = 10290, + type = "deequip", + slot = "hand" + }, -- glutton's mace + { + itemid = 10289, + type = "equip", + slot = "shield" + }, -- meat shield + { + itemid = 10289, + type = "deequip", + slot = "shield" + }, -- meat shield + { + itemid = 10221, + type = "equip", + slot = "necklace", + level = 80 + }, -- shockwave amulet + { + itemid = 10221, + type = "deequip", + slot = "necklace", + level = 80 + }, -- shockwave amulet + { + itemid = 10220, + type = "equip", + slot = "necklace", + level = 80 + }, -- leviathan's amulet + { + itemid = 10220, + type = "deequip", + slot = "necklace", + level = 80 + }, -- leviathan's amulet + { + itemid = 10219, + type = "equip", + slot = "necklace", + level = 80 + }, -- sacred tree amulet + { + itemid = 10219, + type = "deequip", + slot = "necklace", + level = 80 + }, -- sacred tree amulet + { + itemid = 10218, + type = "equip", + slot = "necklace", + level = 80 + }, -- bonfire amulet + { + itemid = 10218, + type = "deequip", + slot = "necklace", + level = 80 + }, -- bonfire amulet + { + itemid = 10139, + type = "equip", + slot = "head" + }, -- laurel wreath + { + itemid = 10139, + type = "deequip", + slot = "head" + }, -- laurel wreath + { + itemid = 10135, + type = "equip", + slot = "necklace" + }, -- bronze medal + { + itemid = 10135, + type = "deequip", + slot = "necklace" + }, -- bronze medal + { + itemid = 10134, + type = "equip", + slot = "necklace" + }, -- silver medal + { + itemid = 10134, + type = "deequip", + slot = "necklace" + }, -- silver medal + { + itemid = 10133, + type = "equip", + slot = "necklace" + }, -- gold medal + { + itemid = 10133, + type = "deequip", + slot = "necklace" + }, -- gold medal + { + itemid = 10070, + type = "equip", + slot = "backpack" + }, -- grey bag + { + itemid = 10070, + type = "deequip", + slot = "backpack" + }, -- grey bag + { + itemid = 10016, + type = "equip", + slot = "head", + level = 50, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- batwing hat + { + itemid = 10016, + type = "deequip", + slot = "head", + level = 50 + }, -- batwing hat + { + itemid = 9933, + type = "equip", + slot = "feet", + level = 130 + }, -- pair firewalker boots + { + itemid = 9933, + type = "deequip", + slot = "feet", + level = 130 + }, -- pair firewalker boots + { + itemid = 9932, + type = "equip", + slot = "feet", + level = 130 + }, -- firewalker boots + { + itemid = 9932, + type = "deequip", + slot = "feet", + level = 130 + }, -- firewalker boots + { + itemid = 9931, + type = "equip", + slot = "feet" + }, -- coconut shoes + { + itemid = 9931, + type = "deequip", + slot = "feet" + }, -- coconut shoes + { + itemid = 9929, + type = "equip", + slot = "armor" + }, -- flower dress + { + itemid = 9929, + type = "deequip", + slot = "armor" + }, -- flower dress + { + itemid = 9928, + type = "equip", + slot = "legs" + }, -- leaf legs + { + itemid = 9928, + type = "deequip", + slot = "legs" + }, -- leaf legs + { + itemid = 9927, + type = "equip", + slot = "head" + }, -- flower wreath + { + itemid = 9927, + type = "deequip", + slot = "head" + }, -- flower wreath + { + itemid = 9778, + type = "equip", + slot = "head", + level = 80, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- yalahari mask + { + itemid = 9778, + type = "deequip", + slot = "head", + level = 80 + }, -- yalahari mask + { + itemid = 9777, + type = "equip", + slot = "legs", + level = 80, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- yalahari leg piece + { + itemid = 9777, + type = "deequip", + slot = "legs", + level = 80 + }, -- yalahari leg piece + { + itemid = 9776, + type = "equip", + slot = "armor", + level = 80, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- yalahari armor + { + itemid = 9776, + type = "deequip", + slot = "armor", + level = 80 + }, -- yalahari armor + { + itemid = 9775, + type = "equip", + slot = "backpack" + }, -- brocade bag + { + itemid = 9775, + type = "deequip", + slot = "backpack" + }, -- brocade bag + { + itemid = 9774, + type = "equip", + slot = "backpack" + }, -- brocade backpack + { + itemid = 9774, + type = "deequip", + slot = "backpack" + }, -- brocade backpack + { + itemid = 9077, + type = "equip", + slot = "backpack" + }, -- golden bag + { + itemid = 9077, + type = "deequip", + slot = "backpack" + }, -- golden bag + { + itemid = 9075, + type = "equip", + slot = "backpack" + }, -- purple bag + { + itemid = 9075, + type = "deequip", + slot = "backpack" + }, -- purple bag + { + itemid = 8932, + type = "equip", + slot = "hand" + }, -- the calamity + { + itemid = 8932, + type = "deequip", + slot = "hand" + }, -- the calamity + { + itemid = 8931, + type = "equip", + slot = "hand" + }, -- the epiphany + { + itemid = 8931, + type = "deequip", + slot = "hand" + }, -- the epiphany + { + itemid = 8930, + type = "equip", + slot = "hand" + }, -- emerald sword + { + itemid = 8930, + type = "deequip", + slot = "hand" + }, -- emerald sword + { + itemid = 8929, + type = "equip", + slot = "hand" + }, -- the stomper + { + itemid = 8929, + type = "deequip", + slot = "hand" + }, -- the stomper + { + itemid = 8928, + type = "equip", + slot = "hand" + }, -- obsidian truncheon + { + itemid = 8928, + type = "deequip", + slot = "hand" + }, -- obsidian truncheon + { + itemid = 8927, + type = "equip", + slot = "hand" + }, -- dark trinity mace + { + itemid = 8927, + type = "deequip", + slot = "hand" + }, -- dark trinity mace + { + itemid = 8926, + type = "equip", + slot = "hand" + }, -- demonwing axe + { + itemid = 8926, + type = "deequip", + slot = "hand" + }, -- demonwing axe + { + itemid = 8925, + type = "equip", + slot = "hand" + }, -- solar axe + { + itemid = 8925, + type = "deequip", + slot = "hand" + }, -- solar axe + { + itemid = 8924, + type = "equip", + slot = "hand" + }, -- hellforged axe + { + itemid = 8924, + type = "deequip", + slot = "hand" + }, -- hellforged axe + { + itemid = 8923, + type = "equip", + slot = "legs", + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- ranger legs + { + itemid = 8923, + type = "deequip", + slot = "legs" + }, -- ranger legs + { + itemid = 8922, + type = "equip", + slot = "hand", + level = 42, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of voodoo + { + itemid = 8922, + type = "deequip", + slot = "hand", + level = 42 + }, -- wand of voodoo + { + itemid = 8921, + type = "equip", + slot = "hand", + level = 22, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of draconia + { + itemid = 8921, + type = "deequip", + slot = "hand", + level = 22 + }, -- wand of draconia + { + itemid = 8920, + type = "equip", + slot = "hand", + level = 37, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of starmstorm + { + itemid = 8920, + type = "deequip", + slot = "hand", + level = 37 + }, -- wand of starmstorm + { + itemid = 8918, + type = "equip", + slot = "shield", + level = 80, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- spellbook of dark mysteries + { + itemid = 8918, + type = "deequip", + slot = "shield", + level = 80 + }, -- spellbook of dark mysteries + { + itemid = 8912, + type = "equip", + slot = "hand", + level = 37, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- springsprout rod + { + itemid = 8912, + type = "deequip", + slot = "hand", + level = 37 + }, -- springsprout rod + { + itemid = 8911, + type = "equip", + slot = "hand", + level = 22, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- northwind rod + { + itemid = 8911, + type = "deequip", + slot = "hand", + level = 22 + }, -- northwind rod + { + itemid = 8910, + type = "equip", + slot = "hand", + level = 42, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- underworld rod + { + itemid = 8910, + type = "deequip", + slot = "hand", + level = 42 + }, -- underworld rod + { + itemid = 8909, + type = "equip", + slot = "shield", + level = 100, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- terran rainbow shield + { + itemid = 8909, + type = "deequip", + slot = "shield", + level = 100 + }, -- terran rainbow shield + { + itemid = 8908, + type = "equip", + slot = "shield", + level = 100, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- sparking rainbow shield + { + itemid = 8908, + type = "deequip", + slot = "shield", + level = 100 + }, -- sparking rainbow shield + { + itemid = 8907, + type = "equip", + slot = "shield", + level = 100, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- icy rainbow shield + { + itemid = 8907, + type = "deequip", + slot = "shield", + level = 100 + }, -- icy rainbow shield + { + itemid = 8906, + type = "equip", + slot = "shield", + level = 100, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- fiery rainbow shield + { + itemid = 8906, + type = "deequip", + slot = "shield", + level = 100 + }, -- fiery rainbow shield + { + itemid = 8905, + type = "equip", + slot = "shield", + level = 100, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- rainbow shield + { + itemid = 8905, + type = "deequip", + slot = "shield", + level = 100 + }, -- rainbow shield + { + itemid = 8904, + type = "equip", + slot = "shield", + level = 70, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- spellscroll of prophecies + { + itemid = 8904, + type = "deequip", + slot = "shield", + level = 70 + }, -- spellscroll of prophecies + { + itemid = 8903, + type = "equip", + slot = "shield", + level = 60, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- spellbook of lost souls + { + itemid = 8903, + type = "deequip", + slot = "shield", + level = 60 + }, -- spellbook of lost souls + { + itemid = 8902, + type = "equip", + slot = "shield", + level = 50, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- spellbook of mind control + { + itemid = 8902, + type = "deequip", + slot = "shield", + level = 50 + }, -- spellbook of mind control + { + itemid = 8901, + type = "equip", + slot = "shield", + level = 40, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- spellbook of warding + { + itemid = 8901, + type = "deequip", + slot = "shield", + level = 40 + }, -- spellbook of warding + { + itemid = 8900, + type = "equip", + slot = "shield", + level = 30, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- spellbook of enlightenment + { + itemid = 8900, + type = "deequip", + slot = "shield", + level = 30 + }, -- spellbook of enlightenment + { + itemid = 8892, + type = "equip", + slot = "armor", + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- ethno coat + { + itemid = 8892, + type = "deequip", + slot = "armor" + }, -- ethno coat + { + itemid = 8891, + type = "equip", + slot = "armor", + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- paladin armor + { + itemid = 8891, + type = "deequip", + slot = "armor" + }, -- paladin armor + { + itemid = 8890, + type = "equip", + slot = "armor", + level = 100, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- robe of the underworld + { + itemid = 8890, + type = "deequip", + slot = "armor", + level = 100 + }, -- robe of the underworld + { + itemid = 8889, + type = "equip", + slot = "armor", + level = 85, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- skullcracker armor + { + itemid = 8889, + type = "deequip", + slot = "armor", + level = 85 + }, -- skullcracker armor + { + itemid = 8888, + type = "equip", + slot = "armor", + level = 100, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- master archer's armor + { + itemid = 8888, + type = "deequip", + slot = "armor", + level = 100 + }, -- master archer's armor + { + itemid = 8887, + type = "equip", + slot = "armor", + level = 75, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- frozen plate + { + itemid = 8887, + type = "deequip", + slot = "armor", + level = 75 + }, -- frozen plate + { + itemid = 8886, + type = "equip", + slot = "armor", + level = 75, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- molten plate + { + itemid = 8886, + type = "deequip", + slot = "armor", + level = 75 + }, -- molten plate + { + itemid = 8885, + type = "equip", + slot = "armor", + level = 75, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- divine plate + { + itemid = 8885, + type = "deequip", + slot = "armor", + level = 75 + }, -- divine plate + { + itemid = 8884, + type = "equip", + slot = "armor", + level = 100, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- oceanborn leviathan armor + { + itemid = 8884, + type = "deequip", + slot = "armor", + level = 100 + }, -- oceanborn leviathan armor + { + itemid = 8883, + type = "equip", + slot = "armor", + level = 100, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- windborn colossus armor + { + itemid = 8883, + type = "deequip", + slot = "armor", + level = 100 + }, -- windborn colossus armor + { + itemid = 8882, + type = "equip", + slot = "armor", + level = 100, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- earthborn titan armor + { + itemid = 8882, + type = "deequip", + slot = "armor", + level = 100 + }, -- earthborn titan armor + { + itemid = 8881, + type = "equip", + slot = "armor", + level = 100, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- fireborn giant armor + { + itemid = 8881, + type = "deequip", + slot = "armor", + level = 100 + }, -- fireborn giant armor + { + itemid = 8880, + type = "equip", + slot = "armor", + level = 60, + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- swamplair armor + { + itemid = 8880, + type = "deequip", + slot = "armor", + level = 60 + }, -- swamplair armor + { + itemid = 8879, + type = "equip", + slot = "armor", + level = 60, + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- voltage armor + { + itemid = 8879, + type = "deequip", + slot = "armor", + level = 60 + }, -- voltage armor + { + itemid = 8878, + type = "equip", + slot = "armor", + level = 60, + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- crystalline armor + { + itemid = 8878, + type = "deequip", + slot = "armor", + level = 60 + }, -- crystalline armor + { + itemid = 8877, + type = "equip", + slot = "armor", + level = 60, + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- lavos armor + { + itemid = 8877, + type = "deequip", + slot = "armor", + level = 60 + }, -- lavos armor + { + itemid = 8876, + type = "equip", + slot = "armor" + }, -- girl's dress + { + itemid = 8876, + type = "deequip", + slot = "armor" + }, -- girl's dress + { + itemid = 8875, + type = "equip", + slot = "armor" + }, -- tunic + { + itemid = 8875, + type = "deequip", + slot = "armor" + }, -- tunic + { + itemid = 8874, + type = "equip", + slot = "armor" + }, -- summer dress + { + itemid = 8874, + type = "deequip", + slot = "armor" + }, -- summer dress + { + itemid = 8873, + type = "equip", + slot = "armor" + }, -- hibiscus dress + { + itemid = 8873, + type = "deequip", + slot = "armor" + }, -- hibiscus dress + { + itemid = 8872, + type = "equip", + slot = "armor", + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- belted cape + { + itemid = 8872, + type = "deequip", + slot = "armor" + }, -- belted cape + { + itemid = 8871, + type = "equip", + slot = "armor", + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- focus cape + { + itemid = 8871, + type = "deequip", + slot = "armor" + }, -- focus cape + { + itemid = 8870, + type = "equip", + slot = "armor", + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- spirit cloak + { + itemid = 8870, + type = "deequip", + slot = "armor" + }, -- spirit cloak + { + itemid = 8869, + type = "equip", + slot = "armor", + level = 75, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- greenwood coat + { + itemid = 8869, + type = "deequip", + slot = "armor", + level = 75 + }, -- greenwood coat + { + itemid = 8868, + type = "equip", + slot = "armor", + level = 75, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- velvet mantle + { + itemid = 8868, + type = "deequip", + slot = "armor", + level = 75 + }, -- velvet mantle + { + itemid = 8867, + type = "equip", + slot = "armor", + level = 75, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- dragon robe + { + itemid = 8867, + type = "deequip", + slot = "armor", + level = 75 + }, -- dragon robe + { + itemid = 8866, + type = "equip", + slot = "armor", + level = 75, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- robe of the ice queen + { + itemid = 8866, + type = "deequip", + slot = "armor", + level = 75 + }, -- robe of the ice queen + { + itemid = 8865, + type = "equip", + slot = "armor", + level = 65, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- dark lord's cape + { + itemid = 8865, + type = "deequip", + slot = "armor", + level = 65 + }, -- dark lord's cape + { + itemid = 8858, + type = "equip", + slot = "hand" + }, -- elethriel's elemental bow + { + itemid = 8858, + type = "deequip", + slot = "hand" + }, -- elethriel's elemental bow + { + itemid = 8857, + type = "equip", + slot = "hand" + }, -- silkweaver bow + { + itemid = 8857, + type = "deequip", + slot = "hand" + }, -- silkweaver bow + { + itemid = 8856, + type = "equip", + slot = "hand" + }, -- yol's bow + { + itemid = 8856, + type = "deequip", + slot = "hand" + }, -- yol's bow + { + itemid = 8855, + type = "equip", + slot = "hand" + }, -- composite hornbow + { + itemid = 8855, + type = "deequip", + slot = "hand" + }, -- composite hornbow + { + itemid = 8854, + type = "equip", + slot = "hand" + }, -- warsinger bow + { + itemid = 8854, + type = "deequip", + slot = "hand" + }, -- warsinger bow + { + itemid = 8853, + type = "equip", + slot = "hand" + }, -- ironworker + { + itemid = 8853, + type = "deequip", + slot = "hand" + }, -- ironworker + { + itemid = 8852, + type = "equip", + slot = "hand" + }, -- devileye + { + itemid = 8852, + type = "deequip", + slot = "hand" + }, -- devileye + { + itemid = 8851, + type = "equip", + slot = "hand" + }, -- royal crossbow + { + itemid = 8851, + type = "deequip", + slot = "hand" + }, -- royal crossbow + { + itemid = 8850, + type = "equip", + slot = "hand" + }, -- chain bolter + { + itemid = 8850, + type = "deequip", + slot = "hand" + }, -- chain bolter + { + itemid = 8849, + type = "equip", + slot = "hand" + }, -- modified crossbow + { + itemid = 8849, + type = "deequip", + slot = "hand" + }, -- modified crossbow + { + itemid = 8821, + type = "equip", + slot = "armor", + level = 50 + }, -- witchhunter's coat + { + itemid = 8821, + type = "deequip", + slot = "armor", + level = 50 + }, -- witchhunter's coat + { + itemid = 8820, + type = "equip", + slot = "head", + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- mage hat + { + itemid = 8820, + type = "deequip", + slot = "head" + }, -- mage hat + { + itemid = 8819, + type = "equip", + slot = "armor", + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- magician's robe + { + itemid = 8819, + type = "deequip", + slot = "armor" + }, -- magician's robe + { + itemid = 8602, + type = "equip", + slot = "hand" + }, -- jagged sword + { + itemid = 8602, + type = "deequip", + slot = "hand" + }, -- jagged sword + { + itemid = 8601, + type = "equip", + slot = "hand" + }, -- steel axe + { + itemid = 8601, + type = "deequip", + slot = "hand" + }, -- steel axe + { + itemid = 8584, + type = "equip", + slot = "necklace" + }, -- Jerom's family necklace + { + itemid = 8584, + type = "deequip", + slot = "necklace" + }, -- Jerom's family necklace + { + itemid = 8266, + type = "equip", + slot = "necklace" + }, -- Koshei's ancient amulet + { + itemid = 8266, + type = "deequip", + slot = "necklace" + }, -- Koshei's ancient amulet + { + itemid = 8209, + type = "equip", + slot = "hand" + }, -- crimson sword + { + itemid = 8209, + type = "deequip", + slot = "hand" + }, -- crimson sword + { + itemid = 7968, + type = "equip", + slot = "ring" + }, -- shapeshifter ring + { + itemid = 7968, + type = "deequip", + slot = "ring" + }, -- shapeshifter ring + { + itemid = 7967, + type = "equip", + slot = "ring" + }, -- shapeshifter ring + { + itemid = 7967, + type = "deequip", + slot = "ring" + }, -- shapeshifter ring + { + itemid = 7957, + type = "equip", + slot = "head" + }, -- jester hat + { + itemid = 7957, + type = "deequip", + slot = "head" + }, -- jester hat + { + itemid = 7903, + type = "equip", + slot = "head", + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- terra hood + { + itemid = 7903, + type = "deequip", + slot = "head" + }, -- terra hood + { + itemid = 7902, + type = "equip", + slot = "head", + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- glacier mask + { + itemid = 7902, + type = "deequip", + slot = "head" + }, -- glacier mask + { + itemid = 7901, + type = "equip", + slot = "head", + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- lightning headband + { + itemid = 7901, + type = "deequip", + slot = "head" + }, -- lightning headband + { + itemid = 7900, + type = "equip", + slot = "head", + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- magma monocle + { + itemid = 7900, + type = "deequip", + slot = "head" + }, -- magma monocle + { + itemid = 7899, + type = "equip", + slot = "armor", + level = 50, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- magma coat + { + itemid = 7899, + type = "deequip", + slot = "armor", + level = 50 + }, -- magma coat + { + itemid = 7898, + type = "equip", + slot = "armor", + level = 50, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- lightning robe + { + itemid = 7898, + type = "deequip", + slot = "armor", + level = 50 + }, -- lightning robe + { + itemid = 7897, + type = "equip", + slot = "armor", + level = 50, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- glacier robe + { + itemid = 7897, + type = "deequip", + slot = "armor", + level = 50 + }, -- glacier robe + { + itemid = 7896, + type = "equip", + slot = "legs", + level = 40, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- glacier kilt + { + itemid = 7896, + type = "deequip", + slot = "legs", + level = 40 + }, -- glacier kilt + { + itemid = 7895, + type = "equip", + slot = "legs", + level = 40, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- lightning legs + { + itemid = 7895, + type = "deequip", + slot = "legs", + level = 40 + }, -- lightning legs + { + itemid = 7894, + type = "equip", + slot = "legs", + level = 40, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- magma legs + { + itemid = 7894, + type = "deequip", + slot = "legs", + level = 40 + }, -- magma legs + { + itemid = 7893, + type = "equip", + slot = "feet", + level = 35, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- lightning boots + { + itemid = 7893, + type = "deequip", + slot = "feet", + level = 35 + }, -- lightning boots + { + itemid = 7892, + type = "equip", + slot = "feet", + level = 35, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- glacier shoes + { + itemid = 7892, + type = "deequip", + slot = "feet", + level = 35 + }, -- glacier shoes + { + itemid = 7891, + type = "equip", + slot = "feet", + level = 35, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- magma boots + { + itemid = 7891, + type = "deequip", + slot = "feet", + level = 35 + }, -- magma boots + { + itemid = 7890, + type = "equip", + slot = "necklace", + level = 60 + }, -- magma amulet + { + itemid = 7890, + type = "deequip", + slot = "necklace", + level = 60 + }, -- magma amulet + { + itemid = 7889, + type = "equip", + slot = "necklace", + level = 60 + }, -- lightning pendant + { + itemid = 7889, + type = "deequip", + slot = "necklace", + level = 60 + }, -- lightning pendant + { + itemid = 7888, + type = "equip", + slot = "necklace", + level = 60 + }, -- glacier amulet + { + itemid = 7888, + type = "deequip", + slot = "necklace", + level = 60 + }, -- glacier amulet + { + itemid = 7887, + type = "equip", + slot = "necklace", + level = 60 + }, -- terra amulet + { + itemid = 7887, + type = "deequip", + slot = "necklace", + level = 60 + }, -- terra amulet + { + itemid = 7886, + type = "equip", + slot = "feet", + level = 35, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- terra boots + { + itemid = 7886, + type = "deequip", + slot = "feet", + level = 35 + }, -- terra boots + { + itemid = 7885, + type = "equip", + slot = "legs", + level = 40, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- terra legs + { + itemid = 7885, + type = "deequip", + slot = "legs", + level = 40 + }, -- terra legs + { + itemid = 7884, + type = "equip", + slot = "armor", + level = 50, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- terra mantle + { + itemid = 7884, + type = "deequip", + slot = "armor", + level = 50 + }, -- terra mantle + { + itemid = 7883, + type = "equip", + slot = "hand" + }, -- energy war hammer + { + itemid = 7883, + type = "deequip", + slot = "hand" + }, -- energy war hammer + { + itemid = 7882, + type = "equip", + slot = "hand" + }, -- energy orcish maul + { + itemid = 7882, + type = "deequip", + slot = "hand" + }, -- energy orcish maul + { + itemid = 7881, + type = "equip", + slot = "hand" + }, -- energy cranial basher + { + itemid = 7881, + type = "deequip", + slot = "hand" + }, -- energy cranial basher + { + itemid = 7880, + type = "equip", + slot = "hand" + }, -- energy crystal mace + { + itemid = 7880, + type = "deequip", + slot = "hand" + }, -- energy crystal mace + { + itemid = 7879, + type = "equip", + slot = "hand" + }, -- energy clerical mace + { + itemid = 7879, + type = "deequip", + slot = "hand" + }, -- energy clerical mace + { + itemid = 7878, + type = "equip", + slot = "hand" + }, -- energy war axe + { + itemid = 7878, + type = "deequip", + slot = "hand" + }, -- energy war axe + { + itemid = 7877, + type = "equip", + slot = "hand" + }, -- energy headchopper + { + itemid = 7877, + type = "deequip", + slot = "hand" + }, -- energy headchopper + { + itemid = 7876, + type = "equip", + slot = "hand" + }, -- energy heroic axe + { + itemid = 7876, + type = "deequip", + slot = "hand" + }, -- energy heroic axe + { + itemid = 7875, + type = "equip", + slot = "hand" + }, -- energy knight axe + { + itemid = 7875, + type = "deequip", + slot = "hand" + }, -- energy knight axe + { + itemid = 7874, + type = "equip", + slot = "hand" + }, -- energy barbarian axe + { + itemid = 7874, + type = "deequip", + slot = "hand" + }, -- energy barbarian axe + { + itemid = 7873, + type = "equip", + slot = "hand" + }, -- energy dragon slayer + { + itemid = 7873, + type = "deequip", + slot = "hand" + }, -- energy dragon slayer + { + itemid = 7872, + type = "equip", + slot = "hand" + }, -- energy blacksteel sword + { + itemid = 7872, + type = "deequip", + slot = "hand" + }, -- energy blacksteel sword + { + itemid = 7871, + type = "equip", + slot = "hand" + }, -- energy mystic blade + { + itemid = 7871, + type = "deequip", + slot = "hand" + }, -- energy mystic blade + { + itemid = 7870, + type = "equip", + slot = "hand" + }, -- energy relic sword + { + itemid = 7870, + type = "deequip", + slot = "hand" + }, -- energy relic sword + { + itemid = 7869, + type = "equip", + slot = "hand" + }, -- energy spike sword + { + itemid = 7869, + type = "deequip", + slot = "hand" + }, -- energy spike sword + { + itemid = 7868, + type = "equip", + slot = "hand" + }, -- earth war hammer + { + itemid = 7868, + type = "deequip", + slot = "hand" + }, -- earth war hammer + { + itemid = 7867, + type = "equip", + slot = "hand" + }, -- earth orcish maul + { + itemid = 7867, + type = "deequip", + slot = "hand" + }, -- earth orcish maul + { + itemid = 7866, + type = "equip", + slot = "hand" + }, -- earth cranial basher + { + itemid = 7866, + type = "deequip", + slot = "hand" + }, -- earth cranial basher + { + itemid = 7865, + type = "equip", + slot = "hand" + }, -- earth crystal mace + { + itemid = 7865, + type = "deequip", + slot = "hand" + }, -- earth crystal mace + { + itemid = 7864, + type = "equip", + slot = "hand" + }, -- earth clerical mace + { + itemid = 7864, + type = "deequip", + slot = "hand" + }, -- earth clerical mace + { + itemid = 7863, + type = "equip", + slot = "hand" + }, -- earth war axe + { + itemid = 7863, + type = "deequip", + slot = "hand" + }, -- earth war axe + { + itemid = 7862, + type = "equip", + slot = "hand" + }, -- earth headchopper + { + itemid = 7862, + type = "deequip", + slot = "hand" + }, -- earth headchopper + { + itemid = 7861, + type = "equip", + slot = "hand" + }, -- earth heroic axe + { + itemid = 7861, + type = "deequip", + slot = "hand" + }, -- earth heroic axe + { + itemid = 7860, + type = "equip", + slot = "hand" + }, -- earth knight axe + { + itemid = 7860, + type = "deequip", + slot = "hand" + }, -- earth knight axe + { + itemid = 7859, + type = "equip", + slot = "hand" + }, -- earth barbarian axe + { + itemid = 7859, + type = "deequip", + slot = "hand" + }, -- earth barbarian axe + { + itemid = 7858, + type = "equip", + slot = "hand" + }, -- earth dragon slayer + { + itemid = 7858, + type = "deequip", + slot = "hand" + }, -- earth dragon slayer + { + itemid = 7857, + type = "equip", + slot = "hand" + }, -- earth blacksteel sword + { + itemid = 7857, + type = "deequip", + slot = "hand" + }, -- earth blacksteel sword + { + itemid = 7856, + type = "equip", + slot = "hand" + }, -- earth mystic blade + { + itemid = 7856, + type = "deequip", + slot = "hand" + }, -- earth mystic blade + { + itemid = 7855, + type = "equip", + slot = "hand" + }, -- earth relic sword + { + itemid = 7855, + type = "deequip", + slot = "hand" + }, -- earth relic sword + { + itemid = 7854, + type = "equip", + slot = "hand" + }, -- earth spike sword + { + itemid = 7854, + type = "deequip", + slot = "hand" + }, -- earth spike sword + { + itemid = 7850, + type = "equip", + slot = "ammo" + }, -- earth arrow + { + itemid = 7850, + type = "deequip", + slot = "ammo" + }, -- earth arrow + { + itemid = 7840, + type = "equip", + slot = "ammo" + }, -- flaming arrow + { + itemid = 7840, + type = "deequip", + slot = "ammo" + }, -- flaming arrow + { + itemid = 7839, + type = "equip", + slot = "ammo" + }, -- shiver arrow + { + itemid = 7839, + type = "deequip", + slot = "ammo" + }, -- shiver arrow + { + itemid = 7838, + type = "equip", + slot = "ammo" + }, -- flash arrow + { + itemid = 7838, + type = "deequip", + slot = "ammo" + }, -- flash arrow + { + itemid = 7777, + type = "equip", + slot = "hand" + }, -- icy war hammer + { + itemid = 7777, + type = "deequip", + slot = "hand" + }, -- icy war hammer + { + itemid = 7776, + type = "equip", + slot = "hand" + }, -- icy orcish maul + { + itemid = 7776, + type = "deequip", + slot = "hand" + }, -- icy orcish maul + { + itemid = 7775, + type = "equip", + slot = "hand" + }, -- icy cranial basher + { + itemid = 7775, + type = "deequip", + slot = "hand" + }, -- icy cranial basher + { + itemid = 7774, + type = "equip", + slot = "hand" + }, -- icy crystal mace + { + itemid = 7774, + type = "deequip", + slot = "hand" + }, -- icy crystal mace + { + itemid = 7773, + type = "equip", + slot = "hand" + }, -- icy clerical mace + { + itemid = 7773, + type = "deequip", + slot = "hand" + }, -- icy clerical mace + { + itemid = 7772, + type = "equip", + slot = "hand" + }, -- icy war axe + { + itemid = 7772, + type = "deequip", + slot = "hand" + }, -- icy war axe + { + itemid = 7771, + type = "equip", + slot = "hand" + }, -- icy headchopper + { + itemid = 7771, + type = "deequip", + slot = "hand" + }, -- icy headchopper + { + itemid = 7770, + type = "equip", + slot = "hand" + }, -- icy heroic axe + { + itemid = 7770, + type = "deequip", + slot = "hand" + }, -- icy heroic axe + { + itemid = 7769, + type = "equip", + slot = "hand" + }, -- icy knight axe + { + itemid = 7769, + type = "deequip", + slot = "hand" + }, -- icy knight axe + { + itemid = 7768, + type = "equip", + slot = "hand" + }, -- icy barbarian axe + { + itemid = 7768, + type = "deequip", + slot = "hand" + }, -- icy barbarian axe + { + itemid = 7767, + type = "equip", + slot = "hand" + }, -- icy dragon slayer + { + itemid = 7767, + type = "deequip", + slot = "hand" + }, -- icy dragon slayer + { + itemid = 7766, + type = "equip", + slot = "hand" + }, -- icy blacksteel sword + { + itemid = 7766, + type = "deequip", + slot = "hand" + }, -- icy blacksteel sword + { + itemid = 7765, + type = "equip", + slot = "hand" + }, -- icy mystic blade + { + itemid = 7765, + type = "deequip", + slot = "hand" + }, -- icy mystic blade + { + itemid = 7764, + type = "equip", + slot = "hand" + }, -- icy relic sword + { + itemid = 7764, + type = "deequip", + slot = "hand" + }, -- icy relic sword + { + itemid = 7763, + type = "equip", + slot = "hand" + }, -- icy spike sword + { + itemid = 7763, + type = "deequip", + slot = "hand" + }, -- icy spike sword + { + itemid = 7758, + type = "equip", + slot = "hand" + }, -- fiery war hammer + { + itemid = 7758, + type = "deequip", + slot = "hand" + }, -- fiery war hammer + { + itemid = 7757, + type = "equip", + slot = "hand" + }, -- fiery orcish maul + { + itemid = 7757, + type = "deequip", + slot = "hand" + }, -- fiery orcish maul + { + itemid = 7756, + type = "equip", + slot = "hand" + }, -- fiery cranial basher + { + itemid = 7756, + type = "deequip", + slot = "hand" + }, -- fiery cranial basher + { + itemid = 7755, + type = "equip", + slot = "hand" + }, -- fiery crystal mace + { + itemid = 7755, + type = "deequip", + slot = "hand" + }, -- fiery crystal mace + { + itemid = 7754, + type = "equip", + slot = "hand" + }, -- fiery clerical mace + { + itemid = 7754, + type = "deequip", + slot = "hand" + }, -- fiery clerical mace + { + itemid = 7753, + type = "equip", + slot = "hand" + }, -- fiery war axe + { + itemid = 7753, + type = "deequip", + slot = "hand" + }, -- fiery war axe + { + itemid = 7752, + type = "equip", + slot = "hand" + }, -- fiery headchopper + { + itemid = 7752, + type = "deequip", + slot = "hand" + }, -- fiery headchopper + { + itemid = 7751, + type = "equip", + slot = "hand" + }, -- fiery heroic axe + { + itemid = 7751, + type = "deequip", + slot = "hand" + }, -- fiery heroic axe + { + itemid = 7750, + type = "equip", + slot = "hand" + }, -- fiery knight axe + { + itemid = 7750, + type = "deequip", + slot = "hand" + }, -- fiery knight axe + { + itemid = 7749, + type = "equip", + slot = "hand" + }, -- fiery barbarian axe + { + itemid = 7749, + type = "deequip", + slot = "hand" + }, -- fiery barbarian axe + { + itemid = 7748, + type = "equip", + slot = "hand" + }, -- fiery dragon slayer + { + itemid = 7748, + type = "deequip", + slot = "hand" + }, -- fiery dragon slayer + { + itemid = 7747, + type = "equip", + slot = "hand" + }, -- fiery blacksteel sword + { + itemid = 7747, + type = "deequip", + slot = "hand" + }, -- fiery blacksteel sword + { + itemid = 7746, + type = "equip", + slot = "hand" + }, -- fiery mystic blade + { + itemid = 7746, + type = "deequip", + slot = "hand" + }, -- fiery mystic blade + { + itemid = 7745, + type = "equip", + slot = "hand" + }, -- fiery relic sword + { + itemid = 7745, + type = "deequip", + slot = "hand" + }, -- fiery relic sword + { + itemid = 7744, + type = "equip", + slot = "hand" + }, -- fiery spike sword + { + itemid = 7744, + type = "deequip", + slot = "hand" + }, -- fiery spike sword + { + itemid = 7730, + type = "equip", + slot = "legs" + }, -- blue legs + { + itemid = 7730, + type = "deequip", + slot = "legs" + }, -- blue legs + { + itemid = 7708, + type = "equip", + slot = "ring" + }, -- suspicious signet ring + { + itemid = 7708, + type = "deequip", + slot = "ring" + }, -- suspicious signet ring + { + itemid = 7697, + type = "equip", + slot = "ring" + }, -- family signet ring + { + itemid = 7697, + type = "deequip", + slot = "ring" + }, -- family signet ring + { + itemid = 7497, + type = "equip", + slot = "head" + }, -- mining helmet + { + itemid = 7497, + type = "deequip", + slot = "head" + }, -- mining helmet + { + itemid = 7464, + type = "equip", + slot = "legs" + }, -- mammoth fur shorts + { + itemid = 7464, + type = "deequip", + slot = "legs" + }, -- mammoth fur shorts + { + itemid = 7463, + type = "equip", + slot = "armor" + }, -- mammoth fur cape + { + itemid = 7463, + type = "deequip", + slot = "armor" + }, -- mammoth fur cape + { + itemid = 7462, + type = "equip", + slot = "head" + }, -- ragnir helmet + { + itemid = 7462, + type = "deequip", + slot = "head" + }, -- ragnir helmet + { + itemid = 7461, + type = "equip", + slot = "head" + }, -- krimhorn helmet + { + itemid = 7461, + type = "deequip", + slot = "head" + }, -- krimhorn helmet + { + itemid = 7460, + type = "equip", + slot = "shield" + }, -- norse shield + { + itemid = 7460, + type = "deequip", + slot = "shield" + }, -- norse shield + { + itemid = 7459, + type = "equip", + slot = "head" + }, -- pair of earmuffs + { + itemid = 7459, + type = "deequip", + slot = "head" + }, -- pair of earmuffs + { + itemid = 7458, + type = "equip", + slot = "head" + }, -- fur cap + { + itemid = 7458, + type = "deequip", + slot = "head" + }, -- fur cap + { + itemid = 7457, + type = "equip", + slot = "feet" + }, -- fur boots + { + itemid = 7457, + type = "deequip", + slot = "feet" + }, -- fur boots + { + itemid = 7456, + type = "equip", + slot = "hand" + }, -- noble axe + { + itemid = 7456, + type = "deequip", + slot = "hand" + }, -- noble axe + { + itemid = 7455, + type = "equip", + slot = "hand" + }, -- mythril axe + { + itemid = 7455, + type = "deequip", + slot = "hand" + }, -- mythril axe + { + itemid = 7454, + type = "equip", + slot = "hand" + }, -- glorious axe + { + itemid = 7454, + type = "deequip", + slot = "hand" + }, -- glorious axe + { + itemid = 7453, + type = "equip", + slot = "hand" + }, -- executioner + { + itemid = 7453, + type = "deequip", + slot = "hand" + }, -- executioner + { + itemid = 7452, + type = "equip", + slot = "hand" + }, -- spiked squelcher + { + itemid = 7452, + type = "deequip", + slot = "hand" + }, -- spiked squelcher + { + itemid = 7451, + type = "equip", + slot = "hand" + }, -- shadow sceptre + { + itemid = 7451, + type = "deequip", + slot = "hand" + }, -- shadow sceptre + { + itemid = 7450, + type = "equip", + slot = "hand" + }, -- hammer of prophecy + { + itemid = 7450, + type = "deequip", + slot = "hand" + }, -- hammer of prophecy + { + itemid = 7449, + type = "equip", + slot = "hand" + }, -- crystal sword + { + itemid = 7449, + type = "deequip", + slot = "hand" + }, -- crystal sword + { + itemid = 7438, + type = "equip", + slot = "hand" + }, -- elvish bow + { + itemid = 7438, + type = "deequip", + slot = "hand" + }, -- elvish bow + { + itemid = 7437, + type = "equip", + slot = "hand" + }, -- sapphire hammer + { + itemid = 7437, + type = "deequip", + slot = "hand" + }, -- sapphire hammer + { + itemid = 7436, + type = "equip", + slot = "hand" + }, -- angelic axe + { + itemid = 7436, + type = "deequip", + slot = "hand" + }, -- angelic axe + { + itemid = 7435, + type = "equip", + slot = "hand" + }, -- impaler + { + itemid = 7435, + type = "deequip", + slot = "hand" + }, -- impaler + { + itemid = 7434, + type = "equip", + slot = "hand" + }, -- royal axe + { + itemid = 7434, + type = "deequip", + slot = "hand" + }, -- royal axe + { + itemid = 7433, + type = "equip", + slot = "hand" + }, -- ravenwing + { + itemid = 7433, + type = "deequip", + slot = "hand" + }, -- ravenwing + { + itemid = 7432, + type = "equip", + slot = "hand" + }, -- furry club + { + itemid = 7432, + type = "deequip", + slot = "hand" + }, -- furry club + { + itemid = 7431, + type = "equip", + slot = "hand" + }, -- demonbone + { + itemid = 7431, + type = "deequip", + slot = "hand" + }, -- demonbone + { + itemid = 7430, + type = "equip", + slot = "hand" + }, -- dragonbone staff + { + itemid = 7430, + type = "deequip", + slot = "hand" + }, -- dragonbone staff + { + itemid = 7429, + type = "equip", + slot = "hand" + }, -- blessed sceptre + { + itemid = 7429, + type = "deequip", + slot = "hand" + }, -- blessed sceptre + { + itemid = 7428, + type = "equip", + slot = "hand" + }, -- bonebreaker + { + itemid = 7428, + type = "deequip", + slot = "hand" + }, -- bonebreaker + { + itemid = 7427, + type = "equip", + slot = "hand" + }, -- chaos mace + { + itemid = 7427, + type = "deequip", + slot = "hand" + }, -- chaos mace + { + itemid = 7426, + type = "equip", + slot = "hand" + }, -- amber staff + { + itemid = 7426, + type = "deequip", + slot = "hand" + }, -- amber staff + { + itemid = 7425, + type = "equip", + slot = "hand" + }, -- taurus mace + { + itemid = 7425, + type = "deequip", + slot = "hand" + }, -- taurus mace + { + itemid = 7424, + type = "equip", + slot = "hand" + }, -- lunar staff + { + itemid = 7424, + type = "deequip", + slot = "hand" + }, -- lunar staff + { + itemid = 7423, + type = "equip", + slot = "hand" + }, -- skullcrusher + { + itemid = 7423, + type = "deequip", + slot = "hand" + }, -- skullcrusher + { + itemid = 7422, + type = "equip", + slot = "hand" + }, -- jade hammer + { + itemid = 7422, + type = "deequip", + slot = "hand" + }, -- jade hammer + { + itemid = 7421, + type = "equip", + slot = "hand" + }, -- onyx flail + { + itemid = 7421, + type = "deequip", + slot = "hand" + }, -- onyx flail + { + itemid = 7420, + type = "equip", + slot = "hand" + }, -- reaper's axe + { + itemid = 7420, + type = "deequip", + slot = "hand" + }, -- reaper's axe + { + itemid = 7419, + type = "equip", + slot = "hand" + }, -- dreaded cleaver + { + itemid = 7419, + type = "deequip", + slot = "hand" + }, -- dreaded cleaver + { + itemid = 7418, + type = "equip", + slot = "hand" + }, -- nightmare blade + { + itemid = 7418, + type = "deequip", + slot = "hand" + }, -- nightmare blade + { + itemid = 7417, + type = "equip", + slot = "hand" + }, -- runed sword + { + itemid = 7417, + type = "deequip", + slot = "hand" + }, -- runed sword + { + itemid = 7416, + type = "equip", + slot = "hand" + }, -- bloody edge + { + itemid = 7416, + type = "deequip", + slot = "hand" + }, -- bloody edge + { + itemid = 7415, + type = "equip", + slot = "hand" + }, -- cranial basher + { + itemid = 7415, + type = "deequip", + slot = "hand" + }, -- cranial basher + { + itemid = 7414, + type = "equip", + slot = "hand" + }, -- abyss hammer + { + itemid = 7414, + type = "deequip", + slot = "hand" + }, -- abyss hammer + { + itemid = 7413, + type = "equip", + slot = "hand" + }, -- titan axe + { + itemid = 7413, + type = "deequip", + slot = "hand" + }, -- titan axe + { + itemid = 7412, + type = "equip", + slot = "hand" + }, -- butcher's axe + { + itemid = 7412, + type = "deequip", + slot = "hand" + }, -- butcher's axe + { + itemid = 7411, + type = "equip", + slot = "hand" + }, -- ornamented axe + { + itemid = 7411, + type = "deequip", + slot = "hand" + }, -- ornamented axe + { + itemid = 7410, + type = "equip", + slot = "hand" + }, -- queen's sceptre + { + itemid = 7410, + type = "deequip", + slot = "hand" + }, -- queen's sceptre + { + itemid = 7409, + type = "equip", + slot = "hand" + }, -- northern star + { + itemid = 7409, + type = "deequip", + slot = "hand" + }, -- northern star + { + itemid = 7408, + type = "equip", + slot = "hand" + }, -- wyvern fang + { + itemid = 7408, + type = "deequip", + slot = "hand" + }, -- wyvern fang + { + itemid = 7407, + type = "equip", + slot = "hand" + }, -- haunted blade + { + itemid = 7407, + type = "deequip", + slot = "hand" + }, -- haunted blade + { + itemid = 7406, + type = "equip", + slot = "hand" + }, -- blacksteel sword + { + itemid = 7406, + type = "deequip", + slot = "hand" + }, -- blacksteel sword + { + itemid = 7405, + type = "equip", + slot = "hand" + }, -- havoc blade + { + itemid = 7405, + type = "deequip", + slot = "hand" + }, -- havoc blade + { + itemid = 7404, + type = "equip", + slot = "hand" + }, -- assassin dagger + { + itemid = 7404, + type = "deequip", + slot = "hand" + }, -- assassin dagger + { + itemid = 7403, + type = "equip", + slot = "hand" + }, -- berserker + { + itemid = 7403, + type = "deequip", + slot = "hand" + }, -- berserker + { + itemid = 7402, + type = "equip", + slot = "hand" + }, -- dragon slayer + { + itemid = 7402, + type = "deequip", + slot = "hand" + }, -- dragon slayer + { + itemid = 7392, + type = "equip", + slot = "hand" + }, -- orcish maul + { + itemid = 7392, + type = "deequip", + slot = "hand" + }, -- orcish maul + { + itemid = 7391, + type = "equip", + slot = "hand" + }, -- thaian sword + { + itemid = 7391, + type = "deequip", + slot = "hand" + }, -- thaian sword + { + itemid = 7390, + type = "equip", + slot = "hand" + }, -- the justice seeker + { + itemid = 7390, + type = "deequip", + slot = "hand" + }, -- the justice seeker + { + itemid = 7389, + type = "equip", + slot = "hand" + }, -- heroic axe + { + itemid = 7389, + type = "deequip", + slot = "hand" + }, -- heroic axe + { + itemid = 7388, + type = "equip", + slot = "hand" + }, -- vile axe + { + itemid = 7388, + type = "deequip", + slot = "hand" + }, -- vile axe + { + itemid = 7387, + type = "equip", + slot = "hand" + }, -- diamond sceptre + { + itemid = 7387, + type = "deequip", + slot = "hand" + }, -- diamond sceptre + { + itemid = 7386, + type = "equip", + slot = "hand" + }, -- mercenary sword + { + itemid = 7386, + type = "deequip", + slot = "hand" + }, -- mercenary sword + { + itemid = 7385, + type = "equip", + slot = "hand" + }, -- crimson sword + { + itemid = 7385, + type = "deequip", + slot = "hand" + }, -- crimson sword + { + itemid = 7384, + type = "equip", + slot = "hand" + }, -- mystic blade + { + itemid = 7384, + type = "deequip", + slot = "hand" + }, -- mystic blade + { + itemid = 7383, + type = "equip", + slot = "hand" + }, -- relic sword + { + itemid = 7383, + type = "deequip", + slot = "hand" + }, -- relic sword + { + itemid = 7382, + type = "equip", + slot = "hand" + }, -- demonrage sword + { + itemid = 7382, + type = "deequip", + slot = "hand" + }, -- demonrage sword + { + itemid = 7381, + type = "equip", + slot = "hand" + }, -- mammoth whopper + { + itemid = 7381, + type = "deequip", + slot = "hand" + }, -- mammoth whopper + { + itemid = 7380, + type = "equip", + slot = "hand" + }, -- headchopper + { + itemid = 7380, + type = "deequip", + slot = "hand" + }, -- headchopper + { + itemid = 7379, + type = "equip", + slot = "hand" + }, -- brutetamer's staff + { + itemid = 7379, + type = "deequip", + slot = "hand" + }, -- brutetamer's staff + { + itemid = 7378, + type = "equip", + slot = "hand" + }, -- royal spear + { + itemid = 7378, + type = "deequip", + slot = "hand" + }, -- royal spear + { + itemid = 7368, + type = "equip", + slot = "hand" + }, -- assassin star + { + itemid = 7368, + type = "deequip", + slot = "hand" + }, -- assassin star + { + itemid = 7367, + type = "equip", + slot = "hand" + }, -- enchanted spear + { + itemid = 7367, + type = "deequip", + slot = "hand" + }, -- enchanted spear + { + itemid = 7365, + type = "equip", + slot = "ammo" + }, -- onyx arrow + { + itemid = 7365, + type = "deequip", + slot = "ammo" + }, -- onyx arrow + { + itemid = 7364, + type = "equip", + slot = "ammo" + }, -- sniper arrow + { + itemid = 7364, + type = "deequip", + slot = "ammo" + }, -- sniper arrow + { + itemid = 7363, + type = "equip", + slot = "ammo" + }, -- piercing bolt + { + itemid = 7363, + type = "deequip", + slot = "ammo" + }, -- piercing bolt + { + itemid = 7360, + type = "additem" + }, -- flame of life + { + itemid = 7359, + type = "stepin" + }, -- flame of life + { + itemid = 7343, + type = "equip", + slot = "backpack" + }, -- fur bag + { + itemid = 7343, + type = "deequip", + slot = "backpack" + }, -- fur bag + { + itemid = 7342, + type = "equip", + slot = "backpack" + }, -- fur backpack + { + itemid = 7342, + type = "deequip", + slot = "backpack" + }, -- fur backpack + { + itemid = 6578, + type = "equip", + slot = "head" + }, -- party hat + { + itemid = 6578, + type = "deequip", + slot = "head" + }, -- party hat + { + itemid = 6553, + type = "equip", + slot = "hand" + }, -- ruthless axe + { + itemid = 6553, + type = "deequip", + slot = "hand" + }, -- ruthless axe + { + itemid = 6531, + type = "equip", + slot = "head" + }, -- santa hat + { + itemid = 6531, + type = "deequip", + slot = "head" + }, -- santa hat + { + itemid = 6529, + type = "equip", + slot = "ammo" + }, -- infernal bolt + { + itemid = 6529, + type = "deequip", + slot = "ammo" + }, -- infernal bolt + { + itemid = 6528, + type = "equip", + slot = "hand" + }, -- the avenger + { + itemid = 6528, + type = "deequip", + slot = "hand" + }, -- the avenger + { + itemid = 6433, + type = "equip", + slot = "shield" + }, -- necromancer shield + { + itemid = 6433, + type = "deequip", + slot = "shield" + }, -- necromancer shield + { + itemid = 6391, + type = "equip", + slot = "shield" + }, -- nightmare shield + { + itemid = 6391, + type = "deequip", + slot = "shield" + }, -- nightmare shield + { + itemid = 6301, + type = "equip", + slot = "ring" + }, -- death ring + { + itemid = 6301, + type = "deequip", + slot = "ring" + }, -- death ring + { + itemid = 6300, + type = "equip", + slot = "ring" + }, -- death ring + { + itemid = 6300, + type = "deequip", + slot = "ring" + }, -- death ring + { + itemid = 6132, + type = "equip", + slot = "feet", + level = 180 + }, -- pair of soft boots + { + itemid = 6132, + type = "deequip", + slot = "feet", + level = 180 + }, -- pair of soft boots + { + itemid = 6131, + type = "equip", + slot = "shield" + }, -- tortoise shield + { + itemid = 6131, + type = "deequip", + slot = "shield" + }, -- tortoise shield + { + itemid = 6120, + type = "equip", + slot = "shield" + }, -- Dragha's spellbook + { + itemid = 6120, + type = "deequip", + slot = "shield" + }, -- Dragha's spellbook + { + itemid = 6101, + type = "equip", + slot = "hand" + }, -- Ron the Ripper's sabre + { + itemid = 6101, + type = "deequip", + slot = "hand" + }, -- Ron the Ripper's sabre + { + itemid = 6096, + type = "equip", + slot = "head" + }, -- pirate hat + { + itemid = 6096, + type = "deequip", + slot = "head" + }, -- pirate hat + { + itemid = 6095, + type = "equip", + slot = "armor" + }, -- pirate shirt + { + itemid = 6095, + type = "deequip", + slot = "armor" + }, -- pirate shirt + { + itemid = 5950, + type = "equip", + slot = "backpack" + }, -- beach bag + { + itemid = 5950, + type = "deequip", + slot = "backpack" + }, -- beach bag + { + itemid = 5949, + type = "equip", + slot = "backpack" + }, -- beach backpack + { + itemid = 5949, + type = "deequip", + slot = "backpack" + }, -- beach backpack + { + itemid = 5927, + type = "equip", + slot = "backpack" + }, -- pirate bag + { + itemid = 5927, + type = "deequip", + slot = "backpack" + }, -- pirate bag + { + itemid = 5926, + type = "equip", + slot = "backpack" + }, -- pirate backpack + { + itemid = 5926, + type = "deequip", + slot = "backpack" + }, -- pirate backpack + { + itemid = 5918, + type = "equip", + slot = "legs" + }, -- pirate knee breeches + { + itemid = 5918, + type = "deequip", + slot = "legs" + }, -- pirate knee breeches + { + itemid = 5917, + type = "equip", + slot = "head" + }, -- bandana + { + itemid = 5917, + type = "deequip", + slot = "head" + }, -- bandana + { + itemid = 5903, + type = "equip", + slot = "head" + }, -- Ferumbras' hat + { + itemid = 5903, + type = "deequip", + slot = "head" + }, -- Ferumbras' hat + { + itemid = 5803, + type = "equip", + slot = "hand" + }, -- arbalest + { + itemid = 5803, + type = "deequip", + slot = "hand" + }, -- arbalest + { + itemid = 5801, + type = "equip", + slot = "backpack" + }, -- jewelled backpack + { + itemid = 5801, + type = "deequip", + slot = "backpack" + }, -- jewelled backpack + { + itemid = 5741, + type = "equip", + slot = "head" + }, -- skull helmet + { + itemid = 5741, + type = "deequip", + slot = "head" + }, -- skull helmet + { + itemid = 5462, + type = "equip", + slot = "feet" + }, -- pirate boots + { + itemid = 5462, + type = "deequip", + slot = "feet" + }, -- pirate boots + { + itemid = 5461, + type = "equip", + slot = "head" + }, -- helmet of the deep + { + itemid = 5461, + type = "deequip", + slot = "head" + }, -- helmet of the deep + { + itemid = 4847, + type = "equip", + slot = "armor" + }, -- spectral dress + { + itemid = 4847, + type = "deequip", + slot = "armor" + }, -- spectral dress + { + itemid = 3983, + type = "equip", + slot = "legs" + }, -- bast skirt + { + itemid = 3983, + type = "deequip", + slot = "legs" + }, -- bast skirt + { + itemid = 3982, + type = "equip", + slot = "feet" + }, -- crocodile boots + { + itemid = 3982, + type = "deequip", + slot = "feet" + }, -- crocodile boots + { + itemid = 3975, + type = "equip", + slot = "shield" + }, -- salamander shield + { + itemid = 3975, + type = "deequip", + slot = "shield" + }, -- salamander shield + { + itemid = 3974, + type = "equip", + slot = "shield" + }, -- sentinel shield + { + itemid = 3974, + type = "deequip", + slot = "shield" + }, -- sentinel shield + { + itemid = 3973, + type = "equip", + slot = "shield" + }, -- tusk shield + { + itemid = 3973, + type = "deequip", + slot = "shield" + }, -- tusk shield + { + itemid = 3972, + type = "equip", + slot = "head" + }, -- bonelord helmet + { + itemid = 3972, + type = "deequip", + slot = "head" + }, -- bonelord helmet + { + itemid = 3971, + type = "equip", + slot = "head" + }, -- charmer's tiara + { + itemid = 3971, + type = "deequip", + slot = "head" + }, -- charmer's tiara + { + itemid = 3970, + type = "equip", + slot = "head" + }, -- feather headdress + { + itemid = 3970, + type = "deequip", + slot = "head" + }, -- feather headdress + { + itemid = 3969, + type = "equip", + slot = "head" + }, -- horseman helmet + { + itemid = 3969, + type = "deequip", + slot = "head" + }, -- horseman helmet + { + itemid = 3968, + type = "equip", + slot = "armor" + }, -- leopard armor + { + itemid = 3968, + type = "deequip", + slot = "armor" + }, -- leopard armor + { + itemid = 3967, + type = "equip", + slot = "head" + }, -- tribal mask + { + itemid = 3967, + type = "deequip", + slot = "head" + }, -- tribal mask + { + itemid = 3966, + type = "equip", + slot = "hand" + }, -- banana staff + { + itemid = 3966, + type = "deequip", + slot = "hand" + }, -- banana staff + { + itemid = 3965, + type = "equip", + slot = "hand" + }, -- hunting spear + { + itemid = 3965, + type = "deequip", + slot = "hand" + }, -- hunting spear + { + itemid = 3964, + type = "equip", + slot = "hand" + }, -- ripper lance + { + itemid = 3964, + type = "deequip", + slot = "hand" + }, -- ripper lance + { + itemid = 3963, + type = "equip", + slot = "hand" + }, -- templar scytheblade + { + itemid = 3963, + type = "deequip", + slot = "hand" + }, -- templar scytheblade + { + itemid = 3962, + type = "equip", + slot = "hand" + }, -- beastslayer axe + { + itemid = 3962, + type = "deequip", + slot = "hand" + }, -- beastslayer axe + { + itemid = 3961, + type = "equip", + slot = "hand" + }, -- lich staff + { + itemid = 3961, + type = "deequip", + slot = "hand" + }, -- lich staff + { + itemid = 3960, + type = "equip", + slot = "backpack" + }, -- old and used backpack + { + itemid = 3960, + type = "deequip", + slot = "backpack" + }, -- old and used backpack + { + itemid = 3940, + type = "equip", + slot = "backpack" + }, -- camouflage backpack + { + itemid = 3940, + type = "deequip", + slot = "backpack" + }, -- camouflage backpack + { + itemid = 3939, + type = "equip", + slot = "backpack" + }, -- camouflage bag + { + itemid = 3939, + type = "deequip", + slot = "backpack" + }, -- camouflage bag + { + itemid = 2665, + type = "equip", + slot = "head" + }, -- post officer's hat + { + itemid = 2665, + type = "deequip", + slot = "head" + }, -- post officer's hat + { + itemid = 2664, + type = "equip", + slot = "head", + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- wood cape + { + itemid = 2664, + type = "deequip", + slot = "head" + }, -- wood cape + { + itemid = 2663, + type = "equip", + slot = "head" + }, -- mystic turban + { + itemid = 2663, + type = "deequip", + slot = "head" + }, -- mystic turban + { + itemid = 2662, + type = "equip", + slot = "head" + }, -- magician hat + { + itemid = 2662, + type = "deequip", + slot = "head" + }, -- magician hat + { + itemid = 2661, + type = "equip", + slot = "necklace" + }, -- scarf + { + itemid = 2661, + type = "deequip", + slot = "necklace" + }, -- scarf + { + itemid = 2660, + type = "equip", + slot = "armor", + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- ranger's cloak + { + itemid = 2660, + type = "deequip", + slot = "armor" + }, -- ranger's cloak + { + itemid = 2659, + type = "equip", + slot = "armor" + }, -- ball gown + { + itemid = 2659, + type = "deequip", + slot = "armor" + }, -- ball gown + { + itemid = 2658, + type = "equip", + slot = "armor" + }, -- white dress + { + itemid = 2658, + type = "deequip", + slot = "armor" + }, -- white dress + { + itemid = 2657, + type = "equip", + slot = "armor" + }, -- simple dress + { + itemid = 2657, + type = "deequip", + slot = "armor" + }, -- simple dress + { + itemid = 2656, + type = "equip", + slot = "armor" + }, -- blue robe + { + itemid = 2656, + type = "deequip", + slot = "armor" + }, -- blue robe + { + itemid = 2655, + type = "equip", + slot = "armor" + }, -- red robe + { + itemid = 2655, + type = "deequip", + slot = "armor" + }, -- red robe + { + itemid = 2654, + type = "equip", + slot = "armor" + }, -- cape + { + itemid = 2654, + type = "deequip", + slot = "armor" + }, -- cape + { + itemid = 2653, + type = "equip", + slot = "armor" + }, -- red tunic + { + itemid = 2653, + type = "deequip", + slot = "armor" + }, -- red tunic + { + itemid = 2652, + type = "equip", + slot = "armor" + }, -- green tunic + { + itemid = 2652, + type = "deequip", + slot = "armor" + }, -- green tunic + { + itemid = 2651, + type = "equip", + slot = "armor" + }, -- coat + { + itemid = 2651, + type = "deequip", + slot = "armor" + }, -- coat + { + itemid = 2650, + type = "equip", + slot = "armor" + }, -- jacket + { + itemid = 2650, + type = "deequip", + slot = "armor" + }, -- jacket + { + itemid = 2649, + type = "equip", + slot = "legs" + }, -- leather legs + { + itemid = 2649, + type = "deequip", + slot = "legs" + }, -- leather legs + { + itemid = 2648, + type = "equip", + slot = "legs" + }, -- chain legs + { + itemid = 2648, + type = "deequip", + slot = "legs" + }, -- chain legs + { + itemid = 2647, + type = "equip", + slot = "legs" + }, -- plate legs + { + itemid = 2647, + type = "deequip", + slot = "legs" + }, -- plate legs + { + itemid = 2646, + type = "equip", + slot = "feet" + }, -- golden boots + { + itemid = 2646, + type = "deequip", + slot = "feet" + }, -- golden boots + { + itemid = 2645, + type = "equip", + slot = "feet" + }, -- steel boots + { + itemid = 2645, + type = "deequip", + slot = "feet" + }, -- steel boots + { + itemid = 2644, + type = "equip", + slot = "feet" + }, -- bunnyslippers + { + itemid = 2644, + type = "deequip", + slot = "feet" + }, -- bunnyslippers + { + itemid = 2643, + type = "equip", + slot = "feet" + }, -- leather boots + { + itemid = 2643, + type = "deequip", + slot = "feet" + }, -- leather boots + { + itemid = 2642, + type = "equip", + slot = "feet" + }, -- sandals + { + itemid = 2642, + type = "deequip", + slot = "feet" + }, -- sandals + { + itemid = 2641, + type = "equip", + slot = "feet" + }, -- patched boots + { + itemid = 2641, + type = "deequip", + slot = "feet" + }, -- patched boots + { + itemid = 2640, + type = "equip", + slot = "feet", + level = 180 + }, -- pair of soft boots + { + itemid = 2640, + type = "deequip", + slot = "feet", + level = 180 + }, -- pair of soft boots + { + itemid = 2550, + type = "equip", + slot = "hand" + }, -- scythe + { + itemid = 2550, + type = "deequip", + slot = "hand" + }, -- scythe + { + itemid = 2547, + type = "equip", + slot = "ammo" + }, -- power bolt + { + itemid = 2547, + type = "deequip", + slot = "ammo" + }, -- power bolt + { + itemid = 2544, + type = "equip", + slot = "ammo" + }, -- arrow + { + itemid = 2544, + type = "deequip", + slot = "ammo" + }, -- arrow + { + itemid = 2543, + type = "equip", + slot = "ammo" + }, -- bolt + { + itemid = 2543, + type = "deequip", + slot = "ammo" + }, -- bolt + { + itemid = 2542, + type = "equip", + slot = "shield" + }, -- tempest shield + { + itemid = 2542, + type = "deequip", + slot = "shield" + }, -- tempest shield + { + itemid = 2541, + type = "equip", + slot = "shield" + }, -- bone shield + { + itemid = 2541, + type = "deequip", + slot = "shield" + }, -- bone shield + { + itemid = 2540, + type = "equip", + slot = "shield" + }, -- scarab shield + { + itemid = 2540, + type = "deequip", + slot = "shield" + }, -- scarab shield + { + itemid = 2539, + type = "equip", + slot = "shield" + }, -- phoenix shield + { + itemid = 2539, + type = "deequip", + slot = "shield" + }, -- phoenix shield + { + itemid = 2538, + type = "equip", + slot = "shield" + }, -- eagle shield + { + itemid = 2538, + type = "deequip", + slot = "shield" + }, -- eagle shield + { + itemid = 2537, + type = "equip", + slot = "shield" + }, -- amazon shield + { + itemid = 2537, + type = "deequip", + slot = "shield" + }, -- amazon shield + { + itemid = 2536, + type = "equip", + slot = "shield" + }, -- medusa shield + { + itemid = 2536, + type = "deequip", + slot = "shield" + }, -- medusa shield + { + itemid = 2535, + type = "equip", + slot = "shield" + }, -- castle shield + { + itemid = 2535, + type = "deequip", + slot = "shield" + }, -- castle shield + { + itemid = 2534, + type = "equip", + slot = "shield" + }, -- vampire shield + { + itemid = 2534, + type = "deequip", + slot = "shield" + }, -- vampire shield + { + itemid = 2533, + type = "equip", + slot = "shield" + }, -- griffin shield + { + itemid = 2533, + type = "deequip", + slot = "shield" + }, -- griffin shield + { + itemid = 2532, + type = "equip", + slot = "shield" + }, -- ancient shield + { + itemid = 2532, + type = "deequip", + slot = "shield" + }, -- ancient shield + { + itemid = 2531, + type = "equip", + slot = "shield" + }, -- viking shield + { + itemid = 2531, + type = "deequip", + slot = "shield" + }, -- viking shield + { + itemid = 2530, + type = "equip", + slot = "shield" + }, -- copper shield + { + itemid = 2530, + type = "deequip", + slot = "shield" + }, -- copper shield + { + itemid = 2529, + type = "equip", + slot = "shield" + }, -- black shield + { + itemid = 2529, + type = "deequip", + slot = "shield" + }, -- black shield + { + itemid = 2528, + type = "equip", + slot = "shield" + }, -- tower shield + { + itemid = 2528, + type = "deequip", + slot = "shield" + }, -- tower shield + { + itemid = 2527, + type = "equip", + slot = "shield" + }, -- rose shield + { + itemid = 2527, + type = "deequip", + slot = "shield" + }, -- rose shield + { + itemid = 2526, + type = "equip", + slot = "shield" + }, -- studded shield + { + itemid = 2526, + type = "deequip", + slot = "shield" + }, -- studded shield + { + itemid = 2525, + type = "equip", + slot = "shield" + }, -- dwarven shield + { + itemid = 2525, + type = "deequip", + slot = "shield" + }, -- dwarven shield + { + itemid = 2524, + type = "equip", + slot = "shield" + }, -- ornamented shield + { + itemid = 2524, + type = "deequip", + slot = "shield" + }, -- ornamented shield + { + itemid = 2523, + type = "equip", + slot = "shield" + }, -- blessed shield + { + itemid = 2523, + type = "deequip", + slot = "shield" + }, -- blessed shield + { + itemid = 2522, + type = "equip", + slot = "shield" + }, -- great shield + { + itemid = 2522, + type = "deequip", + slot = "shield" + }, -- great shield + { + itemid = 2521, + type = "equip", + slot = "shield" + }, -- dark shield + { + itemid = 2521, + type = "deequip", + slot = "shield" + }, -- dark shield + { + itemid = 2520, + type = "equip", + slot = "shield" + }, -- demon shield + { + itemid = 2520, + type = "deequip", + slot = "shield" + }, -- demon shield + { + itemid = 2519, + type = "equip", + slot = "shield" + }, -- crown shield + { + itemid = 2519, + type = "deequip", + slot = "shield" + }, -- crown shield + { + itemid = 2518, + type = "equip", + slot = "shield" + }, -- bonelord shield + { + itemid = 2518, + type = "deequip", + slot = "shield" + }, -- bonelord shield + { + itemid = 2517, + type = "equip", + slot = "shield" + }, -- shield of honour + { + itemid = 2517, + type = "deequip", + slot = "shield" + }, -- shield of honour + { + itemid = 2516, + type = "equip", + slot = "shield" + }, -- dragon shield + { + itemid = 2516, + type = "deequip", + slot = "shield" + }, -- dragon shield + { + itemid = 2515, + type = "equip", + slot = "shield" + }, -- guardian shield + { + itemid = 2515, + type = "deequip", + slot = "shield" + }, -- guardian shield + { + itemid = 2514, + type = "equip", + slot = "shield" + }, -- mastermind shield + { + itemid = 2514, + type = "deequip", + slot = "shield" + }, -- mastermind shield + { + itemid = 2513, + type = "equip", + slot = "shield" + }, -- battle shield + { + itemid = 2513, + type = "deequip", + slot = "shield" + }, -- battle shield + { + itemid = 2512, + type = "equip", + slot = "shield" + }, -- wooden shield + { + itemid = 2512, + type = "deequip", + slot = "shield" + }, -- wooden shield + { + itemid = 2511, + type = "equip", + slot = "shield" + }, -- brass shield + { + itemid = 2511, + type = "deequip", + slot = "shield" + }, -- brass shield + { + itemid = 2510, + type = "equip", + slot = "shield" + }, -- plate shield + { + itemid = 2510, + type = "deequip", + slot = "shield" + }, -- plate shield + { + itemid = 2509, + type = "equip", + slot = "shield" + }, -- steel shield + { + itemid = 2509, + type = "deequip", + slot = "shield" + }, -- steel shield + { + itemid = 2508, + type = "equip", + slot = "armor" + }, -- native armor + { + itemid = 2508, + type = "deequip", + slot = "armor" + }, -- native armor + { + itemid = 2507, + type = "equip", + slot = "legs" + }, -- elven legs + { + itemid = 2507, + type = "deequip", + slot = "legs" + }, -- elven legs + { + itemid = 2506, + type = "equip", + slot = "head" + }, -- dragon scale helmet + { + itemid = 2506, + type = "deequip", + slot = "head" + }, -- dragon scale helmet + { + itemid = 2505, + type = "equip", + slot = "armor" + }, -- elven mail + { + itemid = 2505, + type = "deequip", + slot = "armor" + }, -- elven mail + { + itemid = 2504, + type = "equip", + slot = "legs" + }, -- dwarven legs + { + itemid = 2504, + type = "deequip", + slot = "legs" + }, -- dwarven legs + { + itemid = 2503, + type = "equip", + slot = "armor" + }, -- dwarven armor + { + itemid = 2503, + type = "deequip", + slot = "armor" + }, -- dwarven armor + { + itemid = 2502, + type = "equip", + slot = "head" + }, -- dwarven helmet + { + itemid = 2502, + type = "deequip", + slot = "head" + }, -- dwarven helmet + { + itemid = 2501, + type = "equip", + slot = "head" + }, -- ceremonial mask + { + itemid = 2501, + type = "deequip", + slot = "head" + }, -- ceremonial mask + { + itemid = 2500, + type = "equip", + slot = "armor", + level = 60, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- amazon armor + { + itemid = 2500, + type = "deequip", + slot = "armor", + level = 60 + }, -- amazon armor + { + itemid = 2499, + type = "equip", + slot = "head" + }, -- amazon helmet + { + itemid = 2499, + type = "deequip", + slot = "head" + }, -- amazon helmet + { + itemid = 2498, + type = "equip", + slot = "head" + }, -- royal helmet + { + itemid = 2498, + type = "deequip", + slot = "head" + }, -- royal helmet + { + itemid = 2497, + type = "equip", + slot = "head" + }, -- crusader helmet + { + itemid = 2497, + type = "deequip", + slot = "head" + }, -- crusader helmet + { + itemid = 2496, + type = "equip", + slot = "head" + }, -- horned helmet + { + itemid = 2496, + type = "deequip", + slot = "head" + }, -- horned helmet + { + itemid = 2495, + type = "equip", + slot = "legs" + }, -- demon legs + { + itemid = 2495, + type = "deequip", + slot = "legs" + }, -- demon legs + { + itemid = 2494, + type = "equip", + slot = "armor" + }, -- demon armor + { + itemid = 2494, + type = "deequip", + slot = "armor" + }, -- demon armor + { + itemid = 2493, + type = "equip", + slot = "head" + }, -- demon helmet + { + itemid = 2493, + type = "deequip", + slot = "head" + }, -- demon helmet + { + itemid = 2492, + type = "equip", + slot = "armor", + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- dragon scale mail + { + itemid = 2492, + type = "deequip", + slot = "armor" + }, -- dragon scale mail + { + itemid = 2491, + type = "equip", + slot = "head" + }, -- crown helmet + { + itemid = 2491, + type = "deequip", + slot = "head" + }, -- crown helmet + { + itemid = 2490, + type = "equip", + slot = "head" + }, -- dark helmet + { + itemid = 2490, + type = "deequip", + slot = "head" + }, -- dark helmet + { + itemid = 2489, + type = "equip", + slot = "armor" + }, -- dark armor + { + itemid = 2489, + type = "deequip", + slot = "armor" + }, -- dark armor + { + itemid = 2488, + type = "equip", + slot = "legs", + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- crown legs + { + itemid = 2488, + type = "deequip", + slot = "legs" + }, -- crown legs + { + itemid = 2487, + type = "equip", + slot = "armor", + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- crown armor + { + itemid = 2487, + type = "deequip", + slot = "armor" + }, -- crown armor + { + itemid = 2486, + type = "equip", + slot = "armor" + }, -- noble armor + { + itemid = 2486, + type = "deequip", + slot = "armor" + }, -- noble armor + { + itemid = 2485, + type = "equip", + slot = "armor" + }, -- doublet + { + itemid = 2485, + type = "deequip", + slot = "armor" + }, -- doublet + { + itemid = 2484, + type = "equip", + slot = "armor" + }, -- studded armor + { + itemid = 2484, + type = "deequip", + slot = "armor" + }, -- studded armor + { + itemid = 2483, + type = "equip", + slot = "armor" + }, -- scale armor + { + itemid = 2483, + type = "deequip", + slot = "armor" + }, -- scale armor + { + itemid = 2482, + type = "equip", + slot = "head" + }, -- studded helmet + { + itemid = 2482, + type = "deequip", + slot = "head" + }, -- studded helmet + { + itemid = 2481, + type = "equip", + slot = "head" + }, -- soldier helmet + { + itemid = 2481, + type = "deequip", + slot = "head" + }, -- soldier helmet + { + itemid = 2480, + type = "equip", + slot = "head" + }, -- legion helmet + { + itemid = 2480, + type = "deequip", + slot = "head" + }, -- legion helmet + { + itemid = 2479, + type = "equip", + slot = "head" + }, -- strange helmet + { + itemid = 2479, + type = "deequip", + slot = "head" + }, -- strange helmet + { + itemid = 2478, + type = "equip", + slot = "legs" + }, -- brass legs + { + itemid = 2478, + type = "deequip", + slot = "legs" + }, -- brass legs + { + itemid = 2477, + type = "equip", + slot = "legs", + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- knight legs + { + itemid = 2477, + type = "deequip", + slot = "legs" + }, -- knight legs + { + itemid = 2476, + type = "equip", + slot = "armor", + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- knight armor + { + itemid = 2476, + type = "deequip", + slot = "armor" + }, -- knight armor + { + itemid = 2475, + type = "equip", + slot = "head" + }, -- warrior helmet + { + itemid = 2475, + type = "deequip", + slot = "head" + }, -- warrior helmet + { + itemid = 2474, + type = "equip", + slot = "head" + }, -- winged helmet + { + itemid = 2474, + type = "deequip", + slot = "head" + }, -- winged helmet + { + itemid = 2473, + type = "equip", + slot = "head" + }, -- viking helmet + { + itemid = 2473, + type = "deequip", + slot = "head" + }, -- viking helmet + { + itemid = 2472, + type = "equip", + slot = "armor", + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- magic plate armor + { + itemid = 2472, + type = "deequip", + slot = "armor" + }, -- magic plate armor + { + itemid = 2471, + type = "equip", + slot = "head" + }, -- golden helmet + { + itemid = 2471, + type = "deequip", + slot = "head" + }, -- golden helmet + { + itemid = 2470, + type = "equip", + slot = "legs", + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- golden legs + { + itemid = 2470, + type = "deequip", + slot = "legs" + }, -- golden legs + { + itemid = 2469, + type = "equip", + slot = "legs" + }, -- dragon scale legs + { + itemid = 2469, + type = "deequip", + slot = "legs" + }, -- dragon scale legs + { + itemid = 2468, + type = "equip", + slot = "legs" + }, -- studded legs + { + itemid = 2468, + type = "deequip", + slot = "legs" + }, -- studded legs + { + itemid = 2467, + type = "equip", + slot = "armor" + }, -- leather armor + { + itemid = 2467, + type = "deequip", + slot = "armor" + }, -- leather armor + { + itemid = 2466, + type = "equip", + slot = "armor", + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- golden armor + { + itemid = 2466, + type = "deequip", + slot = "armor" + }, -- golden armor + { + itemid = 2465, + type = "equip", + slot = "armor" + }, -- brass armor + { + itemid = 2465, + type = "deequip", + slot = "armor" + }, -- brass armor + { + itemid = 2464, + type = "equip", + slot = "armor" + }, -- chain armor + { + itemid = 2464, + type = "deequip", + slot = "armor" + }, -- chain armor + { + itemid = 2463, + type = "equip", + slot = "armor" + }, -- plate armor + { + itemid = 2463, + type = "deequip", + slot = "armor" + }, -- plate armor + { + itemid = 2462, + type = "equip", + slot = "head" + }, -- devil helmet + { + itemid = 2462, + type = "deequip", + slot = "head" + }, -- devil helmet + { + itemid = 2461, + type = "equip", + slot = "head" + }, -- leather helmet + { + itemid = 2461, + type = "deequip", + slot = "head" + }, -- leather helmet + { + itemid = 2460, + type = "equip", + slot = "head" + }, -- brass helmet + { + itemid = 2460, + type = "deequip", + slot = "head" + }, -- brass helmet + { + itemid = 2459, + type = "equip", + slot = "head" + }, -- iron helmet + { + itemid = 2459, + type = "deequip", + slot = "head" + }, -- iron helmet + { + itemid = 2458, + type = "equip", + slot = "head" + }, -- chain helmet + { + itemid = 2458, + type = "deequip", + slot = "head" + }, -- chain helmet + { + itemid = 2457, + type = "equip", + slot = "head" + }, -- steel helmet + { + itemid = 2457, + type = "deequip", + slot = "head" + }, -- steel helmet + { + itemid = 2456, + type = "equip", + slot = "hand" + }, -- bow + { + itemid = 2456, + type = "deequip", + slot = "hand" + }, -- bow + { + itemid = 2455, + type = "equip", + slot = "hand" + }, -- crossbow + { + itemid = 2455, + type = "deequip", + slot = "hand" + }, -- crossbow + { + itemid = 2454, + type = "equip", + slot = "hand" + }, -- war axe + { + itemid = 2454, + type = "deequip", + slot = "hand" + }, -- war axe + { + itemid = 2453, + type = "equip", + slot = "hand" + }, -- arcane staff + { + itemid = 2453, + type = "deequip", + slot = "hand" + }, -- arcane staff + { + itemid = 2452, + type = "equip", + slot = "hand" + }, -- heavy mace + { + itemid = 2452, + type = "deequip", + slot = "hand" + }, -- heavy mace + { + itemid = 2451, + type = "equip", + slot = "hand" + }, -- djinn blade + { + itemid = 2451, + type = "deequip", + slot = "hand" + }, -- djinn blade + { + itemid = 2450, + type = "equip", + slot = "hand" + }, -- bone sword + { + itemid = 2450, + type = "deequip", + slot = "hand" + }, -- bone sword + { + itemid = 2449, + type = "equip", + slot = "hand" + }, -- bone club + { + itemid = 2449, + type = "deequip", + slot = "hand" + }, -- bone club + { + itemid = 2448, + type = "equip", + slot = "hand" + }, -- studded club + { + itemid = 2448, + type = "deequip", + slot = "hand" + }, -- studded club + { + itemid = 2447, + type = "equip", + slot = "hand" + }, -- twin axe + { + itemid = 2447, + type = "deequip", + slot = "hand" + }, -- twin axe + { + itemid = 2446, + type = "equip", + slot = "hand" + }, -- pharaoh sword + { + itemid = 2446, + type = "deequip", + slot = "hand" + }, -- pharaoh sword + { + itemid = 2445, + type = "equip", + slot = "hand" + }, -- crystal mace + { + itemid = 2445, + type = "deequip", + slot = "hand" + }, -- crystal mace + { + itemid = 2444, + type = "equip", + slot = "hand" + }, -- hammer of wrath + { + itemid = 2444, + type = "deequip", + slot = "hand" + }, -- hammer of wrath + { + itemid = 2443, + type = "equip", + slot = "hand" + }, -- ravager's axe + { + itemid = 2443, + type = "deequip", + slot = "hand" + }, -- ravager's axe + { + itemid = 2442, + type = "equip", + slot = "hand" + }, -- heavy machete + { + itemid = 2442, + type = "deequip", + slot = "hand" + }, -- heavy machete + { + itemid = 2441, + type = "equip", + slot = "hand" + }, -- daramian axe + { + itemid = 2441, + type = "deequip", + slot = "hand" + }, -- daramian axe + { + itemid = 2440, + type = "equip", + slot = "hand" + }, -- daramian waraxe + { + itemid = 2440, + type = "deequip", + slot = "hand" + }, -- daramian waraxe + { + itemid = 2439, + type = "equip", + slot = "hand" + }, -- daramian mace + { + itemid = 2439, + type = "deequip", + slot = "hand" + }, -- daramian mace + { + itemid = 2438, + type = "equip", + slot = "hand" + }, -- epee + { + itemid = 2438, + type = "deequip", + slot = "hand" + }, -- epee + { + itemid = 2437, + type = "equip", + slot = "hand" + }, -- light mace + { + itemid = 2437, + type = "deequip", + slot = "hand" + }, -- light mace + { + itemid = 2436, + type = "equip", + slot = "hand" + }, -- skull staff + { + itemid = 2436, + type = "deequip", + slot = "hand" + }, -- skull staff + { + itemid = 2435, + type = "equip", + slot = "hand" + }, -- dwarven axe + { + itemid = 2435, + type = "deequip", + slot = "hand" + }, -- dwarven axe + { + itemid = 2434, + type = "equip", + slot = "hand" + }, -- dragon hammer + { + itemid = 2434, + type = "deequip", + slot = "hand" + }, -- dragon hammer + { + itemid = 2433, + type = "equip", + slot = "hand" + }, -- enchanted staff + { + itemid = 2433, + type = "deequip", + slot = "hand" + }, -- enchanted staff + { + itemid = 2432, + type = "equip", + slot = "hand" + }, -- fire axe + { + itemid = 2432, + type = "deequip", + slot = "hand" + }, -- fire axe + { + itemid = 2431, + type = "equip", + slot = "hand" + }, -- stonecutter axe + { + itemid = 2431, + type = "deequip", + slot = "hand" + }, -- stonecutter axe + { + itemid = 2430, + type = "equip", + slot = "hand" + }, -- knight axe + { + itemid = 2430, + type = "deequip", + slot = "hand" + }, -- knight axe + { + itemid = 2429, + type = "equip", + slot = "hand" + }, -- barbarian axe + { + itemid = 2429, + type = "deequip", + slot = "hand" + }, -- barbarian axe + { + itemid = 2428, + type = "equip", + slot = "hand" + }, -- orcish axe + { + itemid = 2428, + type = "deequip", + slot = "hand" + }, -- orcish axe + { + itemid = 2427, + type = "equip", + slot = "hand" + }, -- guardian halberd + { + itemid = 2427, + type = "deequip", + slot = "hand" + }, -- guardian halberd + { + itemid = 2426, + type = "equip", + slot = "hand" + }, -- naginata + { + itemid = 2426, + type = "deequip", + slot = "hand" + }, -- naginata + { + itemid = 2425, + type = "equip", + slot = "hand" + }, -- obsidian lance + { + itemid = 2425, + type = "deequip", + slot = "hand" + }, -- obsidian lance + { + itemid = 2424, + type = "equip", + slot = "hand" + }, -- silver mace + { + itemid = 2424, + type = "deequip", + slot = "hand" + }, -- silver mace + { + itemid = 2423, + type = "equip", + slot = "hand" + }, -- clerical mace + { + itemid = 2423, + type = "deequip", + slot = "hand" + }, -- clerical mace + { + itemid = 2422, + type = "equip", + slot = "hand" + }, -- iron hammer + { + itemid = 2422, + type = "deequip", + slot = "hand" + }, -- iron hammer + { + itemid = 2421, + type = "equip", + slot = "hand" + }, -- thunder hammer + { + itemid = 2421, + type = "deequip", + slot = "hand" + }, -- thunder hammer + { + itemid = 2420, + type = "equip", + slot = "hand" + }, -- machete + { + itemid = 2420, + type = "deequip", + slot = "hand" + }, -- machete + { + itemid = 2419, + type = "equip", + slot = "hand" + }, -- scimitar + { + itemid = 2419, + type = "deequip", + slot = "hand" + }, -- scimitar + { + itemid = 2418, + type = "equip", + slot = "hand" + }, -- golden sickle + { + itemid = 2418, + type = "deequip", + slot = "hand" + }, -- golden sickle + { + itemid = 2417, + type = "equip", + slot = "hand" + }, -- battle hammer + { + itemid = 2417, + type = "deequip", + slot = "hand" + }, -- battle hammer + { + itemid = 2416, + type = "equip", + slot = "hand" + }, -- crowbar + { + itemid = 2416, + type = "deequip", + slot = "hand" + }, -- crowbar + { + itemid = 2415, + type = "equip", + slot = "hand" + }, -- great axe + { + itemid = 2415, + type = "deequip", + slot = "hand" + }, -- great axe + { + itemid = 2414, + type = "equip", + slot = "hand" + }, -- dragon lance + { + itemid = 2414, + type = "deequip", + slot = "hand" + }, -- dragon lance + { + itemid = 2413, + type = "equip", + slot = "hand" + }, -- broadsword + { + itemid = 2413, + type = "deequip", + slot = "hand" + }, -- broadsword + { + itemid = 2412, + type = "equip", + slot = "hand" + }, -- katana + { + itemid = 2412, + type = "deequip", + slot = "hand" + }, -- katana + { + itemid = 2411, + type = "equip", + slot = "hand" + }, -- poison dagger + { + itemid = 2411, + type = "deequip", + slot = "hand" + }, -- poison dagger + { + itemid = 2410, + type = "equip", + slot = "hand" + }, -- throwing knife + { + itemid = 2410, + type = "deequip", + slot = "hand" + }, -- throwing knife + { + itemid = 2409, + type = "equip", + slot = "hand" + }, -- serpent sword + { + itemid = 2409, + type = "deequip", + slot = "hand" + }, -- serpent sword + { + itemid = 2408, + type = "equip", + slot = "hand" + }, -- warlord sword + { + itemid = 2408, + type = "deequip", + slot = "hand" + }, -- warlord sword + { + itemid = 2407, + type = "equip", + slot = "hand" + }, -- bright sword + { + itemid = 2407, + type = "deequip", + slot = "hand" + }, -- bright sword + { + itemid = 2406, + type = "equip", + slot = "hand" + }, -- short sword + { + itemid = 2406, + type = "deequip", + slot = "hand" + }, -- short sword + { + itemid = 2405, + type = "equip", + slot = "hand" + }, -- sickle + { + itemid = 2405, + type = "deequip", + slot = "hand" + }, -- sickle + { + itemid = 2404, + type = "equip", + slot = "hand" + }, -- combat knife + { + itemid = 2404, + type = "deequip", + slot = "hand" + }, -- combat knife + { + itemid = 2403, + type = "equip", + slot = "hand" + }, -- knife + { + itemid = 2403, + type = "deequip", + slot = "hand" + }, -- knife + { + itemid = 2402, + type = "equip", + slot = "hand" + }, -- silver dagger + { + itemid = 2402, + type = "deequip", + slot = "hand" + }, -- silver dagger + { + itemid = 2401, + type = "equip", + slot = "hand" + }, -- staff + { + itemid = 2401, + type = "deequip", + slot = "hand" + }, -- staff + { + itemid = 2400, + type = "equip", + slot = "hand" + }, -- magic sword + { + itemid = 2400, + type = "deequip", + slot = "hand" + }, -- magic sword + { + itemid = 2399, + type = "equip", + slot = "hand" + }, -- throwing star + { + itemid = 2399, + type = "deequip", + slot = "hand" + }, -- throwing star + { + itemid = 2398, + type = "equip", + slot = "hand" + }, -- mace + { + itemid = 2398, + type = "deequip", + slot = "hand" + }, -- mace + { + itemid = 2397, + type = "equip", + slot = "hand" + }, -- longsword + { + itemid = 2397, + type = "deequip", + slot = "hand" + }, -- longsword + { + itemid = 2396, + type = "equip", + slot = "hand" + }, -- ice rapier + { + itemid = 2396, + type = "deequip", + slot = "hand" + }, -- ice rapier + { + itemid = 2395, + type = "equip", + slot = "hand" + }, -- carlin sword + { + itemid = 2395, + type = "deequip", + slot = "hand" + }, -- carlin sword + { + itemid = 2394, + type = "equip", + slot = "hand" + }, -- morning star + { + itemid = 2394, + type = "deequip", + slot = "hand" + }, -- morning star + { + itemid = 2393, + type = "equip", + slot = "hand" + }, -- giant sword + { + itemid = 2393, + type = "deequip", + slot = "hand" + }, -- giant sword + { + itemid = 2392, + type = "equip", + slot = "hand" + }, -- fire sword + { + itemid = 2392, + type = "deequip", + slot = "hand" + }, -- fire sword + { + itemid = 2391, + type = "equip", + slot = "hand" + }, -- war hammer + { + itemid = 2391, + type = "deequip", + slot = "hand" + }, -- war hammer + { + itemid = 2390, + type = "equip", + slot = "hand" + }, -- magic longsword + { + itemid = 2390, + type = "deequip", + slot = "hand" + }, -- magic longsword + { + itemid = 2389, + type = "equip", + slot = "hand" + }, -- spear + { + itemid = 2389, + type = "deequip", + slot = "hand" + }, -- spear + { + itemid = 2388, + type = "equip", + slot = "hand" + }, -- hatchet + { + itemid = 2388, + type = "deequip", + slot = "hand" + }, -- hatchet + { + itemid = 2387, + type = "equip", + slot = "hand" + }, -- double axe + { + itemid = 2387, + type = "deequip", + slot = "hand" + }, -- double axe + { + itemid = 2386, + type = "equip", + slot = "hand" + }, -- axe + { + itemid = 2386, + type = "deequip", + slot = "hand" + }, -- axe + { + itemid = 2385, + type = "equip", + slot = "hand" + }, -- sabre + { + itemid = 2385, + type = "deequip", + slot = "hand" + }, -- sabre + { + itemid = 2384, + type = "equip", + slot = "hand" + }, -- rapier + { + itemid = 2384, + type = "deequip", + slot = "hand" + }, -- rapier + { + itemid = 2383, + type = "equip", + slot = "hand" + }, -- spike sword + { + itemid = 2383, + type = "deequip", + slot = "hand" + }, -- spike sword + { + itemid = 2382, + type = "equip", + slot = "hand" + }, -- club + { + itemid = 2382, + type = "deequip", + slot = "hand" + }, -- club + { + itemid = 2381, + type = "equip", + slot = "hand" + }, -- halberd + { + itemid = 2381, + type = "deequip", + slot = "hand" + }, -- halberd + { + itemid = 2380, + type = "equip", + slot = "hand" + }, -- hand axe + { + itemid = 2380, + type = "deequip", + slot = "hand" + }, -- hand axe + { + itemid = 2379, + type = "equip", + slot = "hand" + }, -- dagger + { + itemid = 2379, + type = "deequip", + slot = "hand" + }, -- dagger + { + itemid = 2378, + type = "equip", + slot = "hand" + }, -- battle axe + { + itemid = 2378, + type = "deequip", + slot = "hand" + }, -- battle axe + { + itemid = 2377, + type = "equip", + slot = "hand" + }, -- two handed sword + { + itemid = 2377, + type = "deequip", + slot = "hand" + }, -- two handed sword + { + itemid = 2376, + type = "equip", + slot = "hand" + }, -- sword + { + itemid = 2376, + type = "deequip", + slot = "hand" + }, -- sword + { + itemid = 2365, + type = "equip", + slot = "backpack" + }, -- backpack of holding + { + itemid = 2365, + type = "deequip", + slot = "backpack" + }, -- backpack of holding + { + itemid = 2358, + type = "equip", + slot = "feet" + }, -- boots of waterwalking + { + itemid = 2358, + type = "deequip", + slot = "feet" + }, -- boots of waterwalking + { + itemid = 2357, + type = "equip", + slot = "ring" + }, -- ring of wishes + { + itemid = 2357, + type = "deequip", + slot = "ring" + }, -- ring of wishes + { + itemid = 2343, + type = "equip", + slot = "head" + }, -- helmet of the ancients + { + itemid = 2343, + type = "deequip", + slot = "head" + }, -- helmet of the ancients + { + itemid = 2342, + type = "equip", + slot = "head" + }, -- helmet of the ancients + { + itemid = 2342, + type = "deequip", + slot = "head" + }, -- helmet of the ancients + { + itemid = 2339, + type = "equip", + slot = "head" + }, -- damaged helmet + { + itemid = 2339, + type = "deequip", + slot = "head" + }, -- damaged helmet + { + itemid = 2323, + type = "equip", + slot = "head", + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- hat of the mad + { + itemid = 2323, + type = "deequip", + slot = "head" + }, -- hat of the mad + { + itemid = 2321, + type = "equip", + slot = "hand" + }, -- giant smithhammer + { + itemid = 2321, + type = "deequip", + slot = "hand" + }, -- giant smithhammer + { + itemid = 2218, + type = "equip", + slot = "necklace" + }, -- paw amulet + { + itemid = 2218, + type = "deequip", + slot = "necklace" + }, -- paw amulet + { + itemid = 2216, + type = "equip", + slot = "ring" + }, -- ring of healing + { + itemid = 2216, + type = "deequip", + slot = "ring" + }, -- ring of healing + { + itemid = 2215, + type = "equip", + slot = "ring" + }, -- dwarven ring + { + itemid = 2215, + type = "deequip", + slot = "ring" + }, -- dwarven ring + { + itemid = 2214, + type = "equip", + slot = "ring" + }, -- ring of healing + { + itemid = 2214, + type = "deequip", + slot = "ring" + }, -- ring of healing + { + itemid = 2213, + type = "equip", + slot = "ring" + }, -- dwarven ring + { + itemid = 2213, + type = "deequip", + slot = "ring" + }, -- dwarven ring + { + itemid = 2212, + type = "equip", + slot = "ring" + }, -- club ring + { + itemid = 2212, + type = "deequip", + slot = "ring" + }, -- club ring + { + itemid = 2211, + type = "equip", + slot = "ring" + }, -- axe ring + { + itemid = 2211, + type = "deequip", + slot = "ring" + }, -- axe ring + { + itemid = 2210, + type = "equip", + slot = "ring" + }, -- sword ring + { + itemid = 2210, + type = "deequip", + slot = "ring" + }, -- sword ring + { + itemid = 2209, + type = "equip", + slot = "ring" + }, -- club ring + { + itemid = 2209, + type = "deequip", + slot = "ring" + }, -- club ring + { + itemid = 2208, + type = "equip", + slot = "ring" + }, -- axe ring + { + itemid = 2208, + type = "deequip", + slot = "ring" + }, -- axe ring + { + itemid = 2207, + type = "equip", + slot = "ring" + }, -- sword ring + { + itemid = 2207, + type = "deequip", + slot = "ring" + }, -- sword ring + { + itemid = 2206, + type = "equip", + slot = "ring" + }, -- time ring + { + itemid = 2206, + type = "deequip", + slot = "ring" + }, -- time ring + { + itemid = 2205, + type = "equip", + slot = "ring" + }, -- life ring + { + itemid = 2205, + type = "deequip", + slot = "ring" + }, -- life ring + { + itemid = 2204, + type = "equip", + slot = "ring", + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- energy ring + { + itemid = 2204, + type = "deequip", + slot = "ring" + }, -- energy ring + { + itemid = 2203, + type = "equip", + slot = "ring" + }, -- power ring + { + itemid = 2203, + type = "deequip", + slot = "ring" + }, -- power ring + { + itemid = 2202, + type = "equip", + slot = "ring" + }, -- stealth ring + { + itemid = 2202, + type = "deequip", + slot = "ring" + }, -- stealth ring + { + itemid = 2201, + type = "equip", + slot = "necklace" + }, -- dragon necklace + { + itemid = 2201, + type = "deequip", + slot = "necklace" + }, -- dragon necklace + { + itemid = 2200, + type = "equip", + slot = "necklace" + }, -- protection amulet + { + itemid = 2200, + type = "deequip", + slot = "necklace" + }, -- protection amulet + { + itemid = 2199, + type = "equip", + slot = "necklace" + }, -- garlic necklace + { + itemid = 2199, + type = "deequip", + slot = "necklace" + }, -- garlic necklace + { + itemid = 2198, + type = "equip", + slot = "necklace" + }, -- elven amulet + { + itemid = 2198, + type = "deequip", + slot = "necklace" + }, -- elven amulet + { + itemid = 2197, + type = "equip", + slot = "necklace" + }, -- stone skin amulet + { + itemid = 2197, + type = "deequip", + slot = "necklace" + }, -- stone skin amulet + { + itemid = 2196, + type = "equip", + slot = "necklace" + }, -- amulet of life + { + itemid = 2196, + type = "deequip", + slot = "necklace" + }, -- amulet of life + { + itemid = 2195, + type = "equip", + slot = "feet" + }, -- boots of haste + { + itemid = 2195, + type = "deequip", + slot = "feet" + }, -- boots of haste + { + itemid = 2191, + type = "equip", + slot = "hand", + level = 13, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of dragonbreath + { + itemid = 2191, + type = "deequip", + slot = "hand", + level = 13 + }, -- wand of dragonbreath + { + itemid = 2190, + type = "equip", + slot = "hand", + level = 6, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of vortex + { + itemid = 2190, + type = "deequip", + slot = "hand", + level = 6 + }, -- wand of vortex + { + itemid = 2189, + type = "equip", + slot = "hand", + level = 26, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of cosmic energy + { + itemid = 2189, + type = "deequip", + slot = "hand", + level = 26 + }, -- wand of cosmic energy + { + itemid = 2188, + type = "equip", + slot = "hand", + level = 19, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of decay + { + itemid = 2188, + type = "deequip", + slot = "hand", + level = 19 + }, -- wand of decay + { + itemid = 2187, + type = "equip", + slot = "hand", + level = 33, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of inferno + { + itemid = 2187, + type = "deequip", + slot = "hand", + level = 33 + }, -- wand of inferno + { + itemid = 2186, + type = "equip", + slot = "hand", + level = 13, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- moonlight rod + { + itemid = 2186, + type = "deequip", + slot = "hand", + level = 13 + }, -- moonlight rod + { + itemid = 2185, + type = "equip", + slot = "hand", + level = 19, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- necrotic rod + { + itemid = 2185, + type = "deequip", + slot = "hand", + level = 19 + }, -- necrotic rod + { + itemid = 2183, + type = "equip", + slot = "hand", + level = 33, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- hailstorm rod + { + itemid = 2183, + type = "deequip", + slot = "hand", + level = 33 + }, -- hailstorm rod + { + itemid = 2182, + type = "equip", + slot = "hand", + level = 6, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- snakebit rod + { + itemid = 2182, + type = "deequip", + slot = "hand", + level = 6 + }, -- snakebit rod + { + itemid = 2181, + type = "equip", + slot = "hand", + level = 26, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- terra rod + { + itemid = 2181, + type = "deequip", + slot = "hand", + level = 26 + }, -- terra rod + { + itemid = 2179, + type = "equip", + slot = "ring" + }, -- gold ring + { + itemid = 2179, + type = "deequip", + slot = "ring" + }, -- gold ring + { + itemid = 2175, + type = "equip", + slot = "shield", + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- spellbook + { + itemid = 2175, + type = "deequip", + slot = "shield" + }, -- spellbook + { + itemid = 2173, + type = "equip", + slot = "necklace" + }, -- amulet of loss + { + itemid = 2173, + type = "deequip", + slot = "necklace" + }, -- amulet of loss + { + itemid = 2172, + type = "equip", + slot = "necklace" + }, -- bronze amulet + { + itemid = 2172, + type = "deequip", + slot = "necklace" + }, -- bronze amulet + { + itemid = 2171, + type = "equip", + slot = "necklace" + }, -- platinum amulet + { + itemid = 2171, + type = "deequip", + slot = "necklace" + }, -- platinum amulet + { + itemid = 2170, + type = "equip", + slot = "necklace" + }, -- silver amulet + { + itemid = 2170, + type = "deequip", + slot = "necklace" + }, -- silver amulet + { + itemid = 2169, + type = "equip", + slot = "ring" + }, -- time ring + { + itemid = 2169, + type = "deequip", + slot = "ring" + }, -- time ring + { + itemid = 2168, + type = "equip", + slot = "ring" + }, -- life ring + { + itemid = 2168, + type = "deequip", + slot = "ring" + }, -- life ring + { + itemid = 2167, + type = "equip", + slot = "ring", + vocation = { + {"Knight", true}, + {"Paladin", true, true}, + {"Elite Knight"}, + {"Royal Paladin"} + } + }, -- energy ring + { + itemid = 2167, + type = "deequip", + slot = "ring" + }, -- energy ring + { + itemid = 2166, + type = "equip", + slot = "ring" + }, -- power ring + { + itemid = 2166, + type = "deequip", + slot = "ring" + }, -- power ring + { + itemid = 2165, + type = "equip", + slot = "ring" + }, -- stealth ring + { + itemid = 2165, + type = "deequip", + slot = "ring" + }, -- stealth ring + { + itemid = 2164, + type = "equip", + slot = "ring" + }, -- might ring + { + itemid = 2164, + type = "deequip", + slot = "ring" + }, -- might ring + { + itemid = 2161, + type = "equip", + slot = "necklace" + }, -- strange talisman + { + itemid = 2161, + type = "deequip", + slot = "necklace" + }, -- strange talisman + { + itemid = 2142, + type = "equip", + slot = "necklace" + }, -- ancient amulet + { + itemid = 2142, + type = "deequip", + slot = "necklace" + }, -- ancient amulet + { + itemid = 2139, + type = "equip", + slot = "head" + }, -- ancient tiara + { + itemid = 2139, + type = "deequip", + slot = "head" + }, -- ancient tiara + { + itemid = 2138, + type = "equip", + slot = "necklace" + }, -- sapphire amulet + { + itemid = 2138, + type = "deequip", + slot = "necklace" + }, -- sapphire amulet + { + itemid = 2136, + type = "equip", + slot = "necklace" + }, -- demonbone amulet + { + itemid = 2136, + type = "deequip", + slot = "necklace" + }, -- demonbone amulet + { + itemid = 2135, + type = "equip", + slot = "necklace" + }, -- scarab amulet + { + itemid = 2135, + type = "deequip", + slot = "necklace" + }, -- scarab amulet + { + itemid = 2133, + type = "equip", + slot = "necklace" + }, -- ruby necklace + { + itemid = 2133, + type = "deequip", + slot = "necklace" + }, -- ruby necklace + { + itemid = 2132, + type = "equip", + slot = "necklace" + }, -- silver necklace + { + itemid = 2132, + type = "deequip", + slot = "necklace" + }, -- silver necklace + { + itemid = 2131, + type = "equip", + slot = "necklace" + }, -- star amulet + { + itemid = 2131, + type = "deequip", + slot = "necklace" + }, -- star amulet + { + itemid = 2130, + type = "equip", + slot = "necklace" + }, -- golden amulet + { + itemid = 2130, + type = "deequip", + slot = "necklace" + }, -- golden amulet + { + itemid = 2129, + type = "equip", + slot = "necklace" + }, -- wolf tooth chain + { + itemid = 2129, + type = "deequip", + slot = "necklace" + }, -- wolf tooth chain + { + itemid = 2128, + type = "equip", + slot = "head" + }, -- crown + { + itemid = 2128, + type = "deequip", + slot = "head" + }, -- crown + { + itemid = 2126, + type = "equip", + slot = "necklace" + }, -- bronze necklace + { + itemid = 2126, + type = "deequip", + slot = "necklace" + }, -- bronze necklace + { + itemid = 2125, + type = "equip", + slot = "necklace" + }, -- crystal necklace + { + itemid = 2125, + type = "deequip", + slot = "necklace" + }, -- crystal necklace + { + itemid = 2124, + type = "equip", + slot = "ring" + }, -- crystal ring + { + itemid = 2124, + type = "deequip", + slot = "ring" + }, -- crystal ring + { + itemid = 2123, + type = "equip", + slot = "ring" + }, -- ring of the sky + { + itemid = 2123, + type = "deequip", + slot = "ring" + }, -- ring of the sky + { + itemid = 2121, + type = "equip", + slot = "ring" + }, -- wedding ring + { + itemid = 2121, + type = "deequip", + slot = "ring" + }, -- wedding ring + { + itemid = 2111, + type = "equip", + slot = "hand" + }, -- snowball + { + itemid = 2111, + type = "deequip", + slot = "hand" + }, -- snowball + { + itemid = 2004, + type = "equip", + slot = "backpack" + }, -- golden backpack + { + itemid = 2004, + type = "deequip", + slot = "backpack" + }, -- golden backpack + { + itemid = 2003, + type = "equip", + slot = "backpack" + }, -- grey backpack + { + itemid = 2003, + type = "deequip", + slot = "backpack" + }, -- grey backpack + { + itemid = 2002, + type = "equip", + slot = "backpack" + }, -- blue backpack + { + itemid = 2002, + type = "deequip", + slot = "backpack" + }, -- blue backpack + { + itemid = 2001, + type = "equip", + slot = "backpack" + }, -- purple backpack + { + itemid = 2001, + type = "deequip", + slot = "backpack" + }, -- purple backpack + { + itemid = 2000, + type = "equip", + slot = "backpack" + }, -- red backpack + { + itemid = 2000, + type = "deequip", + slot = "backpack" + }, -- red backpack + { + itemid = 1999, + type = "equip", + slot = "backpack" + }, -- yellow backpack + { + itemid = 1999, + type = "deequip", + slot = "backpack" + }, -- yellow backpack + { + itemid = 1998, + type = "equip", + slot = "backpack" + }, -- green backpack + { + itemid = 1998, + type = "deequip", + slot = "backpack" + }, -- green backpack + { + itemid = 1997, + type = "equip", + slot = "backpack" + }, -- golden bag + { + itemid = 1997, + type = "deequip", + slot = "backpack" + }, -- golden bag + { + itemid = 1996, + type = "equip", + slot = "backpack" + }, -- grey bag + { + itemid = 1996, + type = "deequip", + slot = "backpack" + }, -- grey bag + { + itemid = 1995, + type = "equip", + slot = "backpack" + }, -- blue bag + { + itemid = 1995, + type = "deequip", + slot = "backpack" + }, -- blue bag + { + itemid = 1994, + type = "equip", + slot = "backpack" + }, -- purple bag + { + itemid = 1994, + type = "deequip", + slot = "backpack" + }, -- purple bag + { + itemid = 1993, + type = "equip", + slot = "backpack" + }, -- red bag + { + itemid = 1993, + type = "deequip", + slot = "backpack" + }, -- red bag + { + itemid = 1992, + type = "equip", + slot = "backpack" + }, -- yellow bag + { + itemid = 1992, + type = "deequip", + slot = "backpack" + }, -- yellow bag + { + itemid = 1991, + type = "equip", + slot = "backpack" + }, -- green bag + { + itemid = 1991, + type = "deequip", + slot = "backpack" + }, -- green bag + { + itemid = 1988, + type = "equip", + slot = "backpack" + }, -- backpack + { + itemid = 1988, + type = "deequip", + slot = "backpack" + }, -- backpack + { + itemid = 1987, + type = "equip", + slot = "backpack" + }, -- bag + { + itemid = 1987, + type = "deequip", + slot = "backpack" + }, -- bag + { + itemid = 1507, + type = "stepin" + }, -- searing fire + { + itemid = 1507, + type = "additem" + }, -- searing fire + { + itemid = 1506, + type = "stepin" + }, -- searing fire + { + itemid = 1506, + type = "additem" + }, -- searing fire + { + itemid = 1505, + type = "stepin" + }, -- smoke + { + itemid = 1505, + type = "additem" + }, -- smoke + { + itemid = 1504, + type = "stepin" + }, -- energy field + { + itemid = 1504, + type = "additem" + }, -- energy field + { + itemid = 1503, + type = "stepin" + }, -- poison gas + { + itemid = 1503, + type = "additem" + }, -- poison gas + { + itemid = 1502, + type = "stepin" + }, -- fire field + { + itemid = 1502, + type = "additem" + }, -- fire field + { + itemid = 1501, + type = "stepin" + }, -- fire field + { + itemid = 1501, + type = "additem" + }, -- fire field + { + itemid = 1500, + type = "stepin" + }, -- fire field + { + itemid = 1500, + type = "additem" + }, -- fire field + { + itemid = 1499, + type = "stepin" + }, -- rush wood + { + itemid = 1499, + type = "additem" + }, -- rush wood + { + itemid = 1498, + type = "stepin" + }, -- magic wall + { + itemid = 1498, + type = "additem" + }, -- magic wall + { + itemid = 1497, + type = "stepin" + }, -- magic wall + { + itemid = 1497, + type = "additem" + }, -- magic wall + { + itemid = 1496, + type = "stepin" + }, -- poison field + { + itemid = 1496, + type = "additem" + }, -- poison field + { + itemid = 1495, + type = "stepin" + }, -- energy field + { + itemid = 1495, + type = "additem" + }, -- energy field + { + itemid = 1494, + type = "stepin" + }, -- fire field + { + itemid = 1494, + type = "additem" + }, -- fire field + { + itemid = 1493, + type = "stepin" + }, -- fire field + { + itemid = 1493, + type = "additem" + }, -- fire field + { + itemid = 1492, + type = "stepin" + }, -- fire field + { + itemid = 1492, + type = "additem" + }, -- fire field + { + itemid = 1491, + type = "stepin" + }, -- energy field + { + itemid = 1491, + type = "additem" + }, -- energy field + { + itemid = 1490, + type = "stepin" + }, -- poison field + { + itemid = 1490, + type = "additem" + }, -- poison field + { + itemid = 1489, + type = "stepin" + }, -- fire field + { + itemid = 1489, + type = "additem" + }, -- fire field + { + itemid = 1488, + type = "stepin" + }, -- fire field + { + itemid = 1488, + type = "additem" + }, -- fire field + { + itemid = 1487, + type = "stepin" + }, -- fire field + { + itemid = 1487, + type = "additem" + }, -- fire field + { + itemid = 1425, + type = "stepin" + }, -- campfire + { + itemid = 1425, + type = "additem" + }, -- campfire + { + itemid = 1424, + type = "stepin" + }, -- campfire + { + itemid = 1424, + type = "additem" + }, -- campfire + { + itemid = 1423, + type = "stepin" + }, -- campfire + { + itemid = 1423, + type = "additem" + }, -- campfire + { + itemid = 1294, + type = "equip", + slot = "hand" + }, -- small stone + { + itemid = 1294, + type = "deequip", + slot = "hand" + }, -- small stone + + } +end + +for index, equipments in ipairs(equipmentsTable) do + local movement = MoveEvent() + movement:id(equipments.itemid) + + if(equipments.type) then + movement:type(equipments.type) + end + if(equipments.slot) then + movement:slot(equipments.slot) + end + if(equipments.level) then + movement:level(equipments.level) + end + if(equipments.vocation) then + for vocationIndex, vocation in ipairs(equipments.vocation) do + movement:vocation(vocation[1], vocation[2] or false, vocation[3] or false) + end + end + movement:register() +end diff --git a/data/scripts/movements/oramond/oramond_entrance.lua b/data/scripts/movements/oramond/oramond_entrance.lua new file mode 100644 index 00000000000..7de1980d19e --- /dev/null +++ b/data/scripts/movements/oramond/oramond_entrance.lua @@ -0,0 +1,26 @@ +local portals = { + [50500] = {position = Position(33539, 32014, 6), message = 'Slrrp!'}, --entrance + [50501] = {position = Position(33491, 31985, 7), message = 'Slrrp!'}, --exit +} + +local oramondEntrance = MoveEvent() + +function oramondEntrance.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local portal = portals[item.uid] + if portal then + player:teleportTo(portal.position) + item:getPosition():sendMagicEffect(CONST_ME_GREEN_RINGS) + player:say(portal.message, TALKTYPE_MONSTER_SAY) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +oramondEntrance:type("stepin") +oramondEntrance:uid(50500, 50501) +oramondEntrance:register() diff --git a/data/scripts/movements/oramond/oramond_movements.lua b/data/scripts/movements/oramond/oramond_movements.lua new file mode 100644 index 00000000000..b24e0a51829 --- /dev/null +++ b/data/scripts/movements/oramond/oramond_movements.lua @@ -0,0 +1,76 @@ +local positions = { + [13400] = Position(33634, 31891, 6), + [13401] = Position(33488, 31987, 7), + [13402] = Position(33632, 31661, 12), + [13403] = Position(33682, 31939, 9), + [13404] = Position(33678, 32461, 7), + [13405] = Position(32942, 31594, 8), + [13406] = Position(33143, 31528, 2), + [13407] = Position(33626, 31897, 6), + [13408] = Position(33651, 31943, 7), + [13409] = Position(33662, 31936, 9), + [13410] = Position(33612, 31640, 14), + [13411] = Position(33787, 31736, 12), + [13412] = Position(33626, 31639, 15), + [13413] = Position(33623, 31627, 14), + [13415] = Position(33506, 31577, 8), -- krailos + [13416] = Position(33503, 31580, 7), -- krailos + [13417] = Position(33622, 31789, 13), -- oramond sea + [13418] = Position(32234, 32919, 9), -- liberty bay quaras + [13419] = Position(32235, 32921, 8), -- liberty bay quaras + [13420] = Position(32247, 32893, 9), -- liberty bay quaras + [13421] = Position(32244, 32892, 8), -- liberty bay quaras + [13422] = Position(32262, 32913, 9), -- liberty bay quaras + [13423] = Position(32264, 32911, 8), -- liberty bay quaras + [13424] = Position(32271, 32872, 9), -- liberty bay quaras + [13425] = Position(32272, 32872, 8), -- liberty bay quaras + [13426] = Position(31376, 32776, 7), -- treiners + [13427] = Position(31247, 32787, 7), -- treiners + [13428] = Position(33545, 31861, 7), + [13510] = Position(32520, 32022, 8), -- kazordoon + [13511] = Position(32444, 32388, 10), -- kazordoon + [13512] = Position(33159, 32636, 8), -- ankrahmun + [13513] = Position(32130, 31359, 12), -- ankrahmun + [13514] = Position(32103, 31329, 12), -- no respawn + [13515] = Position(32114, 31327, 12), -- no respawn + [13516] = Position(32111, 31372, 14), -- reward + [13517] = Position(32102, 31400, 13), -- out reward + [13518] = Position(32114, 31353, 13), -- init + [13519] = Position(32090, 31320, 13), + [13520] = Position(32272, 31382, 14), -- first boss for the second lever + [13521] = Position(32113, 31353, 13), -- exit boss + [13522] = Position(32337, 31289, 14), -- second boss for the thrird lever + [13523] = Position(32306, 31250, 14), -- third boss for the four lever + [13524] = Position(32203, 31284, 14), -- four boss for the last boss lever + [13525] = Position(32216, 31378, 14), -- world devourer exit for the reward + [13526] = Position(32162, 31295, 7), -- svarground exit + [13527] = Position(32112, 31390, 11), -- svarground entrance + [13528] = Position(33185, 31643, 8), -- from the quest for edron + [13529] = Position(32113, 31358, 13), -- from edron for the quest + [13531] = Position(32113, 31358, 13), -- from farmine for the quest +} + +local oramondMovements = MoveEvent() + +function oramondMovements.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return false + end + + local newPosition = positions[item.actionid] + if newPosition then + player:teleportTo(newPosition) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + player:say("Slrrp!", TALKTYPE_MONSTER_SAY) + end + return true +end + +oramondMovements:type("stepin") + +for index, value in pairs(positions) do + oramondMovements:aid(index) +end + +oramondMovements:register() diff --git a/data/scripts/movements/oramond/oramond_teleport.lua b/data/scripts/movements/oramond/oramond_teleport.lua new file mode 100644 index 00000000000..d5c3009e85a --- /dev/null +++ b/data/scripts/movements/oramond/oramond_teleport.lua @@ -0,0 +1,34 @@ +local config = { + [36489] = Position(33559, 31970, 12), --Glooth + [42626] = Position(33539, 32014, 6), --Oramond + [42627] = Position(33491, 31985, 7), --Oramond + [42630] = Position(33636, 31891, 6), --City + [42631] = Position(33486, 31982, 7), --City + [50389] = Position(33651, 31942, 7), --Glooth +} + +local oramondTeleport = MoveEvent() + +function oramondTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local teleport = config[item.actionid] + if teleport then + player:teleportTo(teleport) + fromPosition:sendMagicEffect(CONST_ME_GREEN_RINGS) + teleport:sendMagicEffect(CONST_ME_GREEN_RINGS) + player:say("Slrrp!", TALKTYPE_MONSTER_SAY) + end + return true +end + +oramondTeleport:type("stepin") + +for index, value in pairs(config) do + oramondTeleport:aid(index) +end + +oramondTeleport:register() diff --git a/data/scripts/movements/oramond/seacrest.lua b/data/scripts/movements/oramond/seacrest.lua new file mode 100644 index 00000000000..b8036363567 --- /dev/null +++ b/data/scripts/movements/oramond/seacrest.lua @@ -0,0 +1,22 @@ +local oramondSeacrest = MoveEvent() + +function oramondSeacrest.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local headItem = player:getSlotItem(CONST_SLOT_HEAD) + if headItem and isInArray({5461, 12541, 15408}, headItem.itemid) then + player:teleportTo(Position(33552, 31775, 13)) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You enter the seacrest ground.') + else + player:teleportTo(Position(33544, 31861, 7)) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You must wear an underwater exploration helmet in order to dive.') + end + return true +end + +oramondSeacrest:type("stepin") +oramondSeacrest:uid(1110) +oramondSeacrest:register() diff --git a/data/scripts/movements/oramond/teleport.lua b/data/scripts/movements/oramond/teleport.lua new file mode 100644 index 00000000000..ae4ff480c66 --- /dev/null +++ b/data/scripts/movements/oramond/teleport.lua @@ -0,0 +1,46 @@ +local setting = { + [50510] = {position = Position(33459, 31715, 9), message = 'Slrrp!', premium = false}, --entrance + [50511] = {position = Position(33668, 31887, 5), message = 'Slrrp!', premium = false}, --exit + + [50512] = {position = Position(31254, 32604, 9), message = 'Slrrp!', premium = false}, --minos entrance + [50513] = {position = Position(31061, 32605, 9), message = 'Slrrp!', premium = false}, --golens entrance + + [50514] = {position = Position(33668, 31887, 5), message = 'Slrrp!', premium = false}, --minos exit + [50515] = {position = Position(33668, 31887, 5), message = 'Slrrp!', premium = false}, --golens exit + + [50624] = {position = Position(33668, 31887, 5), message = 'Slrrp!', premium = false}, --minos exit + [50625] = {position = Position(33668, 31887, 5), message = 'Slrrp!', premium = false}, --golens exit +} + +local oramondTeleports = MoveEvent() + +function oramondTeleports.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local teleport = setting[item.uid] + if teleport then + if not player:isPremium() and teleport.premium then + player:teleportTo(fromPosition) + player:sendCancelMessage("You need a premium account to access this area.") + fromPosition:sendMagicEffect(CONST_ME_POFF) + return true + end + + player:teleportTo(teleport.position) + item:getPosition():sendMagicEffect(CONST_ME_GREEN_RINGS) + player:say(teleport.message, TALKTYPE_MONSTER_SAY) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +oramondTeleports:type("stepin") + +for index, value in pairs(setting) do + oramondTeleports:uid(index) +end + +oramondTeleports:register() diff --git a/data/scripts/movements/oramond/voting_oramond.lua b/data/scripts/movements/oramond/voting_oramond.lua new file mode 100644 index 00000000000..a5a00a7c4f2 --- /dev/null +++ b/data/scripts/movements/oramond/voting_oramond.lua @@ -0,0 +1,30 @@ +local setting = { + ["Monday"] = Position(31254, 32604, 9), --Minos + ["Tuesday"] = Position(33459, 31715, 9), --Catacombs + ["Wednesday"] = Position(31061, 32605, 9), --Golem + ["Thursday"] = Position(33459, 31715, 9), --Catacombs + ["Friday"] = Position(33459, 31715, 9), --Catacombs + ["Saturday"] = Position(31254, 32604, 9), --Minos + ["Sunday"] = Position(33459, 31715, 9) --Catacombs +} + +local votingOramond = MoveEvent() + +function votingOramond.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local teleport = setting[os.date("%A")] + if teleport then + player:teleportTo(teleport) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + player:say("Slrrp!", TALKTYPE_MONSTER_SAY) + end + return true +end + +votingOramond:type("stepin") +votingOramond:aid(42628) +votingOramond:register() diff --git a/data/scripts/movements/others/bath_tub.lua b/data/scripts/movements/others/bath_tub.lua new file mode 100644 index 00000000000..f20783807c1 --- /dev/null +++ b/data/scripts/movements/others/bath_tub.lua @@ -0,0 +1,34 @@ +local bathtubEnter = MoveEvent() +local playerBathTub = 29323 + +function bathtubEnter.onStepIn(creature, item, position, fromPosition) + if not creature:isPlayer() then + return false + end + + local condition = Condition(CONDITION_OUTFIT) + condition:setOutfit({lookTypeEx = playerBathTub}) + condition:setTicks(-1) + + position:sendMagicEffect(CONST_ME_WATERSPLASH) + item:transform(BATHTUB_FILLED_NOTMOVABLE) + creature:addCondition(condition) + return true +end + +bathtubEnter:id(BATHTUB_FILLED) +bathtubEnter:register() + +local bathtubExit = MoveEvent() +function bathtubExit.onStepOut(creature, item, position, fromPosition) + if not creature:isPlayer() then + return false + end + + item:transform(BATHTUB_FILLED) + creature:removeCondition(CONDITION_OUTFIT) + return true +end + +bathtubExit:id(BATHTUB_FILLED_NOTMOVABLE) +bathtubExit:register() diff --git a/data/scripts/movements/others/cake.lua b/data/scripts/movements/others/cake.lua new file mode 100644 index 00000000000..c53ebea31df --- /dev/null +++ b/data/scripts/movements/others/cake.lua @@ -0,0 +1,17 @@ +local cake = MoveEvent() + +function cake.onAddItem(moveitem, tileitem, position) + -- has to be a candle + if moveitem.itemid ~= 2048 then + return true + end + + moveitem:remove() + tileitem:transform(6280) + position:sendMagicEffect(CONST_ME_MAGIC_RED) + return true +end + +cake:type("additem") +cake:id(6279) +cake:register() diff --git a/data/scripts/movements/others/closing_door.lua b/data/scripts/movements/others/closing_door.lua new file mode 100644 index 00000000000..da3116346ab --- /dev/null +++ b/data/scripts/movements/others/closing_door.lua @@ -0,0 +1,120 @@ +-- Level and quests closing door (onStepIn). +-- This prevents a player who has not yet done the quest, from crossing the player who has already done so, skipping the entire quest and going straight to the final reward. +local closingDoor = MoveEvent() + +local doorIds = {} +for index, value in ipairs(QuestDoorTable) do + if not table.contains(doorIds, value.openDoor) then + table.insert(doorIds, value.openDoor) + end +end +for index, value in ipairs(LevelDoorTable) do + if not table.contains(doorIds, value.openDoor) then + table.insert(doorIds, value.openDoor) + end +end + +function closingDoor.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + + for index, value in ipairs(QuestDoorTable) do + if value.openDoor == item.itemid then + if player:getStorageValue(item.actionid) ~= -1 then + return true + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The door seems to be sealed against unwanted intruders.") + player:teleportTo(fromPosition, true) + return false + end + end + end + for index, value in ipairs(LevelDoorTable) do + if value.openDoor == item.itemid then + if item.actionid > 0 and player:getLevel() >= item.actionid - 1000 then + return true + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Only the worthy may pass.") + player:teleportTo(fromPosition, true) + return false + end + end + end + return true +end + +for index, value in ipairs(doorIds) do + closingDoor:id(value) +end + +closingDoor:register() + +-- Level and quests closing door (onStepOut). +-- This closes the door after the player passes through it. +local closingDoor = MoveEvent() + +local doorIds = {} +for index, value in ipairs(QuestDoorTable) do + if not table.contains(doorIds, value.openDoor) then + table.insert(doorIds, value.openDoor) + end +end +for index, value in ipairs(LevelDoorTable) do + if not table.contains(doorIds, value.openDoor) then + table.insert(doorIds, value.openDoor) + end +end + +function closingDoor.onStepOut(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + + local tile = Tile(position) + if tile:getCreatureCount() > 0 then + return true + end + + local newPosition = {x = position.x + 1, y = position.y, z = position.z} + local query = Tile(newPosition):queryAdd(creature) + if query ~= RETURNVALUE_NOERROR or query == RETURNVALUE_NOTENOUGHROOM then + newPosition.x = newPosition.x - 1 + newPosition.y = newPosition.y + 1 + query = Tile(newPosition):queryAdd(creature) + end + + if query == RETURNVALUE_NOERROR or query ~= RETURNVALUE_NOTENOUGHROOM then + doRelocate(position, newPosition) + end + + local i, tileItem, tileCount = 1, true, tile:getThingCount() + while tileItem and i < tileCount do + tileItem = tile:getThing(i) + if tileItem and tileItem:getUniqueId() ~= item.uid and tileItem:getType():isMovable() then + tileItem:remove() + else + i = i + 1 + end + end + + for index, value in ipairs(LevelDoorTable) do + if value.openDoor == item.itemid then + item:transform(value.closedDoor) + end + end + for index, value in ipairs(QuestDoorTable) do + if value.openDoor == item.itemid then + item:transform(value.closedDoor) + end + end + return true +end + +for index, value in ipairs(doorIds) do + closingDoor:id(value) +end + +closingDoor:register() diff --git a/data/scripts/movements/others/dawnport_tiles.lua b/data/scripts/movements/others/dawnport_tiles.lua new file mode 100644 index 00000000000..9da94c7e945 --- /dev/null +++ b/data/scripts/movements/others/dawnport_tiles.lua @@ -0,0 +1,260 @@ +local chestRooms = { + entrances = { + [25010] = {destination = {x = 32054, y = 31883, z = 6}}, + [25011] = {destination = {x = 32073, y = 31883, z = 6}}, + [25012] = {destination = {x = 32059, y = 31883, z = 6}}, + [25013] = {destination = {x = 32068, y = 31883, z = 6}} + }, + exits = { + [25014] = {vocation = VOCATION.ID.SORCERER, destination = {x = 32054, y = 31879, z = 6}}, + [25015] = {vocation = VOCATION.ID.DRUID, destination = {x = 32073, y = 31879, z = 6}}, + [25016] = {vocation = VOCATION.ID.PALADIN, destination = {x = 32059, y = 31879, z = 6}}, + [25017] = {vocation = VOCATION.ID.KNIGHT, destination = {x = 32068, y = 31879, z = 6}} + } +} + +local effects = { + CONST_ME_TUTORIALARROW, + CONST_ME_TUTORIALSQUARE +} + +local chestRoomTile = MoveEvent() + +function chestRoomTile.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local chestRoomExit = chestRooms.exits[item.actionid] + if chestRoomExit then + if player:getVocation():getId() == chestRoomExit.vocation then + if player:getStorageValue(Storage.Quest.Dawnport.VocationReward) == -1 then + player:sendTextMessage( + MESSAGE_EVENT_ADVANCE, + "You should check the chest for your " .. player:getVocation():getName() .. " equipment." + ) + elseif player:getStorageValue(Storage.Quest.Dawnport.VocationReward) == 1 then + player:teleportTo(chestRoomExit.destination, true) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage( + MESSAGE_EVENT_ADVANCE, + "You should leave for the Mainland now. Go left to reach the ship." + ) + end + elseif player:getVocation():getId() ~= chestRoomExit.vocation then + player:teleportTo(chestRoomExit.destination, true) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have not the right vocation to enter this room.") + end + return true + end + local chestRoomEntrance = chestRooms.entrances[item.actionid] + if chestRoomEntrance then + if player:getStorageValue(Storage.Dawnport.DoorVocation) == player:getVocation():getId() then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have chosen your vocation. You cannot go back.") + player:teleportTo(chestRoomEntrance.destination, true) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true + end + return true +end + +for index, value in pairs(chestRooms.entrances) do + chestRoomTile:aid(index) +end + +for index, value in pairs(chestRooms.exits) do + chestRoomTile:aid(index) +end + +chestRoomTile:register() + +-- Oressa stair, back if have reached level 20 or have chosen vocation +local templeStairs = MoveEvent() + +function templeStairs.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + if player:getStorageValue(Storage.Dawnport.DoorVocation) == player:getVocation():getId() then + player:sendTextMessage( + MESSAGE_EVENT_ADVANCE, + "You cannot go upstairs. You have chosen a vocation and must now leave for the Mainlands." + ) + player:teleportTo({x = 32063, y = 31891, z = 6}, true) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + elseif player:getLevel() >= 20 then + player:teleportTo(fromPosition, true) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +templeStairs:aid(25009) +templeStairs:register() + +-- First tutorial tile, on the first dawnport town +local tutorialTile = MoveEvent() + +function tutorialTile.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getLastLoginSaved() == 0 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Use these stairs to enter the Adventurer's Outpost on Dawnport.") + player:sendTutorial(1) + for i = 1, #effects do + Position({x = 32075, y = 31900, z = 6}):sendMagicEffect(effects[i]) + end + end + + return true +end + +tutorialTile:position({x = 32069, y = 31901, z = 6}) +tutorialTile:register() + +-- Before up stair on the first dawnport town +local tutorialTile1 = MoveEvent() + +function tutorialTile1.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + if player:getStorageValue(Storage.Quest.Dawnport.Questline) == 1 then + return true + end + if player:getStorageValue(Storage.Quest.Dawnport.Questline) < 1 then + player:sendTextMessage( + MESSAGE_EVENT_ADVANCE, + "Welcome to Dawnport! Walk around and explore on your own, or talk to Inigo if you need directions." + ) + player:sendTutorial(2) + player:setStorageValue(Storage.Quest.Dawnport.Questline, 1) + player:setStorageValue(Storage.Quest.Dawnport.GoMain, 1) + player:setTown(Town(TOWNS_LIST.DAWNPORT)) + end + return true +end + +tutorialTile1:position({x = 32075, y = 31898, z = 5}) +tutorialTile1:register() + +-- Tutorial tile for not back to dawnport first town +local tutorialTile2 = MoveEvent() + +function tutorialTile2.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + if item.itemid == 22693 then + player:teleportTo({x = 32070, y = 31900, z = 6}, true) + elseif item.itemid == 23745 then + player:teleportTo({x = 32075, y = 31899, z = 5}, true) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, " You move away hurriedly.") + end + return true +end + +tutorialTile2:id(22693, 23745) +tutorialTile2:register() + +-- Message on step in the stair for go to NPC's +local tutorialTile3 = MoveEvent() + +function tutorialTile3.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + if player:getStorageValue(Storage.Dawnport.Tutorial) ~= 0 then + player:sendTextMessage( + MESSAGE_EVENT_ADVANCE, + "To walk on STAIRS, use your arrow keys on your keyboard. You can also use them to walk in general." + ) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:setStorageValue(Storage.Dawnport.Tutorial, 0) + end + return true +end + +local positions = { + {x = 32075, y = 31896, z = 5}, + {x = 32074, y = 31896, z = 5}, + {x = 32073, y = 31896, z = 5}, + {x = 32072, y = 31896, z = 5}, + {x = 32072, y = 31895, z = 5} +} + +for i = 1, #positions do + tutorialTile3:position(positions[i]) +end + +tutorialTile3:register() + +-- Message before down stairs of vocation tiles +local tutorialTile4 = MoveEvent() + +function tutorialTile4.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + if player:getStorageValue(Storage.Dawnport.MessageStair) < 1 then + player:sendTextMessage( + MESSAGE_EVENT_ADVANCE, + "To ATTACK, click on a target in the battle list next to the game window. \z + A red frame shows which enemy you're attacking." + ) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:setStorageValue(Storage.Dawnport.MessageStair, 1) + end + + return true +end + +local positions = { + {x = 32063, y = 31906, z = 6}, + {x = 32064, y = 31906, z = 6}, + {x = 32065, y = 31906, z = 6}, + {x = 32049, y = 31890, z = 6}, + {x = 32049, y = 31891, z = 6}, + {x = 32049, y = 31892, z = 6}, + {x = 32079, y = 31890, z = 6}, + {x = 32079, y = 31891, z = 6}, + {x = 32079, y = 31892, z = 6}, + {x = 32063, y = 31875, z = 6}, + {x = 32064, y = 31875, z = 6}, + {x = 32065, y = 31875, z = 6} +} + +for i = 1, #positions do + tutorialTile4:position(positions[i]) +end + +tutorialTile4:register() + +-- Cure poison tiles at dawnport outpost entrances +local cureTile = MoveEvent() + +function cureTile.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + if player:getCondition(CONDITION_POISON) then + player:removeCondition(CONDITION_POISON) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are cured.") + end + return true +end + +cureTile:aid(20001) +cureTile:register() diff --git a/data/scripts/movements/others/dawnport_vocation_trial.lua b/data/scripts/movements/others/dawnport_vocation_trial.lua new file mode 100644 index 00000000000..0277f6f014d --- /dev/null +++ b/data/scripts/movements/others/dawnport_vocation_trial.lua @@ -0,0 +1,284 @@ +local tutorialEffects = { + CONST_ME_TUTORIALARROW, + CONST_ME_TUTORIALSQUARE +} + +local vocationTrials = { + -- Sorcerer trial + [25005] = { + tutorialId = 5, + effectPosition = {x = 32050, y = 31891, z = 5}, + storage = Storage.Dawnport.Sorcerer, + message = "As a sorcerer, you can use the following spells: Magic Patch, Buzz, Scorch.", + vocation = { + id = VOCATION.ID.SORCERER, + name = "sorcerer", + outfit = { + lookType = { + [PLAYERSEX_FEMALE] = 138, + [PLAYERSEX_MALE] = 130 + }, + lookHead = 95, + lookBody = 109, + lookLegs = 112, + lookFeet = 128 + } + }, + items = { + {id = 23719, amount = 1, slot = CONST_SLOT_LEFT}, -- The scorcher + {id = 23771, amount = 1, slot = CONST_SLOT_RIGHT}, -- Spellbook of the novice + {id = 8704, amount = 2, storage = Storage.Dawnport.SorcererHealthPotion, limit = 1}, -- Health potion + {id = 7620, amount = 10, storage = Storage.Dawnport.SorcererManaPotion, limit = 1}, -- Mana potion + {id = 23723, amount = 2, storage = Storage.Dawnport.SorcererLightestMissile, limit = 1}, -- Lightest missile runes + {id = 23722, amount = 2, storage = Storage.Dawnport.SorcererLightStoneShower, limit = 1}, -- Light stone shower runes + {id = 2666, amount = 1, storage = Storage.Dawnport.SorcererMeat, limit = 1} -- Meat + } + }, + -- Druid trial + [25006] = { + tutorialId = 6, + effectPosition = {x = 32064, y = 31905, z = 5}, + storage = Storage.Dawnport.Druid, + message = "As a druid, you can use these spells: Mud Attack, Chill Out, Magic Patch.", + vocation = { + id = VOCATION.ID.DRUID, + name = "druid", + outfit = { + lookType = { + [PLAYERSEX_FEMALE] = 138, + [PLAYERSEX_MALE] = 130 + }, + lookHead = 95, + lookBody = 123, + lookLegs = 9, + lookFeet = 118 + } + }, + items = { + {id = 23721, amount = 1, slot = CONST_SLOT_LEFT}, -- The chiller + {id = 23771, amount = 1, slot = CONST_SLOT_RIGHT}, -- Spellbook of the novice + {id = 8704, amount = 2, storage = Storage.Dawnport.DruidHealthPotion, limit = 1}, -- Health potion + {id = 7620, amount = 10, storage = Storage.Dawnport.DruidManaPotion, limit = 1}, -- Mana potion + {id = 23723, amount = 2, storage = Storage.Dawnport.DruidLightestMissile, limit = 1}, -- Lightest missile runes + {id = 23722, amount = 2, storage = Storage.Dawnport.DruidLightStoneShower, limit = 1}, -- Light stone shower runes + {id = 2666, amount = 1, storage = Storage.Dawnport.DruidMeat, limit = 1} -- Meat + } + }, + -- Paladin trial + [25007] = { + tutorialId = 4, + effectPosition = {x = 32078, y = 31891, z = 5}, + storage = Storage.Dawnport.Paladin, + message = "As a paladin, you can use the following spells: Magic Patch, Arrow Call.", + vocation = { + id = VOCATION.ID.PALADIN, + name = "paladin", + outfit = { + lookType = { + [PLAYERSEX_FEMALE] = 137, + [PLAYERSEX_MALE] = 129 + }, + lookHead = 95, + lookBody = 117, + lookLegs = 98, + lookFeet = 78 + } + }, + items = { + {id = 2456, amount = 1, slot = CONST_SLOT_LEFT}, -- Bow + {id = 40397, amount = 1, slot = CONST_SLOT_RIGHT}, -- Quiver + {id = 23839, amount = 100}, -- Simple arrow + {id = 8704, amount = 7, storage = Storage.Dawnport.PaladinHealthPotion, limit = 1}, -- Health potion + {id = 7620, amount = 5, storage = Storage.Dawnport.PaladinManaPotion, limit = 1}, -- Mana potion + {id = 23723, amount = 1, storage = Storage.Dawnport.PaladinLightestMissile, limit = 1}, -- Lightest missile rune + {id = 23722, amount = 1, storage = Storage.Dawnport.PaladinLightStoneShower, limit = 1}, -- Light stone shower rune + {id = 2666, amount = 1, storage = Storage.Dawnport.PaladinMeat, limit = 1} -- Meat + } + }, + -- Knight trial + [25008] = { + tutorialId = 3, + effectPosition = {x = 32064, y = 31876, z = 5}, + storage = Storage.Dawnport.Knight, + message = "As a knight, you can use the following spells: Bruise Bane.", + vocation = { + id = VOCATION.ID.KNIGHT, + name = "knight", + outfit = { + lookType = { + [PLAYERSEX_FEMALE] = 139, + [PLAYERSEX_MALE] = 131 + }, + lookHead = 95, + lookBody = 38, + lookLegs = 94, + lookFeet = 115 + } + }, + items = { + {id = 2379, amount = 1, slot = CONST_SLOT_LEFT}, -- Dagger + {id = 2512, amount = 1, slot = CONST_SLOT_RIGHT}, -- Wooden shield + {id = 8704, amount = 10, storage = Storage.Dawnport.KnightHealthPotion, limit = 1}, -- Health potion + {id = 7620, amount = 2, storage = Storage.Dawnport.KnightManaPotion, limit = 1}, -- Mana potion + {id = 2666, amount = 1, storage = Storage.Dawnport.KnightMeat, limit = 1} -- Meat + } + } +} + +-- First items, added only in first step and having no vocation +local function addFirstItems(player) + local firstItems = { + slots = { + [CONST_SLOT_HEAD] = Game.createItem(2461), + [CONST_SLOT_ARMOR] = Game.createItem(2651), + [CONST_SLOT_LEGS] = Game.createItem(2649), + [CONST_SLOT_FEET] = Game.createItem(2643) + } + } + for slot, item in pairs(firstItems.slots) do + local ret = player:addItemEx(item, false, sot) + if not ret then + player:addItemEx(item, false, INDEX_WHEREEVER, 0) + end + end +end + +-- On step in tiles, for first step, second and third or more steps +local function tileStep(player, trial) + -- First Step + local vocationId = player:getVocation():getId() + if vocationId == VOCATION.ID.NONE then + for i = 1, #tutorialEffects do + Position(trial.effectPosition):sendMagicEffect(tutorialEffects[i]) + end + player:sendTutorial(trial.tutorialId) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + "As this is the first time you try out a vocation, the Guild has kitted you out. " .. trial.message) + addFirstItems(player) + -- Second step + elseif player:getStorageValue(trial.storage) == -1 and vocationId ~= VOCATION.ID.NONE then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("As this is your first time as a \z + ".. trial.vocation.name ..', you received a few extra items. ' .. trial.message)) + player:setStorageValue(trial.storage, 1) + player:sendTutorial(trial.tutorialId) + -- Other steps + elseif player:getStorageValue(trial.storage) == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("You have received the weapons of a \z + ".. trial.vocation.name ..'. ' .. trial.message)) + end + return true +end + +-- Remove vocation trial equipment items +local function removeItems(player) + local equipmentItemIds = { + 23719, -- The scorcher + 23721, -- The chiller + 23771, -- Spellbook of the novice + 2456, -- Bow + 2379, -- Dagger + 2512, -- Wooden shield + 40397 -- Quiver + } + for i = 1, #equipmentItemIds do + local equipmentItemAmount = player:getItemCount(equipmentItemIds[i]) + if equipmentItemAmount > 0 then + player:removeItem(equipmentItemIds[i], equipmentItemAmount) + end + end +end + +-- Add items to player from trial items data +local function addItems(player, items) + local backpack = player:getSlotItem(CONST_SLOT_BACKPACK) + for i = 1, #items do + local extra + if not items[i].slot then + extra = true + else + local equipped = player:getSlotItem(items[i].slot) + if equipped and backpack then + equipped:moveTo(backpack) + end + end + local giveItem = true + if items[i].limit and items[i].storage then + local given = math.max(player:getStorageValue(items[i].storage), 0) + if given >= items[i].limit then + giveItem = false + else + player:setStorageValue(items[i].storage, given + 1) + end + end + if giveItem then + if extra then + local itemType = ItemType(items[i].id) + if itemType:getWeaponType() == WEAPON_AMMO and isInArray({AMMO_ARROW, AMMO_BOLT}, itemType:getAmmoType()) then + local equipment = player:getSlotItem(CONST_SLOT_RIGHT) + local equipmentType = ItemType(equipment.itemid) + if equipment and equipmentType:getWeaponType() == WEAPON_QUIVER then + equipment:addItem(items[i].id, items[i].amount) + end + else + player:addItemEx(Game.createItem(items[i].id, items[i].amount), true, CONST_SLOT_WHEREEVER) + end + else + player:addItemEx(Game.createItem(items[i].id, items[i].amount), true, items[i].slot) + end + end + end +end + +-- Set player outfit from trial outfit data +local function setOutfit(player, outfit) + player:setOutfit({ + lookTypeEx = 0, + lookType = outfit.lookType[player:getSex()], + lookHead = outfit.lookHead, + lookBody = outfit.lookBody, + lookLegs = outfit.lookLegs, + lookFeet = outfit.lookFeet, + lookAddons = 0, + lookMount = 0 + }) +end + +-- Dawnport trial tiles step event +local dawnportVocationTrial = MoveEvent() + +function dawnportVocationTrial.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local trial = vocationTrials[item.actionid] + if trial then + -- Center room position + local centerPosition = Position(32065, 31891, 5) + if centerPosition:getDistance(fromPosition) < centerPosition:getDistance(position) then + -- Blocks the vocation trial if same vocation or after level 20 + if player:getVocation():getId() == trial.vocation.id or player:getLevel() >= 20 then + return true + end + -- On step in the tile + tileStep(player, trial) + -- Change to new vocation, convert magic level and skills and set proper stats + player:changeVocation(trial.vocation.id) + -- Remove vocation trial equipment items + removeItems(player) + -- Add player item + addItems(player, trial.items) + -- Change outfit + setOutfit(player, trial.vocation.outfit) + player:getPosition():sendMagicEffect(CONST_ME_BLOCKHIT) + return true + end + end + return true +end + +for index, value in pairs(vocationTrials) do + dawnportVocationTrial:aid(index) +end + +dawnportVocationTrial:register() diff --git a/data/scripts/movements/others/decay.lua b/data/scripts/movements/others/decay.lua new file mode 100644 index 00000000000..60127fda1d3 --- /dev/null +++ b/data/scripts/movements/others/decay.lua @@ -0,0 +1,11 @@ +local decay = MoveEvent() + +function decay.onStepIn(creature, item, position, fromPosition) + item:transform(item.itemid + 1) + item:decay() + return true +end + +decay:type("stepin") +decay:id(293, 461, 3310) +decay:register() diff --git a/data/scripts/movements/others/dough.lua b/data/scripts/movements/others/dough.lua new file mode 100644 index 00000000000..38da21f94d3 --- /dev/null +++ b/data/scripts/movements/others/dough.lua @@ -0,0 +1,21 @@ +local pastries = { + [2693] = 2689, + [6277] = 6278 +} + +local dough = MoveEvent() + +function dough.onAddItem(moveitem, tileitem, position) + local pastryId = pastries[moveitem.itemid] + if not pastryId then + return true + end + + moveitem:transform(pastryId) + position:sendMagicEffect(CONST_ME_HITBYFIRE) + return true +end + +dough:type("additem") +dough:id(1786, 1788, 1790, 1792) +dough:register() diff --git a/data/scripts/movements/others/drowning.lua b/data/scripts/movements/others/drowning.lua new file mode 100644 index 00000000000..9a91b6e823f --- /dev/null +++ b/data/scripts/movements/others/drowning.lua @@ -0,0 +1,65 @@ +local condition = createConditionObject(CONDITION_DROWN) +setConditionParam(condition, CONDITION_PARAM_PERIODICDAMAGE, -20) +setConditionParam(condition, CONDITION_PARAM_TICKS, -1) +setConditionParam(condition, CONDITION_PARAM_TICKINTERVAL, 2000) + +local underWater = {5405, 5406, 5407, 5408, 5409, 5410, 5743, 5744, 5764, 9671, 9672, 9673, 10019} + +local drowning = MoveEvent() + +function drowning.onStepIn(player, item, pos, fromPosition) +local cid = player:getId() + if player:isPlayer() then + if player:getCondition(CONDITION_DROWN,CONDITIONID_COMBAT) == nil then + doAddCondition(cid, condition) + end + if player:getStorageValue(17100) > os.time() then + if player:getStorageValue(17101) < 1 then + doChangeSpeed(cid, 600) + player:setStorageValue(17101,1) + end + end + end + + if(math.random(1, 10) == 1) then + Position(pos):sendMagicEffect(CONST_ME_BUBBLES) + end + return true +end + +drowning:type("stepin") + +for index, value in pairs(underWater) do + drowning:id(index) +end + +drowning:register() + +local underWater = {5405, 5406, 5407, 5408, 5409, 5410, 5743, 5744, 5764, 9671, 9672, 9673, 10019} + +drowning = MoveEvent() + +function drowning.onStepOut(player, item, pos) +local cid = player:getId() + if player:isPlayer() then + local ppos = player:getPosition() + if(isInArray(underWater, getThingfromPos({x = ppos.x, y = ppos.y, z = ppos.z, stackpos = 0}).itemid)) then + return true + else + doRemoveCondition(cid, CONDITION_DROWN) + if player:getStorageValue(17101) == 1 then + doChangeSpeed(cid, 600 * (-1)) + player:setStorageValue(17101,0) + end + end + end + return true +end + +drowning:type("stepout") + +for index, value in pairs(underWater) do + drowning:id(index) +end + +drowning:register() diff --git a/data/scripts/movements/others/noxious_claw.lua b/data/scripts/movements/others/noxious_claw.lua new file mode 100644 index 00000000000..065d31a042c --- /dev/null +++ b/data/scripts/movements/others/noxious_claw.lua @@ -0,0 +1,17 @@ +local noxiousClaw = MoveEvent() + +function noxiousClaw.onEquip(player, item, slot) + item:transform(10309) + if Tile(player:getPosition()):hasFlag(TILESTATE_PROTECTIONZONE) then + return true + end + + doTargetCombatHealth(0, player, COMBAT_PHYSICALDAMAGE, -200, -200, CONST_ME_DRAWBLOOD) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "It tightens around your wrist as you take it on.") + return true +end + +noxiousClaw:type("equip") +noxiousClaw:id(10310) +noxiousClaw:level(100) +noxiousClaw:register() diff --git a/data/scripts/movements/others/remove-create_item.lua b/data/scripts/movements/others/remove-create_item.lua new file mode 100644 index 00000000000..4032b514b8b --- /dev/null +++ b/data/scripts/movements/others/remove-create_item.lua @@ -0,0 +1,67 @@ +--[[ +This script will remove/create an item when onStepIn/onStepOut on a configurable tile +Just put the variables in the table and it will register everything by itself + +Table path: data/startup/tables/tile.lua +]] + +local movement = MoveEvent() +movement:type("stepin") + +function movement.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local setting = TileUnique[item.uid] + if not setting then + return true + end + + local tile = Tile(setting.targetPos) + if tile then + local getItemTile = tile:getItemById(setting.targetItem) + if getItemTile then + getItemTile:remove() + end + end + return true +end + +for uniqueRange = 29001, 30000 do + movement:uid(uniqueRange) +end + +movement:register() + +-- onStepOut +movement = MoveEvent() +movement:type("stepout") + +function movement.onStepOut(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local setting = TileUnique[item.uid] + if not setting then + return true + end + + local tile = Tile(setting.targetPos) + if tile then + local getItemTile = tile:getItemById(setting.targetItem) + if not getItemTile then + Game.createItem(setting.targetItem, 1, setting.targetPos) + end + end + return true +end + +for uniqueRange = 29001, 30000 do + movement:uid(uniqueRange) +end + +movement:register() diff --git a/data/scripts/movements/others/snow.lua b/data/scripts/movements/others/snow.lua new file mode 100644 index 00000000000..01b4be22ca5 --- /dev/null +++ b/data/scripts/movements/others/snow.lua @@ -0,0 +1,20 @@ +local snow = MoveEvent() + +function snow.onStepOut(creature, item, position, fromPosition) + local player = creature:getPlayer() + if player and player:isInGhostMode() then + return true + end + + if item.itemid == 670 then + item:transform(6594) + else + item:transform(item.itemid + 15) + end + item:decay() + return true +end + +snow:type("stepout") +snow:id(670, 6580, 6581, 6582, 6583, 6584, 6585, 6586, 6587, 6588, 6589, 6590, 6591, 6592, 6593) +snow:register() diff --git a/data/scripts/movements/others/swimming.lua b/data/scripts/movements/others/swimming.lua new file mode 100644 index 00000000000..9c387a810f0 --- /dev/null +++ b/data/scripts/movements/others/swimming.lua @@ -0,0 +1,42 @@ +local condition = Condition(CONDITION_OUTFIT) +condition:setOutfit({lookType = 267}) +condition:setTicks(-1) + +local conditions = { + CONDITION_POISON, CONDITION_FIRE, CONDITION_ENERGY, + CONDITION_PARALYZE, CONDITION_DRUNK, CONDITION_DROWN, + CONDITION_FREEZING, CONDITION_DAZZLED, CONDITION_CURSED, + CONDITION_BLEEDING +} + +local swimming = MoveEvent() + +function swimming.onStepIn(creature, item, position, fromPosition) + if not creature:isPlayer() then + return false + end + for i = 1, #conditions do + creature:removeCondition(conditions[i]) + end + creature:addCondition(condition) + return true +end + +swimming:type("stepin") +swimming:id(4620, 4621, 4622, 4623, 4624, 4625) +swimming:register() + +swimming = MoveEvent() + +function swimming.onStepOut(creature, item, position, fromPosition) + if not creature:isPlayer() then + return false + end + + creature:removeCondition(CONDITION_OUTFIT) + return true +end + +swimming:type("stepout") +swimming:id(4620, 4621, 4622, 4623, 4624, 4625) +swimming:register() diff --git a/data/scripts/movements/others/teleport.lua b/data/scripts/movements/others/teleport.lua new file mode 100644 index 00000000000..c430e446311 --- /dev/null +++ b/data/scripts/movements/others/teleport.lua @@ -0,0 +1,22 @@ +-- Table Path: data/startup/tables/teleport.lua +local teleport = MoveEvent() + +function teleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local setting = TeleportUnique[item.uid] + if setting then + player:teleportTo(setting.destination) + player:getPosition():sendMagicEffect(setting.effect) + end + return true +end + +for uniqueRange = 38001, 40000 do + teleport:uid(uniqueRange) +end + +teleport:register() diff --git a/data/scripts/movements/others/tiles.lua b/data/scripts/movements/others/tiles.lua new file mode 100644 index 00000000000..e457d6a03a7 --- /dev/null +++ b/data/scripts/movements/others/tiles.lua @@ -0,0 +1,85 @@ +local increasing = {[416] = 417, [426] = 425, [446] = 447, [3216] = 3217, [3202] = 3215, [11062] = 11063} +local decreasing = {[417] = 416, [425] = 426, [447] = 446, [3217] = 3216, [3215] = 3202, [11063] = 11062} + +-- onStepIn +local tiles = MoveEvent() + +function tiles.onStepIn(creature, item, position, fromPosition) + if not increasing[item.itemid] then + return true + end + + local player = creature:getPlayer() + if not player or player:isInGhostMode() then + return true + end + + item:transform(increasing[item.itemid]) + + if item.actionid >= 1000 then + if player:getLevel() < item.actionid - 1000 then + player:teleportTo(fromPosition, false) + position:sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:sendTextMessage(MESSAGE_FAILURE, "The tile seems to be protected against unwanted intruders.") + end + return true + end + + if position:getTile():hasFlag(TILESTATE_PROTECTIONZONE) then + local lookPosition = player:getPosition() + lookPosition:getNextPosition(player:getDirection()) + local depotItem = lookPosition:getTile():getItemByType(ITEM_TYPE_DEPOT) + + if depotItem ~= nil then + local depotItems = 0 + for id = 1, configManager.getNumber("depotBoxes") do + depotItems = depotItems + player:getDepotChest(id, true):getItemHoldingCount() + end + + player:sendTextMessage(MESSAGE_FAILURE, "Your depot contains " .. depotItems .. " item" .. (depotItems > 1 and "s." or ".") .. "\ + Your supply stash contains " .. player:getStashCount() .. " item" .. (player:getStashCount() > 1 and "s." or ".")) + player:setSpecialContainersAvailable(true, true) + return true + end + end + + if item.actionid ~= 0 and player:getStorageValue(item.actionid) <= 0 then + player:teleportTo(fromPosition, false) + position:sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The tile seems to be protected against unwanted intruders.") + return true + end +end + +tiles:type("stepin") + +for index, value in pairs(increasing) do + tiles:id(index) +end + +tiles:register() + +tiles = MoveEvent() + +function tiles.onStepOut(creature, item, position, fromPosition) + if not decreasing[item.itemid] then + return false + end + + local player = creature:getPlayer() + if not player or player:isInGhostMode() then + return true + end + + item:transform(decreasing[item.itemid]) + player:setSpecialContainersAvailable(false, false) + return true +end + +tiles:type("stepout") + +for index, value in pairs(decreasing) do + tiles:id(index) +end + +tiles:register() diff --git a/data/scripts/movements/others/trap.lua b/data/scripts/movements/others/trap.lua new file mode 100644 index 00000000000..a84f69b46c8 --- /dev/null +++ b/data/scripts/movements/others/trap.lua @@ -0,0 +1,68 @@ +local traps = { + [1510] = {transformTo = 1511, damage = {-50, -100}}, + [1513] = {damage = {-50, -100}}, + [2579] = {transformTo = 2578, damage = {-15, -30}, ignorePlayer = (Game.getWorldType() == WORLD_TYPE_NO_PVP) }, + [4208] = {transformTo = 4209, damage = {-15, -30}, type = COMBAT_EARTHDAMAGE} +} + +local trap = MoveEvent() + +function trap.onStepIn(creature, item, position, fromPosition) + local trap = traps[item.itemid] + if not trap then + return true + end + + if Tile(position):hasFlag(TILESTATE_PROTECTIONZONE) then + return true + end + + if Tile(position):getItemCountById(2579) > 1 then + return true + end + + if trap.ignorePlayer and creature:isPlayer() then + return true + end + + if trap.transformTo then + item:transform(trap.transformTo) + end + + doTargetCombatHealth(0, creature, trap.type or COMBAT_PHYSICALDAMAGE, trap.damage[1], trap.damage[2], CONST_ME_NONE) + return true +end + +trap:type("stepin") +trap:id(1510, 1513, 2579, 4208) +trap:register() + +trap = MoveEvent() + +function trap.onStepOut(creature, item, position, fromPosition) + if Tile(position):hasFlag(TILESTATE_PROTECTIONZONE) then + return true + end + + item:transform(item.itemid - 1) + return true +end + +trap:type("stepout") +trap:id(1511, 4209) +trap:register() + +trap = MoveEvent() + +function trap.onRemoveItem(item, tile, position) + local itemPosition = item:getPosition() + if itemPosition:getDistance(position) > 0 then + item:transform(item.itemid - 1) + itemPosition:sendMagicEffect(CONST_ME_POFF) + end + return true +end + +trap:type("removeitem") +trap:id(2579) +trap:register() diff --git a/data/scripts/movements/others/walkback.lua b/data/scripts/movements/others/walkback.lua new file mode 100644 index 00000000000..3427daaf414 --- /dev/null +++ b/data/scripts/movements/others/walkback.lua @@ -0,0 +1,32 @@ +local SPECIAL_QUESTS = {2215, 2216, 10544, 12374, 12513, 26300, 27300, 28300} + +local walkback = MoveEvent() + +function walkback.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + + if not player or (player:getAccountType() ~= ACCOUNT_TYPE_NORMAL and player:getGroup():getId() > GROUP_TYPE_SENIORTUTOR) then + return true + end + + if (Container(item.uid) and not isInArray(SPECIAL_QUESTS, item.actionid) and item.uid > 65535) then + return true + end + + if position == fromPosition then + if player:isPlayer() then + local temple = creature:getTown():getTemplePosition() + player:teleportTo(temple, false) + else + player:remove() + end + else + creature:teleportTo(fromPosition, true) + end + + return true +end + +walkback:type("stepin") +walkback:id(1714, 1715, 1716, 1717, 1738, 1740, 1741, 1746, 1747, 1748, 1749, 23798, 23799, 23800, 23801, 23802, 23803, 23804, 23805) +walkback:register() diff --git a/data/scripts/movements/quests/assassin_outfit/erayo_house.lua b/data/scripts/movements/quests/assassin_outfit/erayo_house.lua new file mode 100644 index 00000000000..e54bd2d1236 --- /dev/null +++ b/data/scripts/movements/quests/assassin_outfit/erayo_house.lua @@ -0,0 +1,25 @@ +local enterPosition = Position(32519, 32911, 7) +local exitPosition = Position(32519, 32912, 7) + +local erayoHouse = MoveEvent() + +function erayoHouse.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if not (position == enterPosition) then + return true + end + + if not player:getItemById(2202, deepSearch) and not player:getCondition(CONDITION_INVISIBLE) then + player:teleportTo(exitPosition) + end + + return true +end + +erayoHouse:type("stepin") +erayoHouse:id(3139) +erayoHouse:register() diff --git a/data/scripts/movements/quests/bigfoot_burden/gnomebase_teleport.lua b/data/scripts/movements/quests/bigfoot_burden/gnomebase_teleport.lua new file mode 100644 index 00000000000..245d59c63eb --- /dev/null +++ b/data/scripts/movements/quests/bigfoot_burden/gnomebase_teleport.lua @@ -0,0 +1,68 @@ +local destination = { + [4121] = {position = Position(32801, 31766, 9), storageValue = 1, needCrystal = true}, + [3220] = {position = Position(32627, 31864, 11), storageValue = 1, needCrystal = true}, + [3128] = {position = Position(33000, 31870, 13), storageValue = 1}, + [3129] = {position = Position(32795, 31762, 10), storageValue = 1}, + [3130] = {position = Position(32864, 31844, 11), storageValue = 1}, + [3131] = {position = Position(32803, 31746, 10), storageValue = 1}, + [3132] = {position = Position(32988, 31862, 9), storageValue = 27}, -- gnomebase alpha + [3133] = {position = Position(32798, 31783, 10), storageValue = 27}, -- city + [3134] = {position = Position(32959, 31953, 9), storageValue = 27}, -- golems + [3135] = {position = Position(33001, 31915, 9), storageValue = 27}, -- back from golems + [3136] = {position = Position(32904, 31894, 13), storageValue = 27}, -- vulcongras + [3137] = {position = Position(32979, 31907, 9), storageValue = 27}, -- back from vulcongras + [3215] = {position = Position(32329, 32172, 9), storageValue = 1, needCrystal = true}, + [3216] = {position = Position(32195, 31182, 8), storageValue = 1, needCrystal = true}, + [3217] = {position = Position(32402, 32816, 6), storageValue = 1, needCrystal = true}, + [3218] = {position = Position(33153, 31833, 10), storageValue = 1, needCrystal = true}, + [3219] = {position = Position(33186, 32385, 8), storageValue = 1, needCrystal = true}, + [3222] = {position = Position(32771, 31800, 10), storageValue = 11, needCrystal = false}, + [3221] = {position = Position(32790, 31795, 10), storageValue = 11, needCrystal = false} +} + +local gnomebaseTeleport = MoveEvent() + +function gnomebaseTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + + local teleportCrystal = destination[item.actionid] + if not teleportCrystal then + return + end + + if player:getStorageValue(Storage.BigfootBurden.QuestLine) < 1 then + fromPosition:sendMagicEffect(CONST_ME_POFF) + player:teleportTo(fromPosition) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have no idea on how to use this device. Xelvar in Kazordoon might tell you more about it.') + return false + end + + if player:getStorageValue(Storage.BigfootBurden.QuestLine) < teleportCrystal.storageValue then + position:sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(fromPosition) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your rank among the Gnomes is too low.") + return false + end + + if not teleportCrystal.needCrystal or player:removeItem(18457, 1) then + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(teleportCrystal.position) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + fromPosition:sendMagicEffect(CONST_ME_POFF) + player:teleportTo(fromPosition) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You need a teleport crystal in order to use this device.') + end + return true +end + +gnomebaseTeleport:type("stepin") + +for index, value in pairs(destination) do + gnomebaseTeleport:aid(index) +end + +gnomebaseTeleport:register() diff --git a/data/scripts/movements/quests/bigfoot_burden/task_endurance.lua b/data/scripts/movements/quests/bigfoot_burden/task_endurance.lua new file mode 100644 index 00000000000..8e65ca613c7 --- /dev/null +++ b/data/scripts/movements/quests/bigfoot_burden/task_endurance.lua @@ -0,0 +1,50 @@ +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 2000) +condition:setFormula(-0.9, 0, -0.9, 0) + +local taskEndurance = MoveEvent() + +function taskEndurance.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if item.actionid == 7816 then + local chance = math.random(5) + if chance == 1 then + local chancegasp = math.random(10) + if chancegasp == 4 then + fromPosition:sendMagicEffect(CONST_ME_STUN) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "") + end + player:teleportTo(fromPosition) + elseif chance == 2 then + player:teleportTo(Position(position.x, position.y + 1, position.z), true) + player:setDirection(DIRECTION_SOUTH) + elseif chance == 3 then + player:teleportTo(fromPosition) + end + + elseif item.actionid == 7817 then --finish of the test + player:setStorageValue(Storage.BigfootBurden.QuestLine, 18) + player:teleportTo(Position(32760, 31811, 10)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + + elseif item.actionid == 7818 then -- entrance to the test + if player:getStorageValue(Storage.BigfootBurden.QuestLine) == 17 then + player:teleportTo(Position(32759, 31812, 11)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + local backPos = Position(32760, 31811, 10) + player:teleportTo(backPos) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Luckily you do not have to take the endurance at this time.") + backPos:sendMagicEffect(CONST_ME_TELEPORT) + end + end + return true +end + +taskEndurance:type("stepin") +taskEndurance:aid(7816, 7817, 7818) +taskEndurance:register() diff --git a/data/scripts/movements/quests/bigfoot_burden/task_shooting.lua b/data/scripts/movements/quests/bigfoot_burden/task_shooting.lua new file mode 100644 index 00000000000..fb063721657 --- /dev/null +++ b/data/scripts/movements/quests/bigfoot_burden/task_shooting.lua @@ -0,0 +1,66 @@ +local function doCreateDummy(cid, position, storv) + local player = Player(cid) + if not player then + return true + end + + local tile = Tile(position) + if tile then + local thing = tile:getTopVisibleThing() + if thing and isInArray({18226, 18227}, thing.itemid) then + thing:remove() + end + end + + if Game.getStorageValue(storv) == 0 then -- Only spawn the target if the storage corresponds that someone is there shooting + return true + end + + position:sendMagicEffect(CONST_ME_POFF) + Game.createItem(math.random(18226, 18227), 1, position) + addEvent(doCreateDummy, 4 * 1000, cid, position, storv) +end + +local taskShooting = MoveEvent() + +function taskShooting.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.BigfootBurden.QuestLine) ~= 13 then + player:teleportTo(fromPosition) + return true + end + + Game.setStorageValue(position.x, 1) -- Set global storage for the script to know if someone is there shooting + local playerPosition = player:getPosition() + position:sendMagicEffect(CONST_ME_POFF) + doCreateDummy(player.uid, Position(playerPosition.x, playerPosition.y - 5, 10), position.x) + return true +end + +taskShooting:type("stepin") +taskShooting:aid(8030) +taskShooting:register() + +taskShooting = MoveEvent() + +function taskShooting.onStepOut(creature, item, position, fromPosition) + Game.setStorageValue(fromPosition.x, 0) + + -- Remove the target if it remains there + thingpos = Position(position.x, position.y - 5, position.z) + local tile = Tile(thingpos) + if tile then + local thing = tile:getTopVisibleThing() + if thing and isInArray({18226, 18227}, thing.itemid) then + thing:remove() + end + end +end + +taskShooting:type("stepout") +taskShooting:aid(8030) +taskShooting:register() diff --git a/data/scripts/movements/quests/bigfoot_burden/task_truffles.lua b/data/scripts/movements/quests/bigfoot_burden/task_truffles.lua new file mode 100644 index 00000000000..966b29f3784 --- /dev/null +++ b/data/scripts/movements/quests/bigfoot_burden/task_truffles.lua @@ -0,0 +1,27 @@ +local taskTruffles = MoveEvent() + +function taskTruffles.onStepIn(creature, item, position, fromPosition) + if creature:getName():lower() ~= 'mushroom sniffer' then + return true + end + + local moldFloor = Tile(position):getItemById(18340) + if moldFloor.actionid == 100 then + return true + end + + if math.random(3) < 3 then + moldFloor:transform(18218) + moldFloor:decay() + position:sendMagicEffect(CONST_ME_POFF) + else + moldFloor:transform(18341) + moldFloor:decay() + position:sendMagicEffect(CONST_ME_GROUNDSHAKER) + end + return true +end + +taskTruffles:type("stepin") +taskTruffles:id(18340) +taskTruffles:register() diff --git a/data/scripts/movements/quests/bigfoot_burden/task_x_ray.lua b/data/scripts/movements/quests/bigfoot_burden/task_x_ray.lua new file mode 100644 index 00000000000..af5dbe76e56 --- /dev/null +++ b/data/scripts/movements/quests/bigfoot_burden/task_x_ray.lua @@ -0,0 +1,86 @@ +local messages = { + {"Gnomedix: So let the examination begin! Now don't move. Don't be afraid. \z + The good doctor gnome won't hurt you - hopefully!", CONST_ME_LOSEENERGY}, + {"Gnomedix: Now! Now! Don't panic! It's all over soon!"}, + {"Gnomedix: Let me try a bigger chisel!", CONST_ME_POFF}, + {"Gnomedix: We're almost don... holy gnome! What's THIS???"}, + {"Gnomedix: I need a drill! Gnomenursey, quick!"}, + {"Gnomedix: Hold still now! This might tickle a little..", CONST_ME_STUN}, + {"Gnomedix: Take this, you evil ... whatever you are!"}, + {"Gnomedix: I got it! Yikes! What was that? Uhm, well ... \z + you passed the ear examination. Talk to Gnomaticus for your next test.", CONST_ME_BLOCKHIT} +} + +local function sendTextMessages(cid, index, position) + local player = Player(cid) + if not player then + return true + end + + if index ~= player:getStorageValue(Storage.BigfootBurden.GnomedixMsg) then + return false + end + + local playerposuid = Tile(player:getPosition()):getGround() + playerposuid = playerposuid:getUniqueId() + if playerposuid ~= 3123 then + return false + end + + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, messages[index][1]) + if messages[index][2] then + position:sendMagicEffect(messages[index][2]) + end + player:setStorageValue(Storage.BigfootBurden.GnomedixMsg, + player:getStorageValue(Storage.BigfootBurden.GnomedixMsg) + 1) + if index == 8 then + position.y = position.y + 1 + Game.createMonster("Strange Slime", position) + player:setStorageValue(Storage.BigfootBurden.QuestLine, 11) + end +end + +local condition = Condition(CONDITION_OUTFIT) +condition:setTicks(2000) +condition:setOutfit({lookType = 33}) -- skeleton looktype + +local taskXRay = MoveEvent() + +function taskXRay.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if item.actionid == 9200 then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) == 8 then + player:addCondition(condition) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + end + elseif item.actionid == 9201 then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) == 8 then + player:addCondition(condition) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:setStorageValue(Storage.BigfootBurden.QuestLine, 10) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + "You have been succesfully g-rayed. Now let Doctor Gnomedix inspect your ears!") + end + elseif item.uid == 3123 then + if player:getStorageValue(Storage.BigfootBurden.QuestLine) ~= 10 then + return true + end + player:setStorageValue(Storage.BigfootBurden.GnomedixMsg, 1) + position:sendMagicEffect(CONST_ME_LOSEENERGY) + + for i = player:getStorageValue(Storage.BigfootBurden.GnomedixMsg), #messages do + addEvent(sendTextMessages, (i - 1) * 4000, player.uid, i, player:getPosition()) + end + + end + return true +end + +taskXRay:type("stepin") +taskXRay:aid(9200, 9201) +taskXRay:uid(3123) +taskXRay:register() diff --git a/data/scripts/movements/quests/bigfoot_burden/versperoth_spawn.lua b/data/scripts/movements/quests/bigfoot_burden/versperoth_spawn.lua new file mode 100644 index 00000000000..2924ffebf00 --- /dev/null +++ b/data/scripts/movements/quests/bigfoot_burden/versperoth_spawn.lua @@ -0,0 +1,83 @@ +local versperothPosition = Position(33075, 31878, 12) + +local function removeMinion(mid) + local monster = Monster(mid) + if monster then + monster:getPosition():sendMagicEffect(CONST_ME_POFF) + monster:remove() + end +end + +local function executeVersperothBattle(mid) + if Game.getStorageValue(GlobalStorage.BigfootBurden.Versperoth.Battle) ~= 1 then + return false + end + + if mid then + local monster = Monster(mid) + if not monster then + return false + else + end + + Game.setStorageValue(GlobalStorage.BigfootBurden.Versperoth.Health, monster:getHealth()) + monster:remove() + local blood = Tile(versperothPosition):getItemById(2019) + if blood then + blood:remove() + end + + local hole = Tile(versperothPosition):getItemById(18462) + if not hole then + Game.createItem(18462, 1, versperothPosition) + end + versperothPosition:sendMagicEffect(CONST_ME_POFF) + + local position, minionMonster + for i = 1, 10 do + position = Position(math.random(33070, 33081), math.random(31874, 31883), 12) + minionMonster = Game.createMonster('Minion of Versperoth', position) + position:sendMagicEffect(CONST_ME_TELEPORT) + if minionMonster then + addEvent(removeMinion, 20 * 1000, minionMonster.uid) + end + end + addEvent(executeVersperothBattle, 10 * 1000) + return + end + + local monster = Game.createMonster('Versperoth', versperothPosition, false, true) + if monster then + local holee = Tile(versperothPosition):getItemById(18462) + if holee then + holee:remove() + end + versperothPosition:sendMagicEffect(CONST_ME_GROUNDSHAKER) + monster:setHealth(Game.getStorageValue(GlobalStorage.BigfootBurden.Versperoth.Health)) + addEvent(executeVersperothBattle, 20 * 1000, monster.uid) + end +end + +local versperothSpawn = MoveEvent() + +function versperothSpawn.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if Game.getStorageValue(GlobalStorage.BigfootBurden.Versperoth.Battle) >= 1 then + player:say("Versperoth has already been defeated in the last 30 minutes.", TALKTYPE_MONSTER_SAY) + return true + end + player:teleportTo(Position(33072, 31877, 12)) + Game.setStorageValue(GlobalStorage.BigfootBurden.Versperoth.Battle, 1) + Game.setStorageValue(GlobalStorage.BigfootBurden.Versperoth.Health, 100000) + executeVersperothBattle() + item:remove() + return true +end + +versperothSpawn:type("stepin") +versperothSpawn:id(18463) +versperothSpawn:register() diff --git a/data/scripts/movements/quests/bigfoot_burden/warzone_boss.lua b/data/scripts/movements/quests/bigfoot_burden/warzone_boss.lua new file mode 100644 index 00000000000..073d49380b9 --- /dev/null +++ b/data/scripts/movements/quests/bigfoot_burden/warzone_boss.lua @@ -0,0 +1,52 @@ +local function filter(list, f, i) + if i < #list then + if f(list[i]) then + return list[i], filter(list, f, i + 1) + else + return filter(list, f, i + 1) + end + elseif list[i] and f(list[i]) then + return list[i] + end +end + +local function spawnBoss(inf) + local boss = Game.createMonster(inf.boss, inf.bossResp) + boss:registerEvent('BossWarzoneDeath') +end + +local warzoneBoss = MoveEvent() + +function warzoneBoss.onStepIn(creature, item, pos, fromPosition) + if not creature:isPlayer() then + creature:teleportTo(fromPosition) + return false + end + + local warzone = warzoneConfig[item:getActionId()] + if not warzone then + return false + end + + if creature:getStorageValue(warzone.storage) > os.time() then + creature:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have already cleared this warzone in the last 20 hours.") + creature:teleportTo(fromPosition) + return false + end + + if warzone.locked then + creature:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Please, wait until the room is cleared. \z + This happens 30 minutes after the last team entered.") + creature:teleportTo(fromPosition) + return true + end + + creature:teleportTo(warzone.teleportTo) + creature:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have half an hour to heroically defeat the \z + " .. warzone.boss .. ". Otherwise you'll be teleported out by the gnomish emergency device." ) + return true +end + +warzoneBoss:type("stepin") +warzoneBoss:aid(45700, 45701, 45702) +warzoneBoss:register() diff --git a/data/scripts/movements/quests/bigfoot_burden/warzone_teleport.lua b/data/scripts/movements/quests/bigfoot_burden/warzone_teleport.lua new file mode 100644 index 00000000000..0ec71e7711b --- /dev/null +++ b/data/scripts/movements/quests/bigfoot_burden/warzone_teleport.lua @@ -0,0 +1,53 @@ +local destinations = { + [3140] = {teleportPosition = Position(32996, 31922, 10), storage = Storage.BigfootBurden.Warzone1Access, value = 1}, + [3141] = {teleportPosition = Position(33011, 31943, 11), storage = Storage.BigfootBurden.Warzone2Access, value = 2}, + [3142] = {teleportPosition = Position(32989, 31909, 12), storage = Storage.BigfootBurden.Warzone3Access, value = 3}, +} + +local warzoneTeleport = MoveEvent() + +function warzoneTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local destination = destinations[item.uid] + if not destination then + return true + end + + if player:getStorageValue(Storage.BigfootBurden.QuestLine) < 30 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are not permitted to enter.") + player:teleportTo(fromPosition) + position:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + if player:getStorageValue(Storage.BigfootBurden.WarzoneStatus) < 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You finally have enough renown among the gnomes, \z + ask Gnomission for a mission to fight on the warzones.") + player:teleportTo(fromPosition) + position:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + if player:getStorageValue(destination.storage) < 1 and not player:removeItem(18509, 1) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need a mission crystal or a job done with Gnomission to enter.") + player:teleportTo(fromPosition) + position:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + player:teleportTo(destination.teleportPosition) + destination.teleportPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +warzoneTeleport:type("stepin") + +for index, value in pairs(destinations) do + warzoneTeleport:uid(index) +end + +warzoneTeleport:register() diff --git a/data/scripts/movements/quests/bright_sword/entrance.lua b/data/scripts/movements/quests/bright_sword/entrance.lua new file mode 100644 index 00000000000..85447176db6 --- /dev/null +++ b/data/scripts/movements/quests/bright_sword/entrance.lua @@ -0,0 +1,15 @@ +local brightSword = MoveEvent() + +function brightSword.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + player:teleportTo(Position(32619, 32249, 8)) + return true +end + +brightSword:type("stepin") +brightSword:aid(5634) +brightSword:register() diff --git a/data/scripts/movements/quests/chayenne_realm/enter_realm.lua b/data/scripts/movements/quests/chayenne_realm/enter_realm.lua new file mode 100644 index 00000000000..8f6c1e165a4 --- /dev/null +++ b/data/scripts/movements/quests/chayenne_realm/enter_realm.lua @@ -0,0 +1,30 @@ +local enterRealm = MoveEvent() + +function enterRealm.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if item.actionid == 55022 then + if player:getItemCount(16015) >= 1 and player:getLevel() >= 40 then + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(Position(32829, 31451, 8)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You're entering the realm of dreams.") + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You do not have level 40+ or missing the Chayenne's magical key.") + player:teleportTo(fromPosition, true) + end + elseif item.actionid == 55024 then + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(Position(33117, 32604, 6)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Goodbye, dream traveller...") + end + return true +end + +enterRealm:type("stepin") +enterRealm:aid(55022, 55024) +enterRealm:register() diff --git a/data/scripts/movements/quests/children_of_the_revolution/click.lua b/data/scripts/movements/quests/children_of_the_revolution/click.lua new file mode 100644 index 00000000000..4abe279fc70 --- /dev/null +++ b/data/scripts/movements/quests/children_of_the_revolution/click.lua @@ -0,0 +1,106 @@ +local config = { + positions = { + ({x = 33258, y = 31080, z = 8}), + ({x = 33266, y = 31084, z = 8}), + ({x = 33259, y = 31089, z = 8}), + ({x = 33263, y = 31093, z = 8}) + }, + stairPosition = Position(33265, 31116, 8), + areaCenter = Position(33268, 31119, 7), + zalamonPosition = Position(33353, 31410, 8), + + summonArea = { + from = Position(33252, 31105, 7), + to = Position(33288, 31134, 7) + }, + waves = { + {monster = 'eternal guardian', size = 20}, + {monster = 'eternal guardian', size = 20}, + {monster = 'eternal guardian', size = 20}, + {monster = 'lizard chosen', size = 20} + } +} + +function doClearMissionArea() + Game.setStorageValue(Storage.ChildrenoftheRevolution.Mission05, -1) + + local spectators, spectator = Game.getSpectators(config.areaCenter, false, true, 26, 26, 20, 20) + for i = 1, #spectators do + spectator = spectators[i] + if spectator:isPlayer() then + spectator:teleportTo(config.zalamonPosition) + spectator:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + if spectator:getStorageValue(Storage.ChildrenoftheRevolution.Questline) == 19 then + spectator:setStorageValue(Storage.ChildrenoftheRevolution.Questline, 20) + end + else + spectator:remove() + end + end + return true +end + +local function removeStairs() + local stair = Tile(config.stairPosition):getItemById(3687) + if stair then + stair:transform(3653) + end +end + +local function summonWave(i) + local wave = config.waves[i] + local summonPosition + for i = 1, wave.size do + summonPosition = Position(math.random(config.summonArea.from.x, + config.summonArea.to.x), math.random(config.summonArea.from.y, config.summonArea.to.y), 7) + Game.createMonster(wave.monster, summonPosition) + summonPosition:sendMagicEffect(CONST_ME_TELEPORT) + end +end + +local click = MoveEvent() + +function click.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.ChildrenoftheRevolution.Questline) ~= 19 + or Game.getStorageValue(Storage.ChildrenoftheRevolution.Mission05) == 1 then + return true + end + + local players = {} + for i = 1, #config.positions do + local creature = Tile(Position(config.positions[i])):getTopCreature() + if creature and creature:isPlayer() then + players[#players + 1] = creature + end + end + + if #players ~= #config.positions then + return true + end + + for i = 1, #players do + players[i]:say('A clicking sound tatters the silence.', TALKTYPE_MONSTER_SAY) + end + + local stair = Tile(config.stairPosition):getItemById(3653) + if stair then + stair:transform(3687) + end + Game.setStorageValue(Storage.ChildrenoftheRevolution.Mission05, 1) + + for wave = 1, #config.waves do + addEvent(summonWave, wave * 30 * 1000, wave) + end + addEvent(removeStairs, 30 * 1000) + addEvent(doClearMissionArea, 5 * 30 * 1000) + return true +end + +click:type("stepin") +click:aid(8014) +click:register() diff --git a/data/scripts/movements/quests/children_of_the_revolution/spy.lua b/data/scripts/movements/quests/children_of_the_revolution/spy.lua new file mode 100644 index 00000000000..f9f95a94da7 --- /dev/null +++ b/data/scripts/movements/quests/children_of_the_revolution/spy.lua @@ -0,0 +1,41 @@ +local config = { + [8009] = { + storage = Storage.ChildrenoftheRevolution.SpyBuilding01, + text = "An impressive ammount of fish is stored here."}, + [8010] = { + storage = Storage.ChildrenoftheRevolution.SpyBuilding02, + text = "A seemingly endless array of weapon stretches before you into the darkness."}, + [8011] = { + storage = Storage.ChildrenoftheRevolution.SpyBuilding03, + text = "These barracks seem to be home for quite a lot of soldiers."} +} + +local spy = MoveEvent() + +function spy.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local targetTile = config[item.actionid] + if not targetTile then + return true + end + + if player:getStorageValue(targetTile.storage) < 1 then + --Questlog, Children of the Revolution "Mission 2: Imperial Zzecret Weaponzz" + player:setStorageValue(Storage.ChildrenoftheRevolution.Mission02, player:getStorageValue(Storage.ChildrenoftheRevolution.Mission02) + 1) + player:setStorageValue(targetTile.storage, 1) + player:say(targetTile.text, TALKTYPE_MONSTER_SAY) + end + return true +end + +spy:type("stepin") + +for index, value in pairs(config) do + spy:aid(index) +end + +spy:register() diff --git a/data/scripts/movements/quests/children_of_the_revolution/stair.lua b/data/scripts/movements/quests/children_of_the_revolution/stair.lua new file mode 100644 index 00000000000..7ca2f73acbb --- /dev/null +++ b/data/scripts/movements/quests/children_of_the_revolution/stair.lua @@ -0,0 +1,36 @@ +local stairsPosition = Position(33265, 31116, 7) + +local function revertStairs() + Tile(stairsPosition):getItemById(9197):transform(3219) +end + +local stair = MoveEvent() + +function stair.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + -- check if going upstairs + if not Tile(position):getItemById(3687) then + return true + end + + local stairs = Tile(stairsPosition):getItemById(3219) + if stairs then + stairs:transform(9197) + addEvent(revertStairs, 5 * 30 * 1000) + end + + player:say('The area around the gate is suspiciously quiet, you have a bad feeling about this.', TALKTYPE_MONSTER_SAY) + if player:getStorageValue(Storage.ChildrenoftheRevolution.Mission05) == 1 then + --Questlog, Children of the Revolution 'Mission 5: Phantom Army' + player:setStorageValue(Storage.ChildrenoftheRevolution.Mission05, 2) + end + return true +end + +stair:type("stepin") +stair:uid(3169) +stair:register() diff --git a/data/scripts/movements/quests/children_of_the_revolution/symbol.lua b/data/scripts/movements/quests/children_of_the_revolution/symbol.lua new file mode 100644 index 00000000000..2381df4eb36 --- /dev/null +++ b/data/scripts/movements/quests/children_of_the_revolution/symbol.lua @@ -0,0 +1,21 @@ +local symbol = MoveEvent() + +function symbol.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.ChildrenoftheRevolution.StrangeSymbols) < 1 and + player:getStorageValue(Storage.ChildrenoftheRevolution.Mission03) >= 2 then + --Questlog, Children of the Revolution 'Mission 4: Zze Way of Zztonezz' + player:setStorageValue(Storage.ChildrenoftheRevolution.Mission04, 2) + player:setStorageValue(Storage.ChildrenoftheRevolution.StrangeSymbols, 1) + player:say('A part of the floor before you displays an arrangement of strange symbols.', TALKTYPE_MONSTER_SAY) + end + return true +end + +symbol:type("stepin") +symbol:uid(3166) +symbol:register() diff --git a/data/scripts/movements/quests/children_of_the_revolution/teleport.lua b/data/scripts/movements/quests/children_of_the_revolution/teleport.lua new file mode 100644 index 00000000000..73ffcd56223 --- /dev/null +++ b/data/scripts/movements/quests/children_of_the_revolution/teleport.lua @@ -0,0 +1,36 @@ +local config = { + [3167] = { + storage = Storage.ChildrenoftheRevolution.Questline, + teleportToPosition = {Position(33257, 31116, 8), Position(33356, 31126, 7)}}, + [3168] = { + storage = Storage.ChildrenoftheRevolution.Questline, + teleportToPosition = {Position(33356, 31125, 7), Position(33356, 31125, 7)}} +} + +local teleport = MoveEvent() + +function teleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local targetTile = config[item.uid] + if not targetTile then + return true + end + + local hasStorageValue = player:getStorageValue(targetTile.storage) >= 19 + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(targetTile.teleportToPosition[hasStorageValue and 1 or 2]) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +teleport:type("stepin") + +for index, value in pairs(config) do + teleport:uid(index) +end + +teleport:register() diff --git a/data/scripts/movements/quests/children_of_the_revolution/temple.lua b/data/scripts/movements/quests/children_of_the_revolution/temple.lua new file mode 100644 index 00000000000..80e6065d8e3 --- /dev/null +++ b/data/scripts/movements/quests/children_of_the_revolution/temple.lua @@ -0,0 +1,21 @@ +local temple = MoveEvent() + +function temple.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.ChildrenoftheRevolution.Questline) == 4 then + --Questlog, Children of the Revolution 'Mission 1: Corruption' + player:setStorageValue(Storage.ChildrenoftheRevolution.Mission01, 2) + player:setStorageValue(Storage.ChildrenoftheRevolution.Questline, 5) + player:say('The temple has been corrupted and is lost. Zalamon should be informed about this as soon as possible.', + TALKTYPE_MONSTER_SAY) + end + return true +end + +temple:type("stepin") +temple:uid(3163) +temple:register() diff --git a/data/scripts/movements/quests/cults_of_tibia/begin_task.lua b/data/scripts/movements/quests/cults_of_tibia/begin_task.lua new file mode 100644 index 00000000000..540f1530077 --- /dev/null +++ b/data/scripts/movements/quests/cults_of_tibia/begin_task.lua @@ -0,0 +1,58 @@ +function fallFloor(pid, id) + local player = Player(pid) + if not player then + return true + end + + local amulet = player:getSlotItem(CONST_SLOT_NECKLACE) + if not amulet or amulet:getId() ~= id then + return true + end + + local chance = math.random(0, 100) + if chance <= 1 then + amulet:moveTo(player:getPosition()) + end + addEvent(fallFloor, 10000, player:getId(), id) + return true +end + +local beginTask = MoveEvent() + +function beginTask.onEquip(player, item, slot, isCheck) + if isCheck then + return true + end + + if player:getStorageValue(Storage.CultsOfTibia.Misguided.Mission) >= 2 and + player:getStorageValue(Storage.CultsOfTibia.Misguided.Mission) <= 3 then + local equippedBefore = item:getSpecialAttribute("task") or 0 + if equippedBefore ~= player:getGuid() and + player:getStorageValue(Storage.CultsOfTibia.Misguided.Monsters) < 10 then + player:setStorageValue(Storage.CultsOfTibia.Misguided.Monsters, 0) + item:setSpecialAttribute("task", player:getGuid()) + end + if player:getStorageValue(Storage.CultsOfTibia.Misguided.Mission) == 2 then + player:setStorageValue(Storage.CultsOfTibia.Misguided.Mission, 3) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"The amulet burns your skin. \z + It hungers for energy right now, gather a large amount of energy as fast as possible to charge it. ") + end + end + addEvent(fallFloor, 10000, player:getId(), item:getId()) + return true +end + +beginTask:type("equip") +beginTask:id(28657, 28658) +beginTask:register() + +beginTask = MoveEvent() + +function beginTask.onDeEquip(player, item, slot, isCheck) + item:setAttribute(ITEM_ATTRIBUTE_DECAYSTATE, 0) + return true +end + +beginTask:type("deequip") +beginTask:id(28657, 28658) +beginTask:register() diff --git a/data/scripts/movements/quests/cults_of_tibia/boss_timer.lua b/data/scripts/movements/quests/cults_of_tibia/boss_timer.lua new file mode 100644 index 00000000000..51d64aea95e --- /dev/null +++ b/data/scripts/movements/quests/cults_of_tibia/boss_timer.lua @@ -0,0 +1,36 @@ +local setting = { + [5511] = {storage = Storage.CultsOfTibia.Minotaurs.BossTimer}, + [5513] = {storage = Storage.CultsOfTibia.Humans.BossTimer}, + [5514] = {storage = Storage.CultsOfTibia.Misguided.BossTimer}, + [5515] = {storage = Storage.CultsOfTibia.FinalBoss.BossTimer}, + [5516] = {storage = Storage.CultsOfTibia.Orcs.BossTimer}, + [5512] = {storage = Storage.CultsOfTibia.Barkless.BossTimer} + } + +local bossTimer = MoveEvent() + +function bossTimer.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local bossTimer = setting[item.actionid] + if bossTimer then + if player:getStorageValue(bossTimer.storage) > os.time() then + player:sendCancelMessage("You need to wait for 20 hours to face this boss again.") + player:teleportTo(fromPosition) + return false + end + end + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +bossTimer:type("stepin") + +for index, value in pairs(setting) do + bossTimer:aid(index) +end + +bossTimer:register() diff --git a/data/scripts/movements/quests/cults_of_tibia/check_oasis.lua b/data/scripts/movements/quests/cults_of_tibia/check_oasis.lua new file mode 100644 index 00000000000..2676a3a2011 --- /dev/null +++ b/data/scripts/movements/quests/cults_of_tibia/check_oasis.lua @@ -0,0 +1,19 @@ +local checkOasis = MoveEvent() + +function checkOasis.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.CultsOfTibia.Life.Mission) == 2 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + "You have found a lovely oasis with green fauna and juicy fruit. You didn't expect that.") + player:setStorageValue(Storage.CultsOfTibia.Life.Mission, 3) + end + return true +end + +checkOasis:type("stepin") +checkOasis:aid(5560) +checkOasis:register() diff --git a/data/scripts/movements/quests/cults_of_tibia/energy_fence.lua b/data/scripts/movements/quests/cults_of_tibia/energy_fence.lua new file mode 100644 index 00000000000..28df8a83600 --- /dev/null +++ b/data/scripts/movements/quests/cults_of_tibia/energy_fence.lua @@ -0,0 +1,67 @@ +local misguided = { + [1] = Position(32527, 32468, 10), + [2] = Position(32528, 32468, 10), + [3] = Position(32529, 32468, 10), + [4] = Position(32530, 32468, 10), + [5] = Position(32531, 32468, 10), + [6] = Position(32532, 32468, 10), + [7] = Position(32533, 32468, 10), + [8] = Position(32534, 32468, 10), + [9] = Position(32535, 32468, 10), + [10] = Position(32536, 32468, 10), + [11] = Position(32537, 32468, 10), + [12] = Position(32538, 32468, 10) +} + +local energyFence = MoveEvent() + +function energyFence.onStepIn(creature, item, position, fromPosition) + local firstCheck = Position(32350, 31657, 8) + local secondCheck = Position(32327, 31692, 9) + local misguidedFirst = Position(32527, 32468, 10) + + local player = creature:getPlayer() + if not player then + creature:teleportTo(fromPosition) + return false + end + + if position == firstCheck or position == Position(firstCheck.x + 1, firstCheck.y, firstCheck.z) or + position == Position(firstCheck.x + 2, firstCheck.y, firstCheck.z) then + if player:getStorageValue(Storage.CultsOfTibia.Humans.Vaporized) == 10 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + "With you being the vessel binding the power of whitered souls, you step through the magic barrier.") + player:getPosition():sendMagicEffect(CONST_ME_ENERGYHIT) + else + player:teleportTo(fromPosition, true) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"The combined powers of decaying souls \z + roaming these halls may help breach this barrier, it needs but a vessel to bind them.") + end + elseif position == secondCheck or position == Position(secondCheck.x + 1, secondCheck.y, secondCheck.z) then + if player:getStorageValue(Storage.CultsOfTibia.Humans.Decaying) == 10 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + "With you being the vessel binding the power of whitered souls, you step through the magic barrier.") + player:getPosition():sendMagicEffect(CONST_ME_ENERGYHIT) + else + player:teleportTo(fromPosition, true) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The combined powers of decaying souls \z + roaming these halls may help breach this barrier, it needs but a vessel to bind them.") + end + elseif misguided then + for i, position in pairs(misguided) do + if player:getStorageValue(Storage.CultsOfTibia.Misguided.Exorcisms) >= 5 then + player:getPosition():sendMagicEffect(CONST_ME_ENERGYHIT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "As you cross the threshold in to the inner \z + sanctuary of the cult of the Misguided, you feel an eerie presence all around you.") + break + else + player:teleportTo(fromPosition, true) + end + end + end + return true +end + +energyFence:type("stepin") +energyFence:aid(5581) +energyFence:register() diff --git a/data/scripts/movements/quests/cults_of_tibia/geyser.lua b/data/scripts/movements/quests/cults_of_tibia/geyser.lua new file mode 100644 index 00000000000..6e3baf80b1d --- /dev/null +++ b/data/scripts/movements/quests/cults_of_tibia/geyser.lua @@ -0,0 +1,49 @@ +local function bossTransformBack(creatureid, itemid) + local creature = Creature(creatureid) + if not creature then + return false + end + + local position = creature:getPosition() + if Tile(position):getItemCountById(itemid) > 0 then + addEvent(bossTransformBack, 4*1000, creature:getId(), itemid) + return false + end + + local bossTransformBack = Game.createMonster("the sinister hermit dirty", position, true, true) + local currentLife = creature:getHealth() + if bossTransformBack then + bossTransformBack:registerEvent("SpawnBoss") + creature:remove() + local subtract = bossTransformBack:getHealth() - currentLife + bossTransformBack:addHealth(-subtract) + end + return true +end + +local geyser = MoveEvent() + +function geyser.onStepIn(creature, item, position, fromPosition) + if not creature:isMonster() then + return true + end + + if creature:getType():getName():lower() == "the sinister hermit" and creature:getOutfit().lookBody == 63 then + local currentLife = creature:getHealth() + local bossTransform = Game.createMonster("the sinister hermit dirty", creature:getPosition(), true, true) + if bossTransform then + creature:remove() + item:remove() + local subtract = bossTransform:getHealth() - currentLife + bossTransform:addHealth(-subtract) + bossTransform:registerEvent("spawnBoss") + addEvent(bossTransformBack, 4*1000, bossTransform:getId(), item:getId()) + return false + end + end + return true +end + +geyser:type("stepin") +geyser:id(28869) +geyser:register() diff --git a/data/scripts/movements/quests/cults_of_tibia/ice.lua b/data/scripts/movements/quests/cults_of_tibia/ice.lua new file mode 100644 index 00000000000..77373c71732 --- /dev/null +++ b/data/scripts/movements/quests/cults_of_tibia/ice.lua @@ -0,0 +1,101 @@ +function sendConditionCults(playerid, info, fromPos, toPos, fromPos2, toPos2, time) + local player = Player(playerid) + if not player then + return false + end + + if ( not player:getPosition():isInRange(fromPos2, toPos2) ) then + if (not player:getPosition():isInRange(fromPos, toPos)) then + return true + end + end + + time = time + 2 + if time == 30 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, info.msgs[2]) + elseif time == 60 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, info.msgs[2]) + elseif time == 90 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, info.msgs[2]) + elseif time >= 120 then + local storage = player:getStorageValue(info.storageBarkless) < 0 and 0 or + player:getStorageValue(info.storageBarkless) + if storage < 3 and storage ~= 1 and storage ~= 2 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, info.msgs[3]) + player:setStorageValue(info.storageBarkless, 1) + end + end + player:getPosition():sendMagicEffect(info.effect) + addEvent(sendConditionCults, 2000, playerid, info, fromPos, toPos, fromPos2, toPos2, time) +end + +local function floorPassage(playerid, info, time) + local player = Player(playerid) + if not player then + return true + end + local storage = player:getStorageValue(info.storageBarkless) < 0 and 0 or + player:getStorageValue(info.storageBarkless) + if time == 0 and storage < 3 then + player:setStorageValue(info.storageBarkless, 0) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, info.msgs[6]) + return true + end + if storage == 3 then + return true + end + addEvent(floorPassage, 1000, playerid, info, time - 1) +end + +local ice = MoveEvent() + +function ice.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local setting = { + fromPos = Position(32677, 31393, 8), + toPos = Position(32722, 31440, 8), + fromPos2 = Position(32696, 31429, 8), + toPos2 = Position(32728, 31435, 8), + effect = CONST_ME_GIANTICE, + firstSqm = Position(32698, 31405, 8), + storageBarkless = Storage.CultsOfTibia.Barkless.Ice, + msgs = { + "As you enter the icy cavern, you feel an unnatural frostiness. \z + The ice cold air stings in your face. Survive and prove worthy.", -- on enter + "Your body temperature sinks. You can see your breath freezing in the cold.", -- 30/60 seconds + "The icy cold is grasping to you. You can barely move anymore.", -- 120 seconds + "You are now washed and ready to purify yourself in the chambers of purification.", -- step in the first tile + "You are now ready to prove your worth. Take heart and cross the threshold of ice.", -- step in the second tile + "You took so long. You are no longer purified.", -- there's no time to step + } + } + if fromPosition.y == 31441 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, setting.msgs[1]) + sendConditionCults(player:getId(), setting, setting.fromPos, + setting.toPos, setting.fromPos2, setting.toPos2, 0) + return true + end + + if item:getPosition():compare(setting.firstSqm) then + if player:getStorageValue(setting.storageBarkless) ~= 1 then + return true + end + player:setStorageValue(setting.storageBarkless, 2) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, setting.msgs[4]) + floorPassage(player:getId(), setting, 60) + return true + end + + if fromPosition.y == 31439 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "A bit of warmth returns to your body as you leave the icy cavern.") + return true + end + return true +end + +ice:type("stepin") +ice:aid(5532) +ice:register() diff --git a/data/scripts/movements/quests/cults_of_tibia/ice_death.lua b/data/scripts/movements/quests/cults_of_tibia/ice_death.lua new file mode 100644 index 00000000000..2c1cddeb3c3 --- /dev/null +++ b/data/scripts/movements/quests/cults_of_tibia/ice_death.lua @@ -0,0 +1,81 @@ +function Player.sendFakeDeathWindow(self) + -- consider migrating to ProtocolGame::sendDeath + local msg = NetworkMessage(); + msg:addByte(0x28); + msg:addByte(0x01); + msg:addByte(2); + msg:addByte(0x00); -- Use death redemption + msg:sendToPlayer(self, false); + return true +end + +local condition = Condition(CONDITION_OUTFIT) +condition:setTicks(-1) + +local conditions = { + CONDITION_POISON, + CONDITION_FIRE, + CONDITION_ENERGY, + CONDITION_BLEEDING, + CONDITION_HASTE, + CONDITION_PARALYZE, + CONDITION_INVISIBLE, + CONDITION_LIGHT, + CONDITION_MANASHIELD, + CONDITION_INFIGHT, + CONDITION_DRUNK, + CONDITION_SOUL, + CONDITION_DROWN, + CONDITION_YELLTICKS, + CONDITION_ATTRIBUTES, + CONDITION_FREEZING, + CONDITION_DAZZLED, + CONDITION_CURSED, + CONDITION_EXHAUST_COMBAT, + CONDITION_EXHAUST_HEAL, + CONDITION_SPELLCOOLDOWN, + CONDITION_SPELLGROUPCOOLDOWN +} + +local iceDeath = MoveEvent() + +function iceDeath.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + if player:getStorageValue(Storage.CultsOfTibia.Barkless.Ice) == 2 then + player:setStorageValue(Storage.CultsOfTibia.Barkless.Ice, 3) + player:setStorageValue(Storage.CultsOfTibia.Barkless.Death, 1) + for _, conditionType in pairs(conditions) do + if player:getCondition(conditionType) then + player:removeCondition(conditionType) + end + end + condition:setOutfit(player:getSex() == PLAYERSEX_FEMALE and 3065 or 3058) + player:addCondition(condition) + local it = Game.createItem(player:getSex() == PLAYERSEX_FEMALE and 3065 or 3058, 1, player:getPosition()) + if it then + it:decay() + end + player:addHealth((-player:getHealth() + 1)) + player:sendTextMessage(MESSAGE_BEYOND_LAST, "You were killed by something evil and others.") + -- TODO parse active blessings and show that you didn't lose any blessings + player:sendTextMessage(MESSAGE_BEYOND_LAST, + "You are still blessed with Wisdom of Solitude, Spark of the Phoenix,Fire of the Suns, \z + Spiritual Shielding, Embrace of Tibia, Heart of the Mountani, Blood of the Montain and Twist of Fate.") + player:sendTextMessage(MESSAGE_BEYOND_LAST, "You lost 0 experience and 0.00% of all of your skills.") + player:sendTextMessage(MESSAGE_BEYOND_LAST, "You did not lose any items.") + player:setStorageValue(Storage.CultsOfTibia.Barkless.Mission, 3) + player:setStorageValue(Storage.CultsOfTibia.Barkless.AccessDoor, 1) + player:sendTextMessage(MESSAGE_BEYOND_LAST, "The cold has all but disappeared from your body and you're getting warmer. You need to renew all preparations for purification.") + player:sendFakeDeathWindow() + else + player:teleportTo(fromPosition, true) + end + return true +end + +iceDeath:type("stepin") +iceDeath:aid(5533) +iceDeath:register() diff --git a/data/scripts/movements/quests/cults_of_tibia/looktype.lua b/data/scripts/movements/quests/cults_of_tibia/looktype.lua new file mode 100644 index 00000000000..13490faa348 --- /dev/null +++ b/data/scripts/movements/quests/cults_of_tibia/looktype.lua @@ -0,0 +1,54 @@ + +local looktype = MoveEvent() + +function looktype.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local firstCheck = Position(33135, 31859, 10) + local secondCheck = Position(33128, 31885, 11) + local thirdCheck = Position(33175, 31923, 12) + if position == firstCheck or position == Position(firstCheck.x + 1, firstCheck.y, firstCheck.z) then + if player:getStorageValue(Storage.CultsOfTibia.Orcs.LookType) < 1 then + if creature:getOutfit().lookType == 5 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Due to the strength of an orc you are able to pass this rift.") + player:setStorageValue(Storage.CultsOfTibia.Orcs.LookType, 1) + else + player:teleportTo(fromPosition, true) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need the strength of an orc to pass this rift.") + end + end + end + if position == secondCheck or position == Position(secondCheck.x + 1, secondCheck.y, secondCheck.z) then + if player:getStorageValue(Storage.CultsOfTibia.Orcs.LookType) < 2 then + if creature:getOutfit().lookType == 2 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + "With the help off the might of an orc warlod you are able to pass this rift.") + player:setStorageValue(Storage.CultsOfTibia.Orcs.LookType, 2) + else + player:teleportTo(fromPosition, true) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need the might of an orc warlod to pass this rift.") + end + end + end + if position == thirdCheck or position == Position(thirdCheck.x + 1, thirdCheck.y, thirdCheck.z) or + position == Position(thirdCheck.x + 2, thirdCheck.y, thirdCheck.z) then + if player:getStorageValue(Storage.CultsOfTibia.Orcs.LookType) < 3 then + if creature:getOutfit().lookType == 6 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + "With the help of the wisdom of an orc shaman you are able to pass this rift.") + player:setStorageValue(Storage.CultsOfTibia.Orcs.LookType, 3) + else + player:teleportTo(fromPosition, true) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need the wisdom of an orc shaman to pass this rift.") + end + end + end + return true +end + +looktype:type("stepin") +looktype:aid(5540) +looktype:register() diff --git a/data/scripts/movements/quests/cults_of_tibia/orc_teleport.lua b/data/scripts/movements/quests/cults_of_tibia/orc_teleport.lua new file mode 100644 index 00000000000..e2d84b5a3eb --- /dev/null +++ b/data/scripts/movements/quests/cults_of_tibia/orc_teleport.lua @@ -0,0 +1,21 @@ +local orcTeleport = MoveEvent() + +function orcTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if item:getPosition() == Position(33167, 31930, 12) then + player:teleportTo(Position(33182, 31837, 15)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + elseif item:getPosition() == Position(33183, 31837, 15) then + player:teleportTo(Position(33168, 31930, 12)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +orcTeleport:type("stepin") +orcTeleport:id(11798) +orcTeleport:register() diff --git a/data/scripts/movements/quests/cults_of_tibia/river_teleport.lua b/data/scripts/movements/quests/cults_of_tibia/river_teleport.lua new file mode 100644 index 00000000000..76ae68726e7 --- /dev/null +++ b/data/scripts/movements/quests/cults_of_tibia/river_teleport.lua @@ -0,0 +1,29 @@ +local riverTeleport = MoveEvent() + +function riverTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if (player:getStorageValue(player:getStorageValue(Storage.CultsOfTibia.Life.BossTimer)) > os.time()) then + player:sendCancelMessage('You need to wait for 20 hours to face this boss again.') + player:teleportTo(fromPosition) + return false + end + + if player:getStorageValue(Storage.CultsOfTibia.Life.Mission) < 7 then + player:teleportTo(Position(33474, 32281, 10)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + + if player:getStorageValue(Storage.CultsOfTibia.Life.Mission) >= 7 then + player:teleportTo(Position(33479, 32235, 10)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +riverTeleport:type("stepin") +riverTeleport:aid(5517) +riverTeleport:register() diff --git a/data/scripts/movements/quests/cults_of_tibia/sand_entrance.lua b/data/scripts/movements/quests/cults_of_tibia/sand_entrance.lua new file mode 100644 index 00000000000..c5d5be48313 --- /dev/null +++ b/data/scripts/movements/quests/cults_of_tibia/sand_entrance.lua @@ -0,0 +1,19 @@ +local sandEntrance = MoveEvent() + +function sandEntrance.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if (player:getStorageValue(Storage.CultsOfTibia.Life.Mission) < 1 and + player:getStorageValue(Storage.CultsOfTibia.MotA.Mission)) < 1 then + player:teleportTo(fromPosition, true) + player:sendCancelMessage("You can't go there yet.") + end + return true +end + +sandEntrance:type("stepin") +sandEntrance:aid(4999) +sandEntrance:register() diff --git a/data/scripts/movements/quests/cults_of_tibia/sandking.lua b/data/scripts/movements/quests/cults_of_tibia/sandking.lua new file mode 100644 index 00000000000..919e39b0844 --- /dev/null +++ b/data/scripts/movements/quests/cults_of_tibia/sandking.lua @@ -0,0 +1,17 @@ +local sandking = MoveEvent() + +function sandking.onStepIn(creature, item, position, fromPosition) + if not creature:isMonster() then + return true + end + + if creature:getName():lower() == "the sandking" then + item:remove() + creature:addHealth(math.random(100, 1000)) + end + return true +end + +sandking:type("stepin") +sandking:aid(5595) +sandking:register() diff --git a/data/scripts/movements/quests/cults_of_tibia/tar.lua b/data/scripts/movements/quests/cults_of_tibia/tar.lua new file mode 100644 index 00000000000..2f9d38fcf1f --- /dev/null +++ b/data/scripts/movements/quests/cults_of_tibia/tar.lua @@ -0,0 +1,162 @@ +local configQuest = { + ["fire"] = { + itidCount = 3613, + beginPos = Position(32748, 31488, 8), + fromPos = Position(32737, 31489, 8), + toPos = Position(32761, 31512, 8), + effect = CONST_ME_HITBYFIRE, + firstSqm = Position(32750, 31508, 8), + secondSqm = Position(32746, 31469, 8), + storageBarkless = Storage.CultsOfTibia.Barkless.Tar, + msgs = { + "As you enter the tar pits, you feel the heat around you rising dramatically. \z + Survive the heat long enough to prove worthy.", -- on enter + "Your body is heating up, the air around you is flickering.", -- 30/60 seconds + "The heat is now unbearable, the blood in your body feels like lava. \z + There's almost no strength left in you - act quickly!", -- 90 segunds + "Embrace the stigma of bad fortune. The tar does not feel so hot anymore. \z + You passed the tar trial.", -- step in the first tile + "Your body reacts to this strange green substance as you reach out to touch it. \z + You feel an urge for more of this energy.", -- step in the second tile + "The tar covering you has cooled down and tell off for the most part. \z + Your body is not heated up anymore.", -- there's no time to step + } + }, + ["acid"] = { + itidCount = 4417, + beginPos = Position(32693, 31478, 8), + fromPos = Position(32647, 31479, 8), + toPos = Position(32710, 31519, 8), + effect = CONST_ME_YELLOW_RINGS, + firstSqm = Position(32680, 31485, 8), + secondSqm = Position(32664, 31504, 8), + storageBarkless = Storage.CultsOfTibia.Barkless.sulphur, + msgs = { + "As you enter the sulphur pits, you feel the dry, burning vapours of the sulphur all around you. Prove worthy, survive the acid.", -- on enter + "The sulphur is burning your skin. You almost feel your body melting away in acid.", -- 30/60 segunds + "The acid burning is now unbearable, you skin feels like a sieve. \z + ]There's almost no strength left in you - act quickly!", -- 90 segunds + "Embrace the stigma of vanity. The sulphur does not burn your skin anymore. \z + You passed the trial.", -- step in the first tile + "You are now ready to prove your worth. \z + Take heart and cross the threshold of sulphur.", -- step in the second tile + "The acid covering you has cooled down and tell off for the most part. \z + Your body is not heated up anymore.", -- there's no time to step + } + }, +} + +function sendConditionCults(playerid, _type, fromPos, toPos, tempo) + local player = Player(playerid) + if not player or not player:getPosition():isInRange(fromPos, toPos) then + return false + end + + local inf = configQuest[_type] + tempo = tempo + 2 + if tempo == 30 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, inf.msgs[2]) + elseif tempo == 60 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, inf.msgs[2]) + elseif tempo >= 90 then + local stg = player:getStorageValue(inf.storageBarkless) < 0 and 0 or player:getStorageValue(inf.storageBarkless) + if stg < 3 and stg ~= 1 and stg ~= 2 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, inf.msgs[3]) + player:setStorageValue(inf.storageBarkless, 1) + end + end + player:getPosition():sendMagicEffect(inf.effect) + addEvent(sendConditionCults, 2000, playerid, _type, fromPos, toPos, tempo) +end + +function passagemPiso1Piso2(playerid, info, tempo) + local player = Player(playerid) + if not player then + return true + end + local stg = player:getStorageValue(info.storageBarkless) < 0 and 0 or player:getStorageValue(info.storageBarkless) + if tempo == 0 and stg < 3 then + player:setStorageValue(info.storageBarkless, 0) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, info.msgs[6]) + return true + end + if stg == 3 then + return true + end + addEvent(passagemPiso1Piso2, 1000, playerid, info, tempo - 1) +end + +local tar = MoveEvent() + +function tar.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + for index, value in pairs(configQuest)do + if item:getId() == value.itidCount and fromPosition:compare(value.beginPos) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, value.msgs[1]) + sendConditionCults(player:getId(), index, value.fromPos, value.toPos, 0) + return true + elseif position:compare(value.firstSqm) and player:getStorageValue(value.storageBarkless) == 1 then + if player:getStorageValue(value.storageBarkless) ~= 1 then + return true + end + player:setStorageValue(value.storageBarkless, 2) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, value.msgs[4]) + passagemPiso1Piso2(player:getId(), value, 60) + elseif position:compare(value.secondSqm) then + if player:getStorageValue(value.storageBarkless) == 2 then + player:setStorageValue(value.storageBarkless, 3) + if player:getStorageValue(Storage.CultsOfTibia.Barkless.sulphur) == 3 and + player:getStorageValue(Storage.CultsOfTibia.Barkless.Tar) == 3 then + player:setStorageValue(Storage.CultsOfTibia.Barkless.Mission, 2) + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, value.msgs[5]) + end + end + end + return true +end + +tar:type("stepin") +tar:aid(5530, 5531) +tar:register() + +tar = MoveEvent() + +function tar.onStepOut(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if item:getActionId() == 5531 then + if fromPosition.x == 32736 then + player:getPosition():sendMagicEffect(CONST_ME_POFF) + if player:getStorageValue(Storage.CultsOfTibia.Barkless.Tar) < 3 then + player:teleportTo(Position(32737, 31451, 8), true) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are not ready yet.") + return false + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You traverse the tar unharmed.") + end + end + if item:getActionId() == 5530 then + if fromPosition.x == 32717 then + player:getPosition():sendMagicEffect(CONST_ME_POFF) + if player:getStorageValue(Storage.CultsOfTibia.Barkless.sulphur) < 3 then + player:teleportTo(Position(32718, 31444, 8), true) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are not ready yet.") + return false + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You traverse the sulphur unharmed.") + end + end + return true +end + +tar:type("stepout") +tar:aid(5530, 5531) +tar:register() diff --git a/data/scripts/movements/quests/cults_of_tibia/task_teleport.lua b/data/scripts/movements/quests/cults_of_tibia/task_teleport.lua new file mode 100644 index 00000000000..6a62529ab2f --- /dev/null +++ b/data/scripts/movements/quests/cults_of_tibia/task_teleport.lua @@ -0,0 +1,54 @@ +local setting = { + [26138] = { + storage = Storage.CultsOfTibia.Humans.Decaying, + max = 10, + id = 26138, + text = "You absorb the energetic remains of this decaying soul. Its power is very fragile and fleeting" + }, + [26140] = { + storage = Storage.CultsOfTibia.Humans.Vaporized, + max = 10, + id = 26140, + text = "You absorb the energetic remains of this whitering soul. Its power is very fragile and fleeting." + } +} + +local taskTeleport = MoveEvent() + +function taskTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.CultsOfTibia.Questline) < 1 then + player:setStorageValue(Storage.CultsOfTibia.Questline, 1) + end + if player:getStorageValue(Storage.CultsOfTibia.Humans.Mission) < 1 then + player:setStorageValue(Storage.CultsOfTibia.Humans.Mission, 1) + end + + for index, value in pairs(setting) do + local teleport = Tile(position):getItemById(index) + if teleport then + local storage = (player:getStorageValue(value.storage) < 0 and 0 or player:getStorageValue(value.storage)) + local attribute = teleport:getSpecialAttribute("task") or '' + if attribute:find(player:getName()) or storage >= value.max then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + "The power of these souls is now within you. You cannot absorb any more souls.") + return false + end + attribute = string.format("%s, %s", attribute, player:getName()) + teleport:setSpecialAttribute("task", attribute) + player:setStorageValue(value.storage, storage + 1) + player:getPosition():sendMagicEffect(CONST_ME_ENERGYHIT) + teleport:remove() + player:say(value.text, TALKTYPE_MONSTER_SAY) + end + end + return true +end + +taskTeleport:type("stepin") +taskTeleport:aid(5580) +taskTeleport:register() diff --git a/data/scripts/movements/quests/dangerous_depth/boss_entrance.lua b/data/scripts/movements/quests/dangerous_depth/boss_entrance.lua new file mode 100644 index 00000000000..2dbeb0c8a7a --- /dev/null +++ b/data/scripts/movements/quests/dangerous_depth/boss_entrance.lua @@ -0,0 +1,50 @@ +local bossEntrance = MoveEvent() + +function bossEntrance.onStepIn(creature, item, position, fromPosition, toPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local WarzoneIV = Position(33460, 32267, 15) + local WarzoneIV_b = Position(33650, 32310, 15) + + local WarzoneV = Position(33324, 32109, 15) + local WarzoneV_b = Position(33681, 32338, 15) + + local WarzoneVI = Position(33275, 32316, 15) + local WarzoneVI_b = Position(33717, 32302, 15) + + if item:getPosition() == WarzoneIV then -- Warzone IV + if player:getStorageValue(Storage.DangerousDepths.Bosses.TheBaronFromBelow) > os.time() then + player:teleportTo(fromPosition) + player:say('You have to wait to challenge this enemy again!', TALKTYPE_MONSTER_SAY) + else + player:teleportTo(WarzoneIV_b) + end + end + + if item:getPosition() == WarzoneV then -- Warzone V + if player:getStorageValue(Storage.DangerousDepths.Bosses.TheCountOfTheCore) > os.time() then + player:teleportTo(fromPosition) + player:say('You have to wait to challenge this enemy again!', TALKTYPE_MONSTER_SAY) + else + player:teleportTo(WarzoneV_b) + end + end + + if item:getPosition() == WarzoneVI then -- Warzone VI + if player:getStorageValue(Storage.DangerousDepths.Bosses.TheDukeOfTheDepths) > os.time() then + player:teleportTo(fromPosition) + player:say('You have to wait to challenge this enemy again!', TALKTYPE_MONSTER_SAY) + else + player:teleportTo(WarzoneVI_b) + end + end + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +bossEntrance:type("stepin") +bossEntrance:aid(57243) +bossEntrance:register() diff --git a/data/scripts/movements/quests/dangerous_depth/energy_entrance.lua b/data/scripts/movements/quests/dangerous_depth/energy_entrance.lua new file mode 100644 index 00000000000..e2cef6430d2 --- /dev/null +++ b/data/scripts/movements/quests/dangerous_depth/energy_entrance.lua @@ -0,0 +1,46 @@ +local energyEntrance = MoveEvent() + +function energyEntrance.onStepIn(creature, item, position, fromPosition, toPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if item:getPosition() == Position(33831, 32138, 14) then + if player:getStorageValue(Storage.DangerousDepths.Scouts.Status) >= 10 then + player:teleportTo(Position(34023, 32037, 14)) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You can not use this portal yet.") + player:teleportTo(Position(fromPosition.x, fromPosition.y + 1, fromPosition.z)) + end + elseif item:getPosition() == Position(34021, 32037, 14) then + end + + if item:getPosition() == Position(33784, 32205, 14) then + if player:getStorageValue(Storage.DangerousDepths.Dwarves.Status) >= 10 then + player:teleportTo(Position(33921, 32401, 14)) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You can not use this portal yet.") + player:teleportTo(Position(fromPosition.x - 1, fromPosition.y, fromPosition.z)) + end + elseif item:getPosition() == Position(33921, 32402, 14) then + player:teleportTo(Position(33782, 32205, 14)) + end + + if item:getPosition() == Position(33829, 32187, 14) then + if player:getStorageValue(Storage.DangerousDepths.Gnomes.Status) >= 10 then + player:teleportTo(Position(33982, 32236, 14)) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You can not use this portal yet.") + player:teleportTo(Position(fromPosition.x, fromPosition.y - 1, fromPosition.z)) + end + elseif item:getPosition() == Position(33982, 32234, 14) then + player:teleportTo(Position(33829, 32186, 14)) + end + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +energyEntrance:type("stepin") +energyEntrance:aid(57232) +energyEntrance:register() diff --git a/data/scripts/movements/quests/dangerous_depth/gnome_avalanche.lua b/data/scripts/movements/quests/dangerous_depth/gnome_avalanche.lua new file mode 100644 index 00000000000..0decfe65ac7 --- /dev/null +++ b/data/scripts/movements/quests/dangerous_depth/gnome_avalanche.lua @@ -0,0 +1,46 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_STONES) +combat:setArea(createCombatArea(AREA_CIRCLE6X6)) + +function spellCallback(param) + local tile = Tile(Position(param.pos)) + if tile then + if tile:getTopCreature() then + tile:getTopCreature():addHealth( - math.random(1000, 1500)) + end + end +end + +function onTargetTile(cid, pos) + local param = {} + param.cid = cid + param.pos = pos + param.count = 0 + spellCallback(param) +end + +setCombatCallback(combat, CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +local gnomeAvalanche = MoveEvent() + +function gnomeAvalanche.onStepIn(creature, position, fromPosition, toPosition) + if not creature or not creature:isMonster() then + return true + end + + local monsterName = creature:getName():lower() + local var = {type = 1, number = creature:getId()} + local r = math.random(1, 100) + + if monsterName == "lost gnome" then + if r <= 25 then + combat:execute(creature, var) + end + end + return true +end + +gnomeAvalanche:type("stepin") +gnomeAvalanche:aid(57240) +gnomeAvalanche:register() diff --git a/data/scripts/movements/quests/dangerous_depth/gnome_ordnance.lua b/data/scripts/movements/quests/dangerous_depth/gnome_ordnance.lua new file mode 100644 index 00000000000..c74f3db575c --- /dev/null +++ b/data/scripts/movements/quests/dangerous_depth/gnome_ordnance.lua @@ -0,0 +1,18 @@ +local gnomeOrdnance = MoveEvent() + +function gnomeOrdnance.onStepIn(creature, position, fromPosition, toPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.DangerousDepths.Gnomes.Ordnance) == 1 then + player:setStorageValue(Storage.DangerousDepths.Gnomes.Ordnance, 2) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You started an escort, get everyone to safety!") + end + return true +end + +gnomeOrdnance:type("stepin") +gnomeOrdnance:aid(57241) +gnomeOrdnance:register() diff --git a/data/scripts/movements/quests/dangerous_depth/gnomes_ordnance_end.lua b/data/scripts/movements/quests/dangerous_depth/gnomes_ordnance_end.lua new file mode 100644 index 00000000000..3bb8c2f8c9e --- /dev/null +++ b/data/scripts/movements/quests/dangerous_depth/gnomes_ordnance_end.lua @@ -0,0 +1,65 @@ +local gnomesOrdnanceEnd = MoveEvent() + +function gnomesOrdnanceEnd.onStepIn(creature, position, fromPosition, toPosition) + if not creature or not creature:isMonster() then + return true + end + + local pos = creature:getPosition() + local fromPos = Position(pos.x - 5, pos.y - 5, pos.z) + local toPos = Position(pos.x + 5, pos.y + 5, pos.z) + if creature and creature:getName():lower() == "lost gnome" then + for x = fromPos.x, toPos.x do + for y = fromPos.y, toPos.y do + for z = fromPos.z, toPos.z do + if Tile(Position(x, y, z)) then + if Tile(Position(x, y, z)) then + local c = Tile(Position(x, y, z)):getTopCreature() + if c then + if c:isPlayer() then + if c:getStorageValue(Storage.DangerousDepths.Gnomes.Ordnance) == 2 then + if c:getStorageValue(Storage.DangerousDepths.Gnomes.GnomesCount) < 5 then + c:setStorageValue(Storage.DangerousDepths.Gnomes.GnomesCount, c:getStorageValue(Storage.DangerousDepths.Gnomes.GnomesCount) + 1) + c:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your escort has end.") + end + end + end + end + end + end + end + end + end + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + creature:remove() + elseif creature and creature:getName():lower() == "gnome pack crawler" then + for x = fromPos.x, toPos.x do + for y = fromPos.y, toPos.y do + for z = fromPos.z, toPos.z do + if Tile(Position(x, y, z)) then + if Tile(Position(x, y, z)) then + local c = Tile(Position(x, y, z)):getTopCreature() + if c then + if c:isPlayer() then + if c:getStorageValue(Storage.DangerousDepths.Gnomes.Ordnance) == 2 then + if c:getStorageValue(Storage.DangerousDepths.Gnomes.CrawlersCount) < 3 then + c:setStorageValue(Storage.DangerousDepths.Gnomes.CrawlersCount, c:getStorageValue(Storage.DangerousDepths.Gnomes.CrawlersCount) + 1) + c:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your escort has end.") + end + end + end + end + end + end + end + end + end + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + creature:remove() + end + return true +end + +gnomesOrdnanceEnd:type("stepin") +gnomesOrdnanceEnd:aid(57242) +gnomesOrdnanceEnd:register() diff --git a/data/scripts/movements/quests/dangerous_depth/lava_damage.lua b/data/scripts/movements/quests/dangerous_depth/lava_damage.lua new file mode 100644 index 00000000000..20b20e80551 --- /dev/null +++ b/data/scripts/movements/quests/dangerous_depth/lava_damage.lua @@ -0,0 +1,12 @@ +local lavaDamage = MoveEvent() + +function lavaDamage.onStepIn(creature, position, fromPosition, toPosition) + if creature and (creature:isPlayer() or creature:getMaster()) then + doTargetCombatHealth(0, creature, COMBAT_FIREDAMAGE, -500, -500, CONST_ME_HITBYFIRE) + end + return true +end + +lavaDamage:type("stepin") +lavaDamage:id(25331) +lavaDamage:register() diff --git a/data/scripts/movements/quests/dangerous_depth/lost_exiles.lua b/data/scripts/movements/quests/dangerous_depth/lost_exiles.lua new file mode 100644 index 00000000000..2c53dbaba75 --- /dev/null +++ b/data/scripts/movements/quests/dangerous_depth/lost_exiles.lua @@ -0,0 +1,41 @@ +local lostExiles = MoveEvent() + +function lostExiles.onStepIn(creature, position, fromPosition, toPosition) + if not creature or not creature:isMonster() then + return true + end + + local pos = creature:getPosition() + local fromPos = Position(pos.x - 5, pos.y - 5, pos.z) + local toPos = Position(pos.x + 5, pos.y + 5, pos.z) + if creature:getName():lower() == "captured dwarf" then + for x = fromPos.x, toPos.x do + for y = fromPos.y, toPos.y do + for z = fromPos.z, toPos.z do + if Tile(Position(x, y, z)) then + if Tile(Position(x, y, z)) then + local creature = Tile(Position(x, y, z)):getTopCreature() + if creature then + if creature:isPlayer() then + if creature:getStorageValue(Storage.DangerousDepths.Dwarves.Home) == 1 then + if creature:getStorageValue(Storage.DangerousDepths.Dwarves.Prisoners) < 3 then + creature:setStorageValue(Storage.DangerousDepths.Dwarves.Prisoners, creature:getStorageValue(Storage.DangerousDepths.Dwarves.Prisoners) + 1) + creature:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your escort has end.") + end + end + end + end + end + end + end + end + end + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + creature:remove() + end + return true +end + +lostExiles:type("stepin") +lostExiles:aid(57231) +lostExiles:register() diff --git a/data/scripts/movements/quests/dangerous_depth/warzone_entrance.lua b/data/scripts/movements/quests/dangerous_depth/warzone_entrance.lua new file mode 100644 index 00000000000..9a5569c5042 --- /dev/null +++ b/data/scripts/movements/quests/dangerous_depth/warzone_entrance.lua @@ -0,0 +1,74 @@ +local warzoneEntrance = MoveEvent() + +function warzoneEntrance.onStepIn(creature, item, position, fromPosition, toPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local warzoneVI = Position(33367, 32307, 15) + if item:getPosition() == Position(33829, 32128, 14) then + if player:getStorageValue(Storage.DangerousDepths.Access.LavaPumpWarzoneVI) == 1 and + player:getStorageValue(Storage.DangerousDepths.Access.TimerWarzoneVI) <= os.time() then + player:setStorageValue(Storage.DangerousDepths.Access.LavaPumpWarzoneVI, 0) + player:setStorageValue(Storage.DangerousDepths.Scouts.Status, + player:getStorageValue(Storage.DangerousDepths.Scouts.Status) - 10) + player:setStorageValue(Storage.DangerousDepths.Access.TimerWarzoneVI, os.time() + 8*60*60) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Entering the warzone (you can enter freely for 8 hours from now).") + player:teleportTo(warzoneVI) + elseif player:getStorageValue(Storage.DangerousDepths.Access.LavaPumpWarzoneVI) < 1 and + player:getStorageValue(Storage.DangerousDepths.Access.TimerWarzoneVI) <= os.time() then + player:teleportTo(Position(fromPosition.x + 1, fromPosition.y, fromPosition.z)) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You cannot enter this warzone. \z + The enemy still pumps lava into this area. Find a way to stop the pumps!") + elseif player:getStorageValue(Storage.DangerousDepths.Access.TimerWarzoneVI) > os.time() then + player:teleportTo(warzoneVI) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Entering the warzone.") + end + end + local warzoneV = Position(33208, 32119, 15) + if item:getPosition() == Position(33777, 32192, 14) then + if player:getStorageValue(Storage.DangerousDepths.Access.LavaPumpWarzoneV) == 1 and + player:getStorageValue(Storage.DangerousDepths.Access.TimerWarzoneV) <= os.time() then + player:setStorageValue(Storage.DangerousDepths.Access.LavaPumpWarzoneV, 0) + player:setStorageValue(Storage.DangerousDepths.Dwarves.Status, + player:getStorageValue(Storage.DangerousDepths.Dwarves.Status) - 10) + player:setStorageValue(Storage.DangerousDepths.Access.TimerWarzoneV, os.time() + 8*60*60) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Entering the warzone (you can enter freely for 8 hours from now).") + player:teleportTo(warzoneV) + elseif player:getStorageValue(Storage.DangerousDepths.Access.LavaPumpWarzoneV) < 1 and + player:getStorageValue(Storage.DangerousDepths.Access.TimerWarzoneV) <= os.time() then + player:teleportTo(Position(fromPosition.x, fromPosition.y + 1, fromPosition.z)) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You cannot enter this warzone. \z + The enemy still pumps lava into this area. Find a way to stop the pumps!") + elseif player:getStorageValue(Storage.DangerousDepths.Access.TimerWarzoneV) > os.time() then + player:teleportTo(warzoneV) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Entering the warzone.") + end + end + local warzoneIV = Position(33534, 32184, 15) + if item:getPosition() == Position(33827, 32172, 14) then + if player:getStorageValue(Storage.DangerousDepths.Access.LavaPumpWarzoneIV) == 1 and + player:getStorageValue(Storage.DangerousDepths.Access.TimerWarzoneIV) <= os.time() then + player:setStorageValue(Storage.DangerousDepths.Access.LavaPumpWarzoneIV, 0) + player:setStorageValue(Storage.DangerousDepths.Gnomes.Status, + player:getStorageValue(Storage.DangerousDepths.Gnomes.Status) - 10) + player:setStorageValue(Storage.DangerousDepths.Access.TimerWarzoneIV, os.time() + 8*60*60) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Entering the warzone (you can enter freely for 8 hours from now).") + player:teleportTo(warzoneIV) + elseif player:getStorageValue(Storage.DangerousDepths.Access.LavaPumpWarzoneIV) < 1 and player:getStorageValue(Storage.DangerousDepths.Access.TimerWarzoneIV) <= os.time() then + player:teleportTo(Position(fromPosition.x, fromPosition.y + 1, fromPosition.z)) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You cannot enter this warzone. \z + The enemy still pumps lava into this area. Find a way to stop the pumps!") + elseif player:getStorageValue(Storage.DangerousDepths.Access.TimerWarzoneIV) > os.time() then + player:teleportTo(warzoneIV) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Entering the warzone.") + end + end + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +warzoneEntrance:type("stepin") +warzoneEntrance:aid(57230) +warzoneEntrance:register() diff --git a/data/scripts/movements/quests/dark_trails/necrometer_tile_access.lua b/data/scripts/movements/quests/dark_trails/necrometer_tile_access.lua new file mode 100644 index 00000000000..874148c4301 --- /dev/null +++ b/data/scripts/movements/quests/dark_trails/necrometer_tile_access.lua @@ -0,0 +1,20 @@ +local necrometerTileAccess = MoveEvent() + +function necrometerTileAccess.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return false + end + + if player:getStorageValue(Storage.DarkTrails.Mission04) == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "A strange ritual has taken place here. Report about it to the Gloot Brothers.") + player:setStorageValue(Storage.DarkTrails.Mission05, 1) -- Start mission 5 + elseif player:getStorageValue(Storage.DarkTrails.Mission10) >= 1 and player:getItemCount(23495) > 0 then + player:teleportTo({x = 33419, y = 32106, z = 10}) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The necrometer reveals a hidden passage!") + end + return true +end + +necrometerTileAccess:aid(25001) +necrometerTileAccess:register() diff --git a/data/scripts/movements/quests/dawnport/legion_helmet.lua b/data/scripts/movements/quests/dawnport/legion_helmet.lua new file mode 100644 index 00000000000..a6dea61d6d2 --- /dev/null +++ b/data/scripts/movements/quests/dawnport/legion_helmet.lua @@ -0,0 +1,21 @@ +local sacrificeTeleport = MoveEvent() + +function sacrificeTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.Quest.SanctuaryOfTheLizardGod.LizardGodTeleport) == 1 then + player:teleportTo({x = 32124, y = 31938, z = 8}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:teleportTo(fromPosition, true) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Offer the lives of the yet unborn to the lizard god if you want to enter the sanctuary.") + end + return true +end + +sacrificeTeleport:uid(35010) +sacrificeTeleport:register() diff --git a/data/scripts/movements/quests/deeplings_worldchange/deepling_bosses.lua b/data/scripts/movements/quests/deeplings_worldchange/deepling_bosses.lua new file mode 100644 index 00000000000..8a2740b04cc --- /dev/null +++ b/data/scripts/movements/quests/deeplings_worldchange/deepling_bosses.lua @@ -0,0 +1,31 @@ +local config = { + [28574] = {storage = Storage.DeeplingsWorldChange.Crystal, value = 13, position = Position(33641, 31236, 11)}, + [28575] = {storage = Storage.DeeplingsWorldChange.Crystal, value = 13, position = Position(33421, 31255, 11)}, + [28576] = {storage = Storage.DeeplingsWorldChange.Crystal, value = 13, position = Position(33543, 31263, 11)} +} + +local deeplingBosses = MoveEvent() + +function deeplingBosses.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local setting = config[item.uid] + if player:getStorageValue(setting.storage) == setting.value then + player:teleportTo(setting.position) + player:getPosition():sendMagicEffect(CONST_ME_WATERSPLASH) + return true + else + player:teleportTo(fromPosition, true) + player:getPosition():sendMagicEffect(CONST_ME_WATERSPLASH) + return true + end +end + +for index, value in pairs(config) do + deeplingBosses:uid(index) +end + +deeplingBosses:register() diff --git a/data/scripts/movements/quests/demon_oak/area_damage.lua b/data/scripts/movements/quests/demon_oak/area_damage.lua new file mode 100644 index 00000000000..f6c4e2f0358 --- /dev/null +++ b/data/scripts/movements/quests/demon_oak/area_damage.lua @@ -0,0 +1,17 @@ +local areaDamage = MoveEvent() + +function areaDamage.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if math.random(24) == 1 then + doTargetCombatHealth(0, player, COMBAT_EARTHDAMAGE, -270, -310, CONST_ME_BIGPLANTS) + end + return true +end + +areaDamage:type("stepin") +areaDamage:id(8292) +areaDamage:register() diff --git a/data/scripts/movements/quests/demon_oak/entrance.lua b/data/scripts/movements/quests/demon_oak/entrance.lua new file mode 100644 index 00000000000..1de18df26f4 --- /dev/null +++ b/data/scripts/movements/quests/demon_oak/entrance.lua @@ -0,0 +1,52 @@ +local entrance = MoveEvent() + +function entrance.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.DemonOak.Done) >= 1 then + player:teleportTo(DEMON_OAK_KICK_POSITION) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + if player:getLevel() < 120 then + player:say("LEAVE LITTLE FISH, YOU ARE NOT WORTH IT!", TALKTYPE_MONSTER_YELL, false, player, DEMON_OAK_POSITION) + player:teleportTo(DEMON_OAK_KICK_POSITION) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + if (#Game.getSpectators(DEMON_OAK_POSITION, false, true, 9, 9, 6, 6) == 0) then + if (player:getItemCount(10305) == 0) then + if player:getStorageValue(Storage.DemonOak.Progress) < 1 then + player:say("You need finish the demons task!", TALKTYPE_MONSTER_YELL, false, player, DEMON_OAK_KICK_POSITION) + player:teleportTo(DEMON_OAK_KICK_POSITION) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + end + + if (player:getItemCount(8293) == 0) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + "Go talk with Odralk and get the Hallowed Axe to kill The Demon Oak.") + end + + player:removeItem(10305, 1) + player:teleportTo(DEMON_OAK_ENTER_POSITION) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:setStorageValue(Storage.DemonOak.Progress, 1) + player:say("I AWAITED YOU! COME HERE AND GET YOUR REWARD!", + TALKTYPE_MONSTER_YELL, false, player, DEMON_OAK_POSITION) + else + player:teleportTo(DEMON_OAK_KICK_POSITION) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +entrance:type("stepin") +entrance:uid(9000) +entrance:register() diff --git a/data/scripts/movements/quests/demon_oak/squares.lua b/data/scripts/movements/quests/demon_oak/squares.lua new file mode 100644 index 00000000000..8657e4e13bb --- /dev/null +++ b/data/scripts/movements/quests/demon_oak/squares.lua @@ -0,0 +1,30 @@ +local voices = { + "Release me and you will be rewarded greatefully!", + "What is this? Demon Legs lying here? Someone might have lost them!", + "I'm trapped, come here and free me fast!!", + "I can bring your beloved back from the dead, just release me!", + "What a nice shiny golden armor. Come to me and you can have it!", + "Find a way in here and release me! Pleeeease hurry!", + "You can have my demon set, if you help me get out of here!" +} + +local squares = MoveEvent() + +function squares.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local status = math.max(player:getStorageValue(Storage.DemonOak.Squares), 0) + local startUid = 9000 + if item.uid - startUid == status + 1 then + player:setStorageValue(Storage.DemonOak.Squares, status + 1) + player:say(voices[math.random(#voices)], TALKTYPE_MONSTER_YELL, false, player, DEMON_OAK_POSITION) + end + return true +end + +squares:type("stepin") +squares:uid(9001, 9002, 9003, 9004, 9005) +squares:register() diff --git a/data/scripts/movements/quests/devil_helmet/sewer.lua b/data/scripts/movements/quests/devil_helmet/sewer.lua new file mode 100644 index 00000000000..ad4f46157ad --- /dev/null +++ b/data/scripts/movements/quests/devil_helmet/sewer.lua @@ -0,0 +1,45 @@ +local sewerPosition = Position(32482, 32170, 14) + +local sewer = MoveEvent() + +function sewer.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local tile = Tile(sewerPosition) + if (tile) then + local tileItem = tile:getItemById(430) + if (not tileItem) then + Game.createItem(430, 1, sewerPosition) + end + end + return true +end + +sewer:type("stepin") +sewer:uid(65203) +sewer:register() + +sewer = MoveEvent() + +function sewer.onStepOut(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local tile = Tile(sewerPosition) + if (tile) then + local tileItem = tile:getItemById(430) + if (tileItem) then + tileItem:remove(1) + end + end + return true +end + +sewer:type("stepout") +sewer:uid(65203) +sewer:register() diff --git a/data/scripts/movements/quests/dreamer_challenge/carrot.lua b/data/scripts/movements/quests/dreamer_challenge/carrot.lua new file mode 100644 index 00000000000..65072c1698c --- /dev/null +++ b/data/scripts/movements/quests/dreamer_challenge/carrot.lua @@ -0,0 +1,26 @@ +local carrot = MoveEvent() + +function carrot.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if item.uid == 2241 then + if player:getItemCount(2684) > 0 then + player:teleportTo(Position(32861, 32235, 9)) + player:removeItem(2684, 1) + else + player:teleportTo(fromPosition) + doAreaCombatHealth(player, COMBAT_FIREDAMAGE, fromPosition, 0, -10, -20, CONST_ME_HITBYFIRE) + end + elseif item.uid == 2242 then + player:teleportTo(Position(32861, 32240, 9)) + end + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +carrot:type("stepin") +carrot:uid(2241, 2242) +carrot:register() diff --git a/data/scripts/movements/quests/dreamer_challenge/clock_tile.lua b/data/scripts/movements/quests/dreamer_challenge/clock_tile.lua new file mode 100644 index 00000000000..2273dea06a0 --- /dev/null +++ b/data/scripts/movements/quests/dreamer_challenge/clock_tile.lua @@ -0,0 +1,25 @@ +local words = { + "YOU ARE DREAMING!", + "WAKE UP!", + "TIC TAC", + "TAC", + "TIC" +} + +local clockTile = MoveEvent() + +function clockTile.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + position.x = position.x + math.random(-3, 3) + position.y = position.y + math.random(-3, 3) + player:say(words[math.random(#words)], TALKTYPE_MONSTER_SAY, false, 0, position) + return true +end + +clockTile:type("stepin") +clockTile:aid(9049) +clockTile:register() diff --git a/data/scripts/movements/quests/dreamer_challenge/court_teleport.lua b/data/scripts/movements/quests/dreamer_challenge/court_teleport.lua new file mode 100644 index 00000000000..5d7533ac686 --- /dev/null +++ b/data/scripts/movements/quests/dreamer_challenge/court_teleport.lua @@ -0,0 +1,29 @@ +local teleports = { + [3200] = {position = Position(33672, 32228, 7) }, -- summer entry + [3201] = {position = Position(33584, 32208, 7) }, -- summer exit + [3202] = {position = Position(33675, 32148, 7) }, -- winter entry + [3203] = {position = Position(32354, 31248, 3) } -- winter exit +} + +local courtTeleport = MoveEvent() + +function courtTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return false + end + + for index, value in pairs(teleports) do + if item.actionid == index then + player:teleportTo(value.position) + end + end +end + +courtTeleport:type("stepin") + +for index, value in pairs(teleports) do + courtTeleport:aid(index) +end + +courtTeleport:register() diff --git a/data/scripts/movements/quests/dreamer_challenge/death_ring.lua b/data/scripts/movements/quests/dreamer_challenge/death_ring.lua new file mode 100644 index 00000000000..ea070981450 --- /dev/null +++ b/data/scripts/movements/quests/dreamer_challenge/death_ring.lua @@ -0,0 +1,27 @@ +local trees = { + Position(32857, 32231, 11), + Position(32857, 32232, 11), + Position(32857, 32233, 11) +} + +local deathRing = MoveEvent() + +function deathRing.onAddItem(moveitem, tileitem, position) + if moveitem.itemid ~= 6300 then + return true + end + + moveitem:remove() + for i = 1, #trees do + local treeItem = Tile(trees[i]):getItemById(2722) + if treeItem then + treeItem:remove() + trees[i]:sendMagicEffect(CONST_ME_MAGIC_BLUE) + end + end + return true +end + +deathRing:type("additem") +deathRing:uid(2244) +deathRing:register() diff --git a/data/scripts/movements/quests/dreamer_challenge/death_ring_teleport.lua b/data/scripts/movements/quests/dreamer_challenge/death_ring_teleport.lua new file mode 100644 index 00000000000..4b44be1853d --- /dev/null +++ b/data/scripts/movements/quests/dreamer_challenge/death_ring_teleport.lua @@ -0,0 +1,28 @@ +local trees = { + Position(32857, 32231, 11), + Position(32857, 32232, 11), + Position(32857, 32233, 11) +} + +local deathRingTeleport = MoveEvent() + +function deathRingTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + player:teleportTo(Position(32819, 32347, 9)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + for i = 1, #trees do + if not Tile(trees[i]):getItemById(2722) then + Game.createItem(2722, 1, trees[i]) + trees[i]:sendMagicEffect(CONST_ME_MAGIC_BLUE) + end + end + return true +end + +deathRingTeleport:type("stepin") +deathRingTeleport:uid(9234) +deathRingTeleport:register() diff --git a/data/scripts/movements/quests/dreamer_challenge/fire_bug_teleport.lua b/data/scripts/movements/quests/dreamer_challenge/fire_bug_teleport.lua new file mode 100644 index 00000000000..2f51126e3f6 --- /dev/null +++ b/data/scripts/movements/quests/dreamer_challenge/fire_bug_teleport.lua @@ -0,0 +1,19 @@ +local fireBugTeleport = MoveEvent() + +function fireBugTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if item.itemid == 1387 then + player:teleportTo(Position(32857, 32234, 11)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + item:transform(2249) + end + return true +end + +fireBugTeleport:type("stepin") +fireBugTeleport:uid(2243) +fireBugTeleport:register() diff --git a/data/scripts/movements/quests/dreamer_challenge/riddle.lua b/data/scripts/movements/quests/dreamer_challenge/riddle.lua new file mode 100644 index 00000000000..b95f95d035c --- /dev/null +++ b/data/scripts/movements/quests/dreamer_challenge/riddle.lua @@ -0,0 +1,55 @@ +local riddle = MoveEvent() + +function riddle.onStepIn(creature, item, position, fromPosition) + item:transform(425) + + if item.actionid == 2245 then + local new_position = Position(0, position.y, position.z) + for i = 5, 0, -1 do + new_position.x = position.x + 2 + i + local tile = new_position:getTile() + if i == 5 then + new_position.x = position.x + 2 + else + new_position.x = new_position.x + 1 + end + + local itemCount = tile:getDownItemCount() + if itemCount > 0 then + tile:getThing(tile:getTopItemCount() + tile:getCreatureCount() + itemCount):moveTo(new_position) + end + end + elseif item.actionid == 2246 then + local new_position = Position(position.x, 0, position.z) + for i = 5, 0, -1 do + new_position.y = position.y + 2 + i + local tile = new_position:getTile() + if i == 5 then + new_position.y = position.y + 2 + else + new_position.y = new_position.y + 1 + end + + local itemCount = tile:getDownItemCount() + if itemCount > 0 then + tile:getThing(tile:getTopItemCount() + tile:getCreatureCount() + itemCount):moveTo(new_position) + end + end + end + return true +end + +riddle:type("stepin") +riddle:aid(2245, 2246) +riddle:register() + +riddle = MoveEvent() + +function riddle.onStepOut(creature, item, position, fromPosition) + item:transform(426) + return true +end + +riddle:type("stepout") +riddle:aid(2245, 2246) +riddle:register() diff --git a/data/scripts/movements/quests/dreamer_challenge/riddle_teleport.lua b/data/scripts/movements/quests/dreamer_challenge/riddle_teleport.lua new file mode 100644 index 00000000000..6bbd9bfaf4c --- /dev/null +++ b/data/scripts/movements/quests/dreamer_challenge/riddle_teleport.lua @@ -0,0 +1,68 @@ +local function shuffleTable(t) + local newTable = {} + for i = 1, #t do + randomId = math.random(1, #t) + newTable[#newTable + 1] = t[randomId] + table.remove(t, randomId) + end + return newTable +end + +local arenaPosition = Position(32818, 32334, 9) + +local function doResetPillows() + local storePillows = {} + for i = 0, 3 do + local pillowId = 1686 + i + for i = 1, 9 do + storePillows[#storePillows + 1] = pillowId + end + end + + storePillows = shuffleTable(storePillows) + for aX = arenaPosition.x, arenaPosition.x + 5 do + for aY = arenaPosition.y, arenaPosition.y + 5 do + local pillow = math.random(#storePillows) + Tile(aX, aY, 9):getThing(1):transform(storePillows[pillow]) + table.remove(storePillows, pillow) + end + end + return true +end + +local function checkPillows(posX, posY, item) + for px = posX, posX + 2 do + for py = posY, posY + 2 do + if Tile(px, py, 9):getThing(1).itemid ~= item then + return false + end + end + end + return true +end + +local riddleTeleport = MoveEvent() + +function riddleTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return false + end + + if checkPillows(arenaPosition.x, arenaPosition.y, 1686) + and checkPillows(arenaPosition.x + 3, arenaPosition.y, 1688) + and checkPillows(arenaPosition.x, arenaPosition.y + 3, 1687) + and checkPillows(arenaPosition.x + 3, arenaPosition.y + 3, 1689) then + player:teleportTo(Position(32766, 32275, 14)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + doResetPillows() + else + player:teleportTo(fromPosition, true) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +riddleTeleport:type("stepin") +riddleTeleport:uid(50147) +riddleTeleport:register() diff --git a/data/scripts/movements/quests/dreamer_challenge/sacrifice_teleport.lua b/data/scripts/movements/quests/dreamer_challenge/sacrifice_teleport.lua new file mode 100644 index 00000000000..50fe8a9d8f9 --- /dev/null +++ b/data/scripts/movements/quests/dreamer_challenge/sacrifice_teleport.lua @@ -0,0 +1,26 @@ +local sacrificeTeleport = MoveEvent() + +function sacrificeTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + if item.actionid == 50149 and player:getStorageValue(Storage.OutfitQuest.NightmareOutfit) >= 2 then + player:teleportTo(Position(32835, 32225, 14)) --Sacrifice 2 + doSendMagicEffect(Position(32835, 32225, 14), CONST_ME_POFF) --Sacrifice 2 + else + player:teleportTo(Position(32844, 32228, 14)) --Sacrifice + if item.actionid == 50150 and player:getStorageValue(Storage.OutfitQuest.BrotherhoodOutfit) >= 2 then + player:teleportTo(Position(32784, 32226, 14)) --Sacrifice 4 + doSendMagicEffect(Position(32835, 32225, 14), CONST_ME_POFF) --Sacrifice 2 + else + player:teleportTo(Position(32790, 32227, 14)) --Sacrifice 3 + end + player:getPosition():sendMagicEffect(CONST_ME_POFF) + return true + end +end + +sacrificeTeleport:type("stepin") +sacrificeTeleport:aid(50149, 50150) +sacrificeTeleport:register() diff --git a/data/scripts/movements/quests/dreamer_challenge/stone_teleport.lua b/data/scripts/movements/quests/dreamer_challenge/stone_teleport.lua new file mode 100644 index 00000000000..df986d3a543 --- /dev/null +++ b/data/scripts/movements/quests/dreamer_challenge/stone_teleport.lua @@ -0,0 +1,100 @@ +local config = { + {position = Position(32873, 32263, 14), itemId = 1946, transformId = 1945}, + {position = Position(32874, 32263, 14), itemId = 3733, transformId = 3729}, + {position = Position(32875, 32263, 14), itemId = 3734, transformId = 3730}, + {position = Position(32874, 32264, 14), itemId = 3735, transformId = 3731}, + {position = Position(32875, 32264, 14), itemId = 3736, transformId = 3732} +} + +local sacrifices = { + {position = Position(32878, 32270, 14), itemId = 2016}, + {position = Position(32881, 32267, 14), itemId = 2168}, + {position = Position(32881, 32273, 14), itemId = 6300}, + {position = Position(32884, 32270, 14), itemId = 1487} +} + +local stoneTeleport = MoveEvent() + +function stoneTeleport.onAddItem(moveitem, tileitem, position) + local sacrificeItems, sacrificeItem = true + for i = 1, #sacrifices do + sacrificeItem = Tile(sacrifices[i].position):getItemById(sacrifices[i].itemId) + if not sacrificeItem then + sacrificeItems = false + break + end + end + + if not sacrificeItems then + return true + end + + local stonePosition = Position(32881, 32270, 14) + local stoneItem = Tile(stonePosition):getItemById(1355) + if stoneItem then + stoneItem:remove() + end + + local teleportExists = Tile(stonePosition):getItemById(1387) + if not teleportExists then + local newItem = Game.createItem(1387, 1, stonePosition) + if newItem then + newItem:setActionId(9031) + stonePosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + end + end + return true +end + +stoneTeleport:type("additem") +stoneTeleport:aid(8034) +stoneTeleport:register() + +stoneTeleport = MoveEvent() + +function stoneTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return false + end + + local sacrificeItems, sacrificeItem = true + for i = 1, #sacrifices do + sacrificeItem = Tile(sacrifices[i].position):getItemById(sacrifices[i].itemId) + if not sacrificeItem then + sacrificeItems = false + break + end + end + + if not sacrificeItems then + player:teleportTo(fromPosition, true) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + item:transform(1355) + return true + end + + for i = 1, #sacrifices do + sacrificeItem = Tile(sacrifices[i].position):getItemById(sacrifices[i].itemId) + if sacrificeItem then + sacrificeItem:remove() + end + end + + player:teleportTo(Position(32920, 32296, 13)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + item:transform(1355) + + local thing + for i = 1, #config do + thing = Tile(config[i].position):getItemById(config[i].itemId) + if thing then + thing:transform(config[i].transformId) + end + end + return true +end + +stoneTeleport:type("stepin") +stoneTeleport:aid(9031) +stoneTeleport:register() diff --git a/data/scripts/movements/quests/dreamer_challenge/teleport.lua b/data/scripts/movements/quests/dreamer_challenge/teleport.lua new file mode 100644 index 00000000000..715b7288dc8 --- /dev/null +++ b/data/scripts/movements/quests/dreamer_challenge/teleport.lua @@ -0,0 +1,29 @@ +local teleports = { + [2250] = {x = 32915, y = 32263, z = 14}, + [2251] = {x = 32946, y = 32270, z = 13}, + [2252] = {x = 32976, y = 32270, z = 14}, + [2253] = {x = 32933, y = 32282, z = 13}, + [2254] = {x = 32753, y = 32344, z = 14}, + [2255] = {x = 32753, y = 32344, z = 14} +} + +local teleport = MoveEvent() + +function teleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return false + end + + player:teleportTo(Position(teleports[item.uid])) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +teleport:type("stepin") + +for index, value in pairs(teleports) do + teleport:uid(index) +end + +teleport:register() diff --git a/data/scripts/movements/quests/dreamer_challenge/tic_teleport.lua b/data/scripts/movements/quests/dreamer_challenge/tic_teleport.lua new file mode 100644 index 00000000000..94f8a19aed6 --- /dev/null +++ b/data/scripts/movements/quests/dreamer_challenge/tic_teleport.lua @@ -0,0 +1,50 @@ +local config = { + {position = Position(32836, 32288, 14), itemId = 1387, transformId = 6299}, + {position = Position(32836, 32278, 14), itemId = 1946, transformId = 1945}, + {position = Position(32834, 32285, 14), itemId = 1946, transformId = 1945} +} + +local tokens = { + {position = Position(32845, 32264, 14), itemId = 2639}, + {position = Position(32843, 32266, 14), itemId = 2639}, + {position = Position(32843, 32268, 14), itemId = 2639}, + {position = Position(32845, 32268, 14), itemId = 2639}, + {position = Position(32844, 32267, 14), itemId = 2639}, + {position = Position(32840, 32269, 14), itemId = 2639}, + {position = Position(32841, 32269, 14), itemId = 2638}, + {position = Position(32840, 32268, 14), itemId = 2638}, + {position = Position(32842, 32267, 14), itemId = 2638} +} + +local ticTeleport = MoveEvent() + +function ticTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local thing + for i = 1, #config do + thing = Tile(config[i].position):getItemById(config[i].itemId) + if thing then + thing:transform(config[i].transformId) + end + end + + local token + for i = 1, #tokens do + token = Tile(tokens[i].position):getItemById(tokens[i].itemId) + if token then + token:remove() + end + end + + player:teleportTo(Position(32874, 32275, 14)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +ticTeleport:type("stepin") +ticTeleport:aid(9032) +ticTeleport:register() diff --git a/data/scripts/movements/quests/dreamer_challenge/tower.lua b/data/scripts/movements/quests/dreamer_challenge/tower.lua new file mode 100644 index 00000000000..89398cf8423 --- /dev/null +++ b/data/scripts/movements/quests/dreamer_challenge/tower.lua @@ -0,0 +1,44 @@ +local config = { + [3048] = {storageValue = 1, toPosition = Position(32360, 31782, 7)}, -- Carlin + [3049] = {storageValue = 1, toPosition = Position(32369, 32241, 7)}, -- Thais + [3050] = {storageValue = 1, toPosition = Position(32750, 32344, 14)}, -- Dream realm + [3051] = {storageValue = 2, toPosition = Position(32649, 31925, 11)}, -- Kazoordoon + [3052] = {storageValue = 2, toPosition = Position(32732, 31634, 7)}, -- Ab + [3053] = {storageValue = 2, toPosition = Position(32181, 32436, 7)}, -- Fibula + [3054] = {storageValue = 4, toPosition = Position(33213, 32454, 1)}, -- Darashia + [3055] = {storageValue = 4, toPosition = Position(33194, 32853, 8)}, -- Ankrahmun + [3056] = {storageValue = 4, toPosition = Position(32417, 32139, 15)} -- Mintwalin +} + +local tower = MoveEvent() + +function tower.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local targetTeleport = config[item.uid] + if not targetTeleport then + return true + end + + if (player:getStorageValue(Storage.OutfitQuest.NightmareOutfit) >= targetTeleport.storageValue + or player:getStorageValue(Storage.OutfitQuest.BrotherhoodOutfit) >= targetTeleport.storageValue) + and player:removeItem(5022, 1) then + player:teleportTo(targetTeleport.toPosition) + else + player:teleportTo(fromPosition) + end + + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +tower:type("stepin") + +for index, value in pairs(config) do + tower:uid(index) +end + +tower:register() diff --git a/data/scripts/movements/quests/dreamer_challenge/wall_teleport.lua b/data/scripts/movements/quests/dreamer_challenge/wall_teleport.lua new file mode 100644 index 00000000000..51897846c15 --- /dev/null +++ b/data/scripts/movements/quests/dreamer_challenge/wall_teleport.lua @@ -0,0 +1,43 @@ +local walls = { + { x = 32760, y = 32288, z = 14}, + { x = 32761, y = 32288, z = 14}, + { x = 32762, y = 32288, z = 14}, + { x = 32763, y = 32288, z = 14}, + { x = 32764, y = 32288, z = 14}, + { x = 32764, y = 32289, z = 14}, + { x = 32764, y = 32290, z = 14}, + { x = 32764, y = 32291, z = 14}, + { x = 32764, y = 32292, z = 14}, + { x = 32763, y = 32292, z = 14}, + { x = 32762, y = 32292, z = 14}, + { x = 32761, y = 32292, z = 14}, + { x = 32760, y = 32292, z = 14}, + { x = 32760, y = 32291, z = 14}, + { x = 32760, y = 32290, z = 14}, + { x = 32760, y = 32289, z = 14} +} + +local wallTeleport = MoveEvent() + +function wallTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + for i = 1, #walls do + if Tile(Position(walls[i])):hasFlag(TILESTATE_IMMOVABLEBLOCKSOLID) then + player:teleportTo(Position(32762, 32305, 14)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + end + + player:teleportTo(Position(32852, 32287, 14)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +wallTeleport:type("stepin") +wallTeleport:uid(9030) +wallTeleport:register() diff --git a/data/scripts/movements/quests/edron_rope/rope.lua b/data/scripts/movements/quests/edron_rope/rope.lua new file mode 100644 index 00000000000..6c700a5f4d5 --- /dev/null +++ b/data/scripts/movements/quests/edron_rope/rope.lua @@ -0,0 +1,20 @@ +local rope = MoveEvent() + +function rope.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.EdronRopeQuest) >= os.time() then + return true + end + + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "In this cave there is a rope. It once belonged to a wanderer who was stuck. Only take it if you're stuck as well.") + player:setStorageValue(Storage.EdronRopeQuest, os.time() + 30) + return true +end + +rope:type("stepin") +rope:aid(4254) +rope:register() diff --git a/data/scripts/movements/quests/elemental_spheres/aoe_teleport_out.lua b/data/scripts/movements/quests/elemental_spheres/aoe_teleport_out.lua new file mode 100644 index 00000000000..01f40c66fdc --- /dev/null +++ b/data/scripts/movements/quests/elemental_spheres/aoe_teleport_out.lua @@ -0,0 +1,19 @@ +local aoeTeleportOut = MoveEvent() + +function aoeTeleportOut.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + player:teleportTo(Position(33265, 31838, 10)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + for i = 10005, 10008 do + player:setStorageValue(i, -1) + end + return true +end + +aoeTeleportOut:type("stepin") +aoeTeleportOut:aid(9029) +aoeTeleportOut:register() diff --git a/data/scripts/movements/quests/elemental_spheres/soil_entrance.lua b/data/scripts/movements/quests/elemental_spheres/soil_entrance.lua new file mode 100644 index 00000000000..ab1200b54b0 --- /dev/null +++ b/data/scripts/movements/quests/elemental_spheres/soil_entrance.lua @@ -0,0 +1,36 @@ +local setting = { + [1062] = {destination = Position(33085, 32096, 13), vocation = VOCATION.CLIENT_ID.KNIGHT, storage = 10130}, + [1063] = {destination = Position(33264, 32201, 13), vocation = VOCATION.CLIENT_ID.PALADIN, storage = 10131}, + [1064] = {destination = Position(33330, 32077, 13), vocation = VOCATION.CLIENT_ID.DRUID, storage = 10132}, + [1065] = {destination = Position(33183, 32198, 13), vocation = VOCATION.CLIENT_ID.SORCERER, storage = 10133} +} + +local soilEntrance = MoveEvent() + +function soilEntrance.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local teleport = setting[item.uid] + if not teleport or player:getVocation():getClientId() ~= teleport.vocation or player:getLevel() < 10 then + player:teleportTo(fromPosition, true) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say('Your vocation cant enter in this teleport.', TALKTYPE_MONSTER_SAY) + return true + end + + player:teleportTo(teleport.destination) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:setStorageValue(teleport.storage, 1) + return true +end + +soilEntrance:type("stepin") + +for index, value in pairs(setting) do + soilEntrance:uid(index) +end + +soilEntrance:register() diff --git a/data/scripts/movements/quests/elemental_spheres/soil_exit.lua b/data/scripts/movements/quests/elemental_spheres/soil_exit.lua new file mode 100644 index 00000000000..719b89c5bbc --- /dev/null +++ b/data/scripts/movements/quests/elemental_spheres/soil_exit.lua @@ -0,0 +1,33 @@ +local setting = { + {storage = 10130, toPosition = Position(33264, 31835, 10)}, --EK + {storage = 10131, toPosition = Position(33272, 31835, 10)}, --RP + {storage = 10132, toPosition = Position(33268, 31840, 10)}, --ED + {storage = 10133, toPosition = Position(33268, 31831, 10)} -- SORC +} + +local soilExit = MoveEvent() + +function soilExit.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + + for i = 1, #setting do + local config = setting[i] + if player:getStorageValue(config.storage) >= 1 then + player:teleportTo(config.toPosition) + config.toPosition:sendMagicEffect(CONST_ME_TELEPORT) + player:setStorageValue(config.storage, 0) + return true + end + end + + player:teleportTo(player:getTown():getTemplePosition()) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +soilExit:type("stepin") +soilExit:aid(24545) +soilExit:register() diff --git a/data/scripts/movements/quests/elemental_spheres/summon_overlord.lua b/data/scripts/movements/quests/elemental_spheres/summon_overlord.lua new file mode 100644 index 00000000000..7d2528a37d5 --- /dev/null +++ b/data/scripts/movements/quests/elemental_spheres/summon_overlord.lua @@ -0,0 +1,114 @@ +local config = { + [8568] = { + storage = GlobalStorage.ElementalSphere.KnightBoss, + corpse = 8967, + charged = 1495, + inactive = 0, + boss = "energy overlord", + effect = CONST_ME_BIGCLOUDS, + summonPos = Position(33095, 32194, 13), + positions = { + Position(33094, 32189, 13), + Position(33097, 32189, 13), + Position(33099, 32191, 13), + Position(33099, 32194, 13), + Position(33097, 32196, 13), + Position(33094, 32196, 13), + Position(33092, 32194, 13), + Position(33092, 32191, 13) + } + }, + [8569] = { + storage = GlobalStorage.ElementalSphere.SorcererBoss, + corpse = 8969, + charged = 8575, + inactive = 8573, + boss = "fire overlord", + effect = CONST_ME_FIREAREA, + summonPos = Position(33199, 32103, 13), + positions = { + Position(33198, 32102, 13), + Position(33201, 32102, 13), + Position(33203, 32104, 13), + Position(33203, 32107, 13), + Position(33201, 32109, 13), + Position(33198, 32109, 13), + Position(33196, 32107, 13), + Position(33196, 32104, 13) + } + }, + [8570] = { + storage = GlobalStorage.ElementalSphere.PaladinBoss, + corpse = 8968, + charged = 8574, + inactive = 8571, + boss = 'Ice Overlord', + effect = CONST_ME_ICETORNADO, + summonEffect = CONST_ME_ICEAREA, + summonPos = Position(33286, 32102, 13), + positions = { + Position(33285, 32097, 13), + Position(33288, 32097, 13), + Position(33290, 32099, 13), + Position(33290, 32102, 13), + Position(33288, 32104, 13), + Position(33285, 32104, 13), + Position(33283, 32102, 13), + Position(33283, 32099, 13) + } + }, + [8578] = { + storage = GlobalStorage.ElementalSphere.DruidBoss, + corpse = 8934, + charged = 8576, + inactive = 8572, + boss = 'Earth Overlord', + effect = CONST_ME_BIGPLANTS, + summonPos = Position(33347, 32208, 13), + positions = { + Position(33346, 32203, 13), + Position(33349, 32203, 13), + Position(33351, 32205, 13), + Position(33351, 32208, 13), + Position(33349, 32210, 13), + Position(33346, 32210, 13), + Position(33344, 32208, 13), + Position(33344, 32205, 13) + } + } +} + +local summonOverlord = MoveEvent() + +function summonOverlord.onAddItem(moveitem, tileitem, position) + local target = config[tileitem.itemid] + if not target then + return true + end + + local cStorage = target.storage + if target.corpse ~= moveitem.itemid or Game.getStorageValue(cStorage) == 1 then + return true + end + + for i = 1, #target.positions do + if not Tile(target.positions[i]):getItemById(target.charged) then + return true + end + end + + moveitem:remove() + position:sendMagicEffect(target.effect) + target.summonPos:sendMagicEffect(target.summonEffect or target.effect) + Game.createMonster(target.boss, target.summonPos) + Game.setStorageValue(cStorage, 1) + return true +end + +summonOverlord:type("additem") + +for index, value in pairs(config) do + summonOverlord:id(index) +end + +summonOverlord:register() diff --git a/data/scripts/movements/quests/explorer_society/calassa.lua b/data/scripts/movements/quests/explorer_society/calassa.lua new file mode 100644 index 00000000000..8fb5154d8b5 --- /dev/null +++ b/data/scripts/movements/quests/explorer_society/calassa.lua @@ -0,0 +1,25 @@ +local calassa = MoveEvent() + +function calassa.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local headItem = player:getSlotItem(CONST_SLOT_HEAD) + if headItem and isInArray({5461, 12541, 15408}, headItem.itemid) then + player:teleportTo(Position(31914, 32713, 12)) + player:getPosition():sendMagicEffect(CONST_ME_WATERSPLASH) + player:getPosition():sendMagicEffect(CONST_ME_LOSEENERGY) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You enter the realm of Calassa.') + else + player:teleportTo(fromPosition) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You must wear an underwater exploration helmet in order to dive.') + end + return true +end + +calassa:type("stepin") +calassa:aid(2070) +calassa:register() diff --git a/data/scripts/movements/quests/explorer_society/carving_teleport_liberty_bay.lua b/data/scripts/movements/quests/explorer_society/carving_teleport_liberty_bay.lua new file mode 100644 index 00000000000..3dc67f95446 --- /dev/null +++ b/data/scripts/movements/quests/explorer_society/carving_teleport_liberty_bay.lua @@ -0,0 +1,38 @@ +local destination = { + [25020] = {position = Position(32320, 31137, 6)}, + [25021] = {position = Position(32359, 32807, 6)} +} + +local carvingTeleportLibertyBay = MoveEvent() + +function carvingTeleportLibertyBay.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + + local carvingTP = destination[item.uid] + if not carvingTP then + return + end + + if player:getStorageValue(Storage.ExplorerSociety.TheIceMusic) >= 62 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) >= 62 + and player:removeItem(5022, 1) then + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(carvingTP.position) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:teleportTo(fromPosition) + end + return true +end + +carvingTeleportLibertyBay:type("stepin") + +for index, value in pairs(destination) do + carvingTeleportLibertyBay:uid(index) +end + +carvingTeleportLibertyBay:register() diff --git a/data/scripts/movements/quests/explorer_society/carvingteleport_port_hope.lua b/data/scripts/movements/quests/explorer_society/carvingteleport_port_hope.lua new file mode 100644 index 00000000000..d9fdb0fa539 --- /dev/null +++ b/data/scripts/movements/quests/explorer_society/carvingteleport_port_hope.lua @@ -0,0 +1,38 @@ +local destination = { + [25018] = {position = Position(32498, 31622, 6)}, + [25019] = {position = Position(32665, 32735, 6)} +} + +local carvingTeleportPortHope = MoveEvent() + +function carvingTeleportPortHope.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + + local carvingTP = destination[item.uid] + if not carvingTP then + return + end + + if player:getStorageValue(Storage.ExplorerSociety.TheAstralPortals) >= 56 + and player:getStorageValue(Storage.ExplorerSociety.QuestLine) >= 56 + and player:removeItem(5022, 1) then + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(carvingTP.position) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:teleportTo(fromPosition) + end + return true +end + +carvingTeleportPortHope:type("stepin") + +for index, value in pairs(destination) do + carvingTeleportPortHope:uid(index) +end + +carvingTeleportPortHope:register() diff --git a/data/scripts/movements/quests/extension_mota/extension_mota.lua b/data/scripts/movements/quests/extension_mota/extension_mota.lua new file mode 100644 index 00000000000..c5945c2b61c --- /dev/null +++ b/data/scripts/movements/quests/extension_mota/extension_mota.lua @@ -0,0 +1,29 @@ +local destination = { + [64015] = {toPosition = Position(33246, 32099, 8)}, --Entrance + [64016] = {toPosition = Position(33246, 32108, 8)} --Exit +} + +local extensionMota = MoveEvent() + +function extensionMota.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + + local teleport = destination[item.actionid] + if not teleport then + return + end + player:teleportTo(teleport.toPosition) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +extensionMota:type("stepin") + +for index, value in pairs(destination) do + extensionMota:aid(index) +end + +extensionMota:register() diff --git a/data/scripts/movements/quests/ferumbras_ascendant/blue_gem.lua b/data/scripts/movements/quests/ferumbras_ascendant/blue_gem.lua new file mode 100644 index 00000000000..9ae95270ec9 --- /dev/null +++ b/data/scripts/movements/quests/ferumbras_ascendant/blue_gem.lua @@ -0,0 +1,77 @@ +local function revertItem(position, itemId, transformId) + local item = Tile(position):getItemById(itemId) + if item then + item:transform(transformId) + end +end +local function activeBasin(position) + local basinOne = Tile(Position(position.x - 1, position.y - 2, position.z)):getItemById(12450) + local basinTwo = Tile(Position(position.x, position.y - 2, position.z)):getItemById(12451) + local basinThree = Tile(Position(position.x - 1, position.y - 1, position.z)):getItemById(12452) + local basinFour = Tile(Position(position.x, position.y - 1, position.z)):getItemById(12453) + basinOne:transform(12458) + basinTwo:transform(12459) + basinThree:transform(12460) + basinFour:transform(12461) +end + +local function revertBasin(position) + local basinOne = Tile(Position(position.x - 1, position.y - 2, position.z)):getItemById(12458) + local basinTwo = Tile(Position(position.x, position.y - 2, position.z)):getItemById(12459) + local basinThree = Tile(Position(position.x - 1, position.y - 1, position.z)):getItemById(12460) + local basinFour = Tile(Position(position.x, position.y - 1, position.z)):getItemById(12461) + basinOne:transform(12450) + basinTwo:transform(12451) + basinThree:transform(12452) + basinFour:transform(12453) +end + +function revertStorages() + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Active, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.First, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Second, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Third, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Four, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Done, 0) +end + +local blueGem = MoveEvent() + +function blueGem.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player or Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Active) >= 1 then + position:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + if item.itemid == 9563 then + local leverFirst = Tile(Position(33671, 32638, 13)):getItemById(10029) + or Tile(Position(33671, 32638, 13)):getItemById(10030) -- lever blue + local leverSecond = Tile(Position(33613, 32691, 13)):getItemById(10029) + or Tile(Position(33613, 32691, 13)):getItemById(10030) -- lever green + local leverThird = Tile(Position(33651, 32661, 13)):getItemById(10029) + or Tile(Position(33651, 32661, 13)):getItemById(10030) -- lever red + local leverFour = Tile(Position(33672, 32688, 13)):getItemById(10029) + or Tile(Position(33672, 32688, 13)):getItemById(10030) -- lever green + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.First, 3) -- blue + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Second, 2) -- green + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Third, 1) -- red + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Four, 5) -- grass + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You hear a whisper: \z + 'You will not be guided but your path shines in the colours blue, green and red. Heed this hierarchy.'") + leverFirst:setActionId(53821) + leverSecond:setActionId(53822) + leverThird:setActionId(53823) + leverFour:setActionId(53824) + end + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Active, 1) + item:transform(9564) + addEvent(activeBasin, 1 * 1000, position) + addEvent(revertBasin, 60 * 60 * 1000, position) + addEvent(revertStorages, 60 * 60 * 1000) + addEvent(revertItem, 60 * 60 * 1000, position, 9564, item.itemid) + return true +end + +blueGem:type("stepin") +blueGem:aid(53813) +blueGem:register() diff --git a/data/scripts/movements/quests/ferumbras_ascendant/boss_teleport.lua b/data/scripts/movements/quests/ferumbras_ascendant/boss_teleport.lua new file mode 100644 index 00000000000..8140087bb3a --- /dev/null +++ b/data/scripts/movements/quests/ferumbras_ascendant/boss_teleport.lua @@ -0,0 +1,36 @@ +local config = { + [24830] = {storage = Storage.FerumbrasAscension.Razzagorn}, + [24831] = {storage = Storage.FerumbrasAscension.Ragiaz}, + [24832] = {storage = Storage.FerumbrasAscension.Zamulosh}, + [24833] = {storage = Storage.FerumbrasAscension.Mazoran}, + [24834] = {storage = Storage.FerumbrasAscension.Tarbaz}, + [24835] = {storage = Storage.FerumbrasAscension.Shulgrax}, + [24836] = {storage = Storage.FerumbrasAscension.Plagirath} +} + +local bossTeleport = MoveEvent() + +function bossTeleport.onStepIn(creature, item, position, fromPosition) + local teleport = config[item.actionid] + if not teleport then + return false + end + local player = creature:getPlayer() + if not player then + return true + end + if player:getStorageValue(teleport.storage) == 1 then + local position = player:getPosition() + position.z = position.z - 1 + player:teleportTo(position) + end + return true +end + +bossTeleport:type("stepin") + +for index, value in pairs(config) do + bossTeleport:aid(index) +end + +bossTeleport:register() diff --git a/data/scripts/movements/quests/ferumbras_ascendant/desperate_soul.lua b/data/scripts/movements/quests/ferumbras_ascendant/desperate_soul.lua new file mode 100644 index 00000000000..d12456687e0 --- /dev/null +++ b/data/scripts/movements/quests/ferumbras_ascendant/desperate_soul.lua @@ -0,0 +1,18 @@ +local desperateSoul = MoveEvent() + +function desperateSoul.onStepIn(creature, item, position, fromPosition) + local monster = creature:getMonster() + if not monster or monster:getName():lower() ~= 'desperate soul' then + return true + end + + monster:remove() + position:sendMagicEffect(CONST_ME_POFF) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.FerumbrasEssence, 1) + addEvent(Game.setStorageValue, 2 * 60 * 1000, GlobalStorage.FerumbrasAscendant.FerumbrasEssence, 0) + return true +end + +desperateSoul:type("stepin") +desperateSoul:aid(54390) +desperateSoul:register() diff --git a/data/scripts/movements/quests/ferumbras_ascendant/entrance.lua b/data/scripts/movements/quests/ferumbras_ascendant/entrance.lua new file mode 100644 index 00000000000..bef1d3eb41f --- /dev/null +++ b/data/scripts/movements/quests/ferumbras_ascendant/entrance.lua @@ -0,0 +1,54 @@ +local config = { + [1] = {storage = Storage.FerumbrasAscension.Razzagorn}, + [2] = {storage = Storage.FerumbrasAscension.Ragiaz}, + [3] = {storage = Storage.FerumbrasAscension.Zamulosh}, + [4] = {storage = Storage.FerumbrasAscension.Mazoran}, + [5] = {storage = Storage.FerumbrasAscension.Tarbaz}, + [6] = {storage = Storage.FerumbrasAscension.Shulgrax}, + [7] = {storage = Storage.FerumbrasAscension.Plagirath} +} + +local entrance = MoveEvent() + +function entrance.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local complete = false + for i = 1, #config do + local storage = config[i].storage + if player:getStorageValue(storage) ~= 1 then + complete = false + else + complete = true + end + end + if item:getActionId() == 24837 then + if complete then + player:teleportTo(Position(33275, 32390, 9)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + else + player:teleportTo(Position(33275, 32390, 8)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + elseif item:getActionId() == 24838 then + if player:getStorageValue(Storage.FerumbrasAscension.Access) < 1 then + player:teleportTo(Position(33275, 32390, 8)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + "This portal is not yet strong enough to breach the destination dimension.") + return true + end + player:teleportTo(Position(33319, 32317, 13)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + return true +end + +entrance:type("stepin") +entrance:aid(24837, 24838) +entrance:register() diff --git a/data/scripts/movements/quests/ferumbras_ascendant/flower_puzzle.lua b/data/scripts/movements/quests/ferumbras_ascendant/flower_puzzle.lua new file mode 100644 index 00000000000..c371b0fedcf --- /dev/null +++ b/data/scripts/movements/quests/ferumbras_ascendant/flower_puzzle.lua @@ -0,0 +1,213 @@ +local positions = { + [1] = { + squarePos = Position(33452, 32721, 14), + flowerOne = Position(33455, 32685, 14), + flowerTwo = Position(33455, 32691, 14), + flowerThree = Position(33455, 32707, 14) + }, + [2] = { + squarePos = Position(33455, 32721, 14), + flowerOne = Position(33456, 32685, 14), + flowerTwo = Position(33456, 32691, 14), + flowerThree = Position(33456, 32707, 14) + }, + [3] = { + squarePos = Position(33458, 32721, 14), + flowerOne = Position(33457, 32685, 14), + flowerTwo = Position(33457, 32691, 14), + flowerThree = Position(33457, 32707, 14) + }, + [4] = { + squarePos = Position(33461, 32721, 14), + flowerOne = Position(33458, 32685, 14), + flowerTwo = Position(33458, 32691, 14), + flowerThree = Position(33458, 32707, 14) + }, + [5] = { + squarePos = Position(33464, 32721, 14), + flowerOne = Position(33459, 32685, 14), + flowerTwo = Position(33459, 32691, 14), + flowerThree = Position(33459, 32707, 14) + }, + [6] = { + squarePos = Position(33467, 32721, 14), + flowerOne = Position(33460, 32685, 14), + flowerTwo = Position(33460, 32691, 14), + flowerThree = Position(33460, 32707, 14)}, -- done + [7] = { + squarePos = Position(33452, 32724, 14), + flowerOne = Position(33455, 32686, 14), + flowerTwo = Position(33455, 32692, 14), + flowerThree = Position(33455, 32708, 14) + }, + [8] = { + squarePos = Position(33455, 32724, 14), + flowerOne = Position(33456, 32686, 14), + flowerTwo = Position(33456, 32692, 14), + flowerThree = Position(33456, 32708, 14) + }, + [9] = { + squarePos = Position(33458, 32724, 14), + flowerOne = Position(33457, 32686, 14), + flowerTwo = Position(33457, 32692, 14), + flowerThree = Position(33457, 32708, 14) + }, + [10] = { + squarePos = Position(33461, 32724, 14), + flowerOne = Position(33458, 32686, 14), + flowerTwo = Position(33458, 32692, 14), + flowerThree = Position(33458, 32708, 14) + }, + [11] = { + squarePos = Position(33464, 32724, 14), + flowerOne = Position(33459, 32686, 14), + flowerTwo = Position(33459, 32692, 14), + flowerThree = Position(33459, 32708, 14) + }, + [12] = { + squarePos = Position(33467, 32724, 14), + flowerOne = Position(33460, 32686, 14), + flowerTwo = Position(33460, 32692, 14), + flowerThree = Position(33460, 32708, 14)}, -- done + [13] = { + squarePos = Position(33452, 32727, 14), + flowerOne = Position(33455, 32687, 14), + flowerTwo = Position(33455, 32693, 14), + flowerThree = Position(33455, 32709, 14) + }, + [14] = { + squarePos = Position(33455, 32727, 14), + flowerOne = Position(33456, 32687, 14), + flowerTwo = Position(33456, 32693, 14), + flowerThree = Position(33456, 32709, 14) + }, + [15] = { + squarePos = Position(33458, 32727, 14), + flowerOne = Position(33457, 32687, 14), + flowerTwo = Position(33457, 32693, 14), + flowerThree = Position(33457, 32709, 14) + }, + [16] = { + squarePos = Position(33461, 32727, 14), + flowerOne = Position(33458, 32687, 14), + flowerTwo = Position(33458, 32693, 14), + flowerThree = Position(33458, 32709, 14) + }, + [17] = { + squarePos = Position(33464, 32727, 14), + flowerOne = Position(33459, 32687, 14), + flowerTwo = Position(33459, 32693, 14), + flowerThree = Position(33459, 32709, 14) + }, + [18] = { + squarePos = Position(33467, 32727, 14), + flowerOne = Position(33460, 32687, 14), + flowerTwo = Position(33460, 32693, 14), + flowerThree = Position(33460, 32709, 14)} + +} + +local flowerPuzzle = MoveEvent() + +function flowerPuzzle.onStepIn(creature, item, position, fromPosition) + for i = 1, #positions do + local itempos = positions[i] + if position == itempos.squarePos then + if item.itemid == 25194 then + item:transform(25195) + local flowerOne = Tile(itempos.flowerOne):getItemById(2762) + or Tile(itempos.flowerOne):getItemById(2764) + or Tile(itempos.flowerOne):getItemById(2763) + local flowerTwo = Tile(itempos.flowerTwo):getItemById(2762) + or Tile(itempos.flowerTwo):getItemById(2764) + or Tile(itempos.flowerTwo):getItemById(2763) + local flowerThree = Tile(itempos.flowerThree):getItemById(2762) + or Tile(itempos.flowerThree):getItemById(2764) + or Tile(itempos.flowerThree):getItemById(2763) + if not flowerOne then + flowerOne = Game.createItem(2763, 1, itempos.flowerOne) + end + if not flowerTwo then + flowerTwo = Game.createItem(2763, 1, itempos.flowerTwo) + end + if not flowerThree then + flowerThree = Game.createItem(2763, 1, itempos.flowerThree) + end + flowerOne:transform(2763) + flowerTwo:transform(2763) + flowerThree:transform(2763) + elseif item.itemid == 25195 then + item:transform(25196) + local flowerOne = Tile(itempos.flowerOne):getItemById(2762) + or Tile(itempos.flowerOne):getItemById(2764) + or Tile(itempos.flowerOne):getItemById(2763) + local flowerTwo = Tile(itempos.flowerTwo):getItemById(2762) + or Tile(itempos.flowerTwo):getItemById(2764) + or Tile(itempos.flowerTwo):getItemById(2763) + local flowerThree = Tile(itempos.flowerThree):getItemById(2762) + or Tile(itempos.flowerThree):getItemById(2764) + or Tile(itempos.flowerThree):getItemById(2763) + if not flowerOne then + flowerOne = Game.createItem(2764, 1, itempos.flowerOne) + end + if not flowerTwo then + flowerTwo = Game.createItem(2764, 1, itempos.flowerTwo) + end + if not flowerThree then + flowerThree = Game.createItem(2764, 1, itempos.flowerThree) + end + flowerOne:transform(2764) + flowerTwo:transform(2764) + flowerThree:transform(2764) + elseif item.itemid == 25196 then + item:transform(25197) + local flowerOne = Tile(itempos.flowerOne):getItemById(2762) + or Tile(itempos.flowerOne):getItemById(2764) + or Tile(itempos.flowerOne):getItemById(2763) + local flowerTwo = Tile(itempos.flowerTwo):getItemById(2762) + or Tile(itempos.flowerTwo):getItemById(2764) + or Tile(itempos.flowerTwo):getItemById(2763) + local flowerThree = Tile(itempos.flowerThree):getItemById(2762) + or Tile(itempos.flowerThree):getItemById(2764) + or Tile(itempos.flowerThree):getItemById(2763) + if not flowerOne then + flowerOne = Game.createItem(2762, 1, itempos.flowerOne) + end + if not flowerTwo then + flowerTwo = Game.createItem(2762, 1, itempos.flowerTwo) + end + if not flowerThree then + flowerThree = Game.createItem(2762, 1, itempos.flowerThree) + end + flowerOne:transform(2762) + flowerTwo:transform(2762) + flowerThree:transform(2762) + elseif item.itemid == 25197 then + item:transform(25194) + local flowerOne = Tile(itempos.flowerOne):getItemById(2762) + or Tile(itempos.flowerOne):getItemById(2764) + or Tile(itempos.flowerOne):getItemById(2763) + local flowerTwo = Tile(itempos.flowerTwo):getItemById(2762) + or Tile(itempos.flowerTwo):getItemById(2764) + or Tile(itempos.flowerTwo):getItemById(2763) + local flowerThree = Tile(itempos.flowerThree):getItemById(2762) + or Tile(itempos.flowerThree):getItemById(2764) + or Tile(itempos.flowerThree):getItemById(2763) + if flowerOne then + flowerOne:remove() + end + if flowerTwo then + flowerTwo:remove() + end + if flowerThree then + flowerThree:remove() + end + end + end + end + return true +end + +flowerPuzzle:type("stepin") +flowerPuzzle:id(25194, 25195, 25196, 25197) +flowerPuzzle:register() diff --git a/data/scripts/movements/quests/ferumbras_ascendant/gate_of_deathstruction.lua b/data/scripts/movements/quests/ferumbras_ascendant/gate_of_deathstruction.lua new file mode 100644 index 00000000000..a2ae5154066 --- /dev/null +++ b/data/scripts/movements/quests/ferumbras_ascendant/gate_of_deathstruction.lua @@ -0,0 +1,27 @@ +local gateOfDeathstruction = MoveEvent() + +function gateOfDeathstruction.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.FerumbrasAscension.Statue) < 1 then + position:sendMagicEffect(CONST_ME_TELEPORT) + position.y = position.y + 2 + player:teleportTo(position) + position:sendMagicEffect(CONST_ME_TELEPORT) + else + player:teleportTo(Position(33414, 32379, 13)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + local gatePos = Position(33415, 32377, 13) + gatePos:sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + "You have performed the Blood Well Ritual and now are worthy to enter the lower tunnels.") + end + return true +end + +gateOfDeathstruction:type("stepin") +gateOfDeathstruction:aid(53802) +gateOfDeathstruction:register() diff --git a/data/scripts/movements/quests/ferumbras_ascendant/green_gem.lua b/data/scripts/movements/quests/ferumbras_ascendant/green_gem.lua new file mode 100644 index 00000000000..40cf3805f76 --- /dev/null +++ b/data/scripts/movements/quests/ferumbras_ascendant/green_gem.lua @@ -0,0 +1,79 @@ +local function revertItem(position, itemId, transformId) + local item = Tile(position):getItemById(itemId) + if item then + item:transform(transformId) + end +end + +local function activeBasin(position) + local basinOne = Tile(Position(position.x - 1, position.y - 2, position.z)):getItemById(12450) + local basinTwo = Tile(Position(position.x, position.y - 2, position.z)):getItemById(12451) + local basinThree = Tile(Position(position.x - 1, position.y - 1, position.z)):getItemById(12452) + local basinFour = Tile(Position(position.x, position.y - 1, position.z)):getItemById(12453) + basinOne:transform(12458) + basinTwo:transform(12459) + basinThree:transform(12460) + basinFour:transform(12461) +end + +local function revertBasin(position) + local basinOne = Tile(Position(position.x - 1, position.y - 2, position.z)):getItemById(12458) + local basinTwo = Tile(Position(position.x, position.y - 2, position.z)):getItemById(12459) + local basinThree = Tile(Position(position.x - 1, position.y - 1, position.z)):getItemById(12460) + local basinFour = Tile(Position(position.x, position.y - 1, position.z)):getItemById(12461) + basinOne:transform(12450) + basinTwo:transform(12451) + basinThree:transform(12452) + basinFour:transform(12453) +end + +function revertStorages() + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Active, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.First, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Second, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Third, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Four, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Done, 0) +end + +local greenGem = MoveEvent() + +function greenGem.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player + or Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Active) >= 1 then + position:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + if item.itemid == 9565 then + local leverFirst = Tile(Position(33613, 32691, 13)):getItemById(10029) + or Tile(Position(33613, 32691, 13)):getItemById(10030) -- lever green + local leverSecond = Tile(Position(33671, 32638, 13)):getItemById(10029) + or Tile(Position(33671, 32638, 13)):getItemById(10030) -- lever blue + local leverThird = Tile(Position(33651, 32661, 13)):getItemById(10029) + or Tile(Position(33651, 32661, 13)):getItemById(10030) -- lever red + local leverFour = Tile(Position(33673, 32688, 13)):getItemById(10029) + or Tile(Position(33673, 32688, 13)):getItemById(10030) -- lever green + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.First, 2) -- green + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Second, 3) -- blue + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Third, 1) -- red + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Four, 6) -- ice + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You hear a whisper: \z + 'You will not be guided but your path shines in the colours green, blue and red. Heed this hierarchy.'") + leverFirst:setActionId(53821) + leverSecond:setActionId(53822) + leverThird:setActionId(53823) + leverFour:setActionId(53824) + end + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Active, 1) + item:transform(9564) + addEvent(activeBasin, 1 * 1000, position) + addEvent(revertBasin, 60 * 60 * 1000, position) + addEvent(revertStorages, 60 * 60 * 1000) + addEvent(revertItem, 60 * 60 * 1000, position, 9564, item.itemid) + return true +end + +greenGem:type("stepin") +greenGem:aid(53814) +greenGem:register() diff --git a/data/scripts/movements/quests/ferumbras_ascendant/habitats_access.lua b/data/scripts/movements/quests/ferumbras_ascendant/habitats_access.lua new file mode 100644 index 00000000000..86a0ef52649 --- /dev/null +++ b/data/scripts/movements/quests/ferumbras_ascendant/habitats_access.lua @@ -0,0 +1,49 @@ +local config = { + [34323] = { + toPosition = Position(33630, 32651, 12), + backPosition = Position(33630, 32651, 12), + timer = Storage.FerumbrasAscension.HabitatsTimer + } +} + +local habitatsAccess = MoveEvent() + +function habitatsAccess.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local setting = config[item.actionid] + if not setting then + return true + end + + if item.actionid == 34323 then + if player:getStorageValue(Storage.FerumbrasAscension.HabitatsAccess) >= 1 then + if player:getStorageValue(setting.timer) < os.time() then + player:teleportTo(setting.toPosition) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + local pos = position + pos.y = pos.y + 2 + player:teleportTo(pos) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say('You have to wait to challenge this enemy again!', TALKTYPE_MONSTER_SAY) + return true + end + else + local pos = position + pos.y = pos.y + 2 + player:teleportTo(pos) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You not proven your worth. There is no escape for you here.') + item:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + end + return true +end + +habitatsAccess:type("stepin") +habitatsAccess:aid(34323) +habitatsAccess:register() diff --git a/data/scripts/movements/quests/ferumbras_ascendant/lovely_monsters.lua b/data/scripts/movements/quests/ferumbras_ascendant/lovely_monsters.lua new file mode 100644 index 00000000000..9f58a32babd --- /dev/null +++ b/data/scripts/movements/quests/ferumbras_ascendant/lovely_monsters.lua @@ -0,0 +1,51 @@ +local config = { + [34315] = {name = 'lovely frazzlemaw', centerPos = Position(33618, 32666, 12)}, + [34316] = {name = 'lovely deer', centerPos = Position(33641, 32666, 12)}, + [34317] = {name = 'lovely rotworm', centerPos = Position(33618, 32684, 12)}, + [34318] = {name = 'lovely scorpion', centerPos = Position(33641, 32684, 12)}, + [34319] = {name = 'lovely snake', centerPos = Position(33618, 32702, 12)}, + [34320] = {name = 'lovely polar bear', centerPos = Position(33641, 32702, 12)}, + [34321] = {name = 'lovely souleater', centerPos = Position(33618, 32720, 12)}, + [34322] = {name = 'lovely yielothax', centerPos = Position(33641, 32720, 12)} +} + +local lovelyMonsters = MoveEvent() + +function lovelyMonsters.onStepIn(creature, item, position, fromPosition) + local config = config[item.actionid] + if not config then + return true + end + + if creature:isPlayer() then + return true + end + + local monster = creature:getMonster() + if monster:getName():lower() == config.name then + monster:say('That seemed correct!', TALKTYPE_MONSTER_SAY) + monster:getPosition():sendMagicEffect(CONST_ME_THUNDER) + monster:remove() + local spectators = Game.getSpectators(config.centerPos, false, true, 9, 9, 9, 9) + for _, spectator in pairs(spectators) do + if spectator:isPlayer() then + local player = spectator + if player:getStorageValue(Storage.FerumbrasAscension.ZamuloshTeleports) < 0 then + player:setStorageValue(Storage.FerumbrasAscension.ZamuloshTeleports, 0) + end + player:setStorageValue(Storage.FerumbrasAscension.ZamuloshTeleports, + player:getStorageValue(Storage.FerumbrasAscension.ZamuloshTeleports) + 1) + end + end + return true + end + return true +end + +lovelyMonsters:type("stepin") + +for index, value in pairs(config) do + lovelyMonsters:aid(index) +end + +lovelyMonsters:register() diff --git a/data/scripts/movements/quests/ferumbras_ascendant/mazoran_fire.lua b/data/scripts/movements/quests/ferumbras_ascendant/mazoran_fire.lua new file mode 100644 index 00000000000..2efed9e74bf --- /dev/null +++ b/data/scripts/movements/quests/ferumbras_ascendant/mazoran_fire.lua @@ -0,0 +1,15 @@ +local mazoranFire = MoveEvent() + +function mazoranFire.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + doTargetCombatHealth(0, player, COMBAT_FIREDAMAGE, -1000, -1000, CONST_ME_HITBYFIRE) + return true +end + +mazoranFire:type("stepin") +mazoranFire:aid(34200) +mazoranFire:register() diff --git a/data/scripts/movements/quests/ferumbras_ascendant/plagirath_access.lua b/data/scripts/movements/quests/ferumbras_ascendant/plagirath_access.lua new file mode 100644 index 00000000000..b949b797b90 --- /dev/null +++ b/data/scripts/movements/quests/ferumbras_ascendant/plagirath_access.lua @@ -0,0 +1,24 @@ +local plagirathAccess = MoveEvent() + +function plagirathAccess.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.FerumbrasAscension.TheLordOfTheLiceAccess) < 1 then + local pos = player:getPosition() + pos.x = pos.x - 2 + player:teleportTo(pos) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say("You don't have access to this teleport yet.", TALKTYPE_MONSTER_SAY) + return true + end + player:teleportTo(Position(33238, 31477, 13)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +plagirathAccess:type("stepin") +plagirathAccess:aid(53800) +plagirathAccess:register() diff --git a/data/scripts/movements/quests/ferumbras_ascendant/razzagorn_access.lua b/data/scripts/movements/quests/ferumbras_ascendant/razzagorn_access.lua new file mode 100644 index 00000000000..c83b7be6f48 --- /dev/null +++ b/data/scripts/movements/quests/ferumbras_ascendant/razzagorn_access.lua @@ -0,0 +1,24 @@ +local razzagornAccess = MoveEvent() + +function razzagornAccess.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.FerumbrasAscension.TheShatterer) >= 1 then + player:teleportTo(Position(33437, 32443, 15)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + local pos = player:getPosition() + pos.x = pos.x + 2 + player:teleportTo(pos) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say("You don't have access to this teleport yet.", TALKTYPE_MONSTER_SAY) + end + return true +end + +razzagornAccess:type("stepin") +razzagornAccess:aid(53801) +razzagornAccess:register() diff --git a/data/scripts/movements/quests/ferumbras_ascendant/red_gem.lua b/data/scripts/movements/quests/ferumbras_ascendant/red_gem.lua new file mode 100644 index 00000000000..e877bf50819 --- /dev/null +++ b/data/scripts/movements/quests/ferumbras_ascendant/red_gem.lua @@ -0,0 +1,78 @@ +local function revertItem(position, itemId, transformId) + local item = Tile(position):getItemById(itemId) + if item then + item:transform(transformId) + end +end + +local function activeBasin(position) + local basinOne = Tile(Position(position.x - 1, position.y - 2, position.z)):getItemById(12450) + local basinTwo = Tile(Position(position.x, position.y - 2, position.z)):getItemById(12451) + local basinThree = Tile(Position(position.x - 1, position.y - 1, position.z)):getItemById(12452) + local basinFour = Tile(Position(position.x, position.y - 1, position.z)):getItemById(12453) + basinOne:transform(12458) + basinTwo:transform(12459) + basinThree:transform(12460) + basinFour:transform(12461) +end + +local function revertBasin(position) + local basinOne = Tile(Position(position.x - 1, position.y - 2, position.z)):getItemById(12458) + local basinTwo = Tile(Position(position.x, position.y - 2, position.z)):getItemById(12459) + local basinThree = Tile(Position(position.x - 1, position.y - 1, position.z)):getItemById(12460) + local basinFour = Tile(Position(position.x, position.y - 1, position.z)):getItemById(12461) + basinOne:transform(12450) + basinTwo:transform(12451) + basinThree:transform(12452) + basinFour:transform(12453) +end + +function revertStorages() + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Active, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.First, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Second, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Third, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Four, 0) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Done, 0) +end + +local redGem = MoveEvent() + +function redGem.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player or Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Active) >= 1 then + position:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + if item.itemid == 9562 then + local leverFirst = Tile(Position(33651, 32661, 13)):getItemById(10029) + or Tile(Position(33651, 32661, 13)):getItemById(10030) -- lever red + local leverSecond = Tile(Position(33671, 32638, 13)):getItemById(10029) + or Tile(Position(33671, 32638, 13)):getItemById(10030) -- lever blue + local leverThird = Tile(Position(33613, 32691, 13)):getItemById(10029) + or Tile(Position(33613, 32691, 13)):getItemById(10030) -- lever green + local leverFour = Tile(Position(33671, 32688, 13)):getItemById(10029) + or Tile(Position(33671, 32688, 13)):getItemById(10030) -- lever green + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.First, 1) -- red + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Second, 3) -- blue + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Third, 2) -- green + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Four, 4) -- blood + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You hear a whisper: \z + 'You will not be guided but your path shines in the colours red, blue and green. Heed this hierarchy.'") + leverFirst:setActionId(53820 + Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Elements.First)) + leverSecond:setActionId(53820 + Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Second)) + leverThird:setActionId(53820 + Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Third)) + leverFour:setActionId(53824) + end + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Active, 1) + item:transform(9564) + addEvent(activeBasin, 1 * 1000, position) + addEvent(revertBasin, 60 * 60 * 1000, position) + addEvent(revertStorages, 60 * 60 * 1000) + addEvent(revertItem, 60 * 60 * 1000, position, 9564, item.itemid) + return true +end + +redGem:type("stepin") +redGem:aid(53812) +redGem:register() diff --git a/data/scripts/movements/quests/ferumbras_ascendant/seal.lua b/data/scripts/movements/quests/ferumbras_ascendant/seal.lua new file mode 100644 index 00000000000..8d4e379db46 --- /dev/null +++ b/data/scripts/movements/quests/ferumbras_ascendant/seal.lua @@ -0,0 +1,118 @@ +local config = { + [24839] = { + toPosition = Position(33419, 32841, 11), + backPosition = Position(33484, 32775, 12), + timer = Storage.FerumbrasAscension.TarbazTimer + + }, + [24840] = { + toPosition = Position(33452, 32356, 13), + backPosition = Position(33432, 32330, 14), + timer = Storage.FerumbrasAscension.RagiazTimer + }, + [24841] = { + toPosition = Position(33230, 31493, 13), + backPosition = Position(33197, 31438, 13), + timer = Storage.FerumbrasAscension.PlagirathTimer + }, + [24842] = { + toPosition = Position(33380, 32454, 14), + backPosition = Position(33399, 32402, 15), + timer = Storage.FerumbrasAscension.RazzagornTimer + }, + [24843] = { + toPosition = Position(33680, 32736, 11), + backPosition = Position(33664, 32682, 10), + timer = Storage.FerumbrasAscension.ZamuloshTimer + }, + [24844] = { + toPosition = Position(33593, 32658, 14), + backPosition = Position(33675, 32690, 13), + timer = Storage.FerumbrasAscension.MazoranTimer + }, + [24845] = { + toPosition = Position(33436, 32800, 13), + backPosition = Position(33477, 32701, 14), + timer = Storage.FerumbrasAscension.ShulgraxTimer + }, + [24846] = { + toPosition = Position(33270, 31474, 14), + backPosition = Position(33324, 31374, 14), + timer = Storage.FerumbrasAscension.FerumbrasTimer + } +} + +local seal = MoveEvent() + +function seal.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local setting = config[item.actionid] + if not setting then + return true + end + + if item.actionid == 24844 then + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Elements.Done) >= 4 then + if player:getStorageValue(setting.timer) < os.time() then + player:teleportTo(setting.toPosition) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:teleportTo(Position(33675, 32690, 13)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say('You have to wait to challenge this enemy again!', TALKTYPE_MONSTER_SAY) + return true + end + else + local pos = position + pos.y = pos.y + 2 + player:teleportTo(pos) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You not proven your worth. There is no escape for you here.') + item:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + end + if item.actionid == 24845 then + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.FlowerPuzzleTimer) >= 1 then + if player:getStorageValue(setting.timer) < os.time() then + player:teleportTo(setting.toPosition) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:teleportTo(Position(33477, 32701, 14)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say('You have to wait to challenge this enemy again!', TALKTYPE_MONSTER_SAY) + return true + end + else + local pos = position + pos.y = pos.y + 2 + player:teleportTo(pos) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You not proven your worth. There is no escape for you here.') + item:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + end + if player:getStorageValue(setting.timer) < os.time() then + player:teleportTo(setting.toPosition) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + elseif player:getStorageValue(setting.timer) >= os.time() then + player:teleportTo(setting.backPosition) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say('You have to wait to challenge this enemy again!', TALKTYPE_MONSTER_SAY) + elseif item.actionid == 24846 and player:getStorageValue(setting.timer) >= os.time() then + player:say('You cannot enter, you must wait fourteen days after preventing the ascension of Ferumbras.', + TALKTYPE_MONSTER_SAY) + end + return true +end + +seal:type("stepin") + +for index, value in pairs(config) do + seal:aid(index) +end + +seal:register() diff --git a/data/scripts/movements/quests/ferumbras_ascendant/shulgrax_lever.lua b/data/scripts/movements/quests/ferumbras_ascendant/shulgrax_lever.lua new file mode 100644 index 00000000000..f0a74a7a058 --- /dev/null +++ b/data/scripts/movements/quests/ferumbras_ascendant/shulgrax_lever.lua @@ -0,0 +1,24 @@ +local shulgraxLever = MoveEvent() + +function shulgraxLever.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.FlowerPuzzleTimer) >= 1 then + player:teleportTo(Position(33436, 32800, 13)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + local pos = position + pos.y = pos.y + 1 + player:teleportTo(pos) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You not proven your worth. There is no escape for you here.") + item:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +shulgraxLever:type("stepin") +shulgraxLever:aid(34301) +shulgraxLever:register() diff --git a/data/scripts/movements/quests/ferumbras_ascendant/stair.lua b/data/scripts/movements/quests/ferumbras_ascendant/stair.lua new file mode 100644 index 00000000000..a8e419c67de --- /dev/null +++ b/data/scripts/movements/quests/ferumbras_ascendant/stair.lua @@ -0,0 +1,43 @@ +local config = { + [1] = {storage = Storage.FerumbrasAscension.Razzagorn}, + [2] = {storage = Storage.FerumbrasAscension.Ragiaz}, + [3] = {storage = Storage.FerumbrasAscension.Zamulosh}, + [4] = {storage = Storage.FerumbrasAscension.Mazoran}, + [5] = {storage = Storage.FerumbrasAscension.Tarbaz}, + [6] = {storage = Storage.FerumbrasAscension.Shulgrax}, + [7] = {storage = Storage.FerumbrasAscension.Plagirath} +} + +local stair = MoveEvent() + +function stair.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + if item:getId() == 24813 then + local complete = false + for i = 1, #config do + local storage = config[i].storage + if player:getStorageValue(storage) ~= 1 then + complete = false + else + complete = true + end + end + if complete then + player:teleportTo(Position(33271, 32396, 9)) + else + player:teleportTo(Position(33271, 32396, 8)) + end + player:setDirection(SOUTH) + elseif item:getId() == 24812 then + player:teleportTo(Position(33271, 32394, 7)) + player:setDirection(NORTH) + end + return true +end + +stair:type("stepin") +stair:id(24812, 24813) +stair:register() diff --git a/data/scripts/movements/quests/ferumbras_ascendant/vortex.lua b/data/scripts/movements/quests/ferumbras_ascendant/vortex.lua new file mode 100644 index 00000000000..482ca6f9564 --- /dev/null +++ b/data/scripts/movements/quests/ferumbras_ascendant/vortex.lua @@ -0,0 +1,24 @@ +local vortex = MoveEvent() + +function vortex.onStepIn(creature, item, position, fromPosition) + local monster = creature:getMonster() + if not monster or monster:getName():lower() ~= 'ferumbras essence' then + return true + end + + monster:remove() + position:sendMagicEffect(CONST_ME_POFF) + Game.setStorageValue(GlobalStorage.FerumbrasAscendant.FerumbrasEssence, + Game.getStorageValue(GlobalStorage.FerumbrasAscendant.FerumbrasEssence) + 1) + if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.FerumbrasEssence) >= 8 then + Game.createMonster('Destabilized Ferumbras', Position(33392, 31473, 14), true, true) + for i = 1, 20 do + Game.createMonster('Rift Fragment', Position(math.random(33381, 33403), math.random(31462, 31483), 14), true, true) + end + end + return true +end + +vortex:type("stepin") +vortex:id(22455) +vortex:register() diff --git a/data/scripts/movements/quests/ferumbras_ascendant/zamulosh_teleport.lua b/data/scripts/movements/quests/ferumbras_ascendant/zamulosh_teleport.lua new file mode 100644 index 00000000000..ed31cc8841d --- /dev/null +++ b/data/scripts/movements/quests/ferumbras_ascendant/zamulosh_teleport.lua @@ -0,0 +1,47 @@ +local zamuloshTeleport = MoveEvent() + +function zamuloshTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if item.actionid == 34313 then + if player:getStorageValue(Storage.FerumbrasAscension.ZamuloshTeleports) >= 9 then + player:teleportTo(Position(33618, 32620, 10)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + "What was wrong is not necessarily right now. Nevertheless you nade it further.") + return true + else + local pos = player:getPosition() + pos.x = pos.x - 2 + player:teleportTo(pos) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You don't have access to this teleport yet.") + return true + end + elseif item.actionid == 34314 then + if player:getStorageValue(Storage.FerumbrasAscension.ZamuloshTeleports) >= 4 + and Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.AllHabitats) >= 8 then + player:teleportTo(Position(33618, 32620, 10)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + "What was wrong is not necessarily right now. Nevertheless you nade it further.") + player:setStorageValue(Storage.FerumbrasAscension.ZamuloshTeleports, 9) + return true + else + local pos = player:getPosition() + pos.x = pos.x - 2 + player:teleportTo(pos) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You don't have access to this teleport yet.") + return true + end + end + return true +end + +zamuloshTeleport:type("stepin") +zamuloshTeleport:aid(34313, 34314) +zamuloshTeleport:register() diff --git a/data/scripts/movements/quests/feyrist/kroazur_entrance.lua b/data/scripts/movements/quests/feyrist/kroazur_entrance.lua new file mode 100644 index 00000000000..e552f67d587 --- /dev/null +++ b/data/scripts/movements/quests/feyrist/kroazur_entrance.lua @@ -0,0 +1,58 @@ +local config = { + [24900] = { + timer = Storage.ThreatenedDreams.KroazurTimer, + range = 20, + newPos = Position(33591, 32315, 10), + bossName = 'Kroazur', + bossPos = Position(33591, 32305, 10) + } +} + +local kroazurEntrance = MoveEvent() + +function kroazurEntrance.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + + local teleport = config[item.actionid] + if not teleport then + return + end + + if player:getStorageValue(teleport.timer) > os.time() then + position:sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(fromPosition, true) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say('You have to wait to challenge this enemy again!', TALKTYPE_MONSTER_SAY) + return true + end + + if roomIsOccupied(teleport.bossPos, teleport.range, teleport.range) then + position:sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(fromPosition, true) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say('Someone is fighting against the boss! You need wait awhile.', TALKTYPE_MONSTER_SAY) + return true + end + clearRoom(teleport.bossPos, teleport.range, teleport.range, fromPosition) + local monster = Game.createMonster(teleport.bossName, teleport.bossPos, true, true) + if not monster then + return true + end + + position:sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(teleport.newPos) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say( + 'You have ten minutes to kill and loot this boss. \z + Otherwise you will lose that chance and will be kicked out.', TALKTYPE_MONSTER_SAY) + addEvent(clearBossRoom, 60 * 10 * 1000, player.uid, monster.uid, teleport.bossPos, teleport.range, teleport.range, fromPosition) + player:setStorageValue(teleport.timer, os.time() + 2 * 3600) + return true +end + +kroazurEntrance:type("stepin") +kroazurEntrance:aid(24900) +kroazurEntrance:register() diff --git a/data/scripts/movements/quests/feyrist/kroazur_exit.lua b/data/scripts/movements/quests/feyrist/kroazur_exit.lua new file mode 100644 index 00000000000..421e833b7d3 --- /dev/null +++ b/data/scripts/movements/quests/feyrist/kroazur_exit.lua @@ -0,0 +1,26 @@ +local config = { + [24901] = {backPos = Position(33619, 32306, 9) + } +} + +local kroazurExit = MoveEvent() + +function kroazurExit.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local teleport = config[item.actionid] + if not teleport then + return true + end + position:sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(teleport.backPos) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +kroazurExit:type("stepin") +kroazurExit:aid(24901) +kroazurExit:register() diff --git a/data/scripts/movements/quests/first_dragon/entrance_teleport.lua b/data/scripts/movements/quests/first_dragon/entrance_teleport.lua new file mode 100644 index 00000000000..8582692cc09 --- /dev/null +++ b/data/scripts/movements/quests/first_dragon/entrance_teleport.lua @@ -0,0 +1,101 @@ +local UniqueTable = { + -- Tazhadur entrance + [35001] = { + storage = Storage.FirstDragon.DragonCounter, + value = 200, + range = 10, + timer = Storage.FirstDragon.TazhadurTimer, + newPos = {x = 32015, y = 32466, z = 8}, + bossName = "Tazhadur", + bossPos = {x = 32018, y = 32465, z = 8} + }, + -- Kalyassa entrance + [35002] = { + storage = Storage.FirstDragon.ChestCounter, + value = 5, + range = 10, + timer = Storage.FirstDragon.KalyassaTimer, + newPos = {x = 32078, y = 32456, z = 8}, + bossName = "Kalyassa", + bossPos = {x = 32079, y = 32459, z = 8} + }, + -- Zorvorax entrance + [35003] = { + storage = Storage.FirstDragon.SecretsCounter, + value = 3, + range = 10, + timer = Storage.FirstDragon.ZorvoraxTimer, + newPos = {x = 32008, y = 32396, z = 8}, + bossName = "Zorvorax", + bossPos = {x = 32015, y = 32396, z = 8} + }, + -- Gelidrazah entrance + [35004] = { + storage = Storage.FirstDragon.GelidrazahAccess, + value = 1, + range = 10, + timer = Storage.FirstDragon.GelidrazahTimer, + newPos = {x = 32076, y = 32402, z = 8}, + bossName = "Gelidrazah The Frozen", + bossPos = {x = 32078, y = 32400, z = 8} + } +} + +local entranceTeleport = MoveEvent() +function entranceTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + + local setting = UniqueTable[item.uid] + if not setting then + return true + end + + if roomIsOccupied(setting.bossPos, setting.range, setting.range) then + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(fromPosition) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say("Someone is fighting against the boss! You need wait a while.", TALKTYPE_MONSTER_SAY) + return true + end + + if player:getStorageValue(setting.timer) >= os.time() then + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(fromPosition) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say("You have to wait to challenge this enemy again!", TALKTYPE_MONSTER_SAY) + return true + end + + if player:getStorageValue(Storage.FirstDragon.Questline) < 1 or player:getStorageValue(setting.storage) < setting.value then + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(fromPosition) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say("You don't have permission to use this portal", TALKTYPE_MONSTER_SAY) + return true + end + + if player:getStorageValue(setting.storage) >= setting.value then + local monster = Game.createMonster(setting.bossName, setting.bossPos, true, true) + if not monster then + return true + end + + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(setting.newPos) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say("You have ten minutes to kill and loot this boss. Otherwise you will lose that chance and will be kicked out.", TALKTYPE_MONSTER_SAY) + player:setStorageValue(setting.timer, os.time() + 2 * 3600) + addEvent(clearBossRoom, 60 * 30 * 1000, player.uid, monster.uid, setting.bossPos, setting.range, fromPosition) + return true + end + return true +end + +for index, value in pairs(UniqueTable) do + entranceTeleport:uid(index) +end + +entranceTeleport:register() diff --git a/data/scripts/movements/quests/first_dragon/exit_teleport.lua b/data/scripts/movements/quests/first_dragon/exit_teleport.lua new file mode 100644 index 00000000000..dc004d7c345 --- /dev/null +++ b/data/scripts/movements/quests/first_dragon/exit_teleport.lua @@ -0,0 +1,40 @@ +local UniqueTable = { + -- Tazhadur exit + [35005] = { + backPos = {x = 33234, y = 32278, z = 12} + }, + -- Kalyassa exit + [35006] = { + backPos = {x = 33162, y = 31320, z = 5} + }, + -- Zorvorax exit + [35007] = { + backPos = {x = 33002, y = 31595, z = 11} + }, + -- Gelidrazah exit + [35008] = { + backPos = {x = 32278, y = 31367, z = 4} + } +} + +local exitTeleport = MoveEvent() +function exitTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local setting = UniqueTable[item.uid] + if not setting then + return true + end + player:teleportTo(setting.backPos) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +for index, value in pairs(UniqueTable) do + exitTeleport:uid(index) +end + +exitTeleport:register() diff --git a/data/scripts/movements/quests/first_dragon/flower_bowl.lua b/data/scripts/movements/quests/first_dragon/flower_bowl.lua new file mode 100644 index 00000000000..976b2e31a2c --- /dev/null +++ b/data/scripts/movements/quests/first_dragon/flower_bowl.lua @@ -0,0 +1,19 @@ +local flowerBowl = MoveEvent() + +function flowerBowl.onStepIn(creature, item, position, fromPosition) + if creature:isPlayer() then + return true + end + + if item.uid == 1066 then + if creature:getName() == 'Unbeatable Dragon' then + creature:say('An allergic reaction weakens the dragon!', TALKTYPE_MONSTER_SAY) + creature:remove() + Game.createMonster('Somewhat Beatable', position, true, true) + end + end + return true +end + +flowerBowl:id(9679) +flowerBowl:register() \ No newline at end of file diff --git a/data/scripts/movements/quests/first_dragon/heaven_blossom.lua b/data/scripts/movements/quests/first_dragon/heaven_blossom.lua new file mode 100644 index 00000000000..565a54dcb04 --- /dev/null +++ b/data/scripts/movements/quests/first_dragon/heaven_blossom.lua @@ -0,0 +1,21 @@ +local heavenBlossom = MoveEvent() + +function heavenBlossom.onStepIn(creature, item, position, fromPosition) + if creature:isPlayer() then + return true + end + + if item.uid == 1066 then + if creature:getName() == 'Spirit of Fertility' then + creature:say('An allergic reaction weakens the dragon!', TALKTYPE_MONSTER_SAY) + creature:remove() + Game.createMonster('Angry Plant', position, true, true) + item:remove() + creature:say('The fertile spirit brings a plant monster to life!', TALKTYPE_MONSTER_SAY) + end + end + return true +end + +heavenBlossom:id(2743) +heavenBlossom:register() \ No newline at end of file diff --git a/data/scripts/movements/quests/first_dragon/last_teleport.lua b/data/scripts/movements/quests/first_dragon/last_teleport.lua new file mode 100644 index 00000000000..0625ede43ba --- /dev/null +++ b/data/scripts/movements/quests/first_dragon/last_teleport.lua @@ -0,0 +1,27 @@ +local lastTeleport = MoveEvent() + +function lastTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + + local setting = UniqueTable[item.uid] + if not setting then + return true + end + + if player:getStorageValue(Storage.FirstDragon.FirstDragonTimer) < os.time() then + position:sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(setting.destination) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:teleportTo(fromPosition, true) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have to wait to challenge The First Dragon again!") + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +lastTeleport:uid(24894) +lastTeleport:register() diff --git a/data/scripts/movements/quests/first_dragon/zorvorax_secrets.lua b/data/scripts/movements/quests/first_dragon/zorvorax_secrets.lua new file mode 100644 index 00000000000..fc92bcc81f5 --- /dev/null +++ b/data/scripts/movements/quests/first_dragon/zorvorax_secrets.lua @@ -0,0 +1,45 @@ +local UniqueTable = { + [25002] = { + storage = Storage.FirstDragon.DesertTile, + msg = "You enter the beautiful oasis. \ + By visiting this sacred site you're infused with the power of water bringing life to the desert." + }, + [25003] = { + storage = Storage.FirstDragon.StoneSculptureTile, + msg = "You enter the circle of trees and flowers. \ + By visiting this sacred site you're infused with the power of nature and plants." + }, + [25004] = { + storage = Storage.FirstDragon.SuntowerTile, + msg = "You entered the suntower of Ab'dendriel. \ + By visiting this sacred site you're infused with the power of the life-giving sun." + } +} + +local zorvoraxSecrets = MoveEvent() + +function zorvoraxSecrets.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local setting = UniqueTable[item.actionid] + if not setting then + return true + end + + if player:getStorageValue(setting.storage) < 1 then + player:setStorageValue(setting.storage, 1) + player:setStorageValue(Storage.FirstDragon.SecretsCounter, player:getStorageValue(Storage.FirstDragon.SecretsCounter) + 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, setting.msg) + return true + end + return true +end + +for index, value in pairs(UniqueTable) do + zorvoraxSecrets:aid(index) +end + +zorvoraxSecrets:register() diff --git a/data/scripts/movements/quests/forgotten_knowledge/cave_entrance.lua b/data/scripts/movements/quests/forgotten_knowledge/cave_entrance.lua new file mode 100644 index 00000000000..bc80358e31d --- /dev/null +++ b/data/scripts/movements/quests/forgotten_knowledge/cave_entrance.lua @@ -0,0 +1,20 @@ +local caveEntrance = MoveEvent() + +function caveEntrance.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + local pos = item:getPosition() + if pos.z == 5 then + player:teleportTo(Position(33515, 31103, 8)) + elseif pos.z == 8 then + player:teleportTo(Position(33334, 31151, 5)) + end + player:setDirection(SOUTH) + return true +end + +caveEntrance:type("stepin") +caveEntrance:id(26403) +caveEntrance:register() diff --git a/data/scripts/movements/quests/forgotten_knowledge/challenger.lua b/data/scripts/movements/quests/forgotten_knowledge/challenger.lua new file mode 100644 index 00000000000..7646339fe6a --- /dev/null +++ b/data/scripts/movements/quests/forgotten_knowledge/challenger.lua @@ -0,0 +1,74 @@ +local destination = { + [1067] = { + newPos = Position(32903, 31630, 14), + backPos = Position(32915, 31639, 14), + storage = Storage.ForgottenKnowledge.LadyTenebrisTimer + }, + [1068] = { + newPos = Position(32658, 32885, 14), + backPos = Position(32678, 32888, 14), + storage = Storage.ForgottenKnowledge.ThornKnightTimer + }, + [1069] = { + newPos = Position(33391, 31184, 10), + backPos = Position(33407, 31172, 10), + storage = Storage.ForgottenKnowledge.DragonkingTimer + }, + [1070] = { + newPos = Position(32302, 31095, 14), + backPos = Position(32318, 31091, 14), + storage = Storage.ForgottenKnowledge.HorrorTimer + }, + [1071] = { + newPos = Position(33026, 31663, 14), + backPos = Position(32849, 32691, 15), + storage = Storage.ForgottenKnowledge.TimeGuardianTimer + }, + [1072] = { + newPos = Position(32019, 32851, 14), + backPos = Position(32035, 32859, 14), + storage = Storage.ForgottenKnowledge.LastLoreTimer + } +} + +local challenger = MoveEvent() + +function challenger.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + + local teleport = destination[item.uid] + if not teleport then + return + end + if player:getStorageValue(teleport.storage) <= os.time() then + if item.uid == 24882 then + if player:getStorageValue(Storage.ForgottenKnowledge.BabyDragon) < 1 then + player:teleportTo(teleport.backPos) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You not have permission to use this teleport!") + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + end + position:sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(teleport.newPos) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + else + player:teleportTo(teleport.backPos) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have to wait to challenge this enemy again!") + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + return true +end + +challenger:type("stepin") + +for index, value in pairs(destination) do + challenger:uid(index) +end + +challenger:register() diff --git a/data/scripts/movements/quests/forgotten_knowledge/dragonking_vortex.lua b/data/scripts/movements/quests/forgotten_knowledge/dragonking_vortex.lua new file mode 100644 index 00000000000..a586c74ddb4 --- /dev/null +++ b/data/scripts/movements/quests/forgotten_knowledge/dragonking_vortex.lua @@ -0,0 +1,60 @@ +local function functionBack() + local soul, diference, health = false, 0, 0 + local spectators, spectator = Game.getSpectators(Position(33358, 31183, 11), false, false, 15, 15, 15, 15) + for v = 1, #spectators do + spectator = spectators[v] + if spectator:getName():lower() == 'soul of dragonking zyrtarch' then + soul = true + end + end + + local dragonking = Tile(Position(33359, 31182, 12)):getTopCreature() + if not soul then + dragonking:remove() + return true + end + + local specs, spec = Game.getSpectators(Position(33358, 31183, 11), false, false, 15, 15, 15, 15) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + spec:teleportTo(Position(33358, 31183, 10)) + elseif spec:isMonster() and spec:getName():lower() == 'soul of dragonking zyrtarch' then + spec:teleportTo(Position(33359, 31182, 12)) + health = spec:getHealth() + diference = dragonking:getHealth() - health + end + end + dragonking:addHealth( - diference) + dragonking:teleportTo(Position(33358, 31183, 10)) +end + +local function removeVortex(position) + local vortex = Tile(position):getItemById(26580) + if vortex then + vortex:remove() + end +end + +local dragonkingVortex = MoveEvent() + +function dragonkingVortex.onStepIn(creature, item, position, fromPosition) + if creature:isMonster() and creature:getName():lower() ~= 'dragonking zyrtarch' then + return true + end + if creature:isPlayer() then + creature:teleportTo(Position(33357, 31183, 11)) + end + if creature:getName():lower() == 'dragonking zyrtarch' then + local soul = Tile(Position(33359, 31182, 12)):getTopCreature() + creature:teleportTo(Position(33359, 31182, 12)) + soul:teleportTo(Position(33358, 31183, 11)) + addEvent(functionBack, 30 * 1000) + addEvent(removeVortex, 15 * 1000, position) + end + return true +end + +dragonkingVortex:type("stepin") +dragonkingVortex:id(26396) +dragonkingVortex:register() diff --git a/data/scripts/movements/quests/forgotten_knowledge/entrance_teleport.lua b/data/scripts/movements/quests/forgotten_knowledge/entrance_teleport.lua new file mode 100644 index 00000000000..d1dc0c0796c --- /dev/null +++ b/data/scripts/movements/quests/forgotten_knowledge/entrance_teleport.lua @@ -0,0 +1,123 @@ +local destination = { + [27715] = { + newPos = Position(32807, 31657, 8), + storage = Storage.ForgottenKnowledge.AccessDeath, + effect = CONST_ME_MORTAREA + }, + [27716] = { + newPos = Position(32325, 32089,7), + storage = Storage.ForgottenKnowledge.AccessDeath, + effect = CONST_ME_MORTAREA + }, + [27719] = { + newPos = Position(32786, 32820, 13), + storage = Storage.ForgottenKnowledge.AccessViolet, + effect = CONST_ME_PURPLEENERGY + }, + [27720] = { + newPos = Position(32328, 32089,7), + storage = Storage.ForgottenKnowledge.AccessViolet, + effect = CONST_ME_PURPLEENERGY + }, + [27717] = { + newPos = Position(32637, 32256, 7), + storage = Storage.ForgottenKnowledge.AccessEarth, + effect = CONST_ME_SMALLPLANTS + }, + [27718] = { + newPos = Position(32331, 32089, 7), + storage = Storage.ForgottenKnowledge.AccessEarth, + effect = CONST_ME_SMALLPLANTS + }, + [27721] = { + newPos = Position(33341, 31168, 7), + storage = Storage.ForgottenKnowledge.AccessFire, + effect = CONST_ME_FIREAREA + }, + [27722] = { + newPos = Position(32334, 32089,7), + storage = Storage.ForgottenKnowledge.AccessFire, + effect = CONST_ME_FIREAREA + }, + [27725] = { + newPos = Position(32207, 31036, 10), + storage = Storage.ForgottenKnowledge.AccessIce, + effect = CONST_ME_ICEATTACK + }, + [27726] = { + newPos = Position(32337, 32089,7), + storage = Storage.ForgottenKnowledge.AccessIce, + effect = CONST_ME_ICEATTACK + }, + [27723] = { + newPos = Position(32780, 32686, 14), + storage = Storage.ForgottenKnowledge.AccessGolden, + effect = CONST_ME_YELLOWENERGY + }, + [27724] = { + newPos = Position(32340, 32089, 7), + storage = Storage.ForgottenKnowledge.AccessGolden, + effect = CONST_ME_YELLOWENERGY + }, + [11796] = { + newPos = Position(32907, 32848, 13), + storage = Storage.ForgottenKnowledge.AccessLast, + effect = CONST_ME_ENERGYHIT + }, + [11798] = { + newPos = Position(32332, 32092, 7), + storage = Storage.ForgottenKnowledge.AccessLast, + effect = CONST_ME_ENERGYHIT} +} + +local entranceTeleport = MoveEvent() + +function entranceTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + + local teleport = destination[item.itemid] + if not teleport then + return + end + if item.itemid == 11796 then + if player:getStorageValue(Storage.ForgottenKnowledge.AccessLast) < 1 then + if player:getStorageValue(Storage.ForgottenKnowledge.LadyTenebrisKilled) >= 1 + and player:getStorageValue(Storage.ForgottenKnowledge.LloydKilled) >= 1 + and player:getStorageValue(Storage.ForgottenKnowledge.ThornKnightKilled) >= 1 + and player:getStorageValue(Storage.ForgottenKnowledge.DragonkingKilled) >= 1 + and player:getStorageValue(Storage.ForgottenKnowledge.HorrorKilled) >= 1 + and player:getStorageValue(Storage.ForgottenKnowledge.TimeGuardianKilled) >= 1 then + player:setStorageValue(Storage.ForgottenKnowledge.AccessLast, 1) + end + end + end + if player:getStorageValue(teleport.storage) >= 1 then + position:sendMagicEffect(teleport.effect) + player:teleportTo(teleport.newPos) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + else + if item.itemid == 11796 then + player:teleportTo(fromPosition) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You don\'t have the permission to use this portal.") + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + local pos = position + pos.y = pos.y + 2 + player:teleportTo(pos) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You don\'t have the permission to use this portal.") + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + pos.y = pos.y - 2 + pos:sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + + +entranceTeleport:type("stepin") +entranceTeleport:aid(24873) +entranceTeleport:register() diff --git a/data/scripts/movements/quests/forgotten_knowledge/fount.lua b/data/scripts/movements/quests/forgotten_knowledge/fount.lua new file mode 100644 index 00000000000..2d4d69cdc65 --- /dev/null +++ b/data/scripts/movements/quests/forgotten_knowledge/fount.lua @@ -0,0 +1,21 @@ +local fount = MoveEvent() + +function fount.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + if player:getStorageValue(Storage.ForgottenKnowledge.Phial) >= 1 then + player:teleportTo(Position(32722, 32242, 8)) + player:getPosition():sendMagicEffect(CONST_ME_WATERSPLASH) + return true + else + player:teleportTo(Position(32614, 32269, 7)) + player:getPosition():sendMagicEffect(CONST_ME_WATERSPLASH) + end + return true +end + +fount:type("stepin") +fount:id(27803, 27804, 27805, 27806) +fount:register() diff --git a/data/scripts/movements/quests/forgotten_knowledge/ice_teleport.lua b/data/scripts/movements/quests/forgotten_knowledge/ice_teleport.lua new file mode 100644 index 00000000000..e23888ca883 --- /dev/null +++ b/data/scripts/movements/quests/forgotten_knowledge/ice_teleport.lua @@ -0,0 +1,38 @@ +local destination = { + [26667] = { + position = Position(32273, 31053, 13), + storage = Storage.ForgottenKnowledge.AccessMachine + } +} + +local iceTeleport = MoveEvent() + +function iceTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + + local teleport = destination[item.actionid] + if not teleport then + return + end + + if player:getStorageValue(teleport.storage) >= 1 then + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(teleport.position) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + local pos = position + item:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + pos.x = pos.x + 1 + player:teleportTo(pos) + player:say("You haven't permission to use this teleport.", TALKTYPE_MONSTER_SAY, false, nil, position) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +iceTeleport:type("stepin") +iceTeleport:aid(26667) +iceTeleport:register() diff --git a/data/scripts/movements/quests/forgotten_knowledge/lava_teleport.lua b/data/scripts/movements/quests/forgotten_knowledge/lava_teleport.lua new file mode 100644 index 00000000000..5256fe9f1a0 --- /dev/null +++ b/data/scripts/movements/quests/forgotten_knowledge/lava_teleport.lua @@ -0,0 +1,38 @@ +local destination = { + [26668] = { + position = Position(33411, 31082, 10), + storage = Storage.ForgottenKnowledge.AccessLavaTeleport + } +} + +local lavaTeleport = MoveEvent() + +function lavaTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + + local teleport = destination[item.actionid] + if not teleport then + return + end + + if player:getStorageValue(teleport.storage) >= 1 then + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(teleport.position) + player:getPosition():sendMagicEffect(CONST_ME_FIREAREA) + else + local pos = position + item:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + pos.y = pos.y - 2 + player:teleportTo(pos) + player:say("You haven't permission to use this teleport.", TALKTYPE_MONSTER_SAY, false, nil, position) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +lavaTeleport:type("stepin") +lavaTeleport:aid(26668) +lavaTeleport:register() diff --git a/data/scripts/movements/quests/forgotten_knowledge/servant_teleport.lua b/data/scripts/movements/quests/forgotten_knowledge/servant_teleport.lua new file mode 100644 index 00000000000..237860be73d --- /dev/null +++ b/data/scripts/movements/quests/forgotten_knowledge/servant_teleport.lua @@ -0,0 +1,33 @@ +local servantTeleport = MoveEvent() + +function servantTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + + if player:getStorageValue(Storage.ForgottenKnowledge.LloydTimer) >= os.time() then + player:teleportTo(Position(32815, 32872, 13)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + position:sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have to wait to challenge this enemy again!") + return true + end + if player:getStorageValue(Storage.ForgottenKnowledge.GoldenServantCounter) >= 5 + and player:getStorageValue(Storage.ForgottenKnowledge.DiamondServantCounter) >= 5 then + player:teleportTo(Position(32760, 32876, 14)) + player:getPosition():sendMagicEffect(CONST_ME_ENERGYHIT) + return true + else + player:teleportTo(Position(32815, 32872, 13)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + position:sendMagicEffect(CONST_ME_TELEPORT) + player:say('Seems that you don\'t absorb enough energy to use this portal.', + TALKTYPE_MONSTER_SAY, false, nil, position) + end + return true +end + +servantTeleport:type("stepin") +servantTeleport:aid(26665) +servantTeleport:register() diff --git a/data/scripts/movements/quests/forgotten_knowledge/teleport_tree.lua b/data/scripts/movements/quests/forgotten_knowledge/teleport_tree.lua new file mode 100644 index 00000000000..2ea714ce48b --- /dev/null +++ b/data/scripts/movements/quests/forgotten_knowledge/teleport_tree.lua @@ -0,0 +1,25 @@ +local teleportTree = MoveEvent() + +function teleportTree.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + + if player:getStorageValue(Storage.ForgottenKnowledge.PlantCounter) < 5 + or player:getStorageValue(Storage.ForgottenKnowledge.BirdCounter) < 3 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You don't help in anything to enter here") + player:teleportTo(Position(32737, 32117, 10)) + position:sendMagicEffect(CONST_ME_TELEPORT) + player:setDirection(SOUTH) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + player:teleportTo(Position(32720, 32927, 14)) + player:getPosition():sendMagicEffect(CONST_ME_SMALLPLANTS) + return true +end + +teleportTree:type("stepin") +teleportTree:aid(27830) +teleportTree:register() diff --git a/data/scripts/movements/quests/formogar_mine_hoist/hoist.lua b/data/scripts/movements/quests/formogar_mine_hoist/hoist.lua new file mode 100644 index 00000000000..ed2742fdd1a --- /dev/null +++ b/data/scripts/movements/quests/formogar_mine_hoist/hoist.lua @@ -0,0 +1,32 @@ +local hoist = MoveEvent() + +function hoist.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.QuestChests.FormorgarMinesHoistSkeleton) ~= 1 + or player:getStorageValue(Storage.QuestChests.FormorgarMinesHoistChest) ~= 1 then + player:teleportTo(fromPosition) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You must first find the hoist instruction before using it.') + return true + end + + if table.contains({3059, 3061}, item.uid) then + player:teleportTo(Position(32157, 31125, 10)) + elseif item.uid == 3060 then + if Tile(Position(32156, 31125, 10)):getItemById(1945) then + player:teleportTo(Position(32157, 31125, 11)) + else + player:teleportTo(Position(32157, 31125, 9)) + end + end + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +hoist:type("stepin") +hoist:uid(3059, 3060, 3061) +hoist:register() diff --git a/data/scripts/movements/quests/grimvale/silvered_trap.lua b/data/scripts/movements/quests/grimvale/silvered_trap.lua new file mode 100644 index 00000000000..356b438770a --- /dev/null +++ b/data/scripts/movements/quests/grimvale/silvered_trap.lua @@ -0,0 +1,22 @@ +local silveredTrap = MoveEvent() + +function silveredTrap.onStepIn(creature, item, position, fromPosition) + local monster = creature:getMonster() + if not monster then + return true + end + + if monster:getName():lower() ~= "feroxa" then + return true + end + if monster:getMaxHealth() == 50000 then + doTargetCombatHealth(0, monster, COMBAT_UNDEFINEDDAMAGE, -1000, -1000, CONST_ME_DRAWBLOOD) + end + item:transform(24730) + position:sendMagicEffect(CONST_ME_BLOCKHIT) + return true +end + +silveredTrap:type("stepin") +silveredTrap:id(24715) +silveredTrap:register() diff --git a/data/scripts/movements/quests/grimvale/strangely_glowing_mark.lua b/data/scripts/movements/quests/grimvale/strangely_glowing_mark.lua new file mode 100644 index 00000000000..0a1ff016153 --- /dev/null +++ b/data/scripts/movements/quests/grimvale/strangely_glowing_mark.lua @@ -0,0 +1,35 @@ +local condition = Condition(CONDITION_HASTE) +condition:setParameter(CONDITION_PARAM_TICKS, 22000) +condition:setFormula(0.7, -56, 0.7, -56) + +local strangelyGlowingMark = MoveEvent() + +function strangelyGlowingMark.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if item.itemid == 24732 then + if player:getStorageValue(199990) >= os.time() then + return true + end + player:addHealth(200, true, true) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The mythic fires beneath your feet heal you.") + player:setStorageValue(199990, os.time() + 60) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + elseif item.itemid == 24733 then + if player:getStorageValue(199991) >= os.time() then + return true + end + player:addCondition(condition) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:setStorageValue(199991, os.time() + 60) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The mythic fires beneath your feet gave you speed.") + end + return true +end + +strangelyGlowingMark:type("stepin") +strangelyGlowingMark:id(24732, 24733) +strangelyGlowingMark:register() diff --git a/data/scripts/movements/quests/heart_of_destruction/teleport.lua b/data/scripts/movements/quests/heart_of_destruction/teleport.lua new file mode 100644 index 00000000000..101cecc28c2 --- /dev/null +++ b/data/scripts/movements/quests/heart_of_destruction/teleport.lua @@ -0,0 +1,38 @@ +local setting = { + [48060] = Position(32017, 31357, 11), -- from edron + [48061] = Position(33183, 31643, 8), -- to edron + [48062] = Position(32522, 32020, 8), -- to kazz + [48063] = Position(32448, 32389, 10), -- from kazz + [48064] = Position(33158, 32636, 8), -- to ankrah + [48065] = Position(32130, 31359, 12), -- from ankrah + [48066] = Position(32159, 31294, 7), -- to svargrond + [48067] = Position(32113, 31386, 11), -- from svargrond + [48068] = Position(33026, 31367, 8), -- to farmine + [48069] = Position(32117, 31355, 13) -- from farmine +} + +local teleport = MoveEvent() + +function teleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local targetPosition = setting[item.actionid] + if not targetPosition then + return true + end + + player:teleportTo(targetPosition) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +teleport:type("stepin") + +for index, value in pairs(setting) do + teleport:aid(index) +end + +teleport:register() diff --git a/data/scripts/movements/quests/heart_of_destruction/teleport_heart.lua b/data/scripts/movements/quests/heart_of_destruction/teleport_heart.lua new file mode 100644 index 00000000000..33dc1f579b3 --- /dev/null +++ b/data/scripts/movements/quests/heart_of_destruction/teleport_heart.lua @@ -0,0 +1,125 @@ +local vortex = { + [14321] = Position(32149, 31359, 14), -- Charger TP 1 + [14322] = Position(32092, 31330, 12), -- Charger Exit + [14324] = Position(32104, 31329, 12), -- Anomaly Exit + [14325] = Position(32216, 31380, 14), -- Main Room + [14340] = Position(32159, 31329, 11), -- Main Room Exit + [14341] = Position(32078, 31320, 13), -- Cracklers Exit + [14343] = Position(32088, 31321, 13), -- Rupture Exit + [14345] = Position(32230, 31358, 11), -- Realityquake Exit + [14347] = Position(32225, 31347, 11), -- Unstable Sparks Exit + [14348] = Position(32218, 31375, 14), -- Eradicator Exit (Main Room) + [14350] = Position(32208, 31372, 14), -- Outburst Exit (Main Room) + [14352] = Position(32214, 31376, 14), -- World Devourer Exit (Main Room) + [14354] = Position(32112, 31375, 14), -- World Devourer (Reward Room) +} + +local accessVortex = { + -- Anomaly enter + [14323] = { + position = Position(32246, 31252, 14), + storage = 14320, + storageTime = 14321 + }, + -- Rupture enter + [14342] = { + position = Position(32305, 31249, 14), + storage = 14322, + storageTime = 14323 + }, + -- Realityquake enter + [14344] = { + position = Position(32181, 31240, 14), + storage = 14324, + storageTime = 14325 + }, +} + +local finalBosses = { + -- Eradicator enter + [14346] = { + position = Position(32336, 31293, 14), + storage1 = 14326, + storage2 = 14327, + storage3 = 14328, + storageTime = 14329 + }, + -- Outburst enter + [14349] = { + position = Position(32204, 31290, 14), + storage1 = 14326, + storage2 = 14327, + storage3 = 14328, + storageTime = 14331 + } +} + +local teleportHeart = MoveEvent() + +function teleportHeart.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local normalVortex = vortex[item.actionid] + local bossVortex = accessVortex[item.actionid] + local uBosses = finalBosses[item.actionid] + if normalVortex then + player:teleportTo(normalVortex) + elseif bossVortex then + if player:getStorageValue(bossVortex.storage) >= 1 then + if player:getStorageValue(bossVortex.storageTime) < os.time() then + player:teleportTo(bossVortex.position) + else + player:teleportTo(fromPosition) + player:sendTextMessage(19, "It's too early for you to endure this challenge again.") + end + else + player:teleportTo(fromPosition) + player:sendTextMessage(19, "You don't have access to this portal.") + end + elseif uBosses then + if player:getStorageValue(uBosses.storage1) >= 1 + and player:getStorageValue(uBosses.storage2) >= 1 + and player:getStorageValue(uBosses.storage3) >= 1 then + if player:getStorageValue(uBosses.storageTime) < os.time() then + player:teleportTo(uBosses.position) + else + player:teleportTo(fromPosition) + player:sendTextMessage(19, "It's too early for you to endure this challenge again.") + end + else + player:teleportTo(fromPosition) + player:sendTextMessage(19, "You don't have access to this portal.") + end + elseif item.actionid == 14351 then + if player:getStorageValue(14330) >= 1 + and player:getStorageValue(14332) >= 1 then + if player:getStorageValue(14333) < os.time() then + player:teleportTo(Position(32272, 31384, 14)) + else + player:teleportTo(fromPosition) + player:sendTextMessage(19, "It's too early for you to endure this challenge again.") + end + else + player:teleportTo(fromPosition) + player:sendTextMessage(19, "You don't have access to this portal.") + end + elseif item.actionid == 14353 then -- Remove storages from mini bosses + player:teleportTo(Position(32214, 31376, 14)) + player:setStorageValue(14334, -1) + player:setStorageValue(14335, -1) + player:setStorageValue(14336, -1) + player:unregisterEvent("DevourerStorage") + end + return true +end + +teleportHeart:type("stepin") + +for index, value in pairs(vortex) do + teleportHeart:aid(index) +end + +teleportHeart:register() diff --git a/data/scripts/movements/quests/heart_of_destruction/vortex_anomaly.lua b/data/scripts/movements/quests/heart_of_destruction/vortex_anomaly.lua new file mode 100644 index 00000000000..6067ef4ed7b --- /dev/null +++ b/data/scripts/movements/quests/heart_of_destruction/vortex_anomaly.lua @@ -0,0 +1,18 @@ +local vortexAnomaly = MoveEvent() + +function vortexAnomaly.onStepIn(creature, item, position, fromPosition) + if item.itemid == 25550 then + if creature:isMonster() then + if creature:getName():lower() == "charged anomaly" then + creature:addHealth(-6000, COMBAT_DROWNDAMAGE) + end + elseif isPlayer(creature) then + creature:addHealth(-100, COMBAT_ENERGYDAMAGE) + end + end + return true +end + +vortexAnomaly:type("stepin") +vortexAnomaly:id(25550) +vortexAnomaly:register() diff --git a/data/scripts/movements/quests/heart_of_destruction/vortex_crackler.lua b/data/scripts/movements/quests/heart_of_destruction/vortex_crackler.lua new file mode 100644 index 00000000000..f82756ec21c --- /dev/null +++ b/data/scripts/movements/quests/heart_of_destruction/vortex_crackler.lua @@ -0,0 +1,102 @@ +local positions1 = { + {x = 32197, y = 31322, z = 14}, + {x = 32202, y = 31328, z = 14}, + {x = 32208, y = 31324, z = 14}, + {x = 32210, y = 31334, z = 14}, +} + +local positions2 = { + {x = 32202, y = 31325, z = 14}, + {x = 32201, y = 31334, z = 14}, + {x = 32215, y = 31332, z = 14}, + {x = 32208, y = 31320, z = 14}, +} + +local positions3 = { + {x = 32199, y = 31329, z = 14}, + {x = 32207, y = 31335, z = 14}, + {x = 32208, y = 31327, z = 14}, + {x = 32213, y = 31322, z = 14}, +} + +local positions4 = { + {x = 32203, y = 31319, z = 14}, + {x = 32205, y = 31325, z = 14}, + {x = 32212, y = 31330, z = 14}, + {x = 32219, y = 31328, z = 14}, +} + +local vortexCrackler = MoveEvent() + +function vortexCrackler.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if item.itemid == 26127 then + if vortexPositions == 1 then + local storePlayers, playerTile = {} + for i = 1, #positions1 do + playerTile = Tile(positions1[i]):getTopCreature() + if playerTile:isPlayer() then + storePlayers[#storePlayers + 1] = playerTile + end + end + if #storePlayers == #positions1 then + cracklerTransform = true + end + elseif vortexPositions == 2 then + local storePlayers, playerTile = {} + for i = 1, #positions2 do + playerTile = Tile(positions2[i]):getTopCreature() + if playerTile:isPlayer() then + storePlayers[#storePlayers + 1] = playerTile + end + end + if #storePlayers == #positions2 then + cracklerTransform = true + end + elseif vortexPositions == 3 then + local storePlayers, playerTile = {} + for i = 1, #positions3 do + playerTile = Tile(positions3[i]):getTopCreature() + if playerTile:isPlayer() then + storePlayers[#storePlayers + 1] = playerTile + end + end + if #storePlayers == #positions3 then + cracklerTransform = true + end + elseif vortexPositions == 0 then + local storePlayers, playerTile = {} + for i = 1, #positions4 do + playerTile = Tile(positions4[i]):getTopCreature() + if playerTile:isPlayer() then + storePlayers[#storePlayers + 1] = playerTile + end + end + if #storePlayers == #positions4 then + cracklerTransform = true + end + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your presence begins to polarize the area!") + player:getPosition():sendMagicEffect(48) + end + return true +end + +vortexCrackler:type("stepin") +vortexCrackler:id(26127) +vortexCrackler:register() + +vortexCrackler = MoveEvent() + +function vortexCrackler.onStepOut(creature, item, position, fromPosition) + cracklerTransform = false + return true +end + +vortexCrackler:type("stepout") +vortexCrackler:id(26127) +vortexCrackler:register() diff --git a/data/scripts/movements/quests/heart_of_destruction/vortex_hunger.lua b/data/scripts/movements/quests/heart_of_destruction/vortex_hunger.lua new file mode 100644 index 00000000000..04dfc90accf --- /dev/null +++ b/data/scripts/movements/quests/heart_of_destruction/vortex_hunger.lua @@ -0,0 +1,41 @@ +local vortexHunger = MoveEvent() + +function vortexHunger.onStepIn(creature, item, position, fromPosition) + local monster = creature:getMonster() + if not monster then + return true + end + + if item.itemid == 26125 then + if monster:getName():lower() == "the hunger" then + local tile = Tile({x = 32244, y = 31371, z = 14}) + if tile then + local ground = tile:getGround() + if ground then + ground:transform(26126) + ground:decay() + end + end + elseif monster:getName():lower() == "world devourer" then + local tile = Tile({x = 32271, y = 31346, z = 14}) + if tile then + local ground = tile:getGround() + if ground then + ground:transform(26126) + ground:decay() + end + end + end + elseif item.itemid == 26126 then + if monster:getName():lower() == "greed" then + monster:remove() + hungerSummon = hungerSummon - 1 + devourerSummon = devourerSummon - 1 + end + end + return true +end + +vortexHunger:type("stepin") +vortexHunger:id(26125, 26126) +vortexHunger:register() diff --git a/data/scripts/movements/quests/hero_of_rathleton/deep_terror.lua b/data/scripts/movements/quests/hero_of_rathleton/deep_terror.lua new file mode 100644 index 00000000000..dfdfa50aaad --- /dev/null +++ b/data/scripts/movements/quests/hero_of_rathleton/deep_terror.lua @@ -0,0 +1,75 @@ +local function startWaves() + Game.setStorageValue(GlobalStorage.HeroRathleton.DeepRunning, 1) + if Game.getStorageValue(GlobalStorage.HeroRathleton.TentacleWave) < 9 then + for i = 1, 7 do + Game.createMonster("glooth anemone", Position(math.random(33736, 33746), + math.random(31948, 31957), 14), true, true) + end + elseif Game.getStorageValue(GlobalStorage.HeroRathleton.TentacleWave) == 9 then + for i = 1, 4 do + Game.createMonster("tentacle of the deep terror", Position(math.random(33736, 33746), + math.random(31948, 31957), 14), true, true) + end + end + Game.setStorageValue(GlobalStorage.HeroRathleton.TentacleWave, + Game.getStorageValue(GlobalStorage.HeroRathleton.TentacleWave) + 1) + if Game.getStorageValue(GlobalStorage.HeroRathleton.TentacleWave) > 9 then + return true + end + addEvent(startWaves, 40 * 1000) +end + +local function clearArea() + local spectators = Game.getSpectators(Position(33740, 31953, 14), false, false, 13, 13, 13, 13) + for i = 1, #spectators do + local spectator = spectators[i] + if spectator:isPlayer() then + spectator:teleportTo(Position(33724, 31953, 14)) + spectator:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + spectator:say("Time out!", TALKTYPE_MONSTER_SAY) + elseif spectator:isMonster() then + spectator:remove() + end + end + Game.setStorageValue(GlobalStorage.HeroRathleton.DeepRunning, 0) +end + +local deepTerror = MoveEvent() + +function deepTerror.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if Game.getStorageValue(GlobalStorage.HeroRathleton.DeepRunning) == 1 then + player:say("Has someone fighting against Deep Terror. \nTry again later.", TALKTYPE_MONSTER_SAY, false, nil, position) + player:teleportTo(Position(33724, 31951, 14)) + position:sendMagicEffect(CONST_ME_TELEPORT) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + if Game.getStorageValue(GlobalStorage.HeroRathleton.FirstMachines) < 8 then + player:say("No energy enough to use this teleport!", TALKTYPE_MONSTER_SAY, false, nil, position) + player:teleportTo(Position(33724, 31951, 14)) + position:sendMagicEffect(CONST_ME_TELEPORT) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + if Game.getStorageValue(GlobalStorage.HeroRathleton.FirstMachines) == 8 then + if Game.getStorageValue(GlobalStorage.HeroRathleton.DeepRunning) < 1 then + addEvent(Game.setStorageValue, 3 * 60 * 1000, GlobalStorage.HeroRathleton.DeepRunning, 1) + addEvent(startWaves, 3 * 60 * 1000) + addEvent(Game.setStorageValue, 3 * 60 * 1000, GlobalStorage.HeroRathleton.TentacleWave, 0) + addEvent(clearArea, 20 * 60 * 1000) + end + player:teleportTo(Position(33738, 31953, 14)) + position:sendMagicEffect(CONST_ME_TELEPORT) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +deepTerror:type("stepin") +deepTerror:aid(24862) +deepTerror:register() diff --git a/data/scripts/movements/quests/hero_of_rathleton/exit.lua b/data/scripts/movements/quests/hero_of_rathleton/exit.lua new file mode 100644 index 00000000000..f7605f523e6 --- /dev/null +++ b/data/scripts/movements/quests/hero_of_rathleton/exit.lua @@ -0,0 +1,17 @@ +local exit = MoveEvent() + +function exit.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + + player:teleportTo(Position(33623, 31901, 6)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say("Slurp!", TALKTYPE_MONSTER_SAY) + return true +end + +exit:type("stepin") +exit:aid(24872) +exit:register() diff --git a/data/scripts/movements/quests/hero_of_rathleton/fast_way.lua b/data/scripts/movements/quests/hero_of_rathleton/fast_way.lua new file mode 100644 index 00000000000..4b927da830e --- /dev/null +++ b/data/scripts/movements/quests/hero_of_rathleton/fast_way.lua @@ -0,0 +1,41 @@ +local destination = { + [24869] = {position = Position(33740, 31940, 15)}, + [24870] = {position = Position(33534, 31955, 15)}, + [24871] = {position = Position(33611, 32055, 15)} +} + +local fastWay = MoveEvent() + +function fastWay.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + + local teleport = destination[item.actionid] + if not teleport then + return + end + + if player:getStorageValue(24867) >= 1 then + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(teleport.position) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You use the secret codes you've read on Maxxen's chest.") + else + local pos = position + pos.y = pos.y + 2 + player:teleportTo(pos) + player:say("You haven't permission to use this teleport.", TALKTYPE_MONSTER_SAY, false, nil, position) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +fastWay:type("stepin") + +for index, value in pairs(destination) do + fastWay:aid(index) +end + +fastWay:register() diff --git a/data/scripts/movements/quests/hero_of_rathleton/glooth_horror.lua b/data/scripts/movements/quests/hero_of_rathleton/glooth_horror.lua new file mode 100644 index 00000000000..23c0aac9c8d --- /dev/null +++ b/data/scripts/movements/quests/hero_of_rathleton/glooth_horror.lua @@ -0,0 +1,80 @@ +local function startWaves() + Game.setStorageValue(GlobalStorage.HeroRathleton.HorrorRunning, 1) + if Game.getStorageValue(GlobalStorage.HeroRathleton.DevourerWave) < 9 then + for i = 1, 6 do + Game.createMonster("rot elemental", Position(math.random(33548, 33562), math.random(31949, 31962), 15), true, true) + Game.createMonster("devourer", Position(math.random(33548, 33562), math.random(31949, 31962), 15), true, true) + end + elseif Game.getStorageValue(GlobalStorage.HeroRathleton.DevourerWave) == 9 then + Game.createMonster("feeble glooth horror", Position(33555, 31956, 15), true, true) + end + Game.setStorageValue(GlobalStorage.HeroRathleton.DevourerWave, + Game.getStorageValue(GlobalStorage.HeroRathleton.DevourerWave) + 1) + if Game.getStorageValue(GlobalStorage.HeroRathleton.DevourerWave) > 9 then + return true + end + addEvent(startWaves, 40 * 1000) +end + +local function clearArea() + local spectators = Game.getSpectators(Position(33555, 31956, 15), false, false, 13, 13, 13, 13) + for i = 1, #spectators do + local spectator = spectators[i] + if spectator:isPlayer() then + spectator:teleportTo(Position(33573, 31949, 15)) + spectator:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + spectator:say("Time out!", TALKTYPE_MONSTER_SAY) + elseif spectator:isMonster() then + spectator:remove() + end + end + Game.setStorageValue(GlobalStorage.HeroRathleton.HorrorRunning, 0) +end + +local gloothHorror = MoveEvent() + +function gloothHorror.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(GlobalStorage.HeroRathleton.AccessTeleport1) < 1 then + player:teleportTo(Position(33571, 31947, 15)) + position:sendMagicEffect(CONST_ME_TELEPORT) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say("You haven't permission to use this teleport.", TALKTYPE_MONSTER_SAY, false, nil, position) + return true + end + if Game.getStorageValue(GlobalStorage.HeroRathleton.HorrorRunning) == 1 then + player:say("Has someone fighting against Glooth Horror. \nTry again later.", + TALKTYPE_MONSTER_SAY, false, nil, position) + player:teleportTo(Position(33571, 31947, 15)) + position:sendMagicEffect(CONST_ME_TELEPORT) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + if Game.getStorageValue(GlobalStorage.HeroRathleton.SecondMachines) < 8 then + player:say("No energy enough to use this teleport!", TALKTYPE_MONSTER_SAY, false, nil, position) + player:teleportTo(Position(33571, 31947, 15)) + position:sendMagicEffect(CONST_ME_TELEPORT) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + if Game.getStorageValue(GlobalStorage.HeroRathleton.SecondMachines) == 8 then + if Game.getStorageValue(GlobalStorage.HeroRathleton.HorrorRunning) < 1 then + addEvent(Game.setStorageValue, 3 * 60 * 1000, GlobalStorage.HeroRathleton.HorrorRunning, 1) + addEvent(startWaves, 3 * 60 * 1000) + addEvent(Game.setStorageValue, 3 * 60 * 1000, GlobalStorage.HeroRathleton.DevourerWave, 0) + addEvent(clearArea, 20 * 60 * 1000) + end + player:teleportTo(Position(33561, 31954, 15)) + position:sendMagicEffect(CONST_ME_TELEPORT) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +gloothHorror:type("stepin") +gloothHorror:aid(24864) +gloothHorror:register() diff --git a/data/scripts/movements/quests/hero_of_rathleton/lava.lua b/data/scripts/movements/quests/hero_of_rathleton/lava.lua new file mode 100644 index 00000000000..6e33848c482 --- /dev/null +++ b/data/scripts/movements/quests/hero_of_rathleton/lava.lua @@ -0,0 +1,112 @@ +local changes = { + [1] = {centerPos = Position(33552, 32049, 15), nextPos = Position(33552, 32082, 15)}, + [2] = {centerPos = Position(33552, 32082, 15), nextPos = Position(33552, 32115, 15)}, + [3] = {centerPos = Position(33552, 32115, 15), nextPos = Position(33552, 32148, 15)}, + [4] = {centerPos = Position(33552, 32148, 15), nextPos = Position(33584, 32148, 15)}, + [5] = {centerPos = Position(33584, 32148, 15), nextPos = Position(33616, 32148, 15)}, + [6] = {centerPos = Position(33616, 32148, 15), nextPos = Position(33648, 32148, 15)}, + [7] = {centerPos = Position(33648, 32148, 15), nextPos = Position(33611, 32055, 15)} +} + +local function checkCounter() + local storage = Game.getStorageValue(GlobalStorage.HeroRathleton.LavaChange) + if storage == 7 then + local spectators = Game.getSpectators(changes[storage].centerPos, false, false, 13, 13, 13, 13) + for i = 1, #spectators do + local spectator = spectators[i] + if spectator:isPlayer() then + spectator:teleportTo(Position(33611, 32055, 15)) + spectator:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + spectator:addAchievement("Go with da Lava Flow") + elseif spectator:isMonster() then + spectator:remove() + end + end + Game.setStorageValue(GlobalStorage.HeroRathleton.LavaChange, 0) + Game.setStorageValue(GlobalStorage.HeroRathleton.LavaRunning, 0) + stopEvent(checkCounter) + return true + end + if Game.getStorageValue(GlobalStorage.HeroRathleton.LavaCounter) < 5 then + local spectators = Game.getSpectators(changes[storage].centerPos, false, false, 13, 13, 13, 13) + for i = 1, #spectators do + local spectator = spectators[i] + if spectator:isPlayer() then + spectator:teleportTo(Position(33371, 31955, 15)) + spectator:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + elseif spectator:isMonster() then + spectator:remove() + end + end + Game.setStorageValue(GlobalStorage.HeroRathleton.LavaChange, 0) + Game.setStorageValue(GlobalStorage.HeroRathleton.LavaRunning, 0) + stopEvent(checkCounter) + return true + end + local spectators = Game.getSpectators(changes[storage].centerPos, false, false, 13, 13, 13, 13) + for i = 1, #spectators do + local spectator = spectators[i] + if spectator:isPlayer() then + spectator:teleportTo(changes[storage].nextPos) + end + end + if storage < 7 then + for p = 1, 5 do + addEvent(Game.createMonster, 15 * 1000, "raging fire", changes[storage].nextPos, true, true) + end + end + Game.setStorageValue(GlobalStorage.HeroRathleton.LavaChange, + Game.getStorageValue(GlobalStorage.HeroRathleton.LavaChange) + 1) + Game.setStorageValue(GlobalStorage.HeroRathleton.LavaCounter, 0) + return true +end + +local lava = MoveEvent() + +function lava.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + if player:getStorageValue(GlobalStorage.HeroRathleton.AccessTeleport2) < 1 then + player:teleportTo(Position(33371, 31955, 15)) + position:sendMagicEffect(CONST_ME_TELEPORT) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say("You haven't permission to use this teleport.", TALKTYPE_MONSTER_SAY, false, nil, position) + return true + end + if Game.getStorageValue(GlobalStorage.HeroRathleton.LavaRunning) == 1 then + player:say("Has someone trying active the machine. Try again later.", TALKTYPE_MONSTER_SAY, false, nil, position) + player:teleportTo(Position(33371, 31955, 15)) + position:sendMagicEffect(CONST_ME_TELEPORT) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + if Game.getStorageValue(GlobalStorage.HeroRathleton.FourthMachines) < 7 then + player:say("No energy enough to use this teleport!", TALKTYPE_MONSTER_SAY, false, nil, position) + player:teleportTo(Position(33371, 31955, 15)) + position:sendMagicEffect(CONST_ME_TELEPORT) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + if Game.getStorageValue(GlobalStorage.HeroRathleton.FourthMachines) == 7 then + if Game.getStorageValue(GlobalStorage.HeroRathleton.LavaRunning) < 1 then + addEvent(Game.setStorageValue, 1 * 30 * 1000, GlobalStorage.HeroRathleton.LavaRunning, 1) + for i = 1, 5 do + addEvent(Game.createMonster, 1 * 30 * 1000, "raging fire", Position(33552, 32049, 15), true, true) + end + for a = 1, 7 do + addEvent(checkCounter, a * 60 * 1000) + end + end + Game.setStorageValue(GlobalStorage.HeroRathleton.LavaChange, 1) + player:teleportTo(Position(33552, 32049, 15)) + position:sendMagicEffect(CONST_ME_TELEPORT) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +lava:type("stepin") +lava:aid(24866) +lava:register() diff --git a/data/scripts/movements/quests/hero_of_rathleton/professor_maxxen.lua b/data/scripts/movements/quests/hero_of_rathleton/professor_maxxen.lua new file mode 100644 index 00000000000..15af373fd8c --- /dev/null +++ b/data/scripts/movements/quests/hero_of_rathleton/professor_maxxen.lua @@ -0,0 +1,95 @@ +local function startWaves() + local position = math.random(33704, 33718), math.random(32040, 32053), 15 + Game.setStorageValue(GlobalStorage.HeroRathleton.MaxxenRunning, 1) + if Game.getStorageValue(GlobalStorage.HeroRathleton.GloothWave) < 8 then + for i = 1, 4 do + local chance = math.random(2) + if chance == 1 then + Game.createMonster("glooth masher", Position(position), true, true) + else + Game.createMonster("glooth golem", Position(position), true, true) + end + end + elseif Game.getStorageValue(GlobalStorage.HeroRathleton.GloothWave) == 8 then + for i = 1, 4 do + local chance = math.random(3) + if chance == 1 then + Game.createMonster("glooth trasher", Position(position), true, true) + elseif chance == 2 then + Game.createMonster("glooth slasher", Position(position), true, true) + else + Game.createMonster("glooth golem", Position(position), true, true) + end + end + Game.createMonster("professor maxxen", Position(33711, 32046, 15), true, true) + end + Game.setStorageValue(GlobalStorage.HeroRathleton.GloothWave, + Game.getStorageValue(GlobalStorage.HeroRathleton.GloothWave) + 1) + if Game.getStorageValue(GlobalStorage.HeroRathleton.GloothWave) > 8 then + return true + end + addEvent(startWaves, 40 * 1000) +end + +local function clearArea() + local spectators = Game.getSpectators(Position(33711, 32046, 15), false, false, 13, 13, 13, 13) + for i = 1, #spectators do + local spectator = spectators[i] + if spectator:isPlayer() then + spectator:teleportTo(Position(33661, 32058, 15)) + spectator:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + spectator:say("Time out!", TALKTYPE_MONSTER_SAY) + elseif spectator:isMonster() then + spectator:remove() + end + end + Game.setStorageValue(GlobalStorage.HeroRathleton.MaxxenRunning, 0) +end + +local professorMaxxen = MoveEvent() + +function professorMaxxen.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(GlobalStorage.HeroRathleton.AccessTeleport3) < 1 then + player:teleportTo(Position(33661, 32058, 15)) + position:sendMagicEffect(CONST_ME_TELEPORT) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say("You haven't permission to use this teleport.", TALKTYPE_MONSTER_SAY, false, nil, position) + return true + end + if Game.getStorageValue(GlobalStorage.HeroRathleton.MaxxenRunning) == 1 then + player:say("Has someone fighting against Professor Maxxen.\nTry again later.", + TALKTYPE_MONSTER_SAY, false, nil, position) + player:teleportTo(Position(33661, 32058, 15)) + position:sendMagicEffect(CONST_ME_TELEPORT) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + if Game.getStorageValue(GlobalStorage.HeroRathleton.ThirdMachines) < 8 then + player:say("No energy enough to use this teleport!", TALKTYPE_MONSTER_SAY, false, nil, position) + player:teleportTo(Position(33661, 32058, 15)) + position:sendMagicEffect(CONST_ME_TELEPORT) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + if Game.getStorageValue(GlobalStorage.HeroRathleton.ThirdMachines) == 8 then + if Game.getStorageValue(GlobalStorage.HeroRathleton.MaxxenRunning) < 1 then + addEvent(Game.setStorageValue, 3 * 60 * 1000, GlobalStorage.HeroRathleton.MaxxenRunning, 1) + addEvent(startWaves, 3 * 60 * 1000) + addEvent(Game.setStorageValue, 3 * 60 * 1000, GlobalStorage.HeroRathleton.GloothWave, 0) + addEvent(clearArea, 20 * 60 * 1000) + end + player:teleportTo(Position(33711, 32052, 15)) + position:sendMagicEffect(CONST_ME_TELEPORT) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +professorMaxxen:type("stepin") +professorMaxxen:aid(24868) +professorMaxxen:register() diff --git a/data/scripts/movements/quests/in_service_of_yalahar/demon_teleport.lua b/data/scripts/movements/quests/in_service_of_yalahar/demon_teleport.lua new file mode 100644 index 00000000000..005b128d56f --- /dev/null +++ b/data/scripts/movements/quests/in_service_of_yalahar/demon_teleport.lua @@ -0,0 +1,54 @@ +local teleports = { + [3103] = {destination = Position(32861, 31061, 9), soilPosition = Position(32859, 31056, 9)}, + [3104] = {destination = Position(32856, 31055, 9)}, + [3105] = {destination = Position(32888, 31045, 9), soilPosition = Position(32894, 31044, 9)}, + [3106] = {destination = Position(32894, 31046, 9)}, +} + +local soilIds = {8302, 8303, 8298, 8299} + +local demonTeleport = MoveEvent() + +function demonTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local teleport = teleports[item.uid] + if not teleport.soilPosition then + player:teleportTo(teleport.destination) + teleport.destination:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + local soilItem + local soilRemoved = false + for i = 1, #soilIds do + soilItem = Tile(teleport.soilPosition):getItemById(soilIds[i]) + if soilItem then + soilItem:remove(1) + soilRemoved = true + break + end + end + + if not soilRemoved then + player:teleportTo(fromPosition) + fromPosition:sendMagicEffect(CONST_ME_ENERGYHIT) + player:say("You may not enter without a sacrifice of a elemental soil.", TALKTYPE_MONSTER_SAY) + return true + end + + player:teleportTo(teleport.destination) + teleport.destination:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +demonTeleport:type("stepin") + +for index, value in pairs(teleports) do + demonTeleport:uid(index) +end + +demonTeleport:register() diff --git a/data/scripts/movements/quests/in_service_of_yalahar/last_fight_teleport.lua b/data/scripts/movements/quests/in_service_of_yalahar/last_fight_teleport.lua new file mode 100644 index 00000000000..a26129881ad --- /dev/null +++ b/data/scripts/movements/quests/in_service_of_yalahar/last_fight_teleport.lua @@ -0,0 +1,34 @@ +local lastFightTeleport = MoveEvent() + +function lastFightTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if item.uid == 7809 then + if player:getStorageValue(Storage.InServiceofYalahar.Questline) == 51 then + if Game.getStorageValue(GlobalStorage.InServiceOfYalahar.LastFight) ~= 1 then + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(Position(32783, 31174, 10)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say('The apparatus in the centre looks odd! You should inspect it.', TALKTYPE_MONSTER_SAY) + end + else + player:teleportTo(fromPosition) + end + elseif item.uid == 7810 then + if Game.getStorageValue(GlobalStorage.InServiceOfYalahar.LastFight) ~= 1 then + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(Position(32784, 31178, 9)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:teleportTo(fromPosition) + end + end + return true +end + +lastFightTeleport:type("stepin") +lastFightTeleport:uid(7809, 7810) +lastFightTeleport:register() diff --git a/data/scripts/movements/quests/in_service_of_yalahar/morik.lua b/data/scripts/movements/quests/in_service_of_yalahar/morik.lua new file mode 100644 index 00000000000..13677f1937a --- /dev/null +++ b/data/scripts/movements/quests/in_service_of_yalahar/morik.lua @@ -0,0 +1,22 @@ +local morik = MoveEvent() + +function morik.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.InServiceofYalahar.Questline) == 51 then + -- StorageValue for Questlog 'Mission 10: The Final Battle' + player:setStorageValue(Storage.InServiceofYalahar.Mission10, 3) + player:setStorageValue(Storage.InServiceofYalahar.Questline, 52) + player:say('It seems by defeating Azerus you have stopped this army from entering your world! \z + Better leave this ghastly place forever.', TALKTYPE_MONSTER_SAY) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + end + return true +end + +morik:type("stepin") +morik:uid(3087) +morik:register() diff --git a/data/scripts/movements/quests/in_service_of_yalahar/quara_vortex.lua b/data/scripts/movements/quests/in_service_of_yalahar/quara_vortex.lua new file mode 100644 index 00000000000..5a3800fb830 --- /dev/null +++ b/data/scripts/movements/quests/in_service_of_yalahar/quara_vortex.lua @@ -0,0 +1,24 @@ +local quaraVortex = MoveEvent() + +function quaraVortex.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local headItem = player:getSlotItem(CONST_SLOT_HEAD) + if headItem and table.contains({5461, 12541, 15408}, headItem.itemid) then + player:teleportTo(Position(32950, 31181, 9)) + player:getPosition():sendMagicEffect(CONST_ME_WATERSPLASH) + player:say("The vortex throws you out in this vicious place.", TALKTYPE_MONSTER_SAY) + else + player:teleportTo(fromPosition) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You must wear an underwater exploration helmet in order to dive.") + end + return true +end + +quaraVortex:type("stepin") +quaraVortex:aid(7812) +quaraVortex:register() diff --git a/data/scripts/movements/quests/in_service_of_yalahar/yalahar_machine_war_golems.lua b/data/scripts/movements/quests/in_service_of_yalahar/yalahar_machine_war_golems.lua new file mode 100644 index 00000000000..3112ef432d4 --- /dev/null +++ b/data/scripts/movements/quests/in_service_of_yalahar/yalahar_machine_war_golems.lua @@ -0,0 +1,50 @@ +local setting = { + [23698] = { + storage = GlobalStorage.InServiceOfYalahar.WarGolemsMachine2, + destination = Position(32869, 31312, 11) + }, + [23699] = { + storage = GlobalStorage.InServiceOfYalahar.WarGolemsMachine1, + destination = Position(32881, 31312, 11) + }, + [23702] = { + destination = Position(32876, 31321, 10) + }, + [23703] = { + destination = Position(32875, 31321, 10) + } +} + +local yalaharMachineWarGolems = MoveEvent() + +function yalaharMachineWarGolems.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local machine = setting[item.actionid] + if not machine then + return true + end + + if machine.storage and Game.getStorageValue(machine.storage) ~= 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The machines are not activated.") + player:teleportTo(Position(32875, 31321, 10)) + position:sendMagicEffect(CONST_ME_POFF) + return true + end + + player:teleportTo(machine.destination) + position:sendMagicEffect(CONST_ME_ENERGYHIT) + machine.destination:sendMagicEffect(CONST_ME_ENERGYHIT) + return true +end + +yalaharMachineWarGolems:type("stepin") + +for index, value in pairs(setting) do + yalaharMachineWarGolems:aid(index) +end + +yalaharMachineWarGolems:register() diff --git a/data/scripts/movements/quests/inquisition/entrance.lua b/data/scripts/movements/quests/inquisition/entrance.lua new file mode 100644 index 00000000000..42af7dac129 --- /dev/null +++ b/data/scripts/movements/quests/inquisition/entrance.lua @@ -0,0 +1,46 @@ +local throneStorages = { + Storage.PitsOfInferno.ThroneInfernatil, + Storage.PitsOfInferno.ThroneTafariel, + Storage.PitsOfInferno.ThroneVerminor, + Storage.PitsOfInferno.ThroneApocalypse, + Storage.PitsOfInferno.ThroneBazir, + Storage.PitsOfInferno.ThroneAshfalor, + Storage.PitsOfInferno.ThronePumin +} + +local function hasTouchedOneThrone(player) + for i = 1, #throneStorages do + if player:getStorageValue(throneStorages[i]) == 1 then + return true + end + end + return false +end + +local entrance = MoveEvent() + +function entrance.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if hasTouchedOneThrone(player) and player:getLevel() >= 100 + and player:getStorageValue(Storage.TheInquisition.Questline) >= 20 then + local destination = Position(33168, 31683, 15) + player:teleportTo(destination) + position:sendMagicEffect(CONST_ME_TELEPORT) + destination:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + player:teleportTo(fromPosition, true) + position:sendMagicEffect(CONST_ME_TELEPORT) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true + +end + +entrance:type("stepin") +entrance:uid(9014) +entrance:register() diff --git a/data/scripts/movements/quests/inquisition/reward_room_text.lua b/data/scripts/movements/quests/inquisition/reward_room_text.lua new file mode 100644 index 00000000000..5d11c756c8a --- /dev/null +++ b/data/scripts/movements/quests/inquisition/reward_room_text.lua @@ -0,0 +1,16 @@ +local rewardRoomText = MoveEvent() + +function rewardRoomText.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player or player:getStorageValue(Storage.TheInquisition.RewardRoomText) == 1 then + return true + end + + player:setStorageValue(Storage.TheInquisition.RewardRoomText, 1) + player:say("You can choose exactly one of these chets. Choose wisely!", TALKTYPE_MONSTER_SAY, false, player) + return true +end + +rewardRoomText:type("stepin") +rewardRoomText:aid(4003) +rewardRoomText:register() diff --git a/data/scripts/movements/quests/inquisition/teleport_main.lua b/data/scripts/movements/quests/inquisition/teleport_main.lua new file mode 100644 index 00000000000..6ed278a9a99 --- /dev/null +++ b/data/scripts/movements/quests/inquisition/teleport_main.lua @@ -0,0 +1,223 @@ +local teleports = { + -- to ushuriel ward + [2150] = { + text = "Entering Ushuriel's ward.", + newPos = Position(33158, 31728, 11), + storage = 0, alwaysSetStorage = true + }, + -- from ushuriel ward + [2151] = { + text = "Entering the Crystal Caves.", + bossStorage = 200, + newPos = Position(33069, 31782, 13), + storage = 1 + }, + -- from crystal caves + [2152] = { + text = "Escaping back to the Retreat.", + newPos = Position(33165, 31709, 14) + }, + -- to crystal caves + [2153] = { + text = "Entering the Crystal Caves.", + newPos = Position(33069, 31782, 13), + storage = 1 + }, + -- to sunken caves + [2154] = { + text = "Entering the Sunken Caves.", + newPos = Position(33169, 31755, 13) + }, + -- from sunken caves + [2155] = { + text = "Entering the Mirror Maze of Madness.", + newPos = Position(33065, 31772, 10) + }, + -- to zugurosh ward + [2156] = { + text = "Entering Zugurosh's ward.", + newPos = Position(33124, 31692, 11) + }, + -- from zugurosh ward + [2157] = { + text = "Entering the Blood Halls.", + bossStorage = 201, + newPos = Position(33372, 31613, 14), + storage = 2 + }, + -- from blood halls + [2158] = { + text = "Escaping back to the Retreat.", + newPos = Position(33165, 31709, 14) + }, + -- to blood halls + [2159] = { + text = "Entering the Blood Halls.", + newPos = Position(33372, 31613, 14), + storage = 2 + }, + -- to foundry + [2160] = { + text = "Entering the Foundry.", + newPos = Position(33356, 31589, 11) + }, + -- to madareth ward + [2161] = { + text = "Entering Madareth's ward.", + newPos = Position(33197, 31767, 11) + }, + -- from madareth ward + [2162] = { + text = "Entering the Vats.", + bossStorage = 202, + newPos = Position(33153, 31782, 12), + storage = 3 + }, + -- from vats + [2163] = { + text = "Escaping back to the Retreat.", + newPos = Position(33165, 31709, 14) + }, + -- to vats + [2164] = { + text = "Entering the Vats.", + newPos = Position(33153, 31782, 12), + storage = 3 + }, + -- to battlefield + [2165] = { + text = "Entering the Battlefield.", + newPos = Position(33250, 31632, 13) + }, + -- from battlefield + [2166] = { + text = "Entering the Vats.", + newPos = Position(33233, 31758, 12) + }, + -- to brothers ward + [2167] = { + text = "Entering the Demon Forge.", + newPos = Position(33232, 31733, 11) + }, + -- from demon forge + [2168] = { + text = "Entering the Arcanum.", + bossStorage = 203, + newPos = Position(33038, 31753, 15), + storage = 4 + }, + -- from arcanum + [2169] = { + text = "Escaping back to the Retreat.", + newPos = Position(33165, 31709, 14) + }, + -- to arcanum + [2170] = { + text = "Entering the Arcanum.", + newPos = Position(33038, 31753, 15), + storage = 4 + }, + -- to soul wells + [2171] = { + text = "Entering the Soul Wells.", + newPos = Position(33093, 31575, 11) + }, + -- from soul wells + [2172] = { + text = "Entering the Arcanum.", + newPos = Position(33186, 31759, 15) + }, + -- to annihilon ward + [2173] = { + text = "Entering the Annihilon's ward.", + newPos = Position(33197, 31703, 11) + }, + -- from annihilon ward + [2174] = { + text = "Entering the Hive.", + bossStorage = 204, + newPos = Position(33199, 31686, 12), + storage = 5 + }, + -- from hive + [2175] = { + text = "Escaping back to the Retreat.", + newPos = Position(33165, 31709, 14) + }, + -- to hive + [2176] = { + text = "Entering the Hive.", + newPos = Position(33199, 31686, 12), + storage = 5 + }, + -- to hellgorak ward + [2177] = { + text = "Entering the Hellgorak's ward.", + newPos = Position(33104, 31734, 11) + }, + -- from hellgorak ward + [2178] = { + text = "Entering the Shadow Nexus. Abandon all Hope.", + bossStorage = 205, + newPos = Position(33110, 31682, 12), + storage = 6 + }, + -- from shadow nexus + [2179] = { + text = "Escaping back to the Retreat.", + newPos = Position(33165, 31709, 14) + }, + -- from foundry to blood halls + [2180] = { + text = "Entering the Blood Halls.", + newPos = Position(33357, 31589, 12) + } +} + +local teleportMain = MoveEvent() + +function teleportMain.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local teleport = teleports + [item.uid] + if teleport.alwaysSetStorage and player:getStorageValue(Storage.TheInquisition.EnterTeleport) < teleport.storage then + player:setStorageValue(Storage.TheInquisition.EnterTeleport, teleport.storage) + end + + if teleport.bossStorage then + if Game.getStorageValue(teleport.bossStorage) >= 2 then + if player:getStorageValue(Storage.TheInquisition.EnterTeleport) < teleport.storage then + player:setStorageValue(Storage.TheInquisition.EnterTeleport, teleport.storage) + player:setStorageValue(teleport.bossStorage, 0) + + end + else + player:teleportTo(Position(33165, 31709, 14)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say("Escaping back to the Retreat.", TALKTYPE_MONSTER_SAY) + return true + end + elseif teleport.storage and player:getStorageValue(Storage.TheInquisition.EnterTeleport) < teleport.storage then + player:teleportTo(fromPosition) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say("You don't have enough energy to enter this portal", TALKTYPE_MONSTER_SAY) + return true + end + + player:teleportTo(teleport.newPos) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say(teleport.text, TALKTYPE_MONSTER_SAY) + return true +end + +teleportMain:type("stepin") + +for index, value in pairs(teleports) do + teleportMain:uid(index) +end + +teleportMain:register() diff --git a/data/scripts/movements/quests/killing_in_the_name_of/boss.lua b/data/scripts/movements/quests/killing_in_the_name_of/boss.lua new file mode 100644 index 00000000000..da5d4a33273 --- /dev/null +++ b/data/scripts/movements/quests/killing_in_the_name_of/boss.lua @@ -0,0 +1,372 @@ +local function roomIsOccupied(centerPosition, + rangeX, rangeY) + local spectators = Game.getSpectators(centerPosition, false, true, + rangeX, + rangeX, rangeY, rangeY) + if #spectators ~= 0 then + return true + end + return false +end + +function clearBossRoom(playerId, bossId, + centerPosition, + rangeX, rangeY, exitPosition) + local spectators, spectator = Game.getSpectators(centerPosition, false, false, + rangeX, + rangeX, rangeY, rangeY) + for i = 1, #spectators do + spectator = spectators[i] + if spectator:isPlayer() and spectator.uid == playerId then + spectator:teleportTo(exitPosition) + exitPosition:sendMagicEffect(CONST_ME_TELEPORT) + end + if spectator:isMonster() and spectator.uid == bossId then + spectator:remove() + end + end +end + +local bosses = { + [3230] = { + bossName = 'the snapper', + storage = 34100, + playerPosition = Position(32610, 32723, 8), + bossPosition = Position(32617, 32732, 8), + centerPosition = Position(32613, 32727, 8), + rangeX = 5, rangeY = 5, + flamePosition = Position(32612, 32733, 8) + }, + [3231] = { + bossName = 'hide', + storage = 34101, + playerPosition = Position(32815, 32703, 8), + bossPosition = Position(32816, 32712, 8), + centerPosition = Position(32816, 32707, 8), + rangeX = 6, rangeY = 5, + flamePosition = Position(32810, 32704, 8) + }, + [3232] = { + bossName = 'deathbine', + storage = 34102, + playerPosition = Position(32715, 32736, 8), + bossPosition = Position(32714, 32713, 8), + centerPosition = Position(32716, 32724, 8), + rangeX = 9, rangeY = 13, + flamePosition = Position(32726, 32727, 8) + }, + [3233] = { + bossName = 'the bloodtusk', + storage = 34103, + playerPosition = Position(32102, 31124, 2), + bossPosition = Position(32102, 31134, 2), + centerPosition = Position(32101, 31129, 2), + rangeX = 5, rangeY = 6, + flamePosition = Position(32093, 31130, 2) + }, + [3234] = { + bossName = 'shardhead', + storage = 34104, + playerPosition = Position(32152, 31137, 3), + bossPosition = Position(32159, 31132, 3), + centerPosition = Position(32155, 31136, 3), + rangeX = 5, rangeY = 7, + flamePosition = Position(32149, 31137, 3) + }, + [3235] = { + bossName = 'esmeralda', + storage = 34105, + playerPosition = Position(32759, 31252, 9), + bossPosition = Position(32759, 31258, 9), + centerPosition = Position(32759, 31254, 9), + rangeX = 4, rangeY = 4, + flamePosition = Position(32758, 31248, 9) + }, + [3236] = { + bossName = 'fleshcrawler', + storage = 34106, + playerPosition = Position(33100, 32785, 11), + bossPosition = Position(33121, 32797, 11), + centerPosition = Position(33112, 32789, 11), + rangeX = 15, rangeY = 13, + flamePosition = Position(33106, 32775, 11) + }, + [3237] = { + bossName = 'ribstride', + storage = 34107, + playerPosition = Position(33012, 32813, 13), + bossPosition = Position(33013, 32801, 13), + centerPosition = Position(33012, 32805, 13), + rangeX = 10, rangeY = 9, + flamePosition = Position(33018, 32814, 13) + }, + [3238] = { + bossName = 'the bloodweb', + storage = 34108, + playerPosition = Position(32019, 31037, 8), + bossPosition = Position(32032, 31033, 8), + centerPosition = Position(32023, 31033, 8), + rangeX = 11, rangeY = 11, + flamePosition = Position(32010, 31031, 8) + }, + [3239] = { + bossName = 'thul', + storage = 34109, + playerPosition = Position(32078, 32780, 13), + bossPosition = Position(32088, 32780, 13), + centerPosition = Position(32083, 32781, 13), + rangeX = 6, rangeY = 6, + flamePosition = Position(32086, 32776, 13) + }, + [3240] = { + bossName = 'the old widow', + storage = 34110, + playerPosition = Position(32805, 32280, 8), + bossPosition = Position(32797, 32281, 8), + centerPosition = Position(32801, 32276, 8), + rangeX = 5, rangeY = 5, + flamePosition = Position(32808, 32283, 8) + }, + [3241] = { + bossName = 'hemming', + storage = 34111, + playerPosition = Position(32999, 31452, 8), + bossPosition = Position(33013, 31441, 8), + centerPosition = Position(33006, 31445, 8), + rangeX = 9, rangeY = 7, + flamePosition = Position(33005, 31437, 8) + }, + [3242] = { + bossName = 'tormentor', + storage = 34112, + playerPosition = Position(32043, 31258, 11), + bossPosition = Position(32058, 31267, 11), + centerPosition = Position(32051, 31264, 11), + rangeX = 11, rangeY = 14, + flamePosition = Position(32051, 31249, 11) + }, + [3243] = { + bossName = 'flameborn', + storage = 34113, + playerPosition = Position(32940, 31064, 8), + bossPosition = Position(32947, 31058, 8), + centerPosition = Position(32944, 31060, 8), + rangeX = 11, rangeY = 10, + flamePosition = Position(32818, 31026, 7) + }, + [3244] = { + bossName = 'fazzrah', + storage = 34114, + playerPosition = Position(32993, 31175, 7), + bossPosition = Position(33005, 31174, 7), + centerPosition = Position(33003, 31177, 7), + rangeX = 14, rangeY = 6, + flamePosition = Position(33007, 31171, 7) + }, + [3245] = { + bossName = 'tromphonyte', + storage = 34115, + playerPosition = Position(33111, 31184, 8), + bossPosition = Position(33120, 31195, 8), + centerPosition = Position(33113, 31188, 8), + rangeX = 11, rangeY = 18, + flamePosition = Position(33109, 31168, 8) + }, + [3246] = { + bossName = 'sulphur scuttler', + storage = 34116, + playerPosition = Position(33269, 31046, 9), + bossPosition = Position(33274, 31037, 9), + centerPosition = Position(33088, 31012, 8), + rangeX = 11, rangeY = 11, + flamePosition = Position(0, 0, 0) + }, + [3247] = { + bossName = 'bruise payne', + storage = 34117, + playerPosition = Position(33237, 31006, 2), + bossPosition = Position(33266, 31016, 2), + centerPosition = Position(33251, 31016, 2), + rangeX = 22, rangeY = 11, + flamePosition = Position(33260, 31003, 2) + }, + [3248] = { + bossName = 'the many', + storage = 34118, + playerPosition = Position(32921, 32893, 8), + bossPosition = Position(32926, 32903, 8), + centerPosition = Position(32921, 32898, 8), + rangeX = 5, rangeY = 6, + flamePosition = Position(32921, 32890, 8) + }, + [3249] = { + bossName = 'the noxious spawn', + storage = 34119, + playerPosition = Position(32842, 32667, 11), + bossPosition = Position(32843, 32675, 11), + centerPosition = Position(32843, 32670, 11), + rangeX = 5, rangeY = 5, + flamePosition = Position(0, 0, 0) + }, + [3250] = { + bossName = 'gorgo', + storage = 34120, + playerPosition = Position(32759, 32447, 11), + bossPosition = Position(32763, 32435, 11), + centerPosition = Position(32759, 32440, 11), + rangeX = 9, rangeY = 10, + flamePosition = Position(32768, 32440, 11) + }, + [3251] = { + bossName = 'stonecracker', + storage = 34121, + playerPosition = Position(33259, 31694, 15), + bossPosition = Position(33257, 31705, 15), + centerPosition = Position(33259, 31670, 15), + rangeX = 5, rangeY = 7, + flamePosition = Position(33259, 31689, 15) + }, + [3252] = { + bossName = 'leviathan', + storage = 34122, + playerPosition = Position(31915, 31071, 10), + bossPosition = Position(31903, 31072, 10), + centerPosition = Position(31909, 31072, 10), + rangeX = 8, rangeY = 7, + flamePosition = Position(31918, 31071, 10) + }, + [3253] = { + bossName = 'kerberos', + storage = 34123, + playerPosition = Position(32048, 32581, 15), + bossPosition = Position(32032, 32565, 15), + centerPosition = Position(32041, 32569, 15), + rangeX = 11, rangeY = 13, + flamePosition = Position(32030, 32555, 15) + }, + [3254] = { + bossName = 'ethershreck', + storage = 34124, + playerPosition = Position(33089, 31021, 8), + bossPosition = Position(33085, 31004, 8), + centerPosition = Position(33088, 31012, 8), + rangeX = 11, rangeY = 11, + flamePosition = Position(33076, 31007, 8) + }, + [3255] = { + bossName = 'paiz the pauperizer', + storage = 34125, + playerPosition = Position(33069, 31110, 1), + bossPosition = Position(33082, 31105, 1), + centerPosition = Position(33076, 31110, 1), + rangeX = 8, rangeY = 6, + flamePosition = Position(33076, 31110, 1) + }, + [3256] = { + bossName = 'bretzecutioner', + storage = 34126, + playerPosition = Position(31973, 31184, 10), + bossPosition = Position(31979, 31176, 10), + centerPosition = Position(31973, 31177, 10), + rangeX = 15, rangeY = 10, + flamePosition = Position(31973, 31166, 10) + }, + [3257] = { + bossName = 'zanakeph', + storage = 34127, + playerPosition = Position(33077, 31040, 12), + bossPosition = Position(33082, 31056, 12), + centerPosition = Position(33077, 31050, 12), + rangeX = 13, rangeY = 10, + flamePosition = Position(33070, 31039, 12) + }, + [3258] = { + bossName = 'tiquandas revenge', + storage = Storage.KillingInTheNameOf.TiquandasRevengeTeleport, + playerPosition = Position(32888, 32580, 4), + bossPosition = Position(32888, 32586, 4), + centerPosition = Position(32748, 32293, 10), + rangeX = 8, rangeY = 7, + flamePosition = Position(33076, 31029, 11) + }, + [3259] = { + bossName = 'demodras', + storage = Storage.KillingInTheNameOf.DemodrasTeleport, + playerPosition = Position(32748, 32287, 10), + bossPosition = Position(32747, 32294, 10), + centerPosition = Position(32887, 32583, 4), + rangeX = 6, rangeY = 5, + flamePosition = Position(33076, 31029, 12) + }, + [3260] = { + bossName = 'necropharus', + storage = 17521, + playerPosition = Position(33028, 32426, 12), + bossPosition = Position(33026, 32422, 12), + centerPosition = Position(33028, 32424, 12), + rangeX = 6, rangeY = 5, + flamePosition = Position(33070, 31035, 12) + }, + [3261] = { + bossName = 'the horned fox', + storage = 17522, + playerPosition = Position(32458, 31994, 9), + bossPosition = Position(32458, 32005, 9), + centerPosition = Position(32450, 31400, 9), + rangeX = 5, rangeY = 8, + flamePosition = Position(33070, 31029, 12) + }, + [3262] = { + bossName = 'lethal lissy', + storage = 17523, + playerPosition = Position(31976, 32896, 0), + bossPosition = Position(31983, 32897, 0), + centerPosition = Position(31982, 32897, 0), + rangeX = 5, rangeY = 8, + flamePosition = Position(31987, 32896, 0) + } +} + +local boss = MoveEvent() + +function boss.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local boss = bosses[item.uid] or bosses[item:getActionId()] + if not boss then + return true + end + + if player:getStorageValue(boss.storage) ~= 1 or roomIsOccupied(boss.centerPosition, boss.rangeX, boss.rangeY) then + player:teleportTo(fromPosition, true) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + player:setStorageValue(boss.storage, 0) + player:teleportTo(boss.playerPosition) + boss.playerPosition:sendMagicEffect(CONST_ME_TELEPORT) + + local monster = Game.createMonster(boss.bossName, boss.bossPosition) + if not monster then + return true + end + + addEvent(clearBossRoom, 60 * 10 * 1000, player.uid, monster.uid, boss.centerPosition, boss.rangeX, boss.rangeY, fromPosition) + player:say( + "You have ten minutes to kill and loot this boss. Otherwise you will lose that chance and will be kicked out.", + TALKTYPE_MONSTER_SAY + ) + return true +end + +boss:type("stepin") + +for index, value in pairs(bosses) do + boss:uid(index) +end + +boss:register() diff --git a/data/scripts/movements/quests/kilmaresh/firetp.lua b/data/scripts/movements/quests/kilmaresh/firetp.lua new file mode 100644 index 00000000000..d9100b5d9a9 --- /dev/null +++ b/data/scripts/movements/quests/kilmaresh/firetp.lua @@ -0,0 +1,124 @@ +local primeirotp = { + configaid = 57539, -- action id teleport + localfireum = {x = 33830, y = 31628, z = 9}, -- local do fire um + localfiredois = {x = 33832, y = 31628, z = 9}, -- local do fire dois + localfiretres = {x = 33834, y = 31628, z = 9}, -- local do fire tres + fireon = 7527, -- id do fire on + fireoff = 1485, -- id do fire off +} + +local segundotp = { + configaid = 57540, -- action id teleport + localfireum = {x = 33830, y = 31628, z = 9}, -- local do fire um + localfiredois = {x = 33832, y = 31628, z = 9}, -- local do fire dois + localfiretres = {x = 33834, y = 31628, z = 9}, -- local do fire tres + fireon = 7527, -- id do fire on + fireoff = 1485, -- id do fire off +} + +local terceirotp = { + configaid = 57541, -- action id teleport + localfireum = {x = 33830, y = 31628, z = 9}, -- local do fire um + localfiredois = {x = 33832, y = 31628, z = 9}, -- local do fire dois + localfiretres = {x = 33834, y = 31628, z = 9}, -- local do fire tres + fireon = 7527, -- id do fire on + fireoff = 1485, -- id do fire off +} + +local quartotp = { + configaid = 57542, -- action id teleport + localfireum = {x = 33830, y = 31628, z = 9}, -- local do fire um + localfiredois = {x = 33832, y = 31628, z = 9}, -- local do fire dois + localfiretres = {x = 33834, y = 31628, z = 9}, -- local do fire tres + fireon = 7527, -- id do fire on + fireoff = 1485, -- id do fire off +} + + +local errotp = {x = 33822, y = 31645, z = 9} -- errou +local finaltp = {x = 33826, y = 31620, z = 9} -- deu certo + +local firetp = MoveEvent() + +function firetp.onStepIn(creature, item, position, fromPosition) + + + local player = creature:getPlayer() + if not player then + return true + end + + + local firstfasefireum = Tile(primeirotp.localfireum):getItemById(primeirotp.fireoff) + local firstfasefiredois = Tile(primeirotp.localfiredois):getItemById(primeirotp.fireoff) + local firstfasefiretres = Tile(primeirotp.localfiretres):getItemById(primeirotp.fireoff) + + if item.actionid == primeirotp.configaid then + if firstfasefireum and firstfasefiredois and firstfasefiretres then + player:teleportTo(finaltp) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:teleportTo(errotp) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + + + + local secondfasefireum = Tile(segundotp.localfireum):getItemById(segundotp.fireon) + local secondfasefiredois = Tile(segundotp.localfiredois):getItemById(segundotp.fireoff) + local secondfasefiretres = Tile(segundotp.localfiretres):getItemById(segundotp.fireoff) + + if item.actionid == segundotp.configaid then + if secondfasefireum and secondfasefiredois and secondfasefiretres then + player:teleportTo(finaltp) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:teleportTo(errotp) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + + + + local thirdfasefireum = Tile(terceirotp.localfireum):getItemById(terceirotp.fireon) + local thirdfasefiredois = Tile(terceirotp.localfiredois):getItemById(terceirotp.fireon) + local thirdfasefiretres = Tile(terceirotp.localfiretres):getItemById(terceirotp.fireoff) + + if item.actionid == terceirotp.configaid then + if thirdfasefireum and thirdfasefiredois and thirdfasefiretres then + player:teleportTo(finaltp) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:teleportTo(errotp) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + + + + local fourthfasefireum = Tile(quartotp.localfireum):getItemById(quartotp.fireon) + local fourthfasefiredois = Tile(quartotp.localfiredois):getItemById(quartotp.fireon) + local fourthfasefiretres = Tile(quartotp.localfiretres):getItemById(quartotp.fireon) + + if item.actionid == quartotp.configaid then + if fourthfasefireum and fourthfasefiredois and fourthfasefiretres then + player:teleportTo(finaltp) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:teleportTo(errotp) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + end + + + + + return true +end + +firetp:aid(57539, 57540, 57541, 57542) +firetp:register() + + + diff --git a/data/scripts/movements/quests/kilmaresh/pisatile.lua b/data/scripts/movements/quests/kilmaresh/pisatile.lua new file mode 100644 index 00000000000..40570c83d02 --- /dev/null +++ b/data/scripts/movements/quests/kilmaresh/pisatile.lua @@ -0,0 +1,44 @@ +local config = { + [57535] = {active = 57535, tileId = 413, positionto = {x = 33829, y = 31635, z = 9}}, + [57536] = {active = 57536, tileId = 414, positionto = {x = 33831, y = 31635, z = 9}}, + [57537] = {active = 57537, tileId = 415, positionto = {x = 33833, y = 31635, z = 9}}, + [57538] = {active = 57538, tileId = 420, positionto = {x = 33835, y = 31635, z = 9}} +} + +local errotp = {x = 33826, y = 31611, z = 9} + +local pegapisoum = {x = 33829, y = 31616, z = 9} + + +local pisatile = MoveEvent() + +function pisatile.onStepIn(player, item, frompos, item2, topos) + + local tilescon = config[item.actionid] + if not tilescon then + return true + end + + + local idpegapisoum = Tile(pegapisoum):getItemById(413) -- verifica primeiro piso + + + + + if tilescon.tileId == idpegapisoum then + + else + player:teleportTo(errotp) + end + + + + + + + + return true +end + +pisatile:aid(57535, 57536, 57537, 57538) +pisatile:register() \ No newline at end of file diff --git a/data/scripts/movements/quests/kilmaresh/tpvoc.lua b/data/scripts/movements/quests/kilmaresh/tpvoc.lua new file mode 100644 index 00000000000..952298a1217 --- /dev/null +++ b/data/scripts/movements/quests/kilmaresh/tpvoc.lua @@ -0,0 +1,48 @@ +local setting = { + [57531] = { + vocationId = VOCATION.CLIENT_ID.SORCERER, + toPosition = {x = 33829, y = 31635, z = 9} + }, + [57532] = { + vocationId = VOCATION.CLIENT_ID.DRUID, + toPosition = {x = 33831, y = 31635, z = 9} + }, + [57533] = { + vocationId = VOCATION.CLIENT_ID.PALADIN, + toPosition = {x = 33833, y = 31635, z = 9} + }, + [57534] = { + vocationId = VOCATION.CLIENT_ID.KNIGHT, + toPosition = {x = 33835, y = 31635, z = 9} + } +} + +local tpvoc = MoveEvent() + +function tpvoc.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local vocation = setting[item.actionid] + if not vocation then + return true + end + + if player:getVocation():getClientId() == vocation.vocationId then + player:teleportTo(vocacoes.toPosition) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:teleportTo({x = 33822, y = 31645, z = 9}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + + return true +end + +for key = 57531, 57534 do + tpvoc:aid(key) +end + +tpvoc:register() diff --git a/data/scripts/movements/quests/krailos/access_depot.lua b/data/scripts/movements/quests/krailos/access_depot.lua new file mode 100644 index 00000000000..3a49ed7b68d --- /dev/null +++ b/data/scripts/movements/quests/krailos/access_depot.lua @@ -0,0 +1,22 @@ +local setting = { + [19049] = {position = Position(33657, 31658, 8)}, --Entrance +} + +local accessDepot = MoveEvent() + +function accessDepot.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local portal = setting[item.actionid] + if portal then + player:teleportTo(portal.position) + end + return true +end + +accessDepot:type("stepin") +accessDepot:aid(19049) +accessDepot:register() diff --git a/data/scripts/movements/quests/lions_rock/lions_rock.lua b/data/scripts/movements/quests/lions_rock/lions_rock.lua new file mode 100644 index 00000000000..7d0aa0d6294 --- /dev/null +++ b/data/scripts/movements/quests/lions_rock/lions_rock.lua @@ -0,0 +1,102 @@ +local UniqueTable = { + [25001] = { + storage = Storage.LionsRock.SnakeSign, + needStorage = Storage.LionsRock.Questline, + value = 5, + item = 23836, + message1 = "With the aid of the old scroll you translate the inscriptions on the floor: \z + And the mighty lion defeated the jealous snake.", + message2 = "As a sign of victory he tooks its eye, yellow as envy and malevolence, and out \z + of a foul creature created a precious treasure." + }, + [25002] = { + storage = Storage.LionsRock.LizardSign, + needStorage = Storage.LionsRock.Questline, + value = 5, + item = 23836, + message1 = "With the aid of the old scroll you translate the inscriptions on the floor: \z + And the mighty lion defeated the lazy lizard.", + message2 = "As a sign of victory he tooks its egg, blue as sloth and conceit, and out \z + of a foul creature created a precious treasure." + }, + [25003] = { + storage = Storage.LionsRock.ScorpionSign, + needStorage = Storage.LionsRock.Questline, + value = 5, + item = 23836, + message1 = "With the aid of the old scroll you translate the inscriptions on the golden altar: \z + And the mighty lion defeated the treacherous scorpion.", + message2 = "As a sign of victory he tooks its poison, violet as deceit and betrayal, and \z + created a precious treasure." + }, + [25004] = { + storage = Storage.LionsRock.HyenaSign, + needStorage = Storage.LionsRock.Questline, + value = 5, + item = 23836, + message1 = "With the aid of the old scroll you translate the inscriptions on the golden statue: \z + And the mighty lion defeated the greedy hyaena.", + message2 = "As a sign of victory he tooks its blood, red as voracity and lust, and \z + created a precious treasure." + } +} + +-- Lions rock entrance +local lionsRockEntrance = MoveEvent() + +function lionsRockEntrance.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.LionsRock.Questline) >= 4 then + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo({x = 33122, y = 32308, z = 8}) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have passed the Lion's Tests and are now worthy to enter the inner sanctum!") + player:getPosition():sendMagicEffect(CONST_ME_THUNDER) + else + player:getPosition():sendMagicEffect(CONST_ME_ENERGYHIT) + player:teleportTo(fromPosition, true) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have to pass the Lion's Tests to enter the inner sanctum!") + end + return true +end + +lionsRockEntrance:uid(35009) +lionsRockEntrance:register() + +-- Lions rock sign +local lionsRockSigns = MoveEvent() + +function lionsRockSigns.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + + local setting = UniqueTable[item.uid] + if not setting then + return true + end + + local currentStorage = player:getStorageValue(setting.needStorage) + if currentStorage >= setting.value and currentStorage < 10 then + if player:getStorageValue(setting.storage) < 1 then + if player:getItemCount(setting.item) == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, setting.message1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, setting.message2) + player:setStorageValue(setting.needStorage, player:getStorageValue(setting.needStorage) + 1) + player:setStorageValue(setting.storage, 1) + end + end + end + + return true +end + +for index, value in pairs(UniqueTable) do + lionsRockSigns:uid(index) +end + +lionsRockSigns:register() diff --git a/data/scripts/movements/quests/liquid_black/ladder.lua b/data/scripts/movements/quests/liquid_black/ladder.lua new file mode 100644 index 00000000000..9e61a4e0468 --- /dev/null +++ b/data/scripts/movements/quests/liquid_black/ladder.lua @@ -0,0 +1,19 @@ +local ladder = MoveEvent() + +function ladder.onStepIn(creature, item, toPosition, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.LiquidBlackQuest.Visitor) >= 4 then + player:getPosition():sendMagicEffect(CONST_ME_WATERSPLASH) + else + player:teleportTo(fromPosition, true) + player:getPosition():sendMagicEffect(CONST_ME_WATERSPLASH) + end + return true +end + +ladder:aid(57745) +ladder:register() diff --git a/data/scripts/movements/quests/liquid_black/quick_access.lua b/data/scripts/movements/quests/liquid_black/quick_access.lua new file mode 100644 index 00000000000..497bb18edf8 --- /dev/null +++ b/data/scripts/movements/quests/liquid_black/quick_access.lua @@ -0,0 +1,22 @@ +local enterPosition = {x = 33446, y = 31288, z = 14} + +local quickAccess = MoveEvent() + +function quickAccess.onStepIn(creature, item, toPosition, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.LiquidBlackQuest.Visitor) >= 5 then + player:teleportTo(enterPosition) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:teleportTo(fromPosition, true) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +quickAccess:aid(57747) +quickAccess:register() diff --git a/data/scripts/movements/quests/liquid_black/shortcut.lua b/data/scripts/movements/quests/liquid_black/shortcut.lua new file mode 100644 index 00000000000..8fa08542e15 --- /dev/null +++ b/data/scripts/movements/quests/liquid_black/shortcut.lua @@ -0,0 +1,23 @@ +local enterPosition = {x = 33478, y = 31314, z = 7} + +local shortcut = MoveEvent() + +function shortcut.onStepIn(creature, item, toPosition, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.LiquidBlackQuest.Visitor) >= 4 then + player:setStorageValue(Storage.LiquidBlackQuest.Visitor, 5) + player:teleportTo(enterPosition) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:teleportTo(fromPosition, true) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +shortcut:aid(57746) +shortcut:register() diff --git a/data/scripts/movements/quests/nightmare_isles/teleport.lua b/data/scripts/movements/quests/nightmare_isles/teleport.lua new file mode 100644 index 00000000000..c5be3307991 --- /dev/null +++ b/data/scripts/movements/quests/nightmare_isles/teleport.lua @@ -0,0 +1,42 @@ +local setting = { + {storage = 210001, teleportPosition = Position(33032, 32400, 7)}, -- entrance teleport Darashia Northwest + {storage = 210002, teleportPosition = Position(33215, 32273, 7)}, -- entrance teleport Darashia North + {storage = 210016, teleportPosition = Position(33255, 32678, 7)} -- {x = 33255, y = 32678, z = 7} +} + +local teleports = { + [64001] = 210001, -- northwest Darashia + [64002] = 210002, -- north Darashia + [64003] = 210016 -- north Ankrahmun +} + +local teleport = MoveEvent() + +function teleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + + for i = 1, #setting do + local table = setting[i] + local backStorage = table.storage + if player:getStorageValue(backStorage) >= 1 then + player:teleportTo(table.teleportPosition) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:setStorageValue(backStorage, 0) + break + end + end + + local storagePortal = teleports[item.uid] + if storagePortal then + player:teleportTo(Position(33497, 32616, 8)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:setStorageValue(storagePortal, 1) + end + return true +end + +teleport:uid(35020, 64001, 64002, 64003) +teleport:register() diff --git a/data/scripts/movements/quests/nightmare_isles/teleport_ladder.lua b/data/scripts/movements/quests/nightmare_isles/teleport_ladder.lua new file mode 100644 index 00000000000..0fd79a4b9a8 --- /dev/null +++ b/data/scripts/movements/quests/nightmare_isles/teleport_ladder.lua @@ -0,0 +1,53 @@ +local setting = { + [64103] = Position(33475, 32641, 10), + [64104] = Position(33473, 32647, 9), + [64105] = Position(33463, 32585, 8), + [64106] = Position(33457, 32580, 8), + [64107] = Position(33422, 32582, 8), + [64108] = Position(33430, 32600, 10), + [64109] = Position(33420, 32604, 10), + [64120] = Position(33446, 32616, 11), + [64121] = Position(33460, 32632, 10), + [64122] = Position(33429, 32626, 10), + [64123] = Position(33425, 32633, 8), + [64124] = Position(33435, 32631, 8), + [64125] = Position(33478, 32621, 10), + [64126] = Position(33484, 32629, 8), + [64127] = Position(33452, 32617, 11), + [64128] = Position(33419, 32589, 10) +} + +local teleportLadder = MoveEvent() + +function teleportLadder.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.TheShatteredIsles.AccessToLagunaIsland) ~= 1 and item.uid == 3206 then + local accessPosition = Position(32340, 32540, 7) + player:teleportTo(accessPosition) + position:sendMagicEffect(CONST_ME_TELEPORT) + accessPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + local targetPosition = setting[item.actionid] + if not targetPosition then + return true + end + + player:teleportTo(targetPosition) + position:sendMagicEffect(CONST_ME_TELEPORT) + targetPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +teleportLadder:type("stepin") + +for index, value in pairs(setting) do + teleportLadder:aid(index) +end + +teleportLadder:register() diff --git a/data/scripts/movements/quests/pits_of_inferno/bazir_tile.lua b/data/scripts/movements/quests/pits_of_inferno/bazir_tile.lua new file mode 100644 index 00000000000..542dc88edfe --- /dev/null +++ b/data/scripts/movements/quests/pits_of_inferno/bazir_tile.lua @@ -0,0 +1,32 @@ +local setting = { + [16772] = Position(32754, 32365, 15), + [16773] = Position(32725, 32381, 15), + [16774] = Position(32827, 32241, 12), + [50082] = Position(32745, 32394, 14), + [50083] = Position(32745, 32394, 14) +} + +local bazirTile = MoveEvent() + +function bazirTile.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local targetPosition = setting[item.actionid] + if not targetPosition then + return true + end + + player:teleportTo(targetPosition) + return true +end + +bazirTile:type("stepin") + +for index, value in pairs(setting) do + bazirTile:aid(index) +end + +bazirTile:register() diff --git a/data/scripts/movements/quests/pits_of_inferno/check_throne.lua b/data/scripts/movements/quests/pits_of_inferno/check_throne.lua new file mode 100644 index 00000000000..a941bd5b889 --- /dev/null +++ b/data/scripts/movements/quests/pits_of_inferno/check_throne.lua @@ -0,0 +1,37 @@ +local setting = { + [2090] = {storage = Storage.PitsOfInferno.ThroneInfernatil, value = 1}, + [2091] = {storage = Storage.PitsOfInferno.ThroneTafariel, value = 1}, + [2092] = {storage = Storage.PitsOfInferno.ThroneVerminor, value = 1}, + [2093] = {storage = Storage.PitsOfInferno.ThroneApocalypse, value = 1}, + [2094] = {storage = Storage.PitsOfInferno.ThroneBazir, value = 1}, + [2095] = {storage = Storage.PitsOfInferno.ThroneAshfalor, value = 1}, + [2096] = {storage = Storage.PitsOfInferno.ThronePumin, value = 1} +} + +local checkThrone = MoveEvent() + +function checkThrone.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local thrones = setting[item.uid] + if not thrones then + return true + end + + if player:getStorageValue(thrones.storage) ~= thrones.value then + player:teleportTo(fromPosition, true) + player:say("You've not absorbed energy from this throne.", TALKTYPE_MONSTER_SAY) + end + return true +end + +checkThrone:type("stepin") + +for index, value in pairs(setting) do + checkThrone:uid(index) +end + +checkThrone:register() diff --git a/data/scripts/movements/quests/pits_of_inferno/drawbridge.lua b/data/scripts/movements/quests/pits_of_inferno/drawbridge.lua new file mode 100644 index 00000000000..8e91a25d36a --- /dev/null +++ b/data/scripts/movements/quests/pits_of_inferno/drawbridge.lua @@ -0,0 +1,56 @@ +local bridgePosition = Position(32851, 32309, 11) +local relocatePosition = Position(32852, 32310, 11) +local dirtIds = {4808, 4810} + +local drawbridge = MoveEvent() + +function drawbridge.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local tile = Tile(bridgePosition) + local lavaItem = tile:getItemById(598) + if lavaItem then + lavaItem:transform(1284) + + local dirtItem + for i = 1, #dirtIds do + dirtItem = tile:getItemById(dirtIds[i]) + if dirtItem then + dirtItem:remove() + end + end + end + return true +end + +drawbridge:type("stepin") +drawbridge:aid(4002) +drawbridge:register() + +drawbridge = MoveEvent() + +function drawbridge.onStepOut(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local tile = Tile(bridgePosition) + local bridgeItem = tile:getItemById(1284) + if bridgeItem then + tile:relocateTo(relocatePosition) + bridgeItem:transform(598) + + for i = 1, #dirtIds do + Game.createItem(dirtIds[i], 1, bridgePosition) + end + end + return true +end + +drawbridge:type("stepout") +drawbridge:aid(4002) +drawbridge:register() diff --git a/data/scripts/movements/quests/pits_of_inferno/fire_tile.lua b/data/scripts/movements/quests/pits_of_inferno/fire_tile.lua new file mode 100644 index 00000000000..0151275f2b8 --- /dev/null +++ b/data/scripts/movements/quests/pits_of_inferno/fire_tile.lua @@ -0,0 +1,59 @@ +local fires = { + [2040] = {vocationId = VOCATION.CLIENT_ID.SORCERER, damage = 300}, + [2041] = {vocationId = VOCATION.CLIENT_ID.SORCERER, damage = 600}, + [2042] = {vocationId = VOCATION.CLIENT_ID.SORCERER, damage = 1200}, + [2043] = {vocationId = VOCATION.CLIENT_ID.SORCERER, damage = 2400}, + [2044] = {vocationId = VOCATION.CLIENT_ID.SORCERER, damage = 3600}, + [2045] = {vocationId = VOCATION.CLIENT_ID.SORCERER, damage = 7200}, + [2046] = {vocationId = VOCATION.CLIENT_ID.DRUID, damage = 300}, + [2047] = {vocationId = VOCATION.CLIENT_ID.DRUID, damage = 600}, + [2048] = {vocationId = VOCATION.CLIENT_ID.DRUID, damage = 1200}, + [2049] = {vocationId = VOCATION.CLIENT_ID.DRUID, damage = 2400}, + [2050] = {vocationId = VOCATION.CLIENT_ID.DRUID, damage = 3600}, + [2051] = {vocationId = VOCATION.CLIENT_ID.DRUID, damage = 7200}, + [2052] = {vocationId = VOCATION.CLIENT_ID.PALADIN, damage = 300}, + [2053] = {vocationId = VOCATION.CLIENT_ID.PALADIN, damage = 600}, + [2054] = {vocationId = VOCATION.CLIENT_ID.PALADIN, damage = 1200}, + [2055] = {vocationId = VOCATION.CLIENT_ID.PALADIN, damage = 2400}, + [2056] = {vocationId = VOCATION.CLIENT_ID.PALADIN, damage = 3600}, + [2057] = {vocationId = VOCATION.CLIENT_ID.PALADIN, damage = 7200}, + [2058] = {vocationId = VOCATION.CLIENT_ID.KNIGHT, damage = 300}, + [2059] = {vocationId = VOCATION.CLIENT_ID.KNIGHT, damage = 600}, + [2060] = {vocationId = VOCATION.CLIENT_ID.KNIGHT, damage = 1200}, + [2061] = {vocationId = VOCATION.CLIENT_ID.KNIGHT, damage = 2400}, + [2062] = {vocationId = VOCATION.CLIENT_ID.KNIGHT, damage = 3600}, + [2063] = {vocationId = VOCATION.CLIENT_ID.KNIGHT, damage = 7200} +} + +local fireTile = MoveEvent() + +function fireTile.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local fire = fires[item.actionid] + if not fire then + return true + end + + if player:getVocation():getClientId() == fire.vocationId then + doTargetCombatHealth(0, player, COMBAT_FIREDAMAGE, -300, -300, CONST_ME_HITBYFIRE) + else + local combatType = COMBAT_FIREDAMAGE + if fire.damage > 300 then + combatType = COMBAT_PHYSICALDAMAGE + end + doTargetCombatHealth(0, player, combatType, -fire.damage, -fire.damage, CONST_ME_FIREATTACK) + end + return true +end + +fireTile:type("stepin") + +for index, value in pairs(fires) do + fireTile:aid(index) +end + +fireTile:register() diff --git a/data/scripts/movements/quests/pits_of_inferno/holy_tible_tile.lua b/data/scripts/movements/quests/pits_of_inferno/holy_tible_tile.lua new file mode 100644 index 00000000000..d5c7d081590 --- /dev/null +++ b/data/scripts/movements/quests/pits_of_inferno/holy_tible_tile.lua @@ -0,0 +1,30 @@ +local destinations = { + [2000] = Position(32791, 32331, 10), + [2001] = Position(32791, 32327, 10) +} + +local holyTibleTile = MoveEvent() + +function holyTibleTile.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return false + end + + if player:getItemCount(1970) < 1 then + player:teleportTo(fromPosition, true) + return true + end + + player:teleportTo(destinations[item.uid]) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +holyTibleTile:type("stepin") + +for index, value in pairs(destinations) do + holyTibleTile:uid(index) +end + +holyTibleTile:register() diff --git a/data/scripts/movements/quests/pits_of_inferno/ladder.lua b/data/scripts/movements/quests/pits_of_inferno/ladder.lua new file mode 100644 index 00000000000..1c23fe7ca5b --- /dev/null +++ b/data/scripts/movements/quests/pits_of_inferno/ladder.lua @@ -0,0 +1,40 @@ +local ladderPosition = Position(32854, 32321, 11) +local ladder = MoveEvent() + +function ladder.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local ladderItem = Tile(ladderPosition):getItemById(5543) + if not ladderItem then + Game.createItem(5543, 1, ladderPosition) + player:say("You hear a rumbling from far away.", TALKTYPE_MONSTER_SAY, false, player) + end + return true +end + +ladder:type("stepin") +ladder:uid(2002) +ladder:register() + +ladder = MoveEvent() + +function ladder.onStepOut(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local ladderItem = Tile(Position(32854, 32321, 11)):getItemById(5543) + if ladderItem then + ladderItem:remove() + player:say("You hear a rumbling from far away.", TALKTYPE_MONSTER_SAY, false, player) + end + return true +end + +ladder:type("stepout") +ladder:uid(2002) +ladder:register() diff --git a/data/scripts/movements/quests/pits_of_inferno/pumin_teleport.lua b/data/scripts/movements/quests/pits_of_inferno/pumin_teleport.lua new file mode 100644 index 00000000000..efd45f2b0d4 --- /dev/null +++ b/data/scripts/movements/quests/pits_of_inferno/pumin_teleport.lua @@ -0,0 +1,22 @@ +local puminTeleport = MoveEvent() + +function puminTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.PitsOfInferno.ThronePumin) < 50 then + player:teleportTo(Position(32786, 32308, 15)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:teleportTo(fromPosition) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "To enter Pumin's domain you must gain permission from the bureaucrats.") + end + return true +end + +puminTeleport:type("stepin") +puminTeleport:aid(50087) +puminTeleport:register() diff --git a/data/scripts/movements/quests/pits_of_inferno/second_trap.lua b/data/scripts/movements/quests/pits_of_inferno/second_trap.lua new file mode 100644 index 00000000000..2c32079c174 --- /dev/null +++ b/data/scripts/movements/quests/pits_of_inferno/second_trap.lua @@ -0,0 +1,28 @@ +local stonePosition = Position(32826, 32274, 11) + +function removeStone() + local stoneItem = Tile(stonePosition):getItemById(1285) + if stoneItem then + stoneItem:remove() + stonePosition:sendMagicEffect(CONST_ME_POFF) + end +end + +local secondTrap = MoveEvent() + +function secondTrap.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + player:teleportTo(Position(32826, 32273, 12)) + player:getPosition():sendMagicEffect(CONST_ME_EXPLOSIONAREA) + Game.createItem(1285, 1, stonePosition) + addEvent(removeStone, 10 * 1000) + return true +end + +secondTrap:type("stepin") +secondTrap:uid(3303) +secondTrap:register() diff --git a/data/scripts/movements/quests/pits_of_inferno/shortcuts.lua b/data/scripts/movements/quests/pits_of_inferno/shortcuts.lua new file mode 100644 index 00000000000..ff297fc01e8 --- /dev/null +++ b/data/scripts/movements/quests/pits_of_inferno/shortcuts.lua @@ -0,0 +1,27 @@ +local setting = { + [8816] = Storage.PitsOfInferno.ShortcutHubDoor, + [8817] = Storage.PitsOfInferno.ShortcutLeverDoor +} + +local shortcuts = MoveEvent() + +function shortcuts.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local storage = setting[item.actionid] + if player:getStorageValue(storage) ~= 1 then + player:setStorageValue(storage, 1) + end + return true +end + +shortcuts:type("stepin") + +for index, value in pairs(setting) do + shortcuts:aid(index) +end + +shortcuts:register() diff --git a/data/scripts/movements/quests/pits_of_inferno/stone.lua b/data/scripts/movements/quests/pits_of_inferno/stone.lua new file mode 100644 index 00000000000..886e2609f0c --- /dev/null +++ b/data/scripts/movements/quests/pits_of_inferno/stone.lua @@ -0,0 +1,21 @@ +local stone = MoveEvent() + +function stone.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local stonePosition = Position(32849, 32282, 10) + local stoneItem, leverItem = Tile(stonePosition):getItemById(1304), Tile(Position(32850, 32268, 10)):getItemById(1946) + if not stoneItem and leverItem then + Game.createItem(1304, 1, stonePosition) + leverItem:transform(1945) + player:say('You hear a rumbling from far away.', TALKTYPE_MONSTER_SAY, false, player) + end + return true +end + +stone:type("stepin") +stone:aid(4001) +stone:register() diff --git a/data/scripts/movements/quests/pits_of_inferno/throne.lua b/data/scripts/movements/quests/pits_of_inferno/throne.lua new file mode 100644 index 00000000000..54667278255 --- /dev/null +++ b/data/scripts/movements/quests/pits_of_inferno/throne.lua @@ -0,0 +1,77 @@ +local setting = { + [2080] = { + storage = Storage.PitsOfInferno.ThroneInfernatil, + text = "You have touched Infernatil's throne and absorbed some of his spirit.", + effect = CONST_ME_FIREAREA, + toPosition = Position(32909, 32211, 15) + }, + [2081] = { + storage = Storage.PitsOfInferno.ThroneTafariel, + text = "You have touched Tafariel's throne and absorbed some of his spirit.", + effect = CONST_ME_MORTAREA, + toPosition = Position(32761, 32243, 15) + }, + [2082] = { + storage = Storage.PitsOfInferno.ThroneVerminor, + text = "You have touched Verminor's throne and absorbed some of his spirit.", + effect = CONST_ME_POISONAREA, + toPosition = Position(32840, 32327, 15) + }, + [2083] = { + storage = Storage.PitsOfInferno.ThroneApocalypse, + text = "You have touched Apocalypse's throne and absorbed some of his spirit.", + effect = CONST_ME_EXPLOSIONAREA, + toPosition = Position(32875, 32267, 15) + }, + [2084] = { + storage = Storage.PitsOfInferno.ThroneBazir, + text = "You have touched Bazir's throne and absorbed some of his spirit.", + effect = CONST_ME_MAGIC_GREEN, + toPosition = Position(32745, 32385, 15) + }, + [2085] = { + storage = Storage.PitsOfInferno.ThroneAshfalor, + text = "You have touched Ashfalor's throne and absorbed some of his spirit.", + effect = CONST_ME_FIREAREA, + toPosition = Position(32839, 32310, 15) + }, + [2086] = { + storage = Storage.PitsOfInferno.ThronePumin, + text = "You have touched Pumin's throne and absorbed some of his spirit.", + effect = CONST_ME_MORTAREA, + toPosition = Position(32785, 32279, 15) + } +} + +local throne = MoveEvent() + +function throne.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local throne = setting[item.uid] + if not throne then + return true + end + + if player:getStorageValue(throne.storage) ~= 1 then + player:setStorageValue(throne.storage, 1) + player:getPosition():sendMagicEffect(throne.effect) + player:say(throne.text, TALKTYPE_MONSTER_SAY) + else + player:teleportTo(throne.toPosition) + player:getPosition():sendMagicEffect(CONST_ME_MORTAREA) + player:say("Begone!", TALKTYPE_MONSTER_SAY) + end + return true +end + +throne:type("stepin") + +for index, value in pairs(setting) do + throne:uid(index) +end + +throne:register() diff --git a/data/scripts/movements/quests/pits_of_inferno/tile_teleport.lua b/data/scripts/movements/quests/pits_of_inferno/tile_teleport.lua new file mode 100644 index 00000000000..0a1f9dcbfd9 --- /dev/null +++ b/data/scripts/movements/quests/pits_of_inferno/tile_teleport.lua @@ -0,0 +1,48 @@ +local destinations = { + [28810] = Position(32838, 32304, 9), + [28811] = Position(32839, 32320, 9), + [28812] = Position(32844, 32310, 9), + [28813] = Position(32847, 32307, 9), + [28814] = Position(32856, 32306, 9), + [28815] = Position(32827, 32308, 9), + [28816] = Position(32840, 32317, 9), + [28817] = Position(32855, 32296, 9), + [28818] = Position(32857, 32307, 9), + [28819] = Position(32856, 32289, 9), + [28820] = Position(32843, 32313, 9), + [28821] = Position(32861, 32320, 9), + [28822] = Position(32841, 32323, 9), + [28823] = Position(32847, 32287, 9), + [28824] = Position(32854, 32323, 9), + [28825] = Position(32855, 32304, 9), + [28826] = Position(32841, 32323, 9), + [28827] = Position(32861, 32317, 9), + [28828] = Position(32827, 32314, 9), + [28829] = Position(32858, 32296, 9), + [28830] = Position(32861, 32301, 9), + [28831] = Position(32855, 32321, 9), + [28832] = Position(32855, 32320, 9), + [28833] = Position(32855, 32318, 9), + [28834] = Position(32855, 32319, 9) +} + +local tileTeleport = MoveEvent() + +function tileTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + player:teleportTo(destinations[item.actionid]) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +tileTeleport:type("stepin") + +for index, value in pairs(destinations) do + tileTeleport:aid(index) +end + +tileTeleport:register() diff --git a/data/scripts/movements/quests/pits_of_inferno/trap.lua b/data/scripts/movements/quests/pits_of_inferno/trap.lua new file mode 100644 index 00000000000..f5edcf9f7ff --- /dev/null +++ b/data/scripts/movements/quests/pits_of_inferno/trap.lua @@ -0,0 +1,17 @@ +local trap = MoveEvent() + +function trap.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + position.z = position.z + 1 + player:teleportTo(position) + position:sendMagicEffect(CONST_ME_FIREATTACK) + return true +end + +trap:type("stepin") +trap:aid(7799) +trap:register() diff --git a/data/scripts/movements/quests/secret_service/amazon.lua b/data/scripts/movements/quests/secret_service/amazon.lua new file mode 100644 index 00000000000..dc983b432bc --- /dev/null +++ b/data/scripts/movements/quests/secret_service/amazon.lua @@ -0,0 +1,20 @@ +local amazon = MoveEvent() + +function amazon.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.SecretService.AVINMission03) == 1 then + player:setStorageValue(Storage.SecretService.AVINMission03, 2) + Game.createMonster("amazon", Position(32326, 31803, 8)) + Game.createMonster("amazon", Position(32330, 31803, 8)) + end + return true +end + +amazon:type("stepin") +amazon:position({x= 32328, y = 31802, z = 8}) +amazon:position({x= 32328, y = 31803, z = 8}) +amazon:register() diff --git a/data/scripts/movements/quests/secret_service/pirate.lua b/data/scripts/movements/quests/secret_service/pirate.lua new file mode 100644 index 00000000000..382fe985f3e --- /dev/null +++ b/data/scripts/movements/quests/secret_service/pirate.lua @@ -0,0 +1,19 @@ +local pirate = MoveEvent() + +function pirate.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.SecretService.TBIMission03) == 1 then + player:setStorageValue(Storage.SecretService.TBIMission03, 2) + Game.createMonster("pirate buccaneer", Position(32641, 32733, 7)) + Game.createMonster("pirate buccaneer", Position(32642, 32733, 7)) + end + return true +end + +pirate:type("stepin") +pirate:aid(12571) +pirate:register() diff --git a/data/scripts/movements/quests/svargrond_arena/arena_enter.lua b/data/scripts/movements/quests/svargrond_arena/arena_enter.lua new file mode 100644 index 00000000000..35d25f38aa0 --- /dev/null +++ b/data/scripts/movements/quests/svargrond_arena/arena_enter.lua @@ -0,0 +1,42 @@ +local arenaEnter = MoveEvent() + +function arenaEnter.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local pitId = player:getStorageValue(Storage.SvargrondArena.PitDoor) + if pitId < 1 or pitId > 10 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You cannot enter without Halvar's permission.") + player:teleportTo(fromPosition, true) + return true + end + + local arenaId = player:getStorageValue(Storage.SvargrondArena.Arena) + if not(PITS[pitId] and ARENA[arenaId]) then + player:teleportTo(fromPosition, true) + return true + end + + local occupant = SvargrondArena.getPitOccupant(pitId, player) + if occupant then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, occupant:getName() .. + " is currently in the next arena pit. Please wait until " .. (occupant:getSex() == PLAYERSEX_FEMALE + and "s" or "") .. "he is done fighting.") + player:teleportTo(fromPosition, true) + return true + end + SvargrondArena.resetPit(pitId) + SvargrondArena.scheduleKickPlayer(player.uid, pitId) + Game.createMonster(ARENA[arenaId].creatures[pitId], PITS[pitId].summon, false, true) + + player:teleportTo(PITS[pitId].center) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + player:say("FIGHT!", TALKTYPE_MONSTER_SAY) + return true +end + +arenaEnter:type("stepin") +arenaEnter:aid(25100) +arenaEnter:register() diff --git a/data/scripts/movements/quests/svargrond_arena/arena_pit.lua b/data/scripts/movements/quests/svargrond_arena/arena_pit.lua new file mode 100644 index 00000000000..d8cbfec42ad --- /dev/null +++ b/data/scripts/movements/quests/svargrond_arena/arena_pit.lua @@ -0,0 +1,74 @@ +local condition = Condition(CONDITION_OUTFIT) +condition:setTicks(120000) +condition:setOutfit({lookType = 111}) + +local arenaPit = MoveEvent() + +function arenaPit.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local playerId = player.uid + if item.actionid == 25300 then + player:addCondition(condition) + + player:setStorageValue(Storage.SvargrondArena.PitDoor, -1) + player:teleportTo(SvargrondArena.kickPosition) + player:say("Coward!", TALKTYPE_MONSTER_SAY) + SvargrondArena.cancelEvents(playerId) + return true + end + + local pitId = player:getStorageValue(Storage.SvargrondArena.PitDoor) + local arenaId = player:getStorageValue(Storage.SvargrondArena.Arena) + if pitId > 10 then + player:teleportTo(SvargrondArena.rewardPosition) + player:setStorageValue(Storage.SvargrondArena.PitDoor, 0) + + if arenaId == 1 then + SvargrondArena.rewardPosition:sendMagicEffect(CONST_ME_FIREWORK_BLUE) + player:setStorageValue(Storage.SvargrondArena.GreenhornDoor, 1) + player:say("Welcome back, little hero!", TALKTYPE_MONSTER_SAY) + elseif arenaId == 2 then + SvargrondArena.rewardPosition:sendMagicEffect(CONST_ME_FIREWORK_YELLOW) + player:setStorageValue(Storage.SvargrondArena.ScrapperDoor, 1) + player:say("Congratulations, brave warrior!", TALKTYPE_MONSTER_SAY) + elseif arenaId == 3 then + SvargrondArena.rewardPosition:sendMagicEffect(CONST_ME_FIREWORK_RED) + player:setStorageValue(Storage.SvargrondArena.WarlordDoor, 1) + player:say("Respect and honour to you, champion!", TALKTYPE_MONSTER_SAY) + end + + player:setStorageValue(Storage.SvargrondArena.Arena, player:getStorageValue(Storage.SvargrondArena.Arena) + 1) + player:say("Congratulations! You completed " .. ARENA[arenaId].name .. " arena, you should take your reward now.") + player:setStorageValue(ARENA[arenaId].questLog, 2) + player:addAchievement(ARENA[arenaId].achievement) + SvargrondArena.cancelEvents(playerId) + return true + end + + local occupant = SvargrondArena.getPitOccupant(pitId, player) + if occupant then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, occupant:getName() .. + " is currently in the next arena pit. Please wait until " .. (occupant:getSex() == PLAYERSEX_FEMALE + and "s" or "") .. "he is done fighting.") + player:teleportTo(fromPosition, true) + return true + end + + SvargrondArena.cancelEvents(playerId) + SvargrondArena.resetPit(pitId) + SvargrondArena.scheduleKickPlayer(playerId, pitId) + Game.createMonster(ARENA[arenaId].creatures[pitId], PITS[pitId].summon, false, true) + + player:teleportTo(PITS[pitId].center) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + player:say("Fight!", TALKTYPE_MONSTER_SAY) + return true +end + +arenaPit:type("stepin") +arenaPit:aid(25200, 25300) +arenaPit:register() diff --git a/data/scripts/movements/quests/svargrond_arena/arena_trophy.lua b/data/scripts/movements/quests/svargrond_arena/arena_trophy.lua new file mode 100644 index 00000000000..ba8a6888acc --- /dev/null +++ b/data/scripts/movements/quests/svargrond_arena/arena_trophy.lua @@ -0,0 +1,34 @@ +local arenaTrophy = MoveEvent() + +function arenaTrophy.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local arenaId = ARENA_TROPHY[item.uid] + if not arenaId then + return true + end + + local storage = arenaId.trophyStorage + if player:getStorageValue(storage) == 1 then + return true + end + + local rewardPosition = player:getPosition() + rewardPosition.y = rewardPosition.y - 1 + + local rewardItem = Game.createItem(arenaId.trophy, 1, rewardPosition) + if rewardItem then + rewardItem:setDescription(string.format(arenaId.desc, player:getName())) + end + + player:setStorageValue(storage, 1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + return true +end + +arenaTrophy:type("stepin") +arenaTrophy:uid(3264, 3265, 3266) +arenaTrophy:register() diff --git a/data/scripts/movements/quests/the_ancient_tombs/craft_helmet.lua b/data/scripts/movements/quests/the_ancient_tombs/craft_helmet.lua new file mode 100644 index 00000000000..427978adefa --- /dev/null +++ b/data/scripts/movements/quests/the_ancient_tombs/craft_helmet.lua @@ -0,0 +1,45 @@ +local helmetIds = {2335, 2336, 2337, 2338, 2339, 2340, 2341} + +local craftHelmet = MoveEvent() + +function craftHelmet.onAddItem(moveitem, tileitem, position) + if moveitem.itemid == 2147 then + local tile = Tile(position):getItemById(2342) + if not tile then + return true + end + + tile:transform(2343) + tile:decay() + position:sendMagicEffect(CONST_ME_FIREAREA) + Item(moveitem.uid):remove(1) + return true + end + + if not isInArray(helmetIds, moveitem.itemid) then + return true + end + + local tile, helmetItems = Tile(position), {} + local helmetItem + for i = 1, #helmetIds do + helmetItem = tile:getItemById(helmetIds[i]) + if not helmetItem then + return true + end + + helmetItems[#helmetItems + 1] = helmetItem + end + + for i = 1, #helmetItems do + helmetItems[i]:remove() + end + + Game.createItem(2342, 1, position) + position:sendMagicEffect(CONST_ME_FIREAREA) + return true +end + +craftHelmet:type("additem") +craftHelmet:aid(60626) +craftHelmet:register() diff --git a/data/scripts/movements/quests/the_ancient_tombs/enter_ashmunrah_teleport_switche_done.lua b/data/scripts/movements/quests/the_ancient_tombs/enter_ashmunrah_teleport_switche_done.lua new file mode 100644 index 00000000000..fb8d66329c0 --- /dev/null +++ b/data/scripts/movements/quests/the_ancient_tombs/enter_ashmunrah_teleport_switche_done.lua @@ -0,0 +1,23 @@ +local enterAshmunrahTeleport = MoveEvent() + +function enterAshmunrahTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if Game.getStorageValue(GlobalStorage.TheAncientTombs.AshmunrahSwitchesGlobalStorage) < 6 then + player:teleportTo(fromPosition, true) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + local destination = Position(33198, 32885, 11) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +enterAshmunrahTeleport:type("stepin") +enterAshmunrahTeleport:uid(50138) +enterAshmunrahTeleport:register() diff --git a/data/scripts/movements/quests/the_ancient_tombs/enter_diprath_teleport_switche_done.lua b/data/scripts/movements/quests/the_ancient_tombs/enter_diprath_teleport_switche_done.lua new file mode 100644 index 00000000000..eb418d07917 --- /dev/null +++ b/data/scripts/movements/quests/the_ancient_tombs/enter_diprath_teleport_switche_done.lua @@ -0,0 +1,23 @@ +local enterDiprathTeleport = MoveEvent() + +function enterDiprathTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if Game.getStorageValue(GlobalStorage.TheAncientTombs.DiprathSwitchesGlobalStorage) < 7 then + player:teleportTo(fromPosition, true) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + local destination = Position(33083, 32568, 14) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +enterDiprathTeleport:type("stepin") +enterDiprathTeleport:uid(50137) +enterDiprathTeleport:register() diff --git a/data/scripts/movements/quests/the_ancient_tombs/enter_thalas_poison_tile.lua b/data/scripts/movements/quests/the_ancient_tombs/enter_thalas_poison_tile.lua new file mode 100644 index 00000000000..782cf675ffa --- /dev/null +++ b/data/scripts/movements/quests/the_ancient_tombs/enter_thalas_poison_tile.lua @@ -0,0 +1,25 @@ +local condition = Condition(CONDITION_POISON, CONDITIONID_COMBAT) +condition:setParameter(CONDITION_PARAM_DELAYED, true) +condition:setParameter(CONDITION_PARAM_MINVALUE, 20) +condition:setParameter(CONDITION_PARAM_MAXVALUE, 70) +condition:setParameter(CONDITION_PARAM_STARTVALUE, 50) +condition:setParameter(CONDITION_PARAM_TICKINTERVAL, 6000) +condition:setParameter(CONDITION_PARAM_FORCEUPDATE, true) + +local enterThalasPoisonTile = MoveEvent() + +function enterThalasPoisonTile.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + player:getPosition():sendMagicEffect(CONST_ME_GREEN_RINGS) + player:addCondition(condition) + item:transform(417) + return true +end + +enterThalasPoisonTile:type("stepin") +enterThalasPoisonTile:uid(50136) +enterThalasPoisonTile:register() diff --git a/data/scripts/movements/quests/the_ancient_tombs/enter_thalas_teleport_switches_done.lua b/data/scripts/movements/quests/the_ancient_tombs/enter_thalas_teleport_switches_done.lua new file mode 100644 index 00000000000..b3592d39b9c --- /dev/null +++ b/data/scripts/movements/quests/the_ancient_tombs/enter_thalas_teleport_switches_done.lua @@ -0,0 +1,23 @@ +local enterThalasTeleport = MoveEvent() + +function enterThalasTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if Game.getStorageValue(GlobalStorage.TheAncientTombs.ThalasSwitchesGlobalStorage) < 8 then + player:teleportTo(fromPosition, true) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + local destination = Position(33367, 32805, 14) + player:teleportTo(Position(33367, 32805, 14)) + destination:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +enterThalasTeleport:type("stepin") +enterThalasTeleport:uid(50135) +enterThalasTeleport:register() diff --git a/data/scripts/movements/quests/the_ancient_tombs/peninsula_tomb_maze.lua b/data/scripts/movements/quests/the_ancient_tombs/peninsula_tomb_maze.lua new file mode 100644 index 00000000000..9eebedd4c7d --- /dev/null +++ b/data/scripts/movements/quests/the_ancient_tombs/peninsula_tomb_maze.lua @@ -0,0 +1,16 @@ +local peninsulaTombMaze = MoveEvent() + +function peninsulaTombMaze.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + player:teleportTo(fromPosition, true) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +peninsulaTombMaze:type("stepin") +peninsulaTombMaze:aid(12101) +peninsulaTombMaze:register() diff --git a/data/scripts/movements/quests/the_ancient_tombs/step_morguthis_blue_flames.lua b/data/scripts/movements/quests/the_ancient_tombs/step_morguthis_blue_flames.lua new file mode 100644 index 00000000000..1a07ba2db67 --- /dev/null +++ b/data/scripts/movements/quests/the_ancient_tombs/step_morguthis_blue_flames.lua @@ -0,0 +1,54 @@ +local setting = { + [50139] = Storage.TheAncientTombs.MorguthisBlueFlameStorage1, + [50140] = Storage.TheAncientTombs.MorguthisBlueFlameStorage2, + [50141] = Storage.TheAncientTombs.MorguthisBlueFlameStorage3, + [50142] = Storage.TheAncientTombs.MorguthisBlueFlameStorage4, + [50143] = Storage.TheAncientTombs.MorguthisBlueFlameStorage5, + [50144] = Storage.TheAncientTombs.MorguthisBlueFlameStorage6, + [50145] = Storage.TheAncientTombs.MorguthisBlueFlameStorage7 +} + +local stepMorguthisBlueFlames = MoveEvent() + +function stepMorguthisBlueFlames.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local storage = setting[item.uid] + if storage then + if player:getStorageValue(storage) ~= 1 then + player:setStorageValue(storage, 1) + end + + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + else + local missingStorage = false + for i = Storage.TheAncientTombs.MorguthisBlueFlameStorage1, + Storage.TheAncientTombs.MorguthisBlueFlameStorage7 do + if player:getStorageValue(i) ~= 1 then + missingStorage = true + break + end + end + + if missingStorage then + player:teleportTo(fromPosition, true) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + player:teleportTo(Position(33163, 32694, 14)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +stepMorguthisBlueFlames:type("stepin") + +for index, value in pairs(setting) do + stepMorguthisBlueFlames:uid(index) +end + +stepMorguthisBlueFlames:register() diff --git a/data/scripts/movements/quests/the_ancient_tombs/tomb_teleport.lua b/data/scripts/movements/quests/the_ancient_tombs/tomb_teleport.lua new file mode 100644 index 00000000000..951474e81f7 --- /dev/null +++ b/data/scripts/movements/quests/the_ancient_tombs/tomb_teleport.lua @@ -0,0 +1,77 @@ +local config = { + -- from Morguthis Boss + [3950] = { + removeId = 2350, + destination = Position(33182, 32714, 14), + exitDestination = Position(33231, 32705, 8) + }, + -- from Thalas Boss + [3951] = { + removeId = 2351, + destination = Position(33174, 32934, 15), + exitDestination = Position(33282, 32744, 8) + }, + -- from Mahrdis Boss + [3952] = { + removeId = 2353, + destination = Position(33126, 32591, 15), + exitDestination = Position(33250, 32832, 8) + }, + -- from Omruc Boss + [3953] = { + removeId = 2352, + destination = Position(33145, 32665, 15), + exitDestination = Position(33025, 32868, 8) + }, + -- from Rahemos Boss + [3954] = { + removeId = 2348, + destination = Position(33041, 32774, 14), + exitDestination = Position(33133, 32642, 8) + }, + -- from Dipthrah Boss + [3955] = { + removeId = 2354, + destination = Position(33349, 32827, 14), + exitDestination = Position(33131, 32566, 8) + }, + -- from Vashresamun Boss + [3956] = { + removeId = 2349, + destination = Position(33186, 33012, 14), + exitDestination = Position(33206, 32592, 8) + } +} + +local tombTeleport = MoveEvent() + +function tombTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local teleport = config[item.uid] + if not teleport then + return true + end + + if not player:removeItem(teleport.removeId, 1) then + player:teleportTo(teleport.exitDestination) + teleport.exitDestination:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + player:teleportTo(teleport.destination) + teleport.destination:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +tombTeleport:type("stepin") + +for index, value in pairs(config) do + tombTeleport:uid(index) +end + +tombTeleport:aid(12108) +tombTeleport:register() diff --git a/data/scripts/movements/quests/the_ape_city/mission4_parchment_decyphering.lua b/data/scripts/movements/quests/the_ape_city/mission4_parchment_decyphering.lua new file mode 100644 index 00000000000..306333dcfe4 --- /dev/null +++ b/data/scripts/movements/quests/the_ape_city/mission4_parchment_decyphering.lua @@ -0,0 +1,20 @@ +local mission4ParchmentDecyphering = MoveEvent() + +function mission4ParchmentDecyphering.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.TheApeCity.Questline) == 7 + and player:getStorageValue(Storage.TheApeCity.ParchmentDecyphering) ~= 1 then + player:setStorageValue(Storage.TheApeCity.ParchmentDecyphering, 1) + end + + player:say("!-! -O- I_I (/( --I Morgathla", TALKTYPE_MONSTER_SAY) + return true +end + +mission4ParchmentDecyphering:type("stepin") +mission4ParchmentDecyphering:aid(12124) +mission4ParchmentDecyphering:register() diff --git a/data/scripts/movements/quests/the_ape_city/mission9_the_deepest_catacomb_teleport.lua b/data/scripts/movements/quests/the_ape_city/mission9_the_deepest_catacomb_teleport.lua new file mode 100644 index 00000000000..1d6776f3853 --- /dev/null +++ b/data/scripts/movements/quests/the_ape_city/mission9_the_deepest_catacomb_teleport.lua @@ -0,0 +1,49 @@ +local config = { + amphoraPositions = { + Position(32792, 32527, 10), + Position(32823, 32525, 10), + Position(32876, 32584, 10), + Position(32744, 32586, 10) + }, + brokenAmphoraId = 2252 --4997 +} + +local mission9TheDeepestCatacombTeleport = MoveEvent() + +function mission9TheDeepestCatacombTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if item.uid == 12129 then + if player:getStorageValue(Storage.TheApeCity.Questline) >= 17 then + player:teleportTo(Position(32749, 32536, 10)) + position:sendMagicEffect(CONST_ME_TELEPORT) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:teleportTo(fromPosition, true) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You don't have access to this area.") + end + elseif item.uid == 12130 then + for i = 1, #config.amphoraPositions do + local amphoraItem = Tile(config.amphoraPositions[i]):getItemById(config.brokenAmphoraId) + if not amphoraItem then + player:teleportTo({x = 32852, y = 32544, z = 10}) + position:sendMagicEffect(CONST_ME_TELEPORT) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + "There are 4 large amphoras that must be broken in order to open the teleporter.") + return true + end + end + player:teleportTo({x = 32885, y = 32632, z = 11}) + position:sendMagicEffect(CONST_ME_TELEPORT) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end +end + +mission9TheDeepestCatacombTeleport:type("stepin") +mission9TheDeepestCatacombTeleport:uid(9257, 9258) +mission9TheDeepestCatacombTeleport:register() diff --git a/data/scripts/movements/quests/the_cursed_crystal/StepIn_CursedCrystal.lua b/data/scripts/movements/quests/the_cursed_crystal/StepIn_CursedCrystal.lua new file mode 100644 index 00000000000..4c67d1ff873 --- /dev/null +++ b/data/scripts/movements/quests/the_cursed_crystal/StepIn_CursedCrystal.lua @@ -0,0 +1,55 @@ +local teleports = { + [TCC_MEDUSACRYSTAL_ENTRY_MAP] = {position = TCC_MEDUSACRYSTAL_ENTRY}, -- medusa entry + [TCC_MEDUSACRYSTAL_EXIT_MAP] = {position = TCC_MEDUSACRYSTAL_EXIT}, -- medusa exit + [TCC_VORTEX_POSITION] = {position = TCC_VORTEX_TELEPORTED}, -- Vortex + [TCC_MEDUSAMSG_ONEMAP] = {}, -- medusa crystal message + [TCC_MEDUSAMSG_TWOMAP] = {}, -- medusa crystal message + [TCC_AFTERVORTEX_EXIT_ONE_MAP] = {position = TCC_AFTERVORTEX_EXIT_ONE}, -- Vortex exit 1 + [TCC_AFTERVORTEX_EXIT_TWO_MAP] = {position = TCC_AFTERVORTEX_EXIT_TWO} -- Vortex exit 2 +} + +local StepInCursedCrystal = MoveEvent() + +function StepInCursedCrystal.onStepIn(creature, item, position, fromPosition) +local player = creature:getPlayer() + if not player then + return false + end + for index, value in pairs(teleports) do + if item:getPosition() == index then + if item:getPosition() == TCC_MEDUSACRYSTAL_ENTRY_MAP then + if (player:getStorageValue(Storage.TibiaTales.TheCursedCrystal.Oneeyedjoe) > 0) then + doSendMagicEffect(player:getPosition(), CONST_ME_TELEPORT) + player:teleportTo(value.position) + doSendMagicEffect(value.position, CONST_ME_TELEPORT) + else + nopermission(player, fromPosition) + end + return + elseif item:getPosition() == TCC_MEDUSAMSG_ONEMAP or item:getPosition() == TCC_MEDUSAMSG_TWOMAP then + if(player:getStorageValue(Storage.TibiaTales.TheCursedCrystal.MedusaOil) < os.time())then + if (player:getStorageValue(Storage.TibiaTales.TheCursedCrystal.Questline) == 0)then + player:setStorageValue(Storage.TibiaTales.TheCursedCrystal.Questline, 1) + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "This small room could once have been a shrine of some kind. You discover an old inscription between two ornate stone walls.") + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The text is partly crumbled: 'Take ... vial of emb... fl... and mix ... a medusa's bl.... Then .. the dust of ... crystal, so ... will get the Medusa's Ointm... powerful ... able to unpetrify ...") + return + end + else + doSendMagicEffect(player:getPosition(), CONST_ME_TELEPORT) + player:teleportTo(value.position) + doSendMagicEffect(value.position, CONST_ME_TELEPORT) + return + end + end + end +end +function nopermission(teleporter, fromthisposition) + teleporter:teleportTo(fromthisposition, false) + doSendMagicEffect(fromthisposition, CONST_ME_TELEPORT) + teleporter:say("You need permision to access this area.", TALKTYPE_MONSTER_SAY) +end + +StepInCursedCrystal:type("stepin") +StepInCursedCrystal:aid(25018, 35001) +StepInCursedCrystal:register() diff --git a/data/scripts/movements/quests/the_gravedigger_of_drefia/dormitory_teleport.lua b/data/scripts/movements/quests/the_gravedigger_of_drefia/dormitory_teleport.lua new file mode 100644 index 00000000000..0cc519c4f42 --- /dev/null +++ b/data/scripts/movements/quests/the_gravedigger_of_drefia/dormitory_teleport.lua @@ -0,0 +1,29 @@ +local dormitoryTeleport = MoveEvent() + +function dormitoryTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if item.actionid == 4534 + and player:getStorageValue(Storage.GravediggerOfDrefia.Mission55) == 1 + and player:getStorageValue(Storage.GravediggerOfDrefia.Mission56) < 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission56,1) + player:setStorageValue(Storage.GravediggerOfDrefia.Mission57,1) + player:teleportTo(Position(33015, 32440, 10)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + "You should hurry, try not to dwell here any longer than a few minutes.") + Game.createMonster("necromancer servant", {x = 33008, y = 32437, z = 11}) + else + player:teleportTo(Position(33018, 32437, 10)) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The teleport is accessible only once.") + player:getPosition():sendMagicEffect(CONST_ME_POFF) + end + return true +end + +dormitoryTeleport:type("stepin") +dormitoryTeleport:aid(4534, 4535) +dormitoryTeleport:register() diff --git a/data/scripts/movements/quests/the_gravedigger_of_drefia/necromancer_servant.lua b/data/scripts/movements/quests/the_gravedigger_of_drefia/necromancer_servant.lua new file mode 100644 index 00000000000..d262d2fdec1 --- /dev/null +++ b/data/scripts/movements/quests/the_gravedigger_of_drefia/necromancer_servant.lua @@ -0,0 +1,18 @@ +local necromancerServant = MoveEvent() + +function necromancerServant.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.GravediggerOfDrefia.Mission56) == 1 + and player:getStorageValue(Storage.GravediggerOfDrefia.Mission57) ~= 1 then + player:setStorageValue(Storage.GravediggerOfDrefia.Mission57, 1) + Game.createMonster('necromancer servant', Position(33011, 32437, 11)) + end +end + +necromancerServant:type("stepin") +necromancerServant:aid(4541, 4542) +necromancerServant:register() diff --git a/data/scripts/movements/quests/the_gravedigger_of_drefia/sacrifice_teleport.lua b/data/scripts/movements/quests/the_gravedigger_of_drefia/sacrifice_teleport.lua new file mode 100644 index 00000000000..14d98de5393 --- /dev/null +++ b/data/scripts/movements/quests/the_gravedigger_of_drefia/sacrifice_teleport.lua @@ -0,0 +1,21 @@ +local sacrificeTeleport = MoveEvent() + +function sacrificeTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if item.actionid == 4541 and player:getStorageValue(Storage.GravediggerOfDrefia.Mission73) == 1 then + player:teleportTo(Position(33015, 32422, 11)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:teleportTo(Position(33021, 32419, 11)) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + end + return true +end + +sacrificeTeleport:type("stepin") +sacrificeTeleport:aid(4536) +sacrificeTeleport:register() diff --git a/data/scripts/movements/quests/the_gravedigger_of_drefia/teleport.lua b/data/scripts/movements/quests/the_gravedigger_of_drefia/teleport.lua new file mode 100644 index 00000000000..39d81017b3e --- /dev/null +++ b/data/scripts/movements/quests/the_gravedigger_of_drefia/teleport.lua @@ -0,0 +1,42 @@ +local setting = { + [4530] = { + firstStorage = Storage.GravediggerOfDrefia.Mission05, + secondStorage = Storage.GravediggerOfDrefia.Mission06, + firstDestination = Position(32987, 32401, 9), + secondDestination = Position(32988, 32397, 9) + }, + [4532] = { + storage = Storage.GravediggerOfDrefia.Mission08, + storageTwo = Storage.GravediggerOfDrefia.Mission09, + firstDestination = Position(33022, 32334, 10), + secondDestination = Position(33022, 32338, 10) + } +} + +local teleport = MoveEvent() + +function teleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local teleport = setting[item.actionid] + if teleport and player:getStorageValue(teleport.firstStorage) == 1 + and player:getStorageValue(teleport.secondStorage) < 1 then + player:teleportTo(teleport.firstDestination) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:teleportTo(teleport.secondDestination) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + end + return true +end + +teleport:type("stepin") + +for index, value in pairs(setting) do + teleport:aid(index) +end + +teleport:register() diff --git a/data/scripts/movements/quests/the_hidden_city_of_beregar/bellow.lua b/data/scripts/movements/quests/the_hidden_city_of_beregar/bellow.lua new file mode 100644 index 00000000000..34fdb113948 --- /dev/null +++ b/data/scripts/movements/quests/the_hidden_city_of_beregar/bellow.lua @@ -0,0 +1,29 @@ +local bellow = MoveEvent() + +function bellow.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local crucibleItem = Tile(Position(32699, 31494, 11)):getItemById(8641) + if not crucibleItem then + return true + end + + if crucibleItem.actionid == 0 then + crucibleItem:setActionId(50120) + Position(32696, 31494, 11):sendMagicEffect(CONST_ME_POFF) + elseif crucibleItem.actionid == 50120 then + crucibleItem:setActionId(50121) + Position(32695, 31494, 10):sendMagicEffect(CONST_ME_POFF) + elseif crucibleItem.actionid == 50121 then + player:say('TSSSSHHHHH', TALKTYPE_MONSTER_SAY, false, 0, Position(32695, 31494, 11)) + player:say('CHOOOOOOOHHHHH', TALKTYPE_MONSTER_SAY, false, 0, Position(32698, 31492, 11)) + end + return true +end + +bellow:type("stepin") +bellow:uid(50107) +bellow:register() diff --git a/data/scripts/movements/quests/the_hidden_city_of_beregar/elevator.lua b/data/scripts/movements/quests/the_hidden_city_of_beregar/elevator.lua new file mode 100644 index 00000000000..1828f0fd1f1 --- /dev/null +++ b/data/scripts/movements/quests/the_hidden_city_of_beregar/elevator.lua @@ -0,0 +1,34 @@ +local setting = { + [50092] = Position(32612, 31499, 15), + [50093] = Position(32612, 31499, 14) +} + +local elevator = MoveEvent() + +function elevator.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local teleport = setting[item.actionid] + if not teleport then + return true + end + + if player:getStorageValue(Storage.HiddenCityOfBeregar.GoingDown) == 2 then + player:teleportTo(teleport) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You don't know how to use this yet.") + end + return true +end + +elevator:type("stepin") + +for index, value in pairs(setting) do + elevator:aid(index) +end + +elevator:register() diff --git a/data/scripts/movements/quests/the_hidden_city_of_beregar/gap.lua b/data/scripts/movements/quests/the_hidden_city_of_beregar/gap.lua new file mode 100644 index 00000000000..684234ff28c --- /dev/null +++ b/data/scripts/movements/quests/the_hidden_city_of_beregar/gap.lua @@ -0,0 +1,16 @@ +local gap = MoveEvent() + +function gap.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + player:teleportTo(Position(32569, 31507, 9)) + player:say("Use the wagon to pass the gap.", TALKTYPE_MONSTER_SAY) + return true +end + +gap:type("stepin") +gap:aid(50111) +gap:register() diff --git a/data/scripts/movements/quests/the_hidden_city_of_beregar/ore_wagon.lua b/data/scripts/movements/quests/the_hidden_city_of_beregar/ore_wagon.lua new file mode 100644 index 00000000000..683bef87e66 --- /dev/null +++ b/data/scripts/movements/quests/the_hidden_city_of_beregar/ore_wagon.lua @@ -0,0 +1,19 @@ +local oreWagon = MoveEvent() + +function oreWagon.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.HiddenCityOfBeregar.OreWagon) ~= 1 then + player:setStorageValue(Storage.HiddenCityOfBeregar.OreWagon, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + "You have found the entrance to the hidden city of Beregar and may now use the ore wagon.") + end + return true +end + +oreWagon:type("stepin") +oreWagon:aid(50091) +oreWagon:register() diff --git a/data/scripts/movements/quests/the_hidden_city_of_beregar/pythius_boss_teleport.lua b/data/scripts/movements/quests/the_hidden_city_of_beregar/pythius_boss_teleport.lua new file mode 100644 index 00000000000..da594cfb4cf --- /dev/null +++ b/data/scripts/movements/quests/the_hidden_city_of_beregar/pythius_boss_teleport.lua @@ -0,0 +1,74 @@ +local function roomIsOccupied() + local spectators = Game.getSpectators(Position(32566, 31406, 15), false, true, 7, 7) + if #spectators ~= 0 then + return true + end + return false +end + +local pythiusBossTeleport = MoveEvent() + +function pythiusBossTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if item.actionid == 50126 then + if player:getStorageValue(Storage.QuestChests.FirewalkerBoots) == 1 or roomIsOccupied() then + player:teleportTo(fromPosition, true) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + item:remove() + + local steamPosition = Position(32551, 31379, 15) + iterateArea( + function(position) + local groundItem = Tile(position):getGround() + if groundItem and groundItem.itemid == 5815 then + groundItem:transform(598) + end + end, + Position(32550, 31373, 15), + steamPosition + ) + + Game.createItem(1304, 1, steamPosition) + local steamItem = Game.createItem(9341, 1, steamPosition) + if steamItem then + steamItem:setActionId(50127) + end + + local destination = Position(32560, 31404, 15) + player:teleportTo(destination) + position:sendMagicEffect(CONST_ME_TELEPORT) + destination:sendMagicEffect(CONST_ME_TELEPORT) + + local monster = Game.createMonster("pythius the rotten", Position(32571, 31406, 15)) + if monster then + monster:say("WHO IS SNEAKING AROUND BEHIND MY TREASURE?", TALKTYPE_MONSTER_YELL, false, player) + end + + else + + local spectators, spectator = Game.getSpectators(Position(32566, 31406, 15), false, false, 7, 7) + for i = 1, #spectators do + spectator = spectators[i] + if spectator:isMonster() then + spectator:remove() + end + end + + local destination = Position(32552, 31378, 15) + player:teleportTo(destination) + position:sendMagicEffect(CONST_ME_TELEPORT) + destination:sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +pythiusBossTeleport:type("stepin") +pythiusBossTeleport:aid(50125, 50126) +pythiusBossTeleport:register() diff --git a/data/scripts/movements/quests/the_hidden_city_of_beregar/pythius_teleport.lua b/data/scripts/movements/quests/the_hidden_city_of_beregar/pythius_teleport.lua new file mode 100644 index 00000000000..76824ec2cc5 --- /dev/null +++ b/data/scripts/movements/quests/the_hidden_city_of_beregar/pythius_teleport.lua @@ -0,0 +1,27 @@ +local pythiusTeleport = MoveEvent() + +function pythiusTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.HiddenCityOfBeregar.PythiusTheRotten) < os.time() then + position.y = position.y + 4 + player:teleportTo(position) + player:say("OFFER ME SOMETHING IF YOU WANT TO PASS!", + TALKTYPE_MONSTER_YELL, false, player, Position(32589, 31407, 15)) + position:sendMagicEffect(CONST_ME_FIREAREA) + return true + end + + local destination = Position(32601, 31397, 14) + player:teleportTo(destination) + position:sendMagicEffect(CONST_ME_TELEPORT) + destination:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +pythiusTeleport:type("stepin") +pythiusTeleport:uid(50127) +pythiusTeleport:register() diff --git a/data/scripts/movements/quests/the_hidden_city_of_beregar/tunnel.lua b/data/scripts/movements/quests/the_hidden_city_of_beregar/tunnel.lua new file mode 100644 index 00000000000..4f0f7fcf498 --- /dev/null +++ b/data/scripts/movements/quests/the_hidden_city_of_beregar/tunnel.lua @@ -0,0 +1,16 @@ +local tunnel = MoveEvent() + +function tunnel.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + player:teleportTo(Position(32616, 31514, 9)) + player:say("Use the ore wagon to pass this spot.", TALKTYPE_MONSTER_SAY) + return true +end + +tunnel:type("stepin") +tunnel:aid(50116) +tunnel:register() diff --git a/data/scripts/movements/quests/the_ice_islands/helheim.lua b/data/scripts/movements/quests/the_ice_islands/helheim.lua new file mode 100644 index 00000000000..a1c524dfbcd --- /dev/null +++ b/data/scripts/movements/quests/the_ice_islands/helheim.lua @@ -0,0 +1,33 @@ +local helheim = MoveEvent() + +function helheim.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.TheIceIslands.Questline) ~= 30 then + return true + end + + -- Questlog The Ice Islands Quest, The Secret of Helheim + player:setStorageValue(Storage.TheIceIslands.Mission07, 3) + player:setStorageValue(Storage.TheIceIslands.Questline, 31) + player:say("You discovered the necromantic altar and should report about it.", TALKTYPE_MONSTER_SAY) + position:sendMagicEffect(CONST_ME_MAGIC_RED) + + for x = -1, 1 do + for y = -1, 1 do + if y ~= 0 or x ~= 0 then + Position(position.x + x, position.y + y, position.z):sendMagicEffect(CONST_ME_MORTAREA) + end + end + end + + Position(position.x, position.y - 1, position.z):sendMagicEffect(CONST_ME_YALAHARIGHOST) + return true +end + +helheim:type("stepin") +helheim:uid(1061) +helheim:register() diff --git a/data/scripts/movements/quests/the_ice_islands/nibelor_dog_led.lua b/data/scripts/movements/quests/the_ice_islands/nibelor_dog_led.lua new file mode 100644 index 00000000000..5f91dc77f4a --- /dev/null +++ b/data/scripts/movements/quests/the_ice_islands/nibelor_dog_led.lua @@ -0,0 +1,48 @@ +local setting = { + -- Nibelor 5: Cure the Dogs needed or Barbarian Test Quest needed + [12025] = { + destination = Position(32407, 31067, 7), + storage = Storage.TheIceIslands.Mission06, + value = 8 + }, + [12026] = { + destination = Position(32365, 31059, 7), + storage = Storage.TheIceIslands.Mission06, + value = 8 + }, + [12027] = { + destination = Position(32329, 31045, 7), + storage = Storage.TheIceIslands.Mission03, + value = 3 + }, + [12028] = { + destination = Position(32301, 31080, 7), + storage = Storage.TheIceIslands.Mission03, + value = 3 + } +} + +local nibelorDogLed = MoveEvent() + +function nibelorDogLed.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local sled = setting[item.uid] + if not sled then + return true + end + + if player:getStorageValue(sled.storage) == sled.value and player:removeItem(2671, 1) then + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:teleportTo(sled.destination) + sled.destination:sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +nibelorDogLed:type("stepin") +nibelorDogLed:uid(1057, 1058, 1059, 1060) +nibelorDogLed:register() diff --git a/data/scripts/movements/quests/the_new_frontier/jail_exit.lua b/data/scripts/movements/quests/the_new_frontier/jail_exit.lua new file mode 100644 index 00000000000..3a0d57d126d --- /dev/null +++ b/data/scripts/movements/quests/the_new_frontier/jail_exit.lua @@ -0,0 +1,26 @@ +local destination = Position(33145, 31247, 6) + +local jailExit = MoveEvent() + +function jailExit.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.TheNewFrontier.Mission08) >= 1 then + player:teleportTo(destination) + position:sendMagicEffect(CONST_ME_TELEPORT) + destination:sendMagicEffect(CONST_ME_TELEPORT) + else + player:teleportTo(fromPosition) + position:sendMagicEffect(CONST_ME_TELEPORT) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You don't have access to this area.") + end + return true +end + +jailExit:type("stepin") +jailExit:aid(12138) +jailExit:register() diff --git a/data/scripts/movements/quests/the_new_frontier/minotaur_boss.lua b/data/scripts/movements/quests/the_new_frontier/minotaur_boss.lua new file mode 100644 index 00000000000..71a2a79f32e --- /dev/null +++ b/data/scripts/movements/quests/the_new_frontier/minotaur_boss.lua @@ -0,0 +1,42 @@ +local setting = { + arenaPosition = Position(33154, 31415, 7), + successPosition = Position(33145, 31419, 7) +} + +local function completeTest(cid) + local player = Player(cid) + if not player then + return true + end + + if player:getStorageValue(Storage.TheNewFrontier.Questline) == 19 then + player:teleportTo(setting.successPosition) + player:say("You have passed the test. Report to Curos.", TALKTYPE_MONSTER_SAY) + end +end + +local minotaurBoss = MoveEvent() + +function minotaurBoss.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.TheNewFrontier.Questline) ~= 18 then + player:teleportTo(fromPosition) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You don't have access to this area.") + return true + end + + addEvent(completeTest, 2 * 60 * 1000, player.uid) + player:setStorageValue(Storage.TheNewFrontier.Questline, 19) + player:teleportTo(setting.arenaPosition) + setting.arenaPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +minotaurBoss:type("stepin") +minotaurBoss:aid(12135) +minotaurBoss:register() diff --git a/data/scripts/movements/quests/the_new_frontier/trap.lua b/data/scripts/movements/quests/the_new_frontier/trap.lua new file mode 100644 index 00000000000..f2d37188bd6 --- /dev/null +++ b/data/scripts/movements/quests/the_new_frontier/trap.lua @@ -0,0 +1,25 @@ +local destination = Position(33170, 31253, 11) + +local trap = MoveEvent() + +function trap.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.TheNewFrontier.Questline) == 22 then + --Questlog, The New Frontier Quest "Mission 07: Messengers Of Peace" + player:setStorageValue(Storage.TheNewFrontier.Mission07, 2) + player:setStorageValue(Storage.TheNewFrontier.Questline, 23) + end + + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_POFF) + player:say("So far for the negotiating peace. Now you have other problems to handle.", TALKTYPE_MONSTER_SAY) + return true +end + +trap:type("stepin") +trap:aid(8007) +trap:register() diff --git a/data/scripts/movements/quests/the_new_frontier/wayout.lua b/data/scripts/movements/quests/the_new_frontier/wayout.lua new file mode 100644 index 00000000000..8ab35123d25 --- /dev/null +++ b/data/scripts/movements/quests/the_new_frontier/wayout.lua @@ -0,0 +1,21 @@ +local wayout = MoveEvent() + +function wayout.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.TheNewFrontier.Questline) == 1 then + --Questlog, The New Frontier Quest "Mission 01: New Land" + player:setStorageValue(Storage.TheNewFrontier.Mission01, 2) + player:setStorageValue(Storage.TheNewFrontier.Questline, 2) + player:say("You have found the passage through the mountains and can report about your success.", + TALKTYPE_MONSTER_SAY) + end + return true +end + +wayout:type("stepin") +wayout:aid(8000) +wayout:register() diff --git a/data/scripts/movements/quests/the_secret_library/boat.lua b/data/scripts/movements/quests/the_secret_library/boat.lua new file mode 100644 index 00000000000..d2220614071 --- /dev/null +++ b/data/scripts/movements/quests/the_secret_library/boat.lua @@ -0,0 +1,17 @@ +local boat = MoveEvent() + +function boat.onStepIn(creature, item, toPosition, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.TheSecretLibrary.HighDry) == 1 then + player:setStorageValue(Storage.TheSecretLibrary.HighDry, 2) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"There are still some loose planks and hawsers. You can\'t use the raft like this, it will sink for sure.") + end + return true +end + +boat:aid(26701) +boat:register() diff --git a/data/scripts/movements/quests/the_secret_library/golem_teleport.lua b/data/scripts/movements/quests/the_secret_library/golem_teleport.lua new file mode 100644 index 00000000000..c8f53be5453 --- /dev/null +++ b/data/scripts/movements/quests/the_secret_library/golem_teleport.lua @@ -0,0 +1,17 @@ +local golemTeleport = MoveEvent() + +function golemTeleport.onStepIn(creature, item, toPosition, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.TheSecretLibrary.Mota) == 10 then + player:setStorageValue(Storage.TheSecretLibrary.Mota, 11) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +golemTeleport:aid(26688) +golemTeleport:register() diff --git a/data/scripts/movements/quests/the_secret_library/pink_teleport.lua b/data/scripts/movements/quests/the_secret_library/pink_teleport.lua new file mode 100644 index 00000000000..772926ede5e --- /dev/null +++ b/data/scripts/movements/quests/the_secret_library/pink_teleport.lua @@ -0,0 +1,17 @@ +local pinkTeleport = MoveEvent() + +function pinkTeleport.onStepIn(creature, item, toPosition, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.TheSecretLibrary.Peacock) == 2 then + player:teleportTo(Position(32880, 32828, 11)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +pinkTeleport:aid(26698) +pinkTeleport:register() diff --git a/data/scripts/movements/quests/the_secret_library/teleport.lua b/data/scripts/movements/quests/the_secret_library/teleport.lua new file mode 100644 index 00000000000..e788c64e0a4 --- /dev/null +++ b/data/scripts/movements/quests/the_secret_library/teleport.lua @@ -0,0 +1,35 @@ +local destination = { + [64007] = Position(33345, 31347, 7), --Falcon + [64008] = Position(33357, 31308, 4), --Falcon + [64009] = Position(33382, 31292, 7), --Falcon + [64010] = Position(33327, 31351, 7), --Falcon + [64011] = Position(33201, 31765, 1), --Falcon + [64012] = Position(33327, 31351, 7), --Falcon + [64013] = Position(32958, 32324, 8), --Deep desert + [64014] = Position(33110, 32386, 7), --Deep desert +} + +local teleport = MoveEvent() + +function teleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local teleport = destination[item.actionid] + if teleport then + player:teleportTo(teleport) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + teleport:sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +teleport:type("stepin") + +for index, value in pairs(destination) do + teleport:aid(index) +end + +teleport:register() diff --git a/data/scripts/movements/quests/the_sharttered_isles/energy_barrier.lua b/data/scripts/movements/quests/the_sharttered_isles/energy_barrier.lua new file mode 100644 index 00000000000..c51eaf60b92 --- /dev/null +++ b/data/scripts/movements/quests/the_sharttered_isles/energy_barrier.lua @@ -0,0 +1,21 @@ +local energyBarrier = MoveEvent() + +function energyBarrier.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.TheShatteredIsles.TheCounterspell) ~= 4 then + position:sendMagicEffect(CONST_ME_ENERGYHIT) + position.x = position.x + 2 + player:teleportTo(position) + return true + end + + return true +end + +energyBarrier:type("stepin") +energyBarrier:aid(4000) +energyBarrier:register() diff --git a/data/scripts/movements/quests/the_sharttered_isles/teleport.lua b/data/scripts/movements/quests/the_sharttered_isles/teleport.lua new file mode 100644 index 00000000000..c3d8ef4828b --- /dev/null +++ b/data/scripts/movements/quests/the_sharttered_isles/teleport.lua @@ -0,0 +1,50 @@ +local sacrifices = { + [2787] = Tile(Position(31918, 32598, 10)), -- top left + [2789] = Tile(Position(31918, 32599, 10)), -- bottom left + [2796] = Tile(Position(31920, 32598, 10)), -- top right + [2792] = Tile(Position(31920, 32599, 10)) -- bottom right +} + +local teleport = MoveEvent() + +function teleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local completedSacrifice = true + for sacrificeItemId, sacrificeTile in pairs (sacrifices) do + if sacrificeTile:getThing(1).itemId ~= sacrificeItemId then + completedSacrifice = false + break + end + end + + local failDestination = Position(31919, 32596, 10) + if not sacrifices then + player:teleportTo(failDestination) + position:sendMagicEffect(CONST_ME_ENERGYHIT) + failDestination:sendMagicEffect(CONST_ME_ENERGYHIT) + return true + end + + for sacrificeItemId, sacrificeTile in pairs(sacrifices) do + if sacrificeTile:getThing(1).itemId == 1485 then + sacrificeTile:getThing(1):remove() + end + if sacrificeTile:getThing(0).itemId == 1485 then + sacrificeTile:getThing(0):remove() + end + end + + local successDestination = Position(31916, 32607, 10) + player:teleportTo(successDestination) + position:sendMagicEffect(CONST_ME_HITBYFIRE) + successDestination:sendMagicEffect(CONST_ME_HITBYFIRE) + return true +end + +teleport:type("stepin") +teleport:aid(12585) +teleport:register() diff --git a/data/scripts/movements/quests/the_spike_tasks/geomantic_charges.lua b/data/scripts/movements/quests/the_spike_tasks/geomantic_charges.lua new file mode 100644 index 00000000000..5aaf465a024 --- /dev/null +++ b/data/scripts/movements/quests/the_spike_tasks/geomantic_charges.lua @@ -0,0 +1,45 @@ +local condition = createConditionObject(CONDITION_OUTFIT) +setConditionParam(condition, CONDITION_PARAM_TICKS, 120000) +addOutfitCondition(condition, 0, 307, 0, 0, 0, 0) + +local geomanticCharges = MoveEvent() + +function geomanticCharges.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local tasksLoaded = {} + if not isInArray({-1, 8}, player:getStorageValue(SPIKE_MIDDLE_NEST_MAIN)) then + tasksLoaded["NEST"] = true + end + if player:getStorageValue(SPIKE_MIDDLE_CHARGE_MAIN) == 1 then + tasksLoaded["CHARGE"] = true + end + + if not tasksLoaded["NEST"] and not tasksLoaded["CHARGE"] then + player:teleportTo(fromPosition, true) + return true + end + + if tasksLoaded["NEST"] then + if player:getCondition(CONDITION_OUTFIT) or (player:getOutfit().lookType == 307) then + player:teleportTo(fromPosition, true) + return true + end + player:addCondition(condition) + player:getPosition():sendMagicEffect(11) + end + + if tasksLoaded["CHARGE"] then + player:getPosition():sendMagicEffect(12) + player:setStorageValue(SPIKE_MIDDLE_CHARGE_MAIN, 2) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have charged your body with geomantic energy and can report about it.") + end + return true +end + +geomanticCharges:type("stepin") +geomanticCharges:aid(56421) +geomanticCharges:register() diff --git a/data/scripts/movements/quests/the_spike_tasks/spike_teleport.lua b/data/scripts/movements/quests/the_spike_tasks/spike_teleport.lua new file mode 100644 index 00000000000..27dfc65d620 --- /dev/null +++ b/data/scripts/movements/quests/the_spike_tasks/spike_teleport.lua @@ -0,0 +1,58 @@ +local config = { + [4226] = {premium = true, destination = Position(32243, 32598, 8)}, + [4227] = {destination = Position(32624, 31855, 11)}, + [4228] = {level = 80, destination = Position(32228, 32596, 8)}, + [4229] = {destination = Position(32237, 32605, 8)}, + [4230] = {level = 80, destination = Position(32243, 32619, 9)}, + [4231] = {destination = Position(32237, 32605, 9)}, + [4232] = {level = 80, destination = Position(32240, 32620, 10)}, + [4233] = {destination = Position(32237, 32605, 10)}, + [4234] = {level = 80, destination = Position(32227, 32598, 11)}, + [4235] = {destination = Position(32237, 32605, 11)}, + [4236] = {level = 80, destination = Position(32238, 32622, 12)}, + [4237] = {destination = Position(32237, 32605, 12)}, + [4238] = {level = 80, destination = Position(32244, 32619, 13)}, + [4239] = {destination = Position(32237, 32605, 13)}, + [4240] = {level = 80, destination = Position(32244, 32588, 14)}, + [4241] = {destination = Position(32237, 32605, 14)}, + [4242] = {level = 80, destination = Position(32224, 32606, 15)}, + [4243] = {destination = Position(32237, 32605, 15)} +} + +local spikeTeleport = MoveEvent() + +function spikeTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local targetPortal = config[item.actionid] + if not targetPortal then + return true + end + + if targetPortal.premium then + if not player:isPremium() then + local toPosition = Position(32624, 31855, 11) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Only premium accounts can use this teleporter.") + player:teleportTo(toPosition) + position:sendMagicEffect(CONST_ME_TELEPORT) + toPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + end + + player:teleportTo(targetPortal.destination) + position:sendMagicEffect(CONST_ME_TELEPORT) + targetPortal.destination:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +spikeTeleport:type("stepin") + +for index, value in pairs(config) do + spikeTeleport:aid(index) +end + +spikeTeleport:register() diff --git a/data/scripts/movements/quests/their_master_voice/entrance.lua b/data/scripts/movements/quests/their_master_voice/entrance.lua new file mode 100644 index 00000000000..1c7104f68d0 --- /dev/null +++ b/data/scripts/movements/quests/their_master_voice/entrance.lua @@ -0,0 +1,9 @@ +local entrance = MoveEvent() + +function entrance.onStepIn(creature, item, toPosition, fromPosition) + return Entrance_onStepIn(creature, item, toPosition, fromPosition) +end + +entrance:type("stepin") +entrance:aid(47710) +entrance:register() diff --git a/data/scripts/movements/quests/threatened_dreams/swan_feathers.lua b/data/scripts/movements/quests/threatened_dreams/swan_feathers.lua new file mode 100644 index 00000000000..f66209fad36 --- /dev/null +++ b/data/scripts/movements/quests/threatened_dreams/swan_feathers.lua @@ -0,0 +1,43 @@ +local config = { -- Ref: https://www.tibiawiki.com.br/wiki/Threatened_Dreams_Quest#Troubled_Animals + storages = { -- Positions https://www.tibiawiki.com.br/images/3/30/WinterUp9.png + [50301] = "You found some more feathers on the grass near the wheat. Now you should have enough for an entire cloak.", -- Edron + [50302] = "You found some beautiful swan feathers in the dustbin.", -- Darasha in City + [50303] = "You found some beautiful swan feathers entangled in the cactus stings.", -- Darashia Nort of City + [50304] = "You found some beautiful swan feathers beneath the dragon skull.", -- Darashia Nort + Far of City + [50305] = "You found some more feaathers under the dead tree. Now you should have enough for an entire cloak." -- Darashia Nort + Far + Far of City + } +} + +local swanFeathers = MoveEvent() + +function swanFeathers.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if (player:getStorageValue(Storage.ThreatenedDreams.TroubledMission01) == 15) then + if (player:getStorageValue(Storage.ThreatenedDreams.TatteredSwanFeathers) <= 5) then + if (player:getStorageValue(item.actionid) == 1) then + player:sendCancelMessage("You have already completed this mission.") + else + player:addItem(28605, 1) + player:setStorageValue(item.actionid, 1) + player:setStorageValue(Storage.ThreatenedDreams.TatteredSwanFeathers, player:getStorageValue(Storage.ThreatenedDreams.TatteredSwanFeathers)+1) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, config.storages[item.actionid]) + if (player:getStorageValue(Storage.ThreatenedDreams.TatteredSwanFeathers) == 5) then + player:getStorageValue(Storage.ThreatenedDreams.TroubledMission01, 13) -- Finish the mission + end + end + else + player:sendCancelMessage("You have already completed this mission.") + end + else + player:sendCancelMessage("You are not on that mission.") + end + return true +end + +swanFeathers:aid(50301,50302,50303,50304,50305) +swanFeathers:register() \ No newline at end of file diff --git a/data/scripts/movements/quests/unnatural_selection/mission2_all_around_the_world.lua b/data/scripts/movements/quests/unnatural_selection/mission2_all_around_the_world.lua new file mode 100644 index 00000000000..0b0aa4d8df0 --- /dev/null +++ b/data/scripts/movements/quests/unnatural_selection/mission2_all_around_the_world.lua @@ -0,0 +1,75 @@ +local config = { + [1] = { + text = "You hold the skull up high. You can resist the urge to have it look through a telescope though.", + position = Position(33263, 31834, 1) + }, + [2] = { + text = "You hold up the skull and let it take a peek over the beautiful elven town through the dense leaves.", + position = Position(32711, 31668, 1) + }, + [3] = { + text = "Thanita gives you a really strange look as you hold up the skull, but oh well.", + position = Position(32537, 31772, 1) + }, + [4] = { + text = "That was a real easy one. And you are used to getting strange looks now, so whatever!", + position = Position(33216, 32450, 1) + }, + [5] = { + text = "Wow, it's hot up here. Luckily the skull can't get a sunburn any more, \z + but you can, so you better descend again!", + position = Position(33151, 32845, 2) + }, + [6] = { + text = "Considering that higher places around here aren't that easy to reach, \z + you think the view from here is tolerably good.", + position = Position(32589, 32801, 4) + }, + [7] = { + text = "Yep, that's a pretty high spot. \z + If Lazaran ever sees what the skull sees, he'd be pretty satisfied with that nice view.", + position = Position(32346, 32808, 2) + }, + [8] = { + text = "Well, there are higher spots around here, but none of them is as easily reachable as this one. \z + It just has to suffice.", + position = Position(32789, 31238, 3) + }, + [9] = { + text = "Nice! White in white as far as the eye can see. Time to leave before your fingers turn into icicles.", + position = Position(32236, 31096, 2) + }, + [10] = { + text = "That's definitely one of the highest spots in whole Tibia. \z + If that's not simply perfect you don't know what it is.", + position = Position(32344, 32265, 0) + }, + [11] = { + text = "What a beautiful view. Worthy of a Queen indeed! Time to head back to Lazaran and show him what you got.", + position = Position(32316, 31752, 0)} +} + +local mission2AllAroundTheWorld = MoveEvent() + +function mission2AllAroundTheWorld.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local targetValue = config[player:getStorageValue(Storage.UnnaturalSelection.Mission02)] + if not targetValue then + return true + end + + if player:getPosition() == targetValue.position and player:getItemCount(11076) >= 1 then + --Questlog, Unnatural Selection Quest "Mission 2: All Around the World" + player:setStorageValue(Storage.UnnaturalSelection.Mission02, player:getStorageValue(Storage.UnnaturalSelection.Mission02) + 1) + player:say(targetValue.text, TALKTYPE_MONSTER_SAY) + end + return true +end + +mission2AllAroundTheWorld:type("stepin") +mission2AllAroundTheWorld:aid(12332) +mission2AllAroundTheWorld:register() diff --git a/data/scripts/movements/quests/unnatural_selection/mission3_dance_dance_evolution.lua b/data/scripts/movements/quests/unnatural_selection/mission3_dance_dance_evolution.lua new file mode 100644 index 00000000000..56c3e82f1ee --- /dev/null +++ b/data/scripts/movements/quests/unnatural_selection/mission3_dance_dance_evolution.lua @@ -0,0 +1,67 @@ +local config = { + [1] = Position(32991, 31497, 1), + [2] = Position(32990, 31498, 1), + [3] = Position(32991, 31497, 1), + [4] = Position(32992, 31498, 1), + [5] = Position(32991, 31497, 1), + [6] = Position(32991, 31498, 1), + [7] = Position(32990, 31497, 1), + [8] = Position(32991, 31496, 1), + [9] = Position(32992, 31497, 1), + [10] = Position(32991, 31496, 1), + [11] = Position(32991, 31497, 1), + [12] = Position(32990, 31496, 1), + [13] = Position(32991, 31497, 1), + [14] = Position(32992, 31496, 1), + [15] = Position(32991, 31497, 1), + [16] = Position(32991, 31496, 1) +} + +-- Missing: CONST_ME_CARNIPHILA effects when dancing (pattern unknown) + +local mission3DanceDanceEvolution = MoveEvent() + +function mission3DanceDanceEvolution.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local dancePosition = config[player:getStorageValue(Storage.UnnaturalSelection.DanceStatus)] + if not dancePosition then + return true + end + + if position ~= dancePosition then + player:setStorageValue(Storage.UnnaturalSelection.DanceStatus, 1) + player:say("You did it wrong. now you have to start again.", TALKTYPE_MONSTER_SAY) + config[1]:sendMagicEffect(CONST_ME_SMALLPLANTS) + return true + end + + local danceStatus = player:getStorageValue(Storage.UnnaturalSelection.DanceStatus) + if danceStatus == 1 then + player:say("Dance for the mighty Krunus!", TALKTYPE_MONSTER_SAY) + end + + --Questlog, Unnatural Selection Quest "Mission 2: All Around the World" + player:setStorageValue(Storage.UnnaturalSelection.DanceStatus, danceStatus + 1) + + local nextpos = config[player:getStorageValue(Storage.UnnaturalSelection.DanceStatus)] + if nextpos then + nextpos:sendMagicEffect(CONST_ME_SMALLPLANTS) + end + + if danceStatus + 1 > #config then + --Questlog, Unnatural Selection Quest "Mission 3: Dance Dance Evolution" + player:setStorageValue(Storage.UnnaturalSelection.Mission03, 3) + player:setStorageValue(Storage.UnnaturalSelection.Questline, 7) + player:say("Krunus should be pleased.", TALKTYPE_MONSTER_SAY) + player:addAchievement("Talented Dancer") + end + return true +end + +mission3DanceDanceEvolution:type("stepin") +mission3DanceDanceEvolution:aid(12333) +mission3DanceDanceEvolution:register() diff --git a/data/scripts/movements/quests/waterfall/waterfall.lua b/data/scripts/movements/quests/waterfall/waterfall.lua new file mode 100644 index 00000000000..8d23a869907 --- /dev/null +++ b/data/scripts/movements/quests/waterfall/waterfall.lua @@ -0,0 +1,36 @@ +local setting = { + swimmingPosition = Position(32968, 32626, 5), + caveEntrancePosition = Position(32968, 32631, 8), + caveExitPosition = Position(32971, 32620, 8) +} + +local waterfall = MoveEvent() + +function waterfall.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + -- Jumping off the mountain edge into the water / onto water edge + if position.x == 32966 and position.y == 32626 and position.z == 5 then + player:teleportTo(setting.swimmingPosition) + setting.swimmingPosition:sendMagicEffect(CONST_ME_WATERSPLASH) + -- Splash effect when jumping down the waterfall + elseif position.x == 32968 and position.y == 32630 and position.z == 7 then + position:sendMagicEffect(CONST_ME_WATERSPLASH) + -- Teleport when entering the waterfall / cave + elseif position.x == 32968 and position.y == 32629 and position.z == 7 then + player:teleportTo(setting.caveEntrancePosition) + player:setDirection(DIRECTION_SOUTH) + -- Leaving the cave through teleport + elseif position.x == 32967 and position.y == 32630 and position.z == 8 then + player:teleportTo(setting.caveExitPosition) + player:setDirection(DIRECTION_EAST) + end + return true +end + +waterfall:type("stepin") +waterfall:aid(50022) +waterfall:register() diff --git a/data/scripts/movements/quests/what_a_foolish/destroy_pies.lua b/data/scripts/movements/quests/what_a_foolish/destroy_pies.lua new file mode 100644 index 00000000000..668c3516140 --- /dev/null +++ b/data/scripts/movements/quests/what_a_foolish/destroy_pies.lua @@ -0,0 +1,28 @@ +local destroyPies = MoveEvent() + +function destroyPies.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.WhatAFoolish.PieBoxTimer) > os.time() then + player:getStorageValue(Storage.WhatAFoolish.PieBoxTimer, 1) + end + + local pieBox = player:getItemById(7484, true) + if not pieBox then + return true + end + + pieBox:transform(2250) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:say("Stand still! These pies are confiscated!", + TALKTYPE_MONSTER_SAY, false, player, Position(33189, 31788, 7)) + player:say("Dirty pie smuggler!", TALKTYPE_MONSTER_SAY, false, player, Position(33193, 31788, 7)) + return true +end + +destroyPies:type("stepin") +destroyPies:aid(4201) +destroyPies:register() diff --git a/data/scripts/movements/quests/white_pearl/white_pearl.lua b/data/scripts/movements/quests/white_pearl/white_pearl.lua new file mode 100644 index 00000000000..289edff5f9e --- /dev/null +++ b/data/scripts/movements/quests/white_pearl/white_pearl.lua @@ -0,0 +1,46 @@ +local setting = { + [5630] = { + teleportPosition = Position(33145, 32863, 7), + effect = CONST_ME_MAGIC_GREEN, + potPosition = Position(33151, 32864, 7) + }, + [5631] = { + teleportPosition = Position(33147, 32864, 7), + effect = CONST_ME_MAGIC_GREEN + } +} + +local whitePearl = MoveEvent() + +function whitePearl.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local teleport = setting[item.actionid] + if not teleport then + return true + end + + if teleport.potPosition then + local potItem = Tile(Position(33145, 32862, 7)):getItemById(2562) + if potItem then + player:teleportTo(teleport.potPosition) + teleport.potPosition:sendMagicEffect(teleport.effect) + return true + end + end + + player:teleportTo(teleport.teleportPosition) + teleport.teleportPosition:sendMagicEffect(teleport.effect) + return true +end + +whitePearl:type("stepin") + +for index, value in pairs(setting) do + whitePearl:aid(index) +end + +whitePearl:register() diff --git a/data/scripts/movements/quests/wrath_of_the_emperor/boss_teleport.lua b/data/scripts/movements/quests/wrath_of_the_emperor/boss_teleport.lua new file mode 100644 index 00000000000..709b95247ce --- /dev/null +++ b/data/scripts/movements/quests/wrath_of_the_emperor/boss_teleport.lua @@ -0,0 +1,62 @@ +local teleports = { + [3189] = { + destination = Position(33041, 31086, 15), + storage = GlobalStorage.WrathOfTheEmperor.Bosses.Fury + }, + [3190] = { + destination = Position(33091, 31083, 15), + storage = GlobalStorage.WrathOfTheEmperor.Bosses.Wrath + }, + [3191] = { + destination = Position(33094, 31118, 15), + storage = GlobalStorage.WrathOfTheEmperor.Bosses.Scorn + }, + [3192] = { + destination = Position(33038, 31119, 15), + storage = GlobalStorage.WrathOfTheEmperor.Bosses.Spite + } +} + +local bossTeleport = MoveEvent() + +function bossTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local teleport = teleports[item.uid] + if not teleport then + return true + end + + if player:getStorageValue(Storage.WrathoftheEmperor.BossStatus) == 5 then + local destination = Position(33072, 31151, 15) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + if player:getStorageValue(Storage.WrathoftheEmperor.BossStatus) ~= item.uid - 3188 then + player:teleportTo(fromPosition, true) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Go to another Teleport or take mission with Zizzle.") + return true + end + + if Game.getStorageValue(teleport.storage) ~= 1 then + player:teleportTo(teleport.destination) + teleport.destination:sendMagicEffect(CONST_ME_TELEPORT) + else + player:teleportTo(teleport.destination) + end + return true +end + +bossTeleport:type("stepin") + +for index, value in pairs(teleports) do + bossTeleport:uid(index) +end + +bossTeleport:register() diff --git a/data/scripts/movements/quests/wrath_of_the_emperor/crate.lua b/data/scripts/movements/quests/wrath_of_the_emperor/crate.lua new file mode 100644 index 00000000000..bc61963b041 --- /dev/null +++ b/data/scripts/movements/quests/wrath_of_the_emperor/crate.lua @@ -0,0 +1,58 @@ +function catchPlayer(cid) + local player = Player(cid) + player:setStorageValue(Storage.WrathoftheEmperor.GuardcaughtYou, 1) + player:setStorageValue(Storage.WrathoftheEmperor.CrateStatus, 0) + player:teleportTo({x = 33361, y = 31206, z = 8}, false) + player:say("The guards have spotted you. You were forcibly dragged into a small cell. \z + It looks like you need to build another disguise.", TALKTYPE_MONSTER_SAY) + return true +end + +local crate = MoveEvent() + +function crate.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local playerId = player:getId() + if item.actionid == 8015 then + player:say("You hear guards moving behind doors in the distance. \z + If you have any sort of disguise with you, this is the moment to use it.", TALKTYPE_MONSTER_SAY) + elseif item.actionid == 8016 then + if Tile(Position(player:getPosition().y < 31094 and 33080 + or 33385, player:getPosition().y, 8)):getItemById(12213) then + catchPlayer(playerId) + end + elseif item.actionid == 8017 or item.actionid == 32362 or item.itemid == 11436 then + catchPlayer(playerId) + elseif item.actionid == 8018 then + if Game.getStorageValue(GlobalStorage.WrathOfTheEmperor.Light01) ~= 1 then + catchPlayer(playerId) + end + elseif item.actionid == 8019 then + if Game.getStorageValue(GlobalStorage.WrathOfTheEmperor.Light02) ~= 1 then + catchPlayer(playerId) + end + elseif item.actionid == 8020 then + if Game.getStorageValue(GlobalStorage.WrathOfTheEmperor.Light03) ~= 1 then + catchPlayer(playerId) + end + elseif item.actionid == 8021 then + player:say("Guards heavily patrol this area. \z + Try to stay hidden and do not draw any attention to yourself by trying to attack.", TALKTYPE_MONSTER_SAY) + elseif item.actionid == 8022 then + if player:getStorageValue(Storage.WrathoftheEmperor.CrateStatus) ~= 1 then + catchPlayer(playerId) + end + elseif item.actionid == 8023 then + player:setStorageValue(Storage.WrathoftheEmperor.CrateStatus, 0) + player:setOutfit({lookTypeEx = 12496}, 1) + end + return true +end + +crate:type("stepin") +crate:aid(8015, 8016, 8017, 8018, 8019, 8020, 8021, 8022, 8023, 32362) +crate:register() diff --git a/data/scripts/movements/quests/wrath_of_the_emperor/entrance_teleport.lua b/data/scripts/movements/quests/wrath_of_the_emperor/entrance_teleport.lua new file mode 100644 index 00000000000..92c0447a5e7 --- /dev/null +++ b/data/scripts/movements/quests/wrath_of_the_emperor/entrance_teleport.lua @@ -0,0 +1,37 @@ +local entranceTeleport = MoveEvent() + +function entranceTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.WrathoftheEmperor.Questline) < 30 then + local destinationz = Position(33138, 31249, 6) + player:teleportTo(destinationz) + return true + end + + if player:getStorageValue(Storage.WrathoftheEmperor.BossStatus) < 5 then + player:teleportTo(Position(33138, 31249, 6)) + return true + end + + if player:getStorageValue(Storage.WrathoftheEmperor.Questline) > 31 then + local firstDestination = Position(33360, 31397, 9) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(firstDestination) + firstDestination:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + local secondDestination = Position(33359, 31397, 9) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(secondDestination) + secondDestination:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +entranceTeleport:type("stepin") +entranceTeleport:uid(1109) +entranceTeleport:register() diff --git a/data/scripts/movements/quests/wrath_of_the_emperor/keeper.lua b/data/scripts/movements/quests/wrath_of_the_emperor/keeper.lua new file mode 100644 index 00000000000..3e34a2ab3f6 --- /dev/null +++ b/data/scripts/movements/quests/wrath_of_the_emperor/keeper.lua @@ -0,0 +1,28 @@ +local function revertItem(position, itemId, transformId) + local item = Tile(position):getItemById(itemId) + if item then + item:transform(transformId) + end +end + +local keeper = MoveEvent() + +function keeper.onStepIn(creature, item, position, fromPosition) + local monster = creature:isMonster() + if not monster then + return true + end + + if monster:getName():lower() ~= 'the keeper' then + return true + end + + doTargetCombatHealth(0, monster, COMBAT_PHYSICALDAMAGE, -6000, -8000, CONST_ME_BIGPLANTS) + item:transform(12335) + addEvent(revertItem, math.random(10, 30) * 1000, position, 12335, 12334) + return true +end + +keeper:type("stepin") +keeper:id(12334) +keeper:register() diff --git a/data/scripts/movements/quests/wrath_of_the_emperor/prison.lua b/data/scripts/movements/quests/wrath_of_the_emperor/prison.lua new file mode 100644 index 00000000000..b9eac355005 --- /dev/null +++ b/data/scripts/movements/quests/wrath_of_the_emperor/prison.lua @@ -0,0 +1,24 @@ +local prison = MoveEvent() + +function prison.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player or player:getStorageValue(Storage.WrathoftheEmperor.PrisonReleaseStatus) ~= 1 then + return true + end + + if player:getCondition(CONDITION_OUTFIT) then + player:removeCondition(CONDITION_OUTFIT) + end + + player:setStorageValue(Storage.WrathoftheEmperor.PrisonReleaseStatus, 0) + + local destination = Position(33363, 31188, 8) + player:teleportTo(destination) + position:sendMagicEffect(CONST_ME_TELEPORT) + destination:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +prison:type("stepin") +prison:uid(3175) +prison:register() diff --git a/data/scripts/movements/quests/wrath_of_the_emperor/realm_teleport.lua b/data/scripts/movements/quests/wrath_of_the_emperor/realm_teleport.lua new file mode 100644 index 00000000000..d083af2dc4e --- /dev/null +++ b/data/scripts/movements/quests/wrath_of_the_emperor/realm_teleport.lua @@ -0,0 +1,24 @@ +local realmTeleport = MoveEvent() + +function realmTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + --TODO check why has this hasBlessing here + if player:getStorageValue(Storage.WrathoftheEmperor.Mission10) < 2 or not player:hasBlessing(1) then + player:teleportTo(fromPosition) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + local realm = Position(33028, 31086, 13) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(realm) + realm:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +realmTeleport:type("stepin") +realmTeleport:aid(8028) +realmTeleport:register() diff --git a/data/scripts/movements/quests/wrath_of_the_emperor/sleeping_dragon_teleport.lua b/data/scripts/movements/quests/wrath_of_the_emperor/sleeping_dragon_teleport.lua new file mode 100644 index 00000000000..ed4251b9fbe --- /dev/null +++ b/data/scripts/movements/quests/wrath_of_the_emperor/sleeping_dragon_teleport.lua @@ -0,0 +1,24 @@ +local sleepingDragonTeleport = MoveEvent() + +function sleepingDragonTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.WrathoftheEmperor.Mission09) == -1 then + player:teleportTo(fromPosition, true) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + local sleepingDragon = Position(33240, 31247, 10) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(sleepingDragon) + sleepingDragon:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +sleepingDragonTeleport:type("stepin") +sleepingDragonTeleport:uid(9263) +sleepingDragonTeleport:register() diff --git a/data/scripts/movements/quests/wrath_of_the_emperor/teleport_rebel_to_zlak.lua b/data/scripts/movements/quests/wrath_of_the_emperor/teleport_rebel_to_zlak.lua new file mode 100644 index 00000000000..578f7bb803c --- /dev/null +++ b/data/scripts/movements/quests/wrath_of_the_emperor/teleport_rebel_to_zlak.lua @@ -0,0 +1,43 @@ +local setting = { + [12382] = { + storage = Storage.WrathoftheEmperor.Questline, + toPosition = {Position(33078, 31219, 8), Position(33216, 31069, 9)} + }, + [12383] = { + storage = Storage.WrathoftheEmperor.Questline, + toPosition = {Position(33216, 31069, 9), Position(33078, 31219, 8)} + } +} + +local teleportRebelToZlak = MoveEvent() + +function teleportRebelToZlak.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local targetTile = setting[item.actionid] + if not targetTile then + return true + end + + local hasStorageValue = player:getStorageValue(targetTile.storage) >= 23 + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(targetTile.toPosition[hasStorageValue and 1 or 2]) + player:teleportTo(targetTile.toPosition[1]) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + + if not hasStorageValue then + player:say("This portal is not activated", TALKTYPE_MONSTER_SAY) + end + return true +end + +teleportRebelToZlak:type("stepin") + +for index, value in pairs(setting) do + teleportRebelToZlak:aid(index) +end + +teleportRebelToZlak:register() diff --git a/data/scripts/movements/quests/wrath_of_the_emperor/teleport_to_zalamon.lua b/data/scripts/movements/quests/wrath_of_the_emperor/teleport_to_zalamon.lua new file mode 100644 index 00000000000..73684460a43 --- /dev/null +++ b/data/scripts/movements/quests/wrath_of_the_emperor/teleport_to_zalamon.lua @@ -0,0 +1,32 @@ +local teleportToZalamon = MoveEvent() + +function teleportToZalamon.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.WrathoftheEmperor.Questline) < 31 then + local destinations = Position(33359, 31397, 9) + player:teleportTo(destinations) + return true + end + + if player:getStorageValue(Storage.WrathoftheEmperor.Questline) > 32 then + local destination = Position(33078, 31219, 8) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + local destination = Position(33359, 31397, 9) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(destination) + destination:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +teleportToZalamon:type("stepin") +teleportToZalamon:uid(3197) +teleportToZalamon:register() diff --git a/data/scripts/movements/quests/wrath_of_the_emperor/teleports_muggy_plains.lua b/data/scripts/movements/quests/wrath_of_the_emperor/teleports_muggy_plains.lua new file mode 100644 index 00000000000..0cbccb39df0 --- /dev/null +++ b/data/scripts/movements/quests/wrath_of_the_emperor/teleports_muggy_plains.lua @@ -0,0 +1,37 @@ +local setting = { + [12380] = {storageKey = Storage.WrathoftheEmperor.Questline, toPosition = {Position(33138, 31248, 6), Position(33211, 31065, 9)}}, + [12381] = {storageKey = Storage.WrathoftheEmperor.Questline, toPosition = {Position(33211, 31065, 9), Position(33138, 31248, 6)}} +} + +local teleportsMuggyPlains = MoveEvent() + +function teleportsMuggyPlains.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local targetTile = config[item.actionid] + if not targetTile then + return true + end + + local hasStorageValue = player:getStorageValue(targetTile.storageKey) >= 5 + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:teleportTo(targetTile.toPosition[hasStorageValue and 1 or 2]) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + + if not hasStorageValue then + player:say('This portal is not activated, you need done some missions.', TALKTYPE_MONSTER_SAY) + end + + return true +end + +teleportsMuggyPlains:type("stepin") + +for index, value in pairs(setting) do + teleportsMuggyPlains:aid(index) +end + +teleportsMuggyPlains:register() diff --git a/data/scripts/movements/rookgaard/level_bridge.lua b/data/scripts/movements/rookgaard/level_bridge.lua new file mode 100644 index 00000000000..af5adbc49ac --- /dev/null +++ b/data/scripts/movements/rookgaard/level_bridge.lua @@ -0,0 +1,23 @@ +local failPosition = Position(32092, 32177, 6) + +local levelBridge = MoveEvent() + +function levelBridge.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getLevel() >= 2 then + return true + end + + player:teleportTo(failPosition) + failPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You need to be at least Level 2 in order to pass.') + return true +end + +levelBridge:type("stepin") +levelBridge:aid(50998) +levelBridge:register() diff --git a/data/scripts/movements/rookgaard/premium_bridge.lua b/data/scripts/movements/rookgaard/premium_bridge.lua new file mode 100644 index 00000000000..f6d57817aa8 --- /dev/null +++ b/data/scripts/movements/rookgaard/premium_bridge.lua @@ -0,0 +1,22 @@ +local failPosition = Position(32066, 32192, 7) + +local premiumBridge = MoveEvent() + +function premiumBridge.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:isPremium() then + return true + end + + failPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:teleportTo(failPosition) + return true +end + +premiumBridge:type("stepin") +premiumBridge:aid(50241) +premiumBridge:register() diff --git a/data/scripts/movements/rookgaard/rook_village.lua b/data/scripts/movements/rookgaard/rook_village.lua new file mode 100644 index 00000000000..5ddd8118ee6 --- /dev/null +++ b/data/scripts/movements/rookgaard/rook_village.lua @@ -0,0 +1,18 @@ +local rookVillage = MoveEvent() + +function rookVillage.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + player:teleportTo(Position(player:getPosition().x, player:getPosition().y-1, player:getPosition().z)) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You don't have any business there anymore.") + + return true + +end + +rookVillage:type("stepin") +rookVillage:id(8716) +rookVillage:register() diff --git a/data/scripts/movements/teleport/adventurers_guild.lua b/data/scripts/movements/teleport/adventurers_guild.lua new file mode 100644 index 00000000000..bc58bda7576 --- /dev/null +++ b/data/scripts/movements/teleport/adventurers_guild.lua @@ -0,0 +1,21 @@ +local adventurersGuild = MoveEvent() + +function adventurersGuild.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local townId = player:getStorageValue(Storage.AdventurersGuild.Stone) + local destination = townId ~= -1 and Town(townId):getTemplePosition() or player:getTown():getTemplePosition() + + player:setStorageValue(Storage.AdventurersGuild.Stone, -1) + player:teleportTo(destination) + position:sendMagicEffect(CONST_ME_TELEPORT) + destination:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +adventurersGuild:type("stepin") +adventurersGuild:aid(4255) +adventurersGuild:register() diff --git a/data/scripts/movements/teleport/citizen.lua b/data/scripts/movements/teleport/citizen.lua new file mode 100644 index 00000000000..c8a5a846449 --- /dev/null +++ b/data/scripts/movements/teleport/citizen.lua @@ -0,0 +1,59 @@ +local config = { + [9059] = TOWNS_LIST.AB_DENDRIEL, + [9056] = TOWNS_LIST.CARLIN, + [9060] = TOWNS_LIST.KAZORDOON, + [9057] = TOWNS_LIST.THAIS, + [9058] = TOWNS_LIST.VENORE, + [9061] = TOWNS_LIST.DARASHIA, + [9062] = TOWNS_LIST.ANKRAHMUN, + [9063] = TOWNS_LIST.EDRON, + [9068] = TOWNS_LIST.FARMINE, + [9064] = TOWNS_LIST.LIBERTY_BAY, + [9065] = TOWNS_LIST.PORT_HOPE, + [9066] = TOWNS_LIST.SVARGROND, + [9067] = TOWNS_LIST.YALAHAR, + [9240] = TOWNS_LIST.GRAY_BEACH, + [9510] = TOWNS_LIST.RATHLETON, + [9500] = TOWNS_LIST.ROSHAMUUL, + [9515] = TOWNS_LIST.ISSAVI, +} + +local citizen = MoveEvent() + +function citizen.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local townId = config[item.uid] + if not townId then + return true + end + + local town = Town(townId) + if not town then + return true + end + + if town:getId() == TOWNS_LIST.SVARGROND and player:getStorageValue(Storage.BarbarianTest.Questline) < 8 then + player:sendTextMessage(MESSAGE_GAME_HIGHLIGHT, 'You first need to absolve the Barbarian Test Quest to become citizen!') + player:teleportTo(town:getTemplePosition()) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + player:setTown(town) + player:teleportTo(town:getTemplePosition()) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You are now a citizen of ' .. town:getName() .. '.') + return true +end + +citizen:type("stepin") + +for index, value in pairs(config) do + citizen:uid(index) +end + +citizen:register() diff --git a/data/scripts/movements/teleport/citizen_svargrond.lua b/data/scripts/movements/teleport/citizen_svargrond.lua new file mode 100644 index 00000000000..1e7b146fab2 --- /dev/null +++ b/data/scripts/movements/teleport/citizen_svargrond.lua @@ -0,0 +1,23 @@ +local citizenSvargrond = MoveEvent() + +function citizenSvargrond.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.BarbarianTest.Mission03) == 3 then + player:teleportTo(Position(32212, 31131, 5)) + else + player:teleportTo(Position(32210, 31134, 7)) + player:say("You have to be a honorary barbarian to access the roof. Talk to the Jarl about it.", TALKTYPE_MONSTER_SAY) + end + + player:setDirection(DIRECTION_EAST) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +citizenSvargrond:type("stepin") +citizenSvargrond:aid(30032) +citizenSvargrond:register() diff --git a/data/scripts/movements/teleport/deeper_banuta_shortcut_teleport.lua b/data/scripts/movements/teleport/deeper_banuta_shortcut_teleport.lua new file mode 100644 index 00000000000..304e4ccf6a1 --- /dev/null +++ b/data/scripts/movements/teleport/deeper_banuta_shortcut_teleport.lua @@ -0,0 +1,33 @@ +local setting = { + [50084] = Position(32857, 32667, 9), + [50085] = Position(32892, 32632, 11), + [50086] = Position(32886, 32632, 11) +} + +local deeperBanutaShortcutTeleport = MoveEvent() + +function deeperBanutaShortcutTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local targetPosition = setting[item.actionid] + if not targetPosition then + return true + end + + if player:getStorageValue(Storage.BanutaSecretTunnel.DeeperBanutaShortcut) < 100 then + player:teleportTo(targetPosition) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +deeperBanutaShortcutTeleport:type("stepin") + +for index, value in pairs(setting) do + deeperBanutaShortcutTeleport:aid(index) +end + +deeperBanutaShortcutTeleport:register() diff --git a/data/scripts/movements/teleport/falcon_castle.lua b/data/scripts/movements/teleport/falcon_castle.lua new file mode 100644 index 00000000000..1987d064e56 --- /dev/null +++ b/data/scripts/movements/teleport/falcon_castle.lua @@ -0,0 +1,39 @@ +local config = { + [3255] = {position = Position(33349, 31346, 8)}, + [57602] = {position = Position(33329, 31332, 9)}, + [57604] = {position = Position(33363, 31342, 9)}, + [57699] = {position = Position(33308, 31325, 8)} +} + +local falconCastle = MoveEvent() + +function falconCastle.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return false + end + + for index, value in pairs(config) do + if item.actionid == index then + if(item.actionid == 57604)then + if(player:getStorageValue(Storage.TheSecretLibrary.TheOrderOfTheFalcon.OberonTimer) > os.time())then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have faced this boss in the last 20 hours.") + player:teleportTo(fromPosition, true) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return false + end + end + doSendMagicEffect(player:getPosition(), CONST_ME_TELEPORT) + player:teleportTo(value.position) + doSendMagicEffect(value.position, CONST_ME_TELEPORT) + end + end +end + +falconCastle:type("stepin") + +for index, value in pairs(config) do + falconCastle:aid(index) +end + +falconCastle:register() diff --git a/data/scripts/movements/teleport/fibula.lua b/data/scripts/movements/teleport/fibula.lua new file mode 100644 index 00000000000..0f20ee1600b --- /dev/null +++ b/data/scripts/movements/teleport/fibula.lua @@ -0,0 +1,32 @@ +local setting = { + [50390] = {effectTeleport = CONST_ME_GREEN_RINGS, newPosition = Position(33651, 31942, 7)}, + [50391] = {effectTeleport = CONST_ME_STONES, newPosition = Position(32172, 32439, 8)}, +} + +local fibula = MoveEvent() + +function fibula.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local teleport = setting[item.actionid] + if teleport then + local newPosition = teleport.newPosition + player:teleportTo(newPosition) + + fromPosition:sendMagicEffect(teleport.effectTeleport) + newPosition:sendMagicEffect(teleport.effectTeleport) + player:say("Slrrp!", TALKTYPE_MONSTER_SAY) + end + return true +end + +fibula:type("stepin") + +for index, value in pairs(setting) do + fibula:aid(index) +end + +fibula:register() diff --git a/data/scripts/movements/teleport/gray_beach_vortex.lua b/data/scripts/movements/teleport/gray_beach_vortex.lua new file mode 100644 index 00000000000..cce41013360 --- /dev/null +++ b/data/scripts/movements/teleport/gray_beach_vortex.lua @@ -0,0 +1,31 @@ +local config = { + [9238] = Position(33456, 31346, 8), + [9239] = Position(33199, 31978, 8) +} + +local grayBeachVortex = MoveEvent() + +function grayBeachVortex.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local targetPosition = config[item.uid] + if not targetPosition then + return true + end + + player:teleportTo(targetPosition) + targetPosition:sendMagicEffect(CONST_ME_WATERSPLASH) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You dive into the vortex to swim below the rocks to the other side of the cave.") + return true +end + +grayBeachVortex:type("stepin") + +for index, value in pairs(config) do + grayBeachVortex:uid(index) +end + +grayBeachVortex:register() diff --git a/data/scripts/movements/teleport/item_teleports.lua b/data/scripts/movements/teleport/item_teleports.lua new file mode 100644 index 00000000000..36a53bc6b46 --- /dev/null +++ b/data/scripts/movements/teleport/item_teleports.lua @@ -0,0 +1,16 @@ +local itemTeleports = MoveEvent() + +function itemTeleports.onAddItem(moveitem, tileitem, position) + local setting = ItemTeleports[tileitem.actionid] + if not setting then + return true + end + + moveitem:moveTo(setting.destination) + setting.destination:sendMagicEffect(setting.effect) + return true +end + +itemTeleports:type("additem") +itemTeleports:id(1387, 8058) +itemTeleports:register() diff --git a/data/scripts/movements/teleport/lower_roshamuul.lua b/data/scripts/movements/teleport/lower_roshamuul.lua new file mode 100644 index 00000000000..17ea56d6921 --- /dev/null +++ b/data/scripts/movements/teleport/lower_roshamuul.lua @@ -0,0 +1,28 @@ +local roshamuulCaves = { + Position(33560, 32523, 8), + Position(33554, 32543, 8), + Position(33573, 32545, 8), + Position(33543, 32560, 8), + Position(33579, 32565, 8), + Position(33527, 32597, 8) +} + +local lowerRoshamuul = MoveEvent() + +function lowerRoshamuul.onStepIn(creature, item, position, fromPosition) + if not creature:isPlayer() then + return false + end + + if item:getId() == 22456 then + creature:teleportTo(Position(33551, 32556, 7)) + else + creature:teleportTo(roshamuulCaves[math.random(#roshamuulCaves)]) + end + return true +end + +lowerRoshamuul:type("stepin") +lowerRoshamuul:id(22456) +lowerRoshamuul:aid(1500) +lowerRoshamuul:register() diff --git a/data/scripts/movements/teleport/magician_quarter.lua b/data/scripts/movements/teleport/magician_quarter.lua new file mode 100644 index 00000000000..3a352770b9f --- /dev/null +++ b/data/scripts/movements/teleport/magician_quarter.lua @@ -0,0 +1,37 @@ +local config = { + [31077] = {requireSoil = false, toPosition = Position(32908, 31081, 7), effect = CONST_ME_ENERGYHIT}, + [31080] = {requireSoil = true, pushbackPosition = Position(32908, 31081, 7), toPosition = Position(32908, 31076, 7), effect = CONST_ME_ENERGYHIT}, + [31081] = {requireSoil = true, pushbackPosition = Position(32906, 31080, 7), toPosition = Position(32908, 31085, 7), effect = CONST_ME_HITBYFIRE}, + [31084] = {requireSoil = false, toPosition = Position(32906, 31080, 7), effect = CONST_ME_HITBYFIRE} +} + +local magicianQuarter = MoveEvent() + +function magicianQuarter.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local targetWall = config[fromPosition.y] + if not targetWall then + return true + end + + if targetWall.requireSoil then + if not (player:removeItem(8298, 1) or player:removeItem(8299, 1) or player:removeItem(8302, 1) or player:removeItem(8303, 1)) then + player:teleportTo(targetWall.pushbackPosition) + player:say('You may not enter without a sacrifice of elemental soil.', TALKTYPE_MONSTER_SAY) + targetWall.pushbackPosition:sendMagicEffect(targetWall.effect) + return true + end + end + + player:teleportTo(targetWall.toPosition) + targetWall.toPosition:sendMagicEffect(targetWall.effect) + return true +end + +magicianQuarter:type("stepin") +magicianQuarter:aid(7813) +magicianQuarter:register() diff --git a/data/scripts/movements/teleport/port_hope_deathling.lua b/data/scripts/movements/teleport/port_hope_deathling.lua new file mode 100644 index 00000000000..d32448fc285 --- /dev/null +++ b/data/scripts/movements/teleport/port_hope_deathling.lua @@ -0,0 +1,29 @@ +local destination = { + [64017] = Position(32881, 32474, 9), --Entrance + [64018] = Position(32870, 32510, 7) --Exit +} + +local portHopeDeathling = MoveEvent() + +function portHopeDeathling.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local teleport = destination[item.actionid] + if teleport then + player:teleportTo(teleport) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + teleport:sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +portHopeDeathling:type("stepin") + +for index, value in pairs(destination) do + portHopeDeathling:aid(index) +end + +portHopeDeathling:register() diff --git a/data/scripts/movements/teleport/roshamuul_carpet.lua b/data/scripts/movements/teleport/roshamuul_carpet.lua new file mode 100644 index 00000000000..f13cff3a0fe --- /dev/null +++ b/data/scripts/movements/teleport/roshamuul_carpet.lua @@ -0,0 +1,24 @@ +local roshamuulCarpet = MoveEvent() + +function roshamuulCarpet.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local town = Town(TOWNS_LIST.THAIS) + if not town then + return true + end + + local destination = town:getTemplePosition() + player:teleportTo(destination) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The flying carpet brought you back to Thais.") + position:sendMagicEffect(CONST_ME_POFF) + destination:sendMagicEffect(CONST_ME_POFF) + return true +end + +roshamuulCarpet:type("stepin") +roshamuulCarpet:aid(4256) +roshamuulCarpet:register() diff --git a/data/scripts/movements/teleport/schrodingers_island_teleport_lvl_999.lua b/data/scripts/movements/teleport/schrodingers_island_teleport_lvl_999.lua new file mode 100644 index 00000000000..d7b1da920ee --- /dev/null +++ b/data/scripts/movements/teleport/schrodingers_island_teleport_lvl_999.lua @@ -0,0 +1,27 @@ +local schrodingersIslandTeleportLvl999 = MoveEvent() + +function schrodingersIslandTeleportLvl999.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return false + end + + if player:getLevel() < 999 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need level 999 to enter here.") + creature:teleportTo(fromPosition) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Congratulations!") + + local accessPosition = Position(32832, 32435, 7) + player:teleportTo(accessPosition) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + accessPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +schrodingersIslandTeleportLvl999:type("stepin") +schrodingersIslandTeleportLvl999:aid(15998) +schrodingersIslandTeleportLvl999:register() diff --git a/data/scripts/movements/teleport/schrodingers_island_teleport_lvl_999_exit.lua b/data/scripts/movements/teleport/schrodingers_island_teleport_lvl_999_exit.lua new file mode 100644 index 00000000000..37669e59b3f --- /dev/null +++ b/data/scripts/movements/teleport/schrodingers_island_teleport_lvl_999_exit.lua @@ -0,0 +1,20 @@ +local schrodingersIslandTeleportLvl999Exit = MoveEvent() + +function schrodingersIslandTeleportLvl999Exit.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return false + end + + if player:getLevel() >= 999 then + local exitPosition = Position(32883, 32527, 11) + player:teleportTo(exitPosition) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + exitPosition:sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +schrodingersIslandTeleportLvl999Exit:type("stepin") +schrodingersIslandTeleportLvl999Exit:aid(15999) +schrodingersIslandTeleportLvl999Exit:register() diff --git a/data/scripts/movements/teleport/shrine_entrance.lua b/data/scripts/movements/teleport/shrine_entrance.lua new file mode 100644 index 00000000000..a49cdb4493a --- /dev/null +++ b/data/scripts/movements/teleport/shrine_entrance.lua @@ -0,0 +1,97 @@ +local setting = { + --Carlin + [9069] = {position = Position(32192, 31419, 2), storage = 10017}, --ice + [9070] = {position = Position(32972, 32227, 7), storage = 10017}, --earth + [9071] = {position = Position(32911, 32336, 15), storage = 10017}, --fire + [9072] = {position = Position(33059, 32716, 5), storage = 10017}, --electric + --Thais + [9073] = {position = Position(32192, 31419, 2), storage = 10018}, --ice + [9074] = {position = Position(32972, 32227, 7), storage = 10018}, --earth + [9075] = {position = Position(32911, 32336, 15), storage = 10018}, --fire + [9076] = {position = Position(33059, 32716, 5), storage = 10018}, --electric + --Venore + [9077] = {position = Position(32192, 31419, 2), storage = 10019}, --ice + [9078] = {position = Position(32972, 32227, 7), storage = 10019}, --earth + [9079] = {position = Position(32911, 32336, 15), storage = 10019}, --fire + [9080] = {position = Position(33059, 32716, 5), storage = 10019}, --electric + --Ab"Dendriel + [9081] = {position = Position(32192, 31419, 2), storage = 10020}, --ice + [9082] = {position = Position(32972, 32227, 7), storage = 10020}, --earth + [9083] = {position = Position(32911, 32336, 15), storage = 10020}, --fire + [9084] = {position = Position(33059, 32716, 5), storage = 10020}, --electric + --Kazodron + [9085] = {position = Position(32192, 31419, 2), storage = 10021 }, --ice + [9086] = {position = Position(32972, 32227, 7), storage = 10021}, --earth + [9087] = {position = Position(32911, 32336, 15), storage = 10021}, --fire + [9088] = {position = Position(33059, 32716, 5), storage = 10021}, --electric + --Darashia + [9089] = {position = Position(32192, 31419, 2), storage = 10022}, --ice + [9090] = {position = Position(32972, 32227, 7), storage = 10022}, --earth + [9091] = {position = Position(32911, 32336, 15), storage = 10022}, --fire + [9092] = {position = Position(33059, 32716, 5), storage = 10022}, --electric + --Ankrahmun + [9093] = {position = Position(32192, 31419, 2), storage = 10023}, --ice + [9094] = {position = Position(32972, 32227, 7), storage = 10023}, --earth + [9095] = {position = Position(32911, 32336, 15), storage = 10023}, --fire + [9096] = {position = Position(33059, 32716, 5), storage = 10023}, --electric + --Edron + [9097] = {position = Position(32192, 31419, 2), storage = 10024}, --ice + [9098] = {position = Position(32972, 32227, 7), storage = 10024}, --earth + [9099] = {position = Position(32911, 32336, 15), storage = 10024}, --fire + [9100] = {position = Position(33059, 32716, 5), storage = 10024}, --electric + --Liberty Bay + [9101] = {position = Position(32192, 31419, 2), storage = 10025}, --ice + [9102] = {position = Position(32972, 32227, 7), storage = 10025}, --earth + [9103] = {position = Position(32911, 32336, 15), storage = 10025}, --fire + [9104] = {position = Position(33059, 32716, 5), storage = 10025}, --electric + --Port Hope + [9105] = {position = Position(32192, 31419, 2), storage = 10026}, --ice + [9106] = {position = Position(32972, 32227, 7), storage = 10026}, --earth + [9107] = {position = Position(32911, 32336, 15), storage = 10026}, --fire + [9108] = {position = Position(33059, 32716, 5), storage = 10026}, --electric + --Svargrond + [9109] = {position = Position(32192, 31419, 2), storage = 10027}, --ice + [9110] = {position = Position(32972, 32227, 7), storage = 10027}, --earth + [9111] = {position = Position(32911, 32336, 15), storage = 10027}, --fire + [9112] = {position = Position(33059, 32716, 5), storage = 10027}, --electric + --Yalahar + [9113] = {position = Position(32192, 31419, 2), storage = 10028}, --ice + [9114] = {position = Position(32972, 32227, 7), storage = 10028}, --earth + [9115] = {position = Position(32911, 32336, 15), storage = 10028}, --fire + [9116] = {position = Position(33059, 32716, 5), storage = 10028}, --electric + --Oramond + [9117] = {position = Position(32192, 31419, 2), storage = 10029}, --ice + [9118] = {position = Position(32972, 32227, 7), storage = 10029}, --earth + [9119] = {position = Position(32911, 32336, 15), storage = 10029}, --fire + [9120] = {position = Position(33059, 32716, 5), storage = 10029} --electric +} + +local shrineEntrance = MoveEvent() + +function shrineEntrance.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local portal = setting[item.uid] + if not portal or player:getLevel() < 30 then + player:teleportTo(fromPosition, true) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:say("Only players of level 30 or higher may enter this portal.", TALKTYPE_MONSTER_SAY) + return true + end + + player:teleportTo(portal.position) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:setStorageValue(portal.storage, 1) + return true +end + +shrineEntrance:type("stepin") + +for index, value in pairs(setting) do + shrineEntrance:uid(index) +end + +shrineEntrance:register() diff --git a/data/scripts/movements/teleport/shrine_exit.lua b/data/scripts/movements/teleport/shrine_exit.lua new file mode 100644 index 00000000000..6a251466272 --- /dev/null +++ b/data/scripts/movements/teleport/shrine_exit.lua @@ -0,0 +1,42 @@ +local setting = { + {storage = 10017, destination = Position(32360, 31781, 9)}, + {storage = 10018, destination = Position(32369, 32242, 6)}, + {storage = 10019, destination = Position(32958, 32077, 5)}, + {storage = 10020, destination = Position(32681, 31686, 2)}, + {storage = 10021, destination = Position(32646, 31925, 11)}, + {storage = 10022, destination = Position(33230, 32392, 5)}, + {storage = 10023, destination = Position(33130, 32815, 4)}, + {storage = 10024, destination = Position(33266, 31835, 9)}, + {storage = 10025, destination = Position(32337, 32837, 8)}, + {storage = 10026, destination = Position(32628, 32743, 4)}, + {storage = 10027, destination = Position(32213, 31132, 8)}, + {storage = 10028, destination = Position(32786, 31245, 5)}, + {storage = 10029, destination = Position(33594, 31899, 4)} +} + +local shrineExit = MoveEvent() + +function shrineExit.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return + end + + for i = 1, #setting do + local teleport = setting[i] + if player:getStorageValue(teleport.storage) >= 1 then + player:teleportTo(teleport.destination) + teleport.destination:sendMagicEffect(CONST_ME_TELEPORT) + player:setStorageValue(teleport.storage, 0) + return true + end + end + + player:teleportTo(player:getTown():getTemplePosition()) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +shrineExit:type("stepin") +shrineExit:aid(9117) +shrineExit:register() diff --git a/data/scripts/movements/teleport/sorcerer_guild_thais.lua b/data/scripts/movements/teleport/sorcerer_guild_thais.lua new file mode 100644 index 00000000000..db9e96ec96b --- /dev/null +++ b/data/scripts/movements/teleport/sorcerer_guild_thais.lua @@ -0,0 +1,20 @@ +local sorcererGuildThais = MoveEvent() + +function sorcererGuildThais.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:isSorcerer() then + return true + end + + player:teleportTo(Position(32308, 32267, 7)) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + return true +end + +sorcererGuildThais:type("stepin") +sorcererGuildThais:aid(5555) +sorcererGuildThais:register() diff --git a/data/scripts/movements/teleport/teleport_ab_dendriel.lua b/data/scripts/movements/teleport/teleport_ab_dendriel.lua new file mode 100644 index 00000000000..1c5a8e04e0d --- /dev/null +++ b/data/scripts/movements/teleport/teleport_ab_dendriel.lua @@ -0,0 +1,34 @@ +local setting = { + [9700] = Position(32667, 31681, 6), + [9701] = Position(32726, 31666, 6), + [9702] = Position(32674, 31617, 6), + [9703] = Position(32664, 31679, 6), + [9704] = Position(32658, 31688, 8), + [9705] = Position(32655, 31688, 6) +} + +local teleportAbDendriel = MoveEvent() + +function teleportAbDendriel.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local toPosition = setting[item.actionid] + if not toPosition then + return true + end + + player:teleportTo(toPosition) + toPosition:sendMagicEffect(CONST_ME_POFF) + return true +end + +teleportAbDendriel:type("stepin") + +for index, value in pairs(setting) do + teleportAbDendriel:aid(index) +end + +teleportAbDendriel:register() diff --git a/data/scripts/movements/teleport/tomb_coal_basin.lua b/data/scripts/movements/teleport/tomb_coal_basin.lua new file mode 100644 index 00000000000..2f3b90ce2d3 --- /dev/null +++ b/data/scripts/movements/teleport/tomb_coal_basin.lua @@ -0,0 +1,35 @@ +local config = { + [9033] = {flamePosition = Position(33097, 32816, 13), toPosition = Position(33093, 32824, 13)}, + [9034] = {flamePosition = Position(33293, 32742, 13), toPosition = Position(33299, 32742, 13)}, + [9035] = {flamePosition = Position(33073, 32590, 13), toPosition = Position(33080, 32588, 13)}, + [9036] = {flamePosition = Position(33240, 32856, 13), toPosition = Position(33246, 32850, 13)}, + [9037] = {flamePosition = Position(33276, 32553, 14), toPosition = Position(33271, 32553, 14)}, + [9038] = {flamePosition = Position(33234, 32692, 13), toPosition = Position(33234, 32687, 13)}, + [9039] = {flamePosition = Position(33135, 32683, 12), toPosition = Position(33130, 32683, 12)}, + [9040] = {flamePosition = Position(33162, 32831, 10), toPosition = Position(33158, 32832, 10)} +} + +local tombCoalBasin = MoveEvent() + +function tombCoalBasin.onAddItem(moveitem, tileitem, position) + local targetCoalBasin = config[tileitem.uid] + if not targetCoalBasin then + return true + end + + if moveitem.itemid ~= 2159 then + position:sendMagicEffect(CONST_ME_POFF) + return true + end + + moveitem:remove() + position:sendMagicEffect(CONST_ME_HITBYFIRE) + + Tile(targetCoalBasin.flamePosition):relocateTo(targetCoalBasin.toPosition) + targetCoalBasin.toPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +tombCoalBasin:type("additem") +tombCoalBasin:id(1485) +tombCoalBasin:register() diff --git a/data/scripts/movements/teleport/turtles.lua b/data/scripts/movements/teleport/turtles.lua new file mode 100644 index 00000000000..003c5f2dc9c --- /dev/null +++ b/data/scripts/movements/teleport/turtles.lua @@ -0,0 +1,45 @@ +local setting = { + [3206] = Position(32359, 32901, 7), + [3207] = Position(32340, 32538, 7), + [3208] = Position(32472, 32869, 7), + [3209] = Position(32415, 32916, 7), + [3210] = Position(32490, 32979, 7), + [3211] = Position(32440, 32971, 7), + [3212] = Position(32527, 32951, 7), + [3213] = Position(32523, 32923, 7) +} + +local turtles = MoveEvent() + +function turtles.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.TheShatteredIsles.AccessToLagunaIsland) ~= 1 and item.uid == 3206 then + local accessPosition = Position(32340, 32540, 7) + player:teleportTo(accessPosition) + position:sendMagicEffect(CONST_ME_TELEPORT) + accessPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + local toPosition = setting[item.uid] + if not toPosition then + return true + end + + player:teleportTo(toPosition) + position:sendMagicEffect(CONST_ME_TELEPORT) + toPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +turtles:type("stepin") + +for index, value in pairs(setting) do + turtles:uid(index) +end + +turtles:register() diff --git a/data/scripts/movements/teleport/vengoth_teleport.lua b/data/scripts/movements/teleport/vengoth_teleport.lua new file mode 100644 index 00000000000..90906e580d0 --- /dev/null +++ b/data/scripts/movements/teleport/vengoth_teleport.lua @@ -0,0 +1,38 @@ +local setting = { + [50220] = Position(32943, 31553, 1), + [50221] = Position(32938, 31573, 0), + [50222] = Position(32950, 31575, 1), + [50223] = Position(32961, 31559, 1), + [50224] = Position(32959, 31540, 4), + [50225] = Position(32961, 31552, 1), + [50226] = Position(32951, 31568, 1), + [50227] = Position(32940, 31577, 0), + [50228] = Position(32940, 31558, 1), + [50229] = Position(32951, 31552, 3) +} + +local vengothTeleport = MoveEvent() + +function vengothTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local toPosition = setting[item.actionid] + if not toPosition then + return true + end + + player:teleportTo(toPosition) + toPosition:sendMagicEffect(CONST_ME_PURPLEENERGY) + return true +end + +vengothTeleport:type("stepin") + +for index, value in pairs(setting) do + vengothTeleport:aid(index) +end + +vengothTeleport:register() diff --git a/data/scripts/movements/teleport/yalahar_demon.lua b/data/scripts/movements/teleport/yalahar_demon.lua new file mode 100644 index 00000000000..13a9183002a --- /dev/null +++ b/data/scripts/movements/teleport/yalahar_demon.lua @@ -0,0 +1,59 @@ +local setting = { + -- west entrance + [4244] = { + sacrificePosition = Position(32859, 31056, 9), + pushPosition = Position(32856, 31054, 9), + destination = Position(32860, 31061, 9) + }, + --east entrance + [4245] = { + sacrificePosition = Position(32894, 31044, 9), + pushPosition = Position(32895, 31046, 9), + destination = Position(32888, 31044, 9) + } +} + +local yalaharDemon = MoveEvent() + +function yalaharDemon.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local flame = setting[item.actionid] + if not flame then + return true + end + + local sacrificeId, sacrifice = Tile(flame.sacrificePosition):getThing(1).itemid, true + if not isInArray({8298, 8299, 8302, 8303}, sacrificeId) then + sacrifice = false + end + + if not sacrifice then + player:teleportTo(flame.pushPosition) + position:sendMagicEffect(CONST_ME_ENERGYHIT) + flame.pushPosition:sendMagicEffect(CONST_ME_ENERGYHIT) + return true + end + + local soilItem = Tile(flame.sacrificePosition):getItemById(sacrificeId) + if soilItem then + soilItem:remove() + end + + player:teleportTo(flame.destination) + position:sendMagicEffect(CONST_ME_HITBYFIRE) + flame.sacrificePosition:sendMagicEffect(CONST_ME_HITBYFIRE) + flame.destination:sendMagicEffect(CONST_ME_HITBYFIRE) + return true +end + +yalaharDemon:type("stepin") + +for index, value in pairs(setting) do + yalaharDemon:aid(index) +end + +yalaharDemon:register() diff --git a/data/scripts/quests/alawars_vault/action-lever.lua b/data/scripts/quests/alawars_vault/action-lever.lua new file mode 100644 index 00000000000..40b664a20f2 --- /dev/null +++ b/data/scripts/quests/alawars_vault/action-lever.lua @@ -0,0 +1,21 @@ +local wallsPositions = { + {x = 32186, y = 31626, z = 8}, + {x = 32187, y = 31626, z = 8}, + {x = 32188, y = 31626, z = 8}, + {x = 32189, y = 31626, z = 8} +} + +local lever = Action() + +function lever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + for i = 1, #wallsPositions do + if item.itemid == 1945 then + Tile(wallsPositions[i]):getItemById(1498):remove() + item:remove() + end + end + return true +end + +lever:uid(30008) +lever:register() diff --git a/data/scripts/quests/behemoth/action-lever.lua b/data/scripts/quests/behemoth/action-lever.lua new file mode 100644 index 00000000000..adb3d97bf22 --- /dev/null +++ b/data/scripts/quests/behemoth/action-lever.lua @@ -0,0 +1,28 @@ +local wallsPositions = { + {x = 33295, y = 31677, z = 15}, + {x = 33296, y = 31677, z = 15}, + {x = 33297, y = 31677, z = 15}, + {x = 33298, y = 31677, z = 15}, + {x = 33299, y = 31677, z = 15} +} + +local lever = Action() + +function lever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 1946 then + return false + end + + for i = 1, #wallsPositions do + local walls = Tile(wallsPositions[i]):getItemById(1304) + if walls then + walls:remove() + end + end + + item:transform(1946) + return true +end + +lever:uid(30009) +lever:register() diff --git a/data/scripts/quests/deeper_fibula/action-draw_well.lua b/data/scripts/quests/deeper_fibula/action-draw_well.lua new file mode 100644 index 00000000000..96c0a3dcedf --- /dev/null +++ b/data/scripts/quests/deeper_fibula/action-draw_well.lua @@ -0,0 +1,9 @@ +local drawWell = Action() + +function drawWell.onUse(player, item, fromPosition, target, toPosition, isHotkey) + player:teleportTo({x = 32172, y = 32439, z = 8}) + return true +end + +drawWell:aid(15005) +drawWell:register() diff --git a/data/scripts/quests/demon_helmet/action-lever.lua b/data/scripts/quests/demon_helmet/action-lever.lua new file mode 100644 index 00000000000..5039ef6a2e9 --- /dev/null +++ b/data/scripts/quests/demon_helmet/action-lever.lua @@ -0,0 +1,27 @@ +local lever = Action() + +function lever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local teleportPosition = {x = 33316, y = 31574, z = 15} + local stonePosition = {x = 33314, y = 31575, z = 15} + + if item.itemid == 1945 then + local teleport = Game.createItem(1387, 1, teleportPosition) + if teleport then + teleport:setDestination({x = 33328, y = 31592, z = 14}) + Position(teleportPosition):sendMagicEffect(CONST_ME_TELEPORT) + end + + Tile(stonePosition):getItemById(1355):remove() + item:transform(1946) + elseif item.itemid == 1946 then + Position(stonePosition):hasCreature({x = 33315, y = 31575, z = 15}) + Tile(teleportPosition):getItemById(1387):remove() + Position(teleportPosition):sendMagicEffect(CONST_ME_POFF) + Game.createItem(1355, 1, stonePosition) + item:transform(1945) + end + return true +end + +lever:uid(30007) +lever:register() diff --git a/data/scripts/quests/demon_helmet/movement-walls.lua b/data/scripts/quests/demon_helmet/movement-walls.lua new file mode 100644 index 00000000000..f7891f316d6 --- /dev/null +++ b/data/scripts/quests/demon_helmet/movement-walls.lua @@ -0,0 +1,64 @@ +local tilesPositions = { + {x = 33190, y = 31629, z = 13}, + {x = 33191, y = 31629, z = 13} +} + +local wallsPositions = { + {x = 33210, y = 31630, z = 13}, + {x = 33211, y = 31630, z = 13}, + {x = 33212, y = 31630, z = 13} +} + +local walls = MoveEvent() +walls:type("stepin") + +function walls.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local tileCreature1 = Tile(tilesPositions[1]):getTopCreature() + local tileCreature2 = Tile(tilesPositions[2]):getTopCreature() + -- Check 2 tiles positions have a creature and it is a player + if tileCreature1 and tileCreature1:getPlayer() and tileCreature2 and tileCreature2:getPlayer() then + for i = 1, #wallsPositions do + wall = Tile(wallsPositions[i]):getItemById(1050) + -- Check there walls before delete them + if wall then + wall:remove() + end + end + end + return true +end + +for index, value in pairs(tilesPositions) do + walls:position(value) +end + +walls:register() + +walls = MoveEvent() +walls:type("stepout") + +function walls.onStepOut(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + for i = 1, #wallsPositions do + wall = Tile(wallsPositions[i]):getItemById(1050) + -- Check there is no walls before create new ones + if not wall then + Position(wallsPositions[i]):hasCreature({x = 33211, y = 31631, z = 13}) + Game.createItem(1050, 1, wallsPositions[i]) + end + end + return true +end + +for index, value in pairs(tilesPositions) do + walls:position(value) +end + +walls:register() diff --git a/data/scripts/quests/draconia/action-lever.lua b/data/scripts/quests/draconia/action-lever.lua new file mode 100644 index 00000000000..9617f6be06a --- /dev/null +++ b/data/scripts/quests/draconia/action-lever.lua @@ -0,0 +1,16 @@ +local lever = Action() + +function lever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local position = {x = 32790, y = 31594, z = 7} + if item.itemid == 1945 then + Tile(position):getItemById(1285):remove() + item:transform(1946) + elseif item.itemid == 1946 then + Game.createItem(1285, 1, position) + item:transform(1945) + end + return true +end + +lever:uid(30006) +lever:register() diff --git a/data/scripts/quests/draconia/movement-escape.lua b/data/scripts/quests/draconia/movement-escape.lua new file mode 100644 index 00000000000..a7fd55cc16a --- /dev/null +++ b/data/scripts/quests/draconia/movement-escape.lua @@ -0,0 +1,26 @@ +local escape = MoveEvent() + +function escape.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local sacrificeItem = Tile({x = 32816, y = 31601, z = 9}):getItemById(2319) + if not sacrificeItem then + player:teleportTo({x = 32818, y = 31599, z = 9}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + if player:getStorageValue(Storage.Dragonfetish) == 1 then + player:setStorageValue(Storage.Dragonfetish, 0) + end + player:teleportTo({x = 32701, y = 31639, z = 6}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + sacrificeItem:remove() + return true +end + +escape:uid(35012) +escape:register() diff --git a/data/scripts/quests/draconia/movement-exit_teleport.lua b/data/scripts/quests/draconia/movement-exit_teleport.lua new file mode 100644 index 00000000000..146cbc7c00b --- /dev/null +++ b/data/scripts/quests/draconia/movement-exit_teleport.lua @@ -0,0 +1,37 @@ +local config = { + {leverPosition = Position(32802, 31584, 1), leverId = 1945}, + {leverPosition = Position(32803, 31584, 1), leverId = 1946}, + {leverPosition = Position(32804, 31584, 1), leverId = 1945}, + {leverPosition = Position(32805, 31584, 1), leverId = 1946} +} + +local exitTeleport = MoveEvent() + +function exitTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local correct, leverItem = true + for i = 1, #config do + leverItem = Tile(config[i].leverPosition):getItemById(config[i].leverId) + if not leverItem then + correct = false + break + end + end + + if not correct then + player:teleportTo({x = 32803, y = 31587, z = 1}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + player:teleportTo({x = 32701, y = 31639, z = 6}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +exitTeleport:uid(35011) +exitTeleport:register() diff --git a/data/scripts/quests/giant_smithhammer/lever.lua b/data/scripts/quests/giant_smithhammer/lever.lua new file mode 100644 index 00000000000..2538a4e8c95 --- /dev/null +++ b/data/scripts/quests/giant_smithhammer/lever.lua @@ -0,0 +1,20 @@ +local lever = Action() + +function lever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local tile = Tile(Position({ x = 32780 , y = 32231 , z = 8})) + if item.itemid == 1945 then + if tile:getItemById(387) then + tile:getItemById(387):remove() + item:transform(1946) + else + Game.createItem(387, 1, { x = 32780 , y = 32231 , z = 8}) + end + else + Game.createItem(387, 1, { x = 32780 , y = 32231 , z = 8}) + item:transform(1945) + end + return true +end + +lever:uid(30024) +lever:register() diff --git a/data/scripts/quests/kilmaresh/1-fafnars-wrath/2-ambassadors-treason.lua b/data/scripts/quests/kilmaresh/1-fafnars-wrath/2-ambassadors-treason.lua new file mode 100644 index 00000000000..4afb07e5a38 --- /dev/null +++ b/data/scripts/quests/kilmaresh/1-fafnars-wrath/2-ambassadors-treason.lua @@ -0,0 +1,65 @@ +-- + +local paper = Action() + +function paper.onUse(player, item, frompos, item2, topos) + if player:getStorageValue(Storage.Kilmaresh.Second.Investigating) == 2 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"Documents were burnt here recently. Only the part of one scroll still lies in front of the chimney but it's too sooted to read.") + player:setStorageValue(Storage.Kilmaresh.Second.Investigating, 3) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You already investigated this.") + end + return true +end + +paper:uid(40030) +paper:register() + +-- + +local paperScraps = Action() + +function paperScraps.onUse(player, item, frompos, item2, topos) + if player:getStorageValue(Storage.Kilmaresh.Second.Investigating) == 3 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"Paper scraps lie scattered on the floor. It takes some time to put them back together. But it's only a badly written poem.") + player:setStorageValue(Storage.Kilmaresh.Second.Investigating, 4) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You already investigated this.") + end + return true +end + +paperScraps:uid(40031) +paperScraps:register() + +-- + +local scrolls = Action() + +function scrolls.onUse(player, item, frompos, item2, topos) + if player:getStorageValue(Storage.Kilmaresh.Second.Investigating) == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You examine the scrolls carefully. Those are orders from Rathleton for the Ambassador. No sign of treason here.") + player:setStorageValue(Storage.Kilmaresh.Second.Investigating, 2) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You already investigated this.") + end + return true +end + +scrolls:uid(40029) +scrolls:register() + +-- + +local roofTop = MoveEvent() + +function roofTop.onStepIn(player, item, frompos, item2, topos) + if player:getStorageValue(Storage.Kilmaresh.Second.Investigating) == 4 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You find nothing in the Ambassador's house. If he's in fact a traitor he got rid of any evidence that could incriminate him.") + player:setStorageValue(Storage.Kilmaresh.Second.Investigating, 5) + end + return true +end + +roofTop:aid(50307) +roofTop:register() \ No newline at end of file diff --git a/data/scripts/quests/kilmaresh/1-fafnars-wrath/3-urmahlullu-the-immaculate.lua b/data/scripts/quests/kilmaresh/1-fafnars-wrath/3-urmahlullu-the-immaculate.lua new file mode 100644 index 00000000000..c906a03df15 --- /dev/null +++ b/data/scripts/quests/kilmaresh/1-fafnars-wrath/3-urmahlullu-the-immaculate.lua @@ -0,0 +1,84 @@ +-- lever to urmahlullu room + +local config = { + requiredLevel = 100, + daily = true, + roomCenterPosition = Position(33919, 31648, 8), + playerPositions = { + Position(33918, 31626, 8), + Position(33919, 31626, 8), + Position(33920, 31626, 8), + Position(33921, 31626, 8), + Position(33922, 31626, 8) + }, + teleportPosition = Position(33918, 31657, 8), + bossPosition = Position(33918, 31641, 8) +} + +local leverboss = Action() + +function leverboss.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 9825 then + -- Check if the player that pulled the lever is on the correct position + if player:getPosition() ~= config.playerPositions[1] then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You can\'t start the battle.") + return true + end + + local team, participant = {} + + for i = 1, #config.playerPositions do + participant = Tile(config.playerPositions[i]):getTopCreature() + + -- Check there is a participant player + if participant and participant:isPlayer() then + -- Check participant level + if participant:getLevel() < config.requiredLevel then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, + "All the players need to be level ".. config.requiredLevel .." or higher.") + return true + end + + -- Check participant boss timer + if config.daily and participant:getStorageValue(Storage.Kilmaresh.UrmahlulluTimer) > os.time() then + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:sendCancelMessage("Not all players are ready yet from last battle.") + return true + end + + team[#team + 1] = participant + end + end + + -- Check if a team currently inside the boss room + local specs, spec = Game.getSpectators(config.roomCenterPosition, false, false, 14, 14, 13, 13) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "A team is already inside the boss room.") + return true + end + + spec:remove() + end + + -- Spawn boss + Game.createMonster("Urmahlullu the Immaculate", config.bossPosition) + + -- Teleport team participants + for i = 1, #team do + team[i]:getPosition():sendMagicEffect(CONST_ME_POFF) + team[i]:teleportTo(config.teleportPosition) + -- Assign boss timer + team[i]:setStorageValue(Storage.Kilmaresh.UrmahlulluTimer, os.time() + 20*60*60) -- 20 hours + end + + config.teleportPosition:sendMagicEffect(CONST_ME_ENERGYAREA) + end + + item:transform(9825) + return true +end + +leverboss:uid(9545) +leverboss:register() diff --git a/data/scripts/quests/kilmaresh/1-fafnars-wrath/6-mind-travel.lua b/data/scripts/quests/kilmaresh/1-fafnars-wrath/6-mind-travel.lua new file mode 100644 index 00000000000..c780544ae98 --- /dev/null +++ b/data/scripts/quests/kilmaresh/1-fafnars-wrath/6-mind-travel.lua @@ -0,0 +1,149 @@ +local brainPositions = { + {x = 33913, y = 31653, z = 9}, -- left + {x = 33921, y = 31650, z = 9} -- right +} + +local mirrorTeleportPositions = { + {x = 33899, y = 31644, z = 9}, -- left + {x = 33936, y = 31648, z = 9} -- right +} + +local templeCenter = { x = 33865, y = 31533, z = 7 } +local templeRadiusX = 8 +local templeRadiusY = 7 + +local chargedRingOfSecretThoughtsItemId = 36141 + +-- Hallucinogen's potion + +local potion = Action() + +function potion.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getSlotItem(CONST_SLOT_RING) and player:getSlotItem(CONST_SLOT_RING):getId() == chargedRingOfSecretThoughtsItemId then + local spectators = Game.getSpectators(templeCenter, false, true, templeRadiusX, templeRadiusX, templeRadiusY, templeRadiusY) + + for i = 1, #spectators do + if spectators[i].uid == player.uid then + player:teleportTo(brainPositions[math.random(#brainPositions)]) + item:remove(1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE,"You feel shaky and dizzy, the world turns dark around you. Then your sight clears again - and you are somewhere else.") + player:getPosition():sendMagicEffect(CONST_ME_ENERGYAREA) + return true + end + end + end + + return false +end + +potion:id(36185) +potion:register() + + +-- Mirror neuron + +local leftMirror = MoveEvent() + +function leftMirror.onStepIn(creature) + if creature:isPlayer() then + creature:teleportTo(mirrorTeleportPositions[2]) + creature:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You were moved to the right brain side") + creature:getPosition():sendMagicEffect(CONST_ME_ENERGYAREA) + return true + end + + return false +end + +leftMirror:uid(57505) +leftMirror:register() + + +local rightMirror = MoveEvent() + +function rightMirror.onStepIn(creature) + if creature:isPlayer() then + creature:teleportTo(mirrorTeleportPositions[1]) + creature:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You were moved to the left brain side") + creature:getPosition():sendMagicEffect(CONST_ME_ENERGYAREA) + return true + end + + return false +end + +rightMirror:uid(57506) +rightMirror:register() + + +-- Memories + +local shardIds = {36189, 36190, 36191} + +local memoriesWords = { + "The Ambassador tells another dignitary: Rathleton must never be surpassed! I will procure that the Empire falters!", + "Through a dimensional gate you can see the Ambassador of Rathleton wearing a cloak with a black sphinx on it.", + "Through a dimensional gate you can see how the Ambassador of Rathleton is talking to Fafnar cultists in a quite familiar way. The proof is absolutely substantive. The Ambassador is a betrayer!" +} + +local memoryShardsItemIdsBitmasks = { + [36189] = 1, + [36190] = 2, + [36191] = 4 +} + +local memoryShards = Action() + +function memoryShards.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local memoryStorage = player:getStorageValue(Storage.Kilmaresh.Fifth.Memories) + local memoriesShardsStorage = player:getStorageValue(Storage.Kilmaresh.Fifth.MemoriesShards) + local hasUsedShard = testFlag(memoriesShardsStorage, memoryShardsItemIdsBitmasks[item:getId()]) + + if memoryStorage >= 1 and -- following the quest + not hasUsedShard and -- making sure we don't use the same shard twice + target.uid == 57507 -- is it the shrine? + then + player:say(memoriesWords[memoryStorage], TALKTYPE_MONSTER_SAY, false, player, toPosition) + player:setStorageValue(Storage.Kilmaresh.Fifth.Memories, memoryStorage + 1) + player:setStorageValue(Storage.Kilmaresh.Fifth.MemoriesShards, setFlag(memoriesShardsStorage, memoryShardsItemIdsBitmasks[item:getId()])) + toPosition:sendMagicEffect(CONST_ME_ENERGYAREA) + return true + end + return false +end + +memoryShards:id(shardIds) -- Green, blue and purple memory shards +memoryShards:register() + + +-- Energy fields + +local energyField = MoveEvent() + +function energyField.onStepIn(creature, item, position, fromPosition) + + local player = creature:getPlayer() + + if not player then + return true + end + + local playerShardIds = {} + + -- Get player owned shards + for i = 1, #shardIds do + if player:getItemById(shardIds[i], true) then + table.insert(playerShardIds, shardIds[i]) + end + end + + -- Remove a random one, if have any + if #playerShardIds > 0 then + player:removeItem(playerShardIds[math.random(#playerShardIds)], 1) + end + + return true +end + +energyField:aid(40004) +energyField:register() diff --git a/data/scripts/quests/kilmaresh/1-fafnars-wrath/7-four-masks.lua b/data/scripts/quests/kilmaresh/1-fafnars-wrath/7-four-masks.lua new file mode 100644 index 00000000000..9daf853436c --- /dev/null +++ b/data/scripts/quests/kilmaresh/1-fafnars-wrath/7-four-masks.lua @@ -0,0 +1,52 @@ +local masks = { + [36204] = { + storage = 1, + successMessage = "You have found a gryphon mask.", -- TODO Gryphon Mask + emptyMessage = "The gryphon nest is empty." + }, + [36205] = { -- Silver mask + storage = 2, + successMessage = "You have found a silver mask.", + emptyMessage = "This palm is empty." + }, + [36206] = { -- For Ivory mask action see data\scripts\actions\other\gems.lua + storage = 4 + }, + [36207] = { -- Mirror Mask + storage = 8, + successMessage = "You have found a mirror mask.", + emptyMessage = "The sarcophagus is empty." + } +} + +local uidRewards = { + [40033] = 36204, + [40034] = 36205, + [40035] = 36207 +} + +local masksAction = Action() + +function masksAction.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local maskDiscovered = uidRewards[item.uid] + local mask = masks[maskDiscovered] + + if player:getStorageValue(Storage.Kilmaresh.Sixth.Favor) >= 1 and + not testFlag(player:getStorageValue(Storage.Kilmaresh.Sixth.FourMasks), mask.storage) + then + player:addItem(maskDiscovered, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, mask.successMessage) + player:setStorageValue(Storage.Kilmaresh.Sixth.Favor, player:getStorageValue(Storage.Kilmaresh.Sixth.Favor) + 1) + player:setStorageValue(Storage.Kilmaresh.Sixth.FourMasks, player:getStorageValue(Storage.Kilmaresh.Sixth.FourMasks) + mask.storage) + elseif player:getStorageValue(Storage.Kilmaresh.Sixth.Favor) >= 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, mask.emptyMessage) + else + return false + end + + return true +end + +masksAction:uid(40033, 40034, 40035) +masksAction:register() + diff --git a/data/scripts/quests/kilmaresh/1-fafnars-wrath/8-blessing-the-statues.lua b/data/scripts/quests/kilmaresh/1-fafnars-wrath/8-blessing-the-statues.lua new file mode 100644 index 00000000000..4370c50c918 --- /dev/null +++ b/data/scripts/quests/kilmaresh/1-fafnars-wrath/8-blessing-the-statues.lua @@ -0,0 +1,47 @@ +local config = { + [40036] = { + itemId = 35997, + storage = 1 + }, + [40037] = { + itemId = 35997, + storage = 2 + }, + [40038] = { + itemId = 35996, + storage = 4 + }, + [40039] = { + itemId = 35997, + storage = 8 + }, + [40040] = { + itemId = 35996, + storage = 16 + }, +} + +local statuesActions = Action() + +function statuesActions.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local key = config[target.uid] + + if not table.contains({key.itemId}, target.itemid) then + return false + end + + if player:getStorageValue(Storage.Kilmaresh.Sixth.Favor) >= 5 and + not testFlag(player:getStorageValue(Storage.Kilmaresh.Sixth.BlessedStatues), key.storage) + then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You bless the statue.") + player:setStorageValue(Storage.Kilmaresh.Sixth.Favor, player:getStorageValue(Storage.Kilmaresh.Sixth.Favor) + 1) + player:setStorageValue(Storage.Kilmaresh.Sixth.BlessedStatues, player:getStorageValue(Storage.Kilmaresh.Sixth.BlessedStatues) + key.storage) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You already blessed this statue.") + end + + return true +end + +statuesActions:id(36249) +statuesActions:register() \ No newline at end of file diff --git a/data/scripts/quests/parchment_room/parchment.lua b/data/scripts/quests/parchment_room/parchment.lua new file mode 100644 index 00000000000..e9c2141a78c --- /dev/null +++ b/data/scripts/quests/parchment_room/parchment.lua @@ -0,0 +1,34 @@ +local demonPositions = { + {x = 33060, y = 31623, z= 15}, + {x = 33066, y = 31623, z= 15}, + {x = 33060, y = 31627, z= 15}, + {x = 33066, y = 31627, z= 15} +} + +local function recreateParchment(position) + local item = Tile(position):getItemById(1953) + if item then + item:setActionId(104) + else + local parchment = Game.createItem(1953, 1, position) + if parchment then + parchment:setText("Buried forever that he never shall return. Don't remove this seal or bad things may happen.") + parchment:setActionId(104) + end + end +end + +local parchment = MoveEvent() + +function parchment.onRemoveItem(item, tile, position) + item:removeAttribute(ITEM_ATTRIBUTE_ACTIONID) + addEvent(recreateParchment, 2 * 60 * 60 * 1000, position) -- 2 hours + + for i = 1, #demonPositions do + Game.createMonster('Demon', demonPositions[i]) + end + return true +end + +parchment:aid(104) +parchment:register() diff --git a/data/scripts/quests/thais_lighthouse/action-lever.lua b/data/scripts/quests/thais_lighthouse/action-lever.lua new file mode 100644 index 00000000000..7e1cd6cefb2 --- /dev/null +++ b/data/scripts/quests/thais_lighthouse/action-lever.lua @@ -0,0 +1,43 @@ +local lever = Action() + +function lever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + -- First lever to open the ladder + if item.uid == 30004 then + local laddertile = Tile({x = 32225, y = 32276, z = 8}) + if item.itemid == 1945 then + laddertile:getItemById(9021):transform(8280) + item:transform(1946) + else + laddertile:getItemById(8280):transform(9021) + item:transform(1945) + end + -- Second lever to open the teleport to cyclops + elseif item.uid == 30005 then + local entranceTeleportTile = Tile({x = 32232, y = 32276, z = 9}) + local exitTeleportTile = Tile({x = 32225, y = 32276, z = 10}) + if item.itemid == 1945 then + if entranceTeleportTile:getItemById(1387) and exitTeleportTile:getItemById(1387) then + entranceTeleportTile:getItemById(1387):remove() + exitTeleportTile:getItemById(1387):remove() + else + local teleportEntrance = Game.createItem(1387, 1, {x = 32232, y = 32276, z = 9}) + local teleportExit = Game.createItem(1387, 1, {x = 32225, y = 32276, z = 10}) + if teleportEntrance and teleportExit then + teleportEntrance:setDestination({x = 32225, y = 32274, z = 10}) + teleportExit:setDestination({x = 32230, y = 32276, z = 9}) + end + item:transform(1946) + end + elseif item.itemid == 1946 then + if entranceTeleportTile:getItemById(1387) and exitTeleportTile:getItemById(1387) then + entranceTeleportTile:getItemById(1387):remove() + exitTeleportTile:getItemById(1387):remove() + item:transform(1945) + end + end + end + return true +end + +lever:uid(30004, 30005) +lever:register() diff --git a/data/scripts/quests/thais_lighthouse/movement-stair.lua b/data/scripts/quests/thais_lighthouse/movement-stair.lua new file mode 100644 index 00000000000..3048958dbd0 --- /dev/null +++ b/data/scripts/quests/thais_lighthouse/movement-stair.lua @@ -0,0 +1,35 @@ +local stairPosition = {x = 32225, y = 32282, z = 9} + +local stair = MoveEvent() +stair:type("stepin") + +function stair.onStepIn(creature, item, position, fromPosition) + -- Create stairs + if item.uid == 25010 then + local stairsItem = Tile(stairPosition):getItemById(424) + if stairsItem then + stairsItem:transform(8280) + end + item:transform(425) + end + return true +end + +stair:uid(25010) +stair:register() + +stair = MoveEvent() +stair:type("stepout") + +function stair.onStepOut(creature, item, position, fromPosition) + local stairsItem = Tile(stairPosition):getItemById(8280) + if stairsItem then + stairsItem:transform(424) + end + + item:transform(426) + return true +end + +stair:uid(25010) +stair:register() diff --git a/data/scripts/quests/the_annihilator/door.lua b/data/scripts/quests/the_annihilator/door.lua new file mode 100644 index 00000000000..91f6b6f3a65 --- /dev/null +++ b/data/scripts/quests/the_annihilator/door.lua @@ -0,0 +1,25 @@ +local door = Action() + +function door.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:getStorageValue(Storage.Quest.TheAnnihilator.Reward) == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The door seems to be sealed against unwanted intruders.") + return true + end + + if item.itemid == 5114 then + player:teleportTo(toPosition, true) + item:transform(item.itemid + 1) + elseif item.itemid == 5115 then + if Creature.checkCreatureInsideDoor(player, toPosition) then + return true + end + if item.itemid == 5115 then + item:transform(item.itemid - 1) + return true + end + end + return true +end + +door:aid(10102) +door:register() diff --git a/data/scripts/quests/the_annihilator/lever.lua b/data/scripts/quests/the_annihilator/lever.lua new file mode 100644 index 00000000000..ca2b95cd534 --- /dev/null +++ b/data/scripts/quests/the_annihilator/lever.lua @@ -0,0 +1,84 @@ +local setting = { + -- At what level can do the quest? + requiredLevel = 100, + -- Can it be done daily? true = yes, false = no + daily = true, + -- Do not change from here down + centerDemonRoomPosition = {x = 33221, y = 31659, z = 13}, + demonsPositions = { + {x = 33219, y = 31657, z = 13}, + {x = 33221, y = 31657, z = 13}, + {x = 33223, y = 31659, z = 13}, + {x = 33224, y = 31659, z = 13}, + {x = 33220, y = 31661, z = 13}, + {x = 33222, y = 31661, z = 13} + }, + playersPositions = { + {fromPos = {x = 33225, y = 31671, z = 13}, toPos = {x = 33222, y = 31659, z = 13}}, + {fromPos = {x = 33224, y = 31671, z = 13}, toPos = {x = 33221, y = 31659, z = 13}}, + {fromPos = {x = 33223, y = 31671, z = 13}, toPos = {x = 33220, y = 31659, z = 13}}, + {fromPos = {x = 33222, y = 31671, z = 13}, toPos = {x = 33219, y = 31659, z = 13}}, + } +} + +local lever = Action() + +function lever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == 1945 then + -- Checks if you have the 4 players and if they have the required level + for i = 1, #setting.playersPositions do + local creature = Tile(setting.playersPositions[i].fromPos):getTopCreature() + if not creature then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Four players are required to start the quest.") + return true + end + if creature and creature:getLevel() < setting.requiredLevel then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "All the players need to be level ".. setting.requiredLevel .." or higher.") + return true + end + end + + -- Checks if there are still players inside the room, if so, return true + if Position.hasPlayer(setting.centerDemonRoomPosition, 4, 4) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "A team is already inside the quest room.") + return true + end + + -- Create monsters + for i = 1, #setting.demonsPositions do + Game.createMonster("Angry Demon", setting.demonsPositions[i]) + end + + -- Get players from the tiles "playersPositions" and teleport to the demons room if all of the above requirements are met + for i = 1, #setting.playersPositions do + local creature = Tile(setting.playersPositions[i].fromPos):getTopCreature() + if creature and creature:isPlayer() then + creature:teleportTo(setting.playersPositions[i].toPos) + creature:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + return false + end + end + item:transform(1946) + elseif item.itemid == 1946 then + -- If it has "daily = true" then it will execute this function + if setting.daily then + player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + return true + end + -- Not be able to push the lever back if someone is still inside the monsters room + if Position.hasPlayer(setting.centerDemonRoomPosition, 4, 4) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "A team is already inside the quest room.") + return true + end + -- Removes all monsters so that the next team can enter + if Position.removeMonster(setting.centerDemonRoomPosition, 4, 4) then + return true + end + item:transform(1945) + end + return true +end + +lever:uid(30025) +lever:register() diff --git a/data/scripts/quests/the_paradox_tower/action-fifth_floor_lever.lua b/data/scripts/quests/the_paradox_tower/action-fifth_floor_lever.lua new file mode 100644 index 00000000000..2ee80c41f26 --- /dev/null +++ b/data/scripts/quests/the_paradox_tower/action-fifth_floor_lever.lua @@ -0,0 +1,41 @@ +local positions = { + {x = 32478, y = 31903, z = 3}, + {x = 32479, y = 31903, z = 3} +} + +local fifthFloorLever = Action() + +function fifthFloorLever.onUse(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local stairPosition = {x = 32479, y = 31904, z = 3} + local stairId = 1386 + + if item.itemid == 1945 then + -- Check if have all items + if Position(positions[1]):hasItem(2628) and Position(positions[2]):hasItem(2634) then + -- If have all items, then remove it + Position(positions[1]):removeItem(2628) + Position(positions[2]):removeItem(2634) + -- Create ladder + Position(stairPosition):createItem(stairId) + item:transform(1946) + -- If not have all items, then send poff effect + else + item:getPosition():sendMagicEffect(CONST_ME_POFF) + end + elseif item.itemid == 1946 then + -- Remove ladder + if Position(stairPosition):hasItem(stairId) then + Position(stairPosition):removeItem(stairId) + end + item:transform(1945) + end + return true +end + +fifthFloorLever:uid(30028) +fifthFloorLever:register() diff --git a/data/scripts/quests/the_paradox_tower/action-four_floor_lever.lua b/data/scripts/quests/the_paradox_tower/action-four_floor_lever.lua new file mode 100644 index 00000000000..294947fa360 --- /dev/null +++ b/data/scripts/quests/the_paradox_tower/action-four_floor_lever.lua @@ -0,0 +1,54 @@ +local positions = { + {x = 32476, y = 31900, z = 4}, + {x = 32477, y = 31900, z = 4}, + {x = 32478, y = 31900, z = 4}, + {x = 32479, y = 31900, z = 4}, + {x = 32480, y = 31900, z = 4}, + {x = 32481, y = 31900, z = 4} +} + +local fourFloorLever = Action() + +function fourFloorLever.onUse(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local stairPosition = {x = 32476, y = 31904, z = 4} + local stairId = 1386 + + if item.itemid == 1945 then + -- Check if have all items + if Position(positions[1]):hasItem(2682) + and Position(positions[2]):hasItem(2676) + and Position(positions[3]):hasItem(2679) + and Position(positions[4]):hasItem(2674) + and Position(positions[5]):hasItem(2681) + and Position(positions[6]):hasItem(2678) then + -- If have all items, then remove it + Position(positions[1]):removeItem(2682) + Position(positions[2]):removeItem(2676) + Position(positions[3]):removeItem(2679) + Position(positions[4]):removeItem(2674) + Position(positions[5]):removeItem(2681) + Position(positions[6]):removeItem(2678) + -- Create ladder + Position(stairPosition):createItem(stairId) + item:transform(1946) + -- If not have all items, then send poff effect + else + item:getPosition():sendMagicEffect(CONST_ME_POFF) + end + elseif item.itemid == 1946 then + -- Remove ladder + if Position(stairPosition):hasItem(stairId) then + Position(stairPosition):removeItem(stairId) + end + item:transform(1945) + end + return true +end + +fourFloorLever:uid(30027) +fourFloorLever:register() diff --git a/data/scripts/quests/the_paradox_tower/action-second_floor_lever.lua b/data/scripts/quests/the_paradox_tower/action-second_floor_lever.lua new file mode 100644 index 00000000000..0c117c4e300 --- /dev/null +++ b/data/scripts/quests/the_paradox_tower/action-second_floor_lever.lua @@ -0,0 +1,47 @@ +local positions = { + {x = 32476, y = 31900, z = 6}, + {x = 32477, y = 31900, z = 6}, + {x = 32478, y = 31900, z = 6}, + {x = 32479, y = 31900, z = 6}, + {x = 32480, y = 31900, z = 6}, + {x = 32481, y = 31900, z = 6} +} + +local secondFloorLever = Action() + +function secondFloorLever.onUse(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local stairPosition = {x = 32476, y = 31904, z = 6} + local stairId = 1386 + + -- Create stair + -- The stair is only created if all the jungles of the "position" variable (line 1) are growing again + if item.itemid == 1945 then + -- Checks if all levers glass are in the correct positions + if Position(positions[1]):hasItem(1946) + and Position(positions[2]):hasItem(1946) + and Position(positions[3]):hasItem(1945) + and Position(positions[4]):hasItem(1945) + and Position(positions[5]):hasItem(1946) + and Position(positions[6]):hasItem(1945) then + -- If all the jungles are growing again, then he turns the stone on the stairs + Position(stairPosition):createItem(stairId) + item:transform(1946) + else + item:getPosition():sendMagicEffect(CONST_ME_POFF) + end + elseif item.itemid == 1946 then + if Position(stairPosition):hasItem(stairId) then + Position(stairPosition):removeItem(stairId) + end + item:transform(1945) + end + return true +end + +secondFloorLever:uid(25016) +secondFloorLever:register() diff --git a/data/scripts/quests/the_paradox_tower/action-third_floor_lever.lua b/data/scripts/quests/the_paradox_tower/action-third_floor_lever.lua new file mode 100644 index 00000000000..e2c757c2994 --- /dev/null +++ b/data/scripts/quests/the_paradox_tower/action-third_floor_lever.lua @@ -0,0 +1,30 @@ +local thirdFloorLever = Action() + +function thirdFloorLever.onUse(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + -- Create stair + -- The stair is only created if all the jungles of the "position" variable (line 1) are growing again + if item.itemid == 10044 then + -- Checks if all levers glass are in the correct positions + addEvent( + function() + Game.createMonster("ghoul", {x = 32479, y = 31900, z = 5}) + end, 2000) + item:transform(10045) + addEvent( + function() + Position.hasCreatureInArea({x= 32476, y = 31900, z = 5}, {x= 32481, y = 31901, z = 5}, true, false) + item:transform(10044) + end, 100000) + elseif item.itemid == 10045 then + player:sendCancelMessage(RETURNVALUE_CANNOTUSETHISOBJECT) + end + return true +end + +thirdFloorLever:uid(30026) +thirdFloorLever:register() diff --git a/data/scripts/quests/the_paradox_tower/movement-first_floor_stair.lua b/data/scripts/quests/the_paradox_tower/movement-first_floor_stair.lua new file mode 100644 index 00000000000..c5d59e6ffed --- /dev/null +++ b/data/scripts/quests/the_paradox_tower/movement-first_floor_stair.lua @@ -0,0 +1,47 @@ +local positions = { + {x = 32478, y = 31920, z = 7}, + {x = 32479, y = 31920, z = 7}, + {x = 32478, y = 31921, z = 7}, + {x = 32479, y = 31921, z = 7}, + {x = 32478, y = 31922, z = 7}, + {x = 32479, y = 31922, z = 7}, +} + +local firstFloorStair = MoveEvent() + +function firstFloorStair.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local jungleGrassId = 2782 + local stairPosition = {x = 32478, y = 31902, z = 7} + local stairId = 1385 + local stoneId = 1304 + + -- Create stair + -- The stair is only created if all the jungles of the "position" variable (line 1) are growing again + if item.uid == 25013 then + -- Checks if all jungle glass are in the positions + if Position(positions[1]):hasItem(jungleGrassId) + and Position(positions[2]):hasItem(jungleGrassId) + and Position(positions[3]):hasItem(jungleGrassId) + and Position(positions[4]):hasItem(jungleGrassId) + and Position(positions[5]):hasItem(jungleGrassId) + and Position(positions[6]):hasItem(jungleGrassId) then + -- If all the jungles are growing again, then he turns the stone on the stairs + Position(stairPosition):transformItem(stoneId, stairId, CONST_ME_POFF) + end + -- Remove stair if exit of the tower + elseif table.contains({25014, 25015}, item.uid) then + -- Checks whether the item in position is the stair + if Position(stairPosition):hasItem(stairId) then + Position(stairPosition):transformItem(stairId, stoneId, CONST_ME_POFF) + end + end + return true +end + +firstFloorStair:uid(25013, 25014, 25015) +firstFloorStair:register() diff --git a/data/scripts/quests/the_paradox_tower/movement-last_floor_reward.lua b/data/scripts/quests/the_paradox_tower/movement-last_floor_reward.lua new file mode 100644 index 00000000000..d91571efc6b --- /dev/null +++ b/data/scripts/quests/the_paradox_tower/movement-last_floor_reward.lua @@ -0,0 +1,50 @@ +local setting = { + [50308] = { + position = {x = 32477, y = 31900, z = 1}, + storage = Storage.Quest.TheParadoxTower.Reward.Egg + }, + [50309] = { + position = {x = 32478, y = 31900, z = 1}, + storage = Storage.Quest.TheParadoxTower.Reward.Gold + }, + [50310] = { + position = {x = 32479, y = 31900, z = 1}, + storage = Storage.Quest.TheParadoxTower.Reward.Talon + }, + [50311] = { + position = {x = 32480, y = 31900, z = 1}, + storage = Storage.Quest.TheParadoxTower.Reward.Wand + } +} + +local lastFloorReward = MoveEvent() + +function lastFloorReward.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + -- Checks the table on line 1 + local action = setting[item.actionid] + if not action then + return true + end + + -- If already step in on the tile, nothing will happen + if player:getStorageValue(action.storage) == 1 then + return true + end + + -- Sends the effect to the chest position + Position(action.position):sendMagicEffect(CONST_ME_FIREAREA) + -- Set the storage if reward, to "destroy" the chest + player:setStorageValue(action.storage, 1) + return true +end + +for action, value in pairs(setting) do + lastFloorReward:aid(action) +end + +lastFloorReward:register() diff --git a/data/scripts/quests/the_paradox_tower/movement-poison.lua b/data/scripts/quests/the_paradox_tower/movement-poison.lua new file mode 100644 index 00000000000..5d3f68a886a --- /dev/null +++ b/data/scripts/quests/the_paradox_tower/movement-poison.lua @@ -0,0 +1,32 @@ +local positions = { + {x = 32497, y = 31889, z = 7}, + {x = 32497, y = 31890, z = 7}, + {x = 32498, y = 31890, z = 7}, + {x = 32499, y = 31890, z = 7}, + {x = 32502, y = 31890, z = 7}, + {x = 32494, y = 31888, z = 7} +} + +local poison = MoveEvent() + +function poison.onStepOut(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local removeHealth = Tile({x = 32497, y = 31889, z = 7}):getFieldItem() + if not removeHealth then + player:addHealth(-200, COMBAT_POISONDAMAGE) + for i = 1, #positions do + local tile = Tile(positions[i]):getFieldItem() + if not tile then + Game.createItem(1490, 1, Position(positions[i])) + end + end + end + return true +end + +poison:uid(25011) +poison:register() diff --git a/data/scripts/quests/the_paradox_tower/movement-sacrifice_skulls.lua b/data/scripts/quests/the_paradox_tower/movement-sacrifice_skulls.lua new file mode 100644 index 00000000000..e7ec35e0da1 --- /dev/null +++ b/data/scripts/quests/the_paradox_tower/movement-sacrifice_skulls.lua @@ -0,0 +1,42 @@ +local positions = { + {x = 32563, y = 31957, z = 1}, + {x = 32565, y = 31957, z = 1}, + {x = 32567, y = 31957, z = 1}, + {x = 32569, y = 31957, z = 1} +} + +local sacrificeSkulls = MoveEvent() + +function sacrificeSkulls.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + for i = 4, #positions do + -- Check if have skulls in all positions + local tile = Tile(positions[i]):getItemById(2229) + if tile then + -- Message, only send in the first acess of the paradox tower + if player:getStorageValue(FirstParadoxAcess) < 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "One of the toxic salt seas in Krailos carries fresh and clean water again. The ogres' water supply is ensured for now") + player:setStorageValue(FirstParadoxAcess, 1) + end + -- Remove skulls + for skulls = 1, #positions do + local skull = Tile(positions[skulls]):getItemById(2229) + if skull then + -- Create poison fields from the positions + Game.createItem(1490, 1, Position(positions[skulls])) + -- Remove skulls from the positions + skull:remove(1) + end + end + player:teleportTo({x = 32479, y = 31923, z = 7}) + end + end + return true +end + +sacrificeSkulls:uid(25012) +sacrificeSkulls:register() diff --git a/data/scripts/quests/the_paradox_tower/movement-third_floor_ghoul.lua b/data/scripts/quests/the_paradox_tower/movement-third_floor_ghoul.lua new file mode 100644 index 00000000000..b471faae257 --- /dev/null +++ b/data/scripts/quests/the_paradox_tower/movement-third_floor_ghoul.lua @@ -0,0 +1,37 @@ +local ladderPosition = {x = 32478, y = 31904, z = 5} + +local thirdFloorGhoul = MoveEvent() + +function thirdFloorGhoul.onStepIn(creature, item, position, fromPosition) + local monster = creature:getMonster() + if monster then + if item.uid == 25017 then + -- If ghoul step in tile, create the ladder + item:transform(425) + Position(ladderPosition):createItem(1386) + monster:say("") + end + end + return true +end + +thirdFloorGhoul:uid(25017) +thirdFloorGhoul:register() + +local thirdFloorGhoul = MoveEvent() + +function thirdFloorGhoul.onStepOut(creature, item, position, fromPosition) + local monster = creature:getMonster() + if monster then + if item.uid == 25017 then + item:transform(426) + -- If ghoul step in tile, remove the ladder + Position(ladderPosition):removeItem(1386) + monster:say("") + end + end + return true +end + +thirdFloorGhoul:uid(25017) +thirdFloorGhoul:register() diff --git a/data/scripts/quests/the_queen_of_the_banshees/action-1-first_seal_lever.lua b/data/scripts/quests/the_queen_of_the_banshees/action-1-first_seal_lever.lua new file mode 100644 index 00000000000..669209a6278 --- /dev/null +++ b/data/scripts/quests/the_queen_of_the_banshees/action-1-first_seal_lever.lua @@ -0,0 +1,45 @@ +local leverFirstSeal = Action() + +function leverFirstSeal.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local wall = firstSealTable[item.uid] + if not wall then + return false + end + + if item.uid == 30012 then + if item.itemid == 32400 then + Position(wall.position):removeItem(1498) + Position(wall.position):createItem(369) + item:transform(1946) + return true + elseif item.itemid == 1946 then + Position(wall.position):removeItem(369) + Position(wall.position):createItem(1498) + item:transform(32400) + return true + end + return false + end + + if item.itemid == 1945 then + Position(wall.position):removeItem(1498) + if wall.revert == true then + addEvent(Position.revertItem, 100 * 1000, wall.position, 1498) + end + item:transform(1946) + elseif item.itemid == 1946 then + if Position(wall.position):createItem(1498) then + stopEvent(Position.revertItem) + item:transform(1945) + return true + end + item:transform(1945) + end + return true +end + +for index, value in pairs(firstSealTable) do + leverFirstSeal:uid(index) +end + +leverFirstSeal:register() diff --git a/data/scripts/quests/the_queen_of_the_banshees/action-3-third_seal_lever.lua b/data/scripts/quests/the_queen_of_the_banshees/action-3-third_seal_lever.lua new file mode 100644 index 00000000000..abd40fa937f --- /dev/null +++ b/data/scripts/quests/the_queen_of_the_banshees/action-3-third_seal_lever.lua @@ -0,0 +1,48 @@ +local thirdSealLever = Action() + +function thirdSealLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid ~= 1946 then + return false + end + + local switchNum = Game.getStorageValue("switchNum") + if switchNum == -1 then + Game.setStorageValue("switchNum", 1) + end + + local table = thirdSealTable[switchNum] + if not table then + return true + end + + if player:getStorageValue(Storage.Quest.TheQueenOfTheBanshees.ThirdSeal) == 1 then + return false + end + + if player:getStorageValue(Storage.Quest.TheQueenOfTheBanshees.ThirdSeal) < 1 then + if item.uid == table then + item:transform(1945) + Game.setStorageValue("switchNum", Game.getStorageValue("switchNum") + 1) + toPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + for i = 1, #thirdSealTable.effectPosition[switchNum] do + Position(thirdSealTable.effectPosition[switchNum][i]):sendMagicEffect(CONST_ME_ENERGYHIT) + end + if Game.getStorageValue("switchNum") == 6 then + for i = 1, #thirdSealTable.coalBasinPosition do + local positions = thirdSealTable.coalBasinPosition[i] + Position(positions):removeItem(1485) + Position(positions):createItem(1484) + end + end + else + toPosition:sendMagicEffect(CONST_ME_ENERGYHIT) + end + end + return true +end + +for uniqueRange = 30013, 30017 do + thirdSealLever:uid(uniqueRange) +end + +thirdSealLever:register() diff --git a/data/scripts/quests/the_queen_of_the_banshees/action-6-sixth_seal_lever.lua b/data/scripts/quests/the_queen_of_the_banshees/action-6-sixth_seal_lever.lua new file mode 100644 index 00000000000..2378a7ecbc8 --- /dev/null +++ b/data/scripts/quests/the_queen_of_the_banshees/action-6-sixth_seal_lever.lua @@ -0,0 +1,34 @@ +local sixthSeal = Action() + +function sixthSeal.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local lever = sixthSealTable.uniqueTable[item.uid] + if not lever then + return false + end + + local tile = Tile(lever) + if tile then + if item.itemid == 1945 then + local campfire = tile:getItemById(1423) + if campfire then + campfire:transform(1421) + end + item:transform(1946) + return true + elseif item.itemid == 1946 then + local campfire = tile:getItemById(1421) + if campfire then + campfire:transform(1423) + end + item:transform(1945) + return true + end + end + return false +end + +for index, value in pairs(sixthSealTable.uniqueTable) do + sixthSeal:uid(index) +end + +sixthSeal:register() diff --git a/data/scripts/quests/the_queen_of_the_banshees/movement-1-first_seal_close_mw.lua b/data/scripts/quests/the_queen_of_the_banshees/movement-1-first_seal_close_mw.lua new file mode 100644 index 00000000000..2094576f103 --- /dev/null +++ b/data/scripts/quests/the_queen_of_the_banshees/movement-1-first_seal_close_mw.lua @@ -0,0 +1,57 @@ +-- First magic wall (first lever) +local firstSealCloseMw = MoveEvent() + +function firstSealCloseMw.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local magicWallPosition = {x = 32259, y = 31890, z = 10} + if Position(magicWallPosition):createItem(1498) then + stopEvent(Position.revertItem) + end + return true +end + +firstSealCloseMw:position({x = 32257, y = 31887, z = 10}) +firstSealCloseMw:register() + +-- Second magic wall (second lever) +local firstSealCloseMw = MoveEvent() + +function firstSealCloseMw.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local magicWallPosition = {x = 32259, y = 31891, z = 10} + if Position(magicWallPosition):createItem(1498) then + stopEvent(Position.revertItem) + end + return true +end + +firstSealCloseMw:position({x = 32258, y = 31887, z = 10}) +firstSealCloseMw:register() + +-- Third magic wall (third lever) +local firstSealCloseMw = MoveEvent() + +function firstSealCloseMw.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local magicWallPosition = {x = 32266, y = 31860, z = 11} + Position(magicWallPosition):removeItem(369) + + local leverPosition = {x = 32266, y = 31861, z = 11} + Position.revertItem(magicWallPosition, 1498, leverPosition, 1946, 32400) + return true +end + +firstSealCloseMw:position({x = 32266, y = 31860, z = 12}) +firstSealCloseMw:register() diff --git a/data/scripts/quests/the_queen_of_the_banshees/movement-1-first_seal_flame.lua b/data/scripts/quests/the_queen_of_the_banshees/movement-1-first_seal_flame.lua new file mode 100644 index 00000000000..29bd46448c6 --- /dev/null +++ b/data/scripts/quests/the_queen_of_the_banshees/movement-1-first_seal_flame.lua @@ -0,0 +1,25 @@ +local firstSealFlame = MoveEvent() + +function firstSealFlame.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.Quest.TheQueenOfTheBanshees.FirstSeal) < 1 then + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.FirstSeal, 1) + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.FirstSealDoor, 1) + player:teleportTo({x = 32266, y = 31849, z = 15}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + Game.createMonster('ghost', Position(32276, 31902, 13), false, true) + Game.createMonster('ghost', Position(32274, 31902, 13), false, true) + Game.createMonster('demon skeleton', Position(32276, 31904, 13), false, true) + else + player:teleportTo(fromPosition, true) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +firstSealFlame:uid(35013) +firstSealFlame:register() diff --git a/data/scripts/quests/the_queen_of_the_banshees/movement-1-first_seal_teleport_back.lua b/data/scripts/quests/the_queen_of_the_banshees/movement-1-first_seal_teleport_back.lua new file mode 100644 index 00000000000..55d5c7fd9f6 --- /dev/null +++ b/data/scripts/quests/the_queen_of_the_banshees/movement-1-first_seal_teleport_back.lua @@ -0,0 +1,14 @@ +local teleportBack = MoveEvent() + +function teleportBack.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if item.actionid ~= 25019 or not player then + return true + end + + player:teleportTo({x = 32266, y = 31886, z = 12}) + return true +end + +teleportBack:aid(25019) +teleportBack:register() diff --git a/data/scripts/quests/the_queen_of_the_banshees/movement-2-second_seal_flame.lua b/data/scripts/quests/the_queen_of_the_banshees/movement-2-second_seal_flame.lua new file mode 100644 index 00000000000..85cd41470e8 --- /dev/null +++ b/data/scripts/quests/the_queen_of_the_banshees/movement-2-second_seal_flame.lua @@ -0,0 +1,23 @@ +local secondSealFlame = MoveEvent() + +function secondSealFlame.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.Quest.TheQueenOfTheBanshees.SecondSeal) < 1 then + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.SecondSeal, 1) + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.SecondSealDoor, 1) + player:teleportTo(Position(32272, 31849, 15)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:teleportTo(fromPosition, true) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +secondSealFlame:uid(35014) +secondSealFlame:type("stepin") +secondSealFlame:register() diff --git a/data/scripts/quests/the_queen_of_the_banshees/movement-2-second_seal_pearl.lua b/data/scripts/quests/the_queen_of_the_banshees/movement-2-second_seal_pearl.lua new file mode 100644 index 00000000000..4a5092aebfe --- /dev/null +++ b/data/scripts/quests/the_queen_of_the_banshees/movement-2-second_seal_pearl.lua @@ -0,0 +1,38 @@ +local secondSealPearl = MoveEvent() + +function secondSealPearl.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.Quest.TheQueenOfTheBanshees.SecondSeal) >= 1 then + player:teleportTo(fromPosition, true) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + local pearlItems = {} + for i = 1, #secondSealTable.positions do + local pearlItem = Tile(secondSealTable.positions[i].position):getItemById(secondSealTable.positions[i].pearlId) + if not pearlItem then + player:teleportTo(fromPosition, true) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + pearlItems[#pearlItems + 1] = pearlItem + end + + for i = 1, #pearlItems do + pearlItems[i]:remove(1) + end + + player:teleportTo(Position(position.x, position.y - 6, position.z)) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +secondSealPearl:type("stepin") +secondSealPearl:aid(35002) +secondSealPearl:register() diff --git a/data/scripts/quests/the_queen_of_the_banshees/movement-3-third_seal_flame.lua b/data/scripts/quests/the_queen_of_the_banshees/movement-3-third_seal_flame.lua new file mode 100644 index 00000000000..24e3d1eaa11 --- /dev/null +++ b/data/scripts/quests/the_queen_of_the_banshees/movement-3-third_seal_flame.lua @@ -0,0 +1,35 @@ +local thirdSealFlame = MoveEvent() + +function thirdSealFlame.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.Quest.TheQueenOfTheBanshees.ThirdSeal) >= 1 or Game.getStorageValue('switchNum') ~= 6 then + player:teleportTo(fromPosition) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + for i = 1, #thirdSealTable.coalBasinPosition do + local positions = thirdSealTable.coalBasinPosition[i] + Position(positions):transformItem(1484, 1485) + end + + for i = 1, #thirdSealTable.switchPosition do + local positions = thirdSealTable.switchPosition[i] + Position(positions):transformItem(1945, 1946) + end + + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.ThirdSeal, 1) + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.ThirdSealDoor, 1) + Game.setStorageValue('switchNum', 1) + player:teleportTo({x = 32271, y = 31857, z = 15}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +thirdSealFlame:uid(35015) +thirdSealFlame:type("stepin") +thirdSealFlame:register() diff --git a/data/scripts/quests/the_queen_of_the_banshees/movement-3-third_seal_warlock_tile.lua b/data/scripts/quests/the_queen_of_the_banshees/movement-3-third_seal_warlock_tile.lua new file mode 100644 index 00000000000..4331ac8f85a --- /dev/null +++ b/data/scripts/quests/the_queen_of_the_banshees/movement-3-third_seal_warlock_tile.lua @@ -0,0 +1,20 @@ +local thirdSealWarlockTile = MoveEvent() + +function thirdSealWarlockTile.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.Quest.TheQueenOfTheBanshees.ThirdSealWarlocks) < 1 then + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.ThirdSealWarlocks, 1) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + Game.createMonster('Warlock', {x = 32215, y = 31835, z = 15}, false, true) + Game.createMonster('Warlock', {x = 32215, y = 31840, z = 15}, false, true) + end + return true +end + +thirdSealWarlockTile:aid(25023) +thirdSealWarlockTile:type("stepin") +thirdSealWarlockTile:register() diff --git a/data/scripts/quests/the_queen_of_the_banshees/movement-4-fourth_seal_flame.lua b/data/scripts/quests/the_queen_of_the_banshees/movement-4-fourth_seal_flame.lua new file mode 100644 index 00000000000..2f82096b7af --- /dev/null +++ b/data/scripts/quests/the_queen_of_the_banshees/movement-4-fourth_seal_flame.lua @@ -0,0 +1,36 @@ +local fourthSealFlame = MoveEvent() + +function fourthSealFlame.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.Quest.TheQueenOfTheBanshees.FourthSeal) >= 1 then + player:teleportTo(fromPosition, true) + return true + end + + local bloodPos = {x = 32243, y = 31892, z = 14} + local tile = Tile(bloodPos) + if tile then + local bloodItem = tile:getItemById(2016, 2) + if not bloodItem then + player:teleportTo(fromPosition, true) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + bloodItem:remove() + end + + Position(bloodPos):sendMagicEffect(CONST_ME_MAGIC_RED) + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.FourthSeal, 1) + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.FourthSealDoor, 1) + player:teleportTo({x = 32261, y = 31849, z = 15}) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + return true +end + +fourthSealFlame:type("stepin") +fourthSealFlame:uid(35016) +fourthSealFlame:register() diff --git a/data/scripts/quests/the_queen_of_the_banshees/movement-4-fourth_seal_sacrifice.lua b/data/scripts/quests/the_queen_of_the_banshees/movement-4-fourth_seal_sacrifice.lua new file mode 100644 index 00000000000..dd99e066606 --- /dev/null +++ b/data/scripts/quests/the_queen_of_the_banshees/movement-4-fourth_seal_sacrifice.lua @@ -0,0 +1,16 @@ +local fourthSealSacrifice = MoveEvent() + +function fourthSealSacrifice.onAddItem(moveitem, tileitem, position) + if moveitem.itemid ~= 2016 or moveitem.type ~= 2 then + return true + end + + for i = 1, #fourthSealTable.positions do + Position(fourthSealTable.positions[i]):sendMagicEffect(CONST_ME_DRAWBLOOD) + end + return true +end + +fourthSealSacrifice:type("additem") +fourthSealSacrifice:id(426) +fourthSealSacrifice:register() diff --git a/data/scripts/quests/the_queen_of_the_banshees/movement-5-fifth_seal_flame.lua b/data/scripts/quests/the_queen_of_the_banshees/movement-5-fifth_seal_flame.lua new file mode 100644 index 00000000000..a8e818debd1 --- /dev/null +++ b/data/scripts/quests/the_queen_of_the_banshees/movement-5-fifth_seal_flame.lua @@ -0,0 +1,24 @@ +local fifthSealFlame = MoveEvent() + +function fifthSealFlame.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.Quest.TheQueenOfTheBanshees.FifthSeal) ~= 1 + and player:getStorageValue(Storage.Quest.TheQueenOfTheBanshees.FifthSealTile) == 9 then + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.FifthSealTile, 1) + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.FifthSeal, 1) + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.FifthSealDoor, 1) + player:teleportTo({x = 32268, y = 31856, z = 15}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + player:teleportTo({x = 32185, y = 31939, z = 14}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +fifthSealFlame:uid(35017) +fifthSealFlame:register() diff --git a/data/scripts/quests/the_queen_of_the_banshees/movement-5-fifth_seal_path.lua b/data/scripts/quests/the_queen_of_the_banshees/movement-5-fifth_seal_path.lua new file mode 100644 index 00000000000..4ec4deda551 --- /dev/null +++ b/data/scripts/quests/the_queen_of_the_banshees/movement-5-fifth_seal_path.lua @@ -0,0 +1,24 @@ +local fifthSealTile = MoveEvent() + +function fifthSealTile.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + local storage = Storage.Quest.TheQueenOfTheBanshees.FifthSealTile + local getStorage = player:getStorageValue(storage) + if item.actionid == 25020 then + if getStorage >= 1 and getStorage <= 8 then + player:setStorageValue(storage, getStorage + 1) + end + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + elseif item.actionid == 25021 then + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + player:setStorageValue(storage, 1) + end + return true +end + +fifthSealTile:aid(25020, 25021) +fifthSealTile:register() diff --git a/data/scripts/quests/the_queen_of_the_banshees/movement-6-sixth_seal_flame.lua b/data/scripts/quests/the_queen_of_the_banshees/movement-6-sixth_seal_flame.lua new file mode 100644 index 00000000000..b1f79b96cfd --- /dev/null +++ b/data/scripts/quests/the_queen_of_the_banshees/movement-6-sixth_seal_flame.lua @@ -0,0 +1,35 @@ +local flameSixthSeal = MoveEvent() + +function flameSixthSeal.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + if player:getStorageValue(Storage.Quest.TheQueenOfTheBanshees.SixthSeal) >= 1 then + player:teleportTo(fromPosition) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + + for i = 1, #sixthSealTable.positions do + local tile = Tile(sixthSealTable.positions[i].position) + if tile then + local campfireItem = tile:getItemById(sixthSealTable.positions[i].campfireId) + if not campfireItem then + player:teleportTo(fromPosition) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + end + end + + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.SixthSeal, 1) + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.SixthSealDoor, 1) + player:teleportTo({x = 32261, y = 31856, z = 15}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +flameSixthSeal:uid(35018) +flameSixthSeal:register() diff --git a/data/scripts/quests/the_queen_of_the_banshees/movement-7-last_seal_flame.lua b/data/scripts/quests/the_queen_of_the_banshees/movement-7-last_seal_flame.lua new file mode 100644 index 00000000000..baf65ccb2fe --- /dev/null +++ b/data/scripts/quests/the_queen_of_the_banshees/movement-7-last_seal_flame.lua @@ -0,0 +1,24 @@ +local lastSealFlame = MoveEvent() + +function lastSealFlame.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.FirstSealDoor, -1) + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.SecondSealDoor, -1) + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.ThirdSealDoor, -1) + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.FourthSealDoor, -1) + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.FifthSealDoor, -1) + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.SixthSealDoor, -1) + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.LastSealDoor, -1) + player:setStorageValue(Storage.Quest.TheQueenOfTheBanshees.FinalBattle, 1) + player:teleportTo({x = 32269, y = 31853, z = 15}) + player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end + +lastSealFlame:uid(35019) +lastSealFlame:type("stepin") +lastSealFlame:register() diff --git a/data/scripts/quests/the_rookie_guard/mission02_defence.lua b/data/scripts/quests/the_rookie_guard/mission02_defence.lua new file mode 100644 index 00000000000..99fe6a7f13a --- /dev/null +++ b/data/scripts/quests/the_rookie_guard/mission02_defence.lua @@ -0,0 +1,145 @@ +-- The Rookie Guard Quest - Mission 02: Defence! + +local CATAPULT_ID = { + BAR = 1, + ACADEMY_1 = 2, + ACADEMY_2 = 4, + SHOP = 8 +} + +local missionTiles = { + [50313] = { + states = {1}, + message = "This is the house Vascalir mentioned. You should find a stone pile in the cellar. Use it to get a stone!", + arrowPosition = {x = 32082, y = 32189, z = 7} + }, + [50314] = { + states = {2, 3}, + message = "This is Norma's bar. If you go to the roof, you should find one of the catapults that need to be filled with stones.", + arrowPosition = {x = 32097, y = 32184, z = 7}, + catapults = {CATAPULT_ID.BAR} + }, + [50315] = { + states = {2, 3}, + message = "These stairs lead up to the roof of the academy. Up there you should find TWO of the catapults.", + arrowPosition = {x = 32098, y = 32190, z = 7}, + catapults = {CATAPULT_ID.ACADEMY_1, CATAPULT_ID.ACADEMY_2} + }, + [50316] = { + states = {2, 3}, + message = "This is Obi's shop. Up on his roof you should find one of the catapults Vascalir mentioned.", + arrowPosition = {x = 32104, y = 32205, z = 7}, + catapults = {CATAPULT_ID.SHOP} + } +} + +-- Mission tutorial tiles + +local missionGuide = MoveEvent() + +function missionGuide.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission02) + -- Skip if not was started or finished + if missionState == -1 or missionState >= 4 then + return true + end + local missionTile = missionTiles[item.actionid] + -- Check if the tile has bound a catapult(s) + local hasUsedCatapult = missionTile.catapults ~= nil or false + if hasUsedCatapult then + local catapultsState = player:getStorageValue(Storage.TheRookieGuard.Catapults) + for i = 1, #missionTile.catapults do + -- Check if the catapult was used + hasUsedCatapult = testFlag(catapultsState, missionTile.catapults[i]) + if hasUsedCatapult then + break + end + end + end + -- Check if the tile is active + if table.find(missionTile.states, missionState) and not hasUsedCatapult then + -- Check delayed notifications (message/arrow) + if not isTutorialNotificationDelayed(player) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, missionTile.message) + if missionTile.arrowPosition then + Position(missionTile.arrowPosition):sendMagicEffect(CONST_ME_TUTORIALARROW) + end + end + end + return true +end + +for index, value in pairs(missionTiles) do + missionGuide:aid(index) +end +missionGuide:register() + +-- Stone pile (gather heavy stone) + +local stonePile = Action() + +function stonePile.onUse(player, item, frompos, item2, topos) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission02) + -- Skip if not was started + if missionState == -1 then + return true + end + if missionState <= 3 then + if missionState == 1 then + player:setStorageValue(Storage.TheRookieGuard.Mission02, 2) + end + -- Gather delay + if player:getStorageValue(Storage.TheRookieGuard.StonePileTimer) - os.time() <= 0 then + player:setStorageValue(Storage.TheRookieGuard.StonePileTimer, os.time() + 2 * 60) + player:addItemEx(Game.createItem(13866, 1), true, CONST_SLOT_WHEREEVER) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have to wait a few minutes before you can pick up a new stone.") + end + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You don't need any stones anymore. Rookgaard's defences have been fortified.") + end + return true +end + +stonePile:aid(40005) +stonePile:register() + +local catapults = { + [40006] = CATAPULT_ID.BAR, + [40007] = CATAPULT_ID.ACADEMY_1, + [40008] = CATAPULT_ID.ACADEMY_2, + [40009] = CATAPULT_ID.SHOP +} + +-- Heavy stone (load stone on catapult) + +local heavyStone = Action() + +function heavyStone.onUse(player, item, frompos, item2, topos) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission02) + if missionState >= 2 and missionState <= 3 and catapults[item2.actionid] then + local catapultsState = player:getStorageValue(Storage.TheRookieGuard.Catapults) + local hasUsedCatapult = testFlag(catapultsState, catapults[item2.actionid]) + if not hasUsedCatapult then + if missionState == 2 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You load the heavy stone on the catapult. Now, get another stone and find the remaining catapult.") + elseif missionState == 3 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You loaded the last stone on the catapults. Time to return to Vascalir.") + end + player:setStorageValue(Storage.TheRookieGuard.Mission02, missionState + 1) + player:setStorageValue(Storage.TheRookieGuard.Catapults, catapultsState + catapults[item2.actionid]) + player:addExperience(5, true) + player:removeItem(13866, 1) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have already loaded a stone on this catapult. Look around on other roofs to find the remaining catapults.") + end + end + return true +end + +heavyStone:id(13866) +heavyStone:register() diff --git a/data/scripts/quests/the_rookie_guard/mission03_rational_request.lua b/data/scripts/quests/the_rookie_guard/mission03_rational_request.lua new file mode 100644 index 00000000000..7bd56fbd633 --- /dev/null +++ b/data/scripts/quests/the_rookie_guard/mission03_rational_request.lua @@ -0,0 +1,23 @@ +-- The Rookie Guard Quest - Mission 03: A Rational Request + +-- Mission Kills + +local ratKill = CreatureEvent("VascalirRatKills") + +function ratKill.onKill(player, target) + if target:isPlayer() or target:getMaster() then + return true + end + if not target:getName():lower() == "rat" then + return true + end + if player:getStorageValue(Storage.TheRookieGuard.Mission03) == 1 then + local counter = player:getStorageValue(Storage.TheRookieGuard.RatKills) + if counter < 5 then + player:setStorageValue(Storage.TheRookieGuard.RatKills, counter + 1) + end + end + return true +end + +ratKill:register() diff --git a/data/scripts/quests/the_rookie_guard/mission04_home_brewed.lua b/data/scripts/quests/the_rookie_guard/mission04_home_brewed.lua new file mode 100644 index 00000000000..5994d305558 --- /dev/null +++ b/data/scripts/quests/the_rookie_guard/mission04_home_brewed.lua @@ -0,0 +1,56 @@ +-- The Rookie Guard Quest - Mission 04: Home-Brewed + +local missionTiles = { + [50317] = { + states = 1, + message = "This is not the way to Lily. Follow the road leading to the south-west to find her shop.", + arrowPosition = {x = 32090, y = 32201, z = 7} + }, + [50318] = { + states = 2, + message = "This is not the way to Hyacinth. Follow the path to the north exit of the village.", + arrowPosition = {x = 32090, y = 32190, z = 7} + }, + [50320] = { + states = 2, + message = "This is not the way to Hyacinth. Follow the path to the east to find Hyacinth's little house.", + arrowPosition = {x = 32092, y = 32164, z = 7} + }, + [50322] = { + states = 2, + message = "This is not the way to Hyacinth. Stay on the path a little more to the north to find Hyacinth's little house." + } +} + +-- Mission tutorial tiles + +local missionGuide = MoveEvent() + +function missionGuide.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission04) + -- Skip if not was started or finished + if missionState == -1 or missionState > 2 then + return true + end + local missionTile = missionTiles[item.actionid] + -- Check if the tile is active + if missionTile.states == missionState then + -- Check delayed notifications (message/arrow) + if not isTutorialNotificationDelayed(player) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, missionTile.message) + if missionTile.arrowPosition then + Position(missionTile.arrowPosition):sendMagicEffect(CONST_ME_TUTORIALARROW) + end + end + end + return true +end + +for index, value in pairs(missionTiles) do + missionGuide:aid(index) +end +missionGuide:register() diff --git a/data/scripts/quests/the_rookie_guard/mission05_web_terror.lua b/data/scripts/quests/the_rookie_guard/mission05_web_terror.lua new file mode 100644 index 00000000000..bdcde74d8ce --- /dev/null +++ b/data/scripts/quests/the_rookie_guard/mission05_web_terror.lua @@ -0,0 +1,161 @@ +-- The Rookie Guard Quest - Mission 05: Web of Terror + +local missionTiles = { + [50324] = { + states = {1}, + message = "This is not the way to the tarantula's lair. Head up the little ramp to the southwest.", + arrowPosition = {x = 32090, y = 32147, z = 7} + }, + [50326] = { + states = {1}, + message = "Follow the small path to the north to reach the spider lair.", + arrowPosition = {x = 32067, y = 32132, z = 7} + }, + [50327] = { + states = {1}, + message = "Walk to the west from here to reach the hole leading to the tarantula lair.", + arrowPosition = {x = 32051, y = 32110, z = 7} + }, + [50328] = { + states = {1, 2, 4}, + message = "Remember that you have to aquire a web sample for Vascalir. You should not leave this cave without it.", + arrowPosition = {x = 32003, y = 32109, z = 11}, + walkBack = true + } +} + +-- Mission tutorial tiles + +local missionGuide = MoveEvent() + +function missionGuide.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local state = player:getStorageValue(Storage.TheRookieGuard.Mission05) + -- Skip if not was started or finished + if state == -1 or state == 3 then + return true + end + local missionTile = missionTiles[item.actionid] + -- Check if the tile is active + if table.find(missionTile.states, state) then + -- Check delayed notifications (message/arrow) + if not isTutorialNotificationDelayed(player) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, missionTile.message) + if missionTile.arrowPosition then + Position(missionTile.arrowPosition):sendMagicEffect(CONST_ME_TUTORIALARROW) + end + end + -- Walk back from south to north + if missionTile.walkBack and (fromPosition.y > position.y or fromPosition.y == position.y and fromPosition.x ~= position.x) then + player:teleportTo(fromPosition, true) + end + end + return true +end + +for index, value in pairs(missionTiles) do + missionGuide:aid(index) +end +missionGuide:register() + +-- Spider lair hole + +local spiderLairHole = MoveEvent() + +function spiderLairHole.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission05) + if missionState == -1 or missionState >= 3 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have no business down there.") + player:teleportTo(fromPosition, true) + end + return true +end + +spiderLairHole:uid(25022) +spiderLairHole:register() + +-- Greasy stones + +local greasyStone = Action() + +function greasyStone.onUse(player, item, frompos, item2, topos) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission05) + -- Skip if not was started + if missionState == -1 then + return true + end + if missionState <= 2 or missionState == 4 then + local condition = Condition(CONDITION_INVISIBLE) + condition:setParameter(CONDITION_PARAM_TICKS, 120000) + player:addCondition(condition) + -- Check delayed notifications (message/arrow) + if not isTutorialNotificationDelayed(player) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You rub the strange grease on your body. The spider queen will not be able to smell you for about 2 minutes. Hurry!") + Position({x = 32018, y = 32098, z = 11}):sendMagicEffect(CONST_ME_TUTORIALARROW) + end + player:setStorageValue(Storage.TheRookieGuard.Mission05, 2) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You already retrieved some of the spider queen's web. No need to go back down there.") + end + return true +end + +greasyStone:id(13868) +greasyStone:register() + +-- Spider queen chamber hole + +local spiderQueenChamberHole = MoveEvent() + +function spiderQueenChamberHole.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission05) + if missionState == 1 then + -- Check delayed notifications (message/arrow) + if not isTutorialNotificationDelayed(player) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Don't enter the lair without a protective grease. Use one of the stones to the north to become invisible to her.") + Position({x = 32014, y = 32096, z = 11}):sendMagicEffect(CONST_ME_TUTORIALARROW) + end + player:teleportTo(fromPosition, true) + elseif missionState == 3 then + -- Check delayed notifications (message/arrow) + if not isTutorialNotificationDelayed(player) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You already have the spider queen's web. You should go back to Vascalir and not take any further risks.") + end + player:teleportTo(fromPosition, true) + end + return true +end + +spiderQueenChamberHole:uid(25023) +spiderQueenChamberHole:register() + +-- Spider webs + +local spiderWeb = Action() + +function spiderWeb.onUse(player, item, frompos, item2, topos) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission05) + -- Skip if not was started + if missionState == -1 then + return true + end + if missionState == 2 or missionState == 4 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You retrieved some of the spider queen's web. Hurry back before she can smell you again!") + player:setStorageValue(Storage.TheRookieGuard.Mission05, 3) + end + return true +end + +spiderWeb:aid(40010) +spiderWeb:register() diff --git a/data/scripts/quests/the_rookie_guard/mission06_run_like_wolf.lua b/data/scripts/quests/the_rookie_guard/mission06_run_like_wolf.lua new file mode 100644 index 00000000000..8f459dde375 --- /dev/null +++ b/data/scripts/quests/the_rookie_guard/mission06_run_like_wolf.lua @@ -0,0 +1,239 @@ +-- The Rookie Guard Quest - Mission 06: Run Like a Wolf + +local missionTiles = { + [50329] = { + state = 2, + message = "Follow the north-eastern path into the forest. Beware of wolves!", + arrowPosition = {x = 32109, y = 32166, z = 7} + }, + [50330] = { + state = 2, + message = "This is not the way into the wolf forest. Stay on the southern path leading to the north-east!" + }, + [50331] = { + state = 2, + message = "This is not the way into the wolf forest. Stay on the southern path leading to the north-east!" + }, + [50332] = { + state = 2, + message = "This hole leads into the wolves' den. Only enter if you have full health and food - this might be dangerous.", + arrowPosition = {x = 32138, y = 32132, z = 7} + }, + [50333] = { + state = 3, + message = "It seems plans changed. It's up to you now to find a dead war wolf and use the skinning knife on it to get some leather." + } +} + +-- Mission tutorial tiles + +local missionGuide = MoveEvent() + +function missionGuide.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission06) + -- Skip if not was started or finished + if missionState == -1 or missionState >= 4 then + return true + end + local tile = missionTiles[item.actionid] + -- Check if the tile is active + if missionState == tile.state then + -- Check delayed notifications (message/arrow) + if not isTutorialNotificationDelayed(player) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, tile.message) + if tile.arrowPosition then + Position(tile.arrowPosition):sendMagicEffect(CONST_ME_TUTORIALARROW) + end + end + end + return true +end + +for index, value in pairs(missionTiles) do + missionGuide:aid(index) +end +missionGuide:register() + +-- War wolf den hole + +local warWolfDenHole = MoveEvent() + +function warWolfDenHole.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission06) + if missionState == -1 or missionState >= 4 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have no business down there.") + player:teleportTo(fromPosition, true) + end + return true +end + +warWolfDenHole:uid(25024) +warWolfDenHole:register() + +local specialMissionTiles = { + [25025] = { + state = 2, + message = "Well.. that seems to be the poacher. Dead. Check his body - maybe he still has something that you can use.", + arrowPosition = {x = 32135, y = 32133, z = 8}, + newState = 3 + }, + [25026] = { + state = 3, + message = "There is a dead war wolf! Use the knife, and then use it on its body to get some leather - but quickly!", + arrowPosition = {x = 32108, y = 32132, z = 11} + }, + [25027] = { + state = 5, + message = "You reached the exit in time! Phew.. back to Tom.", + newState = 6 + } +} + +-- War wolf den special tiles + +local warWolfDenTiles = MoveEvent() + +function warWolfDenTiles.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission06) + if missionState == -1 then + return true + end + local missionTile = specialMissionTiles[item.uid] + -- Check if the tile is active + if missionState == missionTile.state then + -- Check delayed notifications (message/arrow) + if not isTutorialNotificationDelayed(player) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, missionTile.message) + if missionTile.arrowPosition then + Position(missionTile.arrowPosition):sendMagicEffect(CONST_ME_TUTORIALARROW) + end + end + if missionTile.newState then + player:setStorageValue(Storage.TheRookieGuard.Mission06, missionTile.newState) + end + end + return true +end + +for index, value in pairs(specialMissionTiles) do + warWolfDenTiles:uid(index) +end +warWolfDenTiles:register() + +-- War wolf den boost tiles + +local function teleportBack(uid) + local player = Player(uid) + if player and player:getStorageValue(Storage.TheRookieGuard.Mission06) == 5 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Oh no... you were too slow and the wolves caught up with you. You may try again.") + player:setStorageValue(Storage.TheRookieGuard.Mission06, 4) + player:teleportTo({x = 32109, y = 32131, z = 11}) + end +end + +local warWolfDenBoostTiles = MoveEvent() + +function warWolfDenBoostTiles.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission06) + if missionState == 4 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "RUUUUUUUUUUUUUUUUUN!") + player:setStorageValue(Storage.TheRookieGuard.Mission06, 5) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + local conditionHaste = Condition(CONDITION_HASTE) + conditionHaste:setParameter(CONDITION_PARAM_TICKS, 25000) + conditionHaste:setFormula(0.3, -24, 0.3, -24) + player:addCondition(conditionHaste) + addEvent(teleportBack, 25000, player:getId()) + end + return true +end + +warWolfDenBoostTiles:aid(50334) +warWolfDenBoostTiles:register() + +-- Poacher corpse (gather skinning knife) + +local poacherCorpse = Action() + +function poacherCorpse.onUse(player, item, frompos, item2, topos) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission06) + -- Skip if not was started + if missionState == -1 then + return true + end + if missionState == 3 then + local corpseState = player:getStorageValue(Storage.TheRookieGuard.PoacherCorpse) + if corpseState == -1 then + local reward = Game.createItem(13828, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found " .. reward:getArticle() .. " " .. reward:getName() .. ".") + player:setStorageValue(Storage.TheRookieGuard.PoacherCorpse, 1) + player:addItemEx(reward, true, CONST_SLOT_WHEREEVER) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The " .. item:getName() .. " is empty.") + end + end + return true +end + +poacherCorpse:uid(40044) +poacherCorpse:register() + +-- Skinning knife (skinning dead war wolf) + +local skinningKnife = Action() + +function skinningKnife.onUse(player, item, frompos, item2, topos) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission06) + if missionState == 3 and item2.uid == 40045 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You got the war wolf leather - but you hear a scary howl behind you. Time to get out of here - FAST!") + player:setStorageValue(Storage.TheRookieGuard.Mission06, 4) + player:addExperience(50, true) + player:removeItem(13828, 1) + player:addItemEx(Game.createItem(13879, 1), true, CONST_SLOT_WHEREEVER) + end + return true +end + +skinningKnife:id(13828) +skinningKnife:register() + +-- War wolf den chest (Small health potion) + +local warWolfDenChest = Action() + +function warWolfDenChest.onUse(player, item, frompos, item2, topos) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission06) + -- Skip if not was started + if missionState == -1 then + return true + end + local chestState = player:getStorageValue(Storage.TheRookieGuard.WarWolfDenChest) + if chestState == -1 then + local reward = Game.createItem(8704, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found " .. reward:getArticle() .. " " .. reward:getName() .. ".") + player:setStorageValue(Storage.TheRookieGuard.WarWolfDenChest, 1) + player:addItemEx(reward, true, CONST_SLOT_WHEREEVER) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The " .. item:getName() .. " is empty.") + end + return true +end + +warWolfDenChest:uid(40076) +warWolfDenChest:register() diff --git a/data/scripts/quests/the_rookie_guard/mission07_attack.lua b/data/scripts/quests/the_rookie_guard/mission07_attack.lua new file mode 100644 index 00000000000..9fa8f4aa918 --- /dev/null +++ b/data/scripts/quests/the_rookie_guard/mission07_attack.lua @@ -0,0 +1,159 @@ +-- The Rookie Guard Quest - Mission 07: Attack! + +local missionTiles = { + [50337] = { + message = "Go down the stairs to reach the vault. It smells like fire down there. Make sure you are healthy!", + arrowPosition = {x = 32089, y = 32154, z = 9} + }, + [50338] = { + message = "The vault is on fire! There is almost no air in here. You don't have much time to find the book. Hurry!" + }, + [50340] = { + message = "This must be the chest with the book - but it's covered in flames!", + arrowPosition = {x = 32083, y = 32141, z = 10} + }, + [50341] = { + message = "Right-click on the grey rune on the table and then left-click on the fire! You can't take the rune, but it works.", + arrowPosition = {x = 32082, y = 32143, z = 10} + } +} + +-- Mission tutorial tiles + +local missionGuide = MoveEvent() + +function missionGuide.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission07) + -- Skip if not was started or finished + if missionState == -1 or missionState == 2 then + return true + end + local missionTile = missionTiles[item.actionid] + local libraryChestState = player:getStorageValue(Storage.TheRookieGuard.LibraryChest) + -- Check if the tile is active + if missionState == 1 and libraryChestState == -1 then + -- Check delayed notifications (message/arrow) + if not isTutorialNotificationDelayed(player) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, missionTile.message) + if missionTile.arrowPosition then + Position(missionTile.arrowPosition):sendMagicEffect(CONST_ME_TUTORIALARROW) + end + end + end + return true +end + +for index, value in pairs(missionTiles) do + missionGuide:aid(index) +end +missionGuide:register() + +-- Cough inside library vault + +local libraryVaultSteps = MoveEvent() + +function libraryVaultSteps.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission07) + -- Skip if not was started or finished + if missionState == -1 or missionState == 2 then + return true + end + if math.random(100) <= 20 then + player:say("", TALKTYPE_MONSTER_SAY, false, player, position) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + player:addHealth(-1, COMBAT_PHYSICALDAMAGE) + local health, maxHealth = player:getHealth(), player:getMaxHealth() + local coughTolerance = (health / maxHealth) * 100 + if health <= (maxHealth / 3) or math.random(100) <= (100 - coughTolerance) then + player:teleportTo({x = 32089, y = 32152, z = 9}) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You're coughing so badly that you had to return upstairs. Take a few deep breaths and try again.") + player:addHealth((maxHealth - health), COMBAT_HEALING) + end + end + return true +end + +libraryVaultSteps:aid(50339) +libraryVaultSteps:register() + +-- Fire fields (walk back on big fire fields) + +local fireFields = MoveEvent() + +function fireFields.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + if item.itemid == 13882 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "This fire is much too hot to walk through it. Use the destroy field rune on the fire to weaken the flames!") + player:teleportTo(fromPosition, true) + end + return true +end + +fireFields:aid(40011) +fireFields:register() + +-- Destroy field rune (destroy fire fields) + +local function restoreFirefield(position) + local tile = Tile(position) + if tile then + local item = tile:getItemById(13883) + if item then + item:transform(13882, 1) + end + end +end + +local destroyFieldRune = Action() + +function destroyFieldRune.onUse(player, item, frompos, item2, topos) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission07) + if missionState == 1 and item2.itemid == 13882 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Fire in this stadium can be crossed without taking damage. Open the chest and get out of here!") + item2:getPosition():sendMagicEffect(CONST_ME_POFF) + item2:transform(13883, 1) + addEvent(restoreFirefield, 25000, item2:getPosition()) + end + return true +end + +destroyFieldRune:uid(40046) +destroyFieldRune:register() + +-- Treasure chest (gather orc language book) + +local treasureChest = Action() + +function treasureChest.onUse(player, item, frompos, item2, topos) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission07) + -- Skip if not was started + if missionState == -1 then + return true + end + if missionState == 1 then + local libraryChestState = player:getStorageValue(Storage.TheRookieGuard.LibraryChest) + if libraryChestState == -1 then + local reward = Game.createItem(13831, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found " .. reward:getArticle() .. " " .. reward:getName() .. ".") + player:setStorageValue(Storage.TheRookieGuard.LibraryChest, 1) + player:addItemEx(reward, true, CONST_SLOT_WHEREEVER) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The " .. item:getName() .. " is empty.") + end + end + return true +end + +treasureChest:uid(40047) +treasureChest:register() diff --git a/data/scripts/quests/the_rookie_guard/mission09_rock_troll.lua b/data/scripts/quests/the_rookie_guard/mission09_rock_troll.lua new file mode 100644 index 00000000000..58878ee123c --- /dev/null +++ b/data/scripts/quests/the_rookie_guard/mission09_rock_troll.lua @@ -0,0 +1,173 @@ +-- The Rookie Guard Quest - Mission 09: Rock 'n Troll + +local missionTiles = { + [50342] = { + state = 1, + message = "This is not the way to the troll caves. Go back down the stairs and walk north to find them.", + arrowPosition = {x = 32089, y = 32147, z = 6} + }, + [50343] = { + state = 1, + message = "This is not the way to the troll caves. Go back down the stairs and walk north to find them.", + arrowPosition = {x = 32094, y = 32137, z = 7} + }, + [50344] = { + state = 1, + newState = 2, + message = "You've reached the newly dug troll tunnel. Take what you find in this chest and use it to bring down all support beams!", + arrowPosition = {x = 32059, y = 32132, z = 10} + }, + [50345] = { + state = 7, + newState = 8, + message = "You hear a crumbling below you. The tunnel collapsed. Vascalir will be pleased to hear about that." + } +} + +-- Mission tutorial tiles + +local missionGuide = MoveEvent() + +function missionGuide.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission09) + -- Skip if not was started or finished + if missionState == -1 or missionState > 7 then + return true + end + local missionTile = missionTiles[item.actionid] + -- Check if the tile is active + if missionState == missionTile.state then + -- Check delayed notifications (message/arrow) + if not isTutorialNotificationDelayed(player) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, missionTile.message) + if missionTile.arrowPosition then + Position(missionTile.arrowPosition):sendMagicEffect(CONST_ME_TUTORIALARROW) + end + end + if missionTile.newState then + player:setStorageValue(Storage.TheRookieGuard.Mission09, missionTile.newState) + end + end + return true +end + +for index, value in pairs(missionTiles) do + missionGuide:aid(index) +end +missionGuide:register() + +-- Troll caves dug tunnel hole + +local tunnelHole = MoveEvent() + +function tunnelHole.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission09) + if missionState == -1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have no business down there.") + player:teleportTo(fromPosition, true) + elseif missionState >= 7 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The cave has collapsed. It's not safe to go down there anymore.") + player:teleportTo(fromPosition, true) + end + return true +end + +tunnelHole:uid(25028) +tunnelHole:register() + +-- Trunk chests (gather leather legs and pick) + +local CHEST_ID = { + LEATHER_LEGS = 1, + PICK = 2 +} + +local chests = { + [40048] = { + id = CHEST_ID.LEATHER_LEGS, + itemId = 2649 + }, + [40049] = { + id = CHEST_ID.PICK, + itemId = 2553 + } +} + +local trunkChest = Action() + +function trunkChest.onUse(player, item, frompos, item2, topos) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission09) + -- Skip if not was started + if missionState == -1 then + return true + end + if missionState >= 2 then + local chest = chests[item.uid] + local chestsState = player:getStorageValue(Storage.TheRookieGuard.TrollChests) + local hasOpenedChest = testFlag(chestsState, chest.id) + if not hasOpenedChest then + local reward = Game.createItem(chest.itemId, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found " .. reward:getArticle() .. " " .. reward:getName() .. ".") + player:setStorageValue(Storage.TheRookieGuard.TrollChests, chestsState + chest.id) + player:addItemEx(reward, true, CONST_SLOT_WHEREEVER) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The " .. item:getName() .. " is empty.") + end + end + return true +end + +trunkChest:uid(40048, 40049) +trunkChest:register() + +-- Pick (use pick on pillars) + +local PILLAR_ID = { + BOTOM_RIGHT = 1, + BOTTOM_LEFT = 2, + TOP_LEFT = 4, + TOP_CENTER = 8, + TOP_RIGHT = 16 +} + +local tunnelPillars = { + [40050] = PILLAR_ID.BOTOM_RIGHT, + [40051] = PILLAR_ID.BOTTOM_LEFT, + [40052] = PILLAR_ID.TOP_LEFT, + [40053] = PILLAR_ID.TOP_CENTER, + [40054] = PILLAR_ID.TOP_RIGHT +} + +-- /data/scripts/lib/register_actions.lua (onUsePick) +function onUsePickAtTunnelPillar(player, item, fromPosition, item2, toPosition) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission09) + local pillarId = tunnelPillars[item2.uid] + if missionState >= 2 and missionState <= 7 and pillarId then + local pillarsState = player:getStorageValue(Storage.TheRookieGuard.TunnelPillars) + local hasDamagedPillar = testFlag(pillarsState, pillarId) + if not hasDamagedPillar then + local newMissionState = missionState + 1 + if table.find({3, 4, 5, 6}, newMissionState) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "That should weaken the beam enough to make it collapse soon.") + elseif newMissionState == 7 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "This was the last beam. Now, get out of here before the cave collapses!") + player:addExperience(100, true) + end + player:say("", TALKTYPE_MONSTER_SAY, false, player, toPosition) + toPosition:sendMagicEffect(CONST_ME_HITAREA) + player:setStorageValue(Storage.TheRookieGuard.Mission09, newMissionState) + player:setStorageValue(Storage.TheRookieGuard.TunnelPillars, pillarsState + pillarId) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You've already weakened this beam. Better leave it alone now so it won't collapse before you are out of here.") + end + end + return true +end diff --git a/data/scripts/quests/the_rookie_guard/mission10_tomb_raiding.lua b/data/scripts/quests/the_rookie_guard/mission10_tomb_raiding.lua new file mode 100644 index 00000000000..360afec2195 --- /dev/null +++ b/data/scripts/quests/the_rookie_guard/mission10_tomb_raiding.lua @@ -0,0 +1,155 @@ +-- The Rookie Guard Quest - Mission 10: Tomb Raiding + +local missionTiles = { + [50346] = { + { + sarcophagus = -1, + message = "This is not the way to the crypt. Go south-west to reach the graveyard.", + arrowPosition = {x = 32124, y = 32177, z = 7} + } + }, + [50347] = { + { + sarcophagus = -1, + message = "This is the crypt Vascalir was talking about. Explore it and search the coffins - one of them must hold a nice fleshy bone.", + arrowPosition = {x = 32131, y = 32201, z = 7} + } + }, + [50348] = { + { + sarcophagus = -1, + message = "This door seems to lead deeper into the crypt. Go downstairs and look for a special coffin. Beware of the walking dead!", + arrowPosition = {x = 32147, y = 32185, z = 9} + } + }, + [50349] = { + { + sarcophagus = -1, + message = "This sarcophagus seems special. Sarcophagi are said to conserve meat longer than normal coffins - maybe you get lucky.", + arrowPosition = {x = 32145, y = 32204, z = 10} + }, + { + sarcophagus = 1, + message = "Now that you have a fleshy bone, it's time to find out what Vascalir wanted with it.", + arrowPosition = {x = 32136, y = 32202, z = 10} + } + } +} + +-- Mission tutorial tiles + +local missionGuide = MoveEvent() + +function missionGuide.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission10) + -- Skip if not was started or finished + if missionState == -1 or missionState > 1 then + return true + end + local missionTile = missionTiles[item.actionid] + local sarcophagusState = player:getStorageValue(Storage.TheRookieGuard.Sarcophagus) + -- Check mission state cases for the tile + for i = 1, #missionTile do + -- Check if the tile is active + if missionState == 1 and sarcophagusState == missionTile[i].sarcophagus then + -- Check delayed notifications (message/arrow) + if not isTutorialNotificationDelayed(player) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, missionTile[i].message) + if missionTile[i].arrowPosition then + Position(missionTile[i].arrowPosition):sendMagicEffect(CONST_ME_TUTORIALARROW) + end + end + break + end + end + return true +end + +for index, value in pairs(missionTiles) do + missionGuide:aid(index) +end +missionGuide:register() + +-- Sarcophagus (gather fleshy bone) + +local sarcophagus = Action() + +function sarcophagus.onUse(player, item, frompos, item2, topos) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission10) + -- Skip if not was started + if missionState == -1 then + return true + end + if missionState >= 1 then + local sarcophagusState = player:getStorageValue(Storage.TheRookieGuard.Sarcophagus) + if sarcophagusState == -1 then + local reward = Game.createItem(13830, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found " .. reward:getArticle() .. " " .. reward:getName() .. ".") + player:setStorageValue(Storage.TheRookieGuard.Sarcophagus, 1) + player:addItemEx(reward, true, CONST_SLOT_WHEREEVER) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The " .. item:getName() .. " is empty.") + end + end + return true +end + +sarcophagus:uid(40055) +sarcophagus:register() + +-- Unholy crypt chests + +local CHEST_ID = { + BOX = 1, + COFFIN = 2 +} + +local chests = { + [40077] = { + id = CHEST_ID.BOX, + item = { + id = 2789, + amount = 5 + } + }, + [40078] = { + id = CHEST_ID.COFFIN, + item = { + id = 8704, + amount = 1 + } + } +} + +local unholyCryptChests = Action() + +function unholyCryptChests.onUse(player, item, frompos, item2, topos) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission10) + -- Skip if not was started + if missionState == -1 then + return true + end + local chest = chests[item.uid] + local chestsState = player:getStorageValue(Storage.TheRookieGuard.UnholyCryptChests) + local hasOpenedChest = testFlag(chestsState, chest.id) + if not hasOpenedChest then + local reward = Game.createItem(chest.item.id, chest.item.amount) + if reward:getCount() == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found " .. reward:getArticle() .. " " .. reward:getName() .. ".") + elseif reward:getCount() > 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found " .. reward:getCount() .. " " .. reward:getPluralName() .. ".") + end + player:setStorageValue(Storage.TheRookieGuard.UnholyCryptChests, chestsState + chest.id) + player:addItemEx(reward, true, CONST_SLOT_WHEREEVER) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The " .. item:getName() .. " is empty.") + end + return true +end + +unholyCryptChests:uid(40077, 40078) +unholyCryptChests:register() diff --git a/data/scripts/quests/the_rookie_guard/mission11_sweet_poison.lua b/data/scripts/quests/the_rookie_guard/mission11_sweet_poison.lua new file mode 100644 index 00000000000..5ce6e22c3fa --- /dev/null +++ b/data/scripts/quests/the_rookie_guard/mission11_sweet_poison.lua @@ -0,0 +1,68 @@ +-- The Rookie Guard Quest - Mission 11: Sweet Poison + +local missionTiles = { + [50350] = { + state = 1, + message = "Cross the bridge to the west and go south to reach the wasps' nest.", + arrowPosition = {x = 32090, y = 32147, z = 7} + }, + [50353] = { + state = 1, + newState = 2, + message = "You've found the wasp tower. Kill a wasp and use the flask you got from Vascalir on its corpse to retrieve some of its poison." + } +} + +-- Mission tutorial tiles + +local missionGuide = MoveEvent() + +function missionGuide.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission11) + -- Skip if not was started or finished + if missionState == -1 or missionState > 1 then + return true + end + local missionTile = missionTiles[item.actionid] + -- Check if the tile is active + if missionState == missionTile.state then + -- Check delayed notifications (message/arrow) + if not isTutorialNotificationDelayed(player) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, missionTile.message) + if missionTile.arrowPosition then + Position(missionTile.arrowPosition):sendMagicEffect(CONST_ME_TUTORIALARROW) + end + end + if missionTile.newState then + player:setStorageValue(Storage.TheRookieGuard.Mission11, missionTile.newState) + end + end + return true +end + +for index, value in pairs(missionTiles) do + missionGuide:aid(index) +end +missionGuide:register() + +-- Special flask (gather poison on wasp corpse) + +local specialFlask = Action() + +function specialFlask.onUse(player, item, frompos, item2, topos) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission11) + if missionState == 2 and item2.itemid == 5989 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You carefully gather some of the wasp poison. Bring it back to Vascalir.") + player:setStorageValue(Storage.TheRookieGuard.Mission11, 3) + player:removeItem(13924, 1) + player:addItemEx(Game.createItem(13923, 1), true, CONST_SLOT_WHEREEVER) + end + return true +end + +specialFlask:id(13924) +specialFlask:register() diff --git a/data/scripts/quests/the_rookie_guard/mission12_into_fortress.lua b/data/scripts/quests/the_rookie_guard/mission12_into_fortress.lua new file mode 100644 index 00000000000..2cb17e58fbe --- /dev/null +++ b/data/scripts/quests/the_rookie_guard/mission12_into_fortress.lua @@ -0,0 +1,788 @@ +-- The Rookie Guard Quest - Mission 12: Into The Fortress + +local missionTiles = { + [50354] = { + { + states = {1}, + extra = { + storage = Storage.TheRookieGuard.AcademyChest, + state = -1 + }, + message = "This chest should contain everything you need to infiltrate the fortress.", + arrowPosition = {x = 32109, y = 32187, z = 8} + }, + { + states = {1}, + extra = { + storage = Storage.TheRookieGuard.AcademyChest, + state = 1 + }, + message = "Those items should be what you need to infiltrate the fortress. Go back near the wasps' nest and walk south from there.", + newState = 2 + } + }, + [50355] = { + { + states = {2}, + message = "This orc has turned his back to you and is obviously taking a break. Use the rolling pin on him to knock him out!" + } + }, + [50356] = { + { + states = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + condition = function(player) + return player:getOutfit().lookType ~= 5 + end, + message = "This guard will definitely not let you pass. Sneak around the fortress to find a way to disguise yourself.", + walkTo = {x = 1, y = 0, z = 0} + }, + { + states = {4}, + condition = function(player) + return player:getOutfit().lookType == 5 + end, + message = "You sneaked into the orc fortress. Careful now, don't go outside again.", + newState = 5, + walkTo = {x = -1, y = 0, z = 0} + } + }, + [50357] = { + { + states = {5}, + message = "You cannot hope to sneak past this guard. Maybe some distraction would help? You could try using the fleshy bone on him..." + } + }, + [50358] = { + { + states = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, + condition = function(player) + return Tile(Position(31977, 32150, 7)):getItemById(13931) ~= nil + end, + message = "You cannot hope to sneak past this guard. Maybe some distraction would help? You could try using the fleshy bone on him...", + teleportTo = {x = 31977, y = 32155, z = 7} + } + }, + [50359] = { + { + states = {6}, + newState = 7, + message = "You've managed to reach the interior of the orc fortress. Be prepared for a fight - and look for the soup cauldron." + } + }, + [50360] = { + { + states = {7}, + message = "You're apperently in the kitchen. If you find a big cauldron, use the flask of wasp poison on it." + } + }, + [50361] = { + { + states = {7}, + message = "You haven't used the poison on Kraknaknork's soup yet. Don't try to fight him before that - or he will definitely kill you.", + walkTo = {x = 0, y = -1, z = 0} + } + }, + [50362] = { + { + states = {8}, + message = "Got your tarantula trap ready? You might need to use it soon..." + } + }, + [50363] = { + { + states = {11}, + message = "Beware... you're approaching Kraknaknork's room. Once you enter, you have only 5 minutes to kill him before he throws you out." + } + } +} + +-- Mission tutorial tiles + +local missionGuide = MoveEvent() + +function missionGuide.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission12) + -- Skip if not was started or finished + if missionState == -1 then + return true + end + local tile = missionTiles[item.actionid] + for i = 1, #tile do + local extraState = tile[i].extra == nil or player:getStorageValue(tile[i].extra.storage) == tile[i].extra.state + local condition = tile[i].condition == nil or tile[i].condition(player) + -- Check if the tile is active + if table.find(tile[i].states, missionState) and extraState and condition then + -- Check delayed notifications (message/arrow) + if not isTutorialNotificationDelayed(player) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, tile[i].message) + if tile[i].arrowPosition then + Position(tile[i].arrowPosition):sendMagicEffect(CONST_ME_TUTORIALARROW) + end + end + -- Update state + if tile[i].newState then + player:setStorageValue(Storage.TheRookieGuard.Mission12, tile[i].newState) + end + -- Walk to relative position + if tile[i].walkTo then + local walkTo = tile[i].walkTo + player:teleportTo(Position(position.x + walkTo.x, position.y + walkTo.y, position.z + walkTo.z), true) + end + -- Teleport to position + if tile[i].teleportTo then + player:teleportTo(Position(tile[i].teleportTo), false) + end + break + end + end + return true +end + +for index, value in pairs(missionTiles) do + missionGuide:aid(index) +end +missionGuide:register() + +-- Treasure chest (gather final mission items) + +local reward = { + containerId = 1987, + itemIds = { + 13927, + 13928, + 13923, + 13830 + } +} + +local treasureChest = Action() + +function treasureChest.onUse(player, item, frompos, item2, topos) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission12) + -- Skip if not was started + if missionState == -1 then + return true + end + if missionState >= 1 and missionState <= 13 then + local chestState = player:getStorageValue(Storage.TheRookieGuard.AcademyChest) + local chestTimer = player:getStorageValue(Storage.TheRookieGuard.AcademyChestTimer) + if chestState == -1 or chestTimer - os.time() <= 0 then + local container = Game.createItem(reward.containerId) + for i = #reward.itemIds, 1, -1 do + container:addItem(reward.itemIds[i], 1) + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found " .. container:getArticle() .. " " .. container:getName() .. ".") + player:setStorageValue(Storage.TheRookieGuard.AcademyChest, 1) + player:setStorageValue(Storage.TheRookieGuard.AcademyChestTimer, os.time() + 24 * 60 * 60) + player:addItemEx(container, true, CONST_SLOT_WHEREEVER) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The " .. item:getName() .. " is empty.") + end + end + return true +end + +treasureChest:uid(40056) +treasureChest:register() + +-- Rolling pin (Knock out peeing orc) + +local function orcRecovery(position) + local tile = Tile(position) + if tile then + local item = tile:getItemById(13930) + if item then + item:transform(13929, 1) + end + end +end + +local rollingPin = Action() + +function rollingPin.onUse(player, item, frompos, item2, topos) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission12) + if missionState >= 2 and missionState <= 13 and item2.itemid == 13929 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You knock the unsuspicious orc unconscious. Use him to disguise yourself as orc!") + if missionState == 2 then + player:setStorageValue(Storage.TheRookieGuard.Mission12, 3) + player:addExperience(50, true) + end + item2:transform(13930, 1) + addEvent(orcRecovery, 60000, item2:getPosition()) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have no reason to do such an insidious thing.") + end + return true +end + +rollingPin:id(13928) +rollingPin:register() + +-- Unconscious orc (Disguise like orc) + +local unconsciousOrc = Action() + +function unconsciousOrc.onUse(player, item, frompos, item2, topos) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission12) + if missionState >= 3 and missionState <= 13 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You look almost like an orc. It won't fool all orcs, but the stupid guardsman in front of the fortress should fall for it.") + if missionState == 3 then + player:setStorageValue(Storage.TheRookieGuard.Mission12, 4) + end + local conditionOutfit = Condition(CONDITION_OUTFIT) + conditionOutfit:setTicks(300000) + conditionOutfit:setOutfit({lookType = 5}) + player:addCondition(conditionOutfit) + end + return true +end + +unconsciousOrc:id(13930) +unconsciousOrc:register() + +-- Fleshy bone (Distract elite orc guard) + +local monstersList = { + {name = "Running Elite Orc Guard", amount = 1}, + {name = "Wild Dog", amount = 8} +} +local monsters = {} + +local function eliteOrcGuardRecovery(position) + local spectators = Game.getSpectators(position, false, true, 2, 2, 2, 2) + if #spectators > 0 then + local hidePosition = Position(31977, 32154, 7) + for i = 1, #spectators do + spectators[i]:teleportTo(hidePosition, false) + end + end + if monsters then + for i = 1, #monsters do + monsters[i]:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + monsters[i]:remove() + end + end + Game.createItem(13931, 1, position) +end + +local fleshyBone = Action() + +function fleshyBone.onUse(player, item, frompos, item2, topos) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission12) + if missionState >= 5 and item2.itemid == 13931 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "This should be enough distraction for you to sneak into the fortress! Hurry up!") + if missionState == 5 then + player:setStorageValue(Storage.TheRookieGuard.Mission12, 6) + player:addExperience(50, true) + end + local position = item2:getPosition() + local spawnPosition = Position(position.x, position.y + 1, position.z) + item2:remove() + monsters = {} + for i = 1, #monstersList do + if i == 2 then + spawnPosition.y = spawnPosition.y + 2 + end + for j = 1, monstersList[i].amount do + monsters[#monsters + 1] = Game.createMonster(monstersList[i].name, spawnPosition) + end + end + position:sendMagicEffect(CONST_ME_TELEPORT) + addEvent(eliteOrcGuardRecovery, 120000, position) + end + return true +end + +fleshyBone:id(13830) +fleshyBone:register() + +-- Wasp poison flask (Poison cauldron) + +local poisonFlask = Action() + +function poisonFlask.onUse(player, item, frompos, item2, topos) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission12) + if missionState == 7 and item2.actionid == 40012 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You poisoned Kraknaknork's soup. This should weaken him immensely. Time to find his room.") + player:setStorageValue(Storage.TheRookieGuard.Mission12, 8) + player:removeItem(13923, 1) + player:addExperience(50, true) + end + return true +end + +poisonFlask:id(13923) +poisonFlask:register() + +-- Tarantula trap (Slow furious orc berserker) + +local taranturaTrap = Action() + +function taranturaTrap.onUse(player, item, frompos, item2, topos) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission12) + target = Tile(topos):getTopCreature() + if missionState >= 8 and target:getName() == "Furious Orc Berserker" then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The berserker can't catch you anymore - but only for 20 seconds. You need to lure him away from the teleporter!") + if missionState == 8 then + player:setStorageValue(Storage.TheRookieGuard.Mission12, 9) + end + local conditionSlow = Condition(CONDITION_PARALYZE) + conditionSlow:setParameter(CONDITION_PARAM_TICKS, 20000) + conditionSlow:setFormula(-0.3, 0, -0.45, 0) + target:addCondition(conditionSlow) + end + return true +end + +taranturaTrap:id(13927) +taranturaTrap:register() + +-- Kraknaknork lair teleport + +local bossLairTeleport = MoveEvent() + +function bossLairTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission12) + -- Skip if not was started or finished + if missionState == -1 then + return true + end + if missionState >= 8 then + local spectators = Game.getSpectators(position, false, false, 2, 2, 2, 2) + for i = 1, #spectators do + if not spectators[i]:isPlayer() and spectators[i]:getName() == "Furious Orc Berserker" then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "As long as the orc berserker is near that teleporter, you can't enter.") + player:teleportTo(fromPosition, true) + position:sendMagicEffect(CONST_ME_TELEPORT) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + return true + end + end + if missionState == 9 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You're entering Kraknaknork's lair.") + player:setStorageValue(Storage.TheRookieGuard.Mission12, 10) + end + local toPosition = Position(31980, 32173, 10) + player:teleportTo(toPosition, false) + position:sendMagicEffect(CONST_ME_TELEPORT) + toPosition:sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +bossLairTeleport:uid(40057) +bossLairTeleport:register() + +-- Energy barriers + +local energyBarriers = { + [40058] = { + position = {x = 31974, y = 32174, z = 10}, + teleportTo = {x = 31977, y = 32174, z = 10}, + message = "Kraknaknork maintains strong energy barriers. There is only one way to disable them." + }, + [40059] = { + position = {x = 31962, y = 32174, z = 10}, + teleportTo = {x = 31964, y = 32174, z = 10} + }, + [40060] = { + position = {x = 31960, y = 32184, z = 10}, + teleportTo = {x = 31958, y = 32184, z = 10} + }, + [40061] = { + position = {x = 31953, y = 32187, z = 10}, + teleportTo = {x = 31955, y = 32187, z = 10} + }, + [40062] = { + position = {x = 31972, y = 32183, z = 10}, + teleportTo = {x = 31970, y = 32183, z = 10} + }, + [40063] = { + position = {x = 31952, y = 32174, z = 10}, + teleportTo = {x = 31954, y = 32174, z = 10} + } +} + +local missionEnergyBarriers = MoveEvent() + +function missionEnergyBarriers.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local energyBarrier = energyBarriers[item.uid] + local teleportPosition = Position(energyBarrier.teleportTo) + player:teleportTo(teleportPosition, false) + position:sendMagicEffect(CONST_ME_PURPLEENERGY) + teleportPosition:sendMagicEffect(CONST_ME_PURPLEENERGY) + if energyBarrier.message then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, energyBarrier.message) + end + return true +end + +for index, value in pairs(energyBarriers) do + missionEnergyBarriers:uid(index) +end +missionEnergyBarriers:register() + +-- Levers + +local levers = { + [40064] = { + barrier = 40058, + message = "The energy barrier to the south temporarily disappeared." + }, + [40065] = { + barrier = 40059 + }, + [40066] = { + barrier = 40060 + }, + [40067] = { + barrier = 40061 + }, + [40068] = { + barrier = 40062 + }, + [40069] = { + barrier = 40063, + newState = 11 + } +} + +local function energyBarrierRestore(barrierUID) + local energyBarrier = Tile(energyBarriers[barrierUID].position):getItemById(13934) + if not energyBarrier then + energyBarrier = Game.createItem(13934, 1, energyBarriers[barrierUID].position) + energyBarrier:setAttribute(ITEM_ATTRIBUTE_UNIQUEID, barrierUID) + end +end + +local missionLevers = Action() + +function missionLevers.onUse(player, item, position, item2, toPosition) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission12) + if missionState >= 10 then + local lever = levers[item.uid] + local energyBarrier = Tile(energyBarriers[lever.barrier].position):getItemById(13934) + if energyBarrier then + energyBarrier:getPosition():sendMagicEffect(CONST_ME_PURPLEENERGY) + energyBarrier:remove() + if lever.message then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, lever.message) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "An energy barrier somewhere temporarily disappeared.") + end + if missionState == 10 and lever.newState then + player:setStorageValue(Storage.TheRookieGuard.Mission12, lever.newState) + end + addEvent(energyBarrierRestore, 60000, lever.barrier) + else + player:say("", TALKTYPE_MONSTER_SAY, false, player, position) + end + end + return true +end + +for index, value in pairs(levers) do + missionLevers:uid(index) +end +missionLevers:register() + +-- Kraknaknork room + +local boss = { + uid = nil, + fight = nil, + roomCenter = {x = 31937, y = 32170, z = 10} +} + +local function finishBossFight(playerUid, bossUid) + local player = Player(playerUid) + -- Kick out the player + if player then + local roomExitPosition = Position(31980, 32173, 10) + player:teleportTo(roomExitPosition, false) + roomExitPosition:sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "With his last energy, Kraknaknork pushes you out of his throne room. Hurry back and defeat him before he regains his power.") + local health, maxHealth = player:getHealth(), player:getBaseMaxHealth() + -- Heal the player if needed + if health < maxHealth then + player:addHealth((maxHealth - health), COMBAT_HEALING) + end + end + local boss = Creature(bossUid) + -- Despawn the boss + if boss then + boss:getPosition():sendMagicEffect(CONST_ME_POFF) + boss:remove() + end +end + +-- Kraknaknork room enter teleport + +local enterBossRoomTeleport = MoveEvent() + +function enterBossRoomTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission12) + -- Skip if not was started or finished + if missionState == -1 then + return true + end + if missionState >= 11 then + local spectators = Game.getSpectators(Position(boss.roomCenter), false, true, 8, 8, 5, 5) + -- Check if there is a player inside the room + if #spectators > 0 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "A player is already inside the boss room.") + player:teleportTo(fromPosition, false) + return true + end + -- Spawn the boss + local bossCreature = Game.createMonster("Kraknaknork", Position(31930, 32170, 10)) + local bossDeath = CreatureEvent("KraknaknorkDeath") + function bossDeath.onDeath(player, corpse, killer, mostDamage, unjustified, mostDamage_unjustified) + stopEvent(boss.fight) + end + bossDeath:register() + bossCreature:registerEvent("KraknaknorkDeath") + boss.uid = bossCreature.uid + -- Teleport the player to the room + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You're entering Kraknaknork's throne room. You have 5 minutes to kill him!") + player:setStorageValue(Storage.TheRookieGuard.Mission12, 12) + local roomPosition = Position(31944, 32174, 10) + player:teleportTo(roomPosition, false) + position:sendMagicEffect(CONST_ME_TELEPORT) + roomPosition:sendMagicEffect(CONST_ME_TELEPORT) + -- Start boss fight timer + boss.fight = addEvent(finishBossFight, 5*60*1000, player.uid, bossCreature.uid) + end + return true +end + +enterBossRoomTeleport:uid(40070) +enterBossRoomTeleport:register() + +-- Kraknaknork room exit teleport + +local exitBossRoomTeleport = MoveEvent() + +function exitBossRoomTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + -- Cancel boss fight timer + stopEvent(boss.fight) + -- Teleport the player + local roomExitPosition = Position(31954, 32174, 10) + player:teleportTo(roomExitPosition, false) + position:sendMagicEffect(CONST_ME_TELEPORT) + roomExitPosition:sendMagicEffect(CONST_ME_TELEPORT) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You backed out of the fight. You may try again at any time.") + -- Despawn the boss + local boss = Creature(boss.uid) + if boss then + boss:getPosition():sendMagicEffect(CONST_ME_POFF) + boss:remove() + end + return true +end + +exitBossRoomTeleport:uid(40071) +exitBossRoomTeleport:register() + +-- Kraknaknork treasure room enter teleport + +local enterTreasureRoomTeleport = MoveEvent() + +function enterTreasureRoomTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission12) + if missionState == 12 then + local spectators = Game.getSpectators(Position(boss.roomCenter), false, false, 8, 8, 5, 5) + -- Check the boss do not exist + if #spectators > 0 then + for i = 1, #spectators do + if not spectators[i]:isPlayer() and spectators[i]:getName() == "Kraknaknork" then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You may not use this teleporter yet.") + player:teleportTo(fromPosition, false) + position:sendMagicEffect(CONST_ME_TELEPORT) + fromPosition:sendMagicEffect(CONST_ME_TELEPORT) + return false + end + end + end + -- Teleport the player to the treasure room + player:setStorageValue(Storage.TheRookieGuard.Mission12, 13) + local treasureRoomPosition = Position(31932, 32171, 11) + player:teleportTo(treasureRoomPosition, false) + position:sendMagicEffect(CONST_ME_TELEPORT) + treasureRoomPosition:sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +enterTreasureRoomTeleport:uid(40072) +enterTreasureRoomTeleport:register() + +-- Boss treasure chests (Rewards: small ruby and 2 platinum coins) + +local CHEST_ID = { + LEFT = 1, + RIGHT = 2 +} + +local chests = { + [40073] = { + id = CHEST_ID.LEFT, + item = { + id = 2147, + amount = 1 + } + }, + [40074] = { + id = CHEST_ID.RIGHT, + item = { + id = 2152, + amount = 2 + } + } +} + +local bossChests = Action() + +function bossChests.onUse(player, item, frompos, item2, topos) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission12) + -- Skip if not was started + if missionState == -1 then + return true + end + if missionState == 13 then + local chest = chests[item.uid] + local chestsState = player:getStorageValue(Storage.TheRookieGuard.KraknaknorkChests) + local hasUsedChest = testFlag(chestsState, chest.id) + if not hasUsedChest then + local reward = Game.createItem(chest.item.id, chest.item.amount) + if reward:getCount() == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found " .. reward:getArticle() .. " " .. reward:getName() .. ".") + elseif reward:getCount() > 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found " .. reward:getCount() .. " " .. reward:getPluralName() .. ".") + end + player:setStorageValue(Storage.TheRookieGuard.KraknaknorkChests, chestsState + chest.id) + player:addItemEx(reward, true, CONST_SLOT_WHEREEVER) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The " .. item:getName() .. " is empty.") + end + end + return true +end + +bossChests:uid(40073, 40074) +bossChests:register() + +-- Kraknaknork treasure room exit teleport + +local exitTreasureRoomTeleport = MoveEvent() + +function exitTreasureRoomTeleport.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission12) + if missionState == 13 then + local health, maxHealth = player:getHealth(), player:getBaseMaxHealth() + -- Heal the player if needed + if health < maxHealth then + player:addHealth((maxHealth - health), COMBAT_HEALING) + end + -- Teleport the player to the orcland exit + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "With Kraknaknork's final source of energy, you escape the fortress. Time to return to Vascalir.") + player:setStorageValue(Storage.TheRookieGuard.Mission12, 14) + local exitPosition = Position(32016, 32150, 7) + player:teleportTo(exitPosition, false) + position:sendMagicEffect(CONST_ME_TELEPORT) + exitPosition:sendMagicEffect(CONST_ME_TELEPORT) + end + return true +end + +exitTreasureRoomTeleport:uid(40075) +exitTreasureRoomTeleport:register() + +-- Orc fortress and Kraknaknork lair chests + +local CHEST_ID = { + FORTRESS_TREASURE_CHEST = 1, + FORTRESS_TRUNK = 2, + LAIR_TREASURE_CHEST = 4 +} + +local chests = { + [40079] = { + id = CHEST_ID.FORTRESS_TREASURE_CHEST, + item = { + id = 2695, + amount = 30 + } + }, + [40080] = { + id = CHEST_ID.FORTRESS_TRUNK, + item = { + id = 8704, + amount = 2 + } + }, + [40081] = { + id = CHEST_ID.LAIR_TREASURE_CHEST, + item = { + id = 8704, + amount = 1 + } + } +} + +local orcFortressChests = Action() + +function orcFortressChests.onUse(player, item, frompos, item2, topos) + local missionState = player:getStorageValue(Storage.TheRookieGuard.Mission10) + -- Skip if not was started + if missionState == -1 then + return true + end + local chest = chests[item.uid] + local chestsState = player:getStorageValue(Storage.TheRookieGuard.OrcFortressChests) + local hasOpenedChest = testFlag(chestsState, chest.id) + if not hasOpenedChest then + local reward = Game.createItem(chest.item.id, chest.item.amount) + if reward:getCount() == 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found " .. reward:getArticle() .. " " .. reward:getName() .. ".") + elseif reward:getCount() > 1 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found " .. reward:getCount() .. " " .. reward:getPluralName() .. ".") + end + player:setStorageValue(Storage.TheRookieGuard.OrcFortressChests, chestsState + chest.id) + player:addItemEx(reward, true, CONST_SLOT_WHEREEVER) + else + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The " .. item:getName() .. " is empty.") + end + return true +end + +orcFortressChests:uid(40079, 40080, 40081) +orcFortressChests:register() diff --git a/data/scripts/quests/the_rookie_guard/missions.lua b/data/scripts/quests/the_rookie_guard/missions.lua new file mode 100644 index 00000000000..d235d77bc0b --- /dev/null +++ b/data/scripts/quests/the_rookie_guard/missions.lua @@ -0,0 +1,241 @@ +-- The Rookie Guard Quest + +-- Handle avoid spam (message and arrow) in mission tiles +function isTutorialNotificationDelayed(player) + -- Check delay + if player:getStorageValue(Storage.TheRookieGuard.TutorialDelay) - os.time() <= 0 then + -- Reset delay + player:setStorageValue(Storage.TheRookieGuard.TutorialDelay, os.time() + 4) + return false + end + return true +end + +-- Missions shared tiles (Handled together due not possible more than one MoveEvent per action id) + +local missionTiles = { + -- North exit + [50312] = { + { + mission = Storage.TheRookieGuard.Mission02, + states = {1, 2, 3, 4}, + message = "This road is the main access of the village. You might want to finish your business here first." + }, + { + mission = Storage.TheRookieGuard.Mission03, + states = {1}, + message = "This road is the main access of the village. You might want to finish your business here first." + } + }, + -- North bridge exit + [50319] = { + { + mission = Storage.TheRookieGuard.Mission04, + states = {2}, + message = "Follow the path to the east to find Hyacinth's little house.", + arrowPosition = {x = 32096, y = 32169, z = 7} + }, + { + mission = Storage.TheRookieGuard.Mission06, + states = {2}, + message = "Follow the path east, and when it splits, head north-east to find the wolf forest.", + arrowPosition = {x = 32094, y = 32169, z = 7} + }, + { + mission = Storage.TheRookieGuard.Mission09, + states = {1}, + message = "Follow the path to the north past the hill to reach the troll caves.", + arrowPosition = {x = 32091, y = 32166, z = 7} + }, + { + mission = Storage.TheRookieGuard.Mission10, + states = {1}, + extra = { + storage = Storage.TheRookieGuard.Sarcophagus, + state = -1 + }, + message = "Follow the way to the east and go south to reach the graveyard.", + arrowPosition = {x = 32095, y = 32169, z = 7} + }, + { + mission = Storage.TheRookieGuard.Mission11, + states = {1}, + message = "To reach the wasps' nests follow the path to the north and cross the bridge to the west as if you wanted to reach the spiders.", + arrowPosition = {x = 32090, y = 32165, z = 7} + }, + { + mission = Storage.TheRookieGuard.Mission12, + states = {2}, + extra = { + storage = Storage.TheRookieGuard.AcademyChest, + state = 1 + }, + message = "Follow the path to the north, cross the bridge to the south and walk west to reach the orc fortress.", + arrowPosition = {x = 32091, y = 32166, z = 7} + } + }, + [50321] = { + { + mission = Storage.TheRookieGuard.Mission04, + states = {2}, + message = "This is not the way to Hyacinth. Stay on the path a little more to the south to find Hyacinth's little house." + }, + { + mission = Storage.TheRookieGuard.Mission10, + states = {1}, + extra = { + storage = Storage.TheRookieGuard.Sarcophagus, + state = -1 + }, + message = "This is not the way to the crypt. Go south to reach the graveyard." + } + }, + -- Outer east + [50323] = { + { + mission = Storage.TheRookieGuard.Mission05, + states = {1}, + message = "This is not the way to the tarantula's lair. Head northwest and go up the little ramp." + }, + { + mission = Storage.TheRookieGuard.Mission09, + states = {1}, + message = "This is not the way to the troll caves. Follow the path to the north past the hill to reach them.", + arrowPosition = {x = 32091, y = 32166, z = 7} + } + }, + -- North-west drawbridge + [50325] = { + { + mission = Storage.TheRookieGuard.Mission05, + states = {1}, + message = "Walk to the north and down the stairs to reach the tarantula's lair.", + arrowPosition = {x = 32069, y = 32145, z = 6} + }, + { + mission = Storage.TheRookieGuard.Mission11, + states = {1}, + message = "Take the southern stairs down the bridge to go to the wasps' lair.", + arrowPosition = {x = 32068, y = 32149, z = 6} + } + }, + -- Academy entrance + [50335] = { + { + mission = Storage.TheRookieGuard.Mission07, + states = {1}, + extra = { + storage = Storage.TheRookieGuard.LibraryChest, + state = -1 + }, + message = "The library vault is below the academy. Go north and head down several stairs until you find a quest door.", + arrowPosition = {x = 32097, y = 32197, z = 7} + }, + { + mission = Storage.TheRookieGuard.Mission08, + states = {1}, + message = "The bank is below the academy. Go north and head down the stairs and to the right.", + arrowPosition = {x = 32097, y = 32197, z = 7} + }, + { + mission = Storage.TheRookieGuard.Mission12, + states = {1}, + extra = { + storage = Storage.TheRookieGuard.AcademyChest, + state = -1 + }, + message = "You don't have the bag with the items yet. Open the door in the basement of the academy to the left of Paulie to get them!", + arrowPosition = {x = 32097, y = 32197, z = 7} + } + }, + -- Academy downstairs + [50336] = { + { + mission = Storage.TheRookieGuard.Mission07, + states = {1}, + extra = { + storage = Storage.TheRookieGuard.LibraryChest, + state = -1 + }, + message = "Head through the northern door and follow the hallways to find the library vault.", + arrowPosition = {x = 32095, y = 32188, z = 8} + }, + { + mission = Storage.TheRookieGuard.Mission08, + states = {1}, + message = "Go to the right to find the bank and talk to Paulie.", + arrowPosition = {x = 32100, y = 32191, z = 8} + } + }, + -- North-west drawbridge south downstairs + [50351] = { + { + mission = Storage.TheRookieGuard.Mission11, + states = {1}, + message = "Follow the path to the west to find the wasps' lair.", + arrowPosition = {x = 32063, y = 32159, z = 7} + }, + { + mission = Storage.TheRookieGuard.Mission12, + states = {2}, + extra = { + storage = Storage.TheRookieGuard.AcademyChest, + state = 1 + }, + message = "Follow the path to the west to reach the orc fortress.", + arrowPosition = {x = 32063, y = 32159, z = 7} + } + }, + -- Orc land entrance + [50352] = { + { + mission = Storage.TheRookieGuard.Mission11, + states = {1}, + message = "This is not the way to the wasps' lair. Choose the northern path to reach it.", + arrowPosition = {x = 32003, y = 32148, z = 7} + }, + { + mission = Storage.TheRookieGuard.Mission12, + states = {2}, + extra = { + storage = Storage.TheRookieGuard.AcademyChest, + state = 1 + }, + message = "You're entering orcland." + } + } +} + +-- Missions tutorial tiles + +local missionGuide = MoveEvent() + +function missionGuide.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() + if not player then + return true + end + local tile = missionTiles[item.actionid] + -- Check mission cases for the tile + for i = 1, #tile do + local missionState = player:getStorageValue(tile[i].mission) + local extraState = tile[i].extra == nil or player:getStorageValue(tile[i].extra.storage) == tile[i].extra.state + -- Check if the tile is active + if missionState ~= -1 and table.find(tile[i].states, missionState) and extraState then + -- Check delayed notifications (message/arrow) + if not isTutorialNotificationDelayed(player) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, tile[i].message) + if tile[i].arrowPosition then + Position(tile[i].arrowPosition):sendMagicEffect(CONST_ME_TUTORIALARROW) + end + end + break + end + end + return true +end + +for index, value in pairs(missionTiles) do + missionGuide:aid(index) +end +missionGuide:register() diff --git a/data/scripts/runes/#example.lua b/data/scripts/runes/#example.lua new file mode 100644 index 00000000000..9ba6a17b880 --- /dev/null +++ b/data/scripts/runes/#example.lua @@ -0,0 +1,52 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE) +combat:setParameter(COMBAT_PARAM_TARGETCASTERORTOPMOST, true) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false) + +function onGetFormulaValues(player, level, magicLevel) + local min = (level / 5) + (magicLevel * 3.2) + 20 + local max = (level / 5) + (magicLevel * 5.4) + 40 + return min, max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +local spell = Spell(SPELL_RUNE) + +function spell.onCastSpell(creature, variant, isHotkey) + return combat:execute(creature, variant) +end + +spell:name("test rune") +spell:runeId(2275) +spell:id(220) +spell:level(20) +spell:magicLevel(5) +spell:needTarget(true) +spell:isAggressive(false) +spell:allowFarUse(true) +spell:charges(25) +spell:vocation("sorcerer;true", "master sorcerer") +spell:register() + +local conjureRune = Spell(SPELL_INSTANT) + +function conjureRune.onCastSpell(creature, variant) + return creature:conjureItem(2260, 2275, 25) +end + +conjureRune:name("Test") +conjureRune:id(221) +conjureRune:words("adori mas test") +conjureRune:level(30) +conjureRune:mana(530) +conjureRune:group("support") +conjureRune:soul(3) +conjureRune:isAggressive(false) +conjureRune:cooldown(2000) +conjureRune:groupCooldown(2000) +conjureRune:needLearn(false) +conjureRune:vocation("sorcerer", "master sorcerer") +conjureRune:register() diff --git a/data/scripts/runes/magic_wall.lua b/data/scripts/runes/magic_wall.lua new file mode 100644 index 00000000000..e5fd722fa08 --- /dev/null +++ b/data/scripts/runes/magic_wall.lua @@ -0,0 +1,28 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + +function onCreateMagicWall(creature, tile) + local item = Game.createItem(Game.getWorldType() == WORLD_TYPE_NO_PVP and ITEM_MAGICWALL_SAFE or ITEM_MAGICWALL, 1, tile) + item:setAttribute(ITEM_ATTRIBUTE_DURATION, math.random(14000, 20000)) +end + +combat:setCallback(CALLBACK_PARAM_TARGETTILE, "onCreateMagicWall") + +local spell = Spell("rune") +function spell.onCastSpell(creature, variant, isHotkey) + return combat:execute(creature, variant) +end + + +spell:name("Magic Wall Rune") +spell:group("attack") +spell:id(86) +spell:cooldown(2 * 1000) +spell:groupCooldown(2 * 1000) +spell:level(32) +spell:magicLevel(9) +spell:runeId(2293) +spell:charges(3) +spell:isBlocking(true, true) +spell:allowFarUse(true) +spell:register() diff --git a/data/scripts/runes/wild_growth.lua b/data/scripts/runes/wild_growth.lua new file mode 100644 index 00000000000..90971b9d7ce --- /dev/null +++ b/data/scripts/runes/wild_growth.lua @@ -0,0 +1,28 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_EARTH) + +function onCreateMagicWall(creature, tile) + local item = Game.createItem(Game.getWorldType() == WORLD_TYPE_NO_PVP and ITEM_WILDGROWTH_SAFE or ITEM_WILDGROWTH, 1, tile) + item:setAttribute(ITEM_ATTRIBUTE_DURATION, math.random(38000, 45000)) +end + +combat:setCallback(CALLBACK_PARAM_TARGETTILE, "onCreateMagicWall") + +local spell = Spell("rune") +function spell.onCastSpell(creature, variant, isHotkey) + return combat:execute(creature, variant) +end + +spell:name("Wild Growth Rune") +spell:group("attack") +spell:id(94) +spell:cooldown(2 * 1000) +spell:groupCooldown(2 * 1000) +spell:level(27) +spell:magicLevel(8) +spell:runeId(2269) +spell:charges(2) +spell:isBlocking(true, true) +spell:allowFarUse(true) +spell:vocation("druid;true", "elder druid") +spell:register() diff --git a/data/scripts/talkactions/god/add_outfit.lua b/data/scripts/talkactions/god/add_outfit.lua new file mode 100644 index 00000000000..92f6a304afa --- /dev/null +++ b/data/scripts/talkactions/god/add_outfit.lua @@ -0,0 +1,43 @@ +--[[ + /addoutfit playername, looktype + make sure you’re adding a male outfit to a male character + if you try to add a female outfit to a male character, it won’t work +]] + +local printConsole = true + +local addOutfit = TalkAction("/addoutfit") + +function addOutfit.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + if param == "" then + player:sendCancelMessage("Command param required.") + return false + end + + local split = param:split(",") + local name = split[1] + local lookType = tonumber(split[2]) + + local target = Player(name) + if target then + target:addOutfit(lookType) + target:sendTextMessage(MESSAGE_ADMINISTRADOR, "".. player:getName() .." has been added a new outfit for you.") + player:sendTextMessage(MESSAGE_ADMINISTRADOR, "You have sucessfull added looktype ".. lookType .. " to the player ".. target:getName() ..".") + if printConsole then + Spdlog.info(string.format("[addOutfit.onSay] - Player: %s has been added looktype: %s to the player: %s", + player:getName(), lookType, target:getName())) + end + return true + else + player:sendCancelMessage("Player not found.") + return true + end + return false +end + +addOutfit:separator(" ") +addOutfit:register() diff --git a/data/scripts/talkactions/god/add_skill.lua b/data/scripts/talkactions/god/add_skill.lua new file mode 100644 index 00000000000..7c41b2fc768 --- /dev/null +++ b/data/scripts/talkactions/god/add_skill.lua @@ -0,0 +1,77 @@ +local function getSkillId(skillName) + if skillName == "club" then + return SKILL_CLUB + elseif skillName == "sword" then + return SKILL_SWORD + elseif skillName == "axe" then + return SKILL_AXE + elseif skillName:sub(1, 4) == "dist" then + return SKILL_DISTANCE + elseif skillName:sub(1, 6) == "shield" then + return SKILL_SHIELD + elseif skillName:sub(1, 4) == "fish" then + return SKILL_FISHING + else + return SKILL_FIST + end +end + +local function getExpForLevel(level) + level = level - 1 + return ((50 * level * level * level) - (150 * level * level) + (400 * level)) / 3 +end + + +local addSkill = TalkAction("/addskill") + +function addSkill.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + if param == "" then + player:sendCancelMessage("Command param required.") + return false + end + + local split = param:split(",") + if not split[2] then + player:sendCancelMessage("Insufficient parameters.") + return false + end + + local target = Player(split[1]) + if not target then + player:sendCancelMessage("A player with that name is not online.") + return false + end + + -- Trim left + split[2] = split[2]:gsub("^%s*(.-)$", "%1") + + local count = 1 + if split[3] then + count = tonumber(split[3]) + end + + local ch = split[2]:sub(1, 1) + if ch == "l" or ch == "e" then + targetLevel = target:getLevel() + count + targetExp = getExpForLevel(targetLevel) + addExp = targetExp - target:getExperience() + target:addExperience(addExp, false) + elseif ch == "m" then + for i = 1, count do + target:addManaSpent(target:getVocation():getRequiredManaSpent(target:getBaseMagicLevel() + 1) - target:getManaSpent()) + end + else + local skillId = getSkillId(split[2]) + for i = 1, count do + target:addSkillTries(skillId, target:getVocation():getRequiredSkillTries(skillId, target:getSkillLevel(skillId) + 1) - target:getSkillTries(skillId)) + end + end + return false +end + +addSkill:separator(" ") +addSkill:register() diff --git a/data/scripts/talkactions/god/alladdons.lua b/data/scripts/talkactions/god/alladdons.lua new file mode 100644 index 00000000000..e979edf3225 --- /dev/null +++ b/data/scripts/talkactions/god/alladdons.lua @@ -0,0 +1,57 @@ +-- /addons playername + +local addons = TalkAction("/addons") +local looktypes = { + + -- Female Outfits + 136, 137, 138, 139, 140, 141, 142, 147, 148, 149, 150, 155, 156, 157, 158, 252, 269, 270, 279, 288, + 324, 329, 336, 366, 431, 433, 464, 466, 471, 513, 514, 542, 575, 578, 618, 620, 632, 635, 636, 664, + 666, 683, 694, 696, 698, 724, 732, 745, 749, 759, 845, 852, 874, 885, 900, 909, 929, 956, 958, 963, + 965, 967, 969, 971, 973, 975, 1020, 1024, 1043, 1050, 1057, 1070, 1095, 1103, 1128, 1147, 1162, 1174, 1187, + 1203, 1205, 1207, 1211, 1244, 1246, 1252, 1271, 1280, 1283, 1289, 1293, 1323, 1332, 1339, 1372, 1383, 1385, + + -- Male Outfits + 128, 129, 130, 131, 132, 133, 134, 143, 144, 145, 146, 151, 152, 153, 154, 251, 268, 273, 278, 289, + 325, 328, 335, 367, 430, 432, 463, 465, 472, 512, 516, 541, 574, 577, 610, 619, 633, 634, 637, 665, + 667, 684, 695, 697, 699, 725, 733, 746, 750, 760, 846, 853, 873, 884, 899, 908, 931, 955, 957, 962, + 964, 966, 968, 970, 972, 974, 1021, 1023, 1042, 1051, 1056, 1069, 1094, 1102, 1127, 1146, 1161, 1173, 1186, + 1202, 1204, 1206, 1210, 1243, 1245, 1251, 1270, 1279, 1282, 1288, 1292, 1322, 1331, 1338, 1371, 1382, 1384 +} + +function addons.onSay(player, words, param) + if not player:getGroup():getAccess() then + return true + end + + local target + if param == '' then + target = player:getTarget() + if not target then + player:sendTextMessage(MESSAGE_ATTENTION, 'Gives players the ability to wear all addons. Usage: /addons ') + return false + end + else + target = Player(param) + end + + if not target then + player:sendTextMessage(MESSAGE_ATTENTION, 'Player ' .. param .. ' is currently not online.') + return false + end + + if player:getAccountType() < ACCOUNT_TYPE_GOD then + player:sendTextMessage(MESSAGE_ATTENTION, 'Cannot perform action.') + return false + end + + for i = 1, #looktypes do + target:addOutfitAddon(looktypes[i], 3) + end + + player:sendTextMessage(MESSAGE_ATTENTION, 'All addons unlocked for ' .. target:getName() .. '.') + target:sendTextMessage(MESSAGE_ATTENTION, 'All of your addons have been unlocked!') + return false +end + +addons:separator(" ") +addons:register() \ No newline at end of file diff --git a/data/scripts/talkactions/god/allmounts.lua b/data/scripts/talkactions/god/allmounts.lua new file mode 100644 index 00000000000..86ef3f11b26 --- /dev/null +++ b/data/scripts/talkactions/god/allmounts.lua @@ -0,0 +1,40 @@ +-- /mounts playername + +local mounts = TalkAction("/mounts") +function mounts.onSay(player, words, param) + if not player:getGroup():getAccess() then + return true + end + + local target + if param == '' then + target = player:getTarget() + if not target then + player:sendTextMessage(MESSAGE_ATTENTION, 'Unlocks all mounts for certain player. Usage: /mounts ') + return false + end + else + target = Player(param) + end + + if not target then + player:sendTextMessage(MESSAGE_ATTENTION, 'Player ' .. param .. ' is not currently online.') + return false + end + + if player:getAccountType() < ACCOUNT_TYPE_GOD then + player:sendTextMessage(MESSAGE_ATTENTION, 'Cannot perform action.') + return false + end + + for i = 1, 181 do + target:addMount(i) + end + + player:sendTextMessage(MESSAGE_ATTENTION, 'All mounts unlocked for: ' .. target:getName()) + target:sendTextMessage(MESSAGE_ATTENTION, 'All of your mounts have been unlocked!') + return false +end + +mounts:separator(" ") +mounts:register() diff --git a/data/scripts/talkactions/god/attributes.lua b/data/scripts/talkactions/god/attributes.lua new file mode 100644 index 00000000000..6bb2f4c50e9 --- /dev/null +++ b/data/scripts/talkactions/god/attributes.lua @@ -0,0 +1,108 @@ +local itemFunctions = { + ["actionid"] = { isActive = true, targetFunction = function (item, target) return item:setActionId(target) end }, + ["action"] = { isActive = true, targetFunction = function (item, target) return item:setActionId(target) end }, + ["aid"] = { isActive = true, targetFunction = function (item, target) return item:setActionId(target) end }, + ["uniqueid"] = { isActive = true, targetFunction = function (item, target) return item:setAttribute(ITEM_ATTRIBUTE_UNIQUEID, target) end }, + ["unique"] = { isActive = true, targetFunction = function (item, target) return item:setAttribute(ITEM_ATTRIBUTE_UNIQUEID, target) end }, + ["uid"] = { isActive = true, targetFunction = function (item, target) return item:setAttribute(ITEM_ATTRIBUTE_UNIQUEID, target) end }, + ["description"] = { isActive = true, targetFunction = function (item, target) return item:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, target) end }, + ["desc"] = { isActive = true, targetFunction = function (item, target) return item:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, target) end }, + ["name"] = { isActive = true, targetFunction = function (item, target) return item:setAttribute(ITEM_ATTRIBUTE_NAME, target) end }, + ["remove"] = { isActive = true, targetFunction = function (item, target) return item:remove() end }, + ["decay"] = { isActive = true, targetFunction = function (item, target) return item:decay() end }, + ["transform"] = { isActive = true, targetFunction = function (item, target) return item:transform(target) end }, + ["clone"] = { isActive = true, targetFunction = function (item, target) return item:clone() end }, + ["attack"] = { isActive = true, targetFunction = function (item, target) return item:setAttribute(ITEM_ATTRIBUTE_ATTACK, target) end }, + ["defense"] = { isActive = true, targetFunction = function (item, target) return item:setAttribute(ITEM_ATTRIBUTE_DEFENSE, target) end }, + ["extradefense"] = { isActive = true, targetFunction = function (item, target) return item:setAttribute(ITEM_ATTRIBUTE_EXTRADEFENSE, target) end }, + ["armor"] = { isActive = true, targetFunction = function (item, target) return item:setAttribute(ITEM_ATTRIBUTE_ARMOR, target) end } +} + +local creatureFunctions = { + ["health"] = { isActive = true, targetFunction = function (creature, target) return creature:addHealth(target) end }, + ["mana"] = { isActive = true, targetFunction = function (creature, target) return creature:addMana(target) end }, + ["speed"] = { isActive = true, targetFunction = function (creature, target) return creature:changeSpeed(target) end }, + ["droploot"] = { isActive = true, targetFunction = function (creature, target) return creature:setDropLoot(target) end }, + ["skull"] = { isActive = true, targetFunction = function (creature, target) return creature:setSkull(target) end }, + ["direction"] = { isActive = true, targetFunction = function (creature, target) return creature:setDirection(target) end }, + ["maxHealth"] = { isActive = true, targetFunction = function (creature, target) return creature:setMaxHealth(target) end }, + ["say"] = { isActive = true, targetFunction = function (creature, target) creature:say(target, TALKTYPE_SAY) end } +} + +local playerFunctions = { + ["fyi"] = { isActive = true, targetFunction = function (player, target) return player:popupFYI(target) end }, + ["tutorial"] = { isActive = true, targetFunction = function (player, target) return player:sendTutorial(target) end }, + ["guildnick"] = { isActive = true, targetFunction = function (player, target) return player:setGuildNick(target) end }, + ["group"] = { isActive = true, targetFunction = function (player, target) return player:setGroup(Group(target)) end }, + ["vocation"] = { isActive = true, targetFunction = function (player, target) return player:setVocation(Vocation(target)) end }, + ["stamina"] = { isActive = true, targetFunction = function (player, target) return player:setStamina(target) end }, + ["town"] = { isActive = true, targetFunction = function (player, target) return player:setTown(Town(target)) end }, + ["balance"] = { isActive = true, targetFunction = function (player, target) return player:setBankBalance(target + player:getBankBalance()) end }, + ["save"] = { isActive = true, targetFunction = function (player, target) return player:save() end }, + ["type"] = { isActive = true, targetFunction = function (player, target) return player:setAccountType(target) end }, + ["skullTime"] = { isActive = true, targetFunction = function (player, target) return player:setSkullTime(target) end }, + ["maxMana"] = { isActive = true, targetFunction = function (player, target) return player:setMaxMana(target) end }, + ["maxHealth"] = { isActive = true, targetFunction = function (player, target) return player:setMaxHealth(target) end }, + ["addItem"] = { isActive = true, targetFunction = function (player, target) return player:addItem(target, 1) end }, + ["removeItem"] = { isActive = true, targetFunction = function (player, target) return player:removeItem(target, 1) end }, + ["premium"] = { isActive = true, targetFunction = function (player, target) return player:addPremiumDays(target) end } +} + +local attributes = TalkAction("/attr") + +function attributes.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + if param == "" then + player:sendCancelMessage("Command param required.") + return false + end + + local position = player:getPosition() + position:getNextPosition(player:getDirection(), 1) + + local split = param:split(",") + local itemFunction, creatureFunction, playerFunction = itemFunctions[split[1]], creatureFunctions[split[1]], playerFunctions[split[1]] + if(itemFunction and itemFunction.isActive) then + local item = Tile(position):getTopVisibleThing(player) + if(not item or not item:isItem()) then + player:sendCancelMessage("Item not found.") + return false + end + if(itemFunction.targetFunction(item, split[2])) then + position:sendMagicEffect(CONST_ME_MAGIC_GREEN) + else + player:sendCancelMessage("You cannot add that attribute to this item.") + end + elseif(creatureFunction and creatureFunction.isActive) then + local creature = Tile(position):getTopCreature() + if(not creature or not creature:isCreature()) then + player:sendCancelMessage("Creature not found.") + return false + end + if(creatureFunction.targetFunction(creature, split[2])) then + position:sendMagicEffect(CONST_ME_MAGIC_GREEN) + else + player:sendCancelMessage("You cannot add that attribute to this creature.") + end + elseif(playerFunction and playerFunction.isActive) then + local targetPlayer = Tile(position):getTopCreature() + if(not targetPlayer or not targetPlayer:getPlayer()) then + player:sendCancelMessage("Player not found.") + return false + end + if(playerFunction.targetFunction(targetPlayer, split[2])) then + position:sendMagicEffect(CONST_ME_MAGIC_GREEN) + else + player:sendCancelMessage("You cannot add that attribute to this player.") + end + else + player:sendCancelMessage("Unknow attribute.") + end + return false +end + +attributes:separator(" ") +attributes:register() diff --git a/data/scripts/talkactions/god/ban.lua b/data/scripts/talkactions/god/ban.lua new file mode 100644 index 00000000000..51c212d2e76 --- /dev/null +++ b/data/scripts/talkactions/god/ban.lua @@ -0,0 +1,50 @@ +local banDays = 7 + +local ban = TalkAction("/ban") + +function ban.onSay(player, words, param) + + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + if param == "" then + player:sendCancelMessage("Command param required.") + return false + end + + local name = param + local reason = '' + + local separatorPos = param:find(',') + if separatorPos then + name = param:sub(0, separatorPos - 1) + reason = string.trim(param:sub(separatorPos + 1)) + end + + local accountId = getAccountNumberByPlayerName(name) + if accountId == 0 then + return false + end + + local resultId = db.storeQuery("SELECT 1 FROM `account_bans` WHERE `account_id` = " .. accountId) + if resultId ~= false then + result.free(resultId) + return false + end + + local timeNow = os.time() + db.query("INSERT INTO `account_bans` (`account_id`, `reason`, `banned_at`, `expires_at`, `banned_by`) VALUES (" .. + accountId .. ", " .. db.escapeString(reason) .. ", " .. timeNow .. ", " .. timeNow + (banDays * 86400) .. ", " .. player:getGuid() .. ")") + + local target = Player(name) + if target then + player:sendTextMessage(MESSAGE_ADMINISTRADOR, target:getName() .. " has been banned.") + target:remove() + else + player:sendTextMessage(MESSAGE_ADMINISTRADOR, name .. " has been banned.") + end +end + +ban:separator(" ") +ban:register() diff --git a/data/scripts/talkactions/god/bless_status.lua b/data/scripts/talkactions/god/bless_status.lua new file mode 100644 index 00000000000..13b49fccb76 --- /dev/null +++ b/data/scripts/talkactions/god/bless_status.lua @@ -0,0 +1,15 @@ +dofile('data/modules/scripts/blessings/blessings.lua') + +local blessStatus = TalkAction("/bless") + +function blessStatus.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + Blessings.sendBlessStatus(player) + return false +end + +blessStatus:separator(" ") +blessStatus:register() diff --git a/data/scripts/talkactions/god/broadcast.lua b/data/scripts/talkactions/god/broadcast.lua new file mode 100644 index 00000000000..fc1ad54ec60 --- /dev/null +++ b/data/scripts/talkactions/god/broadcast.lua @@ -0,0 +1,21 @@ +local broadcast = TalkAction("/b") + +function broadcast.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + if param == "" then + player:sendCancelMessage("Command param required.") + return false + end + + Spdlog.info("" .. player:getName() .. " broadcasted: ".. param) + for _, targetPlayer in ipairs(Game.getPlayers()) do + targetPlayer:sendPrivateMessage(player, param, TALKTYPE_BROADCAST) + end + return false +end + +broadcast:separator(" ") +broadcast:register() diff --git a/data/scripts/talkactions/god/charms.lua b/data/scripts/talkactions/god/charms.lua new file mode 100644 index 00000000000..e72a2930212 --- /dev/null +++ b/data/scripts/talkactions/god/charms.lua @@ -0,0 +1,154 @@ +local addCharm = TalkAction("/addcharms") + +function addCharm.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + local usage = "/addcharms PLAYER NAME,AMOUNT" + if param == "" then + player:sendCancelMessage("Command param required. Usage: ".. usage) + return false + end + local split = param:split(",") + if not split[2] then + player:sendCancelMessage("Insufficient parameters. Usage: ".. usage) + return false + end + local target = Player(split[1]) + if not target then + player:sendCancelMessage("A player with that name is not online.") + return false + end + --trim left + split[2] = split[2]:gsub("^%s*(.-)$", "%1") + + player:sendCancelMessage("Added " .. split[2] .. " charm points to character '" .. target:getName() .. "'.") + target:sendCancelMessage("Received " .. split[2] .. " charm points!") + target:addCharmPoints(tonumber(split[2])) + target:getPosition():sendMagicEffect(CONST_ME_HOLYAREA) + +end +addCharm:separator(" ") +addCharm:register() + +local resetCharm = TalkAction("/resetcharms") + +function resetCharm.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + if param == "" then + param = player:getName() + end + local target = Player(param) + if not target then + player:sendCancelMessage("A player with that name is not online.") + return false + end + + player:sendCancelMessage("Reseted charm points from character '" .. target:getName() .. "'.") + target:sendCancelMessage("Reseted your charm points!") + target:resetCharmsBestiary() + target:getPosition():sendMagicEffect(CONST_ME_HOLYAREA) + +end + +resetCharm:separator(" ") +resetCharm:register() + +local charmExpansion = TalkAction("/charmexpansion") + +function charmExpansion.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + if param == "" then + param = player:getName() + end + local target = Player(param) + if not target then + player:sendCancelMessage("A player with that name is not online.") + return false + end + + player:sendCancelMessage("Added charm expansion for player '" .. target:getName() .. "'.") + target:sendCancelMessage("Received charm expansion!") + target:charmExpansion(true) + target:getPosition():sendMagicEffect(CONST_ME_HOLYAREA) + +end + +charmExpansion:separator(" ") +charmExpansion:register() + +local charmRune = TalkAction("/charmrunes") + +function charmRune.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + if param == "" then + param = player:getName() + end + local target = Player(param) + if not target then + player:sendCancelMessage("A player with that name is not online.") + return false + end + + player:sendCancelMessage("Added all charm runes to '" .. target:getName() .. "'.") + target:sendCancelMessage("Received all charm runes!") + target:unlockAllCharmRunes() + target:getPosition():sendMagicEffect(CONST_ME_HOLYAREA) + +end + +charmRune:separator(" ") +charmRune:register() + +local setBestiary = TalkAction("/setbestiary") + +function setBestiary.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + local usage = "/setbestiary PLAYER NAME,MONSTER NAME,AMOUNT" + if param == "" then + player:sendCancelMessage("Command param required. Usage: ".. usage) + return false + end + local split = param:split(",") + if not split[3] then + player:sendCancelMessage("Insufficient parameters. Usage: ".. usage) + return false + end + local target = Player(split[1]) + if not target then + player:sendCancelMessage("A player with that name is not online.") + return false + end + + split[2] = split[2]:gsub("^%s*(.-)$", "%1") --Trim left + split[3] = split[3]:gsub("^%s*(.-)$", "%1") --Trim left + + local monsterName = split[2] + local mType = MonsterType(monsterName) + if not(mType) or (mType and mType:raceId() == 0) then + player:sendCancelMessage("This monster has no bestiary. Type the name exactly as in game.") + return false + end + local amount = tonumber(split[3]) + + player:sendCancelMessage("Set bestiary kill of monster '".. monsterName .. "' from player '" .. target:getName() .. "' to '" .. amount .. "'.") + target:sendCancelMessage("Updated kills of monster '".. monsterName .. "'!") + target:addBestiaryKill(monsterName, amount) + target:getPosition():sendMagicEffect(CONST_ME_HOLYAREA) +end + + +setBestiary:separator(" ") +setBestiary:register() diff --git a/data/scripts/talkactions/god/clean.lua b/data/scripts/talkactions/god/clean.lua new file mode 100644 index 00000000000..1ec547b0ab7 --- /dev/null +++ b/data/scripts/talkactions/god/clean.lua @@ -0,0 +1,16 @@ +local clean = TalkAction("/clean") + +function clean.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + local itemCount = cleanMap() + if itemCount ~= 0 then + player:sendTextMessage(MESSAGE_ADMINISTRADOR, "Cleaned " .. itemCount .. " item" .. (itemCount > 1 and "s" or "") .. " from the map.") + end + return false +end + +clean:separator(" ") +clean:register() diff --git a/data/scripts/talkactions/god/close_server.lua b/data/scripts/talkactions/god/close_server.lua new file mode 100644 index 00000000000..7295875bc17 --- /dev/null +++ b/data/scripts/talkactions/god/close_server.lua @@ -0,0 +1,18 @@ +local closeServer = TalkAction("/closeserver") + +function closeServer.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + if param == "shutdown" then + Game.setGameState(GAME_STATE_SHUTDOWN) + else + Game.setGameState(GAME_STATE_CLOSED) + player:sendTextMessage(MESSAGE_ADMINISTRADOR, "Server is now closed.") + end + return false +end + +closeServer:separator(" ") +closeServer:register() diff --git a/data/scripts/talkactions/god/count_monsters.lua b/data/scripts/talkactions/god/count_monsters.lua new file mode 100644 index 00000000000..5ec3ba4e544 --- /dev/null +++ b/data/scripts/talkactions/god/count_monsters.lua @@ -0,0 +1,47 @@ +local xml_monster_dir = 'data/world/otservbr-spawn.xml' -- Diretório do arquivo onde contém os monstros. +local new_file_name = 'monster_count.txt' + +local count_monsters = TalkAction("/countmonsters") + +function count_monsters.onSay(player, words, param) + + if not player:getGroup():getAccess() then + return true + end + + if player:getAccountType() < ACCOUNT_TYPE_GOD then + return false + end + + logCommand(player, words, param) + + local open_file = io.open(xml_monster_dir, "r") + local writing_file = io.open(new_file_name, "w+") + local file_read = open_file:read("*all") + + open_file:close() + + local monsters = {} + + for str_match in file_read:gmatch('") + return false + end +end + +getlook:separator(" ") +getlook:register() diff --git a/data/scripts/talkactions/god/ghost.lua b/data/scripts/talkactions/god/ghost.lua new file mode 100644 index 00000000000..c59b5c284f0 --- /dev/null +++ b/data/scripts/talkactions/god/ghost.lua @@ -0,0 +1,24 @@ +local ghost = TalkAction("/ghost") + +function ghost.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + local position = player:getPosition() + local isGhost = not player:isInGhostMode() + + player:setGhostMode(isGhost) + if isGhost then + player:sendTextMessage(MESSAGE_HOTKEY_PRESSED, "You are now invisible.") + position:sendMagicEffect(CONST_ME_YALAHARIGHOST) + else + player:sendTextMessage(MESSAGE_HOTKEY_PRESSED, "You are visible again.") + position.x = position.x + 1 + position:sendMagicEffect(CONST_ME_SMOKE) + end + return false +end + +ghost:separator(" ") +ghost:register() diff --git a/data/scripts/talkactions/god/gold_highscore.lua b/data/scripts/talkactions/god/gold_highscore.lua new file mode 100644 index 00000000000..2f35fee09a7 --- /dev/null +++ b/data/scripts/talkactions/god/gold_highscore.lua @@ -0,0 +1,35 @@ +local gold_rank = TalkAction("/goldrank") + +function gold_rank.onSay(player, words, param) + + if not player:getGroup():getAccess() then + return true + end + + if player:getAccountType() < ACCOUNT_TYPE_GOD then + return false + end + + logCommand(player, words, param) + + local resultId = db.storeQuery("SELECT `balance`, `name` FROM `players` WHERE group_id < 3 ORDER BY balance DESC LIMIT 10") + if resultId ~= false then + local str = "" + local x = 0 + repeat + x = x + 1 + str = str.."\n"..x.."- "..result.getDataString(resultId, "name").." ("..result.getDataInt(resultId, "balance")..")." + until not result.next(resultId) + result.free(resultId) + if str == "" then + str = "No highscore to show." + end + player:popupFYI("Current gold highscore for this server:\n" .. str) + else + player:sendCancelMessage("No highscore to show.") + end +return false +end + +gold_rank:separator(" ") +gold_rank:register() diff --git a/data/scripts/talkactions/god/house_owner.lua b/data/scripts/talkactions/god/house_owner.lua new file mode 100644 index 00000000000..4b8e680919e --- /dev/null +++ b/data/scripts/talkactions/god/house_owner.lua @@ -0,0 +1,31 @@ +local houseOwner = TalkAction("/owner") + +function houseOwner.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + local tile = Tile(player:getPosition()) + local house = tile and tile:getHouse() + if not house then + player:sendCancelMessage("You are not inside a house.") + return false + end + + if param == "" or param == "none" then + house:setOwnerGuid(0) + return false + end + + local targetPlayer = Player(param) + if not targetPlayer then + player:sendCancelMessage("Player not found.") + return false + end + + house:setOwnerGuid(targetPlayer:getGuid()) + return false +end + +houseOwner:separator(" ") +houseOwner:register() diff --git a/data/scripts/talkactions/god/info.lua b/data/scripts/talkactions/god/info.lua new file mode 100644 index 00000000000..9b7ca72ac91 --- /dev/null +++ b/data/scripts/talkactions/god/info.lua @@ -0,0 +1,42 @@ +local info = TalkAction("/info") + +function info.onSay(player, words, param) + local target = Player(param) + if not target then + player:sendCancelMessage("Player not found.") + return false + end + + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + if param == "" then + player:sendCancelMessage("Command param required.") + return false + end + + local targetIp = target:getIp() + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Name: " .. target:getName()) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Access: " .. (target:getGroup():getAccess() and "1" or "0")) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Level: " .. target:getLevel()) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Magic Level: " .. target:getMagicLevel()) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Speed: " .. target:getSpeed()) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Position: " .. string.format("(%0.5d / %0.5d / %0.3d)", target:getPosition().x, target:getPosition().y, target:getPosition().z)) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "IP: " .. Game.convertIpToString(targetIp)) + + local players = {} + for _, targetPlayer in ipairs(Game.getPlayers()) do + if targetPlayer:getIp() == targetIp and targetPlayer ~= target then + players[#players + 1] = targetPlayer:getName() .. " [" .. targetPlayer:getLevel() .. "]" + end + end + + if #players > 0 then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Other players on same IP: " .. table.concat(players, ", ") .. ".") + end + return false +end + +info:separator(" ") +info:register() diff --git a/data/scripts/talkactions/god/ip_ban.lua b/data/scripts/talkactions/god/ip_ban.lua new file mode 100644 index 00000000000..3e83c8c3ef6 --- /dev/null +++ b/data/scripts/talkactions/god/ip_ban.lua @@ -0,0 +1,49 @@ +local ipBanDays = 7 + +local ipBan = TalkAction("/ipban") + +function ipBan.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + if param == "" then + player:sendCancelMessage("Command param required.") + return false + end + + local resultId = db.storeQuery("SELECT `name`, `lastip` FROM `players` WHERE `name` = " .. db.escapeString(param)) + if resultId == false then + return false + end + + local targetName = result.getString(resultId, "name") + local targetIp = result.getNumber(resultId, "lastip") + result.free(resultId) + + local targetPlayer = Player(param) + if targetPlayer then + targetIp = targetPlayer:getIp() + targetPlayer:remove() + end + + if targetIp == 0 then + return false + end + + resultId = db.storeQuery("SELECT 1 FROM `ip_bans` WHERE `ip` = " .. targetIp) + if resultId ~= false then + player:sendTextMessage(MESSAGE_ADMINISTRADOR, targetName .. " is already IP banned.") + result.free(resultId) + return false + end + + local timeNow = os.time() + db.query("INSERT INTO `ip_bans` (`ip`, `reason`, `banned_at`, `expires_at`, `banned_by`) VALUES (" .. + targetIp .. ", '', " .. timeNow .. ", " .. timeNow + (ipBanDays * 86400) .. ", " .. player:getGuid() .. ")") + player:sendTextMessage(MESSAGE_ADMINISTRADOR, targetName .. " has been IP banned.") + return false +end + +ipBan:separator(" ") +ipBan:register() diff --git a/data/scripts/talkactions/god/kick.lua b/data/scripts/talkactions/god/kick.lua new file mode 100644 index 00000000000..a294be07cd3 --- /dev/null +++ b/data/scripts/talkactions/god/kick.lua @@ -0,0 +1,24 @@ +local kick = TalkAction("/kick") + +function kick.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + local target = Player(param) + if not target then + player:sendCancelMessage("Player not found.") + return false + end + + if target:getGroup():getAccess() then + player:sendCancelMessage("You cannot kick this player.") + return false + end + + target:remove() + return false +end + +kick:separator(" ") +kick:register() diff --git a/data/scripts/talkactions/god/looktype.lua b/data/scripts/talkactions/god/looktype.lua new file mode 100644 index 00000000000..b7327beb1ec --- /dev/null +++ b/data/scripts/talkactions/god/looktype.lua @@ -0,0 +1,53 @@ +-- keep it ordered +local invalidTypes = { + 1, 135, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 411, 415, 424, 439, 440, 468, 469, 474, 475, 476, 477, 478, + 479, 480, 481, 482, 483, 484, 485, 501, 518, 519, 520, 524, 525, 536, 543, + 549, 576, 581, 582, 597, 616, 623, 625, 638, 639, 640, 641, 642, 643, 645, + 646, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 700, 701, + 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 713, 715, 718, 719, 722, + 723, 737, 741, 742, 743, 744, 748, 751, 752, 753, 754, 755, 756, 757, 758, + 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, + 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, + 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, + 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, + 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, + 839, 840, 841, 847, 861, 864, 865, 866, 867, 871, 872, 880, 891, 892, 893, + 894, 895, 896, 897, 898, 911, 912, 917, 930, 941, 942, 946, 953, 954, 959, + 983, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, + 1008, 1009, 1010, 1012, 1014, 1015, 1022, 1028, 1074, 1075, 1080, 1081, 1082, + 1083, 1084, 1085, 1086, 1087, 1089, 1090, 1096, 1097, 1098, 1099, 1100, 1141, + 1145, 1153, 1154, 1155, 1156, 1160, 1170, 1171, 1172, 1176, 1177, 1178, 1182, + 1192, 1193, 1194, 1198, 1215, 1216, 1225, 1226, 1227, 1228, 1235, 1236, 1237, + 1238, 1239, 1240, 1241, 1242, 1250, 1254, 1263, 1267, 1273, 1274, 1287, 1302, + 1318, 1319, 1320, 1327, 1328, 1329, 1330, 1340, 1343, 1345, 1347, 1348, 1349, + 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, + 1368, 1369, 1370, 1374, 1375, 1376, +} + +local looktype = TalkAction("/looktype") + +function looktype.onSay(player, words, param) + if not player:getGroup():getAccess() then + return true + end + + if param == "" then + player:sendCancelMessage("Command param required.") + return false + end + + local lookType = tonumber(param) + if lookType >= 0 and lookType < 1384 and not table.contains(invalidTypes, lookType) then + local playerOutfit = player:getOutfit() + playerOutfit.lookType = lookType + player:setOutfit(playerOutfit) + else + player:sendCancelMessage("A look type with that id does not exist.") + end + return false +end + +looktype:separator(" ") +looktype:register() diff --git a/data/scripts/talkactions/god/magiceffect.lua b/data/scripts/talkactions/god/magiceffect.lua new file mode 100644 index 00000000000..6c4c96bc287 --- /dev/null +++ b/data/scripts/talkactions/god/magiceffect.lua @@ -0,0 +1,22 @@ +local magicEffect = TalkAction("/effect") + +function magicEffect.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + if param == "" then + player:sendCancelMessage("Command param required.") + return false + end + + local effect = tonumber(param) + if(effect ~= nil and effect > 0) then + player:getPosition():sendMagicEffect(effect) + end + + return false +end + +magicEffect:separator(" ") +magicEffect:register() diff --git a/data/scripts/talkactions/god/mc_check.lua b/data/scripts/talkactions/god/mc_check.lua new file mode 100644 index 00000000000..86821349eda --- /dev/null +++ b/data/scripts/talkactions/god/mc_check.lua @@ -0,0 +1,40 @@ +local mcCheck = TalkAction("/mc") + +function mcCheck.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + player:sendTextMessage(MESSAGE_ADMINISTRADOR, "Multiclient Check List:") + local ipList = {} + local players = Game.getPlayers() + for i = 1, #players do + local tmpPlayer = players[i] + local ip = tmpPlayer:getIp() + if ip ~= 0 then + local list = ipList[ip] + if not list then + ipList[ip] = {} + list = ipList[ip] + end + list[#list + 1] = tmpPlayer + end + end + + for ip, list in pairs(ipList) do + local listLength = #list + if listLength > 1 then + local tmpPlayer = list[1] + local message = ("%s: %s [%d]"):format(Game.convertIpToString(ip), tmpPlayer:getName(), tmpPlayer:getLevel()) + for i = 2, listLength do + tmpPlayer = list[i] + message = ("%s, %s [%d]"):format(message, tmpPlayer:getName(), tmpPlayer:getLevel()) + end + player:sendTextMessage(MESSAGE_ADMINISTRADOR, message .. ".") + end + end + return false +end + +mcCheck:separator(" ") +mcCheck:register() diff --git a/data/scripts/talkactions/god/open_server.lua b/data/scripts/talkactions/god/open_server.lua new file mode 100644 index 00000000000..efbcec5e070 --- /dev/null +++ b/data/scripts/talkactions/god/open_server.lua @@ -0,0 +1,14 @@ +local openServer = TalkAction("/openserver") + +function openServer.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + Game.setGameState(GAME_STATE_NORMAL) + player:sendTextMessage(MESSAGE_ADMINISTRADOR, "Server is now open.") + return false +end + +openServer:separator(" ") +openServer:register() diff --git a/data/scripts/talkactions/god/position.lua b/data/scripts/talkactions/god/position.lua new file mode 100644 index 00000000000..b019020d8d3 --- /dev/null +++ b/data/scripts/talkactions/god/position.lua @@ -0,0 +1,25 @@ +local position = TalkAction("/pos", "!pos") + +function position.onSay(player, words, param) + + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + local param = string.gsub(param, "%s+", "") + local position = player:getPosition() + local tile = load("return "..param)() + local split = param:split(",") + if type(tile) == "table" and tile.x and tile.y and tile.z then + player:teleportTo(Position(tile.x, tile.y, tile.z)) + elseif split and param ~= "" then + player:teleportTo(Position(split[1], split[2], split[3])) + elseif param == "" then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your current position is: \z + " .. position.x .. ", " .. position.y .. ", " .. position.z .. ".") + end + return false +end + +position:separator(" ") +position:register() diff --git a/data/scripts/talkactions/god/push_creature.lua b/data/scripts/talkactions/god/push_creature.lua new file mode 100644 index 00000000000..0cabb24f089 --- /dev/null +++ b/data/scripts/talkactions/god/push_creature.lua @@ -0,0 +1,34 @@ +local pushCreature = TalkAction("/c") + +function pushCreature.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + if param == "" then + player:sendCancelMessage("Command param required.") + return false + end + + local creature = Creature(param) + if not creature then + player:sendCancelMessage("A creature with that name could not be found.") + return false + end + + local oldPosition = creature:getPosition() + local newPosition = creature:getClosestFreePosition(player:getPosition(), false) + if newPosition.x == 0 then + player:sendCancelMessage("You can not teleport " .. creature:getName() .. ".") + return false + elseif creature:teleportTo(newPosition) then + if not creature:isInGhostMode() then + oldPosition:sendMagicEffect(CONST_ME_POFF) + newPosition:sendMagicEffect(CONST_ME_TELEPORT) + end + end + return false +end + +pushCreature:separator(" ") +pushCreature:register() diff --git a/data/scripts/talkactions/god/push_town.lua b/data/scripts/talkactions/god/push_town.lua new file mode 100644 index 00000000000..c967dd462ac --- /dev/null +++ b/data/scripts/talkactions/god/push_town.lua @@ -0,0 +1,12 @@ +local pushTown = TalkAction("/t") + +function pushTown.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + player:teleportTo(player:getTown():getTemplePosition()) + return false +end + +pushTown:register() diff --git a/data/scripts/talkactions/god/reload.lua b/data/scripts/talkactions/god/reload.lua new file mode 100644 index 00000000000..cc92e6e940f --- /dev/null +++ b/data/scripts/talkactions/god/reload.lua @@ -0,0 +1,74 @@ +local reloadTypes = { + ["all"] = RELOAD_TYPE_ALL, + + ["channel"] = RELOAD_TYPE_CHAT, + ["chat"] = RELOAD_TYPE_CHAT, + ["chatchannels"] = RELOAD_TYPE_CHAT, + + ["config"] = RELOAD_TYPE_CONFIG, + ["configuration"] = RELOAD_TYPE_CONFIG, + + ["events"] = RELOAD_TYPE_EVENTS, + + ["items"] = RELOAD_TYPE_ITEMS, + + ["module"] = RELOAD_TYPE_MODULES, + ["modules"] = RELOAD_TYPE_MODULES, + + ["monster"] = RELOAD_TYPE_MONSTERS, + ["monsters"] = RELOAD_TYPE_MONSTERS, + + ["mount"] = RELOAD_TYPE_MOUNTS, + ["mounts"] = RELOAD_TYPE_MOUNTS, + + ["npc"] = RELOAD_TYPE_NPCS, + ["npcs"] = RELOAD_TYPE_NPCS, + + ["raid"] = RELOAD_TYPE_RAIDS, + ["raids"] = RELOAD_TYPE_RAIDS, + + ["rate"] = RELOAD_TYPE_STAGES, + ["rates"] = RELOAD_TYPE_STAGES, + + ["scripts"] = RELOAD_TYPE_SCRIPTS, + + ["spell"] = RELOAD_TYPE_SPELLS, + ["spells"] = RELOAD_TYPE_SPELLS, + + ["stage"] = RELOAD_TYPE_STAGES, + ["stages"] = RELOAD_TYPE_STAGES, + + ["global"] = RELOAD_TYPE_GLOBAL, + ["libs"] = RELOAD_TYPE_GLOBAL +} + +local reload = TalkAction("/reload") + +function reload.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + if param == "" then + player:sendCancelMessage("Command param required.") + return false + end + + logCommand(player, words, param) + + local reloadType = reloadTypes[param:lower()] + if reloadType then + Game.reload(reloadType) + player:sendTextMessage(MESSAGE_ADMINISTRADOR, string.format("Reloaded %s.", param:lower())) + Spdlog.info("Reloaded " .. param:lower()) + return true + elseif not reloadType then + player:sendCancelMessage("Reload type not found.") + Spdlog.warn("[reload.onSay] - Reload type '".. param.. "' not found") + return false + end + return false +end + +reload:separator(" ") +reload:register() diff --git a/data/scripts/talkactions/god/remove_thing.lua b/data/scripts/talkactions/god/remove_thing.lua new file mode 100644 index 00000000000..6b05c66aed1 --- /dev/null +++ b/data/scripts/talkactions/god/remove_thing.lua @@ -0,0 +1,38 @@ +local removeThing = TalkAction("/r") + +function removeThing.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + local position = player:getPosition() + position:getNextPosition(player:getDirection()) + + local tile = Tile(position) + if not tile then + player:sendCancelMessage("Object not found.") + return false + end + + local thing = tile:getTopVisibleThing(player) + if not thing then + player:sendCancelMessage("Thing not found.") + return false + end + + if thing:isCreature() then + thing:remove() + elseif thing:isItem() then + if thing == tile:getGround() then + player:sendCancelMessage("You may not remove a ground tile.") + return false + end + thing:remove(tonumber(param) or -1) + end + + position:sendMagicEffect(CONST_ME_MAGIC_RED) + return false +end + +removeThing:separator(" ") +removeThing:register() diff --git a/data/scripts/talkactions/god/save.lua b/data/scripts/talkactions/god/save.lua new file mode 100644 index 00000000000..2cc77c2b1e1 --- /dev/null +++ b/data/scripts/talkactions/god/save.lua @@ -0,0 +1,28 @@ +local savingEvent = 0 +function saveLoop(delay) + saveServer() + SaveHirelings() + Spdlog.info("Saved Hirelings") + if delay > 0 then + savingEvent = addEvent(saveLoop, delay, delay) + end +end + +local save = TalkAction("/save") + +function save.onSay(player, words, param) + if player:getGroup():getAccess() then + if isNumber(param) then + stopEvent(savingEvent) + saveLoop(tonumber(param) * 60 * 1000) + else + saveServer() + SaveHirelings() + Spdlog.info("Saved Hirelings") + player:sendTextMessage(MESSAGE_ADMINISTRADOR, "Server is saved ...") + end + end +end + +save:separator(" ") +save:register() diff --git a/data/scripts/talkactions/god/set_light.lua b/data/scripts/talkactions/god/set_light.lua new file mode 100644 index 00000000000..5c6e192ec84 --- /dev/null +++ b/data/scripts/talkactions/god/set_light.lua @@ -0,0 +1,43 @@ +--local luz = {240, 218, 1, 6, 7, 36, 215} +--[[ +green: 30 +blue: 1065 or 809 or 17 +red: 1020 +purple: 375 or 845 or 667 or 155 or 917 + +]] + +local set_light = TalkAction("/setlight") + +function set_light.onSay(player, words, param) + if not player:getGroup():getAccess() then + return true + end + + if player:getAccountType() < ACCOUNT_TYPE_GOD then + return false + end + + logCommand(player, words, param) + + local split = param:split(",") + + local color = split[1] + if color == nil then + player:sendCancelMessage("You need to specify the light color.") + return false + end + local intensity = tonumber(split[2]) or 4--32 + + if tonumber(color) and tonumber(color) <= 1500 and intensity >= 0 and intensity < 33 then + --player:setLight(tonumber(color) >= 0 and luz[tonumber(color)] or 0, intensity) + player:setLight(tonumber(color) >= 0 and tonumber(color) or 0, intensity) + else + player:sendCancelMessage("Use like this: /setlight color (0-".. 1500 .."), (1-32). The first param is color and the second is intensity.") + end + + return false +end + +set_light:separator(" ") +set_light:register() \ No newline at end of file diff --git a/data/scripts/talkactions/god/skip_tiles.lua b/data/scripts/talkactions/god/skip_tiles.lua new file mode 100644 index 00000000000..caf44a87fb5 --- /dev/null +++ b/data/scripts/talkactions/god/skip_tiles.lua @@ -0,0 +1,32 @@ +local skipTiles = TalkAction("/a") + +function skipTiles.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + if param == "" then + player:sendCancelMessage("Command param required.") + return false + end + + local steps = tonumber(param) + if not steps then + return false + end + + local position = player:getPosition() + position:getNextPosition(player:getDirection(), steps) + + position = player:getClosestFreePosition(position, false) + if position.x == 0 then + player:sendCancelMessage("You cannot teleport there.") + return false + end + + player:teleportTo(position) + return false +end + +skipTiles:separator(" ") +skipTiles:register() diff --git a/data/scripts/talkactions/god/spy.lua b/data/scripts/talkactions/god/spy.lua new file mode 100644 index 00000000000..aa62a0f7942 --- /dev/null +++ b/data/scripts/talkactions/god/spy.lua @@ -0,0 +1,80 @@ +local function getItemsInContainer(cont, sep) + local text = "" + local tsep = "" + local count = "" + for i=1, sep do + tsep = tsep.."-" + end + tsep = tsep..">" + for i=0, getContainerSize(cont.uid)-1 do + local item = getContainerItem(cont.uid, i) + if not isContainer(item.uid) then + if item.type > 0 then + count = "("..item.type.."x)" + else + count = "" + end + text = text.."\n"..tsep..ItemType(item.itemid):getName().." "..count + else + if getContainerSize(item.uid) > 0 then + text = text.."\n"..tsep..ItemType(item.itemd):getName() + text = text..getItemsInContainer(item, sep+2) + else + text = text.."\n"..tsep..ItemType(item.itemid):getName() + end + end + end +return text +end + +local spy = TalkAction("/spy") + +function spy.onSay(cid, words, param) + if not cid:getGroup():getAccess() then + return true + end + + if cid:getAccountType() < ACCOUNT_TYPE_GAMEMASTER then + return false + end + + logCommand(Player(cid), words, param) + + if(param == "") then + cid:sendCancelMessage("Write the name of the character to be spyed.") + return false + end + + local slotName = {"Helmet", "Amulet", "Backpack", "Armor", "Right Hand", "Left Hand", "Legs", "Boots", "Ring", "Arrow"} + local player = Player(param) + + if player and player:isPlayer() then + local text = "Equipments of "..Creature(player):getName() + for i=1, 10 do + text = text.."\n\n" + local item = player:getSlotItem(i) + if item and item.itemid > 0 then + if isContainer(item.uid) then + text = text..slotName[i]..": "..ItemType(item.itemid):getName() ..getItemsInContainer(item, 1) + else + local count = "" + if item.type > 0 then + count = "("..item.type.."x)" + else + count = "" + end + text = text..slotName[i]..": "..ItemType(item.itemid):getName().." "..count + end + else + text = text..slotName[i]..": Empty" + end + end + cid:showTextDialog(6528, text) + else + cid:sendCancelMessage("This player is offline or doesn't exist.") + end + return false +end + +spy:separator(" ") +spy:register() diff --git a/data/scripts/talkactions/god/start_raid.lua b/data/scripts/talkactions/god/start_raid.lua new file mode 100644 index 00000000000..094d94c941b --- /dev/null +++ b/data/scripts/talkactions/god/start_raid.lua @@ -0,0 +1,24 @@ +local startRaid = TalkAction("/raid") + +function startRaid.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + if param == "" then + player:sendCancelMessage("Command param required.") + return false + end + + logCommand(player, words, param) + local returnValue = Game.startRaid(param) + if returnValue ~= RETURNVALUE_NOERROR then + player:sendTextMessage(MESSAGE_ADMINISTRADOR, Game.getReturnMessage(returnValue)) + else + player:sendTextMessage(MESSAGE_ADMINISTRADOR, "Raid started.") + end + return false +end + +startRaid:separator(" ") +startRaid:register() diff --git a/data/scripts/talkactions/god/storage_add.lua b/data/scripts/talkactions/god/storage_add.lua new file mode 100644 index 00000000000..401cffd3a13 --- /dev/null +++ b/data/scripts/talkactions/god/storage_add.lua @@ -0,0 +1,39 @@ +-- /addstorage ,[=1],[=self] + +local storage = TalkAction("/addstorage") + +function storage.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + -- Sanity check for parameters + if param == "" then + player:sendCancelMessage("You need to pass at least the storage that will be set.") + return false + end + + local split = param:split(",") + local value = 1 -- Check if it was passed some value to be set to the storage + if split[2] then + value = split[2] + end + + -- Check if it should add storage to another player + if split[3] then + local targetPlayer = Player(param[3]) + if not targetPlayer then + player:sendCancelMessage("Player not found.") + return false + else + targetPlayer:setStorageValue(split[1], value) + return false + end + else + player:setStorageValue(split[1], value) + end + return false +end + +storage:separator(" ") +storage:register() diff --git a/data/scripts/talkactions/god/storage_get.lua b/data/scripts/talkactions/god/storage_get.lua new file mode 100644 index 00000000000..823d253e6b0 --- /dev/null +++ b/data/scripts/talkactions/god/storage_get.lua @@ -0,0 +1,35 @@ +local storageGet = TalkAction("/get") + +function storageGet.onSay(cid, words, param) + local player = Player(cid) + if not player:getGroup():getAccess() then + return true + end + + if player:getAccountType() < ACCOUNT_TYPE_GOD then + return false + end + + local split = param:split(",") + if split[2] == nil then + player:sendCancelMessage("Insufficient parameters.") + return false + end + + local target = Player(split[1]) + if target == nil then + player:sendCancelMessage("A player with that name is not online.") + return false + end + + -- Trim left + split[2] = split[2]:gsub("^%s*(.-)$", "%1") + + local ch = split[2] + sto=getPlayerStorageValue(getPlayerByName(split[1]), tonumber(ch)) + doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, "The storage with id: "..tonumber(ch).." from player "..split[1].." is: "..sto..".") + return false +end + +storageGet:separator(" ") +storageGet:register() diff --git a/data/scripts/talkactions/god/storage_set.lua b/data/scripts/talkactions/god/storage_set.lua new file mode 100644 index 00000000000..48c3ed5c229 --- /dev/null +++ b/data/scripts/talkactions/god/storage_set.lua @@ -0,0 +1,36 @@ +local storageSet = TalkAction("/set") + +function storageSet.onSay(cid, words, param) + local player = Player(cid) + if not player:getGroup():getAccess() then + return true + end + + if player:getAccountType() < ACCOUNT_TYPE_GOD then + return false + end + + local split = param:split(",") + if split[2] == nil then + player:sendCancelMessage("Insufficient parameters.") + return false + end + + local target = Player(split[1]) + if target == nil then + player:sendCancelMessage("A player with that name is not online.") + return false + end + + -- Trim left + split[2] = split[2]:gsub("^%s*(.-)$", "%1") + split[3] = split[3]:gsub("^%s*(.-)$", "%1") + local ch = split[2] + local ch2 = split[3] + setPlayerStorageValue(getPlayerByName(split[1]), tonumber(ch), tonumber(ch2)) + doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, "The storage with id: "..tonumber(ch).." from player "..split[1].." is now: "..ch2..".") + return false +end + +storageSet:separator(" ") +storageSet:register() diff --git a/data/scripts/talkactions/god/teleport_to_creature.lua b/data/scripts/talkactions/god/teleport_to_creature.lua new file mode 100644 index 00000000000..ec410655dc5 --- /dev/null +++ b/data/scripts/talkactions/god/teleport_to_creature.lua @@ -0,0 +1,23 @@ +local teleportToCreature = TalkAction("/goto") + +function teleportToCreature.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + if param == "" then + player:sendCancelMessage("Command param required.") + return false + end + + local target = Creature(param) + if target then + player:teleportTo(target:getPosition()) + else + player:sendCancelMessage("Creature not found.") + end + return false +end + +teleportToCreature:separator(" ") +teleportToCreature:register() diff --git a/data/scripts/talkactions/god/teleport_to_town.lua b/data/scripts/talkactions/god/teleport_to_town.lua new file mode 100644 index 00000000000..a0a6263731d --- /dev/null +++ b/data/scripts/talkactions/god/teleport_to_town.lua @@ -0,0 +1,23 @@ +local teleportToTown = TalkAction("/town") + +function teleportToTown.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + if param == "" then + player:sendCancelMessage("Command param required.") + return false + end + + local town = Town(param) or Town(tonumber(param)) + if town then + player:teleportTo(town:getTemplePosition()) + else + player:sendCancelMessage("Town not found.") + end + return false +end + +teleportToTown:separator(" ") +teleportToTown:register() diff --git a/data/scripts/talkactions/god/unban.lua b/data/scripts/talkactions/god/unban.lua new file mode 100644 index 00000000000..16d203a11cc --- /dev/null +++ b/data/scripts/talkactions/god/unban.lua @@ -0,0 +1,26 @@ +local unban = TalkAction("/unban") + +function unban.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + if param == "" then + player:sendCancelMessage("Command param required.") + return false + end + + local resultId = db.storeQuery("SELECT `account_id`, `lastip` FROM `players` WHERE `name` = " .. db.escapeString(param)) + if resultId == false then + return false + end + + db.asyncQuery("DELETE FROM `account_bans` WHERE `account_id` = " .. result.getNumber(resultId, "account_id")) + db.asyncQuery("DELETE FROM `ip_bans` WHERE `ip` = " .. result.getNumber(resultId, "lastip")) + result.free(resultId) + player:sendTextMessage(MESSAGE_ADMINISTRADOR, param .. " has been unbanned.") + return false +end + +unban:separator(" ") +unban:register() diff --git a/data/scripts/talkactions/god/up.lua b/data/scripts/talkactions/god/up.lua new file mode 100644 index 00000000000..5db69203377 --- /dev/null +++ b/data/scripts/talkactions/god/up.lua @@ -0,0 +1,15 @@ +local up = TalkAction("/up") + +function up.onSay(player, words, param) + if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then + return true + end + + local position = player:getPosition() + position.z = position.z - 1 + player:teleportTo(position) + return false +end + +up:separator(" ") +up:register() diff --git a/data/scripts/talkactions/player/aol.lua b/data/scripts/talkactions/player/aol.lua new file mode 100644 index 00000000000..7394225826f --- /dev/null +++ b/data/scripts/talkactions/player/aol.lua @@ -0,0 +1,14 @@ +local aol = TalkAction("!aol") + +function aol.onSay(player, words, param) + if player:removeMoneyNpc(50000) then + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + player:addItem(2173, 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have bought an amulet of loss for 50K!") + else + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:sendCancelMessage("You do not have enough money.") + end +end + +aol:register() diff --git a/data/scripts/talkactions/player/bless.lua b/data/scripts/talkactions/player/bless.lua new file mode 100644 index 00000000000..cc373147141 --- /dev/null +++ b/data/scripts/talkactions/player/bless.lua @@ -0,0 +1,7 @@ +local bless = TalkAction("!bless") + +function bless.onSay(player, words, param) + return Blessings.BuyAllBlesses(player) +end + +bless:register() diff --git a/data/scripts/talkactions/player/buy_house.lua b/data/scripts/talkactions/player/buy_house.lua new file mode 100644 index 00000000000..be37ba81aa3 --- /dev/null +++ b/data/scripts/talkactions/player/buy_house.lua @@ -0,0 +1,46 @@ +local buyHouse = TalkAction("!buyhouse") + +function buyHouse.onSay(player, words, param) + local housePrice = configManager.getNumber(configKeys.HOUSE_PRICE) + if housePrice == -1 then + return true + end + + if not player:isPremium() then + player:sendCancelMessage("You need a premium account.") + return false + end + + local position = player:getPosition() + position:getNextPosition(player:getDirection()) + + local tile = Tile(position) + local house = tile and tile:getHouse() + if not house then + player:sendCancelMessage("You have to be looking at the door of the house you would like to buy.") + return false + end + + if house:getOwnerGuid() > 0 then + player:sendCancelMessage("This house already has an owner.") + return false + end + + if player:getHouse() then + player:sendCancelMessage("You are already the owner of a house.") + return false + end + + local price = house:getTileCount() * housePrice + if not player:removeMoneyNpc(price) then + player:sendCancelMessage("You do not have enough money.") + return false + end + + house:setOwnerGuid(player:getGuid()) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have successfully bought this house, be sure to have the money for the rent in the bank.") + return false +end + +buyHouse:separator(" ") +buyHouse:register() diff --git a/data/scripts/talkactions/player/leave_house.lua b/data/scripts/talkactions/player/leave_house.lua new file mode 100644 index 00000000000..e8bfae421db --- /dev/null +++ b/data/scripts/talkactions/player/leave_house.lua @@ -0,0 +1,26 @@ +local leaveHouse = TalkAction("!leavehouse") + +function leaveHouse.onSay(player, words, param) + local position = player:getPosition() + local tile = Tile(position) + local house = tile and tile:getHouse() + if not house then + player:sendCancelMessage("You are not inside a house.") + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + if house:getOwnerGuid() ~= player:getGuid() then + player:sendCancelMessage("You are not the owner of this house.") + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + house:setOwnerGuid(0) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have successfully left your house.") + position:sendMagicEffect(CONST_ME_POFF) + return false +end + +leaveHouse:separator(" ") +leaveHouse:register() diff --git a/data/scripts/talkactions/player/online.lua b/data/scripts/talkactions/player/online.lua new file mode 100644 index 00000000000..7d57fea312b --- /dev/null +++ b/data/scripts/talkactions/player/online.lua @@ -0,0 +1,26 @@ +local maxPlayersPerMessage = 10 +local playersOnline = TalkAction("!online") + +function playersOnline.onSay(player, words, param) + local hasAccess = player:getGroup():getAccess() + local players = Game.getPlayers() + local onlineList = {} + + for _, targetPlayer in ipairs(players) do + if hasAccess or not targetPlayer:isInGhostMode() then + table.insert(onlineList, ("%s [%d]"):format(targetPlayer:getName(), targetPlayer:getLevel())) + end + end + + local playersOnlineList = #onlineList + player:sendTextMessage(MESSAGE_ATTENTION, ("%d players online!"):format(playersOnlineList)) + + for i = 1, playersOnlineList, maxPlayersPerMessage do + local j = math.min(i + maxPlayersPerMessage - 1, playersOnlineList) + local msg = table.concat(onlineList, ", ", i, j) .. "." + player:sendTextMessage(MESSAGE_ATTENTION, msg) + end + return false +end + +playersOnline:register() diff --git a/data/scripts/talkactions/player/sell_house.lua b/data/scripts/talkactions/player/sell_house.lua new file mode 100644 index 00000000000..34c46e8f91f --- /dev/null +++ b/data/scripts/talkactions/player/sell_house.lua @@ -0,0 +1,24 @@ +local sellHouse = TalkAction("!sellhouse") + +function sellHouse.onSay(player, words, param) + local tradePartner = Player(param) + if not tradePartner or tradePartner == player then + player:sendCancelMessage("Trade player not found.") + return false + end + + local house = player:getTile():getHouse() + if not house then + player:sendCancelMessage("You must stand in your house to initiate the trade.") + return false + end + + local returnValue = house:startTrade(player, tradePartner) + if returnValue ~= RETURNVALUE_NOERROR then + player:sendCancelMessage(returnValue) + end + return false +end + +sellHouse:separator(" ") +sellHouse:register() diff --git a/data/scripts/talkactions/player/server_info.lua b/data/scripts/talkactions/player/server_info.lua new file mode 100644 index 00000000000..ba5cb3d34e1 --- /dev/null +++ b/data/scripts/talkactions/player/server_info.lua @@ -0,0 +1,19 @@ +local serverInfo = TalkAction("!serverinfo") + +function serverInfo.onSay(player, words, param) + local configRateSkill = configManager.getNumber(configKeys.RATE_SKILL) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Server Info:" + .. "\nExp rate: " .. getRateFromTable(experienceStages, player:getLevel(), configManager.getNumber(configKeys.RATE_EXP)) + .. "\nSword Skill rate: " .. getRateFromTable(skillsStages, player:getEffectiveSkillLevel(SKILL_SWORD), configRateSkill) + .. "\nClub Skill rate: " .. getRateFromTable(skillsStages, player:getEffectiveSkillLevel(SKILL_CLUB), configRateSkill) + .. "\nAxe Skill rate: " .. getRateFromTable(skillsStages, player:getEffectiveSkillLevel(SKILL_AXE), configRateSkill) + .. "\nDistance Skill rate: " .. getRateFromTable(skillsStages, player:getEffectiveSkillLevel(SKILL_DISTANCE), configRateSkill) + .. "\nShield Skill rate: " .. getRateFromTable(skillsStages, player:getEffectiveSkillLevel(SKILL_SHIELD), configRateSkill) + .. "\nFist Skill rate: " .. getRateFromTable(skillsStages, player:getEffectiveSkillLevel(SKILL_FIST), configRateSkill) + .. "\nMagic rate: " .. getRateFromTable(magicLevelStages, player:getMagicLevel(), configManager.getNumber(configKeys.RATE_MAGIC)) + .. "\nLoot rate: " .. configManager.getNumber(configKeys.RATE_LOOT)) + return false +end + +serverInfo:separator(" ") +serverInfo:register() diff --git a/data/scripts/talkactions/player/tibia_timer.lua b/data/scripts/talkactions/player/tibia_timer.lua new file mode 100644 index 00000000000..9fb1bdae198 --- /dev/null +++ b/data/scripts/talkactions/player/tibia_timer.lua @@ -0,0 +1,11 @@ +local statusTime = TalkAction("!time") +function statusTime.onSay(player, words, param) + local time = getWorldTime() + local light = getWorldLight() + local dayOrNight = getTibiaTimerDayOrNight(getFormattedWorldTime(time)) + + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Now is ".. dayOrNight .." in Tibia Time, time now is "..getFormattedWorldTime(time)..".") + return false +end + +statusTime:register() diff --git a/data/scripts/talkactions/player/tutor_position.lua b/data/scripts/talkactions/player/tutor_position.lua new file mode 100644 index 00000000000..d14d2ea5a60 --- /dev/null +++ b/data/scripts/talkactions/player/tutor_position.lua @@ -0,0 +1,15 @@ +local tutorPosition = TalkAction("!position") + +function tutorPosition.onSay(player, words, param) + + if player:getAccountType() == ACCOUNT_TYPE_NORMAL then + return true + end + + local position = player:getPosition() + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your current position is: \z + " .. position.x .. ", " .. position.y .. ", " .. position.z .. ".") + return false +end + +tutorPosition:register() diff --git a/data/scripts/weapons/dawnport_weapon.lua b/data/scripts/weapons/dawnport_weapon.lua new file mode 100644 index 00000000000..f3cc3b507eb --- /dev/null +++ b/data/scripts/weapons/dawnport_weapon.lua @@ -0,0 +1,47 @@ +-- the chille +local dawnportWeapon = Weapon(WEAPON_WAND) + +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ICE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 0.4) + 3 + local max = (level / 5) + (maglevel * 0.7) + 7 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +dawnportWeapon.onUseWeapon = function(player, variant) + return combat:execute(player, variant) +end + +dawnportWeapon:id(23721) +dawnportWeapon:mana(1) +dawnportWeapon:range(3) +dawnportWeapon:register() + +-- the scorcher +local dawnportWeapon = Weapon(WEAPON_WAND) + +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 0.4) + 3 + local max = (level / 5) + (maglevel * 0.7) + 7 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +dawnportWeapon.onUseWeapon = function(player, variant) + return combat:execute(player, variant) +end + +dawnportWeapon:id(23719) +dawnportWeapon:mana(1) +dawnportWeapon:range(3) +dawnportWeapon:register() diff --git a/data/scripts/weapons/scripts/burst_arrow.lua b/data/scripts/weapons/scripts/burst_arrow.lua new file mode 100644 index 00000000000..a86b7f933cf --- /dev/null +++ b/data/scripts/weapons/scripts/burst_arrow.lua @@ -0,0 +1,31 @@ +local area = createCombatArea({ + {1, 1, 1}, + {1, 3, 1}, + {1, 1, 1} + }) + +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_BURSTARROW) +combat:setParameter(COMBAT_PARAM_BLOCKARMOR, true) +combat:setFormula(COMBAT_FORMULA_SKILL, 0, 0, 1, 0) +combat:setArea(area) + +local burstArrow = Weapon(WEAPON_AMMO) + +burstArrow.onUseWeapon = function(player, variant) + if player:getSkull() == SKULL_BLACK then + return false + end + + return combat:execute(player, variant) +end + +burstArrow:id(2546) +burstArrow:attack(27) +burstArrow:action("removecount") +burstArrow:ammoType("arrow") +burstArrow:shootType(CONST_ANI_BURSTARROW) +burstArrow:maxHitChance(100) +burstArrow:register() diff --git a/data/scripts/weapons/scripts/diamond_arrow.lua b/data/scripts/weapons/scripts/diamond_arrow.lua new file mode 100644 index 00000000000..2d5f3e2415e --- /dev/null +++ b/data/scripts/weapons/scripts/diamond_arrow.lua @@ -0,0 +1,32 @@ +local area = createCombatArea({ + {0, 1, 1, 1, 0}, + {1, 1, 1, 1, 1}, + {1, 1, 3, 1, 1}, + {1, 1, 1, 1, 1}, + {0, 1, 1, 1, 0}, + }) + +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_DIAMONDARROW) +combat:setParameter(COMBAT_PARAM_BLOCKARMOR, true) +combat:setFormula(COMBAT_FORMULA_SKILL, 0, 0, 1, 0) +combat:setArea(area) + +local diamondArrow = Weapon(WEAPON_AMMO) + +function diamondArrow.onUseWeapon(player, variant) + return combat:execute(player, variant) +end + +diamondArrow:id(29057) +diamondArrow:id(40736) +diamondArrow:level(150) +diamondArrow:attack(37) +diamondArrow:action("removecount") +diamondArrow:ammoType("arrow") +diamondArrow:shootType(CONST_ANI_DIAMONDARROW) +diamondArrow:maxHitChance(100) +diamondArrow:wieldUnproperly(true) +diamondArrow:register() diff --git a/data/scripts/weapons/scripts/poison_arrow.lua b/data/scripts/weapons/scripts/poison_arrow.lua new file mode 100644 index 00000000000..8f946e521b1 --- /dev/null +++ b/data/scripts/weapons/scripts/poison_arrow.lua @@ -0,0 +1,26 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISONARROW) +combat:setParameter(COMBAT_PARAM_BLOCKARMOR, true) +combat:setFormula(COMBAT_FORMULA_SKILL, 0, 0, 1, 0) + +local condition = Condition(CONDITION_POISON) +condition:setParameter(CONDITION_PARAM_DELAYED, true) +condition:addDamage(4, 4000, -3) +condition:addDamage(9, 4000, -2) +condition:addDamage(20, 4000, -1) +combat:addCondition(condition) + +local poisonArrow = Weapon(WEAPON_AMMO) + +function poisonArrow.onUseWeapon(player, variant) + return combat:execute(player, variant) +end + +poisonArrow:id(2545) +poisonArrow:attack(21) +poisonArrow:action("removecount") +poisonArrow:ammoType("arrow") +poisonArrow:shootType(CONST_ANI_POISONARROW) +poisonArrow:maxHitChance(91) +poisonArrow:register() diff --git a/data/scripts/weapons/scripts/viper_star.lua b/data/scripts/weapons/scripts/viper_star.lua new file mode 100644 index 00000000000..853aa12f37f --- /dev/null +++ b/data/scripts/weapons/scripts/viper_star.lua @@ -0,0 +1,37 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_GREENSTAR) +combat:setParameter(COMBAT_PARAM_BLOCKARMOR, true) +combat:setFormula(COMBAT_FORMULA_SKILL, 0, 0, 1, 0) + +local condition = Condition(CONDITION_POISON) +condition:setParameter(CONDITION_PARAM_DELAYED, true) +condition:addDamage(10, 4000, -2) +condition:addDamage(20, 4000, -1) + +local secondCombat = Combat() +secondCombat:setParameter(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE) +secondCombat:addCondition(condition) + +local viperStar = Weapon(WEAPON_DISTANCE) + +function viperStar.onUseWeapon(player, variant) + local boolean = combat:execute(player, variant) + if not boolean then + return false + end + + local target = variant:getNumber() + if target ~= 0 then + boolean = secondCombat:execute(player, variant) + end + return boolean +end + +viperStar:id(7366) +viperStar:attack(28) +viperStar:breakChance(9) +viperStar:shootType(CONST_ANI_GREENSTAR) +viperStar:maxHitChance(76) +viperStar:register() + diff --git a/data/scripts/weapons/unscripted_weapons.lua b/data/scripts/weapons/unscripted_weapons.lua new file mode 100644 index 00000000000..d3c26b74bd3 --- /dev/null +++ b/data/scripts/weapons/unscripted_weapons.lua @@ -0,0 +1,4326 @@ +local weapons = { + { + itemId = 40737, + type = WEAPON_AMMO, + level = 150, + unproperly = true, + action = "removecount" + }, -- spectral bolt (no decay) + { + itemId = 40357, + type = WEAPON_WAND, + wandType = "earth", + level = 150, + mana = 19, + damage = {80, 100}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- jungle wand + { + itemId = 40356, + type = WEAPON_WAND, + wandType = "ice", + level = 150, + mana = 19, + damage = {80, 100}, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- jungle rod + { + itemId = 40353, + type = WEAPON_DISTANCE, + level = 150, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- jungle bow + { + itemId = 40350, + type = WEAPON_AXE, + level = 150, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- throwing axe + { + itemId = 40349, + type = WEAPON_CLUB, + level = 150, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- jungle flail + { + itemId = 38990, + type = WEAPON_SWORD, + level = 270, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- lion longsword + { + itemId = 39089, + type = WEAPON_CLUB, + level = 270, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- lion hammer + { + itemId = 39088, + type = WEAPON_AXE, + level = 270, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- lion axe + { + itemId = 38987, + type = WEAPON_WAND, + wandType = "ice", + level = 220, + mana = 21, + damage = {89, 109}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- lion wand + { + itemId = 38986, + type = WEAPON_WAND, + wandType = "ice", + level = 270, + mana = 20, + damage = {85, 105}, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- lion rod + { + itemId = 38985, + type = WEAPON_DISTANCE, + level = 270, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- lion longbow + { + itemId = 38926, + type = WEAPON_WAND, + wandType = "ice", + level = 400, + mana = 21, + damage = {98, 118}, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- soulhexer rod + { + itemId = 38925, + type = WEAPON_WAND, + wandType = "death", + level = 400, + mana = 21, + damage = {100, 120}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- soultainter wand + { + itemId = 38924, + type = WEAPON_DISTANCE, + level = 400, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- soulpiercer crossbow + { + itemId = 38923, + type = WEAPON_DISTANCE, + level = 400, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- soulbleeder bow + { + itemId = 38922, + type = WEAPON_CLUB, + level = 400, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- soulmaimer club + { + itemId = 38921, + type = WEAPON_CLUB, + level = 400, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- soulcrusher club + { + itemId = 38920, + type = WEAPON_AXE, + level = 400, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- souleater axe + { + itemId = 38919, + type = WEAPON_AXE, + level = 400, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- soulbiter axe + { + itemId = 38918, + type = WEAPON_SWORD, + level = 400, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- soulshredder sword + { + itemId = 38917, + type = WEAPON_SWORD, + level = 400, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- soulcutter sword + { + itemId = 37451, + type = WEAPON_AXE, + level = 180, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- phantasmal axe + { + itemId = 36928, + type = WEAPON_CLUB + }, -- meat hammer + { + itemId = 36449, + type = WEAPON_SWORD, + level = 250, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- tagralt blade + { + itemId = 36416, + type = WEAPON_DISTANCE, + level = 250, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- bow of cataclysm + { + itemId = 36415, + type = WEAPON_CLUB, + level = 220, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- mortal mace + { + itemId = 35235, + type = WEAPON_WAND, + wandType = "earth", + level = 220, + mana = 21, + damage = {70, 110}, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- cobra rod + { + itemId = 35234, + type = WEAPON_WAND, + wandType = "energy", + level = 270, + mana = 22, + damage = {94, 100}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- cobra wand + { + itemId = 35233, + type = WEAPON_SWORD, + level = 220, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- cobra sword + { + itemId = 35231, + type = WEAPON_AXE, + level = 220, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- cobra axe + { + itemId = 35230, + type = WEAPON_CLUB, + level = 220, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- cobra club + { + itemId = 35228, + type = WEAPON_DISTANCE, + level = 220, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- cobra crossbow + { + itemId = 35112, + type = WEAPON_AXE + }, -- ice hatchet + { + itemId = 34063, + type = WEAPON_WAND, + wandType = "fire", + level = 180, + mana = 24, + damage = {88, 108}, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- energized limb + { + itemId = 34060, + type = WEAPON_SWORD, + level = 200, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- winterblade + { + itemId = 34059, + type = WEAPON_SWORD, + level = 200, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- summerblade + { + itemId = 34057, + type = WEAPON_CLUB, + level = 230, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- resizer + { + itemId = 34055, + type = WEAPON_DISTANCE, + level = 220, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- living vine bow + { + itemId = 33925, + type = WEAPON_AXE + }, -- golden axe + { + itemId = 33267, + type = WEAPON_WAND + }, -- wand of destruction test + { + itemId = 33266, + type = WEAPON_DISTANCE + }, -- umbral master bow test + { + itemId = 33254, + type = WEAPON_WAND + }, -- sorcerer test weapon + { + itemId = 33253, + type = WEAPON_DISTANCE + }, -- bow of destruction test + { + itemId = 33252, + type = WEAPON_SWORD + }, -- test weapon for knights + { + itemId = 32529, + type = WEAPON_CLUB, + level = 80, + unproperly = true + }, -- sulphurous demonbone + { + itemId = 32528, + type = WEAPON_CLUB, + level = 80, + unproperly = true + }, -- unliving demonbone + { + itemId = 32527, + type = WEAPON_CLUB, + level = 80, + unproperly = true + }, -- energized demonbone + { + itemId = 32526, + type = WEAPON_CLUB, + level = 80, + unproperly = true + }, -- rotten demonbone + { + itemId = 32523, + type = WEAPON_WAND, + wandType = "ice", + level = 230, + mana = 23, + damage = {80, 120}, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- deepling fork + { + itemId = 32522, + type = WEAPON_WAND, + wandType = "ice", + level = 180, + mana = 23, + damage = {86, 98}, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- deepling ceremonial dagger + { + itemId = 32425, + type = WEAPON_CLUB, + level = 300, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- falcon mace + { + itemId = 32424, + type = WEAPON_AXE, + level = 300, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- falcon battleaxe + { + itemId = 32423, + type = WEAPON_SWORD, + level = 300, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- falcon longsword + { + itemId = 32418, + type = WEAPON_DISTANCE, + level = 300, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- falcon bow + { + itemId = 32417, + type = WEAPON_WAND, + wandType = "energy", + level = 300, + mana = 21, + damage = {86, 102}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- falcon wand + { + itemId = 32416, + type = WEAPON_WAND, + wandType = "earth", + level = 300, + mana = 20, + damage = {87, 101}, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- falcon rod + { + itemId = 30886, + type = WEAPON_SWORD, + level = 250, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- gnome sword + { + itemId = 30760, + type = WEAPON_CLUB + }, -- mallet handle + { + itemId = 30758, + type = WEAPON_CLUB + }, -- strange mallet + { + itemId = 30693, + type = WEAPON_WAND, + wandType = "ice", + level = 200, + mana = 20, + damage = {80, 110}, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- rod of destruction + { + itemId = 30692, + type = WEAPON_WAND, + wandType = "energy", + level = 200, + mana = 20, + damage = {80, 110}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of destruction + { + itemId = 30691, + type = WEAPON_DISTANCE, + level = 200, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- crossbow of destruction + { + itemId = 30690, + type = WEAPON_DISTANCE, + level = 200, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- bow of destruction + { + itemId = 30689, + type = WEAPON_CLUB, + level = 200, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- hammer of destruction + { + itemId = 30688, + type = WEAPON_CLUB, + level = 200, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- mace of destruction + { + itemId = 30687, + type = WEAPON_AXE, + level = 200, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- chopper of destruction + { + itemId = 30686, + type = WEAPON_AXE, + level = 200, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- axe of destruction + { + itemId = 30685, + type = WEAPON_SWORD, + level = 200, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- slayer of destruction + { + itemId = 30684, + type = WEAPON_SWORD, + level = 200, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- blade of destruction + { + itemId = 29297, + type = WEAPON_CLUB + }, -- ornate carving hammer + { + itemId = 29296, + type = WEAPON_CLUB + }, -- valuable carving hammer + { + itemId = 29295, + type = WEAPON_CLUB + }, -- plain carving hammer + { + itemId = 29294, + type = WEAPON_CLUB + }, -- ornate carving mace + { + itemId = 29293, + type = WEAPON_CLUB + }, -- valuable carving mace + { + itemId = 29292, + type = WEAPON_CLUB + }, -- plain carving mace + { + itemId = 29291, + type = WEAPON_AXE + }, -- ornate carving chopper + { + itemId = 29290, + type = WEAPON_AXE + }, -- valuable carving chopper + { + itemId = 29289, + type = WEAPON_AXE + }, -- plain carving chopper + { + itemId = 29288, + type = WEAPON_AXE + }, -- ornate carving axe + { + itemId = 29287, + type = WEAPON_AXE + }, -- valuable carving axe + { + itemId = 29286, + type = WEAPON_AXE + }, -- plain carving axe + { + itemId = 29285, + type = WEAPON_SWORD + }, -- ornate carving slayer + { + itemId = 29284, + type = WEAPON_SWORD + }, -- valuable carving slayer + { + itemId = 29283, + type = WEAPON_SWORD + }, -- plain carving slayer + { + itemId = 29282, + type = WEAPON_SWORD + }, -- ornate carving blade + { + itemId = 29281, + type = WEAPON_SWORD + }, -- valuable carving blade + { + itemId = 29280, + type = WEAPON_SWORD + }, -- plain carving blade + { + itemId = 29267, + type = WEAPON_CLUB + }, -- ornate remedy hammer + { + itemId = 29266, + type = WEAPON_CLUB + }, -- valuable remedy hammer + { + itemId = 29265, + type = WEAPON_CLUB + }, -- plain remedy hammer + { + itemId = 29264, + type = WEAPON_CLUB + }, -- ornate remedy mace + { + itemId = 29263, + type = WEAPON_CLUB + }, -- valuable remedy mace + { + itemId = 29262, + type = WEAPON_CLUB + }, -- plain remedy mace + { + itemId = 29261, + type = WEAPON_AXE + }, -- ornate remedy chopper + { + itemId = 29260, + type = WEAPON_AXE + }, -- valuable remedy chopper + { + itemId = 29259, + type = WEAPON_AXE + }, -- plain remedy chopper + { + itemId = 29258, + type = WEAPON_AXE + }, -- ornate remedy axe + { + itemId = 29257, + type = WEAPON_AXE + }, -- valuable remedy axe + { + itemId = 29256, + type = WEAPON_AXE + }, -- plain remedy axe + { + itemId = 29255, + type = WEAPON_SWORD + }, -- ornate remedy slayer + { + itemId = 29254, + type = WEAPON_SWORD + }, -- valuable remedy slayer + { + itemId = 29253, + type = WEAPON_SWORD + }, -- plain remedy slayer + { + itemId = 29252, + type = WEAPON_SWORD + }, -- ornate remedy blade + { + itemId = 29251, + type = WEAPON_SWORD + }, -- valuable remedy blade + { + itemId = 29250, + type = WEAPON_SWORD + }, -- plain remedy blade + { + itemId = 29236, + type = WEAPON_CLUB + }, -- ornate mayhem hammer + { + itemId = 29235, + type = WEAPON_CLUB + }, -- valuable mayhem hammer + { + itemId = 29234, + type = WEAPON_CLUB + }, -- plain mayhem hammer + { + itemId = 29233, + type = WEAPON_CLUB + }, -- ornate mayhem mace + { + itemId = 29232, + type = WEAPON_CLUB + }, -- valuable mayhem mace + { + itemId = 29231, + type = WEAPON_CLUB + }, -- plain mayhem mace + { + itemId = 29230, + type = WEAPON_AXE + }, -- ornate mayhem chopper + { + itemId = 29229, + type = WEAPON_AXE + }, -- valuable mayhem chopper + { + itemId = 29228, + type = WEAPON_AXE + }, -- plain mayhem chopper + { + itemId = 29227, + type = WEAPON_AXE + }, -- ornate mayhem axe + { + itemId = 29226, + type = WEAPON_AXE + }, -- valuable mayhem axe + { + itemId = 29225, + type = WEAPON_AXE + }, -- plain mayhem axe + { + itemId = 29224, + type = WEAPON_SWORD + }, -- ornate mayhem slayer + { + itemId = 29223, + type = WEAPON_SWORD + }, -- valuable mayhem slayer + { + itemId = 29222, + type = WEAPON_SWORD + }, -- plain mayhem slayer + { + itemId = 29221, + type = WEAPON_SWORD + }, -- ornate mayhem blade + { + itemId = 29220, + type = WEAPON_SWORD + }, -- valuable mayhem blade + { + itemId = 29219, + type = WEAPON_SWORD + }, -- plain mayhem blade + { + itemId = 29210, + type = WEAPON_CLUB + }, -- energy war hammer replica + { + itemId = 29209, + type = WEAPON_CLUB + }, -- energy orcish maul replica + { + itemId = 29208, + type = WEAPON_CLUB + }, -- energy basher replica + { + itemId = 29207, + type = WEAPON_CLUB + }, -- energy crystal mace replica + { + itemId = 29206, + type = WEAPON_CLUB + }, -- energy clerical mace replica + { + itemId = 29205, + type = WEAPON_AXE + }, -- energy war axe replica + { + itemId = 29204, + type = WEAPON_AXE + }, -- energy headchopper replica + { + itemId = 29203, + type = WEAPON_AXE + }, -- energy heroic axe replica + { + itemId = 29202, + type = WEAPON_AXE + }, -- energy knight axe replica + { + itemId = 29201, + type = WEAPON_AXE + }, -- energy barbarian axe replica + { + itemId = 29200, + type = WEAPON_SWORD + }, -- energy dragon slayer replica + { + itemId = 29199, + type = WEAPON_SWORD + }, -- energy blacksteel replica + { + itemId = 29198, + type = WEAPON_SWORD + }, -- energy mystic blade replica + { + itemId = 29197, + type = WEAPON_SWORD + }, -- energy relic sword replica + { + itemId = 29196, + type = WEAPON_SWORD + }, -- energy spike sword replica + { + itemId = 29195, + type = WEAPON_CLUB + }, -- earth war hammer replica + { + itemId = 29194, + type = WEAPON_CLUB + }, -- earth orcish maul replica + { + itemId = 29193, + type = WEAPON_CLUB + }, -- earth basher replica + { + itemId = 29192, + type = WEAPON_CLUB + }, -- earth crystal mace replica + { + itemId = 29191, + type = WEAPON_CLUB + }, -- earth clerical mace replica + { + itemId = 29190, + type = WEAPON_AXE + }, -- earth war axe replica + { + itemId = 29189, + type = WEAPON_AXE + }, -- earth headchopper replica + { + itemId = 29188, + type = WEAPON_AXE + }, -- earth heroic axe replica + { + itemId = 29187, + type = WEAPON_AXE + }, -- earth knight axe replica + { + itemId = 29186, + type = WEAPON_AXE + }, -- earth barbarian axe replica + { + itemId = 29185, + type = WEAPON_SWORD + }, -- earth dragon slayer replica + { + itemId = 29184, + type = WEAPON_SWORD + }, -- earth blacksteel replica + { + itemId = 29183, + type = WEAPON_SWORD + }, -- earth mystic blade replica + { + itemId = 29182, + type = WEAPON_SWORD + }, -- earth relic sword replica + { + itemId = 29181, + type = WEAPON_SWORD + }, -- earth spike sword replica + { + itemId = 29180, + type = WEAPON_CLUB + }, -- icy war hammer replica + { + itemId = 29179, + type = WEAPON_CLUB + }, -- icy orcish maul replica + { + itemId = 29178, + type = WEAPON_CLUB + }, -- icy basher replica + { + itemId = 29177, + type = WEAPON_CLUB + }, -- icy crystal mace replica + { + itemId = 29176, + type = WEAPON_CLUB + }, -- icy clerical mace replica + { + itemId = 29175, + type = WEAPON_AXE + }, -- icy war axe replica + { + itemId = 29174, + type = WEAPON_AXE + }, -- icy headchopper replica + { + itemId = 29173, + type = WEAPON_AXE + }, -- icy heroic axe replica + { + itemId = 29172, + type = WEAPON_AXE + }, -- icy knight axe replica + { + itemId = 29171, + type = WEAPON_AXE + }, -- icy barbarian axe replica + { + itemId = 29170, + type = WEAPON_SWORD + }, -- icy dragon slayer replica + { + itemId = 29169, + type = WEAPON_SWORD + }, -- icy blacksteel replica + { + itemId = 29168, + type = WEAPON_SWORD + }, -- icy mystic blade replica + { + itemId = 29167, + type = WEAPON_SWORD + }, -- icy relic sword replica + { + itemId = 29166, + type = WEAPON_SWORD + }, -- icy spike sword replica + { + itemId = 29165, + type = WEAPON_CLUB + }, -- fiery war hammer replica + { + itemId = 29164, + type = WEAPON_CLUB + }, -- fiery orcish maul replica + { + itemId = 29163, + type = WEAPON_CLUB + }, -- fiery basher replica + { + itemId = 29162, + type = WEAPON_CLUB + }, -- fiery crystal mace replica + { + itemId = 29161, + type = WEAPON_CLUB + }, -- fiery clerical mace replica + { + itemId = 29160, + type = WEAPON_AXE + }, -- fiery war axe replica + { + itemId = 29159, + type = WEAPON_AXE + }, -- fiery headchopper replica + { + itemId = 29158, + type = WEAPON_AXE + }, -- fiery heroic axe replica + { + itemId = 29157, + type = WEAPON_AXE + }, -- fiery knight axe replica + { + itemId = 29156, + type = WEAPON_AXE + }, -- fiery barbarian axe replica + { + itemId = 29155, + type = WEAPON_SWORD + }, -- fiery dragon slayer replica + { + itemId = 29154, + type = WEAPON_SWORD + }, -- fiery blacksteel replica + { + itemId = 29153, + type = WEAPON_SWORD + }, -- fiery mystic blade replica + { + itemId = 29152, + type = WEAPON_SWORD + }, -- fiery relic sword replica + { + itemId = 29151, + type = WEAPON_SWORD + }, -- fiery spike sword replica + { + itemId = 29060, + type = WEAPON_WAND, + wandType = "death", + level = 41, + mana = 15, + damage = {75, 95}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of darkness + { + itemId = 29059, + type = WEAPON_DISTANCE, + level = 120, + unproperly = true, + breakChance = 30 + }, -- royal star + { + itemId = 29058, + type = WEAPON_AMMO, + level = 150, + unproperly = true, + action = "removecount" + }, -- spectral bolt + { + itemId = 29036, + type = WEAPON_DISTANCE, + level = 60, + unproperly = true, + breakChance = 40 + }, -- leaf star + { + itemId = 29005, + type = WEAPON_WAND, + wandType = "energy", + level = 80, + mana = 18, + damage = {63, 77}, + vocation = { + {"Sorcerer", true}, + {"Druid", true, true}, + {"Master Sorcerer"}, + {"Elder Druid"} + } + }, -- dream blossom staff + { + itemId = 25995, + type = WEAPON_WAND, + wandType = "ice", + level = 100, + mana = 18, + damage = {70, 105}, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- rod of carving + { + itemId = 25991, + type = WEAPON_WAND, + wandType = "energy", + level = 100, + mana = 18, + damage = {70, 105}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of carving + { + itemId = 25987, + type = WEAPON_DISTANCE, + level = 100, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- crossbow of carving + { + itemId = 25983, + type = WEAPON_DISTANCE, + level = 100, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- bow of carving + { + itemId = 25979, + type = WEAPON_CLUB, + level = 100, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- hammer of carving + { + itemId = 25975, + type = WEAPON_CLUB, + level = 100, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- mace of carving + { + itemId = 25971, + type = WEAPON_AXE, + level = 100, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- chopper of carving + { + itemId = 25967, + type = WEAPON_AXE, + level = 100, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- axe of carving + { + itemId = 25963, + type = WEAPON_SWORD, + level = 100, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- slayer of carving + { + itemId = 25959, + type = WEAPON_SWORD, + level = 100, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- blade of carving + { + itemId = 25955, + type = WEAPON_WAND, + wandType = "ice", + level = 100, + mana = 18, + damage = {70, 105}, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- rod of remedy + { + itemId = 25951, + type = WEAPON_WAND, + wandType = "energy", + level = 100, + mana = 18, + damage = {70, 105}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of remedy + { + itemId = 25947, + type = WEAPON_DISTANCE, + level = 100, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- crossbow of remedy + { + itemId = 25943, + type = WEAPON_DISTANCE, + level = 100, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- bow of remedy + { + itemId = 25939, + type = WEAPON_CLUB, + level = 100, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- hammer of remedy + { + itemId = 25935, + type = WEAPON_CLUB, + level = 100, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- mace of remedy + { + itemId = 25931, + type = WEAPON_AXE, + level = 100, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- chopper of remedy + { + itemId = 25927, + type = WEAPON_AXE, + level = 100, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- axe of remedy + { + itemId = 25923, + type = WEAPON_SWORD, + level = 100, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- slayer of remedy + { + itemId = 25919, + type = WEAPON_SWORD, + level = 100, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- blade of remedy + { + itemId = 25888, + type = WEAPON_WAND, + wandType = "ice", + level = 100, + mana = 18, + damage = {70, 105}, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- rod of mayhem + { + itemId = 25887, + type = WEAPON_WAND, + wandType = "energy", + level = 100, + mana = 18, + damage = {70, 105}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of mayhem + { + itemId = 25886, + type = WEAPON_DISTANCE, + level = 100, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- crossbow of mayhem + { + itemId = 25885, + type = WEAPON_DISTANCE, + level = 100, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- bow of mayhem + { + itemId = 25884, + type = WEAPON_CLUB, + level = 100, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- hammer of mayhem + { + itemId = 25883, + type = WEAPON_CLUB, + level = 100, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- mace of mayhem + { + itemId = 25882, + type = WEAPON_AXE, + level = 100, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- chopper of mayhem + { + itemId = 25881, + type = WEAPON_AXE, + level = 100, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- axe of mayhem + { + itemId = 25880, + type = WEAPON_SWORD, + level = 100, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- slayer of mayhem + { + itemId = 25879, + type = WEAPON_SWORD, + level = 100, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- blade of mayhem + { + itemId = 25523, + type = WEAPON_DISTANCE, + level = 120, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- rift crossbow + { + itemId = 25522, + type = WEAPON_DISTANCE, + level = 120, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- rift bow + { + itemId = 25422, + type = WEAPON_WAND, + wandType = "energy", + level = 100, + mana = 19, + damage = {80, 110}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- ferumbras' staff (enchanted) + { + itemId = 25421, + type = WEAPON_WAND, + wandType = "energy", + level = 65, + mana = 17, + damage = {65, 95}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- ferumbras' staff (failed) + { + itemId = 25420, + type = WEAPON_CLUB, + level = 100, + unproperly = true + }, -- Ferumbras' staff + { + itemId = 25418, + type = WEAPON_CLUB, + level = 150, + unproperly = true + }, -- maimer + { + itemId = 25416, + type = WEAPON_SWORD, + level = 150, + unproperly = true + }, -- Impaler of the igniter + { + itemId = 25415, + type = WEAPON_AXE, + level = 150, + unproperly = true + }, -- plague bite + { + itemId = 25383, + type = WEAPON_AXE, + level = 70, + unproperly = true + }, -- rift lance + { + itemId = 24839, + type = WEAPON_WAND, + wandType = "earth", + level = 37, + mana = 13, + damage = {56, 74}, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- ogre sceptra + { + itemId = 24828, + type = WEAPON_AXE, + level = 25, + unproperly = true + }, -- ogre choppa + { + itemId = 24827, + type = WEAPON_AXE, + level = 50, + unproperly = true + }, -- ogre klubba + { + itemId = 23839, + type = WEAPON_AMMO, + action = "removecount" + }, -- simple arrow + --[[ + the chiller + {itemId = 23721} + scripted weapon + ]] + --[[ + the scorcher + {itemId = 23719} + scripted weapon + ]] + { + itemId = 23590, + type = WEAPON_CLUB, + level = 70, + unproperly = true + }, -- one hit wonder + { + itemId = 23551, + type = WEAPON_AXE, + level = 75, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- glooth axe + { + itemId = 23550, + type = WEAPON_SWORD, + level = 75, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- glooth blade + { + itemId = 23549, + type = WEAPON_CLUB, + level = 75, + unproperly = true, + action = "removecharge", + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- glooth club + { + itemId = 23548, + type = WEAPON_SWORD, + level = 25, + unproperly = true + }, -- cowtana + { + itemId = 23547, + type = WEAPON_AXE, + level = 55, + unproperly = true + }, -- execowtioner axe + { + itemId = 23545, + type = WEAPON_AXE, + level = 45, + unproperly = true + }, -- mino lance + { + itemId = 23544, + type = WEAPON_CLUB, + level = 60, + unproperly = true + }, -- moohtant cudgel + { + itemId = 23543, + type = WEAPON_CLUB, + level = 25, + unproperly = true + }, -- glooth whip + { + itemId = 23542, + type = WEAPON_CLUB, + level = 55, + unproperly = true + }, -- metal bat + { + itemId = 23529, + type = WEAPON_DISTANCE, + level = 60, + unproperly = true, + breakChance = 2 + }, -- glooth spear + { + itemId = 22421, + type = WEAPON_DISTANCE, + level = 250, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- umbral master crossbow + { + itemId = 22420, + type = WEAPON_DISTANCE, + level = 120, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- umbral crossbow + { + itemId = 22419, + type = WEAPON_DISTANCE, + level = 75, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- crude umbral crossbow + { + itemId = 22418, + type = WEAPON_DISTANCE, + level = 250, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- umbral master bow + { + itemId = 22417, + type = WEAPON_DISTANCE, + level = 120, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- umbral bow + { + itemId = 22416, + type = WEAPON_DISTANCE, + level = 75, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- crude umbral bow + { + itemId = 22415, + type = WEAPON_CLUB, + level = 250, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- umbral master hammer + { + itemId = 22414, + type = WEAPON_CLUB, + level = 120, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- umbral hammer + { + itemId = 22413, + type = WEAPON_CLUB, + level = 75, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- crude umbral hammer + { + itemId = 22412, + type = WEAPON_CLUB, + level = 250, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- umbral master mace + { + itemId = 22411, + type = WEAPON_CLUB, + level = 120, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- umbral mace + { + itemId = 22410, + type = WEAPON_CLUB, + level = 75, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- crude umbral mace + { + itemId = 22409, + type = WEAPON_AXE, + level = 250, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- umbral master chopper + { + itemId = 22408, + type = WEAPON_AXE, + level = 120, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- umbral chopper + { + itemId = 22407, + type = WEAPON_AXE, + level = 75, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- guardian halberd + { + itemId = 22406, + type = WEAPON_AXE, + level = 250, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- umbral master axe + { + itemId = 22405, + type = WEAPON_AXE, + level = 120, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- umbral axe + { + itemId = 22404, + type = WEAPON_AXE, + level = 75, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- crude umbral axe + { + itemId = 22403, + type = WEAPON_SWORD, + level = 250, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- umbral master slayer + { + itemId = 22402, + type = WEAPON_SWORD, + level = 120, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- umbral slayer + { + itemId = 22401, + type = WEAPON_SWORD, + level = 75, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- crude umbral slayer + { + itemId = 22400, + type = WEAPON_SWORD, + level = 250, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- umbral masterblade + { + itemId = 22399, + type = WEAPON_SWORD, + level = 120, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- umbral blade + { + itemId = 22398, + type = WEAPON_SWORD, + level = 75, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- crude umbral blade + { + itemId = 21696, + type = WEAPON_DISTANCE, + unproperly = true + }, -- icicle bow + { + itemId = 21690, + type = WEAPON_DISTANCE, + level = 70, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- triple bolt crossbow + { + itemId = 20139, + type = WEAPON_CLUB, + level = 20, + unproperly = true + }, -- spiky club + { + itemId = 20108, + type = WEAPON_CLUB, + level = 50, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- pair of iron fists + { + itemId = 20104, + type = WEAPON_CLUB + }, -- swampling club + { + itemId = 20093, + type = WEAPON_CLUB, + level = 15, + unproperly = true + }, -- life preserver + { + itemId = 20092, + type = WEAPON_SWORD, + level = 15, + unproperly = true + }, -- ratana + { + itemId = 19391, + type = WEAPON_WAND, + wandType = "energy", + level = 1, + mana = 2, + damage = {8, 18}, + vocation = { + {"None", true} + } + }, -- sorc and druid staff + { + itemId = 19390, + type = WEAPON_DISTANCE, + breakChance = 3, + vocation = { + {"None", true} + } + }, -- mean paladin spear + { + itemId = 19389, + type = WEAPON_SWORD, + unproperly = true, + vocation = { + {"None", true} + } + }, -- mean knight sword + { + itemId = 18465, + type = WEAPON_SWORD, + level = 120, + unproperly = true + }, -- shiny blade + { + itemId = 18454, + type = WEAPON_DISTANCE, + level = 105, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- mycological bow + { + itemId = 18453, + type = WEAPON_DISTANCE, + level = 90, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- crystal crossbow + { + itemId = 18452, + type = WEAPON_CLUB, + level = 120, + unproperly = true + }, -- mycological mace + { + itemId = 18451, + type = WEAPON_AXE, + level = 120, + unproperly = true + }, -- crystalline axe + { + itemId = 18450, + type = WEAPON_SWORD, + level = 62, + unproperly = true + }, -- crystalline sword + { + itemId = 18437, + type = WEAPON_AMMO, + level = 70, + unproperly = true, + action = "removecount" + }, -- envenomed arrow + { + itemId = 18436, + type = WEAPON_AMMO, + level = 70, + unproperly = true, + action = "removecount" + }, -- drill bolt + { + itemId = 18435, + type = WEAPON_AMMO, + level = 90, + unproperly = true, + action = "removecount" + }, -- prismatic bolt + { + itemId = 18412, + type = WEAPON_WAND, + wandType = "ice", + level = 65, + mana = 17, + damage = {75, 95}, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- glacial rod + { + itemId = 18411, + type = WEAPON_WAND, + wandType = "earth", + level = 65, + mana = 17, + damage = {75, 95}, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- muck rod + { + itemId = 18409, + type = WEAPON_WAND, + wandType = "fire", + level = 65, + mana = 17, + damage = {75, 95}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of everblazing + { + itemId = 18390, + type = WEAPON_WAND, + wandType = "energy", + level = 65, + mana = 17, + damage = {75, 95}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of defiance + { + itemId = 18304, + type = WEAPON_AMMO, + level = 90, + unproperly = true, + action = "removecount" + }, -- crystalline arrow + { + itemId = 18303, + type = WEAPON_AMMO, + action = "removecount" + }, -- crystal bolt + { + itemId = 16111, + type = WEAPON_DISTANCE, + level = 150, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- thorn spitter + { + itemId = 15649, + type = WEAPON_AMMO, + level = 40, + unproperly = true, + action = "removecount" + }, -- vortex bolt + { + itemId = 15648, + type = WEAPON_AMMO, + level = 30, + unproperly = true, + action = "removecount" + }, -- tarsal arrow + { + itemId = 15647, + type = WEAPON_CLUB, + level = 48, + unproperly = true + }, -- deepling squelcher + { + itemId = 15644, + type = WEAPON_DISTANCE, + level = 50, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- ornate crossbow + { + itemId = 15643, + type = WEAPON_DISTANCE, + level = 85, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- hive bow + { + itemId = 15492, + type = WEAPON_AXE, + level = 70, + unproperly = true + }, -- hive scythe + { + itemId = 15454, + type = WEAPON_AXE, + level = 50, + unproperly = true + }, -- guardian axe + { + itemId = 15451, + type = WEAPON_AXE, + level = 40, + unproperly = true + }, -- warrior's axe + { + itemId = 15414, + type = WEAPON_CLUB, + level = 90, + unproperly = true + }, -- ornate mace + { + itemId = 15404, + type = WEAPON_AXE, + level = 80, + unproperly = true + }, -- deepling axe + { + itemId = 15400, + type = WEAPON_CLUB, + level = 38, + unproperly = true + }, -- deepling staff + { + itemId = 13880, + type = WEAPON_WAND, + wandType = "energy", + level = 40, + mana = 13, + damage = {56, 74}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- shimmer wand + { + itemId = 13873, + type = WEAPON_DISTANCE, + level = 40, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- shimmer bow + { + itemId = 13872, + type = WEAPON_WAND, + wandType = "ice", + level = 40, + mana = 13, + damage = {56, 74}, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- shimmer rod + { + itemId = 13871, + type = WEAPON_SWORD, + level = 40, + unproperly = true + }, -- shimmer sword + { + itemId = 13838, + type = WEAPON_AXE, + level = 25, + unproperly = true + }, -- heavy trident + { + itemId = 13829, + type = WEAPON_SWORD + }, -- wooden sword + { + itemId = 13760, + type = WEAPON_WAND, + wandType = "death", + level = 37, + mana = 9, + damage = {44, 62}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of dimensions + { + itemId = 12649, + type = WEAPON_SWORD, + level = 82, + unproperly = true + }, -- blade of corruption + { + itemId = 12648, + type = WEAPON_CLUB, + level = 82, + unproperly = true + }, -- snake god's sceptre + { + itemId = 12613, + type = WEAPON_SWORD, + level = 58, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- twiceslicer + { + itemId = 11323, + type = WEAPON_AXE, + level = 25, + unproperly = true + }, -- Zaoan halberd + { + itemId = 11309, + type = WEAPON_SWORD, + level = 20, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- twin hooks + { + itemId = 11308, + type = WEAPON_CLUB, + level = 55, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- drachaku + { + itemId = 11307, + type = WEAPON_SWORD, + level = 55, + unproperly = true + }, -- Zaoan sword + { + itemId = 11306, + type = WEAPON_SWORD, + level = 50, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- sai + { + itemId = 11305, + type = WEAPON_AXE, + level = 60, + unproperly = true + }, -- drakinata + { + itemId = 10313, + type = WEAPON_SWORD + }, -- incredible mumpiz slayer + { + itemId = 10304, + type = WEAPON_SWORD + }, -- poet's fencing quill + { + itemId = 10303, + type = WEAPON_AXE + }, -- farmer's avenger + { + itemId = 10302, + type = WEAPON_CLUB + }, -- club of the fury + { + itemId = 10301, + type = WEAPON_AXE + }, -- scythe of the reaper + { + itemId = 10295, + type = WEAPON_DISTANCE + }, -- musician's bow + { + itemId = 10293, + type = WEAPON_CLUB + }, -- stale bread of ancientness + { + itemId = 10292, + type = WEAPON_SWORD + }, -- pointed rabbitslayer + { + itemId = 10290, + type = WEAPON_CLUB + }, -- glutton's mace + { + itemId = 8932, + type = WEAPON_SWORD, + level = 100, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- the calamity + { + itemId = 8931, + type = WEAPON_SWORD, + level = 120, + unproperly = true + }, -- the epiphany + { + itemId = 8930, + type = WEAPON_SWORD, + level = 100, + unproperly = true + }, -- emerald sword + { + itemId = 8929, + type = WEAPON_CLUB, + level = 100, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- the stomper + { + itemId = 8928, + type = WEAPON_CLUB, + level = 100, + unproperly = true + }, -- obsidian truncheon + { + itemId = 8927, + type = WEAPON_CLUB, + level = 120, + unproperly = true + }, -- dark trinity mace + { + itemId = 8926, + type = WEAPON_AXE, + level = 120, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- demonwing axe + { + itemId = 8925, + type = WEAPON_AXE, + level = 130, + unproperly = true + }, -- solar axe + { + itemId = 8924, + type = WEAPON_AXE, + level = 110, + unproperly = true + }, -- hellforged axe + { + itemId = 8922, + type = WEAPON_WAND, + wandType = "death", + level = 42, + mana = 13, + damage = {56, 74}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of voodoo + { + itemId = 8921, + type = WEAPON_WAND, + wandType = "fire", + level = 22, + mana = 5, + damage = {23, 37}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of draconia + { + itemId = 8920, + type = WEAPON_WAND, + wandType = "energy", + level = 37, + mana = 13, + damage = {56, 74}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of starmstorm + { + itemId = 8912, + type = WEAPON_WAND, + wandType = "earth", + level = 37, + mana = 13, + damage = {56, 74}, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- springsprout rod + { + itemId = 8911, + type = WEAPON_WAND, + wandType = "ice", + level = 22, + mana = 5, + damage = {23, 37}, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- northwind rod + { + itemId = 8910, + type = WEAPON_WAND, + wandType = "death", + level = 42, + mana = 13, + damage = {56, 74}, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- underworld rod + { + itemId = 8858, + type = WEAPON_DISTANCE, + level = 70, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- elethriel's elemental bow + { + itemId = 8857, + type = WEAPON_DISTANCE, + level = 40, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- silkweaver bow + { + itemId = 8856, + type = WEAPON_DISTANCE, + level = 60, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- yol's bow + { + itemId = 8855, + type = WEAPON_DISTANCE, + level = 50, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- composite hornbow + { + itemId = 8854, + type = WEAPON_DISTANCE, + level = 80, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- warsinger bow + { + itemId = 8853, + type = WEAPON_DISTANCE, + level = 80, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- ironworker + { + itemId = 8852, + type = WEAPON_DISTANCE, + level = 100, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- devileye + { + itemId = 8851, + type = WEAPON_DISTANCE, + level = 130, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- royal crossbow + { + itemId = 8850, + type = WEAPON_DISTANCE, + level = 60, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- chain bolter + { + itemId = 8849, + type = WEAPON_DISTANCE, + level = 45, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- modified crossbow + { + itemId = 8602, + type = WEAPON_SWORD + }, -- jagged sword + { + itemId = 8601, + type = WEAPON_AXE + }, -- steel axe + { + itemId = 8209, + type = WEAPON_SWORD + }, -- crimson sword + { + itemId = 7883, + type = WEAPON_CLUB, + level = 50, + unproperly = true, + action = "removecharge", + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- energy war hammer + { + itemId = 7882, + type = WEAPON_CLUB, + level = 35, + unproperly = true, + action = "removecharge" + }, -- energy orcish maul + { + itemId = 7881, + type = WEAPON_CLUB, + level = 60, + unproperly = true, + action = "removecharge" + }, -- energy cranial basher + { + itemId = 7880, + type = WEAPON_CLUB, + level = 35, + unproperly = true, + action = "removecharge" + }, -- energy crystal mace + { + itemId = 7879, + type = WEAPON_CLUB, + level = 20, + unproperly = true, + action = "removecharge" + }, -- energy clerical mace + { + itemId = 7878, + type = WEAPON_AXE, + level = 65, + unproperly = true, + action = "removecharge", + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- energy war axe + { + itemId = 7877, + type = WEAPON_AXE, + level = 35, + unproperly = true, + action = "removecharge", + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- energy headchopper + { + itemId = 7876, + type = WEAPON_AXE, + level = 60, + unproperly = true, + action = "removecharge" + }, -- energy heroic axe + { + itemId = 7875, + type = WEAPON_AXE, + level = 25, + unproperly = true, + action = "removecharge" + }, -- energy knight axe + { + itemId = 7874, + type = WEAPON_AXE, + level = 20, + unproperly = true, + action = "removecharge" + }, -- energy barbarian axe + { + itemId = 7873, + type = WEAPON_SWORD, + level = 45, + unproperly = true, + action = "removecharge", + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- energy dragon slayer + { + itemId = 7872, + type = WEAPON_SWORD, + level = 35, + unproperly = true, + action = "removecharge", + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- energy blacksteel sword + { + itemId = 7871, + type = WEAPON_SWORD, + level = 60, + unproperly = true, + action = "removecharge" + }, -- energy mystic blade + { + itemId = 7870, + type = WEAPON_SWORD, + level = 50, + unproperly = true, + action = "removecharge" + }, -- energy relic sword + { + itemId = 7869, + type = WEAPON_SWORD, + action = "removecharge" + }, -- energy spike sword + { + itemId = 7868, + type = WEAPON_CLUB, + level = 50, + unproperly = true, + action = "removecharge", + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- earth war hammer + { + itemId = 7867, + type = WEAPON_CLUB, + level = 35, + unproperly = true, + action = "removecharge" + }, -- earth orcish maul + { + itemId = 7866, + type = WEAPON_CLUB, + level = 60, + unproperly = true, + action = "removecharge" + }, -- earth cranial basher + { + itemId = 7865, + type = WEAPON_CLUB, + level = 35, + unproperly = true, + action = "removecharge" + }, -- earth crystal mace + { + itemId = 7864, + type = WEAPON_CLUB, + level = 20, + unproperly = true, + action = "removecharge" + }, -- earth clerical mace + { + itemId = 7863, + type = WEAPON_AXE, + level = 65, + unproperly = true, + action = "removecharge", + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- earth war axe + { + itemId = 7862, + type = WEAPON_AXE, + level = 35, + unproperly = true, + action = "removecharge", + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- earth headchopper + { + itemId = 7861, + type = WEAPON_AXE, + level = 60, + unproperly = true, + action = "removecharge" + }, -- earth heroic axe + { + itemId = 7860, + type = WEAPON_AXE, + level = 25, + unproperly = true, + action = "removecharge" + }, -- earth knight axe + { + itemId = 7859, + type = WEAPON_AXE, + level = 20, + unproperly = true, + action = "removecharge" + }, -- earth barbarian axe + { + itemId = 7858, + type = WEAPON_SWORD, + level = 45, + unproperly = true, + action = "removecharge", + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- earth dragon slayer + { + itemId = 7857, + type = WEAPON_SWORD, + level = 35, + unproperly = true, + action = "removecharge", + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- earth blacksteel sword + { + itemId = 7856, + type = WEAPON_SWORD, + level = 60, + unproperly = true, + action = "removecharge" + }, -- earth mystic blade + { + itemId = 7855, + type = WEAPON_SWORD, + level = 50, + unproperly = true, + action = "removecharge" + }, -- earth relic sword + { + itemId = 7854, + type = WEAPON_SWORD, + action = "removecharge" + }, -- earth spike sword + { + itemId = 7850, + type = WEAPON_AMMO, + level = 20, + unproperly = true, + action = "removecount" + }, -- earth arrow + { + itemId = 7840, + type = WEAPON_AMMO, + level = 20, + unproperly = true, + action = "removecount" + }, -- flaming arrow + { + itemId = 7839, + type = WEAPON_AMMO, + level = 20, + unproperly = true, + action = "removecount" + }, -- shiver arrow + { + itemId = 7838, + type = WEAPON_AMMO, + level = 20, + unproperly = true, + action = "removecount" + }, -- flash arrow + { + itemId = 7777, + type = WEAPON_CLUB, + level = 50, + unproperly = true, + action = "removecharge", + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- icy war hammer + { + itemId = 7776, + type = WEAPON_CLUB, + level = 35, + unproperly = true, + action = "removecharge" + }, -- icy orcish maul + { + itemId = 7775, + type = WEAPON_CLUB, + level = 60, + unproperly = true, + action = "removecharge" + }, -- icy cranial basher + { + itemId = 7774, + type = WEAPON_CLUB, + level = 35, + unproperly = true, + action = "removecharge" + }, -- icy crystal mace + { + itemId = 7773, + type = WEAPON_CLUB, + level = 20, + unproperly = true, + action = "removecharge" + }, -- icy clerical mace + { + itemId = 7772, + type = WEAPON_AXE, + level = 65, + unproperly = true, + action = "removecharge", + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- icy war axe + { + itemId = 7771, + type = WEAPON_AXE, + level = 35, + unproperly = true, + action = "removecharge", + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- icy headchopper + { + itemId = 7770, + type = WEAPON_AXE, + level = 60, + unproperly = true, + action = "removecharge" + }, -- icy heroic axe + { + itemId = 7769, + type = WEAPON_AXE, + level = 25, + unproperly = true, + action = "removecharge" + }, -- icy knight axe + { + itemId = 7768, + type = WEAPON_AXE, + level = 20, + unproperly = true, + action = "removecharge" + }, -- icy barbarian axe + { + itemId = 7767, + type = WEAPON_SWORD, + level = 45, + unproperly = true, + action = "removecharge", + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- icy dragon slayer + { + itemId = 7766, + type = WEAPON_SWORD, + level = 35, + unproperly = true, + action = "removecharge", + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- icy blacksteel sword + { + itemId = 7765, + type = WEAPON_SWORD, + level = 60, + unproperly = true, + action = "removecharge" + }, -- icy mystic blade + { + itemId = 7764, + type = WEAPON_SWORD, + level = 50, + unproperly = true, + action = "removecharge" + }, -- icy relic sword + { + itemId = 7763, + type = WEAPON_SWORD, + action = "removecharge" + }, -- icy spike sword + { + itemId = 7758, + type = WEAPON_CLUB, + level = 50, + unproperly = true, + action = "removecharge", + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- fiery war hammer + { + itemId = 7757, + type = WEAPON_CLUB, + level = 35, + unproperly = true, + action = "removecharge" + }, -- fiery orcish maul + { + itemId = 7756, + type = WEAPON_CLUB, + level = 60, + unproperly = true, + action = "removecharge" + }, -- fiery cranial basher + { + itemId = 7755, + type = WEAPON_CLUB, + level = 35, + unproperly = true, + action = "removecharge" + }, -- fiery crystal mace + { + itemId = 7754, + type = WEAPON_CLUB, + level = 20, + unproperly = true, + action = "removecharge" + }, -- fiery clerical mace + { + itemId = 7753, + type = WEAPON_AXE, + level = 65, + unproperly = true, + action = "removecharge", + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- fiery war axe + { + itemId = 7752, + type = WEAPON_AXE, + level = 35, + unproperly = true, + action = "removecharge", + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- fiery headchopper + { + itemId = 7751, + type = WEAPON_AXE, + level = 60, + unproperly = true, + action = "removecharge" + }, -- fiery heroic axe + { + itemId = 7750, + type = WEAPON_AXE, + level = 25, + unproperly = true, + action = "removecharge" + }, -- fiery knight axe + { + itemId = 7749, + type = WEAPON_AXE, + level = 20, + unproperly = true, + action = "removecharge" + }, -- fiery barbarian axe + { + itemId = 7748, + type = WEAPON_SWORD, + level = 45, + unproperly = true, + action = "removecharge", + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- fiery dragon slayer + { + itemId = 7747, + type = WEAPON_SWORD, + level = 35, + unproperly = true, + action = "removecharge", + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- fiery blacksteel sword + { + itemId = 7746, + type = WEAPON_SWORD, + level = 60, + unproperly = true, + action = "removecharge" + }, -- fiery mystic blade + { + itemId = 7745, + type = WEAPON_SWORD, + level = 50, + unproperly = true, + action = "removecharge" + }, -- fiery relic sword + { + itemId = 7744, + type = WEAPON_SWORD, + action = "removecharge" + }, -- fiery spike sword + { + itemId = 7456, + type = WEAPON_AXE, + level = 35, + unproperly = true + }, -- noble axe + { + itemId = 7455, + type = WEAPON_AXE, + level = 80, + unproperly = true + }, -- mythril axe + { + itemId = 7454, + type = WEAPON_AXE, + level = 30, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- glorious axe + { + itemId = 7453, + type = WEAPON_AXE, + level = 85, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- executioner + { + itemId = 7452, + type = WEAPON_CLUB, + level = 30, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- spiked squelcher + { + itemId = 7451, + type = WEAPON_CLUB, + level = 35, + unproperly = true + }, -- shadow sceptre + { + itemId = 7450, + type = WEAPON_CLUB, + level = 120, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- hammer of prophecy + { + itemId = 7449, + type = WEAPON_SWORD, + level = 25, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- crystal sword + { + itemId = 7438, + type = WEAPON_DISTANCE + }, -- elvish bow + { + itemId = 7437, + type = WEAPON_CLUB, + level = 30, + unproperly = true + }, -- sapphire hammer + { + itemId = 7436, + type = WEAPON_AXE, + level = 45, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- angelic axe + { + itemId = 7435, + type = WEAPON_AXE, + level = 85, + unproperly = true + }, -- impaler + { + itemId = 7434, + type = WEAPON_AXE, + level = 75, + unproperly = true + }, -- royal axe + { + itemId = 7433, + type = WEAPON_AXE, + level = 65, + unproperly = true + }, -- ravenwing + { + itemId = 7432, + type = WEAPON_CLUB, + level = 20, + unproperly = true + }, -- furry club + { + itemId = 7431, + type = WEAPON_CLUB, + level = 80, + unproperly = true + }, -- demonbone + { + itemId = 7430, + type = WEAPON_CLUB, + level = 30, + unproperly = true + }, -- dragonbone staff + { + itemId = 7429, + type = WEAPON_CLUB, + level = 75, + unproperly = true + }, -- blessed sceptre + { + itemId = 7428, + type = WEAPON_CLUB, + level = 55, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- bonebreaker + { + itemId = 7427, + type = WEAPON_CLUB, + level = 45, + unproperly = true + }, -- chaos mace + { + itemId = 7426, + type = WEAPON_CLUB, + level = 40, + unproperly = true + }, -- amber staff + { + itemId = 7425, + type = WEAPON_CLUB, + level = 20, + unproperly = true + }, -- taurus mace + { + itemId = 7424, + type = WEAPON_CLUB, + level = 30, + unproperly = true + }, -- lunar staff + { + itemId = 7423, + type = WEAPON_CLUB, + level = 85, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- skullcrusher + { + itemId = 7422, + type = WEAPON_CLUB, + level = 70, + unproperly = true + }, -- jade hammer + { + itemId = 7421, + type = WEAPON_CLUB, + level = 65, + unproperly = true + }, -- onyx flail + { + itemId = 7420, + type = WEAPON_AXE, + level = 70, + unproperly = true + }, -- reaper's axe + { + itemId = 7419, + type = WEAPON_AXE, + level = 40, + unproperly = true + }, -- dreaded cleaver + { + itemId = 7418, + type = WEAPON_SWORD, + level = 70, + unproperly = true + }, -- nightmare blade + { + itemId = 7417, + type = WEAPON_SWORD, + level = 65, + unproperly = true + }, -- runed sword + { + itemId = 7416, + type = WEAPON_SWORD, + level = 55, + unproperly = true + }, -- bloody edge + { + itemId = 7415, + type = WEAPON_CLUB, + level = 60, + unproperly = true + }, -- cranial basher + { + itemId = 7414, + type = WEAPON_CLUB, + level = 60, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- abyss hammer + { + itemId = 7413, + type = WEAPON_AXE, + level = 40, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- titan axe + { + itemId = 7412, + type = WEAPON_AXE, + level = 45, + unproperly = true + }, -- butcher's axe + { + itemId = 7411, + type = WEAPON_AXE, + level = 50, + unproperly = true + }, -- ornamented axe + { + itemId = 7410, + type = WEAPON_CLUB, + level = 55, + unproperly = true + }, -- queen's sceptre + { + itemId = 7409, + type = WEAPON_CLUB, + level = 50, + unproperly = true + }, -- northern star + { + itemId = 7408, + type = WEAPON_SWORD, + level = 25, + unproperly = true + }, -- wyvern fang + { + itemId = 7407, + type = WEAPON_SWORD, + level = 30, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- haunted blade + { + itemId = 7406, + type = WEAPON_SWORD, + level = 35, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- blacksteel sword + { + itemId = 7405, + type = WEAPON_SWORD, + level = 70, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- havoc blade + { + itemId = 7404, + type = WEAPON_SWORD, + level = 40, + unproperly = true + }, -- assassin dagger + { + itemId = 7403, + type = WEAPON_SWORD, + level = 65, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- berserker + { + itemId = 7402, + type = WEAPON_SWORD, + level = 45, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- dragon slayer + { + itemId = 7392, + type = WEAPON_CLUB, + level = 35, + unproperly = true + }, -- orcish maul + { + itemId = 7391, + type = WEAPON_SWORD, + level = 50, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- thaian sword + { + itemId = 7390, + type = WEAPON_SWORD, + level = 75, + unproperly = true + }, -- the justice seeker + { + itemId = 7389, + type = WEAPON_AXE, + level = 60, + unproperly = true + }, -- heroic axe + { + itemId = 7388, + type = WEAPON_AXE, + level = 55, + unproperly = true + }, -- vile axe + { + itemId = 7387, + type = WEAPON_CLUB, + level = 25, + unproperly = true + }, -- diamond sceptre + { + itemId = 7386, + type = WEAPON_SWORD, + level = 40, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- mercenary sword + { + itemId = 7385, + type = WEAPON_SWORD, + level = 20, + unproperly = true + }, -- crimson sword + { + itemId = 7384, + type = WEAPON_SWORD, + level = 60, + unproperly = true + }, -- mystic blade + { + itemId = 7383, + type = WEAPON_SWORD, + level = 50, + unproperly = true + }, -- relic sword + { + itemId = 7382, + type = WEAPON_SWORD, + level = 60, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- demonrage sword + { + itemId = 7381, + type = WEAPON_CLUB, + level = 20, + unproperly = true + }, -- mammoth whopper + { + itemId = 7380, + type = WEAPON_AXE, + level = 35, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- headchopper + { + itemId = 7379, + type = WEAPON_CLUB, + level = 25, + unproperly = true + }, -- brutetamer's staff + { + itemId = 7378, + type = WEAPON_DISTANCE, + level = 25, + unproperly = true, + breakChance = 3 + }, -- royal spear + { + itemId = 7368, + type = WEAPON_DISTANCE, + level = 80, + unproperly = true, + breakChance = 33 + }, -- assassin star + { + itemId = 7367, + type = WEAPON_DISTANCE, + level = 42, + unproperly = true, + breakChance = 1 + }, -- enchanted spear + { + itemId = 7365, + type = WEAPON_AMMO, + level = 40, + unproperly = true, + action = "removecount" + }, -- onyx arrow + { + itemId = 7364, + type = WEAPON_AMMO, + level = 20, + unproperly = true, + action = "removecount" + }, -- sniper arrow + { + itemId = 7363, + type = WEAPON_AMMO, + level = 30, + unproperly = true, + action = "removecount" + }, -- piercing bolt + { + itemId = 6553, + type = WEAPON_AXE, + level = 75, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- ruthless axe + { + itemId = 6529, + type = WEAPON_AMMO, + level = 110, + unproperly = true, + action = "removecount" + }, -- infernal bolt + { + itemId = 6528, + type = WEAPON_SWORD, + level = 75, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- the avenger + { + itemId = 6101, + type = WEAPON_SWORD + }, -- Ron the Ripper's sabre + { + itemId = 5803, + type = WEAPON_DISTANCE, + level = 75, + unproperly = true, + vocation = { + {"Paladin", true}, + {"Royal Paladin"} + } + }, -- arbalest + { + itemId = 3966, + type = WEAPON_CLUB + }, -- banana staff + { + itemId = 3965, + type = WEAPON_DISTANCE, + level = 20, + unproperly = true, + breakChance = 6 + }, -- hunting spear + { + itemId = 3964, + type = WEAPON_AXE + }, -- ripper lance + { + itemId = 3963, + type = WEAPON_SWORD + }, -- templar scytheblade + { + itemId = 3962, + type = WEAPON_AXE, + level = 30, + unproperly = true + }, -- beastslayer axe + { + itemId = 3961, + type = WEAPON_CLUB, + level = 40, + unproperly = true + }, -- lich staff + { + itemId = 2550, + type = WEAPON_CLUB + }, -- scythe + { + itemId = 2547, + type = WEAPON_AMMO, + level = 55, + unproperly = true, + action = "removecount" + }, -- power bolt + { + itemId = 2544, + type = WEAPON_AMMO, + action = "removecount" + }, -- arrow + { + itemId = 2543, + type = WEAPON_AMMO, + action = "removecount" + }, -- bolt + { + itemId = 2456, + type = WEAPON_DISTANCE + }, -- bow + { + itemId = 2455, + type = WEAPON_DISTANCE + }, -- crossbow + { + itemId = 2454, + type = WEAPON_AXE, + level = 65, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- war axe + { + itemId = 2453, + type = WEAPON_CLUB, + level = 75, + unproperly = true + }, -- arcane staff + { + itemId = 2452, + type = WEAPON_CLUB, + level = 70, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- heavy mace + { + itemId = 2451, + type = WEAPON_SWORD, + level = 35, + unproperly = true + }, -- djinn blade + { + itemId = 2450, + type = WEAPON_SWORD + }, -- bone sword + { + itemId = 2449, + type = WEAPON_CLUB + }, -- bone club + { + itemId = 2448, + type = WEAPON_CLUB + }, -- studded club + { + itemId = 2447, + type = WEAPON_AXE, + level = 50, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- twin axe + { + itemId = 2446, + type = WEAPON_SWORD, + level = 45, + unproperly = true + }, -- pharaoh sword + { + itemId = 2445, + type = WEAPON_CLUB, + level = 35, + unproperly = true + }, -- crystal mace + { + itemId = 2444, + type = WEAPON_CLUB, + level = 65, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- hammer of wrath + { + itemId = 2443, + type = WEAPON_AXE, + level = 70, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- ravager's axe + { + itemId = 2442, + type = WEAPON_SWORD + }, -- heavy machete + { + itemId = 2441, + type = WEAPON_AXE + }, -- daramian axe + { + itemId = 2440, + type = WEAPON_AXE, + level = 25, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- daramian waraxe + { + itemId = 2439, + type = WEAPON_CLUB + }, -- daramian mace + { + itemId = 2438, + type = WEAPON_SWORD, + level = 30, + unproperly = true + }, -- epee + { + itemId = 2437, + type = WEAPON_CLUB + }, -- light mace + { + itemId = 2436, + type = WEAPON_CLUB, + level = 30, + unproperly = true + }, -- skull staff + { + itemId = 2435, + type = WEAPON_AXE, + level = 20, + unproperly = true + }, -- dwarven axe + { + itemId = 2434, + type = WEAPON_CLUB, + level = 25, + unproperly = true + }, -- dragon hammer + { + itemId = 2433, + type = WEAPON_CLUB + }, -- enchanted staff + { + itemId = 2432, + type = WEAPON_AXE, + level = 35, + unproperly = true + }, -- fire axe + { + itemId = 2431, + type = WEAPON_AXE, + level = 90, + unproperly = true + }, -- stonecutter axe + { + itemId = 2430, + type = WEAPON_AXE, + level = 25, + unproperly = true + }, -- knight axe + { + itemId = 2429, + type = WEAPON_AXE, + level = 20, + unproperly = true + }, -- barbarian axe + { + itemId = 2428, + type = WEAPON_AXE + }, -- orcish axe + { + itemId = 2427, + type = WEAPON_AXE, + level = 55, + unproperly = true + }, -- guardian halberd + { + itemId = 2426, + type = WEAPON_AXE, + level = 25, + unproperly = true + }, -- naginata + { + itemId = 2425, + type = WEAPON_AXE, + level = 20, + unproperly = true + }, -- obsidian lance + { + itemId = 2424, + type = WEAPON_CLUB, + level = 45, + unproperly = true + }, -- silver mace + { + itemId = 2423, + type = WEAPON_CLUB, + level = 20, + unproperly = true + }, -- clerical mace + { + itemId = 2422, + type = WEAPON_CLUB + }, -- iron hammer + { + itemId = 2421, + type = WEAPON_CLUB, + level = 85, + unproperly = true + }, -- thunder hammer + { + itemId = 2420, + type = WEAPON_SWORD + }, -- machete + { + itemId = 2419, + type = WEAPON_SWORD + }, -- scimitar + { + itemId = 2418, + type = WEAPON_AXE + }, -- golden sickle + { + itemId = 2417, + type = WEAPON_CLUB + }, -- battle hammer + { + itemId = 2416, + type = WEAPON_CLUB + }, -- crowbar + { + itemId = 2415, + type = WEAPON_AXE, + level = 95, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- great axe + { + itemId = 2414, + type = WEAPON_AXE, + level = 60, + unproperly = true + }, -- dragon lance + { + itemId = 2413, + type = WEAPON_SWORD, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- broadsword + { + itemId = 2412, + type = WEAPON_SWORD + }, -- katana + { + itemId = 2411, + type = WEAPON_SWORD + }, -- poison dagger + { + itemId = 2410, + type = WEAPON_DISTANCE, + breakChance = 7 + }, -- throwing knife + { + itemId = 2409, + type = WEAPON_SWORD + }, -- serpent sword + { + itemId = 2408, + type = WEAPON_SWORD, + level = 120, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- warlord sword + { + itemId = 2407, + type = WEAPON_SWORD, + level = 30, + unproperly = true + }, -- bright sword + { + itemId = 2406, + type = WEAPON_SWORD + }, -- short sword + { + itemId = 2405, + type = WEAPON_AXE + }, -- sickle + { + itemId = 2404, + type = WEAPON_SWORD + }, -- combat knife + { + itemId = 2403, + type = WEAPON_SWORD + }, -- knife + { + itemId = 2402, + type = WEAPON_SWORD + }, -- silver dagger + { + itemId = 2401, + type = WEAPON_CLUB + }, -- staff + { + itemId = 2400, + type = WEAPON_SWORD, + level = 80, + unproperly = true + }, -- magic sword + { + itemId = 2399, + type = WEAPON_DISTANCE, + breakChance = 10 + }, -- throwing star + { + itemId = 2398, + type = WEAPON_CLUB + }, -- mace + { + itemId = 2397, + type = WEAPON_SWORD + }, -- longsword + { + itemId = 2396, + type = WEAPON_SWORD, + action = "removecharge", + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- ice rapier + { + itemId = 2395, + type = WEAPON_SWORD + }, -- carlin sword + { + itemId = 2394, + type = WEAPON_CLUB + }, -- morning star + { + itemId = 2393, + type = WEAPON_SWORD, + level = 55, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- giant sword + { + itemId = 2392, + type = WEAPON_SWORD, + level = 30, + unproperly = true + }, -- fire sword + { + itemId = 2391, + type = WEAPON_CLUB, + level = 50, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- war hammer + { + itemId = 2390, + type = WEAPON_SWORD, + level = 140, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- magic longsword + { + itemId = 2389, + type = WEAPON_DISTANCE, + breakChance = 3 + }, -- spear + { + itemId = 2388, + type = WEAPON_AXE + }, -- hatchet + { + itemId = 2387, + type = WEAPON_AXE, + level = 25, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- double axe + { + itemId = 2386, + type = WEAPON_AXE + }, -- axe + { + itemId = 2385, + type = WEAPON_SWORD + }, -- sabre + { + itemId = 2384, + type = WEAPON_SWORD + }, -- rapier + { + itemId = 2383, + type = WEAPON_SWORD + }, -- spike sword + { + itemId = 2382, + type = WEAPON_CLUB + }, -- club + { + itemId = 2381, + type = WEAPON_AXE, + level = 25, + unproperly = true + }, -- halberd + { + itemId = 2380, + type = WEAPON_AXE + }, -- hand axe + { + itemId = 2379, + type = WEAPON_SWORD + }, -- dagger + { + itemId = 2378, + type = WEAPON_AXE, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- battle axe + { + itemId = 2377, + type = WEAPON_SWORD, + level = 20, + unproperly = true, + vocation = { + {"Knight", true}, + {"Elite Knight"} + } + }, -- two handed sword + { + itemId = 2376, + type = WEAPON_SWORD + }, -- sword + { + itemId = 2321, + type = WEAPON_CLUB + }, -- giant smithhammer + { + itemId = 2191, + type = WEAPON_WAND, + wandType = "fire", + level = 13, + mana = 3, + damage = {13, 25}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of dragonbreath + { + itemId = 2190, + type = WEAPON_WAND, + wandType = "energy", + level = 6, + mana = 1, + damage = {8, 18}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of vortex + { + itemId = 2189, + type = WEAPON_WAND, + wandType = "energy", + level = 26, + mana = 8, + damage = {37, 53}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of cosmic energy + { + itemId = 2188, + type = WEAPON_WAND, + wandType = "death", + level = 19, + mana = 5, + damage = {23, 37}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of decay + { + itemId = 2187, + type = WEAPON_WAND, + wandType = "fire", + level = 33, + mana = 8, + damage = {56, 74}, + vocation = { + {"Sorcerer", true}, + {"Master Sorcerer"} + } + }, -- wand of inferno + { + itemId = 2186, + type = WEAPON_WAND, + wandType = "ice", + level = 13, + mana = 3, + damage = {13, 25}, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- moonlight rod + { + itemId = 2185, + type = WEAPON_WAND, + wandType = "death", + level = 19, + mana = 5, + damage = {23, 37}, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- necrotic rod + { + itemId = 2183, + type = WEAPON_WAND, + wandType = "ice", + level = 33, + mana = 13, + damage = {56, 74}, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- hailstorm rod + { + itemId = 2182, + type = WEAPON_WAND, + wandType = "earth", + level = 6, + mana = 2, + damage = {8, 18}, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- snakebit rod + { + itemId = 2181, + type = WEAPON_WAND, + wandType = "earth", + level = 26, + mana = 8, + damage = {37, 53}, + vocation = { + {"Druid", true}, + {"Elder Druid"} + } + }, -- terra rod + { + itemId = 2111, + type = WEAPON_DISTANCE, + action = "removecount" + }, -- snowball + { + itemId = 1294, + type = WEAPON_DISTANCE, + breakChance = 3 + } -- small stone +} + +for index, weaponTable in ipairs(weapons) do + local weapon = Weapon(weaponTable.type) + weapon:id(weaponTable.itemId) + + if(weaponTable.action) then + weapon:action(weaponTable.action) + end + if(weaponTable.breakChance) then + weapon:breakChance(weaponTable.breakChance) + end + if(weaponTable.level) then + weapon:level(weaponTable.level) + end + if(weaponTable.mana) then + weapon:mana(weaponTable.mana) + end + if(weaponTable.unproperly) then + weapon:wieldUnproperly(weaponTable.unproperly) + end + if(weaponTable.damage) then + weapon:damage(weaponTable.damage[1], weaponTable.damage[2]) + end + if(weaponTable.wandType) then + weapon:element(weaponTable.wandType) + end + if(weaponTable.vocation) then + for index, vocation in ipairs(weaponTable.vocation) do + weapon:vocation(vocation[1], vocation[2] or false, vocation[3] or false) + end + end + + weapon:register() +end diff --git a/data/spells/lib/spells.lua b/data/spells/lib/spells.lua new file mode 100644 index 00000000000..6a54a3e4fca --- /dev/null +++ b/data/spells/lib/spells.lua @@ -0,0 +1,506 @@ +--Pre-made areas + +--Waves +AREA_SHORTWAVE3 = { +{1, 1, 1}, +{1, 1, 1}, +{0, 3, 0} +} + +AREA_WAVE10 = { +{1, 1, 1, 1, 1, 1, 1}, +{0, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 0, 0}, +{0, 0, 0, 3, 0, 0, 0} +} + +AREA_WAVE11 = { +{1, 1, 1, 1, 1, 1, 1}, +{0, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 0, 0, 0}, +{0, 0, 0, 3, 0, 0, 0} +} + +AREA_WAVE12 = { +{0, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 0, 0, 0}, +{0, 0, 0, 3, 0, 0, 0} +} + +AREA_WAVE13 = { +{1, 1, 1, 1, 1, 1, 1}, +{1, 1, 1, 1, 1, 1, 1}, +{0, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 0, 0, 0}, +{0, 0, 0, 3, 0, 0, 0} +} + +AREA_WAVE4 = { +{1, 1, 1, 1, 1}, +{0, 1, 1, 1, 0}, +{0, 1, 1, 1, 0}, +{0, 0, 3, 0, 0} +} + +AREA_WAVE5 = { +{1, 1, 1, 1, 1}, +{0, 1, 1, 1, 0}, +{0, 1, 1, 1, 0}, +{0, 1, 1, 1, 0}, +{0, 0, 1, 0, 0}, +{0, 0, 3, 0, 0} +} + +AREA_WAVE6 = { +{0, 0, 0, 0, 0}, +{0, 1, 3, 1, 0}, +{0, 0, 0, 0, 0} +} + +AREA_WAVE7 = { +{1, 1, 1, 1, 1}, +{1, 1, 1, 1, 1}, +{0, 1, 1, 1, 0}, +{0, 1, 1, 1, 0}, +{0, 0, 3, 0, 0} +} + +AREA_SQUAREWAVE5 = { +{1, 1, 1}, +{1, 1, 1}, +{1, 1, 1}, +{0, 1, 0}, +{0, 3, 0} +} + +AREA_SQUAREWAVE6 = { +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} +} + +AREA_SQUAREWAVE7 = { +{0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} +} + +--Diagonal waves +AREADIAGONAL_WAVE4 = { +{0, 0, 0, 0, 1, 0}, +{0, 0, 0, 1, 1, 0}, +{0, 0, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 0}, +{1, 1, 1, 1, 1, 0}, +{0, 0, 0, 0, 0, 3} +} + +AREADIAGONAL_SQUAREWAVE5 = { +{1, 1, 1, 0, 0}, +{1, 1, 1, 0, 0}, +{1, 1, 1, 0, 0}, +{0, 0, 0, 1, 0}, +{0, 0, 0, 0, 3} +} + +AREADIAGONAL_WAVE6 = { +{0, 0, 1}, +{0, 3, 0}, +{1, 0, 0} +} + +AREADIAGONAL_WAVE7 = { +{0, 0, 0, 0, 0, 1, 0}, +{0, 0, 0, 0, 1, 1, 0}, +{0, 0, 0, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 0}, +{1, 1, 1, 1, 1, 1, 0}, +{0, 0, 0, 0, 0, 0, 3} +} + +--Beams +AREA_BEAM1 = { +{3} +} + +AREA_BEAM5 = { +{1}, +{1}, +{1}, +{1}, +{3} +} + +AREA_BEAM7 = { +{1}, +{1}, +{1}, +{1}, +{1}, +{1}, +{3} +} + +AREA_BEAM8 = { +{1}, +{1}, +{1}, +{1}, +{1}, +{1}, +{1}, +{3} +} + +--Diagonal Beams +AREADIAGONAL_BEAM5 = { +{1, 0, 0, 0, 0}, +{0, 1, 0, 0, 0}, +{0, 0, 1, 0, 0}, +{0, 0, 0, 1, 0}, +{0, 0, 0, 0, 3} +} + +AREADIAGONAL_BEAM7 = { +{1, 0, 0, 0, 0, 0, 0}, +{0, 1, 0, 0, 0, 0, 0}, +{0, 0, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 0, 0}, +{0, 0, 0, 0, 0, 1, 0}, +{0, 0, 0, 0, 0, 0, 3} +} + +--Circles +AREA_CIRCLE2X2 = { +{0, 1, 1, 1, 0}, +{1, 1, 1, 1, 1}, +{1, 1, 3, 1, 1}, +{1, 1, 1, 1, 1}, +{0, 1, 1, 1, 0} +} + +AREA_CIRCLE3X3 = { +{0, 0, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 0}, +{1, 1, 1, 1, 1, 1, 1}, +{1, 1, 1, 3, 1, 1, 1}, +{1, 1, 1, 1, 1, 1, 1}, +{0, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 0, 0} +} + +AREA_CIRCLE3X32 = { +{1, 1, 1, 1, 1, 1, 1}, +{1, 1, 1, 1, 1, 1, 1}, +{1, 1, 1, 1, 1, 1, 1}, +{1, 1, 1, 3, 1, 1, 1}, +{1, 1, 1, 1, 1, 1, 1}, +{1, 1, 1, 1, 1, 1, 1}, +{1, 1, 1, 1, 1, 1, 1} +} + +AREA_CIRCLE3X33 = { +{1, 1, 1, 1, 1, 1, 1}, +{1, 1, 1, 1, 1, 1, 1}, +{1, 1, 0, 0, 1, 1, 1}, +{1, 1, 0, 3, 1, 1, 1}, +{1, 1, 0, 1, 1, 1, 1}, +{1, 1, 1, 1, 1, 1, 1}, +{1, 1, 1, 1, 1, 1, 1} +} + +-- Crosses +AREA_CIRCLE1X1 = { +{0, 1, 0}, +{1, 3, 1}, +{0, 1, 0} +} + +AREA_CIRCLE5X5 = { +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0} +} + +AREA_CIRCLE5X5V2 = { +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 3, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +} + +AREA_CIRCLE6X6 = { +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0} +} + +--Squares +AREA_SQUARE1X1 = { +{1, 1, 1}, +{1, 3, 1}, +{1, 1, 1} +} + +-- Walls +AREA_WALLFIELD = { +{1, 1, 3, 1, 1} +} + +AREADIAGONAL_WALLFIELD = { +{0, 0, 0, 0, 1}, +{0, 0, 0, 1, 1}, +{0, 1, 3, 1, 0}, +{1, 1, 0, 0, 0}, +{1, 0, 0, 0, 0}, +} + +-- Walls Energy +AREA_WALLFIELD_ENERGY = { +{1, 1, 1, 3, 1, 1, 1} +} + +AREADIAGONAL_WALLFIELD_ENERGY = { +{0, 0, 0, 0, 0, 0, 1}, +{0, 0, 0, 0, 0, 1, 1}, +{0, 0, 0, 0, 1, 1, 0}, +{0, 0, 1, 3, 1, 0, 0}, +{0, 1, 1, 0, 0, 0, 0}, +{0, 1, 0, 0, 0, 0, 0}, +{1, 0, 0, 0, 0, 0, 0}, +} + +-- Spells-only arrays + +--This HUGE array contains all corpses of the game, until protocol 8.0 +-- It is used on animate dead rune and on undead legion spell. No unmoveable corpses are there. +CORPSES = { +2806,2807,2808,2809,2810,2811,2812,2813,2814,2815,2816,2817,2818,2819,2820,2821,2822,2823, +2824,2825,2826,2827,2828,2829,2830,2831,2832,2833,2834,2835,2836,2837,2838,2839,2840,2841, +2842,2843,2844,2845,2846,2847,2848,2849,2850,2851,2852,2853,2854,2855,2856,2857,2858,2859, +2879,2880,2881,2882,2883,2884,2885,2886,2887,2888,2889,2890,2891,2892,2893,2894,2895,2896, +2897,2898,2899,2900,2901,2902,2903,2904,2905,2906,2907,2908,2909,2910,2911,2912,2913,2914, +2915,2916,2917,2918,2919,2920,2921,2922,2923,2924,2925,2926,2927,2928,2929,2930,2931,2932, +2933,2934,2935,2936,2937,2938,2939,2940,2941,2942,2943,2944,2945,2946,2947,2948,2949,2950, +2951,2952,2953,2954,2955,2956,2957,2958,2959,2960,2961,2962,2963,2964,2965,2966,2967,2968, +2969,2970,2971,2972,2973,2974,2975,2976,2977,2978,2979,2980,2981,2982,2983,2984,2985,2986, +2987,2988,2989,2990,2991,2992,2993,2994,2995,2996,2997,2998,2999,3000,3001,3002,3003,3004, +3005,3006,3007,3008,3009,3010,3011,3012,3013,3014,3015,3016,3017,3018,3019,3020,3021,3022, +3023,3024,3025,3026,3027,3028,3029,3030,3031,3032,3033,3034,3035,3036,3037,3038,3039,3040, +3041,3042,3043,3044,3045,3046,3047,3048,3049,3050,3051,3052,3053,3054,3055,3056,3057,3058, +3059,3060,3061,3062,3063,3064,3065,3066,3067,3068,3069,3070,3071,3072,3073,3074,3075,3076, +3077,3078,3079,3080,3081,3082,3083,3084,3085,3086,3087,3088,3089,3090,3091,3092,3093,3094, +3095,3096,3097,3098,3099,3100,3101,3102,3103,3104,3105,3106,3107,3108,3109,3110,3111,3112, +3113,3114,3115,3116,3117,3118,3119,3120,3121,3128,3129,3130,3131,3132,3133,3134,4252,4253, +4254,4255,4256,4257,4258,4259,4260,4261,4262,4263,4264,4265,4266,4267,4268,4269,4270,4271, +4272,4273,4274,4275,4276,4277,4278,4279,4280,4281,4282,4283,4284,4285,4286,4287,4288,4289, +4290,4291,4292,4293,4294,4295,4296,4297,4298,4299,4300,4301,4302,4303,4304,4305,4306,4307, +4308,4309,4310,4311,4312,4313,4314,4315,4316,4317,4318,4319,4320,4321,4322,4323,4324,4325, +4326,4327,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536,5537, +5538,5540,5541,5542,5565,5566,5567,5568,5625,5626,5627,5628,5629,5630,5666,5667,5668,5688, +5689,5690,5727,5728,5729,5762,5765,5766,5767,5931,5932,5933,5934,5935,5936,5965,6022,6082, +6083,6084,6303,6304,6305,6307,6308,6309,6310,6313,6314,6315,6317,6318,6319,6321,6322,6323, +6325,6326,6327,6328,6329,6330,6333,6334,6335,6337,6338,6339,6341,6342,6343,6345,6346,6347, +6349,6350,6351,6355,6365,6366,6367,6520,6521,6522,6560,7092,7093,7094,7256,7257,7258,7283, +7284,7285,7317,7318,7319,7321,7322,7323,7325,7326,7328,7329,7331,7332,7333,7335,7336,7337, +7339,7340,7341,7345,7346,7347,7623,7624,7625,7626,7627,7629,7630,7631,7638,7639,7640,7741, +7742,7743,7848,7849,7908,7927,7928,7929,7931,7970,7971,8272} + +-- This array contains all destroyable field items +FIELDS = {1487,1488,1489,1490,1491,1492,1493,1494,1495,1496,1500,1501,1502,1503,1504} + +-- The numbered-keys represents the damage values, and their table +-- contains the minimum and maximum number of rounds of those damage values. +RANGE = { +[1] = {19, 20}, [2] = {10, 10}, [3] = {6, 7}, [4] = {4, 5}, [5] = {3, 4}, +[6] = {3, 4}, [7] = {2, 3}, [8] = {2, 3}, [9] = {2, 3}, [10] = {1, 2}, +[11] = {1, 2}, [12] = {1, 2}, [13] = {1, 2}, [14] = {1, 2}, [15] = {1, 2}, +[16] = {1, 2}, [17] = {1, 2}, [18] = {1, 2}, [19] = {1, 2} +} + +function Creature:addDamageCondition(target, conditionType, listType, damage, time, rounds) + if target:isImmune(conditionType) then + return false + end + + local condition = Condition(conditionType) + condition:setParameter(CONDITION_PARAM_OWNER, self:getId()) + condition:setParameter(CONDITION_PARAM_DELAYED, true) + + if listType == 0 then + local exponent, value = -10, 0 + while value < damage do + value = math.floor(10 * math.pow(1.2, exponent) + 0.5) + condition:addDamage(1, time or 4000, -value) + + if value >= damage then + local permille = math.random(10, 1200) / 1000 + condition:addDamage(1, time or 4000, -math.max(1, math.floor(value * permille + 0.5))) + else + exponent = exponent + 1 + end + end + elseif listType == 1 then + rounds = rounds or RANGE + if rounds[damage] then + condition:addDamage(math.random(1, rounds[damage][2]), time or 4000, -damage) + damage = damage - 1 + end + + while damage > 0 do + condition:addDamage(rounds[damage] and math.random(rounds[damage][1], rounds[damage][2]) or 1, time or 4000, -damage) + damage = damage - (damage > 21 and math.floor(damage / 20) + math.random(0, 1) or 1) + end + elseif listType == 2 then + for _ = 1, rounds do + condition:addDamage(1, math.random(time[1], time[2]) * 1000, -damage) + end + end + + target:addCondition(condition) + return true +end + +function Player:addPartyCondition(combat, variant, condition, baseMana) + local party = self:getParty() + if not party then + self:sendCancelMessage(RETURNVALUE_NOPARTYMEMBERSINRANGE) + self:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + + local members = party:getMembers() + members[#members + 1] = party:getLeader() + + local position = self:getPosition() + local affectedMembers = {} + for _, member in ipairs(members) do + if member:getPosition():getDistance(position) <= 36 then + affectedMembers[#affectedMembers + 1] = member + end + end + + if #affectedMembers <= 1 then + self:sendCancelMessage(RETURNVALUE_NOPARTYMEMBERSINRANGE) + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + local mana = math.ceil(math.pow(0.9, #affectedMembers - 1) * baseMana * #affectedMembers) + if self:getMana() < mana then + self:sendCancelMessage(RETURNVALUE_NOTENOUGHMANA) + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + if not combat:execute(self, variant) then + self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + self:addMana(baseMana - mana, false) + self:addManaSpent(mana - baseMana) + + for _, member in ipairs(affectedMembers) do + member:addCondition(condition) + end + return true +end + +function Player:conjureItem(reagentId, conjureId, conjureCount, effect) + if not conjureCount and conjureId ~= 0 then + local itemType = ItemType(conjureId) + if itemType:getId() == 0 then + return false + end + + local charges = itemType:getCharges() + if charges ~= 0 then + conjureCount = charges + end + end + + if reagentId ~= 0 and not self:removeItem(reagentId, 1, -1) then + self:sendCancelMessage(RETURNVALUE_YOUNEEDAMAGICITEMTOCASTSPELL) + self:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + + local item = self:addItem(conjureId, conjureCount) + if not item then + self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + self:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + + if item:hasAttribute(ITEM_ATTRIBUTE_DURATION) then + item:decay() + end + + self:getPosition():sendMagicEffect(item:getType():isRune() and CONST_ME_MAGIC_RED or effect) + return true +end diff --git a/data/spells/scripts/attack/annihilation.lua b/data/spells/scripts/attack/annihilation.lua new file mode 100644 index 00000000000..5223d83b23b --- /dev/null +++ b/data/spells/scripts/attack/annihilation.lua @@ -0,0 +1,18 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_WEAPONTYPE) +combat:setParameter(COMBAT_PARAM_BLOCKARMOR, 1) +combat:setParameter(COMBAT_PARAM_USECHARGES, 1) + +function onGetFormulaValues(player, skill, attack, factor) + local skillTotal = skill * attack + local levelTotal = player:getLevel() / 5 + return -(((skillTotal * 0.17) + 13) + (levelTotal)) * 1.28, -(((skillTotal * 0.20) + 34) + (levelTotal)) * 1.28 -- TODO : Use New Real Formula instead of an % +end + +combat:setCallback(CALLBACK_PARAM_SKILLVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/apprentices strike.lua b/data/spells/scripts/attack/apprentices strike.lua new file mode 100644 index 00000000000..7c35d13ce07 --- /dev/null +++ b/data/spells/scripts/attack/apprentices strike.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREATTACK) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 0.4) + 3 + local max = (level / 5) + (maglevel * 0.7) + 5 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/avalanche.lua b/data/spells/scripts/attack/avalanche.lua new file mode 100644 index 00000000000..3320838c0d1 --- /dev/null +++ b/data/spells/scripts/attack/avalanche.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ICE) +combat:setArea(createCombatArea(AREA_CIRCLE3X3)) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 1.2) + 7 + local max = (level / 5) + (maglevel * 2.8) + 17 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, variant, isHotkey) + return combat:execute(creature, variant) +end diff --git a/data/spells/scripts/attack/berserk.lua b/data/spells/scripts/attack/berserk.lua new file mode 100644 index 00000000000..d4b4f5b8d72 --- /dev/null +++ b/data/spells/scripts/attack/berserk.lua @@ -0,0 +1,21 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) +combat:setParameter(COMBAT_PARAM_BLOCKARMOR, 1) +combat:setParameter(COMBAT_PARAM_USECHARGES, 1) +combat:setArea(createCombatArea(AREA_SQUARE1X1)) + +function onGetFormulaValues(player, skill, attack, factor) + local level = player:getLevel() + + local min = (level / 5) + (skill + attack) * 0.5 + local max = (level / 5) + (skill + attack) * 1.5 + + return -min * 1.1, -max * 1.1 -- TODO : Use New Real Formula instead of an % +end + +combat:setCallback(CALLBACK_PARAM_SKILLVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/brutal strike.lua b/data/spells/scripts/attack/brutal strike.lua new file mode 100644 index 00000000000..8cdcf6d7b87 --- /dev/null +++ b/data/spells/scripts/attack/brutal strike.lua @@ -0,0 +1,18 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_WEAPONTYPE) +combat:setParameter(COMBAT_PARAM_BLOCKARMOR, 1) +combat:setParameter(COMBAT_PARAM_USECHARGES, 1) + +function onGetFormulaValues(player, skill, attack, factor) + local skillTotal = skill * attack + local levelTotal = player:getLevel() / 5 + return -(((skillTotal * 0.02) + 4) + (levelTotal)) * 1.28, -(((skillTotal * 0.04) + 9) + (levelTotal)) * 1.28 -- TODO : Use New Real Formula instead of an % +end + +combat:setCallback(CALLBACK_PARAM_SKILLVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/buzz.lua b/data/spells/scripts/attack/buzz.lua new file mode 100644 index 00000000000..0b8f5588331 --- /dev/null +++ b/data/spells/scripts/attack/buzz.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 0.4) + 3 + local max = (level / 5) + (maglevel * 0.7) + 5 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/chill_out.lua b/data/spells/scripts/attack/chill_out.lua new file mode 100644 index 00000000000..83dae7c4725 --- /dev/null +++ b/data/spells/scripts/attack/chill_out.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEAREA) +combat:setArea(createCombatArea(AREA_WAVE4, AREADIAGONAL_WAVE4)) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 0.3) + 2 + local max = (level / 5) + (maglevel * 0.6) + 4 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/curse.lua b/data/spells/scripts/attack/curse.lua new file mode 100644 index 00000000000..79cab190904 --- /dev/null +++ b/data/spells/scripts/attack/curse.lua @@ -0,0 +1,30 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_DEATH) + +local condition = Condition(CONDITION_CURSED) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) + +condition:addDamage(1, 3000, -45) +condition:addDamage(1, 3000, -40) +condition:addDamage(1, 3000, -35) +condition:addDamage(1, 3000, -34) +condition:addDamage(2, 3000, -33) +condition:addDamage(2, 3000, -32) +condition:addDamage(2, 3000, -31) +condition:addDamage(2, 3000, -30) +condition:addDamage(3, 3000, -29) +condition:addDamage(3, 3000, -25) +condition:addDamage(3, 3000, -24) +condition:addDamage(4, 3000, -23) +condition:addDamage(4, 3000, -20) +condition:addDamage(5, 3000, -19) +condition:addDamage(5, 3000, -15) +condition:addDamage(6, 3000, -10) +condition:addDamage(10, 3000, -5) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/death strike.lua b/data/spells/scripts/attack/death strike.lua new file mode 100644 index 00000000000..74056fd1fa7 --- /dev/null +++ b/data/spells/scripts/attack/death strike.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_DEATH) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 1.403) + 8 + local max = (level / 5) + (maglevel * 2.203) + 13 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/divine caldera.lua b/data/spells/scripts/attack/divine caldera.lua new file mode 100644 index 00000000000..a4bef700353 --- /dev/null +++ b/data/spells/scripts/attack/divine caldera.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HOLYAREA) +combat:setArea(createCombatArea(AREA_CIRCLE3X3)) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 4) + local max = (level / 5) + (maglevel * 6) + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/divine missile.lua b/data/spells/scripts/attack/divine missile.lua new file mode 100644 index 00000000000..9f974ad44be --- /dev/null +++ b/data/spells/scripts/attack/divine missile.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HOLYDAMAGE) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SMALLHOLY) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 1.79) + 11 + local max = (level / 5) + (maglevel * 3) + 18 + return -min, -max +end +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/electrify.lua b/data/spells/scripts/attack/electrify.lua new file mode 100644 index 00000000000..bc3d739646a --- /dev/null +++ b/data/spells/scripts/attack/electrify.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + +local condition = Condition(CONDITION_ENERGY) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(25, 3000, -45) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/energy beam.lua b/data/spells/scripts/attack/energy beam.lua new file mode 100644 index 00000000000..b330c251edd --- /dev/null +++ b/data/spells/scripts/attack/energy beam.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT) +combat:setArea(createCombatArea(AREA_BEAM5, AREADIAGONAL_BEAM5)) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 2.5) + local max = (level / 5) + (maglevel * 4) + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/energy bomb.lua b/data/spells/scripts/attack/energy bomb.lua new file mode 100644 index 00000000000..60a275c7b76 --- /dev/null +++ b/data/spells/scripts/attack/energy bomb.lua @@ -0,0 +1,10 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGYBALL) +combat:setParameter(COMBAT_PARAM_CREATEITEM, ITEM_ENERGYFIELD_PVP) +combat:setArea(createCombatArea(AREA_SQUARE1X1)) + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/energy field.lua b/data/spells/scripts/attack/energy field.lua new file mode 100644 index 00000000000..55fb4e68ca1 --- /dev/null +++ b/data/spells/scripts/attack/energy field.lua @@ -0,0 +1,9 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGYBALL) +combat:setParameter(COMBAT_PARAM_CREATEITEM, ITEM_ENERGYFIELD_PVP) + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/energy strike.lua b/data/spells/scripts/attack/energy strike.lua new file mode 100644 index 00000000000..73f967ed5b0 --- /dev/null +++ b/data/spells/scripts/attack/energy strike.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 1.403) + 8 + local max = (level / 5) + (maglevel * 2.203) + 13 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/energy wall.lua b/data/spells/scripts/attack/energy wall.lua new file mode 100644 index 00000000000..abadfc798f7 --- /dev/null +++ b/data/spells/scripts/attack/energy wall.lua @@ -0,0 +1,10 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGYBALL) +combat:setParameter(COMBAT_PARAM_CREATEITEM, ITEM_ENERGYFIELD_PVP) +combat:setArea(createCombatArea(AREA_WALLFIELD_ENERGY, AREADIAGONAL_WALLFIELD_ENERGY)) + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/energy wave.lua b/data/spells/scripts/attack/energy wave.lua new file mode 100644 index 00000000000..4eb27b28e98 --- /dev/null +++ b/data/spells/scripts/attack/energy wave.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) +combat:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5)) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 4.5) + local max = (level / 5) + (maglevel * 9) + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, variant) + return combat:execute(creature, variant) +end diff --git a/data/spells/scripts/attack/envenom.lua b/data/spells/scripts/attack/envenom.lua new file mode 100644 index 00000000000..92a65961cce --- /dev/null +++ b/data/spells/scripts/attack/envenom.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLPLANTS) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_EARTH) + +local condition = Condition(CONDITION_POISON) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(25, 3000, -45) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/eternal winter.lua b/data/spells/scripts/attack/eternal winter.lua new file mode 100644 index 00000000000..e4ac1fa34ee --- /dev/null +++ b/data/spells/scripts/attack/eternal winter.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICETORNADO) +combat:setArea(createCombatArea(AREA_CIRCLE5X5)) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 6) + local max = (level / 5) + (maglevel * 12) + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, variant) + return combat:execute(creature, variant) +end diff --git a/data/spells/scripts/attack/ethereal spear.lua b/data/spells/scripts/attack/ethereal spear.lua new file mode 100644 index 00000000000..ad5b90c578b --- /dev/null +++ b/data/spells/scripts/attack/ethereal spear.lua @@ -0,0 +1,20 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ETHEREALSPEAR) +combat:setParameter(COMBAT_PARAM_BLOCKARMOR, 1) + +function onGetFormulaValues(player, skill, attack, factor) + local level = player:getLevel() + + local min = (level / 5) + (skill + 25) / 3 + local max = (level / 5) + skill + 25 + + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_SKILLVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/explosion.lua b/data/spells/scripts/attack/explosion.lua new file mode 100644 index 00000000000..3e47abd16d9 --- /dev/null +++ b/data/spells/scripts/attack/explosion.lua @@ -0,0 +1,18 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_EXPLOSION) +combat:setParameter(COMBAT_PARAM_BLOCKARMOR, 1) +combat:setArea(createCombatArea(AREA_CIRCLE1X1)) + +function onGetFormulaValues(player, level, maglevel) + local min = 0 + local max = (level / 5) + (maglevel * 4.8) + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/fierce berserk.lua b/data/spells/scripts/attack/fierce berserk.lua new file mode 100644 index 00000000000..fbef4c68483 --- /dev/null +++ b/data/spells/scripts/attack/fierce berserk.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) +combat:setParameter(COMBAT_PARAM_BLOCKARMOR, 1) +combat:setParameter(COMBAT_PARAM_USECHARGES, 1) +combat:setArea(createCombatArea(AREA_SQUARE1X1)) + +function onGetFormulaValues(player, skill, attack, factor) + local level = player:getLevel() + + local min = (level / 5) + (skill + 2 * attack) * 1.1 + local max = (level / 5) + (skill + 2 * attack) * 3 + + return -min * 1.1, -max * 1.1 -- TODO : Use New Real Formula instead of an % +end + + +combat:setCallback(CALLBACK_PARAM_SKILLVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/fire bomb.lua b/data/spells/scripts/attack/fire bomb.lua new file mode 100644 index 00000000000..9e982efaa3a --- /dev/null +++ b/data/spells/scripts/attack/fire bomb.lua @@ -0,0 +1,10 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYFIRE) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE) +combat:setParameter(COMBAT_PARAM_CREATEITEM, ITEM_FIREFIELD_PVP_FULL) +combat:setArea(createCombatArea(AREA_SQUARE1X1)) + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/fire field.lua b/data/spells/scripts/attack/fire field.lua new file mode 100644 index 00000000000..e214679eb53 --- /dev/null +++ b/data/spells/scripts/attack/fire field.lua @@ -0,0 +1,9 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYFIRE) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE) +combat:setParameter(COMBAT_PARAM_CREATEITEM, ITEM_FIREFIELD_PVP_FULL) + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/fire wall.lua b/data/spells/scripts/attack/fire wall.lua new file mode 100644 index 00000000000..203444ef6ed --- /dev/null +++ b/data/spells/scripts/attack/fire wall.lua @@ -0,0 +1,10 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYFIRE) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE) +combat:setParameter(COMBAT_PARAM_CREATEITEM, ITEM_FIREFIELD_PVP_FULL) +combat:setArea(createCombatArea(AREA_WALLFIELD, AREADIAGONAL_WALLFIELD)) + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/fire wave.lua b/data/spells/scripts/attack/fire wave.lua new file mode 100644 index 00000000000..6c4fe11731e --- /dev/null +++ b/data/spells/scripts/attack/fire wave.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYFIRE) + +local area = createCombatArea(AREA_WAVE4, AREADIAGONAL_WAVE4) +combat:setArea(area) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 1.25) + 4 + local max = (level / 5) + (maglevel * 2) + 12 + return -min, -max +end +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/fireball.lua b/data/spells/scripts/attack/fireball.lua new file mode 100644 index 00000000000..ebe135252ff --- /dev/null +++ b/data/spells/scripts/attack/fireball.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREATTACK) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 1.81) + 10 + local max = (level / 5) + (maglevel * 3) + 18 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/flame strike.lua b/data/spells/scripts/attack/flame strike.lua new file mode 100644 index 00000000000..0a130d61f64 --- /dev/null +++ b/data/spells/scripts/attack/flame strike.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREATTACK) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 1.403) + 8 + local max = (level / 5) + (maglevel * 2.203) + 13 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/front sweep.lua b/data/spells/scripts/attack/front sweep.lua new file mode 100644 index 00000000000..a2cc47b9e06 --- /dev/null +++ b/data/spells/scripts/attack/front sweep.lua @@ -0,0 +1,18 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) +combat:setParameter(COMBAT_PARAM_BLOCKARMOR, 1) +combat:setParameter(COMBAT_PARAM_USECHARGES, 1) +combat:setArea(createCombatArea(AREA_WAVE6, AREADIAGONAL_WAVE6)) + +function onGetFormulaValues(player, skill, attack, factor) + local skillTotal = skill * attack + local levelTotal = player:getLevel() / 5 + return -(((skillTotal * 0.04) + 31) + (levelTotal)) * 1.1, -(((skillTotal * 0.08) + 45) + (levelTotal)) * 1.1 -- TODO : Use New Real Formula instead of an % +end + +combat:setCallback(CALLBACK_PARAM_SKILLVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/great energy beam.lua b/data/spells/scripts/attack/great energy beam.lua new file mode 100644 index 00000000000..749eef3865e --- /dev/null +++ b/data/spells/scripts/attack/great energy beam.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA) +combat:setArea(createCombatArea(AREA_BEAM8)) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 4) + local max = (level / 5) + (maglevel * 7) + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/great fire wave.lua b/data/spells/scripts/attack/great fire wave.lua new file mode 100644 index 00000000000..033d617795e --- /dev/null +++ b/data/spells/scripts/attack/great fire wave.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYFIRE) + +local area = createCombatArea(AREA_WAVE7, AREADIAGONAL_WAVE7) +combat:setArea(area) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 2.8) + 16 + local max = (level / 5) + (maglevel * 4.4) + 28 -- TODO: Formulas (TibiaWiki says ~Strong Flame Strike but we need more acurracy) + return -min, -max +end +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/great fireball.lua b/data/spells/scripts/attack/great fireball.lua new file mode 100644 index 00000000000..fbddf57eb80 --- /dev/null +++ b/data/spells/scripts/attack/great fireball.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE) +combat:setArea(createCombatArea(AREA_CIRCLE3X3)) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 1.2) + 7 + local max = (level / 5) + (maglevel * 2.8) + 17 + return -min, -max +end +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/groundshaker.lua b/data/spells/scripts/attack/groundshaker.lua new file mode 100644 index 00000000000..39ceeaf0b25 --- /dev/null +++ b/data/spells/scripts/attack/groundshaker.lua @@ -0,0 +1,21 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GROUNDSHAKER) +combat:setParameter(COMBAT_PARAM_BLOCKARMOR, 1) +combat:setParameter(COMBAT_PARAM_USECHARGES, 1) +combat:setArea(createCombatArea(AREA_CIRCLE3X3)) + +function onGetFormulaValues(player, skill, attack, factor) + local level = player:getLevel() + + local min = (level / 5) + (skill + attack) * 0.5 + local max = (level / 5) + (skill + attack) * 1.1 + + return -min * 1.28, -max * 1.28 -- TODO : Use New Real Formula instead of an % +end + +combat:setCallback(CALLBACK_PARAM_SKILLVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/heavy magic missile.lua b/data/spells/scripts/attack/heavy magic missile.lua new file mode 100644 index 00000000000..a2652c6be55 --- /dev/null +++ b/data/spells/scripts/attack/heavy magic missile.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 0.4) + 2 + local max = (level / 5) + (maglevel * 1.59) + 10 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/hells core.lua b/data/spells/scripts/attack/hells core.lua new file mode 100644 index 00000000000..f31becd4d67 --- /dev/null +++ b/data/spells/scripts/attack/hells core.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREAREA) +combat:setArea(createCombatArea(AREA_CIRCLE5X5)) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 10) + local max = (level / 5) + (maglevel * 14) + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, variant) + return combat:execute(creature, variant) +end diff --git a/data/spells/scripts/attack/holy flash.lua b/data/spells/scripts/attack/holy flash.lua new file mode 100644 index 00000000000..719c857e4ca --- /dev/null +++ b/data/spells/scripts/attack/holy flash.lua @@ -0,0 +1,12 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SMALLHOLY) + +local condition = Condition(CONDITION_DAZZLED) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(math.random(7,11), 3000, -20) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/holy missile.lua b/data/spells/scripts/attack/holy missile.lua new file mode 100644 index 00000000000..86c93ae3132 --- /dev/null +++ b/data/spells/scripts/attack/holy missile.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HOLYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HOLYAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_HOLY) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 1.79) + 11 + local max = (level / 5) + (maglevel * 3.75) + 24 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/ice strike.lua b/data/spells/scripts/attack/ice strike.lua new file mode 100644 index 00000000000..46c394ad6ce --- /dev/null +++ b/data/spells/scripts/attack/ice strike.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEATTACK) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SMALLICE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 1.403) + 8 + local max = (level / 5) + (maglevel * 2.203) + 13 + return -min, -max +end + + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/ice wave.lua b/data/spells/scripts/attack/ice wave.lua new file mode 100644 index 00000000000..bdc9bfbd59e --- /dev/null +++ b/data/spells/scripts/attack/ice wave.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEAREA) +combat:setArea(createCombatArea(AREA_WAVE4, AREADIAGONAL_WAVE4)) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 0.81) + 4 + local max = (level / 5) + (maglevel * 2) + 12 + return -min, -max +end +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/icicle.lua b/data/spells/scripts/attack/icicle.lua new file mode 100644 index 00000000000..0f08e538f30 --- /dev/null +++ b/data/spells/scripts/attack/icicle.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ICE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 1.81) + 10 + local max = (level / 5) + (maglevel * 3) + 18 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/ignite.lua b/data/spells/scripts/attack/ignite.lua new file mode 100644 index 00000000000..1027d63716d --- /dev/null +++ b/data/spells/scripts/attack/ignite.lua @@ -0,0 +1,12 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(25, 3000, -45) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/inflict wound.lua b/data/spells/scripts/attack/inflict wound.lua new file mode 100644 index 00000000000..9e4ca6513ae --- /dev/null +++ b/data/spells/scripts/attack/inflict wound.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_TARGETCASTERORTOPMOST, 1) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_DRAWBLOOD) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_WEAPONTYPE) +combat:setParameter(COMBATPARAM_USECHARGES, 1) + +local condition = Condition(CONDITION_BLEEDING) +condition:setParameter(CONDITION_PARAM_DELAYED, 10) +condition:addDamage(15, 2000, -50) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/light magic missile.lua b/data/spells/scripts/attack/light magic missile.lua new file mode 100644 index 00000000000..8bb14104f9a --- /dev/null +++ b/data/spells/scripts/attack/light magic missile.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 0.4) + 2 + local max = (level / 5) + (maglevel * 0.81) + 4 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/light stone shower.lua b/data/spells/scripts/attack/light stone shower.lua new file mode 100644 index 00000000000..53579533e29 --- /dev/null +++ b/data/spells/scripts/attack/light stone shower.lua @@ -0,0 +1,19 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_STONES) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_EARTH) +combat:setArea(createCombatArea(AREA_CIRCLE1X1)) + +function onGetFormulaValues(player, level, maglevel) + level = math.min(level, 20) + maglevel = math.min(maglevel, 20) + local min = (level / 5) + (maglevel * 0.3) + 2 + local max = (level / 5) + (maglevel * 0.45) + 3 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, variant, isHotkey) + return combat:execute(creature, variant) +end diff --git a/data/spells/scripts/attack/lightest magic missile.lua b/data/spells/scripts/attack/lightest magic missile.lua new file mode 100644 index 00000000000..1794ea5e775 --- /dev/null +++ b/data/spells/scripts/attack/lightest magic missile.lua @@ -0,0 +1,14 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + +function onGetFormulaValues(player, level, maglevel) + return -3, -5 +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/lightest missile.lua b/data/spells/scripts/attack/lightest missile.lua new file mode 100644 index 00000000000..7b23ba65e2c --- /dev/null +++ b/data/spells/scripts/attack/lightest missile.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 0.4) + 3 + local max = (level / 5) + (maglevel * 0.8) + 5 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/lightning.lua b/data/spells/scripts/attack/lightning.lua new file mode 100644 index 00000000000..9126bdc7d83 --- /dev/null +++ b/data/spells/scripts/attack/lightning.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 2.2) + 12 + local max = (level / 5) + (maglevel * 3.4) + 21 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/mud_attack.lua b/data/spells/scripts/attack/mud_attack.lua new file mode 100644 index 00000000000..56081526d87 --- /dev/null +++ b/data/spells/scripts/attack/mud_attack.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_CARNIPHILA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SMALLEARTH) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 0.4) + 3 + local max = (level / 5) + (maglevel * 0.7) + 5 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/physical strike.lua b/data/spells/scripts/attack/physical strike.lua new file mode 100644 index 00000000000..d6c28d43771 --- /dev/null +++ b/data/spells/scripts/attack/physical strike.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_EXPLOSION) +combat:setParameter(COMBAT_PARAM_BLOCKARMOR, 1) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 1.403) + 8 + local max = (level / 5) + (maglevel * 2.203) + 13 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/poison bomb.lua b/data/spells/scripts/attack/poison bomb.lua new file mode 100644 index 00000000000..daebbaa9c2c --- /dev/null +++ b/data/spells/scripts/attack/poison bomb.lua @@ -0,0 +1,10 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GREEN_RINGS) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) +combat:setParameter(COMBAT_PARAM_CREATEITEM, ITEM_POISONFIELD_PVP) +combat:setArea(createCombatArea(AREA_SQUARE1X1)) + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/poison field.lua b/data/spells/scripts/attack/poison field.lua new file mode 100644 index 00000000000..30c235c9137 --- /dev/null +++ b/data/spells/scripts/attack/poison field.lua @@ -0,0 +1,9 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GREEN_RINGS) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) +combat:setParameter(COMBAT_PARAM_CREATEITEM, ITEM_POISONFIELD_PVP) + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/poison wall.lua b/data/spells/scripts/attack/poison wall.lua new file mode 100644 index 00000000000..be2fece9143 --- /dev/null +++ b/data/spells/scripts/attack/poison wall.lua @@ -0,0 +1,10 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GREEN_RINGS) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) +combat:setParameter(COMBAT_PARAM_CREATEITEM, ITEM_POISONFIELD_PVP) +combat:setArea(createCombatArea(AREA_WALLFIELD, AREADIAGONAL_WALLFIELD)) + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/practise fire wave.lua b/data/spells/scripts/attack/practise fire wave.lua new file mode 100644 index 00000000000..2beca088dee --- /dev/null +++ b/data/spells/scripts/attack/practise fire wave.lua @@ -0,0 +1,14 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYFIRE) +combat:setArea(createCombatArea(AREA_WAVE4, AREADIAGONAL_WAVE4)) + +function onGetFormulaValues(player, level, maglevel) + return -8, -11 +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/rage of the skies.lua b/data/spells/scripts/attack/rage of the skies.lua new file mode 100644 index 00000000000..71b5a22b883 --- /dev/null +++ b/data/spells/scripts/attack/rage of the skies.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BIGCLOUDS) +combat:setArea(createCombatArea(AREA_CIRCLE6X6)) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 7) + local max = (level / 5) + (maglevel * 14) + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, variant) + return combat:execute(creature, variant) +end diff --git a/data/spells/scripts/attack/scorch.lua b/data/spells/scripts/attack/scorch.lua new file mode 100644 index 00000000000..084324e73b2 --- /dev/null +++ b/data/spells/scripts/attack/scorch.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYFIRE) +combat:setArea(createCombatArea(AREA_WAVE4, AREADIAGONAL_WAVE4)) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 0.3) + 2 + local max = (level / 5) + (maglevel * 0.6) + 4 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/soul fire.lua b/data/spells/scripts/attack/soul fire.lua new file mode 100644 index 00000000000..d99c0110fb6 --- /dev/null +++ b/data/spells/scripts/attack/soul fire.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYFIRE) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(10, 2000, -10) +combat:addCondition(condition) + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/stalagmite.lua b/data/spells/scripts/attack/stalagmite.lua new file mode 100644 index 00000000000..33d34780af5 --- /dev/null +++ b/data/spells/scripts/attack/stalagmite.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_STONES) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_EARTH) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 0.4) + 2 + local max = (level / 5) + (maglevel * 1.59) + 10 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/stone shower.lua b/data/spells/scripts/attack/stone shower.lua new file mode 100644 index 00000000000..50011f8b670 --- /dev/null +++ b/data/spells/scripts/attack/stone shower.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_STONES) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_EARTH) +combat:setArea(createCombatArea(AREA_CIRCLE3X3)) + +function onGetFormulaValues(player, level, magicLevel) + local min = (level / 5) + (magicLevel * 1) + 6 + local max = (level / 5) + (magicLevel * 2.6) + 16 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, variant, isHotkey) + return combat:execute(creature, variant) +end diff --git a/data/spells/scripts/attack/strong energy strike.lua b/data/spells/scripts/attack/strong energy strike.lua new file mode 100644 index 00000000000..b9900530608 --- /dev/null +++ b/data/spells/scripts/attack/strong energy strike.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 2.8) + 16 + local max = (level / 5) + (maglevel * 4.4) + 28 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/strong ethereal spear.lua b/data/spells/scripts/attack/strong ethereal spear.lua new file mode 100644 index 00000000000..7a0a97ad28b --- /dev/null +++ b/data/spells/scripts/attack/strong ethereal spear.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ETHEREALSPEAR) +combat:setParameter(COMBAT_PARAM_BLOCKARMOR, 1) + +function onGetFormulaValues(player, skill, attack, factor) + local levelTotal = player:getLevel() / 5 + return -(((2 * skill + attack / 2500) * 2.30) + (levelTotal) + 7), -(((2 * skill + attack / 1875) * 3.30) + (levelTotal) + 13) +end + +combat:setCallback(CALLBACK_PARAM_SKILLVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/strong flame strike.lua b/data/spells/scripts/attack/strong flame strike.lua new file mode 100644 index 00000000000..ecf29f39f2e --- /dev/null +++ b/data/spells/scripts/attack/strong flame strike.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREATTACK) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 2.8) + 16 + local max = (level / 5) + (maglevel * 4.4) + 28 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/strong ice strike.lua b/data/spells/scripts/attack/strong ice strike.lua new file mode 100644 index 00000000000..5ab6cca75a9 --- /dev/null +++ b/data/spells/scripts/attack/strong ice strike.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEATTACK) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SMALLICE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 2.8) + 16 + local max = (level / 5) + (maglevel * 4.4) + 28 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/strong ice wave.lua b/data/spells/scripts/attack/strong ice wave.lua new file mode 100644 index 00000000000..16f42158a72 --- /dev/null +++ b/data/spells/scripts/attack/strong ice wave.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEAREA) +combat:setArea(createCombatArea(AREA_SHORTWAVE3)) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 4.5) + 20 + local max = (level / 5) + (maglevel * 7.6) + 48 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/strong terra strike.lua b/data/spells/scripts/attack/strong terra strike.lua new file mode 100644 index 00000000000..3019d64bd41 --- /dev/null +++ b/data/spells/scripts/attack/strong terra strike.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_CARNIPHILA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SMALLEARTH) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 2.8) + 16 + local max = (level / 5) + (maglevel * 4.4) + 28 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/sudden death.lua b/data/spells/scripts/attack/sudden death.lua new file mode 100644 index 00000000000..e7387e88758 --- /dev/null +++ b/data/spells/scripts/attack/sudden death.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 4.605) + 28 + local max = (level / 5) + (maglevel * 7.395) + 46 + return -min, -max +end +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/terra strike.lua b/data/spells/scripts/attack/terra strike.lua new file mode 100644 index 00000000000..b7c905a1739 --- /dev/null +++ b/data/spells/scripts/attack/terra strike.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_CARNIPHILA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SMALLEARTH) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 1.403) + 8 + local max = (level / 5) + (maglevel * 2.203) + 13 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/terra wave.lua b/data/spells/scripts/attack/terra wave.lua new file mode 100644 index 00000000000..6fd62c56905 --- /dev/null +++ b/data/spells/scripts/attack/terra wave.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLPLANTS) +combat:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5)) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 3.5) + local max = (level / 5) + (maglevel * 7) + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, variant) + return combat:execute(creature, variant) +end diff --git a/data/spells/scripts/attack/thunderstorm.lua b/data/spells/scripts/attack/thunderstorm.lua new file mode 100644 index 00000000000..7e8ee63f2bb --- /dev/null +++ b/data/spells/scripts/attack/thunderstorm.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGYBALL) +combat:setArea(createCombatArea(AREA_CIRCLE3X3)) + +function onGetFormulaValues(player, level, magicLevel) + local min = (level / 5) + (magicLevel * 1) + 6 + local max = (level / 5) + (magicLevel * 2.6) + 16 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, variant, isHotkey) + return combat:execute(creature, variant) +end diff --git a/data/spells/scripts/attack/ultimate energy strike.lua b/data/spells/scripts/attack/ultimate energy strike.lua new file mode 100644 index 00000000000..ba58f08ad13 --- /dev/null +++ b/data/spells/scripts/attack/ultimate energy strike.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 4.5) + 35 + local max = (level / 5) + (maglevel * 7.3) + 55 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/ultimate flame strike.lua b/data/spells/scripts/attack/ultimate flame strike.lua new file mode 100644 index 00000000000..ce62c517f66 --- /dev/null +++ b/data/spells/scripts/attack/ultimate flame strike.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREATTACK) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 4.5) + 35 + local max = (level / 5) + (maglevel * 7.3) + 55 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/ultimate ice strike.lua b/data/spells/scripts/attack/ultimate ice strike.lua new file mode 100644 index 00000000000..30b69596fd7 --- /dev/null +++ b/data/spells/scripts/attack/ultimate ice strike.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEATTACK) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SMALLICE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 4.5) + 35 + local max = (level / 5) + (maglevel * 7.3) + 55 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/ultimate terra strike.lua b/data/spells/scripts/attack/ultimate terra strike.lua new file mode 100644 index 00000000000..b1aad4ddaa6 --- /dev/null +++ b/data/spells/scripts/attack/ultimate terra strike.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_CARNIPHILA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SMALLEARTH) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 4.5) + 35 + local max = (level / 5) + (maglevel * 7.3) + 55 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/whirlwind throw.lua b/data/spells/scripts/attack/whirlwind throw.lua new file mode 100644 index 00000000000..ffa71d96c36 --- /dev/null +++ b/data/spells/scripts/attack/whirlwind throw.lua @@ -0,0 +1,21 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_WEAPONTYPE) +combat:setParameter(COMBAT_PARAM_BLOCKARMOR, 1) +combat:setParameter(COMBAT_PARAM_USECHARGES, 1) + +function onGetFormulaValues(player, skill, attack, factor) + local level = player:getLevel() + + local min = (level / 5) + (skill + attack) / 3 + local max = (level / 5) + skill + attack + + return -min * 1.28, -max * 1.28 -- TODO : Use New Real Formula instead of an % +end + +combat:setCallback(CALLBACK_PARAM_SKILLVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/attack/wrath of nature.lua b/data/spells/scripts/attack/wrath of nature.lua new file mode 100644 index 00000000000..3295b7ee6e1 --- /dev/null +++ b/data/spells/scripts/attack/wrath of nature.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLPLANTS) +combat:setArea(createCombatArea(AREA_CIRCLE6X6)) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 5) + local max = (level / 5) + (maglevel * 10) + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, variant) + return combat:execute(creature, variant) +end diff --git a/data/spells/scripts/conjuring/Conjure_Wand_of_Darkness.lua b/data/spells/scripts/conjuring/Conjure_Wand_of_Darkness.lua new file mode 100644 index 00000000000..135d7f2e31e --- /dev/null +++ b/data/spells/scripts/conjuring/Conjure_Wand_of_Darkness.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(0, 29060, 1, CONST_ME_MAGIC_BLUE) +end diff --git a/data/spells/scripts/conjuring/animate_dead_rune.lua b/data/spells/scripts/conjuring/animate_dead_rune.lua new file mode 100644 index 00000000000..d377f8a8192 --- /dev/null +++ b/data/spells/scripts/conjuring/animate_dead_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2316, 1) +end diff --git a/data/spells/scripts/conjuring/arrow_call.lua b/data/spells/scripts/conjuring/arrow_call.lua new file mode 100644 index 00000000000..061a908b8dc --- /dev/null +++ b/data/spells/scripts/conjuring/arrow_call.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(0, 23839, 3, CONST_ME_MAGIC_BLUE) +end diff --git a/data/spells/scripts/conjuring/avalanche_rune.lua b/data/spells/scripts/conjuring/avalanche_rune.lua new file mode 100644 index 00000000000..551e6698487 --- /dev/null +++ b/data/spells/scripts/conjuring/avalanche_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2274, 4) +end diff --git a/data/spells/scripts/conjuring/blank_rune.lua b/data/spells/scripts/conjuring/blank_rune.lua new file mode 100644 index 00000000000..6edf7f2c403 --- /dev/null +++ b/data/spells/scripts/conjuring/blank_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(0, 2260, 1) +end diff --git a/data/spells/scripts/conjuring/chameleon_rune.lua b/data/spells/scripts/conjuring/chameleon_rune.lua new file mode 100644 index 00000000000..eeaef4300d3 --- /dev/null +++ b/data/spells/scripts/conjuring/chameleon_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2291, 1) +end diff --git a/data/spells/scripts/conjuring/conjure_arrow.lua b/data/spells/scripts/conjuring/conjure_arrow.lua new file mode 100644 index 00000000000..c930588e371 --- /dev/null +++ b/data/spells/scripts/conjuring/conjure_arrow.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(0, 2544, 10, CONST_ME_MAGIC_BLUE) +end diff --git a/data/spells/scripts/conjuring/conjure_bolt.lua b/data/spells/scripts/conjuring/conjure_bolt.lua new file mode 100644 index 00000000000..13acd1092e7 --- /dev/null +++ b/data/spells/scripts/conjuring/conjure_bolt.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(0, 2543, 5, CONST_ME_MAGIC_BLUE) +end diff --git a/data/spells/scripts/conjuring/conjure_explosive_arrow.lua b/data/spells/scripts/conjuring/conjure_explosive_arrow.lua new file mode 100644 index 00000000000..fda0294a598 --- /dev/null +++ b/data/spells/scripts/conjuring/conjure_explosive_arrow.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(0, 2546, 8, CONST_ME_MAGIC_BLUE) +end diff --git a/data/spells/scripts/conjuring/conjure_piercing_bolt.lua b/data/spells/scripts/conjuring/conjure_piercing_bolt.lua new file mode 100644 index 00000000000..b9c11801afd --- /dev/null +++ b/data/spells/scripts/conjuring/conjure_piercing_bolt.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(0, 7363, 5, CONST_ME_MAGIC_BLUE) +end diff --git a/data/spells/scripts/conjuring/conjure_poisoned_arrow.lua b/data/spells/scripts/conjuring/conjure_poisoned_arrow.lua new file mode 100644 index 00000000000..cf3ab9ea966 --- /dev/null +++ b/data/spells/scripts/conjuring/conjure_poisoned_arrow.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(0, 2545, 7, CONST_ME_MAGIC_BLUE) +end diff --git a/data/spells/scripts/conjuring/conjure_power_bolt.lua b/data/spells/scripts/conjuring/conjure_power_bolt.lua new file mode 100644 index 00000000000..bd2448564e4 --- /dev/null +++ b/data/spells/scripts/conjuring/conjure_power_bolt.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(0, 2547, 10, CONST_ME_MAGIC_BLUE) +end diff --git a/data/spells/scripts/conjuring/conjure_sniper_arrow.lua b/data/spells/scripts/conjuring/conjure_sniper_arrow.lua new file mode 100644 index 00000000000..a286d5245de --- /dev/null +++ b/data/spells/scripts/conjuring/conjure_sniper_arrow.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(0, 7364, 5, CONST_ME_MAGIC_BLUE) +end diff --git a/data/spells/scripts/conjuring/convince_creature_rune.lua b/data/spells/scripts/conjuring/convince_creature_rune.lua new file mode 100644 index 00000000000..b250a7dd01c --- /dev/null +++ b/data/spells/scripts/conjuring/convince_creature_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2290, 1) +end diff --git a/data/spells/scripts/conjuring/cure_poison_rune.lua b/data/spells/scripts/conjuring/cure_poison_rune.lua new file mode 100644 index 00000000000..2456b884336 --- /dev/null +++ b/data/spells/scripts/conjuring/cure_poison_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2266, 1) +end diff --git a/data/spells/scripts/conjuring/destroy_field_rune.lua b/data/spells/scripts/conjuring/destroy_field_rune.lua new file mode 100644 index 00000000000..4ce3fd34f1d --- /dev/null +++ b/data/spells/scripts/conjuring/destroy_field_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2261, 3) +end diff --git a/data/spells/scripts/conjuring/disintegrate_rune.lua b/data/spells/scripts/conjuring/disintegrate_rune.lua new file mode 100644 index 00000000000..ec5ec6790ad --- /dev/null +++ b/data/spells/scripts/conjuring/disintegrate_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2310, 3) +end diff --git a/data/spells/scripts/conjuring/enchant_spear.lua b/data/spells/scripts/conjuring/enchant_spear.lua new file mode 100644 index 00000000000..b534cef266a --- /dev/null +++ b/data/spells/scripts/conjuring/enchant_spear.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2389, 7367, 1, CONST_ME_MAGIC_GREEN) +end diff --git a/data/spells/scripts/conjuring/enchant_staff.lua b/data/spells/scripts/conjuring/enchant_staff.lua new file mode 100644 index 00000000000..cd794822b18 --- /dev/null +++ b/data/spells/scripts/conjuring/enchant_staff.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2401, 2433, 1, CONST_ME_MAGIC_GREEN) +end diff --git a/data/spells/scripts/conjuring/energy_bomb_rune.lua b/data/spells/scripts/conjuring/energy_bomb_rune.lua new file mode 100644 index 00000000000..470977f2432 --- /dev/null +++ b/data/spells/scripts/conjuring/energy_bomb_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2262, 2) +end diff --git a/data/spells/scripts/conjuring/energy_field_rune.lua b/data/spells/scripts/conjuring/energy_field_rune.lua new file mode 100644 index 00000000000..77a9b02482f --- /dev/null +++ b/data/spells/scripts/conjuring/energy_field_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2277, 3) +end diff --git a/data/spells/scripts/conjuring/energy_wall_rune.lua b/data/spells/scripts/conjuring/energy_wall_rune.lua new file mode 100644 index 00000000000..fa6d968fc14 --- /dev/null +++ b/data/spells/scripts/conjuring/energy_wall_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2279, 4) +end diff --git a/data/spells/scripts/conjuring/explosion_rune.lua b/data/spells/scripts/conjuring/explosion_rune.lua new file mode 100644 index 00000000000..483f619a0a0 --- /dev/null +++ b/data/spells/scripts/conjuring/explosion_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2313, 6) +end diff --git a/data/spells/scripts/conjuring/fire_bomb_rune.lua b/data/spells/scripts/conjuring/fire_bomb_rune.lua new file mode 100644 index 00000000000..4beda358408 --- /dev/null +++ b/data/spells/scripts/conjuring/fire_bomb_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2305, 2) +end diff --git a/data/spells/scripts/conjuring/fire_field_rune.lua b/data/spells/scripts/conjuring/fire_field_rune.lua new file mode 100644 index 00000000000..96c1fe3d056 --- /dev/null +++ b/data/spells/scripts/conjuring/fire_field_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2301, 3) +end diff --git a/data/spells/scripts/conjuring/fire_wall_rune.lua b/data/spells/scripts/conjuring/fire_wall_rune.lua new file mode 100644 index 00000000000..2186343aaeb --- /dev/null +++ b/data/spells/scripts/conjuring/fire_wall_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2303, 4) +end diff --git a/data/spells/scripts/conjuring/fireball_rune.lua b/data/spells/scripts/conjuring/fireball_rune.lua new file mode 100644 index 00000000000..bdcb120e279 --- /dev/null +++ b/data/spells/scripts/conjuring/fireball_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2302, 5) +end diff --git a/data/spells/scripts/conjuring/great_fireball_rune.lua b/data/spells/scripts/conjuring/great_fireball_rune.lua new file mode 100644 index 00000000000..1842809f2ab --- /dev/null +++ b/data/spells/scripts/conjuring/great_fireball_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2304, 4) +end diff --git a/data/spells/scripts/conjuring/heavy_magic_missile_rune.lua b/data/spells/scripts/conjuring/heavy_magic_missile_rune.lua new file mode 100644 index 00000000000..786c3b1e6d0 --- /dev/null +++ b/data/spells/scripts/conjuring/heavy_magic_missile_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2311, 10) +end diff --git a/data/spells/scripts/conjuring/holy_missile_rune.lua b/data/spells/scripts/conjuring/holy_missile_rune.lua new file mode 100644 index 00000000000..b4931f09d0c --- /dev/null +++ b/data/spells/scripts/conjuring/holy_missile_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2295, 5) +end diff --git a/data/spells/scripts/conjuring/icicle_rune.lua b/data/spells/scripts/conjuring/icicle_rune.lua new file mode 100644 index 00000000000..3ff841c260f --- /dev/null +++ b/data/spells/scripts/conjuring/icicle_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2271, 5) +end diff --git a/data/spells/scripts/conjuring/intense_healing_rune.lua b/data/spells/scripts/conjuring/intense_healing_rune.lua new file mode 100644 index 00000000000..9080b9a3846 --- /dev/null +++ b/data/spells/scripts/conjuring/intense_healing_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2265, 1) +end diff --git a/data/spells/scripts/conjuring/light_magic_missile_rune.lua b/data/spells/scripts/conjuring/light_magic_missile_rune.lua new file mode 100644 index 00000000000..6018747fb25 --- /dev/null +++ b/data/spells/scripts/conjuring/light_magic_missile_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2287, 10) +end diff --git a/data/spells/scripts/conjuring/light_stone_shower_rune.lua b/data/spells/scripts/conjuring/light_stone_shower_rune.lua new file mode 100644 index 00000000000..5f275853c98 --- /dev/null +++ b/data/spells/scripts/conjuring/light_stone_shower_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 23722, 4) +end diff --git a/data/spells/scripts/conjuring/lightest_magic_missile_rune.lua b/data/spells/scripts/conjuring/lightest_magic_missile_rune.lua new file mode 100644 index 00000000000..8391fde48c4 --- /dev/null +++ b/data/spells/scripts/conjuring/lightest_magic_missile_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(0, 2287, 10, CONST_ME_MAGIC_BLUE) +end diff --git a/data/spells/scripts/conjuring/lightest_missile_rune.lua b/data/spells/scripts/conjuring/lightest_missile_rune.lua new file mode 100644 index 00000000000..3da065341f0 --- /dev/null +++ b/data/spells/scripts/conjuring/lightest_missile_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 23723, 10) +end diff --git a/data/spells/scripts/conjuring/magic_wall_rune.lua b/data/spells/scripts/conjuring/magic_wall_rune.lua new file mode 100644 index 00000000000..d0964d6954c --- /dev/null +++ b/data/spells/scripts/conjuring/magic_wall_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2293, 3) +end diff --git a/data/spells/scripts/conjuring/paralyze_rune.lua b/data/spells/scripts/conjuring/paralyze_rune.lua new file mode 100644 index 00000000000..88c1b9f49f8 --- /dev/null +++ b/data/spells/scripts/conjuring/paralyze_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2278, 1) +end diff --git a/data/spells/scripts/conjuring/poison_bomb_rune.lua b/data/spells/scripts/conjuring/poison_bomb_rune.lua new file mode 100644 index 00000000000..2bfd3359581 --- /dev/null +++ b/data/spells/scripts/conjuring/poison_bomb_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2286, 2) +end diff --git a/data/spells/scripts/conjuring/poison_field_rune.lua b/data/spells/scripts/conjuring/poison_field_rune.lua new file mode 100644 index 00000000000..3c82f9188fa --- /dev/null +++ b/data/spells/scripts/conjuring/poison_field_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2285, 3) +end diff --git a/data/spells/scripts/conjuring/poison_wall_rune.lua b/data/spells/scripts/conjuring/poison_wall_rune.lua new file mode 100644 index 00000000000..841903b6233 --- /dev/null +++ b/data/spells/scripts/conjuring/poison_wall_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2289, 4) +end diff --git a/data/spells/scripts/conjuring/soulfire_rune.lua b/data/spells/scripts/conjuring/soulfire_rune.lua new file mode 100644 index 00000000000..95b19785c48 --- /dev/null +++ b/data/spells/scripts/conjuring/soulfire_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2308, 3) +end diff --git a/data/spells/scripts/conjuring/stalagmite_rune.lua b/data/spells/scripts/conjuring/stalagmite_rune.lua new file mode 100644 index 00000000000..4b8ee41da73 --- /dev/null +++ b/data/spells/scripts/conjuring/stalagmite_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2292, 10) +end diff --git a/data/spells/scripts/conjuring/stone_shower_rune.lua b/data/spells/scripts/conjuring/stone_shower_rune.lua new file mode 100644 index 00000000000..094f74afbd8 --- /dev/null +++ b/data/spells/scripts/conjuring/stone_shower_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2288, 4) +end diff --git a/data/spells/scripts/conjuring/sudden_death_rune.lua b/data/spells/scripts/conjuring/sudden_death_rune.lua new file mode 100644 index 00000000000..6e23bb319e4 --- /dev/null +++ b/data/spells/scripts/conjuring/sudden_death_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2268, 3) +end diff --git a/data/spells/scripts/conjuring/thunderstorm_rune.lua b/data/spells/scripts/conjuring/thunderstorm_rune.lua new file mode 100644 index 00000000000..4a2e6e92f17 --- /dev/null +++ b/data/spells/scripts/conjuring/thunderstorm_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2315, 4) +end diff --git a/data/spells/scripts/conjuring/ultimate_healing_rune.lua b/data/spells/scripts/conjuring/ultimate_healing_rune.lua new file mode 100644 index 00000000000..7481442f10e --- /dev/null +++ b/data/spells/scripts/conjuring/ultimate_healing_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2273, 1) +end diff --git a/data/spells/scripts/conjuring/wild_growth_rune.lua b/data/spells/scripts/conjuring/wild_growth_rune.lua new file mode 100644 index 00000000000..af73e35dd9f --- /dev/null +++ b/data/spells/scripts/conjuring/wild_growth_rune.lua @@ -0,0 +1,3 @@ +function onCastSpell(creature, variant) + return creature:conjureItem(2260, 2269, 2) +end diff --git a/data/spells/scripts/healing/antidote rune.lua b/data/spells/scripts/healing/antidote rune.lua new file mode 100644 index 00000000000..157ba14c6db --- /dev/null +++ b/data/spells/scripts/healing/antidote rune.lua @@ -0,0 +1,8 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_POISON) + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/antidote.lua b/data/spells/scripts/healing/antidote.lua new file mode 100644 index 00000000000..d7fa024c2a8 --- /dev/null +++ b/data/spells/scripts/healing/antidote.lua @@ -0,0 +1,8 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_POISON) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/bruise_bane.lua b/data/spells/scripts/healing/bruise_bane.lua new file mode 100644 index 00000000000..88ef3b28a98 --- /dev/null +++ b/data/spells/scripts/healing/bruise_bane.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 1.3) + 6 + local max = (level / 5) + (maglevel * 3) + 12 + return min, max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/cure bleeding.lua b/data/spells/scripts/healing/cure bleeding.lua new file mode 100644 index 00000000000..51425c2395e --- /dev/null +++ b/data/spells/scripts/healing/cure bleeding.lua @@ -0,0 +1,8 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_BLEEDING) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/cure burning.lua b/data/spells/scripts/healing/cure burning.lua new file mode 100644 index 00000000000..cef48b89e95 --- /dev/null +++ b/data/spells/scripts/healing/cure burning.lua @@ -0,0 +1,8 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_FIRE) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/cure curse.lua b/data/spells/scripts/healing/cure curse.lua new file mode 100644 index 00000000000..53e69c377e7 --- /dev/null +++ b/data/spells/scripts/healing/cure curse.lua @@ -0,0 +1,8 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_CURSED) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/cure electrification.lua b/data/spells/scripts/healing/cure electrification.lua new file mode 100644 index 00000000000..431bc948fda --- /dev/null +++ b/data/spells/scripts/healing/cure electrification.lua @@ -0,0 +1,8 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_ENERGY) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/divine healing.lua b/data/spells/scripts/healing/divine healing.lua new file mode 100644 index 00000000000..58779e2c720 --- /dev/null +++ b/data/spells/scripts/healing/divine healing.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 18.5) + local max = (level / 5) + (maglevel * 25) + return min, max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/fair wound cleansing.lua b/data/spells/scripts/healing/fair wound cleansing.lua new file mode 100644 index 00000000000..77b4bf754ed --- /dev/null +++ b/data/spells/scripts/healing/fair wound cleansing.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 2.5) + (maglevel * 8) + 50 + local max = (level / 2.5) + (maglevel * 16.9) + 102 -- TODO: Formulas (TibiaWiki says x2 but need more acurracy) + return min, max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/heal friend.lua b/data/spells/scripts/healing/heal friend.lua new file mode 100644 index 00000000000..c6b41d04deb --- /dev/null +++ b/data/spells/scripts/healing/heal friend.lua @@ -0,0 +1,23 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 10) + local max = (level / 5) + (maglevel * 14) + return min, max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + if creature:isPlayer() and var:getNumber() == creature:getId() then + creature:sendCancelMessage("You can't cast this spell to yourself.") + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + else + return combat:execute(creature, var) + end +end diff --git a/data/spells/scripts/healing/heal monsters 9x9.lua b/data/spells/scripts/healing/heal monsters 9x9.lua new file mode 100644 index 00000000000..0a52ea2e739 --- /dev/null +++ b/data/spells/scripts/healing/heal monsters 9x9.lua @@ -0,0 +1,27 @@ +function onTargetCreature(creature, target) + local player = creature:getPlayer() + local min = 0 + local max = 1000 + local master = target:getMaster() + + if target:isPlayer() then + return true + end + if master then + return true + end + + doTargetCombatHealth(0, target, COMBAT_HEALING, min, max, CONST_ME_NONE) + return true +end + +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE) +combat:setArea(createCombatArea(AREA_CIRCLE6X6)) +combat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/heal monsters.lua b/data/spells/scripts/healing/heal monsters.lua new file mode 100644 index 00000000000..116188b0cfc --- /dev/null +++ b/data/spells/scripts/healing/heal monsters.lua @@ -0,0 +1,27 @@ +function onTargetCreature(creature, target) + local player = creature:getPlayer() + local min = 100 + local max = 300 + local master = target:getMaster() + + if target:isPlayer() then + return true + end + if master then + return true + end + + doTargetCombatHealth(0, target, COMBAT_HEALING, min, max, CONST_ME_NONE) + return true +end + +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE) +combat:setArea(createCombatArea(AREA_CIRCLE3X3)) +combat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/intense healing rune.lua b/data/spells/scripts/healing/intense healing rune.lua new file mode 100644 index 00000000000..08cb9087e11 --- /dev/null +++ b/data/spells/scripts/healing/intense healing rune.lua @@ -0,0 +1,18 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_TARGETCASTERORTOPMOST, 1) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 3.2) + 20 + local max = (level / 5) + (maglevel * 5.4) + 40 + return min, max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/intense healing.lua b/data/spells/scripts/healing/intense healing.lua new file mode 100644 index 00000000000..a4ec0d1471e --- /dev/null +++ b/data/spells/scripts/healing/intense healing.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 3.184) + 20 + local max = (level / 5) + (maglevel * 5.59) + 35 + return min, max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/intense recovery.lua b/data/spells/scripts/healing/intense recovery.lua new file mode 100644 index 00000000000..d04a92d4524 --- /dev/null +++ b/data/spells/scripts/healing/intense recovery.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) + +local condition = Condition(CONDITION_REGENERATION) +condition:setParameter(CONDITION_PARAM_SUBID, 1) +condition:setParameter(CONDITION_PARAM_BUFF_SPELL, 1) +condition:setParameter(CONDITION_PARAM_TICKS, 1 * 60 * 1000) +condition:setParameter(CONDITION_PARAM_HEALTHGAIN, 40) +condition:setParameter(CONDITION_PARAM_HEALTHTICKS, 3000) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/intense wound cleansing.lua b/data/spells/scripts/healing/intense wound cleansing.lua new file mode 100644 index 00000000000..392740be4c5 --- /dev/null +++ b/data/spells/scripts/healing/intense wound cleansing.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 70) + 438 + local max = (level / 5) + (maglevel * 92) + 544 + return min, max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/light healing.lua b/data/spells/scripts/healing/light healing.lua new file mode 100644 index 00000000000..05d07ab0f27 --- /dev/null +++ b/data/spells/scripts/healing/light healing.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 1.4) + 8 + local max = (level / 5) + (maglevel * 1.795) + 11 + return min, max +end +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/magic_patch.lua b/data/spells/scripts/healing/magic_patch.lua new file mode 100644 index 00000000000..ba3085d6e77 --- /dev/null +++ b/data/spells/scripts/healing/magic_patch.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 0.4) + 3 + local max = (level / 5) + (maglevel * 0.6) + 4 + return min, max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/mass healing.lua b/data/spells/scripts/healing/mass healing.lua new file mode 100644 index 00000000000..0807b14f800 --- /dev/null +++ b/data/spells/scripts/healing/mass healing.lua @@ -0,0 +1,27 @@ +function onTargetCreature(creature, target) + local player = creature:getPlayer() + local min = ((player:getLevel() / 5) + (player:getMagicLevel() * 5.7) + 26) + local max = ((player:getLevel() / 5) + (player:getMagicLevel() * 10.43) + 62) + + local bosses = {"leiden", "ravennous hunger", "dorokoll the mystic", "eshtaba the conjurer", "eliz the unyielding", "mezlon the defiler", "malkhar deathbringer", "containment crystal"} + local master = target:getMaster() + if target:isMonster() and not master or master and master:isMonster() then + if (not isInArray(bosses, target:getName():lower())) then + return true + end + end + + doTargetCombatHealth(0, target, COMBAT_HEALING, min, max, CONST_ME_NONE) + return true +end + +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE) +combat:setArea(createCombatArea(AREA_CIRCLE3X3)) +combat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/nature's embrace.lua b/data/spells/scripts/healing/nature's embrace.lua new file mode 100644 index 00000000000..86c72b6464c --- /dev/null +++ b/data/spells/scripts/healing/nature's embrace.lua @@ -0,0 +1,23 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 2.5) + (maglevel * 20) + local max = (level / 2.5) + (maglevel * 28) -- TODO: Formulas (TibiaWiki says x2 but need more acurracy) + return min, max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + if creature:isPlayer() and var:getNumber() == creature:getId() then + creature:sendCancelMessage("You can't cast this spell to yourself.") + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + else + return combat:execute(creature, var) + end +end diff --git a/data/spells/scripts/healing/practise healing.lua b/data/spells/scripts/healing/practise healing.lua new file mode 100644 index 00000000000..f5f99ae1ad8 --- /dev/null +++ b/data/spells/scripts/healing/practise healing.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE) + +function onGetFormulaValues(player, level, maglevel) + return 4, 7 +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/recovery.lua b/data/spells/scripts/healing/recovery.lua new file mode 100644 index 00000000000..954cfdd2cf9 --- /dev/null +++ b/data/spells/scripts/healing/recovery.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) + +local condition = Condition(CONDITION_REGENERATION) +condition:setParameter(CONDITION_PARAM_SUBID, 1) +condition:setParameter(CONDITION_PARAM_BUFF_SPELL, 1) +condition:setParameter(CONDITION_PARAM_TICKS, 1 * 60 * 1000) +condition:setParameter(CONDITION_PARAM_HEALTHGAIN, 20) +condition:setParameter(CONDITION_PARAM_HEALTHTICKS, 3000) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/restoration.lua b/data/spells/scripts/healing/restoration.lua new file mode 100644 index 00000000000..4b88f6187bd --- /dev/null +++ b/data/spells/scripts/healing/restoration.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level * 1.4 / 5) + (maglevel * 9.22 * 1.4) + 44 * 1.4 + local max = (level * 1.4 / 5) + (maglevel * 10.79 * 1.4) + 79 * 1.4 -- TODO: Formulas (Right now using 40% extra on Ultimate Healing with closer min and max values to the avg) + return min, max +end +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/salvation.lua b/data/spells/scripts/healing/salvation.lua new file mode 100644 index 00000000000..6bbd53545bf --- /dev/null +++ b/data/spells/scripts/healing/salvation.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 12) + 75 + local max = (level / 5) + (maglevel * 20) + 125 + return min, max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/ultimate healing rune.lua b/data/spells/scripts/healing/ultimate healing rune.lua new file mode 100644 index 00000000000..82c4d115b98 --- /dev/null +++ b/data/spells/scripts/healing/ultimate healing rune.lua @@ -0,0 +1,18 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_TARGETCASTERORTOPMOST, 1) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 7.3) + 42 + local max = (level / 5) + (maglevel * 12.4) + 90 + return min, max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var, isHotkey) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/ultimate healing.lua b/data/spells/scripts/healing/ultimate healing.lua new file mode 100644 index 00000000000..64e3b7106c3 --- /dev/null +++ b/data/spells/scripts/healing/ultimate healing.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 7.22) + 44 + local max = (level / 5) + (maglevel * 12.79) + 79 + return min, max +end +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/healing/wound cleansing.lua b/data/spells/scripts/healing/wound cleansing.lua new file mode 100644 index 00000000000..4003bbf212c --- /dev/null +++ b/data/spells/scripts/healing/wound cleansing.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 4) + 25 + local max = (level / 5) + (maglevel * 7.95) + 51 + return min, max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/house/edit_door_list.lua b/data/spells/scripts/house/edit_door_list.lua new file mode 100644 index 00000000000..495dbbdc47e --- /dev/null +++ b/data/spells/scripts/house/edit_door_list.lua @@ -0,0 +1,16 @@ +function onCastSpell(creature, variant) + local creaturePos = creature:getPosition() + creaturePos:getNextPosition(creature:getDirection()) + local tile = Tile(creaturePos) + local house = tile and tile:getHouse() + local doorId = house and house:getDoorIdByPosition(creaturePos) + if not doorId or not house:canEditAccessList(doorId, creature) then + creature:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + + creature:setEditHouse(house, doorId) + creature:sendHouseWindow(house, doorId) + return true +end diff --git a/data/spells/scripts/house/edit_guest_list.lua b/data/spells/scripts/house/edit_guest_list.lua new file mode 100644 index 00000000000..f5f904cda93 --- /dev/null +++ b/data/spells/scripts/house/edit_guest_list.lua @@ -0,0 +1,15 @@ +function onCastSpell(player, variant) + local house = player:getTile():getHouse() + if not house then + return false + end + + if house:canEditAccessList(GUEST_LIST, player) then + player:setEditHouse(house, GUEST_LIST) + player:sendHouseWindow(house, GUEST_LIST) + else + player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + end + return true +end diff --git a/data/spells/scripts/house/edit_subowner_list.lua b/data/spells/scripts/house/edit_subowner_list.lua new file mode 100644 index 00000000000..d955e84efcd --- /dev/null +++ b/data/spells/scripts/house/edit_subowner_list.lua @@ -0,0 +1,15 @@ +function onCastSpell(player, variant) + local house = player:getTile():getHouse() + if not house then + return false + end + + if house:canEditAccessList(SUBOWNER_LIST, player) then + player:setEditHouse(house, SUBOWNER_LIST) + player:sendHouseWindow(house, SUBOWNER_LIST) + else + player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + end + return true +end diff --git a/data/spells/scripts/house/kick.lua b/data/spells/scripts/house/kick.lua new file mode 100644 index 00000000000..38fff2998cb --- /dev/null +++ b/data/spells/scripts/house/kick.lua @@ -0,0 +1,11 @@ +function onCastSpell(player, variant) + local targetPlayer = Player(variant:getString()) or player + local guest = targetPlayer:getTile():getHouse() + local owner = player:getTile():getHouse() + if not owner or not guest or not guest:kickPlayer(player, targetPlayer) then + player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + return true +end diff --git a/data/spells/scripts/monster/abyssador paralyze.lua b/data/spells/scripts/monster/abyssador paralyze.lua new file mode 100644 index 00000000000..f696ae8370d --- /dev/null +++ b/data/spells/scripts/monster/abyssador paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_EXPLOSION) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.70, 0, -0.85, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/abyssador poison wave.lua b/data/spells/scripts/monster/abyssador poison wave.lua new file mode 100644 index 00000000000..1ade9c93aab --- /dev/null +++ b/data/spells/scripts/monster/abyssador poison wave.lua @@ -0,0 +1,19 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_POISONDAMAGE) + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_PLANTATTACK) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + + local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/abyssador skill reducer 1.lua b/data/spells/scripts/monster/abyssador skill reducer 1.lua new file mode 100644 index 00000000000..01a2d040cef --- /dev/null +++ b/data/spells/scripts/monster/abyssador skill reducer 1.lua @@ -0,0 +1,18 @@ +local combat = {} + +for i = 20, 55 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 15000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE1X1) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(20, 55)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/abyssador skill reducer 2.lua b/data/spells/scripts/monster/abyssador skill reducer 2.lua new file mode 100644 index 00000000000..42dac97e17f --- /dev/null +++ b/data/spells/scripts/monster/abyssador skill reducer 2.lua @@ -0,0 +1,19 @@ +local combat = {} + +for i = 50, 90 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 15000) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE1X1) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(50, 90)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/aftershock wave.lua b/data/spells/scripts/monster/aftershock wave.lua new file mode 100644 index 00000000000..9321913a41a --- /dev/null +++ b/data/spells/scripts/monster/aftershock wave.lua @@ -0,0 +1,10 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_TELEPORT) + +local area = createCombatArea(AREA_WAVE11) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/aggresiveLavaWave.lua b/data/spells/scripts/monster/aggresiveLavaWave.lua new file mode 100644 index 00000000000..f5d4e6be3a1 --- /dev/null +++ b/data/spells/scripts/monster/aggresiveLavaWave.lua @@ -0,0 +1,36 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYFIRE) + +combat:setArea(createCombatArea({ +{0, 1, 1, 1, 0}, +{1, 1, 1, 1, 1}, +{1, 1, 3, 1, 1}, +{1, 1, 1, 1, 1}, +{0, 1, 1, 1, 0}, +})) + +function spellCallback(param) + local tile = Tile(Position(param.pos)) + if tile then + if tile:getTopCreature() and tile:getTopCreature():isMonster() then + if tile:getTopCreature():getName():lower() == "the duke of the depths" or tile:getTopCreature():getName():lower() == "the duke of the depths immortal" then + tile:getTopCreature():addHealth(math.random(0, 2000)) + end + end + end +end + +function onTargetTile(cid, pos) + local param = {} + param.cid = cid + param.pos = pos + param.count = 0 + spellCallback(param) +end + +setCombatCallback(combat, CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ancient scarab paralyze.lua b/data/spells/scripts/monster/ancient scarab paralyze.lua new file mode 100644 index 00000000000..f5723af77d3 --- /dev/null +++ b/data/spells/scripts/monster/ancient scarab paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POISONAREA) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) + + local condition = Condition(CONDITION_PARALYZE) + combat:setParameter(CONDITION_PARAM_TICKS, 25000) + combat:setFormula(-0.45, 0, -0.75, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/annihilon paralyze.lua b/data/spells/scripts/monster/annihilon paralyze.lua new file mode 100644 index 00000000000..7b16aecea72 --- /dev/null +++ b/data/spells/scripts/monster/annihilon paralyze.lua @@ -0,0 +1,16 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEATTACK) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SNOWBALL) + + local condition = Condition(CONDITION_PARALYZE) + combat:setParameter(CONDITION_PARAM_TICKS, 20000) + combat:setFormula(-0.55, 0, -0.75, 0) + combat:addCondition(condition) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/annihilon skill reducer.lua b/data/spells/scripts/monster/annihilon skill reducer.lua new file mode 100644 index 00000000000..44d43fbfc68 --- /dev/null +++ b/data/spells/scripts/monster/annihilon skill reducer.lua @@ -0,0 +1,19 @@ +local combat = {} + +for i = 40, 55 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POFF) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 10000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(40, 55)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/anomaly break.lua b/data/spells/scripts/monster/anomaly break.lua new file mode 100644 index 00000000000..4c8202bf837 --- /dev/null +++ b/data/spells/scripts/monster/anomaly break.lua @@ -0,0 +1,27 @@ +local function anomalyBreak(pos) + local upConer = {x = pos.x - 1, y = pos.y - 1, z = pos.z} -- upLeftCorner + local downConer = {x = pos.x + 1, y = pos.y + 1, z = pos.z} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k= upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + if tile:getItemById(1499) then + tile:getItemById(1499):remove() + Position(room):sendMagicEffect(3) + elseif tile:getItemById(1497) then + tile:getItemById(1497):remove() + Position(room):sendMagicEffect(3) + end + end + end + end + end +end + +function onCastSpell(creature, var) + local pos = creature:getPosition() + anomalyBreak(pos) +end diff --git a/data/spells/scripts/monster/anomaly wave.lua b/data/spells/scripts/monster/anomaly wave.lua new file mode 100644 index 00000000000..d9fa8eae45b --- /dev/null +++ b/data/spells/scripts/monster/anomaly wave.lua @@ -0,0 +1,10 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA) + +local area = createCombatArea(AREA_WAVE12) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/apprentice sheng summon.lua b/data/spells/scripts/monster/apprentice sheng summon.lua new file mode 100644 index 00000000000..2011fc0dd7c --- /dev/null +++ b/data/spells/scripts/monster/apprentice sheng summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Hyaena", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/arachir the ancient one summon.lua b/data/spells/scripts/monster/arachir the ancient one summon.lua new file mode 100644 index 00000000000..1e6faaba5e5 --- /dev/null +++ b/data/spells/scripts/monster/arachir the ancient one summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Lich", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/arachnophobica wavedice.lua b/data/spells/scripts/monster/arachnophobica wavedice.lua new file mode 100644 index 00000000000..e44c4ab491b --- /dev/null +++ b/data/spells/scripts/monster/arachnophobica wavedice.lua @@ -0,0 +1,20 @@ +local combat = createCombatObject() +setCombatParam(combat, COMBAT_PARAM_TYPE, CONDITION_DROWN) +setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_CRAPS) + + arr = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + setCombatArea(combat, area) + + +function onCastSpell(cid, var) + return doCombat(cid, combat, var) +end diff --git a/data/spells/scripts/monster/arachnophobica waveenergy.lua b/data/spells/scripts/monster/arachnophobica waveenergy.lua new file mode 100644 index 00000000000..f5a7e36e655 --- /dev/null +++ b/data/spells/scripts/monster/arachnophobica waveenergy.lua @@ -0,0 +1,20 @@ +local combat = createCombatObject() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA) + + arr = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + setCombatArea(combat, area) + + +function onCastSpell(cid, var) + return doCombat(cid, combat, var) +end diff --git a/data/spells/scripts/monster/arkhothep curse.lua b/data/spells/scripts/monster/arkhothep curse.lua new file mode 100644 index 00000000000..3a9a146b4a9 --- /dev/null +++ b/data/spells/scripts/monster/arkhothep curse.lua @@ -0,0 +1,41 @@ +local combat = {} + +for i = 2, 5 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + + local condition = Condition(CONDITION_CURSED) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + + local damage = i + condition:addDamage(1, 4000, -damage) + for j = 1, 33 do + damage = damage * 1.2 + condition:addDamage(1, 4000, -damage) + end + + arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(2, 5)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/arkhothep paralyze.lua b/data/spells/scripts/monster/arkhothep paralyze.lua new file mode 100644 index 00000000000..d2242b5421d --- /dev/null +++ b/data/spells/scripts/monster/arkhothep paralyze.lua @@ -0,0 +1,31 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POFF) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.75, 0, -0.95, 0) + combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/arkhothep summon.lua b/data/spells/scripts/monster/arkhothep summon.lua new file mode 100644 index 00000000000..d7e131343f3 --- /dev/null +++ b/data/spells/scripts/monster/arkhothep summon.lua @@ -0,0 +1,38 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) + +arr = { +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 1, 3, 1, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +} + +local area = createCombatArea(arr) +combat:setArea(area) + +local maxsummons = 6 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 6 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Ancient Scarab", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/arthei summon.lua b/data/spells/scripts/monster/arthei summon.lua new file mode 100644 index 00000000000..06a5effe6f3 --- /dev/null +++ b/data/spells/scripts/monster/arthei summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 4 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 4 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Vampire", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ashfalor summon.lua b/data/spells/scripts/monster/ashfalor summon.lua new file mode 100644 index 00000000000..1109bb0303d --- /dev/null +++ b/data/spells/scripts/monster/ashfalor summon.lua @@ -0,0 +1,62 @@ +local summons = { + [1] = {name = "Demon Skeleton"}, + [2] = {name = "Bonebeast"}, + [3] = {name = "Banshee"}, + [4] = {name = "Blightwalker"}, + [5] = {name = "Crypt Shambler"}, + [6] = {name = "Ghoul"}, + [7] = {name = "Lich"}, + [8] = {name = "Mummy"}, + [9] = {name = "Zombie"}, + [10] = {name = "Ghost"}, + [11] = {name = "Enraged Soul"}, + [12] = {name = "Vampire"}, + [13] = {name = "Vampire Bride"}, + [14] = {name = "Vampire Viscount"}, + [15] = {name = "Pirate Ghost"}, + [16] = {name = "Souleater"}, + [17] = {name = "Tarnished Spirit"}, + [18] = {name = "White Shade"}, + [19] = {name = "Vicious Manbat"} +} + +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + + arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat:setArea(area) + +local maxsummons = 25 + +function onCastSpell(creature, var) +creature:say("RISE MY SERVANTS! RISE!!", TALKTYPE_ORANGE_2) + + local summoncount = creature:getSummons() + local creaturePos = creature:getPosition() + if #summoncount < 25 then + for i = 1, maxsummons do + local mid = Game.createMonster(summons[math.random(#summons)].name, Position(creaturePos.x + math.random(-3, 3), creaturePos.y + math.random(-3, 3), creaturePos.z)) + if not mid then + return + end + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/askarak wave.lua b/data/spells/scripts/monster/askarak wave.lua new file mode 100644 index 00000000000..99204f4a2d9 --- /dev/null +++ b/data/spells/scripts/monster/askarak wave.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_POISONDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GREEN_RINGS) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/azerus electrify.lua b/data/spells/scripts/monster/azerus electrify.lua new file mode 100644 index 00000000000..cf04341ef90 --- /dev/null +++ b/data/spells/scripts/monster/azerus electrify.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_YELLOWENERGY) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGYBALL) + +local condition = Condition(CONDITION_ENERGY) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(10, 10000, -25) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/azerus skill reducer 1.lua b/data/spells/scripts/monster/azerus skill reducer 1.lua new file mode 100644 index 00000000000..50e214e480e --- /dev/null +++ b/data/spells/scripts/monster/azerus skill reducer 1.lua @@ -0,0 +1,16 @@ +local combat = {} + +for i = 40, 50 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_DEATH) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 15000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(40, 50)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/azerus skill reducer 2.lua b/data/spells/scripts/monster/azerus skill reducer 2.lua new file mode 100644 index 00000000000..a0db0ce62b6 --- /dev/null +++ b/data/spells/scripts/monster/azerus skill reducer 2.lua @@ -0,0 +1,17 @@ +local combat = {} + +for i = 40, 55 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_DEATH) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 15000) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(40, 55)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/azerus skill reducer 3.lua b/data/spells/scripts/monster/azerus skill reducer 3.lua new file mode 100644 index 00000000000..770c9d45974 --- /dev/null +++ b/data/spells/scripts/monster/azerus skill reducer 3.lua @@ -0,0 +1,16 @@ +local combat = {} + +for i = 45, 55 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_DEATH) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 15000) + condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(45, 55)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/azerus soulfire 1.lua b/data/spells/scripts/monster/azerus soulfire 1.lua new file mode 100644 index 00000000000..fa2712bc8c2 --- /dev/null +++ b/data/spells/scripts/monster/azerus soulfire 1.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYFIRE) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(20, 9000, -10) + +local area = createCombatArea(AREA_CIRCLE3X3) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/azerus soulfire 2.lua b/data/spells/scripts/monster/azerus soulfire 2.lua new file mode 100644 index 00000000000..a5854e6c340 --- /dev/null +++ b/data/spells/scripts/monster/azerus soulfire 2.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYFIRE) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(20, 9000, -10) + +local area = createCombatArea(AREA_CIRCLE3X3) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/azerus summon 1.lua b/data/spells/scripts/monster/azerus summon 1.lua new file mode 100644 index 00000000000..7112388e93d --- /dev/null +++ b/data/spells/scripts/monster/azerus summon 1.lua @@ -0,0 +1,38 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GROUNDSHAKER) + +arr = { +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 1, 3, 1, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +} + +local area = createCombatArea(arr) +combat:setArea(area) + +local maxsummons = 6 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 6 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Rift Worm", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/azerus summon 2.lua b/data/spells/scripts/monster/azerus summon 2.lua new file mode 100644 index 00000000000..efef3eb1369 --- /dev/null +++ b/data/spells/scripts/monster/azerus summon 2.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BIGCLOUDS) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) + +local maxsummons = 4 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 4 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Rift Brood", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/azerus summon 3.lua b/data/spells/scripts/monster/azerus summon 3.lua new file mode 100644 index 00000000000..ba875d46346 --- /dev/null +++ b/data/spells/scripts/monster/azerus summon 3.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) + +local maxsummons = 4 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 4 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Rift Scythe", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/azerus summon 4.lua b/data/spells/scripts/monster/azerus summon 4.lua new file mode 100644 index 00000000000..23654ee5377 --- /dev/null +++ b/data/spells/scripts/monster/azerus summon 4.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 4 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 4 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("War Golem", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/bane of light paralyze.lua b/data/spells/scripts/monster/bane of light paralyze.lua new file mode 100644 index 00000000000..2df69d164c0 --- /dev/null +++ b/data/spells/scripts/monster/bane of light paralyze.lua @@ -0,0 +1,30 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.45, 0, -0.8, 0) + combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/banshee paralyze.lua b/data/spells/scripts/monster/banshee paralyze.lua new file mode 100644 index 00000000000..25fc3e1ed75 --- /dev/null +++ b/data/spells/scripts/monster/banshee paralyze.lua @@ -0,0 +1,11 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.65, 0, -0.9, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/barbarian brutetamer skill reducer.lua b/data/spells/scripts/monster/barbarian brutetamer skill reducer.lua new file mode 100644 index 00000000000..844902a4cb5 --- /dev/null +++ b/data/spells/scripts/monster/barbarian brutetamer skill reducer.lua @@ -0,0 +1,20 @@ +local combat = {} + +for i = 90, 99 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SNOWBALL) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 8000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(90, 99)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/betrayed wraith paralyze.lua b/data/spells/scripts/monster/betrayed wraith paralyze.lua new file mode 100644 index 00000000000..152ad9076ae --- /dev/null +++ b/data/spells/scripts/monster/betrayed wraith paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 3000) + condition:setFormula(-0.85, 0, -0.95, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/betrayed wraith skill reducer.lua b/data/spells/scripts/monster/betrayed wraith skill reducer.lua new file mode 100644 index 00000000000..5fefe60b1cd --- /dev/null +++ b/data/spells/scripts/monster/betrayed wraith skill reducer.lua @@ -0,0 +1,29 @@ +local combat = {} + +for i = 1, 20 do +combat[i] = Combat() +combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_YELLOW_RINGS) + +local condition = Condition(CONDITION_ATTRIBUTES) +condition:setParameter(CONDITION_PARAM_TICKS, 8000) +condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + +local area = createCombatArea({ + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0} +}) + +combat[i]:setArea(area) +combat[i]:addCondition(condition) + +end + +function onCastSpell(creature, var) + return combat[math.random(1, 20)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/bibby bloodbath paralyze.lua b/data/spells/scripts/monster/bibby bloodbath paralyze.lua new file mode 100644 index 00000000000..04abf1480b9 --- /dev/null +++ b/data/spells/scripts/monster/bibby bloodbath paralyze.lua @@ -0,0 +1,15 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BLOCKHIT) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.35, 0, -0.55, 0) + combat:addCondition(condition) + + local area = createCombatArea(AREA_SQUARE1X1) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/big boss trolliver summon.lua b/data/spells/scripts/monster/big boss trolliver summon.lua new file mode 100644 index 00000000000..6013ec83cfb --- /dev/null +++ b/data/spells/scripts/monster/big boss trolliver summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_NONE) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 5 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 5 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Troll Champion", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/big death wave.lua b/data/spells/scripts/monster/big death wave.lua new file mode 100644 index 00000000000..520855c5433 --- /dev/null +++ b/data/spells/scripts/monster/big death wave.lua @@ -0,0 +1,10 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + +local area = createCombatArea(AREA_WAVE11) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/big energy purple wave.lua b/data/spells/scripts/monster/big energy purple wave.lua new file mode 100644 index 00000000000..e53cb0ebf12 --- /dev/null +++ b/data/spells/scripts/monster/big energy purple wave.lua @@ -0,0 +1,10 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_PURPLEENERGY) + +local area = createCombatArea(AREA_WAVE11) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/big energy purple wave2.lua b/data/spells/scripts/monster/big energy purple wave2.lua new file mode 100644 index 00000000000..5b0869eb3b6 --- /dev/null +++ b/data/spells/scripts/monster/big energy purple wave2.lua @@ -0,0 +1,10 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_PURPLEENERGY) + +local area = createCombatArea(AREA_WAVE11) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/big energy wave.lua b/data/spells/scripts/monster/big energy wave.lua new file mode 100644 index 00000000000..8496b3ca958 --- /dev/null +++ b/data/spells/scripts/monster/big energy wave.lua @@ -0,0 +1,10 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA) + +local area = createCombatArea(AREA_WAVE11) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/big explosion wave.lua b/data/spells/scripts/monster/big explosion wave.lua new file mode 100644 index 00000000000..b8fe969f75a --- /dev/null +++ b/data/spells/scripts/monster/big explosion wave.lua @@ -0,0 +1,10 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONAREA) + +local area = createCombatArea(AREA_WAVE11) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/big lifedrain wave.lua b/data/spells/scripts/monster/big lifedrain wave.lua new file mode 100644 index 00000000000..f3b9d92c39c --- /dev/null +++ b/data/spells/scripts/monster/big lifedrain wave.lua @@ -0,0 +1,10 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_LIFEDRAIN) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + +local area = createCombatArea(AREA_WAVE11) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/big skill reducer.lua b/data/spells/scripts/monster/big skill reducer.lua new file mode 100644 index 00000000000..601cda87bd9 --- /dev/null +++ b/data/spells/scripts/monster/big skill reducer.lua @@ -0,0 +1,34 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) + +local condition = Condition(CONDITION_ATTRIBUTES) +condition:setParameter(CONDITION_PARAM_TICKS, 6000) +condition:setParameter(CONDITION_PARAM_SKILL_DISTANCE, -15) +condition:setParameter(CONDITION_PARAM_SKILL_SHIELD, -15) +condition:setParameter(CONDITION_PARAM_SKILL_MELEE, -15) +condition:setParameter(CONDITION_PARAM_STAT_MAGICPOINTS, -15) + +arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + +local area = createCombatArea(arr) + +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/blightwalker curse.lua b/data/spells/scripts/monster/blightwalker curse.lua new file mode 100644 index 00000000000..7601c351ae4 --- /dev/null +++ b/data/spells/scripts/monster/blightwalker curse.lua @@ -0,0 +1,41 @@ +local combat = {} + +for i = 1, 1 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + + local condition = Condition(CONDITION_CURSED) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + + local damage = i + condition:addDamage(1, 4000, -damage) + for j = 1, 26 do + damage = damage * 1.2 + condition:addDamage(1, 4000, -damage) + end + + arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(1, 1)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/blightwalker paralyze.lua b/data/spells/scripts/monster/blightwalker paralyze.lua new file mode 100644 index 00000000000..3308fff4dc1 --- /dev/null +++ b/data/spells/scripts/monster/blightwalker paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GREEN_RINGS) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 25000) + condition:setFormula(-0.7, 0, -0.9, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/blood hand paralyze.lua b/data/spells/scripts/monster/blood hand paralyze.lua new file mode 100644 index 00000000000..a7999655a03 --- /dev/null +++ b/data/spells/scripts/monster/blood hand paralyze.lua @@ -0,0 +1,15 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BLOCKHIT) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 3000) + condition:setFormula(-0.45, 0, -0.65, 0) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/bog raider paralyze.lua b/data/spells/scripts/monster/bog raider paralyze.lua new file mode 100644 index 00000000000..37e77302155 --- /dev/null +++ b/data/spells/scripts/monster/bog raider paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLPLANTS) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.40, 0, -0.50, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/bonebeast paralyze.lua b/data/spells/scripts/monster/bonebeast paralyze.lua new file mode 100644 index 00000000000..5c27a9a84e6 --- /dev/null +++ b/data/spells/scripts/monster/bonebeast paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POISONAREA) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 25000) + condition:setFormula(-0.3, 0, -0.5, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/boogey summon.lua b/data/spells/scripts/monster/boogey summon.lua new file mode 100644 index 00000000000..ddbbcfbd1a8 --- /dev/null +++ b/data/spells/scripts/monster/boogey summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Demon Skeleton", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/braindeath paralyze.lua b/data/spells/scripts/monster/braindeath paralyze.lua new file mode 100644 index 00000000000..1d11261579c --- /dev/null +++ b/data/spells/scripts/monster/braindeath paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_DEATH) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.65, 0, -0.85, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/breach brood reducer.lua b/data/spells/scripts/monster/breach brood reducer.lua new file mode 100644 index 00000000000..68a4bcbf954 --- /dev/null +++ b/data/spells/scripts/monster/breach brood reducer.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_BURSTARROW) + +local condition = Condition(CONDITION_ATTRIBUTES) +condition:setParameter(CONDITION_PARAM_TICKS, 10000) +condition:setParameter(CONDITION_PARAM_STAT_MAGICPOINTS, -15) + +local area = createCombatArea(AREA_SQUARE1X1) + +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/brimstone bug paralyze.lua b/data/spells/scripts/monster/brimstone bug paralyze.lua new file mode 100644 index 00000000000..b7013b33994 --- /dev/null +++ b/data/spells/scripts/monster/brimstone bug paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_DEATH) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 25000) + condition:setFormula(-0.65, 0, -0.80, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/brimstone bug wave.lua b/data/spells/scripts/monster/brimstone bug wave.lua new file mode 100644 index 00000000000..0444cc69b31 --- /dev/null +++ b/data/spells/scripts/monster/brimstone bug wave.lua @@ -0,0 +1,19 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_POISONDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_YELLOW_RINGS) + + arr = { + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/bullwark paralyze.lua b/data/spells/scripts/monster/bullwark paralyze.lua new file mode 100644 index 00000000000..ae91638dffd --- /dev/null +++ b/data/spells/scripts/monster/bullwark paralyze.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BLOCKHIT) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 5000) +condition:setFormula(-0.55, 0, -0.7, 0) +combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/bullwark summon.lua b/data/spells/scripts/monster/bullwark summon.lua new file mode 100644 index 00000000000..cfbf46326b6 --- /dev/null +++ b/data/spells/scripts/monster/bullwark summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 4 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 4 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Moohtant", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/burning gladiator firering.lua b/data/spells/scripts/monster/burning gladiator firering.lua new file mode 100644 index 00000000000..c962773cb89 --- /dev/null +++ b/data/spells/scripts/monster/burning gladiator firering.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREATTACK) +arr = { +{0, 1, 1, 1, 0}, +{1, 0, 0, 0, 1}, +{1, 0, 2, 0, 1}, +{1, 0, 0, 0, 1}, +{0, 1, 1, 1, 0} +} + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/burning gladiator firex.lua b/data/spells/scripts/monster/burning gladiator firex.lua new file mode 100644 index 00000000000..0fbf7545dd1 --- /dev/null +++ b/data/spells/scripts/monster/burning gladiator firex.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREATTACK) +arr = { +{1, 0, 1}, +{0, 2, 0}, +{1, 0, 1} +} + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/canopic jar heal.lua b/data/spells/scripts/monster/canopic jar heal.lua new file mode 100644 index 00000000000..5c645887e7a --- /dev/null +++ b/data/spells/scripts/monster/canopic jar heal.lua @@ -0,0 +1,51 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_DRAWBLOOD) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) + +arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onTargetCreature(creature, target) + local hp = (creature:getHealth()/creature:getMaxHealth())*100 + local min = 4000 + local max = 5000 + + local master = target:getMaster() + if target:isPlayer() and not master + or master and master:isPlayer() then + return true + end + if hp > 75 then + doTargetCombatHealth(0, target, COMBAT_HEALING, min, max, CONST_ME_NONE) + elseif hp < 75 and hp > 50 then + doTargetCombatHealth(0, target, COMBAT_HEALING, min*0.5, max*0.5, CONST_ME_NONE) + elseif hp < 50 and hp > 25 then + doTargetCombatHealth(0, target, COMBAT_HEALING, min*0.25, max*0.25, CONST_ME_NONE) + elseif hp < 25 then + doTargetCombatHealth(0, target, COMBAT_HEALING, min*0.10, max*0.10, CONST_ME_NONE) + end + + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/carniphila paralyze.lua b/data/spells/scripts/monster/carniphila paralyze.lua new file mode 100644 index 00000000000..d2243ed3105 --- /dev/null +++ b/data/spells/scripts/monster/carniphila paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYPOISON) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.45, 0, -0.75, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/chakoya freeze.lua b/data/spells/scripts/monster/chakoya freeze.lua new file mode 100644 index 00000000000..e3cc2641e04 --- /dev/null +++ b/data/spells/scripts/monster/chakoya freeze.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEATTACK) + +local condition = Condition(CONDITION_FREEZING) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(2, 8000, -8) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/charge vortex.lua b/data/spells/scripts/monster/charge vortex.lua new file mode 100644 index 00000000000..83690256f23 --- /dev/null +++ b/data/spells/scripts/monster/charge vortex.lua @@ -0,0 +1,47 @@ +local mathCount = 0 + +local positions = {} + +local function createVortex() + local storedPositions = { + {x = 32264, y = 31253, z = 14}, + {x = 32269, y = 31258, z = 14}, + {x = 32275, y = 31255, z = 14}, + {x = 32280, y = 31253, z = 14}, + {x = 32271, y = 31248, z = 14}, + {x = 32264, y = 31245, z = 14}, + {x = 32270, y = 31240, z = 14}, + {x = 32269, y = 31253, z = 14}, + {x = 32275, y = 31245, z = 14}, + {x = 32276, y = 31250, z = 14}, + {x = 32266, y = 31249, z = 14}, + } + + if mathCount == 0 then + positions = storedPositions + end + + local r1 = math.random(#positions) + + local tile = Tile(positions[r1]) + + if tile then + local ground = tile:getGround() + if ground then + ground:transform(25550) + addEvent(function() + ground:transform(25705) + end, 10*1000) -- 10*1000 = 10 SECONDS + mathCount = mathCount + 1 + table.remove(positions, r1) + end + end + + if mathCount == 11 then + mathCount = 0 + end +end + +function onCastSpell(creature, var) + createVortex() +end diff --git a/data/spells/scripts/monster/charged energy elemental electrify.lua b/data/spells/scripts/monster/charged energy elemental electrify.lua new file mode 100644 index 00000000000..bcf32b42684 --- /dev/null +++ b/data/spells/scripts/monster/charged energy elemental electrify.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BLOCKHIT) + +local condition = Condition(CONDITION_ENERGY) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(4, 10000, -25) + +local area = createCombatArea(AREA_CIRCLE3X3) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/chizzoron the distorter paralyze.lua b/data/spells/scripts/monster/chizzoron the distorter paralyze.lua new file mode 100644 index 00000000000..912f20d8c66 --- /dev/null +++ b/data/spells/scripts/monster/chizzoron the distorter paralyze.lua @@ -0,0 +1,15 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POISONAREA) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.60, 0, -0.85, 0) + combat:addCondition(condition) + + local area = createCombatArea(AREA_CIRCLE3X3) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/chizzoron the distorter summon.lua b/data/spells/scripts/monster/chizzoron the distorter summon.lua new file mode 100644 index 00000000000..b6b6e956d4f --- /dev/null +++ b/data/spells/scripts/monster/chizzoron the distorter summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Lizard Dragon Priest2", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/choking fear drown.lua b/data/spells/scripts/monster/choking fear drown.lua new file mode 100644 index 00000000000..b7075b5f5c0 --- /dev/null +++ b/data/spells/scripts/monster/choking fear drown.lua @@ -0,0 +1,31 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_DROWNDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BUBBLES) + +arr = { +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +} + +local condition = Condition(CONDITION_DROWN) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(50, 5000, -20) + +local area = createCombatArea(arr) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/choking fear paralyze.lua b/data/spells/scripts/monster/choking fear paralyze.lua new file mode 100644 index 00000000000..edfd62b3d4b --- /dev/null +++ b/data/spells/scripts/monster/choking fear paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SLEEP) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_DEATH) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.6, 0, -0.8, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/cliff strider electrify.lua b/data/spells/scripts/monster/cliff strider electrify.lua new file mode 100644 index 00000000000..6ddb3a7aed3 --- /dev/null +++ b/data/spells/scripts/monster/cliff strider electrify.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_PURPLEENERGY) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGYBALL) + +local condition = Condition(CONDITION_ENERGY) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(20, 10000, -25) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/cliff strider skill reducer.lua b/data/spells/scripts/monster/cliff strider skill reducer.lua new file mode 100644 index 00000000000..49bb73e5e18 --- /dev/null +++ b/data/spells/scripts/monster/cliff strider skill reducer.lua @@ -0,0 +1,19 @@ +local combat = {} + +for i = 15, 45 do +combat[i] = Combat() +combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + +local condition = Condition(CONDITION_ATTRIBUTES) +condition:setParameter(CONDITION_PARAM_TICKS, 4000) +condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat[i]:setArea(area) +combat[i]:addCondition(condition) + +end + +function onCastSpell(creature, var) + return combat[math.random(15, 45)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/coldheart paralyze.lua b/data/spells/scripts/monster/coldheart paralyze.lua new file mode 100644 index 00000000000..6b6cf75a793 --- /dev/null +++ b/data/spells/scripts/monster/coldheart paralyze.lua @@ -0,0 +1,15 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.5, 0, -0.75, 0) + combat:addCondition(condition) + + local area = createCombatArea(AREA_SQUARE1X1) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/corym vanguard wave.lua b/data/spells/scripts/monster/corym vanguard wave.lua new file mode 100644 index 00000000000..317919d1fff --- /dev/null +++ b/data/spells/scripts/monster/corym vanguard wave.lua @@ -0,0 +1,19 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_POISONDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GREEN_RINGS) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/crystal spider paralyze 1.lua b/data/spells/scripts/monster/crystal spider paralyze 1.lua new file mode 100644 index 00000000000..6a75c6100f4 --- /dev/null +++ b/data/spells/scripts/monster/crystal spider paralyze 1.lua @@ -0,0 +1,32 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POFF) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.25, 0, -0.4, 0) +combat:addCondition(condition) + +arr = { +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +} + +local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/crystal spider paralyze 2.lua b/data/spells/scripts/monster/crystal spider paralyze 2.lua new file mode 100644 index 00000000000..9abcb5532d8 --- /dev/null +++ b/data/spells/scripts/monster/crystal spider paralyze 2.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SNOWBALL) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.5, 0, -0.6, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/crystal wolf wave.lua b/data/spells/scripts/monster/crystal wolf wave.lua new file mode 100644 index 00000000000..482a5d80c49 --- /dev/null +++ b/data/spells/scripts/monster/crystal wolf wave.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_STONES) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/cults of tibia armor buff.lua b/data/spells/scripts/monster/cults of tibia armor buff.lua new file mode 100644 index 00000000000..28ee37e12e2 --- /dev/null +++ b/data/spells/scripts/monster/cults of tibia armor buff.lua @@ -0,0 +1,32 @@ +local combat = {} + +for i = 130, 150 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 6000) + condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + +arr = { +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0} +} + + local area = createCombatArea(arr) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(130, 150)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/dark torturer skill reducer.lua b/data/spells/scripts/monster/dark torturer skill reducer.lua new file mode 100644 index 00000000000..850dafd061e --- /dev/null +++ b/data/spells/scripts/monster/dark torturer skill reducer.lua @@ -0,0 +1,36 @@ +local combat = {} + +for i = 1, 40 do +combat[i] = Combat() +combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_PURPLE) + +local condition = Condition(CONDITION_ATTRIBUTES) +condition:setParameter(CONDITION_PARAM_TICKS, 4000) +condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + +local area = createCombatArea({ + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0} +}) + +combat[i]:setArea(area) +combat[i]:addCondition(condition) + +end + +function onCastSpell(creature, var) + return combat[math.random(1, 40)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/death blob curse.lua b/data/spells/scripts/monster/death blob curse.lua new file mode 100644 index 00000000000..5e462ada6d8 --- /dev/null +++ b/data/spells/scripts/monster/death blob curse.lua @@ -0,0 +1,24 @@ +local combat = {} + +for i = 2, 2 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_CURSED) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + + local damage = i + condition:addDamage(1, 4000, -damage) + for j = 1, 18 do + damage = damage * 1.2 + condition:addDamage(1, 4000, -damage) + end + + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(2, 2)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/death priest shargon curse.lua b/data/spells/scripts/monster/death priest shargon curse.lua new file mode 100644 index 00000000000..18b087312a0 --- /dev/null +++ b/data/spells/scripts/monster/death priest shargon curse.lua @@ -0,0 +1,23 @@ +local combat = {} + +for i = 1.12, 1.12 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_CURSED) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + + local damage = i + condition:addDamage(1, 4000, -damage) + for j = 1, 32 do + damage = damage * 1.2 + condition:addDamage(1, 4000, -damage) + end + + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(1.12, 1.12)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/death priest shargon dazzle.lua b/data/spells/scripts/monster/death priest shargon dazzle.lua new file mode 100644 index 00000000000..5fc553bb1ed --- /dev/null +++ b/data/spells/scripts/monster/death priest shargon dazzle.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + +local condition = Condition(CONDITION_DAZZLED) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(20, 10000, -20) +combat:addCondition(condition) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/death priest shargon summon.lua b/data/spells/scripts/monster/death priest shargon summon.lua new file mode 100644 index 00000000000..5a4e63ca3a4 --- /dev/null +++ b/data/spells/scripts/monster/death priest shargon summon.lua @@ -0,0 +1,13 @@ +local maxsummons = 2 + +function onCastSpell(creature, var) +local summoncount = creature:getSummons() + if #summoncount < 2 then + local mon = Game.createMonster("Lesser Death Minion", creature:getPosition(), true, true) + if not mon then + return + end + mon:setMaster(creature) + end + return true +end diff --git a/data/spells/scripts/monster/deathbringer drown.lua b/data/spells/scripts/monster/deathbringer drown.lua new file mode 100644 index 00000000000..6405437a9b3 --- /dev/null +++ b/data/spells/scripts/monster/deathbringer drown.lua @@ -0,0 +1,26 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_DROWNDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POFF) + + arr = { + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local condition = Condition(CONDITION_DROWN) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(20, 5000, -20) + +local area = createCombatArea(arr) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/deathstrike freeze.lua b/data/spells/scripts/monster/deathstrike freeze.lua new file mode 100644 index 00000000000..3029e514bc6 --- /dev/null +++ b/data/spells/scripts/monster/deathstrike freeze.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_PURPLEENERGY) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + +local condition = Condition(CONDITION_FREEZING) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(30, 8000, -8) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/deathstrike manadrain.lua b/data/spells/scripts/monster/deathstrike manadrain.lua new file mode 100644 index 00000000000..5530e568671 --- /dev/null +++ b/data/spells/scripts/monster/deathstrike manadrain.lua @@ -0,0 +1,20 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_MANADRAIN) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/deathstrike paralyze.lua b/data/spells/scripts/monster/deathstrike paralyze.lua new file mode 100644 index 00000000000..e32e2d454a9 --- /dev/null +++ b/data/spells/scripts/monster/deathstrike paralyze.lua @@ -0,0 +1,31 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_STUN) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.45, 0, -0.75, 0) + combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/deepling spellsinger skill reducer.lua b/data/spells/scripts/monster/deepling spellsinger skill reducer.lua new file mode 100644 index 00000000000..6bdecb78c37 --- /dev/null +++ b/data/spells/scripts/monster/deepling spellsinger skill reducer.lua @@ -0,0 +1,21 @@ +local combat = {} + +for i = 35, 65 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_STUN) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 8000) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + + local area = createCombatArea(AREA_BEAM1) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(35, 65)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/defiler paralyze 1.lua b/data/spells/scripts/monster/defiler paralyze 1.lua new file mode 100644 index 00000000000..34beec63d88 --- /dev/null +++ b/data/spells/scripts/monster/defiler paralyze 1.lua @@ -0,0 +1,32 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYPOISON) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.85, 0, -0.90, 0) +combat:addCondition(condition) + +arr = { +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +} + +local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/defiler paralyze 2.lua b/data/spells/scripts/monster/defiler paralyze 2.lua new file mode 100644 index 00000000000..e62eb5bbf49 --- /dev/null +++ b/data/spells/scripts/monster/defiler paralyze 2.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POISONAREA) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.85, 0, -0.90, 0) +combat:addCondition(condition) + + +local area = createCombatArea(AREA_SQUARE1X1) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/defiler paralyze 3.lua b/data/spells/scripts/monster/defiler paralyze 3.lua new file mode 100644 index 00000000000..c44fd6db3ab --- /dev/null +++ b/data/spells/scripts/monster/defiler paralyze 3.lua @@ -0,0 +1,28 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.85, 0, -0.90, 0) +combat:addCondition(condition) + + arr = { + {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/demon outcast skill reducer.lua b/data/spells/scripts/monster/demon outcast skill reducer.lua new file mode 100644 index 00000000000..4765f68e6b2 --- /dev/null +++ b/data/spells/scripts/monster/demon outcast skill reducer.lua @@ -0,0 +1,19 @@ +local combat = {} + +for i = 20, 25 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FLASHARROW) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 10000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(20, 25)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/demon paralyze.lua b/data/spells/scripts/monster/demon paralyze.lua new file mode 100644 index 00000000000..2ac024081a2 --- /dev/null +++ b/data/spells/scripts/monster/demon paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 25000) + condition:setFormula(-0.3, 0, -0.45, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/demon summon.lua b/data/spells/scripts/monster/demon summon.lua new file mode 100644 index 00000000000..cdc66650083 --- /dev/null +++ b/data/spells/scripts/monster/demon summon.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREATTACK) + +local maxsummons = 1 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 1 then + mid = Game.createMonster("Fire Elemental", { x=creature:getPosition().x+math.random(-1, 1), y=creature:getPosition().y+math.random(-1, 1), z=creature:getPosition().z }) + if not mid then + return + end + mid:setMaster(creature) + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/destruction summon.lua b/data/spells/scripts/monster/destruction summon.lua new file mode 100644 index 00000000000..e00f775b111 --- /dev/null +++ b/data/spells/scripts/monster/destruction summon.lua @@ -0,0 +1,27 @@ +local destructionSummonDelay = false + +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_NONE) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) + +local function removeDelay() + destructionSummonDelay = false +end + +function onCastSpell(creature, var) + + if destructionSummonDelay == false then + if destructionSummon < 3 then + Game.createMonster("Disruption", {x=creature:getPosition().x+math.random(-1, 1), y=creature:getPosition().y+math.random(-1, 1), z=creature:getPosition().z}, false, true) + destructionSummon = destructionSummon + 1 + + destructionSummonDelay = true + addEvent(removeDelay, 15000) + end + end + + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/devourer paralyze.lua b/data/spells/scripts/monster/devourer paralyze.lua new file mode 100644 index 00000000000..8db155e6bcb --- /dev/null +++ b/data/spells/scripts/monster/devourer paralyze.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POISONAREA) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.55, 0, -0.75, 0) +combat:addCondition(condition) + + +local area = createCombatArea(AREA_SQUARE1X1) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/devourer summon.lua b/data/spells/scripts/monster/devourer summon.lua new file mode 100644 index 00000000000..fd237126451 --- /dev/null +++ b/data/spells/scripts/monster/devourer summon.lua @@ -0,0 +1,19 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_NONE) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) + +function onCastSpell(creature, var) + + local creatures = {"Greed", "Frenzy", "Disruption"} + local monster = creatures[math.random(#creatures)] + + if devourerSummon < 3 then + Game.createMonster(monster, {x=creature:getPosition().x+math.random(-1, 1), y=creature:getPosition().y+math.random(-1, 1), z=creature:getPosition().z}, false, true) + devourerSummon = devourerSummon + 1 + end + + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/devourer wave.lua b/data/spells/scripts/monster/devourer wave.lua new file mode 100644 index 00000000000..07df1fe3e36 --- /dev/null +++ b/data/spells/scripts/monster/devourer wave.lua @@ -0,0 +1,19 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_POISONDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLPLANTS) + + arr = { + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/devovorga curse.lua b/data/spells/scripts/monster/devovorga curse.lua new file mode 100644 index 00000000000..8a3f8c7b8a5 --- /dev/null +++ b/data/spells/scripts/monster/devovorga curse.lua @@ -0,0 +1,41 @@ +local combat = {} + +for i = 1, 3 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + + local condition = Condition(CONDITION_CURSED) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + + local damage = i + condition:addDamage(1, 4000, -damage) + for j = 1, 35 do + damage = damage * 1.2 + condition:addDamage(1, 4000, -damage) + end + + arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(2, 5)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/dharalion skill reducer.lua b/data/spells/scripts/monster/dharalion skill reducer.lua new file mode 100644 index 00000000000..6ec5c8c5bb0 --- /dev/null +++ b/data/spells/scripts/monster/dharalion skill reducer.lua @@ -0,0 +1,16 @@ +local combat = {} + +for i = 10, 35 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POISONAREA) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(10, 35)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/diabolic imp skill reducer.lua b/data/spells/scripts/monster/diabolic imp skill reducer.lua new file mode 100644 index 00000000000..a557f1f6861 --- /dev/null +++ b/data/spells/scripts/monster/diabolic imp skill reducer.lua @@ -0,0 +1,20 @@ +local combat = {} + +for i = 5, 20 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 6000) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + + local area = createCombatArea(AREA_BEAM1) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(5, 20)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/diblis the fair summon.lua b/data/spells/scripts/monster/diblis the fair summon.lua new file mode 100644 index 00000000000..be40599bc75 --- /dev/null +++ b/data/spells/scripts/monster/diblis the fair summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_NONE) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 4 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 4 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Banshee", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/dipthrah skill reducer.lua b/data/spells/scripts/monster/dipthrah skill reducer.lua new file mode 100644 index 00000000000..0851db575f7 --- /dev/null +++ b/data/spells/scripts/monster/dipthrah skill reducer.lua @@ -0,0 +1,20 @@ +local combat = {} + +for i = 45, 65 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HOLYAREA) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 80000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE3X3) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(45, 65)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/dire penguin paralyze.lua b/data/spells/scripts/monster/dire penguin paralyze.lua new file mode 100644 index 00000000000..4f84198e75b --- /dev/null +++ b/data/spells/scripts/monster/dire penguin paralyze.lua @@ -0,0 +1,15 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POFF) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 6000) + condition:setFormula(-0.24, 0, -0.29, 0) + combat:addCondition(condition) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/dirtbeard summon.lua b/data/spells/scripts/monster/dirtbeard summon.lua new file mode 100644 index 00000000000..e21f5a55916 --- /dev/null +++ b/data/spells/scripts/monster/dirtbeard summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_RED) + +local area = createCombatArea(AREA_CIRCLE3X3) +combat:setArea(area) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Pirate Marauder", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/diseased paralyze.lua b/data/spells/scripts/monster/diseased paralyze.lua new file mode 100644 index 00000000000..a7c04ad6063 --- /dev/null +++ b/data/spells/scripts/monster/diseased paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.40, 0, -0.50, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/djinn cancel invisibility.lua b/data/spells/scripts/monster/djinn cancel invisibility.lua new file mode 100644 index 00000000000..c3ef04068e5 --- /dev/null +++ b/data/spells/scripts/monster/djinn cancel invisibility.lua @@ -0,0 +1,9 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_INVISIBLE) + +local area = createCombatArea(AREA_CIRCLE3X3) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/djinn electrify 2.lua b/data/spells/scripts/monster/djinn electrify 2.lua new file mode 100644 index 00000000000..024f76a5f1c --- /dev/null +++ b/data/spells/scripts/monster/djinn electrify 2.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT) + +local condition = Condition(CONDITION_ENERGY) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(3, 10000, -25) +combat:addCondition(condition) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/djinn electrify.lua b/data/spells/scripts/monster/djinn electrify.lua new file mode 100644 index 00000000000..55b5669012b --- /dev/null +++ b/data/spells/scripts/monster/djinn electrify.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + +local condition = Condition(CONDITION_ENERGY) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(3, 10000, -25) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/djinn paralyze.lua b/data/spells/scripts/monster/djinn paralyze.lua new file mode 100644 index 00000000000..ffb990ab17c --- /dev/null +++ b/data/spells/scripts/monster/djinn paralyze.lua @@ -0,0 +1,11 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.4, 0, -0.75, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/doctor perhaps summon.lua b/data/spells/scripts/monster/doctor perhaps summon.lua new file mode 100644 index 00000000000..bc5acfae7d0 --- /dev/null +++ b/data/spells/scripts/monster/doctor perhaps summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POISONAREA) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Zombie", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/dragonling paralyze.lua b/data/spells/scripts/monster/dragonling paralyze.lua new file mode 100644 index 00000000000..b1f91411494 --- /dev/null +++ b/data/spells/scripts/monster/dragonling paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_STUN) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_DEATH) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 25000) + condition:setFormula(-0.6, 0, -0.75, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/dragonling wave.lua b/data/spells/scripts/monster/dragonling wave.lua new file mode 100644 index 00000000000..546e961496b --- /dev/null +++ b/data/spells/scripts/monster/dragonling wave.lua @@ -0,0 +1,20 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYFIRE) + + arr = { + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/draken abomination curse.lua b/data/spells/scripts/monster/draken abomination curse.lua new file mode 100644 index 00000000000..13b70ffb5fa --- /dev/null +++ b/data/spells/scripts/monster/draken abomination curse.lua @@ -0,0 +1,24 @@ +local combat = {} + +for i = 15, 30 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_DEATH) + + local condition = Condition(CONDITION_CURSED) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + + local damage = i + condition:addDamage(1, 4000, -damage) + for j = 1, 8 do + damage = damage * 1.2 + condition:addDamage(1, 4000, -damage) + end + + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(15, 30)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/draken abomination summon.lua b/data/spells/scripts/monster/draken abomination summon.lua new file mode 100644 index 00000000000..adcbfa46be1 --- /dev/null +++ b/data/spells/scripts/monster/draken abomination summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYPOISON) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Death Blob", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/draken elite soulfire.lua b/data/spells/scripts/monster/draken elite soulfire.lua new file mode 100644 index 00000000000..2bac7cd9730 --- /dev/null +++ b/data/spells/scripts/monster/draken elite soulfire.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(20, 9000, -10) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/dread intruder wave.lua b/data/spells/scripts/monster/dread intruder wave.lua new file mode 100644 index 00000000000..ba09d85f6fe --- /dev/null +++ b/data/spells/scripts/monster/dread intruder wave.lua @@ -0,0 +1,10 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_PURPLEENERGY) + +local area = createCombatArea(AREA_SQUAREWAVE6) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/dreadbeast skill reducer.lua b/data/spells/scripts/monster/dreadbeast skill reducer.lua new file mode 100644 index 00000000000..a21653c423c --- /dev/null +++ b/data/spells/scripts/monster/dreadbeast skill reducer.lua @@ -0,0 +1,17 @@ +local combat = {} + +for i = 70, 80 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_YELLOWENERGY) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(70, 80)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/dreadbeast summon.lua b/data/spells/scripts/monster/dreadbeast summon.lua new file mode 100644 index 00000000000..1d2cb52d107 --- /dev/null +++ b/data/spells/scripts/monster/dreadbeast summon.lua @@ -0,0 +1,27 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GROUNDSHAKER) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +function onCastSpell(creature, var) +local t, spectator = Game.getSpectators(creature:getPosition(), false, false, 50, 50, 50, 50) + local check = 0 + if #t ~= nil then + for i = 1, #t do + spectator = t[i] + if spectator:getName() == "Dreadbeast" then + check = check + 1 + end + end + end + if (check < 10) then + local summon = Game.createMonster("Dreadbeast", creature:getPosition(), true, false) + if summon then + end + summon:setMaster(creature) + else + end +return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/dreadwing curse.lua b/data/spells/scripts/monster/dreadwing curse.lua new file mode 100644 index 00000000000..038abc2c5ca --- /dev/null +++ b/data/spells/scripts/monster/dreadwing curse.lua @@ -0,0 +1,34 @@ +local combat = {} + +for i = 1, 1 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_PURPLE) + + local condition = Condition(CONDITION_CURSED) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + + local damage = i + condition:addDamage(1, 4000, -damage) + for j = 1, 15 do + damage = damage * 1.2 + condition:addDamage(1, 4000, -damage) + end + + local area = createCombatArea({ + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + }) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(1, 1)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/dreadwing skill reducer.lua b/data/spells/scripts/monster/dreadwing skill reducer.lua new file mode 100644 index 00000000000..84198218ec5 --- /dev/null +++ b/data/spells/scripts/monster/dreadwing skill reducer.lua @@ -0,0 +1,16 @@ +local combat = {} + +for i = 30, 60 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_RED) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 10000) + condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(30, 60)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/drillworm paralyze.lua b/data/spells/scripts/monster/drillworm paralyze.lua new file mode 100644 index 00000000000..58fb8608c5c --- /dev/null +++ b/data/spells/scripts/monster/drillworm paralyze.lua @@ -0,0 +1,26 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 10000) + condition:setFormula(-0.35, 0, -0.65, 0) + combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/dryad paralyze.lua b/data/spells/scripts/monster/dryad paralyze.lua new file mode 100644 index 00000000000..2a72b2568ca --- /dev/null +++ b/data/spells/scripts/monster/dryad paralyze.lua @@ -0,0 +1,15 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POISONAREA) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.25, 0, -0.4, 0) + combat:addCondition(condition) + + local area = createCombatArea(AREA_CIRCLE3X3) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/dwarf henchman drown.lua b/data/spells/scripts/monster/dwarf henchman drown.lua new file mode 100644 index 00000000000..0bd7dd604e6 --- /dev/null +++ b/data/spells/scripts/monster/dwarf henchman drown.lua @@ -0,0 +1,12 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_DROWNDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POFF) + +local condition = Condition(CONDITION_DROWN) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(4, 5000, -20) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/dworc paralyze.lua b/data/spells/scripts/monster/dworc paralyze.lua new file mode 100644 index 00000000000..9ec719dc7f3 --- /dev/null +++ b/data/spells/scripts/monster/dworc paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.5, 0, -0.75, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/elder bonelord paralyze.lua b/data/spells/scripts/monster/elder bonelord paralyze.lua new file mode 100644 index 00000000000..44f35f747e9 --- /dev/null +++ b/data/spells/scripts/monster/elder bonelord paralyze.lua @@ -0,0 +1,11 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.65, 0, -0.85, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/elder mummy paralyze.lua b/data/spells/scripts/monster/elder mummy paralyze.lua new file mode 100644 index 00000000000..69be4dd31f8 --- /dev/null +++ b/data/spells/scripts/monster/elder mummy paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.7, 0, -0.85, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/elder wyrm electrify.lua b/data/spells/scripts/monster/elder wyrm electrify.lua new file mode 100644 index 00000000000..f29113bb4f5 --- /dev/null +++ b/data/spells/scripts/monster/elder wyrm electrify.lua @@ -0,0 +1,26 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BLOCKHIT) + +local condition = Condition(CONDITION_ENERGY) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(10, 10000, -25) +combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/elder wyrm wave.lua b/data/spells/scripts/monster/elder wyrm wave.lua new file mode 100644 index 00000000000..5515cf22055 --- /dev/null +++ b/data/spells/scripts/monster/elder wyrm wave.lua @@ -0,0 +1,20 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_LIFEDRAIN) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BLACKSMOKE) + + arr = { + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/emberBeastArea.lua b/data/spells/scripts/monster/emberBeastArea.lua new file mode 100644 index 00000000000..2faae81ec96 --- /dev/null +++ b/data/spells/scripts/monster/emberBeastArea.lua @@ -0,0 +1,34 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONHIT) + +combat:setArea(createCombatArea({ +{1, 1, 1}, +{1, 3, 1}, +{1, 1, 1} +})) + +function spellCallback(param) + local tile = Tile(Position(param.pos)) + if tile then + if tile:getTopCreature() and tile:getTopCreature():isMonster() then + if tile:getTopCreature():getName():lower() == "the count of the core" then + tile:getTopCreature():addHealth(math.random(0, 1500)) + end + end + end +end + +function onTargetTile(cid, pos) + local param = {} + param.cid = cid + param.pos = pos + param.count = 0 + spellCallback(param) +end + +setCombatCallback(combat, CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/emberBeastHur.lua b/data/spells/scripts/monster/emberBeastHur.lua new file mode 100644 index 00000000000..b5f4cfc4474 --- /dev/null +++ b/data/spells/scripts/monster/emberBeastHur.lua @@ -0,0 +1,37 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONHIT) + +combat:setArea(createCombatArea({ +{1}, +{1}, +{1}, +{1}, +{1}, +{3}, +})) + +function spellCallback(param) + local tile = Tile(Position(param.pos)) + if tile then + if tile:getTopCreature() and tile:getTopCreature():isMonster() then + if tile:getTopCreature():getName():lower() == "the count of the core" then + tile:getTopCreature():addHealth(math.random(0, 1500)) + end + end + end +end + +function onTargetTile(cid, pos) + local param = {} + param.cid = cid + param.pos = pos + param.count = 0 + spellCallback(param) +end + +setCombatCallback(combat, CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/emperor summon.lua b/data/spells/scripts/monster/emperor summon.lua new file mode 100644 index 00000000000..01b8993592e --- /dev/null +++ b/data/spells/scripts/monster/emperor summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_PURPLE) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Draken Warmaster", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/energized raging mage skill reducer.lua b/data/spells/scripts/monster/energized raging mage skill reducer.lua new file mode 100644 index 00000000000..ec831606b14 --- /dev/null +++ b/data/spells/scripts/monster/energized raging mage skill reducer.lua @@ -0,0 +1,14 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT) + +local area = createCombatArea(AREA_CIRCLE6X6) +combat:setArea(area) + +local condition = Condition(CONDITION_ATTRIBUTES) +condition:setParameter(CONDITION_PARAM_TICKS, 6000) +condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, 50) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/energy elemental electrify.lua b/data/spells/scripts/monster/energy elemental electrify.lua new file mode 100644 index 00000000000..524e7bfb7ba --- /dev/null +++ b/data/spells/scripts/monster/energy elemental electrify.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BLOCKHIT) + +local condition = Condition(CONDITION_ENERGY) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(7, 10000, -25) + +local area = createCombatArea(AREA_CIRCLE3X3) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/energy overlord paralyze.lua b/data/spells/scripts/monster/energy overlord paralyze.lua new file mode 100644 index 00000000000..8fe601a73f4 --- /dev/null +++ b/data/spells/scripts/monster/energy overlord paralyze.lua @@ -0,0 +1,31 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_PLANTATTACK) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.3, 0, -0.65, 0) + combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/energy pulse explosion.lua b/data/spells/scripts/monster/energy pulse explosion.lua new file mode 100644 index 00000000000..d03f243dcf8 --- /dev/null +++ b/data/spells/scripts/monster/energy pulse explosion.lua @@ -0,0 +1,26 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA) + +arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var), creature:remove() +end diff --git a/data/spells/scripts/monster/enslaved dwarf skill reducer 1.lua b/data/spells/scripts/monster/enslaved dwarf skill reducer 1.lua new file mode 100644 index 00000000000..852d7e31b22 --- /dev/null +++ b/data/spells/scripts/monster/enslaved dwarf skill reducer 1.lua @@ -0,0 +1,18 @@ +local combat = {} + +for i = 20, 65 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 6000) + condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(20, 65)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/enslaved dwarf skill reducer 2.lua b/data/spells/scripts/monster/enslaved dwarf skill reducer 2.lua new file mode 100644 index 00000000000..691bb075a0d --- /dev/null +++ b/data/spells/scripts/monster/enslaved dwarf skill reducer 2.lua @@ -0,0 +1,18 @@ +local combat = {} + +for i = 35, 75 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 6000) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE1X1) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(35, 75)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/eruption of destruction explosion.lua b/data/spells/scripts/monster/eruption of destruction explosion.lua new file mode 100644 index 00000000000..97da487d76b --- /dev/null +++ b/data/spells/scripts/monster/eruption of destruction explosion.lua @@ -0,0 +1,84 @@ +local vocation = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID, + VOCATION.CLIENT_ID.PALADIN, + VOCATION.CLIENT_ID.KNIGHT +} + +local area = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + +local createArea = createCombatArea(area) + +local combat = Combat() +combat:setArea(createArea) + +function onTargetTile(creature, pos) + local creatureTable = {} + local n, i = Tile({x=pos.x, y=pos.y, z=pos.z}).creatures, 1 + if n ~= 0 then + local v = getThingfromPos({x=pos.x, y=pos.y, z=pos.z, stackpos=i}).uid + while v ~= 0 do + if isCreature(v) == true then + table.insert(creatureTable, v) + if n == #creatureTable then + break + end + end + i = i + 1 + v = getThingfromPos({x=pos.x, y=pos.y, z=pos.z, stackpos=i}).uid + end + end + if #creatureTable ~= nil and #creatureTable > 0 then + for r = 1, #creatureTable do + if creatureTable[r] ~= creature then + local min = 4000 + local max = 6000 + local player = Player(creatureTable[r]) + + if isPlayer(creatureTable[r]) == true and table.contains(vocation, player:getVocation():getClientId()) then + doTargetCombatHealth(creature, creatureTable[r], COMBAT_FIREDAMAGE, -min, -max, CONST_ME_NONE) + elseif isMonster(creatureTable[r]) == true then + doTargetCombatHealth(creature, creatureTable[r], COMBAT_FIREDAMAGE, -min, -max, CONST_ME_NONE) + end + end + end + end + pos:sendMagicEffect(CONST_ME_FIREAREA) + creature:remove() + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +local function delayedCastSpell(cid, var) + local creature = Creature(cid) + if not creature then + return + end + if creature:getHealth() >= 1 then + local master = creature:getMaster() + master:addHealth(math.random(20000, 30000), true, true) + Game.createMonster('demon', creature:getPosition(), true, true) + return combat:execute(creature, positionToVariant(creature:getPosition())) + end + return +end + +function onCastSpell(creature, var) + addEvent(delayedCastSpell, 7000, creature:getId(), var) + return true +end diff --git a/data/spells/scripts/monster/essence of darkness curse.lua b/data/spells/scripts/monster/essence of darkness curse.lua new file mode 100644 index 00000000000..5b96bb37572 --- /dev/null +++ b/data/spells/scripts/monster/essence of darkness curse.lua @@ -0,0 +1,24 @@ +local combat = {} + +for i = 2, 2 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_CURSED) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + + local damage = i + condition:addDamage(1, 4000, -damage) + for j = 1, 3 do + damage = damage * 1.2 + condition:addDamage(1, 4000, -damage) + end + + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(2, 2)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/essence of darkness paralyze.lua b/data/spells/scripts/monster/essence of darkness paralyze.lua new file mode 100644 index 00000000000..c5ca5b66f88 --- /dev/null +++ b/data/spells/scripts/monster/essence of darkness paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 5000) + condition:setFormula(-0.2, 0, -0.3, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/evil sheep lord summon.lua b/data/spells/scripts/monster/evil sheep lord summon.lua new file mode 100644 index 00000000000..6eb9d9a60c4 --- /dev/null +++ b/data/spells/scripts/monster/evil sheep lord summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HEARTS) + +local area = createCombatArea(AREA_CIRCLE3X3) +combat:setArea(area) + +local maxsummons = 3 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 3 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Evil Sheep", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/explosion wave.lua b/data/spells/scripts/monster/explosion wave.lua new file mode 100644 index 00000000000..72723bd653c --- /dev/null +++ b/data/spells/scripts/monster/explosion wave.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONHIT) +arr = { +{1, 1, 1}, +{1, 1, 1}, +{0, 1, 0}, +{0, 3, 0} +} + + local area = createCombatArea(arr) + combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/feroxa summon.lua b/data/spells/scripts/monster/feroxa summon.lua new file mode 100644 index 00000000000..c4215ea0460 --- /dev/null +++ b/data/spells/scripts/monster/feroxa summon.lua @@ -0,0 +1,45 @@ +local summons = { + [1] = {name = "Werewolf"} +} + +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_TELEPORT) + + arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat:setArea(area) + +local maxsummons = 10 + +function onCastSpell(creature, var) +creature:say("RISE MY SERVANTS! RISE!!", TALKTYPE_MONSTER_SAY) + + local summoncount = creature:getSummons() + local creaturePos = creature:getPosition() + if #summoncount < 10 then + for i = 1, maxsummons do + local mid = Game.createMonster(summons[math.random(#summons)].name, Position(creaturePos.x + math.random(-3, 3), creaturePos.y + math.random(-3, 3), creaturePos.z)) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ferumbras electrify.lua b/data/spells/scripts/monster/ferumbras electrify.lua new file mode 100644 index 00000000000..c8fdc2329c8 --- /dev/null +++ b/data/spells/scripts/monster/ferumbras electrify.lua @@ -0,0 +1,31 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT) + +local condition = Condition(CONDITION_ENERGY) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(20, 10000, -25) +combat:addCondition(condition) + +arr = { +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 1, 3, 1, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +} + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ferumbras soulfire.lua b/data/spells/scripts/monster/ferumbras soulfire.lua new file mode 100644 index 00000000000..5eab6980d81 --- /dev/null +++ b/data/spells/scripts/monster/ferumbras soulfire.lua @@ -0,0 +1,32 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(50, 9000, -10) +combat:addCondition(condition) + +arr = { +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +} + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/feverish citizen drunk.lua b/data/spells/scripts/monster/feverish citizen drunk.lua new file mode 100644 index 00000000000..1a7a8353f1c --- /dev/null +++ b/data/spells/scripts/monster/feverish citizen drunk.lua @@ -0,0 +1,19 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POISONAREA) + +local condition = Condition(CONDITION_DRUNK) +condition:setParameter(CONDITION_PARAM_TICKS, 25000) +combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/feversleep skill reducer.lua b/data/spells/scripts/monster/feversleep skill reducer.lua new file mode 100644 index 00000000000..061994fde68 --- /dev/null +++ b/data/spells/scripts/monster/feversleep skill reducer.lua @@ -0,0 +1,36 @@ +local combat = {} + +for i = 35, 60 do +combat[i] = Combat() +combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_YELLOW_RINGS) + +local condition = Condition(CONDITION_ATTRIBUTES) +condition:setParameter(CONDITION_PARAM_TICKS, 8000) +condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) +condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + +arr = { +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +} + +local area = createCombatArea(arr) + combat[i]:setArea(area) + combat[i]:addCondition(condition) + +end + +function onCastSpell(creature, var) + return combat[math.random(35, 60)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/fire overlord paralyze.lua b/data/spells/scripts/monster/fire overlord paralyze.lua new file mode 100644 index 00000000000..462976a0116 --- /dev/null +++ b/data/spells/scripts/monster/fire overlord paralyze.lua @@ -0,0 +1,31 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONAREA) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.3, 0, -0.65, 0) + combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/fire overlord soulfire.lua b/data/spells/scripts/monster/fire overlord soulfire.lua new file mode 100644 index 00000000000..f442bed1a40 --- /dev/null +++ b/data/spells/scripts/monster/fire overlord soulfire.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONHIT) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(50, 9000, -10) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/firestarter soulfire.lua b/data/spells/scripts/monster/firestarter soulfire.lua new file mode 100644 index 00000000000..3c2133a17cd --- /dev/null +++ b/data/spells/scripts/monster/firestarter soulfire.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONHIT) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FLAMMINGARROW) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(10, 9000, -10) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/flamecaller zazrak summon.lua b/data/spells/scripts/monster/flamecaller zazrak summon.lua new file mode 100644 index 00000000000..7efd3fff02c --- /dev/null +++ b/data/spells/scripts/monster/flamecaller zazrak summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_NONE) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 3 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 3 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Fire Elemental", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/forest fury skill reducer 1.lua b/data/spells/scripts/monster/forest fury skill reducer 1.lua new file mode 100644 index 00000000000..443c69786ff --- /dev/null +++ b/data/spells/scripts/monster/forest fury skill reducer 1.lua @@ -0,0 +1,19 @@ +local combat = {} + +for i = 40, 50 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_LARGEROCK) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 7000) + condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(40, 50)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/forest fury skill reducer 2.lua b/data/spells/scripts/monster/forest fury skill reducer 2.lua new file mode 100644 index 00000000000..11b8b581823 --- /dev/null +++ b/data/spells/scripts/monster/forest fury skill reducer 2.lua @@ -0,0 +1,19 @@ +local combat = {} + +for i = 50, 65 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_HUNTINGSPEAR) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 7000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(50, 65)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/frazzlemaw paralyze.lua b/data/spells/scripts/monster/frazzlemaw paralyze.lua new file mode 100644 index 00000000000..87ea9c58f9b --- /dev/null +++ b/data/spells/scripts/monster/frazzlemaw paralyze.lua @@ -0,0 +1,30 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.6, 0, -0.8, 0) + combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 1, 1, 1, 1, 3, 1, 1, 1, 1, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/freed soul spell.lua b/data/spells/scripts/monster/freed soul spell.lua new file mode 100644 index 00000000000..513086451fb --- /dev/null +++ b/data/spells/scripts/monster/freed soul spell.lua @@ -0,0 +1,38 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_PURPLEENERGY) + +combat:setArea(createCombatArea({ +{0, 0, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 0}, +{1, 1, 1, 1, 1, 1, 1}, +{1, 1, 1, 3, 1, 1, 1}, +{1, 1, 1, 1, 1, 1, 1}, +{0, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 0, 0} +})) + +function spellCallback(param) + local tile = Tile(Position(param.pos)) + if tile then + if tile:getTopCreature() and tile:getTopCreature():isMonster() then + if tile:getTopCreature():getName():lower() == "the souldespoiler" then + tile:getTopCreature():addHealth( - math.random(500, 2000)) + end + end + end +end + +function onTargetTile(cid, pos) + local param = {} + param.cid = cid + param.pos = pos + param.count = 0 + spellCallback(param) +end + +setCombatCallback(combat, CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/frost dragon paralyze 1.lua b/data/spells/scripts/monster/frost dragon paralyze 1.lua new file mode 100644 index 00000000000..30433f85602 --- /dev/null +++ b/data/spells/scripts/monster/frost dragon paralyze 1.lua @@ -0,0 +1,15 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POFF) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.35, 0, -0.45, 0) + combat:addCondition(condition) + + local area = createCombatArea(AREA_SQUARE1X1) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/frost dragon paralyze 2.lua b/data/spells/scripts/monster/frost dragon paralyze 2.lua new file mode 100644 index 00000000000..24ceddedc05 --- /dev/null +++ b/data/spells/scripts/monster/frost dragon paralyze 2.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ICE) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.35, 0, -0.5, 0) +combat:addCondition(condition) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/frost dragon paralyze 3.lua b/data/spells/scripts/monster/frost dragon paralyze 3.lua new file mode 100644 index 00000000000..2d03c5157c9 --- /dev/null +++ b/data/spells/scripts/monster/frost dragon paralyze 3.lua @@ -0,0 +1,25 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEATTACK) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.6, 0, -0.8, 0) +combat:addCondition(condition) + +local area = createCombatArea({ + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0} +}) +combat:setArea(area) +combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/frozen minion beam.lua b/data/spells/scripts/monster/frozen minion beam.lua new file mode 100644 index 00000000000..9a5bfda35b0 --- /dev/null +++ b/data/spells/scripts/monster/frozen minion beam.lua @@ -0,0 +1,25 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POFF) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setArea(createCombatArea(AREA_BEAM7)) + +function onTargetCreature(creature, target) + local min = 200 + local max = 700 + + local master = target:getMaster() + if target:isPlayer() and not master + or master and master:isPlayer() then + doTargetCombatHealth(0, target, COMBAT_ICEDAMAGE, min, max, CONST_ME_NONE) + return true + end + + doTargetCombatHealth(0, target, COMBAT_HEALING, min, max, CONST_ME_NONE) + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/frozen minion heal.lua b/data/spells/scripts/monster/frozen minion heal.lua new file mode 100644 index 00000000000..7ad5a79779c --- /dev/null +++ b/data/spells/scripts/monster/frozen minion heal.lua @@ -0,0 +1,24 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setArea(createCombatArea(AREA_CIRCLE2X2)) + +function onTargetCreature(creature, target) + local min = 100 + local max = 200 + + local master = target:getMaster() + if target:isPlayer() and not master + or master and master:isPlayer() then + return true + end + + doTargetCombatHealth(0, target, COMBAT_HEALING, min, max, CONST_ME_NONE) + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/frozen minion wave.lua b/data/spells/scripts/monster/frozen minion wave.lua new file mode 100644 index 00000000000..6d5ab12617c --- /dev/null +++ b/data/spells/scripts/monster/frozen minion wave.lua @@ -0,0 +1,35 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POFF) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) + +arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onTargetCreature(creature, target) + local min = 200 + local max = 700 + + local master = target:getMaster() + if target:isPlayer() and not master + or master and master:isPlayer() then + doTargetCombatHealth(0, target, COMBAT_ICEDAMAGE, min, max, CONST_ME_NONE) + return true + end + + doTargetCombatHealth(0, target, COMBAT_HEALING, min, max, CONST_ME_NONE) + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/fury paralyze.lua b/data/spells/scripts/monster/fury paralyze.lua new file mode 100644 index 00000000000..1a848c9390c --- /dev/null +++ b/data/spells/scripts/monster/fury paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_THROWINGSTAR) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 10000) + condition:setFormula(-0.25, 0, -0.35, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/fury skill reducer 1.lua b/data/spells/scripts/monster/fury skill reducer 1.lua new file mode 100644 index 00000000000..697590274a2 --- /dev/null +++ b/data/spells/scripts/monster/fury skill reducer 1.lua @@ -0,0 +1,18 @@ +local combat = {} + +for i = 65, 80 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_YELLOW) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 5000) + condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE3X3) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(65, 80)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/fury skill reducer 2.lua b/data/spells/scripts/monster/fury skill reducer 2.lua new file mode 100644 index 00000000000..7d618689696 --- /dev/null +++ b/data/spells/scripts/monster/fury skill reducer 2.lua @@ -0,0 +1,20 @@ +local combat = {} + +for i = 45, 60 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_YELLOW) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 5000) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE3X3) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(45, 60)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/furyosa deathball.lua b/data/spells/scripts/monster/furyosa deathball.lua new file mode 100644 index 00000000000..760e1ececba --- /dev/null +++ b/data/spells/scripts/monster/furyosa deathball.lua @@ -0,0 +1,31 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + +arr = { +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +} + + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + if creature:getHealth() < creature:getMaxHealth() * 0.4 then + creature:say("Back in black!", TALKTYPE_ORANGE_1) + return combat:execute(creature, var) + end + return false +end diff --git a/data/spells/scripts/monster/furyosa heal.lua b/data/spells/scripts/monster/furyosa heal.lua new file mode 100644 index 00000000000..1df8de9c663 --- /dev/null +++ b/data/spells/scripts/monster/furyosa heal.lua @@ -0,0 +1,15 @@ +local condition = Condition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) +condition:setParameter(CONDITION_PARAM_SUBID, 88888) +condition:setParameter(CONDITION_PARAM_TICKS, 15 * 60 * 1000) +condition:setParameter(CONDITION_PARAM_HEALTHGAIN, 0.01) +condition:setParameter(CONDITION_PARAM_HEALTHTICKS, 15 * 60 * 1000) + +function onCastSpell(creature, var) + if creature:getHealth() < creature:getMaxHealth() * 0.2 and not creature:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, 88888) then + creature:addCondition(condition) + creature:addHealth(10000) + else + return + end + return true +end diff --git a/data/spells/scripts/monster/furyosa manadrain.lua b/data/spells/scripts/monster/furyosa manadrain.lua new file mode 100644 index 00000000000..2e13556063e --- /dev/null +++ b/data/spells/scripts/monster/furyosa manadrain.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_MANADRAIN) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BLOCKHIT) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/furyosa skill reducer.lua b/data/spells/scripts/monster/furyosa skill reducer.lua new file mode 100644 index 00000000000..bb9b8edfea0 --- /dev/null +++ b/data/spells/scripts/monster/furyosa skill reducer.lua @@ -0,0 +1,34 @@ +local combat = {} + +for i = 40, 50 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_YELLOW) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 10000) + condition:setParameter(CONDITION_PARAM_STAT_MAGICPOINTSPERCENT, i) + + arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(40, 50)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/furyosa soulfire.lua b/data/spells/scripts/monster/furyosa soulfire.lua new file mode 100644 index 00000000000..367dab8ff7b --- /dev/null +++ b/data/spells/scripts/monster/furyosa soulfire.lua @@ -0,0 +1,26 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONHIT) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(30, 9000, -10) +combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/furyosa summon.lua b/data/spells/scripts/monster/furyosa summon.lua new file mode 100644 index 00000000000..b971605e1ce --- /dev/null +++ b/data/spells/scripts/monster/furyosa summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_NONE) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) + +local maxsummons = 4 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 4 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Fury", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/gaz'haragoth death.lua b/data/spells/scripts/monster/gaz'haragoth death.lua new file mode 100644 index 00000000000..bff69eba0a6 --- /dev/null +++ b/data/spells/scripts/monster/gaz'haragoth death.lua @@ -0,0 +1,79 @@ +local vocation = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID, + VOCATION.CLIENT_ID.PALADIN, + VOCATION.CLIENT_ID.KNIGHT +} + +local area = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + +local createArea = createCombatArea(area) + +local combat = Combat() +combat:setArea(createArea) + +function onTargetTile(creature, pos) + local creatureTable = {} + local n, i = Tile({x=pos.x, y=pos.y, z=pos.z}).creatures, 1 + if n ~= 0 then + local v = getThingfromPos({x=pos.x, y=pos.y, z=pos.z, stackpos=i}).uid + while v ~= 0 do + if isCreature(v) == true then + table.insert(creatureTable, v) + if n == #creatureTable then + break + end + end + i = i + 1 + v = getThingfromPos({x=pos.x, y=pos.y, z=pos.z, stackpos=i}).uid + end + end + if #creatureTable ~= nil and #creatureTable > 0 then + for r = 1, #creatureTable do + if creatureTable[r] ~= creature then + local min = 30000 + local max = 30000 + local player = Player(creatureTable[r]) + + if isPlayer(creatureTable[r]) == true and table.contains(vocation, player:getVocation():getClientId()) then + doTargetCombatHealth(creature, creatureTable[r], COMBAT_ENERGYDAMAGE, -min, -max, CONST_ME_NONE) + elseif isMonster(creatureTable[r]) == true then + doTargetCombatHealth(creature, creatureTable[r], COMBAT_ENERGYDAMAGE, -min, -max, CONST_ME_NONE) + end + end + end + end + pos:sendMagicEffect(CONST_ME_PURPLEENERGY) + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +local function delayedCastSpell(cid, var) + local creature = Creature(cid) + if not creature then + return + end + creature:say("Gaz'haragoth calls down: DEATH AND DOOM!", TALKTYPE_ORANGE_2) + return combat:execute(creature, positionToVariant(creature:getPosition())) +end + +function onCastSpell(creature, var) + creature:say("Gaz'haragoth begins to channel DEATH AND DOOM into the area! RUN!", TALKTYPE_ORANGE_2) + addEvent(delayedCastSpell, 5000, creature:getId(), var) + return true +end diff --git a/data/spells/scripts/monster/gaz'haragoth iceball.lua b/data/spells/scripts/monster/gaz'haragoth iceball.lua new file mode 100644 index 00000000000..3cba4941b26 --- /dev/null +++ b/data/spells/scripts/monster/gaz'haragoth iceball.lua @@ -0,0 +1,28 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEAREA) + +arr = { +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +} + + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) +creature:say("Chill out!", TALKTYPE_ORANGE_1) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/gaz'haragoth paralyze.lua b/data/spells/scripts/monster/gaz'haragoth paralyze.lua new file mode 100644 index 00000000000..f1dc39c4fb4 --- /dev/null +++ b/data/spells/scripts/monster/gaz'haragoth paralyze.lua @@ -0,0 +1,30 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_STUN) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.55, 0, -0.85, 0) + combat:addCondition(condition) + +arr = { +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 1, 3, 1, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +} + local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/gaz'haragoth summon.lua b/data/spells/scripts/monster/gaz'haragoth summon.lua new file mode 100644 index 00000000000..41481dcd057 --- /dev/null +++ b/data/spells/scripts/monster/gaz'haragoth summon.lua @@ -0,0 +1,27 @@ +function onCastSpell(creature, var) +local t, spectator = Game.getSpectators(creature:getPosition(), false, false, 5, 5, 5, 5) + local check = 0 + if #t ~= nil then + for i = 1, #t do + spectator = t[i] + if spectator:getName() == "Minion Of Gaz'haragoth" then + check = check + 1 + end + end + end + local hp = (creature:getHealth()/creature:getMaxHealth())* 100 + if ((check < 2) and hp <= 95) or ((check < 4) and hp <= 75) or ((check < 6) and hp <= 55) or ((check < 10) and hp <= 35) then + for j = 1, 5 do + creature:say("Minions! Follow my call!", TALKTYPE_ORANGE_1) + end + for k = 1, 2 do + local monster = Game.createMonster("minion of gaz'haragoth", creature:getPosition(), true, false) + if not monster then + return + end + creature:getPosition():sendMagicEffect(CONST_ME_SOUND_RED) + end + else + end +return true +end diff --git a/data/spells/scripts/monster/generator.lua b/data/spells/scripts/monster/generator.lua new file mode 100644 index 00000000000..fa8d74abfb5 --- /dev/null +++ b/data/spells/scripts/monster/generator.lua @@ -0,0 +1,13 @@ +local generator = { + [1] = {pos = Position(33708, 32042, 15)}, + [2] = {pos = Position(33714, 32042, 15)}, + [3] = {pos = Position(33708, 32051, 15)}, + [4] = {pos = Position(33714, 32051, 15)} +} +function onCastSpell(creature, var) + local rand = math.random(1, 4) + local generators = generator[rand] + local monster = Game.createMonster('glooth-generator', generators.pos, true, true) + monster:say('THE GLOOTH GENERATOR CHARGES UP FOR A LETHAL EXPLOSION!', TALKTYPE_MONSTER_YELL) + return +end diff --git a/data/spells/scripts/monster/ghastly dragon curse.lua b/data/spells/scripts/monster/ghastly dragon curse.lua new file mode 100644 index 00000000000..1bd13daf07f --- /dev/null +++ b/data/spells/scripts/monster/ghastly dragon curse.lua @@ -0,0 +1,33 @@ +local combat = {} + +for i = 40, 170 do + for j = 1, 3 do + local index = ((i - 40) * 3) + j + combat[index] = Combat() + combat[index]:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) + combat[index]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + combat[index]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_DEATH) + + local condition = Condition(CONDITION_CURSED) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + + local damage = i + condition:addDamage(1, 4000, -damage) + for k = 1, 4 do + damage = damage * 1.2 + condition:addDamage(1, 4000, -damage) + end + if j > 1 then + damage = damage * 1.2 + condition:addDamage(1, 4000, -damage) + if j > 2 then + condition:addDamage(1, 4000, -(damage * 1.2)) + end + end + combat[index]:addCondition(condition) + end +end + +function onCastSpell(creature, var) + return combat[math.random(#combat)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ghastly dragon paralyze.lua b/data/spells/scripts/monster/ghastly dragon paralyze.lua new file mode 100644 index 00000000000..2e4438fecb8 --- /dev/null +++ b/data/spells/scripts/monster/ghastly dragon paralyze.lua @@ -0,0 +1,11 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BATS) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.8, 0, -0.9, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ghastly dragon wave.lua b/data/spells/scripts/monster/ghastly dragon wave.lua new file mode 100644 index 00000000000..6fb24ae1637 --- /dev/null +++ b/data/spells/scripts/monster/ghastly dragon wave.lua @@ -0,0 +1,19 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_LOSEENERGY) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ghazbaran paralyze.lua b/data/spells/scripts/monster/ghazbaran paralyze.lua new file mode 100644 index 00000000000..d99e602c978 --- /dev/null +++ b/data/spells/scripts/monster/ghazbaran paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_DRAWBLOOD) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_THROWINGKNIFE) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 10000) + condition:setFormula(-0.75, 0, -0.90, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ghazbaran skill reducer 1.lua b/data/spells/scripts/monster/ghazbaran skill reducer 1.lua new file mode 100644 index 00000000000..5c333ec8f25 --- /dev/null +++ b/data/spells/scripts/monster/ghazbaran skill reducer 1.lua @@ -0,0 +1,34 @@ +local combat = {} + +for i = 0, 15 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BLOCKHIT) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 10000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + + arr = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(0, 15)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ghazbaran skill reducer 2.lua b/data/spells/scripts/monster/ghazbaran skill reducer 2.lua new file mode 100644 index 00000000000..f0331ea6e67 --- /dev/null +++ b/data/spells/scripts/monster/ghazbaran skill reducer 2.lua @@ -0,0 +1,34 @@ +local combat = {} + +for i = 0, 15 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 10000) + condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + + arr = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(0, 15)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ghazbaran summon.lua b/data/spells/scripts/monster/ghazbaran summon.lua new file mode 100644 index 00000000000..97cb6a049b9 --- /dev/null +++ b/data/spells/scripts/monster/ghazbaran summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_TELEPORT) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) + +local maxsummons = 4 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 4 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Deathslicer", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ghoulish hyaena wave.lua b/data/spells/scripts/monster/ghoulish hyaena wave.lua new file mode 100644 index 00000000000..067b9bf8b2b --- /dev/null +++ b/data/spells/scripts/monster/ghoulish hyaena wave.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POISONAREA) + +local condition = Condition(CONDITION_POISON) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(1, 4000, -3) +condition:addDamage(9, 4000, -2) +condition:addDamage(21, 4000, -1) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/glooth anemone summon.lua b/data/spells/scripts/monster/glooth anemone summon.lua new file mode 100644 index 00000000000..c6b512c97f5 --- /dev/null +++ b/data/spells/scripts/monster/glooth anemone summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 1 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 1 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Glooth Blob", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/glooth battery heal.lua b/data/spells/scripts/monster/glooth battery heal.lua new file mode 100644 index 00000000000..e052ec48daa --- /dev/null +++ b/data/spells/scripts/monster/glooth battery heal.lua @@ -0,0 +1,26 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +function onTargetCreature(creature, target) + local min = 50 + local max = 500 + + local master = target:getMaster() + if target:isPlayer() and not master + or master and master:isPlayer() then + return true + end + + doTargetCombatHealth(0, target, COMBAT_HEALING, min, max, CONST_ME_NONE) + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/glooth bomb walkthrough.lua b/data/spells/scripts/monster/glooth bomb walkthrough.lua new file mode 100644 index 00000000000..a0d787b8d1d --- /dev/null +++ b/data/spells/scripts/monster/glooth bomb walkthrough.lua @@ -0,0 +1,34 @@ +local condition = Condition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) +condition:setParameter(CONDITION_PARAM_SUBID, 88888) +condition:setParameter(CONDITION_PARAM_TICKS, 10 * 1000) +condition:setParameter(CONDITION_PARAM_HEALTHGAIN, 0.01) +condition:setParameter(CONDITION_PARAM_HEALTHTICKS, 10 * 1000) + +local function changeSpeeds(cid, var) + local creature = Creature(cid) + if not creature then + return + end + creature:changeSpeed(creature:getBaseSpeed()) +end + +function onCastSpell(creature, var) + local nextPosition = creature:getPosition() + local speed = creature:getSpeed() + local tile = Tile(nextPosition.x, nextPosition.y - 1, nextPosition.z) + local topCreature = tile:getTopCreature() + if not creature:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, 88888) then + creature:addCondition(condition) + creature:teleportTo(Position(nextPosition.x, nextPosition.y - 1, nextPosition.z), true) + creature:changeSpeed(-speed) + addEvent(changeSpeeds, 11 * 1000, creature:getId(), var) + if not topCreature then + return + end + if topCreature:isPlayer() then + topCreature:teleportTo(Position(nextPosition.x, nextPosition.y - 3, nextPosition.z), true) + else + end + end + return true +end diff --git a/data/spells/scripts/monster/glooth fairy healing.lua b/data/spells/scripts/monster/glooth fairy healing.lua new file mode 100644 index 00000000000..ea1278695e8 --- /dev/null +++ b/data/spells/scripts/monster/glooth fairy healing.lua @@ -0,0 +1,17 @@ +local condition = Condition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) +condition:setParameter(CONDITION_PARAM_SUBID, 88888) +condition:setParameter(CONDITION_PARAM_TICKS, 30 * 1000) +condition:setParameter(CONDITION_PARAM_HEALTHGAIN, 0.01) +condition:setParameter(CONDITION_PARAM_HEALTHTICKS, 30 * 1000) + +function onCastSpell(creature, var) + if creature:getHealth() < creature:getMaxHealth() * 0.1 and not creature:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, 88888) then + creature:addCondition(condition) + addEvent(function(cid) + creature:addHealth(math.random(7500, 8000)) + creature:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + return true + end, 10 * 1000, creature:getId()) + end + return true +end diff --git a/data/spells/scripts/monster/glooth fairy paralyze.lua b/data/spells/scripts/monster/glooth fairy paralyze.lua new file mode 100644 index 00000000000..8b17249133f --- /dev/null +++ b/data/spells/scripts/monster/glooth fairy paralyze.lua @@ -0,0 +1,32 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYPOISON) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.6, 0, -0.8, 0) +combat:addCondition(condition) + +arr = { +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +} + +local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/glooth fairy skill reducer.lua b/data/spells/scripts/monster/glooth fairy skill reducer.lua new file mode 100644 index 00000000000..2aae6b49e2f --- /dev/null +++ b/data/spells/scripts/monster/glooth fairy skill reducer.lua @@ -0,0 +1,29 @@ +local combat = {} + +for i = 40, 60 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 6000) + condition:setParameter(CONDITION_PARAM_STAT_MAGICPOINTSPERCENT, i) + + local arr = { + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + + local area = createCombatArea(arr) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(40, 60)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/glooth-generator summon.lua b/data/spells/scripts/monster/glooth-generator summon.lua new file mode 100644 index 00000000000..3d584a2b1fa --- /dev/null +++ b/data/spells/scripts/monster/glooth-generator summon.lua @@ -0,0 +1,13 @@ +function onCastSpell(creature, var) + addEvent(function(cid) + local creature = Creature(cid) + if not creature then + return + end + Game.createMonster("Energy Pulse", creature:getPosition(), true, true) + creature:say("The fully charged generator explodes in a blast!", TALKTYPE_ORANGE_2) + creature:remove() + return true + end, 14000, creature:getId()) +return true +end diff --git a/data/spells/scripts/monster/gnomevil drunk.lua b/data/spells/scripts/monster/gnomevil drunk.lua new file mode 100644 index 00000000000..45f3da09e9a --- /dev/null +++ b/data/spells/scripts/monster/gnomevil drunk.lua @@ -0,0 +1,21 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_STUN) + +local condition = Condition(CONDITION_DRUNK) +condition:setParameter(CONDITION_PARAM_TICKS, 25000) +combat:addCondition(condition) + + arr = { + {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/gnomevil electrify.lua b/data/spells/scripts/monster/gnomevil electrify.lua new file mode 100644 index 00000000000..df3dae43ec7 --- /dev/null +++ b/data/spells/scripts/monster/gnomevil electrify.lua @@ -0,0 +1,26 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA) + +local condition = Condition(CONDITION_ENERGY) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(36, 10000, -25) +combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/gnomevil skill reducer 1.lua b/data/spells/scripts/monster/gnomevil skill reducer 1.lua new file mode 100644 index 00000000000..b96f626e3be --- /dev/null +++ b/data/spells/scripts/monster/gnomevil skill reducer 1.lua @@ -0,0 +1,18 @@ +local combat = {} + +for i = 10, 45 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 10000) + condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(10, 45)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/gnomevil skill reducer 2.lua b/data/spells/scripts/monster/gnomevil skill reducer 2.lua new file mode 100644 index 00000000000..b84ccbbf8b1 --- /dev/null +++ b/data/spells/scripts/monster/gnomevil skill reducer 2.lua @@ -0,0 +1,18 @@ +local combat = {} + +for i = 15, 45 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 10000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(15, 45)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/gnomevil soulfire.lua b/data/spells/scripts/monster/gnomevil soulfire.lua new file mode 100644 index 00000000000..dd803af9670 --- /dev/null +++ b/data/spells/scripts/monster/gnomevil soulfire.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREATTACK) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(159, 9000, -10) +combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/gnorre chyllson drown.lua b/data/spells/scripts/monster/gnorre chyllson drown.lua new file mode 100644 index 00000000000..9350ac4ec5c --- /dev/null +++ b/data/spells/scripts/monster/gnorre chyllson drown.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_DROWNDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_LOSEENERGY) + +local condition = Condition(CONDITION_DROWN) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(20, 5000, -20) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/gnorre chyllson paralyze.lua b/data/spells/scripts/monster/gnorre chyllson paralyze.lua new file mode 100644 index 00000000000..80a993a7c17 --- /dev/null +++ b/data/spells/scripts/monster/gnorre chyllson paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SNOWBALL) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.1, 0, -0.2, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/gnorre chyllson skill reducer.lua b/data/spells/scripts/monster/gnorre chyllson skill reducer.lua new file mode 100644 index 00000000000..d95563b33bb --- /dev/null +++ b/data/spells/scripts/monster/gnorre chyllson skill reducer.lua @@ -0,0 +1,21 @@ +local combat = {} + +for i = 45, 55 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POFF) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 3000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE3X3) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(45, 55)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/grand mother foulscale summon.lua b/data/spells/scripts/monster/grand mother foulscale summon.lua new file mode 100644 index 00000000000..f4f35869cf2 --- /dev/null +++ b/data/spells/scripts/monster/grand mother foulscale summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_BLUE) + +local area = createCombatArea(AREA_CIRCLE3X3) +combat:setArea(area) + +local maxsummons = 4 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 4 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Dragon Hatchling", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/grandfather tridian paralyze.lua b/data/spells/scripts/monster/grandfather tridian paralyze.lua new file mode 100644 index 00000000000..8f4b510421a --- /dev/null +++ b/data/spells/scripts/monster/grandfather tridian paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_HOLY) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.50, 0, -0.90, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/greater jar summon.lua b/data/spells/scripts/monster/greater jar summon.lua new file mode 100644 index 00000000000..a2fe58ba1ae --- /dev/null +++ b/data/spells/scripts/monster/greater jar summon.lua @@ -0,0 +1,20 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POFF) + +local area = createCombatArea(AREA_CIRCLE3X3) +combat:setArea(area) + +local maxsummons = 1 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 1 then + mid = Game.createMonster("Elder Mummy", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/haunted treeling paralyze.lua b/data/spells/scripts/monster/haunted treeling paralyze.lua new file mode 100644 index 00000000000..b3565769277 --- /dev/null +++ b/data/spells/scripts/monster/haunted treeling paralyze.lua @@ -0,0 +1,25 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLPLANTS) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.55, 0, -0.75, 0) +combat:addCondition(condition) + + arr = { + {1}, + {1}, + {1}, + {1}, + {1}, + {3} + } + +local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/haunter curse.lua b/data/spells/scripts/monster/haunter curse.lua new file mode 100644 index 00000000000..0a10d639677 --- /dev/null +++ b/data/spells/scripts/monster/haunter curse.lua @@ -0,0 +1,24 @@ +local combat = {} + +for i = 2, 2 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_NONE) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_DEATH) + + local condition = Condition(CONDITION_CURSED) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + + local damage = i + condition:addDamage(1, 4000, -damage) + for j = 1, 19 do + damage = damage * 1.2 + condition:addDamage(1, 4000, -damage) + end + + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(2, 2)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/haunter electrify.lua b/data/spells/scripts/monster/haunter electrify.lua new file mode 100644 index 00000000000..30f3b105ad8 --- /dev/null +++ b/data/spells/scripts/monster/haunter electrify.lua @@ -0,0 +1,12 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + +local condition = Condition(CONDITION_ENERGY) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(10, 10000, -25) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/hell hole summon.lua b/data/spells/scripts/monster/hell hole summon.lua new file mode 100644 index 00000000000..ab0d8a8b12e --- /dev/null +++ b/data/spells/scripts/monster/hell hole summon.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + +local maxsummons = 4 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 4 then + mid = Game.createMonster("Deathspawn", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/hellfire fighter soulfire.lua b/data/spells/scripts/monster/hellfire fighter soulfire.lua new file mode 100644 index 00000000000..2bbb5718a45 --- /dev/null +++ b/data/spells/scripts/monster/hellfire fighter soulfire.lua @@ -0,0 +1,31 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREATTACK) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(20, 9000, -10) + +arr = { +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +} + +local area = createCombatArea(arr) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/hellgorak skill reducer.lua b/data/spells/scripts/monster/hellgorak skill reducer.lua new file mode 100644 index 00000000000..b6365a397ae --- /dev/null +++ b/data/spells/scripts/monster/hellgorak skill reducer.lua @@ -0,0 +1,34 @@ +local combat = {} + +for i = 20, 40 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POFF) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + + arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(20, 40)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/hellspawn soulfire.lua b/data/spells/scripts/monster/hellspawn soulfire.lua new file mode 100644 index 00000000000..c2081685762 --- /dev/null +++ b/data/spells/scripts/monster/hellspawn soulfire.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONHIT) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(26, 9000, -10) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/hideous fungus paralyze.lua b/data/spells/scripts/monster/hideous fungus paralyze.lua new file mode 100644 index 00000000000..a0c52c79f89 --- /dev/null +++ b/data/spells/scripts/monster/hideous fungus paralyze.lua @@ -0,0 +1,19 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_STUN) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_DEATH) + + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.40, 0, -0.80, 0) +combat:addCondition(condition) + + +local area = createCombatArea(AREA_CIRCLE2X2) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/hideous fungus poison.lua b/data/spells/scripts/monster/hideous fungus poison.lua new file mode 100644 index 00000000000..f20d3d23831 --- /dev/null +++ b/data/spells/scripts/monster/hideous fungus poison.lua @@ -0,0 +1,24 @@ +local combat = {} + +for i = 25, 30 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_POISONDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYPOISON) + + local condition = Condition(CONDITION_POISON) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + condition:addDamage(10, 4000, -i) + condition:addDamage(10, 4000, -i + 1) + condition:addDamage(10, 4000, -i + 2) + condition:addDamage(10, 4000, -i + 3) + condition:addDamage(10, 4000, -i + 4) + + + local area = createCombatArea(AREA_SQUARE1X1) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(25, 30)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/hideous fungus summon.lua b/data/spells/scripts/monster/hideous fungus summon.lua new file mode 100644 index 00000000000..4c66250be42 --- /dev/null +++ b/data/spells/scripts/monster/hideous fungus summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_TELEPORT) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Humorless Fungus", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/hirintror freeze.lua b/data/spells/scripts/monster/hirintror freeze.lua new file mode 100644 index 00000000000..7b63cd1dfd9 --- /dev/null +++ b/data/spells/scripts/monster/hirintror freeze.lua @@ -0,0 +1,31 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICETORNADO) + + local condition = Condition(CONDITION_FREEZING) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + condition:addDamage(25, 8000, -8) + combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/hirintror heal.lua b/data/spells/scripts/monster/hirintror heal.lua new file mode 100644 index 00000000000..d4fc56fce6e --- /dev/null +++ b/data/spells/scripts/monster/hirintror heal.lua @@ -0,0 +1,15 @@ +local condition = Condition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) +condition:setParameter(CONDITION_PARAM_SUBID, 88888) +condition:setParameter(CONDITION_PARAM_TICKS, 15 * 60 * 1000) +condition:setParameter(CONDITION_PARAM_HEALTHGAIN, 0.01) +condition:setParameter(CONDITION_PARAM_HEALTHTICKS, 15 * 60 * 1000) + +function onCastSpell(creature, var) + if creature:getHealth() < creature:getMaxHealth() * 0.2 and not creature:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, 88888) then + creature:addCondition(condition) + creature:addHealth(1000) + else + return false + end +return true +end diff --git a/data/spells/scripts/monster/hirintror skill reducer.lua b/data/spells/scripts/monster/hirintror skill reducer.lua new file mode 100644 index 00000000000..7681e9752b5 --- /dev/null +++ b/data/spells/scripts/monster/hirintror skill reducer.lua @@ -0,0 +1,21 @@ +local combat = {} + +for i = 20, 40 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 15000) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + + local area = createCombatArea(AREA_SQUARE1X1) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(20, 40)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/hirintror summon.lua b/data/spells/scripts/monster/hirintror summon.lua new file mode 100644 index 00000000000..6de11a6ae09 --- /dev/null +++ b/data/spells/scripts/monster/hirintror summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_NONE) + +local area = createCombatArea(AREA_CIRCLE3X3) +combat:setArea(area) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Ice Golem", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/hive pore summon.lua b/data/spells/scripts/monster/hive pore summon.lua new file mode 100644 index 00000000000..b3d0f053872 --- /dev/null +++ b/data/spells/scripts/monster/hive pore summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYPOISON) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 3 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 3 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Lesser Swarmer", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/horadron heal.lua b/data/spells/scripts/monster/horadron heal.lua new file mode 100644 index 00000000000..876db5b7d93 --- /dev/null +++ b/data/spells/scripts/monster/horadron heal.lua @@ -0,0 +1,42 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_DRAWBLOOD) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) + +arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onTargetCreature(creature, target) + local min = 400 + local max = 700 + + local master = target:getMaster() + if target:isPlayer() and not master + or master and master:isPlayer() then + return true + end + + doTargetCombatHealth(0, target, COMBAT_HEALING, min, max, CONST_ME_NONE) + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/horadron paralyze.lua b/data/spells/scripts/monster/horadron paralyze.lua new file mode 100644 index 00000000000..18107c151a6 --- /dev/null +++ b/data/spells/scripts/monster/horadron paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_NONE) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.50, 0, -0.75, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/horestis paralyze.lua b/data/spells/scripts/monster/horestis paralyze.lua new file mode 100644 index 00000000000..96c243a42b6 --- /dev/null +++ b/data/spells/scripts/monster/horestis paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.75, 0, -0.90, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/hot dog soulfire.lua b/data/spells/scripts/monster/hot dog soulfire.lua new file mode 100644 index 00000000000..60cab987fc3 --- /dev/null +++ b/data/spells/scripts/monster/hot dog soulfire.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYFIRE) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(20, 9000, -10) + +local area = createCombatArea(AREA_CIRCLE1X1) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/hot dog wave.lua b/data/spells/scripts/monster/hot dog wave.lua new file mode 100644 index 00000000000..634dfd0c2f8 --- /dev/null +++ b/data/spells/scripts/monster/hot dog wave.lua @@ -0,0 +1,19 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYFIRE) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/humongous fungus paralyze.lua b/data/spells/scripts/monster/humongous fungus paralyze.lua new file mode 100644 index 00000000000..43a3997080e --- /dev/null +++ b/data/spells/scripts/monster/humongous fungus paralyze.lua @@ -0,0 +1,24 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.55, 0, -0.80, 0) +combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/humongous fungus poison.lua b/data/spells/scripts/monster/humongous fungus poison.lua new file mode 100644 index 00000000000..1bf66f1e07e --- /dev/null +++ b/data/spells/scripts/monster/humongous fungus poison.lua @@ -0,0 +1,33 @@ +local combat = {} + +for i = 25, 30 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_POISONDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GREEN_RINGS) + + local condition = Condition(CONDITION_POISON) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + condition:addDamage(10, 4000, -i) + condition:addDamage(10, 4000, -i + 1) + condition:addDamage(10, 4000, -i + 2) + condition:addDamage(10, 4000, -i + 3) + condition:addDamage(10, 4000, -i + 4) + + arr = { + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + + local area = createCombatArea(arr) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(25, 30)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/hunger summon.lua b/data/spells/scripts/monster/hunger summon.lua new file mode 100644 index 00000000000..31b08d60404 --- /dev/null +++ b/data/spells/scripts/monster/hunger summon.lua @@ -0,0 +1,27 @@ +local hungerSummonDelay = false + +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_NONE) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) + +local function removeDelay() + hungerSummonDelay = false +end + +function onCastSpell(creature, var) + + if hungerSummonDelay == false then + if hungerSummon < 3 then + Game.createMonster("Greed", {x=creature:getPosition().x+math.random(-1, 1), y=creature:getPosition().y+math.random(-1, 1), z=creature:getPosition().z}, false, true) + hungerSummon = hungerSummon + 1 + + hungerSummonDelay = true + addEvent(removeDelay, 15000) + end + end + + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ice golem paralyze.lua b/data/spells/scripts/monster/ice golem paralyze.lua new file mode 100644 index 00000000000..dbf19598118 --- /dev/null +++ b/data/spells/scripts/monster/ice golem paralyze.lua @@ -0,0 +1,27 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEAREA) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.35, 0, -0.45, 0) +combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ice golem skill reducer.lua b/data/spells/scripts/monster/ice golem skill reducer.lua new file mode 100644 index 00000000000..7681e9752b5 --- /dev/null +++ b/data/spells/scripts/monster/ice golem skill reducer.lua @@ -0,0 +1,21 @@ +local combat = {} + +for i = 20, 40 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 15000) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + + local area = createCombatArea(AREA_SQUARE1X1) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(20, 40)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ice overlord freeze.lua b/data/spells/scripts/monster/ice overlord freeze.lua new file mode 100644 index 00000000000..b2f7bec81c9 --- /dev/null +++ b/data/spells/scripts/monster/ice overlord freeze.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEATTACK) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ICE) + +local condition = Condition(CONDITION_FREEZING) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(30, 8000, -8) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ice overlord paralyze.lua b/data/spells/scripts/monster/ice overlord paralyze.lua new file mode 100644 index 00000000000..86a7086fbc9 --- /dev/null +++ b/data/spells/scripts/monster/ice overlord paralyze.lua @@ -0,0 +1,31 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICETORNADO) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.3, 0, -0.65, 0) + combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ice witch paralyze.lua b/data/spells/scripts/monster/ice witch paralyze.lua new file mode 100644 index 00000000000..02d4f258453 --- /dev/null +++ b/data/spells/scripts/monster/ice witch paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICETORNADO) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ICE) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.55, 0, -0.75, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ice_crystal_bomb.lua b/data/spells/scripts/monster/ice_crystal_bomb.lua new file mode 100644 index 00000000000..5a3154bc9b9 --- /dev/null +++ b/data/spells/scripts/monster/ice_crystal_bomb.lua @@ -0,0 +1,19 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, 44) +combat:setParameter(COMBAT_PARAM_EFFECT, 53) +combat:setParameter(COMBAT_PARAM_BLOCKARMOR, 1) +combat:setParameter(COMBAT_PARAM_USECHARGES, 1) +combat:setArea(createCombatArea(AREA_CIRCLE2X2)) + +function onGetFormulaValues(player, skill, attack, factor) + local skillTotal = skill * attack + local levelTotal = player:getLevel() / 5 + return -(((skillTotal * 0.02) + 4) + (levelTotal)), -(((skillTotal * 0.03) + 6) + (levelTotal)) +end + +combat:setCallback(CALLBACK_PARAM_SKILLVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/icecle heal.lua b/data/spells/scripts/monster/icecle heal.lua new file mode 100644 index 00000000000..19129d6e1c2 --- /dev/null +++ b/data/spells/scripts/monster/icecle heal.lua @@ -0,0 +1,24 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:setArea(createCombatArea(AREA_CIRCLE3X3)) + +function onTargetCreature(creature, target) + local min = 400 + local max = 600 + + local master = target:getMaster() + if target:isPlayer() and not master + or master and master:isPlayer() then + return true + end + + doTargetCombatHealth(0, target, COMBAT_HEALING, min, max, CONST_ME_NONE) + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/incineron soulfire.lua b/data/spells/scripts/monster/incineron soulfire.lua new file mode 100644 index 00000000000..bc53e76ce2f --- /dev/null +++ b/data/spells/scripts/monster/incineron soulfire.lua @@ -0,0 +1,31 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONHIT) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(20, 9000, -10) + +arr = { +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +} + +local area = createCombatArea(arr) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/infected weeper summon.lua b/data/spells/scripts/monster/infected weeper summon.lua new file mode 100644 index 00000000000..c3c3e113b92 --- /dev/null +++ b/data/spells/scripts/monster/infected weeper summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_DRAWBLOOD) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) + +local maxsummons = 1 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 1 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Parasite", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ironblight freeze.lua b/data/spells/scripts/monster/ironblight freeze.lua new file mode 100644 index 00000000000..e8a25b1d527 --- /dev/null +++ b/data/spells/scripts/monster/ironblight freeze.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ICE) + +local condition = Condition(CONDITION_FREEZING) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(30, 8000, -8) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ironblight skill reducer.lua b/data/spells/scripts/monster/ironblight skill reducer.lua new file mode 100644 index 00000000000..0fa6a50cf19 --- /dev/null +++ b/data/spells/scripts/monster/ironblight skill reducer.lua @@ -0,0 +1,18 @@ +local combat = {} + +for i = 30, 70 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 4000) + condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(30, 70)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/jaul paralyze.lua b/data/spells/scripts/monster/jaul paralyze.lua new file mode 100644 index 00000000000..2f469c772d0 --- /dev/null +++ b/data/spells/scripts/monster/jaul paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BUBBLES) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ICE) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 10000) + condition:setFormula(-0.55, 0, -0.85, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/jewelry chest summon.lua b/data/spells/scripts/monster/jewelry chest summon.lua new file mode 100644 index 00000000000..798a89b2e5d --- /dev/null +++ b/data/spells/scripts/monster/jewelry chest summon.lua @@ -0,0 +1,24 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_NONE) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 5 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 5 then + for i = 1, maxsummons - #summoncount do + creature:addHealth(500) + creature:getPosition():sendMagicEffect(12) + local mid = Game.createMonster("Chest Guard", { x=creature:getPosition().x+math.random(-2, 2), y=creature:getPosition().y+math.random(-2, 2), z=creature:getPosition().z }) + if not mid then + return + end + mid:say("FREEZE! LET ME SEE YOUR HANDS UP!", TALKTYPE_ORANGE_2) + end + end +return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/killer rabbit summon.lua b/data/spells/scripts/monster/killer rabbit summon.lua new file mode 100644 index 00000000000..11c273a13bf --- /dev/null +++ b/data/spells/scripts/monster/killer rabbit summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POFF) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Killer Rabbit Summon", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/koshei the deathless curse.lua b/data/spells/scripts/monster/koshei the deathless curse.lua new file mode 100644 index 00000000000..f36250d67e5 --- /dev/null +++ b/data/spells/scripts/monster/koshei the deathless curse.lua @@ -0,0 +1,24 @@ +local combat = {} + +for i = 1, 1 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + + local condition = Condition(CONDITION_CURSED) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + + local damage = i + condition:addDamage(1, 4000, -damage) + for j = 1, 19 do + damage = damage * 1.25 + condition:addDamage(1, 4000, -damage) + end + + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(1, 1)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/koshei the deathless paralyze.lua b/data/spells/scripts/monster/koshei the deathless paralyze.lua new file mode 100644 index 00000000000..b7ebb0323b3 --- /dev/null +++ b/data/spells/scripts/monster/koshei the deathless paralyze.lua @@ -0,0 +1,11 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.6, 0, -0.85, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/kraknaknork explosion wave.lua b/data/spells/scripts/monster/kraknaknork explosion wave.lua new file mode 100644 index 00000000000..9b905432369 --- /dev/null +++ b/data/spells/scripts/monster/kraknaknork explosion wave.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONAREA) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/kraknaknork ice wave.lua b/data/spells/scripts/monster/kraknaknork ice wave.lua new file mode 100644 index 00000000000..1a93d8dd736 --- /dev/null +++ b/data/spells/scripts/monster/kraknaknork ice wave.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEAREA) + + arr = { + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/kraknaknork paralyze.lua b/data/spells/scripts/monster/kraknaknork paralyze.lua new file mode 100644 index 00000000000..27ab798b52d --- /dev/null +++ b/data/spells/scripts/monster/kraknaknork paralyze.lua @@ -0,0 +1,11 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 2000) + condition:setFormula(-0.25, 0, -0.35, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/kraknaknork poison wave.lua b/data/spells/scripts/monster/kraknaknork poison wave.lua new file mode 100644 index 00000000000..95257e4d554 --- /dev/null +++ b/data/spells/scripts/monster/kraknaknork poison wave.lua @@ -0,0 +1,18 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_POISONDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLPLANTS) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lancer beetle curse.lua b/data/spells/scripts/monster/lancer beetle curse.lua new file mode 100644 index 00000000000..cf7ac563714 --- /dev/null +++ b/data/spells/scripts/monster/lancer beetle curse.lua @@ -0,0 +1,23 @@ +local combat = {} + +for i = 1, 1 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_CURSED) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + + local damage = i + condition:addDamage(1, 4000, -damage) + for j = 1, 22 do + damage = damage * 1.2 + condition:addDamage(1, 4000, -damage) + end + + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(1, 1)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lancer beetle skill reducer.lua b/data/spells/scripts/monster/lancer beetle skill reducer.lua new file mode 100644 index 00000000000..e114af216eb --- /dev/null +++ b/data/spells/scripts/monster/lancer beetle skill reducer.lua @@ -0,0 +1,16 @@ +local combat = {} + +for i = 10, 30 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYPOISON) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 15000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(10, 30)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lava golem soulfire.lua b/data/spells/scripts/monster/lava golem soulfire.lua new file mode 100644 index 00000000000..39086b05276 --- /dev/null +++ b/data/spells/scripts/monster/lava golem soulfire.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONHIT) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(40, 9000, -10) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lava golem soulfire2.lua b/data/spells/scripts/monster/lava golem soulfire2.lua new file mode 100644 index 00000000000..f207ffbcb64 --- /dev/null +++ b/data/spells/scripts/monster/lava golem soulfire2.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(40, 9000, -10) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/leaf golem paralyze.lua b/data/spells/scripts/monster/leaf golem paralyze.lua new file mode 100644 index 00000000000..c15470f1c8d --- /dev/null +++ b/data/spells/scripts/monster/leaf golem paralyze.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLPLANTS) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.25, 0, -0.45, 0) +combat:addCondition(condition) + + +local area = createCombatArea(AREA_SQUARE1X1) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lersatio summon.lua b/data/spells/scripts/monster/lersatio summon.lua new file mode 100644 index 00000000000..ca73d88b0b2 --- /dev/null +++ b/data/spells/scripts/monster/lersatio summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BATS) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 3 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 3 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Vampire", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lethal lissy skill reducer.lua b/data/spells/scripts/monster/lethal lissy skill reducer.lua new file mode 100644 index 00000000000..6fd1771b1c2 --- /dev/null +++ b/data/spells/scripts/monster/lethal lissy skill reducer.lua @@ -0,0 +1,20 @@ +local combat = {} + +for i = 10, 25 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_PURPLE) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 10000) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + + local area = createCombatArea(AREA_BEAM1) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(10, 25)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lich paralyze.lua b/data/spells/scripts/monster/lich paralyze.lua new file mode 100644 index 00000000000..6eb66995225 --- /dev/null +++ b/data/spells/scripts/monster/lich paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_DEATH) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.75, 0, -0.85, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lisa heal.lua b/data/spells/scripts/monster/lisa heal.lua new file mode 100644 index 00000000000..47e5a9a7395 --- /dev/null +++ b/data/spells/scripts/monster/lisa heal.lua @@ -0,0 +1,19 @@ +local condition = Condition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) +condition:setParameter(CONDITION_PARAM_SUBID, 88888) +condition:setParameter(CONDITION_PARAM_TICKS, 6 * 1000) +condition:setParameter(CONDITION_PARAM_HEALTHGAIN, 0.01) +condition:setParameter(CONDITION_PARAM_HEALTHTICKS, 6 * 1000) + +function onCastSpell(creature, var) + if creature:getHealth() < creature:getMaxHealth() * 0.07 and not creature:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, 88888) then + creature:say("Lisa takes a final breath before she's healing up!", TALKTYPE_ORANGE_1) + creature:addCondition(condition) + addEvent(function(cid) + creature:addHealth(math.random(18000, 23000)) + creature:say("Lisa healed up!", TALKTYPE_ORANGE_1) + creature:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + return true + end, 6 * 1000, creature:getId()) + end + return true +end diff --git a/data/spells/scripts/monster/lisa paralyze.lua b/data/spells/scripts/monster/lisa paralyze.lua new file mode 100644 index 00000000000..89fa8e49864 --- /dev/null +++ b/data/spells/scripts/monster/lisa paralyze.lua @@ -0,0 +1,15 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.55, 0, -0.75, 0) + combat:addCondition(condition) + + local area = createCombatArea(AREA_CIRCLE3X3) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lisa skill reducer.lua b/data/spells/scripts/monster/lisa skill reducer.lua new file mode 100644 index 00000000000..fa503b2592b --- /dev/null +++ b/data/spells/scripts/monster/lisa skill reducer.lua @@ -0,0 +1,84 @@ +local combat = {} + +for i = 60, 75 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SMALLEARTH) + + local condition1 = Condition(CONDITION_ATTRIBUTES) + condition1:setParameter(CONDITION_PARAM_TICKS, 7000) + condition1:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition1:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + condition1:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + + local condition2 = Condition(CONDITION_ATTRIBUTES) + condition2:setParameter(CONDITION_PARAM_TICKS, 7000) + condition2:setParameter(CONDITION_PARAM_STAT_MAGICPOINTSPERCENT, i) + + local condition3 = Condition(CONDITION_ATTRIBUTES) + condition3:setParameter(CONDITION_PARAM_TICKS, 7000) + condition3:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + condition3:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + + arr = { + {0, 0, 0, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 1, 1, 1}, + {1, 1, 1, 1, 3, 1, 1, 1, 1}, + {1, 1, 1, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 0, 0, 0} + } + + local area = createCombatArea(arr) + combat[i]:setArea(area) + + + function onTargetTile(creature, pos) + local creatureTable = {} + local n, i = Tile({x=pos.x, y=pos.y, z=pos.z}).creatures, 1 + if n ~= 0 then + local v = getThingfromPos({x=pos.x, y=pos.y, z=pos.z, stackpos=i}).uid + while v ~= 0 do + if isCreature(v) == true then + table.insert(creatureTable, v) + if n == #creatureTable then + break + end + end + i = i + 1 + v = getThingfromPos({x=pos.x, y=pos.y, z=pos.z, stackpos=i}).uid + end + end + if #creatureTable ~= nil and #creatureTable > 0 then + for r = 1, #creatureTable do + if creatureTable[r] ~= creature then + local player = Player(creatureTable[r]) + local vocationClientId = player:getVocation():getClientId() + + if isPlayer(creatureTable[r]) == true + and table.contains({VOCATION.CLIENT_ID.SORCERER, VOCATION.CLIENT_ID.DRUID}, vocationClientId) then + player:addCondition(condition2) + elseif isPlayer(creatureTable[r]) == true + and table.contains({VOCATION.CLIENT_ID.PALADIN}, vocationClientId) then + player:addCondition(condition3) + elseif isPlayer(creatureTable[r]) == true + and table.contains({VOCATION.CLIENT_ID.KNIGHT}, vocationClientId) then + player:addCondition(condition1) + elseif isMonster(creatureTable[r]) == true then + end + end + end + end + pos:sendMagicEffect(CONST_ME_SMALLPLANTS) + return true + end + + combat[i]:setCallback(CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +end + +function onCastSpell(creature, var) + return combat[math.random(60, 75)]:execute(creature, var) +end \ No newline at end of file diff --git a/data/spells/scripts/monster/lisa summon.lua b/data/spells/scripts/monster/lisa summon.lua new file mode 100644 index 00000000000..5dac153bbf7 --- /dev/null +++ b/data/spells/scripts/monster/lisa summon.lua @@ -0,0 +1,21 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) + +local maxsummons = 4 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 4 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Glooth Anemone2", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lisa wave.lua b/data/spells/scripts/monster/lisa wave.lua new file mode 100644 index 00000000000..2f9f5b5792a --- /dev/null +++ b/data/spells/scripts/monster/lisa wave.lua @@ -0,0 +1,18 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_POISONDAMAGE) + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GREEN_RINGS) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + + local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lizard dragon priest summon.lua b/data/spells/scripts/monster/lizard dragon priest summon.lua new file mode 100644 index 00000000000..345f60e2b04 --- /dev/null +++ b/data/spells/scripts/monster/lizard dragon priest summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Dragon Hatchling", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lizard gate guardian summon.lua b/data/spells/scripts/monster/lizard gate guardian summon.lua new file mode 100644 index 00000000000..b25835342c4 --- /dev/null +++ b/data/spells/scripts/monster/lizard gate guardian summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Lizard Chosen", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lizard magistratus curse.lua b/data/spells/scripts/monster/lizard magistratus curse.lua new file mode 100644 index 00000000000..bb44b9ef249 --- /dev/null +++ b/data/spells/scripts/monster/lizard magistratus curse.lua @@ -0,0 +1,24 @@ +local combat = {} + +for i = 2, 2 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_DEATH) + + local condition = Condition(CONDITION_CURSED) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + + local damage = i + condition:addDamage(1, 4000, -damage) + for j = 1, 20 do + damage = damage * 1.2 + condition:addDamage(1, 4000, -damage) + end + + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(2, 2)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lizard wave 2.lua b/data/spells/scripts/monster/lizard wave 2.lua new file mode 100644 index 00000000000..cbed884fd60 --- /dev/null +++ b/data/spells/scripts/monster/lizard wave 2.lua @@ -0,0 +1,20 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONHIT) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lizard wave.lua b/data/spells/scripts/monster/lizard wave.lua new file mode 100644 index 00000000000..14415cc1f7e --- /dev/null +++ b/data/spells/scripts/monster/lizard wave.lua @@ -0,0 +1,19 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONHIT) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lloyd wave.lua b/data/spells/scripts/monster/lloyd wave.lua new file mode 100644 index 00000000000..befa9e79d5f --- /dev/null +++ b/data/spells/scripts/monster/lloyd wave.lua @@ -0,0 +1,21 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, 179) + +arr = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +} + + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lloyd wave2.lua b/data/spells/scripts/monster/lloyd wave2.lua new file mode 100644 index 00000000000..f2478e5a400 --- /dev/null +++ b/data/spells/scripts/monster/lloyd wave2.lua @@ -0,0 +1,21 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, 179) + +arr = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +} + + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lloyd wave3.lua b/data/spells/scripts/monster/lloyd wave3.lua new file mode 100644 index 00000000000..fbfa6dc1b54 --- /dev/null +++ b/data/spells/scripts/monster/lloyd wave3.lua @@ -0,0 +1,21 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, 179) + +arr = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +} + + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lord of the elements paralyze.lua b/data/spells/scripts/monster/lord of the elements paralyze.lua new file mode 100644 index 00000000000..f077d1365fa --- /dev/null +++ b/data/spells/scripts/monster/lord of the elements paralyze.lua @@ -0,0 +1,32 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_STONES) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.50, 0, -0.75, 0) +combat:addCondition(condition) + +arr = { +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +} + +local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lord of the elements skill reducer.lua b/data/spells/scripts/monster/lord of the elements skill reducer.lua new file mode 100644 index 00000000000..4bc78ef2e74 --- /dev/null +++ b/data/spells/scripts/monster/lord of the elements skill reducer.lua @@ -0,0 +1,36 @@ +local combat = {} + +for i = 65, 85 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 10000) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + + arr = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(65, 85)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lord of the elements soulfire.lua b/data/spells/scripts/monster/lord of the elements soulfire.lua new file mode 100644 index 00000000000..bc7a5f030e9 --- /dev/null +++ b/data/spells/scripts/monster/lord of the elements soulfire.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREATTACK) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FLAMMINGARROW) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(50, 9000, -10) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lord of the elements summon.lua b/data/spells/scripts/monster/lord of the elements summon.lua new file mode 100644 index 00000000000..13f578d9ad2 --- /dev/null +++ b/data/spells/scripts/monster/lord of the elements summon.lua @@ -0,0 +1,43 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_TELEPORT) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + for i = 1, maxsummons - #summoncount do + + if creature:getOutfit().lookType == 11 then + local mid = Game.createMonster("roaring water elemental", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + elseif creature:getOutfit().lookType == 285 then + local mid = Game.createMonster("jagged earth elemental", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + elseif creature:getOutfit().lookType == 290 then + local mid = Game.createMonster("overcharged energy elemental", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + elseif creature:getOutfit().lookType == 243 then + local mid = Game.createMonster("blistering fire elemental", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + end +return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lost berserker skill reducer.lua b/data/spells/scripts/monster/lost berserker skill reducer.lua new file mode 100644 index 00000000000..fc0685cdc5b --- /dev/null +++ b/data/spells/scripts/monster/lost berserker skill reducer.lua @@ -0,0 +1,18 @@ +local combat = {} + +for i = 15, 55 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 7000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE1X1) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(15, 55)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lost soul paralyze.lua b/data/spells/scripts/monster/lost soul paralyze.lua new file mode 100644 index 00000000000..1dcf45c5fe7 --- /dev/null +++ b/data/spells/scripts/monster/lost soul paralyze.lua @@ -0,0 +1,31 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.6, 0, -0.75, 0) + combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/lost thrower skill reducer.lua b/data/spells/scripts/monster/lost thrower skill reducer.lua new file mode 100644 index 00000000000..7425f9a422d --- /dev/null +++ b/data/spells/scripts/monster/lost thrower skill reducer.lua @@ -0,0 +1,18 @@ +local combat = {} + +for i = 20, 60 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 8000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE1X1) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(20, 60)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/madareth pillar skill reducer.lua b/data/spells/scripts/monster/madareth pillar skill reducer.lua new file mode 100644 index 00000000000..f57cc282438 --- /dev/null +++ b/data/spells/scripts/monster/madareth pillar skill reducer.lua @@ -0,0 +1,24 @@ +local combat = {} + +for i = 5, 10 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POFF) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 15000) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + + local condition2 = Condition(CONDITION_PARALYZE) + condition2:setParameter(CONDITION_PARAM_TICKS, 20000) + condition2:setFormula(-0.7, 0, -0.9, 0) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat[i]:setArea(area) + combat[i]:addCondition(condition) + combat[i]:addCondition(condition2) +end + +function onCastSpell(creature, var) + return combat[math.random(5, 10)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/madareth skill reducer.lua b/data/spells/scripts/monster/madareth skill reducer.lua new file mode 100644 index 00000000000..ad4f968f713 --- /dev/null +++ b/data/spells/scripts/monster/madareth skill reducer.lua @@ -0,0 +1,31 @@ +local combat = {} + +for i = 20, 40 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POFF) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + + arr = { + {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + + local area = createCombatArea(arr) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(20, 40)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/magic pillar summon.lua b/data/spells/scripts/monster/magic pillar summon.lua new file mode 100644 index 00000000000..0bb131ff494 --- /dev/null +++ b/data/spells/scripts/monster/magic pillar summon.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + +local maxsummons = 3 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 3 then + mid = Game.createMonster("Demon2", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/magma crawler skill reducer.lua b/data/spells/scripts/monster/magma crawler skill reducer.lua new file mode 100644 index 00000000000..6f57dc4c710 --- /dev/null +++ b/data/spells/scripts/monster/magma crawler skill reducer.lua @@ -0,0 +1,19 @@ +local combat = {} + +for i = 15, 55 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 7000) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE1X1) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(15, 55)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/magma crawler soulfire 2.lua b/data/spells/scripts/monster/magma crawler soulfire 2.lua new file mode 100644 index 00000000000..2bac7cd9730 --- /dev/null +++ b/data/spells/scripts/monster/magma crawler soulfire 2.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(20, 9000, -10) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/magma crawler soulfire.lua b/data/spells/scripts/monster/magma crawler soulfire.lua new file mode 100644 index 00000000000..45fc009e6f2 --- /dev/null +++ b/data/spells/scripts/monster/magma crawler soulfire.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONHIT) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(20, 9000, -10) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/magma crawler wave.lua b/data/spells/scripts/monster/magma crawler wave.lua new file mode 100644 index 00000000000..02403074631 --- /dev/null +++ b/data/spells/scripts/monster/magma crawler wave.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREATTACK) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/mahrdis soulfire.lua b/data/spells/scripts/monster/mahrdis soulfire.lua new file mode 100644 index 00000000000..a9f981462b1 --- /dev/null +++ b/data/spells/scripts/monster/mahrdis soulfire.lua @@ -0,0 +1,24 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONAREA) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(50, 9000, -10) + +local area = createCombatArea({ + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0} +}) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/mamma longlegs paralyze.lua b/data/spells/scripts/monster/mamma longlegs paralyze.lua new file mode 100644 index 00000000000..af5af557d30 --- /dev/null +++ b/data/spells/scripts/monster/mamma longlegs paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POISONAREA) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 25000) + condition:setFormula(-0.5, 0, -0.8, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/man in the cave summon.lua b/data/spells/scripts/monster/man in the cave summon.lua new file mode 100644 index 00000000000..20defe273b5 --- /dev/null +++ b/data/spells/scripts/monster/man in the cave summon.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GIFT_WRAPS) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + mid = Game.createMonster("Monk", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/massive energy elemental electrify.lua b/data/spells/scripts/monster/massive energy elemental electrify.lua new file mode 100644 index 00000000000..64ccb085718 --- /dev/null +++ b/data/spells/scripts/monster/massive energy elemental electrify.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BLOCKHIT) + +local condition = Condition(CONDITION_ENERGY) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(10, 10000, -25) + +local area = createCombatArea(AREA_CIRCLE3X3) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/massive fire elemental soulfire.lua b/data/spells/scripts/monster/massive fire elemental soulfire.lua new file mode 100644 index 00000000000..8e0befd4301 --- /dev/null +++ b/data/spells/scripts/monster/massive fire elemental soulfire.lua @@ -0,0 +1,31 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(20, 9000, -10) + +arr = { +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +} + +local area = createCombatArea(arr) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/mawhawk summon.lua b/data/spells/scripts/monster/mawhawk summon.lua new file mode 100644 index 00000000000..a524e3d8107 --- /dev/null +++ b/data/spells/scripts/monster/mawhawk summon.lua @@ -0,0 +1,23 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BLOCKHIT) + +local area = createCombatArea(AREA_CIRCLE1X1) +combat:setArea(area) + +local maxsummons = 4 + +function onCastSpell(creature, var) +creature:say("Watch my maws!", TALKTYPE_ORANGE_1) + local summoncount = creature:getSummons() + if #summoncount < 4 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Guzzlemaw", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/mawhawk ue.lua b/data/spells/scripts/monster/mawhawk ue.lua new file mode 100644 index 00000000000..471f78f26a9 --- /dev/null +++ b/data/spells/scripts/monster/mawhawk ue.lua @@ -0,0 +1,89 @@ +local vocation = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID, + VOCATION.CLIENT_ID.PALADIN, + VOCATION.CLIENT_ID.KNIGHT +} + +local condition = Condition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) +condition:setParameter(CONDITION_PARAM_SUBID, 88888) +condition:setParameter(CONDITION_PARAM_TICKS, 10 * 60 * 1000) +condition:setParameter(CONDITION_PARAM_HEALTHGAIN, 0.01) +condition:setParameter(CONDITION_PARAM_HEALTHTICKS, 10 * 60 * 1000) + +local area = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +} + +local createArea = createCombatArea(area) + +local combat = Combat() +combat:setArea(createArea) + +function onTargetTile(creature, pos) + local creatureTable = {} + local n, i = Tile({x=pos.x, y=pos.y, z=pos.z}).creatures, 1 + if n ~= 0 then + local v = getThingfromPos({x=pos.x, y=pos.y, z=pos.z, stackpos=i}).uid + while v ~= 0 do + if isCreature(v) == true then + table.insert(creatureTable, v) + if n == #creatureTable then + break + end + end + i = i + 1 + v = getThingfromPos({x=pos.x, y=pos.y, z=pos.z, stackpos=i}).uid + end + end + if #creatureTable ~= nil and #creatureTable > 0 then + for r = 1, #creatureTable do + if creatureTable[r] ~= creature then + local min = 1500 + local max = 1700 + local player = Player(creatureTable[r]) + + if isPlayer(creatureTable[r]) == true and table.contains(vocation, player:getVocation():getClientId()) then + doTargetCombatHealth(creature, creatureTable[r], COMBAT_FIREDAMAGE, -min, -max, CONST_ME_NONE) + elseif isMonster(creatureTable[r]) == true then + doTargetCombatHealth(creature, creatureTable[r], COMBAT_FIREDAMAGE, -min, -max, CONST_ME_NONE) + end + end + end + end + pos:sendMagicEffect(CONST_ME_FIREAREA) + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +local function delayedCastSpell(cid, var) + local creature = Creature(cid) + if not creature then + return + end + return combat:execute(creature, positionToVariant(creature:getPosition())) +end + +function onCastSpell(creature, var) + if creature:getHealth() < creature:getMaxHealth() * 0.1 and not creature:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, 88888) then + creature:addCondition(condition) + addEvent(delayedCastSpell, 5000, creature:getId(), var) + creature:say("Better flee now.", TALKTYPE_ORANGE_1) + else + return + end + return true +end diff --git a/data/spells/scripts/monster/maxxen teleport.lua b/data/spells/scripts/monster/maxxen teleport.lua new file mode 100644 index 00000000000..c7f6dc24c8f --- /dev/null +++ b/data/spells/scripts/monster/maxxen teleport.lua @@ -0,0 +1,6 @@ +function onCastSpell(creature, var) + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + creature:teleportTo(Position(math.random(33704, 33718), math.random(32040, 32053), 15)) + creature:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return +end diff --git a/data/spells/scripts/monster/mazoran fire.lua b/data/spells/scripts/monster/mazoran fire.lua new file mode 100644 index 00000000000..7657a2f8f25 --- /dev/null +++ b/data/spells/scripts/monster/mazoran fire.lua @@ -0,0 +1,956 @@ +local Montains = {4468, 4469, 4470, 4471, 4472, 4473, 4474, 4475, 4476, 4477, 4478, 4479, 1387} + +local tiles = {9068, 9069, 9070, 9071, 9072, 9073} +local itemsRoom = { + {itemid = 23868, position = Position(33589,32691, 14)}, + {itemid = 23868, position = Position(33588,32686, 14)}, + {itemid = 23868, position = Position(33583,32699, 14)}, + {itemid = 23868, position = Position(33579,32691, 14)}, + {itemid = 23868, position = Position(33576,32685, 14)}, + {itemid = 23868, position = Position(33589,32695, 14)}, + {itemid = 23868, position = Position(33588,32692, 14)}, + {itemid = 23868, position = Position(33588,32695, 14)}, + {itemid = 23868, position = Position(33586,32692, 14)}, + {itemid = 23868, position = Position(33590,32696, 14)}, + {itemid = 23868, position = Position(33572,32690, 14)}, + {itemid = 23868, position = Position(33594,32688, 14)}, + {itemid = 23868, position = Position(33572,32690, 14)}, + {itemid = 23868, position = Position(33574,32690, 14)}, + {itemid = 23868, position = Position(33582,32687, 14)}, + {itemid = 23868, position = Position(33593,32693, 14)}, + {itemid = 23867, position = Position(33592,32689, 14)}, + {itemid = 23867, position = Position(33578,32689, 14)}, + {itemid = 23867, position = Position(33576,32686, 14)}, + {itemid = 23867, position = Position(33579,32682, 14)}, + {itemid = 23867, position = Position(33580,32695, 14)}, + {itemid = 23867, position = Position(33583,32687, 14)}, + {itemid = 23867, position = Position(33583,32698, 14)}, + {itemid = 23867, position = Position(33583,32689, 14)}, + {itemid = 23867, position = Position(33575,32685, 14)}, + {itemid = 23867, position = Position(33582,32682, 14)}, + {itemid = 23866, position = Position(33587,32690, 14)}, + {itemid = 23866, position = Position(33575,32689, 14)}, + {itemid = 23866, position = Position(33578,32693, 14)}, + {itemid = 23866, position = Position(33587,32688, 14)}, + {itemid = 23866, position = Position(33579,32687, 14)}, + {itemid = 23866, position = Position(33594,32695, 14)}, + {itemid = 23866, position = Position(33585,32694, 14)}, + {itemid = 23866, position = Position(33582,32686, 14)}, + {itemid = 23866, position = Position(33583,32688, 14)}, + {itemid = 23866, position = Position(33592,32686, 14)}, + {itemid = 23866, position = Position(33580,32692, 14)}, + {itemid = 23866, position = Position(33574,32685, 14)}, + {itemid = 23865, position = Position(33581,32692, 14)}, + {itemid = 23865, position = Position(33581,32686, 14)}, + {itemid = 23865, position = Position(33587,32692, 14)}, + {itemid = 23865, position = Position(33579,32685, 14)}, + {itemid = 23865, position = Position(33593,32686, 14)}, + {itemid = 23865, position = Position(33586,32687, 14)}, + {itemid = 23865, position = Position(33584,32696, 14)}, + {itemid = 23865, position = Position(33581,32680, 14)}, + {itemid = 23865, position = Position(33585,32696, 14)}, + {itemid = 23865, position = Position(33581,32681, 14)}, + {itemid = 23865, position = Position(33591,32684, 14)}, + {itemid = 23865, position = Position(33579,32681, 14)}, + {itemid = 23865, position = Position(33588,32687, 14)}, + {itemid = 23865, position = Position(33583,32690, 14)}, + {itemid = 23864, position = Position(33591,32688, 14)}, + {itemid = 23864, position = Position(33578,32692, 14)}, + {itemid = 23864, position = Position(33587,32689, 14)}, + {itemid = 23864, position = Position(33588,32684, 14)}, + {itemid = 23864, position = Position(33576,32687, 14)}, + {itemid = 23864, position = Position(33577,32692, 14)}, + {itemid = 23864, position = Position(33580,32686, 14)}, + {itemid = 23864, position = Position(33592,32688, 14)}, + {itemid = 23864, position = Position(33593,32683, 14)}, + {itemid = 23863, position = Position(33593,32694, 14)}, + {itemid = 23863, position = Position(33585,32688, 14)}, + {itemid = 23863, position = Position(33592,32691, 14)}, + {itemid = 23863, position = Position(33591,32692, 14)}, + {itemid = 23863, position = Position(33583,32684, 14)}, + {itemid = 23863, position = Position(33594,32694, 14)}, + {itemid = 23863, position = Position(33589,32692, 14)}, + {itemid = 23863, position = Position(33594,32687, 14)}, + {itemid = 23863, position = Position(33578,32685, 14)}, + {itemid = 23862, position = Position(33582,32683, 14)}, + {itemid = 23862, position = Position(33579,32690, 14)}, + {itemid = 23862, position = Position(33591,32697, 14)}, + {itemid = 23862, position = Position(33592,32690, 14)}, + {itemid = 23862, position = Position(33575,32688, 14)}, + {itemid = 23862, position = Position(33585,32695, 14)}, + {itemid = 23862, position = Position(33593,32684, 14)}, + {itemid = 23861, position = Position(33592,32684, 14)}, + {itemid = 23861, position = Position(33592,32692, 14)}, + {itemid = 23861, position = Position(33585,32690, 14)}, + {itemid = 23861, position = Position(33576,32692, 14)}, + {itemid = 23861, position = Position(33576,32688, 14)}, + {itemid = 23861, position = Position(33573,32690, 14)}, + {itemid = 23861, position = Position(33584,32682, 14)}, + {itemid = 23861, position = Position(33589,32684, 14)}, + {itemid = 23861, position = Position(33591,32696, 14)}, + {itemid = 23861, position = Position(33578,32688, 14)}, + {itemid = 23861, position = Position(33579,32696, 14)}, + {itemid = 23861, position = Position(33587,32691, 14)}, + {itemid = 23861, position = Position(33579,32683, 14)}, + {itemid = 23861, position = Position(33574,32691, 14)}, + {itemid = 23861, position = Position(33590,32688, 14)}, + {itemid = 23861, position = Position(33589,32688, 14)}, + {itemid = 23860, position = Position(33585,32687, 14)}, + {itemid = 23860, position = Position(33586,32690, 14)}, + {itemid = 23860, position = Position(33588,32696, 14)}, + {itemid = 23860, position = Position(33579,32688, 14)}, + {itemid = 23860, position = Position(33594,32690, 14)}, + {itemid = 23860, position = Position(33579,32692, 14)}, + {itemid = 23860, position = Position(33579,32695, 14)}, + {itemid = 23860, position = Position(33593,32690, 14)}, + {itemid = 23860, position = Position(33590,32691, 14)}, + {itemid = 23860, position = Position(33589,32693, 14)}, + {itemid = 23860, position = Position(33588,32690, 14)}, + {itemid = 23860, position = Position(33586,32693, 14)}, + {itemid = 23860, position = Position(33593,32687, 14)}, + {itemid = 23860, position = Position(33587,32686, 14)}, + {itemid = 23860, position = Position(33578,32684, 14)}, + {itemid = 23860, position = Position(33588,32685, 14)}, + {itemid = 23859, position = Position(33583,32700, 14)}, + {itemid = 23859, position = Position(33591,32686, 14)}, + {itemid = 23859, position = Position(33582,32684, 14)}, + {itemid = 23859, position = Position(33588,32688, 14)}, + {itemid = 23859, position = Position(33579,32686, 14)}, + {itemid = 23859, position = Position(33578,32683, 14)}, + {itemid = 23858, position = Position(33578,32694, 14)}, + {itemid = 23858, position = Position(33583,32696, 14)}, + {itemid = 23858, position = Position(33585,32693, 14)}, + {itemid = 23858, position = Position(33589,32690, 14)}, + {itemid = 23858, position = Position(33582,32692, 14)}, + {itemid = 23858, position = Position(33585,32689, 14)}, + {itemid = 23858, position = Position(33585,32680, 14)}, + {itemid = 23858, position = Position(33586,32686, 14)}, + {itemid = 23858, position = Position(33585,32681, 14)}, + {itemid = 23857, position = Position(33590,32695, 14)}, + {itemid = 23857, position = Position(33575,32691, 14)}, + {itemid = 23857, position = Position(33591,32698, 14)}, + {itemid = 23857, position = Position(33578,32695, 14)}, + {itemid = 23857, position = Position(33592,32685, 14)}, + {itemid = 23857, position = Position(33583,32685, 14)}, + {itemid = 23857, position = Position(33576,32691, 14)}, + {itemid = 23857, position = Position(33583,32697, 14)}, + {itemid = 23857, position = Position(33590,32684, 14)}, + {itemid = 23857, position = Position(33584,32689, 14)}, + {itemid = 23857, position = Position(33582,32681, 14)}, + {itemid = 23857, position = Position(33585,32682, 14)}, + {itemid = 23857, position = Position(33584,32683, 14)}, + {itemid = 9073, position = Position(33584,32688, 14)}, + {itemid = 9073, position = Position(33572,32688, 14)}, + {itemid = 9073, position = Position(33586,32700, 14)}, + {itemid = 9073, position = Position(33580,32698, 14)}, + {itemid = 9073, position = Position(33590,32697, 14)}, + {itemid = 9073, position = Position(33581,32693, 14)}, + {itemid = 9073, position = Position(33581,32690, 14)}, + {itemid = 9073, position = Position(33591,32682, 14)}, + {itemid = 9073, position = Position(33587,32680, 14)}, + {itemid = 9073, position = Position(33572,32692, 14)}, + {itemid = 9073, position = Position(33586,32695, 14)}, + {itemid = 9073, position = Position(33583,32695, 14)}, + {itemid = 9073, position = Position(33587,32695, 14)}, + {itemid = 9073, position = Position(33587,32696, 14)}, + {itemid = 9073, position = Position(33581,32700, 14)}, + {itemid = 9073, position = Position(33573,32686, 14)}, + {itemid = 9073, position = Position(33583,32681, 14)}, + {itemid = 9073, position = Position(33597,32690, 14)}, + {itemid = 9073, position = Position(33582,32695, 14)}, + {itemid = 9073, position = Position(33591,32699, 14)}, + {itemid = 9073, position = Position(33581,32689, 14)}, + {itemid = 9073, position = Position(33581,32687, 14)}, + {itemid = 9073, position = Position(33572,32692, 14)}, + {itemid = 9073, position = Position(33574,32689, 14)}, + {itemid = 9073, position = Position(33594,32683, 14)}, + {itemid = 9073, position = Position(33573,32694, 14)}, + {itemid = 9073, position = Position(33579,32698, 14)}, + {itemid = 9073, position = Position(33593,32697, 14)}, + {itemid = 9073, position = Position(33580,32687, 14)}, + {itemid = 9073, position = Position(33580,32690, 14)}, + {itemid = 9073, position = Position(33580,32689, 14)}, + {itemid = 9073, position = Position(33597,32687, 14)}, + {itemid = 9073, position = Position(33593,32682, 14)}, + {itemid = 9073, position = Position(33591,32690, 14)}, + {itemid = 9073, position = Position(33583,32692, 14)}, + {itemid = 9073, position = Position(33586,32683, 14)}, + {itemid = 9073, position = Position(33584,32695, 14)}, + {itemid = 9073, position = Position(33573,32693, 14)}, + {itemid = 9073, position = Position(33579,32689, 14)}, + {itemid = 9073, position = Position(33584,32693, 14)}, + {itemid = 9073, position = Position(33592,32693, 14)}, + {itemid = 9073, position = Position(33572,32688, 14)}, + {itemid = 9073, position = Position(33573,32686, 14)}, + {itemid = 9073, position = Position(33584,32697, 14)}, + {itemid = 9073, position = Position(33583,32694, 14)}, + {itemid = 9073, position = Position(33586,32685, 14)}, + {itemid = 9073, position = Position(33587,32700, 14)}, + {itemid = 9073, position = Position(33596,32689, 14)}, + {itemid = 9073, position = Position(33576,32697, 14)}, + {itemid = 9073, position = Position(33589,32697, 14)}, + {itemid = 9073, position = Position(33589,32696, 14)}, + {itemid = 9073, position = Position(33574,32695, 14)}, + {itemid = 9073, position = Position(33589,32698, 14)}, + {itemid = 9073, position = Position(33593,32689, 14)}, + {itemid = 9073, position = Position(33589,32699, 14)}, + {itemid = 9073, position = Position(33590,32681, 14)}, + {itemid = 9073, position = Position(33595,32693, 14)}, + {itemid = 9073, position = Position(33591,32694, 14)}, + {itemid = 9073, position = Position(33576,32695, 14)}, + {itemid = 9073, position = Position(33576,32696, 14)}, + {itemid = 9073, position = Position(33595,32691, 14)}, + {itemid = 9073, position = Position(33595,32687, 14)}, + {itemid = 9073, position = Position(33577,32696, 14)}, + {itemid = 9073, position = Position(33577,32698, 14)}, + {itemid = 9073, position = Position(33577,32697, 14)}, + {itemid = 9073, position = Position(33575,32696, 14)}, + {itemid = 9073, position = Position(33577,32689, 14)}, + {itemid = 9073, position = Position(33596,32685, 14)}, + {itemid = 9073, position = Position(33575,32683, 14)}, + {itemid = 9073, position = Position(33575,32694, 14)}, + {itemid = 9073, position = Position(33593,32688, 14)}, + {itemid = 9073, position = Position(33590,32694, 14)}, + {itemid = 9073, position = Position(33595,32696, 14)}, + {itemid = 9073, position = Position(33575,32686, 14)}, + {itemid = 9073, position = Position(33588,32682, 14)}, + {itemid = 9073, position = Position(33573,32692, 14)}, + {itemid = 9073, position = Position(33596,32691, 14)}, + {itemid = 9072, position = Position(33596,32690, 14)}, + {itemid = 9072, position = Position(33589,32689, 14)}, + {itemid = 9072, position = Position(33578,32690, 14)}, + {itemid = 9072, position = Position(33581,32691, 14)}, + {itemid = 9072, position = Position(33585,32697, 14)}, + {itemid = 9072, position = Position(33574,32692, 14)}, + {itemid = 9072, position = Position(33574,32686, 14)}, + {itemid = 9072, position = Position(33577,32682, 14)}, + {itemid = 9072, position = Position(33583,32686, 14)}, + {itemid = 9072, position = Position(33587,32683, 14)}, + {itemid = 9072, position = Position(33586,32698, 14)}, + {itemid = 9072, position = Position(33590,32680, 14)}, + {itemid = 9072, position = Position(33575,32692, 14)}, + {itemid = 9072, position = Position(33588,32689, 14)}, + {itemid = 9072, position = Position(33578,32682, 14)}, + {itemid = 9071, position = Position(33591,32685, 14)}, + {itemid = 9071, position = Position(33589,32687, 14)}, + {itemid = 9071, position = Position(33594,32692, 14)}, + {itemid = 9071, position = Position(33595,32690, 14)}, + {itemid = 9071, position = Position(33576,32694, 14)}, + {itemid = 9071, position = Position(33585,32685, 14)}, + {itemid = 9071, position = Position(33597,32691, 14)}, + {itemid = 9071, position = Position(33585,32679, 14)}, + {itemid = 9071, position = Position(33581,32682, 14)}, + {itemid = 9071, position = Position(33590,32689, 14)}, + {itemid = 9071, position = Position(33585,32683, 14)}, + {itemid = 9071, position = Position(33582,32694, 14)}, + {itemid = 9071, position = Position(33590,32698, 14)}, + {itemid = 9071, position = Position(33587,32699, 14)}, + {itemid = 9071, position = Position(33578,32691, 14)}, + {itemid = 9071, position = Position(33586,32694, 14)}, + {itemid = 9070, position = Position(33586,32691, 14)}, + {itemid = 9070, position = Position(33581,32688, 14)}, + {itemid = 9070, position = Position(33590,32682, 14)}, + {itemid = 9070, position = Position(33588,32699, 14)}, + {itemid = 9070, position = Position(33588,32697, 14)}, + {itemid = 9070, position = Position(33590,32699, 14)}, + {itemid = 9070, position = Position(33586,32697, 14)}, + {itemid = 9070, position = Position(33584,32681, 14)}, + {itemid = 9070, position = Position(33576,32682, 14)}, + {itemid = 9070, position = Position(33587,32684, 14)}, + {itemid = 9070, position = Position(33581,32696, 14)}, + {itemid = 9070, position = Position(33585,32692, 14)}, + {itemid = 9070, position = Position(33584,32691, 14)}, + {itemid = 9070, position = Position(33587,32685, 14)}, + {itemid = 9070, position = Position(33584,32692, 14)}, + {itemid = 9070, position = Position(33590,32693, 14)}, + {itemid = 9070, position = Position(33576,32684, 14)}, + {itemid = 9070, position = Position(33597,32692, 14)}, + {itemid = 9070, position = Position(33577,32688, 14)}, + {itemid = 9070, position = Position(33588,32680, 14)}, + {itemid = 9069, position = Position(33593,32696, 14)}, + {itemid = 9069, position = Position(33574,32688, 14)}, + {itemid = 9069, position = Position(33594,32686, 14)}, + {itemid = 9069, position = Position(33579,32699, 14)}, + {itemid = 9069, position = Position(33574,32693, 14)}, + {itemid = 9069, position = Position(33584,32690, 14)}, + {itemid = 9069, position = Position(33584,32699, 14)}, + {itemid = 9069, position = Position(33596,32687, 14)}, + {itemid = 9069, position = Position(33592,32682, 14)}, + {itemid = 9069, position = Position(33575,32687, 14)}, + {itemid = 9069, position = Position(33587,32697, 14)}, + {itemid = 9069, position = Position(33592,32695, 14)}, + {itemid = 9069, position = Position(33591,32681, 14)}, + {itemid = 9069, position = Position(33580,32696, 14)}, + {itemid = 9069, position = Position(33577,32694, 14)}, + {itemid = 9069, position = Position(33582,32685, 14)}, + {itemid = 9069, position = Position(33582,32691, 14)}, + {itemid = 9069, position = Position(33578,32696, 14)}, + {itemid = 9069, position = Position(33585,32684, 14)}, + {itemid = 9069, position = Position(33590,32690, 14)}, + {itemid = 9068, position = Position(33583,32682, 14)}, + {itemid = 9068, position = Position(33584,32685, 14)}, + {itemid = 9068, position = Position(33591,32687, 14)}, + {itemid = 9068, position = Position(33584,32684, 14)}, + {itemid = 9068, position = Position(33584,32686, 14)}, + {itemid = 9068, position = Position(33587,32694, 14)}, + {itemid = 9068, position = Position(33584,32687, 14)}, + {itemid = 9068, position = Position(33590,32692, 14)}, + {itemid = 9068, position = Position(33587,32698, 14)}, + {itemid = 9068, position = Position(33592,32698, 14)}, + {itemid = 9068, position = Position(33590,32683, 14)}, + {itemid = 9068, position = Position(33583,32683, 14)}, + {itemid = 9068, position = Position(33588,32683, 14)}, + {itemid = 9068, position = Position(33583,32680, 14)}, + {itemid = 9068, position = Position(33592,32697, 14)}, + {itemid = 9068, position = Position(33583,32693, 14)}, + {itemid = 9068, position = Position(33590,32686, 14)}, + {itemid = 9068, position = Position(33587,32687, 14)}, + {itemid = 9068, position = Position(33590,32687, 14)}, + {itemid = 9068, position = Position(33583,32691, 14)}, + {itemid = 9068, position = Position(33590,32685, 14)}, + {itemid = 9068, position = Position(33587,32693, 14)}, + {itemid = 9068, position = Position(33584,32680, 14)}, + {itemid = 9068, position = Position(33588,32681, 14)}, + {itemid = 9068, position = Position(33584,32679, 14)}, + {itemid = 9068, position = Position(33594,32685, 14)}, + {itemid = 9068, position = Position(33592,32696, 14)}, + {itemid = 9068, position = Position(33586,32681, 14)}, + {itemid = 9068, position = Position(33587,32682, 14)}, + {itemid = 9068, position = Position(33589,32686, 14)}, + {itemid = 9068, position = Position(33589,32685, 14)}, + {itemid = 9068, position = Position(33589,32683, 14)}, + {itemid = 9068, position = Position(33589,32682, 14)}, + {itemid = 9068, position = Position(33585,32691, 14)}, + {itemid = 9068, position = Position(33588,32698, 14)}, + {itemid = 9068, position = Position(33593,32695, 14)}, + {itemid = 9068, position = Position(33593,32685, 14)}, + {itemid = 9068, position = Position(33591,32691, 14)}, + {itemid = 9068, position = Position(33586,32688, 14)}, + {itemid = 9068, position = Position(33586,32684, 14)}, + {itemid = 9068, position = Position(33593,32698, 14)}, + {itemid = 9068, position = Position(33586,32679, 14)}, + {itemid = 9068, position = Position(33589,32680, 14)}, + {itemid = 9068, position = Position(33586,32680, 14)}, + {itemid = 9068, position = Position(33585,32698, 14)}, + {itemid = 9068, position = Position(33589,32681, 14)}, + {itemid = 9068, position = Position(33588,32700, 14)}, + {itemid = 9068, position = Position(33585,32700, 14)}, + {itemid = 9068, position = Position(33591,32683, 14)}, + {itemid = 9068, position = Position(33585,32699, 14)}, + {itemid = 9068, position = Position(33591,32689, 14)}, + {itemid = 9068, position = Position(33585,32686, 14)}, + {itemid = 9068, position = Position(33592,32687, 14)}, + {itemid = 9068, position = Position(33584,32694, 14)}, + {itemid = 9068, position = Position(33588,32691, 14)}, + {itemid = 9068, position = Position(33592,32694, 14)}, + {itemid = 9068, position = Position(33592,32683, 14)}, + {itemid = 9068, position = Position(33593,32692, 14)}, + {itemid = 9068, position = Position(33591,32693, 14)}, + {itemid = 9068, position = Position(33589,32700, 14)}, + {itemid = 9068, position = Position(33587,32681, 14)}, + {itemid = 9068, position = Position(33586,32682, 14)}, + {itemid = 9068, position = Position(33586,32689, 14)}, + {itemid = 9068, position = Position(33586,32699, 14)}, + {itemid = 9068, position = Position(33584,32698, 14)}, + {itemid = 9068, position = Position(33588,32694, 14)}, + {itemid = 9068, position = Position(33593,32691, 14)}, + {itemid = 9068, position = Position(33591,32695, 14)}, + {itemid = 9068, position = Position(33588,32693, 14)}, + {itemid = 9068, position = Position(33589,32694, 14)}, + {itemid = 9068, position = Position(33594,32684, 14)}, + {itemid = 9068, position = Position(33584,32700, 14)}, + {itemid = 9068, position = Position(33586,32696, 14)}, + {itemid = 9068, position = Position(33583,32679, 14)}, + {itemid = 9068, position = Position(33597,32693, 14)}, + {itemid = 9068, position = Position(33582,32700, 14)}, + {itemid = 9068, position = Position(33581,32697, 14)}, + {itemid = 9068, position = Position(33581,32695, 14)}, + {itemid = 9068, position = Position(33581,32698, 14)}, + {itemid = 9068, position = Position(33580,32684, 14)}, + {itemid = 9068, position = Position(33581,32699, 14)}, + {itemid = 9068, position = Position(33577,32691, 14)}, + {itemid = 9068, position = Position(33581,32694, 14)}, + {itemid = 9068, position = Position(33577,32690, 14)}, + {itemid = 9068, position = Position(33595,32689, 14)}, + {itemid = 9068, position = Position(33580,32685, 14)}, + {itemid = 9068, position = Position(33594,32691, 14)}, + {itemid = 9068, position = Position(33575,32684, 14)}, + {itemid = 9068, position = Position(33574,32694, 14)}, + {itemid = 9068, position = Position(33580,32681, 14)}, + {itemid = 9068, position = Position(33580,32680, 14)}, + {itemid = 9068, position = Position(33574,32687, 14)}, + {itemid = 9068, position = Position(33577,32693, 14)}, + {itemid = 9068, position = Position(33582,32680, 14)}, + {itemid = 9068, position = Position(33582,32679, 14)}, + {itemid = 9068, position = Position(33594,32689, 14)}, + {itemid = 9068, position = Position(33580,32683, 14)}, + {itemid = 9068, position = Position(33580,32682, 14)}, + {itemid = 9068, position = Position(33580,32693, 14)}, + {itemid = 9068, position = Position(33577,32687, 14)}, + {itemid = 9068, position = Position(33581,32685, 14)}, + {itemid = 9068, position = Position(33576,32689, 14)}, + {itemid = 9068, position = Position(33576,32690, 14)}, + {itemid = 9068, position = Position(33580,32691, 14)}, + {itemid = 9068, position = Position(33580,32688, 14)}, + {itemid = 9068, position = Position(33577,32684, 14)}, + {itemid = 9068, position = Position(33580,32699, 14)}, + {itemid = 9068, position = Position(33595,32692, 14)}, + {itemid = 9068, position = Position(33577,32683, 14)}, + {itemid = 9068, position = Position(33580,32697, 14)}, + {itemid = 9068, position = Position(33576,32693, 14)}, + {itemid = 9068, position = Position(33577,32686, 14)}, + {itemid = 9068, position = Position(33581,32679, 14)}, + {itemid = 9068, position = Position(33595,32694, 14)}, + {itemid = 9068, position = Position(33581,32684, 14)}, + {itemid = 9068, position = Position(33575,32693, 14)}, + {itemid = 9068, position = Position(33575,32690, 14)}, + {itemid = 9068, position = Position(33576,32683, 14)}, + {itemid = 9068, position = Position(33581,32683, 14)}, + {itemid = 9068, position = Position(33577,32685, 14)}, + {itemid = 9068, position = Position(33595,32695, 14)}, + {itemid = 9068, position = Position(33594,32693, 14)}, + {itemid = 9068, position = Position(33575,32695, 14)}, + {itemid = 9068, position = Position(33595,32688, 14)}, + {itemid = 9068, position = Position(33577,32695, 14)}, + {itemid = 9068, position = Position(33574,32684, 14)}, + {itemid = 9068, position = Position(33582,32690, 14)}, + {itemid = 9068, position = Position(33579,32684, 14)}, + {itemid = 9068, position = Position(33573,32687, 14)}, + {itemid = 9068, position = Position(33597,32688, 14)}, + {itemid = 9068, position = Position(33578,32698, 14)}, + {itemid = 9068, position = Position(33582,32689, 14)}, + {itemid = 9068, position = Position(33573,32688, 14)}, + {itemid = 9068, position = Position(33596,32695, 14)}, + {itemid = 9068, position = Position(33578,32697, 14)}, + {itemid = 9068, position = Position(33596,32686, 14)}, + {itemid = 9068, position = Position(33597,32689, 14)}, + {itemid = 9068, position = Position(33579,32680, 14)}, + {itemid = 9068, position = Position(33582,32698, 14)}, + {itemid = 9068, position = Position(33582,32699, 14)}, + {itemid = 9068, position = Position(33572,32689, 14)}, + {itemid = 9068, position = Position(33594,32697, 14)}, + {itemid = 9068, position = Position(33582,32697, 14)}, + {itemid = 9068, position = Position(33594,32696, 14)}, + {itemid = 9068, position = Position(33582,32696, 14)}, + {itemid = 9068, position = Position(33582,32693, 14)}, + {itemid = 9068, position = Position(33572,32691, 14)}, + {itemid = 9068, position = Position(33572,32689, 14)}, + {itemid = 9068, position = Position(33582,32688, 14)}, + {itemid = 9068, position = Position(33596,32694, 14)}, + {itemid = 9068, position = Position(33573,32688, 14)}, + {itemid = 9068, position = Position(33595,32686, 14)}, + {itemid = 9068, position = Position(33579,32693, 14)}, + {itemid = 9068, position = Position(33573,32687, 14)}, + {itemid = 9068, position = Position(33573,32689, 14)}, + {itemid = 9068, position = Position(33573,32691, 14)}, + {itemid = 9068, position = Position(33578,32681, 14)}, + {itemid = 9068, position = Position(33596,32688, 14)}, + {itemid = 9068, position = Position(33579,32697, 14)}, + {itemid = 9068, position = Position(33596,32692, 14)}, + {itemid = 9068, position = Position(33579,32694, 14)}, + {itemid = 9068, position = Position(33578,32687, 14)}, + {itemid = 9068, position = Position(33572,32691, 14)}, + {itemid = 9068, position = Position(33578,32686, 14)}, + {itemid = 9068, position = Position(33595,32684, 14)}, + {itemid = 9068, position = Position(33596,32693, 14)}, + {itemid = 9068, position = Position(33595,32685, 14)}, + {itemid = 9068, position = Position(33580,32694, 14)}, + {itemid = 7090, position = Position(33585,32688, 14)}, + {itemid = 7090, position = Position(33586,32693, 14)}, + {itemid = 7090, position = Position(33586,32687, 14)}, + {itemid = 7090, position = Position(33588,32696, 14)}, + {itemid = 7090, position = Position(33578,32689, 14)}, + {itemid = 7090, position = Position(33579,32688, 14)}, + {itemid = 7090, position = Position(33579,32683, 14)}, + {itemid = 7090, position = Position(33585,32696, 14)}, + {itemid = 7090, position = Position(33576,32688, 14)}, + {itemid = 7090, position = Position(33590,32691, 14)}, + {itemid = 7090, position = Position(33593,32684, 14)}, + {itemid = 7090, position = Position(33575,32689, 14)}, + {itemid = 7090, position = Position(33592,32692, 14)}, + {itemid = 7090, position = Position(33589,32693, 14)}, + {itemid = 7090, position = Position(33585,32682, 14)}, + {itemid = 7089, position = Position(33593,32687, 14)}, + {itemid = 7089, position = Position(33591,32698, 14)}, + {itemid = 7089, position = Position(33578,32685, 14)}, + {itemid = 7089, position = Position(33578,32695, 14)}, + {itemid = 7089, position = Position(33583,32685, 14)}, + {itemid = 7089, position = Position(33590,32696, 14)}, + {itemid = 7089, position = Position(33584,32683, 14)}, + {itemid = 7089, position = Position(33593,32694, 14)}, + {itemid = 7089, position = Position(33574,32691, 14)}, + {itemid = 7089, position = Position(33582,32684, 14)}, + {itemid = 7089, position = Position(33579,32696, 14)}, + {itemid = 7089, position = Position(33582,32687, 14)}, + {itemid = 7089, position = Position(33581,32681, 14)}, + {itemid = 7089, position = Position(33594,32688, 14)}, + {itemid = 7089, position = Position(33585,32690, 14)}, + {itemid = 7089, position = Position(33576,32692, 14)}, + {itemid = 7089, position = Position(33589,32691, 14)}, + {itemid = 7088, position = Position(33583,32687, 14)}, + {itemid = 7088, position = Position(33589,32692, 14)}, + {itemid = 7088, position = Position(33579,32685, 14)}, + {itemid = 7088, position = Position(33579,32690, 14)}, + {itemid = 7088, position = Position(33592,32688, 14)}, + {itemid = 7088, position = Position(33586,32690, 14)}, + {itemid = 7088, position = Position(33582,32686, 14)}, + {itemid = 7088, position = Position(33594,32687, 14)}, + {itemid = 7088, position = Position(33572,32692, 14)}, + {itemid = 7088, position = Position(33587,32700, 14)}, + {itemid = 7088, position = Position(33591,32696, 14)}, + {itemid = 7088, position = Position(33582,32681, 14)}, + {itemid = 7088, position = Position(33582,32692, 14)}, + {itemid = 7088, position = Position(33576,32691, 14)}, + {itemid = 7088, position = Position(33583,32684, 14)}, + {itemid = 7088, position = Position(33585,32680, 14)}, + {itemid = 7088, position = Position(33573,32693, 14)}, + {itemid = 7088, position = Position(33589,32690, 14)}, + {itemid = 7088, position = Position(33594,32694, 14)}, + {itemid = 7088, position = Position(33585,32689, 14)}, + {itemid = 7088, position = Position(33580,32695, 14)}, + {itemid = 7088, position = Position(33585,32693, 14)}, + {itemid = 7088, position = Position(33576,32685, 14)}, + {itemid = 7088, position = Position(33590,32695, 14)}, + {itemid = 7088, position = Position(33593,32686, 14)}, + {itemid = 7088, position = Position(33574,32690, 14)}, + {itemid = 7088, position = Position(33593,32683, 14)}, + {itemid = 7088, position = Position(33579,32681, 14)}, + {itemid = 7088, position = Position(33594,32690, 14)}, + {itemid = 7088, position = Position(33572,32692, 14)}, + {itemid = 7087, position = Position(33586,32700, 14)}, + {itemid = 7087, position = Position(33593,32693, 14)}, + {itemid = 7087, position = Position(33587,32688, 14)}, + {itemid = 7087, position = Position(33583,32696, 14)}, + {itemid = 7087, position = Position(33586,32692, 14)}, + {itemid = 7087, position = Position(33591,32692, 14)}, + {itemid = 7087, position = Position(33588,32695, 14)}, + {itemid = 7087, position = Position(33591,32686, 14)}, + {itemid = 7087, position = Position(33575,32688, 14)}, + {itemid = 7087, position = Position(33584,32682, 14)}, + {itemid = 7087, position = Position(33586,32686, 14)}, + {itemid = 7087, position = Position(33578,32683, 14)}, + {itemid = 7087, position = Position(33585,32687, 14)}, + {itemid = 7087, position = Position(33588,32684, 14)}, + {itemid = 7087, position = Position(33578,32688, 14)}, + {itemid = 7087, position = Position(33588,32684, 14)}, + {itemid = 7086, position = Position(33587,32690, 14)}, + {itemid = 7086, position = Position(33588,32684, 14)}, + {itemid = 7086, position = Position(33575,32688, 14)}, + {itemid = 7086, position = Position(33587,32688, 14)}, + {itemid = 7086, position = Position(33578,32688, 14)}, + {itemid = 7086, position = Position(33578,32683, 14)}, + {itemid = 7086, position = Position(33592,32684, 14)}, + {itemid = 7086, position = Position(33588,32684, 14)}, + {itemid = 7086, position = Position(33588,32695, 14)}, + {itemid = 7086, position = Position(33592,32690, 14)}, + {itemid = 7086, position = Position(33578,32692, 14)}, + {itemid = 7086, position = Position(33579,32695, 14)}, + {itemid = 7086, position = Position(33579,32686, 14)}, + {itemid = 7086, position = Position(33583,32689, 14)}, + {itemid = 7086, position = Position(33583,32696, 14)}, + {itemid = 7086, position = Position(33584,32682, 14)}, + {itemid = 7086, position = Position(33586,32686, 14)}, + {itemid = 7086, position = Position(33585,32687, 14)}, + {itemid = 7086, position = Position(33586,32692, 14)}, + {itemid = 7085, position = Position(33589,32690, 14)}, + {itemid = 7085, position = Position(33594,32687, 14)}, + {itemid = 7085, position = Position(33591,32696, 14)}, + {itemid = 7085, position = Position(33588,32686, 14)}, + {itemid = 7085, position = Position(33579,32695, 14)}, + {itemid = 7085, position = Position(33592,32684, 14)}, + {itemid = 7085, position = Position(33582,32686, 14)}, + {itemid = 7085, position = Position(33578,32692, 14)}, + {itemid = 7085, position = Position(33576,32691, 14)}, + {itemid = 7085, position = Position(33582,32681, 14)}, + {itemid = 7085, position = Position(33576,32685, 14)}, + {itemid = 7085, position = Position(33574,32690, 14)}, + {itemid = 7085, position = Position(33594,32694, 14)}, + {itemid = 7085, position = Position(33583,32684, 14)}, + {itemid = 7085, position = Position(33590,32695, 14)}, + {itemid = 7085, position = Position(33583,32687, 14)}, + {itemid = 7085, position = Position(33593,32686, 14)}, + {itemid = 7085, position = Position(33592,32688, 14)}, + {itemid = 7085, position = Position(33585,32689, 14)}, + {itemid = 7085, position = Position(33589,32692, 14)}, + {itemid = 7085, position = Position(33579,32685, 14)}, + {itemid = 7084, position = Position(33592,32690, 14)}, + {itemid = 7084, position = Position(33574,32691, 14)}, + {itemid = 7084, position = Position(33585,32690, 14)}, + {itemid = 7084, position = Position(33579,32692, 14)}, + {itemid = 7084, position = Position(33587,32692, 14)}, + {itemid = 7084, position = Position(33578,32685, 14)}, + {itemid = 7084, position = Position(33583,32689, 14)}, + {itemid = 7084, position = Position(33589,32691, 14)}, + {itemid = 7084, position = Position(33592,32686, 14)}, + {itemid = 7084, position = Position(33593,32687, 14)}, + {itemid = 7084, position = Position(33590,32696, 14)}, + {itemid = 7084, position = Position(33579,32686, 14)}, + {itemid = 7084, position = Position(33581,32681, 14)}, + {itemid = 7084, position = Position(33576,32692, 14)}, + {itemid = 7084, position = Position(33593,32694, 14)}, + {itemid = 7084, position = Position(33588,32688, 14)}, + {itemid = 7084, position = Position(33582,32687, 14)}, + {itemid = 7084, position = Position(33578,32695, 14)}, + {itemid = 7084, position = Position(33587,32690, 14)}, + {itemid = 7084, position = Position(33582,32684, 14)}, + {itemid = 7083, position = Position(33588,32688, 14)}, + {itemid = 7083, position = Position(33579,32692, 14)}, + {itemid = 7083, position = Position(33593,32684, 14)}, + {itemid = 7083, position = Position(33579,32688, 14)}, + {itemid = 7083, position = Position(33579,32683, 14)}, + {itemid = 7083, position = Position(33592,32692, 14)}, + {itemid = 7083, position = Position(33592,32686, 14)}, + {itemid = 7083, position = Position(33576,32688, 14)}, + {itemid = 7083, position = Position(33585,32696, 14)}, + {itemid = 7083, position = Position(33585,32682, 14)}, + {itemid = 7083, position = Position(33588,32686, 14)}, + {itemid = 7083, position = Position(33587,32692, 14)}, + {itemid = 7083, position = Position(33586,32687, 14)}, + {itemid = 7082, position = Position(33585,32681, 14)}, + {itemid = 7082, position = Position(33589,32693, 14)}, + {itemid = 7082, position = Position(33576,32687, 14)}, + {itemid = 7082, position = Position(33585,32688, 14)}, + {itemid = 7082, position = Position(33593,32683, 14)}, + {itemid = 7082, position = Position(33582,32683, 14)}, + {itemid = 7082, position = Position(33581,32680, 14)}, + {itemid = 7082, position = Position(33592,32690, 14)}, + {itemid = 7082, position = Position(33592,32689, 14)}, + {itemid = 7082, position = Position(33583,32690, 14)}, + {itemid = 7082, position = Position(33583,32689, 14)}, + {itemid = 7082, position = Position(33583,32688, 14)}, + {itemid = 7082, position = Position(33592,32691, 14)}, + {itemid = 7082, position = Position(33585,32680, 14)}, + {itemid = 7082, position = Position(33592,32685, 14)}, + {itemid = 7082, position = Position(33583,32697, 14)}, + {itemid = 7082, position = Position(33582,32682, 14)}, + {itemid = 7082, position = Position(33575,32689, 14)}, + {itemid = 7082, position = Position(33591,32697, 14)}, + {itemid = 7082, position = Position(33583,32700, 14)}, + {itemid = 7082, position = Position(33583,32698, 14)}, + {itemid = 7082, position = Position(33583,32699, 14)}, + {itemid = 7082, position = Position(33585,32693, 14)}, + {itemid = 7082, position = Position(33576,32686, 14)}, + {itemid = 7082, position = Position(33594,32695, 14)}, + {itemid = 7082, position = Position(33579,32691, 14)}, + {itemid = 7082, position = Position(33578,32693, 14)}, + {itemid = 7082, position = Position(33578,32694, 14)}, + {itemid = 7082, position = Position(33579,32690, 14)}, + {itemid = 7082, position = Position(33579,32687, 14)}, + {itemid = 7082, position = Position(33588,32696, 14)}, + {itemid = 7082, position = Position(33578,32684, 14)}, + {itemid = 7082, position = Position(33578,32689, 14)}, + {itemid = 7082, position = Position(33586,32693, 14)}, + {itemid = 7082, position = Position(33579,32686, 14)}, + {itemid = 7082, position = Position(33585,32695, 14)}, + {itemid = 7082, position = Position(33578,32684, 14)}, + {itemid = 7082, position = Position(33588,32687, 14)}, + {itemid = 7082, position = Position(33579,32681, 14)}, + {itemid = 7082, position = Position(33588,32685, 14)}, + {itemid = 7082, position = Position(33585,32694, 14)}, + {itemid = 7082, position = Position(33579,32682, 14)}, + {itemid = 7082, position = Position(33587,32690, 14)}, + {itemid = 7082, position = Position(33587,32689, 14)}, + {itemid = 7082, position = Position(33587,32691, 14)}, + {itemid = 7081, position = Position(33591,32684, 14)}, + {itemid = 7081, position = Position(33580,32686, 14)}, + {itemid = 7081, position = Position(33575,32685, 14)}, + {itemid = 7081, position = Position(33594,32690, 14)}, + {itemid = 7081, position = Position(33588,32692, 14)}, + {itemid = 7081, position = Position(33588,32690, 14)}, + {itemid = 7081, position = Position(33581,32692, 14)}, + {itemid = 7081, position = Position(33591,32686, 14)}, + {itemid = 7081, position = Position(33584,32689, 14)}, + {itemid = 7081, position = Position(33574,32685, 14)}, + {itemid = 7081, position = Position(33586,32690, 14)}, + {itemid = 7081, position = Position(33591,32692, 14)}, + {itemid = 7081, position = Position(33587,32692, 14)}, + {itemid = 7081, position = Position(33572,32690, 14)}, + {itemid = 7081, position = Position(33582,32692, 14)}, + {itemid = 7081, position = Position(33572,32690, 14)}, + {itemid = 7081, position = Position(33591,32688, 14)}, + {itemid = 7081, position = Position(33592,32686, 14)}, + {itemid = 7081, position = Position(33583,32692, 14)}, + {itemid = 7081, position = Position(33573,32690, 14)}, + {itemid = 7081, position = Position(33583,32690, 14)}, + {itemid = 7081, position = Position(33579,32692, 14)}, + {itemid = 7081, position = Position(33581,32686, 14)}, + {itemid = 7081, position = Position(33575,32691, 14)}, + {itemid = 7081, position = Position(33588,32688, 14)}, + {itemid = 7081, position = Position(33587,32686, 14)}, + {itemid = 7081, position = Position(33580,32692, 14)}, + {itemid = 7081, position = Position(33590,32684, 14)}, + {itemid = 7081, position = Position(33589,32695, 14)}, + {itemid = 7081, position = Position(33593,32690, 14)}, + {itemid = 7081, position = Position(33580,32695, 14)}, + {itemid = 7081, position = Position(33589,32688, 14)}, + {itemid = 7081, position = Position(33577,32692, 14)}, + {itemid = 7081, position = Position(33584,32696, 14)}, + {itemid = 7081, position = Position(33589,32684, 14)}, + {itemid = 7081, position = Position(33590,32688, 14)}, + {itemid = 7080, position = Position(33579,32687, 14)}, + {itemid = 7080, position = Position(33576,32687, 14)}, + {itemid = 7080, position = Position(33592,32685, 14)}, + {itemid = 7080, position = Position(33583,32692, 14)}, + {itemid = 7080, position = Position(33582,32683, 14)}, + {itemid = 7080, position = Position(33585,32681, 14)}, + {itemid = 7080, position = Position(33591,32697, 14)}, + {itemid = 7080, position = Position(33588,32685, 14)}, + {itemid = 7080, position = Position(33583,32698, 14)}, + {itemid = 7080, position = Position(33591,32698, 14)}, + {itemid = 7080, position = Position(33583,32697, 14)}, + {itemid = 7080, position = Position(33583,32690, 14)}, + {itemid = 7080, position = Position(33588,32686, 14)}, + {itemid = 7080, position = Position(33583,32688, 14)}, + {itemid = 7080, position = Position(33587,32689, 14)}, + {itemid = 7080, position = Position(33579,32682, 14)}, + {itemid = 7080, position = Position(33594,32688, 14)}, + {itemid = 7080, position = Position(33583,32685, 14)}, + {itemid = 7080, position = Position(33578,32693, 14)}, + {itemid = 7080, position = Position(33592,32691, 14)}, + {itemid = 7080, position = Position(33585,32694, 14)}, + {itemid = 7080, position = Position(33578,32694, 14)}, + {itemid = 7080, position = Position(33587,32691, 14)}, + {itemid = 7080, position = Position(33592,32689, 14)}, + {itemid = 7080, position = Position(33585,32695, 14)}, + {itemid = 7080, position = Position(33583,32699, 14)}, + {itemid = 7080, position = Position(33579,32691, 14)}, + {itemid = 7080, position = Position(33583,32700, 14)}, + {itemid = 7080, position = Position(33584,32683, 14)}, + {itemid = 7080, position = Position(33582,32682, 14)}, + {itemid = 7080, position = Position(33581,32680, 14)}, + {itemid = 7080, position = Position(33579,32696, 14)}, + {itemid = 7080, position = Position(33593,32693, 14)}, + {itemid = 7080, position = Position(33576,32686, 14)}, + {itemid = 7080, position = Position(33578,32684, 14)}, + {itemid = 7080, position = Position(33588,32687, 14)}, + {itemid = 7080, position = Position(33594,32695, 14)}, + {itemid = 7080, position = Position(33578,32684, 14)}, + {itemid = 7079, position = Position(33577,32692, 14)}, + {itemid = 7079, position = Position(33572,32690, 14)}, + {itemid = 7079, position = Position(33575,32685, 14)}, + {itemid = 7079, position = Position(33584,32689, 14)}, + {itemid = 7079, position = Position(33584,32696, 14)}, + {itemid = 7079, position = Position(33589,32684, 14)}, + {itemid = 7079, position = Position(33581,32686, 14)}, + {itemid = 7079, position = Position(33572,32690, 14)}, + {itemid = 7079, position = Position(33590,32691, 14)}, + {itemid = 7079, position = Position(33588,32690, 14)}, + {itemid = 7079, position = Position(33589,32688, 14)}, + {itemid = 7079, position = Position(33588,32692, 14)}, + {itemid = 7079, position = Position(33581,32692, 14)}, + {itemid = 7079, position = Position(33580,32692, 14)}, + {itemid = 7079, position = Position(33590,32688, 14)}, + {itemid = 7079, position = Position(33578,32692, 14)}, + {itemid = 7079, position = Position(33590,32684, 14)}, + {itemid = 7079, position = Position(33583,32692, 14)}, + {itemid = 7079, position = Position(33591,32688, 14)}, + {itemid = 7079, position = Position(33593,32690, 14)}, + {itemid = 7079, position = Position(33587,32686, 14)}, + {itemid = 7079, position = Position(33580,32686, 14)}, + {itemid = 7079, position = Position(33573,32690, 14)}, + {itemid = 7079, position = Position(33579,32695, 14)}, + {itemid = 7079, position = Position(33575,32691, 14)}, + {itemid = 7079, position = Position(33574,32685, 14)}, + {itemid = 7079, position = Position(33589,32695, 14)}, + {itemid = 7079, position = Position(33591,32684, 14)}, + {itemid = 7079, position = Position(33592,32684, 14)}, + {itemid = 4479, position = Position(33591,32699, 14)}, + {itemid = 4479, position = Position(33596,32695, 14)}, + {itemid = 4479, position = Position(33589,32700, 14)}, + {itemid = 4479, position = Position(33597,32693, 14)}, + {itemid = 4479, position = Position(33595,32696, 14)}, + {itemid = 4479, position = Position(33593,32698, 14)}, + {itemid = 4479, position = Position(33594,32697, 14)}, + {itemid = 4478, position = Position(33586,32679, 14)}, + {itemid = 4478, position = Position(33590,32680, 14)}, + {itemid = 4478, position = Position(33593,32682, 14)}, + {itemid = 4478, position = Position(33597,32687, 14)}, + {itemid = 4478, position = Position(33596,32685, 14)}, + {itemid = 4478, position = Position(33595,32684, 14)}, + {itemid = 4478, position = Position(33594,32683, 14)}, + {itemid = 4478, position = Position(33591,32681, 14)}, + {itemid = 4477, position = Position(33572,32692, 14)}, + {itemid = 4477, position = Position(33574,32695, 14)}, + {itemid = 4477, position = Position(33575,32696, 14)}, + {itemid = 4477, position = Position(33576,32697, 14)}, + {itemid = 4477, position = Position(33577,32698, 14)}, + {itemid = 4477, position = Position(33581,32700, 14)}, + {itemid = 4477, position = Position(33579,32699, 14)}, + {itemid = 4477, position = Position(33572,32692, 14)}, + {itemid = 4477, position = Position(33573,32694, 14)}, + {itemid = 4476, position = Position(33572,32688, 14)}, + {itemid = 4476, position = Position(33574,32684, 14)}, + {itemid = 4476, position = Position(33572,32688, 14)}, + {itemid = 4476, position = Position(33578,32681, 14)}, + {itemid = 4476, position = Position(33573,32686, 14)}, + {itemid = 4476, position = Position(33581,32679, 14)}, + {itemid = 4476, position = Position(33575,32683, 14)}, + {itemid = 4476, position = Position(33573,32686, 14)}, + {itemid = 4476, position = Position(33579,32680, 14)}, + {itemid = 4476, position = Position(33576,32682, 14)}, + {itemid = 4475, position = Position(33581,32680, 14)}, + {itemid = 4475, position = Position(33573,32688, 14)}, + {itemid = 4475, position = Position(33578,32682, 14)}, + {itemid = 4475, position = Position(33579,32681, 14)}, + {itemid = 4475, position = Position(33576,32683, 14)}, + {itemid = 4475, position = Position(33573,32688, 14)}, + {itemid = 4475, position = Position(33574,32686, 14)}, + {itemid = 4475, position = Position(33575,32684, 14)}, + {itemid = 4474, position = Position(33586,32680, 14)}, + {itemid = 4474, position = Position(33593,32683, 14)}, + {itemid = 4474, position = Position(33594,32684, 14)}, + {itemid = 4474, position = Position(33596,32687, 14)}, + {itemid = 4474, position = Position(33595,32685, 14)}, + {itemid = 4474, position = Position(33591,32682, 14)}, + {itemid = 4474, position = Position(33590,32681, 14)}, + {itemid = 4473, position = Position(33581,32699, 14)}, + {itemid = 4473, position = Position(33574,32694, 14)}, + {itemid = 4473, position = Position(33573,32692, 14)}, + {itemid = 4473, position = Position(33576,32696, 14)}, + {itemid = 4473, position = Position(33577,32697, 14)}, + {itemid = 4473, position = Position(33579,32698, 14)}, + {itemid = 4473, position = Position(33575,32695, 14)}, + {itemid = 4472, position = Position(33572,32691, 14)}, + {itemid = 4472, position = Position(33574,32685, 14)}, + {itemid = 4472, position = Position(33573,32687, 14)}, + {itemid = 4472, position = Position(33573,32687, 14)}, + {itemid = 4472, position = Position(33572,32690, 14)}, + {itemid = 4472, position = Position(33573,32693, 14)}, + {itemid = 4472, position = Position(33572,32690, 14)}, + {itemid = 4472, position = Position(33572,32689, 14)}, + {itemid = 4472, position = Position(33572,32689, 14)}, + {itemid = 4472, position = Position(33572,32691, 14)}, + {itemid = 4471, position = Position(33587,32680, 14)}, + {itemid = 4471, position = Position(33589,32680, 14)}, + {itemid = 4471, position = Position(33588,32680, 14)}, + {itemid = 4471, position = Position(33585,32679, 14)}, + {itemid = 4471, position = Position(33577,32682, 14)}, + {itemid = 4471, position = Position(33584,32679, 14)}, + {itemid = 4471, position = Position(33582,32679, 14)}, + {itemid = 4471, position = Position(33583,32679, 14)}, + {itemid = 4471, position = Position(33592,32682, 14)}, + {itemid = 4471, position = Position(33580,32680, 14)}, + {itemid = 4470, position = Position(33589,32699, 14)}, + {itemid = 4470, position = Position(33594,32696, 14)}, + {itemid = 4470, position = Position(33591,32698, 14)}, + {itemid = 4470, position = Position(33596,32693, 14)}, + {itemid = 4470, position = Position(33593,32697, 14)}, + {itemid = 4470, position = Position(33595,32695, 14)}, + {itemid = 4469, position = Position(33586,32700, 14)}, + {itemid = 4469, position = Position(33590,32699, 14)}, + {itemid = 4469, position = Position(33584,32700, 14)}, + {itemid = 4469, position = Position(33583,32700, 14)}, + {itemid = 4469, position = Position(33580,32699, 14)}, + {itemid = 4469, position = Position(33592,32698, 14)}, + {itemid = 4469, position = Position(33578,32698, 14)}, + {itemid = 4469, position = Position(33582,32700, 14)}, + {itemid = 4469, position = Position(33588,32700, 14)}, + {itemid = 4469, position = Position(33585,32700, 14)}, + {itemid = 4469, position = Position(33587,32700, 14)}, + {itemid = 4468, position = Position(33597,32692, 14)}, + {itemid = 4468, position = Position(33597,32688, 14)}, + {itemid = 4468, position = Position(33596,32686, 14)}, + {itemid = 4468, position = Position(33596,32694, 14)}, + {itemid = 4468, position = Position(33597,32691, 14)}, + {itemid = 4468, position = Position(33597,32689, 14)}, + {itemid = 4468, position = Position(33597,32690, 14)}, + {itemid = 4466, position = Position(33596,32695, 14)}, + {itemid = 4458, position = Position(33584,32700, 14)}, + {itemid = 4458, position = Position(33585,32700, 14)}, + {itemid = 3623, position = Position(33588,32691, 14)}, + {itemid = 3623, position = Position(33595,32686, 14)}, + {itemid = 3622, position = Position(33586,32686, 14)}, + {itemid = 3622, position = Position(33583,32694, 14)}, + {itemid = 3622, position = Position(33591,32686, 14)}, + {itemid = 3622, position = Position(33581,32695, 14)}, + {itemid = 3622, position = Position(33592,32689, 14)}, + {itemid = 3621, position = Position(33581,32683, 14)}, + {itemid = 3621, position = Position(33591,32697, 14)}, + {itemid = 3614, position = Position(33579,32685, 14)}, + {itemid = 3614, position = Position(33578,32688, 14)}, + {itemid = 3614, position = Position(33593,32683, 14)}, + {itemid = 3614, position = Position(33579,32694, 14)}, + {itemid = 3613, position = Position(33592,32696, 14)}, + {itemid = 3613, position = Position(33585,32683, 14)}, + {itemid = 3613, position = Position(33586,32696, 14)}, + {itemid = 3613, position = Position(33582,32680, 14)}, + {itemid = 3612, position = Position(33588,32695, 14)}, + {itemid = 3612, position = Position(33579,32682, 14)}, + {itemid = 3612, position = Position(33596,32690, 14)}, + {itemid = 3612, position = Position(33583,32687, 14)}, + {itemid = 3612, position = Position(33582,32694, 14)}, + {itemid = 3611, position = Position(33591,32683, 14)}, + {itemid = 3611, position = Position(33577,32688, 14)}, + {itemid = 3611, position = Position(33578,32691, 14)}, + {itemid = 3611, position = Position(33590,32696, 14)}, + {itemid = 3611, position = Position(33588,32689, 14)}, + {itemid = 3611, position = Position(33577,32682, 14)}, + {itemid = 3611, position = Position(33583,32682, 14)}, + {itemid = 3611, position = Position(33590,32691, 14)}, + {itemid = 3611, position = Position(33575,32689, 14)}, + {itemid = 3610, position = Position(33581,32689, 14)} +} + +local function revertLava() + for i = 1, #itemsRoom do + local item = itemsRoom[i] + if isInArray(tiles, item.itemid) then + local ground = Tile(item.position):getGround() + local transformid = item.itemid + if ground then + ground:transform(transformid) + ground:setActionId(34201) + end + else + local tp = Game.createItem(item.itemid, 1, item.position) + tp:setActionId(34201) + end + end + return true +end +local function lavaGrounds (cid) + local creature = Creature(cid) + if not creature then return true end + local summoncount = creature:getSummons() + if #summoncount < 4 then + for i = 1, 4 do + local mid = Game.createMonster("Rage of Mazoran", Position(math.random(33576, 33593), math.random(32684, 32695), 14), true, true) + if not mid then + return + end + mid:setMaster(creature) + end + end + for x = 33572, 33598 do + for y = 32679, 32701 do + local position = Position(x, y, 14) + local tile = Tile(position) + if not tile then + return + end + local ground = tile:getGround() + if not ground then + return + end + local grounds = ground:getId() + if grounds ~= 919 then + local items = tile:getItems() + for i = 1, #items do + local item = items[i] + local itemId = item:getId() + if not isInArray(Montains, itemId) then + item:remove() + end + end + ground:transform(23863) + ground:setActionId(34200) + end + end + end + addEvent(revertLava, 5 * 1000) +end +function onCastSpell(creature, var) + creature:say('THE GROUND BEGINS TO HEAT UP RAPIDLY!', TALKTYPE_MONSTER_YELL) + addEvent(lavaGrounds, 3 * 1000, creature:getId()) + return +end diff --git a/data/spells/scripts/monster/mazoran summon.lua b/data/spells/scripts/monster/mazoran summon.lua new file mode 100644 index 00000000000..f20b733df9a --- /dev/null +++ b/data/spells/scripts/monster/mazoran summon.lua @@ -0,0 +1,13 @@ +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 4 then + for i = 1, 4 do + local mid = Game.createMonster("Rage of Mazoran", Position(math.random(33576, 33593), math.random(32684, 32695), 14), true, true) + if not mid then + return + end + mid:setMaster(creature) + end + end + return +end diff --git a/data/spells/scripts/monster/medusa paralyze.lua b/data/spells/scripts/monster/medusa paralyze.lua new file mode 100644 index 00000000000..76a43416ede --- /dev/null +++ b/data/spells/scripts/monster/medusa paralyze.lua @@ -0,0 +1,33 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POFF) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_EARTH) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.45, 0, -0.5, 0) +combat:addCondition(condition) + +arr = { +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +} + +local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/mephiles skill reducer.lua b/data/spells/scripts/monster/mephiles skill reducer.lua new file mode 100644 index 00000000000..241ad6459be --- /dev/null +++ b/data/spells/scripts/monster/mephiles skill reducer.lua @@ -0,0 +1,20 @@ +local combat = {} + +for i = 80, 95 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 6000) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + + local area = createCombatArea(AREA_BEAM1) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(80, 95)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/mephiles summon.lua b/data/spells/scripts/monster/mephiles summon.lua new file mode 100644 index 00000000000..87a89bce73c --- /dev/null +++ b/data/spells/scripts/monster/mephiles summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYFIRE) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Fire Devil", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/metal gargoyle curse.lua b/data/spells/scripts/monster/metal gargoyle curse.lua new file mode 100644 index 00000000000..ac9aa610d90 --- /dev/null +++ b/data/spells/scripts/monster/metal gargoyle curse.lua @@ -0,0 +1,23 @@ +local combat = {} + +for i = 2.32, 2.32 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_CURSED) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + + local damage = i + condition:addDamage(1, 4000, -damage) + for j = 1, 23 do + damage = damage * 1.2 + condition:addDamage(1, 4000, -damage) + end + + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(2.32, 2.32)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/mindmasher drown.lua b/data/spells/scripts/monster/mindmasher drown.lua new file mode 100644 index 00000000000..c9c03be3801 --- /dev/null +++ b/data/spells/scripts/monster/mindmasher drown.lua @@ -0,0 +1,12 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_DROWNDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BUBBLES) + +local condition = Condition(CONDITION_DROWN) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(20, 5000, -20) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/mindmasher summon.lua b/data/spells/scripts/monster/mindmasher summon.lua new file mode 100644 index 00000000000..80d2bb099ef --- /dev/null +++ b/data/spells/scripts/monster/mindmasher summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_NONE) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 4 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 4 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Mindmasher summon", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/minotaur amazon paralyze.lua b/data/spells/scripts/monster/minotaur amazon paralyze.lua new file mode 100644 index 00000000000..ee47404e2c5 --- /dev/null +++ b/data/spells/scripts/monster/minotaur amazon paralyze.lua @@ -0,0 +1,23 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, 3) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 10000) +condition:setFormula(-0.4, 0, -0.7, 0) +combat:addCondition(condition) + + arr = { + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/minotaur wallbreaker walkthrough.lua b/data/spells/scripts/monster/minotaur wallbreaker walkthrough.lua new file mode 100644 index 00000000000..5637b03780b --- /dev/null +++ b/data/spells/scripts/monster/minotaur wallbreaker walkthrough.lua @@ -0,0 +1,34 @@ +local condition = Condition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) +condition:setParameter(CONDITION_PARAM_SUBID, 88888) +condition:setParameter(CONDITION_PARAM_TICKS, 10 * 1000) +condition:setParameter(CONDITION_PARAM_HEALTHGAIN, 0.01) +condition:setParameter(CONDITION_PARAM_HEALTHTICKS, 10 * 1000) + +local function changeSpeeds(cid, var) + local creature = Creature(cid) + if not creature then + return + end + creature:changeSpeed(creature:getBaseSpeed()) +end + +function onCastSpell(creature, var) + local nextPosition = creature:getPosition() + local speed = creature:getSpeed() + local tile = Tile(nextPosition.x - 1, nextPosition.y, nextPosition.z) + local topCreature = tile:getTopCreature() + if not creature:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, 88888) then + creature:addCondition(condition) + creature:teleportTo(Position(nextPosition.x - 1, nextPosition.y, nextPosition.z), true) + creature:changeSpeed(-speed) + addEvent(changeSpeeds, 11 * 1000, creature:getId(), var) + if not topCreature then + return + end + if topCreature:isPlayer() then + topCreature:teleportTo(Position(nextPosition.x - 3, nextPosition.y, nextPosition.z), true) + else + end + end + return true +end diff --git a/data/spells/scripts/monster/monstor summon.lua b/data/spells/scripts/monster/monstor summon.lua new file mode 100644 index 00000000000..23efaeefb0a --- /dev/null +++ b/data/spells/scripts/monster/monstor summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GREEN_RINGS) + +local area = createCombatArea(AREA_CIRCLE3X3) +combat:setArea(area) + +local maxsummons = 3 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 3 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Acid Blob", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/mooh'tah master skill reducer.lua b/data/spells/scripts/monster/mooh'tah master skill reducer.lua new file mode 100644 index 00000000000..3004ecd02cc --- /dev/null +++ b/data/spells/scripts/monster/mooh'tah master skill reducer.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_STUN) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 3000) + condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, -100) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/morgaroth paralyze.lua b/data/spells/scripts/monster/morgaroth paralyze.lua new file mode 100644 index 00000000000..6e9d5079d58 --- /dev/null +++ b/data/spells/scripts/monster/morgaroth paralyze.lua @@ -0,0 +1,31 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_RED) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 30000) + condition:setFormula(-0.7, 0, -0.9, 0) + combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/morgaroth skill reducer 1.lua b/data/spells/scripts/monster/morgaroth skill reducer 1.lua new file mode 100644 index 00000000000..3fd9159c109 --- /dev/null +++ b/data/spells/scripts/monster/morgaroth skill reducer 1.lua @@ -0,0 +1,18 @@ +local combat = {} + +for i = 15, 30 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 15000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE3X3) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(15, 30)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/morgaroth skill reducer 2.lua b/data/spells/scripts/monster/morgaroth skill reducer 2.lua new file mode 100644 index 00000000000..8d8e64dae49 --- /dev/null +++ b/data/spells/scripts/monster/morgaroth skill reducer 2.lua @@ -0,0 +1,18 @@ +local combat = {} + +for i = 15, 30 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_TELEPORT) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 15000) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(15, 30)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/morgaroth summon.lua b/data/spells/scripts/monster/morgaroth summon.lua new file mode 100644 index 00000000000..75d05307b05 --- /dev/null +++ b/data/spells/scripts/monster/morgaroth summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_NONE) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 4 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 4 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Demon2", { x=creature:getPosition().x+math.random(-2, 2), y=creature:getPosition().y+math.random(-2, 2), z=creature:getPosition().z }) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/morik the gladiator summon.lua b/data/spells/scripts/monster/morik the gladiator summon.lua new file mode 100644 index 00000000000..7802a74d969 --- /dev/null +++ b/data/spells/scripts/monster/morik the gladiator summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_GREEN) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Gladiator", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/mummy paralyze.lua b/data/spells/scripts/monster/mummy paralyze.lua new file mode 100644 index 00000000000..ee4ad1b11a5 --- /dev/null +++ b/data/spells/scripts/monster/mummy paralyze.lua @@ -0,0 +1,11 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.7, 0, -0.85, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/munster summon.lua b/data/spells/scripts/monster/munster summon.lua new file mode 100644 index 00000000000..568ded573af --- /dev/null +++ b/data/spells/scripts/monster/munster summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POFF) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Rat", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/mutated bat curse.lua b/data/spells/scripts/monster/mutated bat curse.lua new file mode 100644 index 00000000000..333319f77bf --- /dev/null +++ b/data/spells/scripts/monster/mutated bat curse.lua @@ -0,0 +1,38 @@ +local combat = {} + +for i = 2, 4 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_DEATH) + + local condition = Condition(CONDITION_CURSED) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + + local damage = i + condition:addDamage(1, 4000, -damage) + for j = 1, 9 do + damage = damage * 1.2 + condition:addDamage(1, 4000, -damage) + end + + local area = createCombatArea({ + {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + }) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(2, 4)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/mutated human paralyze.lua b/data/spells/scripts/monster/mutated human paralyze.lua new file mode 100644 index 00000000000..dc85f869a22 --- /dev/null +++ b/data/spells/scripts/monster/mutated human paralyze.lua @@ -0,0 +1,11 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 5000) + condition:setFormula(-0.05, 0, -0.15, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/mutated rat paralyze.lua b/data/spells/scripts/monster/mutated rat paralyze.lua new file mode 100644 index 00000000000..dfbf72c793c --- /dev/null +++ b/data/spells/scripts/monster/mutated rat paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POISONAREA) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.2, 0, -0.45, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/nightstalker paralyze.lua b/data/spells/scripts/monster/nightstalker paralyze.lua new file mode 100644 index 00000000000..10e91fc0f53 --- /dev/null +++ b/data/spells/scripts/monster/nightstalker paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SLEEP) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.7, 0, -0.9, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/obujos skill reducer 1.lua b/data/spells/scripts/monster/obujos skill reducer 1.lua new file mode 100644 index 00000000000..cfea1d0a8b8 --- /dev/null +++ b/data/spells/scripts/monster/obujos skill reducer 1.lua @@ -0,0 +1,16 @@ +local combat = {} + +for i = 35, 50 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_STUN) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 15000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(35, 50)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/obujos skill reducer 2.lua b/data/spells/scripts/monster/obujos skill reducer 2.lua new file mode 100644 index 00000000000..c47a49ce78e --- /dev/null +++ b/data/spells/scripts/monster/obujos skill reducer 2.lua @@ -0,0 +1,17 @@ +local combat = {} + +for i = 35, 60 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_STUN) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 15000) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(35, 60)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ocyakao freeze.lua b/data/spells/scripts/monster/ocyakao freeze.lua new file mode 100644 index 00000000000..be8320db465 --- /dev/null +++ b/data/spells/scripts/monster/ocyakao freeze.lua @@ -0,0 +1,15 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONAREA) + + local condition = Condition(CONDITION_FREEZING) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + condition:addDamage(25, 8000, -8) + combat:addCondition(condition) + + local area = createCombatArea(AREA_CIRCLE3X3) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/omrafir beam.lua b/data/spells/scripts/monster/omrafir beam.lua new file mode 100644 index 00000000000..164e55def5c --- /dev/null +++ b/data/spells/scripts/monster/omrafir beam.lua @@ -0,0 +1,127 @@ +local condition = Condition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) +condition:setParameter(CONDITION_PARAM_SUBID, 88888) +condition:setParameter(CONDITION_PARAM_TICKS, 5 * 1000) +condition:setParameter(CONDITION_PARAM_HEALTHGAIN, 0.01) +condition:setParameter(CONDITION_PARAM_HEALTHTICKS, 5 * 1000) + +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREAREA) +combat:setFormula(COMBAT_FORMULA_DAMAGE, -7000, 0, -10000, 0) + + arr1 = { +{0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +} + +local area1 = createCombatArea(arr1) +combat:setArea(area1) + +----------------------------------------------------------------------------- + +local combat2 = Combat() +combat2:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat2:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREAREA) +combat2:setFormula(COMBAT_FORMULA_DAMAGE, -7000, 0, -10000, 0) + + arr2 = { +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +} + +local area2 = createCombatArea(arr2) +combat2:setArea(area2) + +-------------------------------------------------------------------------- + +local combat3 = Combat() +combat3:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat3:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREAREA) +combat3:setFormula(COMBAT_FORMULA_DAMAGE, -7000, 0, -10000, 0) + + arr3 = { +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +} + +local area3 = createCombatArea(arr3) +combat3:setArea(area3) + +-------------------------------------------------------------------------- + +local combat4 = Combat() +combat4:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat4:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREAREA) +combat4:setFormula(COMBAT_FORMULA_DAMAGE, -7000, 0, -10000, 0) + + arr4 = { +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +} + +local area4 = createCombatArea(arr4) +combat4:setArea(area4) + +-------------------------------------------------------------- + +function onCastSpell(creature, var) + if not creature:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, 88888) then + creature:say("OMRAFIR INHALES DEEPLY!", TALKTYPE_ORANGE_2) + creature:addCondition(condition) + addEvent(function(cid, var) + local creature = Creature(cid) + if not creature then + return + end + if creature:getDirection() == 0 then + combat:execute(creature, positionToVariant(creature:getPosition())) + elseif creature:getDirection() == 1 then + combat2:execute(creature, positionToVariant(creature:getPosition())) + elseif creature:getDirection() == 2 then + combat3:execute(creature, positionToVariant(creature:getPosition())) + elseif creature:getDirection() == 3 then + combat4:execute(creature, positionToVariant(creature:getPosition())) + end + creature:say("OMRAFIR BREATHES INFERNAL FIRE", TALKTYPE_ORANGE_2) +end, 4000, creature:getId(), var) + else + return + end + return true +end diff --git a/data/spells/scripts/monster/omrafir healing 2.lua b/data/spells/scripts/monster/omrafir healing 2.lua new file mode 100644 index 00000000000..ac0c6974d42 --- /dev/null +++ b/data/spells/scripts/monster/omrafir healing 2.lua @@ -0,0 +1,16 @@ +function onCastSpell(creature, var) +local health, hp, cpos = math.random(7500, 9000), (creature:getHealth()/creature:getMaxHealth())*100, creature:getPosition() + + if creature:getName() == "Omrafir" and (hp < 99.99) then + local t = Tile(cpos) + if t == nil then + return + end + if t:getItemById(1487) or t:getItemById(1492) or t:getItemById(1500) then + creature:addHealth(health) + cpos:sendMagicEffect(CONST_ME_MAGIC_BLUE) + creature:say("Omrafir gains new strength from the fire", TALKTYPE_ORANGE_1) + else + end + end +end diff --git a/data/spells/scripts/monster/omrafir summon.lua b/data/spells/scripts/monster/omrafir summon.lua new file mode 100644 index 00000000000..dc63b955e6e --- /dev/null +++ b/data/spells/scripts/monster/omrafir summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_NONE) + +local area = createCombatArea(AREA_CIRCLE3X3) +combat:setArea(area) + +local maxsummons = 4 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 4 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Flame Of Omrafir", { x=creature:getPosition().x+math.random(-2, 2), y=creature:getPosition().y+math.random(-2, 2), z=creature:getPosition().z }) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/omrafir wave.lua b/data/spells/scripts/monster/omrafir wave.lua new file mode 100644 index 00000000000..14fdbcf048b --- /dev/null +++ b/data/spells/scripts/monster/omrafir wave.lua @@ -0,0 +1,18 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONHIT) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/orewalker skill reducer 1.lua b/data/spells/scripts/monster/orewalker skill reducer 1.lua new file mode 100644 index 00000000000..8f97b361c5a --- /dev/null +++ b/data/spells/scripts/monster/orewalker skill reducer 1.lua @@ -0,0 +1,26 @@ +local combat = {} + +for i = 25, 45 do +combat[i] = Combat() +combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BLOCKHIT) + +local condition = Condition(CONDITION_ATTRIBUTES) +condition:setParameter(CONDITION_PARAM_TICKS, 15000) +condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + +local area = createCombatArea({ + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + }) + +combat[i]:setArea(area) +combat[i]:addCondition(condition) + +end + +function onCastSpell(creature, var) + return combat[math.random(25, 45)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/orewalker wave.lua b/data/spells/scripts/monster/orewalker wave.lua new file mode 100644 index 00000000000..5a0b00b0eff --- /dev/null +++ b/data/spells/scripts/monster/orewalker wave.lua @@ -0,0 +1,18 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_MANADRAIN) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/orshabaal skill reducer.lua b/data/spells/scripts/monster/orshabaal skill reducer.lua new file mode 100644 index 00000000000..be083e157ba --- /dev/null +++ b/data/spells/scripts/monster/orshabaal skill reducer.lua @@ -0,0 +1,18 @@ +local combat = {} + +for i = 30, 40 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE3X3) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(30, 40)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/outburst explode.lua b/data/spells/scripts/monster/outburst explode.lua new file mode 100644 index 00000000000..fb0ba5d8357 --- /dev/null +++ b/data/spells/scripts/monster/outburst explode.lua @@ -0,0 +1,75 @@ +local function outExplode() + local upConer = {x = 32223, y = 31273, z = 14} -- upLeftCorner + local downConer = {x = 32246, y = 31297, z = 14} -- downRightCorner + + for i=upConer.x, downConer.x do + for j=upConer.y, downConer.y do + for k= upConer.z, downConer.z do + local room = {x=i, y=j, z=k} + local tile = Tile(room) + if tile then + local creatures = tile:getCreatures() + if creatures and #creatures > 0 then + for _, c in pairs(creatures) do + if isPlayer(c) then + c:teleportTo({x = 32234, y = 31280, z = 14}) + elseif isMonster(c) and c:getName() == "Charging Outburst" then + c:teleportTo({x = 32234, y = 31279, z = 14}) + end + end + end + end + end + end + end +end + +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_PURPLEENERGY) + +arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +} + +local area = createCombatArea(arr) +combat:setArea(area) + +local function delayedCastSpell(creature, var) + if not creature then + return + end + return combat:execute(creature, positionToVariant(creature:getPosition())) +end + +function removeOutburst(cid) + local creature = Creature(cid) + if not isCreature(creature) then return false end + creature:remove() +end + +function onCastSpell(creature, var) + local from = creature:getId() + + outExplode() + delayedCastSpell(creature, var) + chargingOutKilled = true + addEvent(removeOutburst, 1000, creature.uid) + + local monster = Game.createMonster("Outburst", {x = 32234, y = 31284, z = 14}, false, true) + monster:addHealth(-monster:getHealth() + outburstHealth, COMBAT_PHYSICALDAMAGE) + transferBossPoints(from, monster:getId()) + return true +end diff --git a/data/spells/scripts/monster/phantasm drown.lua b/data/spells/scripts/monster/phantasm drown.lua new file mode 100644 index 00000000000..14c8266269f --- /dev/null +++ b/data/spells/scripts/monster/phantasm drown.lua @@ -0,0 +1,24 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_DROWNDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) + +local condition = Condition(CONDITION_DROWN) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(20, 5000, -20) + +local area = createCombatArea({ + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0} +}) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/pirate corsair skill reducer.lua b/data/spells/scripts/monster/pirate corsair skill reducer.lua new file mode 100644 index 00000000000..5e4d3a58d54 --- /dev/null +++ b/data/spells/scripts/monster/pirate corsair skill reducer.lua @@ -0,0 +1,20 @@ +local combat = {} + +for i = 25, 55 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_PURPLE) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 7000) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + + local area = createCombatArea(AREA_BEAM1) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(25, 55)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/pixie skill reducer.lua b/data/spells/scripts/monster/pixie skill reducer.lua new file mode 100644 index 00000000000..fa9cfd56441 --- /dev/null +++ b/data/spells/scripts/monster/pixie skill reducer.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_PIXIE_EXPLOSION) + +local condition = Condition(CONDITION_ATTRIBUTES) +condition:setParameter(CONDITION_PARAM_TICKS, 6000) +condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, 30) +condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, 30) +condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, 30) + +local area = createCombatArea(AREA_CIRCLE2X2) + +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/plagirath bog.lua b/data/spells/scripts/monster/plagirath bog.lua new file mode 100644 index 00000000000..295324212f8 --- /dev/null +++ b/data/spells/scripts/monster/plagirath bog.lua @@ -0,0 +1,58 @@ +local combat2 = Combat() +combat2:setParameter(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE) +combat2:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POISON) +combat2:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) + + +arr = { +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 3, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +} + +local area = createCombatArea(arr) +combat2:setArea(area) + +function onGetFormulaValues(player, level, maglevel) + min = -1500 + max = -1500 + return min, max +end + +combat2:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +local function spellDamage(cid, target, var) + local creature = Creature(cid) + local target = Creature(target) + if not creature or not target then + return + end + if creature:getHealth() >= 1 and creature:getPosition():getDistance(target:getPosition()) < 20 then + return combat2:execute(creature, var) + end +end + +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLPLANTS) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) + +local condition = Condition(CONDITION_OUTFIT) +condition:setParameter(CONDITION_PARAM_TICKS, 10000) +condition:setOutfit({lookType = 299}) +combat:addCondition(condition) + +function onCastSpell(creature, var) + local target = creature:getTarget() + addEvent(spellDamage, 10 * 1000, creature:getId(), target:getId(), var) + return combat:execute(creature, var) +end \ No newline at end of file diff --git a/data/spells/scripts/monster/plagirath heal.lua b/data/spells/scripts/monster/plagirath heal.lua new file mode 100644 index 00000000000..25490527faf --- /dev/null +++ b/data/spells/scripts/monster/plagirath heal.lua @@ -0,0 +1,42 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) + +arr = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onTargetCreature(creature, target) + local min = 300 + local max = 700 + + local master = target:getMaster() + if target:isPlayer() and not master + or master and master:isPlayer() then + return true + end + + doTargetCombatHealth(0, target, COMBAT_HEALING, min, max, CONST_ME_NONE) + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/plagirath summon.lua b/data/spells/scripts/monster/plagirath summon.lua new file mode 100644 index 00000000000..d5af28f4c6e --- /dev/null +++ b/data/spells/scripts/monster/plagirath summon.lua @@ -0,0 +1,14 @@ +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + local maxsummons = 4 + if #summoncount < 4 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Disgusting Ooze", Position(math.random(33163, 33180), math.random(31497, 31506), 13), true, true) + if not mid then + return + end + mid:setMaster(creature) + end + end + return +end diff --git a/data/spells/scripts/monster/plaguesmith paralyze.lua b/data/spells/scripts/monster/plaguesmith paralyze.lua new file mode 100644 index 00000000000..c3ac4df8364 --- /dev/null +++ b/data/spells/scripts/monster/plaguesmith paralyze.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POISONAREA) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.7, 0, -0.85, 0) +combat:addCondition(condition) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/plaguesmith wave.lua b/data/spells/scripts/monster/plaguesmith wave.lua new file mode 100644 index 00000000000..d022965a6f1 --- /dev/null +++ b/data/spells/scripts/monster/plaguesmith wave.lua @@ -0,0 +1,19 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_LIFEDRAINDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_YELLOW_RINGS) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/priestess firering.lua b/data/spells/scripts/monster/priestess firering.lua new file mode 100644 index 00000000000..d97e6a9b475 --- /dev/null +++ b/data/spells/scripts/monster/priestess firering.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONHIT) +combat:setParameter(COMBAT_PARAM_SHOOT_EFFECT, CONST_ANI_FIRE) +arr = { +{1, 0, 1}, +{0, 2, 0}, +{1, 0, 1} +} + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/prince drazzak druid.lua b/data/spells/scripts/monster/prince drazzak druid.lua new file mode 100644 index 00000000000..0cdb19e710a --- /dev/null +++ b/data/spells/scripts/monster/prince drazzak druid.lua @@ -0,0 +1,79 @@ +local storage = 674531 + +local area = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +} + +local createArea = createCombatArea(area) + +local combat = Combat() +combat:setArea(createArea) + +function onTargetTile(creature, pos) + local creatureTable = {} + local n, i = Tile({x=pos.x, y=pos.y, z=pos.z}).creatures, 1 + if n ~= 0 then + local v = getThingfromPos({x=pos.x, y=pos.y, z=pos.z, stackpos=i}).uid + while v ~= 0 do + if isCreature(v) == true then + table.insert(creatureTable, v) + if n == #creatureTable then + break + end + end + i = i + 1 + v = getThingfromPos({x=pos.x, y=pos.y, z=pos.z, stackpos=i}).uid + end + end + if #creatureTable ~= nil and #creatureTable > 0 then + for r = 1, #creatureTable do + if creatureTable[r] ~= creature then + local min = 4000 + local max = 8000 + local player = Player(creatureTable[r]) + + if isPlayer(creatureTable[r]) == true + and table.contains({VOCATION.CLIENT_ID.DRUID}, player:getVocation():getClientId()) then + doTargetCombatHealth(creature, creatureTable[r], COMBAT_POISONDAMAGE, -min, -max, CONST_ME_NONE) + elseif isMonster(creatureTable[r]) == true then + doTargetCombatHealth(creature, creatureTable[r], COMBAT_POISONDAMAGE, -min, -max, CONST_ME_NONE) + end + end + end + end + pos:sendMagicEffect(CONST_ME_POISONAREA) + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +local function delayedCastSpell(cid, var) + local creature = Creature(cid) + if not creature then + return + end + creature:say("DIE!", TALKTYPE_ORANGE_1) + return combat:execute(creature, positionToVariant(creature:getPosition())) +end + +function onCastSpell(creature, var) + local value = Game.getStorageValue(storage) + if(os.time()-value >= 4) then + creature:say("All DRUIDS must DIE!", TALKTYPE_ORANGE_1) + addEvent(delayedCastSpell, 4000, creature:getId(), var) + Game.setStorageValue(storage, os.time()) + end + return true +end diff --git a/data/spells/scripts/monster/prince drazzak knight.lua b/data/spells/scripts/monster/prince drazzak knight.lua new file mode 100644 index 00000000000..20f02890387 --- /dev/null +++ b/data/spells/scripts/monster/prince drazzak knight.lua @@ -0,0 +1,63 @@ +local storage = 674531 + +local area = createCombatArea(AREA_CIRCLE3X3) + +local combat = Combat() +combat:setArea(area) + +function onTargetTile(creature, pos) + local creatureTable = {} + local n, i = Tile({x=pos.x, y=pos.y, z=pos.z}).creatures, 1 + if n ~= 0 then + local v = getThingfromPos({x=pos.x, y=pos.y, z=pos.z, stackpos=i}).uid + while v ~= 0 do + if isCreature(v) == true then + table.insert(creatureTable, v) + if n == #creatureTable then + break + end + end + i = i + 1 + v = getThingfromPos({x=pos.x, y=pos.y, z=pos.z, stackpos=i}).uid + end + end + if #creatureTable ~= nil and #creatureTable > 0 then + for r = 1, #creatureTable do + if creatureTable[r] ~= creature then + local min = 4000 + local max = 8000 + local player = Player(creatureTable[r]) + + if isPlayer(creatureTable[r]) == true + and table.contains({VOCATION.CLIENT_ID.KNIGHT}, player:getVocation():getClientId()) then + doTargetCombatHealth(creature, creatureTable[r], COMBAT_FIREDAMAGE, -min, -max, CONST_ME_NONE) + elseif isMonster(creatureTable[r]) == true then + doTargetCombatHealth(creature, creatureTable[r], COMBAT_FIREDAMAGE, -min, -max, CONST_ME_NONE) + end + end + end + end + pos:sendMagicEffect(CONST_ME_HITBYFIRE) + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +local function delayedCastSpell(cid, var) + local creature = Creature(cid) + if not creature then + return + end + creature:say("DIE!", TALKTYPE_ORANGE_1) + return combat:execute(creature, positionToVariant(creature:getPosition())) +end + +function onCastSpell(creature, var) +local value = Game.getStorageValue(storage) + if(os.time()-value >= 4) then + creature:say("All KNIGHTS must DIE!", TALKTYPE_ORANGE_1) + addEvent(delayedCastSpell, 4000, creature:getId(), var) + Game.setStorageValue(storage, os.time()) + end + return true +end diff --git a/data/spells/scripts/monster/prince drazzak paladin.lua b/data/spells/scripts/monster/prince drazzak paladin.lua new file mode 100644 index 00000000000..2d83c44dcac --- /dev/null +++ b/data/spells/scripts/monster/prince drazzak paladin.lua @@ -0,0 +1,79 @@ +local storage = 674531 + +local area = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + +local createArea = createCombatArea(area) + +local combat = Combat() +combat:setArea(createArea) + +function onTargetTile(creature, pos) + local creatureTable = {} + local n, i = Tile({x=pos.x, y=pos.y, z=pos.z}).creatures, 1 + if n ~= 0 then + local v = getThingfromPos({x=pos.x, y=pos.y, z=pos.z, stackpos=i}).uid + while v ~= 0 do + if isCreature(v) == true then + table.insert(creatureTable, v) + if n == #creatureTable then + break + end + end + i = i + 1 + v = getThingfromPos({x=pos.x, y=pos.y, z=pos.z, stackpos=i}).uid + end + end + if #creatureTable ~= nil and #creatureTable > 0 then + for r = 1, #creatureTable do + if creatureTable[r] ~= creature then + local min = 4000 + local max = 8000 + local player = Player(creatureTable[r]) + + if isPlayer(creatureTable[r]) == true + and table.contains({VOCATION.CLIENT_ID.PALADIN}, player:getVocation():getClientId()) then + doTargetCombatHealth(creature, creatureTable[r], COMBAT_ENERGYDAMAGE, -min, -max, CONST_ME_NONE) + elseif isMonster(creatureTable[r]) == true then + doTargetCombatHealth(creature, creatureTable[r], COMBAT_ENERGYDAMAGE, -min, -max, CONST_ME_NONE) + end + end + end + end + pos:sendMagicEffect(CONST_ME_ENERGYHIT) + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +local function delayedCastSpell(cid, var) + local creature = Creature(cid) + if not creature then + return + end + creature:say("DIE!", TALKTYPE_ORANGE_1) + return combat:execute(creature, positionToVariant(creature:getPosition())) +end + +function onCastSpell(creature, var) +local value = Game.getStorageValue(storage) + if(os.time()-value >= 4) then + creature:say("All PALADINS must DIE!", TALKTYPE_ORANGE_1) + addEvent(delayedCastSpell, 4000, creature:getId(), var) + Game.setStorageValue(storage, os.time()) + end + return true +end diff --git a/data/spells/scripts/monster/prince drazzak sorcerer.lua b/data/spells/scripts/monster/prince drazzak sorcerer.lua new file mode 100644 index 00000000000..5a654dd81a8 --- /dev/null +++ b/data/spells/scripts/monster/prince drazzak sorcerer.lua @@ -0,0 +1,79 @@ +local storage = 674531 + +local area = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + +local createArea = createCombatArea(area) + +local combat = Combat() +combat:setArea(createArea) + +function onTargetTile(creature, pos) + local creatureTable = {} + local n, i = Tile({x=pos.x, y=pos.y, z=pos.z}).creatures, 1 + if n ~= 0 then + local v = getThingfromPos({x=pos.x, y=pos.y, z=pos.z, stackpos=i}).uid + while v ~= 0 do + if isCreature(v) == true then + table.insert(creatureTable, v) + if n == #creatureTable then + break + end + end + i = i + 1 + v = getThingfromPos({x=pos.x, y=pos.y, z=pos.z, stackpos=i}).uid + end + end + if #creatureTable ~= nil and #creatureTable > 0 then + for r = 1, #creatureTable do + if creatureTable[r] ~= creature then + local min = 4000 + local max = 8000 + local player = Player(creatureTable[r]) + + if isPlayer(creatureTable[r]) == true + and table.contains({VOCATION.CLIENT_ID.CLIENT_ID.SORCERER}, player:getVocation():getClientId()) then + doTargetCombatHealth(creature, creatureTable[r], COMBAT_DEATHDAMAGE, -min, -max, CONST_ME_NONE) + elseif isMonster(creatureTable[r]) == true then + doTargetCombatHealth(creature, creatureTable[r], COMBAT_DEATHDAMAGE, -min, -max, CONST_ME_NONE) + end + end + end + end + pos:sendMagicEffect(CONST_ME_MORTAREA) + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +local function delayedCastSpell(cid, var) + local creature = Creature(cid) + if not creature then + return + end + creature:say("DIE!", TALKTYPE_ORANGE_1) + return combat:execute(creature, positionToVariant(creature:getPosition())) +end + +function onCastSpell(creature, var) +local value = Game.getStorageValue(storage) + if(os.time()-value >= 4) then + creature:say("All SORCERERS must DIE!", TALKTYPE_ORANGE_1) + addEvent(delayedCastSpell, 4000, creature:getId(), var) + Game.setStorageValue(storage, os.time()) + end + return true +end diff --git a/data/spells/scripts/monster/prince drazzak summon.lua b/data/spells/scripts/monster/prince drazzak summon.lua new file mode 100644 index 00000000000..ea7cde97133 --- /dev/null +++ b/data/spells/scripts/monster/prince drazzak summon.lua @@ -0,0 +1,20 @@ +function onCastSpell(creature, var) +local t, spectator = Game.getSpectators(Position(33528, 32335, 12), false, false, 20, 20, 20, 20) + local check = 0 + if #t ~= nil then + for i = 1, #t do + spectator = t[i] + if spectator:getName() == "Demon" then + check = check + 1 + end + end + end + if (check < 1) then + creature:say("CRUSH THEM ALL!", TALKTYPE_ORANGE_2) + Game.createMonster("Demon", Position(33528, 32330, 12)) + Game.createMonster("Demon", Position(33523, 32338, 12)) + Game.createMonster("Demon", Position(33532, 32337, 12)) + else + end +return true +end diff --git a/data/spells/scripts/monster/prince drazzak tp.lua b/data/spells/scripts/monster/prince drazzak tp.lua new file mode 100644 index 00000000000..b493ed8a659 --- /dev/null +++ b/data/spells/scripts/monster/prince drazzak tp.lua @@ -0,0 +1,14 @@ +function onCastSpell(creature, var) +local center, center2 = {x=33529, y=32334, z=12, stackpos=255}, {x=33528, y=32334, z=12, stackpos=255} + creature:say("GET OVER HERE!", TALKTYPE_ORANGE_2, false, 0, center2) + for x = 33519, 33538 do + for y = 32327, 32342 do + local a = Tile(Position({x = x, y = y, z = 12})):getTopCreature() + if a ~= 0 and isMonster(a) and creature:getName():lower() ~= "prince drazzak" or isPlayer(a) then + a:teleportTo(center, true) + creature:teleportTo(center2, true) + end + end + end +return true +end diff --git a/data/spells/scripts/monster/prince drazzak wave.lua b/data/spells/scripts/monster/prince drazzak wave.lua new file mode 100644 index 00000000000..c0668bb57ed --- /dev/null +++ b/data/spells/scripts/monster/prince drazzak wave.lua @@ -0,0 +1,18 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/pythius the rotten curse.lua b/data/spells/scripts/monster/pythius the rotten curse.lua new file mode 100644 index 00000000000..58afb932dbc --- /dev/null +++ b/data/spells/scripts/monster/pythius the rotten curse.lua @@ -0,0 +1,24 @@ +local combat = {} + +for i = 1, 1 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_CURSED) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + + local damage = i + condition:addDamage(1, 4000, -damage) + for j = 1, 33 do + damage = damage * 1.2 + condition:addDamage(1, 4000, -damage) + end + + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(1, 1)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/pythius the rotten paralyze.lua b/data/spells/scripts/monster/pythius the rotten paralyze.lua new file mode 100644 index 00000000000..5540f338e81 --- /dev/null +++ b/data/spells/scripts/monster/pythius the rotten paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEATTACK) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ICE) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.15, 0, -0.2, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/pythius the rotten summon.lua b/data/spells/scripts/monster/pythius the rotten summon.lua new file mode 100644 index 00000000000..bd3114852d3 --- /dev/null +++ b/data/spells/scripts/monster/pythius the rotten summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + +local area = createCombatArea(AREA_CIRCLE3X3) +combat:setArea(area) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Undead Gladiator", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/quara constrictor electrify.lua b/data/spells/scripts/monster/quara constrictor electrify.lua new file mode 100644 index 00000000000..55b5669012b --- /dev/null +++ b/data/spells/scripts/monster/quara constrictor electrify.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + +local condition = Condition(CONDITION_ENERGY) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(3, 10000, -25) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/quara constrictor freeze.lua b/data/spells/scripts/monster/quara constrictor freeze.lua new file mode 100644 index 00000000000..6490e0e79c4 --- /dev/null +++ b/data/spells/scripts/monster/quara constrictor freeze.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GREEN_RINGS) + +local condition = Condition(CONDITION_FREEZING) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(10, 8000, -8) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/rage summon.lua b/data/spells/scripts/monster/rage summon.lua new file mode 100644 index 00000000000..97043354b41 --- /dev/null +++ b/data/spells/scripts/monster/rage summon.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_NONE) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) + +function onCastSpell(creature, var) + + if rageSummon < 3 then + Game.createMonster("Frenzy", {x=creature:getPosition().x+math.random(-1, 1), y=creature:getPosition().y+math.random(-1, 1), z=creature:getPosition().z}, false, true) + rageSummon = rageSummon + 1 + end + + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ragiaz transform.lua b/data/spells/scripts/monster/ragiaz transform.lua new file mode 100644 index 00000000000..2aa3c9a036d --- /dev/null +++ b/data/spells/scripts/monster/ragiaz transform.lua @@ -0,0 +1,13 @@ +function onCastSpell(creature, var) + local pos = creature:getPosition() + if pos.z ~= 13 then + return + end + pos:sendMagicEffect(172) + creature:say('Ragiaz encase himself in bones to regenerate.', TALKTYPE_MONSTER_SAY) + creature:teleportTo(Position(33487, 32333, 14)) + creature:addHealth(1000) + local capsule = Tile(Position(33485, 32333, 14)):getTopCreature() + capsule:teleportTo(pos) + return +end diff --git a/data/spells/scripts/monster/raging mage skill reducer 1.lua b/data/spells/scripts/monster/raging mage skill reducer 1.lua new file mode 100644 index 00000000000..d3824a6b34b --- /dev/null +++ b/data/spells/scripts/monster/raging mage skill reducer 1.lua @@ -0,0 +1,16 @@ +local combat = {} + +for i = 35, 55 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 15000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(35, 55)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/raging mage skill reducer 2.lua b/data/spells/scripts/monster/raging mage skill reducer 2.lua new file mode 100644 index 00000000000..83e7fc73fb2 --- /dev/null +++ b/data/spells/scripts/monster/raging mage skill reducer 2.lua @@ -0,0 +1,36 @@ +local combat = {} + +for i = 35, 55 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 15000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + combat[i]:addCondition(condition) + + arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + + +function onCastSpell(creature, var) + return combat[math.random(35, 55)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ravennousLavaLurkerTarget.lua b/data/spells/scripts/monster/ravennousLavaLurkerTarget.lua new file mode 100644 index 00000000000..8d883e997b5 --- /dev/null +++ b/data/spells/scripts/monster/ravennousLavaLurkerTarget.lua @@ -0,0 +1,39 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREATTACK) + +combat:setArea(createCombatArea({ +{0, 0, 0, 0, 0, 0, 0}, +{0, 0, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 0}, +{1, 1, 1, 1, 1, 1, 1}, +{1, 1, 1, 3, 1, 1, 1}, +{1, 1, 1, 1, 1, 1, 1}, +{0, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 0, 0}, +{0, 0, 0, 0, 0, 0, 0}, +})) + +local monsters = { + "lost gnome", + "gnome pack crawler" +} + +function onTargetTile(cid, pos) + local tile = Tile(pos) + if tile then + local target = tile:getTopCreature() + if target and target:isMonster() then + if table.contains(monsters, target:getName():lower()) then + target:addHealth(-(math.random(0, 1000))) + end + end + end + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ravennousLavaLurkerWave.lua b/data/spells/scripts/monster/ravennousLavaLurkerWave.lua new file mode 100644 index 00000000000..804a79ad34c --- /dev/null +++ b/data/spells/scripts/monster/ravennousLavaLurkerWave.lua @@ -0,0 +1,35 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYFIRE) + +combat:setArea(createCombatArea({ +{0, 1, 1, 1, 0}, +{1, 1, 1, 1, 1}, +{1, 1, 3, 1, 1}, +{1, 1, 1, 1, 1}, +{0, 1, 1, 1, 0}, +})) + +local monsters = { + "lost gnome", + "gnome pack crawler" +} + +function onTargetTile(cid, pos) + local tile = Tile(pos) + if tile then + local target = tile:getTopCreature() + if target and target:isMonster() then + if table.contains(monsters, target:getName():lower()) then + target:addHealth(-(math.random(0, 1000))) + end + end + end + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ravennousLavaLurkerWave2.lua b/data/spells/scripts/monster/ravennousLavaLurkerWave2.lua new file mode 100644 index 00000000000..41ffef6b6c0 --- /dev/null +++ b/data/spells/scripts/monster/ravennousLavaLurkerWave2.lua @@ -0,0 +1,35 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYFIRE) + +combat:setArea(createCombatArea({ +{1}, +{1}, +{1}, +{1}, +{3}, +})) + +local monsters = { + "lost gnome", + "gnome pack crawler" +} + +function onTargetTile(cid, pos) + local tile = Tile(pos) + if tile then + local target = tile:getTopCreature() + if target and target:isMonster() then + if table.contains(monsters, target:getName():lower()) then + target:addHealth(-(math.random(0, 1000))) + end + end + end + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/razzagorn summon.lua b/data/spells/scripts/monster/razzagorn summon.lua new file mode 100644 index 00000000000..2ed3c157021 --- /dev/null +++ b/data/spells/scripts/monster/razzagorn summon.lua @@ -0,0 +1,9 @@ +function onCastSpell(creature, var) + for i = 1, 4 do + local mid = Game.createMonster("Demon", Position(math.random(33416, 33431), math.random(32460, 32474), 14), true, true) + if not mid then + return + end + end + return +end diff --git a/data/spells/scripts/monster/reality reaver wave.lua b/data/spells/scripts/monster/reality reaver wave.lua new file mode 100644 index 00000000000..55e6b0d8573 --- /dev/null +++ b/data/spells/scripts/monster/reality reaver wave.lua @@ -0,0 +1,10 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT) + +local area = createCombatArea(AREA_SQUAREWAVE7) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/remorseless wave.lua b/data/spells/scripts/monster/remorseless wave.lua new file mode 100644 index 00000000000..dfce3e631af --- /dev/null +++ b/data/spells/scripts/monster/remorseless wave.lua @@ -0,0 +1,44 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BLACKSMOKE) + +combat:setArea(createCombatArea({ +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0} +})) + +function spellCallback(param) + local tile = Tile(Position(param.pos)) + if tile then + if tile:getTopCreature() and tile:getTopCreature():isPlayer() then + tile:getTopCreature():addHealth( - math.random(0, 600)) + elseif tile:getTopCreature() and tile:getTopCreature():isMonster() then + if tile:getTopCreature():getName():lower() == "stolen soul" then + tile:getTopCreature():addHealth( - math.random(700, 1500)) + end + end + end +end + +function onTargetTile(cid, pos) + local param = {} + param.cid = cid + param.pos = pos + param.count = 0 + spellCallback(param) +end + +setCombatCallback(combat, CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/renegade knight.lua b/data/spells/scripts/monster/renegade knight.lua new file mode 100644 index 00000000000..5826af0f740 --- /dev/null +++ b/data/spells/scripts/monster/renegade knight.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, 6) +combat:setArea(createCombatArea(AREA_SQUARE1X1)) + +local condition = Condition(COMBAT_PHYSICALDAMAGE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(3, 10000, -25) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/retching horror paralyze.lua b/data/spells/scripts/monster/retching horror paralyze.lua new file mode 100644 index 00000000000..991b1d41d8f --- /dev/null +++ b/data/spells/scripts/monster/retching horror paralyze.lua @@ -0,0 +1,15 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.55, 0, -0.75, 0) + combat:addCondition(condition) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/rift brood electrify.lua b/data/spells/scripts/monster/rift brood electrify.lua new file mode 100644 index 00000000000..83c38d30957 --- /dev/null +++ b/data/spells/scripts/monster/rift brood electrify.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + +local condition = Condition(CONDITION_ENERGY) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(10, 10000, -25) +combat:addCondition(condition) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/root_branchy_rotten.lua b/data/spells/scripts/monster/root_branchy_rotten.lua new file mode 100644 index 00000000000..4822d5ea067 --- /dev/null +++ b/data/spells/scripts/monster/root_branchy_rotten.lua @@ -0,0 +1,11 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ROOTS) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_LEAFSTAR) + +local condition = Condition(CONDITION_ROOTED) +condition:setParameter(CONDITION_PARAM_TICKS, 3000) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/rot elemental paralyze.lua b/data/spells/scripts/monster/rot elemental paralyze.lua new file mode 100644 index 00000000000..6a6e35f3ec3 --- /dev/null +++ b/data/spells/scripts/monster/rot elemental paralyze.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_GREEN) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.45, 0, -0.65, 0) +combat:addCondition(condition) + + +local area = createCombatArea(AREA_CIRCLE2X2) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/rupture wave.lua b/data/spells/scripts/monster/rupture wave.lua new file mode 100644 index 00000000000..dc7efd0edef --- /dev/null +++ b/data/spells/scripts/monster/rupture wave.lua @@ -0,0 +1,10 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_PURPLEENERGY) + +local area = createCombatArea(AREA_WAVE11) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/rustheap golem electrify.lua b/data/spells/scripts/monster/rustheap golem electrify.lua new file mode 100644 index 00000000000..fde210d34c5 --- /dev/null +++ b/data/spells/scripts/monster/rustheap golem electrify.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + +local condition = Condition(CONDITION_ENERGY) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(17, 10000, -25) +combat:addCondition(condition) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/rustheap golem wave.lua b/data/spells/scripts/monster/rustheap golem wave.lua new file mode 100644 index 00000000000..3a7ae865350 --- /dev/null +++ b/data/spells/scripts/monster/rustheap golem wave.lua @@ -0,0 +1,18 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_LIFEDRAIN) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BLACKSMOKE) + + arr = { + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/salamander trainer summon.lua b/data/spells/scripts/monster/salamander trainer summon.lua new file mode 100644 index 00000000000..22f0b9daf36 --- /dev/null +++ b/data/spells/scripts/monster/salamander trainer summon.lua @@ -0,0 +1,20 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_RED) + +local area = createCombatArea(AREA_CIRCLE1X1) +combat:setArea(area) + +local maxsummons = 1 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 1 then + mid = Game.createMonster("Troll-trained Salamander", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/sea serpent drown.lua b/data/spells/scripts/monster/sea serpent drown.lua new file mode 100644 index 00000000000..8f43363e027 --- /dev/null +++ b/data/spells/scripts/monster/sea serpent drown.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_DROWNDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_WATERSPLASH) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGYBALL) + +local condition = Condition(CONDITION_DROWN) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(6, 5000, -20) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/seacrest serpent wave.lua b/data/spells/scripts/monster/seacrest serpent wave.lua new file mode 100644 index 00000000000..014c0cc48bb --- /dev/null +++ b/data/spells/scripts/monster/seacrest serpent wave.lua @@ -0,0 +1,19 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_WATERSPLASH) + + arr = { + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/serpent spawn paralyze.lua b/data/spells/scripts/monster/serpent spawn paralyze.lua new file mode 100644 index 00000000000..260d6da8000 --- /dev/null +++ b/data/spells/scripts/monster/serpent spawn paralyze.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GREEN_RINGS) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.6, 0, -0.8, 0) +combat:addCondition(condition) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/shaburak wave.lua b/data/spells/scripts/monster/shaburak wave.lua new file mode 100644 index 00000000000..96e3e081197 --- /dev/null +++ b/data/spells/scripts/monster/shaburak wave.lua @@ -0,0 +1,18 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREATTACK) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/shadow hound curse.lua b/data/spells/scripts/monster/shadow hound curse.lua new file mode 100644 index 00000000000..84ce11871a4 --- /dev/null +++ b/data/spells/scripts/monster/shadow hound curse.lua @@ -0,0 +1,31 @@ +local combat = {} + +for i = 1, 1 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + + local condition = Condition(CONDITION_CURSED) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + + local damage = i + condition:addDamage(1, 4000, -damage) + for j = 1, 12 do + damage = damage * 1.25 + condition:addDamage(1, 4000, -damage) + end + + local area = createCombatArea({ + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + }) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(1, 1)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/shargon heal.lua b/data/spells/scripts/monster/shargon heal.lua new file mode 100644 index 00000000000..708434e8538 --- /dev/null +++ b/data/spells/scripts/monster/shargon heal.lua @@ -0,0 +1,19 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) + +function onCastSpell(creature, var) + local msg = "Shargon absorbs necromantic energy to regenerate!" + local spectators, spectator = Game.getSpectators(creature:getPosition(), false, false, 10, 10, 10, 10) + for i = 1, #spectators do + spectator = spectators[i] + if spectator:isMonster() and spectator:getName() == "Necromantic Energy" then + spectator:getPosition():sendMagicEffect(CONST_ME_POFF) + spectator:remove() + creature:say(msg, TALKTYPE_ORANGE_1) + creature:addHealth(65000) + creature:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + return true + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/shlorg paralyze.lua b/data/spells/scripts/monster/shlorg paralyze.lua new file mode 100644 index 00000000000..3bff927b76c --- /dev/null +++ b/data/spells/scripts/monster/shlorg paralyze.lua @@ -0,0 +1,15 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLPLANTS) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.40, 0, -0.55, 0) + + local area = createCombatArea(AREA_SQUARE1X1) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/shock head paralyze.lua b/data/spells/scripts/monster/shock head paralyze.lua new file mode 100644 index 00000000000..027ad61cc9e --- /dev/null +++ b/data/spells/scripts/monster/shock head paralyze.lua @@ -0,0 +1,25 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_PURPLEENERGY) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.5, 0, -0.75, 0) +combat:addCondition(condition) + + local area = createCombatArea({ + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + }) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/shock head skill reducer 1.lua b/data/spells/scripts/monster/shock head skill reducer 1.lua new file mode 100644 index 00000000000..075d2593057 --- /dev/null +++ b/data/spells/scripts/monster/shock head skill reducer 1.lua @@ -0,0 +1,34 @@ +local combat = {} + +for i = 15, 30 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_STUN) + +arr = { +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, +} + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 6000) + condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + + local area = createCombatArea(arr) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(15, 30)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/shock head skill reducer 2.lua b/data/spells/scripts/monster/shock head skill reducer 2.lua new file mode 100644 index 00000000000..e93d51276b8 --- /dev/null +++ b/data/spells/scripts/monster/shock head skill reducer 2.lua @@ -0,0 +1,30 @@ +local combat = {} + +for i = 20, 50 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 6000) + condition:setParameter(CONDITION_PARAM_STAT_MAGICPOINTSPERCENT, i) + +arr = { +{0, 0, 0, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 0}, +{1, 1, 1, 1, 1, 1, 1, 1, 1}, +{1, 1, 1, 1, 3, 1, 1, 1, 1}, +{1, 1, 1, 1, 1, 1, 1, 1 ,1}, +{0, 1, 1, 1, 1, 1, 1, 1 ,0}, +{0, 0, 1, 1, 1, 1, 1, 0 ,0}, +{0, 0, 0, 1, 1, 1, 0, 0, 0} +} + + local area = createCombatArea(arr) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(20, 50)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/shulgrax summon.lua b/data/spells/scripts/monster/shulgrax summon.lua new file mode 100644 index 00000000000..e6230646f7a --- /dev/null +++ b/data/spells/scripts/monster/shulgrax summon.lua @@ -0,0 +1,19 @@ +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 8 then + for i = 1, 4 do + local mid = Game.createMonster("Sin Devourer", Position(math.random(33478, 33491), math.random(32781, 32793), 13), true, true) + if not mid then + return + end + mid:setMaster(creature) + end + for i = 1, 4 do + local mid2 = Game.createMonster("Damned Soul", Position(math.random(33478, 33491), math.random(32781, 32793), 13), true, true) + if not mid2 then + return + end + end + end + return +end diff --git a/data/spells/scripts/monster/silencer skill reducer.lua b/data/spells/scripts/monster/silencer skill reducer.lua new file mode 100644 index 00000000000..d5dce1d509b --- /dev/null +++ b/data/spells/scripts/monster/silencer skill reducer.lua @@ -0,0 +1,19 @@ +local combat = {} + +for i = 40, 70 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 7000) + condition:setParameter(CONDITION_PARAM_STAT_MAGICPOINTSPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(40, 70)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/sir valorcrest summon.lua b/data/spells/scripts/monster/sir valorcrest summon.lua new file mode 100644 index 00000000000..be6f73d62dd --- /dev/null +++ b/data/spells/scripts/monster/sir valorcrest summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_NONE) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 4 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 4 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Vampire", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/slime puddle paralyze.lua b/data/spells/scripts/monster/slime puddle paralyze.lua new file mode 100644 index 00000000000..0b537ebccf3 --- /dev/null +++ b/data/spells/scripts/monster/slime puddle paralyze.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GREEN_RINGS) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.85, 0, -0.90, 0) +combat:addCondition(condition) + + +local area = createCombatArea(AREA_SQUARE1X1) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/soulcatcher summon.lua b/data/spells/scripts/monster/soulcatcher summon.lua new file mode 100644 index 00000000000..6b661bd8a76 --- /dev/null +++ b/data/spells/scripts/monster/soulcatcher summon.lua @@ -0,0 +1,11 @@ +function onCastSpell(creature, var) + if creature:getCondition(CONDITION_POISON) or creature:getCondition(CONDITION_BLEEDING) then + local pos = creature:getPosition() + pos.y = pos.y - 1 + Game.createMonster('corrupted soul', pos, true, true) + creature:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + else + return + end + return true +end diff --git a/data/spells/scripts/monster/souleater drown.lua b/data/spells/scripts/monster/souleater drown.lua new file mode 100644 index 00000000000..be7c33895a1 --- /dev/null +++ b/data/spells/scripts/monster/souleater drown.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_DROWNDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + +local condition = Condition(CONDITION_DROWN) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(10, 5000, -20) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/souleater wave.lua b/data/spells/scripts/monster/souleater wave.lua new file mode 100644 index 00000000000..769e1f3a02a --- /dev/null +++ b/data/spells/scripts/monster/souleater wave.lua @@ -0,0 +1,18 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_LIFEDRAINDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_RED) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/source of corruption wave.lua b/data/spells/scripts/monster/source of corruption wave.lua new file mode 100644 index 00000000000..c5f3563287a --- /dev/null +++ b/data/spells/scripts/monster/source of corruption wave.lua @@ -0,0 +1,36 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_PURPLEENERGY) + +combat:setArea(createCombatArea({ +{0, 0, 0, 0, 0}, +{0, 1, 3, 1, 0}, +{0, 0, 0, 0, 0} +})) + +function spellCallback(param) + local tile = Tile(Position(param.pos)) + if tile then + if tile:getTopCreature() and tile:getTopCreature():isPlayer() then + tile:getTopCreature():addHealth( - math.random(0, 600)) + elseif tile:getTopCreature() and tile:getTopCreature():isMonster() then + if tile:getTopCreature():getName():lower() == "stolen soul" then + tile:getTopCreature():addHealth( - math.random(700, 1500)) + end + end + end +end + +function onTargetTile(cid, pos) + local param = {} + param.cid = cid + param.pos = pos + param.count = 0 + spellCallback(param) +end + +setCombatCallback(combat, CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/spawn of the welter heal.lua b/data/spells/scripts/monster/spawn of the welter heal.lua new file mode 100644 index 00000000000..c02329df8d0 --- /dev/null +++ b/data/spells/scripts/monster/spawn of the welter heal.lua @@ -0,0 +1,42 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) + +arr = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onTargetCreature(creature, target) + local min = 200 + local max = 700 + + local master = target:getMaster() + if target:isPlayer() and not master + or master and master:isPlayer() then + return true + end + + doTargetCombatHealth(0, target, COMBAT_HEALING, min, max, CONST_ME_NONE) + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/spawn of the welter heal2.lua b/data/spells/scripts/monster/spawn of the welter heal2.lua new file mode 100644 index 00000000000..ac9c3c73786 --- /dev/null +++ b/data/spells/scripts/monster/spawn of the welter heal2.lua @@ -0,0 +1,26 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) + +local area = createCombatArea(AREA_CIRCLE3X3) +combat:setArea(area) + +function onTargetCreature(creature, target) + local min = 200 + local max = 300 + + local master = target:getMaster() + if target:isPlayer() and not master + or master and master:isPlayer() then + return true + end + + doTargetCombatHealth(0, target, COMBAT_HEALING, min, max, CONST_ME_NONE) + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/spectre drown.lua b/data/spells/scripts/monster/spectre drown.lua new file mode 100644 index 00000000000..639d1211b4e --- /dev/null +++ b/data/spells/scripts/monster/spectre drown.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_DROWNDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN) + +local condition = Condition(CONDITION_DROWN) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(20, 5000, -20) + +local area = createCombatArea(AREA_CIRCLE3X3) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/spider_queen_wrap.lua b/data/spells/scripts/monster/spider_queen_wrap.lua new file mode 100644 index 00000000000..8dbbe3ba0a9 --- /dev/null +++ b/data/spells/scripts/monster/spider_queen_wrap.lua @@ -0,0 +1,33 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYPOISON) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) + +local conditionParalize = Condition(CONDITION_PARALYZE) +conditionParalize:setParameter(CONDITION_PARAM_TICKS, 30000) +conditionParalize:setFormula(-0.3, 0, -0.45, 0) +combat:addCondition(conditionParalize) + +local conditionOutfit = Condition(CONDITION_OUTFIT) +conditionOutfit:setTicks(30000) +conditionOutfit:setOutfit({lookType = 422}) + +local function moveToSpiderNest(uid) + local player = Player(uid) + if player then + player:teleportTo({x = 32013, y = 32087, z = 10}) + end +end + +function onCastSpell(creature, var) + local target = creature:getTarget() + if target and target:isPlayer() then + if combat:execute(creature, var) then + target:addCondition(conditionOutfit) + target:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The spider queen caught you in her net and paralysed you!") + target:setStorageValue(Storage.TheRookieGuard.Mission05, 4) + addEvent(moveToSpiderNest, 4500, target:getId()) + return true + end + end + return false +end diff --git a/data/spells/scripts/monster/spirit of earth paralyze.lua b/data/spells/scripts/monster/spirit of earth paralyze.lua new file mode 100644 index 00000000000..18e011045e1 --- /dev/null +++ b/data/spells/scripts/monster/spirit of earth paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SLEEP) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.6, 0, -0.65, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/spitter paralyze.lua b/data/spells/scripts/monster/spitter paralyze.lua new file mode 100644 index 00000000000..8b4a50459a1 --- /dev/null +++ b/data/spells/scripts/monster/spitter paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_EARTH) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.55, 0, -0.7, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/stampor skill reducer.lua b/data/spells/scripts/monster/stampor skill reducer.lua new file mode 100644 index 00000000000..094ea22d601 --- /dev/null +++ b/data/spells/scripts/monster/stampor skill reducer.lua @@ -0,0 +1,21 @@ +local combat = {} + +for i = 60, 85 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLPLANTS) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 25000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + + local area = createCombatArea(AREA_BEAM1) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(60, 85)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/stone devourer paralyze.lua b/data/spells/scripts/monster/stone devourer paralyze.lua new file mode 100644 index 00000000000..8ba310afeba --- /dev/null +++ b/data/spells/scripts/monster/stone devourer paralyze.lua @@ -0,0 +1,29 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GROUNDSHAKER) + + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.50, 0, -0.60, 0) +combat:addCondition(condition) + +arr = { +{0, 0, 0, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 0, 0}, +{0, 1, 1, 1, 1, 1, 1, 1, 0}, +{1, 1, 1, 1, 1, 1, 1, 1, 1}, +{1, 1, 1, 1, 3, 1, 1, 1, 1}, +{1, 1, 1, 1, 1, 1, 1, 1 ,1}, +{0, 1, 1, 1, 1, 1, 1, 1 ,0}, +{0, 0, 1, 1, 1, 1, 1, 0 ,0}, +{0, 0, 0, 1, 1, 1, 0, 0, 0} +} + +local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/summonchallenge.lua b/data/spells/scripts/monster/summonchallenge.lua new file mode 100644 index 00000000000..cbd3643b3e1 --- /dev/null +++ b/data/spells/scripts/monster/summonchallenge.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setArea(createCombatArea(AREA_CIRCLE2X2)) + +function onTargetCreature(creature, target) + return doChallengeCreature(creature, target) +end + +combat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") + +function onCastSpell(creature, variant) + return combat:execute(creature, variant) +end diff --git a/data/spells/scripts/monster/svoren the mad paralyze.lua b/data/spells/scripts/monster/svoren the mad paralyze.lua new file mode 100644 index 00000000000..e081e3de614 --- /dev/null +++ b/data/spells/scripts/monster/svoren the mad paralyze.lua @@ -0,0 +1,15 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_WHITE) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.75, 0, -0.85, 0) + combat:addCondition(condition) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/swampling paralyze.lua b/data/spells/scripts/monster/swampling paralyze.lua new file mode 100644 index 00000000000..05cdd88776a --- /dev/null +++ b/data/spells/scripts/monster/swampling paralyze.lua @@ -0,0 +1,20 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, 2) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 4000) +condition:setFormula(-0.1, 0, -0.1, 0) + +arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/tanjis skill reducer.lua b/data/spells/scripts/monster/tanjis skill reducer.lua new file mode 100644 index 00000000000..3d32a557195 --- /dev/null +++ b/data/spells/scripts/monster/tanjis skill reducer.lua @@ -0,0 +1,16 @@ +local combat = {} + +for i = 35, 60 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_STUN) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 15000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(35, 60)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/tarbaz tp.lua b/data/spells/scripts/monster/tarbaz tp.lua new file mode 100644 index 00000000000..2986b9f9d1b --- /dev/null +++ b/data/spells/scripts/monster/tarbaz tp.lua @@ -0,0 +1,22 @@ +local function teleport(fromPosition, toPosition) + for x = fromPosition.x, toPosition.x do + for y = fromPosition.y, toPosition.y do + for z = fromPosition.z, toPosition.z do + local creature = Tile(Position(x, y, z)):getTopCreature() + if creature then + if creature:isPlayer() then + creature:teleportTo(Position(33454, 32872, 12)) + end + end + end + end + end +end + + + + +function onCastSpell(creature, var) + teleport(Position(33449, 32834, 11), Position(33470, 32854, 11)) + return true +end diff --git a/data/spells/scripts/monster/tenebris summon.lua b/data/spells/scripts/monster/tenebris summon.lua new file mode 100644 index 00000000000..ef34648cd31 --- /dev/null +++ b/data/spells/scripts/monster/tenebris summon.lua @@ -0,0 +1,12 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + +function onCastSpell(creature, var) + local mid = Game.createMonster("shadow fiend", Position(math.random(32906, 32918), math.random(31594, 31604), 14)) + if not mid then + return + end + mid:say('The shadow fiend revives!', TALKTYPE_MONSTER_SAY) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/tenebris ultimate.lua b/data/spells/scripts/monster/tenebris ultimate.lua new file mode 100644 index 00000000000..1c3740bacd9 --- /dev/null +++ b/data/spells/scripts/monster/tenebris ultimate.lua @@ -0,0 +1,94 @@ +local vocation = { + VOCATION.CLIENT_ID.SORCERER, + VOCATION.CLIENT_ID.DRUID, + VOCATION.CLIENT_ID.PALADIN, + VOCATION.CLIENT_ID.KNIGHT +} + +area = { + {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0} +} + +local createArea = createCombatArea(area) + +local combat = Combat() +combat:setArea(createArea) + +function onTargetTile(creature, pos) + local creatureTable = {} + local n, i = Tile({x=pos.x, y=pos.y, z=pos.z}).creatures, 1 + if n ~= 0 then + local v = getThingfromPos({x=pos.x, y=pos.y, z=pos.z, stackpos=i}).uid + while v ~= 0 do + if isCreature(v) == true then + table.insert(creatureTable, v) + if n == #creatureTable then + break + end + end + i = i + 1 + v = getThingfromPos({x=pos.x, y=pos.y, z=pos.z, stackpos=i}).uid + end + end + if #creatureTable ~= nil and #creatureTable > 0 then + for r = 1, #creatureTable do + if creatureTable[r] ~= creature then + local min = 2200 + local max = 2500 + local player = Player(creatureTable[r]) + + if isPlayer(creatureTable[r]) == true and table.contains(vocation, player:getVocation():getClientId()) then + doTargetCombatHealth(creature, creatureTable[r], COMBAT_DEATHDAMAGE, -min, -max, CONST_ME_NONE) + elseif isMonster(creatureTable[r]) == true then + doTargetCombatHealth(creature, creatureTable[r], COMBAT_DEATHDAMAGE, -min, -max, CONST_ME_NONE) + end + end + end + end + pos:sendMagicEffect(CONST_ME_MORTAREA) + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +local function delayedCastSpell(cid, var) + local creature = Creature(cid) + if not creature then + return + end + if creature:getHealth() >= 1 then + creature:setMoveLocked(false) + return combat:execute(creature, positionToVariant(creature:getPosition())) + end + return +end + +function onCastSpell(creature, var) + local specs, spec = Game.getSpectators(Position(32912, 31599, 14), false, false, 12, 12, 12, 12) + for i = 1, #specs do + spec = specs[i] + if spec:isPlayer() then + spec:teleportTo(Position(32912, 31599, 14)) + elseif spec:getName():lower() == 'lady tenebris' then + spec:teleportTo(Position(32912, 31599, 14)) + spec:setMoveLocked(true) + end + end + creature:say("LADY TENEBRIS BEGINS TO CHANNEL A POWERFULL SPELL! TAKE COVER!", TALKTYPE_MONSTER_YELL) + addEvent(delayedCastSpell, 4000, creature:getId(), var) + return true +end diff --git a/data/spells/scripts/monster/terofar curse.lua b/data/spells/scripts/monster/terofar curse.lua new file mode 100644 index 00000000000..0883eed38e3 --- /dev/null +++ b/data/spells/scripts/monster/terofar curse.lua @@ -0,0 +1,35 @@ +local combat = {} +local condition2 = Condition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) +condition2:setParameter(CONDITION_PARAM_SUBID, 88888) +condition2:setParameter(CONDITION_PARAM_TICKS, 15 * 60 * 1000) +condition2:setParameter(CONDITION_PARAM_HEALTHGAIN, 0.01) +condition2:setParameter(CONDITION_PARAM_HEALTHTICKS, 15 * 60 * 1000) + +for i = 0.935, 0.935 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_DEATH) + + local condition = Condition(CONDITION_CURSED) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + + local damage = i + condition:addDamage(1, 4000, -damage) + for j = 1, 38 do + damage = damage * 1.2 + condition:addDamage(1, 4000, -damage) + end + + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + if not creature:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, 88888) then + creature:addCondition(condition2) + creature:say("Terofar cast a greater death curse on you!", TALKTYPE_ORANGE_1) + else + return false + end +return combat[math.random(0.935, 0.935)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/terofar heal.lua b/data/spells/scripts/monster/terofar heal.lua new file mode 100644 index 00000000000..0dca9ba80bc --- /dev/null +++ b/data/spells/scripts/monster/terofar heal.lua @@ -0,0 +1,42 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_DRAWBLOOD) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) + +arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onTargetCreature(creature, target) + local min = 300 + local max = 500 + + local master = target:getMaster() + if target:isPlayer() and not master + or master and master:isPlayer() then + return true + end + + doTargetCombatHealth(0, target, COMBAT_HEALING, min, max, CONST_ME_NONE) + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/terofar skill reducer 1.lua b/data/spells/scripts/monster/terofar skill reducer 1.lua new file mode 100644 index 00000000000..554bb5cfd93 --- /dev/null +++ b/data/spells/scripts/monster/terofar skill reducer 1.lua @@ -0,0 +1,32 @@ +local combat = {} + +for i = 1, 10 do +combat[i] = Combat() +combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + +local condition = Condition(CONDITION_ATTRIBUTES) +condition:setParameter(CONDITION_PARAM_TICKS, 15000) +condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) +condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) +condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) +condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + + local area = createCombatArea({ + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + }) + +combat[i]:setArea(area) +combat[i]:addCondition(condition) + +end + +function onCastSpell(creature, var) + return combat[math.random(1, 10)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/terofar skill reducer 2.lua b/data/spells/scripts/monster/terofar skill reducer 2.lua new file mode 100644 index 00000000000..55b3b752bda --- /dev/null +++ b/data/spells/scripts/monster/terofar skill reducer 2.lua @@ -0,0 +1,29 @@ +local combat = {} + +for i = 1, 10 do +combat[i] = Combat() +combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) + +local condition = Condition(CONDITION_ATTRIBUTES) +condition:setParameter(CONDITION_PARAM_TICKS, 15000) +condition:setParameter(CONDITION_PARAM_STAT_MAGICPOINTSPERCENT, i) + + local area = createCombatArea({ + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + }) + +combat[i]:setArea(area) +combat[i]:addCondition(condition) + +end + +function onCastSpell(creature, var) + return combat[math.random(1, 10)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/thalas summon.lua b/data/spells/scripts/monster/thalas summon.lua new file mode 100644 index 00000000000..9276aa88206 --- /dev/null +++ b/data/spells/scripts/monster/thalas summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_NONE) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 8 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 8 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Slime Summon", { x=creature:getPosition().x+math.random(-2, 2), y=creature:getPosition().y+math.random(-2, 2), z=creature:getPosition().z }) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/the abomination paralyze.lua b/data/spells/scripts/monster/the abomination paralyze.lua new file mode 100644 index 00000000000..0ddae56f187 --- /dev/null +++ b/data/spells/scripts/monster/the abomination paralyze.lua @@ -0,0 +1,31 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POISONAREA) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.75, 0, -0.95, 0) + combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/the abomination summon.lua b/data/spells/scripts/monster/the abomination summon.lua new file mode 100644 index 00000000000..94c0c37fd14 --- /dev/null +++ b/data/spells/scripts/monster/the abomination summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_NONE) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 10 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 10 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Demon Skeleton", { x=creature:getPosition().x+math.random(-2, 2), y=creature:getPosition().y+math.random(-2, 2), z=creature:getPosition().z }) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/the blightfather summon.lua b/data/spells/scripts/monster/the blightfather summon.lua new file mode 100644 index 00000000000..ca305b06679 --- /dev/null +++ b/data/spells/scripts/monster/the blightfather summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_PURPLE) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Lancer Beetle", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/the dark dancer summon.lua b/data/spells/scripts/monster/the dark dancer summon.lua new file mode 100644 index 00000000000..9b2b3f71e9d --- /dev/null +++ b/data/spells/scripts/monster/the dark dancer summon.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_PURPLE) + +local maxsummons = 3 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 3 then + mid = Game.createMonster("Ghoul", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/the dreadorian curse.lua b/data/spells/scripts/monster/the dreadorian curse.lua new file mode 100644 index 00000000000..3c8649b2831 --- /dev/null +++ b/data/spells/scripts/monster/the dreadorian curse.lua @@ -0,0 +1,24 @@ +local combat = {} + +for i = 2, 2 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_DRAWBLOOD) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_CURSED) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + + local damage = i + condition:addDamage(1, 4000, -damage) + for j = 1, 19 do + damage = damage * 1.2 + condition:addDamage(1, 4000, -damage) + end + + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(2, 2)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/the dreadorian drown.lua b/data/spells/scripts/monster/the dreadorian drown.lua new file mode 100644 index 00000000000..c660d0a33ff --- /dev/null +++ b/data/spells/scripts/monster/the dreadorian drown.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_DROWNDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POISONAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON) + +local condition = Condition(CONDITION_DROWN) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(20, 5000, -20) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/the dreadorian soulfire.lua b/data/spells/scripts/monster/the dreadorian soulfire.lua new file mode 100644 index 00000000000..d94642a7abe --- /dev/null +++ b/data/spells/scripts/monster/the dreadorian soulfire.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYFIRE) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(20, 9000, -10) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/the imperor summon.lua b/data/spells/scripts/monster/the imperor summon.lua new file mode 100644 index 00000000000..3e39b171298 --- /dev/null +++ b/data/spells/scripts/monster/the imperor summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_TELEPORT) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Diabolic Imp", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/the pale count bomb.lua b/data/spells/scripts/monster/the pale count bomb.lua new file mode 100644 index 00000000000..7d15e2e7c75 --- /dev/null +++ b/data/spells/scripts/monster/the pale count bomb.lua @@ -0,0 +1,28 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_DEATH) + + arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + creature:say("Feel the hungry kiss of death!", TALKTYPE_ORANGE_1) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/the pale count manadrain.lua b/data/spells/scripts/monster/the pale count manadrain.lua new file mode 100644 index 00000000000..8807979e469 --- /dev/null +++ b/data/spells/scripts/monster/the pale count manadrain.lua @@ -0,0 +1,27 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_MANADRAIN) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_RED) + + arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + creature:say("Feel the hungry kiss of death!", TALKTYPE_ORANGE_1) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/the pale count summon.lua b/data/spells/scripts/monster/the pale count summon.lua new file mode 100644 index 00000000000..5fe63bfe3bd --- /dev/null +++ b/data/spells/scripts/monster/the pale count summon.lua @@ -0,0 +1,23 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BATS) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 4 + +function onCastSpell(creature, var) + creature:say("Out of the dark I call you, fiend in the night!", TALKTYPE_ORANGE_1) + local summoncount = creature:getSummons() + if #summoncount < 4 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Nightfiend", { x=creature:getPosition().x+math.random(-2, 2), y=creature:getPosition().y+math.random(-2, 2), z=creature:getPosition().z }) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/the pale count wave.lua b/data/spells/scripts/monster/the pale count wave.lua new file mode 100644 index 00000000000..b2d0ad90c96 --- /dev/null +++ b/data/spells/scripts/monster/the pale count wave.lua @@ -0,0 +1,20 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/the ravager heal.lua b/data/spells/scripts/monster/the ravager heal.lua new file mode 100644 index 00000000000..0fd9d357906 --- /dev/null +++ b/data/spells/scripts/monster/the ravager heal.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) + +function onCastSpell(creature, var) + local spectators, spectator = Game.getSpectators(creature:getPosition(), false, false, 25, 25, 25, 25) + for i = 1, #spectators do + spectator = spectators[i] + if spectator:isMonster() and spectator:getName() == "Greater Canopic Jar" then + creature:addHealth(10000) + creature:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + return true + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/the voice of ruin paralyze.lua b/data/spells/scripts/monster/the voice of ruin paralyze.lua new file mode 100644 index 00000000000..f7bf00a56d9 --- /dev/null +++ b/data/spells/scripts/monster/the voice of ruin paralyze.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GREEN_RINGS) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.6, 0, -0.75, 0) +combat:addCondition(condition) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/the welter heal.lua b/data/spells/scripts/monster/the welter heal.lua new file mode 100644 index 00000000000..d05d524765c --- /dev/null +++ b/data/spells/scripts/monster/the welter heal.lua @@ -0,0 +1,25 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) + +function onCastSpell(creature, var) + local spectators, spectator = Game.getSpectators(creature:getPosition(), false, false, 10, 10, 10, 10) + for i = 1, #spectators do + spectator = spectators[i] + if spectator:isMonster() and spectator:getName() == "Egg" then + spectator:getPosition():sendMagicEffect(CONST_ME_HITBYPOISON) + spectator:remove() + creature:say("", TALKTYPE_ORANGE_1) + creature:addHealth(25000) + creature:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + return true + elseif spectator:isMonster() and spectator:getName() == "Spawn Of The Welter" then + spectator:getPosition():sendMagicEffect(CONST_ME_DRAWBLOOD) + spectator:remove() + creature:say("", TALKTYPE_ORANGE_1) + creature:addHealth(25000) + creature:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + return true + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/the welter heal2.lua b/data/spells/scripts/monster/the welter heal2.lua new file mode 100644 index 00000000000..e0111eb3e02 --- /dev/null +++ b/data/spells/scripts/monster/the welter heal2.lua @@ -0,0 +1,42 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) + +arr = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onTargetCreature(creature, target) + local min = 100 + local max = 300 + + local master = target:getMaster() + if target:isPlayer() and not master + or master and master:isPlayer() then + return true + end + + doTargetCombatHealth(0, target, COMBAT_HEALING, min, max, CONST_ME_NONE) + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/the welter paralyze.lua b/data/spells/scripts/monster/the welter paralyze.lua new file mode 100644 index 00000000000..32b8634bf5d --- /dev/null +++ b/data/spells/scripts/monster/the welter paralyze.lua @@ -0,0 +1,31 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.7, 0, -0.9, 0) + combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/the welter summon.lua b/data/spells/scripts/monster/the welter summon.lua new file mode 100644 index 00000000000..69e840aa758 --- /dev/null +++ b/data/spells/scripts/monster/the welter summon.lua @@ -0,0 +1,38 @@ +local function delayedCastSpell(cid, var) + local creature = Creature(cid) + if not creature then + return + end + + if creature:getName(creature:getMaster()) == "The Welter" then + local summon = creature:getSummons() + for i = 1, #summon do + if summon[i]:getName() == "Egg" then + summon[i]:getPosition():sendMagicEffect(CONST_ME_POISONAREA) + local newmon = Game.createMonster("Spawn Of The Welter", summon[i]:getPosition(), false, true) + summon[i]:remove() + if not newmon then + return + end + newmon:setMaster(creature) + end + end + end +end + +local maxsummons = 1 + +function onCastSpell(creature, var) +local summoncount = creature:getSummons() + if #summoncount < 1 then + for i = 1, maxsummons - #summoncount do + local mon = Game.createMonster("Egg", creature:getPosition()) + if not mon then + return + end + mon:setMaster(creature) + end + end + addEvent(delayedCastSpell, 10000, creature:getId(), var) + return true +end diff --git a/data/spells/scripts/monster/the welter summon2.lua b/data/spells/scripts/monster/the welter summon2.lua new file mode 100644 index 00000000000..5233f659c6c --- /dev/null +++ b/data/spells/scripts/monster/the welter summon2.lua @@ -0,0 +1,18 @@ +function onCastSpell(creature, var) +local t, spectator = Game.getSpectators(creature:getPosition(), false, false, 50, 50, 50, 50) + local check = 0 + if #t ~= nil then + for i = 1, #t do + spectator = t[i] + if spectator:getName() == "Egg" or spectator:getName() == "Spawn Of The Welter" then + check = check + 1 + end + end + end + if (check < 10) then + creature:getPosition():sendMagicEffect(CONST_ME_GREEN_RINGS) + Game.createMonster("Egg", creature:getPosition(), false, true) + else + end +return true +end diff --git a/data/spells/scripts/monster/thorn summon.lua b/data/spells/scripts/monster/thorn summon.lua new file mode 100644 index 00000000000..3467883ee50 --- /dev/null +++ b/data/spells/scripts/monster/thorn summon.lua @@ -0,0 +1,12 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + +function onCastSpell(creature, var) + local creaturePos = creature:getPosition() + local mid = Game.createMonster('thorn minion', Position(creaturePos.x + math.random(-3, 3), creaturePos.y + math.random(-3, 3), creaturePos.z), true, false) + if not mid then + return + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/thul paralyze.lua b/data/spells/scripts/monster/thul paralyze.lua new file mode 100644 index 00000000000..98bed30906a --- /dev/null +++ b/data/spells/scripts/monster/thul paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SNOWBALL) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 10000) + condition:setFormula(-0.8, 0, -0.9, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/thul summon.lua b/data/spells/scripts/monster/thul summon.lua new file mode 100644 index 00000000000..6b60cb7c0df --- /dev/null +++ b/data/spells/scripts/monster/thul summon.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_LOSEENERGY) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + mid = Game.createMonster("Massive Water Elemental", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end +return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/time guardian lost time.lua b/data/spells/scripts/monster/time guardian lost time.lua new file mode 100644 index 00000000000..cb315fcff57 --- /dev/null +++ b/data/spells/scripts/monster/time guardian lost time.lua @@ -0,0 +1,12 @@ +function onCastSpell(creature, var) + local pos = creature:getPosition() + if pos.z ~= 15 then + return true + end + if creature:getName():lower() == 'the freezing time guardian' then + Game.createMonster('lost time', { x=creature:getPosition().x+math.random(-2, 2), y=creature:getPosition().y+math.random(-2, 2), z=creature:getPosition().z }) + elseif creature:getName():lower() == 'the blazing time guardian' then + Game.createMonster('time waster', { x=creature:getPosition().x+math.random(-2, 2), y=creature:getPosition().y+math.random(-2, 2), z=creature:getPosition().z }) + end + return true +end diff --git a/data/spells/scripts/monster/time guardian.lua b/data/spells/scripts/monster/time guardian.lua new file mode 100644 index 00000000000..316d4a9a025 --- /dev/null +++ b/data/spells/scripts/monster/time guardian.lua @@ -0,0 +1,50 @@ +local monsters = { + [1] = {pos = Position(32980, 31664, 13)}, + [2] = {pos = Position(32975, 31664, 13)} +} + +local function functionBack(position, oldpos) + local guardian = Tile(position):getTopCreature() + local bool, diference, health = false, 0, 0 + local spectators, spectator = Game.getSpectators(Position(32977, 31662, 14), false, false, 15, 15, 15, 15) + for v = 1, #spectators do + spectator = spectators[v] + if spectator:getName():lower() == 'the freezing time guardian' or spectator:getName():lower() == 'the blazing time guardian' then + oldpos = spectator:getPosition() + bool = true + end + end + if not bool then + guardian:remove() + return true + end + local specs, spec = Game.getSpectators(Position(32977, 31662, 14), false, false, 15, 15, 15, 15) + for i = 1, #specs do + spec = specs[i] + if spec:isMonster() and spec:getName():lower() == 'the freezing time guardian' or spec:getName():lower() == 'the blazing time guardian' then + spec:teleportTo(position) + health = spec:getHealth() + diference = guardian:getHealth() - health + end + end + guardian:addHealth( - diference) + guardian:teleportTo(oldpos) +end + +function onCastSpell(creature, var) + local index = math.random(1, 2) + local monsterPos = creature:getPosition() + if monsterPos.z ~= 14 then + return true + end + local position = monsters[index].pos + local form = Tile(position):getTopCreature() + creature:teleportTo(position) + local diference, health = 0, 0 + health = creature:getHealth() + diference = form:getHealth() - health + form:addHealth( - diference) + form:teleportTo(monsterPos) + addEvent(functionBack, 30 * 1000, position, monsterPos) + return true +end diff --git a/data/spells/scripts/monster/time guardiann.lua b/data/spells/scripts/monster/time guardiann.lua new file mode 100644 index 00000000000..57397aa02c2 --- /dev/null +++ b/data/spells/scripts/monster/time guardiann.lua @@ -0,0 +1,50 @@ +local monsters = { + [1] = {pos = Position(32810, 32664, 14)}, + [2] = {pos = Position(32815, 32664, 14)} +} + +local function functionBack(position, oldpos) + local guardian = Tile(position):getTopCreature() + local bool, diference, health = false, 0, 0 + local spectators, spectator = Game.getSpectators(Position(32813, 32664, 14), false, false, 15, 15, 15, 15) + for v = 1, #spectators do + spectator = spectators[v] + if spectator:getName():lower() == 'the blazing time guardian' or spectator:getName():lower() == 'the freezing time guardian' then + oldpos = spectator:getPosition() + bool = true + end + end + if not bool then + guardian:remove() + return true + end + local specs, spec = Game.getSpectators(Position(32813, 32664, 14), false, false, 15, 15, 15, 15) + for i = 1, #specs do + spec = specs[i] + if spec:isMonster() and spec:getName():lower() == 'the blazing time guardian' or spec:getName():lower() == 'the freezing time guardian' then + spec:teleportTo(position) + health = spec:getHealth() + diference = guardian:getHealth() - health + end + end + guardian:addHealth( - diference) + guardian:teleportTo(oldpos) +end + +function onCastSpell(creature, var) + local index = math.random(1, 2) + local monsterPos = creature:getPosition() + if monsterPos.z ~= 14 then + return true + end + local position = monsters[index].pos + local form = Tile(position):getTopCreature() + creature:teleportTo(position) + local diference, health = 0, 0 + health = creature:getHealth() + diference = form:getHealth() - health + form:addHealth( - diference) + form:teleportTo(monsterPos) + addEvent(functionBack, 30 * 1000, position, monsterPos) + return true +end diff --git a/data/spells/scripts/monster/twins skill reducer.lua b/data/spells/scripts/monster/twins skill reducer.lua new file mode 100644 index 00000000000..bdd1ad83156 --- /dev/null +++ b/data/spells/scripts/monster/twins skill reducer.lua @@ -0,0 +1,32 @@ +local combat = {} + +for i = 10, 25 do +combat[i] = Combat() +combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_TELEPORT) + +local condition = Condition(CONDITION_ATTRIBUTES) +condition:setParameter(CONDITION_PARAM_TICKS, 35000) +condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) +condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + + local area = createCombatArea({ + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + }) + +combat[i]:setArea(area) +combat[i]:addCondition(condition) + +end + +function onCastSpell(creature, var) + return combat[math.random(10, 25)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/twisted shaper ice.lua b/data/spells/scripts/monster/twisted shaper ice.lua new file mode 100644 index 00000000000..451ef68cfe2 --- /dev/null +++ b/data/spells/scripts/monster/twisted shaper ice.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, 53) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SMALLICE) + +function onGetFormulaValues(player, level, maglevel) + local min = (level / 5) + (maglevel * 1.4) + 8 + local max = (level / 5) + (maglevel * 2.2) + 14 + return -min, -max +end + +combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/tyrn electrify.lua b/data/spells/scripts/monster/tyrn electrify.lua new file mode 100644 index 00000000000..957570f6af6 --- /dev/null +++ b/data/spells/scripts/monster/tyrn electrify.lua @@ -0,0 +1,24 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMOKE) + +local condition = Condition(CONDITION_ENERGY) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(30, 10000, -25) +combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/tyrn heal.lua b/data/spells/scripts/monster/tyrn heal.lua new file mode 100644 index 00000000000..2dc1c3779c9 --- /dev/null +++ b/data/spells/scripts/monster/tyrn heal.lua @@ -0,0 +1,15 @@ +local condition = Condition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) +condition:setParameter(CONDITION_PARAM_SUBID, 88888) +condition:setParameter(CONDITION_PARAM_TICKS, 15 * 60 * 1000) +condition:setParameter(CONDITION_PARAM_HEALTHGAIN, 0.01) +condition:setParameter(CONDITION_PARAM_HEALTHTICKS, 15 * 60 * 1000) + +function onCastSpell(creature, var) + if creature:getHealth() < creature:getMaxHealth() * 0.2 and not creature:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, 88888) then + creature:addCondition(condition) + creature:addHealth(math.random(5000, 7500)) + else + return + end + return true +end diff --git a/data/spells/scripts/monster/tyrn skill reducer.lua b/data/spells/scripts/monster/tyrn skill reducer.lua new file mode 100644 index 00000000000..c97d194b646 --- /dev/null +++ b/data/spells/scripts/monster/tyrn skill reducer.lua @@ -0,0 +1,36 @@ +local combat = {} + +for i = 40, 55 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_WHITE) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 12000) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + + arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(40, 55)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/undead cavebear curse.lua b/data/spells/scripts/monster/undead cavebear curse.lua new file mode 100644 index 00000000000..12710822f5f --- /dev/null +++ b/data/spells/scripts/monster/undead cavebear curse.lua @@ -0,0 +1,25 @@ +local combat = {} + +for i = 2, 2 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + + local condition = Condition(CONDITION_CURSED) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + + local damage = i + condition:addDamage(1, 4000, -damage) + for j = 1, 18 do + damage = damage * 1.2 + condition:addDamage(1, 4000, -damage) + end + + local area = createCombatArea(AREA_SQUARE1X1) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(2, 2)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/undead dragon curse.lua b/data/spells/scripts/monster/undead dragon curse.lua new file mode 100644 index 00000000000..0e7dc7f7f89 --- /dev/null +++ b/data/spells/scripts/monster/undead dragon curse.lua @@ -0,0 +1,34 @@ +local combat = {} + +for i = 1, 2 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + + local condition = Condition(CONDITION_CURSED) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + + local damage = i + condition:addDamage(1, 4000, -damage) + for j = 1, 30 do + damage = damage * 1.2 + condition:addDamage(1, 4000, -damage) + end + + local area = createCombatArea({ + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + }) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(1, 2)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/undead jester paralyze.lua b/data/spells/scripts/monster/undead jester paralyze.lua new file mode 100644 index 00000000000..112b64950f3 --- /dev/null +++ b/data/spells/scripts/monster/undead jester paralyze.lua @@ -0,0 +1,28 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GIFT_WRAPS) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.35, 0, -0.5, 0) +combat:addCondition(condition) + + arr = { + {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/undead jester summon.lua b/data/spells/scripts/monster/undead jester summon.lua new file mode 100644 index 00000000000..99912edf8ea --- /dev/null +++ b/data/spells/scripts/monster/undead jester summon.lua @@ -0,0 +1,38 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_RED) + +arr = { +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 1, 3, 1, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +} + +local area = createCombatArea(arr) +combat:setArea(area) + +local maxsummons = 4 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 4 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Cave Rat", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/urmahlullu ring.lua b/data/spells/scripts/monster/urmahlullu ring.lua new file mode 100644 index 00000000000..2e6708a45aa --- /dev/null +++ b/data/spells/scripts/monster/urmahlullu ring.lua @@ -0,0 +1,18 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREAREA) +arr = { +{0, 1, 1, 1, 0}, +{1, 0, 0, 0, 1}, +{1, 0, 2, 0, 1}, +{1, 0, 0, 0, 1}, +{0, 1, 1, 1, 0} +} + + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ushuriel curse.lua b/data/spells/scripts/monster/ushuriel curse.lua new file mode 100644 index 00000000000..c27668648ae --- /dev/null +++ b/data/spells/scripts/monster/ushuriel curse.lua @@ -0,0 +1,25 @@ +local combat = {} + +for i = 1, 1.1 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + + local condition = Condition(CONDITION_CURSED) + condition:setParameter(CONDITION_PARAM_DELAYED, 1) + + local damage = i + condition:addDamage(1, 4000, -damage) + for j = 1, 27 do + damage = damage * 1.2 + condition:addDamage(1, 4000, -damage) + end + + local area = createCombatArea(AREA_CIRCLE3X3) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(1, 1.1)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/ushuriel electrify.lua b/data/spells/scripts/monster/ushuriel electrify.lua new file mode 100644 index 00000000000..663176fd8af --- /dev/null +++ b/data/spells/scripts/monster/ushuriel electrify.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT) + +local condition = Condition(CONDITION_ENERGY) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(25, 10000, -25) +combat:addCondition(condition) + +local area = createCombatArea(AREA_CIRCLE3X3) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/vampire paralyze.lua b/data/spells/scripts/monster/vampire paralyze.lua new file mode 100644 index 00000000000..b52f2b760fe --- /dev/null +++ b/data/spells/scripts/monster/vampire paralyze.lua @@ -0,0 +1,11 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.45, 0, -0.8, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/vampire viscount paralyze.lua b/data/spells/scripts/monster/vampire viscount paralyze.lua new file mode 100644 index 00000000000..e3745215e38 --- /dev/null +++ b/data/spells/scripts/monster/vampire viscount paralyze.lua @@ -0,0 +1,15 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.55, 0, -0.7, 0) + combat:addCondition(condition) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/verminor paralyze.lua b/data/spells/scripts/monster/verminor paralyze.lua new file mode 100644 index 00000000000..028634dc9b2 --- /dev/null +++ b/data/spells/scripts/monster/verminor paralyze.lua @@ -0,0 +1,31 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.75, 0, -0.95, 0) + combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + + local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/verminor summon.lua b/data/spells/scripts/monster/verminor summon.lua new file mode 100644 index 00000000000..7351d509875 --- /dev/null +++ b/data/spells/scripts/monster/verminor summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_NONE) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 6 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 6 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Son of Verminor", { x=creature:getPosition().x+math.random(-2, 2), y=creature:getPosition().y+math.random(-2, 2), z=creature:getPosition().z }) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/vile grandmaster.lua b/data/spells/scripts/monster/vile grandmaster.lua new file mode 100644 index 00000000000..6735d0e7ae7 --- /dev/null +++ b/data/spells/scripts/monster/vile grandmaster.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GROUNDSHAKER) +combat:setArea(createCombatArea(AREA_CIRCLE3X3)) + +local condition = Condition(COMBAT_PHYSICALDAMAGE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(3, 100, -35) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/vulcongra soulfire.lua b/data/spells/scripts/monster/vulcongra soulfire.lua new file mode 100644 index 00000000000..851550ac6b1 --- /dev/null +++ b/data/spells/scripts/monster/vulcongra soulfire.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITBYFIRE) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(20, 9000, -10) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/walker skill reducer.lua b/data/spells/scripts/monster/walker skill reducer.lua new file mode 100644 index 00000000000..6d3938192c7 --- /dev/null +++ b/data/spells/scripts/monster/walker skill reducer.lua @@ -0,0 +1,73 @@ +local combat = {} + +for i = 45, 60 do + combat[i] = Combat() + + local condition1 = Condition(CONDITION_ATTRIBUTES) + condition1:setParameter(CONDITION_PARAM_TICKS, 7000) + condition1:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition1:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + condition1:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + + local condition2 = Condition(CONDITION_ATTRIBUTES) + condition2:setParameter(CONDITION_PARAM_TICKS, 7000) + condition2:setParameter(CONDITION_PARAM_STAT_MAGICPOINTSPERCENT, i) + + local condition3 = Condition(CONDITION_ATTRIBUTES) + condition3:setParameter(CONDITION_PARAM_TICKS, 7000) + condition3:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + condition3:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE3X3) + combat[i]:setArea(area) + + + function onTargetTile(creature, pos) + local creatureTable = {} + local n, i = Tile({x=pos.x, y=pos.y, z=pos.z}).creatures, 1 + if n ~= 0 then + local v = getThingfromPos({x=pos.x, y=pos.y, z=pos.z, stackpos=i}).uid + while v ~= 0 do + if isCreature(v) == true then + table.insert(creatureTable, v) + if n == #creatureTable then + break + end + end + i = i + 1 + v = getThingfromPos({x=pos.x, y=pos.y, z=pos.z, stackpos=i}).uid + end + end + + if #creatureTable ~= nil and #creatureTable > 0 then + for r = 1, #creatureTable do + if creatureTable[r] ~= creature then + local specCreature = Player(creatureTable[r]) + + if specCreature and specCreature:isPlayer() then + if specCreature:isKnight() then + specCreature:addCondition(condition1) + end + + if specCreature:isMage() then + specCreature:addCondition(condition2) + end + + if specCreature:isPaladin() then + specCreature:addCondition(condition3) + end + end + end + end + end + pos:sendMagicEffect(CONST_ME_MAGIC_RED) + return true + end + + combat[i]:setCallback(CALLBACK_PARAM_TARGETTILE, "onTargetTile") + +end + +function onCastSpell(creature, var) + return combat[math.random(45, 60)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/war golem electrify.lua b/data/spells/scripts/monster/war golem electrify.lua new file mode 100644 index 00000000000..bd2cf3926c2 --- /dev/null +++ b/data/spells/scripts/monster/war golem electrify.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGYBALL) + +local condition = Condition(CONDITION_ENERGY) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(8, 10000, -25) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/war golem skill reducer.lua b/data/spells/scripts/monster/war golem skill reducer.lua new file mode 100644 index 00000000000..ddd10e87545 --- /dev/null +++ b/data/spells/scripts/monster/war golem skill reducer.lua @@ -0,0 +1,29 @@ +local combat = {} + +for i = 40, 60 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_STUN) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 8000) + condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + + local arr = { + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + + local area = createCombatArea(arr) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(40, 60)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/warden ring.lua b/data/spells/scripts/monster/warden ring.lua new file mode 100644 index 00000000000..f20e56a47dc --- /dev/null +++ b/data/spells/scripts/monster/warden ring.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GROUNDSHAKER) +arr = { +{0, 1, 1, 1, 0}, +{1, 0, 0, 0, 1}, +{1, 0, 2, 0, 1}, +{1, 0, 0, 0, 1}, +{0, 1, 1, 1, 0} +} + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/warden x.lua b/data/spells/scripts/monster/warden x.lua new file mode 100644 index 00000000000..cf848e59e25 --- /dev/null +++ b/data/spells/scripts/monster/warden x.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GROUNDSHAKER) +arr = { +{1, 0, 1}, +{0, 2, 0}, +{1, 0, 1} +} + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/warlock skill reducer.lua b/data/spells/scripts/monster/warlock skill reducer.lua new file mode 100644 index 00000000000..92083e68d97 --- /dev/null +++ b/data/spells/scripts/monster/warlock skill reducer.lua @@ -0,0 +1,18 @@ +local combat = {} + +for i = 40, 50 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 6000) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(40, 50)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/wave t.lua b/data/spells/scripts/monster/wave t.lua new file mode 100644 index 00000000000..5d92d33ee00 --- /dev/null +++ b/data/spells/scripts/monster/wave t.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GREEN_RINGS) +arr = { +{1, 1, 1}, +{0, 1, 0}, +{0, 3, 0} +} + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/webster paralyze.lua b/data/spells/scripts/monster/webster paralyze.lua new file mode 100644 index 00000000000..c9d5f35ab7b --- /dev/null +++ b/data/spells/scripts/monster/webster paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.5, 0, -0.65, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/weeper paralyze.lua b/data/spells/scripts/monster/weeper paralyze.lua new file mode 100644 index 00000000000..069e1d2a93a --- /dev/null +++ b/data/spells/scripts/monster/weeper paralyze.lua @@ -0,0 +1,24 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BLOCKHIT) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 5000) +condition:setFormula(-0.55, 0, -0.7, 0) +combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/weeper skill reducer.lua b/data/spells/scripts/monster/weeper skill reducer.lua new file mode 100644 index 00000000000..d35835f8025 --- /dev/null +++ b/data/spells/scripts/monster/weeper skill reducer.lua @@ -0,0 +1,18 @@ +local combat = {} + +for i = 15, 55 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 7000) + condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE1X1) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(15, 55)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/werelion_wave.lua b/data/spells/scripts/monster/werelion_wave.lua new file mode 100644 index 00000000000..ea644986b40 --- /dev/null +++ b/data/spells/scripts/monster/werelion_wave.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) + + arr = { + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/werewolf skill reducer.lua b/data/spells/scripts/monster/werewolf skill reducer.lua new file mode 100644 index 00000000000..5cec9959689 --- /dev/null +++ b/data/spells/scripts/monster/werewolf skill reducer.lua @@ -0,0 +1,25 @@ +local combat = {} + +for i = 65, 85 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_RED) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 4000) + condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, i) + condition:setParameter(CONDITION_PARAM_SKILL_FISTPERCENT, i) + + arr = { + {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 3, 1, 0, 0, 0, 0} + } + + local area = createCombatArea(arr) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(65, 85)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/werewolf summon.lua b/data/spells/scripts/monster/werewolf summon.lua new file mode 100644 index 00000000000..d15d814359b --- /dev/null +++ b/data/spells/scripts/monster/werewolf summon.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_WHITE) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("War Wolf", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/white pale heal.lua b/data/spells/scripts/monster/white pale heal.lua new file mode 100644 index 00000000000..3e7ff89f4a1 --- /dev/null +++ b/data/spells/scripts/monster/white pale heal.lua @@ -0,0 +1,15 @@ +local condition = Condition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) +condition:setParameter(CONDITION_PARAM_SUBID, 88888) +condition:setParameter(CONDITION_PARAM_TICKS, 15 * 60 * 1000) +condition:setParameter(CONDITION_PARAM_HEALTHGAIN, 0.01) +condition:setParameter(CONDITION_PARAM_HEALTHTICKS, 15 * 60 * 1000) + +function onCastSpell(creature, var) + if creature:getHealth() < creature:getMaxHealth() * 0.2 and not creature:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, 88888) then + creature:addCondition(condition) + creature:addHealth(400) + else + return + end +return true +end diff --git a/data/spells/scripts/monster/white pale paralyze.lua b/data/spells/scripts/monster/white pale paralyze.lua new file mode 100644 index 00000000000..d6118baef6d --- /dev/null +++ b/data/spells/scripts/monster/white pale paralyze.lua @@ -0,0 +1,24 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.6, 0, -0.65, 0) +combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/white pale summon.lua b/data/spells/scripts/monster/white pale summon.lua new file mode 100644 index 00000000000..5c4c096c7b9 --- /dev/null +++ b/data/spells/scripts/monster/white pale summon.lua @@ -0,0 +1,38 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_NONE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GROUNDSHAKER) + +arr = { +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 1, 3, 1, 1, 1, 1, 0, 0}, +{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, +{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, +{0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +} + +local area = createCombatArea(arr) +combat:setArea(area) + +local maxsummons = 2 + +function onCastSpell(creature, var) + local summoncount = creature:getSummons() + if #summoncount < 2 then + for i = 1, maxsummons - #summoncount do + local mid = Game.createMonster("Carrion Worm", creature:getPosition()) + if not mid then + return + end + mid:setMaster(creature) + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/white shade paralyze.lua b/data/spells/scripts/monster/white shade paralyze.lua new file mode 100644 index 00000000000..699e981102b --- /dev/null +++ b/data/spells/scripts/monster/white shade paralyze.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.3, 0, -0.45, 0) +combat:addCondition(condition) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/wiggler paralyze.lua b/data/spells/scripts/monster/wiggler paralyze.lua new file mode 100644 index 00000000000..2ee2dd25883 --- /dev/null +++ b/data/spells/scripts/monster/wiggler paralyze.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.25, 0, -0.5, 0) +combat:addCondition(condition) + + arr = { + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/wilting leaf golem paralyze.lua b/data/spells/scripts/monster/wilting leaf golem paralyze.lua new file mode 100644 index 00000000000..383bf6f0bc0 --- /dev/null +++ b/data/spells/scripts/monster/wilting leaf golem paralyze.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.25, 0, -0.45, 0) +combat:addCondition(condition) + + +local area = createCombatArea(AREA_SQUARE1X1) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/woodling paralyze.lua b/data/spells/scripts/monster/woodling paralyze.lua new file mode 100644 index 00000000000..f7e08f78998 --- /dev/null +++ b/data/spells/scripts/monster/woodling paralyze.lua @@ -0,0 +1,21 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, 2) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 3000) +condition:setFormula(-0.05, 0, -0.1, 0) + +arr = { + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/worm priestess paralyze.lua b/data/spells/scripts/monster/worm priestess paralyze.lua new file mode 100644 index 00000000000..ce7a94dbd88 --- /dev/null +++ b/data/spells/scripts/monster/worm priestess paralyze.lua @@ -0,0 +1,22 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 10000) +condition:setFormula(-0.4, 0, -0.7, 0) +combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/wyrm wave.lua b/data/spells/scripts/monster/wyrm wave.lua new file mode 100644 index 00000000000..016660b988c --- /dev/null +++ b/data/spells/scripts/monster/wyrm wave.lua @@ -0,0 +1,20 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_PURPLEENERGY) + + arr = { + {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) + combat:setArea(area) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/wyvern drunk.lua b/data/spells/scripts/monster/wyvern drunk.lua new file mode 100644 index 00000000000..3914d58038c --- /dev/null +++ b/data/spells/scripts/monster/wyvern drunk.lua @@ -0,0 +1,19 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_RED) + +local condition = Condition(CONDITION_DRUNK) +condition:setParameter(CONDITION_PARAM_TICKS, 25000) +combat:addCondition(condition) + + arr = { + {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0} + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/young sea serpent drown.lua b/data/spells/scripts/monster/young sea serpent drown.lua new file mode 100644 index 00000000000..b1e799ce3cd --- /dev/null +++ b/data/spells/scripts/monster/young sea serpent drown.lua @@ -0,0 +1,15 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_DROWNDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_WATERSPLASH) + +local condition = Condition(CONDITION_DROWN) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(6, 5000, -20) + +local area = createCombatArea(AREA_SQUARE1X1) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/zamulosh invisible.lua b/data/spells/scripts/monster/zamulosh invisible.lua new file mode 100644 index 00000000000..5b24564ef05 --- /dev/null +++ b/data/spells/scripts/monster/zamulosh invisible.lua @@ -0,0 +1,22 @@ +local condition = Condition(CONDITION_INVISIBLE) +condition:setParameter(CONDITION_PARAM_TICKS, 10000) +local function invisible(fromPosition, toPosition) + for x = fromPosition.x, toPosition.x do + for y = fromPosition.y, toPosition.y do + for z = fromPosition.z, toPosition.z do + local creature = Tile(Position(x, y, z)):getTopCreature() + if creature then + if creature:isMonster() and creature:getName():lower() == 'zamulosh' then + creature:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + creature:addCondition(condition) + end + end + end + end + end +end + +function onCastSpell(creature, var) + invisible(Position(33634, 32749, 11), Position(33654, 32765, 11)) + return +end diff --git a/data/spells/scripts/monster/zamulosh tp.lua b/data/spells/scripts/monster/zamulosh tp.lua new file mode 100644 index 00000000000..28bdb00d060 --- /dev/null +++ b/data/spells/scripts/monster/zamulosh tp.lua @@ -0,0 +1,6 @@ +function onCastSpell(creature, var) + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + creature:teleportTo(Position(33644, 32757, 11)) + creature:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return +end diff --git a/data/spells/scripts/monster/zavarash heal.lua b/data/spells/scripts/monster/zavarash heal.lua new file mode 100644 index 00000000000..218364de5c3 --- /dev/null +++ b/data/spells/scripts/monster/zavarash heal.lua @@ -0,0 +1,42 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_DRAWBLOOD) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) + +arr = { + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + } + +local area = createCombatArea(arr) +combat:setArea(area) + +function onTargetCreature(creature, target) + local min = 425 + local max = 575 + + local master = target:getMaster() + if target:isPlayer() and not master + or master and master:isPlayer() then + return true + end + + doTargetCombatHealth(0, target, COMBAT_HEALING, min, max, CONST_ME_NONE) + return true +end + +combat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/zavarash paralyze.lua b/data/spells/scripts/monster/zavarash paralyze.lua new file mode 100644 index 00000000000..a69468ad9a2 --- /dev/null +++ b/data/spells/scripts/monster/zavarash paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.8, 0, -0.9, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/zavarash2 paralyze.lua b/data/spells/scripts/monster/zavarash2 paralyze.lua new file mode 100644 index 00000000000..eb2ac0e2c6f --- /dev/null +++ b/data/spells/scripts/monster/zavarash2 paralyze.lua @@ -0,0 +1,12 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.05, 0, -0.1, 0) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/zugurosh pillar skill reducer.lua b/data/spells/scripts/monster/zugurosh pillar skill reducer.lua new file mode 100644 index 00000000000..9e436329e35 --- /dev/null +++ b/data/spells/scripts/monster/zugurosh pillar skill reducer.lua @@ -0,0 +1,16 @@ +local combat = {} + +for i = 1, 20 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SMALLCLOUDS) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 7000) + condition:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, i) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(1, 20)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/zugurosh soulfire.lua b/data/spells/scripts/monster/zugurosh soulfire.lua new file mode 100644 index 00000000000..f2fc75defc7 --- /dev/null +++ b/data/spells/scripts/monster/zugurosh soulfire.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONHIT) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE) + +local condition = Condition(CONDITION_FIRE) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(30, 9000, -10) + +local area = createCombatArea(AREA_CIRCLE2X2) +combat:setArea(area) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/zulazza the corruptor paralyze.lua b/data/spells/scripts/monster/zulazza the corruptor paralyze.lua new file mode 100644 index 00000000000..9ec9f0eec9a --- /dev/null +++ b/data/spells/scripts/monster/zulazza the corruptor paralyze.lua @@ -0,0 +1,17 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GREEN_RINGS) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_GREENSTAR) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-0.6, 0, -0.8, 0) +combat:addCondition(condition) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat:setArea(area) + combat:addCondition(condition) + + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/zulazza the corruptor skill reducer.lua b/data/spells/scripts/monster/zulazza the corruptor skill reducer.lua new file mode 100644 index 00000000000..65a09ed6d4d --- /dev/null +++ b/data/spells/scripts/monster/zulazza the corruptor skill reducer.lua @@ -0,0 +1,19 @@ +local combat = {} + +for i = 40, 50 do + combat[i] = Combat() + combat[i]:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_POFF) + combat[i]:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_EARTH) + + local condition = Condition(CONDITION_ATTRIBUTES) + condition:setParameter(CONDITION_PARAM_TICKS, 15000) + condition:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, i) + + local area = createCombatArea(AREA_CIRCLE2X2) + combat[i]:setArea(area) + combat[i]:addCondition(condition) +end + +function onCastSpell(creature, var) + return combat[math.random(40, 50)]:execute(creature, var) +end diff --git a/data/spells/scripts/monster/zushuka freeze.lua b/data/spells/scripts/monster/zushuka freeze.lua new file mode 100644 index 00000000000..e94c6cc2dc0 --- /dev/null +++ b/data/spells/scripts/monster/zushuka freeze.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEAREA) +combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SHIVERARROW) + +local condition = Condition(CONDITION_FREEZING) +condition:setParameter(CONDITION_PARAM_DELAYED, 1) +condition:addDamage(30, 8000, -8) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/monster/zushuka heal.lua b/data/spells/scripts/monster/zushuka heal.lua new file mode 100644 index 00000000000..63e482f764c --- /dev/null +++ b/data/spells/scripts/monster/zushuka heal.lua @@ -0,0 +1,15 @@ +local condition = Condition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) +condition:setParameter(CONDITION_PARAM_SUBID, 88888) +condition:setParameter(CONDITION_PARAM_TICKS, 15 * 60 * 1000) +condition:setParameter(CONDITION_PARAM_HEALTHGAIN, 0.01) +condition:setParameter(CONDITION_PARAM_HEALTHTICKS, 15 * 60 * 1000) + +function onCastSpell(creature, var) + if creature:getHealth() < creature:getMaxHealth() * 0.2 and not creature:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, 88888) then + creature:addCondition(condition) + creature:addHealth(math.random(7500, 7515)) + else + return + end +return true +end diff --git a/data/spells/scripts/monster/zushuka paralyze.lua b/data/spells/scripts/monster/zushuka paralyze.lua new file mode 100644 index 00000000000..ff8cb9fcdd5 --- /dev/null +++ b/data/spells/scripts/monster/zushuka paralyze.lua @@ -0,0 +1,15 @@ + local combat = Combat() + combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_SOUND_WHITE) + combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ICE) + + local condition = Condition(CONDITION_PARALYZE) + condition:setParameter(CONDITION_PARAM_TICKS, 20000) + condition:setFormula(-0.6, 0, -0.7, 0) + + local area = createCombatArea(AREA_SQUARE1X1) + combat:setArea(area) + combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/party/enchant.lua b/data/spells/scripts/party/enchant.lua new file mode 100644 index 00000000000..12bf9012137 --- /dev/null +++ b/data/spells/scripts/party/enchant.lua @@ -0,0 +1,66 @@ +local combat = Combat() +combat:setArea(createCombatArea(AREA_CIRCLE5X5)) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) + +local condition = Condition(CONDITION_ATTRIBUTES) +condition:setParameter(CONDITION_PARAM_SUBID, 3) +condition:setParameter(CONDITION_PARAM_BUFF_SPELL, 1) +condition:setParameter(CONDITION_PARAM_TICKS, 2 * 60 * 1000) +condition:setParameter(CONDITION_PARAM_STAT_MAGICPOINTS, 1) + +local baseMana = 120 +function onCastSpell(creature, var, isHotkey) + local position = creature:getPosition() + + local party = creature:getParty() + if not party then + creature:sendCancelMessage("No party members in range.") + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + local membersList = party:getMembers() + membersList[#membersList + 1] = party:getLeader() + if membersList == nil or type(membersList) ~= 'table' or #membersList <= 1 then + creature:sendCancelMessage("No party members in range.") + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + local affectedList = {} + for _, targetPlayer in ipairs(membersList) do + if targetPlayer:getPosition():getDistance(position) <= 36 then + affectedList[#affectedList + 1] = targetPlayer + end + end + + local tmp = #affectedList + if tmp <= 1 then + creature:sendCancelMessage("No party members in range.") + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + local mana = math.ceil((0.9 ^ (tmp - 1) * baseMana) * tmp) + if creature:getMana() < mana then + creature:sendCancelMessage(RETURNVALUE_NOTENOUGHMANA) + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + if not combat:execute(creature, var) then + creature:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + creature:addMana(-(mana - baseMana), FALSE) + creature:addManaSpent((mana - baseMana)) + + for _, targetPlayer in ipairs(affectedList) do + targetPlayer:addCondition(condition) + end + + return true +end diff --git a/data/spells/scripts/party/heal.lua b/data/spells/scripts/party/heal.lua new file mode 100644 index 00000000000..99390761f35 --- /dev/null +++ b/data/spells/scripts/party/heal.lua @@ -0,0 +1,67 @@ +local combat = Combat() +combat:setParameter(createCombatArea(AREA_CIRCLE5X5)) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) + +local condition = Condition(CONDITION_REGENERATION) +condition:setParameter(CONDITION_PARAM_SUBID, 1) +condition:setParameter(CONDITION_PARAM_BUFF_SPELL, 1) +condition:setParameter(CONDITION_PARAM_TICKS, 2 * 60 * 1000) +condition:setParameter(CONDITION_PARAM_HEALTHGAIN, 20) +condition:setParameter(CONDITION_PARAM_HEALTHTICKS, 2000) + +local baseMana = 120 +function onCastSpell(creature, var, isHotkey) + local position = creature:getPosition() + + local party = creature:getParty() + if not party then + creature:sendCancelMessage("No party members in range.") + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + local membersList = party:getMembers() + membersList[#membersList + 1] = party:getLeader() + if membersList == nil or type(membersList) ~= 'table' or #membersList <= 1 then + creature:sendCancelMessage("No party members in range.") + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + local affectedList = {} + for _, targetPlayer in ipairs(membersList) do + if targetPlayer:getPosition():getDistance(position) <= 36 then + affectedList[#affectedList + 1] = targetPlayer + end + end + + local tmp = #affectedList + if tmp <= 1 then + creature:sendCancelMessage("No party members in range.") + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + local mana = math.ceil((0.9 ^ (tmp - 1) * baseMana) * tmp) + if creature:getMana() < mana then + creature:sendCancelMessage(RETURNVALUE_NOTENOUGHMANA) + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + if not combat:execute(creature, var) then + creature:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + creature:addMana(-(mana - baseMana), false) + creature:addManaSpent((mana - baseMana)) + + for _, targetPlayer in ipairs(affectedList) do + targetPlayer:addCondition(condition) + end + + return true +end diff --git a/data/spells/scripts/party/protect.lua b/data/spells/scripts/party/protect.lua new file mode 100644 index 00000000000..7924571300c --- /dev/null +++ b/data/spells/scripts/party/protect.lua @@ -0,0 +1,66 @@ +local combat = Combat() +combat:setArea(createCombatArea(AREA_CIRCLE5X5)) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) + +local condition = Condition(CONDITION_ATTRIBUTES) +condition:setParameter(CONDITION_PARAM_SUBID, 2) +condition:setParameter(CONDITION_PARAM_BUFF_SPELL, 1) +condition:setParameter(CONDITION_PARAM_TICKS, 2 * 60 * 1000) +condition:setParameter(CONDITION_PARAM_SKILL_SHIELD, 2) + +local baseMana = 90 +function onCastSpell(creature, var, isHotkey) + local position = creature:getPosition() + + local party = creature:getParty() + if not party then + creature:sendCancelMessage("No party members in range.") + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + local membersList = party:getMembers() + membersList[#membersList + 1] = party:getLeader() + if membersList == nil or type(membersList) ~= 'table' or #membersList <= 1 then + creature:sendCancelMessage("No party members in range.") + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + local affectedList = {} + for _, targetPlayer in ipairs(membersList) do + if targetPlayer:getPosition():getDistance(position) <= 36 then + affectedList[#affectedList + 1] = targetPlayer + end + end + + local tmp = #affectedList + if tmp <= 1 then + creature:sendCancelMessage("No party members in range.") + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + local mana = math.ceil((0.9 ^ (tmp - 1) * baseMana) * tmp) + if creature:getMana() < mana then + creature:sendCancelMessage(RETURNVALUE_NOTENOUGHMANA) + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + if not combat:execute(creature, var) then + creature:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + creature:addMana(-(mana - baseMana), false) + creature:addManaSpent((mana - baseMana)) + + for _, targetPlayer in ipairs(affectedList) do + targetPlayer:addCondition(condition) + end + + return true +end diff --git a/data/spells/scripts/party/train.lua b/data/spells/scripts/party/train.lua new file mode 100644 index 00000000000..a93e29b25bd --- /dev/null +++ b/data/spells/scripts/party/train.lua @@ -0,0 +1,67 @@ +local combat = Combat() +combat:setArea(createCombatArea(AREA_CIRCLE5X5)) +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) + +local condition = Condition(CONDITION_ATTRIBUTES) +condition:setParameter(CONDITION_PARAM_SUBID, 1) +condition:setParameter(CONDITION_PARAM_BUFF_SPELL, 1) +condition:setParameter(CONDITION_PARAM_TICKS, 2 * 60 * 1000) +condition:setParameter(CONDITION_PARAM_SKILL_MELEE, 3) +condition:setParameter(CONDITION_PARAM_SKILL_DISTANCE, 3) + +local baseMana = 60 +function onCastSpell(creature, var, isHotkey) + local position = creature:getPosition() + + local party = creature:getParty() + if not party then + creature:sendCancelMessage("No party members in range.") + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + local membersList = party:getMembers() + membersList[#membersList + 1] = party:getLeader() + if membersList == nil or type(membersList) ~= 'table' or #membersList <= 1 then + creature:sendCancelMessage("No party members in range.") + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + local affectedList = {} + for _, targetPlayer in ipairs(membersList) do + if targetPlayer:getPosition():getDistance(position) <= 36 then + affectedList[#affectedList + 1] = targetPlayer + end + end + + local tmp = #affectedList + if tmp <= 1 then + creature:sendCancelMessage("No party members in range.") + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + local mana = math.ceil((0.9 ^ (tmp - 1) * baseMana) * tmp) + if creature:getMana() < mana then + creature:sendCancelMessage(RETURNVALUE_NOTENOUGHMANA) + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + if not combat:execute(creature, var) then + creature:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + creature:addMana(-(mana - baseMana), FALSE) + creature:addManaSpent((mana - baseMana)) + + for _, targetPlayer in ipairs(affectedList) do + targetPlayer:addCondition(condition) + end + + return true +end diff --git a/data/spells/scripts/summon/familiars.lua b/data/spells/scripts/summon/familiars.lua new file mode 100644 index 00000000000..3d9373d1ba3 --- /dev/null +++ b/data/spells/scripts/summon/familiars.lua @@ -0,0 +1,78 @@ +local familiar = { + [VOCATION.CLIENT_ID.SORCERER] = {name = "Sorcerer familiar"}, + [VOCATION.CLIENT_ID.DRUID] = {name = "Druid familiar"}, + [VOCATION.CLIENT_ID.PALADIN] = {name = "Paladin familiar"}, + [VOCATION.CLIENT_ID.KNIGHT] = {name = "Knight familiar"} +} + +local timer = { + [1] = {storage=Storage.PetSummonEvent10, countdown=10, message = "10 seconds"}, + [2] = {storage=Storage.PetSummonEvent60, countdown=60, message = "one minute"} +} + +local function sendMessageFunction(pid, message) + if Player(pid) then + Player(pid):sendTextMessage(MESSAGE_LOOT, "Your summon will disappear in less than " .. message) + end +end + +local function removePet(creatureId, playerId) + local creature = Creature(creatureId) + local player = Player(playerId) + if not creature or not player then + return true + end + creature:remove() + for sendMessage = 1, #timer do + player:setStorageValue(timer[sendMessage].storage, -1) + end +end + +function onCastSpell(player, variant) + if not player or not isPremium(player) then + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:sendCancelMessage("You need a premium account.") + return false + end + + if #player:getSummons() >= 1 then + player:sendCancelMessage("You can't have other summons.") + player:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + + local vocation = familiar[player:getVocation():getClientId()] + local familiarName + + if vocation then + familiarName = vocation.name + end + + if not familiarName then + player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + + local myFamiliar = Game.createMonster(familiarName, player:getPosition(), true, false) + if not myFamiliar then + player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + + player:addSummon(myFamiliar) + myFamiliar:setOutfit({lookType = player:getFamiliarLooktype()}) + --myFamiliar:reload() + myFamiliar:registerEvent("FamiliarDeath") + local deltaSpeed = math.max(player:getSpeed() - myFamiliar:getBaseSpeed(), 0) + myFamiliar:changeSpeed(deltaSpeed) + player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + myFamiliar:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + player:setStorageValue(Storage.PetSummon, os.time() + 15*60) -- 15 minutes from now + addEvent(removePet, 15*60*1000, myFamiliar:getId(), player:getId()) + for sendMessage = 1, #timer do + player:setStorageValue(timer[sendMessage].storage,addEvent(sendMessageFunction, (15*60-timer[sendMessage].countdown)*1000, player:getId(),timer[sendMessage].message)) + end + return true +end diff --git a/data/spells/scripts/summon/summon creature.lua b/data/spells/scripts/summon/summon creature.lua new file mode 100644 index 00000000000..d7803ed88e3 --- /dev/null +++ b/data/spells/scripts/summon/summon creature.lua @@ -0,0 +1,47 @@ +function onCastSpell(player, variant) + local monsterName = variant:getString() + local monsterType = MonsterType(monsterName) + + if not monsterType then + player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + + if not getPlayerFlagValue(player, PlayerFlag_CanSummonAll) then + if not monsterType:isSummonable() then + player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + + if #player:getSummons() >= 2 then + player:sendCancelMessage("You cannot summon more players.") + player:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + end + + local manaCost = monsterType:getManaCost() + if player:getMana() < manaCost and not getPlayerFlagValue(player, PlayerFlag_HasInfiniteMana) then + player:sendCancelMessage(RETURNVALUE_NOTENOUGHMANA) + player:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + + local position = player:getPosition() + local summon = Game.createMonster(monsterName, position, true, false) + if not summon then + player:sendCancelMessage(RETURNVALUE_NOTENOUGHROOM) + position:sendMagicEffect(CONST_ME_POFF) + return false + end + + player:addMana(-manaCost) + player:addManaSpent(manaCost) + player:addSummon(summon) + summon:reload() + position:sendMagicEffect(CONST_ME_MAGIC_BLUE) + summon:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end diff --git a/data/spells/scripts/support/animate dead rune.lua b/data/spells/scripts/support/animate dead rune.lua new file mode 100644 index 00000000000..ad61d6c5e37 --- /dev/null +++ b/data/spells/scripts/support/animate dead rune.lua @@ -0,0 +1,30 @@ +function onCastSpell(player, variant) + local position = variant:getPosition() + local tile = Tile(position) + if tile then + local corpse = tile:getTopDownItem() + if corpse then + local itemType = corpse:getType() + if itemType:isCorpse() and itemType:isMovable() then + if #player:getSummons() < 2 and player:getSkull() ~= SKULL_BLACK then + local summon = Game.createMonster("Skeleton", position, true, true) + if summon then + corpse:remove() + player:addSummon(summon) + summon:reload() + position:sendMagicEffect(CONST_ME_MAGIC_BLUE) + return true + end + else + player:sendCancelMessage("You cannot control more creatures.") + player:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + end + end + end + + player:getPosition():sendMagicEffect(CONST_ME_POFF) + player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + return false +end diff --git a/data/spells/scripts/support/blood rage.lua b/data/spells/scripts/support/blood rage.lua new file mode 100644 index 00000000000..ee909b2c8c3 --- /dev/null +++ b/data/spells/scripts/support/blood rage.lua @@ -0,0 +1,19 @@ +local condition = Condition(CONDITION_ATTRIBUTES) +condition:setParameter(CONDITION_PARAM_SUBID, 5) +condition:setParameter(CONDITION_PARAM_TICKS, 10000) +condition:setParameter(CONDITION_PARAM_SKILL_MELEEPERCENT, 135) +condition:setParameter(CONDITION_PARAM_BUFF_DAMAGERECEIVED, 115) +condition:setParameter(CONDITION_PARAM_DISABLE_DEFENSE, true) +condition:setParameter(CONDITION_PARAM_BUFF_SPELL, true) + +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) +combat:addCondition(condition) + +function onCastSpell(creature, var) + if creature:getCondition(CONDITION_ATTRIBUTES, CONDITIONID_COMBAT, 5) then + creature:removeCondition(CONDITION_ATTRIBUTES, CONDITIONID_COMBAT, 5) + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/support/cancel invisibility.lua b/data/spells/scripts/support/cancel invisibility.lua new file mode 100644 index 00000000000..c99719465a9 --- /dev/null +++ b/data/spells/scripts/support/cancel invisibility.lua @@ -0,0 +1,8 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_INVISIBLE) +combat:setArea(createCombatArea(AREA_CIRCLE3X3)) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/support/cancel magic shield.lua b/data/spells/scripts/support/cancel magic shield.lua new file mode 100644 index 00000000000..9a927996929 --- /dev/null +++ b/data/spells/scripts/support/cancel magic shield.lua @@ -0,0 +1,9 @@ + +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) + +function onCastSpell(creature, var) + creature:removeCondition(CONDITION_MANASHIELD) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/support/challenge.lua b/data/spells/scripts/support/challenge.lua new file mode 100644 index 00000000000..348a3a7addd --- /dev/null +++ b/data/spells/scripts/support/challenge.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setArea(createCombatArea(AREA_SQUARE1X1)) + +function onTargetCreature(creature, target) + return doChallengeCreature(creature, target) +end + +combat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") + +function onCastSpell(creature, variant) + return combat:execute(creature, variant) +end diff --git a/data/spells/scripts/support/chameleon.lua b/data/spells/scripts/support/chameleon.lua new file mode 100644 index 00000000000..e157d1a524d --- /dev/null +++ b/data/spells/scripts/support/chameleon.lua @@ -0,0 +1,27 @@ +local condition = Condition(CONDITION_OUTFIT) +condition:setTicks(200000) + +function onCastSpell(creature, variant, isHotkey) + local position, item = variant:getPosition() + if position.x == CONTAINER_POSITION then + local container = creature:getContainerById(position.y - 64) + if container then + item = container:getItem(position.z) + else + item = creature:getSlotItem(position.y) + end + else + item = Tile(position):getTopDownItem() + end + + if not item or item.itemid == 0 or not isMoveable(item.uid) then + creature:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + + condition:setOutfit({lookTypeEx = item.itemid}) + creature:addCondition(condition) + creature:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + return true +end diff --git a/data/spells/scripts/support/charge.lua b/data/spells/scripts/support/charge.lua new file mode 100644 index 00000000000..6f931d3d525 --- /dev/null +++ b/data/spells/scripts/support/charge.lua @@ -0,0 +1,27 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false) + +local condition = Condition(CONDITION_HASTE) +condition:setParameter(CONDITION_PARAM_TICKS, 5000) +condition:setFormula(0.9, -72, 0.9, -72) +combat:addCondition(condition) + +function onCastSpell(creature, variant) + local summons = creature:getSummons() + if summons and type(summons) == 'table' and #summons > 0 then + for i = 1, #summons do + local summon = summons[i] + local summon_t = summon:getType() + if summon_t and summon_t:isPet() then + local deltaSpeed = math.max(creature:getBaseSpeed() - summon:getBaseSpeed(), 0) + local PetSpeed = ((summon:getBaseSpeed() + deltaSpeed) * 0.9) - 72 + local PetHaste = createConditionObject(CONDITION_HASTE) + setConditionParam(PetHaste, CONDITION_PARAM_TICKS, 5000) + setConditionParam(PetHaste, CONDITION_PARAM_SPEED, PetSpeed) + summon:addCondition(PetHaste) + end + end + end + return combat:execute(creature, variant) +end diff --git a/data/spells/scripts/support/chivalrous challenge.lua b/data/spells/scripts/support/chivalrous challenge.lua new file mode 100644 index 00000000000..a510053bb9b --- /dev/null +++ b/data/spells/scripts/support/chivalrous challenge.lua @@ -0,0 +1,75 @@ +local function getDiagonalDistance(pos1, pos2) + local dstX = math.abs(pos1.x - pos2.x) + local dstY = math.abs(pos1.y - pos2.y) + if dstX > dstY then + return 14 * dstY + 10 * (dstX - dstY) + else + return 14 * dstX + 10 * (dstY - dstX) + end +end +local function chain(player) + local creatures = Game.getSpectators(player:getPosition(), false, false, 9, 9, 6, 6) + local totalChain = 0 + local monsters = {} + for _, creature in pairs(creatures) do + if creature:isMonster() then + if creature:getType():isRewardBoss() then + return -1 + elseif creature:getMaster() == nil and creature:getType():getTargetDistance() > 1 then + table.insert(monsters, creature) + end + end + end + local lastChain = player + local lastChainPosition = player:getPosition() + local closestMonster, closestMonsterIndex, closestMonsterPosition + local path, tempPosition, updateLastChain + while (totalChain < 5 and #monsters > 0) do + closestMonster = nil + for index, monster in pairs(monsters) do + tempPosition = monster:getPosition() + if not closestMonster or getDiagonalDistance(lastChain:getPosition(), tempPosition) < getDiagonalDistance(lastChain:getPosition(), closestMonsterPosition) then + closestMonster = monster + closestMonsterIndex = index + closestMonsterPosition = tempPosition + end + end + table.remove(monsters, closestMonsterIndex) + updateLastChain = false + if lastChainPosition:getDistance(closestMonsterPosition) == 1 then + updateLastChain = true + else + path = lastChainPosition:getPathTo(closestMonsterPosition, 0, 1, true, true, 9) + if path and #path > 0 then + for i=1, #path do + lastChainPosition:getNextPosition(path[i], 1) + lastChainPosition:sendMagicEffect(CONST_ME_CHIVALRIOUS_CHALLENGE) + end + updateLastChain = true + end + end + if updateLastChain then + closestMonsterPosition:sendMagicEffect(CONST_ME_CHIVALRIOUS_CHALLENGE) + closestMonster:changeTargetDistance(1) + doChallengeCreature(player, closestMonster) + lastChain = closestMonster + lastChainPosition = closestMonsterPosition + totalChain = totalChain + 1 + end + end + return totalChain +end +function onCastSpell(creature, variant) + local total = chain(creature) + if total > 0 then + return true + elseif total == -1 then + creature:sendCancelMessage("You can't use this spell if there's a boss.") + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + else + creature:sendCancelMessage("There are no ranged monsters.") + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end +end \ No newline at end of file diff --git a/data/spells/scripts/support/convince_creature.lua b/data/spells/scripts/support/convince_creature.lua new file mode 100644 index 00000000000..a99eb44589f --- /dev/null +++ b/data/spells/scripts/support/convince_creature.lua @@ -0,0 +1,37 @@ +function onCastSpell(creature, variant, isHotkey) + local target = Creature(variant:getNumber()) + if not target or not target:isMonster() then + creature:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + + local monsterType = target:getType() + if not getPlayerFlagValue(creature, PlayerFlag_CanConvinceAll) then + if not monsterType:isConvinceable() then + creature:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + + if #creature:getSummons() >= 2 then + creature:sendCancelMessage("You cannot control more creatures.") + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + end + + local manaCost = target:getType():getManaCost() + if creature:getMana() < manaCost and not getPlayerFlagValue(creature, PlayerFlag_HasInfiniteMana) then + creature:sendCancelMessage(RETURNVALUE_NOTENOUGHMANA) + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + + creature:addMana(-manaCost) + creature:addManaSpent(manaCost) + creature:addSummon(target) + target:reload() + creature:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) + return true +end diff --git a/data/spells/scripts/support/desintegrate rune.lua b/data/spells/scripts/support/desintegrate rune.lua new file mode 100644 index 00000000000..73c0c0ec50d --- /dev/null +++ b/data/spells/scripts/support/desintegrate rune.lua @@ -0,0 +1,25 @@ +local corpseIds = {3058, 3059, 3060, 3061, 3064, 3065, 3066} +local removalLimit = 500 + +function onCastSpell(creature, variant, isHotkey) + local position = variant:getPosition() + local tile = Tile(position) + if tile then + local items = tile:getItems() + if items then + for i, item in ipairs(items) do + if item:getType():isMovable() and item:getUniqueId() > 65535 and item:getActionId() == 0 and not table.contains(corpseIds, item:getId()) then + item:remove() + end + + if i == removalLimit then + break + end + end + end + end + + creature:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + position:sendMagicEffect(CONST_ME_POFF) + return true +end diff --git a/data/spells/scripts/support/destroy field rune.lua b/data/spells/scripts/support/destroy field rune.lua new file mode 100644 index 00000000000..c251ca91953 --- /dev/null +++ b/data/spells/scripts/support/destroy field rune.lua @@ -0,0 +1,14 @@ +function onCastSpell(creature, variant, isHotkey) + local position = Variant.getPosition(variant) + local tile = Tile(position) + local field = tile and tile:getItemByType(ITEM_TYPE_MAGICFIELD) + if field and isInArray(FIELDS, field:getId()) then + field:remove() + position:sendMagicEffect(CONST_ME_POFF) + return true + end + + creature:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + return false +end diff --git a/data/spells/scripts/support/divine dazzle.lua b/data/spells/scripts/support/divine dazzle.lua new file mode 100644 index 00000000000..00b10e2e5e9 --- /dev/null +++ b/data/spells/scripts/support/divine dazzle.lua @@ -0,0 +1,74 @@ +local function getDiagonalDistance(pos1, pos2) + local dstX = math.abs(pos1.x - pos2.x) + local dstY = math.abs(pos1.y - pos2.y) + if dstX > dstY then + return 14 * dstY + 10 * (dstX - dstY) + else + return 14 * dstX + 10 * (dstY - dstX) + end +end +local function chain(player) + local creatures = Game.getSpectators(player:getPosition(), false, false, 6, 6, 6, 6) + local totalChain = 0 + local monsters = {} + for _, creature in pairs(creatures) do + if creature:isMonster() then + if creature:getType():isRewardBoss() then + return -1 + elseif creature:getMaster() == nil and creature:getType():getTargetDistance() > 1 then + table.insert(monsters, creature) + end + end + end + local lastChain = player + local lastChainPosition = player:getPosition() + local closestMonster, closestMonsterIndex, closestMonsterPosition + local path, tempPosition, updateLastChain + while (totalChain < 3 and #monsters > 0) do + closestMonster = nil + for index, monster in pairs(monsters) do + tempPosition = monster:getPosition() + if not closestMonster or getDiagonalDistance(lastChain:getPosition(), tempPosition) < getDiagonalDistance(lastChain:getPosition(), closestMonsterPosition) then + closestMonster = monster + closestMonsterIndex = index + closestMonsterPosition = tempPosition + end + end + table.remove(monsters, closestMonsterIndex) + updateLastChain = false + if lastChainPosition:getDistance(closestMonsterPosition) == 1 then + updateLastChain = true + else + path = lastChainPosition:getPathTo(closestMonsterPosition, 0, 1, true, true, 9) + if path and #path > 0 then + for i=1, #path do + lastChainPosition:getNextPosition(path[i], 1) + lastChainPosition:sendMagicEffect(CONST_ME_DIVINE_DAZZLE) + end + updateLastChain = true + end + end + if updateLastChain then + closestMonsterPosition:sendMagicEffect(CONST_ME_DIVINE_DAZZLE) + closestMonster:changeTargetDistance(1) + lastChain = closestMonster + lastChainPosition = closestMonsterPosition + totalChain = totalChain + 1 + end + end + return totalChain +end +function onCastSpell(creature, variant) + local total = chain(creature) + if total > 0 then + return true + elseif total == -1 then + creature:sendCancelMessage("You can't use this spell if there's a boss.") + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + else + creature:sendCancelMessage("There are no ranged monsters.") + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end +end \ No newline at end of file diff --git a/data/spells/scripts/support/expose weakness.lua b/data/spells/scripts/support/expose weakness.lua new file mode 100644 index 00000000000..72e202b16e8 --- /dev/null +++ b/data/spells/scripts/support/expose weakness.lua @@ -0,0 +1,30 @@ +local condition = Condition(CONDITION_ATTRIBUTES) +condition:setParameter(CONDITION_PARAM_TICKS, 16000) +condition:setParameter(CONDITION_PARAM_BUFF_DAMAGERECEIVED, 105) + +function onTargetCreature(creature, target) + local player = creature:getPlayer() + + if target:isPlayer() then + return false + end + if target:getMaster() then + return true + end + + target:addCondition(condition) + return true +end + +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) +combat:setArea(createCombatArea(AREA_CIRCLE3X3)) +combat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") + +function onCastSpell(creature, var, isHotkey) + local target = creature:getTarget() + if target then + var = Variant(target) + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/support/find person.lua b/data/spells/scripts/support/find person.lua new file mode 100644 index 00000000000..c478efd0605 --- /dev/null +++ b/data/spells/scripts/support/find person.lua @@ -0,0 +1,74 @@ +local LEVEL_LOWER = 1 +local LEVEL_SAME = 2 +local LEVEL_HIGHER = 3 + +local DISTANCE_BESIDE = 1 +local DISTANCE_CLOSE = 2 +local DISTANCE_FAR = 3 +local DISTANCE_VERYFAR = 4 + +local directions = { + [DIRECTION_NORTH] = "north", + [DIRECTION_SOUTH] = "south", + [DIRECTION_EAST] = "east", + [DIRECTION_WEST] = "west", + [DIRECTION_NORTHEAST] = "north-east", + [DIRECTION_NORTHWEST] = "north-west", + [DIRECTION_SOUTHEAST] = "south-east", + [DIRECTION_SOUTHWEST] = "south-west" +} + +local messages = { + [DISTANCE_BESIDE] = { + [LEVEL_LOWER] = "is below you", + [LEVEL_SAME] = "is standing next to you", + [LEVEL_HIGHER] = "is above you" + }, + [DISTANCE_CLOSE] = { + [LEVEL_LOWER] = "is on a lower level to the", + [LEVEL_SAME] = "is to the", + [LEVEL_HIGHER] = "is on a higher level to the" + }, + [DISTANCE_FAR] = "is far to the", + [DISTANCE_VERYFAR] = "is very far to the" +} + +function onCastSpell(creature, variant) + local target = Player(variant:getString()) + if not target or target:getGroup():getAccess() and not creature:getGroup():getAccess() then + creature:sendCancelMessage(RETURNVALUE_PLAYERWITHTHISNAMEISNOTONLINE) + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + + local targetPosition = target:getPosition() + local creaturePosition = creature:getPosition() + local positionDifference = { + x = creaturePosition.x - targetPosition.x, + y = creaturePosition.y - targetPosition.y, + z = creaturePosition.z - targetPosition.z + } + + local maxPositionDifference, direction = math.max(math.abs(positionDifference.x), math.abs(positionDifference.y)) + if maxPositionDifference >= 5 then + local positionTangent = positionDifference.x ~= 0 and positionDifference.y / positionDifference.x or 10 + if math.abs(positionTangent) < 0.4142 then + direction = positionDifference.x > 0 and DIRECTION_WEST or DIRECTION_EAST + elseif math.abs(positionTangent) < 2.4142 then + direction = positionTangent > 0 and (positionDifference.y > 0 and DIRECTION_NORTHWEST or DIRECTION_SOUTHEAST) or positionDifference.x > 0 and DIRECTION_SOUTHWEST or DIRECTION_NORTHEAST + else + direction = positionDifference.y > 0 and DIRECTION_NORTH or DIRECTION_SOUTH + end + end + + local level = positionDifference.z > 0 and LEVEL_HIGHER or positionDifference.z < 0 and LEVEL_LOWER or LEVEL_SAME + local distance = maxPositionDifference < 5 and DISTANCE_BESIDE or maxPositionDifference < 101 and DISTANCE_CLOSE or maxPositionDifference < 275 and DISTANCE_FAR or DISTANCE_VERYFAR + local message = messages[distance][level] or messages[distance] + if distance ~= DISTANCE_BESIDE then + message = message .. " " .. directions[direction] + end + + creature:sendTextMessage(MESSAGE_LOOK, target:getName() .. " " .. message .. ".") + creaturePosition:sendMagicEffect(CONST_ME_MAGIC_BLUE) + return true +end diff --git a/data/spells/scripts/support/food.lua b/data/spells/scripts/support/food.lua new file mode 100644 index 00000000000..b1c81d01396 --- /dev/null +++ b/data/spells/scripts/support/food.lua @@ -0,0 +1,19 @@ +local foods = { + 2666, -- meat + 2671, -- ham + 2681, -- grape + 2674, -- apple + 2689, -- bread + 2690, -- roll + 2696 -- cheese +} + +function onCastSpell(creature, variant) + if math.random(0, 1) == 1 then + creature:addItem(foods[math.random(#foods)]) + end + + creature:addItem(foods[math.random(#foods)]) + creature:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + return true +end diff --git a/data/spells/scripts/support/great light.lua b/data/spells/scripts/support/great light.lua new file mode 100644 index 00000000000..03ebd2b5d39 --- /dev/null +++ b/data/spells/scripts/support/great light.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) + +local condition = Condition(CONDITION_LIGHT) +condition:setParameter(CONDITION_PARAM_LIGHT_LEVEL, 8) +condition:setParameter(CONDITION_PARAM_LIGHT_COLOR, 215) +condition:setParameter(CONDITION_PARAM_TICKS, (11 * 60 + 35) * 1000) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/support/haste.lua b/data/spells/scripts/support/haste.lua new file mode 100644 index 00000000000..fbd438dc4ec --- /dev/null +++ b/data/spells/scripts/support/haste.lua @@ -0,0 +1,27 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false) + +local condition = Condition(CONDITION_HASTE) +condition:setParameter(CONDITION_PARAM_TICKS, 33000) +condition:setFormula(0.3, -24, 0.3, -24) +combat:addCondition(condition) + +function onCastSpell(creature, variant) + local summons = creature:getSummons() + if summons and type(summons) == 'table' and #summons > 0 then + for i = 1, #summons do + local summon = summons[i] + local summon_t = summon:getType() + if summon_t and summon_t:isPet() then + local deltaSpeed = math.max(creature:getBaseSpeed() - summon:getBaseSpeed(), 0) + local PetSpeed = ((summon:getBaseSpeed() + deltaSpeed) * 0.3) - 24 + local PetHaste = createConditionObject(CONDITION_HASTE) + setConditionParam(PetHaste, CONDITION_PARAM_TICKS, 33000) + setConditionParam(PetHaste, CONDITION_PARAM_SPEED, PetSpeed) + summon:addCondition(PetHaste) + end + end + end + return combat:execute(creature, variant) +end diff --git a/data/spells/scripts/support/illusion.lua b/data/spells/scripts/support/illusion.lua new file mode 100644 index 00000000000..39699741e0f --- /dev/null +++ b/data/spells/scripts/support/illusion.lua @@ -0,0 +1,23 @@ +local condition = Condition(CONDITION_OUTFIT) +condition:setTicks(180000) + +function onCastSpell(creature, variant) + local returnValue = RETURNVALUE_NOERROR + local monsterType = MonsterType(variant:getString()) + if not monsterType then + returnValue = RETURNVALUE_CREATUREDOESNOTEXIST + elseif not getPlayerFlagValue(creature, PlayerFlag_CanIllusionAll) and not monsterType:isIllusionable() then + returnValue = RETURNVALUE_NOTPOSSIBLE + end + + if returnValue ~= RETURNVALUE_NOERROR then + creature:sendCancelMessage(returnValue) + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + + condition:setOutfit(monsterType:getOutfit()) + creature:addCondition(condition) + creature:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + return true +end diff --git a/data/spells/scripts/support/invisible.lua b/data/spells/scripts/support/invisible.lua new file mode 100644 index 00000000000..e6a9557c2da --- /dev/null +++ b/data/spells/scripts/support/invisible.lua @@ -0,0 +1,11 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false) + +local condition = Condition(CONDITION_INVISIBLE) +condition:setParameter(CONDITION_PARAM_TICKS, 200000) +combat:addCondition(condition) + +function onCastSpell(creature, variant) + return combat:execute(creature, variant) +end diff --git a/data/spells/scripts/support/levitate.lua b/data/spells/scripts/support/levitate.lua new file mode 100644 index 00000000000..40a7770d5fd --- /dev/null +++ b/data/spells/scripts/support/levitate.lua @@ -0,0 +1,30 @@ +local function levitate(creature, parameter) + local fromPosition = creature:getPosition() + + if parameter == "up" and fromPosition.z ~= 8 or parameter == "down" and fromPosition.z ~= 7 then + local toPosition = creature:getPosition() + toPosition:getNextPosition(creature:getDirection()) + + local tile = Tile(parameter == "up" and Position(fromPosition.x, fromPosition.y, fromPosition.z - 1) or toPosition) + if not tile or not tile:getGround() and not tile:hasFlag(parameter == "up" and TILESTATE_IMMOVABLEBLOCKSOLID or TILESTATE_BLOCKSOLID) then + tile = Tile(toPosition.x, toPosition.y, toPosition.z + (parameter == "up" and -1 or 1)) + + if tile and tile:getGround() and not tile:hasFlag(bit.bor(TILESTATE_IMMOVABLEBLOCKSOLID, TILESTATE_FLOORCHANGE)) then + return creature:move(tile, bit.bor(FLAG_IGNOREBLOCKITEM, FLAG_IGNOREBLOCKCREATURE)) + end + end + end + return RETURNVALUE_NOTPOSSIBLE +end + +function onCastSpell(creature, variant) + local returnValue = levitate(creature, variant:getString():lower()) + if returnValue ~= RETURNVALUE_NOERROR then + creature:sendCancelMessage(returnValue) + creature:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + + creature:getPosition():sendMagicEffect(CONST_ME_TELEPORT) + return true +end diff --git a/data/spells/scripts/support/light.lua b/data/spells/scripts/support/light.lua new file mode 100644 index 00000000000..c69728dcf69 --- /dev/null +++ b/data/spells/scripts/support/light.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false) + +local condition = Condition(CONDITION_LIGHT) +condition:setParameter(CONDITION_PARAM_LIGHT_LEVEL, 6) +condition:setParameter(CONDITION_PARAM_LIGHT_COLOR, 215) +condition:setParameter(CONDITION_PARAM_TICKS, (6 * 60 + 10) * 1000) +combat:addCondition(condition) + +function onCastSpell(creature, variant) + return combat:execute(creature, variant) +end diff --git a/data/spells/scripts/support/magic rope.lua b/data/spells/scripts/support/magic rope.lua new file mode 100644 index 00000000000..2160e9c01e9 --- /dev/null +++ b/data/spells/scripts/support/magic rope.lua @@ -0,0 +1,20 @@ +function onCastSpell(creature, var) + local position = creature:getPosition() + position:sendMagicEffect(CONST_ME_POFF) + + local tile = Tile(position) + if not tile:isRopeSpot() then + creature:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + return false + end + + tile = Tile(position:moveUpstairs()) + if not tile then + creature:sendCancelMessage(RETURNVALUE_NOTENOUGHROOM) + return false + end + + creature:teleportTo(position, false) + position:sendMagicEffect(CONST_ME_TELEPORT) + return true +end diff --git a/data/spells/scripts/support/magic shield.lua b/data/spells/scripts/support/magic shield.lua new file mode 100644 index 00000000000..eb9e473120c --- /dev/null +++ b/data/spells/scripts/support/magic shield.lua @@ -0,0 +1,14 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) + +function onCastSpell(creature, var) + local condition = Condition(CONDITION_MANASHIELD) + condition:setParameter(CONDITION_PARAM_TICKS, 180000) + local player = creature:getPlayer() + if player then + condition:setParameter(CONDITION_PARAM_MANASHIELD, math.min(player:getMaxMana(), 300 + 7.6 * player:getLevel() + 7 * player:getMagicLevel())) + end + creature:addCondition(condition) + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/support/paralyze rune.lua b/data/spells/scripts/support/paralyze rune.lua new file mode 100644 index 00000000000..700bf3e99ce --- /dev/null +++ b/data/spells/scripts/support/paralyze rune.lua @@ -0,0 +1,16 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) + +local condition = Condition(CONDITION_PARALYZE) +condition:setParameter(CONDITION_PARAM_TICKS, 20000) +condition:setFormula(-1, 45, -1, 45) +combat:addCondition(condition) + +function onCastSpell(creature, var) + if not combat:execute(creature, var) then + return false + end + + creature:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) + return true +end diff --git a/data/spells/scripts/support/protector.lua b/data/spells/scripts/support/protector.lua new file mode 100644 index 00000000000..cce74117e45 --- /dev/null +++ b/data/spells/scripts/support/protector.lua @@ -0,0 +1,19 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false) + +local skill = Condition(CONDITION_ATTRIBUTES) +skill:setParameter(CONDITION_PARAM_SUBID, 5) +skill:setParameter(CONDITION_PARAM_TICKS, 13000) +skill:setParameter(CONDITION_PARAM_SKILL_SHIELDPERCENT, 220) +skill:setParameter(CONDITION_PARAM_BUFF_DAMAGEDEALT, 65) +skill:setParameter(CONDITION_PARAM_BUFF_DAMAGERECEIVED, 85) +skill:setParameter(CONDITION_PARAM_BUFF_SPELL, true) +combat:addCondition(skill) + +function onCastSpell(creature, variant) + if creature:getCondition(CONDITION_ATTRIBUTES, CONDITIONID_COMBAT, 5) then + creature:removeCondition(CONDITION_ATTRIBUTES, CONDITIONID_COMBAT, 5) + end + return combat:execute(creature, variant) +end diff --git a/data/spells/scripts/support/sap strength.lua b/data/spells/scripts/support/sap strength.lua new file mode 100644 index 00000000000..b852def1971 --- /dev/null +++ b/data/spells/scripts/support/sap strength.lua @@ -0,0 +1,30 @@ +local condition = Condition(CONDITION_ATTRIBUTES) +condition:setParameter(CONDITION_PARAM_TICKS, 16000) +condition:setParameter(CONDITION_PARAM_BUFF_DAMAGEDEALT, 90) + +function onTargetCreature(creature, target) + local player = creature:getPlayer() + + if target:isPlayer() then + return false + end + if target:getMaster() then + return true + end + + target:addCondition(condition) + return true +end + +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) +combat:setArea(createCombatArea(AREA_CIRCLE3X3)) +combat:setCallback(CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") + +function onCastSpell(creature, var, isHotkey) + local target = creature:getTarget() + if target then + var = Variant(target) + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/support/sharpshooter.lua b/data/spells/scripts/support/sharpshooter.lua new file mode 100644 index 00000000000..93865698929 --- /dev/null +++ b/data/spells/scripts/support/sharpshooter.lua @@ -0,0 +1,30 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false) + +local skill = Condition(CONDITION_ATTRIBUTES) +skill:setParameter(CONDITION_PARAM_SUBID, 6) +skill:setParameter(CONDITION_PARAM_TICKS, 10000) +skill:setParameter(CONDITION_PARAM_SKILL_DISTANCEPERCENT, 140) +skill:setParameter(CONDITION_PARAM_DISABLE_DEFENSE, true) +skill:setParameter(CONDITION_PARAM_BUFF_SPELL, true) +combat:addCondition(skill) + +local speed = Condition(CONDITION_PARALYZE) +speed:setParameter(CONDITION_PARAM_TICKS, 10000) +speed:setFormula(-0.7, 56, -0.7, 56) +combat:addCondition(speed) + +local exhaustHealGroup = Condition(CONDITION_SPELLGROUPCOOLDOWN) +exhaustHealGroup:setParameter(CONDITION_PARAM_SUBID, 2) +exhaustHealGroup:setParameter(CONDITION_PARAM_TICKS, 10000) +combat:addCondition(exhaustHealGroup) + +local exhaustSupportGroup = Condition(CONDITION_SPELLGROUPCOOLDOWN) +exhaustSupportGroup:setParameter(CONDITION_PARAM_SUBID, 3) +exhaustSupportGroup:setParameter(CONDITION_PARAM_TICKS, 10000) +combat:addCondition(exhaustSupportGroup) + +function onCastSpell(creature, variant) + return combat:execute(creature, variant) +end diff --git a/data/spells/scripts/support/strong haste.lua b/data/spells/scripts/support/strong haste.lua new file mode 100644 index 00000000000..9e8697fefea --- /dev/null +++ b/data/spells/scripts/support/strong haste.lua @@ -0,0 +1,27 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) + +local condition = Condition(CONDITION_HASTE) +condition:setParameter(CONDITION_PARAM_TICKS, 22000) +condition:setFormula(0.7, -56, 0.7, -56) +combat:addCondition(condition) + +function onCastSpell(creature, var) + local summons = creature:getSummons() + if summons and type(summons) == 'table' and #summons > 0 then + for i = 1, #summons do + local summon = summons[i] + local summon_t = summon:getType() + if summon_t and summon_t:isPet() then + local deltaSpeed = math.max(creature:getBaseSpeed() - summon:getBaseSpeed(), 0) + local PetSpeed = ((summon:getBaseSpeed() + deltaSpeed) * 0.7) - 56 + local PetHaste = createConditionObject(CONDITION_HASTE) + setConditionParam(PetHaste, CONDITION_PARAM_TICKS, 22000) + setConditionParam(PetHaste, CONDITION_PARAM_SPEED, PetSpeed) + summon:addCondition(PetHaste) + end + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/support/swift foot.lua b/data/spells/scripts/support/swift foot.lua new file mode 100644 index 00000000000..48a774b6045 --- /dev/null +++ b/data/spells/scripts/support/swift foot.lua @@ -0,0 +1,40 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) + +local exhaust = Condition(CONDITION_EXHAUST_COMBAT) +exhaust:setParameter(CONDITION_PARAM_TICKS, 10000) +combat:addCondition(exhaust) + +local condition = Condition(CONDITION_HASTE) +condition:setParameter(CONDITION_PARAM_TICKS, 10000) +condition:setFormula(0.8, -72, 0.8, -72) +combat:addCondition(condition) + +local exhaustAttackGroup = Condition(CONDITION_SPELLGROUPCOOLDOWN) +exhaustAttackGroup:setParameter(CONDITION_PARAM_SUBID, 1) +exhaustAttackGroup:setParameter(CONDITION_PARAM_TICKS, 10000) +combat:addCondition(exhaustAttackGroup) + +local disable = Condition(CONDITION_PACIFIED) +disable:setParameter(CONDITION_PARAM_TICKS, 10000) +combat:addCondition(disable) + +function onCastSpell(creature, var) + local summons = creature:getSummons() + if summons and type(summons) == 'table' and #summons > 0 then + for i = 1, #summons do + local summon = summons[i] + local summon_t = summon:getType() + if summon_t and summon_t:isPet() then + local deltaSpeed = math.max(creature:getBaseSpeed() - summon:getBaseSpeed(), 0) + local PetSpeed = ((summon:getBaseSpeed() + deltaSpeed) * 0.8) - 72 + local PetHaste = createConditionObject(CONDITION_HASTE) + setConditionParam(PetHaste, CONDITION_PARAM_TICKS, 10000) + setConditionParam(PetHaste, CONDITION_PARAM_SPEED, PetSpeed) + summon:addCondition(PetHaste) + end + end + end + return combat:execute(creature, var) +end diff --git a/data/spells/scripts/support/ultimate light.lua b/data/spells/scripts/support/ultimate light.lua new file mode 100644 index 00000000000..8bba89b39f8 --- /dev/null +++ b/data/spells/scripts/support/ultimate light.lua @@ -0,0 +1,13 @@ +local combat = Combat() +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) +combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0) + +local condition = Condition(CONDITION_LIGHT) +condition:setParameter(CONDITION_PARAM_LIGHT_LEVEL, 8) +condition:setParameter(CONDITION_PARAM_LIGHT_COLOR, 215) +condition:setParameter(CONDITION_PARAM_TICKS, (60 * 33 + 10) * 1000) +combat:addCondition(condition) + +function onCastSpell(creature, var) + return combat:execute(creature, var) +end diff --git a/data/spells/spells.xml b/data/spells/spells.xml new file mode 100644 index 00000000000..c1abdd859dd --- /dev/null +++ b/data/spells/spells.xml @@ -0,0 +1,1298 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/stages.lua b/data/stages.lua new file mode 100644 index 00000000000..b18d141a43a --- /dev/null +++ b/data/stages.lua @@ -0,0 +1,75 @@ +-- Minlevel and multiplier are MANDATORY +-- Maxlevel is OPTIONAL, but is considered infinite by default +-- Create a stage with minlevel 1 and no maxlevel to disable stages +experienceStages = { + { + minlevel = 1, + maxlevel = 8, + multiplier = 7 + }, { + minlevel = 9, + maxlevel = 20, + multiplier = 6 + }, { + minlevel = 21, + maxlevel = 50, + multiplier = 5 + }, { + minlevel = 51, + maxlevel = 100, + multiplier = 4 + }, { + minlevel = 101, + multiplier = 2 + } +} + +skillsStages = { + { + minlevel = 10, + maxlevel = 60, + multiplier = 15 + }, { + minlevel = 61, + maxlevel = 80, + multiplier = 10 + }, { + minlevel = 81, + maxlevel = 110, + multiplier = 6 + }, { + minlevel = 111, + maxlevel = 125, + multiplier = 4 + }, { + minlevel = 126, + multiplier = 2 + } +} + +magicLevelStages = { + { + minlevel = 0, + maxlevel = 60, + multiplier = 10 + }, { + minlevel = 61, + maxlevel = 80, + multiplier = 7 + }, { + minlevel = 81, + maxlevel = 100, + multiplier = 5 + }, { + minlevel = 101, + maxlevel = 110, + multiplier = 4 + }, { + minlevel = 111, + maxlevel = 125, + multiplier = 3 + }, { + minlevel = 126, + multiplier = 2 + } +} diff --git a/data/startup/README.md b/data/startup/README.md new file mode 100644 index 00000000000..fed2e5dd56d --- /dev/null +++ b/data/startup/README.md @@ -0,0 +1,115 @@ +Reserved action/unique for tables: + +Door level: +The defined range is from 1000/1999 +Since the three numbers after 1 determine the level +Example: +Level 10 = 1010 +Level 100 = 1100 + +Chest (action) = 5000/12000 +Chest (unique) = 5000/12000 +Chests custom (action) 12001/15000 +Chests custom (unique) 12001/15000 +Reward keys = 5000/6000 + +TeleportItem (action) = 15001/20000 (this is teleport items, not magic forcefield) +TeleportItem (unique) = 15001/20000 (this is teleport items, not magic forcefield) + +Corpse (action )= 20000/25000 +Corpse (unique) = 20000/22000 + +DoorStorage (action) = It is not defined, because it uses storages as action +DoorStorage (unique) = 22001/25000 + +Tile (action) = 25001/29000 +Tile (unique) = 25001/29000 +Tile remove/create item (action) = 29001/30000 +Tile remove/create item (unique) = 29001/30000 + +Lever (action) = 30001/35000 +Lever (unique) = 30001/35000 + +Teleport (action) = 35001/40000 (this is magic forcefield items) +Teleport (unique) = 35001/40000 (this is magic forcefield items) + +Item (action) = 40001/42000 +Item (unique) = 40001/42000 + +This folder was created exclusively for tables and functions that are loaded at startup or that cannot be reloaded, thus maintaining greater organization in the files. + +Action IDS + Use actionID only if you need to create a function that is called multiple times in different locations. + The action is also used as storage, "x" storage is added in the player, + and the same action number gives access to a door, for example. + + Reserved player action storage key ranges (const.h at the source) + [10000000 - 20000000] + [1000 - 1500] + [2001 - 2011] + + Others reserved player action/storages + [100] = unmoveable/untrade/unusable items + [101] = use pick floor + [102] = down floor action + [103] = key 0010 + [103-120] = keys action + [104] = Parchment of the parchment room quest + [303] = key 0303 + [1000] = level door. Here 1 must be used followed by the level. Example: 1010 = level 10, 1100 = level 100] + [3001-3008] = key 3001/3008 + [3012] = key 3012 + [3033] = key 3033 + [3100] = key 3100 + [3142] = key 3142 + [3200] = key 3200 + [3301] = key 3301 + [3302] = key 3302 + [3303] = key 3303 + [3304] = key 3304 + [3350] = key 3350 + [3520] = key 3520 + [3600] = key 3600 + [3610] = key 3610 + [3620] = key 3620 + [3650] = key 3650 + [3666] = key 3666 + [3667] = key 3667 + [3700] = key 3700 + [3701/3703] = key 3701/3703 + [3800/3802] = key 3800/3802 + [3899] = key 3899 + [3900] = key 3900 + [3909/3917] = key 3909/3917 + [3923] = key 3923 + [3925] = key 3925 + [3930] = key 3930 + [3932] = key 3932 + [3934] = key 3934 + [3935] = key 3935 + [3936] = key 3936 + [3938] = key 3938 + [3940] = key 3940 + [3950] = key 3950 + [3960] = key 3960 + [3980] = key 3980 + [3988] = key 3988 + [4001] = key 4001 + [4009] = key 4009 + [4022] = key 4022 + [4023] = key 4023 + [4033] = key 4033 + [4037] = key 4037 + [4055] = key 4055 + [4210] = key 4210 + [4501] = key 4501 + [4502] = key 4502 + [4503] = key 4503 + [4600] = key 4600 + [4601] = key 4601 + [4603] = key 4603 + [5000] = key 5000 + [5002] = key 5002 + [5010] = key 5010 + [5050] = key 5050 + [6010] = key 6010 diff --git a/data/startup/others/bitwise_flags.lua b/data/startup/others/bitwise_flags.lua new file mode 100644 index 00000000000..c6e6b6c07f1 --- /dev/null +++ b/data/startup/others/bitwise_flags.lua @@ -0,0 +1,19 @@ +-- Lua 5.1 doesn't have support for bitwise operations + +function testFlag(set, flag) + return set % (2*flag) >= flag +end + +function setFlag(set, flag) + if set % (2*flag) >= flag then + return set + end + return set + flag +end + +function clearFlag(set, flag) + if set % (2*flag) >= flag then + return set - flag + end + return set +end \ No newline at end of file diff --git a/data/startup/others/functions.lua b/data/startup/others/functions.lua new file mode 100644 index 00000000000..985c4fd5b03 --- /dev/null +++ b/data/startup/others/functions.lua @@ -0,0 +1,209 @@ +-- These functions load the action/unique tables on the map +function loadLuaMapAction(tablename) + -- It load actions + for index, value in pairs(tablename) do + for i = 1, #value.itemPos do + local tile = Tile(value.itemPos[i]) + local item + -- Checks if the position is valid + if tile then + -- Checks that you have no items created + if tile:getItemCountById(value.itemId) == 0 then + Spdlog.warn("[loadLuaMapAction] - Wrong item id found") + Spdlog.warn(string.format("Action id: %d, item id: %d", + index, value.itemId)) + end + if tile:getItemCountById(value.itemId) == 1 then + item = tile:getItemById(value.itemId) + end + -- If he found the item, add the action id. + if item and value.itemId ~= false then + item:setAttribute(ITEM_ATTRIBUTE_ACTIONID, index) + end + if value.itemId == false and tile:getTopDownItem() then + tile:getTopDownItem():setAttribute(ITEM_ATTRIBUTE_ACTIONID, index) + end + if value.itemId == false and tile:getTopTopItem() then + tile:getTopTopItem():setAttribute(ITEM_ATTRIBUTE_ACTIONID, index) + end + if value.itemId == false and tile:getGround() then + tile:getGround():setAttribute(ITEM_ATTRIBUTE_ACTIONID, index) + end + if value.isDailyReward then + if item:isContainer() then + if item:getSize() > 0 then + item:getItem():setAttribute(ITEM_ATTRIBUTE_ACTIONID, index) + end + end + end + end + end + end +end + +function loadLuaMapUnique(tablename) + -- It load uniques + for index, value in pairs(tablename) do + local tile = Tile(value.itemPos) + local item + -- Checks if the position is valid + if tile then + -- Checks that you have no items created + if tile:getItemCountById(value.itemId) == 0 then + Spdlog.warn("[loadLuaMapUnique] - Wrong item id found") + Spdlog.warn("Unique id: ".. index ..", item id: ".. value.itemId .."") + end + if tile:getItemCountById(value.itemId) == 1 then + item = tile:getItemById(value.itemId) + end + -- If he found the item, add the unique id + if item then + item:setAttribute(ITEM_ATTRIBUTE_UNIQUEID, index) + end + end + end +end + +function loadLuaMapSign(tablename) + -- It load signs on map table + for index, value in pairs(tablename) do + local tile = Tile(value.itemPos) + local item + -- Checks if the position is valid + if tile then + -- Checks that you have no items created + if tile:getItemCountById(value.itemId) == 0 then + Spdlog.warn("[loadLuaMapSign] - Wrong item id found") + Spdlog.warn("Sign id: ".. index ..", item id: ".. value.itemId .."") + end + if tile:getItemCountById(value.itemId) == 1 then + item = tile:getItemById(value.itemId) + end + -- If he found the item, add the text + if item then + item:setAttribute(ITEM_ATTRIBUTE_TEXT, value.text) + end + end + end +end + +function loadLuaMapBookDocument(tablename) + -- Index 1: total valid, index 2: total loaded + local totals = {0, 0} + for index, value in ipairs(tablename) do + local tile = Tile(value.position) + -- Check position (some items dont have a know position yet defined, lets ignore them) + if value.position then + totals[1] = totals[1] + 1 + -- Check if is a valid tile + if tile then + -- Try find the container on the map if containerId is set + local container = (value.containerId and tile:getItemById(value.containerId) or nil) + -- Check if cotainerId is not set or if containerId is set also if the container exists + if not value.containerId or value.containerId and container then + local item + -- Check if the item need to be in a container + if container then + -- Create the item inside the container + item = container:addItem(value.itemId, 1, INDEX_WHEREEVER, FLAG_NOLIMIT) + else + -- Try first find the item on the map (in some cases the item is already on the map) + item = tile:getItemById(value.itemId) + -- Create the item at map position if dont was found + if not item then + item = Game.createItem(value.itemId, 1, value.position) + end + end + -- If the item exists, add the text + if item then + item:setAttribute(ITEM_ATTRIBUTE_TEXT, value.text) + totals[2] = totals[2] + 1 + else + Spdlog.warn("[loadLuaMapBookDocument] - Item not found! Index: ".. index ..", itemId: ".. value.itemId.."") + end + else + Spdlog.warn("[loadLuaMapBookDocument] - Container not found! Index: ".. index ..", containerId: ".. value.containerId.."") + end + else + Spdlog.warn("[loadLuaMapBookDocument] - Tile not found! Index: ".. index ..", position: x: ".. value.position.x.." y: ".. value.position.y .." z: ".. value.position.z .."") + end + end + end + if totals[1] == totals[2] then + Spdlog.info("Loaded ".. totals[2] .." books and documents in the map") + else + Spdlog.info("Loaded ".. totals[2] .." of ".. totals[1] .." books and documents in the map") + end +end + +--[[ +-- NOTE: THIS FUNCTION IS DESATIVATED, NPCS IS NOW BY XML (world/otservbr-npc.xml) +function loadLuaNpcs(tablename) + for index, value in pairs(tablename) do + if value.name and value.position then + local spawn = Game.createNpc(value.name, value.position) + if spawn then + spawn:setMasterPos(value.position) + Game.setStorageValue(Storage.NpcSpawn, 1) + end + end + end + Spdlog.info("Loaded ".. (#NpcTable) .." npcs and spawned ".. Game.getMonsterCount() .." monsters") + Spdlog.info("Loaded ".. #Game.getTowns() .. " towns with ".. #Game.getHouses() .." houses in total") +end +]] +-- Function for load the map and spawm custom (config.lua line 92) +-- Set mapCustomEnabled to false for disable the custom map +function loadCustomMap() + local mapName = configManager.getString(configKeys.MAP_CUSTOM_NAME) + if configManager.getBoolean(configKeys.MAP_CUSTOM_ENABLED) then + Spdlog.info("Loading custom map") + Game.loadMap(configManager.getString(configKeys.MAP_CUSTOM_FILE)) + Spdlog.info("Loaded " .. mapName .. " map") + -- It's load the spawn + -- 10 * 1000 = 10 seconds delay for load the spawn after loading the map + addEvent( + function() + --Game.loadSpawnFile(configManager.getString(configKeys.MAP_CUSTOM_SPAWN)) + --Spdlog.info("Loaded " .. mapName .. " spawn") + end, 10 * 1000) + end +end + +-- Functions that cannot be used in reload command, so they have been moved here +-- Prey slots consumption +function preyTimeLeft(player, slot) + local timeLeft = player:getPreyTimeLeft(slot) / 60 + local monster = player:getPreyCurrentMonster(slot) + if (timeLeft >= 1) then + local playerId = player:getId() + local currentTime = os.time() + local timePassed = currentTime - nextPreyTime[playerId][slot] + + -- Setting new timeleft + if timePassed >= 59 then + timeLeft = timeLeft - 1 + nextPreyTime[playerId][slot] = currentTime + 60 + end + + -- Sending new timeLeft + player:setPreyTimeLeft(slot, timeLeft * 60) + else + -- Performing automatic Bonus/LockPrey actions + if player:getPreyTick(slot) == 1 then + player:setAutomaticBonus(slot) + player:sendPreyData(slot) + return true + elseif player:getPreyTick(slot) == 2 then + player:setAutomaticBonus(slot) + player:sendPreyData(slot) + return true + end + + -- Expiring prey as there's no timeLeft + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("Your %s's prey has expired.", monster:lower())) + player:setPreyCurrentMonster(slot, "") + end + + return player:sendPreyData(slot) +end diff --git a/data/startup/others/hireling_lib.lua b/data/startup/others/hireling_lib.lua new file mode 100644 index 00000000000..dbd6d0c10a0 --- /dev/null +++ b/data/startup/others/hireling_lib.lua @@ -0,0 +1,700 @@ +HIRELING_CREDITS = { + Developer = 'Leonardo "Leu" Pereira (jlcvp)', + Version = "1.0-CoronaVaires", + Date = "29/04/2020" +} + +local DEBUG = true -- print debug to console + +HIRELING_CACHE_STORAGE = {} +HIRELINGS = {} +PLAYER_HIRELINGS = {} +HIRELING_OUTFIT_CHANGING = {} + +function DebugPrint(str) + if DEBUG == true then + Spdlog.debug(str) + end +end + +function printTable(t) + local str = '{' + + for k,v in pairs(t) do + str = str .. string.format( "\n %s = %s",tostring(k), tostring(v)) + end + str = str.. '\n}' + Spdlog.debug(str) +end + +-- [[ Constants and ENUMS ]] + +HIRELING_SKILLS = { + BANKER = 1, -- 1<<0 + COOKING = 2, -- 1<<1 + STEWARD = 4, -- 1<<2 + TRADER = 8 -- 1<<3 +} + +HIRELING_SEX = { + FEMALE = 0, + MALE = 1 +} + +HIRELING_OUTFIT_DEFAULT = { name = "Citizen", female = 1107, male = 1108 } + +HIRELING_OUTFITS = { + BANKER = 1, -- 1<<0 + COOKING = 2, -- 1<<1 + STEWARD = 4, -- 1<<2 + TRADER = 8, -- 1<<3 ... + SERVANT = 16, + HYDRA = 32, + FERUMBRAS = 64, + BONELORD = 128, + DRAGON = 256 +} + +HIRELING_OUTFITS_TABLE = { + BANKER = {name = "Banker Dress", female = 1109, male = 1110}, + BONELORD = {name = "Bonelord Dress", female = 1123, male = 1124}, + COOKING = {name = "Cook Dress", female = 1113, male = 1114}, + DRAGON = {name = "Dragon Dress", female = 1125, male = 1126}, + FERUMBRAS = {name = "Ferumbras Dress", female = 1131, male = 1132}, + HYDRA = {name = "Hydra Dress", female = 1129, male = 1130}, + SERVANT = {name = "Servant Dress", female = 1117, male = 1118}, + STEWARD = {name = "Stewart Dress", female = 1115, male = 1116}, + TRADER = {name = "Trader Dress", female = 1111, male = 1112} +} + +HIRELING_STORAGE = { + SKILL = 28800, + OUTFIT = 28900 +} + +HIRELING_LAMP_ID = 34070 +HIRELING_ATTRIBUTE = "HIRELING_ID" + +HIRELING_FOODS_BOOST = { + MAGIC = 35174, + MELEE = 35175, + SHIELDING = 35172, + DISTANCE = 35173, +} + +HIRELING_FOODS = { -- only the non-skill ones + 35176, 35177, 35178, 35179, 35180 +} + +-- [[ LOCAL FUNCTIONS AND UTILS ]] + +local function checkHouseAccess(hireling) + --check if owner still have access to the house + if hireling.active == 0 then return false end + + local house = hireling:getPosition():getTile():getHouse() + local player = Player(hireling:getOwnerId()) + if not player then + player = Game.getOfflinePlayer(hireling:getOwnerId()) + end + + if house:getOwnerGuid() == hireling:getOwnerId() then return true end + + -- player is not invited anymore, return to lamp + Spdlog.info("Returning Hireling:" .. hireling:getName() .. " to owner Inbox") + local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX) + local lamp = inbox:addItem(HIRELING_LAMP_ID, 1) + lamp:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, "This mysterious lamp summons your very own personal hireling.\nThis item cannot be traded.\nThis magic lamp is the home of " .. hireling:getName() .. ".") + lamp:setSpecialAttribute(HIRELING_ATTRIBUTE, hireling:getId()) --save hirelingId on item + player:save() + hireling.active = 0 + hireling.cid = -1 + hireling:setPosition({x=0,y=0,z=0}) + +end + +local function spawnNPCs() + Spdlog.info("Spawning Hirelings") + local hireling + for i=1,#HIRELINGS do + hireling = HIRELINGS[i] + + if checkHouseAccess(hireling) then + hireling:spawn() + end + end +end + +local function addStorageCacheValue(player_id, storage, value) + if not HIRELING_CACHE_STORAGE[player_id] then + HIRELING_CACHE_STORAGE[player_id] = {} + end + HIRELING_CACHE_STORAGE[player_id][storage] = value +end + +local function initStorageCache() + local sql = string.format("SELECT `player_id`, `key`, `value` FROM `player_storage` ".. + "WHERE `key` IN (%d,%d)", HIRELING_STORAGE.SKILL, HIRELING_STORAGE.OUTFIT) + + local resultId = db.storeQuery(sql) + if resultId ~= false then + local player_id, key, value + repeat + player_id = result.getNumber(resultId,"player_id") + key = result.getNumber(resultId,"key") + value = result.getNumber(resultId,"value") + + addStorageCacheValue(player_id, key, value) + until not result.next(resultId) + result.free(resultId) + end +end + +local function getStorageForPlayer(player_id, storage) + local player = Player(player_id) + if player then + return player:getStorageValue(storage) + else + return HIRELING_CACHE_STORAGE[player_id] and HIRELING_CACHE_STORAGE[player_id][storage] or -1 + end +end + +-- [[ DEFINING HIRELING CLASS ]] + +Hireling = { + id = -1, + player_id = -1, + name = 'hireling', + skills = 0, + active = 0, + sex = 0, + posx = 0, + posy = 0, + posz = 0, + lookbody = 34, + lookfeet = 116, + lookhead = 97, + looklegs = 3, + looktype = 0, + cid = -1 +} + +function Hireling:new(o) + o = o or {} + setmetatable(o, self) + self.__index = self + return o +end + +function Hireling:getOwnerId() + return self.player_id +end + +function Hireling:getId() + return self.id +end + +function Hireling:getName() + return self.name +end + +function Hireling:canTalkTo(player) + if not player then return false end + + local tile = Tile(player:getPosition()) + if not tile then return false end + local house = tile:getHouse() + if not house then return false end + + local hirelingHouse = Tile(self:getPosition()):getHouse() + + return house:getId() == hirelingHouse:getId() +end + +function Hireling:getPosition() + return Position(self.posx,self.posy, self.posz) +end + +function Hireling:setPosition(pos) + self.posx = pos.x + self.posy = pos.y + self.posz = pos.z +end + +function Hireling:getOutfit() + local outfit = { + lookType=self.looktype, + lookHead=self.lookhead, + lookAddons=0, + lookMount=0, + lookLegs=self.looklegs, + lookBody=self.lookbody, + lookFeet=self.lookfeet + } + + return outfit +end + +function Hireling:getAvailableOutfits() + + local flags = getStorageForPlayer(self:getOwnerId(),HIRELING_STORAGE.OUTFIT) + local sex = (self.sex == HIRELING_SEX.FEMALE) and 'female' or 'male' + + local outfits = {} + -- add default outfit + table.insert(outfits, { name = HIRELING_OUTFIT_DEFAULT.name, lookType = HIRELING_OUTFIT_DEFAULT[sex] }) + if flags >0 then + local outfit + for key, value in pairs(HIRELING_OUTFITS) do + if hasBitSet(value, flags) then + outfit = { + name = HIRELING_OUTFITS_TABLE[key].name, + lookType = HIRELING_OUTFITS_TABLE[key][sex] + } + table.insert(outfits, outfit) + end + end + end + + return outfits +end + +function Hireling:requestOutfitChange() + local player = Player(self:getOwnerId()) + + HIRELING_OUTFIT_CHANGING[self:getOwnerId()] = self:getId() + player:sendHirelingOutfitWindow(self) +end + +function Hireling:hasOutfit(lookType) + local outfits = self:getAvailableOutfits() + local found = false + for _,outfit in ipairs(outfits) do + if outfit.lookType == lookType then + return true + end + end + + return found +end + +function Hireling:setOutfit(outfit) + self.looktype = outfit.lookType + self.lookhead = outfit.lookHead + self.lookbody = outfit.lookBody + self.looklegs = outfit.lookLegs + self.lookfeet = outfit.lookHead + self.lookAddons = outfit.lookAddons +end + +function Hireling:changeOutfit(outfit) + HIRELING_OUTFIT_CHANGING[self:getOwnerId()] = nil --clear flag + + if not self:hasOutfit(outfit.lookType) then return end + + local npc = Npc(self.cid) + local creature = Creature(npc) --maybe self.cid works here too + + creature:setOutfit(outfit) + self:setOutfit(outfit) +end + + +function Hireling:hasSkill(SKILL) + local skills = getStorageForPlayer(self:getOwnerId(), HIRELING_STORAGE.SKILL) + if skills <= 0 then + return false + else + return hasBitSet(SKILL, skills) + end +end + +function Hireling:setCreature(cid) + self.cid = cid +end + +function Hireling:save() + local sql = "UPDATE `player_hirelings` SET" + sql = sql .. " `name`=" .. db.escapeString(self.name) + sql = sql .. ", `active`=" .. tostring(self.active) + sql = sql .. ", `sex`=" .. tostring(self.sex) + sql = sql .. ", `posx`=" .. tostring(self.posx) + sql = sql .. ", `posy`=" .. tostring(self.posy) + sql = sql .. ", `posz`=" .. tostring(self.posz) + sql = sql .. ", `lookbody`=" .. tostring(self.lookbody) + sql = sql .. ", `lookfeet`=" .. tostring(self.lookfeet) + sql = sql .. ", `lookhead`=" .. tostring(self.lookhead) + sql = sql .. ", `looklegs`=" .. tostring(self.looklegs) + sql = sql .. ", `looktype`=" .. tostring(self.looktype) + + sql = sql .. " WHERE `id`=" .. tostring(self.id) + + db.query(sql) +end + +function Hireling:spawn() + self.active = 1 + local npc = Npc(Game.generateNpc('hireling')) + npc:setName(self:getName()) + local creature = Creature(npc) + creature:setOutfit(self:getOutfit()) + npc:setSpeechBubble(7) + + npc:place(self:getPosition()) + creature:getPosition():sendMagicEffect(CONST_ME_TELEPORT) +end + +function Hireling:returnToLamp(player_id) + local creature = Creature(self.cid) + local player = Player(player_id) + local lampType = ItemType(HIRELING_LAMP_ID) + + if self:getOwnerId() ~= player_id then + player:getPosition():sendMagicEffect(CONST_ME_POFF) + return player:sendTextMessage(MESSAGE_FAILURE, "You are not the master of this hireling.") + end + + if player:getFreeCapacity() < lampType:getWeight(1) then + player:getPosition():sendMagicEffect(CONST_ME_POFF) + return player:sendTextMessage(MESSAGE_FAILURE, "You do not have enough capacity.") + end + + local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX) + if not inbox or inbox:getEmptySlots() == 0 then + player:getPosition():sendMagicEffect(CONST_ME_POFF) + return player:sendTextMessage(MESSAGE_FAILURE, "You don't have enough room in your inbox.") + end + + + local lamp = inbox:addItem(HIRELING_LAMP_ID, 1) + creature:getPosition():sendMagicEffect(CONST_ME_PURPLESMOKE) + creature:remove() --remove hireling + lamp:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, "This mysterious lamp summons your very own personal hireling.\nThis item cannot be traded.\nThis magic lamp is the home of " .. self:getName() .. ".") + lamp:setSpecialAttribute(HIRELING_ATTRIBUTE, self:getId()) --save hirelingId on item + self.active = 0 + self.cid = -1 + self:setPosition({x=0,y=0,z=0}) +end +-- [[ END CLASS DEFINITION ]] + +-- [[ GLOBAL FUNCTIONS DEFINITIONS ]] + +function SaveHirelings() + for _, hireling in ipairs(HIRELINGS) do + hireling:save() + end +end +function getHirelingById(id) + local hireling + for i = 1, #HIRELINGS do + hireling = HIRELINGS[i] + if hireling:getId() == id then + return hireling + end + end + return nil +end + +function getHirelingByPosition(position) + local hireling + for i = 1, #HIRELINGS do + hireling = HIRELINGS[i] + if hireling.posx == position.x and hireling.posy == position.y and hireling.posz == position.z then + return hireling + end + end + return nil +end + +function HirelingsInit() + local rows = db.storeQuery("SELECT * FROM `player_hirelings`") + + if rows then + repeat + local player_id = result.getNumber(rows, "player_id") + + if not PLAYER_HIRELINGS[player_id] then + PLAYER_HIRELINGS[player_id] = {} + end + + local hireling = Hireling:new() + hireling.id = result.getNumber(rows, "id") + hireling.player_id = player_id + hireling.name = result.getString(rows, "name") + hireling.active = result.getNumber(rows, "active") + hireling.sex = result.getNumber(rows, "sex") + hireling.posx = result.getNumber(rows, "posx") + hireling.posy = result.getNumber(rows, "posy") + hireling.posz = result.getNumber(rows, "posz") + hireling.lookbody = result.getNumber(rows, "lookbody") + hireling.lookfeet = result.getNumber(rows, "lookfeet") + hireling.lookhead = result.getNumber(rows, "lookhead") + hireling.looklegs = result.getNumber(rows, "looklegs") + hireling.looktype = result.getNumber(rows, "looktype") + + table.insert(PLAYER_HIRELINGS[player_id], hireling) + table.insert(HIRELINGS, hireling) + until not result.next(rows) + result.free(rows) + + spawnNPCs() + initStorageCache() + + end +end + +function PersistHireling(hireling) + + db.query(string.format("INSERT INTO `player_hirelings` (`player_id`,`name`,`active`,`sex`,`posx`,`posy`,`posz`,`lookbody`,`lookfeet`,`lookhead`,`looklegs`,`looktype`) VALUES (%d, %s, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", + hireling.player_id, db.escapeString(hireling.name), hireling.active, hireling.sex, hireling.posx, hireling.posy, hireling.posz, hireling.lookbody, hireling.lookfeet, hireling.lookhead, hireling.looklegs, hireling.looktype) + ) + + local hirelings = PLAYER_HIRELINGS[hireling.player_id] or {} + local ids = "" + for i=1,#hirelings do + if i > 1 then + ids = ids .. "','" + end + ids = ids .. tostring(hirelings[i].id) + end + local query = string.format("SELECT `id` FROM `player_hirelings` WHERE `player_id`= %d and `id` NOT IN ('%s')", hireling.player_id, ids) + local resultId = db.storeQuery(query) + + if resultId then + local id = result.getNumber(resultId, 'id') + hireling.id = id + return true + else + return false + end +end + + + +-- [[ END GLOBAL FUNCTIONS ]] + +-- [[ Player extension ]] +function Player:getHirelings() + return PLAYER_HIRELINGS[self:getGuid()] or {} +end + +function Player:getHirelingsCount() + local hirelings = self:getHirelings() + return #hirelings +end + +function Player:addNewHireling(name, sex) + local hireling = Hireling:new() + hireling.name = name + hireling.player_id = self:getGuid() + if sex == HIRELING_SEX.FEMALE then + hireling.looktype=136 -- citizen female + hireling.sex = HIRELING_SEX.FEMALE + else + hireling.looktype=128 -- citizen male + hireling.sex = HIRELING_SEX.MALE + end + + local lampType = ItemType(HIRELING_LAMP_ID) + if self:getFreeCapacity() < lampType:getWeight(1) then + self:getPosition():sendMagicEffect(CONST_ME_POFF) + self:sendTextMessage(MESSAGE_FAILURE, "You do not have enough capacity.") + return false + end + + local inbox = self:getSlotItem(CONST_SLOT_STORE_INBOX) + if not inbox or inbox:getEmptySlots() == 0 then + self:getPosition():sendMagicEffect(CONST_ME_POFF) + self:sendTextMessage(MESSAGE_FAILURE, "You don't have enough room in your inbox.") + return false + end + + local saved = PersistHireling(hireling) + if not saved then + DebugPrint('Error saving Hireling:' .. name .. ' - player:' .. self:getName()) + return false + else + if not PLAYER_HIRELINGS[self:getGuid()] then + PLAYER_HIRELINGS[self:getGuid()] = {} + end + table.insert(PLAYER_HIRELINGS[self:getGuid()], hireling) + table.insert(HIRELINGS, hireling) + local lamp = inbox:addItem(HIRELING_LAMP_ID, 1) + lamp:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, "This mysterious lamp summons your very own personal hireling.\nThis item cannot be traded.\nThis magic lamp is the home of " .. hireling:getName() .. ".") + lamp:setSpecialAttribute(HIRELING_ATTRIBUTE, hireling:getId()) --save hirelingId on item + hireling.active = 0 + return hireling + end +end + +function Player:isChangingHirelingOutfit() + return HIRELING_OUTFIT_CHANGING[self:getGuid()] and HIRELING_OUTFIT_CHANGING[self:getGuid()] > 0 or false +end + +function Player:getHirelingChangingOutfit() + local id = HIRELING_OUTFIT_CHANGING[self:getGuid()] + if not id then + return nil + end + + return getHirelingById(id) +end + +local function addOutfit(msg, outfit) + msg:addU16(outfit.lookType) + + msg:addByte(outfit.lookHead) + msg:addByte(outfit.lookBody) + msg:addByte(outfit.lookLegs) + msg:addByte(outfit.lookFeet) + msg:addByte(outfit.lookAddons) + msg:addU16(outfit.lookMount) + msg:addByte(0) + msg:addByte(0) + msg:addByte(0) + msg:addByte(0) + msg:addU16(0) +end + +function Player:sendHirelingOutfitWindow(hireling) + local msg = NetworkMessage() + local client = self:getClient() + msg:addByte(200) -- header + addOutfit(msg, hireling:getOutfit()) -- current outfit + + local availableOutfits = hireling:getAvailableOutfits() + + if client.version >= 1185 then + msg:addU16(#availableOutfits) + else + msg:addByte(#availableOutfits) + end + + for _,outfit in ipairs(availableOutfits) do + msg:addU16(outfit.lookType) + msg:addString(outfit.name) + msg:addByte(0x00) -- addons + + if client.version >= 1185 then + -- something related to the store button (offer_id maybe) not using now + msg:addByte(0x00) + end + end + + -- mounts disabled for hirelings + if client.version >= 1185 then + msg:addU16(0x00) --mounts count + msg:addU16(0x00) --familiar count + msg:addByte(0x00) -- dunno + msg:addByte(0x00) -- dunno2 + else + msg:addByte(0x00) + end + + msg:sendToPlayer(self) +end + +function Player:hasHirelings() + return PLAYER_HIRELINGS[self:getGuid()] and #PLAYER_HIRELINGS[self:getGuid()] > 0 or false +end + +function Player:copyHirelingStorageToCache() + if(self:hasHirelings()) then + local storageSkill = self:getStorageValue(HIRELING_STORAGE.SKILL) + local storageOutfit = self:getStorageValue(HIRELING_STORAGE.OUTFIT) + addStorageCacheValue(self:getGuid(),HIRELING_STORAGE.SKILL, storageSkill) + addStorageCacheValue(self:getGuid(),HIRELING_STORAGE.OUTFIT, storageOutfit) + end +end + +function Player:findHirelingLamp(hirelingId) + local inbox = self:getSlotItem(CONST_SLOT_STORE_INBOX) + if not inbox then return nil end + + local lastIndex = inbox:getSize() - 1 + for i=0,lastIndex do + local item = inbox:getItem(i) + if item and item:getId() == HIRELING_LAMP_ID and item:getSpecialAttribute(HIRELING_ATTRIBUTE) == hirelingId then + return item + end + end + return nil +end + +function Player:sendHirelingSelectionModal(title, message, callback, data) + -- callback(playerId, data, hireling) + -- get all hireling list + local hirelings = self:getHirelings() + local modal = ModalWindow { + title = title, + message = message + } + local hireling + for i=1,#hirelings do + hireling = hirelings[i] + local choice = modal:addChoice(string.format('#%d - %s', i, hireling:getName())) + choice.hireling = hireling + end + + local playerId = self:getId() + local internalConfirm = function(button, choice) + local hrlng = choice and choice.hireling or nil + callback(playerId, data, hrlng) + end + + local internalCancel = function(btn, choice) callback(playerId, data, nil) end + + modal:addButton('Select',internalConfirm) + modal:setDefaultEnterButton('Select') + modal:addButton('Cancel',internalCancel) + modal:setDefaultEscapeButton('Cancel') + + modal:sendToPlayer(self) +end + +function Player:showInfoModal(title, message, buttonText) + local modal = ModalWindow { + title = title, + message = message + } + buttonText = buttonText or 'Close' + modal:addButton(buttonText,function()end) + modal:setDefaultEscapeButton(buttonText) + + modal:sendToPlayer(self) +end + +function Player:hasHirelingSkill(SKILL) + local skills = self:getStorageValue(HIRELING_STORAGE.SKILL) + if skills <= 0 then + return false + else + return hasBitSet(SKILL, skills) + end +end + +function Player:enableHirelingSkill(SKILL) + local skills = self:getStorageValue(HIRELING_STORAGE.SKILL) + if skills < 0 then skills = 0 end + skills = setFlag(SKILL, skills) + self:setStorageValue(HIRELING_STORAGE.SKILL, skills) + self:copyHirelingStorageToCache() +end + +function Player:hasHirelingOutfit(OUTFIT) + local outfits = self:getStorageValue(HIRELING_STORAGE.OUTFIT) + if outfits <= 0 then + return false + else + return hasBitSet(OUTFIT, outfits) + end +end + +function Player:enableHirelingOutfit(OUTFIT) + local outfits = self:getStorageValue(HIRELING_STORAGE.OUTFIT) + if outfits < 0 then outfits = 0 end + outfits = setFlag(OUTFIT, outfits) + self:setStorageValue(HIRELING_STORAGE.OUTFIT, outfits) + self:copyHirelingStorageToCache() +end +-- [[ END PLAYER EXTENSION ]] diff --git a/data/startup/others/others.lua b/data/startup/others/others.lua new file mode 100644 index 00000000000..5bf063313a5 --- /dev/null +++ b/data/startup/others/others.lua @@ -0,0 +1,3 @@ +dofile('data/startup/others/bitwise_flags.lua') +dofile('data/startup/others/functions.lua') +dofile('data/startup/others/hireling_lib.lua') diff --git a/data/startup/startup.lua b/data/startup/startup.lua new file mode 100644 index 00000000000..b235e099512 --- /dev/null +++ b/data/startup/startup.lua @@ -0,0 +1,2 @@ +dofile('data/startup/tables/tables.lua') +dofile('data/startup/others/others.lua') diff --git a/data/startup/tables/chest.lua b/data/startup/tables/chest.lua new file mode 100644 index 00000000000..fee489e5b6b --- /dev/null +++ b/data/startup/tables/chest.lua @@ -0,0 +1,1008 @@ +--[[ + Look README.md for see the reserved action/unique numbers + From range 5000 to 6000 is reserved for keys chest + From range 6001 to 14000 is reserved for script reward + Path: data\scripts\actions\system\quest_reward_common.lua + + From range 14001 to 15000 is reserved for others scripts (varied rewards) + + There is no need to tamper with the chests scripts, just register a new table and configure correctly + So the quest will work in-game + + Example: + [xxxx] = { + -- For use of the map + itemId = xxxx, + itemPos = {x = xxxxx, y = xxxxx, z = x}, + -- For use of the script + container = xxxx (it's for use reward in a container, only put the id of the container here) + keyAction = xxxx, (it's for use one key in the chest and is reward in container, only put the key in reward and action here) + reward = {{xxxx, x}}, + storage = xxxxx + }, + + Note: + The "for use of the map" variables are only used to create the action or unique on the map during startup + If the reward is an key, do not need to use "keyAction", only set the storage as same action id + + The "for use of the script" variables are used by the scripts + To allow a single script to manage all rewards +]] + +ChestAction = { + -- Keys quest + [5000] = { + itemId = xxxx, + itemPos = { + {x = xxxxx, y = xxxxx, z = x}, + {x = xxxxx, y = xxxxx, z = x} + }, + action = xxxx, + reward = {{xxxx, 1}}, + storage = storage + } +} + +ChestUnique = { + -- Keys quest + -- data\scripts\actions\system\quest_reward_key.lua + -- Deeper fibula quest key 3980 + [5000] = { + isKey = true, + itemId = 385, + itemPos = {x = 32219, y = 32401, z = 10}, + reward = {{2091, 1}}, + storage = Storage.Quest.Key.ID3980 + }, + -- Panpipe quest key 4055 + [5001] = { + isKey = true, + itemId = 1290, + itemPos = {x = 32652, y = 32107, z = 7}, + reward = {{2088, 1}}, + storage = Storage.Quest.Key.ID4055 + }, + -- Dawnport quest key 0010 chest + [5002] = { + isKey = true, + itemId = 1717, + itemPos = {x = 32068, y = 31895, z = 3}, + reward = {{23763, 1}}, + storage = Storage.Quest.Key.ID0010 + }, + -- Emperor's cookies quest key 3800 + [5003] = { + isKey = true, + itemId = 1740, + itemPos = {x = 32605, y = 31908, z = 3}, + reward = {{2089, 1}}, + storage = Storage.Quest.Key.ID3800 + }, + -- Emperor's cookies quest key 3801 + [5004] = { + isKey = true, + itemId = 1740, + itemPos = {x = 32648, y = 31905, z = 3}, + container = 1987, + reward = {{2089, 1}, {2687, 20}, {2687, 7}}, + weight = 44, + storage = Storage.Quest.Key.ID3801 + }, + -- Emperor's cookies quest key 3802 + [5005] = { + isKey = true, + itemId = 1740, + itemPos = {x = 32599, y = 31923, z = 6}, + reward = {{2089, 1}}, + storage = Storage.Quest.Key.ID3802 + }, + -- Black knight quest key 5010 + [5006] = { + isKey = true, + itemId = 2720, + itemPos = {x = 32800, y = 31959, z = 7}, + reward = {{2088, 1}}, + storage = Storage.Quest.Key.ID5010 + }, + [5007] = { + isKey = true, + itemId = 2720, + itemPos = {x = 32813, y = 31964, z = 7}, + reward = {{2088, 1}}, + storage = Storage.Quest.Key.ID5010 + }, + [5008] = { + isKey = true, + itemId = 1740, + itemPos = {x = 32201, y = 31571, z = 10}, + container = 1987, + reward = {{2089, 1}, {2148, 23}, {2260, 1}, {2410, 4}, {2490, 1}}, + weight = 80, + storage = Storage.Quest.Key.ID4502 + }, + [5009] = { + isKey = true, + itemId = 1717, + itemPos = {x = 32411, y = 32155, z = 15}, + reward = {{2088, 1}}, + storage = Storage.Quest.Key.ID3620 + }, + [5010] = { + isKey = true, + itemId = 1717, + itemPos = {x = 32411, y = 32155, z = 15}, + reward = {{2088, 1}}, + storage = Storage.Quest.Key.ID3620 + }, + [5011] = { + isKey = true, + itemId = 2720, + itemPos = {x = 32497, y = 31887, z = 7}, + reward = {{2089, 1}}, + storage = Storage.Quest.Key.ID3899 + }, + + -- To add a reward inside a bag, you need to add the variable "container = bagId" before "reward" + -- Just duplicate the table and configure correctly, the scripts already register the entire table automatically + -- Path: data\scripts\actions\system\quest_reward_common.lua + -- Halls of hope + [6001] = { + itemId = 26408, + itemPos = {x = 32349, y = 32194, z = 9}, + reward = {{26654, 1}}, + storage = Storage.HallsOfHope.Reward1 + }, + [6002] = { + itemId = 26408, + itemPos = {x = 32382, y = 32368, z = 9}, + reward = {{26654, 1}}, + storage = Storage.HallsOfHope.Reward2 + }, + [6003] = { + itemId = 26408, + itemPos = {x = 32287, y = 32119, z = 7}, + reward = {{26654, 1}}, + storage = Storage.HallsOfHope.Reward3 + }, + [6004] = { + itemId = 26409, + itemPos = {x = 32389, y = 32001, z = 6}, + reward = {{26654, 1}}, + storage = Storage.HallsOfHope.Reward4 + }, + [6005] = { + itemId = 26408, + itemPos = {x = 32449, y = 32109, z = 8}, + reward = {{26654, 1}}, + storage = Storage.HallsOfHope.Reward5 + }, + -- Dawnport + -- Legion helmet quest (dawnport) + [6006] = { + itemId = 3058, + itemPos = {x = 32143, y = 31910, z = 8}, + reward = {{2480, 1}}, + storage = Storage.Quest.SanctuaryOfTheLizardGod.LegionHelmet + }, + -- Dawnport quest + -- Torn log book + [6007] = { + itemId = 1740, + itemPos = {x = 32059, y = 31800, z = 10}, + reward = {{23749, 1}}, + storage = Storage.Quest.Dawnport.TornLogBook + }, + -- Deeper fibula quest + -- Tower shield + [6008] = { + itemId = 2843, + itemPos = {x = 32239, y = 32471, z = 10}, + reward = {{2528, 1}}, + storage = Storage.Quest.DeeperFibula.RewardTowerShield + }, + -- Warrior helmet + [6009] = { + itemId = 2843, + itemPos = {x = 32239, y = 32478, z = 10}, + reward = {{2475, 1}}, + storage = Storage.Quest.DeeperFibula.RewardWarriorHelmet + }, + -- Dwarven ring + [6010] = { + itemId = 3058, + itemPos = {x = 32233, y = 32491, z = 10}, + reward = {{2213, 1}}, + storage = Storage.Quest.DeeperFibula.RewardDwarvenRing + }, + -- Elven aulet + [6011] = { + itemId = 2844, + itemPos = {x = 32245, y = 32492, z = 10}, + reward = {{2198, 1}}, + storage = Storage.Quest.DeeperFibula.RewardElvenAmulet + }, + -- Knight axe + [6012] = { + itemId = 3058, + itemPos = {x = 32256, y = 32500, z = 10}, + reward = {{2430, 1}}, + storage = Storage.Quest.DeeperFibula.RewardKnightAxe + }, + -- Short sword quest + -- Book + [6013] = { + itemId = 1740, + itemPos = {x = 32171, y = 32197, z = 7}, + reward = {{1955, 1}}, + storage = Storage.Quest.ShortSword.Book + }, + -- Thais lighthouse quest + -- Battle hammer + [6014] = { + itemId = 1740, + itemPos = {x = 32225, y = 32265, z = 10}, + reward = {{2417, 1}}, + storage = Storage.Quest.ThaisLighthouse.BattleHammer + }, + -- Dark shield + [6015] = { + itemId = 1740, + itemPos = {x = 32226, y = 32265, z = 10}, + reward = {{2521, 1}}, + storage = Storage.Quest.ThaisLighthouse.DarkShield + }, + -- Studded shield quest (rookgaard) + -- Banana free account area + [6016] = { + itemId = 2725, + itemPos = {x = 32172, y = 32169, z = 7}, + reward = {{2676, 1}}, + storage = Storage.Quest.StuddedShield.BananaFree + }, + -- Banana premium account area + [6017] = { + itemId = 2725, + itemPos = {x = 31983, y = 32193, z = 5}, + reward = {{2676, 1}}, + storage = Storage.Quest.StuddedShield.BananaPremium + }, + -- Rope (kazordoon, emperor's cookies quest) + [6018] = { + itemId = 1740, + itemPos = {x = 32604, y = 31908, z = 3}, + reward = {{2120, 1}}, + storage = Storage.Quest.EmperorsCookies.RopeReward + }, + -- Explorer brooch quest (kazordoon) + [6019] = { + itemId = 3058, + itemPos = {x = 32636, y = 31873, z = 10}, + reward = {{4873, 1}}, + storage = Storage.Quest.ExplorerBrooch.Reward + }, + -- Orc fortress quest + -- Knight axe + [6020] = { + itemId = 1738, + itemPos = {x = 32980, y = 31727, z = 9}, + reward = {{2430, 1}}, + storage = Storage.Quest.OrcFortress.KnightAxe + }, + -- Knight armor + [6021] = { + itemId = 1738, + itemPos = {x = 32981, y = 31727, z = 9}, + reward = {{2476, 1}}, + storage = Storage.Quest.OrcFortress.KnightArmor + }, + -- Fire sword + [6022] = { + itemId = 1738, + itemPos = {x = 32985, y = 31727, z = 9}, + reward = {{2392, 1}}, + storage = Storage.Quest.OrcFortress.FireSword + }, + -- Draconia quest + [6023] = { + itemId = 1740, + itemPos = {x = 32803, y = 31582, z = 2}, + reward = {{2396, 1}, {2409, 1}}, + storage = Storage.Quest.Draconia.Reward1 + }, + [6024] = { + itemId = 1740, + itemPos = {x = 32804, y = 31582, z = 2}, + reward = {{2197, 5}, {2167, 1}}, + storage = Storage.Quest.Draconia.Reward2 + }, + -- Adorned UH rune quest + [6025] = { + itemId = 1738, + itemPos = {x = 33136, y = 31601, z = 15}, + reward = {{12559, 1}}, + storage = Storage.Quest.AdornedUHRune.Reward + }, + -- Barbarian axe quest + -- Barbarian axe + [6026] = { + itemId = 1738, + itemPos = {x = 33184, y = 31945, z = 11}, + reward = {{2429, 1}}, + storage = Storage.Quest.BarbarianAxe.BarbarianAxe + }, + -- Scimitar + [6027] = { + itemId = 1738, + itemPos = {x = 33185, y = 31945, z = 11}, + reward = {{2419, 1}}, + storage = Storage.Quest.BarbarianAxe.Scimitar + }, + -- Dark armor quest + [6028] = { + itemId = 3128, + itemPos = {x = 33178, y = 31870, z = 12}, + reward = {{2489, 1}}, + storage = Storage.Quest.DarkArmor.Reward + }, + -- Demon helmet quest + -- Steel boots + [6029] = { + itemId = 1740, + itemPos = {x = 33313, y = 31574, z = 15}, + reward = {{2645, 1}}, + storage = Storage.Quest.DemonHelmet.SteelBoots + }, + -- Demon helmet + [6030] = { + itemId = 1740, + itemPos = {x = 33313, y = 31575, z = 15}, + reward = {{2493, 1}}, + storage = Storage.Quest.DemonHelmet.DemonHelmet + }, + -- Demon shield + [6031] = { + itemId = 1740, + itemPos = {x = 33313, y = 31576, z = 15}, + reward = {{2520, 1}}, + storage = Storage.Quest.DemonHelmet.DemonShield + }, + -- Double hero quest + -- Red gem + [6032] = { + itemId = 1738, + itemPos = {x = 33109, y = 31679, z = 13}, + reward = {{2156, 1}}, + storage = Storage.Quest.DoubleHero.RedGem + }, + -- Club ring + [6033] = { + itemId = 1738, + itemPos = {x = 33110, y = 31679, z = 13}, + reward = {{2209, 1}}, + storage = Storage.Quest.DoubleHero.ClubRing + }, + -- Edron goblin quest + -- Silver amulet + [6034] = { + itemId = 1738, + itemPos = {x = 33095, y = 31800, z = 10}, + reward = {{2170, 200}}, + storage = Storage.Quest.EdronGoblin.SilverAmulet + }, + -- Steel shield + [6035] = { + itemId = 1738, + itemPos = {x = 33095, y = 31801, z = 10}, + reward = {{2509, 1}}, + storage = Storage.Quest.EdronGoblin.SteelShield + }, + -- Fire axe quest + -- Fire axe + [6036] = { + itemId = 2843, + itemPos = {x = 33084, y = 31650, z = 12}, + reward = {{2432, 1}}, + storage = Storage.Quest.FireAxe.FireAxe + }, + -- Ring quest + -- Time ring + [6037] = { + itemId = 1738, + itemPos = {x = 33131, y = 31624, z = 15}, + reward = {{2169, 1}}, + storage = Storage.Quest.Ring.TimeRing + }, + -- Sword ring + [6038] = { + itemId = 1738, + itemPos = {x = 33134, y = 31624, z = 15}, + reward = {{2207, 1}}, + storage = Storage.Quest.Ring.SwordRing + }, + -- Troll cave quest + -- Garlic necklace + [6039] = { + itemId = 1741, + itemPos = {x = 33143, y = 31719, z = 10}, + reward = {{2199, 150}}, + storage = Storage.Quest.TrollCave.GarlicNecklace + }, + -- Brass legs + [6040] = { + itemId = 1741, + itemPos = {x = 33143, y = 31721, z = 10}, + reward = {{2478, 1}}, + storage = Storage.Quest.TrollCave.BrassLegs + }, + -- Vampire shield quest + -- Dragon lance + [6041] = { + itemId = 1738, + itemPos = {x = 33189, y = 31688, z = 14}, + reward = {{2414, 1}}, + storage = Storage.Quest.VampireShield.DragonLance + }, + -- Dragon lance + [6042] = { + itemId = 1738, + itemPos = {x = 33195, y = 31688, z = 14}, + reward = {{2534, 1}}, + storage = Storage.Quest.VampireShield.VampireShield + }, + -- Weeding ring quest + -- Dragon necklace + [6043] = { + itemId = 1738, + itemPos = {x = 33158, y = 31621, z = 15}, + reward = {{2201, 200}}, + storage = Storage.Quest.WeddingRing.DragonNecklace + }, + -- Weeding ring + [6044] = { + itemId = 1738, + itemPos = {x = 33158, y = 31622, z = 15}, + reward = {{2121, 1}}, + storage = Storage.Quest.WeddingRing.WeedingRing + }, + -- Alawars vault quest + -- White pearl + [6045] = { + itemId = 1740, + itemPos = {x = 32105, y = 31567, z = 9}, + reward = {{2143, 3}}, + storage = Storage.Quest.AlawarsVault.WhitePearl + }, + -- Broadsword + [6046] = { + itemId = 1740, + itemPos = {x = 32109, y = 31567, z = 9}, + reward = {{2413, 1}}, + storage = Storage.Quest.AlawarsVault.Broadsword + }, + -- Black knight quest + -- Crown armor + [6047] = { + itemId = 2720, + itemPos = {x = 32868, y = 31955, z = 11}, + reward = {{2487, 1}}, + storage = Storage.Quest.BlackKnight.CrownArmor + }, + -- Crown shield + [6048] = { + itemId = 2720, + itemPos = {x = 32880, y = 31955, z = 11}, + reward = {{2519, 1}}, + storage = Storage.Quest.BlackKnight.CrownShield + }, + -- TIme ring quest + -- Crystal ball + [6049] = { + itemId = 1740, + itemPos = {x = 33038, y = 32171, z = 9}, + reward = {{2192, 1}}, + storage = Storage.Quest.TimeRing.CrystalBall + }, + -- Time ring + [6050] = { + itemId = 1740, + itemPos = {x = 33039, y = 32171, z = 9}, + reward = {{2169, 1}}, + storage = Storage.Quest.TimeRing.TimeRing + }, + -- Elven amulet + [6051] = { + itemId = 1740, + itemPos = {x = 33040, y = 32171, z = 9}, + reward = {{2198, 1}}, + storage = Storage.Quest.TimeRing.ElvenAmulet + }, + -- Behemoth quest + -- Guardian halberd + [6052] = { + itemId = 1740, + itemPos = {x = 33295, y = 31658, z = 13}, + reward = {{2427, 1}}, + storage = Storage.Quest.Behemoth.GuardianHalberd + }, + -- Demon shield + [6053] = { + itemId = 1740, + itemPos = {x = 33297, y = 31658, z = 13}, + reward = {{2520, 1}}, + storage = Storage.Quest.Behemoth.DemonShield + }, + -- Golden armor + [6054] = { + itemId = 1740, + itemPos = {x = 33298, y = 31658, z = 13}, + reward = {{2466, 1}}, + storage = Storage.Quest.Behemoth.GoldenArmor + }, + -- Family brooch quest + [6055] = { + itemId = 1744, + itemPos = {x = 32248, y = 31866, z = 8}, + reward = {{2318, 1}}, + storage = Storage.Quest.SimpleChest.FamilyBrooch + }, + -- The queen of the banshees quest + -- Stone skin amulet + [6056] = { + itemId = 1740, + itemPos = {x = 32212, y = 31896, z = 15}, + reward = {{2197, 1}}, + storage = Storage.Quest.TheQueenOfTheBanshees.Reward.StoneSkinAmulet + }, + -- Stone skin amulet + [6057] = { + itemId = 1740, + itemPos = {x = 32226, y = 31896, z = 15}, + reward = {{2165, 1}}, + storage = Storage.Quest.TheQueenOfTheBanshees.Reward.StealthRing + }, + -- Tower shield + [6058] = { + itemId = 1740, + itemPos = {x = 32212, y = 31910, z = 15}, + reward = {{2528, 1}}, + storage = Storage.Quest.TheQueenOfTheBanshees.Reward.TowerShield + }, + -- Giant sword + [6059] = { + itemId = 1740, + itemPos = {x = 32226, y = 31910, z = 15}, + reward = {{2393, 1}}, + storage = Storage.Quest.TheQueenOfTheBanshees.Reward.GiantSword + }, + -- Boots of haste + [6060] = { + itemId = 1740, + itemPos = {x = 32218, y = 31912, z = 15}, + reward = {{2195, 1}}, + storage = Storage.Quest.TheQueenOfTheBanshees.Reward.BootsOfHaste + }, + -- 100 platinum coins + [6061] = { + itemId = 1740, + itemPos = {x = 32220, y = 31912, z = 15}, + reward = {{2152, 100}}, + storage = Storage.Quest.TheQueenOfTheBanshees.Reward.PlatinumCoin + }, + -- Ornamented shield quest + [6062] = { + itemId = 2843, + itemPos = {x = 32778, y = 32282, z = 11}, + container = 1987, + keyAction = Storage.Quest.Key.ID3702, + reward = {{2090,1}, {2600, 1}, {2457, 1}, {2524, 1}, {1955, 1}, {2383, 1}, {2201, 1}, {2164, 1}}, + weight = 194, + storage = Storage.Quest.OrnamentedShield.Bag + }, + [6063] = { + itemId = 1747, + itemPos = {x = 32769, y = 32302, z = 10}, + container = 1993, + reward = {{2071, 1}, {2175, 1}, {2199, 1}, {2152, 5} , {2169, 1}}, + weight = 44, + storage = Storage.Quest.OrnamentedShield.RedBag + }, + --[6064] EMPTY + [6065] = { + itemId = 1740, + itemPos = {x = 32644, y = 32131, z = 8}, + container = 1987, + reward = {{2150, 2}, {2166, 1}, {2074, 1}}, + weight = 44, + storage = Storage.Quest.Panpipe.Reward + }, + [6066] = { + itemId = 1738, + itemPos = {x = 33199, y = 31923, z = 11}, + container = 1987, + reward = {{2148, 98}, {2148, 77}, {2143, 3}}, + weight = 27, + storage = Storage.Quest.BerserkerTreasure.Reward + }, + -- Fire axe quest + -- Bag + [6067] = { + itemId = 1740, + itemPos = {x = 33078, y = 31656, z = 11}, + container = 1987, + reward = {{2214, 1}, {2201, 200}, {2145, 7}}, + weight = 27, + storage = Storage.Quest.FireAxe.Bag + }, + -- Poison daggers quest + -- Backpack reward + [6068] = { + itemId = 1741, + itemPos = {x = 33155, y = 31880, z = 11}, + container = 1988, + reward = {{2545, 30}, {2411, 1}, {2411, 1}}, + weight = 60, + storage = Storage.Quest.PoisonDaggers.BackpackReward + }, + -- Shaman treasure quest + -- Bag with 3 blank runes + [6069] = { + itemId = 2843, + itemPos = {x = 33127, y = 31885, z = 9}, + container = 1987, + reward = {{2260, 3}}, + weight = 15, + storage = Storage.Quest.ShamanTreasure.Bag + }, + -- Strong potions quest + -- Green bag with 5 strong mana potions + [6070] = { + itemId = 1738, + itemPos = {x = 33163, y = 31603, z = 15}, + container = 1991, + reward = {{7589, 5}}, + weight = 23, + storage = Storage.Quest.StrongPotions.Reward + }, + -- Vampire shield quest + -- Bag + [6071] = { + itemId = 1738, + itemPos = {x = 33188, y = 31682, z = 14}, + container = 1987, + reward = {{2174, 1}, {2144, 1}, {2194, 1}}, + weight = 16, + storage = Storage.Quest.VampireShield.Bag + }, + -- [6072] empty + + -- Dragon tower quest + -- Backpack 1 + [6073] = { + itemId = 1738, + itemPos = {x = 33072, y = 32169, z = 2}, + container = 1988, + reward = {{7620, 1}, {7618, 1}, {2546, 30}, {2545, 60}}, + weight = 80, + storage = Storage.Quest.DragonTower.Backpack1 + }, + -- Backpack 2 + [6074] = { + itemId = 1738, + itemPos = {x = 33078, y = 32169, z = 2}, + container = 1988, + reward = {{2456, 1}, {2146, 2}}, + weight = 50, + storage = Storage.Quest.DragonTower.Backpack2 + }, + -- Behemoth quest + -- Bag + [6075] = { + itemId = 1740, + itemPos = {x = 33294, y = 31658, z = 13}, + container = 1987, + reward = {{2145, 3}, {2146, 4}, {2124, 1}, {2168, 1}, {2171, 1}}, + weight = 50, + storage = Storage.Quest.Behemoth.Bag + }, + -- Parchment room quest + -- Bag + [6076] = { + itemId = 1742, + itemPos = {x = 33063, y = 31624, z = 15}, + container = 1987, + keyAction = Storage.Quest.Key.ID6010, + reward = {{2091, 1}, {2229, 1}, {2151, 2}, {2165, 1}, {2230, 1}}, + weight = 42, + storage = Storage.Quest.ParchmentRoom.Bag + }, + -- Giant smithhammer quest + -- Talon + [6077] = { + itemId = 1740, + itemPos = {x = 32774, y = 32253, z = 8}, + reward = {{2151, 1}}, + storage = Storage.Quest.GiantSmithhammer.Talon + }, + -- Giant smithhammer + [6078] = { + itemId = 1740, + itemPos = {x = 32776, y = 32253, z = 8}, + reward = {{2321, 1}}, + storage = Storage.Quest.GiantSmithhammer.Hammer + }, + -- 100 gold coin + [6079] = { + itemId = 1740, + itemPos = {x = 32778, y = 32253, z = 8}, + reward = {{2148, 100}}, + storage = Storage.Quest.GiantSmithhammer.GoldCoin + }, + -- Mad Mage room quest + -- Star amulet + [6080] = { + itemId = 1740, + itemPos = {x = 32578, y = 32195, z = 14}, + reward = {{2131, 1}}, + storage = Storage.Quest.MadMageRoom.StarAmulet + }, + -- Hat of the mad + [6081] = { + itemId = 1740, + itemPos = {x = 32575, y = 32195, z = 14}, + reward = {{2323, 1}}, + storage = Storage.Quest.MadMageRoom.Hat + }, + -- Stone skin amulet + [6082] = { + itemId = 1740, + itemPos = {x = 32572, y = 32195, z = 14}, + reward = {{2197, 5}}, + storage = Storage.Quest.MadMageRoom.StoneSkinAmulet + }, + -- Skull of ratha quest + -- Bag (white pearl, skull) + [6083] = { + itemId = 1738, + itemPos = {x = 32845, y = 31917, z = 6}, + container = 1987, + weight = 42, + reward = {{2143, 1}, {2320, 1}}, + storage = Storage.Quest.SkullOfRatha.Bag1 + }, + -- Bag (wolf tooth chain/dwarven ring) + [6084] = { + itemId = 1738, + itemPos = {x = 32847, y = 31917, z = 6}, + container = 1987, + weight = 42, + reward = {{2129, 1}, {2213, 1}}, + storage = Storage.Quest.SkullOfRatha.Bag2 + }, + -- The annihilator quest + -- Demon armor + [6085] = { + itemId = 1740, + itemPos = {x = 33227, y = 31656, z = 13}, + reward = {{2494, 1}}, + storage = Storage.Quest.TheAnnihilator.Reward + }, + -- Magic sword + [6086] = { + itemId = 1740, + itemPos = {x = 33229, y = 31656, z = 13}, + reward = {{2400, 1}}, + storage = Storage.Quest.TheAnnihilator.Reward + }, + -- Stonecutter axe + [6087] = { + itemId = 1740, + itemPos = {x = 33231, y = 31656, z = 13}, + reward = {{2431, 1}}, + storage = Storage.Quest.TheAnnihilator.Reward + }, + -- Present (annihilation bear) + [6088] = { + itemId = 1740, + itemPos = {x = 33233, y = 31656, z = 13}, + container = 1990, + weight = 50, + reward = {{2326, 1}}, + storage = Storage.Quest.TheAnnihilator.Reward + }, + -- The paradox tower quest + -- Phoenix egg + [6089] = { + itemId = 1740, + itemPos = {x = 32477, y = 31900, z = 1}, + reward = {{11400, 1}}, + storage = Storage.Quest.TheParadoxTower.Reward.Egg + }, + -- 10.000 gold coins + [6090] = { + itemId = 1740, + itemPos = {x = 32478, y = 31900, z = 1}, + reward = {{2152, 100}}, + storage = Storage.Quest.TheParadoxTower.Reward.Gold + }, + -- Talon + [6091] = { + itemId = 1740, + itemPos = {x = 32479, y = 31900, z = 1}, + reward = {{2151, 32}}, + storage = Storage.Quest.TheParadoxTower.Reward.Talon + }, + -- Wand of energy cosmic + [6092] = { + itemId = 1740, + itemPos = {x = 32480, y = 31900, z = 1}, + reward = {{2189, 1}}, + storage = Storage.Quest.TheParadoxTower.Reward.Wand + }, + + -- Reward of others scrips files (varied rewards) + -- The First dragon Quest + -- Treasure chests (data\scripts\actions\quests\first_dragon\treasure_chests.lua) + [14001] = { + itemId = 27545, + itemPos = {x = 32809, y = 32546, z = 6} + }, + [14002] = { + itemId = 27545, + itemPos = {x = 32765, y = 31019, z = 9} + }, + [14003] = { + itemId = 27545, + itemPos = {x = 32046, y = 32894, z = 10} + }, + [14004] = { + itemId = 27543, + itemPos = {x = 32808, y = 31580, z = 3} + }, + [14005] = { + itemId = 27543, + itemPos = {x = 33260, y = 32228, z = 10} + }, + [14006] = { + itemId = 27543, + itemPos = {x = 33016, y = 32614, z = 6} + }, + [14007] = { + itemId = 27543, + itemPos = {x = 33054, y = 32393, z = 10} + }, + [14008] = { + itemId = 27543, + itemPos = {x = 32208, y = 31849, z = 10} + }, + [14009] = { + itemId = 27543, + itemPos = {x = 32024, y = 32602, z = 10} + }, + [14010] = { + itemId = 27543, + itemPos = {x = 33224, y = 31647, z = 7} + }, + [14011] = { + itemId = 27543, + itemPos = {x = 32701, y = 31458, z = 5} + }, + [14012] = { + itemId = 27543, + itemPos = {x = 32647, y = 32091, z = 8} + }, + [14013] = { + itemId = 27545, + itemPos = {x = 32577, y = 31896, z = 7} + }, + [14014] = { + itemId = 27543, + itemPos = {x = 33676, y = 31753, z = 6} + }, + [14015] = { + itemId = 27545, + itemPos = {x = 32242, y = 31390, z = 5} + }, + [14016] = { + itemId = 27543, + itemPos = {x = 33613, y = 31811, z = 9} + }, + [14017] = { + itemId = 27543, + itemPos = {x = 32873, y = 32900, z = 9} + }, + [14018] = { + itemId = 27543, + itemPos = {x = 32171, y = 32974, z = 7} + }, + [14019] = { + itemId = 27545, + itemPos = {x = 32960, y = 31461, z = 3} + }, + [14020] = { + itemId = 27543, + itemPos = {x = 33340, y = 31411, z = 7} + }, + -- Final reward (data\scripts\actions\quests\first_dragon\rewards.lua) + [14021] = { + itemId = 1746, + itemPos = {x = 33616, y = 31015, z = 13} + }, + [14022] = { + itemId = 27531, + itemPos = {x = 33617, y = 31015, z = 13} + }, + [14023] = { + itemId = 1746, + itemPos = {x = 33618, y = 31015, z = 13} + }, + -- The shattered isles + [14024] = { + itemId = 5677, + itemPos = {x = 31938, y = 32837, z = 7} + }, + -- Dawnport vocation rewards + -- Path: data\scripts\actions\quests\dawnport\vocation_reward.lua + -- Sorcerer + [14025] = { + itemId = 1740, + itemPos = {x = 32054, y = 31882, z = 6} + }, + -- Druid + [14026] = { + itemId = 1740, + itemPos = {x = 32073, y = 31882, z = 6} + }, + -- Paladin + [14027] = { + itemId = 1740, + itemPos = {x = 32059, y = 31882, z = 6} + }, + -- Knight + [14028] = { + itemId = 1740, + itemPos = {x = 32068, y = 31882, z = 6} + }, + -- Explorer Society Missions + -- Path: data\scripts\actions\quests\explorer_society\findings.lua + -- Uzgod Family Brooch (Dwacatra) + [14029] = { + itemId = 1741, + itemPos = {x = 32598, y = 31934, z = 15} + }, + -- The Bonelord Secret Chest (Dark Pyramid) + [14030] = { + itemId = 1738, + itemPos = {x = 33308, y = 32279, z = 12} + }, + -- The Orc Powder (Orc Fortress) + [14031] = { + itemId = 1741, + itemPos = {x = 32967, y = 31719, z = 2} + }, + -- The Elven Poetry (Hell Gate) + [14032] = { + itemId = 1740, + itemPos = {x = 32704, y = 31605, z = 14} + }, + -- The Memory Stone (Edron) + [14033] = { + itemId = 1738, + itemPos = {x = 33152, y = 31640, z = 11} + }, + -- The Spectral Dress (Isle of the Kings) + [14034] = { + itemId = 1738, + itemPos = {x = 32259, y = 31949, z = 14} + }, + -- The Undersea Kingdom (Calassa) + [14035] = { + itemId = 1741, + itemPos = {x = 31937, y = 32771, z = 13} + }, + -- Others uniques + -- Threatened Dreams Quest + [34123] = { + itemId = 13903, + itemPos = {x = 32787, y = 31975, z = 11} + } +} diff --git a/data/startup/tables/corpse.lua b/data/startup/tables/corpse.lua new file mode 100644 index 00000000000..928c0ae8d0f --- /dev/null +++ b/data/startup/tables/corpse.lua @@ -0,0 +1,33 @@ +--[[ + +Look README.md for look the reserved action/unique + +]] +CorpseAction = { + [20001] = { + itemId = false, + itemPos = {{x = xxxxx, y = xxxxx, z = xx}} + }, + + -- Others actions + -- Threatened dreams quest + [28600] = { + itemId = 28602, + itemPos = {{x = 32951, y = 31810, z = 7}} + }, +} + +CorpseUnique = { + -- Dark trails (Quandon corpse) + -- Path: data\scripts\actions\quests\dark_trails\corpse.lua + [20001] = { + itemId = 23494, + itemPos = {x = 33574, y = 31952, z = 6} + }, + -- Lions rock corpse + -- Path: data\scripts\actions\quests\lions_rock\lions_rock.lua + [20002] = { + itemId = 6082, + itemPos = {x = 33146, y = 32341, z = 8} + } +} diff --git a/data/startup/tables/door_key.lua b/data/startup/tables/door_key.lua new file mode 100644 index 00000000000..8a4b0d88c20 --- /dev/null +++ b/data/startup/tables/door_key.lua @@ -0,0 +1,129 @@ +--[[ + +Look README.md for look the reserved action of the keys + +]] + +KeyDoorAction = { + -- Door of the key 3001 (draconia quest) + [Storage.Quest.Key.ID3001] = { + itemId = false, + itemPos = {{x = 32814, y = 31597, z = 7}} + }, + -- Door of the key 3002 (draconia quest) + [Storage.Quest.Key.ID3002] = { + itemId = false, + itemPos = {{x = 32796, y = 31597, z = 7}} + }, + -- Door of the key 3003 (draconia quest) + [Storage.Quest.Key.ID3003] = { + itemId = false, + itemPos = {{x = 32811, y = 31597, z = 7}} + }, + -- Door of the key 3004 (draconia quest) + [Storage.Quest.Key.ID3004] = { + itemId = false, + itemPos = {{x = 32809, y = 31593, z = 6}} + }, + -- Door of the key 3005 (draconia quest) + [Storage.Quest.Key.ID3005] = { + itemId = false, + itemPos = {{x = 32794, y = 31582, z = 6}} + }, + -- Door of the key 3006 (draconia quest) + [Storage.Quest.Key.ID3006] = { + itemId = false, + itemPos = {{x = 32814, y = 31595, z = 6}} + }, + -- Door of the key 3007 (draconia quest) + [Storage.Quest.Key.ID3007] = { + itemId = false, + itemPos = {{x = 32797, y = 31592, z = 4}} + }, + -- Door of the key 3008 (draconia quest) + [Storage.Quest.Key.ID3008] = { + itemId = false, + itemPos = {{x = 32804, y = 31585, z = 1}} + }, + -- Door of the key 3012 (draconia quest) + [Storage.Quest.Key.ID3012] = { + itemId = false, + itemPos = { + {x = 32675, y = 31649, z = 10}, + {x = 32676, y = 31671, z = 10} + } + }, + -- Door of the key 3620 (mad mage room quest) + [Storage.Quest.Key.ID3620] = { + itemId = false, + itemPos = { + {x = 32393, y = 32136, z = 14}, + {x = 32395, y = 32117, z = 15}, + {x = 32397, y = 32114, z = 15}, + {x = 32400, y = 32117, z = 15} + } + }, + -- Door of the key 3666 (mad mage room quest) + [Storage.Quest.Key.ID3666] = { + itemId = 1212, + itemPos = {{x = 32578, y = 32197, z = 15}} + }, + -- Door of the key 3800 (emperor's cookies quest) + [Storage.Quest.Key.ID3800] = { + itemId = false, + itemPos = {{x = 32645, y = 31906, z = 3}} + }, + -- Door of the key 3801 (emperor's cookies quest) + [Storage.Quest.Key.ID3801] = { + itemId = false, + itemPos = {{x = 32600, y = 31926, z = 6}} + }, + -- Door of the key 3802 (emperor's cookies quest) + [Storage.Quest.Key.ID3802] = { + itemId = false, + itemPos = { + {x = 32450, y = 31967, z = 10}, + {x = 32452, y = 31972, z = 10}, + {x = 32456, y = 31972, z = 10}, + {x = 32457, y = 31966, z = 10}, + {x = 32602, y = 31975, z = 14}, + {x = 32603, y = 31975, z = 14}, + {x = 32624, y = 31929, z = 3} + } + }, + -- Door of the key 3899 (the paradox tower quest) + [Storage.Quest.Key.ID3899] = { + itemId = false, + itemPos = {{x = 32479, y = 31903, z = 4}} + }, + -- Door of the key 3940 (gained with simmon the beggar) + [Storage.Quest.Key.ID3940] = { + itemId = false, + itemPos = {{x = 32190, y = 32432, z = 8}} + }, + -- Door of the key 3980 + [Storage.Quest.Key.ID3980] = { + itemId = false, + itemPos = {{x = 32277, y = 32420, z = 10}} + }, + -- Door of the key 4055 (panpipe quest) + [Storage.Quest.Key.ID4055] = { + itemId = false, + itemPos = {{x = 32643, y = 32128, z = 8}} + }, + -- Door of the key 4502 (alawar's vault quest) + [Storage.Quest.Key.ID4502] = { + itemId = false, + itemPos = {{x = 32107, y = 31568, z = 9}} + }, + -- Door of the key 5010 (black knight quest) + [Storage.Quest.Key.ID5010] = { + itemId = 6249, + itemPos = {{x = 32824, y = 31969, z = 8}} + }, + -- Door of the key 6010 (demon helmet quest) + [Storage.Quest.Key.ID6010] = { + itemId = 5098, + itemPos = {{x = 33211, y = 31634, z = 13}} + } +} diff --git a/data/startup/tables/door_level.lua b/data/startup/tables/door_level.lua new file mode 100644 index 00000000000..7a7779a4af9 --- /dev/null +++ b/data/startup/tables/door_level.lua @@ -0,0 +1,72 @@ +--[[ + +Look README.md for look the reserved action/unique +Put the position of each range level doors +Just add new positions and it go work in the game + +]] +LevelDoorAction = { + -- Doors for level 25 + [1025] = { + itemId = false, + itemPos = { + {x = 32804, y = 31583, z = 2} + } + }, + -- Doors for level 30 + [1030] = { + itemId = false, + itemPos = { + {x = 33302, y = 31691, z = 11}, + {x = 33302, y = 31692, z = 11}, + {x = 32567, y = 31969, z = 3} + } + }, + -- Doors for level 40 + [1040] = { + itemId = false, + itemPos = { + {x = 32981, y = 31760, z = 9} + } + }, + -- Doors for level 50 + [1050] = { + itemId = false, + itemPos = { + {x = 32212, y = 32435, z = 10}, + {x = 32874, y = 31974, z = 12}, + {x = 32875, y = 31974, z = 12} + } + }, + -- Doors for level 60 + [1060] = { + itemId = false, + itemPos = { + {x = 33085, y = 31650, z = 10}, + {x = 32223, y = 31869, z = 14} + } + }, + -- Doors for level 70 + [1070] = { + itemId = false, + itemPos = { + {x = 33190, y = 31684, z = 14}, + {x = 33195, y = 31684, z = 14} + } + }, + -- Doors for level 80 + [1080] = { + itemId = false, + itemPos = { + {x = 33297, y = 31670, z = 14} + } + }, + -- Doors for level 100 + [1100] = { + itemId = false, + itemPos = { + {x = 33211, y = 31638, z = 13}, + {x = 33214, y = 31671, z = 13} + } + } +} diff --git a/data/startup/tables/door_quest.lua b/data/startup/tables/door_quest.lua new file mode 100644 index 00000000000..57140b71183 --- /dev/null +++ b/data/startup/tables/door_quest.lua @@ -0,0 +1,718 @@ +--[[ + +Look README.md for look the reserved action/unique + +]] +QuestDoorAction = { + -- The queens of the banshee door + [Storage.Quest.TheQueenOfTheBanshees.BansheeDoor] = { + itemId = 5114, + itemPos = { + {x = 32246, y = 31861, z = 14}, + {x = 32246, y = 31862, z = 14} + } + }, + [Storage.Quest.TheQueenOfTheBanshees.FirstSealDoor] = { + itemId = 5105, + itemPos = {{x = 32223, y = 31872, z = 14}} + }, + [Storage.Quest.TheQueenOfTheBanshees.SecondSealDoor] = { + itemId = 5105, + itemPos = {{x = 32223, y = 31875, z = 14}} + }, + [Storage.Quest.TheQueenOfTheBanshees.ThirdSealDoor] = { + itemId = 5105, + itemPos = {{x = 32223, y = 31878, z = 14}} + }, + [Storage.Quest.TheQueenOfTheBanshees.FourthSealDoor] = { + itemId = 5105, + itemPos = {{x = 32223, y = 31881, z = 14}} + }, + [Storage.Quest.TheQueenOfTheBanshees.FifthSealDoor] = { + itemId = 5105, + itemPos = {{x = 32223, y = 31884, z = 14}} + }, + [Storage.Quest.TheQueenOfTheBanshees.SixthSealDoor] = { + itemId = 5105, + itemPos = {{x = 32223, y = 31887, z = 14}} + }, + [Storage.Quest.TheQueenOfTheBanshees.LastSealDoor] = { + itemId = 5105, + itemPos = {{x = 32223, y = 31890, z = 14}} + }, + -- Sams old backpack door + [Storage.SamsOldBackpackDoor] = { + itemId = false, + itemPos = {{x = 32455, y = 31967, z = 14}} + }, + -- Edron + [Storage.Kilmaresh.Sixth.Favor] = { + itemId = false, + itemPos = { + {x = 33855, y = 31450, z = 9}, + {x = 33855, y = 31496, z = 9}, + {x = 33884, y = 31510, z = 9}, + {x = 33884, y = 31536, z = 9}, + {x = 33911, y = 31496, z = 9}, + {x = 33912, y = 31466, z = 9} + } + }, + -- Rathleton quest door + [Storage.HeroRathleton.AccessDoor] = { + itemId = false, + itemPos = { + {x = 33567, y = 31951, z = 14}, + {x = 33569, y = 31951, z = 14} + } + }, + -- Secret library quest door + [Storage.TheSecretLibrary.Mota] = { + itemId = false, + itemPos = { + {x = 33208, y = 32071, z = 8}, + {x = 33246, y = 32122, z = 8} + } + }, + [Storage.TheSecretLibrary.MotaDoor] = { + itemId = false, + itemPos = {{x = 33208, y = 32074, z = 8}} + }, + [Storage.TheSecretLibrary.BasinDoor] = { + itemId = false, + itemPos = {{x = 33341, y = 32117, z = 10}} + }, + [Storage.TheSecretLibrary.SkullDoor] = { + itemId = false, + itemPos = {{x = 33344, y = 32120, z = 10}} + }, + -- Koshei the deathless quest door + [Storage.KosheiTheDeathless.RewardDoor] = { + itemId = false, + itemPos = {{x = 33269, y = 32446, z = 12}} + }, + -- Beggar outfit quest door + [Storage.OutfitQuest.BeggarFirstAddonDoor] = { + itemId = false, + itemPos = {{x = 33165, y = 31600, z = 15}} + }, + -- The explorer society quest doors + -- Mission in Dwacatra + [Storage.ExplorerSociety.DwacatraDoor] = { + itemId = false, + itemPos = {{x = 32598, y = 31933, z = 15}} + }, + -- Mission in Chor + [Storage.ExplorerSociety.ChorurnDoor] = { + itemId = false, + itemPos = {{x = 32957, y = 32835, z = 8}} + }, + -- Mission in Dark Pyramid + [Storage.ExplorerSociety.BonelordsDoor] = { + itemId = false, + itemPos = {{x = 33308, y = 32280, z = 12}} + }, + -- Mission in Orc Fortress + [Storage.ExplorerSociety.OrcDoor] = { + itemId = false, + itemPos = {{x = 32967, y = 31720, z = 2}} + }, + -- Mission in Hell Gate + [Storage.ExplorerSociety.ElvenDoor] = { + itemId = false, + itemPos = {{x = 32703, y = 31605, z = 14}} + }, + -- Mission in Endron + [Storage.ExplorerSociety.MemoryStoneDoor] = { + itemId = false, + itemPos = {{x = 33151, y = 31640, z = 11}} + }, + -- Mission in Isle of Kings + [Storage.ExplorerSociety.BansheeDoor] = { + itemId = false, + itemPos = {{x = 32259, y = 31948, z = 14}} + }, + -- Astral Bridge from Port Hope to Northport + [Storage.ExplorerSociety.SpectralStoneDoor] = { + itemId = false, + itemPos = { + {x = 32665, y = 32734, z = 6}, + {x = 32500, y = 31622, z = 6} + } + }, + -- Astral Bridge from Svargrond to Liberty Bay + [Storage.ExplorerSociety.IceMusicDoor] = { + itemId = false, + itemPos = { + {x = 32318, y = 31137, z = 6}, + {x = 32360, y = 32808, z = 6} + } + }, + -- Mission in Calassa + [Storage.ExplorerSociety.CalassaDoor] = { + itemId = false, + itemPos = {{x = 31939, y = 32771, z = 13}} + }, + -- The war djin quest + -- Marid faction + [Storage.DjinnWar.Faction.MaridDoor] = { + itemId = false, + itemPos = {{x = 33106, y = 32532, z = 6}} + }, + [Storage.DjinnWar.Faction.EfreetDoor] = { + itemId = false, + itemPos = {{x = 33047, y = 32626, z = 6}} + }, + [Storage.DjinnWar.MaridFaction.DoorToLamp] = { + itemId = false, + itemPos = {{x = 33038, y = 32632, z = 1}} + }, + [Storage.DjinnWar.MaridFaction.DoorToEfreetTerritory] = { + itemId = false, + itemPos = {{x = 33034, y = 32620, z = 6}} + }, + -- Efreet faction + [Storage.DjinnWar.EfreetFaction.DoorToLamp] = { + itemId = false, + itemPos = {{x = 33097, y = 32531, z = 1}} + }, + [Storage.DjinnWar.EfreetFaction.DoorToMaridTerritory] = { + itemId = false, + itemPos = {{x = 33100, y = 32518, z = 7}} + }, + -- Bigfoot burden quest + [Storage.BigfootBurden.DoorGoldenFruits] = { + itemId = false, + itemPos = {{x = 32822, y = 31745, z = 10}} + }, + -- Dawnport door key 0010 (npcs dormitory) + [103] = { + itemId = false, + itemPos = {{x = 32067, y = 31896, z = 3}} + }, + -- Cults of tibia door + [Storage.CultsOfTibia.Minotaurs.EntranceAccessDoor] = { + itemId = false, + itemPos = {{x = 31950, y = 32501, z = 8}} + }, + [Storage.CultsOfTibia.Minotaurs.AccessDoor] = { + itemId = false, + itemPos = {{x = 31957, y = 32468, z = 9}} + }, + [Storage.CultsOfTibia.MotA.AccessDoorInvestigation] = { + itemId = false, + itemPos = {{x = 33273, y = 32172, z = 8}} + }, + [Storage.CultsOfTibia.MotA.AccessDoorGareth] = { + itemId = false, + itemPos = {{x = 33220, y = 32147, z = 9}} + }, + [Storage.CultsOfTibia.MotA.AccessDoorDenominator] = { + itemId = false, + itemPos = {{x = 33220, y = 32149, z = 9}} + }, + [Storage.CultsOfTibia.Barkless.TrialAccessDoor] = { + itemId = false, + itemPos = {{x = 32688, y = 31543, z = 9}} + }, + [Storage.CultsOfTibia.Barkless.TarAccessDoor] = { + itemId = false, + itemPos = { + {x = 32747, y = 31462, z = 8}, + {x = 32678, y = 31506, z = 8} + } + }, + [Storage.CultsOfTibia.Barkless.AccessDoor] = { + itemId = false, + itemPos = { + {x = 32742, y = 31408, z = 8}, + {x = 32686, y = 31430, z = 8} + } + }, + [Storage.CultsOfTibia.Barkless.BossAccessDoor] = { + itemId = false, + itemPos = {{x = 32672, y = 31543, z = 9}} + }, + [Storage.CultsOfTibia.Life.AccessDoor] = { + itemId = false, + itemPos = {{x = 33295, y = 32271, z = 12}} + }, + [Storage.CultsOfTibia.Misguided.AccessDoor] = { + itemId = false, + itemPos = {{x = 32508, y = 32370, z = 9}} + }, + [Storage.CultsOfTibia.FinalBoss.AccessDoor] = { + itemId = false, + itemPos = {{x = 33452, y = 32241, z = 7}} + }, + -- Ferumbras ascension door + [Storage.FerumbrasAscension.FirstDoor] = { + itemId = false, + itemPos = {{x = 33479, y = 32782, z = 11}} + }, + [Storage.FerumbrasAscension.MonsterDoor] = { + itemId = false, + itemPos = {{x = 33482, y = 32786, z = 11}} + }, + [Storage.FerumbrasAscension.TarbazDoor] = { + itemId = false, + itemPos = {{x = 33470, y = 32786, z = 11}} + }, + -- Wrath of the emperor door + [Storage.WrathoftheEmperor.Mission02] = { + itemId = false, + itemPos = {{x = 33242, y = 31051, z = 10}} + }, + [Storage.WrathoftheEmperor.Mission08] = { + itemId = false, + itemPos = {{x = 33080, y = 31164, z = 8}} + }, + [Storage.WrathoftheEmperor.Mission12] = { + itemId = false, + itemPos = {{x = 33076, y = 31176, z = 8}} + }, + -- Unnatural selection door + [Storage.UnnaturalSelection.Mission01] = { + itemId = false, + itemPos = {{x = 33046, y = 31302, z = 7}} + }, + -- Dark trails/oramond door + [Storage.Oramond.DoorBeggarKing] = { + itemId = false, + itemPos = {{x = 33573, y = 31982, z = 7}} + }, + [Storage.Oramond.DoorAbandonedSewer] = { + itemId = false, + itemPos = {{x = 33549, y = 31974, z = 10}} + }, + [Storage.DarkTrails.DoorQuandon] = { + itemId = false, + itemPos = {{x = 33573, y = 31953, z = 7}} + }, + [Storage.DarkTrails.DoorHideout] = { + itemId = false, + itemPos = {{x = 33666, y = 31924, z = 7}} + }, + -- Outfit quest door + [Storage.OutfitQuest.HunterHatAddon] = { + itemId = false, + itemPos = {{x = 32369, y = 32796, z = 10}} + }, + -- Ancient tombs door + [Storage.TheAncientTombs.VashresamunsDoor] = { + itemId = false, + itemPos = {{x = 33184, y = 32665, z = 15}} + }, + -- The ape city door + [Storage.TheApeCity.DworcDoor] = { + itemId = false, + itemPos = {{x = 32934, y = 32886, z = 7}} + }, + [Storage.TheApeCity.FibulaDoor] = { + itemId = false, + itemPos = {{x = 32182, y = 32468, z = 10}} + }, + [Storage.TheApeCity.CasksDoor] = { + itemId = false, + itemPos = { + {x = 32861, y = 32495, z = 9}, + {x = 32861, y = 32497, z = 9}, + {x = 32861, y = 32499, z = 9}, + {x = 32861, y = 32501, z = 9}, + {x = 32861, y = 32503, z = 9}, + {x = 32861, y = 32505, z = 9}, + {x = 32861, y = 32507, z = 9} + } + }, + [Storage.TheApeCity.Casks] = { + itemId = false, + itemPos = {{x = 32781, y = 32910, z = 8}} + }, + [Storage.TheNewFrontier.Mission01] = { + itemId = false, + itemPos = { + {x = 33060, y = 31529, z = 10}, + {x = 33061, y = 31529, z = 10}, + {x = 33062, y = 31529, z = 10}, + {x = 33060, y = 31529, z = 12}, + {x = 33061, y = 31529, z = 12}, + {x = 33062, y = 31529, z = 12}, + {x = 33060, y = 31529, z = 14}, + {x = 33061, y = 31529, z = 14}, + {x = 33062, y = 31529, z = 14} + } + }, + [Storage.TheNewFrontier.Mission04] = { + itemId = false, + itemPos = { + {x = 33055, y = 31529, z = 10}, + {x = 33056, y = 31529, z = 10}, + {x = 33057, y = 31529, z = 10}, + {x = 33055, y = 31529, z = 12}, + {x = 33056, y = 31529, z = 12}, + {x = 33057, y = 31529, z = 12}, + {x = 33055, y = 31529, z = 14}, + {x = 33056, y = 31529, z = 14}, + {x = 33057, y = 31529, z = 14} + } + }, + [Storage.TheNewFrontier.Mission07] = { + itemId = false, + itemPos = { + {x = 33170, y = 31260, z = 10}, + {x = 33171, y = 31260, z = 10} + } + }, + [Storage.TheNewFrontier.Mission09] = { + itemId = false, + itemPos = { + {x = 33061, y = 31025, z = 7}, + {x = 33080, y = 31019, z = 2}, + {x = 32990, y = 31547, z = 4} + } + }, + -- The inquisition door + [Storage.TheInquisition.Mission01] = { + itemId = false, + itemPos = {{x = 32316, y = 32264, z = 8}} + }, + [Storage.TheInquisition.RewardDoor] = { + itemId = false, + itemPos = {{x = 32320, y = 32258, z = 9}} + }, + -- In service of yalahar door + [Storage.InServiceofYalahar.Mission03] = { + itemId = false, + itemPos = { + {x = 32801, y = 31220, z = 7}, + {x = 32803, y = 31220, z = 7} + } + }, + [Storage.InServiceofYalahar.AlchemistFormula] = { + itemId = false, + itemPos = {{x = 32693, y = 31085, z = 7}} + }, + [Storage.InServiceofYalahar.TamerinStatus] = { + itemId = false, + itemPos = {{x = 32660, y = 31222, z = 8}} + }, + [Storage.InServiceofYalahar.MorikSummon] = { + itemId = false, + itemPos = {{x = 32690, y = 31241, z = 6}} + }, + [Storage.InServiceofYalahar.MatrixReward] = { + itemId = false, + itemPos = {{x = 32879, y = 31260, z = 8}} + }, + [Storage.InServiceofYalahar.NotesPalimuth] = { + itemId = false, + itemPos = {{x = 32797, y = 31226, z = 7}} + }, + [Storage.InServiceofYalahar.DoorToAzerus] = { + itemId = false, + itemPos = {{x = 32796, y = 31185, z = 7}} + }, + [Storage.InServiceofYalahar.DoorToBog] = { + itemId = false, + itemPos = { + {x = 32673, y = 31121, z = 7}, + {x = 32700, y = 31123, z = 7}, + {x = 32705, y = 31186, z = 8}, + {x = 32709, y = 31186, z = 8} + } + }, + [Storage.InServiceofYalahar.DoorToLastFight] = { + itemId = false, + itemPos = {{x = 32783, y = 31193, z = 8}} + }, + [Storage.InServiceofYalahar.DoorToMatrix] = { + itemId = false, + itemPos = { + {x = 32867, y = 31265, z = 10}, + {x = 32940, y = 31248, z = 9} + } + }, + [Storage.InServiceofYalahar.DoorToQuara] = { + itemId = false, + itemPos = { + {x = 32906, y = 31209, z = 14}, + {x = 32965, y = 31205, z = 14}, + {x = 32975, y = 31148, z = 14} + } + }, + [Storage.InServiceofYalahar.DoorToReward] = { + itemId = false, + itemPos = { + {x = 32780, y = 31205, z = 7}, + {x = 32780, y = 31208, z = 7} + } + }, + -- Children of the revolution door + [Storage.ChildrenoftheRevolution.Mission03] = { + itemId = false, + itemPos = {{x = 33330, y = 31411, z = 8}} + }, + -- Unnatural selection door + [Storage.UnnaturalSelection.Mission05] = { + itemId = false, + itemPos = {{x = 32982, y = 31439, z = 3}} + }, + -- Postman door + [Storage.Postman.Mission05] = { + itemId = false, + itemPos = {{x = 32567, y = 32023, z = 6}} + }, + [Storage.Postman.Mission08] = { + itemId = false, + itemPos = {{x = 32515, y = 32248, z = 8}} + }, + [Storage.Postman.Mission09] = { + itemId = false, + itemPos = {{x = 32569, y = 32023, z = 6}} + }, + [Storage.Postman.Door] = { + itemId = false, + itemPos = { + {x = 31921, y = 32652, z = 8}, + {x = 32008, y = 32863, z = 5}, + {x = 32059, y = 32733, z = 13}, + {x = 32101, y = 31264, z = 7}, + {x = 32148, y = 31122, z = 11}, + {x = 32386, y = 32951, z = 7}, + {x = 32423, y = 32096, z = 15}, + {x = 32448, y = 31965, z = 10}, + {x = 32453, y = 31975, z = 10}, + {x = 32455, y = 31975, z = 10}, + {x = 32459, y = 31965, z = 10}, + {x = 32524, y = 32026, z = 13}, + {x = 32535, y = 31970, z = 7}, + {x = 32615, y = 31435, z = 7}, + {x = 32962, y = 31487, z = 6}, + {x = 32971, y = 31778, z = 7}, + {x = 32995, y = 32447, z = 7}, + {x = 33076, y = 31212, z = 7}, + {x = 33083, y = 32185, z = 8}, + {x = 33201, y = 31064, z = 9}, + {x = 33271, y = 31657, z = 8}, + {x = 33284, y = 31791, z = 13}, + {x = 33307, y = 32291, z = 7} + } + }, + -- The thieves guild door + [Storage.ThievesGuild.Mission04] = { + itemId = false, + itemPos = {{x = 32359, y = 32787, z = 6}} + }, + [Storage.ThievesGuild.Mission05] = { + itemId = false, + itemPos = {{x = 32550, y = 32652, z = 10}} + }, + [Storage.ThievesGuild.Door] = { + itemId = false, + itemPos = {{x = 32314, y = 32210, z = 8}} + }, + [Storage.ThievesGuild.TheatreScript] = { + itemId = false, + itemPos = {{x = 32367, y = 31782, z = 8}} + }, + -- Secret service door + [Storage.SecretService.CGBMission01] = { + itemId = false, + itemPos = {{x = 33270, y = 31839, z = 3}} + }, + [Storage.SecretService.TBIMission02] = { + itemId = false, + itemPos = {{x = 32872, y = 31957, z = 11}} + }, + [Storage.SecretService.AVINMission02] = { + itemId = false, + itemPos = {{x = 32310, y = 32178, z = 5}} + }, + [Storage.SecretService.CGBMission02] = { + itemId = false, + itemPos = {{x = 32876, y = 31957, z = 11}} + }, + [Storage.SecretService.TBIMission03] = { + itemId = false, + itemPos = {{x = 32639, y = 32735, z = 7}} + }, + [Storage.SecretService.TBIMission04] = { + itemId = false, + itemPos = {{x = 32772, y = 31582, z = 11}} + }, + [Storage.SecretService.CGBMission04] = { + itemId = false, + itemPos = {{x = 32906, y = 32013, z = 6}} + }, + [Storage.SecretService.AVINMission05] = { + itemId = false, + itemPos = {{x = 32156, y = 31951, z = 13}} + }, + [Storage.SecretService.CGBMission05] = { + itemId = false, + itemPos = {{x = 32599, y = 32380, z = 10}} + }, + [Storage.SecretService.Mission07] = { + itemId = false, + itemPos = {{x = 32537, y = 31897, z = 13}} + }, + -- Hidden city of beregar door + [Storage.HiddenCityOfBeregar.DoorNorthMine] = { + itemId = false, + itemPos = {{x = 32606, y = 31489, z = 14}} + }, + [Storage.HiddenCityOfBeregar.DoorWestMine] = { + itemId = false, + itemPos = {{x = 32584, y = 31499, z = 14}} + }, + [Storage.HiddenCityOfBeregar.DoorSouthMine] = { + itemId = false, + itemPos = {{x = 32608, y = 31516, z = 14}} + }, + [Storage.TibiaTales.AnInterestInBotanyChestDoor] = { + itemId = false, + itemPos = {{x = 33007, y = 31536, z = 10}} + }, + -- THe shattered isles door + [Storage.TheShatteredIsles.TortoiseEggNargorDoor] = { + itemId = false, + itemPos = {{x = 31934, y = 32838, z = 7}} + }, + [Storage.TheShatteredIsles.YavernDoor] = { + itemId = false, + itemPos = {{x = 31978, y = 32856, z = 3}} + }, + -- Hot cuisine door + [Storage.HotCuisineQuest.CookbookDoor] = { + itemId = false, + itemPos = { + {x = 33065, y = 32529, z = 5}, + {x = 33065, y = 32531, z = 5}, + } + }, + -- The annihilator door + [Storage.Quest.TheAnnihilator.Reward] = { + itemId = 5114, + itemPos = {{x = 33216, y = 31671, z = 13}} + }, + -- Svargrond arena door + [Storage.SvargrondArena.PitDoor] = { + itemId = false, + itemPos = { + {x = 32233, y = 31098, z = 7}, + {x = 32233, y = 31099, z = 7}, + {x = 32233, y = 31100, z = 7} + } + }, + [Storage.SvargrondArena.GreenhornDoor] = { + itemId = false, + itemPos = {{x = 32227, y = 31066, z = 7}} + }, + [Storage.SvargrondArena.ScrapperDoor] = { + itemId = false, + itemPos = {{x = 32227, y = 31059, z = 7}} + }, + [Storage.SvargrondArena.WarlordDoor] = { + itemId = false, + itemPos = {{x = 32227, y = 31052, z = 7}} + }, + -- The pits of inferno door + [Storage.PitsOfInferno.ShortcutHubDoor] = { + itemId = false, + itemPos = {{x = 32786, y = 32328, z = 6}} + }, + [Storage.PitsOfInferno.ShortcutLeverDoor] = { + itemId = false, + itemPos = { + {x = 32825, y = 32331, z = 11}, + {x = 32825, y = 32332, z = 11} + } + }, + -- Fathers burden door + [Storage.FathersBurden.QuestLog] = { + itemId = false, + itemPos = { + {x = 31989, y = 31225, z = 7}, + {x = 32124, y = 31914, z = 14}, + {x = 32638, y = 31985, z = 14}, + {x = 32815, y = 32505, z = 8}, + {x = 33216, y = 31422, z = 10}, + {x = 33231, y = 31756, z = 5}, + {x = 33235, y = 32808, z = 12} + } + }, + -- What a foolish door + [Storage.WhatAFoolish.TriangleTowerDoor] = { + itemId = false, + itemPos = {{x = 32563, y = 32116, z = 4}} + }, + [Storage.WhatAFoolish.QueenEloiseCatDoor] = { + itemId = false, + itemPos = {{x = 32316, y = 31757, z = 9}} + }, + -- White raven monastery door + [Storage.WhiteRavenMonastery.Door] = { + itemId = false, + itemPos = { + {x = 32171, y = 31936, z = 7}, + {x = 32169, y = 31933, z = 7} + } + }, + -- The dream courts door (Andrew Lyze npc) + [Storage.Quest.TheDreamCourts.AndrewDoor] = { + itemId = 22821, + itemPos = {{x = 32761, y = 32630, z = 7}} + }, + -- Kilmaresh doors + [Storage.Kilmaresh.First.Title] = { + itemId = false, + itemPos = { + {x = 33959, y = 31501, z = 4}, + {x = 33375, y = 31346, z = 5}, + {x = 33371, y = 31349, z = 4}, + {x = 33376, y = 31335, z = 3} + } + }, + -- The Rookie Guard Quest - Mission 07: Attack! + -- The library vault door + [Storage.TheRookieGuard.LibraryDoor] = { + itemId = false, + itemPos = {{x = 32090, y = 32156, z = 9}} + }, + -- The Rookie Guard Quest - Mission 10: Tomb Raiding + -- The unholy crypt door + [Storage.TheRookieGuard.UnholyCryptDoor] = { + itemId = false, + itemPos = {{x = 32147, y = 32186, z = 9}} + }, + -- The Rookie Guard Quest - Mission 12: Into The Fortress + -- Lower academy floor door + [Storage.TheRookieGuard.AcademyDoor] = { + itemId = false, + itemPos = {{x = 32109, y = 32189, z = 8}} + } +} + +QuestDoorUnique = { + --Dawnport + -- Vocation doors + -- Sorcerer + [22001] = { + itemId = 12195, + itemPos = {x = 32055, y = 31885, z = 6} + }, + -- Druid + [22002] = { + itemId = 7040, + itemPos = {x = 32073, y = 31885, z = 6} + }, + -- Paladin + [22003] = { + itemId = 6898, + itemPos = {x = 32059, y = 31885, z = 6} + }, + -- Knight + [22004] = { + itemId = 9279, + itemPos = {x = 32069, y = 31885, z = 6} + } +} diff --git a/data/startup/tables/item.lua b/data/startup/tables/item.lua new file mode 100644 index 00000000000..4e8dff4426a --- /dev/null +++ b/data/startup/tables/item.lua @@ -0,0 +1,544 @@ +-- Look README.md for see the reserved action/unique numbers + +ItemAction = { + --Parchment room quest + -- data\scripts\quests\parchment_room\movement-parchment.lua + [104] = { + itemId = 1953, + itemPos = {{x = 33063, y = 31624, z = 15}} + }, + [40001] = { -- The cursed crystal skeletons + itemId = 33156, + itemPos = { + {x = 31974, y = 32907, z = 8}, + {x = 32031, y = 32914, z = 8} + } + }, + [40002] = { -- The cursed crystal red crystal + itemId = 23941, + itemPos = {{x = 32022, y = 32918, z = 10}} + }, + -- Grave danger quest + -- data\scripts\actions\quests\grave_danger\cobra_bastion\scarlett.lua + [40003] = { + itemId = false, + itemPos = { + {x = 33390, y = 32642, z = 6}, + {x = 33394, y = 32642, z = 6}, + {x = 33398, y = 32642, z = 6}, + {x = 33402, y = 32642, z = 6}, + {x = 33390, y = 32646, z = 6}, + {x = 33394, y = 32646, z = 6}, + {x = 33398, y = 32646, z = 6}, + {x = 33402, y = 32646, z = 6}, + {x = 33390, y = 32650, z = 6}, + {x = 33394, y = 32650, z = 6}, + {x = 33398, y = 32650, z = 6}, + {x = 33402, y = 32650, z = 6}, + {x = 33390, y = 32654, z = 6}, + {x = 33394, y = 32654, z = 6}, + {x = 33398, y = 32654, z = 6}, + {x = 33402, y = 32654, z = 6}, + {x = 33398, y = 32640, z = 6}, + {x = 33395, y = 32667, z = 6} + } + }, + -- Kilmaresh + -- First mission + -- data\scripts\quests\kilmaresh\1-fafnars-wrath\6-mind-travel.lua + [40004] = { + itemId = 1495, + itemPos = { + { x = 33915, y = 31635, z = 9 }, + { x = 33920, y = 31638, z = 9 }, + { x = 33909, y = 31642, z = 9 }, + { x = 33916, y = 31642, z = 9 } + } + }, + -- The Rookie Guard Quest - Mission 02: Defence! + -- Path: data\scripts\actions\quests\the_rookie_guard\mission02_defense.lua + -- Stone piles + [40005] = { + itemId = 13867, + itemPos = { + {x = 32080, y = 32183, z = 8}, + {x = 32080, y = 32184, z = 8}, + {x = 32081, y = 32184, z = 8} + } + }, + -- Bar catapult + [40006] = { + itemId = false, + itemPos = { + {x = 32098, y = 32176, z = 5}, + {x = 32099, y = 32176, z = 5}, + {x = 32098, y = 32177, z = 5}, + {x = 32099, y = 32177, z = 5} + } + }, + -- Academy catapult 1 + [40007] = { + itemId = false, + itemPos = { + {x = 32105, y = 32189, z = 5}, + {x = 32105, y = 32190, z = 5}, + {x = 32106, y = 32190, z = 5} + } + }, + -- Academy catapult 2 + [40008] = { + itemId = false, + itemPos = { + {x = 32105, y = 32194, z = 5}, + {x = 32105, y = 32195, z = 5} + } + }, + -- Shop catapult + [40009] = { + itemId = false, + itemPos = { + {x = 32109, y = 32200, z = 5}, + {x = 32110, y = 32200, z = 5}, + {x = 32109, y = 32201, z = 5}, + {x = 32110, y = 32201, z = 5} + } + }, + -- Spider webs + [40010] = { + itemId = false, + itemPos = { + {x = 32011, y = 32076, z = 12}, + {x = 32007, y = 32076, z = 12}, + {x = 32005, y = 32078, z = 12}, + {x = 32015, y = 32078, z = 12}, + {x = 32016, y = 32078, z = 12}, + {x = 32005, y = 32079, z = 12}, + {x = 32020, y = 32080, z = 12}, + {x = 32001, y = 32082, z = 12}, + {x = 32002, y = 32083, z = 12}, + {x = 32021, y = 32083, z = 12}, + {x = 32002, y = 32085, z = 12}, + {x = 32002, y = 32087, z = 12}, + {x = 32002, y = 32092, z = 12}, + {x = 32004, y = 32093, z = 12}, + {x = 32007, y = 32094, z = 12}, + {x = 32015, y = 32096, z = 12} + } + }, + -- The Rookie Guard Quest - Mission 07: Attack! + -- Path: data\scripts\actions\quests\the_rookie_guard\mission07_attack.lua + -- Fire fields + [40011] = { + itemId = 13882, + itemPos = { + {x = 32084, y = 32141, z = 10}, + {x = 32082, y = 32142, z = 10}, + {x = 32083, y = 32142, z = 10}, + {x = 32084, y = 32142, z = 10}, + } + }, + -- Orc fortress large cauldron + [40012] = { + itemId = false, + itemPos = { + {x = 31987, y = 32154, z = 8}, + {x = 31988, y = 32154, z = 8}, + {x = 31987, y = 32155, z = 8}, + {x = 31988, y = 32155, z = 8} + } + } +} + +ItemUnique = { + -- The shattered isles + -- data\scripts\actions\quests\the_shattered_isles\nargor_maps.lua + [40001] = { + itemId = 6118, + itemPos = {x = 31978, y = 32828, z = 2} + }, + [40002] = { + itemId = 6118, + itemPos = {x = 31982, y = 32844, z = 2} + }, + [40003] = { + itemId = 6118, + itemPos = {x = 31992, y = 32847, z = 2} + }, + -- Lions rock quest + -- data\scripts\actions\quests\lions_rock\lions_rock.lua + [40004] = { + itemId = 23761, + itemPos = {x = 33137, y = 32291, z = 8} + }, + [40005] = { + itemId = 1481, + itemPos = {x = 33138, y = 32369, z = 8} + }, + [40006] = { + itemId = 23762, + itemPos = {x = 33154, y = 32279, z = 8} + }, + -- Lions Rock (holy water and translation scrool) + -- data\scripts\actions\quests\lions_rock\lions_rock.lua + [40007] = { + itemId = 23765, + itemPos = {x = 33137, y = 32351, z = 6} + }, + [40008] = { + itemId = 24314, + itemPos = {x = 33119, y = 32247, z = 9} + }, + -- Insectoid cell rewards + -- data\scripts\actions\quests\others\gooey_mass.lua + [40011] = { + -- For use of the map + itemId = 14437, + itemPos = {x = 33480, y = 31196, z = 7} + }, + [40012] = { + itemId = 14437, + itemPos = {x = 33486, y = 31192, z = 1} + }, + [40013] = { + itemId = 14437, + itemPos = {x = 33511, y = 31169, z = 6} + }, + [40014] = { + itemId = 14437, + itemPos = {x = 33544, y = 31208, z = 5} + }, + [40015] = { + itemId = 14437, + itemPos = {x = 33553, y = 31240, z = 8} + }, + [40016] = { + itemId = 14437, + itemPos = {x = 33554, y = 31196, z = 8} + }, + [40017] = { + itemId = 14437, + itemPos = {x = 33586, y = 31213, z = 8} + }, + [40018] = { + itemId = 14437, + itemPos = {x = 33588, y = 31212, z = 4} + }, + [40019] = { + itemId = 14437, + itemPos = {x = 33605, y = 31223, z = 1} + }, + [40020] = { + itemId = 14438, + itemPos = {x = 33476, y = 31199, z = 2} + }, + [40021] = { + itemId = 14438, + itemPos = {x = 33480, y = 31196, z = 4} + }, + [40022] = { + itemId = 14438, + itemPos = {x = 33562, y = 31218, z = 2} + }, + [40023] = { + itemId = 14438, + itemPos = {x = 33564, y = 31217, z = 6} + }, + [40024] = { + itemId = 14438, + itemPos = {x = 33587, y = 31251, z = 7} + }, + [40025] = { + itemId = 14438, + itemPos = {x = 33610, y = 31221, z = 5} + }, + [40026] = { + itemId = 14438, + itemPos = {x = 33478, y = 31197, z = 3} + }, + -- The rare herb + -- data\scripts\actions\quests\dawnport\the_rare_herb.lua + [40027] = { + itemId = false, + itemPos = {x = 32028, y = 31882, z = 7} + }, + -- Grave danger (cobra bastion) + -- data\scripts\actions\quests\grave_danger\cobra_bastion + [40028] = { + itemId = 36319, + itemPos = {x = 33395, y = 32660, z = 6} + }, + + -- Kilmaresh + -- First mission + -- data\scripts\quests\kilmaresh\1-fafnars-wrath\2-ambassadors-treason.lua + [40029] = { + itemId = 36199, + itemPos = {x = 33955, y = 31502, z = 4} + }, + [40030] = { + itemId = 36200, + itemPos = {x = 33955, y = 31501, z = 3} + }, + [40031] = { + itemId = 7729, + itemPos = {x = 33956, y = 31504, z = 3} + }, + -- Four Masks + [40032] = { -- Ivory mask + itemId = 36104, + itemPos = {x = 33879, y = 31490, z = 6} + }, + + [40033] = { -- Gryphon mask + itemId = 36465, + itemPos = {x = 33841, y = 31682, z = 3} + }, + [40034] = { -- Silver mask + itemId = 36557, + itemPos = {x = 33780, y = 31664, z = 7} + }, + [40035] = { -- Mirror mask + itemId = 1417, + itemPos = {x = 33793, y = 31553, z = 8} + }, + -- Blessing the statues + [40036] = { + itemId = 35997, + itemPos = {x = 33854, y = 31521, z = 9} + }, + [40037] = { + itemId = 35997, + itemPos = {x = 33879, y = 31545, z = 9} + }, + [40038] = { + itemId = 35996, + itemPos = {x = 33891, y = 31504, z = 9} + }, + [40039] = { + itemId = 35997, + itemPos = {x = 33853, y = 31464, z = 9} + }, + [40040] = { + itemId = 35996, + itemPos = {x = 33874, y = 31433, z = 9} + }, + -- Explorer Society Quest + -- Path: data\scripts\actions\quests\explorer_society\findings.lua + -- Lizard Urn (Chor) + [40041] = { + itemId = 2034, + itemPos = {x = 32957, y = 32834, z = 8} + }, + -- Frozen Dragon (Okolnir) + -- Path: data\scripts\actions\quests\explorer_society\dragon.lua + [40042] = { + itemId = 7295, + itemPos = {x = 32321, y = 31455, z = 9} + }, + -- Icicles for Ice Music (Camp / Hrodmir) + -- Path: data\scripts\actions\quests\explorer_society\resonance.lua + [40043] = { + itemId = 6966, + itemPos = {x = 32078, y = 31217, z = 7} + }, + -- The Rookie Guard Quest - Mission 06: Run Like a Wolf + -- Path: data\scripts\actions\quests\the_rookie_guard\mission06_run_like_wolf.lua + -- Poacher corpse + [40044] = { + itemId = 2317, + itemPos = {x = 32135, y = 32133, z = 8} + }, + -- War wolf corpse + [40045] = { + itemId = 13878, + itemPos = {x = 32109, y = 32132, z = 11} + }, + -- The Rookie Guard Quest - Mission 07: Attack! + -- Path: data\scripts\actions\quests\the_rookie_guard\mission07_attack.lua + -- Destroy field rune + [40046] = { + itemId = 13884, + itemPos = {x = 32082, y = 32143, z = 10} + }, + -- Library vault treasure chest + [40047] = { + itemId = 12664, + itemPos = {x = 32083, y = 32141, z = 10} + }, + -- The Rookie Guard Quest - Mission 09: Rock 'n Troll + -- Path: data\scripts\actions\quests\the_rookie_guard\mission09_rock_troll.lua + -- Troll caves dug tunnel chest 1 + [40048] = { + itemId = 13903, + itemPos = {x = 32058, y = 32132, z = 10} + }, + -- Troll caves dug tunnel chest 2 + [40049] = { + itemId = 13903, + itemPos = {x = 32059, y = 32132, z = 10} + }, + -- Troll caves dug tunnel pillar 1 + [40050] = { + itemId = 3511, + itemPos = {x = 32067, y = 32143, z = 10} + }, + -- Troll caves dug tunnel pillar 2 + [40051] = { + itemId = 3511, + itemPos = {x = 32060, y = 32140, z = 10} + }, + -- Troll caves dug tunnel pillar 3 + [40052] = { + itemId = 3511, + itemPos = {x = 32065, y = 32134, z = 10} + }, + -- Troll caves dug tunnel pillar 4 + [40053] = { + itemId = 3511, + itemPos = {x = 32070, y = 32132, z = 10} + }, + -- Troll caves dug tunnel pillar 5 + [40054] = { + itemId = 3511, + itemPos = {x = 32076, y = 32129, z = 10} + }, + -- The Rookie Guard Quest - Mission 10: Tomb Raiding + -- Path: data\scripts\actions\quests\the_rookie_guard\mission10_tomb_raiding.lua + -- Unholy crypt sarcophagus + [40055] = { + itemId = 1417, + itemPos = {x = 32145, y = 32204, z = 10} + }, + -- The Rookie Guard Quest - Mission 12: Into The Fortress + -- Path: data\scripts\actions\quests\the_rookie_guard\mission12_into_fortress.lua + -- Academy treasure chest + [40056] = { + itemId = 12664, + itemPos = {x = 32109, y = 32187, z = 8} + }, + -- Kraknaknork lair teleport + [40057] = { + itemId = 8058, + itemPos = {x = 31977, y = 32166, z = 9} + }, + -- Kraknaknork lair energy barrier 1 + [40058] = { + itemId = 13934, + itemPos = {x = 31974, y = 32174, z = 10} + }, + -- Kraknaknork lair energy barrier 2 + [40059] = { + itemId = 13934, + itemPos = {x = 31962, y = 32174, z = 10} + }, + -- Kraknaknork lair energy barrier 3 + [40060] = { + itemId = 13934, + itemPos = {x = 31960, y = 32184, z = 10} + }, + -- Kraknaknork lair energy barrier 4 + [40061] = { + itemId = 13934, + itemPos = {x = 31953, y = 32187, z = 10} + }, + -- Kraknaknork lair energy barrier 5 + [40062] = { + itemId = 13934, + itemPos = {x = 31972, y = 32183, z = 10} + }, + -- Kraknaknork lair energy barrier 6 + [40063] = { + itemId = 13934, + itemPos = {x = 31952, y = 32174, z = 10} + }, + -- Kraknaknork lair lever 1 + [40064] = { + itemId = 10029, + itemPos = {x = 31975, y = 32170, z = 10} + }, + -- Kraknaknork lair lever 2 + [40065] = { + itemId = 10029, + itemPos = {x = 31961, y = 32168, z = 10} + }, + -- Kraknaknork lair lever 3 + [40066] = { + itemId = 10029, + itemPos = {x = 31957, y = 32190, z = 10} + }, + -- Kraknaknork lair lever 4 + [40067] = { + itemId = 10029, + itemPos = {x = 31968, y = 32179, z = 10} + }, + -- Kraknaknork lair lever 5 + [40068] = { + itemId = 10029, + itemPos = {x = 31949, y = 32187, z = 10} + }, + -- Kraknaknork lair lever 6 + [40069] = { + itemId = 10029, + itemPos = {x = 31976, y = 32180, z = 10} + }, + -- Kraknaknork room enter teleport + [40070] = { + itemId = 8058, + itemPos = {x = 31948, y = 32174, z = 10} + }, + -- Kraknaknork room exit teleport + [40071] = { + itemId = 8058, + itemPos = {x = 31945, y = 32174, z = 10} + }, + -- Kraknaknork treasure room enter teleport + [40072] = { + itemId = 8058, + itemPos = {x = 31929, y = 32171, z = 10} + }, + -- Kraknaknork treasure room left treasure chest + [40073] = { + itemId = 12664, + itemPos = {x = 31930, y = 32169, z = 11} + }, + -- Kraknaknork treasure room right treasure chest + [40074] = { + itemId = 12664, + itemPos = {x = 31935, y = 32169, z = 11} + }, + -- Kraknaknork treasure room exit teleport + [40075] = { + itemId = 8058, + itemPos = {x = 31932, y = 32167, z = 11} + }, + -- War wolf den chest + [40076] = { + itemId = 1740, + itemPos = {x = 32126, y = 32137, z = 9} + }, + -- Unholy crypt box + [40077] = { + itemId = 1738, + itemPos = {x = 32144, y = 32177, z = 10} + }, + -- Unholy crypt coffin + [40078] = { + itemId = 1744, + itemPos = {x = 32153, y = 32184, z = 10} + }, + -- Orc fortress treasure chest + [40079] = { + itemId = 12665, + itemPos = {x = 31991, y = 32157, z = 8} + }, + -- Orc fortress trunk + [40080] = { + itemId = 13902, + itemPos = {x = 31975, y = 32170, z = 8} + }, + -- Kraknaknork lair treasure chest + [40081] = { + itemId = 12665, + itemPos = {x = 31978, y = 32184, z = 10} + } +} diff --git a/data/startup/tables/item_daily_reward.lua b/data/startup/tables/item_daily_reward.lua new file mode 100644 index 00000000000..5fc799553f1 --- /dev/null +++ b/data/startup/tables/item_daily_reward.lua @@ -0,0 +1,42 @@ +DailyRewardAction = { + [3001] = { + isDailyReward = true, + itemId = 5972, + itemPos = {{x = 32794, y = 31572, z = 7}} + }, + [3002] = { + isDailyReward = true, + itemId = 2088, + itemPos = {{x = 32802, y = 31576, z = 7}} + }, + [3003] = { + isDailyReward = true, + itemId = 2088, + itemPos = {{x = 32790, y = 31593, z = 7}} + }, + [3004] = { + isDailyReward = true, + itemId = 2088, + itemPos = {{x = 32807, y = 31576, z = 6}} + }, + [3005] = { + isDailyReward = true, + itemId = 2088, + itemPos = {{x = 32792, y = 31590, z = 6}} + }, + [3006] = { + isDailyReward = true, + itemId = 2088, + itemPos = {{x = 32801, y = 31579, z = 6}} + }, + [3007] = { + isDailyReward = true, + itemId = 2088, + itemPos = {{x = 32813, y = 31576, z = 5}} + }, + [3008] = { + isDailyReward = true, + itemId = 1718, + itemPos = {{x = 32800, y = 31582, z = 2}} + } +} diff --git a/data/startup/tables/item_unmoveable.lua b/data/startup/tables/item_unmoveable.lua new file mode 100644 index 00000000000..ab8b7eedcab --- /dev/null +++ b/data/startup/tables/item_unmoveable.lua @@ -0,0 +1,11 @@ +-- Look README.md for see the reserved action/unique numbers + +ItemUnmoveableAction = { + -- Unmovable action, add new position and it create in-game + [100] = { + itemId = false, + itemPos = { + {x = xxxxx, y = yyyyy, z = z} + } + } +} diff --git a/data/startup/tables/lever.lua b/data/startup/tables/lever.lua new file mode 100644 index 00000000000..2fc3685265f --- /dev/null +++ b/data/startup/tables/lever.lua @@ -0,0 +1,152 @@ +-- Look README.md for see the reserved action/unique numbers + +LeverAction = { + -- Dawnport bridge lever + -- Path: data\scripts\actions\dawnport\lever.lua + [30001] = { + itemId = false, + itemPos = { + {x = 32107, y = 31901, z = 7}, + {x = 32104, y = 31906, z = 7} + } + } +} + +LeverUnique = { + -- Dark trails quest (The Ravager lever) + -- Path: data\scripts\actions\quests\dark_trails\lever_the_ravager.lua + [30001] = { + itemId = 1945, + itemPos = {x = 33416, y = 32102, z = 10} + }, + -- Death priest shargon lever + [30002] = { + itemId = 1946, + itemPos = {x = 33582, y = 31844, z = 10} + }, + -- The first dragon quest lever + -- Path: data\scripts\actions\quests\first_dragon\lever.lua + [30003] = { + itemId = 9825, + itemPos = {x = 33583, y = 30992, z = 14} + }, + -- Thais lighthouse quest + -- Path: data\scripts\quests\thais_lighthouse\action-lever.lua + [30004] = { + itemId = 1945, + itemPos = {x = 32227, y = 32278, z = 8} + }, + [30005] = { + itemId = 1945, + itemPos = {x = 32225, y = 32285, z = 10} + }, + -- Draconia quest + -- Path: data\scripts\quests\draconia\action-lever.lua + [30006] = { + itemId = 1945, + itemPos = {x = 32792, y = 31595, z = 7} + }, + -- Demon helmet quest + -- Path: data\scripts\quests\demon_helmet\action-lever.lua + [30007] = { + itemId = 1945, + itemPos = {x = 33330, y = 31574, z = 15} + }, + -- Alawar's vault quest + -- Path: data\scripts\quests\alawars_ault\action-lever.lua + [30008] = { + itemId = 1945, + itemPos = {x = 32180, y = 31633, z = 8} + }, + -- Behemoth quest + -- Path: data\scripts\quests\behemoth\action-lever.lua + [30009] = { + itemId = 1945, + itemPos = {x = 33290, y = 31715, z = 12} + }, + -- The queen of the banshees quest + -- Path: data\scripts\quests\the_queen_of_the_banshees\action(1)-first_seal_lever.lua + [30010] = { + itemId = 1945, + itemPos = {x = 32315, y = 31910, z = 12} + }, + [30011] = { + itemId = 1945, + itemPos = {x = 32212, y = 31888, z = 12} + }, + [30012] = { + itemId = 32400, + itemPos = {x = 32266, y = 31861, z = 11} + }, + -- Path: data\scripts\quests\the_queen_of_the_banshees\action(3)-third_seal_lever.lua + [30013] = { + itemId = 1946, + itemPos = {x = 32220, y = 31843, z = 15} + }, + [30014] = { + itemId = 1946, + itemPos = {x = 32220, y = 31845, z = 15} + }, + [30015] = { + itemId = 1946, + itemPos = {x = 32220, y = 31844, z = 15} + }, + [30016] = { + itemId = 1946, + itemPos = {x = 32220, y = 31842, z = 15} + }, + [30017] = { + itemId = 1946, + itemPos = {x = 32220, y = 31846, z = 15} + }, + -- Path: data\scripts\quests\the_queen_of_the_banshees\action(6)-sixth_seal_lever.lua + [30018] = { + itemId = 1945, + itemPos = {x = 32310, y = 31975, z = 13} + }, + [30019] = { + itemId = 1945, + itemPos = {x = 32310, y = 31976, z = 13} + }, + [30020] = { + itemId = 1945, + itemPos = {x = 32312, y = 31975, z = 13} + }, + [30021] = { + itemId = 1945, + itemPos = {x = 32312, y = 31976, z = 13} + }, + [30022] = { + itemId = 1945, + itemPos = {x = 32314, y = 31975, z = 13} + }, + [30023] = { + itemId = 1945, + itemPos = {x = 32314, y = 31976, z = 13} + }, + -- Path: data\scripts\quests\giant_smithhammer\lever.lua + [30024] = { + itemId = 1945, + itemPos = {x = 32778, y = 32232, z = 8} + }, + -- Path: data\scripts\quests\the_annihilator\lever.lua + [30025] = { + itemId = 1945, + itemPos = {x = 33226, y = 31671, z = 13} + }, + -- Path: data\scripts\quests\the_paradox_tower\action-3-third_floor_lever.lua + [30026] = { + itemId = 10044, + itemPos = {x = 32481, y = 31904, z = 5} + }, + -- Path: data\scripts\quests\the_paradox_tower\action-4-four_floor_lever.lua + [30027] = { + itemId = 1945, + itemPos = {x = 32479, y = 31905, z = 4} + }, + -- Path: data\scripts\quests\the_paradox_tower\action-5-fifth_floor_lever.lua + [30028] = { + itemId = 1945, + itemPos = {x = 32478, y = 31904, z = 3} + } +} diff --git a/data/startup/tables/tables.lua b/data/startup/tables/tables.lua new file mode 100644 index 00000000000..6180dc3c56c --- /dev/null +++ b/data/startup/tables/tables.lua @@ -0,0 +1,14 @@ +dofile('data/startup/tables/chest.lua') +dofile('data/startup/tables/corpse.lua') +dofile('data/startup/tables/door_key.lua') +dofile('data/startup/tables/door_level.lua') +dofile('data/startup/tables/door_quest.lua') +dofile('data/startup/tables/item.lua') +dofile('data/startup/tables/item_daily_reward.lua') +dofile('data/startup/tables/item_unmoveable.lua') +dofile('data/startup/tables/lever.lua') +dofile('data/startup/tables/teleport.lua') +dofile('data/startup/tables/teleport_item.lua') +dofile('data/startup/tables/tile.lua') +dofile('data/startup/tables/tile_pick.lua') +dofile('data/startup/tables/writeable.lua') diff --git a/data/startup/tables/teleport.lua b/data/startup/tables/teleport.lua new file mode 100644 index 00000000000..d1d3145f096 --- /dev/null +++ b/data/startup/tables/teleport.lua @@ -0,0 +1,322 @@ +-- Look README.md for see the reserved action/unique numbers + +TeleportAction = { + [35001] = { -- The Cursed Crystal teleports + itemId = 21721, + itemPos = { + {x = 31973, y = 32905, z = 10}, + {x = 31973, y = 32905, z = 11}, + {x = 32009, y = 32928, z = 10}, + {x = 32009, y = 32928, z = 9} + } + }, + -- Path: data\scripts\movements\quests\the_queen_of_the_banshees\movement(2)-second_seal_pearl.lua + [35002] = { + itemId = 1387, + itemPos = { + {x = 32176, y = 31869, z = 15}, + {x = 32177, y = 31869, z = 15} + } + } +} + +TeleportUnique = { + -- The first dragon quest + -- Path: data\scripts\movements\quests\first_dragon\entrance_teleport.lua + -- Tazhadur entrance + [35001] = { + itemId = 9565, + itemPos = {x = 33234, y = 32276, z = 12} + }, + -- Kalyassa entrance + [35002] = { + itemId = 9562, + itemPos = {x = 33160, y = 31320, z = 5} + }, + -- Zorvorax entrance + [35003] = { + itemId = 9564, + itemPos = {x = 33003, y = 31593, z = 11} + }, + -- Gelidrazah entrance + [35004] = { + itemId = 9563, + itemPos = {x = 32276, y = 31367, z = 4} + }, + -- Tazhadur exit + -- Path: data\scripts\movements\quests\first_dragon\exit_teleport.lua + [35005] = { + itemId = 9565, + itemPos = {x = 32013, y = 32467, z = 8} + }, + -- Kalyassa exit + [35006] = { + itemId = 9562, + itemPos = {x = 32076, y = 32457, z = 8} + }, + -- Zorvorax exit + [35007] = { + itemId = 9564, + itemPos = {x = 32006, y = 32395, z = 8} + }, + -- Gelidrazah exit + [35008] = { + itemId = 9563, + itemPos = {x = 32077, y = 32404, z = 8} + }, + -- Lions rock quest + -- Path: data\scripts\movements\quests\lions_rock\lions_rock.lua + [35009] = { + itemId = 8058, + itemPos = {x = 33128, y = 32308, z = 8} + }, + -- Dawnport quest + -- Sacred snake teleport + -- Path: data\scripts\movements\quests\dawnport\legion_helmet.lua + [35010] = { + itemId = 1387, + itemPos = {x = 32112, y = 31936, z = 8} + }, + -- Draconia quest + -- Exit teleport + -- Path: data\scripts\movements\quests\draconia\movement-exit_teleport.lua + [35011] = { + itemId = 1387, + itemPos = {x = 32805, y = 31587, z = 1} + }, + -- Path: data\scripts\movements\quests\draconia\movement-escape.lua + [35012] = { + itemId = 1387, + itemPos = {x = 32815, y = 31599, z = 9} + }, + -- The queen of the banshees quest + -- Path: data\scripts\movements\quests\the_queen_of_the_banshees\movement(1)-first_seal_flame.lua + [35013] = { + itemId = 8058, + itemPos = {x = 32278, y = 31903, z = 13} + }, + -- Path: data\scripts\movements\quests\the_queen_of_the_banshees\movement(2)-second_seal_flame.lua + [35014] = { + itemId = 8058, + itemPos = {x = 32171, y = 31853, z = 15} + }, + -- Path: data\scripts\movements\quests\the_queen_of_the_banshees\movement(3)-third_seal_flame.lua + [35015] = { + itemId = 8058, + itemPos = {x = 32215, y = 31849, z = 15} + }, + -- Path: data\scripts\movements\quests\the_queen_of_the_banshees\movement(4)-fourth_seal_flame.lua + [35016] = { + itemId = 8058, + itemPos = {x = 32250, y = 31892, z = 14} + }, + -- Path: data\scripts\movements\quests\the_queen_of_the_banshees\movement(5)-fifth_seal_flame.lua + [35017] = { + itemId = 8058, + itemPos = {x = 32192, y = 31938, z = 14} + }, + -- Path: data\scripts\movements\quests\the_queen_of_the_banshees\movement(6)-sixth_seal_flame.lua + [35018] = { + itemId = 8058, + itemPos = {x = 32311, y = 31978, z = 13} + }, + -- Path: data\scripts\movements\quests\the_queen_of_the_banshees\movement(7)-last_seal_flame.lua + [35019] = { + itemId = 1387, + itemPos = {x = 32219, y = 31913, z = 15} + }, + -- Path: data\scripts\movements\quests\nightmare_isles\teleport.lua + [35020] = { + itemId = 11796, + itemPos = {x = 33498, y = 32613, z = 8} + }, + + -- Simple teleports (They are registered automatically, without just configuring the table correctly) + -- Path: data\scripts\movements\others\teleport.lua + + -- Quests teleports + -- Deeper fibula quest teleport + -- Entrance + [38001] = { + itemId = 1387, + itemPos = {x = 32208, y = 32433, z = 10}, + destination = {x = 32281, y = 32389, z = 10}, + effect = CONST_ME_TELEPORT + }, + -- Exit + [38002] = { + itemId = 1387, + itemPos = {x = 32234, y = 32502, z = 10}, + destination = {x = 32210, y = 32437, z = 10}, + effect = CONST_ME_TELEPORT + }, + -- Draconia quest teleports + [38003] = { + itemId = 1387, + itemPos = {x = 32675, y = 31646, z = 10}, + destination = {x = 32725, y = 31589, z = 12}, + effect = CONST_ME_TELEPORT + }, + [38004] = { + itemId = 1387, + itemPos = {x = 32669, y = 31653, z = 10}, + destination = {x = 32679, y = 31673, z = 10}, + effect = CONST_ME_TELEPORT + }, + [38005] = { + itemId = 1387, + itemPos = {x = 32794, y = 31576, z = 5}, + destination = {x = 32812, y = 31577, z = 5}, + effect = CONST_ME_TELEPORT + }, + [38006] = { + itemId = 1387, + itemPos = {x = 32812, y = 31576, z = 5}, + destination = {x = 32794, y = 31577, z = 5}, + effect = CONST_ME_TELEPORT + }, + -- Demom helmet quest teleports + [38007] = { + itemId = 1387, + itemPos = {x = 33278, y = 31592, z = 11}, + destination = {x = 33281, y = 31592, z = 12}, + effect = CONST_ME_TELEPORT + }, + [38008] = { + itemId = 1387, + itemPos = {x = 33286, y = 31589, z = 12}, + destination = {x = 33277, y = 31592, z = 11}, + effect = CONST_ME_TELEPORT + }, + [38009] = { + itemId = 1387, + itemPos = {x = 33324, y = 31592, z = 14}, + destination = {x = 33324, y = 31575, z = 15}, + effect = CONST_ME_TELEPORT + }, + -- Alawar's vault quest + -- Entrance + [38010] = { + itemId = 1387, + itemPos = {x = 32187, y = 31622, z = 8}, + destination = {x = 32107, y = 31567, z = 9}, + effect = CONST_ME_TELEPORT + }, + -- Exit + [38011] = { + itemId = 1387, + itemPos = {x = 32107, y = 31566, z = 9}, + destination = {x = 32189, y = 31625, z = 4}, + effect = CONST_ME_TELEPORT + }, + -- Black knight quest entrance + [38012] = { + itemId = 1387, + itemPos = {x = 32874, y = 31941, z = 12}, + destination = {x = 32874, y = 31948, z = 11}, + effect = CONST_ME_TELEPORT + }, + -- Black knight quest exit + [38013] = { + itemId = 1387, + itemPos = {x = 32874, y = 31955, z = 11}, + destination = {x = 32874, y = 31942, z = 12}, + effect = CONST_ME_TELEPORT + }, + -- The queen of the banshees teleports + [38014] = { + itemId = 1387, + itemPos = {x = 32262, y = 31889, z = 10}, + destination = {x = 32259, y = 31892, z = 10}, + effect = CONST_ME_TELEPORT + }, + [38015] = { + itemId = 1387, + itemPos = {x = 32266, y = 31857, z = 12}, + destination = {x = 32266, y = 31864, z = 12}, + effect = CONST_ME_TELEPORT + }, + [38016] = { + itemId = 1387, + itemPos = {x = 32266, y = 31863, z = 12}, + destination = {x = 32266, y = 31858, z = 12}, + effect = CONST_ME_TELEPORT + }, + -- The annihilator quest room exit + [38017] = { + itemId = 1387, + itemPos = {x = 33236, y = 31655, z = 13}, + destination = {x = 33213, y = 31671, z = 13}, + effect = CONST_ME_TELEPORT + }, + -- The paradox tower quest + [38018] = { + itemId = 1387, + itemPos = {x = 32476, y = 31904, z = 5}, + destination = {x = 32476, y = 31904, z = 6}, + effect = CONST_ME_TELEPORT + }, + [38019] = { + itemId = 1387, + itemPos = {x = 32481, y = 31904, z = 4}, + destination = {x = 32481, y = 31905, z = 5}, + effect = CONST_ME_TELEPORT + }, + [38020] = { + itemId = 1387, + itemPos = {x = 32476, y = 31904, z = 3}, + destination = {x = 32476, y = 31904, z = 4}, + effect = CONST_ME_TELEPORT + }, + [38021] = { + itemId = 1387, + itemPos = {x = 32479, y = 31904, z = 2}, + destination = {x = 32479, y = 31904, z = 3}, + effect = CONST_ME_TELEPORT + }, + [38022] = { + itemId = 1387, + itemPos = {x = 32481, y = 31905, z = 1}, + destination = {x = 32480, y = 31905, z = 2}, + effect = CONST_ME_TELEPORT + }, + + -- Others teleports + -- Water elemental cave (Trapwood) + [39001] = { + itemId = 8632, + itemPos = {x = 32600, y = 33009, z = 8}, + destination = {x = 32600, y = 33009, z = 9}, + effect = CONST_ME_TELEPORT + }, + [39002] = { + itemId = 7106, + itemPos = {x = 32628, y = 33001, z = 9}, + destination = {x = 32624, y = 33001, z = 9}, + effect = CONST_ME_TELEPORT + }, + [39003] = { + itemId = 8632, + itemPos = {x = 32649, y = 32985, z = 8}, + destination = {x = 32653, y = 32987, z = 9}, + effect = CONST_ME_TELEPORT + }, + [39004] = { + itemId = 7106, + itemPos = {x = 32654, y = 32985, z = 9}, + destination = {x = 32651, y = 32983, z = 8}, + effect = CONST_ME_TELEPORT + }, + [39005] = { + itemId = 8632, + itemPos = {x = 32610, y = 32977, z = 8}, + destination = {x = 32612, y = 32980, z = 9}, + effect = CONST_ME_TELEPORT + }, + [39006] = { + itemId = 7106, + itemPos = {x = 32610, y = 32979, z = 9}, + destination = {x = 32608, y = 32978, z = 8}, + effect = CONST_ME_TELEPORT + } +} diff --git a/data/startup/tables/teleport_item.lua b/data/startup/tables/teleport_item.lua new file mode 100644 index 00000000000..8c84b70ec9f --- /dev/null +++ b/data/startup/tables/teleport_item.lua @@ -0,0 +1,73 @@ +-- Look README.md for see the reserved action/unique numbers +-- This file is only for teleports items (miscellaneous) not for magic forcefields + +TeleportItemAction = { + -- Feyrist shrines entrance + -- Path: data\scripts\actions\other\gems.lua + [15001] = { + itemId = false, + itemPos = { + {x = 32194, y = 31418, z = 2}, + {x = 32194, y = 31419, z = 2}, + {x = 32195, y = 31418, z = 2}, + {x = 32195, y = 31419, z = 2} + }, + }, + [15002] = { + itemId = false, + itemPos = { + {x = 32910, y = 32338, z = 15}, + {x = 32910, y = 32339, z = 15}, + {x = 32911, y = 32338, z = 15}, + {x = 32911, y = 32339, z = 15} + } + }, + [15003] = { + itemId = false, + itemPos = { + {x = 32973, y = 32225, z = 7}, + {x = 32973, y = 32226, z = 7}, + {x = 32974, y = 32225, z = 7}, + {x = 32974, y = 32226, z = 7} + } + }, + [15004] = { + itemId = false, + itemPos = { + {x = 33060, y = 32713, z = 5}, + {x = 33060, y = 32714, z = 5}, + {x = 33061, y = 32713, z = 5}, + {x = 33061, y = 32714, z = 5} + } + }, + -- Deeper fibula draw well + -- Path: data\scripts\quests\deeper_fibula\action-draw_well.lua + [15005] = { + itemId = false, + itemPos = { + {x = 32171, y = 32439, z = 7}, + {x = 32172, y = 32439, z = 7} + } + }, +} + +TeleportItemUnique = { + [15001] = { + itemId = 36508, + itemPos = {x = 33315, y = 32647, z = 6}, + destination = {x = 33384, y = 32627, z = 7}, + effect = CONST_ME_TELEPORT + }, + [15002] = { + itemId = 3591, + itemPos = {x = 33383, y = 32626, z = 7}, + destination = {x = 33314, y = 32647, z = 6}, + effect = CONST_ME_TELEPORT + }, + [15003] = { + itemId = 5679, + itemPos = {x = 33918, y = 31471, z = 7}, + destination = {x = 33916, y = 31466, z = 8}, + effect = CONST_ME_TELEPORT + } +} diff --git a/data/startup/tables/tile.lua b/data/startup/tables/tile.lua new file mode 100644 index 00000000000..0fefdec4f20 --- /dev/null +++ b/data/startup/tables/tile.lua @@ -0,0 +1,1220 @@ +-- Look README.md for see the reserved action/unique numbers + +TileAction = { + -- Cure poison tiles at dawnport outpost entrances + -- Tiles data\scripts\movements\others\dawnport_tiles.lua + [20001] = { + itemId = 413, + itemPos = { + {x = 32064, y = 31881, z = 5}, + {x = 32065, y = 31881, z = 5}, + {x = 32074, y = 31890, z = 5}, + {x = 32074, y = 31891, z = 5}, + {x = 32064, y = 31900, z = 5}, + {x = 32065, y = 31900, z = 5}, + {x = 32056, y = 31890, z = 5}, + {x = 32056, y = 31891, z = 5} + } + }, + -- Dark trails quest tile + -- data\scripts\movements\quests\dark_trails\necrometer_tile_access.lua + [25001] = { + itemId = false, + itemPos = { + {x = 33418, y = 32108, z = 10}, + {x = 33419, y = 32108, z = 10} + } + }, + -- First dragon quest tile + -- data\scripts\movements\quests\first_dragon\zorvorax_secrets.lua + [25002] = { + itemId = false, + itemPos = { + {x = 33135, y = 32652, z = 7}, + {x = 33128, y = 32654, z = 7} + } + }, + [25003] = { + itemId = false, + itemPos = { + {x = 32348, y = 31691, z = 7}, + {x = 32343, y = 31694, z = 7} + } + }, + [25004] = { + itemId = false, + itemPos = { + {x = 32696, y = 31720, z = 7}, + {x = 32697, y = 31720, z = 7}, + {x = 32698, y = 31720, z = 7} + } + }, + --Dawnport + --Sorcerer vocation tile + --Vocation trial: data\scripts\movements\others\dawnport_vocation_trial.lua + [25005] = { + itemId = 413, + itemPos = { + {x = 32055, y = 31889, z = 5}, + {x = 32055, y = 31890, z = 5}, + {x = 32055, y = 31891, z = 5}, + {x = 32055, y = 31892, z = 5} + } + }, + --Druid vocation tile + [25006] = { + itemId = 413, + itemPos = { + {x = 32063, y = 31901, z = 5}, + {x = 32064, y = 31901, z = 5}, + {x = 32065, y = 31901, z = 5}, + {x = 32066, y = 31901, z = 5} + } + }, + --Paladin vocation tile + [25007] = { + itemId = 413, + itemPos = { + {x = 32075, y = 31889, z = 5}, + {x = 32075, y = 31890, z = 5}, + {x = 32075, y = 31891, z = 5}, + {x = 32075, y = 31892, z = 5}, + } + }, + --Knight vocation tile + [25008] = { + itemId = 413, + itemPos = { + {x = 32063, y = 31880, z = 5}, + {x = 32064, y = 31880, z = 5}, + {x = 32065, y = 31880, z = 5}, + {x = 32066, y = 31880, z = 5} + } + }, + -- Tiles data\scripts\movements\others\dawnport_tiles.lua + --Stairs decided vocation back + [25009] = { + itemId = 1385, + itemPos = { + {x = 32063, y = 31889, z = 6}, + {x = 32064, y = 31889, z = 6}, + {x = 32065, y = 31889, z = 6}, + {x = 32066, y = 31889, z = 6} + } + }, + --Sorcerer door tile + [25010] = { + itemId = 406, + itemPos = { + {x = 32053, y = 31884, z = 6}, + {x = 32054, y = 31884, z = 6}, + {x = 32055, y = 31884, z = 6} + } + }, + --Druid door tile + [25011] = { + itemId = 406, + itemPos = { + {x = 32072, y = 31884, z = 6}, + {x = 32073, y = 31884, z = 6}, + {x = 32074, y = 31884, z = 6} + } + }, + --Paladin door tile + [25012] = { + itemId = 406, + itemPos = { + {x = 32058, y = 31884, z = 6}, + {x = 32059, y = 31884, z = 6}, + {x = 32060, y = 31884, z = 6} + } + }, + --Knight door tile + [25013] = { + itemId = 406, + itemPos = { + {x = 32067, y = 31884, z = 6}, + {x = 32068, y = 31884, z = 6}, + {x = 32069, y = 31884, z = 6} + } + }, + --Sorcerer chest tile + [25014] = { + itemId = 406, + itemPos = {{x = 32054, y = 31880, z = 6}} + }, + --Druid chest tile + [25015] = { + itemId = 406, + itemPos = {{x = 32073, y = 31880, z = 6}} + }, + --Paladin chest tile + [25016] = { + itemId = 406, + itemPos = {{x = 32059, y = 31880, z = 6}} + }, + --Knight chest tile + [25017] = { + itemId = 406, + itemPos = {{x = 32068, y = 31880, z = 6}} + }, + -- The cursed crystal medusa message + [25018] = { + itemId = 104, + itemPos = { + {x = 32017, y = 32917, z = 10}, + {x = 32017, y = 32918, z = 10} + } + }, + -- The queen of the banshees quest + -- Path: data\scripts\movements\quests\the_queen_of_the_banshees\movement(1)-first_seal_teleport_back.lua + [25019] = { + itemId = 9023, + itemPos = { + {x = 32265, y = 31898, z = 12}, + {x = 32266, y = 31898, z = 12}, + {x = 32267, y = 31898, z = 12} + } + }, + -- Path: data\scripts\movements\quests\the_queen_of_the_banshees\movement(5)-fifth_seal_path.lua + [25020] = { + itemId = 426, + itemPos = { + {x = 32187, y = 31937, z = 14}, + {x = 32188, y = 31937, z = 14}, + {x = 32188, y = 31938, z = 14}, + {x = 32189, y = 31938, z = 14}, + {x = 32189, y = 31939, z = 14}, + {x = 32189, y = 31940, z = 14}, + {x = 32190, y = 31940, z = 14}, + {x = 32191, y = 31939, z = 14}, + {x = 32191, y = 31938, z = 14} + } + }, + -- Path: data\scripts\movements\quests\the_queen_of_the_banshees\movement(5)-fifth_seal_path.lua + [25021] = { + itemId = 426, + itemPos = { + {x = 32187, y = 31936, z = 14}, + {x = 32188, y = 31936, z = 14}, + {x = 32189, y = 31936, z = 14}, + {x = 32190, y = 31936, z = 14}, + {x = 32191, y = 31936, z = 14}, + {x = 32189, y = 31937, z = 14}, + {x = 32190, y = 31937, z = 14}, + {x = 32191, y = 31937, z = 14}, + {x = 32187, y = 31938, z = 14}, + {x = 32190, y = 31938, z = 14}, + {x = 32187, y = 31939, z = 14}, + {x = 32188, y = 31939, z = 14}, + {x = 32190, y = 31939, z = 14}, + {x = 32187, y = 31940, z = 14}, + {x = 32188, y = 31940, z = 14}, + {x = 32189, y = 31940, z = 14}, + {x = 32191, y = 31940, z = 14} + } + }, + -- Path: data\scripts\movements\quests\the_queen_of_the_banshees\movement(4)-fourth_seal_sacrifice.lua + [25022] = { + itemId = 425, + itemPos = {{x = 32243, y = 31892, z = 14}} + }, + -- Path: data\scripts\movements\quests\the_queen_of_the_banshees\movement(3)-third_seal_warlock_tile.lua + [25023] = { + itemId = 426, + itemPos = { + {x = 32215, y = 31838, z = 15}, + {x = 32216, y = 31838, z = 15} + } + }, + -- Others actions + -- Threatened Dreams Quest + [50301] = { + itemId = false, + itemPos = { + {x = 33200, y = 31892, z = 7}, + {x = 33201, y = 31892, z = 7}, + {x = 33201, y = 31893, z = 7}, + {x = 33201, y = 31894, z = 7} + } + }, + [50302] = { + itemId = false, + itemPos = { + {x = 33258, y = 32402, z = 7}, + {x = 33257, y = 32402, z = 7}, + {x = 33257, y = 32401, z = 7}, + {x = 33259, y = 32402, z = 7} + } + }, + [50303] = { + itemId = false, + itemPos = { + {x = 33262, y = 32378, z = 7}, + {x = 33262, y = 32377, z = 7}, + {x = 33263, y = 32377, z = 7}, + {x = 33264, y = 32377, z = 7}, + {x = 33262, y = 32379, z = 7}, + {x = 33263, y = 32379, z = 7}, + {x = 33264, y = 32379, z = 7} + } + }, + [50304] = { + itemId = false, + itemPos = { + {x = 33257, y = 32315, z = 7}, + {x = 33257, y = 32314, z = 7}, + {x = 33259, y = 32314, z = 7}, + {x = 33259, y = 32315, z = 7} + } + }, + [50306] = { + itemId = false, + itemPos = { + {x = 33249, y = 32267, z = 6}, + {x = 33249, y = 32268, z = 6}, + {x = 33250, y = 32268, z = 6} + } + }, + -- Kilmaresh + -- First mission + [50307] = { + itemId = false, + itemPos = { + { x = 33956, y = 31503, z = 2 }, + { x = 33957, y = 31503, z = 2 } + } + }, + -- The paradox tower quest + -- data\scripts\movements\quests\the_paradox_tower\movement-last_floor_reward.lua + -- Phoenix egg + [50308] = { + itemId = 426, + itemPos = { + {x = 32476, y = 31903, z = 1}, + {x = 32477, y = 31903, z = 1}, + {x = 32478, y = 31903, z = 1} + } + }, + -- 10000 gold coins + [50309] = { + itemId = 426, + itemPos = { + {x = 32479, y = 31903, z = 1}, + {x = 32481, y = 31902, z = 1}, + {x = 32476, y = 31902, z = 1} + } + }, + -- Talons + [50310] = { + itemId = 426, + itemPos = { + {x = 32478, y = 31902, z = 1}, + {x = 32479, y = 31902, z = 1}, + {x = 32480, y = 31902, z = 1} + } + }, + -- Wand of cosmic energy + [50311] = { + itemId = 426, + itemPos = { + {x = 32477, y = 31902, z = 1}, + {x = 32480, y = 31903, z = 1}, + {x = 32481, y = 31903, z = 1} + } + }, + -- The Rookie Guard Quest - Mission 02: Defence! + -- Path: data\scripts\actions\quests\the_rookie_guard\mission02_defense.lua + -- North exit + [50312] = { + itemId = false, + itemPos = { + {x = 32087, y = 32181, z = 7}, + {x = 32088, y = 32181, z = 7}, + {x = 32089, y = 32181, z = 7}, + {x = 32090, y = 32181, z = 7}, + {x = 32091, y = 32181, z = 7}, + {x = 32092, y = 32181, z = 7}, + {x = 32093, y = 32181, z = 7}, + {x = 32094, y = 32181, z = 7}, + } + }, + -- Barn entrance + [50313] = { + itemId = false, + itemPos = { + {x = 32081, y = 32190, z = 7}, + {x = 32082, y = 32190, z = 7}, + {x = 32083, y = 32190, z = 7}, + {x = 32084, y = 32189, z = 7} + } + }, + -- Bar entrance + [50314] = { + itemId = false, + itemPos = { + {x = 32095, y = 32182, z = 7}, + {x = 32095, y = 32183, z = 7}, + {x = 32095, y = 32184, z = 7}, + {x = 32095, y = 32185, z = 7} + } + }, + -- Academy center + [50315] = { + itemId = 9146, + itemPos = { + {x = 32096, y = 32194, z = 7}, + {x = 32097, y = 32194, z = 7}, + {x = 32098, y = 32194, z = 7} + } + }, + -- Obi shop entrance + [50316] = { + itemId = 724, + itemPos = { + {x = 32101, y = 32204, z = 7}, + {x = 32101, y = 32205, z = 7}, + {x = 32101, y = 32206, z = 7} + } + }, + -- Center north road + [50317] = { + itemId = false, + itemPos = { + {x = 32089, y = 32197, z = 7}, + {x = 32090, y = 32197, z = 7}, + {x = 32091, y = 32197, z = 7}, + {x = 32092, y = 32197, z = 7}, + {x = 32093, y = 32197, z = 7} + } + }, + -- Center north-west road + [50318] = { + itemId = false, + itemPos = { + {x = 32086, y = 32189, z = 7}, + {x = 32086, y = 32190, z = 7}, + {x = 32086, y = 32191, z = 7}, + {x = 32086, y = 32192, z = 7}, + {x = 32086, y = 32193, z = 7}, + {x = 32086, y = 32194, z = 7}, + {x = 32086, y = 32195, z = 7} + } + }, + -- North bridge exit + [50319] = { + itemId = 724, + itemPos = {{x = 32091, y = 32169, z = 7}} + }, + -- Outer north-west path + [50320] = { + itemId = false, + itemPos = { + {x = 32084, y = 32161, z = 7}, + {x = 32085, y = 32161, z = 7}, + {x = 32086, y = 32161, z = 7}, + {x = 32087, y = 32161, z = 7} + } + }, + -- Outer north-east path + [50321] = { + itemId = false, + itemPos = { + {x = 32097, y = 32161, z = 7}, + {x = 32098, y = 32161, z = 7}, + {x = 32099, y = 32161, z = 7}, + {x = 32100, y = 32161, z = 7}, + {x = 32105, y = 32161, z = 7}, + {x = 32106, y = 32161, z = 7}, + {x = 32107, y = 32161, z = 7}, + {x = 32109, y = 32161, z = 7}, + {x = 32110, y = 32161, z = 7}, + {x = 32111, y = 32161, z = 7}, + {x = 32112, y = 32161, z = 7}, + {x = 32113, y = 32161, z = 7}, + {x = 32114, y = 32161, z = 7}, + {x = 32115, y = 32161, z = 7}, + {x = 32116, y = 32161, z = 7}, + {x = 32117, y = 32161, z = 7}, + {x = 32120, y = 32161, z = 7}, + {x = 32122, y = 32161, z = 7}, + {x = 32124, y = 32161, z = 7}, + {x = 32125, y = 32161, z = 7} + } + }, + -- Outer south path + [50322] = { + itemId = false, + itemPos = { + {x = 32104, y = 32181, z = 7}, + {x = 32105, y = 32181, z = 7}, + {x = 32106, y = 32181, z = 7}, + {x = 32107, y = 32181, z = 7}, + {x = 32108, y = 32181, z = 7}, + {x = 32109, y = 32181, z = 7}, + {x = 32110, y = 32181, z = 7}, + {x = 32111, y = 32181, z = 7}, + {x = 32112, y = 32181, z = 7}, + {x = 32113, y = 32181, z = 7}, + {x = 32114, y = 32181, z = 7}, + {x = 32115, y = 32181, z = 7}, + {x = 32116, y = 32181, z = 7}, + {x = 32117, y = 32181, z = 7}, + {x = 32118, y = 32181, z = 7}, + {x = 32119, y = 32181, z = 7}, + {x = 32120, y = 32181, z = 7}, + {x = 32121, y = 32181, z = 7}, + {x = 32122, y = 32181, z = 7}, + {x = 32123, y = 32181, z = 7}, + {x = 32125, y = 32181, z = 7}, + {x = 32126, y = 32181, z = 7}, + {x = 32128, y = 32181, z = 7}, + {x = 32129, y = 32181, z = 7}, + {x = 32130, y = 32181, z = 7}, + {x = 32131, y = 32181, z = 7}, + {x = 32132, y = 32181, z = 7}, + {x = 32134, y = 32181, z = 7}, + {x = 32135, y = 32181, z = 7}, + {x = 32136, y = 32181, z = 7}, + {x = 32137, y = 32181, z = 7} + } + }, + -- Outer east path limit + [50323] = { + itemId = false, + itemPos = { + {x = 32096, y = 32162, z = 7}, + {x = 32096, y = 32163, z = 7}, + {x = 32096, y = 32164, z = 7}, + {x = 32096, y = 32165, z = 7}, + {x = 32096, y = 32166, z = 7}, + {x = 32096, y = 32167, z = 7}, + {x = 32096, y = 32168, z = 7}, + {x = 32096, y = 32169, z = 7}, + {x = 32096, y = 32170, z = 7}, + {x = 32096, y = 32171, z = 7}, + {x = 32096, y = 32172, z = 7}, + {x = 32096, y = 32173, z = 7}, + {x = 32096, y = 32174, z = 7} + } + }, + -- Outer north troll cave limit + [50324] = { + itemId = false, + itemPos = { + {x = 32090, y = 32143, z = 7}, + {x = 32091, y = 32143, z = 7}, + {x = 32092, y = 32143, z = 7}, + {x = 32093, y = 32143, z = 7}, + {x = 32094, y = 32143, z = 7}, + {x = 32095, y = 32143, z = 7}, + {x = 32096, y = 32143, z = 7}, + {x = 32096, y = 32144, z = 7}, + {x = 32096, y = 32145, z = 7} + } + }, + -- North-west drawbridge limit + [50325] = { + itemId = false, + itemPos = { + {x = 32070, y = 32147, z = 6}, + {x = 32070, y = 32148, z = 6} + } + }, + -- North-west drawbridge, north exit limit + [50326] = { + itemId = false, + itemPos = { + {x = 32066, y = 32136, z = 7}, + {x = 32067, y = 32136, z = 7}, + {x = 32068, y = 32136, z = 7}, + {x = 32066, y = 32137, z = 7}, + {x = 32068, y = 32137, z = 7} + } + }, + -- Spider lair entrance + [50327] = { + itemId = false, + itemPos = { + {x = 32052, y = 32110, z = 7}, + {x = 32053, y = 32110, z = 7}, + {x = 32054, y = 32110, z = 7}, + {x = 32056, y = 32110, z = 7}, + {x = 32057, y = 32110, z = 7}, + {x = 32058, y = 32110, z = 7}, + {x = 32059, y = 32110, z = 7}, + {x = 32061, y = 32110, z = 7}, + {x = 32062, y = 32110, z = 7}, + {x = 32063, y = 32110, z = 7}, + {x = 32064, y = 32110, z = 7}, + {x = 32065, y = 32110, z = 7}, + {x = 32066, y = 32110, z = 7}, + {x = 32067, y = 32110, z = 7}, + {x = 32068, y = 32110, z = 7}, + {x = 32069, y = 32110, z = 7} + } + }, + -- Spider lair 3nd floor + [50328] = { + itemId = false, + itemPos = { + {x = 32001, y = 32108, z = 11}, + {x = 32002, y = 32108, z = 11}, + {x = 32003, y = 32108, z = 11} + } + }, + -- Wolf forest path + [50329] = { + itemId = false, + itemPos = { + {x = 32107, y = 32167, z = 7}, + {x = 32107, y = 32168, z = 7}, + {x = 32107, y = 32169, z = 7}, + {x = 32107, y = 32170, z = 7} + } + }, + -- Wolf forest north limit + [50330] = { + itemId = false, + itemPos = { + {x = 32105, y = 32149, z = 7}, + {x = 32106, y = 32149, z = 7}, + {x = 32107, y = 32149, z = 7}, + {x = 32108, y = 32149, z = 7}, + {x = 32109, y = 32149, z = 7}, + {x = 32110, y = 32149, z = 7}, + {x = 32111, y = 32149, z = 7}, + {x = 32112, y = 32149, z = 7}, + {x = 32113, y = 32149, z = 7}, + {x = 32114, y = 32149, z = 7}, + {x = 32115, y = 32149, z = 7}, + {x = 32116, y = 32149, z = 7}, + {x = 32117, y = 32149, z = 7}, + {x = 32118, y = 32149, z = 7}, + {x = 32119, y = 32149, z = 7} + } + }, + -- Wolf forest north-east limit + [50331] = { + itemId = false, + itemPos = { + {x = 32120, y = 32133, z = 7}, + {x = 32120, y = 32134, z = 7}, + {x = 32120, y = 32135, z = 7}, + {x = 32120, y = 32136, z = 7}, + {x = 32120, y = 32137, z = 7}, + {x = 32120, y = 32138, z = 7}, + {x = 32120, y = 32139, z = 7}, + {x = 32120, y = 32140, z = 7}, + {x = 32120, y = 32141, z = 7}, + {x = 32120, y = 32142, z = 7}, + {x = 32120, y = 32143, z = 7}, + {x = 32120, y = 32144, z = 7}, + {x = 32120, y = 32145, z = 7}, + {x = 32120, y = 32146, z = 7}, + {x = 32120, y = 32147, z = 7} + } + }, + -- War wolf den entrance + [50332] = { + itemId = false, + itemPos = { + {x = 32134, y = 32136, z = 7}, + {x = 32136, y = 32136, z = 7}, + {x = 32138, y = 32136, z = 7}, + {x = 32139, y = 32136, z = 7}, + {x = 32140, y = 32136, z = 7}, + {x = 32141, y = 32136, z = 7}, + {x = 32142, y = 32136, z = 7}, + {x = 32143, y = 32136, z = 7}, + {x = 32144, y = 32136, z = 7} + } + }, + -- War wolf den first floor + [50333] = { + itemId = false, + itemPos = { + {x = 32133, y = 32136, z = 8}, + {x = 32134, y = 32136, z = 8}, + {x = 32135, y = 32136, z = 8}, + {x = 32133, y = 32137, z = 8}, + {x = 32135, y = 32137, z = 8}, + {x = 32133, y = 32138, z = 8}, + {x = 32134, y = 32138, z = 8}, + {x = 32135, y = 32138, z = 8} + } + }, + -- War wolf den boost floor + [50334] = { + itemId = false, + itemPos = { + {x = 32116, y = 32128, z = 11}, + {x = 32116, y = 32129, z = 11}, + {x = 32116, y = 32130, z = 11}, + {x = 32116, y = 32131, z = 11}, + {x = 32116, y = 32132, z = 11}, + {x = 32116, y = 32133, z = 11}, + {x = 32116, y = 32134, z = 11} + } + }, + -- Academy entrance + [50335] = { + itemId = 724, + itemPos = { + {x = 32096, y = 32200, z = 7}, + {x = 32097, y = 32200, z = 7}, + {x = 32098, y = 32200, z = 7} + } + }, + -- Academy low floor downstairs + [50336] = { + itemId = 414, + itemPos = {{x = 32096, y = 32191, z = 8}} + }, + -- Academy library vault entrance + [50337] = { + itemId = 9146, + itemPos = { + {x = 32089, y = 32157, z = 9}, + {x = 32090, y = 32157, z = 9}, + {x = 32091, y = 32157, z = 9} + } + }, + -- Library vault downstairs + [50338] = { + itemId = 414, + itemPos = {{x = 32089, y = 32154, z = 10}} + }, + -- Library vault room floor + [50339] = { + itemId = 414, + itemPos = { + {x = 32085, y = 32139, z = 10}, + {x = 32086, y = 32139, z = 10}, + {x = 32087, y = 32139, z = 10}, + {x = 32088, y = 32139, z = 10}, + {x = 32089, y = 32139, z = 10}, + {x = 32090, y = 32139, z = 10}, + {x = 32091, y = 32139, z = 10}, + {x = 32085, y = 32140, z = 10}, + {x = 32086, y = 32140, z = 10}, + {x = 32087, y = 32140, z = 10}, + {x = 32088, y = 32140, z = 10}, + {x = 32089, y = 32140, z = 10}, + {x = 32090, y = 32140, z = 10}, + {x = 32091, y = 32140, z = 10}, + {x = 32084, y = 32141, z = 10}, + {x = 32085, y = 32141, z = 10}, + {x = 32086, y = 32141, z = 10}, + {x = 32087, y = 32141, z = 10}, + {x = 32088, y = 32141, z = 10}, + {x = 32089, y = 32141, z = 10}, + {x = 32091, y = 32141, z = 10}, + {x = 32092, y = 32141, z = 10}, + {x = 32082, y = 32142, z = 10}, + {x = 32083, y = 32142, z = 10}, + {x = 32084, y = 32142, z = 10}, + {x = 32092, y = 32142, z = 10}, + {x = 32093, y = 32142, z = 10}, + {x = 32094, y = 32142, z = 10}, + {x = 32080, y = 32143, z = 10}, + {x = 32081, y = 32143, z = 10}, + {x = 32084, y = 32143, z = 10}, + {x = 32085, y = 32143, z = 10}, + {x = 32086, y = 32143, z = 10}, + {x = 32087, y = 32143, z = 10}, + {x = 32088, y = 32143, z = 10}, + {x = 32089, y = 32143, z = 10}, + {x = 32090, y = 32143, z = 10}, + {x = 32091, y = 32143, z = 10}, + {x = 32092, y = 32143, z = 10}, + {x = 32093, y = 32143, z = 10}, + {x = 32094, y = 32143, z = 10}, + {x = 32095, y = 32143, z = 10}, + {x = 32096, y = 32143, z = 10}, + {x = 32080, y = 32144, z = 10}, + {x = 32081, y = 32144, z = 10}, + {x = 32082, y = 32144, z = 10}, + {x = 32083, y = 32144, z = 10}, + {x = 32084, y = 32144, z = 10}, + {x = 32085, y = 32144, z = 10}, + {x = 32090, y = 32144, z = 10}, + {x = 32091, y = 32144, z = 10}, + {x = 32092, y = 32144, z = 10}, + {x = 32093, y = 32144, z = 10}, + {x = 32094, y = 32144, z = 10}, + {x = 32095, y = 32144, z = 10}, + {x = 32096, y = 32144, z = 10}, + {x = 32090, y = 32145, z = 10}, + {x = 32091, y = 32145, z = 10}, + {x = 32080, y = 32146, z = 10}, + {x = 32081, y = 32146, z = 10}, + {x = 32082, y = 32146, z = 10}, + {x = 32083, y = 32146, z = 10}, + {x = 32084, y = 32146, z = 10}, + {x = 32085, y = 32146, z = 10}, + {x = 32086, y = 32146, z = 10}, + {x = 32087, y = 32146, z = 10}, + {x = 32088, y = 32146, z = 10}, + {x = 32089, y = 32146, z = 10}, + {x = 32090, y = 32146, z = 10}, + {x = 32091, y = 32146, z = 10}, + {x = 32092, y = 32146, z = 10}, + {x = 32093, y = 32146, z = 10}, + {x = 32094, y = 32146, z = 10}, + {x = 32095, y = 32146, z = 10}, + {x = 32096, y = 32146, z = 10}, + {x = 32081, y = 32147, z = 10}, + {x = 32082, y = 32147, z = 10}, + {x = 32083, y = 32147, z = 10}, + {x = 32084, y = 32147, z = 10}, + {x = 32085, y = 32147, z = 10}, + {x = 32086, y = 32147, z = 10}, + {x = 32087, y = 32147, z = 10}, + {x = 32088, y = 32147, z = 10}, + {x = 32089, y = 32147, z = 10}, + {x = 32090, y = 32147, z = 10}, + {x = 32091, y = 32147, z = 10}, + {x = 32092, y = 32147, z = 10}, + {x = 32093, y = 32147, z = 10}, + {x = 32094, y = 32147, z = 10}, + {x = 32095, y = 32147, z = 10}, + {x = 32096, y = 32147, z = 10}, + {x = 32081, y = 32148, z = 10}, + {x = 32082, y = 32148, z = 10}, + {x = 32083, y = 32148, z = 10}, + {x = 32084, y = 32148, z = 10}, + {x = 32092, y = 32148, z = 10}, + {x = 32093, y = 32148, z = 10}, + {x = 32094, y = 32148, z = 10}, + {x = 32095, y = 32148, z = 10}, + {x = 32096, y = 32148, z = 10}, + {x = 32083, y = 32149, z = 10}, + {x = 32084, y = 32149, z = 10}, + {x = 32085, y = 32149, z = 10}, + {x = 32086, y = 32149, z = 10}, + {x = 32087, y = 32149, z = 10}, + {x = 32088, y = 32149, z = 10}, + {x = 32089, y = 32149, z = 10}, + {x = 32090, y = 32149, z = 10}, + {x = 32091, y = 32149, z = 10}, + {x = 32092, y = 32149, z = 10}, + {x = 32093, y = 32149, z = 10}, + {x = 32085, y = 32150, z = 10}, + {x = 32086, y = 32150, z = 10}, + {x = 32087, y = 32150, z = 10}, + {x = 32088, y = 32150, z = 10}, + {x = 32089, y = 32150, z = 10}, + {x = 32090, y = 32150, z = 10}, + {x = 32091, y = 32150, z = 10}, + {x = 32087, y = 32151, z = 10}, + {x = 32088, y = 32151, z = 10}, + {x = 32089, y = 32151, z = 10}, + {x = 32090, y = 32151, z = 10}, + {x = 32091, y = 32151, z = 10}, + {x = 32087, y = 32152, z = 10}, + {x = 32088, y = 32152, z = 10}, + {x = 32089, y = 32152, z = 10}, + {x = 32090, y = 32152, z = 10}, + {x = 32091, y = 32152, z = 10}, + {x = 32086, y = 32153, z = 10}, + {x = 32087, y = 32153, z = 10}, + {x = 32088, y = 32153, z = 10}, + {x = 32090, y = 32153, z = 10}, + {x = 32091, y = 32153, z = 10}, + {x = 32086, y = 32154, z = 10}, + {x = 32087, y = 32154, z = 10}, + {x = 32088, y = 32154, z = 10}, + {x = 32090, y = 32154, z = 10}, + {x = 32091, y = 32154, z = 10} + } + }, + -- Academy library vault center + [50340] = { + itemId = 414, + itemPos = { + {x = 32085, y = 32145, z = 10}, + {x = 32090, y = 32145, z = 10}, + {x = 32091, y = 32145, z = 10} + } + }, + -- Academy library vault near rune + [50341] = { + itemId = 420, + itemPos = {{x = 32083, y = 32143, z = 10}} + }, + -- North-west drawbridge upstairs + [50342] = { + itemId = 9043, + itemPos = {{x = 32088, y = 32147, z = 6}} + }, + -- Troll caves entrance + [50343] = { + itemId = false, + itemPos = { + {x = 32094, y= 32140, z = 7}, + {x = 32095, y= 32140, z = 7}, + {x = 32096, y= 32140, z = 7}, + {x = 32097, y= 32140, z = 7}, + {x = 32098, y= 32140, z = 7}, + {x = 32099, y= 32140, z = 7} + } + }, + -- Troll caves dug tunnel downstair + [50344] = { + itemId = 9022, + itemPos = {{x = 32059, y = 32135, z = 10}} + }, + -- Troll caves dug tunnel upstair + [50345] = { + itemId = 9023, + itemPos = {{x = 32059, y = 32136, z = 9}} + }, + -- Outer east limit + [50346] = { + itemId = false, + itemPos = { + {x = 32128, y = 32174, z = 7}, + {x = 32128, y = 32176, z = 7}, + {x = 32128, y = 32177, z = 7}, + {x = 32128, y = 32178, z = 7}, + {x = 32128, y = 32179, z = 7}, + {x = 32128, y = 32180, z = 7}, + {x = 32128, y = 32181, z = 7}, + {x = 32128, y = 32184, z = 7}, + {x = 32128, y = 32185, z = 7}, + {x = 32128, y = 32186, z = 7}, + {x = 32128, y = 32187, z = 7}, + {x = 32128, y = 32188, z = 7}, + {x = 32128, y = 32189, z = 7}, + {x = 32128, y = 32191, z = 7}, + {x = 32128, y = 32193, z = 7}, + {x = 32128, y = 32194, z = 7}, + {x = 32128, y = 32196, z = 7}, + {x = 32128, y = 32197, z = 7}, + {x = 32128, y = 32198, z = 7}, + {x = 32129, y = 32198, z = 7} + } + }, + -- Unholy crypt entrance + [50347] = { + itemId = false, + itemPos = { + {x = 32129, y = 32201, z = 7}, + {x = 32129, y = 32202, z = 7}, + {x = 32131, y = 32204, z = 7}, + {x = 32132, y = 32204, z = 7} + } + }, + -- Unholy crypt door entrance + [50348] = { + itemId = 3152, + itemPos = { + {x = 32146, y = 32187, z = 9}, + {x = 32147, y = 32187, z = 9} + } + }, + -- Unholy crypt near sarcophagus + [50349] = { + itemId = false, + itemPos = { + {x = 32140, y = 32202, z = 10}, + {x = 32140, y = 32203, z = 10} + } + }, + -- Near north-west drawbridge + [50350] = { + itemId = false, + itemPos = { + {x = 32091, y = 32147, z = 7}, + {x = 32092, y = 32147, z = 7}, + {x = 32093, y = 32147, z = 7}, + {x = 32094, y = 32147, z = 7} + } + }, + -- North-west drawbridge south downstairs + [50351] = { + itemId = 9043, + itemPos = {{x = 32065, y = 32156, z = 7}} + }, + -- Orc land entrance + [50352] = { + itemId = false, + itemPos = { + {x = 32002, y = 32152, z = 7}, + {x = 32003, y = 32152, z = 7}, + {x = 32004, y = 32152, z = 7}, + {x = 32005, y = 32152, z = 7} + } + }, + -- Wasp lair entrance + [50353] = { + itemId = 9025, + itemPos = { + {x = 31999, y = 32142, z = 7}, + {x = 32000, y = 32142, z = 7} + } + }, + -- Academy downfloor trasure door entrance + [50354] = { + itemId = 414, + itemPos = { + {x = 32108, y = 32190, z = 8}, + {x = 32109, y = 32190, z = 8}, + {x = 32110, y = 32190, z = 8} + } + }, + -- Orc fortress peeing area + [50355] = { + itemId = 194, + itemPos = { + {x = 31968, y = 32148, z = 7}, + {x = 31969, y = 32148, z = 7} + } + }, + -- Orc fortress entrance + [50356] = { + itemId = 194, + itemPos = { + {x = 31986, y = 32158, z = 7}, + {x = 31986, y = 32159, z = 7} + } + }, + -- Orc fortress near elite orc guard + [50357] = { + itemId = 194, + itemPos = { + {x = 31976, y = 32151, z = 7}, + {x = 31978, y = 32151, z = 7}, + {x = 31976, y = 32152, z = 7}, + {x = 31978, y = 32152, z = 7}, + {x = 31972, y = 32152, z = 7}, + {x = 31973, y = 32152, z = 7}, + {x = 31974, y = 32152, z = 7}, + {x = 31975, y = 32152, z = 7}, + {x = 31976, y = 32152, z = 7}, + {x = 31978, y = 32152, z = 7}, + {x = 31979, y = 32152, z = 7}, + {x = 31980, y = 32152, z = 7}, + {x = 31981, y = 32152, z = 7}, + {x = 31982, y = 32152, z = 7} + } + }, + -- Orc fortress in front elite orc guard + [50358] = { + itemId = 194, + itemPos = { + {x = 31977, y = 32151, z = 7}, + {x = 31977, y = 32152, z = 7} + } + }, + -- Orc fortress interior + [50359] = { + itemId = 9023, + itemPos = {{x = 31977, y = 32149, z = 8}} + }, + -- Orc fortress interior kitchen + [50360] = { + itemId = false, + itemPos = { + {x = 31981, y = 32157, z = 8}, + {x = 31981, y = 32158, z = 8}, + {x = 31981, y = 32159, z = 8}, + {x = 31981, y = 32160, z = 8}, + {x = 31982, y = 32160, z = 8}, + {x = 31983, y = 32160, z = 8}, + {x = 31984, y = 32160, z = 8}, + {x = 31985, y = 32160, z = 8}, + {x = 31986, y = 32160, z = 8}, + {x = 31987, y = 32160, z = 8}, + {x = 31988, y = 32160, z = 8} + } + }, + -- Orc fortress interior south path + [50361] = { + itemId = false, + itemPos = { + {x = 31978, y = 32173, z = 8}, + {x = 31979, y = 32173, z = 8} + } + }, + -- Orc fortress interior near south downstair + [50362] = { + itemId = 9021, + itemPos = { + {x = 31978, y = 32178, z = 8}, + {x = 31979, y = 32178, z = 8} + } + }, + -- Kraknaknork lair near room teleport + [50363] = { + itemId = false, + itemPos = { + {x = 31951, y = 32173, z = 10}, + {x = 31951, y = 32174, z = 10} + } + } +} + +TileUnique = { + -- Lions rock tiles + -- data\scripts\movements\quests\lions_rock\lionsrock.lua + -- snake sign + [25001] = { + itemId = 3152, + itemPos = {x = 33095, y = 32244, z = 9} + }, + -- lizard sign + [25002] = { + itemId = 3152, + itemPos = {x = 33128, y = 32300, z = 9} + }, + -- scorpion sign + [25003] = { + itemId = 3152, + itemPos = {x = 33109, y = 32329, z = 9} + }, + -- hyena sign + [25004] = { + itemId = 3152, + itemPos = {x = 33127, y = 32340, z = 9} + }, + -- Lions rock quest (gems tile) scripts/actions/other/gems + [25006] = { + itemId = 23812, + itemPos = {x = 33069, y = 32298, z = 9} + }, + [25007] = { + itemId = 23813, + itemPos = {x = 33069, y = 32302, z = 9} + }, + [25008] = { + itemId = 23811, + itemPos = {x = 33077, y = 32302, z = 9} + }, + [25009] = { + itemId = 23808, + itemPos = {x = 33077, y = 32298, z = 9} + }, + [25010] = { + itemId = 426, + itemPos = {x = 32225, y = 32268, z = 9} + }, + -- The paradox tower quest + [25011] = { + itemId = 9024, + itemPos = {x = 32497, y = 31889, z = 7} + }, + [25012] = { + itemId = 11062, + itemPos = {x = 32566, y = 31957, z = 1} + }, + [25013] = { + itemId = 426, + itemPos = {x = 32481, y = 31905, z = 7} + }, + [25014] = { + itemId = 9023, + itemPos = {x = 32478, y = 31908, z = 7} + }, + [25015] = { + itemId = 9023, + itemPos = {x = 32479, y = 31908, z = 7} + }, + [25016] = { + itemId = 1945, + itemPos = {x = 32479, y = 31905, z = 6} + }, + [25017] = { + itemId = 426, + itemPos = {x = 32476, y = 31900, z = 5} + }, + -- Explorer Society Astral Portals + -- Path: data\scripts\actions\quests\explorer_society\stone.lua + -- Path: data\scripts\movements\quests\explorer_society\carvingteleport_port_hope.lua + -- Path: data\scripts\movements\quests\explorer_society\carving_teleport_liberty_bay.lua + -- Port Hope + [25018] = { + itemId = 474, + itemPos = {x = 32665, y = 32736, z = 6} + }, + -- Northport + [25019] = { + itemId = 474, + itemPos = {x = 32497, y = 31622, z = 6} + }, + -- Liberty Bay + [25020] = { + itemId = 474, + itemPos = {x = 32358, y = 32807, z = 6} + }, + -- Svarground + [25021] = { + itemId = 474, + itemPos = {x = 32321, y = 31137, z = 6} + }, + -- The Rookie Guard Quest - Mission 05: Web of Terror + -- Path: data\scripts\actions\quests\the_rookie_guard\mission05_web_terror.lua + -- Spider lair entrance hole + [25022] = { + itemId = 13869, + itemPos = {x = 32051, y = 32110, z = 7} + }, + -- Spider queen chamber hole + [25023] = { + itemId = 13869, + itemPos = {x = 32018, y = 32098, z = 11} + }, + -- The Rookie Guard Quest - Mission 06: Run Like a Wolf + -- Path: data\scripts\actions\quests\the_rookie_guard\mission06_run_like_wolf.lua + -- War wolf den entrance hole + [25024] = { + itemId = 13869, + itemPos = {x = 32138, y = 32132, z = 7} + }, + -- War wolf den fall tile + [25025] = { + itemId = 9023, + itemPos = {x = 32138, y = 32132, z = 8} + }, + -- War wolf den last floor fall tile + [25026] = { + itemId = 9024, + itemPos = {x = 32106, y = 32130, z = 11} + }, + -- War wolf den last floor ramp tile + [25027] = { + itemId = 8372, + itemPos = {x = 32147, y = 32125, z = 11} + }, + -- The Rookie Guard Quest - Mission 09: Rock 'n Troll + -- Path: data\scripts\actions\quests\the_rookie_guard\mission09_rock_troll.lua + -- Troll caves dug tunnel hole + [25028] = { + itemId = 13869, + itemPos = {x = 32059, y = 32135, z = 9} + }, + -- Remove/create item on stepIn + -- Reserved uniques range from 29001/30000 + + -- Ornamented shield quest + [29001] = { + itemId = 9023, + itemPos = {x = 32770, y = 32282, z = 10}, + targetPos = {x = 32771, y = 32297, z = 10}, + targetItem = 387 + }, + -- Draconia quest + [29002] = { + itemId = 426, + itemPos = {x = 32810, y = 31595, z = 5}, + targetPos = {x = 32796, y = 31594, z = 5}, + targetItem = 1025 + }, + [29003] = { + itemId = 426, + itemPos = {x = 32794, y = 31595, z = 5}, + targetPos = {x = 32796, y = 31576, z = 5}, + targetItem = 1025 + } +} diff --git a/data/startup/tables/tile_pick.lua b/data/startup/tables/tile_pick.lua new file mode 100644 index 00000000000..ab41739058a --- /dev/null +++ b/data/startup/tables/tile_pick.lua @@ -0,0 +1,19 @@ +-- Look README.md for see the reserved action/unique numbers +-- It is for the pickable tiles (on use pick) + +TilePickAction = { + -- Pickable tiles, add new position and it create in-game + [101] = { + itemId = false, + itemPos = { + {x = 32774, y = 32289, z = 10}, + {x = 33094, y = 31626, z = 13}, + {x = 33081, y = 31651, z = 11}, + {x = 32266, y = 31892, z = 12}, + {x = 32266, y = 31916, z = 12}, + {x = 32204, y = 31887, z = 14}, + {x = 32165, y = 31890, z = 14}, + {x = 32162, y = 31921, z = 13} + } + } +} diff --git a/data/startup/tables/writeable.lua b/data/startup/tables/writeable.lua new file mode 100644 index 00000000000..30eb027ff07 --- /dev/null +++ b/data/startup/tables/writeable.lua @@ -0,0 +1,853 @@ +-- Guidelines for BookDocumentTable: +-- containerId: id of the container item (bookcase, shelf, corpse, etc). Optional. +-- itemId: id of item (book, scroll, letter, etc). +-- position: position of the container or of the item (depending on if the item is on a container or not). +-- text: text of item (book, scroll, letter, etc). +BookDocumentTable = { + [1] = { + containerId = 1718, + itemId = 1962, + position = {x = 32063, y = 31884, z = 4}, + text = [[ +MONSTERS AND FOES OF DAWNPORT I + +Intelligent monsters + +The troll - Though intelligent in a limited way, usually trolls do not pose a major threat to our outpost, though they are scouting the outskirts of our grounds and attack passersby. They are able to create and use some basic equipment, and are tough to lesser weapons and unskilled fighters. + +The orc - The green-skinned orc is intelligent and able to use weapons and armor. They are warriors of some power and very dangerous in greater numbers. Luckily enough, there are not many of their more skilled fighters around, like the berserker or warrior. Still, a handful of them is enough to get an adventurer into dire straits. + +The goblin - sneaky and devious, goblins steal everything that is not nailed down. Though small and relatively easy to fight, they don't shirk from attacking humans when they feel superior in numbers. They normally stay in their hideouts underground, where they hoard their loot. + +The minotaur - a dreaded beast and fearsome fighter, the minotaur is a formidable foe for a young adventurer. Particular caution should be exercised when going to their lair underground, as they have some skilled archers and even some mages that may kill you very, very quickly. + +Other beasts - It is certain that other beasts live in the dungeons of our isle. But they are not numerous enough to be recognised yet. If you encounter any unknown beast it is certainly dangerous and a potential lethal enemy. Don't underestimate them. + ]] + }, + [2] = { + containerId = 1718, + itemId = 1962, + position = {x = 32063, y = 31884, z = 4}, + text = [[ +MONSTERS AND FOES OF DAWNPORT II + +Underground and undead beasts + +The rotworm - A creature of decay that lives underground like its small cousin, the earthworm. Its toothed maw is a formidable weapon, and rotworms have torn more than one adventurer to pieces. A horde of them could kill anyone, so great caution is advised when encountering them. + +The carrion worm - They seem to be no species of their own but indeed just older, bigger and meaner rotworms. They are usually accompanied by a host of smaller worms which makes them even more dangerous. Carrion worms have some sort of tusks that can easily penetrate a good armor. + +The skeletons - Skeletons are living undead, rumoured to be the bodies of dead adventurers which have been revived by some evil power. Cropping up in packs and occasionally accompanied by other undead creatures like ghouls or mummies, they are quite nasty opponents, particularly because they are able to drain the life energy of their opponents. + +The bat - Often encountered in caves and ruins, along with other creatures, sometimes undead. Being little stronger than a rat, bats are rather a nuisance than a threat to an experienced adventurer. Their attacks on humans mainly happen out of self-defence. Bats often form a large swarm which is slightly more dangerous to face than a single specimen. Bats can be found almost everywhere as long as there is some close-by dark place where they can breed and sleep. + +The rat - Whether humans brought this pest with them on the isle or whether rats are indigenous to every dark place in Tibia is anyone's guess. However, rats on Dawnport normally prefer to live underground and are mostly harmless, tending to destroy food supplies in cellars. They can become dangerous in greater numbers, though, to any badly equipped adventurer they corner. + ]] + }, + [3] = { + containerId = 1718, + itemId = 1962, + position = {x = 32063, y = 31884, z = 4}, + text = [[ +MONSTERS AND FOES OF DAWNPORT III + +Poisonous beasts + +The salamander - A common creature of the swamp and warm earth of the marshes, the salamander relies on stealth and a little poison to ward off attackers. Normally living on a diet of insects, it seems that here on Dawnport some salamanders have developed a taste for the rare dawnfire herb. Those salamanders have often been sighted in the company of trolls and it is supposed that the trolls keep them as a sort of pet, though to what reason, nobody knows yet. Though relatively harmless, the poison of the troll-trained salamanders is not to be underestimated and can seriously injure or kill inexperienced adventurers. + +The wasp - fast and deadly to the inexperienced, wasps will follow their enemy for quite a while, and their speed makes them dangerous, even more so in high numbers. Their sting hurts and can poison you, so make sure to finish a wasp off quickly when you encounter it. They can be found in warm areas such as woodlands, jungles or deserts; and if there is a heat source, in underground stone caves. + +The poison spider - Though only slightly tougher than an ordinary spider, this one can poison you. Try to avoid being bitten by one, as they usually live far from our base and you might not make it to our local healer in time. + ]] + }, + [4] = { + containerId = 1719, + itemId = 1962, + position = {x = 32064, y = 31884, z = 4}, + text = [[ +MONSTERS AND FOES OF DAWNPORT IV + +Creatures of the meadows and marshes + +The dawnfly - A close relative of the emerald damselfly found in the swamps of Venore, it is supposed the creature may have found its way over the seas to Dawnport and adapted to the isle. Like the damselfly, their diet consists of plant matter and smaller insects though they too attack passersby, supposedly to guard their territory. Their bite is slightly poisonous, but poses a threat only to the wounded or completely unprepared wanderer. + +The woodling - The woodlings could be the missing link between the swamplings and the haunted treelings. Half plant and half animal and at least partially intelligent, treelings love to ambush their prey and make use of the surroundings to drive it into a corner. Looking deceptively tree-like, a woodling will make a grab at any human that passes; supposedly to spice up its diet of rotting leaves and plants with something more juicy. Woodlings can slow down their enemies and are quite tough, which is why any inexperienced adventurer would do well to know the way back to the outpost in a hurry if venturing down to the woody plains. + +The Meadow strider - A giant bird that stalks the marshes and meadows, the meadow strider usually feeds on small insects and amphibians. Being very territorial but short-sighted, it will attack any supposed rival of its own size, which includes humans, and peck at them. Though they are nearly as tough as woodlings, there's good eating on a meadow strider, and they often contain swallowed gold coins and other useful stuff. + ]] + }, + [5] = { + containerId = 1719, + itemId = 1962, + position = {x = 32064, y = 31884, z = 4}, + text = [[ +MONSTERS AND FOES OF DAWNPORT V + +Creatures of the woods + +The wolf - There are some loner wolves roaming this isle. Wolves are fast, tough and dangerous. Often they are the hunters and not the hunted. It is a good decision to engage them in combat only with decent equipment and to fight a wolf one on one. If there's nothing else, you can always eat a hunch of wolf, and sell its fur. + +The bear - Bears are hard to beat! Keep that in mind before challenging one. If you are inexperienced and don't have good equipment, retreat is the tactic of choice. Best kill bears in small hunting parties and use terrain to your advantage. + +The deer - Deers are a fine supply for food and are non-agressive animals and try to flee on sight. It might be difficult to catch them and you might easily enter the territory of a local predator while chasing them. + +The hare - Like deers, hares will flee upon sight and are an excellent source of food for any passing adventurer. They are a common sight in the meadows and forests of Tibia, though larger predators are never very far. + +The squirrel - Swift and impish, squirrels will run from any human they see. Hunters avoid preying on squirrels, as there is a legend that says that the giant immortal Squirrels who ate nuts from Crunor's blessed tree take bloody revenge on each and every killer of their descendants. Squirrels are found in woody areas all over Tibia. +]] + }, + --The isle of the kings (need position) + [6] = { + containerId = 1720, + itemId = 1955, + --position = {x = xxxxx, y = xxxxx, z = x}, + text = [[ +Kazordoon, the hidden city +In the blocklike Mountain, known as the big old one, the hidden city of kazordoon is nestled. Its the last refuge of the ancient race of dwarves. Hidden and heavily fortified it was the last stand of dwarvenhood in the wars of creation and the last hope of that race to adapt to and survive the new ages. The famous giant statue, known as colossus guards its entry, alhough the narrow valley makes it difficult to see that fortress-statue and admire its beauty. Kazordoon is known for its safety and masterful smithery throughout the lands. +Since some generations the dwarven city (whose ruler claims a title that might be translated as 'emperor') is allied with the thaian kingdom. +]] + }, + [7] = { + containerId = 1720, + itemId = 1959, + position = {x = 32065, y = 31884, z = 4}, + text = [[ +Kazordoon, the hidden city +In the blocklike Mountain, known as the big old one, the hidden city of kazordoon is nestled. Its the last refuge of the ancient race of dwarves. Hidden and heavily fortified it was the last stand of dwarvenhood in the wars of creation and the last hope of that race to adapt to and survive the new ages. The famous giant statue, known as colossus guards its entry, alhough the narrow valley makes it difficult to see that fortress-statue and admire its beauty. Kazordoon is known for its safety and masterful smithery throughout the lands. +Since some generations the dwarven city (whose ruler claims a title that might be translated as 'emperor') is allied with the thaian kingdom. + ]] + }, + [8] = { + containerId = 1720, + itemId = 1965, + position = {x = 32066, y = 31884, z = 4}, + text = [[ +Genesis I. The Awakening of the Gods + +In the beginning there was only a big, gaping void. It was everywhere and nowhere. + +In this emptiness two powerful entities appeared who were eventually known as the elder gods: Fardos the Creator and Uman Zathroth who combined in himself two unequal halves. One of these halves was Uman the Wise, a benign god who was gifted with divine intellect, while Zathroth the Destroyer was the other, darker half. These were the two halves of one single enigmatical entity, and even though either of them was perfectly capable of acting on his own just as if he had been fully independent, independent they were not. They were bound together by an eternal bond that could not be broken, and their destiny was one. + +Nobody knows where the elder gods came from, or whether they had always existed and eventually awoke from the slumber of infinity. But somewhere along the way they decided to create a universe. Surely Fardos was the initiator, for he was driven by the need to create and give life. He was overflowing with creative power and impatient to release it, so he stepped into existence and began to unleash his powers. However, none of his attempts to create were successful. All of his creations were swallowed by the void before they were completed, and none survived. + +Uman Zathroth regarded Fardos's undertakings thoughtfully. Uman was sagacious and held awesome magical powers. Most importantly, however, he was driven by an insatiable hunger for knowledge and enlightenment. In his essence he resembled Fardos, but where Fardos worked openly and logically, Uman's domain was the realm of mystery. Still, he shared Fardos's interest in creation, whereas his dark half Zathroth was essentially corruptive. Zathroth was a vain god who was painfully aware that his own creative powers were poor. Because of this he looked at Fardos's work of creation with jealousy, and from the very beginning he was determined to prevent or at least corrupt it in any way he could. Fardos, who did not suspect this, asked him for assistance because he had accepted the fact that he could not achieve creation on his own, but of course Zathroth denied. Uman, however, agreed to help. And from that he and Fardos worked together on the great project that was creation. + + +Unfortunately, their combined efforts were hardly more successful. Just like before, everything Fardos and Uman created was swallowed by the void as soon as it came into existence, and the two gods sadly saw their creation run through their fingers like water through a sieve. On the other hand, Zathroth, who had been watching their efforts with suspicion, rejoiced. He ridiculed their efforts. However, his glee changed into surprise and anger when he found that something strange happened, something which perhaps Uman and Fardos did not expect themselves. To this day, nobody knows precisely what it was that caused it. Perhaps the power that had been spent lured another entity out of the void, or it might be that it simply awoke another divine entity from its slumber. Some even claim that in some mysterious way the power that had been spent by Uman and Fardos actually created a new entity. Whatever the truth may be, a new goddess stepped out of the void like a new-born mermaid from her shell. The amazed elder gods watched her divine beauty in awed admiration, for everything in her was perfect harmony. They agreed to call her Tibiasula. Zathroth, however, stood by and fumed with silent hate. But cunning as he was, he hid his resentment well and feigned to share the joy of the other elder gods. + ]] + }, + [9] = { + containerId = 1720, + itemId = 1965, + position = {x = 32066, y = 31884, z = 4}, + text = [[ +Genesis IV. The First Creatures + +Zathroth watched the progress of creation with wrath and disgust. If he had had his way, he would have obliterated creation then and there. However, he knew that he lacked the power to do that, especially since Fardos and Uman were now well aware of his intentions and watched him carefully. He would have to resort to other means to bring ruin to creation. It was for this reason that he watched the concept of life with great interest, because he foresaw quite clearly that a lot of mischief could be done with it. Much as he loathed most of the gods that had been created, there was one who had caught his attention. Fafnar's base instincts and her destructive powers did not fail to impress him, and so a plan came to his mind. He flattered her with compliments and before long he succeeded in seducing her. Thus Brog the Raging Titan was conceived. An exceedingly ugly abomination that had only one eye in its huge head, Brog had inherited little of his father's cunning and none of his caution, yet he was strong and fierce, and his mother's furious heat burned wildly inside him. + +As he grew up, Brog was pained by the fire burning inside him, until one day when it grew unbearable he summoned all his magical powers and released as much of the painful flame into the world as he could. The searing fire mixed with his rage, and from it rose Garsharak, the very first dragon, who later sired a whole race of intelligent, giant lizards, a race that would eventually bring terror and chaos into Tibia. Brog watched the terrible creature he had created rather accidentally, and he rejoiced when he saw just how fierce and powerful it was. Though he was rather stupid he, too, had the gift to create life, which in an act of vanity he next used to create the cyclopes in his own image. + + +Zathroth watched Brog's experiments with great interest. So far he had not held his son in high esteem, but here was something for which he himself admittedly had little talent for. Since he did not understand the laws of life himself he knew that Brog's gift could prove to be a great asset. He called his son to him and told him to go on with his experiments, urging him to create something more terrifying and destructive than cyclopes. Even though these giants were ferocious and strong, they were not quite as destructive as he wanted them to be. In fact, due to their love of mining and smithing the cyclopes were a creative rather than a destructive race. Worse, they were not propagating fast enough to make them a real threat to creation. For this reason Brog went on to create trolls and goblins, races that were weaker than the cyclopes, but propagated much faster. However, his undisputed masterpiece were the orcs, a race of fearsome, single-minded warriors who lived only to expand and conquer. Soon they had spread all over Tibia, and they were the scourge of all that was alive. + ]] + }, + [10] = { + containerId = 1718, + itemId = 1955, + --position = (isle of the kings), + text = [[ +The Minotaurs by Iregarn Pt. 1 +The minotaurs claimed that they were once the marshals and favoured people of Blog, the raging one. In the wars over creation they were one of the most successful races. But as the war grew more and more fierce it were the wild and raging minotaurs that had to pay the worst blood toll. The berserker rage inherent to their race made them a formidable opponent but also very vulnerable. +Though victorious in most battles, in the end the berserking warriors had to surrender to their wounds or were left crippled and executed and fed to Blogs lesser followers. Even worse, the raging minotaurs knew neither friend nor enemy. Brother slew brother, fathers slaughtered their sons in their rage. Then, one day a minotaur, named Tha'kull conquered his rage. He withdrew from battle and became a hermit. In his travels he met Akkor, the blind one. This minotaur was by fate not subjected to the rage inherent to the minotauren race and had aquired a tranquility and wisdom, unknown to his kind so far. Tha'Kull thaught the blind one how to improve his body and fortitude and Akkor in return teached the warrior how to improve his soul. +He looked upon the world and for the first time in aeons a minotaurean warrior saw the world without hatred. He saw the beauty in things, simple and complex. He saw the harmony in creation and the place the living had in it. He also saw the place that was meant to be taken by the sentient beings among the living. And he went back to his people to teach. Never a warrior of the minotaurs had neglected his rage and even though he was cautious the angry berserker warlords would not allow the words he spoke to be heard by their people. +]] + }, + [11] = { + containerId = 1718, + itemId = 1959, + position = {x = 32061, y = 31889, z = 4}, + text = [[ +The Minotaurs by Iregarn Pt. 1 +The minotaurs claimed that they were once the marshals and favoured people of Blog, the raging one. In the wars over creation they were one of the most successful races. But as the war grew more and more fierce it were the wild and raging minotaurs that had to pay the worst blood toll. The berserker rage inherent to their race made them a formidable opponent but also very vulnerable. +Though victorious in most battles, in the end the berserking warriors had to surrender to their wounds or were left crippled and executed and fed to Blogs lesser followers. Even worse, the raging minotaurs knew neither friend nor enemy. Brother slew brother, fathers slaughtered their sons in their rage. Then, one day a minotaur, named Tha'kull conquered his rage. He withdrew from battle and became a hermit. In his travels he met Akkor, the blind one. This minotaur was by fate not subjected to the rage inherent to the minotauren race and had aquired a tranquility and wisdom, unknown to his kind so far. Tha'Kull thaught the blind one how to improve his body and fortitude and Akkor in return teached the warrior how to improve his soul. +He looked upon the world and for the first time in aeons a minotaurean warrior saw the world without hatred. He saw the beauty in things, simple and complex. He saw the harmony in creation and the place the living had in it. He also saw the place that was meant to be taken by the sentient beings among the living. And he went back to his people to teach. Never a warrior of the minotaurs had neglected his rage and even though he was cautious the angry berserker warlords would not allow the words he spoke to be heard by their people. +]] + }, + [12] = { + containerId = 1720, + itemId = 1950, + --position = (Rookgaard Academy), + text = [[ +Orcs ARE intelligent. Though some dwarves mumble about a shared hivemind of the greenskins, there is no evidence for that. Orcs have speech and are capable to learn other humanoids language quite well ... if they want, what almost never is the case. They lack a written language though. Some of the more educated orcs use human letters to write down orcish texts. Its rumored that the orcs we encounter now and then are just barbarians of their own kind and that there is a more 'civilized' orcish culture somewhere. There are some clues that the orcs indeed had a written language, but the modern orcs is unable to read it as we are. +]] + }, + [13] = { + containerId = 1720, + itemId = 1981, + position = {x = 32062, y = 31889, z = 4}, + text = [[ +Orcs ARE intelligent. Though some dwarves mumble about a shared hivemind of the greenskins, there is no evidence for that. Orcs have speech and are capable to learn other humanoids language quite well ... if they want, what almost never is the case. They lack a written language though. Some of the more educated orcs use human letters to write down orcish texts. Its rumored that the orcs we encounter now and then are just barbarians of their own kind and that there is a more 'civilized' orcish culture somewhere. There are some clues that the orcs indeed had a written language, but the modern orcs is unable to read it as we are. + ]] + }, + [14] = { + containerId = 1718, + itemId = 1964, + position = {x = 32068, y = 31889, z = 4}, + text = [[ +There are two kinds of spells: rune spells and spontaneous spells. Rune spells are cast on blank rune stones, which requires mana. Rune stones can easily be carried around and store the specific spell. It can be used at any time, and only some spells require further investment of mana. +Spontaneous spells are cast in the heartbeat they are needed, and take effect instantly. Most of these are healing spells, but there are also aggressive spells, invisibility or shape change spells, and more. +]] + }, + [15] = { + containerId = 1718, + itemId = 1950, + --position = (Rookgaard Libraries), + text = [[ +Magic + +There are two kinds of spells: rune spells, and instant spells. Rune spells are cast on blank runes and some mana is used up in this process. + +These can easily be carried around and store the specific spell. It can be used at any time, and only some require further investment of mana. + +Instant spells are cast in the heartbeat they are needed and take effect instantly. Some of these spells Instant Spells heal while others are agressive and some even have more astonishing effects, such as invisibility. + ]] + }, + [16] = { + containerId = 1718, + itemId = 1955, + --position = (Isle of the Kings Library), + text = [[ +Magic by Puffels +There are two kinds of spells: rune-spells, and spontaneous spells. +Rune-spells are cast on blank runestones and some mana is used up in this proces. This stones can easily be carried around and store the specific spell. It can be used at any time, and only some require further investment of mana. +Spontaneous spells are cased in the heartbeat they are needed and take effect instantly. Most of these spells are spells of healing but some of them are agressive and some even have more astonishing effectes, as invisibility, illusionary shapechange etc. +]] + }, + [17] = { + containerId = 1719, + itemId = 1955, + position = {x = 32069, y = 31889, z = 4}, + text = [[ +Combat Tactics + +Most monsters are far more dangerous when you're attacked by more of them. Keep in mind that no more than two enemy attacks can be blocked at a time. Use this to your advantage and attack single monsters with help of other heroes. Don't get surrounded by monsters - that might be your death even if the monsters are not that powerful. +]] + }, + [18] = { + containerId = 1718, + itemId = 1950, + --position = (Rookgaard Libraries), + text = [[ +As we traveled through the dungeon tunnels we came to a big cave. In the light of our torches we saw several eyes glowing in the darknes, then the trolls attacked, silent as usual. We imediately dropped our torches and raised our shields to block the first attack, then we counterattacked. Soon the floor was wet with blood, ours and theirs. They were verry skilled in blocking our blows and I am sure with inferior weapons we would have hacked on this beasts for an eternity. +]] + }, + [19] = { + containerId = 1719, + itemId = 1961, + position = {x = 32069, y = 31889, z = 4}, + text = [[ +As we traveled through the dungeon tunnels we came to a big cave. In the light of our torches we saw several eyes glowing in the darknes, then the trolls attacked, silent as usual. We imediately dropped our torches and raised our shields to block the first attack, then we counterattacked. Soon the floor was wet with blood, ours and theirs. They were verry skilled in blocking our blows and I am sure with inferior weapons we would have hacked on this beasts for an eternity. + ]] + }, + [20] = { + containerId = 1719, + itemId = 1950, + position = {x = 32069, y = 31889, z = 4}, + text = [[ +Tactics for close-ranged combat +- Use the terrain to your advantage: always know the way to the nearest ropespot, and make sure you are not surrounded by enemies - that can be a death trap! +- Use narrow passages to make sure not more than one enemy at a time can sneak up. +- Avoid being close to more than two enemies at once if you can, because you can only block two at a time. +- Be careful while chasing an enemy: you might run into his allies or other monsters. +- Target the closest enemy, or you'll become confused and might not be able to defend yourself against other attacks. +- Different enemies require different tactics. While some are best to be fought in an agressive combat mode to finish them off quickly, you might want to defend yourself more against others. Choosing between your combat modes also depends on your equipment - play your strengths! +]] + }, + [21] = { + containerId = 1719, + itemId = 1950, + --position = (Isle of the Kings Library), + text = [[ +The Tibian Wonders of the World! +The known and acknowledged wonders of the world are: +The colossus of Kazordoon +The black pyramid of Dracoria +The great lighthouse tree of Ab'dendriel +The thorntower of Shadowthorn +The underground city of Mintwallin +The black city of skulls in Hellsgate +The great lava falls in Hellsgate +The pyramid city of Ankrahmun + ]] + }, + [22] = { + containerId = 1719, + itemId = 1960, + --position = (Ankrahmun great pyramid), + text = [[ +The Tibian Wonders of the World! +The known and acknowledged wonders of the world are: +The colossus of Kazordoon +The black pyramid of Dracoria +The great lighthouse tree of Ab'dendriel +The thorntower of Shadowthorn +The underground city of Mintwallin +The black city of skulls in Hellsgate +The great lava falls in Hellsgate +The pyramid city of Ankrahmun + ]] + }, + [23] = { + containerId = 1719, + itemId = 1959, + position = {x = 32069, y = 31889, z = 4}, + text = [[ +The Tibian Wonders of the World! +The known and acknowledged wonders of the world are: +The colossus of Kazordoon +The black pyramid of Dracoria +The great lighthouse tree of Ab'dendriel +The thorntower of Shadowthorn +The underground city of Mintwallin +The black city of skulls in Hellsgate +The great lava falls in Hellsgate +The pyramid city of Ankrahmun + ]] + }, + [24] = { + itemId = 1965, + position = {x = 32068, y = 31880, z = 3}, + text = [[ +Genesis VII, ii. Tibia's Renewal + +The humans have availed themselves well of this opportunity. Under the wise guidance of the Thaian kings, who were direct descendants of Banor, the race is living through a golden age. The arts and the sciences prosper, and many a thriving city has been founded. To be sure, the humans' expansion has met with fierce resistance, and in fact the dauntless heroes who still enter this world from the mysterious Portals of Souls are busy enough to fight the constant threat posed by all kinds of hostile creatures. But so far the peace has lasted, and under its protection the human race has finally asserted itself as the dominant species in Tibia. However, there are disquieting signs that this glorious era might slowly come to its end. For the old enemies have never been vanquished, and now it seems that they are growing increasingly restless. The fierce orcs are stirring once more, attacking human settlements and sometimes even major cities in vicious, well-coordinated attacks. The undead have again started to walk the land, striking fear into the hearts of the living. There are even disconcerting reports that the fearsome dragons who have lain dormant for centuries are again leaving their hidden lairs to prey. Worst of all, the humans, that curious race, have started bickering amongst themselves, and more than once tensions have led to armed conflicts. In the course of time, some humans even renounced the Thaian kings' rule and founded own cities and empires. + +It may be that this is yet another one of Zathroth's wicked ploys. It is well known that his most diabolic minions, the gruesome demons, are lurking in the shadows, biding their time. Who knows - perhaps Tibia is on the brink of another cataclysmic war, and a new twilight will fall on the world. Fate alone knows what the future has in store for Tibia. Let us all hope and pray that the humans' unity will not break just when it is needed most. + ]] + }, + [25] = { + itemId = 1965, + position = {x = 32054, y = 31894, z = 4}, + text = [[ +GV.i Part 1: The Age of Chaos + +Uman looked with sadness at the damage his evil half had done to the creation Fardos and he had worked for so hard. He felt that Zathroth had finally gone too far. In his desperation he turned to Fardos for advice. Together, they decided that it would be best to sever the bond between Uman and Zathroth once and for all. They set about to this task with great energy, and their efforts soon enough appeared to be crowned with success. However, the weaker the bond between Uman and Zathroth became, the weaker Uman himself grew, and in the end they realised that the duality could not be separated without endangering Uman's very existence. At last the invocation was aborted. Uman had to accept the fact that the duality between Zathroth and himself could not be broken, and that their fate and indeed their very existence were intertwined for eternity. + +However, Uman's and Fardos's joint efforts did not remain entirely without consequence, for during the unsuccessful attempt to separate the double god a small part broke away from it. This tiny shard grew and expanded until it took shape and eventually became a sentient creature of its own. This was the hour Kirok the Mad was born. Owing to his peculiar ancestry this strange god has a twisted or, as some say, a schizophrenic nature. He inherited Uman's creative mind and his inquisitive nature, so that he eventually became the patron god of all those who follow the path of science and research. However, the one trait Kirok is really famous for is his twisted sense of humour. He adores bad taste and ingenious pranks, and this peculiar characteristic makes him the favourite of bards, jesters and of all other kinds of suspicious people. + +While Fardos and Uman were working hard on their spell, Zathroth's minions went on to lay waste to the elder gods' precious creation, and the devastation continued without pause. It seemed as though the whole world was doomed to perish. However, some of the lesser gods who were tired of just standing by while their beloved Tibia was ravaged. They decided to put up resistance against the reckless hordes. Bastesh the Mistress of the Sea created huge, mysterious creatures that were both elegant and fierce, and she populated her beloved ocean with them to make sure Zathroth's minions would never defile its pure waters. However, there was little she could do to help her cousins who lived on the dry land. Of all her creatures the only ones to survive on land were the dextrous and venomous snakes. Crunor and Nornur, too, created creatures to fight against Brog's and Zathroth's hordes: Crunor the Lord of the Trees created fierce wolves, while Nornur equipped his beloved spiders with deadly poison to make them more powerful. + ]] + }, + [26] = { + containerId = 1718, + itemId = 7492, + position = {x = 32061, y = 31894, z = 4}, + text = [[ +This is written proof that Captain Plunderpurse gave away all the cursed gold to the little kiddies, bless his generous heart. No torture, extortion, cut off limbs, manipulation or embezzlement at all was involved in my testimony, I swear! And I am very thankful not to make the acquaintance of the Captain's pet sharks, lovely beasts though they are. Signed, Triomon Tangleweed, certifying notary. + ]] + }, + [27] = { + containerId = 1718, + itemId = 1960, + position = (Nagor), + text = [[ +Treasures of the Southern Isles + +Quite a few pirates hoarded up treasures in the past. It is known that pirates tend to hide their treasures on deserted islands for some unknown reason. They just bury them on some remote place and then forget about them. This similarity to the behaviour of squirrels was never scientifically verified. However, since pirates love to dress lightly they also love the south. Therefore, it is only natural that they hide their treasures there. Some of the southern isles are so popular among pirates that there is hardly any free space left to bury new treasure. + +If anyone ever is looking for treasures, then those isles are the best place to start with. + ]] + }, + [28] = { + containerId = 1718, + itemId = 1955, + --position = (Isle of the Kings Library), + text = [[ +Treasures of the Southern Isles + +Quite a few pirates hoarded up treasures in the past. It is known that pirates tend to hide their treasures on deserted islands for some unknown reason. They just bury them on some remote place and then forget about them. This similarity to the behaviour of squirrels was never scientifically verified. However, since pirates love to dress lightly they also love the south. Therefore, it is only natural that they hide their treasures there. Some of the southern isles are so popular among pirates that there is hardly any free space left to bury new treasure. + +If anyone ever is looking for treasures, then those isles are the best place to start with. + ]] + }, + [29] = { + containerId = 1718, + itemId = 1961, + position = {x = 32061, y = 31894, z = 4}, + text = [[ +Treasures of the Southern Isles + +Quite a few pirates hoarded up treasures in the past. It is known that pirates tend to hide their treasures on deserted islands for some unknown reason. They just bury them on some remote place and then forget about them. This similarity to the behaviour of squirrels was never scientifically verified. However, since pirates love to dress lightly they also love the south. Therefore, it is only natural that they hide their treasures there. Some of the southern isles are so popular among pirates that there is hardly any free space left to bury new treasure. + +If anyone ever is looking for treasures, then those isles are the best place to start with. + ]] + }, + [30] = { + containerId = 1718, + itemId = 1963, + position = {x = 32061, y = 31894, z = 4}, + text = [[ +The Great Sea Serpents + +The Sea Serpent is as huge as a house and can swallow a small ship in one bite. Its scales are almost impenetrable and its teeth, which are as big as a cyclops, are coated with a corrosive poison that will dissolve human flesh on touch. In their undersea lairs they hoard treasures that would make a dragons hoard look miserable. +]] + }, + [31] = { + containerId = 1718, + itemId = 1960, + --position = (Nagor), + text = [[ +The Great Sea Serpents + +The Sea Serpent is as huge as a house and can swallow a small ship in one bite. Its scales are almost impenetrable and its teeth, which are as big as a cyclops, are coated with a corrosive poison that will dissolve human flesh on touch. In their undersea lairs they hoard treasures that would make a dragons hoard look miserable. + ]] + }, + [32] = { + containerId = 1718, + itemId = 1955, + --position = (Liberty Bay freedom street), + text = [[ +The Great Sea Serpents + +The Sea Serpent is as huge as a house and can swallow a small ship in one bite. Its scales are almost impenetrable and its teeth, which are as big as a cyclops, are coated with a corrosive poison that will dissolve human flesh on touch. In their undersea lairs they hoard treasures that would make a dragons hoard look miserable. + ]] + }, + [33] = { + containerId = 1718, + itemId = 1950, + --position = (Isle of the Kings Library), + text = [[ +The Great Sea Serpents + +The Sea Serpent is as huge as a house and can swallow a small ship in one bite. Its scales are almost impenetrable and its teeth, which are as big as a cyclops, are coated with a corrosive poison that will dissolve human flesh on touch. In their undersea lairs they hoard treasures that would make a dragons hoard look miserable. + ]] + }, + [34] = { + containerId = 1718, + itemId = 1963, + position = (kharos), + text = [[ +The Great Sea Serpents + +The Sea Serpent is as huge as a house and can swallow a small ship in one bite. Its scales are almost impenetrable and its teeth, which are as big as a cyclops, are coated with a corrosive poison that will dissolve human flesh on touch. In their undersea lairs they hoard treasures that would make a dragons hoard look miserable. + ]] + }, + [35] = { + containerId = 1718, + itemId = 1965, + position = {x = 32061, y = 31894, z = 4}, + text = [[ +V.i Part 2: The Age of Chaos + +However, for all their efforts, the gods could not create creatures that were a match for the ruthless, well-organised hordes that roamed the land. The wolves' hides and the spiders chitinous exoskeletons could not resist the steel of the orcish blades, and for every troll that was brought down by poison two others came to take his place. In the end gods' children withdrew to areas that were easy to defend: The wolves fled into the depths of the forests, while the spiders hid deep in caves. There they continued their fights, defending their realms against the onslaught of the superior enemy. These little pockets of resistance were the only sanctuaries in a world that sank deeper and deeper into chaos. And the worst was yet to come, for now the dragons felt the time had come to take what was theirs by right! + +For centuries they had propagated and expanded in silence, largely unnoticed by all other creatures. But now that Garsharak, the very first and strongest of their race, sent them into the world they knew neither restraint nor mercy. The orcish armies were routed by the relentless flames of magical dragon fire, and soon that proud though barbaric race, who until then had not known the meaning of the word defeat, was driven into the shelter of subterranean settlements. Their allies, the mighty cyclopes, fared no better. Although they won a number of notable victories using their powerful weapons and armour, they, too, had to yield to the superior power of the dreaded dragons. They joined their former allies, the orcs, and their weak cousins, the trolls, in their subterranean exile. Their proud cities that had been built in the course of centuries were burnt down to the ground, and their renowned forges were lost forever. + +Thus the dragons had taken over the rule of the land, but the war was by no means over. Their bitter enemies, cyclopes and orcs, resented what they felt was an imprisonment in the bowels of the earth, and they continued the fight from their subterranean hideouts. And in fact the dragons, who had already been weakened in the course of the previous battles, suffered serious losses. But now war also erupted among the former allies, as cyclopes and orcs competed for food and space in their subterranean abodes. And even though no side was strong enough to overcome the others the war went on with undiminished force, and all of the races suffered greatly in the epic struggle. The land was scattered with bodies, and while it seemed that life itself would be wiped from the face of Tibia the losses of all races that were involved daily grew in number. It was as if the living would drown in the bodies of the slain. +]] + }, + [36] = { + containerId = 3826, + itemId = 1965, + position = {x = 32075, y = 31894, z = 4}, + text = [[ +V. ii, The Age of Chaos + +The elder gods watched as the cataclysmic battle went on. They felt no pity for those that were slain because they cared little for Zathroth's creatures, but they knew that something was missing, that somebody was needed to take care of the bodies and souls of those who ceased to live. They began to look for a solution, and finally Uman proposed that a new god should be created, a god who should see to it that the dead would be taken care of. They decided that earth, which in a way was the giver of life, should have a part in taking it back, and that Uman should be the newly created god's father. But alas! The elder gods were not as cautious as they should have been, and so Zathroth the Destroyer learnt about their plans all too soon. He was fascinated by the idea of death from the start, because he saw in it a new chance to bring further havoc and destruction into the world. Soon he had devised a vicious plan. He posed as his good half Uman to fool earth, and with it he sired another god: Urgith the Master of the Undead. This hideous deity was devoted to death just like the god Uman and Fardos had in mind, but he was not the benign guardian of the dead they had envisioned. Instead, Urgith was a cruel god who strove to infuse the bodies of the dead with unholy energy, dooming them to a state that was neither life nor death. Thus, the hour of Urgith's birth marked the beginning of undeath. + +Soon enough innumerable undead roamed the world. After all, Tibia was still covered by countless bodies of slain orcs, cyclopes and other creatures - the legacy of the many years of ceaseless war. These cadavers provided Urgith with the ideal recruitment pool, and he eagerly transformed all carcasses he could lay his hands into his gruesome servants. The gods watched in horror as a new scourge ravaged their beloved creation. They hurried to finally put their own initial plan into practice, and Uman united with earth in order to sire Toth the Warden of the Souls. It was to be his mission to safely guide the souls of the dead to the otherworld, where they would safely rest in the peace of an eternal dreamless slumber, while the worms, his faithful servants, swarmed out to devour their bodies that scattered the face of Tibia. But the damage had been done, and even though Toth and his servants did the best they could Urgith's ghastly creations continued to roam the land. All the other creatures, who were already greatly weakened by their endless wars, could put up little resistance to the new enemy who increased in strength with every loss they suffered. It looked as if Tibia was forever doomed to be a world that was inhabited by the living dead. + +The elder gods looked at what had happened to their world, and their hearts filled with sorrow and resentment. They knew that if they did not act now Tibia would be destined to become a grave, and so they started looking for a solution. Eventually they agreed to try to create a sentient race of their own, a race that would be strong enough to take up the fight against the hordes that ravaged their beloved world. And so they created a race and sent it into Tibia. But alas! Urgith's minions were too strong. Their race was defeated within a generation, and it was wiped from the face of Tibia. So Uman and Fardos created race after race, and race after race was overwhelmed by the vicious abominations that Urgith had released into the world. Most of these races disappeared from the face of Tibia forever, leaving little but melancholy legends and mysterious ruins. Today, this sad era which is commonly known as the Corpse War is largely shrouded in mystery, and the unfortunate races that were destroyed in it are now referred to as the ancients. + ]] + }, + [37] = { + containerId = 3826, + itemId = 1964, + position = {x = 32075, y = 31894, z = 4}, + text = [[ +The Shattered Isles + +Nargor is a hostile rock surrounded by treacherous reefs. Since it is uninhabitable and almost unreachable it is of no interest. + +Treasure Island is not only desert-like but also quite deserted. The only people you meet are treasure hunters that travel there occasionally to try their luck. + +The inhabitants of the town Liberty Bay live on the numerous plantations. The town has developed into a major trading center in recent years, and is under Thaian rule. + +The Forbidden Islands to the north-west are dangerous not only because of the volcanoes that are found there but also due to frequent quara activity. Since there is no real reason to visit these islands, no regular shipping route was ever established. + +The Laguna Islands are quite often visited by passing ships to refresh their supply of water and food. Still the isles are too desolate to establish a settlement there. It is rumored that a small tribe of savages calls one of the isles its home. +]] + }, + [38] = { + containerId = 3826, + itemId = 1959, + position = (Nagor), + text = [[ +The Shattered Isles + +Nargor is a hostile rock surrounded by treacherous reefs. Since it is uninhabitable and almost unreachable it is of no interest. + +Treasure Island is not only desert-like but also quite deserted. The only people you meet are treasure hunters that travel there occasionally to try their luck. + +The inhabitants of the town Liberty Bay live on the numerous plantations. The town has developed into a major trading center in recent years, and is under Thaian rule. + +The Forbidden Islands to the north-west are dangerous not only because of the volcanoes that are found there but also due to frequent quara activity. Since there is no real reason to visit these islands, no regular shipping route was ever established. + +The Laguna Islands are quite often visited by passing ships to refresh their supply of water and food. Still the isles are too desolate to establish a settlement there. It is rumored that a small tribe of savages calls one of the isles its home. + ]] + }, + [39] = { + containerId = 3826, + itemId = 1966, + --position = (Liberty Bay freedom street), + text = [[ +The Shattered Isles + +Nargor is a hostile rock surrounded by treacherous reefs. Since it is uninhabitable and almost unreachable it is of no interest. + +Treasure Island is not only desert-like but also quite deserted. The only people you meet are treasure hunters that travel there occasionally to try their luck. + +The inhabitants of the town Liberty Bay live on the numerous plantations. The town has developed into a major trading center in recent years, and is under Thaian rule. + +The Forbidden Islands to the north-west are dangerous not only because of the volcanoes that are found there but also due to frequent quara activity. Since there is no real reason to visit these islands, no regular shipping route was ever established. + +The Laguna Islands are quite often visited by passing ships to refresh their supply of water and food. Still the isles are too desolate to establish a settlement there. It is rumored that a small tribe of savages calls one of the isles its home. + ]] + }, + [40] = { + containerId = 3826, + itemId = 1973, + --position = (Liberty Bay Malunga), + text = [[ +The Shattered Isles + +Nargor is a hostile rock surrounded by treacherous reefs. Since it is uninhabitable and almost unreachable it is of no interest. + +Treasure Island is not only desert-like but also quite deserted. The only people you meet are treasure hunters that travel there occasionally to try their luck. + +The inhabitants of the town Liberty Bay live on the numerous plantations. The town has developed into a major trading center in recent years, and is under Thaian rule. + +The Forbidden Islands to the north-west are dangerous not only because of the volcanoes that are found there but also due to frequent quara activity. Since there is no real reason to visit these islands, no regular shipping route was ever established. + +The Laguna Islands are quite often visited by passing ships to refresh their supply of water and food. Still the isles are too desolate to establish a settlement there. It is rumored that a small tribe of savages calls one of the isles its home. + ]] + }, + [41] = { + containerId = 3826, + itemId = 1959, + --position = (Carlin Congress), + text = [[ +The Shattered Isles + +Nargor is a hostile rock surrounded by treacherous reefs. Since it is uninhabitable and almost unreachable it is of no interest. + +Treasure Island is not only desert-like but also quite deserted. The only people you meet are treasure hunters that travel there occasionally to try their luck. + +The inhabitants of the town Liberty Bay live on the numerous plantations. The town has developed into a major trading center in recent years, and is under Thaian rule. + +The Forbidden Islands to the north-west are dangerous not only because of the volcanoes that are found there but also due to frequent quara activity. Since there is no real reason to visit these islands, no regular shipping route was ever established. + +The Laguna Islands are quite often visited by passing ships to refresh their supply of water and food. Still the isles are too desolate to establish a settlement there. It is rumored that a small tribe of savages calls one of the isles its home. + ]] + }, + [42] = { + containerId = 3826, + itemId = 1955, + --position = (Carlin Explorer Club), + text = [[ +The Shattered Isles + +Nargor is a hostile rock surrounded by treacherous reefs. Since it is uninhabitable and almost unreachable it is of no interest. + +Treasure Island is not only desert-like but also quite deserted. The only people you meet are treasure hunters that travel there occasionally to try their luck. + +The inhabitants of the town Liberty Bay live on the numerous plantations. The town has developed into a major trading center in recent years, and is under Thaian rule. + +The Forbidden Islands to the north-west are dangerous not only because of the volcanoes that are found there but also due to frequent quara activity. Since there is no real reason to visit these islands, no regular shipping route was ever established. + +The Laguna Islands are quite often visited by passing ships to refresh their supply of water and food. Still the isles are too desolate to establish a settlement there. It is rumored that a small tribe of savages calls one of the isles its home. +]] + }, + [43] = { + containerId = 3827, + itemId = 1966, + position = {x = 32068, y = 31898, z = 4}, + text = [[ +My travels. + +As the orcs approached I've hidden myself in the bushes near the lake. I did hardly dare to breath as they met only some inches from my nose. I thought my wild beating heart might betray me to this murderous beasts. I overheared the greenskined brutes. 'charach' (or so) one said and the other responded the same way, then they began to chat in their strange language, certainly talking about some gruesome plot against mankind. Talking they wandered away and after they vanished from my view I quickly got up and headed to Thais as fast as I could. +]] + }, + [44] = { + containerId = 3827, + itemId = 1955, + --position = (Rookgaard Academy), + text = [[ +My travels. + +As the orcs approached I've hidden myself in the bushes near the lake. I did hardly dare to breath as they met only some inches from my nose. I thought my wild beating heart might betray me to this murderous beasts. I overheared the greenskined brutes. 'charach' (or so) one said and the other responded the same way, then they began to chat in their strange language, certainly talking about some gruesome plot against mankind. Talking they wandered away and after they vanished from my view I quickly got up and headed to Thais as fast as I could. + ]] + }, + [45] = { + containerId = 3827, + itemId = 1955, + position = {x = 32068, y = 31898, z = 4}, + text = [[ +Tibiantis: Fact and Fiction + +In the light of progress made my modern science the tales of Tibiantis can be cheerfully disregarded as blatant myths. The author of this questionable history merely drew upon several myths and mixed them together to create a tale plausible to those given to believe such romantic nonsense. The recently discovered, or more accurately, recently rediscovered, city of Yalahar is very obviously a major inspiration for the story of Tibiantis. Aspects of the story can be found in actual fact in Yalahar - the city itself is huge, and also extended its borders beyond the land into the sea, and judging from what can be found there, was most definitely at some point in its past a city that was home to great wonders, whose inhabitants were in possession of great knowledge. However, one of the great mysteries of Yalahar is whether in actual fact those that live there are even human or another race, until recently unknown amongst the Tibian civilisations. The aspect of the story of Tibiantis referring to the downfall of a civilisation could be influenced by many different myths. One such source could be based upon the discoveries made far to the North of Tibia which suggest the possibility of a civilisation that was wiped out by an as yet unknown catastrophe of cataclysmic proportions. Equally, to the extreme south of Tibia can be found the Shattered Isles. These Isles were so named with good reason - geological studies conducted by the Explorers' Society reveal that these isles did not so much sink but were blasted by a phenomenal explosion of some kind. Relics found upon the Isles also hint that they were once populated by a great and most likely advanced civilisation. It is the sad fate of these isles to be the home of the infamous Quara. It is these twisted creatures who probably provide the origin of the myth's fish people. In summary, I believe I have gathered enough proof here to dispell any reason for believing the tale of Tibiantis, and have proven it to be nothing but a conglomeration of ancient stories and legends which an overly ambitious and half informed so-called historian has put together into a new myth of his own making, in order to gain cheap fame by hoodwinking a gullible and uninformed public. +]] + }, + [46] = { + containerId = 3827, + itemId = 1960, + --position = (Carlin Congress), + text = [[ +Tibiantis: Fact and Fiction + +In the light of progress made my modern science the tales of Tibiantis can be cheerfully disregarded as blatant myths. The author of this questionable history merely drew upon several myths and mixed them together to create a tale plausible to those given to believe such romantic nonsense. The recently discovered, or more accurately, recently rediscovered, city of Yalahar is very obviously a major inspiration for the story of Tibiantis. Aspects of the story can be found in actual fact in Yalahar - the city itself is huge, and also extended its borders beyond the land into the sea, and judging from what can be found there, was most definitely at some point in its past a city that was home to great wonders, whose inhabitants were in possession of great knowledge. However, one of the great mysteries of Yalahar is whether in actual fact those that live there are even human or another race, until recently unknown amongst the Tibian civilisations. The aspect of the story of Tibiantis referring to the downfall of a civilisation could be influenced by many different myths. One such source could be based upon the discoveries made far to the North of Tibia which suggest the possibility of a civilisation that was wiped out by an as yet unknown catastrophe of cataclysmic proportions. Equally, to the extreme south of Tibia can be found the Shattered Isles. These Isles were so named with good reason - geological studies conducted by the Explorers' Society reveal that these isles did not so much sink but were blasted by a phenomenal explosion of some kind. Relics found upon the Isles also hint that they were once populated by a great and most likely advanced civilisation. It is the sad fate of these isles to be the home of the infamous Quara. It is these twisted creatures who probably provide the origin of the myth's fish people. In summary, I believe I have gathered enough proof here to dispell any reason for believing the tale of Tibiantis, and have proven it to be nothing but a conglomeration of ancient stories and legends which an overly ambitious and half informed so-called historian has put together into a new myth of his own making, in order to gain cheap fame by hoodwinking a gullible and uninformed public. + ]] + }, + [47] = { + containerId = 3827, + itemId = 1958, + --position = (Isle of the Kings Library), + text = [[ +Tibiantis: Fact and Fiction + +In the light of progress made my modern science the tales of Tibiantis can be cheerfully disregarded as blatant myths. The author of this questionable history merely drew upon several myths and mixed them together to create a tale plausible to those given to believe such romantic nonsense. The recently discovered, or more accurately, recently rediscovered, city of Yalahar is very obviously a major inspiration for the story of Tibiantis. Aspects of the story can be found in actual fact in Yalahar - the city itself is huge, and also extended its borders beyond the land into the sea, and judging from what can be found there, was most definitely at some point in its past a city that was home to great wonders, whose inhabitants were in possession of great knowledge. However, one of the great mysteries of Yalahar is whether in actual fact those that live there are even human or another race, until recently unknown amongst the Tibian civilisations. The aspect of the story of Tibiantis referring to the downfall of a civilisation could be influenced by many different myths. One such source could be based upon the discoveries made far to the North of Tibia which suggest the possibility of a civilisation that was wiped out by an as yet unknown catastrophe of cataclysmic proportions. Equally, to the extreme south of Tibia can be found the Shattered Isles. These Isles were so named with good reason - geological studies conducted by the Explorers' Society reveal that these isles did not so much sink but were blasted by a phenomenal explosion of some kind. Relics found upon the Isles also hint that they were once populated by a great and most likely advanced civilisation. It is the sad fate of these isles to be the home of the infamous Quara. It is these twisted creatures who probably provide the origin of the myth's fish people. In summary, I believe I have gathered enough proof here to dispell any reason for believing the tale of Tibiantis, and have proven it to be nothing but a conglomeration of ancient stories and legends which an overly ambitious and half informed so-called historian has put together into a new myth of his own making, in order to gain cheap fame by hoodwinking a gullible and uninformed public. + ]] + }, + [48] = { + containerId = 3827, + itemId = 1965, + position = {x = 32068, y = 31898, z = 4}, + text = [[ +You can not even imagine how old I am. In your wildest dreams you won't see the things I have seen. I am the last of my race and even though I am several centuries old I am not immortal and will eventually die. I fear that day. Not for me - I am weary and I don't care much about if I'm alive or dead. But I fear for all these memories that will die with me. For all those who no one will remember anymore. +Words can't truly preserve their essence so I will leave no books or stone tablets. If I die, everything I have witnessed will die with me as if it has never existed. I was there when Rorak slew Tingil at the stairs of the seven temples. I was there as Riik led his peaceloving people to the far north to find refuge from the war. I was there to witness the betrayal of Asric for the whims of a female that was long dead by then. I fought with the last Frdai a futile battle on the plains of Weskurt against the unseen legion. I witnessed Ss'rar making his move on ascension to become the serpent god. I watched the first elves struggling to form a nation with the help of the lightbearers. It was me who assisted the great calculator to assemble the bonelords language. And you come here to this mountain and ask me how to win the heart of some shepherdess? This world has become a ridiculous mockery. +]] + }, + [49] = { + containerId = 3827, + itemId = 1950, + --position = (Isle of the Kings Library), + text = [[ +You can not even imagine how old I am. In your wildest dreams you won't see the things I have seen. I am the last of my race and even though I am several centuries old I am not immortal and will eventually die. I fear that day. Not for me - I am weary and I don't care much about if I'm alive or dead. But I fear for all these memories that will die with me. For all those who no one will remember anymore. +Words can't truly preserve their essence so I will leave no books or stone tablets. If I die, everything I have witnessed will die with me as if it has never existed. I was there when Rorak slew Tingil at the stairs of the seven temples. I was there as Riik led his peaceloving people to the far north to find refuge from the war. I was there to witness the betrayal of Asric for the whims of a female that was long dead by then. I fought with the last Frdai a futile battle on the plains of Weskurt against the unseen legion. I witnessed Ss'rar making his move on ascension to become the serpent god. I watched the first elves struggling to form a nation with the help of the lightbearers. It was me who assisted the great calculator to assemble the bonelords language. And you come here to this mountain and ask me how to win the heart of some shepherdess? This world has become a ridiculous mockery. + ]] + }, + [50] = { + containerId = 3827, + itemId = 1963, + position = {x = 32068, y = 31898, z = 4}, + text = [[ +The Lighthouse in the Middle of Nowhere +Sailors claim to have travelled as far as the end of the world where the water pours down into nothingness. Although it is easily recognizable during daylight it poses a special threat at night. To make matters worse, a spooky lighthouse sometimes appears out of nowhere to lure ships over the edge of the world. Whether it is really a lighthouse or some other source of light differs from story to story and remains to be determined. +]] + }, + [51] = { + containerId = 3827, + itemId = 1961, + --position = (Liberty Bay), + text = [[ +The Lighthouse in the Middle of Nowhere +Sailors claim to have travelled as far as the end of the world where the water pours down into nothingness. Although it is easily recognizable during daylight it poses a special threat at night. To make matters worse, a spooky lighthouse sometimes appears out of nowhere to lure ships over the edge of the world. Whether it is really a lighthouse or some other source of light differs from story to story and remains to be determined. + ]] + }, + [52] = { + itemId = 12397, + position = {x = 32075, y = 31898, z = 4}, + text = "Personal log book of Mr Morris. (The following lines are written in a code that you cannot make out. It seems Mr Morris is a very distrustful person.)" + }, + [53] = { + itemId = 1958, + position = {x = 32070, y = 31900, z = 4}, + text = [[ +The ......... +Some of he ancients formed .......amlands. They build mighty fortresses to ........................, conscious or not. It was then, when the mysteri............... and his anger shook the foundation of .....................................awakened screaming in fear and pain. And after the ................................................................................ were gone! All of them with all ..........................................................ost their best men in theese days and never recovered from the ........................................... for the other ancients and so the time of the first dreammasters ended. +From this time on ............. manipulate little of the matter of the dreamlands to ................................................. others in their .................... and prophecy, but not to .......... +]] + }, + [54] = { + containerId = 3827, + itemId = 1950, + --position = (Isle of the Kings Library), + text = [[ +The ......... +Some of he ancients formed .......amlands. They build mighty fortresses to ........................, conscious or not. It was then, when the mysteri............... and his anger shook the foundation of .....................................awakened screaming in fear and pain. And after the ................................................................................ were gone! All of them with all ..........................................................ost their best men in theese days and never recovered from the ........................................... for the other ancients and so the time of the first dreammasters ended. +From this time on ............. manipulate little of the matter of the dreamlands to ................................................. others in their .................... and prophecy, but not to .......... + ]] + }, + [55] = { + itemId = 7724, + position = {x = 32070, y = 31900, z = 4}, + text = [[ +(It is covered with a strange language that you cannot make out.) + ]] + }, + [56] = { + itemId = 1966, + position = {x = 32052, y = 31898, z = 6}, + text = [[ +... + +The elder gods looked at what had happened to their world, and their hearts filled with sorrow and resentment. They knew that if they did not act now Tibia would be destined to become a grave, and so they started looking for a solution. Eventually they agreed to try to create a sentient race of their own, a race that would be strong enough to take up the fight against the hordes that ravaged their beloved world. And so they created a race and sent it into Tibia. But alas! Urgith's minions were too strong. Their race was defeated within a generation, and it was wiped from the face of Tibia. So Uman and Fardos created race after race, and race after race was overwhelmed by the vicious abominations that Urgith had released into the world. Most of these races disappeared from the face of Tibia forever, leaving little but melancholy legends and mysterious ruins. Today, this sad era which is commonly known as the Corpse War is largely shrouded in mystery, and the unfortunate races that were destroyed in it are now referred to as the Ancients. + +... + ]] + }, + [57] = { + containerId = 3827, + itemId = 1963, + position = {x = 32052, y = 31896, z = 6}, + text = "Cooking Recipes for the Wildlife (excepting Squirrels!), by Richard" + }, + [58] = { + containerId = 3827, + itemId = 1965, + position = {x = 32052, y = 31896, z = 6}, + text = [[ +V. iii, The Age of Chaos + +However, not all of the ancients were eradicated in the fierce struggle. At least two of the races created by the elder gods in the course of this epic struggle somehow managed to escape destruction and to survive until today. One of them was the elves, delicate creatures who could handle bows and musical instruments with equal skill. The other was the dwarfs, a stout race of gifted miners and smiths. Both of these races fought bravely, but both of them had to yield to the vicious power of their enemies, and it was only by fleeing into safe places of refuge that they managed to survive. The elves after many hardships sought shelter in the unfathomable depths of the forests, while the dwarfs barricaded themselves in their impenetrable fortresses deep in Tibia's mountains. There, these races waited for better times, bitterly deploring the cruel fate that had sent them into this dreadful world. But at least they had survived. All the other ancient races were seemingly sentenced to oblivion, although it is occasionally claimed that there are other survivors. + +For all their strength, these races had one important flaw in common: They lacked flexibility. And this proved to be fatal in the war against the relentless enemy they were facing. Those who were not annihilated succumbed to Zathroth's temptations. More than one of the ancients fell for Zathroth's cunning promises of power and knowledge, and legend has it that the wrathful elder gods brutally punished many of them for their treachery. There is even a persistent theory that some of these ancients later on were formed by the devious Zathroth into the very first demons. Be that as it may, all the ancients failed to live up to their creators' expectations: One by one they were overwhelmed by the enemy, and still the hordes walked the world. But the elder gods had learnt from their mistakes. Their next creation was to be well suited for the task. And they called them the humans. + ]] + }, + [59] = { + containerId = 3827, + itemId = 1961, + position = {x = 32052, y = 31896, z = 6}, + text = [[ +Thoughts and Notations on the Noble Craft of Potion-Making, by Grandsieur Haruvan of Drefia (the way of writing and the pages look very, very old) + +The Gods gave their gifts freely, but bestowed them not on all creatures alike. Some ancient creatures were possessed of a far-reaching will to conquer and subdue all others through their thoughts alone, while the newer beings could weave magic in defense or had strength and swiftness to defend and escape the wiles laid out to ensnare them. Some animals and plants, simple though they may seem to us, yet are deadly poisonous in order to ward off their hunter. + + +But only the more intelligent beings - and of those, only a select few - possess the art of making powerful concoctions that enhance their faculties. +The humble woodman or wanderer will never be able to fulfil the complex rites, or even grasp the concept, of the trimagical umbralistic principle of the equinox formula that is crucial to the craft of magical potions. +But still, they can drink, and appreciate, the brews we make to keep a warrior's body alive in a fight, the mage's mana when drained, the paladin's spirit when they need to gather holy force. ... (you lose interest and close the book) + ]] + }, + [60] = { + -- Hiding the Amulet (Dawnport quest) + itemId = 23764, + position = {x = 32046, y = 31915, z = 7}, + text = [[ +(You can barely read the following words on this soiled piece of paper) + +... growing weaker by the minute. I should have... bad feeling about this! +The cyclops ... +... too many of them. No help. I must... +... hid the ancient amulet beneath the sand, before ...should have listened to ... +Must hide... paper, hope an adventurer will... + + +... amulet will be washed ashore if not found... +To any adventurer friend: ... shovel... beach... +.. dig there. ... take it to Morris, maybe he ... decipher the engravings. + +Signed +Dormovo the Impetuous + ]] + }, + [61] = { + itemId = 1953, + position = {x = 32854, y = 31992, z = 11}, + text = [[ +What I thought to be digging men are in fact strange green creatures with many arms or eyestalks, who can dig very fast. I think they are called "Beholders". +They did not attack me yet, although I am sure they can sense me. Who knows, maybe they have no interest in me, and I can use their tunnels to get out of here? I will not attack them, unless I have to defend myself. +I stopped counting the days, because I lost all feeling for time down here. + +Oh, how I long to see humans again!]] + }, + [62] = { + itemId = 1953, + position = {x = 33063, y = 31624, z = 15}, + text = "Buried forever that he never shall return. Don't remove this seal or bad things may happen." + } +} + +SignTable = { + [1] = { + itemId = 1429, + itemPos = {x = 32073, y = 31936, z = 7}, + text = "No come near! Goblin home! Humans leave!" + }, + [2] = { + itemId = 8835, + itemPos = {x = 32053, y = 31886, z = 6}, + text = "Sorcerers of Tibia, use the power of the elements to hunt down your foes and strike \z + fear in the heart of your enemies!" + }, + [3] = { + itemId = 3739, + itemPos = {x = 32061, y = 31886, z = 6}, + text = "Paladins of Tibia, arm yourselves and deal merciless death to all that is evil!" + }, + [4] = { + itemId = 8836, + itemPos = {x = 32067, y = 31886, z = 6}, + text = "Knights of Tibia, gird yourselves to combat evil and to protect the innocent!" + }, + [5] = { + itemId = 8422, + itemPos = {x = 32075, y = 31886, z = 6}, + text = "Druids of Tibia, take up your rod to hunt down evil and heal the wounds of the world!" + }, + [6] = { + itemId = 1810, + itemPos = {x = 32056, y = 31890, z = 6}, + text = "Alchemical fluid generator machine. Caution - random effects!" + }, + [7] = { + itemId = 1448, + itemPos = {x = 32064, y = 31891, z = 6}, + text = "Rise, Heroes!" + }, + [8] = { + itemId = 1815, + itemPos = {x = 32057, y = 31893, z = 6}, + text = "Careful with the dustbin! Every item you throw into it will be PERMANENTLY deleted. \z + So consider carefully if you really, really want to delete an item before you lay it on the dustbin." + }, + [9] = { + itemId = 1441, + itemPos = {x = 32062, y = 31894, z = 3}, + text = "Southern Trade Room" + }, + [10] = { + itemId = 1409, + itemPos = {x = 32566, y = 31964, z = 1}, + text = [[ +No treasures here you fools! +Leave the grave of my master alone or feel my wrath! + ]] + }, + [11] = { + itemId = 1406, + itemPos = {x = 32566, y = 31963, z = 1}, + text = [[ +In memory of my beloved master. +One day you will see from your place in heaven that I was right. I AM NOT MAD! +And it was not my fault! +It's your own fault that you are dead now. +Not mine! + ]] + }, + [12] = { + itemId = 1429, + itemPos = {x = 32477, y = 31904, z = 4}, + text = "Room of Sacrifice" + }, + [13] = { + itemId = 1444, + itemPos = {x = 32476, y = 31900, z = 3}, + text = "Cedric, the white knight" + }, + [14] = { + itemId = 1444, + itemPos = {x = 32481, y = 31900, z = 3}, + text = "Tristan, the black knight" + } +} diff --git a/data/update.lua b/data/update.lua new file mode 100644 index 00000000000..fdd902116fb --- /dev/null +++ b/data/update.lua @@ -0,0 +1 @@ +updated = false \ No newline at end of file diff --git a/data/world/custom/otservbr-custom-houses.xml b/data/world/custom/otservbr-custom-houses.xml new file mode 100644 index 00000000000..e5a6b86118e --- /dev/null +++ b/data/world/custom/otservbr-custom-houses.xml @@ -0,0 +1,2 @@ + + diff --git a/data/world/custom/otservbr-custom-spawn.xml b/data/world/custom/otservbr-custom-spawn.xml new file mode 100644 index 00000000000..47ef4f96d52 --- /dev/null +++ b/data/world/custom/otservbr-custom-spawn.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/world/custom/otservbr-custom.otbm b/data/world/custom/otservbr-custom.otbm new file mode 100644 index 00000000000..3b2dbc98ec0 Binary files /dev/null and b/data/world/custom/otservbr-custom.otbm differ diff --git a/data/world/feroxa/final.otbm b/data/world/feroxa/final.otbm new file mode 100644 index 00000000000..87a2597f746 Binary files /dev/null and b/data/world/feroxa/final.otbm differ diff --git a/data/world/feroxa/middle.otbm b/data/world/feroxa/middle.otbm new file mode 100644 index 00000000000..077f50b3033 Binary files /dev/null and b/data/world/feroxa/middle.otbm differ diff --git a/data/world/furygates/abdendriel.otbm b/data/world/furygates/abdendriel.otbm new file mode 100644 index 00000000000..661200667b8 Binary files /dev/null and b/data/world/furygates/abdendriel.otbm differ diff --git a/data/world/furygates/ankrahmun.otbm b/data/world/furygates/ankrahmun.otbm new file mode 100644 index 00000000000..5f27cb4331c Binary files /dev/null and b/data/world/furygates/ankrahmun.otbm differ diff --git a/data/world/furygates/carlin.otbm b/data/world/furygates/carlin.otbm new file mode 100644 index 00000000000..3e6d0f40bee Binary files /dev/null and b/data/world/furygates/carlin.otbm differ diff --git a/data/world/furygates/darashia.otbm b/data/world/furygates/darashia.otbm new file mode 100644 index 00000000000..ee62f6184e7 Binary files /dev/null and b/data/world/furygates/darashia.otbm differ diff --git a/data/world/furygates/edron.otbm b/data/world/furygates/edron.otbm new file mode 100644 index 00000000000..493edce6b41 Binary files /dev/null and b/data/world/furygates/edron.otbm differ diff --git a/data/world/furygates/kazordoon.otbm b/data/world/furygates/kazordoon.otbm new file mode 100644 index 00000000000..40e434a3e68 Binary files /dev/null and b/data/world/furygates/kazordoon.otbm differ diff --git a/data/world/furygates/libertybay.otbm b/data/world/furygates/libertybay.otbm new file mode 100644 index 00000000000..974d427cfa2 Binary files /dev/null and b/data/world/furygates/libertybay.otbm differ diff --git a/data/world/furygates/porthope.otbm b/data/world/furygates/porthope.otbm new file mode 100644 index 00000000000..766b092f02f Binary files /dev/null and b/data/world/furygates/porthope.otbm differ diff --git a/data/world/furygates/thais.otbm b/data/world/furygates/thais.otbm new file mode 100644 index 00000000000..fc1eeea8dad Binary files /dev/null and b/data/world/furygates/thais.otbm differ diff --git a/data/world/furygates/venore.otbm b/data/world/furygates/venore.otbm new file mode 100644 index 00000000000..060729eb9d8 Binary files /dev/null and b/data/world/furygates/venore.otbm differ diff --git a/data/world/nightmareisle/ankrahmun-north.otbm b/data/world/nightmareisle/ankrahmun-north.otbm new file mode 100644 index 00000000000..4d4915ee02b Binary files /dev/null and b/data/world/nightmareisle/ankrahmun-north.otbm differ diff --git a/data/world/nightmareisle/darashia-north.otbm b/data/world/nightmareisle/darashia-north.otbm new file mode 100644 index 00000000000..a3048c1548d Binary files /dev/null and b/data/world/nightmareisle/darashia-north.otbm differ diff --git a/data/world/nightmareisle/darashia-west.otbm b/data/world/nightmareisle/darashia-west.otbm new file mode 100644 index 00000000000..a42af3dd3fa Binary files /dev/null and b/data/world/nightmareisle/darashia-west.otbm differ diff --git a/data/world/otservbr-house.xml b/data/world/otservbr-house.xml new file mode 100644 index 00000000000..73eee7fafeb --- /dev/null +++ b/data/world/otservbr-house.xml @@ -0,0 +1,987 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/world/otservbr-monster.xml b/data/world/otservbr-monster.xml new file mode 100644 index 00000000000..125a3e0bfc3 --- /dev/null +++ b/data/world/otservbr-monster.xml @@ -0,0 +1,163836 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/world/otservbr-npc.xml b/data/world/otservbr-npc.xml new file mode 100644 index 00000000000..85bca8efe6d --- /dev/null +++ b/data/world/otservbr-npc.xml @@ -0,0 +1,2859 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/world/world.zip b/data/world/world.zip new file mode 100644 index 00000000000..8ae10509fd1 Binary files /dev/null and b/data/world/world.zip differ diff --git a/data/world/worldchanges/folhas-house.xml b/data/world/worldchanges/folhas-house.xml new file mode 100644 index 00000000000..e5a6b86118e --- /dev/null +++ b/data/world/worldchanges/folhas-house.xml @@ -0,0 +1,2 @@ + + diff --git a/data/world/worldchanges/folhas-spawn.xml b/data/world/worldchanges/folhas-spawn.xml new file mode 100644 index 00000000000..242503f2b09 --- /dev/null +++ b/data/world/worldchanges/folhas-spawn.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/world/worldchanges/folhas.otbm b/data/world/worldchanges/folhas.otbm new file mode 100644 index 00000000000..167a16ac1d3 Binary files /dev/null and b/data/world/worldchanges/folhas.otbm differ diff --git a/data/world/worldchanges/habitats.otbm b/data/world/worldchanges/habitats.otbm new file mode 100644 index 00000000000..bf1a44a9527 Binary files /dev/null and b/data/world/worldchanges/habitats.otbm differ diff --git a/data/world/worldchanges/ouro-house.xml b/data/world/worldchanges/ouro-house.xml new file mode 100644 index 00000000000..e5a6b86118e --- /dev/null +++ b/data/world/worldchanges/ouro-house.xml @@ -0,0 +1,2 @@ + + diff --git a/data/world/worldchanges/ouro-spawn.xml b/data/world/worldchanges/ouro-spawn.xml new file mode 100644 index 00000000000..242503f2b09 --- /dev/null +++ b/data/world/worldchanges/ouro-spawn.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/world/worldchanges/ouro.otbm b/data/world/worldchanges/ouro.otbm new file mode 100644 index 00000000000..eb98de3adc2 Binary files /dev/null and b/data/world/worldchanges/ouro.otbm differ diff --git a/data/world/yasir/ankrahmun.otbm b/data/world/yasir/ankrahmun.otbm new file mode 100644 index 00000000000..98fb241487f Binary files /dev/null and b/data/world/yasir/ankrahmun.otbm differ diff --git a/data/world/yasir/carlin.otbm b/data/world/yasir/carlin.otbm new file mode 100644 index 00000000000..623491d2f01 Binary files /dev/null and b/data/world/yasir/carlin.otbm differ diff --git a/data/world/yasir/libertybay.otbm b/data/world/yasir/libertybay.otbm new file mode 100644 index 00000000000..6fae489edaa Binary files /dev/null and b/data/world/yasir/libertybay.otbm differ diff --git a/docker/.gitignore b/docker/.gitignore new file mode 100644 index 00000000000..71f67ff2df6 --- /dev/null +++ b/docker/.gitignore @@ -0,0 +1 @@ +data/web/* diff --git a/docker/DOCKER.md b/docker/DOCKER.md new file mode 100644 index 00000000000..b1b747395e8 --- /dev/null +++ b/docker/DOCKER.md @@ -0,0 +1,37 @@ +# Getting Started with docker + +## - Requirements +- Docker 19 and docker-compose 1.17 +- Execute the script root directory /docker/data/download-myaac.sh +- To use global ip change the login.py on world to use that ip and +also change in config.lua.dist +- Client pointing to http://:8080/login.php + +### Default Values (docker-compose.yml) +- Ports: 7171, 7172, 80(web), 3306, 8080(login) +- Database Server: database +- Database Name/User/Password: otserver + +### - Commands +To compile and start database, webserver and otserver just run +``` +$ docker-compose up -d +``` +Sometimes the server will not start due to database take too long to start +so you can restart it +``` +docker-compose restart otserver + +or + +docker-compose stop otserver +docker-compose start otserver +``` + +To compile your changes in otserver, just stop and start +``` +$ docker-compose up -d --build otserver +``` + +### - Observations +- The data folder persist db and webserver data; diff --git a/docker/data/01-test_account.sql b/docker/data/01-test_account.sql new file mode 100644 index 00000000000..1e02cdb6b2b --- /dev/null +++ b/docker/data/01-test_account.sql @@ -0,0 +1,22 @@ +-- +-- Accounts for test server +-- + +INSERT INTO `accounts` +(`id`, `name` , `email` , `password` , `type`, `coins`) VALUES +(100 , 'dawn' , '@dawn' , 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1 , 10000), +(101 , 'test1' , '@test1' , 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1 , 10000), +(102 , 'test2' , '@test2' , 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1 , 10000), +(103 , 'test3' , '@test3' , 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1 , 10000), +(104 , 'test4' , '@test4' , 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1 , 10000), +(105 , 'test5' , '@test5' , 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1 , 10000), +(106 , 'test6' , '@test6' , 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1 , 10000), +(107 , 'test7' , '@test7' , 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1 , 10000), +(108 , 'test8' , '@test8' , 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1 , 10000), +(109 , 'test9' , '@test9' , 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1 , 10000), +(110 , 'test10', '@test10' , 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1 , 10000), +(111 , 'test11', '@test11' , 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1 , 10000), +(112 , 'test12', '@test12' , 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1 , 10000), +(113 , 'test13', '@test13' , 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1 , 10000), +(114 , 'test14', '@test14' , 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1 , 10000), +(115 , 'test15', '@test15' , 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1 , 10000); diff --git a/docker/data/02-test_account_players.sql b/docker/data/02-test_account_players.sql new file mode 100644 index 00000000000..d51877dc6a8 --- /dev/null +++ b/docker/data/02-test_account_players.sql @@ -0,0 +1,184 @@ +-- +-- Account players for test server +-- + +INSERT INTO `players` +(`id`, `name` , `group_id`, `account_id`, `level`, `vocation`, `health`, `healthmax`, `experience`, `lookbody`, `lookfeet`, `lookhead`, `looklegs`, `looktype`, `mana`, `manamax`, `town_id`, `conditions`, `cap`, `sex`) VALUES +(0 , 'Rook Noob 1' , 1 , 101 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer Noob 1' , 1 , 101 , 8 , 1 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Druid Noob 1' , 1 , 101 , 8 , 2 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Paladin Noob 1' , 1 , 101 , 8 , 3 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Knight Noob 1' , 1 , 101 , 8 , 4 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Rook 1' , 1 , 101 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer 1' , 1 , 101 , 500 , 1 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Druid 1' , 1 , 101 , 500 , 2 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Paladin 1' , 1 , 101 , 500 , 3 , 5105 , 5105 , 2058474 , 106 , 95 , 78 , 116 , 128 , 7420 , 7420 , 8 , '' , 10310, 1), +(0 , 'Knight 1' , 1 , 101 , 500 , 4 , 7565 , 7565 , 2058474 , 106 , 95 , 78 , 116 , 128 , 2500 , 2500 , 8 , '' , 12770, 1), +(0 , 'Rook Noob 2' , 1 , 102 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer Noob 2' , 1 , 102 , 8 , 1 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Druid Noob 2' , 1 , 102 , 8 , 2 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Paladin Noob 2' , 1 , 102 , 8 , 3 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Knight Noob 2' , 1 , 102 , 8 , 4 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Rook 2' , 1 , 102 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer 2' , 1 , 102 , 500 , 1 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Druid 2' , 1 , 102 , 500 , 2 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Paladin 2' , 1 , 102 , 500 , 3 , 5105 , 5105 , 2058474 , 106 , 95 , 78 , 116 , 128 , 7420 , 7420 , 8 , '' , 10310, 1), +(0 , 'Knight 2' , 1 , 102 , 500 , 4 , 7565 , 7565 , 2058474 , 106 , 95 , 78 , 116 , 128 , 2500 , 2500 , 8 , '' , 12770, 1), +(0 , 'Rook Noob 3' , 1 , 103 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer Noob 3' , 1 , 103 , 8 , 1 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Druid Noob 3' , 1 , 103 , 8 , 2 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Paladin Noob 3' , 1 , 103 , 8 , 3 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Knight Noob 3' , 1 , 103 , 8 , 4 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Rook 3' , 1 , 103 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer 3' , 1 , 103 , 500 , 1 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Druid 3' , 1 , 103 , 500 , 2 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Paladin 3' , 1 , 103 , 500 , 3 , 5105 , 5105 , 2058474 , 106 , 95 , 78 , 116 , 128 , 7420 , 7420 , 8 , '' , 10310, 1), +(0 , 'Knight 3' , 1 , 103 , 500 , 4 , 7565 , 7565 , 2058474 , 106 , 95 , 78 , 116 , 128 , 2500 , 2500 , 8 , '' , 12770, 1), +(0 , 'Rook Noob 4' , 1 , 104 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer Noob 4' , 1 , 104 , 8 , 1 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Druid Noob 4' , 1 , 104 , 8 , 2 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Paladin Noob 4' , 1 , 104 , 8 , 3 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Knight Noob 4' , 1 , 104 , 8 , 4 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Rook 4' , 1 , 104 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer 4' , 1 , 104 , 500 , 1 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Druid 4' , 1 , 104 , 500 , 2 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Paladin 4' , 1 , 104 , 500 , 3 , 5105 , 5105 , 2058474 , 106 , 95 , 78 , 116 , 128 , 7420 , 7420 , 8 , '' , 10310, 1), +(0 , 'Knight 4' , 1 , 104 , 500 , 4 , 7565 , 7565 , 2058474 , 106 , 95 , 78 , 116 , 128 , 2500 , 2500 , 8 , '' , 12770, 1), +(0 , 'Rook Noob 5' , 1 , 105 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer Noob 5' , 1 , 105 , 8 , 1 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Druid Noob 5' , 1 , 105 , 8 , 2 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Paladin Noob 5' , 1 , 105 , 8 , 3 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Knight Noob 5' , 1 , 105 , 8 , 4 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Rook 5' , 1 , 105 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer 5' , 1 , 105 , 500 , 1 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Druid 5' , 1 , 105 , 500 , 2 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Paladin 5' , 1 , 105 , 500 , 3 , 5105 , 5105 , 2058474 , 106 , 95 , 78 , 116 , 128 , 7420 , 7420 , 8 , '' , 10310, 1), +(0 , 'Knight 5' , 1 , 105 , 500 , 4 , 7565 , 7565 , 2058474 , 106 , 95 , 78 , 116 , 128 , 2500 , 2500 , 8 , '' , 12770, 1), +(0 , 'Rook Noob 6' , 1 , 106 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer Noob 6' , 1 , 106 , 8 , 1 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Druid Noob 6' , 1 , 106 , 8 , 2 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Paladin Noob 6' , 1 , 106 , 8 , 3 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Knight Noob 6' , 1 , 106 , 8 , 4 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Rook 6' , 1 , 106 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer 6' , 1 , 106 , 500 , 1 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Druid 6' , 1 , 106 , 500 , 2 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Paladin 6' , 1 , 106 , 500 , 3 , 5105 , 5105 , 2058474 , 106 , 95 , 78 , 116 , 128 , 7420 , 7420 , 8 , '' , 10310, 1), +(0 , 'Knight 6' , 1 , 106 , 500 , 4 , 7565 , 7565 , 2058474 , 106 , 95 , 78 , 116 , 128 , 2500 , 2500 , 8 , '' , 12770, 1), +(0 , 'Rook Noob 7' , 1 , 107 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer Noob 7' , 1 , 107 , 8 , 1 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Druid Noob 7' , 1 , 107 , 8 , 2 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Paladin Noob 7' , 1 , 107 , 8 , 3 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Knight Noob 7' , 1 , 107 , 8 , 4 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Rook 7' , 1 , 107 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer 7' , 1 , 107 , 500 , 1 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Druid 7' , 1 , 107 , 500 , 2 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Paladin 7' , 1 , 107 , 500 , 3 , 5105 , 5105 , 2058474 , 106 , 95 , 78 , 116 , 128 , 7420 , 7420 , 8 , '' , 10310, 1), +(0 , 'Knight 7' , 1 , 107 , 500 , 4 , 7565 , 7565 , 2058474 , 106 , 95 , 78 , 116 , 128 , 2500 , 2500 , 8 , '' , 12770, 1), +(0 , 'Rook Noob 8' , 1 , 108 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer Noob 8' , 1 , 108 , 8 , 1 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Druid Noob 8' , 1 , 108 , 8 , 2 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Paladin Noob 8' , 1 , 108 , 8 , 3 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Knight Noob 8' , 1 , 108 , 8 , 4 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Rook 8' , 1 , 108 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer 8' , 1 , 108 , 500 , 1 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Druid 8' , 1 , 108 , 500 , 2 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Paladin 8' , 1 , 108 , 500 , 3 , 5105 , 5105 , 2058474 , 106 , 95 , 78 , 116 , 128 , 7420 , 7420 , 8 , '' , 10310, 1), +(0 , 'Knight 8' , 1 , 108 , 500 , 4 , 7565 , 7565 , 2058474 , 106 , 95 , 78 , 116 , 128 , 2500 , 2500 , 8 , '' , 12770, 1), +(0 , 'Rook Noob 9' , 1 , 109 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer Noob 9' , 1 , 109 , 8 , 1 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Druid Noob 9' , 1 , 109 , 8 , 2 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Paladin Noob 9' , 1 , 109 , 8 , 3 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Knight Noob 9' , 1 , 109 , 8 , 4 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Rook 9' , 1 , 109 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer 9' , 1 , 109 , 500 , 1 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Druid 9' , 1 , 109 , 500 , 2 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Paladin 9' , 1 , 109 , 500 , 3 , 5105 , 5105 , 2058474 , 106 , 95 , 78 , 116 , 128 , 7420 , 7420 , 8 , '' , 10310, 1), +(0 , 'Knight 9' , 1 , 109 , 500 , 4 , 7565 , 7565 , 2058474 , 106 , 95 , 78 , 116 , 128 , 2500 , 2500 , 8 , '' , 12770, 1), +(0 , 'Rook Noob 10' , 1 , 110 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer Noob 10', 1 , 110 , 8 , 1 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Druid Noob 10' , 1 , 110 , 8 , 2 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Paladin Noob 10' , 1 , 110 , 8 , 3 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Knight Noob 10' , 1 , 110 , 8 , 4 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Rook 10' , 1 , 110 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer 10' , 1 , 110 , 500 , 1 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Druid 10' , 1 , 110 , 500 , 2 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Paladin 10' , 1 , 110 , 500 , 3 , 5105 , 5105 , 2058474 , 106 , 95 , 78 , 116 , 128 , 7420 , 7420 , 8 , '' , 10310, 1), +(0 , 'Knight 10' , 1 , 110 , 500 , 4 , 7565 , 7565 , 2058474 , 106 , 95 , 78 , 116 , 128 , 2500 , 2500 , 8 , '' , 12770, 1), +(0 , 'Rook Noob 11' , 1 , 111 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer Noob 11', 1 , 111 , 8 , 1 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Druid Noob 11' , 1 , 111 , 8 , 2 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Paladin Noob 11' , 1 , 111 , 8 , 3 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Knight Noob 11' , 1 , 111 , 8 , 4 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Rook 11' , 1 , 111 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer 11' , 1 , 111 , 500 , 1 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Druid 11' , 1 , 111 , 500 , 2 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Paladin 11' , 1 , 111 , 500 , 3 , 5105 , 5105 , 2058474 , 106 , 95 , 78 , 116 , 128 , 7420 , 7420 , 8 , '' , 10310, 1), +(0 , 'Knight 11' , 1 , 111 , 500 , 4 , 7565 , 7565 , 2058474 , 106 , 95 , 78 , 116 , 128 , 2500 , 2500 , 8 , '' , 12770, 1), +(0 , 'Rook Noob 12' , 1 , 112 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer Noob 12', 1 , 112 , 8 , 1 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Druid Noob 12' , 1 , 112 , 8 , 2 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Paladin Noob 12' , 1 , 112 , 8 , 3 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Knight Noob 12' , 1 , 112 , 8 , 4 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Rook 12' , 1 , 112 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer 12' , 1 , 112 , 500 , 1 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Druid 12' , 1 , 112 , 500 , 2 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Paladin 12' , 1 , 112 , 500 , 3 , 5105 , 5105 , 2058474 , 106 , 95 , 78 , 116 , 128 , 7420 , 7420 , 8 , '' , 10310, 1), +(0 , 'Knight 12' , 1 , 112 , 500 , 4 , 7565 , 7565 , 2058474 , 106 , 95 , 78 , 116 , 128 , 2500 , 2500 , 8 , '' , 12770, 1), +(0 , 'Rook Noob 13' , 1 , 113 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer Noob 13', 1 , 113 , 8 , 1 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Druid Noob 13' , 1 , 113 , 8 , 2 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Paladin Noob 13' , 1 , 113 , 8 , 3 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Knight Noob 13' , 1 , 113 , 8 , 4 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Rook 13' , 1 , 113 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer 13' , 1 , 113 , 500 , 1 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Druid 13' , 1 , 113 , 500 , 2 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Paladin 13' , 1 , 113 , 500 , 3 , 5105 , 5105 , 2058474 , 106 , 95 , 78 , 116 , 128 , 7420 , 7420 , 8 , '' , 10310, 1), +(0 , 'Knight 13' , 1 , 113 , 500 , 4 , 7565 , 7565 , 2058474 , 106 , 95 , 78 , 116 , 128 , 2500 , 2500 , 8 , '' , 12770, 1), +(0 , 'Rook Noob 14' , 1 , 114 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer Noob 14', 1 , 114 , 8 , 1 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Druid Noob 14' , 1 , 114 , 8 , 2 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Paladin Noob 14' , 1 , 114 , 8 , 3 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Knight Noob 14' , 1 , 114 , 8 , 4 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Rook 14' , 1 , 114 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer 14' , 1 , 114 , 500 , 1 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Druid 14' , 1 , 114 , 500 , 2 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Paladin 14' , 1 , 114 , 500 , 3 , 5105 , 5105 , 2058474 , 106 , 95 , 78 , 116 , 128 , 7420 , 7420 , 8 , '' , 10310, 1), +(0 , 'Knight 14' , 1 , 114 , 500 , 4 , 7565 , 7565 , 2058474 , 106 , 95 , 78 , 116 , 128 , 2500 , 2500 , 8 , '' , 12770, 1), +(0 , 'Rook Noob 15' , 1 , 115 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer Noob 15', 1 , 115 , 8 , 1 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Druid Noob 15' , 1 , 115 , 8 , 2 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Paladin Noob 15' , 1 , 115 , 8 , 3 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Knight Noob 15' , 1 , 115 , 8 , 4 , 185 , 185 , 4200 , 106 , 95 , 78 , 116 , 128 , 40 , 40 , 8 , '' , 470 , 1), +(0 , 'Rook 15' , 1 , 115 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 1 , '' , 400 , 0), +(0 , 'Sorcerer 15' , 1 , 115 , 500 , 1 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Druid 15' , 1 , 115 , 500 , 2 , 2645 , 2645 , 2058474 , 106 , 95 , 78 , 116 , 128 , 14800 , 14800 , 8 , '' , 5390 , 1), +(0 , 'Paladin 15' , 1 , 115 , 500 , 3 , 5105 , 5105 , 2058474 , 106 , 95 , 78 , 116 , 128 , 7420 , 7420 , 8 , '' , 10310, 1), +(0 , 'ADM1' , 6 , 115 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 8 , '' , 400 , 1), +(0 , 'ADM2' , 6 , 1 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 8 , '' , 400 , 1), +(0 , 'ADM3' , 6 , 1 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 8 , '' , 400 , 1), +(0 , 'ADM4' , 6 , 1 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 8 , '' , 400 , 1), +(0 , 'ADM5' , 6 , 1 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 8 , '' , 400 , 1), +(0 , 'ADM6' , 6 , 1 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 8 , '' , 400 , 1), +(0 , 'ADM7' , 6 , 1 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 8 , '' , 400 , 1), +(0 , 'ADM8' , 6 , 1 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 8 , '' , 400 , 1), +(0 , 'ADM9' , 6 , 1 , 1 , 0 , 150 , 150 , 0 , 106 , 95 , 78 , 116 , 128 , 5 , 5 , 8 , '' , 400 , 1), +(0 , 'Dawn1' , 1 , 100 , 2 , 0 , 155 , 155 , 0 , 106 , 95 , 78 , 116 , 128 , 60 , 60 , 1 , '' , 410 , 0), +(0 , 'Dawn2' , 1 , 100 , 2 , 0 , 155 , 155 , 0 , 106 , 95 , 78 , 116 , 128 , 60 , 60 , 1 , '' , 410 , 0), +(0 , 'Dawn3' , 1 , 100 , 2 , 0 , 155 , 155 , 0 , 106 , 95 , 78 , 116 , 128 , 60 , 60 , 1 , '' , 410 , 0), +(0 , 'Dawn4' , 1 , 100 , 2 , 0 , 155 , 155 , 0 , 106 , 95 , 78 , 116 , 128 , 60 , 60 , 1 , '' , 410 , 0), +(0 , 'Dawn5' , 1 , 100 , 2 , 0 , 155 , 155 , 0 , 106 , 95 , 78 , 116 , 128 , 60 , 60 , 1 , '' , 410 , 0), +(0 , 'Dawn6' , 1 , 100 , 2 , 0 , 155 , 155 , 0 , 106 , 95 , 78 , 116 , 128 , 60 , 60 , 1 , '' , 410 , 0), +(0 , 'Dawn7' , 1 , 100 , 2 , 0 , 155 , 155 , 0 , 106 , 95 , 78 , 116 , 128 , 60 , 60 , 1 , '' , 410 , 0), +(0 , 'Dawn8' , 1 , 100 , 2 , 0 , 155 , 155 , 0 , 106 , 95 , 78 , 116 , 128 , 60 , 60 , 1 , '' , 410 , 0), +(0 , 'Dawn9' , 1 , 100 , 2 , 0 , 155 , 155 , 0 , 106 , 95 , 78 , 116 , 128 , 60 , 60 , 1 , '' , 410 , 0), +(0 , 'Dawn10' , 1 , 100 , 2 , 0 , 155 , 155 , 0 , 106 , 95 , 78 , 116 , 128 , 60 , 60 , 1 , '' , 410 , 0), +(0 , 'Dawn11' , 1 , 100 , 2 , 0 , 155 , 155 , 0 , 106 , 95 , 78 , 116 , 128 , 60 , 60 , 1 , '' , 410 , 0), +(0 , 'Dawn12' , 1 , 100 , 2 , 0 , 155 , 155 , 0 , 106 , 95 , 78 , 116 , 128 , 60 , 60 , 1 , '' , 410 , 0), +(0 , 'Dawn13' , 1 , 100 , 2 , 0 , 155 , 155 , 0 , 106 , 95 , 78 , 116 , 128 , 60 , 60 , 1 , '' , 410 , 0), +(0 , 'Dawn14' , 1 , 100 , 2 , 0 , 155 , 155 , 0 , 106 , 95 , 78 , 116 , 128 , 60 , 60 , 1 , '' , 410 , 0), +(0 , 'Dawn15' , 1 , 100 , 2 , 0 , 155 , 155 , 0 , 106 , 95 , 78 , 116 , 128 , 60 , 60 , 1 , '' , 410 , 0), +(0 , 'Dawn16' , 1 , 100 , 2 , 0 , 155 , 155 , 0 , 106 , 95 , 78 , 116 , 128 , 60 , 60 , 1 , '' , 410 , 0), +(0 , 'Dawn17' , 1 , 100 , 2 , 0 , 155 , 155 , 0 , 106 , 95 , 78 , 116 , 128 , 60 , 60 , 1 , '' , 410 , 0), +(0 , 'Dawn18' , 1 , 100 , 2 , 0 , 155 , 155 , 0 , 106 , 95 , 78 , 116 , 128 , 60 , 60 , 1 , '' , 410 , 0), +(0 , 'Dawn19' , 1 , 100 , 2 , 0 , 155 , 155 , 0 , 106 , 95 , 78 , 116 , 128 , 60 , 60 , 1 , '' , 410 , 0), +(0 , 'Dawn20' , 1 , 100 , 2 , 0 , 155 , 155 , 0 , 106 , 95 , 78 , 116 , 128 , 60 , 60 , 1 , '' , 410 , 0); diff --git a/docker/data/download-myaac.sh b/docker/data/download-myaac.sh new file mode 100755 index 00000000000..e02b9588553 --- /dev/null +++ b/docker/data/download-myaac.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +wget https://github.com/slawkens/myaac/archive/master.zip -O myaac.zip +unzip -o myaac.zip -d . + +mv myaac-master/* ./web +rm myaac.zip myaac-master -rf + +wget https://github.com/opentibiabr/myaac-tibia12-login/archive/refs/heads/develop.zip -O myaac-otbr-plugin.zip +unzip -o myaac-otbr-plugin.zip -d . + +cp -r myaac-tibia12-login-develop/* ./web +rm -rf myaac-otbr-plugin.zip myaac-tibia12-login-develop \ No newline at end of file diff --git a/docker/data/login.py b/docker/data/login.py new file mode 100755 index 00000000000..4d36df3e98d --- /dev/null +++ b/docker/data/login.py @@ -0,0 +1,183 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +This is python script to simulate the login functions used by the Tibia client +11! +""" + +from flask import Flask +from flask import jsonify +from flask import request +import mysql.connector as mariadb +from mysql.connector import Error +import time +import os + +app = Flask(__name__) + +def do_login(data): + + try: + connection = mariadb.connect(host=os.getenv('DB_IP', 'mysql'), + database=os.getenv('DB_DATABASE', 'otserver'), + user=os.getenv('DB_USER', 'otserver'), + password=os.getenv('DB_PASSWORD', 'otserver')) + + sql_select_Query = "SELECT id, premdays, lastday FROM accounts WHERE name = '" + data['email'].replace('@','') + "'" + + print("Loading account information!") + cursor = connection.cursor() + cursor.execute(sql_select_Query) + records = cursor.fetchall() + for row in records: + print("Id = ", row[0]) + account_id = row[0] + account_premdays = row[1] + account_lastday = row[2] + + session = { + 'sessionkey': data['email'] + '\n' + data['password'], + 'lastlogintime': 0, + 'ispremium': True if account_premdays > 0 else False, + 'premiumuntil': 0 if account_premdays == 0 else int(time.time()) + (account_premdays * 86400), + 'status': 'active', + 'returnernotification': False, + 'showrewardnews': True, + 'isreturner': True, + 'fpstracking': False, + 'optiontracking': False, + 'tournamentticketpurchasestate': 0, + 'emailcoderequest': False + }; + print(session) + + sql_select_Query = "SELECT name, level, sex, vocation, looktype, lookhead, lookbody, looklegs, lookfeet, lookaddons, lastlogin from players where account_id = '" + str(account_id) + "'" + + cursor = connection.cursor() + cursor.execute(sql_select_Query) + records = cursor.fetchall() + print(records) + + players = [] + vocations = ['None', 'Sorcerer', 'Druid', 'Paladin', 'Knight', 'Master Sorcerer', 'Elder Druid', 'Royal Paladin', 'Elite Knight', 'Sorcerer Dawnport', 'Druid Dawnport', 'Paladin Dawnport', 'Knight Dawnport'] + print("Loading account players information!") + for (name, level, sex, vocation, looktype, lookhead, lookbody, looklegs, lookfeet, lookaddons, lastlogin) in records: + player = { + 'worldid': 0, + 'name': name, + 'level': level, + 'ismale': True if sex == 1 else False, + 'vocation': vocations[vocation], + 'outfitid': looktype, + 'headcolor': lookhead, + 'torsocolor': lookbody, + 'legscolor': looklegs, + 'detailcolor': lookfeet, + 'addonsflags': lookaddons, + 'tutorial': False, # True will make the client crash as it will try to auto connect + 'ishidden': False, + 'istournamentparticipant': False, + 'remainingdailytournamentplaytime': 0 + } + players.append(player) + print(players) + + playdata = { + 'worlds': [ + { + 'id': 0, + 'name': os.getenv('SERVER_NAME', 'OTServBR-Global'), + 'externaladdressprotected': os.getenv('PROXY_IP', '127.0.0.1'), + 'externalportprotected': int(os.getenv('SERVER_GAME_PORT', 7172)), + 'externaladdressunprotected': os.getenv('PROXY_IP', '127.0.0.1'), + 'externalportunprotected': int(os.getenv('SERVER_GAME_PORT', 7172)), + 'previewstate': 0, + 'location': 'BRA', + 'anticheatprotection': False, + 'pvptype': 'pvp', + 'istournamentworld': False, + 'restrictedstore': False, + 'currenttournamentphase': 2 + } + ], + "characters": players + } + + answer = {'session': session, 'playdata': playdata} + print(answer) + return jsonify(answer) + + except Error as e: + print("Error reading data from MySQL table", e) + + finally: + if (connection.is_connected()): + connection.close() + cursor.close() + print("MySQL connection is closed") + + +def news(data): + + answer = [] + + return jsonify(answer) + + +@app.route('/login.php', methods=['GET', 'POST', 'PUT']) +def action(): + + data = request.get_json() + print(data) + + if(data['type'] == 'cacheinfo'): + return jsonify({ + 'playersonline': 5, + 'twitchstreams': 0, + 'twitchviewer': 0, + 'gamingyoutubestreams': 0, + 'gamingyoutubeviewer': 0 + }) + if(data['type'] == 'news'): + return jsonify({}) + + # The client has a cache of the events on it so it will ask for the events only when it see that last sync was made some time X ago + if(data['type'] == 'eventschedule'): + return jsonify({ + 'lastupdatetimestamp': time.time(), + 'eventlist': [ + { + 'startdate': int(time.time()), + 'enddate': int(time.time()) + 36600 * 20, + 'colorlight': '#64162b', + 'colordark': '#7a1b34', + 'name': 'First Event', + 'description': 'Canary Event 1', + 'isseasonal': False + }, + { + 'startdate': int(time.time()), + 'enddate': int(time.time()) + 36600 * 20, + 'colorlight': '#8B6D05', + 'colordark': '#735D10', + 'name': 'Second Event', + 'description': 'Canary Event 2', + 'isseasonal': False + } + ] + }) + + if(data['type'] == 'boostedcreature'): + return jsonify({ + 'boostedcreature': True, + 'raceid': 39 + }) + + if(data['type'] == 'login'): + return do_login(data) + + + if(data['type'] == 'news'): + return news(data) + +app.run(debug=True, host='0.0.0.0', port=8080) diff --git a/docker/data/web/.gitignore b/docker/data/web/.gitignore new file mode 100644 index 00000000000..5e7d2734cfc --- /dev/null +++ b/docker/data/web/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 00000000000..a64de8ecd0f --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,60 @@ +version: "3.3" + +services: + server: + build: + context: ../ + dockerfile: docker/server/Dockerfile + ports: + - 7171:7171 + - 7172:7172 + depends_on: + - mysql + - website + - login + links: + - mysql + + mysql: + build: + context: ../ + dockerfile: docker/mysql/Dockerfile + restart: unless-stopped + environment: + - MYSQL_DATABASE=otserver + - MYSQL_USER=otserver + - MYSQL_PASSWORD=otserver + - MYSQL_RANDOM_ROOT_PASSWORD=yes + ports: + - 3306:3306 + volumes: + - db-volume:/var/lib/mysql + + website: + image: webdevops/php-nginx:alpine-php7 + restart: unless-stopped + environment: + - WEB_DOCUMENT_ROOT=/tmp/web/ + - WEB_DOCUMENT_INDEX=index.php + ports: + - 8080:80 + volumes: + - ./docker/data/web:/tmp/web + - ./:/tmp/otserver/ + depends_on: + - mysql + + login: + build: + context: ../ + dockerfile: docker/login/Dockerfile + restart: unless-stopped + volumes: + - ./docker/data/:/tmp/ + ports: + - 80:8080 + depends_on: + - mysql + +volumes: + db-volume: diff --git a/docker/login/Dockerfile b/docker/login/Dockerfile new file mode 100644 index 00000000000..d5f91507a69 --- /dev/null +++ b/docker/login/Dockerfile @@ -0,0 +1,9 @@ +FROM python:3 + +WORKDIR /usr/src/app + +RUN pip install --no-cache-dir Flask mysql-connector-python + +COPY docker/data/login.py . + +CMD [ "python", "./login.py" ] diff --git a/docker/mysql/Dockerfile b/docker/mysql/Dockerfile new file mode 100644 index 00000000000..ba32145a1a1 --- /dev/null +++ b/docker/mysql/Dockerfile @@ -0,0 +1,3 @@ +FROM mariadb:10 + +COPY schema.sql /docker-entrypoint-initdb.d/ diff --git a/docker/server/Dockerfile b/docker/server/Dockerfile new file mode 100644 index 00000000000..ac43bf377e5 --- /dev/null +++ b/docker/server/Dockerfile @@ -0,0 +1,51 @@ +# Stage 1: Download all dependencies +FROM ubuntu:20.04 AS dependencies + +RUN apt-get update && apt-get install -y --no-install-recommends cmake + +RUN apt-get update && apt-get install -y --no-install-recommends git + +RUN apt-get install -y --no-install-recommends \ + build-essential ca-certificates curl zip unzip tar pkg-config + +RUN apt-get install -y --no-install-recommends libluajit-5.1-dev unzip + +WORKDIR /opt +RUN git clone https://github.com/microsoft/vcpkg +RUN ./vcpkg/bootstrap-vcpkg.sh + +WORKDIR /opt/vcpkg +COPY vcpkg.json /opt/vcpkg/ +RUN /opt/vcpkg/vcpkg --feature-flags=binarycaching,manifests,versions install + +# Stage 2: create build +FROM dependencies AS build + +COPY cmake /srv/cmake +COPY CMakeLists.txt vcpkg.json /srv/ +COPY src /srv/src + +WORKDIR /srv/build + +RUN cmake -DCMAKE_TOOLCHAIN_FILE=/opt/vcpkg/scripts/buildsystems/vcpkg.cmake .. && make -j`nproc` + +# Stage 3: load data and execute +FROM build + +COPY --from=build /srv/build/bin/otbr /bin/otbr +COPY LICENSE *.sql key.pem /otbr/ +COPY data /otbr/data +COPY config.lua.dist /otbr/config.lua + +WORKDIR /otbr + +RUN sed -i '/mysqlHost = .*$/c\mysqlHost = "mysql"' config.lua \ + && sed -i '/mysqlUser = .*$/c\mysqlUser = "otserver"' config.lua \ + && sed -i '/mysqlPass = .*$/c\mysqlPass = "otserver"' config.lua \ + && sed -i '/mysqlDatabase = .*$/c\mysqlDatabase = "otserver"' config.lua \ + && unzip -o data/world/world.zip -d data/world/ + +VOLUME /otbr + +ENTRYPOINT ["/bin/otbr"] + diff --git a/docker/test-server.sh b/docker/test-server.sh new file mode 100755 index 00000000000..271517ea0df --- /dev/null +++ b/docker/test-server.sh @@ -0,0 +1,80 @@ +#!/bin/bash + +# set -o xtrace +set -o errexit # abort on nonzero exitstatus +set -o nounset # abort on unbound variable + +export DEBIAN_FRONTEND=noninteractive + +ln -fs /usr/share/zoneinfo/America/Sao_Paulo /etc/localtime + +apt-get update +apt-get install -y \ + apache2 \ + build-essential \ + ca-certificates \ + ccache \ + cmake \ + curl \ + git \ + libapache2-mod-php \ + libluajit-5.1-dev \ + php \ + php-mysql \ + pkg-config \ + python3 \ + python3-pip \ + tar \ + unzip \ + zip + +dpkg-reconfigure --frontend noninteractive tzdata + +apt-get install -y mariadb-server mariadb-client +/etc/init.d/mysql start + +apt-get install -y phpmyadmin +ln -s /usr/share/phpmyadmin /var/www/html +/etc/init.d/apache2 start + +# Create database and import schema +mysql -u root -e "CREATE DATABASE $DB_DATABASE;" +mysql -u root -e "SHOW DATABASES;" +mysql -u root -D $DB_DATABASE < schema.sql +mysql -u root -D $DB_DATABASE < docker/data/01-test_account.sql +mysql -u root -D $DB_DATABASE < docker/data/02-test_account_players.sql + +# Create user +mysql -u root -e "CREATE USER '$DB_USER'@localhost IDENTIFIED BY '$DB_PASSWORD';" +mysql -u root -e "SELECT User FROM mysql.user;" +mysql -u root -e "GRANT ALL PRIVILEGES ON *.* TO '$DB_USER'@localhost IDENTIFIED BY '$DB_PASSWORD';" + +# Make our changes take effect +mysql -u root -e "FLUSH PRIVILEGES;" + +pip3 install --no-cache-dir Flask mysql-connector-python +python3 docker/data/login.py & + +git clone https://github.com/microsoft/vcpkg +cd vcpkg +./bootstrap-vcpkg.sh +cd .. + +mkdir -p build +cd build +cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake .. +make -j`nproc` +mv bin/otbr ../ +cd .. + +unzip -o data/world/world.zip -d data/world/ + +cp config.lua.dist config.lua +sed -i '/ip = .*$/c\ip = "'"$PROXY_IP"'"' config.lua +sed -i '/motd = .*$/c\motd = "Test Server"' config.lua +sed -i '/mysqlHost = .*$/c\mysqlHost = "'"$DB_IP"'"' config.lua +sed -i '/mysqlUser = .*$/c\mysqlUser = "'"$DB_USER"'"' config.lua +sed -i '/mysqlPass = .*$/c\mysqlPass = "'"$DB_PASSWORD"'"' config.lua +sed -i '/mysqlDatabase = .*$/c\mysqlDatabase = "'"$DB_DATABASE"'"' config.lua +sed -i '/onePlayerOnlinePerAccount = .*$/c\onePlayerOnlinePerAccount = false' config.lua +sed -i '/serverSaveShutdown = .*$/c\serverSaveShutdown = false' config.lua diff --git a/docs/Doxyfile.in b/docs/Doxyfile.in new file mode 100644 index 00000000000..f799215dcbe --- /dev/null +++ b/docs/Doxyfile.in @@ -0,0 +1,2494 @@ +# Doxyfile 1.8.13 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv +# for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "OTS" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = $(PROJECT_NUMBER) + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "Open Tibia Server" + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@/doc/source/ + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = YES + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 0. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 0 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = YES + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO, these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = @CMAKE_CURRENT_SOURCE_DIR@/src/ + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: http://www.gnu.org/software/libiconv) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.pyw \ + *.f90 \ + *.f95 \ + *.f03 \ + *.f08 \ + *.f \ + *.for \ + *.tcl \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = YES + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see http://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the +# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the +# cost of reduced performance. This can be particularly helpful with template +# rich C++ code for which doxygen's built-in parser lacks the necessary type +# information. +# Note: The availability of this option depends on whether or not doxygen was +# generated with the -Duse-libclang=ON option for CMake. +# The default value is: NO. + +CLANG_ASSISTED_PARSING = NO + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by doxygen for the files and directories +# specified with INPUT and INCLUDE_PATH. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_OPTIONS = + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# http://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = YES + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: http://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = YES + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# http://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from http://www.mathjax.org before deployment. +# The default value is: http://cdn.mathjax.org/mathjax/latest. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /